summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2014-09-03 20:54:39 +0200
committerChristian Beier <dontmind@freeshell.org>2014-09-03 20:54:39 +0200
commit498d222976975f53dea885cfe43ef0f805abd412 (patch)
treebac684fbde46fdc3e4cc3817616816b71bb67f9f
parent8d2db0486dcc167f1b02d4454ebf4624ce03e1de (diff)
downloadlibvncserver-498d222976975f53dea885cfe43ef0f805abd412.zip
libvncserver-498d222976975f53dea885cfe43ef0f805abd412.tar.gz
Remove x11vnc subdir.
The new x11vnc repo is at https://github.com/LibVNC/x11vnc.
-rw-r--r--x11vnc/.cvsignore5
-rw-r--r--x11vnc/8to24.c2155
-rw-r--r--x11vnc/8to24.h45
-rw-r--r--x11vnc/ChangeLog1257
-rw-r--r--x11vnc/Makefile.am43
-rw-r--r--x11vnc/README18246
-rw-r--r--x11vnc/RELEASE-NOTES1553
-rw-r--r--x11vnc/allowed_input_t.h46
-rw-r--r--x11vnc/appshare.c2124
-rw-r--r--x11vnc/avahi.c434
-rw-r--r--x11vnc/avahi.h43
-rw-r--r--x11vnc/blackout_t.h49
-rw-r--r--x11vnc/cleanup.c769
-rw-r--r--x11vnc/cleanup.h59
-rw-r--r--x11vnc/connections.c4437
-rw-r--r--x11vnc/connections.h83
-rw-r--r--x11vnc/cursor.c2025
-rw-r--r--x11vnc/cursor.h70
-rw-r--r--x11vnc/enc.h2165
-rw-r--r--x11vnc/enums.h54
-rw-r--r--x11vnc/gui.c937
-rw-r--r--x11vnc/gui.h53
-rw-r--r--x11vnc/help.c6441
-rw-r--r--x11vnc/help.h43
-rw-r--r--x11vnc/inet.c936
-rw-r--r--x11vnc/inet.h60
-rw-r--r--x11vnc/keyboard.c3418
-rw-r--r--x11vnc/keyboard.h62
-rw-r--r--x11vnc/linuxfb.c394
-rw-r--r--x11vnc/linuxfb.h42
-rw-r--r--x11vnc/macosx.c752
-rw-r--r--x11vnc/macosx.h63
-rw-r--r--x11vnc/macosxCG.c989
-rw-r--r--x11vnc/macosxCG.h62
-rw-r--r--x11vnc/macosxCGP.c221
-rw-r--r--x11vnc/macosxCGP.h49
-rw-r--r--x11vnc/macosxCGS.c602
-rw-r--r--x11vnc/macosxCGS.h45
-rw-r--r--x11vnc/macosx_opengl.c176
-rw-r--r--x11vnc/macosx_opengl.h41
-rw-r--r--x11vnc/misc/.cvsignore3
-rw-r--r--x11vnc/misc/LICENSE31
-rw-r--r--x11vnc/misc/Makefile.am3
-rw-r--r--x11vnc/misc/README50
-rwxr-xr-xx11vnc/misc/Xdummy1930
-rw-r--r--x11vnc/misc/blockdpy.c352
-rwxr-xr-xx11vnc/misc/connect_switch696
-rwxr-xr-xx11vnc/misc/desktop.cgi1550
-rw-r--r--x11vnc/misc/dtVncPopup109
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/COPYING340
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/README756
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt72
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat1
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl1271
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/esound/download.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/download.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/location.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/download.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/licence.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/download.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/location.url2
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/download.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/location.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-client.conf43
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-server.conf34
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/w98/location.url1
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/.cpover7
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vncviewer.sh39
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.i386/.cpover6
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc7
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc289
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd286
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc7
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer3635
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl19041
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf38
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/build.unix482
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt280
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1233
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1829
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/README7
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/patches/README6
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle103
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches14
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/src/patches/_vncpatchapplied6
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.patch44
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch24370
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fullscreen.patch42
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-newfbsize.patch286
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README16
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/ssvnc.desktop11
-rwxr-xr-xx11vnc/misc/inet6to4420
-rwxr-xr-xx11vnc/misc/panner.pl117
-rwxr-xr-xx11vnc/misc/qt_tslib_inject.pl1064
-rwxr-xr-xx11vnc/misc/ranfb.pl157
-rwxr-xr-xx11vnc/misc/rx11vnc133
-rwxr-xr-xx11vnc/misc/rx11vnc.pl199
-rwxr-xr-xx11vnc/misc/shm_clear97
-rwxr-xr-xx11vnc/misc/slide.pl112
-rw-r--r--x11vnc/misc/turbovnc/Makefile.am8
-rw-r--r--x11vnc/misc/turbovnc/README159
-rwxr-xr-xx11vnc/misc/turbovnc/apply_turbovnc46
-rwxr-xr-xx11vnc/misc/turbovnc/convert79
-rwxr-xr-xx11vnc/misc/turbovnc/convert_rfbserver56
-rw-r--r--x11vnc/misc/turbovnc/tight.c1502
-rw-r--r--x11vnc/misc/turbovnc/turbojpeg.h229
-rwxr-xr-xx11vnc/misc/turbovnc/undo_turbovnc25
-rwxr-xr-xx11vnc/misc/uinput.pl946
-rwxr-xr-xx11vnc/misc/ultravnc_repeater.pl741
-rwxr-xr-xx11vnc/misc/vcinject.pl113
-rwxr-xr-xx11vnc/misc/x11vnc_loop89
-rwxr-xr-xx11vnc/misc/x11vnc_pw24
-rw-r--r--x11vnc/nox11.h6671
-rw-r--r--x11vnc/nox11_funcs.h2822
-rw-r--r--x11vnc/options.c514
-rw-r--r--x11vnc/options.h404
-rw-r--r--x11vnc/params.h103
-rw-r--r--x11vnc/pm.c297
-rw-r--r--x11vnc/pm.h40
-rw-r--r--x11vnc/pointer.c1206
-rw-r--r--x11vnc/pointer.h47
-rw-r--r--x11vnc/rates.c732
-rw-r--r--x11vnc/rates.h55
-rw-r--r--x11vnc/remote.c6323
-rw-r--r--x11vnc/remote.h50
-rw-r--r--x11vnc/scan.c3687
-rw-r--r--x11vnc/scan.h60
-rw-r--r--x11vnc/screen.c4705
-rw-r--r--x11vnc/screen.h68
-rw-r--r--x11vnc/scrollevent_t.h47
-rw-r--r--x11vnc/selection.c548
-rw-r--r--x11vnc/selection.h55
-rw-r--r--x11vnc/solid.c1429
-rw-r--r--x11vnc/solid.h47
-rw-r--r--x11vnc/sslcmds.c908
-rw-r--r--x11vnc/sslcmds.h49
-rw-r--r--x11vnc/sslhelper.c4345
-rw-r--r--x11vnc/sslhelper.h73
-rw-r--r--x11vnc/ssltools.h2560
-rwxr-xr-xx11vnc/tkx11vnc7335
-rw-r--r--x11vnc/tkx11vnc.h7351
-rw-r--r--x11vnc/uinput.c1876
-rw-r--r--x11vnc/uinput.h59
-rw-r--r--x11vnc/unixpw.c2281
-rw-r--r--x11vnc/unixpw.h64
-rw-r--r--x11vnc/user.c3155
-rw-r--r--x11vnc/user.h49
-rw-r--r--x11vnc/userinput.c10199
-rw-r--r--x11vnc/userinput.h77
-rw-r--r--x11vnc/util.c787
-rw-r--r--x11vnc/util.h156
-rw-r--r--x11vnc/v4l.c1785
-rw-r--r--x11vnc/v4l.h42
-rw-r--r--x11vnc/win_utils.c771
-rw-r--r--x11vnc/win_utils.h59
-rw-r--r--x11vnc/winattr_t.h66
-rw-r--r--x11vnc/x11vnc.16962
-rw-r--r--x11vnc/x11vnc.c5945
-rw-r--r--x11vnc/x11vnc.desktop10
-rw-r--r--x11vnc/x11vnc.h699
-rw-r--r--x11vnc/x11vnc_defs.c230
-rw-r--r--x11vnc/xdamage.c840
-rw-r--r--x11vnc/xdamage.h64
-rw-r--r--x11vnc/xevents.c2175
-rw-r--r--x11vnc/xevents.h67
-rw-r--r--x11vnc/xinerama.c563
-rw-r--r--x11vnc/xinerama.h50
-rw-r--r--x11vnc/xkb_bell.c167
-rw-r--r--x11vnc/xkb_bell.h44
-rw-r--r--x11vnc/xrandr.c307
-rw-r--r--x11vnc/xrandr.h94
-rw-r--r--x11vnc/xrecord.c2084
-rw-r--r--x11vnc/xrecord.h68
-rw-r--r--x11vnc/xwrappers.c1522
-rw-r--r--x11vnc/xwrappers.h121
176 files changed, 0 insertions, 210670 deletions
diff --git a/x11vnc/.cvsignore b/x11vnc/.cvsignore
deleted file mode 100644
index 27e9b7a..0000000
--- a/x11vnc/.cvsignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.deps
-Makefile
-Makefile.in
-x11vnc
-
diff --git a/x11vnc/8to24.c b/x11vnc/8to24.c
deleted file mode 100644
index 30c3da2..0000000
--- a/x11vnc/8to24.c
+++ /dev/null
@@ -1,2155 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- 8to24.c -- */
-#include "x11vnc.h"
-#include "cleanup.h"
-#include "scan.h"
-#include "util.h"
-#include "win_utils.h"
-#include "xwrappers.h"
-
-int multivis_count = 0;
-int multivis_24count = 0;
-
-void check_for_multivis(void);
-void bpp8to24(int, int, int, int);
-void mark_8bpp(int);
-
-#if SKIP_8TO24
-void check_for_multivis(void) {}
-void bpp8to24(int x, int y, int z, int t) {}
-void mark_8bpp(int x) {}
-#else
-/* lots... */
-
-static void set_root_cmap(void);
-static int check_pointer_in_depth24(void);
-static void parse_cmap8to24(void);
-static void set_poll_fb(void);
-static int check_depth(Window win, Window top, int doall);
-static int check_depth_win(Window win, Window top, XWindowAttributes *attr);
-static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w);
-static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod);
-static void poll_line_complement(int x1, int x2, int y1, sraRegionPtr mod);
-static int poll_8bpp(sraRegionPtr, int);
-static void poll_8bpp_complement(sraRegionPtr);
-static void mark_rgn_rects(sraRegionPtr mod);
-static int get_8bpp_regions(int validate);
-static int get_cmap(int j, Colormap cmap);
-static void do_8bpp_region(int n, sraRegionPtr mark);
-static XImage *cmap_xi(XImage *xi, Window win, int win_depth);
-static void transform_rect(sraRect rect, Window win, int win_depth, int cm);
-
-/* struct for keeping info about the 8bpp windows: */
-typedef struct window8 {
- Window win;
- Window top;
- int depth;
- int x, y;
- int w, h;
- int map_state;
- Colormap cmap;
- Bool map_installed;
- int fetched;
- double last_fetched;
- sraRegionPtr clip_region;
-} window8bpp_t;
-
-enum mark_8bpp_modes {
- MARK_8BPP_ALL = 0,
- MARK_8BPP_POINTER,
- MARK_8BPP_TOP
-};
-
-
-#define NCOLOR 256
-
-static Colormap root_cmap = 0;
-static unsigned int *root_rgb = NULL;
-
-static void set_root_cmap(void) {
-#if NO_X11
- RAWFB_RET_VOID
- return;
-#else
- static time_t last_set = 0;
- time_t now = time(NULL);
- XWindowAttributes attr;
- static XColor *color = NULL;
- int redo = 0;
- int ncolor = 0;
-
- RAWFB_RET_VOID
-
- if (depth > 16) {
- ncolor = NCOLOR;
- } else if (depth > 8) {
- ncolor = 1 << depth;
- } else {
- ncolor = NCOLOR;
- }
-
- if (!root_rgb) {
- root_rgb = (unsigned int *) malloc(ncolor * sizeof(unsigned int));
- }
- if (!color) {
- color = (XColor *) malloc(ncolor * sizeof(XColor));
- }
-
- if (now > last_set + 10) {
- redo = 1;
- }
- if (! root_cmap || redo) {
- X_LOCK;
- if (! valid_window(window, &attr, 1)) {
- X_UNLOCK;
- return;
- }
- if (attr.colormap) {
- int i, ncells = ncolor;
-
- if (depth < 8) {
- ncells = CellsOfScreen(ScreenOfDisplay(dpy, scr));
- }
- for (i=0; i < ncells; i++) {
- color[i].pixel = i;
- color[i].pad = 0;
- }
- last_set = now;
- root_cmap = attr.colormap;
- XQueryColors(dpy, root_cmap, color, ncells);
- for (i=0; i < ncells; i++) {
- unsigned int red, green, blue;
- /* strip out highest 8 bits of values: */
- red = (color[i].red & 0xff00) >> 8;
- green = (color[i].green & 0xff00) >> 8;
- blue = (color[i].blue & 0xff00) >> 8;
-
- /*
- * the maxes should be at 255 already,
- * but just in case...
- */
- red = (main_red_max * red )/255;
- green = (main_green_max * green)/255;
- blue = (main_blue_max * blue )/255;
-
- /* shift them over and or together for value */
- red = red << main_red_shift;
- green = green << main_green_shift;
- blue = blue << main_blue_shift;
-
- /* store it in the array to be used later */
- root_rgb[i] = red | green | blue;
- }
- }
- X_UNLOCK;
- }
-#endif /* NO_X11 */
-}
-
-/* fixed size array. Will primarily hold visible 8bpp windows */
-#define MAX_8BPP_WINDOWS 64
-static window8bpp_t windows_8bpp[MAX_8BPP_WINDOWS];
-
-static int db24 = 0;
-static int xgetimage_8to24 = 1;
-static double poll_8to24_delay = POLL_8TO24_DELAY;
-static double cache_win = 0.0;
-static int level2_8to24 = 0;
-
-static int check_pointer_in_depth24(void) {
- int tries = 0, in_24 = 0;
- XWindowAttributes attr;
- Window c, w;
- double now = dnow();
-
- c = window;
-
- RAWFB_RET(0)
-
- if (now > last_keyboard_time + 1.0 && now > last_pointer_time + 1.0) {
- return 0;
- }
-
- X_LOCK;
- while (c && tries++ < 3) {
- c = query_pointer(c);
- if (valid_window(c, &attr, 1)) {
- if (attr.depth == 24) {
- in_24 = 1;
- break;
- }
- }
- }
- X_UNLOCK;
- if (in_24) {
- int x1, y1, x2, y2;
- X_LOCK;
- xtranslate(c, window, 0, 0, &x1, &y1, &w, 1);
- X_UNLOCK;
- x2 = x1 + attr.width;
- y2 = y1 + attr.height;
- x1 = nfix(x1, dpy_x);
- y1 = nfix(y1, dpy_y);
- x2 = nfix(x2, dpy_x+1);
- y2 = nfix(y2, dpy_y+1);
- mark_rect_as_modified(x1, y1, x2, y2, 0);
-
-if (db24 > 1) fprintf(stderr, "check_pointer_in_depth24 %d %d %d %d\n", x1, y1, x2, y2);
-
- return 1;
- }
- return 0;
-}
-
-static void parse_cmap8to24(void) {
- if (cmap8to24_str) {
- char *p, *str = strdup(cmap8to24_str);
- p = strtok(str, ",");
- /* defaults: */
- db24 = 0;
- xgetimage_8to24 = 1;
- poll_8to24_delay = POLL_8TO24_DELAY;
- level2_8to24 = 0;
- cache_win = 0.0;
- while (p) {
- if (strstr(p, "dbg=") == p) {
- db24 = atoi(p + strlen("dbg="));
- } else if (strstr(p, "poll=") == p) {
- poll_8to24_delay = atof(p + strlen("poll="));
- } else if (strstr(p, "cachewin=") == p) {
- cache_win = atof(p + strlen("cachewin="));
- } else if (!strcmp(p, "nogetimage")) {
- xgetimage_8to24 = 0;
- } else if (!strcmp(p, "level2")) {
- level2_8to24 = 1;
- }
- p = strtok(NULL, ",");
- }
- free(str);
- } else {
- if (getenv("DEBUG_8TO24") != NULL) {
- db24 = atoi(getenv("DEBUG_8TO24"));
- }
- if (getenv("NOXGETIMAGE_8TO24") != NULL) {
- xgetimage_8to24 = 0;
- }
- }
-}
-
-static char *poll8_fb = NULL, *poll24_fb = NULL;
-static int poll8_fb_w = 0, poll8_fb_h = 0;
-static int poll24_fb_w = 0, poll24_fb_h = 0;
-
-static void pfb(int fac, char **fb, int *w, int *h) {
- if (! *fb || *w != dpy_x || *h != dpy_y) {
- if (*fb) {
- free(*fb);
- }
- *fb = (char *) calloc(fac * dpy_x * dpy_y, 1);
- *w = dpy_x;
- *h = dpy_y;
- }
-}
-
-static void set_poll_fb(void) {
- /* create polling framebuffers or recreate if too small. */
-
- if (! xgetimage_8to24) {
- return; /* this saves a bit of RAM */
- }
- pfb(4, &poll24_fb, &poll24_fb_w, &poll24_fb_h);
- if (depth > 8 && depth <= 16) {
- pfb(2, &poll8_fb, &poll8_fb_w, &poll8_fb_h); /* 2X for rare 16bpp colormap case */
- } else {
- pfb(1, &poll8_fb, &poll8_fb_w, &poll8_fb_h);
- }
-}
-
-int MV_glob = 0;
-int MV_count;
-int MV_hit;
-double MV_start;
-
-void check_for_multivis(void) {
-#if NO_X11
- RAWFB_RET_VOID
- return;
-#else
- XWindowAttributes attr;
- int doall = 0;
- int k, i, cnt, diff;
- static int first = 1;
- static Window *stack_old = NULL;
- static int stack_old_len = 0;
- static double last_parse = 0.0;
- static double last_update = 0.0;
- static double last_clear = 0.0;
- static double last_poll = 0.0;
- static double last_fixup = 0.0;
- static double last_call = 0.0;
- static double last_query = 0.0;
- double now = dnow();
- double delay;
-
- RAWFB_RET_VOID
-
- if (now > last_parse + 1.0) {
- last_parse = now;
- parse_cmap8to24();
- }
-if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
- last_call = now;
-
- if (first) {
- int i;
- /* initialize 8bpp window table: */
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- windows_8bpp[i].win = None;
- windows_8bpp[i].top = None;
- windows_8bpp[i].map_state = IsUnmapped;
- windows_8bpp[i].cmap = (Colormap) 0;
- windows_8bpp[i].fetched = 0;
- windows_8bpp[i].last_fetched = -1.0;
- windows_8bpp[i].clip_region = NULL;
- }
- set_poll_fb();
-
- first = 0;
- doall = 1; /* fetch everything first time */
- }
-
- if (wireframe_in_progress) {
- return;
- }
-
- set_root_cmap();
-
- /*
- * allocate an "old stack" list of all toplevels. we compare
- * this to the current stack to guess stacking order changes.
- */
- if (!stack_old || stack_old_len < stack_list_len) {
- int n = stack_list_len;
- if (n < 256) {
- n = 256;
- }
- if (stack_old) {
- free(stack_old);
- }
- stack_old = (Window *) calloc(n*sizeof(Window), 1);
- stack_old_len = n;
- }
-
- /* fill the old stack with visible windows: */
- cnt = 0;
- for (k=0; k < stack_list_num; k++) {
- if (stack_list[k].valid &&
- stack_list[k].map_state == IsViewable) {
- stack_old[cnt++] = stack_list[k].win;
- }
- }
-
- /* snapshot + update the current stacking order: */
- /* TUNABLE */
- if (poll_8to24_delay >= POLL_8TO24_DELAY) {
- delay = 3.0 * poll_8to24_delay;
- } else {
- delay = 3.0 * POLL_8TO24_DELAY; /* 0.15 */
- }
- if (doall || now > last_update + delay) {
- snapshot_stack_list(0, 0.0);
- update_stack_list();
- last_update = now;
- }
-
- /* look for differences in the visible toplevels: */
- diff = 0;
- cnt = 0;
- for (k=0; k < stack_list_num; k++) {
- if (stack_list[k].valid && stack_list[k].map_state ==
- IsViewable) {
- if (stack_old[cnt] != stack_list[k].win) {
- diff = 1;
- break;
- }
- cnt++;
- }
- }
-
- multivis_count = 0;
- multivis_24count = 0;
-
- /*
- * every 10 seconds we try to clean out and also refresh the window
- * info in the 8bpp window table:
- */
- if (now > last_clear + 10) {
- last_clear = now;
- X_LOCK;
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- Window w = windows_8bpp[i].win;
- if (! valid_window(w, &attr, 1)) {
- /* catch windows that went away: */
- windows_8bpp[i].win = None;
- windows_8bpp[i].top = None;
- windows_8bpp[i].map_state = IsUnmapped;
- windows_8bpp[i].cmap = (Colormap) 0;
- windows_8bpp[i].fetched = 0;
- windows_8bpp[i].last_fetched = -1.0;
- }
- }
- X_UNLOCK;
- }
-
- MV_count = 0;
- MV_hit = 0;
- MV_start = dnow();
-
- set_root_cmap();
-
- /* loop over all toplevels, both 8 and 24 depths: */
-
- X_LOCK; /* a giant lock around the whole activity */
-
- for (k=0; k < stack_list_num; k++) {
- Window r, parent;
- Window *list0;
- Status rc;
- unsigned int nc0;
- int i1;
- XErrorHandler old_handler;
- double delay;
-
- Window win = stack_list[k].win;
-
- /* TUNABLE */
- if (poll_8to24_delay >= POLL_8TO24_DELAY) {
- delay = 1.5 * poll_8to24_delay;
- } else {
- delay = 1.5 * POLL_8TO24_DELAY; /* 0.075 */
- }
-
- if (now < last_query + delay) {
- break;
- }
-
- if (win == None) {
- continue;
- }
-
- if (stack_list[k].map_state != IsViewable) {
- int i;
- /*
- * if the toplevel became unmapped, mark it
- * for the children as well...
- */
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- if (windows_8bpp[i].top == win) {
- windows_8bpp[i].map_state =
- stack_list[k].map_state;
- }
- }
- }
-
- if (check_depth(win, win, doall)) {
- /*
- * returns 1 if no need to recurse down e.g. It
- * is 8bpp and we assume all lower ones are too.
- */
- continue;
- }
-
- /* we recurse up to two levels down from stack_list windows */
-
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
- rc = XQueryTree_wr(dpy, win, &r, &parent, &list0, &nc0);
- XSetErrorHandler(old_handler);
-
- if (! rc || trapped_xerror) {
- trapped_xerror = 0;
- continue;
- }
- trapped_xerror = 0;
-
- /* loop over grandchildren of rootwin: */
- for (i1=0; i1 < (int) nc0; i1++) {
- Window win1 = list0[i1];
- Window *list1;
- unsigned int nc1;
- int i2;
-
- if (check_depth(win1, win, doall)) {
- continue;
- }
-
- if (level2_8to24) {
- continue;
- }
-
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
- rc = XQueryTree_wr(dpy, win1, &r, &parent, &list1, &nc1);
- XSetErrorHandler(old_handler);
-
- if (! rc || trapped_xerror) {
- trapped_xerror = 0;
- continue;
- }
- trapped_xerror = 0;
-
- /* loop over great-grandchildren of rootwin: */
- for (i2=0; i2< (int) nc1; i2++) {
- Window win2 = list1[i2];
-
- if (check_depth(win2, win, doall)) {
- continue;
- }
- /* more? Which wm does this? */
- }
- if (nc1) {
- XFree_wr(list1);
- }
- }
- if (nc0) {
- XFree_wr(list0);
- }
- }
- X_UNLOCK;
-
- last_query = dnow();
-
-MV_glob += MV_count;
-if (0) fprintf(stderr, "MV_count: %d hit: %d %.4f %10.2f\n", MV_count, MV_hit, last_query - MV_start, MV_glob / (last_query - x11vnc_start));
-
- if (screen_fixup_8 > 0.0 && now > last_fixup + screen_fixup_8) {
- last_fixup = now;
- mark_8bpp(MARK_8BPP_ALL);
- last_poll = now;
-
- } else if (poll_8to24_delay > 0.0) {
- int area = -1;
- int validate = 0;
-
- if (diff && multivis_count) {
- validate = 1;
- }
- if (now > last_poll + poll_8to24_delay) {
- sraRegionPtr mod;
-
- last_poll = now;
- mod = sraRgnCreate();
- area = poll_8bpp(mod, validate);
- if (depth == 24) {
- poll_8bpp_complement(mod);
- }
- mark_rgn_rects(mod);
- sraRgnDestroy(mod);
- }
- if (0 && area < dpy_x * dpy_y / 2 && diff && multivis_count) {
- mark_8bpp(MARK_8BPP_POINTER);
- last_poll = now;
- }
-
- } else if (diff && multivis_count) {
- mark_8bpp(MARK_8BPP_ALL);
- last_poll = now;
-
- } else if (depth <= 16 && multivis_24count) {
- static double last_check = 0.0;
- if (now > last_check + 0.4) {
- last_check = now;
- if (check_pointer_in_depth24()) {
- last_poll = now;
- }
- }
- }
-if (0) fprintf(stderr, "done: %.4f\n", dnow() - last_query);
-#endif /* NO_X11 */
-}
-
-#define VW_CACHE_MAX 1024
-static XWindowAttributes vw_cache_attr[VW_CACHE_MAX];
-static Window vw_cache_win[VW_CACHE_MAX];
-
-static void set_attr(XWindowAttributes *attr, int j) {
- memcpy((void *) (vw_cache_attr+j), (void *) attr,
- sizeof(XWindowAttributes));
-}
-#if 0
-static int get_attr(XWindowAttributes *attr, int j) {
- memcpy((void *) attr, (void *) (vw_cache_attr+j),
- sizeof(XWindowAttributes));
- return 1;
-}
-#endif
-
-static XWindowAttributes wattr;
-
-static XWindowAttributes *vw_lookup(Window win) {
- static double last_purge = 0.0;
- double now;
- int i, j, k;
-
- if (win == None) {
- return NULL;
- }
-
- now = dnow();
- if (now > last_purge + cache_win) {
- last_purge = now;
- for (i=0; i<VW_CACHE_MAX; i++) {
- vw_cache_win[i] = None;
- }
- }
-
- j = -1;
- k = -1;
- for (i=0; i<VW_CACHE_MAX; i++) {
- if (vw_cache_win[i] == win) {
- j = i;
- break;
- } else if (vw_cache_win[i] == None) {
- k = i;
- break;
- }
- }
-
- if (j >= 0) {
-MV_hit++;
- return vw_cache_attr+j;
-
- } else if (k >= 0) {
- XWindowAttributes attr2;
- int rc = valid_window(win, &attr2, 1);
- if (rc) {
- vw_cache_win[k] = win;
- set_attr(&attr2, k);
- return vw_cache_attr+k;
- } else {
- return NULL;
- }
- } else {
- /* Full */
- int rc = valid_window(win, &wattr, 1);
- if (rc) {
- return &wattr;
- } else {
- return NULL;
- }
- }
-}
-
-static int check_depth(Window win, Window top, int doall) {
- XWindowAttributes attr, *pattr;
-
- /* first see if it is (still) a valid window: */
-MV_count++;
-
- if (cache_win > 0.0) {
- pattr = vw_lookup(win);
- if (pattr == NULL) {
- return 1; /* indicate done */
- }
- } else {
- if (! valid_window(win, &attr, 1)) {
- return 1; /* indicate done */
- }
- pattr = &attr;
- }
-
- if (! doall && pattr->map_state != IsViewable) {
- /*
- * store results anyway... this may lead to table
- * filling up, but currently this allows us to update
- * state of onetime mapped windows.
- */
- check_depth_win(win, top, pattr);
- return 1; /* indicate done */
- } else if (check_depth_win(win, top, pattr)) {
- return 1; /* indicate done */
- } else {
- return 0; /* indicate not done */
- }
-}
-
-static int check_depth_win(Window win, Window top, XWindowAttributes *attr) {
- int store_it = 0;
- /*
- * only store windows with depth not equal to the default visual's
- * depth note some windows can have depth == 0 ... (skip them).
- */
- if (attr->depth > 0) {
- if (depth == 24 && attr->depth != 24) {
- store_it = 1;
- } else if (depth <= 16 && root_cmap && attr->colormap != root_cmap) {
- store_it = 1;
- }
- }
-
- if (store_it) {
- int i, j = -1, none = -1, nomap = -1;
- int newc = 0;
- if (attr->map_state == IsViewable) {
- /* count the visible ones: */
- multivis_count++;
- if (attr->depth == 24) {
- multivis_24count++;
- }
-if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr->depth);
- }
-
- /* try to find a table slot for this window: */
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- if (none < 0 && windows_8bpp[i].win == None) {
- /* found first None */
- none = i;
- }
- if (windows_8bpp[i].win == win) {
- /* found myself */
- j = i;
- break;
- }
- if (nomap < 0 && windows_8bpp[i].win != None &&
- windows_8bpp[i].map_state != IsViewable) {
- /* found first unmapped */
- nomap = i;
- }
- }
- if (j < 0) {
- if (attr->map_state != IsViewable) {
- /* no slot and not visible: not worth keeping */
- return 1;
- } else if (none >= 0) {
- /* put it in the first None slot */
- j = none;
- newc = 1;
- } else if (nomap >=0) {
- /* put it in the first unmapped slot */
- j = nomap;
- }
- /* otherwise we cannot store it... */
- }
-
-if (db24 > 1) fprintf(stderr, "multivis: 0x%lx ms: %d j: %d no: %d nm: %d dep=%d\n", win, attr->map_state, j, none, nomap, attr->depth);
-
- /* store if if we found a slot j: */
- if (j >= 0) {
- Window w;
- int x, y;
- int now_vis = 0;
-
- if (attr->map_state == IsViewable &&
- windows_8bpp[j].map_state != IsViewable) {
- now_vis = 1;
- }
-if (db24 > 1) fprintf(stderr, "multivis: STORE 0x%lx j: %3d ms: %d dep=%d\n", win, j, attr->map_state, attr->depth);
- windows_8bpp[j].win = win;
- windows_8bpp[j].top = top;
- windows_8bpp[j].depth = attr->depth;
- windows_8bpp[j].map_state = attr->map_state;
- windows_8bpp[j].cmap = attr->colormap;
- windows_8bpp[j].map_installed = attr->map_installed;
- windows_8bpp[j].w = attr->width;
- windows_8bpp[j].h = attr->height;
- windows_8bpp[j].fetched = 1;
- windows_8bpp[j].last_fetched = dnow();
-
- /* translate x y to be WRT the root window (not parent) */
- xtranslate(win, window, 0, 0, &x, &y, &w, 1);
- windows_8bpp[j].x = x;
- windows_8bpp[j].y = y;
-
- if (newc || now_vis) {
-if (db24) fprintf(stderr, "new/now_vis: 0x%lx %d/%d\n", win, newc, now_vis);
- /* mark it immediately if a new one: */
- X_UNLOCK; /* dont forget the giant lock */
- mark_rect_as_modified(x, y, x + attr->width,
- y + attr->height, 0);
- X_LOCK;
- }
- } else {
- /*
- * Error: could not find a slot.
- * perhaps keep age and expire old ones??
- */
-if (db24) fprintf(stderr, "multivis: CANNOT STORE 0x%lx j=%d\n", win, j);
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
-if (db24 > 1) fprintf(stderr, " ------------ 0x%lx i=%d\n", windows_8bpp[i].win, i);
- }
-
- }
- return 1;
- }
- return 0;
-}
-
-/* polling line XImage */
-static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w) {
- RAWFB_RET(NULL)
-
-#if NO_X11
- if (!xi || !visual || !win_depth || !w) {}
- return NULL;
-#else
- if (xi == NULL || *w < dpy_x) {
- char *d;
- if (xi) {
- XDestroyImage(xi);
- }
- if (win_depth != 24) {
- if (win_depth > 8) {
- d = (char *) malloc(dpy_x * 2);
- } else {
- d = (char *) malloc(dpy_x * 1);
- }
- } else {
- d = (char *) malloc(dpy_x * 4);
- }
- *w = dpy_x;
- xi = XCreateImage(dpy, visual, win_depth, ZPixmap, 0, d,
- dpy_x, 1, 8, 0);
- }
- return xi;
-#endif /* NO_X11 */
-}
-
-static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
-#if NO_X11
- RAWFB_RET(1)
- if (!x1 || !x2 || !y1 || !n || !mod) {}
- return 1;
-#else
- int fac, n_off, w, xo, yo;
- char *poll_fb, *dst, *src;
- int w2, xl, xh, stride = 32;
- int inrun = 0, rx1 = -1, rx2 = -1;
-
- static XImage *xi8 = NULL, *xi24 = NULL, *xi_r;
- static int xi8_w = 0, xi24_w = 0;
-
- XErrorHandler old_handler = NULL;
- XImage *xi;
- Window c, win = windows_8bpp[n].win;
-
- static XWindowAttributes attr;
- static Window last_win = None;
- static double last_time = 0.0;
- double now;
-
- sraRegionPtr rect;
- int mx1, mx2, my1, my2;
- int ns = NSCAN/2;
-
- RAWFB_RET(1)
-
- if (win == None) {
- return 1;
- }
- if (windows_8bpp[n].map_state != IsViewable) {
- return 1;
- }
- if (! xgetimage_8to24) {
- return 1;
- }
-
- X_LOCK;
- now = dnow();
- if (last_win != None && win == last_win && now < last_time + 0.5) {
- ; /* use previous attr */
- } else {
- if (! valid_window(win, &attr, 1)) {
- X_UNLOCK;
- last_win = None;
- return 0;
- }
- last_time = now;
- last_win = win;
- }
-
- if (attr.depth > 16 && attr.depth != 24) {
- X_UNLOCK;
- return 1;
- } else if (attr.depth <= 16) {
- xi = xi8 = p_xi(xi8, attr.visual, attr.depth, &xi8_w);
-
- poll_fb = poll8_fb;
- if (attr.depth > 8) {
- fac = 2;
- } else {
- fac = 1;
- }
- n_off = poll8_fb_w * y1 + x1;
- } else {
- xi = xi24 = p_xi(xi24, attr.visual, 24, &xi24_w);
-
- poll_fb = poll24_fb;
- fac = 4;
- n_off = poll24_fb_w * y1 + x1;
- }
-
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
-
- /* xtranslate() not used to save two XSetErrorHandler calls */
- XTranslateCoordinates(dpy, win, window, 0, 0, &xo, &yo, &c);
-
- xo = x1 - xo;
- yo = y1 - yo;
- w = x2 - x1;
-
- if (trapped_xerror || xo < 0 || yo < 0 || xo + w > attr.width) {
-if (db24 > 2) fprintf(stderr, "avoid bad match...\n");
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
- X_UNLOCK;
- return 0;
- }
-
- trapped_xerror = 0;
- xi_r = XGetSubImage(dpy, win, xo, yo, w, 1, AllPlanes, ZPixmap, xi,
- 0, 0);
- XSetErrorHandler(old_handler);
-
- X_UNLOCK;
-
- if (! xi_r || trapped_xerror) {
- trapped_xerror = 0;
- return 0;
- }
- trapped_xerror = 0;
-
- src = xi->data;
- dst = poll_fb + fac * n_off;
-
- inrun = 0;
-
- xl = x1;
- while (xl < x2) {
- xh = xl + stride;
- if (xh > x2) {
- xh = x2;
- }
- w2 = xh - xl;
- if (memcmp(dst, src, fac * w2)) {
- if (inrun) {
- rx2 = xh;
- } else {
- rx1 = xl;
- rx2 = xh;
- inrun = 1;
- }
- } else {
- if (inrun) {
- mx1 = rx1;
- mx2 = rx2;
- my1 = nfix(y1 - ns, dpy_y);
- my2 = nfix(y1 + ns, dpy_y+1);
-
- rect = sraRgnCreateRect(mx1, my1, mx2, my2);
- sraRgnOr(mod, rect);
- sraRgnDestroy(rect);
- inrun = 0;
- }
- }
-
- xl += stride;
- dst += fac * stride;
- src += fac * stride;
- }
-
- if (inrun) {
- mx1 = rx1;
- mx2 = rx2;
- my1 = nfix(y1 - ns, dpy_y);
- my2 = nfix(y1 + ns, dpy_y+1);
-
- rect = sraRgnCreateRect(mx1, my1, mx2, my2);
- sraRgnOr(mod, rect);
- sraRgnDestroy(rect);
- }
- return 1;
-#endif /* NO_X11 */
-}
-
-static void poll_line_complement(int x1, int x2, int y1, sraRegionPtr mod) {
- int n_off, w, xl, xh, stride = 32;
- char *dst, *src;
- int inrun = 0, rx1 = -1, rx2 = -1;
- sraRegionPtr rect;
- int mx1, mx2, my1, my2;
- int ns = NSCAN/2;
-
- if (depth != 24) {
- return;
- }
- if (! cmap8to24_fb) {
- return;
- }
- if (! xgetimage_8to24) {
- return;
- }
-
- n_off = main_bytes_per_line * y1 + 4 * x1;
-
- src = main_fb + n_off;
- dst = cmap8to24_fb + n_off;
-
- inrun = 0;
-
- xl = x1;
- while (xl < x2) {
- xh = xl + stride;
- if (xh > x2) {
- xh = x2;
- }
- w = xh - xl;
- if (memcmp(dst, src, 4 * w)) {
- if (inrun) {
- rx2 = xh;
- } else {
- rx1 = xl;
- rx2 = xh;
- inrun = 1;
- }
- } else {
- if (inrun) {
- mx1 = rx1;
- mx2 = rx2;
- my1 = nfix(y1 - ns, dpy_y);
- my2 = nfix(y1 + ns, dpy_y+1);
-
- rect = sraRgnCreateRect(mx1, my1, mx2, my2);
- sraRgnOr(mod, rect);
- sraRgnDestroy(rect);
-
- inrun = 0;
- }
- }
-
- xl += stride;
- dst += 4 * stride;
- src += 4 * stride;
- }
-
- if (inrun) {
- mx1 = rx1;
- mx2 = rx2;
- my1 = nfix(y1 - ns, dpy_y);
- my2 = nfix(y1 + ns, dpy_y+1);
-
- rect = sraRgnCreateRect(mx1, my1, mx2, my2);
- sraRgnOr(mod, rect);
- sraRgnDestroy(rect);
-
- inrun = 0;
- }
-}
-
-#define CMAPMAX 64
-static Colormap cmaps[CMAPMAX];
-static int ncmaps;
-
-static int poll_8bpp(sraRegionPtr mod, int validate) {
- int i, y, ysh, map_count;
- static int ycnt = 0;
- sraRegionPtr line;
- sraRect rect;
- sraRectangleIterator *iter;
- int br = 0, area = 0;
- static double last_call = 0.0;
-
- map_count = get_8bpp_regions(validate);
-
-if (db24 > 1) fprintf(stderr, "poll_8bpp mc: %d\n", map_count);
-
- if (! map_count) {
- return 0;
- }
-
- set_poll_fb();
-
- ysh = scanlines[(ycnt++) % NSCAN];
-if (db24 > 2) fprintf(stderr, "poll_8bpp: ysh: %2d %.4f\n", ysh, dnow() - last_call);
- last_call = dnow();
-
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- sraRegionPtr reg = windows_8bpp[i].clip_region;
-
- if (! reg || sraRgnEmpty(reg)) {
- continue;
- }
- y = ysh;
- while (y < dpy_y) {
- line = sraRgnCreateRect(0, y, dpy_x, y+1);
-
- if (sraRgnAnd(line, reg)) {
- iter = sraRgnGetIterator(line);
- while (sraRgnIteratorNext(iter, &rect)) {
- if (! poll_line(rect.x1, rect.x2,
- rect.y1, i, mod)) {
- br = 1;
- break; /* exception */
- }
- }
- sraRgnReleaseIterator(iter);
- }
-
- sraRgnDestroy(line);
- y += NSCAN;
- if (br) break;
- }
- if (br) break;
- }
-
- iter = sraRgnGetIterator(mod);
- while (sraRgnIteratorNext(iter, &rect)) {
- area += nabs((rect.x2 - rect.x1)*(rect.y2 - rect.y1));
- }
- sraRgnReleaseIterator(iter);
-
- return area;
-}
-
-static void poll_8bpp_complement(sraRegionPtr mod) {
- int i, y, ysh;
- static int ycnt = 0;
- sraRegionPtr disp, line;
- sraRect rect;
- sraRectangleIterator *iter;
-
- disp = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
-
- ysh = scanlines[(ycnt++) % NSCAN];
-
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- sraRegionPtr reg = windows_8bpp[i].clip_region;
-
- if (! reg) {
- continue;
- }
- if (windows_8bpp[i].map_state != IsViewable) {
- continue;
- }
- sraRgnSubtract(disp, reg);
- }
-
- y = ysh;
- while (y < dpy_y) {
- line = sraRgnCreateRect(0, y, dpy_x, y+1);
-
- if (sraRgnAnd(line, disp)) {
- iter = sraRgnGetIterator(line);
- while (sraRgnIteratorNext(iter, &rect)) {
- poll_line_complement(rect.x1, rect.x2,
- rect.y1, mod);
- }
- sraRgnReleaseIterator(iter);
- }
-
- sraRgnDestroy(line);
-
- y += NSCAN;
- }
-
- sraRgnDestroy(disp);
-}
-
-static void mark_rgn_rects(sraRegionPtr mod) {
- sraRect rect;
- sraRectangleIterator *iter;
- int area = 0;
-
- if (sraRgnEmpty(mod)) {
- return;
- }
-
- iter = sraRgnGetIterator(mod);
- while (sraRgnIteratorNext(iter, &rect)) {
- mark_rect_as_modified(rect.x1, rect.y1, rect.x2, rect.y2, 0);
- area += nabs((rect.x2 - rect.x1)*(rect.y2 - rect.y1));
- }
- sraRgnReleaseIterator(iter);
-
-if (db24 > 1) fprintf(stderr, " mark_rgn_rects area: %d\n", area);
-}
-
-static int get_8bpp_regions(int validate) {
-
- XWindowAttributes attr;
- int i, k, mapcount = 0;
-
- /* initialize color map list */
- ncmaps = 0;
- for (i=0; i < CMAPMAX; i++) {
- cmaps[i] = (Colormap) 0;
- }
-
- /* loop over the table of 8bpp windows: */
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- sraRegionPtr tmp_reg, tmp_reg2;
- Window c, w = windows_8bpp[i].win;
- int x, y;
-
- if (windows_8bpp[i].clip_region) {
- sraRgnDestroy(windows_8bpp[i].clip_region);
- }
- windows_8bpp[i].clip_region = NULL;
-
- if (w == None) {
- continue;
- }
-
-if (db24 > 1) fprintf(stderr, "get_8bpp_regions: 0x%lx ms=%d dep=%d i=%d\n", w, windows_8bpp[i].map_state, windows_8bpp[i].depth, i);
- if (validate) {
- /*
- * this could be slow: validating 8bpp windows each
- * time...
- */
-
- X_LOCK;
- if (! valid_window(w, &attr, 1)) {
- X_UNLOCK;
- windows_8bpp[i].win = None;
- windows_8bpp[i].top = None;
- windows_8bpp[i].map_state = IsUnmapped;
- windows_8bpp[i].cmap = (Colormap) 0;
- windows_8bpp[i].fetched = 0;
- windows_8bpp[i].last_fetched = -1.0;
- continue;
- }
- X_UNLOCK;
-
- windows_8bpp[i].depth = attr.depth;
- windows_8bpp[i].map_state = attr.map_state;
- windows_8bpp[i].cmap = attr.colormap;
- windows_8bpp[i].map_installed = attr.map_installed;
- windows_8bpp[i].w = attr.width;
- windows_8bpp[i].h = attr.height;
- windows_8bpp[i].fetched = 1;
- windows_8bpp[i].last_fetched = dnow();
-
- if (attr.map_state != IsViewable) {
- continue;
- }
-
- X_LOCK;
- xtranslate(w, window, 0, 0, &x, &y, &c, 1);
- X_UNLOCK;
- windows_8bpp[i].x = x;
- windows_8bpp[i].y = y;
-
- } else {
- /* this will be faster: no call to X server: */
- if (windows_8bpp[i].map_state != IsViewable) {
- continue;
- }
- attr.depth = windows_8bpp[i].depth;
- attr.map_state = windows_8bpp[i].map_state;
- attr.colormap = windows_8bpp[i].cmap;
- attr.map_installed = windows_8bpp[i].map_installed;
- attr.width = windows_8bpp[i].w;
- attr.height = windows_8bpp[i].h;
-
- x = windows_8bpp[i].x;
- y = windows_8bpp[i].y;
- }
-
- mapcount++;
-
- /* tmp region for this 8bpp rectangle: */
- tmp_reg = sraRgnCreateRect(nfix(x, dpy_x), nfix(y, dpy_y),
- nfix(x + attr.width, dpy_x+1), nfix(y + attr.height, dpy_y+1));
-
- /* loop over all toplevels, top to bottom clipping: */
- for (k = stack_list_num - 1; k >= 0; k--) {
- Window swin = stack_list[k].win;
- int sx, sy, sw, sh;
-
-if (db24 > 1 && stack_list[k].map_state == IsViewable) fprintf(stderr, "Stack win: 0x%lx %d iv=%d\n", swin, k, stack_list[k].map_state);
-
- if (swin == windows_8bpp[i].top) {
- /* found our top level: we skip the rest. */
-if (db24 > 1) fprintf(stderr, "found top: 0x%lx %d iv=%d\n", swin, k, stack_list[k].map_state);
- break;
- }
- if (stack_list[k].map_state != IsViewable) {
- /* skip unmapped ones: */
- continue;
- }
-
- /* make a temp rect for this toplevel: */
- sx = stack_list[k].x;
- sy = stack_list[k].y;
- sw = stack_list[k].width;
- sh = stack_list[k].height;
-
-if (db24 > 1) fprintf(stderr, "subtract: 0x%lx %d -- %d %d %d %d\n", swin, k, sx, sy, sw, sh);
-
- tmp_reg2 = sraRgnCreateRect(nfix(sx, dpy_x),
- nfix(sy, dpy_y), nfix(sx + sw, dpy_x+1),
- nfix(sy + sh, dpy_y+1));
-
- /* subtract it from the 8bpp window region */
- sraRgnSubtract(tmp_reg, tmp_reg2);
-
- sraRgnDestroy(tmp_reg2);
-
- if (sraRgnEmpty(tmp_reg)) {
- break;
- }
- }
-
- if (sraRgnEmpty(tmp_reg)) {
- /* skip this 8bpp if completely clipped away: */
- sraRgnDestroy(tmp_reg);
- continue;
- }
-
- /* otherwise, store any new colormaps: */
- if (ncmaps < CMAPMAX && attr.colormap != (Colormap) 0) {
- int m, seen = 0;
- for (m=0; m < ncmaps; m++) {
- if (cmaps[m] == attr.colormap) {
- seen = 1;
- break;
- }
- }
- if (!seen && attr.depth <= 16) {
- /* store only new ones: */
- cmaps[ncmaps++] = attr.colormap;
- }
- }
-
- windows_8bpp[i].clip_region = tmp_reg;
- }
-
- return mapcount;
-}
-
-static XColor *color[CMAPMAX];
-static unsigned int *rgb[CMAPMAX];
-static int cmap_failed[CMAPMAX];
-static int color_init = 0;
-int histo[65536];
-
-static int get_cmap(int j, Colormap cmap) {
-#if NO_X11
- RAWFB_RET(0)
- if (!j || !cmap) {}
- return 0;
-#else
- int i, ncells, ncolor;
- XErrorHandler old_handler = NULL;
-
- RAWFB_RET(0)
-
- if (depth > 16) {
- /* 24 */
- ncolor = NCOLOR;
- } else if (depth > 8) {
- ncolor = 1 << depth;
- } else {
- ncolor = NCOLOR;
- }
- if (!color_init) {
- int cm;
- for (cm = 0; cm < CMAPMAX; cm++) {
- color[cm] = (XColor *) malloc(ncolor * sizeof(XColor));
- rgb[cm] = (unsigned int *) malloc(ncolor * sizeof(unsigned int));
- }
- color_init = 1;
- }
-
- if (depth <= 16) {
- /* not working properly for depth 24... */
- X_LOCK;
- ncells = CellsOfScreen(ScreenOfDisplay(dpy, scr));
- X_UNLOCK;
- } else {
- ncells = NCOLOR;
- }
-
- if (depth > 16) {
- ;
- } else if (ncells > ncolor) {
- ncells = ncolor;
- } else if (ncells == 8 && depth != 3) {
- /* XXX. see set_colormap() */
- ncells = 1 << depth;
- }
-
- /* initialize XColor array: */
- for (i=0; i < ncells; i++) {
- color[j][i].pixel = i;
- color[j][i].pad = 0;
- }
-if (db24 > 1) fprintf(stderr, "get_cmap: %d 0x%x ncolor=%d ncells=%d\n", j, (unsigned int) cmap, ncolor, ncells);
-
- /* try to query the colormap, trap errors */
- X_LOCK;
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
- XQueryColors(dpy, cmap, color[j], ncells);
- XSetErrorHandler(old_handler);
- X_UNLOCK;
-
- if (trapped_xerror) {
- trapped_xerror = 0;
- return 0;
- }
- trapped_xerror = 0;
-
- /* now map each index to depth 24 RGB */
- for (i=0; i < ncells; i++) {
- unsigned int red, green, blue;
- /* strip out highest 8 bits of values: */
- red = (color[j][i].red & 0xff00) >> 8;
- green = (color[j][i].green & 0xff00) >> 8;
- blue = (color[j][i].blue & 0xff00) >> 8;
-
- /*
- * the maxes should be at 255 already,
- * but just in case...
- */
- red = (main_red_max * red )/255;
- green = (main_green_max * green)/255;
- blue = (main_blue_max * blue )/255;
-
-if (db24 > 2) fprintf(stderr, " cmap[%02d][%03d]: %03d %03d %03d 0x%08x \n", j, i, red, green, blue, ( red << main_red_shift | green << main_green_shift | blue << main_blue_shift));
-
- /* shift them over and or together for value */
- red = red << main_red_shift;
- green = green << main_green_shift;
- blue = blue << main_blue_shift;
-
- /* store it in the array to be used later */
- rgb[j][i] = red | green | blue;
- }
- return 1;
-#endif /* NO_X11 */
-}
-
-static void do_8bpp_region(int n, sraRegionPtr mark) {
- int k, cm = -1, failed = 0;
- sraRectangleIterator *iter;
- sraRegionPtr clip;
- sraRect rect;
-
- if (! windows_8bpp[n].clip_region) {
- return;
- }
- if (windows_8bpp[n].win == None) {
- return;
- }
- if (windows_8bpp[n].map_state != IsViewable) {
- return;
- }
-if (db24 > 1) fprintf(stderr, "ncmaps: %d\n", ncmaps);
-
- /* see if XQueryColors failed: */
- for (k=0; k<ncmaps; k++) {
- if (windows_8bpp[n].cmap == cmaps[k]) {
- cm = k;
- if (cmap_failed[k]) {
- failed = 1;
- }
- break;
- }
- }
-
- if (windows_8bpp[n].depth != 24) { /* 24 won't have a cmap */
- if (failed || cm == -1) {
- return;
- }
- }
-
- clip = sraRgnCreateRgn(mark);
- sraRgnAnd(clip, windows_8bpp[n].clip_region);
-
- /* loop over the rectangles making up region */
- iter = sraRgnGetIterator(clip);
- while (sraRgnIteratorNext(iter, &rect)) {
- if (rect.x1 > rect.x2) {
- int tmp = rect.x2;
- rect.x2 = rect.x1;
- rect.x1 = tmp;
- }
- if (rect.y1 > rect.y2) {
- int tmp = rect.y2;
- rect.y2 = rect.y1;
- rect.y1 = tmp;
- }
-
- transform_rect(rect, windows_8bpp[n].win,
- windows_8bpp[n].depth, cm);
- }
- sraRgnReleaseIterator(iter);
- sraRgnDestroy(clip);
-}
-
-static XImage *cmap_xi(XImage *xi, Window win, int win_depth) {
-#if NO_X11
- if (!xi || !win || !win_depth) {}
- return NULL;
-#else
- XWindowAttributes attr;
- char *d;
-
- if (xi) {
- XDestroyImage(xi);
- }
- if (! dpy || ! valid_window(win, &attr, 1)) {
- return (XImage *) NULL;
- }
- if (win_depth == 24) {
- d = (char *) malloc(dpy_x * dpy_y * 4);
- } else if (win_depth <= 16) {
- if (win_depth > 8) {
- d = (char *) malloc(dpy_x * dpy_y * 2);
- } else {
- d = (char *) malloc(dpy_x * dpy_y * 1);
- }
- } else {
- return (XImage *) NULL;
- }
- return XCreateImage(dpy, attr.visual, win_depth, ZPixmap, 0, d, dpy_x, dpy_y, 8, 0);
-#endif /* NO_X11 */
-}
-
-
-static void transform_rect(sraRect rect, Window win, int win_depth, int cm) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!rect.x1 || !win || !win_depth || !cm) {}
- return;
-#else
-
- char *src, *dst, *poll;
- unsigned int *ui;
- unsigned short *us;
- unsigned char *uc;
- int ps, pixelsize = bpp/8;
- int poll_Bpl;
-
- int do_getimage = xgetimage_8to24;
- int line, n_off, j, h, w;
- unsigned int hi, idx;
- XWindowAttributes attr;
- XErrorHandler old_handler = NULL;
-
-if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rect.y1, rect.x2, rect.y2, cm);
-
- RAWFB_RET_VOID
-
- attr.width = 0;
- attr.height = 0;
-
- /* now transform the pixels in this rectangle: */
- n_off = main_bytes_per_line * rect.y1 + pixelsize * rect.x1;
-
- h = rect.y2 - rect.y1;
- w = rect.x2 - rect.x1;
-
- if (depth != 24) {
- /* need to fetch depth 24 data. */
- do_getimage = 1;
- }
-
-#if 0
- if (do_getimage) {
- X_LOCK;
- vw = valid_window(win, &attr, 1);
- X_UNLOCK;
- }
-
- if (do_getimage && vw) {
-#else
- if (do_getimage) {
-#endif
- static XImage *xi_8 = NULL;
- static XImage *xi_24 = NULL;
- XImage *xi = NULL, *xi_r;
- Window c;
- unsigned int wu, hu;
- int xo, yo;
-
- wu = (unsigned int) w;
- hu = (unsigned int) h;
-
- X_LOCK;
-#define GETSUBIMAGE
-#ifdef GETSUBIMAGE
- if (win_depth == 24) {
- if (xi_24 == NULL || xi_24->width != dpy_x ||
- xi_24->height != dpy_y) {
- xi_24 = cmap_xi(xi_24, win, 24);
- }
- xi = xi_24;
- } else if (win_depth <= 16) {
- if (xi_8 == NULL || xi_8->width != dpy_x ||
- xi_8->height != dpy_y) {
- if (win_depth > 8) {
- /* XXX */
- xi_8 = cmap_xi(xi_8, win, 16);
- } else {
- xi_8 = cmap_xi(xi_8, win, 8);
- }
- }
- xi = xi_8;
- }
-#endif
-
- if (xi == NULL) {
- rfbLog("transform_rect: xi is NULL\n");
- X_UNLOCK;
- clean_up_exit(1);
- }
-
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
-
- XTranslateCoordinates(dpy, win, window, 0, 0, &xo, &yo, &c);
-
- xo = rect.x1 - xo;
- yo = rect.y1 - yo;
-
-if (db24 > 1) fprintf(stderr, "xywh: %d %d %d %d vs. %d %d\n", xo, yo, w, h, attr.width, attr.height);
-
- if (trapped_xerror || xo < 0 || yo < 0) {
- /* w > attr.width || h > attr.height */
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- trapped_xerror = 0;
-if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
- return;
- }
- trapped_xerror = 0;
-
-#ifndef GETSUBIMAGE
- xi = XGetImage(dpy, win, xo, yo, wu, hu, AllPlanes, ZPixmap);
- xi_r = xi;
-#else
- xi_r = XGetSubImage(dpy, win, xo, yo, wu, hu, AllPlanes,
- ZPixmap, xi, 0, 0);
-#endif
- XSetErrorHandler(old_handler);
-
- X_UNLOCK;
-
- if (! xi_r || trapped_xerror) {
- trapped_xerror = 0;
-if (db24 > 1) fprintf(stderr, "xi-fail: 0x%p trap=%d %d %d %d %d\n", (void *)xi, trapped_xerror, xo, yo, w, h);
- return;
- } else {
-if (db24 > 1) fprintf(stderr, "xi: 0x%p %d %d %d %d -- %d %d\n", (void *)xi, xo, yo, w, h, xi->width, xi->height);
- }
- trapped_xerror = 0;
-
- if (xi->depth > 16 && xi->depth != 24) {
-#ifndef GETSUBIMAGE
- X_LOCK;
- XDestroyImage(xi);
- X_UNLOCK;
-#endif
-if (db24) fprintf(stderr, "xi: wrong depth: %d\n", xi->depth);
- return;
- }
-
- set_poll_fb();
-
- if (xi->depth == 24) {
- /* line by line ... */
- int ps1 = 4, fac;
- if (depth <= 8) {
- fac = 4;
- } else if (depth <= 16) {
- fac = 2;
- } else {
- fac = 1; /* will not happen 24 on 24 */
- }
-
- src = xi->data;
- dst = cmap8to24_fb + fac * n_off;
-
- poll = poll24_fb + (poll24_fb_w * rect.y1 + rect.x1) * 4;
- poll_Bpl = poll24_fb_w * 4;
-
- for (line = 0; line < h; line++) {
- memcpy(dst, src, w * ps1);
- memcpy(poll, src, w * ps1);
-
- src += xi->bytes_per_line;
- dst += main_bytes_per_line * fac;
- poll += poll_Bpl;
- }
- } else if (xi->depth <= 16) {
- int ps1, ps2, fac;
-
- if (depth <= 8) {
- ps1 = 1;
- ps2 = 4;
- fac = 4;
- } else if (depth <= 16) {
- ps1 = 2;
- ps2 = 4;
- fac = 4;
- } else {
- /* should be 24 case */
- ps1 = 1;
- ps2 = pixelsize;
- fac = 1;
- }
-
- src = xi->data;
- dst = cmap8to24_fb + (fac/ps1) * n_off;
-
- poll = poll8_fb + poll8_fb_w * rect.y1 * ps1 + rect.x1 * ps1;
- poll_Bpl = poll8_fb_w * ps1;
-
- /* line by line ... */
- for (line = 0; line < h; line++) {
- /* pixel by pixel... */
- for (j = 0; j < w; j++) {
- if (ps1 == 2) {
- unsigned short *ptmp;
- us = (unsigned short *) (src + ps1 * j);
- idx = (int) (*us);
- ptmp = (unsigned short *) (poll + ps1 * j);
- *ptmp = *us;
- } else {
- uc = (unsigned char *) (src + ps1 * j);
- idx = (int) (*uc);
- *(poll + ps1 * j) = *uc;
- }
- ui = (unsigned int *) (dst + ps2 * j);
- *ui = rgb[cm][idx];
-
- }
- src += xi->bytes_per_line;
- dst += main_bytes_per_line * (fac/ps1);
- poll += poll_Bpl;
- }
- }
-
-#ifndef GETSUBIMAGE
- X_LOCK;
- XDestroyImage(xi);
- X_UNLOCK;
-#endif
-
- } else if (! do_getimage) {
- int fac;
-
- if (depth <= 16) {
- /* cooked up depth 24 TrueColor */
- /* but currently disabled (high bits no useful?) */
- ps = 4;
- fac = 4;
- /* XXX not correct for depth > 8, but do we ever come here in that case? */
- src = cmap8to24_fb + 4 * n_off;
- } else {
- ps = pixelsize;
- fac = 1;
- src = cmap8to24_fb + n_off;
- }
-
- /* line by line ... */
- for (line = 0; line < h; line++) {
- /* pixel by pixel... */
- for (j = 0; j < w; j++) {
-
- /* grab 32 bit value */
- ui = (unsigned int *) (src + ps * j);
-
- /* extract top 8 bits (FIXME: masks?) */
- hi = (*ui) & 0xff000000;
-
- /* map to lookup index; rewrite pixel */
- idx = hi >> 24;
- *ui = hi | rgb[cm][idx];
- }
- src += main_bytes_per_line * fac;
- }
- }
-#endif /* NO_X11 */
-}
-
-void bpp8to24(int x1, int y1, int x2, int y2) {
- char *src, *dst;
- unsigned char *uc;
- unsigned short *us;
- unsigned int *ui;
- int idx, pixelsize = bpp/8;
- int line, k, i, j, h, w;
- int n_off;
- sraRegionPtr rect;
- int validate = 1;
- static int last_map_count = 0, call_count = 0;
- static double last_get_8bpp_validate = 0.0;
- static double last_snapshot = 0.0;
- double now;
- double dt, d0 = 0.0, t2;
-
- RAWFB_RET_VOID
-
- if (! cmap8to24 || ! cmap8to24_fb) {
- /* hmmm, why were we called? */
- return;
- }
-
-if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, dnow() - last_get_8bpp_validate);
-
- call_count++;
-
- /* clip to display just in case: */
- if (!ncache) {
- x1 = nfix(x1, dpy_x);
- y1 = nfix(y1, dpy_y);
- x2 = nfix(x2, dpy_x+1);
- y2 = nfix(y2, dpy_y+1);
- }
-
- if (wireframe_in_progress) {
- /*
- * draw_box() manages cmap8to24_fb for us so we get out as
- * soon as we can. No need to cp main_fb -> cmap8to24_fb.
- */
- return;
- }
-
- /* copy from main_fb to cmap8to24_fb regardless of 8bpp windows: */
-
- h = y2 - y1;
- w = x2 - x1;
-
- if (depth == 24) {
- /* pixelsize = 4 */
- n_off = main_bytes_per_line * y1 + pixelsize * x1;
-
- src = main_fb + n_off;
- dst = cmap8to24_fb + n_off;
-
- /* otherwise, the pixel data as is */
- for (line = 0; line < h; line++) {
- memcpy(dst, src, w * pixelsize);
- src += main_bytes_per_line;
- dst += main_bytes_per_line;
- }
- } else if (depth <= 16) {
- /* need to cook up to depth 24 TrueColor */
- int ps1 = 1, ps2 = 4;
- if (depth > 8) {
- ps1 = 2;
- }
-
- /* pixelsize = 1, 2 */
- n_off = main_bytes_per_line * y1 + pixelsize * x1;
-
- src = main_fb + n_off;
- dst = cmap8to24_fb + (4/ps1) * n_off;
-
- set_root_cmap();
- if (root_cmap) {
-#if 0
- unsigned int hi;
-#endif
-
- /* line by line ... */
- for (line = 0; line < h; line++) {
- /* pixel by pixel... */
- for (j = 0; j < w; j++) {
- if (ps1 == 2) {
- us = (unsigned short *) (src + ps1 * j);
- idx = (int) (*us);
- } else {
- uc = (unsigned char *) (src + ps1 * j);
- idx = (int) (*uc);
- }
- ui = (unsigned int *) (dst + ps2 * j);
-
-if (0 && line % 100 == 0 && j % 32 == 0) fprintf(stderr, "%d %d %u x1=%d y1=%d\n", line, j, root_rgb[idx], x1, y1);
-#if 0
- if (do_hibits) {
- hi = idx << 24;
- *ui = hi | rgb[0][idx];
- } else {
- }
-#endif
- *ui = root_rgb[idx];
-if (db24 > 2) histo[idx]++;
- }
- src += main_bytes_per_line;
- dst += main_bytes_per_line * (4/ps1);
- }
- }
-
- }
-
- if (last_map_count > MAX_8BPP_WINDOWS/4) {
- /* table is filling up... skip validating sometimes: */
- int skip = 3;
- if (last_map_count > MAX_8BPP_WINDOWS/2) {
- skip = 6;
- } else if (last_map_count > 3*MAX_8BPP_WINDOWS/4) {
- skip = 12;
- }
- if (call_count % skip != 0) {
- validate = 0;
- }
- }
-
-if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
-
- now = dnow();
- dt = now - last_get_8bpp_validate;
- /* TUNABLES */
- if (dt < 0.003) {
- ; /* XXX does this still give painting errors? */
- } else {
- int snapit = 0;
- double delay1, delay2, delay3;
- if (poll_8to24_delay >= POLL_8TO24_DELAY) {
- delay1 = 1.0 * poll_8to24_delay;
- delay2 = 2.0 * poll_8to24_delay;
- delay3 = 10. * poll_8to24_delay;
- } else {
- delay1 = 1.0 * POLL_8TO24_DELAY; /* 0.05 */
- delay2 = 2.0 * POLL_8TO24_DELAY; /* 0.1 */
- delay3 = 10. * POLL_8TO24_DELAY; /* 0.5 */
- }
- if (cache_win > 1.0) {
- delay2 *= 2;
- delay3 *= 2;
- }
- if (dt < delay1) {
- validate = 0;
- }
- if (last_map_count) {
- if (now > last_snapshot + delay2) {
- snapit = 1;
- }
- } else {
- if (now > last_snapshot + delay3) {
- snapit = 1;
- }
- }
-
- if (snapit) {
- /* less problems if we update the stack frequently */
- snapshot_stack_list(0, 0.0);
-if (0) fprintf(stderr, "SNAP time: %.4f\n", dnow() - now);
- update_stack_list();
- last_snapshot = dnow();
-if (0) fprintf(stderr, "UPDA time: %.4f\n", last_snapshot - now);
- }
-
-if (0) t2 = dnow();
- last_map_count = get_8bpp_regions(validate);
- if (validate) {
- last_get_8bpp_validate = dnow();
- }
-if (0) fprintf(stderr, "get8bpp-%d: %.4f\n", validate, dnow() - t2);
- }
-if (db24) d0 = dnow();
-
-if (db24 > 1) fprintf(stderr, "bpp8to24 w=%d h=%d m=%p c=%p r=%p ncmaps=%d\n", w, h, main_fb, cmap8to24_fb, rfb_fb, ncmaps);
-
- /*
- * now go back and transform and 8bpp regions to TrueColor in
- * cmap8to24_fb.
- */
- if (last_map_count && (ncmaps || depth <= 16)) {
- int i, j;
- int win[MAX_8BPP_WINDOWS];
- int did[MAX_8BPP_WINDOWS];
- int count = 0;
-
- /*
- * first, grab all of the associated colormaps from the
- * X server. Hopefully just 1 or 2...
- */
- for (j=0; j<ncmaps; j++) {
- if (! get_cmap(j, cmaps[j])) {
- cmap_failed[j] = 1;
- } else {
- cmap_failed[j] = 0;
- }
-if (db24 > 2) fprintf(stderr, "cmap %d %.4f\n", (int) cmaps[j], dnow() - d0);
- }
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- sraRegionPtr reg = windows_8bpp[i].clip_region;
- if (reg) {
- rect = sraRgnCreateRect(x1, y1, x2, y2);
- if (sraRgnAnd(rect, reg)) {
- win[count] = i;
- did[count++] = 0;
- }
- sraRgnDestroy(rect);
- }
- }
-
- if (count) {
-
- rect = sraRgnCreateRect(x1, y1, x2, y2);
- /* try to apply lower windows first */
- for (k=0; k < stack_list_num; k++) {
- Window swin = stack_list[k].win;
- for (j=0; j<count; j++) {
- i = win[j];
- if (did[j]) {
- continue;
- }
- if (windows_8bpp[i].top == swin) {
- do_8bpp_region(i, rect);
- did[j] = 1;
- break;
- }
- }
- }
- for (j=0; j<count; j++) {
- if (! did[j]) {
- i = win[j];
- do_8bpp_region(i, rect);
- did[j] = 1;
- }
- }
- sraRgnDestroy(rect);
- }
- }
-if (0) fprintf(stderr, "done time: %.4f\n", dnow() - d0);
-
-if (db24 > 2) {for(i=0; i<256;i++) {fprintf(stderr, " cmap histo[%03d] %d\n", i, histo[i]);}}
-}
-
-void mark_8bpp(int mode) {
- int i, cnt = 0;
- Window top = None;
-
- RAWFB_RET_VOID
-
- if (! cmap8to24 || !cmap8to24_fb) {
- return;
- }
-
- if (mode == MARK_8BPP_TOP) {
- int k;
- for (k = stack_list_num - 1; k >= 0; k--) {
- Window swin = stack_list[k].win;
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- if (windows_8bpp[i].win == None) {
- continue;
- }
- if (windows_8bpp[i].map_state != IsViewable) {
- continue;
- }
- if (swin == windows_8bpp[i].top) {
- top = swin;
- break;
- }
- }
- if (top != None) {
- break;
- }
- }
- }
-
- /* for each mapped 8bpp window, mark it changed: */
-
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- int x1, y1, x2, y2, w, h, f = 32;
-
- f = 0; /* skip fuzz, may bring in other windows... */
-
- if (windows_8bpp[i].win == None) {
- continue;
- }
- if (mode == MARK_8BPP_TOP) {
- if (windows_8bpp[i].top != top) {
- continue;
- }
- }
- if (windows_8bpp[i].map_state != IsViewable) {
- XWindowAttributes attr;
- int vw = 0;
-
- X_LOCK;
- vw = valid_window(windows_8bpp[i].win, &attr, 1);
- X_UNLOCK;
- if (vw) {
- if (attr.map_state != IsViewable) {
- continue;
- }
- } else {
- continue;
- }
- }
-
- x1 = windows_8bpp[i].x;
- y1 = windows_8bpp[i].y;
- w = windows_8bpp[i].w;
- h = windows_8bpp[i].h;
-
- x2 = x1 + w;
- y2 = y1 + h;
-
- if (mode == MARK_8BPP_POINTER) {
- int b = 32; /* apply some fuzz for wm border */
- if (cursor_x < x1 - b || cursor_y < y1 - b) {
- continue;
- }
- if (cursor_x > x2 + b || cursor_y > y2 + b) {
- continue;
- }
- }
-
- /* apply fuzz f around each one; constrain to screen */
- x1 = nfix(x1 - f, dpy_x);
- y1 = nfix(y1 - f, dpy_y);
- x2 = nfix(x2 + f, dpy_x+1);
- y2 = nfix(y2 + f, dpy_y+1);
-
-if (db24 > 1) fprintf(stderr, "mark_8bpp: 0x%lx %d %d %d %d\n", windows_8bpp[i].win, x1, y1, x2, y2);
-
- mark_rect_as_modified(x1, y1, x2, y2, 0);
- cnt++;
- }
- if (cnt) {
- /* push it to viewers if possible. */
- rfbPE(-1);
- }
-}
-
-#endif /* SKIP_8TO24 */
-
diff --git a/x11vnc/8to24.h b/x11vnc/8to24.h
deleted file mode 100644
index d83412b..0000000
--- a/x11vnc/8to24.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_8TO24_H
-#define _X11VNC_8TO24_H
-
-/* -- 8to24.h -- */
-
-extern int multivis_count;
-extern int multivis_24count;
-
-extern void check_for_multivis(void);
-extern void bpp8to24(int, int, int, int);
-extern void mark_8bpp(int);
-
-#endif /* _X11VNC_8TO24_H */
diff --git a/x11vnc/ChangeLog b/x11vnc/ChangeLog
deleted file mode 100644
index 24e33b2..0000000
--- a/x11vnc/ChangeLog
+++ /dev/null
@@ -1,1257 +0,0 @@
-2010-12-29 Karl Runge <runge@karlrunge.com>
- * x11vnc: Use opengl to read screen on macosx. Experimental
- use of non-deprecated macosx interfaces for input injection.
- Fix cursors for 64bit macosx. Add -unixsock option. Work around
- grep issue on OpenBSD in create_display.
-
-2010-12-21 Karl Runge <runge@karlrunge.com>
- * x11vnc: Add RELEASE-NOTES. Call shutdown_uinput() when exiting.
- Free some minor memory. Do not use GetMainDevice() on macosx.
- Add utility scripts qt_tslib_inject.pl and uinput.pl. Option
- -ungrabboth (not useful.) X11VNC_SB_FACTOR -sb user tweak.
- X11VNC_REFLECT_{bitsPerSample,samplesPerPixel,bytesPerPixel}
- for -reflect vncclient. Fix minor fd leaks. For -create mode
- preserve LC_ALL; FIND_DISPLAY_NO_VT_FIND, FIND_DISPLAY_NO_LSOF,
- and X11VNC_CREATE_LC_ALL_C_OK. Speed up -find and -create scripts
- for large installations. Enable direct event input modes to
- bypass uinput. TSLIB support for uinput touchscreens. Handle
- pressure events on touchscreens. User can set X11VNC_UINPUT_BUS
- and X11VNC_UINPUT_VERSION. Allow Tab switch in -create login:
- prompt. Fix bug in setting bpp for -rawfb. Java viewers now
- handle mousewheel events. No vars named new.
-
-2010-09-10 Karl Runge <runge@karlrunge.com>
- * x11vnc: update classes/ssl jars, patches, and script.
- update prepare_x11vnc_dist.sh to 0.9.13. Makefile.am no top_srcdir
- Allow user to set avahi name and port via env. vars. Add
- avahi_timeout() sigalarm. Rename pointer() to pointer_event()
- because Xdefs.h is included for some unknown reason. Add
- -always_inject option. Add vnc_reflect_cursor_pos() for -reflect
- mode. Attempt at libvncclient VeNCrypt (disabled.) Fix bug
- with --with-system-libvncserver missing FinishedFrameBufferUpdate.
- More info in VncViewer.class http warning. Look for gdm* in
- find display heuristics (e.g. gdm3). More heuristics with
- XAUTHLOCALHOSTNAME attempts. X11VNC_CREATE_MAX_DISPLAYS: let user
- specify max number of -create displays. FD_USERPREFS modes for
- -unixpw (user conf file.) Document all exiting behavior. Let
- user set X11VNC_NO_LIMIT_SHM to avoid autoreduction. Look for
- kdm when avoiding being killed by dm, change timings too.
-
-2010-05-08 Karl Runge <runge@karlrunge.com>
- * x11vnc: set cd->unixname in apply_opts. Print message in
- vnc_reflect_resize. Some tweaks to prepare_x11vnc_dist.sh
-
-2010-05-01 Karl Runge <runge@karlrunge.com>
- * x11vnc: X11VNC_DISABLE_SSL_CLIENT_MODE option to disable SSL
- client role in reverse connections. Improvements to logging in
- ultravnc_repeater, ULTRAVNC_REPEATER_NO_RFB option. Increase
- SSL timeout and print message if 'repeater' mode is detected for
- reverse SSL connection. Fix RECORD scroll XCopyArea detection
- with recent gtk/gdk library; set X11VNC_SCROLL_MUST_EQUAL
- to disable. Limit logging of RECORD error messages.
-
-2010-04-25 Karl Runge <runge@karlrunge.com>
- * x11vnc: incorporate new ultravnc_dsm_helper.c, add pointer_mask
- remote control query. Cut openssl default -ping delay.
-
-2010-04-18 Karl Runge <runge@karlrunge.com>
- * x11vnc/misc: improvements to demo scripts
- * x11vnc: Alias -coe for -connect_or_exit. more accurate
- dotted_ip() and -listen6. Improvements to ipv6 mode.
- http interface for X11VNC_HTTP_LISTEN_LOCALHOST. Print
- warning about missing Xvfb, Xdummy, or Xvnc in -create.
- Fix __LINUX_VIDEODEV2_H / HAVE_V4L2. Always print out info
- about Xinerama screens.
- * x11vnc/misc/enhanced_tightvnc_viewer: check for host cmd.
- fix stunnel mode w/o proxy. Update to stunnel 4.33, Fix
- build.unix with new stunnel on Solaris. ipv6 support for
- unix ssvncviewer
-
-2010-04-09 Karl Runge <runge@karlrunge.com>
- * classes/ssl: debugging and workarounds for java viewer
- * x11vnc/misc: sync ssvnc, improve util scripts.
- * x11vnc: exit(1) for -connect_or_exit failure, quiet query
- mode for grab_state, etc. ipv6 support. STUNNEL_LISTEN for
- particular interface. -input_eagerly in addition to -allinput.
- quiet Xinerama message.
-
-2010-03-20 Karl Runge <runge@karlrunge.com>
- * classes/ssl: Many improvements to Java SSL applet, onetimekey
- serverCert param, debugging printout, user dialogs, catch
- socket exceptions, autodetect x11vnc for GET=1.
- * x11vnc: misc/scripts: desktop.cgi, inet6to4, panner.pl.
- X11VNC_HTTPS_DOWNLOAD_WAIT_TIME, -unixpw %xxx documented, and
- can run user cmd in UNIXPW_CMD. FD_XDMCP_IF for create script,
- autodetect dm on udp6 only. Queries: pointer_x, pointer_y,
- pointer_same, pointer_root. Switch on -xkd if keysyms per key >
- 4 in all cases. daemon mode improvements for connect_switch,
- inet6to4, ultravnc_repeater.pl. Dynamic change of -clip do
- not create new fb if WxH is unchanged.
-
-2010-02-22 Karl Runge <runge@karlrunge.com>
- * classes/ssl: Java SSL applet viewer now works with certificate
- chains.
- * x11vnc: Printout option -sslScripts. Suggest -auth guess
- in error message. Set fake_screen width and height. Test
- for +kb in Xvfb.
-
-2010-01-02 Karl Runge <runge@karlrunge.com>
- * x11vnc: small tweaks to Xdummy, rx11vnc*. Apply
- SMALL_FOOTPRINT to -appshare text. Copyright year change.
-
-2009-12-29 Karl Runge <runge@karlrunge.com>
- * x11vnc: rename -create_x to -create_xsrv. Hopefully
- done fixing Xdummy.
-
-2009-12-28 Karl Runge <runge@karlrunge.com>
- * x11vnc: Fix problems in --without-x builds. Fix crash
- with -QD query for dbus info. Adjust window size for
- small screens in -gui. Improve F1 help for xdm, etc.
- include ssvnc 1.0.25 source.
-
-2009-12-24 Karl Runge <runge@karlrunge.com>
- * x11vnc: prepare_x11vnc_dist.sh for 0.9.10. -xdummy_xvfb,
- -svc_xdummy_xvfb and -create_x shorthand. lxde session.
- Xdummy improvements and root no longer required.
-
-2009-12-21 Karl Runge <runge@karlrunge.com>
- * x11vnc: -DENC_HAVE_OPENSSL=0 to disable enc.h but still
- have ssl. Tweak ps command in find_display. Try to handle
- AIX su. Ignore an initial newline at login: for -unixpw.
-
-2009-12-18 Karl Runge <runge@karlrunge.com>
- * x11vnc: fix keycode and other remote control actions under
- DIRECT: with an extra XFlush and other safety measures.
- fflush(stderr) much in su_verify. Make the -unixpw env. vars
- UNIXPW_DISABLE_SSL and UNIXPW_DISABLE_LOCALHOST work correctly.
- Make -loopbg actually imply -bg. Add tag=... to unixpw opts
- to set FD_TAG. Prefer Xvfb over Xdummy. Reduce wait time
- for https. Add 'Login succeeded' output to unixpw panel.
-
-2009-12-15 Karl Runge <runge@karlrunge.com>
- * x11vnc: X11VNC_REMOTE, X11VNC_TICKER, and VNC_CONNECT properties
- names can be changed via env. vars (e.g. for multiple
- x11vnc instances.) The -quiet option documented better.
- Add fakebuttonevent remote control action. Improve child
- test for connecting to port 113. Add connect_switch and
- ultravnc_repeater.pl to CVS. Report X server number of mouse
- buttons. Change find_display script to check for stale pids
- in /tmp/.XNN-lock. If root under find_display, try FD_XDM
- if previous failed to find auth. Print error reasons for
- -storepasswd failures.
-
-2009-12-06 Karl Runge <runge@karlrunge.com>
- * x11vnc: findauth/-auth guess works with FD_XDM=1 for root
- finding dm's xauthority. Work around for GDM's recent
- 'xhost SI:localuser:root' usage. X11VNC_REOPEN_SLEEP_MAX
- for longer lived -reopen-ing. X11VNC_EXTRA_HTTPS_PARAMS for
- additional URL parameters, X11VNC_HTTP_LISTEN_LOCALHOST=1 to
- force libvncserver http to listen on localhost.
-
-2009-12-04 Karl Runge <runge@karlrunge.com>
- * classes/ssl: update binaries; new signing key; ss_vncviewer.
- * x11vnc: add more wish possibilities for -gui. Declare crypt()
- on all platforms (disable with -DDO_NOT_DECLARE_CRYPT.)
-
-2009-12-02 Karl Runge <runge@karlrunge.com>
- * x11vnc: -appshare mode for sharing an application windows of the
- entire desktop. map port + 5500 in reverse connect. Add id_cmd
- remote control functions for id (and other) windows. Allow zero
- port in SSL reverse connections. Adjust delays between multiple
- reverse connections; X11VNC_REVERSE_SLEEP_MAX env var. Add some
- missing mutex locks; add INPUT_LOCK and threads_drop_input.
- More safety in -threads mode for new framebuffer change. Fix
- some stderr leaking in -inetd mode.
-
-2009-11-18 Karl Runge <runge@karlrunge.com>
- * x11vnc: use -timeout setting for reverse connections too.
- Delay calling xfixes at the beginning of 1st connection to avoid
- display manager Xorg server crash. Delay selwin creation at the
- begin 1st connection to avoid being killed by display manager.
- Options -findauth and '-auth guess'. Export icon_mode query.
- Do not open X display in -rawfb mode unless asked. Bugfix for
- -sid/-id handling window offscreen or bigger than display.
- Search for windows with _DBUS_SESSION_BUS_PID to decide which
- dbus_launch is ours. Fix missing displays in FIND_DISPLAY
- script. Add X11VNC_SKIP_DISPLAY_NEGATE. Improvements to
- 'x11vnc Properties' gui dialog and connecting with x11vnc via
- socket (client list.) X11VNC_SYSTEM_GREETER1 for previous text
- font size. Fix bug with unixpw and vencrypt plain login.
- Have fast fb read rate keep waitms and defer the same.
- More heuristics to check try if GDM is still running (window
- names gdm-*)
-
-2009-10-17 Karl Runge <runge@karlrunge.com>
- * x11vnc: support for -solid option in xfce desktop.
- List -Q guess_dbus query. Implement -showrfbauth option.
- Workaround for inane X_ShmAttach incompatibility in Xorg.
-
-2009-10-08 Karl Runge <runge@karlrunge.com>
- * x11vnc: bcx_xattach/x2x desktop switching facility.
- More remote control features: grab_state, ping:mystring,
- grablocal, resend_cutbuffer, resend_clipboard, resend_primary,
- keycode, keysym, ptr, sleep, get_xprop, set_xprop, wininfo,
- pointer_pos, mouse_xy, noop, guess_dbus Add DIRECT: for
- remote control w/o server. X11VNC_NO_CHECK_PM for more
- quiet DIRECT: usage. Options -query_retries, -remote_prefix,
- and X11VNC_SYNC_TIMEOUT for remote control. Add scripting
- to remote control. ping clients during in unixpw login.
- Option -unixpw_system_greeter as shortcut to XDM/GDM/etc panel.
- Add clear_all, viewonly, nodisplay, to unixpw username:opts.
- F1 help for options (including smaller console font).
- Document FD_TAG. Eat multiple property change events in one
- sitting (also PROP_DBG=1). Support more -ssl features (special
- cert names, single port, client certs, etc.) in -stunnel
- external SSL helper mode. Reorganize openssl code to allow
- integration with stunnel features if not compiled with openssl.
- X11VNC_HTTPS_VS_VNC_TIMEOUT Fix dbus session address for -solid
- in gnome. Use dbus-launch in -create mode if available.
- X11VNC_SKIP_DISPLAY=all in -find/-create mode. let noxauth
- unset XAUTHORITY for use with su - $USER. CREATE_DISPLAY_EXEC
- debugging. Add x_terminal_emulator to -create cmd search.
- Option -extra_fbur to tune fb update requests tracking; make
- default tracking more aggressive. RATE_VERB/CHECK_RATE env. for
- fbur rate. Env. vars to set Tk gui fonts. Catch closed
- socket reads/writes. Try to detect 'crazy' xdamage insertion,
- e.g. from some xscreensavers (needs work.). Don't switch
- on server autorepeat if any keys are pressed down to work
- around Xorg server and/or gnome bug. If PATH is empty, set
- it to minimal one. Fix bug with -bg and -dp/-dk printout if
- logfile present.
- * classes/ssl: license statement.
-
-2009-06-18 Karl Runge <runge@karlrunge.com>
- * classes/ssl: java viewer now handles auth-basic proxy logins.
- * misc/enhanced_tightvnc_viewer: update ssvnc.
-
-2009-06-14 Karl Runge <runge@karlrunge.com>
- * x11vnc: Add X11VNC_REFLECT_PASSWORD env. var. for -reflect mode.
- Message to user about compiz problems suggesting -noxdamage.
- Improvements to single-port detection and logging.
-
-2009-05-21 Karl Runge <runge@karlrunge.com>
- * x11vnc: Thread safety improvements. Add 'OpenOffice' to special
- case list for scroll detection. Fix -clip mode under -rawfb.
- Workaround Xorg bug that yields infinitely repeating keys
- when 'xset r off' action is done with keys pressed. Env. var
- X11VNC_IDLE_TIMEOUT.
-
-2009-03-12 Karl Runge <runge@karlrunge.com>
- * x11vnc: Fix off-screen bug for -ncache_cr copyrect.
-
-2009-03-07 Karl Runge <runge@karlrunge.com>
- * x11vnc: allow range for X11VNC_SKIP_DISPLAY, document grab
- Xserver issue. Add progress_client() to proceed more quickly
- thru handshake. Improvements to turbovnc hack.
-
-2009-02-28 Karl Runge <runge@karlrunge.com>
- * x11vnc: add kludge to experiment with turbovnc.
-
-2009-02-25 Karl Runge <runge@karlrunge.com>
- * x11vnc: fix some -QD cases for use in tkx11vnc.
-
-2009-02-21 Karl Runge <runge@karlrunge.com>
- * x11vnc: add -noskip_lockkeys option for future use.
-
-2009-02-03 Karl Runge <runge@karlrunge.com>
- * x11vnc: Add "sendbell" remote cmd. Fix copyrect updates under
- -reflect. Workaround that checks valid window of selection
- requestor. Wait on some ssl helper pids earlier. Workaround
- XAUTHLOCALHOSTNAME for some new usage modes. Set fake fb to
- requested bpp with correct masks. -padgeom once:... mode.
- Set LIBXCB_ALLOW_SLOPPY_LOCK by default. rfbRandomBytes earlier.
- * classes/ssl: Update jars. Add "TOP_" dropdown customization to
- ultravnc java viewer applet FTP panel.
-
-2009-01-11 Karl Runge <runge@karlrunge.com>
- * classes/ssl: Add configurable Ultra java applet Filexfer Drives
- drop down (e.g. ftpDropDown=Home.Desktop.bin). Document all
- applet parameters in classes/ssl/README.
-
-2009-01-10 Karl Runge <runge@karlrunge.com>
- * x11vnc: fix failure of -8to24 on default depth 24 due to
- nonstandard indexed color support changes. Fix small window
- for failure after XSendEvent selection call; add env var.
- X11VNC_SENDEVENT_SYNC=1 to take even more care.
-
-2009-01-03 Karl Runge <runge@karlrunge.com>
- * 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 <runge@karlrunge.com>
- * x11vnc: 0.9.6 release. Some strtok bugfixes. rename -tlsvnc
- to -anontls. Disable ssl caching. No cert creation prompting
- in inetd or bg modes. waitpid a bit more carefully on ssl
- helpers. Tune ssl initial timeouts. Let -create user specify
- starting X display. fix -rfbport prompt gui for older tk.
- -sslonly option. Error if no -ssl with related options. -rand
- option. -ssl implies -ssl SAVE
-
-2008-11-22 Karl Runge <runge@karlrunge.com>
- * x11vnc: x11vnc.desktop file. -reopen, -dhparams, -sslCRL,
- -setdefer options. -rfbport PROMPT VeNCrypt and TLSVNC SSL/TLS
- encryption support. Tweaks to choose_delay() algorithm.
- -ssl ANON anonymouse Diffie-Hellman mode. Fix bugs in certs
- management. Additions to tray=setpass naive user mode.
-
-2008-11-09 Karl Runge <runge@karlrunge.com>
- * x11vnc: add zeroconf external helpers (avahi-publish and
- dns-sd). Alias -zeroconf. Close pipeinput_fh on exit.
- Kludge to make -solid work on MacOSX console. Attempt at
- cpp macros to disable newer libvncserver interfaces.
-
-2008-10-29 Karl Runge <runge@karlrunge.com>
- * x11vnc: -http_oneport for single port HTTP and VNC.
- Improve find_display wrt lsof blocking with -b.
-
-2008-10-19 Karl Runge <runge@karlrunge.com>
- * x11vnc: -chatwindow for chat window on X console using SSVNC
- as a helper. Print suggestion for X_ShmAttach failure.
- Allow -scale WxH for different X- and Y-scaling factors.
- Workaround for missing -enc cipher EVP_aes_256_cfb. Modify
- message digest and salt/IV parameters. Try to improve compile
- time by breaking up large if blocks.
-
-2008-09-21 Karl Runge <runge@karlrunge.com>
- * x11vnc: Add symmetric key encryption -enc cipher:keyfile,
- works with SSVNC. Make -remap work on MacOSX console.
- update to 0.9.5 strings. Add a couple menu items to tkx11vnc.
-
-2008-09-17 Karl Runge <runge@karlrunge.com>
- * x11vnc: make -allow work in -ssl mode.
-
-2008-09-14 Karl Runge <runge@karlrunge.com>
- * x11vnc: -sleepin m-n for random sleep. More mktemp and mkstemp
- protections. SSL_INIT_TIMEOUT=n env. var. Fix macosx console
- X call bug. Synchronize other projects sources.
-
-2008-09-06 Karl Runge <runge@karlrunge.com>
- * x11vnc: kill gui_pid on exit in -connect/-connect_or_exit mode.
- -grablocal n experiment (not compiled by default). -macuskbd
- option for macosx for orig uskdb code. keycode=N remote contol
- cmd. Find dpy look at non-NFS cookies in /tmp. Fix gui tray
- insertion on recent gnome dt. Fix connect_file bug. Sync SSVNC
-
-2008-06-07 Karl Runge <runge@karlrunge.com>
- * x11vnc: -clip xineramaN option, -DIGNORE_GETSPNAM for HP-UX.
- Print info on SSH_CONNECTION override.
-
-2008-05-31 Karl Runge <runge@karlrunge.com>
- * x11vnc: Improvements to nonstandard indexed color support, e.g.
- depths 1, 4, 12, etc. instead of only 8. Only enable xinerama
- xwarppointer if there is more than 1 subscreen.
-
-2008-05-07 Karl Runge <runge@karlrunge.com>
- * x11vnc: add UltraVNC repeater proxy support. fix to setp gui
- mode. -threads is now strongly discouraged. Read PORT= in url.
- User can set nolisten for Xvfb in -create mode. clean up
- wait_for_client() to some degree.
-
-2008-01-31 Karl Runge <runge@karlrunge.com>
- * x11vnc: during speeds estimate, guard against client
- disconnecting. ssvnc sync.
-
-2008-01-14 Karl Runge <runge@karlrunge.com>
- * x11vnc: -ping option, fix memory corruption in copy_tiles
- after xrandr resize.
-
-2007-12-16 Karl Runge <runge@karlrunge.com>
- * x11vnc: setup remote-ctrl file by default on macosx. improve
- tkx11vnc wrt attaching to existing server in icon/tray mode.
-
-2007-12-15 Karl Runge <runge@karlrunge.com>
- * x11vnc: fix find_display and usleep() prototype on macosx.
- -display console and check DISPLAY /tmp/...:0 on macosx.
- implement -noxinerama.
-
-2007-11-12 Karl Runge <runge@karlrunge.com>
- * x11vnc: add clear_locks (Caps_Lock, etc) action. Fix
- ssh tunnel on Darwin.
-
-2007-10-27 Karl Runge <runge@karlrunge.com>
- * x11vnc: fix ncache bug and others under -8to24, -ssh
- option, socks and other proxies in -proxy option.
- compiler warnings. fix TARGETS selection request bug
- (java, konsole).
-
-2007-10-03 Karl Runge <runge@karlrunge.com>
- * x11vnc: add xfce to createdisplay
-
-2007-09-26 Karl Runge <runge@karlrunge.com>
- * x11vnc: COLUMNS=256 to find/create scripts. More ratecheck.
-
-2007-09-14 Karl Runge <runge@karlrunge.com>
- * x11vnc: Add -sshxdmsvc. Fix find_display for inetd. Improve
- -allinput method; env CHECK_RATE to watch for FBUR build up
- (i.e. JFVNC).
-
-2007-09-11 Karl Runge <runge@karlrunge.com>
- * x11vnc: fix wireframe crash under -clip. Add -redirect for
- VNC redir. -rawfb nullbig, randbig, solid, swirl, etc.
- FD_XDM mode to find_display. -listdpy. Add enlightenment.
- Xvnc.redirect FINDDISPLAY-vnc_redirect. -xvnc, -xvnc_redirect,
- -svc_xvnc. AUTO_PORT.
- * ssvnc: sshvnc ssh-only, tsvnc Terminal Services modes.
- Improvements to ss_vncviewer. Automatically find X dpy and
- X login. Reorganize menus a bit. ~/.ssvncrc file.
-
-2007-09-04 Karl Runge <runge@karlrunge.com>
- * x11vnc: Add -autoport and -finddpy utils. -xdummy creation.
- tweak xkb tiebreaking again. Shut off -ncache in dev mode.
- watch for xrandr events even if no -xrandr. Tips for types
- of URLs for java viewers. Add check_redir_services() to
- create_display and tsdo() redir helper utility (-tsd).
- Improvements to Xdummy. Prevent dcop XAUTHORITY=''
-
-2007-08-19 Karl Runge <runge@karlrunge.com>
- * x11vnc: better -xkb tie-breaking for up keystrokes. Add
- Xsrv/FD_XSRV custom server to FINDCREATEDISPLAY list.
-
-2007-08-18 Karl Runge <runge@karlrunge.com>
- * x11vnc: improve FINDCREATEDISPLAY (-create) script. Document
- FD_GEOM, FD_SESS, FD_OPTS, FD_PROG env vars, add Xvnc support.
-
-2007-08-15 Karl Runge <runge@karlrunge.com>
- * x11vnc: add reverse -connect support to -display WAIT:
- i.e. -find, -create, -svc, ... mode. Document need for
- -shared under -connect host1,host2,... Fix bug in -display
- WAIT: mode if vnc client tries to only retrieve SSL cert.
-
-2007-08-03 Karl Runge <runge@karlrunge.com>
- * x11vnc: add -xrefresh option, fix KDE .DCOPserver parse bug,
- make sure UNIXPW_DISABLE_LOCALHOST/-unixpw_unsafe ignore
- any SSH tunnel that would imply -localhost.
-
-2007-07-04 Karl Runge <runge@karlrunge.com>
- * x11vnc: -debug_ncache, fix big fonts in tkx11vnc.
-
-2007-06-14 Karl Runge <runge@karlrunge.com>
- * x11vnc: add detectors if ultravnc chat or file xfer took place,
- if so ping clients more frequently. Fix compile bug if libssl
- not available.
- * ssvnc: add ultravnc ftp jar feature. Add certificate management
- "Verify All Certs".
-
-2007-05-26 Karl Runge <runge@karlrunge.com>
- * x11vnc: set to version 0.9.2, back to NCACHE -12 for testing.
- in -unixpw, initial Escape means no echo username (see ssvnc).
-
-2007-05-21 Karl Runge <runge@karlrunge.com>
- * x11vnc: set things up (NCACHE = -1) to not have -ncache
- on by default; just give a blurb about it.
-
-2007-05-16 Karl Runge <runge@karlrunge.com>
- * x11vnc: print out peer host and port for debugging SSL.
- * ssvnc: rand check, SOCKS support, PORT=, Verify all Certs
- and accepted certs logging.
-
-2007-05-06 Karl Runge <runge@karlrunge.com>
- * x11vnc: lower -wait and -defer to 20ms. Change some SSL
- debug output. Drop client doing ultravnc stuff in -unixpw
- during login phase.
-
-2007-05-05 Karl Runge <runge@karlrunge.com>
- * x11vnc: add groups handling for -users mode.
-
-2007-05-01 Karl Runge <runge@karlrunge.com>
- * ssl: update to java viewer and utility scripts (add onetimekey).
- * x11vnc: setsid() for -gone mode. setpgrp for -create script and
- add -cc 4 to avoid DirectColor.
-
-2007-04-28 Karl Runge <runge@karlrunge.com>
- * x11vnc: -users sslpeer= option. RFB_SSL_CLIENT_CERT var.
- X11VNC_FINDDISPLAY_ALWAYS_FAILS var. -ncache default 10.
- gid switch fix.
- * ssvnc: Linux.i*86 fix and code sync.
-
-2007-04-07 Karl Runge <runge@karlrunge.com>
- * x11vnc: add gnome, kde, etc. FINDCREATEDISPLAY tags.
- In check_ncache periodically check for changed desktop.
-
-2007-03-24 Karl Runge <runge@karlrunge.com>
- * x11vnc: reverse SSL connections. -sleepin option.
-
-2007-03-20 Karl Runge <runge@karlrunge.com>
- * x11vnc: Add -httpsredir option for router port redirs.
- set Xcursor bg/fg color values to zero. Env var to
- force timeout: X11VNC_HTTPS_VS_VNC_TIMEOUT. Let user
- supply nc=N at login prompt. Disable -ncache beta
- test under -http/-httpdir.
-
-2007-03-13 Karl Runge <runge@karlrunge.com>
- * x11vnc: fix crash for kde dcop. limit ncache beta
- tester to 96MB viewers.
-
-2007-02-18 Karl Runge <runge@karlrunge.com>
- * x11vnc: Get ultravnc textchat working with ssvnc.
-
-2007-02-16 Karl Runge <runge@karlrunge.com>
- * x11vnc: add Files mode to user controlled input. more
- ultra/tight filexfer tweaks. rfbversion remote control.
- noncache/nc unixpw user opt.
-
-2007-02-15 Karl Runge <runge@karlrunge.com>
- * x11vnc: tightvnc filetransfer off by default. avahi
- fixes. FINDCREATEDISPLAY geometry. -noultraext.
-
-2007-02-12 Karl Runge <runge@karlrunge.com>
- * x11vnc: add avahi (aka mDNS/Zeroconf/Bonjour...)
- support thanks to Diego Pettenò. -avahi/-mdns.
- Add -find and -create FINDISPLAY aliases.
-
-2007-02-11 Karl Runge <runge@karlrunge.com>
- * x11vnc: add -grabalways, -forcedpms, -clientdpms, and
- -noserverdpms (ultravnc viewer) for improvements in
- the still approximate server locking. Add -loopbg
- and -svc, -xdmsvc aliases. Bug fix create_display.
-
-2007-02-10 Karl Runge <runge@karlrunge.com>
- * x11vnc: watch things like textchat, etc. more carefully
- in unixpw state. Monitor broken XDAMAGE reports when
- OpenGL apps like beryl are running. Implement simple
- kbdReleaseAllKeys, setSingleWindow, setServerInput actions
- (ultravnc extentions). Try to send XDM the username in
- FINDCREATEDISPLAY, also try .dmrc before .xsession.
-
-2007-01-31 Karl Runge <runge@karlrunge.com>
- * x11vnc: -reflect reflector/repeater mode with libvncclient.
- -ncache tweaks: no kde animations and wm improvements,
- fixes to FINDDISPLAY and FINDCREATEDISPLAY login modes,
- MODTWEAK_LOWEST envvar for HP-UX keyboard workaround.
- -N option for display and rfbport matching.
-
-2007-01-12 Karl Runge <runge@karlrunge.com>
- * x11vnc: -N option, more -ncache improvements, kde/gnome.
-
-2007-01-03 Karl Runge <runge@karlrunge.com>
- * x11vnc: more -ncache improvements.
-
-2007-01-01 Karl Runge <runge@karlrunge.com>
- * x11vnc: more -ncache improvements.
-
-2006-12-28 Karl Runge <runge@karlrunge.com>
- * x11vnc: more work on -ncache, add macosx support, fix X errors
- and improve cache expiration algorithm.
-
-2006-12-17 Karl Runge <runge@karlrunge.com>
- * x11vnc: first pass at client-side caching, -ncache option.
- have -http guess ../classes/.. to run out of build area.
-
-2006-12-17 Karl Runge <runge@karlrunge.com>
- * x11vnc: make -xwarppointer the default if xinerama is active.
-
-2006-12-09 Karl Runge <runge@karlrunge.com>
- * java SSL viewer: guard against empty urlPrefix
- * x11vnc: FINDCREATEDISPLAY support to create X session if
- one cannot be found. close fds utility. Print VNC Viewer
- is.. for find display mode. chvt(1) utility.
-
-2006-11-23 Karl Runge <runge@karlrunge.com>
- * prepare_x11vnc_dist.sh: make ss_vncviewer installed 755.
- * x11vnc: for HTTPONCE open new http port in -inetd mode.
- -prog option to indicate full path to program (not know
- when in -inetd and tcpd)
-
-2006-11-21 Karl Runge <runge@karlrunge.com>
- * x11vnc: macosx: problem with padded framebuffer rows, wait for
- user to switch back, CutText xfer support, ignore a few more
- types of toplevels. Add local user wireframing. -dpms/-nodpms
- option to work around kdesktop_lock problem.
-
-2006-11-13 Karl Runge <runge@karlrunge.com>
- * x11vnc: Native Mac OS X support.
-
-2006-11-07 Karl Runge <runge@karlrunge.com>
- * ssl_vncviewer: vnc:// direct connect, add -x to ssh,
- SSL_VNC_LISTEN variable for direct proxy.
-
-2006-10-29 Karl Runge <runge@karlrunge.com>
- * x11vnc: Add tip about how to reenable RECORD extension.
-
-2006-10-11 Karl Runge <runge@karlrunge.com>
- * x11vnc: -cursor_drag for DnD, etc.
-
-2006-09-23 Karl Runge <runge@karlrunge.com>
- * Java viewer: improvements to connection response, faster
- connections.
- * x11vnc: some cleanup for -unixpw login process.
-
-2006-09-20 Karl Runge <runge@karlrunge.com>
- * x11vnc: -unixpw_cmd, -passwfile cmd:/custom:, -sslnofail,
- -ultrafilexfer
-
-2006-09-17 Karl Runge <runge@karlrunge.com>
- * x11vnc: move some info printout to -v, -verbose mode. Add
- -connect_or_exit option. Have -rfbport 0 lead to no TCP
- listening. Eliminate double certificates in .pem files.
- Always print SSL certificate to the screen to aid pasting.
-
-2006-09-15 Karl Runge <runge@karlrunge.com>
- * x11vnc: allow user set signals to ignore, clear DISPLAY in
- -unixpw su_verify. -rawfb none same as null.
- * rfbserver.c: shorten rfbEncodingNewFBSize message.
-
-2006-09-13 Karl Runge <runge@karlrunge.com>
- * x11vnc: document 'ssh -t' improved keyboard response. add
- extra rfbPE() around keystrokes.
- misc/enhanced_tightvnc_viewer: incorporate scripts, documentation,
- etc. for the enhanced tightvnc viewer package.
-
-2006-09-10 Karl Runge <runge@karlrunge.com>
- * x11vnc: minor changes: REQ_ARGS for -sslGenCert, EV_SYN
- SYN_REPORT check restore cursor most under -display WAIT.
-
-2006-08-10 Karl Runge <runge@karlrunge.com>
- * x11vnc: first pass at touchscreens via uinput.
-
-2006-08-02 Karl Runge <runge@karlrunge.com>
- * x11vnc: add -ssltimeout option; tweak ssl timeouts.
-
-2006-07-28 Karl Runge <runge@karlrunge.com>
- * ssl_vncviewer: remove some bashisms, add features.
- * x11vnc: -rotate option (e.g. handheld), fix FPE on tru64.
-
-2006-07-17 Karl Runge <runge@karlrunge.com>
- * x11vnc: enable --without-x builds for -rawfb only (NO_X11)
-
-2006-07-11 Karl Runge <runge@karlrunge.com>
- * x11vnc: more tweaks to UINPUT, mostly mouse motion.
-
-2006-07-08 Karl Runge <runge@karlrunge.com>
- * x11vnc: add uinput support (-pipeinput UINPUT:...) for full
- mouse and key input to linux console (e.g. for qt-embedded apps)
- add -allinput for handleEventsEagerly.
-
-2006-07-04 Karl Runge <runge@karlrunge.com>
- * x11vnc: 2nd -accept popup with WAIT, and UNIX: info for unixpw
- login. Use RFB_CLIENT_ON_HOLD for -unixpw. -unixpw white arrow
- -license option. Use getspnam if getpwnam is short.
- abbrevs sc=, cm, ck for user:opts.
-
-2006-06-23 Karl Runge <runge@karlrunge.com>
- * x11vnc: misc cleanup.
-
-2006-06-18 Karl Runge <runge@karlrunge.com>
- * x11vnc: -grabkbd, -grabptr, -env options. under -unixpw +
- WAIT let user add some options after his username (e.g. runge:3/4)
- -allowedcmds to fine tune vs. -nocmds. general cleanup.
-
-2006-06-12 Karl Runge <runge@karlrunge.com>
- * x11vnc: word tune SSL Java viewer; fix multi-certs bug. Add
- -display WAIT:cmd=FINDDISPLAY builtin script and cmd=HTTPONCE
- action. -http_ssl option for ssl subdir only. Add -rawfb RAND
- test case. improve raw_xfer() for use in inetd https transfer.
- fix bug SSH + -unixpw -> -localhost. fix bug setup cursors
- in WAIT mode. Mac OS X pty tweak.
-
-2006-06-09 Karl Runge <runge@karlrunge.com>
- * x11vnc: make -display WAIT + -unixpw work on Solaris.
-
-2006-06-08 Karl Runge <runge@karlrunge.com>
- * x11vnc: XOpenDisplay wrapper for raw xauth data, -unixpw
- su_verify() to run any cmd, -users unixpw= mode. -display WAIT:...
- modes for delayed X display opening and dynamic choosing.
-
-2006-06-03 Karl Runge <runge@karlrunge.com>
- * x11vnc: -capslock and -skip_lockkeys options. map some Alt keys
- to Latin under linuxfb. switch to new stats API. Handle more
- cases carefully when switching fb.
-
-2006-05-06 Karl Runge <runge@karlrunge.com>
- * x11vnc: improved support for webcams and tv tuners with
- video4linux /dev/video: -rawfb video, -freqtab etc.
- Convenience option for linux VT's: -rawfb cons (LinuxVNC
- method). -pipeinput builtins for video and console.
- -24to32 option to avoid 24bpp problems. "snap:" method for
- -rawfb.
-
-2006-04-26 Karl Runge <runge@karlrunge.com>
- * x11vnc: skip exit in check_openssl() if not compiled with
- libssl. set SKIP_HELP (again) in small footprint builds.
-
-2006-04-16 Karl Runge <runge@karlrunge.com>
- * x11vnc: More web proxy work for Java SSL applet and wrapper
- script ssl_vncviewer. Apache SSL gateway support for
- incoming x11vnc connections. Handle "double proxy" case.
-
-2006-04-05 Karl Runge <runge@karlrunge.com>
- * x11vnc: add FBPM support (-fbpm) for Suns. -rawfb ZERO for
- testing. Basic key+cert management utilities: -sslGenCA,
- -sslGenCert, -sslEncKey, -sslDelCert, -sslCertInfo, and
- addln features. SSL proxy connection. -storepasswd with
- no args or pw echo.
-
-2006-03-26 Karl Runge <runge@karlrunge.com>
- * x11vnc: -xinerama now on by default. In -ssl mode accept https
- applet downloads thru VNC port. -https option for 2nd https
- port. Look for classes/ssl under -http. add Java URL messages
- to final output lines. make -inetd work with -ssl (even for
- https). fix -unixpw login prompt under -scale. guard against
- clientData = NULL.
-
-2006-03-11 Karl Runge <runge@karlrunge.com>
- * x11vnc: add -ssl mode using libssl. Include Xdummy in misc.
- a few more macros for smallerfoot, etc.
-
-2006-03-08 Karl Runge <runge@karlrunge.com>
- * x11vnc: manage CLIPBOARD in addition to PRIMARY. -debug_sel
- Make reverse connections require passwords. -usepw option.
- -storepasswd w/o args prompts and writes ~/.vnc/passwd.
-
-2006-03-06 Karl Runge <runge@karlrunge.com>
- * x11vnc: switch remote control to X11VNC_REMOTE property. Put
- in -unixpw constraints for reverse connections under -inetd.
- -inetd won't quit when reverse conn client leaves. Allow keyboard
- input for viewonly -unixpw logins. "%*" utils for testing
- -unixpw. improve start time fix bugs, small screen in gui.
-
-2006-03-04 Karl Runge <runge@karlrunge.com>
- * x11vnc: -unixpw on *bsd, hpux and tru64. Add -unixpw_nis for
- non-shadow systems. check stunnel dying. check SSH_CONNECTION
- in -unixpw. gui icon tweaks, unix username.
-
-2006-03-02 Karl Runge <runge@karlrunge.com>
- * x11vnc: more tweaks to -unixpw mode. Add -gone popup mode.
- Change filexfer via -R. Tune SMALL_FOOTPRINT. gui fixes.
-
-2006-02-24 Karl Runge <runge@karlrunge.com>
- * x11vnc: -unixpw for Unix password auth, -stunnel to setup
- stunnel(1) for an SSL tunnel on the server end. Add clipboard
- input to per-client input controls.
-
-2006-02-20 Karl Runge <runge@karlrunge.com>
- * x11vnc: add SIGINT SIGQUIT handling for run_user_command(),
- set some signal handlers to SIG_DLF for forked children,
- put a timeout on port 113 connection to viewer machine.
-
-2006-02-06 Karl Runge <runge@karlrunge.com>
- * x11vnc: fix AIX build wrt h_errno.
-
-2006-02-06 Karl Runge <runge@karlrunge.com>
- * x11vnc: -8to24 more speedups; tunables for very slow machines.
-
-2006-02-04 Karl Runge <runge@karlrunge.com>
- * x11vnc: -8to24 speedups and improvements.
-
-2006-01-21 Karl Runge <runge@karlrunge.com>
- * x11vnc: -8to24 opts, use XGetSubImage. fix -threads deadlocks and
- -rawfb crash.
-
-2006-01-18 Karl Runge <runge@karlrunge.com>
- * x11vnc: -8to24 now works on default depth 8 screens.
-
-2006-01-16 Karl Runge <runge@karlrunge.com>
- * x11vnc: more tweaks to -8to24, add XGETIMAGE_8TO24 mode to call
- XGetImage() on the 8bpp regions.
-
-2006-01-14 Karl Runge <runge@karlrunge.com>
- * x11vnc: add -8to24 option for some multi-depth displays (but use
- of -overlay is preferred if supported).
-
-2006-01-12 Karl Runge <runge@karlrunge.com>
- * fix -DSMALL_FOOTPRINT=N builds.
-
-2006-01-11 Karl Runge <runge@karlrunge.com>
- * x11vnc: close fd > 2 in run_user_command(), -nocmds in crash_debug,
- fix 64bit bug for -solid.
-
-2006-01-08 Karl Runge <runge@karlrunge.com>
- * x11vnc: the big split. opts: -afteraccept and -passwdfile read:
-
-2005-12-24 Karl Runge <runge@karlrunge.com>
- * x11vnc: enhance -passwdfile features, filetransfer on by default,
- call rfbRegisterTightVNCFileTransferExtension() earlier.
-
-2005-11-28 Karl Runge <runge@karlrunge.com>
- * x11vnc: add -loop option.
-
-2005-11-25 Karl Runge <runge@karlrunge.com>
- * x11vnc: throttle load if fb update requests not taking place.
- * misc/x11vnc_pw: add utility script
-
-2005-10-22 Karl Runge <runge@karlrunge.com>
- * add tightVNC FileTransfer (-filexfer) and -DFILEXFER=1
- * -slow_fb for special purpose infrequent polling.
- * make -blackout work with copyrect clipping.
- * -blackout noptr,WxH+X+Y,... to prevent pointer from going
- into a blacked out region.
-
-2005-07-17 Karl Runge <runge@karlrunge.com>
- * more improvements to gui UE. gui requests via client_sock
- PASSWD_REQUIRED and PASSWD_UNLESS_NOPW build options.
-
-2005-07-12 Karl Runge <runge@karlrunge.com>
- * gui: remove nevershared etc., parse cmd line, bug fixes.
- * x11vnc: fix pointer queue buildup under -viewonly.
-
-2005-07-10 Karl Runge <runge@karlrunge.com>
- * more improvements to gui, default values, save-settings..
- * x11vnc scary password warnings. Release settings. -QD option.
- add \# to rc files and fix rcfile read bug.
-
-2005-07-09 Karl Runge <runge@karlrunge.com>
- * add -grab_buster helper thread to break up grabs (might not be
- need any longer due to gett XFlush-ing). Fix scrolls and
- copyrect for -clip and -id cases.
-
-2005-07-06 Karl Runge <runge@karlrunge.com>
- * many improvements to the gui. now embeds into system tray ok.
- x11vnc -debug_grabs, -printgui, -nosync
-
-2005-07-01 Karl Runge <runge@karlrunge.com>
- * support for simple "-gui tray" mode (small icon like the original
- x0rfbserver had). Can't figure how to get a tray to swallow it..
- * passwd, viewpasswd changing in tray mode.
- * allow typos like: x11vnc -R -scale 3/4
-
-2005-06-26 Karl Runge <runge@karlrunge.com>
- * track keycode state for heuristics, -sloppy_keys, -wmdt
- * add -nodbg as option
-
-2005-06-21 Karl Runge <runge@karlrunge.com>
- * reinstate "bad desktop" for wireframe.
- * extra long info and tips of XOpenDisplay fails.
-
-2005-06-18 Karl Runge <runge@karlrunge.com>
- * clean up some malloc/free problems (don't free the current cursor)
- * set DISPLAY before calling gconf, dcop under -solid
- * -inetd -q and no -o logfile implies closing stderr.
-
-2005-06-14 Karl Runge <runge@karlrunge.com>
- * -DNOGUI and -DVIEWONLY build options
- * -noskip_dups the default (windows viewer sends no ups when
- repeating)
- * HAVE_SOLARIS_XREADSCREEN and HAVE_IRIX_XREADDISPLAY
- * Alt+Button+Motion to wireframe. tunable in WIREFRAME_PARMS
- * copyrect now the default under -scale (works OK, but must
- send a cleanup update)
- * fix -pedantic and Sun cc warnings and errors (unsigned, etc..)
- * print out fatal error messages under -quiet
- * -seldir to control and debug selection transfers.
- * fix crashes on 64bit wrt unsigned long in rich cursors.
- * fix kde guessing errors
- * more scrolling and wireframe tweaks.
-
-2005-06-03 Karl Runge <runge@karlrunge.com>
- * make scrollcopyrect more or less usable under -scale
- * add -fixscreen for periodic cleanup of painting errors.
- * adjust keyrepeat scroll behavior.
-
-2005-05-30 Karl Runge <runge@karlrunge.com>
- * alter "magic cleanup key sequences" (N*Alt_L and N*Super_L)
- * dial down check_xrecord_reset() reset times.
-
-2005-05-24 Karl Runge <runge@karlrunge.com>
- * more -scrollcopyrect: GrabServer detection, autorepeat throttling,
- hack to clean screen 3,4,5 Alt_L in a row, mouse wheel detect.
- * fix bug wrt switching to single_copytile, add Darwin to shm limit.
-
-2005-05-17 Karl Runge <runge@karlrunge.com>
- * more -scrollcopyrect, -scr_term hacks for terminals.
- * -wait_ui, -nowait_bog tunables. push cursor sooner.
-
-2005-05-14 Karl Runge <runge@karlrunge.com>
- * much more work on "-scrollcopyrect" mode... getting usable.
- * remove -pointer_mode 3, shift everyone back down
- * -dbg "crash shell" for debugging
- * -add_keysyms now the default, periodically clears if needed.
- * try to autodetect if -xkb would be a good idea.
- * improve keycode guessing for -xkb mode (force ISO_Level3_Shift)
- * -remap DEAD, etc. for dead/mute keys remappings.
-
-2005-05-02 Karl Runge <runge@karlrunge.com>
- * initial support for using RECORD to detect some types of window
- scrolls. This is "-scrollcopyrect" mode, use -noscrollcopyrect
- to disable. Much tuning and painting error repair still required.
- * more build time customizations: REMOTE_DEFAULT, REMOTE_CONTROL,
- EXTERNAL_COMMANDS, NOREPEAT, WIREFRAME*, SCROLL*, ...
- * added bandwidth and latency measurements.
- * added XListHosts to -privremote check.
- * debug_* remote-control variables.
- * removed OLD_TREE stuff.
-
-2005-04-19 Karl Runge <runge@karlrunge.com>
- * somewhat safer remote-control defaults, and addnl options for
- more safe operation: -privremote, -safer, -nocmds, -unsafe
- * -wireframe, -wirecopyrect: instead of having user look at a
- slowly moving, lurching window, guess when a window is being
- moved/resized and just show a wireframe. -wirecopyrect means to
- apply rfbDoCopyRegion to the detected move as well.
- * debugging switches for X events and X damage: debug_xevents
- debug_xdamage.
- * -rawfb bugfixes. -noviewonly hack to still send UI to X.
-
-2005-04-11 Karl Runge <runge@karlrunge.com>
- * fix -clip under -rawfb, fix offset bug under file lseeking.
- * add -rawfb setup:cmd mode to initialize fb. example: misc/ranfb.pl
-
-2005-04-10 Karl Runge <runge@karlrunge.com>
- * -rawfb non X-polling (i.e. shm, mmap, lseek).
- * -pipeinput enable external user input processing command.
- * -xtrap use XESimulateXEventRequest to inject user input.
- * scaling blend for StaticGray, add :fb scaling option.
- * default password macros.
- * improve -norepeat use under -viewonly.
- * -flag flagfile to aid wrapper scripts.
- * add utility scripts, etc. dir ./misc
-
-2005-04-03 Karl Runge <runge@karlrunge.com>
- * try DEC-XTRAP on X11R5 if XTestGrabControl is missing.
- * -shiftcmap n, for 8bpp displays using < 256 color cells
- and with pixel values shifted from zero.
- * fix DAMAGE event leak after viewers disconnect.
- * -http option to try to guess where the java viewer is.
-
-2005-03-29 Karl Runge <runge@karlrunge.com>
- * build-time customizations X11VNC_SHARED, X11VNC_FOREVER,
- REMOTE_CONTROL, SMALL_FOOTPRINT for CPPFLAGS
- * fix event leaks for xkb BellNotify and ClientMessage and others,
- esp. under -nofb. make nofb work with remote control.
- * -nolookup for bad DNS setups.
- * more playing with pointer_mode: check_user_input3()
-
-2005-03-19 Karl Runge <runge@karlrunge.com>
- * scale cursors along with display. Use -scale_cursor to change
- or disable cursor scaling.
- * speed up scaling in some cases, :nb and integer magnification.
- * provide alternative arrow cursors (1-6) via -arrow n.
- * reset no autorepeat a couple times if something turns it off,
- set with -norepeat N.
- * do not take a nap if DAMAGE seems to be doing its job.
-
-2005-03-12 Karl Runge <runge@karlrunge.com>
- * support for the X DAMAGE extension to receive damage
- rectangle reports from the X server. On by default, disable
- with -noxdamage. Currently only trusts small rects
- (but see -xd_area n) and uses the rest as "hints" for the
- scanline polling.
- * -clip WxH+X+Y to show a clipped sub-region of the screen.
- * use RFC 1413 (identd) to attach a name to a client in
- friendly environments.
- * fix XAUTHORITY wrt '-auth ... -gui other:0'.
-
-2005-03-04 Karl Runge <runge@karlrunge.com>
- * add changes to couple with -listen option, in particular
- the behavior of -localhost and remote control cmds.
- * workarounds for old trees.
-
-2005-02-23 Karl Runge <runge@karlrunge.com>
- * final changes for 0.7.1 release.
-
-2005-02-21 Karl Runge <runge@karlrunge.com>
- * -nap is now the default, disable with -nonap
- * set version to 0.7.1, word tune -help, etc.
-
-2005-02-14 Karl Runge <runge@karlrunge.com>
- * cleanup -users stuff, add "lurk=" mode
- * support cde in -solid
- * simple gui mode for beginners, -gui ez,...
-
-2005-02-10 Karl Runge <runge@karlrunge.com>
- * Add -input to fine tune client input (keystroke, mouse motion,
- and button presses). Allow per-client setting via remote cntl.
- * fix bug in get_remote_port, add ip2host for client info.
-
-2005-02-09 Karl Runge <runge@karlrunge.com>
- * Add -users switch user mechanism and related utilities.
- * fix -solid for gnome and kde.
- * exit earlier on trapped XIO errors.
-
-2005-02-05 Karl Runge <runge@karlrunge.com>
- * -solid solid color background when clients are connected.
- * -opts/-? to show option names only.
-
-2005-01-23 Karl Runge <runge@karlrunge.com>
- * sync with new draw cursor mechanism, keep old way in OLD_TREE.
- * add -timeout option, change -alphablend to be default
- * -R norepeat now forces the issue (Xsession may turn it back on).
- * try :0 if no other info.
-
-2005-01-15 Karl Runge <runge@karlrunge.com>
- * adjust alpha blending parameters, -alphablend, handle 24bpp.
- * add -snapfb snapshot fb, not clear how useful it is..
- * more functions etc for -pointer_mode 4, still not finished.
- * scan_for_updates() "count only" mode.
- * increase max shm size on Linux.
- * -oa -logappend, -pm, -speeds
- * fix bugs in -allow, -R connect, screen == NULL
-
-2004-12-27 Karl Runge <runge@karlrunge.com>
- * allow -DLIBVNCSERVER_HAVE_FOO=0 override everything
- * get_xfixes_cursor() try to more carefully convert alpha channel
- to opaque pixel. Options -alphacut, -alphafrac, -alpharemove
- * more commands under remote control: rfbwait, rfbport, http,
- httpport, httpdir, enablehttpproxy, desktop, alwaysshared,
- dontdisconnect. Add to tkx11vnc.
-
-2004-12-22 Karl Runge <runge@karlrunge.com>
- * final polishing for 0.7 release, tkx11vnc tweaks
- * more careful rfbPE in pick_window, start check_user_input4()
-
-2004-12-19 Karl Runge <runge@karlrunge.com>
- * cleanup putenv, snprint, other string manip.
- * add -sync mode to remote control for better control
- * allow -remote and -query at same time.
-
-2004-12-16 Karl Runge <runge@karlrunge.com>
- * support for XFIXES extension to show the exact cursor shape,
- working on Linux/Xorg and Solaris 10. disable with -noxfixes
- * remote control mania - nearly everything can be changed dynamically!
- see the -remote/-query (aka -R/-Q) options. e.g. -R scale:5/6
- * simple gui tkx11vnc based on the remote control mechanism, see -gui
- * support for XRANDR extension, if the X screen changes size (see
- xrandr(1)), x11vnc will resize the fb. Pays to have NewFBSize viewer
- * -overlay support on IRIX with XReadDisplay (not tested).
- * RFB_MODE is set to "accept" or "gone" in environment
- * "-id pick" will let you pick the window (calls xwininfo(1)...)
- * "-pointer_mode n" replaces -old_pointer (n=1) and -old_pointer2 (n=2)
- a new mode n=3 is added (similary to nodragging, but dynamic).
- * "-sb n" screen blank timeout option is now documented.
- * renamed NON_CVS to OLD_TREE
-
-2004-08-31 Karl Runge <runge@karlrunge.com>
- * new check_user_input() pointer input algorithm, it tries to avoid
- extra-draws. still needs tuning, get previous one with -old_pointer2
- * add NON_CVS macro for building in older CVS trees.
-
-2004-08-29 Karl Runge <runge@karlrunge.com>
- * remove old mouse patch code, now use rfbSetCursor (+ workarounds)
- * changed cursor shape options (no more -mouse, ...) to '-cursor mode'
- where 'mode' can be empty "X", "some", or "most". "some" adds
- heuristics for two more cursors.
- * -nocursorshape added.
- * ifdef checks for XSHM and XTEST. Add *_wr wrappers as well.
- * -vncconnect is now the default.
-
-2004-08-15 Karl Runge <runge@karlrunge.com>
- * -overlay option to fix color problems on Sun machines with 8+24
- and 24+8 overlay visuals, uses Solaris XReadScreen().
- * expose -sid option (shifted -id windowid) to allow explicit
- wrapping of XGetImage, etc for -overlay
- * fix misc bugs: missing var types, hardwired blackouts sizes,
- subwin desktop name crash.
-
-2004-08-03 Karl Runge <runge@karlrunge.com>
- * add man page x11vnc.1 autogenerated from x11vnc -help; tweak
- help output a little bit. Adjust autoconf to pick up manpage.
- * add README from website docs.
- * zero watch_bell and use_xkb_modtweak if no XKEYBOARD
-
-2004-07-31 Karl Runge <runge@karlrunge.com>
- * -cursorpos now the default; make cursorpos work when scaling
- * fix bug with multiple adds of the same keysym for -add_keysyms
- * rewhack -help output again
- * adjust version number and output.
-
-2004-07-28 Karl Runge <runge@karlrunge.com>
- * -add_keysyms dynamically add missing keysyms to X server
-
-2004-07-26 Karl Runge <runge@karlrunge.com>
- * first pass at doing modtweak via XKEYBOARD extension (-xkb)
- * -skip_keycodes option for use with -xkb
- * reset modtweak and xkb_modtweak on event MappingNotify.
- * trap Xerror during XSendEvent/XChangeProperty.
- * fix bug requesting PRIMARY way too often.
- * more careful to check if XKeysymToString returns NULL.
- * continuation lines "\" in x11vncrc.
- * undoc'd expts: -isolevel3, -xkbcompat
-
-2004-07-19 Karl Runge <runge@karlrunge.com>
- * ignore keysyms 5-8 for keycode keymapping.
- * help to stdout for easy paging, add lastmod to help and -version.
-
-2004-07-15 Karl Runge <runge@karlrunge.com>
- * make "modtweak" the default, disable with -nomodtweak. this
- corrects ghost "< >" key on pc104 us in XFree86.
- * fix bug wrt no got_keyboard_input under modtweak
-
-2004-07-10 Karl Runge <runge@karlrunge.com>
- * -norepeat to turn off X server autorepeat when clients exist,
- (this is workaround for the repeating keystroke bug. Note that
- client side does autorepeating so not a big loss).
-
-2004-07-04 Karl Runge <runge@karlrunge.com>
- * extend -allow to re-read a file with allowed IP addresses.
- * improvements to -help text.
-
-2004-07-01 Karl Runge <runge@karlrunge.com>
- * improve scaled grid calculation to prevent drift (which causes
- drift in pixel weights and poorer tightvnc compression)
- * add ":pad" scale option, detect small fraction scale = m/n.
-
-2004-06-28 Karl Runge <runge@karlrunge.com>
- * round scaled width to multiple of 4 to make vncviewer happy.
- * allow override of above ":n4" and allow 4 point interpolation
- to be used even with shrinking ":in".
-
-2004-06-27 Karl Runge <runge@karlrunge.com>
- * speed up scaling a bit for slow machines (still all floating point)
- * add no blending option (-scale fraction:nb)
-
-2004-06-26 Karl Runge <runge@karlrunge.com>
- * add -scale fract for global (not per-client) server-side scaling
- working more or less OK, needs to be optimized at some point.
- * remove -hints/-nohints options.
-
-2004-06-17 Karl Runge <runge@karlrunge.com>
- * simple ~/.x11vncrc config file support, -rc, -norc
-
-2004-06-12 Karl Runge <runge@karlrunge.com>
- * add -clear_mods -clear_keys for (rare) case where keys are
- not being released (e.g. Ctrl-C x11vnc thru x11vnc).
- * export RFB_SERVER_IP and RFB_SERVER_PORT to -accept program
- so that the tcp 4-tuple is completely specified.
- * add -storepasswd <pass> <file> so storepasswd program not needed
-
-2004-06-05 Karl Runge <runge@karlrunge.com>
- * rearrange file for easier maintenance, indicating file breakup.
- * add RFB_CLIENT_COUNT, number of other connected clients to
- -accept and -gone commands.
-
-2004-05-27 Karl Runge <runge@karlrunge.com>
- * add view-only passwd via -viewpasswd and 2nd line of -passwdfile
-
-2004-05-21 Karl Runge <runge@karlrunge.com>
- * -accept: add view-only decision and other improvements.
- * add -gone command option for when a client leaves.
- Thanks to Jesus Alvarez for these ideas.
- * -passwdfile to keep passwd off of cmd line.
- * -o logfile send stderr to a logfile.
-
-2004-05-14 Karl Runge <runge@karlrunge.com>
- * improvements to -accept popup: yes/no buttons and timeout.
- * less fprintf under -q so '-q -inetd' has no stderr output.
-
-2004-05-08 Karl Runge <runge@karlrunge.com>
- * add -accept some-command/xmessage/popup to prompt local X11 user
- or otherwise decide to accept an incoming client.
- * clean up -Wall warnings.
-
-2004-05-05 Karl Runge <runge@karlrunge.com>
- * enable mouse button -> keystrokes mapping in -buttonmap (mousewheel)
- * enable keystroke -> mouse button mapping in -remap (touchpad paste)
- (-remap incompat ':' -> '-', sorry...)
- * shm OS blacklist (i.e. <= SunOS 5.8) -> -onetile
- * revert to check_user_input() under -nofb
- * cleanup: lastmod, remove tile_shm and update_client_pointer,
- debug output, rfbPort failure.
- * user friendly last line: 'The VNC desktop is hostname:0'
-
-2004-04-28 Karl Runge <runge@karlrunge.com>
- * -auth cmdline option for xauthority.
- * decrease default deferupdate under -nofb.
- * update_client_pointer() from Edoardo Tirtarahardja.
- * remove some assumptions about libvncserver defaults.
-
-2004-04-19 Karl Runge <runge@karlrunge.com>
- * support for cursor positions updates -cursorpos
- * option for SIGPIPE handling -sigpipe
-
-2004-04-13 Karl Runge <runge@karlrunge.com>
- * solve problem with sending selection when client initializing
- (not yet in RFB_NORMAL state). Increase delay to 15s as well.
- * when threaded: limit rfbMaxClientWait to >= 20 secs and
- increase it to a huge value unless -rfbwait is supplied.
-
-2004-04-08 Karl Runge <runge@karlrunge.com>
- * added support for blacking out regions of the screen, primarily
- for Xinerama usage, options: -blackout -xinerama
- * Xinerama workaround mouse problem on 'embedded' system,
- option -xwarppointer (XWarpPointer instead of XTEST)
- * let -remap option take key remappings on cmdline as well as file.
- * use cargs fix to test for invalid cmdline options. Add --option.
- * remove copy_tile, use copy_tiles(..., 1) instead.
-
-2004-03-10 Karl Runge <runge@karlrunge.com>
- * added reverse connection for vncconnect(1) and other means
- -vncconnect, -connect host:port, and -connect watchfile
- * added first pass at user keysym remapping feature via
- -remap file. Ignores modifier state, need to generalize.
- * debugging options for users -debug_pointer and -debug_keyboard
- * clear -passwd from argv for privacy (if OS allows).
-
-2004-02-19 Karl Runge <runge@karlrunge.com>
- * added handling of clipboard/selection exchange to/from clients,
- even holds PRIMARY which Xvnc does not do. disable with -nosel.
- use -noprimary to disable polling of PRIMARY selection.
- * added -visual option to force framebuffer visual. not really
- of general use, more for testing and workarounds (e.g. win2vnc
- fails under 8bpp index color)
- * improve cleanup and error handling WRT shm and other failures.
-
-2004-01-19 Karl Runge <runge@karlrunge.com>
- * improvements to pointer event handling primarily during window
- dragging. check_user_input() for non-threaded and pointer()
- for threaded. Revert to old way via -old_pointer option.
- * some memory I/O improvement by using copy_tiles() instead
- of copy_tile(). New one does rows of tiles at same time.
- Revert to old way via -old_copytile.
- * handle case of more mouse buttons on client than on X server.
- * added -buttonmap option for finer control over button differences.
-
-2004-01-09 Karl Runge <runge@karlrunge.com>
- * options -allow / -localhost for simple IP based access screening
- * option -nodragging to skip all screen updates during mouse drags
- (thanks to Michal Sabala)
- * option -input_skip to allow users to tune watch_loop dropthru rate
- * try to avoid wasting RAM for framebuffer under -nofb
- * cleanup wrt bpp vs. depth
-
-2003-12-08 Karl Runge <runge@karlrunge.com>
- * add Xbell support using XKEYBOARD extension (disable: -nobell)
- * add "-nofb" to disable framebuffer, i.e. mouse + keyboard only (!)
- * add "-notruecolor" to force indexed 8bpp color (when 8bpp)
- * make alias "-forever" for "-many"
-
-From Karl (x11vnc's father) on Apr 2, 2003:
-
-New option -nocursor to not display the vncviewer local cursor if user
-does not want it (also caused some problems with older vncviewers)
-
-New option -mouse to show the position of the X server mouse (i.e. lagged
-from the user's vnc cursor position). Also: -mouseX will try to show
-the a different cursor (X) when on the root background.
-
-New option -many to wait for more connections rather than exiting when
-the first client(s) disconnect.
-
-New option -flashcmap to try to follow installed colormaps under 8bpp
-indexed color as pointer is moved.
-
-New option -nap to watch for low activity and throttle down the polling
-rate. Useful on shared machines to keep the load down.
-
-Experimental option -id <windowid> to show just that window and not
-the whole display. Some remaining bugs and inconvenient behavior...
-(e.g. new toplevels can be unseen)
-
-Fixed bug on multi-headed machines where the screen number was being
-ignored in a number of places.
-
-Fixed bug wrt connect_once mode. Now just refuses new clients unless
-shared rather than terminating all clients.
-
-Try to follow changing default colormap under 8bpp indexed color
-as color cells are added.
-
-Needed to pick up HAVE_LIBPTHREAD from autoconf.
-
-defined a select() macro for usleep() since usleep is not always thread
-safe.
-
-Catch and exit on errors in the shm setup work (XShmCreateImage, shmget,...)
-and moved the creation and removal work to separate utility functions.
-
-Added signal and X error handlers to try to clean out the shm objects
-before exiting on interrupt, etc.
-
-Improved performance a bit on the memcmp() in scan_display() by checking
-the whole line first.
-
-Added a workaround when threaded where libvncserver may disconnect too
-early if it does not hear from a client (a small heartbeat is sent).
-This may not be needed any longer.
-
-If -desktop has not been prescribed, try to choose a title based on DISPLAY
-and the hostname (and window name under -id).
diff --git a/x11vnc/Makefile.am b/x11vnc/Makefile.am
deleted file mode 100644
index 12ca9f1..0000000
--- a/x11vnc/Makefile.am
+++ /dev/null
@@ -1,43 +0,0 @@
-if HAVE_SYSTEM_LIBVNCSERVER
-LDADD = @SYSTEM_LIBVNCSERVER_LIBS@ @WSOCKLIB@
-else
-LDADD = ../libvncserver/libvncserver.la ../libvncclient/libvncclient.la @WSOCKLIB@
-endif
-
-if OSX
-FRAMEWORKS = -framework ApplicationServices -framework Carbon -framework IOKit -framework Cocoa
-if OSX_OPENGL
-FRAMEWORKS += -framework OpenGL
-if HAVE_X11
-GL = /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib
-FRAMEWORKS += -dylib_file $(GL):$(GL)
-endif
-endif
-x11vnc_LDFLAGS = $(FRAMEWORKS)
-x11vnc_CFLAGS = -ObjC
-endif
-
-SUBDIRS = misc
-DIST_SUBDIRS = misc
-
-desktopdir = $(datadir)/applications
-desktop_DATA = x11vnc.desktop
-
-man_MANS=x11vnc.1
-EXTRA_DIST=ChangeLog README RELEASE-NOTES tkx11vnc $(man_MANS) $(desktop_DATA)
-
-if CYGIPC
-LD_CYGIPC=-lcygipc
-endif
-
-bin_PROGRAMS=x11vnc
-x11vnc_SOURCES = 8to24.c appshare.c avahi.c cleanup.c connections.c cursor.c gui.c help.c inet.c keyboard.c linuxfb.c macosx.c macosxCG.c macosxCGP.c macosxCGS.c macosx_opengl.c options.c pm.c pointer.c rates.c remote.c scan.c screen.c selection.c solid.c sslcmds.c sslhelper.c uinput.c unixpw.c user.c userinput.c util.c v4l.c win_utils.c x11vnc.c x11vnc_defs.c xdamage.c xevents.c xinerama.c xkb_bell.c xrandr.c xrecord.c xwrappers.c 8to24.h allowed_input_t.h avahi.h blackout_t.h cleanup.h connections.h cursor.h enc.h enums.h gui.h help.h inet.h keyboard.h linuxfb.h macosx.h macosxCG.h macosxCGP.h macosxCGS.h macosx_opengl.h nox11.h nox11_funcs.h options.h params.h pm.h pointer.h rates.h remote.h scan.h screen.h scrollevent_t.h selection.h solid.h sslcmds.h sslhelper.h ssltools.h tkx11vnc.h uinput.h unixpw.h user.h userinput.h util.h v4l.h win_utils.h winattr_t.h x11vnc.h xdamage.h xevents.h xinerama.h xkb_bell.h xrandr.h xrecord.h xwrappers.h
-
-if HAVE_SYSTEM_LIBVNCSERVER
-INCLUDES_LIBVNCSERVER = @SYSTEM_LIBVNCSERVER_CFLAGS@
-else
-INCLUDES_LIBVNCSERVER = -I${top_srcdir}
-endif
-INCLUDES = $(INCLUDES_LIBVNCSERVER) @X_CFLAGS@ @AVAHI_CFLAGS@
-
-x11vnc_LDADD=$(LDADD) @SSL_LIBS@ @CRYPT_LIBS@ @X_LIBS@ @AVAHI_LIBS@ $(LD_CYGIPC)
diff --git a/x11vnc/README b/x11vnc/README
deleted file mode 100644
index e8457e6..0000000
--- a/x11vnc/README
+++ /dev/null
@@ -1,18246 +0,0 @@
-
-Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
-All rights reserved.
-
-x11vnc README file Date: Mon Dec 27 20:58:57 EST 2010
-
-The following information is taken from these URLs:
-
- http://www.karlrunge.com/x11vnc/index.html
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- ...
-
-they contain the most up to date info.
-
-
-=======================================================================
-http://www.karlrunge.com/x11vnc/index.html:
-
-
- _________________________________________________________________
-
-x11vnc: a VNC server for real X displays
- (to FAQ) (to Downloads) (to Building) (to Beta Test)
- (to Donations) [PayPal]
-
- x11vnc allows one to view remotely and interact with real X displays
- (i.e. a display corresponding to a physical monitor, keyboard, and
- mouse) with any VNC viewer. In this way it plays the role for Unix/X11
- that WinVNC plays for Windows.
-
- It has built-in SSL/TLS encryption and 2048 bit RSA authentication,
- including VeNCrypt support; UNIX account and password login support;
- server-side scaling; single port HTTPS/HTTP+VNC; Zeroconf service
- advertising; and TightVNC and UltraVNC file-transfer. It has also been
- extended to work with non-X devices: natively on Mac OS X Aqua/Quartz,
- webcams and TV tuner capture devices, and embedded Linux systems such
- as Qtopia Core. Full IPv6 support is provided. More features are
- described here.
-
- It also provides an encrypted Terminal Services mode (-create, -svc,
- or -xdmsvc options) based on Unix usernames and Unix passwords where
- the user does not need to memorize his VNC display/port number.
- Normally a virtual X session (Xvfb) is created for each user, but it
- also works with X sessions on physical hardware. See the tsvnc
- terminal services mode of the SSVNC viewer for one way to take
- advantage of this mode.
-
- I wrote x11vnc back in 2002 because x0rfbserver was basically
- impossible to build on Solaris and had poor performance. The primary
- x0rfbserver build problems centered around esoteric C++ toolkits.
- x11vnc is written in plain C and needs only standard libraries and so
- should work on nearly all Unixes, even very old ones. I also created
- enhancements to improve the interactive response, added many features,
- and etc.
-
- This page including the FAQ contains much information [*]; solutions
- to many problems; and interesting applications, but nevertheless
- please feel free to contact me if you have problems or questions (and
- if I save you time or expense by giving you some of my time, please
- consider a PayPal Donation.) Do check the FAQ and this page first; I
- realize the pages are massive, but you can often use your browser's
- find-in-page search action using a keyword to find the answer to your
- problem or question.
-
- SSVNC: An x11vnc side-project provides an Enhanced TightVNC Viewer
- package (SSVNC) for Unix, Windows, and Mac OS X with automatic SSL
- and/or SSH tunnelling support, SSL Certificate creation, Saved
- connection profiles, Zeroconf, VeNCrypt, and built-in Proxy support.
- Added features for the TightVNC Unix viewer: NewFBSize, ZRLE encoding,
- Viewer-side Scaling, cursor alphablending, low color modes, and
- enhanced popup menu; UltraVNC extensions support for: File Transfer,
- Text Chat, Single Window, Server Input, and 1/n Scaling extensions,
- and UltraVNC DSM encryption. The SSVNC bundle could be placed on, say,
- a USB memory stick for SSL/SSH VNC viewing from nearly any networked
- computer.
-
- _________________________________________________________________
-
- Announcements:
-
- Important: If you created any permanent SSL certificates (e.g. via
- "x11vnc -ssl SAVE ...") on a Debian or Ubuntu system from Sept. 2006
- through May 2008, then those keys are likely extremely weak and can be
- easily cracked. The certificate files should be deleted and recreated
- on a non-Debian system or an updated one. See
- http://www.debian.org/security/2008/dsa-1571 for details. The same
- applies to SSH keys (not used by x11vnc directly, but many people use
- SSH tunnels for VNC access.)
-
- FAQ moved: The huge FAQ has finally been moved to its own page. If you
- are trying to follow someone's link to an FAQ once on this page it is
- now a broken link. Try inserting the string "faq.html", e.g.:
-from: http://www.karlrunge.com/x11vnc/#faq-singleclick
-to: http://www.karlrunge.com/x11vnc/faq.html#faq-singleclick
-
- Apologies for the inconvenience, unfortunately it is not possible to
- automatically redirect to the new page since the '#' anchor is not
- sent to the webserver.
-
- _________________________________________________________________
-
- Background:
-
- VNC (Virtual Network Computing) is a very useful network graphics
- protocol (applications running on one computer but displaying their
- windows on another) in the spirit of X, however, unlike X, the
- viewing-end is very simple and maintains no state. It is a remote
- framebuffer (RFB) protocol.
-
- Some VNC links:
- * http://www.realvnc.com
- * http://www.tightvnc.com
- * http://www.ultravnc.com/
- * http://www.testplant.com/products/vine_server/OS_X
-
- For Unix, the traditional VNC implementation includes a "virtual" X11
- server Xvnc (usually launched via the vncserver command) that is not
- associated with a physical display, but provides a "fake" one X11
- clients (xterm, firefox, etc.) can attach to. A remote user then
- connects to Xvnc via the VNC client vncviewer from anywhere on the
- network to view and interact with the whole virtual X11 desktop.
-
- The VNC protocol is in most cases better suited for remote connections
- with low bandwidth and high latency than is the X11 protocol because
- it involves far fewer "roundtrips" (an exception is the cached pixmap
- data on the viewing-end provided by X.) Also, with no state maintained
- the viewing-end can crash, be rebooted, or relocated and the
- applications and desktop continue running. Not so with X11.
-
- So the standard Xvnc/vncserver program is very useful, I use it for
- things like:
- * Desktop conferencing with other users (e.g. code reviews.)
- * Long running apps/tasks I want to be able to view from many places
- (e.g. from home and work.)
- * Motif, GNOME, and similar applications that would yield very poor
- performance over a high latency link.
-
- However, sometimes one wants to connect to a real X11 display (i.e.
- one attached to a physical monitor, keyboard, and mouse: a Workstation
- or a SunRay session) from far away. Maybe you want to close down an
- application cleanly rather than using kill, or want to work a bit in
- an already running application, or would like to help a distant
- colleague solve a problem with their desktop, or would just like to
- work out on the deck for a while. This is where x11vnc is useful.
- _________________________________________________________________
-
- How to use x11vnc:
-
- In this basic example let's assume the remote machine with the X
- display you wish to view is "far-away.east:0" and the workstation you
- are presently working at is "sitting-here.west".
-
- Step 0. Download x11vnc (see below) and have it available to run on
- far-away.east (on some linux distros it is as easy as "apt-get install
- x11vnc", "emerge x11vnc", etc.) Similarly, have a VNC viewer (e.g.
- vncviewer) ready to run on sitting-here.west. We recommend TightVNC
- Viewers (see also our SSVNC viewer.)
-
- Step 1. By some means log in to far-away.east and get a command shell
- running there. You can use ssh, or even rlogin, telnet, or any other
- method to do this. We do this because the x11vnc process needs to be
- run on the same machine the X server process is running on (otherwise
- things would be extremely slow.)
-
- Step 2. In that far-away.east shell (with command prompt "far-away>"
- in this example) run x11vnc directed at the far-away.east X session
- display:
-
- far-away> x11vnc -display :0
-
- You could have also set the environment variable DISPLAY=:0 instead of
- using "-display :0". This step attaches x11vnc to the far-away.east:0
- X display (i.e. no viewer clients yet.)
-
- Common Gotcha: To get X11 permissions right, you may also need to set
- the XAUTHORITY environment variable (or use the -auth option) to point
- to the correct MIT-MAGIC-COOKIE file (e.g. /home/joe/.Xauthority.) If
- x11vnc does not have the authority to connect to the display it exits
- immediately. More on how to fix this below.
-
- If you suspect an X11 permissions problem do this simple test: while
- sitting at the physical X display open a terminal window
- (gnome-terminal, xterm, etc.) You should be able to run x11vnc
- successfully in that terminal without any need for command line
- options. If that works OK then you know X11 permissions are the only
- thing preventing it from working when you try to start x11vnc via a
- remote shell. Then fix this with the tips below.
-
- Note as of Feb/2007 you can also try the -find option instead of
- "-display ..." and see if that finds your display and Xauthority. Note
- as of Dec/2009 the -findauth and "-auth guess" options may be helpful
- as well.
- (End of Common Gotcha)
-
- When x11vnc starts up there will then be much chatter printed out (use
- "-q" to quiet it), until it finally says something like:
- .
- .
- 13/05/2004 14:59:54 Autoprobing selected port 5900
- 13/05/2004 14:59:54 screen setup finished.
- 13/05/2004 14:59:54
- 13/05/2004 14:59:54 The VNC desktop is far-away:0
- PORT=5900
-
- which means all is OK, and we are ready for the final step.
-
- Step 3. At the place where you are sitting (sitting-here.west in this
- example) you now want to run a VNC viewer program. There are VNC
- viewers for Unix, Windows, MacOS, Java-enabled web browsers, and even
- for PDA's like the Palm Pilot and Cell Phones! You can use any of them
- to connect to x11vnc (see the above VNC links under "Background:" on
- how to obtain a viewer for your platform or see this FAQ. For Solaris,
- vncviewer is available in the Companion CD package SFWvnc.)
-
- In this example we'll use the Unix vncviewer program on sitting-here
- by typing the following command in a second terminal window:
-
- sitting-here> vncviewer far-away.east:0
-
- That should pop up a viewer window on sitting-here.west showing and
- allowing interaction with the far-away.east:0 X11 desktop. Pretty
- nifty! When finished, exit the viewer: the remote x11vnc process will
- shutdown automatically (or you can use the -forever option to have it
- wait for additional viewer connections.)
-
- Common Gotcha: Nowadays there will likely be a host-level firewall on
- the x11vnc side that is blocking remote access to the VNC port (e.g.
- 5900.) You will either have to open up that port (or a range of ports)
- in your firewall administration tool, or try the SSH tunnelling method
- below (even still the firewall must allow in the SSH port, 22.)
-
-
- Shortcut: Of course if you left x11vnc running on far-away.east:0 in a
- terminal window with the -forever option or as a service, you'd only
- have to do Step 3 as you moved around. Be sure to use a VNC Password
- or other measures if you do that.
-
-
- Super Shortcut: Here is a potentially very easy way to get all of it
- working.
- * Have x11vnc (0.9.3 or later) available to run on the remote host
- (i.e. in $PATH.)
- * Download and unpack a SSVNC bundle (1.0.19 or later, e.g.
- ssvnc_no_windows-1.0.28.tar.gz) on the Viewer-side machine.
- * Start the SSVNC Terminal Services mode GUI: ./ssvnc/bin/tsvnc
- * Enter your remote username@hostname (e.g. fred@far-away.east) in
- the "VNC Terminal Server" entry.
- * Click "Connect".
-
- That will do an SSH to username@hostname and start up x11vnc and then
- connect a VNC Viewer through the SSH encrypted tunnel.
-
- There are a number of things assumed here, first that you are able to
- SSH into the remote host; i.e. that you have a Unix account there and
- the SSH server is running. On Unix and MacOS X it is assumed that the
- ssh client command is available on the local machine (on Windows a
- plink binary is included in the SSVNC bundle.) Finally, it is assumed
- that you are already logged into an X session on the remote machine,
- e.g. your workstation (otherwise, a virtual X server, e.g. Xvfb, will
- be started for you.)
-
- In some cases the remote SSH server will not run commands with the
- same $PATH that you normally have in your shell there. In this case
- click on Options -> Advanced -> X11VNC Options, and type in the
- location of the x11vnc binary under "Full Path". (End of Super
- Shortcut)
-
-
- Desktop Sharing: The above more or less assumed nobody was sitting at
- the workstation display "far-away.east:0". This is often the case: a
- user wants to access her workstation remotely. Another usage pattern
- has the user sitting at "far-away.east:0" and invites one or more
- other people to view and interact with his desktop. Perhaps the user
- gives a demo or presentation this way (using the telephone for vocal
- communication.) A "Remote Help Desk" mode would be similar: a
- technician connects remotely to the user's desktop to interactively
- solve a problem the user is having.
-
- For these cases it should be obvious how it is done. The above steps
- will work, but more easily the user sitting at far-away.east:0 simply
- starts up x11vnc from a terminal window, after which the guests would
- start their VNC viewers. For this usage mode the "-connect
- host1,host2" option may be of use to automatically connect to the
- vncviewers in "-listen" mode on the list of hosts.
- _________________________________________________________________
-
- Tunnelling x11vnc via SSH:
-
- The above example had no security or privacy at all. When logging into
- remote machines (certainly when going over the internet) it is best to
- use ssh, or use a VPN (for a VPN, Virtual Private Network, the above
- example should be pretty safe.)
-
- For x11vnc one can tunnel the VNC protocol through an encrypted ssh
- channel. It would look something like running the following commands:
- sitting-here> ssh -t -L 5900:localhost:5900 far-away.east 'x11vnc -localhost
--display :0'
-
- (you will likely have to provide passwords/passphrases to login from
- sitting-here into your far-away.east Unix account; we assume you have
- a login account on far-away.east and it is running the SSH server)
-
- And then in another terminal window on sitting-here run the command:
- sitting-here> vncviewer -encodings "copyrect tight zrle hextile" localhost:0
-
- Note: The -encodings option is very important: vncviewer will often
- default to "raw" encoding if it thinks the connection is to the local
- machine, and so vncviewer gets tricked this way by the ssh
- redirection. "raw" encoding will be extremely slow over a networked
- link, so you need to force the issue with -encodings "copyrect tight
- ...". Nowadays, not all viewers use the -encodings option, try
- "-PreferredEncoding=ZRLE" (although the newer viewers seem to
- autodetect well when to use raw or not.)
-
- Note that "x11vnc -localhost ..." limits incoming vncviewer
- connections to only those from the same machine. This is very natural
- for ssh tunnelling (the redirection appears to come from the same
- machine.) Use of a VNC password is also strongly recommended.
-
- Note also the -t we used above (force allocate pseudoterminal), it
- actually seems to improve interactive typing response via VNC!
-
- You may want to add the -C option to ssh to enable compression. The
- VNC compression is not perfect, and so this may help a bit. However,
- over a fast LAN you probably don't want to enable SSH compression
- because it can slow things down. Try both and see which is faster.
-
- If your username is different on the remote machine use something
- like: "fred@far-away.east" in the above ssh command line.
-
- Some VNC viewers will do the ssh tunnelling for you automatically, the
- TightVNC Unix vncviewer does this when the "-via far-away.east" option
- is supplied to it (this requires x11vnc to be already running on
- far-away.east or having it started by inetd(8).) See the 3rd script
- example below for more info.
-
- SSVNC: You may also want to look at the Enhanced TightVNC Viewer
- (ssvnc) bundles because they contain scripts and GUIs to automatically
- set up SSH tunnels (e.g. the GUI, "ssvnc", does it automatically and
- so does this command: "ssvnc_cmd -ssh user@far-away.east:0") and can
- even start up x11vnc as well.
-
- The Terminal Services mode of SSVNC is perhaps the easiest way to use
- x11vnc. You just need to have x11vnc available in $PATH on the remote
- side (and can SSH to the host), and then on the viewer-side you type
- something like:
- tsvnc fred@far-away.east
-
- everything else is done automatically for you. Normally this will
- start a virtual Terminal Services X session (RAM-only), but if you
- already have a real X session up on the physical hardware it will find
- that one for you.
-
- Gateways: If the machine you SSH into is not the same machine with
- the X display you wish to view (e.g. your company provides incoming
- SSH access to a gateway machine), then you need to change the above
- to, e.g.: "-L 5900:OtherHost:5900":
- sitting-here> ssh -t -L 5900:OtherHost:5900 gateway.east
-
- Where gateway.east is the internet hostname (or IP) of the gateway
- machine (SSH server.) 'OtherHost' might be, e.g., freds-pc or
- 192.168.2.33 (it is OK for these to be private hostnames or private IP
- addresses, the host in -L is relative to the remote server side.)
-
- Once logged in, you'll need to do a second login (ssh, rsh, etc.) to
- the workstation machine 'OtherHost' and then start up x11vnc on it (if
- it isn't already running.) (The "-connect gateway:59xx" option may be
- another alternative here with the viewer already in -listen mode.) For
- an automatic way to use a gateway and have all the network traffic
- encrypted (including inside the firewall) see Chaining SSH's.
-
- These gateway access modes also can be done automatically for you via
- the "Proxy/Gateway" setting in SSVNC (including the Chaining SSH's
- case, "Double Proxy".)
-
- Firewalls/Routers:
-
- A lot of people have inexpensive devices for home or office that act
- as a Firewall and Router to the machines inside on a private LAN. One
- can usually configure the Firewall/Router from inside the LAN via a
- web browser.
-
- Often having a Firewall/Router sitting between the vncviewer and
- x11vnc will make it impossible for the viewer to connect to x11vnc.
-
- One thing that can be done is to redirect a port on the
- Firewall/Router to, say, the SSH port (22) on an inside machine (how
- to do this depends on your particular Firewall/Router, often the
- router config URL is http://192.168.100.1 See www.portforward.com for
- more info.) This way you reach these computers from anywhere on the
- Internet and use x11vnc to view X sessions running on them.
-
- Suppose you configured the Firewall/Router to redirect these ports to
- two internal machines:
- Port 12300 -> 192.168.1.3, Port 22 (SSH)
- Port 12301 -> 192.168.1.4, Port 22 (SSH)
-
- (where 192.168.1.3 is "jills-pc" and 192.168.1.4 is "freds-pc".) Then
- the ssh's would look something like:
- sitting-here> ssh -t -p 12300 -L 5900:localhost:5900 jill@far-away.east 'x11v
-nc -localhost -display :0'
- sitting-here> ssh -t -p 12301 -L 5900:localhost:5900 fred@far-away.east 'x11v
-nc -localhost -display :0'
-
- Where far-away.east means the hostname (or IP) that the
- Router/Firewall is using (for home setups this is usually the IP
- gotten from your ISP via DHCP, the site http://www.whatismyip.com/ is
- a convenient way to determine what it is.)
-
- It is a good idea to add some obscurity to accessing your system via
- SSH by using some high random port (e.g. 12300 in the above example.)
- If you can't remember it, or are otherwise not worried about port
- scanners detecting the presence of your SSH server and there is just
- one internal PC involved you could map 22:
- Port 22 -> 192.168.1.3, Port 22 (SSH)
-
- Again, this SSH gateway access can be done automatically for you via
- the "Proxy/Gateway" setting in SSVNC. And under the "Remote SSH
- Command" setting you can enter the x11vnc -localhost -display :0.
-
- Host-Level-Firewalls: even with the hardware Firewall/Router problem
- solved via a port redirection, most PC systems have their own Host
- level "firewalls" enabled to protect users from themselves. I.e. the
- system itself blocks all incoming connections. So you will need to see
- what is needed to configure it to allow in the port (e.g. 22) that you
- desire. E.g. Yast, Firestarter, iptables(1), etc..
-
- VNC Ports and Firewalls: The above discussion was for configuring the
- Firewall/Router to let in port 22 (SSH), but the same thing can be
- done for the default VNC port 5900:
- Port 5900 -> 192.168.1.3, Port 5900 (VNC)
- Port 5901 -> 192.168.1.4, Port 5900 (VNC)
-
- (where 192.168.1.3 is "jills-pc" and 192.168.1.4 is "freds-pc".) This
- could be used for normal, unencrypted connections and also for SSL
- encrypted ones.
-
- The VNC displays to enter in the VNC viewer would be, say,
- "far-away.east:0" to reach jills-pc and "far-away.east:1" to reach
- freds-pc. We assume above that x11vnc is using port 5900 (and any
- Host-Level-firewalls on jills-pc has been configured to let that port
- in.) Use the "-rfbport" option to tell which port x11vnc should listen
- on.
-
- For a home system one likely does not have a hostname and would have
- to use the IP address, say, "24.56.78.93:0". E.g.:
- vncviewer 24.56.78.93:0
-
- You may want to choose a more obscure port on the router side, e.g.
- 5944, to avoid a lot of port scans finding your VNC server. For 5944
- you would tell the viewer to use:
- vncviewer 24.56.78.93:44
-
- The IP address would need to be communicated to the person running the
- VNC Viewer. The site http://www.whatismyip.com/ can help here.
-
- _________________________________________________________________
-
- Scripts to automate ssh tunneling: As discussed below, there may be
- some problems with port 5900 being available. If that happens, the
- above port and display numbers may change a bit (e.g. -> 5901 and :1).
- However, if you "know" port 5900 will be free on the local and remote
- machines, you can easily automate the above two steps by using the
- x11vnc option -bg (forks into background after connection to the
- display is set up) or using the -f option of ssh. Some example scripts
- are shown below. Feel free to try the ssh -C to enable its compression
- and see if that speeds things up noticeably.
- _________________________________________________________________
-
- #1. A simple example script, assuming no problems with port 5900 being
- taken on the local or remote sides, looks like:
-#!/bin/sh
-# usage: x11vnc_ssh <host>:<xdisplay>
-# e.g.: x11vnc_ssh snoopy.peanuts.com:0
-# (user@host:N also works)
-
-host=`echo $1 | awk -F: '{print $1}'`
-disp=`echo $1 | awk -F: '{print $2}'`
-if [ "x$disp" = "x" ]; then disp=0; fi
-
-cmd="x11vnc -display :$disp -localhost -rfbauth .vnc/passwd"
-enc="copyrect tight zrle hextile zlib corre rre raw"
-
-ssh -f -t -L 5900:localhost:5900 $host "$cmd"
-
-for i in 1 2 3
-do
- sleep 2
- if vncviewer -encodings "$enc" :0; then break; fi
-done
-
- See also rx11vnc.pl below.
- _________________________________________________________________
-
- #2. Another method is to start the VNC viewer in listen mode
- "vncviewer -listen" and have x11vnc initiate a reverse connection
- using the -connect option:
-#!/bin/sh
-# usage: x11vnc_ssh <host>:<xdisplay>
-# e.g.: x11vnc_ssh snoopy.peanuts.com:0
-# (user@host:N also works)
-
-host=`echo $1 | awk -F: '{print $1}'`
-disp=`echo $1 | awk -F: '{print $2}'`
-if [ "x$disp" = "x" ]; then disp=0; fi
-
-cmd="x11vnc -display :$disp -localhost -connect localhost" # <== note new opt
-ion
-enc="copyrect tight zrle hextile zlib corre rre raw"
-
-vncviewer -encodings "$enc" -listen &
-pid=$!
-ssh -t -R 5500:localhost:5500 $host "$cmd"
-kill $pid
-
- Note the use of the ssh option "-R" instead of "-L" to set up a remote
- port redirection.
- _________________________________________________________________
-
- #3. A third way is specific to the TightVNC vncviewer special option
- -via for gateways. The only tricky part is we need to start up x11vnc
- and give it some time (5 seconds in this example) to start listening
- for connections (so we cannot use the TightVNC default setting for
- VNC_VIA_CMD):
-#!/bin/sh
-# usage: x11vnc_ssh <host>:<xdisplay>
-# e.g.: x11vnc_ssh snoopy.peanuts.com:0
-
-host=`echo $1 | awk -F: '{print $1}'`
-disp=`echo $1 | awk -F: '{print $2}'`
-if [ "x$disp" = "x" ]; then disp=0; fi
-
-VNC_VIA_CMD="ssh -f -t -L %L:%H:%R %G x11vnc -localhost -rfbport 5900 -display
-:$disp; sleep 5"
-export VNC_VIA_CMD
-
-vncviewer -via $host localhost:0 # must be TightVNC vncviewer.
-
- Of course if you already have the x11vnc running waiting for
- connections (or have it started out of inetd(8)), you can simply use
- the TightVNC "vncviewer -via gateway host:port" in its default mode to
- provide secure ssh tunnelling.
- _________________________________________________________________
-
-
-
- VNC password file: Also note in the #1. example script that the option
- "-rfbauth .vnc/passwd" provides additional protection by requiring a
- VNC password for every VNC viewer that connects. The vncpasswd or
- storepasswd programs, or the x11vnc -storepasswd option can be used to
- create the password file. x11vnc also has the slightly less secure
- -passwdfile and "-passwd XXXXX" options to specify passwords.
-
- Very Important: It is up to YOU to tell x11vnc to use password
- protection (-rfbauth or -passwdfile), it will NOT do it for you
- automatically or force you to (use -usepw if you want to be forced
- to.) The same goes for encrypting the channel between the viewer and
- x11vnc: it is up to you to use ssh, stunnel, -ssl mode, a VPN, etc.
- (use the Enhanced TightVNC Viewer (SSVNC) GUI if you want to be forced
- to use SSL or SSH.) For additional safety, also look into the -allow
- and -localhost options and building x11vnc with tcp_wrappers support
- to limit host access.
-
- _________________________________________________________________
-
- Tunnelling x11vnc via SSL/TLS:
-
- One can also encrypt the VNC traffic using an SSL/TLS tunnel such as
- stunnel.mirt.net (also stunnel.org) or using the built-in (Mar/2006)
- -ssl openssl mode. A SSL-enabled Java applet VNC Viewer is also
- provided in the x11vnc package (and https can be used to download it.)
-
- Although not as ubiquitous as ssh, SSL tunnelling still provides a
- useful alternative. See this FAQ on -ssl and -stunnel modes for
- details and examples.
-
- The Enhanced TightVNC Viewer (SSVNC) bundles contain some convenient
- utilities to automatically set up an SSL tunnel from the viewer-side
- (i.e. to connect to "x11vnc -ssl ...".) And many other enhancements
- too.
- _________________________________________________________________
-
- Downloading x11vnc:
-
- x11vnc is a contributed program to the LibVNCServer project at
- 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 GIT tree) from the above
- link. As of Sep 2010, the x11vnc-0.9.12.tar.gz source package is
- released (recommended download). The x11vnc 0.9.12 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 x11vnc-0.9.13-dev.tar.gz tarball to build the most up to
- date one.
-
- Precompiled Binaries/Packages: See the FAQ below for information
- about where you might obtain a precompiled x11vnc binary from 3rd
- parties and some ones I create.
-
- VNC Viewers: To obtain VNC viewers for the viewing side (Windows, Mac
- OS, or Unix) try these links:
- * http://www.tightvnc.com/download.html
- * http://www.realvnc.com/download-free.html
- * http://sourceforge.net/projects/cotvnc/
- * http://www.ultravnc.com/
- * Our Enhanced TightVNC Viewer (SSVNC)
-
- [ssvnc.gif]
-
-
- More tools: Here is a ssh/rsh wrapper script rx11vnc that attempts to
- automatically do the above Steps 1-3 for you (provided you have
- ssh/rsh login permission on the machine x11vnc is to be run on.) The
- above example would be: "rx11vnc far-away.east:0" typed into a shell
- on sitting-here.west. Also included is an experimental script
- rx11vnc.pl that attempts to tunnel the vnc traffic through an ssh port
- redirection (and does not assume port 5900 is free.) Have a look at
- them to see what they do and customize as needed:
- * rx11vnc wrapper script
- * rx11vnc.pl wrapper script to tunnel traffic thru ssh
-
- _________________________________________________________________
-
- Building x11vnc:
-
- Make sure you have all the needed build/compile/development packages
- installed (e.g. Linux distributions foolishly don't install them by
- default.) See this build FAQ for more details.
-
- If your OS has libjpeg.so and libz.so in standard locations you can
- build as follows (example given for the 0.9.12 release of x11vnc:
- replace with the version you downloaded):
-(un-tar the x11vnc+libvncserver tarball)
-# gzip -dc x11vnc-0.9.12.tar.gz | tar -xvf -
-
-(cd to the source directory)
-# cd x11vnc-0.9.12
-
-(run configure and then run make)
-# ./configure
-# make
-
-(if all went OK, copy x11vnc to the desired destination, e.g. $HOME/bin)
-# cp ./x11vnc/x11vnc $HOME/bin
-
- Or do make install, it will probably install to /usr/local/bin (run
- ./configure --help for information on customizing your configuration,
- e.g. --prefix=/my/place.) You can now run it via typing "x11vnc",
- "x11vnc -help | more", "x11vnc -forever -shared -display :0", etc.
-
-
- Note: Currently gcc is recommended to build libvncserver. In some
- cases it will build with non-gcc compilers, but the resulting binary
- sometimes fails to run properly. For Solaris pre-built gcc binaries
- are at http://www.sunfreeware.com/. Some Solaris pre-built x11vnc
- binaries are here.
-
- However, one user reports it does work fine when built with Sun Studio
- 10, so YMMV. In fact, here is a little build script to do this on
- Solaris 10:
-#!/bin/sh
-PATH=/usr/ccs/bin:/opt/SUNWspro/bin:$PATH; export PATH
-
-CC='cc' \
-CFLAGS='-xO4' \
-LDFLAGS='-L/usr/sfw/lib -L/usr/X11/lib -R/usr/sfw/lib -R/usr/X11/lib' \
-CPPFLAGS='-I /usr/sfw/include -I/usr/X11/include' \
-./configure
-
-MAKE="make -e"
-AM_CFLAGS=""
-export MAKE AM_CFLAGS
-$MAKE
-
- In general you can use the "make -e" trick if you don't like
- libvncserver's choice of AM_CFLAGS. See the build scripts below for
- more ideas. Scripts similar to the above have been shown to work with
- vendor C compilers on HP-UX (ccom: HP92453-01) and Tru64 (Compaq C
- V6.5-011.)
-
- You can find information on Misc. Build problems here.
-
- _________________________________________________________________
-
- Building on Solaris, FreeBSD, etc: Depending on your version of
- Solaris or other Unix OS the jpeg and/or zlib libraries may be in
- non-standard places (e.g. /usr/local, /usr/sfw, /opt/sfw, etc.)
-
- Note: If configure cannot find these two libraries then TightVNC and
- ZRLE encoding support will be disabled, and you don't want that!!! The
- TightVNC encoding gives very good compression and performance, it even
- makes a noticeable difference over a fast LAN.
-
-
- Shortcuts: On Solaris 10 you can pick up almost everything just by
- insuring that your PATH has /usr/sfw/bin (for gcc) and /usr/ccs/bin
- (for other build tools), e.g.:
- env PATH=/usr/sfw/bin:/usr/ccs/bin:$PATH sh -c './configure; make'
-
- (The only thing this misses is /usr/X11/lib/libXrandr.so.2, which is
- for the little used -xrandr option, see the script below to pick it up
- as well.)
-
-
- libjpeg is included in Solaris 9 and later (/usr/sfw/include and
- /usr/sfw/lib), and zlib in Solaris 8 and later (/usr/include and
- /usr/lib.) So on Solaris 9 you can pick up everything with something
- like this:
- env PATH=/usr/local/bin:/usr/ccs/bin:$PATH sh -c './configure --with-jpeg=/us
-r/sfw; make'
-
- assuming your gcc is in /usr/local/bin and x11vnc 0.7.1 or later.
- These are getting pretty long, see those assignments split up in the
- build script below.
-
-
- If your system does not have these libraries at all you can get the
- source for the libraries to build them: libjpeg is available at
- ftp://ftp.uu.net/graphics/jpeg/ and zlib at http://www.gzip.org/zlib/.
- See also http://www.sunfreeware.com/ for Solaris binary packages of
- these libraries as well as for gcc. Normally they will install into
- /usr/local but you can install them anywhere with the
- --prefix=/path/to/anywhere, etc.
-
-
- Here is a build script that indicates one way to pass the library
- locations information to the libvncserver configuration via the
- CPPFLAGS and LDFLAGS environment variables.
----8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8
-<---
-#!/bin/sh
-
-# Build script for Solaris, etc, with gcc, libjpeg and libz in
-# non-standard locations.
-
-# set to get your gcc, etc:
-#
-PATH=/path/to/gcc/bin:/usr/ccs/bin:/usr/sfw/bin:$PATH
-
-JPEG=/path/to/jpeg # set to maybe "/usr/local", "/usr/sfw", or "/opt/sfw"
-ZLIB=/path/to/zlib # set to maybe "/usr/local", "/usr/sfw", or "/opt/sfw"
-
-# Below we assume headers in $JPEG/include and $ZLIB/include and the
-# shared libraries are in $JPEG/lib and $ZLIB/lib. If your situation
-# is different change the locations in the two lines below.
-#
-CPPFLAGS="-I $JPEG/include -I $ZLIB/include"
-LDFLAGS="-L$JPEG/lib -R $JPEG/lib -L$ZLIB/lib -R $ZLIB/lib"
-
-# These two lines may not be needed on more recent Solaris releases:
-#
-CPPFLAGS="$CPPFLAGS -I /usr/openwin/include"
-LDFLAGS="$LDFLAGS -L/usr/openwin/lib -R /usr/openwin/lib"
-
-# These are for libXrandr.so on Solaris 10:
-#
-CPPFLAGS="$CPPFLAGS -I /usr/X11/include"
-LDFLAGS="$LDFLAGS -L/usr/X11/lib -R /usr/X11/lib"
-
-# Everything needs to built with _REENTRANT for thread safe errno:
-#
-CPPFLAGS="$CPPFLAGS -D_REENTRANT"
-
-export PATH CPPFLAGS LDFLAGS
-
-./configure
-make
-
-ls -l ./x11vnc/x11vnc
-
----8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8
-<---
-
- Then do make install or copy the x11vnc binary to your desired
- destination.
-
- BTW, To run a shell script, just cut-and-paste the above into a file,
- say "myscript", then modify the "/path/to/..." items to correspond to
- your system/environment, and then type: "sh myscript" to run it.
-
- Note that on Solaris make is /usr/ccs/bin/make, so that is why the
- above puts /usr/ccs/bin in PATH. Other important build utilities are
- there too: ld, ar, etc. Also, it is probably a bad idea to have
- /usr/ucb in your PATH while building.
-
- Starting with the 0.7.1 x11vnc release the "configure --with-jpeg=DIR
- --with-zlib=DIR" options are handy if you want to avoid making a
- script.
-
- If you need to link OpenSSL libssl.a on Solaris see this method.
-
- If you need to build on Solaris 2.5.1 or earlier or other older Unix
- OS's, see this workaround FAQ.
-
-
- Building on FreeBSD, OpenBSD, ...: The jpeg libraries seem to be in
- /usr/local or /usr/pkg on these OS's. You won't need the openwin stuff
- in the above script (but you may need /usr/X11R6/....) Also starting
- with the 0.7.1 x11vnc release, this usually works:
- ./configure --with-jpeg=/usr/local
- make
-
-
- Building on HP-UX: For jpeg and zlib you will need to do the same
- sort of thing as described above for Solaris. You set CPPFLAGS and
- LDFLAGS to find them (see below for an example.) You do not need to do
- any of the above /usr/openwin stuff. Also, HP-UX does not seem to
- support -R, so get rid of the -R items in LDFLAGS. Because of this, at
- runtime you may need to set LD_LIBRARY_PATH or SHLIB_PATH to indicate
- the directory paths so the libraries can be found. It is a good idea
- to have static archives, e.g. libz.a and libjpeg.a for the nonstandard
- libraries so that they get bolted into the x11vnc binary (and so won't
- get "lost".)
-
- Here is what we recently did to build x11vnc 0.7.2 on HP-UX 11.11
-./configure --with-jpeg=$HOME/hpux/jpeg --with-zlib=$HOME/hpux/zlib
-make
-
- Where we had static archives (libjpeg.a, libz.a) only and header files
- in the $HOME/hpux/... directories as discussed for the build script.
-
- On HP-UX 11.23 and 11.31 we have had problems compiling with gcc.
- "/usr/include/rpc/auth.h:87: error: field 'syncaddr' has incomplete
- type". As a workaround for x11vnc 0.9.4 and later set your CPPFLAGS to
- include:
- CPPFLAGS="-DIGNORE_GETSPNAM"
- export CPPFLAGS
-
- This disables a very rare usage mode for -unixpw_nis by not trying
- getspnam(3).
-
- Using HP-UX's C compiler on 11.23 and 11.31 we have some severe
- compiler errors that have not been worked around yet. If you need to
- do this, contact me and I will give you a drastic recipe that will
- produce a working binary.
-
-
- Building on AIX: AIX: one user had to add the "X11.adt" package to
- AIX 4.3.3 and 5.2 to get build header files like XShm.h, etc. You may
- also want to make sure that /usr/lpp/X11/include, etc is being picked
- up by the configure and make.
-
- For a recent build on AIX 5.3 we needed to add these CFLAGS to be able
- to build with gcc:
- env CFLAGS='-maix64 -Xlinker -bbigtoc' ./configure ...
-
- we also built our own libjpeg and libz using -maix64.
-
- BTW, one way to run an Xvfb-like virtual X server for testing on AIX
- is something like "/usr/bin/X11/X -force -vfb -ac :1".
-
-
- Building on Mac OS X: There is now native Mac OS X support for
- x11vnc by using the raw framebuffer feature. This mode does not use or
- need X11 at all. To build you may need to disable X11:
-./configure --without-x ...
-make
-
- However, if your system has the Mac OS X build package for X11 apps
- you will not need to supply the "--without-x" option (in this case the
- resulting x11vnc would be able to export both the native Mac OS X
- display and windows displayed in the XDarwin X server.) Be sure to
- include the ./configure option to find libjpeg on your system.
-
-
- OpenSSL: Starting with version 0.8.3 x11vnc can now be built with
- SSL/TLS support. For this to be enabled the libssl.so library needs to
- be available at build time. So you may need to have additional
- CPPFLAGS and LDFLAGS items if your libssl.so is in a non-standard
- place. As of x11vnc 0.9.4 there is also the --with-ssl=DIR configure
- option.
-
- On Solaris using static archives libssl.a and libcrypto.a instead of
- .so shared libraries (e.g. from www.sunfreeware.com), we found we
- needed to also set LDFLAGS as follows to get the configure to work:
-env LDFLAGS='-lsocket -ldl' ./configure --with-ssl=/path/to/openssl ...
-make
-
- _________________________________________________________________
-
- Beta Testing:
-
- I don't have any formal beta-testers for the releases of x11vnc, so
- I'd appreciate any additional testing very much.
-
- Thanks to those who suggested features and helped beta test x11vnc
- 0.9.12 released in Sep 2010!
-
- Please help test and debug the 0.9.13 version for release sometime in
- Winter 2010.
-
- The version 0.9.13 beta tarball is kept here:
- x11vnc-0.9.13-dev.tar.gz
-
- There are also some Linux, Solaris, Mac OS X, and other OS test
- binaries here. Please kick the tires and report bugs, performance
- regressions, undesired behavior, etc. to me.
-
- To aid testing of the 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
- wrapper scripts and a GUI that starts STUNNEL.) It should be pretty
- convenient for automatic SSL and SSH connections. It is described in
- detail at and can be downloaded from the Enhanced TightVNC Viewer
- (SSVNC) page. The SSVNC Unix viewer also supports x11vnc's symmetric
- key encryption ciphers (see the 'UltraVNC DSM Encryption Plugin'
- settings panel.)
-
-
- Here are some features that will appear in the 0.9.13 release:
- * Improved support for non-X11 touchscreen devices (e.g. handheld or
- cell phone) via Linux uinput input injection. Additional tuning
- parameters are added. TSLIB touchscreen calibration is supported.
- Tested on Qtmoko Neo Freerunner. A tool, misc/uinput.pl, is
- provided to diagnose uinput behavior on new devices. The env.
- vars. X11VNC_UINPUT_BUS and X11VNC_UINPUT_VERSION are available if
- leaving them unset does not work.
- * The Linux uinput non-X11 input injection can now be bypassed:
- events can be directly written to the /dev/input/event devices
- specified by the user (direct_abs=..., etc.) A -pipeinput input
- injection helper script, misc/qt_tslib_inject.pl is provided as a
- tweakable non-builtin direct input injection method.
- * The list of new uinput parameters for the above two features is:
- pressure, tslib_cal, touch_always, dragskip, btn_touch;
- direct_rel, direct_abs, direct_btn, direct_key.
- * The MacOSX native server can now use OpenGL for the screen
- capture. In nearly all cases this is faster than the raw
- framebuffer capture method. There are build and run time flags,
- X11VNC_MACOSX_NO_DEPRECATED, etc. to disable use of deprecated
- input injection and screen access interfaces. Cursor shape now
- works for 64bit binaries.
- * The included SSL enabled Java VNC Viewers now handle Mouse Wheel
- events.
- * miscellaneous new features and changes:
- * In -reflect mode, the libvncclient connection can now have the
- pixel format modified via the environment variables
- X11VNC_REFLECT_bitsPerSample, X11VNC_REFLECT_samplesPerPixel, and
- X11VNC_REFLECT_bytesPerPixel
- * In -create mode the following environment variables are added to
- fine tune the behavior: FIND_DISPLAY_NO_LSOF: do not use lsof(1)
- to try to determine the Linux VT, FIND_DISPLAY_NO_VT_FIND: do not
- try to determine the Linux VT at all, X11VNC_CREATE_LC_ALL_C_OK:
- do not bother undoing the setting LC_ALL=C that the create_display
- script sets. The performance of the -create script has been
- improved for large installations (100's of user sessions on one
- machine.)
- * In -unixpw mode, one can now Tab from login: to Password.
- * An environment variable, X11VNC_SB_FACTOR, allows one to scale the
- -sb screenblank sleep time from the default 2 secs.
- * An experimental option -unixsock is available for testing. Note,
- however, that it requires a manual change to
- libvncserver/rfbserver.c for it to work.
- * Documented that -grabkbd is no longer working with some/most
- window managers (it can prevent resizing and menu posting.)
-
-
- Here are some features that appeared in the 0.9.12 release (Sep/2010):
- * One can now specify the maximum number of displays that can be
- created in -create mode via the env. var.
- X11VNC_CREATE_MAX_DISPLAYS
- * The X11VNC_NO_LIMIT_SHM env. var. is added to skip any automatic
- shared memory reduction.
- * The kdm display manager is now detected when trying not to get
- killed by the display manager.
- * A compile time bug is fixed so that configuring using
- --with-system-libvncserver pointing to LibVNCServer 0.9.7 works
- again. A bug from forced use of Xdefs.h is worked around.
-
-
- Here are some features that appeared in the 0.9.11 release (Aug/2010):
- * The source tree is synchronized with the most recent libvncclient
- (this only affects -reflect mode.) Build is fixed for
- incompatibilities when using an external LibVNCServer (e.g.
- ./configure --with-system-libvncserver...) Please help test these
- build and runtime aspects and report back what you find, thanks.
- * The SSL enabled Java VNC Viewer Makefile has been modified so that
- the jar files that are built are compatible back to Java 1.4.
- * In -create/-unixpw mode, the env. var. FD_USERPREFS may be set to
- a filename in the user's home directory that includes default
- username:options values (so the options do not need to be typed
- every time at the login prompt.)
- * In -reflect mode cursor position updates are now handled
- correctly.
-
-
- Here are some features that appeared in the 0.9.10 release (May/2010):
- * The included SSL enabled Java applet viewer now supports Chained
- SSL Certificates. The debugCerts=yes applet parameter aids
- troubleshooting certificate validation. The x11vnc -ssl mode has
- always supported chained SSL certificates (simply put the
- intermediate certificates, in order, after the server certificate
- in the pem file.)
- * A demo CGI script desktop.cgi shows how to create an SSL
- encrypted, multi-user x11vnc web login desktop service. The script
- requires x11vnc version 0.9.10. The user logs into a secure web
- site and gets his/her own virtual desktop (Xvfb.) x11vnc's SSL
- enabled Java Viewer Applet is launched by the web browser for
- secure viewing (and so no software needs to be installed on the
- viewer-side.) One can use the desktop.cgi script for ideas to
- create their own fancier or customized web login desktop service
- (e.g. user-creation, PHP, SQL, specialized desktop application,
- etc.) More info here. There is also an optional 'port redirection'
- mode that allows redirection to other SSL enabled VNC servers
- running inside the firewall.
- * Built-in support for IPv6 (128 bit internet addresses) is now
- provided. See the -6 and -connect options for details.
- Additionally, in case there are still problems with built-in IPv6
- support, a transitional tool is provided in inet6to4 that allows
- x11vnc (or any other IPv4 application) to receive connections over
- IPv6.
- * The Xdummy wrapper script for Xorg's dummy driver is updated and
- no longer requires being run as root. New service options are
- provided to select Xdummy over Xvfb as the virtual X server to be
- created.
- * The "%" unix password verification tricks for the -unixpw option
- are now documented. They have also been extended to run a command
- as the user if one sets the environment variable UNIXPW_CMD. The
- desktop.cgi demo script takes advantage of this new feature.
- * A bug has been fixed that would prevent the Java applet viewer
- from being downloaded successfully in single-port HTTPS/VNC inetd
- mode. The env. var. X11VNC_HTTPS_DOWNLOAD_WAIT_TIME can be used to
- adjust for how many seconds a -inetd or -https httpd download is
- waited for (default 15 seconds.) The applet will now autodetect
- x11vnc and use GET=1 for faster connecting. Many other
- improvements and fixes.
- * The TightVNC security type (TightVNC features enabler) now works
- for RFB version 3.8.
- * The X property X11VNC_TRAP_XRANDR can be set on a desktop to force
- x11vnc to use the -xrandr screen size change trapping code.
- * New remote control query options: pointer_x, pointer_y,
- pointer_same, pointer_root, and pointer_mask. A demo script using
- them misc/panner.pl is provided.
- * The -sslScripts option prints out the SSL certificate management
- scripts.
-
-
- Here are some features that appeared in the 0.9.9 release (Dec/2009):
- * The -unixpw_system_greeter option, when used in combined unixpw
- and XDMCP FINDCREATEDISPLAY mode (for example: -xdmsvc), enables
- the user to press Escape to jump directly to the XDM/GDM/KDM login
- greeter screen. This way the user avoids entering his unix
- password twice at X session creation time. Also, the unixpw login
- panel now has a short help displayed if the user presses 'F1'.
- * x11vnc now tries to be a little bit more aggressive in keeping up
- with VNC client's framebuffer update requests. Some broken VNC
- clients like Eggplant and JollysFastVNC continuously spray these
- requests at VNC servers (regardless of whether they have received
- any updates or not.) Under some circumstances this could lead to
- x11vnc falling behind. The -extra_fbur option allows one to fine
- tune the setting. Additionally, one may also dial down delays:
- e.g. "-defer 5" and "-wait 5" (or to 1 or even 0) or -nonap or
- -allinput to keep up with these VNC clients at the expense of
- increased system load.
- * Heuristics are applied to try to determine if the X display is
- currently in a Display Manager Greeter Login panel (e.g. GDM) If
- so, x11vnc's creation of any windows and use of XFIXES are
- delayed. This is to try to avoid x11vnc being killed after the
- user logs in if the GDM KillInitClients=true is in effect. So one
- does not need to set KillInitClients=false. Note that in recent
- GDM the KillInitClients option has been removed. Also delayed is
- the use of the XFIXES cursor fetching functionality; this avoids
- an Xorg bug that causes Xorg to crash right after the user logs
- in.
- * A new option -findauth runs the FINDDISPLAY script that applies
- heuristics that try to determine the XAUTHORITY file. The use of
- '-auth guess' will use the XAUTHORITY that -findauth reveals. This
- can be handy in with the lastest GDM where the ability to store
- cookies in ~/.Xauthority has been removed. If x11vnc is running as
- root (e.g. inetd) and you add -env FD_XDM=1 to the above -findauth
- or -auth guess command lines, it will find the correct XAUTHORITY
- for the given display (this works for XDM/GDM/KDM if the login
- greeter panel is up or if someone has already logged into an X
- session.)
- * The FINDDISPLAY and FINDCREATEDISPLAY modes (i.e. "-display
- WAIT:cmd=...", -find, -create) now work correctly for the
- user-supplied login program scheme "-unixpw_cmd ...", as long as
- the login program supports running commands specified in the
- environment variable "RFB_UNIXPW_CMD_RUN" as the logged-in user.
- The mode "-unixpw_nis ..." has also been made more consistent.
- * The -stunnel option (like -ssl but uses stunnel as an external
- helper program) now works with the -ssl "SAVE" and "TMP" special
- certificate names. The -sslverify and -sslCRL options now work
- correctly in -stunnel mode. Single port HTTPS connections are also
- supported for this mode.
- * There is an experimental Application Sharing mode that improves
- upon the -id/-sid single window sharing: -appshare (run "x11vnc
- -appshare -help" for more info.) It is still very primitive and
- approximate, but at least it displays multiple top-level windows.
- * The remote control command -R can be used to instruct x11vnc to
- resend its most recent copy of the Clipboard, Primary, or
- Cutbuffer selections: "x11vnc -R resend_clipboard", "x11vnc -R
- resend_primary", and "x11vnc -R resend_cutbuffer".
- * The fonts in the GUI (-gui) can now by set via environment
- variables, e.g. -env X11VNC_FONT_BOLD='Helvetica -16 bold' and
- -env X11VNC_FONT_FIXED='Courier -14'.
- * The XDAMAGE mechanism is now automatically disabled for a period
- of time if a game or screensaver generates too many XDAMAGE
- rectangles per second. This avoids the X11 event queue from
- soaking up too much memory.
- * There is an experimental workaround: "-env X11VNC_WATCH_DX_DY=1"
- that tries to avoid problems with poorly constructed menu themes
- that place the initial position of the mouse cursor inside a menu
- item's active zone. More information can be found here.
-
-
- Here are some features that appeared in the 0.9.8 release (Jul/2009):
- * Stability improvements to -threads mode. Running x11vnc this way
- is more reliable now. Threaded operation sometimes gives better
- interactive response and faster updates: try it out. The threaded
- mode now supports multiple VNC viewers using the same VNC
- encoding. The threaded mode can also yield a performance
- enhancement in the many client case (e.g. class-room broadcast.)
- We have tested with 30 to 50 simultaneous clients. See also
- -reflect.
- For simultaneous clients: the ZRLE encoding is thread safe on all
- platforms, and the Tight and Zlib encodings are currently only
- thread safe on Linux where thread local storage, __thread, is
- used. If your non-Linux system and compiler support __thread one
- can supply -DTLS=__thread to enable it. When there is only one
- connected client, all encodings are safe on all platforms. Note
- that some features (e.g. scroll detection and -ncache) may be
- disabled or run with reduced functionality in -threads mode.
- * Automatically tries to work around an Xorg server and GNOME bug
- involving infinitely repeating keys when turning off key
- repeating. Use -repeat if the automatic workaround fails.
- * Improved reliability of the Single Port SSL VNC and HTTPS java
- viewer applet delivery mechanism.
- * The -clip mode works under -rawfb.
-
-
- Here are some features that appeared in the 0.9.7 release (Mar/2009):
- * Support for polling Linux Virtual Terminals (also called virtual
- consoles) directly instead of using /dev/fb. The option to use is,
- for example, "-rawfb vt2" for Virtual Terminal 2, etc. In this
- case the special file /dev/vcsa2 is used to retrieve vt2's current
- text. Text and colors are shown, but no graphics.
- * Support for less than 8 bits per pixel framebuffers (e.g. 4 or 1
- bpp) in the -rawfb mode.
- * The SSL enabled UltraVNC Java viewer applet now has a [Home] entry
- in the "drives" drop down menu. This menu can be configured with
- the ftpDropDown applet parameter. All of the applet parameters are
- documented in classes/ssl/README.
- * Experimental support for VirtualGL's TurboVNC (an enhanced
- TightVNC for fast LAN high framerate usage.)
- * The CUPS Terminal Services helper mode has been improved.
- * Improvements to the -ncache_cr that allows smooth opaque window
- motions using the 'copyrect' encoding when using -ncache mode.
- * The -rmflag option enables a way to indicate to other processes
- x11vnc has exited.
- * Reverse connections using anonymous Diffie Hellman SSL encryption
- now work.
-
-
- Here are some features that appeared in the 0.9.6 release (Dec/2008):
- * Support for VeNCrypt SSL/TLS encrypted connections. It is enabled
- by default in the -ssl mode. VNC Viewers like vinagre,
- gvncviewer/gtk-vnc, the vencrypt package, SSVNC, and others
- support this encryption mode. It can also be used with the -unixpw
- option to enable Unix username and password authentication
- (VeNCrypt's "*Plain" modes.) A similar but older VNC security type
- "ANONTLS" (used by vino) is supported as well. See the -vencrypt
- and -anontls options for additional control. The difference
- between x11vnc's normal -ssl mode and VeNCrypt is that the former
- wraps the entire VNC connection in SSL (like HTTPS does for HTTP,
- i.e. "vncs://") while VeNCrypt switches on the SSL/TLS at a
- certain point during the VNC handshake. Use -sslonly to disable
- both VeNCrypt and ANONTLS (vino.)
- * The "-ssl ANON" option enables Anonymous Diffie-Hellman (ADH) key
- exchange for x11vnc's normal SSL/TLS operation. Note that
- Anonymous Diffie-Hellman uses encryption for privacy, but provides
- no authentication and so is susceptible to Man-In-The-Middle
- attacks (and so we do not recommend it: we prefer you use "-ssl
- SAVE", etc. and have the VNC viewer verify the cert.) The ANONTLS
- mode (vino) only supports ADH. VeNCrypt mode supports both ADH and
- regular X509 SSL certificates modes. For these ADH is enabled by
- default. See -vencrypt and -anontls for how to disable ADH.
- * For x11vnc's SSL/TLS modes, one can now specify a Certificate
- Revocation List (CRL) with the -sslCRL option. This will only be
- useful for wide deployments: say a company-wide x11vnc SSL access
- deployment using a central Certificate Authority (CA) via
- -sslGenCA and -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 new keys to all users.
- * The default SSL/TLS mode, "-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". Previously "-ssl"
- would create a temporary self-signed cert that was discarded when
- x11vnc exited. The reason for the change is to at least give the
- chance for the VNC Viewer side (e.g. SSVNC) to remember the cert
- to authenticate subsequent connections to the same x11vnc server.
- Use "-ssl TMP" to regain the previous behavior. Use "-ssl
- SAVE_NOPROMPT" to avoid being prompted about using passphrase when
- the certificate is created.
- * The option -http_oneport enables single-port HTTP connections via
- the Java VNC Viewer. So, for example, the web browser URL
- "http://myhost.org:5900" works the same as
- "http://myhost.org:5800", but with the convenience of only
- involving one port instead of two. This works for both unencrypted
- connections and for SSH tunnels (see -httpsredir if the tunnel
- port differs.) Note that HTTPS single-port operation in -ssl SSL
- encrypted mode has been available since x11vnc version 0.8.3.
- * For the -avahi/-zeroconf Service Advertizing mode, if x11vnc was
- not compiled with the avahi-client library, then an external
- helper program, either avahi-publish(1) (on Unix) or dns-sd(1) (on
- Mac OS X), is used instead.
- * The "-rfbport PROMPT" option will prompt the user via the GUI to
- select the VNC port (e.g. 5901) to listen on, and a few other
- basic settings. This enables a handy GUI mode for naive users:
- x11vnc -gui tray=setpass -rfbport PROMPT -logfile $HOME/.x11vnc.log.%VNCDISP
-LAY
- suitable for putting in a launcher or menu, e.g. x11vnc.desktop.
- The -logfile expansion is new too. In the GUI, the tray=setpass
- Properties panel has been improved.
- * The -solid solid background color option now works for the Mac OS
- X console.
- * The -reopen option instructs x11vnc to try to reopen the X display
- if it is prematurely closed by, say, the display manager (e.g.
- GDM.)
-
-
- Here are some features that appeared in the 0.9.5 release (Oct/2008):
- * Symmetric key encryption ciphers. ARC4, AES-128, AES-256,
- blowfish, and 3des are supported. Salt and initialization vector
- seeding is provided. These compliment the more widely used SSL and
- SSH encryption access methods. SSVNC also supports these
- encryption modes.
- * Scaling differently along the X- and Y-directions. E.g. "-scale
- 1280x1024" or "-scale 0.8x0.75" Also, "-geometry WxH" is an
- alias for "-scale WxH"
- * By having SSVNC version 1.0.21 or later available in your $PATH,
- the -chatwindow option allows a UltraVNC Text Chat window to
- appear on the local X11 console/display (this way the remote
- viewer can chat with the person at the physical display; e.g.
- helpdesk mode.) This also works on the Mac OS X console if the
- Xquartz X11 server (enabled by default on leopard) is running for
- the chatwindow.
- * The HTTP Java viewer applet jar, classes/VncViewer.jar, has been
- updated with an improved implementation based on the code used by
- the classes/ssl applets.
-
-
- Here are some features that appeared in the 0.9.4 release (Sep/2008):
- * Improvements to the -find and -create X session finding or
- creating modes: new desktop types and service redirection options.
- Personal cupsd daemon and SSH port redirection helper for use with
- SSVNC's Terminal Services feature.
- * Reverse VNC connections via -connect work in the -find, -create
- and related -display WAIT:... modes.
- * Reverse VNC connections (either normal or SSL) can use a Web Proxy
- or a SOCKS proxy, or a SSH connection, or even a CGI URL to make
- the outgoing connection. See: -proxy. Forward connections can also
- use: -ssh.
- * Reverse VNC connections via the UltraVNC repeater proxy (either
- normal or SSL) are supported. Use either the "-connect
- repeater=ID:NNNN+host:port" or "-connect
- repeater://host:port+ID:NNNN" notation. The SSVNC VNC viewer also
- supports the UltraVNC repeater. Also, a perl repeater implemention
- is here: ultravnc_repeater.pl
- * Support for indexed colormaps (PseudoColor) with depths other than
- 8 (from 1 to 16 now work) for non-standard hardware. Option
- "-advertise_truecolor" to handle some workaround in this mode.
- * Support for the ZYWRLE encoding, this is the RealVNC ZRLE encoding
- extended to do motion video and photo regions more efficiently by
- way of a Wavelet based transformation.
- * The -finddpy and -listdpy utilities help to debug and configure
- the -find, -create, and -display WAIT:... modes.
- * Some automatic detection of screen resizes are handled even if the
- -xrandr option is not supplied.
- * The -autoport options gives more control over the VNC port x11vnc
- chooses.
- * The -ping secs can be used to help keep idle connections alive.
- * Pasting of the selection/clipboard into remote applications (e.g.
- Java) has been improved.
- * Fixed a bug if a client disconnects during the 'speed-estimation'
- phase.
- * To unset Caps_Lock, Num_Lock and raise all keys in the X server
- use -clear_all.
- * Usage with dvorak keyboards has been improved. See also: -xkb.
- * The Java Viewer applet source code is now included in the
- x11vnc-0.9.*.tar.gz tarball. This means you can now build the Java
- viewer applet jar files from source. If you stopped shipping the
- Java viewer applet jar files due to lack of source code, you can
- start again.
-
-
- Here are some features that appeared in the 0.9.3 release (Oct/2007):
- * Viewer-side pixmap caching. A large area of pixels (at least 2-3
- times as big as the framebuffer itself; the bigger the better...
- default is 10X) is placed below the framebuffer to act as a
- buffer/cache area for pixel data. The VNC CopyRect encoding is
- used to move it around, so any viewer can take advantage of it.
- Until we start modifying viewers you will be able to see the cache
- area if you scroll down (this makes it easier to debug!) For
- testing the default is "-ncache 10". The unix Enhanced TightVNC
- Viewer ssvnc has a nice -ycrop option to help hide the pixel cache
- area from view.
-
-
- Here are some features that appeared in the 0.9.2 release (Jun/2007):
- * Building with no OpenSSL libssl available (or with --without-ssl)
- has been fixed.
- * One can configure x11vnc via "./configure
- --with-system-libvncserver" to use a system installed libvncserver
- library instead of the one bundled in the release tarball.
- * If UltraVNC file transfer or chat is detected, then VNC clients
- are "pinged" more often to prevent these side channels from
- becoming serviced too infrequently.
- * In -unixpw mode in the username and password dialog no text will
- be echoed if the first character sent is "Escape". This enables a
- convenience feature in SSVNC to send the username and password
- automatically.
-
-
- Here are some features that appeared in the 0.9.1 release (May/2007):
- * The UltraVNC Java viewer has been enhanced to support SSL (as the
- TightVNC viewer had been previously.) The UltraVNC Java supports
- ultravnc filetransfer, and so can be used as a VNC viewer on Unix
- that supports ultravnc filetransfer. It is in the
- classes/ssl/UltraViewerSSL.jar file (that is pointed to by
- ultra.vnc.) The signed applet SignedUltraViewerSSL.jar version
- (pointed to by ultrasigned.vnc) will be needed to access the local
- drive if you are using it for file transfer via a Web browser.
- Some other bugs in the UltraVNC Java viewer were fixed and a few
- improvements to the UI made.
- * A new Unix username login mode for VNC Viewers authenticated via a
- Client SSL Certificate: "-users sslpeer=". The emailAddress
- subject field is inspected for username@hostname and then acts as
- though "-users +username" has been supplied. This way the Unix
- username is identified by (i.e. simply extracted from) the Client
- SSL Certificate. This could be useful with -find, -create and -svc
- modes if you are also have set up and use VNC Client SSL
- Certificate authentication.
- * For external display finding/creating programs (e.g. WAIT:cmd=...)
- if the VNC Viewer is authenticated via a Client SSL Certificate,
- then that Certificate is available in the environment variable
- RFB_SSL_CLIENT_CERT.
-
-
- Here are some features that appeared in the 0.9 release (Apr/2007):
- * VNC Service advertising via mDNS / ZeroConf / BonJour with the
- Avahi client library. Enable via "-avahi" or "-zeroconf".
- * Implementations of UltraVNC's TextChat, SingleWindow, and
- ServerInput extensions (requires ultravnc viewer or ssvnc Unix
- viewer.) They toggle the selection of a single window (-id), and
- disable (friendly) user input and viewing (monitor blank) at the
- VNC server.
- * Short aliases "-find", "-create", "-svc", and "-xdmsvc" for
- commonly used FINDCREATEDISPLAY usage modes.
- * Reverse VNC connections (viewer listening) now work in SSL (-ssl)
- mode.
- * New options to control the Monitor power state and keyboard/mouse
- grabbing: -forcedpms, -clientdpms, -noserverdpms, and -grabalways.
- * A simple way to emulate inetd(8) to some degree via the "-loopbg"
- option.
- * Monitor the accuracy of XDAMAGE and apply "-noxdamage" if it is
- not working well. OpenGL applications like like beryl and MythTv
- have been shown to make XDAMAGE not work properly.
- * For Java SSL connections involving a router/firewall port
- redirection, an option -httpsredir to spare the user from needing
- to include &PORT=NNN in the browser URL.
-
-
- Here are some features that appeared in the 0.8.4 release (Feb/2007):
- * Native Mac OS X Aqua/Quartz support. (i.e. OSXvnc alternative;
- some activities are faster)
- * A new login mode: "-display WAIT:cmd=FINDCREATEDISPLAY -unixpw
- ..." that will Create a new X session (either virtual or real and
- with or without a display manager, e.g. kdm) for the user if it
- cannot find the user's X session display via the FINDDISPLAY
- method. See the -svc and the -xdmsvc aliases.
- * x11vnc can act as a VNC reflector/repeater using the "-reflect
- host:N" option. Instead of polling an X display, the remote VNC
- Server host:N is connected to and re-exported via VNC. This is
- intended for use in broadcasting a display to many (e.g. > 16;
- classroom or large demo) VNC viewers where bandwidth and other
- resources are conserved by spreading the load over a number of
- repeaters.
- * Wireframe copyrect detection for local user activity (e.g. someone
- sitting at the physical display moving windows) Use
- -nowireframelocal to disable.
- * The "-N" option couples the VNC Display number to the X Display
- number. E.g. if your X DISPLAY is :2 then the VNC display will be
- :2 (i.e. using port 5902.) If that port is taken x11vnc will exit.
- * Option -nodpms to avoid problems with programs like KDE's
- kdesktop_lock that keep restarting the screen saver every few
- seconds.
- * To automatically fix the common mouse motion problem on XINERAMA
- (multi-headed) displays, the -xwarppointer option is enabled by
- default when XINERAMA is active.
-
- If you have a Mac please try out the native Mac OS X support, build
- with "./configure --without-x", or download a binary mentioned above,
- (even if you don't plan on ever using it in this mode!), and let me
- know how it went. Thanks.
-
-
- Here are some features that appeared in the 0.8.3 release (Nov/2006):
- * The -ssl option provides SSL encryption and authentication
- natively via the www.openssl.org library. One can use from a
- simple self-signed certificate server certificate up to full CA
- and client certificate authentication schemes.
- * Similar to -ssl, the -stunnel option starts up a SSL tunnel server
- stunnel (that must be installed separately on the system:
- stunnel.mirt.net ) to allow only encrypted SSL connections from
- the network.
- * The -sslverify option allows for authenticating VNC clients via
- their certificates in either -ssl or -stunnel modes.
- * Certificate creation and management tools are provide in the
- -sslGenCert, -sslGenCA, and related options.
- * An SSL enabled Java applet VNC Viewer applet is provided by x11vnc
- in classes/ssl/VncViewer.jar. In addition to normal HTTP, the
- applet may be loaded into the web browser via HTTPS (HTTP over
- SSL.) (one can use the VNC port, e.g. https://host:5900/, or also
- the separate -https port option.) A wrapper shell script
- ss_vncviewer is also provided that sets up a stunnel client-side
- tunnel on Unix systems. See Enhanced TightVNC Viewer (SSVNC) for
- other SSL/SSH viewer possibilities.
- * The -unixpw option supports Unix username and password
- authentication (a simpler variant is the -unixpw_nis option that
- works in environments where the encrypted passwords are readable,
- e.g. NIS.) The -ssl or -localhost + -stunnel options are enforced
- in this mode to prevent password sniffing. As a convenience, these
- requirements are lifted if a SSH tunnel can be deduced (but
- -localhost still applies.)
- * Coupling -unixpw with "-display WAIT:cmd=FINDDISPLAY" or "-display
- WAIT:cmd=FINDCREATEDISPLAY" provides a way to allow a user to
- login with their UNIX password and have their display connected to
- automatically. See the -svc and the -xdmsvc aliases.
- * Hooks are provided in the -unixpw_cmd and "-passwdfile
- cmd:,custom:..." options to allow you to supply your own
- authentication and password lookup programs.
- * x11vnc can be configured and built to not depend on X11 libraries
- "./configure --without-x" for -rawfb only operation (e.g. embedded
- linux console devices.)
- * The -rotate option enables you to rotate or reflect the screen
- before exporting via VNC. This is intended for use on handhelds
- and other devices where the rotation orientation is not "natural".
- * The "-ultrafilexfer" alias is provided and improved UltraVNC
- filetransfer rates have been achieved.
- * Under the "-connect_or_exit host" option x11vnc will exit
- immediately unless the reverse connection to host succeeds. The
- "-rfbport 0" option disables TCP listening for connections (useful
- for this mode.)
- * The "-rawfb rand" and "-rawfb none" options are useful for testing
- automation scripts, etc., without requiring a full desktop.
- * Reduced spewing of information at startup, use "-verbose" (also
- "-v") to turn it back on for debugging or if you are going to send
- me a problem report.
-
- Here are some Previous Release Notes
- _________________________________________________________________
-
- Some Notes:
-
- Both a client and a server: It is sometimes confusing to people that
- x11vnc is both a client and a server at the same time. It is an X
- client because it connects to the running X server to do the screen
- polls. Think of it as a rather efficient "screenshot" program running
- continuously. It is a server in the sense that it is a VNC server that
- VNC viewers on the network can connect to and view the screen
- framebuffer it manages.
-
- When trying to debug problems, remember to think of both roles. E.g.
- "how is x11vnc connecting to the X server?", "how is the vncviewer
- connecting to x11vnc?", "what permits/restricts the connection?". Both
- links may have reachability, permission, and other issues.
-
- Network performance: Whether you are using Xvnc or x11vnc it is
- always a good idea to have a solid background color instead of a
- pretty background image. Each and every re-exposure of the background
- must be resent over the network: better to have that background be a
- solid color that compresses very well compared to a photo image. (This
- is one place where the X protocol has an advantage over the VNC
- protocol.) I suggest using xsetroot, dtstyle or similar utility to set
- a solid background while using x11vnc. You can turn the pretty
- background image back on when you are using the display directly.
- Update: As of Feb/2005 x11vnc has the -solid [color] option that works
- on recent GNOME, KDE, and CDE and also on classic X (background image
- is on the root window.) Update: As of Oct/2007 x11vnc has the -ncache
- option that does a reasonable job caching the background (and other)
- pixmap data on the viewer side.
-
- I also find the TightVNC encoding gives the best response for my usage
- (Unix <-> Unix over cable modem.) One needs a tightvnc-aware vncviewer
- to take advantage of this encoding.
-
- TCP port issues: Notice the lines
- 18/07/2003 14:36:31 Autoprobing selected port 5900
- PORT=5900
-
- in the output. 5900 is the default VNC listening port (just like 6000
- is X11's default listening port.) Had port 5900 been taken by some
- other application, x11vnc would have next tried 5901. That would mean
- the viewer command above should be changed to vncviewer
- far-away.east:1. You can force the port with the "-rfbport NNNN"
- option where NNNN is the desired port number. If that port is already
- taken, x11vnc will exit immediately. The "-N" option will try to match
- the VNC display number to the X display. (also see the "SunRay
- Gotcha" note below)
-
- Options: x11vnc has (far too) many features that may be activated
- via its command line options. Useful options are, e.g., -scale to do
- server-side scaling, and -rfbauth passwd-file to use VNC password
- protection (the vncpasswd or storepasswd programs, or the x11vnc
- -storepasswd option can be used to create the password file.)
-
- Algorithm: How does x11vnc do it? Rather brute-forcedly: it
- continuously polls the X11 framebuffer for changes using
- XShmGetImage(). When changes are discovered, it instructs libvncserver
- which rectangular regions of the framebuffer have changed, and
- libvncserver compresses the changes and sends them off to any
- connected VNC viewers. A number of applications do similar things,
- such as x0rfbserver, krfb, x0vncserver, vino. x11vnc uses a 32 x 32
- pixel tile model (the desktop is decomposed into roughly 1000 such
- tiles), where changed tiles are found by pseudo-randomly polling 1
- pixel tall horizontal scanlines separated vertically by 32 pixels.
- This is a surprisingly effective algorithm for finding changed
- regions. For keyboard and mouse user input the XTEST extension is used
- to pass the input events to the X server. To detect XBell "beeps" the
- XKEYBOARD extension is used. If available, the XFIXES extension is
- used to retrieve the current mouse cursor shape. Also, if available
- the X DAMAGE extension is used to receive hints from the X server
- where modified regions on the screen are. This greatly reduces the
- system load when not much is changing on the screen and also improves
- how quickly the screen is updated.
-
- Barbershop mirrors effect: What if x11vnc is started up, and
- vncviewer is then started up on the same machine and displayed on the
- same display x11vnc is polling? One might "accidentally" do this when
- first testing out the programs. You get an interesting
- recursive/feedback effect where vncviewer images keep popping up each
- one contained in the previous one and slightly shifted a bit by the
- window manager decorations. There will be an even more interesting
- effect if -scale is used. Also, if the XKEYBOARD is supported and the
- XBell "beeps" once, you get an infinite loop of beeps going off.
- Although all of this is mildly exciting it is not much use: you will
- normally run and display the viewer on a different machine!
- _________________________________________________________________
-
- Sun Ray Notes:
-
- You can run x11vnc on your (connected or disconnected) SunRay session.
- Here are some notes on SunRay usage with x11vnc.
-
- _________________________________________________________________
-
- Limitations:
-
- * Due to the polling nature, some activities (opaque window moves,
- scrolling), can be pretty choppy/ragged and others (exposures of
- large areas) slow. Experiment with interacting a bit differently
- than you normally do to minimize the effects (e.g. do fullpage
- paging rather than line-by-line scrolling, and move windows in a
- single, quick motion.) Recent work has provided the
- -scrollcopyrect and -wireframe speedups using the CopyRect VNC
- encoding and other things, but they only speed up some activities,
- not all.
- * A rate limiting factor for x11vnc performance is that graphics
- hardware is optimized for writing, not reading (x11vnc reads the
- video framebuffer for the screen image data.) The difference can
- be a factor of 10 to 1000, and so it usually takes about 0.5-1 sec
- to read in the whole video hardware framebuffer (e.g. 5MB for
- 1280x1024 at depth 24 with a read rate of 5-10MB/sec.) So whenever
- activity changes most of the screen (e.g. moving or iconifying a
- large window) there is a delay of 0.5-1 sec while x11vnc reads the
- changed regions in.
- A slow framebuffer read rate will often be the performance
- bottleneck on a fast LAN (whereas on slower links the reduced
- network bandwidth becomes the bottleneck.)
- Note: A quick way to get a 2X speedup of this for x11vnc is to
- switch your X server from depth 24 (32bpp) to depth 16 (16bpp.)
- You get a 4X speedup going to 8bpp, but the lack of color cells is
- usually unacceptable.
- To get a sense of the read and write speeds of your video card,
- you can run benchmarks like: "x11perf -getimage500", "x11perf
- -putimage500", "x11perf -shmput500" and for XFree86 displays with
- direct graphics access the "dga" command (press "b" to run the
- benchmark and then after a few seconds press "q" to quit.) Even
- this "dd if=/dev/fb0 of=/dev/null" often gives a good estimate.
- x11vnc also prints out its estimate:
- 28/02/2009 11:11:07 Autoprobing TCP port
- 28/02/2009 11:11:07 Autoprobing selected port 5900
- 28/02/2009 11:11:08 fb read rate: 10 MB/sec
- 28/02/2009 11:11:08 screen setup finished.
- We have seen a few cases where the hardware fb read speed is
- greater than 65 MB/sec: on high end graphics workstations from SGI
- and Sun, and also from a Linux user using nvidia proprietary
- drivers for his nvidia video card. Update 2008: thankfully, these
- sped up drivers are becoming more common on Linux and *BSD systems
- and that makes x11vnc run somewhat more quickly. Sometimes they
- have a read rate of over 400 MB/sec.
- On XFree86/Xorg it is actually possible to increase the
- framebuffer read speed considerably (10-100 times) by using the
- Shadow Framebuffer (a copy of the framebuffer is kept in main
- memory and this can be read much more quickly.) To do this one
- puts the line Option "ShadowFB" "true" in the Device section of
- the /etc/X11/XF86Config or /etc/X11/xorg.conf file. Note that this
- disables 2D acceleration at the physical display and so that might
- be unacceptable if one plays games, etc. on the machine's local
- display. Nevertheless this could be handy in some circumstances,
- e.g. if the slower speed while sitting at the physical display was
- acceptable (this seems to be true for most video cards these
- days.) Unfortunately it does not seem shadowfb can be turned on
- and off dynamically...
- Another amusing thing one can do is use Xvfb as the X server, e.g.
- "xinit $HOME/.xinitrc -- /usr/X11R6/bin/Xvfb :1 -screen 0
- 1024x768x16" x11vnc can poll Xvfb efficiently via main memory.
- It's not exactly clear why one would want to do this instead of
- using vncserver/Xvnc, (perhaps to take advantage of an x11vnc
- feature, such as framebuffer scaling or built-in SSL encryption),
- but we mention it because it may be of use for special purpose
- applications. You may need to use the "-cc 4" option to force Xvfb
- to use a TrueColor visual instead of DirectColor. See also the
- description of the -create option that does all of this
- automatically for you (be sure to install the Xvfb package, e.g.
- apt-get install xvfb.)
- Also, a faster and more accurate way is to use the "dummy"
- Xorg/XFree86 device driver (or our Xdummy wrapper script.) See
- this FAQ for details.
- * Somewhat surprisingly, the X11 mouse (cursor) shape is write-only
- and cannot be queried from the X server. So traditionally in
- x11vnc the cursor shape stays fixed at an arrow. (see the "-cursor
- X" and "-cursor some" options, however, for a partial hack for the
- root window, etc.) However, on Solaris using the SUN_OVL overlay
- extension, x11vnc can show the correct mouse cursor when the
- -overlay option is also supplied. A similar thing is done on IRIX
- as well when -overlay is supplied.
- More generally, as of Dec/2004 x11vnc supports the new XFIXES
- extension (in Xorg and Solaris 10) to query the X server for the
- exact cursor shape, this works pretty well except that cursors
- with transparency (alpha channel) need to approximated to solid
- RGB values (some cursors look worse than others.)
- * Audio from applications is of course not redirected (separate
- redirectors do exist, e.g. esd, see the FAQ on this below.) The
- XBell() "beeps" will work if the X server supports the XKEYBOARD
- extension. (Note that on Solaris XKEYBOARD is disabled by default.
- Passing +kb to Xsun enables it.)
- * The scroll detection algorithm for the -scrollcopyrect option can
- give choppy or bunched up transient output and occasionally
- painting errors.
- * Using -threads can expose some bugs/crashes in libvncserver.
-
- Please feel free to contact me if you have any questions, problems, or
- comments about x11vnc, etc. Please be polite, thorough, and not
- demanding (sadly, the number of people contacting me that are rude and
- demanding is increasing dramatically.)
- Also, some people ask if they can make a donation, see this link for
- that.
-
-=======================================================================
-http://www.karlrunge.com/x11vnc/faq.html:
-
-
- x11vnc Home Donations
- _________________________________________________________________
-
- x11vnc FAQ:
-
-
- [Building and Starting]
-
- Q-1: I can't get x11vnc to start up. It says "XOpenDisplay failed
- (null)" or "Xlib: connection to ":0.0" refused by server Xlib: No
- protocol specified" and then exits. What do I need to do?
-
- Q-2: I can't get x11vnc and/or libvncserver to compile.
-
- Q-3: I just built x11vnc successfully, but when I use it my keystrokes
- and mouse button clicks are ignored (I am able to move the mouse
- though.)
-
- Q-4: Help, I need to run x11vnc on Solaris 2.5.1 (or other old
- Unix/Linux) and it doesn't compile!
-
- Q-5: Where can I get a precompiled x11vnc binary for my Operating
- System?
-
- Q-6: Where can I get a VNC Viewer binary (or source code) for the
- Operating System I will be viewing from?
-
- Q-7: How can I see all of x11vnc's command line options and
- documentation on how to use them?
-
- Q-8: I don't like typing arcane command line options every time I
- start x11vnc. What can I do? Is there a config file? Or a GUI?
-
- Q-9: How can I get the GUI to run in the System Tray, or at least be a
- smaller, simpler icon?
-
- Q-10: How can I get x11vnc to listen on a different port besides the
- default VNC port (5900)?
-
- Q-11: My Firewall/Router doesn't allow VNC Viewers to connect to
- x11vnc.
-
- Q-12: Is it possible for a VNC Viewer and a VNC Server to connect to
- each other even though both are behind Firewalls that block all
- incoming connections?
-
- Q-13: Can I make x11vnc more quiet and also go into the background
- after starting up?
-
- Q-14: Sometimes when a VNC viewer dies abruptly, x11vnc also dies with
- the error message like: "Broken pipe". I'm using the -forever mode and
- I want x11vnc to keep running.
-
- Q-15: The Windows TightVNC 1.3.9 Viewer cannot connect to x11vnc.
-
- Q-16: KDE's krdc VNC viewer cannot connect to x11vnc.
-
- Q-17: When I start x11vnc on an Alpha Tru64 workstation the X server
- crashes!
-
- Q-18: When running x11vnc on an IBM AIX workstation after a few
- minutes the VNC connection freezes.
-
- Q-19: Are there any build-time customizations possible, e.g. change
- defaults, create a smaller binary, etc?
-
- [Win2VNC Related]
-
- Q-20: I have two separate machine displays in front of me, one Windows
- the other X11: can I use x11vnc in combination with Win2VNC in
- dual-screen mode to pass the keystrokes and mouse motions to the X11
- display?
-
- Q-21: I am running Win2VNC on my Windows machine and "x11vnc -nofb" on
- Unix to pass keyboard and mouse to the Unix monitor. Whenever I start
- Win2VNC it quickly disconnects and x11vnc says:
- rfbProcessClientNormalMessage: read: Connection reset by peer
-
- Q-22: Can I run "x11vnc -nofb" on a Mac OS X machine to redirect mouse
- and keyboard input to it from Windows and X11 machines via Win2VNC and
- x2vnc, respectively?
-
- [Color Issues]
-
- Q-23: The X display I run x11vnc on is only 8 bits per pixel (bpp)
- PseudoColor (i.e. only 256 distinct colors.) The x11vnc colors may
- start out OK, but after a while they are incorrect in certain windows.
-
- Q-24: Color problems: Why are the colors for some windows incorrect in
- x11vnc? BTW, my X display has nice overlay/multi-depth visuals of
- different color depths: e.g. there are both depth 8 and 24 visuals
- available at the same time.
-
- Q-25: I am on a high color system (depth >= 24) but I seem to have
- colormap problems. They either flash or everything is very dark.
-
- Q-26: How do I figure out the window id to supply to the -id windowid
- option?
-
- Q-27: Why don't menus or other transient windows come up when I am
- using the -id windowid option to view a single application window?
-
- Q-28: My X display is depth 24 at 24bpp (instead of the normal depth
- 24 at 32bpp.) I'm having lots of color and visual problems with x11vnc
- and/or vncviewer. What's up?
-
- [Xterminals]
-
- Q-29: Can I use x11vnc to view and interact with an Xterminal (e.g.
- NCD) that is not running UNIX and so x11vnc cannot be run on it
- directly?
-
- Q-30: How do I get my X permissions (MIT-MAGIC-COOKIE file) correct
- for a Unix/Linux machine acting as an Xterminal?
-
- [Sun Rays]
-
- Q-31: I'm having trouble using x11vnc with my Sun Ray session.
-
- [Remote Control]
-
- Q-32: How do I stop x11vnc once it is running in the background?
-
- Q-33: Can I change settings in x11vnc without having to restart it?
- Can I remote control it?
-
- [Security and Permissions]
-
- Q-34: How do I create a VNC password for use with x11vnc?
-
- Q-35: Can I make it so -storepasswd doesn't show my password on the
- screen?
-
- Q-36: Can I have two passwords for VNC viewers, one for full access
- and the other for view-only access to the display?
-
- Q-37: Can I have as many full-access and view-only passwords as I
- like?
-
- Q-38: Does x11vnc support Unix usernames and passwords? Can I further
- limit the set of Unix usernames who can connect to the VNC desktop?
-
- Q-39: Can I supply an external program to provide my own custom login
- method (e.g. Dynamic/One-time passwords or non-Unix (LDAP) usernames
- and passwords)?
-
- Q-40: Why does x11vnc exit as soon as the VNC viewer disconnects? And
- why doesn't it allow more than one VNC viewer to connect at the same
- time?
-
- Q-41: Can I limit which machines incoming VNC clients can connect
- from?
-
- Q-42: How do I build x11vnc/libvncserver with libwrap (tcp_wrappers)
- support?
-
- Q-43: Can I have x11vnc only listen on one network interface (e.g.
- internal LAN) rather than having it listen on all network interfaces
- and relying on -allow to filter unwanted connections out?
-
- Q-44: Now that -localhost implies listening only on the loopback
- interface, how I can occasionally allow in a non-localhost via the -R
- allowonce remote control command?
-
- Q-45: Can I fine tune what types of user input are allowed? E.g. have
- some users just be able to move the mouse, but not click or type
- anything?
-
- Q-46: Can I prompt the user at the local X display whether the
- incoming VNC client should be accepted or not? Can I decide to make
- some clients view-only? How about running an arbitrary program to make
- the decisions?
-
- Q-47: I start x11vnc as root because it is launched via inetd(8) or a
- display manager like gdm(1). Can I have x11vnc later switch to a
- different user?
-
- Q-48: I use a screen-lock when I leave my workstation (e.g.
- xscreensaver or xlock.) When I remotely access my workstation desktop
- via x11vnc I can unlock the desktop fine, but I am worried people will
- see my activities on the physical monitor. What can I do to prevent
- this, or at least make it more difficult?
-
- Q-49: Can I have x11vnc automatically lock the screen when I
- disconnect the VNC viewer?
-
- [Encrypted Connections]
-
- Q-50: How can I tunnel my connection to x11vnc via an encrypted SSH
- channel between two Unix machines?
-
- Q-51: How can I tunnel my connection to x11vnc via an encrypted SSH
- channel from Windows using an SSH client like Putty?
-
- Q-52: How can I tunnel my connection to x11vnc via an encrypted SSL
- channel using an external tool like stunnel?
-
- Q-53: Does x11vnc have built-in SSL tunneling?
-
- Q-54: How do I use VNC Viewers with built-in SSL tunneling?
-
- Q-55: How do I use the Java applet VNC Viewer with built-in SSL
- tunneling when going through a Web Proxy?
-
- Q-56: Can Apache web server act as a gateway for users to connect via
- SSL from the Internet with a Web browser to x11vnc running on their
- workstations behind a firewall?
-
- Q-57: Can I create and use my own SSL Certificate Authority (CA) with
- x11vnc?
-
- [Display Managers and Services]
-
- Q-58: How can I run x11vnc as a "service" that is always available?
-
- Q-59: How can I use x11vnc to connect to an X login screen like xdm,
- GNOME gdm, KDE kdm, or CDE dtlogin? (i.e. nobody is logged into an X
- session yet.)
-
- Q-60: Can I run x11vnc out of inetd(8)? How about xinetd(8)?
-
- Q-61: Can I have x11vnc advertise its VNC service and port via mDNS /
- Zeroconf (e.g. Avahi) so VNC viewers on the local network can detect
- it automatically?
-
- Q-62: Can I have x11vnc allow a user to log in with her UNIX username
- and password and then have it find her X session display on that
- machine and then attach to it? How about starting an X session if one
- cannot be found?
-
- Q-63: Can I have x11vnc restart itself after it terminates?
-
- Q-64: How do I make x11vnc work with the Java VNC viewer applet in a
- web browser?
-
- Q-65: Are reverse connections (i.e. the VNC server connecting to the
- VNC viewer) using "vncviewer -listen" and vncconnect(1) supported?
-
- Q-66: Can reverse connections be made to go through a Web or SOCKS
- proxy or SSH?
-
- Q-67: Can x11vnc provide a multi-user desktop web login service as an
- Apache CGI or PHP script?
-
- Q-68: Can I use x11vnc as a replacement for Xvnc? (i.e. not for a real
- display, but for a virtual one I keep around.)
-
- Q-69: How can I use x11vnc on "headless" machines? Why might I want
- to?
-
- [Resource Usage and Performance]
-
- Q-70: I have lots of memory, but why does x11vnc fail with shmget:
- No space left on device or Minor opcode of failed request: 1
- (X_ShmAttach)?
-
- Q-71: How can I make x11vnc use less system resources?
-
- Q-72: How can I make x11vnc use MORE system resources?
-
- Q-73: I use x11vnc over a slow link with high latency (e.g. dialup
- modem or broadband), is there anything I can do to speed things up?
-
- Q-74: Does x11vnc support the X DAMAGE Xserver extension to find
- modified regions of the screen quickly and efficiently?
-
- Q-75: My OpenGL application shows no screen updates unless I supply
- the -noxdamage option to x11vnc.
-
- Q-76: When I drag windows around with the mouse or scroll up and down
- things really bog down (unless I do the drag in a single, quick
- motion.) Is there anything to do to improve things?
-
- Q-77: Why not do something like wireframe animations to avoid the
- windows "lurching" when being moved or resized?
-
- Q-78: Can x11vnc try to apply heuristics to detect when a window is
- scrolling its contents and use the CopyRect encoding for a speedup?
-
- Q-79: Can x11vnc do client-side caching of pixel data? I.e. so when
- that pixel data is needed again it does not have to be retransmitted
- over the network.
-
- Q-80: Does x11vnc support TurboVNC?
-
- [Mouse Cursor Shapes]
-
- Q-81: Why isn't the mouse cursor shape (the little icon shape where
- the mouse pointer is) correct as I move from window to window?
-
- Q-82: When using XFIXES cursorshape mode, some of the cursors look
- really bad with extra black borders around the cursor and other cruft.
- How can I improve their appearance?
-
- Q-83: In XFIXES mode, are there any hacks to handle cursor
- transparency ("alpha channel") exactly?
-
- [Mouse Pointer]
-
- Q-84: Why does the mouse arrow just stay in one corner in my
- vncviewer, whereas my cursor (that does move) is just a dot?
-
- Q-85: Can I take advantage of the TightVNC extension to the VNC
- protocol where Cursor Positions Updates are sent back to all connected
- clients (i.e. passive viewers can see the mouse cursor being moved
- around by another viewer)?
-
- Q-86: Is it possible to swap the mouse buttons (e.g. left-handed
- operation), or arbitrarily remap them? How about mapping button clicks
- to keystrokes, e.g. to partially emulate Mouse wheel scrolling?
-
- [Keyboard Issues]
-
- Q-87: How can I get my AltGr and Shift modifiers to work between
- keyboards for different languages?
-
- Q-88: When I try to type a "<" (i.e. less than) instead I get ">"
- (i.e. greater than)! Strangely, typing ">" works OK!!
-
- Q-89: Extra Character Inserted, E.g.: When I try to type a "<" (i.e.
- less than) instead I get "<," (i.e. an extra comma.)
-
- Q-90: I'm using an "international" keyboard (e.g. German "de", or
- Danish "dk") and the -modtweak mode works well if the VNC viewer is
- run on a Unix/Linux machine with a similar keyboard. But if I run
- the VNC viewer on Unix/Linux with a different keyboard (e.g. "us") or
- Windows with any keyboard, I can't type some keys like: "@", "$",
- "<", ">", etc. How can I fix this?
-
- Q-91: When typing I sometimes get double, triple, or more of my
- keystrokes repeated. I'm sure I only typed them once, what can I do?
-
- Q-92: The x11vnc -norepeat mode is in effect, but I still get repeated
- keystrokes!!
-
- Q-93: After using x11vnc for a while, I find that I cannot type some
- (or any) characters or my mouse clicks and drags no longer have any
- effect, or they lead to strange effects. What happened?
-
- Q-94: The machine where I run x11vnc has an AltGr key, but the local
- machine where I run the VNC viewer does not. Is there a way I can map
- a local unused key to send an AltGr? How about a Compose key as well?
-
- Q-95: I have a Sun machine I run x11vnc on. Its Sun keyboard has just
- one Alt key labelled "Alt" and two Meta keys labelled with little
- diamonds. The machine where I run the VNC viewer only has Alt keys.
- How can I send a Meta keypress? (e.g. emacs needs this)
-
- Q-96: Running x11vnc on HP-UX I cannot type "#" I just get a "3"
- instead.
-
- Q-97: Can I map a keystroke to a mouse button click on the remote
- machine?
-
- Q-98: How can I get Caps_Lock to work between my VNC viewer and
- x11vnc?
-
- [Screen Related Issues and Features]
-
- Q-99: The remote display is larger (in number of pixels) than the
- local display I am running the vncviewer on. I don't like the
- vncviewer scrollbars, what I can do?
-
- Q-100: Does x11vnc support server-side framebuffer scaling? (E.g. to
- make the desktop smaller.)
-
- Q-101: Does x11vnc work with Xinerama? (i.e. multiple monitors joined
- together to form one big, single screen.)
-
- Q-102: Can I use x11vnc on a multi-headed display that is not Xinerama
- (i.e. separate screens :0.0, :0.1, ... for each monitor)?
-
- Q-103: Can x11vnc show only a portion of the display? (E.g. for a
- special purpose application or a very large screen.)
-
- Q-104: Does x11vnc support the XRANDR (X Resize, Rotate and
- Reflection) extension? Whenever I rotate or resize the screen x11vnc
- just seems to crash.
-
- Q-105: Independent of any XRANDR, can I have x11vnc rotate and/or
- reflect the screen that the VNC viewers see? (e.g. for a handheld
- whose screen is rotated 90 degrees.)
-
- Q-106: Why is the view in my VNC viewer completely black? Or why is
- everything flashing around randomly?
-
- Q-107: I use Linux Virtual Terminals (VT's) to implement 'Fast User
- Switching' between users' sessions (e.g. Betty is on Ctrl-Alt-F7,
- Bobby is on Ctrl-Alt-F8, and Sid is on Ctrl-Alt-F1: they use those
- keystrokes to switch between their sessions.) How come the view in a
- VNC viewer connecting to x11vnc is either completely black or
- otherwise all messed up unless the X session x11vnc is attached to is
- in the active VT?
-
- Q-108: I am using x11vnc where my local machine has "popup/hidden
- taskbars" and the remote display where x11vnc runs also has
- "popup/hidden taskbars" and they interfere and fight with each other.
- What can I do?
-
- Q-109: Help! x11vnc and my KDE screensaver keep switching each other
- on and off every few seconds.
-
- Q-110: I am running the compiz 3D window manager (or beryl, MythTv,
- Google Earth, or some other OpenGL app) and I do not get screen
- updates in x11vnc.
-
- Q-111: Can I use x11vnc to view my VMWare session remotely?
-
- [Exporting non-X11 devices via VNC]
-
- Q-112: Can non-X devices (e.g. a raw framebuffer) be viewed (and even
- controlled) via VNC with x11vnc?
-
- Q-113: Can I export the Linux Console (Virtual Terminals) via VNC
- using x11vnc?
-
- Q-114: Can I export via VNC a Webcam or TV tuner framebuffer using
- x11vnc?
-
- Q-115: Can I connect via VNC to a Qt-embedded/Qt-enhanced/Qtopia
- application running on my handheld, cell phone, or PC using the Linux
- console framebuffer (i.e. not X11)?
-
- Q-116: How do I inject touch screen input into an
- Qt-embedded/Qt-enhanced/Qtopia cell phone such as openmoko/qtmoko Neo
- Freerunner?
-
- Q-117: Now that non-X11 devices can be exported via VNC using x11vnc,
- can I build it with no dependencies on X11 header files and libraries?
-
- Q-118: How do I cross compile x11vnc for a different architecture than
- my Linux i386 or amd64 PC?
-
- Q-119: Does x11vnc support Mac OS X Aqua/Quartz displays natively
- (i.e. no X11 involved)?
-
- Q-120: Can x11vnc be used as a VNC reflector/repeater to improve
- performance for the case of a large number of simultaneous VNC viewers
- (e.g. classroom broadcasting or a large demo)?
-
- Q-121: Can x11vnc be used during a Linux, Solaris, etc. system
- Installation so the Installation can be done remotely?
-
- [Misc: Clipboard, File Transfer/Sharing, Printing, Sound, Beeps,
- Thanks, etc.]
-
- Q-122: Does the Clipboard/Selection get transferred between the
- vncviewer and the X display?
-
- Q-123: Can I use x11vnc to record a Shock Wave Flash (or other format)
- video of my desktop, e.g. to record a tutorial or demo?
-
- Q-124: Can I transfer files back and forth with x11vnc?
-
- Q-125: Which UltraVNC extensions are supported?
-
- Q-126: Can x11vnc emulate UltraVNC's Single Click helpdesk mode for
- Unix? I.e. something very simple for a naive user to initiate a
- reverse vnc connection from their Unix desktop to a helpdesk
- operator's VNC Viewer.
-
- Q-127: Can I (temporarily) mount my local (viewer-side) Windows/Samba
- File share on the machine where x11vnc is running?
-
- Q-128: Can I redirect CUPS print jobs from the remote desktop where
- x11vnc is running to a printer on my local (viewer-side) machine?
-
- Q-129: How can I hear the sound (audio) from the remote applications
- on the desktop I am viewing via x11vnc?
-
- Q-130: Why don't I hear the "Beeps" in my X session (e.g. when typing
- tput bel in an xterm)?
-
- Q-131: Does x11vnc work with IPv6?
-
- Q-132: Thanks for your program or for your help! Can I make a
- donation?
- _________________________________________________________________
-
-
- [Building and Starting]
-
- Q-1: I can't get x11vnc to start up. It says "XOpenDisplay failed
- (null)" or "Xlib: connection to ":0.0" refused by server Xlib: No
- protocol specified" and then exits. What do I need to do?
-
- For the former error, you need to specify the X display to connect to
- (it also needs to be on the same machine the x11vnc process is to run
- on.) Set your DISPLAY environment variable (or use the -display
- option) to specify it. Nearly always the correct value will be ":0"
- (in fact, x11vnc will now assume :0 if given no other information.)
-
-
- For the latter error, you need to set up the X11 permissions
- correctly.
-
- To make sure X11 permissions are the problem do this simple test:
- while sitting at the physical X display open a terminal window
- (gnome-terminal, xterm, etc.) You should be able to run x11vnc
- successfully without any need for special steps or command line
- options in that terminal (i.e. just type "x11vnc".) If that works OK
- then you know X11 permissions are the only thing preventing it from
- working when you try to start x11vnc via, say, a remote shell.
-
- How to Solve: See the xauth(1), Xsecurity(7), and xhost(1) man pages
- or this Howto for much info on X11 permissions. For example, you may
- need to set your XAUTHORITY environment variable (or use the -auth
- option) to point to the correct MIT-MAGIC-COOKIE file (e.g.
- /home/joe/.Xauthority or /var/gdm/:0.Xauth or /var/lib/kdm/A:0-crWk72K
- or /tmp/.gdmzndVlR, etc, etc.), or simply be sure you run x11vnc as
- the correct user (i.e. the user who is logged into the X session you
- wish to view.)
-
- Note: The MIT cookie file contains the secret key that allows x11vnc
- to connect to the desired X display.
-
- If, say, sshd has set XAUTHORITY to point to a random file it has
- created for X forwarding that will cause problems. (Under some
- circumstances even su(1) and telnet(1) can set XAUTHORITY. See also
- the gdm parameter NeverPlaceCookiesOnNFS that sets XAUTHORITY to a
- random filename in /tmp for the whole X session.)
-
- Running x11vnc as root is often not enough: you need to know where the
- MIT-MAGIC-COOKIE file for the desired X display is.
-
- Example solution:
- x11vnc -display :0 -auth /var/gdm/:0.Xauth
-
- (this is for the display manager gdm and requires root permission to
- read the gdm cookie file, see this faq for other display manager
- cookie file names.)
-
- Note as of Feb/2007 you can also try the -find option instead of
- "-display ..." and see if that finds your display and Xauthority.
-
- Less safe, but to avoid figuring out where the correct XAUTHORITY file
- is, if the person sitting at the physical X session types "xhost
- +localhost" then one should be able to attach x11vnc to the session
- (from the same machine.) The person could then type "xhost -localhost"
- after x11vnc has connected to go back to the default permissions.
- Also, for some situations the "-users lurk=" option may soon be of use
- (please read the documentation on the -users option.)
-
- To test out your X11 permissions from a remote shell, set DISPLAY and
- possibly XAUTHORITY (see your shell's man page, bash(1), tcsh(1), on
- how to set environment variables) and type xdpyinfo in the same place
- you will be typing (or otherwise running) x11vnc. If information is
- printed out about the X display (screen sizes, supported extensions,
- color visuals info) that means the X11 permissions are set up
- properly: xdpyinfo successfully connected to DISPLAY! You could also
- type xclock and make sure no errors are reported (a clock should
- appear on the X display, press Ctrl-C to stop it.) If these work, then
- typing "x11vnc" in the same environment should also work.
-
- Important: if you cannot get your X11 permissions so that the xdpyinfo
- or xclock tests work, x11vnc also will not work (all of these X
- clients must be allowed to connect to the X server to function
- properly.)
-
- Firewalls: Speaking of permissions, it should go without saying that
- the host-level firewall will need to be configured to allow
- connections in on a port. E.g. 5900 (default VNC port) or 22 (default
- SSH port for tunnelling VNC.) Most systems these days have firewalls
- turned on by default, so you will actively have to do something to
- poke a hole in the firewall at the desired port number. See your
- system administration tool for Firewall settings (Yast, Firestarter,
- etc.)
-
-
- Q-2: I can't get x11vnc and/or libvncserver to compile.
-
- Make sure you have gcc (or other C compiler) and all of the required
- libraries and the corresponding -dev/-devel packages installed. These
- include Xorg/XFree86, libX11, libjpeg, libz, libssl, ... and don't
- forget the devs: libjpeg-dev, libssl-dev ...
-
- The most common build problem that people encounter is that the
- necessary X11 libraries are installed on their system however it does
- not have the corresponding -dev/-devel packages installed. These dev
- packages include C header files and build-time .so symlink. It is a
- shame the current trend in distros is to not install the dev package
- by default when the the library runtime package is installed... (it
- diminishes the power of open source)
-
- As of Nov/2006 here is a list of libraries that x11vnc usually likes
- to use:
-libc.so libX11.so libXtst.so libXext.so
-libXfixes.so libXdamage.so libXinerama.so libXrandr.so
-libz.so libjpeg.so libpthread.so
-libssl.so libcrypto.so libcrypt.so
-
- although x11vnc will be pretty usable with the subset: libc.so,
- libX11.so, libXtst.so, libXext.so, libz.so, and libjpeg.so.
-
- After running the libvncserver configure, carefully examine the output
- and the messages in the config.log file looking for missing
- components. For example, if the configure output looks like:
- checking how to run the C preprocessor... gcc -E
- checking for X... no
- checking for XkbSelectEvents in -lX11... no
- checking for XineramaQueryScreens in -lXinerama... no
- checking for XTestFakeKeyEvent in -lXtst... no
-
- or even worse:
- checking for C compiler default output file name... configure: error:
- C compiler cannot create executables
- See `config.log' for more details.
-
- there is quite a bit wrong with the build environment. Hopefully
- simply adding -dev packages and/or gcc or make will fix it.
-
- For Debian the list seems to be:
- gcc
- make
- libc6-dev
- libjpeg8-dev (formerly libjpeg62-dev)
- libx11-dev
- x11proto-core-dev (formerly x-dev)
- libxext-dev
- libxtst-dev
- libxdamage-dev
- libxfixes-dev
- libxrandr-dev
- libxinerama-dev
- libxss-dev (formerly xlibs-static-dev)
- zlib1g-dev
- libssl-dev
- libavahi-client-dev
- linux-libc-dev (only needed for linux console rawfb support)
-
- Note that depending on your OS version the above names may have been
- changed and/or additional packages may be needed.
-
- For Redhat the list seems to be:
- gcc
- make
- glibc-devel
- libjpeg-devel
- libX11-devel
- xorg-x11-proto-devel
- libXdamage-devel
- libXfixes-devel
- libXrandr-devel
- zlib-devel
- openssl-devel
- avahi-devel
- kernel-headers (only needed for linux console rawfb support)
-
- For other distros or OS's the package names may not be the same but
- will look similar. Also, distros tend to rename packages as well so
- the above list may be out of date. So only use the above lists as
- hints for the package names that are needed.
-
- Have a look at Misc. Build Problems for additional fixes.
-
- Note: there is growing trend in Linux and other distros to slice up
- core X11 software into more and smaller packages. So be prepared for
- more headaches compiling software...
-
-
- Q-3: I just built x11vnc successfully, but when I use it my keystrokes
- and mouse button clicks are ignored (I am able to move the mouse
- though.)
-
- This is most likely due to you not having a working build environment
- for the XTEST client library libXtst.so. The library is probably
- present on your system, but the package installing the build header
- file is missing.
-
- If you were watching carefully while configure was running you would
- have seen:
- checking for XTestFakeKeyEvent in -lXtst... no
-
- The solution is to add the necessary build environment package (and
- the library package if that is missing too.) On Debian the build
- package is libxtst-dev. Other distros/OS's may have it in another
- package.
-
- x11vnc will build without support for this library (e.g. perhaps one
- wants a view-only x11vnc on a stripped down or embedded system...) And
- at runtime it will also continue to run even if the X server it
- connects to does not support XTEST. In both cases it cannot inject
- keystrokes or button clicks since XTEST is needed for that (it can
- still move the mouse pointer using the X API XWarpPointer().)
-
- You will see a warning message something like this at run time:
- 20/03/2005 22:33:09 WARNING: XTEST extension not available (either missing fr
-om
- 20/03/2005 22:33:09 display or client library libXtst missing at build time
-.)
- 20/03/2005 22:33:09 MOST user input (pointer and keyboard) will be DISCARDE
-D.
- 20/03/2005 22:33:09 If display does have XTEST, be sure to build x11vnc wit
-h
- 20/03/2005 22:33:09 a working libXtst build environment (e.g. libxtst-dev,
- 20/03/2005 22:33:09 or other packages.)
- 20/03/2005 22:33:09 No XTEST extension, switching to -xwarppointer mode for
- 20/03/2005 22:33:09 pointer motion input.
-
- Also, as of Nov/2006 there will be a configure build time warning as
- well:
- ...
- checking for XFixesGetCursorImage in -lXfixes... yes
- checking for XDamageQueryExtension in -lXdamage... yes
- configure: WARNING:
- ==========================================================================
- A working build environment for the XTEST extension was not found (libXtst).
- An x11vnc built this way will be only barely usable. You will be able to
- move the mouse but not click or type. There can also be deadlocks if an
- application grabs the X server.
-
- It is recommended that you install the necessary development packages
- for XTEST (perhaps it is named something like libxtst-dev) and run
- configure again.
- ==========================================================================
-
-
- Q-4: Help, I need to run x11vnc on Solaris 2.5.1 (or other old
- Unix/Linux) and it doesn't compile!
-
- We apologize that x11vnc does not build cleanly on older versions of
- Solaris, Linux, etc.: very few users are on these old releases.
-
- We have heard that since Dec/2004 a Solaris 2.6 built x11vnc will run
- on Solaris Solaris 2.5 and 2.5.1 (since a workaround for XConvertCase
- is provided.)
-
- In any event, here is a workaround for Solaris 2.5.1 (and perhaps
- earlier and perhaps non-Solaris):
-
- First use the environment settings (CPPFLAGS, LDFLAGS, etc.) in the
- above Solaris build script to run the configure command. That should
- succeed without failure. Then you have to hand edit the autogenerated
- rfb/rfbconfig.h file in the source tree, and just before the last
- #endif at the bottom of that file insert these workaround lines:
-struct timeval _tmp_usleep_tv;
-#define usleep(x) \
- _tmp_usleep_tv.tv_sec = (x) / 1000000; \
- _tmp_usleep_tv.tv_usec = (x) % 1000000; \
- select(0, NULL, NULL, NULL, &_tmp_usleep_tv);
-int gethostname(char *name, int namelen);
-long random();
-int srandom(unsigned int seed);
-#undef LIBVNCSERVER_HAVE_LIBPTHREAD
-#define SHUT_RDWR 2
-typedef unsigned int in_addr_t;
-#define snprintf(a, n, args...) sprintf((a), ## args)
-
- Then run make with the Solaris build script environment, everything
- should compile without problems, and the resulting x11vnc binary
- should work OK. If some non-x11vnc related programs fail (e.g. test
- programs) and the x11vnc binary is not created try "make -k" to have
- it keep going. Similar sorts of kludges in rfb/rfbconfig.h can be done
- on other older OS (Solaris, Linux, ...) releases.
-
- Here are some notes for similar steps that need to be done to build on
- SunOS 4.x
-
- Please let us know if you had to use the above workaround (and whether
- it worked or not.) If there is enough demand we will try to push clean
- compilations back to earlier Solaris, Linux, etc, releases.
-
-
- Q-5: Where can I get a precompiled x11vnc binary for my Operating
- System?
-
- Hopefully the build steps above and FAQ provide enough info for a
- painless compile for most environments. Please report problems with
- the x11vnc configure, make, etc. on your system (if your system is
- known to compile other GNU packages successfully.)
-
- There are precompiled x11vnc binaries built by other groups that are
- available at the following locations:
- Slackware: (.tgz) http://www.linuxpackages.net/
-
- SuSE: (.rpm) http:/software.opensuse.org/ Gentoo: (info)
- http://gentoo-wiki.com/ and http://gentoo-portage.com/ FreeBSD: (.tbz)
- http://www.freebsd.org/ http://www.freshports.org/net/x11vnc NetBSD:
- (src) http://pkgsrc.se/x11/x11vnc OpenBSD: (.tgz) http://openports.se/
- Arch Linux: (.tgz) http://www.archlinux.org/ Nokia 770 (.deb)
- http://mike.saunby.googlepages.com/x11vncfornokia7702 Sharp Zaurus
- http://www.focv.com/ Debian: (.deb) http://packages.debian.org/x11vnc
- Redhat/Fedora: (.rpm) http://packages.sw.be/x11vnc RPMforge
- http://dag.wieers.com/rpm/packages/x11vnc/ (N.B.: unmaintained after
- 0.9.3) Solaris: (pkg) http://www.sunfreeware.com/
-
- If the above binaries don't work and building x11vnc on your OS fails
- (and all else fails!) you can try one of My Collection of x11vnc
- Binaries for various OS's and x11vnc releases.
-
- As a general note, the x11vnc program is simple enough you don't
- really need to install a package: the binary will in most cases work
- as is and from any location (as long as your system libraries are not
- too old, etc.) So, for Linux distributions that are not one of the
- above, the x11vnc binary from the above packages has a good chance of
- working. You can "install" it by just copying the x11vnc binary to the
- desired directory in your PATH. Tip on extracting files from a Debian
- package: extract the archive via a command like: "ar x
- x11vnc_0.6-2_i386.deb" and then you can find the binary in the
- resulting data.tar.gz tar file. Also, rpm2cpio(1) is useful in
- extracting files from rpm packages.
-
- If you use a standalone binary like this and also want x11vnc to serve
- up the Java VNC Viewer jar file (either SSL enabled or regular one),
- then you will need to extract the classes subdirectory from the source
- tarball and point x11vnc to it via the -httpdir option. E.g.:
- x11vnc -httpdir /path/to/x11vnc-0.9.9/classes/ssl ...
-
-
- Q-6: Where can I get a VNC Viewer binary (or source code) for the
- Operating System I will be viewing from?
-
- To obtain VNC viewers for the viewing side (Windows, Mac OS, or Unix)
- try here:
- * http://www.tightvnc.com/download.html
- * http://www.realvnc.com/download-free.html
- * http://sourceforge.net/projects/cotvnc/
- * http://www.ultravnc.com/
- * Our Enhanced TightVNC Viewer (SSVNC)
-
- [ssvnc.gif]
-
-
- Q-7: How can I see all of x11vnc's command line options and
- documentation on how to use them?
-
- Run: x11vnc -opts to list just the option names or run: x11vnc
- -help for long descriptions about each option. The output is listed
- here as well. Yes, x11vnc does have a lot of options, doesn't it...
-
-
- Q-8: I don't like typing arcane command line options every time I
- start x11vnc. What can I do? Is there a config file? Or a GUI?
-
- You could create a shell script that calls x11vnc with your options:
-#!/bin/sh
-#
-# filename: X11vnc (i.e. not "x11vnc")
-# It resides in a directory in $PATH. "chmod 755 X11vnc" has been run on it.
-#
-x11vnc -wait 50 -localhost -rfbauth $HOME/.vnc/passwd -display :0 $*
-
- a similar thing can be done via aliases in your shell (bash, tcsh,
- csh, etc..)
-
- Or as of Jun/2004 you can use the simple $HOME/.x11vncrc config file
- support. If that file exists, each line is taken as a command line
- option. E.g. the above would be:
-# this is a comment in my ~/.x11vncrc file
-wait 50 # this is a comment to the end of the line.
--localhost # note: the leading "-" is optional.
-rfbauth /home/fred/.vnc/passwd
-display :0
-
- As of Dec/2004 there is now a simple Tcl/Tk GUI based on the
- remote-control functionality ("-R") that was added. The /usr/bin/wish
- program is needed for operation. The gui is not particularly
- user-friendly, it just provides a point and click mode to set all the
- many x11vnc parameters and obtain help on them. It is also very useful
- for testing. See the -gui option for more info. Examples: "x11vnc ...
- -gui" and "x11vnc ... -gui other:0" in the latter case the gui is
- displayed on other:0, not the X display x11vnc is polling. There is
- also a "-gui tray" system tray mode.
-
- [tkx11vnc.gif]
-
- NOTE: You may need to install the "wish" or "tk" or "tk8.4" package
- for the gui mode to work (the package name depends on your OS/distro.)
- The tcl/tk "wish" interpreter is used. In debian (and so ubuntu too)
- one would run "apt-get install tk" or perhaps "apt-get install tk8.4"
-
-
- Q-9: How can I get the GUI to run in the System Tray, or at least be a
- smaller, simpler icon?
-
- As of Jul/2005 the gui can run in a more friendly small icon mode
- "-gui icon" or in the system tray: "-gui tray". It has balloon status,
- a simple menu, and a Properities dialog. The full, complicated, gui is
- only available under "Advanced". Other improvements were added as
- well. Try "Misc -> simple_gui" for a gui with fewer esoteric menu
- items.
-
- If the gui fails to embed itself in the system tray, do a retry via
- "Window View -> icon" followed by "Window View -> tray" with the popup
- menu.
-
- For inexperienced users starting up x11vnc and the GUI while sitting
- at the physical X display (not remotely), using something like "x11vnc
- -display :0 -gui tray=setpass" might be something for them that they
- are accustomed to in a Desktop environment (it prompts for an initial
- password, etc.) This is a basic "Share My Desktop" usage mode.
-
- As of Nov/2008 in x11vnc 0.9.6 there is a desktop menu item
- (x11vnc.desktop) that runs this command:
- x11vnc -gui tray=setpass -rfbport PROMPT -logfile %HOME/.x11vnc.log.%VNCDISP
-LAY
-
- which also prompts for which VNC port to use and a couple other
- parameters.
-
-
- Q-10: How can I get x11vnc to listen on a different port besides the
- default VNC port (5900)?
-
- Use something like, e.g., "x11vnc -rfbport 5901" to force it to use
- port 5901 (this is VNC display :1.) If something else is using that
- port x11vnc will exit immediately. If you do not supply the -rfbport
- option, it will autoprobe starting at 5900 and work its way up to 5999
- looking for a free port to listen on. In that case, watch for the
- PORT=59xx line to see which port it found, then subtract 5900 from it
- for the VNC display number to enter into the VNC Viewer(s).
-
- The "-N" option will try to match the VNC display number to the X
- display (e.g. X11 DISPLAY of :5 (port 6005) will have VNC display :5
- (port 5905).)
-
- Also see the "-autoport n" option to indicated at which value the auto
- probing should start at.
-
-
- Q-11: My Firewall/Router doesn't allow VNC Viewers to connect to
- x11vnc.
-
- See the Firewalls/Routers discussion.
-
-
- Q-12: Is it possible for a VNC Viewer and a VNC Server to connect to
- each other even though both are behind Firewalls that block all
- incoming connections?
-
- This is very difficult or impossible to do unless a third machine,
- reachable by both, is used as a relay. So we assume a third machine is
- somehow being used as a relay.
-
- (Update: It may be possible to do "NAT-2-NAT" without a relay machine
- by using a UDP tunnel such as http://samy.pl/pwnat/. All that is
- required is that both NAT firewalls allow in UDP packets from an IP
- address to which a UDP packet has recently been sent to. If you try it
- out let us know how it went.)
-
- In the following discussion, we will suppose port 5950 is being used
- on the relay machine as the VNC port for the rendezvous.
-
- A way to rendezvous is to have the VNC Server start a reverse
- connection to the relay machine:
- x11vnc -connect third-machine.net:5950 ...
-
- and the VNC viewer forward connects as usual:
- vncviewer third-machine.net:50
-
- Or maybe two ports would be involved, e.g. the viewer goes to display
- :51 (5951.) It depends on the relay software being used.
-
- What software to run on third-machine? A TCP relay of some sort could
- be used... Try a google search on "tcp relay" or "ip relay". However,
- note that this isn't a simple redirection because it hooks up two
- incoming connections. You can look at our UltraVNC repeater
- implementation ultravnc_repeater.pl for ideas and possibly to
- customize.
-
- Also, if you are not the admin of third-machine you'd have to convince
- the owner to allow you to install this software (and he would likely
- need to open his server's firewall to allow the port through.)
-
- It is recommended that SSL is used for encryption (e.g. "-ssl SAVE")
- when going over the internet.
-
- We have a prototype for performing a rendezvous via a Web Server
- acting as the relay machine. Download the vncxfer CGI script and see
- the instructions at the top.
-
- Once that CGI script is set up on the website, both users go to, say,
- http://somesite.com/vncxfer (or maybe a "/cgi-bin" directory or ".cgi"
- suffix must be used.) Previously, both have agreed on the same session
- name (say by phone or email) , e.g. "5cows", and put that into the
- entry form on the vncxfer starting page (hopefully separated by a few
- seconds, so the relay helper can fully start up at the first request.)
-
- The page returned tells them the hostname and port number and possible
- command to use for forward (VNC Viewer) and reverse (VNC Server, i.e.
- x11vnc) connections as described above.
-
- Also since Oct/2007, x11vnc can connect directly (no web browser),
- like this:
- x11vnc ... -connect localhost:0 -proxy 'http://somesite.com/vncxfer?session=
-5cows&'
-
- Unfortunately the prototype requires that the Web server's firewall
- allow in the port (e.g. 5950) used for the rendezvous. Most web
- servers are not configured to do this, so you would need to ask the
- admin to do this for you. Nearly all free webspace sites, e.g.
- www.zendurl.com, will not allow your CGI script to be an open relay
- like this. (If you find one that does allow this, let me know!)
-
- Maybe someday a clever trick will be thought up to relax the listening
- port requirement (e.g. use HTTP/CGI itself for the transfer... it is
- difficult to emulate a full-duplex TCP connection with them.)
-
- See also the Firewalls/Routers discussion and Reverse Connection Proxy
- discussion.
-
-
- SSH method: If both users (i.e. one on Viewer-side and the other on
- x11vnc server side) have SSH access to a common machine on the
- internet (or otherwise mutually reachable), then SSH plumbing can be
- used to solve this problem. The users create SSH tunnels going through
- the SSH login machine.
-
- Instead of assuming port 5900 is free on the SSH machine, we will
- assume both users agreed to use 5933. This will illustrate how to use
- a different port for the redir. It could be any port, what matters is
- that both parties refer to the same one.
-
- Set up the Tunnel from the VNC Server side:
- ssh -t -R 5933:localhost:5900 user@third-machine.net
-
- Set up the Tunnel from the VNC Viewer side:
- ssh -t -L 5900:localhost:5933 user@third-machine.net
-
- Run Server on the VNC Server side:
- x11vnc -rfbport 5900 -localhost ...
-
- Run Viewer on the VNC Viewer side:
- vncviewer -encodings "copyrect tight zrle hextile" localhost:0
-
- (we assume the old-style -encodings option needs to be used. See here
- for details.)
-
- If the SSH machine has been configured (see sshd_config(5)) with the
- option GatewayPorts=yes, then the tunnel set up by the VNC Server will
- be reachable directly by the VNC viewer (as long as the SSH machine's
- firewall does not block the port, 5933 in this example.) So in that
- case the Viewer side does not need to run any ssh command, but rather
- only runs:
- vncviewer third-machine.net:33
-
- In this case we recommend SSL be used for encryption.
-
- The creation of both tunnels can be automated. As of Oct/2007 the -ssh
- x11vnc option is available and so only this command needs to be run on
- the VNC Server side:
- x11vnc -ssh user@third-machine.net:33 ...
-
- (the SSH passphrase may need to be supplied.)
-
- To automate on the VNC Viewer side, the user can use the Enhanced
- TightVNC Viewer (SSVNC) by:
- * Clicking on 'Use SSH'
- * Entering user@third-machine.net:33 into 'VNC Host:Display' entry
- box
- * Clicking on 'Connect'
-
- As above, if the SSH GatewayPorts=yes setting is configured the Viewer
- side doesn't need to create a SSH tunnel. In SSVNC the Viewer user
- could instead select 'Use SSL' and then, e.g., on the Server side
- supply "-ssl SAVE" to x11vnc. Then end-to-end SSL encryption would be
- used (in addition to the SSH encryption on the Server-side leg.)
-
-
- Q-13: Can I make x11vnc more quiet and also go into the background
- after starting up?
-
- Use the -q and -bg options, respectively. (also: -quiet is an alias
- for -q)
-
- Note that under -bg the stderr messages will be lost unless you use
- the "-o logfile" option.
-
-
- Q-14: Sometimes when a VNC viewer dies abruptly, x11vnc also dies with
- the error message like: "Broken pipe". I'm using the -forever mode and
- I want x11vnc to keep running.
-
- As of Jan/2004 the SIGPIPE signal is ignored. So if a viewer client
- terminates abruptly, libvncserver will notice on the next I/O
- operation and will close the connection and continue on.
-
- Up until of Apr/2004 the above fix only works for BSD signal systems
- (Linux, FreeBSD, ...) For SYSV systems there is a workaround in place
- since about Jun/2004.
-
-
- Q-15: The Windows TightVNC 1.3.9 Viewer cannot connect to x11vnc.
-
- This appears to be fixed in x11vnc version 0.9 and later. If you need
- to use an earlier version of x11vnc, try using the "-rfbversion 3.7"
- option. In general sometimes one can get a misbehaving viewer to work
- by supplying rfb versions 3.7 or 3.3.
-
-
- Q-16: KDE's krdc VNC viewer cannot connect to x11vnc.
-
- This has been fixed in x11vnc version 0.8.4. More info here, here, and
- here.
-
-
- Q-17: When I start x11vnc on an Alpha Tru64 workstation the X server
- crashes!
-
- This is a bug in the X server obviously; an X client should never be
- able to crash it.
-
- The problem seems to be with the RECORD X extension and so a
- workaround is to use the "-noxrecord" x11vnc command line option.
-
-
- Q-18: When running x11vnc on an IBM AIX workstation after a few
- minutes the VNC connection freezes.
-
- One user reports when running x11vnc on AIX 5.3 in his CDE session
- after a few minutes or seconds x11vnc will "freeze" (no more updates
- being sent, etc.) The freezing appeared to be worse for versions later
- than 0.9.2.
-
- The problem seems to be with the RECORD X extension on AIX and so a
- workaround is to use the "-noxrecord" x11vnc command line option. The
- user found no freezes occurred when using that option.
-
-
- Q-19: Are there any build-time customizations possible, e.g. change
- defaults, create a smaller binary, etc?
-
- There are some options. They are enabled by adding something like
- -Dxxxx=1 to the CPPFLAGS environment variable before running configure
- (see the build notes for general background.)
-/*
- * Mar/2006
- * Build-time customization via CPPFLAGS.
- *
- * Summary of options to include in CPPFLAGS for custom builds:
- *
- * -DVNCSHARED to have the vnc display shared by default.
- * -DFOREVER to have -forever on by default.
- * -DNOREPEAT=0 to have -repeat on by default.
- * -DADDKEYSYMS=0 to have -noadd_keysyms the default.
- *
- * -DREMOTE_DEFAULT=0 to disable remote-control on by default (-yesremote.)
- * -DREMOTE_CONTROL=0 to disable remote-control mechanism completely.
- * -DEXTERNAL_COMMANDS=0 to disable the running of all external commands.
- * -DFILEXFER=0 disable filexfer.
- *
- * -DHARDWIRE_PASSWD=... hardwired passwords, quoting necessary.
- * -DHARDWIRE_VIEWPASSWD=...
- * -DNOPW=1 make -nopw the default (skip warning)
- * -DUSEPW=1 make -usepw the default
- * -DPASSWD_REQUIRED=1 exit unless a password is supplied.
- * -DPASSWD_UNLESS_NOPW=1 exit unless a password is supplied and no -nopw.
- *
- * -DWIREFRAME=0 to have -nowireframe as the default.
- * -DWIREFRAME_COPYRECT=0 to have -nowirecopyrect as the default.
- * -DWIREFRAME_PARMS=... set default -wirecopyrect parameters.
- * -DSCROLL_COPYRECT=0 to have -noscrollcopyrect as the default.
- * -DSCROLL_COPYRECT_PARMS=... set default -scrollcopyrect parameters.
- * -DSCALING_COPYRECT=0
- * -DXDAMAGE=0 to have -noxdamage as the default.
- * -DSKIPDUPS=0 to have -noskip_dups as the default or vice versa.
- *
- * -DPOINTER_MODE_DEFAULT={0,1,2,3,4} set default -pointer_mode.
- * -DBOLDLY_CLOSE_DISPLAY=0 to not close X DISPLAY under -rawfb.
- * -DSMALL_FOOTPRINT=1 for smaller binary size (no help, no gui, etc)
- * use 2 or 3 for even smaller footprint.
- * -DNOGUI do not include the gui tkx11vnc.
- * -DPOLL_8TO24_DELAY=N
- * -DDEBUG_XEVENTS=1 enable printout for X events.
- *
- * Set these in CPPFLAGS before running configure. E.g.:
- *
- * % env CPPFLAGS="-DFOREVER -DREMOTE_CONTROL=0" ./configure
- * % make
- */
-
- If other things (e.g. "-I ...") are needed in CPPFLAGS add them as
- well.
-
- On some systems is seems you need to set LC_ALL=C for configure to
- work properly...
-
- Be careful the following two variables: HARDWIRE_PASSWD and
- HARDWIRE_VIEWPASSWD. If set (remember to include the double quotes
- around the string), they will be used as default values for the
- -passwd and -viewpasswd options. Of course the strings will exist
- unobscured in the x11vnc binary: it better not be readable by
- unintendeds. Perhaps this is of use in remote access for an embedded
- application, etc...
-
- Let us know if more build-time customizations would be useful.
-
-
- [Win2VNC Related]
-
- Q-20: I have two separate machine displays in front of me, one Windows
- the other X11: can I use x11vnc in combination with Win2VNC in
- dual-screen mode to pass the keystrokes and mouse motions to the X11
- display?
-
- Yes, for best response start up x11vnc with the "-nofb" option
- (disables framebuffer polling, and does other optimizations) on the
- secondary display (X11) machine. Then start up Win2VNC on the primary
- display (Windows) referring it to the secondary display.
-
- This will also work X11 to X11 using x2vnc, however you would probably
- just want to avoid VNC and use x2x for that.
-
- For reference, here are some links to Win2VNC-like programs for
- multiple monitor setups:
- * Original Win2VNC
- * Enhanced Win2VNC (broken?) and sourceforge link
- * x2vnc
- * x2x
- * zvnc (MorphOS)
-
- All of them will work with x11vnc (except x2x where it is not needed.)
-
-
- Q-21: I am running Win2VNC on my Windows machine and "x11vnc -nofb" on
- Unix to pass keyboard and mouse to the Unix monitor. Whenever I start
- Win2VNC it quickly disconnects and x11vnc says:
- rfbProcessClientNormalMessage: read: Connection reset by peer
-
- Is the default visual of the X display you run x11vnc on low color
- (e.g. 8 bit per pixel PseudoColor)? (you can run xdpyinfo to check,
- look in the "screen" section.) There seems to be a bug in Win2VNC in
- that it cannot deal correctly with colormaps (PseudoColor is the most
- common example of a visual with a colormap.)
-
- If so, there are a couple options. 1) Can you set the default visual
- on your display to be depth 24 TrueColor? Sun machines often have 8+24
- overlay/multi-depth visuals, and you can make the default visual depth
- 24 TrueColor (see fbconfig(1) and Xsun(1).) 2) As of Feb/2004 x11vnc
- has the -visual option to allow you to force the framebuffer visual to
- whatever you want (this usually messes up the colors unless you are
- very clever.) In this case, the option provides a convenient
- workaround for the Win2VNC bug:
- x11vnc -nofb -visual TrueColor -display :0 ...
-
- So the visual will be set to 8bpp TrueColor and Win2VNC can handle
- this. Since Win2VNC does not use the framebuffer data there should be
- no problems in doing this.
-
- Q-22: Can I run "x11vnc -nofb" on a Mac OS X machine to redirect mouse
- and keyboard input to it from Windows and X11 machines via Win2VNC and
- x2vnc, respectively?
-
- Yes, as of Nov/2006 you can. There may be a trick or two you'll need
- to do to get the Clipboard exchange between the machines to work.
-
-
-
- [Color Issues]
-
- Q-23: The X display I run x11vnc on is only 8 bits per pixel (bpp)
- PseudoColor (i.e. only 256 distinct colors.) The x11vnc colors may
- start out OK, but after a while they are incorrect in certain windows.
-
- Use the -flashcmap option to have x11vnc watch for changes in the
- colormap, and propagate those changes back to connected clients. This
- can be slow (since the whole screen must be updated over the network
- whenever the colormap changes.) This flashing colormap behavior often
- happens if an application installs its own private colormap when the
- mouse is in its window. "netscape -install" is a well-known historical
- example of this. Consider reconfiguring the system to 16 bpp or depth
- 24 TrueColor if at all possible.
-
- Also note the option -8to24 (Jan/2006) can often remove the need for
- flashing the colormap. Everything is dynamically transformed to depth
- 24 at 32 bpp using the colormaps. There may be painting errors however
- (see the following FAQ for tips on reducing and correcting them.)
-
- In some rare cases (SCO unixware) the -notruecolor option has
- corrected colors on 8bpp displays. The red, green, and blue masks were
- non-zero in 8bpp PseudoColor on an obscure setup, and this option
- corrected the problems.
-
-
- Q-24: Color problems: Why are the colors for some windows incorrect in
- x11vnc? BTW, my X display has nice overlay/multi-depth visuals of
- different color depths: e.g. there are both depth 8 and 24 visuals
- available at the same time.
-
- You may want to review the previous question regarding 8 bpp
- PseudoColor.
-
- On some hardware (Sun/SPARC and SGI), the -overlay option discussed a
- couple paragraphs down may solve this for you (you may want to skip to
- it directly.) On other hardware the less robust -8to24 option may help
- (also discussed below.)
-
- Run xdpyinfo(1) to see what the default visual is and what the depths
- of the other visuals are. Does the default visual have a depth of 8
- but there are other visuals of depth 24? If it does, can you possibly
- re-configure your X server to make a depth 24 visual the default? If
- you can do it, this will save you a lot of grief WRT colors and x11vnc
- (and for general usage too!) Here is how I do this on an old
- Sparcstation 20 running Solaris 9 with SX graphics
- xinit -- -dev /dev/fb defclass TrueColor defdepth 24
-
- and it works nicely (note: to log into console from the dtlogin
- window, select "Options -> Command Line Login", then login and enter
- the above command.) See the -dev section of the Xsun(1) manpage for a
- description of the above arguments. If you have root permission, a
- more permanent and convenient thing to do is to record the arguments
- in a line like:
- :0 Local local_uid@console root /usr/openwin/bin/Xsun -dev /dev/fb defclass
-TrueColor defdepth 24
-
- in /etc/dt/config/Xservers (copy /usr/dt/config/Xservers.) Also look
- at the fbconfig(1) and related manpages (e.g. ffbconfig, m64config,
- pgxconfig, SUNWjfb_config, etc ...) for hardware framebuffer settings
- that may achieve the same effect.
-
- In general for non-Sun machines, look at the "-cc class" and related
- options in your X server manpage (perhaps Xserver(1)), it may allow
- modifying the default visual (e.g. "-cc 4", see <X11/X.h> for the
- visual class numbers.) On XFree86 some video card drivers (e.g. Matrox
- mga) have settings like Option "Overlay" "24,8" to support multi-depth
- overlays. For these, use the "-cc 4" X server command line option to
- get a depth 24 default visual.
-
-
- The -overlay mode: Another option is if the system with overlay
- visuals is a Sun system running Solaris or SGI running IRIX you can
- use the -overlay x11vnc option (Aug/2004) to have x11vnc use the
- Solaris XReadScreen(3X11) function to poll the "true view" of the
- whole screen at depth 24 TrueColor. XReadDisplay(3X11) is used on
- IRIX. This is useful for Legacy applications (older versions of
- Cadence CAD apps are mentioned by x11vnc users) that require the
- default depth be 8bpp, or the app will use a 8bpp visual even if depth
- 24 visuals are available, and so the default depth workaround
- described in the previous paragraph is not sufficient for these apps.
-
- It seems that Xorg is working toward supporting XReadDisplay(3X11) as
- part of the RENDER extension work. When it does support it and
- provides a library API x11vnc will be modified to take advantage of
- the feature to support -overlay on Linux, *BSD, etc. Until then see
- the -8to24 mode below.
-
- Misc. notes on -overlay mode: An amusing by-product of -overlay mode
- is that the mouse cursor shape is correct! (i.e. XFIXES is not
- needed.) The -overlay mode may be somewhat slower than normal mode due
- to the extra framebuffer manipulations that must be performed. Also,
- on Solaris there is a bug in that for some popup menus, the windows
- they overlap will have painting errors (flashing colors) while the
- popup is up (a workaround is to disable SaveUnders by passing -su to
- Xsun, e.g. in your /etc/dt/config/Xservers file.)
-
-
- The -8to24 mode: The -8to24 x11vnc option (Jan/2006) is a kludge to
- try to dynamically rewrite the pixel values so that the 8bpp part of
- the screen is mapped onto depth 24 TrueColor. This is less robust than
- the -overlay mode because it is done by x11vnc outside of the X
- server. So only use it on OS's that do not support -overlay. The
- -8to24 mode will work if the default visual is depth 24 or depth 8. It
- scans for any windows within 3 levels of the root window that are 8bpp
- (i.e. legacy application), or in general ones that are not using the
- default visual. For the windows it finds it uses XGetSubImage() to
- retrieve the pixels values and uses the correct indexed colormap to
- create a depth 24 TrueColor view of the whole screen. This depth 24,
- 32bpp view is exported via VNC.
-
- Even on pure 8bpp displays it can be used as an alternative to
- -flashcmap to avoid color flashing completely.
-
- This scheme is approximate and can often lead to painting errors. You
- can manually correct most painting errors by pressing 3 Alt_L's in a
- row, or by using something like: -fixscreen V=3.0 to automatically
- refresh the screen every 3 seconds. Also -fixscreen 8=3.0 has been
- added to just refresh the non-default visual parts of the screen.
-
- In general the scheme uses many resources and may give rise to
- sluggish behavior. If multiple windows are using different 8bpp
- indexed colormaps all but one window may need to be iconified for the
- colors to be correct. There are a number of tunable parameters to try
- to adjust performance and painting accuracy. The option -8to24
- nogetimage can give a nice speedup if the default depth 24 X server
- supports hiding the 8bpp bits in bits 25-32 of the framebuffer data.
- On very slow machines -8to24 poll=0.2,cachewin=5.0 gives an useful
- speedup. See the -8to24 help description for information on tunable
- parameters, etc.
-
-
- Colors still not working correctly? Run xwininfo on the application
- with the incorrect colors to verify that the depth of its visual is
- different from the default visual depth (gotten from xdpyinfo.) One
- possible workaround in this case is to use the -id option to point
- x11vnc at the application window itself. If the application is
- complicated (lots of toplevel windows and popup menus) this may not be
- acceptable, and may even crash x11vnc (but not the application.) See
- also -appshare.
-
- It is theoretically possible to solve this problem in general (see
- xwd(1) for example), but it does not seem trivial or sufficiently fast
- for x11vnc to be able to do so in real time. The -8to24 method does
- this approximately and is somewhat usable. Fortunately the -overlay
- option works for Solaris machines with overlay visuals where most of
- this problem occurs.
-
-
- Q-25: I am on a high color system (depth >= 24) but I seem to have
- colormap problems. They either flash or everything is very dark.
-
- This can happen if the default Visual (use xdpyinfo to list them) is
- DirectColor instead of TrueColor. These are both usually used in high
- color modes, but whereas TrueColor uses static ramps for the Red,
- Green, and Blue components, DirectColor has arbitrary colormaps for
- the Red, Green, and Blue Components. Currently x11vnc cannot decode
- these colormaps and treats them just like TrueColor.
-
- The only workaround so far is to restart the X server with the "-cc 4"
- option to force TrueColor as the default visual (DirectColor is "-cc
- 5"; see /usr/include/X11/X.h.) The only place we have seen this is
- with the virtual framebuffer server Xvfb on Xorg 7.2. So in that case
- you probably should restart it with something like this: "Xvfb :1 -cc
- 4 -screen 0 1280x1024x24". It should be possible for x11vnc to handle
- DirectColor, but this hasn't been implemented due to its rare usage.
-
- You may also see this problem on an X display with a TrueColor default
- visual where an application chooses a DirectColor visual for its
- window(s). It seems the application also needs to install its own
- colormap for the visual for the colors to be messed up in x11vnc. One
- can make xwud do this for example.
-
-
- Q-26: How do I figure out the window id to supply to the -id windowid
- option?
-
- Run the xwininfo program in a terminal. It will ask you to click on
- the desired application window. After clicking, it will print out much
- information, including the window id (e.g. 0x6000010.) Also, the
- visual and depth of the window printed out is often useful in
- debugging x11vnc color problems.
-
- Also, as of Dec/2004 you can use "-id pick" to have x11vnc run
- xwininfo(1) for you and after you click the window it extracts the
- windowid. Besides "pick" there is also "id:root" to allow you to go
- back to root window when doing remote-control.
-
-
- Q-27: Why don't menus or other transient windows come up when I am
- using the -id windowid option to view a single application window?
-
- This is related to the behavior of the XGetImage(3X11) and
- XShmGetImage() interfaces regarding backingstore, saveunders, etc. The
- way the image is retrieved depends on some aspects of how the X server
- maintains the display image data and whether other windows are
- clipping or obscuring it. See the XGetImage(3X11) man page for more
- details. If you disable BackingStore and SaveUnders in the X server
- you should be able to see these transient windows.
-
- If things are not working and you still want to do the single window
- polling, try the -sid windowid option ("shifted" windowid.)
-
- Update: as of Nov/2009 in the 0.9.9 x11vnc development tarball, there
- is an experimental Application Sharing mode that improves upon the
- -id/-sid single window sharing: -appshare (run "x11vnc -appshare
- -help" for more info.) It is still very primitive and approximate, but
- at least it displays multiple top-level windows.
-
-
- Q-28: My X display is depth 24 at 24bpp (instead of the normal depth
- 24 at 32bpp.) I'm having lots of color and visual problems with x11vnc
- and/or vncviewer. What's up?
-
- First off, depth 24 at 24bpp (bpp=bits-per-pixel) is fairly uncommon
- and can cause problems in general. It also can be slower than depth 24
- at 32bpp. You might want to switch to 32bpp (for XFree86 see the
- "-fbbpp 32", DefaultFbBpp, FbBpp and related options.) Perhaps you
- have 24bpp because the video memory of the machine is low and the
- screen wouldn't fit in video RAM at 32bpp. For this case depth 16 at
- 16bpp might be an acceptable option.
-
- In any event x11vnc should handle depth 24 at 24bpp (although
- performance may be slower, and you may need to use the ZRLE encoding
- instead of Tight.) There are some caveats involving the viewer
- however:
-
- The RealVNC Unix viewer cannot handle 24bpp from the server, it will
- say: "main: setPF: not 8, 16 or 32 bpp?" and exit. I have not checked
- the RealVNC Windows viewer.
-
- So you need to use the TightVNC Unix viewer. However there are some
- problems with that too. It seems libvncserver does not do 24bpp
- correctly with the Tight encoding. The colors and screen ultimately
- get messed up. So you have to use a different encoding with the
- TightVNC vncviewer, try "zlib", "hextile", or one of the other
- encodings (e.g. vncviewer -encodings "zlib hextile" ....) I have not
- checked the TightVNC or UltraVNC Windows viewers.
-
- It appears the older RealVNC Unix viewers (e.g. 3.3.3 and 3.3.7) can
- handle 24bpp from the server, so you may want to use those. They
- evidently request 32 bpp and libvncserver obliges.
-
- Update: as of Apr/2006 you can use the -24to32 option to have x11vnc
- dynamically transform the 24bpp pixel data to 32bpp. This extra
- transformation could slow things down further however.
-
- Now coming the opposite direction if you are running the vncviewer on
- the 24bpp display, TightVNC will fail with "Can't cope with 24
- bits-per-pixel. Sorry." and RealVNC will fail with "main: Error:
- couldn't find suitable pixmap format" so evidently you cannot use
- 24bpp for the vncviewers to work on that X display.
-
- Note, however, that the Unix viewer in the Enhanced TightVNC Viewer
- (SSVNC) project can handle 24bpp X displays. It does this by
- requesting a 16bpp pixel format (or 8bpp if the -bgr233 option has
- been supplied) from the VNC server, and translates that to 24bpp
- locally.
- [Xterminals]
-
- Q-29: Can I use x11vnc to view and interact with an Xterminal (e.g.
- NCD) that is not running UNIX and so x11vnc cannot be run on it
- directly?
-
- You can, but it will likely be very wasteful of network bandwidth
- since you will be polling the X display over the network as opposed to
- over the local hardware. To do this, run x11vnc on a UNIX machine as
- close as possible network-wise (e.g. same switch) to the Xterminal
- machine. Use the -display option to point the display to that of the
- Xterminal (you'll of course need basic X11 permission to do that) and
- finally supply the -noshm option (this enables the polling over the
- network.)
-
- If the Xterminal's X display is open to the network for connections,
- you might use something like "-display xterm123:0". If you are trying
- to do this via an SSH tunnel (assuming you can actually ssh into the
- Xterminal) it will be a little tricky (either use the ssh "-R" option
- or consider ssh-ing in the other direction.) In all cases the X11
- permissions need to allow the connection.
-
- The response will likely be sluggish (maybe only one "frame" per
- second.) This mode is not recommended except for "quick checks" of
- hard to get to X servers. Use something like "-wait 150" to cut down
- on the polling rate. You may also need -flipbyteorder if the colors
- get messed up due to endian byte order differences.
-
- Q-30: How do I get my X permissions (MIT-MAGIC-COOKIE file) correct
- for a Unix/Linux machine acting as an Xterminal?
-
- If the X display machine is a traditional Xterminal (where the X
- server process runs on the Xterminal box, but all of the X client
- applications (firefox, etc) run on a central server (aka "terminal
- server")), you will need to log into the Xterminal machine (i.e. get a
- shell running there) and then start the x11vnc program. If the
- Xterminal Linux/Unix machine is stripped down (e.g. no users besides
- root) that may be difficult.
-
- The next problem is the login Display Manager (e.g. gdm, kdm), and
- hence the MIT-MAGIC-COOKIE auth files, are on the central server and
- not on the Xterminal box where the X server and x11vnc processes are.
-
- So unless X permissions are completely turned off (e.g. "xhost +"), to
- run the x11vnc process on the Xterminal box the MIT-MAGIC-COOKIE auth
- file data (XAUTHORITY or $HOME/.Xauthority) must be accessible by or
- copied to the Xterminal. If $HOME/.Xauthority is exported via NFS
- (this is insecure of course, but has been going on for decades), then
- x11vnc can simply pick it up via NFS (you may need to use the -auth
- option to point to the correct file.) Other options include copying
- the auth file using scp, or something like:
- central-server> xauth nextract - xterm123:0 | ssh xterm123 xauth nmerge -
-
- and then, say, ssh from central-server to xterm123 to start x11vnc.
- Here "xterm123" refers to the computer acting as the Xterminal and
- "central-server" is the terminal server. You can use "xauth -f
- /path/to/cookie-file list" to examine the contents of the cookie(s) in
- a file "/path/to/cookie-file". See the xauth(1) manpage for more
- details.
-
- If the display name in the cookie file needs to be changed between the
- two hosts, see this note on the "xauth add ..." command.
-
- A less secure option is to run something like "xhost +127.0.0.1" while
- sitting at the Xterminal box to allow cookie-free local access for
- x11vnc. You can run "xhost -127.0.0.1" after x11vnc connects if you
- want to go back to the original permissions.
-
- If the Xterminal is really stripped down and doesn't have any user
- accounts, NFS, etc. you'll need to contact your system administrator
- to set something up. It can be done!!! Some Xterminal projects have
- actually enabled "run locally" facilities for the running of an
- occasional app more efficiently locally on the Xterminal box (e.g.
- realplayer.)
-
- Not recommended, but as a last resort, you could have x11vnc poll the
- Xterminal Display over the network. For this you would run a "x11vnc
- -noshm ..." process on the central-server (and hope the network admin
- doesn't get angry...)
-
- Note: use of Display Manager (gdm, kdm, ...) auth cookie files (i.e.
- from /var/..., /tmp/..., or elsewhere) may require modification via
- xauth(1) to correctly include the display x11vnc refers to (e.g.
- "xauth -f cookie-file add :0 . 45be51ae2ce9dfbacd882ab3ef8e96b1",
- where the "45be51..." cookie value was found from an "xauth -f
- /path/to/original/cookie-file list") or other reasons. See xauth(1)
- manpage for full details on how to transfer an MIT-MAGIC-COOKIE
- between machines and displays.
-
- VNCviewer performance on Xterminals: This isn't related to x11vnc on
- Xterminals, but we mention it here anyway because of the similar
- issues. If you are on an Xterminal and want to use vncviewer to
- connect to a VNC server somewhere, then performance would be best if
- you ran the viewer on the Xterminal box. Otherwise, (i.e. running the
- viewer process on the central-server) all of the vncviewer screen
- drawing is done more inefficiently over the network. Something to
- consider, especially on a busy network. (BTW, this has all of the
- above permission, etc, problems: both vncviewer and x11vnc are X
- client apps desired to be run on the Xterminal box.)
-
- [Sun Rays]
-
- Q-31: I'm having trouble using x11vnc with my Sun Ray session.
-
- The Sun Ray technology is a bit like "VNC done in hardware" (the Sun
- Ray terminal device, DTU, playing the role of the vncviewer.)
- Completely independent of that, the SunRay user's session is still an
- X server that speaks the X11 protocol and so x11vnc simply talks to
- the X server part to export the SunRay desktop to any place in the
- world (i.e. not only to a Sun Ray terminal device), creating a sort of
- "Soft Ray". Please see this discussion of Sun Ray issues for solutions
- to problems.
-
- Also see the Sun Ray Remote Control Toolkit that uses x11vnc.
-
- [Remote Control]
-
- Q-32: How do I stop x11vnc once it is running in the background?
-
- As of Dec/2004 there is a remote control feature. It can change a huge
- number of parameters on the fly: see the -remote and -query options.
- To shut down the running x11vnc server just type "x11vnc -R stop". To
- disconnect all clients do "x11vnc -R disconnect:all", etc.
-
- If the -forever option has not been supplied, x11vnc will
- automatically exit after the first client disconnects. In general if
- you cannot use the remote control, then you will have to kill the
- x11vnc process This can be done via: "kill NNNNN" (where NNNNN is the
- x11vnc process id number found from ps(1)), or "pkill x11vnc", or
- "killall x11vnc" (Linux only.)
-
- If you have not put x11vnc in the background via the -bg option or
- shell & operator, then simply press Ctrl-C in the shell where x11vnc
- is running to stop it.
-
- Potential Gotcha: If somehow your Keypress of Ctrl-C went through
- x11vnc to the Xserver that then delivered it to x11vnc it is possible
- one or both of the Ctrl or C keys will be left stuck in the pressed
- down state in the Xserver. Tapping the stuck key (either via a new
- x11vnc or at the physical console) will release it from the stuck
- state. If the keyboard seems to be acting strangely it is often fixed
- by tapping Ctrl, Shift, and Alt. Alternatively, the -clear_mods option
- and -clear_keys option can be used to release pressed keys at startup
- and exit. The option -clear_all will also try to unset Caps_Lock,
- Num_Lock, etc.
-
-
- Q-33: Can I change settings in x11vnc without having to restart it?
- Can I remote control it?
-
- Look at the -remote (an alias is -R) and -query (an alias is -Q)
- options added in Dec/2004. They allow nearly everything to be changed
- dynamically and settings to be queried. Examples: "x11vnc -R shared",
- "x11vnc -R forever", "x11vnc -R scale:3/4", "x11vnc -Q modtweak",
- "x11vnc -R stop", "x11vnc -R disconnect:all", etc..
-
- These commands do not start a x11vnc server, but rather communicate
- with one that is already running. The X display (X11VNC_REMOTE
- property) is used as the communication channel, so the X permissions
- and DISPLAY must be set up correctly for communication to be possible.
-
- There is also a simple Tcl/Tk gui based on this remote control
- mechanism. See the -gui option for more info. You will need to have
- Tcl/Tk (i.e. /usr/bin/wish) installed for it to work. It can also run
- in the system tray: "-gui tray" or as a standalone small icon window:
- "-gui icon". Use "-gui tray=setpass" for a naive user "Share My
- Desktop" mode.
-
- [Security and Permissions]
-
- Q-34: How do I create a VNC password for use with x11vnc?
-
- You may already have one in $HOME/.vnc/passwd if you have used, say,
- the vncserver program from the regular RealVNC or TightVNC packages
- (i.e. launching the Xvnc server.) Otherwise, you could use the
- vncpasswd(1) program from those packages.
-
- As of Jun/2004 x11vnc supports the -storepasswd "pass" "file" option,
- which is the same functionality of storepasswd. Be sure to quote the
- "pass" if it contains shell meta characters, spaces, etc. Example:
- x11vnc -storepasswd 'sword*fish' $HOME/myvncpasswd
-
- You then use the password via the x11vnc option: "-rfbauth
- $HOME/myvncpasswd"
-
- As of Jan/2006 if you do not supply any arguments:
- x11vnc -storepasswd
-
- you will be prompted for a password to save to ~/.vnc/passwd (your
- keystrokes when entering the password will not be echoed to the
- screen.) If you supply one argument, e.g. "x11vnc -storepasswd
- ~/.mypass", the password you are prompted for will be stored in that
- file.
-
- x11vnc also has the -passwdfile and -passwd/-viewpasswd plain text
- (i.e. not obscured like the -rfbauth VNC passwords) password options.
-
- You can use the -usepw option to automatically use any password file
- you have in ~/.vnc/passwd or ~/.vnc/passwdfile (the latter is used
- with the -passwdfile option.)
-
- x11vnc -usepw -display :0 ...
-
- If neither file exists you are prompted to store a password in
- ~/.vnc/passwd. If a password file cannot be found or created x11vnc
- exits immediately. An admin may want to set it up this way for users
- who do not know better.
-
-
- Q-35: Can I make it so -storepasswd doesn't show my password on the
- screen?
-
- You can use the vncpasswd program from RealVNC or TightVNC mentioned
- above. As of Jan/2006 the -storepasswd option without any arguments
- will not echo your password as you type it and save the file to
- ~/.vnc/passwd:
- # x11vnc -storepasswd
- Enter VNC password:
- Verify password:
- Write password to /home/myname/.vnc/passwd? [y]/n
- Password written to: /home/myname/.vnc/passwd
-
- You can also give it an alternate filename, e.g. "x11vnc -storepasswd
- ~/.mypass"
-
-
- Q-36: Can I have two passwords for VNC viewers, one for full access
- and the other for view-only access to the display?
-
- Yes, as of May/2004 there is the -viewpasswd option to supply the
- view-only password. Note the full-access password option -passwd must
- be supplied at the same time. E.g.: -passwd sword -viewpasswd fish.
-
- To avoid specifying the passwords on the command line (where they
- could be observed via the ps(1) command by any user) you can use the
- -passwdfile option to specify a file containing plain text passwords.
- Presumably this file is readable only by you, and ideally it is
- located on the machine x11vnc is run on (to avoid being snooped on
- over the network.) The first line of this file is the full-access
- password. If there is a second line in the file and it is non-blank,
- it is taken as the view-only password. (use "__EMPTY__" to supply an
- empty one.)
-
- View-only passwords currently do not work for the -rfbauth password
- option (standard VNC password storing mechanism.) FWIW, note that
- although the output (usually placed in $HOME/.vnc/passwd) by the
- vncpasswd or storepasswd programs (or from x11vnc -storepasswd) looks
- encrypted they are really just obscured to avoid "casual" password
- stealing. It takes almost no skill to figure out how to extract the
- plain text passwords from $HOME/.vnc/passwd since it is very
- straight-forward to work out what to do from the VNC source code.
-
-
- Q-37: Can I have as many full-access and view-only passwords as I
- like?
-
- Yes, as of Jan/2006 in the libvncserver CVS the -passwdfile option has
- been extended to handle as many passwords as you like. You put the
- view-only passwords after a line __BEGIN_VIEWONLY__.
-
- You can also easily annotate and comment out passwords in the file.
- You can have x11vnc re-read the file dynamically when it is modified.
-
-
- Q-38: Does x11vnc support Unix usernames and passwords? Can I further
- limit the set of Unix usernames who can connect to the VNC desktop?
- Update: as of Feb/2006 x11vnc has the -unixpw option that does this
- outside of the VNC protocol and libvncserver. The standard su(1)
- program is used to validate the user's password. A familiar "login:"
- and "Password:" dialog is presented to the user on a black screen
- inside the vncviewer. The connection is dropped if the user fails to
- supply the correct password in 3 tries or does not send one before a
- 25 second timeout. Existing clients are view-only during this period.
- A list of allowed Unix usernames may also be supplied along with
- per-user settings.
-
- There is also the -unixpw_nis option for non-shadow-password
- (typically NIS environments, hence the name) systems where the
- traditional getpwnam() and crypt() functions are used instead of
- su(1). The encrypted user passwords must be accessible to the user
- running x11vnc in -unixpw_nis mode, otherwise the logins will always
- fail even when the correct password is supplied. See ypcat(1) and
- shadow(5).
-
- Two settings are enforced in the -unixpw and -unixpw_nis modes to
- provide extra security: the 1) -localhost and 2) -stunnel or -ssl
- options. Without these one might send the Unix username and password
- data in clear text over the network which is a very bad idea. They can
- be relaxed if you want to provide encryption other than stunnel or
- -ssl (the constraint is automatically relaxed if SSH_CONNECTION is set
- and indicates you have ssh-ed in, however the -localhost requirement
- is still enforced.)
-
- The two -unixpw modes have been tested on Linux, Solaris, Mac OS X,
- HP-UX, AIX, Tru64, FreeBSD, OpenBSD, and NetBSD. Additional testing is
- appreciated. For the last 4 it appears that su(1) will not prompt for
- a password if su-ing to oneself. Since x11vnc requires a password
- prompt from su, x11vnc forces those logins to fail even when the
- correct password is supplied. On *BSD it appears this can be corrected
- by removing the pam_self.so entry in /etc/pam.d/su.
-
-
- Previous older discussion (prior to the -unixpw option):
-
- Until the VNC protocol and libvncserver support this things will be
- approximate at best.
-
- One approximate method involves starting x11vnc with the -localhost
- option. This basically requires the viewer user to log into the
- workstation where x11vnc is running via their Unix username and
- password, and then somehow set up a port redirection of his vncviewer
- connection to make it appear to emanate from the local machine. As
- discussed above, ssh is useful for this: "ssh -L 5900:localhost:5900
- user@hostname ..." See the ssh wrapper scripts mentioned elsewhere on
- this page. stunnel does this as well.
-
- Of course a malicious user could allow other users to get in through
- his channel, but that is a problem with every method. Another thing to
- watch out for is a malicious user on the viewer side (where ssh is
- running) trying to sneak in through the ssh port redirection there.
-
- Regarding limiting the set of Unix usernames who can connect, the
- traditional way would be to further require a VNC password to supplied
- (-rfbauth, -passwd, etc) and only tell the people allowed in what the
- VNC password is. A scheme that avoids a second password involves using
- the -accept option that runs a program to examine the connection
- information to determine which user is connecting from the local
- machine. That may be difficult to do, but, for example, the program
- could use the ident service on the local machine (normally ident
- should not be trusted over the network, but on the local machine it
- should be accurate: otherwise root has been compromised and so there
- are more serious problems! Unfortunately recent Linux distros seem to
- provide a random string (MD5 hash?) instead of the username.) An
- example script passed in via -accept scriptname that deduces the Unix
- username and limits who can be accepted might look something like
- this:
-#!/bin/sh
-if [ "$RFB_CLIENT_IP" != "127.0.0.1" -o "$RFB_SERVER_IP" != "127.0.0.1" ]; then
- exit 1 # something fishy... reject it.
-fi
-user=`echo "$RFB_CLIENT_PORT, $RFB_SERVER_PORT" | nc -w 1 $RFB_CLIENT_IP 113 \
- | grep 'USERID.*UNIX' | head -n 1 | sed -e 's/[\r ]//g' | awk -F: '{pri
-nt $4}'`
-
-for okuser in fred barney wilma betty
-do
- if [ "X$user" = "X$okuser" ]; then
- exit 0 # accept it
- fi
-done
-exit 1 # reject it
-
- For this to work with ssh port redirection, the ssh option
- UsePrivilegeSeparation must be enabled otherwise the userid will
- always be "root".
-
- Here is a similar example based on Linux netstat(1) output:
-#!/bin/sh
-#
-# accept_local_netstat: x11vnc -accept command to accept a local
-# vncviewer connection from acceptable users. Linux netstat -nte is used.
-
-PATH=/bin:/usr/bin:$PATH; export PATH; # set to get system utils
-
-allowed="`id -u fred`"; # add more user numbers if desired.
-
-# check required settings
-ok=1
-if [ "X$allowed" = "X" ]; then
- ok=0; # something wrong with allowed list
-fi
-if [ "X$RFB_CLIENT_IP" != "X127.0.0.1" -o "X$RFB_SERVER_IP" != "X127.0.0.1" ];
-then
- ok=0; # connection not over localhost
-fi
-if [ "$RFB_CLIENT_PORT" -le 0 -o "$RFB_SERVER_PORT" -le 0 ]; then
- ok=0; # something wrong with tcp port numbers
-fi
-if [ "$ok" = 0 ]; then
- echo "$0: invalid setting:" 1>&2
- env | grep ^RFB | sort 1>&2
- exit 1
-fi
-
-# Linux netstat -nte:
-# Proto Recv-Q Send-Q Local Address Foreign Address State
- User Inode
-# 0 0 0 RFB_CLIENT RFB_SERVER ESTABLISHED
- nnnn ....
-#
-user=`netstat -nte | grep ESTABLISHED \
- | grep " $RFB_CLIENT_IP:$RFB_CLIENT_PORT *$RFB_SERVER_IP:$RFB_SERVER_P
-ORT "`
-
-echo "netstat match: $user" 1>&2
-user=`echo "$user" | head -n 1 | sed -e 's/^.*ESTABLISHED/ /' | awk '{print $1}
-'`
-
-ok=0
-for u in $allowed
-do
- if [ "X$user" = "X$u" ]; then
- ok=1
- break
- fi
-done
-
-if [ "X$ok" = "X1" ]; then
- echo "$0: user accepted: '$user'" 1>&2
- exit 0
-else
- echo "$0: user '$user' invalid:" 1>&2
- echo "$0: allowed: $allowed" 1>&2
- env | grep ^RFB | sort 1>&2
- exit 1
-fi
-
-
- Q-39: Can I supply an external program to provide my own custom login
- method (e.g. Dynamic/One-time passwords or non-Unix (LDAP) usernames
- and passwords)?
- Yes, there are several possibilities. For background see the FAQ on
- the -accept where an external program may be run to decide if a VNC
- client should be allowed to try to connect and log in. If the program
- (or local user prompted by a popup) answers "yes", then -accept
- proceeds to the normal VNC and x11vnc authentication methods,
- otherwise the connection is dropped.
-
- To provide more direct coupling to the VNC client's username and/or
- supplied password the following options were added in Sep/2006:
- * -unixpw_cmd command
- * -passwdfile cmd:command
- * -passwdfile custom:command
-
- In each case "command" is an external command run by x11vnc. You
- supply it. For example, it may couple to your LDAP system or other
- servers you set up.
-
- For -unixpw_cmd the normal -unixpw Login: and Password: prompts are
- supplied to the VNC viewer and the strings the client returns are then
- piped into "command" as the first two lines of its standard input. If
- the command returns success, i.e. exit(0), the VNC client is accepted,
- otherwise it is rejected.
-
- For "-passwdfile cmd:command" the command is run and it returns a
- password list (like a password file, see the -passwdfile read:filename
- mode.) Perhaps a dynamic, one-time password is retrieved from a server
- this way.
-
- For "-passwdfile custom:command" one gets complete control over the
- VNC challenge-response dialog with the VNC client. x11vnc sends out a
- string of random bytes (16 by the VNC spec) and the client returns the
- same number of bytes in a way the server can verify only the
- authorized user could have created. The VNC protocol specifies DES
- encryption with a password. If you are willing to modify the VNC
- viewers, you can have it be anything you want, perhaps a less
- crackable MD5 hash scheme or one-time pad. Your program will read from
- its standard input the size of the challenge-response followed by a
- newline, then the challenge bytes followed by the response bytes. If
- your command then returns success, i.e. exit(0), the VNC client is
- accepted, otherwise it is rejected.
-
- In all cases the "RFB_*" environment variables are set as under
- -accept. These variables can provide useful information for the
- externally supplied program to use.
-
-
- Q-40: Why does x11vnc exit as soon as the VNC viewer disconnects? And
- why doesn't it allow more than one VNC viewer to connect at the same
- time?
-
- These defaults are simple safety measures to avoid someone unknowingly
- leaving his X11 desktop exposed (to the internet, say) for long
- periods of time. Use the -forever option (aka -many) to have x11vnc
- wait for more connections after the first client disconnects. Use the
- -shared option to have x11vnc allow multiple clients to connect
- simultaneously.
-
- Recommended additional safety measures include using ssh (see above),
- stunnel, -ssl, or a VPN to authenticate and encrypt the viewer
- connections or to at least use the -rfbauth passwd-file option to use
- VNC password protection (or -passwdfile) It is up to YOU to apply
- these security measures, they will not be done for you automatically.
-
-
- Q-41: Can I limit which machines incoming VNC clients can connect
- from?
-
- Yes, look at the -allow and -localhost options to limit connections by
- hostname or IP address. E.g.
- x11vnc -allow 192.168.0.1,192.168.0.2
-
- for those two hosts or
- x11vnc -allow 192.168.0.
-
- for a subnet. For individual hosts you can use the hostname instead of
- the IP number, e.g.: "-allow snoopy", and "-allow darkstar,wombat".
- Note that -localhost achieves the same thing as "-allow 127.0.0.1"
-
- For more control, build libvncserver with libwrap support
- (tcp_wrappers) and then use /etc/hosts.allow See hosts_access(5) for
- complete details.
-
-
- Q-42: How do I build x11vnc/libvncserver with libwrap (tcp_wrappers)
- support?
-
- Here is one way to pass this information to the configure script:
- env CPPFLAGS=-DUSE_LIBWRAP LDFLAGS=-lwrap ./configure
-
- then run make as usual. This requires libwrap and its development
- package (tcpd.h) to be installed on the build machine. If additional
- CPPFLAGS or LDFLAGS options are needed supply them as well using
- quotes.
-
- The resulting x11vnc then uses libwrap/tcp_wrappers for connections.
- The service name you will use in /etc/hosts.allow and /etc/hosts.deny
- is "vnc", e.g.:
- vnc: 192.168.100.3 .example.com
-
- Note that if you run x11vnc out of inetd you do not need to build
- x11vnc with libwrap support because the /usr/sbin/tcpd reference in
- /etc/inetd.conf handles the tcp_wrappers stuff.
-
-
- Q-43: Can I have x11vnc only listen on one network interface (e.g.
- internal LAN) rather than having it listen on all network interfaces
- and relying on -allow to filter unwanted connections out?
-
- As of Mar/2005 there is the "-listen ipaddr" option that enables this.
- For ipaddr either supply the desired network interface's IP address
- (or use a hostname that resolves to it) or use the string "localhost".
- For additional filtering simultaneously use the "-allow host1,..."
- option to allow only specific hosts in.
-
- This option is useful if you want to insure that no one can even begin
- a dialog with x11vnc from untrusted network interfaces (e.g. ppp0.)
- The option -localhost now implies "-listen localhost" since that is
- what most people expect it to do.
-
-
- Q-44: Now that -localhost implies listening only on the loopback
- interface, how I can occasionally allow in a non-localhost via the -R
- allowonce remote control command?
-
- To do this specify "-allow localhost". Unlike -localhost this will
- leave x11vnc listening on all interfaces (but of course only allowing
- in local connections, e.g. ssh redirs.) Then you can later run "x11vnc
- -R allowonce:somehost" or use to gui to permit a one-shot connection
- from a remote host.
-
-
- Q-45: Can I fine tune what types of user input are allowed? E.g. have
- some users just be able to move the mouse, but not click or type
- anything?
-
- As of Feb/2005, the -input option allows you to do this. "K", "M",
- "B", "C", and "F" stand for Keystroke, Mouse-motion, Button-clicks,
- Clipboard, and File-Transfer, respectively. The setting: "-input M"
- makes attached viewers only able to move the mouse. "-input KMBC,M"
- lets normal clients do everything and enables view-only clients to
- move the mouse.
-
- These settings can also be applied on a per-viewer basis via the
- remote control mechanism or the GUI. E.g. x11vnc -R input:hostname:M
-
-
- Q-46: Can I prompt the user at the local X display whether the
- incoming VNC client should be accepted or not? Can I decide to make
- some clients view-only? How about running an arbitrary program to make
- the decisions?
-
- Yes, look at the "-accept command" option, it allows you to specify an
- external command that is run for each new client. (use quotes around
- the command if it contains spaces, etc.) If the external command
- returns 0 (success) the client is accepted, otherwise with any other
- return code the client is rejected. See below how to also accept
- clients view-only.
-
- The external command will have the RFB_CLIENT_IP environment variable
- set to the client's numerical IP address, RFB_CLIENT_PORT its port
- number. Similarly for RFB_SERVER_IP and RFB_SERVER_PORT to allow
- identification of the tcp virtual circuit. DISPLAY will be set to that
- of the X11 display being polled. Also, RFB_X11VNC_PID is set to the
- x11vnc process id (e.g. in case you decided to kill it), RFB_CLIENT_ID
- will be an id number, and RFB_CLIENT_COUNT the number of other clients
- currently connected. RFB_MODE will be "accept".
-
- Built-in Popup Window: As a special case, "-accept popup" will
- instruct x11vnc to create its own simple popup window. To accept the
- client press "y" or click mouse on the "Yes" button. To reject the
- client press "n" or click mouse on the "No" button. To accept the
- client View-only, press "v" or click mouse on the "View" button. If
- the -viewonly option has been supplied, the "View" action will not be
- present: the whole display is view only in that case.
-
- The popup window times out after 120 seconds, to change this behavior
- use "-accept popup:N" where N is the number of seconds (use 0 for no
- timeout.) More tricks: "-accept popupmouse" will only take mouse click
- responses, while "-accept popupkey" will only take keystroke responses
- (popup takes both.) After any of the 3 popup keywords you can supply a
- position of the window: +N+M, (the default is to center the window)
- e.g. -accept popupmouse+10+10.
-
- Also as a special case "-accept xmessage" will run the xmessage(1)
- program to prompt the user whether the client should be accepted or
- not. This requires that you have xmessage installed and available via
- PATH. In case it is not already on your system, the xmessage program
- is available at ftp://ftp.x.org/
- (End of Built-in Popup Window:)
-
- To include view-only decisions for the external commands, prefix the
- command something like this: "yes:0,no:*,view:3 mycommand ..." This
- associates the three actions: yes(accept), no(reject), and
- view(accept-view-only), with the numerical return (i.e. exit()) codes.
- Use "*" instead of a number to set the default action (e.g. in case
- the external command returns an unexpected return code.)
-
- Here is an example -accept script called accept_or_lock. It uses
- xmessage and xlock (replace with your screen lock command, maybe it is
- "xscreensaver-command -lock", or kdesktop_lock, or "dtaction
- LockDisplay".) It will prompt the user at the X display whether to
- accept, reject, or accept view-only the client, but if the prompt
- times out after 60 seconds the screen is locked and the VNC client is
- accepted. This allows the remote access when no one is at the display.
-#!/bin/sh
-#
-# accept_or_lock: prompt user at X display whether to accept an incoming
-# VNC connection. If timeout expires, screen is locked
-# and the VNC viewer is accepted (allows remote access
-# when no one is sitting at the display.)
-#
-# usage: x11vnc ... -forever -accept 'yes:0,no:*,view:4 accept_or_lock'
-#
-xmessage -buttons yes:2,no:3,view-only:4 -center \
- -timeout 60 "x11vnc: accept connection from $RFB_CLIENT_IP?"
-rc=$?
-if [ $rc = 0 ]; then
- xlock & # or "xlock -mode blank" for no animations.
- sleep 5
- exit 0
-elif [ $rc = 2 ]; then
- exit 0
-elif [ $rc = 4 ]; then
- exit 4
-fi
-exit 1
-
- Stefan Radman has written a nice dtksh script dtVncPopup for use in
- CDE environments to do the same sort of thing. Information on how to
- use it is found at the top of the file. He encourages you to provide
- feedback to him to help improve the script.
-
- Note that in all cases x11vnc will block while the external command or
- popup is being run, so attached clients will not receive screen
- updates, etc during this period.
-
- To run a command when a client disconnects, use the "-gone command"
- option. This is for the user's convenience only: the return code of
- the command is not interpreted by x11vnc. The same environment
- variables are set as in "-accept command" (except that RFB_MODE will
- be "gone".)
-
- As of Jan/2006 the "-afteraccept command" option will run the command
- only after the VNC client has been accepted and authenticated. Like
- -gone the return code is not interpreted. RFB_MODE will be
- "afteraccept".)
-
-
- Q-47: I start x11vnc as root because it is launched via inetd(8) or a
- display manager like gdm(1). Can I have x11vnc later switch to a
- different user?
-
- As of Feb/2005 x11vnc has the -users option that allows things like
- this. Please read the documentation on it (also in the x11vnc -help
- output) carefully for features and caveats. It's use can often
- decrease security unless care is taken.
-
- BTW, a nice use of it is "-users +nobody" that switches to the Unix
- user nobody right after connections to the X display are established.
-
- In any event, while running x11vnc as root, remember it comes with no
- warranty ;-).
-
-
- Q-48: I use a screen-lock when I leave my workstation (e.g.
- xscreensaver or xlock.) When I remotely access my workstation desktop
- via x11vnc I can unlock the desktop fine, but I am worried people will
- see my activities on the physical monitor. What can I do to prevent
- this, or at least make it more difficult?
-
- Probably most work environments would respect your privacy if you
- powered off the monitor. Also remember if people have physical access
- to your workstation they basically can do anything they want with it
- (e.g. install a backdoor for later use, etc.)
-
- In any event, as of Jun/2004 there is an experimental utility to make
- it more difficult for nosey people to see your x11vnc activities. The
- source for it is blockdpy.c The idea behind it is simple (but
- obviously not bulletproof): when a VNC client attaches to x11vnc put
- the display monitor in the DPMS "off" state, if the DPMS state ever
- changes immediately start up the screen-lock program. The x11vnc user
- will notice something is happening and think about what to do next
- (while the screen is in a locked state.)
-
- This works (or at least has a chance of working) because if the
- intruder moves the mouse or presses a key on the keyboard, the monitor
- wakes up out of the DPMS off state, and this induces the screen lock
- program to activate as soon as possible. Of course there are cracks in
- this, the eavesdropper could detach your monitor and insert a non-DPMS
- one, and there are race conditions. As mentioned above this is not
- bulletproof. A really robust solution would likely require X server
- and perhaps even video hardware support.
-
- The blockdpy utility is launched by the -accept option and told to
- exit via the -gone option (the vnc client user should obviously
- re-lock the screen before disconnecting!) Instructions can be found in
- the source code for the utility at the above link. Roughly it is
- something like this:
- x11vnc ... -accept "blockdpy -bg -f $HOME/.bdpy" -gone "touch $HOME/.bdpy"
-
- but please read the top of the file.
-
- Update: As of Feb/2007 there is some builtin support for this:
- -forcedpms and -clientdpms however, they are probably less robust than
- the above blockdpy.c scheme, since if the person floods the physical
- machine with mouse or pointer input he can usually see flashes of the
- screen before the monitor is powered off again. See also the -grabkbd,
- -grabptr, and -grabalways options.
-
-
- Q-49: Can I have x11vnc automatically lock the screen when I
- disconnect the VNC viewer?
-
- Yes, a user mentions he uses the -gone option under CDE to run a
- screen lock program:
- x11vnc -display :0 -forever -gone 'dtaction LockDisplay'
-
- Other possibilities are:
- x11vnc -display :0 -forever -gone 'xscreensaver-command -lock'
- x11vnc -display :0 -forever -gone 'kdesktop_lock'
- x11vnc -display :0 -forever -gone 'xlock &'
- x11vnc -display :0 -forever -gone 'xlock -mode blank &'
-
- Here is a scheme using the -afteraccept option (in version 0.8) to
- unlock the screen after the first valid VNC login and to lock the
- screen after the last valid VNC login disconnects:
- x11vnc -display :0 -forever -shared -afteraccept ./myxlocker -gone ./myxlocke
-r
-
- Where the script ./myxlocker is:
-#!/bin/sh
-
-#/usr/bin/env | grep RFB_ | sort # for viewing RFB_* settings.
-
-if [ "X$RFB_MODE" = "Xafteraccept" ]; then
- if [ "X$RFB_STATE" = "XNORMAL" ]; then # require valid login
- if [ "X$RFB_CLIENT_COUNT" = "X1" ]; then
- killall xlock # Linux only.
- fi
- fi
-elif [ "X$RFB_MODE" = "Xgone" ]; then
- if [ "X$RFB_STATE" = "XNORMAL" ]; then # require valid login
- if [ "X$RFB_CLIENT_COUNT" = "X0" ]; then
- xlock -mode blank &
- fi
- fi
-fi
-
- Note the xlock option "-mode blank" to avoid animations.
-
- There is a problem if you have x11vnc running this way in -forever
- mode and you hit Ctrl-C to stop it. The xlock (or other program) will
- get killed too. To work around this make a little script called
- setpgrp that looks like:
-#!/usr/bin/perl
-setpgrp(0, 0);
-exec @ARGV;
-
- then use -gone "setpgrp xlock &", etc.
- [Encrypted Connections]
-
- Q-50: How can I tunnel my connection to x11vnc via an encrypted SSH
- channel between two Unix machines?
-
- See the description earlier on this page on how to tunnel VNC via SSH
- from Unix to Unix. A number of ways are described along with some
- issues you may encounter.
-
- Other secure encrypted methods exists, e.g. stunnel, IPSEC, various
- VPNs, etc.
-
- See also the Enhanced TightVNC Viewer (SSVNC) page where much of this
- is now automated.
-
-
- Q-51: How can I tunnel my connection to x11vnc via an encrypted SSH
- channel from Windows using an SSH client like Putty?
-
- Above we described how to tunnel VNC via SSH from Unix to Unix, you
- may want to review it. To do this from Windows using Putty it would go
- something like this:
- * In the Putty dialog window under 'Session' enter the hostname or
- IP number of the Unix machine with display to be viewed.
- * Make sure the SSH protocol is selected and the server port is
- correct.
- * Under 'Connections/SSH/Tunnels' Add a Local connection with
- 'Source port: 5900' and 'Destination: localhost:5900'
- * Log into the remote machine by pressing 'Open' and supplying
- username, password, etc.
- * In that SSH shell, start up x11vnc by typing the command: x11vnc
- -display :0 plus any other desired options (e.g. -localhost.)
- * Finally, start up your VNC Viewer in Windows and enter
- 'localhost:0' as the VNC server.
-
- You can keep all of the settings in a Putty 'Saved Session'. Also,
- once everything is working, you can consider putting x11vnc -display
- :0 (plus other cmdline options) in the 'Remote command' Putty setting
- under 'Connections/SSH'.
-
- See also the Enhanced TightVNC Viewer (SSVNC) page where much of this
- is now automated via the Putty plink utility.
-
- For extra protection feel free to run x11vnc with the -localhost and
- -rfbauth/-passwdfile options.
-
- If the machine you SSH into via Putty is not the same machine with the
- X display you wish to view (e.g. your company provides incoming SSH
- access to a gateway machine), then you need to change the above Putty
- dialog setting to: 'Destination: otherhost:5900', Once logged in,
- you'll need to do a second login (ssh or rsh) to the workstation
- machine 'otherhost' and then start up x11vnc on it. This can also be
- automated by Chaining SSH's.
-
- As discussed above another option is to first start the VNC viewer in
- "listen" mode, and then launch x11vnc with the "-connect localhost"
- option to establish the reverse connection. In this case a Remote port
- redirection (not Local) is needed for port 5500 instead of 5900 (i.e.
- 'Source port: 5500' and 'Destination: localhost:5500' for a Remote
- connection.)
-
-
- Q-52: How can I tunnel my connection to x11vnc via an encrypted SSL
- channel using an external tool like stunnel?
-
- It is possible to use a "lighter weight" encryption setup than SSH or
- IPSEC. SSL tunnels such as stunnel (also stunnel.org) provide an
- encrypted channel without the need for Unix users, passwords, and key
- passphrases required for ssh (and at the other extreme SSL can also
- provide a complete signed certificate chain of trust.) On the other
- hand, since SSH is usually installed everywhere and firewalls often
- let its port through, ssh is frequently the path of least resistance
- (it also nicely manages public keys for you.)
-
- Update: As of Feb/2006 x11vnc has the options -ssl, -stunnel, and
- -sslverify to provide integrated SSL schemes. They are discussed in
- the Next FAQ (you probably want to skip to it now.)
-
- We include these non-built-in method descriptions below for historical
- reference. They are handy because can be used to create SSL tunnels to
- any VNC (or other type of) server.
-
-
- Here are some basic examples using stunnel but the general idea for
- any SSL tunnel utility is the same:
- * Start up x11vnc and constrain it to listen on localhost.
- * Then start up the SSL tunnel running on the same machine to
- forward incoming connections to that x11vnc.
- * Set up and run a similar SSL tunnel for the outgoing connection on
- the VNC viewer machine pointing it to the SSL/x11vnc server.
- * Optionally, set up server (or even client) public/private keys for
- use in authenticating one side to the other.
- * Finally, start the VNC Viewer and tell it to connect to the local
- port (e.g. a vnc display localhost:0) where its outgoing SSL
- tunnel is listening.
-
- We'll first use the stunnel version 3 syntax since it is the most
- concise and Unixy.
-
- Start up x11vnc listening on port 5900:
- x11vnc -display :0 -rfbport 5900 -localhost -bg -passwdfile ~/mypass
-
- Then start stunnel (version 3, not 4) with this command:
- stunnel -d 5901 -r 5900 -p /path/to/stunnel.pem
-
- The above two commands are run on host "far-away.east". The
- stunnel.pem is the self-signed PEM file certificate created when
- stunnel is built. One can also create certificates signed by
- Certificate Authorities or self-signed if desired using the x11vnc
- utilities described there.
-
- SSL Viewers: Next, on the VNC viewer side we need an SSL tunnel to
- encrypt the outgoing connection. The nice thing is any SSL tunnel can
- be used because the protocol is a standard. For this example we'll
- also use stunnel on the viewer side on Unix. First start up the
- client-side stunnel (version 3, not 4):
- stunnel -c -d localhost:5902 -r far-away.east:5901
-
- Then point the viewer to the local tunnel on port 5902:
- vncviewer -encodings "copyrect tight zrle hextile" localhost:2
-
- That's it. Note that the ss_vncviewer script can automate this
- easily, and so can the Enhanced TightVNC Viewer (SSVNC) package.
-
- Be sure to use a VNC password because unlike ssh by default the
- encrypted SSL channel provides no authentication (only privacy.) With
- some extra configuration one could also set up certificates to provide
- authentication of either or both sides as well (and hence avoid
- man-in-the-middle attacks.) See the stunnel and openssl documentation
- and also the key management section for details.
-
- stunnel has also been ported to Windows, and there are likely others
- to choose from for that OS. Much info for using it on Windows can be
- found at the stunnel site and in this article The article also shows
- the detailed steps to set up all the authentication certificates. (for
- both server and clients, see also the x11vnc utilities that do this.)
- The default Windows client setup (no certs) is simpler and only 4
- files are needed in a folder: stunnel.exe, stunnel.conf, libssl32.dll,
- libeay32.dll. We used an stunnel.conf containing:
-# stunnel.conf:
-client = yes
-options = ALL
-[myvncssl]
-accept = localhost:5902
-connect = far-away.east:5901
-
- then double click on the stunnel.exe icon to launch it (followed by
- pointing the VNC viewer to localhost:2).
-
-
- stunnel inetd-like mode:
-
- As an aside, if you don't like the little "gap" of unencrypted TCP
- traffic (and a localhost listening socket) on the local machine
- between stunnel and x11vnc it can actually be closed by having stunnel
- start up x11vnc in -inetd mode:
- stunnel -p /path/to/stunnel.pem -P none -d 5900 -l ./x11vnc_sh
-
- Where the script x11vnc_sh starts up x11vnc:
-#!/bin/sh
-x11vnc -q -inetd -display :0 -passwdfile ~/mypass
-
- Note that this creates a separate x11vnc process for each incoming
- connection (as any inetd x11vnc usage would), but for the case of
- normally just one viewer at a time it should not be a big problem.
-
-
- stunnel 4 syntax:
-
- Somewhat sadly, the stunnel version 4 syntax is not so amenable to the
- command line or scripts. You need to create a config file with the
- parameters. E.g.:
- stunnel x11vnc.cfg
-
- Where the file x11vnc.cfg contains:
-foreground = yes
-pid =
-cert = /path/to/stunnel.pem
-[x11vnc_stunnel]
-accept = 5901
-connect = 5900
-
- One nice thing about version 4 is often the PEM file does not need to
- be specified because stunnel finds it in its installed area. One other
- gotcha the PEM file is usually only readable by root (it has the
- private key afterall), so you'll need to relax the permissions or make
- a copy that the user running x11vnc/stunnel can read.
-
-
- SSL VNC Viewers:
-
- Regarding VNC viewers that "natively" do SSL unfortunately there do
- not seem to be many. The SingleClick UltraVNC Java Viewer is SSL and
- is compatible with x11vnc's -ssl option and stunnel.) Commercial
- versions of VNC seem to have some SSL-like encryption built in, but we
- haven't tried those either and they probably wouldn't work since their
- (proprietary) SSL-like negotiation is likely embedded in the VNC
- protocol unlike our case where it is external.
-
- Note: as of Mar/2006 libvncserver/x11vnc provides a SSL-enabled Java
- applet that can be served up via the -httpdir or -http options when
- -ssl is enabled. It will also be served via HTTPS via either the VNC
- port (e.g. https://host:5900/) or a 2nd port via the -https option.
-
- In general current SSL VNC solutions are not particularly "seemless".
- But it can be done, and with a wrapper script on the viewer side and
- the -stunnel or -ssl option on the server side it works well and is
- convenient. Here is a simple script ss_vncviewer that automates
- running stunnel on the VNC viewer side on Unix a little more carefully
- than the commands printed above. (One could probably do a similar
- thing with a .BAT file on Windows in the stunnel folder.)
-
- Update Jul/2006: we now provide an Enhanced TightVNC Viewer (SSVNC)
- package that starts up STUNNEL automatically along with some other
- features. All binaries (stunnel, vncviewer, and some utilities) are
- provided in the package. It works on Unix, Mac OS X, and Windows.
-
-
- Q-53: Does x11vnc have built-in SSL tunneling?
-
- You can read about non-built-in methods in the Previous FAQ for
- background.
-
- SSL tunnels provide an encrypted channel without the need for Unix
- users, passwords, and key passphrases required for ssh (and at the
- other extreme SSL can also provide a complete signed certificate chain
- of trust.) On the other hand, since SSH is usually installed
- everywhere and firewalls often let its port through, ssh is frequently
- the path of least resistance.
-
- Built-in SSL x11vnc options:
-
- As of Feb/2006 the x11vnc -ssl option automates the SSL tunnel
- creation on the x11vnc server side. An SSL-enabled Java Viewer applet
- is also provided that can be served via HTTP or HTTPS to automate SSL
- on the client side.
-
- The -ssl mode uses the www.openssl.org library if available at build
- time.
-
- The mode requires an SSL certificate and key (i.e. .pem file.) These
- are usually created via the openssl(1) program (in fact in for "-ssl"
- (same as "-ssl SAVE") it will run openssl for you automatically.) So
- the SSL is not completely "built-in" since this external tool needs to
- be installed, but at least x11vnc runs it for you automatically.
-
- An -ssl example:
- x11vnc -display :0 -ssl -passwdfile ~/mypass
-
- You'll get output like this:
- 09/04/2006 19:27:35 Creating a self-signed PEM certificate...
- 09/04/2006 19:27:35
- ...
-
- The SSL VNC desktop is: far-away.east:0
- PORT=5900
- SSLPORT=5900
-
- In this case openssl(1) was used to create a PEM automatically. It
- will prompt you if you want to protect it with with a passphrase. Use
- "-ssl SAVE_NOPROMPT" to not be prompted. Use "-ssl TMP" to create a
- temporary self-signed cert that will be discarded when x11vnc exits.
-
- Update: As of Nov/2008 x11vnc also supports the VeNCrypt SSL/TLS
- tunnel extension to the VNC protocol. The older ANONTLS method (vino)
- is also supported. This support is on by default when the -ssl option
- is in use and can be fine-tuned using these options: -vencrypt,
- -anontls, and -sslonly.
-
- The normal x11vnc -ssl operation is somewhat like a URL method
- vncs://hostname if vnc://hostname indicates a standard unencrypted VNC
- connection. Just as https://hostname is an SSL encrypted version of
- http://hostname. The entire VNC session goes through the SSL tunnel.
- VeNCrypt, on the other hand, switches to SSL/TLS early in the VNC
- protocol handshake. x11vnc 0.9.6 supports both simultaneously when
- -ssl is active.
-
-
- SSL VNC Viewers:. Viewer-side will need to use SSL as well. See the
- next FAQ and here for SSL enabled VNC Viewers, including SSVNC, to
- connect to the above x11vnc via SSL.
-
-
- As seen above, the PEM (privacy enhanced mail) file does not need to
- be supplied if the openssl(1) command is available in PATH, in that
- case a self-signed, certificate good the current and subsequent x11vnc
- sessions is created (this may take a while on very slow machines.)
-
- In general, the PEM file contains both the Certificate (i.e. public
- key) and the Private Key. Because of the latter, the file should be
- protected from being read by untrusted users. The best way to do this
- is to encrypt the key with a passphrase (note however this requires
- supplying the passphrase each time x11vnc is started up.)
-
- See the discussion on x11vnc Key Management for some utilities
- provided for creating and managing certificates and keys and even for
- creating your own Certificate Authority (CA) for signing VNC server
- and client certificates. This may be done by importing the certificate
- into Web Browser or Java plugin keystores, or pointing stunnel to it.
- The wrapper script ss_vncviewer provides an example on unix (see the
- -verify option.)
-
- Here are some notes on the simpler default (non-CA) operation. To have
- x11vnc save the generated certificate and key, use the "SAVE" keyword
- like this:
- x11vnc -ssl SAVE -display :0 ...
-
- (this is the same as the default: "-ssl".) This way it will be saved
- in the default directory ~/.vnc/certs/ as server.crt (the certificate
- only) and server.pem (both certificate and private key.) This opens up
- the possibility of copying the server.crt to machines where the VNC
- Viewer will be run to enable authenticating the x11vnc SSL VNC server
- to the clients. When authentication takes place this way (or via the
- more sophisticated CA signing described here), then
- Man-In-The-Middle-Attacks are prevented. Otherwise, the SSL encryption
- only provides protection against passive network traffic "sniffing"
- (i.e. you are not protected against M-I-T-M attacks.) Nowadays, most
- people seem mostly concerned mainly about passive sniffing (and the
- default x11vnc SSL mode protects against it.) Note that there are
- hacker tools like dsniff/webmitm and cain that implement SSL
- Man-In-The-Middle attacks. They rely on the client not bothering to
- check the cert.
-
-
- One can test to some degree that SSL is working after starting x11vnc
- with the -stunnel or -ssl option. From another machine one can use the
- openssl command something like this:
- openssl s_client -debug -msg -showcerts -connect far-away.east:5900
-
- After all of the debugging output and informational messages you'll
- see the string "RFB 003.008" that came from x11vnc. Pointing a web
- browser connecting to: https://far-away.east:5900/ and then viewing
- the SSL certificate information about the connection in the panels
- will also work.
-
- Note: If you serve up the SSL enabled Java VNC Viewer via something
- like:
- x11vnc -ssl -httpdir /usr/local/share/x11vnc/classes/ssl
-
- (or just the -http option), you can test it out completely using that,
- including using https to download it into the browser and connect to
- x11vnc.
-
-
- The older -stunnel option: Before the -ssl option there was a
- convenience option -stunnel that would start an external SSL tunnel
- for you using stunnel. The -ssl method is the preferred way, but for
- historical reference we keep the -stunnel info here.
-
- The -stunnel mode requires the stunnel.mirt.net command stunnel(8) to
- be installed on the system.
-
- Some -stunnel examples:
- x11vnc -display :0 -stunnel /path/to/stunnel.pem -passwdfile ~/mypass
-
- x11vnc -display :0 -stunnel SAVE ...
-
- You'll get output like this:
- The VNC desktop is: localhost:50
- The SSL VNC desktop is: far-away.east:0
- PORT=5950
- SSLPORT=5900
-
- That indicates stunnel is listening on port 5900 for incoming
- SSL-wrapped VNC connections from viewers. x11vnc is listening for
- local connections on port 5950 in this case (remote viewers cannot
- connect to it directly.) For -stunnel to work the stunnel command must
- be installed on the machine and available in PATH (note stunnel is
- often installed in sbin directories rather than bin.) Note that the
- default "-stunnel" by itself creates a temporary cert (as in "-ssl
- TMP".)
-
-
- Q-54: How do I use VNC Viewers with built-in SSL tunneling?
-
- Notes on using "native" VNC Viewers with SSL:
-
- There aren't any native VNC Viewers that do SSL (ask your VNC viewer
- developer to add the feature.) So a tunnel must be setup that you
- point the VNC Viewer to. This is often STUNNEL. You can do this
- manually, or use the ss_vncviewer script on Unix, or our Enhanced
- TightVNC Viewer (SSVNC) package on Unix, Windows, or MacOSX. See the
- next section for Java Web browser SSL VNC Viewers (you only need a
- Java-enabled Web browser for it to work.)
-
- Notes on the SSL enabled Java VNC Viewer provided in x11vnc
- classes/ssl/VncViewer.jar:
-
- A Java applet VNC Viewer allows you to connect to a VNC Server from a
- Java-enabled Web browser.
-
- The SSL enabled Java VNC Viewer (VncViewer.jar) in the x11vnc package
- supports only SSL based connections by default. As mentioned above the
- -httpdir can be used to specify the path to .../classes/ssl. A typical
- location might be /usr/local/share/x11vnc/classes/ssl. Or -http can be
- used to try to have it find the directory automatically.
-
- Also note that the SingleClick UltraVNC Java Viewer is compatible with
- x11vnc's -ssl SSL mode. (We tested it this way: "java -cp
- ./VncViewer.jar VncViewer HOST far-away.east PORT 5900 USESSL 1
- TRUSTALL 1")
-
- The Java viewer uses SSL to communicate securely with x11vnc. Note
- that the applet can optionally also be downloaded into your web
- browser via HTTPS (which is HTTP over SSL.) This way the HTML page and
- the Java applet itself are also delivered securely with SSL (as
- opposed to only the VNC traffic being encrypted with SSL.)
-
- For this case the output will be something like this:
- x11vnc -ssl SAVE -http
- ...
- The SSL VNC desktop is: far-away.east:0
- Java SSL viewer URL: https://far-away.east:5900/
- Java SSL viewer URL: http://far-away.east:5800/
- PORT=5900
- SSLPORT=5900
-
- Indicating the two URLs (the first one encrypted, the second not) one
- could point the web browser at to get the VNC viewer applet. E.g. put
- this
- http://far-away.east:5800/
-
- or:
- https://far-away.east:5900/
-
- into your Java-enabled Web browser.
-
- Note that KDE's Konqueror web browser seems to have problems with
- https Java applets, so you'll have to use the http/5800 with it (if
- you get https/5900 working let us know how you did it.)
-
- If you are using a router/firewall with port-redirection, and you are
- redirecting ports other than the default ones (5800, 5900) listed
- above see here.
-
- The https service provided thru the actual VNC port (5900 in the above
- example) can occasionally be slow or unreliable (it has to read some
- input and try to guess if the connection is VNC or HTTP.) If it is
- unreliable for you and you still want to serve the Java applet via
- https, use the -https option to get an additional port dedicated to
- https (its URL will also be printed in the output.)
-
- Another possibility is to add the GET applet parameter:
- https://far-away.east:5900/?GET=1
-
- This will have the VNC Viewer send a special HTTP GET string "GET
- /request.https.vnc.connection HTTP/1.0" that x11vnc will notice more
- quickly as a request for a VNC connection. Otherwise it must wait for
- a timeout to expire before it assumes a VNC connection.
-
- You may also use "urlPrefix=somestring" to have /somestring prepended
- to /request.https.vnc.connection". Perhaps you are using a web server
- proxy scheme to enter a firewall or otherwise have rules applied to
- the URL. If you need to have any slashes "/" in "somestring" use
- "_2F_" (a deficiency in libvncserver prevents using the more natural
- "%2F".)
-
- You apply multiple applet parameters in the regular URL way, e.g.:
- https://far-away.east:5900/?GET=1&urlPrefix=mysubdir&...
-
- All of the x11vnc Java Viewer applet parameters are described in the
- file classes/ssl/README
-
-
- Tips on Getting the SSL Java Applet Working the First Time:
- Unfortunately, it can be a little tricky getting the SSL VNC Java
- Viewer working with x11vnc. Here are some tips to getting working the
- first time (afterwards you can incrementally customize with more
- complex settings.)
- * First try it on the LAN: Do NOT try to have it work the first time
- going through firewalls, Web proxies, home router port
- redirections, or Apache portal. Just try a direct connection over
- your LAN first (if you only have 1 machine and no LAN, just do a
- direct connection to the same machine: localhost.) If the LAN
- machine you run x11vnc on has its own host-level firewall (most
- linux machine come with that on by default), disable it or at
- least let tcp ports 5800-6000 through.
- * First try HTTP to download the Java Applet: x11vnc can serve both
- the Java Applet jar file and VNC out of the same port (both
- tunneled through SSL, see below.) But it can lead to timing and
- other problems. So first try HTTP instead of HTTPS to download the
- Applet jar file (VncViewer.jar.) That is to say try
- http://hostname:5800 in your web browser first before trying
- https://hostname:5900. x11vnc will print out the ports and URLs it
- is using, so use the HTTP one it prints out.
- * Always Restart the Browser: If you are having failures and have to
- repeatedly retry things ALWAYS restart the browser (i.e.
- completely exit it and then start a new browser process) each
- time. Otherwise as you are changing things the browser may
- "remember" failed applet downloads, etc. and just add to the
- confusion and irreproducibility. If you see it trying to download
- VncViewer.class (instead of VncViewer.jar) you know it is really
- confused and needs to be restarted.
- * Step Lively: If you get Browser or Java VM or VNC Viewer applet
- dialog boxes saying things like "Do you want to trust this
- certificate?" or "The hostname does not match the one on the
- certificate", etc. just go through them as quickly as possible.
- x11vnc cannot wait forever for each SSL connection, and so if you
- dawdle too long inspecting the certs, etc it can lead to problems.
- Get it working first before taking your time to read the details
- in the dialogs, etc.
- * No inetd, Please: Even if you intend to deploy via inetd or xinetd
- eventually, get that working later (and remember do not use
- something like "-ssl TMP" that creates a new temporary SSL
- certificate for every new socket connection.)
- * Nothing Fancy: Do not try fancy stuff like -svc, -create, -unixpw,
- "-users unixpw=", "-users sslpeer=", -sslverify, etc. Just get the
- simplest connection working first and then incrementally add what
- you need.
-
- So the recommended test command lines are:
- x11vnc -ssl SAVE -http
- x11vnc -ssl SAVE -httpdir /path/to/x11vnc/classes/ssl
-
- Use the latter if x11vnc cannot automatically find the classes/ssl
- directory (this what the -http option instructs it to do.) Then point
- your browser to the HTTP (not HTTPS) URL it prints out.
-
- Following the above guidelines, did it work? If so, Congratulations!!
- you created an SSL encrypted connection between the SSL Java applet
- running in your web browser and x11vnc. The fact that you used HTTP
- instead of HTTPS to download the applet is not the end of the world
- (some users do it this way), the main thing is that the VNC traffic is
- encrypted with SSL. If you are having trouble even with the above
- baseline test case feel free to contact me (please send the Full
- x11vnc output, not just part of it; the complete x11vnc command line;
- the URL(s) entered in the browser; the full Java Console output; and
- anything else you can think of.)
-
- Next, you can add the features you want one by one testing it still
- works each time. I suggest first turning on the HTTPS applet download
- (https://hostname:5900) if that is what you intend to use. That one
- gives the most trouble because of the ambiguity of passing two
- different protocols (HTTP and VNC) through the same SSL service port.
-
- Next, turn on inetd if you intend to use that (this can be tricky too,
- be sure to use -oa logfile and inspect it carefully if there are
- problems.) If you are going to use non-standard ports (e.g. "-rfbport
- 443" as root), work on that next. Then enable the firewall, router
- port redirection channel (you will somehow need to be outside to do
- that, maybe test that through another VNC session.)
-
- Then, if you plan to use them, enable "fancy stuff" like "-svc" or
- "-unixpw", etc, etc. Be sure to add a password either "-rfbauth" or
- "-unixpw" or both. If you need to have the web browser use a corporate
- Web Proxy (i.e. it cannot connect directly) work on that last. Ditto
- for the Apache portal.
-
-
- Router/Firewall port redirs: If you are doing port redirection at
- your router to an internal machine running x11vnc AND the internet
- facing port is different from the internal machine's VNC port, you
- will need to apply the PORT applet parameter to indicate to the applet
- the Internet facing port number (otherwise by default the internal
- machine's port, say 5900, is sent and that of course is rejected at
- the firewall/router.) For example:
- https://far-away.east:443/?GET=1&PORT=443
-
- So in this example the user configures his router to redirect
- connections to port 443 on his Internet side to, say, port 5900 on the
- internal machine running x11vnc. See also the -httpsredir option that
- will try to automate this for you.
-
- To configure your router to do port redirection, see its instructions.
- Typically, from the inside you point a web browser to a special URL
- (e.g. http://192.168.1.1) and you get a web interface to configure it.
- Look for something like "Port Redirection" or "Port Forwarding",
- probably under "Advanced" or something like that. If you have a Linux
- or Unix system acting as your firewall/router, see its firewall
- configuration.
-
- You can also use x11vnc options -rfbport NNNNN and -httpport NNNNN to
- match the ports that your firewall will be redirecting to the machine
- where x11vnc is run.
-
-
- Tedious Dialogs: If you do serve the SSL enabled Java viewer via https
- be prepared for quite a number of "are you sure you trust this site?"
- dialogs:
- * First from the Web browser that cannot verify the self-signed
- certificate when it downloads index.vnc.
- * From the Web browser again noting that the common name on the
- certificate does not match the hostname of the remote machine.
- * Next from the Java VM that cannot verify the self-signed
- certificate when it downloads VncViewer.jar.
- * And also from the Java VM again noting that the common name on the
- certificate does not match the hostname of the remote machine.
- * Finally from the Java VncViewer applet itself saying it cannot
- verify the certificate! (or a popup asking you if you want to see
- the certificate.)
-
- Note that sometimes if you pause too long at one of the above dialogs
- then x11vnc may exceed a timeout and assume the current socket
- connection is VNC instead of the HTTPS it actually is (but since you
- have paused too long at the dialog the GET request comes too late.)
- Often hitting Reload and going through the dialogs more quickly will
- let you connect. The Java VM dialogs are the most important ones to
- NOT linger at. If you see in the x11vnc output a request for
- VncViewer.class instead of VncViewer.jar it is too late... you will
- need to completely restart the Web browser to get it to try for the
- jar again. You can use the -https option if you want a dedicated port
- for HTTPS connections instead of sharing the VNC port.
-
- To see example x11vnc output for a successful https://host:5900/
- connection with the Java Applet see This Page. And here is a newer
- example including the Java Console output.
-
- All of the x11vnc Java Viewer applet parameters are described in the
- file classes/ssl/README
-
-
- Notes on the VNC Viewer ss_vncviewer wrapper script:
-
- If you want to use a native VNC Viewer with the SSL enabled x11vnc you
- will need to run an external SSL tunnel on the Viewer side. There do
- not seem to be any native SSL VNC Viewers outside of our x11vnc and
- SSVNC packages. The basic ideas of doing this were discussed for
- external tunnel utilities here.
-
- The ss_vncviewer script provided with x11vnc and SSVNC can set up the
- stunnel tunnel automatically on unix as long as the stunnel command is
- installed on the Viewer machine and available in PATH (and vncviewer
- too of course.) Note that on a Debian based system you will need to
- install the package stunnel4 not stunnel. You can set the environment
- variables STUNNEL and VNCVIEWERCMD to point to the correct programs if
- you want to override the defaults.
-
- Here are some examples:
- 1) ss_vncviewer far-away.east:0
-
- 2) ss_vncviewer far-away.east:0 -encodings "copyrect tight zrle hextile"
-
- 3) ss_vncviewer -verify ./server.crt far-away.east:0
-
- 4) ss_vncviewer -mycert ./client.pem far-away.east:0
-
- 5) ss_vncviewer -proxy far-away.east:8080 myworkstation:0
-
- The first one is the default mode and accepts the x11vnc certificate
- without question. The second one is as the first, but adds the
- -encodings options to the vncviewer command line.
-
- The third one requires that the x11vnc server authenticate itself to
- the client against the certificate in the file ./server.crt (e.g. one
- created by "x11vnc -ssl SAVE" and safely copied to the VNC viewer
- machine.)
-
- The fourth one is for VNC Viewer authentication, it uses ./client.pem
- to authenticate itself to x11vnc. One can supply both -verify and
- -mycert simultaneously.
-
- The fifth one shows that Web proxies can be used if that is the only
- way to get out of the firewall. If the "double proxy" situation arises
- separate the two by commas. See this page for more information on how
- Web proxies come into play.
-
- If one uses a Certificate Authority (CA) scheme described here, the
- wrapper script would use the CA cert instead of the server cert:
- 3') ss_vncviewer -verify ./cacert.crt far-away.east:0
-
- Update Jul/2006: we now provide an Enhanced TightVNC Viewer (SSVNC)
- package that starts up STUNNEL automatically along with some other
- features. All binaries (stunnel, vncviewer, and some utilities) are
- provided in the package. It works on Unix, Mac OS X, and Windows.
-
-
- Q-55: How do I use the Java applet VNC Viewer with built-in SSL
- tunneling when going through a Web Proxy?
- The SSL enabled Java VNC Viewer and firewall Proxies:
-
- SSL and HTTPS aside, there is a general problem with Firewall Proxies
- and Java Applets that open sockets. The applet is downloaded
- successfully (through the browser) using HTTP and the proxy, but when
- the applet tries to reconnect to the originating host (the only one
- allowed by security) it does not use the proxy channel. So it cannot
- reconnect to the server the applet came from!
-
- We have found a convenient workaround: in the directory where
- VncViewer.jar resides there is a digitally signed version of the same
- applet called SignedVncViewer.jar. Since the applet is digitally
- signed, there will be an additional dialog from the Java VM plugin
- asking you if you want to trust the applet fully.
-
- You should say "Yes". If you do, the applet will be run in a mode
- where it can try to determine the firewall proxy host name and port
- (it will ask you for them if it cannot find them.) This way it can
- connect directly to the Proxy and then request the CONNECT method to
- be redirected to the originating host (the x11vnc VNC Server.) SSL is
- then layered over this socket.
-
- To do this you should use the proxy.vnc HTML file like via this URL in
- your browser:
- https://yourmachine.com:5900/proxy.vnc
-
- (instead of the unsigned one in https://yourmachine.com:5900/ that
- gives the default index.vnc)
-
- Proxies that limit CONNECT to ports 443 and 563:
-
- Things become trickier if the Web proxy restricts which CONNECT ports
- can be redirected to. For security, some (most?) proxies only allow
- port 443 (HTTPS) and 563 (SNEWS) by default. In this case, the only
- thing to do is run x11vnc on that low port, e.g. "-rfbport 443", (or
- use a port redirection on, say, a firewall or router port 443 to the
- internal machine.)
-
- If you do such a redirection to an internal machine and x11vnc is not
- listening on port 443, you will probably need to edit proxy.vnc.
- Suppose the SSL x11vnc server was listening on port 5901. You should
- change the line in proxy.vnc from:
- <param name=PORT value=$PORT>
-
- to:
- <param name=PORT value=443>
-
- Since otherwise $PORT will be expanded to 5901 by x11vnc and the
- viewer applet will fail to connect to that port on the firewall.
-
- Another way to achieve the same thing is to use the applet PORT
- parameter:
- https://yourmachine.com/proxy.vnc?PORT=443
-
- this is cleaner because it avoids editing the file, but requires more
- parameters in the URL. See also the -httpsredir x11vnc option that
- will try to automate this for you. To use the GET trick discussed
- above, do:
- https://yourmachine.com/proxy.vnc?GET=1&PORT=443
-
- All of the x11vnc Java Viewer applet parameters are described in the
- file classes/ssl/README
-
- Here is an example of Java Console and x11vnc output for the Web proxy
- case.
-
-
- Note that both the ss_vncviewer stunnel Unix wrapper script and
- Enhanced TightVNC Viewer (SSVNC) can use Web proxies as well even
- though they do not involve a Web browser.
-
-
- Q-56: Can Apache web server act as a gateway for users to connect via
- SSL from the Internet with a Web browser to x11vnc running on their
- workstations behind a firewall?
- Yes. You will need to configure apache to forward these connections.
- It is discussed here. This SSL VNC portal provides a clean alternative
- to the traditional method where the user uses SSH to log in through
- the gateway to create the encrypted port redirection to x11vnc running
- on her desktop.
-
- Also see the desktop.cgi CGI script method that achieves much of what
- this Apache VNC SSL portal method does (as long as desktop.cgi's 'port
- redirection' mode is enabled.)
-
-
- Q-57: Can I create and use my own SSL Certificate Authority (CA) with
- x11vnc?
- Yes, see this page for how to do this and the utility commands x11vnc
- provides to create and manage many types of certificates and private
- keys.
-
-
-
- [Display Managers and Services]
-
- Q-58: How can I run x11vnc as a "service" that is always available?
-
- There are a number of ways to do this. The primary thing you need to
- decide is whether you want x11vnc to connect to the X session on the
- machine 1) regardless of who (or if anyone) has the X session, or 2)
- only if a certain user has the X session. Because X sessions are
- protected by X permissions (MIT-MAGIC-COOKIE files XAUTHORITY and
- $HOME/.Xauthority) the automatically started x11vnc will of course
- need to have sufficient permissions to connect to the X display.
-
- Here are some ideas:
- * Use the description under "Continuously" in the FAQ on x11vnc and
- Display Managers
- * Use the description in the FAQ on x11vnc and inetd(8)
- * Use the description in the FAQ on Unix user logins and inetd(8)
- * Start x11vnc from your $HOME/.xsession (or $HOME/.xinitrc or
- autostart script or ...)
- * Although less reliable, see the x11vnc_loop rc.local hack below.
-
- The display manager scheme will not be specific to which user has the
- X session unless a test is specifically put into the display startup
- script (often named Xsetup.) The inetd(8) scheme may or may not be
- specific to which user has the X session (and it may not be able to do
- all users via the XAUTHORITY permission issues.)
-
- The .xsession/.xinitrc scheme is obviously is specific to a particular
- user and only when they are logged into X. If you do not know what a
- $HOME/.xsession script is or how to use one, perhaps your desktop has
- a "session startup commands" configuration option. The command to be
- run in the .xsession or .xinitrc file may look like this:
-x11vnc -logfile $HOME/.x11vnc.log -rfbauth $HOME/.vnc/passwd -forever -bg
-
- plus any other options you desire.
-
- Depending on your desktop and/or OS/distribution the automatically run
- X startup scripts (traditionally .xsession/.xinitrc) may have to be in
- a different directory or have a different basename. One user
- recommends the description under 'Running Scripts Automatically' at
- this link.
-
- Firewalls: note all methods will require the host-level firewall to be
- configured to allow connections in on a port. E.g. 5900 (default VNC
- port) or 22 (default SSH port for tunnelling VNC.) Most systems these
- days have firewalls turned on by default, so you will actively have to
- do something to poke a hole in the firewall at the desired port
- number. See your system administration tool for Firewall settings
- (Yast, Firestarter, etc.)
-
-
- Q-59: How can I use x11vnc to connect to an X login screen like xdm,
- GNOME gdm, KDE kdm, or CDE dtlogin? (i.e. nobody is logged into an X
- session yet.)
-
- We describe two scenarios here. The first is called 'One time only'
- meaning you just need to do it quickly once and don't want to repeat;
- and the second is called 'Continuously' meaning you want the access to
- be available after every reboot and after every desktop logout.
- _________________________________________________________________
-
- One time only: If the X login screen is running and you just want to
- connect to it once (i.e. a one-shot):
-
- It is usually possible to do this by just adjusting the XAUTHORITY
- environment variable to point to the correct MIT-COOKIE auth file
- while running x11vnc as root, e.g. for the gnome display manager, GDM:
- x11vnc -auth /var/gdm/:0.Xauth -display :0
-
- (the -auth option sets the XAUTHORITY variable for you.)
-
- There will be a similar thing to do for xdm using however a different
- auth directory path (perhaps something like
- /var/lib/xdm/authdir/authfiles/A:0-XQvaJk) for the xdm greeter or
- /var/lib/kdm/A:0-crWk72 (or /var/run/xauth/A:0-qQPftr, etc. etc) for
- the kdm greeter. Of course, the random characters in the file basename
- will vary and you will need to use the actual filename on your system.
- Read your system docs to find out where the display manager cookie
- files are kept.
-
- Trick: sometimes ps(1) can reveal the X server process -auth argument
- (e.g. "ps wwaux | grep auth") and hence the path to the auth file.
-
- x11vnc must be run as root for this because the /var/gdm/:0.Xauth,
- /var/lib/kdm/A:0-crWk72, etc. auth files are only readable by root. If
- you do not want to run x11vnc as root, you can copy (as root or sudo)
- the auth file to some location and make it readable by your userid.
- Then run x11vnc as your userid with -auth pointed to the copied file.
-
- Update Dec/2009: use "-auth guess" to have x11vnc try to guess the
- location of the auth file for you.
-
- You next connect to x11vnc with a VNC viewer, give your username and
- password to the X login prompt to start your session.
-
- Note: GDM: gdm seems to have an annoying setting that causes x11vnc
- (and any other X clients) to be killed after the user logs in. Setting
- KillInitClients=false in the [daemon] section of /etc/X11/gdm/gdm.conf
- (or /etc/gdm/gdm.conf, etc.) avoids this. Otherwise, just restart
- x11vnc and then reconnect your viewer. Other display managers (kdm,
- etc) may also have a similar problem. One user reports having to alter
- "gdm.conf-custom" as well.
-
- Note: Solaris: For dtlogin in addition to the above sort of trick
- (BTW, the auth file should be in /var/dt), you'll also need to add
- something like Dtlogin*grabServer:False to the Xconfig file
- (/etc/dt/config/Xconfig or /usr/dt/config/Xconfig on Solaris, see the
- example at the end of this FAQ.) Then restart dtlogin, e.g.:
- /etc/init.d/dtlogin stop; /etc/init.d/dtlogin start or reboot.
-
- Update Nov/2008: Regarding GDM KillInitClients: see the -reopen option
- for another possible workaround.
-
- Update Oct/2009: Regarding GDM KillInitClients: starting with x11vnc
- 0.9.9 it will try to apply heuristics to detect if a window manager is
- not running (i.e. whether the Display Manager Greeter Login panel is
- still up.) If it thinks the display manager login is still up it will
- delay creating windows or using XFIXES. The former is what GDM uses to
- kill the initial clients, use of the latter can cause a different
- problem: an Xorg server crash. So with 0.9.9 and later it should all
- work without needing to set KillInitClients=false (which is a good
- because recent GDM, v2.24, has removed this option) or use -noxfixes.
- To disable the heuristics and delaying set X11VNC_AVOID_WINDOWS=never;
- to set the delay time explicitly use, e.g., X11VNC_AVOID_WINDOWS=120
- (delays for 120 seconds after the VNC connection; you have that long
- to log in.)
- _________________________________________________________________
-
- Continuously: Have x11vnc reattach each time the X server is
- restarted (i.e. after each logout and reboot):
-
- To make x11vnc always attached to the X server including the login
- screen you will need to add a command to a display manager startup
- script.
-
- Please consider the security implications of this! The VNC display for
- the X session always accessible (but hopefully password protected.)
- Add -localhost if you only plan to access via a SSH tunnel.
-
- The name of the display manager startup script file depends on desktop
- used and seem to be:
- GDM (GNOME) /etc/X11/gdm/Init/Default
- /etc/gdm/Init/Default
- KDM (KDE) /etc/kde*/kdm/Xsetup
- XDM /etc/X11/xdm/Xsetup (or sometimes xdm/Xsetup_0)
- CDE /etc/dt/config/Xsetup
-
- although the exact location can be operating system, distribution, and
- time dependent. See the documentation for your display manager:
- gdm(1), kdm(1), xdm(1), dtlogin(1) for additional details. There may
- also be display number specific scripts: e.g. Xsetup_0 vs. Xsetup, you
- need to watch out for.
-
- Note: You should read and understand all of the Note's and Update's
- in the 'One time only' section above. All of the GDM topics apply here
- as well:
-
- Note: GDM: The above (in 'One time only') gdm setting of
- KillInitClients=false in /etc/X11/gdm/gdm.conf (or /etc/gdm/gdm.conf,
- etc.) for GDM is needed here as well. Other display managers (KDM,
- etc) may also have a similar problem.
-
- Also see the Update Oct/2009 above where x11vnc 0.9.9 and later
- automatically avoids being killed.
-
- Note: DtLogin: The above (in 'One time only')
- Dtlogin*grabServer:False step for Solaris will be needed for dtlogin
- here as well.
-
- In any event, the line you will add to the display manager script
- (Xsetup, Default, or whatever) will look something like:
- /usr/local/bin/x11vnc -rfbauth /path/to/the/vnc/passwd -o /var/log/x11vnc.log
- -forever -bg
-
- where you should customize the exact command to your needs (e.g.
- -localhost for SSH tunnel-only access; -ssl SAVE for SSL access; etc.)
-
- Happy, happy, joy, joy: Note that we do not need to specify -display
- or -auth because happily they are already set for us in the DISPLAY
- and XAUTHORITY environment variables for the Xsetup script!!!
-
- You may also want to force the VNC port with something like "-rfbport
- 5900" (or -N) to avoid autoselecting one if 5900 is already taken.
- _________________________________________________________________
-
- Fedora/gdm: Here is an example of what we did on a vanilla install of
- Fedora-C3 (seems to use gdm by default.) Add a line like this to
- /etc/X11/gdm/Init/:0
- /usr/local/bin/x11vnc -rfbauth /etc/x11vnc.passwd -forever -bg -o /var/log/x1
-1vnc.log
-
- And then add this line to /etc/X11/gdm/gdm.conf (or /etc/gdm/gdm.conf,
- etc.) in the [daemon] section:
- KillInitClients=false
-
- Then restart: /usr/sbin/gdm-restart (or reboot.) The
- KillInitClients=false setting is important: without it x11vnc will be
- killed immediately after the user logs in. Here are full details on
- how to configure gdm
- _________________________________________________________________
-
- Solaris/dtlogin: Here is an example of what we did on a vanilla
- install of Solaris:
- Make the directory /etc/dt/config:
- mkdir -p /etc/dt/config
-
- Copy over the Xconfig file for customization:
- cp /usr/dt/config/Xconfig /etc/dt/config/Xconfig
-
- Edit /etc/dt/config/Xconfig and uncomment the line:
- Dtlogin*grabServer: False
-
- Next, copy over Xsetup for customization:
- cp /usr/dt/config/Xsetup /etc/dt/config/Xsetup
-
- Edit /etc/dt/config/Xsetup and at the bottom put a line like:
- /usr/local/bin/x11vnc -forever -o /var/log/x11vnc.log -bg
-
- (tweaked to your local setup and preferences, a password via -rfbauth,
- etc. would be a very good idea.)
-
- Restart the X server and dtlogin:
- /etc/init.d/dtlogin stop
- /etc/init.d/dtlogin start
-
- (or reboot or maybe just restart the X session.)
- _________________________________________________________________
-
- KDM: One user running the kdm display manager reports putting this
- line:
- x11vnc -forever -rfbauth /home/xyz/.vnc/passwd -bg -o /var/log/x11vnc.log
-
- in /etc/kde/kdm/Xsetup. After rebooting the system it all seemed to
- work fine.
- _________________________________________________________________
-
-
- If you do not want to deal with any display manager startup scripts,
- here is a kludgey script that can be run manually or out of a boot
- file like rc.local: x11vnc_loop It will need some local customization
- before running. Because the XAUTHORITY auth file must be guessed by
- this script, use of the display manager script method described above
- is greatly preferred. There is also the -loop option that does
- something similar.
-
- If the machine is a traditional Xterminal you may want to read this
- FAQ.
-
- Firewalls: note all methods will require the host-level firewall to be
- configured to allow connections in on a port. E.g. 5900 (default VNC
- port) or 22 (default SSH port for tunnelling VNC.) Most systems these
- days have firewalls turned on by default, so you will actively have to
- do something to poke a hole in the firewall at the desired port
- number. See your system administration tool for Firewall settings
- (Yast, Firestarter, etc.)
-
-
- Q-60: Can I run x11vnc out of inetd(8)? How about xinetd(8)?
-
- Yes, perhaps a line something like this in /etc/inetd.conf will do it
- for you:
-
- 5900 stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/x11vnc_sh
-
- where the shell script /usr/local/bin/x11vnc_sh uses the -inetd option
- and looks something like (you'll need to customize to your settings.)
-#!/bin/sh
-/usr/local/bin/x11vnc -inetd -display :0 -auth /home/fred/.Xauthority \
- -rfbauth /home/fred/.vnc/passwd -o /var/log/x11vnc_sh.log
-
- Important: Note that you must redirect the standard error output to a
- log file (e.g. -o logfile) or "2>/dev/null" for proper operation via
- inetd (otherwise the standard error also goes to the VNC vncviewer,
- and that confuses it greatly, causing it to abort.) If you do not use
- a wrapper script as above but rather call x11vnc directly in
- /etc/inetd.conf and do not redirect stderr to a file, then you must
- specify the -q (aka -quiet) option: "/usr/local/bin/x11vnc -q -inetd
- ...". When you supply both -q and -inet and no "-o logfile" then
- stderr will automatically be closed (to prevent, e.g. library stderr
- messages leaking out to the viewer.) The recommended practice is to
- use "-o logfile" to collect the output in a file or wrapper script
- with "2>logfile" redirection because the errors and warnings printed
- out are very useful in troubleshooting problems.
-
- Note also the need to set XAUTHORITY via -auth to point to the
- MIT-COOKIE auth file to get permission to connect to the X display
- (setting and exporting the XAUTHORITY variable accomplishes the same
- thing.) See the x11vnc_loop file in the previous question for more
- ideas on what that auth file may be, etc. The scheme described in the
- FAQ on Unix user logins and inetd(8) works around the XAUTHORITY issue
- nicely.
-
- Note: On Solaris you cannot have the bare number 5900 in
- /etc/inetd.conf, you'll need to replace it with a word like x11vnc an
- then put something like "x11vnc 5900/tcp" in /etc/services.
-
- Since the process runs as root, it might be a bad idea to have the
- logfile in a world-writable area like /tmp if there are untrustworthy
- users on the machine. Perhaps /var/log is a better place.
-
- Be sure to look at your /etc/hosts.allow and /etc/hosts.deny settings
- to limit the machines that can connect to this service (your desktop!)
- For the above example with /etc/hosts.allow:
- x11vnc_sh : 123.45.67.89
-
- A really safe way to do things is to limit the above inetd to
- localhost only (via /etc/hosts.allow) and use ssh to tunnel the
- incoming connection. Using inetd for this prevents there being a tiny
- window of opportunity between x11vnc starting up and your vncviewer
- connecting to it. Always use a VNC password to further protect against
- unwanted access.
-
- For xinetd(8), one user reports he created the file
- /etc/xinetd.d/x11vncservice containing the following:
-# default: off
-# description:
-service x11vncservice
-{
- flags = REUSE NAMEINARGS
- port = 5900
- type = UNLISTED
- socket_type = stream
- protocol = tcp
- wait = no
- user = root
- server = /usr/sbin/tcpd
- server_args = /usr/local/bin/x11vnc_sh
- disable = no
-}
-
- With the contents of /usr/local/bin/x11vnc_sh similar to the example
- given above. One user reports this works with avoiding the wrapper
- script:
-service x11vncservice
-{
- port = 5900
- type = UNLISTED
- socket_type = stream
- protocol = tcp
- wait = no
- user = root
- server = /usr/local/bin/x11vnc
- server_args = -inetd -q -display :0 -auth /var/gdm/:0.Xauth
- disable = no
-}
-
- (or one can replace the -q with say "-o /var/log/x11vnc.log" to
- capture a log)
-
- The above works nicely for GDM because the -auth file is a fixed name.
- For KDM or XDM the filename varies. Here is one idea for a x11vnc_sh
- wrapper to try to guess the name:
-#!/bin/sh
-COLUMNS=256
-export COLUMNS
-authfile=`ps wwaux | grep '/X.*-auth' | grep -v grep | sed -e 's/^.*-auth *//'
--e 's/ .*$//' | head -n 1`
-
-if [ -r "$authfile" ]; then
- exec /usr/local/bin/x11vnc -inetd -o /var/log/x11vnc.log -display :0 -a
-uth "$authfile"
-fi
-exit 1
-
- Starting with x11vnc 0.9.3 this can be automated by:
-#!/bin/sh
-exec /usr/local/bin/x11vnc -inetd -o /var/log/x11vnc.log -find -env FD_XDM=1
-
-
- Q-61: Can I have x11vnc advertise its VNC service and port via mDNS /
- Zeroconf (e.g. Avahi) so VNC viewers on the local network can detect
- it automatically?
-
- Yes, as of Feb/2007 x11vnc supports mDNS / Zeroconf advertising of its
- service via the Avahi client library. Use the option -avahi (same as
- -mdns or -zeroconf) to enable it. Depending on your setup you may need
- to install Avahi (including the development/build packages), enable
- the server: avahi-daemon and avahi-dnsconfd, and possibly open up UDP
- port 5353 on your firewall.
-
- If the Avahi client library or build environment is not available at
- build-time, then at run-time x11vnc will try to look for external
- helper programs, avahi-browse(1) or dns-sd(1), to do the work.
-
- The service was tested with Chicken of the VNC ("Use Bonjour"
- selected) on a Mac on the same network and the service was noted and
- listed in the servers list. Clicking on it and then "Connect"
- connected automatically w/o having to enter any hostnames or port
- numbers.
-
- It appears SuSE 10.1 comes with avahi (or you can add packages, e.g.
- avahi-0.6.5-27) but not the development package (you can use the
- OpenSuSE avahi-devel rpm.) Unfortunately, you may need to disable
- another Zeroconf daemon "/etc/init.d/mdnsd stop", before doing
- "/etc/init.d/avahi-daemon start" and "/etc/init.d/avahi-dnsconfd
- start". We also had to comment out the browse-domains line in
- /etc/avahi/avahi-daemon.conf. Hopefully there is "LessConf" to do on
- other distros/OS's...
-
-
- Q-62: Can I have x11vnc allow a user to log in with her UNIX username
- and password and then have it find her X session display on that
- machine and then attach to it? How about starting an X session if one
- cannot be found?
-
- The easiest way to do this is via inetd(8) using the -unixpw and
- -display WAIT options. The reason inetd(8) makes this easier is that
- it starts a new x11vnc process for each new user connection. Otherwise
- a wrapper would have to listen for connections and spawn new x11vnc's
- (see this example and also the -loopbg option.) inetd(8) is not
- required for this, but it makes some aspects more general.
-
- Also with inetd(8) users always connect to a fixed VNC display, say
- hostname:0, and do not need to memorize a special VNC display number
- just for their personal use, etc.
-
- Update: Use the -find, -create, -svc, and -xdmsvc options that are
- shorthand for common FINDCREATEDISPLAY usage modes (e.g. terminal
- services) described below. (i.e. simply use "-svc" instead of the
- cumbersome "-display WAIT:cmd=FINDCREATEDISPLAY-Xvfb -unixpw -users
- unixpw= -ssl SAVE")
-
- The -display WAIT option makes x11vnc wait until a VNC viewer is
- connected before attaching to the X display.
-
- Additionally it can be used to run an external command that returns
- the DISPLAY and XAUTHORITY data. We provide some useful builtin ones
- (FINDDISPLAY and FINDCREATEDISPLAY below), but in principle one could
- supply his own script: "-display WAIT:cmd=/path/to/find_display" where
- the script find_display might look something like this.
-
- A default script somewhat like the above is used under "-display
- WAIT:cmd=FINDDISPLAY" (same as -find) The format for any such command
- is that it returns DISPLAY=:disp as the first line and any remaining
- lines are either XAUTHORITY=file or raw xauth data (the above example
- does the latter.) If applicable (-unixpw mode), the program is run as
- the Unix user name who logged in.
-
- On Linux if the virtual terminal is known the program appends ",VT=n"
- to the DISPLAY line; a chvt n will be attempted automatically. Or if
- only the X server process ID is known it appends ",XPID=n" (a chvt
- will be attempted by x11vnc.)
-
- Tip: Note that the -find option is an alias for "-display
- WAIT:cmd=FINDDISPLAY". Use it!
-
- The -unixpw option allows UNIX password logins. It conveniently knows
- the Unix username whose X display should be found. Here are a couple
- /etc/inetd.conf examples of this usage:
-5900 stream tcp nowait nobody /usr/sbin/tcpd /usr/local/bin/x11vnc -inetd
--unixpw \
- -find -o /var/log/x11vnc.log -ssl SAVE -ssldir /usr/local/certs
-5900 stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/x11vnc -inetd
--unixpw \
- -find -o /var/log/x11vnc.log -ssl SAVE -users unixpw=
-
- Note we have used the -find alias and the very long lines have been
- split. An alternative is to use a wrapper script, e.g.
- /usr/local/bin/x11vnc.sh that has all of the options. (see also the
- -svc alias.)
-
- In the first inetd line x11vnc is run as user "nobody" and stays user
- nobody during the whole session. The permissions of the log files and
- certs directory will need to be set up to allow "nobody" to use them.
-
- In the second one x11vnc is run as root and switches to the user that
- logs in due to the "-users unixpw=" option.
-
- Note that SSL is required for this mode because otherwise the Unix
- password would be passed in clear text over the network. In general
- -unixpw is not required for this sort of scheme, but it is convenient
- because it determines exactly who the Unix user is whose display
- should be sought. Otherwise the find_display script would have to use
- some method to work out DISPLAY, XAUTHORITY, etc (perhaps you use
- multiple inetd ports and hardwire usernames for different ports.)
-
- If you really want to disable the SSL or SSH -localhost constraints
- (this is not recommended unless you really know what you are doing:
- Unix passwords sent in clear text is a very bad idea...) read the
- -unixpw documentation.
-
- A inetd(8) scheme for a fixed user that doesn't use SSL or unix
- passwds could be:
- /usr/local/bin/x11vnc -inetd -users =fred -find -rfbauth /home/fred/.vnc/pass
-wd -o /var/log/x11vnc.log
-
- The "-users =fred" option will cause x11vnc to switch to user fred and
- then find his X display. The VNC password (-rfbauth) as opposed to
- Unix password (-unixpw) is used to authenticate the VNC client.
-
- Similar looking commands to the above examples can be run directly and
- do not use inetd (just remove the -inetd option and run from the
- cmdline, etc.)
-
-
- X Session Creation: An added (Nov/2006) extension to FINDDISPLAY is
- FINDCREATEDISPLAY where if it does not find an X display via the
- FINDDISPLAY method it will create an X server session for the user
- (i.e. desktop/terminal server.) This is the only time x11vnc actually
- tries to start up an X server (normally it just attaches to an
- existing one.)
-
- For virtual sessions you will need to install the Xvfb program (e.g.
- apt-get install xvfb) or our Xdummy program (see below.)
-
- By default it will only try to start up virtual (non-hardware) X
- servers: first Xvfb and if that is not available then Xdummy (included
- in the x11vnc source code.) Note that Xdummy only works on Linux
- whereas Xvfb works just about everywhere (and in some situations
- Xdummy must be run as root.) An advantage of Xdummy over Xvfb is that
- Xdummy supports RANDR dynamic screen resizing, which can be handy if
- the user accesses the desktop from different sized screens (e.g.
- workstation and laptop.)
-
- So an inetd(8) example might look like:
-5900 stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/x11vnc -inetd \
- -o /var/log/x11vnc.log -http -prog /usr/local/bin/x11vnc \
- -ssl SAVE -unixpw -users unixpw= -display WAIT:cmd=FINDCREATEDISPLAY
-
- Where the very long lines have been split. See below where that long
- and cumbersome last line is replaced by the -svc alias.
-
- The above mode will allow direct SSL (e.g. ss_vncviewer or SSVNC)
- access and also Java Web browers access via: https://hostname:5900/.
-
- Tip: Note that the -create option is an alias for "-display
- WAIT:cmd=FINDCREATEDISPLAY-Xvfb".
-
- Tip: Note that -svc is a short hand for the long "-ssl SAVE -unixpw
- -users unixpw= -display WAIT:cmd=FINDCREATEDISPLAY" part. Unlike
- -create, this alias also sets up SSL encryption and Unix password
- login.
-
- The above inetd example then simplifies to:
-5900 stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/x11vnc -inetd \
- -o /var/log/x11vnc.log -http -prog /usr/local/bin/x11vnc \
- -svc
-
- Tip: In addition to the usual unixpw parameters, inside the VNC viewer
- the user can specify after his username (following a ":" see -display
- WAIT for details) for FINDCREATEDISPLAY they can add "geom=WxH" or
- "geom=WxHxD" to specify the width, height, and optionally the color
- depth. E.g. "fred:geom=800x600" at the login: prompt. Also if the env.
- var X11VNC_CREATE_GEOM is set to the desired WxH or WxHxD that will be
- used by x11vnc.
-
- You can set the env. var X11VNC_SKIP_DISPLAY to a comma separated list
- of displays to ignore in the FINDDISPLAY process (to force creation of
- new displays in some cases.) The user logging in via the vncviewer can
- also set this via username:nodisplay=...)
-
- If you do not plan on using the Java Web browser applet you can remove
- the -http (and -prog) option since this will speed up logging-in by a
- few seconds (x11vnc will not have to wait to see if a connection is
- HTTPS or VNC.)
-
- For reference, xinetd format in the file, say, /etc/xinetd.d/x11vnc:
-service x11vnc
-{
- type = UNLISTED
- port = 5900
- socket_type = stream
- protocol = tcp
- wait = no
- user = root
- server = /usr/local/bin/x11vnc
- server_args = -inetd -o /var/log/x11vnc.log -http -prog /usr/local/
-bin/x11vnc -svc
- disable = no
-}
-
- To print out the script in this case use "-display
- WAIT:cmd=FINDCREATEDISPLAY-print". To change the preference of
- Xservers and which to try list them, e.g.: "-display
- WAIT:cmd=FINDCREATEDISPLAY-X,Xvfb,Xdummy" or use "-create_xsrv
- X,Xvfb,Xdummy". The "X" one means to try to start up a real, hardware
- X server, e.g. startx(1) (if there is already a real X server running
- this may only work on Linux and the chvt program may need to be run to
- switch to the correct Linux virtual terminal.) x11vnc will try to run
- chvt automatically if it can determine which VT should be switched to.
-
- XDM/GDM/KDM Login Greeter Panel: If you want to present the user with
- a xdm/gdm/kdm display manager "greeter" login you can use Xvfb.xdmcp
- instead of Xvfb, etc in the above list. However, you need to configure
- xdm/gdm/kdm to accept localhost XDMCP messages, this can be done by
- (from -help output):
- If you want the FINDCREATEDISPLAY session to contact an XDMCP login
- manager (xdm/gdm/kdm) on the same machine, then use "Xvfb.xdmcp"
- instead of "Xvfb", etc. The user will have to supply his username
- and password one more time (but he gets to select his desktop
- type so that can be useful.) For this to work, you will need to
- enable localhost XDMCP (udp port 177) for the display manager.
- This seems to be:
-
- for gdm in gdm.conf: Enable=true in section [xdmcp]
- for kdm in kdmrc: Enable=true in section [Xdmcp]
- for xdm in xdm-config: DisplayManager.requestPort: 177
-
- Unless you are also providing XDMCP service to xterminals or other
- machines, make sure that the host access list only allows local
- connections (the name of this file is often Xaccess and it is usually
- setup by default to do just that.) Nowadays, host level firewalling
- will also typically block UDP (port 177 for XDMCP) by default
- effectively limiting the UDP connections to localhost.
-
- Tip: Note that -xdmsvc is a short hand alias for the long "-ssl SAVE
- -unixpw -users unixpw= -display
- WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp". So we simply use:
-service x11vnc
-{
- type = UNLISTED
- port = 5900
- socket_type = stream
- protocol = tcp
- wait = no
- user = root
- server = /usr/local/bin/x11vnc
- server_args = -inetd -o /var/log/x11vnc.log -xdmsvc
- disable = no
-}
-
- (Note: use "-svc" instead of "-xdmsvc" for no XDMCP login greeter.)
-
-
- Local access (VNC Server and VNC Viewer on the same machine): To
- access your virtual X display session locally (i.e. while sitting at
- the same machine it is running on) one can perhaps have something like
- this in their $HOME/.xinitrc
-#!/bin/sh
-x11vnc -create -rfbport 5905 -env WAITBG=1
-vncviewer -geometry +0+0 -encodings raw -passwd $HOME/.vnc/passwd localhost:5
-
- You may not need the -passwd. Recent RealVNC viewers might be this:
-#!/bin/sh
-x11vnc -create -rfbport 5905 -env WAITBG=1
-vncviewer -FullScreen -PreferredEncoding raw -passwd $HOME/.vnc/passwd localhos
-t:5
-
- This way a bare X server is run with no window manager or desktop; it
- simply runs only the VNC Viewer on the real X server. The Viewer then
- draws the virtual X session on to the real one. On your system it
- might not be $HOME/.xinitrc, but rather .xsession, .Xclients, or
- something else. You will need to figure out what it is for your system
- and configuration.
-
- There may be a problem if the resolution (WxH) of the virtual X
- display does not match that of the physical X display.
-
- If you do not want to or cannot figure out the X startup script name
- (.xinitrc, etc) you could save the above commands to a shell script,
- say "vnclocal", and the log in via the normal KDM or GDM greeter
- program using the "Failsafe" option. Then in the lone xterm that comes
- up type "vnclocal" to connect to your virtual X display via x11vnc and
- vncviewer.
-
- _________________________________________________________________
-
- Summary: The "-display WAIT:cmd=FINDCREATEDISPLAY" scheme can be used
- to provide a "desktop service" (i.e. terminal service) on the server
- machine: you always get some desktop there, either a real hardware X
- server or a virtual one (depending on how you set things up.)
-
- So it provides simple "terminal services" based on Unix username and
- password. The created X server sessions (virtual or real hardware)
- will remain running after you disconnect the VNC viewer and will be
- found again on reconnecting via VNC and logging in. To terminate them
- use the normal way to Exit/LogOut from inside your X session. The user
- does not have to memorize which VNC display number is his. They all go
- the same one (e.g. hostname:0) and it switches based on username.
-
-
- Q-63: Can I have x11vnc restart itself after it terminates?
-
- One could do this in a shell script, but now there is an option -loop
- that makes it easier. Of course when x11vnc restarts it needs to have
- permissions to connect to the (potentially new) X display. This mode
- could be useful if the X server restarts often. Use e.g. "-loop5000"
- to sleep 5000 ms between restarts. Also "-loop2000,5" to sleep 2000 ms
- and only restart 5 times.
-
- One can also use the -loopbg to emulate inetd(8) to some degree, where
- each connected process runs in the background. It could be combined,
- say, with the -svc option to provide simple terminal services without
- using inetd(8).
-
-
- Q-64: How do I make x11vnc work with the Java VNC viewer applet in a
- web browser?
-
- To have x11vnc serve up a Java VNC viewer applet to any web browsers
- that connect to it, run x11vnc with this option:
- -httpdir /path/to/the/java/classes/dir
-
- (this directory will contain the files index.vnc and, for example,
- VncViewer.jar) Note that libvncserver contains the TightVNC Java
- classes jar file for your convenience. (it is the file
- classes/VncViewer.jar in the source tree.)
-
- You will see output something like this:
- 14/05/2004 11:13:56 Autoprobing selected port 5900
- 14/05/2004 11:13:56 Listening for HTTP connections on TCP port 5800
- 14/05/2004 11:13:56 URL http://walnut:5800
- 14/05/2004 11:13:56 screen setup finished.
- 14/05/2004 11:13:56 The VNC desktop is walnut:0
- PORT=5900
-
- then you can connect to that URL with any Java enabled browser. Feel
- free to customize the default index.vnc file in the classes directory.
-
- As of May/2005 the -http option will try to guess where the Java
- classes jar file is by looking in expected locations and ones relative
- to the x11vnc binary.
-
- Also note that if you wanted to, you could also start the Java viewer
- entirely from the viewer-side by having the jar file there and using
- either the java or appletviewer commands to run the program.
- java -cp ./VncViewer.jar VncViewer HOST far-away.east PORT 5900
-
- Proxies: See the discussion here if the web browser must use a web
- proxy to connect to the internet. It is tricky to get Java applets to
- work in this case: a signed applet must be used so it can connect to
- the proxy and ask for the redirection to the VNC server. One way to do
- this is to use the signed SSL one referred to in classes/ssl/proxy.vnc
- and set disableSSL=yes (note that this has no encryption; please use
- SSL or SSH as discuss elsewhere on this page) in the URL or the file.
-
-
- Q-65: Are reverse connections (i.e. the VNC server connecting to the
- VNC viewer) using "vncviewer -listen" and vncconnect(1) supported?
-
- As of Mar/2004 x11vnc supports reverse connections. On Unix one starts
- the VNC viewer in listen mode: "vncviewer -listen" (see your
- documentation for Windows, etc), and then starts up x11vnc with the
- -connect option. To connect immediately at x11vnc startup time use the
- "-connect host:port" option (use commas for a list of hosts to connect
- to.) The ":port" is optional (default is VNC listening port is 5500.)
-
- If a file is specified instead: -connect /path/to/some/file then that
- file is checked periodically (about once a second) for new hosts to
- connect to.
-
- The -remote control option (aka -R) can also be used to do this during
- an active x11vnc session, e.g.:
-x11vnc -display :0 -R connect:hostname.domain
-
- Use the "-connect_or_exit" option to have x11vnc exit if the reverse
- connection fails. Also, note the "-rfbport 0" option disables TCP
- listening for connections (potentially useful for reverse connection
- mode, assuming you do not want any "forward" connections.)
-
- Note that as of Mar/2006 x11vnc requires password authentication for
- reverse connections as well as for forward ones (assuming password
- auth has been enabled, e.g. via -rfbauth, -passwdfile, etc.) Many VNC
- servers do not require any password for reverse connections. To regain
- the old behavior supply this option "-env
- X11VNC_REVERSE_CONNECTION_NO_AUTH=1" to x11vnc.
-
- Vncconnect command: To use the vncconnect(1) program (from the core
- VNC package at www.realvnc.com) specify the -vncconnect option to
- x11vnc (Note: as of Dec/2004 -vncconnect is now the default.)
- vncconnect(1) must be pointed to the same X11 DISPLAY as x11vnc (since
- it uses X properties to communicate with x11vnc.) If you do not have
- or do not want to get the vncconnect(1) program, the following script
- (named "Vncconnect") may work if your xprop(1) supports the -set
- option:
-#!/bin/sh
-# usage: Vncconnect <host>
-# Vncconnect <host:port>
-# note: not all xprop(1) support -set.
-#
-xprop -root -f VNC_CONNECT 8s -set VNC_CONNECT "$1"
-
-
- Q-66: Can reverse connections be made to go through a Web or SOCKS
- proxy or SSH?
-
- Yes, as of Oct/2007 x11vnc supports reverse connections through
- proxies: use the "-proxy host:port" option. The default is to assume
- the proxy is a Web proxy. Note that most Web proxies only allow proxy
- destination connections to ports 443 (HTTPS) and 563 (SNEWS) and so
- this might not be too useful unless the proxy has been modified
- (AllowCONNECT apache setting) or the VNC viewer listens on one of
- those ports (or the router does a port redir.) A web proxy may also be
- specified via "-proxy http://host:port"
-
- For SOCKS4 and SOCKS4a proxies use this format "-proxy
- socks://host:port". If the reverse connection hostname is a numerical
- IP or "localhost" then SOCKS4 (no host lookup) is used, otherwise
- SOCKS4a will be used. For SOCKS5 (proxy will do lookup and many other
- things) use "-proxy socks5://host:port". Note that the SSH builtin
- SOCKS proxy "ssh -D port" only does SOCKS4 or SOCKS5, so use socks5://
- for a ssh -D proxy.
-
- The proxying works for both SSL encrypted and normal reverse
- connections.
-
- An experimental mode is "-proxy http://host:port/..." where the URL
- (e.g. a CGI script) is retrieved via the GET method. See -proxy for
- more info.
-
- Another experimental mode is "-proxy ssh://user@host" in which case a
- SSH tunnel is used for the proxying. See -proxy for more info.
-
- Up to 3 proxies may be chained together by listing them by commas
- e.g.: "-proxy http://host1:port1,socks5://host2:port2" in case one
- needs to ricochet off of several machines to ultimately reach the
- listening viewer.
-
-
- Q-67: Can x11vnc provide a multi-user desktop web login service as an
- Apache CGI or PHP script?
- Yes. See the example script desktop.cgi for ideas. It is in the source
- tree in the directory x11vnc/misc. It serves x11vnc's SSL enabled Java
- Applet to the web browser with the correct connection information for
- the user's virtual desktop (an Xvfb session via -create; be sure to
- add the Xvfb package.) HTTPS/SSL enabled Apache should be used to
- serve the script to avoid unix and vnc passwords from being sent in
- cleartext and sniffed.
-
- By default it uses a separate VNC port for each user desktop (either
- by autoprobing in a range of ports or using a port based on the userid
- number.) The web server's firewall must allow incoming connections to
- these ports.
-
- It is somewhat difficult to do all of this with x11vnc listening on a
- single port, however there is also a 'fixed port' scheme described in
- the script based on -loopbg that works fairly well (but more
- experience is needed to see what problems contention for the same port
- causes; however at worst one user may need to re-login.)
-
- There is also an optional 'port redirection' mode for desktop.cgi that
- allows redirection to other machines inside the firewall already
- running SSL enabled VNC servers. This provides much of the
- functionality as the SSL Portal and is easier to set up.
-
-
- Q-68: Can I use x11vnc as a replacement for Xvnc? (i.e. not for a real
- display, but for a virtual one I keep around.)
-
- You can, but you would not be doing this for performance reasons (for
- virtual X sessions via VNC, Xvnc should give the fastest response.)
- You may want to do this because Xvnc is buggy and crashes, does not
- support an X server extension you desire, or you want to take
- advantage of one of x11vnc's unending number of options and features.
-
- One way to achieve this is to have a Xvfb(1) virtual framebuffer X
- server running in the background and have x11vnc attached to it.
- Another method, faster and more accurate, is to use the "dummy" Device
- Driver in XFree86/Xorg (see below.)
-
- For these virtual sessions you will need to install the Xvfb program
- (e.g. apt-get install xvfb) or our Xdummy program (see below.)
-
- In either case, one can view this desktop both remotely and also
- locally using vncviewer. Make sure vncviewer's "-encodings raw" is in
- effect for local viewing (compression seems to slow things down
- locally.) For local viewing you set up a "bare" window manager that
- just starts up vncviewer and nothing else (See how below.)
-
- Here is one way to start up Xvfb:
- xinit -- /usr/bin/Xvfb :1 -cc 4 -screen 0 1024x768x16
-
- This starts up a 16bpp virtual display. To export it via VNC use
- x11vnc -display :1 ...
-
- Then have the remote vncviewer attach to x11vnc's VNC display (e.g. :0
- which is port 5900.)
-
- The "-cc 4" Xvfb option is to force it to use a TrueColor visual
- instead of DirectColor (this works around a recent bug in the Xorg
- Xvfb server.)
-
- One good thing about Xvfb is that the virtual framebuffer exists in
- main memory (rather than in the video hardware), and so x11vnc can
- "screen scrape" it very efficiently (more than, say, 100X faster than
- normal video hardware.)
-
- Update Nov/2006: See the FINDCREATEDISPLAY discussion of the "-display
- WAIT:cmd=FINDDISPLAY" option where virtual (Xvfb or Xdummy, or even
- real ones by changing an option) X servers are started automatically
- for new users connecting. This provides a "desktop service" for the
- machine. You either get your real X session or your virtual
- (Xvfb/Xdummy) one whenever you connect to the machine (inetd(8) is a
- nice way to provide this service.) The -find, -create, -svc, and
- -xdmsvc aliases can also come in handy here.
-
- There are some annoyances WRT Xvfb however. The default keyboard
- mapping seems to be very poor. One should run x11vnc with -add_keysyms
- option to have keysyms added automatically. Also, to add the Shift_R
- and Control_R modifiers something like this is needed:
-#!/bin/sh
-xmodmap -e "keycode any = Shift_R"
-xmodmap -e "add Shift = Shift_L Shift_R"
-xmodmap -e "keycode any = Control_R"
-xmodmap -e "add Control = Control_L Control_R"
-xmodmap -e "keycode any = Alt_L"
-xmodmap -e "keycode any = Alt_R"
-xmodmap -e "keycode any = Meta_L"
-xmodmap -e "add Mod1 = Alt_L Alt_R Meta_L"
-
- (note: these are applied automatically in the FINDCREATEDISPLAY mode
- of x11vnc.) Perhaps the Xvfb options -xkbdb or -xkbmap could be used
- to get a better default keyboard mapping...
-
- Dummy Driver: A user points out a faster and more accurate method is
- to use the "dummy" Device Driver of XFree86/Xorg instead of Xvfb. He
- uses this to create a persistent and resizable desktop accessible from
- anywhere. In the Device Section of the config file set Driver "dummy".
- You may also need to set VideoRam NNN to be large enough to hold the
- framebuffer. The framebuffer is kept in main memory like Xvfb except
- that the server code is closely correlated with the real XFree86/Xorg
- Xserver unlike Xvfb.
-
- The main drawback to this method (besides requiring extra
- configuration and possibly root permission) is that it also does the
- Linux Virtual Console/Terminal (VC/VT) switching even though it does
- not need to (since it doesn't use a real framebuffer.) There are some
- "dual headed" (actually multi-headed/multi-user) patches to the X
- server that turn off the VT usage in the X server. Update: As of
- Jul/2005 we have an LD_PRELOAD script Xdummy that allows you to use a
- stock (i.e. unpatched) Xorg or XFree86 server with the "dummy" driver
- and not have any VT switching problems! An advantage of Xdummy over
- Xvfb is that Xdummy supports RANDR dynamic screen resizing.
-
- The standard way to start the "dummy" driver would be:
-startx -- :1 -config /etc/X11/xorg.conf.dummy
-
- where the file /etc/X11/xorg.conf.dummy has its Device Section
- modified as described above. To use the LD_PRELOAD wrapper script:
-startx -- /path/to/Xdummy :1
-
- An xdm(1) example is also provided.
-
- In general, one can use these sorts of schemes to use x11vnc to export
- other virtual X sessions, say Xnest or even Xvnc itself (useful for
- testing x11vnc.)
-
- Local access (VNC Server and VNC Viewer on the same machine): You use
- a VNC viewer to access the display remotely; to access your virtual X
- display locally (i.e. while sitting at the same machine it is running
- on) one can perhaps have something like this in their $HOME/.xinitrc
-#!/bin/sh
-x11vnc -display :5 -rfbport 5905 -bg
-vncviewer -geometry +0+0 -encodings raw -passwd $HOME/.vnc/passwd localhost:5
-
- The display numbers (VNC and X) will likely be different (you could
- also try -find), and you may not need the -passwd. Recent RealVNC
- viewers might be this:
-#!/bin/sh
-x11vnc -display :5 -rfbport 5905 -bg
-vncviewer -FullScreen -PreferredEncoding raw -passwd $HOME/.vnc/passwd localhos
-t:5
-
- This way a bare X server is run with no window manager or desktop; it
- simply runs only the VNC Viewer on the real X server. The Viewer then
- draws the virtual X session on to the real one. On your system it
- might not be $HOME/.xinitrc, but rather .xsession, .Xclients, or
- something else. You will need to figure out what it is for your system
- and configuration.
-
-
- XDM/GDM/KDM One-Shot X sessions: For the general replacement of Xvnc
- by Xvfb+x11vnc, one user describes a similar setup he created where
- the X sessions are one-shot's (destroyed after the vncviewer
- disconnects) and it uses the XDM/GDM/KDM login greeter here.
-
-
- Q-69: How can I use x11vnc on "headless" machines? Why might I want
- to?
-
- An interesting application of x11vnc is to let it export displays of
- "headless" machines. For example, you may have some lab or server
- machines with no keyboard, mouse, or monitor, but each one still has a
- video card. One can use x11vnc to provide a simple "desktop service"
- from these server machines.
-
- An X server can be started on the headless machine (sometimes this
- requires configuring the X server to not fail if it cannot detect a
- keyboard or mouse, see the next paragraph.) Then you can export that X
- display via x11vnc (e.g. see this FAQ) and access it from anywhere on
- the network via a VNC viewer.
-
- Some tips on getting X servers to start on machines without keyboard
- or mouse: For XFree86/Xorg the Option "AllowMouseOpenFail" "true"
- "ServerFlags" config file option is useful. On Solaris Xsun the
- +nkeyboard and +nmouse options are useful (put them in the server
- command line args in /etc/dt/config/Xservers.) There are patches
- available for Xsun at lease back to Solaris 8 that support this. See
- Xserver(1) for more info.
-
- Although this usage may sound strange it can be quite useful for a GUI
- (or other) testing or QA setups: the engineers do not need to walk to
- lab machines running different hardware, OS's, versions, etc (or have
- many different machines in their office.) They just connect to the
- various test machines over the network via VNC. The advantage to
- testing this way instead of using Xvnc or even Xvfb is that the test
- is done using the real X server, fonts, video hardware, etc. that will
- be used in the field.
-
- One can imagine a single server machine crammed with as many video
- cards as it can hold to provide multiple simultaneous access or
- testing on different kinds of video hardware.
-
- See also the FINDCREATEDISPLAY discussion of the "-display
- WAIT:cmd=FINDDISPLAY" option where virtual Xvfb or Xdummy, or real X
- servers are started automatically for new users connecting. The -find,
- -create, -svc, and -xdmsvc aliases can also come in handy here.
-
- [Resource Usage and Performance]
-
- Q-70: I have lots of memory, but why does x11vnc fail with shmget:
- No space left on device or Minor opcode of failed request: 1
- (X_ShmAttach)?
-
- It is not a matter of free memory, but rather free shared memory (shm)
- slots, also known as shm segments. This often occurs on a public
- Solaris machine using the default of only 100 slots. You (or the owner
- or root) can clean them out with ipcrm(1). x11vnc tries hard to
- release its slots, but it, and other programs, are not always able to
- (e.g. if kill -9'd.)
-
- Sometimes x11vnc will notice the problem with shm segments and tries
- to get by with fewer, only giving a warning like this:
- 19/03/2004 10:10:58 shmat(tile_row) failed.
- shmat: Too many open files
- 19/03/2004 10:10:58 error creating tile-row shm for len=4
- 19/03/2004 10:10:58 reverting to single_copytile mode
-
- Here is a shell script shm_clear to list and prompt for removal of
- your unattached shm segments (attached ones are skipped.) I use it
- while debugging x11vnc (I use "shm_clear -y" to assume "yes" for each
- prompt.) If x11vnc is regularly not cleaning up its shm segments,
- please contact me so we can work to improve the situation.
-
- Longer term, on Solaris you can put something like this in
- /etc/system:
- set shmsys:shminfo_shmmax = 0x2000000
- set shmsys:shminfo_shmmni = 0x1000
-
- to sweep the problem under the rug (4096 slots.) On Linux, examine
- /proc/sys/kernel/shmmni; you can modify the value by writing to that
- file.
-
- Things are even more tight on Solaris 8 and earlier, there is a
- default maximum number of shm segments per process of 6. The error is
- the X server (not x11vnc) being unable to attach to the segments, and
- looks something like this:
- 30/04/2004 14:04:26 Got connection from client 192.168.1.23
- 30/04/2004 14:04:26 other clients:
- X Error of failed request: BadAccess (attempt to access private resource den
-ied)
- Major opcode of failed request: 131 (MIT-SHM)
- Minor opcode of failed request: 1 (X_ShmAttach)
- Serial number of failed request: 14
- Current serial number in output stream: 17
-
- This tight limit on Solaris 8 can be increased via:
- set shmsys:shminfo_shmseg = 100
-
- in /etc/system. See the next paragraph for more workarounds.
-
- To minimize the number of shm segments used by x11vnc try using the
- -onetile option (corresponds to only 3 shm segments used, and adding
- -fs 1.0 knocks it down to 2.) If you are having much trouble with shm
- segments, consider disabling shm completely via the -noshm option.
- Performance will be somewhat degraded but when done over local machine
- sockets it should be acceptable (see an earlier question discussing
- -noshm.)
-
-
- Q-71: How can I make x11vnc use less system resources?
-
- The -nap (now on by default; use -nonap to disable) and "-wait n"
- (where n is the sleep between polls in milliseconds, the default is 30
- or so) option are good places to start. In addition, something like
- "-sb 15" will cause x11vnc to go into a deep-sleep mode after 15
- seconds of no activity (instead of the default 60.)
-
- Reducing the X server bits per pixel depth (e.g. to 16bpp or even
- 8bpp) will further decrease memory I/O and network I/O. The ShadowFB X
- server setting will make x11vnc's screen polling less severe. Using
- the -onetile option will use less memory and use fewer shared memory
- slots (add -fs 1.0 for one less slot.)
-
-
- Q-72: How can I make x11vnc use MORE system resources?
-
- You can try -threads (note this mode can be unstable and/or crash; and
- as of May/2008 is strongly discouraged, see the option description) or
- dial down the wait time (e.g. -wait 1) and possibly dial down -defer
- as well. Note that if you try to increase the "frame rate" too much
- you can bog down the server end with the extra work it needs to do
- compressing the framebuffer data, etc.
-
- That said, it is possible to "stream" video via x11vnc if the video
- window is small enough. E.g. a 256x192 xawtv TV capture window (using
- the x11vnc -id option) can be streamed over a LAN or wireless at a
- reasonable frame rate. If the graphics card's framebuffer read rate is
- faster than normal then the video window size and frame rate can be
- much higher. The use of TurboVNC and/or TurboJPEG can make the frame
- rate somewhat higher still (but most of this hinges on the graphics
- card's read rate.)
-
-
- Q-73: I use x11vnc over a slow link with high latency (e.g. dialup
- modem or broadband), is there anything I can do to speed things up?
-
- Some things you might want to experiment with (many of which will help
- performance on faster links as well):
-
- X server/session parameters:
- * Configure the X server bits per pixel to be 16bpp or even 8bpp.
- (reduces amount of data needed to be polled, compressed, and sent)
- * Use a smaller desktop size (e.g. 1024x768 instead of 1280x1024)
- * Make sure the desktop background is a solid color (the background
- is resent every time it is re-exposed.) Consider using the -solid
- [color] option to try to do this automatically.
- * Configure your window manager or desktop "theme" to not use fancy
- images, shading, and gradients for the window decorations, etc.
- Disable window animations, etc. Maybe your desktop has a "low
- bandwidth" theme you can easily switch into and out of. Also in
- Firefox disable eye-candy, e.g.: Edit -> Preferences -> Advanced
- -> Use Smooth Scrolling (deselect it.)
- * Avoid small scrolls of large windows using the Arrow keys or
- scrollbar. Try to use PageUp/PageDown instead. (not so much of a
- problem in x11vnc 0.7.2 if -scrollcopyrect is active and detecting
- scrolls for the application.)
- * If the -wireframe option is not available (earlier than x11vnc
- 0.7.2 or you have disabled it via -nowireframe) then Disable
- Opaque Moves and Resizes in the window manager/desktop.
- * However if -wireframe is active (on by default in x11vnc 0.7.2)
- then you should Enable Opaque Moves and Resizes in the window
- manager! This seems counter-intuitive, but because x11vnc detects
- the move/resize events early there is a huge speedup over a slow
- link when Opaque Moves and Resizes are enabled. (e.g. CopyRect
- encoding will be used.)
- * Turn off Anti-aliased fonts on your system, web browser, terminal
- windows, etc. AA fonts do not compress as well as traditional
- fonts (sometimes 10X less.)
- * On Firefox/Mozilla (and anything else) turn off "Smooth Scroll"
- animations. In Firefox put in the URL "about:config" and set
- general.smoothScroll to false.
- * On Xorg/XFree86 turn on the Shadow Framebuffer to speed up
- reading. (Option "ShadowFB" "true" in the Device section of
- /etc/X11/XF86Config) This disables 2D acceleration on the physical
- display and so may not be worth it (if you play games, etc), but
- could be of use in some situations. Note: If the network link is
- very slow, this speedup may not be noticed.
-
- VNC viewer parameters:
- * Use a TightVNC enabled viewer! (Actually, RealVNC 4.x viewer with
- ZRLE encoding is not too bad either; some claim it is faster.)
- * Make sure the tight (or zrle) encoding is being used (look at
- vncviewer and x11vnc outputs)
- * Request 8 bits per pixel using -bgr233 (up to 4X speedup over
- depth 24 TrueColor (32bpp), but colors will be off)
- * RealVNC 4.x viewer has some extremely low color modes (only 64 and
- even 8 colors.) SSVNC does too. The colors are poor, but it is
- usually noticeably faster than bgr233 (256 colors.)
- * Try increasing the TightVNC -compresslevel (compresses more on
- server side before sending, but uses more CPU)
- * Try reducing the TightVNC -quality (increases JPEG compression,
- but is lossy with painting artifacts)
- * Try other VNC encodings via -encodings (tight may be the fastest,
- but you should compare it to zrle and maybe some of the others)
- * On the machine where vncviewer is run, make sure Backing Store is
- enabled (Xorg/XFree86 disables it by default causing re-exposures
- of vncviewer to be very slow) Option "backingstore" in config
- file.
-
- x11vnc parameters:
- * Make sure the -wireframe option is active (it should be on by
- default) and you have Opaque Moves/Resizes Enabled in the window
- manager.
- * Make sure the -scrollcopyrect option is active (it should be on by
- default.) This detects scrolls in many (but not all) applications
- an applies the CopyRect encoding for a big speedup.
- * Enforce a solid background when VNC viewers are connected via
- -solid
- * Try x11vnc's client-side caching client-side caching scheme:
- -ncache
- * Specify -speeds modem to force the wireframe and scrollcopyrect
- heuristic parameters (and any future ones) to those of a dialup
- modem connection (or supply the rd,bw,lat numerical values that
- characterize your link.)
- * If wireframe and scrollcopyrect aren't working, try using the more
- drastic -nodragging (no screen updates when dragging mouse, but
- sometimes you miss visual feedback)
- * Set -fs 1.0 (disables fullscreen updates)
- * Try increasing -wait or -defer (reduces the maximum "frame rate",
- but won't help much for large screen changes)
- * Try the -progressive pixelheight mode with the block pixelheight
- 100 or so (delays sending vertical blocks since they may change
- while viewer is receiving earlier ones)
- * If you just want to watch one (simple) window use -id or -appshare
- (cuts down extraneous polling and updates, but can be buggy or
- insufficient)
- * Set -nosel (disables all clipboard selection exchange)
- * Use -nocursor and -nocursorpos (repainting the remote cursor
- position and shape takes resources and round trips)
- * On very slow links (e.g. <= 28.8) you may need to increase the
- -readtimeout n setting if it sometimes takes more than 20sec to
- paint the full screen, etc.
- * Do not use -fixscreen to automatically refresh the whole screen,
- tap three Alt_L's then the screen has painting errors (rare
- problem.)
-
-
- Example for the KDE desktop:
-
- Launch the "KDE Control Center" utility. Sometimes this is called
- "Personal Settings".
-
- Select "Desktop".
-
- Then Select "Window Behavior". In the "Moving" Tab set these:
- * YES - Display content in moving windows
- * YES - Display content in resizing windows
- * NO - Display window geometry when moving or resizing
- * NO - Animate minimize and restore
-
- In the "Translucency" Tab set:
- * NO - Use translucency/shadows
-
- Next hit "Back" and then select "Panels".
-
- In the "Appearance" Tab set:
- * NO - Enable icon mouseover effects
- * NO - Enable transparency
-
- Now go all the way back up to the top and Select "Appearance &
- Themes".
-
- Select "Background" and set:
- * YES - No picture
- * Colors: Single Color
-
- Select "Fonts" and disable anti-aliased fonts if you are bold enough.
-
- Select "Launch Feedback" and set:
- * Busy Cursor: No Busy Cursor
- * NO - Enable taskbar notification
-
- Select "Screen Saver" and set:
- * Screen Saver: Blank Screen
-
- Select "Style" and in the "Effects" Tab set:
- * NO - Enable GUI effects
-
-
- Example for the GNOME desktop:
- * TBD.
-
-
- Q-74: Does x11vnc support the X DAMAGE Xserver extension to find
- modified regions of the screen quickly and efficiently?
-
- Yes, as of Mar/2005 x11vnc will use the X DAMAGE extension by default
- if it is available on the display. This requires libXdamage to be
- available in the build environment as well (recent Linux distros and
- Solaris 10 have it.)
-
- The DAMAGE extension enables the X server to report changed regions of
- the screen back to x11vnc. So x11vnc doesn't have to guess where the
- changes are (by polling every pixel of the entire screen every 2-4
- seconds.) The use of X DAMAGE dramatically reduces the load when the
- screen is not changing very much (i.e. most of the time.) It also
- noticeably improves updates, especially for very small changed areas
- (e.g. clock ticking, cursor flashing, typing, etc.)
-
- Note that the DAMAGE extension does not speed up the actual reading of
- pixels from the video card framebuffer memory, by, say, mirroring them
- in main memory. So reading the fb is still painfully slow (e.g.
- 5MB/sec), and so even using X DAMAGE when large changes occur on the
- screen the bulk of the time is still spent retrieving them. Not ideal,
- but use of the ShadowFB XFree86/Xorg option speeds up the reading
- considerably (at the cost of h/w acceleration.)
-
- Unfortunately the current Xorg DAMAGE extension implementation can at
- times be overly conservative and report very large rectangles as
- "damaged" even though only a small portion of the pixels have actually
- been modified. This behavior is often the fault of the window manager
- (e.g. it redraws the entire, unseen, frame window underneath the
- application window when it gains focus), or the application itself
- (e.g. does large, unnecessary repaints.)
-
- To work around this deficiency, x11vnc currently only trusts small
- DAMAGE rectangles to contain real damage. The larger rectangles are
- only used as hints to focus the traditional scanline polling (i.e. if
- a scanline doesn't intersect a recent DAMAGE rectangle, the scan is
- skipped.) You can use the "-xd_area A" option to adjust the size of
- the trusted DAMAGE rectangles. The default is 20000 pixels (e.g. a
- 140x140 square, etc.) Use "-xd_area 0" to disable the cutoff and trust
- all DAMAGE rectangles.
-
- The option "-xd_mem f" may also be of use in tuning the algorithm. To
- disable using DAMAGE entirely use "-noxdamage".
-
-
- Q-75: My OpenGL application shows no screen updates unless I supply
- the -noxdamage option to x11vnc.
- One user reports in his environment (MythTV using the NVIDIA OpenGL
- drivers) he gets no updates after the initial screen is drawn unless
- he uses the "-noxdamage" option.
-
- This seems to be a bug in the X DAMAGE implementation of that driver.
- You may have to use -noxdamage as well. A way to autodetect this will
- be tried, probably the best it will do is automatically stop using X
- DAMAGE.
-
- A developer for MiniMyth reports that the 'alphapulse' tag of the
- theme G.A.N.T. can also cause problems, and should be avoided when
- using VNC.
-
- Update: see this FAQ too.
-
-
- Q-76: When I drag windows around with the mouse or scroll up and down
- things really bog down (unless I do the drag in a single, quick
- motion.) Is there anything to do to improve things?
-
- This problem is primarily due to slow hardware read rates from video
- cards: as you scroll or move a large window around the screen changes
- are much too rapid for x11vnc to keep up them (it can usually only
- read the video card at about 5-10 MB/sec, so it can take a good
- fraction of a second to read the changes induce from moving a large
- window, if this to be done a number of times in succession the window
- or scroll appears to "lurch" forward.) See the description in the
- -pointer_mode option for more info. The next bottleneck is compressing
- all of these changes and sending them out to connected viewers,
- however the VNC protocol is pretty much self-adapting with respect to
- that (updates are only packaged and sent when viewers ask for them.)
-
- As of Jan/2004 there are some improvements to libvncserver. The
- default should now be much better than before and dragging small
- windows around should no longer be a huge pain. If for some reason
- these changes make matters worse, you can go back to the old way via
- the "-pointer_mode 1" option.
-
- Also added was the -nodragging option that disables all screen updates
- while dragging with the mouse (i.e. mouse motion with a button held
- down.) This gives the snappiest response, but might be undesired in
- some circumstances when you want to see the visual feedback while
- dragging (e.g. menu traversal or text selection.)
-
- As of Dec/2004 the -pointer_mode n option was introduced. n=1 is the
- original mode, n=2 an improvement, etc.. See the -pointer_mode n help
- for more info.
-
- Also, in some circumstances the -threads option can improve response
- considerably. Be forewarned that if more than one vncviewer is
- connected at the same time then libvncserver may not be thread safe
- (try to get the viewers to use different VNC encodings, e.g. tight and
- ZRLE.) This option can be unstable and so as of Feb/2008 it is
- disabled by default. Set env. X11VNC_THREADED=1 to re-enable.
-
- As of Apr/2005 two new options (see the wireframe FAQ and
- scrollcopyrect FAQ below) provide schemes to sweep this problem under
- the rug for window moves or resizes and for some (but not all) window
- scrolls. These are the preferred way of avoiding the "lurching"
- problem, contact me if they are not working. Note on SuSE and some
- other distros the RECORD X extension used by scrollcopyrect is not
- enabled by default, turn it on in xorg.conf:
-Section "Module"
- ...
- Load "record"
- ...
-EndSection
-
-
- Q-77: Why not do something like wireframe animations to avoid the
- windows "lurching" when being moved or resized?
-
- Nice idea for a hack! As of Apr/2005 x11vnc by default will apply
- heuristics to try to guess if a window is being (opaquely) moved or
- resized. If such a change is detected framebuffer polling and updates
- will be suspended and only an animated "wireframe" (a rectangle
- outline drawn where the moved/resized window would be) is shown. When
- the window move/resize stops, it returns to normal processing: you
- should only see the window appear in the new position. This spares you
- from interacting with a "lurching" window between all of the
- intermediate steps. BTW the lurching is due to slow video card read
- rates (see here too.) A displacement, even a small one, of a large
- window requires a non-negligible amount of time, a good fraction of a
- second, to read in from the hardware framebuffer.
-
- Note that Opaque Moves/Resizes must be Enabled by your window manager
- for -wireframe to do any good.
-
- The mode is currently on by default because most people are afflicted
- with the problem. It can be disabled with the -nowireframe option (aka
- -nowf.) Why might one want to turn off the wireframing? Since x11vnc
- is merely guessing when windows are being moved/resized, it may guess
- poorly for your window-manager or desktop, or even for the way you
- move the pointer. If your window-manager or desktop already does its
- own wireframing then this mode is a waste of time and could do the
- wrong thing occasionally. There may be other reasons the new mode
- feels unnatural. If you have very expensive video hardware (SGI, well
- now even proprietary Xorg drivers are fast at reading) or are using an
- in-RAM video framebuffer (SunRay, ShadowFB, Xvfb), the read rate from
- that framebuffer may be very fast (100's of MB/sec) and so you don't
- really see much lurching (at least over a fast LAN): opaque moves look
- smooth in x11vnc. Note: ShadowFB is often turned on when you are using
- the vesafb or fbdev XFree86 video driver instead of a native one so
- you might be using it already and not know.
-
- The heuristics used to guess window motion or resizing are simple, but
- are not fool proof: x11vnc is sometimes tricked and so you'll
- occasionally see the lurching opaque move and rarely something even
- worse.
-
- First it assumes that the move/resize will occur with a mouse button
- pressed, held down and dragged (of course this is only mostly true.)
- Next it will only consider a window for wireframing if the mouse
- pointer is initially "close enough" to the edges of the window frame,
- e.g. you have grabbed the title bar or a resizer edge (this
- requirement can be disabled and it also not applied if a modifier key,
- e.g. Alt, is pressed.) If these are true, it will wait an amount of
- time to see if the window starts moving or resizing. If it does, it
- starts drawing the wireframe "outline" of where the window would be.
- When the mouse button is released, or a timeout occurs, it goes back
- to the standard mode to allow the actual framebuffer changes to
- propagate to the viewers.
-
- These parameters can be tweaked:
- * Color/Shade of the wireframe.
- * Linewidth of the outline frame.
- * Cutoff size of windows to not apply wireframing to.
- * Cutoffs for closeness to Top, Bottom, Left, and Right edges of
- window.
- * Modifier keys to enable interior window grabbing.
- * Maximum time to wait for dragging pointer events.
- * Maximum time to wait for the window to start moving/resizing.
- * Maximum time to show a wireframe animation.
- * Minimum time between sending wireframe outlines.
-
- See the "-wireframe tweaks" option for more details. On a slow link,
- e.g. dialup modem, the parameters may be automatically adjusted for
- better response.
-
-
- CopyRect encoding: In addition to the above there is the
- "-wirecopyrect mode" option. It is also on by default. This instructs
- x11vnc to not only show the wireframe animation, but to also instruct
- all connected VNC viewers to locally translate the window image data
- from the original position to the new position on the screen when the
- animation is done. This speedup is the VNC CopyRect encoding: the
- framebuffer update doesn't need to send the actual new image data.
- This is nice in general, and very convenient over a slow link, but
- since it is based on heuristics you may need to disable it with the
- -nowirecopyrect option (aka -nowcr) if it works incorrectly or
- unnaturally for you.
-
- The -wirecopyrect modes are: "never" (same as -nowirecopyrect); "top",
- only apply the CopyRect if the window is appears to be on the top of
- the window stack and is not obstructed by other windows; and "always"
- to always try to apply the CopyRect (obstructed regions are usually
- clipped off and not translated.)
-
- Note that some desktops (KDE and xfce) appear to mess with the window
- stacking in ways that are not yet clear. In these cases x11vnc works
- around the problem by applying the CopyRect even if obscuring windows'
- data is translated! Use -nowirecopyrect if this yields undesirable
- effects for your desktop.
-
- Also, the CopyRect encoding may give incorrect results under -scale
- (depending on the scale factor the CopyRect operation is often only
- approximate: the correctly scaled framebuffer will be slightly
- different from the translated one.) x11vnc will try to push a
- "cleanup" update after the CopyRect if -scale is in effect. Use
- -nowirecopyrect if this or other painting errors are unacceptable.
-
-
- Q-78: Can x11vnc try to apply heuristics to detect when a window is
- scrolling its contents and use the CopyRect encoding for a speedup?
-
- Another nice idea for a hack! As of May/2005 x11vnc will by default
- apply heuristics to try to detect if the window that has the input
- focus is scrolling its contents (but only when x11vnc is feeding user
- input, keystroke or pointer, to the X server.) So, when detected,
- scrolls induced by dragging on a scrollbar or by typing (e.g. Up or
- Down arrows, hitting Return in a terminal window, etc), will show up
- much more quickly than via the standard x11vnc screen polling update
- mechanism.
-
- There will be a speedup for both slow and fast links to viewers. For
- slow links the speedup is mostly due to the CopyRect encoding not
- requiring the image data to be transmitted over the network. For fast
- links the speedup is primarily due to x11vnc not having to read the
- scrolled framebuffer data from the X server (recall that reading from
- the hardware framebuffer is slow.)
-
- To do this x11vnc uses the RECORD X extension to snoop the X11
- protocol between the X client with the focus window and the X server.
- This extension is usually present on most X servers (but SuSE disables
- it for some reason.) On XFree86/Xorg it can be enabled via Load
- "record" in the Module section of the config file if it isn't already:
-Section "Module"
- ...
- Load "record"
- ...
-EndSection
-
- Currently the RECORD extension is used as little as possible so as to
- not slow down regular use. Only simple heuristics are applied to
- detect XCopyArea and XConfigureWindow calls from the application.
- These catch a lot of scrolls, e.g. in mozilla/firefox and in terminal
- windows like gnome-terminal and xterm. Unfortunately the toolkits KDE
- applications use make scroll detection less effective (only rarely are
- they detected: i.e. Konqueror and Konsole don't work.) An interesting
- project, that may be the direction x11vnc takes, is to record all of
- the X11 protocol from all clients and try to "tee" the stream into a
- modified Xvfb watching for CopyRect and other VNC speedups. A
- potential issue is the RECORD stream is delayed from actual view on
- the X server display: if one falls too far behind it could become a
- mess...
-
- The initial implementation of -scrollcopyrect option is useful in that
- it detects many scrolls and thus gives a much nicer working
- environment (especially when combined with the -wireframe
- -wirecopyrect options, which are also on by default; and if you are
- willing to enable the ShadowFB things are very fast.) The fact that
- there aren't long delays or lurches during scrolling is the primary
- improvement.
-
- But there are some drawbacks:
- * Not all scrolls are detected. Some apps scroll windows in ways
- that cannot currently be detected, and other times x11vnc "misses"
- the scroll due to timeouts, etc. Sometimes it is more distracting
- that a speedup occasionally doesn't work as opposed to being
- consistently slow!
- * For rapid scrolling (i.e. sequence of many scrolls over a short
- period) there can be painting errors (tearing, bunching up, etc.)
- during the scroll. These will repair themselves after the scroll
- is over, but when they are severe it can be distracting. Try to
- think of the approximate window contents as a quicker and more
- useful "animation" compared to the slower polling scheme...
- * Scrolling inside shells in terminal windows (gnome-terminal,
- xterm), can lead to odd painting errors. This is because x11vnc
- did not have time to detect a screen change just before the scroll
- (most common is the terminal undraws the block cursor before
- scrolling the text up: in the viewer you temporarily see multiple
- block cursors.) Another issue is with things like more(1): scroll
- detection for 5-6 lines happens nicely, but then it can't keep up
- and so there is a long pause for the standard polling method to
- deliver the remaining updates.
- * More rarely sometimes painting errors are not repaired after the
- scroll is over. This may be a bug in x11vnc or libvncserver, or it
- may be an inescapable fact of the CopyRect encoding and the delay
- between RECORD callbacks and what is actually on the X display.
- One can tap the Alt_L key (Left "Alt" key) 3 times in a row to
- signal x11vnc to refresh the screen to all viewers. Your
- VNC-viewer may have its own screen refresh hot-key or button. See
- also: -fixscreen
- * Some applications, notably OpenOffice, do XCopyArea scrolls in
- weird ways that assume ancestor window clipping is taking place.
- See the -scr_skip option for ways to tweak this on a
- per-application basis.
- * Selecting text while dragging the mouse may be slower, especially
- if the Button-down event happens near the window's edge. This is
- because the scrollcopyrect scheme is watching for scrolls via
- RECORD and has to wait for a timeout to occur before it does the
- update.
- * For reasons not yet understood the RECORD extension can stop
- responding (and hence scrolls are missed.) As a workaround x11vnc
- attempts to reset the RECORD connection every 60 seconds or so.
- Another workaround is to type 4 Super_L (Left Super/Windows-Flag
- key) in a row to reset RECORD. Work is in progress to try to fix
- this bug.
- * Sometimes you need to "retrain" x11vnc for a certain window
- because it fails to detect scrolls in it. Sometimes clicking
- inside the application window or selecting some text in it to
- force the focus helps.
- * When using the -scale option there will be a quick CopyRect
- scroll, but it needs to be followed by a slower "cleanup" update.
- This is because for a fixed finite screen resolution (e.g. 75 dpi)
- scaling and copyrect-ing are not exactly independent. Scaling
- involves a blending of nearby pixels and if you translate a pixel
- the neighbor pixel weighting may be different. So you have to wait
- a bit for the cleanup update to finish. On slow links x11vnc may
- automatically decide to not detect scrolls when -scale is in
- effect. In general it will also try to defer the cleanup update if
- possible.
-
- If you find the -scrollcopyrect behavior too approximate or
- distracting you can go back to the standard polling-only update method
- with the -noscrollcopyrect (or -noscr for short.) If you find some
- extremely bad and repeatable behavior for -scrollcopyrect please
- report a bug.
-
- Alternatively, as with -wireframe, there are many tuning parameters to
- try to improve the situation. You can also access these parameters
- inside the gui under "Tuning". These parameters can be tweaked:
- * The minimum pixel area of a rectangle to be watched for scrolls.
- * A list if application names to skip scroll detection.
- * Which keystrokes should trigger scroll detection.
- * Which applications should have a "terminal" tweak applied to them.
- * When repeating keys (e.g. Up arrow) should be discarded to
- preserve a scroll.
- * Cutoffs for closeness to Top, Bottom, Left, and Right edges of
- window for mouse induced scrolls.
- * Set timeout parameters for keystroke induced scrolls.
- * Set timeout parameters for mouse pointer induced scrolls.
- * Have the full screen be periodically refreshed to fix painting
- errors.
-
-
- Q-79: Can x11vnc do client-side caching of pixel data? I.e. so when
- that pixel data is needed again it does not have to be retransmitted
- over the network.
-
- As of Dec/2006 in the 0.9 development tarball there is an experimental
- client-side caching implementation enabled by the "-ncache n" option.
- In fact, during the test period it was on by default with n set to 10.
- To disable it use "-noncache".
-
- It is a simple scheme where a (very large) lower portion of the
- framebuffer (i.e. starting just below the user's actual desktop
- display) is used for storing pixel data. CopyRect; a fast, essentially
- local viewer-side VNC encoding; is used to swap the pixel data in and
- out of the actual display area. It gives an excellent speedup for
- iconifying/deiconifying and moving windows and re-posting of menus
- (often it doesn't feel like VNC at all: there is no delay waiting for
- the pixel data to fill in.)
-
- This scheme is nice because it does all of this within the existing
- VNC protocol, and so it works with all VNC viewers.
-
- A challenge to doing more sophisticated (e.g. compressed and/or
- shared) client-side caching is that one needs to extend the VNC
- protocol, modify a viewer and then also convince users to adopt your
- modified VNC Viewer (or get the new features to be folded into the
- main VNC viewers, patches accepted, etc... likely takes many years
- before they might be deployed in the field.) So it is convenient that
- the "-ncache n" works with any unaltered VNC viewer.
-
- A drawback of the "-ncache n" method is that in the VNC Viewer you can
- scroll down and actually see the cached pixel data. So it looks like
- there is a bug: you can scroll down in your viewer and see a strange
- "history" of windows on your desktop. This is working as intended. One
- will need to try to adjust the size of his VNC Viewer window so the
- cache area cannot be seen. SSVNC (see below) can do this
- automatically.
-
- At some point LibVNCServer may implement a "rfbFBCrop" pseudoencoding
- that viewers can use to learn which portion of the framebuffer to
- actually show to the users (with the hidden part used for caching, or
- perhaps something else, maybe double buffering or other offscreen
- rendering...)
-
- The Enhanced TightVNC Viewer (SSVNC) Unix viewer has a nice -ycrop
- option to help hide the pixel cache area from view. It will turn on
- automatically if the framebuffer appears to be very tall (height more
- than twice the width), or you can supply the actual value for the
- height. If the screen is resized by scaling, etc, the ycrop value is
- scaled as well. In fullscreen mode you cannot scroll past the end of
- the actual screen, and in non-fullscreen mode the window manager frame
- is adjusted to fit the actual display (so you don't see the pixel
- cache region) and the scrollbars are very thin to avoid distraction
- and trouble fitting inside your display. Use the "-sbwidth n" viewer
- option to make the scrollbars thicker if you like.
-
- Another drawback of the scheme is that it is VERY memory intensive,
- the n in "-ncache n" is the factor of increase over the base
- framebuffer size to use for caching. It is an even integer and should
- be fairly large, 6-12, to achieve good response. This usually requires
- about 50-100MB of additional RAM on both the client and server sides.
- For example with n=6 a 1280x1024 display will use a framebuffer that
- is 1280x7168: everything below row 1024 is the pixel buffer cache. If
- you are running on low memory machines or memory is tight because of
- other running applications you should not use -ncache.
-
- The reason for so much memory is because the pixel data is not
- compressed and so the whole window to be saved must be stored
- "offscreen". E.g. for a large web browser window this can be nearly 1
- million pixels, and that is only for a single window! One typically
- wants to cycle between 5-10 large active windows. Also because both
- backing-store (the window's actual contents) and save-unders (the
- pixels covered up by the window) are cached offscreen that introduces
- an additional factor of 2 in memory use.
-
- However, even in the smallest usage mode with n equal 2 and
- -ncache_no_rootpixmap set (this requires only 2X additional
- framebuffer memory) there is still a noticable improvement for many
- activities, although it is not as dramatic as with, say n equal 12 and
- rootpixmap (desktop background) caching enabled.
-
- The large memory consumption of the current implementation can be
- thought of as a tradeoff to providing caching and being compatible
- with all VNC viewers and also ease of implementing. Hopefully it can
- be tuned to use less, or the VNC community will extend the protocol to
- allow caching and replaying of compressed blobs of data.
-
- Another option to experiment with is "-ncache_cr". By specifying it,
- x11vnc will try to do smooth opaque window moves instead of its
- wireframe. This can give a very nice effect (note: on Unix the realvnc
- viewer seems to be smoother than the tightvnc viewer), but can lead to
- some painting problems, and can be jerky in some circumstances.
-
- Surprisingly, for very slow connections, e.g. modem, the -ncache_cr
- option can actually improve window drags. This is probably because no
- pixel data (only CopyRect instructions) are sent when dragging a
- window. Normally, the wireframe must be sent and this involves
- compressing and sending the lines that give rise to the moving box
- effect (note that real framebuffer data is sent to "erase" the white
- lines of the box.)
-
- If you experience painting errors you can can tap the Alt_L key (Left
- "Alt" key) 3 times in a row to signal x11vnc to refresh the screen to
- all viewers. You may also need to iconify and then deiconify any
- damaged windows to correct their cache data as well. Note that if you
- change color viewer depth (e.g. 8bpp to full color) dynamically that
- will usually lead to the entire extended framebuffer being resent
- which can take a long time over very slow links: it may be better to
- reconnect and reset the format right after doing so. x11vnc will try
- to detect the format change and clear (make completely black) the
- cache region.
-
- Gotcha for older Unix VNC Viewers: The older Unix VNC viewers (e.g.
- current TightVNC Unix Viewer) require X server backingstore to keep
- off-viewer screen data local. If the viewer-side X server has
- backingstore disabled (sadly, currently the default on Linux, etc),
- then to get the offscreen pixels the viewer has to ask for a refresh
- over the network, thereby defeating the caching. Use something like
- this in your viewer-side /etc/X11/xorg.conf file (or otherwise get
- your viewer-side system to do it)
-Section "Device"
- ...
- Option "backingstore"
- ...
-EndSection
-
- No problems like this have been observed with Windows VNC Viewers:
- they all seem to keep their entire framebuffer in local memory.
-
- Gotcha for KDE krdc VNC Viewer: One user found that KDE's krdc viewer
- has some sort of hardwired limit on the maximum size of the
- framebuffer (64MB?). It fails quickly saying "The connection to the
- host has been interrupted." The workaround for his 1280x1024
- x11vnc-side display was to run with "-ncache 10", i.e. a smaller value
- to be under the krdc threshold.
-
- Although this scheme is not as quick (nor as compressed) as
- nx/nomachine, say, it does provide a good step in the direction of
- improving VNC performance by client side caching.
-
-
- Q-80: Does x11vnc support TurboVNC?
-
- As of Feb/2009 (development tarball) there is an experimental kludge
- to let you build x11vnc using TurboVNC's modified TightVNC encoding.
- TurboVNC is part of the VirtualGL project. It does two main things to
- speed up the TightVNC encoding:
- * It eliminates bottlenecks, overheads, wait-times in the TightVNC
- encoding implementation and instead only worries about sending
- very well (and quickly) compressed JPEG data.
- * A fast proprietary JPEG implemention is used (Intel IPP on x86)
- instead of the usual libjpeg implementation. TurboJPEG is an
- interface library, libturbojpeg, provided by the project that
- achieves this.
-
- TurboVNC works very well over LAN and evidently fast Broadband too.
- When using it with x11vnc in such a situation you may want to dial
- down the delays, e.g. "-wait 5" and "-defer 5" (or even a smaller
- setting) to poll and pump things out more quickly.
-
- See the instructions in "x11vnc/misc/turbovnc/README" for how to build
- x11vnc with TurboVNC support. You will also need to download the
- TurboJPEG software.
-
- In brief, the steps look like this:
- cd x11vnc-x.y.z/x11vnc/misc/turbovnc
- ./apply_turbovnc
- cd ../../..
- env LDFLAGS='-L/DIR -Xlinker --rpath=/DIR' ./configure
- make AM_LDFLAGS='-lturbojpeg'
-
- where you replace "/DIR" with the directory containing libturbojpeg.so
- you downloaded separately. If it works out well enough TurboVNC
- support will be integrated into x11vnc and more of its tuning features
- will be implemented. Support for TurboVNC in SSVNC viewer has been
- added as an experiment as well. If you try either one, let us know how
- it went.
-
- There also may be some Linux.i686 and Darwin.i386 x11vnc binaries with
- TurboVNC support in the misc. bins directory. For other platforms you
- will need to compile yourself.
-
- On relatively cheap and old hardware (Althon64 X2 5000+ / GeForce
- 6200) x11vnc and SSVNC, both TurboVNC enabled, were able to sustain
- 13.5 frames/sec (fps) and 15 Megapixels/sec using the VirtualGL
- supplied OpenGL benchmark program glxspheres. VirtualGL on higher-end
- hardware can sustain 20-30 fps with the glxspheres benchmark.
-
- Potential Slowdown: As we describe elsewhere, unless you use x11vnc
- with an X server using, say, NVidia proprietary drivers (or a virtual
- X server like Xvfb or Xdummy, or in ShadowFB mode), then the read rate
- from the graphics card can be rather slow (e.g. 10 MB/sec) and becomes
- the bottleneck when using x11vnc over fast networks. Note that all of
- Xorg's drivers currently (2009) have slow read rates (only proprietary
- drivers appear to have optimized reads.)
-
- So under these (more or less typical) conditions, the speed
- improvement provided by TurboVNC may only be marginal. Look for this
- output to see your read rate:
- 28/02/2009 11:11:07 Autoprobing TCP port
- 28/02/2009 11:11:07 Autoprobing selected port 5900
- 28/02/2009 11:11:08 fb read rate: 10 MB/sec
- 28/02/2009 11:11:08 screen setup finished.
-
- A rate of 10 MB/sec means a 1280x1024x24 screen takes 0.5 seconds to
- read in. TurboVNC compresses that to JPEG in a much shorter time. On
- the other hand, an NVidia driver may have a read rate of 250 MB/sec
- and so only takes 0.02 seconds to read the entire screen in.
-
-
-
- [Mouse Cursor Shapes]
-
- Q-81: Why isn't the mouse cursor shape (the little icon shape where
- the mouse pointer is) correct as I move from window to window?
-
- On X servers supporting XFIXES or Solaris/IRIX Overlay extensions it
- is possible for x11vnc to do this correctly. See a few paragraphs down
- for the answer.
-
- Historically, the X11 mouse cursor shape (i.e. little picture: an
- arrow, X, I-beam, resizer, etc) is one of the few WRITE-only objects
- in X11. That is, an application can tell the X server what the cursor
- shape should be when the pointer is in a given window, but a program
- (like x11vnc) unfortunately cannot read this information. I believe
- this is because the cursor shape is often downloaded to the graphics
- hardware (video card), but I could be mistaken.
-
- A simple kludge is provided by the "-cursor X" option that changes the
- cursor when the mouse is on the root background (or any window has the
- same cursor as the root background.) Note that desktops like GNOME or
- KDE often cover up the root background, so this won't work for those
- cases. Also see the "-cursor some" option for additional kludges.
-
- Note that as of Aug/2004 on Solaris using the SUN_OVL overlay
- extension and IRIX, x11vnc can show the correct mouse cursor when the
- -overlay option is supplied. See this FAQ for more info.
-
- Also as of Dec/2004 XFIXES X extension support has been added to allow
- exact extraction of the mouse cursor shape. XFIXES fixes the problem
- of the cursor-shape being write-only: x11vnc can now query the X
- server for the current shape and send it back to the connected
- viewers. XFIXES is available on recent Linux Xorg based distros and
- Solaris 10.
-
- The only XFIXES issue is the handling of alpha channel transparency in
- cursors. If a cursor has any translucency then in general it must be
- approximated to opaque RGB values for use in VNC. There are some
- situations where the cursor transparency can also handled exactly:
- when the VNC Viewer requires the cursor shape be drawn into the VNC
- framebuffer or if you apply a patch to your VNC Viewer to extract
- hidden alpha channel data under 32bpp. Details can be found here.
-
-
- Q-82: When using XFIXES cursorshape mode, some of the cursors look
- really bad with extra black borders around the cursor and other cruft.
- How can I improve their appearance?
-
- This happens for cursors with transparency ("alpha channel"); regular
- X cursors (bitmaps) should be correct. Unfortunately x11vnc 0.7 was
- released with a very poor algorithm for approximating the
- transparency, which led to the ugly black borders.
-
- The problem is as follows: XFIXES allows x11vnc to retrieve the
- current X server cursor shape, including the alpha channel for
- transparency. For traditional bitmap cursors the alpha value will be 0
- for completely transparent pixels and 255 for completely opaque
- pixels; whereas for modern, eye-candy cursors an alpha value between 0
- and 255 means to blend in the background colors to that degree with
- the cursor colors. The pixel color blending formula is something like
- this: Red = Red_cursor * a + Red_background * (1 - a), (where here 0
- =< a =< 1), with similar for Green and Blue. The VNC protocol does not
- currently support an alpha channel in cursors: it only supports
- regular X bitmap cursors and Rich Cursors that have RGB (Red, Green,
- Blue) color data, but no "A" = alpha data. So in general x11vnc has to
- approximate a cursor with transparency to create a Rich Cursor. This
- is easier said than done: some cursor themes have cursors with
- complicated drop shadows and other forms of translucency.
-
- Anyway, for the x11vnc 0.7.1 release the algorithm for approximating
- transparency is much improved and hopefully gives decent cursor shapes
- for most cursor themes and you don't have to worry about it.
-
- In case it still looks bad for your cursor theme, there are (of
- course!) some tunable parameters. The "-alphacut n" option lets you
- set the threshold "n" (between 0 and 255): cursor pixels with alpha
- values below n will be considered completely transparent while values
- equal to or above n will be completely opaque. The default is 240. The
- "-alphafrac f" option tries to correct individual cursors that did not
- fare well with the default -alphacut value: if a cursor has less than
- fraction f (between 0.0 and 1.0) of its pixels selected by the default
- -alphacut, the threshold is lowered until f of its pixels are
- selected. The default fraction is 0.33.
-
- Finally, there is an option -alpharemove that is useful for themes
- where many cursors are light colored (e.g. "whiteglass".) XFIXES
- returns the cursor data with the RGB values pre-multiplied by the
- alpha value. If the white cursors look too grey, specify -alpharemove
- to brighten them by having x11vnc divide out the alpha value.
-
- One user played with these parameters and reported back:
- Of the cursor themes present on my system:
-
- gentoo and gentoo-blue: alphacut:192 - noalpharemove
-
- gentoo-silver: alphacut:127 and alpharemove
-
- whiteglass and redglass (presumably also handhelds, which is based
- heavily on redglass) look fine with the apparent default of alphacut:255.
-
-
- Q-83: In XFIXES mode, are there any hacks to handle cursor
- transparency ("alpha channel") exactly?
-
- As of Jan/2005 libvncserver has been modified to allow an alpha
- channel (i.e. RGBA data) for Rich Cursors. So x11vnc can now send the
- alpha channel data to libvncserver. However, this data will only be
- used for VNC clients that do not support the CursorShapeUpdates VNC
- extension (or have disabled it.) It can be disabled for all clients
- with the -nocursorshape x11vnc option. In this case the cursor is
- drawn, correctly blended with the background, into the VNC framebuffer
- before being sent out to the client. So the alpha blending is done on
- the x11vnc side. Use the -noalphablend option to disable this behavior
- (always approximate transparent cursors with opaque RGB values.)
-
- The CursorShapeUpdates VNC extension complicates matters because the
- cursor shape is sent to the VNC viewers supporting it, and the viewers
- draw the cursor locally. This improves response over slow links. Alpha
- channel data for these locally drawn cursors is not supported by the
- VNC protocol.
-
- However, in the libvncserver CVS there is a patch to the TightVNC
- viewer to make this work for CursorShapeUpdates under some
- circumstances. This hack is outside of the VNC protocol. It requires
- the screens on both sides to be depth 24 at 32bpp (it uses the extra 8
- bits to secretly hide the cursor alpha channel data.) Not only does it
- require depth 24 at 32bpp, but it also currently requires the client
- and server to be of the same endianness (otherwise the hidden alpha
- data gets reset to zero by a libvncserver translation function; we can
- fix this at some point if there is interest.) The patch is for the
- TightVNC 1.3dev5 Unix vncviewer and it enables the TightVNC viewer to
- do the cursor alpha blending locally. The patch code should give an
- example on how to change the Windows TightVNC viewer to achieve the
- same thing (send me the patch if you get that working.)
-
- This patch is applied to the Enhanced TightVNC Viewer (SSVNC) package
- we provide.
-
- [Mouse Pointer]
-
- Q-84: Why does the mouse arrow just stay in one corner in my
- vncviewer, whereas my cursor (that does move) is just a dot?
-
- This default takes advantage of a tightvnc extension
- (CursorShapeUpdates) that allows specifying a cursor image shape for
- the local VNC viewer. You may disable it with the -nocursor option to
- x11vnc if your viewer does not have this extension.
-
- Note: as of Aug/2004 this should be fixed: the default for
- non-tightvnc viewers (or ones that do not support CursorShapeUpdates)
- will be to draw the moving cursor into the x11vnc framebuffer. This
- can also be disabled via -nocursor.
-
-
- Q-85: Can I take advantage of the TightVNC extension to the VNC
- protocol where Cursor Positions Updates are sent back to all connected
- clients (i.e. passive viewers can see the mouse cursor being moved
- around by another viewer)?
-
- Use the -cursorpos option when starting x11vnc. A VNC viewer must
- support the Cursor Positions Updates for the user to see the mouse
- motions (the TightVNC viewers support this.) As of Aug/2004 -cursorpos
- is the default. See also -nocursorpos and -nocursorshape.
-
-
- Q-86: Is it possible to swap the mouse buttons (e.g. left-handed
- operation), or arbitrarily remap them? How about mapping button clicks
- to keystrokes, e.g. to partially emulate Mouse wheel scrolling?
-
- You can remap the mouse buttons via something like: -buttonmap 13-31
- (or perhaps 12-21.) Also, note that xmodmap(1) lets you directly
- adjust the X server's button mappings, but in some circumstances it
- might be more desirable to have x11vnc do it.
-
- One user had an X server with only one mouse button(!) and was able to
- map all of the VNC client mouse buttons to it via: -buttonmap 123-111.
-
- Note that the -debug_pointer option prints out much info for every
- mouse/pointer event and is handy in solving problems.
-
- To map mouse button clicks to keystrokes you can use the alternate
- format where the keystrokes are enclosed between colons like this
- :<KeySym>: in place of the mouse button digit. For a sequence of
- keysyms separate them with "+" signs. Look in the include file
- <X11/keysymdef.h>, or use xev(1), or -debug_keyboard to find the
- keysym names. Button clicks can also be included in the sequence via
- the fake keysyms Button1, etc.
-
- As an example, suppose the VNC viewer machine has a mouse wheel (these
- generate button 4 and 5 events), but the machine that x11vnc is run on
- only has the 3 regular buttons. In normal operation x11vnc will
- discard the button 4 and 5 events. However, either of the following
- button maps could possibly be of use emulating the mouse wheel events
- in this case:
- -buttonmap 12345-123:Prior::Next:
- -buttonmap 12345-123:Up+Up+Up::Down+Down+Down:
-
- Exactly what keystroke "scrolling" events they should be bound to
- depends on one's taste. If this method is too approximate, one could
- consider not using -buttonmap but rather configuring the X server to
- think it has a mouse with 5 buttons even though the physical mouse
- does not. (e.g. 'Option "ZAxisMapping" "4 5"'.)
-
- Note that when a keysym-mapped mouse button is clicked down this
- immediately generates the key-press and key-release events (for each
- keysym in turn if the mapping has a sequence of keysyms.) When the
- mouse button goes back up nothing is generated.
-
- If you include modifier keys like Shift_L instead of key-press
- immediately followed by key-release the state of the modifier key is
- toggled (however the initial state of the modifier key is ignored.) So
- to map the right button to type my name 'Karl Runge' I could use this:
- -buttonmap 3-:Shift_L+k+Shift_L+a+r+l+space+Shift_L+r+Shift_L+u+n+g+e:
-
- (yes, this is getting a little silly.)
-
- BTW, Coming the other way around, if the machine you are sitting at
- does not have a mouse wheel, but the remote machine does (or at least
- has 5 buttons configured), this key remapping can be useful:
- -remap Super_R-Button4,Menu-Button5
-
- you just tap those two keys to get the mouse wheel scrolls (this is
- more useful than the Up and Down arrow keys because a mouse wheel
- "click" usually gives a multi-line scroll.)
- [Keyboard Issues]
-
- Q-87: How can I get my AltGr and Shift modifiers to work between
- keyboards for different languages?
-
- The option -modtweak should help here. It is a mode that monitors the
- state of the Shift and AltGr Modifiers and tries to deduce the correct
- keycode to send, possibly by sending fake modifier key presses and
- releases in addition to the actual keystroke.
-
- Update: As of Jul/2004 -modtweak is now the default (use -nomodtweak
- to get the old behavior.) This was done because it was noticed on
- newer XFree86 setups even on bland "us" keyboards like "pc104 us"
- XFree86 included a "ghost" key with both "<" and ">" it. This key does
- not exist on the keyboard (see this FAQ for more info.) Without
- -modtweak there was then an ambiguity in the reverse map keysym =>
- keycode, making it so the "<" symbol could not be typed.
-
- Also see the FAQ about the -xkb option for a more powerful method of
- modifier tweaking for use on X servers with the XKEYBOARD extension.
-
- When trying to resolve keyboard mapping problems, note that the
- -debug_keyboard option prints out much info for every keystroke and so
- can be useful debugging things.
-
- Note that one user had a strange setup and none of the above helped.
- His solution was to disable all of the above and use -nomodtweak. This
- is the simplest form of keystroke insertion and it actually solved the
- problem. Try it if the other options don't help.
-
-
- Q-88: When I try to type a "<" (i.e. less than) instead I get ">"
- (i.e. greater than)! Strangely, typing ">" works OK!!
-
- Does your keyboard have a single key with both "<" and ">" on it? Even
- if it doesn't, your X server may think your keyboard has such a key
- (e.g. pc105 in the XF86Config file when it should be something else,
- say pc104.)
-
- Short Cut: Try the -xkb or -sloppy_keys options and see if that helps
- the situation. The discussion below is a bit outdated (e.g. -modtweak
- is now the default) but it is useful reference for various tricks and
- so is kept.
-
-
- The problem here is that on the Xserver where x11vnc is run there are
- two keycodes that correspond to the "<" keysym. Run something like
- this to see:
-
- xmodmap -pk | egrep -i 'KeyCode|less|greater'
- There are 4 KeySyms per KeyCode; KeyCodes range from 8 to 255.
- KeyCode Keysym (Keysym) ...
- 59 0x002c (comma) 0x003c (less)
- 60 0x002e (period) 0x003e (greater)
- 94 0x003c (less) 0x003e (greater)
-
- That keycode 94 is the special key with both "<" and ">". When x11vnc
- receives the "<" keysym over the wire from the remote VNC client, it
- unfortunately maps it to keycode 94 instead of 59, and sends 94 to the
- X server. Since Shift is down (i.e. you are Shifting the comma key),
- the X server interprets this as Shifted-94, which is ">".
-
- A workaround in the X server configuration is to "deaden" that special
- key:
-
- xmodmap -e "keycode 94 = "
-
- However, one user said he had to do this:
-
- xmodmap -e "keycode 94 = 0x002c 0x003c"
-
- (If the numerical values are different for your setup, substitute the
- ones that correspond to your display. The above xmodmap scheme can
- often be used to work around other ambiguous keysym to keycode
- mappings.)
-
- Alternatively, here are some x11vnc options to try to work around the
- problem:
- -modtweak
-
- and
- -remap less-comma
-
- These are convenient in that they do not modify the actual X server
- settings. The former (-modtweak) is a mode that monitors the state of
- the Shift and AltGr modifiers and tries to deduce the correct keycode
- sequence to send. Since Jul/2004 -modtweak is now the default. The
- latter (-remap less-comma) is an immediate remapping of the keysym
- less to the keysym comma when it comes in from a client (so when Shift
- is down the comma press will yield "<".)
-
- See also the FAQ about the -xkb option as a possible workaround using
- the XKEYBOARD extension.
-
- Note that the -debug_keyboard option prints out much info for every
- keystroke to aid debugging keyboard problems.
-
-
- Q-89: Extra Character Inserted, E.g.: When I try to type a "<" (i.e.
- less than) instead I get "<," (i.e. an extra comma.)
-
- This is likely because you press "Shift" then "<" but then released
- the Shift key before releasing the "<". Because of a keymapping
- ambiguity the last event "< up" is interpreted as "," because that key
- unshifted is the comma.
-
- This extra character insertion will happen for other combinations of
- characters: in general it can happen whenever the Shift key is
- released early.
-
- This should not happen in -xkb mode, because it works hard to resolve
- the ambiguities. If you do not want to use -xkb, try the option
- -sloppy_keys to attempt a similar type of algorithm.
-
- One user had this problem for Italian and German keyboards with the
- key containing ":" and "." When he typed ":" he would get an extra "."
- inserted after the ":". The solution was -sloppy_keys.
-
-
- Q-90: I'm using an "international" keyboard (e.g. German "de", or
- Danish "dk") and the -modtweak mode works well if the VNC viewer is
- run on a Unix/Linux machine with a similar keyboard. But if I run
- the VNC viewer on Unix/Linux with a different keyboard (e.g. "us") or
- Windows with any keyboard, I can't type some keys like: "@", "$",
- "<", ">", etc. How can I fix this?
-
- The problem with Windows is it does not seem to handle AltGr well. It
- seems to fake it up by sending Control_L+Alt_R to applications. The
- Windows VNC viewer sends those two down keystrokes out on the wire to
- the VNC server, but when the user types the next key to get, e.g., "@"
- the Windows VNC viewer sends events bringing the up the
- Control_L+Alt_R keys, and then sends the "@" keysym by itself.
-
- The Unix/Linux VNC viewer on a "us" keyboard does a similar thing
- since "@" is the Shift of the "2" key. The keysyms Shift and "@" are
- sent to the VNC server.
-
- In both cases no AltGr is sent to the VNC server, but we know AltGr is
- needed on the physical international keyboard to type a "@".
-
- This all worked fine with x11vnc running with the -modtweak option (it
- figures out how to adjust the Modifier keys (Shift or AltGr) to get
- the "@".) However it fails under recent versions of XFree86 (and the
- X.org fork.) These run the XKEYBOARD extension by default and make
- heavy use of it to handle international keyboards.
-
- To make a long story short, on these newer XFree86 setups the
- traditional X keymap lookup x11vnc uses is no longer accurate. x11vnc
- can't find the keysym "@" anywhere in the keymapping! (even though it
- is in the XKEYBOARD extended keymapping.)
-
- How to Solve: As of Jul/2004 x11vnc has two changes:
- * -modtweak (tweak Modifier keys) is now the default (use
- -nomodtweak to go back to the old way)
- * there is a new option -xkb to use the XKEYBOARD extension API to
- do the Modifier key tweaking.
-
- The -xkb option seems to fix all of the missing keys: "@", "<", ">",
- etc.: it is recommended that you try it if you have this sort of
- problem. Let us know if there are any remaining problems (see the next
- paragraph for some known problems.) If you specify the -debug_keyboard
- (aka -dk) option twice you will get a huge amount of keystroke
- debugging output (send it along with any problems you report.)
-
- Update: as of Jun/2005 x11vnc will try to automatically enable -xkb if
- it appears that would be beneficial (e.g. if it sees any of "@", "<",
- ">", "[" and similar keys are mapped in a way that needs the -xkb to
- access them.) To disable this automatic check use -noxkb.
-
- Known problems:
- * One user had to disable a "ghost" Mode_switch key that was causing
- problems under -xkb. His physical AltGr key was bound to
- ISO_Level3_Shift (which seems to be the XKEYBOARD way of doing
- things), while there was a ghost key Mode_switch (which seems to
- be obsolete) in the mapping as well. Both of these keysyms were
- bound to Mod5 and x11vnc was unfortunately choosing Mode_switch.
- From the x11vnc -xkb -dk -dk output it was noted that Mode_switch
- was attached to keycode 93 (no physical key generates this
- keycode) while ISO_Level3_Shift was attached to keycode 113. The
- keycode skipping option was used to disable the ghost key:
- -skip_keycodes 93
- * In implementing -xkb we noticed that some characters were still
- not getting through, e.g. "~" and "^". This is not really an
- XKEYBOARD problem. What was happening was the VNC viewer was
- sending the keysyms asciitilde and asciicircum to x11vnc, but on
- the X server with the international keyboard those keysyms were
- not mapped to any keys. So x11vnc had to skip them (Note: as of
- May/2005 they are added by default see -add_keysyms below.)
- The way these characters are typically entered on international
- keyboards is by "dead" (aka "mute") keys. E.g. to enter "~" at the
- physical display the keysym dead_tilde is pressed and released
- (this usually involves holding AltGr down while another key is
- pressed) and then space is pressed. (this can also be used get
- characters with the "~" symbol on top, e.g. "ã" by typing "a"
- instead of space.)
- What to do? In general the VNC protocol has not really solved this
- problem: what should be done if the VNC viewer sends a keysym not
- recognized by the VNC server side? Workarounds can possibly be
- created using the -remap x11vnc option:
- -remap asciitilde-dead_tilde,asciicircum-dead_circumflex
- etc. Use -remap filename if the list is long. Please send us your
- workarounds for this problem on your keyboard. Perhaps we can have
- x11vnc adjust automatically at some point. Also see the
- -add_keysyms option in the next paragraph.
- Update: for convenience "-remap DEAD" does many of these mappings
- at once.
- * To complement the above workaround using the -remap, an option
- -add_keysyms was added. This option instructs x11vnc to bind any
- unknown Keysyms coming in from VNC viewers to unused Keycodes in
- the X server. This modifies the global state of the X server. When
- x11vnc exits it removes the extra keymappings it created. Note
- that the -remap mappings are applied first, right when the Keysym
- is received from a VNC viewer, and only after that would
- -add_keysyms, or anything else, come into play.
- Update: -add_keysyms is now on by default. Use -noadd_keysyms to
- disable.
-
-
- Q-91: When typing I sometimes get double, triple, or more of my
- keystrokes repeated. I'm sure I only typed them once, what can I do?
-
- This may be due to an interplay between your X server's key autorepeat
- delay and the extra time delays caused by x11vnc processing.
-
- Short answer: disable key autorepeating by running the command "xset r
- off" on the Xserver where x11vnc is run (restore via "xset r on") or
- use the new (Jul/2004) -norepeat x11vnc option. You will still have
- autorepeating because that is taken care of on your VNC viewer side.
-
- Update: as of Dec/2004 -norepeat is now the default. Use -repeat to
- disable it.
-
- Details:
- suppose you press a key DOWN and it generates changes in large regions
- of the screen. The CPU and I/O work x11vnc does for the large screen
- change could be longer than your X server's key autorepeat delay.
- x11vnc may not get to processing the key UP event until after the
- screen work is completed. The X server believes the key has been held
- down all this time, and applies its autorepeat rules.
-
- Even without inducing changes in large regions of the screen, this
- problem could arise when accessing x11vnc via a dialup modem or
- otherwise high latency link (e.g. > 250 ms latency.)
-
- Look at the output of "xset q" for the "auto repeat delay" setting. Is
- it low (e.g. < 300 ms)? If you turn off autorepeat completely: "xset r
- off", does the problem go away?
-
- The workaround is to manually apply "xset r off" and "xset r on" as
- needed, or to use the -norepeat (which has since Dec/2004 been made
- the default.) Note that with X server autorepeat turned off the VNC
- viewer side of the connection will (nearly always) do its own
- autorepeating so there is no big loss here, unless someone is also
- working at the physical display and misses his autorepeating.
-
-
- Q-92: The x11vnc -norepeat mode is in effect, but I still get repeated
- keystrokes!!
-
- Are you using x11vnc to log in to an X session via display manager?
- (as described in this FAQ) If so, x11vnc is starting before your
- session and it disables autorepeat when you connect, but then after
- you log in your session startup (GNOME, KDE, ...) could be resetting
- the autorepeat to be on. Or it could be something inside your desktop
- trying to be helpful that decides to turn it back on.
-
- x11vnc in -norepeat mode will by default reset autorepeat to off 2
- times (to help get thru the session startup problem), but it will not
- continue to battle with things turning autorepeat back on. It will
- also turn autorepeat off whenever it goes from a state of zero clients
- to one client. You can adjust the number of resets via "-norepeat N",
- or use "-norepeat -1" to have it keep resetting it whenever autorepeat
- gets turned back on when clients are connected.
-
- In general you can manually turn autorepeating off by typing "xset r
- off", or a using desktop utility/menu, or "x11vnc -R norepeat". If
- something in your desktop is automatically turning it back on you
- should figure out how to disable that somehow.
-
-
- Q-93: After using x11vnc for a while, I find that I cannot type some
- (or any) characters or my mouse clicks and drags no longer have any
- effect, or they lead to strange effects. What happened?
-
- Probably a modifier key, e.g. Control or Alt is "stuck" in a pressed
- down state.
-
- This happens for VNC in general by the following mechanism. Suppose on
- the Viewer side desktop there is some hot-key to switch
- desktops/rooms/spaces, etc. E.g. suppose Alt+LeftArrow moves to the
- left desktop/room/space. Or suppose an Alt+hotkey combination
- iconifies a window. This can leave the Alt key pressed down on the
- remote side.
-
- Consider the sequence that happens. The Alt_L key and then the
- LeftArrow key go down. Since you are inside the viewer the Alt_L key
- press is sent to the other side (x11vnc) and so it is pressed down in
- the remote desktop as well. (by "Alt_L" we mean the Alt key on the
- left-hand side of the keyboard.) Your local desktop (where the VNC
- Viewer is running) then warps to the new desktop/room/space: Leaving
- the Alt_L key still pressed down in the remote desktop.
-
- If someone is sitting at the desktop, or when you return in the viewer
- it may be very confusing because the Alt_L is still pressed down but
- you (or the person sitting at the desktop) do not realize this.
- Depending on which remote desktop (x11vnc side) is used, it can act
- very strangely.
-
- A quick workaround when you notice this is to press and release all of
- the Alt, Shift, Control, Windows-Flag, modifier keys to free the
- pressed one. You need to do this for both the left and right Shift,
- Alt, Control, etc. keys to be sure.
-
- Note that many VNC Viewers try to guard against this when they are
- notified by the window system that the viewer app has "lost focus".
- When it receives the "lost focus" event, the viewer sends VNC
- Key-Release events for all modifier keys that are currently pressed
- down. This does not always work, however, since it depends on how the
- desktop manages these "warps". If the viewer is not notified it cannot
- know it needs to release the modifiers.
-
- You can also use the -clear_mods option to try to clear all of the
- modifier keys at x11vnc startup. You will still have to be careful
- that you do not leave the modifier key pressed down during your
- session. It is difficult to prevent this problem from occurring (short
- of using -remap to prevent sending all of the problem modifier keys,
- which would make the destkop pretty unusable.)
-
- During a session these x11vnc remote control commands can also help:
- x11vnc -R clear_mods
- x11vnc -R clear_keys
- x11vnc -R clear_locks
- x11vnc -R clear_all
-
- A similar problem can occur if you accidentally press the Caps_Lock or
- Num_Lock down. When these are locked on the remote side it can
- sometimes lead to strange desktop behavior (e.g. cannot drag or click
- on windows.) As above you may not notice this because the lock isn't
- down on the local (Viewer) side. See this FAQ on lock keys problem.
- These options may help avoid the problem: -skip_lockkeys and
- -capslock. See also -clear_all.
-
-
- Q-94: The machine where I run x11vnc has an AltGr key, but the local
- machine where I run the VNC viewer does not. Is there a way I can map
- a local unused key to send an AltGr? How about a Compose key as well?
-
- Something like "-remap Super_R-Mode_switch" x11vnc option may work.
- Note that Super_R is the "Right Windoze(tm) Flaggie" key; you may want
- to choose another. The -debug_keyboard option comes in handy in
- finding keysym names (so does xev(1).)
-
- For Compose how about "-remap Menu-Multi_key" (note that Multi_key is
- the official name for Compose.) To do both at the same time: "-remap
- Super_R-Mode_switch,Menu-Multi_key" or use "-remap filename" to
- specify remappings from a file.
-
-
- Q-95: I have a Sun machine I run x11vnc on. Its Sun keyboard has just
- one Alt key labelled "Alt" and two Meta keys labelled with little
- diamonds. The machine where I run the VNC viewer only has Alt keys.
- How can I send a Meta keypress? (e.g. emacs needs this)
-
- Here are a couple ideas. The first one is to simply use xmodmap(1) to
- adjust the Sun X server. Perhaps xmodmap -e "keysym Alt_L = Meta_L
- Alt_L" will do the trick. (there are other ways to do it, one user
- used: xmodmap -e "keycode 26 = Meta_L" for his setup.)
-
- Since xmodmap(1) modifies the X server mappings you may not want to do
- this (because it affects local work on that machine.) Something like
- the -remap Alt_L-Meta_L to x11vnc may be sufficient for ones needs,
- and does not modify the X server environment. Note that you cannot
- send Alt_L in this case, maybe -remap Super_L-Meta_L would be a better
- choice if the Super_L key is typically unused in Unix.
-
-
- Q-96: Running x11vnc on HP-UX I cannot type "#" I just get a "3"
- instead.
-
- One user reports this problem on HP-UX Rel_B.11.23. The problem was
- traced to a strange keyboard mapping for the machine (e.g. xmodmap -pk
- output) that looked like:
- ...
- 039 2 at at at
- ...
- 047 3 numbersign numbersign numbersign
-
- and similar triple mappings (with two in the AltGr/Mode_switch group)
- of a keysum to a single keycode.
-
- Use the -nomodtweak option as a workaround. You can also use xmodmap
- to correct these mappings in the server, e.g.:
- xmodmap -e "keycode 47 = 3 numbersign"
-
- Also, as of Feb/2007, set the environment variable MODTWEAK_LOWEST=1
- (either in your shell or via "-env MODTWEAK_LOWEST=1" option) to
- handle these mappings better.
-
-
- Q-97: Can I map a keystroke to a mouse button click on the remote
- machine?
-
- This can be done directly in some X servers using AccessX and
- Pointer_EnableKeys, but is a bit awkward. It may be more convenient to
- have x11vnc do the remapping. This can be done via the -remap option
- using the fake "keysyms" Button1, Button2, etc. as the "to" keys (i.e.
- the ones after the "-")
-
- As an example, consider a laptop where the VNC viewer is run that has
- a touchpad with only two buttons. It is difficult to do a middle
- button "paste" because (using XFree86/Xorg Emulate3Buttons) you have
- to click both buttons on the touch pad at the same time. This
- remapping:
- -remap Super_R-Button2
-
- maps the Super_R "flag" key press to the Button2 click, thereby making
- X pasting a bit easier.
-
- Note that once the key goes down, the button down and button up events
- are generated immediately on the x11vnc side. When the key is released
- (i.e. goes up) no events are generated.
-
- Q-98: How can I get Caps_Lock to work between my VNC viewer and
- x11vnc?
-
- This is a little tricky because it is possible to get the Caps_Lock
- state out of sync between your viewer-side machine and the x11vnc-side
- X server. For best results, we recommend not ever letting the
- Caps_Lock keypresses be processed by x11vnc. That way when you press
- Caps_Lock in the viewer your local machine goes into the Caps_Lock on
- state and sends keysym "A" say when you press "a". x11vnc will then
- fake things up so that Shift is held down to generate "A". The
- -skip_lockkeys option should help to accomplish this. For finer grain
- control use something like: "-remap Caps_Lock-None".
-
- Also try the -nomodtweak and -capslock options.
-
- Another useful option that turns off any Lock keys on the remote side
- at startup and end is the -clear_all option. During a session you can
- run these remote control commands to modify the Lock keys:
- x11vnc -R clear_locks
- x11vnc -R clear_all
-
- the former will try to unset any Lock keys, the latter will do same
- and also try to make it so no key is pressed down (e.g. "stuck" Alt_L,
- etc.)
- [Screen Related Issues and Features]
-
- Q-99: The remote display is larger (in number of pixels) than the
- local display I am running the vncviewer on. I don't like the
- vncviewer scrollbars, what I can do?
-
- vncviewer has a option (usually accessible via F8 key or -fullscreen
- option) for vncviewer to run in full screen, where it will
- automatically scroll when the mouse is near the edge of the current
- view. For quick scrolling, also make sure Backing Store is enabled on
- the machine vncviewer is run on. (XFree86/Xorg disables it by default
- for some reason, add Option "backingstore" to XF86Config on the
- vncviewer side.)
-
- BTW, contact me if you are having problems with vncviewer in
- fullscreen mode with your window manager (i.e. no keyboard response.)
- I have a workaround for vncviewer using XGrabServer().
-
- There may also be scaling viewers out there (e.g. TightVNC or UltraVNC
- on Windows) that automatically shrink or expand the remote framebuffer
- to fit the local display. Especially for hand-held devices. See also
- the next FAQ on x11vnc scaling.
-
-
- Q-100: Does x11vnc support server-side framebuffer scaling? (E.g. to
- make the desktop smaller.)
-
- As of Jun/2004 x11vnc provides basic server-side scaling. It is a
- global scaling of the desktop, not a per-client setting. To enable it
- use the "-scale fraction" option. "fraction" can either be a floating
- point number (e.g. -scale 0.75) or the alternative m/n fraction
- notation (e.g. -scale 3/4.) Note that if fraction is greater than one
- the display is magnified.
-
- Extra resources (CPU, memory I/O, and memory) are required to do the
- scaling. If the machine is slow where x11vnc is run with scaling
- enabled, the interactive response can be unacceptable. OTOH, if run
- with scaling on a fast machine the performance degradation is usually
- not a big issue or even noticeable.
-
- It may help to compile x11vnc with compiler option -O3 or -O4 to speed
- up the scaling code. Set the CFLAGS env. var. before running
- configure.
-
- Also, if you just want a quick, rough "thumbnail" of the display you
- can append ":nb" to the fraction to turn on "no blending" mode. E.g.:
- "-scale 1/3:nb" Fonts will be difficult to read, but the larger
- features will be recognizable. BTW, "no blending" mode is forced on
- when scaling 8bpp PseudoColor displays (because blending an indexed
- colormap is a bad idea and leads to random colors, use :fb to force it
- on.)
-
- One can also use the ":nb" with an integer scale factor (say "-scale
- 2:nb") to use x11vnc as a screen magnifier for vision impaired
- applications. Since with integer scale factors the framebuffers become
- huge and scaling operations time consuming, be sure to use ":nb" for
- the fastest response.
-
- In general for a scaled display if you are using a TightVNC viewer you
- may want to turn off jpeg encoding (e.g. vncviewer -nojpeg host:0.)
- There appears to be a noise enhancement effect, especially for regions
- containing font/text: the scaling can introduce some pixel artifacts
- that evidently causes the tight encoding algorithm to incorrectly
- detect the regions as image data and thereby introduce additional
- pixel artifacts due to the lossiness of the jpeg compression
- algorithm. Experiment to see if -nojpeg vncviewer option improves the
- readability of text when using -scale to shrink the display size. Also
- note that scaling may actually slow down the transfer of text regions
- because after being scaled they do not compress as well. (this can
- often be a significant slowdown, e.g. 10X.)
-
- Another issue is that it appears VNC viewers require the screen width
- to be a multiple of 4. When scaling x11vnc will round the width to the
- nearest multiple of 4. To disable this use the ":n4" sub option (like
- ":nb" in the previous paragraph; to specify both use a comma:
- ":nb,n4", etc.)
-
- If one desires per-client scaling for something like 1:1 from a
- workstation and 1:2 from a smaller device (e.g. handheld), currently
- the only option is to run two (or more) x11vnc processes with
- different scalings listening on separate ports (-rfbport option, etc.)
-
- Update: As of May/2006 x11vnc also supports the UltraVNC server-side
- scaling. This is a per-client scaling by factors 1/2, 1/3, ... and so
- may be useful for PDA's ("-scale 1/2", etc. will give similar results
- except that it applies to all clients.) You may need to supply
- "-rfbversion 3.6" for this to be recognized by UltraVNC viewers.
-
- BTW, whenever you run two or more x11vnc's on the same X display and
- use the GUI, then to avoid all of the x11vnc's simultaneously
- answering the gui you will need to use something like "-connect file1
- -gui ..." with different connect files for each x11vnc you want to
- control via the gui (or remote-control.) The "-connect file1" usage
- gives separate communication channels between a x11vnc process and the
- gui process. Otherwise they all share the same X property channels:
- VNC_CONNECT and X11VNC_REMOTE.
-
- Update: As of Mar/2005 x11vnc now scales the mouse cursor with the
- same scale factor as the screen. If you don't want that, use the
- "-scale_cursor frac" option to set the cursor scaling to a different
- factor (e.g. use "-scale_cursor 1" to keep the cursor at its natural
- unscaled size.)
-
-
- Q-101: Does x11vnc work with Xinerama? (i.e. multiple monitors joined
- together to form one big, single screen.)
-
- Yes, it should generally work because it simply polls the big
- effective screen.
-
- If the viewing-end monitor is not as big as the remote Xinerama
- display, then the vncviewer scrollbars, etc, will have to be used to
- pan across the large area. However one user started two x11vnc's, one
- with "-clip 1280x1024+0+0" and the other with "-clip 1280x1024+1280+0"
- to split the big screen into two and used two VNC viewers to access
- them.
-
- As of Jun/2008: Use "-clip xinerama0" to clip to the first xinerama
- sub-screen (if xinerama is active.) xinerama1 for the 2nd sub-screen,
- etc. This way you don't need to figure out the WxH+X+Y of the desired
- xinerama sub-screen. screens are sorted in increasing distance from
- the (0,0) origin (I.e. not the Xserver's order.)
-
- There are a couple potential issues with Xinerama however. If the
- screen is not rectangular (e.g. 1280x1024 and 1024x768 monitors joined
- together), then there will be "non-existent" areas on the screen. The
- X server will return "garbage" image data for these areas and so they
- may be distracting to the viewer. The -blackout x11vnc option allows
- you to blacken-out rectangles by manually specifying their WxH+X+Y
- geometries. If your system has the libXinerama library, the -xinerama
- x11vnc option can be used to have it automatically determine the
- rectangles to be blackened out. (Note on 8bpp PseudoColor displays the
- fill color may not be black.) Update: -xinerama is now on by default.
-
- Some users have reported that the mouse does not behave properly for
- their Xinerama display: i.e. the mouse cannot be moved to all regions
- of the large display. If this happens try using the -xwarppointer
- option. This instructs x11vnc to fake mouse pointer motions using the
- XWarpPointer function instead of the XTestFakeMotionEvent XTEST
- function. (This may be due to a bug in the X server for XTEST when
- Xinerama is enabled.) Update: As of Dec/2006 -xwarppointer will be
- applied automatically if Xinerama is detected. To disable use:
- -noxwarppointer
-
-
- Q-102: Can I use x11vnc on a multi-headed display that is not Xinerama
- (i.e. separate screens :0.0, :0.1, ... for each monitor)?
-
- You can, but it is a little bit awkward: you must start separate
- x11vnc processes for each screen, and on the viewing end start up
- separate VNC viewer processes connecting to them. e.g. on the remote
- end:
- x11vnc -display :0.0 -bg -q -rfbport 5900
- x11vnc -display :0.1 -bg -q -rfbport 5901
-
- (this could be automated in the display manager Xsetup for example)
- and then on the local machine where you are sitting:
- vncviewer somehost:0 &
- vncviewer somehost:1 &
-
- Note: if you are running on Solaris 8 or earlier you can easily hit up
- against the maximum of 6 shm segments per process (for Xsun in this
- case) from running multiple x11vnc processes. You should modify
- /etc/system as mentioned in another FAQ to increase the limit. It is
- probably also a good idea to run with the -onetile option in this case
- (to limit each x11vnc to 3 shm segments), or even -noshm to use no shm
- segments.
-
-
- Q-103: Can x11vnc show only a portion of the display? (E.g. for a
- special purpose application or a very large screen.)
-
- As of Mar/2005 x11vnc has the "-clip WxH+X+Y" option to select a
- rectangle of width W, height H and offset (X, Y). Thus the VNC screen
- will be the clipped sub-region of the display and be only WxH in size.
- One user used -clip to split up a large Xinerama screen into two more
- managable smaller screens.
-
- This also works to view a sub-region of a single application window if
- the -id or -sid options are used. The offset is measured from the
- upper left corner of the selected window.
-
-
- Q-104: Does x11vnc support the XRANDR (X Resize, Rotate and
- Reflection) extension? Whenever I rotate or resize the screen x11vnc
- just seems to crash.
-
- As of Dec/2004 x11vnc supports XRANDR. You enable it with the -xrandr
- option to make x11vnc monitor XRANDR events and also trap X server
- errors if the screen change occurred in the middle of an X call like
- XGetImage. Once it traps the screen change it will create a new
- framebuffer using the new screen.
-
- If the connected vnc viewers support the NewFBSize VNC extension
- (Windows TightVNC viewer and RealVNC 4.0 windows and Unix viewers do)
- then the viewer will automatically resize. Otherwise, the new
- framebuffer is fit as best as possible into the original viewer size
- (portions of the screen may be clipped, unused, etc.) For these
- viewers you can try the -padgeom option to make the region big enough
- to hold all resizes and rotations. We have fixed this problem for the
- TightVNC Viewer on Unix: SSVNC
-
- If you specify "-xrandr newfbsize" then vnc viewers that do not
- support NewFBSize will be disconnected before the resize. If you
- specify "-xrandr exit" then all will be disconnected and x11vnc will
- terminate.
-
-
- Q-105: Independent of any XRANDR, can I have x11vnc rotate and/or
- reflect the screen that the VNC viewers see? (e.g. for a handheld
- whose screen is rotated 90 degrees.)
-
- As of Jul/2006 there is the -rotate option allow this. E.g's: "-rotate
- +90", "-rotate -90", "-rotate x", etc.
-
-
- Q-106: Why is the view in my VNC viewer completely black? Or why is
- everything flashing around randomly?
-
- See the next FAQ for a possible explanation.
-
-
- Q-107: I use Linux Virtual Terminals (VT's) to implement 'Fast User
- Switching' between users' sessions (e.g. Betty is on Ctrl-Alt-F7,
- Bobby is on Ctrl-Alt-F8, and Sid is on Ctrl-Alt-F1: they use those
- keystrokes to switch between their sessions.) How come the view in a
- VNC viewer connecting to x11vnc is either completely black or
- otherwise all messed up unless the X session x11vnc is attached to is
- in the active VT?
-
- This seems to have to do with how applications (the X server processes
- in this case) must "play nicely" if they are not on the active VT
- (sometimes called VC for virtual console.) That is, they should not
- read from the keyboard or mouse or manage the video display unless
- they have the active VT. Given that it appears the XGetImage() call
- must ultimately retrieve the framebuffer data from the video hardware
- itself, it would make sense x11vnc's polling wouldn't work unless the
- X session had active control of the VT.
-
- There does not seem to be an easy way to work around this. Even xwd(1)
- doesn't work in this case (try it.) Something would need to be done at
- a lower level, say in the XFree86/Xorg X server. Also, using the
- Shadow Framebuffer (a copy of the video framebuffer is kept in main
- memory) does not appear to fix the problem.
-
- If no one is sitting at the workstation and you just want to remotely
- switch the VT over to the one associated with your X session (so
- x11vnc can poll it correctly), one can use the chvt(1) command, e.g.
- "chvt 7" for VT #7.
-
-
- Q-108: I am using x11vnc where my local machine has "popup/hidden
- taskbars" and the remote display where x11vnc runs also has
- "popup/hidden taskbars" and they interfere and fight with each other.
- What can I do?
-
- When you move the mouse to the edge of the screen where the popups
- happen, the taskbars interfere with each other in strange ways. This
- sometimes happens where the local machine is GNOME or Mac OS X and the
- remote machine is GNOME. Is there a way to temporarily disable one or
- both of these magic desktop taskbars?
-
- One x11vnc user suggests: it should be straightforward to right mouse
- click on the task bar panel, and uncheck "enable auto-hide" from the
- panel properties dialog box. This will make the panel always visible.
-
- Q-109: Help! x11vnc and my KDE screensaver keep switching each other
- on and off every few seconds.
-
- This is a new (Jul/2006) problem seen, say, on the version of KDE that
- is shipped with SuSE 10.1. It is not yet clear what is causing this...
- If you move the mouse through x11vnc the screensaver shuts off like it
- should but then a second or two after you stop moving the mouse the
- screensaver snaps back on.
-
- This may be a bug in kdesktop_lock. For now the only workaround is to
- disable the screensaver. You can try using another one such as
- straight xscreensaver (see the instructions here for how to disable
- kdesktop_lock.) If you have more info on this or see it outside of KDE
- please let us know.
-
- Update: It appears this is due to kdesktop_lock enabling the screen
- saver when the Monitor is in DPMS low-power state (e.g. standby,
- suspend, or off.) In Nov/2006 the x11vnc -nodpms option was added as a
- workaround. Normally it is a good thing that the monitor powers down
- (since x11vnc can still poll the framebuffer in this state), but if
- you experience the kdesktop_lock problem you can specify the "-nodpms"
- option to keep the Monitor out of low power state while VNC clients
- are connected. This is basically the same as typing "xset dpms force
- on" periodically. (if you don't want to do these things just disable
- the screensaver.) Feel free to file a bug against kdesktop_lock with
- KDE.
-
- Q-110: I am running the compiz 3D window manager (or beryl, MythTv,
- Google Earth, or some other OpenGL app) and I do not get screen
- updates in x11vnc.
-
- This appears to be because the 3D OpenGL/GLX hardware screen updates
- do not get reported via the XDAMAGE mechanism. So this is a bug in
- compiz/beryl or XDAMAGE/Xorg or the (possibly 3rd party) video card
- driver.
-
- As a workaround apply the -noxdamage option. As of Feb/2007 x11vnc
- will try to autodetect the problem and disable XDAMAGE if is appears
- to be missing a lot of updates. But if you know you are using compiz
- you might as well always supply -noxdamage. Thanks to this user who
- reported the problem and discovered the workaround.
-
- A developer for MiniMyth reports that the 'alphapulse' tag of the
- theme G.A.N.T. can also cause problems, and should be avoided when
- using VNC.
-
- Please report a bug or complaint to Beryl/Compiz and/or Xorg about
- this: running x11vnc with -noxdamage disables a nice improvement in
- responsiveness (especially for typing) and also leads to unnecessary
- CPU and memory I/O load due to the extra polling.
-
- Update: as of May/2010 NVIDIA may have fixed this problem in their
- proprietary drivers. See the NVIDIA Release Notes. (look for
- 'x11vnc'.)
-
- Q-111: Can I use x11vnc to view my VMWare session remotely?
-
- Yes, since VMWare usually runs as an X application you can view it via
- x11vnc in the normal way.
-
- Note that VMWare has several viewing modes:
- * Normal X application window (with window manager frame)
- * Quick-Switch mode (with no window manager frame)
- * Fullscreen mode
-
- The way VMWare does Fullscreen mode on Linux is to display the Guest
- desktop in a separate Virtual Terminal (e.g. VT 8) (see this FAQ on
- VT's for background.) Unfortunately, this Fullscreen VT is not an X
- server. So x11vnc cannot access it (however, see this discussion of
- -rawfb for a possible workaround.) x11vnc works fine with "Normal X
- application window" and "Quick-Switch mode" because these use X.
-
- Update: It appears the in VMWare 5.x the Fullscreen mode is X, so
- x11vnc access does work.
-
- One user reports he left his machine with VMWare in the Fullscreen
- mode, and even though his X session wasn't in the active VT, he could
- still connect x11vnc to the X session and pass the keystrokes Ctrl-Alt
- (typing "blind") to the VMWare X app. This induced VMWare to switch
- out of Fullscreen into Normal X mode and he could continue working in
- the Guest desktop remotely.
-
-
- Aside: Sometimes it is convenient (for performance, etc.) to start
- VMWare in its own X session using startx(1). This can be used to have
- a minimal window manger (e.g. twm or even no window manager), to
- improve response. One can also cut the display depth (e.g. to 16bpp)
- in this 2nd X session to improve video performance. This 2nd X session
- emulates Fullscreen mode to some degree and can be viewed via x11vnc
- as long as the VMWare X session is in the active VT.
-
- Also note that with a little bit of playing with "xwininfo -all
- -children" output one can extract the (non-toplevel) window-id of the
- of the Guest desktop only when VMWare is running as a normal X
- application. Then one can export just the guest desktop (i.e. without
- the VMWare menu buttons) by use of the -id windowid option. The
- caveats are the X session VMWare is in must be in the active VT and
- the window must be fully visible, so this mode is not terribly
- convenient, but could be useful in some circumstances (e.g. running
- VMWare on a very powerful server machine in a server room that happens
- to have a video card, (but need not have a monitor, Keyboard or
- mouse).)
-
-
-
- [Exporting non-X11 devices via VNC]
-
- Q-112: Can non-X devices (e.g. a raw framebuffer) be viewed (and even
- controlled) via VNC with x11vnc?
-
- As of Apr/2005 there is support for this. Two options were added:
- "-rawfb string" (to indicate the raw frame buffer device, file, etc.
- and its parameters) and "-pipeinput command" (to provide an external
- program that will inject or otherwise process mouse and keystroke
- input.) Some useful -pipeinput schemes, VID, CONSOLE, and UINPUT, have
- since been built into x11vnc for convenience.
-
- This non-X mode for x11vnc is somewhat experimental because it is so
- removed in scope from the intended usage of the tool. Incomplete
- attempt is made to make all of the other options consistent with non-X
- framebuffer polling. So all of the X-related options (e.g.
- -add_keysyms, -xkb) are just ignored or may cause an error if used. Be
- careful applying such an option via remote control.
-
- The format for the -rawfb string is:
- -rawfb <type>:<object>@<W>x<H>x<bpp>[-<BPL>][:<R>/<G>/<B>][+<offset>]
-
- There are also some useful aliases (e.g. "console".) Some examples:
- -rawfb shm:210337933@800x600x32:ff/ff00/ff0000
-
- -rawfb map:/dev/fb0@1024x768x16
-
- -rawfb map:/tmp/Xvfb_screen0@640x480x8+3232
-
- -rawfb file:/tmp/my.pnm@250x200x24+37
-
- -rawfb file:/dev/urandom@128x128x8
-
- -rawfb snap:/dev/video0@320x240x24 -24to32
-
- -rawfb console
-
- -rawfb vt2
-
- -rawfb video
-
- -rawfb setup:mycmd.sh
-
- So the type can be "shm" for shared memory objects, and "map" or
- "file" for file objects. "map" uses mmap(2) to map the file into
- memory and is preferred over "file" (that uses the slower lseek(2)
- access method.) Only use file if map isn't working. BTW, "mmap" is an
- alias for "map" and if you do not supply a type and the file exists,
- map is assumed (see the -help output and below for some exceptions to
- this.) The "snap:" setting applies the -snapfb option with "file:"
- type reading (this is useful for exporting webcams or TV tuner video;
- see the next FAQ for more info.)
-
- Also, if the string is of the form "setup:cmd" then cmd is run and the
- first line of its output retrieved and used as the rawfb string. This
- allows initializing the device, determining WxHxB, etc.
-
- The object will be the numerical shared memory id for the case of shm.
- The idea here is some other program has created this shared memory
- segment and periodically updates it with new framebuffer data. x11vnc
- polls the area for changes. See shmat(2) and ipcs(8) for more info.
- The ipcs command will list current shared memory segments on the
- system. Sometimes you can snoop on a program's framebuffer it did not
- expect you would be polling!
-
- The object will be the path to the regular or character special file
- for the cases of map and file. The idea here is that in the case of a
- regular file some other program is writing/updating framebuffer image
- data to it. In the case of a character special (e.g. /dev/fb0) it is
- the kernel that is "updating" the framebuffer data.
-
- In most cases x11vnc needs to be told the width, height, and number of
- bits per pixel (bpp) of the framebuffer. This is the @WxHxB field. For
- the case of the Linux framebuffer device, /dev/fb0, the fbset(8) may
- be of use (but may not always be accurate for what is currently
- viewable.) In general some guessing may be required, especially for
- the bpp. Update: in "-rawfb console" mode x11vnc will use the linuxfb
- API to try to guess (it is still not always accurate.) Also try
- "-rawfb vtN" (on x11vnc 0.9.7 and later) for the N-th Linux text
- console (aka virtual terminal.) If the number of Bytes Per Line is not
- WxHxB/8 (i.e. the framebuffer lines are padded) you can specify this
- information after WxHxB via "-BPL", e.g. @800x600x16-2048
-
- Based on the bpp x11vnc will try to guess the red, green, and blue
- masks (these indicate which bits correspond to each color.) It if gets
- it wrong you can specify them manually via the optional ":R/G/B"
- field. E.g. ":0xff0000/0x00ff00/0x0000ff" (this is the default for
- 32bpp.)
-
- Finally, the framebuffer may not begin at the beginning of the memory
- object, so use the optional "+offset" parameter to indicate where the
- framebuffer information starts. So as an example, the Xvfb virtual
- framebuffer has options -shmem and -fbdir for exporting its virtual
- screen to either shm or a mapped file. The format of these is XWD and
- so the initial header should be skipped. BTW, since XWD is not
- strictly RGB the view will only be approximate, but usable. Of course
- for the case of Xvfb x11vnc can poll it much better via the X API, but
- you get the idea.
-
- By default in -rawfb mode x11vnc will actually close any X display it
- happened to open. This is basically to shake out bugs (e.g it will
- crash rather than mysteriously interacting with the X display.) If you
- want x11vnc to keep the X display open while polling the raw
- framebuffer prefix a "+" sign at the beginning of the string (e.g.
- +file:/dev/urandom@64x64x8) This could be convenient for keeping the
- remote control channel active (it uses X properties.) The "-connect
- /path/to/file" mechanism could also be used for remote control to
- avoid the X property channel. Rare usage, but if you also supply
- -noviewonly in this "+" mode then the mouse and keyboard input are
- still sent to the X display, presumably for doing something amusing
- with /dev/fb...
-
- Interesting Devices:. Here are some aliases for interesting device
- files that can be polled via -rawfb:
- -rawfb console /dev/fb0 Linux Console
- -rawfb vt2 /dev/vcsa2 Linux Console (e.g. virtual ter
-minal #2)
- -rawfb video /dev/video0 Video4Linux Capture device
- -rawfb rand /dev/urandom Random Bytes
- -rawfb null /dev/zero Zero Bytes (black screen)
-
- The Linux console, /dev/fb0, etc needs to have its driver enabled in
- the kernel. Some of the drivers are video card specific and
- accelerated. The console is either the Text consoles (usually
- tty1-tty6), or X graphical display (usually starting at tty7.) In
- addition to the text console other graphical ones may be viewed and
- interacted with as well, e.g. DirectFB or SVGAlib apps, VMWare non-X
- fullscreen, or Qt-embedded apps (PDAs/Handhelds.) By default the
- pipeinput mechanisms UINPUT and CONSOLE (keystrokes only) are
- automatically attempted in this mode under "-rawfb console".
-
- The Video4Linux Capture device, /dev/video0, etc is either a Webcam or
- a TV capture device and needs to have its driver enabled in the
- kernel. See this FAQ for details. If specified via "-rawfb Video" then
- the pipeinput method "VID" is applied (it lets you change video
- parameters dynamically via keystrokes.)
-
- The last two, /dev/urandom and /dev/zero are just for fun, but are
- also useful in testing.
-
-
- All of the above -rawfb options are just for viewing the raw
- framebuffer (although some of the aliases do imply keystroke and mouse
- pipeinput methods.) That may be enough for certain applications of
- this feature (e.g. suppose a video camera mapped its framebuffer into
- memory and you just wanted to look at it via VNC.)
- To handle the pointer and keyboard input from the viewer users the
- "-pipeinput cmd" option was added to indicate a helper program to
- process the user input. The input is streamed to it and looks
- something like this:
- Pointer 1 205 257 0 None
- Pointer 1 198 253 0 None
- Pointer 1 198 253 1 ButtonPress-1
- Pointer 1 198 253 0 ButtonRelease-1
- Pointer 1 198 252 0 None
- Keysym 1 1 119 w KeyPress
- Keysym 1 0 119 w KeyRelease
- Keysym 1 1 65288 BackSpace KeyPress
- Keysym 1 0 65288 BackSpace KeyRelease
- Keysym 1 1 112 p KeyPress
- Keysym 1 0 112 p KeyRelease
-
- Run "-pipeinput tee:/bin/cat" to get a description of the format. Note
- that the -pipeinput option is independent of -rawfb mode and so may
- have some other interesting uses. The "tee:" prefix means x11vnc will
- both process the user input and pipe it to the command. The default is
- to just pipe it to the -pipeinput command.
-
- Note the -pipeinput helper program could actually control the raw
- framebuffer. In the libvncserver CVS a simple example program
- x11vnc/misc/slide.pl is provided that demonstrates a simple jpeg
- "slideshow" application. Also the builtin "-pipeinput VID" mode does
- this for webcams and TV capture devices (/dev/video0.)
-
- The -pipeinput program is run with these environment variables set:
- X11VNC_PID, X11VNC_PROG, X11VNC_CMDLINE, X11VNC_RAWFB_STR to aid its
- knowing what is up.
-
- Another example provided in libvncserver CVS is a script to inject
- keystrokes into the Linux console (e.g. the virtual consoles:
- /dev/tty1, /dev/tty2, etc) in x11vnc/misc/vcinject.pl. It is based on
- the vncterm/LinuxVNC.c program also in the libvncserver CVS. So to
- view and interact with VT #2 (assuming it is the active VT) one can
- run something like:
- x11vnc -rawfb map:/dev/fb0@1024x768x16 -pipeinput './vcinject.pl 2'
-
- This assumes your Linux framebuffer device (/dev/fb0) is properly
- configured. See fbset(8) and other documentation. Try
- "file:/dev/fb0@WxHxB" as a last resort. Starting with x11vnc 0.8.1,
- the above VT injection is built in, as well as WxHxB determination.
- Just use something like:
- x11vnc -rawfb console
-
- this will try to guess the active virtual console (via /dev/tty0) and
- also the /dev/fb0 WxHxB and rgb masks automatically. Use, e.g.,
- "-rawfb console3" to force the VT number. This input method can be
- used generally via "-pipeinput CONSOLE". Also starting with x11vnc
- 0.8.2 the "-pipeinput UINPUT" mode is tried first (it does both
- keyboard and mouse input) and then falls back to CONSOLE mode if it is
- not available. Here is the -help output for this mode:
-
- 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 (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 may 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".
-
- The string "/dev/fb0" (1, etc) can be used instead of "console".
- This can be used to specify a different framebuffer device, e.g.
- /dev/fb1. As a shortcut the "/dev/" can be dropped. If the name is
- something nonstandard, use "console:/dev/foofb"
-
- 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.
-
- The above is just an example of what can be done. Note that if you
- really want to view and interact with the Linux Text console it is
- better to use the more accurate and faster LinuxVNC program. The
- advantage x11vnc -rawfb might have is that it can allow interaction
- with a non-text application, e.g. one based on SVGAlib or Qt-embedded
- Also, for example the VMWare Fullscreen mode is actually viewable
- under -rawfb and can be interacted with if uinput is enabled.
-
- If the Linux uinput driver is available then full keystroke and mouse
- input into the Linux console can be performed. You may be able to
- enable uinput via commands like these:
- modprobe uinput
- mknod /dev/input/uinput c 10 223
-
- The -rawfb and -pipeinput features are intended to help one creatively
- "get out of a jam" (say on a legacy or embedded device) where X is
- absent or doesn't work properly. Feedback and bug reports are welcome.
- For more control and less overhead use libvncserver in your own C
- program that passes the framebuffer to libvncserver.
-
-
- Q-113: Can I export the Linux Console (Virtual Terminals) via VNC
- using x11vnc?
-
- Yes, you may need to be root to access the devices that make up the
- linux console.
-
- To access the active Linux console via the computer's framebuffer try
- something like:
- x11vnc -rawfb console
- x11vnc -rawfb console2
-
- These will try to access the framebuffer through /dev/fb (or /dev/fb0,
- etc.) and if it succeeds it will show any text or graphics that is
- currently displayed. Keystrokes will be injected via the device
- /dev/tty0 (to force an explicit virtual terminal append a number, e.g.
- "console2" to select /dev/tty2.)
-
- If your Linux system does not have a framebuffer device (/dev/fb) you
- can get one by adding, e.g., vga=0x31B boot parameter. This enables
- the VGA framebuffer device at 1280x1024x24. 0x317 gives 1024x768x16,
- etc. You can also enable a Linux framebuffer device by modprobing a
- framebuffer driver specific to your video card.
-
- Note that this "-rawfb console" mode shows the contents of the
- hardware framebuffer, and so will show whatever is on the screen. It
- has no concept of Virtual Terminals WRT what there is to view, it
- always shows the active virtual terminal.
-
- Another mode is specific to the Linux text Virtual Terminals, it shows
- their text and colors (but no graphics) regardless of whether it is
- the active VT or not. It is available on x11vnc 0.9.7 and later.
- Enable this mode like this:
- x11vnc -rawfb vt
- x11vnc -rawfb vt2
-
- The former will select the active one, the latter the 2nd VT. x11vnc
- implements this mode by opening the current console text file
- "/dev/vcsa2" instead of "/dev/fb". In this way it provides the basic
- functionality of the LibVNCServer LinuxVNC program.
-
- The vt mode can be a useful way to try to get a machine's X server
- working remotely, e.g. you edit /etc/X11/xorg.conf and then type
- startx (or similar, e.g. gdm) in the virtual terminal. A 2nd x11vnc
- could be used to see if the X server is now working correctly.
-
- Q-114: Can I export via VNC a Webcam or TV tuner framebuffer using
- x11vnc?
-
- Yes, this is possible to some degree with the -rawfb option. There is
- no X11 involved: snapshots from the video capture device are used for
- the screen image data. See the previous FAQ on -rawfb for background.
- For best results, use x11vnc version 0.8.1 or later.
-
- Roughly, one would do something like this:
- x11vnc -rawfb snap:/dev/video@320x240x32
-
- This requires that the system allows simple read(2) access to the
- video device. This is true for video4Linux on Linux kernel 2.6 and
- later (it won't work for 2.4, you'll need a separate program to
- snapshot to a file that you point -rawfb to; ask me if it is not clear
- what to do.)
-
- The "snap:" enforces -snapfb mode which appears to be necessary. The
- read pointer for video capture devices cannot be repositioned (which
- would be needed for scanline polling), but you can read a full frame
- of data from the device.
-
- On Linux, if the Video4Linux API is present or the v4l-info(1) program
- (related to xawtv) exists in in PATH, then x11vnc can be instructed to
- try it to determine the -rawfb WxHxB parameters for you automatically.
- In this case one would just type:
- x11vnc -rawfb video
-
- or "-rawfb video1" for the 2nd video device, etc.
-
- x11vnc has also been extended to use the Video4Linux API over v4l-info
- if it is available at build time. This enables setting parameters
- (e.g. size and brightness) via x11vnc. See the description below.
- Without Video4Linux you will need to initialize the settings of the
- video device using something like xawtv or spcaview (and then hope the
- settings persist until x11vnc reopens the device.)
-
- Many video4linux drivers tend to set the framebuffer to be 24bpp (as
- opposed to 32bpp.) Since this can cause problems with VNC viewers,
- etc, the -24to32 option will be automatically imposed when in 24bpp.
-
- Note that by its very nature, video capture involves rapid change in
- the framebuffer. This is especially true for cameras where slight
- wavering in brightness is always happening. This can lead to much
- network bandwidth consumption for the VNC traffic and also local CPU
- and I/O resource usage. You may want to experiment with "dialing down"
- the framerate via the -wait, -slow_fb, or -defer options. Decreasing
- the window size and bpp also helps.
-
-
- Setting Camera/Tuner parameters via x11vnc:
-
- There is also some support for setting parameters of the capture
- device. This is done via "-rawfb video:<settings>". This could be
- useful for unattended startup at boottime, etc. Here is the -help
- description:
-
- A more sophisticated video device scheme allows initializing the
- device's settings using:
-
- -rawfb video:<settings>
-
- The prefix could also be, as above, e.g. "video1:" to specify the
- device file. The v4l API must be available for this to work.
- Otherwise, you will need to try to initialize the device with an
- external program, e.g. xawtv, spcaview, and hope they persist when
- x11vnc re-opens the device.
-
- <settings> is a comma separated list of key=value pairs. The
- device's brightness, color, contrast, and hue can be set to
- percentages, e.g. br=80,co=50,cn=44,hu=60.
-
- The device filename can be set too if needed (if it does not start
- with "video"), e.g. fn=/dev/qcam.
-
- The width, height and bpp of the framebuffer can be set via, e.g.,
- w=160,h=120,bpp=16.
-
- Related to the bpp above, the pixel format can be set via the
- fmt=XXX, where XXX can be one of: GREY, HI240, RGB555, RGB565,
- RGB24, and RGB32 (with bpp 8, 8, 16, 16, 24, and 32 respectively.)
- See http://www.linuxtv.org for more info (V4L api.)
-
- For TV/rf tuner cards one can set the tuning mode via tun=XXX where
- XXX can be one of PAL, NTSC, SECAM, or AUTO.
-
- One can switch the input channel by the inp=XXX setting, where XXX
- is the name of the input channel (Television, Composite1, S-Video,
- etc.) Use the name that is in the information about the device that
- is printed at startup.
-
- For input channels with tuners (e.g. Television) one can change
- which station is selected by the sta=XXX setting. XXX is the
- station number. Currently only the ntsc-cable-us (US cable)
- channels are built into x11vnc. See the -freqtab option below to
- supply one from xawtv. If XXX is greater than 500, then it is
- interpreted as a raw frequency in KHz.
-
- Example:
-
- -rawfb video:br=80,w=320,h=240,fmt=RGB32,tun=NTSC,sta=47
-
- one might need to add inp=Television too for the input channel to
- be TV if the card doesn't come up by default in that one.
-
- Note that not all video capture devices will support all of the
- above settings.
-
- See the -pipeinput VID option below for a way to control the
- settings through the VNC Viewer via keystrokes.
-
- As above, if you specify a "@WxHxB..." after the <settings> string
- they are used verbatim: the device is not queried for the current
- values. Otherwise the device will be queried.
-
- Also, if you supply the "-pipeinput VID" (or use "-rawfb Video")
- option you can control the settings to some degree via keystroke
- mappings, e.g. B to increase the brightness or Up arrow to change the
- TV station:
-
- For "-pipeinput VID" and you are using the -rawfb for a video
- capture device, then an internal list of keyboard mappings is used
- to set parameters of the video. The mappings are:
-
- "B" and "b" adjust the brightness up and down.
- "H" and "h" adjust the hue.
- "C" and "c" adjust the colour.
- "N" and "n" adjust the contrast.
- "S" and "s" adjust the size of the capture screen.
- "I" and "i" cycle through input channels.
- Up and Down arrows adjust the station (if a tuner)
- F1, F2, ..., F6 will switch the video capture pixel
- format to HI240, RGB565, RGB24, RGB32, RGB555, and
- GREY respectively. See -rawfb video for details.
-
- See also the -freqtab option to supply your own xawtv channel to
- frequency mappings for your country (only ntsc-cable-us is built into
- x11vnc.)
-
-
- Q-115: Can I connect via VNC to a Qt-embedded/Qt-enhanced/Qtopia
- application running on my handheld, cell phone, or PC using the Linux
- console framebuffer (i.e. not X11)?
-
- Yes, the basic method for this is the -rawfb scheme where the Linux
- console framebuffer (usually /dev/fb0) is polled and the uinput driver
- is used to inject keystrokes and mouse input. Often you will just have
- to type:
- x11vnc -rawfb console
-
- (you may need to enable the uinput driver on the system via "modprobe
- uinput; mknod /dev/input/uinput c 10 223") If this does not find the
- correct frame buffer properties figure them out or guess them and use
- something like:
- x11vnc -rawfb /dev/fb0@640x480x16
-
- Also, to force usage of the uinput injection method use "-pipeinput
- UINPUT". See the -pipeinput description for tunable parameters, etc.
-
- One problem with the x11vnc uinput scheme is that it cannot guess the
- mouse motion "acceleration" used by the windowing application (e.g.
- QWS or X11.) For X11 and Qt-embedded the acceleration is usually 2
- (i.e. a dx of 1 from the mouse yields a 2 pixel displacement of the
- mouse cursor.) The default x11vnc uses is 2, since that is often used.
- However for one Qt-embedded system we needed to do:
- x11vnc -rawfb console -pipeinput UINPUT:accel=4.0
-
- to get reasonable positioning of the mouse.
-
- Even with the correct acceleration setting there is still some drift
- (probably because of the mouse threshold where the acceleration kicks
- in) and so x11vnc needs to reposition the cursor from 0,0 about 5
- times a second. See the -pipeinput UINPUT option for tuning parameters
- that can be set (there are some experimental thresh=N tuning
- parameters as well)
-
- Currently, one can expect mouse input to be a little flakey. All in
- all, the Linux framebuffer input mechanism for Qt-embedded framebuffer
- apps is not perfect, but it is usable.
-
- If you need to create a smaller x11vnc binary for a handheld
- environment be sure to run strip(1) on it and also consider
- configuring with, e.g. "env CPPFLAGS='-DSMALL_FOOTPRINT=1' ./configure
- ..." to remove rarely used features and large texts (use 2 or 3
- instead of 1 to remove more.) Currently (Jul/2006) this can lower the
- size of the x11vnc from 1.1MB to 0.6-0.7MB.
-
- The x11vnc uinput method applies to nearly anything on the Linux
- framebuffer console, not just Qt-embedded/Qtopia. DirectFB, SDL using
- fbcon driver, SVGAlib applications can also be viewed and interacted
- with. Even a Linux X session can be viewed and interacted with without
- using X11 (and x11vnc does not have to terminate when the X server
- restarts!) The Linux Text consoles (F1-F6) also work.
-
- Note that Qt-embedded supplies its own VNC graphics driver, but it
- cannot do both the Linux console framebuffer and VNC at the same time,
- which is often what is desired from VNC.
-
- Update: We are finding some setups like Qtopia on the IPAQ do not
- allow mouse input via uinput. Please help us debug this problem by
- trying x11vnc on your device and letting us know what does and does
- not work. See the next FAQ for a possible workaround for touchscreens.
-
-
- Q-116: How do I inject touch screen input into an
- Qt-embedded/Qt-enhanced/Qtopia cell phone such as openmoko/qtmoko Neo
- Freerunner?
-
- The qtmoko project does not use X11 for the graphical display.
- Unfortunately the Linux uinput method described in the previous FAQ
- does not work because Qt is using TSLIB (touch screen library) to
- process the input and it only reads from one device (often
- /dev/input/event1) and not from the new UINPUT device that x11vnc
- creates (under -pipeinput UINPUT)
-
- So something else needs to be done. It was discovered that by simply
- writing the touchscreen events directly to /dev/input/event1 then
- input can be injected into the system. There is no x11vnc builtin mode
- for this yet (until we understand it better), but there is a working
- script provided in x11vnc/misc/qt_tslib_inject.pl. So one could use it
- this way for example:
- x11vnc ... -rawfb console -pipeinput path/to/qt_tslib_inject.pl -env INJECT_O
-PTIONS=clickonly,cal=/etc/pointercal
-
- Read the script for how to enable other options and what the above
- options mean (e.g. /etc/pointercal contains TSLIB's calibration
- parameters and are necessary to achieve accurate pointing.)
-
- The x11vnc/misc/qt_tslib_inject.pl script can potentially be modified
- to handle other devices where the uinput method fails. It could also
- be modified to create 'hot keys', etc.
-
- Please let us know how things go if you try this out; there is much to
- learn about synthetic input injection in handhelds and cell phones. As
- we learn more we can develop a builtin x11vnc mode for this sort of
- injection.
-
- Update Dec/2010: There is experimental built-in UINPUT support in the
- x11vnc development tarball for qtmoko with touchpad managed by tslib.
- See -pipeinput UINPUT for more info. Here is an example:
- x11vnc -rawfb console -pipeinput UINPUT:touch,tslib_cal=/etc/pointercal,dire
-ct_abs=/dev/input/event1,nouinput,dragskip=3
-
-
- Q-117: Now that non-X11 devices can be exported via VNC using x11vnc,
- can I build it with no dependencies on X11 header files and libraries?
-
- Yes, as of Jul/2006 x11vnc enables building for -rawfb only support.
- Just do something like when building:
- ./configure --without-x (plus any other flags)
- make
-
- You can then test via "ldd x11vnc" that the binary does not depend on
- libX11.so, etc. See the previous FAQ's for non-X11 framebuffer usage.
- If you use this for an interesting non-X11 application please let us
- know what you did.
-
-
- Q-118: How do I cross compile x11vnc for a different architecture than
- my Linux i386 or amd64 PC?
-
- You will need a cross-compiling toolchain. Perhaps your distro
- provides these or you can find a HOWTO for your distro. We found a
- nice one at qtmoko.org for building armel binaries on Debian Linux
- i386 machines. It includes most of the libraries that x11vnc needs. We
- use that example here.
-
- We ran this script to set PATH, configure, and build:
-#!/bin/sh
-
-# toolchain from: qtmoko-debian-toolchain-armv4t-eabi.tar.gz
-
-export PATH=/opt/toolchains/arm920t-eabi/bin:$PATH
-
-env CC=arm-linux-gcc ./configure --host=arm-linux --without-avahi
-
-make
-
-arm-linux-strip ./x11vnc/x11vnc
-ls -l ./x11vnc/x11vnc
-
- Note we had to include --without-avahi due to lack of
- libavahi-client.so.3 supplied by the toolchain we used. One would need
- to add it if it was desired on the target machine. We also stripped
- the binary to make it smaller.
-
- For an embedded system one may also want to add --without-x if the
- embedded system does not use X11 and the -rawfb mechanism must be
- used.
-
-
- Q-119: Does x11vnc support Mac OS X Aqua/Quartz displays natively
- (i.e. no X11 involved)?
-
- Yes, since Nov/2006 in the development tree (x11vnc-0.8.4 tarball)
- there is support for native Mac OS X Aqua/Quartz displays using the
- -rawfb mechanism described above. The mouse and keyboard input is
- achieved via Mac OS X API's.
-
- So you can use x11vnc as an alternative to OSXvnc (aka Vine Server),
- or Apple Remote Desktop (ARD). Perhaps there is some x11vnc feature
- you'd like to use on Mac OS X, etc. For a number of activities (e.g.
- window drags) it seems to be faster than OSXvnc.
-
- Notes:
-
- X11: x11vnc will also work (as it has for years) with a X11 server
- (XDarwin) running on Mac OS X (people often install this software to
- display remote X11 apps on their Mac OS X system, or use some old
- favorites locally such as xterm.) However in this case x11vnc will
- only work reasonably in single window -id windowid mode (and the
- window may need to have mouse focus.)
-
- If you do not have the DISPLAY env. variable set, x11vnc will assume
- native Aqua/Quartz on Mac OS X, however if DISPLAY is set it will
- assume an X11 connection. Use "-rawfb console" to force the native
- display (or unset DISPLAY.)
-
- Update: Leopard sets DISPLAY by default in all sessions. Since it
- starts with the string "/tmp/" x11vnc will use that to know if it
- should ignore it. Use "-display :0.0" to force it.
-
- Building: If you don't have the X11 build and runtime packages
- installed you will need to build it like this:
- (cd to the e.g. x11vnc-0.9, source directory)
- ./configure --without-x
- make
-
- Win2VNC/x2vnc: One handy use is to use the -nofb mode to redirect
- mouse and keyboard input to a nearby Mac (i.e. one to the side of your
- desk) via x2vnc or Win2VNC. See this FAQ for more info.
-
- Options: Here are the Mac OS X specific x11vnc options:
- -macnodim For the native Mac OS X server, disable dimming.
- -macnosleep For the native Mac OS X server, disable display sleep
-.
- -macnosaver For the native Mac OS X server, disable screensaver.
- -macnowait For the native Mac OS X server, do not wait for the
- user to switch back to his display.
- -macwheel n For the native Mac OS X server, set the mouse wheel
- speed to n (default 5.)
- -macnoswap For the native Mac OS X server, do not swap mouse
- buttons 2 and 3.
- -macnoresize For the native Mac OS X server, do not resize or rese
-t
- the framebuffer even if it is detected that the scree
-n
- resolution or depth has changed.
- -maciconanim n For the native Mac OS X server, set n to the number
- of milliseconds that the window iconify/deiconify
- animation takes. In -ncache mode this value will be
- used to skip the animation if possible. (default 400)
- -macmenu For the native Mac OS X server, in -ncache client-sid
-e
- caching mode, try to cache pull down menus (not perfe
-ct
- because they have animated fades, etc.)
-
- PasteBoard/Clipboard: There is a bug that the Clipboard (called
- PasteBoard on Mac it appears) exchange will not take place unless
- x11vnc was started from inside the Aqua display (e.g. started inside a
- Terminal app window.) Otherwise it cannot connect to the PasteBoard
- server. So Clipboard exchange won't work for our standard "ssh in"
- startup scheme.
-
- Hopefully this deficiency can be removed, but until then for Clipboard
- exchange to work you will need to start x11vnc inside the desktop
- session (i.e. either start it running before you leave, or start up a
- 2nd x11vnc inside from a 1st one started outside, or use the apple
- script below)
-
- Here also is a osascript trick that seems to work (it opens the
- Terminal app and instructs it to start x11vnc):
-
-#!/bin/sh
-#
-# start_x11vnc: start x11vnc in a Terminal window
-# (this will allow Clipboard/Pasteboard exchange to work)
-
-tmp=/tmp/start_x11vnc.$$
-
-cat > $tmp <<END
-
-tell application "Terminal"
- activate
- do script with command "$HOME/x11vnc -rfbauth .vnc/passwd -ssl SAVE"
-end tell
-
-END
-
-osascript $tmp
-rm -f $tmp
-
- where you should customize the x11vnc command line to your needs and
- the full path to the binary. Save it in a file e.g. "start_x11vnc" and
- then after you SSH in just type "./start_x11vnc" (or have ssh run the
- command for you.) Then once you are connected via VNC, iconify the
- Terminal windows (you can't delete them since that will kill x11vnc.)
-
- Update Aug/2010: A user reports the following useful information:
-This is not a problem on Mac OS X 10.6.x (Snow Leopard) when connecting
-via ssh to start x11vnc. And, on Mac OS X 10.5.x (Leopard), the problem
-can be permanently eliminated by doing this:
-
-
-sudo /usr/libexec/PlistBuddy -c 'delete :LimitLoadToSessionType' \
- -c 'add :LimitLoadToSessionType string Background' \
- /System/Library/LaunchAgents/com.apple.pboard.plist
-# ignore any 'Delete: Entry, ":LimitLoadToSessionType", Does Not Exist' message
-
-and then restarting (yes, you must restart not just log off). But
-ONLY do that for Mac OS X 10.5.x and NOT for 10.6.x (which doesn't
-need it anyway).
-
- We recently got access to a MacOSX 10.6.4 (Snow Leopard) macbook and
- have confirmed that the above is correct.
-
-
- Q-120: Can x11vnc be used as a VNC reflector/repeater to improve
- performance for the case of a large number of simultaneous VNC viewers
- (e.g. classroom broadcasting or a large demo)?
-
- Yes, as of Feb/2007 there is the "-reflect host:N" option to connect
- to the VNC server "host:N" (either another x11vnc or any other VNC
- server) and re-export it. VNC viewers then connect to the x11vnc(s)
- running -reflect.
-
- The -reflect option is the same as: "-rawfb vnc:host:N". See the
- -rawfb description under "VNC HOST" for more details.
-
- You can replace "host:N" with "listen" or "listen:port" for reverse
- connections.
-
- One can set up a number of such reflectors/repeaters to spread the
- resource usage around, e.g.:
- C -------<-------|
- C -------<-------|
- C -------<-------|---- R -----|
- C -------<-------| |
- C -------<-------| |
- |
- C -------<-------| |
- C -------<-------| |
- C -------<-------|---- R -----|
- C -------<-------| |
- C -------<-------| |
- |====== S
- C -------<-------| |
- C -------<-------| |
- C -------<-------|---- R -----|
- C -------<-------| |
- C -------<-------| |
- |
- C -------<-------| |
- C -------<-------| |
- C -------<-------|---- R -----|
- C -------<-------|
- C -------<-------|
-
- Where "S" is the original VNC Server, "C" denote VNC viewer clients,
- and "R" denotes an x11vnc running -reflect to "S".
-
- Ideally, a client "C" will be fairly close network-wise to its "R". It
- is fine to run the "R" on the same machine as one of its "C's". A nice
- setup for a large, (e.g. 64-128) viewer classroom broadcast case would
- be to run R's on areas isolated by network switches, e.g. one R per
- switch.
-
- In an extreme case (e.g. 1000 viewers) one might actually need a 2nd
- layer of R's in the tree. If you try something like that let us know!
-
- There are many resource savings in doing something like the above. The
- first obvious one is network bandwidth savings. Another is less CPU
- load on "S" since it handles many fewer simultaneous connections.
- Also, if there are a few clients C on very slow links, their presence
- does not slow down every other client, just the clients on their "R".
- One way a slow client affects things is if there are some large
- framebuffer writes (e.g. jpeg image region) then the repeater may
- block waiting for that large write to finish before going onto the
- next client (however, if the write is small enough, the kernel will
- buffer it and the server can go on to service the next client.)
-
- The x11vnc -reflect implementation uses the libvncclient library in
- the LibVNCServer project to handle the connection to "S". It is not
- currently very efficient since it simply does its normal framebuffer
- polling scheme on the libvncclient framebuffer (which it then
- re-exports via VNC to its clients C.) However, CopyRect and
- CursorShape encodings are preserved in the reflection and that helps.
- Dragging windows with the mouse can be a problem (especially if S is
- not doing wireframing somehow, consider -nodragging if the problem is
- severe) For a really fast reflector/repeater it would have to be
- implemented from scratch with performance in mind. See these other
- projects:
- http://sourceforge.net/projects/vnc-reflector/,
- http://www.tightvnc.com/projector/ (closed source?),
-
-
- Automation via Reverse Connections: Instead of having the R's
- connect directly to S and then the C's connect directly to the R they
- should use, some convenience can be achieved by using reverse
- connections (the x11vnc ""-connect host1,host2,..." option.) Suppose
- all the clients "C" are started up in Listen mode:
- client1> vncviewer -listen
- client2> vncviewer -listen
- client3> vncviewer -listen
- ...
- client64> vncviewer -listen
-
- (e.g. client1> is the cmdline prompt on machine client1 ... etc) and
- all the repeaters R are started like this:
- repeater1> x11vnc -reflect listen -connect client1,client2,...client8
- repeater2> x11vnc -reflect listen -connect client9,client10,...client16
- ...
- repeater8> x11vnc -reflect listen -connect client57,client58,...client64
-
- and finally the main server is started to kick the whole thing into
- motion:
- vncserver> x11vnc -display :0 -connect repeater1,repeater2,...repeater8
-
- (or instruct a non-x11vnc VNC server to reverse connect to the
- repeaters.) For a classroom broadcasting setup one might have the
- first two sets of commands start automatically at bootup or when
- someone logs in, and then start everything up with the S server. One
- may even be able to script the forward connection bootstrap case, let
- us know what you did. A really nice thing would be some sort of
- auto-discovery of your repeater, etc...
-
- Q-121: Can x11vnc be used during a Linux, Solaris, etc. system
- 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. 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. 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.
-
- During the install you need to get a shell to retreive x11vnc.static
- and run it.
-
- If the Solaris install is an older X-based one, there will be a menu
- for you to get a terminal window. From that window you might be able
- to retrieve x11vnc.static via wget, scp, or ftp. Remember to do "chmod
- 755 ./x11vnc.static" and then find the -auth file as in this FAQ.
-
- 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 via something like this:
- cd /tmp
- wget http://192.168.0.22/x11vnc.static
- chmod 755 ./x11vnc.static
-
- Find the name of the auth file as in this FAQ. (maybe run "ps wwaux |
- grep auth".) Then run it like this:
- ./x11vnc.static -forever -nopw -display :0 -auth /tmp/wherever/the/authfile
-
- then press Alt-F7 to go back to the X install. You should now be able
- 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 "-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 (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 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
- uinput, but it doesn't; one can wget uinput.ko and then run insmod on
- it, but the module must match the installation kernel. So, failing
- 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 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
- install console. You should be able to connect via a VNC viewer and
- watch the install.
- [Misc: Clipboard, File Transfer/Sharing, Printing, Sound, Beeps,
- Thanks, etc.]
-
- Q-122: Does the Clipboard/Selection get transferred between the
- vncviewer and the X display?
-
- As of Jan/2004 x11vnc supports the "CutText" part of the RFB (aka VNC)
- protocol. When text is selected/copied in the X session that x11vnc is
- polling it will be sent to connected VNC viewers. And when CutText is
- received from a VNC viewer then x11vnc will set the X11 selections
- PRIMARY, CLIPBOARD, and CUTBUFFER0 to it. x11vnc is able to hold the
- PRIMARY and CLIPBOARD selections (Xvnc does not seem to do this.)
-
- The X11 selections can be confusing, especially to those coming from
- Windows or MacOSX where there is just a single 'Clipboard'. The X11
- CLIPBOARD selection is a lot like that of Windows and MacOSX, e.g.
- highlighted text is sent to the clipboard when the user activates
- "Edit -> Copy" or presses "Control+C" (and pasting it via "Edit ->
- Paste" or "Control+V".) The X11 PRIMARY selection has been described
- as 'for power users' or 'an Easter Egg'. As soon as text is
- highlighted it is set to the PRIMARY selection and so it is
- immediately ready for pasting, usually via the Middle Mouse Button or
- "Shift+Insert". See this jwz link for more information.
-
- x11vnc's default behavior is to watch both CLIPBOARD and PRIMARY and
- whenever one of them changes, it sends the new text to connected
- viewers. Note that since the RFB protocol only has a single "CutText"
- then both selections are "merged" to some degree (and this can lead to
- confusing results.) One user was confused why x11vnc was "forgetting"
- his CLIPBOARD selection and the reason was he also changed PRIMARY
- some time after he copied text to the clipboard. Usually an app will
- set PRIMARY as soon as any text is highlighted so it easy to see how
- CLIPBOARD was forgotten. Use the -noprimary described below as a
- workaround. Similarly, by default when x11vnc receives CutText it sets
- both CLIPBOARD and PRIMARY to it (this is probably less confusing, but
- could possibly lead to some failure modes as well.)
-
- You may not like these defaults. Here are ways to change the behavior:
- * If you don't want the Clipboard/Selection exchanged at all use the
- -nosel option.
- * If you want changes in PRIMARY to be ignored use the -noprimary
- option.
- * If you want changes in CLIPBOARD to be ignored use the
- -noclipboard option.
- * If you don't want x11vnc to set PRIMARY to the "CutText" received
- from viewers use the -nosetprimary option.
- * If you don't want x11vnc to set CLIPBOARD to the "CutText"
- received from viewers use the -nosetclipboard option.
-
- You can also fine-tune it a bit with the -seldir dir option and also
- -input.
-
- You may need to watch out for desktop utilities such as KDE's
- "Klipper" that do odd things with the selection, clipboard, and
- cutbuffers.
-
-
- Q-123: Can I use x11vnc to record a Shock Wave Flash (or other format)
- video of my desktop, e.g. to record a tutorial or demo?
-
- 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
- pyvnc2swf. There are a number of tutorials (broken link?) 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
- parameters should be applied to x11vnc to speed up its polling for
- this sort of application, e.g. "-wait 10 -defer 10".
-
- Q-124: Can I transfer files back and forth with x11vnc?
-
- As of Oct/2005 and May/2006 x11vnc enables, respectively, the TightVNC
- and UltraVNC file transfer implementations that were added to
- libvncserver. This currently works with TightVNC and UltraVNC viewers
- (and Windows viewers only support filetransfer it appears... but they
- do work to some degree under Wine on Linux.)
-
- The 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 -tightfilexfer option.
-
- UltraVNC file transfer is off by default, to enable it use something
- like "-rfbversion 3.6 -permitfiletransfer"
- options (UltraVNC incorrectly uses the RFB protocol version to
- determine if its features are available, so x11vnc has to pretend to
- be version 3.6.) As of Sep/2006 "-ultrafilexfer" is an alias for these
- two options. Note that running as RFB version 3.6 may confuse other
- VNC Viewers.
-
- Sadly you cannot do both -tightfilexfer and -ultrafilexfer at the same
- time because the latter requires setting the version to 3.6 and
- tightvnc will not do filetransfer when it sees that version number.
-
- Also, because of the way the LibVNCServer TightVNC file transfer is
- implemented, you cannot do Tightvnc file transfer in -unixpw mode.
- However, UltraVNC file transfer does work in -unixpw (but if a client
- tries it do a filetransfer during the login process it will be
- disconnected.)
-
- 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 -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
- the gui or by -R remote control. However for TightVNC the changed
- setting only applies for NEW clients, current clients retain their
- TightVNC file transfer ability. For UltraVNC it works better, however
- if an UltraVNC client has initiated a file transfer dialog it will
- remain in effect until the dialog is closed. If you want to switch
- between UltraVNC and TightVNC file transfer in the gui or by remote
- control you will probably be foiled by the "-rfbversion 3.6" issue.
-
-
- Q-125: Which UltraVNC extensions are supported?
-
- Some of them are supported. To get UltraVNC Viewers to attempt to use
- these extensions you will need to supply this option to x11vnc:
- -rfbversion 3.6
-
- Or use -ultrafilexfer which is an alias for the above option and
- "-permitfiletransfer". UltraVNC evidently treats any other RFB version
- number as non-UltraVNC.
-
- Here are a list of the UltraVNC extensions supported by x11vnc:
- * ServerInput: "Toggle Remote Input and Remote Blank Monitor"
- * FileTransfer: "Open File Transfer..."
- * SingleWindow: "Select Single Window..."
- * TextChat: "Open Chat..."
- * 1/n Server Scaling
-
- The SSVNC Unix VNC viewer supports these UltraVNC extensions.
-
- To disable SingleWindow and ServerInput use -noultraext (the others
- are managed by LibVNCServer.) See this option too: -noserverdpms.
-
- Also, the UltraVNC repeater proxy is supported for use with reverse
- connections: "-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. Also, a perl repeater implemention is here:
- ultravnc_repeater.pl
-
-
- Q-126: Can x11vnc emulate UltraVNC's Single Click helpdesk mode for
- Unix? I.e. something very simple for a naive user to initiate a
- reverse vnc connection from their Unix desktop to a helpdesk
- operator's VNC Viewer.
-
- Yes, UltraVNC's Single Click (SC) mode can be emulated 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 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
- should work, although remember the user will be running the programs
- you place there.)
-
- In that "hd" subdirectory copy an x11vnc binary to be run on the Unix
- user's machine (e.g. Linux, etc) and also create a file named "vnc"
- containing the following:
-#!/bin/sh
-
-webhost="http://www.mysite.com/hd" # Your helpdesk dir URL.
-
-vnchost="ip.someplace.net" # Your host running 'vncviewer -listen'
- # It could also be your IP number. If it is
- # a router/firewall, you will need to
- # configure it to redirect port 5500 to you
-r
- # workstation running 'vncviewer -listen'
-
-dir=/tmp/vnc_helpdesk.$$ # Make a temporary working dir.
-mkdir $dir || exit 1
-cd $dir || exit 1
-
-trap "cd /tmp; rm -rf $dir" 0 2 15 # Cleans up on exit.
-
-wget $webhost/x11vnc # Fetch x11vnc binary. If multi-
-chmod 755 ./x11vnc # platform, use $webhost/`uname`/x11vnc
- # or similar.
-
-./x11vnc -connect_or_exit $vnchost -rfbport 0 -nopw
-
- with the hostnames / IP addresses customized to your case.
-
- On the helpdesk VNC viewer machine (ip.someplace.net in this example)
- you have the helpdesk operator running VNC viewer in listen mode:
- vncviewer -listen
-
- or if on Windows, etc. somehow have the VNC viewer be in "listen"
- mode.
-
- Then, when the naive user needs assistance you instruct him to open up
- a terminal window on his Unix desktop and paste the following into the
- shell:
- wget -qO - http://www.mysite.com/hd/vnc | sh -
-
- and then press Enter. You could have this instruction on a web page or
- in an email you send him, etc. This requires that the wget is
- installed on the user's Unix machine (he might only have curl or lynx,
- see below for more info.)
-
-
- So I guess this is about 3-4 clicks (start a terminal and paste) and
- pressing "Enter" instead of "single click"...
-
- See this page for some variations on this method, e.g. how to add a
- password, SSL Certificates, etc.
-
-
- If you don't have a website (there are many free ones) or don't want
- to use one you will have to email him all of the ingredients (x11vnc
- binary and a launcher script) and tell him how to run it. This could
- be easy or challenging depending on the skill of the naive unix
- user...
-
- 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 here.
-
-
- Firewalls: If the helpdesk (you) with the vncviewer is behind a
- NAT/Firewall/Router the 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.
-
- NAT-2-NAT: There is currently no way to go "NAT-2-NAT", i.e. both User
- and Helpdesk workstations behind NAT'ing Firewall/Routers without
- 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. http://sc.uvnc.com provides this
- service for their UltraVNC Single Click users.
-
- Update: It may be possible to do "NAT-2-NAT" with a UDP tunnel such as
- http://samy.pl/pwnat/. All that is required is that both NAT firewalls
- allow in UDP packets from an IP address to which a UDP packet has
- recently been sent to. If you try it out let us know how it went.
-
-
- Very Naive Users:
-
- If it is beyond the user how to open a terminal window and paste in a
- command (you have my condolences...) you would have to somehow setup
- his Web browser to download the "vnc" file (or a script containing the
- above wget line) and prompt the user if he wants to run it. This may
- be tricky to set up (which is probably a good thing to not have the
- web browser readily run arbitrary programs downloaded from the
- internet...)
-
- One command-line free way, tested with KDE, is to name the file vnc.sh
- and then instruct the user to right-click on the link and do "Save
- Link As" to his Desktop. It will appear as an icon, probably one that
- looks like a terminal or a command line prompt. He next should
- right-click on the icon and select "Properties" and go to the
- "Permissions" tab. Then in that dialog select the checkbox "Is
- executable". He should then be able to click on the icon to launch it.
- Another option is to right-click on the icon and select "Open With ->
- Other ..." and for the name of the application type in "/bin/sh".
- Unfortunately in both cases the command output is lost and so errors
- cannot be debugged as easily. A similar thing appears to work in GNOME
- if under "Properties -> Permissions" they click on "Execute" checkbox
- for "Owner". Then when they click on the icon, they will get a dialog
- where they can select "Run in Terminal". In general for such cases, if
- it is feasible, it might be easier to ssh to his machine and set
- things up yourself...
-
-
- SSL Encrypted Helpdesk Connections:
-
- 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 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
- containing the following:
-#!/bin/sh
-
-webhost="http://www.mysite.com/hd" # Your helpdesk dir URL.
-
-vnchost="ip.someplace.net" # Your host running 'vncviewer -listen'
- # It could also be your IP number. If it is
- # a router/firewall, you will need to
- # configure it to redirect port 5500 to you
-r
- # workstation running 'vncviewer -listen'
-
-dir=/tmp/vnc_helpdesk.$$ # Make a temporary working dir.
-mkdir $dir || exit 1
-cd $dir || exit 1
-
-trap "cd /tmp; rm -rf $dir" 0 2 15 # Cleans up on exit.
-
-wget $webhost/x11vnc # Fetch x11vnc binary. If multi-
-chmod 755 ./x11vnc # platform, use $webhost/`uname`/x11vnc
- # or similar.
-
-./x11vnc -connect_or_exit $vnchost -rfbport 0 -nopw -ssl # Note -ssl option.
-
- with the hostnames or IP addresses customized to your case.
-
- The only change from the "vnc" above is the addition of the -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 here.)
-
- The naive user will be doing this:
- wget -qO - http://www.mysite.com/hd/vncs | sh -
-
- (or perhaps even use https:// if available.)
-
- 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 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 'Listen'.
-
- If you don't want to use SSVNC for the viewer, but rather set up
- STUNNEL manually instead, make a file "stunnel.cfg" containing:
-foreground = yes
-pid =
-
-[vnc]
-accept = 5500
-connect = localhost:5501
-
- and run:
- stunnel ./stunnel.cfg
-
- and then start the "vncviewer -listen 1" (i.e. 1 to correspond to the
- 5501 port.) Note that this assumes the stunnel install created a
- Server SSL cert+key, usually /etc/stunnel/stunnel.pem (not all distros
- will do this.) Also, that file is by default only readable by root, so
- stunnel needs to be run as root. If your system does not have a key
- installed or you do not want to run stunnel as root (or change the
- permissions on the file), you can use x11vnc to create one for you for
- example:
- x11vnc -sslGenCert server self:mystunnel
-
- 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 this link and 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
-pid =
-cert = /home/myusername/.vnc/certs/server-self:mystunnel.pem
-
-[vnc]
-accept = 5500
-connect = localhost:5501
-
- In any event, with stunnel having been setup, the naive user is
- instructed to paste in and run:
- wget -qO - http://www.mysite.com/hd/vncs | sh -
-
- to pick up the vncs script this time.
-
- Of course if a man-in-the-middle can alter what the user downloads
- then all bets are off!.
-
- More SSL variations and info about certificates can be found here.
-
-
- OpenSSL libssl.so.0.9.7 problems:
-
- If you build your own stunnel or x11vnc for deployment, you may want
- to statically link libssl.a and libcrypto.a into it because Linux
- distros are currently a bit of a mess regarding which version of
- libssl is installed.
-
- You will find the details here.
-
-
- Q-127: Can I (temporarily) mount my local (viewer-side) Windows/Samba
- File share on the machine where x11vnc is running?
-
- You will have to use an external network redirection for this.
- Filesystem mounting is not part of the VNC protocol.
-
- We show a simple 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:
- sitting-here> ssh -C -R 1139:localhost:139 far-away.east
-
- Or one could combine this with the VNC tunnel at the same time, e.g.:
- sitting-here> ssh -C -R 1139:localhost:139 -t -L 5900:localhost:5900 far-away
-.east 'x11vnc -localhost -display :0'
-
- Port 139 is the Windows Service port. For Windows systems instead of
- Samba, you may need to use the actual IP address of the Window machine
- instead of "localhost" in the -R option (since the Windows service
- does not listen on localhost by default.)
-
- Note that we use 1139 instead of 139 on the remote side because 139
- would require root permission to listen on (and you may have a samba
- server running on it already.)
-
- The ssh -C is to enable compression, which might speed up the data
- transfers.
-
- Depending on the remote system side configuration, it may or may not
- be possible to mount the SMB share as a non-root user. Try it first as
- a non-root user and if that fails you will have to become root.
-
- We will assume the user name is "fred" and we will try to mount the
- viewer-side Windows SMB share "//haystack/pub" in
- /home/fred/smb-haystack-pub.
- far-away> mkdir -p /home/fred/smb-haystack-pub
- far-away> smbmount //haystack/pub /home/fred/smb-haystack-pub -o username=fre
-d,ip=127.0.0.1,port=1139
-
- (The 2nd command may need to be run as root.) Then run "df" or "ls -l
- /home/fred/smb-haystack-pub" to see if it is mounted properly. Consult
- the smbmount(8) and related documentation (it may require some
- fiddling to get write permissions correct, etc.) To unmount:
- far-away> smbumount /home/fred/smb-haystack-pub
-
- At some point we hope to fold some automation for SMB ssh redir setup
- into the Enhanced TightVNC Viewer (SSVNC) package we provide (as of
- Sep 2006 it is there for testing.)
-
-
- Q-128: Can I redirect CUPS print jobs from the remote desktop where
- x11vnc is running to a printer on my local (viewer-side) machine?
-
- 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 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.)
-
- First you will need a tunnel to redirect the print requests from the
- remote machine to the one you sitting at. We use an ssh tunnel:
- sitting-here> ssh -C -R 6631:localhost:631 far-away.east
-
- Or one could combine this with the VNC tunnel at the same time, e.g.:
- sitting-here> ssh -C -R 6631:localhost:631 -t -L 5900:localhost:5900 far-away
-.east 'x11vnc -localhost -display :0'
-
- Port 631 is the default CUPS port. The above assumes you have a Cups
- server running on your viewer machine (localhost:631), if not, use
- something like my-cups-srv:631 (the viewer-side Cups server) in the -R
- instead.
-
- Note that we use 6631 instead of 631 on the remote side because 631
- would require root permission to listen on (and you likely have a cups
- server running on it already.)
-
- Now the tricky part: to get applications to notice your cups
- server/printer on localhost:6631.
-
- If you have administrative privilege (i.e. root password) on the
- x11vnc side where the desktop is running, it should be easy to add the
- printer through some configuration utility (e.g. in KDE: Utilities ->
- Printing -> Printing Manager, and then supply admin password, and then
- Add Printer/Class, and then fill in the inquisitive wizard. Most
- important is the "Remote IPP server" panel where you put in localhost
- 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/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 client.conf file), to have normal cups
- operation.
-
- 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/.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
- lpadmin(8), etc, to use a printer URI something like
- smb://machine:port/printer (this may have some name resolution
- problems WRT localhost.) Also, as with SMB mounting, the port redir
- (-R) to the Windows machine must use the actual IP address instead of
- "localhost".
-
- At some point we hope to fold some automation for CUPS ssh redir setup
- into the Enhanced TightVNC Viewer (SSVNC) package we provide (as of
- Sep 2006 it is there for testing.)
-
-
- Q-129: How can I hear the sound (audio) from the remote applications
- on the desktop I am viewing via x11vnc?
-
- You will have to use an external network audio mechanism for this.
- Audio is not part of the VNC protocol.
-
- We show a simple Unix to Unix esd example here (artsd should be
- possible too, we have also verified the esd Windows port works for the
- method described below.)
-
- First you will need a tunnel to redirect the audio from the remote
- machine to the one you sitting at. We use an ssh tunnel:
- sitting-here> ssh -C -R 16001:localhost:16001 far-away.east
-
- Or one could combine this with the VNC tunnel at the same time, e.g.:
- sitting-here> ssh -C -R 16001:localhost:16001 -t -L 5900:localhost:5900 far-a
-way.east 'x11vnc -localhost -display :0'
-
- Port 16001 is the default ESD uses. So when an application on the
- remote desktop makes a sound it will connect to this tunnel and be
- redirected to port 16001 on the local machine (sitting-here in this
- example.) The -C option is an attempt to compress the audio a little
- bit.
-
- So we next need a local (sitting-here) esd daemon running that will
- receive those requests and play them on the local sound device:
- sitting-here> esd -promiscuous -port 16001 -tcp -bind 127.0.0.1
-
- See the esd(1) man page for the meaning of the options (the above are
- not very secure.) (This method also works with the EsounD windows port
- esd.exe)
-
- To test this sound tunnel, we use the esdplay program to play a simple
- .wav file:
- far-away> esdplay -s localhost:16001 im_so_happy.wav
-
- If you hear the sound (Captain Kirk in this example), that means you
- are in great shape.
-
- To run individual audio applications you can use the esddsp(1)
- command:
- far-away> esddsp -s localhost:16001 xmms
-
- Then you could try playing some sounds inside xmms. You could also set
- the environment variable ESPEAKER=localhost:16001 to not need to
- supply the -s option all the time. (for reasons not clear, sometimes
- esddsp can figure it out on its own.) All the script esddsp does is to
- set ESPEAKER and LD_PRELOAD for you so that when the application opens
- the sound device (usually /dev/dsp) its interactions with the device
- will be intercepted and sent to the esd daemon running on sitting-here
- (that in turn writes them to the real, local /dev/dsp.)
-
- Redirecting All sound:
-
- It does not seem to be possible to switch all of the sound of the
- remote machine from its sound device to the above esd+ssh tunnel
- without some preparation. But it can be done reasonably well if you
- prepare (i.e. restart) the desktop with this in mind.
-
- Here is one way to redirect all sound. The idea is we run the entire
- desktop with sound directed to localhost:16001. When we are sitting at
- far-away.east we run "esd -promiscuous -port 16001 -tcp -bind
- 127.0.0.1" on far-away.east (to be able to hear the sound.) However,
- when we are sitting at sitting-here.west we kill that esd process and
- run that same esd command on sitting-here.west and start up the above
- ssh tunnel. This is a little awkward, but with some scripts one would
- probably kill and restart the esd processes automatically when x11vnc
- is used.
-
- So next we have to run the whole desktop pointing toward our esd. Here
- is a simple way to test. Log in to the machine via the "FailSafe"
- desktop. Then in the lone terminal type something like:
- esddsp -s localhost:16001 gnome-session
-or:
- esddsp -s localhost:16001 startkde
-
- where the last part is whatever command starts your desktop (even
- fvwm2.) This causes the environment variables ESPEAKER and LD_PRELOAD
- to be set appropriately and every application (processes with the
- desktop as an ancestor) will use them. If this scheme works well you
- can make it less klunky by adding the command to your ~/.xsession,
- etc. file that starts your default desktop. Or you may be able to
- configure your desktop to use localhost:16001, or whatever is needed,
- via a gui configuration panel. Some Notes:
- * Not all audio applications are compatible with the esd and artsd
- mechanisms, but many are.
- * The audio is not compressed so you probably need a broadband or
- faster connection. Listening to music may not be very pleasant...
- (Although we found streaming music from across the US over cable
- modem worked OK, but took 200 KB/sec, to use less bandwidth
- consider something like "ssh far-away.east 'cat favorite.mp3' |
- mpg123 -b 4000 -")
- * Linux does not seem to have the concept of LD_PRELOAD_64 so if you
- run on a mixed 64- and 32-bit ABI system (e.g. AMD x86_64) some of
- 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 Enhanced TightVNC Viewer (SSVNC) package we
- provide (as of Sep/2006 it is there for testing.)
-
-
- Q-130: Why don't I hear the "Beeps" in my X session (e.g. when typing
- tput bel in an xterm)?
-
- As of Dec/2003 "Beep" XBell events are tracked by default. The X
- server must support the XKEYBOARD extension (this is not on by default
- 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 -nobell option. If you
- want to hear the audio from the remote applications, consider trying a
- redirector such as esd.
-
-
- Q-131: Does x11vnc work with IPv6?
-
- Update: as of Apr/2010 in the 0.9.10 x11vnc development tarball, there
- is now built-in support for IPv6 (128 bit internet addresses.) See the
- -6 and -connect options for details.
-
- The remainder of this FAQ entry shows how to do with this with pre
- 0.9.10 x11vnc using IPv6 helper tools.
- _________________________________________________________________
-
- Using an external IPv6 helper:
- A way to do this is via a separate helper program such as inetd (or
- for encrypted connections: ssh or stunnel.) For example, 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.
- For inetd.conf, an example is:
- 5900 stream tcp6 nowait root /usr/sbin/tcpd /usr/local/bin/x11vnc_wrapper.sh
-
- We also provide a transitional tool in "x11vnc/misc/inet6to4" that
- acts as a relay for any IPv4 application to allow connections over
- IPv6. For example:
- inet6to4 5900 localhost:5900
-
- where x11vnc is listening on IPv4 port 5900.
-
- Also note that not all VNC Viewers are IPv6 enabled, so a redirector
- may also be needed for them. The tool "inet6to4 -r ..." can do this as
- well. SSVNC (see below) supports IPv6 without need for the helper.
-
- # ./inet6to4 -help
-
- inet6to4: Act as an ipv6-to-ipv4 relay for tcp applications that
- do not support ipv6.
-
- Usage: inet6to4
- inet6to4 -r
-
- Examples: inet6to4 5900 localhost:5900
- inet6to4 8080 web1:80
- inet6to4 -r 5900 fe80::217:f2ff:fee6:6f5a%eth0:5900
-
- The -r option reverses the direction of translation (e.g. for ipv4
- clients that need to connect to ipv6 servers.) Reversing is the default
- if this script is named 'inet4to6' (e.g. by a symlink.)
-
- Use Ctrl-C to stop this program.
-
- You can also set env. vars INET6TO4_LOOP=1 or INET6TO4_LOOP=BG
- to have an outer loop restarting this program (BG means do that
- in the background), and INET6TO4_LOGFILE for a log file.
- Also set INET6TO4_VERBOSE to verbosity level and INET6TO4_WAITTIME
- and INET6TO4_PIDFILE (see below.)
-
- The "INET6TO4_LOOP=BG" and "INET6TO4_LOGFILE=..." env. variables make
- the tool run reliably as a daemon for very long periods. Read the top
- part of the script for more information.
- _________________________________________________________________
-
- Encrypted Tunnels with IPv6 Support:
- For SSH tunnelled encrypted VNC connections, one can of course use the
- IPv6 support in ssh(1).
-
- For SSL encrypted VNC connections, one possibility is to use the IPv6
- support in stunnel(1). This includes the built-in support via the
- -stunnel option. For example:
- x11vnc -stunnel SAVE -env STUNNEL_LISTEN=:: -env STUNNEL_DEBUG=1 ...
- _________________________________________________________________
-
- SSH IPv6 Tricks:
- It is interesting to note that ssh(1) can do basically the same thing
- as inet6to4 above by:
- ssh -g -L 5900:localhost:5901 localhost "printf 'Press Enter to Exit: '; read
- x"
-
- (where we have x11vnc running via "-rfbport 5901" in this case.)
-
- Note that one can also make a home-brew SOCKS5 ipv4-to-ipv6 gateway
- proxy using ssh like this:
- ssh -D '*:1080' localhost "printf 'Press Enter to Exit: '; read x"
-
- then specify a proxy like socks://hostname:1080 where hostname is the
- machine running the above ssh command (add -v to ssh for connection
- logging info.)
- _________________________________________________________________
-
- IPv6 SSVNC Viewer:
- Our SSVNC VNC Viewer is basically a wrapper for ssh(1) and stunnel(1),
- and so it already has good IPv6 support because these two commands do.
- On Unix, MacOSX, and Windows nearly all of the the remaining parts of
- SSVNC (e.g. the built-in proxying and un-encrypted connections) have
- been modified to support IPv6 in SSVNC 1.0.26.
-
-
-
-
-
-
- Contributions:
-
- Q-132: Thanks for your program or for your help! Can I make a
- donation?
-
- Please do (any amount is appreciated; very few have donated) and thank
- you for your support! Click on the PayPal button below for more info.
-
- [x-click-but04.gif]-Submit
-
-=======================================================================
-http://www.karlrunge.com/x11vnc/chainingssh.html:
-
-
- _________________________________________________________________
-
- Chaining ssh's: Note that for use of a ssh gateway and -L redirection
- to an internal host (e.g. "-L 5900:otherhost:5900") the VNC traffic
- inside the firewall is not encrypted and you have to manually log into
- otherhost to start x11vnc. Kyle Amon shows a method where you chain
- two ssh's together that encrypts all network traffic and also
- automatically starts up x11vnc on the internal workstation:
-#!/bin/sh
-#
-gateway="example.com" # or "user@example.com"
-host="labyrinth" # or "user@hostname"
-user="kyle"
-
-# Need to sleep long enough for all of the passwords and x11vnc to start up.
-# The </dev/null below makes the vncviewer prompt for passwd via popup window.
-#
-(sleep 10; vncviewer -encodings "copyrect tight zrle zlib hextile" \
- localhost:0 </dev/null >/dev/null) &
-
-# Chain the vnc connection thru 2 ssh's, and connect x11vnc to user's display:
-#
-exec /usr/bin/ssh -t -L 5900:localhost:5900 $gateway \
- /usr/bin/ssh -t -L 5900:localhost:5900 $host \
- sudo /usr/bin/x11vnc -localhost -auth /home/$user/.Xauthority \
- -rfbauth .vnc/passwd -display :0
-
- Also note the use of sudo(1) to switch to root so that the different
- user's .Xauthority file can be accessed. See the visudo(8) manpage for
- details on how to set this up (remove the sudo if you do not want to
- do this). One can also chain together ssh's for reverse connections
- with vncviewers using the -listen option. For this case -R would
- replace the -L (and 5500 the 5900, see the #2 example script above).
- If the gateway machine's sshd is configured with GatewayPorts=no (the
- default) then the double chaining of "ssh -R ..." will be required for
- reverse connections to work.
-
-=======================================================================
-http://www.karlrunge.com/x11vnc/miscbuild.html:
-
-
- _________________________________________________________________
-
- Misc. Build problems: We collect here rare build problems some users
- have reported and the corresponding workarounds. See also the FAQ's on
- building.
- _________________________________________________________________
-
- ENV parameter: One user had a problem where the build script below was
- failing because his work environment had the ENV variable set to a
- script that was resetting his PATH so that gcc could no longer be
- found. Make sure you do not have any ENV or BASH_ENV in your
- environment doing things like that. Typing "unset ENV", etc. before
- configuring and building should clear it.
- _________________________________________________________________
-
- Bash xpg: One user had his bash shell compiled with
- --enable-xpg-echo-default that causes some strange behavior with
- things like echo "\\1 ..." the configure script executes. In
- particular instead of getting "\1" the non-printable character "^A" is
- produced, and causes failures at compile time like:
- ../rfb/rfbconfig.h:9:22: warning: extra tokens at end of #ifndef directive
-
- The workaround is to configure like this:
- env CONFIG_SHELL=/bin/sh /bin/sh ./configure
-
- i.e. avoid using the bash with the misbehavior. A bug has been filed
- against autoconf to guard against this.
- _________________________________________________________________
-
- AIX: one user had to add the "X11.adt" package to AIX to get build
- header files like XShm.h, etc.
- _________________________________________________________________
-
- Ubuntu Feisty Fawn 7.04: In May/2007 one user said he needed to add
- these packages to compile x11vnc on that Linux distro and version:
- apt-get install build-essential make bin86 libjpeg62-dev libssl-dev libxtst-d
-ev
-
- Note that Ubuntu is based on Debian, so perhaps this is the list
- needed on Debian (testing?) as well. To build in Avahi (mDNS service
- advertising) support it would appear that libavahi-client-dev is
- needed as well.
- _________________________________________________________________
-
- Exceedingly slow compilation: x11vnc has a couple of files which
- contain very large "case statements" (over 100 cases) that on some
- platforms can take a very long time to compile (in extreme cases over
- an hour). However on 32bit Linux with intel/amd processor and gcc
- these files usually take less than 10 seconds to compile. For 64bit
- systems using gcc the problem appears to be much worse.
-
- The two files with the large number of cases, remote.c and x11vnc.c,
- have no real need to be optimized (the code is used only very
- infrequently). So it is fine to supply "-O0" (disables optimization)
- to CFLAGS when compiling them. However, it is tricky with
- autoconf/automake to do this (especially since both the compiler and
- make versions have a big effect).
-
- So if the compile times are getting too long for you for these two
- files you will need to manually change some things. First, run
- configure and when it has finished, edit the generated file
- x11vnc/Makefile and put these lines at the very top:
-x11vnc-x11vnc.o : CFLAGS += -O0
-x11vnc-remote.o : CFLAGS += -O0
-
- Those lines assume gnu make (gmake) is being used. If you are using
- another make, say Solaris make, insert these instead:
-x11vnc-x11vnc.o := CFLAGS += -O0
-x11vnc-remote.o := CFLAGS += -O0
-
- You could write a build shell script that modified the Makefile this
- way before running make.
-
- The "-O0" (note it is "capital Oh" followed by "zero") assumes the gcc
- compiler. If you are using a different compiler you will need to find
- the command line option to disable optimization, or otherwise have the
- lines set CFLAGS to the empty string.
- _________________________________________________________________
-
- Broken Thread Local Storage on SuSE 9.2: Starting with x11vnc 0.9.8
- the bundled libvncserver uses the __thread keyword to make some of the
- encodings (i.e. tight) thread safe (multiple VNC clients can be using
- tight at the same time in x11vnc -threads mode.) Evidently on the old
- SuSE 9.2 system the compiler does not support the thread local storage
- properly. Here is an example build failure:
-tight.c:1126: error: unrecognizable insn:
-(insn:HI 11 10 13 0 (nil) (set (reg/f:SI 59)
- (const:SI (plus:SI (symbol_ref:SI ("%lpalette"))
- (const_int 2048 [0x800])))) -1 (nil)
- (expr_list:REG_EQUAL (const:SI (plus:SI (symbol_ref:SI ("%lpalette"))
- (const_int 2048 [0x800])))
- (nil)))
-tight.c:1126: internal compiler error: in extract_insn, at recog.c:2175
-Please submit a full bug report,
-with preprocessed source if appropriate.
-See URL:http://www.suse.de/feedback for instructions.
-
- The workaround is to disable thread local storage at configure time
- like this:
-env CPPFLAGS="-DTLS=''" ./configure
-
- and then build it.
- _________________________________________________________________
-
-=======================================================================
-http://www.karlrunge.com/x11vnc/sunray.html:
-
-
- Sun Ray Notes:
-
- You can run x11vnc on your (connected or disconnected) SunRay session
- (Please remember to use settings like -wait 200, -sb 15, and not
- running a screensaver animation (blank instead) to avoid being a
- resource hog! x11vnc does induce a lot of memory I/O from polling the
- X server. It also helps to have a solid background color, e.g.
- -solid).
-
- News: Sun Ray Remote Control Toolkit: See the nice set of tools in the
- Sun Ray Remote Control Toolkit that launch x11vnc automatically for
- you for certain usage modes.
-
- You have to know the name of the machine your SunRay session X server
- is running on (so you can ssh into it and start x11vnc). You also need
- to know the X11 DISPLAY number for the session: on a SunRay it could
- be a large number, e.g. :137, since there are many people with X
- sessions (Xsun processes) on the same machine. If you don't know it,
- you can get it by running who(1) in a shell on the SunRay server and
- looking for the dtlocal entry with your username (and if you don't
- even know which server machine has your session, you could login to
- all possible ones looking at the who output for your username...).
-
- I put some code in my ~/.dtprofile script that stores $DISPLAY
- (including the hostname) in a ~/.sunray_current file at session
- startup (and deletes it when the X session ends) to make it easy to
- get at the hostname and X11 display number info for my current X
- sessions when I ssh in and am about to start x11vnc.
-
- SunRay Gotcha #1: Note that even though your SunRay X11 DISPLAY is
- something like :137, x11vnc still tries for port 5900 as its listening
- port if it can get it, in which case the VNC display (i.e. the
- information you supply to the VNC viewer) is something like
- sunray-server:0 (note the :0 corresponding to port 5900, it is not
- :137). If it cannot get 5900, it tries for 5901, and so on. You can
- also try to force the port (and thereby the VNC display) using the
- -rfbport NNNN option.
-
- Especially on a busy Sun Ray server it is often difficult to find free
- ports for both VNC and the HTTP Java applet server to listen on. This
- script, vnc_findports may be of use for doing this automatically. It
- suggests x11vnc command line options based on netstat output that
- lists the occupied ports. It is even more difficult to start
- vncserver/Xvnc on a busy Sun Ray because then 3 ports (HTTP, VNC, and
- X11), all separated by 100 are needed! This script, findvncports may
- be helpful as well. Both scripts start at VNC display :10 and work
- their way up.
-
- SunRay Gotcha #2: If you get an error like:
- shmget(tile) failed.
- shmget: No space left on device
-
- when starting up x11vnc that most likely means all the shared memory
- (shm) slots are filled up on your machine. The Solaris default is only
- 100, and that can get filled up in a week or so on a SunRay server
- with lots of users. If the shm slot is orphaned (e.g. creator process
- dies) the slot is not reclaimed. You can view the shm slots with the
- "ipcs -mA" command. If there are about 100 then you've probably hit
- this problem. They can be cleaned out (by the owner or by root) using
- the ipcrm command. I wrote a script shm_clear that finds the orphans
- and lists or removes them. Longer term, have your SunRay sysadmin add
- something like this to /etc/system:
- set shmsys:shminfo_shmmax = 0x2000000
- set shmsys:shminfo_shmmni = 0x1000
-
- SunRay Gotcha #3: Some SunRay installations have implemented
- suspending certain applications when a SunRay session is in a
- disconnected state (e.g. Java Badge pulled out, utdetach, etc). This
- is a good thing because it limits hoggy or runaway apps from wasting
- the shared CPU resource. Think how much CPU and memory I/O is wasted
- by a bunch of Firefox windows running worthless Flash animations while
- your session is disconnected!
-
- So some sites have implemented scripts to suspend (e.g. kill -STOP)
- certain apps when your badge is removed from the SunRay terminal. When
- you reattach, it kill -CONT them. This causes problems for viewing the
- detached SunRay session via x11vnc: those suspended apps will not
- respond (their windows will be blank or otherwise inactive).
-
- What to do? Well, since you are going to be using the application you
- might as well unfreeze it rather than starting up a 2nd instance. Here
- is one way to do it using the kill -CONT mechanism:
- kill -CONT `ps -ealf | grep ' T ' | grep $LOGNAME | awk '{print $4}'`
-
- If you want to be a good citizen and re-freeze them before you exit
- x11vnc this script could be of use:
-#!/bin/sh
-#
-# kill -STOP/-CONT script for x11vnc (or other) SunRay usage ("freezes"
-# certain apps from hogging resources when disconnected).
-#
-# Put here a pattern that matches the apps that are frozen:
-#
-appmatch="java_vm|jre|netscape-bin|firefox-bin|realplay|acroread|mozilla-bin"
-
-if [ "X$1" = "Xfreeze" ]; then
- pkill -STOP -U $LOGNAME "$appmatch"
-elif [ "X$1" = "Xthaw" ]; then
- pkill -CONT -U $LOGNAME "$appmatch"
-
-elif [ "$RFB_MODE" = "afteraccept" -a "$RFB_STATE" = "NORMAL" ]; then
- # a valid x11vnc login.
- if [ "$RFB_CLIENT_COUNT" = "1" ]; then
- # only one client present.
- pkill -CONT -U $LOGNAME "$appmatch"
- fi
-elif [ "$RFB_MODE" = "gone" -a "$RFB_STATE" = "NORMAL" ]; then
- # a valid x11vnc login.
- if [ "$RFB_CLIENT_COUNT" = "0" ]; then
- # last client present has just left.
- pkill -STOP -U $LOGNAME "$appmatch"
- fi
-fi
-exit 0
-
- If you called the script "goodcitizen" you could type "goodcitizen
- thaw" to unfreeze them, and then "goodcitizen freeze" to refreeze
- them. One could also use these x11vnc options "-afteraccept
- goodcitizen -gone goodcitizen" to do it automatically.
-
- SunRay Gotcha #4: Recent versions of the Sun Ray Server Software
- SRSS (seems to be version 3.0 or 3.1) have a "misfeature" that when
- the session is disconnected (i.e. badge/smartcard out) the screen
- locker (xscreensaver) will freeze the X server just when the "Enter
- Password" dialog box appears. So you cannot unlock the screen remotely
- via x11vnc!
-
- Update: please see Bob Doolittle's detailed description of the this
- issue at the bottom of this section.
-
- Here "freeze" means "stop other X clients from inserting keyboard and
- mouse input and from viewing the current contents of the screen". Or
- something like that; the upshot is x11vnc can't do its normal thing.
-
- There are several workarounds for this.
-
- 1) The easiest one by far is to put these lines in your
- $HOME/.dtprofile file:
-SUN_SUNRAY_UTXLOCK_PREF="/usr/openwin/bin/xlock -mode blank"
-export SUN_SUNRAY_UTXLOCK_PREF
-
- One might argue that xlock isn't particularly "pretty". (Just IMHO,
- but if something like this not being pretty actually gets in the way
- of your work I think some introspection may be in order. :-)
-
- 2) The problem has been traced to the pam_sunray.so PAM module.
- Evidently xscreensaver invokes this pam module and it communicates
- with utsessiond who in turn instructs the Xsun server to not process
- any synthetic mouse/keyboard input or to update the screen
- framebuffer. It is not clear if this is by design (security?) or
- something else.
-
- In any event, the problem can be avoided, somewhat drastically, by
- commenting out the corresponding line in /etc/pam.conf:
-#xscreensaver auth sufficient /opt/SUNWut/lib/pam_sunray.so syncondisplay
-
- Leave the other xscreensaver pam authentication lines unchanged. The
- dtsession-SunRay line may also need to be commented out to avoid the
- problem for CDE sessions. N.B. it is possible the application of a
- SSRS patch, etc, may re-enable that /etc/pam.conf line. It may be
- difficult to convince a sysadmin to make this change.
-
- 3) A more forceful way is to kill the xscreensaver process from a
- shell prompt whenever you connect via x11vnc and the screen is in a
- locked state:
-pkill -U $LOGNAME '^xscreensaver$'
-
- And then after you are in be sure to restart it by typing something
- like:
-xscreensaver &
-
- You may want to avoid restarting it until you are about to disconnect
- your VNC viewer (since if it locks the screen while you are working
- you'll be stuck again).
-
- 3') The above idea can be done a bit more cleanly by having x11vnc do
- it. Suppose we called the following script xss_killer:
-#!/bin/sh
-#
-# xss_killer: kill xscreensaver after a valid x11vnc client logs in.
-# Restart xscreensaver and lock it when the last client
-# disconnects.
-
-PATH=/usr/openwin/bin:/usr/bin:$PATH
-export PATH
-
-if [ "$RFB_MODE" = "afteraccept" -a "$RFB_STATE" = "NORMAL" ]; then
- # a valid x11vnc login.
- if [ "$RFB_CLIENT_COUNT" = "1" ]; then
- # only one client present.
- pkill -U $LOGNAME '^xscreensaver$'
- pkill -KILL -U $LOGNAME -f xscreensaver/hacks
- fi
-elif [ "$RFB_MODE" = "gone" -a "$RFB_STATE" = "NORMAL" ]; then
- # a valid x11vnc login.
- if [ "$RFB_CLIENT_COUNT" = "0" ]; then
- # last client present has just left.
- xscreensaver -nosplash &
- sleep 1
- xscreensaver-command -lock &
- fi
-fi
-
- Then we would run x11vnc with these options: "-afteraccept xss_killer
- -gone xss_killer". The -afteraccept option (introduced in version 0.8)
- is used to run a command after a vncviewer has successfully logged in
- (note that this is a VNC login, not a Unix login, so you may not want
- to do this if you are really paranoid...)
-
- Note if you use the above script and also plan to Ctrl-C (SIGINT)
- x11vnc you have to run the xscreensaver in a new process group to
- avoid killing it as well. One way to do this is via this kludge:
-perl -e 'setpgrp(0,0); exec "xscreensaver -nosplash &"'
-
- in the above script.
-
- 4) There appears to be a bug in pam_sunray.so in that it doesn't seem
- to honor the convention that, say, DISPLAY=unix:3 means to use Unix
- sockets to connect to display 3 on the local machine (this is a bit
- faster than TCP sockets). Rather, it thinks the display is a non-local
- one to a machine named "unix" (that usually does not resolve to an IP
- address).
-
- Amusingly, this can be used to bypass the pam_sunray.so blocking of
- Xsun that prevents one from unlocking the screen remotely via x11vnc.
- One could put something like this in $HOME/.dtprofile to kill any
- existing xscreensavers and then start up a fresh xscreensaver using
- DISPLAY=unix:N
-# stop/kill any running xscreensavers (probably not running yet, but to be sure
-)
-xscreensaver-command -exit
-pkill -U $LOGNAME '^xscreensaver$'
-env DISPLAY=`echo $DISPLAY | sed -e 's/^.*:/unix:/'` xscreensaver &
-
-
- Important: Note that all of the above workarounds side-step the
- pam_sunray.so PAM module in one way or another. You'll need to see if
- that is appropriate for your site's SunRay / smartcard usage. Also,
- these hacks may break other things and so you may want to test various
- scenarios carefully. E.g. check corner cases like XDMCP/dtremote,
- NSCM, etc.
-
-
- Update May 2008: Here is a useful description of this issue from Bob
- Doolittle who is a developer for Sun Ray at Sun. I don't have the time
- to digest and distill it and then adjust the above methods to provide
- a clearer description, so I just include below the description he sent
- me with the hope that it will help some users:
-
- In SRSS 4.0 and earlier, the purpose of pam_sunray.so in the "auth"
- PAM stack of screensavers is to enable NSCM (and, although this is
- much less commonly used, "SC", which is configured when 3rd-party
- software is installed to allow smartcards to be used as part of the
- authentication process) to work. It should have no effect with
- smartcards. Currently, however, it does block the PAM stack for all
- sessions, which causes xscreensaver, when it locks a disconnected
- session, to not process any mouse or keyboard events as you
- describe (unless xscreensaver does an X server grab, however, other
- applications should still be able to draw in the session although
- xscreensaver may be playing tricks like putting a black window on
- top of everything). In both of the NSCM and SC models,
- authentication occurs in a separate session before SRSS will
- reconnect to the user session, in which case pam_sunray.so causes
- xscreensaver to just unlock the screen without prompting the user
- to enter their password again. To do this, pam_sunray.so has to
- block until the session becomes reconnected, so it can query SRSS
- at that time to determine whether the user has already
- authenticated or not. In SRSS 4.0 and earlier releases,
- pam_sunray.so could have been optimized to not block smartcard
- sessions, although since the session is disconnected this typically
- isn't important (except in the x11vnc case, as you've observed).
-
- In SRSS 4.1, however, for increased security the out-of-session
- authentication model has been extended to *all* session types, so
- pam_sunray.so will be required in all cases unless users are
- willing to authenticate twice upon hotdesking (e.g. when their card
- is inserted). In future, we may do away with pam_sunray.so, and in
- fact with any traditional screen locker in the user session, since
- SRSS itself will be providing better security than a screen locker
- running entirely within the user's X session is capable of
- providing.
-
- Your trick of setting DISPLAY to unix:DPY will effectively disable
- pam_sunray.so (I'm not sure I'd call that a bug - you're going out
- of your way to do something that wouldn't occur in the normal
- course of events, and really provides no useful value other than to
- tickle this behavior in pam_sunray.so). This will mean that, in
- SRSS 4.0 and earlier releases, users will be prompted for their
- passwords twice when reconnecting to their sessions for NSCM and SC
- session types. In 4.1, disabling pam_sunray.so in this way will
- cause this double-authentication to occur for *all* sessions,
- including simple smartcard sessions. Users may be willing to pay
- that price in order to be able to use x11vnc in disconnected
- sessions. I like this hack, personally. It's a little less
- convenient than some of the other approaches you describe, but it's
- lighter-weight and more secure than most of the other approaches,
- and provides the value of being able to use x11vnc in locked
- sessions.
-
- Here are some other minor notes: - I wouldn't recommend storing
- your display in your .dtprofile, unless you're willing to live with
- a single session at a time. Personally, I often find myself using
- several sessions, in several FoGs, for short periods of time so
- this would certainly break. IMO it's pretty easy to use $DISPLAY to
- do what you want on the fly, as needed, so I don't think the price
- of breaking multiple-session functionality would be worth the
- convenience, to me at least. Here's some ksh/bash syntax to extract
- the hostname and display number on the fly which you may find
- useful:
-HOSTNAME=${DISPLAY%:*}
-FULLDPY=${DISPLAY#*:}
-DPYNUM=${FULLDPY%.*}
-
- A final note may give you some insight into other clever hacks in
- this area: - Check out utaction. It's a very handy little utility
- that can be run as a daemon in the user session which will invoke a
- specified command upon session connects and/or disconnects.
- Personally, I start one up in my .dtprofile as follows:
-utaction -c $HOME/.srconnectrc -d $HOME/.srdisconnectrc &
-
- This then allows me to construct a .srconnectrc script containing
- useful commands I'd like to have run every time I insert my
- smartcard, and a .srdisconnectrc script of commands to be run every
- time I remove my smartcard (or, connect/disconnect to my session
- via NSCM or SC). This can be used for things like notifying a chat
- client of away status, as well as some of the hacks you've
- described on your page such as freeze/unfreeze, or perhaps to
- terminate an xscreensaver and start up a new one with the unix:DPY
- $DISPLAY specification as you describe (although it probably makes
- most sense to do this at login time, as opposed to every connect or
- disconnect event).
-
-=======================================================================
-http://www.karlrunge.com/x11vnc/ssl.html:
-
-
- _________________________________________________________________
-
- Notes on x11vnc SSL Certificates and Key Management:
-
- The simplest scheme ("x11vnc -ssl TMP") is where x11vnc generates a
- temporary, self-signed certificate each time (automatically using
- openssl(1)) and the VNC viewer client accepts the certificate without
- question (e.g. user clicks "Yes" in a dialog box. Perhaps the dialog
- allows them to view the certificate too). Also note stunnel's default
- is to quietly accept all certificates.
-
- The encryption this provides protects against all passive sniffing of
- the VNC traffic and passwords on the network and so it is quite good,
- but it does not prevent a Man-In-The-Middle active attack: e.g. an
- attacker intercepts the VNC client stream and sends it his own Public
- key for SSL negotiation (pretending to be the server). Then it makes a
- connection to SSL x11vnc itself and forwards the data back and forth.
- He can see all the traffic and modify it as well.
-
- Most people don't seem to worry about Man-In-The-Middle attacks these
- days; they are more concerned about passive sniffing of passwords,
- etc. Perhaps someday that will change if attack tools are used more
- widely to perform the attack. NOTE: There are hacker tools like
- dsniff/webmitm and cain that implement SSL Man-In-The-Middle attacks.
- They all rely on the client not bothering to check that the cert is
- valid.
-
- If you are not worried about Man-In-The-Middle attacks you do not have
- to read the techniques described in the rest of this document.
-
- To prevent Man-In-The-Middle attacks, certificates must somehow be
- verified. This requires the VNC client side have some piece of
- information that can be used to verify the SSL x11vnc server.
- Alternatively, although rarely done, x11vnc can verify VNC Clients'
- certificates, see the -sslverify option that is discussed below.
-
- There are a number of ways to have the client authenticate the SSL
- x11vnc server. The quickest way perhaps would be to copy (safely) the
- certificate x11vnc prints out:
-26/03/2006 21:12:00 Creating a temporary, self-signed PEM certificate...
-...
------BEGIN CERTIFICATE-----
-MIIC4TCCAkqgAwIBAgIJAMnwCaOjvEKaMA0GCSqGSIb3DQEBBAUAMIGmMQswCQYD
-VQQGEwJBVTEOMAwGA1UEBxMFTGludXgxITAfBgNVBAsTGGFuZ2VsYS0xMTQzNDI1
-NTIwLjQxMTE2OTEPMA0GA1UEChMGeDExdm5jMS4wLAYDVQQDEyV4MTF2bmMtU0VM
-(more lines) ...
------END CERTIFICATE-----
-
- to the client machine(s) and have the client's SSL machinery (e.g.
- stunnel, Web Browser, or Java plugin) import the certificate. That way
- when the connection to x11vnc is made the client can verify that is it
- the desired server on the other side of the SSL connection.
-
- So, for example suppose the user is using the SSL enabled Java VNC
- Viewer and has incorporated the x11vnc certificate into his Web
- browser on the viewing side. If he gets a dialog that the certificate
- is not verified he knows something is wrong. It may be a
- Man-In-The-Middle attack, but more likely x11vnc certificate has
- changed or expired or his browser was reinstalled and/or lost the
- certificate, etc, etc.
-
- As another example, if the user was using stunnel with his VNC viewer
- (this is mentioned in this FAQ), e.g. STUNNEL.EXE on Windows, then he
- would have to set the "CAfile = path-to-the-cert" and "verify = 2"
- options in the stunnel.conf file before starting up the tunnel. If a
- x11vnc certificate cannot be verified, stunnel will drop the
- connection (and print a failure message in its log file).
-
- A third example, using the VNC viewer on Unix with stunnel the wrapper
- script can be used this way: "ss_vncviewer -verify ./x11vnc.crt
- far-away.east:0" where ./x11vnc.crt is the copied certificate x11vnc
- printed out.
-
- As fourth example, our SSVNC enhanced tightvnc viewer can also use
- these certificate files for server authentication. You can load them
- via the SSVNC 'Certs...' dialog and set 'ServerCert' to the
- certificate file you safely copied there.
-
- Note that in principle the copying of the certificate to the client
- machine(s) itself could be altered by a Man-In-The-Middle attack! You
- can't win; it is very difficult to be completely secure. It is
- unlikely the attacker could predict how you were going to send it
- unless you had, say, done it many times before the same way. SSH is a
- very good way to send it (but of course it too depends on public keys
- being sent unaltered between the two machines!).
-
- If you are really paranoid, I'm sure you'll figure out a really good
- way to transport the certificates. See the Certificate Authority
- scheme below for a way to make this easier (you just have to do it
- once).
-
- _________________________________________________________________
-
- Saving SSL certificates and keys:
-
- Now, it would be very inconvenient to copy the new temporary
- certificate every time x11vnc is run in SSL mode. So for convenience
- there is the "SAVE" keyword to instruct x11vnc to save the certificate
- it creates:
- x11vnc -ssl SAVE -display :0 ...
-
- This behavior is now the default, you must use "TMP" for a temporary
- one. It will save the certificate and private key in these files:
- ~/.vnc/certs/server.crt
- ~/.vnc/certs/server.pem
-
- The ".crt" file contains only the certificate and should be safely
- copied to the VNC Viewer machine(s) that will be authenticating the
- x11vnc server. The ".pem" file contains both the certificate and the
- private key and should be kept secret. (If you don't like the default
- location ~/.vnc/certs, e.g. it is on an NFS share and you are worried
- about local network sniffing, use the -ssldir dir option to point to a
- different directory.)
-
- So the next time you run "x11vnc -ssl SAVE ..." it will read the
- server.pem file directly instead of creating a new one.
-
- You can manage multiple SSL x11vnc server keys in this simple way by
- using:
- x11vnc -ssl SAVE-key2 -display :0 ...
-
- etc, where you put whatever name you choose for the key after "SAVE-".
- E.g. "-ssl SAVE-fred".
-
- Also, if you want to be prompted to possibly change the made up names,
- etc. that x11vnc creates (e.g. "x11vnc-SELF-SIGNED-CERT-7762" for the
- CommonName) for the certificates distinguished name (DN), then use
- "x11vnc -ssl SAVE_PROMPT ...", "x11vnc -ssl SAVE_PROMPT-fred ..." etc.
- when you create the key the first time.
-
- Tip: when prompting, if you choose the CommonName entry to be the full
- internet hostname of the machine the clients will be connecting to
- then that will avoid an annoying dialog box in their Web browsers that
- warn that the CommonName doesn't match the hostname.
-
- _________________________________________________________________
-
- Passphrases for server keys:
-
- Well, since now with the "SAVE" keyword the certificate and key will
- be longer lived, one can next worry about somebody stealing the
- private key and pretending to be the x11vnc server! How to guard
- against this?
-
- The first is that the file is created with perms 600 (i.e. -rw-------)
- to make it harder for an untrusted user to copy the file. A better way
- is to also encrypt the private key with a passphrase. You are prompted
- whether you want to do this or not when the key is first created under
- "-ssl SAVE" mode ("Protect key with a passphrase? y/n"). It is
- suggested that you use a passphrase. The inconvenience is every time
- you run "x11vnc -ssl SAVE ..." you will need to supply the passphrase
- to access the private key:
- 06/04/2006 11:39:11 using PEM /home/runge/.vnc/certs/server.pem 0.000s
-
- A passphrase is needed to unlock an OpenSSL private key (PEM file).
- Enter passphrase>
-
- before x11vnc can continue.
-
- _________________________________________________________________
-
- Being your own Certificate Authority:
-
- A very sophisticated way that scales well if the number of users is
- large is to use a Certificate Authority (CA) whose public certificate
- is available to all of the VNC clients and whose private key has been
- used to digitally sign the x11vnc server certificate(s).
-
- The idea is as follows:
- * A special CA cert and key is generated.
- * Its private key is always protected by a good passphrase since it
- is only used for signing.
- * The CA cert is (safely) distributed to all machines where VNC
- clients will run.
- * One or more x11vnc server certs and keys are generated.
- * The x11vnc server cert is signed with the CA private key.
- * x11vnc is run using the server key. (e.g. "-ssl SAVE")
- * VNC clients (viewers) can now authenticate the x11vnc server
- because they have the CA certificate.
-
- The advantage is the CA cert only needs to be distributed once to the
- various machines, that can be done even before x11vnc server certs are
- generated.
-
- As above, it is important the CA private key and the x11vnc server key
- are kept secret, otherwise someone could steal them and pretend to be
- the CA or the x11vnc server if they copied the key. It is recommended
- that the x11vnc server keys are also protected via a passphrase (see
- the previous section).
-
- Optionally, VNC viewer certs and keys could also be generated to
- enable the x11vnc server to authenticate each client. This is not
- normally done (usually a simple viewer password scheme is used), but
- this can be useful in some situations. These optional steps go like
- this:
- * One or more VNC client certs and keys are generated.
- * These VNC client certs are signed with the CA private key.
- * The VNC client certs+keys are safely distributed to the
- corresponding client machines.
- * x11vnc is told to verify clients by using the CA cert. (e.g.
- "-sslverify CA")
- * When VNC clients (viewers) connect, they must authenticate
- themselves to x11vnc by using their client key.
-
- Again, it is a good idea if the client private keys are protected with
- a passphrase, otherwise if stolen they could be used to gain access to
- the x11vnc server. Once distributed to the client machines, there is
- no need to keep the client key on the CA machine that generated and
- signed it. You can keep the client certs if you like because they are
- public.
-
- _________________________________________________________________
-
- How to do the above CA steps with x11vnc:
-
- Some utility commands are provided to ease the cert+key creation,
- signing, and management: -sslGenCA, -sslGenCert, -sslDelCert,
- -sslEncKey, -sslCertInfo. They basically run the openssl(1) command
- for you to manage the certs/keys. It is required that openssl(1) is
- installed on the machine and available in PATH. All commands can be
- pointed to an alternate toplevel certificate directory via the -ssldir
- option if you don't want to use the default ~/.vnc/certs.
-
- 1) To generate your Certificate Authority (CA) cert and key run this:
- x11vnc -sslGenCA
-
- Follow the prompts, you can modify any informational strings you care
- to. You will also be required to encrypt the CA private key with a
- passphrase. This generates these files:
- ~/.vnc/certs/CA/cacert.pem (the CA public certificate)
- ~/.vnc/certs/CA/private/cakey.pem (the encrypted CA private key)
-
- If you want to use a different directory use -ssldir It must supplied
- with all subsequent SSL utility options to point them to the correct
- directory.
-
- 2) To generate a signed x11vnc server cert and key run this:
- x11vnc -sslGenCert server
-
- As with the CA generation, follow the prompts and you can modify any
- informational strings that you care to. This will create the files:
- ~/.vnc/certs/server.crt (the server public certificate)
- ~/.vnc/certs/server.pem (the server private key + public cert)
-
- It is recommended to protect the server private key with a passphrase
- (you will be prompted whether you want to). You will need to provide
- it whenever you start x11vnc using this key.
-
- 3) Start up x11vnc using this server key:
- x11vnc -ssl SAVE -display :0 ...
-
- (SAVE corresponds to server.pem, see -sslGenCert server somename info
- on creating additional server keys, server-somename.crt ...)
-
- 4) Next, safely copy the CA certificate to the VNC viewer (client)
- machine(s). Perhaps:
- scp ~/.vnc/CA/cacert.pem clientmachine:.
-
- 5) Then the tricky part, make it so the SSL VNC Viewer uses this
- certificate! There are a number of ways this might be done, it depends
- on what your client and/or SSL tunnel is. Some examples:
-
- For the SSL Java VNC viewer supplied with x11vnc in
- classes/ssl/VncViewer.jar or classes/ssl/SignedVncViewer.jar:
- * Import the cacert.pem cert into your Web Browser (e.g. Edit ->
- Preferences -> Privacy & Security -> Manage Certificates ->
- WebSites -> Import)
- * Or Import the cacert.pem cert into your Java Plugin (e.g. run
- ControlPanel, then Security -> Certificates -> Secure Site ->
- Import)
-
- When importing, one would give the browser/java-plugin the path to the
- copied cacert.pem file in some dialog. Note that the Web browser or
- Java plugin is used for the server authentication. If the user gets a
- "Site not verified" message while connecting he should investigate
- further.
-
- For the use of stunnel (e.g. on Windows) one would add this to the
- stunnel.conf:
- # stunnel.conf:
- client = yes
- options = ALL
- CAfile = /path/to/cacert.pem # or maybe C:\path\to\cacert.pem
- [myvncssl]
- accept = 5901
- connect = far-away.east:5900
-
- (then point the VNC viewer to localhost:1).
-
- Here is an example for the Unix stunnel wrapper script ss_vncviewer in
- our SSVNC package:
- ss_vncviewer -verify ./cacert.pem far-away.east:0
-
- Our SSVNC enhanced tightvnc viewer GUI can also use the certificate
- file for server authentication. You can load it via the SSVNC
- 'Certs...' dialog and set 'ServerCert' to the cacert.pem file you
- safely copied there.
-
- _________________________________________________________________
-
- Tricks for server keys:
-
- To create additional x11vnc server keys do something like this:
- x11vnc -sslGenCert server myotherkey
-
- and use it this way:
- x11vnc -ssl SAVE-myotherkey ...
-
- The files will be ~/.vnc/certs/server-myotherkey.{crt,pem}
-
- You can also create a self-signed server key:
- x11vnc -sslGenCert server self:third_key
-
- and use it this way:
- x11vnc -ssl SAVE-self:third_key ...
-
- This key is not signed by your CA. This can be handy to have a key set
- separate from your CA when you do not want to create a 2nd CA
- cert+key.
-
- _________________________________________________________________
-
- Using external CA's:
-
- You don't have to use your own CA cert+key, you can use a third
- party's instead. Perhaps you have a company-wide CA or you can even
- have your x11vnc certificate signed by a professional CA (e.g.
- www.thawte.com or www.verisign.com or perhaps the free certificate
- service www.startcom.org or www.cacert.org).
-
- The advantage to doing this is that the VNC client machines will
- already have the CA certificates installed and you don't have to
- install it on each machine.
-
- To generate an x11vnc server cert+key this way you should generate a
- "request" for a certicate signing something like this (we use the name
- "external" in this example, it could be anything you want):
- x11vnc -sslGenCert server req:external
-
- This will create the request file:
- ~/.vnc/certs/server-req:external.req
-
- Which you should send to the external CA. When you get the signed
- certificate back from them, save it in the file:
- ~/.vnc/certs/server-req:external.crt
-
- and create the .pem this way:
- mv ~/.vnc/certs/server-req:external.key ~/.vnc/certs/server-req:external.
-pem
- chmod 600 ~/.vnc/certs/server-req:external.pem
- cat ~/.vnc/certs/server-req:external.crt >> ~/.vnc/certs/server-req:external.
-pem
-
- You also rename the two files (.crt and .pem) to have a shorter
- basename if you like. E.g.:
- mv ~/.vnc/certs/server-req:external.pem ~/.vnc/certs/server-ext.pem
- mv ~/.vnc/certs/server-req:external.crt ~/.vnc/certs/server-ext.crt
-
- and the use via "x11vnc -ssl SAVE-ext ...", etc.
-
- On the viewer side make sure the external CA's certificate is
- installed an available for the VNC viewer software you plan to use.
-
- _________________________________________________________________
-
- Using Client Keys for Authentication:
-
- You can optionally create certs+keys for your VNC client machines as
- well. After distributing them to the client machines you can have
- x11vnc verify the clients using SSL. Here is how to do this:
-
- x11vnc -sslGenCert client dilbert
- x11vnc -sslGenCert client wally
- x11vnc -sslGenCert client alice
- ...
-
- As usual, follow the prompts if you want to change any of the info
- field values. As always, it is a good idea (although inconvenient) to
- protect the private keys with a passphrase. These files are created:
- ~/.vnc/certs/clients/dilbert.crt
- ~/.vnc/certs/clients/dilbert.pem
- ...
-
- Note that these are kept in a clients subdirectory.
-
- Next, safely copy the .pem files to each corresponding client machine
- and incorporate them into the VNC viewer / SSL software (see the ideas
- mentioned above for the CA and server keys). The only difference is
- these certificates might be referred to as "My Certificates" or
- "Client Certificates". They are used for client authentication (which
- is relatively rare for SSL).
-
- After copying them you can delete the clients/*.pem files for extra
- safety because the private keys are not needed by the x11vnc server.
- You don't really need the clients/*.crt files either (because they
- have been signed by the CA). But they could come in handy for tracking
- or troubleshooting, etc.
-
- Now start up x11vnc and instruct it to verify connecting clients via
- SSL and the CA cert:
- x11vnc -ssl SAVE -sslverify CA
-
- The "CA" special token instructs x11vnc to use its CA signed certs for
- verification.
-
- For arbitrary self-signed client certificates (no CA) it might be
- something like this:
- x11vnc -ssl SAVE -sslverify path/to/client.crt
- x11vnc -ssl SAVE -sslverify path/to/client-hash-dir
- x11vnc -ssl SAVE -sslverify path/to/certs.txt
-
- Where client.crt would be an individual client certificate;
- client-hash-dir a directory of file names based on md5 hashes of the
- certs (see -sslverify); and certs.txt signifies a single file full of
- client certificates.
-
- Finally, connect with your VNC viewer using the key. Here is an
- example for the Unix stunnel wrapper script ss_vncviewer: using client
- authentication (and the standard server authentication with the CA
- cert):
- ss_vncviewer -mycert ./dilbert.pem -verify ./cacert.pem far-away.east:0
-
- Our SSVNC enhanced tightvnc viewer can also use these openssl .pem
- files (you can load them via Certs... -> MyCert dialog).
-
- It is also possible to use -sslverify on a per-client key basis, and
- also using self-signed client keys (x11vnc -sslGenCert client
- self:dilbert)
-
- Now a tricky part is to get Web browsers or Java Runtime to import and
- use the openssl .pem cert+key files. See the next paragraph on how to
- convert them to pkcs12 format. If you find a robust way to import them
- and and get them to use the cert please let us know!
-
- Here is how to convert our openssl crt/pem files to pkcs12 format
- (contains both the client certificate and key) that can be read by Web
- browsers and Java for use in client authentication:
- openssl pkcs12 -export -in mycert.crt -inkey mycert.pem -out mycert.p12
-
- it will ask for a passphrase to protect mycert.p12. Some software
- (e.g. Java ControlPanel) may require a non-empty passphrase. Actually,
- since our .pem contains both the certificate and private key, you
- could just supply it for the -in and remove the -inkey option. It
- appears that for certificates only importing, our .crt file is
- sufficient and can be read by Mozilla/Firefox and Java...
-
- If you have trouble getting your Java Runtime to import and use the
- cert+key, there is a workaround for the SSL-enabled Java applet. On
- the Web browser URL that retrieves the VNC applet, simply add a
- "/?oneTimeKey=..." applet parameter (see ssl-portal for more details
- on applet parameters; you don't need to do the full portal setup
- though). The value of the oneTimeKey will be the very long string that
- is output of the onetimekey program found in the classes/ssl x11vnc
- directory. Or you can set oneTimeKey=PROMPT in which case the applet
- will ask you to paste in the long string. These scheme is pretty ugly,
- but it works. A nice application of it is to make one time keys for
- users that have already logged into a secure HTTPS site via password.
- A cgi program then makes a one time key for the logged in user to use:
- it is passed back over HTTPS as the applet parameter in the URL and so
- cannot be sniffed. x11vnc is run to use that key via -sslverify.
-
- Update: as of Apr 2007 in the 0.9.1 x11vnc tarball there is a new
- option setting "-users sslpeer=" that will do a switch user much like
- -unixpw does, but this time using the emailAddress field of the
- Certificate subject of the verified Client. This mode requires
- -sslverify turned on to verify the clients via SSL. This mode can be
- useful in situations using -create or -svc where a new X server needs
- to be started up as the authenticated user (but unlike in -unixpw
- mode, the unix username is not obviously known).
-
- _________________________________________________________________
-
- Revoking Certificates:
-
- A large, scaled-up installation may benefit from being able to revoke
- certificates (e.g. suppose a user's laptop with a vnc client or server
- key is compromised.) You can use this option with x11vnc: -sslCRL. See
- the info at that link for a guide on what openssl(1) commands you will
- need to run to revoke a certificate.
-
- _________________________________________________________________
-
- Additional utlities:
-
- You can get information about your keys via -sslCertInfo. These lists
- all your keys:
- x11vnc -sslCertInfo list
- x11vnc -sslCertInfo ll
-
- (the latter is long format).
-
- These print long output, including the public certificate, for
- individual keys:
- x11vnc -sslCertInfo server
- x11vnc -sslCertInfo dilbert
- x11vnc -sslCertInfo all (every key, very long)
-
- If you want to add a protecting passphrase to a key originally created
- without one:
- x11vnc -sslEncKey SAVE
- x11vnc -sslEncKey SAVE-fred
-
- To delete a cert+key:
- x11vnc -sslDelCert SAVE
- x11vnc -sslDelCert SAVE-fred
- x11vnc -sslDelCert wally
-
- (but rm(1) will be just as effective).
-
- _________________________________________________________________
-
- Chained Certificates:
-
- There is increasing interest in using chained CA's instead of a single
- CA. The merits of using chained CA's are not described here besides to
- say its use may make some things easier when a certificate needs to be
- revoked.
-
- x11vnc supports chained CA certificates. We describe a basic use case
- here.
-
- Background: Of course the most straight forward way to use SSL with
- x11vnc is to use no CA at all (see above): a self-signed certificate
- and key is used and its certificate needs to be safely copied to the
- client side. This is basically the same as the SSH style of managing
- keys. Next level up, one can use a single CA to sign server keys: then
- only the CA's certificate needs to be safely copied to the client
- side, this can happen even before any server certs are created (again,
- see all of the discussion above.)
-
- With a certificate chain there are two or more CA's involved. Perhaps
- it looks like this:
- root_CA ---> intermediate_CA ---> server_cert
-
- Where the arrow basically means "signs".
-
- In this usage mode the client (viewer-side) will have root_CA's
- certificate available for verifying (and nothing else.) If the viewer
- only received server_cert's certificate, it would not have enough info
- to verify the server. The client needs to have intermediate_CA's cert
- as well. The way to do this with x11vnc (i.e. an OpenSSL using app) is
- to concatenate the server_cert's pem and the intermediate_CA's
- certificate together.
-
- For example, suppose the file intermediate_CA.crt had
- intermediate_CA's certificate. And suppose the file server_cert.pem
- had the server's certificate and private key pair as described above
- on this page. We need to do this:
- cat intermediate_CA.crt >> server_cert.pem
-
- (Note: the order of the items inside the file matters; intermediate_CA
- must be after the server key and cert) and then we run x11vnc like
- this:
- x11vnc -ssl ./server_cert.pem ...
-
- Then, on the VNC viewer client side, the viewer authenticates the
- x11vnc server by using root_CA's certificate. Suppose that is in a
- file named root_CA.crt, then using the SSVNC wrapper script
- ss_vncviewer (which is also included in the SSVNC package) as our
- example, we have:
- ss_vncviewer -verify ./root_CA.crt hostname:0
-
- (where "hostname" is the machine where x11vnc is running.) One could
- also use the SSVNC GUI setting Certs -> ServerCert to the root_CA.crt
- file. Any other SSL enabled VNC viewer would use root_CA.crt in a
- similar way.
- _________________________________________________________________
-
- Creating Chained Certificates:
-
- Here is a fun example using VeriSign's "Trial Certificate" program.
- Note that VeriSign has a Root CA and also an Intermediate CA and uses
- the latter to sign customers certificates. So this provides an easy
- way to test out the chained certificates mechanism with x11vnc.
-
- First we created a test x11vnc server key:
- openssl genrsa -out V1.key 1024
-
- then we created a certificate signing request (CSR) for it:
- openssl req -new -key V1.key -out V1.csr
-
- (we followed the prompts and supplied information for the various
- fields.)
-
- Then we went to VeriSign's page http://www.verisign.com/ssl/index.html
- and clicked on "FREE TRIAL" (the certificate is good for 14 days.) We
- filled in the forms and got to the point where it asked for the CSR
- and so we pasted in the contents of the above V1.csr file. Then, after
- a few more steps, VeriSign signed and emailed us our certificate.
-
- The VeriSign Trial certificates were found here:
- http://www.verisign.com/support/verisign-intermediate-ca/Trial_Secure_Server_
-Root/index.html
- http://www.verisign.com/support/verisign-intermediate-ca/trial-secure-server-
-intermediate/index.html
-
- The former was pasted into a file V-Root.crt and the latter was pasted
- into V-Intermediate.crt
-
- We pasted our Trial certificate that VeriSign signed and emailed to us
- into a file named V1.crt and then we typed:
- cat V1.key V1.crt > V1.pem
- cat V1.pem V-Intermediate.crt > V1-combined.pem
- chmod 600 V1.pem V1-combined.pem
-
- So now the file V1-combined.pem has our private key and (VeriSign
- signed) certificate and VeriSign's Trial Intermediate certificate.
-
- Next, we start x11vnc:
- x11vnc -ssl ./V1-combined.pem ...
-
- and finally, on the viewer side (SSVNC wrapper script example):
- ss_vncviewer -verify ./V-Root.crt hostname:0
-
- One will find that only that combination of certs and keys will work,
- i.e. allow the SSL connection to be established. Every other
- combination we tried failed (note that ss_vncviewer uses the external
- stunnel command to handle the SSL so we are really testing stunnel's
- SSL implementation on the viewer side); and so the system works as
- expected.
- _________________________________________________________________
-
- VNC Client Authentication using Certificate Chains:
-
- Now, going the other way around with the client authenticating himself
- via this chain of SSL certificates, x11vnc is run this way:
- x11vnc -ssl SAVE -sslverify ./V-Root.crt ...
-
- (note since the server must always supply a cert, we use its normal
- self-signed, etc., one via "-ssl SAVE" and use the VeriSign root cert
- for client authentication via -sslverify. The viewer must now supply
- the combined certificates, e.g.:
- ss_vncviewer -mycert ./V1-combined.pem hostname:0
- _________________________________________________________________
-
- Using OpenSSL and x11vnc to create Certificate Chains:
-
- Although the x11vnc CA mechanism (-sslGenCA and -sslGenCert; see
- above) was designed to only handle a single root CA (to sign server
- and/or client certs) it can be coerced into creating a certificate
- chain by way of an extra openssl(1) command.
-
- We will first create two CA's via -sslGenCA; then use one of these CA
- to sign the other; create a new (non-CA) server cert; and append the
- intermediate CA's cert to the server cert to have everything needed in
- the one file.
-
- Here are the commands we ran to do what the previous paragraph
- outlines.
-
- First we create the two CA's, called CA_root and CA_Intermediate here,
- in separate directories via x11vnc:
- x11vnc -ssldir ~/CA_Root -sslGenCA
- (follow the prompts, we included "CA_Root", e.g. Common Name, to aid ident
-ifying it)
-
- x11vnc -ssldir ~/CA_Intermediate -sslGenCA
- (follow the prompts, we included "CA_Intermediate", e.g. Common Name, to a
-id identifying it)
-
- Next backup CA_Intermediate's cert and then sign it with CA_Root:
- mv ~/CA_Intermediate/CA/cacert.pem ~/CA_Intermediate/CA/cacert.pem.ORIG
- cd ~/CA_Root
- openssl ca -config ./CA/ssl.cnf -policy policy_anything -extensions v3_ca -no
-text -ss_cert ~/CA_Intermediate/CA/cacert.pem.ORIG -out ~/CA_Intermediate/CA/ca
-cert.pem
-
- Note that it is required to cd to the ~/CA_Root directory and run the
- openssl command from there.
-
- You can print out info about the cert you just modified by:
- openssl x509 -noout -text -in ~/CA_Intermediate/CA/cacert.pem
-
- Now we create an x11vnc server cert named "test_chain" that is signed
- by CA_Intermediate:
- x11vnc -ssldir ~/CA_Intermediate -sslGenCert server test_chain
- (follow the prompts)
-
- You can print out information about this server cert just created via
- this command:
- x11vnc -ssldir ~/CA_Intermediate -sslCertInfo SAVE-test_chain
-
- This will tell you the full path to the server certificate, which is
- needed because we need to manually append the CA_Intermediate cert for
- the chain to work:
- cat ~/CA_Intermediate/CA/cacert.pem >> ~/CA_Intermediate/server-test_chain.pe
-m
-
- Now we are finally ready to use it. We can run x11vnc using this
- server cert+key by either this command:
- x11vnc -ssldir ~/CA_Intermediate -ssl SAVE-test_chain ...
-
- or this command:
- x11vnc -ssl ~/CA_Intermediate/server-test_chain.pem ...
-
- since they are equivalent (both load the same pem file.)
-
- Finally we connect via VNC viewer that uses CA_Root to verify the
- server. As before we use ss_vncviewer:
- ss_vncviewer -verify ~/CA_Root/CA/cacert.pem hostname:0
-
- Client Certificates (see above) work in a similar manner.
-
- So although it is a little awkward with the extra steps (e.g.
- appending the CA_Intermediate cert) it is possible. If you want to do
- this entirely with openssl(1) you will have to learn the openssl
- commands corresponding to -genCA and -genCert. You may be able to find
- guides on the Internet to do this. Starting with x11vnc 0.9.10, you
- can have it print out the wrapper scripts it uses via: -sslScripts
- (you will still need to fill in a few pieces of information; ask if it
- is not clear from the source code.)
-
- _________________________________________________________________
-
- More info:
-
- See also this article for some some general info and examples using
- stunnel and openssl on Windows with VNC. Also
- http://www.stunnel.org/faq/certs.html is a very good source of
- information on SSL certificate creation and management.
-
-=======================================================================
-http://www.karlrunge.com/x11vnc/ssl-portal.html:
-
-
- _________________________________________________________________
-
- Using Apache as an SSL Gateway to multiple x11vnc servers inside a
- firewall:
-
- Background:
-
- The typical way to allow access to x11vnc (or any other VNC server)
- running on multiple workstations inside a firewall is via SSH. The
- user somewhere out on the Internet logs in to the SSH gateway machine
- and uses port forwarding (e.g. ssh -t -L 5900:myworkstation:5900
- user@gateway) to set up the encrypted channel that VNC is then
- tunneled through. Next he starts up the VNC viewer on the machine
- where he is sitting directed to the local tunnel port (e.g.
- localhost:0).
-
- The SSH scheme is nice because it is a widely used and well tested
- login technique for users connecting to machines inside their company
- or home firewall. For VNC access it is a bit awkward, however, because
- SSH needs to be installed on the Viewer machine and the user usually
- has to rig up his own port redirection plumbing (however, see our
- other tool).
-
- Also, some users have restrictive work environments where SSH and
- similar applications are prohibited (i.e. only outgoing connections to
- standard WWW ports from a browser are allowed, perhaps mediated by a
- proxy server). These users have successfully used the method described
- here for remote access.
-
- With the SSL support in x11vnc and the SSL enabled Java VNC viewer
- applet, a convenient and secure alternative exists that uses the
- Apache webserver as a gateway. The idea is that the company or home
- internet connection is already running apache as a web server (either
- SSL or non-SSL) and we add to it the ability to act as a gateway for
- SSL VNC connections. The only thing needed on the Viewer side is a
- Java enabled Web Browser: the user simply enters a URL that starts the
- entire VNC connection process. No VNC or SSH specific software needs
- to be installed on the viewer side machine.
-
- The stunnel VNC viewer stunnel wrapper script provided (ss_vncviewer)
- can also take advantage of the method described here with its -proxy
- option.
-
- _________________________________________________________________
-
- Simpler Solutions: This apache SSL VNC portal solution may be too much
- for you. It is mainly intended for automatically redirecting to
- MULTIPLE workstations inside the firewall. If you only have one or two
- inside machines that you want to access, the method described here is
- overly complicated! See below for some simpler (and still non-SSH)
- encrypted setups.
-
- Also see the recent (Mar/2010) desktop.cgi x11vnc desktop web login
- CGI script that achieves much of what the method describes here
- (especially if its 'port redirection' feature is enabled.)
- _________________________________________________________________
-
-
-
- There are numerous ways to achieve this with Apache. We present one of
- the simplest ones here.
-
- Important: these sorts of schemes allow incoming connections from
- anywhere on the Internet to fixed ports on machines inside the
- firewall. Care must be taken to implement and test thoroughly. If one
- is paranoid one can (and should) add extra layers of protection. (e.g.
- extra passwords, packet filtering, SSL certificate verification, etc).
-
- Also, it is easy to miss the point that unless precautions are taken
- to verify SSL Certificates, then the VNC Viewer is vulnerable to
- man-in-the-middle attacks (but not to the more common passive sniffing
- attacks). Note that there are hacker tools like dsniff/webmitm and
- cain that implement SSL Man-In-The-Middle attacks. They rely on the
- client not bothering to check the cert.
- _________________________________________________________________
-
- The Holy Grail: a single https port (443)
-
- Before we discuss the self-contained apache examples here, we want to
- mention that many x11vnc users who read this page and implement the
- apache SSL VNC portal ask for something that (so far) seems difficult
- or impossible to do entirely inside apache:
- * A single port, 443 (the default https:// port), is open to the
- Internet
- * It is HTTPS/SSL encrypted
- * It handles both VNC traffic and Java VNC Applet downloads.
- * And the server can also serve normal HTTPS webpages, CGI, etc.
-
- It is the last item that makes it tricky (otherwise the method
- described on this page will work). If you are interested in such a
- solution and are willing to run a separate helper program
- (connect_switch) look here. Also, see this apache patch.
- _________________________________________________________________
-
- Example:
-
- The scheme described here sets up apache on the firewall/gateway as a
- regular Web proxy into the intranet and allows connections to a single
- fixed port on a limited set of machines.
-
- The configuration described in this section does not use the mod_ssl
- apache module (the optional configuration described in the section
- "Downloading the Java applet to the browser via HTTPS" does take
- advantage of mod_ssl)
-
- In this example suppose the gateway machine running apache is named
- "www.gateway.east" (e.g. it may also provide normal web service). We
- also choose the Internet-facing port for this VNC service to be port
- 563. One could choose any port, including the default HTTP port 80.
-
- Detail: We choose 563 because it is the rarely used SNEWS port that is
- often allowed by Web proxies for the CONNECT method. The idea is the
- user may be coming out of another firewall using a proxy (not the one
- we describe here, that is, the case when two proxies are involved,
- e.g. one at work and another Apache (described here) at home
- redirecting into our firewall; the "double proxy" or "double firewall"
- problem). Using port 563 simplifies things because CONNECT's to it are
- usually allowed by default.
-
- We also assume all of the x11vnc servers on the internal machines are
- all listening on port 5915 ("-rfbport 5915") instead of the default
- 5900. This is to limit any unintended proxy redirections to a lesser
- used port, and also to stay out of the way of normal VNC servers on
- the same machines. One could obviously implement a scheme that handles
- different ports, but we just discuss this simple setup here.
-
- So we basically assume x11vnc has been started this way on all of the
- workstations to be granted VNC access:
- x11vnc -ssl SAVE -http -display :0 -forever -rfbauth ~/.vnc/passwd -rfbport 5
-915
-
- i.e. we force SSL VNC connections, port 5915, serve the Java VNC
- viewer applet, and require a VNC password (another option would be
- -unixpw). The above command could also be run out of inetd(8). It can
- also be used to autodetect the user's display and Xauthority data.
-
-
- These sections are added to the httpd.conf apache configuration file
- on www.gateway.east:
-
-# In the global section you need to enable these modules.
-# Note that the ORDER MATTERS! mod_rewrite must be before mod_proxy
-# (so that we can check the allowed host list via rewrite)
-#
-LoadModule rewrite_module modules/mod_rewrite.so
-LoadModule proxy_module modules/mod_proxy.so
-LoadModule proxy_connect_module modules/mod_proxy_connect.so
-LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
-LoadModule proxy_http_module modules/mod_proxy_http.so
-<IfDefine SSL>
-LoadModule ssl_module modules/mod_ssl.so
-</IfDefine>
-
-
-# Near the bottom of httpd.conf you put the port 563 virtual host:
-
-Listen 563
-
-<VirtualHost *:563>
-
- # Allow proxy CONNECT requests *only* to port 5915.
- # If the machines use different ports, e.g. 5916 list them here as well:
- #
- ProxyRequests On
- AllowCONNECT 5915
-
- RewriteEngine On
-
- # Convenience rules to expand applet parameters. These do not have a traili
-ng "/"
- #
- # /vnc for http jar file downloading:
- #
- RewriteRule /vnc/([^/]+)$ /vnc/$1/index.vnc?CONNECT=$1+5915&PO
-RT=563&urlPrefix=_2F_vnc_2F_$1 [R,NE,L]
- RewriteRule /vnc/trust/([^/]+)$ /vnc/$1/index.vnc?CONNECT=$1+5915&PO
-RT=563&urlPrefix=_2F_vnc_2F_$1&trustAllVncCerts=yes [R,NE,L]
- RewriteRule /vnc/proxy/([^/]+)$ /vnc/$1/proxy.vnc?CONNECT=$1+5915&PO
-RT=563&urlPrefix=_2F_vnc_2F_$1&forceProxy=yes [R,NE,L]
- RewriteRule /vnc/trust/proxy/([^/]+)$ /vnc/$1/proxy.vnc?CONNECT=$1+5915&PO
-RT=563&urlPrefix=_2F_vnc_2F_$1&forceProxy=yes&trustAllVncCerts=yes [R,NE,L]
-
- # Read in the allowed host to vnc display mapping file. It looks like:
- #
- # host1 15
- # host2 15
- # ...
- #
- # the display "15" means 5815 for http applet download, 5915 for SSL vnc.
- #
- RewriteMap vnchosts txt:/dist/apache/conf/vnc.hosts
-
- # Proxy: check for the CONNECT hostname and port being in the vnc.hosts list
-.
- #
- RewriteCond %{THE_REQUEST} ^CONNECT [NC]
- RewriteCond %{REQUEST_URI} ^(.*):(.*)$
- RewriteCond ${vnchosts:%1|NOTFOUND} NOTFOUND
- RewriteRule ^.*$ /VNCFAIL [F,L]
-
- RewriteCond %{THE_REQUEST} ^CONNECT [NC]
- RewriteCond %{REQUEST_URI} ^(.*):(.*)$
- RewriteCond 59${vnchosts:%1}=%2 !^(.*)=(\1)$
- RewriteRule ^.*$ /VNCFAIL [F,L]
-
-
- # Remap /vnc to the proxy http download (e.g. http://host:5815)
- #
- # First, fail if it starts with the string /vnc0:
- #
- RewriteRule ^/vnc0.* /VNCFAIL [F,L]
- #
- # Next, map the prefix to /vnc0/host:protocol:port
- #
- RewriteRule ^/vnc/([^/]+)/(.*) /vnc0/$1:http:58${vnchosts:$1|NOTFOUND}/$2
-[NE]
- #
- # Drop any not found:
- #
- RewriteRule ^/vnc0.*NOTFOUND.* /VNCFAIL [F,L]
-
- # Construct the proxy URL and retrieve it:
- #
- RewriteRule ^/vnc0/([^/]+):([^/]+):([^/]+)/(.*) $2://$1:$3/$4 [P,NE,L]
-
-</VirtualHost>
-
- Then restart apache (perhaps: "apachectl stop; apachectl start").
-
- Note that the listing of allowed internal workstations is done in an
- external file (/dist/apache/conf/vnc.hosts in the example above), the
- format is like this:
-# allowed vnc hosts file:
-hostname1 15
-hostname2 15
-...
-
- You list the hostname and the VNC display (always 15 in our example).
- Only to these hosts will the external VNC viewers be able to connect
- to (via the HTTP CONNECT method).
-
- The above setup requires mod_rewrite and mod_proxy be enabled in the
- apache web server. In this example they are loaded as modules (and
- note that mod_rewrite must be listed before mod_proxy);
-
- The user at the Java enabled Web browser would simply enter this URL
- into the browser:
- http://www.gateway.east:563/vnc/host2
-
- to connect to internal workstation host2, etc.
-
- Important: do not put a trailing "/" on the URL, since that will
- defeat the RewriteRules that look for the hostname at the very end.
-
- There will be a number of SSL certificate, etc, dialogs he will have
- to respond to in addition to any passwords he is required to provide
- (this depends on how you set up user authentication for x11vnc).
-
- If a second Web proxy is involved (i.e. the user's browser is inside
- another firewall and policy requires using a Web proxy server) then
- use this URL:
- http://www.gateway.east:563/vnc/proxy/host2
-
- This will involve downloading a signed java viewer applet jar file
- that is able to interact with the internal proxy for the VNC
- connection. See this FAQ for more info on how this works. Note:
- sometimes with the Proxy case if you see 'Bad Gateway' error you will
- have to wait 10 or so seconds and then hit reload. This seems to be
- due to having to wait for a Connection Keepalive to terminate...
-
- For completeness, the "trust" cases that skip a VNC certificate dialog
- (discussed below) would be entered as:
- http://www.gateway.east:563/vnc/trust/host2
- http://www.gateway.east:563/vnc/trust/proxy/host2
-
- You can of course choose shorter or more easy to remember URL formats.
- Just change the Convenience RewriteRules in httpd.conf.
-
- _________________________________________________________________
-
- Port Variations:
-
- Note that you can run this on the default HTTP port 80 instead of port
- 563. If you do not expect to have a browser connecting from inside a
- proxying firewall (where sometimes only connections to ports 443 and
- 563 are allowed) this should be fine. Use "80" instead of "563" in the
- httpd.conf config file (you may need to merge it with other default
- port 80 things you have there).
-
- Then the URL's will be a bit simpler:
- http://www.gateway.east/vnc/host2
- http://www.gateway.east/vnc/trust/host2
-
- etc.
-
- Besides 80 one could use any other random port number (since there are
- so many port scans on 80, a little obscurity might be useful).
-
- One option is to use port "443" (the default https:// port) instead of
- "563". In this case Apache is not configured for mod_ssl; we just
- happen to use port "443" in the way any random port would be used.
- This could be handy if the Viewer side environment is restrictive in
- that it only allows outgoing connections to ports 80 and 443 (and,
- say, you didn't want to use port 80, or you wanted to use 80 for
- something else). Another reason for using 443 would be some web proxy
- environments only allow the CONNECT method to go to port 443 (and not
- even the case 563 we use above).
-
- _________________________________________________________________
-
- Details:
-
- Let's go through the httpd.conf additions in detail from the top.
-
- The LoadModules directives load the necessary apache modules. Note
- that mod_rewrite must be listed first. If you are compiling from
- scratch something like this worked for us:
- ./configure --enable-proxy=shared --enable-proxy-connect=shared --enable-ssl=
-shared --enable-rewrite=shared --prefix=/dist/apache
-
- Then the VirtualHost *:563 virtual host section starts.
-
- The "ProxyRequests On" and "AllowCONNECT 5915" enable the web server
- to forward proxy requests to port 5915 (and only this port) INSIDE the
- firewall. Think about the implications of this thoroughly and test it
- carefully.
-
- The RewriteRule's are for convenience only so that the URL entered
- into the Web browser does not need the various extra parameters, e.g.:
- http://www.gateway.east:563/vnc/host2/index.vnc?CONNECT=host2+5915&PORT=563,
-blah,blah...
-
- (or otherwise make direct edits to index.vnc to set these parameters).
- The forceProxy=yes parameter is passed to the applet to force the use
- of a outgoing proxy socket connection. Use it only if the Web browser
- is inside a separate Web proxying environment (i.e. large corporation)
-
- The rewrites with parameter urlPrefix are described under Tricks for
- Better Response. The "trust" ones (also described under Tricks) with
- trustAllVncCerts tell the Java VNC applet to skip a dialog asking
- about the VNC Certificate. They are a bit faster and more reliable
- than the original method. In the best situation they lead to being
- logged in 20 seconds or less (without them the time to login can be
- much longer since a number of connections must timeout).
-
- All of the x11vnc Java Viewer applet parameters are described in the
- file classes/ssl/README
-
- The external file /dist/apache/conf/vnc.hosts containing the allowed
- VNC server hostnames is read in. Its 2nd column contains the VNC
- display of the host (always 15 in our example; if you make it vary you
- will need to adjust some lines in the httpd.conf accordingly, e.g.
- AllowCONNECT). This list is used to constrain both the Jar file
- download URL and the proxy CONNECT the VNC viewer makes to only the
- intended VNC servers.
-
- Limiting the proxy CONNECT is done with the two sets of RewriteCond
- conditions.
-
- Limiting the Jar file download URL is done in the remaining 4
- RewriteRule's.
-
- Note that these index.vnc and VncViewer.jar downloads to the browser
- are not encrypted via SSL, and so in principle could be tampered with
- by a really bad guy. The subsequent VNC connection, however, is
- encrypted through a single SSL connection (it makes a CONNECT straight
- to x11vnc). See below for how to have these initial downloads
- encrypted as well (if the apache web server has SSL/mod_ssl, i.e.
- https, enabled and configured).
-
- Unfortunately the Java VNC viewer applet currently is not able to save
- its own list of Certificates (e.g. the user says trust this VNC
- certificate 'always'). This is because an applet it cannot open local
- files, etc. Sadly, the applet cannot even remember certificates in the
- same browser session because it is completely reinitialized for each
- connection (see below).
-
- _________________________________________________________________
-
- Too Much?
-
- If these apache rules are a little too much for you, there is a little
- bit simpler scheme where you have to list each of the individual
- machines in the httpd.conf and ssl.conf files. It may be a little more
- typing to maintain, but perhaps being more straight forward (less
- RewriteRule's) is desirable.
-
- _________________________________________________________________
-
- Problems?
-
- To see example x11vnc output for a successful https://host:5900/
- connection with the Java Applet see This Page.
-
- _________________________________________________________________
-
- Some Ideas for adding extra authentication, etc. for the paranoid:
- * VNC passwords: -rfbauth, -passwdfile, or -usepw. Even adding a
- simple company-wide VNC password helps block unwanted access.
- * Unix passwords: -unixpw
- * SSL Client certificates: -sslverify
- * Apache AuthUserFile directive: .htaccess, etc.
- * Filter connections based on IP address or hostname.
- * Use Port-knocking on your firewall as described in: Enhanced
- TightVNC Viewer (ssvnc).
- * Add proxy password authentication (requires Viewer changes?)
- * Run a separate instance of Apache that provides this VNC service
- so it can be brought up and down independently of the normal web
- server.
- * How secure is the Client side? Public machines in internet cafes,
- etc, are often hacked, with backdoors and VNC servers of their
- own. Prefer using your own firewalled laptop to a public machine.
-
-
- _________________________________________________________________
-
- Using non-Java viewers with this scheme:
-
- The ss_vncviewer stunnel wrapper script for VNC viewers has the -proxy
- option that can take advantage of this method.
- ss_vncviewer -proxy www.gateway.east:563 host1:15
-
- For the case of the "double proxy" situation (see below) supply both
- separated by a comma.
- ss_vncviewer -proxy proxy1.foobar.com:8080,www.gateway.east:563 host1:15
-
- For the Enhanced TightVNC Viewer (ssvnc) GUI (it uses ss_vncviewer on
- Unix) put 'host1:15' into the 'VNC Server' entry box, and here are
- possible Proxy/Gateway entries
- Proxy/Gateway: www.gateway.east:563
- Proxy/Gateway: proxy1.foobar.com:8080,www.gateway.east:563
-
- then click on the 'Connect' button.
-
- _________________________________________________________________
-
- Downloading the Java applet to the browser via HTTPS:
-
- To have the Java applet downloaded to the user's Web Browser via an
- encrypted (and evidently safer) SSL connection the Apache webserver
- should be configured for SSL via mod_ssl.
-
- It is actually possible to use the x11vnc Key Management utility
- "-sslGenCert" to generate your Apache/SSL .crt and .key files. (In
- brief, run something like "x11vnc -sslGenCert server self:apache" then
- copy the resulting self:apache.crt file to conf/ssl.crt/server.crt and
- extract the private key part from self:apache.pem and paste it into
- conf/ssl.key/server.key). Setting the env var REQ_ARGS='-days 1095'
- before running x11vnc will bump up the expiration date (3 years in
- this case).
-
- Or you can use the standard methods described in the Apache mod_ssl
- documentation to create your keys. Then restart Apache, usually
- something like "apachectl stop" followed by "apachectl startssl"
-
- In addition to the above sections in httpd.conf one should add the
- following to ssl.conf:
- SSLProxyEngine On
-
- RewriteEngine On
-
- # Convenience rules to expand applet parameters. These do not have a traili
-ng "/"
- #
- # /vnc http jar file downloading:
- #
- RewriteRule /vnc/([^/]+)$ /vnc/$1/index.vnc?CONNECT=$
-1+5915&PORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vnc_2F_$1 [R,NE,L]
- RewriteRule /vnc/proxy/([^/]+)$ /vnc/$1/proxy.vnc?CONNECT=$
-1+5915&PORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vnc_2F_$1&forceProxy=yes [R,N
-E,L]
- #
- # (we skipped the "trust" ones above, put them in if you like)
- #
- # /vncs https jar file downloading:
- #
- RewriteRule /vncs/([^/]+)$ /vncs/$1/index.vnc?CONNECT=$
-1+5915&PORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1 [R,NE,L]
- RewriteRule /vncs/proxy/([^/]+)$ /vncs/$1/proxy.vnc?CONNECT=$
-1+5915&PORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1&forceProxy=yes [R,
-NE,l]
- RewriteRule /vncs/trust/([^/]+)$ /vncs/$1/index.vnc?CONNECT=$
-1+5915&PORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1&trustAllVncCerts=y
-es [R,NE,L]
- RewriteRule /vncs/trust/proxy/([^/]+)$ /vncs/$1/proxy.vnc?CONNECT=$
-1+5915&PORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1&forceProxy=yes&tru
-stAllVncCerts=yes [R,NE,L]
-
- # Convenience rules used for the connect_switch helper (requires Listen 127.
-0.0.1:443 above):
- #
- RewriteRule /vnc443/([^/]+)$ /vncs/$1/index.vnc?CONNECT=$
-1+5915&PORT=443&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1 [R,NE,L]
- RewriteRule /vnc443/proxy/([^/]+)$ /vncs/$1/proxy.vnc?CONNECT=$
-1+5915&PORT=443&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1&forceProxy=yes [R,
-NE,L]
- RewriteRule /vnc443/trust/([^/]+)$ /vncs/$1/index.vnc?CONNECT=$
-1+5915&PORT=443&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1&trustAllVncCerts=y
-es [R,NE,L]
- RewriteRule /vnc443/trust/proxy/([^/]+)$ /vncs/$1/proxy.vnc?CONNECT=$
-1+5915&PORT=443&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1&forceProxy=yes&tru
-stAllVncCerts=yes [R,NE,L]
-
- # Read in the allowed host to vnc display mapping file. It looks like:
- #
- # host1 15
- # host2 15
- # ...
- #
- # the display "15" means 5915 for SSL VNC and 5815 for http applet download.
- #
- RewriteMap vnchosts txt:/dist/apache/conf/vnc.hosts
-
-
- # Remap /vnc and /vncs to the proxy http download (e.g. https://host:5915)
- #
- # First, fail if it starts with the string /vnc0:
- #
- RewriteRule ^/vnc0.* /VNCFAIL [F,L]
- #
- # Next, map the prefix to /vnc0:host:protocol:port
- #
- RewriteRule ^/vnc/([^/]+)/(.*) /vnc0/$1:http:58${vnchosts:$1|NOTFOUND}/$2
-[NE]
- RewriteRule ^/vncs/([^/]+)/(.*) /vnc0/$1:https:59${vnchosts:$1|NOTFOUND}/$2
-[NE]
- #
- # Drop any not found:
- #
- RewriteRule ^/vnc0.*NOTFOUND.* /VNCFAIL [F,L]
-
- # Construct the proxy URL and retrieve it:
- #
- RewriteRule ^/vnc0/([^/]+):([^/]+):([^/]+)/(.*) $2://$1:$3/$4 [P,NE,L]
-
- This is all in the "<VirtualHost _default_:443>" section of ssl.conf.
-
- The user could then point the Web Browser to:
- https://www.gateway.east/vnc/host2
-
- or
- https://www.gateway.east/vnc/proxy/host2
-
- for the "double proxy" case. (Important: do not put a trailing "/" on
- the URL, since that will defeat the RewriteRules.)
-
- As with the httpd.conf case, the external file
- (/dist/apache/conf/vnc.hosts in the above example) contains the
- hostnames of the allowed VNC servers.
-
- Note that inside the firewall the Java applet download traffic is not
- encrypted (only over the Internet is SSL used) for these cases:
- https://www.gateway.east/vnc/host2
- https://www.gateway.east/vnc/proxy/host2
-
- However for the special "vncs" rules above:
- https://www.gateway.east/vncs/host2
-
- the Java applet download is encrypted via SSL for both legs. Note that
- the two legs are two separate SSL sessions. So the data is decrypted
- inside an apache process and reencrypted by the apache process for the
- 2nd SSL session inside the same apache process (a very small gap one
- might overlook).
-
- The "vncs/trust" ones are like the "trust" ones described earlier
- https://www.gateway.east/vncs/trust/mach2
-
- and similarly for the httpsPort ones. See Tricks for Better Response.
-
- In all of the above cases the VNC traffic from Viewer to x11vnc is
- encrypted end-to-end in a single SSL session, even for the "double
- proxy" case because the CONNECT method is used (there are actually two
- CONNECT's for the "double proxy" case). This part (the VNC traffic) is
- the most important part to have encrypted.
-
- Note that the Certificate dialogs the user has in his web browser will
- be for the Apache Certificate, while for the Java applet it will be
- the x11vnc certificate.
-
- Note also that you can have Apache serve up the Jar file VncViewer.jar
- and/or index.vnc/proxy.vnc instead of each x11vnc if you want to.
-
- The rules in ssl.conf are similar to the ones in httpd.conf and so are
- not discussed in detail. The only really new thing is the /vncs
- handling to download the applet jar via HTTPS on port 5915.
-
- The special entries "/vnc443" are only used for the special helper
- program (connect_switch) for the https port 443 only mode discussed
- here.
-
- _________________________________________________________________
-
- INETD automation:
-
- The "single-port" (i.e. 5915) HTTPS applet download and VNC connection
- aspect shown here is convenient and also enables having x11vnc run out
- of inetd. That way x11vnc is run on demand instead of being run all
- the time (the user does not have to remember to start it). The first
- connections to inetd download index.vnc and the Jar file (via https)
- and the the last connection to inetd establishes the SSL VNC
- connection. Since x11vnc is restarted for each connection, this will
- be a bit slower than the normal process.
-
- For example, the /etc/inetd.conf line could be:
- 5915 stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/x11vnc_ssl.sh
-
- where the script x11vnc_ssl.sh looks something like this:
-#!/bin/sh
-
-/usr/local/bin/x11vnc -inetd -oa /var/log/x11vnc-15.log \
- -ssl SAVE -http -unixpw -localhost \
- -display :0 -auth /home/THE_USER/.Xauthority
-
- where, as usual, the inetd launching needs to know which user is
- typically using the display on that machine. One could imagine giving
- different users different ports, 5915, 5916, etc. to distinguish (then
- the script would need to be passed the username). mod_rewrite could be
- used to automatically map username in the URL to his port number.
-
- A better way is to use the "-display WAIT:cmd=FINDDISPLAY" feature to
- autodetect the user and Xauthority data:
-#!/bin/sh
-
-/usr/local/bin/x11vnc -inetd -oa /var/log/x11vnc-15.log \
- -ssl SAVE -http -unixpw -localhost -users unixpw= \
- -find
-
- (we have used the alias -find for "-display WAIT:cmd=FINDDISPLAY".)
- This way the user must supply his Unix username and password and then
- his display and Xauthority data on that machine will be located and
- returned to x11vnc to allow it to attach. If he doesn't have a display
- running on that machine or he fails to log in correctly, the
- connection will be dropped.
-
- The variant "-display WAIT:cmd=FINDCREATEDISPLAY" (aliased by
- "-create") will actually create a (virtual or real) X server session
- for the user if one doesn't already exist. See here for details.
-
- To enable inetd operation for the non-HTTPS Java viewer download (port
- 5815 in the above httpd.conf example) you will need to run x11vnc in
- HTTPONCE mode on port 5815: For example, the /etc/inetd.conf line
- could be:
- 5815 stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/x11vnc \
- -inetd -prog /usr/local/bin/x11vnc -oa /var/log/x11vnc-15.log \
- -http_ssl -display WAIT:cmd=HTTPONCE
-
- where the long inetd.conf line has been split. Note how the -http_ssl
- tries to automatically find the .../classes/ssl subdirectory. This
- requires the -prog option available in x11vnc 0.8.4 (a shell script
- wrapper, e.g. /usr/local/bin/x11vnc_http.sh can be used to work around
- this).
-
- Also note the use of "-ssl SAVE" above. This way a saved server.pem is
- used for each inetd invocation (rather generating a new one each time
- as happens for "-ssl TMP"). Note that it cannot have a protecting
- passphrase because inetd will not be able to supply it.
-
- Another option is:
- 5815 stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/x11vnc \
- -inetd -httpdir /usr/local/share/x11vnc/classes/ssl \
- -oa /var/log/x11vnc-15.log -display WAIT:cmd=HTTPONCE
-
- (this also requires a feature found in x11vnc 0.8.4).
- _________________________________________________________________
-
- Other Ideas:
-
- - The above schemes work, but they are a bit complicated with all of
- the rigging. There should be more elegant ways to configure Apache to
- do these, but we have not found them (please let us know if you
- discover something nice). However, once this scheme has been set up
- and is working it is easy to maintain and add/delete workstations,
- etc.
-
- - In general Apache is not required, but it makes things convenient.
- The firewall itself could do the port redirection via its firewall
- rules. Evidently different Internet-facing ports would be required for
- each workstation. This could be set up using iptables rules for
- example. If there were just one or two machines this would be the
- easiest method. For example:
- iptables -t nat -A PREROUTING -p tcp -d 24.35.46.57 --dport 5901 -j DNAT --to
--destination 192.168.1.2:5915
- iptables -t nat -A PREROUTING -p tcp -d 24.35.46.57 --dport 5902 -j DNAT --to
--destination 192.168.1.3:5915
-
- Where 24.35.46.57 is the internet IP address of the gateway. In this
- example 24.35.46.57:5901 is redirected to the internal machine
- 192.168.1.2:5915 and 24.35.46.57:5902 is redirected to another
- internal machine 192.168.1.3:5915, both running x11vnc -ssl ... in SSL
- mode. For this example, the user would point the web browser to, e.g.:
- https://24.35.46.57:5901/?PORT=5901
-
- or using the stunnel wrapper script:
- ss_vncviewer 24.35.46.57:1
-
- One can achieve similar things with dedicated firewall/routers (e.g.
- Linksys) using the device's web or other interface to configure the
- firewall.
-
- If the user may be coming out of a firewall using a proxy it may be
- better to redirect ports 443 and 563 (instead of 5901 and 5902) to the
- internal machines so that the user's proxy will allow CONNECTing to
- them.
-
- - The redirection could also be done at the application level using a
- TCP redirect program (e.g. ip_relay or fancier ones). Evidently more
- careful internal hostname checking, etc., could be performed by the
- special purpose application to add security. See connect_switch which
- is somewhat related.
-
- - One might imagine the ProxyPass could be done for the VNC traffic as
- well (for the ssl.conf case) to avoid the CONNECT proxying completely
- (which would be nice to avoid). Unfortunately we were not able to get
- this to work. Since HTTP is a request-response protocol (as opposed to
- a full bidirectional link required by VNC that CONNECT provides) this
- makes it difficult to do. It may be possible, but we haven't found out
- how yet.
-
- All of the x11vnc Java Viewer applet parameters are described in the
- file classes/ssl/README
-
- _________________________________________________________________
-
- Tricks for Better Response and reliability:
-
- The "original scheme" using httpd.conf and ssl.conf rewrites without
- urlPrefix and trustAllVncCerts above should work OK, but may lead to
- slow and/or unreliable loading of the applet and final connection to
- x11vnc. The following are what I do now to get better response and
- reliability. YMMV.
-
- The problem with the "original scheme" is that there is a point where
- the VNC Viewer applet can try up to 3 times to retrieve the x11vnc
- certificate, since it needs to get it to show it to you and ask you if
- you accept it. This can add about 45 seconds to the whole process
- (which takes 1 to 1.5 minutes with all the dialogs) since a couple of
- those connections must time out. The "trust" items in the config add a
- parameter trustAllVncCerts=yes similar to the forceProxy=yes
- parameter. This can cut the total time to the VNC password prompt down
- to 15 seconds which is pretty good. (Note by ignoring the certificate
- this does not protect against man-in-the-middle attacks which are
- rare, but maybe the won't be so rare in the future... see
- dsniff/webmitm and cain)
-
- First make sure the x11vnc SSL certificate+key is the same as
- Apache's. (otherwise you may get one extra dialog and/or one extra
- connection that has to time out).
-
- The following RewriteRule's are the same now advocated in the
- instructions above.
-
- The httpsPort and urlPrefix= parameters give hints to the applet to
- improve connecting: This is what goes in httpd.conf:
- RewriteEngine On
- RewriteRule /vnc/([^/]+)$ /vnc/$1/index.vnc?CONNECT=$1+5915&PO
-RT=563&urlPrefix=_2F_vnc_2F_$1 [R,NE]
- RewriteRule /vnc/trust/([^/]+)$ /vnc/$1/index.vnc?CONNECT=$1+5915&PO
-RT=563&urlPrefix=_2F_vnc_2F_$1&trustAllVncCerts=yes [R,NE]
- RewriteRule /vnc/proxy/([^/]+)$ /vnc/$1/proxy.vnc?CONNECT=$1+5915&PO
-RT=563&urlPrefix=_2F_vnc_2F_$1&forceProxy=yes [R,NE]
- RewriteRule /vnc/trust/proxy/([^/]+)$ /vnc/$1/proxy.vnc?CONNECT=$1+5915&PO
-RT=563&urlPrefix=_2F_vnc_2F_$1&forceProxy=yes&trustAllVncCerts=yes [R,NE]
-
- The httpsPort and urlPrefix provide useful hints to the VNC Viewer
- applet when it connects to x11vnc to glean information about Proxies,
- certificates, etc.
-
- This is what goes into ssl.conf:
- RewriteEngine On
- RewriteRule /vnc/([^/]+)$ /vnc/$1/index.vnc?CONNECT=$1+5915&P
-ORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vnc_2F_$1 [R,NE]
- RewriteRule /vnc/proxy/([^/]+)$ /vnc/$1/proxy.vnc?CONNECT=$1+5915&P
-ORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vnc_2F_$1&forceProxy=yes [R,NE]
- RewriteRule /vncs/([^/]+)$ /vncs/$1/index.vnc?CONNECT=$1+5915&P
-ORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1 [R,NE]
- RewriteRule /vncs/proxy/([^/]+)$ /vncs/$1/proxy.vnc?CONNECT=$1+5915&P
-ORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1&forceProxy=yes [R,NE]
- RewriteRule /vncs/trust/([^/]+)$ /vncs/$1/index.vnc?CONNECT=$1+5915&P
-ORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1&trustAllVncCerts=yes [R,NE
-]
- RewriteRule /vncs/trust/proxy/([^/]+)$ /vncs/$1/proxy.vnc?CONNECT=$1+5915&P
-ORT=563&httpsPort=443&GET=1&urlPrefix=_2F_vncs_2F_$1&forceProxy=yes&trustAllVnc
-Certs=yes [R,NE]
-
- The rest is the same.
-
- The httpsPort and urlPrefix and GET provide useful hints to the VNC
- Viewer applet when it connects to x11vnc to glean information about
- Proxies, certificates, etc, and also for the ultimate VNC connection
- (GET speeds this up by sending a special HTTP GET to cause x11vnc to
- immediately switch to the VNC protocol).
-
- To turn these into URLs, as was done above, take the string in the
- RewriteRule, e.g. /vncs and turn it into
- https://gateway/vncs/machinename Similarly for non-https:
- http://gateway:563/vnc/machinename
-
- If you use the 'trust' ones, you are performing NO checks, visual or
- otherwise, on the VNC SSL certificate. It is trusted without question.
- This speeds things up because it avoids a dialog about certificates,
- but of course has some risk WRT Man in the Middle attacks. I don't
- recommend them. It is better to use /vnc or /vncs and the first time
- you connect carefully check the Certificate and then tell your Browser
- and Java Virtual Machine to trust the certificate 'Always'. Then if
- you later get an unexpected dialog, you know something is wrong.
- Nearly always it is just a changed or expired certificate, but better
- safe than sorry...
-
-=======================================================================
-http://www.karlrunge.com/x11vnc/enhanced_tightvnc_viewer.html:
-
-
- _________________________________________________________________
-
-Enhanced TightVNC Viewer (SSVNC: SSL/SSH VNC viewer)
-
- (To Downloads) (To Quick Start)
-
- [ssvnc.gif] [ssvnc_windows.gif] [ssvnc_macosx.gif] . .
-
-
- The Enhanced TightVNC Viewer, SSVNC, adds encryption security to VNC
- connections.
-
- The package provides a GUI for Windows, Mac OS X, and Unix that
- automatically starts up an STUNNEL SSL tunnel for SSL or ssh/plink for
- SSH connections to any VNC server, such as x11vnc, and then launches
- the VNC Viewer to use the encrypted tunnel.
-
- The x11vnc server has built-in SSL support, however SSVNC can make SSL
- encrypted VNC connections to any VNC Server if they are running an SSL
- tunnel, such as STUNNEL or socat, at their end. SSVNC's SSH tunnel
- will work to any VNC Server host running sshd that you can log into.
-
- The Enhanced TightVNC Viewer package started as a project to add some
- patches to the long neglected Unix TightVNC Viewer. However, now the
- front-end GUI, encryption, and wrapper scripts features possibly
- outweigh the Unix TightVNC Viewer improvements (see the lists below to
- compare).
-
- The SSVNC Unix vncviewer can also be run without the SSVNC encryption
- GUI as an enhanced replacement for the xvncviewer, xtightvncviewer,
- etc., viewers.
-
- In addition to normal SSL, SSVNC also supports the VeNCrypt SSL/TLS
- and Vino/ANONTLS encryption extensions to VNC on Unix, Mac OS X, and
- Windows. Via the provided SSVNC VeNCrypt bridge, VeNCrypt and ANONTLS
- encryption also works with any third party VNC Viewer (e.g. RealVNC,
- TightVNC, UltraVNC, etc...) you select via 'Change VNC Viewer'.
-
- The short name for this project is "ssvnc" for SSL/SSH VNC Viewer.
- This is the name of the command to start it.
-
- There is a simplified SSH-Only mode (sshvnc). And an even more
- simplified Terminal-Services mode (tsvnc) for use with x11vnc on the
- remote side.
-
- The tool has many additional features; see the descriptions below.
-
- It is a self-contained bundle, you could carry it around on, say, a
- USB memory stick / flash drive for secure VNC viewing from almost any
- machine, Unix, Mac OS X, and Windows (and if you create a directory
- named "Home" in the toplevel ssvnc directory on the drive your VNC
- profiles and certs will be kept there as well). For Unix, there is
- also a conventional source tarball to build and install in the normal
- way and not use a pre-built bundle.
-
- _________________________________________________________________
-
- Announcements:
-
- Important: If you created any SSL certificates with SSVNC (or anything
- else) on a Debian or Ubuntu system from Sept. 2006 through May 2008,
- then those keys are likely extremely weak and can be easily cracked.
- The certificate files should be deleted and recreated on a non-Debian
- system or an updated one. See
- http://www.debian.org/security/2008/dsa-1571 for details. The same
- applies to SSH keys.
-
- Please read this information on using SSVNC on workstations with
- Untrusted Local Users.
-
- _________________________________________________________________
-
- Feature List:
-
- Wrapper scripts and a tcl/tk GUI were written to create these features
- for Unix, Mac OS X, and Windows:
- * SSL support for connections using the bundled stunnel program.
- * Automatic SSH connections from the GUI (system ssh is used on Unix
- and MacOS X; bundled plink is used on Windows)
- * Ability to Save and Load VNC profiles for different hosts.
- * You can also use your own VNC Viewer, e.g. UltraVNC or RealVNC,
- with the SSVNC encryption GUI front-end if you prefer.
- * Create or Import SSL Certificates and Private Keys.
- * Reverse (viewer listening) VNC connections via SSL and SSH.
- * VeNCrypt SSL/TLS VNC encryption support (used by VeNCrypt, QEMU,
- ggi, libvirt/virt-manager/xen, vinagre/gvncviewer/gtk-vnc)
- * ANONTLS SSL/TLS VNC encryption support (used by Vino)
- * VeNCrypt and ANONTLS are also enabled for any 3rd party VNC Viewer
- (e.g. RealVNC, TightVNC, UltraVNC ...) on Unix, MacOSX, and
- Windows via the provided SSVNC VeNCrypt Viewer Bridge tool (use
- 'Change VNC Viewer' to select the one you want.)
- * Support for Web Proxies, SOCKS Proxies, and the UltraVNC repeater
- proxy (e.g. repeater://host:port+ID:1234). Multiple proxies may be
- chained together (3 max).
- * Support for SSH Gateway connections and non-standard SSH ports.
- * Automatic Service tunnelling via SSH for CUPS and SMB Printing,
- ESD/ARTSD Audio, and SMB (Windows/Samba) filesystem mounting.
- * Sets up any additional SSH port redirections that you want.
- * Zeroconf (aka Bonjour) is used on Unix and Mac OS X to find VNC
- servers on your local network if the avahi-browse or dns-sd
- program is available and in your PATH.
- * Port Knocking for "closed port" SSH/SSL connections. In addition
- to a simple fixed port sequence and one-time-pad implementation, a
- hook is also provided to run any port knocking client before
- 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. It is now the default on MacOS X.)
- * 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.
- * Unix Username and Password entry for use with "x11vnc -unixpw"
- type login dialogs.
- * Simplified mode launched by command "sshvnc" that is SSH Only.
- * Simplified mode launched by command "tsvnc" that provides a VNC
- "Terminal Services" mode (uses x11vnc on the remote side).
- * IPv6 support for all connection modes on Unix, MacOSX, and
- Windows.
-
- Patches to TightVNC 1.3.9 vnc_unixsrc tree were created for Unix
- TightVNC Viewer improvements (these only apply to the Unix VNC viewer,
- including MacOSX XQuartz):
- * rfbNewFBSize VNC support (dynamic screen resizing)
- * Client-side Scaling of the Desktop in the viewer.
- * ZRLE VNC encoding support (RealVNC's encoding)
- * Support for the ZYWRLE encoding, a wavelet based extension to ZRLE
- to improve compression of motion video and photo regions.
- * TurboVNC support (VirtualGL's modified TightVNC encoding; requires
- TurboJPEG library)
- * Pipelined Updates of the framebuffer as in TurboVNC (asks for the
- next update before the current one has finished downloading; this
- gives some speedup on high latency connections.)
- * Cursor alphablending with x11vnc at 32bpp (-alpha option)
- * Option "-unixpw ..." for use with "x11vnc -unixpw" type login
- dialogs.
- * Support for UltraVNC extensions: 1/n Server side scaling, Text
- Chat, Single Window, Disable Server-side Input. Both UltraVNC and
- x11vnc servers support these extensions.
- * UltraVNC File Transfer via an auxiliary Java helper program (java
- must be in $PATH). Note that the x11vnc server also supports
- UltraVNC file transfer.
- * Connection support for the UltraVNC repeater proxy (-repeater
- option).
- * Support for UltraVNC Single Click operation. (both unencrypted: SC
- I, and SSL encrypted: SC III)
- * Support for UltraVNC DSM Encryption Plugin symmetric encryption
- mode. (ARC4, AESV2, MSRC4, and SecureVNC)
- * Support for UltraVNC MS-Logon authentication (NOTE: the UltraVNC
- MS-Logon key exchange implementation is very weak; an eavesdropper
- on the network can recover your Windows password easily in a few
- seconds; you need to use an additional encrypted tunnel with
- MS-Logon.)
- * Support for symmetric encryption (including blowfish and 3des
- ciphers) to Non-UltraVNC Servers. Any server using the same
- encryption method will work, e.g.: x11vnc -enc blowfish:./my.key
- * Instead of hostname:display one can also supply "exec=command
- args..." to connect the viewer to the stdio of an external command
- (e.g. stunnel or socat) rather than using a TCP/IP socket. Unix
- domain sockets, e.g. /path/to/unix/socket, and a previously opened
- file descriptor fd=0, work too.
- * Local Port Protections for STUNNEL and SSH: avoid having for long
- periods of time a listening port on the the local (VNC viewer)
- side that redirects to the remote side.
- * Reverse (viewer listening) VNC connections can show a Popup dialog
- asking whether to accept the connection or not (-acceptpopup.) The
- extra info provided by UltraVNC Single Click reverse connections
- is also supported (-acceptpopupsc)
- * Extremely low color modes: 64 and 8 colors in 8bpp
- (-use64/-bgr222, -use8/-bgr111)
- * Medium color mode: 16bpp mode on a 32bpp Viewer display
- (-16bpp/-bgr565)
- * For use with x11vnc's client-side caching -ncache method use the
- cropping option -ycrop n. This will "hide" the large pixel buffer
- cache below the actual display. Set to the actual height or use -1
- for autodetection (also, tall screens, H > 2*W, are autodetected
- by default).
- * Escape Keys: specify a set of modifier keys so that when they are
- all pressed down you can invoke Popup menu actions via keystrokes.
- I.e., a set of 'Hot Keys'. One can also pan (move) the desktop
- inside the viewport via Arrow keys or a mouse drag.
- * Scrollbar width setting: -sbwidth n, the default is very thin, 2
- pixels, for less distracting -ycrop usage.
- * Selection text sending and receiving can be fine-tuned with the
- -sendclipboard, -sendalways, and -recvtext options.
- * TightVNC compression and quality levels are automatically set
- based on observed network latency (n.b. not bandwidth.)
- * Improvements to the Popup menu, all of these can now be changed
- dynamically via the menu: ViewOnly, Toggle Bell, CursorShape
- updates, X11 Cursor, Cursor Alphablending, Toggle Tight/ZRLE,
- Toggle JPEG, FullColor/16bpp/8bpp (256/64/8 colors), Greyscale for
- low color modes, Scaling the Viewer resolution, Escape Keys,
- Pipeline Updates, and others, including UltraVNC extensions.
- * Maintains its own BackingStore if the X server does not.
- * The default for localhost:0 connections is not raw encoding since
- same-machine connections are pretty rare. Default assumes you are
- using a SSL or SSH tunnel. Use -rawlocal to revert.
- * XGrabServer support for fullscreen mode, for old window managers
- (-grab/-graball option).
- * Fix for Popup menu positioning for old window managers (-popupfix
- option).
- * The VNC Viewer ssvncviewer supports IPv6 natively (no helpers
- needed.)
-
- The list of 3rd party software bundled in the archive files:
- * TightVNC Viewer (windows, unix, macosx)
- * Chicken of the VNC Viewer (macosx)
- * Stunnel (windows, unix, macosx)
- * Putty/Plink/Pageant (windows)
- * OpenSSL (windows)
- * esound (windows)
-
- These are all self-contained in the bundle directory: they will not be
- installed on your system. Just un-zip or un-tar the file you
- downloaded and run the frontend ssvnc straight from its directory.
- Alternatively, on Unix you can use the conventional source tarball.
-
- _________________________________________________________________
-
- Here is the Quick Start info from the README for how to setup and use
- SSVNC:
-Quick Start:
------------
-
-Unix and Mac OS X:
-
- Inside a Terminal do something like the following.
-
- Unpack the archive:
-
- % gzip -dc ssvnc-1.0.29.tar.gz | tar xvf -
-
- Run the GUI:
-
- % ./ssvnc/Unix/ssvnc (for Unix)
-
- % ./ssvnc/MacOSX/ssvnc (for Mac OS X)
-
- The smaller file "ssvnc_no_windows-1.0.29.tar.gz"
- could have been used as well.
-
- On MacOSX you could also click on the SSVNC app icon in the Finder.
-
- On MacOSX if you don't like the Chicken of the VNC (e.g. no local
- cursors, no screen size rescaling, and no password prompting), and you
- have the XDarwin X server installed, you can set DISPLAY before starting
- ssvnc (or type DISPLAY=... in Host:Disp and hit Return). Then our
- enhanced TightVNC viewer will be used instead of COTVNC.
- Update: there is now a 'Use X11 vncviewer on MacOSX' under Options ...
-
-
- If you want a SSH-only tool (without the distractions of SSL) run
- the command:
-
- sshvnc
-
- instead of "ssvnc". Or click "SSH-Only Mode" under Options.
- Control-h will toggle between the two modes.
-
-
- If you want a simple VNC Terminal Services only mode (requires x11vnc
- on the remote server) run the command:
-
- tsvnc
-
- instead of "ssvnc". Or click "Terminal Services" under Options.
- Control-t will toggle between the two modes.
-
- "tsvnc profile-name" and "tsvnc user@hostname" work too.
-
-
-Unix/MacOSX Install:
-
- There is no standard install for the bundles, but you can make
- symlinks like so:
-
- cd /a/directory/in/PATH
- ln -s /path/to/ssvnc/bin/{s,t}* .
-
- Or put /path/to/ssvnc/bin, /path/to/ssvnc/Unix, or /path/to/ssvnc/MacOSX
- in your PATH.
-
- For the conventional source tarball it will compile and install, e.g.:
-
- gzip -dc ssvnc-1.0.29.src.tar.gz | tar xvf -
- cd ssvnc-1.0.29
- make config
- make all
- make PREFIX=/my/install/dir install
-
- then have /my/install/dir/bin in your PATH.
-
-
-
-Windows:
-
- Unzip, using WinZip or a similar utility, the zip file:
-
- ssvnc-1.0.29.zip
-
- Run the GUI, e.g.:
-
- Start -> Run -> Browse
-
- and then navigate to
-
- .../ssvnc/Windows/ssvnc.exe
-
- select Open, and then OK to launch it.
-
- The smaller file "ssvnc_windows_only-1.0.29.zip"
- could have been used as well.
-
- You can make a Windows shortcut to this program if you want to.
-
- See the Windows/README.txt for more info.
-
-
- If you want a SSH-only tool (without the distractions of SSL) run
- the command:
-
- sshvnc.bat
-
- Or click "SSH-Only Mode" under Options.
-
-
- If you want a simple VNC Terminal Services only mode (requires x11vnc
- on the remote server) run the command:
-
- tsvnc.bat
-
- Or click "Terminal Services" under Options. Control-t will toggle
- between the two modes. "tsvnc profile-name" and "tsvnc user@hostname"
- work too.
-
- _________________________________________________________________
-
- You can read all of the SSVNC GUI's Online Help Text here.
- _________________________________________________________________
-
- The bundle unpacks a directory/folder named: ssvnc. It contains these
- programs to launch the GUI:
- Windows/ssvnc.exe for Windows
- MacOSX/ssvnc for Mac OS X
- Unix/ssvnc for Unix
-
- (the Mac OS X and Unix launchers are simply links to the bin
- directory). See the README for more information.
-
- The SSH-Only mode launcher program has name sshvnc. The Terminal
- Services mode launcher program (assumes x11vnc 0.8.4 or later and Xvfb
- installed on the server machine) has name tsvnc.
-
- The Viewer SSL support is done via a wrapper script (bin/ssvnc_cmd
- that calls bin/util/ss_vncviewer) that starts up the STUNNEL tunnel
- first and then starts the TightVNC viewer pointed at that tunnel. The
- bin/ssvnc program is a GUI front-end to that script. See this FAQ for
- more details on SSL tunnelling. In SSH connection mode, the wrappers
- start up SSH appropriately.
-
-
- Memory Stick Usage: If you create a directory named "Home" in that
- toplevel ssvnc directory then that will be used as the base for
- storing VNC profiles and certificates. Also, for convenience, if you
- first run the command with "." as an argument (e.g. "ssvnc .") it will
- automatically create the "Home" directory for you. This is handy if
- you want to place SSVNC on a USB flash drive that you carry around for
- mobile use and you want the profiles you create to stay with the drive
- (otherwise you'd have to browse to the drive directory each time you
- load or save).
-
- One user on Windows created a BAT file to launch SSVNC and needed to
- do this to get the Home directory correct:
-cd \ssvnc\Windows
-start \ssvnc\Windows\ssvnc.exe
-
- (an optional profile name can be supplied to the ssvnc.exe line)
-
- WARNING: if you use ssvnc from an "Internet Cafe", i.e. some untrusted
- computer, please be aware that someone may have set up that machine to
- be capturing your keystrokes, etc.
-
-
- SSH-Only version: The command "sshvnc" can be run instead of "ssvnc"
- to get an SSH-only version of the tool:
-
- [sshvnc.gif]
-
- These also work: "sshvnc myprofile" and "sshvnc user@hostname". To
- switch from the regular SSVNC mode, click "SSH-Only Mode" under
- Options. This mode is less distracting if you never plan to use SSL,
- manage certificates, etc.
-
-
- Terminal Services Only: The command "tsvnc" can be run instead of
- "ssvnc" to get a "Terminal Services" only version of the tool:
-
- [tsvnc.gif]
-
- These also work: "tsvnc myprofile" and "tsvnc user@hostname". To
- switch from the regular SSVNC mode, click "Terminal Services" under
- Options.
-
- This mode requires x11vnc (0.9.3 or later) installed on the remote
- machine to find, create, and manage the user sessions. SSH is used to
- create the encrypted and authenticated tunnel. The Xvfb (virtual
- framebuffer X server) program must also be installed on the remote
- system. However tsvnc will also connect to a real X session (i.e. on
- the physical hardware) if you are already logged into the X session;
- this is a useful access mode and does not require Xvfb on the remote
- system.
-
- This mode should be very easy for beginner users to understand and
- use. On the remote end you only need to have x11vnc and Xvfb available
- in $PATH, and on the local end you just run something like:
- tsvnc myname@myhost.com
-
- (or start up the tsvnc GUI first and then enter myname@myhost.com and
- press "Connect").
-
- Normally the Terminal Services sessions created are virtual (RAM-only)
- ones (e.g. Xvfb, Xdummy, or Xvnc), however a nice feature is if you
- have a regular X session (i.e displaying on the physical hardware) on
- the remote machine that you are ALREADY logged into, then the x11vnc
- run from tsvnc will find it for you as well.
-
- Also, there is setting "X Login" under Advanced Options that allows
- you to attach to a real X server with no one logged in yet (i.e.
- XDM/GDM/KDM Login Greeter screen) as long as you have sudo(1)
- permission on the remote machine.
-
- Nice features to soon to be added to the tsvnc mode are easy CUPS
- printing (working fairly well) and Sound redirection (needs much work)
- of the Terminal Services Desktop session. It is easier in tsvnc mode
- because the entire desktop session can be started with the correct
- environment. ssvnc tries to handle the general case of an already
- started desktop and that is more difficult.
-
-
- Proxies: Web proxies, SOCKS proxies, and the UltraVNC repeater proxy
- are supported to allow the SSVNC connection to go through the proxy to
- the otherwise unreachable VNC Server. SSH gateway machines can be used
- in the same way. Read more about SSVNC proxy support here.
-
-
- Dynamic VNC Server Port determination: If you are running SSVNC on
- Unix and are using SSH to start the remote VNC server and the VNC
- server prints out the line "PORT=NNNN" to indicate which dynamic port
- it is using (x11vnc does this), then if you prefix the SSH command
- with "PORT=" SSVNC will watch for the PORT=NNNN line and uses ssh's
- built in SOCKS proxy (ssh -D ...) to connect to the dynamic VNC server
- port through the SSH tunnel. For example:
- VNC Host:Display user@somehost.com
- Remote SSH Command: PORT= x11vnc -find
-
- or "PORT= x11vnc -display :0 -localhost", etc. Or use "P= x11vnc ..."
-
- There is also code to detect the display of the regular Unix
- vncserver(1). It extracts the display (and hence port) from the lines
- "New 'X' desktop is hostname:4" and also "VNC server is already
- running as :4". So you can use something like:
- PORT= vncserver; sleep 15
-or: PORT= vncserver :4; sleep 15
-
- the latter is preferred because when you reconnect with it will find
- the already running one. The former one will keep creating new X
- sessions if called repeatedly.
-
- If you use PORT= on Windows, a large random port is selected instead
- and the -rfbport option is passed to x11vnc (it does not work with
- vncserver).
-
-
-
- Patches for Unix Tightvnc viewer:
-
- The rfbNewFBSize support allows the enhanced TightVNC Unix viewer to
- resize when the server does (e.g. "x11vnc -R scale=3/4" remote control
- command).
-
- The cursor alphablending is described here.
-
- The RealVNC ZRLE encoding is supported, in addition to some low colors
- modes (16bpp and 8bpp at 256, 64, and even 8 colors, for use on very
- slow connections). Greyscales are also enabled for the low color
- modes.
-
- The Popup menu (F8) is enhanced with the ability to change many things
- on the fly. F9 is added as a shortcut to toggle FullScreen mode.
-
- Client Side Caching: The x11vnc client-side caching is handled nicely
- by this viewer. The very large pixel cache below the actual display in
- this caching method is distracting. Our Unix VNC viewer will
- automatically try to autodetect the actual display height if the
- framebuffer is very tall (more than twice as high as it is wide). One
- can also set the height to the known value via -ycrop n, or use -ycrop
- -1 to force autodection. In fullscreen mode one is not possible to
- scroll down to the pixel cache region. In non-fullscreen mode the
- window manager frame is "shrink-wrapped" around the actual screen
- display. You can still scroll down to the pixel cache region. The
- scrollbars are set to be very thin (2 pixels) to be less distracting.
- Use the -sbwidth n to make them wider.
-
- Probably nobody is interested in the grabserver patch for old window
- managers when the viewer is in fullscreen mode... This and some other
- unfixed bugs have been fixed in our patches (fullscreen toggle works
- with KDE, -x11cursor has been fixed, and the dot cursor has been made
- smaller).
-
- From the -help output:
-SSVNC Viewer (based on TightVNC viewer version 1.3.9)
-
-Usage: vncviewer [<OPTIONS>] [<HOST>][:<DISPLAY#>]
- vncviewer [<OPTIONS>] [<HOST>][::<PORT#>]
- vncviewer [<OPTIONS>] exec=[CMD ARGS...]
- vncviewer [<OPTIONS>] fd=n
- vncviewer [<OPTIONS>] /path/to/unix/socket
- vncviewer [<OPTIONS>] -listen [<DISPLAY#>]
- vncviewer -help
-
-<OPTIONS> are standard Xt options, or:
- -via <GATEWAY>
- -shared (set by default)
- -noshared
- -viewonly
- -fullscreen
- -noraiseonbeep
- -passwd <PASSWD-FILENAME> (standard VNC authentication)
- -user <USERNAME> (Unix login authentication)
- -encodings <ENCODING-LIST> (e.g. "tight,copyrect")
- -bgr233
- -owncmap
- -truecolour
- -depth <DEPTH>
- -compresslevel <COMPRESS-VALUE> (0..9: 0-fast, 9-best)
- -quality <JPEG-QUALITY-VALUE> (0..9: 0-low, 9-high)
- -nojpeg
- -nocursorshape
- -x11cursor
- -autopass
-
-Option names may be abbreviated, e.g. -bgr instead of -bgr233.
-See the manual page for more information.
-
-
-Enhanced TightVNC viewer (SSVNC) options:
-
- URL http://www.karlrunge.com/x11vnc/ssvnc.html
-
- Note: ZRLE and ZYWRLE encodings are now supported.
-
- Note: F9 is shortcut to Toggle FullScreen mode.
-
- Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1
- to allow more than one incoming VNC server at a time.
- This is the same as -multilisten described below. Set
- SSVNC_MULTIPLE_LISTEN=MAX:n to allow no more than "n"
- simultaneous reverse connections.
-
- Note: If the host:port is specified as "exec=command args..."
- then instead of making a TCP/IP socket connection to the
- remote VNC server, "command args..." is executed and the
- viewer is attached to its stdio. This enables tunnelling
- established via an external command, e.g. an stunnel(8)
- that does not involve a listening socket. This mode does
- not work for -listen reverse connections.
-
- If the host:port is specified as "fd=n" then it is assumed
- n is an already opened file descriptor to the socket. (i.e
- the parent did fork+exec)
-
- If the host:port contains a '/' it is interpreted as a
- unix-domain socket (AF_LOCAL insead of AF_INET)
-
- -multilisten As in -listen (reverse connection listening) except
- allow more than one incoming VNC server to be connected
- at a time. The default for -listen of only one at a
- time tries to play it safe by not allowing anyone on
- the network to put (many) desktops on your screen over
- a long window of time. Use -multilisten for no limit.
-
- -acceptpopup In -listen (reverse connection listening) mode when
- a reverse VNC connection comes in show a popup asking
- whether to Accept or Reject the connection. The IP
- address of the connecting host is shown. Same as
- setting the env. var. SSVNC_ACCEPT_POPUP=1.
-
- -acceptpopupsc As in -acceptpopup except assume UltraVNC Single
- Click (SC) server. Retrieve User and ComputerName
- info from UltraVNC Server and display in the Popup.
-
- -use64 In -bgr233 mode, use 64 colors instead of 256.
- -bgr222 Same as -use64.
-
- -use8 In -bgr233 mode, use 8 colors instead of 256.
- -bgr111 Same as -use8.
-
- -16bpp If the vnc viewer X display is depth 24 at 32bpp
- request a 16bpp format from the VNC server to cut
- network traffic by up to 2X, then tranlate the
- pixels to 32bpp locally.
- -bgr565 Same as -16bpp.
-
- -grey Use a grey scale for the 16- and 8-bpp modes.
-
- -alpha Use alphablending transparency for local cursors
- requires: x11vnc server, both client and server
- must be 32bpp and same endianness.
-
- -scale str Scale the desktop locally. The string "str" can
- 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. "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.
- Use a negative value (e.g. -1) for autodetection.
- Autodetection will always take place if the remote
- fb height is more than 2 times the width.
-
- -sbwidth n Scrollbar width for x11vnc -ncache mode (-ycrop),
- default is very narrow: 2 pixels, it is narrow to
- avoid distraction in -ycrop mode.
-
- -nobell Disable bell.
-
- -rawlocal Prefer raw encoding for localhost, default is
- no, i.e. assumes you have a SSH tunnel instead.
-
- -notty Try to avoid using the terminal for interactive
- responses: use windows for messages and prompting
- instead. Messages will also be printed to terminal.
-
- -sendclipboard Send the X CLIPBOARD selection (i.e. Ctrl+C,
- Ctrl+V) instead of the X PRIMARY selection (mouse
- select and middle button paste.)
-
- -sendalways Whenever the mouse enters the VNC viewer main
- window, send the selection to the VNC server even if
- it has not changed. This is like the Xt resource
- translation SelectionToVNC(always)
-
- -recvtext str When cut text is received from the VNC server,
- ssvncviewer will set both the X PRIMARY and the
- X CLIPBOARD local selections. To control which
- is set, specify 'str' as 'primary', 'clipboard',
- or 'both' (the default.)
-
- -graball Grab the entire X server when in fullscreen mode,
- needed by some old window managers like fvwm2.
-
- -popupfix Warp the popup back to the pointer position,
- needed by some old window managers like fvwm2.
- -sendclipboard Send the X CLIPBOARD selection (i.e. Ctrl+C,
- Ctrl+V) instead of the X PRIMARY selection (mouse
- select and middle button paste.)
-
- -sendalways Whenever the mouse enters the VNC viewer main
- window, send the selection to the VNC server even if
- it has not changed. This is like the Xt resource
- translation SelectionToVNC(always)
-
- -recvtext str When cut text is received from the VNC server,
- ssvncviewer will set both the X PRIMARY and the
- X CLIPBOARD local selections. To control which
- is set, specify 'str' as 'primary', 'clipboard',
- or 'both' (the default.)
-
- -graball Grab the entire X server when in fullscreen mode,
- needed by some old window managers like fvwm2.
-
- -popupfix Warp the popup back to the pointer position,
- needed by some old window managers like fvwm2.
-
- -grabkbd Grab the X keyboard when in fullscreen mode,
- needed by some window managers. Same as -grabkeyboard.
- -grabkbd is the default, use -nograbkbd to disable.
-
- -bs, -nobs Whether or not to use X server Backingstore for the
- main viewer window. The default is to not, mainly
- because most Linux, etc, systems X servers disable
- *all* Backingstore by default. To re-enable it put
-
- Option "Backingstore"
-
- in the Device section of /etc/X11/xorg.conf.
- In -bs mode with no X server backingstore, whenever an
- area of the screen is re-exposed it must go out to the
- VNC server to retrieve the pixels. This is too slow.
-
- In -nobs mode, memory is allocated by the viewer to
- provide its own backing of the main viewer window. This
- actually makes some activities faster (changes in large
- regions) but can appear to "flash" too much.
-
- -noshm Disable use of MIT shared memory extension (not recommended
-)
-
- -termchat Do the UltraVNC chat in the terminal vncviewer is in
- instead of in an independent window.
-
- -unixpw str Useful for logging into x11vnc in -unixpw mode. "str" is a
- string that allows many ways to enter the Unix Username
- and Unix Password. These characters: username, newline,
- password, newline are sent to the VNC server after any VNC
- authentication has taken place. Under x11vnc they are
- used for the -unixpw login. Other VNC servers could do
- something similar.
-
- You can also indicate "str" via the environment
- variable SSVNC_UNIXPW.
-
- Note that the Escape key is actually sent first to tell
- x11vnc to not echo the Unix Username back to the VNC
- viewer. Set SSVNC_UNIXPW_NOESC=1 to override this.
-
- If str is ".", then you are prompted at the command line
- for the username and password in the normal way. If str is
- "-" the stdin is read via getpass(3) for username@password.
- Otherwise if str is a file, it is opened and the first line
- read is taken as the Unix username and the 2nd as the
- password. If str prefixed by "rm:" the file is removed
- after reading. Otherwise, if str has a "@" character,
- it is taken as username@password. Otherwise, the program
- exits with an error. Got all that?
-
- -repeater str This is for use with UltraVNC repeater proxy described
- here: http://www.uvnc.com/addons/repeater.html. The "str"
- is the ID string to be sent to the repeater. E.g. ID:1234
- It can also be the hostname and port or display of the VNC
- server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when
- using -repeater, the host:dpy on the cmdline is the repeate
-r
- server, NOT the VNC server. The repeater will connect you.
-
- Example: vncviewer ... -repeater ID:3333 repeat.host:5900
- Example: vncviewer ... -repeater vhost:0 repeat.host:5900
-
- Use, e.g., '-repeater SCIII=ID:3210' if the repeater is a
- Single Click III (SSL) repeater (repeater_SSL.exe) and you
- are passing the SSL part of the connection through stunnel,
- socat, etc. This way the magic UltraVNC string 'testB'
- needed to work with the repeater is sent to it.
-
- -rfbversion str Set the advertised RFB version. E.g.: -rfbversion 3.6
- For some servers, e.g. UltraVNC this needs to be done.
-
- -ultradsm UltraVNC has symmetric private key encryption DSM plugins:
- http://www.uvnc.com/features/encryption.html. It is assumed
- you are using a unix program (e.g. our ultravnc_dsm_helper)
- to encrypt and decrypt the UltraVNC DSM stream. IN ADDITION
- TO THAT supply -ultradsm to tell THIS viewer to modify the
- RFB data sent so as to work with the UltraVNC Server. For
- some reason, each RFB msg type must be sent twice under DSM
-.
-
- -mslogon user Use Windows MS Logon to an UltraVNC server. Supply the
- username or "1" to be prompted. The default is to
- autodetect the UltraVNC MS Logon server and prompt for
- the username and password.
-
- IMPORTANT NOTE: The UltraVNC MS-Logon Diffie-Hellman
- exchange is very weak and can be brute forced to recover
- your username and password in a few seconds of CPU time.
- To be safe, be sure to use an additional encrypted tunnel
- (e.g. SSL or SSH) for the entire VNC session.
-
- -chatonly Try to be a client that only does UltraVNC text chat. This
- mode is used by x11vnc to present a chat window on the
- physical X11 console (i.e. chat with the person at the
- display).
-
- -env VAR=VALUE To save writing a shell script to set environment variables
-,
- specify as many as you need on the command line. For
- example, -env SSVNC_MULTIPLE_LISTEN=MAX:5 -env EDITOR=vi
-
- -noipv6 Disable all IPv6 sockets. Same as VNCVIEWER_NO_IPV6=1.
-
- -noipv4 Disable all IPv4 sockets. Same as VNCVIEWER_NO_IPV4=1.
-
- -printres Print out the Ssvnc X resources (appdefaults) and then exit
- You can save them to a file and customize them (e.g. the
- keybindings and Popup menu) Then point to the file via
- XENVIRONMENT or XAPPLRESDIR.
-
- -pipeline Like TurboVNC, request the next framebuffer update as soon
- as possible instead of waiting until the end of the current
- framebuffer update coming in. Helps 'pipeline' the updates
-.
- This is currently the default, use -nopipeline to disable.
-
- -appshare Enable features for use with x11vnc's -appshare mode where
- instead of sharing the full desktop only the application's
- windows are shared. Viewer multilisten mode is used to
- create the multiple windows: -multilisten is implied.
- See 'x11vnc -appshare -help' more information on the mode.
-
- Features enabled in the viewer under -appshare are:
- Minimum extra text in the title, auto -ycrop is disabled,
- x11vnc -remote_prefix X11VNC_APPSHARE_CMD: message channel,
- x11vnc initial window position hints. See also Escape Keys
- below for additional key and mouse bindings.
-
- -escape str This sets the 'Escape Keys' modifier sequence and enables
- escape keys mode. When the modifier keys escape sequence
- is held down, the next keystroke is interpreted locally
- to perform a special action instead of being sent to the
- remote VNC server.
-
- Use '-escape default' for the default modifier sequence.
- (Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L)
-
- Here are the 'Escape Keys: Help+Set' instructions from the Popup Menu:
-
- Escape Keys: Enter a comma separated list of modifier keys to be the
- 'escape sequence'. When these keys are held down, the next keystroke is
- interpreted locally to invoke a special action instead of being sent to
- the remote VNC server. In other words, a set of 'Hot Keys'.
-
- To enable or disable this, click on 'Escape Keys: Toggle' in the Popup.
-
- Here is the list of hot-key mappings to special actions:
-
- r: refresh desktop b: toggle bell c: toggle full-color
- f: file transfer x: x11cursor z: toggle Tight/ZRLE
- l: full screen g: graball e: escape keys dialog
- s: scale dialog +: scale up (=) -: scale down (_)
- t: text chat a: alphablend cursor
- V: toggle viewonly Q: quit viewer 1 2 3 4 5 6: UltraVNC scale 1/n
-
- Arrow keys: pan the viewport about 10% for each keypress.
- PageUp / PageDown: pan the viewport by a screenful vertically.
- Home / End: pan the viewport by a screenful horizontally.
- KeyPad Arrow keys: pan the viewport by 1 pixel for each keypress.
- Dragging the Mouse with Button1 pressed also pans the viewport.
- Clicking Mouse Button3 brings up the Popup Menu.
-
- The above mappings are *always* active in ViewOnly mode, unless you set the
- Escape Keys value to 'never'.
-
- If the Escape Keys value below is set to 'default' then a default list of
- of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it
- is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag
- on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side
- of the keyboard.
-
- On Unix the default is Alt and Windows keys on Left side of keyboard.
- On MacOSX the default is Control and Command keys on Left side of keyboard.
-
- Example: Press and hold the Alt and Windows keys on the LEFT side of the
- keyboard and then press 'c' to toggle the full-color state. Or press 't'
- to toggle the ultravnc Text Chat window, etc.
-
- To use something besides the default, supply a comma separated list (or a
- single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L
- Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.
-
-
- New Popup actions:
-
- ViewOnly: ~ -viewonly
- Disable Bell: ~ -nobell
- Cursor Shape: ~ -nocursorshape
- X11 Cursor: ~ -x11cursor
- Cursor Alphablend: ~ -alpha
- Toggle Tight/Hextile: ~ -encodings hextile...
- Toggle Tight/ZRLE: ~ -encodings zrle...
- Toggle ZRLE/ZYWRLE: ~ -encodings zywrle...
- Quality Level ~ -quality (both Tight and ZYWRLE)
- Compress Level ~ -compresslevel
- Disable JPEG: ~ -nojpeg (Tight)
- Pipeline Updates ~ -pipeline
-
- Full Color as many colors as local screen allows.
- Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.
- 16 bit color (BGR565) ~ -16bpp / -bgr565
- 8 bit color (BGR233) ~ -bgr233
- 256 colors ~ -bgr233 default # of colors.
- 64 colors ~ -bgr222 / -use64
- 8 colors ~ -bgr111 / -use8
- Scale Viewer ~ -scale
- Escape Keys: Toggle ~ -escape
- Escape Keys: Help+Set ~ -escape
- Set Y Crop (y-max) ~ -ycrop
- Set Scrollbar Width ~ -sbwidth
- XGrabServer ~ -graball
-
- UltraVNC Extensions:
-
- Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.
- Text Chat Ultravnc ext. Do Text Chat.
- File Transfer Ultravnc ext. File xfer via Java helper.
- Single Window Ultravnc ext. Grab and view a single window.
- (select then click on the window you want).
- Disable Remote Input Ultravnc ext. Try to prevent input and
- viewing of monitor at physical display.
-
- Note: the Ultravnc extensions only apply to servers that support
- them. x11vnc/libvncserver supports some of them.
-
- Send Clipboard not Primary ~ -sendclipboard
- Send Selection Every time ~ -sendalways
-
- Nearly all of these can be changed dynamically in the Popup menu
- (press F8 for it):
-
- [viewer_menu.gif] [unixviewer.jpg]
-
- _________________________________________________________________
-
- Windows:
-
- For Windows, SSL Viewer support is provided by a GUI Windows/ssvnc.exe
- that prompts for the VNC display and then starts up STUNNEL followed
- by the Stock TightVNC Windows Viewer. Both are bundled in the package
- for your convenience. The GUI has other useful features. When the
- connection is finished, you will be asked if you want to terminate the
- STUNNEL program. For SSH connections from Windows the GUI will use
- PLINK instead of STUNNEL.
-
- Unix and Mac OS X:
-
- Run the GUI (ssvnc, see above) and let me know how it goes.
- _________________________________________________________________
-
- Hopefully this tool will make it convenient for people to help test
- and use the built-in SSL support in x11vnc. Extra testing of this
- feature is much appreciated!! Thanks.
-
- Please Help Test the newly added features:
- * Automatic Service tunnelling via SSH for CUPS and SMB Printing
- * ESD/ARTSD Audio
- * SMB (Windows/Samba) filesystem mounting
-
- These allow you to print from the remote (VNC Server) machine to local
- printers, listen to sounds (with some limitations) from the remote VNC
- Server machine, and to mount your local Windows or Samba shares on the
- remote VNC Server machine. Basically these new features try to
- automate the tricks described here:
- http://www.karlrunge.com/x11vnc/faq.html#faq-smb-shares
- http://www.karlrunge.com/x11vnc/faq.html#faq-cups
- http://www.karlrunge.com/x11vnc/faq.html#faq-sound
- _________________________________________________________________
-
- Downloading: Downloads for this project are hosted at Sourceforge.net.
-
- Choose the archive file bundle that best suits you (e.g. no source
- code, windows only, unix only, zip, tar etc).
-
- A quick guide:
-
- On some flavor of Unix, e.g. Linux or Solaris? Use
- "ssvnc_unix_only" (or "ssvnc_no_windows" to recompile).
- On Mac OS X? Use "ssvnc_no_windows".
- On Windows? Use "ssvnc_windows_only".
- ssvnc_windows_only-1.0.28.zip Windows Binaries Only. No source included
- (6.2MB)
- ssvnc_no_windows-1.0.28.tar.gz Unix and Mac OS X Only. No Windows binarie
-s. Source included. (10.1MB)
- ssvnc_unix_only-1.0.28.tar.gz Unix Binaries Only. No source included
-. (7.2MB)
- ssvnc_unix_minimal-1.0.28.tar.gz Unix Minimal. You must supply your own vn
-cviewer and stunnel. (0.2MB)
-
- ssvnc-1.0.28.tar.gz All Unix, Mac OS X, and Windows binaries a
-nd source TGZ. (16.1MB)
- ssvnc-1.0.28.zip All Unix, Mac OS X, and Windows binaries a
-nd source ZIP. (16.4MB)
- ssvnc_all-1.0.28.zip All Unix, Mac OS X, and Windows binaries a
-nd source AND full archives in the zip dir. (19.2MB)
-
-
- Here is a conventional source tarball:
- ssvnc-1.0.28.src.tar.gz Conventional Source for SSVNC GUI and Unix
- VNCviewer (0.5MB)
-
- it will be of use to those who do not want the SSVNC
- "one-size-fits-all" bundles. For example, package/distro maintainers
- will find this more familiar and useful to them (i.e. they run: "make
- config; make all; make install"). Note that it does not include the
- stunnel source, and so has a dependency that the system stunnel is
- installed.
-
- Read the README.src file for more information on using the
- conventional source tarball.
-
-
- Note: even with the Unix bundles, e.g. "ssvnc_no_windows" or
- "ssvnc_all", you may need to run the "./build.unix" script in the top
- directory to recompile for your operating system.
-
- Here are the corresponding 1.0.29 development bundles (Please help
- test them):
-
- ssvnc_windows_only-1.0.29.zip
- ssvnc_no_windows-1.0.29.tar.gz
- ssvnc_unix_only-1.0.29.tar.gz
- ssvnc_unix_minimal-1.0.29.tar.gz
-
- ssvnc-1.0.29.tar.gz
- ssvnc-1.0.29.zip
- ssvnc_all-1.0.29.zip
-
- ssvnc-1.0.29.src.tar.gz Conventional Source for SSVNC GUI and Unix
- VNCviewer (0.5MB)
-
-
- For any Unix system, a self-extracting and running file for the
- "ssvnc_unix_minimal" package is here: ssvnc. Save it as filename
- "ssvnc", type "chmod 755 ./ssvnc", and then launch the GUI via typing
- "./ssvnc". Note that this "ssvnc_unix_minimal" mode requires you
- install the "stunnel" and "vncviewer" programs externally (for
- example, install your distros' versions, e.g. on debian: "apt-get
- install stunnel4 xtightvncviewer".) It will work, but many of the
- SSVNC features will be missing.
-
- Previous releases:
- Release 1.0.18 at Sourceforge.net
- Release 1.0.19 at Sourceforge.net
- Release 1.0.20 at Sourceforge.net
- Release 1.0.21 at Sourceforge.net
- Release 1.0.22 at Sourceforge.net
- Release 1.0.23 at Sourceforge.net
- Release 1.0.24 at Sourceforge.net
- Release 1.0.25 at Sourceforge.net
- Release 1.0.26 at Sourceforge.net
- Release 1.0.27 at Sourceforge.net
- Release 1.0.28 at Sourceforge.net
-
-
- Please help test the UltraVNC File Transfer support in the native Unix
- VNC viewer! Let us know how it went.
-
- Current Unix binaries in the archives:
- Linux.i686
- Linux.x86_64
- Linux.ppc64 X (removed)
- Linux.alpha X (removed)
- SunOS.sun4u
- SunOS.sun4m
- SunOS.i86pc
- Darwin.Power.Macintosh
- Darwin.i386
- HP-UX.9000 X (removed)
- FreeBSD.i386 X (removed)
- NetBSD.i386 X (removed)
- OpenBSD.i386 X (removed)
-
- (some of these are out of date, marked with 'X' above, because I no
- longer have access to machines running those OS's. Use the
- "build.unix" script to recompile on your system).
-
- Note: some of the above binaries depend on libssl.so.0.9.7, whereas
- some recent distros only provide libssl.so.0.9.8 by default (for
- compatibility reasons they should install both by default but not all
- do). So you may need to instruct your distro to install the 0.9.7
- library (it is fine to have both runtimes installed simultaneously
- since the libraries have different names). Update: I now try to
- statically link libssl.a for all of the binaries in the archive.
-
- You can also run the included build.unix script to try to
- automatically build the binaries if your OS is not in the above list
- or the included binary does not run properly on your system. Let me
- know how that goes.
- _________________________________________________________________
-
- IMPORTANT: there may be restrictions for you to download, use, or
- redistribute the above because of cryptographic software they contain
- or for other reasons. Please check out your situation and information
- at the following and related sites:
- http://stunnel.mirt.net
- http://www.stunnel.org
- http://www.openssl.org
- http://www.chiark.greenend.org.uk/~sgtatham/putty/
- http://www.tightvnc.com
- http://www.realvnc.com
- http://sourceforge.net/projects/cotvnc/
- _________________________________________________________________
-
- README: Here is the toplevel README from the bundle.
-
-=======================================================================
-http://www.karlrunge.com/x11vnc/x11vnc_opts.html:
-
-
- _________________________________________________________________
-
-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.13 lastmod: 2010-12-27
-
-x11vnc options:
- -display disp -auth file -N
- -autoport n -rfbport str -6
- -no6 -noipv6 -noipv4
- -reopen -reflect host:N -id windowid
- -sid windowid -appshare -clip WxH+X+Y
- -flashcmap -shiftcmap n -notruecolor
- -advertise_truecolor -visual n -overlay
- -overlay_nocursor -8to24 [opts] -24to32
- -scale fraction -geometry WxH -scale_cursor frac
- -viewonly -shared -once
- -forever -loop -timeout n
- -sleepin n -inetd -tightfilexfer
- -ultrafilexfer -http -http_ssl
- -avahi -mdns -zeroconf
- -connect string -connect_or_exit str -proxy string
- -vncconnect -novncconnect -allow host1[,host2..]
- -localhost -unixsock str -listen6 str
- -nolookup -input string -grabkbd
- -grabptr -ungrabboth -grabalways
- -viewpasswd string -passwdfile filename -showrfbauth filename
- -unixpw [list] -unixpw_nis [list] -unixpw_cmd cmd
- -find -finddpy -listdpy
- -findauth [disp] -create -xdummy
- -xvnc -xvnc_redirect -xdummy_xvfb
- -create_xsrv str -svc -svc_xdummy
- -svc_xvnc -svc_xdummy_xvfb -xdmsvc
- -sshxdmsvc -unixpw_system_greeter -redirect port
- -display WAIT:... -vencrypt mode -anontls mode
- -sslonly -dhparams file -nossl
- -ssl [pem] -ssltimeout n -sslnofail
- -ssldir dir -sslverify path -sslCRL path
- -sslGenCA [dir] -sslGenCert type name -sslEncKey pem
- -sslCertInfo pem -sslDelCert pem -sslScripts
- -stunnel [pem] -stunnel3 [pem] -enc cipher:keyfile
- -https [port] -httpsredir [port] -http_oneport
- -ssh user@host:disp -usepw -storepasswd pass file
- -nopw -accept string -afteraccept string
- -gone string -users list -noshm
- -flipbyteorder -onetile -solid [color]
- -blackout string -xinerama -noxinerama
- -xtrap -xrandr [mode] -rotate string
- -padgeom WxH -o logfile -flag file
- -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 -noskip_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
- -always_inject -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 -input_eagerly -speeds rd,bw,lat
- -wmdt string -debug_pointer -debug_keyboard
- -defer time -wait time -extra_fbur n
- -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 -macnoopengl
- -macnorawfb -gui [gui-opts] -remote command
- -query variable -QD variable -sync
- -query_retries str -remote_prefix str -noremote
- -yesremote -unsafe -safer
- -privremote -nocmds -allowedcmds list
- -deny_all
-
-LibVNCServer options:
--rfbport port TCP port for RFB protocol
--rfbwait time max time in ms to wait for RFB client
--rfbauth passwd-file use authentication on RFB protocol
- (use 'storepasswd' to create a password file)
--rfbversion 3.x Set the version of the RFB we choose to advertise
--permitfiletransfer permit file transfer support
--passwd plain-password use authentication
- (use plain-password as password, USE AT YOUR RISK)
--deferupdate time time in ms to defer updates (default 40)
--deferptrupdate time time in ms to defer pointer updates (default none)
--desktop name VNC desktop name (default "LibVNCServer")
--alwaysshared always treat new clients as shared
--nevershared never treat new clients as shared
--dontdisconnect don't disconnect existing clients when a new non-shared
- connection comes in (refuse new connection instead)
--httpdir dir-path enable http server using dir-path home
--httpport portnum use portnum for http connection
--enablehttpproxy enable http proxy support
--progressive height enable progressive updating for slow links
--listen ipaddr listen for connections only on network interface with
- addr ipaddr. '-listen localhost' and hostname work too.
-
-libvncserver-tight-extension options:
--disablefiletransfer disable file transfer
--ftproot string set ftp root
-
-
-
-
-% x11vnc -help
-
-x11vnc: allow VNC connections to real X11 displays. 0.9.13 lastmod: 2010-12-27
-
-(type "x11vnc -opts" to just list the options.)
-
-Typical usage is:
-
- Run this command in a shell on the remote machine "far-host"
- with X session you wish to view:
-
- x11vnc -display :0
-
- Then run this in another window on the machine you are sitting at:
-
- vncviewer far-host:0
-
-Once x11vnc establishes connections with the X11 server and starts listening
-as a VNC server it will print out a string: PORT=XXXX where XXXX is typically
-5900 (the default VNC server port). One would next run something like
-this on the local machine: "vncviewer hostname:N" where "hostname" is
-the name of the machine running x11vnc and N is XXXX - 5900, i.e. usually
-"vncviewer hostname:0".
-
-By default x11vnc will not allow the screen to be shared and it will exit
-as soon as the client disconnects. See -shared and -forever below to override
-these protections. See the FAQ for details how to tunnel the VNC connection
-through an encrypted channel such as ssh(1). In brief:
-
- ssh -t -L 5900:localhost:5900 far-host 'x11vnc -localhost -display :0'
-
- vncviewer -encodings 'copyrect tight zrle hextile' localhost:0
-
-Also, use of a VNC password (-rfbauth or -passwdfile) is strongly recommended.
-
-For additional info see: http://www.karlrunge.com/x11vnc/
- and http://www.karlrunge.com/x11vnc/faq.html
-
-
-Config file support: if the file $HOME/.x11vncrc exists then each line in
-it is treated as a single command line option. Disable with -norc. For
-each option name, the leading character "-" is not required. E.g. a line
-that is either "forever" or "-forever" may be used and are equivalent.
-Likewise "wait 100" or "-wait 100" are acceptable and equivalent lines.
-The "#" character comments out to the end of the line in the usual way
-(backslash it for a literal). Leading and trailing whitespace is trimmed off.
-Lines may be continued with a "\" as the last character of a line (it
-becomes a space character).
-
-Options:
-
--display disp X11 server display to connect to, usually :0. The X
- server process must be running on same machine and
- support MIT-SHM. Equivalent to setting the DISPLAY
- environment variable to "disp".
-
- See the description below of the "-display WAIT:..."
- extensions, where alias "-find" will find the user's
- display automatically, and "-create" will create a
- Xvfb session if no session is found.
-
--auth file Set the X authority file to be "file", equivalent to
- setting the XAUTHORITY environment variable to "file"
- before startup. Same as -xauth file. See Xsecurity(7),
- xauth(1) man pages for more info.
-
- Use '-auth guess' to have x11vnc use its -findauth
- mechanism (described below) to try to guess the
- XAUTHORITY filename and use it.
-
- XDM/GDM/KDM: if you are running x11vnc as root and want
- to find the XAUTHORITY before anyone has logged into an
- X session yet, use: x11vnc -env FD_XDM=1 -auth guess ...
- (This will also find the XAUTHORITY if a user is already
- logged into the X session.) When running as root,
- FD_XDM=1 will be tried if the initial -auth guess fails.
-
--N If the X display is :N, try to set the VNC display to
- also be :N This just sets the -rfbport option to 5900+N
- The program will exit immediately if that port is not
- available. The -N option only works with normal -display
- usage, e.g. :0 or :8, -N is ignored in the -display
- WAIT:..., -create, -find, -svc, -redirect, etc modes.
-
--autoport n Automatically probe for a free VNC port starting at n.
- The default is to start probing at 5900. Use this to
- stay away from other VNC servers near 5900.
-
--rfbport str The VNC port to listen on (a LibVNCServer option), e.g.
- 5900, 5901, etc. If specified as "-rfbport PROMPT"
- then the x11vnc -gui is used to prompt the user to
- enter the port number.
-
--6 IPv6 listening support. In addition to IPv4, the
- IPv6 address is listened on for incoming connections.
- The same port number as IPv4 is used.
-
- NOTE: This x11vnc binary was compiled to have the
- "-6" IPv6 listening mode ENABLED by default (CPPFLAGS
- -DX11VNC_LISTEN6=1). So to disable IPv6 listening mode
- you MUST supply the "-no6" option (see below.)
-
- The "-6" mode works for both normal connections and
- -ssl encrypted ones. Nearly everything is supported
- for the IPv6 case, but there are a few exceptions.
- See -stunnel for its IPv6 support.
-
- Currently, for absolutely everything to work correctly
- the machine may need to have some IPv4 support, at the
- least for the loopback interface. However, for nearly
- all usage modes no IPv4 support is required. See -nopiv4
-.
-
- If you have trouble compiling or running in IPv6 mode,
- set -DX11VNC_IPV6=0 in CPPFLAGS when configuring to
- disable IPv6 support.
-
--no6 Disable IPv6 listening support (only useful if the
- "-6" mode is compiled in to be the default; see the
- X11VNC_LISTEN6 description above under "-6".)
-
--noipv6 Do not try to use IPv6 for any listening or connecting
- sockets. This includes both the listening service
- port(s) and outgoing connections from -connect,
- -connect_or_exit, or -proxy. Use this if you are having
- problems due to IPv6.
-
--noipv4 Do not try to use IPv4 for any listening or connecting
- sockets. This is mainly for exploring the behavior of
- x11vnc on an IPv6-only system, but may have other uses.
-
--reopen If the X server connection is disconnected, try to
- reopen the X display (up to one time.) This is of use
- for display managers like GDM (KillInitClients option)
- that kill x11vnc just after the user logs into the
- X session. Note: the reopened state may be unstable.
- Set X11VNC_REOPEN_DISPLAY=n to reopen n times and
- set X11VNC_REOPEN_SLEEP_MAX to the number of seconds,
- default 10, to keep trying to reopen the display (once
- per second.)
-
- Update: as of 0.9.9, x11vnc tries to automatically avoid
- being killed by the display manager by delaying creating
- windows or using XFIXES. So you shouldn't need to use
- KillInitClients=false as long as you log in quickly
- enough (within 45 seconds of connecting.) You can
- disable this by setting X11VNC_AVOID_WINDOWS=never.
- You can also set it to the number of seconds to delay.
-
--reflect host:N Instead of connecting to and polling an X display,
- connect to the remote VNC server host:N and be a
- reflector/repeater for it. This is useful for trying
- to manage the case of many simultaneous VNC viewers
- (e.g. classroom broadcasting) where, e.g. you put
- a repeater on each network switch, etc, to improve
- performance by distributing the load and network
- traffic. Implies -shared (use -noshared as a later
- option to disable). See the discussion below under
- -rawfb vnc:host:N for more details.
-
--id windowid Show the X window corresponding to "windowid" not
- the entire display. New windows like popup menus,
- transient toplevels, etc, may not be seen or may be
- clipped. Disabling SaveUnders or BackingStore in the
- X server may help show them. x11vnc may crash if the
- window is initially partially obscured, changes size,
- is iconified, etc. Some steps are taken to avoid this
- and the -xrandr mechanism is used to track resizes. Use
- xwininfo(1) to get the window id, or use "-id pick"
- to have x11vnc run xwininfo(1) for you and extract
- the id. The -id option is useful for exporting very
- simple applications (e.g. the current view on a webcam).
--sid windowid As -id, but instead of using the window directly it
- shifts a root view to it: this shows SaveUnders menus,
- etc, although they will be clipped if they extend beyond
- the window.
-
--appshare Simple application sharing based on the -id/-sid
- mechanism. Every new toplevel window that the
- application creates induces a new viewer window via
- a reverse connection. The -id/-sid and -connect
- options are required. Run 'x11vnc -appshare -help'
- for more info.
-
--clip WxH+X+Y Only show the sub-region of the full display that
- corresponds to the rectangle geometry with size WxH and
- offset +X+Y. The VNC display has size WxH (i.e. smaller
- than the full display). This also works for -id/-sid
- mode where the offset is relative to the upper left
- corner of the selected window. An example use of this
- option would be to split a large (e.g. Xinerama) display
- into two parts to be accessed via separate viewers by
- running a separate x11vnc on each part.
-
- Use '-clip xinerama0' to clip to the first xinerama
- sub-screen (if xinerama is active). xinerama1 for the
- 2nd sub-screen, etc. This way you don't need to figure
- out the WxH+X+Y of the desired xinerama sub-screen.
- screens are sorted in increasing distance from the
- (0,0) origin (I.e. not the Xserver's order).
-
--flashcmap In 8bpp indexed color, let the installed colormap flash
- as the pointer moves from window to window (slow).
- Also try the -8to24 option to avoid flash altogether.
--shiftcmap n Rare problem, but some 8bpp displays use less than 256
- colorcells (e.g. 16-color grayscale, perhaps the other
- bits are used for double buffering) *and* also need to
- shift the pixels values away from 0, .., ncells. "n"
- indicates the shift to be applied to the pixel values.
- To see the pixel values set DEBUG_CMAP=1 to print out
- a colormap histogram. Example: -shiftcmap 240
--notruecolor For 8bpp displays, force indexed color (i.e. a colormap)
- even if it looks like 8bpp TrueColor (rare problem).
--advertise_truecolor If the X11 display is indexed color, lie to clients
- when they first connect by telling them it is truecolor.
- To workaround RealVNC: inPF has colourMap but not 8bpp
- Use '-advertise_truecolor reset' to reset client fb too.
-
--visual n This option probably does not do what you think.
- It simply *forces* the visual used for the framebuffer;
- this may be a bad thing... (e.g. messes up colors or
- cause a crash). It is useful for testing and for some
- workarounds. n may be a decimal number, or 0x hex.
- Run xdpyinfo(1) for the values. One may also use
- "TrueColor", etc. see <X11/X.h> for a list. If the
- string ends in ":m" then for better or for worse
- the visual depth is forced to be m. You may want to
- use -noshm when using this option (so XGetImage may
- automatically translate the pixel data).
-
--overlay Handle multiple depth visuals on one screen, e.g. 8+24
- and 24+8 overlay visuals (the 32 bits per pixel are
- packed with 8 for PseudoColor and 24 for TrueColor).
-
- Currently -overlay only works on Solaris via
- XReadScreen(3X11) and IRIX using XReadDisplay(3).
- On Solaris there is a problem with image "bleeding"
- around transient popup menus (but not for the menu
- itself): a workaround is to disable SaveUnders
- by passing the "-su" argument to Xsun (in
- /etc/dt/config/Xservers).
-
- Use -overlay as a workaround for situations like these:
- Some legacy applications require the default visual to
- be 8bpp (8+24), or they will use 8bpp PseudoColor even
- when the default visual is depth 24 TrueColor (24+8).
- In these cases colors in some windows will be incorrect
- in x11vnc unless -overlay is used. Another use of
- -overlay is to enable showing the exact mouse cursor
- shape (details below).
-
- Under -overlay, performance will be somewhat slower
- due to the extra image transformations required.
- For optimal performance do not use -overlay, but rather
- configure the X server so that the default visual is
- depth 24 TrueColor and try to have all apps use that
- visual (e.g. some apps have -use24 or -visual options).
--overlay_nocursor Sets -overlay, but does not try to draw the exact mouse
- cursor shape using the overlay mechanism.
-
--8to24 [opts] Try this option if -overlay is not supported on your
- OS, and you have a legacy 8bpp app that you want to
- view on a multi-depth display with default depth 24
- (and is 32 bpp) OR have a default depth 8 display with
- depth 24 overlay windows for some apps. This option
- may not work on all X servers and hardware (tested
- on XFree86/Xorg mga driver and Xsun). The "opts"
- string is not required and is described below.
-
- This mode enables a hack where x11vnc monitors windows
- within 3 levels from the root window. If it finds
- any that are 8bpp it extracts the indexed color
- pixel values using XGetImage() and then applies a
- transformation using the colormap(s) to create TrueColor
- RGB values that it in turn inserts into bits 1-24 of
- the framebuffer. This creates a depth 24 "view"
- of the display that is then exported via VNC.
-
- Conversely, for default depth 8 displays, the depth
- 24 regions are read by XGetImage() and everything is
- transformed and inserted into a depth 24 TrueColor
- framebuffer.
-
- Note that even if there are *no* depth 24 visuals or
- windows (i.e. pure 8bpp), this mode is potentially
- an improvement over -flashcmap because it avoids the
- flashing and shows each window in the correct color.
-
- This method works OK, but may still have bugs and it
- does hog resources. If there are multiple 8bpp windows
- using different colormaps, one may have to iconify all
- but one for the colors to be correct.
-
- There may be painting errors for clipping and switching
- between windows of depths 8 and 24. Heuristics are
- applied to try to minimize the painting errors. One can
- also press 3 Alt_L's in a row to refresh the screen
- if the error does not repair itself. Also the option
- -fixscreen 8=3.0 or -fixscreen V=3.0 may be used to
- periodically refresh the screen at the cost of bandwidth
- (every 3 sec for this example).
-
- The [opts] string can contain the following settings.
- Multiple settings are separated by commas.
-
- For for some X servers with default depth 24 a
- speedup may be achieved via the option "nogetimage".
- This enables a scheme were XGetImage() is not used
- to retrieve the 8bpp data. Instead, it assumes that
- the 8bpp data is in bits 25-32 of the 32bit X pixels.
- There is no requirement that the X server should put
- the data there for our poll requests, but some do and
- so the extra steps to retrieve it can be skipped.
- Tested with mga driver with XFree86/Xorg. For the
- default depth 8 case this option is ignored.
-
- To adjust how often XGetImage() is used to poll the
- non-default visual regions for changes, use the option
- "poll=t" where "t" is a floating point time.
- (default: 0.05)
-
- Setting the option "level2" will limit the search
- for non-default visual windows to two levels from the
- root window. Do this on slow machines where you know
- the window manager only imposes one extra window between
- the app window and the root window.
-
- Also for very slow machines use "cachewin=t"
- where t is a floating point amount of time to cache
- XGetWindowAttributes results. E.g. cachewin=5.0.
- This may lead to the windows being unnoticed for this
- amount of time when deiconifying, painting errors, etc.
-
- While testing on a very old SS20 these options gave
- tolerable response: -8to24 poll=0.2,cachewin=5.0. For
- this machine -overlay is supported and gives better
- response.
-
- Debugging for this mode can be enabled by setting
- "dbg=1", "dbg=2", or "dbg=3".
-
--24to32 Very rare problem: if the framebuffer (X display
- or -rawfb) is 24bpp instead of the usual 32bpp, then
- dynamically transform the pixels to 32bpp. This will be
- slower, but can be used to work around problems where
- VNC viewers cannot handle 24bpp (e.g. "main: setPF:
- not 8, 16 or 32 bpp?"). See the FAQ for more info.
-
- In the case of -rawfb mode, the pixels are directly
- modified by inserting a 0 byte to pad them out to 32bpp.
- For X displays, a kludge is done that is equivalent to
- "-noshm -visual TrueColor:32". (If better performance
- is needed for the latter, feel free to ask).
-
--scale fraction Scale the framebuffer by factor "fraction". Values
- less than 1 shrink the fb, larger ones expand it. Note:
- the image may not be sharp and response may be slower.
- If "fraction" contains a decimal point "." it
- is taken as a floating point number, alternatively
- the notation "m/n" may be used to denote fractions
- exactly, e.g. -scale 2/3
-
- To scale asymmetrically in the horizontal and vertical
- directions, specify a WxH geometry to stretch to:
- e.g. '-scale 1024x768', or also '-scale 0.9x0.75'
-
- Scaling Options: can be added after "fraction" via
- ":", to supply multiple ":" options use commas.
- If you just want a quick, rough scaling without
- blending, append ":nb" to "fraction" (e.g. -scale
- 1/3:nb). No blending is the default for 8bpp indexed
- color, to force blending for this case use ":fb".
-
- To disable -scrollcopyrect and -wirecopyrect under
- -scale use ":nocr". If you need to to enable them use
- ":cr" or specify them explicitly on the command line.
- If a slow link is detected, ":nocr" may be applied
- automatically. Default: :cr
-
- More esoteric options: for compatibility with vncviewers
- the scaled width is adjusted to be a multiple of 4:
- to disable this use ":n4". ":in" use interpolation
- scheme even when shrinking, ":pad" pad scaled width
- and height to be multiples of scaling denominator
- (e.g. 3 for 2/3).
-
--geometry WxH Same as -scale WxH
-
--scale_cursor frac By default if -scale is supplied the cursor shape is
- scaled by the same factor. Depending on your usage,
- you may want to scale the cursor independently of the
- screen or not at all. If you specify -scale_cursor
- the cursor will be scaled by that factor. When using
- -scale mode to keep the cursor at its "natural" size
- use "-scale_cursor 1". Most of the ":" scaling
- options apply here as well.
-
--viewonly All VNC clients can only watch (default off).
--shared VNC display is shared, i.e. more than one viewer can
- connect at the same time (default off).
--once Exit after the first successfully connected viewer
- disconnects, opposite of -forever. This is the Default.
--forever Keep listening for more connections rather than exiting
- as soon as the first client(s) disconnect. Same as -many
-
- To get the standard non-shared VNC behavior where when
- a new VNC client connects the existing VNC client is
- dropped use: -nevershared -forever This method can
- also be used to guard against hung TCP connections that
- do not go away.
-
--loop Create an outer loop restarting the x11vnc process
- whenever it terminates. -bg and -inetd are ignored
- in this mode (however see -loopbg below).
-
- Useful for continuing even if the X server terminates
- and restarts (at that moment the process will need
- permission to reconnect to the new X server of course).
-
- Use, e.g., -loop100 to sleep 100 millisecs between
- restarts, etc. Default is 2000ms (i.e. 2 secs) Use,
- e.g. -loop300,5 to sleep 300 ms and only loop 5 times.
-
- If -loopbg (plus any numbers) is specified instead,
- the "-bg" option is implied and the mode approximates
- inetd(8) usage to some degree. In this case when
- it goes into the background any listening sockets
- (i.e. ports 5900, 5800) are closed, so the next one
- in the loop can use them. This mode will only be of
- use if a VNC client (the only client for that process)
- is already connected before the process goes into the
- background, for example, usage of -display WAIT:..,
- -svc, and -connect can make use of this "poor man's"
- inetd mode. The default wait time is 500ms in this
- mode. This usage could use useful: -svc -bg -loopbg
-
--timeout n Exit unless a client connects within the first n seconds
- after startup.
-
- If there have been no connection attempts after n
- seconds x11vnc exits immediately. If a client is
- trying to connect but has not progressed to the normal
- operating state, x11vnc gives it a few more seconds
- to finish and exits if it does not make it to the
- normal state.
-
- For reverse connections via -connect or -connect_or_exit
- a timeout of n seconds will be set for all reverse
- connects. If the connect timeout alarm goes off,
- x11vnc will exit immediately.
-
--sleepin n At startup sleep n seconds before proceeding (e.g. to
- allow redirs and listening clients to start up)
-
- If a range is given: '-sleepin min-max', a random value
- between min and max is slept. E.g. '-sleepin 0-20' and
- '-sleepin 10-30'. Floats are allowed too.
-
--inetd Launched by inetd(8): stdio instead of listening socket.
- Note: if you are not redirecting stderr to a log file
- (via shell 2> or -o option) you MUST also specify the -q
- option, otherwise the stderr goes to the viewer which
- will cause it to abort. Specifying both -inetd and -q
- and no -o will automatically close the stderr.
-
--tightfilexfer Enable the TightVNC file transfer extension. Note that
- that when the -viewonly option is supplied all file
- transfers are disabled. Also clients that log in
- viewonly cannot transfer files. However, if the remote
- control mechanism is used to change the global or
- per-client viewonly state the filetransfer permissions
- will NOT change.
-
- IMPORTANT: please understand if -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 -users option, then
- VNC Viewers that connect are able to do filetransfer
- reads and writes as *root*.
-
- Also, tightfilexfer is disabled in -unixpw mode.
-
--ultrafilexfer Note: to enable UltraVNC filetransfer and to get it to
- work you probably need to supply these LibVNCServer
- options: "-rfbversion 3.6 -permitfiletransfer"
- "-ultrafilexfer" is an alias for this combination.
-
- IMPORTANT: please understand if -ultrafilexfer 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 -users option, then
- VNC Viewers that connect are able to do filetransfer
- reads and writes as *root*.
-
- Note that sadly you cannot do both -tightfilexfer and
- -ultrafilexfer at the same time because the latter
- requires setting the version to 3.6 and tightvnc will
- not do filetransfer when it sees that version number.
-
--http Instead of using -httpdir (see below) to specify
- where the Java vncviewer applet is, have x11vnc try
- to *guess* where the directory is by looking relative
- to the program location and in standard locations
- (/usr/local/share/x11vnc/classes, etc). Under -ssl or
- -stunnel the ssl classes subdirectory is sought.
--http_ssl As -http, but force lookup for ssl classes subdir.
-
- Note that for HTTPS, single-port Java applet delivery
- you can set X11VNC_HTTPS_DOWNLOAD_WAIT_TIME to the
- max number of seconds to wait for the applet download
- to finish. The default is 15.
-
--avahi Use the Avahi/mDNS ZeroConf protocol to advertise
- this VNC server to the local network. (Related terms:
- Rendezvous, Bonjour). Depending on your setup, you
- may need to start avahi-daemon and open udp port 5353
- in your firewall.
-
- You can set X11VNC_AVAHI_NAME, X11VNC_AVAHI_HOST,
- and/or X11VNC_AVAHI_PORT environment variables
- to override the default values. For example:
- -env X11VNC_AVAHI_NAME=wally
-
- If the avahi API cannot be found at build time, a helper
- program like avahi-publish(1) or dns-sd(1) will be tried
-
--mdns Same as -avahi.
--zeroconf Same as -avahi.
-
--connect string For use with "vncviewer -listen" reverse connections.
- If "string" has the form "host" or "host:port"
- the connection is made once at startup.
-
- Use commas for a list of host's and host:port's.
- E.g. -connect host1,host2 or host1:0,host2:5678.
- Note that to reverse connect to multiple hosts at the
- same time you will likely need to also supply: -shared
-
- Note that unlike most vnc servers, x11vnc will require a
- password for reverse as well as for forward connections.
- (provided password auth has been enabled, -rfbauth, etc)
- If you do not want to require a password for reverse
- connections set X11VNC_REVERSE_CONNECTION_NO_AUTH=1 in
- your environment before starting x11vnc.
-
- If "string" contains "/" it is instead interpreted
- as a file to periodically check for new hosts.
- The first line is read and then the file is truncated.
- Be careful about the location of this file if x11vnc
- is running as root (e.g. via gdm(1), etc).
-
-
- Repeater mode: Some services provide an intermediate
- "vnc repeater": http://www.uvnc.com/addons/repeater.html
- (and also http://koti.mbnet.fi/jtko/ for linux port)
- that acts as a proxy/gateway. Modes like these require
- an initial string to be sent for the reverse connection
- before the VNC protocol is started. Here are the ways
- to do this:
-
- -connect pre=some_string+host:port
- -connect pre128=some_string+host:port
- -connect repeater=ID:1234+host:port
- -connect repeater=23.45.67.89::5501+host:port
-
- SSVNC notation is also supported:
-
- -connect repeater://host:port+ID:1234
-
- As with normal -connect usage, if the repeater port is
- not supplied 5500 is assumed.
-
- The basic idea is between the special tag, e.g. "pre="
- and "+" is the pre-string to be sent. Note that in
- this case host:port is the repeater server, NOT the
- vnc viewer. Somehow the pre-string tells the repeater
- server how to find the vnc viewer and connect you to it.
-
- In the case pre=some_string+host:port, "some_string"
- is simply sent. In the case preNNN=some_string+host:port
- "some_string" is sent in a null padded buffer of
- length NNN. repeater= is the same as pre250=, this is
- the ultravnc repeater buffer size.
-
- Strings like "\n" and "\r", etc. are expanded to
- newline and carriage return. "\c" is expanded to
- "," since the connect string is comma separated.
-
- See also the -proxy option below for additional ways
- to plumb reverse connections.
-
- Reverse SSL: using -connect in -ssl mode makes x11vnc
- act as an SSL client (initiates SSL connection) rather
- than an SSL server. The idea is x11vnc might be
- connecting to stunnel on the viewer side with the
- viewer in listening mode. If you do not want this
- behavior, use -env X11VNC_DISABLE_SSL_CLIENT_MODE=1.
- With this the viewer side can act as the SSL client
- as it normally does for forward connections.
-
- Reverse SSL Repeater mode: This will work, but note
- that if the VNC Client does any sort of a 'Fetch Cert'
- action before connecting, then the Repeater will
- likely drop the connection and both sides will need
- to restart. Consider the use of -connect_or_exit
- and -loop300,2 to have x11vnc reconnect once to the
- repeater after the fetch. You will probably also want
- to supply -sslonly to avoid x11vnc thinking the delay
- in response means the connection is VeNCrypt. The env
- var X11VNC_DISABLE_SSL_CLIENT_MODE=1 discussed above
- may also be useful (i.e. the viewer can do a forward
- connection as it normally does.)
-
- IPv6: as of x11vnc 0.9.10 the -connect option should
- connect to IPv6 hosts properly. If there are problems
- you can disable IPv6 by setting -DX11VNC_IPV6=0
- in CPPFLAGS when configuring. If there problems
- connecting to IPv6 hosts consider a relay like the
- included inet6to4 script or the -proxy option.
-
--connect_or_exit str As with -connect, except if none of the reverse
- connections succeed, then x11vnc shuts down immediately
-
- An easier to type alias for this option is '-coe'
-
- By the way, if you do not want x11vnc to listen on
- ANY interface use -rfbport 0 which is handy for the
- -connect_or_exit mode.
-
--proxy string Use proxy in string (e.g. host:port) as a proxy for
- making reverse connections (-connect or -connect_or_exit
- options).
-
- Web proxies are supported, but note by default most of
- them only support destination connections to ports 443
- or 563, so this might not be very useful (the viewer
- would need to listen on that port or the router would
- have to do a port redirection).
-
- A web proxy may be specified by either "host:port"
- or "http://host:port" (the port is required even if
- it is the common choices 80 or 8080)
-
- SOCKS4, SOCKS4a, and SOCKS5 are also supported.
- SOCKS proxies normally do not have restrictions on the
- destination port number.
-
- Use a format like this: socks://host:port or
- socks5://host:port. Note that ssh -D does not support
- SOCKS4a, so use socks5://. For socks:// SOCKS4 is used
- on a numerical IP and "localhost", otherwise SOCKS4a
- is used (and so the proxy tries to do the DNS lookup).
-
- An experimental mode is "-proxy http://host:port/..."
- Note the "/" after the port that distinguishes it from
- a normal web proxy. The port must be supplied even if
- it is the default 80. For this mode a GET is done to
- the supplied URL with the string host=H&port=P appended.
- H and P will be the -connect reverse connect host
- and port. Use the string "__END__" to disable the
- appending. The basic idea here is that maybe some cgi
- script provides the actual viewer hookup and tunnelling.
- How to actually achieve this within cgi, php, etc. is
- not clear... A custom web server or apache module
- would be straight-forward.
-
- Another experimental mode is "-proxy ssh://user@host"
- in which case a SSH tunnel is used for the proxying.
- "user@" is not needed unless your unix username is
- different on "host". For a non-standard SSH port
- use ssh://user@host:port. If proxies are chained (see
- next paragraph) then the ssh one must be the first one.
- If ssh-agent is not active, then the ssh password needs
- to be entered in the terminal where x11vnc is running.
- Examples:
-
- -connect localhost:0 -proxy ssh://me@friends-pc:2222
-
- -connect snoopy:0 -proxy ssh://ssh.company.com
-
- Multiple proxies may be chained together in case one
- needs to ricochet off of a number of hosts to finally
- reach the VNC viewer. Up to 3 may be chained, separate
- them by commas in the order they are to be connected to.
- E.g.: http://host1:port1,socks5://host2:port2 or three
- like: first,second,third
-
- IPv6: as of x11vnc 0.9.10 the -proxy option should
- connect to IPv6 hosts properly. If there are problems
- you can disable IPv6 by setting -DX11VNC_IPV6=0
- in CPPFLAGS when configuring. If there problems
- connecting to IPv6 hosts consider a relay like the
- included inet6to4 script.
-
--vncconnect Monitor the VNC_CONNECT X property set by the standard
--novncconnect VNC program vncconnect(1). When the property is
- set to "host" or "host:port" establish a reverse
- connection. Using xprop(1) instead of vncconnect may
- work (see the FAQ). The -remote control mechanism uses
- X11VNC_REMOTE channel, and this option disables/enables
- it as well. Default: -vncconnect
-
- To use different names for these X11 properties (e.g. to
- have separate communication channels for multiple
- x11vnc's on the same display) set the VNC_CONNECT or
- X11VNC_REMOTE env. vars. to the string you want, for
- example: -env X11VNC_REMOTE=X11VNC_REMOTE_12345
- Both sides of the channel must use the same unique name.
- The same can be done for the internal X11VNC_TICKER
- property (heartbeat and timestamp) if desired.
-
--allow host1[,host2..] Only allow client connections from hosts matching
- the comma separated list of hostnames or IP addresses.
- Can also be a numerical IP prefix, e.g. "192.168.100."
- to match a simple subnet, for more control build
- LibVNCServer with libwrap support (See the FAQ). If the
- list contains a "/" it instead is a interpreted
- as a file containing addresses or prefixes that is
- re-read each time a new client connects. Lines can be
- commented out with the "#" character in the usual way.
-
- -allow applies in -ssl mode, but not in -stunnel mode.
-
- IPv6: as of x11vnc 0.9.10 a host can be specified
- in IPv6 numerical format, e.g. 2001:4860:b009::93.
-
--localhost Basically the same as "-allow 127.0.0.1".
-
- Note: if you want to restrict which network interface
- x11vnc listens on, see the -listen option below.
- E.g. "-listen localhost" or "-listen 192.168.3.21".
- As a special case, the option "-localhost" implies
- "-listen localhost".
-
- A rare case, but for non-localhost -listen usage, if
- you use the remote control mechanism (-R) to change
- the -listen interface you may need to manually adjust
- the -allow list (and vice versa) to avoid situations
- where no connections (or too many) are allowed.
-
- If you do not want x11vnc to listen on ANY interface
- (evidently you are using -connect or -connect_or_exit,
- or plan to use remote control: -R connect:host), use
- -rfbport 0
-
- IPv6: if IPv6 is supported, this option automatically
- implies the IPv6 loopback address '::1' as well.
-
--unixsock str Listen on the unix socket (AF_UNIX) 'str'
- for connections. This mode is for either local
- connections or a tunnel endpoint where one wants the
- file permission of the unix socket file to determine
- what can connect to it. (This currently requires an
- edit to libvnserver/rfbserver.c: comment out lines 310
- and 311, 'close(sock)' and 'return NULL' in rfbserver.c
- after the setsockopt() call.) Note that to disable all
- tcp listening ports specify '-rfbport 0' and should be
- useful with this mode. Example:
- mkdir ~/s; chmod 700 ~/s;
- x11vnc -unixsock ~/s/mysock -rfbport 0 ...
- The SSVNC unix vncviewer can connect to unix sockets.
-
--listen6 str When in IPv6 listen mode "-6", listen only on the
- network interface with address "str". It also works
- for link scope addresses (fe80::219:dbff:fee5:3f92%eth0)
- and IPv6 hostname strings (e.g. ipv6.google.com.)
- Use LibVNCServer -listen option for the IPv4 interface.
-
--nolookup Do not use gethostbyname() or gethostbyaddr() to look up
- host names or IP numbers. Use this if name resolution
- is incorrectly set up and leads to long pauses as name
- lookups time out, etc.
-
--input string Fine tuning of allowed user input. If "string" does
- not contain a comma "," the tuning applies only to
- normal clients. Otherwise the part before "," is
- for normal clients and the part after for view-only
- clients. "K" is for Keystroke input, "M" for
- Mouse-motion input, "B" for Button-click input, "C"
- is for Clipboard input, and "F" is for File transfer
- (ultravnc only). Their presence in the string enables
- that type of input. E.g. "-input M" means normal
- users can only move the mouse and "-input KMBCF,M"
- lets normal users do anything and enables view-only
- users to move the mouse. This option is ignored when
- a global -viewonly is in effect (all input is discarded
- in that case).
-
--grabkbd When VNC viewers are connected, attempt to the grab
- the keyboard so a (non-malicious) user sitting at the
- physical display is not able to enter keystrokes.
- This method uses XGrabKeyboard(3X11) and so it is
- not secure and does not rule out the person at the
- physical display injecting keystrokes by flooding the
- server with them, grabbing the keyboard himself, etc.
- Some degree of cooperation from the person at the
- display is assumed. This is intended for remote
- help-desk or educational usage modes.
-
- Note: on some recent (12/2010) X servers and/or
- desktops, -grabkbd no longer works: it prevents the
- window manager from resizing windows and similar things.
- Try -ungrabboth below (might not work.)
-
--grabptr As -grabkbd, but for the mouse pointer using
- XGrabPointer(3X11). Unfortunately due to the way the X
- server works, the mouse can still be moved around by the
- user at the physical display, but he will not be able to
- change window focus with it. Also some window managers
- that call XGrabServer(3X11) for resizes, etc, will
- act on the local user's input. Again, some degree of
- cooperation from the person at the display is assumed.
-
--ungrabboth Whenever there is any input (either keyboard or
- pointer), ungrab *both* the keyboard and the pointer
- while injecting the synthetic input. This is to allow
- window managers, etc. a chance to grab.
-
--grabalways Apply both -grabkbd and -grabptr even when no VNC
- viewers are connected. If you only want one of them,
- use the -R remote control to turn the other back on,
- e.g. -R nograbptr.
-
--viewpasswd string Supply a 2nd password for view-only logins. The -passwd
- (full-access) password must also be supplied.
-
--passwdfile filename Specify the LibVNCServer password via the first line
- of the file "filename" (instead of via -passwd on
- the command line where others might see it via ps(1)).
-
- See the descriptions below for how to supply multiple
- passwords, view-only passwords, to specify external
- programs for the authentication, and other features.
-
- If the filename is prefixed with "rm:" it will be
- removed after being read. Perhaps this is useful in
- limiting the readability of the file. In general, the
- password file should not be readable by untrusted users
- (BTW: neither should the VNC -rfbauth file: it is NOT
- encrypted, only obscured with a fixed key).
-
- If the filename is prefixed with "read:" it will
- periodically be checked for changes and reread. It is
- guaranteed to be reread just when a new client connects
- so that the latest passwords will be used.
-
- If "filename" is prefixed with "cmd:" then the
- string after the ":" is run as an external command:
- the output of the command will be interpreted as if it
- were read from a password file (see below). If the
- command does not exit with 0, then x11vnc terminates
- immediately. To specify more than 1000 passwords this
- way set X11VNC_MAX_PASSWDS before starting x11vnc.
- The environment variables are set as in -accept.
-
- Note that due to the VNC protocol only the first 8
- characters of a password are used (DES key).
-
- If "filename" is prefixed with "custom:" then a
- custom password checker is supplied as an external
- command following the ":". The command will be run
- when a client authenticates. If the command exits with
- 0 the client is accepted, otherwise it is rejected.
- The environment variables are set as in -accept.
-
- The standard input to the custom command will be a
- decimal digit "len" followed by a newline. "len"
- specifies the challenge size and is usually 16 (the
- VNC spec). Then follows len bytes which is the random
- challenge string that was sent to the client. This is
- then followed by len more bytes holding the client's
- response (i.e. the challenge string encrypted via DES
- with the user password in the standard situation).
-
- The "custom:" scheme can be useful to implement
- dynamic passwords or to implement methods where longer
- passwords and/or different encryption algorithms
- are used. The latter will require customizing the VNC
- client as well. One could create an MD5SUM based scheme
- for example.
-
- File format for -passwdfile:
-
- If multiple non-blank lines exist in the file they are
- all taken as valid passwords. Blank lines are ignored.
- Password lines may be "commented out" (ignored) if
- they begin with the character "#" or the line contains
- the string "__SKIP__". Lines may be annotated by use
- of the "__COMM__" string: from it to the end of the
- line is ignored. An empty password may be specified
- via the "__EMPTY__" string on a line by itself (note
- your viewer might not accept empty passwords).
-
- If the string "__BEGIN_VIEWONLY__" appears on a
- line by itself, the remaining passwords are used for
- viewonly access. For compatibility, as a special case
- if the file contains only two password lines the 2nd
- one is automatically taken as the viewonly password.
- Otherwise the "__BEGIN_VIEWONLY__" token must be
- used to have viewonly passwords. (tip: make the 3rd
- and last line be "__BEGIN_VIEWONLY__" to have 2
- full-access passwords)
-
--showrfbauth filename Print to the screen the obscured VNC password kept in
- the rfbauth file "filename" and then exit.
-
--unixpw [list] Use Unix username and password authentication. x11vnc
- will use the su(1) program to verify the user's
- password. [list] is an optional comma separated list
- of allowed Unix usernames. If the [list] string begins
- with the character "!" then the entire list is taken
- as an exclude list. See below for per-user options
- that can be applied.
-
- A familiar "login:" and "Password:" dialog is
- presented to the user on a black screen inside the
- vncviewer. The connection is dropped if the user fails
- to supply the correct password in 3 tries or does not
- send one before a 45 second timeout. Existing clients
- are view-only during this period.
-
- If the first character received is "Escape" then the
- unix username will not be displayed after "login:"
- as it is typed. This could be of use for VNC viewers
- that automatically type the username and password.
-
- Since the detailed behavior of su(1) can vary from
- OS to OS and for local configurations, test the mode
- before deployment to make sure it is working properly.
- x11vnc will attempt to be conservative and reject a
- login if anything abnormal occurs.
-
- One case to note: FreeBSD and the other BSD's by
- default it is impossible for the user running x11vnc to
- validate his *own* password via su(1) (commenting out
- the pam_self.so entry in /etc/pam.d/su eliminates this
- behavior). So the x11vnc login will always *FAIL* for
- this case (even when the correct password is supplied).
-
- A possible workaround for this on *BSD would be to
- start x11vnc as root with the "-users +nobody" option
- to immediately switch to user nobody where the su'ing
- will proceed normally.
-
- Another source of potential problems are PAM modules
- that prompt for extra info, e.g. password aging modules.
- These logins will fail as well even when the correct
- password is supplied.
-
- **IMPORTANT**: to prevent the Unix password being sent
- in *clear text* over the network, one of two schemes
- will be enforced: 1) the -ssl builtin SSL mode, or 2)
- require both -localhost and -stunnel be enabled.
-
- Method 1) ensures the traffic is encrypted between
- viewer and server. A PEM file will be required, see the
- discussion under -ssl below (under some circumstances
- a temporary one can be automatically generated).
-
- Method 2) requires the viewer connection to appear
- to come from the same machine x11vnc is running on
- (e.g. from a ssh -L port redirection). And that the
- -stunnel SSL mode be used for encryption over the
- network. (see the description of -stunnel below).
-
- Note: as a convenience, if you ssh(1) in and start
- x11vnc it will check if the environment variable
- SSH_CONNECTION is set and appears reasonable. If it
- does, then the -ssl or -stunnel requirement will be
- dropped since it is assumed you are using ssh for the
- encrypted tunnelling. -localhost is still enforced.
- Use -ssl or -stunnel to force SSL usage even if
- SSH_CONNECTION is set.
-
- To override the above restrictions you can set
- environment variables before starting x11vnc:
-
- Set UNIXPW_DISABLE_SSL=1 to disable requiring either
- -ssl or -stunnel (as under SSH_CONNECTION.) Evidently
- you will be using a different method to encrypt the
- data between the vncviewer and x11vnc: perhaps ssh(1)
- or an IPSEC VPN. -localhost is still enforced (however,
- see the next paragraph.)
-
- Set UNIXPW_DISABLE_LOCALHOST=1 to disable the -localhost
- requirement in -unixpw modes. One should never do this
- (i.e. allow the Unix passwords to be sniffed on the
- network.) This also disables the localhost requirement
- for reverse connections (see below.)
-
- Note that use of -localhost with ssh(1) (and no -unixpw)
- is roughly the same as requiring a Unix user login
- (since a Unix password or the user's public key
- authentication is used by sshd on the machine where
- x11vnc runs and only local connections from that machine
- are accepted).
-
- Regarding reverse connections (e.g. -R connect:host
- and -connect host), when the -localhost constraint is
- in effect then reverse connections can only be used
- to connect to the same machine x11vnc is running on
- (default port 5500). Please use a ssh or stunnel port
- redirection to the viewer machine to tunnel the reverse
- connection over an encrypted channel.
-
- In -inetd mode the Method 1) will be enforced (not
- Method 2). With -ssl in effect reverse connections
- are disabled. If you override this via env. var, be
- sure to also use encryption from the viewer to inetd.
- Tip: you can also have your own stunnel spawn x11vnc
- in -inetd mode (thereby bypassing inetd). See the FAQ
- for details.
-
- The user names in the comma separated [list] may have
- per-user options after a ":", e.g. "fred:opts"
- where "opts" is a "+" separated list of
- "viewonly", "fullaccess", "input=XXXX", or
- "deny", e.g. "karl,wally:viewonly,boss:input=M".
- For "input=" it is the K,M,B,C described under -input.
-
- If an item in the list is "*" that means those
- options apply to all users. It ALSO implies all users
- are allowed to log in after supplying a valid password.
- Use "deny" to explicitly deny some users if you use
- "*" to set a global option. If [list] begins with the
- "!" character then "*" is ignored for checking if
- the user is allowed, but the option values associated
- with it do apply as normal.
-
- There are also some utilities for checking passwords
- if [list] starts with the "%" character. See the
- quick_pw() function for more details. Description:
- "%-" or "%stdin" means read one line from stdin.
- "%env" means it is in $UNIXPW env var. A leading
- "%/" or "%." means read the first line from the
- filename that follows after the % character. % by
- itself means prompt for the username and password.
- Otherwise: %user:pass E.g. -unixpw %fred:swordfish
- For the other cases user:pass is read from the indicated
- source. If the password is correct 'Y user' is printed
- and the program exit code is 0. If the password is
- incorrect it prints 'N user' and the exit code is 1.
- If there is some other error the exit code is 2.
- This feature enables x11vnc to be a general unix user
- password checking tool; it could be used from scripts
- or other programs. These % password checks also apply
- to the -unixpw_nis and -unixpw_cmd options.
-
- For the % password check, if the env. var. UNIXPW_CMD
- is set to a command then it is run as the user (assuming
- the password is correct.) The output of the command is
- not printed, the program or script must manage that by
- some other means. The exit code of x11vnc will depend
- on the exit code of the command that is run.
-
- Use -nounixpw to disable unixpw mode if it was enabled
- earlier in the cmd line (e.g. -svc mode)
-
--unixpw_nis [list] As -unixpw above, however do not use su(1) but rather
- use the traditional getpwnam(3) + crypt(3) method to
- verify passwords. All of the above -unixpw options and
- constraints apply.
-
- This mode requires that the encrypted passwords be
- readable. Encrypted passwords stored in /etc/shadow
- will be inaccessible unless x11vnc is run as root.
-
- This is called "NIS" mode simply because in most
- NIS setups user encrypted passwords are accessible
- (e.g. "ypcat passwd") by an ordinary user and so that
- user can authenticate ANY user.
-
- NIS is not required for this mode to work (only that
- getpwnam(3) return the encrypted password is required),
- but it is unlikely it will work (as an ordinary user)
- for most modern environments unless NIS is available.
- On the other hand, when x11vnc is run as root it will
- be able to to access /etc/shadow even if NIS is not
- available (note running as root is often done when
- running x11vnc from inetd and xdm/gdm/kdm).
-
- Looked at another way, if you do not want to use the
- su(1) method provided by -unixpw (i.e. su_verify()), you
- can run x11vnc as root and use -unixpw_nis. Any users
- with passwords in /etc/shadow can then be authenticated.
-
- In -unixpw_nis mode, under no circumstances is x11vnc's
- user password verifying function based on su called
- (i.e. the function su_verify() that runs /bin/su
- in a pseudoterminal to verify passwords.) However,
- if -unixpw_nis is used in conjunction with the -find
- and -create -display WAIT:... modes then, if x11vnc is
- running as root, /bin/su may be called externally to
- run the find or create commands.
-
--unixpw_cmd cmd As -unixpw above, however do not use su(1) but rather
- run the externally supplied command "cmd". The first
- line of its stdin will be the username and the second
- line the received password. If the command exits
- with status 0 (success) the VNC user will be accepted.
- It will be rejected for any other return status.
-
- Dynamic passwords and non-unix passwords, e.g. LDAP,
- can be implemented this way by providing your own custom
- helper program. Note that the remote viewer is given 3
- tries to enter the correct password, and so the program
- may be called in a row that many (or more) times.
-
- If a list of allowed users is needed to limit who can
- log in, use -unixpw [list] in addition to this option.
-
- In FINDDISPLAY and FINDCREATEDISPLAY modes the "cmd"
- will also be run with the RFB_UNIXPW_CMD_RUN env. var.
- non-empty and set to the corresponding display
- find/create command. The first two lines of input are
- the username and passwd as in the normal case described
- above. To support FINDDISPLAY and FINDCREATEDISPLAY,
- "cmd" should run the requested command as the user
- (and most likely refusing to run it if the password is
- not correct.) Here is an example script (note it has
- a hardwired bogus password "abc"!)
-
- #!/bin/sh
- # Example x11vnc -unixpw_cmd script.
- # Read the first two lines of stdin (user and passwd)
- read user
- read pass
-
- debug=0
- if [ $debug = 1 ]; then
- echo "user: $user" 1>&2
- echo "pass: $pass" 1>&2
- env | egrep -i 'rfb|vnc' 1>&2
- fi
-
- # Check if the password is valid.
- # (A real example would use ldap lookup, etc!)
- if [ "X$pass" != "Xabc" ]; then
- exit 1 # incorrect password
- fi
-
- if [ "X$RFB_UNIXPW_CMD_RUN" = "X" ]; then
- exit 0 # correct password
- else
- # Run the requested command (finddisplay)
- if [ $debug = 1 ]; then
- echo "run: $RFB_UNIXPW_CMD_RUN" 1>&2
- fi
- exec /bin/su - "$user" -c "$RFB_UNIXPW_CMD_RUN"
- fi
-
- In -unixpw_cmd mode, under no circumstances is x11vnc's
- user password verifying function based on su called
- (i.e. the function su_verify() that runs /bin/su in a
- pseudoterminal to verify passwords.) It is up to the
- supplied unixpw_cmd to do user switching if desired
- and if it has the permissions to do so.
-
--find Find the user's display using FINDDISPLAY. This
- is an alias for "-display WAIT:cmd=FINDDISPLAY".
-
- Note: if a -display occurs later on the command line
- it will override the -find setting.
-
- For this and the next few options see -display WAIT:...
- below for all of the details.
-
--finddpy Run the FINDDISPLAY program, print out the found
- display (if any) and exit. Output is like: DISPLAY=:0.0
- DISPLAY=:0.0,XPID=12345 or DISPLAY=:0.0,VT=7. XPID is
- the process ID of the found X server. VT is the Linux
- virtual terminal of the X server.
--listdpy Have the FINDDISPLAY program list all of your displays
- (i.e. all the X displays on the local machine that you
- have access rights to). x11vnc then exits.
-
--findauth [disp] Apply the -find/-finddpy heuristics to try to guess
- the XAUTHORITY file for DISPLAY 'disp'. If 'disp'
- is not supplied, then the value in the -display on
- the cmdline is used; failing that $DISPLAY is used;
- and failing that ":0" is used. x11vnc then exits.
-
- If nothing is printed out, that means no XAUTHORITY was
- found for 'disp'; i.e. failure. If "XAUTHORITY="
- is printed out, that means use the default (i.e. do
- not set XAUTHORITY). If "XAUTHORITY=/path/to/file"
- is printed out, then use that file.
-
- XDM/GDM/KDM: if you are running x11vnc as root and want
- to find the XAUTHORITY before anyone has logged into an
- X session yet, use: x11vnc -env FD_XDM=1 -findauth ...
- (This will also find the XAUTHORITY if a user is already
- logged into the X session.) When running as root,
- FD_XDM=1 will be tried if the initial -findauth fails.
-
--create First try to find the user's display using FINDDISPLAY,
- if that doesn't succeed create an X session via the
- FINDCREATEDISPLAY method. This is an alias for
- "-display WAIT:cmd=FINDCREATEDISPLAY-Xvfb".
-
- Note: if a -display occurs later on the command line
- it will override the -create setting.
-
- SSH NOTE: for both -find and -create you can (should!)
- add the "-localhost" option to force SSH tunnel access.
-
--xdummy As in -create, except Xdummy instead of Xvfb.
--xvnc As in -create, except Xvnc instead of Xvfb.
--xvnc_redirect As in -create, except Xvnc.redirect instead of Xvfb.
--xdummy_xvfb Sets WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb
-
--create_xsrv str Sets WAIT:cmd=FINDCREATEDISPLAY-<str> Can be on cmdline
- after anything that sets WAIT:.. and other things
- (e.g. -svc, -xdmsvc) to adjust the X server list.
- Example: -svc ... -create_xsrv Xdummy,X
-
--svc Terminal services mode based on SSL access. Alias for
- -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb -unixpw -users
- unixpw= -ssl SAVE Also "-service".
-
- Note: if a -display, -unixpw, -users, or -ssl occurs
- later on the command line it will override the -svc
- setting.
-
--svc_xdummy As -svc except Xdummy instead of Xvfb.
--svc_xvnc As -svc except Xvnc instead of Xvfb.
--svc_xdummy_xvfb As -svc with Xdummy,Xvfb.
-
--xdmsvc Display manager Terminal services mode based on SSL.
- Alias for -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp
- -unixpw -users unixpw= -ssl SAVE Also "-xdm_service".
-
- Note: if a -display, -unixpw, -users, or -ssl occurs
- later on the command line it will override the -xdmsvc
- setting.
-
- To create a session a user will have to first log in
- to the -unixpw dialog and then log in again to the
- XDM/GDM/KDM prompt. Subsequent re-connections will
- only require the -unixpw password. See the discussion
- under -display WAIT:... for more details about XDM,
- etc configuration.
-
- Remember to enable XDMCP in the xdm-config, gdm.conf,
- or kdmrc configuration file. See -display WAIT: for
- more info.
-
--sshxdmsvc Display manager Terminal services mode based on SSH.
- Alias for -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp
- -localhost.
-
- The -localhost option constrains connections to come
- in via a SSH tunnel (which will require a login).
- To create a session a user will also have to log into
- the XDM GDM KDM prompt. Subsequent re-connections will
- only only require the SSH login. See the discussion
- under -display WAIT:... for more details about XDM,
- etc configuration.
-
- Remember to enable XDMCP in the xdm-config, gdm.conf,
- or kdmrc configuration file. See -display WAIT: for
- more info.
-
--unixpw_system_greeter Present a "Press 'Escape' for System Greeter" option
- to the connecting VNC client in combined -unixpw
- and xdmcp FINDCREATEDISPLAY modes (e.g. -xdmsvc).
-
- Normally in a -unixpw mode the VNC client must
- supply a valid username and password to gain access.
- However, if -unixpw_system_greeter is supplied AND
- the FINDCREATEDISPLAY command matches 'xdmcp', then
- the user has the option to press Escape and then get a
- XDM/GDM/KDM login/greeter panel instead. They will then
- supply a username and password directly to the greeter.
-
- Otherwise, in xdmcp FINDCREATEDISPLAY mode the user
- must supply his username and password TWICE. First to
- the initial unixpw login dialog, and second to the
- subsequent XDM/GDM/KDM greeter. Note that if the user
- re-connects and supplies his username and password in
- the unixpw dialog the xdmcp greeter is skipped and
- he is connected directly to his existing X session.
- So the -unixpw_system_greeter option avoids the extra
- password at X session creation time.
-
- Example: x11vnc -xdmsvc -unixpw_system_greeter
- See -unixpw and -display WAIT:... for more info.
-
- The special options after a colon at the end of the
- username (e.g. user:solid) described under -display
- WAIT: are also applied in this mode if they are typed
- in before the user hits Escape. The username is ignored
- but the colon options are not.
-
- The default message is 2 lines in a small font, set
- the env. var. X11VNC_SYSTEM_GREETER1=true for a 1 line
- message in a larger font.
-
- If the user pressed Escape the FINDCREATEDISPLAY command
- will be run with the env. var. X11VNC_XDM_ONLY=1.
-
- Remember to enable XDMCP in the xdm-config, gdm.conf,
- or kdmrc configuration file. See -display WAIT: for
- more info.
-
--redirect port As in FINDCREATEDISPLAY-Xvnc.redirect mode except
- redirect immediately (i.e. without X session finding
- or creation) to a VNC server listening on port. You
- can also supply host:port to redirect to a different
- machine.
-
- If 0 <= port < 200 it is taken as a VNC display (5900 is
- added to get the actual port), if port < 0 then -port
- is used.
-
- Probably the only reason to use the -redirect option
- is in conjunction with SSL support, e.g. -ssl SAVE.
- This provides an easy way to add SSL encryption to a VNC
- server that does not support SSL (e.g. Xvnc or vnc.so)
- In fact, the protocol does not even need to be VNC,
- and so "-rfbport port1 -ssl SAVE -redirect host:port2"
- can act as a replacement for stunnel(1).
-
- This mode only allows one redirected connection.
- The -forever option does not apply. Use -inetd or
- -loop for persistent service.
-
--display_WAIT :... A special usage mode for the normal -display option.
- Useful with -unixpw, but can be used independently
- of it. If the display string begins with WAIT: then
- x11vnc waits until a VNC client connects before opening
- the X display (or -rawfb device).
-
- This could be useful for delaying opening the display
- for certain usage modes (say if x11vnc is started at
- boot time and no X server is running or users logged
- in yet).
-
- If the string is, e.g. WAIT:0.0 or WAIT:1, i.e. "WAIT"
- in front of a normal X display, then that indicated
- display is used.
-
- One can also insert a geometry between colons, e.g.
- WAIT:1280x1024:... to set the size of the display the
- VNC client first attaches to since some VNC viewers
- will not automatically adjust to a new framebuffer size.
-
- A more interesting case is like this:
-
- WAIT:cmd=/usr/local/bin/find_display
-
- in which case the command after "cmd=" is run to
- dynamically work out the DISPLAY and optionally the
- XAUTHORITY data. The first line of the command output
- must be of the form DISPLAY=<xdisplay>. On Linux
- if the virtual terminal is known append ",VT=n" to
- this string and the chvt(1) program will also be run.
- Any remaining output is taken as XAUTHORITY data.
- It can be either of the form XAUTHORITY=<file> or raw
- xauthority data for the display. For example;
-
- xauth extract - $DISPLAY"
-
- NOTE: As specified in the previous paragraph, you can
- supply your own WAIT:cmd=... program or script, BUT
- there are two very useful *BUILT-IN* ones: FINDDISPLAY
- (alias -find above) and FINDCREATEDISPLAY (alias -create
- above.) Most people use these instead of creating
- their own script. Read the following (especially the
- BUILT-IN modes sections) to see how to configure these
- two useful builtin -display WAIT: modes.
-
- In the case of -unixpw (and -unixpw_nis only if x11vnc
- is running as root), then the cmd= command is run
- as the user who just authenticated via the login and
- password prompt.
-
- In the case of -unixpw_cmd, the commands will also be
- run as the logged-in user, as long as the user-supplied
- helper program supports RFB_UNIXPW_CMD_RUN (see the
- -unixpw_cmd option.)
-
- Also in the case of -unixpw, the user logging in can
- place a colon at the end of her username and supply
- a few options: scale=, scale_cursor= (or sc=), solid
- (or so), id=, clear_mods (or cm), clear_keys (or
- ck), clear_all (or ca), repeat, speeds= (or sp=),
- readtimeout= (or rd=), viewonly (or vo), nodisplay=
- (or nd=), rotate= (or ro=), or noncache (or nc),
- all separated by commas if there is more than one.
- After the user logs in successfully, these options will
- be applied to the VNC screen. For example,
-
- login: fred:scale=3/4,sc=1,repeat
- Password: ...
-
- login: runge:sp=modem,rd=120,solid
-
- for convenience m/n implies scale= e.g. fred:3/4 If you
- type and enter your password incorrectly, to retrieve
- your long "login:" line press the Up arrow once
- (before typing anything else).
-
- Most of these colon options only apply to the builtin
- FINDDISPLAY and FINDCREATEDISPLAY modes, but note
- that they are passed to the extrenal command in the
- environment as well and so could be used.
-
- In the login panel, press F1 to get a list of the
- available options that you can add after the username.
-
- Another option is "geom=WxH" or "geom=WxHxD" (or
- ge=). This only has an effect in FINDCREATEDISPLAY
- mode when a virtual X server such as Xvfb is going
- to be created. It sets the width and height of
- the new display, and optionally the color depth as
- well.
-
- You can also supply "gnome", "kde", "twm",
- "fvwm", "mwm", "dtwm", "wmaker", "xfce",
- "lxde", "enlightenment", "Xsession", or
- "failsafe" (same as "xterm") to have the created
- display use that mode for the user session.
-
- Specify "tag=..." to set the unique FD_TAG desktop
- session tag described below. Note: this option will
- be ignored if the FD_TAG env. var. is already set or
- if the viewer-side supplied value is not completely
- composed of alphanumeric or '_' or '-' characters.
-
- User preferences file: Instead of having the user type
- in geom=WxH,... etc. every time he logs in to find
- or create his X session, if you set FD_USERPREFS to
- a string that does not contain the "/" character,
- then the user's home directory is prepended to that
- string and if the file exists its first line is read
- and appended to any options he supplied at the login:
- prompt. For example -env FD_USERPREFS=.x11vnc_create
- and the user put "geom=1600x1200" in his
- ~/.x11vnc_create file.
-
- To disable the option setting set the environment
- variable X11VNC_NO_UNIXPW_OPTS=1 before starting x11vnc.
- To set any other options, the user can use the gui
- (x11vnc -gui connect) or the remote control method
- (x11vnc -R opt:val) during his VNC session.
-
- So we see the combination of -display WAIT:cmd=... and
- -unixpw allows automatic pairing of an unix
- authenticated VNC user with his desktop. This could
- be very useful on SunRays and also any system where
- multiple users share a given machine. The user does
- not need to remember special ports or passwords set up
- for his desktop and VNC.
-
- A nice way to use WAIT:cmd=... is out of inetd(8)
- (it automatically forks a new x11vnc for each user).
- You can have the x11vnc inetd spawned process run as,
- say, root or nobody. When run as root (for either inetd
- or display manager), you can also supply the option
- "-users unixpw=" to have the x11vnc process switch to
- the user as well. Note: there will be a 2nd SSL helper
- process that will not switch, but it is only encoding
- and decoding the encrypted stream at that point.
-
- BUILT-IN modes:
-
- -- Automatic Finding of User X Sessions --
-
- As a special case, WAIT:cmd=FINDDISPLAY will run a
- script that works on most Unixes to determine a user's
- DISPLAY variable and xauthority data (see who(1)).
-
- NOTE: The option "-find" is an alias for this mode.
-
- To have this default script printed to stdout (e.g. for
- customization) run with WAIT:cmd=FINDDISPLAY-print To
- have the script run to print what display it would find
- use "-finddpy" or WAIT:cmd=FINDDISPLAY-run
-
- The standard script runs xdpyinfo(1) run on potential
- displays. If your X server(s) have a login greeter
- that exclusively grabs the Xserver, then xdpyinfo
- blocks forever and this mode will not work. See
- www.karlrunge.com/x11vnc/faq.html#faq-display-manager
- for how to disable this for dtgreet on Solaris and
- possibly for other greeters.
-
- In -find/cmd=FINDDISPLAY mode, if you set FD_XDM=1,
- e.g. 'x11vnc -env FD_XDM=1 -find ...' and x11vnc is
- running as root (e.g. inetd) then it will try to find
- the XAUTHORITY file of a running XDM/GDM/KDM login
- greeter (i.e. no user has logged into an X session yet.)
-
- As another special case, WAIT:cmd=HTTPONCE will allow
- x11vnc to service one http request and then exit.
- This is usually done in -inetd mode to run on, say,
- port 5800 and allow the Java vncviewer to be downloaded
- by client web browsers. For example:
-
- 5815 stream tcp nowait root /usr/sbin/tcpd /.../x11vnc
-\
- -inetd -q -http_ssl -prog /.../x11vnc \
- -display WAIT:cmd=HTTPONCE
-
- Where /.../x11vnc is the full path to x11vnc.
- It is used in the Apache SSL-portal example (see FAQ).
-
- In this mode you can set X11VNC_SKIP_DISPLAY to a
- comma separated list of displays (e.g. ":0,:1") to
- ignore in the finding process. The ":" is optional.
- Ranges n-m e.g. 0-20 can also be supplied. This string
- can also be set by the connecting user via "nd="
- using "+" instead of "," If "nd=all" or you set
- X11VNC_SKIP_DISPLAY=all then all display finding fails
- as if you set X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 (below.)
-
- On some systems lsof(1) can be very slow. Set the
- env. var. FIND_DISPLAY_NO_LSOF=1 to skip using lsof to
- try to find the Linux VT the X server is running on.
- set FIND_DISPLAY_NO_VT_FIND=1 to avoid looking at all.
-
- -- Automatic Creation of User X Sessions --
-
- An interesting option is WAIT:cmd=FINDCREATEDISPLAY
- that is like FINDDISPLAY in that is uses the same method
- to find an existing display. However, if it does not
- find one it will try to *start* up an X server session
- for the user. This is the only time x11vnc tries to
- actually start up an X server.
-
- NOTE: The option "-create" is an alias for this mode.
-
- It will start looking for an open display number at :20
- Override via X11VNC_CREATE_STARTING_DISPLAY_NUMBER=n
- By default 80 X displays are allowed (i.e. going to :99)
- Override via X11VNC_CREATE_MAX_DISPLAYS=n
-
- For its heuristics, the create display script sets
- LC_ALL=C so that command output is uniform. By default
- it will try to restore LC_ALL right before starting the
- user session. However, if you don't mind it keeping
- LC_ALL=C set the env. var.: X11VNC_CREATE_LC_ALL_C_OK=1
-
- By default FINDCREATEDISPLAY will try Xvfb and then
- Xdummy:
-
- The Xdummy wrapper is part of the x11vnc source code
- (x11vnc/misc/Xdummy) It should be available in PATH
- and have run "Xdummy -install" once to create the
- shared library. Xdummy only works on Linux. As of
- 12/2009 it no longer needs to be run as root, and the
- default is to not run as root. In some circumstances
- permissions may require running it as root, in these
- cases specify FD_XDUMMY_RUN_AS_ROOT=1, this is the same
- as supplying -root to the Xdummy cmdline.
-
- Xvfb is available on most platforms and does not
- require root.
-
- An advantage of Xdummy over Xvfb is that Xdummy supports
- RANDR dynamic screen resizing.
-
- When x11vnc exits (i.e. user disconnects) the X
- server session stays running in the background.
- The FINDDISPLAY will find it directly next time.
- The user must exit the X session in the usual way for
- it to terminate (or kill the X server process if all
- else fails).
-
- To troubleshoot the FINDCREATEDISPLAY mechanism,
- set the following env. var. to an output log file,
- e.g -env CREATE_DISPLAY_OUTPUT=/tmp/mydebug.txt
-
- So this is a somewhat odd mode for x11vnc in that it
- will start up and poll virtual X servers! This can
- be used from, say, inetd(8) to provide a means of
- definitely getting a desktop (either real or virtual)
- on the machine. E.g. a desktop service:
-
- 5900 stream tcp nowait root /usr/sbin/tcpd /.../x11vnc
- -inetd -q -http -ssl SAVE -unixpw -users unixpw=\
- -passwd secret -prog /.../x11vnc \
- -display WAIT:cmd=FINDCREATEDISPLAY
-
- Where /.../x11vnc is the full path to x11vnc.
-
- See the -svc/-service option alias above.
-
- If for some reason you do not want x11vnc to ever
- try to find an existing display set the env. var
- X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 (also -env ...)
- This is the same as setting X11VNC_SKIP_DISPLAY=all or
- supplying "nd=all" after "username:"
-
- Use WAIT:cmd=FINDCREATEDISPLAY-print to print out the
- script that is used for this.
-
- You can specify the preferred X server order via e.g.,
- WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb,X and/or leave
- out ones you do not want. The the case "X" means try
- to start up a real, hardware X server using xinit(1)
- or startx(1). If there is already an X server running
- the X case may only work on Linux (see startx(1)).
-
- "Xvnc" will start up a VNC X server (real-
- or tight-vnc, e.g. use if Xvfb is not available).
- "Xsrv" will start up the server program in the
- variable "FD_XSRV" if it is non-empty. You can make
- this be a wrapper script if you like (it must handle :N,
- -geometry, and -depth and other X server options).
-
- You can set the environment variable FD_GEOM (or
- X11VNC_CREATE_GEOM) to WxH or WxHxD to set the width
- and height and optionally the color depth of the
- created display. You can also set FD_SESS to be the
- session (short name of the windowmanager: kde, gnome,
- twm, failsafe, etc.). FD_OPTS contains extra options
- to pass to the X server. You can also set FD_PROG to
- be the full path to the session/windowmanager program.
-
- More FD tricks: FD_CUPS=port or FD_CUPS=host:port
- will set the cups printing environment. Similarly for
- FD_ESD=port or FD_ESD=host:port for esddsp sound
- redirection. Set FD_EXTRA to a command to be run a
- few seconds after the X server starts up. Set FD_TAG
- to be a unique name for the session, it is set as an
- X property, that makes FINDDISPLAY only find sessions
- with that tag value.
-
- Set FD_XDMCP_IF to the network interface that the
- display manager is running on; default is 'localhost'
- but you may need to set it to '::1' on some IPv6 only
- systems or misconfigured display managers.
-
- If you want the FINDCREATEDISPLAY session to contact an
- XDMCP login manager (xdm/gdm/kdm) on the same machine,
- then use "Xvfb.xdmcp" instead of "Xvfb", etc.
- The user will have to supply his username and password
- one more time (but he gets to select his desktop type
- so that can be useful). For this to work, you will
- need to enable localhost XDMCP (udp port 177) for the
- display manager. This seems to be:
-
- for gdm in gdm.conf: Enable=true in section [xdmcp]
- for kdm in kdmrc: Enable=true in section [Xdmcp]
- for xdm in xdm-config: DisplayManager.requestPort: 177
-
- See the shorthand options above "-svc", "-xdmsvc"
- and "-sshxdmsvc" that specify the above options for
- some useful cases.
-
- If you set the env. var WAITBG=1 x11vnc will go into
- the background once listening in wait mode.
-
- Another special mode is FINDCREATEDISPLAY-Xvnc.redirect,
- (or FINDDISPLAY-Xvnc.redirect). In this case it will
- start up Xvnc as above if needed, but instead of
- polling it in its normal way, it simply does a socket
- redirection of the connected VNC viewer to the Xvnc.
-
- So in Xvnc.redirect x11vnc does no VNC but merely
- transfers the data back and forth. This should be
- faster then x11vnc's polling method, but not as fast
- as connecting directly to the Xvnc with the VNC Viewer.
- The idea here is to take advantage of x11vnc's display
- finding/creating scheme, SSL, and perhaps a few others.
- Most of x11vnc's options do not apply in this mode.
-
- Xvnc.redirect should also work for the vnc.so X server
- module for the h/w display however it will work only
- for finding the display and the user must already be
- logged into the X console.
-
--vencrypt mode The VeNCrypt extension to the VNC protocol allows
- encrypted SSL/TLS connections. If the -ssl mode is
- enabled, then VeNCrypt is enabled as well BY DEFAULT
- (they both use a SSL/TLS tunnel, only the protocol
- handshake is a little different.)
-
- To control when and how VeNCrypt is used, specify the
- mode string. If mode is "never", then VeNCrypt is
- not used. If mode is "support" (the default) then
- VeNCrypt is supported. If mode is "only", then the
- similar and older ANONTLS protocol is not simultaneously
- supported. x11vnc's normal SSL mode (vncs://) will be
- supported under -ssl unless you set mode to "force".
-
- If mode is prefixed with "nodh:", then Diffie Hellman
- anonymous key exchange is disabled. If mode is prefixed
- with "nox509:", then X509 key exchange is disabled.
-
- To disable all Anonymous Diffie-Hellman access
- (susceptible to Man-In-The-Middle attack) you will need
- to supply "-vencrypt nodh:support -anontls never"
- or "-vencrypt nodh:only"
-
- If mode is prefixed with "newdh:", then new Diffie
- Hellman parameters are generated for each connection
- (this can be time consuming: 1-60 secs; see -dhparams
- below for a faster way) rather than using the
- fixed values in the program. Using fixed, publicly
- known values is not known to be a security problem.
- This setting applies to ANONTLS as well.
-
- Long example: -vencrypt newdh:nox509:support
-
- Also, if mode is prefixed with "plain:", then
- if -unixpw mode is active the VeNCrypt "*Plain"
- username+passwd method is enabled for Unix logins.
- Otherwise in -unixpw mode the normal login panel is
- provided.
-
- You *MUST* supply the -ssl option for VeNCrypt to
- be active. The -vencrypt option only fine-tunes its
- operation.
-
--anontls mode The ANONTLS extension to the VNC protocol allows
- encrypted SSL/TLS connections. If the -ssl mode is
- enabled, then ANONTLS is enabled as well BY DEFAULT
- (they both use a SSL/TLS tunnel, only the protocol
- handshake is a little different.)
-
- ANONTLS is an older SSL/TLS mode introduced by vino.
-
- It is referred to as 'TLS' for its registered VNC
- security-type name, but we use the more descriptive
- 'ANONTLS' here because it provides only Anonymous
- Diffie-Hellman encrypted connections, and hence no
- possibility for certificate authentication.
-
- To control when and how ANONTLS is used, specify the
- mode string. If mode is "never", then ANONTLS is not
- used. If mode is "support" (the default) then ANONTLS
- is supported. If mode is "only", then the similar
- VeNCrypt protocol is not simultaneously supported.
- x11vnc's normal SSL mode (vncs://) will be supported
- under -ssl unless you set mode to "force".
-
- If mode is prefixed with "newdh:", then new Diffie
- Hellman parameters are generated for each connection
- (this can be time consuming: 1-60 secs; see -dhparams
- below for a faster way) rather than using the
- fixed values in the program. Using fixed, publicly
- known values is not known to be a security problem.
- This setting applies to VeNCrypt as well. See the
- description of "plain:" under -vencrypt.
-
- Long example: -anontls newdh:plain:support
-
- You *MUST* supply the -ssl option for ANONTLS to
- be active. The -anontls option only fine-tunes its
- operation.
-
--sslonly Same as: "-vencrypt never -anontls never" i.e. it
- disables the VeNCrypt and ANONTLS encryption methods
- and only allows standard SSL tunneling. You must also
- supply the -ssl ... option (see below.)
-
-
--dhparams file For some operations a set of Diffie Hellman parameters
- (prime and generator) is needed. If so, use the
- parameters in "file". In particular, the VeNCrypt and
- ANONTLS anonymous DH mode need them. By default a
- fixed set is used. If you do not want to do that you
- can specify "newdh:" to the -vencrypt and -anontls
- options to generate a new set each session. If that
- is too slow for you, use -dhparams file to a set you
- created manually via "openssl dhparam -out file 1024"
-
--nossl Disable the -ssl option (see below). Since -ssl is off
- by default -nossl would only be used on the commandline
- to unset any *earlier* -ssl option (or -svc...)
-
--ssl [pem] Use the openssl library (www.openssl.org) to provide a
- built-in encrypted SSL/TLS tunnel between VNC viewers
- and x11vnc. This requires libssl support to be
- compiled into x11vnc at build time. If x11vnc is not
- built with libssl support it will exit immediately when
- -ssl is prescribed. See the -stunnel option below for
- an alternative.
-
- The VNC Viewer-side needs to support SSL/TLS as well.
- See this URL and also the discussion below for
- ideas on how to enable SSL support for the viewer:
- http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tun
- nel-viewers . x11vnc provides an SSL enabled Java
- viewer applet in the classes/ssl directory (-http or
- -httpdir options.) The SSVNC viewer package supports
- SSL tunnels too.
-
- If the VNC Viewer supports VeNCrypt or ANONTLS (vino's
- encryption mode) they are also supported by the -ssl
- mode (see the -vencrypt and -anontls options for more
- info; use -sslonly to disable both of them.)
-
- Use "-ssl /path/to/mycert.pem" to specify an SSL
- certificate file in PEM format to use to identify and
- provide a key for this server. See openssl(1) for more
- info about PEMs and the -sslGenCert and "-ssl SAVE"
- options below for how to create them.
-
- The connecting VNC viewer SSL tunnel can (at its option)
- authenticate this server if it has the public key part
- of the certificate (or a common certificate authority,
- CA, is a more sophisticated way to verify this server's
- cert, see -sslGenCA below). This authentication is
- done to prevent Man-In-The-Middle attacks. Otherwise,
- if the VNC viewer simply accepts this server's key
- WITHOUT verification, the traffic is protected from
- passive sniffing on the network, but *NOT* from
- Man-In-The-Middle attacks. There are hacker tools
- like dsniff/webmitm and cain that implement SSL
- Man-In-The-Middle attacks.
-
- If [pem] is empty or the string "SAVE" then the
- openssl(1) command must be available to generate the
- certificate the first time. A self-signed certificate
- is generated (see -sslGenCA and -sslGenCert for use
- of a Certificate Authority.) It will be saved to the
- file ~/.vnc/certs/server.pem. On subsequent calls if
- that file already exists it will be used directly.
-
- Use "SAVE_NOPROMPT" to avoid being prompted to
- protect the generated key with a passphrase. However in
- -inetd and -bg modes there will be no prompting for a
- passphrase in either case.
-
- If [pem] is "SAVE_PROMPT" the server.pem certificate
- will be created based on your answers to its prompts for
- all info such as OrganizationalName, CommonName, etc.
-
- Use "SAVE-<string>" and "SAVE_PROMPT-<string>"
- to refer to the file ~/.vnc/certs/server-<string>.pem
- instead (it will be generated if it does not already
- exist). E.g. "SAVE-charlie" will store to the file
- ~/.vnc/certs/server-charlie.pem
-
- Examples: x11vnc -ssl SAVE -display :0 ...
- x11vnc -ssl SAVE-someother -display :0 ...
-
- If [pem] is "TMP" and the openssl(1) utility
- command exists in PATH, then a temporary, self-signed
- certificate will be generated for this session. If
- openssl(1) cannot be used to generate a temporary
- certificate x11vnc exits immediately. The temporary
- cert will be discarded when x11vnc exits.
-
- If successful in using openssl(1) to generate a
- temporary certificate in "SAVE" or "TMP" creation
- modes, the public part of it will be displayed to stderr
- (e.g. one could copy it to the client-side to provide
- authentication of the server to VNC viewers.)
-
- NOTE: In "TMP" mode, unless you safely copy the
- public part of the temporary Cert to the viewer for
- authenticate *every time* (unlikely...), then only
- passive sniffing attacks are prevented and you are
- still open to Man-In-The-Middle attacks. This is
- why the default "SAVE" mode is preferred (and more
- sophisticated CA mode too). Only with saved keys AND
- the VNC viewer authenticating them (via the public
- certificate), are Man-In-The-Middle attacks prevented.
-
- If [pem] is "ANON" then the Diffie-Hellman anonymous
- key exchange method is used. In this mode there
- are *no* SSL certificates and so it is not possible
- to authenticate either the VNC server or VNC client.
- Thus only passive network sniffing attacks are avoided:
- the "ANON" method is susceptible to Man-In-The-Middle
- attacks. "ANON" is not recommended; instead use
- a SSL PEM you created or the default "SAVE" method.
-
- See -ssldir below to use a directory besides the
- default ~/.vnc/certs
-
- If your x11vnc binary was not compiled with OpenSSL
- library support, use of the -ssl option will induce an
- immediate failure and exit. For such binaries, consider
- using the -stunnel option for SSL encrypted connections.
-
- Misc Info: In temporary cert creation mode "TMP", set
- the env. var. X11VNC_SHOW_TMP_PEM=1 to have x11vnc print
- out the entire certificate, including the PRIVATE KEY
- part, to stderr. There are better ways to get/save this
- info. See "SAVE" above and "-sslGenCert" below.
-
--ssltimeout n Set SSL read timeout to n seconds. In some situations
- (i.e. an iconified viewer in Windows) the viewer stops
- talking and the connection is dropped after the default
- timeout (25s for about the first minute, 43200s later).
- Set to zero to poll forever. Set to a negative value
- to use the builtin setting.
-
- Note that this value does NOT apply to the *initial* ssl
- init connection. The default timeout for that is 20sec.
- Use -env SSL_INIT_TIMEOUT=n to modify it.
-
--sslnofail Exit at the first SSL connection failure. Useful when
- scripting SSL connections (e.g. x11vnc is started via
- ssh) and you do not want x11vnc waiting around for more
- connections, tying up ports, etc.
-
--ssldir dir Use "dir" as an alternate ssl certificate and key
- management toplevel directory. The default is
- ~/.vnc/certs
-
- This directory is used to store server and other
- certificates and keys and also other materials. E.g. in
- the simplest case, "-ssl SAVE" will store the x11vnc
- server cert in dir/server.pem
-
- Use of alternate directories via -ssldir allows you to
- manage multiple VNC Certificate Authority (CA) keys.
- Another use is if ~/.vnc/cert is on an NFS share you
- might want your certificates and keys to be on a local
- filesystem to prevent network snooping (for example
- -ssldir /var/lib/x11vnc-certs).
-
- -ssldir affects nearly all of the other -ssl* options,
- e.g. -ssl SAVE, -sslGenCert, etc..
-
--sslverify path For either of the -ssl or -stunnel modes, use "path"
- to provide certificates to authenticate incoming VNC
- *Client* connections (normally only the server is
- authenticated in SSL.) This can be used as a method
- to replace standard password authentication of clients.
-
- If "path" is a directory it contains the client (or CA)
- certificates in separate files. If path is a file,
- it contains one or more certificates. See special tokens
- below. These correspond to the "CApath = dir" and
- "CAfile = file" stunnel options. See the stunnel(8)
- manpage for details.
-
- Examples:
- x11vnc -ssl -sslverify ~/my.crt
- x11vnc -ssl -sslverify ~/my_pem_dir/
-
- Note that if path is a directory, it must contain
- the certs in separate files named like <HASH>.0, where
- the value of <HASH> is found by running the command
- "openssl x509 -hash -noout -in file.crt". Evidently
- one uses <HASH>.1 if there is a collision...
-
- The the key-management utility "-sslCertInfo HASHON"
- and "-sslCertInfo HASHOFF" will create/delete these
- hashes for you automatically (via symlink) in the HASH
- subdirs it manages. Then you can point -sslverify to
- the HASH subdir.
-
- Special tokens: in -ssl mode, if "path" is not a file or
- a directory, it is taken as a comma separated list of
- tokens that are interpreted as follows:
-
- If a token is "CA" that means load the CA/cacert.pem
- file from the ssl directory. If a token is "clients"
- then all the files clients/*.crt in the ssl directory
- are loaded. Otherwise the file clients/token.crt
- is attempted to be loaded. As a kludge, use a token
- like ../server-foo to load a server cert if you find
- that necessary.
-
- Use -ssldir to use a directory different from the
- ~/.vnc/certs default.
-
- Note that if the "CA" cert is loaded you do not need
- to load any of the certs that have been signed by it.
- You will need to load any additional self-signed certs
- however.
-
- Examples:
- x11vnc -ssl -sslverify CA
- x11vnc -ssl -sslverify self:fred,self:jim
- x11vnc -ssl -sslverify CA,clients
-
- Usually "-sslverify CA" is the most effective.
- See the -sslGenCA and -sslGenCert options below for
- how to set up and manage the CA framework.
-
-
-
- NOTE: the following utilities, -sslGenCA, -sslGenCert,
- -sslEncKey, -sslCertInfo, and -sslCRL are provided for
- completeness, but for casual usage they are overkill.
-
- They provide VNC Certificate Authority (CA) key creation
- and server / client key generation and signing. So they
- provide a basic Public Key management framework for
- VNC-ing with x11vnc. (note that they require openssl(1)
- be installed on the system)
-
- However, the simplest usage mode, "-ssl TMP" (where
- x11vnc automatically generates its own, self-signed,
- temporary key and the VNC viewers always accept it,
- e.g. accepting via a dialog box) is probably safe enough
- for most scenarios. CA management is not needed.
-
- To protect against Man-In-The-Middle attacks the "TMP"
- mode can be improved by using "-ssl SAVE" (same as
- "-ssl", i.e. the default) to have x11vnc create a
- longer term self-signed certificate, and then (safely)
- copy the corresponding public key cert to the desired
- client machines (care must be taken the private key part
- is not stolen; you will be prompted for a passphrase).
-
- So keep in mind no CA key creation or management
- (-sslGenCA and -sslGenCert) is needed for either of
- the above two common usage modes.
-
- One might want to use -sslGenCA and -sslGenCert
- if you had a large number of VNC client and server
- workstations. That way the administrator could generate
- a single CA key with -sslGenCA and distribute its
- certificate part to all of the workstations.
-
- Next, he could create signed VNC server keys
- (-sslGenCert server ...) for each workstation or user
- that then x11vnc would use to authenticate itself to
- any VNC client that has the CA cert.
-
- Optionally, the admin could also make it so the
- VNC clients themselves are authenticated to x11vnc
- (-sslGenCert client ...) For this -sslverify would be
- pointed to the CA cert (and/or self-signed certs).
-
- x11vnc will be able to use all of these cert and
- key files. On the VNC client side, they will need to
- be "imported" somehow. Web browsers have "Manage
- Certificates" actions as does the Java applet plugin
- Control Panel. stunnel can also use these files (see
- the ss_vncviewer example script in the FAQ and SSVNC.)
-
--sslCRL path Set the Certificate Revocation Lists (CRL) to "path".
- This setting applies for both -ssl and -stunnel modes.
-
- If path is a file, the file contains one or more CRLs
- in PEM format. If path is a directory, it contains
- hash named files of CRLs in the usual OpenSSL manner.
- See the OpenSSL and stunnel(8) documentation for
- more info.
-
- This option only applies if -sslverify has been
- supplied: it checks for revocation along the
- certificate chain used to verify the VNC client.
- The -sslCRL setting will be ignored when -sslverify is
- not specified.
-
- Note that if a CRL's expiration date has passed, all
- SSL connections will fail regardless of if they are
- related to the subject of the CRL or not.
-
- Only rarely will one's x11vnc -ssl infrastructure be so
- large that this option would be useful (since normally
- maintaining the contents of the -sslverify file or
- directory should be enough.) However, when using
- x11vnc with a Certificate Authority (see -sslGenCA)
- to authenticate Clients via SSL/TLS, the -sslCRL option
- can be useful to revoke users' certs whose private SSL
- keys were lost or stolen (e.g. laptop.) This way a new
- CA cert+key does not need to be created and new signed
- client keys generated and distributed to all users.
-
- To create a CRL file with revoked certificates the
- commands 'openssl ca -revoke ...' and 'openssl ca
- -gencrl ...' are useful. (Run them in ~/.vnc/certs)
-
--sslGenCA [dir] Generate your own Certificate Authority private key,
- certificate, and other files in directory [dir].
- x11vnc then exits.
-
- If [dir] is not supplied, a -ssldir setting is used,
- or otherwise ~/.vnc/certs is used.
-
- This command also creates directories where server and
- client certs and keys will be stored. The openssl(1)
- program must be installed on the system and available
- in PATH.
-
- After the CA files and directories are created the
- x11vnc command exits; the VNC server is not run.
-
- You will be prompted for information to put into the CA
- certificate. The info does not have to be accurate just
- as long as clients accept the cert for VNC connections.
- You will also need to supply a passphrase of at least
- 4 characters for the CA private key.
-
- Once you have generated the CA you can distribute
- its certificate part, [dir]/CA/cacert.pem, to other
- workstations where VNC viewers will be run. One will
- need to "import" this certificate in the applications,
- e.g. Web browser, Java applet plugin, stunnel, etc.
- Next, you can create and sign keys using the CA with
- the -sslGenCert option below.
-
- Examples:
- x11vnc -sslGenCA
- x11vnc -sslGenCA ~/myCAdir
- x11vnc -ssldir ~/myCAdir -sslGenCA
-
- (the last two lines are equivalent)
-
--sslGenCert type name Generate a VNC server or client certificate and private
- key pair signed by the CA created previously with
- -sslGenCA. The openssl(1) program must be installed
- on the system and available in PATH.
-
- After the Certificate is generated x11vnc exits; the
- VNC server is not run.
-
- The type of key to be generated is the string "type".
- It is either "server" (i.e. for use by x11vnc) or
- "client" (for a VNC viewer). Note that typically
- only "server" is used: the VNC clients authenticate
- themselves by a non-public-key method (e.g. VNC or
- unix password). "type" is required.
-
- An arbitrary default name you want to associate with
- the key is supplied by the "name" string. You can
- change it at the various prompts when creating the key.
- "name" is optional.
-
- If name is left blank for clients keys then "nobody"
- is used. If left blank for server keys, then the
- primary server key: "server.pem" is created (this
- is the saved one referenced by "-ssl SAVE" when the
- server is started)
-
- If "name" begins with the string "self:" then
- a self-signed certificate is created instead of one
- signed by your CA key.
-
- If "name" begins with the string "req:" then only a
- key (.key) and a certificate signing *request* (.req)
- are generated. You can then send the .req file to
- an external CA (even a professional one, e.g. Thawte)
- and then combine the .key and the received cert into
- the .pem file with the same basename.
-
- The distinction between "server" and "client" is
- simply the choice of output filenames and sub-directory.
- This makes it so the -ssl SAVE-name option can easily
- pick up the x11vnc PEM file this option generates.
- And similarly makes it easy for the -sslverify option
- to pick up your client certs.
-
- There is nothing special about the filename or directory
- location of either the "server" and "client" certs.
- You can rename the files or move them to wherever
- you like.
-
- Precede this option with -ssldir [dir] to use a
- directory other than the default ~/.vnc/certs You will
- need to run -sslGenCA on that directory first before
- doing any -sslGenCert key creation.
-
- Note you cannot recreate a cert with exactly the same
- distiguished name (DN) as an existing one. To do so,
- you will need to edit the [dir]/CA/index.txt file to
- delete the line.
-
- Similar to -sslGenCA, you will be prompted to fill
- in some information that will be recorded in the
- certificate when it is created.
-
- Tip: if you know the fully-qualified hostname other
- people will be connecting to, you can use that as the
- CommonName "CN" to avoid some applications (e.g. web
- browsers and java plugin) complaining that it does not
- match the hostname.
-
- You will also need to supply the CA private key
- passphrase to unlock the private key created from
- -sslGenCA. This private key is used to sign the server
- or client certificate.
-
- The "server" certs can be used by x11vnc directly by
- pointing to them via the -ssl [pem] option. The default
- file will be ~/.vnc/certs/server.pem. This one would
- be used by simply typing -ssl SAVE. The pem file
- contains both the certificate and the private key.
- server.crt file contains the cert only.
-
- The "client" cert + private key file will need
- to be copied and imported into the VNC viewer
- side applications (Web browser, Java plugin,
- stunnel, etc.) Once that is done you can delete the
- "client" private key file on this machine since
- it is only needed on the VNC viewer side. The,
- e.g. ~/.vnc/certs/clients/<name>.pem contains both
- the cert and private key. The <name>.crt contains the
- certificate only.
-
- NOTE: It is very important to know one should
- generate new keys with a passphrase. Otherwise if an
- untrusted user steals the key file he could use it to
- masquerade as the x11vnc server (or VNC viewer client).
- You will be prompted whether to encrypt the key with
- a passphrase or not. It is recommended that you do.
- One inconvenience to a passphrase is that it must
- be typed in EVERY time x11vnc or the client app is
- started up.
-
- Examples:
-
- x11vnc -sslGenCert server
- x11vnc -ssl SAVE -display :0 ...
-
- and then on viewer using ss_vncviewer stunnel wrapper
- (see the FAQ):
- ss_vncviewer -verify ./cacert.crt hostname:0
-
- (this assumes the cacert.crt cert from -sslGenCA
- was safely copied to the VNC viewer machine where
- ss_vncviewer is run)
-
- Example using a name:
-
- x11vnc -sslGenCert server charlie
- x11vnc -ssl SAVE-charlie -display :0 ...
-
- Example for a client certificate (rarely used):
-
- x11vnc -sslGenCert client roger
- scp ~/.vnc/certs/clients/roger.pem somehost:.
- rm ~/.vnc/certs/clients/roger.pem
-
- x11vnc is then started with the option -sslverify
- ~/.vnc/certs/clients/roger.crt (or simply -sslverify
- roger), and on the viewer user on somehost could do
- for example:
-
- ss_vncviewer -mycert ./roger.pem hostname:0
-
- If you set the env. var REQ_ARGS='...' it will be
- passed to openssl req(1). A common use would be
- REQ_ARGS='-days 1095' to bump up the expiration date
- (3 years in this case).
-
--sslEncKey pem Utility to encrypt an existing PEM file with a
- passphrase you supply when prompted. For that key to be
- used (e.g. by x11vnc) the passphrase must be supplied
- each time.
-
- The "SAVE" notation described under -ssl applies as
- well. (precede this option with -ssldir [dir] to refer
- a directory besides the default ~/.vnc/certs)
-
- The openssl(1) program must be installed on the system
- and available in PATH. After the Key file is encrypted
- the x11vnc command exits; the VNC server is not run.
-
- Examples:
- x11vnc -sslEncKey /path/to/foo.pem
- x11vnc -sslEncKey SAVE
- x11vnc -sslEncKey SAVE-charlie
-
--sslCertInfo pem Prints out information about an existing PEM file.
- In addition the public certificate is also printed.
- The openssl(1) program must be in PATH. Basically the
- command "openssl x509 -text" is run on the pem.
-
- After the info is printed the x11vnc command exits;
- the VNC server is not run.
-
- The "SAVE" notation described under -ssl applies
- as well.
-
- Using "LIST" will give a list of all certs being
- managed (in the ~/.vnc/certs dir, use -ssldir to refer
- to another dir). "ALL" will print out the info for
- every managed key (this can be very long). Giving a
- client or server cert shortname will also try a lookup
- (e.g. -sslCertInfo charlie). Use "LISTL" or "LL"
- for a long (ls -l style) listing.
-
- Using "HASHON" will create subdirs [dir]/HASH and
- [dir]/HASH with OpenSSL hash filenames (e.g. 0d5fbbf1.0)
- symlinks pointing up to the corresponding *.crt file.
- ([dir] is ~/.vnc/certs or one given by -ssldir.)
- This is a useful way for other OpenSSL applications
- (e.g. stunnel) to access all of the certs without
- having to concatenate them. x11vnc will not use them
- unless you specifically reference them. "HASHOFF"
- removes these HASH subdirs.
-
- The LIST, LISTL, LL, ALL, HASHON, HASHOFF words can
- also be lowercase, e.g. "list".
-
--sslDelCert pem Prompts you to delete all .crt .pem .key .req files
- associated with [pem]. x11vnc then exits. "SAVE"
- and lookups as in -sslCertInfo apply as well.
-
--sslScripts Prints out both the 'genCA' and 'genCert' x11vnc
- openssl wrapper scripts for you to examine, modify, etc.
- The scripts are printed to stdout and then the x11vnc
- program exits.
-
-
--stunnel [pem] Use the stunnel(8) (stunnel.mirt.net) to provide an
- encrypted SSL tunnel between viewers and x11vnc.
-
- This external tunnel method was implemented prior to the
- integrated -ssl encryption described above. It still
- works well and avoids the requirement of linking with
- the OpenSSL libraries. This mode requires stunnel
- to be installed on the system and available via PATH
- (n.b. stunnel is often installed in sbin directories).
- Version 4.x of stunnel is assumed (but see -stunnel3
- below.)
-
- [pem] is optional, use "-stunnel /path/to/stunnel.pem"
- to specify a PEM certificate file to pass to stunnel.
- See the -ssl option for more info on certificate files.
-
- Whether or not your stunnel has its own certificate
- depends on your stunnel configuration; stunnel often
- generates one at install time. See your stunnel
- documentation for details. In any event, if you want to
- use this certificate you must supply the full path to it
- as [pem]. Note: the file may only be readable by root.
-
- [pem] may also be the special strings "TMP", "SAVE",
- and "SAVE..." as described in the -ssl option.
- If [pem] is not supplied, "SAVE" is assumed.
-
- Note that the VeNCrypt, ANONTLS, and "ANON" modes
- are not supported in -stunnel mode.
-
- stunnel is started up as a child process of x11vnc and
- any SSL connections stunnel receives are decrypted and
- sent to x11vnc over a local socket. The strings
- "The SSL VNC desktop is ..." and "SSLPORT=..."
- are printed out at startup to indicate this.
-
- The -localhost option is enforced by default to avoid
- people routing around the SSL channel. Use -env
- STUNNEL_DISABLE_LOCALHOST=1 to disable this security
- requirement.
-
- Set -env STUNNEL_DEBUG=1 for more debugging printout.
-
- Set -env STUNNEL_PROG=xxx to the full path of stunnel
- program you want to be used (e.g. /usr/bin/stunnel4).
-
- Set -env STUNNEL_LISTEN=xxx to the address of the
- network interface to listen on (the default is to listen
- on all interfaces), e.g. STUNNEL_LISTEN=192.168.1.100.
-
- A simple way to add IPv6 support is STUNNEL_LISTEN=::
-
- Your VNC viewer will also need to be able to connect
- via SSL. Unfortunately not too many do this. See the
- information about SSL viewers under the -ssl option.
- The x11vnc project's SSVNC is an option.
-
- Also, in the x11vnc distribution, patched TightVNC
- and UltraVNC Java applet jar files are provided in
- the classes/ssl directory that do SSL connections.
- Enable serving them with the -http, -http_ssl, or
- -httpdir (see the option descriptions for more info.)
-
- Note that for the Java viewer applet usage the
- "?PORT=xxxx" in the various URLs printed at startup
- will need to be supplied to the web browser to connect
- properly.
-
- Currently the automatic "single port" HTTPS mode of
- -ssl is not fully supported in -stunnel mode. However,
- it can be emulated via:
-
- % x11vnc -stunnel -http_ssl -http_oneport ...
-
- In general, it is also not too difficult to set up
- an stunnel or other SSL tunnel on the viewer side.
- A simple example on Unix using stunnel 3.x is:
-
- % stunnel -c -d localhost:5901 -r remotehost:5900
- % vncviewer localhost:1
-
- For Windows, stunnel has been ported to it and there
- are probably other such tools available. See the FAQ
- and SSVNC for more examples.
-
--stunnel3 [pem] Use version 3.x stunnel command line syntax instead of
- version 4.x. The -http/-httpdir Java applet serving
- is currently not available in this mode.
-
--enc cipher:keyfile Use symmetric encryption with cipher "cipher"
- and secret key data in "keyfile". If keyfile is
- pw=<string> then "string" is used as the key data.
-
- NOTE: It is recommended that you use SSL via the -ssl
- option instead of this option because SSL is well
- understood and takes great care to establish unique
- session keys and is more compatible with other software.
- Use this option if you do not want to deal with SSL
- certificates for authentication and do not want to
- use SSH but want some encryption for your VNC session.
- Or if you must interface with a symmetric key tunnel
- that you do not have control over.
-
- Note that this mode will NOT work with the UltraVNC DSM
- plugins because they alter the RFB protocol in addition
- to tunnelling with the symmetric cipher (an unfortunate
- choice of implementation...)
-
- cipher can be one of: arc4, aesv2, aes-cfb, blowfish,
- aes256, or 3des. See the OpenSSL documentation for
- more info. The keysize is 128 bits (except for aes256).
- Here is one way to make a keyfile with that many bits:
-
- dd if=/dev/random of=./my.key bs=16 count=1
-
- you will need to securely share this key with the other
- side of the VNC connection (See SSVNC for examples).
-
- Example: -enc blowfish:./my.key
- Example: -enc blowfish:pw=swordfish
-
- By default 16 bytes of random salt followed by 16 bytes
- of random initialization vector are sent at the very
- beginning of the stream. The other side must read these
- and initialize their cipher with them. These values
- make the session key unique (without them the security
- is minimal). Similarly, the other side must send us
- its random salt and IV with those same lengths.
-
- The salt and key data are combined to create a session
- key using an md5 hash as described in EVP_BytesToKey(3).
-
- The exact call is: EVP_BytesToKey(Cipher, EVP_md5(),
- salt, keydata, len, 1, keystr, NULL); where salt is
- the random data as described above, and keydata is the
- shared secret key data. keystr is the resulting session
- key. The cipher is then seeded with keystr and uses
- the random initialization vector as its first block.
-
- To modify the amount of random salt and initialization
- vector use cipher@n,m where n is the salt length and
- m the initialization vector length. E.g.
-
- -enc aes-cfb@8,16:./my.key
-
- It is not a good idea to set either one to zero,
- although you may be forced to if the other side of the
- tunnel is not under your control.
-
- To skip the salt and EVP_BytesToKey MD5 entirely (no
- hashing is done: the keydata is directly inserted into
- the cipher) specify "-1" for the salt, e.g.
-
- -enc blowfish@-1,16:./my.key
-
- The message digest can also be changed to something
- besides the default MD5. Use cipher@md+n,m where "md"
- can be one of sha, sha1, md5, or ripe. For example:
-
- -enc arc4@sha+8,16:./my.key
-
- The SSVNC vnc viewer project supplies a symmetric
- encryption tool named "ultravnc_dsm_helper" that can
- be used on the viewer side. For example:
-
- ssvncviewer exec='ultravnc_dsm_helper arc4 my.key 0 h:p'
-
- where h:p is the hostname and port of the x11vnc server.
- ultravnc_dsm_helper may also be used standalone to
- provide a symmetric encryption tunnel for any viewer
- or server (VNC or otherwise.) The cipher (1st arg)
- is basically the same syntax as we use above.
-
- Also see the 'Non-Ultra DSM' SSVNC option for the
- 'UltraVNC DSM Encryption Plugin' advanced option.
-
- For both ways of using the viewer, you can specify the
- salt,ivec sizes (in GUI or, e.g. arc4@8,16).
-
--https [port] Use a special, separate HTTPS port (-ssl and
- -stunnel modes only) for HTTPS Java viewer applet
- downloading. I.e. not 5900 and not 5800 (the defaults.)
-
- BACKGROUND: In -ssl mode, it turns out you can use the
- single VNC port (e.g. 5900) for both VNC and HTTPS
- connections. (HTTPS is used to retrieve a SSL-aware
- VncViewer.jar applet that is provided with x11vnc).
- Since both use SSL the implementation was extended to
- detect if HTTP traffic (i.e. GET) is taking place and
- handle it accordingly. The URL would be, e.g.:
-
- https://mymachine.org:5900/
-
- This is convenient for firewalls, etc, because only one
- port needs to be allowed in. However, this heuristic
- adds a few seconds delay to each connection and can be
- unreliable (especially if the user takes much time to
- ponder the Certificate dialogs in his browser, Java VM,
- or VNC Viewer applet. That's right 3 separate "Are
- you sure you want to connect?" dialogs!)
-
- END OF BACKGROUND.
-
- USAGE: So use the -https option to provide a separate,
- more reliable HTTPS port that x11vnc will listen on. If
- [port] is not provided (or is 0), one is autoselected.
- The URL to use is printed out at startup.
-
- The SSL Java applet directory is specified via the
- -httpdir option. If not supplied, -https will try
- to guess the directory as though the -http option
- was supplied.
-
--httpsredir [port] In -ssl mode with the Java applet retrieved via HTTPS,
- when the HTML file containing applet parameters
- ('index.vnc' or 'proxy.vnc') is sent do NOT set the
- applet PORT parameter to the actual VNC port but set it
- to "port" instead. If "port" is not supplied, then
- the port number is guessed from the Host: HTTP header.
-
- This is useful when an incoming TCP connection
- redirection is performed by a router/gateway/firewall
- from one port to an internal machine where x11vnc is
- listening on a different port. The Java applet needs to
- connect to the firewall/router port, not the VNC port
- on the internal workstation. For example, one could
- redir from mygateway.com:443 to workstation:5900.
-
- This spares the user from having to type in
- https://mygateway.com/?PORT=443 into their web
- browser. Note that port 443 is the default https port;
- other ports must be explicitly indicated, for example:
- https://mygateway.com:8000/?PORT=8000. To avoid having
- to include the PORT= in the browser URL, simply supply
- "-httpsredir" to x11vnc.
-
- This option does not work in -stunnel mode.
-
- More tricks: set the env var X11VNC_EXTRA_HTTPS_PARAMS
- to be extra URL parameters to use. This way you do
- not need to specify extra PARAMS in the index.vnc file.
- E.g. x11vnc -env X11VNC_EXTRA_HTTPS_PARAMS='?GET=1' ...
-
- If you do not want to expose the non-SSL HTTP port to
- the network (i.e. you just want the single VNC/HTTPS
- port, e.g. 5900, open for connections) then specify the
- option -env X11VNC_HTTP_LISTEN_LOCALHOST=1 This way
- the connection to the LibVNCServer httpd server will
- only be available on localhost (note that in -ssl mode,
- HTTPS requests are redirected from SSL to the non-SSL
- LibVNCServer HTTP server.)
-
--http_oneport For UN-encrypted connections mode (i.e. no -ssl,
- -stunnel, or -enc options), allow the Java VNC Viewer
- applet to be downloaded thru the VNC port via HTTP.
-
- That is to say, you can use a single port for Java
- applet viewer connections by using a URL in your web
- browser like this, for example:
-
- http://hostname:5900
-
- The regular, two-port mode, URL http://hostname:5800
- will continue to work as well.
-
- As mentioned above, this mode will NOT work with
- the -ssl, -stunnel, or -enc encryption options.
- Note that is it equivalent to '-enc none' (i.e. it
- uses the same detection mechanism as for HTTPS, but
- with no encryption.)
-
- HTTPS single-port is on by default in -ssl encrypted
- mode (and -enc too), so you only need -http_oneport
- when doing non-SSL encrypted connections.
-
- This mode could also be useful for SSH tunnels since
- it means only one port needs to be redirected.
-
- The -httpsredir option may also be useful for this
- mode when using an SSH tunnel as well as for router
- port redirections.
-
- Note that the -env X11VNC_HTTP_LISTEN_LOCALHOST=1
- option described above under -httpsredir applies for
- the LibVNCServer httpd server in all cases (ssl or not.)
-
--ssh user@host:disp Create a remote listening port on machine "host"
- via a SSH tunnel using the -R rport:localhost:lport
- method. lport will be the local x11vnc listening port,
- so a connection to rport (5900+disp) on "host"
- will reach x11vnc. E.g. fred@snoopy.com:0
-
- This could be useful if a firewall/router prevents
- incoming connections to the x11vnc machine, but
- the ssh machine "host" can be reached by the VNC
- viewer. "user@" is not needed unless the remote unix
- username differs from the current one.
-
- By default the remote sshd is usually configured to
- listen only on localhost for rport, so the viewer may
- need to ssh -L redir to "host" as well (See SSVNC to
- automate this). The sshd setting GatewayPorts enables
- listening on all interfaces for rport; viewers can
- reach it more easily.
-
- "disp" is the VNC display for the remote SSH side,
- e.g. 0 corresponds to port 5900, etc. If disp is
- greater than 200 the value is used as the port. Use a
- negative value to force a low port, e.g. host:-80 will
- use port 80.
-
- If ssh-agent is not active, then the ssh password needs
- to be entered in the terminal where x11vnc is running.
-
- By default the remote ssh will issue a 'sleep 300' to
- wait for the incoming connection for 5 mins. To modify
- this use user@host:disp+secs.
-
- If the remote SSH server is on a non-standard port
- (i.e. not 22) use user@host:port:disp+secs.
-
- Note that the ssh process MAY NOT be killed when
- x11vnc exits. It tries by looking at ps(1) output.
-
--usepw If no other password method was supplied on the command
- line, first look for ~/.vnc/passwd and if found use it
- with -rfbauth; next, look for ~/.vnc/passwdfile and
- use it with -passwdfile; otherwise, prompt the user
- for a password to create ~/.vnc/passwd and use it with
- the -rfbauth option. If none of these succeed x11vnc
- exits immediately.
-
--storepasswd pass file Store password "pass" as the VNC password in the
- file "file". Once the password is stored the
- program exits. Use the password via "-rfbauth file"
-
- If called with no arguments, "x11vnc -storepasswd",
- the user is prompted for a password and it is stored
- in the file ~/.vnc/passwd. Called with one argument,
- that will be the file to store the prompted password in.
-
--nopw Disable the big warning message when you use x11vnc
- without some sort of password.
-
--accept string Run a command (possibly to prompt the user at the
- X11 display) to decide whether an incoming client
- should be allowed to connect or not. "string" is
- an external command run via system(3) or some special
- cases described below. Be sure to quote "string"
- if it contains spaces, shell characters, etc. If the
- external command returns 0 the client is accepted,
- otherwise the client is rejected. See below for an
- extension to accept a client view-only.
-
- If x11vnc is running as root (say from inetd(8) or from
- display managers xdm(1), gdm(1), etc), think about the
- security implications carefully before supplying this
- option (likewise for the -gone option).
-
- Environment: The RFB_CLIENT_IP environment variable will
- be set to the incoming client IP number and the port
- in RFB_CLIENT_PORT (or -1 if unavailable). Similarly,
- RFB_SERVER_IP and RFB_SERVER_PORT (the x11vnc side
- of the connection), are set to allow identification
- of the tcp virtual circuit. The x11vnc process
- id will be in RFB_X11VNC_PID, a client id number in
- RFB_CLIENT_ID, and the number of other connected clients
- in RFB_CLIENT_COUNT. RFB_MODE will be "accept".
- RFB_STATE will be PROTOCOL_VERSION, SECURITY_TYPE,
- AUTHENTICATION, INITIALISATION, NORMAL, or UNKNOWN
- indicating up to which state the client has achieved.
- RFB_LOGIN_VIEWONLY will be 0, 1, or -1 (unknown).
- RFB_USERNAME, RFB_LOGIN_TIME, and RFB_CURRENT_TIME may
- also be set.
-
- If "string" is "popup" then a builtin popup window
- is used. The popup will time out after 120 seconds,
- use "popup:N" to modify the timeout to N seconds
- (use 0 for no timeout).
-
- In the case of "popup" and when the -unixpw option
- is specified, then a *second* window will be popped
- up after the user successfully logs in via his UNIX
- password. This time the user will be identified as
- UNIX:username@hostname, the "UNIX:" prefix indicates
- which user the viewer logged as via -unixpw. The first
- popup is only for whether to allow him to even *try*
- to login via unix password.
-
- If "string" is "xmessage" then an xmessage(1)
- invocation is used for the command. xmessage must be
- installed on the machine for this to work.
-
- Both "popup" and "xmessage" will present an option
- for accepting the client "View-Only" (the client
- can only watch). This option will not be presented if
- -viewonly has been specified, in which case the entire
- display is view only.
-
- If the user supplied command is prefixed with something
- like "yes:0,no:*,view:3 mycommand ..." then this
- associates the numerical command return code with
- the actions: accept, reject, and accept-view-only,
- respectively. Use "*" instead of a number to indicate
- the default action (in case the command returns an
- unexpected value). E.g. "no:*" is a good choice.
-
- Note that x11vnc blocks while the external command
- or popup is running (other clients may see no updates
- during this period). So a person sitting a the physical
- display is needed to respond to an popup prompt. (use
- a 2nd x11vnc if you lock yourself out).
-
- More -accept tricks: use "popupmouse" to only allow
- mouse clicks in the builtin popup to be recognized.
- Similarly use "popupkey" to only recognize
- keystroke responses. These are to help avoid the
- user accidentally accepting a client by typing or
- clicking. All 3 of the popup keywords can be followed
- by +N+M to supply a position for the popup window.
- The default is to center the popup window.
--afteraccept string As -accept, except to run a user supplied command after
- a client has been accepted and authenticated. RFB_MODE
- will be set to "afteraccept" and the other RFB_*
- variables are as in -accept. Unlike -accept, the
- command return code is not interpreted by x11vnc.
- Example: -afteraccept 'killall xlock &'
--gone string As -accept, except to run a user supplied command when
- a client goes away (disconnects). RFB_MODE will be
- set to "gone" and the other RFB_* variables are as
- in -accept. The "popup" actions apply as well.
- Unlike -accept, the command return code is not
- interpreted by x11vnc. Example: -gone 'xlock &'
-
--users list If x11vnc is started as root (say from inetd(8) or from
- display managers xdm(1), gdm(1), etc), then as soon
- as possible after connections to the X display are
- established try to switch to one of the users in the
- comma separated "list". If x11vnc is not running as
- root this option is ignored.
-
- Why use this option? In general it is not needed since
- x11vnc is already connected to the X display and can
- perform its primary functions. The option was added
- to make some of the *external* utility commands x11vnc
- occasionally runs work properly. In particular under
- GNOME and KDE to implement the "-solid color" feature
- external commands (gconftool-2 and dcop) unfortunately
- must be run as the user owning the desktop session.
- Since this option switches userid it also affects the
- userid used to run the processes for the -accept and
- -gone options. It also affects the ability to read
- files for options such as -connect, -allow, and -remap
- and also the ultra and tight filetransfer feature if
- enabled. Note that the -connect file is also sometimes
- written to.
-
- So be careful with this option since in some situations
- its use can decrease security.
-
- In general the switch to a user will only take place
- if the display can still be successfully opened as that
- user (this is primarily to try to guess the actual owner
- of the session). Example: "-users fred,wilma,betty".
- Note that a malicious local user "barney" by
- quickly using "xhost +" when logging in may possibly
- get the x11vnc process to switch to user "fred".
- What happens next?
-
- Under display managers it may be a long time before
- the switch succeeds (i.e. a user logs in). To instead
- make it switch immediately regardless if the display
- can be reopened prefix the username with the "+"
- character. E.g. "-users +bob" or "-users +nobody".
-
- The latter (i.e. switching immediately to user
- "nobody") is the only obvious use of the -users option
- that increases security.
-
- Use the following notation to associate a group with
- a user: user1.group1,user2.group2,... Note that
- initgroups(2) will still be called first to try to
- switch to ALL of a user's groups (primary and additional
- groups). Only if that fails or it is not available
- then the single group specified as above (or the user's
- primary group if not specified) is switched to with
- setgid(2). Use -env X11VNC_SINGLE_GROUP=1 to prevent
- trying initgroups(2) and only switch to the single
- group. This sort of setting is only really needed to
- make the ultra or tight filetransfer permissions work
- properly. This format applies to any comma separated lis
-t
- of users, even the special "=" modes described below.
-
- In -unixpw mode, if "-users unixpw=" is supplied
- then after a user authenticates himself via the
- -unixpw mechanism, x11vnc will try to switch to that
- user as though "-users +username" had been supplied.
- If you want to limit which users this will be done for,
- provide them as a comma separated list after "unixpw="
- Groups can also be specified as described above.
-
- Similarly, in -ssl mode, if "-users sslpeer=" is
- supplied then after an SSL client authenticates with his
- cert (the -sslverify option is required for this) x11vnc
- will extract a UNIX username from the "emailAddress"
- field (username@hostname.com) of the "Subject" of the
- x509 SSL cert and then try to switch to that user as
- though "-users +username" had been supplied. If you
- want to limit which users this will be done for, provide
- them as a comma separated list after "sslpeer=".
- Set the env. var X11VNC_SSLPEER_CN to use the Common
- Name (normally a hostname) instead of the Email field.
-
- NOTE: for sslpeer= mode the x11vnc administrator must
- take care that any client certs he adds to -sslverify
- have the intended UNIX username in the "emailAddress"
- field of the cert. Otherwise a user may be able to
- log in as another. This command can be of use in
- checking: "openssl x509 -text -in file.crt", see the
- "Subject:" line. Also, along with the normal RFB_*
- env. vars. (see -accept) passed to external cmd=
- commands, RFB_SSL_CLIENT_CERT will be set to the
- client's x509 certificate string.
-
- The sslpeer= mode can aid finding X sessions via the
- FINDDISPLAY and FINDCREATEDISPLAY mechanisms.
-
- To immediately switch to a user *before* connections
- to the X display are made or any files opened use the
- "=" character: "-users =bob". That user needs to
- be able to open the X display and any files of course.
-
- The special user "guess=" means to examine the utmpx
- database (see who(1)) looking for a user attached to
- the display number (from DISPLAY or -display option)
- and try him/her. To limit the list of guesses, use:
- "-users guess=bob,betty".
-
- Even more sinister is the special user "lurk="
- that means to try to guess the DISPLAY from the utmpx
- login database as well. So it "lurks" waiting for
- anyone to log into an X session and then connects to it.
- Specify a list of users after the = to limit which users
- will be tried. To enable a different searching mode, if
- the first user in the list is something like ":0" or
- ":0-2" that indicates a range of DISPLAY numbers that
- will be tried (regardless of whether they are in the
- utmpx database) for all users that are logged in. Also
- see the "-display WAIT:..." functionality. Examples:
- "-users lurk=" and also "-users lurk=:0-1,bob,mary"
-
- Be especially careful using the "guess=" and "lurk="
- modes. They are not recommended for use on machines
- with untrustworthy local users.
-
--noshm Do not use the MIT-SHM extension for the polling.
- Remote displays can be polled this way: be careful this
- can use large amounts of network bandwidth. This is
- also of use if the local machine has a limited number
- of shm segments and -onetile is not sufficient.
--flipbyteorder Sometimes needed if remotely polled host has different
- endianness. Ignored unless -noshm is set.
--onetile Do not use the new copy_tiles() framebuffer mechanism,
- just use 1 shm tile for polling. Limits shm segments
- used to 3.
-
- To disable any automatic shm reduction set the
- env. var. X11VNC_NO_LIMIT_SHM.
-
--solid [color] To improve performance, when VNC clients are connected
- try to change the desktop background to a solid color.
- The [color] is optional: the default color is "cyan4".
- For a different one specify the X color (rgb.txt name,
- e.g. "darkblue" or numerical "#RRGGBB").
-
- Currently this option only works on GNOME, KDE, CDE,
- XFCE, and classic X (i.e. with the background image
- on the root window). The "gconftool-2", "dcop"
- and "xfconf-query" external commands are run for
- GNOME, KDE, and XFCE respectively. This also works
- on native MacOSX. (There is no color selection for
- MacOSX or XFCE.) Other desktops won't work, (send
- us the corresponding commands if you find them).
- If x11vnc is running as root (inetd(8) or gdm(1)),
- the -users option may be needed for GNOME, KDE, XFCE.
- If x11vnc guesses your desktop incorrectly, you can
- force it by prefixing color with "gnome:", "kde:",
- "cde:", "xfce:", or "root:".
-
- Update: -solid no longer works on KDE4.
-
- This mode works in a limited way on the Mac OS X Console
- with one color ('kelp') using the screensaver writing
- to the background. Look in "~/Library/Screen Savers"
- for VncSolidColor.png to change the color.
-
--blackout string Black out rectangles on the screen. "string" is a
- comma separated list of WxH+X+Y type geometries for
- each rectangle. If one of the items on the list is the
- string "noptr" the mouse pointer will not be allowed
- to go into a blacked out region.
--xinerama If your screen is composed of multiple monitors
--noxinerama glued together via XINERAMA, and that screen is
- not a rectangle this option will try to guess the
- areas to black out (if your system has libXinerama).
- default: -xinerama
-
- In general, we have noticed on XINERAMA displays you may
- need to use the "-xwarppointer" option if the mouse
- pointer misbehaves and it is enabled by default. Use
- "-noxwarppointer" if you do not want this.
-
--xtrap Use the DEC-XTRAP extension for keystroke and mouse
- input insertion. For use on legacy systems, e.g. X11R5,
- running an incomplete or missing XTEST extension.
- By default DEC-XTRAP will be used if XTEST server grab
- control is missing, use -xtrap to do the keystroke and
- mouse insertion via DEC-XTRAP as well.
-
--xrandr [mode] If the display supports the XRANDR (X Resize, Rotate
- and Reflection) extension, and you expect XRANDR events
- to occur to the display while x11vnc is running, this
- options indicates x11vnc should try to respond to
- them (as opposed to simply crashing by assuming the
- old screen size). See the xrandr(1) manpage and run
- 'xrandr -q' for more info. [mode] is optional and
- described below.
-
- Since watching for XRANDR events and trapping errors
- increases polling overhead, only use this option if
- XRANDR changes are expected. For example on a rotatable
- screen PDA or laptop, or using a XRANDR-aware Desktop
- where you resize often. It is best to be viewing with a
- vncviewer that supports the NewFBSize encoding, since it
- knows how to react to screen size changes. Otherwise,
- LibVNCServer tries to do so something reasonable for
- viewers that cannot do this (portions of the screen
- may be clipped, unused, etc).
-
- Note: the default now is to check for XRANDR events, but
- do not trap every X call that may fail due to resize.
- If a resize event is received, the full -xrandr mode
- is enabled. To disable even checking for events supply:
- -noxrandr.
-
- "mode" defaults to "resize", which means create a
- new, resized, framebuffer and hope all viewers can cope
- with the change. "newfbsize" means first disconnect
- all viewers that do not support the NewFBSize VNC
- encoding, and then resize the framebuffer. "exit"
- means disconnect all viewer clients, and then terminate
- x11vnc.
-
--rotate string Rotate and/or flip the framebuffer view exported by VNC.
- This transformation is independent of XRANDR and is
- done in software in main memory and so may be slower.
- This mode could be useful on a handheld with portrait or
- landscape modes that do not correspond to the scanline
- order of the actual framebuffer. "string" can be:
-
- x flip along x-axis
- y flip along y-axis
- xy flip along x- and y-axes
- +90 rotate 90 degrees clockwise
- -90 rotate 90 degrees counter-clockwise
- +90x rotate 90 degrees CW, then flip along x
- +90y rotate 90 degrees CW, then flip along y
-
- these give all possible rotations and reflections.
-
- Aliases: same as xy: yx, +180, -180, 180
- same as -90: +270, 270
- same as +90: 90, (ditto for 90x, 90y)
-
- Like -scale, this transformation is applied at the very
- end of any chain of framebuffer transformations and so
- any options with geometries, e.g. -blackout, -clip, etc.
- are relative to the original X (or -rawfb) framebuffer,
- not the final one sent to VNC viewers.
-
- If you do not want the cursor shape to be rotated
- prefix "string" with "nc:", e.g. "nc:+90",
- "nc:xy", etc.
-
--padgeom WxH Whenever a new vncviewer connects, the framebuffer is
- replaced with a fake, solid black one of geometry WxH.
- Shortly afterwards the framebuffer is replaced with the
- real one. This is intended for use with vncviewers
- that do not support NewFBSize and one wants to make
- sure the initial viewer geometry will be big enough
- to handle all subsequent resizes (e.g. under -xrandr,
- -remote id:windowid, rescaling, etc.)
-
- In -unixpw mode this sets the size of the login screen.
- Use "once:WxH" it ignore padgeom after the login
- screen is set up.
-
--o logfile Write stderr messages to file "logfile" instead of to
- the terminal. Same as "-logfile file". To append
- to the file use "-oa file" or "-logappend file".
- If "logfile" contains the string "%VNCDISPLAY"
- it is expanded to the vnc display (the name may need
- to be guessed at.) "%HOME" works too.
-
--flag file Write the "PORT=NNNN" (e.g. PORT=5900) string to
- "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.
-
--env VAR=VALUE Set the environment variable 'VAR' to value 'VALUE'
- at x11vnc startup. This is a convenience utility to
- avoid shell script wrappers, etc. to set the env. var.
- You may specify as many of these as needed on the
- command line.
--prog /path/to/x11vnc Set the full path to the x11vnc program for cases when
- it cannot be determined from argv[0] (e.g. tcpd/inetd)
-
--h, -help Print this help text.
--?, -opts Only list the x11vnc options.
--V, -version Print program version and last modification date.
--license Print out license information. Same as -copying and
- -warranty.
-
--dbg Instead of exiting after cleaning up, run a simple
- "debug crash shell" when fatal errors are trapped.
-
--q, -quiet Be quiet by printing less informational output to
- stderr. (use -noquiet to undo an earlier -quiet.)
-
- The -quiet option does not eliminate all informational
- output, it only reduces it. It is ignored in most
- auxiliary usage modes, e.g. -storepasswd. To eliminate
- all output use: 2>/dev/null 1>&2, etc.
-
--v, -verbose Print out more information to stderr.
-
--bg Go into the background after screen setup. Messages to
- stderr are lost unless -o logfile is used. Something
- like this could be useful in a script:
- port=`ssh -t $host "x11vnc -display :0 -bg" | grep PORT
-`
- port=`echo "$port" | sed -e 's/PORT=//'`
- port=`expr $port - 5900`
- vncviewer $host:$port
-
--modtweak Option -modtweak automatically tries to adjust the AltGr
--nomodtweak and Shift modifiers for differing language keyboards
- between client and host. Otherwise, only a single key
- press/release of a Keycode is simulated (i.e. ignoring
- the state of the modifiers: this usually works for
- identical keyboards). Also useful in resolving cases
- where a Keysym is bound to multiple keys (e.g. "<" + ">"
- and "," + "<" keys). Default: -modtweak
-
- If you are having trouble with with keys and -xkb or
- -noxkb, and similar things don't help, try -nomodtweak.
-
- On some HP-UX systems it is been noted that they have
- an odd keymapping where a single keycode will have a
- keysym, e.g. "#", up to three times. You can check
- via "xmodmap -pk" or the -dk option. The failure
- is when you try to type "#" it yields "3". If you
- see this problem try setting the environment variable
- MODTWEAK_LOWEST=1 to see if it helps.
-
--xkb When in modtweak mode, use the XKEYBOARD extension (if
--noxkb the X display supports it) to do the modifier tweaking.
- This is powerful and should be tried if there are still
- keymapping problems when using -modtweak by itself.
- The default is to check whether some common keysyms,
- e.g. !, @, [, are only accessible via -xkb mode and if
- so then automatically enable the mode. To disable this
- automatic detection use -noxkb.
-
- When -xkb mode is active you can set these env. vars.
- They apply only when there is ambiguity as to which
- key to choose (i.e the mapping is not one-to-one).
- NOKEYHINTS=1: for up ascii keystrokes do not use score
- hints saved when the key was pressed down. NOANYDOWN=1:
- for up keystrokes do not resort to searching through
- keys that are currently pressed down. KEYSDOWN=N:
- remember the last N keys press down for tie-breaking
- when an up keystroke comes in.
-
--capslock When in -modtweak (the default) or -xkb mode,
- if a keysym in the range A-Z comes in check the X
- server to see if the Caps_Lock is set. If it is do
- not artificially press Shift to generate the keysym.
- This will enable the CapsLock key to behave correctly
- in some circumstances: namely *both* the VNC viewer
- machine and the x11vnc X server are in the CapsLock
- on state. If one side has CapsLock on and the other
- off and the keyboard is not behaving as you think it
- should you should correct the CapsLock states (hint:
- pressing CapsLock inside and outside of the viewer can
- help toggle them both to the correct state). However,
- for best results do not use this option, but rather
- *only* enable CapsLock on the VNC viewer side (i.e. by
- pressing CapsLock outside of the viewer window, also
- -skip_lockkeys below). Also try -nomodtweak for a
- possible workaround.
-
--skip_lockkeys Have x11vnc ignore all Caps_Lock, Shift_Lock, Num_Lock,
--noskip_lockkeys Scroll_Lock keysyms received from viewers. The idea is
- you press Caps_Lock on the VNC Viewer side but that does
- not change the lock state in the x11vnc-side X server.
- Nevertheless your capitalized letters come in over
- the wire and are applied correctly to the x11vnc-side
- X server. Note this mode probably won't do what you
- want in -nomodtweak mode. Also, a kludge for KP_n
- digits is always done in this mode: they are mapped to
- regular digit keysyms. See also -capslock above.
- The default is -noskip_lockkeys.
-
--skip_keycodes string Ignore the comma separated list of decimal keycodes.
- Perhaps these are keycodes not on your keyboard but
- your X server thinks exist. Currently only applies
- to -xkb mode. Use this option to help x11vnc in the
- reverse problem it tries to solve: Keysym -> Keycode(s)
- when ambiguities exist (more than one Keycode per
- Keysym). Run 'xmodmap -pk' to see your keymapping.
- Example: "-skip_keycodes 94,114"
--sloppy_keys Experimental option that tries to correct some
- "sloppy" key behavior. E.g. if at the viewer you
- press Shift+Key but then release the Shift before
- Key that could give rise to extra unwanted characters
- (usually only between keyboards of different languages).
- Only use this option if you observe problems with
- some keystrokes.
--skip_dups Some VNC viewers send impossible repeated key events,
--noskip_dups e.g. key-down, key-down, key-up, key-up all for the same
- key, or 20 downs in a row for the same modifier key!
- Setting -skip_dups means to skip these duplicates and
- just process the first event. Note: some VNC viewers
- assume they can send down's without the corresponding
- up's and so you should not set this option for
- these viewers (symptom: some keys do not autorepeat)
- Default: -noskip_dups
--add_keysyms If a Keysym is received from a VNC viewer and that
--noadd_keysyms Keysym does not exist in the X server, then add the
- Keysym to the X server's keyboard mapping on an unused
- key. Added Keysyms will be removed periodically and
- also when x11vnc exits. Default: -add_keysyms
--clear_mods At startup and exit clear the modifier keys by sending
- KeyRelease for each one. The Lock modifiers are skipped.
- Used to clear the state if the display was accidentally
- left with any pressed down.
--clear_keys As -clear_mods, except try to release ANY pressed key.
- Note that this option and -clear_mods can interfere
- with a person typing at the physical keyboard.
--clear_all As -clear_keys, except try to release any CapsLock,
- NumLock, etc. locks as well.
-
--remap string Read Keysym remappings from file named "string".
- Format is one pair of Keysyms per line (can be name
- or hex value) separated by a space. If no file named
- "string" exists, it is instead interpreted as this
- form: key1-key2,key3-key4,... See <X11/keysymdef.h>
- header file for a list of Keysym names, or use xev(1).
-
- To map a key to a button click, use the fake Keysyms
- "Button1", ..., etc. E.g: "-remap Super_R-Button2"
- (useful for pasting on a laptop)
-
- I use these if the machine I am viewing from does not
- have a scrollwheel or I don't like using the one it has:
-
- -remap Super_R-Button4,Menu-Button5
- -remap KP_Add-Button4,KP_Enter-Button5
-
- the former would be used on a PC, the latter on a
- MacBook. This way those little used keys can be used
- to generate bigger hops than the Up and Down arrows
- provide. One can scroll through text or web pages more
- quickly this way (especially if x11vnc scroll detection
- is active.)
-
- Use Button44, Button12, etc. for multiple clicks.
-
- To disable a keysym (i.e. make it so it will not be
- injected), remap it to "NoSymbol" or "None".
-
- Dead keys: "dead" (or silent, mute) keys are keys that
- do not produce a character but must be followed by a 2nd
- keystroke. This is often used for accenting characters,
- e.g. to put "`" on top of "a" by pressing the dead
- key and then "a". Note that this interpretation
- is not part of core X11, it is up to the toolkit or
- application to decide how to react to the sequence.
- The X11 names for these keysyms are "dead_grave",
- "dead_acute", etc. However some VNC viewers send the
- keysyms "grave", "acute" instead thereby disabling
- the accenting. To work around this -remap can be used.
- For example "-remap grave-dead_grave,acute-dead_acute"
- As a convenience, "-remap DEAD" applies these remaps:
-
- g grave-dead_grave
- a acute-dead_acute
- c asciicircum-dead_circumflex
- t asciitilde-dead_tilde
- m macron-dead_macron
- b breve-dead_breve
- D abovedot-dead_abovedot
- d diaeresis-dead_diaeresis
- o degree-dead_abovering
- A doubleacute-dead_doubleacute
- r caron-dead_caron
- e cedilla-dead_cedilla
-
- If you just want a subset use the first letter
- label, e.g. "-remap DEAD=ga" to get the first two.
- Additional remaps may also be supplied via commas,
- e.g. "-remap DEAD=ga,Super_R-Button2". Finally,
- "DEAD=missing" means to apply all of the above as
- long as the left hand member is not already in the
- X11 keymap.
-
--norepeat Option -norepeat disables X server key auto repeat when
--repeat VNC clients are connected and VNC keyboard input is
- not idle for more than 5 minutes. This works around a
- repeating keystrokes bug (triggered by long processing
- delays between key down and key up client events:
- either from large screen changes or high latency).
- Default: -norepeat
-
- You can set the env. var. X11VNC_IDLE_TIMEOUT to the
- number of idle seconds you want (5min = 300secs).
-
- Note: your VNC viewer side will likely do autorepeating,
- so this is no loss unless someone is simultaneously at
- the real X display.
-
- Use "-norepeat N" to set how many times norepeat will
- be reset if something else (e.g. X session manager)
- undoes it. The default is 2. Use a negative value
- for unlimited resets.
-
--nofb Ignore video framebuffer: only process keyboard and
- pointer. Intended for use with Win2VNC and x2vnc
- dual-monitor setups.
--nobell Do not watch for XBell events. (no beeps will be heard)
- Note: XBell monitoring requires the XKEYBOARD extension.
--nosel Do not manage exchange of X selection/cutbuffer between
- VNC viewers and the X server at all.
--noprimary Do not poll the PRIMARY selection for changes to send
- back to clients. (PRIMARY is still set on received
- changes, however).
--nosetprimary Do not set the PRIMARY selection for changes received
- from VNC clients.
--noclipboard Do not poll the CLIPBOARD selection for changes to send
- back to clients. (CLIPBOARD is still set on received
- changes, however).
--nosetclipboard Do not set the CLIPBOARD selection for changes
- received from VNC clients.
--seldir string If direction string is "send", only send the selection
- to viewers, and if it is "recv" only receive it from
- viewers. To work around apps setting the selection
- too frequently and messing up the other end. You can
- actually supply a comma separated list of directions,
- including "debug" to turn on debugging output.
-
--cursor [mode] Sets how the pointer cursor shape (little icon at the
--nocursor mouse pointer) should be handled. The "mode" string
- is optional and is described below. The default
- is to show some sort of cursor shape(s). How this
- is done depends on the VNC viewer and the X server.
- Use -nocursor to disable cursor shapes completely.
-
- Some VNC viewers support the TightVNC CursorPosUpdates
- and CursorShapeUpdates extensions (cuts down on
- network traffic by not having to send the cursor image
- every time the pointer is moved), in which case these
- extensions are used (see -nocursorshape and -nocursorpos
- below to disable). For other viewers the cursor shape
- is written directly to the framebuffer every time the
- pointer is moved or changed and gets sent along with
- the other framebuffer updates. In this case, there
- will be some lag between the vnc viewer pointer and
- the remote cursor position.
-
- If the X display supports retrieving the cursor shape
- information from the X server, then the default is
- to use that mode. On Solaris this can be done with
- the SUN_OVL extension using -overlay (see also the
- -overlay_nocursor option). A similar overlay scheme
- is used on IRIX. Xorg (e.g. Linux) and recent Solaris
- Xsun servers support the XFIXES extension to retrieve
- the exact cursor shape from the X server. If XFIXES
- is present it is preferred over Overlay and is used by
- default (see -noxfixes below). This can be disabled
- with -nocursor, and also some values of the "mode"
- option below.
-
- Note that under XFIXES cursors with transparency (alpha
- channel) will usually not be exactly represented and one
- may find Overlay preferable. See also the -alphacut
- and -alphafrac options below as fudge factors to try
- to improve the situation for cursors with transparency
- for a given theme.
-
- The "mode" string can be used to fine-tune the
- displaying of cursor shapes. It can be used the
- following ways:
-
- "-cursor arrow" - just show the standard arrow
- nothing more or nothing less.
-
- "-cursor none" - same as "-nocursor"
-
- "-cursor X" - when the cursor appears to be on the
- root window, draw the familiar X shape. Some desktops
- such as GNOME cover up the root window completely,
- and so this will not work, try "X1", etc, to try to
- shift the tree depth. On high latency links or slow
- machines there will be a time lag between expected and
- the actual cursor shape.
-
- "-cursor some" - like "X" but use additional
- heuristics to try to guess if the window should have
- a windowmanager-like resizer cursor or a text input
- I-beam cursor. This is a complete hack, but may be
- useful in some situations because it provides a little
- more feedback about the cursor shape.
-
- "-cursor most" - try to show as many cursors as
- possible. Often this will only be the same as "some"
- unless the display has overlay visuals or XFIXES
- extensions available. On Solaris and IRIX if XFIXES
- is not available, -overlay mode will be attempted.
-
--cursor_drag Show cursor shape changes even when the mouse is being
- dragged with a mouse button down. This is useful if you
- want to be able to see Drag-and-Drop cursor icons, etc.
-
--arrow n Choose an alternate "arrow" cursor from a set of
- some common ones. n can be 1 to 6. Default is: 1
- Ignored when in XFIXES cursor-grabbing mode.
-
--noxfixes Do not use the XFIXES extension to draw the exact cursor
- shape even if it is available.
-
- Note: To work around a crash in Xorg 1.5 and later
- some people needed to use -noxfixes. The Xorg crash
- occurred right after a Display Manager (e.g. GDM) login.
- Starting with x11vnc 0.9.9 it tries to automatically
- avoid using XFIXES until it is sure a window manager
- is running. See the -reopen option for more info and
- how to use X11VNC_AVOID_WINDOWS=never to disable it.
-
--alphacut n When using the XFIXES extension for the cursor shape,
- cursors with transparency will not usually be displayed
- exactly (but opaque ones will). This option sets n as
- a cutoff for cursors that have transparency ("alpha
- channel" with values ranging from 0 to 255) Any cursor
- pixel with alpha value less than n becomes completely
- transparent. Otherwise the pixel is completely opaque.
- Default 240
-
--alphafrac fraction With the threshold in -alphacut some cursors will become
- almost completely transparent because their alpha values
- are not high enough. For those cursors adjust the
- alpha threshold until fraction of the non-zero alpha
- channel pixels become opaque. Default 0.33
--alpharemove By default, XFIXES cursors pixels with transparency have
- the alpha factor multiplied into the RGB color values
- (i.e. that corresponding to blending the cursor with a
- black background). Specify this option to remove the
- alpha factor. (useful for light colored semi-transparent
- cursors).
--noalphablend In XFIXES mode do not send cursor alpha channel data
- to LibVNCServer. The default is to send it. The
- alphablend effect will only be visible in -nocursorshape
- mode or for clients with cursorshapeupdates turned
- off. (However there is a hack for 32bpp with depth 24,
- it uses the extra 8 bits to store cursor transparency
- for use with a hacked vncviewer that applies the
- transparency locally. See the FAQ for more info).
-
--nocursorshape Do not use the TightVNC CursorShapeUpdates extension
- even if clients support it. See -cursor above.
--cursorpos Option -cursorpos enables sending the X cursor position
--nocursorpos back to all vnc clients that support the TightVNC
- CursorPosUpdates extension. Other clients will be able
- to see the pointer motions. Default: -cursorpos
--xwarppointer Move the pointer with XWarpPointer(3X) instead of
--noxwarppointer the XTEST extension. Use this as a workaround
- if the pointer motion behaves incorrectly, e.g.
- on touchscreens or other non-standard setups.
-
- It is also sometimes needed on XINERAMA displays and is
- enabled by default if XINERAMA is found to be active.
- To prevent this, use -noxwarppointer.
-
--always_inject Even if there is no displacement (dx = dy = 0) for a
- VNC mouse event force the pointer to the indicated x,y
- position anyway. Recent (2009) gui toolkits (gnome)
- have problems with x11vnc's original mouse input
- injection method. So x11vnc's mouse input injection
- method has been modified. To regain the OLD behavior
- use this option: -always_inject. Then x11vnc will
- always force positioning the mouse to the x,y position
- even if that position has not changed since the previous
- VNC input event.
-
- The first place this problem was noticed was in gnome
- terminal: if you pressed and released mouse button 3, a
- menu was posted and then its first element 'New Terminal
- Window' was activated. This was because x11vnc injected
- the mouse position twice: once on ButtonPress and again
- on ButtonRelease. The toolkit interpreted the 2nd one
- as mouse motion even though the mouse hadn't moved.
- So now by default x11vnc tries to avoid injecting the
- 2nd one.
-
- Note that with the new default x11vnc will be oblivious
- to applications moving the pointer (warping) or the
- user at the physical display moving it. So it might,
- e.g., inject ButtonRelease at the wrong position.
- If this (or similar scenarios) causes problems in your
- environment, specify -always_inject for the old method.
-
--buttonmap string String to remap mouse buttons. Format: IJK-LMN, this
- maps buttons I -> L, etc., e.g. -buttonmap 13-31
-
- Button presses can also be mapped to keystrokes: replace
- a button digit on the right of the dash with :<sym>:
- or :<sym1>+<sym2>: etc. for multiple keys. For example,
- if the viewing machine has a mouse-wheel (buttons 4 5)
- but the x11vnc side does not, these will do scrolls:
- -buttonmap 12345-123:Prior::Next:
- -buttonmap 12345-123:Up+Up+Up::Down+Down+Down:
-
- See <X11/keysymdef.h> header file for a list of Keysyms,
- or use the xev(1) program. Note: mapping of button
- clicks to Keysyms may not work if -modtweak or -xkb is
- needed for the Keysym.
-
- If you include a modifier like "Shift_L" the
- modifier's up/down state is toggled, e.g. to send
- "The" use :Shift_L+t+Shift_L+h+e: (the 1st one is
- shift down and the 2nd one is shift up). (note: the
- initial state of the modifier is ignored and not reset)
- To include button events use "Button1", ... etc.
-
- -buttonmap currently does not work on MacOSX console
- or in -rawfb mode.
-
- Workaround: use -buttonmap IJ...-LM...=n to limit the
- number of mouse buttons to n, e.g. 123-123=3. This will
- prevent x11vnc from crashing if the X server reports
- there are 5 buttons (4/5 scroll wheel), but there are
- only really 3.
-
--nodragging Do not update the display during mouse dragging events
- (mouse button held down). Greatly improves response on
- slow setups, but you lose all visual feedback for drags,
- text selection, and some menu traversals. It overrides
- any -pointer_mode setting.
-
--ncache n Client-side caching scheme. Framebuffer memory "n"
- (an integer) times that of the full display is allocated
- below the actual framebuffer to cache screen contents
- for rapid retrieval. So a W x H frambuffer is expanded
- to a W x (n+1)*H one. Use 0 to disable.
-
- The "n" is actually optional, the default is 10.
-
- For this and the other -ncache* options below you can
- abbreviate "-ncache" with "-nc". Also, "-nonc"
- is the same as "-ncache 0"
-
- This is an experimental option, currently implemented in
- an awkward way in that in the VNC Viewer you can see the
- pixel cache contents if you scroll down, etc. So you
- will have to set things up so you can't see that region.
- If this method is successful, the changes required for
- clients to do this less awkwardly will be investigated.
-
- The SSVNC viewer does a good job at automatically hiding
- the pixel cache region. Or use SSVNC's -ycrop option
- to explicitly hide the region.
-
- Note that this mode consumes a huge amount of memory,
- both on the x11vnc server side and on the VNC Viewer
- side. If n=2 then the amount of RAM used is roughly
- tripled for both x11vnc and the VNC Viewer. As a rule
- of thumb, note that 1280x1024 at depth 24 is about 5MB
- of pixel data.
-
- For reasonable response when cycling through 4 to 6
- large (e.g. web browser) windows a value n of 6 to 12
- is recommended. (that's right: ~10X more memory...)
-
- Because of the way window backingstore and saveunders
- are implemented, n must be even. It will be incremented
- by 1 if it is not.
-
- This mode also works for native MacOS X, but may not
- be as effective as the X version. This is due to a
- number of things, one is the drop-shadow compositing
- that leaves extra areas that need to be repaired (see
- -ncache_pad). Another is the window iconification
- animations need to be avoided (see -macicontime).
- It appears the that the 'Scale' animation mode gives
- better results than the 'Genie' one. Also, window event
- detection not as accurate as the X version.
-
--ncache_cr In -ncache mode, try to do copyrect opaque window
- moves/drags instead of wireframes (this can induce
- painting errors). The wireframe will still be used when
- moving a window whose save-unders has not yet been set
- or has been invalidated.
-
- Some VNC Viewers provide better response than others
- with this option. On Unix, realvnc viewer gives
- smoother drags than tightvnc viewer. Response may also
- be choppy if the server side machine is too slow.
-
- Sometimes on very slow modem connections, this actually
- gives an improvement because no pixel data at all
- (not even the box animation) is sent during the drag.
-
--ncache_no_moveraise In -ncache mode, do not assume that moving a window
- will cause the window manager to raise it to the top
- of the stack. The default is to assume it does, and
- so at the beginning of any wireframe, etc, window moves
- the window will be pushed to top in the VNC viewer.
-
--ncache_no_dtchange In -ncache mode, do not try to guess when the desktop
- (viewport) changes to another one (i.e. another
- workarea). The default is to try to guess and when
- detected try to make the transistion more smoothly.
-
--ncache_no_rootpixmap In -ncache mode, do not try to snapshot the desktop
- background to use in guessing or reconstructing window
- save-unders.
-
--ncache_keep_anims In -ncache mode, do not try to disable window
- manager animations and other effects (that usually
- degrade ncache performance or cause painting errors).
- The default is to try to disable them on KDE (but not
- GNOME) when VNC clients are connected.
-
- For other window managers or desktops that provide
- animations, effects, compositing, translucency,
- etc. that interfere with the -ncache method you will
- have to disable them manually.
-
--ncache_old_wm In -ncache mode, enable some heuristics for old style
- window managers such as fvwm and twm.
-
--ncache_pad n In -ncache mode, pad each window with n pixels for the
- caching rectangles. This can be used to try to improve
- the situation with dropshadows or other compositing
- (e.g. MacOS X window manager), although it could make
- things worse. The default is 0 on Unix and 24 on
- MacOS X.
--debug_ncache Turn on debugging and profiling output under -ncache.
-
--wireframe [str] Try to detect window moves or resizes when a mouse
--nowireframe button is held down and show a wireframe instead of
- the full opaque window. This is based completely on
- heuristics and may not always work: it depends on your
- window manager and even how you move things around.
- See -pointer_mode below for discussion of the "bogging
- down" problem this tries to avoid.
- Default: -wireframe
-
- Shorter aliases: -wf [str] and -nowf
-
- The value "str" is optional and, of course, is
- packed with many tunable parameters for this scheme:
-
- Format: shade,linewidth,percent,T+B+L+R,mod,t1+t2+t3+t4
- Default: 0xff,2,0,32+8+8+8,all,0.15+0.30+5.0+0.125
-
- If you leave nothing between commas: ",," the default
- value is used. If you don't specify enough commas,
- the trailing parameters are set to their defaults.
-
- "shade" indicate the "color" for the wireframe,
- usually a greyscale: 0-255, however for 16 and 32bpp you
- can specify an rgb.txt X color (e.g. "dodgerblue") or
- a value > 255 is treated as RGB (e.g. red is 0xff0000).
- "linewidth" sets the width of the wireframe in pixels.
- "percent" indicates to not apply the wireframe scheme
- to windows with area less than this percent of the
- full screen.
-
- "T+B+L+R" indicates four integers for how close in
- pixels the pointer has to be from the Top, Bottom, Left,
- or Right edges of the window to consider wireframing.
- This is a speedup to quickly exclude a window from being
- wireframed: set them all to zero to not try the speedup
- (scrolling and selecting text will likely be slower).
-
- "mod" specifies if a button down event in the
- interior of the window with a modifier key (Alt, Shift,
- etc.) down should indicate a wireframe opportunity.
- It can be "0" or "none" to skip it, "1" or "all"
- to apply it to any modifier, or "Shift", "Alt",
- "Control", "Meta", "Super", or "Hyper" to only
- apply for that type of modifier key.
-
- "t1+t2+t3+t4" specify four floating point times in
- seconds: t1 is how long to wait for the pointer to move,
- t2 is how long to wait for the window to start moving
- or being resized (for some window managers this can be
- rather long), t3 is how long to keep a wireframe moving
- before repainting the window. t4 is the minimum time
- between sending wireframe "animations". If a slow
- link is detected, these values may be automatically
- changed to something better for a slow link.
-
--nowireframelocal By default, mouse motion and button presses of a
- user sitting at the LOCAL display are monitored for
- wireframing opportunities (so that the changes will be
- sent efficiently to the VNC clients). Use this option
- to disable this behavior.
-
--wirecopyrect mode Since the -wireframe mechanism evidently tracks moving
--nowirecopyrect windows accurately, a speedup can be obtained by
- telling the VNC viewers to locally copy the translated
- window region. This is the VNC CopyRect encoding:
- the framebuffer update doesn't need to send the actual
- new image data.
-
- Shorter aliases: -wcr [mode] and -nowcr
-
- "mode" can be "never" (same as -nowirecopyrect)
- to never try the copyrect, "top" means only do it if
- the window was not covered by any other windows, and
- "always" means to translate the orginally unobscured
- region (this may look odd as the remaining pieces come
- in, but helps on a slow link). Default: "always"
-
- Note: there can be painting errors or slow response
- when using -scale so you may want to disable CopyRect
- in this case "-wirecopyrect never" on the command
- line or by remote-control. Or you can also use the
- "-scale xxx:nocr" scale option.
-
--debug_wireframe Turn on debugging info printout for the wireframe
- heuristics. "-dwf" is an alias. Specify multiple
- times for more output.
-
--scrollcopyrect mode Like -wirecopyrect, but use heuristics to try to guess
--noscrollcopyrect if a window has scrolled its contents (either vertically
- or horizontally). This requires the RECORD X extension
- to "snoop" on X applications (currently for certain
- XCopyArea and XConfigureWindow X protocol requests).
- Examples: Hitting <Return> in a terminal window when the
- cursor was at the bottom, the text scrolls up one line.
- Hitting <Down> arrow in a web browser window, the web
- page scrolls up a small amount. Or scrolling with a
- scrollbar or mouse wheel.
-
- Shorter aliases: -scr [mode] and -noscr
-
- This scheme will not always detect scrolls, but when
- it does there is a nice speedup from using the VNC
- CopyRect encoding (see -wirecopyrect). The speedup
- is both in reduced network traffic and reduced X
- framebuffer polling/copying. On the other hand, it may
- induce undesired transients (e.g. a terminal cursor
- being scrolled up when it should not be) or other
- painting errors (window tearing, bunching-up, etc).
- These are automatically repaired in a short period
- of time. If this is unacceptable disable the feature
- with -noscrollcopyrect.
-
- Screen clearing kludges: for testing at least, there
- are some "magic key sequences" (must be done in less
- than 1 second) to aid repairing painting errors that
- may be seen when using this mode:
-
- 3 Alt_L's in a row: resend whole screen,
- 4 Alt_L's in a row: reread and resend whole screen,
- 3 Super_L's in a row: mark whole screen for polling,
- 4 Super_L's in a row: reset RECORD context,
- 5 Super_L's in a row: try to push a black screen
-
- note: Alt_L is the Left "Alt" key (a single key)
- Super_L is the Left "Super" key (Windows flag).
- Both of these are modifier keys, and so should not
- generate characters when pressed by themselves. Also,
- your VNC viewer may have its own refresh hot-key
- or button.
-
- "mode" can be "never" (same as -noscrollcopyrect)
- to never try the copyrect, "keys" means to try it
- in response to keystrokes only, "mouse" means to
- try it in response to mouse events only, "always"
- means to do both. Default: "always"
-
- Note: there can be painting errors or slow response
- when using -scale so you may want to disable CopyRect
- in this case "-scrollcopyrect never" on the command
- line or by remote-control. Or you can also use the
- "-scale xxx:nocr" scale option.
-
--scr_area n Set the minimum area in pixels for a rectangle
- to be considered for the -scrollcopyrect detection
- scheme. This is to avoid wasting the effort on small
- rectangles that would be quickly updated the normal way.
- E.g. suppose an app updated the position of its skinny
- scrollbar first and then shifted the large panel
- it controlled. We want to be sure to skip the small
- scrollbar and get the large panel. Default: 60000
-
--scr_skip list Skip scroll detection for applications matching
- the comma separated list of strings in "list".
- Some applications implement their scrolling in
- strange ways where the XCopyArea, etc, also applies
- to invisible portions of the window: if we CopyRect
- those areas it looks awful during the scroll and
- there may be painting errors left after the scroll.
- Soffice.bin is the worst known offender.
-
- Use "##" to denote the start of the application class
- (e.g. "##XTerm") and "++" to denote the start
- of the application instance name (e.g. "++xterm").
- The string your list is matched against is of the form
- "^^WM_NAME##Class++Instance<same-for-any-subwindows>"
- The "xlsclients -la" command will provide this info.
-
- If a pattern is prefixed with "KEY:" it only applies
- to Keystroke generated scrolls (e.g. Up arrow). If it
- is prefixed with "MOUSE:" it only applies to Mouse
- induced scrolls (e.g. dragging on a scrollbar).
- Default: ##Soffice.bin,##StarOffice,##OpenOffice
-
--scr_inc list Opposite of -scr_skip: this list is consulted first
- and if there is a match the window will be monitored
- via RECORD for scrolls irrespective of -scr_skip.
- Use -scr_skip '*' to skip anything that does not match
- your -scr_inc. Use -scr_inc '*' to include everything.
-
--scr_keys list For keystroke scroll detection, only apply the RECORD
- heuristics to the comma separated list of keysyms in
- "list". You may find the RECORD overhead for every
- one of your keystrokes disrupts typing too much, but you
- don't want to turn it off completely with "-scr mouse"
- and -scr_parms does not work or is too confusing.
-
- The listed keysyms can be numeric or the keysym
- names in the <X11/keysymdef.h> header file or from the
- xev(1) program. Example: "-scr_keys Up,Down,Return".
- One probably wants to have application specific lists
- (e.g. for terminals, etc) but that is too icky to think
- about for now...
-
- If "list" begins with the "-" character the list
- is taken as an exclude list: all keysyms except those
- list will be considered. The special string "builtin"
- expands to an internal list of keysyms that are likely
- to cause scrolls. BTW, by default modifier keys,
- Shift_L, Control_R, etc, are skipped since they almost
- never induce scrolling by themselves.
-
--scr_term list Yet another cosmetic kludge. Apply shell/terminal
- heuristics to applications matching comma separated
- list (same as for -scr_skip/-scr_inc). For example an
- annoying transient under scroll detection is if you
- hit Enter in a terminal shell with full text window,
- the solid text cursor block will be scrolled up.
- So for a short time there are two (or more) block
- cursors on the screen. There are similar scenarios,
- (e.g. an output line is duplicated).
-
- These transients are induced by the approximation of
- scroll detection (e.g. it detects the scroll, but not
- the fact that the block cursor was cleared just before
- the scroll). In nearly all cases these transient errors
- are repaired when the true X framebuffer is consulted
- by the normal polling. But they are distracting, so
- what this option provides is extra "padding" near the
- bottom of the terminal window: a few extra lines near
- the bottom will not be scrolled, but rather updated
- from the actual X framebuffer. This usually reduces
- the annoying artifacts. Use "none" to disable.
- Default: "term"
-
--scr_keyrepeat lo-hi If a key is held down (or otherwise repeats rapidly) and
- this induces a rapid sequence of scrolls (e.g. holding
- down an Arrow key) the "scrollcopyrect" detection
- and overhead may not be able to keep up. A time per
- single scroll estimate is performed and if that estimate
- predicts a sustainable scrollrate of keys per second
- between "lo" and "hi" then repeated keys will be
- DISCARDED to maintain the scrollrate. For example your
- key autorepeat may be 25 keys/sec, but for a large
- window or slow link only 8 scrolls per second can be
- sustained, then roughly 2 out of every 3 repeated keys
- will be discarded during this period. Default: "4-20"
-
--scr_parms string Set various parameters for the scrollcopyrect mode.
- The format is similar to that for -wireframe and packed
- with lots of parameters:
-
- Format: T+B+L+R,t1+t2+t3,s1+s2+s3+s4+s5
- Default: 0+64+32+32,0.02+0.10+0.9,0.03+0.06+0.5+0.1+5.0
-
- If you leave nothing between commas: ",," the default
- value is used. If you don't specify enough commas,
- the trailing parameters are set to their defaults.
-
- "T+B+L+R" indicates four integers for how close in
- pixels the pointer has to be from the Top, Bottom, Left,
- or Right edges of the window to consider scrollcopyrect.
- If -wireframe overlaps it takes precedence. This is a
- speedup to quickly exclude a window from being watched
- for scrollcopyrect: set them all to zero to not try
- the speedup (things like selecting text will likely
- be slower).
-
- "t1+t2+t3" specify three floating point times in
- seconds that apply to scrollcopyrect detection with
- *Keystroke* input: t1 is how long to wait after a key
- is pressed for the first scroll, t2 is how long to keep
- looking after a Keystroke scroll for more scrolls.
- t3 is how frequently to try to update surrounding
- scrollbars outside of the scrolling area (0.0 to
- disable)
-
- "s1+s2+s3+s4+s5" specify five floating point times
- in seconds that apply to scrollcopyrect detection with
- *Mouse* input: s1 is how long to wait after a mouse
- button is pressed for the first scroll, s2 is how long
- to keep waiting for additional scrolls after the first
- Mouse scroll was detected. s3 is how frequently to
- try to update surrounding scrollbars outside of the
- scrolling area (0.0 to disable). s4 is how long to
- buffer pointer motion (to try to get fewer, bigger
- mouse scrolls). s5 is the maximum time to spend just
- updating the scroll window without updating the rest
- of the screen.
-
--fixscreen string Periodically "repair" the screen based on settings
- in "string". Hopefully you won't need this option,
- it is intended for cases when the -scrollcopyrect or
- -wirecopyrect features leave too many painting errors,
- but it can be used for any scenario. This option
- periodically performs costly operations and so
- interactive response may be reduced when it is on.
- You can use 3 Alt_L's (the Left "Alt" key) taps in
- a row (as described under -scrollcopyrect) instead to
- manually request a screen repaint when it is needed.
-
- "string" is a comma separated list of one or more of
- the following: "V=t", "C=t", "X=t", and "8=t".
- In these "t" stands for a time in seconds (it is
- a floating point even though one should usually use
- values > 2 to avoid wasting resources). V sets how
- frequently the entire screen should be sent to viewers
- (it is like the 3 Alt_L's). C sets how long to wait
- after a CopyRect to repaint the full screen. X sets
- how frequently to reread the full X11 framebuffer from
- the X server and push it out to connected viewers.
- Use of X should be rare, please report a bug if you
- find you need it. 8= applies only for -8to24 mode: it
- sets how often the non-default visual regions of the
- screen (e.g. 8bpp windows) are refreshed. Examples:
- -fixscreen V=10 -fixscreen C=10
-
--debug_scroll Turn on debugging info printout for the scroll
- heuristics. "-ds" is an alias. Specify it multiple
- times for more output.
-
--noxrecord Disable any use of the RECORD extension. This is
- currently used by the -scrollcopyrect scheme and to
- monitor X server grabs.
-
--grab_buster Some of the use of the RECORD extension can leave a
--nograb_buster tiny window for XGrabServer deadlock. This is only if
- the whole-server grabbing application expects mouse or
- keyboard input before releasing the grab. It is usually
- a window manager that does this. x11vnc takes care to
- avoid the problem, but if caught x11vnc will freeze.
- Without -grab_buster, the only solution is to go the
- physical display and give it some input to satisfy the
- grabbing app. Or manually kill and restart the window
- manager if that is feasible. With -grab_buster, x11vnc
- will fork a helper thread and if x11vnc appears to be
- stuck in a grab after a period of time (20-30 sec) then
- it will inject some user input: button clicks, Escape,
- mouse motion, etc to try to break the grab. If you
- experience a lot of grab deadlock, please report a bug.
-
--debug_grabs Turn on debugging info printout with respect to
- XGrabServer() deadlock for -scrollcopyrect mode.
-
--debug_sel Turn on debugging info printout with respect to
- PRIMARY, CLIPBOARD, and CUTBUFFER0 selections.
-
--pointer_mode n Various pointer motion update schemes. "-pm" is
- an alias. The problem is pointer motion can cause
- rapid changes on the screen: consider the rapid
- changes when you drag a large window around opaquely.
- Neither x11vnc's screen polling and vnc compression
- routines nor the bandwidth to the vncviewers can keep
- up these rapid screen changes: everything will bog down
- when dragging or scrolling. So a scheme has to be used
- to "eat" much of that pointer input before re-polling
- the screen and sending out framebuffer updates. The
- mode number "n" can be 0 to 4 and selects one of
- the schemes desribed below.
-
- Note that the -wireframe and -scrollcopyrect modes
- complement -pointer_mode by detecting (and improving)
- certain periods of "rapid screen change".
-
- n=0: does the same as -nodragging. (all screen polling
- is suspended if a mouse button is pressed.)
-
- n=1: was the original scheme used to about Jan 2004:
- it basically just skips -input_skip keyboard or pointer
- events before repolling the screen.
-
- n=2 is an improved scheme: by watching the current rate
- of input events it tries to detect if it should try to
- "eat" additional pointer events before continuing.
-
- n=3 is basically a dynamic -nodragging mode: it detects
- when the mouse motion has paused and then refreshes
- the display.
-
- n=4 attempts to measures network rates and latency,
- the video card read rate, and how many tiles have been
- changed on the screen. From this, it aggressively tries
- to push screen "frames" when it decides it has enough
- resources to do so. NOT FINISHED.
-
- The default n is 2. Note that modes 2, 3, 4 will skip
- -input_skip keyboard events (but it will not count
- pointer events). Also note that these modes are not
- available in -threads mode which has its own pointer
- event handling mechanism.
-
- To try out the different pointer modes to see which
- one gives the best response for your usage, it is
- convenient to use the remote control function, for
- example "x11vnc -R pm:4" or the tcl/tk gui (Tuning ->
- pointer_mode -> n).
-
--input_skip n For the pointer handling when non-threaded: try to
- read n user input events before scanning display. n < 0
- means to act as though there is always user input.
- Default: 10
-
--allinput Have x11vnc read and process all available client input
- before proceeding.
-
--input_eagerly Similar to -allinput but use the handleEventsEagerly
- mechanism built into LibVNCServer.
-
--speeds rd,bw,lat x11vnc tries to estimate some speed parameters that
- are used to optimize scheduling (e.g. -pointer_mode
- 4, -wireframe, -scrollcopyrect) and other things.
- Use the -speeds option to set these manually.
- The triple "rd,bw,lat" corresponds to video h/w
- read rate in MB/sec, network bandwidth to clients in
- KB/sec, and network latency to clients in milliseconds,
- respectively. If a value is left blank, e.g. "-speeds
- ,100,15", then the internal scheme is used to estimate
- the empty value(s).
-
- Typical PC video cards have read rates of 5-10 MB/sec.
- If the framebuffer is in main memory instead of video
- h/w (e.g. SunRay, shadowfb, dummy driver, Xvfb), the
- read rate may be much faster. "x11perf -getimage500"
- can be used to get a lower bound (remember to factor
- in the bytes per pixel). It is up to you to estimate
- the network bandwith and latency to clients. For the
- latency the ping(1) command can be used.
-
- For convenience there are some aliases provided,
- e.g. "-speeds modem". The aliases are: "modem" for
- 6,4,200; "dsl" for 6,100,50; and "lan" for 6,5000,1
-
--wmdt string For some features, e.g. -wireframe and -scrollcopyrect,
- x11vnc has to work around issues for certain window
- managers or desktops (currently kde and xfce).
- By default it tries to guess which one, but it can
- guess incorrectly. Use this option to indicate which
- wm/dt. "string" can be "gnome", "kde", "cde",
- "xfce", or "root" (classic X wm). Anything else
- is interpreted as "root".
-
--debug_pointer Print debugging output for every pointer event.
--debug_keyboard Print debugging output for every keyboard event.
- Same as -dp and -dk, respectively. Use multiple
- times for more output.
-
--defer time Time in ms to delay sending updates to connected clients
- (deferUpdateTime) Default: 20
-
--wait time Time in ms to pause between screen polls. Used to cut
- down on load. Default: 20
-
--extra_fbur n Perform extra FrameBufferUpdateRequests checks to
- try to be in better sync with the client's requests.
- What this does is perform extra polls of the client
- socket at critical times (before '-defer' and '-wait'
- calls.) The default is n=1. Set to a larger number to
- insert more checks or set to n=0 to disable. A downside
- of these extra calls is that more mouse input may be
- processed than desired.
-
--wait_ui factor Factor by which to cut the -wait time if there
- has been recent user input (pointer or keyboard).
- Improves response, but increases the load whenever you
- are moving the mouse or typing. Default: 2.00
--setdefer n When the -wait_ui mechanism cuts down the wait time ms,
- set the defer time to the same ms value. n=1 to enable,
- 0 to disable, and -1 to set defer to 0 (no delay).
- Similarly, 2 and -2 indicate 'urgent_update' mode should
- be used to push the updates even sooner. Default: 1
--nowait_bog Do not detect if the screen polling is "bogging down"
- and sleep more. Some activities with no user input can
- slow things down a lot: consider a large terminal window
- with a long build running in it continuously streaming
- text output. By default x11vnc will try to detect this
- (3 screen polls in a row each longer than 0.25 sec with
- no user input), and sleep up to 1.5 secs to let things
- "catch up". Use this option to disable that detection.
--slow_fb time Floating point time in seconds to delay all screen
- polling. For special purpose usage where a low frame
- rate is acceptable and desirable, but you want the
- user input processed at the normal rate so you cannot
- use -wait.
--xrefresh time Floating point time in seconds to indicate how often to
- do the equivalent of xrefresh(1) to force all windows
- (in the viewable area if -id, -sid, or -clip is used)
- to repaint themselves. Use this only if applications
- misbehave by not repainting themselves properly.
- See also -noxdamage.
--nap Monitor activity and if it is low take longer naps
--nonap between screen polls to really cut down load when idle.
- Default: take naps
--sb time Time in seconds after NO activity (e.g. screen blank)
- to really throttle down the screen polls (i.e. sleep
- for about 1.5 secs). Use 0 to disable. Default: 60
- Set the env. var. X11VNC_SB_FACTOR to scale it.
-
--readtimeout n Set LibVNCServer rfbMaxClientWait to n seconds. On
- slow links that take a long time to paint the first
- screen LibVNCServer may hit the timeout and drop the
- connection. Default: 20 seconds.
--ping n Send a 1x1 framebuffer update to all clients every n
- seconds (e.g. to try to keep a network connection alive)
-
--nofbpm If the system supports the FBPM (Frame Buffer Power
--fbpm Management) extension (i.e. some Sun systems), then
- prevent the video h/w from going into a reduced power
- state when VNC clients are connected.
-
- FBPM capable video h/w save energy when the workstation
- is idle by going into low power states (similar to DPMS
- for monitors). This interferes with x11vnc's polling
- of the framebuffer data.
-
- "-nofbpm" means prevent FBPM low power states whenever
- VNC clients are connected, while "-fbpm" means to not
- monitor the FBPM state at all. See the xset(1) manpage
- for details. -nofbpm is basically the same as running
- "xset fbpm force on" periodically. Default: -fbpm
-
--nodpms If the system supports the DPMS (Display Power Managemen
-t
--dpms Signaling) extension, then prevent the monitor from
- going into a reduced power state when VNC clients
- are connected.
-
- DPMS reduced power monitor states are a good thing
- and you normally want the power down to take place
- (usually x11vnc has no problem exporting the display in
- this state). You probably only want to use "-nodpms"
- to work around problems with Screen Savers kicking
- on in DPMS low power states. There is known problem
- with kdesktop_lock on KDE where the screen saver keeps
- kicking in every time user input stops for a second
- or two. Specifying "-nodpms" works around it.
-
- "-nodpms" means prevent DPMS low power states whenever
- VNC clients are connected, while "-dpms" means to not
- monitor the DPMS state at all. See the xset(1) manpage
- for details. -nodpms is basically the same as running
- "xset dpms force on" periodically. Default: -dpms
-
--forcedpms If the system supports the DPMS (Display Power
- Management Signaling) extension, then try to keep the
- monitor in a powered off state. This is to prevent
- nosey people at the physical display from viewing what
- is on the screen. Be sure to lock the screen before
- disconnecting.
-
- This method is far from bullet proof, e.g. suppose
- someone attaches a non-DPMS monitor, or loads the
- machine so that there is a gap of time before x11vnc
- restores the powered off state? On many machines if
- he floods it with keyboard and mouse input he can see
- flashes of what is on the screen before the DPMS off
- state is reestablished. For this to work securely
- there would need to be support in the X server to do
- this exactly rather than approximately with DPMS.
-
--clientdpms As -forcedpms but only when VNC clients are connected.
-
--noserverdpms The UltraVNC ServerInput extension is supported.
- This allows the VNC viewer to click a button that will
- cause the server (x11vnc) to try to disable keyboard
- and mouse input at the physical display and put the
- monitor in dpms powered off state. Use this option to
- skip powering off the monitor.
-
--noultraext Disable the following UltraVNC extensions: SingleWindow
- and ServerInput. The others managed by LibVNCServer
- (textchat, 1/n scaling, rfbEncodingUltra) are not.
-
--chatwindow Place a local UltraVNC chat window on the X11 display
- that x11vnc is polling. That way the person on the VNC
- viewer-side can chat with the person at the physical
- X11 console. (e.g. helpdesk w/o telephone)
-
- For this to work the SSVNC package (version 1.0.21 or
- later) MUST BE installed on the system where x11vnc runs
- and the 'ssvnc' command must be available in $PATH.
- The ssvncviewer is used as a chat window helper.
- See http://www.karlrunge.com/x11vnc/ssvnc.html
-
- This option implies '-rfbversion 3.6' so as to trick
- UltraVNC viewers, otherwise they assume chat is not
- available. To specify a different rfbversion, place
- it after the -chatwindow option on the cmdline.
-
- See also the remote control 'chaton' and 'chatoff'
- actions. These can also be set from the tkx11vnc GUI.
-
--noxdamage Do not use the X DAMAGE extension to detect framebuffer
- changes even if it is available. Use -xdamage if your
- default is to have it off.
-
- x11vnc's use of the DAMAGE extension: 1) significantly
- reduces the load when the screen is not changing much,
- and 2) detects changed areas (small ones by default)
- more quickly.
-
- Currently the DAMAGE extension is overly conservative
- and often reports large areas (e.g. a whole terminal
- or browser window) as damaged even though the actual
- changed region is much smaller (sometimes just a few
- pixels). So heuristics were introduced to skip large
- areas and use the damage rectangles only as "hints"
- for the traditional scanline polling. The following
- tuning parameters are introduced to adjust this
- behavior:
-
--xd_area A Set the largest DAMAGE rectangle area "A" (in
- pixels: width * height) to trust as truly damaged:
- the rectangle will be copied from the framebuffer
- (slow) no matter what. Set to zero to trust *all*
- rectangles. Default: 20000
--xd_mem f Set how long DAMAGE rectangles should be "remembered",
- "f" is a floating point number and is in units of the
- scanline repeat cycle time (32 iterations). The default
- (1.0) should give no painting problems. Increase it if
- there are problems or decrease it to live on the edge
- (perhaps useful on a slow machine).
-
--sigpipe string Broken pipe (SIGPIPE) handling. "string" can be
- "ignore" or "exit". For "ignore" LibVNCServer
- will handle the abrupt loss of a client and continue,
- for "exit" x11vnc will cleanup and exit at the 1st
- broken connection.
-
- This option is not really needed since LibVNCServer
- is doing the correct thing now for quite some time.
- However, for convenience you can use it to ignore other
- signals, e.g. "-sigpipe ignore:HUP,INT,TERM" in case
- that would be useful for some sort of application.
- You can also put "exit:.." in the list to have x11vnc
- cleanup on the listed signals. "-sig" is an alias
- for this option if you don't like the 'pipe'. Example:
- -sig ignore:INT,TERM,exit:USR1
-
--threads Whether or not to use the threaded LibVNCServer
--nothreads algorithm [rfbRunEventLoop] if libpthread is available.
- In this mode new threads (one for input and one
- for output) are created to handle each new client.
- Default: -nothreads.
-
- Thread stability is much improved in version 0.9.8.
-
- Multiple clients in threaded mode should be stable
- for the ZRLE encoding on all platforms. The Tight and
- Zlib encodings are currently only stable on Linux for
- multiple clients. Compile with -DTLS=__thread if your
- OS and compiler and linker support it.
-
- For resizes (randr, etc.) set this env. var. to the numb
-er
- of milliseconds to sleep: X11VNC_THREADS_NEW_FB_SLEEP
- at various places in the do_new_fb() action. This is to
- let various activities settle. Default is about 500ms.
-
- Multiple clients in threaded mode could yield better
- performance for 'class-room' broadcasting usage; also in
- -appshare broadcast mode. See also the -reflect option.
-
--fs f If the fraction of changed tiles in a poll is greater
- than f, the whole screen is updated. Default: 0.75
--gaps n Heuristic to fill in gaps in rows or cols of n or
- less tiles. Used to improve text paging. Default: 4
--grow n Heuristic to grow islands of changed tiles n or wider
- by checking the tile near the boundary. Default: 3
--fuzz n Tolerance in pixels to mark a tiles edges as changed.
- Default: 2
--debug_tiles Print debugging output for tiles, fb updates, etc.
-
--snapfb Instead of polling the X display framebuffer (fb)
- for changes, periodically copy all of X display fb
- into main memory and examine that copy for changes.
- (This setting also applies for non-X -rawfb modes).
- Under some circumstances this will improve interactive
- response, or at least make things look smoother, but in
- others (most!) it will make the response worse. If the
- video h/w fb is such that reading small tiles is very
- slow this mode could help. To keep the "framerate"
- up the screen size x bpp cannot be too large. Note that
- this mode is very wasteful of memory I/O resources
- (it makes full screen copies even if nothing changes).
- It may be of use in video capture-like applications,
- webcams, or where window tearing is a problem.
-
--rawfb string Instead of polling X, poll the memory object specified
- in "string".
-
- 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).
-
- For shared memory segments string is of the form:
- "shm:N@WxHxB" which specifies a shmid N and with
- WxHxB as above. See shmat(1) and ipcs(1)
-
- If you do not supply a type "map" is assumed if
- the file exists (see the next paragraphs for some
- exceptions to this.)
-
- If string is "setup:cmd", then the command "cmd"
- is run and the first line from it is read and used
- as "string". This allows initializing the device,
- determining WxHxB, etc. These are often done as root
- so take care.
-
- If the string begins with "video", see the VIDEO4LINUX
- discussion below where the device may be queried for
- (and possibly set) the framebuffer parameters.
-
- 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 (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/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
- -rawfb map:/tmp/Xvfb_screen0@640x480x8+3232
- -rawfb file:/tmp/my.pnm@250x200x24+37
- -rawfb file:/dev/urandom@128x128x8
- -rawfb snap:/dev/video0@320x240x24 -24to32
- -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)
-
- In general all user input is discarded by default (see
- the -pipeinput option for how to use a helper program
- to insert). Most of the X11 (screen, keyboard, mouse)
- options do not make sense and many will cause this
- mode to crash, so please think twice before setting or
- changing them in a running x11vnc.
-
- If you DO NOT want x11vnc to close the X DISPLAY in
- rawfb mode, prepend a "+" e.g. +file:/dev/fb0...
- Keeping the display open enables the default
- remote-control channel, which could be useful.
- Alternatively, if you specify -noviewonly, then the
- mouse and keyboard input are STILL sent to the X
- display, this usage should be very rare, i.e. doing
- 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
- *every* snapfb snapshot, set the environment variable:
- SNAPFB_RAWFB_RESET=1 as well.
-
- If you want x11vnc to dynamically transform a 24bpp
- rawfb to 32bpp (note that this will be slower) also
- supply the -24to32 option. This would be useful for,
- 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.
-
- 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
- device itself. So if you do not supply "@WxHxB...
- parameters x11vnc will try to determine them. It first
- tries the v4l API if that support has been compiled in.
- Otherwise it will run the v4l-info(1) external program
- if it is available.
-
- The simplest examples are "-rawfb video" and "-rawfb
- video1" which imply the device file /dev/video and
- /dev/video1, respectively. You can also supply the
- /dev if you like, e.g. "-rawfb /dev/video0"
-
- Since the video capture device framebuffer usually
- changes continuously (e.g. brightness fluctuations),
- you may want to use the -wait, -slow_fb, or -defer
- options to lower the "framerate" to cut down on
- network VNC traffic.
-
- A more sophisticated video device scheme allows
- initializing the device's settings using:
-
- -rawfb video:<settings>
-
- The prefix could also be, as above, e.g. "video1:" to
- specify the device file. The v4l API must be available
- for this to work. Otherwise, you will need to try
- to initialize the device with an external program,
- e.g. xawtv, spcaview, and hope they persist when x11vnc
- re-opens the device.
-
- <settings> is a comma separated list of key=value pairs.
- The device's brightness, color, contrast, and hue can
- be set to percentages, e.g. br=80,co=50,cn=44,hu=60.
-
- The device filename can be set too if needed (if it
- does not start with "video"), e.g. fn=/dev/qcam.
-
- The width, height and bpp of the framebuffer can be
- set via, e.g., w=160,h=120,bpp=16.
-
- Related to the bpp above, the pixel format can be set
- via the fmt=XXX, where XXX can be one of: GREY, HI240,
- RGB555, RGB565, RGB24, and RGB32 (with bpp 8, 8, 16, 16,
- 24, and 32 respectively). See http://www.linuxtv.org
- for more info (V4L api).
-
- For TV/rf tuner cards one can set the tuning mode
- via tun=XXX where XXX can be one of PAL, NTSC, SECAM,
- or AUTO.
-
- One can switch the input channel by the inp=XXX setting,
- where XXX is the name of the input channel (Television,
- Composite1, S-Video, etc). Use the name that is in the
- information about the device that is printed at startup.
-
- For input channels with tuners (e.g. Television) one
- can change which station is selected by the sta=XXX
- setting. XXX is the station number. Currently only
- the ntsc-cable-us (US cable) channels are built into
- x11vnc. See the -freqtab option below to supply one
- from xawtv. If XXX is greater than 500, then it is
- interpreted as a raw frequency in KHz.
-
- Example:
-
- -rawfb video:br=80,w=320,h=240,fmt=RGB32,tun=NTSC,sta=47
-
- one might need to add inp=Television too for the input
- channel to be TV if the card doesn't come up by default
- in that one.
-
- Note that not all video capture devices will support
- all of the above settings.
-
- See the -pipeinput VID option below for a way to control
- the settings through the VNC Viewer via keystrokes.
- As a shortcut, if the string begins "Video.." instead
- of "video.." then -pipeinput VID is implied.
-
- As above, if you specify a "@WxHxB..." after the
- <settings> string they are used verbatim: the device
- is not queried for the current values. Otherwise the
- device will be queried.
-
- 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 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, 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. It also provides more accurate
- keystroke insertion. 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
- framebuffer device, e.g. /dev/fb1. As a shortcut the
- "/dev/" can be dropped. If the name is something
- nonstandard, use "console:/dev/foofb"
-
- If you do not want x11vnc to guess the framebuffer's
- WxHxB and masks automatically (sometimes the kernel
- gives incorrect information), specify them with a @WxHxB
- (and optional :R/G/B masks) at the end of the string.
-
- Examples:
- -rawfb console
- -rawfb /dev/fb0 (same)
- -rawfb console3 (force /dev/tty3)
- -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
- VNC server "host" is connected to (i.e. x11vnc acts as
- a VNC client itself) and that framebuffer is exported.
-
- This mode is really only of use if you are trying
- to improve performance in the case of many (e.g. >
- 10) simultaneous VNC viewers, and you try a divide
- and conquer scheme to reduce bandwidth and improve
- responsiveness. (However, another user found this mode
- useful to export a demo display through a slow link:
- then multiple demo viewers connected to the reflecting
- x11vnc on the fast side of the link, and so avoided
- all of the demo viewers going through the slow link.)
-
- For example, if there will be 64 simultaneous VNC
- viewers this can lead to a lot of redundant VNC traffic
- to and from the server host:N, extra CPU usage,
- and all viewers response can be reduced by having
- to wait for writes to the slowest client to finish.
- However, if you set up 8 reflectors/repeaters started
- with option -rawfb vnc:host:N, then there are only
- 8 connections to host:N. Each repeater then handles
- 8 vnc viewer connections thereby spreading the load
- around. In classroom broadcast usage, try to put the
- repeaters on different switches. This mode is the same
- as -reflect host:N. Replace "host:N" by "listen"
- or "listen:port" for a reverse connection.
-
- Overall performance will not be as good as a single
- direct connection because, among other things,
- there is an additional level of framebuffer polling
- and pointer motion can still induce many changes per
- second that must be propagated. Tip: if the remote VNC
- is x11vnc doing wireframing, or an X display that does
- wireframing that gives much better response than opaque
- window dragging. Consider the -nodragging option if
- the problem is severe.
-
- The env. var. X11VNC_REFLECT_PASSWORD can be set to
- the password needed to log into the vnc host server, or
- to "file:path_to_file" to indicate a file containing
- the password as its first line.
-
- To set the pixel format that x11vnc requests as a VNC
- CLIENT set the env. vars: X11VNC_REFLECT_bitsPerSample
- X11VNC_REFLECT_samplesPerPixel, and
- X11VNC_REFLECT_bytesPerPixel; the defaults are 8, 3, 4.
- 2, 3, 1 would give a low color mode. See the function
- rfbGetClient() in libvncclient for more info.
-
- The VNC HOST mode implies -shared. Use -noshared as
- a subsequent cmdline option to disable sharing.
-
--freqtab file For use with "-rawfb video" for TV tuner devices to
- specify station frequencies. Instead of using the built
- in ntsc-cable-us mapping of station number to frequency,
- use the data in file. For stations that are not
- numeric, e.g. SE20, they are placed above the highest
- numbered station in the order they are found. Example:
- "-freqtab /usr/X11R6/share/xawtv/europe-west.list"
- You can make your own freqtab by copying the xawtv
- format.
-
--pipeinput cmd This option lets you supply an external command in
- "cmd" that x11vnc will pipe all of the user input
- events to in a simple format. In -pipeinput mode by
- default x11vnc will not process any of the user input
- events. If you prefix "cmd" with "tee:" it will
- both send them to the pipe command and process them.
- For a description of the format run "-pipeinput
- tee:/bin/cat". Another prefix is "reopen" which
- means to reopen pipe if it exits. Separate multiple
- prefixes with commas.
-
- In combination with -rawfb one might be able to
- do amusing things (e.g. control non-X devices).
- To facilitate this, if -rawfb is in effect then the
- value is stored in X11VNC_RAWFB_STR for the pipe command
- to use if it wants. Do 'env | grep X11VNC' for more.
-
- Built-in pipeinput modes (no external program required):
-
- If cmd is "VID" and you are using the -rawfb for a
- video capture device, then an internal list of keyboard
- mappings is used to set parameters of the video.
- The mappings are:
-
- "B" and "b" adjust the brightness up and down.
- "H" and "h" adjust the hue.
- "C" and "c" adjust the colour.
- "N" and "n" adjust the contrast.
- "S" and "s" adjust the size of the capture screen.
- "I" and "i" cycle through input channels.
- Up and Down arrows adjust the station (if a tuner)
- F1, F2, ..., F6 will switch the video capture pixel
- format to HI240, RGB565, RGB24, RGB32, RGB555, and
- GREY respectively. See -rawfb video for details.
-
- If cmd is "CONSOLE" or "CONSOLEn" where n
- is a Linux console number, then the linux console
- keystroke insertion to /dev/ttyN (see -rawfb console)
- is performed.
-
- If cmd begins with "UINPUT" then the Linux uinput
- module is used to insert both keystroke and mouse events
- to the Linux console (see -rawfb above). This usually
- is the /dev/input/uinput device file (you may need to
- create it with "mknod /dev/input/uinput c 10 223"
- and insert the module with "modprobe uinput".
-
- The UINPUT mode currently only does US keyboards (a
- scan code option may be added), and not all keysyms
- are supported. But it is probably more accurate than
- the "CONSOLE" method.
-
- You may want to use the options -cursor none and
- -nodragging in this mode.
-
- Additional tuning options may be supplied via:
- UINPUT:opt1,opt2,... (a comma separated list). If an
- option begins with "/" it is taken as the uinput
- device file.
-
- Which uinput is injected can be controlled by an option
- string made of the characters "K", "M", and "B"
- (see the -input option), e.g. "KM" allows keystroke
- and motion but not button clicks.
-
- A UINPUT option of the form: accel=f, or accel=fx+fy
- sets the mouse motion "acceleration". This is used
- to correct raw mouse relative motion into how much the
- application cursor moves (x11vnc has no control over,
- or knowledge of how the windowing application interprets
- the raw mouse motions). Typically the acceleration
- for an X display is 2 (see xset "m" option). "f"
- is a floating point number, e.g. 3.0. Use "fx+fy"
- if you need to supply different corrections for x and y.
-
- Note: the default acceleration is 2.0 since it seems
- both X and qt-embedded often (but not always) use
- this value.
-
- Even with a correct accel setting the mouse position
- will get out of sync (probably due to a mouse
- "threshold" setting where the acceleration doe not
- apply, set xset(1)). The option reset=N sets the
- number of ms (default 150) after which the cursor is
- attempted to be reset (by forcing the mouse to (0,
- 0) via small increments and then back out to (x, y)
- in 1 jump), This correction seems to be needed but can
- cause jerkiness or unexpected behavior with menus, etc.
- Use reset=0 to disable.
-
- If you set the env. var X11VNC_UINPUT_THRESHOLDS then
- the thresh=n mode will be enabled. It is currently
- not working well. If |dx| <= thresh and |dy| < thresh
- no acceleration is applied. Use "thresh=+n" |dx| +
- |dy| < thresh to be used instead (X11?)
-
- Example:
- -pipeinput UINPUT:accel=4.0 -cursor none
-
- If the uinput device has an absolute pointer (as opposed
- to a normal mouse that is a relative pointer) you can
- specify the option "abs". Note that a touchpad
- on a laptop is an absolute device to some degree.
- This (usually) avoids all the problems with mouse
- acceleration. If x11vnc has trouble deducing the
- size of the device, use "abs=WxH". Furthermore,
- if the device is a touchscreen (assumed to have an
- absolute pointer) use "touch" or "touch=WxH".
- For touchscreens, when a mouse button is pressed,
- a pressure increase is injected, and when the button
- is released a pressure of zero is injected.
-
- If touch has been set, use "touch_always=1" to
- indicate whenever the mouse moves with no button
- pressed, a touch event of zero pressure should be
- sent anyway. Also use "btn_touch=1" to indicate a
- BTN_TOUCH keystroke press or release should be sent
- instead of a pressure change. Set "dragskip=n" to
- skip n dragged mouse touches (with pressure applied)
- before injecting one. To indicate the pressure that
- should be sent when there is a button click for a
- touchscreen device, specify pressure=n, e.g. n=5. The
- default is n=1.
-
- If a touch screen is being used ("touch" above)
- and it is having its input processed by tslib, you can
- specify the tslib calibration file via tslib_cal=<file>.
- For example, tslib_cal=/etc/pointercal. To get accurate
- or even usable positioning this is required when tslib
- is in use.
-
- The Linux uinput mechanism can be bypassed and one can
- write input events DIRECTLY to the devices instead.
- To do this, specify one or more of the following
- for the input classes: direct_rel=<device>
- direct_abs=<device> direct_btn=<device> or
- direct_key=<device>. The <device> file is usually
- something like /dev/input/event1 but you can specify
- any device file or pipe. You must specify each one
- of the above classes even if they correspond to the
- same device file (rel/abs and btn are often the same.)
- Look at the file /proc/bus/input/devices to get an idea
- what is available and the device filenames. Note:
- The /dev/input/mouse* devices do not seem to work,
- use the corresponding /dev/input/event* file instead.
- Any input class not directly specified as above will be
- handled via the uinput mechanism. To disable creating a
- uinput device (and thereby discarding unhandled input),
- specify "nouinput".
-
- Examples:
-
- -pipeinput UINPUT:direct_abs=/dev/input/event1
-
- this was used on a qtmoko Neo freerunner (armel):
-
- -pipeinput UINPUT:touch,tslib_cal=/etc/pointercal,
- direct_abs=/dev/input/event1,nouinput,dragskip=4
-
- (where the long line has been split into two.)
-
- You can set the env. var X11VNC_UINPUT_DEBUG=1 or higher
- to get debugging output for UINPUT mode.
-
--macnodim For the native MacOSX server, disable dimming.
--macnosleep For the native MacOSX server, disable display sleep.
--macnosaver For the native MacOSX server, disable screensaver.
--macnowait For the native MacOSX server, do not wait for the
- user to switch back to his display.
--macwheel n For the native MacOSX server, set the mouse wheel
- speed to n (default 5).
--macnoswap For the native MacOSX server, do not swap mouse
- buttons 2 and 3.
--macnoresize For the native MacOSX server, do not resize or reset
- the framebuffer even if it is detected that the screen
- resolution or depth has changed.
--maciconanim n For the native MacOSX server, set n to the number
- of milliseconds that the window iconify/deiconify
- animation takes. In -ncache mode this value will be
- used to skip the animation if possible. (default 400)
--macmenu For the native MacOSX server, in -ncache client-side
- caching mode, try to cache pull down menus (not perfect
- because they have animated fades, etc.)
--macuskbd For the native MacOSX server, use the original
- keystroke insertion code based on a US keyboard.
--macnoopengl For the native MacOSX server, do not use OpenGL for
- screen capture, but rather use the original, deprecated
- raw memory access method: addr = CGDisplayBaseAddress().
--macnorawfb For the native MacOSX server, disable the raw memory
- address screen capture method.
-
- MACOSX NOTE: There are some deprecated MacOSX interfaces
- to inject keyboard and mouse events and the raw memory
- access method is deprecated as well (however, OpenGL
- will be preferred if available because it is faster.)
- One can force not using any deprecated interfaces at
- compile time by setting -DX11VNC_MACOSX_NO_DEPRECATED=1
- in CPPFLAGS. Or to turn them off one by one:
- -DX11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS=1,
- -DX11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS=1 or
- -DX11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER=1
- At run time, for testing and workarounds, one can
- disable them by using:
- -env X11VNC_MACOSX_NO_DEPRECATED=1
- -env X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS=1
- -env X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS=1 or
- -env X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER=1
- Note: When doing either of these for the mouse input
- not everything works currently, e.g. double clicks and
- wireframing. Also, screen resolution and pixel depth
- changes will not be automatically detected unless the
- deprecated framebuffer interfaces are allowed.
-
- Conversely, if you are compiling on an
- older machine that does not have some of
- the newer interfaces, you may need to specify
- -DX11VNC_MACOSX_NO_CGEVENTCREATESCROLLWHEELEVENT
- -DX11VNC_MACOSX_NO_CGEVENTCREATEMOUSEEVENT or
- -DX11VNC_MACOSX_NO_CGEVENTCREATEKEYBOARDEVENT. Use
- -DX11VNC_MACOSX_USE_GETMAINDEVICE to regain the very
- old QuickDraw GetMainDevice() interface (rare...)
-
--gui [gui-opts] Start up a simple tcl/tk gui based on the remote
- control options -remote/-query described below.
- Requires the "wish" program to be installed on the
- machine. "gui-opts" is not required: the default
- is to start up both the full gui and x11vnc with the
- gui showing up on the X display in the environment
- variable DISPLAY.
-
- "gui-opts" can be a comma separated list of items.
- Currently there are these types of items: 1) a gui
- mode, a 2) gui "simplicity", 3) the X display the
- gui should display on, 4) a "tray" or "icon" mode,
- and 5) a gui geometry.
-
- 1) The gui mode can be "start", "conn", or "wait"
- "start" is the default mode above and is not required.
- "conn" means do not automatically start up x11vnc,
- but instead just try to connect to an existing x11vnc
- process. "wait" means just start the gui and nothing
- else (you will later instruct the gui to start x11vnc
- or connect to an existing one.)
-
- 2) The gui simplicity is off by default (a power-user
- gui with all options is presented) To start with
- something less daunting supply the string "simple"
- ("ez" is an alias for this). Once the gui is
- started you can toggle between the two with "Misc ->
- simple_gui".
-
- 3) Note the possible confusion regarding the potentially
- two different X displays: x11vnc polls one, but you
- may want the gui to appear on another. For example, if
- you ssh in and x11vnc is not running yet you may want
- the gui to come back to you via your ssh redirected X
- display (e.g. localhost:10).
-
- If you do not specify a gui X display in "gui-opts"
- then the DISPLAY environment variable and -display
- option are tried (in that order). Regarding the x11vnc
- X display the gui will try to communication with, it
- first tries -display and then DISPLAY. For example,
- "x11vnc -display :0 -gui otherhost:0", will remote
- control an x11vnc polling :0 and display the gui on
- otherhost:0 The "tray/icon" mode below reverses this
- preference, preferring to display on the x11vnc display.
-
- 4) When "tray" or "icon" is specified, the gui
- presents itself as a small icon with behavior typical
- of a "system tray" or "dock applet". The color
- of the icon indicates status (connected clients) and
- there is also a balloon status. Clicking on the icon
- gives a menu from which properties, etc, can be set and
- the full gui is available under "Advanced". To be
- fully functional, the gui mode should be "start"
- (the default).
-
- Note that tray or icon mode will imply the -forever
- x11vnc option (if the x11vnc server is started along
- with the gui) unless -connect or -connect_or_exit has
- been specified. So x11vnc (and the tray/icon gui)
- will wait for more connections after the first client
- disconnects. If you want only one viewer connection
- include the -once option.
-
- For "icon" the gui just a small standalone window.
- For "tray" it will attempt to embed itself in the
- "system tray" if possible. If "=setpass" is appended the
-n
- at startup the X11 user will be prompted to set the
- VNC session password. If =<hexnumber> is appended
- that icon will attempt to embed itself in the window
- given by hexnumber. Use =noadvanced to disable the
- full gui. (To supply more than one, use "+" sign).
- E.g. -gui tray=setpass and -gui icon=0x3600028
-
- Other modes: "full", the default and need not be
- specified. "-gui none", do not show a gui, useful
- to override a ~/.x11vncrc setting, etc.
-
- 5) When "geom=+X+Y" is specified, that geometry
- is passed to the gui toplevel. This is the icon in
- icon/tray mode, or the full gui otherwise. You can
- also specify width and height, i.e. WxH+X+Y, but it
- is not recommended. In "tray" mode the geometry is
- ignored unless the system tray manager does not seem
- to be running. One could imagine using something like
- "-gui tray,geom=+4000+4000" with a display manager
- to keep the gui invisible until someone logs in...
-
- More icon tricks, "icon=minimal" gives an icon just
- with the VNC display number. You can also set the font
- with "iconfont=...". The following could be useful:
- "-gui icon=minimal,iconfont=5x8,geom=24x10+0-0"
-
- General examples of the -gui option: "x11vnc -gui",
- "x11vnc -gui ez" "x11vnc -gui localhost:10",
- "x11vnc -gui conn,host:0", "x11vnc -gui tray,ez"
- "x11vnc -gui tray=setpass"
-
- If you do not intend to start x11vnc from the gui
- (i.e. just remote control an existing one), then the
- gui process can run on a different machine from the
- x11vnc server as long as X permissions, etc. permit
- communication between the two.
-
- FONTS: On some systems the tk fonts can be too small,
- jagged, or otherwise unreadable. There are 4 env vars
- you can set to be the tk font you prefer:
-
- X11VNC_FONT_BOLD main font for menus and buttons.
- X11VNC_FONT_FIXED font for fixed width text.
-
- X11VNC_FONT_BOLD_SMALL tray icon font.
- X11VNC_FONT_REG_SMALL tray icon menu font.
-
- The last two only apply for the tray icon mode.
-
- Here are some examples:
-
- -env X11VNC_FONT_BOLD='Helvetica -16 bold'
- -env X11VNC_FONT_FIXED='Courier -14'
- -env X11VNC_FONT_REG_SMALL='Helvetica -12'
-
- You can put the lines like the above (without the
- quotes) in your ~/.x11vncrc file to avoid having to
- specify them on the x11vnc command line.
-
--remote command Remotely control some aspects of an already running
- x11vnc server. "-R" and "-r" are aliases for
- "-remote". After the remote control command is
- sent to the running server the 'x11vnc -remote ...'
- x11vnc command exits. You can often use the -query
- command (see below) to see if the x11vnc server
- processed your -remote command.
-
- The default communication channel is that of X
- properties (specifically X11VNC_REMOTE), and so this
- command must be run with correct settings for DISPLAY
- and possibly XAUTHORITY to connect to the X server
- and set the property. Alternatively, use the -display
- and -auth options to set them to the correct values.
- The running server cannot use the -novncconnect option
- because that disables the communication channel.
- See below for alternate channels.
-
- For example: 'x11vnc -remote stop' (which is the same as
- 'x11vnc -R stop') will close down the x11vnc server.
- 'x11vnc -R shared' will enable shared connections, and
- 'x11vnc -R scale:3/4' will rescale the desktop.
-
- To use a different name for the X11 property (e.g. to
- have separate communication channels for multiple
- x11vnc's on the same display) set the X11VNC_REMOTE
- environment variable to the string you want, for
- example: -env X11VNC_REMOTE=X11VNC_REMOTE_12345
- Both sides of the channel must use the same unique name.
-
- To run a bunch of commands in a sequence use something
- like: x11vnc -R 'script:firstcmd;secondcmd;...'
-
- Use x11vnc -R script:file=/path/to/file to read commands
- from a file (can be multi-line and use the comment '#'
- character in the normal way. The ';' separator must
- still be used to separate each command.)
-
- To not try to contact another x11vnc process and instead
- just run the command (or query) directly, prefix the
- command with the string "DIRECT:"
-
- The following -remote/-R commands are supported:
-
- stop terminate the server, same as "quit"
- "exit" or "shutdown".
- ping see if the x11vnc server responds.
- return is: ans=ping:<display>
- ping:mystring as above, but use your own unique string
-.
- return is: ans=ping:mystring:<xdisplay>
- blacken try to push a black fb update to all
- clients (due to timings a client
- could miss it). Same as "zero", also
- "zero:x1,y1,x2,y2" for a rectangle.
- refresh send the entire fb to all clients.
- reset recreate the fb, polling memory, etc.
- id:windowid set -id window to "windowid". empty
- or "root" to go back to root window
- sid:windowid set -sid window to "windowid"
- id_cmd:cmd cmds: raise, lower, map, unmap, iconify,
- move:dXdY, resize:dWdH, geom:WxH+X+Y. dX
- dY, dW, and dH must have a leading "+"
- or "-" e.g.: move:-30+10 resize:+20+35
- also: wm_delete, wm_name:string and
- icon_name:string. Also id_cmd:win=N:cmd
- waitmapped wait until subwin is mapped.
- nowaitmapped do not wait until subwin is mapped.
- clip:WxH+X+Y set -clip mode to "WxH+X+Y"
- flashcmap enable -flashcmap mode.
- noflashcmap disable -flashcmap mode.
- shiftcmap:n set -shiftcmap to n.
- notruecolor enable -notruecolor mode.
- truecolor disable -notruecolor mode.
- overlay enable -overlay mode (if applicable).
- nooverlay disable -overlay mode.
- overlay_cursor in -overlay mode, enable cursor drawing.
- overlay_nocursor disable cursor drawing. same as
- nooverlay_cursor.
- 8to24 enable -8to24 mode (if applicable).
- no8to24 disable -8to24 mode.
- 8to24_opts:str set the -8to24 opts to "str".
- 24to32 enable -24to32 mode (if applicable).
- no24to32 disable -24to32 mode.
- visual:vis set -visual to "vis"
- scale:frac set -scale to "frac"
- scale_cursor:f set -scale_cursor to "f"
- viewonly enable -viewonly mode.
- noviewonly disable -viewonly mode.
- shared enable -shared mode.
- noshared disable -shared mode.
- forever enable -forever mode.
- noforever disable -forever mode.
- timeout:n reset -timeout to n, if there are
- currently no clients, exit unless one
- connects in the next n secs.
- tightfilexfer enable filetransfer for NEW clients.
- notightfilexfer disable filetransfer for NEW clients.
- ultrafilexfer enable filetransfer for clients.
- noultrafilexfer disable filetransfer for clients.
- rfbversion:n.m set -rfbversion for new clients.
- http enable http client connections.
- nohttp disable http client connections.
- deny deny any new connections, same as "lock"
- nodeny allow new connections, same as "unlock"
- avahi enable avahi service advertising.
- noavahi disable avahi service advertising.
- mdns enable avahi service advertising.
- nomdns disable avahi service advertising.
- zeroconf enable avahi service advertising.
- nozeroconf disable avahi service advertising.
- connect:host do reverse connection to host, "host"
- may be a comma separated list of hosts
- or host:ports. See -connect. Passwords
- required as with fwd connections.
- See X11VNC_REVERSE_CONNECTION_NO_AUTH=1
- disconnect:host disconnect any clients from "host"
- same as "close:host". Use host
- "all" to close all current clients.
- If you know the client internal hex ID,
- e.g. 0x3 (returned by "-query clients"
- and RFB_CLIENT_ID) you can use that too.
- proxy:host:port set reverse connection proxy (empty to
- disable).
- allowonce:host For the next connection only, allow
- connection from "host". In -ssl mode
- two connections are allowed (i.e. Fetch
- Cert) unless X11VNC_NO_SSL_ALLOW_TWICE=1
- allow:hostlist set -allow list to (comma separated)
- "hostlist". See -allow and -localhost.
- Do not use with -allow /path/to/file
- Use "+host" to add a single host, and
- use "-host" to delete a single host
- localhost enable -localhost mode
- nolocalhost disable -localhost mode
- listen:str set -listen to str, empty to disable.
- noipv6 enable -noipv6 mode.
- ipv6 disable -noipv6 mode.
- noipv4 enable -noipv4 mode.
- ipv4 disable -noipv4 mode.
- 6 enable -6 IPv6 listening mode.
- no6 disable -6 IPv6 listening mode.
- lookup disable -nolookup mode.
- nolookup enable -nolookup mode.
- lookup disable -nolookup mode.
- input:str set -input to "str", empty to disable.
- grabkbd enable -grabkbd mode.
- nograbkbd disable -grabkbd mode.
- grabptr enable -grabptr mode.
- nograbptr disable -grabptr mode.
- grabalways enable -grabalways mode.
- nograbalways disable -grabalways mode.
- grablocal:n set -grablocal to n.
- client_input:str set the K, M, B -input on a per-client
- basis. select which client as for
- disconnect, e.g. client_input:host:MB
- or client_input:0x2:K
- accept:cmd set -accept "cmd" (empty to disable).
- afteraccept:cmd set -afteraccept (empty to disable).
- gone:cmd set -gone "cmd" (empty to disable).
- noshm enable -noshm mode.
- shm disable -noshm mode (i.e. use shm).
- flipbyteorder enable -flipbyteorder mode, you may need
- to set noshm for this to do something.
- noflipbyteorder disable -flipbyteorder mode.
- onetile enable -onetile mode. (you may need to
- set shm for this to do something)
- noonetile disable -onetile mode.
- solid enable -solid mode
- nosolid disable -solid mode.
- solid_color:color set -solid color (and apply it).
- blackout:str set -blackout "str" (empty to disable).
- See -blackout for the form of "str"
- (basically: WxH+X+Y,...)
- Use "+WxH+X+Y" to append a single
- rectangle use "-WxH+X+Y" to delete one
- xinerama enable -xinerama mode. (if applicable)
- noxinerama disable -xinerama mode.
- xtrap enable -xtrap input mode(if applicable)
- noxtrap disable -xtrap input mode.
- xrandr enable -xrandr mode. (if applicable)
- noxrandr disable -xrandr mode.
- xrandr_mode:mode set the -xrandr mode to "mode".
- rotate:mode set the -rotate mode to "mode".
- padgeom:WxH set -padgeom to WxH (empty to disable)
- If WxH is "force" or "do" the padded
- geometry fb is immediately applied.
- quiet enable -quiet mode.
- noquiet disable -quiet mode.
- modtweak enable -modtweak mode.
- nomodtweak enable -nomodtweak mode.
- xkb enable -xkb modtweak mode.
- noxkb disable -xkb modtweak mode.
- capslock enable -capslock mode.
- nocapslock disable -capslock mode.
- skip_lockkeys enable -skip_lockkeys mode.
- noskip_lockkeys disable -skip_lockkeys mode.
- skip_keycodes:str enable -xkb -skip_keycodes "str".
- sloppy_keys enable -sloppy_keys mode.
- nosloppy_keys disable -sloppy_keys mode.
- skip_dups enable -skip_dups mode.
- noskip_dups disable -skip_dups mode.
- add_keysyms enable -add_keysyms mode.
- noadd_keysyms stop adding keysyms. those added will
- still be removed at exit.
- clear_mods enable -clear_mods mode and clear them.
- noclear_mods disable -clear_mods mode.
- clear_keys enable -clear_keys mode and clear them.
- noclear_keys disable -clear_keys mode.
- clear_locks do the clear_locks action.
- clear_all do the clear_all action.
- keystate have x11vnc print current keystate.
- remap:str set -remap "str" (empty to disable).
- See -remap for the form of "str"
- (basically: key1-key2,key3-key4,...)
- Use "+key1-key2" to append a single
- keymapping, use "-key1-key2" to delete.
- norepeat enable -norepeat mode.
- repeat disable -norepeat mode.
- nofb enable -nofb mode.
- fb disable -nofb mode.
- bell enable bell (if supported).
- nobell disable bell.
- sendbell ring the bell now.
- nosel enable -nosel mode.
- sel disable -nosel mode.
- noprimary enable -noprimary mode.
- primary disable -noprimary mode.
- nosetprimary enable -nosetprimary mode.
- setprimary disable -nosetprimary mode.
- noclipboard enable -noclipboard mode.
- clipboard disable -noclipboard mode.
- nosetclipboard enable -nosetclipboard mode.
- setclipboard disable -nosetclipboard mode.
- seldir:str set -seldir to "str"
- resend_cutbuffer resend the most recent CUTBUFFER0 copy
- resend_clipboard resend the most recent CLIPBOARD copy
- resend_primary resend the most recent PRIMARY copy
- cursor:mode enable -cursor "mode".
- show_cursor enable showing a cursor.
- noshow_cursor disable showing a cursor. (same as
- "nocursor")
- cursor_drag enable cursor changes during drag.
- nocursor_drag disable cursor changes during drag.
- arrow:n set -arrow to alternate n.
- xfixes enable xfixes cursor shape mode.
- noxfixes disable xfixes cursor shape mode.
- alphacut:n set -alphacut to n.
- alphafrac:f set -alphafrac to f.
- alpharemove enable -alpharemove mode.
- noalpharemove disable -alpharemove mode.
- alphablend disable -noalphablend mode.
- noalphablend enable -noalphablend mode.
- cursorshape disable -nocursorshape mode.
- nocursorshape enable -nocursorshape mode.
- cursorpos disable -nocursorpos mode.
- nocursorpos enable -nocursorpos mode.
- xwarp enable -xwarppointer mode.
- noxwarp disable -xwarppointer mode.
- always_inject enable -always_inject mode.
- noalways_inject disable -always_inject mode.
- buttonmap:str set -buttonmap "str", empty to disable
- dragging disable -nodragging mode.
- nodragging enable -nodragging mode.
- ncache reenable -ncache mode.
- noncache disable -ncache mode.
- ncache_size:n set -ncache size to n.
- ncache_cr enable -ncache_cr mode.
- noncache_cr disable -ncache_cr mode.
- ncache_no_moveraise enable no_moveraise mode.
- noncache_no_moveraise disable no_moveraise mode.
- ncache_no_dtchange enable ncache_no_dtchange mode.
- noncache_no_dtchange disable ncache_no_dtchange mode.
- ncache_old_wm enable ncache_old_wm mode.
- noncache_old_wm disable ncache_old_wm mode.
- ncache_no_rootpixmap enable ncache_no_rootpixmap.
- noncache_no_rootpixmap disable ncache_no_rootpixmap.
- ncache_reset_rootpixmap recheck the root pixmap, ncrp
- ncache_keep_anims enable ncache_keep_anims.
- noncache_keep_anims disable ncache_keep_anims.
- ncache_pad:n set -ncache_pad to n.
- wireframe enable -wireframe mode. same as "wf"
- nowireframe disable -wireframe mode. same as "nowf"
- wireframe:str enable -wireframe mode string.
- wireframe_mode:str enable -wireframe mode string.
- wireframelocal enable wireframelocal. same as "wfl"
- nowireframe disable wireframelocal. same as "nowfl"
- wirecopyrect:str set -wirecopyrect string. same as "wcr:
-"
- scrollcopyrect:str set -scrollcopyrect string. same "scr
-"
- noscrollcopyrect disable -scrollcopyrect mode. "noscr"
- scr_area:n set -scr_area to n
- scr_skip:list set -scr_skip to "list"
- scr_inc:list set -scr_inc to "list"
- scr_keys:list set -scr_keys to "list"
- scr_term:list set -scr_term to "list"
- scr_keyrepeat:str set -scr_keyrepeat to "str"
- scr_parms:str set -scr_parms parameters.
- fixscreen:str set -fixscreen to "str".
- noxrecord disable all use of RECORD extension.
- xrecord enable use of RECORD extension.
- reset_record reset RECORD extension (if avail.)
- pointer_mode:n set -pointer_mode to n. same as "pm"
- input_skip:n set -input_skip to n.
- allinput enable use of -allinput mode.
- noallinput disable use of -allinput mode.
- input_eagerly enable use of -input_eagerly mode.
- noinput_eagerly disable use of -input_eagerly mode.
- ssltimeout:n set -ssltimeout to n.
- speeds:str set -speeds to str.
- wmdt:str set -wmdt to str.
- debug_pointer enable -debug_pointer, same as "dp"
- nodebug_pointer disable -debug_pointer, same as "nodp"
- debug_keyboard enable -debug_keyboard, same as "dk"
- nodebug_keyboard disable -debug_keyboard, same as "nodk"
- keycode:n inject keystroke 'keycode' (xmodmap -pk)
- keycode:n,down inject 'keycode' (down=0,1)
- keysym:str inject keystroke 'keysym' (number/name)
- keysym:str,down inject 'keysym' (down=0,1)
- ptr:x,y,mask inject pointer event x, y, button-mask
- fakebuttonevent:button,down direct XTestFakeButtonEvent.
- sleep:t sleep floating point time t.
- get_xprop:p get X property named 'p'.
- set_xprop:p:val set X property named 'p' to 'val'.
- p -> id=NNN:p for hex/dec window id.
- wininfo:id get info about X window id. use 'root'
- for root window, use +id for children.
- grab_state get state of pointer and keyboard grab.
- pointer_pos print XQueryPointer x,y cursor position.
- pointer_x print XQueryPointer x cursor position.
- pointer_y print XQueryPointer y cursor position.
- pointer_same print XQueryPointer ptr on same screen.
- pointer_root print XQueryPointer curr ptr rootwin.
- pointer_mask print XQueryPointer button and mods mask
- mouse_x print x11vnc's idea of cursor position.
- mouse_y print x11vnc's idea of cursor position.
- noop do nothing.
- defer:n set -defer to n ms,same as deferupdate:n
- wait:n set -wait to n ms.
- extra_fbur:n set -extra_fbur to n.
- wait_ui:f set -wait_ui factor to f.
- setdefer:n set -setdefer to -2,-1,0,1, or 2.
- wait_bog disable -nowait_bog mode.
- nowait_bog enable -nowait_bog mode.
- slow_fb:f set -slow_fb to f seconds.
- xrefresh:f set -xrefresh to f seconds.
- readtimeout:n set read timeout to n seconds.
- nap enable -nap mode.
- nonap disable -nap mode.
- sb:n set -sb to n s, same as screen_blank:n
- fbpm disable -nofbpm mode.
- nofbpm enable -nofbpm mode.
- dpms disable -nodpms mode.
- nodpms enable -nodpms mode.
- forcedpms enable -forcedpms mode.
- noforcedpms disable -forcedpms mode.
- clientdpms enable -clientdpms mode.
- noclientdpms disable -clientdpms mode.
- noserverdpms enable -noserverdpms mode.
- serverdpms disable -noserverdpms mode.
- noultraext enable -noultraext mode.
- ultraext disable -noultraext mode.
- chatwindow enable local chatwindow mode.
- nochatwindow disable local chatwindow mode.
- chaton begin chat using local window.
- chatoff end chat using local window.
- xdamage enable xdamage polling hints.
- noxdamage disable xdamage polling hints.
- xd_area:A set -xd_area max pixel area to "A"
- xd_mem:f set -xd_mem remembrance to "f"
- fs:frac set -fs fraction to "frac", e.g. 0.5
- gaps:n set -gaps to n.
- grow:n set -grow to n.
- fuzz:n set -fuzz to n.
- snapfb enable -snapfb mode.
- nosnapfb disable -snapfb mode.
- rawfb:str set -rawfb mode to "str".
- uinput_accel:f set uinput_accel to f.
- uinput_thresh:n set uinput_thresh to n.
- uinput_reset:n set uinput_reset to n ms.
- uinput_always:n set uinput_always to 1/0.
- progressive:n set LibVNCServer -progressive slice
- height parameter to n.
- desktop:str set -desktop name to str for new clients
-.
- rfbport:n set -rfbport to n.
- macnosaver enable -macnosaver mode.
- macsaver disable -macnosaver mode.
- macnowait enable -macnowait mode.
- macwait disable -macnowait mode.
- macwheel:n set -macwheel to n.
- macnoswap enable -macnoswap mouse button mode.
- macswap disable -macnoswap mouse button mode.
- macnoresize enable -macnoresize mode.
- macresize disable -macnoresize mode.
- maciconanim:n set -maciconanim to n.
- macmenu enable -macmenu mode.
- macnomenu disable -macmenu mode.
- macuskbd enable -macuskbd mode.
- macnouskbd disable -macuskbd mode.
- httpport:n set -httpport to n.
- httpdir:dir set -httpdir to dir (and enable http).
- enablehttpproxy enable -enablehttpproxy mode.
- noenablehttpproxy disable -enablehttpproxy mode.
- alwaysshared enable -alwaysshared mode.
- noalwaysshared disable -alwaysshared mode.
- (may interfere with other options)
- nevershared enable -nevershared mode.
- nonevershared disable -nevershared mode.
- (may interfere with other options)
- dontdisconnect enable -dontdisconnect mode.
- nodontdisconnect disable -dontdisconnect mode.
- (may interfere with other options)
- debug_xevents enable debugging X events.
- nodebug_xevents disable debugging X events.
- debug_xdamage enable debugging X DAMAGE mechanism.
- nodebug_xdamage disable debugging X DAMAGE mechanism.
- debug_wireframe enable debugging wireframe mechanism.
- nodebug_wireframe disable debugging wireframe mechanism.
- debug_scroll enable debugging scrollcopy mechanism.
- nodebug_scroll disable debugging scrollcopy mechanism.
- debug_tiles enable -debug_tiles
- nodebug_tiles disable -debug_tiles
- debug_grabs enable -debug_grabs
- nodebug_grabs disable -debug_grabs
- debug_sel enable -debug_sel
- nodebug_sel disable -debug_sel
- debug_ncache enable -debug_ncache
- nodebug_ncache disable -debug_ncache
- dbg enable -dbg crash shell
- nodbg disable -dbg crash shell
-
- noremote disable the -remote command processing,
- it cannot be turned back on.
-
- bcx_xattach:str This remote control command is for
- use with the BARCO xattach program or the x2x program.
- Both of these programs are for 'pointer and keyboard'
- sharing between separate X displays. In general the
- two displays are usually nearby, e.g. on the same desk,
- and this allows the user to share a single pointer and
- keyboard between them. The user moves the mouse to
- an edge and then the mouse pointer appears to 'jump'
- to the other display screen. Thus it emulates what a
- single X server would do for two screens (e.g. :0.0 and
- :0.1) The illusion of a single Xserver with multiple
- screens is achieved by forwarding events to the 2nd
- one via the XTEST extension.
-
- What the x11vnc bcx_xattach command does is to perform
- some pointer movements to try to INDUCE xattach/x2x
- to 'jump' to the other display. In what follows the
- 'master' display refers to the one that when it has
- 'focus' it is basically doing nothing besides watching
- for the mouse to go over an edge. The 'slave'
- display refers to the one to which the mouse and
- keyboard is redirected to once an edge in the master
- has been crossed. Note that the x11vnc executing the
- bcx_xattach command MUST be the one connected to the
- *master* display.
-
- Also note that when input is being redirected (via
- XTEST) from the master display to the slave display,
- the master display's pointer and keyboard are *grabbed*
- by xattach/x2x. x11vnc can use this info to verify that
- the master/slave mode change has taken place correctly.
- If you specify the "ifneeded" option (see below)
- and the initial grab state is that of the desired
- final state, then no pointer movements are injected
- and "DONE,GRAB_OK" is returned.
-
- "str" must contain one of "up", "down", "left",
- or "right" to indicate the direction of the 'jump'.
- "str" must also contain one of "master_to_slave"
- or "slave_to_master" to indicate the type of mode
- change induced by the jump. Use "M2S" and "S2M"
- as shorter aliases.
-
- "str" may be a "+" separated list of additional
- tuning options. The "shift=n" option indicates an
- offset shift position away from (0,0) (default 20).
- "final=x+y" specifies the final position of the cursor
- at the end of the normal move sequence; default 30+30.
- "extra_move=x+y" means to do one more pointer move
- after "final" to x+y. "dt=n" sets the sleep time
- in milliseconds between pointer moves (default: 40ms)
- "retry=n" specifies the maximum number of retries if
- the grab state change fails. "ifneeded" means to not
- apply the pointer movements if the initial grab state is
- that of the desired final state. "nograbcheck" means
- to not check if the grab state changed as expected and
- only apply the pointer movements (default is to check
- the grab states.)
-
- If you do not specify "up", etc., to bcx_xattach
- nothing will be attempted and the command returns
- the string FAIL,NO_DIRECTION_SPECIFIED. If you do
- not specify "master_to_slave" or "M2S", etc., to
- bcx_xattach nothing will be attempted and the command
- returns the string FAIL,NO_MODE_CHANGE_SPECIFIED.
-
- Otherwise, the returned string will contain "DONE".
- It will be "DONE,GRAB_OK" if the grab state changed
- as expected (or if "ifneeded" was supplied and
- the initial grab state was already the desired
- one.) If the initial grab state was incorrect,
- but the final grab state was correct then it is
- "DONE,GRAB_FAIL_INIT". If the initial grab state
- was correct, but the final grab state was incorrect
- then it is "DONE,GRAB_FAIL_FINAL". If both are
- incorrect it will be "DONE,GRAB_FAIL". Under grab
- failure the string will be followed by ":p1,k1-p2,k2"
- where p1,k1 indicates the initial pointer and keyboard
- grab states and p2,k2 the final ones. If GRAB_FAIL or
- GRAB_FAIL_FINAL occurs, the action will be retried up
- to 3 times; trying to reset the state and sleeping a
- bit between each try. Set retry=n to adjust the number
- of retries, zero to disable retries.
-
- Examples:
- -R bcx_xattach:down+M2S
- -R bcx_xattach:up+S2M
- -R bcx_xattach:up+S2M+nograbcheck+dt=30
- -R bcx_xattach:down+M2S+extra_move=100+100
-
- or use -Q instead of -R to retrieve the result text.
-
- End of the bcx_xattach:str description.
-
- The vncconnect(1) command from standard VNC
- distributions may also be used if string is prefixed
- with "cmd=" E.g. 'vncconnect cmd=stop'. Under some
- circumstances xprop(1) can used if it supports -set
- (see the FAQ).
-
- If "-connect /path/to/file" has been supplied to the
- running x11vnc server then that file can be used as a
- communication channel (this is the only way to remote
- control one of many x11vnc's polling the same X display)
- Simply run: 'x11vnc -connect /path/to/file -remote ...'
- or you can directly write to the file via something
- like: "echo cmd=stop > /path/to/file", etc.
-
--query variable Like -remote, except just query the value of
- "variable". "-Q" is an alias for "-query".
- Multiple queries can be done by separating variables
- by commas, e.g. -query var1,var2. The results come
- back in the form ans=var1:value1,ans=var2:value2,...
- to the standard output. If a variable is read-only,
- it comes back with prefix "aro=" instead of "ans=".
-
- Some -remote commands are pure actions that do not make
- sense as variables, e.g. "stop" or "disconnect", in
- these cases the value returned is "N/A". To direct a
- query straight to the X11VNC_REMOTE property or connect
- file use "qry=..." instead of "cmd=..."
-
- ans= stop quit exit shutdown ping resend_cutbuffer
- resend_clipboard resend_primary blacken zero refresh
- reset close disconnect id_cmd id sid waitmapped
- nowaitmapped clip flashcmap noflashcmap shiftcmap
- truecolor notruecolor overlay nooverlay overlay_cursor
- overlay_yescursor nooverlay_nocursor nooverlay_cursor
- nooverlay_yescursor overlay_nocursor 8to24 no8to24
- 8to24_opts 24to32 no24to32 visual scale scale_cursor
- viewonly noviewonly shared noshared forever noforever
- once timeout tightfilexfer notightfilexfer ultrafilexfer
- noultrafilexfer rfbversion deny lock nodeny unlock avahi
- mdns zeroconf noavahi nomdns nozeroconf connect proxy
- allowonce allow noipv6 ipv6 noipv4 ipv4 no6 6 localhost
- nolocalhost listen lookup nolookup accept afteraccept
- gone shm noshm flipbyteorder noflipbyteorder onetile
- noonetile solid_color solid nosolid blackout xinerama
- noxinerama xtrap noxtrap xrandr noxrandr xrandr_mode
- rotate padgeom quiet q noquiet modtweak nomodtweak xkb
- noxkb capslock nocapslock skip_lockkeys noskip_lockkeys
- skip_keycodes sloppy_keys nosloppy_keys skip_dups
- noskip_dups add_keysyms noadd_keysyms clear_mods
- noclear_mods clear_keys noclear_keys clear_all
- clear_locks keystate remap repeat norepeat fb nofb bell
- nobell sendbell sel nosel primary noprimary setprimary
- nosetprimary clipboard noclipboard setclipboard
- nosetclipboard seldir cursorshape nocursorshape
- cursorpos nocursorpos cursor_drag nocursor_drag cursor
- show_cursor noshow_cursor nocursor arrow xfixes noxfixes
- xdamage noxdamage xd_area xd_mem alphacut alphafrac
- alpharemove noalpharemove alphablend noalphablend
- xwarppointer xwarp noxwarppointer noxwarp always_inject
- noalways_inject buttonmap dragging nodragging ncache_cr
- noncache_cr ncache_no_moveraise noncache_no_moveraise
- ncache_no_dtchange noncache_no_dtchange
- ncache_no_rootpixmap noncache_no_rootpixmap
- ncache_reset_rootpixmap ncrp ncache_keep_anims
- noncache_keep_anims ncache_old_wm noncache_old_wm
- ncache_pad ncache noncache ncache_size debug_ncache
- nodebug_ncache wireframe_mode wireframe wf nowireframe
- nowf wireframelocal wfl nowireframelocal nowfl
- wirecopyrect wcr nowirecopyrect nowcr scr_area
- scr_skip scr_inc scr_keys scr_term scr_keyrepeat
- scr_parms scrollcopyrect scr noscrollcopyrect
- noscr fixscreen noxrecord xrecord reset_record
- pointer_mode pm input_skip allinput noallinput
- input_eagerly noinput_eagerly input grabkbd nograbkbd
- grabptr nograbptr grabalways nograbalways grablocal
- client_input ssltimeout speeds wmdt debug_pointer dp
- nodebug_pointer nodp debug_keyboard dk nodebug_keyboard
- nodk keycode keysym ptr fakebuttonevent sleep get_xprop
- set_xprop wininfo bcx_xattach deferupdate defer
- setdefer extra_fbur wait_ui wait_bog nowait_bog
- slow_fb xrefresh wait readtimeout nap nonap sb
- screen_blank fbpm nofbpm dpms nodpms clientdpms
- noclientdpms forcedpms noforcedpms noserverdpms
- serverdpms noultraext ultraext chatwindow nochatwindow
- chaton chatoff fs gaps grow fuzz snapfb nosnapfb
- rawfb uinput_accel uinput_thresh uinput_reset
- uinput_always progressive rfbport http nohttp httpport
- httpdir enablehttpproxy noenablehttpproxy alwaysshared
- noalwaysshared nevershared noalwaysshared dontdisconnect
- nodontdisconnect desktop debug_xevents nodebug_xevents
- debug_xevents debug_xdamage nodebug_xdamage
- debug_xdamage debug_wireframe nodebug_wireframe
- debug_wireframe debug_scroll nodebug_scroll debug_scroll
- debug_tiles dbt nodebug_tiles nodbt debug_tiles
- debug_grabs nodebug_grabs debug_sel nodebug_sel dbg
- nodbg macnosaver macsaver nomacnosaver macnowait macwait
- nomacnowait macwheel macnoswap macswap nomacnoswap
- macnoresize macresize nomacnoresize maciconanim macmenu
- macnomenu nomacmenu macuskbd nomacuskbd noremote
-
- aro= noop display vncdisplay icon_mode autoport
- loop loopbg desktopname guess_desktop guess_dbus
- http_url auth xauth users rootshift clipshift scale_str
- scaled_x scaled_y scale_numer scale_denom scale_fac_x
- scale_fac_y scaling_blend scaling_nomult4 scaling_pad
- scaling_interpolate inetd privremote unsafe safer nocmds
- passwdfile unixpw unixpw_nis unixpw_list ssl ssl_pem
- sslverify stunnel stunnel_pem https httpsredir usepw
- using_shm logfile o flag rmflag rc norc h help V version
- lastmod bg sigpipe threads readrate netrate netlatency
- pipeinput clients client_count pid ext_xtest ext_xtrap
- ext_xrecord ext_xkb ext_xshm ext_xinerama ext_overlay
- ext_xfixes ext_xdamage ext_xrandr rootwin num_buttons
- button_mask mouse_x mouse_y grab_state pointer_pos
- pointer_x pointer_y pointer_same pointer_root
- pointer_mask bpp depth indexed_color dpy_x dpy_y wdpy_x
- wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y rfbauth
- passwd viewpasswd
-
--QD variable Just like -query variable, but returns the default
- value for that parameter (no running x11vnc server
- is consulted)
-
--sync By default -remote commands are run asynchronously, that
- is, the request is posted and the program immediately
- exits. Use -sync to have the program wait for an
- acknowledgement from the x11vnc server that command was
- processed (somehow). On the other hand -query requests
- are always processed synchronously because they have
- to wait for the answer.
-
- Also note that if both -remote and -query requests are
- supplied on the command line, the -remote is processed
- first (synchronously: no need for -sync), and then
- the -query request is processed in the normal way.
- This allows for a reliable way to see if the -remote
- command was processed by querying for any new settings.
- Note however that there is timeout of a few seconds
- (see the next paragraph) so if the x11vnc takes longer
- than that to process the requests the requester will
- think that a failure has taken place.
-
- The default is to wait 3.5 seconds. Or if cmd=stop
- only 1.0 seconds. If cmd matches 'script:' then it
- will wait up to 10.0 seconds. Set X11VNC_SYNC_TIMEOUT
- to the number of seconds you want it to wait.
-
--query_retries str If a query fails to get a response from an x11vnc
- server, retry up to n times. "str" is specified as
- n[:t][/match] Optionally the delay between tries may
- be specified by "t" a floating point time (default
- 0.5 seconds.) Note: the response is not checked for
- validity or whether it corresponds to the query sent.
- The query "ping:mystring" may be used to help uniquely
- identify the query. Optionally, a matching string after
- a "/" will be used to check the result text. Up to
- n retries will take place until the matching string is
- found in the output text. If the match string is never
- found the program's exit code is 1; if the match is
- found it exits with 0. Note that there may be stdout
- printed for each retry (i.e. multiple lines printed
- out to stdout.)
- Example: -query_retries 4:1.5/grab_state
-
--remote_prefix str Enable a remote-control communication channel for
- connected VNC clients. str is a non-empty string. If a
- VNC client sends rfbCutText having the prefix "str"
- then the part after it is processed as though it were
- sent via 'x11vnc -remote ...'. If it begins with
- neither 'cmd=' nor 'qry=' then 'qry=' is assumed.
- Any corresponding output text for that remote control
- command is sent back to all client as rfbCutText.
- The returned output is also prefixed with "str".
- Example: -remote_prefix DO_THIS:
-
- Note that enabling -remote_prefix allows the remote
- VNC viewers to run x11vnc -remote commands. Do not
- use this option if they are not to be trusted.
-
--noremote Do not process any remote control commands or queries.
--yesremote Do process remote control commands or queries.
- Default: -yesremote
-
- A note about security wrt remote control commands.
- If someone can connect to the X display and change
- the property X11VNC_REMOTE, then they can remotely
- control x11vnc. Normally access to the X display is
- protected. Note that if they can modify X11VNC_REMOTE
- on the X server, they have enough permissions to also
- run their own x11vnc and thus have complete control
- of the desktop. If the "-connect /path/to/file"
- channel is being used, obviously anyone who can write
- to /path/to/file can remotely control x11vnc. So be
- sure to protect the X display and that file's write
- permissions. See -privremote below.
-
- If you are paranoid and do not think -noremote is
- enough, to disable the X11VNC_REMOTE property channel
- completely use -novncconnect, or use the -safer option
- that shuts many things off.
-
--unsafe A few remote commands are disabled by default
- (currently: id:pick, accept:<cmd>, gone:<cmd>, and
- rawfb:setup:<cmd>) because they are associated with
- running external programs. If you specify -unsafe, then
- these remote-control commands are allowed. Note that
- you can still specify these parameters on the command
- line, they just cannot be invoked via remote-control.
--safer Equivalent to: -novncconnect -noremote and prohibiting
- -gui and the -connect file. Shuts off communcation
- channels.
--privremote Perform some sanity checks and disable remote-control
- commands if it appears that the X DISPLAY and/or
- connectfile can be accessed by other users. Once
- remote-control is disabled it cannot be turned back on.
--nocmds No external commands (e.g. system(3), popen(3), exec(3))
- will be run at all.
--allowedcmds list "list" contains a comma separated list of the only
- external commands that can be run. The full list of
- associated options is:
-
- stunnel, ssl, unixpw, WAIT, zeroconf, id, accept,
- afteraccept, gone, pipeinput, v4l-info, rawfb-setup,
- dt, gui, ssh, storepasswd, passwdfile, custom_passwd,
- findauth, crash.
-
- See each option's help to learn the associated external
- command. Note that the -nocmds option takes precedence
- and disables all external commands.
-
--deny_all For use with -remote nodeny: start out denying all
- incoming clients until "-remote nodeny" is used to
- let them in.
-
-
-
-These options are passed to LibVNCServer:
-
--rfbport port TCP port for RFB protocol
--rfbwait time max time in ms to wait for RFB client
--rfbauth passwd-file use authentication on RFB protocol
- (use 'storepasswd' to create a password file)
--rfbversion 3.x Set the version of the RFB we choose to advertise
--permitfiletransfer permit file transfer support
--passwd plain-password use authentication
- (use plain-password as password, USE AT YOUR RISK)
--deferupdate time time in ms to defer updates (default 40)
--deferptrupdate time time in ms to defer pointer updates (default none)
--desktop name VNC desktop name (default "LibVNCServer")
--alwaysshared always treat new clients as shared
--nevershared never treat new clients as shared
--dontdisconnect don't disconnect existing clients when a new non-shared
- connection comes in (refuse new connection instead)
--httpdir dir-path enable http server using dir-path home
--httpport portnum use portnum for http connection
--enablehttpproxy enable http proxy support
--progressive height enable progressive updating for slow links
--listen ipaddr listen for connections only on network interface with
- addr ipaddr. '-listen localhost' and hostname work too.
-
-libvncserver-tight-extension options:
--disablefiletransfer disable file transfer
--ftproot string set ftp root
-
- Pretty wild huh? Contact me if you have any questions or problems.
-
- Personally, I use:
-x11vnc -rfbauth $HOME/.vnc/passwd -solid
diff --git a/x11vnc/RELEASE-NOTES b/x11vnc/RELEASE-NOTES
deleted file mode 100644
index 0d5c4b9..0000000
--- a/x11vnc/RELEASE-NOTES
+++ /dev/null
@@ -1,1553 +0,0 @@
-
-x11vnc 0.9.13 2010-12-20
-
-New in the 0.9.13 x11vnc release:
-
- Improved support for non-X11 touchscreen devices (e.g. handheld or
- cell phone) via Linux uinput input injection. Additional
- tuning parameters are added. TSLIB touchscreen calibration
- is supported. Tested on Qtmoko Neo Freerunner.
-
- A tool, misc/uinput.pl, is provided to diagnose uinput
- behavior on new devices.
-
- The env. vars. X11VNC_UINPUT_BUS and X11VNC_UINPUT_VERSION
- are available if leaving them unset does not work.
-
- The Linux uinput non-X11 input injection can now be bypassed:
- events can be directly written to the /dev/input/event
- devices specified by the user (direct_abs=..., etc.)
-
- A -pipeinput input injection helper script,
- misc/qt_tslib_inject.pl is provided as a tweakable
- non-builtin direct input injection method.
-
- The list of new uinput parameters for the above two features is:
- pressure, tslib_cal, touch_always, dragskip, btn_touch;
- direct_rel, direct_abs, direct_btn, direct_key.
-
- The included SSL enabled Java VNC Viewers now handle Mouse
- Wheel events.
-
-
- miscellaneous new features and changes:
-
- In -reflect mode, the libvncclient connection can now have
- the pixel format modified via the environment
- variables X11VNC_REFLECT_bitsPerSample,
- X11VNC_REFLECT_samplesPerPixel, and
- X11VNC_REFLECT_bytesPerPixel
-
- In -create mode the following environment variables are added
- to fine tune the behavior: FIND_DISPLAY_NO_LSOF:
- do not use lsof(1) to try to determine the Linux VT,
- FIND_DISPLAY_NO_VT_FIND: do not try to determine the
- Linux VT at all, X11VNC_CREATE_LC_ALL_C_OK: do not bother
- undoing the setting LC_ALL=C that the create_display
- script sets. The performance of the -create script
- has been improved for large installations (100's of
- user sessions on one machine.)
-
- In -unixpw mode, one can now Tab from login: to Password.
-
- An environment variable, X11VNC_SB_FACTOR, allows one to scale
- the -sb screenblank sleep time from the default 2 secs.
-
- In -rawfb mode, a bug is fixed in setting the number of bits
- per pixel.
-
- Documented that -grabkbd is no longer working with some/most
- window managers (it can prevent resizing and menu posting.)
-
- The macosx deprecated interface GetMainDevice() call is removed.
- Compile with -DX11VNC_MACOSX_USE_GETMAINDEVICE if needed
- for an old macosx version...
-
- Miscellaneous code cleanup.
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.12 2010-09-10
-
-New in the 0.9.12 x11vnc release:
-
- One can now specify the maximum number of displays
- that can be created in -create mode via the
- env. var. X11VNC_CREATE_MAX_DISPLAYS
-
- The X11VNC_NO_LIMIT_SHM env. var. is added to skip any
- automatic shared memory reduction.
-
- The kdm display manager is now detected when trying not to get
- killed by the display manager.
-
- miscellaneous new features and changes:
-
- A compile error is fixed when using --with-system-libvncserver
- pointing to LibVNCServer 0.9.7.
-
- -nevershared -forever usage mode is documented.
-
- Old SuSE broken thread local storage is documented.
-
- x11vnc exit cases are documented.
-
- A compile bug from forced use of Xdefs.h is worked around.
-
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.11 2010-08-08
-
-New in the 0.9.11 x11vnc release:
-
- The source tree is synchronized with the most recent libvncclient
- (this only affects -reflect mode.) The build is fixed
- for incompatibilities when using an external LibVNCServer
- (e.g. ./configure --with-system-libvncserver...)
-
- The SSL enabled Java VNC Viewer Makefile has been modified so
- that the jar files that are built are compatible back
- to Java 1.4.
-
- In -reflect mode cursor position updates are now handled
- correctly.
-
- In -create/-unixpw mode, the env. var. FD_USERPREFS may be set
- to a filename in the user's home directory that includes
- default username:options values (so the options do not
- need to be typed every time at the login prompt.)
-
- miscellaneous new features and changes:
-
- An option -always_inject is provided: Even if there is no
- displacement (dx = dy = 0) for a VNC mouse event force
- the pointer to the indicated x,y position anyway.
-
- New java viewer debugging and workaround applet parameters:
- debugKeyboard mapF5_to_atsign forbid_Ctrl_Alt
-
- You can set X11VNC_AVAHI_NAME, X11VNC_AVAHI_HOST, and/or
- X11VNC_AVAHI_PORT environment variables to override the
- default values. For example: -env X11VNC_AVAHI_NAME=wally
-
- When opening the X11 display extra XAUTHLOCALHOSTNAME settings
- are attempted.
-
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.10 2010-05-03
-
-New in the 0.9.10 x11vnc release:
-
- IPv6 is now supported for all usage modes: forward and reverse
- connections, SSL and unencrypted, etc.
-
- The included SSL enabled Java VNC viewer applet now supports
- Chained SSL Certificates (x11vnc -ssl always has.)
- The applet autodects x11vnc and set GET=1 for faster
- connecting via HTTPS.
-
- A demo CGI script 'desktop.cgi' shows how to create an
- SSL encrypted, multi-user x11vnc web login desktop
- service. The user logs into a secure web site and gets
- his/her own virtual desktop and his browser accesses it
- with the SSL Java VNC Viewer applet.
-
- A serverCert Java Viewer applet parameter is provided.
- Use an authenticated HTTPS browser connection to set
- this parameter (the user could set it locally too.)
- The onetimekey tool has -certonly option for this scheme.
-
- The Xdummy script (use Xorg 'dummy' driver instead of Xvfb)
- no longer requires being run as root.
-
-
- miscellaneous new features and changes:
-
- In the Java viewer applet, debugCerts and debugKeyboard parameters
- are provided. The debugging output of the applet is more
- readable. Some corner-case bugs (e.g. socket exceptions)
- are now handled gracefully. Parameters forbid_Ctrl_Alt
- and mapF5_to_atsign are added.
-
- The amount of time to wait for HTTPS applet downloads to finish
- can be set in env. var. X11VNC_HTTPS_DOWNLOAD_WAIT_TIME.
-
- The -xkb mode is automatically enabled if there are more than
- 4 keysyms per key.
-
- -coe is now an alias for -connect_or_exit.
-
- The -input_eagerly option enables this LibVNCServer feature
- (it is like -allinput.)
-
- The "%" unix password verification tricks for the -unixpw
- option are now documented. They also run a command
- in UNIXPW_CMD.
-
- In -create (-svc, etc.) modes, a warning is printed out if Xvfb
- cannot be found. Xvfb '+kb' option is checked for.
- The -env CREATE_DISPLAY_OUTPUT=/tmp/mydebug.txt debugging
- option is documented. Try to preserve user's PATH
- if possible.
-
- In XDMCP connection mode, a test for GDM listening only
- on IPv6 (::1) is performed. The interface can also be
- specified via FD_XDMCP_IF.
-
- The example scripts connect_switch, ultravnc_repeater.pl, inet6to4
- have settings to let them run reliably for long times
- as daemons. They also support IPv6.
-
- IPv6 notes: for some very esoteric cases (e.g. -chatwindow)
- IPv4 localhost may be required for local IPC. A demo
- transition tool 'inet6to4' is also included (can be
- used for other apps.) x11vnc options related to IPv6:
- -listen6, -6, -no6, -noipv4, -noipv6, and -connect,
- -proxy.
-
- Use STUNNEL_LISTEN in -stunnel mode to have it listen on a
- particular interface. Also STUNNEL_PROG.
-
- New remote control query options: pointer_x, pointer_y,
- pointer_same, pointer_root, and pointer_mask. A demo
- script using them misc/panner.pl is provided.
-
- Remote control change of -clip option will not create new
- framebuffer if the size has not changed (for panner.pl)
-
- The X11VNC_DISABLE_SSL_CLIENT_MODE env. var. can be set to
- disable SSL client role in reverse connections. This
- means the VNC viewer side must be in SSL client role.
- UltraVNC repeater operation can benefit from this.
-
- The SSL_INIT_TIMEOUT is increased to 1 hour if 'repeater'
- is detected in a reverse connect string.
-
- The X property X11VNC_TRAP_XRANDR can be set on a desktop to
- force x11vnc to use the -xrandr screen size change
- trapping code.
-
- The -sslScripts option prints out the SSL certificate management
- scripts.
-
- Suggest '-auth guess' and '-findauth' if X connection fails.
-
- The TightVNC sercurity type (TightVNC features enabler) now
- works for RFB version 3.8.
-
- RECORD scroll detection is now working with the new gtk/gdk scroll
- mechanism. Set X11VNC_SCROLL_MUST_EQUAL to disable.
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.9 2009-12-21
-
-
-
-New in the 0.9.9 x11vnc release:
-
- A new option -findauth runs the FINDDISPLAY script that applies
- heuristics to try to determine the correct XAUTHORITY
- file. The use of '-auth guess' will use the XAUTHORITY
- that -findauth reveals. This can be handy in with
- the lastest GDM where the ability to store cookies in
- ~/.Xauthority has been removed.
-
- If x11vnc is running as root (e.g. inetd or XDM/GDM/KDM)
- the FD_XDM=1 mode will be tried if the above -findauth
- or '-auth guess' command fails; it will find the
- correct XAUTHORITY for the given display (this works for
- XDM/GDM/KDM if the login greeter panel is up or if someone
- has already logged into an X session.) You can also
- set -env FD_XDM=1 to force it to be done on the first try.
-
- The -unixpw_system_greeter option, when used in combined
- unixpw and XDMCP FINDCREATEDISPLAY mode (e.g. -xdmsvc),
- enables the user to press Escape to jump directly to the
- XDM/GDM/KDM login greeter screen. This way the user
- avoids entering his unix password twice at X session
- creation time. For subseqent logins to the same session,
- he uses the regular x11vnc unixpw "login:" prompt. Also,
- the unixpw login panel now has a short help displayed
- if the user presses 'F1' that lists the options.
-
- The -appshare option enables simple application sharing based on
- the -id/-sid mechanism. Every new toplevel window that
- the application creates induces a new viewer window via
- a reverse connection. The -id/-sid and -connect options
- are required. Run 'x11vnc -appshare -help' for more info.
-
- Heuristics are applied to try to determine if the X display
- is currently in a Display Manager Greeter Login panel
- (e.g. GDM.) If so, x11vnc's creation of any windows and
- use of XFIXES are delayed.
-
- This is to try to avoid x11vnc being killed after the user
- logs in if the GDM KillInitClients=true is in effect.
- So one no longer needs to set KillInitClients=false in
- gdm.conf. Note that in recent GDM the KillInitClients
- option has been removed.
-
- Also delayed is the use of the XFIXES cursor fetching
- functionality; this avoids an Xorg bug that causes Xorg
- to crash right after the user logs in.
-
- x11vnc now tries to be more aggressive in keeping up with VNC
- client's framebuffer update requests. Some broken VNC
- clients continuously spray these requests at VNC servers
- (regardless of whether they have received any updates
- or not.) The -extra_fbur option allows one to fine tune
- the setting.
-
- The "-display WAIT:cmd=...", -find, -create modes now work
- correctly for the user-supplied login program scheme
- "-unixpw_cmd ...", as long as the login program supports
- running commands specified in the environment variable
- "RFB_UNIXPW_CMD_RUN" as the logged-in user. The mode
- "-unixpw_nis ..." has also been made more consistent.
- The username option "tag=..." can be used to set FD_TAG.
-
- The -stunnel option (like -ssl but uses stunnel as an external
- helper program) now works with the -ssl "SAVE" and "TMP"
- special certificate names. The -sslverify and -sslCRL
- options now work correctly in -stunnel mode. Single port
- HTTPS connections are also supported for this mode.
-
- The remote control command -R can be used to instruct x11vnc
- to resend its most recent copy of the Clipboard,
- Primary, or Cutbuffer selections: "x11vnc -R
- resend_clipboard", "x11vnc -R resend_primary", and
- "x11vnc -R resend_cutbuffer".
-
- miscellaneous new features and changes:
-
- The fonts in the GUI (-gui) can now by set via environment
- variables, e.g. -env X11VNC_FONT_BOLD='Helvetica -16 bold'
- and -env X11VNC_FONT_FIXED='Courier -14'.
-
- The value of the -timeout option is now also used for the timing
- out of reverse connections. The -timeout exit will
- occur if no client has made it to normal operating state
- (instead of merely trying to connect.)
-
- One can add extra URL parameters to the HTTPS (-ssl) urls
- via X11VNC_EXTRA_HTTPS_PARAMS without needing to edit
- index.vnc. E.g.: -env X11VNC_EXTRA_HTTPS_PARAMS='?GET=1'
-
- One can make the libvncserver HTTP (non-SSL) server listen on
- localhost: -env X11VNC_HTTP_LISTEN_LOCALHOST=1 (this way
- only the single-port VNC+HTTPS is exposed to the network.)
-
- Warnings are printed out at startup if $DISPLAY appears to
- start with "localhost:" (SSH X11 forwarding) or
- "hostname:" (remote X display; will fail w/o -noshm)
-
- The -solid option now uses the DBUS_SESSION_BUS_ADDRESS env. var
- if available. The -solid option now works in xfce.
- If available, the dbus_launch(1) will be used in
- FINDCREATEDISPLAY for gnome sessions.
-
- The bcx_xattach remote control command was added to facilitate
- xattach and x2x desktop cursor switching. Other new
- remote control commands: grab_state, ping:mystring,
- grablocal, resend_cutbuffer, resend_clipboard,
- resend_primary, keycode, keysym, fakebuttonevent,
- ptr, sleep, get_xprop, set_xprop, wininfo, pointer_pos,
- mouse_xy, noop, guess_dbus, DIRECT:query. Remote control
- scripting, -query_retries, and -remote_prefix were
- also added.
-
- In -rawfb mode the X display will not be opened at all unless
- the -rawfb string is prefixed with '+' or -display
- was specified on the cmdline.
-
- For multiple, separate x11vnc instances on the same X display,
- one can rename the X11VNC_REMOTE, X11VNC_TICKER, and
- VNC_CONNECT property names to unique ones.
-
- The -showrfbauth option prints out the VNC rfbauth password.
-
- The XDAMAGE mechanism is now automatically disabled for a
- period of time if a game or screensaver generates too
- many XDAMAGE rectangles per second. This avoids the X11
- event queue from soaking up too much memory.
-
- x11vnc does not switch on server autorepeat if any keys are
- pressed down to work around a recent Xorg server and/or
- gnome bug where the key will never stop repeating.
-
- Thse list of current clients is kept more up-to-date in the
- tkx11vnc gui. Bugs in the gui setpass mode have been
- fixed.
-
- Threads stability is further improved. See under the -threads
- option help info about -env X11VNC_THREADS_NEW_FB_SLEEP=ms
-
- There is an experimental workaround: "-env X11VNC_WATCH_DX_DY=1"
- that tries to avoid problems with poorly constructed
- menu themes that place the initial position of the mouse
- cursor inside a menu item's active zone.
-
- The crypt(3) function is now declared inside the x11vnc code on
- all platforms (not just Linux). To disable this, set
- CPPFLAGS='-DDO_NOT_DECLARE_CRYPT' while configuring.
- (crypt is declared to avoid problems with header files.)
-
- Error reasons are printed for -storepasswd failures.
-
- Two scripts are added to x11vnc/misc: connect_switch and
- ultravnc_repeater.pl
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
-
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.8 2009-07-08
-
-
-New in the 0.9.8 x11vnc release:
-
- Better reliability for the Java Viewer applet when connecting
- through a Web Proxy via HTTPS. A proxy hostname
- and port can be specified via applet parameters.
- Proxy Authentication via Auth-Basic is supported.
- More x11vnc printout in -ssl is provided to help
- troubleshoot this mode and other ssl connections.
-
- Stability improvements to -threads mode. Running x11vnc this
- way is more reliable now. Threaded operation sometimes
- gives better interactive response and faster updates. The
- threaded mode now supports multiple VNC viewers using
- the same VNC encoding (some only on Linux or enabled
- at build time.) The threaded mode can also yield
- a performance enhancement in the many client case
- (e.g. class-room broadcast.) We have tested with 30 to
- 50 simultaneous clients. See also -reflect.
-
-
- miscellaneous new features and changes:
-
- x11vnc automatically tries to work around an Xorg server bug
- involving infinitely repeating keys when turning off key
- repeating. Use -repeat if the automatic workaround fails.
- Also, the environment variable X11VNC_IDLE_TIMEOUT
- (seconds) is provided.
-
- In -reflect mode the environment variable X11VNC_REFLECT_PASSWORD
- is provided.
-
- The -clip mode works under -rawfb.
-
- The -nounixpw option can disable unixpw mode if an earlier option
- enables it (e.g. -svc).
-
- Scroll detection is skipped for windows with 'OpenOffice' in
- their name.
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.7 2009-03-31
-
-
-New in the 0.9.7 x11vnc release:
-
- Basic support for building with VirtualGL's TurboVNC (an
- enhanced TightVNC for fast LAN high framerate usage)
- encoding and TightVNC modifications. More info:
- http://www.karlrunge.com/x11vnc/faq.html#faq-turbovnc
- and x11vnc/misc/turbovnc/README.
-
- The -ncache_cr option has been fixed and so in -ncache mode
- smooth opaque window motions are now work correctly. Try
- it out to see how smooth it is even on a slow link.
-
- Support for Linux text consoles (virtual terminals, e.g. 1-6)
- is provided via, e.g., 'x11vnc -rawfb vt2' (for virtual
- terminal #2).
-
- This is like LinuxVNC (i.e. text only), it avoids using
- /dev/fb and uses /dev/vcsaN instead (the '-rawfb console'
- mode uses /dev/fb.) With /dev/vcsaN the text terminal
- is accessible even it if is not the currently active one.
-
- The -rawfb option now supports framebuffers with bits per pixel
- less than 8 (e.g. 4 or 1 bpp.)
-
- Reverse connections now work in Anonymous Diffie Hellman SSL/TLS
- mode. Reverse connections also work for VeNCrypt and
- ANONTLS modes.
-
-
- miscellaneous new features and changes:
-
- The included SSL enabled UltraVNC java viewer now has a
- configurable [Home] entry in the drives drop down menu.
-
- In the -create, -svc, etc. modes one can now specify a
- range of X displays to ignore in X11VNC_SKIP_DISPLAY.
- Improvements and bugfixes were made to the find_display
- and create_display scripts. FD_EXTRA option is provided.
-
- The '-rawfb video' option finds the video device file more
- carefully.
-
- The -rmflag option allows a new way to indicate to other
- applications that x11vnc has started.
-
- All of the java applet parameters are now documented in
- the classes/ssl/README file.
-
- There is now a "sendbell" remote control command.
-
- A one-time -padgeom once:WxH mode is added.
-
- Improvements to the CUPS Terminal Services helper mode.
-
- If the X display cannot be opened normally then the env. var.
- XAUTHLOCALHOSTNAME=localhost is tried.
-
- Bugfix for selection transfer to a now non-existent X window
- (Thunderbird can cause this.) Related, the env. variable
- LIBXCB_ALLOW_SLOPPY_LOCK is now set by default.
-
- Bugfix for -8to24 mode due to nonstandard indexed color support.
-
- The libvncserver and x11vnc autoconf/automake settings have
- been improved.
-
- libXrandr include file is now found on Solaris.
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.6 2008-12-10
-
-
-New in the 0.9.6 x11vnc release:
-
- x11vnc's SSL encryption is extended to support the VeNCrypt and
- TLS (older; vino) SSL/TLS security type extensions to VNC.
-
- Anonymous Diffie-Hellman key exchange (-ssl ANON) and Certificate
- Revocation List support (-sslCRL) is added to the SSL
- encryption mode.
-
- The Java viewer applet can now be served up through the VNC port
- (5900) in addition to the normal HTTP port (5800) via
- the -http_oneport option. Previously this only worked
- for SSL connections and HTTPS.
-
- The "-rfbport PROMPT" mode presents a simple gui for the user
- to select a port for the x11vnc service and a few other
- settings. This enables a menu entry for naive users
- that is included in x11vnc.desktop.
-
- If x11vnc is not built with the Avahi Zeroconf library an external
- helper program (avahi-publish or dns-sd on Mac OS X)
- is used instead.
-
- miscellaneous new features and changes:
-
- The default mode for '-ssl' is now the '-ssl SAVE' mode; i.e.
- the generated certificate is saved and reused in
- subsequent sessions rather than being discarded.
- Use '-ssl TMP' recover the old way. This change made
- to for it to be more likely that the VNC Viewer can save
- the accepted cert for future authentications.
-
- The solid background color option works on the Mac OS X console.
-
- The -reopen option enables x11vnc to try to re connect to the X
- display if GDM (or other display manager) kills it just
- after the user logs in.
-
- The -dhparams option can be used to point to your own Diffie
- Hellman parameters.
-
- The -setdefer option allows tuning how quickly updates will
- be sent. Default setting tuned.
-
- The option -zeroconf is now an alias for -avahi/-mdns.
-
- In pipeinput mode, the pipe filehandle is now closed when
- x11vnc exits.
-
- The -sshonly option turns off VeNCrypt and TLSVNC (vino) mod
- leaving only the standard SSL (i.e. vncs://)
-
- For testing, the option -rand in an alias for -rawfb rand -nopw
-
- Minor tweaks to improve CUPS Print tunneling.
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.5 2008-10-24
-
-
-New in the 0.9.5 x11vnc release:
-
- Symmetric key encryption using the RC4, AES, Blowfish, and 3DES
- ciphers is supported via the -enc cipher:keyfile option.
- The SSVNC unix viewer 1.0.20 and later supports these
- encryption methods.
-
- Server-side scaling can now have different scale factors along
- the horizontal and vertical axes. E.g. -scale 1280x1024
- (same as -geometry 1280x1024) or -scale 0.8x0.75
-
- The -chatwindow option allows a chat window to appear on the
- X console during UltraVNC chats (requires the SSVNC
- viewer package.)
-
- miscellaneous new features and changes:
-
- The HTTP Java viewer applet jar, classes/VncViewer.jar, has
- been updated with an improved implementation based on
- the code used by the classes/ssl applets.
-
- A description and instructions are now printed out when
- X_ShmAttach fails if one tries to attach to a remote
- $DISPLAY (i.e. $DISPLAY is on a different machine from
- the machine x11vnc is running on; this often happens
- with SSH X redirection, X terminal servers, etc).
-
- The -allow option now works correctly in -ssl mode.
-
- The -remap option now works on the MacOSX console.
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.4 2008-09-17
-
-
-New in the 0.9.4 x11vnc release:
-
- Reverse VNC connections (-connect and -connect_or_exit options)
- work in the -find and -create X session FINDCREATEDISPLAY
- modes.
-
- Reverse VNC connections (either normal or using SSL) can use a
- Web Proxy, a SOCKS proxy, the UltraVNC repeater proxy,
- an SSH connection, or even a CGI URL to make the outgoing
- connection (-proxy option). Forward connections can
- use the -ssh option to set up a reachable redirection.
-
- Support for the ZYWRLE encoding is added, this is the RealVNC ZRLE
- encoding extended to do motion video and photo regions
- more efficiently by way of a Wavelet based transformation.
-
- The session finding and creating modes (-find and -create) have
- been improved to be more reliable and also provide a new
- desktop types (xfce) and new service redirection options.
-
- Support for indexed colormaps (PseudoColor) with depths other
- than 8 is provided (depths 1 to 16 now work).
-
- Java viewer applet source code is provided in the x11vnc 0.9.4
- tarball so now everything can be built from source.
-
- miscellaneous new features and changes:
-
- To unset Caps_Lock, Num_Lock and raise all keys in the X server
- use -clear_all, or by remote control 'x11vnc -R clear_all'
-
- The -autoport option gives more control over the server port
- range that probes.
-
- The -ping option can be used to help keep idle connections alive.
-
- The -finddpy and -listdpy utilities help to debug and configure
- the -find, -create, and -display WAIT:... modes.
-
- Some automatic detection of screen resizes are handled even if
- the -xrandr option is not supplied.
-
- The -advertise_truecolor option can workaround some VNC viewer
- incompatibilities with PseudoColor.
-
- The option '-clip xinerama0' can be used to clip to the first
- Xinerama sub-screen, etc.
-
- If a fast framebuffer read rate is detected the -wait and -defer
- parameters are reduced to 10 and 15 msec, respectively.
-
- Pasting of the selection/clipboard into remote applications
- (e.g. Java) is improved.
-
- Usage with dvorak keyboards is improved. The option -macuskbd is
- available on MacOSX to use the original US keyboard code.
-
- Via a compiler option (-DENABLE_GRABLOCAL) one can use the
- -grablocal n option to filter VNC client input if someone
- at the console has done mouse or keyboard input n secs ago.
-
- The -sleepin option can now sleep a random amount of time between
- min and max time delays (-sleepin min-max).
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.3 2007-10-04
-
-
-New in the 0.9.3 x11vnc release:
-
- This release provides client-side caching to improve interactive
- response. Almost no VNC viewers implement caching which is why
- VNC is slow compared to other remote graphics protocols.
-
- The x11vnc caching will work with any VNC viewer, but they will
- not hide the pixmap cache region that is below the main desktop
- (one must adjust the window manually). The SSVNC Unix VNC viewer,
- however, automatically detects and hides the region.
-
- To enable caching, supply "-ncache n" to x11vnc, where the
- number n, e.g. 10, indicates how much memory to devote to the
- caching scheme.
-
- See http://www.karlrunge.com/x11vnc/#faq-client-caching
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.2 2007-06-18
-
-
-New in the 0.9.2 x11vnc release:
-
- A compile-time bug is fixed for when the OpenSSL library is not
- available or --without-ssl is supplied; previously the
- build would fail.
-
- One can configure x11vnc via "configure --with-system-libvncserver"
- to use a system installed libvncserver library instead of
- the one bundled in the release tarball.
-
- If UltraVNC file transfer or chat is detected, then VNC clients
- are "pinged" more often to prevent these side channels
- from becoming serviced too infrequently.
-
- In -unixpw mode in the username and password dialog no text will
- be echoed if the first character sent is "Escape". This
- enables a convenience feature in SSVNC to send the username
- and password automatically.
-
- miscellaneous new features and changes:
-
- When building from the CVS tree --with-x11vnc must be supplied if
- you want x11vnc to be built. The LibVNCServer release
- tarball no longer contains the x11vnc source.
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9.1 2007-05-24
-
-
-New in the 0.9.1 x11vnc release:
-
- A new Unix username identification scheme is provided when
- SSL client certificates are used to authenticate VNC
- viewers. The username is extracted from the 'Subject'
- section of the cert. The option is "-users sslpeer="
- which, like "-users unixpw=" already does, will cause
- a switch to the Unix user. This is useful for the
- -find and -create options that try to find an existing
- X session associated with the user or create a new one.
-
- The UltraVNC Java Viewer has been modified to support SSL
- connections. Some bugs were also fixed and some
- improvements added. A patch file and a compiled jar file
- (UltraViewerSSL.jar and SignedUltraViewerSSL.jar in the
- classes/ssl directory) are provided in the x11vnc package.
-
- For the -user option groups are now handled better by using
- initgroups(3), or if finer control is needed one can
- use: "-users user1.group1,..."
-
- When SSL client certification is being used and external login
- programs are being used the env. var. RFB_SSL_CLIENT_CERT
- is set to the clients certificate. Set X11VNC_SSLPEER_CN
- to use the Common Name instead of the certificate email
- address to find the unix username.
-
- miscellaneous new features and changes:
-
- The -wait and -defer defaults were lowered from 30 to 20
- milliseconds, set the values explicitly if this increases
- the load too much for your liking.
-
- In -create mode where a Xvfb session is started, mwm was added
- as a session type. setpgrp(2) is used for the spawned
- process if available. The XKEYBOARD extension is
- enabled (+kb, but it doesn't seem to always work).
- TrueColor is forced to be the default visual (recent
- Xvfb seem to choose DirectColor, this is likely a bug)
- One can also force creating a new Xvfb by setting the
- env. var. X11VNC_FINDDISPLAY_ALWAYS_FAILS (not exactly
- clear what this would be used for).
-
- The WAITBG env. var. enables -display WAIT:... to take place in
- the background.
-
- One can specify the X11VNC_SKIP_DISPLAY env. var. for a list of
- displays to exclude in the FINDDISPLAY action. This can
- also be specified via nd=... as a -unixpw login option.
-
- setsid() or setpgrp() is called for the external command spawned
- by the -gone option (since it may be long lived, e.g. a
- screen locker).
-
- The script "onetimekey" utility is provided in the classes/ssl
- subdirectory that allows a (very long) string representing
- a Client SSL certificate to be provided by the authenticating
- client, or via https cgi script (e.g. after a web login).
-
- Some bugs were fixed in the libvncserver implementation of
- UltraVNC file transfer.
-
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.9 2007-04-18
-
-
-New in the 0.9 x11vnc release:
-
- VNC Service advertising via mDNS / ZeroConf / BonJour with the
- Avahi client library. Enable via "-avahi".
-
- Implementations of UltraVNC's TextChat, SingleWindow, and
- ServerInput extensions (requires ultravnc viewer or ssvnc
- Unix viewer). They toggle the selection of a single window
- (-id), and disable (friendly) user input and viewing
- (monitor blank) at the VNC server.
-
- Short aliases "-find", "-create", "-svc", and "-xdmsvc" for
- commonly used FINDCREATEDISPLAY usage modes (to find
- the user's display or create one, etc).
-
- Reverse VNC connections (viewer listening) now work in SSL
- (-ssl) mode.
-
- miscellaneous new features and changes:
-
- New options to control the Monitor power state and keyboard/mouse
- grabbing: -forcedpms, -clientdpms, -noserverdpms,
- and -grabalways.
-
- A simple way to emulate inetd(8) to some degree via the "-loopbg"
- option.
-
- Monitor the accuracy of XDAMAGE and apply "-noxdamage" if it is
- not working well. OpenGL applications like like beryl and
- MythTv have been shown to make XDAMAGE not work properly.
-
- For Java SSL connections involving a router/firewall port
- redirection, an option -httpsredir to spare the user
- from needing to include PORT=NNN in the browser URL.
-
- A -sleepin n option to delay startup by n seconds to let redirs
- and listening clients to get started.
-
- TightVNC file transfer is now off by default; enable via
- -tightfilexfer
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.8.4 2007-02-01
-
-
-New in the 0.8.4 x11vnc release:
-
- Native Mac OS X Aqua/Quartz support. It exports the full
- display (no X11 server, etc).
-
- This provides an alternative to OSXvnc; some activities
- are faster (and see the client-side caching feature
- -ncache in the 0.8.5 development version for more
- speedups).
-
- x11vnc can act as a VNC reflector/repeater using the
- "-reflect host:N" option. This is useful for large
- classroom broadcasting or demos. You set up a number
- of reflectors to spread the network and CPU load around
- for better response.
-
- A new login mode: "-display WAIT:cmd=FINDCREATEDISPLAY -unixpw ..."
- that will Create a new X session (Xvfb, Xdummy, or
- Xorg) for the user if it cannot find the user's X
- session display via the FINDDISPLAY method. It will
- be re-found upon reconnection.
-
- This enables a simple "terminal services" mode based on
- Unix username and password and where the user does not
- have to memorize their VNC display number, etc.
-
-
- miscellaneous new features and changes:
-
- Option -nodpms to avoid problems with programs like KDE's
- kdesktop_lock that keep restarting the screen saver
- every few seconds even with active VNC clients connected.
-
- The "-N" option couples the VNC Display number to the X Display
- number. E.g. if your X DISPLAY is :2 then the VNC display
- will be :2 (i.e. using port 5902). If that port is taken
- x11vnc will exit.
-
- Wireframe copyrect detection for local user activity (e.g. someone
- sitting at the physical display moving windows). You
- can disable this with the -nowireframelocal option.
-
- To automatically fix the common mouse motion problem on XINERAMA
- (multi-headed) displays, the -xwarppointer option is
- enabled by default when XINERAMA is active. You can
- disable this with the -noxwarppointer option.
-
- By default in -reflect mode -shared is implied (it makes sense),
- use -noshared after the -reflect option to disable this.
-
- The -prog option lets you specify the full path (argv[0]) to
- the program, in case it is spawned by inetd/tcpd and
- cannot determine its path. The path is needed for the
- -http option to guess the http classes directory.
-
- Usually not needed, but there are many options for tuning the
- native Mac OS X mode: -macnodim -macnosleep -macnosaver
- -macnowait -macwheel -macnoswap -macnoresize -maciconanim
- -macmenu.
-
- An option -debug_xdamage has been added for debugging and profiling.
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.8.3 2006-11-13
-
-
-New in the 0.8.3 x11vnc release:
-
- The -ssl option provides SSL encryption and authentication
- natively via the www.openssl.org library. One can use
- from a simple self-signed certificate server certificate
- up to full CA and client certificate authentication schemes.
-
- The -sslverify option allows for authenticating VNC clients via
- their certificates in either -ssl or -stunnel modes.
-
- Certificate creation and management tools are provide in the
- -sslGenCert, -sslGenCA, and related options.
-
- An SSL enabled Java applet VNC Viewer applet is provided in
- classes/ssl/VncViewer.jar.
-
- The applet may also be loaded into the web
- browser via HTTPS, i.e one can use the VNC port,
- e.g. https://host:5900/
-
- See our "Enhanced TightVNC Viewer" project, for native
- SSL enabled viewers.
-
- The -unixpw option supports Unix username and password
- authentication. The -ssl or -localhost and -stunnel
- options (or detection of an SSH tunnel) are enforced in
- this mode to prevent password sniffing.
-
- Coupling -unixpw with -display WAIT:cmd=FINDDISPLAY provides a
- way to allow a user to login with their UNIX password
- and have their display connected to automatically.
-
- Hooks are provided in the -unixpw_cmd and "-passwdfile cmd:,custom:..."
- options to allow you to supply your own authentication
- and password lookup programs (e.g. LDAP).
-
- The "-ultrafilexfer" alias is provided and improved UltraVNC
- filetransfer rates have been achieved.
-
- The -rotate option enables you to rotate or reflect the screen
- before exporting via VNC. This is intended for use on
- handhelds and other devices where the rotation orientation
- is not "natural".
-
- miscellaneous new features and changes:
-
- Similar to -ssl, the -stunnel option starts up a SSL tunnel server
- stunnel (that must be installed separately on the system)
- to allow only encrypted SSL connections from the network.
-
- Option -sslnofail to exit immediately if there are any SSL
- connection failures.
-
- A simpler variant of -unixpw is the -unixpw_nis option that
- works in environments where the encrypted passwords are
- readable, e.g. NIS.
-
- x11vnc can be configured and built to not depend on X11 libraries
- "./configure --without-x" for -rawfb only operation
- (e.g. embedded linux console devices).
-
- Add -cursor_drag to change the mouse cursor during Drag and Drop, etc.
-
- Under the "-connect_or_exit host" option x11vnc will exit
- immediately unless the reverse connection to host
- succeeds. The "-rfbport 0" option disables TCP listening
- for connections (useful for this mode).
-
- The "-rawfb rand" and "-rawfb none" options are useful for
- testing automation scripts, etc., without requiring a
- full desktop.
-
- Reduced spewing of information at startup, use "-verbose" (also
- "-v") to turn it back on for debugging.
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.8.2 2006-07-13
-
-
-New in the 0.8.2 x11vnc release:
-
- Support for full mouse and keyboard input into the Linux
- console framebuffer /dev/fb0 in -rawfb mode
- (i.e. non-X11) by using the Linux "uinput" driver.
-
- This enables, for example, viewing and interacting
- with Qt-embedded/Qtopia-Core apps on Linux-based
- handhelds, etc.
-
- Options: -rawfb cons, -pipeinput UINPUT More info:
- http://www.karlrunge.com/x11vnc/#faq-qt-embedded
-
- Extension of the display option: -display WAIT:<disp-or-cmd>
- to delay x11vnc's opening of the X display
- until a VNC client connects (useful built-in:
- -display WAIT:cmd=FINDDISPLAY, to find a user's
- display and Xauthority data).
-
- Options -grabkbd and -grabptr have x11vnc try to grab
- the X display when VNC clients are connected to
- prevent a (non-malicious) user at the physical X
- display from performing keyboard or mouse input.
- E.g. remote help-desk support.
-
-
- miscellaneous new features and changes:
-
- -allowedcmds option to fine-tune which external commands
- may be run by x11vnc, rather than shutting
- them all off with -nocmds.
-
- -env VAR=VALUE convenience option to avoid the need of
- setting environment variables before starting
- x11vnc.
-
- -allinput option to enable libvncserver handleEventsEagerly
- parameter (not clear it yields an improvement).
-
- -rawfb rand fun/testing option using /dev/urandom as a fb.
-
- -license, -copying, -warranty option.
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.8.1 2006-06-03
-
-New in the 0.8.1 x11vnc release:
-
- Improved support for webcams and tv tuners with video4linux
- /dev/video: see the "-rawfb video" and "-pipeinput VID"
- options. (the latter gives a simple keyboard control
- of a tv tuner; see also the -freqtab option for stations).
-
- FBPM support for hardware that provides framebuffer power
- management (it needs to be disabled when vnc clients
- are connected).
-
- The -usepw option will require x11vnc to use a password of
- some sort or otherwise exit immediately. Put it in
- your ~/.x11vncrc so you don't forget.
-
- The command "x11vnc -storepasswd" will prompt for a password
- without echoing and save it in ~/.vnc/passwd
-
- The X CLIPBOARD selection is managed in addition to the
- X PRIMARY selection.
-
-
- miscellaneous new features and changes:
-
- Convenience option for accessing the Linux console: -rawfb cons
- etc. (requires /dev/fb0 to be working).
-
- clipboard/cut-text input can now be managed on a per-client
- basis.
-
- -capslock and -skip_lockkeys options can help make CapsLock work
- better.
-
- The Xdummy wrapper script is included in the source tree.
-
- A mode "-gone popup" as been added.
-
- -24to32 option to avoid 24bpp problems.
-
- -xinerama is on by default.
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.8 2006-02-13
-
-
-New in the 0.8 x11vnc release:
-
- TightVNC file transfer support is enabled via the extension to
- LibVNCServer added by Rohit Kumar.
-
- The -passwdfile option has been enhanced to handle any number
- of full-access and view only passwords in an easy to
- maintain format, and additional features.
-
- The -8to24 option enables multi-depth viewing on systems that do
- not support -overlay. The 8bpp regions are transformed
- to depth 24 TrueColor before exporting via VNC.
-
- The x11vnc source code has gone through a major reorganization.
- The build has been enhanced and many bugs fixed.
-
-
- miscellaneous new features and changes:
-
- -afteraccept option is like -accept however it enables running
- a user supplied command after client authentication
- has taken place. The RFB_* environment variables have
- been extended.
- -loop option will run x11vnc in an outer loop restarting each time
- (useful for situations where the X server restarts often).
- -slow_fb allows for slow polling for special purpose applications
- (e.g. video). -blackout noptr,WxH+X+Y,... will prevent
- the pointer from going into a blacked out region.
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help | less
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.7.2 2005-07-11
-
-
-New in the 0.7.2 x11vnc release:
-
- The X DAMAGE extension is supported to dramatically reduce
- resource consumption when idle: often 20 times less;
- and to pick up small changed regions more quickly.
-
- DAMAGE sends events indicating damaged (modified) screen
- rectangles to x11vnc. These are used as hints to focus
- the polling and also if the rectangle is below a size
- threshold it is accepted unconditionally (i.e. dragged in
- from the framebuffer). Tuning is possible with -xd_area.
-
- DAMAGE is available on recent Xorg servers and Solaris 10.
-
- -wireframe: Heuristics are used to guess when a window is being
- moved or resized and during this period show only a
- moving wireframe outline. Just like on video cards in
- the 90's, remember? This is to avoid window "lurching"
- when you move or resize one opaquely.
-
- Also, -wirecopyrect applies the VNC CopyRect encoding
- for the moved window. Both are on by default, use
- -nowireframe or -nowirecopyrect to disable (aka -nowf
- and -nowcr).
-
- -scrollcopyrect: Sniff the X11 protocol via the RECORD extension
- and to try to detect window scrolls (e.g. via scrollbar,
- Up/Down arrow, etc). When detected, the VNC CopyRect
- encoding is applied to the scrolled regions for a speedup.
-
- The contents of the scrolling window may only be
- approximate while it is being scrolled: e.g. tearing,
- bunching-up, etc. The heuristics will also miss scrolls
- by certain toolkits or applications, so those will still
- happen the slow way. To disable use -noscrollcopyrect
- (aka -noscr). Tuning is also available, see the -help
- entry.
-
- -listen: Makes x11vnc listen only on a single network interface.
- -localhost now implies '-listen localhost'.
-
- -rawfb: Instead of polling an X server framebuffer, poll a raw
- one (i.e. a mapped file or a shm segment). E.g. for
- the linux framebuffer device:
-
- -rawfb map:/dev/fb0@1024x768x32
-
- This is a bit out of x11vnc's scope but may have some
- interesting applications. Perhaps /dev/video?
-
- -pipeinput: Pipe the VNC user's pointer and keyboard input events
- to a helper program you provide. Two examples are in
- misc/vcinject.pl and misc/slide.pl. Primarily intended
- for use with -rawfb to somehow kludge-up user input,
- but it can also be used by itself.
-
- Improvements for the magnification scaling case (e.g. -scale 2)
- for use in low vision applications. It is faster and
- no-blending :nb now works correctly.
-
- More safety measures are taken WRT remote-control in the
- default mode. See the -unsafe, -safer, -privremote,
- and -nocmds options.
-
- The GUI has been improved, and running with the options "-gui icon"
- presents a small, simple gui instead of the full blown one,
- and "-gui tray" attempts to embed the small icon in the
- system tray. Use "-gui tray=setpass" to prompt for
- session password creation at startup.
-
-
- miscellaneous new features and changes:
-
- -xkb: a simple test is performed at startup to see if it is a
- good idea to apply -xkb mode for the current keyboard
- keymapping (i.e. if keysyms like !, @, [ are otherwise
- unavailable). To disable use -noxkb.
- ISO_Level3_Shift vs. Mode_switch: Set things up in -xkb mode to
- prefer ISO_Level3_Shift over Mode_switch for modtweaking.
- No override; let me know if this causes problems.
- -add_keysyms is now the default, use -noadd_keysyms to disable.
- the added keysyms are periodically deleted.
- -remap DEAD: shorthand for mapping many "dead" keysyms to their
- "un-dead" counterparts, e.g. grave -> dead_grave. For
- some VNC viewers that are unable to send the dead keysym.
- -skip_dups: skip impossible duplicate key events sent by some VNC
- viewers. -noskip_dups to disable (currently off by default).
- -sloppy_keys: try to handle sloppy keyboarding (esp. between
- different language keyboards) where, say, Shift is released
- before the key.
- -norepeat N: ping-pong N times if something else on the desktop
- restores key autorepeating (e.g. session startup). Default
- 2. Also, If the VNC client is idle for 5 min. autorepeat
- is restored.
- -wait_ui: If there is very recent user input, cut the -wait sleep
- time by the specified factor (default 2.0).
- -nowait_bog: Detection is now in place to watch for polling "bogging
- down" (e.g. lots of scrolling text from a long build in a
- terminal) and to sleep more. Use -nowait_bog to disable.
- -flag: write PORT=5900 to a flag file to aid wrapper scripts.
- -http: try to guess what the -httpdir should be and if found
- enable http listening.
- -clip WxH+X+Y: only show the specified rectangle not the
- entire screen.
- cursors are now scaled by default under -scale, use -scale_cursor
- to modify this behavior.
- -arrow n: select from some different arrow cursors (ignored under
- XFIXES cursor grabbing mode).
- -nolookup: disable DNS lookups for broken environments.
- -seldir: fine tune and debug selection transfer.
- build-time customization macros: SHARED, FOREVER, NOREPEAT,
- REMOTE_CONTROL, SMALL_FOOTPRINT, default passwd, etc.
- see the top of the x11vnc.c for more info.
- -xtrap: DEC-XTRAP extension is supported for legacy systems
- with insufficient XTEST extension (X11R5).
- -shiftcmap: for legacy systems with non-standard colormap values.
- -noxrecord: do not use the RECORD extension for anything (currently
- only -scrollcopyrect and grabserver watching use it).
- -grab_buster: fork a helper thread to watch for XGrabServer deadlock
- in x11vnc and break the grab. Under -scrollcopyrect there
- is a small window where x11vnc is vulnerable to this deadlock.
- -dbg: A "crash shell" with tips on debugging will be presented
- instead of exiting when a fatal error occurs.
- -fixscreen: periodically refresh the screen to get rid of painting
- errors, etc. induced by new features, jpeg compression, etc.
- -speeds: Tell x11vnc what the network and fb speeds are instead of
- having it try to measure them. (these speeds are used by
- various features, such as -wireframe, -scrollcopyrect, etc.).
- -wmdt: set the window manager or desktop to spare x11vnc from guessing.
- -readtimeout: set libvncserver's read timeout parameter, useful on
- very slow links that take more than 20secs to paint
- the whole screen.
- -nopw: If you use x11vnc without a password it now prints out a
- scary warning message. Use -nopw to disable the warning.
- plugged X event leaks; periodically purge any remaining buildup.
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.7.1 2005-02-24
-
-
-New in the 0.7.1 x11vnc release:
-
- Improved algorithm for approximating XFIXES cursors with
- transparency (alpha channel). No more ugly black fuzz
- around translucent cursors. Tuning parameters -alpha*
- if it is still not right.
-
- Added mechanisms to handle XFIXES cursors with transparency
- exactly (i.e. blend in the background). Works by default
- under -nocursorshape updates, and also works under limited
- circumstances for cursorshape updates if the VNC viewer
- is patched (TightVNC viewer patch provided).
-
- -solid: to improve performance switch the background to a solid
- color when clients are connected. Works on GNOME, KDE,
- CDE, and classic X.
-
- -input: allows fine-tuning the type of allowed user input
- (Keystroke, Mouse-motion, Button-click). Useful for
- certain applications of x11vnc, e.g. demos. Also
- per-client settings via -R input:xyz..
-
- -users: enables switching to different users if started as root.
- Please read the description for details.
-
- -gui ez: less daunting GUI with fewer options via '-gui ez' or
- "Misc -> simple-gui" once started.
-
- miscellaneous new features and changes:
-
- -nap is now the default, use -nonap to disable.
- -snapfb: snapshot h/w fb to RAM periodically, not clear how useful...
- -timeout n: for use in certain applications, exit if no client
- connects after n seconds.
- -oa and -logappend for appending to logfiles.
- -opts will just show the options w/o the long -help descriptions.
- if you forget to set -display, it will beep and try :0 after a bit.
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.7 2004-12-23
-
-
-New in the 0.7 x11vnc release:
-
- Support for the XFIXES X extension to show the exact mouse cursor
- shape. Requires libXfixes. For approximate cursor
- shapes also see: -cursor (none|arrow|X|some|most)
-
- -remote/-R: remote-control support: nearly every setting can be
- changed dynamically without restarting x11vnc. For
- example, "x11vnc -R shared", and "x11vnc -R scale:3/4"
- will connect to a running x11vnc server to make it shared
- and re-scaled, respectively.
-
- -gui: launches a simple tcl/tk GUI based on the remote control
- function. Requires the tcl/tk "wish" program.
-
- -overlay: support for overlay/multi-depth (e.g. 24+8) visuals
- on Solaris (SUN_OVL extension) and IRIX.
-
- -xrandr: support for the XRANDR (X Resize, Rotate and Reflection)
- extension: if the screen changes size or rotates x11vnc
- creates a new framebuffer to match it. Useful to have a VNC
- Viewer that supports NewFBSize extension. (also -padgeom)
-
- -pointer_mode: Experimental pointer input handling schemes,
- e.g.: "-pointer_mode 3" (similar to -nodragging)
-
- man page x11vnc.1 and README files created.
-
- miscellaneous new features and changes:
-
- -sb: set screen blank idle timeout
- -nocursorshape: disable cursor shape VNC extension.
- RFB_MODE = "accept" or "gone" passed to -accept/-gone commands.
- -vncconnect is now the default.
- -norepeat is now the default.
- "-id pick" to pick a window via xwininfo for the -id option.
- -sid option: like -id but crops root window instead.
- Related to remote-control: -query, -noremote, -sync,
- -deny_all, -safer, -unsafe.
-
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help
-
------------------------------------------------------------------------------
-
-
-x11vnc 0.6.2 2004-08-02
-
-New in the 0.6.2 x11vnc release:
-
- -scale option for server side scaling (e.g. -scale 2/3).
-
- -storepasswd option to create VNC password files.
-
- ~/.x11vncrc simple config file support.
-
- -cursorpos now the default (send cursor position updates to clients
- that understand them, disable with -nocursorpos)
-
- more connection info sent to the -accept and -gone commands.
-
- new keyboard related features:
-
- -modtweak is now the default (it automatically adjusts the modifier
- keys state to send a Keysym properly, disable -nomodtweak)
- this works around "ghost" keys like "< >" in XFree86.
-
- -xkb option to use XKEYBOARD extension for modtweak-ing to further
- improve the accuracy of sending Keysyms between different
- language keyboards.
-
- -skip_keycodes and -add_keysyms options to fine tune stubborn
- keyboard differences.
-
- -norepeat option to turn off X server key autorepeat when clients
- are connected (works around the repeated characters problem)
-
- -clear_mods and -clear_keys to send key release events at
- startup and exit.
-
- removed options:
-
- -hints/-nohints: we now always use hints.
-
-For more information:
-
- http://www.karlrunge.com/x11vnc/
- http://www.karlrunge.com/x11vnc/x11vnc_opts.html
- x11vnc -help
-
------------------------------------------------------------------------------
-
diff --git a/x11vnc/allowed_input_t.h b/x11vnc/allowed_input_t.h
deleted file mode 100644
index 99e814e..0000000
--- a/x11vnc/allowed_input_t.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_ALLOWED_INPUT_T_H
-#define _X11VNC_ALLOWED_INPUT_T_H
-
-/* -- allowed_input_t.h -- */
-
-typedef struct allowed_input {
- int keystroke;
- int motion;
- int button;
- int clipboard;
- int files;
-} allowed_input_t;
-
-#endif /* _X11VNC_ALLOWED_INPUT_T_H */
diff --git a/x11vnc/appshare.c b/x11vnc/appshare.c
deleted file mode 100644
index 71cdf17..0000000
--- a/x11vnc/appshare.c
+++ /dev/null
@@ -1,2124 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- appshare.c -- */
-
-#include "x11vnc.h"
-
-extern int pick_windowid(unsigned long *num);
-extern char *get_xprop(char *prop, Window win);
-extern int set_xprop(char *prop, Window win, char *value);
-extern void set_env(char *name, char *value);
-extern double dnow(void);
-
-static char *usage =
-"\n"
-" x11vnc -appshare: an experiment in application sharing via x11vnc.\n"
-"\n"
-#if !SMALL_FOOTPRINT
-" Usage: x11vnc -appshare -id windowid -connect viewer_host:0\n"
-" x11vnc -appshare -id pick -connect viewer_host:0\n"
-"\n"
-" Both the -connect option and the -id (or -sid) option are required.\n"
-" (However see the -control option below that can replace -connect.)\n"
-"\n"
-" The VNC viewer at viewer_host MUST be in 'listen' mode. This is because\n"
-" a new VNC connection (and viewer window) is established for each new\n"
-" toplevel window that the application creates. For example:\n"
-"\n"
-" vncviewer -listen 0\n"
-"\n"
-" The '-connect viewer_host:0' indicates the listening viewer to connect to.\n"
-"\n"
-" No password should be used, otherwise it will need to be typed for each\n"
-" new window (or one could use vncviewer -passwd file if the viewer supports\n"
-" that.) For security an SSH tunnel can be used:\n"
-"\n"
-" ssh -R 5500:localhost:5500 user@server_host\n"
-"\n"
-" (then use -connect localhost:0)\n"
-"\n"
-" The -id/-sid option is as in x11vnc(1). It is either a numerical window\n"
-" id or the string 'pick' which will ask the user to click on an app window.\n"
-" To track more than one application at the same time, list their window ids\n"
-" separated by commas (see also the 'add_app' command below.)\n"
-"\n"
-" Additional options:\n"
-"\n"
-" -h, -help Print this help.\n"
-" -debug Print debugging output (same as X11VNC_APPSHARE_DEBUG=1)\n"
-" -showmenus Create a new viewer window even if a new window is\n"
-" completely inside of an existing one. Default is to\n"
-" try to not show them in a new viewer window.\n"
-" -noexit Do not exit if the main app (windowid/pick) window\n"
-" goes away. Default is to exit.\n"
-" -display dpy X DISPLAY to use.\n"
-" -trackdir dir Set tracking directory to 'dir'. x11vnc -appshare does\n"
-" better if it can communicate with the x11vnc's via a\n"
-" file channel. By default a dir in /tmp is used, -trackdir\n"
-" specifies another directory, or use 'none' to disable.\n"
-" -args 'string' Pass options 'string' to x11vnc (e.g. -scale 3/4,\n"
-" -viewonly, -wait, -once, etc.)\n"
-" -env VAR=VAL Set environment variables on cmdline as in x11vnc.\n"
-"\n"
-" -control file This is a file that one edits to manage the appshare\n"
-" mode. It replaces -connect. Lines beginning with '#'\n"
-" are ignored. Initially start off with all of the\n"
-" desired clients in the file, one per line. If you add\n"
-" a new client-line, that client is connected to. If you\n"
-" delete (or comment out) a client-line, that client is\n"
-" disconnected (for this to work, do not disable trackdir.)\n"
-"\n"
-" You can also put cmd= lines in the control file to perform\n"
-" different actions. These are supported:\n"
-"\n"
-" cmd=quit Disconnect all clients and exit.\n"
-" cmd=restart Restart all of the x11vnc's.\n"
-" cmd=noop Do nothing (e.g. ping)\n"
-" cmd=x11vnc Run ps(1) looking for x11vnc's\n"
-" cmd=help Print out help text.\n"
-" cmd=add_window:win Add a window to be watched.\n"
-" cmd=del_window:win Delete a window.\n"
-" cmd=add_app:win Add an application to be watched.\n"
-" cmd=del_app:win Delete an application.\n"
-" cmd=add_client:host Add client ('internal' mode only)\n"
-" cmd=del_client:host Del client ('internal' mode only)\n"
-" cmd=list_windows List all tracked windows.\n"
-" cmd=list_apps List all tracked applications.\n"
-" cmd=list_clients List all connected clients.\n"
-" cmd=list_all List all three.\n"
-" cmd=print_logs Print out the x11vnc logfiles.\n"
-" cmd=debug:n Set -debug to n (0 or 1).\n"
-" cmd=showmenus:n Set -showmenus to n (0 or 1).\n"
-" cmd=noexit:n Set -noexit to n (0 or 1).\n"
-"\n"
-" See the '-command internal' mode described below for a way\n"
-" that tracks connected clients internally (not in a file.)\n"
-"\n"
-" In '-shell' mode (see below) you can type in the above\n"
-" without the leading 'cmd='.\n"
-"\n"
-" For 'add_window' and 'del_window' the 'win' can be a\n"
-" numerical window id or 'pick'. Same for 'add_app'. Be\n"
-" sure to remove or comment out the add/del line quickly\n"
-" (e.g. before picking) or it will be re-run the next time\n"
-" the file is processed.\n"
-"\n"
-" If a file with the same name as the control file but\n"
-" ending with suffix '.cmd' is found, then commands in it\n"
-" (cmd=...) are processed and then the file is truncated.\n"
-" This allows 'one time' command actions to be run. Any\n"
-" client hostnames in the '.cmd' file are ignored. Also\n"
-" see below for the X11VNC_APPSHARE_COMMAND X property\n"
-" which is similar to '.cmd'\n"
-"\n"
-" -control internal Manage connected clients internally, see below.\n"
-" -control shell Same as: -shell -control internal\n"
-"\n"
-" -delay secs Maximum timeout delay before re-checking the control file.\n"
-" It can be a fraction, e.g. -delay 0.25 Default 0.5\n"
-"\n"
-" -shell Simple command line for '-control internal' mode (see the\n"
-" details of this mode below.) Enter '?' for command list.\n"
-"\n"
-" To stop x11vnc -appshare press Ctrl-C, or (if -noexit not supplied) delete\n"
-" the initial app window or exit the application. Or cmd=quit in -control mode.\n"
-"\n"
-#if 0
-" If you want your setup to survive periods of time where there are no clients\n"
-" connected you will need to supply -args '-forever' otherwise the x11vnc's\n"
-" will exit when the last client disconnects. Howerver, _starting_ with no\n"
-" clients (e.g. empty control file) will work without -args '-forever'.\n"
-"\n"
-#endif
-" In addition to the '.cmd' file channel, for faster response you can set\n"
-" X11VNC_APPSHARE_COMMAND X property on the root window to the string that\n"
-" would go into the '.cmd' file. For example:\n"
-"\n"
-" xprop -root -f X11VNC_APPSHARE_COMMAND 8s -set X11VNC_APPSHARE_COMMAND cmd=quit\n"
-"\n"
-" The property value will be set to 'DONE' after the command(s) is processed.\n"
-"\n"
-" If -control file is specified as 'internal' then no control file is used\n"
-" and client tracking is done internally. You must add and delete clients\n"
-" with the cmd=add_client:<client> and cmd=del_client:<client> commands.\n"
-" Note that '-control internal' is required for '-shell' mode. Using\n"
-" '-control shell' implies internal mode and -shell.\n"
-"\n"
-" Limitations:\n"
-"\n"
-" This is a quick lash-up, many things will not work properly.\n"
-"\n"
-" The main idea is to provide simple application sharing for two or more\n"
-" parties to collaborate without needing to share the entire desktop. It\n"
-" provides an improvement over -id/-sid that only shows a single window.\n"
-"\n"
-" Only reverse connections can be done. (Note: one can specify multiple\n"
-" viewing hosts via: -connect host1,host2,host3 or add/remove them\n"
-" dynamically as described above.)\n"
-"\n"
-" If a new window obscures an old one, you will see some or all of the\n"
-" new window in the old one. The hope is this is a popup dialog or menu\n"
-" that will go away soon. Otherwise a user at the physical display will\n"
-" need to move it. (See also the SSVNC viewer features described below.) \n"
-"\n"
-" The viewer side cannot resize or make windows move on the physical\n"
-" display. Again, a user at the physical display may need to help, or\n"
-" use the SSVNC viewer (see Tip below.)\n"
-"\n"
-" Tip: If the application has its own 'resize corner', then dragging\n"
-" it may successfully resize the application window.\n"
-" Tip: Some desktop environments enable moving a window via, say,\n"
-" Alt+Left-Button-Drag. One may be able to move a window this way.\n"
-" Also, e.g., Alt+Right-Button-Drag may resize a window.\n"
-" Tip: Clicking on part of an obscured window may raise it to the top.\n"
-" Also, e.g., Alt+Middle-Button may toggle Raise/Lower.\n"
-"\n"
-" Tip: The SSVNC 1.0.25 unix and macosx vncviewer has 'EscapeKeys' hot\n"
-" keys that will move, resize, raise, and lower the window via the\n"
-" x11vnc -remote_prefix X11VNC_APPSHARE_CMD: feature. So in the\n"
-" viewer while holding down Shift_L+Super_L+Alt_L the arrow keys\n"
-" move the window, PageUp/PageDn/Home/End resize it, and - and +\n"
-" raise and lower it. Key 'M' or Button1 moves the remote window\n"
-" to the +X+Y of the viewer window. Key 'D' or Button3 deletes\n"
-" the remote window.\n"
-"\n"
-" You can run the SSVNC vncviewer with options '-escape default',\n"
-" '-multilisten' and '-env VNCVIEWER_MIN_TITLE=1'; or just run\n"
-" with option '-appshare' to enable these and automatic placement.\n"
-"\n"
-" If any part of a window goes off of the display screen, then x11vnc\n"
-" may be unable to poll it (without crashing), and so the window will\n"
-" stop updating until the window is completely on-screen again.\n"
-"\n"
-" The (stock) vnc viewer does not know where to best position each new\n"
-" viewer window; it likely centers each one (including when resized.)\n"
-" Note: The SSVNC viewer in '-appshare' mode places them correctly.\n"
-"\n"
-" Deleting a viewer window does not delete the real window.\n"
-" Note: The SSVNC viewer Shift+EscapeKeys+Button3 deletes it.\n"
-"\n"
-" Sometimes new window detection fails.\n"
-"\n"
-" Sometimes menu/popup detection fails.\n"
-"\n"
-" Sometimes the contents of a menu/popup window have blacked-out regions.\n"
-" Try -sid or -showmenus as a workaround.\n"
-"\n"
-" If the application starts up a new application (a different process)\n"
-" that new application will not be tracked (but, unfortunately, it may\n"
-" cover up existing windows that are being tracked.) See cmd=add_window\n"
-" and cmd=add_app described above.\n"
-"\n"
-#endif
-;
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define WMAX 192
-#define CMAX 128
-#define AMAX 32
-
-static Window root = None;
-static Window watch[WMAX];
-static Window apps[WMAX];
-static int state[WMAX];
-static char *clients[CMAX];
-static XWindowAttributes attr;
-static char *ticker_atom_str = "X11VNC_APPSHARE_TICKER";
-static Atom ticker_atom = None;
-static char *cmd_atom_str = "X11VNC_APPSHARE_COMMAND";
-static Atom cmd_atom = None;
-static char *connect_to = NULL;
-static char *x11vnc_args = "";
-static char *id_opt = "-id";
-static int skip_menus = 1;
-static int exit_no_app_win = 1;
-static int shell = 0;
-static int tree_depth = 3;
-static char *prompt = "appshare> ";
-static char *x11vnc = "x11vnc";
-static char *control = NULL;
-static char *trackdir = "unset";
-static char *trackpre = "/tmp/x11vnc-appshare-trackdir-tmp";
-static char *tracktmp = NULL;
-static char unique_tag[100];
-static int use_forever = 1;
-static int last_event_type = 0;
-static pid_t helper_pid = 0;
-static pid_t parent_pid = 0;
-static double helper_delay = 0.5;
-static int appshare_debug = 0;
-static double start_time = 0.0;
-
-static void get_wm_name(Window win, char **name);
-static int win_attr(Window win);
-static int get_xy(Window win, int *x, int *y);
-static Window check_inside(Window win);
-static int ours(Window win);
-static void destroy_win(Window win);
-static int same_app(Window win, Window app);
-
-static void ff(void) {
- fflush(stdout);
- fflush(stderr);
-}
-
-static int find_win(Window win) {
- int i;
- for (i=0; i < WMAX; i++) {
- if (watch[i] == win) {
- return i;
- }
- }
- return -1;
-}
-
-static int find_app(Window app) {
- int i;
- for (i=0; i < AMAX; i++) {
- if (apps[i] == app) {
- return i;
- }
- }
- return -1;
-}
-
-static int find_client(char *cl) {
- int i;
- for (i=0; i < CMAX; i++) {
- if (cl == NULL) {
- if (clients[i] == NULL) {
- return i;
- }
- continue;
- }
- if (clients[i] == NULL) {
- continue;
- }
- if (!strcmp(clients[i], cl)) {
- return i;
- }
- }
- return -1;
-}
-
-static int trackdir_pid(Window win) {
- FILE *f;
- int ln = 0, pid = 0;
- char line[1024];
-
- if (!trackdir) {
- return 0;
- }
- sprintf(tracktmp, "%s/0x%lx.log", trackdir, win);
- f = fopen(tracktmp, "r");
- if (!f) {
- return 0;
- }
- while (fgets(line, sizeof(line), f) != NULL) {
- if (ln++ > 30) {
- break;
- }
- if (strstr(line, "x11vnc version:")) {
- char *q = strstr(line, "pid:");
- if (q) {
- int p;
- if (sscanf(q, "pid: %d", &p) == 1) {
- if (p > 0) {
- pid = p;
- break;
- }
- }
- }
- }
- }
- fclose(f);
- return pid;
-}
-
-static void trackdir_cleanup(Window win) {
- char *suffix[] = {"log", "connect", NULL};
- int i=0;
- if (!trackdir) {
- return;
- }
- while (suffix[i] != NULL) {
- sprintf(tracktmp, "%s/0x%lx.%s", trackdir, win, suffix[i]);
- if (appshare_debug && !strcmp(suffix[i], "log")) {
- fprintf(stderr, "keeping: %s\n", tracktmp);
- ff();
- } else {
- if (appshare_debug) {
- fprintf(stderr, "removing: %s\n", tracktmp);
- ff();
- }
- unlink(tracktmp);
- }
- i++;
- }
-}
-
-static void launch(Window win) {
- char *cmd, *tmp, *connto, *name;
- int len, timeo = 30, uf = use_forever;
- int w = 0, h = 0, x = 0, y = 0;
-
- if (win_attr(win)) {
- /* maybe switch to debug only. */
- w = attr.width;
- h = attr.height;
- get_xy(win, &x, &y);
- }
-
- get_wm_name(win, &name);
-
- if (strstr(x11vnc_args, "-once")) {
- uf = 0;
- }
-
- if (control) {
- int i = 0;
- len = 0;
- for (i=0; i < CMAX; i++) {
- if (clients[i] != NULL) {
- len += strlen(clients[i]) + 2;
- }
- }
- connto = (char *) calloc(len, 1);
- for (i=0; i < CMAX; i++) {
- if (clients[i] != NULL) {
- if (connto[0] != '\0') {
- strcat(connto, ",");
- }
- strcat(connto, clients[i]);
- }
- }
- } else {
- connto = strdup(connect_to);
- }
- if (!strcmp(connto, "")) {
- timeo = 0;
- }
- if (uf) {
- timeo = 0;
- }
-
- len = 1000 + strlen(x11vnc) + strlen(connto) + strlen(x11vnc_args)
- + 3 * (trackdir ? strlen(trackdir) : 100);
-
- cmd = (char *) calloc(len, 1);
- tmp = (char *) calloc(len, 1);
-
- sprintf(cmd, "%s %s 0x%lx -bg -quiet %s -nopw -rfbport 0 "
- "-timeout %d -noxdamage -noxinerama -norc -repeat -speeds dsl "
- "-env X11VNC_AVOID_WINDOWS=never -env X11VNC_APPSHARE_ACTIVE=1 "
- "-env X11VNC_NO_CHECK_PM=1 -env %s -novncconnect -shared -nonap "
- "-remote_prefix X11VNC_APPSHARE_CMD:",
- x11vnc, id_opt, win, use_forever ? "-forever" : "-once", timeo, unique_tag);
-
- if (trackdir) {
- FILE *f;
- sprintf(tracktmp, " -noquiet -o %s/0x%lx.log", trackdir, win);
- strcat(cmd, tracktmp);
- sprintf(tracktmp, "%s/0x%lx.connect", trackdir, win);
- f = fopen(tracktmp, "w");
- if (f) {
- fprintf(f, "%s", connto);
- fclose(f);
- sprintf(tmp, " -connect_or_exit '%s'", tracktmp);
- strcat(cmd, tmp);
- } else {
- sprintf(tmp, " -connect_or_exit '%s'", connto);
- strcat(cmd, tmp);
- }
- } else {
- if (!strcmp(connto, "")) {
- sprintf(tmp, " -connect '%s'", connto);
- } else {
- sprintf(tmp, " -connect_or_exit '%s'", connto);
- }
- strcat(cmd, tmp);
- }
- if (uf) {
- char *q = strstr(cmd, "-connect_or_exit");
- if (q) q = strstr(q, "_or_exit");
- if (q) {
- unsigned int i;
- for (i=0; i < strlen("_or_exit"); i++) {
- *q = ' ';
- q++;
- }
- }
- }
-
- strcat(cmd, " ");
- strcat(cmd, x11vnc_args);
-
- fprintf(stdout, "launching: x11vnc for window 0x%08lx %dx%d+%d+%d \"%s\"\n",
- win, w, h, x, y, name);
-
- if (appshare_debug) {
- fprintf(stderr, "\nrunning: %s\n\n", cmd);
- }
- ff();
-
- system(cmd);
-
- free(cmd);
- free(tmp);
- free(connto);
- free(name);
-}
-
-static void stop(Window win) {
- char *cmd;
- int pid = -1;
- int f = find_win(win);
- if (f < 0 || win == None) {
- return;
- }
- if (state[f] == 0) {
- return;
- }
- if (trackdir) {
- pid = trackdir_pid(win);
- if (pid > 0) {
- if (appshare_debug) {fprintf(stderr,
- "sending SIGTERM to: %d\n", pid); ff();}
- kill((pid_t) pid, SIGTERM);
- }
- }
-
- cmd = (char *) malloc(1000 + strlen(x11vnc));
- sprintf(cmd, "pkill -TERM -f '%s %s 0x%lx -bg'", x11vnc, id_opt, win);
- if (appshare_debug) {
- fprintf(stdout, "stopping: 0x%08lx - %s\n", win, cmd);
- } else {
- fprintf(stdout, "stopping: x11vnc for window 0x%08lx "
- "(pid: %d)\n", win, pid);
- }
- ff();
- system(cmd);
-
- sprintf(cmd, "(sleep 0.25 2>/dev/null || sleep 1; pkill -KILL -f '%s "
- "%s 0x%lx -bg') &", x11vnc, id_opt, win);
- system(cmd);
-
- if (trackdir) {
- trackdir_cleanup(win);
- }
-
- free(cmd);
-}
-
-static void kill_helper_pid(void) {
- int status;
- if (helper_pid <= 0) {
- return;
- }
- fprintf(stderr, "stopping: helper_pid: %d\n", (int) helper_pid);
- kill(helper_pid, SIGTERM);
- usleep(50 * 1000);
- kill(helper_pid, SIGKILL);
- usleep(25 * 1000);
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_WAITPID
- waitpid(helper_pid, &status, WNOHANG);
-#endif
-}
-
-static void be_helper_pid(char *dpy_str) {
- int cnt = 0;
- int ms = (int) (1000 * helper_delay);
- double last_check = 0.0;
-
- if (ms < 50) ms = 50;
-
-#if NO_X11
- fprintf(stderr, "be_helper_pid: not compiled with X11.\n");
-#else
- dpy = XOpenDisplay(dpy_str);
- ticker_atom = XInternAtom(dpy, ticker_atom_str, False);
-
- while (1) {
- char tmp[32];
- sprintf(tmp, "HELPER_CNT_%08d", cnt++);
- XChangeProperty(dpy, DefaultRootWindow(dpy), ticker_atom, XA_STRING, 8,
- PropModeReplace, (unsigned char *) tmp, strlen(tmp));
- XFlush(dpy);
- usleep(ms*1000);
- if (parent_pid > 0) {
- if(dnow() > last_check + 1.0) {
- last_check = dnow();
- if (kill(parent_pid, 0) != 0) {
- fprintf(stderr, "be_helper_pid: parent %d is gone.\n", (int) parent_pid);
- break;
- }
- }
- }
- }
-#endif
- exit(0);
-}
-
-static void print_logs(void) {
- if (trackdir) {
- DIR *dir = opendir(trackdir);
- if (dir) {
- struct dirent *dp;
- while ( (dp = readdir(dir)) != NULL) {
- FILE *f;
- char *name = dp->d_name;
- if (!strcmp(name, ".") || !strcmp(name, "..")) {
- continue;
- }
- if (strstr(name, "0x") != name) {
- continue;
- }
- if (strstr(name, ".log") == NULL) {
- continue;
- }
- sprintf(tracktmp, "%s/%s", trackdir, name);
- f = fopen(tracktmp, "r");
- if (f) {
- char line[1024];
- fprintf(stderr, "===== x11vnc log %s =====\n", tracktmp);
- while (fgets(line, sizeof(line), f) != NULL) {
- fprintf(stderr, "%s", line);
- }
- fprintf(stderr, "\n");
- ff();
- fclose(f);
- }
- }
- closedir(dir);
- }
- }
-}
-
-static void appshare_cleanup(int s) {
- int i;
- if (s) {}
-
- if (use_forever) {
- /* launch this backup in case they kill -9 us before we terminate everything */
- char cmd[1000];
- sprintf(cmd, "(sleep 3; pkill -TERM -f '%s') &", unique_tag);
- if (appshare_debug) fprintf(stderr, "%s\n", cmd);
- system(cmd);
- }
-
- for (i=0; i < WMAX; i++) {
- if (watch[i] != None) {
- stop(watch[i]);
- }
- }
-
- if (trackdir) {
- DIR *dir = opendir(trackdir);
- if (dir) {
- struct dirent *dp;
- while ( (dp = readdir(dir)) != NULL) {
- char *name = dp->d_name;
- if (!strcmp(name, ".") || !strcmp(name, "..")) {
- continue;
- }
- if (strstr(name, "0x") != name) {
- fprintf(stderr, "skipping: %s\n", name);
- continue;
- }
- if (!appshare_debug) {
- fprintf(stderr, "removing: %s\n", name);
- sprintf(tracktmp, "%s/%s", trackdir, name);
- unlink(tracktmp);
- } else {
- if (appshare_debug) fprintf(stderr, "keeping: %s\n", name);
- }
- }
- closedir(dir);
- }
- if (!appshare_debug) {
- if (strstr(trackdir, trackpre) == trackdir) {
- if (appshare_debug) fprintf(stderr, "removing: %s\n", trackdir);
- rmdir(trackdir);
- }
- }
- ff();
- }
-
- kill_helper_pid();
-
-#if !NO_X11
- XCloseDisplay(dpy);
-#endif
- fprintf(stdout, "done.\n");
- ff();
- exit(0);
-}
-
-static int trap_xerror(Display *d, XErrorEvent *error) {
- if (d || error) {}
- return 0;
-}
-
-#if 0
-typedef struct {
- int x, y; /* location of window */
- int width, height; /* width and height of window */
- int border_width; /* border width of window */
- int depth; /* depth of window */
- Visual *visual; /* the associated visual structure */
- Window root; /* root of screen containing window */
- int class; /* InputOutput, InputOnly*/
- int bit_gravity; /* one of bit gravity values */
- int win_gravity; /* one of the window gravity values */
- int backing_store; /* NotUseful, WhenMapped, Always */
- unsigned long backing_planes;/* planes to be preserved if possible */
- unsigned long backing_pixel;/* value to be used when restoring planes */
- Bool save_under; /* boolean, should bits under be saved? */
- Colormap colormap; /* color map to be associated with window */
- Bool map_installed; /* boolean, is color map currently installed*/
- int map_state; /* IsUnmapped, IsUnviewable, IsViewable */
- long all_event_masks; /* set of events all people have interest in*/
- long your_event_mask; /* my event mask */
- long do_not_propagate_mask; /* set of events that should not propagate */
- Bool override_redirect; /* boolean value for override-redirect */
- Screen *screen; /* back pointer to correct screen */
-} XWindowAttributes;
-#endif
-
-static void get_wm_name(Window win, char **name) {
- int ok;
-
-#if !NO_X11
- XErrorHandler old_handler = XSetErrorHandler(trap_xerror);
- ok = XFetchName(dpy, win, name);
- XSetErrorHandler(old_handler);
-#endif
-
- if (!ok || *name == NULL) {
- *name = strdup("unknown");
- }
-}
-
-static int win_attr(Window win) {
- int ok = 0;
-#if !NO_X11
- XErrorHandler old_handler = XSetErrorHandler(trap_xerror);
- ok = XGetWindowAttributes(dpy, win, &attr);
- XSetErrorHandler(old_handler);
-#endif
-
- if (ok) {
- return 1;
- } else {
- return 0;
- }
-}
-
-static void win_select(Window win, int ignore) {
-#if !NO_X11
- XErrorHandler old_handler = XSetErrorHandler(trap_xerror);
- if (ignore) {
- XSelectInput(dpy, win, 0);
- } else {
- XSelectInput(dpy, win, SubstructureNotifyMask);
- }
- XSync(dpy, False);
- XSetErrorHandler(old_handler);
-#endif
-}
-
-static Window get_parent(Window win) {
- int ok;
- Window r, parent = None, *list = NULL;
- unsigned int nchild;
-
-#if !NO_X11
- XErrorHandler old_handler = XSetErrorHandler(trap_xerror);
- ok = XQueryTree(dpy, win, &r, &parent, &list, &nchild);
- XSetErrorHandler(old_handler);
-
- if (!ok) {
- return None;
- }
- if (list) {
- XFree(list);
- }
-#endif
- return parent;
-}
-
-static int get_xy(Window win, int *x, int *y) {
- Window cr;
- Bool rc = False;
-#if !NO_X11
- XErrorHandler old_handler = XSetErrorHandler(trap_xerror);
-
- rc = XTranslateCoordinates(dpy, win, root, 0, 0, x, y, &cr);
- XSetErrorHandler(old_handler);
-#endif
-
- if (!rc) {
- return 0;
- } else {
- return 1;
- }
-}
-
-static Window check_inside(Window win) {
- int i, nwin = 0;
- int w, h, x, y;
- int Ws[WMAX], Hs[WMAX], Xs[WMAX], Ys[WMAX];
- Window wins[WMAX];
-
- if (!win_attr(win)) {
- return None;
- }
-
- /* store them first to give the win app more time to settle. */
- for (i=0; i < WMAX; i++) {
- int X, Y;
- Window wchk = watch[i];
- if (wchk == None) {
- continue;
- }
- if (state[i] == 0) {
- continue;
- }
- if (!win_attr(wchk)) {
- continue;
- }
- if (!get_xy(wchk, &X, &Y)) {
- continue;
- }
-
- Xs[nwin] = X;
- Ys[nwin] = Y;
- Ws[nwin] = attr.width;
- Hs[nwin] = attr.height;
- wins[nwin] = wchk;
- nwin++;
- }
-
- if (nwin == 0) {
- return None;
- }
-
- if (!win_attr(win)) {
- return None;
- }
- w = attr.width;
- h = attr.height;
-
- get_xy(win, &x, &y);
- if (!get_xy(win, &x, &y)) {
- return None;
- }
-
- for (i=0; i < nwin; i++) {
- int X, Y, W, H;
- Window wchk = wins[i];
- X = Xs[i];
- Y = Ys[i];
- W = Ws[i];
- H = Hs[i];
-
- if (appshare_debug) fprintf(stderr, "check inside: 0x%lx %dx%d+%d+%d %dx%d+%d+%d\n", wchk, w, h, x, y, W, H, X, Y);
-
- if (X <= x && Y <= y) {
- if (x + w <= X + W && y + h < Y + H) {
- return wchk;
- }
- }
- }
-
- return None;
-}
-
-static void add_win(Window win) {
- int idx = find_win(win);
- int free = find_win(None);
- if (idx >= 0) {
- if (appshare_debug) {fprintf(stderr, "already watching window: 0x%lx\n", win); ff();}
- return;
- }
- if (free < 0) {
- fprintf(stderr, "ran out of slots for window: 0x%lx\n", win); ff();
- return;
- }
-
- if (appshare_debug) {fprintf(stderr, "watching: 0x%lx at %d\n", win, free); ff();}
-
- watch[free] = win;
- state[free] = 0;
-
- win_select(win, 0);
-}
-
-static void delete_win(Window win) {
- int i;
- for (i=0; i < WMAX; i++) {
- if (watch[i] == win) {
- watch[i] = None;
- state[i] = 0;
- if (appshare_debug) {fprintf(stderr, "deleting: 0x%lx at %d\n", win, i); ff();}
- }
- }
-}
-
-static void recurse_search(int level, int level_max, Window top, Window app, int *nw) {
- Window w, r, parent, *list = NULL;
- unsigned int nchild;
- int ok = 0;
-
- if (appshare_debug > 1) {
- fprintf(stderr, "level: %d level_max: %d top: 0x%lx app: 0x%lx\n", level, level_max, top, app);
- }
- if (level >= level_max) {
- return;
- }
-
-#if !NO_X11
- ok = XQueryTree(dpy, top, &r, &parent, &list, &nchild);
- if (ok) {
- int i;
- for (i=0; i < (int) nchild; i++) {
- w = list[i];
- if (w == None || find_win(w) >= 0) {
- continue;
- }
- if (ours(w) && w != app) {
- if (appshare_debug) fprintf(stderr, "add level %d 0x%lx %d/%d\n",
- level, w, i, nchild);
- add_win(w);
- (*nw)++;
- }
- }
- for (i=0; i < (int) nchild; i++) {
- w = list[i];
- if (w == None || ours(w)) {
- continue;
- }
- recurse_search(level+1, level_max, w, app, nw);
- }
- }
- if (list) {
- XFree(list);
- }
-#endif
-}
-
-static void add_app(Window app) {
- int i, nw = 0, free = -1;
- XErrorHandler old_handler;
-
-#if !NO_X11
- i = find_app(app);
- if (i >= 0) {
- fprintf(stderr, "already tracking app: 0x%lx\n", app);
- return;
- }
- for (i=0; i < AMAX; i++) {
- if (same_app(apps[i], app)) {
- fprintf(stderr, "already tracking app: 0x%lx via 0x%lx\n", app, apps[i]);
- return;
- }
- }
- free = find_app(None);
- if (free < 0) {
- fprintf(stderr, "ran out of app slots.\n");
- return;
- }
- apps[free] = app;
-
- add_win(app);
-
- old_handler = XSetErrorHandler(trap_xerror);
- recurse_search(0, tree_depth, root, app, &nw);
- XSetErrorHandler(old_handler);
-#endif
- fprintf(stderr, "tracking %d windows related to app window 0x%lx\n", nw, app);
-}
-
-static void del_app(Window app) {
- int i;
- for (i=0; i < WMAX; i++) {
- Window win = watch[i];
- if (win != None) {
- if (same_app(app, win)) {
- destroy_win(win);
- }
- }
- }
- for (i=0; i < AMAX; i++) {
- Window app2 = apps[i];
- if (app2 != None) {
- if (same_app(app, app2)) {
- apps[i] = None;
- }
- }
- }
-}
-
-static void wait_until_empty(char *file) {
- double t = 0.0, dt = 0.05;
- while (t < 1.0) {
- struct stat sb;
- if (stat(file, &sb) != 0) {
- return;
- }
- if (sb.st_size == 0) {
- return;
- }
- t += dt;
- usleep( (int) (dt * 1000 * 1000) );
- }
-}
-
-static void client(char *client, int add) {
- DIR *dir;
- struct dirent *dp;
-
- if (!client) {
- return;
- }
- if (!trackdir) {
- fprintf(stderr, "no trackdir, cannot %s client: %s\n",
- add ? "add" : "disconnect", client);
- ff();
- return;
- }
- fprintf(stdout, "%s client: %s\n", add ? "adding " : "deleting", client);
-
- dir = opendir(trackdir);
- if (!dir) {
- fprintf(stderr, "could not opendir trackdir: %s\n", trackdir);
- return;
- }
- while ( (dp = readdir(dir)) != NULL) {
- char *name = dp->d_name;
- if (!strcmp(name, ".") || !strcmp(name, "..")) {
- continue;
- }
- if (strstr(name, "0x") != name) {
- continue;
- }
- if (strstr(name, ".connect")) {
- FILE *f;
- char *tmp;
- Window twin;
-
- if (scan_hexdec(name, &twin)) {
- int f = find_win(twin);
- if (appshare_debug) {
- fprintf(stderr, "twin: 0x%lx name=%s f=%d\n", twin, name, f);
- ff();
- }
- if (f < 0) {
- continue;
- }
- }
-
- tmp = (char *) calloc(100 + strlen(client), 1);
- sprintf(tracktmp, "%s/%s", trackdir, name);
- if (add) {
- sprintf(tmp, "%s\n", client);
- } else {
- sprintf(tmp, "cmd=close:%s\n", client);
- }
- wait_until_empty(tracktmp);
- f = fopen(tracktmp, "w");
- if (f) {
- if (appshare_debug) {
- fprintf(stderr, "%s client: %s + %s",
- add ? "add" : "disconnect", tracktmp, tmp);
- ff();
- }
- fprintf(f, "%s", tmp);
- fclose(f);
- }
- free(tmp);
- }
- }
- closedir(dir);
-}
-
-static void mapped(Window win) {
- int f;
- if (win == None) {
- return;
- }
- f = find_win(win);
- if (f < 0) {
- if (win_attr(win)) {
- if (get_parent(win) == root) {
- /* XXX more cases? */
- add_win(win);
- }
- }
- }
-}
-
-static void unmapped(Window win) {
- int f = find_win(win);
- if (f < 0 || win == None) {
- return;
- }
- stop(win);
- state[f] = 0;
-}
-
-static void destroy_win(Window win) {
- stop(win);
- delete_win(win);
-}
-
-static Window parse_win(char *str) {
- Window win = None;
- if (!str) {
- return None;
- }
- if (!strcmp(str, "pick") || !strcmp(str, "p")) {
- static double last_pick = 0.0;
- if (dnow() < start_time + 15) {
- ;
- } else if (dnow() < last_pick + 2) {
- return None;
- } else {
- last_pick = dnow();
- }
- if (!pick_windowid(&win)) {
- fprintf(stderr, "parse_win: bad window pick.\n");
- win = None;
- }
- if (win == root) {
- fprintf(stderr, "parse_win: ignoring pick of rootwin 0x%lx.\n", win);
- win = None;
- }
- ff();
- } else if (!scan_hexdec(str, &win)) {
- win = None;
- }
- return win;
-}
-
-static void add_or_del_app(char *str, int add) {
- Window win = parse_win(str);
-
- if (win != None) {
- if (add) {
- add_app(win);
- } else {
- del_app(win);
- }
- } else if (!strcmp(str, "all")) {
- if (!add) {
- int i;
- for (i=0; i < AMAX; i++) {
- if (apps[i] != None) {
- del_app(apps[i]);
- }
- }
- }
- }
-}
-
-static void add_or_del_win(char *str, int add) {
- Window win = parse_win(str);
-
- if (win != None) {
- int f = find_win(win);
- if (add) {
- if (f < 0 && win_attr(win)) {
- add_win(win);
- }
- } else {
- if (f >= 0) {
- destroy_win(win);
- }
- }
- } else if (!strcmp(str, "all")) {
- if (!add) {
- int i;
- for (i=0; i < WMAX; i++) {
- if (watch[i] != None) {
- destroy_win(watch[i]);
- }
- }
- }
- }
-}
-
-static void add_or_del_client(char *str, int add) {
- int i;
-
- if (!str) {
- return;
- }
- if (strcmp(control, "internal")) {
- return;
- }
- if (add) {
- int idx = find_client(str);
- int free = find_client(NULL);
-
- if (idx >=0) {
- fprintf(stderr, "already tracking client: %s in slot %d\n", str, idx);
- ff();
- return;
- }
- if (free < 0) {
- static int cnt = 0;
- if (cnt++ < 10) {
- fprintf(stderr, "ran out of client slots.\n");
- ff();
- }
- return;
- }
- clients[free] = strdup(str);
- client(str, 1);
- } else {
- if (str[0] == '#' || str[0] == '%') {
- if (sscanf(str+1, "%d", &i) == 1) {
- i--;
- if (0 <= i && i < CMAX) {
- if (clients[i] != NULL) {
- client(clients[i], 0);
- free(clients[i]);
- clients[i] = NULL;
- return;
- }
- }
- }
- } else if (!strcmp(str, "all")) {
- for (i=0; i < CMAX; i++) {
- if (clients[i] == NULL) {
- continue;
- }
- client(clients[i], 0);
- free(clients[i]);
- clients[i] = NULL;
- }
- return;
- }
-
- i = find_client(str);
- if (i >= 0) {
- free(clients[i]);
- clients[i] = NULL;
- client(str, 0);
- }
- }
-}
-
-static void restart_x11vnc(void) {
- int i, n = 0;
- Window win, active[WMAX];
- for (i=0; i < WMAX; i++) {
- win = watch[i];
- if (win == None) {
- continue;
- }
- if (state[i]) {
- active[n++] = win;
- stop(win);
- }
- }
- if (n) {
- usleep(1500 * 1000);
- }
- for (i=0; i < n; i++) {
- win = active[i];
- launch(win);
- }
-}
-
-static unsigned long cmask = 0x3fc00000; /* 00111111110000000000000000000000 */
-
-static void init_cmask(void) {
- /* dependent on the X server implementation; XmuClientWindow better? */
- /* xc/programs/Xserver/include/resource.h */
- int didit = 0, res_cnt = 29, client_bits = 8;
-
- if (getenv("X11VNC_APPSHARE_CLIENT_MASK")) {
- unsigned long cr;
- if (sscanf(getenv("X11VNC_APPSHARE_CLIENT_MASK"), "0x%lx", &cr) == 1) {
- cmask = cr;
- didit = 1;
- }
- } else if (getenv("X11VNC_APPSHARE_CLIENT_BITS")) {
- int cr = atoi(getenv("X11VNC_APPSHARE_CLIENT_BITS"));
- if (cr > 0) {
- client_bits = cr;
- }
- }
- if (!didit) {
- cmask = (((1 << client_bits) - 1) << (res_cnt-client_bits));
- }
- fprintf(stderr, "client_mask: 0x%08lx\n", cmask);
-}
-
-static int same_app(Window win, Window app) {
- if ( (win & cmask) == (app & cmask) ) {
- return 1;
- } else {
- return 0;
- }
-}
-
-static int ours(Window win) {
- int i;
- for (i=0; i < AMAX; i++) {
- if (apps[i] != None) {
- if (same_app(win, apps[i])) {
- return 1;
- }
- }
- }
- return 0;
-}
-
-static void list_clients(void) {
- int i, n = 0;
- for (i=0; i < CMAX; i++) {
- if (clients[i] == NULL) {
- continue;
- }
- fprintf(stdout, "client[%02d] %s\n", ++n, clients[i]);
- }
- fprintf(stdout, "total clients: %d\n", n);
- ff();
-}
-
-static void list_windows(void) {
- int i, n = 0;
- for (i=0; i < WMAX; i++) {
- char *name;
- Window win = watch[i];
- if (win == None) {
- continue;
- }
- get_wm_name(win, &name);
- fprintf(stdout, "window[%02d] 0x%08lx state: %d slot: %03d \"%s\"\n",
- ++n, win, state[i], i, name);
- free(name);
- }
- fprintf(stdout, "total windows: %d\n", n);
- ff();
-}
-
-static void list_apps(void) {
- int i, n = 0;
- for (i=0; i < AMAX; i++) {
- char *name;
- Window win = apps[i];
- if (win == None) {
- continue;
- }
- get_wm_name(win, &name);
- fprintf(stdout, "app[%02d] 0x%08lx state: %d slot: %03d \"%s\"\n",
- ++n, win, state[i], i, name);
- free(name);
- }
- fprintf(stdout, "total apps: %d\n", n);
- ff();
-}
-
-static int process_control(char *file, int check_clients) {
- int i, nnew = 0, seen[CMAX];
- char line[1024], *newctl[CMAX];
- FILE *f;
-
- f = fopen(file, "r");
- if (!f) {
- return 1;
- }
- if (check_clients) {
- for (i=0; i < CMAX; i++) {
- seen[i] = 0;
- }
- }
- while (fgets(line, sizeof(line), f) != NULL) {
- char *q = strchr(line, '\n');
- if (q) *q = '\0';
-
- if (appshare_debug) {
- fprintf(stderr, "check_control: %s\n", line);
- ff();
- }
-
- q = lblanks(line);
- if (q[0] == '#') {
- continue;
- }
- if (!strcmp(q, "")) {
- continue;
- }
- if (strstr(q, "cmd=") == q) {
- char *cmd = q + strlen("cmd=");
- if (!strcmp(cmd, "quit")) {
- if (strcmp(control, file) && strstr(file, ".cmd")) {
- FILE *f2 = fopen(file, "w");
- if (f2) fclose(f2);
- }
- appshare_cleanup(0);
- } else if (!strcmp(cmd, "wait")) {
- return 0;
- } else if (strstr(cmd, "bcast:") == cmd) {
- ;
- } else if (strstr(cmd, "del_window:") == cmd) {
- add_or_del_win(cmd + strlen("del_window:"), 0);
- } else if (strstr(cmd, "add_window:") == cmd) {
- add_or_del_win(cmd + strlen("add_window:"), 1);
- } else if (strstr(cmd, "del:") == cmd) {
- add_or_del_win(cmd + strlen("del:"), 0);
- } else if (strstr(cmd, "add:") == cmd) {
- add_or_del_win(cmd + strlen("add:"), 1);
- } else if (strstr(cmd, "del_client:") == cmd) {
- add_or_del_client(cmd + strlen("del_client:"), 0);
- } else if (strstr(cmd, "add_client:") == cmd) {
- add_or_del_client(cmd + strlen("add_client:"), 1);
- } else if (strstr(cmd, "-") == cmd) {
- add_or_del_client(cmd + strlen("-"), 0);
- } else if (strstr(cmd, "+") == cmd) {
- add_or_del_client(cmd + strlen("+"), 1);
- } else if (strstr(cmd, "del_app:") == cmd) {
- add_or_del_app(cmd + strlen("del_app:"), 0);
- } else if (strstr(cmd, "add_app:") == cmd) {
- add_or_del_app(cmd + strlen("add_app:"), 1);
- } else if (strstr(cmd, "debug:") == cmd) {
- appshare_debug = atoi(cmd + strlen("debug:"));
- } else if (strstr(cmd, "showmenus:") == cmd) {
- skip_menus = atoi(cmd + strlen("showmenus:"));
- skip_menus = !(skip_menus);
- } else if (strstr(cmd, "noexit:") == cmd) {
- exit_no_app_win = atoi(cmd + strlen("noexit:"));
- exit_no_app_win = !(exit_no_app_win);
- } else if (strstr(cmd, "use_forever:") == cmd) {
- use_forever = atoi(cmd + strlen("use_forever:"));
- } else if (strstr(cmd, "tree_depth:") == cmd) {
- tree_depth = atoi(cmd + strlen("tree_depth:"));
- } else if (strstr(cmd, "x11vnc_args:") == cmd) {
- x11vnc_args = strdup(cmd + strlen("x11vnc_args:"));
- } else if (strstr(cmd, "env:") == cmd) {
- putenv(cmd + strlen("env:"));
- } else if (strstr(cmd, "noop") == cmd) {
- ;
- } else if (!strcmp(cmd, "restart")) {
- restart_x11vnc();
- } else if (!strcmp(cmd, "list_clients") || !strcmp(cmd, "lc")) {
- list_clients();
- } else if (!strcmp(cmd, "list_windows") || !strcmp(cmd, "lw")) {
- list_windows();
- } else if (!strcmp(cmd, "list_apps") || !strcmp(cmd, "la")) {
- list_apps();
- } else if (!strcmp(cmd, "list_all") || !strcmp(cmd, "ls")) {
- list_windows();
- fprintf(stderr, "\n");
- list_apps();
- fprintf(stderr, "\n");
- list_clients();
- } else if (!strcmp(cmd, "print_logs") || !strcmp(cmd, "pl")) {
- print_logs();
- } else if (!strcmp(cmd, "?") || !strcmp(cmd, "h") || !strcmp(cmd, "help")) {
- fprintf(stderr, "available commands:\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " quit restart noop x11vnc help ? ! !!\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " add_window:win (add:win, add:pick)\n");
- fprintf(stderr, " del_window:win (del:win, del:pick, del:all)\n");
- fprintf(stderr, " add_app:win (add_app:pick)\n");
- fprintf(stderr, " del_app:win (del_app:pick, del_app:all)\n");
- fprintf(stderr, " add_client:host (+host)\n");
- fprintf(stderr, " del_client:host (-host, -all)\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " list_windows (lw)\n");
- fprintf(stderr, " list_apps (la)\n");
- fprintf(stderr, " list_clients (lc)\n");
- fprintf(stderr, " list_all (ls)\n");
- fprintf(stderr, " print_logs (pl)\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " debug:n showmenus:n noexit:n\n");
- } else {
- fprintf(stderr, "unrecognized %s\n", q);
- }
- continue;
- }
- if (check_clients) {
- int idx = find_client(q);
- if (idx >= 0) {
- seen[idx] = 1;
- } else {
- newctl[nnew++] = strdup(q);
- }
- }
- }
- fclose(f);
-
- if (check_clients) {
- for (i=0; i < CMAX; i++) {
- if (clients[i] == NULL) {
- continue;
- }
- if (!seen[i]) {
- client(clients[i], 0);
- free(clients[i]);
- clients[i] = NULL;
- }
- }
- for (i=0; i < nnew; i++) {
- int free = find_client(NULL);
- if (free < 0) {
- static int cnt = 0;
- if (cnt++ < 10) {
- fprintf(stderr, "ran out of client slots.\n");
- ff();
- break;
- }
- continue;
- }
- clients[free] = newctl[i];
- client(newctl[i], 1);
- }
- }
- return 1;
-}
-
-static int check_control(void) {
- static int last_size = -1;
- static time_t last_mtime = 0;
- struct stat sb;
- char *control_cmd;
-
- if (!control) {
- return 1;
- }
-
- if (!strcmp(control, "internal")) {
- return 1;
- }
-
- control_cmd = (char *)malloc(strlen(control) + strlen(".cmd") + 1);
- sprintf(control_cmd, "%s.cmd", control);
- if (stat(control_cmd, &sb) == 0) {
- FILE *f;
- if (sb.st_size > 0) {
- process_control(control_cmd, 0);
- }
- f = fopen(control_cmd, "w");
- if (f) {
- fclose(f);
- }
- }
- free(control_cmd);
-
- if (stat(control, &sb) != 0) {
- return 1;
- }
- if (last_size == (int) sb.st_size && last_mtime == sb.st_mtime) {
- return 1;
- }
- last_size = (int) sb.st_size;
- last_mtime = sb.st_mtime;
-
- return process_control(control, 1);
-}
-
-static void update(void) {
- int i, app_ok = 0;
- if (last_event_type != PropertyNotify) {
- if (appshare_debug) fprintf(stderr, "\nupdate ...\n");
- } else if (appshare_debug > 1) {
- fprintf(stderr, "update ... propertynotify\n");
- }
- if (!check_control()) {
- return;
- }
- for (i=0; i < WMAX; i++) {
- Window win = watch[i];
- if (win == None) {
- continue;
- }
- if (!win_attr(win)) {
- destroy_win(win);
- continue;
- }
- if (find_app(win) >= 0) {
- app_ok++;
- }
- if (state[i] == 0) {
- if (attr.map_state == IsViewable) {
- if (skip_menus) {
- Window inside = check_inside(win);
- if (inside != None) {
- if (appshare_debug) {fprintf(stderr, "skip_menus: window 0x%lx is inside of 0x%lx, not tracking it.\n", win, inside); ff();}
- delete_win(win);
- continue;
- }
- }
- launch(win);
- state[i] = 1;
- }
- } else if (state[i] == 1) {
- if (attr.map_state != IsViewable) {
- stop(win);
- state[i] = 0;
- }
- }
- }
- if (exit_no_app_win && !app_ok) {
- for (i=0; i < AMAX; i++) {
- if (apps[i] != None) {
- fprintf(stdout, "main application window is gone: 0x%lx\n", apps[i]);
- }
- }
- ff();
- appshare_cleanup(0);
- }
- if (last_event_type != PropertyNotify) {
- if (appshare_debug) {fprintf(stderr, "update done.\n"); ff();}
- }
-}
-
-static void exiter(char *msg, int rc) {
- fprintf(stderr, "%s", msg);
- ff();
- kill_helper_pid();
- exit(rc);
-}
-
-static void set_trackdir(void) {
- char tmp[256];
- struct stat sb;
- if (!strcmp(trackdir, "none")) {
- trackdir = NULL;
- return;
- }
- if (!strcmp(trackdir, "unset")) {
- int fd;
- sprintf(tmp, "%s.XXXXXX", trackpre);
- fd = mkstemp(tmp);
- if (fd < 0) {
- strcat(tmp, ": failed to create file.\n");
- exiter(tmp, 1);
- }
- /* XXX race */
- close(fd);
- unlink(tmp);
- if (mkdir(tmp, 0700) != 0) {
- strcat(tmp, ": failed to create dir.\n");
- exiter(tmp, 1);
- }
- trackdir = strdup(tmp);
- }
- if (stat(trackdir, &sb) != 0) {
- if (mkdir(trackdir, 0700) != 0) {
- exiter("could not make trackdir.\n", 1);
- }
- } else if (! S_ISDIR(sb.st_mode)) {
- exiter("trackdir not a directory.\n", 1);
- }
- tracktmp = (char *) calloc(1000 + strlen(trackdir), 1);
-}
-
-static void process_string(char *str) {
- FILE *f;
- char *file;
- if (trackdir) {
- sprintf(tracktmp, "%s/0xprop.cmd", trackdir);
- file = strdup(tracktmp);
- } else {
- char tmp[] = "/tmp/x11vnc-appshare.cmd.XXXXXX";
- int fd = mkstemp(tmp);
- if (fd < 0) {
- return;
- }
- file = strdup(tmp);
- close(fd);
- }
- f = fopen(file, "w");
- if (f) {
- fprintf(f, "%s", str);
- fclose(f);
- process_control(file, 0);
- }
- unlink(file);
- free(file);
-}
-
-static void handle_shell(void) {
- struct timeval tv;
- static char lastline[1000];
- static int first = 1;
- fd_set rfds;
- int fd0 = fileno(stdin);
-
- if (first) {
- memset(lastline, 0, sizeof(lastline));
- first = 0;
- }
-
- FD_ZERO(&rfds);
- FD_SET(fd0, &rfds);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- select(fd0+1, &rfds, NULL, NULL, &tv);
- if (FD_ISSET(fd0, &rfds)) {
- char line[1000], line2[1010];
- if (fgets(line, sizeof(line), stdin) != NULL) {
- char *str = lblanks(line);
- char *q = strrchr(str, '\n');
- if (q) *q = '\0';
- if (strcmp(str, "")) {
- if (!strcmp(str, "!!")) {
- sprintf(line, "%s", lastline);
- fprintf(stderr, "%s\n", line);
- str = line;
- }
- if (strstr(str, "!") == str) {
- system(str+1);
- } else if (!strcmp(str, "x11vnc") || !strcmp(str, "ps")) {
- char *cmd = "ps -elf | egrep 'PID|x11vnc' | grep -v egrep";
- fprintf(stderr, "%s\n", cmd);
- system(cmd);
- } else {
- sprintf(line2, "cmd=%s", str);
- process_string(line2);
- }
- sprintf(lastline, "%s", str);
- }
- }
- fprintf(stderr, "\n%s", prompt); ff();
- }
-}
-
-static void handle_prop_cmd(void) {
- char *value, *str, *done = "DONE";
-
- if (cmd_atom == None) {
- return;
- }
-
- value = get_xprop(cmd_atom_str, root);
- if (value == NULL) {
- return;
- }
-
- str = lblanks(value);
- if (!strcmp(str, done)) {
- free(value);
- return;
- }
- if (strstr(str, "cmd=quit") == str || strstr(str, "\ncmd=quit")) {
- set_xprop(cmd_atom_str, root, done);
- appshare_cleanup(0);
- }
-
- process_string(str);
-
- free(value);
- set_xprop(cmd_atom_str, root, done);
-}
-
-#define PREFIX if(appshare_debug) fprintf(stderr, " %8.2f 0x%08lx : ", dnow() - start, ev.xany.window);
-
-static void monitor(void) {
-#if !NO_X11
- XEvent ev;
- double start = dnow();
- int got_prop_cmd = 0;
-
- if (shell) {
- update();
- fprintf(stderr, "\n\n");
- process_string("cmd=help");
- fprintf(stderr, "\n%s", prompt); ff();
- }
-
- while (1) {
- int t;
-
- if (XEventsQueued(dpy, QueuedAlready) == 0) {
- update();
- if (got_prop_cmd) {
- handle_prop_cmd();
- }
- got_prop_cmd = 0;
- if (shell) {
- handle_shell();
- }
- }
-
- XNextEvent(dpy, &ev);
-
- last_event_type = ev.type;
-
- switch (ev.type) {
- case Expose:
- PREFIX
- if(appshare_debug) fprintf(stderr, "Expose %04dx%04d+%04d+%04d\n", ev.xexpose.width, ev.xexpose.height, ev.xexpose.x, ev.xexpose.y);
- break;
- case ConfigureNotify:
-#if 0
- PREFIX
- if(appshare_debug) fprintf(stderr, "ConfigureNotify %04dx%04d+%04d+%04d above: 0x%lx\n", ev.xconfigure.width, ev.xconfigure.height, ev.xconfigure.x, ev.xconfigure.y, ev.xconfigure.above);
-#endif
- break;
- case VisibilityNotify:
- PREFIX
- if (appshare_debug) {
- fprintf(stderr, "VisibilityNotify: ");
- t = ev.xvisibility.state;
- if (t == VisibilityFullyObscured) fprintf(stderr, "VisibilityFullyObscured\n");
- if (t == VisibilityPartiallyObscured) fprintf(stderr, "VisibilityPartiallyObscured\n");
- if (t == VisibilityUnobscured) fprintf(stderr, "VisibilityUnobscured\n");
- }
- break;
- case MapNotify:
- PREFIX
- if(appshare_debug) fprintf(stderr, "MapNotify win: 0x%lx\n", ev.xmap.window);
- if (ours(ev.xmap.window)) {
- mapped(ev.xmap.window);
- }
- break;
- case UnmapNotify:
- PREFIX
- if(appshare_debug) fprintf(stderr, "UnmapNotify win: 0x%lx\n", ev.xmap.window);
- if (ours(ev.xmap.window)) {
- unmapped(ev.xmap.window);
- }
- break;
- case MapRequest:
- PREFIX
- if(appshare_debug) fprintf(stderr, "MapRequest\n");
- break;
- case CreateNotify:
- PREFIX
- if(appshare_debug) fprintf(stderr, "CreateNotify parent: 0x%lx win: 0x%lx\n", ev.xcreatewindow.parent, ev.xcreatewindow.window);
- if (ev.xcreatewindow.parent == root && ours(ev.xcreatewindow.window)) {
- if (find_win(ev.xcreatewindow.window) >= 0) {
- destroy_win(ev.xcreatewindow.window);
- }
- add_win(ev.xcreatewindow.window);
- }
- break;
- case DestroyNotify:
- PREFIX
- if(appshare_debug) fprintf(stderr, "DestroyNotify win: 0x%lx\n", ev.xdestroywindow.window);
- if (ours(ev.xdestroywindow.window)) {
- destroy_win(ev.xdestroywindow.window);
- }
- break;
- case ConfigureRequest:
- PREFIX
- if(appshare_debug) fprintf(stderr, "ConfigureRequest\n");
- break;
- case CirculateRequest:
-#if 0
- PREFIX
- if(appshare_debug) fprintf(stderr, "CirculateRequest parent: 0x%lx win: 0x%lx\n", ev.xcirculaterequest.parent, ev.xcirculaterequest.window);
-#endif
- break;
- case CirculateNotify:
-#if 0
- PREFIX
- if(appshare_debug) fprintf(stderr, "CirculateNotify\n");
-#endif
- break;
- case PropertyNotify:
-#if 0
- PREFIX
- if(appshare_debug) fprintf(stderr, "PropertyNotify\n");
-#endif
- if (cmd_atom != None && ev.xproperty.atom == cmd_atom) {
- got_prop_cmd++;
- }
- break;
- case ReparentNotify:
- PREFIX
- if(appshare_debug) fprintf(stderr, "ReparentNotify parent: 0x%lx win: 0x%lx\n", ev.xreparent.parent, ev.xreparent.window);
- if (ours(ev.xreparent.window)) {
- if (ours(ev.xreparent.parent)) {
- destroy_win(ev.xreparent.window);
- } else if (ev.xreparent.parent == root) {
- /* ??? */
- }
- }
- break;
- default:
- PREFIX
- if(appshare_debug) fprintf(stderr, "Unknown: %d\n", ev.type);
- break;
- }
- }
-#endif
-}
-
-int appshare_main(int argc, char *argv[]) {
- int i;
- char *app_str = NULL;
- char *dpy_str = NULL;
- long xselectinput = 0;
-#if NO_X11
- exiter("not compiled with X11\n", 1);
-#else
- for (i=0; i < WMAX; i++) {
- watch[i] = None;
- state[i] = 0;
- }
- for (i=0; i < AMAX; i++) {
- apps[i] = None;
- }
- for (i=0; i < CMAX; i++) {
- clients[i] = NULL;
- }
-
- x11vnc = strdup(argv[0]);
-
- for (i=1; i < argc; i++) {
- int end = (i == argc-1) ? 1 : 0;
- char *s = argv[i];
- if (strstr(s, "--") == s) {
- s++;
- }
-
- if (!strcmp(s, "-h") || !strcmp(s, "-help")) {
- fprintf(stdout, "%s", usage);
- exit(0);
- } else if (!strcmp(s, "-id")) {
- id_opt = "-id";
- if (end) exiter("no -id value supplied\n", 1);
- app_str = strdup(argv[++i]);
- } else if (!strcmp(s, "-sid")) {
- id_opt = "-sid";
- if (end) exiter("no -sid value supplied\n", 1);
- app_str = strdup(argv[++i]);
- } else if (!strcmp(s, "-connect") || !strcmp(s, "-connect_or_exit") || !strcmp(s, "-coe")) {
- if (end) exiter("no -connect value supplied\n", 1);
- connect_to = strdup(argv[++i]);
- } else if (!strcmp(s, "-control")) {
- if (end) exiter("no -control value supplied\n", 1);
- control = strdup(argv[++i]);
- if (!strcmp(control, "shell")) {
- free(control);
- control = strdup("internal");
- shell = 1;
- }
- } else if (!strcmp(s, "-trackdir")) {
- if (end) exiter("no -trackdir value supplied\n", 1);
- trackdir = strdup(argv[++i]);
- } else if (!strcmp(s, "-display")) {
- if (end) exiter("no -display value supplied\n", 1);
- dpy_str = strdup(argv[++i]);
- set_env("DISPLAY", dpy_str);
- } else if (!strcmp(s, "-delay")) {
- if (end) exiter("no -delay value supplied\n", 1);
- helper_delay = atof(argv[++i]);
- } else if (!strcmp(s, "-args")) {
- if (end) exiter("no -args value supplied\n", 1);
- x11vnc_args = strdup(argv[++i]);
- } else if (!strcmp(s, "-env")) {
- if (end) exiter("no -env value supplied\n", 1);
- putenv(argv[++i]);
- } else if (!strcmp(s, "-debug")) {
- appshare_debug++;
- } else if (!strcmp(s, "-showmenus")) {
- skip_menus = 0;
- } else if (!strcmp(s, "-noexit")) {
- exit_no_app_win = 0;
- } else if (!strcmp(s, "-shell")) {
- shell = 1;
- } else if (!strcmp(s, "-nocmds") || !strcmp(s, "-safer")) {
- fprintf(stderr, "ignoring %s in -appshare mode.\n", s);
- } else if (!strcmp(s, "-appshare")) {
- ;
- } else {
- fprintf(stderr, "unrecognized 'x11vnc -appshare' option: %s\n", s);
- exiter("", 1);
- }
- }
-
- if (getenv("X11VNC_APPSHARE_DEBUG")) {
- appshare_debug = atoi(getenv("X11VNC_APPSHARE_DEBUG"));
- }
-
- /* let user override name for multiple instances: */
- if (getenv("X11VNC_APPSHARE_COMMAND_PROPNAME")) {
- cmd_atom_str = strdup(getenv("X11VNC_APPSHARE_COMMAND_PROPNAME"));
- }
- if (getenv("X11VNC_APPSHARE_TICKER_PROPNAME")) {
- ticker_atom_str = strdup(getenv("X11VNC_APPSHARE_TICKER_PROPNAME"));
- }
-
- if (shell) {
- if (!control || strcmp(control, "internal")) {
- exiter("mode -shell requires '-control internal'\n", 1);
- }
- }
-
- if (connect_to == NULL && control != NULL) {
- struct stat sb;
- if (stat(control, &sb) == 0) {
- int len = 100 + sb.st_size;
- FILE *f = fopen(control, "r");
-
- if (f) {
- char *line = (char *) malloc(len);
- connect_to = (char *) calloc(2 * len, 1);
- while (fgets(line, len, f) != NULL) {
- char *q = strchr(line, '\n');
- if (q) *q = '\0';
- q = lblanks(line);
- if (q[0] == '#') {
- continue;
- }
- if (connect_to[0] != '\0') {
- strcat(connect_to, ",");
- }
- strcat(connect_to, q);
- }
- fclose(f);
- }
- fprintf(stderr, "set -connect to: %s\n", connect_to);
- }
- }
- if (0 && connect_to == NULL && control == NULL) {
- exiter("no -connect host or -control file specified.\n", 1);
- }
-
- if (control) {
- pid_t pid;
- parent_pid = getpid();
- pid = fork();
- if (pid == (pid_t) -1) {
- ;
- } else if (pid == 0) {
- be_helper_pid(dpy_str);
- exit(0);
- } else {
- helper_pid = pid;
- }
- }
-
- dpy = XOpenDisplay(dpy_str);
- if (!dpy) {
- exiter("cannot open display\n", 1);
- }
-
- root = DefaultRootWindow(dpy);
-
- xselectinput = SubstructureNotifyMask;
- if (helper_pid > 0) {
- ticker_atom = XInternAtom(dpy, ticker_atom_str, False);
- xselectinput |= PropertyChangeMask;
- }
- XSelectInput(dpy, root, xselectinput);
-
- cmd_atom = XInternAtom(dpy, cmd_atom_str, False);
-
- init_cmask();
-
- sprintf(unique_tag, "X11VNC_APPSHARE_TAG=%d-tag", getpid());
-
- start_time = dnow();
-
- if (app_str == NULL) {
- exiter("no -id/-sid window specified.\n", 1);
- } else {
- char *p, *str = strdup(app_str);
- char *alist[AMAX];
- int i, n = 0;
-
- p = strtok(str, ",");
- while (p) {
- if (n >= AMAX) {
- fprintf(stderr, "ran out of app slots: %s\n", app_str);
- exiter("", 1);
- }
- alist[n++] = strdup(p);
- p = strtok(NULL, ",");
- }
- free(str);
-
- for (i=0; i < n; i++) {
- Window app = None;
- p = alist[i];
- app = parse_win(p);
- free(p);
-
- if (app != None) {
- if (!ours(app)) {
- add_app(app);
- }
- }
- }
- }
-
- set_trackdir();
-
- signal(SIGINT, appshare_cleanup);
- signal(SIGTERM, appshare_cleanup);
-
- rfbLogEnable(0);
-
- if (connect_to) {
- char *p, *str = strdup(connect_to);
- int n = 0;
- p = strtok(str, ",");
- while (p) {
- clients[n++] = strdup(p);
- p = strtok(NULL, ",");
- }
- free(str);
- } else {
- connect_to = strdup("");
- }
-
- for (i=0; i < AMAX; i++) {
- if (apps[i] == None) {
- continue;
- }
- fprintf(stdout, "Using app win: 0x%08lx root: 0x%08lx\n", apps[i], root);
- }
- fprintf(stdout, "\n");
-
- monitor();
-
- appshare_cleanup(0);
-
-#endif
- return 0;
-}
-
diff --git a/x11vnc/avahi.c b/x11vnc/avahi.c
deleted file mode 100644
index 939a34f..0000000
--- a/x11vnc/avahi.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- avahi.c -- */
-
-#include "x11vnc.h"
-#include "connections.h"
-#include "cleanup.h"
-
-void avahi_initialise(void);
-void avahi_advertise(char *name, char *host, uint16_t port);
-void avahi_reset(void);
-void avahi_cleanup(void);
-
-static pid_t avahi_pid = 0;
-
-static void kill_avahi_pid(void) {
- if (avahi_pid != 0) {
- rfbLog("kill_avahi_pid: %d\n", (int) avahi_pid);
- kill(avahi_pid, SIGTERM);
- avahi_pid = 0;
- }
-}
-
-static int try_avahi_helper(char *name, char *host, uint16_t port) {
-#if LIBVNCSERVER_HAVE_FORK
- char *cmd, *p, *path = getenv("PATH"), portstr[32];
- int i;
-
- if (!name || !host || !port) {}
-
- /* avahi-publish */
- if (no_external_cmds || !cmd_ok("zeroconf")) {
- return 0;
- }
-
- if (!path) {
- return 0;
- }
-
- path = strdup(path);
- cmd = (char *) malloc(strlen(path) + 100);
- sprintf(portstr, "%d", (int) port);
-
- p = strtok(path, ":");
- while (p) {
- struct stat sbuf;
-
- sprintf(cmd, "%s/avahi-publish", p);
- if (stat(cmd, &sbuf) == 0) {
- break;
- }
- sprintf(cmd, "%s/dns-sd", p);
- if (stat(cmd, &sbuf) == 0) {
- break;
- }
- sprintf(cmd, "%s/mDNS", p);
- if (stat(cmd, &sbuf) == 0) {
- break;
- }
- cmd[0] = '\0';
-
- p = strtok(NULL, ":");
- }
- free(path);
-
- if (!strcmp(cmd, "")) {
- free(cmd);
- rfbLog("Could not find an external avahi/zeroconf helper program.\n");
- return 0;
- }
-
- avahi_pid = fork();
-
- if (avahi_pid < 0) {
- rfbLogPerror("fork");
- avahi_pid = 0;
- free(cmd);
- return 0;
- }
-
- if (avahi_pid != 0) {
- int status;
-
- usleep(500 * 1000);
- waitpid(avahi_pid, &status, WNOHANG);
- if (kill(avahi_pid, 0) != 0) {
- waitpid(avahi_pid, &status, WNOHANG);
- avahi_pid = 0;
- free(cmd);
- return 0;
- }
- if (! quiet) {
- rfbLog("%s helper pid is: %d\n", cmd, (int) avahi_pid);
- }
- free(cmd);
- return 1;
- }
-
- for (i=3; i<256; i++) {
- close(i);
- }
-
- if (strstr(cmd, "/avahi-publish")) {
- execlp(cmd, cmd, "-s", name, "_rfb._tcp", portstr, (char *) NULL);
- } else {
- execlp(cmd, cmd, "-R", name, "_rfb._tcp", ".", portstr, (char *) NULL);
- }
- exit(1);
-#else
- if (!name || !host || !port) {}
- return 0;
-#endif
-}
-
-#if !defined(LIBVNCSERVER_HAVE_AVAHI) || !defined(LIBVNCSERVER_HAVE_LIBPTHREAD)
-void avahi_initialise(void) {
- rfbLog("avahi_initialise: no Avahi support at buildtime.\n");
-}
-
-void avahi_advertise(char *name, char *host, uint16_t port) {
- char *t;
- t = getenv("X11VNC_AVAHI_NAME"); if (t) name = t;
- t = getenv("X11VNC_AVAHI_HOST"); if (t) host = t;
- t = getenv("X11VNC_AVAHI_PORT"); if (t) port = atoi(t);
-
- if (!try_avahi_helper(name, host, port)) {
- rfbLog("avahi_advertise: no Avahi support at buildtime.\n");
- avahi = 0;
- }
-}
-
-void avahi_reset(void) {
- kill_avahi_pid();
- rfbLog("avahi_reset: no Avahi support at buildtime.\n");
-}
-
-void avahi_cleanup(void) {
- kill_avahi_pid();
- rfbLog("avahi_cleanup: no Avahi support at buildtime.\n");
-}
-#else
-
-#include <avahi-common/thread-watch.h>
-#include <avahi-common/alternative.h>
-#include <avahi-client/client.h>
-#include <avahi-client/publish.h>
-
-#include <avahi-common/malloc.h>
-#include <avahi-common/error.h>
-
-
-static AvahiThreadedPoll *_poll = NULL;
-static AvahiClient *_client = NULL;
-static AvahiEntryGroup *_group = NULL;
-
-static int db = 0;
-
-typedef struct {
- const char *name;
- const char *host;
- uint16_t port;
-} avahi_service_t;
-
-typedef struct {
- char *name;
- char *host;
- uint16_t port;
-} avahi_reg_t;
-
-#define NREG 16
-static avahi_reg_t registered[NREG];
-
-void avahi_initialise(void) {
- int ret;
- static int first = 1;
-
- if (getenv("AVAHI_DEBUG")) {
- db = 1;
- }
- if (first) {
- int i;
- for (i=0; i<NREG; i++) {
- registered[i].name = NULL;
- registered[i].host = NULL;
- }
- first = 0;
- }
-
-if (db) fprintf(stderr, "in avahi_initialise\n");
- if (_poll) {
-if (db) fprintf(stderr, " avahi_initialise: poll not null\n");
- return;
- }
-
- if (! (_poll = avahi_threaded_poll_new()) ) {
- rfbLog("warning: unable to open Avahi poll.\n");
- return;
- }
-
- _client = avahi_client_new(avahi_threaded_poll_get(_poll),
- 0, NULL, NULL, &ret);
- if (! _client) {
- rfbLog("warning: unable to open Avahi client: %s\n",
- avahi_strerror(ret));
-
- avahi_threaded_poll_free(_poll);
- _poll = NULL;
- return;
- }
-
- if (avahi_threaded_poll_start(_poll) < 0) {
- rfbLog("warning: unable to start Avahi poll.\n");
- avahi_client_free(_client);
- _client = NULL;
- avahi_threaded_poll_free(_poll);
- _poll = NULL;
- return;
- }
-if (db) fprintf(stderr, "out avahi_initialise\n");
-}
-
-static void _avahi_create_services(char *name, char *host,
- uint16_t port);
-
-static void _avahi_entry_group_callback(AvahiEntryGroup *g,
- AvahiEntryGroupState state, void *userdata) {
- char *new_name;
- avahi_service_t *svc = (avahi_service_t *)userdata;
-
-if (db) fprintf(stderr, "in _avahi_entry_group_callback %d 0x%p\n", state, svc);
- if (g != _group && _group != NULL) {
- rfbLog("avahi_entry_group_callback fatal error (group).\n");
- clean_up_exit(1);
- }
- if (userdata == NULL) {
- rfbLog("avahi_entry_group_callback fatal error (userdata).\n");
- clean_up_exit(1);
- }
-
- switch(state) {
- case AVAHI_ENTRY_GROUP_ESTABLISHED:
- rfbLog("Avahi group %s established.\n", svc->name);
-#if 0 /* is this the segv problem? */
- free(svc);
-#endif
- break;
- case AVAHI_ENTRY_GROUP_COLLISION:
- new_name = avahi_alternative_service_name(svc->name);
- _avahi_create_services(new_name, svc->host, svc->port);
- rfbLog("Avahi Entry group collision\n");
- avahi_free(new_name);
- break;
- case AVAHI_ENTRY_GROUP_FAILURE:
- rfbLog("Avahi Entry group failure: %s\n",
- avahi_strerror(avahi_client_errno(
- avahi_entry_group_get_client(g))));
- break;
- default:
- break;
- }
-if (db) fprintf(stderr, "out _avahi_entry_group_callback\n");
-}
-
-static void _avahi_create_services(char *name, char *host, uint16_t port) {
- avahi_service_t *svc = (avahi_service_t *)malloc(sizeof(avahi_service_t));
- int ret = 0;
-
-if (db) fprintf(stderr, "in _avahi_create_services '%s' '%s' %d\n", name, host, port);
- svc->name = name;
- svc->host = host;
- svc->port = port;
-
- if (!_group) {
-if (db) fprintf(stderr, " _avahi_create_services create group\n");
- _group = avahi_entry_group_new(_client,
- _avahi_entry_group_callback, svc);
- }
- if (!_group) {
- rfbLog("avahi_entry_group_new() failed: %s\n",
- avahi_strerror(avahi_client_errno(_client)));
- return;
- }
-
- ret = avahi_entry_group_add_service(_group, AVAHI_IF_UNSPEC,
- AVAHI_PROTO_UNSPEC, 0, name, "_rfb._tcp", NULL, NULL, port, NULL);
- if (ret < 0) {
- rfbLog("Failed to add _rfb._tcp service: %s\n",
- avahi_strerror(ret));
- return;
- }
-
- ret = avahi_entry_group_commit(_group);
- if (ret < 0) {
- rfbLog("Failed to commit entry_group:: %s\n",
- avahi_strerror(ret));
- return;
- }
-if (db) fprintf(stderr, "out _avahi_create_services\n");
-}
-
-void avahi_advertise(char *name, char *host, uint16_t port) {
- int i;
- char *t;
- t = getenv("X11VNC_AVAHI_NAME"); if (t) name = t;
- t = getenv("X11VNC_AVAHI_HOST"); if (t) host = t;
- t = getenv("X11VNC_AVAHI_PORT"); if (t) port = atoi(t);
-
-if (db) fprintf(stderr, "in avahi_advertise: '%s' '%s' %d\n", name, host, port);
- if (!_client) {
-if (db) fprintf(stderr, " avahi_advertise client null\n");
- return;
- }
- if (_poll == NULL) {
- rfbLog("Avahi poll not initialized.\n");
- return;
- }
- /* well, we just track it ourselves... */
- for (i=0; i<NREG; i++) {
- if (!registered[i].name) {
- continue;
- }
- if (strcmp(registered[i].name, name)) {
- continue;
- }
- if (strcmp(registered[i].host, host)) {
- continue;
- }
- if (registered[i].port != port) {
- continue;
- }
-if (db) fprintf(stderr, " avahi_advertise already did this one\n");
- return;
- }
- for (i=0; i<NREG; i++) {
- if (!registered[i].name) {
- registered[i].name = strdup(name);
- registered[i].host = strdup(host);
- registered[i].port = port;
- break;
- }
- }
-
- avahi_threaded_poll_lock(_poll);
- _avahi_create_services(name, host, port >= 5900 ? port : 5900+port);
- avahi_threaded_poll_unlock(_poll);
-if (db) fprintf(stderr, "out avahi_advertise\n");
-}
-
-void avahi_reset(void) {
- int i;
-if (db) fprintf(stderr, "in avahi_reset\n");
- for (i=0; i<NREG; i++) {
- if (registered[i].name) {
- free(registered[i].name);
- registered[i].name = NULL;
- }
- if (registered[i].host) {
- free(registered[i].host);
- registered[i].host = NULL;
- }
- }
- if (!_client || !_group) {
-if (db) fprintf(stderr, " avahi_reset client/group null\n");
- return;
- }
- avahi_entry_group_reset(_group);
- rfbLog("Avahi resetting group.\n");
-if (db) fprintf(stderr, "out avahi_reset\n");
-}
-
-static void avahi_timeout (int sig) {
- rfbLog("sig: %d, avahi_cleanup timed out.\n", sig);
- exit(1);
-}
-
-
-void avahi_cleanup(void) {
-if (db) fprintf(stderr, "in avahi_cleanup\n");
- if (!_client) {
-if (db) fprintf(stderr, " avahi_cleanup client null\n");
- return;
- }
-if (db) fprintf(stderr, " avahi_cleanup poll_lock\n");
- avahi_threaded_poll_lock(_poll);
-if (db) fprintf(stderr, " avahi_cleanup poll_stop\n");
-
- signal(SIGALRM, avahi_timeout);
- alarm(3);
- avahi_threaded_poll_stop(_poll);
- alarm(0);
- signal(SIGALRM, SIG_DFL);
-
-if (db) fprintf(stderr, " avahi_cleanup client_free\n");
- avahi_client_free(_client);
- _client = NULL;
-
-if (db) fprintf(stderr, " avahi_cleanup poll_free\n");
- avahi_threaded_poll_free(_poll);
- _poll = NULL;
-if (db) fprintf(stderr, "out avahi_cleanup\n");
-}
-
-#endif
-
diff --git a/x11vnc/avahi.h b/x11vnc/avahi.h
deleted file mode 100644
index 7b7a6bc..0000000
--- a/x11vnc/avahi.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_AVAHI_H
-#define _X11VNC_AVAHI_H
-
-/* -- avahi.h -- */
-
-extern void avahi_initialise(void);
-extern void avahi_advertise(char *name, char *host, uint16_t port);
-extern void avahi_reset(void);
-extern void avahi_cleanup(void);
-
-#endif /* _X11VNC_AVAHI_H */
diff --git a/x11vnc/blackout_t.h b/x11vnc/blackout_t.h
deleted file mode 100644
index 014f5b4..0000000
--- a/x11vnc/blackout_t.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_BLACKOUT_T_H
-#define _X11VNC_BLACKOUT_T_H
-
-/* -- blackout_t.h -- */
-
-typedef struct bout {
- int x1, y1, x2, y2;
-} blackout_t;
-
-#define BO_MAX 32
-typedef struct tbout {
- blackout_t bo[BO_MAX]; /* hardwired max rectangles. */
- int cover;
- int count;
-} tile_blackout_t;
-
-#endif /* _X11VNC_BLACKOUT_T_H */
diff --git a/x11vnc/cleanup.c b/x11vnc/cleanup.c
deleted file mode 100644
index 60db819..0000000
--- a/x11vnc/cleanup.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- cleanup.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "xdamage.h"
-#include "remote.h"
-#include "keyboard.h"
-#include "scan.h"
-#include "gui.h"
-#include "solid.h"
-#include "unixpw.h"
-#include "sslcmds.h"
-#include "sslhelper.h"
-#include "connections.h"
-#include "macosx.h"
-#include "macosxCG.h"
-#include "avahi.h"
-#include "screen.h"
-#include "xrecord.h"
-#include "xevents.h"
-#include "uinput.h"
-
-/*
- * Exiting and error handling routines
- */
-
-int trapped_xerror = 0;
-int trapped_xioerror = 0;
-int trapped_getimage_xerror = 0;
-int trapped_record_xerror = 0;
-XErrorEvent *trapped_xerror_event;
-
-/* XXX CHECK BEFORE RELEASE */
-int crash_debug = 0;
-
-void clean_shm(int quick);
-void clean_up_exit(int ret);
-int trap_xerror(Display *d, XErrorEvent *error);
-int trap_xioerror(Display *d);
-int trap_getimage_xerror(Display *d, XErrorEvent *error);
-char *xerror_string(XErrorEvent *error);
-void initialize_crash_handler(void);
-void initialize_signals(void);
-void unset_signals(void);
-void close_exec_fds(void);
-int known_sigpipe_mode(char *s);
-
-
-static int exit_flag = 0;
-static int exit_sig = 0;
-
-static void clean_icon_mode(void);
-static int Xerror(Display *d, XErrorEvent *error);
-static int XIOerr(Display *d);
-static void crash_shell_help(void);
-static void crash_shell(void);
-static void interrupted (int sig);
-
-
-void clean_shm(int quick) {
- int i, cnt = 0;
-
- /*
- * to avoid deadlock, etc, under quick=1 we just delete the shm
- * areas and leave the X stuff hanging.
- */
- if (quick) {
- shm_delete(&scanline_shm);
- shm_delete(&fullscreen_shm);
- shm_delete(&snaprect_shm);
- } else {
- shm_clean(&scanline_shm, scanline);
- shm_clean(&fullscreen_shm, fullscreen);
- shm_clean(&snaprect_shm, snaprect);
- }
-
- /*
- * Here we have to clean up quite a few shm areas for all
- * the possible tile row runs (40 for 1280), not as robust
- * as one might like... sometimes need to run ipcrm(1).
- */
- for(i=1; i<=ntiles_x; i++) {
- if (i > tile_shm_count) {
- break;
- }
- if (quick) {
- shm_delete(&tile_row_shm[i]);
- } else {
- shm_clean(&tile_row_shm[i], tile_row[i]);
- }
- cnt++;
- if (single_copytile_count && i >= single_copytile_count) {
- break;
- }
- }
- if (!quiet && cnt > 0) {
- rfbLog("deleted %d tile_row polling images.\n", cnt);
- }
-}
-
-static void clean_icon_mode(void) {
- if (icon_mode && icon_mode_fh) {
- fprintf(icon_mode_fh, "quit\n");
- fflush(icon_mode_fh);
- fclose(icon_mode_fh);
- icon_mode_fh = NULL;
- if (icon_mode_file) {
- unlink(icon_mode_file);
- icon_mode_file = NULL;
- }
- }
-}
-
-/*
- * Normal exiting
- */
-void clean_up_exit(int ret) {
- static int depth = 0;
- exit_flag = 1;
-
- if (depth++ > 2) {
- exit(ret);
- }
-
- if (icon_mode) {
- clean_icon_mode();
- }
-
- /* remove the shm areas: */
- clean_shm(0);
-
- stop_stunnel();
- if (use_openssl) {
- ssl_helper_pid(0, 0); /* killall */
- }
-
- if (ssh_pid > 0) {
- kill(ssh_pid, SIGTERM);
- ssh_pid = 0;
- }
-
-#ifdef MACOSX
- if (client_connect_file) {
- if (strstr(client_connect_file, "/tmp/x11vnc-macosx-remote")
- == client_connect_file) {
- unlink(client_connect_file);
- }
- }
- if (macosx_console) {
- macosxCG_fini();
- }
-#endif
-
- if (pipeinput_fh != NULL) {
- pclose(pipeinput_fh);
- pipeinput_fh = NULL;
- }
-
- shutdown_uinput();
-
- if (unix_sock) {
- if (unix_sock_fd >= 0) {
- rfbLog("deleting unix sock: %s\n", unix_sock);
- close(unix_sock_fd);
- unix_sock_fd = -1;
- unlink(unix_sock);
- }
- }
-
- if (! dpy) { /* raw_rb hack */
- if (rm_flagfile) {
- unlink(rm_flagfile);
- rm_flagfile = NULL;
- }
- exit(ret);
- }
-
- /* X keyboard cleanups */
- delete_added_keycodes(0);
-
- if (clear_mods == 1) {
- clear_modifiers(0);
- } else if (clear_mods == 2) {
- clear_keys();
- } else if (clear_mods == 3) {
- clear_keys();
- clear_locks();
- }
-
- if (no_autorepeat) {
- autorepeat(1, 0);
- }
- if (use_solid_bg) {
- solid_bg(1);
- }
- if (ncache || ncache0) {
- kde_no_animate(1);
- }
- X_LOCK;
- XTestDiscard_wr(dpy);
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- if (xdamage) {
- XDamageDestroy(dpy, xdamage);
- }
-#endif
-#if LIBVNCSERVER_HAVE_LIBXTRAP
- if (trap_ctx) {
- XEFreeTC(trap_ctx);
- }
-#endif
- /* XXX rdpy_ctrl, etc. cannot close w/o blocking */
- XCloseDisplay_wr(dpy);
- X_UNLOCK;
-
- fflush(stderr);
-
- if (rm_flagfile) {
- unlink(rm_flagfile);
- rm_flagfile = NULL;
- }
-
- if (avahi) {
- avahi_cleanup();
- fflush(stderr);
- }
-
- exit(ret);
-}
-
-/* X11 error handlers */
-
-static XErrorHandler Xerror_def;
-static XIOErrorHandler XIOerr_def;
-
-int trap_xerror(Display *d, XErrorEvent *error) {
- trapped_xerror = 1;
- trapped_xerror_event = error;
-
- if (d) {} /* unused vars warning: */
-
- return 0;
-}
-
-int trap_xioerror(Display *d) {
- trapped_xioerror = 1;
-
- if (d) {} /* unused vars warning: */
-
- return 0;
-}
-
-int trap_getimage_xerror(Display *d, XErrorEvent *error) {
- trapped_getimage_xerror = 1;
- trapped_xerror_event = error;
-
- if (d) {} /* unused vars warning: */
-
- return 0;
-}
-
-/* Are silly Xorg people removing X_ShmAttach from XShm.h? */
-/* INDEED! What stupid, myopic morons... */
-/* Maintenance Monkeys busy typing at their keyboards... */
-#ifndef X_ShmAttach
-#define X_ShmAttach 1
-#endif
-
-static int Xerror(Display *d, XErrorEvent *error) {
- X_UNLOCK;
-
- if (getenv("X11VNC_PRINT_XERROR")) {
- fprintf(stderr, "Xerror: major_opcode: %d minor_opcode: %d error_code: %d\n",
- error->request_code, error->minor_code, error->error_code);
- }
-
- if (xshm_opcode > 0 && error->request_code == xshm_opcode) {
- if (error->minor_code == X_ShmAttach) {
- char *dstr = DisplayString(dpy);
- fprintf(stderr, "\nX11 MIT Shared Memory Attach failed:\n");
- fprintf(stderr, " Is your DISPLAY=%s on a remote machine?\n", dstr);
- if (strstr(dstr, "localhost:")) {
- fprintf(stderr, " Note: DISPLAY=localhost:N suggests a SSH X11 redir to a remote machine.\n");
- } else if (dstr[0] != ':') {
- fprintf(stderr, " Note: DISPLAY=hostname:N suggests a remote display.\n");
- }
- fprintf(stderr, " Suggestion, use: x11vnc -display :0 ... for local display :0\n\n");
- }
- }
-
- interrupted(0);
-
- if (d) {} /* unused vars warning: */
-
- return (*Xerror_def)(d, error);
-}
-
-void watch_loop(void);
-
-static int XIOerr(Display *d) {
- static int reopen = 0, rmax = 1;
- X_UNLOCK;
-
- if (getenv("X11VNC_REOPEN_DISPLAY")) {
- rmax = atoi(getenv("X11VNC_REOPEN_DISPLAY"));
- }
-
-#if !NO_X11
- if (reopen < rmax && getenv("X11VNC_REOPEN_DISPLAY")) {
- int db = getenv("X11VNC_REOPEN_DEBUG") ? 1 : 0;
- int sleepmax = 10, i;
- Display *save_dpy = dpy;
- char *dstr = strdup(DisplayString(save_dpy));
- reopen++;
- if (getenv("X11VNC_REOPEN_SLEEP_MAX")) {
- sleepmax = atoi(getenv("X11VNC_REOPEN_SLEEP_MAX"));
- }
- rfbLog("*** XIO error: Trying to reopen[%d/%d] display '%s'\n", reopen, rmax, dstr);
- rfbLog("*** XIO error: Note the reopened state may be unstable.\n");
- for (i=0; i < sleepmax; i++) {
- usleep (1000 * 1000);
- dpy = XOpenDisplay_wr(dstr);
- rfbLog("dpy[%d/%d]: %p\n", i+1, sleepmax, dpy);
- if (dpy) {
- break;
- }
- }
- last_open_xdisplay = time(NULL);
- if (dpy) {
- rfbLog("*** XIO error: Reopened display '%s' successfully.\n", dstr);
- if (db) rfbLog("*** XIO error: '%s' 0x%x\n", dstr, dpy);
- scr = DefaultScreen(dpy);
- rootwin = RootWindow(dpy, scr);
- if (db) rfbLog("*** XIO error: disable_grabserver\n");
- disable_grabserver(dpy, 0);
- if (db) rfbLog("*** XIO error: xrecord\n");
- zerodisp_xrecord();
- initialize_xrecord();
- if (db) rfbLog("*** XIO error: xdamage\n");
- create_xdamage_if_needed(1);
- if (db) rfbLog("*** XIO error: do_new_fb\n");
- if (using_shm) {
- if (db) rfbLog("*** XIO error: clean_shm\n");
- clean_shm(1);
- }
- do_new_fb(1);
- if (db) rfbLog("*** XIO error: check_xevents\n");
- check_xevents(1);
-
- /* sadly, we can never return... */
- if (db) rfbLog("*** XIO error: watch_loop\n");
- watch_loop();
- clean_up_exit(1);
- }
- }
-#endif
-
- interrupted(-1);
-
- if (d) {} /* unused vars warning: */
-
- return (*XIOerr_def)(d);
-}
-
-static char *xerrors[] = {
- "Success",
- "BadRequest",
- "BadValue",
- "BadWindow",
- "BadPixmap",
- "BadAtom",
- "BadCursor",
- "BadFont",
- "BadMatch",
- "BadDrawable",
- "BadAccess",
- "BadAlloc",
- "BadColor",
- "BadGC",
- "BadIDChoice",
- "BadName",
- "BadLength",
- "BadImplementation",
- "unknown"
-};
-static int xerrors_max = BadImplementation;
-
-char *xerror_string(XErrorEvent *error) {
- int index = -1;
- if (error) {
- index = (int) error->error_code;
- }
- if (0 <= index && index <= xerrors_max) {
- return xerrors[index];
- } else {
- return xerrors[xerrors_max+1];
- }
-}
-
-static char *crash_stack_command1 = NULL;
-static char *crash_stack_command2 = NULL;
-static char *crash_debug_command = NULL;
-
-void initialize_crash_handler(void) {
- int pid = program_pid;
- crash_stack_command1 = (char *) malloc(1000);
- crash_stack_command2 = (char *) malloc(1000);
- crash_debug_command = (char *) malloc(1000);
-
- snprintf(crash_stack_command1, 500, "echo where > /tmp/gdb.%d;"
- " env PATH=$PATH:/usr/local/bin:/usr/sfw/bin:/usr/bin"
- " gdb -x /tmp/gdb.%d -batch -n %s %d;"
- " rm -f /tmp/gdb.%d", pid, pid, program_name, pid, pid);
- snprintf(crash_stack_command2, 500, "pstack %d", program_pid);
-
- snprintf(crash_debug_command, 500, "gdb %s %d", program_name, pid);
-}
-
-static void crash_shell_help(void) {
- int pid = program_pid;
- fprintf(stderr, "\n");
- fprintf(stderr, " *** Welcome to the x11vnc crash shell! ***\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "PROGRAM: %s PID: %d\n", program_name, pid);
- fprintf(stderr, "\n");
- fprintf(stderr, "POSSIBLE DEBUGGER COMMAND:\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " %s\n", crash_debug_command);
- fprintf(stderr, "\n");
- fprintf(stderr, "Press \"q\" to quit.\n");
- fprintf(stderr, "Press \"h\" or \"?\" for this help.\n");
- fprintf(stderr, "Press \"s\" to try to run some commands to"
- " show a stack trace (gdb/pstack).\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Anything else is passed to -Q query function.\n");
- fprintf(stderr, "\n");
-}
-
-static void crash_shell(void) {
- char qry[1000], cmd[1000], line[1000];
- char *str, *p;
-
- crash_shell_help();
- fprintf(stderr, "\ncrash> ");
- while (fgets(line, 1000, stdin) != NULL) {
- str = lblanks(line);
-
- p = str;
- while(*p) {
- if (*p == '\n') {
- *p = '\0';
- }
- p++;
- }
-
- if (*str == 'q' && *(str+1) == '\0') {
- fprintf(stderr, "quiting.\n");
- return;
- } else if (*str == 'h' && *(str+1) == '\0') {
- crash_shell_help();
- } else if (*str == '?' && *(str+1) == '\0') {
- crash_shell_help();
- } else if (*str == 's' && *(str+1) == '\0') {
- sprintf(cmd, "sh -c '(%s) &'", crash_stack_command1);
- /* crash */
- if (no_external_cmds || !cmd_ok("crash")) {
- fprintf(stderr, "\nno_external_cmds=%d\n",
- no_external_cmds);
- goto crash_prompt;
- }
- fprintf(stderr, "\nrunning:\n\t%s\n\n",
- crash_stack_command1);
- system(cmd);
- usleep(1000*1000);
-
- sprintf(cmd, "sh -c '(%s) &'", crash_stack_command2);
- fprintf(stderr, "\nrunning:\n\t%s\n\n",
- crash_stack_command2);
- system(cmd);
- usleep(1000*1000);
- } else {
- snprintf(qry, 1000, "qry=%s", str);
- p = process_remote_cmd(qry, 1);
- fprintf(stderr, "\n\nresult:\n%s\n", p);
- free(p);
- }
-
-crash_prompt:
- fprintf(stderr, "crash> ");
- }
-}
-
-/*
- * General problem handler
- */
-static void interrupted (int sig) {
- exit_sig = sig;
- if (exit_flag) {
- fprintf(stderr, "extra[%d] signal: %d\n", exit_flag, sig);
- exit_flag++;
- if (use_threads) {
- usleep2(250 * 1000);
- } else if (exit_flag <= 2) {
- return;
- }
- if (rm_flagfile) {
- unlink(rm_flagfile);
- rm_flagfile = NULL;
- }
- exit(4);
- }
- exit_flag++;
- if (sig == 0) {
- fprintf(stderr, "caught X11 error:\n");
- if (crash_debug) { crash_shell(); }
- } else if (sig == -1) {
- fprintf(stderr, "caught XIO error:\n");
- } else {
- fprintf(stderr, "caught signal: %d\n", sig);
- }
- if (sig == SIGINT) {
- shut_down = 1;
- return;
- }
-
- if (crash_debug) {
- crash_shell();
- }
-
- X_UNLOCK;
-
- if (icon_mode) {
- clean_icon_mode();
- }
- /* remove the shm areas with quick=1: */
- clean_shm(1);
-
- if (sig == -1) {
- /* not worth trying any more cleanup, X server probably gone */
- if (rm_flagfile) {
- unlink(rm_flagfile);
- rm_flagfile = NULL;
- }
- exit(3);
- }
-
- /* X keyboard cleanups */
- delete_added_keycodes(0);
-
- if (clear_mods == 1) {
- clear_modifiers(0);
- } else if (clear_mods == 2) {
- clear_keys();
- } else if (clear_mods == 3) {
- clear_keys();
- clear_locks();
- }
- if (no_autorepeat) {
- autorepeat(1, 0);
- }
- if (use_solid_bg) {
- solid_bg(1);
- }
- if (ncache || ncache0) {
- kde_no_animate(1);
- }
- stop_stunnel();
-
- if (crash_debug) {
- crash_shell();
- }
-
- if (sig) {
- if (rm_flagfile) {
- unlink(rm_flagfile);
- rm_flagfile = NULL;
- }
- exit(2);
- }
-}
-
-static void ignore_sigs(char *list) {
- char *str, *p;
- int ignore = 1;
- if (list == NULL || *list == '\0') {
- return;
- }
- str = strdup(list);
- p = strtok(str, ":,");
-
-#define SETSIG(x, y) \
- if (strstr(p, x)) { \
- if (ignore) { \
- signal(y, SIG_IGN); \
- } else { \
- signal(y, interrupted); \
- } \
- }
-
-#ifdef SIG_IGN
- while (p) {
- if (!strcmp(p, "ignore")) {
- ignore = 1;
- } else if (!strcmp(p, "exit")) {
- ignore = 0;
- }
- /* Take off every 'sig' ;-) */
-#ifdef SIGHUP
- SETSIG("HUP", SIGHUP);
-#endif
-#ifdef SIGINT
- SETSIG("INT", SIGINT);
-#endif
-#ifdef SIGQUIT
- SETSIG("QUIT", SIGQUIT);
-#endif
-#ifdef SIGTRAP
- SETSIG("TRAP", SIGTRAP);
-#endif
-#ifdef SIGABRT
- SETSIG("ABRT", SIGABRT);
-#endif
-#ifdef SIGBUS
- SETSIG("BUS", SIGBUS);
-#endif
-#ifdef SIGFPE
- SETSIG("FPE", SIGFPE);
-#endif
-#ifdef SIGSEGV
- SETSIG("SEGV", SIGSEGV);
-#endif
-#ifdef SIGPIPE
- SETSIG("PIPE", SIGPIPE);
-#endif
-#ifdef SIGTERM
- SETSIG("TERM", SIGTERM);
-#endif
-#ifdef SIGUSR1
- SETSIG("USR1", SIGUSR1);
-#endif
-#ifdef SIGUSR2
- SETSIG("USR2", SIGUSR2);
-#endif
-#ifdef SIGCONT
- SETSIG("CONT", SIGCONT);
-#endif
-#ifdef SIGSTOP
- SETSIG("STOP", SIGSTOP);
-#endif
-#ifdef SIGTSTP
- SETSIG("TSTP", SIGTSTP);
-#endif
- p = strtok(NULL, ":,");
- }
-#endif /* SIG_IGN */
- free(str);
-}
-
-/* signal handlers */
-void initialize_signals(void) {
- signal(SIGHUP, interrupted);
- signal(SIGINT, interrupted);
- signal(SIGQUIT, interrupted);
- signal(SIGABRT, interrupted);
- signal(SIGTERM, interrupted);
- signal(SIGBUS, interrupted);
- signal(SIGSEGV, interrupted);
- signal(SIGFPE, interrupted);
-
- if (!sigpipe || *sigpipe == '\0' || !strcmp(sigpipe, "skip")) {
- ;
- } else if (strstr(sigpipe, "ignore:") == sigpipe) {
- ignore_sigs(sigpipe);
- } else if (strstr(sigpipe, "exit:") == sigpipe) {
- ignore_sigs(sigpipe);
- } else if (!strcmp(sigpipe, "ignore")) {
-#ifdef SIG_IGN
- signal(SIGPIPE, SIG_IGN);
-#endif
- } else if (!strcmp(sigpipe, "exit")) {
- rfbLog("initialize_signals: will exit on SIGPIPE\n");
- signal(SIGPIPE, interrupted);
- }
-
-#if NO_X11
- return;
-#else
- X_LOCK;
- Xerror_def = XSetErrorHandler(Xerror);
- XIOerr_def = XSetIOErrorHandler(XIOerr);
- X_UNLOCK;
-#endif /* NO_X11 */
-}
-
-void unset_signals(void) {
- signal(SIGHUP, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGABRT, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGBUS, SIG_DFL);
- signal(SIGSEGV, SIG_DFL);
- signal(SIGFPE, SIG_DFL);
- signal(SIGPIPE, SIG_DFL);
-}
-
-void close_exec_fds(void) {
- int fd;
-#ifdef FD_CLOEXEC
- for (fd = 3; fd < 64; fd++) {
- int flags = fcntl(fd, F_GETFD);
- if (flags != -1) {
- flags |= FD_CLOEXEC;
- fcntl(fd, F_SETFD, flags);
- }
- }
-#endif
-}
-
-int known_sigpipe_mode(char *s) {
-/*
- * skip, ignore, exit
- */
- if (strstr(s, "ignore:") == s) {
- return 1;
- }
- if (strstr(s, "exit:") == s) {
- return 1;
- }
- if (strcmp(s, "skip") && strcmp(s, "ignore") &&
- strcmp(s, "exit")) {
- return 0;
- } else {
- return 1;
- }
-}
-
-
diff --git a/x11vnc/cleanup.h b/x11vnc/cleanup.h
deleted file mode 100644
index 0c4dcea..0000000
--- a/x11vnc/cleanup.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_CLEANUP_H
-#define _X11VNC_CLEANUP_H
-
-/* -- cleanup.h -- */
-
-extern int trapped_xerror;
-extern int trapped_xioerror;
-extern int trapped_getimage_xerror;
-extern int trapped_record_xerror;
-extern XErrorEvent *trapped_xerror_event;
-
-extern int crash_debug;
-
-extern void clean_shm(int quick);
-extern void clean_up_exit(int ret);
-
-extern int trap_xerror(Display *d, XErrorEvent *error);
-extern int trap_xioerror(Display *d);
-extern int trap_getimage_xerror(Display *d, XErrorEvent *error);
-extern char *xerror_string(XErrorEvent *error);
-extern void initialize_crash_handler(void);
-extern void initialize_signals(void);
-extern void unset_signals(void);
-extern void close_exec_fds(void);
-extern int known_sigpipe_mode(char *s);
-
-#endif /* _X11VNC_CLEANUP_H */
diff --git a/x11vnc/connections.c b/x11vnc/connections.c
deleted file mode 100644
index d2a9b5c..0000000
--- a/x11vnc/connections.c
+++ /dev/null
@@ -1,4437 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- connections.c -- */
-
-#include "x11vnc.h"
-#include "inet.h"
-#include "remote.h"
-#include "keyboard.h"
-#include "cleanup.h"
-#include "gui.h"
-#include "solid.h"
-#include "rates.h"
-#include "screen.h"
-#include "unixpw.h"
-#include "user.h"
-#include "scan.h"
-#include "sslcmds.h"
-#include "sslhelper.h"
-#include "xwrappers.h"
-#include "xevents.h"
-#include "win_utils.h"
-#include "macosx.h"
-#include "macosxCG.h"
-#include "userinput.h"
-#include "pointer.h"
-#include "xrandr.h"
-
-/*
- * routines for handling incoming, outgoing, etc connections
- */
-
-/* string for the VNC_CONNECT property */
-char vnc_connect_str[VNC_CONNECT_MAX+1];
-Atom vnc_connect_prop = None;
-char x11vnc_remote_str[X11VNC_REMOTE_MAX+1];
-Atom x11vnc_remote_prop = None;
-rfbClientPtr inetd_client = NULL;
-
-int all_clients_initialized(void);
-char *list_clients(void);
-int new_fb_size_clients(rfbScreenInfoPtr s);
-void close_all_clients(void);
-void close_clients(char *str);
-void set_client_input(char *str);
-void set_child_info(void);
-int cmd_ok(char *cmd);
-void client_gone(rfbClientPtr client);
-void client_gone_chat_helper(rfbClientPtr client);
-void reverse_connect(char *str);
-void set_vnc_connect_prop(char *str);
-void read_vnc_connect_prop(int);
-void set_x11vnc_remote_prop(char *str);
-void read_x11vnc_remote_prop(int);
-void check_connect_inputs(void);
-void check_gui_inputs(void);
-rfbClientPtr create_new_client(int sock, int start_thread);
-enum rfbNewClientAction new_client(rfbClientPtr client);
-enum rfbNewClientAction new_client_chat_helper(rfbClientPtr client);
-rfbBool password_check_chat_helper(rfbClientPtr cl, const char* response, int len);
-void start_client_info_sock(char *host_port_cookie);
-void send_client_info(char *str);
-void adjust_grabs(int grab, int quiet);
-void check_new_clients(void);
-int accept_client(rfbClientPtr client);
-void check_ipv6_listen(long usec);
-void check_unix_sock(long usec);
-int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
- int len, FILE *output);
-int check_access(char *addr);
-void client_set_net(rfbClientPtr client);
-char *get_xprop(char *prop, Window win);
-int set_xprop(char *prop, Window win, char *value);
-char *bcx_xattach(char *str, int *pg_init, int *kg_init);
-void grab_state(int *ptr_grabbed, int *kbd_grabbed);
-char *wininfo(Window win, int show_children);
-
-static rfbClientPtr *client_match(char *str);
-static void free_client_data(rfbClientPtr client);
-static void ugly_geom(char *p, int *x, int *y);
-static int ugly_window(char *addr, char *userhost, int X, int Y,
- int timeout, char *mode, int accept);
-static int action_match(char *action, int rc);
-static void check_connect_file(char *file);
-static void send_client_connect(void);
-
-
-/*
- * check that all clients are in RFB_NORMAL state
- */
-int all_clients_initialized(void) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int ok = 1;
-
- if (! screen) {
- return ok;
- }
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (cl->state != RFB_NORMAL) {
- ok = 0;
- } else {
- client_normal_count++;
- }
- }
- rfbReleaseClientIterator(iter);
-
- return ok;
-}
-
-char *list_clients(void) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- char *list, tmp[256];
- int count = 0;
-
- if (!screen) {
- return strdup("");
- }
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- client_set_net(cl);
- count++;
- }
- rfbReleaseClientIterator(iter);
-
- /*
- * each client:
- * <id>:<ip>:<port>:<user>:<unix>:<hostname>:<input>:<loginview>:<time>,
- * 8+1+64+1+5+1+24+1+24+1+256+1+5+1+1+1+10+1
- * 123.123.123.123:60000/0x11111111-rw,
- * so count+1 * 1000 must cover it.
- */
- list = (char *) malloc((count+1)*1000);
-
- list[0] = '\0';
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd = (ClientData *) cl->clientData;
- char *tmp_host, *p;
-
- if (! cd) {
- continue;
- }
- if (*list != '\0') {
- strcat(list, ",");
- }
- sprintf(tmp, "0x%x:", cd->uid);
- strcat(list, tmp);
- p = tmp_host = strdup(cl->host);
- while (*p) {
- if (*p == ':') *p = '#';
- p++;
- }
- strcat(list, tmp_host);
- free(tmp_host);
- strcat(list, ":");
- sprintf(tmp, "%d:", cd->client_port);
- strcat(list, tmp);
- if (cd->username[0] == '\0') {
- char *s = ident_username(cl);
- if (s) free(s);
- }
- if (strstr(cd->username, "UNIX:") == cd->username) {
- strcat(list, cd->username + strlen("UNIX:"));
- } else {
- strcat(list, cd->username);
- }
- strcat(list, ":");
- if (cd->unixname[0] == '\0') {
- strcat(list, "none");
- } else {
- strcat(list, cd->unixname);
- }
- strcat(list, ":");
- p = tmp_host = strdup(cd->hostname);
- while (*p) {
- if (*p == ':') *p = '#';
- p++;
- }
- strcat(list, tmp_host);
- free(tmp_host);
- strcat(list, ":");
- strcat(list, cd->input);
- strcat(list, ":");
- sprintf(tmp, "%d", cd->login_viewonly);
- strcat(list, tmp);
- strcat(list, ":");
- sprintf(tmp, "%d", (int) cd->login_time);
- strcat(list, tmp);
- }
- rfbReleaseClientIterator(iter);
- return list;
-}
-
-/* count number of clients supporting NewFBSize */
-int new_fb_size_clients(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int count = 0;
-
- if (! s) {
- return 0;
- }
-
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (cl->useNewFBSize) {
- count++;
- }
- }
- rfbReleaseClientIterator(iter);
- return count;
-}
-
-void close_all_clients(void) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- if (! screen) {
- return;
- }
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- rfbCloseClient(cl);
- rfbClientConnectionGone(cl);
- }
- rfbReleaseClientIterator(iter);
-}
-
-static rfbClientPtr *client_match(char *str) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl, *cl_list;
- int i, n, host_warn = 0, hex_warn = 0;
-
- n = client_count + 10;
- cl_list = (rfbClientPtr *) malloc(n * sizeof(rfbClientPtr));
-
- i = 0;
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd = (ClientData *) cl->clientData;
- if (strstr(str, "0x") == str) {
- unsigned int in;
- int id;
- if (! cd) {
- continue;
- }
- if (sscanf(str, "0x%x", &in) != 1) {
- if (hex_warn++) {
- continue;
- }
- rfbLog("skipping invalid client hex id: %s\n",
- str);
- continue;
- }
- id = (unsigned int) in;
- if (cd->uid == id) {
- cl_list[i++] = cl;
- }
- } else {
- int port = -1;
- char *rstr = strdup(str);
- char *q = strrchr(rstr, ':');
- if (q) {
- port = atoi(q+1);
- *q = '\0';
- if (port == 0 && q[1] != '0') {
- port = -1;
- } else if (port < 0) {
- port = -port;
- } else if (port < 200) {
- port = 5500 + port;
- }
- }
- if (ipv6_ip(str)) {
- ;
- } else if (! dotted_ip(str, 0)) {
- char *orig = rstr;
- rstr = host2ip(rstr);
- free(orig);
- if (rstr == NULL || *rstr == '\0') {
- if (host_warn++) {
- continue;
- }
- rfbLog("skipping bad lookup: \"%s\"\n", str);
- continue;
- }
- rfbLog("lookup: %s -> %s port=%d\n", str, rstr, port);
- }
- if (!strcmp(rstr, cl->host)) {
- int ok = 1;
- if (port > 0) {
- if (cd != NULL && cd->client_port > 0) {
- if (cd->client_port != port) {
- ok = 0;
- }
- } else {
- int cport = get_remote_port(cl->sock);
- if (cport != port) {
- ok = 0;
- }
- }
- }
- if (ok) {
- cl_list[i++] = cl;
- }
- }
- free(rstr);
- }
- if (i >= n - 1) {
- break;
- }
- }
- rfbReleaseClientIterator(iter);
-
- cl_list[i] = NULL;
-
- return cl_list;
-}
-
-void close_clients(char *str) {
- rfbClientPtr *cl_list, *cp;
-
- if (!strcmp(str, "all") || !strcmp(str, "*")) {
- close_all_clients();
- return;
- }
-
- if (! screen) {
- return;
- }
-
- cl_list = client_match(str);
-
- cp = cl_list;
- while (*cp) {
- rfbCloseClient(*cp);
- rfbClientConnectionGone(*cp);
- cp++;
- }
- free(cl_list);
-}
-
-void set_client_input(char *str) {
- rfbClientPtr *cl_list, *cp;
- char *p, *val;
-
- /* str is "match:value" */
-
- if (! screen) {
- return;
- }
-
- p = strrchr(str, ':');
- if (! p) {
- return;
- }
- *p = '\0';
- p++;
- val = short_kmbcf(p);
-
- cl_list = client_match(str);
-
- cp = cl_list;
- while (*cp) {
- ClientData *cd = (ClientData *) (*cp)->clientData;
- if (! cd) {
- continue;
- }
- cd->input[0] = '\0';
- strcat(cd->input, "_");
- strcat(cd->input, val);
- cp++;
- }
-
- free(val);
- free(cl_list);
-}
-
-void set_child_info(void) {
- char pid[16];
- /* set up useful environment for child process */
- sprintf(pid, "%d", (int) getpid());
- set_env("X11VNC_PID", pid);
- if (program_name) {
- /* e.g. for remote control -R */
- set_env("X11VNC_PROG", program_name);
- }
- if (program_cmdline) {
- set_env("X11VNC_CMDLINE", program_cmdline);
- }
- if (raw_fb_str) {
- set_env("X11VNC_RAWFB_STR", raw_fb_str);
- } else {
- set_env("X11VNC_RAWFB_STR", "");
- }
-}
-
-int cmd_ok(char *cmd) {
- char *p, *str;
- if (no_external_cmds) {
- return 0;
- }
- if (! cmd || cmd[0] == '\0') {
- return 0;
- }
- if (! allowed_external_cmds) {
- /* default, allow any (overridden by -nocmds) */
- return 1;
- }
-
- str = strdup(allowed_external_cmds);
- p = strtok(str, ",");
- while (p) {
- if (!strcmp(p, cmd)) {
- free(str);
- return 1;
- }
- p = strtok(NULL, ",");
- }
- free(str);
- return 0;
-}
-
-/*
- * utility to run a user supplied command setting some RFB_ env vars.
- * used by, e.g., accept_client() and client_gone()
- */
-int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
- int len, FILE *output) {
- char *old_display = NULL;
- char *addr = NULL;
- char str[100];
- int rc, ok;
- ClientData *cd = NULL;
- client_set_net(client);
- if (client != NULL) {
- cd = (ClientData *) client->clientData;
- addr = client->host;
- }
-
- if (addr == NULL || addr[0] == '\0') {
- addr = "unknown-host";
- }
-
- /* set RFB_CLIENT_ID to semi unique id for command to use */
- if (cd && cd->uid) {
- sprintf(str, "0x%x", cd->uid);
- } else {
- /* not accepted yet: */
- sprintf(str, "0x%x", clients_served);
- }
- set_env("RFB_CLIENT_ID", str);
-
- /* set RFB_CLIENT_IP to IP addr for command to use */
- set_env("RFB_CLIENT_IP", addr);
-
- /* set RFB_X11VNC_PID to our pid for command to use */
- sprintf(str, "%d", (int) getpid());
- set_env("RFB_X11VNC_PID", str);
-
- if (client == NULL) {
- ;
- } else if (client->state == RFB_PROTOCOL_VERSION) {
- set_env("RFB_STATE", "PROTOCOL_VERSION");
- } else if (client->state == RFB_SECURITY_TYPE) {
- set_env("RFB_STATE", "SECURITY_TYPE");
- } else if (client->state == RFB_AUTHENTICATION) {
- set_env("RFB_STATE", "AUTHENTICATION");
- } else if (client->state == RFB_INITIALISATION) {
- set_env("RFB_STATE", "INITIALISATION");
- } else if (client->state == RFB_NORMAL) {
- set_env("RFB_STATE", "NORMAL");
- } else {
- set_env("RFB_STATE", "UNKNOWN");
- }
- if (certret_str) {
- set_env("RFB_SSL_CLIENT_CERT", certret_str);
- } else {
- set_env("RFB_SSL_CLIENT_CERT", "");
- }
-
- /* set RFB_CLIENT_PORT to peer port for command to use */
- if (cd && cd->client_port > 0) {
- sprintf(str, "%d", cd->client_port);
- } else if (client) {
- sprintf(str, "%d", get_remote_port(client->sock));
- }
- set_env("RFB_CLIENT_PORT", str);
-
- set_env("RFB_MODE", mode);
-
- /*
- * now do RFB_SERVER_IP and RFB_SERVER_PORT (i.e. us!)
- * This will establish a 5-tuple (including tcp) the external
- * program can potentially use to work out the virtual circuit
- * for this connection.
- */
- if (cd && cd->server_ip) {
- set_env("RFB_SERVER_IP", cd->server_ip);
- } else if (client) {
- char *sip = get_local_host(client->sock);
- set_env("RFB_SERVER_IP", sip);
- if (sip) free(sip);
- }
-
- if (cd && cd->server_port > 0) {
- sprintf(str, "%d", cd->server_port);
- } else if (client) {
- sprintf(str, "%d", get_local_port(client->sock));
- }
- set_env("RFB_SERVER_PORT", str);
-
- if (cd) {
- sprintf(str, "%d", cd->login_viewonly);
- } else {
- sprintf(str, "%d", -1);
- }
- set_env("RFB_LOGIN_VIEWONLY", str);
-
- if (cd) {
- sprintf(str, "%d", (int) cd->login_time);
- } else {
- sprintf(str, ">%d", (int) time(NULL));
- }
- set_env("RFB_LOGIN_TIME", str);
-
- sprintf(str, "%d", (int) time(NULL));
- set_env("RFB_CURRENT_TIME", str);
-
- if (!cd || !cd->username || cd->username[0] == '\0') {
- set_env("RFB_USERNAME", "unknown-user");
- } else {
- set_env("RFB_USERNAME", cd->username);
- }
- /*
- * Better set DISPLAY to the one we are polling, if they
- * want something trickier, they can handle on their own
- * via environment, etc.
- */
- if (getenv("DISPLAY")) {
- old_display = strdup(getenv("DISPLAY"));
- }
-
- if (raw_fb && ! dpy) { /* raw_fb hack */
- set_env("DISPLAY", "rawfb");
- } else {
- set_env("DISPLAY", DisplayString(dpy));
- }
-
- /*
- * work out the number of clients (have to use client_count
- * since there is deadlock in rfbGetClientIterator)
- */
- sprintf(str, "%d", client_count);
- set_env("RFB_CLIENT_COUNT", str);
-
- /* gone, accept, afteraccept */
- ok = 0;
- if (!strcmp(mode, "env")) {
- return 1;
- }
- if (!strcmp(mode, "accept") && cmd_ok("accept")) {
- ok = 1;
- }
- if (!strcmp(mode, "afteraccept") && cmd_ok("afteraccept")) {
- ok = 1;
- }
- if (!strcmp(mode, "gone") && cmd_ok("gone")) {
- ok = 1;
- }
- if (!strcmp(mode, "cmd_verify") && cmd_ok("unixpw")) {
- ok = 1;
- }
- if (!strcmp(mode, "read_passwds") && cmd_ok("passwdfile")) {
- ok = 1;
- }
- if (!strcmp(mode, "custom_passwd") && cmd_ok("custom_passwd")) {
- ok = 1;
- }
- if (no_external_cmds || !ok) {
- rfbLogEnable(1);
- rfbLog("cannot run external commands in -nocmds mode:\n");
- rfbLog(" \"%s\"\n", cmd);
- rfbLog(" exiting.\n");
- clean_up_exit(1);
- }
- rfbLog("running command:\n");
- if (!quiet) {
- fprintf(stderr, "\n %s\n\n", cmd);
- }
- close_exec_fds();
-
- if (output != NULL) {
- FILE *ph;
- char line[1024];
- char *cmd2 = NULL;
- char tmp[] = "/tmp/x11vnc-tmp.XXXXXX";
- int deltmp = 0;
-
- if (input != NULL) {
- int tmp_fd = mkstemp(tmp);
- if (tmp_fd < 0) {
- rfbLog("mkstemp failed on: %s\n", tmp);
- clean_up_exit(1);
- }
- write(tmp_fd, input, len);
- close(tmp_fd);
- deltmp = 1;
- cmd2 = (char *) malloc(100 + strlen(tmp) + strlen(cmd));
- sprintf(cmd2, "/bin/cat %s | %s", tmp, cmd);
-
- ph = popen(cmd2, "r");
- } else {
- ph = popen(cmd, "r");
- }
- if (ph == NULL) {
- rfbLog("popen(%s) failed", cmd);
- rfbLogPerror("popen");
- clean_up_exit(1);
- }
- memset(line, 0, sizeof(line));
- while (fgets(line, sizeof(line), ph) != NULL) {
- int j, k = -1;
- if (0) fprintf(stderr, "line: %s", line);
- /* take care to handle embedded nulls */
- for (j=0; j < (int) sizeof(line); j++) {
- if (line[j] != '\0') {
- k = j;
- }
- }
- if (k >= 0) {
- write(fileno(output), line, k+1);
- }
- memset(line, 0, sizeof(line));
- }
-
- rc = pclose(ph);
-
- if (cmd2 != NULL) {
- free(cmd2);
- }
- if (deltmp) {
- unlink(tmp);
- }
- goto got_rc;
- } else if (input != NULL) {
- FILE *ph = popen(cmd, "w");
- if (ph == NULL) {
- rfbLog("popen(%s) failed", cmd);
- rfbLogPerror("popen");
- clean_up_exit(1);
- }
- write(fileno(ph), input, len);
- rc = pclose(ph);
- goto got_rc;
- }
-
-#if LIBVNCSERVER_HAVE_FORK
- {
- pid_t pid, pidw;
- struct sigaction sa, intr, quit;
- sigset_t omask;
-
- sa.sa_handler = SIG_IGN;
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sigaction(SIGINT, &sa, &intr);
- sigaction(SIGQUIT, &sa, &quit);
-
- sigaddset(&sa.sa_mask, SIGCHLD);
- sigprocmask(SIG_BLOCK, &sa.sa_mask, &omask);
-
- if ((pid = fork()) > 0 || pid == -1) {
-
- if (pid != -1) {
- pidw = waitpid(pid, &rc, 0);
- }
-
- sigaction(SIGINT, &intr, (struct sigaction *) NULL);
- sigaction(SIGQUIT, &quit, (struct sigaction *) NULL);
- sigprocmask(SIG_SETMASK, &omask, (sigset_t *) NULL);
-
- if (pid == -1) {
- fprintf(stderr, "could not fork\n");
- rfbLogPerror("fork");
- rc = system(cmd);
- }
- } else {
- /* this should close port 5900, etc.. */
- int fd;
- sigaction(SIGINT, &intr, (struct sigaction *) NULL);
- sigaction(SIGQUIT, &quit, (struct sigaction *) NULL);
- sigprocmask(SIG_SETMASK, &omask, (sigset_t *) NULL);
- for (fd=3; fd<256; fd++) {
- close(fd);
- }
-/* XXX test more */
- if (!strcmp(mode, "gone")) {
-#if LIBVNCSERVER_HAVE_SETSID
- setsid();
-#else
- setpgrp();
-#endif
- }
- execlp("/bin/sh", "/bin/sh", "-c", cmd, (char *) NULL);
- exit(1);
- }
- }
-#else
- rc = system(cmd);
-#endif
- got_rc:
-
- if (rc >= 256) {
- rc = rc/256;
- }
- rfbLog("command returned: %d\n", rc);
-
- if (old_display) {
- set_env("DISPLAY", old_display);
- free(old_display);
- }
-
- return rc;
-}
-
-static void free_client_data(rfbClientPtr client) {
- if (! client) {
- return;
- }
- if (client->clientData) {
- ClientData *cd = (ClientData *) client->clientData;
- if (cd) {
- if (cd->server_ip) {
- free(cd->server_ip);
- cd->server_ip = NULL;
- }
- if (cd->hostname) {
- free(cd->hostname);
- cd->hostname = NULL;
- }
- if (cd->username) {
- free(cd->username);
- cd->username = NULL;
- }
- if (cd->unixname) {
- free(cd->unixname);
- cd->unixname = NULL;
- }
- }
- free(client->clientData);
- client->clientData = NULL;
- }
-}
-
-static int accepted_client = 0;
-
-/*
- * callback for when a client disconnects
- */
-void client_gone(rfbClientPtr client) {
- ClientData *cd = NULL;
-
- CLIENT_LOCK;
-
- client_count--;
- if (client_count < 0) client_count = 0;
-
- speeds_net_rate_measured = 0;
- speeds_net_latency_measured = 0;
-
- rfbLog("client_count: %d\n", client_count);
- last_client_gone = dnow();
-
- if (unixpw_in_progress && unixpw_client) {
- if (client == unixpw_client) {
- unixpw_in_progress = 0;
- /* mutex */
- screen->permitFileTransfer = unixpw_file_xfer_save;
- if ((tightfilexfer = unixpw_tightvnc_xfer_save)) {
-#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
- rfbLog("rfbRegisterTightVNCFileTransferExtension: 3\n");
- rfbRegisterTightVNCFileTransferExtension();
-#endif
- }
- unixpw_client = NULL;
- copy_screen();
- }
- }
-
-
- if (no_autorepeat && client_count == 0) {
- autorepeat(1, 0);
- }
- if (use_solid_bg && client_count == 0) {
- solid_bg(1);
- }
- if ((ncache || ncache0) && client_count == 0) {
- kde_no_animate(1);
- }
- if (client->clientData) {
- cd = (ClientData *) client->clientData;
- if (cd->ssl_helper_pid > 0) {
- int status;
- rfbLog("sending SIGTERM to ssl_helper_pid: %d\n",
- cd->ssl_helper_pid);
- kill(cd->ssl_helper_pid, SIGTERM);
- usleep(200*1000);
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_WAITPID
- waitpid(cd->ssl_helper_pid, &status, WNOHANG);
-#endif
- ssl_helper_pid(cd->ssl_helper_pid, -1); /* delete */
- }
- }
- if (gone_cmd && *gone_cmd != '\0') {
- if (strstr(gone_cmd, "popup") == gone_cmd) {
- int x = -64000, y = -64000, timeout = 120;
- char *userhost = ident_username(client);
- char *addr, *p, *mode;
-
- /* extract timeout */
- if ((p = strchr(gone_cmd, ':')) != NULL) {
- int in;
- if (sscanf(p+1, "%d", &in) == 1) {
- timeout = in;
- }
- }
- /* extract geometry */
- if ((p = strpbrk(gone_cmd, "+-")) != NULL) {
- ugly_geom(p, &x, &y);
- }
-
- /* find mode: mouse, key, or both */
- if (strstr(gone_cmd, "popupmouse") == gone_cmd) {
- mode = "mouse_only";
- } else if (strstr(gone_cmd, "popupkey") == gone_cmd) {
- mode = "key_only";
- } else {
- mode = "both";
- }
-
- addr = client->host;
-
- ugly_window(addr, userhost, x, y, timeout, mode, 0);
-
- free(userhost);
- } else {
- rfbLog("client_gone: using cmd: %s\n", client->host);
- run_user_command(gone_cmd, client, "gone", NULL, 0, NULL);
- }
- }
-
- free_client_data(client);
-
- if (inetd && client == inetd_client) {
- rfbLog("inetd viewer exited.\n");
- if (gui_pid > 0) {
- rfbLog("killing gui_pid %d\n", gui_pid);
- kill(gui_pid, SIGTERM);
- }
- clean_up_exit(0);
- }
-
- if (connect_once) {
- /*
- * This non-exit is done for a bad passwd to be consistent
- * with our RFB_CLIENT_REFUSE behavior in new_client() (i.e.
- * we disconnect after 1 successful connection).
- */
- if ((client->state == RFB_PROTOCOL_VERSION ||
- client->state == RFB_SECURITY_TYPE ||
- client->state == RFB_AUTHENTICATION ||
- client->state == RFB_INITIALISATION) && accepted_client) {
- rfbLog("connect_once: invalid password or early "
- "disconnect. %d\n", client->state);
- rfbLog("connect_once: waiting for next connection.\n");
- accepted_client--;
- if (accepted_client < 0) {
- accepted_client = 0;
- }
- CLIENT_UNLOCK;
- if (connect_or_exit) {
- clean_up_exit(1);
- }
- return;
- }
- if (shared && client_count > 0) {
- rfbLog("connect_once: other shared clients still "
- "connected, not exiting.\n");
- CLIENT_UNLOCK;
- return;
- }
-
- rfbLog("viewer exited.\n");
- if ((client_connect || connect_or_exit) && gui_pid > 0) {
- rfbLog("killing gui_pid %d\n", gui_pid);
- kill(gui_pid, SIGTERM);
- }
- CLIENT_UNLOCK;
- clean_up_exit(0);
- }
-#ifdef MACOSX
- if (macosx_console && client_count == 0) {
- macosxCG_refresh_callback_off();
- }
-#endif
- CLIENT_UNLOCK;
-}
-
-/*
- * Simple routine to limit access via string compare. A power user will
- * want to compile libvncserver with libwrap support and use /etc/hosts.allow.
- */
-int check_access(char *addr) {
- int allowed = 0;
- int ssl = 0;
- char *p, *list;
-
- if (use_openssl || use_stunnel) {
- ssl = 1;
- }
- if (deny_all) {
- rfbLog("check_access: new connections are currently "
- "blocked.\n");
- return 0;
- }
- if (addr == NULL || *addr == '\0') {
- rfbLog("check_access: denying empty host IP address string.\n");
- return 0;
- }
-
- if (allow_list == NULL) {
- /* set to "" to possibly append allow_once */
- allow_list = strdup("");
- }
- if (*allow_list == '\0' && allow_once == NULL) {
- /* no constraints, accept it */
- return 1;
- }
-
- if (strchr(allow_list, '/')) {
- /* a file of IP addresess or prefixes */
- int len, len2 = 0;
- struct stat sbuf;
- FILE *in;
- char line[1024], *q;
-
- if (stat(allow_list, &sbuf) != 0) {
- rfbLogEnable(1);
- rfbLog("check_access: failure stating file: %s\n",
- allow_list);
- rfbLogPerror("stat");
- clean_up_exit(1);
- }
- len = sbuf.st_size + 1; /* 1 more for '\0' at end */
- if (allow_once) {
- len2 = strlen(allow_once) + 2;
- len += len2;
- }
- if (ssl) {
- len2 = strlen("127.0.0.1") + 2;
- len += len2;
- }
- list = (char *) malloc(len);
- list[0] = '\0';
-
- in = fopen(allow_list, "r");
- if (in == NULL) {
- rfbLogEnable(1);
- rfbLog("check_access: cannot open: %s\n", allow_list);
- rfbLogPerror("fopen");
- clean_up_exit(1);
- }
- while (fgets(line, 1024, in) != NULL) {
- if ( (q = strchr(line, '#')) != NULL) {
- *q = '\0';
- }
- if (strlen(list) + strlen(line) >=
- (size_t) (len - len2)) {
- /* file grew since our stat() */
- break;
- }
- strcat(list, line);
- }
- fclose(in);
- if (allow_once) {
- strcat(list, "\n");
- strcat(list, allow_once);
- strcat(list, "\n");
- }
- if (ssl) {
- strcat(list, "\n");
- strcat(list, "127.0.0.1");
- strcat(list, "\n");
- }
- } else {
- int len = strlen(allow_list) + 1;
- if (allow_once) {
- len += strlen(allow_once) + 1;
- }
- if (ssl) {
- len += strlen("127.0.0.1") + 1;
- }
- list = (char *) malloc(len);
- list[0] = '\0';
- strcat(list, allow_list);
- if (allow_once) {
- strcat(list, ",");
- strcat(list, allow_once);
- }
- if (ssl) {
- strcat(list, ",");
- strcat(list, "127.0.0.1");
- }
- }
-
- if (allow_once) {
- free(allow_once);
- allow_once = NULL;
- }
-
- p = strtok(list, ", \t\n\r");
- while (p) {
- char *chk, *q, *r = NULL;
- if (*p == '\0') {
- p = strtok(NULL, ", \t\n\r");
- continue;
- }
- if (ipv6_ip(p)) {
- chk = p;
- } else if (! dotted_ip(p, 1)) {
- r = host2ip(p);
- if (r == NULL || *r == '\0') {
- rfbLog("check_access: bad lookup \"%s\"\n", p);
- p = strtok(NULL, ", \t\n\r");
- continue;
- }
- rfbLog("check_access: lookup %s -> %s\n", p, r);
- chk = r;
- } else {
- chk = p;
- }
- if (getenv("X11VNC_DEBUG_ACCESS")) fprintf(stderr, "chk: %s part: %s addr: %s\n", chk, p, addr);
-
- q = strstr(addr, chk);
- if (ipv6_ip(addr)) {
- if (!strcmp(chk, "localhost") && !strcmp(addr, "::1")) {
- rfbLog("check_access: client addr %s is local.\n", addr);
- allowed = 1;
- } else if (!strcmp(chk, "::1") && !strcmp(addr, "::1")) {
- rfbLog("check_access: client addr %s is local.\n", addr);
- allowed = 1;
- } else if (!strcmp(chk, "127.0.0.1") && !strcmp(addr, "::1")) {
- /* this if for host2ip("localhost") */
- rfbLog("check_access: client addr %s is local.\n", addr);
- allowed = 1;
- } else if (q == addr) {
- rfbLog("check_access: client %s matches pattern %s\n", addr, chk);
- allowed = 1;
- }
- } else if (chk[strlen(chk)-1] != '.') {
- if (!strcmp(addr, chk)) {
- if (chk != p) {
- rfbLog("check_access: client %s " "matches host %s=%s\n", addr, chk, p);
- } else {
- rfbLog("check_access: client %s " "matches host %s\n", addr, chk);
- }
- allowed = 1;
- } else if(!strcmp(chk, "localhost") && !strcmp(addr, "127.0.0.1")) {
- allowed = 1;
- }
- } else if (q == addr) {
- rfbLog("check_access: client %s matches pattern %s\n", addr, chk);
- allowed = 1;
- }
- p = strtok(NULL, ", \t\n\r");
- if (r) {
- free(r);
- }
- if (allowed) {
- break;
- }
- }
- free(list);
- return allowed;
-}
-
-/*
- * x11vnc's first (and only) visible widget: accept/reject dialog window.
- * We go through this pain to avoid dependency on libXt...
- */
-static int ugly_window(char *addr, char *userhost, int X, int Y,
- int timeout, char *mode, int accept) {
-#if NO_X11
- if (!addr || !userhost || !X || !Y || !timeout || !mode || !accept) {}
- RAWFB_RET(0)
- nox11_exit(1);
- return 0;
-#else
-
-#define t2x2_width 16
-#define t2x2_height 16
-static unsigned char t2x2_bits[] = {
- 0xff, 0xff, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff,
- 0x33, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33,
- 0xff, 0xff, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33};
-
- Window awin;
- GC gc;
- XSizeHints hints;
- XGCValues values;
- static XFontStruct *font_info = NULL;
- static Pixmap ico = 0;
- unsigned long valuemask = 0;
- static char dash_list[] = {20, 40};
- int list_length = sizeof(dash_list);
-
- Atom wm_protocols;
- Atom wm_delete_window;
-
- XEvent ev;
- long evmask = ExposureMask | KeyPressMask | ButtonPressMask
- | StructureNotifyMask;
- double waited = 0.0;
-
- /* strings and geometries y/n */
- KeyCode key_y, key_n, key_v;
- char strh[100];
- char stri[100];
- char str1_b[] = "To accept: press \"y\" or click the \"Yes\" button";
- char str2_b[] = "To reject: press \"n\" or click the \"No\" button";
- char str3_b[] = "View only: press \"v\" or click the \"View\" button";
- char str1_m[] = "To accept: click the \"Yes\" button";
- char str2_m[] = "To reject: click the \"No\" button";
- char str3_m[] = "View only: click the \"View\" button";
- char str1_k[] = "To accept: press \"y\"";
- char str2_k[] = "To reject: press \"n\"";
- char str3_k[] = "View only: press \"v\"";
- char *str1, *str2, *str3;
- char str_y[] = "Yes";
- char str_n[] = "No";
- char str_v[] = "View";
- int x, y, w = 345, h = 175, ret = 0;
- int X_sh = 20, Y_sh = 30, dY = 20;
- int Ye_x = 20, Ye_y = 0, Ye_w = 45, Ye_h = 20;
- int No_x = 75, No_y = 0, No_w = 45, No_h = 20;
- int Vi_x = 130, Vi_y = 0, Vi_w = 45, Vi_h = 20;
- char *sprop = "new x11vnc client";
-
- KeyCode key_o;
-
- RAWFB_RET(0)
-
- if (! accept) {
- sprintf(str_y, "OK");
- sprop = "x11vnc client disconnected";
- h = 110;
- str1 = "";
- str2 = "";
- str3 = "";
- } else if (!strcmp(mode, "mouse_only")) {
- str1 = str1_m;
- str2 = str2_m;
- str3 = str3_m;
- } else if (!strcmp(mode, "key_only")) {
- str1 = str1_k;
- str2 = str2_k;
- str3 = str3_k;
- h -= dY;
- } else {
- str1 = str1_b;
- str2 = str2_b;
- str3 = str3_b;
- }
- if (view_only) {
- h -= dY;
- }
-
- /* XXX handle coff_x/coff_y? */
- if (X < -dpy_x) {
- x = (dpy_x - w)/2; /* large negative: center */
- if (x < 0) x = 0;
- } else if (X < 0) {
- x = dpy_x + X - w; /* from lower right */
- } else {
- x = X; /* from upper left */
- }
-
- if (Y < -dpy_y) {
- y = (dpy_y - h)/2;
- if (y < 0) y = 0;
- } else if (Y < 0) {
- y = dpy_y + Y - h;
- } else {
- y = Y;
- }
-
- X_LOCK;
-
- awin = XCreateSimpleWindow(dpy, window, x, y, w, h, 4,
- BlackPixel(dpy, scr), WhitePixel(dpy, scr));
-
- wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
- wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- XSetWMProtocols(dpy, awin, &wm_delete_window, 1);
-
- if (! ico) {
- ico = XCreateBitmapFromData(dpy, awin, (char *) t2x2_bits,
- t2x2_width, t2x2_height);
- }
-
- hints.flags = PPosition | PSize | PMinSize;
- hints.x = x;
- hints.y = y;
- hints.width = w;
- hints.height = h;
- hints.min_width = w;
- hints.min_height = h;
-
- XSetStandardProperties(dpy, awin, sprop, "x11vnc query", ico, NULL,
- 0, &hints);
-
- XSelectInput_wr(dpy, awin, evmask);
-
- if (! font_info && (font_info = XLoadQueryFont(dpy, "fixed")) == NULL) {
- rfbLogEnable(1);
- rfbLog("ugly_window: cannot locate font fixed.\n");
- X_UNLOCK;
- clean_up_exit(1);
- }
-
- gc = XCreateGC(dpy, awin, valuemask, &values);
- XSetFont(dpy, gc, font_info->fid);
- XSetForeground(dpy, gc, BlackPixel(dpy, scr));
- XSetLineAttributes(dpy, gc, 1, LineSolid, CapButt, JoinMiter);
- XSetDashes(dpy, gc, 0, dash_list, list_length);
-
- XMapWindow(dpy, awin);
- XFlush_wr(dpy);
-
- if (accept) {
- char *ip = addr;
- char *type = "accept";
- if (unixpw && strstr(userhost, "UNIX:") != userhost) {
- type = "UNIXPW";
- if (openssl_last_ip) {
- ip = openssl_last_ip;
- }
- }
- snprintf(strh, 100, "x11vnc: %s connection from %s?", type, ip);
- } else {
- snprintf(strh, 100, "x11vnc: client disconnected from %s", addr);
- }
- snprintf(stri, 100, " (%s)", userhost);
-
- key_o = XKeysymToKeycode(dpy, XStringToKeysym("o"));
- key_y = XKeysymToKeycode(dpy, XStringToKeysym("y"));
- key_n = XKeysymToKeycode(dpy, XStringToKeysym("n"));
- key_v = XKeysymToKeycode(dpy, XStringToKeysym("v"));
-
- while (1) {
- int out = -1, x, y, tw, k;
-
- if (XCheckWindowEvent(dpy, awin, evmask, &ev)) {
- ; /* proceed to handling */
- } else if (XCheckTypedEvent(dpy, ClientMessage, &ev)) {
- ; /* proceed to handling */
- } else {
- int ms = 100; /* sleep a bit */
- usleep(ms * 1000);
- waited += ((double) ms)/1000.;
- if (timeout && (int) waited >= timeout) {
- rfbLog("ugly_window: popup timed out after "
- "%d seconds.\n", timeout);
- out = 0;
- ev.type = 0;
- } else {
- continue;
- }
- }
-
- switch(ev.type) {
- case Expose:
- while (XCheckTypedEvent(dpy, Expose, &ev)) {
- ;
- }
- k=0;
-
- /* instructions */
- XDrawString(dpy, awin, gc, X_sh, Y_sh+(k++)*dY,
- strh, strlen(strh));
- XDrawString(dpy, awin, gc, X_sh, Y_sh+(k++)*dY,
- stri, strlen(stri));
- if (accept) {
- XDrawString(dpy, awin, gc, X_sh, Y_sh+(k++)*dY,
- str1, strlen(str1));
- XDrawString(dpy, awin, gc, X_sh, Y_sh+(k++)*dY,
- str2, strlen(str2));
- if (! view_only) {
- XDrawString(dpy, awin, gc, X_sh, Y_sh+(k++)*dY,
- str3, strlen(str3));
- }
- }
-
- if (!strcmp(mode, "key_only")) {
- break;
- }
-
- /* buttons */
- Ye_y = Y_sh+k*dY;
- No_y = Y_sh+k*dY;
- Vi_y = Y_sh+k*dY;
- XDrawRectangle(dpy, awin, gc, Ye_x, Ye_y, Ye_w, Ye_h);
-
- if (accept) {
- XDrawRectangle(dpy, awin, gc, No_x, No_y, No_w, No_h);
- if (! view_only) {
- XDrawRectangle(dpy, awin, gc, Vi_x, Vi_y,
- Vi_w, Vi_h);
- }
- }
-
- tw = XTextWidth(font_info, str_y, strlen(str_y));
- tw = (Ye_w - tw)/2;
- if (tw < 0) tw = 1;
- XDrawString(dpy, awin, gc, Ye_x+tw, Ye_y+Ye_h-5,
- str_y, strlen(str_y));
-
- if (!accept) {
- break;
- }
- tw = XTextWidth(font_info, str_n, strlen(str_n));
- tw = (No_w - tw)/2;
- if (tw < 0) tw = 1;
- XDrawString(dpy, awin, gc, No_x+tw, No_y+No_h-5,
- str_n, strlen(str_n));
-
- if (! view_only) {
- tw = XTextWidth(font_info, str_v,
- strlen(str_v));
- tw = (Vi_w - tw)/2;
- if (tw < 0) tw = 1;
- XDrawString(dpy, awin, gc, Vi_x+tw,
- Vi_y+Vi_h-5, str_v, strlen(str_v));
- }
-
- break;
-
- case ClientMessage:
- if (ev.xclient.message_type == wm_protocols &&
- (Atom) ev.xclient.data.l[0] == wm_delete_window) {
- out = 0;
- }
- break;
-
- case ButtonPress:
- x = ev.xbutton.x;
- y = ev.xbutton.y;
- if (!strcmp(mode, "key_only")) {
- ;
- } else if (x > Ye_x && x < Ye_x+Ye_w && y > Ye_y
- && y < Ye_y+Ye_h) {
- out = 1;
- } else if (! accept) {
- ;
- } else if (x > No_x && x < No_x+No_w && y > No_y
- && y < No_y+No_h) {
- out = 0;
- } else if (! view_only && x > Vi_x && x < Vi_x+Vi_w
- && y > Vi_y && y < Vi_y+Ye_h) {
- out = 2;
- }
- break;
-
- case KeyPress:
- if (!strcmp(mode, "mouse_only")) {
- ;
- } else if (! accept) {
- if (ev.xkey.keycode == key_o) {
- out = 1;
- }
- if (ev.xkey.keycode == key_y) {
- out = 1;
- }
- } else if (ev.xkey.keycode == key_y) {
- out = 1;
- ;
- } else if (ev.xkey.keycode == key_n) {
- out = 0;
- } else if (! view_only && ev.xkey.keycode == key_v) {
- out = 2;
- }
- break;
- default:
- break;
- }
- if (out != -1) {
- ret = out;
- XSelectInput_wr(dpy, awin, 0);
- XUnmapWindow(dpy, awin);
- XFree_wr(gc);
- XDestroyWindow(dpy, awin);
- XFlush_wr(dpy);
- break;
- }
- }
- X_UNLOCK;
-
- return ret;
-#endif /* NO_X11 */
-}
-
-/*
- * process a "yes:0,no:*,view:3" type action list comparing to command
- * return code rc. * means the default action with no other match.
- */
-static int action_match(char *action, int rc) {
- char *p, *q, *s = strdup(action);
- int cases[4], i, result;
- char *labels[4];
-
- labels[1] = "yes";
- labels[2] = "no";
- labels[3] = "view";
-
- rfbLog("accept_client: process action line: %s\n",
- action);
-
- for (i=1; i <= 3; i++) {
- cases[i] = -2;
- }
-
- p = strtok(s, ",");
- while (p) {
- if ((q = strchr(p, ':')) != NULL) {
- int in, k = 1;
- *q = '\0';
- q++;
- if (strstr(p, "yes") == p) {
- k = 1;
- } else if (strstr(p, "no") == p) {
- k = 2;
- } else if (strstr(p, "view") == p) {
- k = 3;
- } else {
- rfbLogEnable(1);
- rfbLog("invalid action line: %s\n", action);
- clean_up_exit(1);
- }
- if (*q == '*') {
- cases[k] = -1;
- } else if (sscanf(q, "%d", &in) == 1) {
- if (in < 0) {
- rfbLogEnable(1);
- rfbLog("invalid action line: %s\n",
- action);
- clean_up_exit(1);
- }
- cases[k] = in;
- } else {
- rfbLogEnable(1);
- rfbLog("invalid action line: %s\n", action);
- clean_up_exit(1);
- }
- } else {
- rfbLogEnable(1);
- rfbLog("invalid action line: %s\n", action);
- clean_up_exit(1);
- }
- p = strtok(NULL, ",");
- }
- free(s);
-
- result = -1;
- for (i=1; i <= 3; i++) {
- if (cases[i] == -1) {
- rfbLog("accept_client: default action is case=%d %s\n",
- i, labels[i]);
- result = i;
- break;
- }
- }
- if (result == -1) {
- rfbLog("accept_client: no default action\n");
- }
- for (i=1; i <= 3; i++) {
- if (cases[i] >= 0 && cases[i] == rc) {
- rfbLog("accept_client: matched action is case=%d %s\n",
- i, labels[i]);
- result = i;
- break;
- }
- }
- if (result < 0) {
- rfbLog("no action match: %s rc=%d set to no\n", action, rc);
- result = 2;
- }
- return result;
-}
-
-static void ugly_geom(char *p, int *x, int *y) {
- int x1, y1;
-
- if (sscanf(p, "+%d+%d", &x1, &y1) == 2) {
- *x = x1;
- *y = y1;
- } else if (sscanf(p, "+%d-%d", &x1, &y1) == 2) {
- *x = x1;
- *y = -y1;
- } else if (sscanf(p, "-%d+%d", &x1, &y1) == 2) {
- *x = -x1;
- *y = y1;
- } else if (sscanf(p, "-%d-%d", &x1, &y1) == 2) {
- *x = -x1;
- *y = -y1;
- }
-}
-
-/*
- * Simple routine to prompt the user on the X display whether an incoming
- * client should be allowed to connect or not. If a gui is involved it
- * will be running in the environment/context of the X11 DISPLAY.
- *
- * The command supplied via -accept is run as is (i.e. no string
- * substitution) with the RFB_CLIENT_IP environment variable set to the
- * incoming client's numerical IP address.
- *
- * If the external command exits with 0 the client is accepted, otherwise
- * the client is rejected.
- *
- * Some builtins are provided:
- *
- * xmessage: use homebrew xmessage(1) for the external command.
- * popup: use internal X widgets for prompting.
- *
- */
-int accept_client(rfbClientPtr client) {
-
- char xmessage[200], *cmd = NULL;
- char *addr = client->host;
- char *action = NULL;
-
- if (accept_cmd == NULL || *accept_cmd == '\0') {
- return 1; /* no command specified, so we accept */
- }
-
- if (addr == NULL || addr[0] == '\0') {
- addr = "unknown-host";
- }
-
- if (strstr(accept_cmd, "popup") == accept_cmd) {
- /* use our builtin popup button */
-
- /* (popup|popupkey|popupmouse)[+-X+-Y][:timeout] */
-
- int ret, timeout = 120;
- int x = -64000, y = -64000;
- char *p, *mode;
- char *userhost = ident_username(client);
-
- /* extract timeout */
- if ((p = strchr(accept_cmd, ':')) != NULL) {
- int in;
- if (sscanf(p+1, "%d", &in) == 1) {
- timeout = in;
- }
- }
- /* extract geometry */
- if ((p = strpbrk(accept_cmd, "+-")) != NULL) {
- ugly_geom(p, &x, &y);
- }
-
- /* find mode: mouse, key, or both */
- if (strstr(accept_cmd, "popupmouse") == accept_cmd) {
- mode = "mouse_only";
- } else if (strstr(accept_cmd, "popupkey") == accept_cmd) {
- mode = "key_only";
- } else {
- mode = "both";
- }
-
- if (dpy == NULL && use_dpy && strstr(use_dpy, "WAIT:") ==
- use_dpy) {
- rfbLog("accept_client: warning allowing client under conditions:\n");
- rfbLog(" -display WAIT:, dpy == NULL, -accept popup.\n");
- rfbLog(" There will be another popup.\n");
- return 1;
- }
-
- rfbLog("accept_client: using builtin popup for: %s\n", addr);
- if ((ret = ugly_window(addr, userhost, x, y, timeout,
- mode, 1))) {
- free(userhost);
- if (ret == 2) {
- rfbLog("accept_client: viewonly: %s\n", addr);
- client->viewOnly = TRUE;
- }
- rfbLog("accept_client: popup accepted: %s\n", addr);
- return 1;
- } else {
- free(userhost);
- rfbLog("accept_client: popup rejected: %s\n", addr);
- return 0;
- }
-
- } else if (!strcmp(accept_cmd, "xmessage")) {
- /* make our own command using xmessage(1) */
-
- if (view_only) {
- sprintf(xmessage, "xmessage -buttons yes:0,no:2 -center"
- " 'x11vnc: accept connection from %s?'", addr);
- } else {
- sprintf(xmessage, "xmessage -buttons yes:0,no:2,"
- "view-only:3 -center" " 'x11vnc: accept connection"
- " from %s?'", addr);
- action = "yes:0,no:*,view:3";
- }
- cmd = xmessage;
-
- } else {
- /* use the user supplied command: */
-
- cmd = accept_cmd;
-
- /* extract any action prefix: yes:N,no:M,view:K */
- if (strstr(accept_cmd, "yes:") == accept_cmd) {
- char *p;
- if ((p = strpbrk(accept_cmd, " \t")) != NULL) {
- int i;
- cmd = p;
- p = accept_cmd;
- for (i=0; i<200; i++) {
- if (*p == ' ' || *p == '\t') {
- xmessage[i] = '\0';
- break;
- }
- xmessage[i] = *p;
- p++;
- }
- xmessage[200-1] = '\0';
- action = xmessage;
- }
- }
- }
-
- if (cmd) {
- int rc;
-
- rfbLog("accept_client: using cmd for: %s\n", addr);
- rc = run_user_command(cmd, client, "accept", NULL, 0, NULL);
-
- if (action) {
- int result;
-
- if (rc < 0) {
- rfbLog("accept_client: cannot use negative "
- "rc: %d, action %s\n", rc, action);
- result = 2;
- } else {
- result = action_match(action, rc);
- }
-
- if (result == 1) {
- rc = 0;
- } else if (result == 2) {
- rc = 1;
- } else if (result == 3) {
- rc = 0;
- rfbLog("accept_client: viewonly: %s\n", addr);
- client->viewOnly = TRUE;
- } else {
- rc = 1; /* NOTREACHED */
- }
- }
-
- if (rc == 0) {
- rfbLog("accept_client: accepted: %s\n", addr);
- return 1;
- } else {
- rfbLog("accept_client: rejected: %s\n", addr);
- return 0;
- }
- } else {
- rfbLog("accept_client: no command, rejecting %s\n", addr);
- return 0;
- }
-
- /* return 0; NOTREACHED */
-}
-
-void check_ipv6_listen(long usec) {
-#if X11VNC_IPV6
- fd_set fds;
- struct timeval tv;
- int nfds, csock = -1, one = 1;
- struct sockaddr_in6 addr;
- socklen_t addrlen = sizeof(addr);
- rfbClientPtr cl;
- int nmax = 0;
- char *name;
-
- if (!ipv6_listen || noipv6) {
- return;
- }
- if (ipv6_listen_fd < 0 && ipv6_http_fd < 0) {
- return;
- }
-
- FD_ZERO(&fds);
- if (ipv6_listen_fd >= 0) {
- FD_SET(ipv6_listen_fd, &fds);
- nmax = ipv6_listen_fd;
- }
- if (ipv6_http_fd >= 0 && screen->httpSock < 0) {
- FD_SET(ipv6_http_fd, &fds);
- if (ipv6_http_fd > nmax) {
- nmax = ipv6_http_fd;
- }
- }
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- nfds = select(nmax+1, &fds, NULL, NULL, &tv);
-
- if (nfds <= 0) {
- return;
- }
-
- if (ipv6_listen_fd >= 0 && FD_ISSET(ipv6_listen_fd, &fds)) {
-
- csock = accept(ipv6_listen_fd, (struct sockaddr *)&addr, &addrlen);
- if (csock < 0) {
- rfbLogPerror("check_ipv6_listen: accept");
- goto err1;
- }
- if (fcntl(csock, F_SETFL, O_NONBLOCK) < 0) {
- rfbLogPerror("check_ipv6_listen: fcntl");
- close(csock);
- goto err1;
- }
- if (setsockopt(csock, IPPROTO_TCP, TCP_NODELAY,
- (char *)&one, sizeof(one)) < 0) {
- rfbLogPerror("check_ipv6_listen: setsockopt");
- close(csock);
- goto err1;
- }
-
- name = ipv6_getipaddr((struct sockaddr *) &addr, addrlen);
-
- ipv6_client_ip_str = name;
- cl = rfbNewClient(screen, csock);
- ipv6_client_ip_str = NULL;
- if (cl == NULL) {
- close(csock);
- goto err1;
- }
-
- if (name) {
- if (cl->host) {
- free(cl->host);
- }
- cl->host = name;
- rfbLog("ipv6 client: %s\n", name);
- }
- }
-
- err1:
-
- if (ipv6_http_fd >= 0 && FD_ISSET(ipv6_http_fd, &fds)) {
-
- csock = accept(ipv6_http_fd, (struct sockaddr *)&addr, &addrlen);
- if (csock < 0) {
- rfbLogPerror("check_ipv6_listen: accept");
- return;
- }
- if (fcntl(csock, F_SETFL, O_NONBLOCK) < 0) {
- rfbLogPerror("check_ipv6_listen: fcntl");
- close(csock);
- return;
- }
- if (setsockopt(csock, IPPROTO_TCP, TCP_NODELAY,
- (char *)&one, sizeof(one)) < 0) {
- rfbLogPerror("check_ipv6_listen: setsockopt");
- close(csock);
- return;
- }
-
- rfbLog("check_ipv6_listen: setting httpSock to %d\n", csock);
- screen->httpSock = csock;
-
- if (screen->httpListenSock < 0) {
- /* this may not always work... */
- int save = screen->httpListenSock;
- screen->httpListenSock = ipv6_http_fd;
- rfbLog("check_ipv6_listen: no httpListenSock, calling rfbHttpCheckFds()\n");
- rfbHttpCheckFds(screen);
- screen->httpListenSock = save;
- }
- }
-#endif
- if (usec) {}
-}
-
-void check_unix_sock(long usec) {
- fd_set fds;
- struct timeval tv;
- int nfds, csock = -1;
- rfbClientPtr cl;
- int nmax = 0;
- char *name;
-
- if (!unix_sock || unix_sock_fd < 0) {
- return;
- }
-
- FD_ZERO(&fds);
- if (unix_sock_fd >= 0) {
- FD_SET(unix_sock_fd, &fds);
- nmax = unix_sock_fd;
- }
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- nfds = select(nmax+1, &fds, NULL, NULL, &tv);
-
- if (nfds <= 0) {
- return;
- }
-
- if (unix_sock_fd >= 0 && FD_ISSET(unix_sock_fd, &fds)) {
- csock = accept_unix(unix_sock_fd);
- if (csock < 0) {
- return;
- }
- if (fcntl(csock, F_SETFL, O_NONBLOCK) < 0) {
- rfbLogPerror("check_unix_sock: fcntl");
- close(csock);
- return;
- }
-
- /* rfbNewClient() will screw us with setsockopt TCP_NODELAY...
- you need to comment out in libvncserver/rfbserver.c:
- rfbLogPerror("setsockopt failed");
- close(sock);
- return NULL;
- */
- cl = rfbNewClient(screen, csock);
-
- if (cl == NULL) {
- close(csock);
- return;
- }
-
- name = strdup(unix_sock);
-
- if (name) {
- if (cl->host) {
- free(cl->host);
- }
- cl->host = name;
- rfbLog("unix sock client: %s\n", name);
- }
- }
-}
-
-/*
- * For the -connect <file> option: periodically read the file looking for
- * a connect string. If one is found set client_connect to it.
- */
-static void check_connect_file(char *file) {
- FILE *in;
- char line[VNC_CONNECT_MAX], host[VNC_CONNECT_MAX];
- static int first_warn = 1, truncate_ok = 1;
- static double last_time = 0.0, delay = 0.5;
- double now = dnow();
- struct stat sbuf;
-
- if (last_time == 0.0) {
- if (!getenv("X11VNC_APPSHARE_ACTIVE")) {
- /* skip first */
- last_time = now;
- } else {
- delay = 0.25;
- }
- }
- if (now - last_time < delay) {
- /* check only about once a second */
- return;
- }
- last_time = now;
-
- if (! truncate_ok) {
- /* check if permissions changed */
- if (access(file, W_OK) == 0) {
- truncate_ok = 1;
- } else {
- return;
- }
- }
-
- if (stat(file, &sbuf) == 0) {
- /* skip empty file directly */
- if (sbuf.st_size == 0) {
- return;
- }
- }
-
- in = fopen(file, "r");
- if (in == NULL) {
- if (first_warn) {
- rfbLog("check_connect_file: fopen failure: %s\n", file);
- rfbLogPerror("fopen");
- first_warn = 0;
- }
- return;
- }
-
- if (fgets(line, VNC_CONNECT_MAX, in) != NULL) {
- if (sscanf(line, "%s", host) == 1) {
- if (strlen(host) > 0) {
- char *str = strdup(host);
- if (strlen(str) > 38) {
- char trim[100];
- trim[0] = '\0';
- strncat(trim, str, 38);
- rfbLog("read connect file: %s ...\n",
- trim);
- } else {
- rfbLog("read connect file: %s\n", str);
- }
- if (!strcmp(str, "cmd=stop") &&
- dnowx() < 3.0) {
- rfbLog("ignoring stale cmd=stop\n");
- } else {
- client_connect = str;
- }
- }
- }
- }
- fclose(in);
-
- /* truncate file */
- in = fopen(file, "w");
- if (in != NULL) {
- fclose(in);
- } else {
- /* disable if we cannot truncate */
- rfbLog("check_connect_file: could not truncate %s, "
- "disabling checking.\n", file);
- truncate_ok = 0;
- }
-}
-
-static int socks5_proxy(char *host, int port, int sock) {
- unsigned char buf[512], tmp[2];
- char reply[512];
- int len, n, i, j = 0;
-
- memset(buf, 0, 512);
- memset(reply, 0, 512);
-
- buf[0] = 0x5;
- buf[1] = 0x1;
- buf[2] = 0x0;
-
- write(sock, buf, 3);
-
- n = read(sock, buf, 2);
-
- if (n != 2) {
- rfbLog("socks5_proxy: read error: %d\n", n);
- close(sock);
- return 0;
- }
- if (buf[0] != 0x5 || buf[1] != 0x0) {
- rfbLog("socks5_proxy: handshake error: %d %d\n", (int) buf[0], (int) buf[1]);
- close(sock);
- return 0;
- }
-
- buf[0] = 0x5;
- buf[1] = 0x1;
- buf[2] = 0x0;
- buf[3] = 0x3;
-
- buf[4] = (unsigned char) strlen(host);
- strcat((char *) buf+5, host);
-
- len = 5 + strlen(host);
-
- buf[len] = (unsigned char) (port >> 8);
- buf[len+1] = (unsigned char) (port & 0xff);
-
- write(sock, buf, len+2);
-
- for (i=0; i<4; i++) {
- int n;
- n = read(sock, tmp, 1);
- j++;
- if (n < 0) {
- if (errno != EINTR) {
- break;
- } else {
- i--;
- if (j > 100) {
- break;
- }
- continue;
- }
- }
- if (n == 0) {
- break;
- }
- reply[i] = tmp[0];
- }
- if (reply[3] == 0x1) {
- read(sock, reply+4, 4 + 2);
- } else if (reply[3] == 0x3) {
- n = read(sock, tmp, 1);
- reply[4] = tmp[0];
- read(sock, reply+5, (int) reply[4] + 2);
- } else if (reply[3] == 0x4) {
- read(sock, reply+4, 16 + 2);
- }
-
- if (0) {
- int i;
- for (i=0; i<len+2; i++) {
- fprintf(stderr, "b[%d]: %d\n", i, (int) buf[i]);
- }
- for (i=0; i<len+2; i++) {
- fprintf(stderr, "r[%d]: %d\n", i, (int) reply[i]);
- }
- }
- if (reply[0] == 0x5 && reply[1] == 0x0 && reply[2] == 0x0) {
- rfbLog("SOCKS5 connect OK to %s:%d sock=%d\n", host, port, sock);
- return 1;
- } else {
- rfbLog("SOCKS5 error to %s:%d sock=%d\n", host, port, sock);
- close(sock);
- return 0;
- }
-}
-
-static int socks_proxy(char *host, int port, int sock) {
- unsigned char buf[512], tmp[2];
- char reply[16];
- int socks4a = 0, len, i, j = 0, d1, d2, d3, d4;
-
- memset(buf, 0, 512);
-
- buf[0] = 0x4;
- buf[1] = 0x1;
- buf[2] = (unsigned char) (port >> 8);
- buf[3] = (unsigned char) (port & 0xff);
-
-
- if (strlen(host) > 256) {
- rfbLog("socks_proxy: hostname too long: %s\n", host);
- close(sock);
- return 0;
- }
-
- if (!strcmp(host, "localhost") || !strcmp(host, "127.0.0.1")) {
- buf[4] = 127;
- buf[5] = 0;
- buf[6] = 0;
- buf[7] = 1;
- } else if (sscanf(host, "%d.%d.%d.%d", &d1, &d2, &d3, &d4) == 4) {
- buf[4] = (unsigned char) d1;
- buf[5] = (unsigned char) d2;
- buf[6] = (unsigned char) d3;
- buf[7] = (unsigned char) d4;
- } else {
- buf[4] = 0x0;
- buf[5] = 0x0;
- buf[6] = 0x0;
- buf[7] = 0x3;
- socks4a = 1;
- }
- len = 8;
-
- strcat((char *)buf+8, "nobody");
- len += strlen("nobody") + 1;
-
- if (socks4a) {
- strcat((char *) buf+8+strlen("nobody") + 1, host);
- len += strlen(host) + 1;
- }
-
- write(sock, buf, len);
-
- for (i=0; i<8; i++) {
- int n;
- n = read(sock, tmp, 1);
- j++;
- if (n < 0) {
- if (errno != EINTR) {
- break;
- } else {
- i--;
- if (j > 100) {
- break;
- }
- continue;
- }
- }
- if (n == 0) {
- break;
- }
- reply[i] = tmp[0];
- }
- if (0) {
- int i;
- for (i=0; i<len; i++) {
- fprintf(stderr, "b[%d]: %d\n", i, (int) buf[i]);
- }
- for (i=0; i<8; i++) {
- fprintf(stderr, "r[%d]: %d\n", i, (int) reply[i]);
- }
- }
- if (reply[0] == 0x0 && reply[1] == 0x5a) {
- if (socks4a) {
- rfbLog("SOCKS4a connect OK to %s:%d sock=%d\n", host, port, sock);
- } else {
- rfbLog("SOCKS4 connect OK to %s:%d sock=%d\n", host, port, sock);
- }
- return 1;
- } else {
- if (socks4a) {
- rfbLog("SOCKS4a error to %s:%d sock=%d\n", host, port, sock);
- } else {
- rfbLog("SOCKS4 error to %s:%d sock=%d\n", host, port, sock);
- }
- close(sock);
- return 0;
- }
-}
-
-#define PXY_HTTP 1
-#define PXY_GET 2
-#define PXY_SOCKS 3
-#define PXY_SOCKS5 4
-#define PXY_SSH 5
-#define PXY 3
-
-static int pxy_get_sock;
-
-static int pconnect(int psock, char *host, int port, int type, char *http_path, char *gethost, int getport) {
- char reply[4096];
- int i, ok, len;
- char *req;
-
- pxy_get_sock = -1;
-
- if (type == PXY_SOCKS) {
- return socks_proxy(host, port, psock);
- }
- if (type == PXY_SOCKS5) {
- return socks5_proxy(host, port, psock);
- }
- if (type == PXY_SSH) {
- return 1;
- }
-
- len = strlen("CONNECT ") + strlen(host);
- if (type == PXY_GET) {
- len += strlen(http_path) + strlen(gethost);
- len += strlen("host=") + 1 + strlen("port=") + 1 + 1;
- }
- len += 1 + 20 + strlen("HTTP/1.1\r\n") + 1;
-
- req = (char *)malloc(len);
-
- if (type == PXY_GET) {
- int noquery = 0;
- char *t = strstr(http_path, "__END__");
- if (t) {
- noquery = 1;
- *t = '\0';
- }
-
- if (noquery) {
- sprintf(req, "GET %s HTTP/1.1\r\n", http_path);
- } else {
- sprintf(req, "GET %shost=%s&port=%d HTTP/1.1\r\n", http_path, host, port);
- }
- } else {
- sprintf(req, "CONNECT %s:%d HTTP/1.1\r\n", host, port);
- }
- rfbLog("http proxy: %s", req);
- write(psock, req, strlen(req));
-
- if (type == PXY_GET) {
- char *t = "Connection: close\r\n";
- write(psock, t, strlen(t));
- }
-
- if (type == PXY_GET) {
- sprintf(req, "Host: %s:%d\r\n", gethost, getport);
- rfbLog("http proxy: %s", req);
- sprintf(req, "Host: %s:%d\r\n\r\n", gethost, getport);
- } else {
- sprintf(req, "Host: %s:%d\r\n", host, port);
- rfbLog("http proxy: %s", req);
- sprintf(req, "Host: %s:%d\r\n\r\n", host, port);
- }
-
- write(psock, req, strlen(req));
-
- ok = 0;
- reply[0] = '\0';
-
- for (i=0; i<4096; i++) {
- int n;
- req[0] = req[1] = '\0';
- n = read(psock, req, 1);
- if (n < 0) {
- if (errno != EINTR) {
- break;
- } else {
- continue;
- }
- }
- if (n == 0) {
- break;
- }
- strcat(reply, req);
- if (strstr(reply, "\r\n\r\n")) {
- if (strstr(reply, "HTTP/") == reply) {
- char *q = strchr(reply, ' ');
- if (q) {
- q++;
- if (q[0] == '2' && q[1] == '0' && q[2] == '0' && q[3] == ' ') {
- ok = 1;
- }
- }
- }
- break;
- }
- }
-
- if (type == PXY_GET) {
- char *t1 = strstr(reply, "VNC-IP-Port: ");
- char *t2 = strstr(reply, "VNC-Host-Port: ");
- char *s, *newhost = NULL;
- int newport = 0;
- fprintf(stderr, "%s\n", reply);
- if (t1) {
- t1 += strlen("VNC-IP-Port: ");
- s = strstr(t1, ":");
- if (s) {
- *s = '\0';
- newhost = strdup(t1);
- newport = atoi(s+1);
- }
- } else if (t2) {
- t2 += strlen("VNC-Host-Port: ");
- s = strstr(t2, ":");
- if (s) {
- *s = '\0';
- newhost = strdup(t2);
- newport = atoi(s+1);
- }
- }
- if (newhost && newport > 0) {
- rfbLog("proxy GET reconnect to: %s:%d\n", newhost, newport);
- pxy_get_sock = connect_tcp(newhost, newport);
- }
- }
- free(req);
-
- return ok;
-}
-
-static int proxy_connect(char *host, int port) {
- char *p, *q, *str;
- int i, n, pxy[PXY],pxy_p[PXY];
- int psock = -1;
- char *pxy_h[PXY], *pxy_g[PXY];
-
- if (! connect_proxy) {
- return -1;
- }
- str = strdup(connect_proxy);
-
- for (i=0; i<PXY; i++) {
- pxy[i] = 0;
- pxy_p[i] = 0;
- pxy_h[i] = NULL;
- pxy_g[i] = NULL;
- }
-
- n = 0;
- p = str;
- while (p) {
- char *hp, *c, *s = NULL;
-
- q = strchr(p, ',');
- if (q) {
- *q = '\0';
- }
-
- if (n==0) fprintf(stderr, "\n");
- rfbLog("proxy_connect[%d]: %s\n", n+1, p);
-
- pxy[n] = 0;
- pxy_p[n] = 0;
- pxy_h[n] = NULL;
- pxy_g[n] = NULL;
-
- if (strstr(p, "socks://") == p) {
- hp = strstr(p, "://") + 3;
- pxy[n] = PXY_SOCKS;
- } else if (strstr(p, "socks4://") == p) {
- hp = strstr(p, "://") + 3;
- pxy[n] = PXY_SOCKS;
- } else if (strstr(p, "socks5://") == p) {
- hp = strstr(p, "://") + 3;
- pxy[n] = PXY_SOCKS5;
- } else if (strstr(p, "ssh://") == p) {
- if (n != 0) {
- rfbLog("ssh:// proxy must be the first one\n");
- clean_up_exit(1);
- }
- hp = strstr(p, "://") + 3;
- pxy[n] = PXY_SSH;
- } else if (strstr(p, "http://") == p) {
- hp = strstr(p, "://") + 3;
- pxy[n] = PXY_HTTP;
- } else if (strstr(p, "https://") == p) {
- hp = strstr(p, "://") + 3;
- pxy[n] = PXY_HTTP;
- } else {
- hp = p;
- pxy[n] = PXY_HTTP;
- }
- c = strstr(hp, ":");
- if (!c && pxy[n] == PXY_SSH) {
- char *hp2 = (char *) malloc(strlen(hp) + 5);
- sprintf(hp2, "%s:1", hp);
- hp = hp2;
- c = strstr(hp, ":");
- }
- if (!c) {
- pxy[n] = 0;
- if (q) {
- *q = ',';
- p = q + 1;
- } else {
- p = NULL;
- }
- continue;
- }
-
- if (pxy[n] == PXY_HTTP) {
- s = strstr(c, "/");
- if (s) {
- pxy[n] = PXY_GET;
- pxy_g[n] = strdup(s);
- *s = '\0';
- }
- }
- pxy_p[n] = atoi(c+1);
-
- if (pxy_p[n] <= 0) {
- pxy[n] = 0;
- pxy_p[n] = 0;
- if (q) {
- *q = ',';
- p = q + 1;
- } else {
- p = NULL;
- }
- continue;
- }
- *c = '\0';
- pxy_h[n] = strdup(hp);
-
- if (++n >= PXY) {
- break;
- }
-
- if (q) {
- *q = ',';
- p = q + 1;
- } else {
- p = NULL;
- }
- }
- free(str);
-
- if (!n) {
- psock = -1;
- goto pxy_clean;
- }
-
- if (pxy[0] == PXY_SSH) {
- int rc, len = 0;
- char *cmd, *ssh;
- int sport = find_free_port(7300, 8000);
- if (getenv("SSH")) {
- ssh = getenv("SSH");
- } else {
- ssh = "ssh";
- }
- len = 200 + strlen(ssh) + strlen(pxy_h[0]) + strlen(host);
- cmd = (char *) malloc(len);
- if (n == 1) {
- if (pxy_p[0] <= 1) {
- sprintf(cmd, "%s -f -L '%d:%s:%d' '%s' 'sleep 20'", ssh, sport, host, port, pxy_h[0]);
- } else {
- sprintf(cmd, "%s -f -p %d -L '%d:%s:%d' '%s' 'sleep 20'", ssh, pxy_p[0], sport, host, port, pxy_h[0]);
- }
- } else {
- if (pxy_p[0] <= 1) {
- sprintf(cmd, "%s -f -L '%d:%s:%d' '%s' 'sleep 20'", ssh, sport, pxy_h[1], pxy_p[1], pxy_h[0]);
- } else {
- sprintf(cmd, "%s -f -p %d -L '%d:%s:%d' '%s' 'sleep 20'", ssh, pxy_p[0], sport, pxy_h[1], pxy_p[1], pxy_h[0]);
- }
- }
- if (no_external_cmds || !cmd_ok("ssh")) {
- rfbLogEnable(1);
- rfbLog("cannot run external commands in -nocmds mode:\n");
- rfbLog(" \"%s\"\n", cmd);
- rfbLog(" exiting.\n");
- clean_up_exit(1);
- }
- close_exec_fds();
- fprintf(stderr, "\n");
- rfbLog("running: %s\n", cmd);
- rc = system(cmd);
- free(cmd);
- if (rc != 0) {
- psock = -1;
- goto pxy_clean;
- }
- psock = connect_tcp("localhost", sport);
-
- } else {
- psock = connect_tcp(pxy_h[0], pxy_p[0]);
- }
-
- if (psock < 0) {
- psock = -1;
- goto pxy_clean;
- }
- rfbLog("opened socket to proxy: %s:%d\n", pxy_h[0], pxy_p[0]);
-
- if (n >= 2) {
- if (! pconnect(psock, pxy_h[1], pxy_p[1], pxy[0], pxy_g[0], pxy_h[0], pxy_p[0])) {
- close(psock); psock = -1; goto pxy_clean;
- }
- if (pxy_get_sock >= 0) {close(psock); psock = pxy_get_sock;}
-
- if (n >= 3) {
- if (! pconnect(psock, pxy_h[2], pxy_p[2], pxy[1], pxy_g[1], pxy_h[1], pxy_p[1])) {
- close(psock); psock = -1; goto pxy_clean;
- }
- if (pxy_get_sock >= 0) {close(psock); psock = pxy_get_sock;}
- if (! pconnect(psock, host, port, pxy[2], pxy_g[2], pxy_h[2], pxy_p[2])) {
- close(psock); psock = -1; goto pxy_clean;
- }
- if (pxy_get_sock >= 0) {close(psock); psock = pxy_get_sock;}
-
- } else {
- if (! pconnect(psock, host, port, pxy[1], pxy_g[1], pxy_h[1], pxy_p[1])) {
- close(psock); psock = -1; goto pxy_clean;
- }
- if (pxy_get_sock >= 0) {close(psock); psock = pxy_get_sock;}
- }
- } else {
- if (! pconnect(psock, host, port, pxy[0], pxy_g[0], pxy_h[0], pxy_p[0])) {
- close(psock); psock = -1; goto pxy_clean;
- }
- if (pxy_get_sock >= 0) {close(psock); psock = pxy_get_sock;}
- }
-
- pxy_clean:
- for (i=0; i < PXY; i++) {
- if (pxy_h[i] != NULL) {
- free(pxy_h[i]);
- }
- if (pxy_g[i] != NULL) {
- free(pxy_g[i]);
- }
- }
-
- return psock;
-}
-
-char *get_repeater_string(char *str, int *len) {
- int pren, which = 0;
- int prestring_len = 0;
- char *prestring = NULL, *ptmp = NULL;
- char *equals = strchr(str, '=');
- char *plus = strrchr(str, '+');
-
- *len = 0;
- if (!plus || !equals) {
- return NULL;
- }
-
- *plus = '\0';
- if (strstr(str, "repeater=") == str) {
- /* ultravnc repeater http://www.uvnc.com/addons/repeater.html */
- prestring_len = 250;
- ptmp = (char *) calloc(prestring_len+1, 1);
- snprintf(ptmp, 250, "%s", str + strlen("repeater="));
- which = 1;
- } else if (strstr(str, "pre=") == str) {
- prestring_len = strlen(str + strlen("pre="));
- ptmp = (char *) calloc(prestring_len+1, 1);
- snprintf(ptmp, prestring_len+1, "%s", str + strlen("pre="));
- which = 2;
- } else if (sscanf(str, "pre%d=", &pren) == 1) {
- if (pren > 0 && pren <= 16384) {
- prestring_len = pren;
- ptmp = (char *) calloc(prestring_len+1, 1);
- snprintf(prestring, prestring_len, "%s", equals+1);
- which = 3;
- }
- }
- if (ptmp != NULL) {
- int i, k = 0;
- char *p = ptmp;
- prestring = (char *)calloc(prestring_len+1, 1);
- /* translate \n to newline, etc. */
- for (i=0; i < prestring_len; i++) {
- if (i < prestring_len-1 && *(p+i) == '\\') {
- if (*(p+i+1) == 'r') {
- prestring[k++] = '\r'; i++;
- } else if (*(p+i+1) == 'n') {
- prestring[k++] = '\n'; i++;
- } else if (*(p+i+1) == 't') {
- prestring[k++] = '\t'; i++;
- } else if (*(p+i+1) == 'a') {
- prestring[k++] = '\a'; i++;
- } else if (*(p+i+1) == 'b') {
- prestring[k++] = '\b'; i++;
- } else if (*(p+i+1) == 'v') {
- prestring[k++] = '\v'; i++;
- } else if (*(p+i+1) == 'f') {
- prestring[k++] = '\f'; i++;
- } else if (*(p+i+1) == '\\') {
- prestring[k++] = '\\'; i++;
- } else if (*(p+i+1) == 'c') {
- prestring[k++] = ','; i++;
- } else {
- prestring[k++] = *(p+i);
- }
- } else {
- prestring[k++] = *(p+i);
- }
- }
- if (which == 2) {
- prestring_len = k;
- }
- if (!quiet) {
- rfbLog("-connect prestring: '%s'\n", prestring);
- }
- free(ptmp);
- }
- *plus = '+';
-
- *len = prestring_len;
- return prestring;
-}
-
-#ifndef USE_TIMEOUT_INTERRUPT
-#define USE_TIMEOUT_INTERRUPT 0
-#endif
-
-static void reverse_connect_timeout (int sig) {
- rfbLog("sig: %d, reverse_connect_timeout.\n", sig);
-#if USE_TIMEOUT_INTERRUPT
- rfbLog("reverse_connect_timeout proceeding assuming connect(2) interrupt.\n");
-#else
- clean_up_exit(0);
-#endif
-}
-
-
-/*
- * Do a reverse connect for a single "host" or "host:port"
- */
-
-static int do_reverse_connect(char *str_in) {
- rfbClientPtr cl;
- char *host, *p, *str = str_in, *s = NULL;
- char *prestring = NULL;
- int prestring_len = 0;
- int rport = 5500, len = strlen(str);
- int set_alarm = 0;
-
- if (len < 1) {
- return 0;
- }
- if (len > 1024) {
- rfbLog("reverse_connect: string too long: %d bytes\n", len);
- return 0;
- }
- if (!screen) {
- rfbLog("reverse_connect: screen not setup yet.\n");
- return 0;
- }
- if (unixpw_in_progress) return 0;
-
- /* look for repeater pre-string */
- if (strchr(str, '=') && strrchr(str, '+')
- && (strstr(str, "pre") == str || strstr(str, "repeater=") == str)) {
- prestring = get_repeater_string(str, &prestring_len);
- str = strrchr(str, '+') + 1;
- } else if (strrchr(str, '+') && strstr(str, "repeater://") == str) {
- /* repeater://host:port+string */
- /* repeater=string+host:port */
- char *plus = strrchr(str, '+');
- str = (char *) malloc(strlen(str_in)+1);
- s = str;
- *plus = '\0';
- sprintf(str, "repeater=%s+%s", plus+1, str_in + strlen("repeater://"));
- prestring = get_repeater_string(str, &prestring_len);
- str = strrchr(str, '+') + 1;
- *plus = '+';
- }
-
- /* copy in to host */
- host = (char *) malloc(len+1);
- if (! host) {
- rfbLog("reverse_connect: could not malloc string %d\n", len);
- return 0;
- }
- strncpy(host, str, len);
- host[len] = '\0';
-
- /* extract port, if any */
- if ((p = strrchr(host, ':')) != NULL) {
- rport = atoi(p+1);
- if (rport < 0) {
- rport = -rport;
- } else if (rport < 20) {
- rport = 5500 + rport;
- }
- *p = '\0';
- }
-
- if (ipv6_client_ip_str) {
- free(ipv6_client_ip_str);
- ipv6_client_ip_str = NULL;
- }
-
- if (use_openssl) {
- int vncsock;
- if (connect_proxy) {
- vncsock = proxy_connect(host, rport);
- } else {
- vncsock = connect_tcp(host, rport);
- }
- if (vncsock < 0) {
- rfbLog("reverse_connect: failed to connect to: %s\n", str);
- return 0;
- }
- if (prestring != NULL) {
- write(vncsock, prestring, prestring_len);
- free(prestring);
- }
-/* XXX use header */
-#define OPENSSL_REVERSE 6
- if (!getenv("X11VNC_DISABLE_SSL_CLIENT_MODE")) {
- openssl_init(1);
- }
-
- if (first_conn_timeout > 0) {
- set_alarm = 1;
- signal(SIGALRM, reverse_connect_timeout);
-#if USE_TIMEOUT_INTERRUPT
- siginterrupt(SIGALRM, 1);
-#endif
- rfbLog("reverse_connect: using alarm() timeout of %d seconds.\n", first_conn_timeout);
- alarm(first_conn_timeout);
- }
- accept_openssl(OPENSSL_REVERSE, vncsock);
- if (set_alarm) {alarm(0); signal(SIGALRM, SIG_DFL);}
-
- openssl_init(0);
- free(host);
- return 1;
- }
-
- if (use_stunnel) {
- if(strcmp(host, "localhost") && strcmp(host, "127.0.0.1")) {
- if (!getenv("STUNNEL_DISABLE_LOCALHOST")) {
- rfbLog("reverse_connect: error host not localhost in -stunnel mode.\n");
- return 0;
- }
- }
- }
-
- if (unixpw) {
- int is_localhost = 0, user_disabled_it = 0;
-
- if(!strcmp(host, "localhost") || !strcmp(host, "127.0.0.1")) {
- is_localhost = 1;
- }
- if (getenv("UNIXPW_DISABLE_LOCALHOST")) {
- user_disabled_it = 1;
- }
-
- if (! is_localhost) {
- if (user_disabled_it) {
- rfbLog("reverse_connect: warning disabling localhost constraint in -unixpw\n");
- } else {
- rfbLog("reverse_connect: error not localhost in -unixpw\n");
- return 0;
- }
- }
- }
-
- if (first_conn_timeout > 0) {
- set_alarm = 1;
- signal(SIGALRM, reverse_connect_timeout);
-#if USE_TIMEOUT_INTERRUPT
- siginterrupt(SIGALRM, 1);
-#endif
- rfbLog("reverse_connect: using alarm() timeout of %d seconds.\n", first_conn_timeout);
- alarm(first_conn_timeout);
- }
-
- if (connect_proxy != NULL) {
- int sock = proxy_connect(host, rport);
- if (set_alarm) {alarm(0); signal(SIGALRM, SIG_DFL);}
- if (sock >= 0) {
- if (prestring != NULL) {
- write(sock, prestring, prestring_len);
- free(prestring);
- }
- cl = create_new_client(sock, 1);
- } else {
- return 0;
- }
- } else if (prestring != NULL) {
- int sock = connect_tcp(host, rport);
- if (set_alarm) {alarm(0); signal(SIGALRM, SIG_DFL);}
- if (sock >= 0) {
- write(sock, prestring, prestring_len);
- free(prestring);
- cl = create_new_client(sock, 1);
- } else {
- return 0;
- }
- } else {
- cl = rfbReverseConnection(screen, host, rport);
- if (cl == NULL) {
- int sock = connect_tcp(host, rport);
- if (sock >= 0) {
- cl = create_new_client(sock, 1);
- }
- }
- if (set_alarm) {alarm(0); signal(SIGALRM, SIG_DFL);}
- if (cl != NULL && use_threads) {
- cl->onHold = FALSE;
- rfbStartOnHoldClient(cl);
- }
- }
-
- free(host);
-
- if (ipv6_client_ip_str) {
- free(ipv6_client_ip_str);
- ipv6_client_ip_str = NULL;
- }
-
-
- if (cl == NULL) {
- if (quiet && connect_or_exit) {
- rfbLogEnable(1);
- }
- rfbLog("reverse_connect: %s failed\n", str);
- return 0;
- } else {
- rfbLog("reverse_connect: %s/%s OK\n", str, cl->host);
- /* let's see if anyone complains: */
- if (! getenv("X11VNC_REVERSE_CONNECTION_NO_AUTH")) {
- rfbLog("reverse_connect: turning on auth for %s\n",
- cl->host);
- cl->reverseConnection = FALSE;
- }
- return 1;
- }
-}
-
-/*
- * Break up comma separated list of hosts and call do_reverse_connect()
- */
-void reverse_connect(char *str) {
- char *p, *tmp;
- int sleep_between_host = 300;
- int sleep_min = 1500, sleep_max = 4500, n_max = 5;
- int n, tot, t, dt = 100, cnt = 0;
- int nclients0 = client_count;
- int lcnt, j;
- char **list;
- int do_appshare = 0;
-
- if (!getenv("X11VNC_REVERSE_USE_OLD_SLEEP")) {
- sleep_min = 500;
- sleep_max = 2500;
- }
-
- if (unixpw_in_progress) return;
-
- tmp = strdup(str);
-
- list = (char **) calloc( (strlen(tmp)+2) * sizeof (char *), 1);
- lcnt = 0;
-
- p = strtok(tmp, ", \t\r\n");
- while (p) {
- list[lcnt++] = strdup(p);
- p = strtok(NULL, ", \t\r\n");
- }
- free(tmp);
-
- if (subwin && getenv("X11VNC_APPSHARE_ACTIVE")) {
- do_appshare = 1;
- sleep_between_host = 0; /* too agressive??? */
- }
- if (getenv("X11VNC_REVERSE_SLEEP_BETWEEN_HOST")) {
- sleep_between_host = atoi(getenv("X11VNC_REVERSE_SLEEP_BETWEEN_HOST"));
- }
-
- if (do_appshare) {
- if (screen && dpy) {
- char *s = choose_title(DisplayString(dpy));
-
- /* mutex */
- screen->desktopName = s;
- if (rfb_desktop_name) {
- free(rfb_desktop_name);
- }
- rfb_desktop_name = strdup(s);
- }
- }
-
- for (j = 0; j < lcnt; j++) {
- p = list[j];
-
- if ((n = do_reverse_connect(p)) != 0) {
- int i;
- progress_client();
- for (i=0; i < 3; i++) {
- rfbPE(-1);
- }
- }
- cnt += n;
- if (list[j+1] != NULL) {
- t = 0;
- while (t < sleep_between_host) {
- double t1, t2;
- int i;
- t1 = dnow();
- for (i=0; i < 8; i++) {
- rfbPE(-1);
- if (do_appshare && t == 0) {
- rfbPE(-1);
- }
- }
- t2 = dnow();
- t += (int) (1000 * (t2 - t1));
- if (t >= sleep_between_host) {
- break;
- }
- usleep(dt * 1000);
- t += dt;
- }
- }
- }
-
- for (j = 0; j < lcnt; j++) {
- p = list[j];
- if (p) free(p);
- }
- free(list);
-
- if (cnt == 0) {
- if (connect_or_exit) {
- rfbLogEnable(1);
- rfbLog("exiting under -connect_or_exit\n");
- if (gui_pid > 0) {
- rfbLog("killing gui_pid %d\n", gui_pid);
- kill(gui_pid, SIGTERM);
- }
- clean_up_exit(1);
- }
- if (xrandr || xrandr_maybe) {
- check_xrandr_event("reverse_connect1");
- }
- return;
- }
-
- /*
- * XXX: we need to process some of the initial handshaking
- * events, otherwise the client can get messed up (why??)
- * so we send rfbProcessEvents() all over the place.
- *
- * How much is this still needed?
- */
-
- n = cnt;
- if (n >= n_max) {
- n = n_max;
- }
- t = sleep_max - sleep_min;
- tot = sleep_min + ((n-1) * t) / (n_max-1);
-
- if (do_appshare) {
- tot /= 3;
- if (tot < dt) {
- tot = dt;
- }
- tot = 0; /* too agressive??? */
- }
-
- if (getenv("X11VNC_REVERSE_SLEEP_MAX")) {
- tot = atoi(getenv("X11VNC_REVERSE_SLEEP_MAX"));
- }
-
- t = 0;
- while (t < tot) {
- int i;
- double t1, t2;
- t1 = dnow();
- for (i=0; i < 8; i++) {
- rfbPE(-1);
- if (t == 0) rfbPE(-1);
- }
- t2 = dnow();
- t += (int) (1000 * (t2 - t1));
- if (t >= tot) {
- break;
- }
- usleep(dt * 1000);
- t += dt;
- }
- if (connect_or_exit) {
- if (client_count <= nclients0) {
- for (t = 0; t < 10; t++) {
- int i;
- for (i=0; i < 3; i++) {
- rfbPE(-1);
- }
- usleep(100 * 1000);
- }
- }
- if (client_count <= nclients0) {
- rfbLogEnable(1);
- rfbLog("exiting under -connect_or_exit\n");
- if (gui_pid > 0) {
- rfbLog("killing gui_pid %d\n", gui_pid);
- kill(gui_pid, SIGTERM);
- }
- clean_up_exit(1);
- }
- }
- if (xrandr || xrandr_maybe) {
- check_xrandr_event("reverse_connect2");
- }
-}
-
-/*
- * Routines for monitoring the VNC_CONNECT and X11VNC_REMOTE properties
- * for changes. The vncconnect(1) will set it on our X display.
- */
-void set_vnc_connect_prop(char *str) {
- RAWFB_RET_VOID
-#if !NO_X11
- if (vnc_connect_prop == None) return;
- XChangeProperty(dpy, rootwin, vnc_connect_prop, XA_STRING, 8,
- PropModeReplace, (unsigned char *)str, strlen(str));
-#else
- if (!str) {}
-#endif /* NO_X11 */
-}
-
-void set_x11vnc_remote_prop(char *str) {
- RAWFB_RET_VOID
-#if !NO_X11
- if (x11vnc_remote_prop == None) return;
- XChangeProperty(dpy, rootwin, x11vnc_remote_prop, XA_STRING, 8,
- PropModeReplace, (unsigned char *)str, strlen(str));
-#else
- if (!str) {}
-#endif /* NO_X11 */
-}
-
-void read_vnc_connect_prop(int nomsg) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!nomsg) {}
- return;
-#else
- Atom type;
- int format, slen, dlen;
- unsigned long nitems = 0, bytes_after = 0;
- unsigned char* data = NULL;
- int db = 1;
-
- vnc_connect_str[0] = '\0';
- slen = 0;
-
- if (! vnc_connect || vnc_connect_prop == None) {
- /* not active or problem with VNC_CONNECT atom */
- return;
- }
- RAWFB_RET_VOID
-
- /* read the property value into vnc_connect_str: */
- do {
- if (XGetWindowProperty(dpy, DefaultRootWindow(dpy),
- vnc_connect_prop, nitems/4, VNC_CONNECT_MAX/16, False,
- AnyPropertyType, &type, &format, &nitems, &bytes_after,
- &data) == Success) {
-
- dlen = nitems * (format/8);
- if (slen + dlen > VNC_CONNECT_MAX) {
- /* too big */
- rfbLog("warning: truncating large VNC_CONNECT"
- " string > %d bytes.\n", VNC_CONNECT_MAX);
- XFree_wr(data);
- break;
- }
- memcpy(vnc_connect_str+slen, data, dlen);
- slen += dlen;
- vnc_connect_str[slen] = '\0';
- XFree_wr(data);
- }
- } while (bytes_after > 0);
-
- vnc_connect_str[VNC_CONNECT_MAX] = '\0';
- if (! db || nomsg) {
- ;
- } else {
- rfbLog("read VNC_CONNECT: %s\n", vnc_connect_str);
- }
-#endif /* NO_X11 */
-}
-
-void read_x11vnc_remote_prop(int nomsg) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!nomsg) {}
- return;
-#else
- Atom type;
- int format, slen, dlen;
- unsigned long nitems = 0, bytes_after = 0;
- unsigned char* data = NULL;
- int db = 1;
-
- x11vnc_remote_str[0] = '\0';
- slen = 0;
-
- if (! vnc_connect || x11vnc_remote_prop == None) {
- /* not active or problem with X11VNC_REMOTE atom */
- return;
- }
- RAWFB_RET_VOID
-
- /* read the property value into x11vnc_remote_str: */
- do {
- if (XGetWindowProperty(dpy, DefaultRootWindow(dpy),
- x11vnc_remote_prop, nitems/4, X11VNC_REMOTE_MAX/16, False,
- AnyPropertyType, &type, &format, &nitems, &bytes_after,
- &data) == Success) {
-
- dlen = nitems * (format/8);
- if (slen + dlen > X11VNC_REMOTE_MAX) {
- /* too big */
- rfbLog("warning: truncating large X11VNC_REMOTE"
- " string > %d bytes.\n", X11VNC_REMOTE_MAX);
- XFree_wr(data);
- break;
- }
- memcpy(x11vnc_remote_str+slen, data, dlen);
- slen += dlen;
- x11vnc_remote_str[slen] = '\0';
- XFree_wr(data);
- }
- } while (bytes_after > 0);
-
- x11vnc_remote_str[X11VNC_REMOTE_MAX] = '\0';
- if (! db || nomsg) {
- ;
- } else if (strstr(x11vnc_remote_str, "ans=stop:N/A,ans=quit:N/A,ans=")) {
- ;
- } else if (strstr(x11vnc_remote_str, "qry=stop,quit,exit")) {
- ;
- } else if (strstr(x11vnc_remote_str, "ack=") == x11vnc_remote_str) {
- ;
- } else if (quiet && strstr(x11vnc_remote_str, "qry=ping") ==
- x11vnc_remote_str) {
- ;
- } else if (strstr(x11vnc_remote_str, "cmd=") &&
- strstr(x11vnc_remote_str, "passwd")) {
- rfbLog("read X11VNC_REMOTE: *\n");
- } else if (strlen(x11vnc_remote_str) > 36) {
- char trim[100];
- trim[0] = '\0';
- strncat(trim, x11vnc_remote_str, 36);
- rfbLog("read X11VNC_REMOTE: %s ...\n", trim);
-
- } else {
- rfbLog("read X11VNC_REMOTE: %s\n", x11vnc_remote_str);
- }
-#endif /* NO_X11 */
-}
-
-extern int rc_npieces;
-
-void grab_state(int *ptr_grabbed, int *kbd_grabbed) {
- int rcp, rck;
- double t0, t1;
- double ta, tb, tc;
- *ptr_grabbed = -1;
- *kbd_grabbed = -1;
-
- if (!dpy) {
- return;
- }
- *ptr_grabbed = 0;
- *kbd_grabbed = 0;
-
-#if !NO_X11
- X_LOCK;
-
- XSync(dpy, False);
-
- ta = t0 = dnow();
-
- rcp = XGrabPointer(dpy, window, False, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
- XUngrabPointer(dpy, CurrentTime);
-
- tb = dnow();
-
- rck = XGrabKeyboard(dpy, window, False, GrabModeAsync, GrabModeAsync, CurrentTime);
- XUngrabKeyboard(dpy, CurrentTime);
-
- tc = dnow();
-
- XSync(dpy, False);
-
- t1 = dnow();
-
- X_UNLOCK;
- if (rcp == AlreadyGrabbed || rcp == GrabFrozen) {
- *ptr_grabbed = 1;
- }
- if (rck == AlreadyGrabbed || rck == GrabFrozen) {
- *kbd_grabbed = 1;
- }
- if (rc_npieces < 10) {
- rfbLog("grab_state: checked %d,%d in %.6f sec (%.6f %.6f)\n",
- *ptr_grabbed, *kbd_grabbed, t1-t0, tb-ta, tc-tb);
- }
-#endif
-}
-
-static void pmove(int x, int y) {
- if (x < 0 || y < 0) {
- rfbLog("pmove: skipping negative x or y: %d %d\n", x, y);
- return;
- }
- rfbLog("pmove: x y: %d %d\n", x, y);
- pointer_event(0, x, y, NULL);
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
-}
-
-
-char *bcx_xattach(char *str, int *pg_init, int *kg_init) {
- int grab_check = 1;
- int shift = 20;
- int final_x = 30, final_y = 30;
- int extra_x = -1, extra_y = -1;
- int t1, t2, dt = 40 * 1000;
- int ifneeded = 0;
- char *dir = "none", *flip = "none", *q;
- int pg1, kg1, pg2, kg2;
- char _bcx_res[128];
-
- /* str:[up,down,left,right]+nograbcheck+shift=n+final=x+y+extra_move=x+y+[master_to_slave,slave_to_master,M2S,S2M]+dt=n+retry=n+ifneeded */
-
- if (strstr(str, "up")) {
- dir = "up";
- } else if (strstr(str, "down")) {
- dir = "down";
- } else if (strstr(str, "left")) {
- dir = "left";
- } else if (strstr(str, "right")) {
- dir = "right";
- } else {
- return strdup("FAIL,NO_DIRECTION_SPECIFIED");
- }
-
- if (strstr(str, "master_to_slave") || strstr(str, "M2S")) {
- flip = "M2S";
- } else if (strstr(str, "slave_to_master") || strstr(str, "S2M")) {
- flip = "S2M";
- } else {
- return strdup("FAIL,NO_MODE_CHANGE_SPECIFIED");
- }
-
- if (strstr(str, "nograbcheck")) {
- grab_check = 0;
- }
- if (strstr(str, "ifneeded")) {
- ifneeded = 1;
- }
- q = strstr(str, "shift=");
- if (q && sscanf(q, "shift=%d", &t1) == 1) {
- shift = t1;
- }
- q = strstr(str, "final=");
- if (q && sscanf(q, "final=%d+%d", &t1, &t2) == 2) {
- final_x = t1;
- final_y = t2;
- }
- q = strstr(str, "extra_move=");
- if (q && sscanf(q, "extra_move=%d+%d", &t1, &t2) == 2) {
- extra_x = t1;
- extra_y = t2;
- }
- q = strstr(str, "dt=");
- if (q && sscanf(q, "dt=%d", &t1) == 1) {
- dt = t1 * 1000;
- }
-
- if (grab_check) {
- int read_init = 0;
-
- if (*pg_init >=0 && *kg_init >=0) {
- pg1 = *pg_init;
- kg1 = *kg_init;
- read_init = 1;
- } else {
- grab_state(&pg1, &kg1);
- read_init = 0;
- }
-
- if (!strcmp(flip, "M2S")) {
- if (ifneeded && pg1 == 1 && kg1 == 1) {
- rfbLog("bcx_xattach: M2S grab state is already what we want, skipping moves: %d,%d\n", pg1, kg1);
- return strdup("DONE,GRAB_OK");
- }
- } else if (!strcmp(flip, "S2M")) {
- if (ifneeded && pg1 == 0 && kg1 == 0) {
- rfbLog("bcx_xattach: S2M grab state is already what we want, skipping moves: %d,%d\n", pg1, kg1);
- return strdup("DONE,GRAB_OK");
- }
- }
-
- if (read_init) {
- ;
- } else if (!strcmp(flip, "M2S")) {
- if (pg1 != 0 || kg1 != 0) {
- rfbLog("bcx_xattach: M2S init grab state incorrect: %d,%d\n", pg1, kg1);
- usleep(2*dt);
- grab_state(&pg1, &kg1);
- rfbLog("bcx_xattach: slept and retried, grab is now: %d,%d\n", pg1, kg1);
- }
- } else if (!strcmp(flip, "S2M")) {
- if (pg1 != 1 || kg1 != 1) {
- rfbLog("bcx_xattach: S2M init grab state incorrect: %d,%d\n", pg1, kg1);
- usleep(2*dt);
- grab_state(&pg1, &kg1);
- rfbLog("bcx_xattach: slept and retried, grab is now: %d,%d\n", pg1, kg1);
- }
- }
- if (!read_init) {
- *pg_init = pg1;
- *kg_init = kg1;
- }
- }
-
- /*
- * A guide for BARCO xattach:
- *
- * For -cursor_rule 'b(0):%:t(1),t(1):%:b(0)'
- * down+M2S up+S2M
- * For -cursor_rule 'r(0):%:l(1),l(1):%:r(0)'
- * right+M2S left+S2M
- *
- * For -cursor_rule 't(0):%:b(1),b(1):%:t(0)'
- * up+M2S down+S2M
- * For -cursor_rule 'l(0):%:r(1),r(1):%:l(0)'
- * left+M2S right+S2M
- * For -cursor_rule 'l(0):%:r(1),r(1):%:l(0),r(0):%:l(1),l(1):%:r(0)'
- * left+M2S right+S2M (we used to do both 'right')
- */
-
- if (!strcmp(flip, "M2S")) {
- if (!strcmp(dir, "up")) {
- pmove(shift, 0); /* go to top edge */
- usleep(dt);
- pmove(shift+1, 0); /* move 1 for MotionNotify */
- } else if (!strcmp(dir, "down")) {
- pmove(shift, dpy_y-1); /* go to bottom edge */
- usleep(dt);
- pmove(shift+1, dpy_y-1); /* move 1 for MotionNotify */
- } else if (!strcmp(dir, "left")) {
- pmove(0, shift); /* go to left edge */
- usleep(dt);
- pmove(0, shift+1); /* move 1 for MotionNotify */
- } else if (!strcmp(dir, "right")) {
- pmove(dpy_x-1, shift); /* go to right edge */
- usleep(dt);
- pmove(dpy_x-1, shift+1); /* move 1 for Motion Notify */
- }
- } else if (!strcmp(flip, "S2M")) {
- int dts = dt/2;
- if (!strcmp(dir, "up")) {
- pmove(shift, 2); /* Approach top edge in 3 moves. 1st move */
- usleep(dts);
- pmove(shift, 1); /* 2nd move */
- usleep(dts);
- pmove(shift, 0); /* 3rd move */
- usleep(dts);
- pmove(shift+1, 0); /* move 1 for MotionNotify */
- usleep(dts);
- pmove(shift+1, dpy_y-2); /* go to height-2 for extra pixel (slave y now == 0?) */
- usleep(dts);
- pmove(shift, dpy_y-2); /* move 1 for MotionNotify */
- usleep(dts);
- pmove(shift, 1); /* go to 1 to be sure slave y == 0 */
- usleep(dts);
- pmove(shift+1, 1); /* move 1 for MotionNotify */
- } else if (!strcmp(dir, "down")) {
- pmove(shift, dpy_y-3); /* Approach bottom edge in 3 moves. 1st move */
- usleep(dts);
- pmove(shift, dpy_y-2); /* 2nd move */
- usleep(dts);
- pmove(shift, dpy_y-1); /* 3rd move */
- usleep(dts);
- pmove(shift+1, dpy_y-1); /* move 1 for MotionNotify */
- usleep(dts);
- pmove(shift+1, 1); /* go to 1 for extra pixel (slave y now == dpy_y-1?) */
- usleep(dts);
- pmove(shift, 1); /* move 1 for MotionNotify */
- usleep(dts);
- pmove(shift, dpy_y-2); /* go to dpy_y-2 to be sure slave y == dpy_y-1 */
- usleep(dts);
- pmove(shift+1, dpy_y-2); /* move 1 for MotionNotify */
- } else if (!strcmp(dir, "left")) {
- pmove(2, shift); /* Approach left edge in 3 moves. 1st move */
- usleep(dts);
- pmove(1, shift); /* 2nd move */
- usleep(dts);
- pmove(0, shift); /* 3rd move */
- usleep(dts);
- pmove(0, shift+1); /* move 1 for MotionNotify */
- usleep(dts);
- pmove(dpy_x-2, shift+1); /* go to width-2 for extra pixel (slave x now == 0?) */
- usleep(dts);
- pmove(dpy_x-2, shift); /* move 1 for MotionNotify */
- usleep(dts);
- pmove(1, shift); /* go to 1 to be sure slave x == 0 */
- usleep(dts);
- pmove(1, shift+1); /* move 1 for MotionNotify */
- } else if (!strcmp(dir, "right")) {
- pmove(dpy_x-3, shift); /* Approach right edge in 3 moves. 1st move */
- usleep(dts);
- pmove(dpy_x-2, shift); /* 2nd move */
- usleep(dts);
- pmove(dpy_x-1, shift); /* 3rd move */
- usleep(dts);
- pmove(dpy_x-1, shift+1); /* move 1 for MotionNotify */
- usleep(dts);
- pmove(1, shift+1); /* go to 1 to extra pixel (slave x now == dpy_x-1?) */
- usleep(dts);
- pmove(1, shift); /* move 1 for MotionNotify */
- usleep(dts);
- pmove(dpy_x-2, shift); /* go to dpy_x-2 to be sure slave x == dpy_x-1 */
- usleep(dts);
- pmove(dpy_x-2, shift+1); /* move 1 for MotionNotify */
- }
- }
-
- usleep(dt);
- pmove(final_x, final_y);
- usleep(dt);
-
- if (extra_x >= 0 && extra_y >= 0) {
- pmove(extra_x, extra_y);
- usleep(dt);
- }
-
- strcpy(_bcx_res, "DONE");
-
- if (grab_check) {
- char st[64];
-
- usleep(3*dt);
- grab_state(&pg2, &kg2);
-
- if (!strcmp(flip, "M2S")) {
- if (pg2 != 1 || kg2 != 1) {
- rfbLog("bcx_xattach: M2S fini grab state incorrect: %d,%d\n", pg2, kg2);
- usleep(2*dt);
- grab_state(&pg2, &kg2);
- rfbLog("bcx_xattach: slept and retried, grab is now: %d,%d\n", pg2, kg2);
- }
- } else if (!strcmp(flip, "S2M")) {
- if (pg2 != 0 || kg2 != 0) {
- rfbLog("bcx_xattach: S2M fini grab state incorrect: %d,%d\n", pg2, kg2);
- usleep(2*dt);
- grab_state(&pg2, &kg2);
- rfbLog("bcx_xattach: slept and retried, grab is now: %d,%d\n", pg2, kg2);
- }
- }
-
- sprintf(st, ":%d,%d-%d,%d", pg1, kg1, pg2, kg2);
-
- if (getenv("GRAB_CHECK_LOOP")) {
- int i, n = atoi(getenv("GRAB_CHECK_LOOP"));
- rfbLog("grab st: %s\n", st);
- for (i=0; i < n; i++) {
- usleep(dt);
- grab_state(&pg2, &kg2);
- sprintf(st, ":%d,%d-%d,%d", pg1, kg1, pg2, kg2);
- rfbLog("grab st: %s\n", st);
- }
- }
-
- if (!strcmp(flip, "M2S")) {
- if (pg1 == 0 && kg1 == 0 && pg2 == 1 && kg2 == 1) {
- strcat(_bcx_res, ",GRAB_OK");
- } else {
- rfbLog("bcx_xattach: M2S grab state incorrect: %d,%d -> %d,%d\n", pg1, kg1, pg2, kg2);
- strcat(_bcx_res, ",GRAB_FAIL");
- if (pg2 == 1 && kg2 == 1) {
- strcat(_bcx_res, "_INIT");
- } else if (pg1 == 0 && kg1 == 0) {
- strcat(_bcx_res, "_FINAL");
- }
- strcat(_bcx_res, st);
- }
- } else if (!strcmp(flip, "S2M")) {
- if (pg1 == 1 && kg1 == 1 && pg2 == 0 && kg2 == 0) {
- strcat(_bcx_res, ",GRAB_OK");
- } else {
- rfbLog("bcx_xattach: S2M grab state incorrect: %d,%d -> %d,%d\n", pg1, kg1, pg2, kg2);
- strcat(_bcx_res, ",GRAB_FAIL");
- if (pg2 == 0 && kg2 == 0) {
- strcat(_bcx_res, "_INIT");
- } else if (pg1 == 1 && kg1 == 1) {
- strcat(_bcx_res, "_FINAL");
- }
- strcat(_bcx_res, st);
- }
- }
- }
- return strdup(_bcx_res);
-}
-
-int set_xprop(char *prop, Window win, char *value) {
- int rc = -1;
-#if !NO_X11
- Atom aprop;
-
- RAWFB_RET(rc)
-
- if (!prop || !value) {
- return rc;
- }
- if (win == None) {
- win = rootwin;
- }
- aprop = XInternAtom(dpy, prop, False);
- if (aprop == None) {
- return rc;
- }
- rc = XChangeProperty(dpy, win, aprop, XA_STRING, 8,
- PropModeReplace, (unsigned char *)value, strlen(value));
- return rc;
-#else
- RAWFB_RET(rc)
- if (!prop || !win || !value) {}
- return rc;
-#endif /* NO_X11 */
-}
-
-char *get_xprop(char *prop, Window win) {
-#if NO_X11
- RAWFB_RET(NULL)
- if (!prop || !win) {}
- return NULL;
-#else
- Atom type, aprop;
- int format, slen, dlen;
- unsigned long nitems = 0, bytes_after = 0;
- unsigned char* data = NULL;
- char get_str[VNC_CONNECT_MAX+1];
-
- RAWFB_RET(NULL)
-
- if (prop == NULL || !strcmp(prop, "")) {
- return NULL;
- }
- if (win == None) {
- win = rootwin;
- }
- aprop = XInternAtom(dpy, prop, True);
- if (aprop == None) {
- return NULL;
- }
-
- get_str[0] = '\0';
- slen = 0;
-
- /* read the property value into get_str: */
- do {
- if (XGetWindowProperty(dpy, win, aprop, nitems/4,
- VNC_CONNECT_MAX/16, False, AnyPropertyType, &type,
- &format, &nitems, &bytes_after, &data) == Success) {
-
- dlen = nitems * (format/8);
- if (slen + dlen > VNC_CONNECT_MAX) {
- /* too big */
- rfbLog("get_xprop: warning: truncating large '%s'"
- " string > %d bytes.\n", prop, VNC_CONNECT_MAX);
- XFree_wr(data);
- break;
- }
- memcpy(get_str+slen, data, dlen);
- slen += dlen;
- get_str[slen] = '\0';
- XFree_wr(data);
- }
- } while (bytes_after > 0);
-
- get_str[VNC_CONNECT_MAX] = '\0';
- rfbLog("get_prop: read: '%s' = '%s'\n", prop, get_str);
-
- return strdup(get_str);
-#endif /* NO_X11 */
-}
-
-static char _win_fmt[1000];
-
-static char *win_fmt(Window win, XWindowAttributes a) {
- memset(_win_fmt, 0, sizeof(_win_fmt));
- sprintf(_win_fmt, "0x%lx:%dx%dx%d+%d+%d-map:%d-bw:%d-cl:%d-vis:%d-bs:%d/%d",
- win, a.width, a.height, a.depth, a.x, a.y, a.map_state, a.border_width, a.class,
- (int) ((a.visual)->visualid), a.backing_store, a.save_under);
- return _win_fmt;
-}
-
-char *wininfo(Window win, int show_children) {
-#if NO_X11
- RAWFB_RET(NULL)
- if (!win || !show_children) {}
- return NULL;
-#else
- XWindowAttributes attr;
- int n, size = X11VNC_REMOTE_MAX;
- char get_str[X11VNC_REMOTE_MAX+1];
- unsigned int nchildren;
- Window rr, pr, *children;
-
- RAWFB_RET(NULL)
-
- if (win == None) {
- return strdup("None");
- }
-
- X_LOCK;
- if (!valid_window(win, &attr, 1)) {
- X_UNLOCK;
- return strdup("Invalid");
- }
- get_str[0] = '\0';
-
- if (show_children) {
- XQueryTree_wr(dpy, win, &rr, &pr, &children, &nchildren);
- } else {
- nchildren = 1;
- children = (Window *) calloc(2 * sizeof(Window), 1);
- children[0] = win;
- }
- for (n=0; n < (int) nchildren; n++) {
- char tmp[32];
- char *str = "Invalid";
- Window w = children[n];
- if (valid_window(w, &attr, 1)) {
- if (!show_children) {
- str = win_fmt(w, attr);
- } else {
- sprintf(tmp, "0x%lx", w);
- str = tmp;
- }
- }
- if ((int) (strlen(get_str) + 1 + strlen(str)) >= size) {
- break;
- }
- if (n > 0) {
- strcat(get_str, ",");
- }
- strcat(get_str, str);
- }
- get_str[size] = '\0';
- if (!show_children) {
- free(children);
- } else if (nchildren) {
- XFree_wr(children);
- }
- rfbLog("wininfo computed: %s\n", get_str);
- X_UNLOCK;
-
- return strdup(get_str);
-#endif /* NO_X11 */
-}
-
-/*
- * check if client_connect has been set, if so make the reverse connections.
- */
-static void send_client_connect(void) {
- if (client_connect != NULL) {
- char *str = client_connect;
- if (strstr(str, "cmd=") == str || strstr(str, "qry=") == str) {
- process_remote_cmd(client_connect, 0);
- } else if (strstr(str, "ans=") == str
- || strstr(str, "aro=") == str) {
- ;
- } else if (strstr(str, "ack=") == str) {
- ;
- } else {
- reverse_connect(client_connect);
- }
- free(client_connect);
- client_connect = NULL;
- }
-}
-
-/*
- * monitor the various input methods
- */
-void check_connect_inputs(void) {
-
- if (unixpw_in_progress) return;
-
- /* flush any already set: */
- send_client_connect();
-
- /* connect file: */
- if (client_connect_file != NULL) {
- check_connect_file(client_connect_file);
- }
- send_client_connect();
-
- /* VNC_CONNECT property (vncconnect program) */
- if (vnc_connect && *vnc_connect_str != '\0') {
- client_connect = strdup(vnc_connect_str);
- vnc_connect_str[0] = '\0';
- }
- send_client_connect();
-
- /* X11VNC_REMOTE property */
- if (vnc_connect && *x11vnc_remote_str != '\0') {
- client_connect = strdup(x11vnc_remote_str);
- x11vnc_remote_str[0] = '\0';
- }
- send_client_connect();
-}
-
-void check_gui_inputs(void) {
- int i, gnmax = 0, n = 0, nfds;
- int socks[ICON_MODE_SOCKS];
- fd_set fds;
- struct timeval tv;
- char buf[X11VNC_REMOTE_MAX+1];
- ssize_t nbytes;
-
- if (unixpw_in_progress) return;
-
- for (i=0; i<ICON_MODE_SOCKS; i++) {
- if (icon_mode_socks[i] >= 0) {
- socks[n++] = i;
- if (icon_mode_socks[i] > gnmax) {
- gnmax = icon_mode_socks[i];
- }
- }
- }
-
- if (! n) {
- return;
- }
-
- FD_ZERO(&fds);
- for (i=0; i<n; i++) {
- FD_SET(icon_mode_socks[socks[i]], &fds);
- }
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- nfds = select(gnmax+1, &fds, NULL, NULL, &tv);
- if (nfds <= 0) {
- return;
- }
-
- for (i=0; i<n; i++) {
- int k, fd = icon_mode_socks[socks[i]];
- char *p;
- char **list;
- int lind;
-
- if (! FD_ISSET(fd, &fds)) {
- continue;
- }
- for (k=0; k<=X11VNC_REMOTE_MAX; k++) {
- buf[k] = '\0';
- }
- nbytes = read(fd, buf, X11VNC_REMOTE_MAX);
- if (nbytes <= 0) {
- close(fd);
- icon_mode_socks[socks[i]] = -1;
- continue;
- }
-
- list = (char **) calloc((strlen(buf)+2) * sizeof(char *), 1);
-
- lind = 0;
- p = strtok(buf, "\r\n");
- while (p) {
- list[lind++] = strdup(p);
- p = strtok(NULL, "\r\n");
- }
-
- lind = 0;
- while (list[lind] != NULL) {
- p = list[lind++];
- if (strstr(p, "cmd=") == p ||
- strstr(p, "qry=") == p) {
- char *str = process_remote_cmd(p, 1);
- if (! str) {
- str = strdup("");
- }
- nbytes = write(fd, str, strlen(str));
- write(fd, "\n", 1);
- free(str);
- if (nbytes < 0) {
- close(fd);
- icon_mode_socks[socks[i]] = -1;
- break;
- }
- }
- }
-
- lind = 0;
- while (list[lind] != NULL) {
- p = list[lind++];
- if (p) free(p);
- }
- free(list);
- }
-}
-
-rfbClientPtr create_new_client(int sock, int start_thread) {
- rfbClientPtr cl;
-
- if (!screen) {
- return NULL;
- }
-
- cl = rfbNewClient(screen, sock);
-
- if (cl == NULL) {
- return NULL;
- }
- if (use_threads) {
- cl->onHold = FALSE;
- if (start_thread) {
- rfbStartOnHoldClient(cl);
- }
- }
- return cl;
-}
-
-static int turn_off_truecolor = 0;
-
-static void turn_off_truecolor_ad(rfbClientPtr client) {
- if (client) {}
- if (turn_off_truecolor) {
- rfbLog("turning off truecolor advertising.\n");
- /* mutex */
- screen->serverFormat.trueColour = FALSE;
- screen->displayHook = NULL;
- screen->serverFormat.redShift = 0;
- screen->serverFormat.greenShift = 0;
- screen->serverFormat.blueShift = 0;
- screen->serverFormat.redMax = 0;
- screen->serverFormat.greenMax = 0;
- screen->serverFormat.blueMax = 0;
- turn_off_truecolor = 0;
- }
-}
-
-/*
- * some overrides for the local console text chat.
- * could be useful in general for local helpers.
- */
-
-rfbBool password_check_chat_helper(rfbClientPtr cl, const char* response, int len) {
- if (response || len) {}
- if (cl != chat_window_client) {
- rfbLog("invalid client during chat_helper login\n");
- return FALSE;
- } else {
- if (!cl->host) {
- rfbLog("empty cl->host during chat_helper login\n");
- return FALSE;
- }
- if (strcmp(cl->host, "127.0.0.1")) {
- rfbLog("invalid cl->host during chat_helper login: %s\n", cl->host);
- return FALSE;
- }
- rfbLog("chat_helper login accepted\n");
- return TRUE;
- }
-}
-
-enum rfbNewClientAction new_client_chat_helper(rfbClientPtr client) {
- if (client) {}
- client->clientGoneHook = client_gone_chat_helper;
- rfbLog("new chat helper\n");
- return(RFB_CLIENT_ACCEPT);
-}
-
-void client_gone_chat_helper(rfbClientPtr client) {
- if (client) {}
- rfbLog("finished chat helper\n");
- chat_window_client = NULL;
-}
-
-void client_set_net(rfbClientPtr client) {
- ClientData *cd;
- if (client == NULL) {
- return;
- }
- cd = (ClientData *) client->clientData;
- if (cd == NULL) {
- return;
- }
- if (cd->client_port < 0) {
- double dt = dnow();
- cd->client_port = get_remote_port(client->sock);
- cd->server_port = get_local_port(client->sock);
- cd->server_ip = get_local_host(client->sock);
- cd->hostname = ip2host(client->host);
- rfbLog("client_set_net: %s %.4f\n", client->host, dnow() - dt);
- }
-}
-/*
- * libvncserver callback for when a new client connects
- */
-enum rfbNewClientAction new_client(rfbClientPtr client) {
- ClientData *cd;
-
- CLIENT_LOCK;
-
- last_event = last_input = time(NULL);
-
- latest_client = client;
-
- if (inetd) {
- /*
- * Set this so we exit as soon as connection closes,
- * otherwise client_gone is only called after RFB_CLIENT_ACCEPT
- */
- if (inetd_client == NULL) {
- inetd_client = client;
- client->clientGoneHook = client_gone;
- }
- }
-
- clients_served++;
-
- if (use_openssl || use_stunnel) {
- if (! ssl_initialized) {
- rfbLog("denying additional client: %s ssl not setup"
- " yet.\n", client->host);
- CLIENT_UNLOCK;
- return(RFB_CLIENT_REFUSE);
- }
- }
- if (unixpw_in_progress) {
- rfbLog("denying additional client: %s during -unixpw login.\n",
- client->host);
- CLIENT_UNLOCK;
- return(RFB_CLIENT_REFUSE);
- }
- if (connect_once) {
- if (screen->dontDisconnect && screen->neverShared) {
- if (! shared && accepted_client) {
- rfbLog("denying additional client: %s:%d\n",
- client->host, get_remote_port(client->sock));
- CLIENT_UNLOCK;
- return(RFB_CLIENT_REFUSE);
- }
- }
- }
-
- if (ipv6_client_ip_str != NULL) {
- rfbLog("renaming client->host from '%s' to '%s'\n",
- client->host ? client->host : "", ipv6_client_ip_str);
- if (client->host) {
- free(client->host);
- }
- client->host = strdup(ipv6_client_ip_str);
- }
-
- if (! check_access(client->host)) {
- rfbLog("denying client: %s does not match %s\n", client->host,
- allow_list ? allow_list : "(null)" );
- CLIENT_UNLOCK;
- return(RFB_CLIENT_REFUSE);
- }
-
- client->clientData = (void *) calloc(sizeof(ClientData), 1);
- cd = (ClientData *) client->clientData;
-
- /* see client_set_net() we delay the DNS lookups during handshake */
- cd->client_port = -1;
- cd->username = strdup("");
- cd->unixname = strdup("");
-
- cd->input[0] = '-';
- cd->login_viewonly = -1;
- cd->login_time = time(NULL);
- cd->ssl_helper_pid = 0;
-
- if (use_openssl && openssl_last_helper_pid) {
- cd->ssl_helper_pid = openssl_last_helper_pid;
- openssl_last_helper_pid = 0;
- }
-
- if (! accept_client(client)) {
- rfbLog("denying client: %s local user rejected connection.\n",
- client->host);
- rfbLog("denying client: accept_cmd=\"%s\"\n",
- accept_cmd ? accept_cmd : "(null)" );
-
- free_client_data(client);
-
- CLIENT_UNLOCK;
- return(RFB_CLIENT_REFUSE);
- }
-
- /* We will RFB_CLIENT_ACCEPT or RFB_CLIENT_ON_HOLD from here on. */
-
- if (passwdfile) {
- if (strstr(passwdfile, "read:") == passwdfile ||
- strstr(passwdfile, "cmd:") == passwdfile) {
- if (read_passwds(passwdfile)) {
- install_passwds();
- } else {
- rfbLog("problem reading: %s\n", passwdfile);
- clean_up_exit(1);
- }
- } else if (strstr(passwdfile, "custom:") == passwdfile) {
- if (screen) {
- /* mutex */
- screen->passwordCheck = custom_passwd_check;
- }
- }
- }
-
- cd->uid = clients_served;
-
- client->clientGoneHook = client_gone;
-
- if (client_count) {
- speeds_net_rate_measured = 0;
- speeds_net_latency_measured = 0;
- }
- client_count++;
-
- last_keyboard_input = last_pointer_input = time(NULL);
-
- if (no_autorepeat && client_count == 1 && ! view_only) {
- /*
- * first client, turn off X server autorepeat
- * XXX handle dynamic change of view_only and per-client.
- */
- autorepeat(0, 0);
- }
-#ifdef MACOSX
- if (macosx_console && client_count == 1) {
- macosxCG_refresh_callback_on();
- }
-#endif
- if (use_solid_bg && client_count == 1) {
- solid_bg(0);
- }
-
- if (pad_geometry) {
- install_padded_fb(pad_geometry);
- }
-
- cd->timer = last_new_client = dnow();
- cd->send_cmp_rate = 0.0;
- cd->send_raw_rate = 0.0;
- cd->latency = 0.0;
- cd->cmp_bytes_sent = 0;
- cd->raw_bytes_sent = 0;
-
- accepted_client++;
- rfbLog("incr accepted_client=%d for %s:%d sock=%d\n", accepted_client,
- client->host, get_remote_port(client->sock), client->sock);
- last_client = time(NULL);
-
- if (ncache) {
- check_ncache(1, 0);
- }
-
- if (advertise_truecolor && indexed_color) {
- int rs = 0, gs = 2, bs = 4;
- int rm = 3, gm = 3, bm = 3;
- if (bpp >= 24) {
- rs = 0, gs = 8, bs = 16;
- rm = 255, gm = 255, bm = 255;
- } else if (bpp >= 16) {
- rs = 0, gs = 5, bs = 10;
- rm = 31, gm = 31, bm = 31;
- }
- rfbLog("advertising truecolor.\n");
- if (getenv("ADVERT_BMSHIFT")) {
- bm--;
- }
-
- if (use_threads) LOCK(client->updateMutex);
-
- client->format.trueColour = TRUE;
- client->format.redShift = rs;
- client->format.greenShift = gs;
- client->format.blueShift = bs;
- client->format.redMax = rm;
- client->format.greenMax = gm;
- client->format.blueMax = bm;
-
- if (use_threads) UNLOCK(client->updateMutex);
-
- rfbSetTranslateFunction(client);
-
- /* mutex */
- screen->serverFormat.trueColour = TRUE;
- screen->serverFormat.redShift = rs;
- screen->serverFormat.greenShift = gs;
- screen->serverFormat.blueShift = bs;
- screen->serverFormat.redMax = rm;
- screen->serverFormat.greenMax = gm;
- screen->serverFormat.blueMax = bm;
- screen->displayHook = turn_off_truecolor_ad;
-
- turn_off_truecolor = 1;
- }
-
- if (unixpw) {
- unixpw_in_progress = 1;
- unixpw_client = client;
- unixpw_login_viewonly = 0;
-
- unixpw_file_xfer_save = screen->permitFileTransfer;
- screen->permitFileTransfer = FALSE;
- unixpw_tightvnc_xfer_save = tightfilexfer;
- tightfilexfer = 0;
-#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
- rfbLog("rfbUnregisterTightVNCFileTransferExtension: 1\n");
- rfbUnregisterTightVNCFileTransferExtension();
-#endif
-
- if (client->viewOnly) {
- unixpw_login_viewonly = 1;
- client->viewOnly = FALSE;
- }
- unixpw_last_try_time = time(NULL) + 10;
-
- unixpw_screen(1);
- unixpw_keystroke(0, 0, 1);
-
- if (!unixpw_in_rfbPE) {
- rfbLog("new client: %s in non-unixpw_in_rfbPE.\n",
- client->host);
- }
- CLIENT_UNLOCK;
- if (!use_threads) {
- /* always put client on hold even if unixpw_in_rfbPE is true */
- return(RFB_CLIENT_ON_HOLD);
- } else {
- /* unixpw threads is still in testing mode, disabled by default. See UNIXPW_THREADS */
- return(RFB_CLIENT_ACCEPT);
- }
- }
-
- CLIENT_UNLOCK;
- return(RFB_CLIENT_ACCEPT);
-}
-
-void start_client_info_sock(char *host_port_cookie) {
- char *host = NULL, *cookie = NULL, *p;
- char *str = strdup(host_port_cookie);
- int i, port, sock, next = -1;
- static time_t start_time[ICON_MODE_SOCKS];
- time_t oldest = 0;
- int db = 0;
-
- port = -1;
-
- for (i = 0; i < ICON_MODE_SOCKS; i++) {
- if (icon_mode_socks[i] < 0) {
- next = i;
- break;
- }
- if (oldest == 0 || start_time[i] < oldest) {
- next = i;
- oldest = start_time[i];
- }
- }
-
- p = strtok(str, ":");
- i = 0;
- while (p) {
- if (i == 0) {
- host = strdup(p);
- } else if (i == 1) {
- port = atoi(p);
- } else if (i == 2) {
- cookie = strdup(p);
- }
- i++;
- p = strtok(NULL, ":");
- }
- free(str);
-
- if (db) fprintf(stderr, "%s/%d/%s next=%d\n", host, port, cookie, next);
-
- if (host && port && cookie) {
- if (*host == '\0') {
- free(host);
- host = strdup("localhost");
- }
- sock = connect_tcp(host, port);
- if (sock < 0) {
- usleep(200 * 1000);
- sock = connect_tcp(host, port);
- }
- if (sock >= 0) {
- char *lst = list_clients();
- icon_mode_socks[next] = sock;
- start_time[next] = time(NULL);
- write(sock, "COOKIE:", strlen("COOKIE:"));
- write(sock, cookie, strlen(cookie));
- write(sock, "\n", strlen("\n"));
- write(sock, "none\n", strlen("none\n"));
- write(sock, "none\n", strlen("none\n"));
- write(sock, lst, strlen(lst));
- write(sock, "\n", strlen("\n"));
- if (db) {
- fprintf(stderr, "list: %s\n", lst);
- }
- free(lst);
- rfbLog("client_info_sock to: %s:%d\n", host, port);
- } else {
- rfbLog("failed client_info_sock: %s:%d\n", host, port);
- }
- } else {
- rfbLog("malformed client_info_sock: %s\n", host_port_cookie);
- }
-
- if (host) free(host);
- if (cookie) free(cookie);
-}
-
-void send_client_info(char *str) {
- int i;
- static char *pstr = NULL;
- static int len = 128;
-
- if (!str || strlen(str) == 0) {
- return;
- }
-
- if (!pstr) {
- pstr = (char *)malloc(len);
- }
- if (strlen(str) + 2 > (size_t) len) {
- free(pstr);
- len *= 2;
- pstr = (char *)malloc(len);
- }
- strcpy(pstr, str);
- strcat(pstr, "\n");
-
- if (icon_mode_fh) {
- if (0) fprintf(icon_mode_fh, "\n");
- fprintf(icon_mode_fh, "%s", pstr);
- fflush(icon_mode_fh);
- }
-
- for (i=0; i<ICON_MODE_SOCKS; i++) {
- int len, n, sock = icon_mode_socks[i];
- char *buf = pstr;
-
- if (sock < 0) {
- continue;
- }
-
- len = strlen(pstr);
- while (len > 0) {
- if (0) write(sock, "\n", 1);
- n = write(sock, buf, len);
- if (n > 0) {
- buf += n;
- len -= n;
- continue;
- }
-
- if (n < 0 && errno == EINTR) {
- continue;
- }
- close(sock);
- icon_mode_socks[i] = -1;
- break;
- }
- }
-}
-
-void adjust_grabs(int grab, int quiet) {
- RAWFB_RET_VOID
-#if NO_X11
- if (!grab || !quiet) {}
- return;
-#else
- /* n.b. caller decides to X_LOCK or not. */
- if (grab) {
- if (grab_kbd) {
- if (! quiet) {
- rfbLog("grabbing keyboard with XGrabKeyboard\n");
- }
- XGrabKeyboard(dpy, window, False, GrabModeAsync,
- GrabModeAsync, CurrentTime);
- }
- if (grab_ptr) {
- if (! quiet) {
- rfbLog("grabbing pointer with XGrabPointer\n");
- }
- XGrabPointer(dpy, window, False, 0, GrabModeAsync,
- GrabModeAsync, None, None, CurrentTime);
- }
- } else {
- if (grab_kbd) {
- if (! quiet) {
- rfbLog("ungrabbing keyboard with XUngrabKeyboard\n");
- }
- XUngrabKeyboard(dpy, CurrentTime);
- }
- if (grab_ptr) {
- if (! quiet) {
- rfbLog("ungrabbing pointer with XUngrabPointer\n");
- }
- XUngrabPointer(dpy, CurrentTime);
- }
- }
-#endif /* NO_X11 */
-}
-
-void check_new_clients(void) {
- static int last_count = -1;
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int i, send_info = 0;
- int run_after_accept = 0;
-
- if (unixpw_in_progress) {
- static double lping = 0.0;
- if (lping < dnow() + 5) {
- mark_rect_as_modified(0, 0, 1, 1, 1);
- lping = dnow();
- }
- if (unixpw_client && unixpw_client->viewOnly) {
- unixpw_login_viewonly = 1;
- unixpw_client->viewOnly = FALSE;
- }
- if (time(NULL) > unixpw_last_try_time + 45) {
- rfbLog("unixpw_deny: timed out waiting for reply.\n");
- unixpw_deny();
- }
- return;
- }
-
- if (grab_always) {
- ;
- } else if (grab_kbd || grab_ptr) {
- static double last_force = 0.0;
- if (client_count != last_count || dnow() > last_force + 0.25) {
- int q = (client_count == last_count);
- last_force = dnow();
- X_LOCK;
- if (client_count) {
- adjust_grabs(1, q);
- } else {
- adjust_grabs(0, q);
- }
- X_UNLOCK;
- }
- }
-
- if (last_count == -1) {
- last_count = 0;
- } else if (client_count == last_count) {
- return;
- }
-
- if (! all_clients_initialized()) {
- return;
- }
-
- if (client_count > last_count) {
- if (afteraccept_cmd != NULL && afteraccept_cmd[0] != '\0') {
- run_after_accept = 1;
- }
- }
-
- last_count = client_count;
-
- if (! screen) {
- return;
- }
-
- if (! client_count) {
- send_client_info("clients:none");
- return;
- }
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd = (ClientData *) cl->clientData;
- char *s;
-
- client_set_net(cl);
- if (! cd) {
- continue;
- }
-
- if (cd->login_viewonly < 0) {
- /* this is a general trigger to initialize things */
- if (cl->viewOnly) {
- cd->login_viewonly = 1;
- s = allowed_input_view_only;
- if (s && cd->input[0] == '-') {
- cl->viewOnly = FALSE;
- cd->input[0] = '\0';
- strncpy(cd->input, s, CILEN);
- }
- } else {
- cd->login_viewonly = 0;
- s = allowed_input_normal;
- if (s && cd->input[0] == '-') {
- cd->input[0] = '\0';
- strncpy(cd->input, s, CILEN);
- }
- }
- if (run_after_accept) {
- run_user_command(afteraccept_cmd, cl,
- "afteraccept", NULL, 0, NULL);
- }
- }
- }
- rfbReleaseClientIterator(iter);
-
- if (icon_mode_fh) {
- send_info++;
- }
- for (i = 0; i < ICON_MODE_SOCKS; i++) {
- if (send_info || icon_mode_socks[i] >= 0) {
- send_info++;
- break;
- }
- }
- if (send_info) {
- char *str, *s = list_clients();
- str = (char *) malloc(strlen("clients:") + strlen(s) + 1);
- sprintf(str, "clients:%s", s);
- send_client_info(str);
- free(str);
- free(s);
- }
-}
-
diff --git a/x11vnc/connections.h b/x11vnc/connections.h
deleted file mode 100644
index 3bdeffb..0000000
--- a/x11vnc/connections.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_CONNECTIONS_H
-#define _X11VNC_CONNECTIONS_H
-
-/* -- connections.h -- */
-
-extern char vnc_connect_str[];
-extern Atom vnc_connect_prop;
-extern char x11vnc_remote_str[];
-extern Atom x11vnc_remote_prop;
-extern rfbClientPtr inetd_client;
-
-
-extern int all_clients_initialized(void);
-extern char *list_clients(void);
-extern int new_fb_size_clients(rfbScreenInfoPtr s);
-extern void close_all_clients(void);
-extern void close_clients(char *str);
-extern void set_client_input(char *str);
-extern void set_child_info(void);
-extern int cmd_ok(char *cmd);
-extern void client_gone(rfbClientPtr client);
-extern void client_gone_chat_helper(rfbClientPtr client);
-extern void reverse_connect(char *str);
-extern void set_vnc_connect_prop(char *str);
-extern void read_vnc_connect_prop(int);
-extern void set_x11vnc_remote_prop(char *str);
-extern void read_x11vnc_remote_prop(int);
-extern void check_connect_inputs(void);
-extern void check_gui_inputs(void);
-extern rfbClientPtr create_new_client(int sock, int start_thread);
-extern enum rfbNewClientAction new_client(rfbClientPtr client);
-extern enum rfbNewClientAction new_client_chat_helper(rfbClientPtr client);
-extern rfbBool password_check_chat_helper(rfbClientPtr cl, const char* response, int len);
-extern void start_client_info_sock(char *host_port_cookie);
-extern void send_client_info(char *str);
-extern void adjust_grabs(int grab, int quiet);
-extern void check_new_clients(void);
-extern int accept_client(rfbClientPtr client);
-extern void check_ipv6_listen(long usec);
-extern void check_unix_sock(long usec);
-extern int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
- int len, FILE *output);
-extern int check_access(char *addr);
-extern void client_set_net(rfbClientPtr client);
-extern char *get_xprop(char *prop, Window win);
-extern int set_xprop(char *prop, Window win, char *value);
-extern char *bcx_xattach(char *str, int *pg_init, int *kg_init);
-extern void grab_state(int *ptr_grabbed, int *kbd_grabbed);
-extern char *wininfo(Window win, int show_children);
-
-#endif /* _X11VNC_CONNECTIONS_H */
diff --git a/x11vnc/cursor.c b/x11vnc/cursor.c
deleted file mode 100644
index 3d613a6..0000000
--- a/x11vnc/cursor.c
+++ /dev/null
@@ -1,2025 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- cursor.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "cleanup.h"
-#include "screen.h"
-#include "scan.h"
-#include "unixpw.h"
-#include "macosx.h"
-
-int xfixes_present = 0;
-int xfixes_first_initialized = 0;
-int use_xfixes = 1;
-int got_xfixes_cursor_notify = 0;
-int cursor_changes = 0;
-int alpha_threshold = 240;
-double alpha_frac = 0.33;
-int alpha_remove = 0;
-int alpha_blend = 1;
-int alt_arrow = 1;
-
-
-void first_cursor(void);
-void setup_cursors_and_push(void);
-void initialize_xfixes(void);
-int known_cursors_mode(char *s);
-void initialize_cursors_mode(void);
-int get_which_cursor(void);
-void restore_cursor_shape_updates(rfbScreenInfoPtr s);
-void disable_cursor_shape_updates(rfbScreenInfoPtr s);
-int cursor_shape_updates_clients(rfbScreenInfoPtr s);
-int cursor_pos_updates_clients(rfbScreenInfoPtr s);
-void cursor_position(int x, int y);
-void set_no_cursor(void);
-void set_warrow_cursor(void);
-int set_cursor(int x, int y, int which);
-int check_x11_pointer(void);
-int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp, int xhot, int yhot);
-unsigned long get_cursor_serial(int mode);
-
-
-typedef struct win_str_info {
- char *wm_name;
- char *res_name;
- char *res_class;
-} win_str_info_t;
-
-typedef struct cursor_info {
- char *data; /* data and mask pointers */
- char *mask;
- int wx, wy; /* size of cursor */
- int sx, sy; /* shift to its centering point */
- int reverse; /* swap black and white */
- rfbCursorPtr rfb;
-} cursor_info_t;
-
-
-static void curs_copy(cursor_info_t *dest, cursor_info_t *src);
-static void setup_cursors(void);
-static void set_rfb_cursor(int which);
-static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo);
-static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
- int xhot, int yhot, int Bpp);
-static int get_exact_cursor(int init);
-static void set_cursor_was_changed(rfbScreenInfoPtr s);
-
-
-/*
- * Here begins a bit of a mess to experiment with multiple cursors
- * drawn on the remote background ...
- */
-static void curs_copy(cursor_info_t *dest, cursor_info_t *src) {
- if (src->data != NULL) {
- dest->data = strdup(src->data);
- } else {
- dest->data = NULL;
- }
- if (src->mask != NULL) {
- dest->mask = strdup(src->mask);
- } else {
- dest->mask = NULL;
- }
- dest->wx = src->wx;
- dest->wy = src->wy;
- dest->sx = src->sx;
- dest->sy = src->sy;
- dest->reverse = src->reverse;
- dest->rfb = src->rfb;
-
- if (rotating && rotating_cursors && dest->data != NULL) {
- int tx, ty;
- rotate_curs(dest->data, src->data, src->wx, src->wy, 1);
- rotate_curs(dest->mask, src->mask, src->wx, src->wy, 1);
- rotate_coords(dest->sx, dest->sy, &tx, &ty, src->wx, src->wy);
- dest->sx = tx;
- dest->sy = ty;
- if (! rotating_same) {
- dest->wx = src->wy;
- dest->wy = src->wx;
- }
- }
-}
-
-/* empty cursor */
-static char* curs_empty_data =
-" "
-" ";
-
-static char* curs_empty_mask =
-" "
-" ";
-static cursor_info_t cur_empty = {NULL, NULL, 2, 2, 0, 0, 0, NULL};
-
-/* dot cursor */
-static char* curs_dot_data =
-" "
-" x";
-
-static char* curs_dot_mask =
-" "
-" x";
-static cursor_info_t cur_dot = {NULL, NULL, 2, 2, 0, 0, 0, NULL};
-
-
-/* main cursor */
-static char* curs_arrow_data =
-" "
-" x "
-" xx "
-" xxx "
-" xxxx "
-" xxxxx "
-" xxxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxx "
-" xx xx "
-" x xx "
-" xx "
-" xx "
-" xx "
-" "
-" "
-" ";
-
-static char* curs_arrow_mask =
-"xx "
-"xxx "
-"xxxx "
-"xxxxx "
-"xxxxxx "
-"xxxxxxx "
-"xxxxxxxx "
-"xxxxxxxxx "
-"xxxxxxxxxx "
-"xxxxxxxxxx "
-"xxxxxxx "
-"xxx xxxx "
-"xx xxxx "
-" xxxx "
-" xxxx "
-" xx "
-" "
-" ";
-static cursor_info_t cur_arrow = {NULL, NULL, 18, 18, 0, 0, 1, NULL};
-
-static char* curs_arrow2_data =
-" "
-" x "
-" xx "
-" xxx "
-" xxxx "
-" xxxxx "
-" xxxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxx "
-" xx xx "
-" x xx "
-" xx "
-" xx "
-" xx "
-" "
-" "
-" ";
-
-static char* curs_arrow2_mask =
-"xx "
-"xxx "
-"xxxx "
-"xxxxx "
-"xxxxxx "
-"xxxxxxx "
-"xxxxxxxx "
-"xxxxxxxxx "
-"xxxxxxxxxx "
-"xxxxxxxxxx "
-"xxxxxxx "
-"xxx xxxx "
-"xx xxxx "
-" xxxx "
-" xxxx "
-" xx "
-" "
-" ";
-static cursor_info_t cur_arrow2 = {NULL, NULL, 18, 18, 0, 0, 0, NULL};
-
-static char* curs_arrow3_data =
-" "
-" xx "
-" xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxx "
-" xxxxx "
-" xx x "
-" xx x "
-" x x "
-" x x "
-" x "
-" x "
-" ";
-
-static char* curs_arrow3_mask =
-"xxx "
-"xxxxx "
-"xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxxx "
-" xxxxxxx "
-" xxxxxxx "
-" xxxx xxx "
-" xxx xxx "
-" xxx xxx "
-" xxx xxx "
-" xxx"
-" xx";
-
-static cursor_info_t cur_arrow3 = {NULL, NULL, 16, 16, 0, 0, 1, NULL};
-
-static char* curs_arrow4_data =
-" "
-" xx "
-" xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxx "
-" xxxxx "
-" xx x "
-" xx x "
-" x x "
-" x x "
-" x "
-" x "
-" ";
-
-static char* curs_arrow4_mask =
-"xxx "
-"xxxxx "
-"xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxxx "
-" xxxxxxx "
-" xxxxxxx "
-" xxxx xxx "
-" xxx xxx "
-" xxx xxx "
-" xxx xxx "
-" xxx"
-" xx";
-
-static cursor_info_t cur_arrow4 = {NULL, NULL, 16, 16, 0, 0, 0, NULL};
-
-static char* curs_arrow5_data =
-"x "
-" xx "
-" xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxx "
-" xx x "
-" x x "
-" x x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x";
-
-static char* curs_arrow5_mask =
-"xx "
-"xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxx "
-" xxxxx "
-" xxxxxx "
-" xx xxx "
-" x xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx"
-" xx";
-
-static cursor_info_t cur_arrow5 = {NULL, NULL, 15, 15, 0, 0, 1, NULL};
-
-static char* curs_arrow6_data =
-"x "
-" xx "
-" xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxx "
-" xx x "
-" x x "
-" x x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x";
-
-static char* curs_arrow6_mask =
-"xx "
-"xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxx "
-" xxxxx "
-" xxxxxx "
-" xx xxx "
-" x xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx"
-" xx";
-
-static cursor_info_t cur_arrow6 = {NULL, NULL, 15, 15, 0, 0, 0, NULL};
-
-int alt_arrow_max = 6;
-/*
- * It turns out we can at least detect mouse is on the root window so
- * show it (under -cursor X) with this familiar cursor...
- */
-static char* curs_root_data =
-" "
-" "
-" xxx xxx "
-" xxxx xxxx "
-" xxxxx xxxxx "
-" xxxxx xxxxx "
-" xxxxxxxxxx "
-" xxxxxxxx "
-" xxxxxx "
-" xxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxx xxxxx "
-" xxxxx xxxxx "
-" xxxx xxxx "
-" xxx xxx "
-" "
-" ";
-
-static char* curs_root_mask =
-" "
-" xxxx xxxx "
-" xxxxx xxxxx "
-" xxxxxx xxxxxx "
-" xxxxxxx xxxxxxx "
-" xxxxxxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxx "
-" xxxxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxxxxxx "
-" xxxxxxx xxxxxxx "
-" xxxxxx xxxxxx "
-" xxxxx xxxxx "
-" xxxx xxxx "
-" ";
-static cursor_info_t cur_root = {NULL, NULL, 18, 18, 8, 8, 1, NULL};
-
-static char* curs_fleur_data =
-" "
-" xx "
-" xxxx "
-" xxxxxx "
-" xx "
-" x xx x "
-" xx xx xx "
-" xxxxxxxxxxxxxx "
-" xxxxxxxxxxxxxx "
-" xx xx xx "
-" x xx x "
-" xx "
-" xxxxxx "
-" xxxx "
-" xx "
-" ";
-
-static char* curs_fleur_mask =
-" xxxx "
-" xxxxx "
-" xxxxxx "
-" xxxxxxxx "
-" x xxxxxx x "
-" xxx xxxx xxx "
-"xxxxxxxxxxxxxxxx"
-"xxxxxxxxxxxxxxxx"
-"xxxxxxxxxxxxxxxx"
-"xxxxxxxxxxxxxxxx"
-" xxx xxxx xxx "
-" x xxxxxx x "
-" xxxxxxxx "
-" xxxxxx "
-" xxxx "
-" xxxx ";
-
-static cursor_info_t cur_fleur = {NULL, NULL, 16, 16, 8, 8, 1, NULL};
-
-static char* curs_plus_data =
-" "
-" xx "
-" xx "
-" xx "
-" xx "
-" xxxxxxxxxx "
-" xxxxxxxxxx "
-" xx "
-" xx "
-" xx "
-" xx "
-" ";
-
-static char* curs_plus_mask =
-" xxxx "
-" xxxx "
-" xxxx "
-" xxxx "
-"xxxxxxxxxxxx"
-"xxxxxxxxxxxx"
-"xxxxxxxxxxxx"
-"xxxxxxxxxxxx"
-" xxxx "
-" xxxx "
-" xxxx "
-" xxxx ";
-static cursor_info_t cur_plus = {NULL, NULL, 12, 12, 5, 6, 1, NULL};
-
-static char* curs_xterm_data =
-" "
-" xxx xxx "
-" xxx "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" xxx "
-" xxx xxx "
-" ";
-
-static char* curs_xterm_mask =
-" xxxx xxxx "
-" xxxxxxxxx "
-" xxxxxxxxx "
-" xxxxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxxxx "
-" xxxxxxxxx "
-" xxxxxxxxx "
-" xxxx xxxx ";
-static cursor_info_t cur_xterm = {NULL, NULL, 16, 16, 8, 8, 1, NULL};
-
-enum cursor_names {
- CURS_EMPTY = 0,
- CURS_DOT,
-
- CURS_ARROW,
- CURS_WARROW,
- CURS_ROOT,
- CURS_WM,
- CURS_TERM,
- CURS_PLUS,
-
- CURS_DYN1,
- CURS_DYN2,
- CURS_DYN3,
- CURS_DYN4,
- CURS_DYN5,
- CURS_DYN6,
- CURS_DYN7,
- CURS_DYN8,
- CURS_DYN9,
- CURS_DYN10,
- CURS_DYN11,
- CURS_DYN12,
- CURS_DYN13,
- CURS_DYN14,
- CURS_DYN15,
- CURS_DYN16
-};
-
-#define CURS_DYN_MIN CURS_DYN1
-#define CURS_DYN_MAX CURS_DYN16
-#define CURS_DYN_NUM (CURS_DYN_MAX - CURS_DYN_MIN + 1)
-
-#define CURS_MAX 32
-static cursor_info_t *cursors[CURS_MAX];
-
-void first_cursor(void) {
- if (! screen) {
- return;
- }
- if (! show_cursor) {
- LOCK(screen->cursorMutex);
- screen->cursor = NULL;
- UNLOCK(screen->cursorMutex);
- } else {
- got_xfixes_cursor_notify++;
- set_rfb_cursor(get_which_cursor());
- set_cursor_was_changed(screen);
- }
-}
-
-static void setup_cursors(void) {
- rfbCursorPtr rfb_curs;
- char *scale = NULL;
- int i, j, n = 0;
- int w_in = 0, h_in = 0;
- static int first = 1;
-
- if (verbose || use_threads) {
- rfbLog("setting up %d cursors...\n", CURS_MAX);
- }
-
- if (first) {
- for (i=0; i<CURS_MAX; i++) {
- cursors[i] = NULL;
- }
- }
- first = 0;
-
- if (screen) {
- LOCK(screen->cursorMutex);
- screen->cursor = NULL;
- }
-
- for (i=0; i<CURS_MAX; i++) {
- cursor_info_t *ci;
- if (cursors[i]) {
- /* clear out any existing ones: */
- ci = cursors[i];
- if (ci->rfb) {
- /* this is the rfbCursor part: */
- if (ci->rfb->richSource) {
- free(ci->rfb->richSource);
- ci->rfb->richSource = NULL;
- }
- if (ci->rfb->source) {
- free(ci->rfb->source);
- ci->rfb->source = NULL;
- }
- if (ci->rfb->mask) {
- free(ci->rfb->mask);
- ci->rfb->mask = NULL;
- }
- free(ci->rfb);
- ci->rfb = NULL;
- }
- if (ci->data) {
- free(ci->data);
- ci->data = NULL;
- }
- if (ci->mask) {
- free(ci->mask);
- ci->mask = NULL;
- }
- free(ci);
- ci = NULL;
- }
-
- /* create new struct: */
- ci = (cursor_info_t *) malloc(sizeof(cursor_info_t));
- ci->data = NULL;
- ci->mask = NULL;
- ci->wx = 0;
- ci->wy = 0;
- ci->sx = 0;
- ci->sy = 0;
- ci->reverse = 0;
- ci->rfb = NULL;
- cursors[i] = ci;
- }
-
- /* clear any xfixes cursor cache (no freeing is done) */
- get_exact_cursor(1);
-
- /* manually fill in the data+masks: */
- cur_empty.data = curs_empty_data;
- cur_empty.mask = curs_empty_mask;
-
- cur_dot.data = curs_dot_data;
- cur_dot.mask = curs_dot_mask;
-
- cur_arrow.data = curs_arrow_data;
- cur_arrow.mask = curs_arrow_mask;
- cur_arrow2.data = curs_arrow2_data;
- cur_arrow2.mask = curs_arrow2_mask;
- cur_arrow3.data = curs_arrow3_data;
- cur_arrow3.mask = curs_arrow3_mask;
- cur_arrow4.data = curs_arrow4_data;
- cur_arrow4.mask = curs_arrow4_mask;
- cur_arrow5.data = curs_arrow5_data;
- cur_arrow5.mask = curs_arrow5_mask;
- cur_arrow6.data = curs_arrow6_data;
- cur_arrow6.mask = curs_arrow6_mask;
-
- cur_root.data = curs_root_data;
- cur_root.mask = curs_root_mask;
-
- cur_plus.data = curs_plus_data;
- cur_plus.mask = curs_plus_mask;
-
- cur_fleur.data = curs_fleur_data;
- cur_fleur.mask = curs_fleur_mask;
-
- cur_xterm.data = curs_xterm_data;
- cur_xterm.mask = curs_xterm_mask;
-
- curs_copy(cursors[CURS_EMPTY], &cur_empty); n++;
- curs_copy(cursors[CURS_DOT], &cur_dot); n++;
-
- if (alt_arrow < 1 || alt_arrow > alt_arrow_max) {
- alt_arrow = 1;
- }
- if (alt_arrow == 1) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow); n++;
- } else if (alt_arrow == 2) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow2); n++;
- } else if (alt_arrow == 3) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow3); n++;
- } else if (alt_arrow == 4) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow4); n++;
- } else if (alt_arrow == 5) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow5); n++;
- } else if (alt_arrow == 6) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow6); n++;
- } else {
- alt_arrow = 1;
- curs_copy(cursors[CURS_ARROW], &cur_arrow); n++;
- }
- curs_copy(cursors[CURS_WARROW], &cur_arrow2); n++;
-
- curs_copy(cursors[CURS_ROOT], &cur_root); n++;
- curs_copy(cursors[CURS_WM], &cur_fleur); n++;
- curs_copy(cursors[CURS_TERM], &cur_xterm); n++;
- curs_copy(cursors[CURS_PLUS], &cur_plus); n++;
-
- if (scale_cursor_str) {
- scale = scale_cursor_str;
- } else if (scaling && scale_str) {
- scale = scale_str;
- }
- if (scale && sscanf(scale, "%dx%d", &i, &j) == 2) {
- if (wdpy_x > 0) {
- w_in = wdpy_x;
- h_in = wdpy_y;
- } else {
- w_in = dpy_x;
- h_in = dpy_y;
- }
- }
-
- /* scale = NULL zeroes everything */
- parse_scale_string(scale, &scale_cursor_fac_x, &scale_cursor_fac_y, &scaling_cursor,
- &scaling_cursor_blend, &j, &j, &scaling_cursor_interpolate,
- &scale_cursor_numer, &scale_cursor_denom, w_in, h_in);
-
- for (i=0; i<n; i++) {
- /* create rfbCursors for the special cursors: */
-
- cursor_info_t *ci = cursors[i];
-
- if (scaling_cursor && (scale_cursor_fac_x != 1.0 || scale_cursor_fac_y != 1.0)) {
- int w, h, x, y, k;
- unsigned long *pixels;
-
- w = ci->wx;
- h = ci->wy;
-
- pixels = (unsigned long *) malloc(w * h
- * sizeof(unsigned long));
-
- k = 0;
- for (y=0; y<h; y++) {
- for (x=0; x<w; x++) {
- char d = ci->data[k];
- char m = ci->mask[k];
- unsigned long *p;
-
- p = pixels + k;
-
- /* set alpha on */
- *p = 0xff000000;
-
- if (d == ' ' && m == ' ') {
- /* alpha off */
- *p = 0x00000000;
- } else if (d != ' ') {
- /* body */
- if (ci->reverse) {
- *p |= 0x00000000;
- } else {
- *p |= 0x00ffffff;
- }
- } else if (m != ' ') {
- /* edge */
- if (ci->reverse) {
- *p |= 0x00ffffff;
- } else {
- *p |= 0x00000000;
- }
- }
- k++;
- }
- }
-
- rfb_curs = pixels2curs(pixels, w, h, ci->sx, ci->sy,
- bpp/8);
-
- free(pixels);
-
- } else {
-
- /* standard X cursor */
- rfb_curs = rfbMakeXCursor(ci->wx, ci->wy,
- ci->data, ci->mask);
-
- if (ci->reverse) {
- rfb_curs->foreRed = 0x0000;
- rfb_curs->foreGreen = 0x0000;
- rfb_curs->foreBlue = 0x0000;
- rfb_curs->backRed = 0xffff;
- rfb_curs->backGreen = 0xffff;
- rfb_curs->backBlue = 0xffff;
- }
- rfb_curs->alphaSource = NULL;
-
- rfb_curs->xhot = ci->sx;
- rfb_curs->yhot = ci->sy;
- rfb_curs->cleanup = FALSE;
- rfb_curs->cleanupSource = FALSE;
- rfb_curs->cleanupMask = FALSE;
- rfb_curs->cleanupRichSource = FALSE;
-
- if (bpp == 8 && indexed_color) {
- /*
- * use richsource in PseudoColor for better
- * looking cursors (i.e. two-color).
- */
- int x, y, k = 0, bw;
- int black = 0, white = 1;
- char d, m;
-
- if (dpy) { /* raw_fb hack */
- black = BlackPixel(dpy, scr);
- white = WhitePixel(dpy, scr);
- }
-
- rfb_curs->richSource = (unsigned char *)
- calloc(ci->wx * ci->wy, 1);
-
- for (y = 0; y < ci->wy; y++) {
- for (x = 0; x < ci->wx; x++) {
- d = *(ci->data + k);
- m = *(ci->mask + k);
- if (d == ' ' && m == ' ') {
- k++;
- continue;
- } else if (m != ' ' && d == ' ') {
- bw = black;
- } else {
- bw = white;
- }
- if (ci->reverse) {
- if (bw == black) {
- bw = white;
- } else {
- bw = black;
- }
- }
- *(rfb_curs->richSource+k) =
- (unsigned char) bw;
- k++;
- }
- }
- }
- }
- ci->rfb = rfb_curs;
- }
- if (screen) {
- UNLOCK(screen->cursorMutex);
- }
- if (verbose) {
- rfbLog(" done.\n");
- }
- rfbLog("\n");
-}
-
-void setup_cursors_and_push(void) {
- setup_cursors();
- first_cursor();
-}
-
-/*
- * Descends window tree at pointer until the window cursor matches the current
- * cursor. So far only used to detect if mouse is on root background or not.
- * (returns 0 in that case, 1 otherwise).
- *
- */
-static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!depth || !w || !winfo) {}
- return;
-#else
- Window r, c;
- int i, rx, ry, wx, wy;
- unsigned int mask;
- Window wins[10];
- int descend, maxtries = 10;
- char *name, *s = multiple_cursors_mode;
- static XClassHint *classhint = NULL;
- int nm_info = 1;
- XErrorHandler old_handler;
-
- RAWFB_RET_VOID
-
- if (!strcmp(s, "default") || !strcmp(s, "X") || !strcmp(s, "arrow")) {
- nm_info = 0;
- }
-
- *(winfo->wm_name) = '\0';
- *(winfo->res_name) = '\0';
- *(winfo->res_class) = '\0';
-
- for (i=0; i < maxtries; i++) {
- wins[i] = None;
- }
-
- /* some times a window can go away before we get to it */
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
-
- c = window;
- descend = -1;
-
- while (c) {
- wins[++descend] = c;
- if (descend >= maxtries - 1) {
- break;
- }
- if ( XTestCompareCurrentCursorWithWindow_wr(dpy, c) ) {
- break;
- }
- /* TBD: query_pointer() */
- XQueryPointer_wr(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &mask);
- }
-
- if (nm_info) {
- int got_wm_name = 0, got_res_name = 0, got_res_class = 0;
-
- if (! classhint) {
- classhint = XAllocClassHint();
- }
-
- for (i = descend; i >=0; i--) {
- c = wins[i];
- if (! c) {
- continue;
- }
-
- if (! got_wm_name && XFetchName(dpy, c, &name)) {
- if (name) {
- if (*name != '\0') {
- strcpy(winfo->wm_name, name);
- got_wm_name = 1;
- }
- XFree_wr(name);
- }
- }
- if (classhint && (! got_res_name || ! got_res_class)) {
- if (XGetClassHint(dpy, c, classhint)) {
- char *p;
- p = classhint->res_name;
- if (p) {
- if (*p != '\0' && ! got_res_name) {
- strcpy(winfo->res_name, p);
- got_res_name = 1;
- }
- XFree_wr(p);
- classhint->res_name = NULL;
- }
- p = classhint->res_class;
- if (p) {
- if (*p != '\0' && ! got_res_class) {
- strcpy(winfo->res_class, p);
- got_res_class = 1;
- }
- XFree_wr(p);
- classhint->res_class = NULL;
- }
- }
- }
- }
- }
-
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
-
- *depth = descend;
- *w = wins[descend];
-#endif /* NO_X11 */
-}
-
-void initialize_xfixes(void) {
-#if LIBVNCSERVER_HAVE_LIBXFIXES
- if (xfixes_present) {
- X_LOCK;
- if (use_xfixes) {
- XFixesSelectCursorInput(dpy, rootwin,
- XFixesDisplayCursorNotifyMask);
- } else {
- XFixesSelectCursorInput(dpy, rootwin, 0);
- }
- X_UNLOCK;
- xfixes_first_initialized = 1;
- }
-#endif
-}
-
-static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
- int xhot, int yhot, int Bpp) {
- rfbCursorPtr c;
- static unsigned long black = 0, white = 1;
- static int first = 1;
- char *bitmap, *rich, *alpha;
- char *pixels_new = NULL;
- int n_opaque, n_trans, n_alpha, len, histo[256];
- int send_alpha = 0, alpha_shift = 0, thresh;
- int i, x, y;
-
- if (first && dpy) { /* raw_fb hack */
- X_LOCK;
- black = BlackPixel(dpy, scr);
- white = WhitePixel(dpy, scr);
- X_UNLOCK;
- first = 0;
- }
-
- if (cmap8to24 && cmap8to24_fb && depth <= 16) {
- if (Bpp <= 2) {
- Bpp = 4;
- }
- }
-
- if (scaling_cursor && (scale_cursor_fac_x != 1.0 || scale_cursor_fac_y != 1.0)) {
- int W, H;
- char *pixels_use = (char *) pixels;
- unsigned int *pixels32 = NULL;
-
- W = w;
- H = h;
-
- w = scale_round(W, scale_cursor_fac_x);
- h = scale_round(H, scale_cursor_fac_y);
-
- pixels_new = (char *) malloc(4*w*h);
-
- if (sizeof(unsigned long) == 8) {
- int i, j, k = 0;
- /*
- * to avoid 64bpp code in scale_rect() we knock
- * down to unsigned int on 64bit machines:
- */
- pixels32 = (unsigned int*) malloc(4*W*H);
- for (j=0; j<H; j++) {
- for (i=0; i<W; i++) {
- *(pixels32+k) = 0xffffffff & (*(pixels+k));
- k++;
- }
- }
- pixels_use = (char *) pixels32;
- }
-
- scale_rect(scale_cursor_fac_x, scale_cursor_fac_y, scaling_cursor_blend,
- scaling_cursor_interpolate,
- 4, pixels_use, 4*W, pixels_new, 4*w,
- W, H, w, h, 0, 0, W, H, 0);
-
- if (sizeof(unsigned long) == 8) {
- int i, j, k = 0;
- unsigned long *pixels64;
- unsigned int* source = (unsigned int*) pixels_new;
- /*
- * now knock it back up to unsigned long:
- */
- pixels64 = (unsigned long*) malloc(8*w*h);
- for (j=0; j<h; j++) {
- for (i=0; i<w; i++) {
- *(pixels64+k) = (unsigned long) (*(source+k));
- k++;
- }
- }
- free(pixels_new);
- pixels_new = (char *) pixels64;
- if (pixels32) {
- free(pixels32);
- pixels32 = NULL;
- }
- }
-
- pixels = (unsigned long *) pixels_new;
-
- xhot = scale_round(xhot, scale_cursor_fac_x);
- yhot = scale_round(yhot, scale_cursor_fac_y);
- }
-
- len = w * h;
- /* for bitmap data */
- bitmap = (char *) malloc(len+1);
- bitmap[len] = '\0';
-
- /* for rich cursor pixel data */
- rich = (char *)calloc(Bpp*len, 1);
- alpha = (char *)calloc(1*len, 1);
-
- n_opaque = 0;
- n_trans = 0;
- n_alpha = 0;
- for (i=0; i<256; i++) {
- histo[i] = 0;
- }
-
- i = 0;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- unsigned long a;
-
- a = 0xff000000 & (*(pixels+i));
- a = a >> 24; /* alpha channel */
- if (a > 0) {
- n_alpha++;
- }
- histo[a]++;
- if (a < (unsigned int) alpha_threshold) {
- n_trans++;
- } else {
- n_opaque++;
- }
- i++;
- }
- }
- if (alpha_blend) {
- send_alpha = 0;
- if (Bpp == 4) {
- send_alpha = 1;
- }
- alpha_shift = 24;
- if (main_red_shift == 24 || main_green_shift == 24 ||
- main_blue_shift == 24) {
- alpha_shift = 0; /* XXX correct? */
- }
- }
- if (n_opaque >= alpha_frac * n_alpha) {
- thresh = alpha_threshold;
- } else {
- n_opaque = 0;
- for (i=255; i>=0; i--) {
- n_opaque += histo[i];
- thresh = i;
- if (n_opaque >= alpha_frac * n_alpha) {
- break;
- }
- }
- }
-
- i = 0;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- unsigned long r, g, b, a;
- unsigned int ui;
- char *p;
-
- a = 0xff000000 & (*(pixels+i));
- a = a >> 24; /* alpha channel */
-
- if (a < (unsigned int) thresh) {
- bitmap[i] = ' ';
- } else {
- bitmap[i] = 'x';
- }
-
- r = 0x00ff0000 & (*(pixels+i));
- g = 0x0000ff00 & (*(pixels+i));
- b = 0x000000ff & (*(pixels+i));
- r = r >> 16; /* red */
- g = g >> 8; /* green */
- b = b >> 0; /* blue */
-
- if (alpha_remove && a != 0) {
- r = (255 * r) / a;
- g = (255 * g) / a;
- b = (255 * b) / a;
- if (r > 255) r = 255;
- if (g > 255) g = 255;
- if (b > 255) b = 255;
- }
-
- if (indexed_color) {
- /*
- * Choose black or white for
- * PseudoColor case.
- */
- int value = (r+g+b)/3;
- if (value > 127) {
- ui = white;
- } else {
- ui = black;
- }
- } else {
- /*
- * Otherwise map the RGB data onto
- * the framebuffer format:
- */
- r = (main_red_max * r)/255;
- g = (main_green_max * g)/255;
- b = (main_blue_max * b)/255;
- ui = 0;
- ui |= (r << main_red_shift);
- ui |= (g << main_green_shift);
- ui |= (b << main_blue_shift);
- if (send_alpha) {
- ui |= (a << alpha_shift);
- }
- }
-
- /* insert value into rich source: */
- p = rich + Bpp*i;
-
- if (Bpp == 1) {
- *((unsigned char *)p)
- = (unsigned char) ui;
- } else if (Bpp == 2) {
- *((unsigned short *)p)
- = (unsigned short) ui;
- } else if (Bpp == 3) {
- *((unsigned char *)p)
- = (unsigned char) ((ui & 0x0000ff) >> 0);
- *((unsigned char *)(p+1))
- = (unsigned char) ((ui & 0x00ff00) >> 8);
- *((unsigned char *)(p+2))
- = (unsigned char) ((ui & 0xff0000) >> 16);
- } else if (Bpp == 4) {
- *((unsigned int *)p)
- = (unsigned int) ui;
- }
-
- /* insert alpha value into alpha source: */
- p = alpha + i;
- *((unsigned char *)p) = (unsigned char) a;
-
- i++;
- }
- }
-
- /* create the cursor with the bitmap: */
- c = rfbMakeXCursor(w, h, bitmap, bitmap);
- free(bitmap);
-
- if (pixels_new) {
- free(pixels_new);
- }
-
- /* set up the cursor parameters: */
- c->xhot = xhot;
- c->yhot = yhot;
- c->cleanup = FALSE;
- c->cleanupSource = FALSE;
- c->cleanupMask = FALSE;
- c->cleanupRichSource = FALSE;
- c->richSource = (unsigned char *) rich;
-
- /* zeroes mean interpolate the rich cursor somehow and use B+W */
- c->foreRed = 0;
- c->foreGreen = 0;
- c->foreBlue = 0;
- c->backRed = 0;
- c->backGreen = 0;
- c->backBlue = 0;
-
- c->source = NULL;
-
- if (alpha_blend && !indexed_color) {
- c->alphaSource = (unsigned char *) alpha;
- c->alphaPreMultiplied = TRUE;
- } else {
- free(alpha);
- c->alphaSource = NULL;
- }
- return c;
-}
-
-static unsigned long last_cursor = 0;
-static int last_index = 0;
-static time_t curs_times[CURS_MAX];
-static unsigned long curs_index[CURS_MAX];
-
-unsigned long get_cursor_serial(int mode) {
- if (mode == 0) {
- return last_cursor;
- } else if (mode == 1) {
- return (unsigned long) last_index;
- } else {
- return (unsigned long) last_index;
- }
-}
-
-static int get_exact_cursor(int init) {
- int which = CURS_ARROW;
-
- if (init) {
- /* zero out our cache (cursors are not freed) */
- int i;
- for (i=0; i<CURS_MAX; i++) {
- curs_times[i] = 0;
- curs_index[i] = 0;
- }
- last_cursor = 0;
- last_index = 0;
- return -1;
- }
-
-#ifdef MACOSX
- if (macosx_console) {
- return macosx_get_cursor();
- }
-#endif
-
- if (rawfb_vnc_reflect) {
- int last_idx = (int) get_cursor_serial(1);
- if (last_idx) {
- which = last_idx;
- }
- return which;
- }
- if (xfixes_present && dpy) {
-#if LIBVNCSERVER_HAVE_LIBXFIXES
- int last_idx = (int) get_cursor_serial(1);
- XFixesCursorImage *xfc;
-
- if (last_idx) {
- which = last_idx;
- }
- if (! xfixes_first_initialized) {
- return which;
- }
-
- X_LOCK;
- if (! got_xfixes_cursor_notify && xfixes_base_event_type) {
- /* try again for XFixesCursorNotify event */
- XEvent xev;
- if (XCheckTypedEvent(dpy, xfixes_base_event_type +
- XFixesCursorNotify, &xev)) {
- got_xfixes_cursor_notify++;
- }
- }
- if (! got_xfixes_cursor_notify) {
- /* evidently no cursor change, just return last one */
- X_UNLOCK;
- return which;
- }
- got_xfixes_cursor_notify = 0;
-
- /* retrieve the cursor info + pixels from server: */
- xfc = XFixesGetCursorImage(dpy);
- X_UNLOCK;
- if (! xfc) {
- /* failure. */
- return which;
- }
-
- which = store_cursor(xfc->cursor_serial, xfc->pixels,
- xfc->width, xfc->height, 32, xfc->xhot, xfc->yhot);
-
- X_LOCK;
- XFree_wr(xfc);
- X_UNLOCK;
-#endif
- }
- return(which);
-}
-
-int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp,
- int xhot, int yhot) {
- int which = CURS_ARROW;
- int use, oldest, i;
- time_t oldtime, now;
-
-#if 0
-fprintf(stderr, "sc: %d %d/%d %d - %d %d\n", serial, w, h, cbpp, xhot, yhot);
-#endif
-
- oldest = CURS_DYN_MIN;
- if (screen && screen->cursor == cursors[oldest]->rfb) {
- oldest++;
- }
- oldtime = curs_times[oldest];
- now = time(NULL);
- for (i = CURS_DYN_MIN; i <= CURS_DYN_MAX; i++) {
- if (screen && screen->cursor == cursors[i]->rfb) {
- ;
- } else if (curs_times[i] < oldtime) {
- /* watch for oldest one to overwrite */
- oldest = i;
- oldtime = curs_times[i];
- }
- if (serial == (int) curs_index[i]) {
- /*
- * got a hit with an existing cursor,
- * use that one.
- */
-#ifdef MACOSX
- if (now > curs_times[i] + 1) {
- continue;
- }
-#endif
- last_cursor = curs_index[i];
- curs_times[i] = now;
- last_index = i;
- return last_index;
- }
- }
-
- /* we need to create the cursor and overwrite oldest */
- use = oldest;
- if (cursors[use]->rfb) {
- /* clean up oldest if it exists */
- if (cursors[use]->rfb->richSource) {
- free(cursors[use]->rfb->richSource);
- cursors[use]->rfb->richSource = NULL;
- }
- if (cursors[use]->rfb->alphaSource) {
- free(cursors[use]->rfb->alphaSource);
- cursors[use]->rfb->alphaSource = NULL;
- }
- if (cursors[use]->rfb->source) {
- free(cursors[use]->rfb->source);
- cursors[use]->rfb->source = NULL;
- }
- if (cursors[use]->rfb->mask) {
- free(cursors[use]->rfb->mask);
- cursors[use]->rfb->mask = NULL;
- }
- free(cursors[use]->rfb);
- cursors[use]->rfb = NULL;
- }
-
- if (rotating && rotating_cursors) {
- char *dst;
- int tx, ty;
-
- dst = (char *) malloc(w * h * cbpp/8);
- rotate_curs(dst, (char *) data, w, h, cbpp/8);
-
- memcpy(data, dst, w * h * cbpp/8);
- free(dst);
-
- rotate_coords(xhot, yhot, &tx, &ty, w, h);
- xhot = tx;
- yhot = ty;
- if (! rotating_same) {
- int tmp = w;
- w = h;
- h = tmp;
- }
- }
-
- /* place cursor into our collection */
- cursors[use]->rfb = pixels2curs(data, w, h, xhot, yhot, bpp/8);
-
- /* update time and serial index: */
- curs_times[use] = now;
- curs_index[use] = serial;
- last_index = use;
- last_cursor = serial;
-
- which = last_index;
-
- return which;
-}
-
-int known_cursors_mode(char *s) {
-/*
- * default: see initialize_cursors_mode() for default behavior.
- * arrow: unchanging white arrow.
- * Xn*: show X on root background. Optional n sets treedepth.
- * some: do the heuristics for root, wm, term detection.
- * most: if display have overlay or xfixes, show all cursors,
- * otherwise do the same as "some"
- * none: show no cursor.
- */
- if (strcmp(s, "default") && strcmp(s, "arrow") && *s != 'X' &&
- strcmp(s, "some") && strcmp(s, "most") && strcmp(s, "none")) {
- return 0;
- } else {
- return 1;
- }
-}
-
-void initialize_cursors_mode(void) {
- char *s = multiple_cursors_mode;
- if (!s || !known_cursors_mode(s)) {
- rfbLog("unknown cursors mode: %s\n", s);
- rfbLog("resetting cursors mode to \"default\"\n");
- if (multiple_cursors_mode) free(multiple_cursors_mode);
- multiple_cursors_mode = strdup("default");
- s = multiple_cursors_mode;
- }
- if (!strcmp(s, "none")) {
- show_cursor = 0;
- } else {
- /* we do NOT set show_cursor = 1, let the caller do that */
- }
-
- show_multiple_cursors = 0;
- if (show_cursor) {
- if (!strcmp(s, "default")) {
- if(multiple_cursors_mode) free(multiple_cursors_mode);
- multiple_cursors_mode = strdup("X");
- s = multiple_cursors_mode;
- }
- if (*s == 'X' || !strcmp(s, "some") || !strcmp(s, "most")) {
- show_multiple_cursors = 1;
- } else {
- show_multiple_cursors = 0;
- /* hmmm, some bug going back to arrow mode.. */
- set_rfb_cursor(CURS_ARROW);
- }
- if (screen) {
- set_cursor_was_changed(screen);
- }
- } else {
- if (screen) {
- LOCK(screen->cursorMutex);
- screen->cursor = NULL;
- UNLOCK(screen->cursorMutex);
- set_cursor_was_changed(screen);
- }
- }
-}
-
-int get_which_cursor(void) {
- int which = CURS_ARROW;
- int db = 0;
-
- if (show_multiple_cursors) {
- int depth = 0, rint;
- static win_str_info_t winfo;
- static int first = 1, depth_cutoff = -1;
- Window win = None;
- XErrorHandler old_handler;
- int mode = 0;
-
- if (drag_in_progress || button_mask) {
- /* XXX not exactly what we want for menus */
- if (! cursor_drag_changes) {
- return -1;
- }
- }
-
- if (!strcmp(multiple_cursors_mode, "arrow")) {
- /* should not happen... */
- return CURS_ARROW;
- } else if (!strcmp(multiple_cursors_mode, "default")) {
- mode = 0;
- } else if (!strcmp(multiple_cursors_mode, "X")) {
- mode = 1;
- } else if (!strcmp(multiple_cursors_mode, "some")) {
- mode = 2;
- } else if (!strcmp(multiple_cursors_mode, "most")) {
- mode = 3;
- }
-
- if (rawfb_vnc_reflect && mode > -1) {
- rint = get_exact_cursor(0);
- return rint;
- }
- if (mode == 3) {
- if ((xfixes_present && use_xfixes) || macosx_console) {
- if (db) fprintf(stderr, "get_which_cursor call get_exact_cursor\n");
- rint = get_exact_cursor(0);
- return rint;
- }
- }
-
- if (depth_cutoff < 0) {
- int din;
- if (sscanf(multiple_cursors_mode, "X%d", &din) == 1) {
- depth_cutoff = din;
- } else {
- depth_cutoff = 0;
- }
- }
-
- if (first) {
- winfo.wm_name = (char *) malloc(1024);
- winfo.res_name = (char *) malloc(1024);
- winfo.res_class = (char *) malloc(1024);
- }
- first = 0;
-
- X_LOCK;
- tree_descend_cursor(&depth, &win, &winfo);
- X_UNLOCK;
-
- if (depth <= depth_cutoff && !subwin) {
- which = CURS_ROOT;
-
- } else if (mode == 2 || mode == 3) {
- int which0 = which;
-
- /* apply crude heuristics to choose a cursor... */
- if (win && dpy) {
- int ratio = 10, x, y;
- unsigned int w, h, bw, d;
- Window r;
-
-#if !NO_X11
- trapped_xerror = 0;
- X_LOCK;
- old_handler = XSetErrorHandler(trap_xerror);
-
- /* "narrow" windows are WM */
- if (XGetGeometry(dpy, win, &r, &x, &y, &w, &h,
- &bw, &d)) {
- if (w > ratio * h || h > ratio * w) {
- which = CURS_WM;
- }
- }
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- trapped_xerror = 0;
-#else
- if (!r || !d || !bw || !h || !w || !y || !x || !ratio || !old_handler) {}
-#endif /* NO_X11 */
- }
- if (which == which0) {
- /* the string "term" means I-beam. */
- char *name, *class;
- lowercase(winfo.res_name);
- lowercase(winfo.res_class);
- name = winfo.res_name;
- class = winfo.res_class;
- if (strstr(name, "term")) {
- which = CURS_TERM;
- } else if (strstr(class, "term")) {
- which = CURS_TERM;
- } else if (strstr(name, "text")) {
- which = CURS_TERM;
- } else if (strstr(class, "text")) {
- which = CURS_TERM;
- } else if (strstr(name, "onsole")) {
- which = CURS_TERM;
- } else if (strstr(class, "onsole")) {
- which = CURS_TERM;
- } else if (strstr(name, "cmdtool")) {
- which = CURS_TERM;
- } else if (strstr(class, "cmdtool")) {
- which = CURS_TERM;
- } else if (strstr(name, "shelltool")) {
- which = CURS_TERM;
- } else if (strstr(class, "shelltool")) {
- which = CURS_TERM;
- }
- }
- }
- }
- if (db) fprintf(stderr, "get_which_cursor which: %d\n", which);
- return which;
-}
-
-static void set_cursor_was_changed(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- if (! s) {
- return;
- }
- iter = rfbGetClientIterator(s);
- LOCK(screen->cursorMutex);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- cl->cursorWasChanged = TRUE;
- }
- UNLOCK(screen->cursorMutex);
- rfbReleaseClientIterator(iter);
-}
-
-#if 0
-/* not yet used */
-static void set_cursor_was_moved(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- if (! s) {
- return;
- }
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- cl->cursorWasMoved = TRUE;
- }
- rfbReleaseClientIterator(iter);
-}
-#endif
-
-void restore_cursor_shape_updates(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int count = 0;
-
- if (! s || ! s->clientHead) {
- return;
- }
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- int changed = 0;
- ClientData *cd = (ClientData *) cl->clientData;
-
- if (! cd) {
- continue;
- }
- if (cd->had_cursor_shape_updates) {
- rfbLog("restoring enableCursorShapeUpdates for client"
- " 0x%x\n", cl);
- cl->enableCursorShapeUpdates = TRUE;
- changed = 1;
- }
- if (cd->had_cursor_pos_updates) {
- rfbLog("restoring enableCursorPosUpdates for client"
- " 0x%x\n", cl);
- cl->enableCursorPosUpdates = TRUE;
- changed = 1;
- }
- if (changed) {
- cl->cursorWasChanged = TRUE;
- count++;
- }
- }
- rfbReleaseClientIterator(iter);
-}
-
-void disable_cursor_shape_updates(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- static int changed = 0;
- int count = 0;
-
- if (! s || ! s->clientHead) {
- return;
- }
- if (unixpw_in_progress) return;
-
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd;
- cd = (ClientData *) cl->clientData;
-
- if (cl->enableCursorShapeUpdates) {
- if (cd) {
- cd->had_cursor_shape_updates = 1;
- }
- count++;
- if (debug_pointer) {
- rfbLog("%s disable HCSU\n", cl->host);
- }
- }
- if (cl->enableCursorPosUpdates) {
- if (cd) {
- cd->had_cursor_pos_updates = 1;
- }
- count++;
- if (debug_pointer) {
- rfbLog("%s disable HCPU\n", cl->host);
- }
- }
-
- cl->enableCursorShapeUpdates = FALSE;
- cl->enableCursorPosUpdates = FALSE;
- cl->cursorWasChanged = FALSE;
- }
- rfbReleaseClientIterator(iter);
-
- if (count) {
- changed = 1;
- }
-}
-
-int cursor_shape_updates_clients(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int count = 0;
-
- if (! s) {
- return 0;
- }
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (cl->enableCursorShapeUpdates) {
- count++;
- }
- }
- rfbReleaseClientIterator(iter);
- return count;
-}
-
-int cursor_noshape_updates_clients(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int count = 0;
-
- if (! s) {
- return 0;
- }
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (!cl->enableCursorShapeUpdates) {
- count++;
- }
- }
- rfbReleaseClientIterator(iter);
- return count;
-}
-
-int cursor_pos_updates_clients(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int count = 0;
-
- if (! s) {
- return 0;
- }
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (cl->enableCursorPosUpdates) {
- count++;
- }
- }
- rfbReleaseClientIterator(iter);
- return count;
-}
-
-/*
- * Record rfb cursor position screen->cursorX, etc (a la defaultPtrAddEvent())
- * Then set up for sending rfbCursorPosUpdates back
- * to clients that understand them. This seems to be TightVNC specific.
- */
-void cursor_position(int x, int y) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int cnt = 0, nonCursorPosUpdates_clients = 0;
- int x_in = x, y_in = y;
-
- /* x and y are current positions of X11 pointer on the X11 display */
- if (!screen) {
- return;
- }
-
- if (scaling) {
- x = ((double) x / dpy_x) * scaled_x;
- x = nfix(x, scaled_x);
- y = ((double) y / dpy_y) * scaled_y;
- y = nfix(y, scaled_y);
- }
-
- if (clipshift) {
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- if (x >= dpy_x) x = dpy_x-1;
- if (y >= dpy_y) y = dpy_y-1;
- }
-
- if (x == screen->cursorX && y == screen->cursorY) {
- return;
- }
-
- LOCK(screen->cursorMutex);
- screen->cursorX = x;
- screen->cursorY = y;
- UNLOCK(screen->cursorMutex);
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (! cl->enableCursorPosUpdates) {
- nonCursorPosUpdates_clients++;
- continue;
- }
- if (! cursor_pos_updates) {
- continue;
- }
- if (cl == last_pointer_client) {
- /*
- * special case if this client was the last one to
- * send a pointer position.
- */
- if (x_in == cursor_x && y_in == cursor_y) {
- cl->cursorWasMoved = FALSE;
- } else {
- /* an X11 app evidently warped the pointer */
- if (debug_pointer) {
- rfbLog("cursor_position: warp "
- "detected dx=%3d dy=%3d\n",
- cursor_x - x, cursor_y - y);
- }
- cl->cursorWasMoved = TRUE;
- cnt++;
- }
- } else {
- cl->cursorWasMoved = TRUE;
- cnt++;
- }
- }
- rfbReleaseClientIterator(iter);
-
- if (debug_pointer && cnt) {
- rfbLog("cursor_position: sent position x=%3d y=%3d to %d"
- " clients\n", x, y, cnt);
- }
-}
-
-static void set_rfb_cursor(int which) {
-
- if (! show_cursor) {
- return;
- }
- if (! screen) {
- return;
- }
-
- if (!cursors[which] || !cursors[which]->rfb) {
- rfbLog("non-existent cursor: which=%d\n", which);
- return;
- } else {
- rfbSetCursor(screen, cursors[which]->rfb);
- }
-}
-
-void set_no_cursor(void) {
- set_rfb_cursor(CURS_EMPTY);
-}
-
-void set_warrow_cursor(void) {
- set_rfb_cursor(CURS_WARROW);
-}
-
-int set_cursor(int x, int y, int which) {
- static int last = -1;
- int changed_cursor = 0;
-
- if (x || y) {} /* unused vars warning: */
-
- if (which < 0) {
- which = last;
- }
- if (last < 0 || which != last) {
- set_rfb_cursor(which);
- changed_cursor = 1;
- }
- last = which;
-
- return changed_cursor;
-}
-
-/*
- * routine called periodically to update cursor aspects, this catches
- * warps and cursor shape changes.
- */
-int check_x11_pointer(void) {
- Window root_w, child_w;
- rfbBool ret = 0;
- int root_x, root_y, win_x, win_y;
- int x, y, rint;
- unsigned int mask;
-
- if (unixpw_in_progress) return 0;
-
-#ifdef MACOSX
- if (macosx_console) {
- ret = macosx_get_cursor_pos(&root_x, &root_y);
- } else {
- RAWFB_RET(0)
- }
-#else
-
- RAWFB_RET(0)
-
-# if NO_X11
- return 0;
-# endif
-
-#endif
-
-
-#if ! NO_X11
- if (dpy) {
- X_LOCK;
- ret = XQueryPointer_wr(dpy, rootwin, &root_w, &child_w, &root_x, &root_y,
- &win_x, &win_y, &mask);
- X_UNLOCK;
- }
-#else
- if (!mask || !win_y || !win_x || !child_w || !root_w) {}
-#endif /* NO_X11 */
-
-if (0) fprintf(stderr, "check_x11_pointer %d %d\n", root_x, root_y);
- if (! ret) {
- return 0;
- }
- if (debug_pointer) {
- static int last_x = -1, last_y = -1;
- if (root_x != last_x || root_y != last_y) {
- rfbLog("XQueryPointer: x:%4d, y:%4d)\n",
- root_x, root_y);
- }
- last_x = root_x;
- last_y = root_y;
- }
-
- /* offset subtracted since XQueryPointer relative to rootwin */
- x = root_x - off_x - coff_x;
- y = root_y - off_y - coff_y;
-
- if (clipshift) {
- static int cnt = 0;
- if (x < 0 || y < 0 || x >= dpy_x || y >= dpy_y) {
- if (cnt++ % 4 != 0) {
- if (debug_pointer) {
- rfbLog("Skipping cursor_position() outside our clipshift\n");
- }
- return 0;
- }
- }
- }
-
- /* record the cursor position in the rfb screen */
- cursor_position(x, y);
-
- /* change the cursor shape if necessary */
- rint = set_cursor(x, y, get_which_cursor());
- return rint;
-}
-
diff --git a/x11vnc/cursor.h b/x11vnc/cursor.h
deleted file mode 100644
index 9c74944..0000000
--- a/x11vnc/cursor.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_CURSOR_H
-#define _X11VNC_CURSOR_H
-
-/* -- cursor.h -- */
-
-extern int xfixes_present;
-extern int xfixes_first_initialized;
-extern int use_xfixes;
-extern int got_xfixes_cursor_notify;
-extern int cursor_changes;
-extern int alpha_threshold;
-extern double alpha_frac;
-extern int alpha_remove;
-extern int alpha_blend;
-extern int alt_arrow;
-extern int alt_arrow_max;
-
-
-extern void first_cursor(void);
-extern void setup_cursors_and_push(void);
-extern void initialize_xfixes(void);
-extern int known_cursors_mode(char *s);
-extern void initialize_cursors_mode(void);
-extern int get_which_cursor(void);
-extern void restore_cursor_shape_updates(rfbScreenInfoPtr s);
-extern void disable_cursor_shape_updates(rfbScreenInfoPtr s);
-extern int cursor_shape_updates_clients(rfbScreenInfoPtr s);
-extern int cursor_noshape_updates_clients(rfbScreenInfoPtr s);
-extern int cursor_pos_updates_clients(rfbScreenInfoPtr s);
-extern void cursor_position(int x, int y);
-extern void set_no_cursor(void);
-extern void set_warrow_cursor(void);
-extern int set_cursor(int x, int y, int which);
-extern int check_x11_pointer(void);
-extern int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp, int xhot, int yhot);
-extern unsigned long get_cursor_serial(int mode);
-
-#endif /* _X11VNC_CURSOR_H */
diff --git a/x11vnc/enc.h b/x11vnc/enc.h
deleted file mode 100644
index 55d49bb..0000000
--- a/x11vnc/enc.h
+++ /dev/null
@@ -1,2165 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_ENC_H
-#define _X11VNC_ENC_H
-
-/* -- enc.h -- */
-
-#if 0
-:r /home/runge/uvnc/ultraSC/rc4/ultravnc_dsm_helper.c
-#endif
-
-/*
- * ultravnc_dsm_helper.c unix/openssl UltraVNC encryption encoder/decoder.
- * (also a generic symmetric encryption tunnel)
- * (also a generic TCP relay and supports IPv6)
- *
- * compile via:
-
- cc -O -o ultravnc_dsm_helper ultravnc_dsm_helper.c -lssl -lcrypto
- cc -DDBG -O -o ultravnc_dsm_helper ultravnc_dsm_helper.c -lssl -lcrypto
-
- *
- * See usage below for how to run it.
- *
- * Note: since the UltraVNC DSM plugin implementation changes the RFB
- * (aka VNC) protocol (extra data is sent), you will *ALSO* need to modify
- * your VNC viewer or server to discard (or insert) this extra data.
- *
- * This tool knows nothing about the RFB protocol: it simply
- * encrypts/decrypts a stream using a symmetric cipher, arc4 and aesv2,
- * (others have been added, see usage). It could be used as a general
- * encrypted tunnel:
- *
- * any-client <=> ultravnc_dsm_helper <--network--> ultravnc_dsm_helper(reverse mode) <=> any-server
- *
- * e.g. to connect a non-ultra-dsm-vnc viewer to a non-ultra-dsm-vnc server
- * without using SSH or SSL.
- *
- * It can also be used as a general TCP relay (no encryption.)
- *
- * It supports IPv6 and so can also be used as a IPv6 gateway.
- *
- * -----------------------------------------------------------------------
- * Copyright (C) 2008-2010 Karl J. Runge <runge@karlrunge.com>
- * All rights reserved.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License, or (at
- * your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA or see <http://www.gnu.org/licenses/>.
- *
- * In addition, as a special exception, Karl J. Runge gives permission
- * to link the code of its release of ultravnc_dsm_helper with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify this file, you may extend this exception to your version of the
- * file, but you are not obligated to do so. If you do not wish to do
- * so, delete this exception statement from your version.
- * -----------------------------------------------------------------------
- */
-
-static char *usage =
- "\n"
- "ultravnc_dsm_helper: a symmetric encryption tunnel. version 0.2\n"
- "\n"
- " Created to enable encrypted VNC connections to UltraVNC, it can act as\n"
- " a general encrypted tunnel between any two applications. It can also\n"
- " be used as a general TCP relay (i.e. no encryption) or an IPv6 gateway.\n"
- "\n"
- "Usage: ultravnc_dsm_helper cipher keyfile listenport remotehost:port\n"
- " ultravnc_dsm_helper relay listenport remotehost:port\n"
- " ultravnc_dsm_helper showcert remotehost:port\n"
- "\n"
- "e.g.: ultravnc_dsm_helper arc4 ./arc4.key 5901 snoopy.net:5900\n"
- "\n"
- " IPv6 is supported: both IPv4 and IPv6 are attempted to listen on (port\n"
- " 'listenport'.) For connections to remotehost, if IPv4 fails\n"
- " then IPv6 is tried. Set the env. var ULTRAVNC_DSM_HELPER_NOIPV6\n"
- " to completely disable the use of IPv6.\n"
- "\n"
- "\n"
- " cipher: specify 'msrc4', 'msrc4_sc', 'arc4', 'aesv2', 'aes-cfb',\n"
- " 'aes256', 'blowfish', '3des', 'securevnc'.\n"
- "\n"
- " Also 'none', 'relay', or 'showcert'. See below for details.\n"
- "\n"
- " 'msrc4_sc' enables a workaround for UVNC SC -plugin use.\n"
- " (it might not be required in SC circa 2009 and later; try 'msrc4'.)\n"
- "\n"
- " use 'securevnc' for SecureVNCPlugin (RSA key exchange). 'keyfile' is\n"
- " used as a server RSA keystore in this mode. If 'keyfile' does not\n"
- " exist the user is prompted whether to save the key or not (a MD5\n"
- " hash of it is shown) If 'keyfile' already exists the server key\n"
- " must match its contents or the connection is dropped.\n"
- "\n"
- " HOWEVER, if 'keyfile' ends in the string 'ClientAuth.pkey', then the\n"
- " normal SecureVNCPlugin client key authentication is performed.\n"
- " If you want to do both have 'keyfile' end with 'ClientAuth.pkey.rsa'\n"
- " that file will be used for the RSA keystore, and the '.rsa' will be\n"
- " trimmed off and the remaining name used as the Client Auth file.\n"
- "\n"
- " use '.' to have it try to guess the cipher from the keyfile name,\n"
- " e.g. 'arc4.key' implies arc4, 'rc4.key' implies msrc4, etc.\n"
- "\n"
- " use 'rev:arc4', etc. to reverse the roles of encrypter and decrypter.\n"
- " (i.e. if you want to use it for a vnc server, not vnc viewer)\n"
- "\n"
- " use 'noultra:...' to skip steps involving salt and IV to try to be\n"
- " compatible with UltraVNC DSM, i.e. assume a normal symmetric cipher\n"
- " at the other end.\n"
- "\n"
- " use 'noultra:rev:...' if both are to be supplied.\n"
- "\n"
- "\n"
- " keyfile: file holding the key (16 bytes for arc4 and aesv2, 87 for msrc4)\n"
- " E.g. dd if=/dev/random of=./my.key bs=16 count=1\n"
- " keyfile can also be pw=<string> to use \"string\" for the key.\n"
- " Or for 'securevnc' the RSA keystore and/or ClientAuth file.\n"
- "\n"
- "\n"
- " listenport: port to listen for incoming connection on. (use 0 to connect\n"
- " to stdio, use a negative value to force localhost listening)\n"
- "\n"
- "\n"
- " remotehost:port: host and port to connect to. (e.g. ultravnc server)\n"
- "\n"
- "\n"
- " Also: cipher may be cipher@n,m where n is the salt size and m is the\n"
- " initialization vector size. E.g. aesv2@8,16 Use n=-1 to disable salt\n"
- " and the MD5 hash (i.e. insert the keydata directly into the cipher.)\n"
- "\n"
- " Use cipher@md+n,m to change the message digest. E.g. arc4@sha+8,16\n"
- " Supported: 'md5', 'sha', 'sha1', 'ripemd160'.\n"
- "\n"
- "\n"
- " TCP Relay mode: to connect without any encryption use a cipher type of\n"
- " either 'relay' or 'none' (both are the equivalent):\n"
- "\n"
- " ultravnc_dsm_helper relay listenport remotehost:port\n"
- " ultravnc_dsm_helper none listenport remotehost:port\n"
- "\n"
- " where 'relay' or 'none' is a literal string.\n"
- " Note that for this mode no keyfile is suppled.\n"
- " Note that this mode can act as an IPv4 to IPv6 gateway.\n"
- "\n"
- " ultravnc_dsm_helper relay 8080 ipv6.beijing2008.cn:80\n"
- "\n"
- "\n"
- " SSL Show Certificate mode: Set the cipher to 'showcert' to fetch\n"
- " the SSL certificate from remotehost:port and print it to the stdout.\n"
- " No certificate authentication or verification is performed. E.g.\n"
- "\n"
- " ultravnc_dsm_helper showcert www.verisign.com:443\n"
- "\n"
- " (the output resembles that of 'openssl s_client ...') Set the env var\n"
- " ULTRAVNC_DSM_HELPER_SHOWCERT_ADH=1 for Anonymous Diffie Hellman mode.\n"
- "\n"
- "\n"
- " Looping Mode: Set the env. var. ULTRAVNC_DSM_HELPER_LOOP=1 to have it\n"
- " restart itself after every disconnection in an endless loop. It pauses\n"
- " 500 msec before restarting. Use ULTRAVNC_DSM_HELPER_LOOP=N to set the\n"
- " pause to N msec.\n"
- "\n"
- " You can also set the env. var. ULTRAVNC_DSM_HELPER_BG to have the\n"
- " program fork into the background for each connection, thereby acting\n"
- " as a simple daemon.\n"
-;
-
-/*
- * We can also run as a module included into x11vnc (-enc option)
- * The includer must set ENC_MODULE and ENC_HAVE_OPENSSL.
- *
- * Note that when running as a module we still assume we have been
- * forked off of the parent process and are communicating back to it
- * via a socket. So we *still* exit(3) at the end or on error. And
- * the global settings won't work.
- */
-#ifdef ENC_MODULE
-# define main __enc_main
-static char *prog = "enc_helper";
-#else
-# define ENC_HAVE_OPENSSL 1
-static char *prog = "ultravnc_dsm_helper";
-#endif
-
-/* unix includes */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include <string.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-
-/* Solaris (sysv?) needs INADDR_NONE */
-#ifndef INADDR_NONE
-#define INADDR_NONE ((in_addr_t) 0xffffffff)
-#endif
-
-/* openssl includes */
-#if ENC_HAVE_OPENSSL
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <openssl/rsa.h>
-#include <openssl/err.h>
-#include <openssl/ssl.h>
-#include <openssl/rsa.h>
-static const EVP_CIPHER *Cipher;
-static const EVP_MD *Digest;
-#endif
-
-static char *cipher = NULL; /* name of cipher, e.g. "aesv2" */
-static int reverse = 0; /* listening connection */
-static int msrc4_sc = 0; /* enables workaround for SC I/II */
-static int noultra = 0; /* manage salt/iv differently from ultradsm */
-static int nomd = 0; /* use the keydata directly, no md5 or salt */
-static int pw_in = 0; /* pw=.... read in */
-
-
-/* The data that was read in from key file (or pw=password) */
-static char keydata[1024];
-static int keydata_len;
-
-/* Size of salt and IV; based on UltraVNC DSM */
-#define SALT 16
-#define MSRC4_SALT 11
-#define IVEC 16
-
-/* Set default values of salt and IV */
-static int salt_size = SALT;
-static int ivec_size = IVEC;
-
-/* To track parent and child pids */
-static pid_t parent, child;
-
-/* transfer buffer size */
-#define BSIZE 8192
-
-/* Some very verbose debugging stuff I enable for testing */
-#ifdef DBG
-# include "dbg.h"
-#else
-# define DEC_CT_DBG(p, n)
-# define DEC_PT_DBG(p, n)
-# define ENC_CT_DBG(p, n)
-# define ENC_PT_DBG(p, n)
-# define PRINT_IVEC
-# define PRINT_KEYDATA
-# define PRINT_KEYSTR_AND_FRIENDS
-# define PRINT_LOOP_DBG1
-# define PRINT_LOOP_DBG2
-# define PRINT_LOOP_DBG3
-#endif
-
-/* SecureVNCPlugin from: http://adamwalling.com/SecureVNC/ */
-#define SECUREVNC_RSA_PUBKEY_SIZE 270
-#define SECUREVNC_ENCRYPTED_KEY_SIZE 256
-#define SECUREVNC_SIGNATURE_SIZE 256
-#define SECUREVNC_KEY_SIZE 16
-#define SECUREVNC_RESERVED_SIZE 4
-#define SECUREVNC_RC4_DROP_BYTES 3072
-#define SECUREVNC_RAND_KEY_SOURCE 1024
-static int securevnc = 0;
-static int securevnc_arc4 = 0;
-static char *securevnc_file = NULL;
-
-static void enc_connections(int, char*, int);
-
-#if !ENC_HAVE_OPENSSL
-
-/* In case we are a module and there is no OpenSSL buildtime support */
-
-extern void enc_do(char *ciph, char *keyfile, char *lport, char *rhp) {
- fprintf(stderr, "%s: not compiled with OpenSSL\n", prog);
- exit(1);
-}
-
-#else
-
-#if defined(NO_EVP_aes_256_cfb) || (defined (__SVR4) && defined (__sun) && !defined(EVP_aes_256_cfb) && !defined(ASSUME_EVP_aes_256_cfb))
-/*
- * For Solaris 10 missing 192 & 256 bit crypto.
- * Note that EVP_aes_256_cfb is a macro.
- */
-#undef EVP_aes_256_cfb
-#define EVP_aes_256_cfb() EVP_aes_128_cfb(); {fprintf(stderr, "Not compiled with EVP_aes_256_cfb() 'aes256' support.\n"); exit(1);}
-#endif
-
-/* If we are a module, enc_do() is the only interface we export. */
-
-
-/* This works out key type & etc., reads key, calls enc_connections */
-
-extern void enc_do(char *ciph, char *keyfile, char *lport, char *rhp) {
-
- struct stat sb;
- char *q, *p, *connect_host;
- char tmp[16];
- int fd, len = 0, listen_port = 0, connect_port, mbits;
-
- q = ciph;
-
- /* check for noultra mode: */
- if (strstr(q, "noultra:") == q) {
- noultra = 1;
- q += strlen("noultra:");
- }
-
- /* check for reverse mode: */
- if (strstr(q, "rev:") == q) {
- reverse = 1;
- q += strlen("rev:");
- }
-
- /* work out which cipher and set Cipher to the selected one. */
- if (!strcasecmp(q, "msrc4")) {
- Cipher = EVP_rc4(); cipher = "msrc4";
-
- } else if (!strcasecmp(q, "msrc4_sc")) {
- Cipher = EVP_rc4(); cipher = "msrc4";
- msrc4_sc = 1; /* no salt/iv workaround */
-
- } else if (strstr(q, "arc4") == q) {
- Cipher = EVP_rc4(); cipher = "arc4";
-
- } else if (strstr(q, "aesv2") == q || strstr(q, "aes-ofb") == q) {
- Cipher = EVP_aes_128_ofb(); cipher = "aesv2";
-
- } else if (strstr(q, "aes-cfb") == q) {
- Cipher = EVP_aes_128_cfb(); cipher = "aes-cfb";
-
- } else if (strstr(q, "aes256") == q) {
- Cipher = EVP_aes_256_cfb(); cipher = "aes256";
-
- } else if (strstr(q, "blowfish") == q) {
- Cipher = EVP_bf_cfb(); cipher = "blowfish";
-
- } else if (strstr(q, "3des") == q) {
- Cipher = EVP_des_ede3_cfb(); cipher = "3des";
-
- } else if (strstr(q, "securevnc") == q) {
- Cipher = EVP_aes_128_ofb(); cipher = "securevnc";
- securevnc = 1;
-
- } else if (strstr(q, "none") == q || strstr(q, "relay") == q) {
- cipher = "none";
-
- } else if (strstr(q, "showcert") == q) {
- cipher = "showcert";
-
- } else if (strstr(q, ".") == q) {
- /* otherwise, try to guess cipher from key filename: */
- if (strstr(keyfile, "arc4.key")) {
- Cipher = EVP_rc4(); cipher = "arc4";
-
- } else if (strstr(keyfile, "rc4.key")) {
- Cipher = EVP_rc4(); cipher = "msrc4";
-
- } else if (strstr(keyfile, "aesv2.key")) {
- Cipher = EVP_aes_128_ofb(); cipher = "aesv2";
-
- } else if (strstr(keyfile, "aes-cfb.key")) {
- Cipher = EVP_aes_128_cfb(); cipher = "aes-cfb";
-
- } else if (strstr(keyfile, "aes256.key")) {
- Cipher = EVP_aes_256_cfb(); cipher = "aes256";
-
- } else if (strstr(keyfile, "blowfish.key")) {
- Cipher = EVP_bf_cfb(); cipher = "blowfish";
-
- } else if (strstr(keyfile, "3des.key")) {
- Cipher = EVP_des_ede3_cfb(); cipher = "3des";
-
- } else if (strstr(keyfile, "securevnc.")) {
- Cipher = EVP_aes_128_ofb(); cipher = "securevnc";
- securevnc = 1;
-
- } else {
- fprintf(stderr, "cannot figure out cipher, supply 'msrc4', 'arc4', or 'aesv2' ...\n");
- exit(1);
- }
- } else {
- fprintf(stderr, "cannot figure out cipher, supply 'msrc4', 'arc4', or 'aesv2' ...\n");
- exit(1);
- }
-
- /* set the default message digest (md5) */
- if (!securevnc) {
- Digest = EVP_md5();
- } else {
- Digest = EVP_sha1();
- }
-
- /*
- * Look for user specified salt and IV sizes at the end
- * ( ciph@salt,iv and ciph@[md+]salt,iv ):
- */
- p = strchr(q, '@');
- if (p) {
- int s, v;
- p++;
- if (strstr(p, "md5+") == p) {
- Digest = EVP_md5(); p += strlen("md5+");
- } else if (strstr(p, "sha+") == p) {
- Digest = EVP_sha(); p += strlen("sha+");
- } else if (strstr(p, "sha1+") == p) {
- Digest = EVP_sha1(); p += strlen("sha1+");
- } else if (strstr(p, "ripe+") == p) {
- Digest = EVP_ripemd160(); p += strlen("ripe+");
- } else if (strstr(p, "ripemd160+") == p) {
- Digest = EVP_ripemd160(); p += strlen("ripemd160+");
- }
- if (sscanf(p, "%d,%d", &s, &v) == 2) {
- /* cipher@n,m */
- if (-1 <= s && s <= SALT) {
- salt_size = s;
- } else {
- fprintf(stderr, "%s: invalid salt size: %d\n",
- prog, s);
- exit(1);
- }
- if (0 <= v && v <= EVP_MAX_IV_LENGTH) {
- ivec_size = v;
- } else {
- fprintf(stderr, "%s: invalid IV size: %d\n",
- prog, v);
- exit(1);
- }
- } else if (sscanf(p, "%d", &s) == 1) {
- /* cipher@n */
- if (-1 <= s && s <= SALT) {
- salt_size = s;
- } else {
- fprintf(stderr, "%s: invalid salt size: %d\n",
- prog, s);
- exit(1);
- }
- }
- if (salt_size == -1) {
- /* let salt = -1 mean skip both MD5 and salt */
- nomd = 1;
- salt_size = 0;
- }
- }
-
- /* port to listen on (0 => stdio, negative => localhost) */
- if (lport != NULL) {
- listen_port = atoi(lport);
- }
-
- /* extract remote hostname and port */
- q = strrchr(rhp, ':');
- if (q) {
- connect_port = atoi(q+1);
- *q = '\0';
- } else {
- /* otherwise guess VNC display 0 ... */
- connect_port = 5900;
- }
- connect_host = strdup(rhp);
-
- /* check for and read in the key file */
- memset(keydata, 0, sizeof(keydata));
-
- if (!strcmp(cipher, "none")) {
- goto readed_in;
- }
- if (!strcmp(cipher, "showcert")) {
- goto readed_in;
- }
-
- if (securevnc) {
- /* note the keyfile for rsa verification later */
- if (keyfile != NULL && strcasecmp(keyfile, "none")) {
- securevnc_file = keyfile;
- }
- goto readed_in;
- }
-
- if (stat(keyfile, &sb) != 0) {
- if (strstr(keyfile, "pw=") == keyfile) {
- /* user specified key/password on cmdline */
- int i;
- len = 0;
- pw_in = 1;
- for (i=0; i < (int) strlen(keyfile); i++) {
- /* load the string to keydata: */
- int n = i + strlen("pw=");
- keydata[i] = keyfile[n];
- if (keyfile[n] == '\0') break;
- len++;
- if (i > 100) break;
- }
- goto readed_in;
- }
- /* otherwise invalid file */
- perror("stat");
- exit(1);
- }
- if (sb.st_size > 1024) {
- fprintf(stderr, "%s: key file too big.\n", prog);
- exit(1);
- }
- fd = open(keyfile, O_RDONLY);
- if (fd < 0) {
- perror("open");
- exit(1);
- }
-
- /* read it all in */
- len = (int) read(fd, keydata, (size_t) sb.st_size);
- if (len != sb.st_size) {
- perror("read");
- fprintf(stderr, "%s, could not read key file.\n", prog);
- exit(1);
- }
- close(fd);
-
- readed_in:
-
-
- /* check for ultravnc msrc4 format 'rc4.key' */
- mbits = 0;
- if (strstr(keydata, "128 bit") == keydata) {
- mbits = 128;
- } else if (strstr(keydata, " 56 bit") == keydata) {
- mbits = 56;
- } else if (strstr(keydata, " 40 bit") == keydata) {
- mbits = 40;
- }
- if (mbits > 0) {
- /* 4 is for int key length, 12 is for BLOBHEADER. */
- int i, offset = strlen("xxx bit") + 4 + 12;
-
- /* the key is stored in reverse order! */
- len = mbits/8;
- for (i=0; i < len; i++) {
- tmp[i] = keydata[offset + len - i - 1];
- }
-
- /* clear keydata and then copy the reversed bytes there: */
- memset(keydata, 0, sizeof(keydata));
- memcpy(keydata, tmp, len);
- }
-
- keydata_len = len;
-
- /* initialize random */
- RAND_poll();
-
- /*
- * Setup connections, then transfer data when they are all
- * hooked up.
- */
- enc_connections(listen_port, connect_host, connect_port);
-}
-#endif
-
-static void enc_raw_xfer(int sock_fr, int sock_to) {
-
- unsigned char buf[BSIZE];
- unsigned char *psrc = NULL;
- int len, m, n = 0;
-
- /* zero the buffers */
- memset(buf, 0, BSIZE);
-
- /* now loop forever processing the data stream */
- while (1) {
- errno = 0;
-
- /* general case of loop, read some in: */
- n = read(sock_fr, buf, BSIZE);
-
- if (n == 0 || (n < 0 && errno != EINTR)) {
- /* failure to read any data, it is EOF or fatal error */
- int err = errno;
-
- /* debug output: */
- fprintf(stderr, "%s: input stream finished: n=%d, err=%d", prog, n, err);
-
- /* EOF or fatal error */
- break;
-
- } else if (n > 0) {
-
- /* write data to the other end: */
- len = n;
- psrc = buf;
- while (len > 0) {
- errno = 0;
- m = write(sock_to, psrc, len);
-
- if (m > 0) {
- /* scoot them by how much was written: */
- psrc += m;
- len -= m;
- }
- if (m < 0 && (errno == EINTR || errno == EAGAIN)) {
- /* interrupted or blocked */
- continue;
- }
- /* EOF or fatal error */
- break;
- }
- } else {
- /* this is EINTR */
- }
- }
-
- /* transfer done (viewer exited or some error) */
-
- fprintf(stderr, "\n%s: close sock_to\n", prog);
- close(sock_to);
-
- fprintf(stderr, "%s: close sock_fr\n", prog);
- close(sock_fr);
-
- /* kill our partner after 1 secs. */
- sleep(1);
- if (child) {
- if (kill(child, SIGTERM) == 0) {
- fprintf(stderr, "%s[%d]: killed my partner: %d\n",
- prog, (int) getpid(), (int) child);
- }
- } else {
- if (kill(parent, SIGTERM) == 0) {
- fprintf(stderr, "%s[%d]: killed my partner: %d\n",
- prog, (int) getpid(), (int) parent);
- }
- }
-}
-
-#if ENC_HAVE_OPENSSL
-/*
- * Initialize cipher context and then loop till EOF doing transfer &
- * encrypt or decrypt.
- */
-static void enc_xfer(int sock_fr, int sock_to, int encrypt) {
- /*
- * We keep both E and D aspects in case we revert back to a
- * single process calling select(2) on all fds...
- */
- unsigned char E_keystr[EVP_MAX_KEY_LENGTH];
- unsigned char D_keystr[EVP_MAX_KEY_LENGTH];
- EVP_CIPHER_CTX E_ctx, D_ctx;
- EVP_CIPHER_CTX *ctx = NULL;
-
- unsigned char buf[BSIZE], out[BSIZE];
- unsigned char *psrc = NULL, *keystr;
- unsigned char salt[SALT+1];
- unsigned char ivec_real[EVP_MAX_IV_LENGTH];
- unsigned char *ivec = ivec_real;
-
- int i, cnt, len, m, n = 0, vb = 0, first = 1;
- int whoops = 1; /* for the msrc4 problem */
- char *encstr, *encsym;
-
- /* zero the buffers */
- memset(buf, 0, BSIZE);
- memset(out, 0, BSIZE);
- memset(salt, 0, sizeof(salt));
- memset(ivec_real, 0, sizeof(ivec_real));
- memset(E_keystr, 0, sizeof(E_keystr));
- memset(D_keystr, 0, sizeof(D_keystr));
-
- if (!strcmp(cipher, "msrc4")) {
- salt_size = MSRC4_SALT; /* 11 vs. 16 */
- }
-
- if (msrc4_sc) {
- whoops = 1; /* force workaround in SC mode */
- }
-
- if (getenv("ENCRYPT_VERBOSE")) {
- vb = 1; /* let user turn on some debugging via env. var. */
- }
-
- /*
- * reverse mode, e.g. we help a vnc server instead of a viewer.
- */
- if (reverse) {
- encrypt = (!encrypt);
- }
- encstr = encrypt ? "encrypt" : "decrypt"; /* string for messages */
- encsym = encrypt ? "+" : "-";
-
- /* use the encryption/decryption context variables below */
- if (encrypt) {
- ctx = &E_ctx;
- keystr = E_keystr;
- } else {
- ctx = &D_ctx;
- keystr = D_keystr;
- }
-
- if (securevnc) {
- first = 0; /* no need for salt+iv on first time */
- salt_size = 0; /* we want no salt */
- n = 0; /* nothing read */
- ivec_size = 0; /* we want no IV. */
- ivec = NULL;
- } else if (encrypt) {
- /* encrypter initializes the salt and initialization vector */
-
- /*
- * Our salt is 16 bytes but I believe only the first 8
- * bytes are used by EVP_BytesToKey(3). Since we send it
- * to the other "plugin" we need to keep it 16. Also,
- * the IV size can depend on the cipher type. Again, 16.
- */
- RAND_bytes(salt, salt_size);
- RAND_bytes(ivec, ivec_size);
-
- /* place them in the send buffer: */
- memcpy(buf, salt, salt_size);
- memcpy(buf+salt_size, ivec, ivec_size);
-
- n = salt_size + ivec_size;
-
- ENC_PT_DBG(buf, n);
-
- } else {
- /* decrypter needs to read salt + iv from the wire: */
-
- /* sleep 100 ms (TODO: select on fd) */
- struct timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = 100 * 1000;
- select(1, NULL, NULL, NULL, &tv);
-
- if (salt_size+ivec_size == 0) {
- n = 0; /* no salt or iv, skip reading. */
- } else {
- n = read(sock_fr, buf, salt_size+ivec_size+96);
- }
- if (n == 0 && salt_size+ivec_size > 0) {
- fprintf(stderr, "%s: decrypt finished.\n", prog);
- goto finished;
- }
- if (n < salt_size+ivec_size) {
- if (msrc4_sc && n == 12) {
- fprintf(stderr, "%s: only %d bytes read. Assuming "
- "UVNC Single Click server.\n", prog, n);
- } else {
- if (n < 0) perror("read");
- fprintf(stderr, "%s: could not read enough for salt "
- "and ivec: n=%d\n", prog, n);
- goto finished;
- }
- }
-
- DEC_CT_DBG(buf, n);
-
- if (msrc4_sc && n == 12) {
- ; /* send it as is */
- } else {
- /* extract them to their buffers: */
- memcpy(salt, buf, salt_size);
- memcpy(ivec, buf+salt_size, ivec_size);
-
- /* the rest is some encrypted data: */
- n = n - salt_size - ivec_size;
- psrc = buf + salt_size + ivec_size;
-
- if (n > 0) {
- /*
- * copy it down to the start of buf for
- * sending below:
- */
- for (i=0; i < n; i++) {
- buf[i] = psrc[i];
- }
- }
- }
- }
-
- /* debug output */
- PRINT_KEYDATA;
- PRINT_IVEC;
-
- if (!strcmp(cipher, "msrc4")) {
- /* special cases for MSRC4: */
-
- if (whoops) {
- fprintf(stderr, "%s: %s - WARNING: MSRC4 mode and IGNORING random salt\n", prog, encstr);
- fprintf(stderr, "%s: %s - WARNING: and initialization vector!!\n", prog, encstr);
- EVP_CIPHER_CTX_init(ctx);
- if (pw_in) {
- /* for pw=xxxx a md5 hash is used */
- EVP_BytesToKey(Cipher, Digest, NULL, (unsigned char *) keydata,
- keydata_len, 1, keystr, NULL);
- EVP_CipherInit_ex(ctx, Cipher, NULL, keystr, NULL,
- encrypt);
- } else {
- /* otherwise keydata as is */
- EVP_CipherInit_ex(ctx, Cipher, NULL,
- (unsigned char *) keydata, NULL, encrypt);
- }
- } else {
- /* XXX might not be correct, just exit. */
- fprintf(stderr, "%s: %s - Not sure about msrc4 && !whoops case, exiting.\n", prog, encstr);
- exit(1);
-
- EVP_BytesToKey(Cipher, Digest, NULL, (unsigned char *) keydata,
- keydata_len, 1, keystr, ivec);
- EVP_CIPHER_CTX_init(ctx);
- EVP_CipherInit_ex(ctx, Cipher, NULL, keystr, ivec,
- encrypt);
- }
-
- } else {
- unsigned char *in_salt = NULL;
-
- /* check salt and IV source and size. */
- if (securevnc) {
- in_salt = NULL;
- } else if (salt_size <= 0) {
- /* let salt_size = 0 mean keep it out of the MD5 */
- fprintf(stderr, "%s: %s - WARNING: no salt\n",
- prog, encstr);
- in_salt = NULL;
- } else {
- in_salt = salt;
- }
-
- if (ivec_size < Cipher->iv_len && !securevnc) {
- fprintf(stderr, "%s: %s - WARNING: short IV %d < %d\n",
- prog, encstr, ivec_size, Cipher->iv_len);
- }
-
- /* make the hashed value and place in keystr */
-
- /*
- * XXX N.B.: DSM plugin had count=0, and overwrote ivec
- * by not passing NULL iv.
- */
-
- if (nomd) {
- /* special mode: no salt or md5, use keydata directly */
-
- int sz = keydata_len < EVP_MAX_KEY_LENGTH ?
- keydata_len : EVP_MAX_KEY_LENGTH;
-
- fprintf(stderr, "%s: %s - WARNING: no-md5 specified: ignoring salt & hash\n", prog, encstr);
- memcpy(keystr, keydata, sz);
-
- } else if (noultra && ivec_size > 0) {
- /* "normal" mode, don't overwrite ivec. */
-
- EVP_BytesToKey(Cipher, Digest, in_salt, (unsigned char *) keydata,
- keydata_len, 1, keystr, NULL);
-
- } else {
- /*
- * Ultra DSM compatibility mode. Note that this
- * clobbers the ivec we set up above! Under
- * noultra we overwrite ivec only if ivec_size=0.
- *
- * SecureVNC also goes through here. in_salt and ivec are NULL.
- * And ivec is NULL below in the EVP_CipherInit_ex() call.
- */
- EVP_BytesToKey(Cipher, Digest, in_salt, (unsigned char *) keydata,
- keydata_len, 1, keystr, ivec);
- }
-
-
- /* initialize the context */
- EVP_CIPHER_CTX_init(ctx);
-
-
- /* set the cipher & initialize */
-
- /*
- * XXX N.B.: DSM plugin implementation had encrypt=1
- * for both (i.e. perfectly symmetric)
- */
-
- EVP_CipherInit_ex(ctx, Cipher, NULL, keystr, ivec, encrypt);
- }
-
- if (securevnc && securevnc_arc4) {
- /* need to discard initial 3072 bytes */
- unsigned char buf1[SECUREVNC_RC4_DROP_BYTES];
- unsigned char buf2[SECUREVNC_RC4_DROP_BYTES];
- int cnt = 0;
- EVP_CipherUpdate(ctx, buf1, &cnt, buf2, SECUREVNC_RC4_DROP_BYTES);
- }
-
- /* debug output */
- PRINT_KEYSTR_AND_FRIENDS;
-
- /* now loop forever processing the data stream */
-
- while (1) {
- errno = 0;
- if (first && n > 0) {
- if (encrypt && msrc4_sc) {
- /* skip sending salt+iv */
- first = 0;
- continue;
- } else {
- /* use that first block of data placed in buf */
- }
- } else if (first && n == 0 && salt_size + ivec_size == 0) {
- first = 0;
- continue;
- } else {
- /* general case of loop, read some in: */
- n = read(sock_fr, buf, BSIZE);
- }
-
- /* debug output: */
- if (vb) fprintf(stderr, "%s%d/%d ", encsym, n, errno);
- PRINT_LOOP_DBG1;
-
- if (n == 0 || (n < 0 && errno != EINTR)) {
- /* failure to read any data, it is EOF or fatal error */
- int err = errno;
-
- /* debug output: */
- PRINT_LOOP_DBG2;
- fprintf(stderr, "%s: %s - input stream finished: n=%d, err=%d", prog, encstr, n, err);
-
- /* EOF or fatal error */
- break;
-
- } else if (n > 0) {
- /* we read in some data, now transform it: */
-
- if (first && encrypt) {
- /* first time, copy the salt and ivec to out[] for sending */
- memcpy(out, buf, n);
- cnt = n;
-
- } else if (!EVP_CipherUpdate(ctx, out, &cnt, buf, n)) {
- /* otherwise, we transform the data */
- fprintf(stderr, "%s: enc_xfer EVP_CipherUpdate failed.\n", prog);
- break;
- }
-
- /* debug output: */
- if (vb) fprintf(stderr, "%sc%d/%d ", encsym, cnt, n);
- PRINT_LOOP_DBG3;
-
- /* write transformed data to the other end: */
- len = cnt;
- psrc = out;
- while (len > 0) {
- errno = 0;
- m = write(sock_to, psrc, len);
-
- /* debug output: */
- if (vb) fprintf(stderr, "m%s%d/%d ", encsym, m, errno);
-
- if (m > 0) {
- /* scoot them by how much was written: */
- psrc += m;
- len -= m;
- }
- if (m < 0 && (errno == EINTR || errno == EAGAIN)) {
- /* interrupted or blocked */
- continue;
- }
- /* EOF or fatal error */
- break;
- }
- } else {
- /* this is EINTR */
- }
- first = 0;
- }
-
- /* transfer done (viewer exited or some error) */
- finished:
-
- fprintf(stderr, "\n%s: %s - close sock_to\n", prog, encstr);
- close(sock_to);
-
- fprintf(stderr, "%s: %s - close sock_fr\n", prog, encstr);
- close(sock_fr);
-
- /* kill our partner after 2 secs. */
- sleep(2);
- if (child) {
- if (kill(child, SIGTERM) == 0) {
- fprintf(stderr, "%s[%d]: %s - killed my partner: %d\n",
- prog, (int) getpid(), encstr, (int) child);
- }
- } else {
- if (kill(parent, SIGTERM) == 0) {
- fprintf(stderr, "%s[%d]: %s - killed my partner: %d\n",
- prog, (int) getpid(), encstr, (int) parent);
- }
- }
-}
-
-static int securevnc_server_rsa_save_dialog(char *file, char *md5str, unsigned char* rsabuf) {
- /* since we are likely running in the background, use this kludge by running tk */
- FILE *p;
- char str[2], *q = file, *cmd = getenv("WISH") ? getenv("WISH") : "wish";
- int rc;
-
- memset(str, 0, sizeof(str));
-
- p = popen(cmd, "w");
- if (p == NULL) {
- fprintf(stderr, "checkserver_rsa: could not run: %s\n", cmd);
- return 0;
- }
-
- /* start piping tk/tcl code to it: */
- fprintf(p, "wm withdraw .\n");
- fprintf(p, "set x [expr [winfo screenwidth .]/2]\n");
- fprintf(p, "set y [expr [winfo screenheight .]/2]\n");
- fprintf(p, "wm geometry . +$x+$y; update\n");
- fprintf(p, "catch {option add *Dialog.msg.font {helvetica -14 bold}}\n");
- fprintf(p, "catch {option add *Dialog.msg.wrapLength 6i}\n");
- fprintf(p, "set ans [tk_messageBox -title \"Save and Trust UltraVNC RSA Key?\" -icon question ");
- fprintf(p, "-type yesno -message \"Save and Trust UltraVNC SecureVNCPlugin RSA Key\\n\\n");
- fprintf(p, "With MD5 sum: %s\\n\\n", md5str);
- fprintf(p, "In file: ");
- while (*q != '\0') {
- /* sanitize user supplied string: */
- str[0] = *q;
- if (strpbrk(str, "[](){}`'\"$&*|<>") == NULL) {
- fprintf(p, "%s", str);
- }
- q++;
- }
- fprintf(p, " ?\"]\n");
- fprintf(p, "if { $ans == \"yes\" } {destroy .; exit 0} else {destroy .; exit 1}\n");
- rc = pclose(p);
- if (rc == 0) {
- fprintf(stderr, "checkserver_rsa: query returned: %d. saving it.\n", rc);
- p = fopen(file, "w");
- if (p == NULL) {
- fprintf(stderr, "checkserver_rsa: could not open %s\n", file);
- return 0;
- }
- write(fileno(p), rsabuf, SECUREVNC_RSA_PUBKEY_SIZE);
- fclose(p);
- return 2;
- } else {
- fprintf(stderr, "checkserver_rsa: query returned: %d. NOT saving it.\n", rc);
- return -1;
- }
-}
-
-static char *rsa_md5_sum(unsigned char* rsabuf) {
- EVP_MD_CTX md;
- char digest[EVP_MAX_MD_SIZE], tmp[16];
- char md5str[EVP_MAX_MD_SIZE * 8];
- unsigned int i, size = 0;
-
- EVP_DigestInit(&md, EVP_md5());
- EVP_DigestUpdate(&md, rsabuf, SECUREVNC_RSA_PUBKEY_SIZE);
- EVP_DigestFinal(&md, (unsigned char *)digest, &size);
-
- memset(md5str, 0, sizeof(md5str));
- for (i=0; i < size; i++) {
- unsigned char uc = (unsigned char) digest[i];
- sprintf(tmp, "%02x", (int) uc);
- strcat(md5str, tmp);
- }
- return strdup(md5str);
-}
-
-static int securevnc_check_server_rsa(char *file, unsigned char *rsabuf) {
- struct stat sb;
- unsigned char filebuf[SECUREVNC_RSA_PUBKEY_SIZE];
- char *md5str = rsa_md5_sum(rsabuf);
-
- if (!file) {
- return 0;
- }
-
- memset(filebuf, 0, sizeof(filebuf));
- if (stat(file, &sb) == 0) {
- int n, fd, i, ok = 1;
-
- if (sb.st_size != SECUREVNC_RSA_PUBKEY_SIZE) {
- fprintf(stderr, "checkserver_rsa: file is wrong size: %d != %d '%s'\n",
- (int) sb.st_size, SECUREVNC_RSA_PUBKEY_SIZE, file);
- return 0;
- }
-
- fd = open(file, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "checkserver_rsa: could not open: '%s'\n", file);
- return 0;
- }
-
- n = (int) read(fd, filebuf, SECUREVNC_RSA_PUBKEY_SIZE);
- close(fd);
- if (n != SECUREVNC_RSA_PUBKEY_SIZE) {
- fprintf(stderr, "checkserver_rsa: could not read all of file: %d != %d '%s'\n",
- n, SECUREVNC_RSA_PUBKEY_SIZE, file);
- return 0;
- }
-
- for (i=0; i < SECUREVNC_RSA_PUBKEY_SIZE; i++) {
- if (filebuf[i] != rsabuf[i]) {
- ok = 0;
- }
- }
- if (!ok) {
- char *str1 = rsa_md5_sum(rsabuf);
- char *str2 = rsa_md5_sum(filebuf);
- fprintf(stderr, "checkserver_rsa: rsa keystore contents differ for '%s'\n", file);
- fprintf(stderr, "checkserver_rsa: MD5 sum of server key: %s\n", str1);
- fprintf(stderr, "checkserver_rsa: MD5 sum of keystore: %s\n", str2);
- }
- return ok;
- } else {
-
- fprintf(stderr, "checkserver_rsa: rsa keystore file does not exist: '%s'\n", file);
- fprintf(stderr, "checkserver_rsa: asking user if we should store rsa key in it.\n\n");
- fprintf(stderr, "checkserver_rsa: RSA key has MD5 sum: %s\n\n", md5str);
-
- return securevnc_server_rsa_save_dialog(file, md5str, rsabuf);
- }
-}
-
-static RSA *load_client_auth(char *file) {
- struct stat sb;
- int fd, n;
- char *contents;
- RSA *rsa;
-
- if (!file) {
- return NULL;
- }
- if (stat(file, &sb) != 0) {
- return NULL;
- }
-
- fd = open(file, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "load_client_auth: could not open: '%s'\n", file);
- return NULL;
- }
-
- contents = (char *) malloc(sb.st_size);
- n = (int) read(fd, contents, sb.st_size);
- close(fd);
-
- if (n != sb.st_size) {
- fprintf(stderr, "load_client_auth: could not read all of: '%s'\n", file);
- free(contents);
- return NULL;
- }
-
- rsa = d2i_RSAPrivateKey(NULL, (const unsigned char **) ((void *) &contents), sb.st_size);
- if (!rsa) {
- fprintf(stderr, "load_client_auth: d2i_RSAPrivateKey failed for: '%s'\n", file);
- return NULL;
- }
-
- if (RSA_check_key(rsa) != 1) {
- fprintf(stderr, "load_client_auth: rsa key invalid: '%s'\n", file);
- return NULL;
- }
-
- return rsa;
-}
-
-static void sslexit(char *msg) {
- fprintf(stderr, "%s: %s\n", msg, ERR_error_string(ERR_get_error(), NULL));
- exit(1);
-}
-
-static void securevnc_setup(int conn1, int conn2) {
- RSA *rsa = NULL;
- EVP_CIPHER_CTX init_ctx;
- unsigned char keystr[EVP_MAX_KEY_LENGTH];
- unsigned char *rsabuf, *rsasav;
- unsigned char *encrypted_keybuf;
- unsigned char *initkey;
- unsigned int server_flags = 0;
- unsigned char one = 1, zero = 0, sig = 16;
- unsigned char b1, b2, b3, b4;
- unsigned char buf[BSIZE], to_viewer[BSIZE];
- int to_viewer_len = 0;
- int n = 0, len, rc;
- int server = reverse ? conn1 : conn2;
- int viewer = reverse ? conn2 : conn1;
- char *client_auth = NULL;
- int client_auth_req = 0;
- int keystore_verified = 0;
-
- ERR_load_crypto_strings();
-
- /* alloc and read from server the 270 comprising the rsa public key: */
- rsabuf = (unsigned char *) calloc(SECUREVNC_RSA_PUBKEY_SIZE, 1);
- rsasav = (unsigned char *) calloc(SECUREVNC_RSA_PUBKEY_SIZE, 1);
- len = 0;
- while (len < SECUREVNC_RSA_PUBKEY_SIZE) {
- n = read(server, rsabuf + len, SECUREVNC_RSA_PUBKEY_SIZE - len);
- if (n == 0 || (n < 0 && errno != EINTR)) {
- fprintf(stderr, "securevnc_setup: fail read rsabuf: n=%d len=%d\n", n, len);
- exit(1);
- }
- len += n;
- }
- if (len != SECUREVNC_RSA_PUBKEY_SIZE) {
- fprintf(stderr, "securevnc_setup: fail final read rsabuf: n=%d len=%d\n", n, len);
- exit(1);
- }
- fprintf(stderr, "securevnc_setup: rsa data read len: %d\n", len);
- memcpy(rsasav, rsabuf, SECUREVNC_RSA_PUBKEY_SIZE);
-
- fprintf(stderr, "securevnc_setup: RSA key has MD5 sum: %s\n", rsa_md5_sum(rsabuf));
- fprintf(stderr, "securevnc_setup:\n");
- fprintf(stderr, "securevnc_setup: One way to print out the SecureVNC Server key MD5 sum is:\n\n");
- fprintf(stderr, "openssl rsa -inform DER -outform DER -pubout -in ./Server_SecureVNC.pkey | dd bs=1 skip=24 | md5sum\n\n");
- if (securevnc_file == NULL) {
- fprintf(stderr, "securevnc_setup:\n");
- fprintf(stderr, "securevnc_setup: ** WARNING: ULTRAVNC SERVER RSA KEY NOT VERIFIED. **\n");
- fprintf(stderr, "securevnc_setup: ** WARNING: A MAN-IN-THE-MIDDLE ATTACK IS POSSIBLE. **\n");
- fprintf(stderr, "securevnc_setup:\n");
- } else {
- char *q = strrchr(securevnc_file, 'C');
- int skip = 0;
- if (q) {
- if (!strcmp(q, "ClientAuth.pkey")) {
- client_auth = strdup(securevnc_file);
- skip = 1;
- } else if (!strcmp(q, "ClientAuth.pkey.rsa")) {
- client_auth = strdup(securevnc_file);
- q = strrchr(client_auth, '.');
- *q = '\0';
- }
- }
- if (!skip) {
- rc = securevnc_check_server_rsa(securevnc_file, rsabuf);
- }
- if (skip) {
- ;
- } else if (rc == 0) {
- fprintf(stderr, "securevnc_setup:\n");
- fprintf(stderr, "securevnc_setup: VERIFY_ERROR: SERVER RSA KEY DID NOT MATCH:\n");
- fprintf(stderr, "securevnc_setup: %s\n", securevnc_file);
- fprintf(stderr, "securevnc_setup:\n");
- exit(1);
- } else if (rc == -1) {
- fprintf(stderr, "securevnc_setup: User cancelled the save and hence the connection.\n");
- fprintf(stderr, "securevnc_setup: %s\n", securevnc_file);
- exit(1);
- } else if (rc == 1) {
- fprintf(stderr, "securevnc_setup: VERIFY SUCCESS: server rsa key matches the contents of:\n");
- fprintf(stderr, "securevnc_setup: %s\n", securevnc_file);
- keystore_verified = 1;
- } else if (rc == 2) {
- fprintf(stderr, "securevnc_setup: Server rsa key stored in:\n");
- fprintf(stderr, "securevnc_setup: %s\n", securevnc_file);
- keystore_verified = 2;
- }
- }
-
- /*
- * read in the server flags. Note that SecureVNCPlugin sends these
- * in little endian and not network order!!
- */
- read(server, (char *) &b1, 1);
- read(server, (char *) &b2, 1);
- read(server, (char *) &b3, 1);
- read(server, (char *) &b4, 1);
-
- server_flags = 0;
- server_flags |= ((unsigned int) b4) << 24;
- server_flags |= ((unsigned int) b3) << 16;
- server_flags |= ((unsigned int) b2) << 8;
- server_flags |= ((unsigned int) b1) << 0;
- fprintf(stderr, "securevnc_setup: server_flags: 0x%08x\n", server_flags);
-
- /* check for arc4 usage: */
- if (server_flags & 0x1) {
- fprintf(stderr, "securevnc_setup: server uses AES cipher.\n");
- } else {
- fprintf(stderr, "securevnc_setup: server uses ARC4 cipher.\n");
- securevnc_arc4 = 1;
- Cipher = EVP_rc4();
- }
-
- /* check for client auth signature requirement: */
- if (server_flags & (sig << 24)) {
- fprintf(stderr, "securevnc_setup: server requires Client Auth signature.\n");
- client_auth_req = 1;
- if (!client_auth) {
- fprintf(stderr, "securevnc_setup: However, NO *ClientAuth.pkey keyfile was supplied on our\n");
- fprintf(stderr, "securevnc_setup: command line. Exiting.\n");
- exit(1);
- }
- }
-
- /*
- * The first packet 'RFB 003.006' is obscured with key
- * that is a sha1 hash of public key. So make this tmp key now:
- *
- */
- initkey = (unsigned char *) calloc(SECUREVNC_KEY_SIZE, 1);
- EVP_BytesToKey(EVP_rc4(), EVP_sha1(), NULL, rsabuf, SECUREVNC_RSA_PUBKEY_SIZE, 1, initkey, NULL);
-
- /* expand the transported rsabuf into an rsa object */
- rsa = d2i_RSAPublicKey(NULL, (const unsigned char **) &rsabuf, SECUREVNC_RSA_PUBKEY_SIZE);
- if (rsa == NULL) {
- sslexit("securevnc_setup: failed to create rsa");
- }
-
- /*
- * Back to the work involving the tmp obscuring key:
- */
- EVP_CIPHER_CTX_init(&init_ctx);
- rc = EVP_CipherInit_ex(&init_ctx, EVP_rc4(), NULL, initkey, NULL, 1);
- if (rc == 0) {
- sslexit("securevnc_setup: EVP_CipherInit_ex(init_ctx) failed");
- }
-
- /* for the first obscured packet, read what we can... */
- n = read(server, (char *) buf, BSIZE);
- fprintf(stderr, "securevnc_setup: data read: %d\n", n);
- if (n < 0) {
- exit(1);
- }
- fprintf(stderr, "securevnc_setup: initial data[%d]: ", n);
-
- /* decode with the tmp key */
- if (n > 0) {
- memset(to_viewer, 0, sizeof(to_viewer));
- if (EVP_CipherUpdate(&init_ctx, to_viewer, &len, buf, n) == 0) {
- sslexit("securevnc_setup: EVP_CipherUpdate(init_ctx) failed");
- exit(1);
- }
- to_viewer_len = len;
- }
- EVP_CIPHER_CTX_cleanup(&init_ctx);
- free(initkey);
-
- /* print what we would send to the viewer (sent below): */
- write(2, to_viewer, 12); /* and first 12 bytes 'RFB ...' as message */
-
- /* now create the random session key: */
- encrypted_keybuf = (unsigned char*) calloc(RSA_size(rsa), 1);
-
- fprintf(stderr, "securevnc_setup: creating random session key: %d/%d\n",
- SECUREVNC_KEY_SIZE, SECUREVNC_RAND_KEY_SOURCE);
- keydata_len = SECUREVNC_RAND_KEY_SOURCE;
-
- rc = RAND_bytes((unsigned char *)keydata, SECUREVNC_RAND_KEY_SOURCE);
- if (rc <= 0) {
- fprintf(stderr, "securevnc_setup: RAND_bytes() failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
- rc = RAND_pseudo_bytes((unsigned char *)keydata, SECUREVNC_RAND_KEY_SOURCE);
- fprintf(stderr, "securevnc_setup: RAND_pseudo_bytes() rc=%d\n", rc);
- if (getenv("RANDSTR")) {
- char *s = getenv("RANDSTR");
- fprintf(stderr, "securevnc_setup: seeding with RANDSTR len=%d\n", strlen(s));
- RAND_add(s, strlen(s), strlen(s));
- }
- }
-
- /* N.B. this will be repeated in enc_xfer() setup. */
- EVP_BytesToKey(Cipher, Digest, NULL, (unsigned char *) keydata, keydata_len, 1, keystr, NULL);
-
- /* encrypt the session key with the server's public rsa key: */
- n = RSA_public_encrypt(SECUREVNC_KEY_SIZE, keystr, encrypted_keybuf, rsa, RSA_PKCS1_PADDING);
- if (n == -1) {
- sslexit("securevnc_setup: RSA_public_encrypt() failed");
- exit(1);
- }
- fprintf(stderr, "securevnc_setup: encrypted session key size: %d. sending to server.\n", n);
-
- /* send it to the server: */
- write(server, encrypted_keybuf, n);
- free(encrypted_keybuf);
-
- /*
- * Reply back with flags indicating cipher (same as one sent to
- * us) and we do not want client-side auth.
- *
- * We send it out on the wire in little endian order:
- */
- if (securevnc_arc4) {
- write(server, (char *)&zero, 1);
- } else {
- write(server, (char *)&one, 1);
- }
- write(server, (char *)&zero, 1);
- write(server, (char *)&zero, 1);
- if (client_auth_req) {
- write(server, (char *)&sig, 1);
- } else {
- write(server, (char *)&zero, 1);
- }
-
- if (client_auth_req && client_auth) {
- RSA *client_rsa = load_client_auth(client_auth);
- EVP_MD_CTX dctx;
- unsigned char digest[EVP_MAX_MD_SIZE], *signature;
- unsigned int ndig = 0, nsig = 0;
-
- if (0) {
- /* for testing only, use the wrong RSA key: */
- client_rsa = RSA_generate_key(2048, 0x10001, NULL, NULL);
- }
-
- if (client_rsa == NULL) {
- fprintf(stderr, "securevnc_setup: problem reading rsa key from '%s'\n", client_auth);
- exit(1);
- }
-
- EVP_DigestInit(&dctx, EVP_sha1());
- EVP_DigestUpdate(&dctx, keystr, SECUREVNC_KEY_SIZE);
- /*
- * Without something like the following MITM is still possible.
- * This is because the MITM knows keystr and can use it with
- * the server connection as well, and then he just forwards our
- * signed digest. The additional information below would be the
- * MITM's rsa public key, and so the real VNC server will notice
- * the difference. And MITM can't sign keystr+server_rsa.pub since
- * he doesn't have Viewer_ClientAuth.pkey.
- */
- if (0) {
- EVP_DigestUpdate(&dctx, rsasav, SECUREVNC_RSA_PUBKEY_SIZE);
- if (!keystore_verified) {
- fprintf(stderr, "securevnc_setup:\n");
- fprintf(stderr, "securevnc_setup: Warning: even *WITH* Client Authentication in SecureVNC,\n");
- fprintf(stderr, "securevnc_setup: an attacker may be able to trick you into connecting to his\n");
- fprintf(stderr, "securevnc_setup: fake VNC server and supplying VNC or Windows passwords, etc.\n");
- fprintf(stderr, "securevnc_setup: To increase security manually verify the Server RSA key's MD5\n");
- fprintf(stderr, "securevnc_setup: checksum and then have SSVNC save the key in its keystore to\n");
- fprintf(stderr, "securevnc_setup: be used to verify the server in subsequent connections.\n");
- fprintf(stderr, "securevnc_setup:\n");
- }
- } else {
- if (!keystore_verified) {
- fprintf(stderr, "securevnc_setup:\n");
- fprintf(stderr, "securevnc_setup: WARNING: THE FIRST VERSION OF THE SECUREVNC PROTOCOL IS\n");
- fprintf(stderr, "securevnc_setup: WARNING: BEING USED. *EVEN* WITH CLIENT AUTHENTICATION IT\n");
- fprintf(stderr, "securevnc_setup: WARNING: IS SUSCEPTIBLE TO A MAN-IN-THE-MIDDLE ATTACK.\n");
- fprintf(stderr, "securevnc_setup: To increase security manually verify the Server RSA key's MD5\n");
- fprintf(stderr, "securevnc_setup: checksum and then have SSVNC save the key in its keystore to\n");
- fprintf(stderr, "securevnc_setup: be used to verify the server in subsequent connections.\n");
- fprintf(stderr, "securevnc_setup:\n");
- }
- }
- EVP_DigestFinal(&dctx, (unsigned char *)digest, &ndig);
-
- signature = (unsigned char *) calloc(RSA_size(client_rsa), 1);
- RSA_sign(NID_sha1, digest, ndig, signature, &nsig, client_rsa);
-
- fprintf(stderr, "securevnc_setup: sending ClientAuth.pkey signed data: %d\n", nsig);
- write(server, signature, nsig);
- free(signature);
-
- RSA_free(client_rsa);
- }
-
- fprintf(stderr, "securevnc_setup: done.\n");
-
- /* now send the 'RFB ...' to the viewer */
- if (to_viewer_len > 0) {
- write(viewer, to_viewer, to_viewer_len);
- }
-}
-
-#ifndef ENC_DISABLE_SHOW_CERT
-static void enc_sslerrexit(void) {
- unsigned long err = ERR_get_error();
-
- if (err) {
- char str[256];
- ERR_error_string(err, str);
- fprintf(stdout, "ssl error: %s\n", str);
- }
- exit(1);
-}
-#endif
-
-static void show_cert(int sock) {
-#ifndef ENC_DISABLE_SHOW_CERT
- SSL_CTX *ctx;
- SSL *ssl = NULL;
- STACK_OF(X509) *sk = NULL;
- X509 *peer = NULL;
- SSL_CIPHER *c;
- BIO *bio;
- unsigned char *sid = (unsigned char *) "ultravnc_dsm_helper SID";
- long mode;
- int i;
-
- fprintf(stdout, "CONNECTED(%08X)\n",sock);
-
- SSL_library_init();
- SSL_load_error_strings();
-
- if (!RAND_status()) {
- RAND_poll();
- }
- /* this is not for a secured connection. */
- for (i=0; i < 100; i++) {
- if (!RAND_status()) {
- char tmp[32];
- sprintf(tmp, "%d", getpid() * (17 + i));
- RAND_add(tmp, strlen(tmp), 5);
- } else {
- break;
- }
- }
-
- ctx = SSL_CTX_new( SSLv23_client_method() );
- if (ctx == NULL) {
- fprintf(stdout, "show_cert: SSL_CTX_new failed.\n");
- close(sock);
- enc_sslerrexit();
- }
-
- mode = 0;
- mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
- mode |= SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
- SSL_CTX_set_mode(ctx, mode);
-
- if (getenv("ULTRAVNC_DSM_HELPER_SHOWCERT_ADH")) {
- SSL_CTX_set_cipher_list(ctx, "ADH:@STRENGTH");
- SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
- }
-
- ssl = SSL_new(ctx);
-
- if (ssl == NULL) {
- fprintf(stdout, "show_cert: SSL_new failed.\n");
- close(sock);
- enc_sslerrexit();
- }
-
- SSL_set_session_id_context(ssl, sid, strlen((char *)sid));
-
- if (! SSL_set_fd(ssl, sock)) {
- fprintf(stdout, "show_cert: SSL_set_fd failed.\n");
- close(sock);
- enc_sslerrexit();
- }
-
- SSL_set_connect_state(ssl);
-
- if (SSL_connect(ssl) <= 0) {
- unsigned long err = ERR_get_error();
- fprintf(stdout, "show_cert: SSL_connect failed.\n");
- if (err) {
- char str[256];
- ERR_error_string(err, str);
- fprintf(stdout, "ssl error: %s\n", str);
- }
- }
-
- SSL_get_verify_result(ssl);
-
- sk = SSL_get_peer_cert_chain(ssl);
- if (sk != NULL) {
- fprintf(stdout, "---\nCertificate chain\n");
- for (i=0; i < sk_X509_num(sk); i++) {
- char buf[2048];
- X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk,i)), buf, sizeof buf);
- fprintf(stdout, "%2d s:%s\n", i, buf);
- X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk,i)), buf, sizeof buf);
- fprintf(stdout, " i:%s\n", buf);
- }
- } else {
- fprintf(stdout, "show_cert: SSL_get_peer_cert_chain failed.\n");
- }
- fprintf(stdout, "---\n");
- peer = SSL_get_peer_certificate(ssl);
- bio = BIO_new_fp(stdout, BIO_NOCLOSE);
- if (peer != NULL) {
- char buf[2048];
- BIO_printf(bio,"Server certificate\n");
- PEM_write_bio_X509(bio, peer);
-
- X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
- BIO_printf(bio,"subject=%s\n",buf);
- X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
- BIO_printf(bio,"issuer=%s\n",buf);
- } else {
- fprintf(stdout, "show_cert: SSL_get_peer_certificate failed.\n");
- }
-
- c = SSL_get_current_cipher(ssl);
- BIO_printf(bio,"---\nNew, %s, Cipher is %s\n", SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
-
- if (peer != NULL) {
- EVP_PKEY *pktmp;
- pktmp = X509_get_pubkey(peer);
- BIO_printf(bio,"Server public key is %d bit\n", EVP_PKEY_bits(pktmp));
- EVP_PKEY_free(pktmp);
- }
- BIO_printf(bio,"---\nDONE\n---\n");
-
- fflush(stdout);
-
-#endif
- close(sock);
- exit(0);
-}
-
-#ifndef SOL_IPV6
-#ifdef IPPROTO_IPV6
-#define SOL_IPV6 IPPROTO_IPV6
-#endif
-#endif
-
-/*
- * Listens on incoming port for a client, then connects to remote server.
- * Then forks into two processes one is the encrypter the other the
- * decrypter.
- */
-static void enc_connections(int listen_port, char *connect_host, int connect_port) {
- int listen_fd = -1, listen_fd6 = -1, conn1 = -1, conn2 = -1, ret, one = 1;
- socklen_t clen;
- struct hostent *hp;
- struct sockaddr_in client, server;
- fd_set fds;
- int maxfd = -1;
-
- /* zero means use stdio (preferably from socketpair()) */
- if (listen_port == 0) {
- conn1 = fileno(stdin);
- goto use_stdio;
- }
-
- if (!strcmp(cipher, "showcert")) {
- goto use_stdio;
- }
-
- /* fd=n,m means use the supplied already established sockets */
- if (sscanf(connect_host, "fd=%d,%d", &conn1, &conn2) == 2) {
- goto use_input_fds;
- }
-
- /* create the listening socket: */
- memset(&client, 0, sizeof(client));
- client.sin_family = AF_INET;
- if (listen_port < 0) {
- /* negative port means use loopback */
- client.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- client.sin_port = htons(-listen_port);
- } else {
- client.sin_addr.s_addr = htonl(INADDR_ANY);
- client.sin_port = htons(listen_port);
- }
-
- listen_fd = socket(AF_INET, SOCK_STREAM, 0);
- if (listen_fd < 0) {
- perror("socket");
- goto try6;
- }
-
- ret = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR,
- (char *)&one, sizeof(one));
- if (ret < 0) {
- perror("setsockopt");
- close(listen_fd);
- listen_fd = -1;
- goto try6;
- }
-
- ret = bind(listen_fd, (struct sockaddr *) &client, sizeof(client));
- if (ret < 0) {
- perror("bind");
- close(listen_fd);
- listen_fd = -1;
- goto try6;
- }
-
- ret = listen(listen_fd, 2);
- if (ret < 0) {
- perror("listen");
- close(listen_fd);
- listen_fd = -1;
- goto try6;
- }
-
- try6:
-#ifdef AF_INET6
- if (!getenv("ULTRAVNC_DSM_HELPER_NOIPV6")) {
- struct sockaddr_in6 sin;
- int one = 1, sock = -1;
-
- sock = socket(AF_INET6, SOCK_STREAM, 0);
- if (sock < 0) {
- perror("socket6");
- goto fail;
- }
-
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
- perror("setsockopt6 SO_REUSEADDR");
- close(sock);
- sock = -1;
- goto fail;
- }
-
-#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
- if (setsockopt(sock, SOL_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
- perror("setsockopt6 IPV6_V6ONLY");
- close(sock);
- sock = -1;
- goto fail;
- }
-#endif
-
- memset((char *)&sin, 0, sizeof(sin));
- sin.sin6_family = AF_INET6;
-
- if (listen_port < 0) {
- sin.sin6_addr = in6addr_loopback;
- sin.sin6_port = htons(-listen_port);
- } else {
- sin.sin6_addr = in6addr_any;
- sin.sin6_port = htons(listen_port);
- }
-
- if (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
- perror("bind6");
- close(sock);
- sock = -1;
- goto fail;
- }
-
- if (listen(sock, 2) < 0) {
- perror("listen6");
- close(sock);
- sock = -1;
- goto fail;
- }
-
- fail:
- listen_fd6 = sock;
- }
-#endif
-
- if (listen_fd < 0 && listen_fd6 < 0) {
- fprintf(stderr, "%s: could not listen on port: %d\n",
- prog, listen_port);
- exit(1);
- }
-
- fprintf(stderr, "%s: waiting for connection on port: %d\n",
- prog, listen_port);
-
- /* wait for a connection: */
- FD_ZERO(&fds);
- if (listen_fd >= 0) {
- FD_SET(listen_fd, &fds);
- if (listen_fd > maxfd) {
- maxfd = listen_fd;
- }
- }
- if (listen_fd6 >= 0) {
- FD_SET(listen_fd6, &fds);
- if (listen_fd6 > maxfd) {
- maxfd = listen_fd6;
- }
- }
- if (select(maxfd+1, &fds, NULL, NULL, NULL) <= 0) {
- perror("select");
- exit(1);
- }
-
- if (FD_ISSET(listen_fd, &fds)) {
- clen = sizeof(client);
- conn1 = accept(listen_fd, (struct sockaddr *) &client, &clen);
- if (conn1 < 0) {
- perror("accept");
- exit(1);
- }
- } else if (FD_ISSET(listen_fd6, &fds)) {
-#ifdef AF_INET6
- struct sockaddr_in6 addr;
- socklen_t addrlen = sizeof(addr);
-
- conn1 = accept(listen_fd6, (struct sockaddr *) &addr, &addrlen);
- if (conn1 < 0) {
- perror("accept6");
- exit(1);
- }
-#else
- fprintf(stderr, "No IPv6 / AF_INET6 support.\n");
- exit(1);
-#endif
- }
-
- if (setsockopt(conn1, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) {
- perror("setsockopt TCP_NODELAY");
- exit(1);
- }
-
- /* done with the listening socket(s): */
- if (listen_fd >= 0) {
- close(listen_fd);
- }
- if (listen_fd6 >= 0) {
- close(listen_fd6);
- }
-
- if (getenv("ULTRAVNC_DSM_HELPER_BG")) {
- int p, n;
- if ((p = fork()) > 0) {
- fprintf(stderr, "%s: putting child %d in background.\n",
- prog, p);
- exit(0);
- } else if (p == -1) {
- fprintf(stderr, "%s: could not fork\n", prog);
- perror("fork");
- exit(1);
- }
- if (setsid() == -1) {
- fprintf(stderr, "%s: setsid failed\n", prog);
- perror("setsid");
- exit(1);
- }
- /* adjust our stdio */
- n = open("/dev/null", O_RDONLY);
- dup2(n, 0);
- dup2(n, 1);
- dup2(n, 2);
- if (n > 2) {
- close(n);
- }
- }
-
- use_stdio:
-
- fprintf(stderr, "%s: got connection: %d\n", prog, conn1);
-
- /* now connect to remote server: */
- memset(&server, 0, sizeof(server));
- server.sin_family = AF_INET;
- server.sin_port = htons(connect_port);
-
- if ((server.sin_addr.s_addr = inet_addr(connect_host)) == htonl(INADDR_NONE)) {
- if (!(hp = gethostbyname(connect_host))) {
- perror("gethostbyname");
- goto tryconn6;
- }
- server.sin_addr.s_addr = *(unsigned long *)hp->h_addr;
- }
-
- conn2 = socket(AF_INET, SOCK_STREAM, 0);
- if (conn2 < 0) {
- perror("socket");
- goto tryconn6;
- }
-
- if (connect(conn2, (struct sockaddr *)&server, (sizeof(server))) < 0) {
- perror("connect");
- goto tryconn6;
- }
-
- tryconn6:
-#ifdef AF_INET6
- if (conn2 < 0 && !getenv("ULTRAVNC_DSM_HELPER_NOIPV6")) {
- int err;
- struct addrinfo *ai;
- struct addrinfo hints;
- char service[32];
-
- fprintf(stderr, "connect[ipv6]: trying to connect via IPv6 to %s\n", connect_host);
- conn2 = -1;
-
- memset(&hints, 0, sizeof(hints));
- sprintf(service, "%d", connect_port);
-
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-#ifdef AI_ADDRCONFIG
- hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-#ifdef AI_NUMERICSERV
- hints.ai_flags |= AI_NUMERICSERV;
-#endif
-
- err = getaddrinfo(connect_host, service, &hints, &ai);
- if (err != 0) {
- fprintf(stderr, "getaddrinfo[%d]: %s\n", err, gai_strerror(err));
- } else {
- struct addrinfo *ap = ai;
- while (ap != NULL) {
- int fd = -1;
- fd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
- if (fd == -1) {
- perror("socket6");
- } else {
- int dmsg = 0;
- int res = connect(fd, ap->ai_addr, ap->ai_addrlen);
-#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
- if (res != 0) {
- int zero = 0;
- perror("connect6");
- dmsg = 1;
- if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, (char *)&zero, sizeof(zero)) == 0) {
- fprintf(stderr, "connect[ipv6]: trying again with IPV6_V6ONLY=0\n");
- res = connect(fd, ap->ai_addr, ap->ai_addrlen);
- dmsg = 0;
- }
- }
-#endif
- if (res == 0) {
- conn2 = fd;
- break;
- } else {
- if (!dmsg) perror("connect6");
- close(fd);
- }
- }
- ap = ap->ai_next;
- }
- freeaddrinfo(ai);
- }
- }
-#endif
- if (conn2 < 0) {
- fprintf(stderr, "could not connect to %s\n", connect_host);
- exit(1);
- }
- if (conn2 >= 0 && setsockopt(conn2, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) {
- perror("setsockopt TCP_NODELAY");
- }
-
- use_input_fds:
-
- if (!strcmp(cipher, "showcert")) {
- show_cert(conn2);
- close(conn2);
- exit(0);
- }
-
- if (securevnc) {
- securevnc_setup(conn1, conn2);
- }
-
- /* fork into two processes; one for each direction: */
- parent = getpid();
-
- child = fork();
-
- if (child == (pid_t) -1) {
- /* couldn't fork... */
- perror("fork");
- close(conn1);
- close(conn2);
- exit(1);
- }
-
- /* Do transfer/encode/decode loop: */
-
- if (child == 0) {
- /* encrypter: local-viewer -> remote-server */
- if (!strcmp(cipher, "none") || !strcmp(cipher, "relay")) {
- enc_raw_xfer(conn1, conn2);
- } else {
- enc_xfer(conn1, conn2, 1);
- }
- } else {
- /* decrypter: remote-server -> local-viewer */
- if (!strcmp(cipher, "none") || !strcmp(cipher, "relay")) {
- enc_raw_xfer(conn2, conn1);
- } else {
- enc_xfer(conn2, conn1, 0);
- }
- }
-}
-#endif /* ENC_HAVE_OPENSSL */
-
-static void doloop (int argc, char *argv[]) {
- int ms = atoi(getenv("ULTRAVNC_DSM_HELPER_LOOP"));
- if (ms > 0) {
- char *cmd;
- int i, len = 0;
- for (i = 0; i < argc; i++) {
- len += strlen(argv[i]) + 2;
- }
- cmd = (char *)malloc(len);
- cmd[0] = '\0';
- for (i = 0; i < argc; i++) {
- strcat(cmd, argv[i]);
- if (i < argc - 1) {
- strcat(cmd, " ");
- }
- }
-
- putenv("ULTRAVNC_DSM_HELPER_LOOP_SET=1");
- if (ms == 1) {
- ms = 500;
- }
- i = 0;
- while (1) {
- fprintf(stderr, "loop running[%d]: %s\n", ++i, cmd);
- system(cmd);
- usleep(1000 * ms);
- }
- }
-}
-
-extern int main (int argc, char *argv[]) {
- char *kf, *q;
-
- if (getenv("ULTRAVNC_DSM_HELPER_LOOP")) {
- if (!getenv("ULTRAVNC_DSM_HELPER_LOOP_SET")) {
- doloop(argc, argv);
- }
- }
-
- if (argc == 3) {
- if (!strcmp(argv[1], "showcert")) {
- enc_do(argv[1], NULL, NULL, argv[2]);
- return 0;
- }
- }
- if (argc == 4) {
- if (!strcmp(argv[1], "none") || !strcmp(argv[1], "relay")) {
- enc_do(argv[1], NULL, argv[2], argv[3]);
- return 0;
- }
- }
- if (argc < 5) {
- fprintf(stdout, "%s\n", usage);
- exit(1);
- }
-
- /* guard against pw= on cmdline (e.g. linux) */
- kf = strdup(argv[2]);
- q = strstr(argv[2], "pw=");
- if (q) {
- while (*q != '\0') {
- *q = '\0'; /* now ps(1) won't show it */
- q++;
- }
- }
-
- enc_do(argv[1], kf, argv[3], argv[4]);
-
- return 0;
-}
-
-/*
- * a crude utility to have this work "keyless" i.e. the vnc password
- * is used instead of a pre-shared key file.
- */
-
-/*
-
-#!/usr/bin/perl
-#
-# md5_to_rc4key.pl
-#
-# This program requires md5sum(1) installed on your machine.
-#
-# It translates a VNC password to a ultravnc dsm plugin
-# compatible key file.
-#
-# Supply VNC password on cmdline, capture in key file:
-#
-# md5_to_rc4key.pl swordfish > rc4.key
-# md5_to_rc4key.pl -a swordfish > arc4.key
-#
-# Use rc4.key with ultravnc_dsm_helper in msrc4 mode,
-# or arc4.key in either arc4 or aesv4 mode.
-#
-#
-$rfmt = 1;
-if ($ARGV[0] eq '-a') {
- $rfmt = 0;
- shift;
-}
-
-# n.b. this is not super secure against bad locals...
-
-$pw = shift;
-$tmp = "/tmp/md5out.$$";
-
-open(MD5, "| md5sum > $tmp");
-print MD5 $pw;
-close MD5;
-
-$md5 = `cat $tmp`;
-unlink $tmp;
-
-($md5, $junk) = split(/\s/, $md5);
-
-print "128 bit" if $rfmt;
-print 'a' x 4 if $rfmt;
-print 'b' x 12 if $rfmt;
-
-$str = '';
-foreach $d (split(//, $md5)) {
- $str .= $d;
- if (length($str) == 2) {
- push @key, $str;
- $str = '';
- }
-}
-
-@key = (reverse @key) if $rfmt;
-
-foreach $h (@key) {
- $c = pack('c', hex("0x$h"));
- print $c;
-}
-
-print 'c' x 48 if $rfmt;
-
-*/
-#endif /* _X11VNC_ENC_H */
diff --git a/x11vnc/enums.h b/x11vnc/enums.h
deleted file mode 100644
index d9ce84c..0000000
--- a/x11vnc/enums.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_ENUMS_H
-#define _X11VNC_ENUMS_H
-
-/* -- enums.h -- */
-
-enum {
- LR_UNSET = 0,
- LR_UNKNOWN,
- LR_DIALUP,
- LR_BROADBAND,
- LR_LAN
-};
-
-enum scroll_types {
- SCR_NONE = 0,
- SCR_MOUSE,
- SCR_KEY,
- SCR_FAIL,
- SCR_SUCCESS
-};
-
-#endif /* _X11VNC_ENUMS_H */
diff --git a/x11vnc/gui.c b/x11vnc/gui.c
deleted file mode 100644
index 6101adb..0000000
--- a/x11vnc/gui.c
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- gui.c -- */
-
-#include "x11vnc.h"
-#include "xevents.h"
-#include "win_utils.h"
-#include "remote.h"
-#include "cleanup.h"
-#include "xwrappers.h"
-#include "connections.h"
-
-#include "tkx11vnc.h"
-
-#define SYSTEM_TRAY_REQUEST_DOCK 0
-#define SYSTEM_TRAY_BEGIN_MESSAGE 1
-#define SYSTEM_TRAY_CANCEL_MESSAGE 2
-#define XEMBED_VERSION 0
-#define XEMBED_MAPPED (1 << 0)
-
-int icon_mode = 0; /* hack for -gui tray/icon */
-char *icon_mode_file = NULL;
-FILE *icon_mode_fh = NULL;
-int icon_mode_socks[ICON_MODE_SOCKS];
-int tray_manager_ok = 0;
-Window tray_request = None;
-Window tray_window = None;
-int tray_unembed = 0;
-pid_t run_gui_pid = 0;
-pid_t gui_pid = 0;
-
-
-char *get_gui_code(void);
-int tray_embed(Window iconwin, int remove);
-void do_gui(char *opts, int sleep);
-
-
-static Window tweak_tk_window_id(Window win);
-static int tray_manager_running(Display *d, Window *manager);
-static void run_gui(char *gui_xdisplay, int connect_to_x11vnc, int start_x11vnc,
- int simple_gui, pid_t parent, char *gui_opts);
-
-
-char *get_gui_code(void) {
- return gui_code;
-}
-
-static Window tweak_tk_window_id(Window win) {
-#if NO_X11
- if (!win) {}
- return None;
-#else
- char *name = NULL;
- Window parent, new_win;
-
- if (getenv("NO_TWEAK_TK_WINDOW_ID")) {
- return win;
- }
-
- /* hack for tk, does not report outermost window */
- new_win = win;
- parent = parent_window(win, &name);
- if (parent && name != NULL) {
- lowercase(name);
- if (strstr(name, "wish") || strstr(name, "x11vnc")) {
- new_win = parent;
- rfbLog("tray_embed: using parent: %s\n", name);
- }
- }
- if (name != NULL) {
- XFree_wr(name);
- }
- return new_win;
-#endif /* NO_X11 */
-}
-
-int tray_embed(Window iconwin, int remove) {
-#if NO_X11
- RAWFB_RET(0)
- if (!iconwin || !remove) {}
- return 0;
-#else
- XEvent ev;
- XErrorHandler old_handler;
- Window manager;
- Atom xembed_info;
- Atom tatom;
- XWindowAttributes attr;
- long info[2] = {XEMBED_VERSION, XEMBED_MAPPED};
- long data = 0;
-
- RAWFB_RET(0)
-
- if (remove) {
- if (!valid_window(iconwin, &attr, 1)) {
- return 0;
- }
- iconwin = tweak_tk_window_id(iconwin);
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
-
- /*
- * unfortunately no desktops seem to obey this
- * part of the XEMBED spec yet...
- */
- XReparentWindow(dpy, iconwin, rootwin, 0, 0);
-
- XSetErrorHandler(old_handler);
- if (trapped_xerror) {
- trapped_xerror = 0;
- return 0;
- }
- trapped_xerror = 0;
- return 1;
- }
-
- xembed_info = XInternAtom(dpy, "_XEMBED_INFO", False);
- if (xembed_info == None) {
- return 0;
- }
-
- if (!tray_manager_running(dpy, &manager)) {
- return 0;
- }
-
- memset(&ev, 0, sizeof(ev));
- ev.xclient.type = ClientMessage;
- ev.xclient.window = manager;
- ev.xclient.message_type = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE",
- False);
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = CurrentTime;
- ev.xclient.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
- ev.xclient.data.l[2] = iconwin;
- ev.xclient.data.l[3] = 0;
- ev.xclient.data.l[4] = 0;
-
- if (!valid_window(iconwin, &attr, 1)) {
- return 0;
- }
-
- iconwin = tweak_tk_window_id(iconwin);
- ev.xclient.data.l[2] = iconwin;
-
- XUnmapWindow(dpy, iconwin);
-
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
-
- XSendEvent(dpy, manager, False, NoEventMask, &ev);
- XSync(dpy, False);
-
- if (trapped_xerror) {
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
- return 0;
- }
-
- XChangeProperty(dpy, iconwin, xembed_info, xembed_info, 32,
- PropModeReplace, (unsigned char *)&info, 2);
-
-#if 0
-{
-XSizeHints *xszh = XAllocSizeHints();
-xszh->flags = PMinSize;
-xszh->min_width = 24;
-xszh->min_height = 24;
-XSetWMNormalHints(dpy, iconwin, xszh);
-}
-#endif
-
- /* kludge for KDE evidently needed... */
- tatom = XInternAtom(dpy, "KWM_DOCKWINDOW", False);
- XChangeProperty(dpy, iconwin, tatom, tatom, 32, PropModeReplace,
- (unsigned char *)&data, 1);
- tatom = XInternAtom(dpy, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
- XChangeProperty(dpy, iconwin, tatom, XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)&data, 1);
-
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
- return 1;
-#endif /* NO_X11 */
-}
-
-static int tray_manager_running(Display *d, Window *manager) {
-#if NO_X11
- RAWFB_RET(0)
- if (!d || !manager) {}
- return 0;
-#else
- char tray_string[100];
- Atom tray_manager;
- Window tray_win;
-
- RAWFB_RET(0)
-
- if (manager) {
- *manager = None;
- }
- sprintf(tray_string, "_NET_SYSTEM_TRAY_S%d", scr);
-
- tray_manager = XInternAtom(d, tray_string, True);
- if (tray_manager == None) {
- return 0;
- }
-
- tray_win = XGetSelectionOwner(d, tray_manager);
- if (manager) {
- *manager = tray_win;
- }
-
- if (tray_win == None) {
- return 0;
- } else {
- return 1;
- }
-#endif /* NO_X11 */
-}
-
-static char *gui_geometry = NULL;
-static int icon_in_tray = 0;
-static char *icon_mode_embed_id = NULL;
-static char *icon_mode_font = NULL;
-static char *icon_mode_params = NULL;
-
-static int got_sigusr1 = 0;
-
-static void sigusr1 (int sig) {
- got_sigusr1 = 1;
- if (0) sig = 0;
-}
-
-/* Most of the following mess is for wish on Solaris: */
-
-static char *extra_path = ":/usr/local/bin:/usr/bin/X11:/usr/sfw/bin"
- ":/usr/X11R6/bin:/usr/openwin/bin:/usr/dt/bin:/opt/sfw/bin";
-static char *wishes[] = {"wish8.4", "wish", "wish8.3", "wish8.5", "wish8.6", "wish8.7", "wishx", "wish8.0", NULL};
-
-static void run_gui(char *gui_xdisplay, int connect_to_x11vnc, int start_x11vnc,
- int simple_gui, pid_t parent, char *gui_opts) {
- char *x11vnc_xdisplay = NULL;
- char cmd[100];
- char *wish = NULL, *orig_path, *full_path, *tpath, *p;
- char *old_xauth = NULL;
- int try_max = 4, sleep = 300, totms, rc = 0;
- pid_t mypid = getpid();
- FILE *pipe, *tmpf;
-
-if (0) fprintf(stderr, "run_gui: %s -- %d %d\n", gui_xdisplay, connect_to_x11vnc, (int) parent);
- if (*gui_code == '\0') {
- rfbLog("gui: gui not compiled into this program.\n");
- exit(0);
- }
- if (getenv("DISPLAY") != NULL) {
- /* worst case */
- x11vnc_xdisplay = strdup(getenv("DISPLAY"));
- }
- if (use_dpy) {
- /* better */
- x11vnc_xdisplay = strdup(use_dpy);
- }
- if (connect_to_x11vnc) {
- int i;
- rfbLogEnable(1);
- if (! client_connect_file) {
- if (getenv("XAUTHORITY") != NULL) {
- old_xauth = strdup(getenv("XAUTHORITY"));
- } else {
- old_xauth = strdup("");
- }
- dpy = XOpenDisplay_wr(x11vnc_xdisplay);
- if (! dpy && auth_file) {
- set_env("XAUTHORITY", auth_file);
- dpy = XOpenDisplay_wr(x11vnc_xdisplay);
- }
- if (! dpy && ! x11vnc_xdisplay) {
- /* worstest case */
- x11vnc_xdisplay = strdup(":0");
- dpy = XOpenDisplay_wr(x11vnc_xdisplay);
- }
- if (! dpy) {
- rfbLog("gui: could not open x11vnc "
- "display: %s\n", NONUL(x11vnc_xdisplay));
-#ifdef MACOSX
- goto macjump;
-#endif
- exit(1);
- }
- scr = DefaultScreen(dpy);
- rootwin = RootWindow(dpy, scr);
- initialize_vnc_connect_prop();
- initialize_x11vnc_remote_prop();
- }
-
-#ifdef MACOSX
- macjump:
-#endif
-
- signal(SIGUSR1, sigusr1);
- got_sigusr1 = 0;
- totms = 0;
- while (totms < 3500) {
- usleep(50*1000);
- totms += 50;
- if (got_sigusr1) {
- fprintf(stderr, "\n");
- if (! quiet) rfbLog("gui: got SIGUSR1\n");
- break;
- }
- if (! start_x11vnc && totms >= 150) {
- break;
- }
- }
- signal(SIGUSR1, SIG_DFL);
- if (! got_sigusr1) fprintf(stderr, "\n");
-
- if (!quiet && ! got_sigusr1) {
- rfbLog("gui: trying to contact a x11vnc server at X"
- " display %s ...\n", NONUL(x11vnc_xdisplay));
- }
-
- for (i=0; i<try_max; i++) {
- if (! got_sigusr1) {
- if (!quiet) {
- rfbLog("gui: pinging %s try=%d ...\n",
- NONUL(x11vnc_xdisplay), i+1);
- }
- rc = send_remote_cmd("qry=ping", 1, 1);
- if (rc == 0) {
- break;
- }
- } else {
- rc = 0;
- break;
- }
- if (parent && mypid != parent && kill(parent, 0) != 0) {
- rfbLog("gui: parent process %d has gone"
- " away: bailing out.\n", parent);
- rc = 1;
- break;
- }
- usleep(sleep*1000);
- }
- set_env("X11VNC_XDISPLAY", x11vnc_xdisplay);
- if (getenv("XAUTHORITY") != NULL) {
- set_env("X11VNC_AUTH_FILE", getenv("XAUTHORITY"));
- }
- if (rc == 0) {
- rfbLog("gui: ping succeeded.\n");
- set_env("X11VNC_CONNECT", "1");
- } else {
- rfbLog("gui: could not connect to: '%s', try"
- " again manually.\n", x11vnc_xdisplay);
- }
- if (client_connect_file) {
- set_env("X11VNC_CONNECT_FILE", client_connect_file);
- }
- if (dpy) {
- XCloseDisplay_wr(dpy);
- dpy = NULL;
- }
- if (old_xauth) {
- if (*old_xauth == '\0') {
- /* wasn't set, hack it out if it is now */
- char *xauth = getenv("XAUTHORITY");
- if (xauth) {
- *(xauth-2) = '_'; /* yow */
- }
- } else {
- set_env("XAUTHORITY", old_xauth);
- }
- free(old_xauth);
- }
- rfbLogEnable(0);
- }
-
- orig_path = getenv("PATH");
- if (! orig_path) {
- orig_path = strdup("/bin:/usr/bin:/usr/bin/X11");
- }
- full_path = (char *) malloc(strlen(orig_path)+strlen(extra_path)+1);
- strcpy(full_path, orig_path);
- strcat(full_path, extra_path);
-
- tpath = strdup(full_path);
- p = strtok(tpath, ":");
-
- while (p) {
- char *try;
- struct stat sbuf;
- int i;
-
- try = (char *) malloc(strlen(p) + 1 + strlen("wish8.4") + 1);
- i = 0;
- while (wishes[i] != NULL) {
- sprintf(try, "%s/%s", p, wishes[i]);
- if (stat(try, &sbuf) == 0) {
- /* assume executable, should check mode */
- wish = wishes[i];
- break;
- }
- i++;
- }
- free(try);
- if (wish) {
- break;
- }
- p = strtok(NULL, ":");
- }
- free(tpath);
- if (!wish) {
- wish = strdup("wish");
- }
- if (getenv("WISH")) {
- char *w = getenv("WISH");
- if (strcmp(w, "")) {
- wish = strdup(w);
- }
- }
- if (getenv("DEBUG_WISH")) {
- fprintf(stderr, "wish: %s\n", wish);
- }
- set_env("PATH", full_path);
- set_env("DISPLAY", gui_xdisplay);
- set_env("X11VNC_PROG", program_name);
- set_env("X11VNC_CMDLINE", program_cmdline);
- set_env("X11VNC_WISHCMD", wish);
- if (simple_gui) {
- set_env("X11VNC_SIMPLE_GUI", "1");
- }
- if (gui_opts) {
- set_env("X11VNC_GUI_PARAMS", gui_opts);
- }
- if (gui_geometry) {
- set_env("X11VNC_GUI_GEOM", gui_geometry);
- }
- if (start_x11vnc) {
- set_env("X11VNC_STARTED", "1");
- }
- if (icon_mode) {
- set_env("X11VNC_ICON_MODE", "1");
- if (icon_mode_file) {
- set_env("X11VNC_CLIENT_FILE", icon_mode_file);
- }
- if (icon_in_tray) {
- if (tray_manager_ok) {
- set_env("X11VNC_ICON_MODE", "TRAY:RUNNING");
- } else {
- set_env("X11VNC_ICON_MODE", "TRAY");
- }
- } else {
- set_env("X11VNC_ICON_MODE", "ICON");
- }
- if (icon_mode_params) {
- char *p, *str = strdup(icon_mode_params);
- p = strtok(str, ":-/,.+");
- while (p) {
- if(strstr(p, "setp") == p) {
- set_env("X11VNC_ICON_SETPASS", "1");
- if (rc != 0) {
- set_env("X11VNC_SETPASS_FAIL", "1");
- }
- } else if(strstr(p, "noadvanced") == p) {
- set_env("X11VNC_ICON_NOADVANCED", "1");
- } else if(strstr(p, "minimal") == p) {
- set_env("X11VNC_ICON_MINIMAL", "1");
- } else if (strstr(p, "0x") == p) {
- set_env("X11VNC_ICON_EMBED_ID", p);
- icon_mode_embed_id = strdup(p);
- }
- p = strtok(NULL, ":-/,.+");
- }
- free(str);
- }
- }
- if (icon_mode_font) {
- set_env("X11VNC_ICON_FONT", icon_mode_font);
- }
-
- /* gui */
- if (no_external_cmds || !cmd_ok("gui")) {
- fprintf(stderr, "cannot run external commands in -nocmds "
- "mode:\n");
- fprintf(stderr, " \"%s\"\n", "gui + wish");
- fprintf(stderr, " exiting.\n");
- fflush(stderr);
- exit(1);
- }
-
- tmpf = tmpfile();
- if (tmpf == NULL) {
- /* if no tmpfile, use a pipe */
- if (icon_mode_embed_id) {
- if (strlen(icon_mode_embed_id) < 20) {
- strcat(cmd, " -use ");
- strcat(cmd, icon_mode_embed_id);
- }
- }
- close_exec_fds();
- pipe = popen(cmd, "w");
- if (! pipe) {
- fprintf(stderr, "could not run: %s\n", cmd);
- perror("popen");
- }
- fprintf(pipe, "%s", gui_code);
- pclose(pipe);
- } else {
- /*
- * we prefer a tmpfile since then this x11vnc process
- * will then be gone, otherwise the x11vnc program text
- * will still be in use.
- */
- int n = fileno(tmpf);
- fprintf(tmpf, "%s", gui_code);
- fflush(tmpf);
- rewind(tmpf);
- dup2(n, 0);
- close(n);
- if (icon_mode_embed_id) {
- execlp(wish, wish, "-", "-use", icon_mode_embed_id,
- (char *) NULL);
- } else {
- execlp(wish, wish, "-", (char *) NULL);
- }
- fprintf(stderr, "could not exec wish: %s -\n", wish);
- perror("execlp");
- }
- exit(0);
-}
-
-void do_gui(char *opts, int sleep) {
- char *s, *p;
- char *old_xauth = NULL;
- char *gui_xdisplay = NULL;
- int got_gui_xdisplay = 0;
- int start_x11vnc = 1;
- int connect_to_x11vnc = 0;
- int simple_gui = 0, none_gui = 0;
- int portprompt = 0;
- Display *test_dpy;
-
- if (opts) {
- s = strdup(opts);
- } else {
- s = strdup("");
- }
-
- if (use_dpy) {
- /* worst case */
- gui_xdisplay = strdup(use_dpy);
-
- }
- if (getenv("DISPLAY") != NULL) {
- /* better */
- gui_xdisplay = strdup(getenv("DISPLAY"));
- }
-
- p = strtok(s, ",");
-
- while(p) {
- if (*p == '\0') {
- ;
- } else if (strchr(p, ':') != NULL) {
- /* best */
- if (gui_xdisplay) {
- free(gui_xdisplay);
- }
- gui_xdisplay = strdup(p);
- got_gui_xdisplay = 1;
- } else if (!strcmp(p, "wait")) {
- start_x11vnc = 0;
- connect_to_x11vnc = 0;
- } else if (!strcmp(p, "none")) {
- none_gui = 1;
- } else if (!strcmp(p, "portprompt")) {
- start_x11vnc = 0;
- connect_to_x11vnc = 0;
- portprompt = 1;
- } else if (!strcmp(p, "conn") || !strcmp(p, "connect")) {
- start_x11vnc = 0;
- connect_to_x11vnc = 1;
- } else if (!strcmp(p, "ez") || !strcmp(p, "simple")) {
- simple_gui = 1;
- } else if (strstr(p, "iconfont") == p) {
- char *q;
- if ((q = strchr(p, '=')) != NULL) {
- icon_mode_font = strdup(q+1);
- }
- } else if (strstr(p, "full") == p) {
- if (strstr(p, "setp") && 0) {
- set_env("X11VNC_ICON_MODE", "2");
- set_env("X11VNC_ICON_SETPASS", "2");
- }
- } else if (strstr(p, "tray") == p || strstr(p, "icon") == p) {
- char *q;
- icon_mode = 1;
- if ((q = strchr(p, '=')) != NULL) {
- icon_mode_params = strdup(q+1);
- if (strstr(icon_mode_params, "setp")) {
- deny_all = 1;
- }
- }
- if (strstr(p, "tray") == p) {
- icon_in_tray = 1;
- }
- } else if (strstr(p, "geom") == p) {
- char *q;
- if ((q = strchr(p, '=')) != NULL) {
- gui_geometry = strdup(q+1);
- }
- } else {
- fprintf(stderr, "unrecognized gui opt: %s\n", p);
- }
-
- p = strtok(NULL, ",");
- }
- free(s);
-
- if (none_gui) {
- if (!start_x11vnc) {
- exit(0);
- }
- return;
- }
- if (start_x11vnc) {
- connect_to_x11vnc = 1;
- }
-
-
-#ifdef MACOSX
- goto startit;
-#endif
-
- if (icon_mode && !got_gui_xdisplay) {
- /* for tray mode, prefer the polled DISPLAY */
- if (use_dpy) {
- if (gui_xdisplay) {
- free(gui_xdisplay);
- }
- gui_xdisplay = strdup(use_dpy);
- }
- }
-
- if (! gui_xdisplay) {
- fprintf(stderr, "error: cannot determine X DISPLAY for gui"
- " to display on.\n");
- exit(1);
- }
- if (!quiet && !portprompt) {
- fprintf(stderr, "starting gui, trying display: %s\n",
- gui_xdisplay);
- }
- test_dpy = XOpenDisplay_wr(gui_xdisplay);
- if (! test_dpy && auth_file) {
- if (getenv("XAUTHORITY") != NULL) {
- old_xauth = strdup(getenv("XAUTHORITY"));
- }
- set_env("XAUTHORITY", auth_file);
- test_dpy = XOpenDisplay_wr(gui_xdisplay);
- }
- if (! test_dpy) {
- if (! old_xauth && getenv("XAUTHORITY") != NULL) {
- old_xauth = strdup(getenv("XAUTHORITY"));
- }
- set_env("XAUTHORITY", "");
- test_dpy = XOpenDisplay_wr(gui_xdisplay);
- }
- if (! test_dpy) {
- fprintf(stderr, "error: cannot connect to gui X DISPLAY: %s\n",
- gui_xdisplay);
- exit(1);
- }
- if (icon_mode && icon_in_tray) {
- if (tray_manager_running(test_dpy, NULL)) {
- tray_manager_ok = 1;
- } else {
- tray_manager_ok = 0;
- }
- }
- XCloseDisplay_wr(test_dpy);
-
-#ifdef MACOSX
- startit:
-#endif
- if (portprompt) {
- char *cmd, *p, *p2, *p1, *p0 = getenv("PATH");
- char tf1[] = "/tmp/x11vnc_port_prompt.2XXXXXX";
- char tf2[] = "/tmp/x11vnc_port_prompt.1XXXXXX";
- int fd;
- char *dstr = "", *wish = NULL;
- char line[128];
- FILE *fp;
-
- if (no_external_cmds || !cmd_ok("gui")) {
- return;
- }
-
- if (gui_xdisplay) {
- dstr = gui_xdisplay;
- if (strchr(gui_xdisplay, '\'')) {
- return;
- }
- }
- if (!p0) {
- p0 = "";
- }
- if (strchr(p0, '\'')) {
- return;
- }
-
- fd = mkstemp(tf2);
- if (fd < 0) {
- return;
- }
- close(fd);
-
- fd = mkstemp(tf1);
- if (fd < 0) {
- unlink(tf2);
- return;
- }
-
- write(fd, gui_code, strlen(gui_code));
- close(fd);
-
- p1 = (char *) malloc(10 + strlen(p0) + strlen(extra_path));
- sprintf(p1, "%s:%s", p0, extra_path);
- p2 = strdup(p1);
- p = strtok(p2, ":");
-
- while (p) {
- char *try;
- struct stat sbuf;
- int i;
-
- try = (char *) malloc(strlen(p) + 1 + strlen("wish8.4") + 1);
- i = 0;
- while (wishes[i] != NULL) {
- sprintf(try, "%s/%s", p, wishes[i]);
- if (stat(try, &sbuf) == 0) {
- /* assume executable, should check mode */
- wish = wishes[i];
- break;
- }
- i++;
- }
- free(try);
- if (wish) {
- break;
- }
- p = strtok(NULL, ":");
- }
- free(p2);
-
- if (!wish) {
- wish = "wish";
- }
-
- cmd = (char *) malloc(200 + strlen(dstr) + strlen(p1));
-
- if (!strcmp(dstr, "")) {
- sprintf(cmd, "env PATH='%s' %s %s -name x11vnc_port_prompt -portprompt > %s", p1, wish, tf1, tf2);
- } else {
- sprintf(cmd, "env PATH='%s' DISPLAY='%s' %s %s -name x11vnc_port_prompt -portprompt > %s", p1, dstr, wish, tf1, tf2);
- }
- if (getenv("X11VNC_DEBUG_PORTPROMPT")) {
- fprintf(stderr, "cmd=%s\n", cmd);
- }
- if (use_openssl) {
- set_env("X11VNC_SSL_ENABLED", "1");
- }
- if (allow_list && !strcmp(allow_list, "127.0.0.1")) {
- set_env("X11VNC_LOCALHOST_ENABLED", "1");
- }
- if (got_ultrafilexfer) {
- set_env("X11VNC_FILETRANSFER_ENABLED", "ultra");
- } else if (tightfilexfer) {
- set_env("X11VNC_FILETRANSFER_ENABLED", "tight");
- }
- system(cmd);
- free(cmd);
- free(p1);
-
- fp = fopen(tf2, "r");
- memset(line, 0, sizeof(line));
- if (fp) {
- fgets(line, 128, fp);
- fclose(fp);
- if (line[0] != '\0') {
- int readport = atoi(line);
- if (readport > 0) {
- got_rfbport_val = readport;
- }
- }
- }
-
- if (strstr(line, "ssl0")) {
- if (use_openssl) use_openssl = 0;
- } else if (strstr(line, "ssl1")) {
- if (!use_openssl) {
- use_openssl = 1;
- openssl_pem = strdup("SAVE_NOPROMPT");
- set_env("X11VNC_GOT_SSL", "1");
- }
- }
-
- if (strstr(line, "localhost0")) {
- if (allow_list && !strcmp(allow_list, "127.0.0.1")) {
- allow_list = NULL;
- }
- } else if (strstr(line, "localhost1")) {
- allow_list = strdup("127.0.0.1");
- }
-
- if (strstr(line, "ft_ultra")) {
- got_ultrafilexfer = 1;
- tightfilexfer = 0;
- } else if (strstr(line, "ft_tight")) {
- got_ultrafilexfer = 0;
- tightfilexfer = 1;
- } else if (strstr(line, "ft_none")) {
- got_ultrafilexfer = 0;
- tightfilexfer = 0;
- }
-
- unlink(tf1);
- unlink(tf2);
-
- if (old_xauth) {
- set_env("XAUTHORITY", old_xauth);
- }
-
- return;
- }
-
- if (start_x11vnc) {
-
-#if LIBVNCSERVER_HAVE_FORK
- /* fork into the background now */
- int p;
- pid_t parent = getpid();
-
- if (icon_mode) {
- char tf[] = "/tmp/x11vnc.tray.XXXXXX";
- int fd;
-
- fd = mkstemp(tf);
- if (fd < 0) {
- icon_mode = 0;
- } else {
- close(fd);
- icon_mode_fh = fopen(tf, "w");
- if (! icon_mode_fh) {
- icon_mode = 0;
- } else {
- chmod(tf, 0400);
- icon_mode_file = strdup(tf);
- rfbLog("icon_mode_file=%s\n", icon_mode_file);
- fprintf(icon_mode_fh, "none\n");
- fprintf(icon_mode_fh, "none\n");
- fflush(icon_mode_fh);
- if (! got_connect_once) {
- if (!client_connect && !connect_or_exit) {
- /* want -forever for tray? */
- connect_once = 0;
- }
- }
- }
- }
- }
-
- if ((p = fork()) > 0) {
- ; /* parent */
- } else if (p == -1) {
- fprintf(stderr, "could not fork\n");
- perror("fork");
- clean_up_exit(1);
- } else {
- if (sleep > 0) {
- usleep(sleep * 1000 * 1000);
- }
- run_gui(gui_xdisplay, connect_to_x11vnc, start_x11vnc,
- simple_gui, parent, opts);
- exit(1);
- }
- if (connect_to_x11vnc) {
- run_gui_pid = p;
- gui_pid = p;
- }
-#else
- fprintf(stderr, "system does not support fork: start "
- "x11vnc in the gui.\n");
- start_x11vnc = 0;
-#endif
- }
- if (!start_x11vnc) {
- run_gui(gui_xdisplay, connect_to_x11vnc, start_x11vnc,
- simple_gui, 0, opts);
- exit(1);
- }
- if (old_xauth) {
- set_env("XAUTHORITY", old_xauth);
- }
-}
-
-
diff --git a/x11vnc/gui.h b/x11vnc/gui.h
deleted file mode 100644
index d097ddb..0000000
--- a/x11vnc/gui.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_GUI_H
-#define _X11VNC_GUI_H
-
-/* -- gui.h -- */
-
-extern int icon_mode;
-extern char *icon_mode_file;
-extern FILE *icon_mode_fh;
-extern int icon_mode_socks[];
-extern int tray_manager_ok;
-extern Window tray_request;
-extern Window tray_window;
-extern int tray_unembed;
-extern pid_t run_gui_pid;
-extern pid_t gui_pid;
-
-extern char *get_gui_code(void);
-extern int tray_embed(Window iconwin, int remove);
-extern void do_gui(char *opts, int sleep);
-
-#endif /* _X11VNC_GUI_H */
diff --git a/x11vnc/help.c b/x11vnc/help.c
deleted file mode 100644
index 5cd5c12..0000000
--- a/x11vnc/help.c
+++ /dev/null
@@ -1,6441 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- help.c -- */
-
-#include "x11vnc.h"
-#include "xdamage.h"
-#include "cursor.h"
-
-/*
- * text printed out under -help option
- */
-
-void print_help(int mode);
-void print_license(void);
-void xopen_display_fail_message(char *disp);
-void nopassword_warning_msg(int gotloc);
-
-
-void print_help(int mode) {
-#if !SKIP_HELP
- char help[] =
-"\n"
-"x11vnc: allow VNC connections to real X11 displays. %s\n"
-"\n"
-"(type \"x11vnc -opts\" to just list the options.)\n"
-"\n"
-"Typical usage is:\n"
-"\n"
-" Run this command in a shell on the remote machine \"far-host\"\n"
-" with X session you wish to view:\n"
-"\n"
-" x11vnc -display :0\n"
-"\n"
-" Then run this in another window on the machine you are sitting at:\n"
-"\n"
-" vncviewer far-host:0\n"
-"\n"
-"Once x11vnc establishes connections with the X11 server and starts listening\n"
-"as a VNC server it will print out a string: PORT=XXXX where XXXX is typically\n"
-"5900 (the default VNC server port). One would next run something like\n"
-"this on the local machine: \"vncviewer hostname:N\" where \"hostname\" is\n"
-"the name of the machine running x11vnc and N is XXXX - 5900, i.e. usually\n"
-"\"vncviewer hostname:0\".\n"
-"\n"
-"By default x11vnc will not allow the screen to be shared and it will exit\n"
-"as soon as the client disconnects. See -shared and -forever below to override\n"
-"these protections. See the FAQ for details how to tunnel the VNC connection\n"
-"through an encrypted channel such as ssh(1). In brief:\n"
-"\n"
-" ssh -t -L 5900:localhost:5900 far-host 'x11vnc -localhost -display :0'\n"
-"\n"
-" vncviewer -encodings 'copyrect tight zrle hextile' localhost:0\n"
-"\n"
-"Also, use of a VNC password (-rfbauth or -passwdfile) is strongly recommended.\n"
-"\n"
-"For additional info see: http://www.karlrunge.com/x11vnc/\n"
-" and http://www.karlrunge.com/x11vnc/faq.html\n"
-"\n"
-"\n"
-"Config file support: if the file $HOME/.x11vncrc exists then each line in\n"
-"it is treated as a single command line option. Disable with -norc. For\n"
-"each option name, the leading character \"-\" is not required. E.g. a line\n"
-"that is either \"forever\" or \"-forever\" may be used and are equivalent.\n"
-"Likewise \"wait 100\" or \"-wait 100\" are acceptable and equivalent lines.\n"
-"The \"#\" character comments out to the end of the line in the usual way\n"
-"(backslash it for a literal). Leading and trailing whitespace is trimmed off.\n"
-"Lines may be continued with a \"\\\" as the last character of a line (it\n"
-"becomes a space character).\n"
-"\n"
-"Options:\n"
-"\n"
-"-display disp X11 server display to connect to, usually :0. The X\n"
-" server process must be running on same machine and\n"
-" support MIT-SHM. Equivalent to setting the DISPLAY\n"
-" environment variable to \"disp\".\n"
-"\n"
-" See the description below of the \"-display WAIT:...\"\n"
-" extensions, where alias \"-find\" will find the user's\n"
-" display automatically, and \"-create\" will create a\n"
-" Xvfb session if no session is found.\n"
-"\n"
-"-auth file Set the X authority file to be \"file\", equivalent to\n"
-" setting the XAUTHORITY environment variable to \"file\"\n"
-" before startup. Same as -xauth file. See Xsecurity(7),\n"
-" xauth(1) man pages for more info.\n"
-"\n"
-" Use '-auth guess' to have x11vnc use its -findauth\n"
-" mechanism (described below) to try to guess the\n"
-" XAUTHORITY filename and use it.\n"
-"\n"
-" XDM/GDM/KDM: if you are running x11vnc as root and want\n"
-" to find the XAUTHORITY before anyone has logged into an\n"
-" X session yet, use: x11vnc -env FD_XDM=1 -auth guess ...\n"
-" (This will also find the XAUTHORITY if a user is already\n"
-" logged into the X session.) When running as root,\n"
-" FD_XDM=1 will be tried if the initial -auth guess fails.\n"
-"\n"
-"-N If the X display is :N, try to set the VNC display to\n"
-" also be :N This just sets the -rfbport option to 5900+N\n"
-" The program will exit immediately if that port is not\n"
-" available. The -N option only works with normal -display\n"
-" usage, e.g. :0 or :8, -N is ignored in the -display\n"
-" WAIT:..., -create, -find, -svc, -redirect, etc modes.\n"
-"\n"
-"-autoport n Automatically probe for a free VNC port starting at n.\n"
-" The default is to start probing at 5900. Use this to\n"
-" stay away from other VNC servers near 5900.\n"
-"\n"
-"-rfbport str The VNC port to listen on (a LibVNCServer option), e.g.\n"
-" 5900, 5901, etc. If specified as \"-rfbport PROMPT\"\n"
-" then the x11vnc -gui is used to prompt the user to\n"
-" enter the port number.\n"
-"\n"
-#if X11VNC_IPV6
-"-6 IPv6 listening support. In addition to IPv4, the\n"
-" IPv6 address is listened on for incoming connections.\n"
-" The same port number as IPv4 is used.\n"
-"\n"
-#if X11VNC_LISTEN6
-" NOTE: This x11vnc binary was compiled to have the\n"
-" \"-6\" IPv6 listening mode ENABLED by default (CPPFLAGS\n"
-" -DX11VNC_LISTEN6=1). So to disable IPv6 listening mode\n"
-" you MUST supply the \"-no6\" option (see below.)\n"
-#else
-" NOTE: This x11vnc binary was compiled to have\n"
-" the \"-6\" IPv6 listening mode DISABLED by default\n"
-" (CPPFLAGS -DX11VNC_LISTEN6=0).\n"
-#endif
-"\n"
-" The \"-6\" mode works for both normal connections and\n"
-" -ssl encrypted ones. Nearly everything is supported\n"
-" for the IPv6 case, but there are a few exceptions.\n"
-" See -stunnel for its IPv6 support.\n"
-"\n"
-" Currently, for absolutely everything to work correctly\n"
-" the machine may need to have some IPv4 support, at the\n"
-" least for the loopback interface. However, for nearly\n"
-" all usage modes no IPv4 support is required. See -nopiv4.\n"
-"\n"
-" If you have trouble compiling or running in IPv6 mode,\n"
-" set -DX11VNC_IPV6=0 in CPPFLAGS when configuring to\n"
-" disable IPv6 support.\n"
-"\n"
-"-no6 Disable IPv6 listening support (only useful if the\n"
-" \"-6\" mode is compiled in to be the default; see the\n"
-" X11VNC_LISTEN6 description above under \"-6\".)\n"
-"\n"
-"-noipv6 Do not try to use IPv6 for any listening or connecting\n"
-" sockets. This includes both the listening service\n"
-" port(s) and outgoing connections from -connect,\n"
-" -connect_or_exit, or -proxy. Use this if you are having\n"
-" problems due to IPv6.\n"
-"\n"
-"-noipv4 Do not try to use IPv4 for any listening or connecting\n"
-" sockets. This is mainly for exploring the behavior of\n"
-" x11vnc on an IPv6-only system, but may have other uses.\n"
-"\n"
-#endif
-"-reopen If the X server connection is disconnected, try to\n"
-" reopen the X display (up to one time.) This is of use\n"
-" for display managers like GDM (KillInitClients option)\n"
-" that kill x11vnc just after the user logs into the\n"
-" X session. Note: the reopened state may be unstable.\n"
-" Set X11VNC_REOPEN_DISPLAY=n to reopen n times and\n"
-" set X11VNC_REOPEN_SLEEP_MAX to the number of seconds,\n"
-" default 10, to keep trying to reopen the display (once\n"
-" per second.)\n"
-"\n"
-" Update: as of 0.9.9, x11vnc tries to automatically avoid\n"
-" being killed by the display manager by delaying creating\n"
-" windows or using XFIXES. So you shouldn't need to use\n"
-" KillInitClients=false as long as you log in quickly\n"
-" enough (within 45 seconds of connecting.) You can\n"
-" disable this by setting X11VNC_AVOID_WINDOWS=never.\n"
-" You can also set it to the number of seconds to delay.\n"
-"\n"
-"-reflect host:N Instead of connecting to and polling an X display,\n"
-" connect to the remote VNC server host:N and be a\n"
-" reflector/repeater for it. This is useful for trying\n"
-" to manage the case of many simultaneous VNC viewers\n"
-" (e.g. classroom broadcasting) where, e.g. you put\n"
-" a repeater on each network switch, etc, to improve\n"
-" performance by distributing the load and network\n"
-" traffic. Implies -shared (use -noshared as a later\n"
-" option to disable). See the discussion below under\n"
-" -rawfb vnc:host:N for more details.\n"
-"\n"
-"-id windowid Show the X window corresponding to \"windowid\" not\n"
-" the entire display. New windows like popup menus,\n"
-" transient toplevels, etc, may not be seen or may be\n"
-" clipped. Disabling SaveUnders or BackingStore in the\n"
-" X server may help show them. x11vnc may crash if the\n"
-" window is initially partially obscured, changes size,\n"
-" is iconified, etc. Some steps are taken to avoid this\n"
-" and the -xrandr mechanism is used to track resizes. Use\n"
-" xwininfo(1) to get the window id, or use \"-id pick\"\n"
-" to have x11vnc run xwininfo(1) for you and extract\n"
-" the id. The -id option is useful for exporting very\n"
-" simple applications (e.g. the current view on a webcam).\n"
-"-sid windowid As -id, but instead of using the window directly it\n"
-" shifts a root view to it: this shows SaveUnders menus,\n"
-" etc, although they will be clipped if they extend beyond\n"
-" the window.\n"
-"\n"
-"-appshare Simple application sharing based on the -id/-sid\n"
-" mechanism. Every new toplevel window that the\n"
-" application creates induces a new viewer window via\n"
-" a reverse connection. The -id/-sid and -connect\n"
-" options are required. Run 'x11vnc -appshare -help'\n"
-" for more info.\n"
-"\n"
-#if 0
-"-freeze_when_obscured Probably only of use in -appshare mode: if the -id/-sid\n"
-" window is partially or fully obscured by other windows,\n"
-" stop checking for framebuffer updates. Mouse and\n"
-" keyboard events are still processed and injected.\n"
-"\n"
-#endif
-"-clip WxH+X+Y Only show the sub-region of the full display that\n"
-" corresponds to the rectangle geometry with size WxH and\n"
-" offset +X+Y. The VNC display has size WxH (i.e. smaller\n"
-" than the full display). This also works for -id/-sid\n"
-" mode where the offset is relative to the upper left\n"
-" corner of the selected window. An example use of this\n"
-" option would be to split a large (e.g. Xinerama) display\n"
-" into two parts to be accessed via separate viewers by\n"
-" running a separate x11vnc on each part.\n"
-"\n"
-" Use '-clip xinerama0' to clip to the first xinerama\n"
-" sub-screen (if xinerama is active). xinerama1 for the\n"
-" 2nd sub-screen, etc. This way you don't need to figure\n"
-" out the WxH+X+Y of the desired xinerama sub-screen.\n"
-" screens are sorted in increasing distance from the\n"
-" (0,0) origin (I.e. not the Xserver's order).\n"
-"\n"
-"-flashcmap In 8bpp indexed color, let the installed colormap flash\n"
-" as the pointer moves from window to window (slow).\n"
-" Also try the -8to24 option to avoid flash altogether.\n"
-"-shiftcmap n Rare problem, but some 8bpp displays use less than 256\n"
-" colorcells (e.g. 16-color grayscale, perhaps the other\n"
-" bits are used for double buffering) *and* also need to\n"
-" shift the pixels values away from 0, .., ncells. \"n\"\n"
-" indicates the shift to be applied to the pixel values.\n"
-" To see the pixel values set DEBUG_CMAP=1 to print out\n"
-" a colormap histogram. Example: -shiftcmap 240\n"
-"-notruecolor For 8bpp displays, force indexed color (i.e. a colormap)\n"
-" even if it looks like 8bpp TrueColor (rare problem).\n"
-"-advertise_truecolor If the X11 display is indexed color, lie to clients\n"
-" when they first connect by telling them it is truecolor.\n"
-" To workaround RealVNC: inPF has colourMap but not 8bpp\n"
-" Use '-advertise_truecolor reset' to reset client fb too.\n"
-"\n"
-"-visual n This option probably does not do what you think.\n"
-" It simply *forces* the visual used for the framebuffer;\n"
-" this may be a bad thing... (e.g. messes up colors or\n"
-" cause a crash). It is useful for testing and for some\n"
-" workarounds. n may be a decimal number, or 0x hex.\n"
-" Run xdpyinfo(1) for the values. One may also use\n"
-" \"TrueColor\", etc. see <X11/X.h> for a list. If the\n"
-" string ends in \":m\" then for better or for worse\n"
-" the visual depth is forced to be m. You may want to\n"
-" use -noshm when using this option (so XGetImage may\n"
-" automatically translate the pixel data).\n"
-"\n"
-"-overlay Handle multiple depth visuals on one screen, e.g. 8+24\n"
-" and 24+8 overlay visuals (the 32 bits per pixel are\n"
-" packed with 8 for PseudoColor and 24 for TrueColor).\n"
-"\n"
-" Currently -overlay only works on Solaris via\n"
-" XReadScreen(3X11) and IRIX using XReadDisplay(3).\n"
-" On Solaris there is a problem with image \"bleeding\"\n"
-" around transient popup menus (but not for the menu\n"
-" itself): a workaround is to disable SaveUnders\n"
-" by passing the \"-su\" argument to Xsun (in\n"
-" /etc/dt/config/Xservers).\n"
-"\n"
-" Use -overlay as a workaround for situations like these:\n"
-" Some legacy applications require the default visual to\n"
-" be 8bpp (8+24), or they will use 8bpp PseudoColor even\n"
-" when the default visual is depth 24 TrueColor (24+8).\n"
-" In these cases colors in some windows will be incorrect\n"
-" in x11vnc unless -overlay is used. Another use of\n"
-" -overlay is to enable showing the exact mouse cursor\n"
-" shape (details below).\n"
-"\n"
-" Under -overlay, performance will be somewhat slower\n"
-" due to the extra image transformations required.\n"
-" For optimal performance do not use -overlay, but rather\n"
-" configure the X server so that the default visual is\n"
-" depth 24 TrueColor and try to have all apps use that\n"
-" visual (e.g. some apps have -use24 or -visual options).\n"
-"-overlay_nocursor Sets -overlay, but does not try to draw the exact mouse\n"
-" cursor shape using the overlay mechanism.\n"
-"\n"
-"-8to24 [opts] Try this option if -overlay is not supported on your\n"
-" OS, and you have a legacy 8bpp app that you want to\n"
-" view on a multi-depth display with default depth 24\n"
-" (and is 32 bpp) OR have a default depth 8 display with\n"
-" depth 24 overlay windows for some apps. This option\n"
-" may not work on all X servers and hardware (tested\n"
-" on XFree86/Xorg mga driver and Xsun). The \"opts\"\n"
-" string is not required and is described below.\n"
-"\n"
-" This mode enables a hack where x11vnc monitors windows\n"
-" within 3 levels from the root window. If it finds\n"
-" any that are 8bpp it extracts the indexed color\n"
-" pixel values using XGetImage() and then applies a\n"
-" transformation using the colormap(s) to create TrueColor\n"
-" RGB values that it in turn inserts into bits 1-24 of\n"
-" the framebuffer. This creates a depth 24 \"view\"\n"
-" of the display that is then exported via VNC.\n"
-"\n"
-" Conversely, for default depth 8 displays, the depth\n"
-" 24 regions are read by XGetImage() and everything is\n"
-" transformed and inserted into a depth 24 TrueColor\n"
-" framebuffer.\n"
-"\n"
-" Note that even if there are *no* depth 24 visuals or\n"
-" windows (i.e. pure 8bpp), this mode is potentially\n"
-" an improvement over -flashcmap because it avoids the\n"
-" flashing and shows each window in the correct color.\n"
-"\n"
-" This method works OK, but may still have bugs and it\n"
-" does hog resources. If there are multiple 8bpp windows\n"
-" using different colormaps, one may have to iconify all\n"
-" but one for the colors to be correct.\n"
-"\n"
-" There may be painting errors for clipping and switching\n"
-" between windows of depths 8 and 24. Heuristics are\n"
-" applied to try to minimize the painting errors. One can\n"
-" also press 3 Alt_L's in a row to refresh the screen\n"
-" if the error does not repair itself. Also the option\n"
-" -fixscreen 8=3.0 or -fixscreen V=3.0 may be used to\n"
-" periodically refresh the screen at the cost of bandwidth\n"
-" (every 3 sec for this example).\n"
-"\n"
-" The [opts] string can contain the following settings.\n"
-" Multiple settings are separated by commas.\n"
-"\n"
-" For for some X servers with default depth 24 a\n"
-" speedup may be achieved via the option \"nogetimage\".\n"
-" This enables a scheme were XGetImage() is not used\n"
-" to retrieve the 8bpp data. Instead, it assumes that\n"
-" the 8bpp data is in bits 25-32 of the 32bit X pixels.\n"
-" There is no requirement that the X server should put\n"
-" the data there for our poll requests, but some do and\n"
-" so the extra steps to retrieve it can be skipped.\n"
-" Tested with mga driver with XFree86/Xorg. For the\n"
-" default depth 8 case this option is ignored.\n"
-"\n"
-" To adjust how often XGetImage() is used to poll the\n"
-" non-default visual regions for changes, use the option\n"
-" \"poll=t\" where \"t\" is a floating point time.\n"
-" (default: %.2f)\n"
-"\n"
-" Setting the option \"level2\" will limit the search\n"
-" for non-default visual windows to two levels from the\n"
-" root window. Do this on slow machines where you know\n"
-" the window manager only imposes one extra window between\n"
-" the app window and the root window.\n"
-"\n"
-" Also for very slow machines use \"cachewin=t\"\n"
-" where t is a floating point amount of time to cache\n"
-" XGetWindowAttributes results. E.g. cachewin=5.0.\n"
-" This may lead to the windows being unnoticed for this\n"
-" amount of time when deiconifying, painting errors, etc.\n"
-"\n"
-" While testing on a very old SS20 these options gave\n"
-" tolerable response: -8to24 poll=0.2,cachewin=5.0. For\n"
-" this machine -overlay is supported and gives better\n"
-" response.\n"
-"\n"
-" Debugging for this mode can be enabled by setting\n"
-" \"dbg=1\", \"dbg=2\", or \"dbg=3\".\n"
-"\n"
-"-24to32 Very rare problem: if the framebuffer (X display\n"
-" or -rawfb) is 24bpp instead of the usual 32bpp, then\n"
-" dynamically transform the pixels to 32bpp. This will be\n"
-" slower, but can be used to work around problems where\n"
-" VNC viewers cannot handle 24bpp (e.g. \"main: setPF:\n"
-" not 8, 16 or 32 bpp?\"). See the FAQ for more info.\n"
-"\n"
-" In the case of -rawfb mode, the pixels are directly\n"
-" modified by inserting a 0 byte to pad them out to 32bpp.\n"
-" For X displays, a kludge is done that is equivalent to\n"
-" \"-noshm -visual TrueColor:32\". (If better performance\n"
-" is needed for the latter, feel free to ask).\n"
-"\n"
-"-scale fraction Scale the framebuffer by factor \"fraction\". Values\n"
-" less than 1 shrink the fb, larger ones expand it. Note:\n"
-" the image may not be sharp and response may be slower.\n"
-" If \"fraction\" contains a decimal point \".\" it\n"
-" is taken as a floating point number, alternatively\n"
-" the notation \"m/n\" may be used to denote fractions\n"
-" exactly, e.g. -scale 2/3\n"
-"\n"
-" To scale asymmetrically in the horizontal and vertical\n"
-" directions, specify a WxH geometry to stretch to:\n"
-" e.g. '-scale 1024x768', or also '-scale 0.9x0.75'\n"
-"\n"
-" Scaling Options: can be added after \"fraction\" via\n"
-" \":\", to supply multiple \":\" options use commas.\n"
-" If you just want a quick, rough scaling without\n"
-" blending, append \":nb\" to \"fraction\" (e.g. -scale\n"
-" 1/3:nb). No blending is the default for 8bpp indexed\n"
-" color, to force blending for this case use \":fb\".\n"
-"\n"
-" To disable -scrollcopyrect and -wirecopyrect under\n"
-" -scale use \":nocr\". If you need to to enable them use\n"
-" \":cr\" or specify them explicitly on the command line.\n"
-" If a slow link is detected, \":nocr\" may be applied\n"
-" automatically. Default: %s\n"
-"\n"
-" More esoteric options: for compatibility with vncviewers\n"
-" the scaled width is adjusted to be a multiple of 4:\n"
-" to disable this use \":n4\". \":in\" use interpolation\n"
-" scheme even when shrinking, \":pad\" pad scaled width\n"
-" and height to be multiples of scaling denominator\n"
-" (e.g. 3 for 2/3).\n"
-"\n"
-"-geometry WxH Same as -scale WxH\n"
-"\n"
-"-scale_cursor frac By default if -scale is supplied the cursor shape is\n"
-" scaled by the same factor. Depending on your usage,\n"
-" you may want to scale the cursor independently of the\n"
-" screen or not at all. If you specify -scale_cursor\n"
-" the cursor will be scaled by that factor. When using\n"
-" -scale mode to keep the cursor at its \"natural\" size\n"
-" use \"-scale_cursor 1\". Most of the \":\" scaling\n"
-" options apply here as well.\n"
-"\n"
-"-viewonly All VNC clients can only watch (default %s).\n"
-"-shared VNC display is shared, i.e. more than one viewer can\n"
-" connect at the same time (default %s).\n"
-"-once Exit after the first successfully connected viewer\n"
-" disconnects, opposite of -forever. This is the Default.\n"
-"-forever Keep listening for more connections rather than exiting\n"
-" as soon as the first client(s) disconnect. Same as -many\n"
-"\n"
-" To get the standard non-shared VNC behavior where when\n"
-" a new VNC client connects the existing VNC client is\n"
-" dropped use: -nevershared -forever This method can\n"
-" also be used to guard against hung TCP connections that\n"
-" do not go away.\n"
-"\n"
-"-loop Create an outer loop restarting the x11vnc process\n"
-" whenever it terminates. -bg and -inetd are ignored\n"
-" in this mode (however see -loopbg below).\n"
-"\n"
-" Useful for continuing even if the X server terminates\n"
-" and restarts (at that moment the process will need\n"
-" permission to reconnect to the new X server of course).\n"
-"\n"
-" Use, e.g., -loop100 to sleep 100 millisecs between\n"
-" restarts, etc. Default is 2000ms (i.e. 2 secs) Use,\n"
-" e.g. -loop300,5 to sleep 300 ms and only loop 5 times.\n"
-"\n"
-" If -loopbg (plus any numbers) is specified instead,\n"
-" the \"-bg\" option is implied and the mode approximates\n"
-" inetd(8) usage to some degree. In this case when\n"
-" it goes into the background any listening sockets\n"
-" (i.e. ports 5900, 5800) are closed, so the next one\n"
-" in the loop can use them. This mode will only be of\n"
-" use if a VNC client (the only client for that process)\n"
-" is already connected before the process goes into the\n"
-" background, for example, usage of -display WAIT:..,\n"
-" -svc, and -connect can make use of this \"poor man's\"\n"
-" inetd mode. The default wait time is 500ms in this\n"
-" mode. This usage could use useful: -svc -bg -loopbg\n"
-"\n"
-"-timeout n Exit unless a client connects within the first n seconds\n"
-" after startup.\n"
-"\n"
-" If there have been no connection attempts after n\n"
-" seconds x11vnc exits immediately. If a client is\n"
-" trying to connect but has not progressed to the normal\n"
-" operating state, x11vnc gives it a few more seconds\n"
-" to finish and exits if it does not make it to the\n"
-" normal state.\n"
-"\n"
-" For reverse connections via -connect or -connect_or_exit\n"
-" a timeout of n seconds will be set for all reverse\n"
-" connects. If the connect timeout alarm goes off,\n"
-" x11vnc will exit immediately.\n"
-"\n"
-"-sleepin n At startup sleep n seconds before proceeding (e.g. to\n"
-" allow redirs and listening clients to start up)\n"
-"\n"
-" If a range is given: '-sleepin min-max', a random value\n"
-" between min and max is slept. E.g. '-sleepin 0-20' and\n"
-" '-sleepin 10-30'. Floats are allowed too.\n"
-"\n"
-"-inetd Launched by inetd(8): stdio instead of listening socket.\n"
-" Note: if you are not redirecting stderr to a log file\n"
-" (via shell 2> or -o option) you MUST also specify the -q\n"
-" option, otherwise the stderr goes to the viewer which\n"
-" will cause it to abort. Specifying both -inetd and -q\n"
-" and no -o will automatically close the stderr.\n"
-"\n"
-"-tightfilexfer Enable the TightVNC file transfer extension. Note that\n"
-" that when the -viewonly option is supplied all file\n"
-" transfers are disabled. Also clients that log in\n"
-" viewonly cannot transfer files. However, if the remote\n"
-" control mechanism is used to change the global or\n"
-" per-client viewonly state the filetransfer permissions\n"
-" will NOT change.\n"
-"\n"
-" IMPORTANT: please understand if -tightfilexfer is\n"
-" specified and you run x11vnc as root for, say, inetd\n"
-" or display manager (gdm, kdm, ...) access and you do\n"
-" not have it switch users via the -users option, then\n"
-" VNC Viewers that connect are able to do filetransfer\n"
-" reads and writes as *root*.\n"
-"\n"
-" Also, tightfilexfer is disabled in -unixpw mode.\n"
-"\n"
-"-ultrafilexfer Note: to enable UltraVNC filetransfer and to get it to\n"
-" work you probably need to supply these LibVNCServer\n"
-" options: \"-rfbversion 3.6 -permitfiletransfer\"\n"
-" \"-ultrafilexfer\" is an alias for this combination.\n"
-"\n"
-" IMPORTANT: please understand if -ultrafilexfer is\n"
-" specified and you run x11vnc as root for, say, inetd\n"
-" or display manager (gdm, kdm, ...) access and you do\n"
-" not have it switch users via the -users option, then\n"
-" VNC Viewers that connect are able to do filetransfer\n"
-" reads and writes as *root*.\n"
-"\n"
-" Note that sadly you cannot do both -tightfilexfer and\n"
-" -ultrafilexfer at the same time because the latter\n"
-" requires setting the version to 3.6 and tightvnc will\n"
-" not do filetransfer when it sees that version number.\n"
-"\n"
-"-http Instead of using -httpdir (see below) to specify\n"
-" where the Java vncviewer applet is, have x11vnc try\n"
-" to *guess* where the directory is by looking relative\n"
-" to the program location and in standard locations\n"
-" (/usr/local/share/x11vnc/classes, etc). Under -ssl or\n"
-" -stunnel the ssl classes subdirectory is sought.\n"
-"-http_ssl As -http, but force lookup for ssl classes subdir.\n"
-"\n"
-" Note that for HTTPS, single-port Java applet delivery\n"
-" you can set X11VNC_HTTPS_DOWNLOAD_WAIT_TIME to the\n"
-" max number of seconds to wait for the applet download\n"
-" to finish. The default is 15.\n"
-"\n"
-"-avahi Use the Avahi/mDNS ZeroConf protocol to advertise\n"
-" this VNC server to the local network. (Related terms:\n"
-" Rendezvous, Bonjour). Depending on your setup, you\n"
-" may need to start avahi-daemon and open udp port 5353\n"
-" in your firewall.\n"
-"\n"
-" You can set X11VNC_AVAHI_NAME, X11VNC_AVAHI_HOST,\n"
-" and/or X11VNC_AVAHI_PORT environment variables\n"
-" to override the default values. For example:\n"
-" -env X11VNC_AVAHI_NAME=wally\n"
-"\n"
-" If the avahi API cannot be found at build time, a helper\n"
-" program like avahi-publish(1) or dns-sd(1) will be tried\n"
-"\n"
-"-mdns Same as -avahi.\n"
-"-zeroconf Same as -avahi.\n"
-"\n"
-"-connect string For use with \"vncviewer -listen\" reverse connections.\n"
-" If \"string\" has the form \"host\" or \"host:port\"\n"
-" the connection is made once at startup.\n"
-"\n"
-" Use commas for a list of host's and host:port's.\n"
-" E.g. -connect host1,host2 or host1:0,host2:5678.\n"
-" Note that to reverse connect to multiple hosts at the\n"
-" same time you will likely need to also supply: -shared\n"
-"\n"
-" Note that unlike most vnc servers, x11vnc will require a\n"
-" password for reverse as well as for forward connections.\n"
-" (provided password auth has been enabled, -rfbauth, etc)\n"
-" If you do not want to require a password for reverse\n"
-" connections set X11VNC_REVERSE_CONNECTION_NO_AUTH=1 in\n"
-" your environment before starting x11vnc.\n"
-"\n"
-" If \"string\" contains \"/\" it is instead interpreted\n"
-" as a file to periodically check for new hosts.\n"
-" The first line is read and then the file is truncated.\n"
-" Be careful about the location of this file if x11vnc\n"
-" is running as root (e.g. via gdm(1), etc).\n"
-"\n"
-"\n"
-" Repeater mode: Some services provide an intermediate\n"
-" \"vnc repeater\": http://www.uvnc.com/addons/repeater.html\n"
-" (and also http://koti.mbnet.fi/jtko/ for linux port)\n"
-" that acts as a proxy/gateway. Modes like these require\n"
-" an initial string to be sent for the reverse connection\n"
-" before the VNC protocol is started. Here are the ways\n"
-" to do this:\n"
-"\n"
-" -connect pre=some_string+host:port\n"
-" -connect pre128=some_string+host:port\n"
-" -connect repeater=ID:1234+host:port\n"
-" -connect repeater=23.45.67.89::5501+host:port\n"
-"\n"
-" SSVNC notation is also supported:\n"
-"\n"
-" -connect repeater://host:port+ID:1234\n"
-"\n"
-" As with normal -connect usage, if the repeater port is\n"
-" not supplied 5500 is assumed.\n"
-"\n"
-" The basic idea is between the special tag, e.g. \"pre=\"\n"
-" and \"+\" is the pre-string to be sent. Note that in\n"
-" this case host:port is the repeater server, NOT the\n"
-" vnc viewer. Somehow the pre-string tells the repeater\n"
-" server how to find the vnc viewer and connect you to it.\n"
-"\n"
-" In the case pre=some_string+host:port, \"some_string\"\n"
-" is simply sent. In the case preNNN=some_string+host:port\n"
-" \"some_string\" is sent in a null padded buffer of\n"
-" length NNN. repeater= is the same as pre250=, this is\n"
-" the ultravnc repeater buffer size.\n"
-"\n"
-" Strings like \"\\n\" and \"\\r\", etc. are expanded to\n"
-" newline and carriage return. \"\\c\" is expanded to\n"
-" \",\" since the connect string is comma separated.\n"
-"\n"
-" See also the -proxy option below for additional ways\n"
-" to plumb reverse connections.\n"
-"\n"
-" Reverse SSL: using -connect in -ssl mode makes x11vnc\n"
-" act as an SSL client (initiates SSL connection) rather\n"
-" than an SSL server. The idea is x11vnc might be\n"
-" connecting to stunnel on the viewer side with the\n"
-" viewer in listening mode. If you do not want this\n"
-" behavior, use -env X11VNC_DISABLE_SSL_CLIENT_MODE=1.\n"
-" With this the viewer side can act as the SSL client\n"
-" as it normally does for forward connections.\n"
-"\n"
-" Reverse SSL Repeater mode: This will work, but note\n"
-" that if the VNC Client does any sort of a 'Fetch Cert'\n"
-" action before connecting, then the Repeater will\n"
-" likely drop the connection and both sides will need\n"
-" to restart. Consider the use of -connect_or_exit\n"
-" and -loop300,2 to have x11vnc reconnect once to the\n"
-" repeater after the fetch. You will probably also want\n"
-" to supply -sslonly to avoid x11vnc thinking the delay\n"
-" in response means the connection is VeNCrypt. The env\n"
-" var X11VNC_DISABLE_SSL_CLIENT_MODE=1 discussed above\n"
-" may also be useful (i.e. the viewer can do a forward\n"
-" connection as it normally does.)\n"
-"\n"
-" IPv6: as of x11vnc 0.9.10 the -connect option should\n"
-" connect to IPv6 hosts properly. If there are problems\n"
-" you can disable IPv6 by setting -DX11VNC_IPV6=0\n"
-" in CPPFLAGS when configuring. If there problems\n"
-" connecting to IPv6 hosts consider a relay like the\n"
-" included inet6to4 script or the -proxy option.\n"
-"\n"
-"-connect_or_exit str As with -connect, except if none of the reverse\n"
-" connections succeed, then x11vnc shuts down immediately\n"
-"\n"
-" An easier to type alias for this option is '-coe'\n"
-"\n"
-" By the way, if you do not want x11vnc to listen on\n"
-" ANY interface use -rfbport 0 which is handy for the\n"
-" -connect_or_exit mode.\n"
-"\n"
-"-proxy string Use proxy in string (e.g. host:port) as a proxy for\n"
-" making reverse connections (-connect or -connect_or_exit\n"
-" options).\n"
-"\n"
-" Web proxies are supported, but note by default most of\n"
-" them only support destination connections to ports 443\n"
-" or 563, so this might not be very useful (the viewer\n"
-" would need to listen on that port or the router would\n"
-" have to do a port redirection).\n"
-"\n"
-" A web proxy may be specified by either \"host:port\"\n"
-" or \"http://host:port\" (the port is required even if\n"
-" it is the common choices 80 or 8080)\n"
-"\n"
-" SOCKS4, SOCKS4a, and SOCKS5 are also supported.\n"
-" SOCKS proxies normally do not have restrictions on the\n"
-" destination port number.\n"
-"\n"
-" Use a format like this: socks://host:port or\n"
-" socks5://host:port. Note that ssh -D does not support\n"
-" SOCKS4a, so use socks5://. For socks:// SOCKS4 is used\n"
-" on a numerical IP and \"localhost\", otherwise SOCKS4a\n"
-" is used (and so the proxy tries to do the DNS lookup).\n"
-"\n"
-" An experimental mode is \"-proxy http://host:port/...\"\n"
-" Note the \"/\" after the port that distinguishes it from\n"
-" a normal web proxy. The port must be supplied even if\n"
-" it is the default 80. For this mode a GET is done to\n"
-" the supplied URL with the string host=H&port=P appended.\n"
-" H and P will be the -connect reverse connect host\n"
-" and port. Use the string \"__END__\" to disable the\n"
-" appending. The basic idea here is that maybe some cgi\n"
-" script provides the actual viewer hookup and tunnelling.\n"
-" How to actually achieve this within cgi, php, etc. is\n"
-" not clear... A custom web server or apache module\n"
-" would be straight-forward.\n"
-"\n"
-" Another experimental mode is \"-proxy ssh://user@host\"\n"
-" in which case a SSH tunnel is used for the proxying.\n"
-" \"user@\" is not needed unless your unix username is\n"
-" different on \"host\". For a non-standard SSH port\n"
-" use ssh://user@host:port. If proxies are chained (see\n"
-" next paragraph) then the ssh one must be the first one.\n"
-" If ssh-agent is not active, then the ssh password needs\n"
-" to be entered in the terminal where x11vnc is running.\n"
-" Examples:\n"
-"\n"
-" -connect localhost:0 -proxy ssh://me@friends-pc:2222\n"
-"\n"
-" -connect snoopy:0 -proxy ssh://ssh.company.com\n"
-"\n"
-" Multiple proxies may be chained together in case one\n"
-" needs to ricochet off of a number of hosts to finally\n"
-" reach the VNC viewer. Up to 3 may be chained, separate\n"
-" them by commas in the order they are to be connected to.\n"
-" E.g.: http://host1:port1,socks5://host2:port2 or three\n"
-" like: first,second,third\n"
-"\n"
-" IPv6: as of x11vnc 0.9.10 the -proxy option should\n"
-" connect to IPv6 hosts properly. If there are problems\n"
-" you can disable IPv6 by setting -DX11VNC_IPV6=0\n"
-" in CPPFLAGS when configuring. If there problems\n"
-" connecting to IPv6 hosts consider a relay like the\n"
-" included inet6to4 script.\n"
-"\n"
-"-vncconnect Monitor the VNC_CONNECT X property set by the standard\n"
-"-novncconnect VNC program vncconnect(1). When the property is\n"
-" set to \"host\" or \"host:port\" establish a reverse\n"
-" connection. Using xprop(1) instead of vncconnect may\n"
-" work (see the FAQ). The -remote control mechanism uses\n"
-" X11VNC_REMOTE channel, and this option disables/enables\n"
-" it as well. Default: %s\n"
-"\n"
-" To use different names for these X11 properties (e.g. to\n"
-" have separate communication channels for multiple\n"
-" x11vnc's on the same display) set the VNC_CONNECT or\n"
-" X11VNC_REMOTE env. vars. to the string you want, for\n"
-" example: -env X11VNC_REMOTE=X11VNC_REMOTE_12345\n"
-" Both sides of the channel must use the same unique name.\n"
-" The same can be done for the internal X11VNC_TICKER\n"
-" property (heartbeat and timestamp) if desired.\n"
-"\n"
-"-allow host1[,host2..] Only allow client connections from hosts matching\n"
-" the comma separated list of hostnames or IP addresses.\n"
-" Can also be a numerical IP prefix, e.g. \"192.168.100.\"\n"
-" to match a simple subnet, for more control build\n"
-" LibVNCServer with libwrap support (See the FAQ). If the\n"
-" list contains a \"/\" it instead is a interpreted\n"
-" as a file containing addresses or prefixes that is\n"
-" re-read each time a new client connects. Lines can be\n"
-" commented out with the \"#\" character in the usual way.\n"
-"\n"
-" -allow applies in -ssl mode, but not in -stunnel mode.\n"
-"\n"
-" IPv6: as of x11vnc 0.9.10 a host can be specified\n"
-" in IPv6 numerical format, e.g. 2001:4860:b009::93.\n"
-"\n"
-"-localhost Basically the same as \"-allow 127.0.0.1\".\n"
-"\n"
-" Note: if you want to restrict which network interface\n"
-" x11vnc listens on, see the -listen option below.\n"
-" E.g. \"-listen localhost\" or \"-listen 192.168.3.21\".\n"
-" As a special case, the option \"-localhost\" implies\n"
-" \"-listen localhost\".\n"
-"\n"
-" A rare case, but for non-localhost -listen usage, if\n"
-" you use the remote control mechanism (-R) to change\n"
-" the -listen interface you may need to manually adjust\n"
-" the -allow list (and vice versa) to avoid situations\n"
-" where no connections (or too many) are allowed.\n"
-"\n"
-" If you do not want x11vnc to listen on ANY interface\n"
-" (evidently you are using -connect or -connect_or_exit,\n"
-" or plan to use remote control: -R connect:host), use\n"
-" -rfbport 0\n"
-"\n"
-" IPv6: if IPv6 is supported, this option automatically\n"
-" implies the IPv6 loopback address '::1' as well.\n"
-"\n"
-"-unixsock str Listen on the unix socket (AF_UNIX) 'str'\n"
-" for connections. This mode is for either local\n"
-" connections or a tunnel endpoint where one wants the\n"
-" file permission of the unix socket file to determine\n"
-" what can connect to it. (This currently requires an\n"
-" edit to libvnserver/rfbserver.c: comment out lines 310\n"
-" and 311, 'close(sock)' and 'return NULL' in rfbserver.c\n"
-" after the setsockopt() call.) Note that to disable all\n"
-" tcp listening ports specify '-rfbport 0' and should be\n"
-" useful with this mode. Example:\n"
-" mkdir ~/s; chmod 700 ~/s;\n"
-" x11vnc -unixsock ~/s/mysock -rfbport 0 ...\n"
-" The SSVNC unix vncviewer can connect to unix sockets.\n"
-"\n"
-#if X11VNC_IPV6
-"-listen6 str When in IPv6 listen mode \"-6\", listen only on the\n"
-" network interface with address \"str\". It also works\n"
-" for link scope addresses (fe80::219:dbff:fee5:3f92%%eth0)\n"
-" and IPv6 hostname strings (e.g. ipv6.google.com.)\n"
-" Use LibVNCServer -listen option for the IPv4 interface.\n"
-"\n"
-#endif
-"-nolookup Do not use gethostbyname() or gethostbyaddr() to look up\n"
-" host names or IP numbers. Use this if name resolution\n"
-" is incorrectly set up and leads to long pauses as name\n"
-" lookups time out, etc.\n"
-"\n"
-"-input string Fine tuning of allowed user input. If \"string\" does\n"
-" not contain a comma \",\" the tuning applies only to\n"
-" normal clients. Otherwise the part before \",\" is\n"
-" for normal clients and the part after for view-only\n"
-" clients. \"K\" is for Keystroke input, \"M\" for\n"
-" Mouse-motion input, \"B\" for Button-click input, \"C\"\n"
-" is for Clipboard input, and \"F\" is for File transfer\n"
-" (ultravnc only). Their presence in the string enables\n"
-" that type of input. E.g. \"-input M\" means normal\n"
-" users can only move the mouse and \"-input KMBCF,M\"\n"
-" lets normal users do anything and enables view-only\n"
-" users to move the mouse. This option is ignored when\n"
-" a global -viewonly is in effect (all input is discarded\n"
-" in that case).\n"
-"\n"
-"-grabkbd When VNC viewers are connected, attempt to the grab\n"
-" the keyboard so a (non-malicious) user sitting at the\n"
-" physical display is not able to enter keystrokes.\n"
-" This method uses XGrabKeyboard(3X11) and so it is\n"
-" not secure and does not rule out the person at the\n"
-" physical display injecting keystrokes by flooding the\n"
-" server with them, grabbing the keyboard himself, etc.\n"
-" Some degree of cooperation from the person at the\n"
-" display is assumed. This is intended for remote\n"
-" help-desk or educational usage modes.\n"
-"\n"
-" Note: on some recent (12/2010) X servers and/or\n"
-" desktops, -grabkbd no longer works: it prevents the\n"
-" window manager from resizing windows and similar things.\n"
-" Try -ungrabboth below (might not work.)\n"
-"\n"
-"-grabptr As -grabkbd, but for the mouse pointer using\n"
-" XGrabPointer(3X11). Unfortunately due to the way the X\n"
-" server works, the mouse can still be moved around by the\n"
-" user at the physical display, but he will not be able to\n"
-" change window focus with it. Also some window managers\n"
-" that call XGrabServer(3X11) for resizes, etc, will\n"
-" act on the local user's input. Again, some degree of\n"
-" cooperation from the person at the display is assumed.\n"
-"\n"
-"-ungrabboth Whenever there is any input (either keyboard or\n"
-" pointer), ungrab *both* the keyboard and the pointer\n"
-" while injecting the synthetic input. This is to allow\n"
-" window managers, etc. a chance to grab.\n"
-"\n"
-"-grabalways Apply both -grabkbd and -grabptr even when no VNC\n"
-" viewers are connected. If you only want one of them,\n"
-" use the -R remote control to turn the other back on,\n"
-" e.g. -R nograbptr.\n"
-"\n"
-#ifdef ENABLE_GRABLOCAL
-"-grablocal n If it appears that a user sitting at the physical\n"
-" display has injected a keystroke or mouse event ignore\n"
-" any VNC client inputs for the next n seconds. The idea\n"
-" is that during a demonstration, etc, the local user\n"
-" will not be interrupted by viewers accidentally moving\n"
-" the mouse, etc. The detection of local user input is\n"
-" approximate and so at times gives unexpected results.\n"
-"\n"
-#endif
-"-viewpasswd string Supply a 2nd password for view-only logins. The -passwd\n"
-" (full-access) password must also be supplied.\n"
-"\n"
-"-passwdfile filename Specify the LibVNCServer password via the first line\n"
-" of the file \"filename\" (instead of via -passwd on\n"
-" the command line where others might see it via ps(1)).\n"
-"\n"
-" See the descriptions below for how to supply multiple\n"
-" passwords, view-only passwords, to specify external\n"
-" programs for the authentication, and other features.\n"
-"\n"
-" If the filename is prefixed with \"rm:\" it will be\n"
-" removed after being read. Perhaps this is useful in\n"
-" limiting the readability of the file. In general, the\n"
-" password file should not be readable by untrusted users\n"
-" (BTW: neither should the VNC -rfbauth file: it is NOT\n"
-" encrypted, only obscured with a fixed key).\n"
-"\n"
-" If the filename is prefixed with \"read:\" it will\n"
-" periodically be checked for changes and reread. It is\n"
-" guaranteed to be reread just when a new client connects\n"
-" so that the latest passwords will be used.\n"
-"\n"
-" If \"filename\" is prefixed with \"cmd:\" then the\n"
-" string after the \":\" is run as an external command:\n"
-" the output of the command will be interpreted as if it\n"
-" were read from a password file (see below). If the\n"
-" command does not exit with 0, then x11vnc terminates\n"
-" immediately. To specify more than 1000 passwords this\n"
-" way set X11VNC_MAX_PASSWDS before starting x11vnc.\n"
-" The environment variables are set as in -accept.\n"
-"\n"
-" Note that due to the VNC protocol only the first 8\n"
-" characters of a password are used (DES key).\n"
-"\n"
-" If \"filename\" is prefixed with \"custom:\" then a\n"
-" custom password checker is supplied as an external\n"
-" command following the \":\". The command will be run\n"
-" when a client authenticates. If the command exits with\n"
-" 0 the client is accepted, otherwise it is rejected.\n"
-" The environment variables are set as in -accept.\n"
-"\n"
-" The standard input to the custom command will be a\n"
-" decimal digit \"len\" followed by a newline. \"len\"\n"
-" specifies the challenge size and is usually 16 (the\n"
-" VNC spec). Then follows len bytes which is the random\n"
-" challenge string that was sent to the client. This is\n"
-" then followed by len more bytes holding the client's\n"
-" response (i.e. the challenge string encrypted via DES\n"
-" with the user password in the standard situation).\n"
-"\n"
-" The \"custom:\" scheme can be useful to implement\n"
-" dynamic passwords or to implement methods where longer\n"
-" passwords and/or different encryption algorithms\n"
-" are used. The latter will require customizing the VNC\n"
-" client as well. One could create an MD5SUM based scheme\n"
-" for example.\n"
-"\n"
-" File format for -passwdfile:\n"
-"\n"
-" If multiple non-blank lines exist in the file they are\n"
-" all taken as valid passwords. Blank lines are ignored.\n"
-" Password lines may be \"commented out\" (ignored) if\n"
-" they begin with the character \"#\" or the line contains\n"
-" the string \"__SKIP__\". Lines may be annotated by use\n"
-" of the \"__COMM__\" string: from it to the end of the\n"
-" line is ignored. An empty password may be specified\n"
-" via the \"__EMPTY__\" string on a line by itself (note\n"
-" your viewer might not accept empty passwords).\n"
-"\n"
-" If the string \"__BEGIN_VIEWONLY__\" appears on a\n"
-" line by itself, the remaining passwords are used for\n"
-" viewonly access. For compatibility, as a special case\n"
-" if the file contains only two password lines the 2nd\n"
-" one is automatically taken as the viewonly password.\n"
-" Otherwise the \"__BEGIN_VIEWONLY__\" token must be\n"
-" used to have viewonly passwords. (tip: make the 3rd\n"
-" and last line be \"__BEGIN_VIEWONLY__\" to have 2\n"
-" full-access passwords)\n"
-"\n"
-"-showrfbauth filename Print to the screen the obscured VNC password kept in\n"
-" the rfbauth file \"filename\" and then exit.\n"
-"\n"
-"-unixpw [list] Use Unix username and password authentication. x11vnc\n"
-" will use the su(1) program to verify the user's\n"
-" password. [list] is an optional comma separated list\n"
-" of allowed Unix usernames. If the [list] string begins\n"
-" with the character \"!\" then the entire list is taken\n"
-" as an exclude list. See below for per-user options\n"
-" that can be applied.\n"
-"\n"
-" A familiar \"login:\" and \"Password:\" dialog is\n"
-" presented to the user on a black screen inside the\n"
-" vncviewer. The connection is dropped if the user fails\n"
-" to supply the correct password in 3 tries or does not\n"
-" send one before a 45 second timeout. Existing clients\n"
-" are view-only during this period.\n"
-"\n"
-" If the first character received is \"Escape\" then the\n"
-" unix username will not be displayed after \"login:\"\n"
-" as it is typed. This could be of use for VNC viewers\n"
-" that automatically type the username and password.\n"
-"\n"
-" Since the detailed behavior of su(1) can vary from\n"
-" OS to OS and for local configurations, test the mode\n"
-" before deployment to make sure it is working properly.\n"
-" x11vnc will attempt to be conservative and reject a\n"
-" login if anything abnormal occurs.\n"
-"\n"
-" One case to note: FreeBSD and the other BSD's by\n"
-" default it is impossible for the user running x11vnc to\n"
-" validate his *own* password via su(1) (commenting out\n"
-" the pam_self.so entry in /etc/pam.d/su eliminates this\n"
-" behavior). So the x11vnc login will always *FAIL* for\n"
-" this case (even when the correct password is supplied).\n"
-"\n"
-" A possible workaround for this on *BSD would be to\n"
-" start x11vnc as root with the \"-users +nobody\" option\n"
-" to immediately switch to user nobody where the su'ing\n"
-" will proceed normally.\n"
-"\n"
-" Another source of potential problems are PAM modules\n"
-" that prompt for extra info, e.g. password aging modules.\n"
-" These logins will fail as well even when the correct\n"
-" password is supplied.\n"
-"\n"
-" **IMPORTANT**: to prevent the Unix password being sent\n"
-" in *clear text* over the network, one of two schemes\n"
-" will be enforced: 1) the -ssl builtin SSL mode, or 2)\n"
-" require both -localhost and -stunnel be enabled.\n"
-"\n"
-" Method 1) ensures the traffic is encrypted between\n"
-" viewer and server. A PEM file will be required, see the\n"
-" discussion under -ssl below (under some circumstances\n"
-" a temporary one can be automatically generated).\n"
-"\n"
-" Method 2) requires the viewer connection to appear\n"
-" to come from the same machine x11vnc is running on\n"
-" (e.g. from a ssh -L port redirection). And that the\n"
-" -stunnel SSL mode be used for encryption over the\n"
-" network. (see the description of -stunnel below).\n"
-"\n"
-" Note: as a convenience, if you ssh(1) in and start\n"
-" x11vnc it will check if the environment variable\n"
-" SSH_CONNECTION is set and appears reasonable. If it\n"
-" does, then the -ssl or -stunnel requirement will be\n"
-" dropped since it is assumed you are using ssh for the\n"
-" encrypted tunnelling. -localhost is still enforced.\n"
-" Use -ssl or -stunnel to force SSL usage even if\n"
-" SSH_CONNECTION is set.\n"
-"\n"
-" To override the above restrictions you can set\n"
-" environment variables before starting x11vnc:\n"
-"\n"
-" Set UNIXPW_DISABLE_SSL=1 to disable requiring either\n"
-" -ssl or -stunnel (as under SSH_CONNECTION.) Evidently\n"
-" you will be using a different method to encrypt the\n"
-" data between the vncviewer and x11vnc: perhaps ssh(1)\n"
-" or an IPSEC VPN. -localhost is still enforced (however,\n"
-" see the next paragraph.)\n"
-"\n"
-" Set UNIXPW_DISABLE_LOCALHOST=1 to disable the -localhost\n"
-" requirement in -unixpw modes. One should never do this\n"
-" (i.e. allow the Unix passwords to be sniffed on the\n"
-" network.) This also disables the localhost requirement\n"
-" for reverse connections (see below.)\n"
-"\n"
-" Note that use of -localhost with ssh(1) (and no -unixpw)\n"
-" is roughly the same as requiring a Unix user login\n"
-" (since a Unix password or the user's public key\n"
-" authentication is used by sshd on the machine where\n"
-" x11vnc runs and only local connections from that machine\n"
-" are accepted).\n"
-"\n"
-" Regarding reverse connections (e.g. -R connect:host\n"
-" and -connect host), when the -localhost constraint is\n"
-" in effect then reverse connections can only be used\n"
-" to connect to the same machine x11vnc is running on\n"
-" (default port 5500). Please use a ssh or stunnel port\n"
-" redirection to the viewer machine to tunnel the reverse\n"
-" connection over an encrypted channel.\n"
-"\n"
-" In -inetd mode the Method 1) will be enforced (not\n"
-" Method 2). With -ssl in effect reverse connections\n"
-" are disabled. If you override this via env. var, be\n"
-" sure to also use encryption from the viewer to inetd.\n"
-" Tip: you can also have your own stunnel spawn x11vnc\n"
-" in -inetd mode (thereby bypassing inetd). See the FAQ\n"
-" for details.\n"
-"\n"
-" The user names in the comma separated [list] may have\n"
-" per-user options after a \":\", e.g. \"fred:opts\"\n"
-" where \"opts\" is a \"+\" separated list of\n"
-" \"viewonly\", \"fullaccess\", \"input=XXXX\", or\n"
-" \"deny\", e.g. \"karl,wally:viewonly,boss:input=M\".\n"
-" For \"input=\" it is the K,M,B,C described under -input.\n"
-"\n"
-" If an item in the list is \"*\" that means those\n"
-" options apply to all users. It ALSO implies all users\n"
-" are allowed to log in after supplying a valid password.\n"
-" Use \"deny\" to explicitly deny some users if you use\n"
-" \"*\" to set a global option. If [list] begins with the\n"
-" \"!\" character then \"*\" is ignored for checking if\n"
-" the user is allowed, but the option values associated\n"
-" with it do apply as normal.\n"
-"\n"
-" There are also some utilities for checking passwords\n"
-" if [list] starts with the \"%%\" character. See the\n"
-" quick_pw() function for more details. Description:\n"
-" \"%%-\" or \"%%stdin\" means read one line from stdin.\n"
-" \"%%env\" means it is in $UNIXPW env var. A leading\n"
-" \"%%/\" or \"%%.\" means read the first line from the\n"
-" filename that follows after the %% character. %% by\n"
-" itself means prompt for the username and password.\n"
-" Otherwise: %%user:pass E.g. -unixpw %%fred:swordfish\n"
-" For the other cases user:pass is read from the indicated\n"
-" source. If the password is correct 'Y user' is printed\n"
-" and the program exit code is 0. If the password is\n"
-" incorrect it prints 'N user' and the exit code is 1.\n"
-" If there is some other error the exit code is 2.\n"
-" This feature enables x11vnc to be a general unix user\n"
-" password checking tool; it could be used from scripts\n"
-" or other programs. These %% password checks also apply\n"
-" to the -unixpw_nis and -unixpw_cmd options.\n"
-"\n"
-" For the %% password check, if the env. var. UNIXPW_CMD\n"
-" is set to a command then it is run as the user (assuming\n"
-" the password is correct.) The output of the command is\n"
-" not printed, the program or script must manage that by\n"
-" some other means. The exit code of x11vnc will depend\n"
-" on the exit code of the command that is run.\n"
-"\n"
-" Use -nounixpw to disable unixpw mode if it was enabled\n"
-" earlier in the cmd line (e.g. -svc mode)\n"
-"\n"
-"-unixpw_nis [list] As -unixpw above, however do not use su(1) but rather\n"
-" use the traditional getpwnam(3) + crypt(3) method to\n"
-" verify passwords. All of the above -unixpw options and\n"
-" constraints apply.\n"
-"\n"
-" This mode requires that the encrypted passwords be\n"
-" readable. Encrypted passwords stored in /etc/shadow\n"
-" will be inaccessible unless x11vnc is run as root.\n"
-"\n"
-" This is called \"NIS\" mode simply because in most\n"
-" NIS setups user encrypted passwords are accessible\n"
-" (e.g. \"ypcat passwd\") by an ordinary user and so that\n"
-" user can authenticate ANY user.\n"
-"\n"
-" NIS is not required for this mode to work (only that\n"
-" getpwnam(3) return the encrypted password is required),\n"
-" but it is unlikely it will work (as an ordinary user)\n"
-" for most modern environments unless NIS is available.\n"
-" On the other hand, when x11vnc is run as root it will\n"
-" be able to to access /etc/shadow even if NIS is not\n"
-" available (note running as root is often done when\n"
-" running x11vnc from inetd and xdm/gdm/kdm).\n"
-"\n"
-" Looked at another way, if you do not want to use the\n"
-" su(1) method provided by -unixpw (i.e. su_verify()), you\n"
-" can run x11vnc as root and use -unixpw_nis. Any users\n"
-" with passwords in /etc/shadow can then be authenticated.\n"
-"\n"
-" In -unixpw_nis mode, under no circumstances is x11vnc's\n"
-" user password verifying function based on su called\n"
-" (i.e. the function su_verify() that runs /bin/su\n"
-" in a pseudoterminal to verify passwords.) However,\n"
-" if -unixpw_nis is used in conjunction with the -find\n"
-" and -create -display WAIT:... modes then, if x11vnc is\n"
-" running as root, /bin/su may be called externally to\n"
-" run the find or create commands.\n"
-"\n"
-"-unixpw_cmd cmd As -unixpw above, however do not use su(1) but rather\n"
-" run the externally supplied command \"cmd\". The first\n"
-" line of its stdin will be the username and the second\n"
-" line the received password. If the command exits\n"
-" with status 0 (success) the VNC user will be accepted.\n"
-" It will be rejected for any other return status.\n"
-"\n"
-" Dynamic passwords and non-unix passwords, e.g. LDAP,\n"
-" can be implemented this way by providing your own custom\n"
-" helper program. Note that the remote viewer is given 3\n"
-" tries to enter the correct password, and so the program\n"
-" may be called in a row that many (or more) times.\n"
-"\n"
-" If a list of allowed users is needed to limit who can\n"
-" log in, use -unixpw [list] in addition to this option.\n"
-"\n"
-" In FINDDISPLAY and FINDCREATEDISPLAY modes the \"cmd\"\n"
-" will also be run with the RFB_UNIXPW_CMD_RUN env. var.\n"
-" non-empty and set to the corresponding display\n"
-" find/create command. The first two lines of input are\n"
-" the username and passwd as in the normal case described\n"
-" above. To support FINDDISPLAY and FINDCREATEDISPLAY,\n"
-" \"cmd\" should run the requested command as the user\n"
-" (and most likely refusing to run it if the password is\n"
-" not correct.) Here is an example script (note it has\n"
-" a hardwired bogus password \"abc\"!)\n"
-"\n"
-" #!/bin/sh\n"
-" # Example x11vnc -unixpw_cmd script.\n"
-" # Read the first two lines of stdin (user and passwd)\n"
-" read user\n"
-" read pass\n"
-" \n"
-" debug=0\n"
-" if [ $debug = 1 ]; then\n"
-" echo \"user: $user\" 1>&2\n"
-" echo \"pass: $pass\" 1>&2\n"
-" env | egrep -i 'rfb|vnc' 1>&2\n"
-" fi\n"
-" \n"
-" # Check if the password is valid.\n"
-" # (A real example would use ldap lookup, etc!)\n"
-" if [ \"X$pass\" != \"Xabc\" ]; then\n"
-" exit 1 # incorrect password\n"
-" fi\n"
-" \n"
-" if [ \"X$RFB_UNIXPW_CMD_RUN\" = \"X\" ]; then\n"
-" exit 0 # correct password\n"
-" else\n"
-" # Run the requested command (finddisplay)\n"
-" if [ $debug = 1 ]; then\n"
-" echo \"run: $RFB_UNIXPW_CMD_RUN\" 1>&2\n"
-" fi\n"
-" exec /bin/su - \"$user\" -c \"$RFB_UNIXPW_CMD_RUN\"\n"
-" fi\n"
-"\n"
-" In -unixpw_cmd mode, under no circumstances is x11vnc's\n"
-" user password verifying function based on su called\n"
-" (i.e. the function su_verify() that runs /bin/su in a\n"
-" pseudoterminal to verify passwords.) It is up to the\n"
-" supplied unixpw_cmd to do user switching if desired\n"
-" and if it has the permissions to do so.\n"
-"\n"
-"-find Find the user's display using FINDDISPLAY. This\n"
-" is an alias for \"-display WAIT:cmd=FINDDISPLAY\".\n"
-"\n"
-" Note: if a -display occurs later on the command line\n"
-" it will override the -find setting.\n"
-"\n"
-" For this and the next few options see -display WAIT:...\n"
-" below for all of the details.\n"
-"\n"
-"-finddpy Run the FINDDISPLAY program, print out the found\n"
-" display (if any) and exit. Output is like: DISPLAY=:0.0\n"
-" DISPLAY=:0.0,XPID=12345 or DISPLAY=:0.0,VT=7. XPID is\n"
-" the process ID of the found X server. VT is the Linux\n"
-" virtual terminal of the X server.\n"
-"-listdpy Have the FINDDISPLAY program list all of your displays\n"
-" (i.e. all the X displays on the local machine that you\n"
-" have access rights to). x11vnc then exits.\n"
-"\n"
-"-findauth [disp] Apply the -find/-finddpy heuristics to try to guess\n"
-" the XAUTHORITY file for DISPLAY 'disp'. If 'disp'\n"
-" is not supplied, then the value in the -display on\n"
-" the cmdline is used; failing that $DISPLAY is used;\n"
-" and failing that \":0\" is used. x11vnc then exits.\n"
-"\n"
-" If nothing is printed out, that means no XAUTHORITY was\n"
-" found for 'disp'; i.e. failure. If \"XAUTHORITY=\"\n"
-" is printed out, that means use the default (i.e. do\n"
-" not set XAUTHORITY). If \"XAUTHORITY=/path/to/file\"\n"
-" is printed out, then use that file.\n"
-"\n"
-" XDM/GDM/KDM: if you are running x11vnc as root and want\n"
-" to find the XAUTHORITY before anyone has logged into an\n"
-" X session yet, use: x11vnc -env FD_XDM=1 -findauth ...\n"
-" (This will also find the XAUTHORITY if a user is already\n"
-" logged into the X session.) When running as root,\n"
-" FD_XDM=1 will be tried if the initial -findauth fails.\n"
-"\n"
-"-create First try to find the user's display using FINDDISPLAY,\n"
-" if that doesn't succeed create an X session via the\n"
-" FINDCREATEDISPLAY method. This is an alias for\n"
-" \"-display WAIT:cmd=FINDCREATEDISPLAY-Xvfb\".\n"
-"\n"
-" Note: if a -display occurs later on the command line\n"
-" it will override the -create setting.\n"
-"\n"
-" SSH NOTE: for both -find and -create you can (should!)\n"
-" add the \"-localhost\" option to force SSH tunnel access.\n"
-"\n"
-"-xdummy As in -create, except Xdummy instead of Xvfb.\n"
-"-xvnc As in -create, except Xvnc instead of Xvfb.\n"
-"-xvnc_redirect As in -create, except Xvnc.redirect instead of Xvfb.\n"
-"-xdummy_xvfb Sets WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb\n"
-"\n"
-"-create_xsrv str Sets WAIT:cmd=FINDCREATEDISPLAY-<str> Can be on cmdline\n"
-" after anything that sets WAIT:.. and other things\n"
-" (e.g. -svc, -xdmsvc) to adjust the X server list.\n"
-" Example: -svc ... -create_xsrv Xdummy,X\n"
-"\n"
-"-svc Terminal services mode based on SSL access. Alias for\n"
-" -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb -unixpw -users\n"
-" unixpw= -ssl SAVE Also \"-service\".\n"
-"\n"
-" Note: if a -display, -unixpw, -users, or -ssl occurs\n"
-" later on the command line it will override the -svc\n"
-" setting.\n"
-"\n"
-"-svc_xdummy As -svc except Xdummy instead of Xvfb.\n"
-"-svc_xvnc As -svc except Xvnc instead of Xvfb.\n"
-"-svc_xdummy_xvfb As -svc with Xdummy,Xvfb.\n"
-"\n"
-"-xdmsvc Display manager Terminal services mode based on SSL.\n"
-" Alias for -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp\n"
-" -unixpw -users unixpw= -ssl SAVE Also \"-xdm_service\".\n"
-"\n"
-" Note: if a -display, -unixpw, -users, or -ssl occurs\n"
-" later on the command line it will override the -xdmsvc\n"
-" setting.\n"
-"\n"
-" To create a session a user will have to first log in\n"
-" to the -unixpw dialog and then log in again to the\n"
-" XDM/GDM/KDM prompt. Subsequent re-connections will\n"
-" only require the -unixpw password. See the discussion\n"
-" under -display WAIT:... for more details about XDM,\n"
-" etc configuration.\n"
-"\n"
-" Remember to enable XDMCP in the xdm-config, gdm.conf,\n"
-" or kdmrc configuration file. See -display WAIT: for\n"
-" more info.\n"
-"\n"
-"-sshxdmsvc Display manager Terminal services mode based on SSH.\n"
-" Alias for -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp\n"
-" -localhost.\n"
-"\n"
-" The -localhost option constrains connections to come\n"
-" in via a SSH tunnel (which will require a login).\n"
-" To create a session a user will also have to log into\n"
-" the XDM GDM KDM prompt. Subsequent re-connections will\n"
-" only only require the SSH login. See the discussion\n"
-" under -display WAIT:... for more details about XDM,\n"
-" etc configuration.\n"
-"\n"
-" Remember to enable XDMCP in the xdm-config, gdm.conf,\n"
-" or kdmrc configuration file. See -display WAIT: for\n"
-" more info.\n"
-"\n"
-"-unixpw_system_greeter Present a \"Press 'Escape' for System Greeter\" option\n"
-" to the connecting VNC client in combined -unixpw\n"
-" and xdmcp FINDCREATEDISPLAY modes (e.g. -xdmsvc).\n"
-"\n"
-" Normally in a -unixpw mode the VNC client must\n"
-" supply a valid username and password to gain access.\n"
-" However, if -unixpw_system_greeter is supplied AND\n"
-" the FINDCREATEDISPLAY command matches 'xdmcp', then\n"
-" the user has the option to press Escape and then get a\n"
-" XDM/GDM/KDM login/greeter panel instead. They will then\n"
-" supply a username and password directly to the greeter.\n"
-"\n"
-" Otherwise, in xdmcp FINDCREATEDISPLAY mode the user\n"
-" must supply his username and password TWICE. First to\n"
-" the initial unixpw login dialog, and second to the\n"
-" subsequent XDM/GDM/KDM greeter. Note that if the user\n"
-" re-connects and supplies his username and password in\n"
-" the unixpw dialog the xdmcp greeter is skipped and\n"
-" he is connected directly to his existing X session.\n"
-" So the -unixpw_system_greeter option avoids the extra\n"
-" password at X session creation time.\n"
-"\n"
-" Example: x11vnc -xdmsvc -unixpw_system_greeter\n"
-" See -unixpw and -display WAIT:... for more info.\n"
-"\n"
-" The special options after a colon at the end of the\n"
-" username (e.g. user:solid) described under -display\n"
-" WAIT: are also applied in this mode if they are typed\n"
-" in before the user hits Escape. The username is ignored\n"
-" but the colon options are not.\n"
-"\n"
-" The default message is 2 lines in a small font, set\n"
-" the env. var. X11VNC_SYSTEM_GREETER1=true for a 1 line\n"
-" message in a larger font.\n"
-"\n"
-" If the user pressed Escape the FINDCREATEDISPLAY command\n"
-" will be run with the env. var. X11VNC_XDM_ONLY=1.\n"
-"\n"
-" Remember to enable XDMCP in the xdm-config, gdm.conf,\n"
-" or kdmrc configuration file. See -display WAIT: for\n"
-" more info.\n"
-"\n"
-"-redirect port As in FINDCREATEDISPLAY-Xvnc.redirect mode except\n"
-" redirect immediately (i.e. without X session finding\n"
-" or creation) to a VNC server listening on port. You\n"
-" can also supply host:port to redirect to a different\n"
-" machine.\n"
-"\n"
-" If 0 <= port < 200 it is taken as a VNC display (5900 is\n"
-" added to get the actual port), if port < 0 then -port\n"
-" is used.\n"
-"\n"
-" Probably the only reason to use the -redirect option\n"
-" is in conjunction with SSL support, e.g. -ssl SAVE.\n"
-" This provides an easy way to add SSL encryption to a VNC\n"
-" server that does not support SSL (e.g. Xvnc or vnc.so)\n"
-" In fact, the protocol does not even need to be VNC,\n"
-" and so \"-rfbport port1 -ssl SAVE -redirect host:port2\"\n"
-" can act as a replacement for stunnel(1).\n"
-"\n"
-" This mode only allows one redirected connection.\n"
-" The -forever option does not apply. Use -inetd or\n"
-" -loop for persistent service.\n"
-"\n"
-"-display WAIT:... A special usage mode for the normal -display option.\n"
-" Useful with -unixpw, but can be used independently\n"
-" of it. If the display string begins with WAIT: then\n"
-" x11vnc waits until a VNC client connects before opening\n"
-" the X display (or -rawfb device).\n"
-"\n"
-" This could be useful for delaying opening the display\n"
-" for certain usage modes (say if x11vnc is started at\n"
-" boot time and no X server is running or users logged\n"
-" in yet).\n"
-"\n"
-" If the string is, e.g. WAIT:0.0 or WAIT:1, i.e. \"WAIT\"\n"
-" in front of a normal X display, then that indicated\n"
-" display is used.\n"
-"\n"
-" One can also insert a geometry between colons, e.g.\n"
-" WAIT:1280x1024:... to set the size of the display the\n"
-" VNC client first attaches to since some VNC viewers\n"
-" will not automatically adjust to a new framebuffer size.\n"
-"\n"
-" A more interesting case is like this:\n"
-"\n"
-" WAIT:cmd=/usr/local/bin/find_display\n"
-"\n"
-" in which case the command after \"cmd=\" is run to\n"
-" dynamically work out the DISPLAY and optionally the\n"
-" XAUTHORITY data. The first line of the command output\n"
-" must be of the form DISPLAY=<xdisplay>. On Linux\n"
-" if the virtual terminal is known append \",VT=n\" to\n"
-" this string and the chvt(1) program will also be run.\n"
-" Any remaining output is taken as XAUTHORITY data.\n"
-" It can be either of the form XAUTHORITY=<file> or raw\n"
-" xauthority data for the display. For example;\n"
-"\n"
-" xauth extract - $DISPLAY\"\n"
-"\n"
-" NOTE: As specified in the previous paragraph, you can\n"
-" supply your own WAIT:cmd=... program or script, BUT\n"
-" there are two very useful *BUILT-IN* ones: FINDDISPLAY\n"
-" (alias -find above) and FINDCREATEDISPLAY (alias -create\n"
-" above.) Most people use these instead of creating\n"
-" their own script. Read the following (especially the\n"
-" BUILT-IN modes sections) to see how to configure these\n"
-" two useful builtin -display WAIT: modes.\n"
-"\n"
-" In the case of -unixpw (and -unixpw_nis only if x11vnc\n"
-" is running as root), then the cmd= command is run\n"
-" as the user who just authenticated via the login and\n"
-" password prompt.\n"
-"\n"
-" In the case of -unixpw_cmd, the commands will also be\n"
-" run as the logged-in user, as long as the user-supplied\n"
-" helper program supports RFB_UNIXPW_CMD_RUN (see the\n"
-" -unixpw_cmd option.)\n"
-"\n"
-" Also in the case of -unixpw, the user logging in can\n"
-" place a colon at the end of her username and supply\n"
-" a few options: scale=, scale_cursor= (or sc=), solid\n"
-" (or so), id=, clear_mods (or cm), clear_keys (or\n"
-" ck), clear_all (or ca), repeat, speeds= (or sp=),\n"
-" readtimeout= (or rd=), viewonly (or vo), nodisplay=\n"
-" (or nd=), rotate= (or ro=), or noncache (or nc),\n"
-" all separated by commas if there is more than one.\n"
-" After the user logs in successfully, these options will\n"
-" be applied to the VNC screen. For example,\n"
-"\n"
-" login: fred:scale=3/4,sc=1,repeat\n"
-" Password: ...\n"
-"\n"
-" login: runge:sp=modem,rd=120,solid\n"
-"\n"
-" for convenience m/n implies scale= e.g. fred:3/4 If you\n"
-" type and enter your password incorrectly, to retrieve\n"
-" your long \"login:\" line press the Up arrow once\n"
-" (before typing anything else).\n"
-"\n"
-" Most of these colon options only apply to the builtin\n"
-" FINDDISPLAY and FINDCREATEDISPLAY modes, but note\n"
-" that they are passed to the extrenal command in the\n"
-" environment as well and so could be used.\n"
-"\n"
-" In the login panel, press F1 to get a list of the\n"
-" available options that you can add after the username.\n"
-"\n"
-" Another option is \"geom=WxH\" or \"geom=WxHxD\" (or\n"
-" ge=). This only has an effect in FINDCREATEDISPLAY\n"
-" mode when a virtual X server such as Xvfb is going\n"
-" to be created. It sets the width and height of\n"
-" the new display, and optionally the color depth as\n"
-" well.\n"
-"\n"
-" You can also supply \"gnome\", \"kde\", \"twm\",\n"
-" \"fvwm\", \"mwm\", \"dtwm\", \"wmaker\", \"xfce\",\n"
-" \"lxde\", \"enlightenment\", \"Xsession\", or\n"
-" \"failsafe\" (same as \"xterm\") to have the created\n"
-" display use that mode for the user session.\n"
-"\n"
-" Specify \"tag=...\" to set the unique FD_TAG desktop\n"
-" session tag described below. Note: this option will\n"
-" be ignored if the FD_TAG env. var. is already set or\n"
-" if the viewer-side supplied value is not completely\n"
-" composed of alphanumeric or '_' or '-' characters.\n"
-"\n"
-" User preferences file: Instead of having the user type\n"
-" in geom=WxH,... etc. every time he logs in to find\n"
-" or create his X session, if you set FD_USERPREFS to\n"
-" a string that does not contain the \"/\" character,\n"
-" then the user's home directory is prepended to that\n"
-" string and if the file exists its first line is read\n"
-" and appended to any options he supplied at the login:\n"
-" prompt. For example -env FD_USERPREFS=.x11vnc_create\n"
-" and the user put \"geom=1600x1200\" in his\n"
-" ~/.x11vnc_create file.\n"
-"\n"
-" To disable the option setting set the environment\n"
-" variable X11VNC_NO_UNIXPW_OPTS=1 before starting x11vnc.\n"
-" To set any other options, the user can use the gui\n"
-" (x11vnc -gui connect) or the remote control method\n"
-" (x11vnc -R opt:val) during his VNC session.\n"
-"\n"
-" So we see the combination of -display WAIT:cmd=... and\n"
-" -unixpw allows automatic pairing of an unix\n"
-" authenticated VNC user with his desktop. This could\n"
-" be very useful on SunRays and also any system where\n"
-" multiple users share a given machine. The user does\n"
-" not need to remember special ports or passwords set up\n"
-" for his desktop and VNC.\n"
-"\n"
-" A nice way to use WAIT:cmd=... is out of inetd(8)\n"
-" (it automatically forks a new x11vnc for each user).\n"
-" You can have the x11vnc inetd spawned process run as,\n"
-" say, root or nobody. When run as root (for either inetd\n"
-" or display manager), you can also supply the option\n"
-" \"-users unixpw=\" to have the x11vnc process switch to\n"
-" the user as well. Note: there will be a 2nd SSL helper\n"
-" process that will not switch, but it is only encoding\n"
-" and decoding the encrypted stream at that point.\n"
-"\n"
-" BUILT-IN modes:\n"
-"\n"
-" -- Automatic Finding of User X Sessions --\n"
-"\n"
-" As a special case, WAIT:cmd=FINDDISPLAY will run a\n"
-" script that works on most Unixes to determine a user's\n"
-" DISPLAY variable and xauthority data (see who(1)).\n"
-"\n"
-" NOTE: The option \"-find\" is an alias for this mode.\n"
-"\n"
-" To have this default script printed to stdout (e.g. for\n"
-" customization) run with WAIT:cmd=FINDDISPLAY-print To\n"
-" have the script run to print what display it would find\n"
-" use \"-finddpy\" or WAIT:cmd=FINDDISPLAY-run\n"
-"\n"
-" The standard script runs xdpyinfo(1) run on potential\n"
-" displays. If your X server(s) have a login greeter\n"
-" that exclusively grabs the Xserver, then xdpyinfo\n"
-" blocks forever and this mode will not work. See\n"
-" www.karlrunge.com/x11vnc/faq.html#faq-display-manager\n"
-" for how to disable this for dtgreet on Solaris and\n"
-" possibly for other greeters.\n"
-"\n"
-" In -find/cmd=FINDDISPLAY mode, if you set FD_XDM=1,\n"
-" e.g. 'x11vnc -env FD_XDM=1 -find ...' and x11vnc is\n"
-" running as root (e.g. inetd) then it will try to find\n"
-" the XAUTHORITY file of a running XDM/GDM/KDM login\n"
-" greeter (i.e. no user has logged into an X session yet.)\n"
-"\n"
-" As another special case, WAIT:cmd=HTTPONCE will allow\n"
-" x11vnc to service one http request and then exit.\n"
-" This is usually done in -inetd mode to run on, say,\n"
-" port 5800 and allow the Java vncviewer to be downloaded\n"
-" by client web browsers. For example:\n"
-"\n"
-" 5815 stream tcp nowait root /usr/sbin/tcpd /.../x11vnc \\\n"
-" -inetd -q -http_ssl -prog /.../x11vnc \\\n"
-" -display WAIT:cmd=HTTPONCE\n"
-"\n"
-" Where /.../x11vnc is the full path to x11vnc.\n"
-" It is used in the Apache SSL-portal example (see FAQ).\n"
-"\n"
-" In this mode you can set X11VNC_SKIP_DISPLAY to a\n"
-" comma separated list of displays (e.g. \":0,:1\") to\n"
-" ignore in the finding process. The \":\" is optional.\n"
-" Ranges n-m e.g. 0-20 can also be supplied. This string\n"
-" can also be set by the connecting user via \"nd=\"\n"
-" using \"+\" instead of \",\" If \"nd=all\" or you set\n"
-" X11VNC_SKIP_DISPLAY=all then all display finding fails\n"
-" as if you set X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 (below.)\n"
-"\n"
-" On some systems lsof(1) can be very slow. Set the\n"
-" env. var. FIND_DISPLAY_NO_LSOF=1 to skip using lsof to\n"
-" try to find the Linux VT the X server is running on.\n"
-" set FIND_DISPLAY_NO_VT_FIND=1 to avoid looking at all.\n"
-"\n"
-" -- Automatic Creation of User X Sessions --\n"
-"\n"
-" An interesting option is WAIT:cmd=FINDCREATEDISPLAY\n"
-" that is like FINDDISPLAY in that is uses the same method\n"
-" to find an existing display. However, if it does not\n"
-" find one it will try to *start* up an X server session\n"
-" for the user. This is the only time x11vnc tries to\n"
-" actually start up an X server.\n"
-"\n"
-" NOTE: The option \"-create\" is an alias for this mode.\n"
-"\n"
-" It will start looking for an open display number at :20\n"
-" Override via X11VNC_CREATE_STARTING_DISPLAY_NUMBER=n\n"
-" By default 80 X displays are allowed (i.e. going to :99)\n"
-" Override via X11VNC_CREATE_MAX_DISPLAYS=n\n"
-"\n"
-" For its heuristics, the create display script sets\n"
-" LC_ALL=C so that command output is uniform. By default\n"
-" it will try to restore LC_ALL right before starting the\n"
-" user session. However, if you don't mind it keeping\n"
-" LC_ALL=C set the env. var.: X11VNC_CREATE_LC_ALL_C_OK=1\n"
-"\n"
-" By default FINDCREATEDISPLAY will try Xvfb and then\n"
-" Xdummy:\n"
-"\n"
-" The Xdummy wrapper is part of the x11vnc source code\n"
-" (x11vnc/misc/Xdummy) It should be available in PATH\n"
-" and have run \"Xdummy -install\" once to create the\n"
-" shared library. Xdummy only works on Linux. As of\n"
-" 12/2009 it no longer needs to be run as root, and the\n"
-" default is to not run as root. In some circumstances\n"
-" permissions may require running it as root, in these\n"
-" cases specify FD_XDUMMY_RUN_AS_ROOT=1, this is the same\n"
-" as supplying -root to the Xdummy cmdline.\n"
-"\n"
-" Xvfb is available on most platforms and does not\n"
-" require root.\n"
-"\n"
-" An advantage of Xdummy over Xvfb is that Xdummy supports\n"
-" RANDR dynamic screen resizing.\n"
-"\n"
-" When x11vnc exits (i.e. user disconnects) the X\n"
-" server session stays running in the background.\n"
-" The FINDDISPLAY will find it directly next time.\n"
-" The user must exit the X session in the usual way for\n"
-" it to terminate (or kill the X server process if all\n"
-" else fails).\n"
-"\n"
-" To troubleshoot the FINDCREATEDISPLAY mechanism,\n"
-" set the following env. var. to an output log file,\n"
-" e.g -env CREATE_DISPLAY_OUTPUT=/tmp/mydebug.txt\n"
-"\n"
-" So this is a somewhat odd mode for x11vnc in that it\n"
-" will start up and poll virtual X servers! This can\n"
-" be used from, say, inetd(8) to provide a means of\n"
-" definitely getting a desktop (either real or virtual)\n"
-" on the machine. E.g. a desktop service:\n"
-"\n"
-" 5900 stream tcp nowait root /usr/sbin/tcpd /.../x11vnc\n"
-" -inetd -q -http -ssl SAVE -unixpw -users unixpw=\\\n"
-" -passwd secret -prog /.../x11vnc \\\n"
-" -display WAIT:cmd=FINDCREATEDISPLAY\n"
-"\n"
-" Where /.../x11vnc is the full path to x11vnc.\n"
-"\n"
-" See the -svc/-service option alias above.\n"
-"\n"
-" If for some reason you do not want x11vnc to ever\n"
-" try to find an existing display set the env. var\n"
-" X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 (also -env ...)\n"
-" This is the same as setting X11VNC_SKIP_DISPLAY=all or\n"
-" supplying \"nd=all\" after \"username:\"\n"
-"\n"
-" Use WAIT:cmd=FINDCREATEDISPLAY-print to print out the\n"
-" script that is used for this.\n"
-"\n"
-" You can specify the preferred X server order via e.g.,\n"
-" WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb,X and/or leave\n"
-" out ones you do not want. The the case \"X\" means try\n"
-" to start up a real, hardware X server using xinit(1)\n"
-" or startx(1). If there is already an X server running\n"
-" the X case may only work on Linux (see startx(1)).\n"
-"\n"
-" \"Xvnc\" will start up a VNC X server (real-\n"
-" or tight-vnc, e.g. use if Xvfb is not available).\n"
-" \"Xsrv\" will start up the server program in the\n"
-" variable \"FD_XSRV\" if it is non-empty. You can make\n"
-" this be a wrapper script if you like (it must handle :N,\n"
-" -geometry, and -depth and other X server options).\n"
-"\n"
-" You can set the environment variable FD_GEOM (or\n"
-" X11VNC_CREATE_GEOM) to WxH or WxHxD to set the width\n"
-" and height and optionally the color depth of the\n"
-" created display. You can also set FD_SESS to be the\n"
-" session (short name of the windowmanager: kde, gnome,\n"
-" twm, failsafe, etc.). FD_OPTS contains extra options\n"
-" to pass to the X server. You can also set FD_PROG to\n"
-" be the full path to the session/windowmanager program.\n"
-"\n"
-" More FD tricks: FD_CUPS=port or FD_CUPS=host:port\n"
-" will set the cups printing environment. Similarly for\n"
-" FD_ESD=port or FD_ESD=host:port for esddsp sound\n"
-" redirection. Set FD_EXTRA to a command to be run a\n"
-" few seconds after the X server starts up. Set FD_TAG\n"
-" to be a unique name for the session, it is set as an\n"
-" X property, that makes FINDDISPLAY only find sessions\n"
-" with that tag value.\n"
-"\n"
-" Set FD_XDMCP_IF to the network interface that the\n"
-" display manager is running on; default is 'localhost'\n"
-" but you may need to set it to '::1' on some IPv6 only\n"
-" systems or misconfigured display managers.\n"
-"\n"
-" If you want the FINDCREATEDISPLAY session to contact an\n"
-" XDMCP login manager (xdm/gdm/kdm) on the same machine,\n"
-" then use \"Xvfb.xdmcp\" instead of \"Xvfb\", etc.\n"
-" The user will have to supply his username and password\n"
-" one more time (but he gets to select his desktop type\n"
-" so that can be useful). For this to work, you will\n"
-" need to enable localhost XDMCP (udp port 177) for the\n"
-" display manager. This seems to be:\n"
-"\n"
-" for gdm in gdm.conf: Enable=true in section [xdmcp]\n"
-" for kdm in kdmrc: Enable=true in section [Xdmcp]\n"
-" for xdm in xdm-config: DisplayManager.requestPort: 177\n"
-"\n"
-" See the shorthand options above \"-svc\", \"-xdmsvc\"\n"
-" and \"-sshxdmsvc\" that specify the above options for\n"
-" some useful cases.\n"
-"\n"
-" If you set the env. var WAITBG=1 x11vnc will go into\n"
-" the background once listening in wait mode.\n"
-"\n"
-" Another special mode is FINDCREATEDISPLAY-Xvnc.redirect,\n"
-" (or FINDDISPLAY-Xvnc.redirect). In this case it will\n"
-" start up Xvnc as above if needed, but instead of\n"
-" polling it in its normal way, it simply does a socket\n"
-" redirection of the connected VNC viewer to the Xvnc.\n"
-"\n"
-" So in Xvnc.redirect x11vnc does no VNC but merely\n"
-" transfers the data back and forth. This should be\n"
-" faster then x11vnc's polling method, but not as fast\n"
-" as connecting directly to the Xvnc with the VNC Viewer.\n"
-" The idea here is to take advantage of x11vnc's display\n"
-" finding/creating scheme, SSL, and perhaps a few others.\n"
-" Most of x11vnc's options do not apply in this mode.\n"
-"\n"
-" Xvnc.redirect should also work for the vnc.so X server\n"
-" module for the h/w display however it will work only\n"
-" for finding the display and the user must already be\n"
-" logged into the X console.\n"
-"\n"
-"-vencrypt mode The VeNCrypt extension to the VNC protocol allows\n"
-" encrypted SSL/TLS connections. If the -ssl mode is\n"
-" enabled, then VeNCrypt is enabled as well BY DEFAULT\n"
-" (they both use a SSL/TLS tunnel, only the protocol\n"
-" handshake is a little different.)\n"
-"\n"
-" To control when and how VeNCrypt is used, specify the\n"
-" mode string. If mode is \"never\", then VeNCrypt is\n"
-" not used. If mode is \"support\" (the default) then\n"
-" VeNCrypt is supported. If mode is \"only\", then the\n"
-" similar and older ANONTLS protocol is not simultaneously\n"
-" supported. x11vnc's normal SSL mode (vncs://) will be\n"
-" supported under -ssl unless you set mode to \"force\".\n"
-"\n"
-" If mode is prefixed with \"nodh:\", then Diffie Hellman\n"
-" anonymous key exchange is disabled. If mode is prefixed\n"
-" with \"nox509:\", then X509 key exchange is disabled.\n"
-"\n"
-" To disable all Anonymous Diffie-Hellman access\n"
-" (susceptible to Man-In-The-Middle attack) you will need\n"
-" to supply \"-vencrypt nodh:support -anontls never\"\n"
-" or \"-vencrypt nodh:only\"\n"
-"\n"
-" If mode is prefixed with \"newdh:\", then new Diffie\n"
-" Hellman parameters are generated for each connection\n"
-" (this can be time consuming: 1-60 secs; see -dhparams\n"
-" below for a faster way) rather than using the\n"
-" fixed values in the program. Using fixed, publicly\n"
-" known values is not known to be a security problem.\n"
-" This setting applies to ANONTLS as well.\n"
-"\n"
-" Long example: -vencrypt newdh:nox509:support\n"
-"\n"
-" Also, if mode is prefixed with \"plain:\", then\n"
-" if -unixpw mode is active the VeNCrypt \"*Plain\"\n"
-" username+passwd method is enabled for Unix logins.\n"
-" Otherwise in -unixpw mode the normal login panel is\n"
-" provided.\n"
-"\n"
-" You *MUST* supply the -ssl option for VeNCrypt to\n"
-" be active. The -vencrypt option only fine-tunes its\n"
-" operation.\n"
-"\n"
-"-anontls mode The ANONTLS extension to the VNC protocol allows\n"
-" encrypted SSL/TLS connections. If the -ssl mode is\n"
-" enabled, then ANONTLS is enabled as well BY DEFAULT\n"
-" (they both use a SSL/TLS tunnel, only the protocol\n"
-" handshake is a little different.)\n"
-"\n"
-" ANONTLS is an older SSL/TLS mode introduced by vino.\n"
-"\n"
-" It is referred to as 'TLS' for its registered VNC\n"
-" security-type name, but we use the more descriptive\n"
-" 'ANONTLS' here because it provides only Anonymous\n"
-" Diffie-Hellman encrypted connections, and hence no\n"
-" possibility for certificate authentication.\n"
-"\n"
-" To control when and how ANONTLS is used, specify the\n"
-" mode string. If mode is \"never\", then ANONTLS is not\n"
-" used. If mode is \"support\" (the default) then ANONTLS\n"
-" is supported. If mode is \"only\", then the similar\n"
-" VeNCrypt protocol is not simultaneously supported.\n"
-" x11vnc's normal SSL mode (vncs://) will be supported\n"
-" under -ssl unless you set mode to \"force\".\n"
-"\n"
-" If mode is prefixed with \"newdh:\", then new Diffie\n"
-" Hellman parameters are generated for each connection\n"
-" (this can be time consuming: 1-60 secs; see -dhparams\n"
-" below for a faster way) rather than using the\n"
-" fixed values in the program. Using fixed, publicly\n"
-" known values is not known to be a security problem.\n"
-" This setting applies to VeNCrypt as well. See the\n"
-" description of \"plain:\" under -vencrypt.\n"
-"\n"
-" Long example: -anontls newdh:plain:support\n"
-"\n"
-" You *MUST* supply the -ssl option for ANONTLS to\n"
-" be active. The -anontls option only fine-tunes its\n"
-" operation.\n"
-"\n"
-"-sslonly Same as: \"-vencrypt never -anontls never\" i.e. it\n"
-" disables the VeNCrypt and ANONTLS encryption methods\n"
-" and only allows standard SSL tunneling. You must also\n"
-" supply the -ssl ... option (see below.)\n"
-"\n"
-"\n"
-"-dhparams file For some operations a set of Diffie Hellman parameters\n"
-" (prime and generator) is needed. If so, use the\n"
-" parameters in \"file\". In particular, the VeNCrypt and\n"
-" ANONTLS anonymous DH mode need them. By default a\n"
-" fixed set is used. If you do not want to do that you\n"
-" can specify \"newdh:\" to the -vencrypt and -anontls\n"
-" options to generate a new set each session. If that\n"
-" is too slow for you, use -dhparams file to a set you\n"
-" created manually via \"openssl dhparam -out file 1024\"\n"
-"\n"
-"-nossl Disable the -ssl option (see below). Since -ssl is off\n"
-" by default -nossl would only be used on the commandline\n"
-" to unset any *earlier* -ssl option (or -svc...)\n"
-"\n"
-"-ssl [pem] Use the openssl library (www.openssl.org) to provide a\n"
-" built-in encrypted SSL/TLS tunnel between VNC viewers\n"
-" and x11vnc. This requires libssl support to be\n"
-" compiled into x11vnc at build time. If x11vnc is not\n"
-" built with libssl support it will exit immediately when\n"
-" -ssl is prescribed. See the -stunnel option below for\n"
-" an alternative.\n"
-"\n"
-" The VNC Viewer-side needs to support SSL/TLS as well.\n"
-" See this URL and also the discussion below for\n"
-" ideas on how to enable SSL support for the viewer:\n"
-" http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tun\n"
-" nel-viewers . x11vnc provides an SSL enabled Java\n"
-" viewer applet in the classes/ssl directory (-http or\n"
-" -httpdir options.) The SSVNC viewer package supports\n"
-" SSL tunnels too.\n"
-"\n"
-" If the VNC Viewer supports VeNCrypt or ANONTLS (vino's\n"
-" encryption mode) they are also supported by the -ssl\n"
-" mode (see the -vencrypt and -anontls options for more\n"
-" info; use -sslonly to disable both of them.)\n"
-"\n"
-" Use \"-ssl /path/to/mycert.pem\" to specify an SSL\n"
-" certificate file in PEM format to use to identify and\n"
-" provide a key for this server. See openssl(1) for more\n"
-" info about PEMs and the -sslGenCert and \"-ssl SAVE\"\n"
-" options below for how to create them.\n"
-"\n"
-" The connecting VNC viewer SSL tunnel can (at its option)\n"
-" authenticate this server if it has the public key part\n"
-" of the certificate (or a common certificate authority,\n"
-" CA, is a more sophisticated way to verify this server's\n"
-" cert, see -sslGenCA below). This authentication is\n"
-" done to prevent Man-In-The-Middle attacks. Otherwise,\n"
-" if the VNC viewer simply accepts this server's key\n"
-" WITHOUT verification, the traffic is protected from\n"
-" passive sniffing on the network, but *NOT* from\n"
-" Man-In-The-Middle attacks. There are hacker tools\n"
-" like dsniff/webmitm and cain that implement SSL\n"
-" Man-In-The-Middle attacks.\n"
-"\n"
-" If [pem] is empty or the string \"SAVE\" then the\n"
-" openssl(1) command must be available to generate the\n"
-" certificate the first time. A self-signed certificate\n"
-" is generated (see -sslGenCA and -sslGenCert for use\n"
-" of a Certificate Authority.) It will be saved to the\n"
-" file ~/.vnc/certs/server.pem. On subsequent calls if\n"
-" that file already exists it will be used directly.\n"
-"\n"
-" Use \"SAVE_NOPROMPT\" to avoid being prompted to\n"
-" protect the generated key with a passphrase. However in\n"
-" -inetd and -bg modes there will be no prompting for a\n"
-" passphrase in either case.\n"
-"\n"
-" If [pem] is \"SAVE_PROMPT\" the server.pem certificate\n"
-" will be created based on your answers to its prompts for\n"
-" all info such as OrganizationalName, CommonName, etc.\n"
-"\n"
-" Use \"SAVE-<string>\" and \"SAVE_PROMPT-<string>\"\n"
-" to refer to the file ~/.vnc/certs/server-<string>.pem\n"
-" instead (it will be generated if it does not already\n"
-" exist). E.g. \"SAVE-charlie\" will store to the file\n"
-" ~/.vnc/certs/server-charlie.pem\n"
-"\n"
-" Examples: x11vnc -ssl SAVE -display :0 ...\n"
-" x11vnc -ssl SAVE-someother -display :0 ...\n"
-"\n"
-" If [pem] is \"TMP\" and the openssl(1) utility\n"
-" command exists in PATH, then a temporary, self-signed\n"
-" certificate will be generated for this session. If\n"
-" openssl(1) cannot be used to generate a temporary\n"
-" certificate x11vnc exits immediately. The temporary\n"
-" cert will be discarded when x11vnc exits.\n"
-"\n"
-" If successful in using openssl(1) to generate a\n"
-" temporary certificate in \"SAVE\" or \"TMP\" creation\n"
-" modes, the public part of it will be displayed to stderr\n"
-" (e.g. one could copy it to the client-side to provide\n"
-" authentication of the server to VNC viewers.)\n"
-"\n"
-" NOTE: In \"TMP\" mode, unless you safely copy the\n"
-" public part of the temporary Cert to the viewer for\n"
-" authenticate *every time* (unlikely...), then only\n"
-" passive sniffing attacks are prevented and you are\n"
-" still open to Man-In-The-Middle attacks. This is\n"
-" why the default \"SAVE\" mode is preferred (and more\n"
-" sophisticated CA mode too). Only with saved keys AND\n"
-" the VNC viewer authenticating them (via the public\n"
-" certificate), are Man-In-The-Middle attacks prevented.\n"
-"\n"
-" If [pem] is \"ANON\" then the Diffie-Hellman anonymous\n"
-" key exchange method is used. In this mode there\n"
-" are *no* SSL certificates and so it is not possible\n"
-" to authenticate either the VNC server or VNC client.\n"
-" Thus only passive network sniffing attacks are avoided:\n"
-" the \"ANON\" method is susceptible to Man-In-The-Middle\n"
-" attacks. \"ANON\" is not recommended; instead use\n"
-" a SSL PEM you created or the default \"SAVE\" method.\n"
-"\n"
-" See -ssldir below to use a directory besides the\n"
-" default ~/.vnc/certs\n"
-"\n"
-" If your x11vnc binary was not compiled with OpenSSL\n"
-" library support, use of the -ssl option will induce an\n"
-" immediate failure and exit. For such binaries, consider\n"
-" using the -stunnel option for SSL encrypted connections.\n"
-"\n"
-" Misc Info: In temporary cert creation mode \"TMP\", set\n"
-" the env. var. X11VNC_SHOW_TMP_PEM=1 to have x11vnc print\n"
-" out the entire certificate, including the PRIVATE KEY\n"
-" part, to stderr. There are better ways to get/save this\n"
-" info. See \"SAVE\" above and \"-sslGenCert\" below.\n"
-"\n"
-"-ssltimeout n Set SSL read timeout to n seconds. In some situations\n"
-" (i.e. an iconified viewer in Windows) the viewer stops\n"
-" talking and the connection is dropped after the default\n"
-" timeout (25s for about the first minute, 43200s later).\n"
-" Set to zero to poll forever. Set to a negative value\n"
-" to use the builtin setting.\n"
-"\n"
-" Note that this value does NOT apply to the *initial* ssl\n"
-" init connection. The default timeout for that is 20sec.\n"
-" Use -env SSL_INIT_TIMEOUT=n to modify it.\n"
-"\n"
-"-sslnofail Exit at the first SSL connection failure. Useful when\n"
-" scripting SSL connections (e.g. x11vnc is started via\n"
-" ssh) and you do not want x11vnc waiting around for more\n"
-" connections, tying up ports, etc.\n"
-"\n"
-"-ssldir dir Use \"dir\" as an alternate ssl certificate and key\n"
-" management toplevel directory. The default is\n"
-" ~/.vnc/certs\n"
-"\n"
-" This directory is used to store server and other\n"
-" certificates and keys and also other materials. E.g. in\n"
-" the simplest case, \"-ssl SAVE\" will store the x11vnc\n"
-" server cert in dir/server.pem\n"
-"\n"
-" Use of alternate directories via -ssldir allows you to\n"
-" manage multiple VNC Certificate Authority (CA) keys.\n"
-" Another use is if ~/.vnc/cert is on an NFS share you\n"
-" might want your certificates and keys to be on a local\n"
-" filesystem to prevent network snooping (for example\n"
-" -ssldir /var/lib/x11vnc-certs).\n"
-"\n"
-" -ssldir affects nearly all of the other -ssl* options,\n"
-" e.g. -ssl SAVE, -sslGenCert, etc..\n"
-"\n"
-"-sslverify path For either of the -ssl or -stunnel modes, use \"path\"\n"
-" to provide certificates to authenticate incoming VNC\n"
-" *Client* connections (normally only the server is\n"
-" authenticated in SSL.) This can be used as a method\n"
-" to replace standard password authentication of clients.\n"
-"\n"
-" If \"path\" is a directory it contains the client (or CA)\n"
-" certificates in separate files. If path is a file,\n"
-" it contains one or more certificates. See special tokens\n"
-" below. These correspond to the \"CApath = dir\" and\n"
-" \"CAfile = file\" stunnel options. See the stunnel(8)\n"
-" manpage for details.\n"
-"\n"
-" Examples:\n"
-" x11vnc -ssl -sslverify ~/my.crt\n"
-" x11vnc -ssl -sslverify ~/my_pem_dir/\n"
-"\n"
-" Note that if path is a directory, it must contain\n"
-" the certs in separate files named like <HASH>.0, where\n"
-" the value of <HASH> is found by running the command\n"
-" \"openssl x509 -hash -noout -in file.crt\". Evidently\n"
-" one uses <HASH>.1 if there is a collision...\n"
-"\n"
-" The the key-management utility \"-sslCertInfo HASHON\"\n"
-" and \"-sslCertInfo HASHOFF\" will create/delete these\n"
-" hashes for you automatically (via symlink) in the HASH\n"
-" subdirs it manages. Then you can point -sslverify to\n"
-" the HASH subdir.\n"
-"\n"
-" Special tokens: in -ssl mode, if \"path\" is not a file or\n"
-" a directory, it is taken as a comma separated list of\n"
-" tokens that are interpreted as follows:\n"
-"\n"
-" If a token is \"CA\" that means load the CA/cacert.pem\n"
-" file from the ssl directory. If a token is \"clients\"\n"
-" then all the files clients/*.crt in the ssl directory\n"
-" are loaded. Otherwise the file clients/token.crt\n"
-" is attempted to be loaded. As a kludge, use a token\n"
-" like ../server-foo to load a server cert if you find\n"
-" that necessary.\n"
-"\n"
-" Use -ssldir to use a directory different from the\n"
-" ~/.vnc/certs default.\n"
-"\n"
-" Note that if the \"CA\" cert is loaded you do not need\n"
-" to load any of the certs that have been signed by it.\n"
-" You will need to load any additional self-signed certs\n"
-" however.\n"
-"\n"
-" Examples:\n"
-" x11vnc -ssl -sslverify CA\n"
-" x11vnc -ssl -sslverify self:fred,self:jim\n"
-" x11vnc -ssl -sslverify CA,clients\n"
-"\n"
-" Usually \"-sslverify CA\" is the most effective.\n"
-" See the -sslGenCA and -sslGenCert options below for\n"
-" how to set up and manage the CA framework.\n"
-"\n"
-"\n"
-"\n"
-" NOTE: the following utilities, -sslGenCA, -sslGenCert,\n"
-" -sslEncKey, -sslCertInfo, and -sslCRL are provided for\n"
-" completeness, but for casual usage they are overkill.\n"
-"\n"
-" They provide VNC Certificate Authority (CA) key creation\n"
-" and server / client key generation and signing. So they\n"
-" provide a basic Public Key management framework for\n"
-" VNC-ing with x11vnc. (note that they require openssl(1)\n"
-" be installed on the system)\n"
-"\n"
-" However, the simplest usage mode, \"-ssl TMP\" (where\n"
-" x11vnc automatically generates its own, self-signed,\n"
-" temporary key and the VNC viewers always accept it,\n"
-" e.g. accepting via a dialog box) is probably safe enough\n"
-" for most scenarios. CA management is not needed.\n"
-"\n"
-" To protect against Man-In-The-Middle attacks the \"TMP\"\n"
-" mode can be improved by using \"-ssl SAVE\" (same as\n"
-" \"-ssl\", i.e. the default) to have x11vnc create a\n"
-" longer term self-signed certificate, and then (safely)\n"
-" copy the corresponding public key cert to the desired\n"
-" client machines (care must be taken the private key part\n"
-" is not stolen; you will be prompted for a passphrase).\n"
-"\n"
-" So keep in mind no CA key creation or management\n"
-" (-sslGenCA and -sslGenCert) is needed for either of\n"
-" the above two common usage modes.\n"
-"\n"
-" One might want to use -sslGenCA and -sslGenCert\n"
-" if you had a large number of VNC client and server\n"
-" workstations. That way the administrator could generate\n"
-" a single CA key with -sslGenCA and distribute its\n"
-" certificate part to all of the workstations.\n"
-"\n"
-" Next, he could create signed VNC server keys\n"
-" (-sslGenCert server ...) for each workstation or user\n"
-" that then x11vnc would use to authenticate itself to\n"
-" any VNC client that has the CA cert.\n"
-"\n"
-" Optionally, the admin could also make it so the\n"
-" VNC clients themselves are authenticated to x11vnc\n"
-" (-sslGenCert client ...) For this -sslverify would be\n"
-" pointed to the CA cert (and/or self-signed certs).\n"
-"\n"
-" x11vnc will be able to use all of these cert and\n"
-" key files. On the VNC client side, they will need to\n"
-" be \"imported\" somehow. Web browsers have \"Manage\n"
-" Certificates\" actions as does the Java applet plugin\n"
-" Control Panel. stunnel can also use these files (see\n"
-" the ss_vncviewer example script in the FAQ and SSVNC.)\n"
-"\n"
-"-sslCRL path Set the Certificate Revocation Lists (CRL) to \"path\".\n"
-" This setting applies for both -ssl and -stunnel modes.\n"
-"\n"
-" If path is a file, the file contains one or more CRLs\n"
-" in PEM format. If path is a directory, it contains\n"
-" hash named files of CRLs in the usual OpenSSL manner.\n"
-" See the OpenSSL and stunnel(8) documentation for\n"
-" more info.\n"
-"\n"
-" This option only applies if -sslverify has been\n"
-" supplied: it checks for revocation along the\n"
-" certificate chain used to verify the VNC client.\n"
-" The -sslCRL setting will be ignored when -sslverify is\n"
-" not specified.\n"
-"\n"
-" Note that if a CRL's expiration date has passed, all\n"
-" SSL connections will fail regardless of if they are\n"
-" related to the subject of the CRL or not.\n"
-"\n"
-" Only rarely will one's x11vnc -ssl infrastructure be so\n"
-" large that this option would be useful (since normally\n"
-" maintaining the contents of the -sslverify file or\n"
-" directory should be enough.) However, when using\n"
-" x11vnc with a Certificate Authority (see -sslGenCA)\n"
-" to authenticate Clients via SSL/TLS, the -sslCRL option\n"
-" can be useful to revoke users' certs whose private SSL\n"
-" keys were lost or stolen (e.g. laptop.) This way a new\n"
-" CA cert+key does not need to be created and new signed\n"
-" client keys generated and distributed to all users.\n"
-"\n"
-" To create a CRL file with revoked certificates the\n"
-" commands 'openssl ca -revoke ...' and 'openssl ca\n"
-" -gencrl ...' are useful. (Run them in ~/.vnc/certs)\n"
-"\n"
-"-sslGenCA [dir] Generate your own Certificate Authority private key,\n"
-" certificate, and other files in directory [dir].\n"
-" x11vnc then exits.\n"
-"\n"
-" If [dir] is not supplied, a -ssldir setting is used,\n"
-" or otherwise ~/.vnc/certs is used.\n"
-"\n"
-" This command also creates directories where server and\n"
-" client certs and keys will be stored. The openssl(1)\n"
-" program must be installed on the system and available\n"
-" in PATH.\n"
-"\n"
-" After the CA files and directories are created the\n"
-" x11vnc command exits; the VNC server is not run.\n"
-"\n"
-" You will be prompted for information to put into the CA\n"
-" certificate. The info does not have to be accurate just\n"
-" as long as clients accept the cert for VNC connections.\n"
-" You will also need to supply a passphrase of at least\n"
-" 4 characters for the CA private key.\n"
-"\n"
-" Once you have generated the CA you can distribute\n"
-" its certificate part, [dir]/CA/cacert.pem, to other\n"
-" workstations where VNC viewers will be run. One will\n"
-" need to \"import\" this certificate in the applications,\n"
-" e.g. Web browser, Java applet plugin, stunnel, etc.\n"
-" Next, you can create and sign keys using the CA with\n"
-" the -sslGenCert option below.\n"
-"\n"
-" Examples:\n"
-" x11vnc -sslGenCA\n"
-" x11vnc -sslGenCA ~/myCAdir\n"
-" x11vnc -ssldir ~/myCAdir -sslGenCA\n"
-"\n"
-" (the last two lines are equivalent)\n"
-"\n"
-"-sslGenCert type name Generate a VNC server or client certificate and private\n"
-" key pair signed by the CA created previously with\n"
-" -sslGenCA. The openssl(1) program must be installed\n"
-" on the system and available in PATH.\n"
-"\n"
-" After the Certificate is generated x11vnc exits; the\n"
-" VNC server is not run.\n"
-"\n"
-" The type of key to be generated is the string \"type\".\n"
-" It is either \"server\" (i.e. for use by x11vnc) or\n"
-" \"client\" (for a VNC viewer). Note that typically\n"
-" only \"server\" is used: the VNC clients authenticate\n"
-" themselves by a non-public-key method (e.g. VNC or\n"
-" unix password). \"type\" is required.\n"
-"\n"
-" An arbitrary default name you want to associate with\n"
-" the key is supplied by the \"name\" string. You can\n"
-" change it at the various prompts when creating the key.\n"
-" \"name\" is optional.\n"
-"\n"
-" If name is left blank for clients keys then \"nobody\"\n"
-" is used. If left blank for server keys, then the\n"
-" primary server key: \"server.pem\" is created (this\n"
-" is the saved one referenced by \"-ssl SAVE\" when the\n"
-" server is started)\n"
-"\n"
-" If \"name\" begins with the string \"self:\" then\n"
-" a self-signed certificate is created instead of one\n"
-" signed by your CA key.\n"
-"\n"
-" If \"name\" begins with the string \"req:\" then only a\n"
-" key (.key) and a certificate signing *request* (.req)\n"
-" are generated. You can then send the .req file to\n"
-" an external CA (even a professional one, e.g. Thawte)\n"
-" and then combine the .key and the received cert into\n"
-" the .pem file with the same basename.\n"
-"\n"
-" The distinction between \"server\" and \"client\" is\n"
-" simply the choice of output filenames and sub-directory.\n"
-" This makes it so the -ssl SAVE-name option can easily\n"
-" pick up the x11vnc PEM file this option generates.\n"
-" And similarly makes it easy for the -sslverify option\n"
-" to pick up your client certs.\n"
-"\n"
-" There is nothing special about the filename or directory\n"
-" location of either the \"server\" and \"client\" certs.\n"
-" You can rename the files or move them to wherever\n"
-" you like.\n"
-"\n"
-" Precede this option with -ssldir [dir] to use a\n"
-" directory other than the default ~/.vnc/certs You will\n"
-" need to run -sslGenCA on that directory first before\n"
-" doing any -sslGenCert key creation.\n"
-"\n"
-" Note you cannot recreate a cert with exactly the same\n"
-" distiguished name (DN) as an existing one. To do so,\n"
-" you will need to edit the [dir]/CA/index.txt file to\n"
-" delete the line.\n"
-"\n"
-" Similar to -sslGenCA, you will be prompted to fill\n"
-" in some information that will be recorded in the\n"
-" certificate when it is created.\n"
-"\n"
-" Tip: if you know the fully-qualified hostname other\n"
-" people will be connecting to, you can use that as the\n"
-" CommonName \"CN\" to avoid some applications (e.g. web\n"
-" browsers and java plugin) complaining that it does not\n"
-" match the hostname.\n"
-"\n"
-" You will also need to supply the CA private key\n"
-" passphrase to unlock the private key created from\n"
-" -sslGenCA. This private key is used to sign the server\n"
-" or client certificate.\n"
-"\n"
-" The \"server\" certs can be used by x11vnc directly by\n"
-" pointing to them via the -ssl [pem] option. The default\n"
-" file will be ~/.vnc/certs/server.pem. This one would\n"
-" be used by simply typing -ssl SAVE. The pem file\n"
-" contains both the certificate and the private key.\n"
-" server.crt file contains the cert only.\n"
-"\n"
-" The \"client\" cert + private key file will need\n"
-" to be copied and imported into the VNC viewer\n"
-" side applications (Web browser, Java plugin,\n"
-" stunnel, etc.) Once that is done you can delete the\n"
-" \"client\" private key file on this machine since\n"
-" it is only needed on the VNC viewer side. The,\n"
-" e.g. ~/.vnc/certs/clients/<name>.pem contains both\n"
-" the cert and private key. The <name>.crt contains the\n"
-" certificate only.\n"
-"\n"
-" NOTE: It is very important to know one should\n"
-" generate new keys with a passphrase. Otherwise if an\n"
-" untrusted user steals the key file he could use it to\n"
-" masquerade as the x11vnc server (or VNC viewer client).\n"
-" You will be prompted whether to encrypt the key with\n"
-" a passphrase or not. It is recommended that you do.\n"
-" One inconvenience to a passphrase is that it must\n"
-" be typed in EVERY time x11vnc or the client app is\n"
-" started up.\n"
-"\n"
-" Examples:\n"
-"\n"
-" x11vnc -sslGenCert server\n"
-" x11vnc -ssl SAVE -display :0 ...\n"
-"\n"
-" and then on viewer using ss_vncviewer stunnel wrapper\n"
-" (see the FAQ):\n"
-
-" ss_vncviewer -verify ./cacert.crt hostname:0\n"
-"\n"
-" (this assumes the cacert.crt cert from -sslGenCA\n"
-" was safely copied to the VNC viewer machine where\n"
-" ss_vncviewer is run)\n"
-"\n"
-" Example using a name:\n"
-"\n"
-" x11vnc -sslGenCert server charlie\n"
-" x11vnc -ssl SAVE-charlie -display :0 ...\n"
-"\n"
-" Example for a client certificate (rarely used):\n"
-"\n"
-" x11vnc -sslGenCert client roger\n"
-" scp ~/.vnc/certs/clients/roger.pem somehost:.\n"
-" rm ~/.vnc/certs/clients/roger.pem\n"
-"\n"
-" x11vnc is then started with the option -sslverify\n"
-" ~/.vnc/certs/clients/roger.crt (or simply -sslverify\n"
-" roger), and on the viewer user on somehost could do\n"
-" for example:\n"
-"\n"
-" ss_vncviewer -mycert ./roger.pem hostname:0\n"
-"\n"
-" If you set the env. var REQ_ARGS='...' it will be\n"
-" passed to openssl req(1). A common use would be\n"
-" REQ_ARGS='-days 1095' to bump up the expiration date\n"
-" (3 years in this case).\n"
-"\n"
-"-sslEncKey pem Utility to encrypt an existing PEM file with a\n"
-" passphrase you supply when prompted. For that key to be\n"
-" used (e.g. by x11vnc) the passphrase must be supplied\n"
-" each time.\n"
-"\n"
-" The \"SAVE\" notation described under -ssl applies as\n"
-" well. (precede this option with -ssldir [dir] to refer\n"
-" a directory besides the default ~/.vnc/certs)\n"
-"\n"
-" The openssl(1) program must be installed on the system\n"
-" and available in PATH. After the Key file is encrypted\n"
-" the x11vnc command exits; the VNC server is not run.\n"
-"\n"
-" Examples:\n"
-" x11vnc -sslEncKey /path/to/foo.pem\n"
-" x11vnc -sslEncKey SAVE\n"
-" x11vnc -sslEncKey SAVE-charlie\n"
-"\n"
-"-sslCertInfo pem Prints out information about an existing PEM file.\n"
-" In addition the public certificate is also printed.\n"
-" The openssl(1) program must be in PATH. Basically the\n"
-" command \"openssl x509 -text\" is run on the pem.\n"
-"\n"
-" After the info is printed the x11vnc command exits;\n"
-" the VNC server is not run.\n"
-"\n"
-" The \"SAVE\" notation described under -ssl applies\n"
-" as well.\n"
-"\n"
-" Using \"LIST\" will give a list of all certs being\n"
-" managed (in the ~/.vnc/certs dir, use -ssldir to refer\n"
-" to another dir). \"ALL\" will print out the info for\n"
-" every managed key (this can be very long). Giving a\n"
-" client or server cert shortname will also try a lookup\n"
-" (e.g. -sslCertInfo charlie). Use \"LISTL\" or \"LL\"\n"
-" for a long (ls -l style) listing.\n"
-"\n"
-" Using \"HASHON\" will create subdirs [dir]/HASH and\n"
-" [dir]/HASH with OpenSSL hash filenames (e.g. 0d5fbbf1.0)\n"
-" symlinks pointing up to the corresponding *.crt file.\n"
-" ([dir] is ~/.vnc/certs or one given by -ssldir.)\n"
-" This is a useful way for other OpenSSL applications\n"
-" (e.g. stunnel) to access all of the certs without\n"
-" having to concatenate them. x11vnc will not use them\n"
-" unless you specifically reference them. \"HASHOFF\"\n"
-" removes these HASH subdirs.\n"
-"\n"
-" The LIST, LISTL, LL, ALL, HASHON, HASHOFF words can\n"
-" also be lowercase, e.g. \"list\".\n"
-"\n"
-"-sslDelCert pem Prompts you to delete all .crt .pem .key .req files\n"
-" associated with [pem]. x11vnc then exits. \"SAVE\"\n"
-" and lookups as in -sslCertInfo apply as well.\n"
-"\n"
-"-sslScripts Prints out both the 'genCA' and 'genCert' x11vnc\n"
-" openssl wrapper scripts for you to examine, modify, etc.\n"
-" The scripts are printed to stdout and then the x11vnc\n"
-" program exits.\n"
-"\n"
-"\n"
-"-stunnel [pem] Use the stunnel(8) (stunnel.mirt.net) to provide an\n"
-" encrypted SSL tunnel between viewers and x11vnc.\n"
-"\n"
-" This external tunnel method was implemented prior to the\n"
-" integrated -ssl encryption described above. It still\n"
-" works well and avoids the requirement of linking with\n"
-" the OpenSSL libraries. This mode requires stunnel\n"
-" to be installed on the system and available via PATH\n"
-" (n.b. stunnel is often installed in sbin directories).\n"
-" Version 4.x of stunnel is assumed (but see -stunnel3\n"
-" below.)\n"
-"\n"
-" [pem] is optional, use \"-stunnel /path/to/stunnel.pem\"\n"
-" to specify a PEM certificate file to pass to stunnel.\n"
-" See the -ssl option for more info on certificate files.\n"
-"\n"
-" Whether or not your stunnel has its own certificate\n"
-" depends on your stunnel configuration; stunnel often\n"
-" generates one at install time. See your stunnel\n"
-" documentation for details. In any event, if you want to\n"
-" use this certificate you must supply the full path to it\n"
-" as [pem]. Note: the file may only be readable by root.\n"
-"\n"
-" [pem] may also be the special strings \"TMP\", \"SAVE\",\n"
-" and \"SAVE...\" as described in the -ssl option.\n"
-" If [pem] is not supplied, \"SAVE\" is assumed.\n"
-"\n"
-" Note that the VeNCrypt, ANONTLS, and \"ANON\" modes\n"
-" are not supported in -stunnel mode.\n"
-"\n"
-" stunnel is started up as a child process of x11vnc and\n"
-" any SSL connections stunnel receives are decrypted and\n"
-" sent to x11vnc over a local socket. The strings\n"
-" \"The SSL VNC desktop is ...\" and \"SSLPORT=...\"\n"
-" are printed out at startup to indicate this.\n"
-"\n"
-" The -localhost option is enforced by default to avoid\n"
-" people routing around the SSL channel. Use -env\n"
-" STUNNEL_DISABLE_LOCALHOST=1 to disable this security\n"
-" requirement.\n"
-"\n"
-" Set -env STUNNEL_DEBUG=1 for more debugging printout.\n"
-"\n"
-" Set -env STUNNEL_PROG=xxx to the full path of stunnel\n"
-" program you want to be used (e.g. /usr/bin/stunnel4).\n"
-"\n"
-" Set -env STUNNEL_LISTEN=xxx to the address of the\n"
-" network interface to listen on (the default is to listen\n"
-" on all interfaces), e.g. STUNNEL_LISTEN=192.168.1.100.\n"
-"\n"
-" A simple way to add IPv6 support is STUNNEL_LISTEN=::\n"
-"\n"
-" Your VNC viewer will also need to be able to connect\n"
-" via SSL. Unfortunately not too many do this. See the\n"
-" information about SSL viewers under the -ssl option.\n"
-" The x11vnc project's SSVNC is an option.\n"
-"\n"
-" Also, in the x11vnc distribution, patched TightVNC\n"
-" and UltraVNC Java applet jar files are provided in\n"
-" the classes/ssl directory that do SSL connections.\n"
-" Enable serving them with the -http, -http_ssl, or\n"
-" -httpdir (see the option descriptions for more info.)\n"
-"\n"
-" Note that for the Java viewer applet usage the\n"
-" \"?PORT=xxxx\" in the various URLs printed at startup\n"
-" will need to be supplied to the web browser to connect\n"
-" properly.\n"
-"\n"
-" Currently the automatic \"single port\" HTTPS mode of\n"
-" -ssl is not fully supported in -stunnel mode. However,\n"
-" it can be emulated via:\n"
-"\n"
-" %% x11vnc -stunnel -http_ssl -http_oneport ...\n"
-"\n"
-" In general, it is also not too difficult to set up\n"
-" an stunnel or other SSL tunnel on the viewer side.\n"
-" A simple example on Unix using stunnel 3.x is:\n"
-"\n"
-" %% stunnel -c -d localhost:5901 -r remotehost:5900\n"
-" %% vncviewer localhost:1\n"
-"\n"
-" For Windows, stunnel has been ported to it and there\n"
-" are probably other such tools available. See the FAQ\n"
-" and SSVNC for more examples.\n"
-"\n"
-"-stunnel3 [pem] Use version 3.x stunnel command line syntax instead of\n"
-" version 4.x. The -http/-httpdir Java applet serving\n"
-" is currently not available in this mode.\n"
-"\n"
-"-enc cipher:keyfile Use symmetric encryption with cipher \"cipher\"\n"
-" and secret key data in \"keyfile\". If keyfile is\n"
-" pw=<string> then \"string\" is used as the key data.\n"
-"\n"
-" NOTE: It is recommended that you use SSL via the -ssl\n"
-" option instead of this option because SSL is well\n"
-" understood and takes great care to establish unique\n"
-" session keys and is more compatible with other software.\n"
-" Use this option if you do not want to deal with SSL\n"
-" certificates for authentication and do not want to\n"
-" use SSH but want some encryption for your VNC session.\n"
-" Or if you must interface with a symmetric key tunnel\n"
-" that you do not have control over.\n"
-"\n"
-" Note that this mode will NOT work with the UltraVNC DSM\n"
-" plugins because they alter the RFB protocol in addition\n"
-" to tunnelling with the symmetric cipher (an unfortunate\n"
-" choice of implementation...)\n"
-"\n"
-" cipher can be one of: arc4, aesv2, aes-cfb, blowfish,\n"
-" aes256, or 3des. See the OpenSSL documentation for\n"
-" more info. The keysize is 128 bits (except for aes256).\n"
-" Here is one way to make a keyfile with that many bits:\n"
-"\n"
-" dd if=/dev/random of=./my.key bs=16 count=1\n"
-"\n"
-" you will need to securely share this key with the other\n"
-" side of the VNC connection (See SSVNC for examples).\n"
-"\n"
-" Example: -enc blowfish:./my.key\n"
-" Example: -enc blowfish:pw=swordfish\n"
-"\n"
-" By default 16 bytes of random salt followed by 16 bytes\n"
-" of random initialization vector are sent at the very\n"
-" beginning of the stream. The other side must read these\n"
-" and initialize their cipher with them. These values\n"
-" make the session key unique (without them the security\n"
-" is minimal). Similarly, the other side must send us\n"
-" its random salt and IV with those same lengths.\n"
-"\n"
-" The salt and key data are combined to create a session\n"
-" key using an md5 hash as described in EVP_BytesToKey(3).\n"
-"\n"
-" The exact call is: EVP_BytesToKey(Cipher, EVP_md5(),\n"
-" salt, keydata, len, 1, keystr, NULL); where salt is\n"
-" the random data as described above, and keydata is the\n"
-" shared secret key data. keystr is the resulting session\n"
-" key. The cipher is then seeded with keystr and uses\n"
-" the random initialization vector as its first block.\n"
-"\n"
-" To modify the amount of random salt and initialization\n"
-" vector use cipher@n,m where n is the salt length and\n"
-" m the initialization vector length. E.g.\n"
-"\n"
-" -enc aes-cfb@8,16:./my.key\n"
-"\n"
-" It is not a good idea to set either one to zero,\n"
-" although you may be forced to if the other side of the\n"
-" tunnel is not under your control.\n"
-"\n"
-" To skip the salt and EVP_BytesToKey MD5 entirely (no\n"
-" hashing is done: the keydata is directly inserted into\n"
-" the cipher) specify \"-1\" for the salt, e.g.\n"
-"\n"
-" -enc blowfish@-1,16:./my.key\n"
-"\n"
-" The message digest can also be changed to something\n"
-" besides the default MD5. Use cipher@md+n,m where \"md\"\n"
-" can be one of sha, sha1, md5, or ripe. For example:\n"
-"\n"
-" -enc arc4@sha+8,16:./my.key\n"
-"\n"
-" The SSVNC vnc viewer project supplies a symmetric\n"
-" encryption tool named \"ultravnc_dsm_helper\" that can\n"
-" be used on the viewer side. For example:\n"
-"\n"
-" ssvncviewer exec='ultravnc_dsm_helper arc4 my.key 0 h:p'\n"
-"\n"
-" where h:p is the hostname and port of the x11vnc server.\n"
-" ultravnc_dsm_helper may also be used standalone to\n"
-" provide a symmetric encryption tunnel for any viewer\n"
-" or server (VNC or otherwise.) The cipher (1st arg)\n"
-" is basically the same syntax as we use above.\n"
-"\n"
-" Also see the 'Non-Ultra DSM' SSVNC option for the\n"
-" 'UltraVNC DSM Encryption Plugin' advanced option.\n"
-"\n"
-" For both ways of using the viewer, you can specify the\n"
-" salt,ivec sizes (in GUI or, e.g. arc4@8,16).\n"
-"\n"
-"-https [port] Use a special, separate HTTPS port (-ssl and\n"
-" -stunnel modes only) for HTTPS Java viewer applet\n"
-" downloading. I.e. not 5900 and not 5800 (the defaults.)\n"
-"\n"
-" BACKGROUND: In -ssl mode, it turns out you can use the\n"
-" single VNC port (e.g. 5900) for both VNC and HTTPS\n"
-" connections. (HTTPS is used to retrieve a SSL-aware\n"
-" VncViewer.jar applet that is provided with x11vnc).\n"
-" Since both use SSL the implementation was extended to\n"
-" detect if HTTP traffic (i.e. GET) is taking place and\n"
-" handle it accordingly. The URL would be, e.g.:\n"
-"\n"
-" https://mymachine.org:5900/\n"
-"\n"
-" This is convenient for firewalls, etc, because only one\n"
-" port needs to be allowed in. However, this heuristic\n"
-" adds a few seconds delay to each connection and can be\n"
-" unreliable (especially if the user takes much time to\n"
-" ponder the Certificate dialogs in his browser, Java VM,\n"
-" or VNC Viewer applet. That's right 3 separate \"Are\n"
-" you sure you want to connect?\" dialogs!)\n"
-"\n"
-" END OF BACKGROUND.\n"
-"\n"
-" USAGE: So use the -https option to provide a separate,\n"
-" more reliable HTTPS port that x11vnc will listen on. If\n"
-" [port] is not provided (or is 0), one is autoselected.\n"
-" The URL to use is printed out at startup.\n"
-"\n"
-" The SSL Java applet directory is specified via the\n"
-" -httpdir option. If not supplied, -https will try\n"
-" to guess the directory as though the -http option\n"
-" was supplied.\n"
-"\n"
-"-httpsredir [port] In -ssl mode with the Java applet retrieved via HTTPS,\n"
-" when the HTML file containing applet parameters\n"
-" ('index.vnc' or 'proxy.vnc') is sent do NOT set the\n"
-" applet PORT parameter to the actual VNC port but set it\n"
-" to \"port\" instead. If \"port\" is not supplied, then\n"
-" the port number is guessed from the Host: HTTP header.\n"
-"\n"
-" This is useful when an incoming TCP connection\n"
-" redirection is performed by a router/gateway/firewall\n"
-" from one port to an internal machine where x11vnc is\n"
-" listening on a different port. The Java applet needs to\n"
-" connect to the firewall/router port, not the VNC port\n"
-" on the internal workstation. For example, one could\n"
-" redir from mygateway.com:443 to workstation:5900.\n"
-"\n"
-" This spares the user from having to type in\n"
-" https://mygateway.com/?PORT=443 into their web\n"
-" browser. Note that port 443 is the default https port;\n"
-" other ports must be explicitly indicated, for example:\n"
-" https://mygateway.com:8000/?PORT=8000. To avoid having\n"
-" to include the PORT= in the browser URL, simply supply\n"
-" \"-httpsredir\" to x11vnc.\n"
-"\n"
-" This option does not work in -stunnel mode.\n"
-"\n"
-" More tricks: set the env var X11VNC_EXTRA_HTTPS_PARAMS\n"
-" to be extra URL parameters to use. This way you do\n"
-" not need to specify extra PARAMS in the index.vnc file.\n"
-" E.g. x11vnc -env X11VNC_EXTRA_HTTPS_PARAMS='?GET=1' ...\n"
-"\n"
-" If you do not want to expose the non-SSL HTTP port to\n"
-" the network (i.e. you just want the single VNC/HTTPS\n"
-" port, e.g. 5900, open for connections) then specify the\n"
-" option -env X11VNC_HTTP_LISTEN_LOCALHOST=1 This way\n"
-" the connection to the LibVNCServer httpd server will\n"
-" only be available on localhost (note that in -ssl mode,\n"
-" HTTPS requests are redirected from SSL to the non-SSL\n"
-" LibVNCServer HTTP server.)\n"
-"\n"
-"-http_oneport For UN-encrypted connections mode (i.e. no -ssl,\n"
-" -stunnel, or -enc options), allow the Java VNC Viewer\n"
-" applet to be downloaded thru the VNC port via HTTP.\n"
-"\n"
-" That is to say, you can use a single port for Java\n"
-" applet viewer connections by using a URL in your web\n"
-" browser like this, for example:\n"
-"\n"
-" http://hostname:5900\n"
-"\n"
-" The regular, two-port mode, URL http://hostname:5800\n"
-" will continue to work as well.\n"
-"\n"
-" As mentioned above, this mode will NOT work with\n"
-" the -ssl, -stunnel, or -enc encryption options.\n"
-" Note that is it equivalent to '-enc none' (i.e. it\n"
-" uses the same detection mechanism as for HTTPS, but\n"
-" with no encryption.)\n"
-"\n"
-" HTTPS single-port is on by default in -ssl encrypted\n"
-" mode (and -enc too), so you only need -http_oneport\n"
-" when doing non-SSL encrypted connections.\n"
-"\n"
-" This mode could also be useful for SSH tunnels since\n"
-" it means only one port needs to be redirected.\n"
-"\n"
-" The -httpsredir option may also be useful for this\n"
-" mode when using an SSH tunnel as well as for router\n"
-" port redirections.\n"
-"\n"
-" Note that the -env X11VNC_HTTP_LISTEN_LOCALHOST=1\n"
-" option described above under -httpsredir applies for\n"
-" the LibVNCServer httpd server in all cases (ssl or not.)\n"
-"\n"
-"-ssh user@host:disp Create a remote listening port on machine \"host\"\n"
-" via a SSH tunnel using the -R rport:localhost:lport\n"
-" method. lport will be the local x11vnc listening port,\n"
-" so a connection to rport (5900+disp) on \"host\"\n"
-" will reach x11vnc. E.g. fred@snoopy.com:0\n"
-"\n"
-" This could be useful if a firewall/router prevents\n"
-" incoming connections to the x11vnc machine, but\n"
-" the ssh machine \"host\" can be reached by the VNC\n"
-" viewer. \"user@\" is not needed unless the remote unix\n"
-" username differs from the current one.\n"
-"\n"
-" By default the remote sshd is usually configured to\n"
-" listen only on localhost for rport, so the viewer may\n"
-" need to ssh -L redir to \"host\" as well (See SSVNC to\n"
-" automate this). The sshd setting GatewayPorts enables\n"
-" listening on all interfaces for rport; viewers can\n"
-" reach it more easily.\n"
-"\n"
-" \"disp\" is the VNC display for the remote SSH side,\n"
-" e.g. 0 corresponds to port 5900, etc. If disp is\n"
-" greater than 200 the value is used as the port. Use a\n"
-" negative value to force a low port, e.g. host:-80 will\n"
-" use port 80.\n"
-"\n"
-" If ssh-agent is not active, then the ssh password needs\n"
-" to be entered in the terminal where x11vnc is running.\n"
-"\n"
-" By default the remote ssh will issue a 'sleep 300' to\n"
-" wait for the incoming connection for 5 mins. To modify\n"
-" this use user@host:disp+secs.\n"
-"\n"
-" If the remote SSH server is on a non-standard port\n"
-" (i.e. not 22) use user@host:port:disp+secs.\n"
-"\n"
-" Note that the ssh process MAY NOT be killed when\n"
-" x11vnc exits. It tries by looking at ps(1) output.\n"
-"\n"
-"-usepw If no other password method was supplied on the command\n"
-" line, first look for ~/.vnc/passwd and if found use it\n"
-" with -rfbauth; next, look for ~/.vnc/passwdfile and\n"
-" use it with -passwdfile; otherwise, prompt the user\n"
-" for a password to create ~/.vnc/passwd and use it with\n"
-" the -rfbauth option. If none of these succeed x11vnc\n"
-" exits immediately.\n"
-"\n"
-"-storepasswd pass file Store password \"pass\" as the VNC password in the\n"
-" file \"file\". Once the password is stored the\n"
-" program exits. Use the password via \"-rfbauth file\"\n"
-"\n"
-" If called with no arguments, \"x11vnc -storepasswd\",\n"
-" the user is prompted for a password and it is stored\n"
-" in the file ~/.vnc/passwd. Called with one argument,\n"
-" that will be the file to store the prompted password in.\n"
-"\n"
-"-nopw Disable the big warning message when you use x11vnc\n"
-" without some sort of password.\n"
-"\n"
-"-accept string Run a command (possibly to prompt the user at the\n"
-" X11 display) to decide whether an incoming client\n"
-" should be allowed to connect or not. \"string\" is\n"
-" an external command run via system(3) or some special\n"
-" cases described below. Be sure to quote \"string\"\n"
-" if it contains spaces, shell characters, etc. If the\n"
-" external command returns 0 the client is accepted,\n"
-" otherwise the client is rejected. See below for an\n"
-" extension to accept a client view-only.\n"
-"\n"
-" If x11vnc is running as root (say from inetd(8) or from\n"
-" display managers xdm(1), gdm(1), etc), think about the\n"
-" security implications carefully before supplying this\n"
-" option (likewise for the -gone option).\n"
-"\n"
-" Environment: The RFB_CLIENT_IP environment variable will\n"
-" be set to the incoming client IP number and the port\n"
-" in RFB_CLIENT_PORT (or -1 if unavailable). Similarly,\n"
-" RFB_SERVER_IP and RFB_SERVER_PORT (the x11vnc side\n"
-" of the connection), are set to allow identification\n"
-" of the tcp virtual circuit. The x11vnc process\n"
-" id will be in RFB_X11VNC_PID, a client id number in\n"
-" RFB_CLIENT_ID, and the number of other connected clients\n"
-" in RFB_CLIENT_COUNT. RFB_MODE will be \"accept\".\n"
-" RFB_STATE will be PROTOCOL_VERSION, SECURITY_TYPE,\n"
-" AUTHENTICATION, INITIALISATION, NORMAL, or UNKNOWN\n"
-" indicating up to which state the client has achieved.\n"
-" RFB_LOGIN_VIEWONLY will be 0, 1, or -1 (unknown).\n"
-" RFB_USERNAME, RFB_LOGIN_TIME, and RFB_CURRENT_TIME may\n"
-" also be set.\n"
-"\n"
-" If \"string\" is \"popup\" then a builtin popup window\n"
-" is used. The popup will time out after 120 seconds,\n"
-" use \"popup:N\" to modify the timeout to N seconds\n"
-" (use 0 for no timeout).\n"
-"\n"
-" In the case of \"popup\" and when the -unixpw option\n"
-" is specified, then a *second* window will be popped\n"
-" up after the user successfully logs in via his UNIX\n"
-" password. This time the user will be identified as\n"
-" UNIX:username@hostname, the \"UNIX:\" prefix indicates\n"
-" which user the viewer logged as via -unixpw. The first\n"
-" popup is only for whether to allow him to even *try*\n"
-" to login via unix password.\n"
-"\n"
-" If \"string\" is \"xmessage\" then an xmessage(1)\n"
-" invocation is used for the command. xmessage must be\n"
-" installed on the machine for this to work.\n"
-"\n"
-" Both \"popup\" and \"xmessage\" will present an option\n"
-" for accepting the client \"View-Only\" (the client\n"
-" can only watch). This option will not be presented if\n"
-" -viewonly has been specified, in which case the entire\n"
-" display is view only.\n"
-"\n"
-" If the user supplied command is prefixed with something\n"
-" like \"yes:0,no:*,view:3 mycommand ...\" then this\n"
-" associates the numerical command return code with\n"
-" the actions: accept, reject, and accept-view-only,\n"
-" respectively. Use \"*\" instead of a number to indicate\n"
-" the default action (in case the command returns an\n"
-" unexpected value). E.g. \"no:*\" is a good choice.\n"
-"\n"
-" Note that x11vnc blocks while the external command\n"
-" or popup is running (other clients may see no updates\n"
-" during this period). So a person sitting a the physical\n"
-" display is needed to respond to an popup prompt. (use\n"
-" a 2nd x11vnc if you lock yourself out).\n"
-"\n"
-" More -accept tricks: use \"popupmouse\" to only allow\n"
-" mouse clicks in the builtin popup to be recognized.\n"
-" Similarly use \"popupkey\" to only recognize\n"
-" keystroke responses. These are to help avoid the\n"
-" user accidentally accepting a client by typing or\n"
-" clicking. All 3 of the popup keywords can be followed\n"
-" by +N+M to supply a position for the popup window.\n"
-" The default is to center the popup window.\n"
-"-afteraccept string As -accept, except to run a user supplied command after\n"
-" a client has been accepted and authenticated. RFB_MODE\n"
-" will be set to \"afteraccept\" and the other RFB_*\n"
-" variables are as in -accept. Unlike -accept, the\n"
-" command return code is not interpreted by x11vnc.\n"
-" Example: -afteraccept 'killall xlock &'\n"
-"-gone string As -accept, except to run a user supplied command when\n"
-" a client goes away (disconnects). RFB_MODE will be\n"
-" set to \"gone\" and the other RFB_* variables are as\n"
-" in -accept. The \"popup\" actions apply as well.\n"
-" Unlike -accept, the command return code is not\n"
-" interpreted by x11vnc. Example: -gone 'xlock &'\n"
-"\n"
-"-users list If x11vnc is started as root (say from inetd(8) or from\n"
-" display managers xdm(1), gdm(1), etc), then as soon\n"
-" as possible after connections to the X display are\n"
-" established try to switch to one of the users in the\n"
-" comma separated \"list\". If x11vnc is not running as\n"
-" root this option is ignored.\n"
-"\n"
-" Why use this option? In general it is not needed since\n"
-" x11vnc is already connected to the X display and can\n"
-" perform its primary functions. The option was added\n"
-" to make some of the *external* utility commands x11vnc\n"
-" occasionally runs work properly. In particular under\n"
-" GNOME and KDE to implement the \"-solid color\" feature\n"
-" external commands (gconftool-2 and dcop) unfortunately\n"
-" must be run as the user owning the desktop session.\n"
-" Since this option switches userid it also affects the\n"
-" userid used to run the processes for the -accept and\n"
-" -gone options. It also affects the ability to read\n"
-" files for options such as -connect, -allow, and -remap\n"
-" and also the ultra and tight filetransfer feature if\n"
-" enabled. Note that the -connect file is also sometimes\n"
-" written to.\n"
-"\n"
-" So be careful with this option since in some situations\n"
-" its use can decrease security.\n"
-"\n"
-" In general the switch to a user will only take place\n"
-" if the display can still be successfully opened as that\n"
-" user (this is primarily to try to guess the actual owner\n"
-" of the session). Example: \"-users fred,wilma,betty\".\n"
-" Note that a malicious local user \"barney\" by\n"
-" quickly using \"xhost +\" when logging in may possibly\n"
-" get the x11vnc process to switch to user \"fred\".\n"
-" What happens next?\n"
-"\n"
-" Under display managers it may be a long time before\n"
-" the switch succeeds (i.e. a user logs in). To instead\n"
-" make it switch immediately regardless if the display\n"
-" can be reopened prefix the username with the \"+\"\n"
-" character. E.g. \"-users +bob\" or \"-users +nobody\".\n"
-"\n"
-" The latter (i.e. switching immediately to user\n"
-" \"nobody\") is the only obvious use of the -users option\n"
-" that increases security.\n"
-"\n"
-" Use the following notation to associate a group with\n"
-" a user: user1.group1,user2.group2,... Note that\n"
-" initgroups(2) will still be called first to try to\n"
-" switch to ALL of a user's groups (primary and additional\n"
-" groups). Only if that fails or it is not available\n"
-" then the single group specified as above (or the user's\n"
-" primary group if not specified) is switched to with\n"
-" setgid(2). Use -env X11VNC_SINGLE_GROUP=1 to prevent\n"
-" trying initgroups(2) and only switch to the single\n"
-" group. This sort of setting is only really needed to\n"
-" make the ultra or tight filetransfer permissions work\n"
-" properly. This format applies to any comma separated list\n"
-" of users, even the special \"=\" modes described below.\n"
-"\n"
-" In -unixpw mode, if \"-users unixpw=\" is supplied\n"
-" then after a user authenticates himself via the\n"
-" -unixpw mechanism, x11vnc will try to switch to that\n"
-" user as though \"-users +username\" had been supplied.\n"
-" If you want to limit which users this will be done for,\n"
-" provide them as a comma separated list after \"unixpw=\"\n"
-" Groups can also be specified as described above.\n"
-"\n"
-" Similarly, in -ssl mode, if \"-users sslpeer=\" is\n"
-" supplied then after an SSL client authenticates with his\n"
-" cert (the -sslverify option is required for this) x11vnc\n"
-" will extract a UNIX username from the \"emailAddress\"\n"
-" field (username@hostname.com) of the \"Subject\" of the\n"
-" x509 SSL cert and then try to switch to that user as\n"
-" though \"-users +username\" had been supplied. If you\n"
-" want to limit which users this will be done for, provide\n"
-" them as a comma separated list after \"sslpeer=\".\n"
-" Set the env. var X11VNC_SSLPEER_CN to use the Common\n"
-" Name (normally a hostname) instead of the Email field.\n"
-"\n"
-" NOTE: for sslpeer= mode the x11vnc administrator must\n"
-" take care that any client certs he adds to -sslverify\n"
-" have the intended UNIX username in the \"emailAddress\"\n"
-" field of the cert. Otherwise a user may be able to\n"
-" log in as another. This command can be of use in\n"
-" checking: \"openssl x509 -text -in file.crt\", see the\n"
-" \"Subject:\" line. Also, along with the normal RFB_*\n"
-" env. vars. (see -accept) passed to external cmd=\n"
-" commands, RFB_SSL_CLIENT_CERT will be set to the\n"
-" client's x509 certificate string.\n"
-"\n"
-" The sslpeer= mode can aid finding X sessions via the\n"
-" FINDDISPLAY and FINDCREATEDISPLAY mechanisms.\n"
-"\n"
-" To immediately switch to a user *before* connections\n"
-" to the X display are made or any files opened use the\n"
-" \"=\" character: \"-users =bob\". That user needs to\n"
-" be able to open the X display and any files of course.\n"
-"\n"
-" The special user \"guess=\" means to examine the utmpx\n"
-" database (see who(1)) looking for a user attached to\n"
-" the display number (from DISPLAY or -display option)\n"
-" and try him/her. To limit the list of guesses, use:\n"
-" \"-users guess=bob,betty\".\n"
-"\n"
-" Even more sinister is the special user \"lurk=\"\n"
-" that means to try to guess the DISPLAY from the utmpx\n"
-" login database as well. So it \"lurks\" waiting for\n"
-" anyone to log into an X session and then connects to it.\n"
-" Specify a list of users after the = to limit which users\n"
-" will be tried. To enable a different searching mode, if\n"
-" the first user in the list is something like \":0\" or\n"
-" \":0-2\" that indicates a range of DISPLAY numbers that\n"
-" will be tried (regardless of whether they are in the\n"
-" utmpx database) for all users that are logged in. Also\n"
-" see the \"-display WAIT:...\" functionality. Examples:\n"
-" \"-users lurk=\" and also \"-users lurk=:0-1,bob,mary\"\n"
-"\n"
-" Be especially careful using the \"guess=\" and \"lurk=\"\n"
-" modes. They are not recommended for use on machines\n"
-" with untrustworthy local users.\n"
-"\n"
-"-noshm Do not use the MIT-SHM extension for the polling.\n"
-" Remote displays can be polled this way: be careful this\n"
-" can use large amounts of network bandwidth. This is\n"
-" also of use if the local machine has a limited number\n"
-" of shm segments and -onetile is not sufficient.\n"
-"-flipbyteorder Sometimes needed if remotely polled host has different\n"
-" endianness. Ignored unless -noshm is set.\n"
-"-onetile Do not use the new copy_tiles() framebuffer mechanism,\n"
-" just use 1 shm tile for polling. Limits shm segments\n"
-" used to 3.\n"
-"\n"
-" To disable any automatic shm reduction set the\n"
-" env. var. X11VNC_NO_LIMIT_SHM.\n"
-"\n"
-"-solid [color] To improve performance, when VNC clients are connected\n"
-" try to change the desktop background to a solid color.\n"
-" The [color] is optional: the default color is \"cyan4\".\n"
-" For a different one specify the X color (rgb.txt name,\n"
-" e.g. \"darkblue\" or numerical \"#RRGGBB\").\n"
-"\n"
-" Currently this option only works on GNOME, KDE, CDE,\n"
-" XFCE, and classic X (i.e. with the background image\n"
-" on the root window). The \"gconftool-2\", \"dcop\"\n"
-" and \"xfconf-query\" external commands are run for\n"
-" GNOME, KDE, and XFCE respectively. This also works\n"
-" on native MacOSX. (There is no color selection for\n"
-" MacOSX or XFCE.) Other desktops won't work, (send\n"
-" us the corresponding commands if you find them).\n"
-" If x11vnc is running as root (inetd(8) or gdm(1)),\n"
-" the -users option may be needed for GNOME, KDE, XFCE.\n"
-" If x11vnc guesses your desktop incorrectly, you can\n"
-" force it by prefixing color with \"gnome:\", \"kde:\",\n"
-" \"cde:\", \"xfce:\", or \"root:\".\n"
-"\n"
-" Update: -solid no longer works on KDE4.\n"
-"\n"
-" This mode works in a limited way on the Mac OS X Console\n"
-" with one color ('kelp') using the screensaver writing\n"
-" to the background. Look in \"~/Library/Screen Savers\"\n"
-" for VncSolidColor.png to change the color.\n"
-"\n"
-"-blackout string Black out rectangles on the screen. \"string\" is a\n"
-" comma separated list of WxH+X+Y type geometries for\n"
-" each rectangle. If one of the items on the list is the\n"
-" string \"noptr\" the mouse pointer will not be allowed\n"
-" to go into a blacked out region.\n"
-"-xinerama If your screen is composed of multiple monitors\n"
-"-noxinerama glued together via XINERAMA, and that screen is\n"
-" not a rectangle this option will try to guess the\n"
-" areas to black out (if your system has libXinerama).\n"
-" default: %s\n"
-"\n"
-" In general, we have noticed on XINERAMA displays you may\n"
-" need to use the \"-xwarppointer\" option if the mouse\n"
-" pointer misbehaves and it is enabled by default. Use\n"
-" \"-noxwarppointer\" if you do not want this.\n"
-"\n"
-"-xtrap Use the DEC-XTRAP extension for keystroke and mouse\n"
-" input insertion. For use on legacy systems, e.g. X11R5,\n"
-" running an incomplete or missing XTEST extension.\n"
-" By default DEC-XTRAP will be used if XTEST server grab\n"
-" control is missing, use -xtrap to do the keystroke and\n"
-" mouse insertion via DEC-XTRAP as well.\n"
-"\n"
-"-xrandr [mode] If the display supports the XRANDR (X Resize, Rotate\n"
-" and Reflection) extension, and you expect XRANDR events\n"
-" to occur to the display while x11vnc is running, this\n"
-" options indicates x11vnc should try to respond to\n"
-" them (as opposed to simply crashing by assuming the\n"
-" old screen size). See the xrandr(1) manpage and run\n"
-" 'xrandr -q' for more info. [mode] is optional and\n"
-" described below.\n"
-"\n"
-" Since watching for XRANDR events and trapping errors\n"
-" increases polling overhead, only use this option if\n"
-" XRANDR changes are expected. For example on a rotatable\n"
-" screen PDA or laptop, or using a XRANDR-aware Desktop\n"
-" where you resize often. It is best to be viewing with a\n"
-" vncviewer that supports the NewFBSize encoding, since it\n"
-" knows how to react to screen size changes. Otherwise,\n"
-" LibVNCServer tries to do so something reasonable for\n"
-" viewers that cannot do this (portions of the screen\n"
-" may be clipped, unused, etc).\n"
-"\n"
-" Note: the default now is to check for XRANDR events, but\n"
-" do not trap every X call that may fail due to resize.\n"
-" If a resize event is received, the full -xrandr mode\n"
-" is enabled. To disable even checking for events supply:\n"
-" -noxrandr.\n"
-"\n"
-" \"mode\" defaults to \"resize\", which means create a\n"
-" new, resized, framebuffer and hope all viewers can cope\n"
-" with the change. \"newfbsize\" means first disconnect\n"
-" all viewers that do not support the NewFBSize VNC\n"
-" encoding, and then resize the framebuffer. \"exit\"\n"
-" means disconnect all viewer clients, and then terminate\n"
-" x11vnc.\n"
-"\n"
-"-rotate string Rotate and/or flip the framebuffer view exported by VNC.\n"
-" This transformation is independent of XRANDR and is\n"
-" done in software in main memory and so may be slower.\n"
-" This mode could be useful on a handheld with portrait or\n"
-" landscape modes that do not correspond to the scanline\n"
-" order of the actual framebuffer. \"string\" can be:\n"
-"\n"
-" x flip along x-axis\n"
-" y flip along y-axis\n"
-" xy flip along x- and y-axes\n"
-" +90 rotate 90 degrees clockwise\n"
-" -90 rotate 90 degrees counter-clockwise\n"
-" +90x rotate 90 degrees CW, then flip along x\n"
-" +90y rotate 90 degrees CW, then flip along y\n"
-"\n"
-" these give all possible rotations and reflections.\n"
-"\n"
-" Aliases: same as xy: yx, +180, -180, 180\n"
-" same as -90: +270, 270\n"
-" same as +90: 90, (ditto for 90x, 90y)\n"
-"\n"
-" Like -scale, this transformation is applied at the very\n"
-" end of any chain of framebuffer transformations and so\n"
-" any options with geometries, e.g. -blackout, -clip, etc.\n"
-" are relative to the original X (or -rawfb) framebuffer,\n"
-" not the final one sent to VNC viewers.\n"
-"\n"
-" If you do not want the cursor shape to be rotated\n"
-" prefix \"string\" with \"nc:\", e.g. \"nc:+90\",\n"
-" \"nc:xy\", etc.\n"
-"\n"
-"-padgeom WxH Whenever a new vncviewer connects, the framebuffer is\n"
-" replaced with a fake, solid black one of geometry WxH.\n"
-" Shortly afterwards the framebuffer is replaced with the\n"
-" real one. This is intended for use with vncviewers\n"
-" that do not support NewFBSize and one wants to make\n"
-" sure the initial viewer geometry will be big enough\n"
-" to handle all subsequent resizes (e.g. under -xrandr,\n"
-" -remote id:windowid, rescaling, etc.)\n"
-"\n"
-" In -unixpw mode this sets the size of the login screen.\n"
-" Use \"once:WxH\" it ignore padgeom after the login\n"
-" screen is set up.\n"
-"\n"
-"-o logfile Write stderr messages to file \"logfile\" instead of to\n"
-" the terminal. Same as \"-logfile file\". To append\n"
-" to the file use \"-oa file\" or \"-logappend file\".\n"
-" If \"logfile\" contains the string \"%%VNCDISPLAY\"\n"
-" it is expanded to the vnc display (the name may need\n"
-" to be guessed at.) \"%%HOME\" works too.\n"
-"\n"
-"-flag file Write the \"PORT=NNNN\" (e.g. PORT=5900) string to\n"
-" \"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"
-"-env VAR=VALUE Set the environment variable 'VAR' to value 'VALUE'\n"
-" at x11vnc startup. This is a convenience utility to\n"
-" avoid shell script wrappers, etc. to set the env. var.\n"
-" You may specify as many of these as needed on the\n"
-" command line.\n"
-"-prog /path/to/x11vnc Set the full path to the x11vnc program for cases when\n"
-" it cannot be determined from argv[0] (e.g. tcpd/inetd)\n"
-"\n"
-"-h, -help Print this help text.\n"
-"-?, -opts Only list the x11vnc options.\n"
-"-V, -version Print program version and last modification date.\n"
-"-license Print out license information. Same as -copying and\n"
-" -warranty.\n"
-"\n"
-"-dbg Instead of exiting after cleaning up, run a simple\n"
-" \"debug crash shell\" when fatal errors are trapped.\n"
-"\n"
-"-q, -quiet Be quiet by printing less informational output to\n"
-" stderr. (use -noquiet to undo an earlier -quiet.)\n"
-"\n"
-" The -quiet option does not eliminate all informational\n"
-" output, it only reduces it. It is ignored in most\n"
-" auxiliary usage modes, e.g. -storepasswd. To eliminate\n"
-" all output use: 2>/dev/null 1>&2, etc.\n"
-"\n"
-"-v, -verbose Print out more information to stderr.\n"
-"\n"
-"-bg Go into the background after screen setup. Messages to\n"
-" stderr are lost unless -o logfile is used. Something\n"
-" like this could be useful in a script:\n"
-" port=`ssh -t $host \"x11vnc -display :0 -bg\" | grep PORT`\n"
-" port=`echo \"$port\" | sed -e 's/PORT=//'`\n"
-" port=`expr $port - 5900`\n"
-" vncviewer $host:$port\n"
-"\n"
-"-modtweak Option -modtweak automatically tries to adjust the AltGr\n"
-"-nomodtweak and Shift modifiers for differing language keyboards\n"
-" between client and host. Otherwise, only a single key\n"
-" press/release of a Keycode is simulated (i.e. ignoring\n"
-" the state of the modifiers: this usually works for\n"
-" identical keyboards). Also useful in resolving cases\n"
-" where a Keysym is bound to multiple keys (e.g. \"<\" + \">\"\n"
-" and \",\" + \"<\" keys). Default: %s\n"
-"\n"
-" If you are having trouble with with keys and -xkb or\n"
-" -noxkb, and similar things don't help, try -nomodtweak.\n"
-"\n"
-" On some HP-UX systems it is been noted that they have\n"
-" an odd keymapping where a single keycode will have a\n"
-" keysym, e.g. \"#\", up to three times. You can check\n"
-" via \"xmodmap -pk\" or the -dk option. The failure\n"
-" is when you try to type \"#\" it yields \"3\". If you\n"
-" see this problem try setting the environment variable\n"
-" MODTWEAK_LOWEST=1 to see if it helps.\n"
-"\n"
-"-xkb When in modtweak mode, use the XKEYBOARD extension (if\n"
-"-noxkb the X display supports it) to do the modifier tweaking.\n"
-" This is powerful and should be tried if there are still\n"
-" keymapping problems when using -modtweak by itself.\n"
-" The default is to check whether some common keysyms,\n"
-" e.g. !, @, [, are only accessible via -xkb mode and if\n"
-" so then automatically enable the mode. To disable this\n"
-" automatic detection use -noxkb.\n"
-"\n"
-" When -xkb mode is active you can set these env. vars.\n"
-" They apply only when there is ambiguity as to which\n"
-" key to choose (i.e the mapping is not one-to-one).\n"
-" NOKEYHINTS=1: for up ascii keystrokes do not use score\n"
-" hints saved when the key was pressed down. NOANYDOWN=1:\n"
-" for up keystrokes do not resort to searching through\n"
-" keys that are currently pressed down. KEYSDOWN=N:\n"
-" remember the last N keys press down for tie-breaking\n"
-" when an up keystroke comes in.\n"
-"\n"
-"-capslock When in -modtweak (the default) or -xkb mode,\n"
-" if a keysym in the range A-Z comes in check the X\n"
-" server to see if the Caps_Lock is set. If it is do\n"
-" not artificially press Shift to generate the keysym.\n"
-" This will enable the CapsLock key to behave correctly\n"
-" in some circumstances: namely *both* the VNC viewer\n"
-" machine and the x11vnc X server are in the CapsLock\n"
-" on state. If one side has CapsLock on and the other\n"
-" off and the keyboard is not behaving as you think it\n"
-" should you should correct the CapsLock states (hint:\n"
-" pressing CapsLock inside and outside of the viewer can\n"
-" help toggle them both to the correct state). However,\n"
-" for best results do not use this option, but rather\n"
-" *only* enable CapsLock on the VNC viewer side (i.e. by\n"
-" pressing CapsLock outside of the viewer window, also\n"
-" -skip_lockkeys below). Also try -nomodtweak for a\n"
-" possible workaround.\n"
-"\n"
-"-skip_lockkeys Have x11vnc ignore all Caps_Lock, Shift_Lock, Num_Lock,\n"
-"-noskip_lockkeys Scroll_Lock keysyms received from viewers. The idea is\n"
-" you press Caps_Lock on the VNC Viewer side but that does\n"
-" not change the lock state in the x11vnc-side X server.\n"
-" Nevertheless your capitalized letters come in over\n"
-" the wire and are applied correctly to the x11vnc-side\n"
-" X server. Note this mode probably won't do what you\n"
-" want in -nomodtweak mode. Also, a kludge for KP_n\n"
-" digits is always done in this mode: they are mapped to\n"
-" regular digit keysyms. See also -capslock above.\n"
-" The default is -noskip_lockkeys.\n"
-"\n"
-"-skip_keycodes string Ignore the comma separated list of decimal keycodes.\n"
-" Perhaps these are keycodes not on your keyboard but\n"
-" your X server thinks exist. Currently only applies\n"
-" to -xkb mode. Use this option to help x11vnc in the\n"
-" reverse problem it tries to solve: Keysym -> Keycode(s)\n"
-" when ambiguities exist (more than one Keycode per\n"
-" Keysym). Run 'xmodmap -pk' to see your keymapping.\n"
-" Example: \"-skip_keycodes 94,114\"\n"
-"-sloppy_keys Experimental option that tries to correct some\n"
-" \"sloppy\" key behavior. E.g. if at the viewer you\n"
-" press Shift+Key but then release the Shift before\n"
-" Key that could give rise to extra unwanted characters\n"
-" (usually only between keyboards of different languages).\n"
-" Only use this option if you observe problems with\n"
-" some keystrokes.\n"
-"-skip_dups Some VNC viewers send impossible repeated key events,\n"
-"-noskip_dups e.g. key-down, key-down, key-up, key-up all for the same\n"
-" key, or 20 downs in a row for the same modifier key!\n"
-" Setting -skip_dups means to skip these duplicates and\n"
-" just process the first event. Note: some VNC viewers\n"
-" assume they can send down's without the corresponding\n"
-" up's and so you should not set this option for\n"
-" these viewers (symptom: some keys do not autorepeat)\n"
-" Default: %s\n"
-"-add_keysyms If a Keysym is received from a VNC viewer and that\n"
-"-noadd_keysyms Keysym does not exist in the X server, then add the\n"
-" Keysym to the X server's keyboard mapping on an unused\n"
-" key. Added Keysyms will be removed periodically and\n"
-" also when x11vnc exits. Default: %s\n"
-"-clear_mods At startup and exit clear the modifier keys by sending\n"
-" KeyRelease for each one. The Lock modifiers are skipped.\n"
-" Used to clear the state if the display was accidentally\n"
-" left with any pressed down.\n"
-"-clear_keys As -clear_mods, except try to release ANY pressed key.\n"
-" Note that this option and -clear_mods can interfere\n"
-" with a person typing at the physical keyboard.\n"
-"-clear_all As -clear_keys, except try to release any CapsLock,\n"
-" NumLock, etc. locks as well.\n"
-"\n"
-"-remap string Read Keysym remappings from file named \"string\".\n"
-" Format is one pair of Keysyms per line (can be name\n"
-" or hex value) separated by a space. If no file named\n"
-" \"string\" exists, it is instead interpreted as this\n"
-" form: key1-key2,key3-key4,... See <X11/keysymdef.h>\n"
-" header file for a list of Keysym names, or use xev(1).\n"
-"\n"
-" To map a key to a button click, use the fake Keysyms\n"
-" \"Button1\", ..., etc. E.g: \"-remap Super_R-Button2\"\n"
-" (useful for pasting on a laptop)\n"
-"\n"
-" I use these if the machine I am viewing from does not\n"
-" have a scrollwheel or I don't like using the one it has:\n"
-"\n"
-" -remap Super_R-Button4,Menu-Button5\n"
-" -remap KP_Add-Button4,KP_Enter-Button5\n"
-"\n"
-" the former would be used on a PC, the latter on a\n"
-" MacBook. This way those little used keys can be used\n"
-" to generate bigger hops than the Up and Down arrows\n"
-" provide. One can scroll through text or web pages more\n"
-" quickly this way (especially if x11vnc scroll detection\n"
-" is active.)\n"
-"\n"
-" Use Button44, Button12, etc. for multiple clicks.\n"
-"\n"
-" To disable a keysym (i.e. make it so it will not be\n"
-" injected), remap it to \"NoSymbol\" or \"None\".\n"
-"\n"
-" Dead keys: \"dead\" (or silent, mute) keys are keys that\n"
-" do not produce a character but must be followed by a 2nd\n"
-" keystroke. This is often used for accenting characters,\n"
-" e.g. to put \"`\" on top of \"a\" by pressing the dead\n"
-" key and then \"a\". Note that this interpretation\n"
-" is not part of core X11, it is up to the toolkit or\n"
-" application to decide how to react to the sequence.\n"
-" The X11 names for these keysyms are \"dead_grave\",\n"
-" \"dead_acute\", etc. However some VNC viewers send the\n"
-" keysyms \"grave\", \"acute\" instead thereby disabling\n"
-" the accenting. To work around this -remap can be used.\n"
-" For example \"-remap grave-dead_grave,acute-dead_acute\"\n"
-" As a convenience, \"-remap DEAD\" applies these remaps:\n"
-"\n"
-" g grave-dead_grave\n"
-" a acute-dead_acute\n"
-" c asciicircum-dead_circumflex\n"
-" t asciitilde-dead_tilde\n"
-" m macron-dead_macron\n"
-" b breve-dead_breve\n"
-" D abovedot-dead_abovedot\n"
-" d diaeresis-dead_diaeresis\n"
-" o degree-dead_abovering\n"
-" A doubleacute-dead_doubleacute\n"
-" r caron-dead_caron\n"
-" e cedilla-dead_cedilla\n"
-"\n"
-" If you just want a subset use the first letter\n"
-" label, e.g. \"-remap DEAD=ga\" to get the first two.\n"
-" Additional remaps may also be supplied via commas,\n"
-" e.g. \"-remap DEAD=ga,Super_R-Button2\". Finally,\n"
-" \"DEAD=missing\" means to apply all of the above as\n"
-" long as the left hand member is not already in the\n"
-" X11 keymap.\n"
-"\n"
-"-norepeat Option -norepeat disables X server key auto repeat when\n"
-"-repeat VNC clients are connected and VNC keyboard input is\n"
-" not idle for more than 5 minutes. This works around a\n"
-" repeating keystrokes bug (triggered by long processing\n"
-" delays between key down and key up client events:\n"
-" either from large screen changes or high latency).\n"
-" Default: %s\n"
-"\n"
-" You can set the env. var. X11VNC_IDLE_TIMEOUT to the\n"
-" number of idle seconds you want (5min = 300secs).\n"
-"\n"
-" Note: your VNC viewer side will likely do autorepeating,\n"
-" so this is no loss unless someone is simultaneously at\n"
-" the real X display.\n"
-"\n"
-" Use \"-norepeat N\" to set how many times norepeat will\n"
-" be reset if something else (e.g. X session manager)\n"
-" undoes it. The default is 2. Use a negative value\n"
-" for unlimited resets.\n"
-"\n"
-"-nofb Ignore video framebuffer: only process keyboard and\n"
-" pointer. Intended for use with Win2VNC and x2vnc\n"
-" dual-monitor setups.\n"
-"-nobell Do not watch for XBell events. (no beeps will be heard)\n"
-" Note: XBell monitoring requires the XKEYBOARD extension.\n"
-"-nosel Do not manage exchange of X selection/cutbuffer between\n"
-" VNC viewers and the X server at all.\n"
-"-noprimary Do not poll the PRIMARY selection for changes to send\n"
-" back to clients. (PRIMARY is still set on received\n"
-" changes, however).\n"
-"-nosetprimary Do not set the PRIMARY selection for changes received\n"
-" from VNC clients.\n"
-"-noclipboard Do not poll the CLIPBOARD selection for changes to send\n"
-" back to clients. (CLIPBOARD is still set on received\n"
-" changes, however).\n"
-"-nosetclipboard Do not set the CLIPBOARD selection for changes\n"
-" received from VNC clients.\n"
-"-seldir string If direction string is \"send\", only send the selection\n"
-" to viewers, and if it is \"recv\" only receive it from\n"
-" viewers. To work around apps setting the selection\n"
-" too frequently and messing up the other end. You can\n"
-" actually supply a comma separated list of directions,\n"
-" including \"debug\" to turn on debugging output.\n"
-"\n"
-"-cursor [mode] Sets how the pointer cursor shape (little icon at the\n"
-"-nocursor mouse pointer) should be handled. The \"mode\" string\n"
-" is optional and is described below. The default\n"
-" is to show some sort of cursor shape(s). How this\n"
-" is done depends on the VNC viewer and the X server.\n"
-" Use -nocursor to disable cursor shapes completely.\n"
-"\n"
-" Some VNC viewers support the TightVNC CursorPosUpdates\n"
-" and CursorShapeUpdates extensions (cuts down on\n"
-" network traffic by not having to send the cursor image\n"
-" every time the pointer is moved), in which case these\n"
-" extensions are used (see -nocursorshape and -nocursorpos\n"
-" below to disable). For other viewers the cursor shape\n"
-" is written directly to the framebuffer every time the\n"
-" pointer is moved or changed and gets sent along with\n"
-" the other framebuffer updates. In this case, there\n"
-" will be some lag between the vnc viewer pointer and\n"
-" the remote cursor position.\n"
-"\n"
-" If the X display supports retrieving the cursor shape\n"
-" information from the X server, then the default is\n"
-" to use that mode. On Solaris this can be done with\n"
-" the SUN_OVL extension using -overlay (see also the\n"
-" -overlay_nocursor option). A similar overlay scheme\n"
-" is used on IRIX. Xorg (e.g. Linux) and recent Solaris\n"
-" Xsun servers support the XFIXES extension to retrieve\n"
-" the exact cursor shape from the X server. If XFIXES\n"
-" is present it is preferred over Overlay and is used by\n"
-" default (see -noxfixes below). This can be disabled\n"
-" with -nocursor, and also some values of the \"mode\"\n"
-" option below.\n"
-"\n"
-" Note that under XFIXES cursors with transparency (alpha\n"
-" channel) will usually not be exactly represented and one\n"
-" may find Overlay preferable. See also the -alphacut\n"
-" and -alphafrac options below as fudge factors to try\n"
-" to improve the situation for cursors with transparency\n"
-" for a given theme.\n"
-"\n"
-" The \"mode\" string can be used to fine-tune the\n"
-" displaying of cursor shapes. It can be used the\n"
-" following ways:\n"
-"\n"
-" \"-cursor arrow\" - just show the standard arrow\n"
-" nothing more or nothing less.\n"
-"\n"
-" \"-cursor none\" - same as \"-nocursor\"\n"
-"\n"
-" \"-cursor X\" - when the cursor appears to be on the\n"
-" root window, draw the familiar X shape. Some desktops\n"
-" such as GNOME cover up the root window completely,\n"
-" and so this will not work, try \"X1\", etc, to try to\n"
-" shift the tree depth. On high latency links or slow\n"
-" machines there will be a time lag between expected and\n"
-" the actual cursor shape.\n"
-"\n"
-" \"-cursor some\" - like \"X\" but use additional\n"
-" heuristics to try to guess if the window should have\n"
-" a windowmanager-like resizer cursor or a text input\n"
-" I-beam cursor. This is a complete hack, but may be\n"
-" useful in some situations because it provides a little\n"
-" more feedback about the cursor shape.\n"
-"\n"
-" \"-cursor most\" - try to show as many cursors as\n"
-" possible. Often this will only be the same as \"some\"\n"
-" unless the display has overlay visuals or XFIXES\n"
-" extensions available. On Solaris and IRIX if XFIXES\n"
-" is not available, -overlay mode will be attempted.\n"
-"\n"
-"-cursor_drag Show cursor shape changes even when the mouse is being\n"
-" dragged with a mouse button down. This is useful if you\n"
-" want to be able to see Drag-and-Drop cursor icons, etc.\n"
-"\n"
-"-arrow n Choose an alternate \"arrow\" cursor from a set of\n"
-" some common ones. n can be 1 to %d. Default is: %d\n"
-" Ignored when in XFIXES cursor-grabbing mode.\n"
-"\n"
-"-noxfixes Do not use the XFIXES extension to draw the exact cursor\n"
-" shape even if it is available.\n"
-"\n"
-" Note: To work around a crash in Xorg 1.5 and later\n"
-" some people needed to use -noxfixes. The Xorg crash\n"
-" occurred right after a Display Manager (e.g. GDM) login.\n"
-" Starting with x11vnc 0.9.9 it tries to automatically\n"
-" avoid using XFIXES until it is sure a window manager\n"
-" is running. See the -reopen option for more info and\n"
-" how to use X11VNC_AVOID_WINDOWS=never to disable it.\n"
-"\n"
-"-alphacut n When using the XFIXES extension for the cursor shape,\n"
-" cursors with transparency will not usually be displayed\n"
-" exactly (but opaque ones will). This option sets n as\n"
-" a cutoff for cursors that have transparency (\"alpha\n"
-" channel\" with values ranging from 0 to 255) Any cursor\n"
-" pixel with alpha value less than n becomes completely\n"
-" transparent. Otherwise the pixel is completely opaque.\n"
-" Default %d\n"
-"\n"
-"-alphafrac fraction With the threshold in -alphacut some cursors will become\n"
-" almost completely transparent because their alpha values\n"
-" are not high enough. For those cursors adjust the\n"
-" alpha threshold until fraction of the non-zero alpha\n"
-" channel pixels become opaque. Default %.2f\n"
-"-alpharemove By default, XFIXES cursors pixels with transparency have\n"
-" the alpha factor multiplied into the RGB color values\n"
-" (i.e. that corresponding to blending the cursor with a\n"
-" black background). Specify this option to remove the\n"
-" alpha factor. (useful for light colored semi-transparent\n"
-" cursors).\n"
-"-noalphablend In XFIXES mode do not send cursor alpha channel data\n"
-" to LibVNCServer. The default is to send it. The\n"
-" alphablend effect will only be visible in -nocursorshape\n"
-" mode or for clients with cursorshapeupdates turned\n"
-" off. (However there is a hack for 32bpp with depth 24,\n"
-" it uses the extra 8 bits to store cursor transparency\n"
-" for use with a hacked vncviewer that applies the\n"
-" transparency locally. See the FAQ for more info).\n"
-"\n"
-"-nocursorshape Do not use the TightVNC CursorShapeUpdates extension\n"
-" even if clients support it. See -cursor above.\n"
-"-cursorpos Option -cursorpos enables sending the X cursor position\n"
-"-nocursorpos back to all vnc clients that support the TightVNC\n"
-" CursorPosUpdates extension. Other clients will be able\n"
-" to see the pointer motions. Default: %s\n"
-"-xwarppointer Move the pointer with XWarpPointer(3X) instead of\n"
-"-noxwarppointer the XTEST extension. Use this as a workaround\n"
-" if the pointer motion behaves incorrectly, e.g.\n"
-" on touchscreens or other non-standard setups.\n"
-"\n"
-" It is also sometimes needed on XINERAMA displays and is\n"
-" enabled by default if XINERAMA is found to be active.\n"
-" To prevent this, use -noxwarppointer.\n"
-"\n"
-"-always_inject Even if there is no displacement (dx = dy = 0) for a\n"
-" VNC mouse event force the pointer to the indicated x,y\n"
-" position anyway. Recent (2009) gui toolkits (gnome)\n"
-" have problems with x11vnc's original mouse input\n"
-" injection method. So x11vnc's mouse input injection\n"
-" method has been modified. To regain the OLD behavior\n"
-" use this option: -always_inject. Then x11vnc will\n"
-" always force positioning the mouse to the x,y position\n"
-" even if that position has not changed since the previous\n"
-" VNC input event.\n"
-"\n"
-" The first place this problem was noticed was in gnome\n"
-" terminal: if you pressed and released mouse button 3, a\n"
-" menu was posted and then its first element 'New Terminal\n"
-" Window' was activated. This was because x11vnc injected\n"
-" the mouse position twice: once on ButtonPress and again\n"
-" on ButtonRelease. The toolkit interpreted the 2nd one\n"
-" as mouse motion even though the mouse hadn't moved.\n"
-" So now by default x11vnc tries to avoid injecting the\n"
-" 2nd one.\n"
-"\n"
-" Note that with the new default x11vnc will be oblivious\n"
-" to applications moving the pointer (warping) or the\n"
-" user at the physical display moving it. So it might,\n"
-" e.g., inject ButtonRelease at the wrong position.\n"
-" If this (or similar scenarios) causes problems in your\n"
-" environment, specify -always_inject for the old method.\n"
-"\n"
-"-buttonmap string String to remap mouse buttons. Format: IJK-LMN, this\n"
-" maps buttons I -> L, etc., e.g. -buttonmap 13-31\n"
-"\n"
-" Button presses can also be mapped to keystrokes: replace\n"
-" a button digit on the right of the dash with :<sym>:\n"
-" or :<sym1>+<sym2>: etc. for multiple keys. For example,\n"
-" if the viewing machine has a mouse-wheel (buttons 4 5)\n"
-" but the x11vnc side does not, these will do scrolls:\n"
-" -buttonmap 12345-123:Prior::Next:\n"
-" -buttonmap 12345-123:Up+Up+Up::Down+Down+Down:\n"
-"\n"
-" See <X11/keysymdef.h> header file for a list of Keysyms,\n"
-" or use the xev(1) program. Note: mapping of button\n"
-" clicks to Keysyms may not work if -modtweak or -xkb is\n"
-" needed for the Keysym.\n"
-"\n"
-" If you include a modifier like \"Shift_L\" the\n"
-" modifier's up/down state is toggled, e.g. to send\n"
-" \"The\" use :Shift_L+t+Shift_L+h+e: (the 1st one is\n"
-" shift down and the 2nd one is shift up). (note: the\n"
-" initial state of the modifier is ignored and not reset)\n"
-" To include button events use \"Button1\", ... etc.\n"
-"\n"
-" -buttonmap currently does not work on MacOSX console\n"
-" or in -rawfb mode.\n"
-"\n"
-" Workaround: use -buttonmap IJ...-LM...=n to limit the\n"
-" number of mouse buttons to n, e.g. 123-123=3. This will\n"
-" prevent x11vnc from crashing if the X server reports\n"
-" there are 5 buttons (4/5 scroll wheel), but there are\n"
-" only really 3.\n"
-"\n"
-"-nodragging Do not update the display during mouse dragging events\n"
-" (mouse button held down). Greatly improves response on\n"
-" slow setups, but you lose all visual feedback for drags,\n"
-" text selection, and some menu traversals. It overrides\n"
-" any -pointer_mode setting.\n"
-"\n"
-#ifndef NO_NCACHE
-"-ncache n Client-side caching scheme. Framebuffer memory \"n\"\n"
-" (an integer) times that of the full display is allocated\n"
-" below the actual framebuffer to cache screen contents\n"
-" for rapid retrieval. So a W x H frambuffer is expanded\n"
-" to a W x (n+1)*H one. Use 0 to disable.\n"
-"\n"
-" The \"n\" is actually optional, the default is 10.\n"
-"\n"
-" For this and the other -ncache* options below you can\n"
-" abbreviate \"-ncache\" with \"-nc\". Also, \"-nonc\"\n"
-" is the same as \"-ncache 0\"\n"
-"\n"
-" This is an experimental option, currently implemented in\n"
-" an awkward way in that in the VNC Viewer you can see the\n"
-" pixel cache contents if you scroll down, etc. So you\n"
-" will have to set things up so you can't see that region.\n"
-" If this method is successful, the changes required for\n"
-" clients to do this less awkwardly will be investigated.\n"
-"\n"
-" The SSVNC viewer does a good job at automatically hiding\n"
-" the pixel cache region. Or use SSVNC's -ycrop option\n"
-" to explicitly hide the region.\n"
-"\n"
-" Note that this mode consumes a huge amount of memory,\n"
-" both on the x11vnc server side and on the VNC Viewer\n"
-" side. If n=2 then the amount of RAM used is roughly\n"
-" tripled for both x11vnc and the VNC Viewer. As a rule\n"
-" of thumb, note that 1280x1024 at depth 24 is about 5MB\n"
-" of pixel data.\n"
-"\n"
-" For reasonable response when cycling through 4 to 6\n"
-" large (e.g. web browser) windows a value n of 6 to 12\n"
-" is recommended. (that's right: ~10X more memory...)\n"
-"\n"
-" Because of the way window backingstore and saveunders\n"
-" are implemented, n must be even. It will be incremented\n"
-" by 1 if it is not.\n"
-"\n"
-" This mode also works for native MacOS X, but may not\n"
-" be as effective as the X version. This is due to a\n"
-" number of things, one is the drop-shadow compositing\n"
-" that leaves extra areas that need to be repaired (see\n"
-" -ncache_pad). Another is the window iconification\n"
-" animations need to be avoided (see -macicontime).\n"
-" It appears the that the 'Scale' animation mode gives\n"
-" better results than the 'Genie' one. Also, window event\n"
-" detection not as accurate as the X version.\n"
-"\n"
-"-ncache_cr In -ncache mode, try to do copyrect opaque window\n"
-" moves/drags instead of wireframes (this can induce\n"
-" painting errors). The wireframe will still be used when\n"
-" moving a window whose save-unders has not yet been set\n"
-" or has been invalidated.\n"
-"\n"
-" Some VNC Viewers provide better response than others\n"
-" with this option. On Unix, realvnc viewer gives\n"
-" smoother drags than tightvnc viewer. Response may also\n"
-" be choppy if the server side machine is too slow.\n"
-"\n"
-" Sometimes on very slow modem connections, this actually\n"
-" gives an improvement because no pixel data at all\n"
-" (not even the box animation) is sent during the drag.\n"
-"\n"
-"-ncache_no_moveraise In -ncache mode, do not assume that moving a window\n"
-" will cause the window manager to raise it to the top\n"
-" of the stack. The default is to assume it does, and\n"
-" so at the beginning of any wireframe, etc, window moves\n"
-" the window will be pushed to top in the VNC viewer.\n"
-"\n"
-"-ncache_no_dtchange In -ncache mode, do not try to guess when the desktop\n"
-" (viewport) changes to another one (i.e. another\n"
-" workarea). The default is to try to guess and when\n"
-" detected try to make the transistion more smoothly.\n"
-"\n"
-"-ncache_no_rootpixmap In -ncache mode, do not try to snapshot the desktop\n"
-" background to use in guessing or reconstructing window\n"
-" save-unders.\n"
-"\n"
-"-ncache_keep_anims In -ncache mode, do not try to disable window\n"
-" manager animations and other effects (that usually\n"
-" degrade ncache performance or cause painting errors).\n"
-" The default is to try to disable them on KDE (but not\n"
-" GNOME) when VNC clients are connected.\n"
-"\n"
-" For other window managers or desktops that provide\n"
-" animations, effects, compositing, translucency,\n"
-" etc. that interfere with the -ncache method you will\n"
-" have to disable them manually.\n"
-"\n"
-"-ncache_old_wm In -ncache mode, enable some heuristics for old style\n"
-" window managers such as fvwm and twm.\n"
-"\n"
-"-ncache_pad n In -ncache mode, pad each window with n pixels for the\n"
-" caching rectangles. This can be used to try to improve\n"
-" the situation with dropshadows or other compositing\n"
-" (e.g. MacOS X window manager), although it could make\n"
-" things worse. The default is 0 on Unix and 24 on\n"
-" MacOS X.\n"
-"-debug_ncache Turn on debugging and profiling output under -ncache.\n"
-"\n"
-#endif
-"-wireframe [str] Try to detect window moves or resizes when a mouse\n"
-"-nowireframe button is held down and show a wireframe instead of\n"
-" the full opaque window. This is based completely on\n"
-" heuristics and may not always work: it depends on your\n"
-" window manager and even how you move things around.\n"
-" See -pointer_mode below for discussion of the \"bogging\n"
-" down\" problem this tries to avoid.\n"
-" Default: %s\n"
-"\n"
-" Shorter aliases: -wf [str] and -nowf\n"
-"\n"
-" The value \"str\" is optional and, of course, is\n"
-" packed with many tunable parameters for this scheme:\n"
-"\n"
-" Format: shade,linewidth,percent,T+B+L+R,mod,t1+t2+t3+t4\n"
-" Default: %s\n"
-"\n"
-" If you leave nothing between commas: \",,\" the default\n"
-" value is used. If you don't specify enough commas,\n"
-" the trailing parameters are set to their defaults.\n"
-"\n"
-" \"shade\" indicate the \"color\" for the wireframe,\n"
-" usually a greyscale: 0-255, however for 16 and 32bpp you\n"
-" can specify an rgb.txt X color (e.g. \"dodgerblue\") or\n"
-" a value > 255 is treated as RGB (e.g. red is 0xff0000).\n"
-" \"linewidth\" sets the width of the wireframe in pixels.\n"
-" \"percent\" indicates to not apply the wireframe scheme\n"
-" to windows with area less than this percent of the\n"
-" full screen.\n"
-"\n"
-" \"T+B+L+R\" indicates four integers for how close in\n"
-" pixels the pointer has to be from the Top, Bottom, Left,\n"
-" or Right edges of the window to consider wireframing.\n"
-" This is a speedup to quickly exclude a window from being\n"
-" wireframed: set them all to zero to not try the speedup\n"
-" (scrolling and selecting text will likely be slower).\n"
-"\n"
-" \"mod\" specifies if a button down event in the\n"
-" interior of the window with a modifier key (Alt, Shift,\n"
-" etc.) down should indicate a wireframe opportunity.\n"
-" It can be \"0\" or \"none\" to skip it, \"1\" or \"all\"\n"
-" to apply it to any modifier, or \"Shift\", \"Alt\",\n"
-" \"Control\", \"Meta\", \"Super\", or \"Hyper\" to only\n"
-" apply for that type of modifier key.\n"
-"\n"
-" \"t1+t2+t3+t4\" specify four floating point times in\n"
-" seconds: t1 is how long to wait for the pointer to move,\n"
-" t2 is how long to wait for the window to start moving\n"
-" or being resized (for some window managers this can be\n"
-" rather long), t3 is how long to keep a wireframe moving\n"
-" before repainting the window. t4 is the minimum time\n"
-" between sending wireframe \"animations\". If a slow\n"
-" link is detected, these values may be automatically\n"
-" changed to something better for a slow link.\n"
-"\n"
-"-nowireframelocal By default, mouse motion and button presses of a\n"
-" user sitting at the LOCAL display are monitored for\n"
-" wireframing opportunities (so that the changes will be\n"
-" sent efficiently to the VNC clients). Use this option\n"
-" to disable this behavior.\n"
-"\n"
-"-wirecopyrect mode Since the -wireframe mechanism evidently tracks moving\n"
-"-nowirecopyrect windows accurately, a speedup can be obtained by\n"
-" telling the VNC viewers to locally copy the translated\n"
-" window region. This is the VNC CopyRect encoding:\n"
-" the framebuffer update doesn't need to send the actual\n"
-" new image data.\n"
-"\n"
-" Shorter aliases: -wcr [mode] and -nowcr\n"
-"\n"
-" \"mode\" can be \"never\" (same as -nowirecopyrect)\n"
-" to never try the copyrect, \"top\" means only do it if\n"
-" the window was not covered by any other windows, and\n"
-" \"always\" means to translate the orginally unobscured\n"
-" region (this may look odd as the remaining pieces come\n"
-" in, but helps on a slow link). Default: \"%s\"\n"
-"\n"
-" Note: there can be painting errors or slow response\n"
-" when using -scale so you may want to disable CopyRect\n"
-" in this case \"-wirecopyrect never\" on the command\n"
-" line or by remote-control. Or you can also use the\n"
-" \"-scale xxx:nocr\" scale option.\n"
-"\n"
-"-debug_wireframe Turn on debugging info printout for the wireframe\n"
-" heuristics. \"-dwf\" is an alias. Specify multiple\n"
-" times for more output.\n"
-"\n"
-"-scrollcopyrect mode Like -wirecopyrect, but use heuristics to try to guess\n"
-"-noscrollcopyrect if a window has scrolled its contents (either vertically\n"
-" or horizontally). This requires the RECORD X extension\n"
-" to \"snoop\" on X applications (currently for certain\n"
-" XCopyArea and XConfigureWindow X protocol requests).\n"
-" Examples: Hitting <Return> in a terminal window when the\n"
-" cursor was at the bottom, the text scrolls up one line.\n"
-" Hitting <Down> arrow in a web browser window, the web\n"
-" page scrolls up a small amount. Or scrolling with a\n"
-" scrollbar or mouse wheel.\n"
-"\n"
-" Shorter aliases: -scr [mode] and -noscr\n"
-"\n"
-" This scheme will not always detect scrolls, but when\n"
-" it does there is a nice speedup from using the VNC\n"
-" CopyRect encoding (see -wirecopyrect). The speedup\n"
-" is both in reduced network traffic and reduced X\n"
-" framebuffer polling/copying. On the other hand, it may\n"
-" induce undesired transients (e.g. a terminal cursor\n"
-" being scrolled up when it should not be) or other\n"
-" painting errors (window tearing, bunching-up, etc).\n"
-" These are automatically repaired in a short period\n"
-" of time. If this is unacceptable disable the feature\n"
-" with -noscrollcopyrect.\n"
-"\n"
-" Screen clearing kludges: for testing at least, there\n"
-" are some \"magic key sequences\" (must be done in less\n"
-" than 1 second) to aid repairing painting errors that\n"
-" may be seen when using this mode:\n"
-"\n"
-" 3 Alt_L's in a row: resend whole screen,\n"
-" 4 Alt_L's in a row: reread and resend whole screen,\n"
-" 3 Super_L's in a row: mark whole screen for polling,\n"
-" 4 Super_L's in a row: reset RECORD context,\n"
-" 5 Super_L's in a row: try to push a black screen\n"
-"\n"
-" note: Alt_L is the Left \"Alt\" key (a single key)\n"
-" Super_L is the Left \"Super\" key (Windows flag).\n"
-" Both of these are modifier keys, and so should not\n"
-" generate characters when pressed by themselves. Also,\n"
-" your VNC viewer may have its own refresh hot-key\n"
-" or button.\n"
-"\n"
-" \"mode\" can be \"never\" (same as -noscrollcopyrect)\n"
-" to never try the copyrect, \"keys\" means to try it\n"
-" in response to keystrokes only, \"mouse\" means to\n"
-" try it in response to mouse events only, \"always\"\n"
-" means to do both. Default: \"%s\"\n"
-"\n"
-" Note: there can be painting errors or slow response\n"
-" when using -scale so you may want to disable CopyRect\n"
-" in this case \"-scrollcopyrect never\" on the command\n"
-" line or by remote-control. Or you can also use the\n"
-" \"-scale xxx:nocr\" scale option.\n"
-"\n"
-"-scr_area n Set the minimum area in pixels for a rectangle\n"
-" to be considered for the -scrollcopyrect detection\n"
-" scheme. This is to avoid wasting the effort on small\n"
-" rectangles that would be quickly updated the normal way.\n"
-" E.g. suppose an app updated the position of its skinny\n"
-" scrollbar first and then shifted the large panel\n"
-" it controlled. We want to be sure to skip the small\n"
-" scrollbar and get the large panel. Default: %d\n"
-"\n"
-"-scr_skip list Skip scroll detection for applications matching\n"
-" the comma separated list of strings in \"list\".\n"
-" Some applications implement their scrolling in\n"
-" strange ways where the XCopyArea, etc, also applies\n"
-" to invisible portions of the window: if we CopyRect\n"
-" those areas it looks awful during the scroll and\n"
-" there may be painting errors left after the scroll.\n"
-" Soffice.bin is the worst known offender.\n"
-"\n"
-" Use \"##\" to denote the start of the application class\n"
-" (e.g. \"##XTerm\") and \"++\" to denote the start\n"
-" of the application instance name (e.g. \"++xterm\").\n"
-" The string your list is matched against is of the form\n"
-" \"^^WM_NAME##Class++Instance<same-for-any-subwindows>\"\n"
-" The \"xlsclients -la\" command will provide this info.\n"
-"\n"
-" If a pattern is prefixed with \"KEY:\" it only applies\n"
-" to Keystroke generated scrolls (e.g. Up arrow). If it\n"
-" is prefixed with \"MOUSE:\" it only applies to Mouse\n"
-" induced scrolls (e.g. dragging on a scrollbar).\n"
-" Default: %s\n"
-"\n"
-"-scr_inc list Opposite of -scr_skip: this list is consulted first\n"
-" and if there is a match the window will be monitored\n"
-" via RECORD for scrolls irrespective of -scr_skip.\n"
-" Use -scr_skip '*' to skip anything that does not match\n"
-" your -scr_inc. Use -scr_inc '*' to include everything.\n"
-"\n"
-"-scr_keys list For keystroke scroll detection, only apply the RECORD\n"
-" heuristics to the comma separated list of keysyms in\n"
-" \"list\". You may find the RECORD overhead for every\n"
-" one of your keystrokes disrupts typing too much, but you\n"
-" don't want to turn it off completely with \"-scr mouse\"\n"
-" and -scr_parms does not work or is too confusing.\n"
-"\n"
-" The listed keysyms can be numeric or the keysym\n"
-" names in the <X11/keysymdef.h> header file or from the\n"
-" xev(1) program. Example: \"-scr_keys Up,Down,Return\".\n"
-" One probably wants to have application specific lists\n"
-" (e.g. for terminals, etc) but that is too icky to think\n"
-" about for now...\n"
-"\n"
-" If \"list\" begins with the \"-\" character the list\n"
-" is taken as an exclude list: all keysyms except those\n"
-" list will be considered. The special string \"builtin\"\n"
-" expands to an internal list of keysyms that are likely\n"
-" to cause scrolls. BTW, by default modifier keys,\n"
-" Shift_L, Control_R, etc, are skipped since they almost\n"
-" never induce scrolling by themselves.\n"
-"\n"
-"-scr_term list Yet another cosmetic kludge. Apply shell/terminal\n"
-" heuristics to applications matching comma separated\n"
-" list (same as for -scr_skip/-scr_inc). For example an\n"
-" annoying transient under scroll detection is if you\n"
-" hit Enter in a terminal shell with full text window,\n"
-" the solid text cursor block will be scrolled up.\n"
-" So for a short time there are two (or more) block\n"
-" cursors on the screen. There are similar scenarios,\n"
-" (e.g. an output line is duplicated).\n"
-"\n"
-" These transients are induced by the approximation of\n"
-" scroll detection (e.g. it detects the scroll, but not\n"
-" the fact that the block cursor was cleared just before\n"
-" the scroll). In nearly all cases these transient errors\n"
-" are repaired when the true X framebuffer is consulted\n"
-" by the normal polling. But they are distracting, so\n"
-" what this option provides is extra \"padding\" near the\n"
-" bottom of the terminal window: a few extra lines near\n"
-" the bottom will not be scrolled, but rather updated\n"
-" from the actual X framebuffer. This usually reduces\n"
-" the annoying artifacts. Use \"none\" to disable.\n"
-" Default: \"%s\"\n"
-"\n"
-"-scr_keyrepeat lo-hi If a key is held down (or otherwise repeats rapidly) and\n"
-" this induces a rapid sequence of scrolls (e.g. holding\n"
-" down an Arrow key) the \"scrollcopyrect\" detection\n"
-" and overhead may not be able to keep up. A time per\n"
-" single scroll estimate is performed and if that estimate\n"
-" predicts a sustainable scrollrate of keys per second\n"
-" between \"lo\" and \"hi\" then repeated keys will be\n"
-" DISCARDED to maintain the scrollrate. For example your\n"
-" key autorepeat may be 25 keys/sec, but for a large\n"
-" window or slow link only 8 scrolls per second can be\n"
-" sustained, then roughly 2 out of every 3 repeated keys\n"
-" will be discarded during this period. Default: \"%s\"\n"
-"\n"
-"-scr_parms string Set various parameters for the scrollcopyrect mode.\n"
-" The format is similar to that for -wireframe and packed\n"
-" with lots of parameters:\n"
-"\n"
-" Format: T+B+L+R,t1+t2+t3,s1+s2+s3+s4+s5\n"
-" Default: %s\n"
-"\n"
-" If you leave nothing between commas: \",,\" the default\n"
-" value is used. If you don't specify enough commas,\n"
-" the trailing parameters are set to their defaults.\n"
-"\n"
-" \"T+B+L+R\" indicates four integers for how close in\n"
-" pixels the pointer has to be from the Top, Bottom, Left,\n"
-" or Right edges of the window to consider scrollcopyrect.\n"
-" If -wireframe overlaps it takes precedence. This is a\n"
-" speedup to quickly exclude a window from being watched\n"
-" for scrollcopyrect: set them all to zero to not try\n"
-" the speedup (things like selecting text will likely\n"
-" be slower).\n"
-"\n"
-" \"t1+t2+t3\" specify three floating point times in\n"
-" seconds that apply to scrollcopyrect detection with\n"
-" *Keystroke* input: t1 is how long to wait after a key\n"
-" is pressed for the first scroll, t2 is how long to keep\n"
-" looking after a Keystroke scroll for more scrolls.\n"
-" t3 is how frequently to try to update surrounding\n"
-" scrollbars outside of the scrolling area (0.0 to\n"
-" disable)\n"
-"\n"
-" \"s1+s2+s3+s4+s5\" specify five floating point times\n"
-" in seconds that apply to scrollcopyrect detection with\n"
-" *Mouse* input: s1 is how long to wait after a mouse\n"
-" button is pressed for the first scroll, s2 is how long\n"
-" to keep waiting for additional scrolls after the first\n"
-" Mouse scroll was detected. s3 is how frequently to\n"
-" try to update surrounding scrollbars outside of the\n"
-" scrolling area (0.0 to disable). s4 is how long to\n"
-" buffer pointer motion (to try to get fewer, bigger\n"
-" mouse scrolls). s5 is the maximum time to spend just\n"
-" updating the scroll window without updating the rest\n"
-" of the screen.\n"
-"\n"
-"-fixscreen string Periodically \"repair\" the screen based on settings\n"
-" in \"string\". Hopefully you won't need this option,\n"
-" it is intended for cases when the -scrollcopyrect or\n"
-" -wirecopyrect features leave too many painting errors,\n"
-" but it can be used for any scenario. This option\n"
-" periodically performs costly operations and so\n"
-" interactive response may be reduced when it is on.\n"
-" You can use 3 Alt_L's (the Left \"Alt\" key) taps in\n"
-" a row (as described under -scrollcopyrect) instead to\n"
-" manually request a screen repaint when it is needed.\n"
-"\n"
-" \"string\" is a comma separated list of one or more of\n"
-" the following: \"V=t\", \"C=t\", \"X=t\", and \"8=t\".\n"
-" In these \"t\" stands for a time in seconds (it is\n"
-" a floating point even though one should usually use\n"
-" values > 2 to avoid wasting resources). V sets how\n"
-" frequently the entire screen should be sent to viewers\n"
-" (it is like the 3 Alt_L's). C sets how long to wait\n"
-" after a CopyRect to repaint the full screen. X sets\n"
-" how frequently to reread the full X11 framebuffer from\n"
-" the X server and push it out to connected viewers.\n"
-" Use of X should be rare, please report a bug if you\n"
-" find you need it. 8= applies only for -8to24 mode: it\n"
-" sets how often the non-default visual regions of the\n"
-" screen (e.g. 8bpp windows) are refreshed. Examples:\n"
-" -fixscreen V=10 -fixscreen C=10\n"
-"\n"
-"-debug_scroll Turn on debugging info printout for the scroll\n"
-" heuristics. \"-ds\" is an alias. Specify it multiple\n"
-" times for more output.\n"
-"\n"
-"-noxrecord Disable any use of the RECORD extension. This is\n"
-" currently used by the -scrollcopyrect scheme and to\n"
-" monitor X server grabs.\n"
-"\n"
-"-grab_buster Some of the use of the RECORD extension can leave a\n"
-"-nograb_buster tiny window for XGrabServer deadlock. This is only if\n"
-" the whole-server grabbing application expects mouse or\n"
-" keyboard input before releasing the grab. It is usually\n"
-" a window manager that does this. x11vnc takes care to\n"
-" avoid the problem, but if caught x11vnc will freeze.\n"
-" Without -grab_buster, the only solution is to go the\n"
-" physical display and give it some input to satisfy the\n"
-" grabbing app. Or manually kill and restart the window\n"
-" manager if that is feasible. With -grab_buster, x11vnc\n"
-" will fork a helper thread and if x11vnc appears to be\n"
-" stuck in a grab after a period of time (20-30 sec) then\n"
-" it will inject some user input: button clicks, Escape,\n"
-" mouse motion, etc to try to break the grab. If you\n"
-" experience a lot of grab deadlock, please report a bug.\n"
-"\n"
-"-debug_grabs Turn on debugging info printout with respect to\n"
-" XGrabServer() deadlock for -scrollcopyrect mode.\n"
-"\n"
-"-debug_sel Turn on debugging info printout with respect to\n"
-" PRIMARY, CLIPBOARD, and CUTBUFFER0 selections.\n"
-"\n"
-"-pointer_mode n Various pointer motion update schemes. \"-pm\" is\n"
-" an alias. The problem is pointer motion can cause\n"
-" rapid changes on the screen: consider the rapid\n"
-" changes when you drag a large window around opaquely.\n"
-" Neither x11vnc's screen polling and vnc compression\n"
-" routines nor the bandwidth to the vncviewers can keep\n"
-" up these rapid screen changes: everything will bog down\n"
-" when dragging or scrolling. So a scheme has to be used\n"
-" to \"eat\" much of that pointer input before re-polling\n"
-" the screen and sending out framebuffer updates. The\n"
-" mode number \"n\" can be 0 to %d and selects one of\n"
-" the schemes desribed below.\n"
-"\n"
-" Note that the -wireframe and -scrollcopyrect modes\n"
-" complement -pointer_mode by detecting (and improving)\n"
-" certain periods of \"rapid screen change\".\n"
-"\n"
-" n=0: does the same as -nodragging. (all screen polling\n"
-" is suspended if a mouse button is pressed.)\n"
-"\n"
-" n=1: was the original scheme used to about Jan 2004:\n"
-" it basically just skips -input_skip keyboard or pointer\n"
-" events before repolling the screen.\n"
-"\n"
-" n=2 is an improved scheme: by watching the current rate\n"
-" of input events it tries to detect if it should try to\n"
-" \"eat\" additional pointer events before continuing.\n"
-"\n"
-" n=3 is basically a dynamic -nodragging mode: it detects\n"
-" when the mouse motion has paused and then refreshes\n"
-" the display.\n"
-"\n"
-" n=4 attempts to measures network rates and latency,\n"
-" the video card read rate, and how many tiles have been\n"
-" changed on the screen. From this, it aggressively tries\n"
-" to push screen \"frames\" when it decides it has enough\n"
-" resources to do so. NOT FINISHED.\n"
-"\n"
-" The default n is %d. Note that modes 2, 3, 4 will skip\n"
-" -input_skip keyboard events (but it will not count\n"
-" pointer events). Also note that these modes are not\n"
-" available in -threads mode which has its own pointer\n"
-" event handling mechanism.\n"
-"\n"
-" To try out the different pointer modes to see which\n"
-" one gives the best response for your usage, it is\n"
-" convenient to use the remote control function, for\n"
-" example \"x11vnc -R pm:4\" or the tcl/tk gui (Tuning ->\n"
-" pointer_mode -> n).\n"
-"\n"
-"-input_skip n For the pointer handling when non-threaded: try to\n"
-" read n user input events before scanning display. n < 0\n"
-" means to act as though there is always user input.\n"
-" Default: %d\n"
-"\n"
-"-allinput Have x11vnc read and process all available client input\n"
-" before proceeding.\n"
-"\n"
-"-input_eagerly Similar to -allinput but use the handleEventsEagerly\n"
-" mechanism built into LibVNCServer.\n"
-"\n"
-"-speeds rd,bw,lat x11vnc tries to estimate some speed parameters that\n"
-" are used to optimize scheduling (e.g. -pointer_mode\n"
-" 4, -wireframe, -scrollcopyrect) and other things.\n"
-" Use the -speeds option to set these manually.\n"
-" The triple \"rd,bw,lat\" corresponds to video h/w\n"
-" read rate in MB/sec, network bandwidth to clients in\n"
-" KB/sec, and network latency to clients in milliseconds,\n"
-" respectively. If a value is left blank, e.g. \"-speeds\n"
-" ,100,15\", then the internal scheme is used to estimate\n"
-" the empty value(s).\n"
-"\n"
-" Typical PC video cards have read rates of 5-10 MB/sec.\n"
-" If the framebuffer is in main memory instead of video\n"
-" h/w (e.g. SunRay, shadowfb, dummy driver, Xvfb), the\n"
-" read rate may be much faster. \"x11perf -getimage500\"\n"
-" can be used to get a lower bound (remember to factor\n"
-" in the bytes per pixel). It is up to you to estimate\n"
-" the network bandwith and latency to clients. For the\n"
-" latency the ping(1) command can be used.\n"
-"\n"
-" For convenience there are some aliases provided,\n"
-" e.g. \"-speeds modem\". The aliases are: \"modem\" for\n"
-" 6,4,200; \"dsl\" for 6,100,50; and \"lan\" for 6,5000,1\n"
-"\n"
-"-wmdt string For some features, e.g. -wireframe and -scrollcopyrect,\n"
-" x11vnc has to work around issues for certain window\n"
-" managers or desktops (currently kde and xfce).\n"
-" By default it tries to guess which one, but it can\n"
-" guess incorrectly. Use this option to indicate which\n"
-" wm/dt. \"string\" can be \"gnome\", \"kde\", \"cde\",\n"
-" \"xfce\", or \"root\" (classic X wm). Anything else\n"
-" is interpreted as \"root\".\n"
-"\n"
-"-debug_pointer Print debugging output for every pointer event.\n"
-"-debug_keyboard Print debugging output for every keyboard event.\n"
-" Same as -dp and -dk, respectively. Use multiple\n"
-" times for more output.\n"
-"\n"
-"-defer time Time in ms to delay sending updates to connected clients\n"
-" (deferUpdateTime) Default: %d\n"
-"\n"
-"-wait time Time in ms to pause between screen polls. Used to cut\n"
-" down on load. Default: %d\n"
-"\n"
-"-extra_fbur n Perform extra FrameBufferUpdateRequests checks to\n"
-" try to be in better sync with the client's requests.\n"
-" What this does is perform extra polls of the client\n"
-" socket at critical times (before '-defer' and '-wait'\n"
-" calls.) The default is n=1. Set to a larger number to\n"
-" insert more checks or set to n=0 to disable. A downside\n"
-" of these extra calls is that more mouse input may be\n"
-" processed than desired.\n"
-"\n"
-"-wait_ui factor Factor by which to cut the -wait time if there\n"
-" has been recent user input (pointer or keyboard).\n"
-" Improves response, but increases the load whenever you\n"
-" are moving the mouse or typing. Default: %.2f\n"
-"-setdefer n When the -wait_ui mechanism cuts down the wait time ms,\n"
-" set the defer time to the same ms value. n=1 to enable,\n"
-" 0 to disable, and -1 to set defer to 0 (no delay).\n"
-" Similarly, 2 and -2 indicate 'urgent_update' mode should\n"
-" be used to push the updates even sooner. Default: 1\n"
-"-nowait_bog Do not detect if the screen polling is \"bogging down\"\n"
-" and sleep more. Some activities with no user input can\n"
-" slow things down a lot: consider a large terminal window\n"
-" with a long build running in it continuously streaming\n"
-" text output. By default x11vnc will try to detect this\n"
-" (3 screen polls in a row each longer than 0.25 sec with\n"
-" no user input), and sleep up to 1.5 secs to let things\n"
-" \"catch up\". Use this option to disable that detection.\n"
-"-slow_fb time Floating point time in seconds to delay all screen\n"
-" polling. For special purpose usage where a low frame\n"
-" rate is acceptable and desirable, but you want the\n"
-" user input processed at the normal rate so you cannot\n"
-" use -wait.\n"
-"-xrefresh time Floating point time in seconds to indicate how often to\n"
-" do the equivalent of xrefresh(1) to force all windows\n"
-" (in the viewable area if -id, -sid, or -clip is used)\n"
-" to repaint themselves. Use this only if applications\n"
-" misbehave by not repainting themselves properly.\n"
-" See also -noxdamage.\n"
-"-nap Monitor activity and if it is low take longer naps\n"
-"-nonap between screen polls to really cut down load when idle.\n"
-" Default: %s\n"
-"-sb time Time in seconds after NO activity (e.g. screen blank)\n"
-" to really throttle down the screen polls (i.e. sleep\n"
-" for about 1.5 secs). Use 0 to disable. Default: %d\n"
-" Set the env. var. X11VNC_SB_FACTOR to scale it.\n"
-"\n"
-"-readtimeout n Set LibVNCServer rfbMaxClientWait to n seconds. On\n"
-" slow links that take a long time to paint the first\n"
-" screen LibVNCServer may hit the timeout and drop the\n"
-" connection. Default: %d seconds.\n"
-"-ping n Send a 1x1 framebuffer update to all clients every n\n"
-" seconds (e.g. to try to keep a network connection alive)\n"
-"\n"
-"-nofbpm If the system supports the FBPM (Frame Buffer Power\n"
-"-fbpm Management) extension (i.e. some Sun systems), then\n"
-" prevent the video h/w from going into a reduced power\n"
-" state when VNC clients are connected.\n"
-"\n"
-" FBPM capable video h/w save energy when the workstation\n"
-" is idle by going into low power states (similar to DPMS\n"
-" for monitors). This interferes with x11vnc's polling\n"
-" of the framebuffer data.\n"
-"\n"
-" \"-nofbpm\" means prevent FBPM low power states whenever\n"
-" VNC clients are connected, while \"-fbpm\" means to not\n"
-" monitor the FBPM state at all. See the xset(1) manpage\n"
-" for details. -nofbpm is basically the same as running\n"
-" \"xset fbpm force on\" periodically. Default: %s\n"
-"\n"
-"-nodpms If the system supports the DPMS (Display Power Management\n"
-"-dpms Signaling) extension, then prevent the monitor from\n"
-" going into a reduced power state when VNC clients\n"
-" are connected.\n"
-"\n"
-" DPMS reduced power monitor states are a good thing\n"
-" and you normally want the power down to take place\n"
-" (usually x11vnc has no problem exporting the display in\n"
-" this state). You probably only want to use \"-nodpms\"\n"
-" to work around problems with Screen Savers kicking\n"
-" on in DPMS low power states. There is known problem\n"
-" with kdesktop_lock on KDE where the screen saver keeps\n"
-" kicking in every time user input stops for a second\n"
-" or two. Specifying \"-nodpms\" works around it.\n"
-"\n"
-" \"-nodpms\" means prevent DPMS low power states whenever\n"
-" VNC clients are connected, while \"-dpms\" means to not\n"
-" monitor the DPMS state at all. See the xset(1) manpage\n"
-" for details. -nodpms is basically the same as running\n"
-" \"xset dpms force on\" periodically. Default: %s\n"
-"\n"
-"-forcedpms If the system supports the DPMS (Display Power\n"
-" Management Signaling) extension, then try to keep the\n"
-" monitor in a powered off state. This is to prevent\n"
-" nosey people at the physical display from viewing what\n"
-" is on the screen. Be sure to lock the screen before\n"
-" disconnecting.\n"
-"\n"
-" This method is far from bullet proof, e.g. suppose\n"
-" someone attaches a non-DPMS monitor, or loads the\n"
-" machine so that there is a gap of time before x11vnc\n"
-" restores the powered off state? On many machines if\n"
-" he floods it with keyboard and mouse input he can see\n"
-" flashes of what is on the screen before the DPMS off\n"
-" state is reestablished. For this to work securely\n"
-" there would need to be support in the X server to do\n"
-" this exactly rather than approximately with DPMS.\n"
-"\n"
-"-clientdpms As -forcedpms but only when VNC clients are connected.\n"
-"\n"
-"-noserverdpms The UltraVNC ServerInput extension is supported.\n"
-" This allows the VNC viewer to click a button that will\n"
-" cause the server (x11vnc) to try to disable keyboard\n"
-" and mouse input at the physical display and put the\n"
-" monitor in dpms powered off state. Use this option to\n"
-" skip powering off the monitor.\n"
-"\n"
-"-noultraext Disable the following UltraVNC extensions: SingleWindow\n"
-" and ServerInput. The others managed by LibVNCServer\n"
-" (textchat, 1/n scaling, rfbEncodingUltra) are not.\n"
-"\n"
-"-chatwindow Place a local UltraVNC chat window on the X11 display\n"
-" that x11vnc is polling. That way the person on the VNC\n"
-" viewer-side can chat with the person at the physical\n"
-" X11 console. (e.g. helpdesk w/o telephone)\n"
-"\n"
-" For this to work the SSVNC package (version 1.0.21 or\n"
-" later) MUST BE installed on the system where x11vnc runs\n"
-" and the 'ssvnc' command must be available in $PATH.\n"
-" The ssvncviewer is used as a chat window helper.\n"
-" See http://www.karlrunge.com/x11vnc/ssvnc.html\n"
-"\n"
-" This option implies '-rfbversion 3.6' so as to trick\n"
-" UltraVNC viewers, otherwise they assume chat is not\n"
-" available. To specify a different rfbversion, place\n"
-" it after the -chatwindow option on the cmdline.\n"
-"\n"
-" See also the remote control 'chaton' and 'chatoff'\n"
-" actions. These can also be set from the tkx11vnc GUI.\n"
-"\n"
-"-noxdamage Do not use the X DAMAGE extension to detect framebuffer\n"
-" changes even if it is available. Use -xdamage if your\n"
-" default is to have it off.\n"
-"\n"
-" x11vnc's use of the DAMAGE extension: 1) significantly\n"
-" reduces the load when the screen is not changing much,\n"
-" and 2) detects changed areas (small ones by default)\n"
-" more quickly.\n"
-"\n"
-" Currently the DAMAGE extension is overly conservative\n"
-" and often reports large areas (e.g. a whole terminal\n"
-" or browser window) as damaged even though the actual\n"
-" changed region is much smaller (sometimes just a few\n"
-" pixels). So heuristics were introduced to skip large\n"
-" areas and use the damage rectangles only as \"hints\"\n"
-" for the traditional scanline polling. The following\n"
-" tuning parameters are introduced to adjust this\n"
-" behavior:\n"
-"\n"
-"-xd_area A Set the largest DAMAGE rectangle area \"A\" (in\n"
-" pixels: width * height) to trust as truly damaged:\n"
-" the rectangle will be copied from the framebuffer\n"
-" (slow) no matter what. Set to zero to trust *all*\n"
-" rectangles. Default: %d\n"
-"-xd_mem f Set how long DAMAGE rectangles should be \"remembered\",\n"
-" \"f\" is a floating point number and is in units of the\n"
-" scanline repeat cycle time (%d iterations). The default\n"
-" (%.1f) should give no painting problems. Increase it if\n"
-" there are problems or decrease it to live on the edge\n"
-" (perhaps useful on a slow machine).\n"
-"\n"
-"-sigpipe string Broken pipe (SIGPIPE) handling. \"string\" can be\n"
-" \"ignore\" or \"exit\". For \"ignore\" LibVNCServer\n"
-" will handle the abrupt loss of a client and continue,\n"
-" for \"exit\" x11vnc will cleanup and exit at the 1st\n"
-" broken connection.\n"
-"\n"
-" This option is not really needed since LibVNCServer\n"
-" is doing the correct thing now for quite some time.\n"
-" However, for convenience you can use it to ignore other\n"
-" signals, e.g. \"-sigpipe ignore:HUP,INT,TERM\" in case\n"
-" that would be useful for some sort of application.\n"
-" You can also put \"exit:..\" in the list to have x11vnc\n"
-" cleanup on the listed signals. \"-sig\" is an alias\n"
-" for this option if you don't like the 'pipe'. Example:\n"
-" -sig ignore:INT,TERM,exit:USR1\n"
-"\n"
-"-threads Whether or not to use the threaded LibVNCServer\n"
-"-nothreads algorithm [rfbRunEventLoop] if libpthread is available.\n"
-" In this mode new threads (one for input and one\n"
-" for output) are created to handle each new client.\n"
-" Default: %s.\n"
-"\n"
-" Thread stability is much improved in version 0.9.8.\n"
-"\n"
-" Multiple clients in threaded mode should be stable\n"
-" for the ZRLE encoding on all platforms. The Tight and\n"
-" Zlib encodings are currently only stable on Linux for\n"
-" multiple clients. Compile with -DTLS=__thread if your\n"
-" OS and compiler and linker support it.\n"
-"\n"
-" For resizes (randr, etc.) set this env. var. to the number\n"
-" of milliseconds to sleep: X11VNC_THREADS_NEW_FB_SLEEP\n"
-" at various places in the do_new_fb() action. This is to\n"
-" let various activities settle. Default is about 500ms.\n"
-"\n"
-" Multiple clients in threaded mode could yield better\n"
-" performance for 'class-room' broadcasting usage; also in\n"
-" -appshare broadcast mode. See also the -reflect option.\n"
-"\n"
-"-fs f If the fraction of changed tiles in a poll is greater\n"
-" than f, the whole screen is updated. Default: %.2f\n"
-"-gaps n Heuristic to fill in gaps in rows or cols of n or\n"
-" less tiles. Used to improve text paging. Default: %d\n"
-"-grow n Heuristic to grow islands of changed tiles n or wider\n"
-" by checking the tile near the boundary. Default: %d\n"
-"-fuzz n Tolerance in pixels to mark a tiles edges as changed.\n"
-" Default: %d\n"
-"-debug_tiles Print debugging output for tiles, fb updates, etc.\n"
-"\n"
-"-snapfb Instead of polling the X display framebuffer (fb)\n"
-" for changes, periodically copy all of X display fb\n"
-" into main memory and examine that copy for changes.\n"
-" (This setting also applies for non-X -rawfb modes).\n"
-" Under some circumstances this will improve interactive\n"
-" response, or at least make things look smoother, but in\n"
-" others (most!) it will make the response worse. If the\n"
-" video h/w fb is such that reading small tiles is very\n"
-" slow this mode could help. To keep the \"framerate\"\n"
-" up the screen size x bpp cannot be too large. Note that\n"
-" this mode is very wasteful of memory I/O resources\n"
-" (it makes full screen copies even if nothing changes).\n"
-" It may be of use in video capture-like applications,\n"
-" webcams, or where window tearing is a problem.\n"
-"\n"
-"-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"
-" \"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.\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"
-" WxHxB as above. See shmat(1) and ipcs(1)\n"
-"\n"
-" If you do not supply a type \"map\" is assumed if\n"
-" the file exists (see the next paragraphs for some\n"
-" exceptions to this.)\n"
-"\n"
-" If string is \"setup:cmd\", then the command \"cmd\"\n"
-" is run and the first line from it is read and used\n"
-" as \"string\". This allows initializing the device,\n"
-" determining WxHxB, etc. These are often done as root\n"
-" so take care.\n"
-"\n"
-" If the string begins with \"video\", see the VIDEO4LINUX\n"
-" 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\",\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 (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/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"
-" -rawfb map:/tmp/Xvfb_screen0@640x480x8+3232\n"
-" -rawfb file:/tmp/my.pnm@250x200x24+37\n"
-" -rawfb file:/dev/urandom@128x128x8\n"
-" -rawfb snap:/dev/video0@320x240x24 -24to32\n"
-" -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"
-"\n"
-" In general all user input is discarded by default (see\n"
-" the -pipeinput option for how to use a helper program\n"
-" to insert). Most of the X11 (screen, keyboard, mouse)\n"
-" options do not make sense and many will cause this\n"
-" mode to crash, so please think twice before setting or\n"
-" changing them in a running x11vnc.\n"
-"\n"
-" If you DO NOT want x11vnc to close the X DISPLAY in\n"
-" rawfb mode, prepend a \"+\" e.g. +file:/dev/fb0...\n"
-" Keeping the display open enables the default\n"
-" remote-control channel, which could be useful.\n"
-" Alternatively, if you specify -noviewonly, then the\n"
-" mouse and keyboard input are STILL sent to the X\n"
-" display, this usage should be very rare, i.e. doing\n"
-" something strange with /dev/fb0.\n"
-"\n"
-" 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"
-" *every* snapfb snapshot, set the environment variable:\n"
-" SNAPFB_RAWFB_RESET=1 as well.\n"
-"\n"
-" If you want x11vnc to dynamically transform a 24bpp\n"
-" rawfb to 32bpp (note that this will be slower) also\n"
-" supply the -24to32 option. This would be useful for,\n"
-" say, a video camera that delivers the pixel data as\n"
-" 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"
-" device itself. So if you do not supply \"@WxHxB...\n"
-" parameters x11vnc will try to determine them. It first\n"
-" tries the v4l API if that support has been compiled in.\n"
-" Otherwise it will run the v4l-info(1) external program\n"
-" if it is available.\n"
-"\n"
-" The simplest examples are \"-rawfb video\" and \"-rawfb\n"
-" video1\" which imply the device file /dev/video and\n"
-" /dev/video1, respectively. You can also supply the\n"
-" /dev if you like, e.g. \"-rawfb /dev/video0\"\n"
-"\n"
-" Since the video capture device framebuffer usually\n"
-" changes continuously (e.g. brightness fluctuations),\n"
-" you may want to use the -wait, -slow_fb, or -defer\n"
-" options to lower the \"framerate\" to cut down on\n"
-" network VNC traffic.\n"
-"\n"
-" A more sophisticated video device scheme allows\n"
-" initializing the device's settings using:\n"
-"\n"
-" -rawfb video:<settings>\n"
-"\n"
-" The prefix could also be, as above, e.g. \"video1:\" to\n"
-" specify the device file. The v4l API must be available\n"
-" for this to work. Otherwise, you will need to try\n"
-" to initialize the device with an external program,\n"
-" e.g. xawtv, spcaview, and hope they persist when x11vnc\n"
-" re-opens the device.\n"
-"\n"
-" <settings> is a comma separated list of key=value pairs.\n"
-" The device's brightness, color, contrast, and hue can\n"
-" be set to percentages, e.g. br=80,co=50,cn=44,hu=60.\n"
-"\n"
-" The device filename can be set too if needed (if it\n"
-" does not start with \"video\"), e.g. fn=/dev/qcam.\n"
-"\n"
-" The width, height and bpp of the framebuffer can be\n"
-" set via, e.g., w=160,h=120,bpp=16.\n"
-"\n"
-" Related to the bpp above, the pixel format can be set\n"
-" via the fmt=XXX, where XXX can be one of: GREY, HI240,\n"
-" RGB555, RGB565, RGB24, and RGB32 (with bpp 8, 8, 16, 16,\n"
-" 24, and 32 respectively). See http://www.linuxtv.org\n"
-" for more info (V4L api).\n"
-"\n"
-" For TV/rf tuner cards one can set the tuning mode\n"
-" via tun=XXX where XXX can be one of PAL, NTSC, SECAM,\n"
-" or AUTO.\n"
-"\n"
-" One can switch the input channel by the inp=XXX setting,\n"
-" where XXX is the name of the input channel (Television,\n"
-" Composite1, S-Video, etc). Use the name that is in the\n"
-" information about the device that is printed at startup.\n"
-"\n"
-" For input channels with tuners (e.g. Television) one\n"
-" can change which station is selected by the sta=XXX\n"
-" setting. XXX is the station number. Currently only\n"
-" the ntsc-cable-us (US cable) channels are built into\n"
-" x11vnc. See the -freqtab option below to supply one\n"
-" from xawtv. If XXX is greater than 500, then it is\n"
-" interpreted as a raw frequency in KHz.\n"
-"\n"
-" Example:\n"
-"\n"
-" -rawfb video:br=80,w=320,h=240,fmt=RGB32,tun=NTSC,sta=47\n"
-"\n"
-" one might need to add inp=Television too for the input\n"
-" channel to be TV if the card doesn't come up by default\n"
-" in that one.\n"
-"\n"
-" Note that not all video capture devices will support\n"
-" all of the above settings.\n"
-"\n"
-" See the -pipeinput VID option below for a way to control\n"
-" the settings through the VNC Viewer via keystrokes.\n"
-" As a shortcut, if the string begins \"Video..\" instead\n"
-" of \"video..\" then -pipeinput VID is implied.\n"
-"\n"
-" As above, if you specify a \"@WxHxB...\" after the\n"
-" <settings> string they are used verbatim: the device\n"
-" is not queried for the current values. Otherwise the\n"
-" device will be queried.\n"
-"\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 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, 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\n"
-" or later and the \"uinput\" module appears to be\n"
-" present (modprobe uinput), then the uinput method\n"
-" 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. It also provides more accurate\n"
-" keystroke insertion. 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 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"
-" framebuffer device, e.g. /dev/fb1. As a shortcut the\n"
-" \"/dev/\" can be dropped. If the name is something\n"
-" nonstandard, use \"console:/dev/foofb\"\n"
-"\n"
-" If you do not want x11vnc to guess the framebuffer's\n"
-" WxHxB and masks automatically (sometimes the kernel\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"
-" -rawfb /dev/fb0 (same)\n"
-" -rawfb console3 (force /dev/tty3)\n"
-" -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"
-" VNC server \"host\" is connected to (i.e. x11vnc acts as\n"
-" a VNC client itself) and that framebuffer is exported.\n"
-"\n"
-" This mode is really only of use if you are trying\n"
-" to improve performance in the case of many (e.g. >\n"
-" 10) simultaneous VNC viewers, and you try a divide\n"
-" and conquer scheme to reduce bandwidth and improve\n"
-" responsiveness. (However, another user found this mode\n"
-" useful to export a demo display through a slow link:\n"
-" then multiple demo viewers connected to the reflecting\n"
-" x11vnc on the fast side of the link, and so avoided\n"
-" all of the demo viewers going through the slow link.)\n"
-"\n"
-" For example, if there will be 64 simultaneous VNC\n"
-" viewers this can lead to a lot of redundant VNC traffic\n"
-" to and from the server host:N, extra CPU usage,\n"
-" and all viewers response can be reduced by having\n"
-" to wait for writes to the slowest client to finish.\n"
-" However, if you set up 8 reflectors/repeaters started\n"
-" with option -rawfb vnc:host:N, then there are only\n"
-" 8 connections to host:N. Each repeater then handles\n"
-" 8 vnc viewer connections thereby spreading the load\n"
-" around. In classroom broadcast usage, try to put the\n"
-" repeaters on different switches. This mode is the same\n"
-" as -reflect host:N. Replace \"host:N\" by \"listen\"\n"
-" or \"listen:port\" for a reverse connection.\n"
-"\n"
-" Overall performance will not be as good as a single\n"
-" direct connection because, among other things,\n"
-" there is an additional level of framebuffer polling\n"
-" and pointer motion can still induce many changes per\n"
-" second that must be propagated. Tip: if the remote VNC\n"
-" is x11vnc doing wireframing, or an X display that does\n"
-" wireframing that gives much better response than opaque\n"
-" window dragging. Consider the -nodragging option if\n"
-" the problem is severe.\n"
-"\n"
-" The env. var. X11VNC_REFLECT_PASSWORD can be set to\n"
-" the password needed to log into the vnc host server, or\n"
-" to \"file:path_to_file\" to indicate a file containing\n"
-" the password as its first line.\n"
-"\n"
-" To set the pixel format that x11vnc requests as a VNC\n"
-" CLIENT set the env. vars: X11VNC_REFLECT_bitsPerSample\n"
-" X11VNC_REFLECT_samplesPerPixel, and\n"
-" X11VNC_REFLECT_bytesPerPixel; the defaults are 8, 3, 4.\n"
-" 2, 3, 1 would give a low color mode. See the function\n"
-" rfbGetClient() in libvncclient for more info.\n"
-"\n"
-" The VNC HOST mode implies -shared. Use -noshared as\n"
-" a subsequent cmdline option to disable sharing.\n"
-"\n"
-"-freqtab file For use with \"-rawfb video\" for TV tuner devices to\n"
-" specify station frequencies. Instead of using the built\n"
-" in ntsc-cable-us mapping of station number to frequency,\n"
-" use the data in file. For stations that are not\n"
-" numeric, e.g. SE20, they are placed above the highest\n"
-" numbered station in the order they are found. Example:\n"
-" \"-freqtab /usr/X11R6/share/xawtv/europe-west.list\"\n"
-" You can make your own freqtab by copying the xawtv\n"
-" format.\n"
-"\n"
-"-pipeinput cmd This option lets you supply an external command in\n"
-" \"cmd\" that x11vnc will pipe all of the user input\n"
-" events to in a simple format. In -pipeinput mode by\n"
-" default x11vnc will not process any of the user input\n"
-" events. If you prefix \"cmd\" with \"tee:\" it will\n"
-" both send them to the pipe command and process them.\n"
-" For a description of the format run \"-pipeinput\n"
-" tee:/bin/cat\". Another prefix is \"reopen\" which\n"
-" means to reopen pipe if it exits. Separate multiple\n"
-" prefixes with commas.\n"
-"\n"
-" In combination with -rawfb one might be able to\n"
-" do amusing things (e.g. control non-X devices).\n"
-" To facilitate this, if -rawfb is in effect then the\n"
-" value is stored in X11VNC_RAWFB_STR for the pipe command\n"
-" to use if it wants. Do 'env | grep X11VNC' for more.\n"
-"\n"
-" Built-in pipeinput modes (no external program required):\n"
-"\n"
-" If cmd is \"VID\" and you are using the -rawfb for a\n"
-" video capture device, then an internal list of keyboard\n"
-" mappings is used to set parameters of the video.\n"
-" The mappings are:\n"
-"\n"
-" \"B\" and \"b\" adjust the brightness up and down.\n"
-" \"H\" and \"h\" adjust the hue.\n"
-" \"C\" and \"c\" adjust the colour.\n"
-" \"N\" and \"n\" adjust the contrast.\n"
-" \"S\" and \"s\" adjust the size of the capture screen.\n"
-" \"I\" and \"i\" cycle through input channels.\n"
-" Up and Down arrows adjust the station (if a tuner)\n"
-" F1, F2, ..., F6 will switch the video capture pixel\n"
-" format to HI240, RGB565, RGB24, RGB32, RGB555, and\n"
-" GREY respectively. See -rawfb video for details.\n"
-"\n"
-" If cmd is \"CONSOLE\" or \"CONSOLEn\" where n\n"
-" is a Linux console number, then the linux console\n"
-" keystroke insertion to /dev/ttyN (see -rawfb console)\n"
-" is performed.\n"
-"\n"
-" If cmd begins with \"UINPUT\" then the Linux uinput\n"
-" module is used to insert both keystroke and mouse events\n"
-" to the Linux console (see -rawfb above). This usually\n"
-" is the /dev/input/uinput device file (you may need to\n"
-" create it with \"mknod /dev/input/uinput c 10 223\"\n"
-" and insert the module with \"modprobe uinput\".\n"
-"\n"
-" The UINPUT mode currently only does US keyboards (a\n"
-" scan code option may be added), and not all keysyms\n"
-" are supported. But it is probably more accurate than\n"
-" the \"CONSOLE\" method.\n"
-"\n"
-" You may want to use the options -cursor none and\n"
-" -nodragging in this mode.\n"
-"\n"
-" Additional tuning options may be supplied via:\n"
-" UINPUT:opt1,opt2,... (a comma separated list). If an\n"
-" option begins with \"/\" it is taken as the uinput\n"
-" device file.\n"
-" \n"
-" Which uinput is injected can be controlled by an option\n"
-" string made of the characters \"K\", \"M\", and \"B\"\n"
-" (see the -input option), e.g. \"KM\" allows keystroke\n"
-" and motion but not button clicks.\n"
-"\n"
-" A UINPUT option of the form: accel=f, or accel=fx+fy\n"
-" sets the mouse motion \"acceleration\". This is used\n"
-" to correct raw mouse relative motion into how much the\n"
-" application cursor moves (x11vnc has no control over,\n"
-" or knowledge of how the windowing application interprets\n"
-" the raw mouse motions). Typically the acceleration\n"
-" for an X display is 2 (see xset \"m\" option). \"f\"\n"
-" is a floating point number, e.g. 3.0. Use \"fx+fy\"\n"
-" if you need to supply different corrections for x and y.\n"
-"\n"
-" Note: the default acceleration is 2.0 since it seems\n"
-" both X and qt-embedded often (but not always) use\n"
-" this value.\n"
-"\n"
-" Even with a correct accel setting the mouse position\n"
-" will get out of sync (probably due to a mouse\n"
-" \"threshold\" setting where the acceleration doe not\n"
-" apply, set xset(1)). The option reset=N sets the\n"
-" number of ms (default 150) after which the cursor is\n"
-" attempted to be reset (by forcing the mouse to (0,\n"
-" 0) via small increments and then back out to (x, y)\n"
-" in 1 jump), This correction seems to be needed but can\n"
-" cause jerkiness or unexpected behavior with menus, etc.\n"
-" Use reset=0 to disable.\n"
-"\n"
-" If you set the env. var X11VNC_UINPUT_THRESHOLDS then\n"
-" the thresh=n mode will be enabled. It is currently\n"
-" not working well. If |dx| <= thresh and |dy| < thresh\n"
-" no acceleration is applied. Use \"thresh=+n\" |dx| +\n"
-" |dy| < thresh to be used instead (X11?)\n"
-"\n"
-" Example:\n"
-" -pipeinput UINPUT:accel=4.0 -cursor none\n"
-"\n"
-" If the uinput device has an absolute pointer (as opposed\n"
-" to a normal mouse that is a relative pointer) you can\n"
-" specify the option \"abs\". Note that a touchpad\n"
-" on a laptop is an absolute device to some degree.\n"
-" This (usually) avoids all the problems with mouse\n"
-" acceleration. If x11vnc has trouble deducing the\n"
-" size of the device, use \"abs=WxH\". Furthermore,\n"
-" if the device is a touchscreen (assumed to have an\n"
-" absolute pointer) use \"touch\" or \"touch=WxH\".\n"
-" For touchscreens, when a mouse button is pressed,\n"
-" a pressure increase is injected, and when the button\n"
-" is released a pressure of zero is injected.\n"
-"\n"
-" If touch has been set, use \"touch_always=1\" to\n"
-" indicate whenever the mouse moves with no button\n"
-" pressed, a touch event of zero pressure should be\n"
-" sent anyway. Also use \"btn_touch=1\" to indicate a\n"
-" BTN_TOUCH keystroke press or release should be sent\n"
-" instead of a pressure change. Set \"dragskip=n\" to\n"
-" skip n dragged mouse touches (with pressure applied)\n"
-" before injecting one. To indicate the pressure that\n"
-" should be sent when there is a button click for a\n"
-" touchscreen device, specify pressure=n, e.g. n=5. The\n"
-" default is n=1.\n"
-"\n"
-" If a touch screen is being used (\"touch\" above)\n"
-" and it is having its input processed by tslib, you can\n"
-" specify the tslib calibration file via tslib_cal=<file>.\n"
-" For example, tslib_cal=/etc/pointercal. To get accurate\n"
-" or even usable positioning this is required when tslib\n"
-" is in use.\n"
-"\n"
-" The Linux uinput mechanism can be bypassed and one can\n"
-" write input events DIRECTLY to the devices instead.\n"
-" To do this, specify one or more of the following\n"
-" for the input classes: direct_rel=<device>\n"
-" direct_abs=<device> direct_btn=<device> or\n"
-" direct_key=<device>. The <device> file is usually\n"
-" something like /dev/input/event1 but you can specify\n"
-" any device file or pipe. You must specify each one\n"
-" of the above classes even if they correspond to the\n"
-" same device file (rel/abs and btn are often the same.)\n"
-" Look at the file /proc/bus/input/devices to get an idea\n"
-" what is available and the device filenames. Note:\n"
-" The /dev/input/mouse* devices do not seem to work,\n"
-" use the corresponding /dev/input/event* file instead.\n"
-" Any input class not directly specified as above will be\n"
-" handled via the uinput mechanism. To disable creating a\n"
-" uinput device (and thereby discarding unhandled input),\n"
-" specify \"nouinput\".\n"
-"\n"
-" Examples:\n"
-"\n"
-" -pipeinput UINPUT:direct_abs=/dev/input/event1\n"
-"\n"
-" this was used on a qtmoko Neo freerunner (armel):\n"
-"\n"
-" -pipeinput UINPUT:touch,tslib_cal=/etc/pointercal,\n"
-" direct_abs=/dev/input/event1,nouinput,dragskip=4\n"
-"\n"
-" (where the long line has been split into two.)\n"
-"\n"
-" You can set the env. var X11VNC_UINPUT_DEBUG=1 or higher\n"
-" to get debugging output for UINPUT mode.\n"
-"\n"
-"-macnodim For the native MacOSX server, disable dimming. \n"
-"-macnosleep For the native MacOSX server, disable display sleep.\n"
-"-macnosaver For the native MacOSX server, disable screensaver.\n"
-"-macnowait For the native MacOSX server, do not wait for the\n"
-" user to switch back to his display.\n"
-"-macwheel n For the native MacOSX server, set the mouse wheel\n"
-" speed to n (default 5).\n"
-"-macnoswap For the native MacOSX server, do not swap mouse\n"
-" buttons 2 and 3.\n"
-"-macnoresize For the native MacOSX server, do not resize or reset\n"
-" the framebuffer even if it is detected that the screen\n"
-" resolution or depth has changed.\n"
-"-maciconanim n For the native MacOSX server, set n to the number\n"
-" of milliseconds that the window iconify/deiconify\n"
-" animation takes. In -ncache mode this value will be\n"
-" used to skip the animation if possible. (default 400)\n"
-"-macmenu For the native MacOSX server, in -ncache client-side\n"
-" caching mode, try to cache pull down menus (not perfect\n"
-" because they have animated fades, etc.)\n"
-"-macuskbd For the native MacOSX server, use the original\n"
-" keystroke insertion code based on a US keyboard.\n"
-"-macnoopengl For the native MacOSX server, do not use OpenGL for\n"
-" screen capture, but rather use the original, deprecated\n"
-" raw memory access method: addr = CGDisplayBaseAddress().\n"
-"-macnorawfb For the native MacOSX server, disable the raw memory\n"
-" address screen capture method.\n"
-"\n"
-" MACOSX NOTE: There are some deprecated MacOSX interfaces\n"
-" to inject keyboard and mouse events and the raw memory\n"
-" access method is deprecated as well (however, OpenGL\n"
-" will be preferred if available because it is faster.)\n"
-" One can force not using any deprecated interfaces at\n"
-" compile time by setting -DX11VNC_MACOSX_NO_DEPRECATED=1\n"
-" in CPPFLAGS. Or to turn them off one by one:\n"
-" -DX11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS=1,\n"
-" -DX11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS=1 or\n"
-" -DX11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER=1\n"
-" At run time, for testing and workarounds, one can\n"
-" disable them by using:\n"
-" -env X11VNC_MACOSX_NO_DEPRECATED=1\n"
-" -env X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS=1\n"
-" -env X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS=1 or\n"
-" -env X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER=1\n"
-" Note: When doing either of these for the mouse input\n"
-" not everything works currently, e.g. double clicks and\n"
-" wireframing. Also, screen resolution and pixel depth\n"
-" changes will not be automatically detected unless the\n"
-" deprecated framebuffer interfaces are allowed.\n"
-"\n"
-" Conversely, if you are compiling on an\n"
-" older machine that does not have some of\n"
-" the newer interfaces, you may need to specify\n"
-" -DX11VNC_MACOSX_NO_CGEVENTCREATESCROLLWHEELEVENT\n"
-" -DX11VNC_MACOSX_NO_CGEVENTCREATEMOUSEEVENT or\n"
-" -DX11VNC_MACOSX_NO_CGEVENTCREATEKEYBOARDEVENT. Use\n"
-" -DX11VNC_MACOSX_USE_GETMAINDEVICE to regain the very\n"
-" old QuickDraw GetMainDevice() interface (rare...)\n"
-"\n"
-"-gui [gui-opts] Start up a simple tcl/tk gui based on the remote\n"
-" control options -remote/-query described below.\n"
-" Requires the \"wish\" program to be installed on the\n"
-" machine. \"gui-opts\" is not required: the default\n"
-" is to start up both the full gui and x11vnc with the\n"
-" gui showing up on the X display in the environment\n"
-" variable DISPLAY.\n"
-"\n"
-" \"gui-opts\" can be a comma separated list of items.\n"
-" Currently there are these types of items: 1) a gui\n"
-" mode, a 2) gui \"simplicity\", 3) the X display the\n"
-" gui should display on, 4) a \"tray\" or \"icon\" mode,\n"
-" and 5) a gui geometry.\n"
-"\n"
-" 1) The gui mode can be \"start\", \"conn\", or \"wait\"\n"
-" \"start\" is the default mode above and is not required.\n"
-" \"conn\" means do not automatically start up x11vnc,\n"
-" but instead just try to connect to an existing x11vnc\n"
-" process. \"wait\" means just start the gui and nothing\n"
-" else (you will later instruct the gui to start x11vnc\n"
-" or connect to an existing one.)\n"
-"\n"
-" 2) The gui simplicity is off by default (a power-user\n"
-" gui with all options is presented) To start with\n"
-" something less daunting supply the string \"simple\"\n"
-" (\"ez\" is an alias for this). Once the gui is\n"
-" started you can toggle between the two with \"Misc ->\n"
-" simple_gui\".\n"
-"\n"
-" 3) Note the possible confusion regarding the potentially\n"
-" two different X displays: x11vnc polls one, but you\n"
-" may want the gui to appear on another. For example, if\n"
-" you ssh in and x11vnc is not running yet you may want\n"
-" the gui to come back to you via your ssh redirected X\n"
-" display (e.g. localhost:10).\n"
-"\n"
-" If you do not specify a gui X display in \"gui-opts\"\n"
-" then the DISPLAY environment variable and -display\n"
-" option are tried (in that order). Regarding the x11vnc\n"
-" X display the gui will try to communication with, it\n"
-" first tries -display and then DISPLAY. For example,\n"
-" \"x11vnc -display :0 -gui otherhost:0\", will remote\n"
-" control an x11vnc polling :0 and display the gui on\n"
-" otherhost:0 The \"tray/icon\" mode below reverses this\n"
-" preference, preferring to display on the x11vnc display.\n"
-"\n"
-" 4) When \"tray\" or \"icon\" is specified, the gui\n"
-" presents itself as a small icon with behavior typical\n"
-" of a \"system tray\" or \"dock applet\". The color\n"
-" of the icon indicates status (connected clients) and\n"
-" there is also a balloon status. Clicking on the icon\n"
-" gives a menu from which properties, etc, can be set and\n"
-" the full gui is available under \"Advanced\". To be\n"
-" fully functional, the gui mode should be \"start\"\n"
-" (the default).\n"
-"\n"
-" Note that tray or icon mode will imply the -forever\n"
-" x11vnc option (if the x11vnc server is started along\n"
-" with the gui) unless -connect or -connect_or_exit has\n"
-" been specified. So x11vnc (and the tray/icon gui)\n"
-" will wait for more connections after the first client\n"
-" disconnects. If you want only one viewer connection\n"
-" include the -once option.\n"
-"\n"
-" For \"icon\" the gui just a small standalone window.\n"
-" For \"tray\" it will attempt to embed itself in the\n"
-" \"system tray\" if possible. If \"=setpass\" is appended then\n"
-" at startup the X11 user will be prompted to set the\n"
-" VNC session password. If =<hexnumber> is appended\n"
-" that icon will attempt to embed itself in the window\n"
-" given by hexnumber. Use =noadvanced to disable the\n"
-" full gui. (To supply more than one, use \"+\" sign).\n"
-" E.g. -gui tray=setpass and -gui icon=0x3600028\n"
-"\n"
-" Other modes: \"full\", the default and need not be\n"
-" specified. \"-gui none\", do not show a gui, useful\n"
-" to override a ~/.x11vncrc setting, etc.\n"
-"\n"
-" 5) When \"geom=+X+Y\" is specified, that geometry\n"
-" is passed to the gui toplevel. This is the icon in\n"
-" icon/tray mode, or the full gui otherwise. You can\n"
-" also specify width and height, i.e. WxH+X+Y, but it\n"
-" is not recommended. In \"tray\" mode the geometry is\n"
-" ignored unless the system tray manager does not seem\n"
-" to be running. One could imagine using something like\n"
-" \"-gui tray,geom=+4000+4000\" with a display manager\n"
-" to keep the gui invisible until someone logs in...\n"
-"\n"
-" More icon tricks, \"icon=minimal\" gives an icon just\n"
-" with the VNC display number. You can also set the font\n"
-" with \"iconfont=...\". The following could be useful:\n"
-" \"-gui icon=minimal,iconfont=5x8,geom=24x10+0-0\"\n"
-"\n"
-" General examples of the -gui option: \"x11vnc -gui\",\n"
-" \"x11vnc -gui ez\" \"x11vnc -gui localhost:10\",\n"
-" \"x11vnc -gui conn,host:0\", \"x11vnc -gui tray,ez\"\n"
-" \"x11vnc -gui tray=setpass\"\n"
-"\n"
-" If you do not intend to start x11vnc from the gui\n"
-" (i.e. just remote control an existing one), then the\n"
-" gui process can run on a different machine from the\n"
-" x11vnc server as long as X permissions, etc. permit\n"
-" communication between the two.\n"
-"\n"
-" FONTS: On some systems the tk fonts can be too small,\n"
-" jagged, or otherwise unreadable. There are 4 env vars\n"
-" you can set to be the tk font you prefer:\n"
-"\n"
-" X11VNC_FONT_BOLD main font for menus and buttons.\n"
-" X11VNC_FONT_FIXED font for fixed width text.\n"
-"\n"
-" X11VNC_FONT_BOLD_SMALL tray icon font.\n"
-" X11VNC_FONT_REG_SMALL tray icon menu font.\n"
-"\n"
-" The last two only apply for the tray icon mode.\n"
-"\n"
-" Here are some examples:\n"
-"\n"
-" -env X11VNC_FONT_BOLD='Helvetica -16 bold'\n"
-" -env X11VNC_FONT_FIXED='Courier -14'\n"
-" -env X11VNC_FONT_REG_SMALL='Helvetica -12'\n"
-"\n"
-" You can put the lines like the above (without the\n"
-" quotes) in your ~/.x11vncrc file to avoid having to\n"
-" specify them on the x11vnc command line.\n"
-"\n"
-"-remote command Remotely control some aspects of an already running\n"
-" x11vnc server. \"-R\" and \"-r\" are aliases for\n"
-" \"-remote\". After the remote control command is\n"
-" sent to the running server the 'x11vnc -remote ...'\n"
-" x11vnc command exits. You can often use the -query\n"
-" command (see below) to see if the x11vnc server\n"
-" processed your -remote command.\n"
-"\n"
-" The default communication channel is that of X\n"
-" properties (specifically X11VNC_REMOTE), and so this\n"
-" command must be run with correct settings for DISPLAY\n"
-" and possibly XAUTHORITY to connect to the X server\n"
-" and set the property. Alternatively, use the -display\n"
-" and -auth options to set them to the correct values.\n"
-" The running server cannot use the -novncconnect option\n"
-" because that disables the communication channel.\n"
-" See below for alternate channels.\n"
-"\n"
-" For example: 'x11vnc -remote stop' (which is the same as\n"
-" 'x11vnc -R stop') will close down the x11vnc server.\n"
-" 'x11vnc -R shared' will enable shared connections, and\n"
-" 'x11vnc -R scale:3/4' will rescale the desktop.\n"
-"\n"
-" To use a different name for the X11 property (e.g. to\n"
-" have separate communication channels for multiple\n"
-" x11vnc's on the same display) set the X11VNC_REMOTE\n"
-" environment variable to the string you want, for\n"
-" example: -env X11VNC_REMOTE=X11VNC_REMOTE_12345\n"
-" Both sides of the channel must use the same unique name.\n"
-"\n"
-" To run a bunch of commands in a sequence use something\n"
-" like: x11vnc -R 'script:firstcmd;secondcmd;...'\n"
-"\n"
-" Use x11vnc -R script:file=/path/to/file to read commands\n"
-" from a file (can be multi-line and use the comment '#'\n"
-" character in the normal way. The ';' separator must\n"
-" still be used to separate each command.)\n"
-"\n"
-" To not try to contact another x11vnc process and instead\n"
-" just run the command (or query) directly, prefix the\n"
-" command with the string \"DIRECT:\"\n"
-"\n"
-" The following -remote/-R commands are supported:\n"
-"\n"
-" stop terminate the server, same as \"quit\"\n"
-" \"exit\" or \"shutdown\".\n"
-" ping see if the x11vnc server responds.\n"
-" return is: ans=ping:<display>\n"
-" ping:mystring as above, but use your own unique string.\n"
-" return is: ans=ping:mystring:<xdisplay>\n"
-" blacken try to push a black fb update to all\n"
-" clients (due to timings a client\n"
-" could miss it). Same as \"zero\", also\n"
-" \"zero:x1,y1,x2,y2\" for a rectangle.\n"
-" refresh send the entire fb to all clients.\n"
-" reset recreate the fb, polling memory, etc.\n"
-/* ext. cmd. */
-" id:windowid set -id window to \"windowid\". empty\n"
-" or \"root\" to go back to root window\n"
-" sid:windowid set -sid window to \"windowid\"\n"
-" id_cmd:cmd cmds: raise, lower, map, unmap, iconify,\n"
-" move:dXdY, resize:dWdH, geom:WxH+X+Y. dX\n"
-" dY, dW, and dH must have a leading \"+\"\n"
-" or \"-\" e.g.: move:-30+10 resize:+20+35\n"
-" also: wm_delete, wm_name:string and\n"
-" icon_name:string. Also id_cmd:win=N:cmd\n"
-" waitmapped wait until subwin is mapped.\n"
-" nowaitmapped do not wait until subwin is mapped.\n"
-" clip:WxH+X+Y set -clip mode to \"WxH+X+Y\"\n"
-" flashcmap enable -flashcmap mode.\n"
-" noflashcmap disable -flashcmap mode.\n"
-" shiftcmap:n set -shiftcmap to n.\n"
-" notruecolor enable -notruecolor mode.\n"
-" truecolor disable -notruecolor mode.\n"
-" overlay enable -overlay mode (if applicable).\n"
-" nooverlay disable -overlay mode.\n"
-" overlay_cursor in -overlay mode, enable cursor drawing.\n"
-" overlay_nocursor disable cursor drawing. same as\n"
-" nooverlay_cursor.\n"
-" 8to24 enable -8to24 mode (if applicable).\n"
-" no8to24 disable -8to24 mode.\n"
-" 8to24_opts:str set the -8to24 opts to \"str\".\n"
-" 24to32 enable -24to32 mode (if applicable).\n"
-" no24to32 disable -24to32 mode.\n"
-" visual:vis set -visual to \"vis\"\n"
-" scale:frac set -scale to \"frac\"\n"
-" scale_cursor:f set -scale_cursor to \"f\"\n"
-" viewonly enable -viewonly mode.\n"
-/* access view,share,forever */
-" noviewonly disable -viewonly mode.\n"
-" shared enable -shared mode.\n"
-" noshared disable -shared mode.\n"
-" forever enable -forever mode.\n"
-" noforever disable -forever mode.\n"
-" timeout:n reset -timeout to n, if there are\n"
-" currently no clients, exit unless one\n"
-" connects in the next n secs.\n"
-" tightfilexfer enable filetransfer for NEW clients.\n"
-" notightfilexfer disable filetransfer for NEW clients.\n"
-" ultrafilexfer enable filetransfer for clients.\n"
-" noultrafilexfer disable filetransfer for clients.\n"
-" rfbversion:n.m set -rfbversion for new clients.\n"
-/* access */
-" http enable http client connections.\n"
-" nohttp disable http client connections.\n"
-" deny deny any new connections, same as \"lock\"\n"
-" nodeny allow new connections, same as \"unlock\"\n"
-" avahi enable avahi service advertising.\n"
-" noavahi disable avahi service advertising.\n"
-" mdns enable avahi service advertising.\n"
-" nomdns disable avahi service advertising.\n"
-" zeroconf enable avahi service advertising.\n"
-" nozeroconf disable avahi service advertising.\n"
-/* access, filename */
-" connect:host do reverse connection to host, \"host\"\n"
-" may be a comma separated list of hosts\n"
-" or host:ports. See -connect. Passwords\n"
-" required as with fwd connections.\n"
-" See X11VNC_REVERSE_CONNECTION_NO_AUTH=1\n"
-" disconnect:host disconnect any clients from \"host\"\n"
-" same as \"close:host\". Use host\n"
-" \"all\" to close all current clients.\n"
-" If you know the client internal hex ID,\n"
-" e.g. 0x3 (returned by \"-query clients\"\n"
-" and RFB_CLIENT_ID) you can use that too.\n"
-" proxy:host:port set reverse connection proxy (empty to\n"
-" disable).\n"
-/* access */
-" allowonce:host For the next connection only, allow\n"
-" connection from \"host\". In -ssl mode\n"
-" two connections are allowed (i.e. Fetch\n"
-" Cert) unless X11VNC_NO_SSL_ALLOW_TWICE=1\n"
-/* access */
-" allow:hostlist set -allow list to (comma separated)\n"
-" \"hostlist\". See -allow and -localhost.\n"
-" Do not use with -allow /path/to/file\n"
-" Use \"+host\" to add a single host, and\n"
-" use \"-host\" to delete a single host\n"
-" localhost enable -localhost mode\n"
-" nolocalhost disable -localhost mode\n"
-" listen:str set -listen to str, empty to disable.\n"
-" noipv6 enable -noipv6 mode.\n"
-" ipv6 disable -noipv6 mode.\n"
-" noipv4 enable -noipv4 mode.\n"
-" ipv4 disable -noipv4 mode.\n"
-" 6 enable -6 IPv6 listening mode.\n"
-" no6 disable -6 IPv6 listening mode.\n"
-" lookup disable -nolookup mode.\n"
-" nolookup enable -nolookup mode.\n"
-" lookup disable -nolookup mode.\n"
-" input:str set -input to \"str\", empty to disable.\n"
-" grabkbd enable -grabkbd mode.\n"
-" nograbkbd disable -grabkbd mode.\n"
-" grabptr enable -grabptr mode.\n"
-" nograbptr disable -grabptr mode.\n"
-" grabalways enable -grabalways mode.\n"
-" nograbalways disable -grabalways mode.\n"
-" grablocal:n set -grablocal to n.\n"
-" client_input:str set the K, M, B -input on a per-client\n"
-" basis. select which client as for\n"
-" disconnect, e.g. client_input:host:MB\n"
-" or client_input:0x2:K\n"
-/* ext. cmd. */
-" accept:cmd set -accept \"cmd\" (empty to disable).\n"
-" afteraccept:cmd set -afteraccept (empty to disable).\n"
-" gone:cmd set -gone \"cmd\" (empty to disable).\n"
-" noshm enable -noshm mode.\n"
-" shm disable -noshm mode (i.e. use shm).\n"
-" flipbyteorder enable -flipbyteorder mode, you may need\n"
-" to set noshm for this to do something.\n"
-" noflipbyteorder disable -flipbyteorder mode.\n"
-" onetile enable -onetile mode. (you may need to\n"
-" set shm for this to do something)\n"
-" noonetile disable -onetile mode.\n"
-/* ext. cmd. */
-" solid enable -solid mode\n"
-" nosolid disable -solid mode.\n"
-" solid_color:color set -solid color (and apply it).\n"
-" blackout:str set -blackout \"str\" (empty to disable).\n"
-" See -blackout for the form of \"str\"\n"
-" (basically: WxH+X+Y,...)\n"
-" Use \"+WxH+X+Y\" to append a single\n"
-" rectangle use \"-WxH+X+Y\" to delete one\n"
-" xinerama enable -xinerama mode. (if applicable)\n"
-" noxinerama disable -xinerama mode.\n"
-" xtrap enable -xtrap input mode(if applicable)\n"
-" noxtrap disable -xtrap input mode.\n"
-" xrandr enable -xrandr mode. (if applicable)\n"
-" noxrandr disable -xrandr mode.\n"
-" xrandr_mode:mode set the -xrandr mode to \"mode\".\n"
-" rotate:mode set the -rotate mode to \"mode\".\n"
-" padgeom:WxH set -padgeom to WxH (empty to disable)\n"
-" If WxH is \"force\" or \"do\" the padded\n"
-" geometry fb is immediately applied.\n"
-" quiet enable -quiet mode.\n"
-" noquiet disable -quiet mode.\n"
-" modtweak enable -modtweak mode.\n"
-" nomodtweak enable -nomodtweak mode.\n"
-" xkb enable -xkb modtweak mode.\n"
-" noxkb disable -xkb modtweak mode.\n"
-" capslock enable -capslock mode.\n"
-" nocapslock disable -capslock mode.\n"
-" skip_lockkeys enable -skip_lockkeys mode.\n"
-" noskip_lockkeys disable -skip_lockkeys mode.\n"
-" skip_keycodes:str enable -xkb -skip_keycodes \"str\".\n"
-" sloppy_keys enable -sloppy_keys mode.\n"
-" nosloppy_keys disable -sloppy_keys mode.\n"
-" skip_dups enable -skip_dups mode.\n"
-" noskip_dups disable -skip_dups mode.\n"
-" add_keysyms enable -add_keysyms mode.\n"
-" noadd_keysyms stop adding keysyms. those added will\n"
-" still be removed at exit.\n"
-" clear_mods enable -clear_mods mode and clear them.\n"
-" noclear_mods disable -clear_mods mode.\n"
-" clear_keys enable -clear_keys mode and clear them.\n"
-" noclear_keys disable -clear_keys mode.\n"
-" clear_locks do the clear_locks action.\n"
-" clear_all do the clear_all action.\n"
-" keystate have x11vnc print current keystate.\n"
-/* filename */
-" remap:str set -remap \"str\" (empty to disable).\n"
-" See -remap for the form of \"str\"\n"
-" (basically: key1-key2,key3-key4,...)\n"
-" Use \"+key1-key2\" to append a single\n"
-" keymapping, use \"-key1-key2\" to delete.\n"
-" norepeat enable -norepeat mode.\n"
-" repeat disable -norepeat mode.\n"
-" nofb enable -nofb mode.\n"
-" fb disable -nofb mode.\n"
-" bell enable bell (if supported).\n"
-" nobell disable bell.\n"
-" sendbell ring the bell now.\n"
-" nosel enable -nosel mode.\n"
-" sel disable -nosel mode.\n"
-" noprimary enable -noprimary mode.\n"
-" primary disable -noprimary mode.\n"
-" nosetprimary enable -nosetprimary mode.\n"
-" setprimary disable -nosetprimary mode.\n"
-" noclipboard enable -noclipboard mode.\n"
-" clipboard disable -noclipboard mode.\n"
-" nosetclipboard enable -nosetclipboard mode.\n"
-" setclipboard disable -nosetclipboard mode.\n"
-" seldir:str set -seldir to \"str\"\n"
-" resend_cutbuffer resend the most recent CUTBUFFER0 copy\n"
-" resend_clipboard resend the most recent CLIPBOARD copy\n"
-" resend_primary resend the most recent PRIMARY copy\n"
-" cursor:mode enable -cursor \"mode\".\n"
-" show_cursor enable showing a cursor.\n"
-" noshow_cursor disable showing a cursor. (same as\n"
-" \"nocursor\")\n"
-" cursor_drag enable cursor changes during drag.\n"
-" nocursor_drag disable cursor changes during drag.\n"
-" arrow:n set -arrow to alternate n.\n"
-" xfixes enable xfixes cursor shape mode.\n"
-" noxfixes disable xfixes cursor shape mode.\n"
-" alphacut:n set -alphacut to n.\n"
-" alphafrac:f set -alphafrac to f.\n"
-" alpharemove enable -alpharemove mode.\n"
-" noalpharemove disable -alpharemove mode.\n"
-" alphablend disable -noalphablend mode.\n"
-" noalphablend enable -noalphablend mode.\n"
-" cursorshape disable -nocursorshape mode.\n"
-" nocursorshape enable -nocursorshape mode.\n"
-" cursorpos disable -nocursorpos mode.\n"
-" nocursorpos enable -nocursorpos mode.\n"
-" xwarp enable -xwarppointer mode.\n"
-" noxwarp disable -xwarppointer mode.\n"
-" always_inject enable -always_inject mode.\n"
-" noalways_inject disable -always_inject mode.\n"
-" buttonmap:str set -buttonmap \"str\", empty to disable\n"
-" dragging disable -nodragging mode.\n"
-" nodragging enable -nodragging mode.\n"
-" ncache reenable -ncache mode.\n"
-" noncache disable -ncache mode.\n"
-" ncache_size:n set -ncache size to n.\n"
-" ncache_cr enable -ncache_cr mode.\n"
-" noncache_cr disable -ncache_cr mode.\n"
-" ncache_no_moveraise enable no_moveraise mode.\n"
-" noncache_no_moveraise disable no_moveraise mode.\n"
-" ncache_no_dtchange enable ncache_no_dtchange mode.\n"
-" noncache_no_dtchange disable ncache_no_dtchange mode.\n"
-" ncache_old_wm enable ncache_old_wm mode.\n"
-" noncache_old_wm disable ncache_old_wm mode.\n"
-" ncache_no_rootpixmap enable ncache_no_rootpixmap.\n"
-" noncache_no_rootpixmap disable ncache_no_rootpixmap.\n"
-" ncache_reset_rootpixmap recheck the root pixmap, ncrp\n"
-" ncache_keep_anims enable ncache_keep_anims.\n"
-" noncache_keep_anims disable ncache_keep_anims.\n"
-" ncache_pad:n set -ncache_pad to n.\n"
-" wireframe enable -wireframe mode. same as \"wf\"\n"
-" nowireframe disable -wireframe mode. same as \"nowf\"\n"
-" wireframe:str enable -wireframe mode string.\n"
-" wireframe_mode:str enable -wireframe mode string.\n"
-" wireframelocal enable wireframelocal. same as \"wfl\"\n"
-" nowireframe disable wireframelocal. same as \"nowfl\"\n"
-" wirecopyrect:str set -wirecopyrect string. same as \"wcr:\"\n"
-" scrollcopyrect:str set -scrollcopyrect string. same \"scr\"\n"
-" noscrollcopyrect disable -scrollcopyrect mode. \"noscr\"\n"
-" scr_area:n set -scr_area to n\n"
-" scr_skip:list set -scr_skip to \"list\"\n"
-" scr_inc:list set -scr_inc to \"list\"\n"
-" scr_keys:list set -scr_keys to \"list\"\n"
-" scr_term:list set -scr_term to \"list\"\n"
-" scr_keyrepeat:str set -scr_keyrepeat to \"str\"\n"
-" scr_parms:str set -scr_parms parameters.\n"
-" fixscreen:str set -fixscreen to \"str\".\n"
-" noxrecord disable all use of RECORD extension.\n"
-" xrecord enable use of RECORD extension.\n"
-" reset_record reset RECORD extension (if avail.)\n"
-" pointer_mode:n set -pointer_mode to n. same as \"pm\"\n"
-" input_skip:n set -input_skip to n.\n"
-" allinput enable use of -allinput mode.\n"
-" noallinput disable use of -allinput mode.\n"
-" input_eagerly enable use of -input_eagerly mode.\n"
-" noinput_eagerly disable use of -input_eagerly mode.\n"
-" ssltimeout:n set -ssltimeout to n.\n"
-" speeds:str set -speeds to str.\n"
-" wmdt:str set -wmdt to str.\n"
-" debug_pointer enable -debug_pointer, same as \"dp\"\n"
-" nodebug_pointer disable -debug_pointer, same as \"nodp\"\n"
-" debug_keyboard enable -debug_keyboard, same as \"dk\"\n"
-" nodebug_keyboard disable -debug_keyboard, same as \"nodk\"\n"
-" keycode:n inject keystroke 'keycode' (xmodmap -pk)\n"
-" keycode:n,down inject 'keycode' (down=0,1)\n"
-" keysym:str inject keystroke 'keysym' (number/name)\n"
-" keysym:str,down inject 'keysym' (down=0,1)\n"
-" ptr:x,y,mask inject pointer event x, y, button-mask\n"
-" fakebuttonevent:button,down direct XTestFakeButtonEvent.\n"
-" sleep:t sleep floating point time t.\n"
-" get_xprop:p get X property named 'p'.\n"
-" set_xprop:p:val set X property named 'p' to 'val'.\n"
-" p -> id=NNN:p for hex/dec window id.\n"
-" wininfo:id get info about X window id. use 'root'\n"
-" for root window, use +id for children.\n"
-" grab_state get state of pointer and keyboard grab.\n"
-" pointer_pos print XQueryPointer x,y cursor position.\n"
-" pointer_x print XQueryPointer x cursor position.\n"
-" pointer_y print XQueryPointer y cursor position.\n"
-" pointer_same print XQueryPointer ptr on same screen.\n"
-" pointer_root print XQueryPointer curr ptr rootwin.\n"
-" pointer_mask print XQueryPointer button and mods mask\n"
-" mouse_x print x11vnc's idea of cursor position.\n"
-" mouse_y print x11vnc's idea of cursor position.\n"
-" noop do nothing.\n"
-" defer:n set -defer to n ms,same as deferupdate:n\n"
-" wait:n set -wait to n ms.\n"
-" extra_fbur:n set -extra_fbur to n.\n"
-" wait_ui:f set -wait_ui factor to f.\n"
-" setdefer:n set -setdefer to -2,-1,0,1, or 2.\n"
-" wait_bog disable -nowait_bog mode.\n"
-" nowait_bog enable -nowait_bog mode.\n"
-" slow_fb:f set -slow_fb to f seconds.\n"
-" xrefresh:f set -xrefresh to f seconds.\n"
-" readtimeout:n set read timeout to n seconds.\n"
-" nap enable -nap mode.\n"
-" nonap disable -nap mode.\n"
-" sb:n set -sb to n s, same as screen_blank:n\n"
-" fbpm disable -nofbpm mode.\n"
-" nofbpm enable -nofbpm mode.\n"
-" dpms disable -nodpms mode.\n"
-" nodpms enable -nodpms mode.\n"
-" forcedpms enable -forcedpms mode.\n"
-" noforcedpms disable -forcedpms mode.\n"
-" clientdpms enable -clientdpms mode.\n"
-" noclientdpms disable -clientdpms mode.\n"
-" noserverdpms enable -noserverdpms mode.\n"
-" serverdpms disable -noserverdpms mode.\n"
-" noultraext enable -noultraext mode.\n"
-" ultraext disable -noultraext mode.\n"
-" chatwindow enable local chatwindow mode.\n"
-" nochatwindow disable local chatwindow mode.\n"
-" chaton begin chat using local window.\n"
-" chatoff end chat using local window.\n"
-" xdamage enable xdamage polling hints.\n"
-" noxdamage disable xdamage polling hints.\n"
-" xd_area:A set -xd_area max pixel area to \"A\"\n"
-" xd_mem:f set -xd_mem remembrance to \"f\"\n"
-" fs:frac set -fs fraction to \"frac\", e.g. 0.5\n"
-" gaps:n set -gaps to n.\n"
-" grow:n set -grow to n.\n"
-" fuzz:n set -fuzz to n.\n"
-" snapfb enable -snapfb mode.\n"
-" nosnapfb disable -snapfb mode.\n"
-" rawfb:str set -rawfb mode to \"str\".\n"
-" uinput_accel:f set uinput_accel to f.\n"
-" uinput_thresh:n set uinput_thresh to n.\n"
-" uinput_reset:n set uinput_reset to n ms.\n"
-" uinput_always:n set uinput_always to 1/0.\n"
-" progressive:n set LibVNCServer -progressive slice\n"
-" height parameter to n.\n"
-" desktop:str set -desktop name to str for new clients.\n"
-" rfbport:n set -rfbport to n.\n"
-" macnosaver enable -macnosaver mode.\n"
-" macsaver disable -macnosaver mode.\n"
-" macnowait enable -macnowait mode.\n"
-" macwait disable -macnowait mode.\n"
-" macwheel:n set -macwheel to n.\n"
-" macnoswap enable -macnoswap mouse button mode.\n"
-" macswap disable -macnoswap mouse button mode.\n"
-" macnoresize enable -macnoresize mode.\n"
-" macresize disable -macnoresize mode.\n"
-" maciconanim:n set -maciconanim to n.\n"
-" macmenu enable -macmenu mode.\n"
-" macnomenu disable -macmenu mode.\n"
-" macuskbd enable -macuskbd mode.\n"
-" macnouskbd disable -macuskbd mode.\n"
-/* access */
-" httpport:n set -httpport to n.\n"
-" httpdir:dir set -httpdir to dir (and enable http).\n"
-" enablehttpproxy enable -enablehttpproxy mode.\n"
-" noenablehttpproxy disable -enablehttpproxy mode.\n"
-" alwaysshared enable -alwaysshared mode.\n"
-" noalwaysshared disable -alwaysshared mode.\n"
-" (may interfere with other options)\n"
-" nevershared enable -nevershared mode.\n"
-" nonevershared disable -nevershared mode.\n"
-" (may interfere with other options)\n"
-" dontdisconnect enable -dontdisconnect mode.\n"
-" nodontdisconnect disable -dontdisconnect mode.\n"
-" (may interfere with other options)\n"
-" debug_xevents enable debugging X events.\n"
-" nodebug_xevents disable debugging X events.\n"
-" debug_xdamage enable debugging X DAMAGE mechanism.\n"
-" nodebug_xdamage disable debugging X DAMAGE mechanism.\n"
-" debug_wireframe enable debugging wireframe mechanism.\n"
-" nodebug_wireframe disable debugging wireframe mechanism.\n"
-" debug_scroll enable debugging scrollcopy mechanism.\n"
-" nodebug_scroll disable debugging scrollcopy mechanism.\n"
-" debug_tiles enable -debug_tiles\n"
-" nodebug_tiles disable -debug_tiles\n"
-" debug_grabs enable -debug_grabs\n"
-" nodebug_grabs disable -debug_grabs\n"
-" debug_sel enable -debug_sel\n"
-" nodebug_sel disable -debug_sel\n"
-" debug_ncache enable -debug_ncache\n"
-" nodebug_ncache disable -debug_ncache\n"
-" dbg enable -dbg crash shell\n"
-" nodbg disable -dbg crash shell\n"
-"\n"
-" noremote disable the -remote command processing,\n"
-" it cannot be turned back on.\n"
-"\n"
-" bcx_xattach:str This remote control command is for\n"
-" use with the BARCO xattach program or the x2x program.\n"
-" Both of these programs are for 'pointer and keyboard'\n"
-" sharing between separate X displays. In general the\n"
-" two displays are usually nearby, e.g. on the same desk,\n"
-" and this allows the user to share a single pointer and\n"
-" keyboard between them. The user moves the mouse to\n"
-" an edge and then the mouse pointer appears to 'jump'\n"
-" to the other display screen. Thus it emulates what a\n"
-" single X server would do for two screens (e.g. :0.0 and\n"
-" :0.1) The illusion of a single Xserver with multiple\n"
-" screens is achieved by forwarding events to the 2nd\n"
-" one via the XTEST extension.\n"
-"\n"
-" What the x11vnc bcx_xattach command does is to perform\n"
-" some pointer movements to try to INDUCE xattach/x2x\n"
-" to 'jump' to the other display. In what follows the\n"
-" 'master' display refers to the one that when it has\n"
-" 'focus' it is basically doing nothing besides watching\n"
-" for the mouse to go over an edge. The 'slave'\n"
-" display refers to the one to which the mouse and\n"
-" keyboard is redirected to once an edge in the master\n"
-" has been crossed. Note that the x11vnc executing the\n"
-" bcx_xattach command MUST be the one connected to the\n"
-" *master* display.\n"
-"\n"
-" Also note that when input is being redirected (via\n"
-" XTEST) from the master display to the slave display,\n"
-" the master display's pointer and keyboard are *grabbed*\n"
-" by xattach/x2x. x11vnc can use this info to verify that\n"
-" the master/slave mode change has taken place correctly.\n"
-" If you specify the \"ifneeded\" option (see below)\n"
-" and the initial grab state is that of the desired\n"
-" final state, then no pointer movements are injected\n"
-" and \"DONE,GRAB_OK\" is returned.\n"
-"\n"
-" \"str\" must contain one of \"up\", \"down\", \"left\",\n"
-" or \"right\" to indicate the direction of the 'jump'.\n"
-" \"str\" must also contain one of \"master_to_slave\"\n"
-" or \"slave_to_master\" to indicate the type of mode\n"
-" change induced by the jump. Use \"M2S\" and \"S2M\"\n"
-" as shorter aliases.\n"
-"\n"
-" \"str\" may be a \"+\" separated list of additional\n"
-" tuning options. The \"shift=n\" option indicates an\n"
-" offset shift position away from (0,0) (default 20).\n"
-" \"final=x+y\" specifies the final position of the cursor\n"
-" at the end of the normal move sequence; default 30+30.\n"
-" \"extra_move=x+y\" means to do one more pointer move\n"
-" after \"final\" to x+y. \"dt=n\" sets the sleep time\n"
-" in milliseconds between pointer moves (default: 40ms)\n"
-" \"retry=n\" specifies the maximum number of retries if\n"
-" the grab state change fails. \"ifneeded\" means to not\n"
-" apply the pointer movements if the initial grab state is\n"
-" that of the desired final state. \"nograbcheck\" means\n"
-" to not check if the grab state changed as expected and\n"
-" only apply the pointer movements (default is to check\n"
-" the grab states.)\n"
-"\n"
-" If you do not specify \"up\", etc., to bcx_xattach\n"
-" nothing will be attempted and the command returns\n"
-" the string FAIL,NO_DIRECTION_SPECIFIED. If you do\n"
-" not specify \"master_to_slave\" or \"M2S\", etc., to\n"
-" bcx_xattach nothing will be attempted and the command\n"
-" returns the string FAIL,NO_MODE_CHANGE_SPECIFIED.\n"
-"\n"
-" Otherwise, the returned string will contain \"DONE\".\n"
-" It will be \"DONE,GRAB_OK\" if the grab state changed\n"
-" as expected (or if \"ifneeded\" was supplied and\n"
-" the initial grab state was already the desired\n"
-" one.) If the initial grab state was incorrect,\n"
-" but the final grab state was correct then it is\n"
-" \"DONE,GRAB_FAIL_INIT\". If the initial grab state\n"
-" was correct, but the final grab state was incorrect\n"
-" then it is \"DONE,GRAB_FAIL_FINAL\". If both are\n"
-" incorrect it will be \"DONE,GRAB_FAIL\". Under grab\n"
-" failure the string will be followed by \":p1,k1-p2,k2\"\n"
-" where p1,k1 indicates the initial pointer and keyboard\n"
-" grab states and p2,k2 the final ones. If GRAB_FAIL or\n"
-" GRAB_FAIL_FINAL occurs, the action will be retried up\n"
-" to 3 times; trying to reset the state and sleeping a\n"
-" bit between each try. Set retry=n to adjust the number\n"
-" of retries, zero to disable retries.\n"
-"\n"
-" Examples:\n"
-" -R bcx_xattach:down+M2S\n"
-" -R bcx_xattach:up+S2M\n"
-" -R bcx_xattach:up+S2M+nograbcheck+dt=30\n"
-" -R bcx_xattach:down+M2S+extra_move=100+100\n"
-"\n"
-" or use -Q instead of -R to retrieve the result text.\n"
-"\n"
-" End of the bcx_xattach:str description.\n"
-"\n"
-" The vncconnect(1) command from standard VNC\n"
-" distributions may also be used if string is prefixed\n"
-" with \"cmd=\" E.g. 'vncconnect cmd=stop'. Under some\n"
-" circumstances xprop(1) can used if it supports -set\n"
-" (see the FAQ).\n"
-"\n"
-" If \"-connect /path/to/file\" has been supplied to the\n"
-" running x11vnc server then that file can be used as a\n"
-" communication channel (this is the only way to remote\n"
-" control one of many x11vnc's polling the same X display)\n"
-" Simply run: 'x11vnc -connect /path/to/file -remote ...'\n"
-" or you can directly write to the file via something\n"
-" like: \"echo cmd=stop > /path/to/file\", etc.\n"
-"\n"
-"-query variable Like -remote, except just query the value of\n"
-" \"variable\". \"-Q\" is an alias for \"-query\".\n"
-" Multiple queries can be done by separating variables\n"
-" by commas, e.g. -query var1,var2. The results come\n"
-" back in the form ans=var1:value1,ans=var2:value2,...\n"
-" to the standard output. If a variable is read-only,\n"
-" it comes back with prefix \"aro=\" instead of \"ans=\".\n"
-"\n"
-" Some -remote commands are pure actions that do not make\n"
-" sense as variables, e.g. \"stop\" or \"disconnect\", in\n"
-" these cases the value returned is \"N/A\". To direct a\n"
-" query straight to the X11VNC_REMOTE property or connect\n"
-" file use \"qry=...\" instead of \"cmd=...\"\n"
-"\n"
-" ans= stop quit exit shutdown ping resend_cutbuffer\n"
-" resend_clipboard resend_primary blacken zero refresh\n"
-" reset close disconnect id_cmd id sid waitmapped\n"
-" nowaitmapped clip flashcmap noflashcmap shiftcmap\n"
-" truecolor notruecolor overlay nooverlay overlay_cursor\n"
-" overlay_yescursor nooverlay_nocursor nooverlay_cursor\n"
-" nooverlay_yescursor overlay_nocursor 8to24 no8to24\n"
-" 8to24_opts 24to32 no24to32 visual scale scale_cursor\n"
-" viewonly noviewonly shared noshared forever noforever\n"
-" once timeout tightfilexfer notightfilexfer ultrafilexfer\n"
-" noultrafilexfer rfbversion deny lock nodeny unlock avahi\n"
-" mdns zeroconf noavahi nomdns nozeroconf connect proxy\n"
-" allowonce allow noipv6 ipv6 noipv4 ipv4 no6 6 localhost\n"
-" nolocalhost listen lookup nolookup accept afteraccept\n"
-" gone shm noshm flipbyteorder noflipbyteorder onetile\n"
-" noonetile solid_color solid nosolid blackout xinerama\n"
-" noxinerama xtrap noxtrap xrandr noxrandr xrandr_mode\n"
-" rotate padgeom quiet q noquiet modtweak nomodtweak xkb\n"
-" noxkb capslock nocapslock skip_lockkeys noskip_lockkeys\n"
-" skip_keycodes sloppy_keys nosloppy_keys skip_dups\n"
-" noskip_dups add_keysyms noadd_keysyms clear_mods\n"
-" noclear_mods clear_keys noclear_keys clear_all\n"
-" clear_locks keystate remap repeat norepeat fb nofb bell\n"
-" nobell sendbell sel nosel primary noprimary setprimary\n"
-" nosetprimary clipboard noclipboard setclipboard\n"
-" nosetclipboard seldir cursorshape nocursorshape\n"
-" cursorpos nocursorpos cursor_drag nocursor_drag cursor\n"
-" show_cursor noshow_cursor nocursor arrow xfixes noxfixes\n"
-" xdamage noxdamage xd_area xd_mem alphacut alphafrac\n"
-" alpharemove noalpharemove alphablend noalphablend\n"
-" xwarppointer xwarp noxwarppointer noxwarp always_inject\n"
-" noalways_inject buttonmap dragging nodragging ncache_cr\n"
-" noncache_cr ncache_no_moveraise noncache_no_moveraise\n"
-" ncache_no_dtchange noncache_no_dtchange\n"
-" ncache_no_rootpixmap noncache_no_rootpixmap\n"
-" ncache_reset_rootpixmap ncrp ncache_keep_anims\n"
-" noncache_keep_anims ncache_old_wm noncache_old_wm\n"
-" ncache_pad ncache noncache ncache_size debug_ncache\n"
-" nodebug_ncache wireframe_mode wireframe wf nowireframe\n"
-" nowf wireframelocal wfl nowireframelocal nowfl\n"
-" wirecopyrect wcr nowirecopyrect nowcr scr_area\n"
-" scr_skip scr_inc scr_keys scr_term scr_keyrepeat\n"
-" scr_parms scrollcopyrect scr noscrollcopyrect\n"
-" noscr fixscreen noxrecord xrecord reset_record\n"
-" pointer_mode pm input_skip allinput noallinput\n"
-" input_eagerly noinput_eagerly input grabkbd nograbkbd\n"
-" grabptr nograbptr grabalways nograbalways grablocal\n"
-" client_input ssltimeout speeds wmdt debug_pointer dp\n"
-" nodebug_pointer nodp debug_keyboard dk nodebug_keyboard\n"
-" nodk keycode keysym ptr fakebuttonevent sleep get_xprop\n"
-" set_xprop wininfo bcx_xattach deferupdate defer\n"
-" setdefer extra_fbur wait_ui wait_bog nowait_bog\n"
-" slow_fb xrefresh wait readtimeout nap nonap sb\n"
-" screen_blank fbpm nofbpm dpms nodpms clientdpms\n"
-" noclientdpms forcedpms noforcedpms noserverdpms\n"
-" serverdpms noultraext ultraext chatwindow nochatwindow\n"
-" chaton chatoff fs gaps grow fuzz snapfb nosnapfb\n"
-" rawfb uinput_accel uinput_thresh uinput_reset\n"
-" uinput_always progressive rfbport http nohttp httpport\n"
-" httpdir enablehttpproxy noenablehttpproxy alwaysshared\n"
-" noalwaysshared nevershared noalwaysshared dontdisconnect\n"
-" nodontdisconnect desktop debug_xevents nodebug_xevents\n"
-" debug_xevents debug_xdamage nodebug_xdamage\n"
-" debug_xdamage debug_wireframe nodebug_wireframe\n"
-" debug_wireframe debug_scroll nodebug_scroll debug_scroll\n"
-" debug_tiles dbt nodebug_tiles nodbt debug_tiles\n"
-" debug_grabs nodebug_grabs debug_sel nodebug_sel dbg\n"
-" nodbg macnosaver macsaver nomacnosaver macnowait macwait\n"
-" nomacnowait macwheel macnoswap macswap nomacnoswap\n"
-" macnoresize macresize nomacnoresize maciconanim macmenu\n"
-" macnomenu nomacmenu macuskbd nomacuskbd noremote\n"
-"\n"
-" aro= noop display vncdisplay icon_mode autoport\n"
-" loop loopbg desktopname guess_desktop guess_dbus\n"
-" http_url auth xauth users rootshift clipshift scale_str\n"
-" scaled_x scaled_y scale_numer scale_denom scale_fac_x\n"
-" scale_fac_y scaling_blend scaling_nomult4 scaling_pad\n"
-" scaling_interpolate inetd privremote unsafe safer nocmds\n"
-" passwdfile unixpw unixpw_nis unixpw_list ssl ssl_pem\n"
-" sslverify stunnel stunnel_pem https httpsredir usepw\n"
-" using_shm logfile o flag rmflag rc norc h help V version\n"
-" lastmod bg sigpipe threads readrate netrate netlatency\n"
-" pipeinput clients client_count pid ext_xtest ext_xtrap\n"
-" ext_xrecord ext_xkb ext_xshm ext_xinerama ext_overlay\n"
-" ext_xfixes ext_xdamage ext_xrandr rootwin num_buttons\n"
-" button_mask mouse_x mouse_y grab_state pointer_pos\n"
-" pointer_x pointer_y pointer_same pointer_root\n"
-" pointer_mask bpp depth indexed_color dpy_x dpy_y wdpy_x\n"
-" wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y rfbauth\n"
-" passwd viewpasswd\n"
-"\n"
-"-QD variable Just like -query variable, but returns the default\n"
-" value for that parameter (no running x11vnc server\n"
-" is consulted)\n"
-"\n"
-"-sync By default -remote commands are run asynchronously, that\n"
-" is, the request is posted and the program immediately\n"
-" exits. Use -sync to have the program wait for an\n"
-" acknowledgement from the x11vnc server that command was\n"
-" processed (somehow). On the other hand -query requests\n"
-" are always processed synchronously because they have\n"
-" to wait for the answer.\n"
-"\n"
-" Also note that if both -remote and -query requests are\n"
-" supplied on the command line, the -remote is processed\n"
-" first (synchronously: no need for -sync), and then\n"
-" the -query request is processed in the normal way.\n"
-" This allows for a reliable way to see if the -remote\n"
-" command was processed by querying for any new settings.\n"
-" Note however that there is timeout of a few seconds\n"
-" (see the next paragraph) so if the x11vnc takes longer\n"
-" than that to process the requests the requester will\n"
-" think that a failure has taken place.\n"
-"\n"
-" The default is to wait 3.5 seconds. Or if cmd=stop\n"
-" only 1.0 seconds. If cmd matches 'script:' then it\n"
-" will wait up to 10.0 seconds. Set X11VNC_SYNC_TIMEOUT\n"
-" to the number of seconds you want it to wait.\n"
-"\n"
-"-query_retries str If a query fails to get a response from an x11vnc\n"
-" server, retry up to n times. \"str\" is specified as\n"
-" n[:t][/match] Optionally the delay between tries may\n"
-" be specified by \"t\" a floating point time (default\n"
-" 0.5 seconds.) Note: the response is not checked for\n"
-" validity or whether it corresponds to the query sent.\n"
-" The query \"ping:mystring\" may be used to help uniquely\n"
-" identify the query. Optionally, a matching string after\n"
-" a \"/\" will be used to check the result text. Up to\n"
-" n retries will take place until the matching string is\n"
-" found in the output text. If the match string is never\n"
-" found the program's exit code is 1; if the match is\n"
-" found it exits with 0. Note that there may be stdout\n"
-" printed for each retry (i.e. multiple lines printed\n"
-" out to stdout.)\n"
-" Example: -query_retries 4:1.5/grab_state\n"
-"\n"
-"-remote_prefix str Enable a remote-control communication channel for\n"
-" connected VNC clients. str is a non-empty string. If a\n"
-" VNC client sends rfbCutText having the prefix \"str\"\n"
-" then the part after it is processed as though it were\n"
-" sent via 'x11vnc -remote ...'. If it begins with\n"
-" neither 'cmd=' nor 'qry=' then 'qry=' is assumed.\n"
-" Any corresponding output text for that remote control\n"
-" command is sent back to all client as rfbCutText.\n"
-" The returned output is also prefixed with \"str\".\n"
-" Example: -remote_prefix DO_THIS:\n"
-"\n"
-" Note that enabling -remote_prefix allows the remote\n"
-" VNC viewers to run x11vnc -remote commands. Do not\n"
-" use this option if they are not to be trusted.\n"
-"\n"
-"-noremote Do not process any remote control commands or queries.\n"
-"-yesremote Do process remote control commands or queries.\n"
-" Default: %s\n"
-"\n"
-" A note about security wrt remote control commands.\n"
-" If someone can connect to the X display and change\n"
-" the property X11VNC_REMOTE, then they can remotely\n"
-" control x11vnc. Normally access to the X display is\n"
-" protected. Note that if they can modify X11VNC_REMOTE\n"
-" on the X server, they have enough permissions to also\n"
-" run their own x11vnc and thus have complete control\n"
-" of the desktop. If the \"-connect /path/to/file\"\n"
-" channel is being used, obviously anyone who can write\n"
-" to /path/to/file can remotely control x11vnc. So be\n"
-" sure to protect the X display and that file's write\n"
-" permissions. See -privremote below.\n"
-"\n"
-" If you are paranoid and do not think -noremote is\n"
-" enough, to disable the X11VNC_REMOTE property channel\n"
-" completely use -novncconnect, or use the -safer option\n"
-" that shuts many things off.\n"
-"\n"
-"-unsafe A few remote commands are disabled by default\n"
-" (currently: id:pick, accept:<cmd>, gone:<cmd>, and\n"
-" rawfb:setup:<cmd>) because they are associated with\n"
-" running external programs. If you specify -unsafe, then\n"
-" these remote-control commands are allowed. Note that\n"
-" you can still specify these parameters on the command\n"
-" line, they just cannot be invoked via remote-control.\n"
-"-safer Equivalent to: -novncconnect -noremote and prohibiting\n"
-" -gui and the -connect file. Shuts off communcation\n"
-" channels.\n"
-"-privremote Perform some sanity checks and disable remote-control\n"
-" commands if it appears that the X DISPLAY and/or\n"
-" connectfile can be accessed by other users. Once\n"
-" remote-control is disabled it cannot be turned back on.\n"
-"-nocmds No external commands (e.g. system(3), popen(3), exec(3))\n"
-" will be run at all.\n"
-"-allowedcmds list \"list\" contains a comma separated list of the only\n"
-" external commands that can be run. The full list of\n"
-" associated options is:\n"
-"\n"
-" stunnel, ssl, unixpw, WAIT, zeroconf, id, accept,\n"
-" afteraccept, gone, pipeinput, v4l-info, rawfb-setup,\n"
-" dt, gui, ssh, storepasswd, passwdfile, custom_passwd,\n"
-" findauth, crash.\n"
-"\n"
-" See each option's help to learn the associated external\n"
-" command. Note that the -nocmds option takes precedence\n"
-" and disables all external commands.\n"
-"\n"
-"-deny_all For use with -remote nodeny: start out denying all\n"
-" incoming clients until \"-remote nodeny\" is used to\n"
-" let them in.\n"
-"\n"
-"%s\n"
-"\n"
-"These options are passed to LibVNCServer:\n"
-"\n"
-;
- /* have both our help and rfbUsage to stdout for more(1), etc. */
- dup2(1, 2);
-
- /* register extension(s) to get their help output */
-#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
- rfbRegisterTightVNCFileTransferExtension();
-#endif
-
- if (mode == 1) {
- char *p;
- int l = 0;
- fprintf(stderr, "x11vnc: allow VNC connections to real "
- "X11 displays. %s\n\nx11vnc options:\n", lastmod);
- p = strtok(help, "\n");
- while (p) {
- int w = 23;
- char tmp[100];
- if (p[0] == '-') {
- memset(tmp, 0, sizeof(tmp));
- strncpy(tmp, p, w);
- fprintf(stderr, " %s", tmp);
- l++;
- if (l % 3 == 0) {
- fprintf(stderr, "\n");
- }
- }
- p = strtok(NULL, "\n");
- }
- fprintf(stderr, "\n\nLibVNCServer options:\n");
- rfbUsage();
- fprintf(stderr, "\n");
- exit(1);
- }
-#if 1
- fprintf(stderr, help, lastmod,
- POLL_8TO24_DELAY,
- scaling_copyrect ? ":cr":":nocr",
- view_only ? "on":"off",
- shared ? "on":"off",
- vnc_connect ? "-vncconnect":"-novncconnect",
- xinerama ? "-xinerama":"-noxinerama",
- use_modifier_tweak ? "-modtweak":"-nomodtweak",
- skip_duplicate_key_events ? "-skip_dups":"-noskip_dups",
- add_keysyms ? "-add_keysyms":"-noadd_keysyms",
- no_autorepeat ? "-norepeat":"-repeat",
- alt_arrow_max, alt_arrow,
- alpha_threshold,
- alpha_frac,
- cursor_pos_updates ? "-cursorpos":"-nocursorpos",
- wireframe ? "-wireframe":"-nowireframe",
- WIREFRAME_PARMS,
- wireframe_copyrect_default,
- scroll_copyrect_default,
- scrollcopyrect_min_area,
- scroll_skip_str0 ? scroll_skip_str0 : "(empty)",
- scroll_term_str0,
- max_keyrepeat_str0,
- SCROLL_COPYRECT_PARMS,
- pointer_mode_max, pointer_mode,
- ui_skip,
- defer_update,
- waitms,
- wait_ui,
- take_naps ? "take naps":"no naps",
- screen_blank,
- rfbMaxClientWait/1000,
- watch_fbpm ? "-nofbpm":"-fbpm",
- watch_dpms ? "-nodpms":"-dpms",
- xdamage_max_area, NSCAN, xdamage_memory,
- use_threads ? "-threads":"-nothreads",
- fs_frac,
- gaps_fill,
- grow_fill,
- tile_fuzz,
- accept_remote_cmds ? "-yesremote":"-noremote",
- ""
- );
-#else
- fprintf(stderr, "%s", help);
-#endif
-
- rfbUsage();
-#endif
- exit(1);
-}
-
-void xopen_display_fail_message(char *disp) {
- fprintf(stderr, "\n");
- fprintf(stderr, "*** x11vnc was unable to open the X DISPLAY: \"%s\","
- " it cannot continue.\n", disp);
- fprintf(stderr, "*** There may be \"Xlib:\" error messages above"
- " with details about the failure.\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Some tips and guidelines:\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "** An X server (the one you wish to view) must"
- " be running before x11vnc is\n");
- fprintf(stderr, " started: x11vnc does not start the X server. "
- "(however, see the -create\n");
- fprintf(stderr, " option if that is what you really want).\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "** You must use -display <disp>, -OR- set and"
- " export your $DISPLAY\n");
- fprintf(stderr, " environment variable to refer to the display of"
- " the desired X server.\n");
- fprintf(stderr, " - Usually the display is simply \":0\" (in fact"
- " x11vnc uses this if you forget\n");
- fprintf(stderr, " to specify it), but in some multi-user"
- " situations it could be \":1\", \":2\",\n");
- fprintf(stderr, " or even \":137\". Ask your administrator"
- " or a guru if you are having\n");
- fprintf(stderr, " difficulty determining what your X DISPLAY is.\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "** Next, you need to have sufficient permissions"
- " (Xauthority) \n");
- fprintf(stderr, " to connect to the X DISPLAY. Here are some"
- " Tips:\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " - Often, you just need to run x11vnc as the user"
- " logged into the X session.\n");
- fprintf(stderr, " So make sure to be that user when you type"
- " x11vnc.\n");
- fprintf(stderr, " - Being root is usually not enough because the"
- " incorrect MIT-MAGIC-COOKIE\n");
- fprintf(stderr, " file may be accessed. The cookie file contains"
- " the secret key that\n");
- fprintf(stderr, " allows x11vnc to connect to the desired"
- " X DISPLAY.\n");
- fprintf(stderr, " - You can explicitly indicate which MIT-MAGIC-COOKIE"
- " file should be used\n");
- fprintf(stderr, " by the -auth option, e.g.:\n");
- fprintf(stderr, " x11vnc -auth /home/someuser/.Xauthority"
- " -display :0\n");
- fprintf(stderr, " x11vnc -auth /tmp/.gdmzndVlR"
- " -display :0\n");
- fprintf(stderr, " you must have read permission for the auth file.\n");
- fprintf(stderr, " See also '-auth guess' and '-findauth' discussed below.\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "** If NO ONE is logged into an X session yet, but"
- " there is a greeter login\n");
- fprintf(stderr, " program like \"gdm\", \"kdm\", \"xdm\", or"
- " \"dtlogin\" running, you will need\n");
- fprintf(stderr, " to find and use the raw display manager"
- " MIT-MAGIC-COOKIE file.\n");
- fprintf(stderr, " Some examples for various display managers:\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " gdm: -auth /var/gdm/:0.Xauth\n");
- fprintf(stderr, " -auth /var/lib/gdm/:0.Xauth\n");
- fprintf(stderr, " kdm: -auth /var/lib/kdm/A:0-crWk72\n");
- fprintf(stderr, " -auth /var/run/xauth/A:0-crWk72\n");
- fprintf(stderr, " xdm: -auth /var/lib/xdm/authdir/authfiles/A:0-XQvaJk\n");
- fprintf(stderr, " dtlogin: -auth /var/dt/A:0-UgaaXa\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " Sometimes the command \"ps wwwwaux | grep auth\""
- " can reveal the file location.\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " Starting with x11vnc 0.9.9 you can have it try to guess by using:\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " -auth guess\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " (see also the x11vnc -findauth option.)\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " Only root will have read permission for the"
- " file, and so x11vnc must be run\n");
- fprintf(stderr, " as root (or copy it). The random characters in the filenames"
- " will of course\n");
- fprintf(stderr, " change and the directory the cookie file resides in"
- " is system dependent.\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "See also: http://www.karlrunge.com/x11vnc/faq.html\n");
-}
-
-void nopassword_warning_msg(int gotloc) {
-
- char str1[] =
-"###############################################################\n"
-"#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#\n"
-"#@ @#\n"
-"#@ ** WARNING ** WARNING ** WARNING ** WARNING ** @#\n"
-"#@ @#\n"
-"#@ YOU ARE RUNNING X11VNC WITHOUT A PASSWORD!! @#\n"
-"#@ @#\n"
-"#@ This means anyone with network access to this computer @#\n"
-"#@ may be able to view and control your desktop. @#\n"
-"#@ @#\n"
-"#@ >>> If you did not mean to do this Press CTRL-C now!! <<< @#\n"
-"#@ @#\n"
-"#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#\n"
-;
- char str2[] =
-"#@ @#\n"
-"#@ You can create an x11vnc password file by running: @#\n"
-"#@ @#\n"
-"#@ x11vnc -storepasswd password /path/to/passfile @#\n"
-"#@ or x11vnc -storepasswd /path/to/passfile @#\n"
-"#@ or x11vnc -storepasswd @#\n"
-"#@ @#\n"
-"#@ (the last one will use ~/.vnc/passwd) @#\n"
-"#@ @#\n"
-"#@ and then starting x11vnc via: @#\n"
-"#@ @#\n"
-"#@ x11vnc -rfbauth /path/to/passfile @#\n"
-"#@ @#\n"
-"#@ an existing ~/.vnc/passwd file from another VNC @#\n"
-"#@ application will work fine too. @#\n"
-"#@ @#\n"
-"#@ You can also use the -passwdfile or -passwd options. @#\n"
-"#@ (note -passwd is unsafe if local users are not trusted) @#\n"
-"#@ @#\n"
-"#@ Make sure any -rfbauth and -passwdfile password files @#\n"
-"#@ cannot be read by untrusted users. @#\n"
-"#@ @#\n"
-"#@ Use x11vnc -usepw to automatically use your @#\n"
-"#@ ~/.vnc/passwd or ~/.vnc/passwdfile password files. @#\n"
-"#@ (and prompt you to create ~/.vnc/passwd if neither @#\n"
-"#@ file exists.) Under -usepw, x11vnc will exit if it @#\n"
-"#@ cannot find a password to use. @#\n"
-"#@ @#\n"
-"#@ @#\n"
-"#@ Even with a password, the subsequent VNC traffic is @#\n"
-"#@ sent in the clear. Consider tunnelling via ssh(1): @#\n"
-"#@ @#\n"
-"#@ http://www.karlrunge.com/x11vnc/#tunnelling @#\n"
-"#@ @#\n"
-"#@ Or using the x11vnc SSL options: -ssl and -stunnel @#\n"
-"#@ @#\n"
-"#@ Please Read the documention for more info about @#\n"
-"#@ passwords, security, and encryption. @#\n"
-"#@ @#\n"
-"#@ http://www.karlrunge.com/x11vnc/faq.html#faq-passwd @#\n"
-;
- char str3[] =
-"#@ @#\n"
-"#@ You are using the -localhost option and that is a good @#\n"
-"#@ thing!! Especially if you ssh(1) into this machine and @#\n"
-"#@ use port redirection. Nevertheless, without a password @#\n"
-"#@ other users could possibly do redirection as well to @#\n"
-"#@ gain access to your desktop. @#\n"
-;
- char str4[] =
-"#@ @#\n"
-"#@ To disable this warning use the -nopw option, or put @#\n"
-"#@ 'nopw' on a line in your ~/.x11vncrc file. @#\n"
-"#@ @#\n"
-"#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#\n"
-"###############################################################\n"
-;
- char str5[] =
-"###############################################################\n\n"
-;
- if (inetd) {
- return;
- }
-
- fprintf(stderr, "%s", str1);
- fflush(stderr);
-#if !PASSWD_REQUIRED
- usleep(750 * 1000);
-#endif
- if (!quiet) {
- fprintf(stderr, "%s", str2);
- if (gotloc) {
- fprintf(stderr, "%s", str3);
- }
- fprintf(stderr, "%s", str4);
- } else {
- fprintf(stderr, "%s", str5);
- }
- fflush(stderr);
-#if !PASSWD_REQUIRED
- usleep(250 * 1000);
-#endif
-}
-
-void print_license(void) {
- char license[] =
-#if !SKIP_HELP
-" GNU GENERAL PUBLIC LICENSE\n"
-" Version 2, June 1991\n"
-"\n"
-" Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n"
-" 59 Temple Place - Suite 330, Boston, MA\n"
-" 02111-1307, USA.\n"
-" Everyone is permitted to copy and distribute verbatim copies\n"
-" of this license document, but changing it is not allowed.\n"
-"\n"
-" Preamble\n"
-"\n"
-" The licenses for most software are designed to take away your\n"
-"freedom to share and change it. By contrast, the GNU General Public\n"
-"License is intended to guarantee your freedom to share and change free\n"
-"software--to make sure the software is free for all its users. This\n"
-"General Public License applies to most of the Free Software\n"
-"Foundation's software and to any other program whose authors commit to\n"
-"using it. (Some other Free Software Foundation software is covered by\n"
-"the GNU Library General Public License instead.) You can apply it to\n"
-"your programs, too.\n"
-"\n"
-" When we speak of free software, we are referring to freedom, not\n"
-"price. Our General Public Licenses are designed to make sure that you\n"
-"have the freedom to distribute copies of free software (and charge for\n"
-"this service if you wish), that you receive source code or can get it\n"
-"if you want it, that you can change the software or use pieces of it\n"
-"in new free programs; and that you know you can do these things.\n"
-"\n"
-" To protect your rights, we need to make restrictions that forbid\n"
-"anyone to deny you these rights or to ask you to surrender the rights.\n"
-"These restrictions translate to certain responsibilities for you if you\n"
-"distribute copies of the software, or if you modify it.\n"
-"\n"
-" For example, if you distribute copies of such a program, whether\n"
-"gratis or for a fee, you must give the recipients all the rights that\n"
-"you have. You must make sure that they, too, receive or can get the\n"
-"source code. And you must show them these terms so they know their\n"
-"rights.\n"
-"\n"
-" We protect your rights with two steps: (1) copyright the software, and\n"
-"(2) offer you this license which gives you legal permission to copy,\n"
-"distribute and/or modify the software.\n"
-"\n"
-" Also, for each author's protection and ours, we want to make certain\n"
-"that everyone understands that there is no warranty for this free\n"
-"software. If the software is modified by someone else and passed on, we\n"
-"want its recipients to know that what they have is not the original, so\n"
-"that any problems introduced by others will not reflect on the original\n"
-"authors' reputations.\n"
-"\n"
-" Finally, any free program is threatened constantly by software\n"
-"patents. We wish to avoid the danger that redistributors of a free\n"
-"program will individually obtain patent licenses, in effect making the\n"
-"program proprietary. To prevent this, we have made it clear that any\n"
-"patent must be licensed for everyone's free use or not licensed at all.\n"
-"\n"
-" The precise terms and conditions for copying, distribution and\n"
-"modification follow.\n"
-" \n"
-" GNU GENERAL PUBLIC LICENSE\n"
-" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n"
-"\n"
-" 0. This License applies to any program or other work which contains\n"
-"a notice placed by the copyright holder saying it may be distributed\n"
-"under the terms of this General Public License. The \"Program\", below,\n"
-"refers to any such program or work, and a \"work based on the Program\"\n"
-"means either the Program or any derivative work under copyright law:\n"
-"that is to say, a work containing the Program or a portion of it,\n"
-"either verbatim or with modifications and/or translated into another\n"
-"language. (Hereinafter, translation is included without limitation in\n"
-"the term \"modification\".) Each licensee is addressed as \"you\".\n"
-"\n"
-"Activities other than copying, distribution and modification are not\n"
-"covered by this License; they are outside its scope. The act of\n"
-"running the Program is not restricted, and the output from the Program\n"
-"is covered only if its contents constitute a work based on the\n"
-"Program (independent of having been made by running the Program).\n"
-"Whether that is true depends on what the Program does.\n"
-"\n"
-" 1. You may copy and distribute verbatim copies of the Program's\n"
-"source code as you receive it, in any medium, provided that you\n"
-"conspicuously and appropriately publish on each copy an appropriate\n"
-"copyright notice and disclaimer of warranty; keep intact all the\n"
-"notices that refer to this License and to the absence of any warranty;\n"
-"and give any other recipients of the Program a copy of this License\n"
-"along with the Program.\n"
-"\n"
-"You may charge a fee for the physical act of transferring a copy, and\n"
-"you may at your option offer warranty protection in exchange for a fee.\n"
-"\n"
-" 2. You may modify your copy or copies of the Program or any portion\n"
-"of it, thus forming a work based on the Program, and copy and\n"
-"distribute such modifications or work under the terms of Section 1\n"
-"above, provided that you also meet all of these conditions:\n"
-"\n"
-" a) You must cause the modified files to carry prominent notices\n"
-" stating that you changed the files and the date of any change.\n"
-"\n"
-" b) You must cause any work that you distribute or publish, that in\n"
-" whole or in part contains or is derived from the Program or any\n"
-" part thereof, to be licensed as a whole at no charge to all third\n"
-" parties under the terms of this License.\n"
-"\n"
-" c) If the modified program normally reads commands interactively\n"
-" when run, you must cause it, when started running for such\n"
-" interactive use in the most ordinary way, to print or display an\n"
-" announcement including an appropriate copyright notice and a\n"
-" notice that there is no warranty (or else, saying that you provide\n"
-" a warranty) and that users may redistribute the program under\n"
-" these conditions, and telling the user how to view a copy of this\n"
-" License. (Exception: if the Program itself is interactive but\n"
-" does not normally print such an announcement, your work based on\n"
-" the Program is not required to print an announcement.)\n"
-" \n"
-"These requirements apply to the modified work as a whole. If\n"
-"identifiable sections of that work are not derived from the Program,\n"
-"and can be reasonably considered independent and separate works in\n"
-"themselves, then this License, and its terms, do not apply to those\n"
-"sections when you distribute them as separate works. But when you\n"
-"distribute the same sections as part of a whole which is a work based\n"
-"on the Program, the distribution of the whole must be on the terms of\n"
-"this License, whose permissions for other licensees extend to the\n"
-"entire whole, and thus to each and every part regardless of who wrote it.\n"
-"\n"
-"Thus, it is not the intent of this section to claim rights or contest\n"
-"your rights to work written entirely by you; rather, the intent is to\n"
-"exercise the right to control the distribution of derivative or\n"
-"collective works based on the Program.\n"
-"\n"
-"In addition, mere aggregation of another work not based on the Program\n"
-"with the Program (or with a work based on the Program) on a volume of\n"
-"a storage or distribution medium does not bring the other work under\n"
-"the scope of this License.\n"
-"\n"
-" 3. You may copy and distribute the Program (or a work based on it,\n"
-"under Section 2) in object code or executable form under the terms of\n"
-"Sections 1 and 2 above provided that you also do one of the following:\n"
-"\n"
-" a) Accompany it with the complete corresponding machine-readable\n"
-" source code, which must be distributed under the terms of Sections\n"
-" 1 and 2 above on a medium customarily used for software interchange; or,\n"
-"\n"
-" b) Accompany it with a written offer, valid for at least three\n"
-" years, to give any third party, for a charge no more than your\n"
-" cost of physically performing source distribution, a complete\n"
-" machine-readable copy of the corresponding source code, to be\n"
-" distributed under the terms of Sections 1 and 2 above on a medium\n"
-" customarily used for software interchange; or,\n"
-"\n"
-" c) Accompany it with the information you received as to the offer\n"
-" to distribute corresponding source code. (This alternative is\n"
-" allowed only for noncommercial distribution and only if you\n"
-" received the program in object code or executable form with such\n"
-" an offer, in accord with Subsection b above.)\n"
-"\n"
-"The source code for a work means the preferred form of the work for\n"
-"making modifications to it. For an executable work, complete source\n"
-"code means all the source code for all modules it contains, plus any\n"
-"associated interface definition files, plus the scripts used to\n"
-"control compilation and installation of the executable. However, as a\n"
-"special exception, the source code distributed need not include\n"
-"anything that is normally distributed (in either source or binary\n"
-"form) with the major components (compiler, kernel, and so on) of the\n"
-"operating system on which the executable runs, unless that component\n"
-"itself accompanies the executable.\n"
-"\n"
-"If distribution of executable or object code is made by offering\n"
-"access to copy from a designated place, then offering equivalent\n"
-"access to copy the source code from the same place counts as\n"
-"distribution of the source code, even though third parties are not\n"
-"compelled to copy the source along with the object code.\n"
-" \n"
-" 4. You may not copy, modify, sublicense, or distribute the Program\n"
-"except as expressly provided under this License. Any attempt\n"
-"otherwise to copy, modify, sublicense or distribute the Program is\n"
-"void, and will automatically terminate your rights under this License.\n"
-"However, parties who have received copies, or rights, from you under\n"
-"this License will not have their licenses terminated so long as such\n"
-"parties remain in full compliance.\n"
-"\n"
-" 5. You are not required to accept this License, since you have not\n"
-"signed it. However, nothing else grants you permission to modify or\n"
-"distribute the Program or its derivative works. These actions are\n"
-"prohibited by law if you do not accept this License. Therefore, by\n"
-"modifying or distributing the Program (or any work based on the\n"
-"Program), you indicate your acceptance of this License to do so, and\n"
-"all its terms and conditions for copying, distributing or modifying\n"
-"the Program or works based on it.\n"
-"\n"
-" 6. Each time you redistribute the Program (or any work based on the\n"
-"Program), the recipient automatically receives a license from the\n"
-"original licensor to copy, distribute or modify the Program subject to\n"
-"these terms and conditions. You may not impose any further\n"
-"restrictions on the recipients' exercise of the rights granted herein.\n"
-"You are not responsible for enforcing compliance by third parties to\n"
-"this License.\n"
-"\n"
-" 7. If, as a consequence of a court judgment or allegation of patent\n"
-"infringement or for any other reason (not limited to patent issues),\n"
-"conditions are imposed on you (whether by court order, agreement or\n"
-"otherwise) that contradict the conditions of this License, they do not\n"
-"excuse you from the conditions of this License. If you cannot\n"
-"distribute so as to satisfy simultaneously your obligations under this\n"
-"License and any other pertinent obligations, then as a consequence you\n"
-"may not distribute the Program at all. For example, if a patent\n"
-"license would not permit royalty-free redistribution of the Program by\n"
-"all those who receive copies directly or indirectly through you, then\n"
-"the only way you could satisfy both it and this License would be to\n"
-"refrain entirely from distribution of the Program.\n"
-"\n"
-"If any portion of this section is held invalid or unenforceable under\n"
-"any particular circumstance, the balance of the section is intended to\n"
-"apply and the section as a whole is intended to apply in other\n"
-"circumstances.\n"
-"\n"
-"It is not the purpose of this section to induce you to infringe any\n"
-"patents or other property right claims or to contest validity of any\n"
-"such claims; this section has the sole purpose of protecting the\n"
-"integrity of the free software distribution system, which is\n"
-"implemented by public license practices. Many people have made\n"
-"generous contributions to the wide range of software distributed\n"
-"through that system in reliance on consistent application of that\n"
-"system; it is up to the author/donor to decide if he or she is willing\n"
-"to distribute software through any other system and a licensee cannot\n"
-"impose that choice.\n"
-"\n"
-"This section is intended to make thoroughly clear what is believed to\n"
-"be a consequence of the rest of this License.\n"
-" \n"
-" 8. If the distribution and/or use of the Program is restricted in\n"
-"certain countries either by patents or by copyrighted interfaces, the\n"
-"original copyright holder who places the Program under this License\n"
-"may add an explicit geographical distribution limitation excluding\n"
-"those countries, so that distribution is permitted only in or among\n"
-"countries not thus excluded. In such case, this License incorporates\n"
-"the limitation as if written in the body of this License.\n"
-"\n"
-" 9. The Free Software Foundation may publish revised and/or new versions\n"
-"of the General Public License from time to time. Such new versions will\n"
-"be similar in spirit to the present version, but may differ in detail to\n"
-"address new problems or concerns.\n"
-"\n"
-"Each version is given a distinguishing version number. If the Program\n"
-"specifies a version number of this License which applies to it and \"any\n"
-"later version\", you have the option of following the terms and conditions\n"
-"either of that version or of any later version published by the Free\n"
-"Software Foundation. If the Program does not specify a version number of\n"
-"this License, you may choose any version ever published by the Free Software\n"
-"Foundation.\n"
-"\n"
-" 10. If you wish to incorporate parts of the Program into other free\n"
-"programs whose distribution conditions are different, write to the author\n"
-"to ask for permission. For software which is copyrighted by the Free\n"
-"Software Foundation, write to the Free Software Foundation; we sometimes\n"
-"make exceptions for this. Our decision will be guided by the two goals\n"
-"of preserving the free status of all derivatives of our free software and\n"
-"of promoting the sharing and reuse of software generally.\n"
-"\n"
-#endif
-" NO WARRANTY\n"
-"\n"
-" 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"
-"FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n"
-"OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"
-"PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"
-"OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
-"MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n"
-"TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n"
-"PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"
-"REPAIR OR CORRECTION.\n"
-"\n"
-" 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"
-"WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"
-"REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"
-"INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"
-"OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"
-"TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"
-"YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"
-"PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"
-"POSSIBILITY OF SUCH DAMAGES.\n"
-"\n"
-#if !SKIP_HELP
-" END OF TERMS AND CONDITIONS\n"
-" \n"
-" Appendix: How to Apply These Terms to Your New Programs\n"
-"\n"
-" If you develop a new program, and you want it to be of the greatest\n"
-"possible use to the public, the best way to achieve this is to make it\n"
-"free software which everyone can redistribute and change under these terms.\n"
-"\n"
-" To do so, attach the following notices to the program. It is safest\n"
-"to attach them to the start of each source file to most effectively\n"
-"convey the exclusion of warranty; and each file should have at least\n"
-"the \"copyright\" line and a pointer to where the full notice is found.\n"
-"\n"
-" <one line to give the program's name and a brief idea of what it does.>\n"
-" Copyright (C) 19yy <name of author>\n"
-"\n"
-" This program is free software; you can redistribute it and/or modify\n"
-" it under the terms of the GNU General Public License as published by\n"
-" the Free Software Foundation; either version 2 of the License, or\n"
-" (at your option) any later version.\n"
-"\n"
-" This program is distributed in the hope that it will be useful,\n"
-" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
-" GNU General Public License for more details.\n"
-"\n"
-" You should have received a copy of the GNU General Public License\n"
-" along with this program; if not, write to the Free Software\n"
-" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"
-"\n"
-"Also add information on how to contact you by electronic and paper mail.\n"
-"\n"
-"If the program is interactive, make it output a short notice like this\n"
-"when it starts in an interactive mode:\n"
-"\n"
-" Gnomovision version 69, Copyright (C) 19yy name of author\n"
-" Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n"
-" This is free software, and you are welcome to redistribute it\n"
-" under certain conditions; type `show c' for details.\n"
-"\n"
-"The hypothetical commands `show w' and `show c' should show the appropriate\n"
-"parts of the General Public License. Of course, the commands you use may\n"
-"be called something other than `show w' and `show c'; they could even be\n"
-"mouse-clicks or menu items--whatever suits your program.\n"
-"\n"
-"You should also get your employer (if you work as a programmer) or your\n"
-"school, if any, to sign a \"copyright disclaimer\" for the program, if\n"
-"necessary. Here is a sample; alter the names:\n"
-"\n"
-" Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n"
-" `Gnomovision' (which makes passes at compilers) written by James Hacker.\n"
-"\n"
-" <signature of Ty Coon>, 1 April 1989\n"
-" Ty Coon, President of Vice\n"
-"\n"
-"This General Public License does not permit incorporating your program into\n"
-"proprietary programs. If your program is a subroutine library, you may\n"
-"consider it more useful to permit linking proprietary applications with the\n"
-"library. If this is what you want to do, use the GNU Library General\n"
-"Public License instead of this License.\n"
-#endif
-;
-
- char top[] =
-"\n"
-"x11vnc: a VNC server for X displays. %s\n"
-"\n"
-"Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>\n"
-"All rights reserved.\n"
-"\n"
-;
- dup2(1, 2);
- fprintf(stderr, top, lastmod);
- fprintf(stderr, "%s", license);
- exit(1);
-}
-
diff --git a/x11vnc/help.h b/x11vnc/help.h
deleted file mode 100644
index 4607af8..0000000
--- a/x11vnc/help.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_HELP_H
-#define _X11VNC_HELP_H
-
-/* -- help.h -- */
-
-extern void print_help(int mode);
-extern void print_license(void);
-extern void xopen_display_fail_message(char *disp);
-extern void nopassword_warning_msg(int gotloc);
-
-#endif /* _X11VNC_HELP_H */
diff --git a/x11vnc/inet.c b/x11vnc/inet.c
deleted file mode 100644
index 23a911e..0000000
--- a/x11vnc/inet.c
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- inet.c -- */
-
-#include "x11vnc.h"
-#include "unixpw.h"
-#include "sslhelper.h"
-
-/*
- * Simple utility to map host name to dotted IP address. Ignores aliases.
- * Up to caller to free returned string.
- */
-char *host2ip(char *host);
-char *raw2host(char *raw, int len);
-char *raw2ip(char *raw);
-char *ip2host(char *ip);
-int ipv6_ip(char *host);
-int dotted_ip(char *host, int partial);
-int get_remote_port(int sock);
-int get_local_port(int sock);
-char *get_remote_host(int sock);
-char *get_local_host(int sock);
-char *ident_username(rfbClientPtr client);
-int find_free_port(int start, int end);
-int find_free_port6(int start, int end);
-int have_ssh_env(void);
-char *ipv6_getnameinfo(struct sockaddr *paddr, int addrlen);
-char *ipv6_getipaddr(struct sockaddr *paddr, int addrlen);
-int listen6(int port);
-int listen_unix(char *file);
-int accept_unix(int s);
-int connect_tcp(char *host, int port);
-int listen_tcp(int port, in_addr_t iface, int try6);
-
-static int get_port(int sock, int remote);
-static char *get_host(int sock, int remote);
-
-char *host2ip(char *host) {
- struct hostent *hp;
- struct sockaddr_in addr;
- char *str;
-
- if (! host_lookup) {
- return NULL;
- }
-
- hp = gethostbyname(host);
- if (!hp) {
- return NULL;
- }
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = *(unsigned long *)hp->h_addr;
- str = strdup(inet_ntoa(addr.sin_addr));
- return str;
-}
-
-char *raw2host(char *raw, int len) {
- char *str;
-#if LIBVNCSERVER_HAVE_NETDB_H && LIBVNCSERVER_HAVE_NETINET_IN_H
- struct hostent *hp;
-
- if (! host_lookup) {
- return strdup("unknown");
- }
-
- hp = gethostbyaddr(raw, len, AF_INET);
- if (!hp) {
- return strdup(inet_ntoa(*((struct in_addr *)raw)));
- }
- str = strdup(hp->h_name);
-#else
- str = strdup("unknown");
-#endif
- return str;
-}
-
-char *raw2ip(char *raw) {
- return strdup(inet_ntoa(*((struct in_addr *)raw)));
-}
-
-char *ip2host(char *ip) {
- char *str;
-#if LIBVNCSERVER_HAVE_NETDB_H && LIBVNCSERVER_HAVE_NETINET_IN_H
- struct hostent *hp;
- in_addr_t iaddr;
-
- if (! host_lookup) {
- return strdup("unknown");
- }
-
- iaddr = inet_addr(ip);
- if (iaddr == htonl(INADDR_NONE)) {
- return strdup("unknown");
- }
-
- hp = gethostbyaddr((char *)&iaddr, sizeof(in_addr_t), AF_INET);
- if (!hp) {
- return strdup("unknown");
- }
- str = strdup(hp->h_name);
-#else
- str = strdup("unknown");
-#endif
- return str;
-}
-
-int ipv6_ip(char *host_in) {
- char *p, *host, a[2];
- int ncol = 0, nhex = 0;
-
- if (host_in[0] == '[') {
- host = host_in + 1;
- } else {
- host = host_in;
- }
-
- if (strstr(host, "::ffff:") == host || strstr(host, "::FFFF:") == host) {
- return dotted_ip(host + strlen("::ffff:"), 0);
- }
-
- a[1] = '\0';
-
- p = host;
- while (*p != '\0' && *p != '%' && *p != ']') {
- if (*p == ':') {
- ncol++;
- } else {
- nhex++;
- }
- a[0] = *p;
- if (strpbrk(a, ":abcdef0123456789") == a) {
- p++;
- continue;
- }
- return 0;
- }
- if (ncol < 2 || ncol > 8 || nhex == 0) {
- return 0;
- } else {
- return 1;
- }
-}
-
-int dotted_ip(char *host, int partial) {
- int len, dots = 0;
- char *p = host;
-
- if (!host) {
- return 0;
- }
-
- if (!isdigit((unsigned char) host[0])) {
- return 0;
- }
-
- len = strlen(host);
- if (!partial && !isdigit((unsigned char) host[len-1])) {
- return 0;
- }
-
- while (*p != '\0') {
- if (*p == '.') dots++;
- if (*p == '.' || isdigit((unsigned char) (*p))) {
- p++;
- continue;
- }
- return 0;
- }
- if (!partial && dots != 3) {
- return 0;
- }
- return 1;
-}
-
-static int get_port(int sock, int remote) {
- struct sockaddr_in saddr;
- unsigned int saddr_len;
- int saddr_port;
-
- saddr_len = sizeof(saddr);
- memset(&saddr, 0, sizeof(saddr));
- saddr_port = -1;
- if (remote) {
- if (!getpeername(sock, (struct sockaddr *)&saddr, &saddr_len)) {
- saddr_port = ntohs(saddr.sin_port);
- }
- } else {
- if (!getsockname(sock, (struct sockaddr *)&saddr, &saddr_len)) {
- saddr_port = ntohs(saddr.sin_port);
- }
- }
- return saddr_port;
-}
-
-int get_remote_port(int sock) {
- return get_port(sock, 1);
-}
-
-int get_local_port(int sock) {
- return get_port(sock, 0);
-}
-
-static char *get_host(int sock, int remote) {
- struct sockaddr_in saddr;
- unsigned int saddr_len;
- int saddr_port;
- char *saddr_ip_str = NULL;
-
- saddr_len = sizeof(saddr);
- memset(&saddr, 0, sizeof(saddr));
- saddr_port = -1;
-#if LIBVNCSERVER_HAVE_NETINET_IN_H
- if (remote) {
- if (!getpeername(sock, (struct sockaddr *)&saddr, &saddr_len)) {
- saddr_ip_str = inet_ntoa(saddr.sin_addr);
- }
- } else {
- if (!getsockname(sock, (struct sockaddr *)&saddr, &saddr_len)) {
- saddr_ip_str = inet_ntoa(saddr.sin_addr);
- }
- }
-#endif
- if (! saddr_ip_str) {
- saddr_ip_str = "unknown";
- }
- return strdup(saddr_ip_str);
-}
-
-char *get_remote_host(int sock) {
- return get_host(sock, 1);
-}
-
-char *get_local_host(int sock) {
- return get_host(sock, 0);
-}
-
-char *ident_username(rfbClientPtr client) {
- ClientData *cd = (ClientData *) client->clientData;
- char *str, *newhost, *user = NULL, *newuser = NULL;
- int len;
-
- if (cd) {
- user = cd->username;
- }
- if (!user || *user == '\0') {
- int n, sock, ok = 0;
- int block = 0;
- int refused = 0;
-
- /*
- * need to check to see if the operation will block for
- * a long time: a firewall may just ignore our packets.
- */
-#if LIBVNCSERVER_HAVE_FORK
- { pid_t pid, pidw;
- int rc;
- if ((pid = fork()) > 0) {
- usleep(100 * 1000); /* 0.1 sec for quick success or refusal */
- pidw = waitpid(pid, &rc, WNOHANG);
- if (pidw <= 0) {
- usleep(1500 * 1000); /* 1.5 sec */
- pidw = waitpid(pid, &rc, WNOHANG);
- if (pidw <= 0) {
- int rc2;
- rfbLog("ident_username: set block=1 (hung)\n");
- block = 1;
- kill(pid, SIGTERM);
- usleep(100 * 1000);
- waitpid(pid, &rc2, WNOHANG);
- }
- }
- if (pidw > 0 && !block) {
- if (WIFEXITED(rc) && WEXITSTATUS(rc) == 1) {
- rfbLog("ident_username: set refused=1 (exit)\n");
- refused = 1;
- }
- }
- } else if (pid == -1) {
- ;
- } else {
- /* child */
- signal(SIGHUP, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
-
- if ((sock = connect_tcp(client->host, 113)) < 0) {
- exit(1);
- } else {
- close(sock);
- exit(0);
- }
- }
- }
-#endif
- if (block || refused) {
- ;
- } else if ((sock = connect_tcp(client->host, 113)) < 0) {
- rfbLog("ident_username: could not connect to ident: %s:%d\n",
- client->host, 113);
- } else {
- char msg[128];
- int ret;
- fd_set rfds;
- struct timeval tv;
- int rport = get_remote_port(client->sock);
- int lport = get_local_port(client->sock);
-
- sprintf(msg, "%d, %d\r\n", rport, lport);
- n = write(sock, msg, strlen(msg));
-
- FD_ZERO(&rfds);
- FD_SET(sock, &rfds);
- tv.tv_sec = 3;
- tv.tv_usec = 0;
- ret = select(sock+1, &rfds, NULL, NULL, &tv);
-
- if (ret > 0) {
- int i;
- char *q, *p;
- for (i=0; i < (int) sizeof(msg); i++) {
- msg[i] = '\0';
- }
- usleep(250*1000);
- n = read(sock, msg, 127);
- close(sock);
- if (n <= 0) goto badreply;
-
- /* 32782 , 6000 : USERID : UNIX :runge */
- q = strstr(msg, "USERID");
- if (!q) goto badreply;
- q = strstr(q, ":");
- if (!q) goto badreply;
- q++;
- q = strstr(q, ":");
- if (!q) goto badreply;
- q++;
- q = lblanks(q);
- p = q;
- while (*p) {
- if (*p == '\r' || *p == '\n') {
- *p = '\0';
- }
- p++;
- }
- ok = 1;
- if (strlen(q) > 24) {
- *(q+24) = '\0';
- }
- newuser = strdup(q);
-
- badreply:
- n = 0; /* avoid syntax error */
- } else {
- close(sock);
- }
- }
- if (! ok || !newuser) {
- newuser = strdup("unknown-user");
- }
- if (cd) {
- if (cd->username) {
- free(cd->username);
- }
- cd->username = newuser;
- }
- user = newuser;
- }
- if (!strcmp(user, "unknown-user") && cd && cd->unixname[0] != '\0') {
- user = cd->unixname;
- }
- if (unixpw && openssl_last_ip && strstr("UNIX:", user) != user) {
- newhost = ip2host(openssl_last_ip);
- } else {
- newhost = ip2host(client->host);
- }
- len = strlen(user) + 1 + strlen(newhost) + 1;
- str = (char *) malloc(len);
- sprintf(str, "%s@%s", user, newhost);
- free(newhost);
- return str;
-}
-
-int find_free_port(int start, int end) {
- int port;
- if (start <= 0) {
- start = 1024;
- }
- if (end <= 0) {
- end = 65530;
- }
- for (port = start; port <= end; port++) {
- int sock = listen_tcp(port, htonl(INADDR_ANY), 0);
- if (sock >= 0) {
- close(sock);
- return port;
- }
- }
- return 0;
-}
-
-int find_free_port6(int start, int end) {
- int port;
- if (start <= 0) {
- start = 1024;
- }
- if (end <= 0) {
- end = 65530;
- }
- for (port = start; port <= end; port++) {
- int sock = listen6(port);
- if (sock >= 0) {
- close(sock);
- return port;
- }
- }
- return 0;
-}
-
-int have_ssh_env(void) {
- char *str, *p = getenv("SSH_CONNECTION");
- char *rhost, *rport, *lhost, *lport;
-
- if (! p) {
- char *q = getenv("SSH_CLIENT");
- if (! q) {
- return 0;
- }
- if (strstr(q, "127.0.0.1") != NULL) {
- return 0;
- }
- return 1;
- }
-
- if (strstr(p, "127.0.0.1") != NULL) {
- return 0;
- }
-
- str = strdup(p);
-
- p = strtok(str, " ");
- rhost = p;
-
- p = strtok(NULL, " ");
- if (! p) goto fail;
-
- rport = p;
-
- p = strtok(NULL, " ");
- if (! p) goto fail;
-
- lhost = p;
-
- p = strtok(NULL, " ");
- if (! p) goto fail;
-
- lport = p;
-
-if (0) fprintf(stderr, "%d/%d - '%s' '%s'\n", atoi(rport), atoi(lport), rhost, lhost);
-
- if (atoi(rport) <= 16 || atoi(rport) > 65535) {
- goto fail;
- }
- if (atoi(lport) <= 16 || atoi(lport) > 65535) {
- goto fail;
- }
-
- if (!strcmp(rhost, lhost)) {
- goto fail;
- }
-
- free(str);
-
- return 1;
-
- fail:
-
- free(str);
-
- return 0;
-}
-
-char *ipv6_getnameinfo(struct sockaddr *paddr, int addrlen) {
-#if X11VNC_IPV6
- char name[200];
- if (noipv6) {
- return strdup("unknown");
- }
- if (getnameinfo(paddr, addrlen, name, sizeof(name), NULL, 0, 0) == 0) {
- return strdup(name);
- }
-#endif
- return strdup("unknown");
-}
-
-char *ipv6_getipaddr(struct sockaddr *paddr, int addrlen) {
-#if X11VNC_IPV6 && defined(NI_NUMERICHOST)
- char name[200];
- if (noipv6) {
- return strdup("unknown");
- }
- if (getnameinfo(paddr, addrlen, name, sizeof(name), NULL, 0, NI_NUMERICHOST) == 0) {
- return strdup(name);
- }
-#endif
- return strdup("unknown");
-}
-
-int listen6(int port) {
-#if X11VNC_IPV6
- struct sockaddr_in6 sin;
- int fd = -1, one = 1;
-
- if (noipv6) {
- return -1;
- }
- if (port <= 0 || 65535 < port) {
- /* for us, invalid port means do not listen. */
- return -1;
- }
-
- fd = socket(AF_INET6, SOCK_STREAM, 0);
- if (fd < 0) {
- rfbLogPerror("listen6: socket");
- rfbLog("(Ignore the above error if this system is IPv4-only.)\n");
- return -1;
- }
-
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
- rfbLogPerror("listen6: setsockopt SO_REUSEADDR");
- close(fd);
- return -1;
- }
-
-#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
- if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
- rfbLogPerror("listen6: setsockopt IPV6_V6ONLY");
- close(fd);
- return -1;
- }
-#endif
-
- memset((char *)&sin, 0, sizeof(sin));
- sin.sin6_family = AF_INET6;
- sin.sin6_port = htons(port);
- sin.sin6_addr = in6addr_any;
-
- if (listen_str6) {
- if (!strcmp(listen_str6, "localhost") || !strcmp(listen_str6, "::1")) {
- sin.sin6_addr = in6addr_loopback;
- } else {
- int err;
- struct addrinfo *ai;
- struct addrinfo hints;
- char service[32];
-
- memset(&hints, 0, sizeof(hints));
- sprintf(service, "%d", port);
-
- hints.ai_family = AF_INET6;
- hints.ai_socktype = SOCK_STREAM;
-#ifdef AI_ADDRCONFIG
- hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-#ifdef AI_NUMERICHOST
- if(ipv6_ip(listen_str6)) {
- hints.ai_flags |= AI_NUMERICHOST;
- }
-#endif
-#ifdef AI_NUMERICSERV
- hints.ai_flags |= AI_NUMERICSERV;
-#endif
- err = getaddrinfo(listen_str6, service, &hints, &ai);
- if (err == 0) {
- struct addrinfo *ap = ai;
- err = 1;
- while (ap != NULL) {
- char *s = ipv6_getipaddr(ap->ai_addr, ap->ai_addrlen);
- if (!s) s = strdup("unknown");
-
- rfbLog("listen6: checking: %s family: %d\n", s, ap->ai_family);
- if (ap->ai_family == AF_INET6) {
- memcpy((char *)&sin, ap->ai_addr, sizeof(sin));
- rfbLog("listen6: using: %s scope_id: %d\n", s, sin.sin6_scope_id);
- err = 0;
- free(s);
- break;
- }
- free(s);
- ap = ap->ai_next;
- }
- freeaddrinfo(ai);
- }
-
- if (err != 0) {
- rfbLog("Invalid or Unsupported -listen6 string: %s\n", listen_str6);
- close(fd);
- return -1;
- }
- }
- } else if (allow_list && !strcmp(allow_list, "127.0.0.1")) {
- sin.sin6_addr = in6addr_loopback;
- } else if (listen_str) {
- if (!strcmp(listen_str, "localhost")) {
- sin.sin6_addr = in6addr_loopback;
- }
- }
-
- if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
- rfbLogPerror("listen6: bind");
- close(fd);
- return -1;
- }
- if (listen(fd, 32) < 0) {
- rfbLogPerror("listen6: listen");
- close(fd);
- return -1;
- }
- return fd;
-#else
- if (port) {}
- return -1;
-#endif
-}
-
-#ifdef LIBVNCSERVER_HAVE_SYS_SOCKET_H
-#include <sys/un.h>
-#endif
-
-int listen_unix(char *file) {
-#if !defined(AF_UNIX) || !defined(LIBVNCSERVER_HAVE_SYS_SOCKET_H)
- if (sock) {}
- return -1;
-#else
- int s, len;
- struct sockaddr_un saun;
-
- s = socket(AF_UNIX, SOCK_STREAM, 0);
- if (s < 0) {
- rfbLogPerror("listen_unix: socket");
- return -1;
- }
- saun.sun_family = AF_UNIX;
- strcpy(saun.sun_path, file);
- unlink(file);
-
- len = sizeof(saun.sun_family) + strlen(saun.sun_path);
-
- if (bind(s, (struct sockaddr *)&saun, len) < 0) {
- rfbLogPerror("listen_unix: bind");
- close(s);
- return -1;
- }
-
- if (listen(s, 32) < 0) {
- rfbLogPerror("listen_unix: listen");
- close(s);
- return -1;
- }
- rfbLog("listening on unix socket: %s fd=%d\n", file, s);
- return s;
-#endif
-}
-
-int accept_unix(int s) {
-#if !defined(AF_UNIX) || !defined(LIBVNCSERVER_HAVE_SYS_SOCKET_H)
- if (s) {}
- return -1;
-#else
- int fd, fromlen;
- struct sockaddr_un fsaun;
-
- fd = accept(s, (struct sockaddr *)&fsaun, &fromlen);
- if (fd < 0) {
- rfbLogPerror("accept_unix: accept");
- return -1;
- }
- return fd;
-#endif
-}
-
-int connect_tcp(char *host, int port) {
- double t0 = dnow();
- int fd = -1;
- int fail4 = noipv4;
- if (getenv("IPV4_FAILS")) {
- fail4 = 2;
- }
-
- rfbLog("connect_tcp: trying: %s %d\n", host, port);
-
- if (fail4) {
- if (fail4 > 1) {
- rfbLog("TESTING: IPV4_FAILS for connect_tcp.\n");
- }
- } else {
- fd = rfbConnectToTcpAddr(host, port);
- }
-
- if (fd >= 0) {
- return fd;
- }
- rfbLogPerror("connect_tcp: connection failed");
-
- if (dnow() - t0 < 4.0) {
- rfbLog("connect_tcp: re-trying %s %d\n", host, port);
- usleep (100 * 1000);
- if (!fail4) {
- fd = rfbConnectToTcpAddr(host, port);
- }
- if (fd < 0) {
- rfbLogPerror("connect_tcp: connection failed");
- }
- }
-
- if (fd < 0 && !noipv6) {
-#if X11VNC_IPV6
- int err;
- struct addrinfo *ai;
- struct addrinfo hints;
- char service[32], *host2, *q;
-
- rfbLog("connect_tcp: trying IPv6 %s %d\n", host, port);
-
- memset(&hints, 0, sizeof(hints));
- sprintf(service, "%d", port);
-
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-#ifdef AI_ADDRCONFIG
- hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- if(ipv6_ip(host)) {
-#ifdef AI_NUMERICHOST
- rfbLog("connect_tcp[ipv6]: setting AI_NUMERICHOST for %s\n", host);
- hints.ai_flags |= AI_NUMERICHOST;
-#endif
- }
-#ifdef AI_NUMERICSERV
- hints.ai_flags |= AI_NUMERICSERV;
-#endif
-
- if (!strcmp(host, "127.0.0.1")) {
- host2 = strdup("::1");
- } else if (host[0] == '[') {
- host2 = strdup(host+1);
- } else {
- host2 = strdup(host);
- }
- q = strrchr(host2, ']');
- if (q) {
- *q = '\0';
- }
-
- err = getaddrinfo(host2, service, &hints, &ai);
- if (err != 0) {
- rfbLog("connect_tcp[ipv6]: getaddrinfo[%d]: %s\n", err, gai_strerror(err));
- usleep(100 * 1000);
- err = getaddrinfo(host2, service, &hints, &ai);
- }
- free(host2);
-
- if (err != 0) {
- rfbLog("connect_tcp[ipv6]: getaddrinfo[%d]: %s\n", err, gai_strerror(err));
- } else {
- struct addrinfo *ap = ai;
- while (ap != NULL) {
- int sock;
-
- if (fail4) {
- struct sockaddr_in6 *s6ptr;
- if (ap->ai_family != AF_INET6) {
- rfbLog("connect_tcp[ipv6]: skipping AF_INET address under -noipv4\n");
- ap = ap->ai_next;
- continue;
- }
-#ifdef IN6_IS_ADDR_V4MAPPED
- s6ptr = (struct sockaddr_in6 *) ap->ai_addr;
- if (IN6_IS_ADDR_V4MAPPED(&(s6ptr->sin6_addr))) {
- rfbLog("connect_tcp[ipv6]: skipping V4MAPPED address under -noipv4\n");
- ap = ap->ai_next;
- continue;
- }
-#endif
- }
-
- sock = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
-
- if (sock == -1) {
- rfbLogPerror("connect_tcp[ipv6]: socket");
- if (0) rfbLog("(Ignore the above error if this system is IPv4-only.)\n");
- } else {
- int res = -1, dmsg = 0;
- char *s = ipv6_getipaddr(ap->ai_addr, ap->ai_addrlen);
- if (!s) s = strdup("unknown");
-
- rfbLog("connect_tcp[ipv6]: trying sock=%d fam=%d proto=%d using %s\n",
- sock, ap->ai_family, ap->ai_protocol, s);
- res = connect(sock, ap->ai_addr, ap->ai_addrlen);
-#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
- if (res != 0) {
- int zero = 0;
- rfbLogPerror("connect_tcp[ipv6]: connect");
- dmsg = 1;
- if (setsockopt(sock, SOL_IPV6, IPV6_V6ONLY, (char *)&zero, sizeof(zero)) == 0) {
- rfbLog("connect_tcp[ipv6]: trying again with IPV6_V6ONLY=0\n");
- res = connect(sock, ap->ai_addr, ap->ai_addrlen);
- dmsg = 0;
- } else {
- rfbLogPerror("connect_tcp[ipv6]: setsockopt IPV6_V6ONLY");
- }
- }
-#endif
- if (res == 0) {
- rfbLog("connect_tcp[ipv6]: connect OK\n");
- fd = sock;
- if (!ipv6_client_ip_str) {
- ipv6_client_ip_str = strdup(s);
- }
- free(s);
- break;
- } else {
- if (!dmsg) rfbLogPerror("connect_tcp[ipv6]: connect");
- close(sock);
- }
- free(s);
- }
- ap = ap->ai_next;
- }
- freeaddrinfo(ai);
- }
-#endif
- }
- if (fd < 0 && !fail4) {
- /* this is a kludge for IPv4-only machines getting v4mapped string. */
- char *q, *host2;
- if (host[0] == '[') {
- host2 = strdup(host+1);
- } else {
- host2 = strdup(host);
- }
- q = strrchr(host2, ']');
- if (q) {
- *q = '\0';
- }
- if (strstr(host2, "::ffff:") == host2 || strstr(host2, "::FFFF:") == host2) {
- char *host3 = host2 + strlen("::ffff:");
- if (dotted_ip(host3, 0)) {
- rfbLog("connect_tcp[ipv4]: trying fallback to IPv4 for %s\n", host2);
- fd = rfbConnectToTcpAddr(host3, port);
- if (fd < 0) {
- rfbLogPerror("connect_tcp[ipv4]: connection failed");
- }
- }
- }
- free(host2);
- }
- return fd;
-}
-
-int listen_tcp(int port, in_addr_t iface, int try6) {
- int fd = -1;
- int fail4 = noipv4;
- if (getenv("IPV4_FAILS")) {
- fail4 = 2;
- }
-
- if (port <= 0 || 65535 < port) {
- /* for us, invalid port means do not listen. */
- return -1;
- }
-
- if (fail4) {
- if (fail4 > 1) {
- rfbLog("TESTING: IPV4_FAILS for listen_tcp: port=%d try6=%d\n", port, try6);
- }
- } else {
- fd = rfbListenOnTCPPort(port, iface);
- }
-
- if (fd >= 0) {
- return fd;
- }
- if (fail4 > 1) {
- rfbLogPerror("listen_tcp: listen failed");
- }
-
- if (fd < 0 && try6 && ipv6_listen && !noipv6) {
-#if X11VNC_IPV6
- char *save = listen_str6;
- if (iface == htonl(INADDR_LOOPBACK)) {
- listen_str6 = "localhost";
- rfbLog("listen_tcp: retrying on IPv6 in6addr_loopback ...\n");
- fd = listen6(port);
- } else if (iface == htonl(INADDR_ANY)) {
- listen_str6 = NULL;
- rfbLog("listen_tcp: retrying on IPv6 in6addr_any ...\n");
- fd = listen6(port);
- }
- listen_str6 = save;
-#endif
- }
- return fd;
-}
-
diff --git a/x11vnc/inet.h b/x11vnc/inet.h
deleted file mode 100644
index b76dbb4..0000000
--- a/x11vnc/inet.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_INET_H
-#define _X11VNC_INET_H
-
-/* -- inet.h -- */
-
-extern char *host2ip(char *host);
-extern char *raw2host(char *raw, int len);
-extern char *raw2ip(char *raw);
-extern char *ip2host(char *ip);
-extern int ipv6_ip(char *host);
-extern int dotted_ip(char *host, int partial);
-extern int get_remote_port(int sock);
-extern int get_local_port(int sock);
-extern char *get_remote_host(int sock);
-extern char *get_local_host(int sock);
-extern char *ident_username(rfbClientPtr client);
-extern int find_free_port(int start, int end);
-extern int find_free_port6(int start, int end);
-extern int have_ssh_env(void);
-extern char *ipv6_getnameinfo(struct sockaddr *paddr, int addrlen);
-extern char *ipv6_getipaddr(struct sockaddr *paddr, int addrlen);
-extern int listen6(int port);
-extern int listen_unix(char *file);
-extern int accept_unix(int s);
-extern int connect_tcp(char *host, int port);
-extern int listen_tcp(int port, in_addr_t iface, int try6);
-
-#endif /* _X11VNC_INET_H */
diff --git a/x11vnc/keyboard.c b/x11vnc/keyboard.c
deleted file mode 100644
index 54ff70e..0000000
--- a/x11vnc/keyboard.c
+++ /dev/null
@@ -1,3418 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- keyboard.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "xrecord.h"
-#include "xinerama.h"
-#include "pointer.h"
-#include "userinput.h"
-#include "win_utils.h"
-#include "rates.h"
-#include "cleanup.h"
-#include "allowed_input_t.h"
-#include "unixpw.h"
-#include "v4l.h"
-#include "linuxfb.h"
-#include "uinput.h"
-#include "macosx.h"
-#include "screen.h"
-
-void get_keystate(int *keystate);
-void clear_modifiers(int init);
-int track_mod_state(rfbKeySym keysym, rfbBool down, rfbBool set);
-void clear_keys(void);
-void clear_locks(void);
-int get_autorepeat_state(void);
-int get_initial_autorepeat_state(void);
-void autorepeat(int restore, int bequiet);
-void check_add_keysyms(void);
-int add_keysym(KeySym keysym);
-void delete_added_keycodes(int bequiet);
-void initialize_remap(char *infile);
-int sloppy_key_check(int key, rfbBool down, rfbKeySym keysym, int *new_kc);
-void switch_to_xkb_if_better(void);
-char *short_kmbcf(char *str);
-void initialize_allowed_input(void);
-void initialize_modtweak(void);
-void initialize_keyboard_and_pointer(void);
-void get_allowed_input(rfbClientPtr client, allowed_input_t *input);
-double typing_rate(double time_window, int *repeating);
-int skip_cr_when_scaling(char *mode);
-void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
-
-
-static void delete_keycode(KeyCode kc, int bequiet);
-static int count_added_keycodes(void);
-static void add_remap(char *line);
-static void add_dead_keysyms(char *str);
-static void initialize_xkb_modtweak(void);
-static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
- rfbClientPtr client);
-static void tweak_mod(signed char mod, rfbBool down);
-static void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym,
- rfbClientPtr client);
-static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
-
-
-/*
- * Routine to retreive current state keyboard. 1 means down, 0 up.
- */
-void get_keystate(int *keystate) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!keystate) {}
- return;
-#else
- int i, k;
- char keys[32];
-
- RAWFB_RET_VOID
-
- /* n.b. caller decides to X_LOCK or not. */
- XQueryKeymap(dpy, keys);
- for (i=0; i<32; i++) {
- char c = keys[i];
-
- for (k=0; k < 8; k++) {
- if (c & 0x1) {
- keystate[8*i + k] = 1;
- } else {
- keystate[8*i + k] = 0;
- }
- c = c >> 1;
- }
- }
-#endif /* NO_X11 */
-}
-
-/*
- * Try to KeyRelease any non-Lock modifiers that are down.
- */
-void clear_modifiers(int init) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!init) {}
- return;
-#else
- static KeyCode keycodes[256];
- static KeySym keysyms[256];
- static char *keystrs[256];
- static int kcount = 0, first = 1;
- int keystate[256];
- int i, j, minkey, maxkey, syms_per_keycode;
- KeySym *keymap;
- KeySym keysym;
- KeyCode keycode;
-
- RAWFB_RET_VOID
-
- /* n.b. caller decides to X_LOCK or not. */
- if (first) {
- /*
- * we store results in static arrays, to aid interrupted
- * case, but modifiers could have changed during session...
- */
- XDisplayKeycodes(dpy, &minkey, &maxkey);
-
- keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1),
- &syms_per_keycode);
-
- for (i = minkey; i <= maxkey; i++) {
- for (j = 0; j < syms_per_keycode; j++) {
- char *str;
- keysym = keymap[ (i - minkey) * syms_per_keycode + j ];
- if (keysym == NoSymbol || ! ismodkey(keysym)) {
- continue;
- }
- keycode = XKeysymToKeycode(dpy, keysym);
- if (keycode == NoSymbol) {
- continue;
- }
- keycodes[kcount] = keycode;
- keysyms[kcount] = keysym;
- str = XKeysymToString(keysym);
- if (! str) str = "null";
- keystrs[kcount] = strdup(str);
- kcount++;
- }
- }
- XFree_wr((void *) keymap);
- first = 0;
- }
- if (init) {
- return;
- }
-
- get_keystate(keystate);
- for (i=0; i < kcount; i++) {
- keysym = keysyms[i];
- keycode = keycodes[i];
-
- if (! keystate[(int) keycode]) {
- continue;
- }
-
- if (clear_mods) {
- rfbLog("clear_modifiers: up: %-10s (0x%x) "
- "keycode=0x%x\n", keystrs[i], keysym, keycode);
- }
- XTestFakeKeyEvent_wr(dpy, keycode, False, CurrentTime);
- }
- XFlush_wr(dpy);
-#endif /* NO_X11 */
-}
-
-static KeySym simple_mods[] = {
- XK_Shift_L, XK_Shift_R,
- XK_Control_L, XK_Control_R,
- XK_Meta_L, XK_Meta_R,
- XK_Alt_L, XK_Alt_R,
- XK_Super_L, XK_Super_R,
- XK_Hyper_L, XK_Hyper_R,
- XK_Mode_switch,
- NoSymbol
-};
-#define NSIMPLE_MODS 13
-
-int track_mod_state(rfbKeySym keysym, rfbBool down, rfbBool set) {
- KeySym sym = (KeySym) keysym;
- static rfbBool isdown[NSIMPLE_MODS];
- static int first = 1;
- int i, cnt = 0;
-
- /*
- * simple tracking method for the modifier state without
- * contacting the Xserver. Ignores, of course what keys are
- * pressed on the physical display.
- *
- * This is unrelated to our mod_tweak and xkb stuff.
- * Just a simple thing for wireframe/scroll heuristics,
- * sloppy keys etc.
- */
-
- if (first) {
- for (i=0; i<NSIMPLE_MODS; i++) {
- isdown[i] = FALSE;
- }
- first = 0;
- }
-
- if (sym != NoSymbol) {
- for (i=0; i<NSIMPLE_MODS; i++) {
- if (sym == simple_mods[i]) {
- if (set) {
- isdown[i] = down;
- return 1;
- } else {
- if (isdown[i]) {
- return 1;
- } else {
- return 0;
- }
- }
- break;
- }
- }
- /* not a modifier */
- if (set) {
- return 0;
- } else {
- return -1;
- }
- }
-
- /* called with NoSymbol: return number currently pressed: */
- for (i=0; i<NSIMPLE_MODS; i++) {
- if (isdown[i]) {
- cnt++;
- }
- }
- return cnt;
-}
-
-/*
- * Attempt to set all keys to Up position. Can mess up typing at the
- * physical keyboard so use with caution.
- */
-void clear_keys(void) {
- int k, keystate[256];
-
- RAWFB_RET_VOID
-
- /* n.b. caller decides to X_LOCK or not. */
- get_keystate(keystate);
- for (k=0; k<256; k++) {
- if (keystate[k]) {
- KeyCode keycode = (KeyCode) k;
- rfbLog("clear_keys: keycode=%d\n", keycode);
- XTestFakeKeyEvent_wr(dpy, keycode, False, CurrentTime);
- }
- }
- XFlush_wr(dpy);
-}
-
-
-void clear_locks(void) {
-#if NO_X11
- RAWFB_RET_VOID
- return;
-#else
- XModifierKeymap *map;
- int i, j, k = 0;
- unsigned int state = 0;
-
- RAWFB_RET_VOID
-
- /* n.b. caller decides to X_LOCK or not. */
-#if LIBVNCSERVER_HAVE_XKEYBOARD
- if (xkb_present) {
- XkbStateRec kbstate;
- XkbGetState(dpy, XkbUseCoreKbd, &kbstate);
- rfbLog("locked: 0x%x\n", kbstate.locked_mods);
- rfbLog("latched: 0x%x\n", kbstate.latched_mods);
- rfbLog("compat: 0x%x\n", kbstate.compat_state);
- state = kbstate.locked_mods;
- if (! state) {
- state = kbstate.compat_state;
- }
- } else
-#endif
- {
- state = mask_state();
- /* this may contain non-locks too... */
- rfbLog("state: 0x%x\n", state);
- }
- if (! state) {
- return;
- }
- map = XGetModifierMapping(dpy);
- if (! map) {
- return;
- }
- for (i = 0; i < 8; i++) {
- int did = 0;
- for (j = 0; j < map->max_keypermod; j++) {
- if (! did && state & (0x1 << i)) {
- if (map->modifiermap[k]) {
- KeyCode key = map->modifiermap[k];
- KeySym ks = XKeycodeToKeysym(dpy, key, 0);
- char *nm = XKeysymToString(ks);
- rfbLog("toggling: %03d / %03d -- %s\n", key, ks, nm ? nm : "BadKey");
- did = 1;
- XTestFakeKeyEvent_wr(dpy, key, True, CurrentTime);
- usleep(10*1000);
- XTestFakeKeyEvent_wr(dpy, key, False, CurrentTime);
- XFlush_wr(dpy);
- }
- }
- k++;
- }
- }
- XFreeModifiermap(map);
- XFlush_wr(dpy);
- rfbLog("state: 0x%x\n", mask_state());
-#endif
-}
-
-/*
- * Kludge for -norepeat option: we turn off keystroke autorepeat in
- * the X server when clients are connected. This may annoy people at
- * the physical display. We do this because 'key down' and 'key up'
- * user input events may be separated by 100s of ms due to screen fb
- * processing or link latency, thereby inducing the X server to apply
- * autorepeat when it should not. Since the *client* is likely doing
- * keystroke autorepeating as well, it kind of makes sense to shut it
- * off if no one is at the physical display...
- */
-static int save_auto_repeat = -1;
-
-int get_autorepeat_state(void) {
-#if NO_X11
- RAWFB_RET(0)
- return 0;
-#else
- XKeyboardState kstate;
-
- RAWFB_RET(0)
-
- X_LOCK;
- XGetKeyboardControl(dpy, &kstate);
- X_UNLOCK;
- return kstate.global_auto_repeat;
-#endif /* NO_X11 */
-}
-
-int get_initial_autorepeat_state(void) {
- if (save_auto_repeat < 0) {
- save_auto_repeat = get_autorepeat_state();
- }
- return save_auto_repeat;
-}
-
-void autorepeat(int restore, int bequiet) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!restore || !bequiet) {}
- return;
-#else
- int global_auto_repeat;
- XKeyboardControl kctrl;
-
- RAWFB_RET_VOID
-
- if (restore) {
- if (save_auto_repeat < 0) {
- return; /* nothing to restore */
- }
- global_auto_repeat = get_autorepeat_state();
- /* read state and skip restore if equal (e.g. no clients) */
- if (global_auto_repeat == save_auto_repeat) {
- return;
- }
-
- X_LOCK;
- kctrl.auto_repeat_mode = save_auto_repeat;
- XChangeKeyboardControl(dpy, KBAutoRepeatMode, &kctrl);
- XFlush_wr(dpy);
- X_UNLOCK;
-
- if (! bequiet && ! quiet) {
- rfbLog("Restored X server key autorepeat to: %d\n",
- save_auto_repeat);
- }
- } else {
- global_auto_repeat = get_autorepeat_state();
- if (save_auto_repeat < 0) {
- /*
- * we only remember the state at startup
- * to avoid confusing ourselves later on.
- */
- save_auto_repeat = global_auto_repeat;
- }
-
- X_LOCK;
- kctrl.auto_repeat_mode = AutoRepeatModeOff;
- XChangeKeyboardControl(dpy, KBAutoRepeatMode, &kctrl);
- XFlush_wr(dpy);
- X_UNLOCK;
-
- if (! bequiet && ! quiet) {
- rfbLog("Disabled X server key autorepeat.\n");
- if (no_repeat_countdown >= 0) {
- rfbLog(" to force back on run: 'xset r on' (%d "
- "times)\n", no_repeat_countdown+1);
- }
- }
- }
-#endif /* NO_X11 */
-}
-
-/*
- * We periodically delete any keysyms we have added, this is to
- * lessen our effect on the X server state if we are terminated abruptly
- * and cannot clear them and also to clear out any strange little used
- * ones that would just fill up the keymapping.
- */
-void check_add_keysyms(void) {
- static time_t last_check = 0;
- int clear_freq = 300, quiet = 1, count;
- time_t now = time(NULL);
-
- if (unixpw_in_progress) return;
-
- if (now > last_check + clear_freq) {
- count = count_added_keycodes();
- /*
- * only really delete if they have not typed recently
- * and we have added 8 or more.
- */
- if (now > last_keyboard_input + 5 && count >= 8) {
- X_LOCK;
- delete_added_keycodes(quiet);
- X_UNLOCK;
- }
- last_check = now;
- }
-}
-
-static KeySym added_keysyms[0x100];
-
-/* these are just for rfbLog messages: */
-static KeySym alltime_added_keysyms[1024];
-static int alltime_len = 1024;
-static int alltime_num = 0;
-
-int add_keysym(KeySym keysym) {
- static int first = 1;
- int n;
-#if NO_X11
- if (first) {
- for (n=0; n < 0x100; n++) {
- added_keysyms[n] = NoSymbol;
- }
- first = 0;
- }
- RAWFB_RET(0)
- if (!keysym) {}
- return 0;
-#else
- int minkey, maxkey, syms_per_keycode;
- int kc, ret = 0;
- KeySym *keymap;
-
- if (first) {
- for (n=0; n < 0x100; n++) {
- added_keysyms[n] = NoSymbol;
- }
- first = 0;
- }
-
- RAWFB_RET(0)
-
- if (keysym == NoSymbol) {
- return 0;
- }
- /* there can be a race before MappingNotify */
- for (n=0; n < 0x100; n++) {
- if (added_keysyms[n] == keysym) {
- return n;
- }
- }
-
- XDisplayKeycodes(dpy, &minkey, &maxkey);
- keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1),
- &syms_per_keycode);
-
- for (kc = minkey+1; kc <= maxkey; kc++) {
- int i, j, didmsg = 0, is_empty = 1;
- char *str;
- KeySym newks[8];
-
- for (n=0; n < syms_per_keycode; n++) {
- if (keymap[ (kc-minkey) * syms_per_keycode + n]
- != NoSymbol) {
- is_empty = 0;
- break;
- }
- }
- if (! is_empty) {
- continue;
- }
-
- for (i=0; i<8; i++) {
- newks[i] = NoSymbol;
- }
- if (add_keysyms == 2) {
- newks[0] = keysym; /* XXX remove me */
- } else {
- for(i=0; i < syms_per_keycode; i++) {
- newks[i] = keysym;
- if (i >= 7) break;
- }
- }
-
- XChangeKeyboardMapping(dpy, kc, syms_per_keycode,
- newks, 1);
-
- if (alltime_num >= alltime_len) {
- didmsg = 1; /* something weird */
- } else {
- for (j=0; j<alltime_num; j++) {
- if (alltime_added_keysyms[j] == keysym) {
- didmsg = 1;
- break;
- }
- }
- }
- if (! didmsg) {
- str = XKeysymToString(keysym);
- rfbLog("added missing keysym to X display: %03d "
- "0x%x \"%s\"\n", kc, keysym, str ? str : "null");
-
- if (alltime_num < alltime_len) {
- alltime_added_keysyms[alltime_num++] = keysym;
- }
- }
-
- XFlush_wr(dpy);
- added_keysyms[kc] = keysym;
- ret = kc;
- break;
- }
- XFree_wr(keymap);
- return ret;
-#endif /* NO_X11 */
-}
-
-static void delete_keycode(KeyCode kc, int bequiet) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!kc || !bequiet) {}
- return;
-#else
- int minkey, maxkey, syms_per_keycode, i;
- KeySym *keymap;
- KeySym ksym, newks[8];
- char *str;
-
- RAWFB_RET_VOID
-
- XDisplayKeycodes(dpy, &minkey, &maxkey);
- keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1),
- &syms_per_keycode);
-
- for (i=0; i<8; i++) {
- newks[i] = NoSymbol;
- }
-
- XChangeKeyboardMapping(dpy, kc, syms_per_keycode, newks, 1);
-
- if (! bequiet && ! quiet) {
- ksym = XKeycodeToKeysym(dpy, kc, 0);
- str = XKeysymToString(ksym);
- rfbLog("deleted keycode from X display: %03d 0x%x \"%s\"\n",
- kc, ksym, str ? str : "null");
- }
-
- XFree_wr(keymap);
- XFlush_wr(dpy);
-#endif /* NO_X11 */
-}
-
-static int count_added_keycodes(void) {
- int kc, count = 0;
- for (kc = 0; kc < 0x100; kc++) {
- if (added_keysyms[kc] != NoSymbol) {
- count++;
- }
- }
- return count;
-}
-
-void delete_added_keycodes(int bequiet) {
- int kc;
- for (kc = 0; kc < 0x100; kc++) {
- if (added_keysyms[kc] != NoSymbol) {
- delete_keycode(kc, bequiet);
- added_keysyms[kc] = NoSymbol;
- }
- }
-}
-
-/*
- * The following is for an experimental -remap option to allow the user
- * to remap keystrokes. It is currently confusing wrt modifiers...
- */
-typedef struct keyremap {
- KeySym before;
- KeySym after;
- int isbutton;
- struct keyremap *next;
-} keyremap_t;
-
-static keyremap_t *keyremaps = NULL;
-
-static void add_remap(char *line) {
- char str1[256], str2[256];
- KeySym ksym1, ksym2;
- int isbtn = 0;
- unsigned int i;
- static keyremap_t *current = NULL;
- keyremap_t *remap;
-
- if (sscanf(line, "%s %s", str1, str2) != 2) {
- rfbLogEnable(1);
- rfbLog("remap: invalid line: %s\n", line);
- clean_up_exit(1);
- }
- if (sscanf(str1, "0x%x", &i) == 1) {
- ksym1 = (KeySym) i;
- } else {
- ksym1 = XStringToKeysym(str1);
- }
- if (sscanf(str2, "0x%x", &i) == 1) {
- ksym2 = (KeySym) i;
- } else {
- ksym2 = XStringToKeysym(str2);
- }
- if (ksym2 == NoSymbol) {
- if (sscanf(str2, "Button%u", &i) == 1) {
- ksym2 = (KeySym) i;
- isbtn = 1;
- }
- }
- if (ksym1 == NoSymbol || ksym2 == NoSymbol) {
- if (strcasecmp(str2, "NoSymbol") && strcasecmp(str2, "None")) {
- rfbLog("warning: skipping invalid remap line: %s", line);
- return;
- }
- }
- remap = (keyremap_t *) malloc((size_t) sizeof(keyremap_t));
- remap->before = ksym1;
- remap->after = ksym2;
- remap->isbutton = isbtn;
- remap->next = NULL;
-
- rfbLog("remapping: (%s, 0x%x) -> (%s, 0x%x) isbtn=%d\n", str1,
- ksym1, str2, ksym2, isbtn);
-
- if (keyremaps == NULL) {
- keyremaps = remap;
- } else {
- current->next = remap;
- }
- current = remap;
-}
-
-static void add_dead_keysyms(char *str) {
- char *p, *q;
- int i;
- char *list[] = {
- "g grave dead_grave",
- "a acute dead_acute",
- "c asciicircum dead_circumflex",
- "t asciitilde dead_tilde",
- "m macron dead_macron",
- "b breve dead_breve",
- "D abovedot dead_abovedot",
- "d diaeresis dead_diaeresis",
- "o degree dead_abovering",
- "A doubleacute dead_doubleacute",
- "r caron dead_caron",
- "e cedilla dead_cedilla",
-/* "x XXX-ogonek dead_ogonek", */
-/* "x XXX-belowdot dead_belowdot", */
-/* "x XXX-hook dead_hook", */
-/* "x XXX-horn dead_horn", */
- NULL
- };
-
- p = str;
-
- while (*p != '\0') {
- if (isspace((unsigned char) (*p))) {
- *p = '\0';
- }
- p++;
- }
-
- if (!strcmp(str, "DEAD")) {
- for (i = 0; list[i] != NULL; i++) {
- p = list[i] + 2;
- add_remap(p);
- }
- } else if (!strcmp(str, "DEAD=missing")) {
- for (i = 0; list[i] != NULL; i++) {
- KeySym ksym, ksym2;
- int inmap = 0;
-
- p = strdup(list[i] + 2);
- q = strchr(p, ' ');
- if (q == NULL) {
- free(p);
- continue;
- }
- *q = '\0';
- ksym = XStringToKeysym(p);
- *q = ' ';
- if (ksym == NoSymbol) {
- free(p);
- continue;
- }
- if (XKeysymToKeycode(dpy, ksym)) {
- inmap = 1;
- }
-#if LIBVNCSERVER_HAVE_XKEYBOARD
- if (! inmap && xkb_present && dpy) {
- int kc, grp, lvl;
- for (kc = 0; kc < 0x100; kc++) {
- for (grp = 0; grp < 4; grp++) {
- for (lvl = 0; lvl < 8; lvl++) {
- ksym2 = XkbKeycodeToKeysym(dpy,
- kc, grp, lvl);
- if (ksym2 == NoSymbol) {
- continue;
- }
- if (ksym2 == ksym) {
- inmap = 1;
- break;
- }
- }
- }
- }
- }
-#else
- if ((ksym2 = 0)) {}
-#endif
- if (! inmap) {
- add_remap(p);
- }
- free(p);
- }
- } else if ((p = strchr(str, '=')) != NULL) {
- while (*p != '\0') {
- for (i = 0; list[i] != NULL; i++) {
- q = list[i];
- if (*p == *q) {
- q += 2;
- add_remap(q);
- break;
- }
- }
- p++;
- }
- }
-}
-
-/*
- * process the -remap string (file or mapping string)
- */
-void initialize_remap(char *infile) {
- FILE *in;
- char *p, *q, line[256];
-
- if (keyremaps != NULL) {
- /* free last remapping */
- keyremap_t *next_remap, *curr_remap = keyremaps;
- while (curr_remap != NULL) {
- next_remap = curr_remap->next;
- free(curr_remap);
- curr_remap = next_remap;
- }
- keyremaps = NULL;
- }
- if (infile == NULL || *infile == '\0') {
- /* just unset remapping */
- return;
- }
-
- in = fopen(infile, "r");
- if (in == NULL) {
- /* assume cmd line key1-key2,key3-key4 */
- if (strstr(infile, "DEAD") == infile) {
- ;
- } else if (!strchr(infile, '-')) {
- rfbLogEnable(1);
- rfbLog("remap: cannot open: %s\n", infile);
- rfbLogPerror("fopen");
- clean_up_exit(1);
- }
- if ((in = tmpfile()) == NULL) {
- rfbLogEnable(1);
- rfbLog("remap: cannot open tmpfile for %s\n", infile);
- rfbLogPerror("tmpfile");
- clean_up_exit(1);
- }
-
- /* copy in the string to file format */
- p = infile;
- while (*p) {
- if (*p == '-') {
- fprintf(in, " ");
- } else if (*p == ',' || *p == ' ' || *p == '\t') {
- fprintf(in, "\n");
- } else {
- fprintf(in, "%c", *p);
- }
- p++;
- }
- fprintf(in, "\n");
- fflush(in);
- rewind(in);
- }
-
- while (fgets(line, 256, in) != NULL) {
- p = lblanks(line);
- if (*p == '\0') {
- continue;
- }
- if (strchr(line, '#')) {
- continue;
- }
-
- if (strstr(p, "DEAD") == p) {
- add_dead_keysyms(p);
- continue;
- }
- if ((q = strchr(line, '-')) != NULL) {
- /* allow Keysym1-Keysym2 notation */
- *q = ' ';
- }
- add_remap(p);
- }
- fclose(in);
-}
-
-/*
- * preliminary support for using the Xkb (XKEYBOARD) extension for handling
- * user input. inelegant, slow, and incomplete currently... but initial
- * tests show it is useful for some setups.
- */
-typedef struct keychar {
- KeyCode code;
- int group;
- int level;
-} keychar_t;
-
-/* max number of key groups and shift levels we consider */
-#define GRP 4
-#define LVL 8
-static int lvl_max, grp_max, kc_min, kc_max;
-static KeySym xkbkeysyms[0x100][GRP][LVL];
-static unsigned int xkbstate[0x100][GRP][LVL];
-static unsigned int xkbignore[0x100][GRP][LVL];
-static unsigned int xkbmodifiers[0x100][GRP][LVL];
-static int multi_key[0x100], mode_switch[0x100], skipkeycode[0x100];
-static int shift_keys[0x100];
-
-/*
- * for trying to order the keycodes to avoid problems, note the
- * *first* keycode bound to it. kc_vec will be a permutation
- * of 1...256 to get them in the preferred order.
- */
-static int kc_vec[0x100];
-static int kc1_shift, kc1_control, kc1_caplock, kc1_alt;
-static int kc1_meta, kc1_numlock, kc1_super, kc1_hyper;
-static int kc1_mode_switch, kc1_iso_level3_shift, kc1_multi_key;
-
-int sloppy_key_check(int key, rfbBool down, rfbKeySym keysym, int *new_kc) {
- if (!sloppy_keys) {
- return 0;
- }
-
- RAWFB_RET(0)
-#if NO_X11
- if (!key || !down || !keysym || !new_kc) {}
- return 0;
-#else
-
- if (!down && !keycode_state[key] && !IsModifierKey(keysym)) {
- int i, cnt = 0, downkey = -1;
- int nmods_down = track_mod_state(NoSymbol, FALSE, FALSE);
- int mods_down[256];
-
- if (nmods_down) {
- /* tracking to skip down modifier keycodes. */
- for(i=0; i<256; i++) {
- mods_down[i] = 0;
- }
- i = 0;
- while (simple_mods[i] != NoSymbol) {
- KeySym ksym = simple_mods[i];
- KeyCode k = XKeysymToKeycode(dpy, ksym);
- if (k != NoSymbol && keycode_state[(int) k]) {
- mods_down[(int) k] = 1;
- }
-
- i++;
- }
- }
- /*
- * the keycode is already up... look for a single one
- * (non modifier) that is down
- */
- for (i=0; i<256; i++) {
- if (keycode_state[i]) {
- if (nmods_down && mods_down[i]) {
- continue;
- }
- cnt++;
- downkey = i;
- }
- }
- if (cnt == 1) {
- if (debug_keyboard) {
- fprintf(stderr, " sloppy_keys: %d/0x%x "
- "-> %d/0x%x (nmods: %d)\n", (int) key,
- (int) key, downkey, downkey, nmods_down);
- }
- *new_kc = downkey;
- return 1;
- }
- }
- return 0;
-#endif /* NO_X11 */
-}
-
-#if !LIBVNCSERVER_HAVE_XKEYBOARD || SKIP_XKB
-
-/* empty functions for no xkb */
-static void initialize_xkb_modtweak(void) {}
-static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
- rfbClientPtr client) {
- if (!client || !down || !keysym) {} /* unused vars warning: */
-}
-void switch_to_xkb_if_better(void) {}
-
-#else
-
-void switch_to_xkb_if_better(void) {
- KeySym keysym, *keymap;
- int miss_noxkb[256], miss_xkb[256], missing_noxkb = 0, missing_xkb = 0;
- int i, j, k, n, minkey, maxkey, syms_per_keycode;
- int syms_gt_4 = 0;
- int kc, grp, lvl;
-
- /* non-alphanumeric on us keyboard */
- KeySym must_have[] = {
- XK_exclam,
- XK_at,
- XK_numbersign,
- XK_dollar,
- XK_percent,
-/* XK_asciicircum, */
- XK_ampersand,
- XK_asterisk,
- XK_parenleft,
- XK_parenright,
- XK_underscore,
- XK_plus,
- XK_minus,
- XK_equal,
- XK_bracketleft,
- XK_bracketright,
- XK_braceleft,
- XK_braceright,
- XK_bar,
- XK_backslash,
- XK_semicolon,
-/* XK_apostrophe, */
- XK_colon,
- XK_quotedbl,
- XK_comma,
- XK_period,
- XK_less,
- XK_greater,
- XK_slash,
- XK_question,
-/* XK_asciitilde, */
-/* XK_grave, */
- NoSymbol
- };
-
- if (! use_modifier_tweak || got_noxkb) {
- return;
- }
- if (use_xkb_modtweak) {
- /* already using it */
- return;
- }
- RAWFB_RET_VOID
-
- XDisplayKeycodes(dpy, &minkey, &maxkey);
-
- keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1),
- &syms_per_keycode);
-
- /* handle alphabetic char with only one keysym (no upper + lower) */
- for (i = minkey; i <= maxkey; i++) {
- KeySym lower, upper;
- /* 2nd one */
- keysym = keymap[(i - minkey) * syms_per_keycode + 1];
- if (keysym != NoSymbol) {
- continue;
- }
- /* 1st one */
- keysym = keymap[(i - minkey) * syms_per_keycode + 0];
- if (keysym == NoSymbol) {
- continue;
- }
- XConvertCase(keysym, &lower, &upper);
- if (lower != upper) {
- keymap[(i - minkey) * syms_per_keycode + 0] = lower;
- keymap[(i - minkey) * syms_per_keycode + 1] = upper;
- }
- }
-
- k = 0;
- while (must_have[k] != NoSymbol) {
- int gotit = 0;
- KeySym must = must_have[k];
- for (i = minkey; i <= maxkey; i++) {
- for (j = 0; j < syms_per_keycode; j++) {
- keysym = keymap[(i-minkey) * syms_per_keycode + j];
- if (j >= 4) {
- if (k == 0 && keysym != NoSymbol) {
- /* for k=0 count the high keysyms */
- syms_gt_4++;
- if (debug_keyboard > 1) {
- char *str = XKeysymToString(keysym);
- fprintf(stderr, "- high keysym mapping"
- ": at %3d j=%d "
- "'%s'\n", i, j, str ? str : "null");
- }
- }
- continue;
- }
- if (keysym == must) {
- if (debug_keyboard > 1) {
- char *str = XKeysymToString(must);
- fprintf(stderr, "- at %3d j=%d found "
- "'%s'\n", i, j, str ? str : "null");
- }
- /* n.b. do not break, see syms_gt_4 above. */
- gotit = 1;
- }
- }
- }
- if (! gotit) {
- if (debug_keyboard > 1) {
- char *str = XKeysymToString(must);
- KeyCode kc = XKeysymToKeycode(dpy, must);
- fprintf(stderr, "- did not find 0x%lx '%s'\t"
- "Ks2Kc: %d\n", must, str ? str:"null", kc);
- if (kc != None) {
- int j2;
- for(j2=0; j2<syms_per_keycode; j2++) {
- keysym = keymap[(kc-minkey) *
- syms_per_keycode + j2];
- fprintf(stderr, " %d=0x%lx",
- j2, keysym);
- }
- fprintf(stderr, "\n");
- }
- }
- missing_noxkb++;
- miss_noxkb[k] = 1;
- } else {
- miss_noxkb[k] = 0;
- }
- k++;
- }
- n = k;
-
- XFree_wr(keymap);
- if (missing_noxkb == 0 && syms_per_keycode > 4 && syms_gt_4 >= 0) {
- /* we used to have syms_gt_4 >= 8, now always on. */
- if (! raw_fb_str) {
- rfbLog("\n");
- rfbLog("XKEYBOARD: number of keysyms per keycode %d is greater\n", syms_per_keycode);
- rfbLog(" than 4 and %d keysyms are mapped above 4.\n", syms_gt_4);
- rfbLog(" Automatically switching to -xkb mode.\n");
- rfbLog(" If this makes the key mapping worse you can\n");
- rfbLog(" disable it with the \"-noxkb\" option.\n");
- rfbLog(" Also, remember \"-remap DEAD\" for accenting characters.\n");
- rfbLog("\n");
- }
-
- use_xkb_modtweak = 1;
- return;
-
- } else if (missing_noxkb == 0) {
- if (! raw_fb_str) {
- rfbLog("\n");
- rfbLog("XKEYBOARD: all %d \"must have\" keysyms accounted for.\n", n);
- rfbLog(" Not automatically switching to -xkb mode.\n");
- rfbLog(" If some keys still cannot be typed, try using -xkb.\n");
- rfbLog(" Also, remember \"-remap DEAD\" for accenting characters.\n");
- rfbLog("\n");
- }
- return;
- }
-
- for (k=0; k<n; k++) {
- miss_xkb[k] = 1;
- }
-
- for (kc = 0; kc < 0x100; kc++) {
- for (grp = 0; grp < GRP; grp++) {
- for (lvl = 0; lvl < LVL; lvl++) {
- /* look up the Keysym, if any */
- keysym = XkbKeycodeToKeysym(dpy, kc, grp, lvl);
- if (keysym == NoSymbol) {
- continue;
- }
- for (k=0; k<n; k++) {
- if (keysym == must_have[k]) {
- miss_xkb[k] = 0;
- }
- }
- }
- }
- }
-
- for (k=0; k<n; k++) {
- if (miss_xkb[k]) {
- missing_xkb++;
- }
- }
-
- rfbLog("\n");
- if (missing_xkb < missing_noxkb) {
- rfbLog("XKEYBOARD:\n");
- rfbLog("Switching to -xkb mode to recover these keysyms:\n");
- } else {
- rfbLog("XKEYBOARD: \"must have\" keysyms better accounted"
- " for\n");
- rfbLog("under -noxkb mode: not switching to -xkb mode:\n");
- }
-
- rfbLog(" xkb noxkb Keysym (\"X\" means present)\n");
- rfbLog(" --- ----- -----------------------------\n");
- for (k=0; k<n; k++) {
- char *xx, *xn, *name;
-
- keysym = must_have[k];
- if (keysym == NoSymbol) {
- continue;
- }
- if (!miss_xkb[k] && !miss_noxkb[k]) {
- continue;
- }
- if (miss_xkb[k]) {
- xx = " ";
- } else {
- xx = " X ";
- }
- if (miss_noxkb[k]) {
- xn = " ";
- } else {
- xn = " X ";
- }
- name = XKeysymToString(keysym);
- rfbLog(" %s %s 0x%lx %s\n", xx, xn, keysym,
- name ? name : "null");
- }
- rfbLog("\n");
-
- if (missing_xkb < missing_noxkb) {
- rfbLog(" If this makes the key mapping worse you can\n");
- rfbLog(" disable it with the \"-noxkb\" option.\n");
- rfbLog("\n");
-
- use_xkb_modtweak = 1;
-
- } else {
- rfbLog(" If some keys still cannot be typed, try using"
- " -xkb.\n");
- rfbLog(" Also, remember \"-remap DEAD\" for accenting"
- " characters.\n");
- }
- rfbLog("\n");
-}
-
-/* sets up all the keymapping info via Xkb API */
-
-static void initialize_xkb_modtweak(void) {
- KeySym ks;
- int kc, grp, lvl, k;
- unsigned int state;
-
-/*
- * Here is a guide:
-
-Workarounds arrays:
-
-multi_key[] indicates which keycodes have Multi_key (Compose)
- bound to them.
-mode_switch[] indicates which keycodes have Mode_switch (AltGr)
- bound to them.
-shift_keys[] indicates which keycodes have Shift bound to them.
-skipkeycode[] indicates which keycodes are to be skipped
- for any lookups from -skip_keycodes option.
-
-Groups and Levels, here is an example:
-
- ^ --------
- | L2 | A AE |
- shift | |
- level L1 | a ae |
- --------
- G1 G2
-
- group ->
-
-Traditionally this it all a key could do. L1 vs. L2 selected via Shift
-and G1 vs. G2 selected via Mode_switch. Up to 4 Keysyms could be bound
-to a key. See initialize_modtweak() for an example of using that type
-of keymap from XGetKeyboardMapping().
-
-Xkb gives us up to 4 groups and 63 shift levels per key, with the
-situation being potentially different for each key. This is complicated,
-and I don't claim to understand it all, but in the following we just think
-of ranging over the group and level indices as covering all of the cases.
-This gives us an accurate view of the keymap. The main tricky part
-is mapping between group+level and modifier state.
-
-On current linux/XFree86 setups (Xkb is enabled by default) the
-information from XGetKeyboardMapping() (evidently the compat map)
-is incomplete and inaccurate, so we are really forced to use the
-Xkb API.
-
-xkbkeysyms[] For a (keycode,group,level) holds the KeySym (0 for none)
-xkbstate[] For a (keycode,group,level) holds the corresponding
- modifier state needed to get that KeySym
-xkbignore[] For a (keycode,group,level) which modifiers can be
- ignored (the 0 bits can be ignored).
-xkbmodifiers[] For the KeySym bound to this (keycode,group,level) store
- the modifier mask.
- *
- */
-
- RAWFB_RET_VOID
-
- /* initialize all the arrays: */
- for (kc = 0; kc < 0x100; kc++) {
- multi_key[kc] = 0;
- mode_switch[kc] = 0;
- skipkeycode[kc] = 0;
- shift_keys[kc] = 0;
-
- for (grp = 0; grp < GRP; grp++) {
- for (lvl = 0; lvl < LVL; lvl++) {
- xkbkeysyms[kc][grp][lvl] = NoSymbol;
- xkbmodifiers[kc][grp][lvl] = -1;
- xkbstate[kc][grp][lvl] = -1;
- }
- }
- }
-
- /*
- * the array is 256*LVL*GRP, but we can make the searched region
- * smaller by computing the actual ranges.
- */
- lvl_max = 0;
- grp_max = 0;
- kc_max = 0;
- kc_min = 0x100;
-
- /* first keycode for a modifier type (multi_key too) */
- kc1_shift = -1;
- kc1_control = -1;
- kc1_caplock = -1;
- kc1_alt = -1;
- kc1_meta = -1;
- kc1_numlock = -1;
- kc1_super = -1;
- kc1_hyper = -1;
- kc1_mode_switch = -1;
- kc1_iso_level3_shift = -1;
- kc1_multi_key = -1;
-
- /*
- * loop over all possible (keycode, group, level) triples
- * and record what we find for it:
- */
- if (debug_keyboard) {
- rfbLog("initialize_xkb_modtweak: XKB keycode -> keysyms "
- "mapping info:\n");
- }
- for (kc = 0; kc < 0x100; kc++) {
- for (grp = 0; grp < GRP; grp++) {
- for (lvl = 0; lvl < LVL; lvl++) {
- unsigned int ms, mods;
- int state_save = -1, mods_save = -1;
- KeySym ks2;
-
- /* look up the Keysym, if any */
- ks = XkbKeycodeToKeysym(dpy, kc, grp, lvl);
- xkbkeysyms[kc][grp][lvl] = ks;
-
- /* if no Keysym, on to next */
- if (ks == NoSymbol) {
- continue;
- }
- /*
- * for various workarounds, note where these special
- * keys are bound to.
- */
- if (ks == XK_Multi_key) {
- multi_key[kc] = lvl+1;
- }
- if (ks == XK_Mode_switch) {
- mode_switch[kc] = lvl+1;
- }
- if (ks == XK_Shift_L || ks == XK_Shift_R) {
- shift_keys[kc] = lvl+1;
- }
-
- if (ks == XK_Shift_L || ks == XK_Shift_R) {
- if (kc1_shift == -1) {
- kc1_shift = kc;
- }
- }
- if (ks == XK_Control_L || ks == XK_Control_R) {
- if (kc1_control == -1) {
- kc1_control = kc;
- }
- }
- if (ks == XK_Caps_Lock || ks == XK_Caps_Lock) {
- if (kc1_caplock == -1) {
- kc1_caplock = kc;
- }
- }
- if (ks == XK_Alt_L || ks == XK_Alt_R) {
- if (kc1_alt == -1) {
- kc1_alt = kc;
- }
- }
- if (ks == XK_Meta_L || ks == XK_Meta_R) {
- if (kc1_meta == -1) {
- kc1_meta = kc;
- }
- }
- if (ks == XK_Num_Lock) {
- if (kc1_numlock == -1) {
- kc1_numlock = kc;
- }
- }
- if (ks == XK_Super_L || ks == XK_Super_R) {
- if (kc1_super == -1) {
- kc1_super = kc;
- }
- }
- if (ks == XK_Hyper_L || ks == XK_Hyper_R) {
- if (kc1_hyper == -1) {
- kc1_hyper = kc;
- }
- }
- if (ks == XK_Mode_switch) {
- if (kc1_mode_switch == -1) {
- kc1_mode_switch = kc;
- }
- }
- if (ks == XK_ISO_Level3_Shift) {
- if (kc1_iso_level3_shift == -1) {
- kc1_iso_level3_shift = kc;
- }
- }
- if (ks == XK_Multi_key) { /* not a modifier.. */
- if (kc1_multi_key == -1) {
- kc1_multi_key = kc;
- }
- }
-
- /*
- * record maximum extent for group/level indices
- * and keycode range:
- */
- if (grp > grp_max) {
- grp_max = grp;
- }
- if (lvl > lvl_max) {
- lvl_max = lvl;
- }
- if (kc > kc_max) {
- kc_max = kc;
- }
- if (kc < kc_min) {
- kc_min = kc;
- }
-
- /*
- * lookup on *keysym* (i.e. not kc, grp, lvl)
- * and get the modifier mask. this is 0 for
- * most keysyms, only non zero for modifiers.
- */
- ms = XkbKeysymToModifiers(dpy, ks);
- xkbmodifiers[kc][grp][lvl] = ms;
-
- /*
- * Amusing heuristic (may have bugs). There are
- * 8 modifier bits, so 256 possible modifier
- * states. We loop over all of them for this
- * keycode (simulating Key "events") and ask
- * XkbLookupKeySym to tell us the Keysym. Once it
- * matches the Keysym we have for this (keycode,
- * group, level), gotten via XkbKeycodeToKeysym()
- * above, we then (hopefully...) know that state
- * of modifiers needed to generate this keysym.
- *
- * Yes... keep your fingers crossed.
- *
- * Note that many of the 256 states give the
- * Keysym, we just need one, and we take the
- * first one found.
- */
- state = 0;
- while(state < 256) {
- if (XkbLookupKeySym(dpy, kc, state, &mods,
- &ks2)) {
-
- /* save these for workaround below */
- if (state_save == -1) {
- state_save = state;
- mods_save = mods;
- }
- if (ks2 == ks) {
- /*
- * zero the irrelevant bits
- * by anding with mods.
- */
- xkbstate[kc][grp][lvl]
- = state & mods;
- /*
- * also remember the irrelevant
- * bits since it is handy.
- */
- xkbignore[kc][grp][lvl] = mods;
-
- break;
- }
- }
- state++;
- }
- if (xkbstate[kc][grp][lvl] == (unsigned int) -1
- && grp == 1) {
- /*
- * Hack on Solaris 9 for Mode_switch
- * for Group2 characters. We force the
- * Mode_switch modifier bit on.
- * XXX Need to figure out better what is
- * happening here. Is compat on somehow??
- */
- unsigned int ms2;
- ms2 = XkbKeysymToModifiers(dpy, XK_Mode_switch);
-
- xkbstate[kc][grp][lvl]
- = (state_save & mods_save) | ms2;
-
- xkbignore[kc][grp][lvl] = mods_save | ms2;
- }
-
- if (debug_keyboard) {
- char *str;
- fprintf(stderr, " %03d G%d L%d mod=%s ",
- kc, grp+1, lvl+1, bitprint(ms, 8));
- fprintf(stderr, "state=%s ",
- bitprint(xkbstate[kc][grp][lvl], 8));
- fprintf(stderr, "ignore=%s ",
- bitprint(xkbignore[kc][grp][lvl], 8));
- str = XKeysymToString(ks);
- fprintf(stderr, " ks=0x%08lx \"%s\"\n",
- ks, str ? str : "null");
- }
- }
- }
- }
-
- /*
- * kc_vec will be used in some places to find modifiers, etc
- * we apply some permutations to it as workarounds.
- */
- for (kc = 0; kc < 0x100; kc++) {
- kc_vec[kc] = kc;
- }
-
- if (kc1_mode_switch != -1 && kc1_iso_level3_shift != -1) {
- if (kc1_mode_switch < kc1_iso_level3_shift) {
- /* we prefer XK_ISO_Level3_Shift: */
- kc_vec[kc1_mode_switch] = kc1_iso_level3_shift;
- kc_vec[kc1_iso_level3_shift] = kc1_mode_switch;
- }
- }
- /* any more? need to watch for undoing the above. */
-
- /*
- * process the user supplied -skip_keycodes string.
- * This is presumably a list if "ghost" keycodes, the X server
- * thinks they exist, but they do not. ghosts can lead to
- * ambiguities in the reverse map: Keysym -> KeyCode + Modstate,
- * so if we can ignore them so much the better. Presumably the
- * user can never generate them from the physical keyboard.
- * There may be other reasons to deaden some keys.
- */
- if (skip_keycodes != NULL) {
- char *p, *str = strdup(skip_keycodes);
- p = strtok(str, ", \t\n\r");
- while (p) {
- k = 1;
- if (sscanf(p, "%d", &k) != 1 || k < 0 || k >= 0x100) {
- rfbLogEnable(1);
- rfbLog("invalid skip_keycodes: %s %s\n",
- skip_keycodes, p);
- clean_up_exit(1);
- }
- skipkeycode[k] = 1;
- p = strtok(NULL, ", \t\n\r");
- }
- free(str);
- }
- if (debug_keyboard) {
- fprintf(stderr, "grp_max=%d lvl_max=%d\n", grp_max, lvl_max);
- }
-}
-
-static short **score_hint = NULL;
-/*
- * Called on user keyboard input. Try to solve the reverse mapping
- * problem: KeySym (from VNC client) => KeyCode(s) to press to generate
- * it. The one-to-many KeySym => KeyCode mapping makes it difficult, as
- * does working out what changes to the modifier keypresses are needed.
- */
-static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
- rfbClientPtr client) {
-
- int kc, grp, lvl, i, kci;
- int kc_f[0x100], grp_f[0x100], lvl_f[0x100], state_f[0x100], found;
- int ignore_f[0x100];
- unsigned int state = 0;
-
-
- /* these are used for finding modifiers, etc */
- XkbStateRec kbstate;
- int got_kbstate = 0;
- int Kc_f, Grp_f = 0, Lvl_f = 0;
-# define KLAST 10
- static int Kc_last_down[KLAST];
- static KeySym Ks_last_down[KLAST];
- static int klast = 0, khints = 1, anydown = 1;
- static int cnt = 0;
-
- if (!client || !down || !keysym) {} /* unused vars warning: */
-
- RAWFB_RET_VOID
-
- X_LOCK;
-
- if (klast == 0) {
- int i, j;
- for (i=0; i<KLAST; i++) {
- Kc_last_down[i] = -1;
- Ks_last_down[i] = NoSymbol;
- }
- if (getenv("NOKEYHINTS")) {
- khints = 0;
- }
- if (getenv("NOANYDOWN")) {
- anydown = 0;
- }
- if (getenv("KEYSDOWN")) {
- klast = atoi(getenv("KEYSDOWN"));
- if (klast < 1) klast = 1;
- if (klast > KLAST) klast = KLAST;
- } else {
- klast = 3;
- }
- if (khints && score_hint == NULL) {
- score_hint = (short **) malloc(0x100 * sizeof(short *));
- for (i=0; i<0x100; i++) {
- score_hint[i] = (short *) malloc(0x100 * sizeof(short));
- }
-
- for (i=0; i<0x100; i++) {
- for (j=0; j<0x100; j++) {
- score_hint[i][j] = -1;
- }
- }
- }
- }
- cnt++;
- if (cnt % 100 && khints && score_hint != NULL) {
- int i, j;
- for (i=0; i<0x100; i++) {
- for (j=0; j<0x100; j++) {
- score_hint[i][j] = -1;
- }
- }
- }
-
- if (debug_keyboard) {
- char *str = XKeysymToString(keysym);
-
- if (debug_keyboard > 1) {
- rfbLog("----------start-xkb_tweak_keyboard (%s) "
- "--------\n", down ? "DOWN" : "UP");
- }
-
- rfbLog("xkb_tweak_keyboard: %s keysym=0x%x \"%s\"\n",
- down ? "down" : "up", (int) keysym, str ? str : "null");
- }
-
- /*
- * set everything to not-yet-found.
- * these "found" arrays (*_f) let us dynamically consider the
- * one-to-many Keysym -> Keycode issue. we set the size at 256,
- * but of course only very few will be found.
- */
- for (i = 0; i < 0x100; i++) {
- kc_f[i] = -1;
- grp_f[i] = -1;
- lvl_f[i] = -1;
- state_f[i] = -1;
- ignore_f[i] = -1;
- }
- found = 0;
-
- /*
- * loop over all (keycode, group, level) triples looking for
- * matching keysyms. Amazingly this isn't slow (but maybe if
- * you type really fast...). Hash lookup into a linked list of
- * (keycode,grp,lvl) triples would be the way to improve this
- * in the future if needed.
- */
- for (kc = kc_min; kc <= kc_max; kc++) {
- for (grp = 0; grp < grp_max+1; grp++) {
- for (lvl = 0; lvl < lvl_max+1; lvl++) {
- if (keysym != xkbkeysyms[kc][grp][lvl]) {
- continue;
- }
- /* got a keysym match */
- state = xkbstate[kc][grp][lvl];
-
- if (debug_keyboard > 1) {
- char *s1, *s2;
- s1 = XKeysymToString(XKeycodeToKeysym(dpy,
- kc, 0));
- if (! s1) s1 = "null";
- s2 = XKeysymToString(keysym);
- if (! s2) s2 = "null";
- fprintf(stderr, " got match kc=%03d=0x%02x G%d"
- " L%d ks=0x%x \"%s\" (basesym: \"%s\")\n",
- kc, kc, grp+1, lvl+1, keysym, s2, s1);
- fprintf(stderr, " need state: %s\n",
- bitprint(state, 8));
- fprintf(stderr, " ignorable : %s\n",
- bitprint(xkbignore[kc][grp][lvl], 8));
- }
-
- /* save it if state is OK and not told to skip */
- if (state == (unsigned int) -1) {
- continue;
- }
- if (skipkeycode[kc] && debug_keyboard) {
- fprintf(stderr, " xxx skipping keycode: %d "
- "G%d/L%d\n", kc, grp+1, lvl+1);
- }
- if (skipkeycode[kc]) {
- continue;
- }
- if (found > 0 && kc == kc_f[found-1]) {
- /* ignore repeats for same keycode */
- continue;
- }
- kc_f[found] = kc;
- grp_f[found] = grp;
- lvl_f[found] = lvl;
- state_f[found] = state;
- ignore_f[found] = xkbignore[kc][grp][lvl];
- found++;
- }
- }
- }
-
-#define PKBSTATE \
- fprintf(stderr, " --- current mod state:\n"); \
- fprintf(stderr, " mods : %s\n", bitprint(kbstate.mods, 8)); \
- fprintf(stderr, " base_mods : %s\n", bitprint(kbstate.base_mods, 8)); \
- fprintf(stderr, " latch_mods: %s\n", bitprint(kbstate.latched_mods, 8)); \
- fprintf(stderr, " lock_mods : %s\n", bitprint(kbstate.locked_mods, 8)); \
- fprintf(stderr, " compat : %s\n", bitprint(kbstate.compat_state, 8));
-
- /*
- * Now get the current state of the keyboard from the X server.
- * This seems to be the safest way to go as opposed to our
- * keeping track of the modifier state on our own. Again,
- * this is fortunately not too slow.
- */
-
- if (debug_keyboard > 1) {
- /* get state early for debug output */
- XkbGetState(dpy, XkbUseCoreKbd, &kbstate);
- got_kbstate = 1;
- PKBSTATE
- }
-
- if (!found && add_keysyms && keysym && ! IsModifierKey(keysym)) {
- int new_kc = add_keysym(keysym);
- if (new_kc != 0) {
- found = 1;
- kc_f[0] = new_kc;
- grp_f[0] = 0;
- lvl_f[0] = 0;
- state_f[0] = 0;
- }
- }
-
- if (!found && debug_keyboard) {
- char *str = XKeysymToString(keysym);
- fprintf(stderr, " *** NO key found for: 0x%x %s "
- "*keystroke ignored*\n", keysym, str ? str : "null");
- }
- if (!found) {
- X_UNLOCK;
- return;
- }
-
- /*
- * we try to optimize here if found > 1
- * e.g. minimize lvl or grp, or other things to give
- * "safest" scenario to simulate the keystrokes.
- */
-
- if (found > 1) {
- if (down) {
- int l, score[0x100];
- int best = 0, best_score = -1;
- /* need to break the tie... */
- if (! got_kbstate) {
- XkbGetState(dpy, XkbUseCoreKbd, &kbstate);
- got_kbstate = 1;
- }
- if (khints && keysym < 0x100) {
- int ks = (int) keysym, j;
- for (j=0; j< 0x100; j++) {
- score_hint[ks][j] = -1;
- }
- }
- for (l=0; l < found; l++) {
- int myscore = 0, b = 0x1, i;
- int curr, curr_state = kbstate.mods;
- int need, need_state = state_f[l];
- int ignore_state = ignore_f[l];
-
- /* see how many modifiers need to be changed */
- for (i=0; i<8; i++) {
- curr = b & curr_state;
- need = b & need_state;
- if (! (b & ignore_state)) {
- ;
- } else if (curr == need) {
- ;
- } else {
- myscore++;
- }
- b = b << 1;
- }
- myscore *= 100;
-
- /* throw in some minimization of lvl too: */
- myscore += 2*lvl_f[l] + grp_f[l];
-
- /*
- * XXX since we now internally track
- * keycode_state[], we could throw that into
- * the score as well. I.e. if it is already
- * down, it is pointless to think we can
- * press it down further! E.g.
- * myscore += 1000 * keycode_state[kc_f[l]];
- * Also could watch multiple modifier
- * problem, e.g. Shift+key -> Alt
- * keycode = 125 on my keyboard.
- */
-
- score[l] = myscore;
- if (debug_keyboard > 1) {
- fprintf(stderr, " *** score for "
- "keycode %03d: %4d\n",
- kc_f[l], myscore);
- }
- if (khints && keysym < 0x100 && kc_f[l] < 0x100) {
- score_hint[(int) keysym][kc_f[l]] = (short) score[l];
- }
- }
- for (l=0; l < found; l++) {
- int myscore = score[l];
- if (best_score == -1 || myscore < best_score) {
- best = l;
- best_score = myscore;
- }
- }
- Kc_f = kc_f[best];
- Grp_f = grp_f[best];
- Lvl_f = lvl_f[best];
- state = state_f[best];
-
- } else {
- /* up */
- int i, Kc_loc = -1;
- Kc_f = -1;
-
- /* first try the scores we remembered when the key went down: */
- if (khints && keysym < 0x100) {
- /* low keysyms, ascii, only */
- int ks = (int) keysym;
- int ok = 1, lbest = 0, l;
- short sbest = -1;
- for (l=0; l < found; l++) {
- if (kc_f[l] < 0x100) {
- int key = (int) kc_f[l];
- if (! keycode_state[key]) {
- continue;
- }
- if (score_hint[ks][key] < 0) {
- ok = 0;
- break;
- }
- if (sbest < 0 || score_hint[ks][key] < sbest) {
- sbest = score_hint[ks][key];
- lbest = l;
- }
- } else {
- ok = 0;
- break;
- }
- }
- if (ok && sbest != -1) {
- Kc_f = kc_f[lbest];
- }
- if (debug_keyboard && Kc_f != -1) {
- fprintf(stderr, " UP: found via score_hint, s/l=%d/%d\n",
- sbest, lbest);
- }
- }
-
- /* next look at our list of recently pressed down keys */
- if (Kc_f == -1) {
- for (i=klast-1; i>=0; i--) {
- /*
- * some people type really fast and leave
- * lots of keys down before releasing
- * them. this gives problem on weird
- * qwerty+dvorak keymappings where each
- * alpha character is on TWO keys.
- */
- if (keysym == Ks_last_down[i]) {
- int l;
- for (l=0; l < found; l++) {
- if (Kc_last_down[i] == kc_f[l]) {
- int key = (int) kc_f[l];
- if (keycode_state[key]) {
- Kc_f = Kc_last_down[i];
- Kc_loc = i;
- break;
- }
- }
- }
- }
- if (Kc_f != -1) {
- break;
- }
- }
- if (debug_keyboard && Kc_f != -1) {
- fprintf(stderr, " UP: found via klast, i=%d\n", Kc_loc);
- }
- }
-
- /* next just check for "best" one that is down */
- if (Kc_f == -1 && anydown) {
- int l;
- int best = -1, lbest = 0;
- /*
- * If it is already down, that is
- * a great hint. Use it.
- *
- * note: keycode_state is internal and
- * ignores someone pressing keys on the
- * physical display (but is updated
- * periodically to clean out stale info).
- */
- for (l=0; l < found; l++) {
- int key = (int) kc_f[l];
- int j, jmatch = -1;
-
- if (! keycode_state[key]) {
- continue;
- }
- /* break ties based on lowest XKeycodeToKeysym index */
- for (j=0; j<8; j++) {
- KeySym ks = XKeycodeToKeysym(dpy, kc_f[l], j);
- if (ks != NoSymbol && ks == keysym) {
- jmatch = j;
- break;
- }
- }
- if (jmatch == -1) {
- continue;
- }
- if (best == -1 || jmatch < best) {
- best = jmatch;
- lbest = l;
- }
- }
- if (best != -1) {
- Kc_f = kc_f[lbest];
- }
- if (debug_keyboard && Kc_f != -1) {
- fprintf(stderr, " UP: found via downlist, l=%d\n", lbest);
- }
- }
-
- /* next, use the first one found that is down */
- if (Kc_f == -1) {
- int l;
- for (l=0; l < found; l++) {
- int key = (int) kc_f[l];
- if (keycode_state[key]) {
- Kc_f = kc_f[l];
- break;
- }
- }
- if (debug_keyboard && Kc_f != -1) {
- fprintf(stderr, " UP: set to first one down, kc_f[%d]!!\n", l);
- }
- }
-
- /* last, use the first one found */
- if (Kc_f == -1) {
- /* hope for the best... XXX check mods */
- Kc_f = kc_f[0];
- if (debug_keyboard && Kc_f != -1) {
- fprintf(stderr, " UP: set to first one at all, kc_f[0]!!\n");
- }
- }
- }
- } else {
- Kc_f = kc_f[0];
- Grp_f = grp_f[0];
- Lvl_f = lvl_f[0];
- state = state_f[0];
- }
-
- if (debug_keyboard && found > 1) {
- int l;
- char *str;
- fprintf(stderr, " *** found more than one keycode: ");
- for (l = 0; l < found; l++) {
- fprintf(stderr, "%03d ", kc_f[l]);
- }
- for (l = 0; l < found; l++) {
- str = XKeysymToString(XKeycodeToKeysym(dpy,kc_f[l],0));
- fprintf(stderr, " \"%s\"", str ? str : "null");
- }
- fprintf(stderr, ", picked this one: %03d (last down: %03d)\n",
- Kc_f, Kc_last_down[0]);
- }
-
- if (sloppy_keys) {
- int new_kc;
- if (sloppy_key_check(Kc_f, down, keysym, &new_kc)) {
- Kc_f = new_kc;
- }
- }
-
- if (down) {
- /*
- * need to set up the mods for tweaking and other workarounds
- */
- int needmods[8], sentmods[8], Ilist[8], keystate[256];
- int involves_multi_key, shift_is_down;
- int i, j, b, curr, need;
- unsigned int ms;
- KeySym ks;
- Bool dn;
-
- /* remember these to aid the subsequent up case: */
- for (i=KLAST-1; i >= 1; i--) {
- Ks_last_down[i] = Ks_last_down[i-1];
- Kc_last_down[i] = Kc_last_down[i-1];
- }
- Ks_last_down[0] = keysym;
- Kc_last_down[0] = Kc_f;
-
- if (! got_kbstate) {
- /* get the current modifier state if we haven't yet */
- XkbGetState(dpy, XkbUseCoreKbd, &kbstate);
- got_kbstate = 1;
- }
-
- /*
- * needmods[] whether or not that modifier bit needs
- * something done to it.
- * < 0 means no,
- * 0 means needs to go up.
- * 1 means needs to go down.
- *
- * -1, -2, -3 are used for debugging info to indicate
- * why nothing needs to be done with the modifier, see below.
- *
- * sentmods[] is the corresponding keycode to use
- * to achieve the needmods[] requirement for the bit.
- */
-
- for (i=0; i<8; i++) {
- needmods[i] = -1;
- sentmods[i] = 0;
- }
-
- /*
- * Loop over the 8 modifier bits and check if the current
- * setting is what we need it to be or whether it should
- * be changed (by us sending some keycode event)
- *
- * If nothing needs to be done to it record why:
- * -1 the modifier bit is ignored.
- * -2 the modifier bit is ignored, but is correct anyway.
- * -3 the modifier bit is correct.
- */
-
- b = 0x1;
- for (i=0; i<8; i++) {
- curr = b & kbstate.mods;
- need = b & state;
-
- if (! (b & xkbignore[Kc_f][Grp_f][Lvl_f])) {
- /* irrelevant modifier bit */
- needmods[i] = -1;
- if (curr == need) needmods[i] = -2;
- } else if (curr == need) {
- /* already correct */
- needmods[i] = -3;
- } else if (! curr && need) {
- /* need it down */
- needmods[i] = 1;
- } else if (curr && ! need) {
- /* need it up */
- needmods[i] = 0;
- }
-
- b = b << 1;
- }
-
- /*
- * Again we dynamically probe the X server for information,
- * this time for the state of all the keycodes. Useful
- * info, and evidently is not too slow...
- */
- get_keystate(keystate);
-
- /*
- * We try to determine if Shift is down (since that can
- * screw up ISO_Level3_Shift manipulations).
- */
- shift_is_down = 0;
-
- for (kc = kc_min; kc <= kc_max; kc++) {
- if (skipkeycode[kc] && debug_keyboard) {
- fprintf(stderr, " xxx skipping keycode: "
- "%d\n", kc);
- }
- if (skipkeycode[kc]) {
- continue;
- }
- if (shift_keys[kc] && keystate[kc]) {
- shift_is_down = kc;
- break;
- }
- }
-
- /*
- * Now loop over the modifier bits and try to deduce the
- * keycode presses/release require to match the desired
- * state.
- */
- for (i=0; i<8; i++) {
- if (needmods[i] < 0 && debug_keyboard > 1) {
- int k = -needmods[i] - 1;
- char *words[] = {"ignorable",
- "bitset+ignorable", "bitset"};
- fprintf(stderr, " +++ needmods: mod=%d is "
- "OK (%s)\n", i, words[k]);
- }
- if (needmods[i] < 0) {
- continue;
- }
-
- b = 1 << i;
-
- if (debug_keyboard > 1) {
- fprintf(stderr, " +++ needmods: mod=%d %s "
- "need it to be: %d %s\n", i, bitprint(b, 8),
- needmods[i], needmods[i] ? "down" : "up");
- }
-
- /*
- * Again, an inefficient loop, this time just
- * looking for modifiers...
- *
- * note the use of kc_vec to prefer XK_ISO_Level3_Shift
- * over XK_Mode_switch.
- */
- for (kci = kc_min; kci <= kc_max; kci++) {
- for (grp = 0; grp < grp_max+1; grp++) {
- for (lvl = 0; lvl < lvl_max+1; lvl++) {
- int skip = 1, dbmsg = 0;
-
- kc = kc_vec[kci];
-
- ms = xkbmodifiers[kc][grp][lvl];
- if (! ms || ms != (unsigned int) b) {
- continue;
- }
-
- if (skipkeycode[kc] && debug_keyboard) {
- fprintf(stderr, " xxx skipping keycode:"
- " %d G%d/L%d\n", kc, grp+1, lvl+1);
- }
- if (skipkeycode[kc]) {
- continue;
- }
-
- ks = xkbkeysyms[kc][grp][lvl];
- if (! ks) {
- continue;
- }
-
- if (ks == XK_Shift_L) {
- skip = 0;
- } else if (ks == XK_Shift_R) {
- skip = 0;
- } else if (ks == XK_Mode_switch) {
- skip = 0;
- } else if (ks == XK_ISO_Level3_Shift) {
- skip = 0;
- }
-
- if (watch_capslock && kbstate.locked_mods & LockMask) {
- if (keysym >= 'A' && keysym <= 'Z') {
- if (ks == XK_Shift_L || ks == XK_Shift_R) {
- if (debug_keyboard > 1) {
- fprintf(stderr, " A-Z caplock skip Shift\n");
- }
- skip = 1;
- } else if (ks == XK_Caps_Lock) {
- if (debug_keyboard > 1) {
- fprintf(stderr, " A-Z caplock noskip CapsLock\n");
- }
- skip = 0;
- }
- }
- }
- /*
- * Alt, Meta, Control, Super,
- * Hyper, Num, Caps are skipped.
- *
- * XXX need more work on Locks,
- * and non-standard modifiers.
- * (e.g. XF86_Next_VMode using
- * Ctrl+Alt)
- */
- if (debug_keyboard > 1) {
- char *str = XKeysymToString(ks);
- int kt = keystate[kc];
- fprintf(stderr, " === for mod=%s "
- "found kc=%03d/G%d/L%d it is %d "
- "%s skip=%d (%s)\n", bitprint(b,8),
- kc, grp+1, lvl+1, kt, kt ?
- "down" : "up ", skip, str ?
- str : "null");
- }
-
- if (! skip && needmods[i] !=
- keystate[kc] && sentmods[i] == 0) {
- sentmods[i] = kc;
- dbmsg = 1;
- }
-
- if (debug_keyboard > 1 && dbmsg) {
- int nm = needmods[i];
- fprintf(stderr, " >>> we choose "
- "kc=%03d=0x%02x to change it to: "
- "%d %s\n", kc, kc, nm, nm ?
- "down" : "up");
- }
-
- }
- }
- }
- }
- for (i=0; i<8; i++) {
- /*
- * reverse order is useful for tweaking
- * ISO_Level3_Shift before Shift, but assumes they
- * are in that order (i.e. Shift is first bit).
- */
- int reverse = 1;
- if (reverse) {
- Ilist[i] = 7 - i;
- } else {
- Ilist[i] = i;
- }
- }
-
- /*
- * check to see if Multi_key is bound to one of the Mods
- * we have to tweak
- */
- involves_multi_key = 0;
- for (j=0; j<8; j++) {
- i = Ilist[j];
- if (sentmods[i] == 0) continue;
- dn = (Bool) needmods[i];
- if (!dn) continue;
- if (multi_key[sentmods[i]]) {
- involves_multi_key = i+1;
- }
- }
-
- if (involves_multi_key && shift_is_down && needmods[0] < 0) {
- /*
- * Workaround for Multi_key and shift.
- * Assumes Shift is bit 1 (needmods[0])
- */
- if (debug_keyboard) {
- fprintf(stderr, " ^^^ trying to avoid "
- "inadvertent Multi_key from Shift "
- "(doing %03d up now)\n", shift_is_down);
- }
- XTestFakeKeyEvent_wr(dpy, shift_is_down, False,
- CurrentTime);
- } else {
- involves_multi_key = 0;
- }
-
- for (j=0; j<8; j++) {
- /* do the Mod ups */
- i = Ilist[j];
- if (sentmods[i] == 0) continue;
- dn = (Bool) needmods[i];
- if (dn) continue;
- XTestFakeKeyEvent_wr(dpy, sentmods[i], dn, CurrentTime);
- }
- for (j=0; j<8; j++) {
- /* next, do the Mod downs */
- i = Ilist[j];
- if (sentmods[i] == 0) continue;
- dn = (Bool) needmods[i];
- if (!dn) continue;
- XTestFakeKeyEvent_wr(dpy, sentmods[i], dn, CurrentTime);
- }
-
- if (involves_multi_key) {
- /*
- * Reverse workaround for Multi_key and shift.
- */
- if (debug_keyboard) {
- fprintf(stderr, " vvv trying to avoid "
- "inadvertent Multi_key from Shift "
- "(doing %03d down now)\n", shift_is_down);
- }
- XTestFakeKeyEvent_wr(dpy, shift_is_down, True,
- CurrentTime);
- }
-
- /*
- * With the above modifier work done, send the actual keycode:
- */
- XTestFakeKeyEvent_wr(dpy, Kc_f, (Bool) down, CurrentTime);
-
- /*
- * Now undo the modifier work:
- */
- for (j=7; j>=0; j--) {
- /* reverse Mod downs we did */
- i = Ilist[j];
- if (sentmods[i] == 0) continue;
- dn = (Bool) needmods[i];
- if (!dn) continue;
- XTestFakeKeyEvent_wr(dpy, sentmods[i], !dn,
- CurrentTime);
- }
- for (j=7; j>=0; j--) {
- /* finally reverse the Mod ups we did */
- i = Ilist[j];
- if (sentmods[i] == 0) continue;
- dn = (Bool) needmods[i];
- if (dn) continue;
- XTestFakeKeyEvent_wr(dpy, sentmods[i], !dn,
- CurrentTime);
- }
-
- } else { /* for up case, hopefully just need to pop it up: */
-
- XTestFakeKeyEvent_wr(dpy, Kc_f, (Bool) down, CurrentTime);
- }
- X_UNLOCK;
-}
-#endif
-
-/*
- * For tweaking modifiers wrt the Alt-Graph key, etc.
- */
-#define LEFTSHIFT 1
-#define RIGHTSHIFT 2
-#define ALTGR 4
-static char mod_state = 0;
-
-static char modifiers[0x100];
-static KeyCode keycodes[0x100];
-static KeyCode left_shift_code, right_shift_code, altgr_code, iso_level3_code;
-
-/* workaround for X11R5, Latin 1 only */
-#ifndef XConvertCase
-#define XConvertCase(sym, lower, upper) \
-*(lower) = sym; \
-*(upper) = sym; \
-if (sym >> 8 == 0) { \
- if ((sym >= XK_A) && (sym <= XK_Z)) \
- *(lower) += (XK_a - XK_A); \
- else if ((sym >= XK_a) && (sym <= XK_z)) \
- *(upper) -= (XK_a - XK_A); \
- else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) \
- *(lower) += (XK_agrave - XK_Agrave); \
- else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) \
- *(upper) -= (XK_agrave - XK_Agrave); \
- else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) \
- *(lower) += (XK_oslash - XK_Ooblique); \
- else if ((sym >= XK_oslash) && (sym <= XK_thorn)) \
- *(upper) -= (XK_oslash - XK_Ooblique); \
-}
-#endif
-
-char *short_kmbcf(char *str) {
- int i, saw_k = 0, saw_m = 0, saw_b = 0, saw_c = 0, saw_f = 0, n = 10;
- char *p, tmp[10];
-
- for (i=0; i<n; i++) {
- tmp[i] = '\0';
- }
-
- p = str;
- i = 0;
- while (*p) {
- if ((*p == 'K' || *p == 'k') && !saw_k) {
- tmp[i++] = 'K';
- saw_k = 1;
- } else if ((*p == 'M' || *p == 'm') && !saw_m) {
- tmp[i++] = 'M';
- saw_m = 1;
- } else if ((*p == 'B' || *p == 'b') && !saw_b) {
- tmp[i++] = 'B';
- saw_b = 1;
- } else if ((*p == 'C' || *p == 'c') && !saw_c) {
- tmp[i++] = 'C';
- saw_c = 1;
- } else if ((*p == 'F' || *p == 'f') && !saw_f) {
- tmp[i++] = 'F';
- saw_f = 1;
- }
- p++;
- }
- return(strdup(tmp));
-}
-
-void initialize_allowed_input(void) {
- char *str;
-
- if (allowed_input_normal) {
- free(allowed_input_normal);
- allowed_input_normal = NULL;
- }
- if (allowed_input_view_only) {
- free(allowed_input_view_only);
- allowed_input_view_only = NULL;
- }
-
- if (! allowed_input_str) {
- allowed_input_normal = strdup("KMBCF");
- allowed_input_view_only = strdup("");
- } else {
- char *p, *str = strdup(allowed_input_str);
- p = strchr(str, ',');
- if (p) {
- allowed_input_view_only = strdup(p+1);
- *p = '\0';
- allowed_input_normal = strdup(str);
- } else {
- allowed_input_normal = strdup(str);
- allowed_input_view_only = strdup("");
- }
- free(str);
- }
-
- /* shorten them */
- str = short_kmbcf(allowed_input_normal);
- free(allowed_input_normal);
- allowed_input_normal = str;
-
- str = short_kmbcf(allowed_input_view_only);
- free(allowed_input_view_only);
- allowed_input_view_only = str;
-
- if (screen) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd = (ClientData *) cl->clientData;
-
- if (! cd) {
- continue;
- }
-#if 0
-rfbLog("cd: %p\n", cd);
-rfbLog("cd->input: %s\n", cd->input);
-rfbLog("cd->login_viewonly: %d\n", cd->login_viewonly);
-rfbLog("allowed_input_view_only: %s\n", allowed_input_view_only);
-#endif
-
- if (cd->input[0] == '=') {
- ; /* custom setting */
- } else if (cd->login_viewonly) {
- if (*allowed_input_view_only != '\0') {
- cl->viewOnly = FALSE;
- cd->input[0] = '\0';
- strncpy(cd->input,
- allowed_input_view_only, CILEN);
- } else {
- cl->viewOnly = TRUE;
- }
- } else {
- if (allowed_input_normal) {
- cd->input[0] = '\0';
- strncpy(cd->input,
- allowed_input_normal, CILEN);
- }
- }
- }
- rfbReleaseClientIterator(iter);
- }
-}
-
-void initialize_modtweak(void) {
-#if NO_X11
- RAWFB_RET_VOID
- return;
-#else
- KeySym keysym, *keymap;
- int i, j, minkey, maxkey, syms_per_keycode;
- int use_lowest_index = 0;
-
- if (use_xkb_modtweak) {
- initialize_xkb_modtweak();
- return;
- }
- memset(modifiers, -1, sizeof(modifiers));
- for (i=0; i<0x100; i++) {
- keycodes[i] = NoSymbol;
- }
-
- RAWFB_RET_VOID
-
- if (getenv("MODTWEAK_LOWEST")) {
- use_lowest_index = 1;
- }
-
- X_LOCK;
- XDisplayKeycodes(dpy, &minkey, &maxkey);
-
- keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1),
- &syms_per_keycode);
-
- /* handle alphabetic char with only one keysym (no upper + lower) */
- for (i = minkey; i <= maxkey; i++) {
- KeySym lower, upper;
- /* 2nd one */
- keysym = keymap[(i - minkey) * syms_per_keycode + 1];
- if (keysym != NoSymbol) {
- continue;
- }
- /* 1st one */
- keysym = keymap[(i - minkey) * syms_per_keycode + 0];
- if (keysym == NoSymbol) {
- continue;
- }
- XConvertCase(keysym, &lower, &upper);
- if (lower != upper) {
- keymap[(i - minkey) * syms_per_keycode + 0] = lower;
- keymap[(i - minkey) * syms_per_keycode + 1] = upper;
- }
- }
- for (i = minkey; i <= maxkey; i++) {
- if (debug_keyboard) {
- if (i == minkey) {
- rfbLog("initialize_modtweak: keycode -> "
- "keysyms mapping info:\n");
- }
- fprintf(stderr, " %03d ", i);
- }
- for (j = 0; j < syms_per_keycode; j++) {
- if (debug_keyboard) {
- char *sym;
-#if 0
- sym =XKeysymToString(XKeycodeToKeysym(dpy,i,j));
-#else
- keysym = keymap[(i-minkey)*syms_per_keycode+j];
- sym = XKeysymToString(keysym);
-#endif
- fprintf(stderr, "%-18s ", sym ? sym : "null");
- if (j == syms_per_keycode - 1) {
- fprintf(stderr, "\n");
- }
- }
- if (j >= 4) {
- /*
- * Something wacky in the keymapping.
- * Ignore these non Shift/AltGr chords
- * for now... n.b. we try to automatically
- * switch to -xkb for this case.
- */
- continue;
- }
- keysym = keymap[ (i - minkey) * syms_per_keycode + j ];
- if ( keysym >= ' ' && keysym < 0x100
- && i == XKeysymToKeycode(dpy, keysym) ) {
- if (use_lowest_index && keycodes[keysym] != NoSymbol) {
- continue;
- }
- keycodes[keysym] = i;
- modifiers[keysym] = j;
- }
- }
- }
-
- left_shift_code = XKeysymToKeycode(dpy, XK_Shift_L);
- right_shift_code = XKeysymToKeycode(dpy, XK_Shift_R);
- altgr_code = XKeysymToKeycode(dpy, XK_Mode_switch);
- iso_level3_code = NoSymbol;
-#ifdef XK_ISO_Level3_Shift
- iso_level3_code = XKeysymToKeycode(dpy, XK_ISO_Level3_Shift);
-#endif
-
- XFree_wr ((void *) keymap);
-
- X_UNLOCK;
-#endif /* NO_X11 */
-}
-
-/*
- * does the actual tweak:
- */
-static void tweak_mod(signed char mod, rfbBool down) {
- rfbBool is_shift = mod_state & (LEFTSHIFT|RIGHTSHIFT);
- Bool dn = (Bool) down;
- KeyCode altgr = altgr_code;
-
- RAWFB_RET_VOID
-
- if (mod < 0) {
- if (debug_keyboard) {
- rfbLog("tweak_mod: Skip: down=%d index=%d\n", down,
- (int) mod);
- }
- return;
- }
- if (debug_keyboard) {
- rfbLog("tweak_mod: Start: down=%d index=%d mod_state=0x%x"
- " is_shift=%d\n", down, (int) mod, (int) mod_state,
- is_shift);
- }
-
- if (use_iso_level3 && iso_level3_code) {
- altgr = iso_level3_code;
- }
-
- X_LOCK;
- if (is_shift && mod != 1) {
- if (mod_state & LEFTSHIFT) {
- XTestFakeKeyEvent_wr(dpy, left_shift_code, !dn, CurrentTime);
- }
- if (mod_state & RIGHTSHIFT) {
- XTestFakeKeyEvent_wr(dpy, right_shift_code, !dn, CurrentTime);
- }
- }
- if ( ! is_shift && mod == 1 ) {
- XTestFakeKeyEvent_wr(dpy, left_shift_code, dn, CurrentTime);
- }
- if ( altgr && (mod_state & ALTGR) && mod != 2 ) {
- XTestFakeKeyEvent_wr(dpy, altgr, !dn, CurrentTime);
- }
- if ( altgr && ! (mod_state & ALTGR) && mod == 2 ) {
- XTestFakeKeyEvent_wr(dpy, altgr, dn, CurrentTime);
- }
- X_UNLOCK;
-
- if (debug_keyboard) {
- rfbLog("tweak_mod: Finish: down=%d index=%d mod_state=0x%x"
- " is_shift=%d\n", down, (int) mod, (int) mod_state,
- is_shift);
- }
-}
-
-/*
- * tweak the modifier under -modtweak
- */
-static void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym,
- rfbClientPtr client) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!down || !keysym || !client) {}
- return;
-#else
- KeyCode k;
- int tweak = 0;
-
- RAWFB_RET_VOID
-
- if (use_xkb_modtweak) {
- xkb_tweak_keyboard(down, keysym, client);
- return;
- }
- if (debug_keyboard) {
- rfbLog("modifier_tweak_keyboard: %s keysym=0x%x\n",
- down ? "down" : "up", (int) keysym);
- }
-
-#define ADJUSTMOD(sym, state) \
- if (keysym == sym) { \
- if (down) { \
- mod_state |= state; \
- } else { \
- mod_state &= ~state; \
- } \
- }
-
- ADJUSTMOD(XK_Shift_L, LEFTSHIFT)
- ADJUSTMOD(XK_Shift_R, RIGHTSHIFT)
- ADJUSTMOD(XK_Mode_switch, ALTGR)
-
- if ( down && keysym >= ' ' && keysym < 0x100 ) {
- unsigned int state = 0;
- tweak = 1;
- if (watch_capslock && keysym >= 'A' && keysym <= 'Z') {
- X_LOCK;
- state = mask_state();
- X_UNLOCK;
- }
- if (state & LockMask) {
- /* capslock set for A-Z, so no tweak */
- X_LOCK;
- k = XKeysymToKeycode(dpy, (KeySym) keysym);
- X_UNLOCK;
- tweak = 0;
- } else {
- tweak_mod(modifiers[keysym], True);
- k = keycodes[keysym];
- }
- } else {
- X_LOCK;
- k = XKeysymToKeycode(dpy, (KeySym) keysym);
- X_UNLOCK;
- }
- if (k == NoSymbol && add_keysyms && ! IsModifierKey(keysym)) {
- int new_kc = add_keysym(keysym);
- if (new_kc) {
- k = new_kc;
- }
- }
-
- if (sloppy_keys) {
- int new_kc;
- if (sloppy_key_check((int) k, down, keysym, &new_kc)) {
- k = (KeyCode) new_kc;
- }
- }
-
- if (debug_keyboard) {
- char *str = XKeysymToString(keysym);
- rfbLog("modifier_tweak_keyboard: KeySym 0x%x \"%s\" -> "
- "KeyCode 0x%x%s\n", (int) keysym, str ? str : "null",
- (int) k, k ? "" : " *ignored*");
- }
- if ( k != NoSymbol ) {
- X_LOCK;
- XTestFakeKeyEvent_wr(dpy, k, (Bool) down, CurrentTime);
- X_UNLOCK;
- }
-
- if ( tweak ) {
- tweak_mod(modifiers[keysym], False);
- }
-#endif /* NO_X11 */
-}
-
-void initialize_keyboard_and_pointer(void) {
-
-#ifdef MACOSX
- if (macosx_console) {
- initialize_remap(remap_file);
- initialize_pointer_map(pointer_remap);
- }
-#endif
-
- RAWFB_RET_VOID
-
- if (use_modifier_tweak) {
- initialize_modtweak();
- }
-
- initialize_remap(remap_file);
- initialize_pointer_map(pointer_remap);
-
- X_LOCK;
- clear_modifiers(1);
- if (clear_mods == 1) {
- clear_modifiers(0);
- }
- if (clear_mods == 3) {
- clear_locks();
- }
- X_UNLOCK;
-}
-
-void get_allowed_input(rfbClientPtr client, allowed_input_t *input) {
- ClientData *cd;
- char *str;
-
- input->keystroke = 0;
- input->motion = 0;
- input->button = 0;
- input->clipboard = 0;
- input->files = 0;
-
- if (! client) {
- input->keystroke = 1;
- input->motion = 1;
- input->button = 1;
- input->clipboard = 1;
- input->files = 1;
- return;
- }
-
- cd = (ClientData *) client->clientData;
-
- if (! cd) {
- return;
- }
-
- if (cd->input[0] != '-') {
- str = cd->input;
- } else if (client->viewOnly) {
- if (allowed_input_view_only) {
- str = allowed_input_view_only;
- } else {
- str = "";
- }
- } else {
- if (allowed_input_normal) {
- str = allowed_input_normal;
- } else {
- str = "KMBCF";
- }
- }
-if (0) fprintf(stderr, "GAI: %s - %s\n", str, cd->input);
-
- while (*str) {
- if (*str == 'K') {
- input->keystroke = 1;
- } else if (*str == 'M') {
- input->motion = 1;
- } else if (*str == 'B') {
- input->button = 1;
- } else if (*str == 'C') {
- input->clipboard = 1;
- } else if (*str == 'F') {
- input->files = 1;
- }
- str++;
- }
-}
-
-static void apply_remap(rfbKeySym *keysym, int *isbutton) {
- if (keyremaps) {
- keyremap_t *remap = keyremaps;
- while (remap != NULL) {
- if (remap->before == *keysym) {
- *keysym = remap->after;
- *isbutton = remap->isbutton;
- if (debug_keyboard) {
- char *str1, *str2;
- X_LOCK;
- str1 = XKeysymToString(remap->before);
- str2 = XKeysymToString(remap->after);
- rfbLog("keyboard(): remapping keysym: "
- "0x%x \"%s\" -> 0x%x \"%s\"\n",
- (int) remap->before,
- str1 ? str1 : "null",
- (int) remap->after,
- remap->isbutton ? "button" :
- str2 ? str2 : "null");
- X_UNLOCK;
- }
- break;
- }
- remap = remap->next;
- }
- }
-}
-
-/* for -pipeinput mode */
-static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
- int can_input = 0, uid = 0, isbutton = 0;
- allowed_input_t input;
- char *name;
- ClientData *cd = (ClientData *) client->clientData;
-
- apply_remap(&keysym, &isbutton);
-
- if (isbutton) {
- int mask, button = (int) keysym;
- int x = cursor_x, y = cursor_y;
- char *b, bstr[32];
-
- if (!down) {
- return;
- }
- if (debug_keyboard) {
- rfbLog("keyboard(): remapping keystroke to button %d"
- " click\n", button);
- }
- dtime0(&last_key_to_button_remap_time);
-
- /*
- * This in principle can be a little dicey... i.e. even
- * remap the button click to keystroke sequences!
- * Usually just will simulate the button click.
- */
-
- /* loop over possible multiclicks: Button123 */
- sprintf(bstr, "%d", button);
- b = bstr;
- while (*b != '\0') {
- char t[2];
- int butt;
- t[0] = *b;
- t[1] = '\0';
- if (sscanf(t, "%d", &butt) == 1) {
- mask = 1<<(butt-1);
- pointer_event(mask, x, y, client);
- mask = 0;
- pointer_event(mask, x, y, client);
- }
- b++;
- }
- return;
- }
-
- if (pipeinput_int == PIPEINPUT_VID) {
- v4l_key_command(down, keysym, client);
- } else if (pipeinput_int == PIPEINPUT_CONSOLE) {
- console_key_command(down, keysym, client);
- } else if (pipeinput_int == PIPEINPUT_UINPUT) {
- uinput_key_command(down, keysym, client);
- } else if (pipeinput_int == PIPEINPUT_MACOSX) {
- macosx_key_command(down, keysym, client);
- } else if (pipeinput_int == PIPEINPUT_VNC) {
- vnc_reflect_send_key((uint32_t) keysym, down);
- }
- if (pipeinput_fh == NULL) {
- return;
- }
-
- if (! view_only) {
- get_allowed_input(client, &input);
- if (input.keystroke) {
- can_input = 1; /* XXX distinguish later */
- }
- }
- if (cd) {
- uid = cd->uid;
- }
- if (! can_input) {
- uid = -uid;
- }
-
- X_LOCK;
- name = XKeysymToString(keysym);
- X_UNLOCK;
-
- fprintf(pipeinput_fh, "Keysym %d %d %u %s %s\n", uid, down,
- keysym, name ? name : "null", down ? "KeyPress" : "KeyRelease");
-
- fflush(pipeinput_fh);
- check_pipeinput();
-}
-
-typedef struct keyevent {
- rfbKeySym sym;
- rfbBool down;
- double time;
-} keyevent_t;
-
-#define KEY_HIST 256
-static int key_history_idx = -1;
-static keyevent_t key_history[KEY_HIST];
-
-double typing_rate(double time_window, int *repeating) {
- double dt = 1.0, now = dnow();
- KeySym key = NoSymbol;
- int i, idx, cnt = 0, repeat_keys = 0;
-
- if (key_history_idx == -1) {
- if (repeating) {
- *repeating = 0;
- }
- return 0.0;
- }
- if (time_window > 0.0) {
- dt = time_window;
- }
- for (i=0; i<KEY_HIST; i++) {
- idx = key_history_idx - i;
- if (idx < 0) {
- idx += KEY_HIST;
- }
- if (! key_history[idx].down) {
- continue;
- }
- if (now > key_history[idx].time + dt) {
- break;
- }
- cnt++;
- if (key == NoSymbol) {
- key = key_history[idx].sym;
- repeat_keys = 1;
- } else if (key == key_history[idx].sym) {
- repeat_keys++;
- }
- }
-
- if (repeating) {
- if (repeat_keys >= 2) {
- *repeating = repeat_keys;
- } else {
- *repeating = 0;
- }
- }
-
- /*
- * n.b. keyrate could seem very high with libvncserver buffering them
- * so avoid using small dt.
- */
- return ((double) cnt)/dt;
-}
-
-int skip_cr_when_scaling(char *mode) {
- int got = 0;
-
- if (!scaling) {
- return 0;
- }
-
- if (scaling_copyrect != scaling_copyrect0) {
- /* user override via -scale: */
- if (! scaling_copyrect) {
- return 1;
- } else {
- return 0;
- }
- }
- if (*mode == 's') {
- got = got_scrollcopyrect;
- } else if (*mode == 'w') {
- got = got_wirecopyrect;
- }
- if (scaling_copyrect || got) {
- int lat, rate;
- int link = link_rate(&lat, &rate);
- if (link == LR_DIALUP) {
- return 1;
- } else if (rate < 25) {
- /* the fill-in of the repair may be too slow */
- return 1;
- } else {
- return 0;
- }
- } else {
- return 1;
- }
-}
-
-/*
- * key event handler. See the above functions for contortions for
- * running under -modtweak.
- */
-static rfbClientPtr last_keyboard_client = NULL;
-
-void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
- KeyCode k;
- int idx, isbutton = 0;
- allowed_input_t input;
- time_t now = time(NULL);
- double tnow;
- static int skipped_last_down;
- static rfbBool last_down;
- static rfbKeySym last_keysym = NoSymbol;
- static rfbKeySym max_keyrepeat_last_keysym = NoSymbol;
- static double max_keyrepeat_last_time = 0.0;
- static double max_keyrepeat_always = -1.0;
-
- if (threads_drop_input) {
- return;
- }
-
- dtime0(&tnow);
- got_keyboard_calls++;
-
- if (debug_keyboard) {
- char *str;
- X_LOCK;
- str = XKeysymToString((KeySym) keysym);
- X_UNLOCK;
- rfbLog("# keyboard(%s, 0x%x \"%s\") uip=%d %.4f\n",
- down ? "down":"up", (int) keysym, str ? str : "null",
- unixpw_in_progress, tnow - x11vnc_start);
- }
-
- if (keysym <= 0) {
- rfbLog("keyboard: skipping 0x0 keysym\n");
- return;
- }
-
- if (unixpw_in_progress) {
- if (unixpw_denied) {
- rfbLog("keyboard: ignoring keystroke 0x%x in "
- "unixpw_denied=1 state\n", (int) keysym);
- return;
- }
- if (client != unixpw_client) {
- rfbLog("keyboard: skipping other client in unixpw\n");
- return;
- }
-
- unixpw_keystroke(down, keysym, 0);
-
- return;
- }
-
- if (skip_duplicate_key_events) {
- if (keysym == last_keysym && down == last_down) {
- if (debug_keyboard) {
- rfbLog("skipping dup key event: %d 0x%x\n",
- down, keysym);
- }
- return;
- }
- }
-
- if (skip_lockkeys) {
- /* we don't handle XK_ISO*_Lock or XK_Kana_Lock ... */
- if (keysym == XK_Scroll_Lock || keysym == XK_Num_Lock ||
- keysym == XK_Caps_Lock || keysym == XK_Shift_Lock) {
- if (debug_keyboard) {
- rfbLog("skipping lock key event: %d 0x%x\n",
- down, keysym);
- }
- return;
- } else if (keysym >= XK_KP_0 && keysym <= XK_KP_9) {
- /* ugh this is probably what they meant... assume NumLock. */
- if (debug_keyboard) {
- rfbLog("changed KP digit to regular digit: %d 0x%x\n",
- down, keysym);
- }
- keysym = (keysym - XK_KP_0) + XK_0;
- } else if (keysym == XK_KP_Decimal) {
- if (debug_keyboard) {
- rfbLog("changed XK_KP_Decimal to XK_period: %d 0x%x\n",
- down, keysym);
- }
- keysym = XK_period;
- }
- }
-
- INPUT_LOCK;
-
- last_down = down;
- last_keysym = keysym;
- last_keyboard_time = tnow;
-
- last_rfb_down = down;
- last_rfb_keysym = keysym;
- last_rfb_keytime = tnow;
- last_rfb_key_accepted = FALSE;
-
- if (key_history_idx == -1) {
- for (idx=0; idx<KEY_HIST; idx++) {
- key_history[idx].sym = NoSymbol;
- key_history[idx].down = FALSE;
- key_history[idx].time = 0.0;
- }
- }
- idx = ++key_history_idx;
- if (key_history_idx >= KEY_HIST) {
- key_history_idx = 0;
- idx = 0;
- }
- key_history[idx].sym = keysym;
- key_history[idx].down = down;
- key_history[idx].time = tnow;
-
- if (down && (keysym == XK_Alt_L || keysym == XK_Super_L)) {
- int i, k, run = 0, ups = 0;
- double delay = 1.0;
- KeySym ks;
- for (i=0; i<16; i++) {
- k = idx - i;
- if (k < 0) k += KEY_HIST;
- if (!key_history[k].down) {
- ups++;
- continue;
- }
- ks = key_history[k].sym;
- if (key_history[k].time < tnow - delay) {
- break;
- } else if (ks == keysym && ks == XK_Alt_L) {
- run++;
- } else if (ks == keysym && ks == XK_Super_L) {
- run++;
- } else {
- break;
- }
- }
- if (ups < 2) {
- ;
- } else if (run == 3 && keysym == XK_Alt_L) {
- rfbLog("3*Alt_L, calling: refresh_screen(0)\n");
- refresh_screen(0);
- } else if (run == 4 && keysym == XK_Alt_L) {
- rfbLog("4*Alt_L, setting: do_copy_screen\n");
- do_copy_screen = 1;
- } else if (run == 5 && keysym == XK_Alt_L) {
- ;
- } else if (run == 3 && keysym == XK_Super_L) {
- rfbLog("3*Super_L, calling: set_xdamage_mark()\n");
- set_xdamage_mark(0, 0, dpy_x, dpy_y);
- } else if (run == 4 && keysym == XK_Super_L) {
- rfbLog("4*Super_L, calling: check_xrecord_reset()\n");
- check_xrecord_reset(1);
- } else if (run == 5 && keysym == XK_Super_L) {
- rfbLog("5*Super_L, calling: push_black_screen(0)\n");
- push_black_screen(0);
- }
- }
-
-#ifdef MAX_KEYREPEAT
- if (max_keyrepeat_always < 0.0) {
- if (getenv("MAX_KEYREPEAT")) {
- max_keyrepeat_always = atof(getenv("MAX_KEYREPEAT"));
- } else {
- max_keyrepeat_always = 0.0;
- }
- }
- if (max_keyrepeat_always > 0.0) {
- max_keyrepeat_time = max_keyrepeat_always;
- }
-#else
- if (0) {max_keyrepeat_always=0;}
-#endif
- if (!down && skipped_last_down) {
- int db = debug_scroll;
- if (keysym == max_keyrepeat_last_keysym) {
- skipped_last_down = 0;
- if (db) rfbLog("--- scroll keyrate skipping 0x%lx %s "
- "%.4f %.4f\n", keysym, down ? "down":"up ",
- tnow - x11vnc_start, tnow - max_keyrepeat_last_time);
- INPUT_UNLOCK;
- return;
- }
- }
- if (down && max_keyrepeat_time > 0.0) {
- int skip = 0;
- int db = debug_scroll;
-
- if (max_keyrepeat_last_keysym != NoSymbol &&
- max_keyrepeat_last_keysym != keysym) {
- ;
- } else {
- if (tnow < max_keyrepeat_last_time+max_keyrepeat_time) {
- skip = 1;
- }
- }
- max_keyrepeat_time = 0.0;
- if (skip) {
- if (db) rfbLog("--- scroll keyrate skipping 0x%lx %s "
- "%.4f %.4f\n", keysym, down ? "down":"up ",
- tnow - x11vnc_start, tnow - max_keyrepeat_last_time);
- max_keyrepeat_last_keysym = keysym;
- skipped_last_down = 1;
- INPUT_UNLOCK;
- return;
- } else {
- if (db) rfbLog("--- scroll keyrate KEEPING 0x%lx %s "
- "%.4f %.4f\n", keysym, down ? "down":"up ",
- tnow - x11vnc_start, tnow - max_keyrepeat_last_time);
- }
- }
- max_keyrepeat_last_keysym = keysym;
- max_keyrepeat_last_time = tnow;
- skipped_last_down = 0;
- last_rfb_key_accepted = TRUE;
-
- if (pipeinput_fh != NULL || pipeinput_int) {
- pipe_keyboard(down, keysym, client); /* MACOSX here. */
- if (! pipeinput_tee) {
- if (! view_only || raw_fb) { /* raw_fb hack */
- last_keyboard_client = client;
- last_event = last_input = now;
- last_keyboard_input = now;
-
- last_keysym = keysym;
-
- last_rfb_down = down;
- last_rfb_keysym = keysym;
- last_rfb_keytime = tnow;
- last_rfb_key_injected = dnow();
-
- got_user_input++;
- got_keyboard_input++;
- }
- INPUT_UNLOCK;
- return;
- }
- }
-
- if (view_only) {
- INPUT_UNLOCK;
- return;
- }
- get_allowed_input(client, &input);
- if (! input.keystroke) {
- INPUT_UNLOCK;
- return;
- }
-
- track_mod_state(keysym, down, TRUE); /* ignores remaps */
-
- last_keyboard_client = client;
- last_event = last_input = now;
- last_keyboard_input = now;
-
- last_keysym = keysym;
-
- last_rfb_down = down;
- last_rfb_keysym = keysym;
- last_rfb_keytime = tnow;
- last_rfb_key_injected = dnow();
-
- got_user_input++;
- got_keyboard_input++;
-
- RAWFB_RET_VOID
-
-
- apply_remap(&keysym, &isbutton);
-
- if (use_xrecord && ! xrecording && down) {
-
- if (!strcmp(scroll_copyrect, "never")) {
- ;
- } else if (!strcmp(scroll_copyrect, "mouse")) {
- ;
- } else if (skip_cr_when_scaling("scroll")) {
- ;
- } else if (! xrecord_skip_keysym(keysym)) {
- snapshot_stack_list(0, 0.25);
- xrecord_watch(1, SCR_KEY);
- xrecord_set_by_keys = 1;
- xrecord_keysym = keysym;
- } else {
- if (debug_scroll) {
- char *str = XKeysymToString(keysym);
- rfbLog("xrecord_skip_keysym: %s\n",
- str ? str : "NoSymbol");
- }
- }
- }
-
- if (isbutton) {
- int mask, button = (int) keysym;
- char *b, bstr[32];
-
- if (! down) {
- INPUT_UNLOCK;
- return; /* nothing to send */
- }
- if (debug_keyboard) {
- rfbLog("keyboard(): remapping keystroke to button %d"
- " click\n", button);
- }
- dtime0(&last_key_to_button_remap_time);
-
- X_LOCK;
- /*
- * This in principle can be a little dicey... i.e. even
- * remap the button click to keystroke sequences!
- * Usually just will simulate the button click.
- */
-
- /* loop over possible multiclicks: Button123 */
- sprintf(bstr, "%d", button);
- b = bstr;
- while (*b != '\0') {
- char t[2];
- int butt;
- t[0] = *b;
- t[1] = '\0';
- if (sscanf(t, "%d", &butt) == 1) {
- mask = 1<<(butt-1);
- do_button_mask_change(mask, butt); /* down */
- mask = 0;
- do_button_mask_change(mask, butt); /* up */
- }
- b++;
- }
- XFlush_wr(dpy);
- X_UNLOCK;
- INPUT_UNLOCK;
- return;
- }
-
- if (use_modifier_tweak) {
- modifier_tweak_keyboard(down, keysym, client);
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- INPUT_UNLOCK;
- return;
- }
-
- X_LOCK;
-
- k = XKeysymToKeycode(dpy, (KeySym) keysym);
-
- if (k == NoSymbol && add_keysyms && ! IsModifierKey(keysym)) {
- int new_kc = add_keysym(keysym);
- if (new_kc) {
- k = new_kc;
- }
- }
- if (debug_keyboard) {
- char *str = XKeysymToString(keysym);
- rfbLog("keyboard(): KeySym 0x%x \"%s\" -> KeyCode 0x%x%s\n",
- (int) keysym, str ? str : "null", (int) k,
- k ? "" : " *ignored*");
- }
-
- if ( k != NoSymbol ) {
- XTestFakeKeyEvent_wr(dpy, k, (Bool) down, CurrentTime);
- XFlush_wr(dpy);
- }
-
- X_UNLOCK;
- INPUT_UNLOCK;
-}
-
-
diff --git a/x11vnc/keyboard.h b/x11vnc/keyboard.h
deleted file mode 100644
index 39a1a89..0000000
--- a/x11vnc/keyboard.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_KEYBOARD_H
-#define _X11VNC_KEYBOARD_H
-
-/* -- keyboard.h -- */
-#include "allowed_input_t.h"
-
-extern void get_keystate(int *keystate);
-extern void clear_modifiers(int init);
-extern int track_mod_state(rfbKeySym keysym, rfbBool down, rfbBool set);
-extern void clear_keys(void);
-extern void clear_locks(void);
-extern int get_autorepeat_state(void);
-extern int get_initial_autorepeat_state(void);
-extern void autorepeat(int restore, int bequiet);
-extern void check_add_keysyms(void);
-extern int add_keysym(KeySym keysym);
-extern void delete_added_keycodes(int bequiet);
-extern void initialize_remap(char *infile);
-extern int sloppy_key_check(int key, rfbBool down, rfbKeySym keysym, int *new_kc);
-extern void switch_to_xkb_if_better(void);
-extern char *short_kmbcf(char *str);
-extern void initialize_allowed_input(void);
-extern void initialize_modtweak(void);
-extern void initialize_keyboard_and_pointer(void);
-extern void get_allowed_input(rfbClientPtr client, allowed_input_t *input);
-extern double typing_rate(double time_window, int *repeating);
-extern int skip_cr_when_scaling(char *mode);
-extern void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
-
-#endif /* _X11VNC_KEYBOARD_H */
diff --git a/x11vnc/linuxfb.c b/x11vnc/linuxfb.c
deleted file mode 100644
index 1831c5f..0000000
--- a/x11vnc/linuxfb.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- linuxfb.c -- */
-
-#include "x11vnc.h"
-#include "cleanup.h"
-#include "scan.h"
-#include "xinerama.h"
-#include "screen.h"
-#include "pointer.h"
-#include "allowed_input_t.h"
-#include "uinput.h"
-#include "keyboard.h"
-#include "macosx.h"
-
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#if LIBVNCSERVER_HAVE_LINUX_FB_H
-#include <linux/fb.h>
-#endif
-
-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;
- int do_input, have_uinput, tty = -1;
-
-#ifdef MACOSX
- return macosx_console_guess(str, fd);
-#endif
-
-
- if (strstr(in, "/dev/fb") == in) {
- free(in);
- in = (char *) malloc(strlen("console:") + strlen(str) + 1);
- sprintf(in, "console:%s", str);
- } else if (strstr(in, "fb") == in) {
- 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) {
- rfbLog("console_guess: unrecognized console/fb format: %s\n", str);
- free(in);
- return NULL;
- }
-
- q = strrchr(in, '@');
- if (q) {
- atparms = strdup(q+1);
- *q = '\0';
- }
- q = strrchr(in, ':');
- if (q) {
- file = strdup(q+1);
- *q = '\0';
- }
- if (! file || file[0] == '\0') {
- file = strdup("/dev/fb");
- }
- if (strstr(file, "fb") == file) {
- q = (char *) malloc(strlen("/dev/") + strlen(file) + 1);
- sprintf(q, "/dev/%s", file);
- free(file);
- file = q;
- }
- if (!strcmp(file, "/dev/fb")) {
- /* sometimes no sylink fb -> fb0 */
- struct stat sbuf;
- if (stat(file, &sbuf) != 0) {
- free(file);
- file = strdup("/dev/fb0");
- }
- }
-
- do_input = 1;
- if (pipeinput_str) {
- have_uinput = 0;
- do_input = 0;
- } 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) {
- tty = 0;
- }
- } else {
- int n;
- 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
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
- struct fb_var_screeninfo var_info;
- int d = open(file, O_RDWR);
- if (d >= 0) {
- int w, h, b;
- unsigned long rm = 0, gm = 0, bm = 0;
- if (ioctl(d, FBIOGET_VSCREENINFO, &var_info) != -1) {
- w = (int) var_info.xres;
- h = (int) var_info.yres;
- b = (int) var_info.bits_per_pixel;
-
- rm = (1 << var_info.red.length) - 1;
- gm = (1 << var_info.green.length) - 1;
- bm = (1 << var_info.blue.length) - 1;
- rm = rm << var_info.red.offset;
- gm = gm << var_info.green.offset;
- bm = bm << var_info.blue.offset;
-
- if (b == 8 && rm == 0xff && gm == 0xff && bm == 0xff) {
- /* I don't believe it... */
- rm = 0x07;
- 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);
- sprintf(atparms, "%dx%dx%d:%lx/%lx/%lx",
- w, h, b, rm, gm, bm);
- *fd = d;
- } else {
- perror("ioctl");
- close(d);
- }
- } else {
- rfbLog("could not open: %s\n", file);
- rfbLogPerror("open");
- linux_dev_fb_msg(file);
- close(d);
- }
-#endif
-#endif
- }
-
- if (atparms) {
- int gw, gh, gb;
- if (sscanf(atparms, "%dx%dx%d", &gw, &gh, &gb) == 3) {
- fb_x = gw;
- fb_y = gh;
- fb_b = gb;
- }
- }
-
- if (do_input) {
- if (tty >=0 && tty < 64) {
- pipeinput_str = (char *) malloc(10);
- sprintf(pipeinput_str, "CONSOLE%d", tty);
- rfbLog("console_guess: file pipeinput %s\n",
- pipeinput_str);
- initialize_pipeinput();
- } else if (have_uinput) {
- pipeinput_str = strdup("UINPUT");
- rfbLog("console_guess: file pipeinput %s\n",
- pipeinput_str);
- initialize_pipeinput();
- }
- }
-
- if (! atparms) {
- rfbLog("console_guess: could not get @ parameters.\n");
- return NULL;
- }
-
- 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);
- }
- free(atparms);
- return q;
-}
-
-void console_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
- static int control = 0, alt = 0;
- allowed_input_t input;
-
- if (debug_keyboard) fprintf(stderr, "console_key_command: %d %s\n", (int) keysym, down ? "down" : "up");
-
- if (pipeinput_cons_fd < 0) {
- return;
- }
- if (view_only) {
- return;
- }
- get_allowed_input(client, &input);
- if (! input.keystroke) {
- return;
- }
-
- /* From LinuxVNC.c: */
- if (keysym == XK_Control_L || keysym == XK_Control_R) {
- if (! down) {
- if (control > 0) {
- control--;
- }
- } else {
- control++;
- }
- return;
- }
- if (keysym == XK_Alt_L || keysym == XK_Alt_R) {
- if (! down) {
- if (alt > 0) {
- alt--;
- }
- } else {
- alt++;
- }
- return;
- }
- if (!down) {
- return;
- }
- if (keysym == XK_Escape) {
- keysym = 27;
- }
- if (control) {
- /* shift down to the "control" zone */
- if (keysym >= 'a' && keysym <= 'z') {
- keysym -= ('a' - 1);
- } else if (keysym >= 'A' && keysym <= 'Z') {
- keysym -= ('A' - 1);
- } else {
- keysym = 0xffff;
- }
- } else if (alt) {
- /* shift up to the upper half Latin zone */
- if (keysym >= '!' && keysym <= '~') {
- keysym += 128;
- }
- }
- if (debug_keyboard) fprintf(stderr, "keysym now: %d\n", (int) keysym);
- if (keysym == XK_Tab) {
- keysym = '\t';
- } else if (keysym == XK_Return || keysym == XK_KP_Enter) {
- keysym = '\r';
- } else if (keysym == XK_BackSpace) {
- keysym = 8;
- } else if (keysym == XK_Home || keysym == XK_KP_Home) {
- keysym = 1;
- } else if (keysym == XK_End || keysym == XK_KP_End) {
- keysym = 5;
- } else if (keysym == XK_Up || keysym == XK_KP_Up) {
- keysym = 16;
- } else if (keysym == XK_Down || keysym == XK_KP_Down) {
- keysym = 14;
- } else if (keysym == XK_Right || keysym == XK_KP_Right) {
- keysym = 6;
- } else if (keysym == XK_Next || keysym == XK_KP_Next) {
- keysym = 6;
- } else if (keysym == XK_Left || keysym == XK_KP_Left) {
- keysym = 2;
- } else if (keysym == XK_Prior || keysym == XK_KP_Prior) {
- keysym = 2;
- } else {
- if (keysym >= XK_KP_Multiply && keysym <= XK_KP_Equal) {
- keysym -= 0xFF80;
- }
- }
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCSTI)
- if (keysym < 0x100) {
- if (ioctl(pipeinput_cons_fd, TIOCSTI, &keysym) != -1) {
- return;
- }
- perror("ioctl");
- close(pipeinput_cons_fd);
- pipeinput_cons_fd = -1;
- if (! pipeinput_cons_dev) {
- return;
- }
- pipeinput_cons_fd = open(pipeinput_cons_dev, O_WRONLY);
- if (pipeinput_cons_fd < 0) {
- rfbLog("pipeinput: could not reopen %s\n",
- pipeinput_cons_dev);
- perror("open");
- return;
- }
- if (ioctl(pipeinput_cons_fd, TIOCSTI, &keysym) == -1) {
- perror("ioctl");
- close(pipeinput_cons_fd);
- pipeinput_cons_fd = -1;
- rfbLog("pipeinput: could not reopen %s\n",
- pipeinput_cons_dev);
- }
- }
-#endif
-
- if (client) {}
-}
-
-void console_pointer_command(int mask, int x, int y, rfbClientPtr client) {
- /* do not forget viewonly perms */
- if (mask || x || y || client) {}
-}
-
diff --git a/x11vnc/linuxfb.h b/x11vnc/linuxfb.h
deleted file mode 100644
index d3886c9..0000000
--- a/x11vnc/linuxfb.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_LINUXFB_H
-#define _X11VNC_LINUXFB_H
-
-/* -- linuxfb.h -- */
-extern char *console_guess(char *str, int *fd);
-extern void console_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
-extern void console_pointer_command(int mask, int x, int y, rfbClientPtr client);
-
-
-#endif /* _X11VNC_LINUXFB_H */
diff --git a/x11vnc/macosx.c b/x11vnc/macosx.c
deleted file mode 100644
index 34126f4..0000000
--- a/x11vnc/macosx.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- macosx.c -- */
-
-#include "rfb/rfbconfig.h"
-#if (defined(__MACH__) && defined(__APPLE__) && defined(LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY))
-
-#define DOMAC 1
-
-#else
-
-#define DOMAC 0
-
-#endif
-
-#include "x11vnc.h"
-#include "cleanup.h"
-#include "scan.h"
-#include "screen.h"
-#include "pointer.h"
-#include "allowed_input_t.h"
-#include "keyboard.h"
-#include "cursor.h"
-#include "connections.h"
-#include "macosxCG.h"
-#include "macosxCGP.h"
-#include "macosxCGS.h"
-
-void macosx_log(char *);
-char *macosx_console_guess(char *str, int *fd);
-void macosx_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
-void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client);
-char *macosx_get_fb_addr(void);
-int macosx_get_cursor(void);
-int macosx_get_cursor_pos(int *, int *);
-void macosx_send_sel(char *, int);
-void macosx_set_sel(char *, int);
-int macosx_valid_window(Window, XWindowAttributes*);
-
-Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
- Window **children_return, unsigned int *nchildren_return);
-int macosx_get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
- Window *frame, Window *win);
-
-void macosx_add_mapnotify(Window win, int level, int map);
-void macosx_add_create(Window win, int level);
-void macosx_add_destroy(Window win, int level);
-void macosx_add_visnotify(Window win, int level, int obscured);
-int macosx_checkevent(XEvent *ev);
-
-void macosx_log(char *str) {
- rfbLog(str);
-}
-
-#if (! DOMAC)
-
-void macosx_event_loop(void) {
- return;
-}
-char *macosx_console_guess(char *str, int *fd) {
- if (!str || !fd) {}
- return NULL;
-}
-void macosx_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
- if (!down || !keysym || !client) {}
- return;
-}
-void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
- if (!mask || !x || !y || !client) {}
- return;
-}
-char *macosx_get_fb_addr(void) {
- return NULL;
-}
-int macosx_get_cursor(void) {
- return 0;
-}
-int macosx_get_cursor_pos(int *x, int *y) {
- if (!x || !y) {}
- return 0;
-}
-void macosx_send_sel(char * str, int len) {
- if (!str || !len) {}
- return;
-}
-void macosx_set_sel(char * str, int len) {
- if (!str || !len) {}
- return;
-}
-int macosx_valid_window(Window w, XWindowAttributes* a) {
- if (!w || !a) {}
- return 0;
-}
-Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
- Window **children_return, unsigned int *nchildren_return) {
- if (!w || !root_return || !parent_return || !children_return || !nchildren_return) {}
- return (Status) 0;
-}
-void macosx_add_mapnotify(Window win, int level, int map) {
- if (!win || !level || !map) {}
- return;
-}
-void macosx_add_create(Window win, int level) {
- if (!win || !level) {}
- return;
-}
-void macosx_add_destroy(Window win, int level) {
- if (!win || !level) {}
- return;
-}
-void macosx_add_visnotify(Window win, int level, int obscured) {
- if (!win || !level || !obscured) {}
- return;
-}
-
-int macosx_checkevent(XEvent *ev) {
- if (!ev) {}
- return 0;
-}
-
-
-#else
-
-void macosx_event_loop(void) {
- macosxCG_event_loop();
-}
-
-char *macosx_get_fb_addr(void) {
- macosxCG_init();
- return macosxCG_get_fb_addr();
-}
-
-int macosx_opengl_get_width(void);
-int macosx_opengl_get_height(void);
-int macosx_opengl_get_bpp(void);
-int macosx_opengl_get_bps(void);
-int macosx_opengl_get_spp(void);
-
-char *macosx_console_guess(char *str, int *fd) {
- char *q, *in = strdup(str);
- char *atparms = NULL, *file = NULL;
-
- macosxCG_init();
-
- if (strstr(in, "console") != in) {
- rfbLog("console_guess: unrecognized console/fb format: %s\n", str);
- free(in);
- return NULL;
- }
-
- *fd = -1;
-
- q = strrchr(in, '@');
- if (q) {
- atparms = strdup(q+1);
- *q = '\0';
- }
- q = strrchr(in, ':');
- if (q) {
- file = strdup(q+1);
- *q = '\0';
- }
- if (! file || file[0] == '\0') {
- file = strdup("/dev/null");
- }
- rfbLog("console_guess: file is %s\n", file);
-
- if (! pipeinput_str) {
- pipeinput_str = strdup("MACOSX");
- initialize_pipeinput();
- }
-
- if (! atparms) {
- int w, h, b, bps, dep;
- unsigned long rm = 0, gm = 0, bm = 0;
-
- if (macosx_read_opengl) {
- w = macosx_opengl_get_width();
- h = macosx_opengl_get_height();
- b = macosx_opengl_get_bpp();
-
- bps = macosx_opengl_get_bps();
- dep = macosx_opengl_get_spp() * bps;
-
- } else {
- w = macosxCG_CGDisplayPixelsWide();
- h = macosxCG_CGDisplayPixelsHigh();
- b = macosxCG_CGDisplayBitsPerPixel();
-
- bps = macosxCG_CGDisplayBitsPerSample();
- dep = macosxCG_CGDisplaySamplesPerPixel() * bps;
- }
-
- rm = (1 << bps) - 1;
- gm = (1 << bps) - 1;
- bm = (1 << bps) - 1;
- rm = rm << 2 * bps;
- gm = gm << 1 * bps;
- bm = bm << 0 * bps;
-
- if (b == 8 && rm == 0xff && gm == 0xff && bm == 0xff) {
- /* I don't believe it... */
- rm = 0x07;
- gm = 0x38;
- bm = 0xc0;
- }
-
- /* @66666x66666x32:0xffffffff:... */
- atparms = (char *) malloc(200);
- sprintf(atparms, "%dx%dx%d:%lx/%lx/%lx", w, h, b, rm, gm, bm);
- }
- if (atparms) {
- int gw, gh, gb;
- if (sscanf(atparms, "%dx%dx%d", &gw, &gh, &gb) == 3) {
- fb_x = gw;
- fb_y = gh;
- fb_b = gb;
- }
- }
- if (! atparms) {
- rfbLog("console_guess: could not get @ parameters.\n");
- return NULL;
- }
-
- q = (char *) malloc(strlen("map:macosx:") + strlen(file) + 1 + strlen(atparms) + 1);
- sprintf(q, "map:macosx:%s@%s", file, atparms);
- free(atparms);
- return q;
-}
-
-Window macosx_click_frame = None;
-
-void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
- allowed_input_t input;
- static int last_mask = 0;
- int rc;
-
- if (0) fprintf(stderr, "macosx_pointer_command: %d %d - %d\n", x, y, mask);
-
- if (mask >= 0) {
- got_pointer_calls++;
- }
-
- if (view_only) {
- return;
- }
-
- get_allowed_input(client, &input);
-
- if (! input.motion || ! input.button) {
- /* XXX fix me with last_x, last_y, etc. */
- return;
- }
-
- if (mask >= 0) {
- got_user_input++;
- got_pointer_input++;
- last_pointer_client = client;
- last_pointer_time = time(NULL);
- }
- if (last_mask != mask) {
- if (0) fprintf(stderr, "about to inject mask change %d -> %d: %.4f\n", last_mask, mask, dnowx());
- if (mask) {
- int px, py, x, y, w, h;
- macosx_click_frame = None;
- if (!macosx_get_wm_frame_pos(&px, &py, &x, &y, &w, &h, &macosx_click_frame, NULL)) {
- macosx_click_frame = None;
- }
- }
- }
-
- macosxCG_pointer_inject(mask, x, y);
-
- if (cursor_x != x || cursor_y != y) {
- last_pointer_motion_time = dnow();
- }
-
- cursor_x = x;
- cursor_y = y;
-
- if (last_mask != mask) {
- last_pointer_click_time = dnow();
- if (ncache > 0) {
- /* XXX Y */
- int i;
-if (0) fprintf(stderr, "about to get all windows: %.4f\n", dnowx());
- for (i=0; i < 2; i++) {
- macosxCGS_get_all_windows();
- if (0) fprintf(stderr, "!");
- if (macosx_checkevent(NULL)) {
- break;
- }
- }
-if (0) fprintf(stderr, "\ndone: %.4f\n", dnowx());
- }
- }
- last_mask = mask;
-
- /* record the x, y position for the rfb screen as well. */
- cursor_position(x, y);
-
- /* change the cursor shape if necessary */
- rc = set_cursor(x, y, get_which_cursor());
- cursor_changes += rc;
-
- last_event = last_input = last_pointer_input = time(NULL);
-}
-
-void init_key_table(void) {
- macosxCG_init_key_table();
-}
-
-void macosx_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
- allowed_input_t input;
- if (debug_keyboard) fprintf(stderr, "macosx_key_command: %d %s\n", (int) keysym, down ? "down" : "up");
-
- if (view_only) {
- return;
- }
- get_allowed_input(client, &input);
- if (! input.keystroke) {
- return;
- }
-
- init_key_table();
- macosxCG_keysym_inject((int) down, (unsigned int) keysym);
-}
-
-extern void macosxGCS_poll_pb(void);
-
-int macosx_get_cursor_pos(int *x, int *y) {
- macosxCG_get_cursor_pos(x, y);
- if (nofb) {
- /* good time to poll the pasteboard */
- macosxGCS_poll_pb();
- }
- return 1;
-}
-
-static char *cuttext = NULL;
-static int cutlen = 0;
-
-void macosx_send_sel(char *str, int len) {
- if (screen && all_clients_initialized()) {
- if (cuttext) {
- int n = cutlen;
- if (len < n) {
- n = len;
- }
- if (!memcmp(str, cuttext, (size_t) n)) {
- /* the same text we set pasteboard to ... */
- return;
- }
- }
- if (debug_sel) {
- rfbLog("macosx_send_sel: %d\n", len);
- }
- rfbSendServerCutText(screen, str, len);
- }
-}
-
-void macosx_set_sel(char *str, int len) {
- if (screen && all_clients_initialized()) {
- if (cutlen <= len) {
- if (cuttext) {
- free(cuttext);
- }
- cutlen = 2*(len+1);
- cuttext = (char *) calloc(cutlen, 1);
- }
- memcpy(cuttext, str, (size_t) len);
- cuttext[len] = '\0';
- if (debug_sel) {
- rfbLog("macosx_set_sel: %d\n", len);
- }
- macosxGCS_set_pasteboard(str, len);
- }
-}
-
-int macosx_get_cursor(void) {
- return macosxCG_get_cursor();
-}
-
-typedef struct evdat {
- int win;
- int map;
- int level;
- int vis;
- int type;
-} evdat_t;
-
-#define MAX_EVENTS 1024
-evdat_t mac_events[MAX_EVENTS];
-int mac_events_ptr = 0;
-int mac_events_last = 0;
-
-void macosx_add_mapnotify(Window win, int level, int map) {
- int i = mac_events_last++;
- mac_events[i].win = win;
- mac_events[i].level = level;
-
- if (map) {
- mac_events[i].type = MapNotify;
- } else {
- mac_events[i].type = UnmapNotify;
- }
- mac_events[i].map = map;
- mac_events[i].vis = -1;
-
- mac_events_last = mac_events_last % MAX_EVENTS;
-
- return;
-}
-
-void macosx_add_create(Window win, int level) {
- int i = mac_events_last++;
- mac_events[i].win = win;
- mac_events[i].level = level;
-
- mac_events[i].type = CreateNotify;
- mac_events[i].map = -1;
- mac_events[i].vis = -1;
-
- mac_events_last = mac_events_last % MAX_EVENTS;
-
- return;
-}
-
-void macosx_add_destroy(Window win, int level) {
- int i = mac_events_last++;
- mac_events[i].win = win;
- mac_events[i].level = level;
-
- mac_events[i].type = DestroyNotify;
- mac_events[i].map = -1;
- mac_events[i].vis = -1;
-
- mac_events_last = mac_events_last % MAX_EVENTS;
-
- return;
-}
-
-void macosx_add_visnotify(Window win, int level, int obscured) {
- int i = mac_events_last++;
- mac_events[i].win = win;
- mac_events[i].level = level;
-
- mac_events[i].type = VisibilityNotify;
- mac_events[i].map = -1;
-
- mac_events[i].vis = 1;
- if (obscured == 0) {
- mac_events[i].vis = VisibilityUnobscured;
- } else if (obscured == 1) {
- mac_events[i].vis = VisibilityPartiallyObscured;
- } else if (obscured == 2) {
- mac_events[i].vis = VisibilityFullyObscured; /* NI */
- }
-
- mac_events_last = mac_events_last % MAX_EVENTS;
-
- return;
-}
-
-int macosx_checkevent(XEvent *ev) {
- int i = mac_events_ptr;
-
- if (mac_events_ptr == mac_events_last) {
- return 0;
- }
- if (ev == NULL) {
- return mac_events[i].type;
- }
-
- ev->xany.window = mac_events[i].win;
-
- if (mac_events[i].type == CreateNotify) {
- ev->type = CreateNotify;
- ev->xany.window = rootwin;
- ev->xcreatewindow.window = mac_events[i].win;
- } else if (mac_events[i].type == DestroyNotify) {
- ev->type = DestroyNotify;
- ev->xdestroywindow.window = mac_events[i].win;
- } else if (mac_events[i].type == VisibilityNotify) {
- ev->type = VisibilityNotify;
- ev->xvisibility.state = mac_events[i].vis;
- } else if (mac_events[i].type == MapNotify) {
- ev->type = MapNotify;
- } else if (mac_events[i].type == UnmapNotify) {
- ev->type = UnmapNotify;
- } else {
- fprintf(stderr, "unknown macosx_checkevent: %d\n", mac_events[i].type);
- }
- mac_events_ptr++;
- mac_events_ptr = mac_events_ptr % MAX_EVENTS;
-
- return mac_events[i].type;
-}
-
-typedef struct windat {
- int win;
- int x, y;
- int width, height;
- int level;
- int mapped;
- int clipped;
- int ncache_only;
-} windat_t;
-
-extern int macwinmax;
-extern windat_t macwins[];
-
-int macosx_get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
- Window *frame, Window *win) {
- static int last_idx = -1;
- int x1, x2, y1, y2;
- int idx = -1, k;
- macosxCGS_get_all_windows();
- macosxCG_get_cursor_pos(px, py);
-
- for (k = 0; k<macwinmax; k++) {
- if (! macwins[k].mapped) {
- continue;
- }
- x1 = macwins[k].x;
- x2 = macwins[k].x + macwins[k].width;
- y1 = macwins[k].y;
- y2 = macwins[k].y + macwins[k].height;
-if (debug_wireframe) fprintf(stderr, "%d/%d: %d %d %d - %d %d %d\n", k, macwins[k].win, x1, *px, x2, y1, *py, y2);
- if (x1 <= *px && *px < x2) {
- if (y1 <= *py && *py < y2) {
- idx = k;
- break;
- }
- }
- }
- if (idx < 0) {
- return 0;
- }
-
- *x = macwins[idx].x;
- *y = macwins[idx].y;
- *w = macwins[idx].width;
- *h = macwins[idx].height;
- *frame = (Window) macwins[idx].win;
- if (win != NULL) {
- *win = *frame;
- }
-
- last_idx = idx;
-
- return 1;
-}
-
-int macosx_valid_window(Window w, XWindowAttributes* a) {
- static int last_idx = -1;
- int win = (int) w;
- int i, k, idx = -1;
-
- if (last_idx >= 0 && last_idx < macwinmax) {
- if (macwins[last_idx].win == win) {
- idx = last_idx;
- }
- }
-
- if (idx < 0) {
- idx = macosxCGS_get_qlook(w);
- if (idx >= 0 && idx < macwinmax) {
- if (macwins[idx].win != win) {
- idx = -1;
- }
- } else {
- idx = -1;
- }
- }
-
- if (idx < 0) {
- for (i = 0; i<macwinmax; i++) {
- k = i;
- if (i == -1) {
- if (last_idx >= 0 && last_idx < macwinmax) {
- k = last_idx;
- } else {
- last_idx = -1;
- continue;
- }
- }
- if (macwins[k].win == win) {
- idx = k;
- break;
- }
- }
- }
- if (idx < 0) {
- return 0;
- }
-
- a->x = macwins[idx].x;
- a->y = macwins[idx].y;
- a->width = macwins[idx].width;
- a->height = macwins[idx].height;
- a->depth = depth;
- a->border_width = 0;
- a->backing_store = 0;
- if (macwins[idx].mapped) {
- a->map_state = IsViewable;
- } else {
- a->map_state = IsUnmapped;
- }
-
- last_idx = idx;
-
- return 1;
-}
-
-#define QTMAX 2048
-static Window cret[QTMAX];
-
-extern int CGS_levelmax;
-extern int CGS_levels[];
-
-Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
- Window **children_return, unsigned int *nchildren_return) {
-
- int i, n, k;
-
- *root_return = (Window) 0;
- *parent_return = (Window) 0;
- if (!w) {}
-
- macosxCGS_get_all_windows();
-
- n = 0;
- for (k = CGS_levelmax - 1; k >= 0; k--) {
- for (i = macwinmax - 1; i >= 0; i--) {
- if (n >= QTMAX) break;
- if (macwins[i].level == CGS_levels[k]) {
-if (0) fprintf(stderr, "k=%d i=%d n=%d\n", k, i, n);
- cret[n++] = (Window) macwins[i].win;
- }
- }
- }
- *children_return = cret;
- *nchildren_return = (unsigned int) macwinmax;
-
- return (Status) 1;
-}
-
-int macosx_check_offscreen(int win) {
- sraRegionPtr r0, r1;
- int x1, y1, x2, y2;
- int ret;
- int i = macosxCGS_find_index(win);
-
- if (i < 0) {
- return 0;
- }
-
- x1 = macwins[i].x;
- y1 = macwins[i].y;
- x2 = macwins[i].x + macwins[i].width;
- y2 = macwins[i].y + macwins[i].height;
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- r1 = sraRgnCreateRect(x1, y1, x2, y2);
-
- if (sraRgnAnd(r1, r0)) {
- ret = 0;
- } else {
- ret = 1;
- }
- sraRgnDestroy(r0);
- sraRgnDestroy(r1);
-
- return ret;
-}
-
-int macosx_check_clipped(int win, int *list, int n) {
- sraRegionPtr r0, r1, r2;
- int x1, y1, x2, y2;
- int ret = 0;
- int k, j, i = macosxCGS_find_index(win);
-
- if (i < 0) {
- return 0;
- }
-
- x1 = macwins[i].x;
- y1 = macwins[i].y;
- x2 = macwins[i].x + macwins[i].width;
- y2 = macwins[i].y + macwins[i].height;
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- r1 = sraRgnCreateRect(x1, y1, x2, y2);
- sraRgnAnd(r1, r0);
-
- for (k = 0; k < n; k++) {
- j = macosxCGS_find_index(list[k]); /* XXX slow? */
- if (j < 0) {
- continue;
- }
- x1 = macwins[j].x;
- y1 = macwins[j].y;
- x2 = macwins[j].x + macwins[j].width;
- y2 = macwins[j].y + macwins[j].height;
- r2 = sraRgnCreateRect(x1, y1, x2, y2);
- if (sraRgnAnd(r2, r1)) {
- ret = 1;
- sraRgnDestroy(r2);
- break;
- }
- sraRgnDestroy(r2);
- }
- sraRgnDestroy(r0);
- sraRgnDestroy(r1);
-
- return ret;
-}
-
-
-#endif /* LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY */
-
diff --git a/x11vnc/macosx.h b/x11vnc/macosx.h
deleted file mode 100644
index 60620c8..0000000
--- a/x11vnc/macosx.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_MACOSX_H
-#define _X11VNC_MACOSX_H
-
-/* -- macosx.h -- */
-
-extern void macosx_log(char *);
-extern char *macosx_console_guess(char *str, int *fd);
-extern char *macosx_get_fb_addr(void);
-extern void macosx_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
-extern void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client);
-extern void macosx_event_loop(void);
-extern int macosx_get_cursor(void);
-extern int macosx_get_cursor_pos(int *, int *);
-extern int macosx_valid_window(Window, XWindowAttributes*);
-extern Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
- Window **children_return, unsigned int *nchildren_return);
-extern int macosx_get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
- Window *frame, Window *win);
-extern void macosx_send_sel(char *, int);
-extern void macosx_set_sel(char *, int);
-
-extern void macosx_add_mapnotify(Window win, int level, int map);
-extern void macosx_add_create(Window win, int level);
-extern void macosx_add_destroy(Window win, int level);
-extern void macosx_add_visnotify(Window win, int level, int obscured);
-extern int macosx_checkevent(XEvent *ev);
-
-extern Window macosx_click_frame;
-
-
-#endif /* _X11VNC_MACOSX_H */
diff --git a/x11vnc/macosxCG.c b/x11vnc/macosxCG.c
deleted file mode 100644
index 12041e0..0000000
--- a/x11vnc/macosxCG.c
+++ /dev/null
@@ -1,989 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- macosxCG.c -- */
-
-/*
- * We need to keep this separate from nearly everything else, e.g. rfb.h
- * and the other stuff, otherwise it does not work properly, mouse drags
- * will not work!!
- */
-
-void macosxCG_dummy(void) {}
-
-#if (defined(__MACH__) && defined(__APPLE__))
-
-#include <ApplicationServices/ApplicationServices.h>
-#include <Cocoa/Cocoa.h>
-#include <Carbon/Carbon.h>
-
-void macosxCG_init(void);
-void macosxCG_fini(void);
-void macosxCG_event_loop(void);
-char *macosxCG_get_fb_addr(void);
-
-int macosxCG_CGDisplayPixelsWide(void);
-int macosxCG_CGDisplayPixelsHigh(void);
-int macosxCG_CGDisplayBitsPerPixel(void);
-int macosxCG_CGDisplayBitsPerSample(void);
-int macosxCG_CGDisplaySamplesPerPixel(void);
-int macosxCG_CGDisplayBytesPerRow(void);
-
-void macosxCG_pointer_inject(int mask, int x, int y);
-int macosxCG_get_cursor_pos(int *x, int *y);
-int macosxCG_get_cursor(void);
-void macosxCG_init_key_table(void);
-void macosxCG_keysym_inject(int down, unsigned int keysym);
-void macosxCG_keycode_inject(int down, int keycode);
-
-CGDirectDisplayID displayID = 0;
-
-extern void macosx_log(char *);
-extern int collect_non_X_xdamage(int x_in, int y_in, int w_in, int h_in, int call);
-
-static void macosxCG_callback(CGRectCount n, const CGRect *rects, void *dum) {
- int i, db = 0;
- if (db) fprintf(stderr, "macosx_callback: n=%d\n", (int) n);
- if (!dum) {}
- for (i=0; i < (int) n; i++) {
- if (db > 1) fprintf(stderr, " : %g %g - %g %g\n", rects[i].origin.x, rects[i].origin.y, rects[i].size.width, rects[i].size.height);
- collect_non_X_xdamage( (int) rects[i].origin.x, (int) rects[i].origin.y,
- (int) rects[i].size.width, (int) rects[i].size.height, 1);
- }
-}
-
-#if 0
->
-> if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/local/include -I/opt/local/include -ObjC -g -O2 -Wall -MT x11vnc-macosxCG.o -MD -MP -MF ".deps/x11vnc-macosxCG.Tpo" -c -o x11vnc-macosxCG.o `test -f 'macosxCG.c' || echo './'`macosxCG.c; \
-> then mv -f ".deps/x11vnc-macosxCG.Tpo" ".deps/x11vnc-macosxCG.Po"; else rm -f ".deps/x11vnc-macosxCG.Tpo"; exit 1; fi
-> macosxCG.c:149: warning: CGSetLocalEventsSuppressionInterval is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:373)
-> macosxCG.c:150: warning: CGSetLocalEventsFilterDuringSuppressionState is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:366)
-> macosxCG.c:153: warning: CGSetLocalEventsFilterDuringSuppressionState is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:366)
-> macosxCG.c:244: warning: CGDisplayBaseAddress is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:466)
-> macosxCG.c:254: warning: CGDisplayBitsPerPixel is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:517)
-> macosxCG.c:257: warning: CGDisplayBitsPerSample is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:522)
-> macosxCG.c:260: warning: CGDisplaySamplesPerPixel is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:526)
-> macosxCG.c:263: warning: CGDisplayBytesPerRow is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:476)
-> macosxCG.c:419: warning: CGPostScrollWheelEvent is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:327)
-> macosxCG.c:422: warning: CGPostScrollWheelEvent is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:327)
-> macosxCG.c:425: warning: CGPostMouseEvent is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:307)
-> macosxCG.c:641: warning: CGPostKeyboardEvent is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:333)
-> macosxCG.c:661: warning: CGPostKeyboardEvent is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:333)
->
-
-X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS
-X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS
-X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER
-X11VNC_MACOSX_NO_DEPRECATED
-
-#endif
-
-static int callback_set = 0;
-extern int nofb;
-
-void macosxCG_refresh_callback_on(void) {
- if (nofb) {
- return;
- }
-
- if (! callback_set) {
- if (1) macosx_log("macosxCG_refresh_callback: register\n");
- CGRegisterScreenRefreshCallback(macosxCG_callback, NULL);
- }
- callback_set = 1;
-}
-
-void macosxCG_refresh_callback_off(void) {
- if (callback_set) {
- if (1) macosx_log("macosxCG_refresh_callback: unregister\n");
- CGUnregisterScreenRefreshCallback(macosxCG_callback, NULL);
- }
- callback_set = 0;
-}
-
-extern int macosx_noscreensaver;
-extern int macosx_read_opengl;
-extern int macosx_read_rawfb;
-
-extern void macosxGCS_initpb(void);
-extern int macosxCGP_init_dimming(void);
-extern int macosxCGP_undim(void);
-extern int macosxCGP_dim_shutdown(void);
-extern void macosxCGP_screensaver_timer_off(void);
-extern void macosxCGP_screensaver_timer_on(void);
-extern void macosx_opengl_init(void);
-extern void macosx_opengl_fini(void);
-
-int x11vnc_macosx_no_deprecated_localevents = 0;
-int x11vnc_macosx_no_deprecated_postevents = 0;
-int x11vnc_macosx_no_deprecated_framebuffer = 0;
-
-void macosxCG_init(void) {
-
- x11vnc_macosx_no_deprecated_localevents = 0;
- x11vnc_macosx_no_deprecated_postevents = 0;
- x11vnc_macosx_no_deprecated_framebuffer = 0;
-
- if (getenv("X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) {
- x11vnc_macosx_no_deprecated_localevents = 1;
- }
- if (getenv("X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) {
- x11vnc_macosx_no_deprecated_postevents = 1;
- }
- if (getenv("X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) {
- x11vnc_macosx_no_deprecated_framebuffer = 1;
- }
-
- if (displayID == 0) {
- macosx_log("macosxCG_init: initializing display.\n");
-
- displayID = kCGDirectMainDisplay;
-#ifdef X11VNC_MACOSX_USE_GETMAINDEVICE
- /* not sure this ever did anything. */
- (void) GetMainDevice();
-#endif
- if (displayID == 0) {
- macosx_log("macosxCG_init: could not get kCGDirectMainDisplay / CGMainDisplayID() display.\n");
- exit(1);
- }
-
-#if X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS || X11VNC_MACOSX_NO_DEPRECATED
- macosx_log("NO_DEPRECATED_LOCALEVENTS: not calling CGSetLocalEventsSuppressionInterval()\n");
- macosx_log("NO_DEPRECATED_LOCALEVENTS: not calling CGSetLocalEventsFilterDuringSupressionState()\n");
-#else
- if (!x11vnc_macosx_no_deprecated_localevents) {
- CGSetLocalEventsSuppressionInterval(0.0);
- CGSetLocalEventsFilterDuringSupressionState(
- kCGEventFilterMaskPermitAllEvents,
- kCGEventSupressionStateSupressionInterval);
- CGSetLocalEventsFilterDuringSupressionState(
- kCGEventFilterMaskPermitAllEvents,
- kCGEventSupressionStateRemoteMouseDrag);
- } else {
- macosx_log("NO_DEPRECATED_LOCALEVENTS: not calling CGSetLocalEventsSuppressionInterval()\n");
- macosx_log("NO_DEPRECATED_LOCALEVENTS: not calling CGSetLocalEventsFilterDuringSupressionState()\n");
- }
-#endif
-
- macosx_opengl_init();
-
- if (!macosx_read_opengl) {
- char *addr = macosxCG_get_fb_addr();
- if (addr == NULL) {
- macosx_log("macosxCG_init: could not get raw framebuffer address / CGDisplayBaseAddress().\n");
- exit(1);
- }
- macosx_read_rawfb = 1;
- macosx_log("macosxCG_init: using raw framebuffer address for screen capture.\n");
- }
-
- macosxCGP_init_dimming();
- if (macosx_noscreensaver) {
- macosxCGP_screensaver_timer_on();
- }
-
- macosxGCS_initpb();
- }
-}
-
-void macosxCG_fini(void) {
- macosxCGP_dim_shutdown();
- if (macosx_noscreensaver) {
- macosxCGP_screensaver_timer_off();
- }
- macosxCG_refresh_callback_off();
- macosx_opengl_fini();
- displayID = 0;
-}
-
-extern int dpy_x, dpy_y, bpp, wdpy_x, wdpy_y;
-extern int client_count, nofb;
-extern void do_new_fb(int);
-extern int macosx_wait_for_switch, macosx_resize;
-
-extern void macosxGCS_poll_pb(void);
-#if 0
-extern void usleep(unsigned long usec);
-#else
-extern int usleep(useconds_t usec);
-#endif
-extern unsigned int sleep(unsigned int seconds);
-extern void clean_up_exit(int ret);
-
-void macosxCG_event_loop(void) {
- OSStatus rc;
- int nbpp;
- static int nbpp_save = -1;
-
- macosxGCS_poll_pb();
- if (nofb) {
- return;
- }
-
- rc = RunCurrentEventLoop(kEventDurationSecond/30);
-
- if (client_count) {
- macosxCG_refresh_callback_on();
- } else {
- macosxCG_refresh_callback_off();
- }
-
- nbpp = macosxCG_CGDisplayBitsPerPixel();
-
- if (nbpp_save < 0) {
- nbpp_save = nbpp;
- }
-
- if (nbpp > 0 && nbpp != nbpp_save) {
- nbpp_save = nbpp;
- if (macosx_resize) {
- do_new_fb(1);
- }
- } else if (wdpy_x != macosxCG_CGDisplayPixelsWide()) {
- if (wdpy_y != macosxCG_CGDisplayPixelsHigh()) {
- if (macosx_wait_for_switch) {
- int cnt = 0;
- while (1) {
- if(macosxCG_CGDisplayPixelsWide() > 0) {
- if(macosxCG_CGDisplayPixelsHigh() > 0) {
- usleep(500*1000);
- break;
- }
- }
- if ((cnt++ % 120) == 0) {
- macosx_log("waiting for user to "
- "switch back..\n");
- }
- sleep(1);
- }
- if (wdpy_x == macosxCG_CGDisplayPixelsWide()) {
- if (wdpy_y == macosxCG_CGDisplayPixelsHigh()) {
- macosx_log("we're back...\n");
- return;
- }
- }
- }
- if (macosx_resize) {
- do_new_fb(1);
- }
- }
- }
- if (nbpp > 0) {
- nbpp_save = nbpp;
- }
-}
-
-extern int macosx_no_rawfb;
-extern int macosx_read_opengl;
-extern int macosx_opengl_get_width();
-extern int macosx_opengl_get_height();
-extern int macosx_opengl_get_bpp();
-extern int macosx_opengl_get_bps();
-extern int macosx_opengl_get_spp();
-
-#if X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER || X11VNC_MACOSX_NO_DEPRECATED
-
-char *macosxCG_get_fb_addr(void) {
- return NULL;
-}
-int macosxCG_CGDisplayPixelsWide(void) {
- return macosx_opengl_get_width();
-}
-int macosxCG_CGDisplayPixelsHigh(void) {
- return macosx_opengl_get_height();
-}
-int macosxCG_CGDisplayBitsPerPixel(void) {
- return macosx_opengl_get_bpp();
-}
-int macosxCG_CGDisplayBitsPerSample(void) {
- return macosx_opengl_get_bps();
-}
-int macosxCG_CGDisplaySamplesPerPixel(void) {
- return macosx_opengl_get_spp();
-}
-int macosxCG_CGDisplayBytesPerRow(void) {
- return macosx_opengl_get_width() * macosx_opengl_get_bpp() / 8;
-}
-
-#else
-
-char *macosxCG_get_fb_addr(void) {
- if (x11vnc_macosx_no_deprecated_framebuffer) {
- macosx_log("CGDisplayBaseAddress disabled by env. var\n");
- return NULL;
- }
- if (macosx_no_rawfb) {
- macosx_log("CGDisplayBaseAddress disabled by user.\n");
- return NULL;
- }
- if (macosx_read_opengl) {
- macosx_log("CGDisplayBaseAddress disabled by OpenGL.\n");
- return NULL;
- }
- return (char *) CGDisplayBaseAddress(displayID);
-}
-
-int macosxCG_CGDisplayPixelsWide(void) {
- if ((0 && macosx_read_opengl) || x11vnc_macosx_no_deprecated_framebuffer) {
- return macosx_opengl_get_width();
- }
- return (int) CGDisplayPixelsWide(displayID);
-}
-int macosxCG_CGDisplayPixelsHigh(void) {
- if ((0 && macosx_read_opengl) || x11vnc_macosx_no_deprecated_framebuffer) {
- return macosx_opengl_get_height();
- }
- return (int) CGDisplayPixelsHigh(displayID);
-}
-int macosxCG_CGDisplayBitsPerPixel(void) {
- if ((0 && macosx_read_opengl) || x11vnc_macosx_no_deprecated_framebuffer) {
- return macosx_opengl_get_bpp();
- }
- return (int) CGDisplayBitsPerPixel(displayID);
-}
-int macosxCG_CGDisplayBitsPerSample(void) {
- if (macosx_read_opengl || x11vnc_macosx_no_deprecated_framebuffer) {
- return macosx_opengl_get_bps();
- }
- return (int) CGDisplayBitsPerSample(displayID);
-}
-int macosxCG_CGDisplaySamplesPerPixel(void) {
- if (macosx_read_opengl || x11vnc_macosx_no_deprecated_framebuffer) {
- return macosx_opengl_get_spp();
- }
- return (int) CGDisplaySamplesPerPixel(displayID);
-}
-int macosxCG_CGDisplayBytesPerRow(void) {
- if (macosx_read_opengl || x11vnc_macosx_no_deprecated_framebuffer) {
- return macosx_opengl_get_width() * macosx_opengl_get_bpp()/8;
- }
- return (int) CGDisplayBytesPerRow(displayID);;
-}
-
-#endif
-
-typedef int CGSConnectionRef;
-static CGSConnectionRef conn = 0;
-extern CGError CGSNewConnection(void*, CGSConnectionRef*);
-extern CGError CGSReleaseConnection(CGSConnectionRef);
-extern CGError CGSGetGlobalCursorDataSize(CGSConnectionRef, int*);
-extern CGError CGSGetGlobalCursorData(CGSConnectionRef, unsigned char*,
- int*, int*, CGRect*, CGPoint*, int*, int*, int*);
-extern CGError CGSGetCurrentCursorLocation(CGSConnectionRef, CGPoint*);
-extern int CGSCurrentCursorSeed(void);
-extern int CGSHardwareCursorActive();
-
-static unsigned int last_local_button_mask = 0;
-static unsigned int last_local_mod_mask = 0;
-static int last_local_x = 0;
-static int last_local_y = 0;
-
-extern unsigned int display_button_mask;
-extern unsigned int display_mod_mask;
-extern int got_local_pointer_input;
-extern time_t last_local_input;
-
-static CGPoint current_cursor_pos(void) {
- CGPoint pos;
- pos.x = 0;
- pos.y = 0;
- if (! conn) {
- if (CGSNewConnection(NULL, &conn) != kCGErrorSuccess) {
- macosx_log("CGSNewConnection error.\n");
- if (!dpy_x || !dpy_y || !wdpy_x || !wdpy_y) {
- clean_up_exit(1);
- }
- }
- }
- if (CGSGetCurrentCursorLocation(conn, &pos) != kCGErrorSuccess) {
- macosx_log("CGSGetCurrentCursorLocation error\n");
- }
-
- display_button_mask = GetCurrentButtonState();
-#if 0
-/* not used yet */
- display_mod_mask = GetCurrentKeyModifiers();
-#endif
-
- if (last_local_button_mask != display_button_mask) {
- got_local_pointer_input++;
- last_local_input = time(NULL);
- } else if (pos.x != last_local_x || pos.y != last_local_y) {
- got_local_pointer_input++;
- last_local_input = time(NULL);
- }
- last_local_button_mask = display_button_mask;
- last_local_mod_mask = display_mod_mask;
- last_local_x = pos.x;
- last_local_y = pos.y;
-
- return pos;
-}
-
-int macosxCG_get_cursor_pos(int *x, int *y) {
- CGPoint pos = current_cursor_pos();
- *x = pos.x;
- *y = pos.y;
- return 1;
-}
-
-extern int get_cursor_serial(int);
-extern int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp, int xhot, int yhot);
-
-int macosxCG_get_cursor(void) {
- int last_idx = (int) get_cursor_serial(1);
- int which = 1;
- CGError err;
- int datasize, row_bytes, cdepth, comps, bpcomp;
- CGRect rect;
- CGPoint hot;
- unsigned char *data;
- int cursor_seed;
- static int last_cursor_seed = -1;
- static time_t last_fetch = 0;
- time_t now = time(NULL);
-
- if (last_idx) {
- which = last_idx;
- }
-
- if (! conn) {
- if (CGSNewConnection(NULL, &conn) != kCGErrorSuccess) {
- macosx_log("CGSNewConnection error.\n");
- if (!dpy_x || !dpy_y || !wdpy_x || !wdpy_y) {
- clean_up_exit(1);
- }
- return which;
- }
- }
-
- /* XXX all of these interfaces are undocumented. */
-
- cursor_seed = CGSCurrentCursorSeed();
- if (last_idx && cursor_seed == last_cursor_seed) {
- if (now < last_fetch + 2) {
- return which;
- }
- }
- last_cursor_seed = cursor_seed;
- last_fetch = now;
-
- if (CGSGetGlobalCursorDataSize(conn, &datasize) != kCGErrorSuccess) {
- macosx_log("CGSGetGlobalCursorDataSize error\n");
- return which;
- }
-
- data = (unsigned char*) malloc(datasize);
-
- err = CGSGetGlobalCursorData(conn, data, &datasize, &row_bytes,
- &rect, &hot, &cdepth, &comps, &bpcomp);
-#if 0
- fprintf(stderr, "datasize: %d row_bytes: %d cdepth: %d comps: %d bpcomp: %d w: %d h: %d\n",
- datasize, row_bytes, cdepth, comps, bpcomp, (int) rect.size.width, (int) rect.size.height);
-#endif
- if (err != kCGErrorSuccess) {
- macosx_log("CGSGetGlobalCursorData error\n");
- return which;
- }
-
- if (cdepth == 24) {
- cdepth = 32;
- }
-
- if (sizeof(long) == 8 && comps * bpcomp <= 32) {
- /* pad it out to unsigned long array size (like xfixes) */
- int i;
- unsigned char *dsave;
- unsigned char *data64 = (unsigned char*) malloc(2 *datasize);
- unsigned int *uI = (unsigned int *) data;
- unsigned long *uL = (unsigned long *) data64;
- for (i=0; i < datasize/4; i++) {
- uL[i] = uI[i];
- }
- dsave = data;
- data = data64;
- free(dsave);
- }
-
- which = store_cursor(cursor_seed, (unsigned long*) data,
- (int) rect.size.width, (int) rect.size.height, cdepth, (int) hot.x, (int) hot.y);
-
- free(data);
- return(which);
-}
-
-extern int macosx_mouse_wheel_speed;
-extern int macosx_swap23;
-extern int off_x, coff_x, off_y, coff_y;
-
-extern int debug_pointer;
-
-static void CGPostScrollWheelEvent_wr(CGWheelCount wheel_count, int wheel_distance) {
- static int post_mode = -1, mcnt = 0;
-
-#if !X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS && !X11VNC_MACOSX_NO_DEPRECATED
- if (post_mode < 0) {
- post_mode = 1;
- if (getenv("X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) {
- post_mode = 0;
- }
- }
-
- if (post_mode) {
- if (mcnt++ < 10 || debug_pointer) fprintf(stderr, "CGPostScrollWheelEvent()\n");
- CGPostScrollWheelEvent(wheel_count, wheel_distance);
- } else
-#endif
- {
- /* XXX 10.5 and later */
-#ifndef X11VNC_MACOSX_NO_CGEVENTCREATESCROLLWHEELEVENT
- CGEventRef event;
- event = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, wheel_count, wheel_distance);
- if (event != NULL) {
- CGEventPost(kCGHIDEventTap, event);
- CFRelease(event);
- }
-#endif
- if (mcnt++ < 10 || debug_pointer) fprintf(stderr, "CGEventCreateScrollWheelEvent()\n");
- }
-}
-
-static void CGPostMouseEvent_wr(CGPoint loc, int update, int count, int d1, int d2, int d3, int p1, int p2, int p3) {
- static int post_mode = -1, mcnt = 0;
-
-#if !X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS && !X11VNC_MACOSX_NO_DEPRECATED
- if (post_mode < 0) {
- post_mode = 1;
- if (getenv("X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) {
- post_mode = 0;
- }
- }
-
- if (post_mode) {
- if (mcnt++ < 10 || debug_pointer) fprintf(stderr, "CGPostMouseEvent()\n");
- CGPostMouseEvent(loc, update, count, d1, d2, d3);
- } else
-#endif
- {
- /* XXX 10.4 and later */
-#ifndef X11VNC_MACOSX_NO_CGEVENTCREATEMOUSEEVENT
- CGEventRef event;
- static int xp = -1, yp;
-
- if (xp == -1) {
- xp = loc.x;
- yp = loc.y;
- }
- if (xp != loc.x || yp != loc.y) {
- int moved = 0;
- if (p1 && p1 == d1) {
- event = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDragged, loc, 0);
- if (event != NULL) {
- moved = 1;
- CGEventPost(kCGHIDEventTap, event);
- CFRelease(event);
- }
- }
- if (p3 && p3 == d3) {
- event = CGEventCreateMouseEvent(NULL, kCGEventOtherMouseDragged, loc, 0);
- if (event != NULL) {
- moved = 1;
- CGEventPost(kCGHIDEventTap, event);
- CFRelease(event);
- }
- }
- if (p2 && p2 == d2) {
- event = CGEventCreateMouseEvent(NULL, kCGEventRightMouseDragged, loc, 0);
- if (event != NULL) {
- moved = 1;
- CGEventPost(kCGHIDEventTap, event);
- CFRelease(event);
- }
- }
- if (!moved) {
- event = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, loc, 0);
- if (event != NULL) {
- CGEventPost(kCGHIDEventTap, event);
- CFRelease(event);
- }
- }
- }
- xp = loc.x;
- yp = loc.y;
- if (p1 != d1) {
- CGEventType type = (!p1 && d1) ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
- event = CGEventCreateMouseEvent(NULL, type, loc, 0);
- if (event != NULL) {
- CGEventPost(kCGHIDEventTap, event);
- CFRelease(event);
- }
- }
- if (p3 != d3) {
- CGEventType type = (!p3 && d3) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
- event = CGEventCreateMouseEvent(NULL, type, loc, kCGMouseButtonCenter);
- if (event != NULL) {
- CGEventPost(kCGHIDEventTap, event);
- CFRelease(event);
- }
- }
- if (p2 != d2) {
- CGEventType type = (!p2 && d2) ? kCGEventRightMouseDown : kCGEventRightMouseUp;
- event = CGEventCreateMouseEvent(NULL, type, loc, 0);
- if (event != NULL) {
- CGEventPost(kCGHIDEventTap, event);
- CFRelease(event);
- }
- }
-#endif
- if (mcnt++ < 10 || debug_pointer) fprintf(stderr, "CGEventCreateMouseEvent()\n");
- }
-}
-
-void macosxCG_pointer_inject(int mask, int x, int y) {
- int swap23 = macosx_swap23;
- int s1 = 0, s2 = 1, s3 = 2, s4 = 3, s5 = 4;
- CGPoint loc;
- int wheel_distance = macosx_mouse_wheel_speed;
- static int cnt = 0;
- static int first = 1, prev1 = 0, prev2 = 0, prev3 = 0;
- int curr1, curr2, curr3;
-
- if (swap23) {
- s2 = 2;
- s3 = 1;
- }
-
- loc.x = x + off_x + coff_x;
- loc.y = y + off_y + coff_y;
-
- if ((cnt++ % 10) == 0) {
- macosxCGP_undim();
- }
-
- if ((mask & (1 << s4))) {
- CGPostScrollWheelEvent_wr(1, wheel_distance);
- }
- if ((mask & (1 << s5))) {
- CGPostScrollWheelEvent_wr(1, -wheel_distance);
- }
-
- curr1 = (mask & (1 << s1)) ? TRUE : FALSE;
- curr2 = (mask & (1 << s2)) ? TRUE : FALSE;
- curr3 = (mask & (1 << s3)) ? TRUE : FALSE;
-
- if (first) {
- prev1 = curr1;
- prev2 = curr2;
- prev3 = curr3;
- first = 0;
- }
-
- CGPostMouseEvent_wr(loc, TRUE, 3, curr1, curr2, curr3, prev1, prev2, prev3);
-
- prev1 = curr1;
- prev2 = curr2;
- prev3 = curr3;
-}
-
-#define keyTableSize 0xFFFF
-
-#include <rfb/keysym.h>
-
-static int USKeyCodes[] = {
- /* The alphabet */
- XK_A, 0, /* A */
- XK_B, 11, /* B */
- XK_C, 8, /* C */
- XK_D, 2, /* D */
- XK_E, 14, /* E */
- XK_F, 3, /* F */
- XK_G, 5, /* G */
- XK_H, 4, /* H */
- XK_I, 34, /* I */
- XK_J, 38, /* J */
- XK_K, 40, /* K */
- XK_L, 37, /* L */
- XK_M, 46, /* M */
- XK_N, 45, /* N */
- XK_O, 31, /* O */
- XK_P, 35, /* P */
- XK_Q, 12, /* Q */
- XK_R, 15, /* R */
- XK_S, 1, /* S */
- XK_T, 17, /* T */
- XK_U, 32, /* U */
- XK_V, 9, /* V */
- XK_W, 13, /* W */
- XK_X, 7, /* X */
- XK_Y, 16, /* Y */
- XK_Z, 6, /* Z */
- XK_a, 0, /* a */
- XK_b, 11, /* b */
- XK_c, 8, /* c */
- XK_d, 2, /* d */
- XK_e, 14, /* e */
- XK_f, 3, /* f */
- XK_g, 5, /* g */
- XK_h, 4, /* h */
- XK_i, 34, /* i */
- XK_j, 38, /* j */
- XK_k, 40, /* k */
- XK_l, 37, /* l */
- XK_m, 46, /* m */
- XK_n, 45, /* n */
- XK_o, 31, /* o */
- XK_p, 35, /* p */
- XK_q, 12, /* q */
- XK_r, 15, /* r */
- XK_s, 1, /* s */
- XK_t, 17, /* t */
- XK_u, 32, /* u */
- XK_v, 9, /* v */
- XK_w, 13, /* w */
- XK_x, 7, /* x */
- XK_y, 16, /* y */
- XK_z, 6, /* z */
-
- /* Numbers */
- XK_0, 29, /* 0 */
- XK_1, 18, /* 1 */
- XK_2, 19, /* 2 */
- XK_3, 20, /* 3 */
- XK_4, 21, /* 4 */
- XK_5, 23, /* 5 */
- XK_6, 22, /* 6 */
- XK_7, 26, /* 7 */
- XK_8, 28, /* 8 */
- XK_9, 25, /* 9 */
-
- /* Symbols */
- XK_exclam, 18, /* ! */
- XK_at, 19, /* @ */
- XK_numbersign, 20, /* # */
- XK_dollar, 21, /* $ */
- XK_percent, 23, /* % */
- XK_asciicircum, 22, /* ^ */
- XK_ampersand, 26, /* & */
- XK_asterisk, 28, /* * */
- XK_parenleft, 25, /* ( */
- XK_parenright, 29, /* ) */
- XK_minus, 27, /* - */
- XK_underscore, 27, /* _ */
- XK_equal, 24, /* = */
- XK_plus, 24, /* + */
- XK_grave, 50, /* ` */ /* XXX ? */
- XK_asciitilde, 50, /* ~ */
- XK_bracketleft, 33, /* [ */
- XK_braceleft, 33, /* { */
- XK_bracketright, 30, /* ] */
- XK_braceright, 30, /* } */
- XK_semicolon, 41, /* ; */
- XK_colon, 41, /* : */
- XK_apostrophe, 39, /* ' */
- XK_quotedbl, 39, /* " */
- XK_comma, 43, /* , */
- XK_less, 43, /* < */
- XK_period, 47, /* . */
- XK_greater, 47, /* > */
- XK_slash, 44, /* / */
- XK_question, 44, /* ? */
- XK_backslash, 42, /* \ */
- XK_bar, 42, /* | */
- /* OS X Sends this (END OF MEDIUM) for Shift-Tab (with US Keyboard) */
- 0x0019, 48, /* Tab */
- XK_space, 49, /* Space */
-};
-
-static int SpecialKeyCodes[] = {
- /* "Special" keys */
- XK_Return, 36, /* Return */
- XK_Delete, 117, /* Delete */
- XK_Tab, 48, /* Tab */
- XK_Escape, 53, /* Esc */
- XK_Caps_Lock, 57, /* Caps Lock */
- XK_Num_Lock, 71, /* Num Lock */
- XK_Scroll_Lock, 107, /* Scroll Lock */
- XK_Pause, 113, /* Pause */
- XK_BackSpace, 51, /* Backspace */
- XK_Insert, 114, /* Insert */
-
- /* Cursor movement */
- XK_Up, 126, /* Cursor Up */
- XK_Down, 125, /* Cursor Down */
- XK_Left, 123, /* Cursor Left */
- XK_Right, 124, /* Cursor Right */
- XK_Page_Up, 116, /* Page Up */
- XK_Page_Down, 121, /* Page Down */
- XK_Home, 115, /* Home */
- XK_End, 119, /* End */
-
- /* Numeric keypad */
- XK_KP_0, 82, /* KP 0 */
- XK_KP_1, 83, /* KP 1 */
- XK_KP_2, 84, /* KP 2 */
- XK_KP_3, 85, /* KP 3 */
- XK_KP_4, 86, /* KP 4 */
- XK_KP_5, 87, /* KP 5 */
- XK_KP_6, 88, /* KP 6 */
- XK_KP_7, 89, /* KP 7 */
- XK_KP_8, 91, /* KP 8 */
- XK_KP_9, 92, /* KP 9 */
- XK_KP_Enter, 76, /* KP Enter */
- XK_KP_Decimal, 65, /* KP . */
- XK_KP_Add, 69, /* KP + */
- XK_KP_Subtract, 78, /* KP - */
- XK_KP_Multiply, 67, /* KP * */
- XK_KP_Divide, 75, /* KP / */
-
- /* Function keys */
- XK_F1, 122, /* F1 */
- XK_F2, 120, /* F2 */
- XK_F3, 99, /* F3 */
- XK_F4, 118, /* F4 */
- XK_F5, 96, /* F5 */
- XK_F6, 97, /* F6 */
- XK_F7, 98, /* F7 */
- XK_F8, 100, /* F8 */
- XK_F9, 101, /* F9 */
- XK_F10, 109, /* F10 */
- XK_F11, 103, /* F11 */
- XK_F12, 111, /* F12 */
-
- /* Modifier keys */
- XK_Alt_L, 55, /* Alt Left (-> Command) */
- XK_Alt_R, 55, /* Alt Right (-> Command) */
- XK_Shift_L, 56, /* Shift Left */
- XK_Shift_R, 56, /* Shift Right */
- XK_Meta_L, 58, /* Option Left (-> Option) */
- XK_Meta_R, 58, /* Option Right (-> Option) */
- XK_Super_L, 58, /* Option Left (-> Option) */
- XK_Super_R, 58, /* Option Right (-> Option) */
- XK_Control_L, 59, /* Ctrl Left */
- XK_Control_R, 59, /* Ctrl Right */
-};
-
-CGKeyCode keyTable[keyTableSize];
-unsigned char keyTableMods[keyTableSize];
-
-void macosxCG_init_key_table(void) {
- static int init = 0;
- int i;
- if (init) {
- return;
- }
- init = 1;
-
- for (i=0; i < keyTableSize; i++) {
- keyTable[i] = 0xFFFF;
- keyTableMods[i] = 0;
- }
- for (i=0; i< (int) (sizeof(USKeyCodes) / sizeof(int)); i += 2) {
- int j = USKeyCodes[i];
- keyTable[(unsigned short) j] = (CGKeyCode) USKeyCodes[i+1];
- }
- for (i=0; i< (int) (sizeof(SpecialKeyCodes) / sizeof(int)); i += 2) {
- int j = SpecialKeyCodes[i];
- keyTable[(unsigned short) j] = (CGKeyCode) SpecialKeyCodes[i+1];
- }
-}
-
-extern void init_key_table(void);
-extern int macosx_us_kbd;
-
-extern int debug_keyboard;
-
-void CGPostKeyboardEvent_wr(CGCharCode keyChar, CGKeyCode keyCode, int down) {
- static int post_mode = -1, mcnt = 0;
-
-#if !X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS && !X11VNC_MACOSX_NO_DEPRECATED
- if (post_mode < 0) {
- post_mode = 1;
- if (getenv("X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) {
- post_mode = 0;
- }
- }
-
- if (post_mode) {
- if (mcnt++ < 10 || debug_keyboard) fprintf(stderr, "CGPostKeyboardEvent(keyChar=%d, keyCode=%d, down=%d)\n", keyChar, keyCode, down);
- CGPostKeyboardEvent(keyChar, keyCode, down);
- } else
-#endif
- {
- /* XXX 10.4 and later */
-#ifndef X11VNC_MACOSX_NO_CGEVENTCREATEKEYBOARDEVENT
- CGEventRef event;
- event = CGEventCreateKeyboardEvent(NULL, keyCode, down);
- if (event != NULL) {
- CGEventPost(kCGHIDEventTap, event);
- CFRelease(event);
- }
-#endif
- if (mcnt++ < 10 || debug_keyboard) fprintf(stderr, "CGEventCreateKeyboardEvent(NULL, keyCode=%d, down=%d)\n", keyCode, down);
- }
-}
-
-void macosxCG_keycode_inject(int down, int keycode) {
- CGKeyCode keyCode = (CGKeyCode) keycode;
- CGCharCode keyChar = 0;
-
- if (debug_keyboard) fprintf(stderr, "macosxCG_keycode_inject(down=%d, keycode=%d)\n", down, keycode);
-
- CGPostKeyboardEvent_wr(keyChar, keyCode, down);
-}
-
-void macosxCG_keysym_inject(int down, unsigned int keysym) {
- CGKeyCode keyCode = keyTable[(unsigned short)keysym];
- CGCharCode keyChar = 0;
-#if 0
- int pressModsForKeys = FALSE;
- UInt32 modsForKey = keyTableMods[keysym] << 8;
-#endif
-
- init_key_table();
-
- if (debug_keyboard) fprintf(stderr, "macosxCG_keysym_inject(down=%d, keysym=%d)\n", down, (int) keysym);
-
- if (keysym < 0xFF && macosx_us_kbd) {
- keyChar = (CGCharCode) keysym;
- if (debug_keyboard) fprintf(stderr, "macosxCG_keysym_inject keyChar=>%d\n", (int) keyChar);
- }
- if (keyCode == 0xFFFF) {
- return;
- }
- macosxCGP_undim();
-
- CGPostKeyboardEvent_wr(keyChar, keyCode, down);
-}
-
-#endif /* __APPLE__ */
-
-
diff --git a/x11vnc/macosxCG.h b/x11vnc/macosxCG.h
deleted file mode 100644
index fb9e497..0000000
--- a/x11vnc/macosxCG.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_MACOSXCG_H
-#define _X11VNC_MACOSXCG_H
-
-/* -- macosxCG.h -- */
-
-extern void macosxCG_init(void);
-extern void macosxCG_fini(void);
-extern void macosxCG_event_loop(void);
-extern char *macosxCG_get_fb_addr(void);
-
-extern int macosxCG_CGDisplayPixelsWide(void);
-extern int macosxCG_CGDisplayPixelsHigh(void);
-extern int macosxCG_CGDisplayBitsPerPixel(void);
-extern int macosxCG_CGDisplayBitsPerSample(void);
-extern int macosxCG_CGDisplaySamplesPerPixel(void);
-extern int macosxCG_CGDisplayBytesPerRow(void);
-
-extern void macosxCG_pointer_inject(int mask, int x, int y);
-extern int macosxCG_get_cursor_pos(int *x, int *y);
-extern int macosxCG_get_cursor(void);
-extern void macosxCG_init_key_table(void);
-extern void macosxCG_keysym_inject(int down, unsigned int keysym);
-extern void macosxCG_keycode_inject(int down, int keycode);
-
-extern void macosxCG_refresh_callback_off(void);
-extern void macosxCG_refresh_callback_on(void);
-
-
-
-#endif /* _X11VNC_MACOSXCG_H */
diff --git a/x11vnc/macosxCGP.c b/x11vnc/macosxCGP.c
deleted file mode 100644
index 230042c..0000000
--- a/x11vnc/macosxCGP.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- macosxCGP.c -- */
-
-void macosxCGP_unused(void) {}
-
-#if (defined(__MACH__) && defined(__APPLE__))
-
-#include <ApplicationServices/ApplicationServices.h>
-#include <Cocoa/Cocoa.h>
-#include <Carbon/Carbon.h>
-
-int macosxCGP_save_dim(void);
-int macosxCGP_restore_dim(void);
-int macosxCGP_save_sleep(void);
-int macosxCGP_restore_sleep(void);
-int macosxCGP_init_dimming(void);
-int macosxCGP_undim(void);
-int macosxCGP_dim_shutdown(void);
-void macosxCGP_screensaver_timer_off(void);
-void macosxCGP_screensaver_timer_on(void);
-
-#include <IOKit/pwr_mgt/IOPMLib.h>
-#include <IOKit/pwr_mgt/IOPM.h>
-
-extern CGDirectDisplayID displayID;
-
-static unsigned long dim_time;
-static unsigned long sleep_time;
-static int dim_time_saved = 0;
-static int sleep_time_saved = 0;
-static int initialized = 0;
-static mach_port_t master_dev_port;
-static io_connect_t power_mgt;
-
-extern int client_count;
-extern int macosx_nodimming;
-extern int macosx_nosleep;
-extern int macosx_noscreensaver;
-
-static EventLoopTimerUPP sstimerUPP;
-static EventLoopTimerRef sstimer;
-
-void macosxCG_screensaver_timer(EventLoopTimerRef timer, void *data) {
- if (0) fprintf(stderr, "macosxCG_screensaver_timer: %d\n", (int) time(0));
- if (!timer || !data) {}
- if (macosx_nosleep && client_count) {
- if (0) fprintf(stderr, "UpdateSystemActivity: %d\n", (int) time(0));
- UpdateSystemActivity(IdleActivity);
- }
-}
-
-void macosxCGP_screensaver_timer_off(void) {
- if (0) fprintf(stderr, "macosxCGP_screensaver_timer_off: %d\n", (int) time(0));
- RemoveEventLoopTimer(sstimer);
- DisposeEventLoopTimerUPP(sstimerUPP);
-}
-
-void macosxCGP_screensaver_timer_on(void) {
- if (0) fprintf(stderr, "macosxCGP_screensaver_timer_on: %d\n", (int) time(0));
- sstimerUPP = NewEventLoopTimerUPP(macosxCG_screensaver_timer);
- InstallEventLoopTimer(GetMainEventLoop(), kEventDurationSecond * 30,
- kEventDurationSecond * 30, sstimerUPP, NULL, &sstimer);
-}
-
-int macosxCGP_save_dim(void) {
- if (IOPMGetAggressiveness(power_mgt, kPMMinutesToDim,
- &dim_time) != kIOReturnSuccess) {
- return 0;
- }
- dim_time_saved = 1;
- return 1;
-}
-
-int macosxCGP_restore_dim(void) {
- if (! dim_time_saved) {
- return 0;
- }
- if (IOPMSetAggressiveness(power_mgt, kPMMinutesToDim,
- dim_time) != kIOReturnSuccess) {
- return 0;
- }
- dim_time_saved = 0;
- dim_time = 0;
- return 1;
-}
-
-int macosxCGP_save_sleep(void) {
- if (IOPMGetAggressiveness(power_mgt, kPMMinutesToSleep,
- &sleep_time) != kIOReturnSuccess) {
- return 0;
- }
- sleep_time_saved = 1;
- return 1;
-}
-
-int macosxCGP_restore_sleep(void) {
- if (! sleep_time_saved) {
- return 0;
- }
- if (IOPMSetAggressiveness(power_mgt, kPMMinutesToSleep,
- dim_time) != kIOReturnSuccess) {
- return 0;
- }
- sleep_time_saved = 0;
- sleep_time = 0;
- return 1;
-}
-
-int macosxCGP_init_dimming(void) {
- if (IOMasterPort(bootstrap_port, &master_dev_port) !=
- kIOReturnSuccess) {
- return 0;
- }
- if (!(power_mgt = IOPMFindPowerManagement(master_dev_port))) {
- return 0;
- }
- if (macosx_nodimming) {
- if (! macosxCGP_save_dim()) {
- return 0;
- }
- if (IOPMSetAggressiveness(power_mgt, kPMMinutesToDim, 0)
- != kIOReturnSuccess) {
- return 0;
- }
- }
- if (macosx_nosleep) {
- if (! macosxCGP_save_sleep()) {
- return 0;
- }
- if (IOPMSetAggressiveness(power_mgt, kPMMinutesToSleep, 0)
- != kIOReturnSuccess) {
- return 0;
- }
- }
-
- initialized = 1;
- return 1;
-}
-
-int macosxCGP_undim(void) {
- if (! initialized) {
- return 0;
- }
- if (! macosx_nodimming) {
- if (! macosxCGP_save_dim()) {
- return 0;
- }
- if (IOPMSetAggressiveness(power_mgt, kPMMinutesToDim, 0)
- != kIOReturnSuccess) {
- return 0;
- }
- if (! macosxCGP_restore_dim()) {
- return 0;
- }
- }
- if (! macosx_nosleep) {
- if (! macosxCGP_save_sleep()) {
- return 0;
- }
- if (IOPMSetAggressiveness(power_mgt, kPMMinutesToSleep, 0)
- != kIOReturnSuccess) {
- return 0;
- }
- if (! macosxCGP_restore_sleep()) {
- return 0;
- }
- }
- return 1;
-}
-
-int macosxCGP_dim_shutdown(void) {
- if (! initialized) {
- return 0;
- }
- if (dim_time_saved) {
- if (! macosxCGP_restore_dim()) {
- return 0;
- }
- }
- if (sleep_time_saved) {
- if (! macosxCGP_restore_sleep()) {
- return 0;
- }
- }
- return 1;
-}
-
-#endif /* __APPLE__ */
-
-
diff --git a/x11vnc/macosxCGP.h b/x11vnc/macosxCGP.h
deleted file mode 100644
index 47026b0..0000000
--- a/x11vnc/macosxCGP.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_MACOSXCGP_H
-#define _X11VNC_MACOSXCGP_H
-
-/* -- macosxCGP.h -- */
-
-extern int macosxCGP_save_dim(void);
-extern int macosxCGP_restore_dim(void);
-extern int macosxCGP_save_sleep(void);
-extern int macosxCGP_restore_sleep(void);
-extern int macosxCGP_init_dimming(void);
-extern int macosxCGP_undim(void);
-extern int macosxCGP_dim_shutdown(void);
-extern void macosxCGP_screensaver_timer_off(void);
-extern void macosxCGP_screensaver_timer_on(void);
-
-
-#endif /* _X11VNC_MACOSXCGP_H */
diff --git a/x11vnc/macosxCGS.c b/x11vnc/macosxCGS.c
deleted file mode 100644
index 7680130..0000000
--- a/x11vnc/macosxCGS.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- macosxCGS.c -- */
-
-/*
- * We need to keep this separate from nearly everything else, e.g. rfb.h
- * and the other stuff, otherwise it does not work properly, mouse drags
- * will not work!!
- */
-void macosxCGS_unused(void) {}
-
-#if (defined(__MACH__) && defined(__APPLE__))
-
-#include <ApplicationServices/ApplicationServices.h>
-#include <Cocoa/Cocoa.h>
-#include <Carbon/Carbon.h>
-
-extern CGDirectDisplayID displayID;
-
-void macosxCGS_get_all_windows(void);
-int macosxCGS_get_qlook(int);
-void macosxGCS_set_pasteboard(char *str, int len);
-
-typedef CGError CGSError;
-typedef long CGSWindowCount;
-typedef void * CGSConnectionID;
-typedef int CGSWindowID;
-typedef CGSWindowID* CGSWindowIDList;
-typedef CGWindowLevel CGSWindowLevel;
-typedef NSRect CGSRect;
-
-extern CGSConnectionID _CGSDefaultConnection ();
-
-extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
- CGSConnectionID owner, CGSWindowCount listCapacity,
- CGSWindowIDList list, CGSWindowCount *listCount);
-
-extern CGSError CGSGetWindowList (CGSConnectionID cid,
- CGSConnectionID owner, CGSWindowCount listCapacity,
- CGSWindowIDList list, CGSWindowCount *listCount);
-
-extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
- CGSWindowID wid, CGSRect *rect);
-
-extern CGWindowLevel CGSGetWindowLevel (CGSConnectionID cid,
- CGSWindowID wid, CGSWindowLevel *level);
-
-typedef enum _CGSWindowOrderingMode {
- kCGSOrderAbove = 1, /* Window is ordered above target. */
- kCGSOrderBelow = -1, /* Window is ordered below target. */
- kCGSOrderOut = 0 /* Window is removed from the on-screen window list. */
-} CGSWindowOrderingMode;
-
-extern OSStatus CGSOrderWindow(const CGSConnectionID cid,
- const CGSWindowID wid, CGSWindowOrderingMode place, CGSWindowID relativeToWindowID);
-
-static CGSConnectionID cid = NULL;
-
-extern void macosx_log(char *);
-
-int macwinmax = 0;
-typedef struct windat {
- int win;
- int x, y;
- int width, height;
- int level;
- int mapped;
- int clipped;
- int ncache_only;
-} windat_t;
-
-extern int ncache;
-
-#define MAXWINDAT 4096
-windat_t macwins[MAXWINDAT];
-static CGSWindowID _wins_all[MAXWINDAT];
-static CGSWindowID _wins_mapped[MAXWINDAT];
-static CGSWindowCount _wins_all_cnt, _wins_mapped_cnt;
-static int _wins_int[MAXWINDAT];
-
-#define WINHISTNUM 32768
-#define WINHISTMAX 4
-char whist[WINHISTMAX][WINHISTNUM];
-int whist_idx = -1;
-int qlook[WINHISTNUM];
-
-char is_exist = 0x1;
-char is_mapped = 0x2;
-char is_clipped = 0x4;
-char is_offscreen = 0x8;
-
-extern double dnow(void);
-extern double dnowx(void);
-
-extern int dpy_x, dpy_y;
-extern int macosx_icon_anim_time;
-
-extern void macosx_add_mapnotify(int, int, int);
-extern void macosx_add_create(int, int);
-extern void macosx_add_destroy(int, int);
-extern void macosx_add_visnotify(int, int, int);
-
-int CGS_levelmax;
-int CGS_levels[16];
-
-int macosxCGS_get_qlook(int w) {
- if (w >= WINHISTNUM) {
- return -1;
- }
- return qlook[w];
-}
-
-int macosxCGS_find_index(int w) {
- static int last_index = -1;
- int idx;
-
- if (last_index >= 0) {
- if (macwins[last_index].win == w) {
- return last_index;
- }
- }
-
- idx = macosxCGS_get_qlook(w);
- if (idx >= 0) {
- if (macwins[idx].win == w) {
- last_index = idx;
- return idx;
- }
- }
-
- for (idx=0; idx < macwinmax; idx++) {
- if (macwins[idx].win == w) {
- last_index = idx;
- return idx;
- }
- }
- return -1;
-}
-
-#if 0
-extern void usleep(unsigned long usec);
-#else
-extern int usleep(useconds_t usec);
-#endif
-
-int macosxCGS_follow_animation_win(int win, int idx, int grow) {
- double t = dnow();
- int diffs = 0;
- int x, y, w, h;
- int xp = -1, yp = -1, wp = -1, hp = -1;
- CGSRect rect;
- CGSError err;
-
- int reps = 0;
-
- if (cid == NULL) {
- cid = _CGSDefaultConnection();
- if (cid == NULL) {
- return 0;
- }
- }
-
- if (idx < 0) {
- idx = macosxCGS_find_index(win);
- }
- if (idx < 0) {
- return 0;
- }
-
- while (dnow() < t + 0.001 * macosx_icon_anim_time) {
- err = CGSGetScreenRectForWindow(cid, win, &rect);
- if (err != 0) {
- break;
- }
- x = (int) rect.origin.x;
- y = (int) rect.origin.y;
- w = (int) rect.size.width;
- h = (int) rect.size.height;
-
- if (grow) {
- macwins[idx].x = x;
- macwins[idx].y = y;
- macwins[idx].width = w;
- macwins[idx].height = h;
- }
-
- if (0) fprintf(stderr, " chase: %03dx%03d+%03d+%03d %d\n", w, h, x, y, win);
- if (x == xp && y == yp && w == wp && h == hp) {
- reps++;
- if (reps >= 2) {
- break;
- }
- } else {
- diffs++;
- reps = 0;
- }
- xp = x;
- yp = y;
- wp = w;
- hp = h;
- usleep(50 * 1000);
- }
- if (diffs >= 2) {
- return 1;
- } else {
- return 0;
- }
-}
-
-extern int macosx_check_clipped(int win, int *list, int n);
-extern int macosx_check_offscreen(int win);
-
-static int check_clipped(int win) {
- int i, n = 0, win2;
- for (i = 0; i < (int) _wins_mapped_cnt; i++) {
- win2 = (int) _wins_mapped[i];
- if (win2 == win) {
- break;
- }
- _wins_int[n++] = win2;
- }
- return macosx_check_clipped(win, _wins_int, n);
-}
-
-static int check_offscreen(int win) {
- return macosx_check_offscreen(win);
-}
-
-extern int macosx_ncache_macmenu;
-
-
-void macosxCGS_get_all_windows(void) {
- static double last = 0.0;
- static int totcnt = 0;
- double dt = 0.0, now = dnow();
- int i, db = 0, whist_prv = 0, maxwin = 0, whist_skip = 0;
- CGSWindowCount cap = (CGSWindowCount) MAXWINDAT;
- CGSError err;
-
- CGS_levelmax = 0;
- CGS_levels[CGS_levelmax++] = (int) kCGDraggingWindowLevel; /* 500 ? */
- if (0) CGS_levels[CGS_levelmax++] = (int) kCGHelpWindowLevel; /* 102 ? */
- if (macosx_ncache_macmenu) CGS_levels[CGS_levelmax++] = (int) kCGPopUpMenuWindowLevel; /* 101 pulldown menu */
- CGS_levels[CGS_levelmax++] = (int) kCGMainMenuWindowLevelKey; /* 24 ? */
- CGS_levels[CGS_levelmax++] = (int) kCGModalPanelWindowLevel; /* 8 open dialog box */
- CGS_levels[CGS_levelmax++] = (int) kCGFloatingWindowLevel; /* 3 ? */
- CGS_levels[CGS_levelmax++] = (int) kCGNormalWindowLevel; /* 0 regular window */
-
- if (cid == NULL) {
- cid = _CGSDefaultConnection();
- if (cid == NULL) {
- return;
- }
- }
-
- if (dt > 0.0 && now < last + dt) {
- return;
- }
-
- last = now;
-
- macwinmax = 0;
-
- totcnt++;
-
- if (ncache > 0) {
- whist_prv = whist_idx++;
- if (whist_prv < 0) {
- whist_skip = 1;
- whist_prv = 0;
- }
- whist_idx = whist_idx % WINHISTMAX;
- for (i=0; i < WINHISTNUM; i++) {
- whist[whist_idx][i] = 0;
- qlook[i] = -1;
- }
- }
-
- err = CGSGetWindowList(cid, NULL, cap, _wins_all, &_wins_all_cnt);
-
-if (db) fprintf(stderr, "cnt: %d err: %d\n", (int) _wins_all_cnt, err);
-
- if (err != 0) {
- return;
- }
-
- for (i=0; i < (int) _wins_all_cnt; i++) {
- CGSRect rect;
- CGSWindowLevel level;
- int j, keepit = 0;
- err = CGSGetScreenRectForWindow(cid, _wins_all[i], &rect);
- if (err != 0) {
- continue;
- }
- if (rect.origin.x == 0 && rect.origin.y == 0) {
- if (rect.size.width == dpy_x) {
- if (rect.size.height == dpy_y) {
- continue;
- }
- }
- }
- err = CGSGetWindowLevel(cid, _wins_all[i], &level);
- if (err != 0) {
- continue;
- }
- for (j=0; j<CGS_levelmax; j++) {
- if ((int) level == CGS_levels[j]) {
- keepit = 1;
- break;
- }
- }
- if (! keepit) {
- continue;
- }
-
- macwins[macwinmax].level = (int) level;
- macwins[macwinmax].win = (int) _wins_all[i];
- macwins[macwinmax].x = (int) rect.origin.x;
- macwins[macwinmax].y = (int) rect.origin.y;
- macwins[macwinmax].width = (int) rect.size.width;
- macwins[macwinmax].height = (int) rect.size.height;
- macwins[macwinmax].mapped = 0;
- macwins[macwinmax].clipped = 0;
- macwins[macwinmax].ncache_only = 0;
- if (level == kCGPopUpMenuWindowLevel) {
- macwins[macwinmax].ncache_only = 1;
- }
-
-if (0 || db) fprintf(stderr, "i=%03d ID: %06d x: %03d y: %03d w: %03d h: %03d level: %d\n", i, _wins_all[i],
- (int) rect.origin.x, (int) rect.origin.y,(int) rect.size.width, (int) rect.size.height, (int) level);
-
- if (macwins[macwinmax].win < WINHISTNUM) {
- qlook[macwins[macwinmax].win] = macwinmax;
- if (macwins[macwinmax].win > maxwin) {
- maxwin = macwins[macwinmax].win;
- }
- }
-
- macwinmax++;
- }
-
- err = CGSGetOnScreenWindowList(cid, NULL, cap, _wins_mapped, &_wins_mapped_cnt);
-
-if (db) fprintf(stderr, "cnt: %d err: %d\n", (int) _wins_mapped_cnt, err);
-
- if (err != 0) {
- return;
- }
-
- for (i=0; i < (int) _wins_mapped_cnt; i++) {
- int j, idx = -1;
- int win = (int) _wins_mapped[i];
-
- if (0 <= win && win < WINHISTNUM) {
- j = qlook[win];
- if (j >= 0 && macwins[j].win == win) {
- idx = j;
- }
- }
- if (idx < 0) {
- for (j=0; j < macwinmax; j++) {
- if (macwins[j].win == win) {
- idx = j;
- break;
- }
- }
- }
- if (idx >= 0) {
- macwins[idx].mapped = 1;
- }
- }
-
- if (ncache > 0) {
- int nv= 0, NBMAX = 64;
- int nv_win[64];
- int nv_lvl[64];
- int nv_vis[64];
-
- for (i=0; i < macwinmax; i++) {
- int win = macwins[i].win;
- char prev, curr;
-
- if (win >= WINHISTNUM) {
- continue;
- }
-
- whist[whist_idx][win] |= is_exist;
- if (macwins[i].mapped) {
- whist[whist_idx][win] |= is_mapped;
- if (check_clipped(win)) {
- whist[whist_idx][win] |= is_clipped;
- macwins[i].clipped = 1;
- }
- if (check_offscreen(win)) {
- whist[whist_idx][win] |= is_offscreen;
- }
- } else {
- whist[whist_idx][win] |= is_offscreen;
- }
-
- curr = whist[whist_idx][win];
- prev = whist[whist_prv][win];
-
- if (whist_skip) {
- ;
- } else if ( !(prev & is_mapped) && (curr & is_mapped)) {
- /* MapNotify */
- if (0) fprintf(stderr, "MapNotify: %d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
- macosx_add_mapnotify(win, macwins[i].level, 1);
- if (0) macosxCGS_follow_animation_win(win, i, 1);
-
- } else if ( !(curr & is_mapped) && (prev & is_mapped)) {
- /* UnmapNotify */
- if (0) fprintf(stderr, "UnmapNotify: %d/%d %d %.4f A tot=%d\n", prev, curr, win, dnowx(), totcnt);
- macosx_add_mapnotify(win, macwins[i].level, 0);
- } else if ( !(prev & is_exist) && (curr & is_exist)) {
- /* CreateNotify */
- if (0) fprintf(stderr, "CreateNotify:%d/%d %d %.4f whist: %d/%d 0x%x tot=%d\n", prev, curr, win, dnowx(), whist_prv, whist_idx, win, totcnt);
- macosx_add_create(win, macwins[i].level);
- if (curr & is_mapped) {
- if (0) fprintf(stderr, "MapNotify: %d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
- macosx_add_mapnotify(win, macwins[i].level, 1);
- }
- }
- if (whist_skip) {
- ;
- } else if (nv >= NBMAX) {
- ;
- } else if (!(curr & is_mapped)) {
- ;
- } else if (!(prev & is_mapped)) {
- if (1) {
- ;
- } else if (curr & is_clipped) {
- if (0) fprintf(stderr, "VisibNotify: %d/%d %d OBS tot=%d\n", prev, curr, win, totcnt);
- nv_win[nv] = win;
- nv_lvl[nv] = macwins[i].level;
- nv_vis[nv++] = 1;
- } else {
- if (0) fprintf(stderr, "VisibNotify: %d/%d %d UNOBS tot=%d\n", prev, curr, win, totcnt);
- nv_win[nv] = win;
- nv_lvl[nv] = macwins[i].level;
- nv_vis[nv++] = 0;
- }
- } else {
- if ( !(prev & is_clipped) && (curr & is_clipped) ) {
- if (0) fprintf(stderr, "VisibNotify: %d/%d %d OBS tot=%d\n", prev, curr, win, totcnt);
- nv_win[nv] = win;
- nv_lvl[nv] = macwins[i].level;
- nv_vis[nv++] = 1;
- } else if ( (prev & is_clipped) && !(curr & is_clipped) ) {
- if (0) fprintf(stderr, "VisibNotify: %d/%d %d UNOBS tot=%d\n", prev, curr, win, totcnt);
- nv_win[nv] = win;
- nv_lvl[nv] = macwins[i].level;
- nv_vis[nv++] = 0;
- }
- }
- }
- for (i=0; i < maxwin; i++) {
- char prev, curr;
- int win = i;
- int q = qlook[i];
- int lvl = 0;
-
- if (whist_skip) {
- break;
- }
-
- if (q >= 0) {
- lvl = macwins[q].level;
- }
- curr = whist[whist_idx][win];
- prev = whist[whist_prv][win];
- if (!(curr & is_exist) && (prev & is_exist)) {
- if (prev & is_mapped) {
- if (0) fprintf(stderr, "UnmapNotify: %d/%d %d %.4f B tot=%d\n", prev, curr, win, dnowx(), totcnt);
- macosx_add_mapnotify(win, lvl, 0);
- }
- /* DestroyNotify */
- if (0) fprintf(stderr, "DestroNotify:%d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
- macosx_add_destroy(win, lvl);
- }
- }
- if (nv) {
- int k;
- for (k = 0; k < nv; k++) {
- macosx_add_visnotify(nv_win[k], nv_lvl[k], nv_vis[k]);
- }
- }
- }
-}
-
-#if 1
-NSLock *pblock = nil;
-NSString *pbstr = nil;
-NSString *cuttext = nil;
-
-int pbcnt = -1;
-NSStringEncoding pbenc = NSWindowsCP1252StringEncoding;
-
-void macosxGCS_initpb(void) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- pblock = [[NSLock alloc] init];
- if (![NSPasteboard generalPasteboard]) {
- macosx_log("macosxGCS_initpb: **PASTEBOARD INACCESSIBLE**.\n");
- macosx_log("macosxGCS_initpb: Clipboard exchange will NOT work.\n");
- macosx_log("macosxGCS_initpb: Start x11vnc *inside* Aqua for Clipboard.\n");
- pbcnt = 0;
- pbstr = [[NSString alloc] initWithString:@"\e<PASTEBOARD INACCESSIBLE>\e"];
- }
- [pool release];
-}
-
-void macosxGCS_set_pasteboard(char *str, int len) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- if (pbcnt != 0) {
- [pblock lock];
- [cuttext release];
- cuttext = [[NSString alloc] initWithData:[NSData dataWithBytes:str length:len] encoding: pbenc];
- if ([[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]) {
- NS_DURING
- [[NSPasteboard generalPasteboard] setString:cuttext forType:NSStringPboardType];
- NS_HANDLER
- fprintf(stderr, "macosxGCS_set_pasteboard: problem writing to pasteboard\n");
- NS_ENDHANDLER
- } else {
- fprintf(stderr, "macosxGCS_set_pasteboard: problem writing to pasteboard\n");
- }
- [cuttext release];
- cuttext = nil;
- [pblock unlock];
- }
- [pool release];
-}
-
-extern void macosx_send_sel(char *, int);
-
-void macosxGCS_poll_pb(void) {
-
- static double dlast = 0.0;
- double now = dnow();
-
- if (now < dlast + 0.2) {
- return;
- }
- dlast = now;
-
- {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [pblock lock];
- if (pbcnt != [[NSPasteboard generalPasteboard] changeCount]) {
- pbcnt = [[NSPasteboard generalPasteboard] changeCount];
- [pbstr release];
- pbstr = nil;
- if ([[NSPasteboard generalPasteboard] availableTypeFromArray:[NSArray arrayWithObject:NSStringPboardType]]) {
- pbstr = [[[NSPasteboard generalPasteboard] stringForType:NSStringPboardType] copy];
- if (pbstr) {
- NSData *str = [pbstr dataUsingEncoding:pbenc allowLossyConversion:YES];
- if ([str length]) {
- macosx_send_sel((char *) [str bytes], [str length]);
- }
- }
- }
- }
- [pblock unlock];
- [pool release];
- }
-}
-#endif
-
-#endif /* __APPLE__ */
-
diff --git a/x11vnc/macosxCGS.h b/x11vnc/macosxCGS.h
deleted file mode 100644
index 21bdebd..0000000
--- a/x11vnc/macosxCGS.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_MACOSXCGS_H
-#define _X11VNC_MACOSXCGS_H
-
-/* -- macosxCGS.h -- */
-
-extern void macosxCGS_get_all_windows(void);
-extern int macosxCGS_get_qlook(int);
-extern void macosxGCS_set_pasteboard(char *str, int len);
-extern int macosxCGS_follow_animation_win(int win, int idx, int grow);
-extern int macosxCGS_find_index(int w);
-
-
-#endif /* _X11VNC_MACOSXCGS_H */
diff --git a/x11vnc/macosx_opengl.c b/x11vnc/macosx_opengl.c
deleted file mode 100644
index 9788279..0000000
--- a/x11vnc/macosx_opengl.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- macosx_opengl.c -- */
-
-#if (defined(__MACH__) && defined(__APPLE__))
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <ApplicationServices/ApplicationServices.h>
-
-#include <rfb/rfb.h>
-#if LIBVNCSERVER_HAVE_MACOSX_OPENGL_H
-#include <OpenGL/OpenGL.h>
-#include <OpenGL/gl.h>
-#endif
-
-extern int macosx_no_opengl, macosx_read_opengl;
-extern CGDirectDisplayID displayID;
-
-static CGLContextObj glContextObj;
-
-int macosx_opengl_width = 0;
-int macosx_opengl_height = 0;
-int macosx_opengl_bpp = 0;
-
-int macosx_opengl_get_width(void) {
- GLint viewport[4];
-
- glGetIntegerv(GL_VIEWPORT, viewport);
- return (int) viewport[2];
-}
-
-int macosx_opengl_get_height(void) {
- GLint viewport[4];
-
- glGetIntegerv(GL_VIEWPORT, viewport);
- return (int) viewport[3];
-}
-
-int macosx_opengl_get_bpp(void) {
- return 32;
-}
-
-int macosx_opengl_get_bps(void) {
- return 8;
-}
-
-int macosx_opengl_get_spp(void) {
- return 3;
-}
-
-void macosx_opengl_init(void) {
- CGLPixelFormatObj pixelFormatObj;
- GLint numPixelFormats;
- CGLPixelFormatAttribute attribs[] = {
- kCGLPFAFullScreen,
- kCGLPFADisplayMask,
- 0,
- 0
- };
-
- if (macosx_no_opengl) {
- return;
- }
-
- attribs[2] = CGDisplayIDToOpenGLDisplayMask(displayID);
-
- CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
- if (pixelFormatObj == NULL) {
- rfbLog("macosx_opengl_init: CGLChoosePixelFormat failed. Not using OpenGL.\n");
- return;
- }
-
- CGLCreateContext(pixelFormatObj, NULL, &glContextObj);
- CGLDestroyPixelFormat(pixelFormatObj);
-
- if (glContextObj == NULL) {
- rfbLog("macosx_opengl_init: CGLCreateContext failed. Not using OpenGL.\n");
- return;
- }
-
- CGLSetCurrentContext(glContextObj);
- CGLSetFullScreen(glContextObj);
-
- macosx_opengl_width = macosx_opengl_get_width();
- macosx_opengl_height = macosx_opengl_get_height();
-
- macosx_opengl_bpp = macosx_opengl_get_bpp();
-
- glFinish();
-
- glPixelStorei(GL_PACK_ALIGNMENT, 4);
- glPixelStorei(GL_PACK_ROW_LENGTH, 0);
- glPixelStorei(GL_PACK_SKIP_ROWS, 0);
- glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
-
- rfbLog("macosx_opengl_init: Using OpenGL for screen capture.\n");
- macosx_read_opengl = 1;
-}
-
-void macosx_opengl_fini(void) {
- if (!macosx_read_opengl) {
- return;
- }
- CGLSetCurrentContext(NULL);
- CGLClearDrawable(glContextObj);
- CGLDestroyContext(glContextObj);
-}
-
-void macosx_copy_opengl(char *dest, int x, int y, unsigned int w, unsigned int h) {
- int yflip = macosx_opengl_height - y - h;
-
- CGLSetCurrentContext(glContextObj);
-
- glReadPixels((GLint) x, (GLint) yflip, (int) w, (int) h,
- GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, dest);
-
- if (h > 1) {
- static char *pbuf = NULL;
- static int buflen = 0;
- int top = 0, bot = h - 1, rowlen = w * macosx_opengl_bpp/8;
- char *ptop, *pbot;
-
- if (rowlen > buflen || buflen == 0) {
- buflen = rowlen + 128;
- if (pbuf) {
- free(pbuf);
- }
- pbuf = (char *) malloc(buflen);
- }
- while (top < bot) {
- ptop = dest + top * rowlen;
- pbot = dest + bot * rowlen;
- memcpy(pbuf, ptop, rowlen);
- memcpy(ptop, pbot, rowlen);
- memcpy(pbot, pbuf, rowlen);
- top++;
- bot--;
- }
- }
-}
-
-
-#else
-
-#endif /* __APPLE__ */
-
diff --git a/x11vnc/macosx_opengl.h b/x11vnc/macosx_opengl.h
deleted file mode 100644
index 5531a0c..0000000
--- a/x11vnc/macosx_opengl.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_MACOSX_OPENGL_H
-#define _X11VNC_MACOSX_OPENGL_H
-
-/* -- macosx_opengl.h -- */
-
-extern void macosx_opengl_init(void);
-
-
-#endif /* _X11VNC_MACOSX_OPENGL_H */
diff --git a/x11vnc/misc/.cvsignore b/x11vnc/misc/.cvsignore
deleted file mode 100644
index 22a4e72..0000000
--- a/x11vnc/misc/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
-Makefile
-Makefile.in
-
diff --git a/x11vnc/misc/LICENSE b/x11vnc/misc/LICENSE
deleted file mode 100644
index ea4bdb0..0000000
--- a/x11vnc/misc/LICENSE
+++ /dev/null
@@ -1,31 +0,0 @@
-The following files in this directory:
-
- Makefile.am
- README
- Xdummy
- blockdpy.c
- ranfb.pl
- rx11vnc
- rx11vnc.pl
- shm_clear
- slide.pl
- vcinject.pl
- x11vnc_loop
- x11vnc_pw
-
-are all Copyright (C) 2002-2009 Karl J. Runge <runge@karlrunge.com>
-and are all released under this license:
-
- This is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This software is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this software; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- USA or see <http://www.gnu.org/licenses/>.
diff --git a/x11vnc/misc/Makefile.am b/x11vnc/misc/Makefile.am
deleted file mode 100644
index e6a50aa..0000000
--- a/x11vnc/misc/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = turbovnc
-DIST_SUBDIRS = turbovnc
-EXTRA_DIST=README blockdpy.c dtVncPopup rx11vnc rx11vnc.pl shm_clear ranfb.pl slide.pl vcinject.pl x11vnc_loop Xdummy ultravnc_repeater.pl connect_switch panner.pl desktop.cgi inet6to4 uinput.pl qt_tslib_inject.pl
diff --git a/x11vnc/misc/README b/x11vnc/misc/README
deleted file mode 100644
index 2ed1dff..0000000
--- a/x11vnc/misc/README
+++ /dev/null
@@ -1,50 +0,0 @@
-
-In this directory you'll find a hodgepodge of wrapper scripts and
-utility programs that have found some use with x11vnc.
-
-Some are on the rough side and will need some customization for your
-use. Many of them are described on the webpage:
-
- http://www.karlrunge.com/x11vnc
-
-(use your browser's Find action to find them!). Some of them also have
-documentation near the top of the file.
-
-x11vnc -accept scripts:
-
- blockdpy.c try to lock screen if local person knocks monitor out of DPMS
- dtVncPopup CDE/dtksh by Stefan Radman to accept connections, lock screen
-
-x11vnc launch wrappers:
-
- rx11vnc simple ssh/rsh x11vnc launcher. -S option needs work...
- rx11vnc.pl perl script tries to do rx11vnc -S tunnelling better.
-
-x11vnc -pipeinput/-rawfb utilities:
-
- vcinject.pl perl script like LinuxVNC.c, for x11vnc viewing of linux console
- slide.pl amusing example using x11vnc -rawfb for jpeg slideshow.
- ranfb.pl example -rawfb setup:./ranfb.pl to set up a framebuffer.
-
- uinput.pl test perl script for Linux uinput injection.
-
- qt_tslib_inject.pl touchscreen -pipeinput helper for tslib on qtmoko.
-
-Misc. scripts:
-
- shm_clear list or remove orphaned shm slots from hard x11vnc crashes.
- x11vnc_loop kludge to run in bg attaching x11vnc to X login. Better to
- use Xsetup mechanism.
- Xdummy An LD_PRELOAD kludge to run the Xorg "dummy" device driver
- like Xvfb.
-
- ultravnc_repeater.pl: Unix script to act as UltraVNC repeater proxy.
-
- connect_switch: Share HTTPS, VNC, SSH, etc. through a single port (e.g. 443)
-
- panner.pl Allows a small rectangle to pan around a desktop more or less.
-
- desktop.cgi CGI script for creating multi-user virtual desktops on a
- server. Also can do port-redirection to internal machines.
-
- inet6to4 ipv6 to ipv4 relay (i.e. until libvncserver supports ipv6)
diff --git a/x11vnc/misc/Xdummy b/x11vnc/misc/Xdummy
deleted file mode 100755
index 638a7b3..0000000
--- a/x11vnc/misc/Xdummy
+++ /dev/null
@@ -1,1930 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------
-# Copyright (C) 2005-2010 Karl J. Runge <runge@karlrunge.com>
-# All rights reserved.
-#
-# This file is part of Xdummy.
-#
-# Xdummy is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# Xdummy is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Xdummy; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-# or see <http://www.gnu.org/licenses/>.
-# ----------------------------------------------------------------------
-#
-#
-# Xdummy: an LD_PRELOAD hack to run a stock Xorg(1) or XFree86(1) server
-# with the "dummy" video driver to make it avoid Linux VT switching, etc.
-#
-# Run "Xdummy -help" for more info.
-#
-install=""
-uninstall=""
-runit=1
-prconf=""
-notweak=""
-root=""
-nosudo=""
-xserver=""
-geom=""
-nomodelines=""
-depth=""
-debug=""
-strace=""
-cmdline_config=""
-
-PATH=$PATH:/bin:/usr/bin
-export PATH
-
-program=`basename "$0"`
-
-help () {
- ${PAGER:-more} << END
-$program:
-
- A hack to run a stock Xorg(1) or XFree86(1) X server with the "dummy"
- (RAM-only framebuffer) video driver such that it AVOIDS the Linux VT
- switching, opening device files in /dev, keyboard and mouse conflicts,
- and other problems associated with the normal use of "dummy".
-
- In other words, it tries to make Xorg/XFree86 with the "dummy"
- device driver act more like Xvfb(1).
-
- The primary motivation for the Xdummy script is to provide a virtual X
- server for x11vnc but with more features than Xvfb (or Xvnc); however
- it could be used for other reasons (e.g. better automated testing
- than with Xvfb.) One nice thing is the dummy server supports RANDR
- dynamic resizing while Xvfb does not.
-
- So, for example, x11vnc+Xdummy terminal services are a little better
- than x11vnc+Xvfb.
-
- To achieve this, while running the real Xserver $program intercepts
- system and library calls via the LD_PRELOAD method and modifies
- the behavior to make it work correctly (e.g. avoid the VT stuff.)
- LD_PRELOAD tricks are usually "clever hacks" and so might not work
- in all situations or break when something changes.
-
- WARNING: Take care in using Xdummy, although it never has it is
- possible that it could damage hardware. One can use the -prconf
- option to have it print out the xorg.conf config that it would use
- and then inspect it carefully before actually using it.
-
- This program no longer needs to be run as root as of 12/2009.
- However, if there are problems for certain situations (usually older
- servers) it may perform better if run as root (use the -root option.)
- When running as root remember the previous paragraph and that Xdummy
- comes without any warranty.
-
- gcc/cc and other build tools are required for this script to be able
- to compile the LD_PRELOAD shared object. Be sure they are installed
- on the system. See -install and -uninstall described below.
-
- Your Linux distribution may not install the dummy driver by default,
- e.g:
-
- /usr/lib/xorg/modules/drivers/dummy_drv.so
-
- some have it in a package named xserver-xorg-video-dummy you that
- need to install.
-
-Usage:
-
- $program <${program}-args> <Xserver-args>
-
- (actually, the arguments can be supplied in any order.)
-
-Examples:
-
- $program -install
-
- $program :1
-
- $program -debug :1
-
- $program -tmpdir ~/mytmp :1 -nolisten tcp
-
-startx example:
-
- startx -e bash -- $program :2 -depth 16
-
- (if startx needs to be run as root, you can su(1) to a normal
- user in the bash shell and then launch ~/.xinitrc or ~/.xsession,
- gnome-session, startkde, startxfce4, etc.)
-
-xdm example:
-
- xdm -config /usr/local/dummy/xdm-config -nodaemon
-
- where the xdm-config file has line:
-
- DisplayManager.servers: /usr/local/dummy/Xservers
-
- and /usr/local/dummy/Xservers has lines:
-
- :1 local /usr/local/dummy/Xdummy :1 -debug
- :2 local /usr/local/dummy/Xdummy :2 -debug
-
- (-debug is optional)
-
-gdm/kdm example:
-
- TBD.
-
-Root permission and x11vnc:
-
- Update: as of 12/2009 this program no longer must be run as root.
- So try it as non-root before running it as root and/or the
- following schemes.
-
- In some circumstances X server program may need to be run as root.
- If so, one could run x11vnc as root with -unixpw (it switches
- to the user that logs in) and that may be OK, some other ideas:
-
- - add this to sudo via visudo:
-
- ALL ALL = NOPASSWD: /usr/local/bin/Xdummy
-
- - use this little suid wrapper:
-/*
- * xdummy.c
- *
- cc -o ./xdummy xdummy.c
- sudo cp ./xdummy /usr/local/bin/xdummy
- sudo chown root:root /usr/local/bin/xdummy
- sudo chmod u+s /usr/local/bin/xdummy
- *
- */
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <stdio.h>
-
-int main (int argc, char *argv[]) {
- extern char **environ;
- char str[100];
- sprintf(str, "XDUMMY_UID=%d", (int) getuid());
- putenv(str);
- setuid(0);
- setgid(0);
- execv("/usr/local/bin/Xdummy", argv);
- exit(1);
- return 1;
-}
-
-
-Options:
-
- ${program}-args:
-
- -install Compile the LD_PRELOAD shared object and install it
- next to the $program script file as:
-
- $0.so
-
- When that file exists it is used as the LD_PRELOAD
- shared object without recompiling. Otherwise,
- each time $program is run the LD_PRELOAD shared
- object is compiled as a file in /tmp (or -tmpdir)
-
- If you set the environment variable
- INTERPOSE_GETUID=1 when building, then when
- $program is run as an ordinary user, the shared
- object will interpose getuid() calls and pretend
- to be root. Otherwise it doesn't pretend to
- be root.
-
- You can also set the CFLAGS environment variable
- to anything else you want on the compile cmdline.
-
- -uninstall Remove the file:
-
- $0.so
-
- The LD_PRELOAD shared object will then be compiled
- each time this program is run.
-
- The X server is not started under -install, -uninstall, or -prconf.
-
-
- :N The DISPLAY (e.g. :15) is often the first
- argument. It is passed to the real X server and
- also used by the Xdummy script as an identifier.
-
- -geom geom1[,geom2...] Take the geometry (e.g. 1024x768) or list
- of geometries and insert them into the Screen
- section of the tweaked X server config file.
- Use this to have a different geometry than the
- one(s) in the system config file.
-
- The option -geometry can be used instead of -geom;
- x11vnc calls Xdummy and Xvfb this way.
-
- -nomodelines When you specify -geom/-geometry, $program will
- create Modelines for each geometry and put them
- in the Monitor section. If you do not want this
- then supply -nomodelines.
-
- -depth n Use pixel color depth n (e.g. 8, 16, or 24). This
- makes sure the X config file has a Screen.Display
- subsection of this depth. Note this option is
- ALSO passed to the X server.
-
- -DEPTH n Same as -depth, except not passed to X server.
-
- -tmpdir dir Specify a temporary directory, owned by you and
- only writable by you. This is used in place of
- /tmp/Xdummy.\$USER/.. to place the $program.so
- shared object, tweaked config files, etc.
-
- -nonroot Run in non-root mode (working 12/2009, now default)
-
- -root Run as root (may still be needed in some
- environments.) Same as XDUMMY_RUN_AS_ROOT=1.
-
- -nosudo Do not try to use sudo(1) when re-running as root,
- use su(1) instead.
-
- -xserver path Specify the path to the Xserver to use. Default
- is to try "Xorg" first and then "XFree86". If
- those are not in \$PATH, it tries these locations:
- /usr/bin/Xorg
- /usr/X11R6/bin/Xorg
- /usr/X11R6/bin/XFree86
-
- -n Do not run the command to start the X server,
- just show the command that $program would run.
- The LD_PRELOAD shared object will be built,
- if needed. Also note any XDUMMY* environment
- variables that need to be set.
-
- -prconf Print, to stdout, the tweaked Xorg/XFree86
- config file (-config and -xf86config server
- options, respectively.) The Xserver is not
- started.
-
- -notweak Do not tweak (modify) the Xorg/XFree86 config file
- (system or server command line) at all. The -geom
- and similar config file modifications are ignored.
-
- It is up to you to make sure it is a working
- config file (e.g. "dummy" driver, etc.)
- Perhaps you want to use a file based on the
- -prconf output.
-
- -debug Extra debugging output.
-
- -strace strace(1) the Xserver process (for troubleshooting.)
- -ltrace ltrace(1) instead of strace (can be slow.)
-
- -h, -help Print out this help.
-
-
- Xserver-args:
-
- Most of the Xorg and XFree86 options will work and are simply
- passed along if you supply them. Important ones that may be
- supplied if missing:
-
- :N X Display number for server to use.
-
- vtNN Linux virtual terminal (VT) to use (a VT is currently
- still used, just not switched to and from.)
-
- -config file Driver "dummy" tweaked config file, a
- -xf86config file number of settings are tweaked besides Driver.
-
- If -config/-xf86config is not given, the system one
- (e.g. /etc/X11/xorg.conf) is used. If the system one cannot be
- found, a built-in one is used. Any settings in the config file
- that are not consistent with "dummy" mode will be overwritten
- (unless -notweak is specified.)
-
- Use -config xdummy-builtin to force usage of the builtin config.
-
- If "file" is only a basename (e.g. "xorg.dummy.conf") with no /'s,
- then no tweaking of it is done: the X server will look for that
- basename via its normal search algorithm. If the found file does
- not refer to the "dummy" driver, etc, then the X server will fail.
-
-Notes:
-
- The Xorg/XFree86 "dummy" driver is currently undocumented. It works
- well in this mode, but it is evidently not intended for end-users.
- So it could be removed or broken at any time.
-
- If the display Xserver-arg (e.g. :1) is not given, or ":" is given
- that indicates $program should try to find a free one (based on
- tcp ports.)
-
- If the display virtual terminal, VT, (e.g. vt9) is not given that
- indicates $program should try to find a free one (or guess a high one.)
-
- This program is not completely secure WRT files in /tmp (but it tries
- to a good degree.) Better is to use the -tmpdir option to supply a
- directory only writable by you. Even better is to get rid of users
- on the local machine you do not trust :-)
-
- Set XDUMMY_SET_XV=1 to turn on debugging output for this script.
-
-END
-}
-
-warn() {
- echo "$*" 1>&2
-}
-
-if [ "X$XDUMMY_SET_XV" != "X" ]; then
- set -xv
-fi
-
-if [ "X$XDUMMY_UID" = "X" ]; then
- XDUMMY_UID=`id -u`
- export XDUMMY_UID
-fi
-if [ "X$XDUMMY_UID" = "X0" ]; then
- if [ "X$SUDO_UID" != "X" ]; then
- XDUMMY_UID=$SUDO_UID
- export XDUMMY_UID
- fi
-fi
-
-# check if root=1 first:
-#
-if [ "X$XDUMMY_RUN_AS_ROOT" = "X1" ]; then
- root=1
-fi
-for arg in $*
-do
- if [ "X$arg" = "X-nonroot" ]; then
- root=""
- elif [ "X$arg" = "X-root" ]; then
- root=1
- fi
-done
-
-# See if it really needs to be run as root:
-#
-if [ "X$XDUMMY_SU_EXEC" = "X" -a "X$root" = "X1" -a "X`id -u`" != "X0" ]; then
- # this is to prevent infinite loop in case su/sudo doesn't work:
- XDUMMY_SU_EXEC=1
- export XDUMMY_SU_EXEC
-
- dosu=1
- nosudo=""
-
- for arg in $*
- do
- if [ "X$arg" = "X-nonroot" ]; then
- dosu=""
- elif [ "X$arg" = "X-nosudo" ]; then
- nosudo="1"
- elif [ "X$arg" = "X-help" ]; then
- dosu=""
- elif [ "X$arg" = "X-h" ]; then
- dosu=""
- elif [ "X$arg" = "X-install" ]; then
- dosu=""
- elif [ "X$arg" = "X-uninstall" ]; then
- dosu=""
- elif [ "X$arg" = "X-n" ]; then
- dosu=""
- elif [ "X$arg" = "X-prconf" ]; then
- dosu=""
- fi
- done
- if [ $dosu ]; then
- # we need to restart it with su/sudo:
- if type sudo > /dev/null 2>&1; then
- :
- else
- nosudo=1
- fi
- if [ "X$nosudo" = "X" ]; then
- warn "$program: supply the sudo password to restart as root:"
- if [ "X$XDUMMY_UID" != "X" ]; then
- exec sudo $0 -uid $XDUMMY_UID "$@"
- else
- exec sudo $0 "$@"
- fi
- else
- warn "$program: supply the root password to restart as root:"
- if [ "X$XDUMMY_UID" != "X" ]; then
- exec su -c "$0 -uid $XDUMMY_UID $*"
- else
- exec su -c "$0 $*"
- fi
- fi
- # DONE:
- exit
- fi
-fi
-
-# This will hold the X display, e.g. :20
-#
-disp=""
-args=""
-cmdline_config=""
-
-# Process Xdummy args:
-#
-while [ "X$1" != "X" ]
-do
- if [ "X$1" = "X-config" -o "X$1" = "X-xf86config" ]; then
- cmdline_config="$2"
- fi
- case $1 in
- ":"*) disp=$1
- ;;
- "-install") install=1; runit=""
- ;;
- "-uninstall") uninstall=1; runit=""
- ;;
- "-n") runit=""
- ;;
- "-no") runit=""
- ;;
- "-norun") runit=""
- ;;
- "-prconf") prconf=1; runit=""
- ;;
- "-notweak") notweak=1
- ;;
- "-noconf") notweak=1
- ;;
- "-nonroot") root=""
- ;;
- "-root") root=1
- ;;
- "-nosudo") nosudo=1
- ;;
- "-xserver") xserver="$2"; shift
- ;;
- "-uid") XDUMMY_UID="$2"; shift
- export XDUMMY_UID
- ;;
- "-geom") geom="$2"; shift
- ;;
- "-geometry") geom="$2"; shift
- ;;
- "-nomodelines") nomodelines=1
- ;;
- "-depth") depth="$2"; args="$args -depth $2";
- shift
- ;;
- "-DEPTH") depth="$2"; shift
- ;;
- "-tmpdir") XDUMMY_TMPDIR="$2"; shift
- ;;
- "-debug") debug=1
- ;;
- "-nodebug") debug=""
- ;;
- "-strace") strace=1
- ;;
- "-ltrace") strace=2
- ;;
- "-h") help; exit 0
- ;;
- "-help") help; exit 0
- ;;
- *) args="$args $1"
- ;;
- esac
- shift
-done
-
-# Try to get a username for use in our tmp directory, etc.
-#
-user=""
-if [ X`id -u` = "X0" ]; then
- user=root # this will also be used below for id=0
-elif [ "X$USER" != "X" ]; then
- user=$USER
-elif [ "X$LOGNAME" != "X" ]; then
- user=$LOGNAME
-fi
-
-# Keep trying...
-#
-if [ "X$user" = "X" ]; then
- user=`whoami 2>/dev/null`
-fi
-if [ "X$user" = "X" ]; then
- user=`basename "$HOME"`
-fi
-if [ "X$user" = "X" -o "X$user" = "X." ]; then
- user="u$$"
-fi
-
-if [ "X$debug" = "X1" -a "X$runit" != "X" ]; then
- echo ""
- echo "/usr/bin/env:"
- env | egrep -v '^(LS_COLORS|TERMCAP)' | sort
- echo ""
-fi
-
-# Function to compile the LD_PRELOAD shared object:
-#
-make_so() {
- # extract code embedded in this script into a tmp C file:
- n1=`grep -n '^#code_begin' $0 | head -1 | awk -F: '{print $1}'`
- n2=`grep -n '^#code_end' $0 | head -1 | awk -F: '{print $1}'`
- n1=`expr $n1 + 1`
- dn=`expr $n2 - $n1`
-
- tmp=$tdir/Xdummy.$RANDOM$$.c
- rm -f $tmp
- if [ -e $tmp -o -h $tmp ]; then
- warn "$tmp still exists."
- exit 1
- fi
- touch $tmp || exit 1
- tail -n +$n1 $0 | head -n $dn > $tmp
-
- # compile it to Xdummy.so:
- if [ -f "$SO" ]; then
- mv $SO $SO.$$
- rm -f $SO.$$
- fi
- rm -f $SO
- touch $SO
- if [ ! -f "$SO" ]; then
- SO=$tdir/Xdummy.$user.so
- warn "warning switching LD_PRELOAD shared object to: $SO"
- fi
-
- if [ -f "$SO" ]; then
- mv $SO $SO.$$
- rm -f $SO.$$
- fi
- rm -f $SO
-
- # we assume gcc:
- if [ "X$INTERPOSE_GETUID" = "X1" ]; then
- CFLAGS="$CFLAGS -DINTERPOSE_GETUID"
- fi
- echo "$program:" cc -shared -fPIC $CFLAGS -o $SO $tmp
- cc -shared -fPIC $CFLAGS -o $SO $tmp
- rc=$?
- rm -f $tmp
- if [ $rc != 0 ]; then
- warn "$program: cannot build $SO"
- exit 1
- fi
- if [ "X$debug" != "X" -o "X$install" != "X" ]; then
- warn "$program: created $SO"
- ls -l "$SO"
- fi
-}
-
-# Set tdir to tmp dir for make_so():
-if [ "X$XDUMMY_TMPDIR" != "X" ]; then
- tdir=$XDUMMY_TMPDIR
- mkdir -p $tdir
-else
- tdir="/tmp"
-fi
-
-# Handle -install/-uninstall case:
-SO=$0.so
-if [ "X$install" != "X" -o "X$uninstall" != "X" ]; then
- if [ -e "$SO" -o -h "$SO" ]; then
- warn "$program: removing $SO"
- fi
- if [ -f "$SO" ]; then
- mv $SO $SO.$$
- rm -f $SO.$$
- fi
- rm -f $SO
- if [ -e "$SO" -o -h "$SO" ]; then
- warn "warning: $SO still exists."
- exit 1
- fi
- if [ $install ]; then
- make_so
- if [ ! -f "$SO" ]; then
- exit 1
- fi
- fi
- exit 0
-fi
-
-# We need a tmp directory for the .so, tweaked config file, and for
-# redirecting filenames we cannot create (under -nonroot)
-#
-tack=""
-if [ "X$XDUMMY_TMPDIR" = "X" ]; then
- XDUMMY_TMPDIR="/tmp/Xdummy.$user"
-
- # try to tack on a unique subdir (display number or pid)
- # to allow multiple instances
- #
- if [ "X$disp" != "X" ]; then
- t0=$disp
- else
- t0=$1
- fi
- tack=`echo "$t0" | sed -e 's/^.*://'`
- if echo "$tack" | grep '^[0-9][0-9]*$' > /dev/null; then
- :
- else
- tack=$$
- fi
- if [ "X$tack" != "X" ]; then
- XDUMMY_TMPDIR="$XDUMMY_TMPDIR/$tack"
- fi
-fi
-
-tmp=$XDUMMY_TMPDIR
-if echo "$tmp" | grep '^/tmp' > /dev/null; then
- if [ "X$tmp" != "X/tmp" -a "X$tmp" != "X/tmp/" ]; then
- # clean this subdir of /tmp out, otherwise leave it...
- rm -rf $XDUMMY_TMPDIR
- if [ -e $XDUMMY_TMPDIR ]; then
- warn "$XDUMMY_TMPDIR still exists"
- exit 1
- fi
- fi
-fi
-
-mkdir -p $XDUMMY_TMPDIR
-chmod 700 $XDUMMY_TMPDIR
-if [ "X$tack" != "X" ]; then
- chmod 700 `dirname "$XDUMMY_TMPDIR"` 2>/dev/null
-fi
-
-# See if we can write something there:
-#
-tfile="$XDUMMY_TMPDIR/test.file"
-touch $tfile
-if [ ! -f "$tfile" ]; then
- XDUMMY_TMPDIR="/tmp/Xdummy.$$.$USER"
- warn "warning: setting tmpdir to $XDUMMY_TMPDIR ..."
- rm -rf $XDUMMY_TMPDIR || exit 1
- mkdir -p $XDUMMY_TMPDIR || exit 1
-fi
-rm -f $tfile
-
-export XDUMMY_TMPDIR
-
-# Compile the LD_PRELOAD shared object if needed (needs XDUMMY_TMPDIR)
-#
-if [ ! -f "$SO" ]; then
- SO="$XDUMMY_TMPDIR/Xdummy.so"
- make_so
-fi
-
-# Decide which X server to use:
-#
-if [ "X$xserver" = "X" ]; then
- if type Xorg >/dev/null 2>&1; then
- xserver="Xorg"
- elif type XFree86 >/dev/null 2>&1; then
- xserver="XFree86"
- elif -x /usr/bin/Xorg; then
- xserver="/usr/bin/Xorg"
- elif -x /usr/X11R6/bin/Xorg; then
- xserver="/usr/X11R6/bin/Xorg"
- elif -x /usr/X11R6/bin/XFree86; then
- xserver="/usr/X11R6/bin/XFree86"
- fi
- if [ "X$xserver" = "X" ]; then
- # just let it fail below.
- xserver="/usr/bin/Xorg"
- warn "$program: cannot locate a stock Xserver... assuming $xserver"
- fi
-fi
-
-# See if the binary is suid or not readable under -nonroot mode:
-#
-if [ "X$BASH_VERSION" != "X" ]; then
- xserver_path=`type -p $xserver 2>/dev/null`
-else
- xserver_path=`type $xserver 2>/dev/null | awk '{print $NF}'`
-fi
-if [ -e "$xserver_path" -a "X$root" = "X" -a "X$runit" != "X" ]; then
- if [ ! -r $xserver_path -o -u $xserver_path -o -g $xserver_path ]; then
- # XXX not quite correct with rm -rf $XDUMMY_TMPDIR ...
- # we keep on a filesystem we know root can write to.
- base=`basename "$xserver_path"`
- new="/tmp/$base.$user.bin"
- if [ -e $new ]; then
- snew=`ls -l $new | awk '{print $5}' | grep '^[0-9][0-9]*$'`
- sold=`ls -l $xserver_path | awk '{print $5}' | grep '^[0-9][0-9]*$'`
- if [ "X$snew" != "X" -a "X$sold" != "X" -a "X$sold" != "X$snew" ]; then
- warn "removing different sized copy:"
- ls -l $new $xserver_path
- rm -f $new
- fi
- fi
- if [ ! -e $new -o ! -s $new ]; then
- rm -f $new
- touch $new || exit 1
- chmod 700 $new || exit 1
- if [ ! -r $xserver_path ]; then
- warn ""
- warn "NEED TO COPY UNREADABLE $xserver_path to $new as root:"
- warn ""
- ls -l $xserver_path 1>&2
- warn ""
- warn "This only needs to be done once:"
- warn " cat $xserver_path > $new"
- warn ""
- nos=$nosudo
- if type sudo > /dev/null 2>&1; then
- :
- else
- nos=1
- fi
- if [ "X$nos" = "X1" ]; then
- warn "Please supply root passwd to 'su -c'"
- su -c "cat $xserver_path > $new"
- else
- warn "Please supply the sudo passwd if asked:"
- sudo /bin/sh -c "cat $xserver_path > $new"
- fi
- else
- warn ""
- warn "COPYING SETUID $xserver_path to $new"
- warn ""
- ls -l $xserver_path 1>&2
- warn ""
- cat $xserver_path > $new
- fi
- ls -l $new
- if [ -s $new ]; then
- :
- else
- rm -f $new
- ls -l $new
- exit 1
- fi
- warn ""
- warn "Please restart Xdummy now."
- exit 0
- fi
- if [ ! -O $new ]; then
- warn "file \"$new\" not owned by us!"
- ls -l $new
- exit 1
- fi
- xserver=$new
- fi
-fi
-
-# Work out display:
-#
-if [ "X$disp" != "X" ]; then
- :
-elif [ "X$1" != "X" ]; then
- if echo "$1" | grep '^:[0-9]' > /dev/null; then
- disp=$1
- shift
- elif [ "X$1" = "X:" ]; then
- # ":" means for us to find one.
- shift
- fi
-fi
-if [ "X$disp" = "X" -o "X$disp" = "X:" ]; then
- # try to find an open display port:
- # (tcp outdated...)
- ports=`netstat -ant | grep LISTEN | awk '{print $4}' | sed -e 's/^.*://'`
- n=0
- while [ $n -le 20 ]
- do
- port=`printf "60%02d" $n`
- if echo "$ports" | grep "^${port}\$" > /dev/null; then
- :
- else
- disp=":$n"
- warn "$program: auto-selected DISPLAY $disp"
- break
- fi
- n=`expr $n + 1`
- done
-fi
-
-# Work out which vt to use, try to find/guess an open one if necessary.
-#
-vt=""
-for arg in $*
-do
- if echo "$arg" | grep '^vt' > /dev/null; then
- vt=$arg
- break
- fi
-done
-if [ "X$vt" = "X" ]; then
- if [ "X$user" = "Xroot" ]; then
- # root can user fuser(1) to see if it is in use:
- if type fuser >/dev/null 2>&1; then
- # try /dev/tty17 thru /dev/tty32
- n=17
- while [ $n -le 32 ]
- do
- dev="/dev/tty$n"
- if fuser $dev >/dev/null 2>&1; then
- :
- else
- vt="vt$n"
- warn "$program: auto-selected VT $vt => $dev"
- break
- fi
- n=`expr $n + 1`
- done
- fi
- fi
- if [ "X$vt" = "X" ]; then
- # take a wild guess...
- vt=vt16
- warn "$program: selected fallback VT $vt"
- fi
-else
- vt=""
-fi
-
-# Decide flavor of Xserver:
-#
-stype=`basename "$xserver"`
-if echo "$stype" | grep -i xfree86 > /dev/null; then
- stype=xfree86
-else
- stype=xorg
-fi
-
-tweak_config() {
- in="$1"
- config2="$XDUMMY_TMPDIR/xdummy_modified_xconfig.conf"
- if [ "X$disp" != "X" ]; then
- d=`echo "$disp" | sed -e 's,/,,g' -e 's/:/_/g'`
- config2="$config2$d"
- fi
-
- # perl script to tweak the config file... add/delete options, etc.
- #
- env XDUMMY_GEOM=$geom \
- XDUMMY_DEPTH=$depth \
- XDUMMY_NOMODELINES=$nomodelines \
- perl > $config2 < $in -e '
- $n = 0;
- $geom = $ENV{XDUMMY_GEOM};
- $depth = $ENV{XDUMMY_DEPTH};
- $nomodelines = $ENV{XDUMMY_NOMODELINES};
- $mode_str = "";
- $videoram = "24000";
- $HorizSync = "30.0 - 130.0";
- $VertRefresh = "50.0 - 250.0";
- if ($geom ne "") {
- my $tmp = "";
- foreach $g (split(/,/, $geom)) {
- $tmp .= "\"$g\" ";
- if (!$nomodelines && $g =~ /(\d+)x(\d+)/) {
- my $w = $1;
- my $h = $2;
- $mode_str .= " Modeline \"$g\" ";
- my $dot = sprintf("%.2f", $w * $h * 70 * 1.e-6);
- $mode_str .= $dot;
- $mode_str .= " " . $w;
- $mode_str .= " " . int(1.02 * $w);
- $mode_str .= " " . int(1.10 * $w);
- $mode_str .= " " . int(1.20 * $w);
- $mode_str .= " " . $h;
- $mode_str .= " " . int($h + 1);
- $mode_str .= " " . int($h + 3);
- $mode_str .= " " . int($h + 20);
- $mode_str .= "\n";
- }
- }
- $tmp =~ s/\s*$//;
- $geom = $tmp;
- }
- while (<>) {
- if ($ENV{XDUMMY_NOTWEAK}) {
- print $_;
- next;
- }
- $n++;
- if (/^\s*#/) {
- # pass comments straight thru
- print;
- next;
- }
- if (/^\s*Section\s+(\S+)/i) {
- # start of Section
- $sect = $1;
- $sect =~ s/\W//g;
- $sect =~ y/A-Z/a-z/;
- $sects{$sect} = 1;
- print;
- next;
- }
- if (/^\s*EndSection/i) {
- # end of Section
- if ($sect eq "serverflags") {
- if (!$got_DontVTSwitch) {
- print " ##Xdummy:##\n";
- print " Option \"DontVTSwitch\" \"true\"\n";
- }
- if (!$got_AllowMouseOpenFail) {
- print " ##Xdummy:##\n";
- print " Option \"AllowMouseOpenFail\" \"true\"\n";
- }
- if (!$got_PciForceNone) {
- print " ##Xdummy:##\n";
- print " Option \"PciForceNone\" \"true\"\n";
- }
- } elsif ($sect eq "device") {
- if (!$got_Driver) {
- print " ##Xdummy:##\n";
- print " Driver \"dummy\"\n";
- }
- if (!$got_VideoRam) {
- print " ##Xdummy:##\n";
- print " VideoRam $videoram\n";
- }
- } elsif ($sect eq "screen") {
- if ($depth ne "" && !got_DefaultDepth) {
- print " ##Xdummy:##\n";
- print " DefaultDepth $depth\n";
- }
- if ($got_Monitor eq "") {
- print " ##Xdummy:##\n";
- print " Monitor \"Monitor0\"\n";
- }
- } elsif ($sect eq "monitor") {
- if (!got_HorizSync) {
- print " ##Xdummy:##\n";
- print " HorizSync $HorizSync\n";
- }
- if (!got_VertRefresh) {
- print " ##Xdummy:##\n";
- print " VertRefresh $VertRefresh\n";
- }
- if (!$nomodelines) {
- print " ##Xdummy:##\n";
- print $mode_str;
- }
- }
- $sect = "";
- print;
- next;
- }
-
- if (/^\s*SubSection\s+(\S+)/i) {
- # start of Section
- $subsect = $1;
- $subsect =~ s/\W//g;
- $subsect =~ y/A-Z/a-z/;
- $subsects{$subsect} = 1;
- if ($sect eq "screen" && $subsect eq "display") {
- $got_Modes = 0;
- }
- print;
- next;
- }
- if (/^\s*EndSubSection/i) {
- # end of SubSection
- if ($sect eq "screen") {
- if ($subsect eq "display") {
- if ($depth ne "" && !$set_Depth) {
- print " ##Xdummy:##\n";
- print " Depth\t$depth\n";
- }
- if ($geom ne "" && ! $got_Modes) {
- print " ##Xdummy:##\n";
- print " Modes\t$geom\n";
- }
- }
- }
- $subsect = "";
- print;
- next;
- }
-
- $l = $_;
- $l =~ s/#.*$//;
- if ($sect eq "serverflags") {
- if ($l =~ /^\s*Option.*DontVTSwitch/i) {
- $_ =~ s/false/true/ig;
- $got_DontVTSwitch = 1;
- }
- if ($l =~ /^\s*Option.*AllowMouseOpenFail/i) {
- $_ =~ s/false/true/ig;
- $got_AllowMouseOpenFail = 1;
- }
- if ($l =~ /^\s*Option.*PciForceNone/i) {
- $_ =~ s/false/true/ig;
- $got_PciForceNone= 1;
- }
- }
- if ($sect eq "module") {
- if ($l =~ /^\s*Load.*\b(dri|fbdevhw)\b/i) {
- $_ = "##Xdummy## $_";
- }
- }
- if ($sect eq "monitor") {
- if ($l =~ /^\s*HorizSync/i) {
- $got_HorizSync = 1;
- }
- if ($l =~ /^\s*VertRefresh/i) {
- $got_VertRefresh = 1;
- }
- }
- if ($sect eq "device") {
- if ($l =~ /^(\s*Driver)\b/i) {
- $_ = "$1 \"dummy\"\n";
- $got_Driver = 1;
- }
- if ($l =~ /^\s*VideoRam/i) {
- $got_VideoRam= 1;
- }
- }
- if ($sect eq "inputdevice") {
- if ($l =~ /^\s*Option.*\bDevice\b/i) {
- print " ##Xdummy:##\n";
- $_ = " Option \"Device\" \"/dev/dilbert$n\"\n";
- }
- }
- if ($sect eq "screen") {
- if ($l =~ /^\s*DefaultDepth\s+(\d+)/i) {
- if ($depth ne "") {
- print " ##Xdummy:##\n";
- $_ = " DefaultDepth\t$depth\n";
- }
- $got_DefaultDepth = 1;
- }
- if ($l =~ /^\s*Monitor\s+(\S+)/i) {
- $got_Monitor = $1;
- $got_Monitor =~ s/"//g;
- }
- if ($subsect eq "display") {
- if ($geom ne "") {
- if ($l =~ /^(\s*Modes)\b/i) {
- print " ##Xdummy:##\n";
- $_ = "$1 $geom\n";
- $got_Modes = 1;
- }
- }
- if ($l =~ /^\s*Depth\s+(\d+)/i) {
- my $d = $1;
- if (!$set_Depth && $depth ne "") {
- $set_Depth = 1;
- if ($depth != $d) {
- print " ##Xdummy:##\n";
- $_ = " Depth\t$depth\n";
- }
- }
- }
- }
- }
- print;
- }
- if ($ENV{XDUMMY_NOTWEAK}) {
- exit;
- }
- # create any crucial sections that are missing:
- if (! exists($sects{serverflags})) {
- print "\n##Xdummy:##\n";
- print "Section \"ServerFlags\"\n";
- print " Option \"DontVTSwitch\" \"true\"\n";
- print " Option \"AllowMouseOpenFail\" \"true\"\n";
- print " Option \"PciForceNone\" \"true\"\n";
- print "EndSection\n";
- }
- if (! exists($sects{device})) {
- print "\n##Xdummy:##\n";
- print "Section \"Device\"\n";
- print " Identifier \"Videocard0\"\n";
- print " Driver \"dummy\"\n";
- print " VideoRam $videoram\n";
- print "EndSection\n";
- }
- if (! exists($sects{monitor})) {
- print "\n##Xdummy:##\n";
- print "Section \"Monitor\"\n";
- print " Identifier \"Monitor0\"\n";
- print " HorizSync $HorizSync\n";
- print " VertRefresh $VertRefresh\n";
- print "EndSection\n";
- }
- if (! exists($sects{screen})) {
- print "\n##Xdummy:##\n";
- print "Section \"Screen\"\n";
- print " Identifier \"Screen0\"\n";
- print " Device \"Videocard0\"\n";
- if ($got_Monitor ne "") {
- print " Monitor \"$got_Monitor\"\n";
- } else {
- print " Monitor \"Monitor0\"\n";
- }
- if ($depth ne "") {
- print " DefaultDepth $depth\n";
- } else {
- print " DefaultDepth 24\n";
- }
- print " SubSection \"Display\"\n";
- print " Viewport 0 0\n";
- print " Depth 24\n";
- if ($got_Modes) {
- ;
- } elsif ($geom ne "") {
- print " Modes $geom\n";
- } else {
- print " Modes \"1280x1024\" \"1024x768\" \"800x600\"\n";
- }
- print " EndSubSection\n";
- print "EndSection\n";
- }
-';
-}
-
-# Work out config file and tweak it.
-#
-if [ "X$cmdline_config" = "X" ]; then
- :
-elif [ "X$cmdline_config" = "Xxdummy-builtin" ]; then
- :
-elif echo "$cmdline_config" | grep '/' > /dev/null; then
- :
-else
- # ignore basename only case (let server handle it)
- cmdline_config=""
- notweak=1
-fi
-
-config=$cmdline_config
-
-if [ "X$notweak" = "X1" -a "X$root" = "X" -a -f "$cmdline_config" ]; then
- # if not root we need to copy (but not tweak) the specified config.
- XDUMMY_NOTWEAK=1
- export XDUMMY_NOTWEAK
- notweak=""
-fi
-
-if [ ! $notweak ]; then
- # tweaked config will be put in $config2:
- config2=""
- if [ "X$config" = "X" ]; then
- # use the default one:
- if [ "X$stype" = "Xxorg" ]; then
- config=/etc/X11/xorg.conf
- else
- if [ -f "/etc/X11/XF86Config-4" ]; then
- config="/etc/X11/XF86Config-4"
- else
- config="/etc/X11/XF86Config"
- fi
- fi
- if [ ! -f "$config" ]; then
- for c in /etc/X11/xorg.conf /etc/X11/XF86Config-4 /etc/X11/XF86Config
- do
- if [ -f $c ]; then
- config=$c
- break
- fi
- done
- fi
- fi
-
- if [ "X$config" = "Xxdummy-builtin" ]; then
- config=""
- fi
-
- if [ ! -f "$config" ]; then
- config="$XDUMMY_TMPDIR/xorg.conf"
- warn "$program: using minimal built-in xorg.conf settings."
- cat > $config <<END
-
-Section "ServerLayout"
- Identifier "Layout0"
- Screen 0 "Screen0"
- InputDevice "Keyboard0" "CoreKeyboard"
- InputDevice "Mouse0" "CorePointer"
-EndSection
-
-Section "Files"
-EndSection
-
-Section "Module"
- Load "dbe"
- Load "extmod"
- Load "freetype"
- Load "glx"
-EndSection
-
-Section "InputDevice"
- Identifier "Mouse0"
- Driver "mouse"
- Option "Protocol" "auto"
- Option "Device" "/dev/psaux"
- Option "Emulate3Buttons" "no"
- Option "ZAxisMapping" "4 5"
-EndSection
-
-Section "InputDevice"
- Identifier "Keyboard0"
- Driver "kbd"
-EndSection
-
-Section "Monitor"
- Identifier "Monitor0"
- VendorName "Unknown"
- ModelName "Unknown"
- HorizSync 30.0 - 130.0
- VertRefresh 50.0 - 250.0
- Option "DPMS"
-EndSection
-
-Section "Device"
- Identifier "Device0"
- Driver "foovideo"
- VendorName "foovideo Corporation"
-EndSection
-
-Section "Screen"
- Identifier "Screen0"
- Device "Device0"
- Monitor "Monitor0"
- DefaultDepth 24
- SubSection "Display"
- Depth 24
- Modes "1280x1024"
- EndSubSection
-EndSection
-
-END
- fi
-
- if [ -f "$config" ]; then
- tweak_config $config
- fi
-
- # now we need to get our tweaked config file onto the command line:
- if [ "X$cmdline_config" = "X" ]; then
- # append to cmdline (FUBAR will be substituted below.)
- if [ "X$stype" = "Xxorg" ]; then
- args="$args -config FUBAR"
- else
- args="$args -xf86config FUBAR"
- fi
- fi
- if [ "X$config2" != "X" ]; then
- # or modify $args:
- c2=$config2
- if [ "X$root" = "X" ]; then
- # ordinary user cannot use absolute path.
- c2=`basename $config2`
- fi
- args=`echo "$args" | sed \
- -e "s,-config *[^ ][^ ]*,-config $c2,g" \
- -e "s,-xf86config *[^ ][^ ]*,-xf86config $c2,g"`
- fi
-fi
-
-if [ $prconf ]; then
- warn ""
- warn "Printing out the Xorg/XFree86 server config file:"
- warn ""
- if [ "X$config2" = "X" ]; then
- warn "NO CONFIG GENERATED."
- exit 1
- else
- cat "$config2"
- fi
- exit 0
-fi
-
-if [ $debug ]; then
- XDUMMY_DEBUG=1
- export XDUMMY_DEBUG
-fi
-if [ $root ]; then
- XDUMMY_ROOT=1
- export XDUMMY_ROOT
-fi
-
-# Finally, run it:
-#
-if [ "X$debug" != "X" -o "X$runit" = "X" ]; then
- if [ ! $runit ]; then
- echo ""
- echo "/usr/bin/env:"
- env | egrep -v '^(LS_COLORS|TERMCAP)' | sort
- echo ""
- echo "XDUMMY*:"
- env | grep '^XDUMMY' | sort
- echo ""
- fi
- warn ""
- warn "The command to run is:"
- warn ""
- so=$SO
- pwd=`pwd`
- if echo "$so" | grep '^\./' > /dev/null; then
- so=`echo "$so" | sed -e "s,^\.,$pwd,"`
- fi
- if echo "$so" | grep '/' > /dev/null; then
- :
- else
- so="$pwd/$so"
- fi
- warn "env LD_PRELOAD=$so $xserver $disp $args $vt"
- warn ""
- if [ ! $runit ]; then
- exit 0
- fi
-fi
-
-if [ $strace ]; then
- if [ "X$strace" = "X2" ]; then
- ltrace -f env LD_PRELOAD=$SO $xserver $disp $args $vt
- else
- strace -f env LD_PRELOAD=$SO $xserver $disp $args $vt
- fi
-else
- exec env LD_PRELOAD=$SO $xserver $disp $args $vt
-fi
-
-exit $?
-
-#########################################################################
-
-code() {
-#code_begin
-#include <stdio.h>
-#define O_ACCMODE 0003
-#define O_RDONLY 00
-#define O_WRONLY 01
-#define O_RDWR 02
-#define O_CREAT 0100 /* not fcntl */
-#define O_EXCL 0200 /* not fcntl */
-#define O_NOCTTY 0400 /* not fcntl */
-#define O_TRUNC 01000 /* not fcntl */
-#define O_APPEND 02000
-#define O_NONBLOCK 04000
-#define O_NDELAY O_NONBLOCK
-#define O_SYNC 010000
-#define O_FSYNC O_SYNC
-#define O_ASYNC 020000
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <linux/vt.h>
-#include <linux/kd.h>
-
-#define __USE_GNU
-#include <dlfcn.h>
-
-static char tmpdir[4096];
-static char str1[4096];
-static char str2[4096];
-
-static char devs[256][1024];
-static int debug = -1;
-static int root = -1;
-static int changed_uid = 0;
-static int saw_fonts = 0;
-static int saw_lib_modules = 0;
-
-static time_t start = 0;
-
-void check_debug(void) {
- if (debug < 0) {
- if (getenv("XDUMMY_DEBUG") != NULL) {
- debug = 1;
- } else {
- debug = 0;
- }
- /* prevent other processes using the preload: */
- putenv("LD_PRELOAD=");
- }
-}
-void check_root(void) {
- if (root < 0) {
- /* script tells us if we are root */
- if (getenv("XDUMMY_ROOT") != NULL) {
- root = 1;
- } else {
- root = 0;
- }
- }
-}
-
-void check_uid(void) {
- if (start == 0) {
- start = time(NULL);
- if (debug) fprintf(stderr, "START: %u\n", (unsigned int) start);
- return;
- } else if (changed_uid == 0) {
- if (saw_fonts || time(NULL) > start + 20) {
- if (getenv("XDUMMY_UID")) {
- int uid = atoi(getenv("XDUMMY_UID"));
- if (debug) fprintf(stderr, "SETREUID: %d saw_fonts=%d\n", uid, saw_fonts);
- if (uid >= 0) {
- /* this will simply fail in -nonroot mode: */
- setreuid(uid, -1);
- }
- }
- changed_uid = 1;
- }
- }
-}
-
-#define CHECKIT if (debug < 0) check_debug(); \
- if (root < 0) check_root(); \
- check_uid();
-
-static void set_tmpdir(void) {
- char *s;
- static int didset = 0;
- if (didset) {
- return;
- }
- s = getenv("XDUMMY_TMPDIR");
- if (! s) {
- s = "/tmp";
- }
- tmpdir[0] = '\0';
- strcat(tmpdir, s);
- strcat(tmpdir, "/");
- didset = 1;
-}
-
-static char *tmpdir_path(const char *path) {
- char *str;
- set_tmpdir();
- strcpy(str2, path);
- str = str2;
- while (*str) {
- if (*str == '/') {
- *str = '_';
- }
- str++;
- }
- strcpy(str1, tmpdir);
- strcat(str1, str2);
- return str1;
-}
-
-int open(const char *pathname, int flags, unsigned short mode) {
- int fd;
- char *store_dev = NULL;
- static int (*real_open)(const char *, int , unsigned short) = NULL;
-
- CHECKIT
- if (! real_open) {
- real_open = (int (*)(const char *, int , unsigned short))
- dlsym(RTLD_NEXT, "open");
- }
-
- if (strstr(pathname, "lib/modules/")) {
- /* not currently used. */
- saw_lib_modules = 1;
- }
-
- if (!root) {
- if (strstr(pathname, "/dev/") == pathname) {
- store_dev = strdup(pathname);
- }
- if (strstr(pathname, "/dev/tty") == pathname && strcmp(pathname, "/dev/tty")) {
- pathname = tmpdir_path(pathname);
- if (debug) fprintf(stderr, "OPEN: %s -> %s (as FIFO)\n", store_dev, pathname);
- /* we make it a FIFO so ioctl on it does not fail */
- unlink(pathname);
- mkfifo(pathname, 0666);
- } else if (0) {
- /* we used to handle more /dev files ... */
- fd = real_open(pathname, O_WRONLY|O_CREAT, 0777);
- close(fd);
- }
- }
-
- fd = real_open(pathname, flags, mode);
-
- if (debug) fprintf(stderr, "OPEN: %s %d %d fd=%d\n", pathname, flags, mode, fd);
-
- if (! root) {
- if (store_dev) {
- if (fd < 256) {
- strcpy(devs[fd], store_dev);
- }
- free(store_dev);
- }
- }
-
- return(fd);
-}
-
-int open64(const char *pathname, int flags, unsigned short mode) {
- int fd;
-
- CHECKIT
- if (debug) fprintf(stderr, "OPEN64: %s %d %d\n", pathname, flags, mode);
-
- fd = open(pathname, flags, mode);
- return(fd);
-}
-
-int rename(const char *oldpath, const char *newpath) {
- static int (*real_rename)(const char *, const char *) = NULL;
-
- CHECKIT
- if (! real_rename) {
- real_rename = (int (*)(const char *, const char *))
- dlsym(RTLD_NEXT, "rename");
- }
-
- if (debug) fprintf(stderr, "RENAME: %s %s\n", oldpath, newpath);
-
- if (root) {
- return(real_rename(oldpath, newpath));
- }
-
- if (strstr(oldpath, "/var/log") == oldpath) {
- if (debug) fprintf(stderr, "RENAME: returning 0\n");
- return 0;
- }
- return(real_rename(oldpath, newpath));
-}
-
-FILE *fopen(const char *pathname, const char *mode) {
- static FILE* (*real_fopen)(const char *, const char *) = NULL;
- char *str;
-
- if (! saw_fonts) {
- if (strstr(pathname, "/fonts/")) {
- if (strstr(pathname, "fonts.dir")) {
- saw_fonts = 1;
- } else if (strstr(pathname, "fonts.alias")) {
- saw_fonts = 1;
- }
- }
- }
-
- CHECKIT
- if (! real_fopen) {
- real_fopen = (FILE* (*)(const char *, const char *))
- dlsym(RTLD_NEXT, "fopen");
- }
-
- if (debug) fprintf(stderr, "FOPEN: %s %s\n", pathname, mode);
-
- if (strstr(pathname, "xdummy_modified_xconfig.conf")) {
- /* make our config appear to be in /etc/X11, etc. */
- char *q = strrchr(pathname, '/');
- if (q != NULL && getenv("XDUMMY_TMPDIR") != NULL) {
- strcpy(str1, getenv("XDUMMY_TMPDIR"));
- strcat(str1, q);
- if (debug) fprintf(stderr, "FOPEN: %s -> %s\n", pathname, str1);
- pathname = str1;
- }
- }
-
- if (root) {
- return(real_fopen(pathname, mode));
- }
-
- str = (char *) pathname;
- if (strstr(pathname, "/var/log") == pathname) {
- str = tmpdir_path(pathname);
- if (debug) fprintf(stderr, "FOPEN: %s -> %s\n", pathname, str);
- }
- return(real_fopen(str, mode));
-}
-
-
-#define RETURN0 if (debug) \
- {fprintf(stderr, "IOCTL: covered %d 0x%x\n", fd, req);} return 0;
-#define RETURN1 if (debug) \
- {fprintf(stderr, "IOCTL: covered %d 0x%x\n", fd, req);} return -1;
-
-int ioctl(int fd, int req, void *ptr) {
- static int closed_xf86Info_consoleFd = 0;
- static int (*real_ioctl)(int, int , void *) = NULL;
-
- CHECKIT
- if (! real_ioctl) {
- real_ioctl = (int (*)(int, int , void *))
- dlsym(RTLD_NEXT, "open");
- }
- if (debug) fprintf(stderr, "IOCTL: %d 0x%x %p\n", fd, req, ptr);
-
- /* based on xorg-x11-6.8.1-dualhead.patch */
- if (req == VT_GETMODE) {
- /* close(xf86Info.consoleFd) */
- if (0 && ! closed_xf86Info_consoleFd) {
- /* I think better not to close it... */
- close(fd);
- closed_xf86Info_consoleFd = 1;
- }
- RETURN0
- } else if (req == VT_SETMODE) {
- RETURN0
- } else if (req == VT_GETSTATE) {
- RETURN0
- } else if (req == KDSETMODE) {
- RETURN0
- } else if (req == KDSETLED) {
- RETURN0
- } else if (req == KDGKBMODE) {
- RETURN0
- } else if (req == KDSKBMODE) {
- RETURN0
- } else if (req == VT_ACTIVATE) {
- RETURN0
- } else if (req == VT_WAITACTIVE) {
- RETURN0
- } else if (req == VT_RELDISP) {
- if (ptr == (void *) 1) {
- RETURN1
- } else if (ptr == (void *) VT_ACKACQ) {
- RETURN0
- }
- }
-
- return(real_ioctl(fd, req, ptr));
-}
-
-typedef void (*sighandler_t)(int);
-#define SIGUSR1 10
-#define SIG_DFL ((sighandler_t)0)
-
-sighandler_t signal(int signum, sighandler_t handler) {
- static sighandler_t (*real_signal)(int, sighandler_t) = NULL;
-
- CHECKIT
- if (! real_signal) {
- real_signal = (sighandler_t (*)(int, sighandler_t))
- dlsym(RTLD_NEXT, "signal");
- }
-
- if (debug) fprintf(stderr, "SIGNAL: %d %p\n", signum, handler);
-
- if (signum == SIGUSR1) {
- if (debug) fprintf(stderr, "SIGNAL: skip SIGUSR1\n");
- return SIG_DFL;
- }
-
- return(real_signal(signum, handler));
-}
-
-int close(int fd) {
- static int (*real_close)(int) = NULL;
-
- CHECKIT
- if (! real_close) {
- real_close = (int (*)(int)) dlsym(RTLD_NEXT, "close");
- }
-
- if (debug) fprintf(stderr, "CLOSE: %d\n", fd);
- if (!root) {
- if (fd < 256) {
- devs[fd][0] = '\0';
- }
- }
- return(real_close(fd));
-}
-
-struct stat {
- int foo;
-};
-
-int stat(const char *path, struct stat *buf) {
- static int (*real_stat)(const char *, struct stat *) = NULL;
-
- CHECKIT
- if (! real_stat) {
- real_stat = (int (*)(const char *, struct stat *))
- dlsym(RTLD_NEXT, "stat");
- }
-
- if (debug) fprintf(stderr, "STAT: %s\n", path);
-
- return(real_stat(path, buf));
-}
-
-int stat64(const char *path, struct stat *buf) {
- static int (*real_stat64)(const char *, struct stat *) = NULL;
-
- CHECKIT
- if (! real_stat64) {
- real_stat64 = (int (*)(const char *, struct stat *))
- dlsym(RTLD_NEXT, "stat64");
- }
-
- if (debug) fprintf(stderr, "STAT64: %s\n", path);
-
- return(real_stat64(path, buf));
-}
-
-int chown(const char *path, uid_t owner, gid_t group) {
- static int (*real_chown)(const char *, uid_t, gid_t) = NULL;
-
- CHECKIT
- if (! real_chown) {
- real_chown = (int (*)(const char *, uid_t, gid_t))
- dlsym(RTLD_NEXT, "chown");
- }
-
- if (root) {
- return(real_chown(path, owner, group));
- }
-
- if (debug) fprintf(stderr, "CHOWN: %s %d %d\n", path, owner, group);
-
- if (strstr(path, "/dev") == path) {
- if (debug) fprintf(stderr, "CHOWN: return 0\n");
- return 0;
- }
-
- return(real_chown(path, owner, group));
-}
-
-extern int *__errno_location (void);
-#ifndef ENODEV
-#define ENODEV 19
-#endif
-
-int ioperm(unsigned long from, unsigned long num, int turn_on) {
- static int (*real_ioperm)(unsigned long, unsigned long, int) = NULL;
-
- CHECKIT
- if (! real_ioperm) {
- real_ioperm = (int (*)(unsigned long, unsigned long, int))
- dlsym(RTLD_NEXT, "ioperm");
- }
- if (debug) fprintf(stderr, "IOPERM: %d %d %d\n", (int) from, (int) num, turn_on);
- if (root) {
- return(real_ioperm(from, num, turn_on));
- }
- if (from == 0 && num == 1024 && turn_on == 1) {
- /* we want xf86EnableIO to fail */
- if (debug) fprintf(stderr, "IOPERM: setting ENODEV.\n");
- *__errno_location() = ENODEV;
- return -1;
- }
- return 0;
-}
-
-int iopl(int level) {
- static int (*real_iopl)(int) = NULL;
-
- CHECKIT
- if (! real_iopl) {
- real_iopl = (int (*)(int)) dlsym(RTLD_NEXT, "iopl");
- }
- if (debug) fprintf(stderr, "IOPL: %d\n", level);
- if (root) {
- return(real_iopl(level));
- }
- return 0;
-}
-
-#ifdef INTERPOSE_GETUID
-
-/*
- * we got things to work w/o pretending to be root.
- * so we no longer interpose getuid(), etc.
- */
-
-uid_t getuid(void) {
- static uid_t (*real_getuid)(void) = NULL;
- CHECKIT
- if (! real_getuid) {
- real_getuid = (uid_t (*)(void)) dlsym(RTLD_NEXT, "getuid");
- }
- if (root) {
- return(real_getuid());
- }
- if (debug) fprintf(stderr, "GETUID: 0\n");
- return 0;
-}
-uid_t geteuid(void) {
- static uid_t (*real_geteuid)(void) = NULL;
- CHECKIT
- if (! real_geteuid) {
- real_geteuid = (uid_t (*)(void)) dlsym(RTLD_NEXT, "geteuid");
- }
- if (root) {
- return(real_geteuid());
- }
- if (debug) fprintf(stderr, "GETEUID: 0\n");
- return 0;
-}
-uid_t geteuid_kludge1(void) {
- static uid_t (*real_geteuid)(void) = NULL;
- CHECKIT
- if (! real_geteuid) {
- real_geteuid = (uid_t (*)(void)) dlsym(RTLD_NEXT, "geteuid");
- }
- if (debug) fprintf(stderr, "GETEUID: 0 saw_libmodules=%d\n", saw_lib_modules);
- if (root && !saw_lib_modules) {
- return(real_geteuid());
- } else {
- saw_lib_modules = 0;
- return 0;
- }
-}
-
-uid_t getuid32(void) {
- static uid_t (*real_getuid32)(void) = NULL;
- CHECKIT
- if (! real_getuid32) {
- real_getuid32 = (uid_t (*)(void)) dlsym(RTLD_NEXT, "getuid32");
- }
- if (root) {
- return(real_getuid32());
- }
- if (debug) fprintf(stderr, "GETUID32: 0\n");
- return 0;
-}
-uid_t geteuid32(void) {
- static uid_t (*real_geteuid32)(void) = NULL;
- CHECKIT
- if (! real_geteuid32) {
- real_geteuid32 = (uid_t (*)(void)) dlsym(RTLD_NEXT, "geteuid32");
- }
- if (root) {
- return(real_geteuid32());
- }
- if (debug) fprintf(stderr, "GETEUID32: 0\n");
- return 0;
-}
-
-gid_t getgid(void) {
- static gid_t (*real_getgid)(void) = NULL;
- CHECKIT
- if (! real_getgid) {
- real_getgid = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getgid");
- }
- if (root) {
- return(real_getgid());
- }
- if (debug) fprintf(stderr, "GETGID: 0\n");
- return 0;
-}
-gid_t getegid(void) {
- static gid_t (*real_getegid)(void) = NULL;
- CHECKIT
- if (! real_getegid) {
- real_getegid = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getegid");
- }
- if (root) {
- return(real_getegid());
- }
- if (debug) fprintf(stderr, "GETEGID: 0\n");
- return 0;
-}
-gid_t getgid32(void) {
- static gid_t (*real_getgid32)(void) = NULL;
- CHECKIT
- if (! real_getgid32) {
- real_getgid32 = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getgid32");
- }
- if (root) {
- return(real_getgid32());
- }
- if (debug) fprintf(stderr, "GETGID32: 0\n");
- return 0;
-}
-gid_t getegid32(void) {
- static gid_t (*real_getegid32)(void) = NULL;
- CHECKIT
- if (! real_getegid32) {
- real_getegid32 = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getegid32");
- }
- if (root) {
- return(real_getegid32());
- }
- if (debug) fprintf(stderr, "GETEGID32: 0\n");
- return 0;
-}
-#endif
-
-#if 0
-/* maybe we need to interpose on strcmp someday... here is the template */
-int strcmp(const char *s1, const char *s2) {
- static int (*real_strcmp)(const char *, const char *) = NULL;
- CHECKIT
- if (! real_strcmp) {
- real_strcmp = (int (*)(const char *, const char *)) dlsym(RTLD_NEXT, "strcmp");
- }
- if (debug) fprintf(stderr, "STRCMP: '%s' '%s'\n", s1, s2);
- return(real_strcmp(s1, s2));
-}
-#endif
-
-#code_end
-}
diff --git a/x11vnc/misc/blockdpy.c b/x11vnc/misc/blockdpy.c
deleted file mode 100644
index f3b428e..0000000
--- a/x11vnc/misc/blockdpy.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * blockdpy.c
- *
- * Copyright (c) 2004 Karl J. Runge <runge@karlrunge.com>
- * All rights reserved.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
- *
- *-----------------------------------------------------------------------
- *
- * This tool is intended for use with x11vnc. It is a kludge to try to
- * "block" access via the physical display while x11vnc is running.
- *
- * The expected application is that of a user who screen-locks his
- * workstation before leaving and then later unlocks it remotely via
- * x11vnc. The user is concerned people with physical access to the
- * machine will be watching, etc.
- *
- * Of course if people have physical access to the machine there are
- * much larger potential security problems, but the idea here is to put
- * up a larger barrier than simply turning on the monitor and tapping
- * the mouse (i.e. to wake up the monitor from DPMS and then observe
- * the x11vnc activity).
- *
- * This program requires DPMS support in the video card and monitor,
- * and the DPMS extension in the X server and the corresponding
- * library with the DPMS API (libXext).
- *
- * It starts off by forcing the state to be DPMSModeOff (lowest power).
- * Then it periodically (a few times a second) checks if the system is
- * still in that state. If it discovers it to be in another state, it
- * immediately runs, as a separate command, a screen-lock program, "xlock"
- * by default. The environment variable XLOCK_CMD or -lock option can
- * override this default. "xscreensaver-command" might be another choice.
- *
- * It is up to the user to make sure the screen-lock command works
- * and PATH is set up correctly, etc. The command can do anything,
- * it doesn't have to lock the screen. It could make the sound of a
- * dog barking, for example :-)
- *
- * The option '-grab' causes the program to additionally call
- * XGrabServer() to try to prevent physical mouse or keyboard input to get
- * to any applications on the screen. NOTE: do NOT use, not working yet!
- * Freezes everything.
- *
- * The options: -display and -auth can be used to set the DISPLAY and
- * XAUTHORITY environment variables via the command line.
- *
- * The options -standby and -suspend change the desired DPMS level
- * to be DPMSModeStandby and DPMSModeSuspend, respectively.
- *
- * The option '-f flagfile' indicates a flag file to watch for to cause
- * the program to clean up and exit once it exists. No screen locking is
- * done when the file appears: it is an 'all clear' flag. Presumably the
- * x11vnc user has relocked the screen before the flagfile is created.
- * See below for coupling this behavior with the -gone command.
- *
- * The option '-bg' causes the program to fork into the background and
- * return 0 if everything looks ok. If there was an error up to that
- * point the return value would be 1.
- *
- * Option '-v' prints more info out, useful for testing and debugging.
- *
- *
- * These options allow this sort of x11vnc usage:
- *
- * x11vnc ... -accept "blockdpy -bg -f $HOME/.bdpy" -gone "touch $HOME/.bdpy"
- *
- * (this may also work for gone: -gone "killall blockdpy")
- *
- * In the above, once a client connects this program starts up in the
- * background and monitors the DPMS level. When the client disconnects
- * (he relocked the screen before doing so) the flag file is created and
- * so this program exits normally. On the other hand, if the physical
- * mouse or keyboard was used during the session, this program would
- * have locked the screen as soon as it noticed the DPMS change.
- *
- * One could create shell scripts for -accept and -gone that do much
- * more sophisticated things. This would be needed if more than one
- * client connects at a time.
- *
- * It is important to remember once this program locks the screen
- * it *exits*, so nothing will be watching the screen at that point.
- * Don't immediately unlock the screen from in x11vnc!! Best to think
- * about what might have happened, disconnect the VNC viewer, and then
- * restart x11vnc (thereby having this monitoring program started again).
- *
- *
- * To compile on Linux or Solaris:
-
- cc -o blockdpy blockdpy.c -L /usr/X11R6/lib -L /usr/openwin/lib -lX11 -lXext
-
- * (may also need -I /usr/.../include on older machines).
- *
- */
-
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <signal.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xproto.h>
-#include <X11/extensions/dpms.h>
-
-Display *dpy = NULL;
-CARD16 standby, suspend, off;
-int grab = 0;
-int verbose = 0;
-int bg = 0;
-
-/* for sleeping some number of millisecs */
-struct timeval _mysleep;
-#define msleep(x) \
- _mysleep.tv_sec = ((x)*1000) / 1000000; \
- _mysleep.tv_usec = ((x)*1000) % 1000000; \
- select(0, NULL, NULL, NULL, &_mysleep);
-
-/* called on signal or if DPMS changed, or other problem */
-void reset(int sig) {
- if (grab) {
- if (verbose) {
- fprintf(stderr, "calling XUngrabServer()\n");
- }
- XUngrabServer(dpy);
- }
- if (verbose) {
- fprintf(stderr, "resetting original DPMS values.\n");
- }
- fprintf(stderr, "blockdpy: reset sig=%d called\n", sig);
- DPMSEnable(dpy);
- DPMSSetTimeouts(dpy, standby, suspend, off);
- XFlush(dpy);
- if (sig) {
- XCloseDisplay(dpy);
- exit(0);
- }
-}
-
-int main(int argc, char** argv) {
-
- int verbose = 0, bg = 0;
- int i, ev, er;
- char *lock_cmd = "xlock";
- char *flag_file = NULL;
- char estr[100], cmd[500];
- struct stat sbuf;
- CARD16 power;
- CARD16 desired = DPMSModeOff;
- BOOL state;
-
-
- /* setup the lock command. it may be reset by -lock below. */
- if (getenv("XLOCK_CMD")) {
- lock_cmd = (char *) getenv("XLOCK_CMD");
- }
-
- /* process cmd line: */
- for (i=1; i<argc; i++) {
- if (!strcmp(argv[i], "-display")) {
- sprintf(estr, "DISPLAY=%s", argv[++i]);
- putenv(strdup(estr));
- } else if (!strcmp(argv[i], "-auth")) {
- sprintf(estr, "XAUTHORITY=%s", argv[++i]);
- putenv(strdup(estr));
- } else if (!strcmp(argv[i], "-lock")) {
- lock_cmd = argv[++i];
- } else if (!strcmp(argv[i], "-f")) {
- flag_file = argv[++i];
- unlink(flag_file);
- } else if (!strcmp(argv[i], "-grab")) {
- grab = 1;
- } else if (!strcmp(argv[i], "-bg")) {
- bg = 1;
- } else if (!strcmp(argv[i], "-v")) {
- verbose = 1;
- } else if (!strcmp(argv[i], "-standby")) {
- desired = DPMSModeStandby;
- } else if (!strcmp(argv[i], "-suspend")) {
- desired = DPMSModeSuspend;
- } else if (!strcmp(argv[i], "-off")) {
- desired = DPMSModeOff;
- }
- }
-
- /* we want it to go into background to avoid blocking, so add '&'. */
- strcpy(cmd, lock_cmd);
- strcat(cmd, " &");
- lock_cmd = cmd;
-
- /* close any file descriptors we may have inherited (e.g. port 5900) */
- for (i=3; i<=100; i++) {
- close(i);
- }
-
- /* open DISPLAY */
- dpy = XOpenDisplay(NULL);
- if (! dpy) {
- fprintf(stderr, "XOpenDisplay failed.\n");
- exit(1);
- }
-
- /* check for DPMS extension */
- if (! DPMSQueryExtension(dpy, &ev, &er)) {
- fprintf(stderr, "DPMSQueryExtension failed.\n");
- exit(1);
- }
- if (! DPMSCapable(dpy)) {
- fprintf(stderr, "DPMSCapable failed.\n");
- exit(1);
- }
- /* make sure DPMS is enabled */
- if (! DPMSEnable(dpy)) {
- fprintf(stderr, "DPMSEnable failed.\n");
- exit(1);
- }
-
- /* retrieve the timeouts for later resetting */
- if (! DPMSGetTimeouts(dpy, &standby, &suspend, &off)) {
- fprintf(stderr, "DPMSGetTimeouts failed.\n");
- exit(1);
- }
- if (! standby || ! suspend || ! off) {
- /* if none, set to some reasonable values */
- standby = 900;
- suspend = 1200;
- off = 1800;
- }
- if (verbose) {
- fprintf(stderr, "DPMS timeouts: %d %d %d\n", standby,
- suspend, off);
- }
-
- /* now set them to very small values */
- if (desired == DPMSModeOff) {
- if (! DPMSSetTimeouts(dpy, 1, 1, 1)) {
- fprintf(stderr, "DPMSSetTimeouts failed.\n");
- exit(1);
- }
- } else if (desired == DPMSModeSuspend) {
- if (! DPMSSetTimeouts(dpy, 1, 1, 0)) {
- fprintf(stderr, "DPMSSetTimeouts failed.\n");
- exit(1);
- }
- } else if (desired == DPMSModeStandby) {
- if (! DPMSSetTimeouts(dpy, 1, 0, 0)) {
- fprintf(stderr, "DPMSSetTimeouts failed.\n");
- exit(1);
- }
- }
- XFlush(dpy);
-
- /* set handlers for clean up in case we terminate via signal */
- signal(SIGHUP, reset);
- signal(SIGINT, reset);
- signal(SIGQUIT, reset);
- signal(SIGABRT, reset);
- signal(SIGTERM, reset);
-
- /* force state into DPMS Off (lowest power) mode */
- if (! DPMSForceLevel(dpy, desired)) {
- fprintf(stderr, "DPMSForceLevel failed.\n");
- exit(1);
- }
- XFlush(dpy);
-
- /* read state */
- msleep(500);
- if (! DPMSInfo(dpy, &power, &state)) {
- fprintf(stderr, "DPMSInfo failed.\n");
- exit(1);
- }
- fprintf(stderr, "power: %d state: %d\n", power, state);
-
- /* grab display if desired. NOT WORKING */
- if (grab) {
- if (verbose) {
- fprintf(stderr, "calling XGrabServer()\n");
- }
- XGrabServer(dpy);
- }
-
- /* go into background if desired. */
- if (bg) {
- pid_t p;
- if ((p = fork()) != 0) {
- if (p < 0) {
- fprintf(stderr, "problem forking.\n");
- exit(1);
- } else {
- /* XXX no fd closing */
- exit(0);
- }
- }
- }
-
- /* main loop: */
- while (1) {
- /* reassert DPMSModeOff (desired) */
- if (verbose) fprintf(stderr, "reasserting desired DPMSMode\n");
- DPMSForceLevel(dpy, desired);
- XFlush(dpy);
-
- /* wait a bit */
- msleep(200);
-
- /* check for flag file appearence */
- if (flag_file && stat(flag_file, &sbuf) == 0) {
- if (verbose) {
- fprintf(stderr, "flag found: %s\n", flag_file);
- }
- unlink(flag_file);
- reset(0);
- exit(0);
- }
-
- /* check state and power level */
- if (! DPMSInfo(dpy, &power, &state)) {
- fprintf(stderr, "DPMSInfo failed.\n");
- reset(0);
- exit(1);
- }
- if (verbose) {
- fprintf(stderr, "power: %d state: %d\n", power, state);
- }
- if (!state || power != desired) {
- /* Someone (or maybe a cat) is evidently watching... */
- fprintf(stderr, "DPMS CHANGE: power: %d state: %d\n",
- power, state);
- break;
- }
- }
- reset(0);
- fprintf(stderr, "locking screen with command: \"%s\"\n", lock_cmd);
- system(lock_cmd);
- exit(0);
-}
diff --git a/x11vnc/misc/connect_switch b/x11vnc/misc/connect_switch
deleted file mode 100755
index 08376c6..0000000
--- a/x11vnc/misc/connect_switch
+++ /dev/null
@@ -1,696 +0,0 @@
-#!/usr/bin/perl
-#
-# Copyright (c) 2006-2010 by Karl J. Runge <runge@karlrunge.com>
-#
-# connect_switch is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# connect_switch is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with connect_switch; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-# or see <http://www.gnu.org/licenses/>.
-#
-#
-# connect_switch:
-#
-# A kludge script that sits between web clients and a mod_ssl (https)
-# enabled apache webserver.
-#
-# If an incoming web client connection makes a proxy CONNECT request
-# it is handled directly by this script (apache is not involved).
-# Otherwise, all other connections are forwarded to the apache webserver.
-#
-# This can be useful for VNC redirection using an existing https (port
-# 443) webserver, thereby not requiring a 2nd (non-https) port open on
-# the firewall for the CONNECT requests.
-#
-# It does not seem possible (to me) to achieve this entirely within apache
-# because the CONNECT request appears to be forwarded encrypted to
-# the remote host and so the SSL dies immediately.
-#
-# It can also be used to redirect ANY protocol, e.g. SSH, not just VNC.
-# See CONNECT_SWITCH_APPLY_VNC_OFFSET=0 to disable VNC 5900 shift.
-#
-# Note: There is no need to use this script for a non-ssl apache webserver
-# port because mod_proxy works fine for doing the switching all inside
-# apache (see ProxyRequests and AllowCONNECT parameters).
-#
-#
-# Apache configuration:
-#
-# The mod_ssl configuration is often in a file named ssl.conf. In the
-# simplest case you change something like this:
-#
-# From:
-#
-# Listen 443
-#
-# <VirtualHost _default_:443>
-# ...
-# </VirtualHost>
-#
-# To:
-#
-# Listen 127.0.0.1:443
-#
-# <VirtualHost _default_:443>
-# ...
-# </VirtualHost>
-#
-# (i.e. just change the Listen directive).
-#
-# If you have mod_ssl listening on a different internal port, you do
-# not need to specify the localhost Listen address.
-#
-# It is probably a good idea to set $listen_host below to the known
-# IP address you want the service to listen on (to avoid localhost where
-# apache is listening).
-#
-
-####################################################################
-# NOTE: For more info on configuration settings, read below for
-# all of the CONNECT_SWITCH_* env. var. parameters.
-####################################################################
-
-
-####################################################################
-# Allow env vars to also be specified on cmdline:
-#
-foreach my $arg (@ARGV) {
- if ($arg =~ /^(CONNECT_SWITCH.*?)=(.*)$/) {
- $ENV{$1} = $2;
- }
-}
-
-# Set up logging:
-#
-if (exists $ENV{CONNECT_SWITCH_LOGFILE}) {
- close STDOUT;
- if (!open(STDOUT, ">>$ENV{CONNECT_SWITCH_LOGFILE}")) {
- die "connect_switch: $ENV{CONNECT_SWITCH_LOGFILE} $!\n";
- }
- close STDERR;
- open(STDERR, ">&STDOUT");
-}
-select(STDERR); $| = 1;
-select(STDOUT); $| = 1;
-
-# interrupt handler:
-#
-my $looppid = '';
-my $pidfile = '';
-my $listen_sock = ''; # declared here for get_out()
-#
-sub get_out {
- print STDERR "$_[0]:\t$$ looppid=$looppid\n";
- close $listen_sock if $listen_sock;
- if ($looppid) {
- kill 'TERM', $looppid;
- fsleep(0.2);
- }
- unlink $pidfile if $pidfile;
- exit 0;
-}
-$SIG{INT} = \&get_out;
-$SIG{TERM} = \&get_out;
-
-# pidfile:
-#
-sub open_pidfile {
- if (exists $ENV{CONNECT_SWITCH_PIDFILE}) {
- my $pf = $ENV{CONNECT_SWITCH_PIDFILE};
- if (open(PID, ">$pf")) {
- print PID "$$\n";
- close PID;
- $pidfile = $pf;
- } else {
- print STDERR "could not open pidfile: $pf - $! - continuing...\n";
- }
- delete $ENV{CONNECT_SWITCH_PIDFILE};
- }
-}
-
-####################################################################
-# Set CONNECT_SWITCH_LOOP=1 to have this script create an outer loop
-# restarting itself if it ever exits. Set CONNECT_SWITCH_LOOP=BG to
-# do this in the background as a daemon.
-
-if (exists $ENV{CONNECT_SWITCH_LOOP}) {
- my $csl = $ENV{CONNECT_SWITCH_LOOP};
- if ($csl ne 'BG' && $csl ne '1') {
- die "connect_switch: invalid CONNECT_SWITCH_LOOP.\n";
- }
- if ($csl eq 'BG') {
- # go into bg as "daemon":
- setpgrp(0, 0);
- my $pid = fork();
- if (! defined $pid) {
- die "connect_switch: $!\n";
- } elsif ($pid) {
- wait;
- exit 0;
- }
- if (fork) {
- exit 0;
- }
- setpgrp(0, 0);
- close STDIN;
- if (! $ENV{CONNECT_SWITCH_LOGFILE}) {
- close STDOUT;
- close STDERR;
- }
- }
- delete $ENV{CONNECT_SWITCH_LOOP};
-
- if (exists $ENV{CONNECT_SWITCH_PIDFILE}) {
- open_pidfile();
- }
-
- print STDERR "connect_switch: starting service at ", scalar(localtime), " master-pid=$$\n";
- while (1) {
- $looppid = fork;
- if (! defined $looppid) {
- sleep 10;
- } elsif ($looppid) {
- wait;
- } else {
- exec $0;
- exit 1;
- }
- print STDERR "connect_switch: re-starting service at ", scalar(localtime), " master-pid=$$\n";
- sleep 1;
- }
- exit 0;
-}
-if (exists $ENV{CONNECT_SWITCH_PIDFILE}) {
- open_pidfile();
-}
-
-
-############################################################################
-# The defaults for hosts and ports (you can override them below if needed):
-#
-# Look below for these environment variables that let you set the various
-# parameters without needing to edit this script:
-#
-# CONNECT_SWITCH_LISTEN
-# CONNECT_SWITCH_HTTPD
-# CONNECT_SWITCH_ALLOWED
-# CONNECT_SWITCH_ALLOW_FILE
-# CONNECT_SWITCH_VERBOSE
-# CONNECT_SWITCH_APPLY_VNC_OFFSET
-# CONNECT_SWITCH_VNC_OFFSET
-# CONNECT_SWITCH_LISTEN_IPV6
-# CONNECT_SWITCH_BUFSIZE
-# CONNECT_SWITCH_LOGFILE
-# CONNECT_SWITCH_PIDFILE
-# CONNECT_SWITCH_MAX_CONNECTIONS
-#
-# You can also set these on the cmdline:
-# connect_switch CONNECT_SWITCH_LISTEN=X CONNECT_SWITCH_ALLOW_FILE=Y ...
-#
-
-# By default we will use hostname and assume it resolves:
-#
-my $hostname = `hostname`;
-chomp $hostname;
-
-my $listen_host = $hostname;
-my $listen_port = 443;
-
-# Let user override listening situation, e.g. multihomed:
-#
-if (exists $ENV{CONNECT_SWITCH_LISTEN}) {
- #
- # E.g. CONNECT_SWITCH_LISTEN=192.168.0.32:443
- #
- $listen_host = '';
- $listen_port = '';
- if ($ENV{CONNECT_SWITCH_LISTEN} =~ /^(.*):(\d+)$/) {
- ($listen_host, $listen_port) = ($1, $2);
- }
-}
-
-my $httpd_host = 'localhost';
-my $httpd_port = 443;
-
-if (exists $ENV{CONNECT_SWITCH_HTTPD}) {
- #
- # E.g. CONNECT_SWITCH_HTTPD=127.0.0.1:443
- #
- $httpd_host = '';
- $httpd_port = '';
- if ($ENV{CONNECT_SWITCH_HTTPD} =~ /^(.*):(\d+)$/) {
- ($httpd_host, $httpd_port) = ($1, $2);
- }
-}
-
-my $bufsize = 8192;
-if (exists $ENV{CONNECT_SWITCH_BUFSIZE}) {
- #
- # E.g. CONNECT_SWITCH_BUFSIZE=32768
- #
- $bufsize = $ENV{CONNECT_SWITCH_BUFSIZE};
-}
-
-
-############################################################################
-# You can/should override the host/port settings here:
-#
-#$listen_host = '23.45.67.89'; # set to your interface IP number.
-#$listen_port = 555; # and/or nonstandard port.
-#$httpd_host = 'somehost'; # maybe you redir https to another machine.
-#$httpd_port = 666; # and/or nonstandard port.
-
-# You must set the allowed host:port CONNECT redirection list.
-# Only these host:port pairs will be redirected to.
-# Port ranges are allowed too: host:5900-5930.
-# If there is one entry named ALL all connections are allow.
-# You must supply something, default is deny.
-#
-my @allowed = qw(
- machine1:5915
- machine2:5900
-);
-
-if (exists $ENV{CONNECT_SWITCH_ALLOWED}) {
- #
- # E.g. CONNECT_SWITCH_ALLOWED=machine1:5915,machine2:5900
- #
- @allowed = split(/,/, $ENV{CONNECT_SWITCH_ALLOWED});
-}
-
-# Or you could also use an external "allow file".
-# They get added to the @allowed list.
-# The file is re-read for each new connection.
-#
-# Format of $allow_file:
-#
-# host1 vncdisp
-# host2 vncdisp
-#
-# where, e.g. vncdisp = 15 => port 5915, say
-#
-# joesbox 15
-# fredsbox 15
-# rupert 1
-
-# For examply, mine is:
-#
-my $allow_file = '/dist/apache/2.0/conf/vnc.hosts';
-$allow_file = '';
-
-if (exists $ENV{CONNECT_SWITCH_ALLOW_FILE}) {
- # E.g. CONNECT_SWITCH_ALLOW_FILE=/usr/local/etc/allow.txt
- $allow_file = $ENV{CONNECT_SWITCH_ALLOW_FILE};
-}
-
-# Set to 1 to re-map to vnc port, e.g. 'hostname 15' to 'hostname 5915'
-# i.e. assume a port 0 <= port < 200 is actually a VNC display
-# and add 5900 to it. Set to 0 to not do the mapping.
-# Note that negative ports, e.g. 'joesbox -22' go directly to -port.
-#
-my $apply_vnc_offset = 1;
-my $vnc_offset = 5900;
-
-if (exists $ENV{CONNECT_SWITCH_APPLY_VNC_OFFSET}) {
- #
- # E.g. CONNECT_SWITCH_APPLY_VNC_OFFSET=0
- #
- $apply_vnc_offset = $ENV{CONNECT_SWITCH_APPLY_VNC_OFFSET};
-}
-if (exists $ENV{CONNECT_SWITCH_VNC_OFFSET}) {
- #
- # E.g. CONNECT_SWITCH_VNC_OFFSET=6000
- #
- $vnc_offset = $ENV{CONNECT_SWITCH_VNC_OFFSET};
-}
-
-# Set to 1 or higher for more info output:
-#
-my $verbose = 0;
-
-if (exists $ENV{CONNECT_SWITCH_VERBOSE}) {
- #
- # E.g. CONNECT_SWITCH_VERBOSE=1
- #
- $verbose = $ENV{CONNECT_SWITCH_VERBOSE};
-}
-
-# zero means loop forever, positive value means exit after handling that
-# many connections.
-#
-my $cmax = 0;
-if (exists $ENV{CONNECT_SWITCH_MAX_CONNECTIONS}) {
- $cmax = $ENV{CONNECT_SWITCH_MAX_CONNECTIONS};
-}
-
-
-#===========================================================================
-# No need for any changes below here.
-#===========================================================================
-
-use IO::Socket::INET;
-use strict;
-use warnings;
-
-# Test for INET6 support:
-#
-my $have_inet6 = 0;
-eval "use IO::Socket::INET6;";
-$have_inet6 = 1 if $@ eq "";
-
-my $killpid = 1;
-
-setpgrp(0, 0);
-
-if (exists $ENV{CONNECT_SWITCH_LISTEN_IPV6}) {
- # note we leave out LocalAddr.
- my $cmd = '
- $listen_sock = IO::Socket::INET6->new(
- Listen => 10,
- LocalPort => $listen_port,
- ReuseAddr => 1,
- Domain => AF_INET6,
- Proto => "tcp"
- );
- ';
- eval $cmd;
- die "$@\n" if $@;
-} else {
- $listen_sock = IO::Socket::INET->new(
- Listen => 10,
- LocalAddr => $listen_host,
- LocalPort => $listen_port,
- ReuseAddr => 1,
- Proto => "tcp"
- );
-}
-
-if (! $listen_sock) {
- die "connect_switch: $!\n";
-}
-
-my $current_fh1 = '';
-my $current_fh2 = '';
-
-my $conn = 0;
-
-while (1) {
- $conn++;
- if ($cmax > 0 && $conn > $cmax) {
- print STDERR "last connection ($cmax)\n" if $verbose;
- last;
- }
- print STDERR "listening for connection: $conn\n" if $verbose;
- my ($client, $ip) = $listen_sock->accept();
- if (! $client) {
- fsleep(0.5);
- next;
- }
- print STDERR "conn: $conn -- ", $client->peerhost(), " at ", scalar(localtime), "\n" if $verbose;
-
- my $pid = fork();
- if (! defined $pid) {
- die "connect_switch: $!\n";
- } elsif ($pid) {
- wait;
- next;
- } else {
- close $listen_sock;
- if (fork) {
- exit 0;
- }
- setpgrp(0, 0);
- handle_conn($client);
- }
-}
-
-exit 0;
-
-sub handle_conn {
- my $client = shift;
-
- my $start = time();
-
- my @allow = @allowed;
-
- # read allow file. Note we read it for every connection
- # to allow the admin to modify it w/o restarting us.
- # better way would be to read in parent and check mtime.
- #
- if ($allow_file && -f $allow_file) {
- if (open(ALLOW, "<$allow_file")) {
- while (<ALLOW>) {
- next if /^\s*#/;
- next if /^\s*$/;
- chomp;
- my ($host, $dpy) = split(' ', $_);
- next if ! defined $host;
- next if ! defined $dpy;
- if ($dpy < 0) {
- $dpy = -$dpy;
- } elsif ($apply_vnc_offset) {
- $dpy += $vnc_offset if $dpy < 200;
- }
- push @allow, "$host:$dpy";
- }
- close(ALLOW);
- } else {
- warn "$allow_file: $!\n";
- }
- }
-
- # Read the first 7 bytes of connection, see if it is 'CONNECT'
- #
- my $str = '';
- my $N = 0;
- my $isconn = 1;
- for (my $i = 0; $i < 7; $i++) {
- my $b;
- sysread($client, $b, 1);
- $str .= $b;
- $N++;
- print STDERR "read: '$str'\n" if $verbose > 1;
- my $cstr = substr('CONNECT', 0, $i+1);
- if ($str ne $cstr) {
- $isconn = 0;
- last;
- }
- }
-
- my $sock = '';
-
- if ($isconn) {
- # it is CONNECT, read rest of HTTP header:
- #
- while ($str !~ /\r\n\r\n/) {
- my $b;
- sysread($client, $b, 1);
- $str .= $b;
- }
- print STDERR "read: $str\n" if $verbose > 1;
-
- # get http version and host:port
- #
- my $ok = 0;
- my $hostport = '';
- my $http_vers = '1.0';
- if ($str =~ /^CONNECT\s+(\S+)\s+HTTP\/(\S+)/) {
- $hostport = $1;
- $http_vers = $2;
- my $h = '';
- my $p = '';
-
- if ($hostport =~ /^(.*):(\d+)$/) {
- ($h, $p) = ($1, $2);
- }
- if ($p =~ /^\d+$/) {
- # check allowed host list:
- foreach my $hp (@allow) {
- if ($hp eq 'ALL') {
- $ok = 1;
- }
- if ($hp eq $hostport) {
- $ok = 1;
- }
- if ($hp =~ /^(.*):(\d+)-(\d+)$/) {
- my $ahost = $1;
- my $pmin = $2;
- my $pmax = $3;
- if ($h eq $ahost) {
- if ($p >= $pmin && $p <= $pmax) {
- $ok = 1;
- }
- }
- }
- last if $ok;
- }
- }
- }
-
- my $msg_1 = "HTTP/$http_vers 200 Connection Established\r\n"
- . "Proxy-agent: connect_switch v0.2\r\n\r\n";
- my $msg_2 = "HTTP/$http_vers 502 Bad Gateway\r\n"
- . "Connection: close\r\n\r\n";
-
- if (! $ok) {
- # disallowed. drop with message.
- #
- syswrite($client, $msg_2, length($msg_2));
- close $client;
- exit 0;
- }
-
- my $host = '';
- my $port = '';
-
- if ($hostport =~ /^(.*):(\d+)$/) {
- ($host, $port) = ($1, $2);
- }
-
- print STDERR "connecting to: $host:$port\n" if $verbose;
-
- $sock = IO::Socket::INET->new(
- PeerAddr => $host,
- PeerPort => $port,
- Proto => "tcp"
- );
- print STDERR "connect to host='$host' port='$port' failed: $!\n" if !$sock;
- if (! $sock && $have_inet6) {
- eval {$sock = IO::Socket::INET6->new(
- PeerAddr => $host,
- PeerPort => $port,
- Proto => "tcp"
- );};
- print STDERR "connect to host='$host' port='$port' failed: $! (ipv6)\n" if !$sock;
- }
- my $msg;
-
- # send the connect proxy reply:
- #
- if ($sock) {
- $msg = $msg_1;
- } else {
- $msg = $msg_2;
- }
- syswrite($client, $msg, length($msg));
- $str = '';
- } else {
- # otherwise, redirect to apache for normal https:
- #
- print STDERR "connecting to: $httpd_host:$httpd_port\n" if $verbose;
- $sock = IO::Socket::INET->new(
- PeerAddr => $httpd_host,
- PeerPort => $httpd_port,
- Proto => "tcp"
- );
- if (! $sock && $have_inet6) {
- eval {$sock = IO::Socket::INET6->new(
- PeerAddr => $httpd_host,
- PeerPort => $httpd_port,
- Proto => "tcp"
- );};
- }
- }
-
- if (! $sock) {
- close $client;
- die "connect_switch: $!\n";
- }
-
- # get ready for xfer phase:
- #
- $current_fh1 = $client;
- $current_fh2 = $sock;
-
- $SIG{TERM} = sub {print STDERR "got sigterm\[$$]\n" if $verbose; close $current_fh1; close $current_fh2; exit 0};
-
- my $parent = $$;
- if (my $child = fork()) {
- xfer($sock, $client, 'S->C');
- if ($killpid) {
- fsleep(0.5);
- kill 'TERM', $child;
- }
- } else {
- # write those first bytes if not CONNECT:
- #
- if ($str ne '' && $N > 0) {
- syswrite($sock, $str, $N);
- }
- xfer($client, $sock, 'C->S');
- if ($killpid) {
- fsleep(0.75);
- kill 'TERM', $parent;
- }
- }
- if ($verbose > 1) {
- my $dt = time() - $start;
- print STDERR "duration\[$$]: $dt seconds. ", scalar(localtime), "\n";
- }
- exit 0;
-}
-
-sub xfer {
- my($in, $out, $lab) = @_;
- my ($RIN, $WIN, $EIN, $ROUT);
- $RIN = $WIN = $EIN = "";
- $ROUT = "";
- vec($RIN, fileno($in), 1) = 1;
- vec($WIN, fileno($in), 1) = 1;
- $EIN = $RIN | $WIN;
- my $buf;
-
- while (1) {
- my $nf = 0;
- while (! $nf) {
- $nf = select($ROUT=$RIN, undef, undef, undef);
- }
- my $len = sysread($in, $buf, $bufsize);
- if (! defined($len)) {
- next if $! =~ /^Interrupted/;
- print STDERR "connect_switch\[$lab/$conn/$$]: $!\n";
- last;
- } elsif ($len == 0) {
- print STDERR "connect_switch\[$lab/$conn/$$]: "
- . "Input is EOF.\n";
- last;
- }
-
- if (0) {
- # very verbose debugging of data:
- syswrite(STDERR , "\n$lab: ", 6);
- syswrite(STDERR , $buf, $len);
- }
-
- my $offset = 0;
- my $quit = 0;
- while ($len) {
- my $written = syswrite($out, $buf, $len, $offset);
- if (! defined $written) {
- print STDERR "connect_switch\[$lab/$conn/$$]: "
- . "Output is EOF. $!\n";
- $quit = 1;
- last;
- }
- $len -= $written;
- $offset += $written;
- }
- last if $quit;
- }
- close($in);
- close($out);
-}
-
-sub fsleep {
- my ($time) = @_;
- select(undef, undef, undef, $time) if $time;
-}
diff --git a/x11vnc/misc/desktop.cgi b/x11vnc/misc/desktop.cgi
deleted file mode 100755
index d99a39c..0000000
--- a/x11vnc/misc/desktop.cgi
+++ /dev/null
@@ -1,1550 +0,0 @@
-#!/usr/bin/perl
-#
-##########################################################################
-# desktop.cgi:
-#
-# This is an example CGI script to provide multi-user web access to
-# x11vnc desktops. The user desktop sessions run in 'Xvfb' displays
-# that are created automatically.
-#
-# This script should/must be served by an HTTPS (i.e. SSL) webserver,
-# otherwise the unix and vnc passwords would be sent over the network
-# unencrypted (see below to disable if you really want to.)
-#
-# The Java VNC Viewer applet connections are encrypted by SSL as well.
-#
-# You can use this script to provide unix users desktops available on
-# demand via any Java enabled web browser. One could also use this for
-# a special-purpose 'single application' service running in a minimal
-# window manager.
-#
-# One example of a special-purpose application would be a scientific
-# data visualization tool running on a server where the data is housed.
-# To do this set $x11vnc_extra_opts = '-env FD_PROG=/path/to/app/launcher'
-# where the program launches your special purpose application. A very
-# simple example: '-env FD_PROG=/usr/bin/xclock'
-#
-#
-# Depending on where you place this script, the user accesses the service
-# with the URL:
-#
-# https://your.webserver.net/cgi-bin/desktop.cgi
-#
-# Then they login with their unix username and password to get their
-# own desktop session.
-#
-# If the user has an existing desktop it is connected to directly,
-# otherwise a new session is created inside an Xvfb display and then
-# connected to by VNC.
-#
-# It is possible to do port redirection to other machines running SSL
-# enabled VNC servers (see below.) This script does not start the VNC
-# servers on the other machines, although with some extra rigging you
-# should be able to do that as well.
-#
-# You can customize the login procedure to whatever you want by modifying
-# this script, or by using ideas in this script write your own PHP,
-# (for example), script.
-#
-##########################################################################
-# Overriding default settings:
-#
-# If you want to override any settings in this script and do not
-# want to edit this script create the assignments in a file named
-# 'desktop.cgi.conf' in the same directory as desktop.cgi. It will be
-# sourced after the defaults are set. The format of desktop.cgi.conf
-# is simply perl statements that make the assignments.
-#
-# For example, if you put something like this in desktop.cgi.conf:
-#
-# $x11vnc = '/usr/local/bin/x11vnc';
-#
-# that will set the path to the x11vnc binary to that location. Look at
-# the settings below for the other variables that you can modify, for
-# example one could set $allowed_users_file.
-#
-##########################################################################
-# x11vnc:
-#
-# You need to install x11vnc or otherwise have it available. It is
-# REQUIRED that you use x11vnc 0.9.10 or later. It won't work with
-# earlier versions. See below the $x11vnc parameter that you can set
-# to the full path to x11vnc.
-#
-##########################################################################
-# Xvfb:
-#
-# Note that the x11vnc -create virtual desktop service used below requires
-# that you install the 'Xvfb' program. On debian this is currently done
-# via 'apt-get install xvfb'.
-#
-# If you are having trouble getting 'x11vnc -create' to work with this
-# script (it can be tricky), try it manually and/or see the x11vnc FAQ
-# links below.
-#
-##########################################################################
-# Apache httpd:
-#
-# You should put this script in, say, a cgi-bin directory. Enable cgi
-# scripts in your apache (or other httpd) config. For example, we have
-# these lines (not commented):
-#
-# In httpd.conf:
-#
-# ScriptAlias /cgi-bin/ "/dist/apache/2.0/cgi-bin/"
-#
-# <Directory "/dist/apache/2.0/cgi-bin">
-# AllowOverride None
-# Options None
-# Order allow,deny
-# Allow from all
-# </Directory>
-#
-# and in ssl.conf:
-#
-# <Directory "/dist/apache/2.0/cgi-bin">
-# SSLOptions +StdEnvVars
-# </Directory>
-#
-# Do not be confused by the non-standard /dist/apache/2.0 apache
-# installation location that we happen to use. Yours will be different.
-#
-# You can test that you have CGI scripts working properly with the
-# 'test-cgi' and 'printenv' scripts apache provides.
-#
-# Copy this file (desktop.cgi) to /dist/apache/2.0/cgi-bin and then run
-# 'chmod 755 ...' on it to make it executable.
-#
-##########################################################################
-# Applet Jar files served by apache:
-#
-# You will *also* need to copy the x11vnc classes/ssl/UltraViewerSSL.jar
-# file to the httpd DocumentRoot to be accessible by: /UltraViewerSSL.jar
-# in a URL (or change $applet_jar below or the html in $applet_html if
-# you want to use a different location.)
-#
-# This location is relative to the apache DocumentRoot 'htdocs' directory.
-# For our (non-standard location installation) that meant we copied the
-# file to:
-#
-# /dist/apache/2.0/htdocs/UltraViewerSSL.jar
-#
-# (your DocumentRoot directory will be different.)
-#
-# The VncViewer.jar (tightvnc) will also work, but you need to change
-# the $applet_jar below. You can get these jar files from the x11vnc
-# tarball from:
-#
-# http://www.karlrunge.com/x11vnc/#downloading
-#
-# This script requires x11vnc 0.9.10 or later.
-#
-# Note that the usage mode for this script is a different from regular
-# 'x11vnc -http ...' usage where x11vnc acts as a mini web server and
-# serves its own applet jars. We don't use that mode for this script.
-# Apache (httpd) serves the jars.
-#
-#
-##########################################################################
-# Notes and Information:
-#
-# Each x11vnc server created for a user login will listen on its own port
-# (see below for port selection schemes.) Your firewall must let in *ALL*
-# of these ports (e.g. a port range, see below for the syntax.)
-#
-# It is also possible, although not as reliable, to do all of this through
-# a single port, see the fixed port scheme $find_free_port = 'fixed:5910'
-# below. This single port mode must be different from apache's port
-# (usually 443 for https) and must also be allowed in by your firewall.
-#
-# Note: The fixed port scheme is DISABLED by default.
-#
-# It is also possible to have this script act as a vnc redirector to SSL
-# enabled VNC servers running on *other* machines inside your firewall
-# (presumably the users' desktops) See the $enable_port_redirection
-# setting below. The user provides 'username@host:port' instead of just
-# 'username' when she logs in. This script doesn't start VNC servers
-# on those other machines, the servers must be running there already.
-# (If you want this script to start them you will need to add it
-# yourself.) It is possible to provide a host:port allow list to limit
-# which internal machines and ports can be redirected to. This is the
-# $port_redirection_allowed_hosts parameter.
-#
-# Note: The vnc redirector scheme is DISABLED by default.
-#
-# Note there are *two* SSL certificates involved that the user may be
-# asked to inspect: apache's SSL cert and x11vnc's SSL cert. This may
-# confuse naive users. You may want to use the same cert for both.
-#
-# This script provides one example on how to provide the service. You can
-# customize it to meet your needs, e.g. switch to php, newer cgi modules,
-# different authentication, SQL database for user authentication, etc,
-# etc. If you plan to use it in production, please examine all security
-# aspects of it carefully; read the comments in the script for more info.
-#
-# More information and background and troubleshooting:
-#
-# http://www.karlrunge.com/x11vnc/faq.html#faq-xvfb
-# http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-viewers
-# http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-java-viewer-proxy
-# http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-portal
-# http://www.karlrunge.com/x11vnc/faq.html#faq-unix-passwords
-# http://www.karlrunge.com/x11vnc/faq.html#faq-userlogin
-#
-#
-# Please also read the comments below for changing specific settings.
-# You can modify them in this script or by override file 'desktop.cgi.conf'
-
-
-#-------------------------------------------------------------------------
-# Copyright (c) 2010 by Karl J. Runge <runge@karlrunge.com>
-#
-# desktop.cgi is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# desktop.cgi is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with desktop.cgi; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-# or see <http://www.gnu.org/licenses/>.
-#-------------------------------------------------------------------------
-
-use strict;
-use IO::Socket::INET;
-
-# Test for INET6 support:
-#
-my $have_inet6 = 0;
-eval "use IO::Socket::INET6;";
-$have_inet6 = 1 if $@ eq "";
-
-##########################################################################
-# Path to the x11vnc program:
-#
-my $x11vnc = '/usr/bin/x11vnc';
-
-
-##########################################################################
-# You can set some extra x11vnc cmdline options here:
-#
-my $x11vnc_extra_opts = '';
-
-
-##########################################################################
-# Override the default x11vnc viewer connection timeout of 75 seconds:
-#
-my $x11vnc_timeout = '';
-
-
-##########################################################################
-# TCP Ports:
-#
-# Set find_free_port to 1 (or the other modes described below) to
-# autoselect a free port to use. The default is to use a port based on
-# the userid number (7000 + uid).
-#
-my $find_free_port = 0;
-
-# Or specify a port range:
-#
-#$find_free_port = '7000-8000';
-#
-# Or indicate to use a kludge to try to do everything through a SINGLE
-# port. To try to avoid contention on the port, simultaneous instances
-# of this script attempt to 'take turns' using it the single port.
-#
-#$find_free_port = 'fixed:5910';
-
-# This is the starting port for 7000 + uid and also $find_free_port = 1
-# autoselection:
-#
-my $starting_port = 7000;
-
-# Listen on AF_INET6 if IO::Socket::INET6 is available.
-#
-my $listen_on_ipv6 = 0;
-
-
-##########################################################################
-# Port redirection mode:
-#
-# This is to enable port redirection mode: username@host:port. If
-# username is valid, there will be a port redirection to internal machine
-# host:port. Presumably there is already an SSL enabled and password
-# protected VNC server running there. We don't start that VNC server.
-# (You might be able to figure out a way to do this yourself.)
-#
-# See the next setting for an allowed hosts file. The default for port
-# redirection is off.
-#
-my $enable_port_redirection = 0;
-
-# A file with allowed port redirections. The empty string '' (the
-# default) means all host:port redirections would be allowed.
-#
-# Format of the file: A list of 'user@host:port' or 'host:port'
-# entries, one per line. Port ranges, e.g. host:n-m are also accepted.
-#
-# Leading and trailing whitespace is trimmed off each line. Blank lines
-# and comment lines starting with '#' are skipped. A line consisting of
-# 'ALL' matches everything. If no match can be found or the file cannot
-# be opened the connection is dropped.
-#
-my $port_redirection_allowed_hosts = '';
-
-
-##########################################################################
-# Allowed users:
-#
-# To limit which users can use this service, set the following to a file
-# that contains the allowed user names one per line. Lines starting with
-# the '#' character are skipped.
-#
-my $allowed_users_file = '';
-
-
-##########################################################################
-# Denied users:
-#
-# As with $allowed_users_file, but to deny certain users. Applied after
-# any $allowed_users_file check and overrides the result.
-#
-my $denied_users_file = '';
-
-
-##########################################################################
-# trustUrlVncCert applet parameter:
-#
-# Set to 0 to have the java applet html set the parameter
-# trustUrlVncCert=no, i.e. the applet will not automatically accept
-# an SSL cert already accepted by an HTTPS URL. See $applet_html and
-# print_applet_html() below for more info.
-#
-my $trustUrlVncCert = 1;
-
-
-##########################################################################
-# One-time VNC password fifo:
-#
-# For extra security against local untrusted users a fifo is used
-# to copy the one-time VNC password to the user's VNC password file
-# ~user/x11vnc.pw. If that fifo transfer technique causes problems,
-# you can set this value to 1 to disable the security feature:
-#
-my $disable_vnc_passwd_fifo_safety = 0;
-
-
-##########################################################################
-# Comment this out if you don't want PATH modified:
-#
-$ENV{PATH} = "/usr/bin:/bin:$ENV{PATH}";
-
-
-##########################################################################
-# For the next two settings, note that most users will be confused that
-# geometry and session are ignored when they are returning to their
-# existing desktop session (x11vnc FINDDISPLAY action.)
-
-
-##########################################################################
-# Used below if user did not specify preferred geometry and color depth:
-#
-my $default_geometry = '1024x768x24';
-
-
-# Set this to the list of x11vnc -create sessions types to show a session
-# dropdown for the user to select from.
-#
-my $session_types = '';
-#
-# example:
-#$session_types = 'gnome kde xfce lxde wmaker enlightenment mwm twm failsafe';
-
-
-##########################################################################
-# Set this to 1 to enable user setting a unique tag for each one
-# of his desktops and so can have multiple ones simultaneously and
-# select which one he wants. For now we just hack this onto geometry
-# 1024x768x24:my_2nd_desktop but ultimately there should be a form entry
-# for it. Search for enable_unique_tags for more info:
-#
-my $enable_unique_tags = 0;
-my $unique_tag = '';
-
-
-##########################################################################
-# String of HTML for the login form:
-#
-# Feel free to customize to your taste, _USERNAME_ and _GEOMETRY_ are
-# expanded to that of the request.
-#
-my $login_str = <<"END";
-<title>x11vnc web access</title>
-<h3>x11vnc web access</h3>
-<form action="$ENV{REQUEST_URI}" method="post">
- <table border="0">
- <tr><td colspan=2><h2>Login</h2></td></tr>
- <tr><td>Username:</td><td>
- <input type="text" name="username" maxlength="40" value="_USERNAME_">
- </td></tr>
- <tr><td>Password:</td><td>
- <input type="password" name="password" maxlength="50">
- </td></tr>
- <tr><td>Geometry:</td><td>
- <input type="text" name="geometry" maxlength="40" value="_GEOMETRY_">
- </td></tr>
- <!-- session -->
- <tr><td colspan="2" align="right">
- <input type="submit" name="submit" value="Login">
- </td></tr>
- </table>
-</form>
-END
-
-
-##########################################################################
-# String of HTML returned to web browser to launch applet:
-#
-# Feel free to customize to your taste, _UID_, _VNC_PORT_, _WIDTH_,
-# _HEIGHT_, _PASS_, _TRUST_UVC_, _APPLET_JAR_, and _APPLET_CLASS_ are
-# expanded to the appropriate values before sending out to the browser.
-#
-my $applet_html = <<"END";
-<html>
-<TITLE>
-x11vnc desktop (_UID_/_VNC_PORT_)
-</TITLE>
-<APPLET CODE=_APPLET_CLASS_ ARCHIVE=_APPLET_JAR_ WIDTH=_WIDTH_ HEIGHT=_HEIGHT_>
-<param name=PORT value=_VNC_PORT_>
-<param name=VNCSERVERPORT value=_VNC_PORT_>
-<param name=PASSWORD value=_PASS_>
-<param name=trustUrlVncCert value=_TRUST_UVC_>
-<param name="Open New Window" value=yes>
-<param name="Offer Relogin" value=no>
-<param name="ignoreMSLogonCheck" value=yes>
-<param name="delayAuthPanel" value=yes>
-<!-- extra -->
-</APPLET>
-<br>
-<a href="$ENV{REQUEST_URI}">Login page</a><br>
-<a href=http://www.karlrunge.com/x11vnc>x11vnc website</a>
-</html>
-END
-
-
-##########################################################################
-# These java applet strings are expanded into the above $applet_html.
-# Note that $applet_jar is relative to your apache DocumentRoot (htdocs)
-# not the filesystem root.
-#
-my $applet_jar = '/UltraViewerSSL.jar';
-my $applet_class = 'VncViewer.class';
-
-# These make the applet panel smaller because we use 'Open New Window'
-# anyway (set to 'W' or 'H' to use actual session geometry values):
-#
-my $applet_width = '400';
-my $applet_height = '300';
-
-# To customize ALL of the HTML printed out you may need to redefine
-# the bye() subtroutine in your desktop.cgi.conf file.
-
-
-##########################################################################
-# Override any of the above settings by setting them in a file named
-# 'desktop.cgi.conf'. It is sourced here.
-#
-# You can override any variable set above by supplying perl code
-# in $0.conf that sets it to the desired value.
-#
-# Some examples you could put in $0.conf:
-#
-# $x11vnc = '/usr/local/bin/x11vnc';
-# $x11vnc_extra_opts = '-env FD_PROG=/usr/bin/xclock';
-# $x11vnc_extra_opts = '-ssl /usr/local/etc/dtcgi.pem';
-# $find_free_port = 'fixed:5999';
-# $enable_port_redirection = 1;
-# $allowed_users_file = '/usr/local/etc/dtcgi.allowed';
-#
-if (-f "$0.conf") {
- eval `cat "$0.conf"`;
-}
-
-
-##########################################################################
-# END OF MAIN USER SETTINGS.
-# Only power users should change anything below.
-##########################################################################
-
-# Print http header reply:
-#
-print STDOUT "Content-Type: text/html\r\n\r\n";
-
-
-# Require HTTPS so that unix and vnc passwords are not sent in clear text
-# (perhaps it is too late...) Disable HTTPS here at your own risk.
-#
-if ($ENV{HTTPS} !~ /^on$/i) {
- bye("HTTPS must be used (to encrypt passwords)");
-}
-
-
-# Read URL request:
-#
-my $request;
-if ($ENV{'REQUEST_METHOD'} eq "POST") {
- read(STDIN, $request, $ENV{'CONTENT_LENGTH'});
-} elsif ($ENV{'REQUEST_METHOD'} eq "GET" ) {
- $request = $ENV{'QUERY_STRING'};
-} else {
- $request = $ARGV[0];
-}
-
-my %request = url_decode(split(/[&=]/, $request));
-
-
-# Experiment for FD_TAG x11vnc feature for multiple desktops for a
-# single user:
-#
-# we hide it in geometry:tag for now:
-#
-if ($enable_unique_tags && $request{geometry} =~ /^(.*):(\w+)$/) {
- $request{geometry} = $1;
- $unique_tag = $2;
-}
-
-# Check/set geometry and session:
-#
-if (!exists $request{geometry} || $request{geometry} !~ /^[x\d]+$/) {
- # default geometry and depth:
- $request{geometry} = $default_geometry;
-}
-if (!exists $request{session} || $request{session} =~ /^\s*$/) {
- $request{session} = '';
-}
-
-
-# Expand _USERNAME_ and _GEOMETRY_ in the login string HTML:
-#
-$login_str =~ s/_USERNAME_/$request{username}/g;
-$login_str =~ s/_GEOMETRY_/$request{geometry}/g;
-
-
-# Check x11vnc version for installers of this script who do not know
-# how to read and follow instructions:
-#
-my $version = (split(' ', `$x11vnc -version`))[1];
-$version =~ s/\D*$//;
-
-my ($major, $minor, $micro) = split(/\./, $version);
-if ($major !~ /^\d+$/ || $minor !~ /^\d+$/) {
- bye("The x11vnc program is not installed correctly.");
-}
-$micro = 0 unless $micro;
-my $level = $major * 100 * 100 + $minor * 100 + $micro;
-my $needed = 0 * 100 * 100 + 9 * 100 + 10;
-if ($level < $needed) {
- bye("x11vnc version 0.9.10 or later is required. (Found version $version)");
-}
-
-
-# Set up user selected desktop session list, if enabled:
-#
-my %sessions;
-
-if ($session_types ne '') {
- my $str = "<tr><td>Session:</td><td>\n<select name=session>";
- $str .= "<option value=none>select</option>";
-
- foreach my $sess (split(' ', $session_types)) {
- next if $sess =~ /^\s*$/;
- next if $sess !~ /^\w+$/; # alphanumeric
- $sessions{$sess} = 1;
- $str .= "<option value=$sess>$sess</option>";
- }
- $str .= "</select>\n</td></tr>";
-
- # This forces $request{session} to be a valid one:
- #
- if (! exists $sessions{$request{session}}) {
- $request{session} = 'none';
- }
-
- # Insert into login_str:
- #
- my $r = $request{session};
- $str =~ s/option value=\Q$r\E/option selected value=$r/;
- $login_str =~ s/<!-- session -->/$str/;
-}
-
-
-# If no username or password, show login form:
-#
-if (!$request{username} && !$request{password}) {
- bye($login_str);
-} elsif (!$request{username}) {
- bye("No Username.<p>$login_str");
-} elsif (!$request{password}) {
- bye("No Password.<p>$login_str");
-}
-
-
-# Some shorthand names:
-#
-my $username = $request{username};
-my $password = $request{password};
-my $geometry = $request{geometry};
-my $session = $request{session};
-
-
-# If port redirection is enabled, split username@host:port
-#
-my $redirect_host = '';
-my $current_fh1 = '';
-my $current_fh2 = '';
-
-if ($enable_port_redirection) {
- ($username, $redirect_host) = split(/@/, $username, 2);
- if ($redirect_host ne '') {
- # will exit if the redirection is not allowed:
- check_redirect_host();
- }
-}
-
-# If there is an $allowed_users_file, check username against it:
-#
-if ($allowed_users_file ne '') {
- if (! open(USERS, "<$allowed_users_file")) {
- bye("Internal Error #0");
- }
- my $ok = 0;
- while (<USERS>) {
- chomp;
- $_ =~ s/^\s*//;
- $_ =~ s/\s*$//;
- next if /^#/;
- if ($username eq $_) {
- $ok = 1;
- }
- }
- close USERS;
- if (! $ok) {
- bye("Denied Username.<p>$login_str");
- }
-}
-
-# If there is a $denied_users_file, check username against it:
-#
-if ($denied_users_file ne '') {
- if (! open(USERS, "<$denied_users_file")) {
- bye("Internal Error #0");
- }
- my $ok = 1;
- while (<USERS>) {
- chomp;
- $_ =~ s/^\s*//;
- $_ =~ s/\s*$//;
- next if /^#/;
- if ($username eq $_) {
- $ok = 0;
- }
- }
- close USERS;
- if (! $ok) {
- bye("Denied Username.<p>$login_str");
- }
-}
-
-# Require username to be alphanumeric + '-' + '_':
-# (one may want to add '.' as well)
-#
-if ($username !~ /^\w[-\w]*$/) {
- bye("Invalid Username.<p>$login_str");
-}
-
-
-# Get the userid number, we may use it as his VNC display port; this
-# also checks if the username exists:
-#
-my $uid = `/usr/bin/id -u '$username'`;
-chomp $uid;
-if ($? != 0 || $uid !~ /^\d+$/) {
- bye("Invalid Username.<p>$login_str");
-}
-
-
-# Use x11vnc trick to check if the unix password is valid:
-# (requires x11vnc 0.9.10 or later.)
-#
-if (!open(X11VNC, "| $x11vnc -unixpw \%stdin > /dev/null")) {
- bye("Internal Error #1");
-}
-print X11VNC "$username:$password\n";
-
-if (!close X11VNC) {
- # x11vnc returns non-zero for invalid username+password:
- bye("Invalid Password.<p>$login_str");
-}
-
-
-# Initialize random number generator for use below:
-#
-initialize_random();
-
-
-# Set vnc port:
-#
-my $vnc_port = 0;
-my $fixed_port = 0;
-
-if (! $find_free_port) {
- # Fixed port based on userid (we assume it is free):
- #
- $vnc_port = $starting_port + $uid;
-
-} elsif ($find_free_port =~ /^fixed:(\d+)$/) {
- #
- # Enable the -loopbg method that tries to share a single port:
- #
- $vnc_port = $1;
- $fixed_port = 1;
-} else {
- # Autoselect a port, either default range (7000-8000) or a user
- # supplied range. (note that $find_free_port will now contain
- # a socket listening on the found port so that it is held.)
- #
- $vnc_port = auto_select_port();
-}
-
-# Check for crazy port value:
-#
-if ($vnc_port > 64000 || $vnc_port < 1) {
- bye("Internal Error #2 $vnc_port");
-}
-
-
-# If port redirection is enabled and the user selected it via
-# username@host:port, we do that right now and then exit.
-#
-if ($enable_port_redirection && $redirect_host ne '') {
- port_redir();
- exit 0;
-}
-
-
-# Make a random, onetime vnc password:
-#
-my $pass = '';
-my $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-my @abc = split(//, $chars);
-
-for (my $i = 0; $i < 8; $i++) {
- $pass .= $abc[ rand(scalar(@abc)) ];
-}
-
-# Use x11vnc trick to switch to user and store vnc pass in the passwdfile.
-# Result is $pass is placed in user's $HOME/x11vnc.pw
-#
-# (This is actually difficult to do without untrusted LOCAL users being
-# able to see the pass as well, see copy_password_to_user() for details
-# on how we try to avoid this.)
-#
-copy_password_to_user($pass);
-
-
-# Make a tmp file for x11vnc launcher script:
-#
-my $tmpfile = `/bin/mktemp /tmp/desktop.cgi.XXXXXX`;
-chomp $tmpfile;
-
-# Check if the tmpfile is valid:
-#
-if (! -e $tmpfile || ! -o $tmpfile || -l $tmpfile) {
- unlink $tmpfile;
- bye("Internal Error #3");
-}
-if (!chmod 0644, $tmpfile) {
- unlink $tmpfile;
- bye("Internal Error #4");
-}
-if (!open(TMP, ">$tmpfile")) {
- unlink $tmpfile;
- bye("Internal Error #5");
-}
-
-
-# The x11vnc command. You adjust it to suit your needs.
-#
-# some ideas: -env FD_PROG=/usr/bin/gnome-session
-# -env FD_SESS=kde
-# -env FD_TAG=my_2nd_desktop
-# -ultrafilexfer
-#
-# Note that -timeout will cause it to exit if client does not connect
-# and -sslonly disables VeNCrypt SSL connections.
-
-# Some settings:
-# (change these if you encounter timing problems, etc.)
-#
-my $timeout = 75;
-my $extra = '';
-if ($fixed_port) {
- # settings for fixed port case:
- $timeout = 45;
- $extra .= " -loopbg100,1";
-}
-$timeout = $x11vnc_timeout if $x11vnc_timeout ne '';
-
-if ($session_types ne '') {
- # settings for session selection case:
- if (exists $sessions{$session}) {
- $extra .= " -env FD_SESS='$session'";
- }
-}
-if ($enable_unique_tags && $unique_tag ne '' && $unique_tag =~ /^\w+$/) {
- $extra .= " -env FD_TAG='$unique_tag'";
-}
-
-# This md5sum check of the vnc passwd is for extra safety (see
-# copy_password_to_user for details.)
-#
-my $md5sum = '';
-system("type md5sum > /dev/null");
-if ($? == 0) {
- my $md5 = `/bin/mktemp /tmp/desktop.cgi.XXXXXX`;
- chomp $md5;
- # compute md5sum of password:
- if (-o $md5 && open(MD5, "| md5sum > $md5")) {
- print MD5 "$pass\n";
- close MD5;
- if (open(MD5, "<$md5")) {
- # read it:
- my $line = <MD5>;
- close MD5;
- my ($s, $t) = split(' ', $line);
- if (length($s) >= 32 && $s =~ /^\w+$/) {
- # shell code for user to check he has correct passwd:
- $md5sum = "if md5sum \$HOME/x11vnc.pw | grep '$s' > /dev/null; then true; else exit 1; fi";
- }
- }
- }
- unlink $md5;
-}
-
-# Write x11vnc command to the tmp file:
-#
-print TMP <<"END";
-#!/bin/sh
-export PATH=/usr/bin:/bin:\$PATH
-$md5sum
-$x11vnc -sigpipe ignore:HUP -nopw -rfbport $vnc_port \\
- -passwdfile \$HOME/x11vnc.pw -oa \$HOME/x11vnc.log \\
- -create -ssl SAVE -sslonly -env FD_GEOM=$geometry \\
- -timeout $timeout $extra $x11vnc_extra_opts \\
- >/dev/null 2>/dev/null </dev/null &
-sleep 2
-exit 0
-END
-
-close TMP;
-
-# Now launch x11vnc to switch to user and run the wrapper script:
-# (this requires x11vnc 0.9.10 or later.)
-#
-$ENV{UNIXPW_CMD} = "/bin/sh $tmpfile";
-
-# For the fixed port scheme we try to cooperate via lock file:
-# (disabled by default.)
-#
-my $rmlock = '';
-#
-if ($fixed_port) {
- # try to grab the fixed port for the next 90 secs removing stale
- # locks older than 60 secs:
- #
- $rmlock = lock_fixed_port(90, 60);
-}
-
-# Start the x11vnc cmd:
-#
-if (!open(X11VNC, "| $x11vnc -unixpw \%stdin > /dev/null")) {
- unlink $tmpfile;
- unlink $rmlock if $rmlock;
- bye("Internal Error #6");
-}
-
-select(X11VNC); $| = 1; select(STDOUT);
-
-# Close any port we held. There is still a gap of time between now
-# and when when x11vnc in $tmpfile reopens the port after the password
-# authentication. So another instance of this script could accidentally
-# think it is free...
-#
-sleep 1;
-close $find_free_port if $find_free_port;
-
-print X11VNC "$username:$password\n";
-close X11VNC; # note we ignore return value.
-unlink $tmpfile;
-
-if ($rmlock) {
- # let our x11vnc proceed a bit before removing lock.
- sleep 2;
- unlink $rmlock;
-}
-
-# Return html for the java applet to connect to x11vnc.
-#
-print_applet_html();
-
-exit 0;
-
-#################################################################
-# Subroutines:
-
-# print the message to client and exit with success.
-#
-sub bye {
- my $msg = shift;
- print STDOUT "<html>$msg</html>\n";
- exit 0;
-}
-
-# decode %xx to character:
-#
-sub url_decode {
- foreach (@_) {
- tr/+/ /;
- s/%(..)/pack("c",hex($1))/ge;
- }
- @_;
-}
-
-# seed random
-#
-sub initialize_random {
- my $rbytes = '';
- if (open(RAN, "</dev/urandom")) {
- read(RAN, $rbytes, 8);
- } elsif (open(RAN, "</dev/random")) {
- read(RAN, $rbytes, 8);
- } else {
- $rbytes = sprintf("%08d", $$);
- }
- close RAN;
-
- # set seed:
- #
- my $seed = join('', unpack("C8", $rbytes));
- $seed = substr($seed, -9);
- srand($seed);
-
- for (my $i = 0; $i < ($$ % 4096); $i++) {
- # Mix it up even a little bit more. There should be
- # over 1 billion possible vnc passwords now.
- rand();
- }
-}
-
-# Autoselect a port for vnc. Note that a socket for the found port
-# is kept open (and stored in $find_free_port) until we call x11vnc at
-# the end.
-#
-sub auto_select_port {
- my $pmin = $starting_port; # default range 7000-8000.
- my $pmax = $starting_port + 1000;
-
- if ($find_free_port =~ /^(\d+)-(\d+)$/) {
- # user supplied a range:
- $pmin = $1;
- $pmax = $2;
- if ($pmin > $pmax) {
- ($pmin, $pmax) = ($pmax, $pmin);
- }
- } elsif ($find_free_port > 1024) {
- # user supplied a starting port:
- $pmin = $find_free_port;
- $pmax = $pmin + 1000;
- }
-
- # Try to add a bit of randomness to the starting port so
- # simultaneous instances of this script won't be fooled by the gap
- # of time before x11vnc reopens the port (see near the bottom.)
- #
- my $dp = int(rand(1.0) * 0.25 * ($pmax - $pmin));
- if ($pmin + $dp < $pmax - 20) {
- $pmin = $pmin + $dp;
- }
-
- my $port = 0;
-
- # Now try to find a free one:
- #
- for (my $p = $pmin; $p <= $pmax; $p++) {
- my $sock = '';
- if ($have_inet6 && $listen_on_ipv6) {
- eval {$sock = IO::Socket::INET6->new(
- Listen => 1,
- LocalPort => $p,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => "::",
- Proto => "tcp"
- );};
- } else {
- $sock = IO::Socket::INET->new(
- Listen => 1,
- LocalPort => $p,
- ReuseAddr => 1,
- Proto => "tcp"
- );
- }
- if ($sock) {
- # we will keep this open until we call x11vnc:
- $find_free_port = $sock;
- $port = $p;
- last;
- }
- }
- return $port;
-}
-
-# Since apache typically runs as user 'apache', 'nobody', etc, and not
-# as root it is tricky for us to copy the pass string to a file owned by
-# the user without some other untrusted local user being able to learn
-# the password (e.g. via reading a file or watching ps.) Note that with
-# the x11vnc -unixpw trick we unfortunately can't use a pipe because
-# the user command is run in its own tty.
-#
-# The best way would be a sudo action or a special setuid program for
-# copying. So consider doing that and thereby simplify this function.
-#
-# Short of a special program doing this, we use a fifo so ONLY ONE
-# process can read the password. If the untrusted local user reads it,
-# then the logging-in user's x11vnc won't get it. The login and x11vnc
-# will fail, but the untrusted user won't gain access to the logging-in
-# user's desktop.
-#
-# So here we start long, tedious work carefully managing the fifo.
-#
-sub copy_password_to_user {
-
- my $pass = shift;
-
- my $use_fifo = '';
-
- # Find a command to make a fifo:
- #
- system("type mkfifo > /dev/null");
- if ($? == 0) {
- $use_fifo = 'mkfifo %s';
- } else {
- system("type mknod > /dev/null");
- if ($? == 0) {
- $use_fifo = 'mknod %s p';
- }
- }
-
- # Create the filename for our fifo:
- #
- my $fifo = `/bin/mktemp /tmp/desktop.cgi.XXXXXX`;
- chomp $fifo;
-
- if (! -e $fifo || ! -o $fifo || -l $fifo) {
- unlink $fifo;
- bye("Internal Error #7");
- }
-
- # disable fifo safety if requested:
- #
- if ($disable_vnc_passwd_fifo_safety) {
- $use_fifo = '';
- }
-
- # Make the fifo:
- #
- if ($use_fifo) {
- $use_fifo = sprintf($use_fifo, $fifo);
-
- # there is a small race here:
- system("umask 077; rm -f $fifo; $use_fifo; chmod 600 $fifo");
-
- if (!chmod 0600, $fifo) {
- # we chmod once more..
- unlink $fifo;
- bye("Internal Error #8");
- }
-
- if (! -o $fifo || ! -p $fifo || -l $fifo) {
- # but we get out if not owned by us anymore:
- unlink $fifo;
- bye("Internal Error #9");
- }
- }
-
- # Build cmd for user to read our fifo:
- #
- my $upw = '$HOME/x11vnc.pw';
- $ENV{UNIXPW_CMD} = "touch $upw; chmod 600 $upw; cat $fifo > $upw";
-
- # Start it:
- #
- if (!open(X11VNC, "| $x11vnc -unixpw \%stdin > /dev/null")) {
- unlink $fifo;
- bye("Internal Error #10");
- }
- select(X11VNC); $| = 1; select(STDOUT);
-
- if (! $use_fifo) {
- # regular file, we need to write it now.
- if (!open(FIFO, ">$fifo")) {
- close X11VNC;
- unlink $fifo;
- bye("Internal Error #11");
- }
- print FIFO "$pass\n";
- close FIFO;
- }
-
- # open fifo up for reading.
- # (this means the bad guy can read it too.)
- #
- if (!chmod 0644, $fifo) {
- unlink $fifo;
- bye("Internal Error #12");
- }
-
- # send the user's passwd now:
- #
- print X11VNC "$username:$password\n";
-
- if ($use_fifo) {
- # wait a bit for the cat $fifo to start, reader will block.
- sleep 1;
- if (!open(FIFO, ">$fifo")) {
- close X11VNC;
- unlink $fifo;
- bye("Internal Error #13");
- }
- # here it goes:
- print FIFO "$pass\n";
- close FIFO;
- }
- close X11VNC; # note we ignore return value.
- fsleep(0.5);
- unlink $fifo;
-
- # Done!
-}
-
-# For fixed, single port mode. Try to open and lock the port before
-# proceeding.
-#
-sub lock_fixed_port {
- my ($t_max, $t_age) = @_;
-
- # lock file name:
- #
- my $lock = '/tmp/desktop.cgi.lock';
- my $remove = '';
-
- my $t = 0;
- my $sock = '';
-
- while ($t < $t_max) {
- if (-e $lock) {
- # clean out stale locks if possible:
- if (! -l $lock) {
- unlink $lock;
- } else {
- my ($pid, $time) = split(/:/, readlink($lock));
- if (! -d "/proc/$pid") {
- unlink $lock;
- }
- if (time() > $time + $t_age) {
- unlink $lock;
- }
- }
- }
-
- my $reason = '';
-
- if (-l $lock) {
- # someone has locked it.
- $reason = 'locked';
- } else {
- # unlocked, try to listen on port:
- if ($have_inet6 && $listen_on_ipv6) {
- eval {$sock = IO::Socket::INET6->new(
- Listen => 1,
- LocalPort => $vnc_port,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => "::",
- Proto => "tcp"
- );};
- } else {
- $sock = IO::Socket::INET->new(
- Listen => 1,
- LocalPort => $vnc_port,
- ReuseAddr => 1,
- Proto => "tcp"
- );
- }
- if ($sock) {
- # we got it, now try to lock:
- my $str = "$$:" . time();
- if (symlink($str, $lock)) {
- $remove = $lock;
- $find_free_port = $sock;
- last;
- }
- # wow, we didn't lock it...
- $reason = "symlink failed: $!";
- close $sock;
- } else {
- $reason = "listen failed: $!";
- }
- }
- # sleep a bit and then try again:
- #
- print STDERR "$$ failed to get fixed port $vnc_port for $username at $t ($reason)\n";
- $sock = '';
- $t += 5;
- sleep 5;
- }
- if (! $sock) {
- bye("Failed to lock fixed TCP port. Try again a bit later.<p>$login_str");
- }
- print STDERR "$$ got fixed port $vnc_port for $username at $t\n";
-
- # Return the file to remove, if any:
- #
- return $remove;
-}
-
-
-# Return html for the java applet to connect to x11vnc.
-#
-# N.B. Please examine the applet params, e.g. trustUrlVncCert=yes to
-# see if you agree with them. See x11vnc classes/ssl/README for all
-# parameters.
-#
-# Note how we do not take extreme care to authenticate the server to
-# the client applet (but note that trustUrlVncCert=yes is better than
-# trustAllVncCerts=yes) One can tighten all of this up at the expense
-# of extra certificate dialogs (assuming the user bothers to check...)
-#
-# This assumes /UltraViewerSSL.jar is at document root; you need to put
-# it there.
-#
-sub print_applet_html {
- my ($W, $H, $D) = split(/x/, $geometry);
-
- # make it smaller since we 'Open New Window' below anyway.
- if ($applet_width ne 'W') {
- $W = $applet_width;
- }
- if ($applet_height ne 'H') {
- $H = $applet_height;
- }
-
- my $tUVC = ($trustUrlVncCert ? 'yes' : 'no');
-
- # see $applet_html set in defaults section for more info:
- #
- my $str = $applet_html;
-
- $str =~ s/_UID_/$uid/g;
- $str =~ s/_VNC_PORT_/$vnc_port/g;
- $str =~ s/_WIDTH_/$W/g;
- $str =~ s/_HEIGHT_/$H/g;
- $str =~ s/_PASS_/$pass/g;
- $str =~ s/_APPLET_JAR_/$applet_jar/g;
- $str =~ s/_APPLET_CLASS_/$applet_class/g;
- $str =~ s/_TRUST_UVC_/$tUVC/g;
-
- if ($enable_port_redirection && $redirect_host ne '') {
- $str =~ s/name=PASSWORD value=.*>/name=NOT_USED value=yes>/i;
- #$str =~ s/<!-- extra -->/<!-- extra -->\n<param name="ignoreProxy" value=yes>/;
- }
-
- print $str;
-}
-
-##########################################################################
-# The following subroutines are for port redirection only, which is
-# disabled by default ($enable_port_redirection == 0)
-#
-sub port_redir {
- # To aid in avoiding zombies:
- #
- setpgrp(0, 0);
-
- # For the fixed port scheme we try to cooperate via lock file:
- #
- my $rmlock = '';
- #
- if ($fixed_port) {
- # try to grab the fixed port for the next 90 secs removing
- # stale locks older than 60 secs:
- #
- $rmlock = lock_fixed_port(90, 60);
-
- } elsif ($find_free_port eq '0') {
- if ($have_inet6 && $listen_on_ipv6) {
- eval {$find_free_port = IO::Socket::INET6->new(
- Listen => 1,
- LocalPort => $vnc_port,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => "::",
- Proto => "tcp"
- );};
- } else {
- $find_free_port = IO::Socket::INET->new(
- Listen => 1,
- LocalPort => $vnc_port,
- ReuseAddr => 1,
- Proto => "tcp"
- );
- }
- }
- # In all cases, at this point $find_free_port is the listening
- # socket.
-
- # fork a helper process to do the port redir:
- #
- # Actually we need to spawn 4(!) of them in case the proxy check
- # /check.https.proxy.connection (it is by default) and the other
- # test connections. Spawn one for each expected connection, for
- # whatever applet parameter usage mode you set up.
- #
- for (my $n = 1; $n <= 4; $n++) {
- my $pid = fork();
- if (! defined $pid) {
- bye("Internal Error #14");
- } elsif ($pid) {
- wait;
- } else {
- if (fork) {
- exit 0;
- }
- setpgrp(0, 0);
- handle_conn();
- exit 0;
- }
- }
-
- # We now close the listening socket:
- #
- close $find_free_port;
-
- if ($rmlock) {
- # let our process proceed a bit before removing lock.
- sleep 1;
- unlink $rmlock;
- }
-
- # Now send html to the browser so it can connect:
- #
- print_applet_html();
-
- exit 0;
-}
-
-# This checks the validity of a username@host:port for the port
-# redirection mode. Finishes and exits if it is invalid.
-#
-sub check_redirect_host {
- # First check that the host:port string is valid:
- #
- if ($redirect_host !~ /^\w[-\w\.]*:\d+$/) {
- bye("Invalid Redirect Host:Port.<p>$login_str");
- }
- # Second, check if the allowed host file permits it:
- #
- if ($port_redirection_allowed_hosts ne '') {
- if (! open(ALLOWED, "<$port_redirection_allowed_hosts")) {
- bye("Internal Error #15");
- }
- my $ok = 0;
- while (my $line = <ALLOWED>) {
- chomp $line;
- # skip blank lines and '#' comments:
- next if $line =~ /^\s*$/;
- next if $line =~ /^\s*#/;
-
- # trim spaces from ends:
- $line =~ s/^\s*//;
- $line =~ s/\s*$//;
-
- # collect host:ports in case port range given:
- my @items;
- if ($line =~ /^(.*):(\d+)-(\d+)$/) {
- # port range:
- my $host = $1;
- my $pmin = $2;
- my $pmax = $3;
- for (my $p = $pmin; $p <= $pmax; $p++) {
- push @items, "$host:$p";
- }
- } else {
- push @items, $line;
- }
-
- # now check each item for a match:
- foreach my $item (@items) {
- if ($item eq 'ALL') {
- $ok = 1;
- last;
- } elsif ($item =~ /@/) {
- if ("$username\@$redirect_host" eq $item) {
- $ok = 1;
- last;
- }
- } elsif ($redirect_host eq $item) {
- $ok = 1;
- last;
- }
- }
- # got a match:
- last if $ok;
- }
- close ALLOWED;
-
- if (! $ok) {
- bye("Disallowed Redirect Host:Port.<p>$login_str");
- }
- }
-}
-
-# Much of this code is borrowed from 'connect_switch':
-#
-# (it only applies to the vnc redirector $enable_port_redirection mode
-# which is off by default.)
-#
-sub handle_conn {
- close STDIN;
- close STDOUT;
- close STDERR;
-
- $SIG{ALRM} = sub {close $find_free_port; exit 0};
-
- # We only wait 30 secs for the redir case, esp. since
- # we need to spawn so many helpers...
- #
- alarm(30);
-
- my ($client, $ip) = $find_free_port->accept();
-
- alarm(0);
-
- close $find_free_port;
-
- if (!$client) {
- exit 1;
- }
-
- my $host = '';
- my $port = '';
- if ($redirect_host =~ /^(.*):(\d+)$/) {
- ($host, $port) = ($1, $2);
- }
-
- my $sock = IO::Socket::INET->new(
- PeerAddr => $host,
- PeerPort => $port,
- Proto => "tcp"
- );
- if (! $sock && $have_inet6) {
- eval {$sock = IO::Socket::INET6->new(
- PeerAddr => $host,
- PeerPort => $port,
- Proto => "tcp"
- );};
- }
-
- if (! $sock) {
- close $client;
- exit 1;
- }
-
- $current_fh1 = $client;
- $current_fh2 = $sock;
-
- $SIG{TERM} = sub {close $current_fh1; close $current_fh2; exit 0};
-
- my $killpid = 1;
-
- my $parent = $$;
- if (my $child = fork()) {
- xfer($sock, $client, 'S->C');
- if ($killpid) {
- fsleep(0.5);
- kill 'TERM', $child;
- }
- } else {
- xfer($client, $sock, 'C->S');
- if ($killpid) {
- fsleep(0.75);
- kill 'TERM', $parent;
- }
- }
- exit 0;
-}
-
-# This does socket data transfer in one direction.
-#
-sub xfer {
- my($in, $out, $lab) = @_;
- my ($RIN, $WIN, $EIN, $ROUT);
- $RIN = $WIN = $EIN = "";
- $ROUT = "";
- vec($RIN, fileno($in), 1) = 1;
- vec($WIN, fileno($in), 1) = 1;
- $EIN = $RIN | $WIN;
- my $buf;
-
- while (1) {
- my $nf = 0;
- while (! $nf) {
- $nf = select($ROUT=$RIN, undef, undef, undef);
- }
- my $len = sysread($in, $buf, 8192);
- if (! defined($len)) {
- next if $! =~ /^Interrupted/;
- last;
- } elsif ($len == 0) {
- last;
- }
-
- my $offset = 0;
- my $quit = 0;
- while ($len) {
- my $written = syswrite($out, $buf, $len, $offset);
- if (! defined $written) {
- $quit = 1;
- last;
- }
- $len -= $written;
- $offset += $written;
- }
- last if $quit;
- }
- close($in);
- close($out);
-}
-
-# Sleep a small amount of time (float)
-#
-sub fsleep {
- my ($time) = @_;
- select(undef, undef, undef, $time) if $time;
-}
diff --git a/x11vnc/misc/dtVncPopup b/x11vnc/misc/dtVncPopup
deleted file mode 100644
index e90cc8b..0000000
--- a/x11vnc/misc/dtVncPopup
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/usr/dt/bin/dtksh
-#
-# accept dialog script for x11vnc
-# 2004-07-13 stefan.radman@ctbto.org
-# should work in any CDE environment (Sun,HP,IBM,...)
-#
-# when called without parameters shows a CDE question dialog:
-# Do you want to accept a VNC connection
-# from IP address $RFB_CLIENT_IP to your desktop?
-# Note:
-# After 30 seconds the screen will
-# be locked and the connection will be
-# accepted automatically."
-# [Yes} {__No__] [View/Only]
-# and counts down a timer in the dialog title bar
-# when the timer is down to 0, it locks the display and returns 0
-# (if the screenlock was successful or if the login prompt was active)
-#
-# buttons=retcode:
-# Yes = 0
-# No = 1 (same as closing the dialog windows)
-# View/Only = 3
-#
-# usage: x11vnc -forever -shared -accept "yes:0,no:*,view:3 dtVncPopup" -gone "dtVncPopup lock"
-#
-# security considerations: when you return to your console and unlock the display
-# you can never know if enyone else is connected to your display
-#
-
-# timeout until accept
-timeout=30
-
-# dialog message
-test -z "${RFB_CLIENT_IP}" && unknown="an unknown " || ip="$RFB_CLIENT_IP "
-message="\
-Do you want to accept a VNC connection
-from ${unknown}IP address ${ip}to your desktop?
-Note:
-After $timeout seconds the screen will
-be locked and the connection will be
-accepted automatically."
-
-# action functions
-accept () {
- exit 0
-}
-reject () {
- exit 1
-}
-view () {
- exit 3
-}
-lock () {
- # lock only if dtsession active
- xrdb -query | grep -c '^dtsession*' || accept
- # accept only if lock succeeds
- /usr/dt/bin/dtaction LockDisplay && accept || reject
-}
-
-# main
-
-# actions can be called directly
-test $# -gt 0 && $@
-
-# initialize the display
-XtInitialize TOPLEVEL vncPopup VncPopup "$0" "$@"
-
-# create a message dialog containing the contents of the specified file
-XmCreateQuestionDialog DIALOG $TOPLEVEL dialog \
- dialogTitle:"$DTKSH_APPNAME" \
- messageString:"$message" \
- unmapCallback:reject \
-# symbolPixmap:/usr/dt/appconfig/icons/C/DtFlag.m.pm
-
-# change the OK button to "Yes"
-XmMessageBoxGetChild OK_BUTTON $DIALOG DIALOG_OK_BUTTON
-XtSetValues $OK_BUTTON \
- labelString:"Yes" \
- activateCallback:accept
-
-# change the Cancel Button to "No"
-XmMessageBoxGetChild CANCEL_BUTTON $DIALOG DIALOG_CANCEL_BUTTON
-XtSetValues $CANCEL_BUTTON \
- labelString:"No" \
- activateCallback:reject
-
-# change Help button to View-Only, set focus and make it the default
-XmMessageBoxGetChild HELP_BUTTON $DIALOG DIALOG_HELP_BUTTON
-XtSetValues $HELP_BUTTON \
- labelString:"View\nOnly" \
- activateCallback:view
-
-# make "No" the default (for unmap as well)
-XtSetValues $DIALOG \
- defaultButton:$CANCEL_BUTTON initialFocus:$CANCEL_BUTTON \
-
-# create the ticker
-ticker () {
- test $timeout -eq 0 && lock
- XtSetValues $DIALOG dialogTitle:"accepting in $timeout seconds"
- XtAddTimeOut TICKER 1000 ticker
- timeout=`expr $timeout - 1`
-}
-
-# display dialog and activate ticker
-XtAddTimeOut TICKER 1000 ticker
-XtManageChild $DIALOG
-XtMainLoop
-
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/COPYING b/x11vnc/misc/enhanced_tightvnc_viewer/COPYING
deleted file mode 100644
index a3f6b12..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/COPYING
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- Appendix: How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/README b/x11vnc/misc/enhanced_tightvnc_viewer/README
deleted file mode 100644
index 52eb93a..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/README
+++ /dev/null
@@ -1,756 +0,0 @@
- Enhanced TightVNC Viewer (SSVNC: SSL/SSH VNC viewer)
-
-Copyright (c) 2006-2009 Karl J. Runge <runge@karlrunge.com>
-All rights reserved.
-
-These bundles provide 1) An enhanced TightVNC Viewer on Unix, 2) Binaries
-for many Operating Systems (including Windows and Mac OS X) for your
-convenience, 3) Wrapper scripts and a GUI for gluing them all together.
-
-One can straight-forwardly download all of the components and get them
-to work together by oneself: this bundle is mostly for your convenience
-to combine and wrap together the freely available software.
-
-Bundled software co-shipped is copyright and licensed by others.
-See these sites and related ones for more information:
-
- http://www.tightvnc.com
- http://www.realvnc.com
- http://stunnel.mirt.net
- http://www.stunnel.org
- http://www.openssl.org
- http://www.chiark.greenend.org.uk/~sgtatham/putty/
- http://sourceforge.net/projects/cotvnc/
-
-Note: Some of the binaries included contain cryptographic software that
-you may not be allowed to download, use, or redistribute. Please check
-your situation first before downloading any of these bundles. See the
-survey http://rechten.uvt.nl/koops/cryptolaw/index.htm for useful
-information.
-
-All work done by Karl J. Runge in this project is
-Copyright (c) 2006-2008 Karl J. Runge and is licensed under the GPL as
-described in the file COPYING in this directory.
-
-All the files and information in this project are provided "AS IS"
-without any warranty of any kind. Use them at your own risk.
-
-
-=============================================================================
-
-This bundle contains a convenient collection of enhanced TightVNC
-viewers and stunnel binaries for different flavors of Unix and wrapper
-scripts and a GUI front-end to glue them together. Automatic SSL and
-SSH encryption tunnelling is provided.
-
-A Windows SSL wrapper for the bundled TightVNC binary and other utilities
-are provided. (Launch ssvnc.exe in the Windows subdirectory).
-
-The short name of the project is "ssvnc" for SSL/SSH VNC Viewer.
-
-It is a self-contained bundle, you could carry it around on, say,
-a USB memory stick for secure VNC viewing from almost any machine,
-Unix, Mac, or Windows.
-
-Features:
---------
-
-The enhanced TightVNC viewer features are:
-
- - SSL support for connections using the bundled stunnel program.
-
- - Automatic SSH connections from the GUI (ssh must already be
- installed on Unix; bundled plink is used on Windows)
-
- - Ability to Save and Load VNC profiles for different hosts.
-
- - You can also use your own VNC Viewer, e.g. UltraVNC or RealVNC,
- with the front-end GUI or scripts if you like.
-
- - Create or Import SSL Certificates and Private Keys.
-
- - Reverse (viewer listening) VNC connections via SSL and SSH.
-
- - VeNCrypt SSL/TLS VNC encryption support (used by VeNCrypt,
- QEMU, ggi, libvirt/virt-manager/xen, vinagre/gvncviewer/gtk-vnc)
-
- - ANONTLS SSL/TLS VNC encryption support (used by Vino)
-
- - VeNCrypt and ANONTLS are also enabled for any 3rd party VNC
- Viewer (e.g. RealVNC, TightVNC, UltraVNC ...) on Unix, MacOSX,
- and Windows via the provided SSVNC VeNCrypt Viewer Bridge tool
- (use 'Change VNC Viewer' to select the one you want.)
-
- - Support for Web Proxies, SOCKS Proxies, and the UltraVNC
- repeater proxy (e.g. repeater://host:port+ID:1234). Multiple
- proxies may be chained together (3 max).
-
- - Support for SSH Gateway connections and non-standard SSH ports.
-
- - Automatic Service tunnelling via SSH for CUPS and SMB Printing,
- ESD/ARTSD Audio, and SMB (Windows/Samba) filesystem mounting.
-
- - Sets up any additional SSH port redirections that you want.
-
- - Zeroconf (aka Bonjour) is used on Unix and Mac OS X to find
- VNC servers on your local network if the avahi-browse or dns-sd
- program is available and in your PATH.
-
- - Port Knocking for "closed port" SSH/SSL connections. In addition
- to a simple fixed port sequence and one-time-pad implementation,
- a hook is also provided to run any port knocking client before a
- 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).
-
- - Dynamic VNC Server Port determination and redirection (using
- ssh's builtin SOCKS proxy, -D) for servers like x11vnc that
- print out PORT= at startup.
-
- - Unix Username and Password entry for use with "x11vnc -unixpw"
- type login dialogs.
-
- - Simplified mode launched by command "sshvnc" that is SSH Only.
-
- - Simplified mode launched by command "tsvnc" that provides a VNC
- "Terminal Services" mode (uses x11vnc on the remote side).
-
-
- (the following features only apply to the bundled Unix tightvnc viewer
- including MacOS X)
-
- - rfbNewFBSize VNC support (screen resizing)
-
- - Client-side Scaling of the Viewer.
-
- - ZRLE VNC encoding support (RealVNC's encoding)
-
- - Support for the ZYWRLE encoding, a wavelet based extension to
- ZRLE to improve compression of motion video and photo regions.
-
- - TurboVNC support (VirtualGL's modified TightVNC encoding;
- requires TurboJPEG library)
-
- - Pipelined Updates of the framebuffer as in TurboVNC (asks for
- the next update before the current one has finished downloading;
- this gives some speedup on high latency connections.)
-
- - Cursor alphablending with x11vnc at 32bpp (-alpha option)
-
- - Option "-unixpw ..." for use with "x11vnc -unixpw" login dialogs.
-
- - Support for UltraVNC extensions: Single Window, Disable
- Server-side Input, 1/n Server side scaling, Text Chat (shell
- terminal UI). Both UltraVNC and x11vnc servers support these
- extensions
-
- - UltraVNC File Transfer via an auxiliary Java helper program
- (java must be in $PATH). Note that the x11vnc server supports
- UltraVNC file transfer.
-
- - Connection support for the UltraVNC repeater proxy (-repeater
- option).
-
- - Support for UltraVNC Single Click operation. (both unencrypted:
- SC I, and SSL encrypted: SC III)
-
- - Support for UltraVNC DSM Encryption Plugin mode. (ARC4 and
- AESV2, MSRC4, and SecureVNC)
-
- - Support for UltraVNC MS-Logon authentication (NOTE: the
- UltraVNC MS-Logon key exchange implementation is very weak; an
- eavesdropper on the network can recover your Windows password
- easily in a few seconds; you need to use an additional encrypted
- tunnel with MS-Logon.)
-
- - Support for symmetric encryption (including blowfish and 3des
- ciphers) to Non-UltraVNC Servers. Any server using the same
- encryption method will work, e.g.: x11vnc -enc blowfish:./my.key
-
- - Instead of hostname:display one can also supply "exec=command
- args..." to connect the viewer to the stdio of an external command
- (e.g. stunnel or socat) rather than using a TCP/IP socket. Unix
- domain sockets, e.g. /path/to/unix/socket, and a previously
- opened file descriptor fd=0, work too.
-
- - Local Port Protections for STUNNEL and SSH: avoid having for
- long periods of time a listening port on the the local (VNC
- viewer) side that redirects to the remote side.
-
- - Reverse (viewer listening) VNC connections can show a
- Popup dialog asking whether to accept the connection or not
- (-acceptpopup.) The extra info provided by UltraVNC Single Click
- reverse connections is also supported (-acceptpopupsc)
-
- - Extremely low color modes: 64 and 8 colors in 8bpp
- (-use64/-bgr222, -use8/-bgr111)
-
- - Medium color mode: 16bpp mode even for 32bpp Viewer display
- (-16bpp/-bgr565)
-
- - x11vnc's client-side caching -ncache method cropping option
- (-ycrop n). This will "hide" the large pixel buffer cache
- below the actual display. Set to actual height or use -1 for
- autodetection (tall screens are autodetected by default).
-
- - Escape Keys: enable a set of modifier keys so when they
- are all pressed down you can invoke Popup menu actions via
- keystrokes. I.e., a set of 'Hot Keys'. One can also pan (move)
- the desktop inside the viewport via Arrow keys or a mouse drag.
-
- - Scrollbar width setting: -sbwidth n, the default is very thin,
- 2 pixels, for less distracting -ycrop usage.
-
- - Selection text sending and receiving can be fine-tuned with the
- -sendclipboard, -sendalways, and -recvtext options.
-
- - TightVNC compression and quality levels are automatically set
- based on observed network latency (n.b. not bandwidth.)
-
- - Improvements to the Popup menu, all of these can now be changed
- dynamically via the menu: ViewOnly, Toggle Bell, CursorShape
- updates, X11 Cursor, Cursor Alphablending, Toggle Tight/ZRLE,
- Toggle JPEG, FullColor/16bpp/8bpp (256/64/8 colors), Greyscale
- for low color modes, Scaling the Viewer resolution, Escape Keys,
- Pipeline Updates, and others, including UltraVNC extensions.
-
- - Maintains its own BackingStore if the X server does not
-
- - The default for localhost:0 connections is not raw encoding
- (local machine). Default assumes you are using SSH tunnel. Use
- -rawlocal to revert.
-
- - XGrabServer support for fullscreen mode, for old window managers
- (-grab/-graball option).
-
- - Fix for Popup menu positioning for old window managers
- (-popupfix option).
-
- - Run vncviewer -help for all options.
-
-
-
-The list of software bundled in the archive files:
-
- TightVNC Viewer (windows, unix, macosx)
- Chicken of the VNC Viewer (macosx)
- Stunnel (windows, unix, macosx)
- Putty/Plink/Pageant (windows)
- OpenSSL (windows)
- esound (windows)
-
-These are all self-contained in the bundle directory: they will not be
-installed on your system. Just un-zip or un-tar the file you downloaded
-and run it straight from its directory.
-
-
-Quick Start:
------------
-
-Unix and Mac OS X:
-
- Inside a Terminal do something like the following.
-
- Unpack the archive:
-
- % gzip -dc ssvnc-1.0.28.tar.gz | tar xvf -
-
- Run the GUI:
-
- % ./ssvnc/Unix/ssvnc (for Unix)
-
- % ./ssvnc/MacOSX/ssvnc (for Mac OS X)
-
- The smaller file "ssvnc_no_windows-1.0.28.tar.gz"
- could have been used as well.
-
- On MacOSX you could also click on the SSVNC app icon in the Finder.
-
- On MacOSX if you don't like the Chicken of the VNC (e.g. no local
- cursors, no screen size rescaling, and no password prompting), and you
- have the XDarwin X server installed, you can set DISPLAY before starting
- ssvnc (or type DISPLAY=... in Host:Disp and hit Return). Then our
- enhanced TightVNC viewer will be used instead of COTVNC.
- Update: there is now a 'Use X11 vncviewer on MacOSX' under Options ...
-
-
- If you want a SSH-only tool (without the distractions of SSL) run
- the command:
-
- sshvnc
-
- instead of "ssvnc". Or click "SSH-Only Mode" under Options.
- Control-h will toggle between the two modes.
-
-
- If you want a simple VNC Terminal Services only mode (requires x11vnc
- on the remote server) run the command:
-
- tsvnc
-
- instead of "ssvnc". Or click "Terminal Services" under Options.
- Control-t will toggle between the two modes.
-
- "tsvnc profile-name" and "tsvnc user@hostname" work too.
-
-
-Unix/MacOSX Install:
-
- There is no standard install for the bundles, but you can make
- symlinks like so:
-
- cd /a/directory/in/PATH
- ln -s /path/to/ssvnc/bin/{s,t}* .
-
- Or put /path/to/ssvnc/bin, /path/to/ssvnc/Unix, or /path/to/ssvnc/MacOSX
- in your PATH.
-
- For the conventional source tarball it will compile and install, e.g.:
-
- gzip -dc ssvnc-1.0.28.src.tar.gz | tar xvf -
- cd ssvnc-1.0.28
- make config
- make all
- make PREFIX=/my/install/dir install
-
- then have /my/install/dir/bin in your PATH.
-
-
-Windows:
-
- Unzip, using WinZip or a similar utility, the zip file:
-
- ssvnc-1.0.28.zip
-
- Run the GUI, e.g.:
-
- Start -> Run -> Browse
-
- and then navigate to
-
- .../ssvnc/Windows/ssvnc.exe
-
- select Open, and then OK to launch it.
-
- The smaller file "ssvnc_windows_only-1.0.28.zip"
- could have been used as well.
-
- You can make a Windows shortcut to this program if you want to.
-
- See the Windows/README.txt for more info.
-
-
- If you want a SSH-only tool (without the distractions of SSL) run
- the command:
-
- sshvnc.bat
-
- Or click "SSH-Only Mode" under Options.
-
-
- If you want a simple VNC Terminal Services only mode (requires x11vnc
- on the remote server) run the command:
-
- tsvnc.bat
-
- Or click "Terminal Services" under Options. Control-t will toggle
- between the two modes. "tsvnc profile-name" and "tsvnc user@hostname"
- work too.
-
-
-
-Important Note for Windows Vista: One user reports that on Windows Vista
-if you move or extract the "ssvnc" folder down to the "Program Files"
-folder you will be prompted to do this as the Administrator. But then
-when you start up ssvnc, as a regular user, it cannot create files in
-that folder and so it fails to run properly. We recommend to not copy
-or extract the "ssvnc" folder into "Program Files". Rather, extract
-it to somewhere you have write permission (e.g. C:\ or your User dir)
-and create a Shortcut to ssvnc.exe on the desktop.
-
-If you must put a launcher file down in "Program Files", perhaps an
-"ssvnc.bat" that looks like this:
-
-C:
-cd \ssvnc\Windows
-ssvnc.exe
-
-
-SSH-ONLY Mode:
---------------
-
-If you don't care for SSL and the distractions it provides in the GUI,
-run "sshvnc" (unix/macosx) or "sshvnc.bat" (windows) to run an SSH only
-version of the GUI.
-
-Terminal Services Mode
-----------------------
-
-There is an even simpler mode that uses x11vnc on the remote side for the
-session finding and management. Run "tsvnc" (unix/macosx) or "tsvnc.bat"
-(windows) to run the Terminal Services version of the GUI.
-
-
-Bundle Info:
-------------
-
-The bundle files unpack a directory/folder named: ssvnc
-
-It contains these programs to launch the GUI:
-
- Windows/ssvnc.exe for Windows
- MacOSX/ssvnc for Mac OS X
- Unix/ssvnc for Unix
-
-(the Mac OS X and Unix launchers are simply links to the bin directory).
-
-
-Your bundle file should have included binaries for many OS's: Linux,
-Solaris, FreeBSD, etc. Unpack your archive and see the subdirectories of
-
- ./bin
-
-for the ones that were shipped in this project, e.g. ./bin/Linux.i686
-Run "uname -sm" to see your OS+arch combination (n.b. all Linux x86 are
-mapped to Linux.i686). (See the ./bin/ssvnc_cmd -h output for how to
-override platform autodection via the UNAME env. var).
-
-
-Memory Stick Usage:
--------------------
-
-If you create a directory named "Home" in that toplevel ssvnc directory
-then that will be used as the base for storing VNC profiles and
-certificates. Also, for convenience, if you first run the command with
-"." as an argument (e.g. "ssvnc .") it will automatically create that
-"Home" directory for you. This is handy if you want to place SSVNC
-on a USB flash drive that you carry around for mobile use and you want
-the profiles you create to stay with the drive (otherwise you'd have to
-browse to the drive directory each time you load or save).
-
-One user on Windows created a BAT file to launch SSVNC and needed to
-do this to get the Home directory correct:
-
-cd \ssvnc\Windows
-start \ssvnc\Windows\ssvnc.exe
-
-(an optional profile name can be supplied to the ssvnc.exe line)
-
-WARNING: if you use ssvnc from an "Internet Cafe", i.e. an untrusted
-computer, an intruder may be capturing keystrokes etc.
-
-
-External Dependencies:
-----------------------
-
-On Windows everything is included. Let us know if you find otherwise.
-
-On Unix depending on what you do you need these programs installed:
-
- - basic unix utilities (sh, ls, cat, awk, sed, etc..)
- - tcl/tk (wish interpreter)
- - xterm
- - perl
- - ssh
- - openssl
-
- Lesser used ones: netcat, esd/artsd, smbclient, smbmount, cups
-
-On Mac OS X depending on what you do you need these programs installed:
-
- - basic unix utilities (sh, ls, cat, awk, sed, etc..)
- - tcl/tk (wish interpreter)
- - Terminal
- - perl
- - ssh
- - openssl
-
- Lesser used ones: netcat, smbclient, cups
-
-Most Mac OS X and Unix OS come with the main components installed.
-
-See the README.src for a more detailed description of dependencies.
-
-
-TurboVNC Support:
-----------------
-
-TurboVNC is supported in an experimental way. To it build via the
-build.unix script described in the next section, do something like:
-
- env TURBOVNC='-L/DIR -Xlinker --rpath=/DIR -lturbojpeg' ./build.unix
-
-where you replace /DIR with the directory where the libturbojpeg.so
-(http://sourceforge.net/project/showfiles.php?group_id=117509&package_id=166100)
-is installed.
-
-You may not need to set rpath if libturbojpeg.so is installed in a
-standard location or you use LD_LIBRARY_PATH to point to it.
-
-See the turbovnc/README in the vnc_unixsrc/vncviewer directory for
-more info. You can find it in the ssvnc source tarball and also
-in:
-
- src/zips/vnc_unixsrc_vncviewer.patched.tar
-
-More TurboVNC features will be enabled in the future.
-
-
-If you need to Build:
---------------------
-
-If your OS/arch is not included or the provided binary has the wrong
-library dependencies, etc. the script "build.unix" may be able to
-successfully build on for you and deposit the binaries down in ./bin/...
-using the included source code. It is a hack but usually works.
-
-You MUST run the build.unix script from this directory (that this toplevel
-README is in, i.e "ssvnc") and like this:
-
- ./build.unix
-
-To use custom locations for libraries see the LDFLAGS_OS and CPPFLAGS_OS
-description at the top of the build.unix script.
-
-You can set these env. vars to customize the build:
-
- SSVNC_BUILD_NO_STATIC=1 do not try to statically link libs
- SSVNC_BUILD_FORCE_OVERWRITE=1 do not prompt about existing binaries
- SSVNC_BUILD_SKIP_VIEWER=1 do not build vncviewer
- SSVNC_BUILD_SKIP_STUNNEL=1 do not build stunnel
- SSVNC_BUILD_ULTRAFTP=1 only build the file xfer helper jar
-
-here is an example to build only the vncviewer and with normal library
-linking (and in a more or less automated way):
-
- env SSVNC_BUILD_NO_STATIC=1 SSVNC_BUILD_FORCE_OVERWRITE=1 SSVNC_BUILD_SKIP_STUNNEL=1 ./build.unix
-
-Feel free to ask us if you need help running ./build.unix
-
-
-Convential Build:
-
-A more conventional source tarball is provided in ssvnc-x.y.z.src.tar.gz.
-It uses a more or less familiar 'make config; make all; make PREFIX=path install'
-method. It does not include stunnel, so that must be installed on the
-system separately.
-
-
-The programs:
-------------
-
-Unpack your archive, and you will see "bin", "Windows", "src" directories
-and other files. The command line wrapper scripts:
-
- ./bin/ssvnc_cmd
- ./bin/tightvncviewer
-
-are the main programs that are run and will try to autodetect your OS+arch
-combination and if binaries are present for it automatically use them.
-(if not found try the running the build.unix script).
-
-If you prefer a GUI to prompt for parameters and then start ssvnc_cmd
-you can run this instead:
-
- ./bin/ssvnc
-
-this is the same GUI that is run on Windows (the ssvnc.exe).
-There are also:
-
- ./bin/sshvnc (SSH-Only)
- ./bin/tsvnc (Terminal Services Mode)
-
-For convenience, you can make symlinks from a directory in your PATH to
-any of the 3 programs above you wish to run. That is all you usually
-need to do for it to pick up all of the binaries, utils, etc. E.g.
-assuming $HOME/bin is in your $PATH:
-
- cd $HOME/bin
- ln -s /path/to/ssvnc/bin/{s,t}* .
-
-(note the "." at the end). The above commands is basically the way to
-"install" this on Unix or MacOS X.
-
-Also links to the GUI launcher script are provided in:
-
- MacOSX/ssvnc
- Unix/ssvnc
-
-and sshvnc and tsvnc. You could also put the Unix or MacOSX directory
-in your PATH.
-
-
-On Windows unpack your archive and run:
-
- Windows/ssvnc.exe
-
-
-Examples:
---------
-
-The following assume you are in the toplevel directory of the
-archive you unpacked.
-
-Use enhanced TightVNC unix viewer to connect to x11vnc via SSL:
-
- ./bin/ssvnc_cmd far-away.east:0
-
- ./bin/tightvncviewer -ssl far-away.east:0 (same)
-
- ./bin/ssvnc (start GUI launcher)
-
-Use enhanced TightVNC unix viewer without SSL:
-
- ./bin/tightvncviewer far-away.east:0
-
-Use SSL to connect to a x11vnc server, and also verify the server's
-identity using the SSL Certificate in the file ./x11vnc.pem:
-
- ./bin/ssvnc_cmd -alpha -verify ./x11vnc.pem far-away.east:0
-
-(also turns on the viewer-side cursor alphablending hack).
-
-
-Brief description of the subdirectories:
----------------------------------------
-
- ./bin/util some utility scripts, e.g. ss_vncviewer
- and ssvnc.tcl
-
- ./src source code and patches.
- ./src/zips zip files of source code and binaries.
-
- ./src/vnc_unixsrc unpacked tightvnc source code tree.
- ./src/stunnel-4.14 unpacked stunnel source code tree.
- ./src/patches patches to TightVNC viewer for the new
- features on Unix (used by build.unix).
- ./src/tmp temporary build dir for build.unix
- (the last four are used by build.unix)
-
-
- ./man man pages for TightVNC viewer and stunnel.
-
- ./Windows Stock TightVNC viewer and Stunnel, Openssl
- etc Windows binaries. ssvnc.exe is the
- program to run.
-
- ./MacOSX contains an unpacked Chicken of the VNC
- viewer and a symlink to ssvnc.
-
- ./Unix contains a symlink to ssvnc.
-
-Depending on which bundle you use not all of the above may be present.
-The smallest bundles with binaries are:
-
- ssvnc_windows_only-1.x.y.zip Windows
- ssvnc_no_windows-1.x.y.tar.gz Unix and MacOSX
-
-however, the tiny scripts only one (only 60KB) will run properly on Unix
-as long as you install external vncviewer and stunnel packages:
-
- ssvnc_unix_minimal-1.x.y.tar.gz
-
-
-Untrusted Local Users:
----------------------
-
- *IMPORTANT WARNING*: If you run SSVNC on a workstation or computer
- that other users can log into and you DO NOT TRUST these users
- (it is a shame but sometimes one has to work in an environment like
- this), then please note the following warning.
-
- By 'do not trust' we mean they might try to gain access to remote
- machines you connect to via SSVNC. Note that an untrusted local
- user can often obtain root access in a short amount of time; if a
- user has achieved that, then all bets are off for ANYTHING that you
- do on the workstation. It is best to get rid of Untrusted Local
- Users as soon as possible.
-
- Both the SSL and SSH tunnels set up by SSVNC listen on certain ports
- on the 'localhost' address and redirect TCP connections to the remote
- machine; usually the VNC server running there (but it could also be
- another service, e.g. CUPS printing). These are the stunnel(8) SSL
- redirection and the ssh(1) '-L' port redirection. Because 'localhost'
- is used only users or programs on the same workstation that is
- running SSVNC can connect to these ports, however this includes any
- local users (not just the user running SSVNC.)
-
- If the untrusted local user tries to connect to these ports, he may
- succeed in varying degrees to gain access to the remote machine.
- We now list some safeguards one can put in place to try to make this
- more difficult to achieve.
-
- It probably pays to have the VNC server require a password, even
- though there has already been SSL or SSH authentication (via
- certificates or passwords). In general if the VNC Server requires
- SSL authentication of the viewer that helps, unless the untrusted
- local user has gained access to your SSVNC certificate keys.
-
- If the VNC server is configured to only allow one viewer connection
- at a time, then the window of opportunity that the untrusted local
- user can use is greatly reduced: he might only have a second or two
- between the tunnel being set up and the SSVNC vncviewer connecting
- to it (i.e. if the VNC server only allows a single connection, the
- untrusted local user cannot connect once your session is established).
- Similarly, when you disconnect the tunnel is torn down quickly and
- there is little or no window of opportunity to connect (e.g. x11vnc
- in its default mode exits after the first client disconnects).
-
- Also for SSL tunnelling with stunnel(8) on Unix using one of the SSVNC
- prebuilt 'bundles', a patched stunnel is provided that denies all
- connections after the first one, and exits when the first one closes.
- This is not true if the system installed stunnel(8) is used and is
- not true when using SSVNC on Windows.
-
- The following are two experimental features that are added to SSVNC
- to improve the situation for the SSL/stunnel case. Set them via
- Options -> Advanced -> "STUNNEL Local Port Protections".
-
- 1) For SSL tunnelling with stunnel(8) on Unix there is a setting
- 'Use stunnel EXEC mode' (experimental) that will try to exec(2)
- stunnel instead of using a listening socket. This will require
- using the specially modified vncviewer unix viewer provided
- by SSVNC. If this mode proves stable it will become the default.
-
- 2) For SSL tunnelling with stunnel(8) on Unix there is a setting
- 'Use stunnel IDENT check' (experimental) to limit socket
- connections to be from you (this assumes the untrusted local
- user has not become root on your workstation and has modified
- your local IDENT check service; if he has you have much bigger
- problems to worry about...)
-
- There is also one simple LD_PRELOAD trick for SSH to limit the number
- of accepted port redirection connections. This makes the window of
- time the untrusted local user can connect to the tunnel much smaller.
- Enable it via Options -> Advanced -> "SSH Local Port Protections".
- You will need to have the lim_accept.so file in your SSVNC package.
-
- The main message is to 'Watch your Back' when you connect via the
- SSVNC tunnels and there are users you don't trust on your workstation.
- The same applies to ANY use of SSH '-L' port redirections or outgoing
- stunnel SSL redirection services.
-
-
-Help and Info:
--------------
-
-For more help on other options and usage patterns run these:
-
- ./bin/ssvnc_cmd -h
- ./bin/util/ss_vncviewer -h
-
-See also:
-
- http://www.karlrunge.com/x11vnc
- http://www.karlrunge.com/x11vnc/faq.html
- x11vnc -h | more
-
- http://stunnel.mirt.net
- http://www.stunnel.org
- http://www.openssl.org
- http://www.tightvnc.com
- http://www.realvnc.com
- http://www.chiark.greenend.org.uk/~sgtatham/putty/
- http://sourceforge.net/projects/cotvnc/
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt
deleted file mode 100644
index 4d816d2..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-
-This is a Windows utility to automatically start up STUNNEL to redirect
-SSL VNC connections to a remote host. Then TightVNC Viewer (included)
-is launched to use this SSL tunnel.
-
-An example server would be "x11vnc -ssl", or any VNC server with a
-2nd STUNNEL program running on the server side.
-
-Just click on the program "ssvnc.exe", and then enter the remote
-VNC Server and click "Connect". Click on "Help" for more information
-information. You can also set some simple options under "Options ..."
-
-If you want that application to run in "SSH-ONLY" mode, click on
-the "sshvnc.bat" wrapper instead. Or enter SSH_ONLY.
-
-Note that on Windows when the TightVNC viewer disconnects you may need to
-terminate the STUNNEL program manually. To do this: Click on the STUNNEL
-icon (dark green) on the System Tray and then click "Exit". Before that,
-however, you will be prompted if you want ssvnc.exe to try to terminate
-STUNNEL for you. (Note that even if STUNNEL termination is successful,
-the Tray Icon may not go away until the mouse hovers over it!)
-
-With this STUNNEL and TightVNC Viewer wrapper you can also enable using
-SSL Certificates with STUNNEL, and so the connection is not only encrypted
-but it is also not susceptible to man-in-the-middle attacks.
-
-See the STUNNEL and x11vnc documentation for how to create and add SSL
-Certificates (PEM files) for authentication. Click on the "Certs ..."
-button to specify the certificate(s). See the Help there for more info
-and also:
-
- http://www.karlrunge.com/x11vnc
- http://www.tightvnc.com
- http://www.stunnel.org
- http://www.openssl.org
- http://www.chiark.greenend.org.uk/~sgtatham/putty/
-
-You can use x11vnc to create certificates if you like:
-
- http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca
-
-
-Misc:
-
- The openssl.exe stunnel.exe vncviewer.exe libeay32.dll
- libssl32.dll programs came from the websites mentioned above.
-
- IMPORTANT: some of these binaries may have cryptographic
- software that you may not be allowed to download or use.
- See the above websites for more information and also the
- util/info subdirectories.
-
- Also, the kill.exe and tlist.exe programs in the w98 directory
- came from diagnostic tools ftp site of Microsoft's.
-
-
-
-Important Note for Windows Vista: One user reports that on Windows Vista
-if you move or extract the "ssvnc" folder down to the "Program Files"
-folder you will be prompted to do this as the Administrator. But then
-when you start up ssvnc, as a regular user, it cannot create files in
-that folder and so it fails to run properly. We recommend to not copy
-or extract the "ssvnc" folder into "Program Files". Rather, extract
-it to somewhere you have write permission (e.g. C:\ or your User dir)
-and create a Shortcut to ssvnc.exe on the desktop.
-
-If you must put a launcher file down in "Program Files", perhaps an
-"ssvnc.bat" that looks like this:
-C:
-cd \ssvnc\Windows
-ssvnc.exe
-
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat
deleted file mode 100644
index 9cd2d9e..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat
+++ /dev/null
@@ -1 +0,0 @@
-start ssvnc.exe -ssh %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat
deleted file mode 100644
index 1331d02..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat
+++ /dev/null
@@ -1 +0,0 @@
-start ssvnc.exe -ts %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl
deleted file mode 100755
index ec2e0b0..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl
+++ /dev/null
@@ -1,1271 +0,0 @@
-#!/usr/bin/wish
-
-proc check_callback {} {
- global debug
- if {$debug} {
- puts stderr "."
- }
- check_closed
- after 1000 check_callback
-}
-
-proc getout {} {
- global client_fh server_fh
-
- set delay 50
- catch {flush $client_fh}
- after $delay
- catch {close $client_fh}
- set client_fh ""
- after $delay
- catch {flush $server_fh}
- after $delay
- catch {close $server_fh}
- set server_fh ""
- after $delay
-
- global bmesg_cnt
- if [info exists bmesg_cnt] {
- catch {tkwait window .bmesg$bmesg_cnt}
- }
- destroy .
- exit
-}
-
-proc check_closed {} {
- global got_connection debug
- global client_fh server_fh
-
- if {! $got_connection} {
- return
- }
- if {$client_fh != ""} {
- set ef ""
- catch {set ef [eof $client_fh]}
- if {$ef == 1} {
- if {$debug} {
- puts stderr "client_fh EOF"
- }
- getout
- }
- }
- if {$server_fh != ""} {
- set ef ""
- catch {set ef [eof $server_fh]}
- if {$ef == 1} {
- if {$debug} {
- puts stderr "server_fh EOF"
- }
- getout
- }
- }
-}
-
-proc xfer_in_to_out {} {
- global client_fh server_fh debug do_bridge
- if {$client_fh != "" && ![eof $client_fh]} {
- set ef ""
- catch {set ef [eof $client_fh]}
- if {$ef == 0} {
- set str ""
- catch {set str [read $client_fh 4096]}
- if {$debug} {
- #puts stderr "xfer_in_to_out: $str"
- puts stderr "xfer_in_to_out: [string length $str]"
- }
- if {$server_fh != "" && $str != ""} {
- catch {puts -nonewline $server_fh $str}
- catch {flush $server_fh}
- }
- }
- }
- check_closed
-}
-
-proc xfer_out_to_in {} {
- global client_fh server_fh debug do_bridge
- if {$server_fh != ""} {
- set ef ""
- catch {set ef [eof $server_fh]}
- if {$ef == 0} {
- set str ""
- catch {set str [read $server_fh 4096]}
- if {$debug} {
- #puts stderr "xfer_out_to_in: $str"
- puts stderr "xfer_out_to_in: [string length $str]"
- }
- if {$client_fh != "" && $str != ""} {
- catch {puts -nonewline $client_fh $str}
- catch {flush $client_fh}
- }
- }
- }
- check_closed
-}
-
-proc bmesg {msg} {
- global env
- if {! [info exists env(BMESG)]} {
- return
- }
- if {$env(BMESG) == 0} {
- return
- }
-
- global bmesg_cnt
- if {! [info exists bmesg_cnt]} {
- set bmesg_cnt 0
- }
- incr bmesg_cnt
- set w .bmesg$bmesg_cnt
- catch {destroy $w}
- toplevel $w
- label $w.l -width 70 -text "$msg"
- pack $w.l
- update
- if {$env(BMESG) > 1} {
- for {set i 0} {$i < $env(BMESG)} {incr i} {
- after 1000
- update
- }
- }
-}
-
-proc do_connect_http {sock hostport which} {
- global debug cur_proxy
- set con ""
- append con "CONNECT $hostport HTTP/1.1\r\n"
- append con "Host: $hostport\r\n"
- append con "Connection: close\r\n\r\n"
-
- puts stderr "pxy=$which CONNECT $hostport HTTP/1.1 via $cur_proxy"
- bmesg "H: $which CONNECT $hostport HTTP/1.1 $cur_proxy";
-
- puts -nonewline $sock $con
- flush $sock
-
- set r ""
- set cnt 0
- while {1} {
- incr cnt
- set c [read $sock 1]
- if {$c == ""} {
- check_closed
- after 20
- }
- append r $c
- if {[regexp "\r\n\r\n" $r] || [regexp "a--no--\n\n" $r]} {
- break
- }
- if {$cnt > 30000} {
- break
- }
- }
- if {! [regexp {HTTP/.* 200} $r]} {
- puts stderr "did not find HTTP 200 #1"
- destroy .
- exit 1
- }
-}
-
-proc do_connect_socks4 {sock hostport which} {
- global debug cur_proxy
-
- set host ""
- set port ""
- if [regexp {^(.*):([0-9][0-9]*)$} $hostport mvar host port] {
- ;
- } else {
- puts stderr "could not parse host:port $hostport"
- destroy .
- exit 1
- }
-
- set i1 ""
- set i2 ""
- set i3 ""
- set i4 ""
-
- set socks4a 0
-
- if {$host == "localhost" || $host == "127.0.0.1"} {
- set i1 127
- set i2 0
- set i3 0
- set i4 1
-
- } elseif [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $host] {
- set n [split $host "."]
- set i1 [lindex $n 0]
- set i2 [lindex $n 1]
- set i3 [lindex $n 2]
- set i4 [lindex $n 3]
- } else {
- set i1 0
- set i2 0
- set i3 0
- set i4 3
-
- set socks4a 1
- }
-
- if {$socks4a} {
- puts stderr "pxy=$which socks4a connection to $host:$port via $cur_proxy"
- } else {
- puts stderr "pxy=$which socks4 connection to $host:$port via $cur_proxy"
- }
-
- set p1 [binary format ccScccc 4 1 $port $i1 $i2 $i3 $i4]
- set p2 "nobody"
- set p3 [binary format c 0]
-
- puts -nonewline $sock $p1
- puts -nonewline $sock $p2
- puts -nonewline $sock $p3
- if {$socks4a} {
- puts -nonewline $sock $host
- puts -nonewline $sock $p3
- }
- flush $sock
-
- set r ""; set s ""; set i 0; set cnt 0
- set ok 1
- while {$cnt < 30000 && $i < 8} {
- incr cnt
- set c [read $sock 1]
- if {$c == ""} {
- check_closed
- after 20
- continue
- }
-
- binary scan $c c s
- if {$i == 0 && $s != 0} {
- puts stderr "socks4: $i - $s"
- set ok 0
- }
- if {$i == 1 && $s != 90} {
- puts stderr "socks4: $i - $s"
- set ok 0
- }
- set r "$r,$s"
- incr i
- }
- if {! $ok} {
- puts stderr "socks4 failure: $r"
- destroy .
- exit 1
- }
-}
-
-proc do_connect_socks5 {sock hostport which} {
- global debug cur_proxy
-
- set host ""
- set port ""
- if [regexp {^(.*):([0-9][0-9]*)$} $hostport mvar host port] {
- ;
- } else {
- puts stderr "could not parse host:port $hostport"
- destroy .
- exit 1
- }
-
- set p1 [binary format ccc 5 1 0]
- puts -nonewline $sock $p1
- flush $sock
-
- set r ""; set s ""; set i 0; set cnt 0
- set ok 1
- while {$cnt < 30000 && $i < 2} {
- incr cnt
- set c [read $sock 1]
- if {$c == ""} {
- check_closed
- after 20
- continue
- }
-
- binary scan $c c s
- if {$i == 0 && $s != 5} {
- puts stderr "$i - $s"
- set ok 0
- }
- if {$i == 1 && $s != 0} {
- puts stderr "$i - $s"
- set ok 0
- }
- set r "$r,$s"
- incr i
- }
- if {! $ok} {
- puts stderr "socks5 failure: $r"
- destroy .
- exit 1
- }
-
- set len [string length $host]
- set p1 [binary format ccccc 5 1 0 3 $len]
- set p2 $host
-
- set n1 [expr int($port/256)]
- set n2 [expr "$port - $n1 * 256"]
- set p3 [binary format cc $n1 $n2]
-
- puts stderr "pxy=$which socks5 connection to $host:$port via $cur_proxy"
-
- puts -nonewline $sock $p1
- puts -nonewline $sock $p2
- puts -nonewline $sock $p3
- flush $sock
-
- set i1 ""; set i2 ""; set i3 ""; set i4 ""
- set r ""; set s ""; set i 0; set cnt 0
- set ok 1
- while {$cnt < 30000 && $i < 4} {
- incr cnt
- set c [read $sock 1]
- if {$c == ""} {
- check_closed
- after 20
- continue
- }
-
- binary scan $c c s
- if {$i == 0} {
- set i1 $s
- } elseif {$i == 1} {
- set i2 $s
- } elseif {$i == 2} {
- set i3 $s
- } elseif {$i == 3} {
- set i4 $s
- }
- incr i
- }
- set r "i1=$i1,i2=$i2,i3=$i3,i4=$i4"
-
- if {$i4 == 1} {
- set n 6
- } elseif {$i4 == 3} {
- set c ""
- for {set i 0} {$i < 1000} {incr i} {
- set c [read $sock 1]
- if {$c == ""} {
- check_closed
- after 20
- continue
- }
- break;
- }
- if {$c == ""} {
- puts stderr "socks5 failure c: $r"
- destroy .
- exit 1
- }
- binary scan $c c s
- set n [expr $s + 2]
- } elseif {$i4 == 4} {
- set n 18
- } else {
- puts stderr "socks5 failure x: $r"
- destroy .
- exit 1
- }
- #puts "n=$n --- $r"
-
- set i 0; set cnt 0
- while {$cnt < 30000 && $i < $n} {
- incr cnt
- set c [read $sock 1]
- if {$c == ""} {
- check_closed
- after 20
- continue
- }
- incr i
- }
- if {$i1 != 5 || $i2 != 0 || $i3 != 0} {
- puts stderr "socks failure $r"
- destroy .
- exit 1
- }
-}
-
-proc do_connect_repeater {sock hostport which repeater} {
- global debug cur_proxy
-
- # 250 is UltraVNC buffer size.
- set con [binary format a250 $repeater]
-
- puts stderr "pxy=$which REPEATER $repeater via $cur_proxy"
- bmesg "R: $which CONNECT $hostport | $repeater $cur_proxy";
-
- puts -nonewline $sock $con
- flush $sock
-
- set r ""
- set cnt 0
- while {1} {
- incr cnt
- set c [read $sock 1]
- if {$c == ""} {
- check_closed
- after 20
- }
- append r $c
- if {[string length $r] >= 12} {
- puts stderr "do_connect_repeater: $r"
- break
- }
- if {$cnt > 30000} {
- break
- }
- }
-}
-
-proc vread {n sock} {
- set str ""
- set max 3000
- set dt 10
- set i 0
- set cnt 0
- while {$cnt < $max && $i < $n} {
- incr cnt
- set c [read $sock 1]
- if {$c == ""} {
- check_closed
- after $dt
- continue
- }
- incr i
- append str $c
- }
- if {$i != $n} {
- puts stderr "vread failure $n $i"
- destroy .; exit 1
- }
- return $str
-}
-
-proc append_handshake {str} {
- global env
- if [info exists env(SSVNC_PREDIGESTED_HANDSHAKE)] {
- set file $env(SSVNC_PREDIGESTED_HANDSHAKE)
- set fh ""
- catch {set fh [open $file a]}
- if {$fh != ""} {
- puts $fh $str
- catch {close $fh}
- }
- }
-}
-
-proc vencrypt_bridge_connection {fh host port} {
- puts stderr "vencrypt_bridge_connection: got connection $fh $host $port"
- bmesg "vencrypt_bridge_connection: got connection $fh $host $port"
- global viewer_sock
- set viewer_sock $fh
-}
-
-proc center_win {w} {
- update
- set W [winfo screenwidth $w]
- set W [expr $W + 1]
- wm geometry $w +$W+0
- update
- set x [expr [winfo screenwidth $w]/2 - [winfo width $w]/2]
- set y [expr [winfo screenheight $w]/2 - [winfo height $w]/2]
-
- wm geometry $w +$x+$y
- wm deiconify $w
- update
-}
-
-
-proc get_user_pass {} {
- global env
- set up ""
- if [info exists env(SSVNC_UNIXPW)] {
- set rm 0
- set up $env(SSVNC_UNIXPW)
- if [regexp {^rm:} $up] {
- set rm 1
- regsub {^rm:} $up "" up
- }
- if [file exists $up] {
- set fh ""
- set f $up
- catch {set fh [open $up r]}
- if {$fh != ""} {
- gets $fh u
- gets $fh p
- catch {close $fh}
- set up "$u@$p"
- }
- if {$rm} {
- catch {file delete $f}
- }
- }
- } elseif [info exists env(SSVNC_VENCRYPT_USERPASS)] {
- set up $env(SSVNC_VENCRYPT_USERPASS)
- }
- if {$up != ""} {
- return $up
- }
-
- toplevel .t
- wm title .t {VeNCrypt Viewer Bridge User/Pass}
-
- global user pass
- set user ""
- set pass ""
- label .t.l -text {SSVNC VeNCrypt Viewer Bridge}
-
- frame .t.f0
- frame .t.f0.fL
- label .t.f0.fL.la -text {Username: }
- label .t.f0.fL.lb -text {Password: }
-
- pack .t.f0.fL.la .t.f0.fL.lb -side top
-
- frame .t.f0.fR
- entry .t.f0.fR.ea -width 24 -textvariable user
- entry .t.f0.fR.eb -width 24 -textvariable pass -show *
-
- pack .t.f0.fR.ea .t.f0.fR.eb -side top -fill x
-
- pack .t.f0.fL -side left
- pack .t.f0.fR -side right -expand 1 -fill x
-
- button .t.no -text Cancel -command {set user ""; set pass ""; destroy .t}
- button .t.ok -text Done -command {destroy .t}
-
- center_win .t
- pack .t.l .t.f0 .t.no .t.ok -side top -fill x
- update
- wm deiconify .t
-
- bind .t.f0.fR.ea <Return> {focus .t.f0.fR.eb}
- bind .t.f0.fR.eb <Return> {destroy .t}
- focus .t.f0.fR.ea
-
- wm resizable .t 1 0
- wm minsize .t [winfo reqwidth .t] [winfo reqheight .t]
-
- tkwait window .t
- if {$user == "" || $pass == ""} {
- return ""
- } else {
- return "$user@$pass"
- }
-}
-
-proc do_vencrypt_viewer_bridge {listen connect} {
- global env
-
- #set env(BMESG) 1
-
- vencrypt_constants
-
- set backwards 0
-
- if {! [info exists env(SSVNC_PREDIGESTED_HANDSHAKE)]} {
- puts stderr "no SSVNC_PREDIGESTED_HANDSHAKE filename in environment."
- destroy .; exit 1
- }
- set handshake $env(SSVNC_PREDIGESTED_HANDSHAKE)
- bmesg $handshake
-
- if {$listen < 0} {
- set backwards 1
- set listen [expr -$listen]
- }
-
- # listen on $listen
- global viewer_sock
- set viewer_sock ""
- set lsock ""
- set rc [catch {set lsock [socket -myaddr 127.0.0.1 -server vencrypt_bridge_connection $listen]}]
- if {$rc != 0} {
- puts stderr "error listening on 127.0.0.1:$listen"
- destroy .; exit 1
- }
- bmesg "listen on $listen OK"
-
- # accept
- vwait viewer_sock
- catch {close $lsock}
- fconfigure $viewer_sock -translation binary -blocking 0
-
- global got_connection
- set got_connection 1
-
- # connect to $connect
- set server_sock ""
- set rc [catch {set server_sock [socket 127.0.0.1 $connect]}]
- if {$rc != 0} {
- puts stderr "error connecting to 127.0.0.1:$connect"
- destroy .; exit 1
- }
- bmesg "made connection to $connect"
- fconfigure $server_sock -translation binary -blocking 0
-
- if {$backwards} {
- puts stderr "reversing roles of viewer and server"
- set t $viewer_sock
- set viewer_sock $server_sock
- set server_sock $t
- }
-
- # wait for SSVNC_PREDIGESTED_HANDSHAKE "done", put in hash.
- set dt 200
- set slept 0
- set maxwait 20000
- set hs(mode) init
- while {$slept < $maxwait} {
- after $dt
- set slept [expr $slept + $dt]
- set done 0
- set fh ""
- catch {set fh [open $handshake r]}
- set str ""
- if {$fh != ""} {
- array unset hs
- while {[gets $fh line] > -1} {
- set line [string trim $line]
- set str "$str$line\n";
- if {$line == "done"} {
- set done 1
- } elseif [regexp {=} $line] {
- set s [split $line "="]
- set key [lindex $s 0]
- set val [lindex $s 1]
- set hs($key) $val
- }
- }
- catch {close $fh}
- }
- if {$done} {
- puts stderr $str
- bmesg "$str"
- break
- }
- }
-
- catch [file delete $handshake]
-
- if {! [info exists hs(sectype)]} {
- puts stderr "no hs(sectype) found"
- destroy .; exit 1
- }
-
- # read viewer RFB
- if {! [info exists hs(server)]} {
- set hs(server) "RFB 003.008"
- }
- puts -nonewline $viewer_sock "$hs(server)\n"
- flush $viewer_sock
- puts stderr "sent $hs(server) to viewer sock."
-
- set viewer_rfb [vread 12 $viewer_sock]
- puts stderr "read viewer_rfb $viewer_rfb"
-
- set viewer_major 3
- set viewer_minor 8
- if [regexp {^RFB 003\.0*([0-9][0-9]*)} $viewer_rfb m v] {
- set viewer_minor $v
- }
-
- if {$hs(sectype) == $rfbSecTypeAnonTls} {
- puts stderr "handling rfbSecTypeAnonTls"
- if {$viewer_major > 3 || $viewer_minor >= 7} {
- puts stderr "viewer >= 3.7, nothing to set up."
- } else {
- puts stderr "viewer <= 3.3, faking things up."
- set t [vread 1 $server_sock]
- binary scan $t c nsectypes
- puts stderr "nsectypes=$nsectypes"
- for {set i 0} {$i < $nsectypes} {incr i} {
- set t [vread 1 $server_sock]
- binary scan $t c st
- puts stderr " $i: $st"
- set types($st) $i
- }
- set use 1
- if [info exists types(1)] {
- set use 1
- } elseif [info exists types(2)] {
- set use 2
- } else {
- puts stderr "no valid sectypes"
- destroy .; exit 1
- }
- # this should be MSB:
- vsend_uchar $viewer_sock 0
- vsend_uchar $viewer_sock 0
- vsend_uchar $viewer_sock 0
- vsend_uchar $viewer_sock $use
-
- vsend_uchar $server_sock $use
- if {$use == 1} {
- set t [vread 4 $server_sock]
- }
- }
- } elseif {$hs(sectype) == $rfbSecTypeVencrypt} {
- puts stderr "handling rfbSecTypeVencrypt"
- if {! [info exists hs(subtype)]} {
- puts stderr "no subtype"
- destroy .; exit 1
- }
- set fake_type "None"
- set plain 0
-
- set sub_type $hs(subtype)
-
-
- if {$sub_type == $rfbVencryptTlsNone} {
- set fake_type "None"
- } elseif {$sub_type == $rfbVencryptTlsVnc} {
- set fake_type "VncAuth"
- } elseif {$sub_type == $rfbVencryptTlsPlain} {
- set fake_type "None"
- set plain 1
- } elseif {$sub_type == $rfbVencryptX509None} {
- set fake_type "None"
- } elseif {$sub_type == $rfbVencryptX509Vnc} {
- set fake_type "VncAuth"
- } elseif {$sub_type == $rfbVencryptX509Plain} {
- set fake_type "None"
- set plain 1
- }
-
- if {$plain} {
- set up [get_user_pass]
- if [regexp {@} $up] {
- set user $up
- set pass $up
- regsub {@.*$} $user "" user
- regsub {^[^@]*@} $pass "" pass
- vsend_uchar $server_sock 0
- vsend_uchar $server_sock 0
- vsend_uchar $server_sock 0
- vsend_uchar $server_sock [string length $user]
- vsend_uchar $server_sock 0
- vsend_uchar $server_sock 0
- vsend_uchar $server_sock 0
- vsend_uchar $server_sock [string length $pass]
- puts stderr "sending VencryptPlain user and pass."
- puts -nonewline $server_sock $user
- puts -nonewline $server_sock $pass
- flush $server_sock
- }
- }
- set ft 0
- if {$fake_type == "None"} {
- set ft 1
- } elseif {$fake_type == "VncAuth"} {
- set ft 2
- } else {
- puts stderr "no valid fake_type"
- destroy .; exit 1
- }
-
- if {$viewer_major > 3 || $viewer_minor >= 7} {
- vsend_uchar $viewer_sock 1
- vsend_uchar $viewer_sock $ft
- set t [vread 1 $viewer_sock]
- binary scan $t c cr
- if {$cr != $ft} {
- puts stderr "client selected wront type $cr $ft"
- destroy .; exit 1
- }
- } else {
- puts stderr "viewer <= 3.3, faking things up."
- # this should be MSB:
- vsend_uchar $viewer_sock 0
- vsend_uchar $viewer_sock 0
- vsend_uchar $viewer_sock 0
- vsend_uchar $viewer_sock $ft
-
- if {$ft == 1} {
- set t [vread 4 $server_sock]
- }
- }
- }
-
- global client_fh server_fh
- set client_fh $viewer_sock
- set server_fh $server_sock
-
- fileevent $client_fh readable xfer_in_to_out
- fileevent $server_fh readable xfer_out_to_in
-}
-
-proc vsend_uchar {sock n} {
- set s [binary format c $n]
- puts -nonewline $sock $s
- flush $sock
-}
-
-proc vencrypt_constants {} {
- uplevel {
- set rfbSecTypeAnonTls 18
- set rfbSecTypeVencrypt 19
-
- set rfbVencryptPlain 256
- set rfbVencryptTlsNone 257
- set rfbVencryptTlsVnc 258
- set rfbVencryptTlsPlain 259
- set rfbVencryptX509None 260
- set rfbVencryptX509Vnc 261
- set rfbVencryptX509Plain 262
- }
-}
-
-proc do_vencrypt {sock which} {
-
- vencrypt_constants
-
- set t [vread 1 $sock]
- binary scan $t c vs_major
- set t [vread 1 $sock]
- binary scan $t c vs_minor
-
- if {$vs_minor == "" || $vs_major == "" || $vs_major != 0 || $vs_minor < 2} {
- puts stderr "vencrypt failure bad vs version major=$major minor=$minor"
- destroy .; exit 1
- }
- puts stderr "server vencrypt version $vs_major.$vs_minor"
- bmesg "server vencrypt version $vs_major.$vs_minor"
-
- append_handshake "subversion=0.2"
- vsend_uchar $sock 0
- vsend_uchar $sock 2
-
- set t [vread 1 $sock]
- binary scan $t c result
- if {$result != 0} {
- puts stderr "vencrypt failed result: $result"
- bmesg "vencrypt failed result: $result"
- destroy .; exit 1
- }
-
- set t [vread 1 $sock]
- binary scan $t c nsubtypes
- puts stderr "nsubtypes: $nsubtypes"
- bmesg "nsubtypes: $nsubtypes"
-
- for {set i 0} {$i < $nsubtypes} {incr i} {
- set t [vread 4 $sock]
- binary scan $t I stype
- puts stderr "subtypes: $i: $stype"
- append_handshake "sst$i=$stype"
- set subtypes($stype) $i
- }
-
- set subtype 0
- if [info exists subtypes($rfbVencryptX509None)] {
- set subtype $rfbVencryptX509None
- puts stderr "selected rfbVencryptX509None"
- } elseif [info exists subtypes($rfbVencryptX509Vnc)] {
- set subtype $rfbVencryptX509Vnc
- puts stderr "selected rfbVencryptX509Vnc"
- } elseif [info exists subtypes($rfbVencryptX509Plain)] {
- set subtype $rfbVencryptX509Plain
- puts stderr "selected rfbVencryptX509Plain"
- } elseif [info exists subtypes($rfbVencryptTlsNone)] {
- set subtype $rfbVencryptTlsNone
- puts stderr "selected rfbVencryptTlsNone"
- } elseif [info exists subtypes($rfbVencryptTlsVnc)] {
- set subtype $rfbVencryptTlsVnc
- puts stderr "selected rfbVencryptTlsVnc"
- } elseif [info exists subtypes($rfbVencryptTlsPlain)] {
- set subtype $rfbVencryptTlsPlain
- puts stderr "selected rfbVencryptTlsPlain"
- }
- append_handshake "subtype=$subtype"
- set st [binary format I $subtype]
- puts -nonewline $sock $st
- flush $sock
-
- if {$subtype == 0} {
- puts stderr "vencrypt could not find an acceptable subtype: $subtype"
- destroy .; exit 1
- }
-
- set t [vread 1 $sock]
- binary scan $t c result
- puts stderr "result=$result"
-
- append_handshake "done"
-
- if {$result == 0} {
- puts stderr "vencrypt failure result: $result"
- destroy .; exit 1
- }
-
-}
-
-proc do_connect_vencrypt {sock hostport which} {
- global debug cur_proxy
-
- vencrypt_constants
-
- puts stderr "pxy=$which vencrypt $hostport via $cur_proxy"
- bmesg "V: $which vencrypt $hostport via $cur_proxy"
-
- append_handshake "mode=connect"
-
- set srfb [vread 12 $sock]
- puts stderr "srfb: $srfb"
- bmesg "srfb: $srfb"
- set srfb [string trim $srfb]
- append_handshake "server=$srfb"
-
- set minor ""
- if [regexp {^RFB 00[456]\.} $srfb] {
- set minor 8
- } elseif [regexp {^RFB 003\.0*([0-9][0-9]*)} $srfb mvar minor] {
- ;
- }
- if {$minor == "" || $minor < 7} {
- puts stderr "vencrypt failure bad minor=$minor"
- destroy .; exit 1
- }
-
- set vrfb "RFB 003.008\n"
- if {$minor == 7} {
- set vrfb "RFB 003.007\n"
- }
- puts -nonewline $sock $vrfb
- flush $sock
-
- set vrfb [string trim $vrfb]
- append_handshake "viewer=$vrfb"
- append_handshake "latency=0.10"
-
- set str [vread 1 $sock]
- binary scan $str c nsec
- puts stderr "nsec: $nsec"
- bmesg "nsec: $nsec"
- for {set i 0} {$i < $nsec} {incr i} {
- set str [vread 1 $sock]
- binary scan $str c sec
- puts stderr "sec: $sec"
- bmesg "sec: $sec"
- set sectypes($i) $sec
- }
- for {set i 0} {$i < $nsec} {incr i} {
- if {$sectypes($i) == $rfbSecTypeVencrypt} {
- append_handshake "sectype=$rfbSecTypeVencrypt"
- vsend_uchar $sock $rfbSecTypeVencrypt
- after 500
- bmesg "do_vencrypt $sock $which"
- do_vencrypt $sock $which
- return
- }
- }
- for {set i 0} {$i < $nsec} {incr i} {
- if {$sectypes($i) == $rfbSecTypeAnonTls} {
- append_handshake "sectype=$rfbSecTypeAnonTls"
- vsend_uchar $sock $rfbSecTypeAnonTls
- bmesg "rfbSecTypeAnonTls"
- after 500
- append_handshake "done"
- return
- }
- }
-}
-
-proc do_connect {sock type hostport which} {
- if {$type == "http"} {
- do_connect_http $sock $hostport $which
- } elseif {$type == "socks"} {
- do_connect_socks4 $sock $hostport $which
- } elseif {$type == "socks5"} {
- do_connect_socks5 $sock $hostport $which
- } elseif [regexp -nocase {^repeater:} $type] {
- regsub -nocase {^repeater:} $type "" repeater
- do_connect_repeater $sock $hostport $which $repeater
- } elseif {$type == "vencrypt"} {
- do_connect_vencrypt $sock $hostport $which
- }
-}
-
-proc handle_connection {fh host port} {
- global proxy1_host proxy1_port proxy1_type
- global proxy2_host proxy2_port proxy2_type
- global proxy3_host proxy3_port proxy3_type
- global proxy1 proxy2 proxy3 dest
- global debug cur_proxy
- global got_connection
-
- if {$got_connection} {
- catch {close $fh}
- return
- }
- set got_connection 1
-
- if {$debug} {
- puts stderr "connection from: $host $port"
- puts stderr "socket $proxy1_host $proxy1_port"
- }
-
- set rc [catch {set sock [socket $proxy1_host $proxy1_port]}]
- if {$rc != 0} {
- puts stderr "error connecting"
- catch {close $sock}
- destroy .
- exit
- }
-
- if {$debug} {
- puts stderr "got sock: $sock"
- }
-
- global client_fh server_fh
- set client_fh $fh
- set server_fh $sock
-
- fconfigure $fh -translation binary -blocking 0
- fconfigure $sock -translation binary -blocking 0
-
- set cur_proxy $proxy1
- if {$proxy2 != ""} {
- do_connect $sock $proxy1_type "$proxy2_host:$proxy2_port" 1
-
- set cur_proxy $proxy2
- if {$proxy3 != ""} {
- do_connect $sock $proxy2_type "$proxy3_host:$proxy3_port" 2
-
- set cur_proxy $proxy3
- do_connect $sock $proxy3_type $dest 3
-
- } else {
- do_connect $sock $proxy2_type $dest 2
- }
- } else {
- do_connect $sock $proxy1_type $dest 1
- }
-
- fileevent $fh readable xfer_in_to_out
- fileevent $sock readable xfer_out_to_in
-}
-
-proc proxy_type {proxy} {
- if [regexp -nocase {^socks://} $proxy] {
- return "socks"
- } elseif [regexp -nocase {^socks4://} $proxy] {
- return "socks"
- } elseif [regexp -nocase {^socks4a://} $proxy] {
- return "socks"
- } elseif [regexp -nocase {^socks5://} $proxy] {
- return "socks5"
- } elseif [regexp -nocase {^http://} $proxy] {
- return "http"
- } elseif [regexp -nocase {^https://} $proxy] {
- return "http"
- } elseif [regexp -nocase {^repeater://.*\+(.*)$} $proxy mat idstr] {
- return "repeater:$idstr"
- } elseif [regexp -nocase {^vencrypt://} $proxy] {
- return "vencrypt"
- } else {
- return "http"
- }
-}
-
-proc proxy_hostport {proxy} {
- regsub -nocase {^[a-z][a-z0-9]*://} $proxy "" hp
- regsub {\+.*$} $hp "" hp
- if {! [regexp {:[0-9]} $hp] && [regexp {^repeater:} $proxy]} {
- set hp "$hp:5900"
- }
- return $hp
-}
-
-proc setb {} {
- wm withdraw .
- catch {destroy .b}
- button .b -text "CONNECT_BR" -command {destroy .}
- pack .b
- after 1000 check_callback
-}
-
-proc connect_br_sleep {} {
- global env
- if [info exists env(CONNECT_BR_SLEEP)] {
- if [regexp {^[0-9][0-9]*$} $env(CONNECT_BR_SLEEP)] {
- setb
- for {set i 0} {$i < $env(CONNECT_BR_SLEEP)} {incr i} {
- bmesg "$i sleep"
- after 1000
- }
- }
- }
-}
-
-global env
-
-set got_connection 0
-set proxy1 ""
-set proxy2 ""
-set proxy3 ""
-set client_fh ""
-set server_fh ""
-set do_bridge 0
-set debug 0
-
-if [info exists env(CONNECT_BR_DEBUG)] {
- set debug 1
-}
-
-if [info exists env(SSVNC_VENCRYPT_VIEWER_BRIDGE)] {
- set s [split $env(SSVNC_VENCRYPT_VIEWER_BRIDGE) ","]
- set listen [lindex $s 0]
- set connect [lindex $s 1]
-
- setb
-
- do_vencrypt_viewer_bridge $listen $connect
- set do_bridge 1
-}
-
-if {$do_bridge} {
- ;
-} else {
- if {$debug && 0} {
- if {! [info exists env(SSVNC_DEST)]} {
- set env(SSVNC_DEST) "haystack:2037"
- }
- if {! [info exists env(SSVNC_PROXY)]} {
- set env(SSVNC_PROXY) "haystack:2037"
- }
- if {! [info exists env(SSVNC_LISTEN)]} {
- set env(SSVNC_LISTEN) "6789"
- }
- } else {
- if {! [info exists env(SSVNC_DEST)]} {
- destroy .; exit;
- }
- if {! [info exists env(SSVNC_PROXY)]} {
- destroy .; exit;
- }
- if {! [info exists env(SSVNC_LISTEN)] && ! [info exists env(SSVNC_REVERSE)]} {
- destroy .; exit;
- }
- }
-
- #set env(BMESG) 1
-
- set dest $env(SSVNC_DEST)
-
- if [regexp {,} $env(SSVNC_PROXY)] {
- set s [split $env(SSVNC_PROXY) ","]
- set proxy1 [lindex $s 0]
- set proxy2 [lindex $s 1]
- set proxy3 [lindex $s 2]
- } else {
- set proxy1 $env(SSVNC_PROXY)
- }
-
- set proxy1_type [proxy_type $proxy1]
- set proxy1_hp [proxy_hostport $proxy1]
-
- set proxy1_host ""
- set proxy1_port ""
- if [regexp {^(.*):([0-9][0-9]*)$} $proxy1_hp mvar proxy1_host proxy1_port] {
- ;
- } else {
- puts stderr "could not parse hp1 host:port $proxy1_hp"
- destroy .
- exit 1
- }
-
- set proxy2_type ""
- set proxy2_host ""
- set proxy2_port ""
-
- if {$proxy2 != ""} {
- set proxy2_type [proxy_type $proxy2]
- set proxy2_hp [proxy_hostport $proxy2]
-
- set proxy2_host ""
- set proxy2_port ""
- if [regexp {^(.*):([0-9][0-9]*)$} $proxy2_hp mvar proxy2_host proxy2_port] {
- ;
- } else {
- puts stderr "could not parse hp2 host:port $proxy2_hp"
- destroy .
- exit 1
- }
- }
-
- set proxy3_type ""
- set proxy3_host ""
- set proxy3_port ""
-
- if {$proxy3 != ""} {
- set proxy3_type [proxy_type $proxy3]
- set proxy3_hp [proxy_hostport $proxy3]
-
- set proxy3_host ""
- set proxy3_port ""
- if [regexp {^(.*):([0-9][0-9]*)$} $proxy3_hp mvar proxy3_host proxy3_port] {
- ;
- } else {
- puts stderr "could not parse hp3 host:port $proxy3_hp"
- destroy .
- exit 1
- }
- }
-
- bmesg "1: '$proxy1_host' '$proxy1_port' '$proxy1_type'";
- bmesg "2: '$proxy2_host' '$proxy2_port' '$proxy2_type'";
- bmesg "3: '$proxy3_host' '$proxy3_port' '$proxy3_type'";
-
- if [info exists env(SSVNC_REVERSE)] {
- set rhost ""
- set rport ""
- if [regexp {^(.*):([0-9][0-9]*)$} $env(SSVNC_REVERSE) mvar rhost rport] {
- ;
- } else {
- puts stderr "could not parse SSVNC_REVERSE host:port $env(SSVNC_REVERSE)"
- destroy .
- exit 1
- }
- setb
- set rc [catch {set lsock [socket $rhost $rport]}]
- if {$rc != 0} {
- puts stderr "error reversing"
- bmesg "1 error reversing"
- after 2000
- set rc [catch {set lsock [socket $rhost $rport]}]
- }
- if {$rc != 0} {
- puts stderr "error reversing"
- bmesg "2 error reversing"
- after 2000
- set rc [catch {set lsock [socket $rhost $rport]}]
- }
- if {$rc != 0} {
- puts stderr "error reversing"
- bmesg "3 error reversing"
- destroy .; exit 1
- }
- puts stderr "SSVNC_REVERSE to $rhost $rport OK";
- bmesg "SSVNC_REVERSE to $rhost $rport OK";
- connect_br_sleep
- handle_connection $lsock $rhost $rport
- } else {
- set lport $env(SSVNC_LISTEN)
- connect_br_sleep
- set rc [catch {set lsock [socket -myaddr 127.0.0.1 -server handle_connection $lport]}]
- if {$rc != 0} {
- puts stderr "error listening"
- destroy .; exit 1
- }
- puts stderr "SSVNC_LISTEN on $lport OK";
- setb
- }
-}
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/esound/download.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/esound/download.url
deleted file mode 100644
index 59f1f6b..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/esound/download.url
+++ /dev/null
@@ -1 +0,0 @@
-http://www.tux.org/~ricdude/EsounD.html
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/download.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/download.url
deleted file mode 100644
index 237d4b1..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/download.url
+++ /dev/null
@@ -1 +0,0 @@
-http://www.stunnel.org/download/stunnel/win32/
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/location.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/location.url
deleted file mode 100644
index c700866..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/location.url
+++ /dev/null
@@ -1 +0,0 @@
-http://www.stunnel.org/download/binaries.html
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/download.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/download.url
deleted file mode 100644
index a23901e..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/download.url
+++ /dev/null
@@ -1 +0,0 @@
-http://www.chiark.greenend.org.uk/%7esgtatham/putty/download.html
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/licence.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/licence.url
deleted file mode 100644
index 2efcc31..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/licence.url
+++ /dev/null
@@ -1 +0,0 @@
-http://www.chiark.greenend.org.uk/%7esgtatham/putty/licence.html
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/download.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/download.url
deleted file mode 100644
index 237d4b1..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/download.url
+++ /dev/null
@@ -1 +0,0 @@
-http://www.stunnel.org/download/stunnel/win32/
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/location.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/location.url
deleted file mode 100644
index 4f87491..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/location.url
+++ /dev/null
@@ -1,2 +0,0 @@
-http://www.stunnel.org/download/binaries.html
-http://stunnel.mirt.net/
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/download.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/download.url
deleted file mode 100644
index 36c60e4..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/download.url
+++ /dev/null
@@ -1 +0,0 @@
-http://www.tightvnc.com/download.html
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/location.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/location.url
deleted file mode 100644
index a686ae0..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/location.url
+++ /dev/null
@@ -1 +0,0 @@
-http://www.tightvnc.com
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-client.conf b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-client.conf
deleted file mode 100644
index 7517e23..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-client.conf
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Example SSL stunnel CLIENT configuration file. (you run stunnel on
-# this machine and point your vnc viewer to it, it goes to remote VNC
-# server via SSL)
-#
-# To use this file you will need to edit it. Then you will need
-# to manually start up stunnel using it.
-# (e.g. /path/to/stunnel stunnel-server.conf)
-#
-# This is just an example and is not used by the tools in this package.
-# It is here to show how to create outgoing SSL connections to remote
-# VNC servers when not using the tools in this package.
-#
-client = yes
-options = ALL
-RNDbytes = 2048
-RNDfile = bananarand.bin
-RNDoverwrite = yes
-#
-# Remote server certs could go here:
-# CApath = /path/to/.../crt-dir
-# CAfile = /path/to/.../foo.crt
-# verify = 2
-# My cert could go here:
-# cert = /path/to/.../my.pem
-#
-[vnc]
-#
-# Set to local listening port number (e.g. 5900 for vnc display 0):
-#
-accept = localhost:5900
-#
-# Set to remote host:port to connect to (e.g. far-away.east:5900):
-# (this is where the VNC server is. :0 -> port 5900, etc)
-#
-connect = HOST:PORT
-delay = no
-#
-# You could add additional ones going to other VNC servers:
-# [vnc2]
-# accept = localhost:5901
-# connect = HOST2:PORT2
-# etc ...
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-server.conf b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-server.conf
deleted file mode 100644
index 8e5dd50..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-server.conf
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# Example SSL stunnel SERVER configuration file. (e.g. for your VNC
-# server on this same machine.)
-#
-# To use this file you may need to edit it. Then you will need
-# to manually start up stunnel using it.
-# (e.g. /path/to/stunnel stunnel-server.conf)
-#
-# This is just an example and is not used by the tools in this package.
-# It is here in case you wanted to see how to add SSL support to any
-# VNC server you have.
-#
-RNDbytes = 2048
-RNDfile = bananarand.bin
-RNDoverwrite = yes
-#
-# Remote client certs could go here:
-# CApath = /path/to/.../crt-dir
-# CAfile = /path/to/.../foo.crt
-# verify = 2
-# My server cert could go here:
-# cert = /path/to/.../my.pem
-#
-[vnc]
-#
-# Set to local listening port number (e.g. 5901 for vnc display 1):
-# so the remote viewers would connect to: yourmachine:1
-#
-accept = 5901
-#
-# Set to localhost:port to connect to VNC server on this same machine:
-# (E.g. you run WinVNC on :0, preferably listening on localhost).
-#
-connect = localhost:5900
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/w98/location.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/w98/location.url
deleted file mode 100644
index eb94b91..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/w98/location.url
+++ /dev/null
@@ -1 +0,0 @@
-ftp://ftp.microsoft.com/Services/TechNet/samples/PS/Win98/Reskit/DIAGNOSE/
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/.cpover b/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/.cpover
deleted file mode 100755
index 45ec5ae..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/.cpover
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-cp -p vncviewer.sh vncviewer
-pwd
-ls -l vncviewer.sh vncviewer
-
-(cd ../Darwin.i386; .cpover)
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vncviewer.sh b/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vncviewer.sh
deleted file mode 100755
index 92dcefb..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vncviewer.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-
-# copy "vncviewer.sh" back over to "vncviewer" in case you delete or overwrite it
-# via build.unix. etc
-
-dir=`dirname "$0"`
-
-if [ "X$SSVNC_DYLD_LIBRARY_PATH" != "X" ]; then
- if [ "X$DYLD_LIBRARY_PATH" = "X" ] ; then
- DYLD_LIBRARY_PATH=$SSVNC_DYLD_LIBRARY_PATH
- else
- DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$SSVNC_DYLD_LIBRARY_PATH
- fi
- export DYLD_LIBRARY_PATH
-fi
-
-if [ "X$DISPLAY" != "X" -a "X$DARWIN_COTVNC" != "X1" ]; then
- "$dir/vncviewer.x11" "$@"
-else
- args=""
- for a in "$@"
- do
- if echo "$a" | grep '^-' > /dev/null; then
- args="$args $a"
- elif echo "$a" | grep ':' > /dev/null; then
- h=`echo "$a" | awk -F: '{print $1}'`
- p=`echo "$a" | awk -F: '{print $2}'`
- if [ "X$p" != "X" ]; then
- if [ $p -lt 5900 ]; then
- p=`expr $p + 5900`
- fi
- fi
- args="$args $h:$p"
- else
- args="$args $a"
- fi
- done
- "$dir/../../MacOSX/Chicken of the VNC.app/Contents/MacOS/Chicken of the VNC" $args
-fi
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.i386/.cpover b/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.i386/.cpover
deleted file mode 100755
index c0080b1..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.i386/.cpover
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-cp -p ../Darwin.Power.Macintosh/vncviewer.sh .
-cp -p vncviewer.sh vncviewer
-pwd
-ls -l vncviewer.sh vncviewer
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc b/x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc
deleted file mode 100755
index a427b42..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-#
-# wrapper for SSH_ONLY mode
-#
-PATH=`dirname "$0"`:$PATH; export PATH
-SSVNC_SSH_ONLY=1; export SSVNC_SSH_ONLY
-exec ssvnc -ssh "$@"
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc
deleted file mode 100755
index 9cd636b..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc
+++ /dev/null
@@ -1,289 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006-2009 by Karl J. Runge <runge@karlrunge.com>
-#
-# ssvnc:
-#
-# A wrapper for ssvnc_cmd using a tcl/tk gui.
-#
-# See ssvnc_cmd for details.
-#
-if [ "X$1" = "X-help" -o "X$1" = "X-h" ]; then
- cat << END
-ssvnc - a GUI wrapper for SSL and SSH VNC connections.
-
-SYNOPSIS
- ssvnc
- ssvnc [host][:display]
- ssvnc [saved-profile-name]
- ssvnc [options] [host-or-profile]
- ssvnc -cmd [ssvnc_cmd-args]
- ssvnc --help
-
-DESCRIPTION
- ssvnc is a tcl/tk gui wrapper that runs on Unix, MacOSX, and Windows.
- It sets up an SSL or SSH tunnel to the remote VNC Server and then
- launches the VNC viewer (either the one provided or another one that
- you have specified) to use that encrypted tunnel to connect to the VNC
- Server. The use of Proxies and Gateways to make the connections is
- implemented.
-
-OPTIONS
- -help, -h Print this help.
-
- --help Starts up the GUI as though the 'Help' button was pressed to
- show the main Help panel.
-
- -cmd [ssvnc_cmd-args]
- Launch the ssvnc_cmd utility command directly (no GUI) with the
- given arguments (for use when ssvnc_cmd is not in one's PATH.)
- If neither ssvnc_cmd nor ssvncviewer is in PATH, one can launch
- the viewer directly via: ssvnc -cmd -viewer [viewer-args]
-
- -profiles
- List the saved SSVNC profiles you have created. A profile is a
- destination host with specific parameter settings.
-
- -list Same as -profiles
-
- -ssh Start in "SSH Only Mode". No SSL aspects are shown. Same as
- running the command sshvnc
-
- -ts Start in "Terminal Services Mode". This is like "SSH Only
- Mode", but simpler and assumes x11vnc is available on the remote
- side to start and manage X and VNC sessions. Same as running
- the command tsvnc
-
- -tso Same as -ts "Terminal Services Mode", however never let the user
- leave this mode (no button to switch modes is provided.) Same
- as SSVNC_TS_ALWAYS=1.
-
- -ssl Force the full GUI Mode: both SSL and SSH. This is the default.
- Same as -ss.
-
- -nv Toggle the "Verify All Certs" button to be off at startup.
-
- -nvb Never show the "Verify All Certs" button. Same as SSVNC_NO_VER-
- IFY_ALL_BUTTON=1.
-
- -bigger
- Make the Profile Selection Dialog window bigger. Same as
- SSVNC_BIGGER_DIALOG=1.
-
- -noenc Start off in a mode where a 'No Encryption' check button is
- present. You can toggle the mode with Ctrl-E. Same as
- SSVNC_DISABLE_ENCRYPTION_BUTTON=1. Or noenc=1 in ~/.ssvncrc.
- Selecting no encryption is the same as the vnc:// and Vnc://
- prefixes described below. The -noenc mode is now the default,
- use -enc or noenc=0 for the opposite behavior.
-
- -killstunnel
- On Windows, automatically terminate the STUNNEL process when the
- viewer exits instead of prompting you (same as killstunnel=1 in
- ssvnc_rc or toggle in Options menu)
-
- -nokillstunnel
- On Windows, disable -killstunnel mode. Same as killstunnel=0 in
- ssvnc_rc or toggle in Options menu. Note that -killstunnel mode
- is now the default.
-
- -mycert /path/to/mycert.pem
- Set the default "MyCert" to be /path/to/mycert.pem. Same as
- -cert. If the file does not exist, ~/.vnc/certs is prefixed and
- tried. You can also set mycert=/path/to/mycert.pem in ~/.ssvncrc
-
- -cacert /path/to/cacert.crt
- Set the default "ServerCert" to be /path/to/cacert.crt. Same as
- -ca. If the file does not exist, ~/.vnc/certs is prefixed and
- tried. You can also set cacert=/path/to/cacert.crt in ~/.ssvncrc
-
- -crl /path/to/mycrl.pem
- Set the default Certificate Revocation List to be
- /path/to/mycrl.pem. If the file does not exist, ~/.vnc/certs is
- prefixed and tried. You can also set crl=/path/to/mycrl.pem in
- ~/.ssvncrc.
-END
- exit 0
-fi
-if [ "X$1" = "X-ssh" ]; then
- if [ "X$2" = "X-help" -o "X$2" = "X-h" ]; then
- cat << END
-sshvnc - a GUI wrapper for SSH VNC connections.
-
-SYNOPSIS
- sshvnc
- sshvnc [host][:display]
- sshvnc [saved-profile-name]
- sshvnc [options] [host-or-profile]
- sshvnc --help
-
-See 'ssvnc $2' and 'ssvnc --help' for more information.
-END
- exit 0
- fi
-fi
-
-if [ "X$1" = "X-ts" -o "X$1" = "X-tso" ]; then
- if [ "X$2" = "X-help" -o "X$2" = "X-h" ]; then
- cat << END
-tsvnc - a GUI wrapper for SSH VNC connections using x11vnc Terminal Services.
-
-SYNOPSIS
- tsvnc
- tsvnc [host][:display]
- tsvnc [saved-profile-name]
- tsvnc [options] [host-or-profile]
- tsvnc --help
-
-See 'ssvnc $2' and 'tsvnc --help' for more information.
-END
- exit 0
- fi
-fi
-
-
-if [ "X$XTERM_PRINT" != "X" ]; then
- XTERM_PRINT=""
- cat > /dev/null
-fi
-if [ "X$1" = "X-bg" ]; then
- shift
- $0 "$@" &
- exit 0
-fi
-
-
-PATH=$PATH:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/openwin/bin:/usr/sfw/bin:/usr/local/bin
-export PATH
-
-if [ "X$FULLNAME" = "XKarl J. Runge" ]; then
- if [ "X$NOPOPUFIX" = "X" ]; then
- VNCVIEWER_POPUP_FIX=1
- export VNCVIEWER_POPUP_FIX
- fi
- PATH=`echo "$PATH" | sed -e 's,runge/bin/override,-------------,'`
-fi
-
-if [ "X$WISH" = "X" ]; then
- WISH=wish
- for try in wish8.4 wish wish8.3 wish8.5 wish8.6
- do
- if type $try > /dev/null 2>&1; then
- WISH=$try
- break
- fi
- done
- export WISH
-fi
-
-
-SSVNC_GUI_CMD="$0 $*"
-export SSVNC_GUI_CMD
-SSVNC_LAUNCH=$SSVNC_GUI_CMD
-export SSVNC_LAUNCH
-
-# work out os.arch platform string and check for binaries:
-#
-name=$UNAME
-if [ "X$name" = "X" ]; then
- name=`uname -sm | sed -e 's/ /./g' -e 's,/.*,,' -e 's/Linux\.i.86/Linux.i686/'`
-fi
-
-dL="-L"
-if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then
- dL="-h"
-fi
-
-f="$0"
-for t in 1 2 3 4 5
-do
- if [ $dL "$f" ]; then
- f0="$f"
- f=`ls -l "$f" | sed -e 's/^.* -> //'`
- if echo "$f" | grep '^/' > /dev/null; then
- :
- else
- f="`dirname "$f0"`/$f"
- fi
- else
- break
- fi
-done
-dir=`dirname "$f"`
-PATH="$dir:$PATH"
-
-nearby=0
-if [ -x "$dir/vncviewer" -a -x "$dir/stunnel" ]; then
- nearby=1
-fi
-if [ "X$name" = "X." ]; then
- :
- #type vncviewer
- #type stunnel
-elif [ ! -d "$dir/$name" -a $nearby = 0 ]; then
- echo
- echo "Cannot find platform dir for your OS `uname -sm`:"
- echo
- echo " $dir/$name"
- echo
- PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin
-
- quit=0
- if type vncviewer >/dev/null 2>/dev/null; then
- :
- else
- echo "vncviewer not found in PATH."
- quit=1
- fi
- if type stunnel >/dev/null 2>/dev/null; then
- :
- else
- echo "stunnel not found in PATH."
- quit=1
- fi
- echo
- if [ "X$quit" = "X1" ]; then
- echo "You can set the \$UNAME env. var. to override the OS setting."
- echo "Or, if available, run the ./build.unix script to build it."
- echo "Or install external \"vncviewer\" and \"stunnel\" packages."
- exit 1
- fi
- echo "Using externel \"vncviewer\" and \"stunnel\" found in PATH."
-else
- STUNNEL=stunnel
- #STUNNEL_EXTRA_OPTS=${STUNNEL_EXTRA_OPTS:-"maxconn = 1"}
- #export STUNNEL STUNNEL_EXTRA_OPTS
- SSVNC_VIEWER_INTERNAL=1
- export SSVNC_VIEWER_INTERNAL
-fi
-
-
-# Put our os.arch and other utils dirs at head of PATH to be sure to
-# pick them up:
-#
-PATH="$dir:$dir/$name:$dir/util:$PATH"
-if echo "$dir" | grep '^/' > /dev/null; then
- :
-else
- dir=`pwd`/$dir
- PATH="$dir:$dir/$name:$dir/util:$PATH"
-fi
-
-SSVNC_BASEDIR="$dir"
-export SSVNC_BASEDIR
-SSVNC_BASEDIRNAME="$dir/$name"
-export SSVNC_BASEDIRNAME
-
-if [ -f "$dir/util/ultraftp.jar" ]; then
- SSVNC_ULTRA_FTP_JAR="$dir/util/ultraftp.jar"
- export SSVNC_ULTRA_FTP_JAR
-fi
-
-if [ "X$1" = "X-cmd" -o "X$1" = "X--cmd" ]; then
- shift
- exec ssvnc_cmd "$@"
-elif [ "X$WISH" = "Xwish" ]; then
- exec ssvnc.tcl "$@"
-else
- exec $WISH $dir/util/ssvnc.tcl "$@"
-fi
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd
deleted file mode 100755
index f84eb58..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd
+++ /dev/null
@@ -1,286 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006-2009 by Karl J. Runge <runge@karlrunge.com>
-#
-# ssvnc_cmd:
-#
-# A wrapper that calls ss_vncviewer to use the enhanced TightVNC viewer.
-#
-# The enhanced TightVNC viewer features are:
-#
-# - SSL support for connections using the co-bundled stunnel program.
-# - rfbNewFBSize VNC support (screen resizing)
-# - cursor alphablending with x11vnc at 32bpp
-# - xgrabserver support for fullscreen mode (for old window mgrs)
-#
-#
-# Your platform (e.g. Linux.i686) is autodetected and enhanced
-# vncviewer and stunnel binaries for it are used (see the ./bin directory).
-#
-# See the build.unix script if your platform is not in this package.
-# You can also set the env. var. UNAME=os.arch to any "os.arch" you want
-# to override the autodetetion.
-#
-# Usage:
-#
-# ssvnc_cmd [ss_vncviewer-args] hostname:N [vncviewer-args]
-#
-# if, instead, this script is named "tightvncviewer" or "-viewer" is the
-# first argument it calls the vncviewer directly (there is no encryption)
-# and must be invoked as:
-#
-# tightvncviewer [vncviewer-args] hostname:N
-# or
-# ssvnc_cmd -viewer [vncviewer-args] hostname:N
-#
-# In both cases, "hostname:N" is the host and VNC display to connect to,
-# e.g. snoopy:0. (-listen N and -appshare N modes works too.)
-#
-# See the script util/ss_vncviewer for details about its arguments:
-#
-# -verify pemfile
-# -mycert pemfile
-# -proxy phost:pport
-# -alpha
-# -grab
-#
-# N.B. if this script is named "tightvncviewer" the vncviewer is called
-# directly, and there won't be any SSL or SSH encryption tunnels.
-#
-# If the *very first* argument is "-cotvnc" then it is assumed you are on
-# Darwin and want to run the Chicken of the VNC viewer via our wrapper.
-#
-#
-# See the TightVNC viewer documentation for on its cmdline arguments.
-#
-# For convenience, here is the TightVNC 1.3dev5 viewer -help output:
-#
-# TightVNC viewer version 1.3dev5
-#
-# Usage: vncviewer [<OPTIONS>] [<HOST>][:<DISPLAY#>]
-# vncviewer [<OPTIONS>] [<HOST>][::<PORT#>]
-# vncviewer [<OPTIONS>] -listen [<DISPLAY#>]
-# vncviewer -help
-#
-# <OPTIONS> are standard Xt options, or:
-# -via <GATEWAY>
-# -shared (set by default)
-# -noshared
-# -viewonly
-# -fullscreen
-# -noraiseonbeep
-# -passwd <PASSWD-FILENAME> (standard VNC authentication)
-# -user <USERNAME> (Unix login authentication)
-# -encodings <ENCODING-LIST> (e.g. "tight copyrect")
-# -bgr233
-# -owncmap
-# -truecolour
-# -depth <DEPTH>
-# -compresslevel <COMPRESS-VALUE> (0..9: 0-fast, 9-best)
-# -quality <JPEG-QUALITY-VALUE> (0..9: 0-low, 9-high)
-# -nojpeg
-# -nocursorshape
-# -x11cursor
-# -autopass
-#
-# Option names may be abbreviated, e.g. -bgr instead of -bgr233.
-# See the manual page for more information.
-#
-# Note: the enhanced tightvnc viewer (SSVNC) has many more options, run
-# this script as "ssvnc_cmd Vnc://a:0 -help" or "tightvncviewer -help"
-# to seem them.
-
-if [ "X$1" = "X-h" -o "X$1" = "X-helpxxx" -o "X$1" = "X--help" ]; then
- tail -n +2 "$0" | sed -e '/^$/ q' -e 's/^#//'
- exit
-fi
-
-# Include /usr/bin... to be sure to get regular utilities:
-#
-PATH=$PATH:/usr/bin:/bin
-export PATH
-
-if [ "X$FULLNAME" = "XKarl J. Runge" ]; then
- if [ "X$NOPOPUFIX" = "X" ]; then
- VNCVIEWER_POPUP_FIX=1
- export VNCVIEWER_POPUP_FIX
- fi
- PATH=`echo "$PATH" | sed -e 's,runge/bin/override,-------------,'`
-fi
-
-# Set this for ss_vncviewer to pick up:
-#
-if [ "X$1" = "X-cotvnc" ]; then
- shift
- DARWIN_COTVNC=1
- export DARWIN_COTVNC
-elif [ "X$DARWIN_COTVNC" = "X" -a "X$DISPLAY" = "X" ]; then
- uname=`uname`
- if [ "X$uname" = "XDarwin" ]; then
- DARWIN_COTVNC=1
- export DARWIN_COTVNC
- fi
-fi
-
-use_ours=0
-if [ "X$VNCVIEWERCMD" = "X" ]; then
- VNCVIEWERCMD="vncviewer"
- export VNCVIEWERCMD
- if [ "X$DARWIN_COTVNC" != "X1" ]; then
- use_ours=1
- fi
-fi
-
-# work out os.arch platform string and check for binaries:
-#
-name=$UNAME
-if [ "X$name" = "X" ]; then
- name=`uname -sm | sed -e 's/ /./g' -e 's,/.*,,' -e 's/Linux\.i.86/Linux.i686/'`
-fi
-
-dL="-L"
-if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then
- dL="-h"
-fi
-
-f="$0"
-for t in 1 2 3 4 5 6
-do
- if [ $dL "$f" ]; then
- f0="$f"
- f=`ls -l "$f" | sed -e 's/^.* -> //'`
- if echo "$f" | grep '^/' > /dev/null; then
- :
- else
- f="`dirname "$f0"`/$f"
- fi
- else
- break
- fi
-done
-dir=`dirname "$f"`
-PATH="$dir:$PATH"
-SSVNC_BASEDIR="$dir"
-export SSVNC_BASEDIR
-SSVNC_BASEDIRNAME="$dir/$name"
-export SSVNC_BASEDIRNAME
-SSVNC_UNAME="$name"
-export SSVNC_UNAME
-
-nearby=0
-if [ -x "$dir/vncviewer" -a -x "$dir/stunnel" ]; then
- nearby=1
-fi
-if [ "X$name" = "X." ]; then
- :
- #type vncviewer
- #type stunnel
-elif [ ! -d "$dir/$name" -a $nearby = 0 ]; then
- echo
- echo "Cannot find platform dir for your OS `uname -sm`:"
- echo
- echo " $dir/$name"
- echo
- PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin
-
- quit=0
- if type vncviewer >/dev/null 2>/dev/null; then
- :
- else
- echo "vncviewer not found in PATH."
- quit=1
- fi
- if type stunnel >/dev/null 2>/dev/null; then
- :
- else
- echo "stunnel not found in PATH."
- quit=1
- fi
- echo
- if [ "X$quit" = "X1" ]; then
- echo "You can set the \$UNAME env. var. to override the OS setting."
- echo "Or, if available, run the ./build.unix script to build it."
- echo "Or install external \"vncviewer\" and \"stunnel\" packages."
- exit 1
- fi
- echo "Using externel \"vncviewer\" and \"stunnel\" found in PATH."
-
-else
- STUNNEL=stunnel
- #STUNNEL_EXTRA_OPTS=${STUNNEL_EXTRA_OPTS:-"maxconn = 1"}
- #export STUNNEL STUNNEL_EXTRA_OPTS
- SSVNC_VIEWER_INTERNAL=1
- export SSVNC_VIEWER_INTERNAL
-fi
-
-if [ "X$DARWIN_COTVNC" != "X1" -a "X$VNCVIEWERCMD" = "Xvncviewer" ]; then
- hstr=`$VNCVIEWERCMD -h 2>&1 | head -5`
- if echo "$hstr" | grep 'SSVNC.*TightVNC.*version 1\.3' > /dev/null; then
- # we need to avoid raw encoding
- use_ours=1
- fi
-fi
-
-# Put our os.arch and other utils dirs at head of PATH to be sure to
-# pick them up:
-#
-PATH="$dir:$dir/$name:$dir/util:$PATH"
-if echo "$dir" | grep '^/' > /dev/null; then
- :
-else
- dir=`pwd`/$dir
- PATH="$dir:$dir/$name:$dir/util:$PATH"
-fi
-
-if [ -f "$dir/util/ultraftp.jar" ]; then
- SSVNC_ULTRA_FTP_JAR="$dir/util/ultraftp.jar"
- export SSVNC_ULTRA_FTP_JAR
-fi
-
-base=`basename "$0"`
-if [ "X$1" = "X-ssl" ]; then
- shift
- base="ssvnc_cmd"
-fi
-
-do_viewer_directly=""
-if [ "X$1" = "X-viewer" ]; then
- do_viewer_directly=1
- shift
-fi
-if [ "X$base" = "Xtightvncviewer" ]; then
- do_viewer_directly=1
-fi
-
-# If ours (and not cotvnc), force the use of tight encoding for localhost
-# redir connection:
-#
-#
-if [ $use_ours = 1 ]; then
- # avoid system vncviewer app-defaults
- #XFILESEARCHPATH="/tmp/path/nowhere"; export XFILESEARCHPATH
-
- SSVNC_USE_OURS=1; export SSVNC_USE_OURS
-
- if [ "X$SSVNC_TURBOVNC" != "X" ]; then
- if echo "$VNCVIEWERCMD" | grep '\.turbovnc' > /dev/null; then
- :
- else
- if type "$VNCVIEWERCMD.turbovnc" > /dev/null 2>/dev/null; then
- VNCVIEWERCMD="$VNCVIEWERCMD.turbovnc"
- fi
- fi
- fi
-
- if [ "X$do_viewer_directly" = "X1" ]; then
- $VNCVIEWERCMD -encodings 'copyrect tight zrle zlib hextile' "$@"
- else
- ss_vncviewer "$@" -encodings 'copyrect tight zrle zlib hextile'
- fi
-else
- if [ "X$do_viewer_directly" = "X1" ]; then
- $VNCVIEWERCMD "$@"
- else
- ss_vncviewer "$@"
- fi
-fi
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc b/x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc
deleted file mode 100755
index acf55c6..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-#
-# wrapper for TS_ONLY mode
-#
-PATH=`dirname "$0"`:$PATH; export PATH
-SSVNC_TS_ONLY=1; export SSVNC_TS_ONLY
-exec ssvnc -ts "$@"
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer
deleted file mode 100755
index b0245af..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer
+++ /dev/null
@@ -1,3635 +0,0 @@
-#!/bin/sh
-#
-# ss_vncviewer: wrapper for vncviewer to use an stunnel SSL tunnel
-# or an SSH tunnel.
-#
-# Copyright (c) 2006-2009 by Karl J. Runge <runge@karlrunge.com>
-#
-# ss_vncviewer is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# ss_vncviewer is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with ss_vncviewer; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-# or see <http://www.gnu.org/licenses/>.
-#
-#
-# You must have stunnel(8) installed on the system and in your PATH
-# (however, see the -ssh option below, in which case you will need ssh(1)
-# installed) Note: stunnel is usually installed in an "sbin" subdirectory.
-#
-# You should have "x11vnc -ssl ..." or "x11vnc -stunnel ..."
-# already running as the VNC server on the remote machine.
-# (or use stunnel on the server side for any other VNC server)
-#
-#
-# Usage: ss_vncviewer [cert-args] host:display <vncviewer-args>
-#
-# e.g.: ss_vncviewer snoopy:0
-# ss_vncviewer snoopy:0 -encodings "copyrect tight zrle hextile"
-#
-# [cert-args] can be:
-#
-# -verify /path/to/cacert.pem
-# -mycert /path/to/mycert.pem
-# -crl /path/to/my_crl.pem (or directory)
-# -proxy host:port
-#
-# -verify specifies a CA cert PEM file (or a self-signed one) for
-# authenticating the VNC server.
-#
-# -mycert specifies this client's cert+key PEM file for the VNC server to
-# authenticate this client.
-#
-# -proxy try host:port as a Web proxy to use the CONNECT method
-# to reach the VNC server (e.g. your firewall requires a proxy).
-#
-# For the "double proxy" case use -proxy host1:port1,host2:port2
-# (the first CONNECT is done through host1:port1 to host2:port2
-# and then a 2nd CONNECT to the destination VNC server.)
-#
-# Use socks://host:port, socks4://host:port, or socks5://host,port
-# to force usage of a SOCKS proxy. Also repeater://host:port and
-# sslrepeater://host:port.
-#
-# -showcert Only fetch the certificate using the 'openssl s_client'
-# command (openssl(1) must in installed). On ssvnc 1.0.27 and
-# later the bundled command 'ultravnc_dsm_helper' is used.
-#
-# See http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca for details on
-# SSL certificates with VNC.
-#
-# A few other args (not related to SSL and certs):
-#
-# -2nd Run the vncviewer a 2nd time if the first connections fails.
-#
-# -ssh Use ssh instead of stunnel SSL. ssh(1) must be installed and you
-# must be able to log into the remote machine via ssh.
-#
-# In this case "host:display" may be of the form "user@host:display"
-# where "user@host" is used for the ssh login (see ssh(1) manpage).
-#
-# If -proxy is supplied it can be of the forms: "gwhost" "gwhost:port"
-# "user@gwhost" or "user@gwhost:port". "gwhost" is an incoming ssh
-# gateway machine (the VNC server is not running there), an ssh -L
-# redir is used to "host" in "host:display" from "gwhost". Any "user@"
-# part must be in the -proxy string (not in "host:display").
-#
-# Under -proxy use "gwhost:port" if connecting to any ssh port
-# other than the default (22). (even for the non-gateway case,
-# -proxy must be used to specify a non-standard ssh port)
-#
-# A "double ssh" can be specified via a -proxy string with the two
-# hosts separated by a comma:
-#
-# [user1@]host1[:port1],[user2@]host2[:port2]
-#
-# in which case a ssh to host1 and thru it via a -L redir a 2nd
-# ssh is established to host2.
-#
-# Examples:
-#
-# ss_vncviewer -ssh bob@bobs-home.net:0
-# ss_vncviewer -ssh -sshcmd 'x11vnc -localhost' bob@bobs-home.net:0
-#
-# ss_vncviewer -ssh -proxy fred@mygate.com:2022 mymachine:0
-# ss_vncviewer -ssh -proxy bob@bobs-home.net:2222 localhost:0
-#
-# ss_vncviewer -ssh -proxy fred@gw-host,fred@peecee localhost:0
-#
-# -sshcmd cmd Run "cmd" via ssh instead of the default "sleep 15"
-# e.g. -sshcmd 'x11vnc -display :0 -localhost -rfbport 5900'
-#
-# -sshargs "args" pass "args" to the ssh process, e.g. -L/-R port redirs.
-#
-# -sshssl Tunnel the SSL connection thru a SSH connection. The tunnel as
-# under -ssh is set up and the SSL connection goes thru it. Use
-# this if you want to have and end-to-end SSL connection but must
-# go thru a SSH gateway host (e.g. not the vnc server). Or use
-# this if you need to tunnel additional services via -R and -L
-# (see -sshargs above).
-#
-# ss_vncviewer -sshssl -proxy fred@mygate.com mymachine:0
-#
-# -listen (or -reverse) set up a reverse connection.
-#
-# -alpha turn on cursor alphablending hack if you are using the
-# enhanced tightvnc vncviewer.
-#
-# -grab turn on XGrabServer hack if you are using the enhanced tightvnc
-# vncviewer (e.g. for fullscreen mode in some windowmanagers like
-# fvwm that do not otherwise work in fullscreen mode)
-#
-#
-# set VNCVIEWERCMD to whatever vncviewer command you want to use.
-#
-VNCIPCMD=${VNCVIEWERCMD:-vncip}
-VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer}
-if [ "X$SSVNC_TURBOVNC" != "X" ]; then
- if echo "$VNCVIEWERCMD" | grep '\.turbovnc' > /dev/null; then
- :
- else
- if type "$VNCVIEWERCMD.turbovnc" > /dev/null 2>/dev/null; then
- VNCVIEWERCMD="$VNCVIEWERCMD.turbovnc"
- fi
- fi
-fi
-#
-# Same for STUNNEL, e.g. set it to /path/to/stunnel or stunnel4, etc.
-#
-
-# turn on verbose debugging output
-if [ "X$SS_DEBUG" != "X" -a "X$SS_DEBUG" != "X0" ]; then
- set -xv
-fi
-
-PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin; export PATH
-
-localhost="localhost"
-if uname | grep Darwin >/dev/null; then
- localhost="127.0.0.1"
-fi
-
-# work out which stunnel to use (debian installs as stunnel4)
-stunnel_set_here=""
-if [ "X$STUNNEL" = "X" ]; then
- check_stunnel=1
- if [ "X$SSVNC_BASEDIRNAME" != "X" ]; then
- if [ -x "$SSVNC_BASEDIRNAME/stunnel" ]; then
- type stunnel > /dev/null 2>&1
- if [ $? = 0 ]; then
- # found ours
- STUNNEL=stunnel
- check_stunnel=0
- fi
- fi
- fi
- if [ "X$check_stunnel" = "X1" ]; then
- type stunnel4 > /dev/null 2>&1
- if [ $? = 0 ]; then
- STUNNEL=stunnel4
- else
- STUNNEL=stunnel
- fi
- fi
- stunnel_set_here=1
-fi
-
-help() {
- tail -n +2 "$0" | sed -e '/^$/ q'
-}
-
-secondtry=""
-gotalpha=""
-use_ssh=""
-use_sshssl=""
-direct_connect=""
-ssh_sleep=15
-
-# sleep longer in -listen mode:
-if echo "$*" | grep '.*-listen' > /dev/null; then
- ssh_sleep=1800
-fi
-
-
-ssh_cmd=""
-# env override of ssh_cmd:
-if [ "X$SS_VNCVIEWER_SSH_CMD" != "X" ]; then
- ssh_cmd="$SS_VNCVIEWER_SSH_CMD"
-fi
-
-ssh_args=""
-showcert=""
-reverse=""
-
-ciphers=""
-anondh="ALL:RC4+RSA:+SSLv2:@STRENGTH"
-anondh_set=""
-stunnel_debug="6"
-if [ "X$SS_DEBUG" != "X" -o "X$SSVNC_VENCRYPT_DEBUG" != "X" -o "X$SSVNC_STUNNEL_DEBUG" != "X" ]; then
- stunnel_debug="7"
-fi
-
-if [ "X$1" = "X-viewerflavor" ]; then
- # special case, try to guess which viewer:
- #
- if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
- echo "unknown"
- exit 0
- fi
- if echo "$VNCVIEWERCMD" | grep -i chicken.of > /dev/null; then
- echo "cotvnc"
- exit 0
- fi
- if echo "$VNCVIEWERCMD" | grep -i ultra > /dev/null; then
- echo "ultravnc"
- exit 0
- fi
- # OK, run it for help output...
- str=`$VNCVIEWERCMD -h 2>&1 | head -n 5`
- if echo "$str" | grep -i 'TightVNC.viewer' > /dev/null; then
- echo "tightvnc"
- elif echo "$str" | grep -i 'VNC viewer version 3' > /dev/null; then
- echo "realvnc3"
- elif echo "$str" | grep -i 'VNC viewer .*Edition 4' > /dev/null; then
- echo "realvnc4"
- elif echo "$str" | grep -i 'RealVNC.Ltd' > /dev/null; then
- echo "realvnc4"
- else
- echo "unknown"
- fi
- exit 0
-fi
-if [ "X$1" = "X-viewerhelp" ]; then
- $VNCVIEWERCMD -h 2>&1
- exit 0
-fi
-
-# grab our cmdline options:
-while [ "X$1" != "X" ]
-do
- case $1 in
- "-verify") shift; verify="$1"
- ;;
- "-mycert") shift; mycert="$1"
- ;;
- "-crl") shift; crl="$1"
- ;;
- "-proxy") shift; proxy="$1"
- ;;
- "-ssh") use_ssh=1
- ;;
- "-sshssl") use_ssh=1
- use_sshssl=1
- ;;
- "-sshcmd") shift; ssh_cmd="$1"
- ;;
- "-sshargs") shift; ssh_args="$1"
- ;;
- "-anondh") ciphers="ciphers=$anondh"
- ULTRAVNC_DSM_HELPER_SHOWCERT_ADH=1
- export ULTRAVNC_DSM_HELPER_SHOWCERT_ADH
- anondh_set=1
- ;;
- "-ciphers") shift; ciphers="ciphers=$1"
- ;;
- "-alpha") gotalpha=1
- ;;
- "-showcert") showcert=1
- ;;
- "-listen") reverse=1
- ;;
- "-reverse") reverse=1
- ;;
- "-2nd") secondtry=1
- ;;
- "-grab") VNCVIEWER_GRAB_SERVER=1; export VNCVIEWER_GRAB_SERVER
- ;;
- "-x11cursor") VNCVIEWER_X11CURSOR=1; export VNCVIEWER_X11CURSOR
- ;;
- "-rawlocal") VNCVIEWER_RAWLOCAL=1; export VNCVIEWER_RAWLOCAL
- ;;
- "-scale") shift; SSVNC_SCALE="$1"; export SSVNC_SCALE
- ;;
- "-onelisten") SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
- ;;
- "-sendclipboard") VNCVIEWER_SEND_CLIPBOARD=1; export VNCVIEWER_SEND_CLIPBOARD
- ;;
- "-sendalways") VNCVIEWER_SEND_ALWAYS=1; export VNCVIEWER_SEND_ALWAYS
- ;;
- "-recvtext") shift; VNCVIEWER_RECV_TEXT="$1"; export VNCVIEWER_RECV_TEXT
- ;;
- "-escape") shift; VNCVIEWER_ESCAPE="$1"; export VNCVIEWER_ESCAPE
- ;;
- "-ssvnc_encodings") shift; VNCVIEWER_ENCODINGS="$1"; export VNCVIEWER_ENCODINGS
- ;;
- "-ssvnc_extra_opts") shift; VNCVIEWERCMD_EXTRA_OPTS="$1"; export VNCVIEWERCMD_EXTRA_OPTS
- ;;
- "-rfbversion") shift; VNCVIEWER_RFBVERSION="$1"; export VNCVIEWER_RFBVERSION
- ;;
- "-nobell") VNCVIEWER_NOBELL=1; export VNCVIEWER_NOBELL
- ;;
- "-popupfix") VNCVIEWER_POPUP_FIX=1; export VNCVIEWER_POPUP_FIX
- ;;
- "-realvnc4") VNCVIEWER_IS_REALVNC4=1; export VNCVIEWER_IS_REALVNC4
- ;;
- "-h"*) help; exit 0
- ;;
- "--h"*) help; exit 0
- ;;
- *) break
- ;;
- esac
- shift
-done
-
-# maxconn is something we added to stunnel, this disables it:
-if [ "X$SS_VNCVIEWER_NO_MAXCONN" != "X" ]; then
- STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
-elif echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
- STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
-elif [ "X$reverse" != "X" ]; then
- STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
-else
- # new way (our patches). other than the above, we set these:
- if [ "X$SKIP_STUNNEL_ONCE" = "X" ]; then
- STUNNEL_ONCE=1; export STUNNEL_ONCE
- fi
- if [ "X$SKIP_STUNNEL_MAX_CLIENTS" = "X" ]; then
- STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS
- fi
-fi
-# always set this one:
-if [ "X$SKIP_STUNNEL_NO_SYSLOG" = "X" ]; then
- STUNNEL_NO_SYSLOG=1; export STUNNEL_NO_SYSLOG
-fi
-
-# this is the -t ssh option (gives better keyboard response thru SSH tunnel)
-targ="-t"
-if [ "X$SS_VNCVIEWER_NO_T" != "X" ]; then
- targ=""
-fi
-
-# set the alpha blending env. hack:
-if [ "X$gotalpha" = "X1" ]; then
- VNCVIEWER_ALPHABLEND=1
- export VNCVIEWER_ALPHABLEND
-else
- NO_ALPHABLEND=1
- export NO_ALPHABLEND
-fi
-
-if [ "X$reverse" != "X" ]; then
- ssh_sleep=1800
- if [ "X$proxy" != "X" ]; then
- # check proxy usage under reverse connection:
- if [ "X$use_ssh" = "X" -a "X$use_sshssl" = "X" ]; then
- echo ""
- if echo "$proxy" | egrep -i "(repeater|vencrypt)://" > /dev/null; then
- :
- else
- echo "*Warning*: SSL -listen and a Web proxy does not make sense."
- sleep 2
- fi
- elif echo "$proxy" | grep "," > /dev/null; then
- :
- else
- echo ""
- echo "*Warning*: -listen and a single proxy/gateway does not make sense."
- sleep 2
- fi
-
- # we now try to PPROXY_LOOP_THYSELF, set this var to disable that.
- #SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
- fi
-fi
-if [ "X$ssh_cmd" = "X" ]; then
- # if no remote ssh cmd, sleep a bit:
- ssh_cmd="sleep $ssh_sleep"
-fi
-
-# this should be a host:display:
-#
-orig="$1"
-shift
-
-dL="-L"
-if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then
- dL="-h"
-fi
-
-have_uvnc_dsm_helper_showcert=""
-if [ "X$showcert" = "X1" -a "X$SSVNC_USE_S_CLIENT" = "X" -a "X$reverse" = "X" ]; then
- if type ultravnc_dsm_helper >/dev/null 2>&1; then
- if ultravnc_dsm_helper -help 2>&1 | grep -w showcert >/dev/null; then
- have_uvnc_dsm_helper_showcert=1
- fi
- fi
-fi
-have_uvnc_dsm_helper_ipv6=""
-if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
- if type ultravnc_dsm_helper >/dev/null 2>&1; then
- if ultravnc_dsm_helper -help 2>&1 | grep -iw ipv6 >/dev/null; then
- have_uvnc_dsm_helper_ipv6=1
- fi
- fi
-fi
-
-rchk() {
- # a kludge to set $RANDOM if we are not bash:
- if [ "X$BASH_VERSION" = "X" ]; then
- RANDOM=`date +%S``sh -c 'echo $$'``ps -elf 2>&1 | sum 2>&1 | awk '{print $1}'`
- fi
-}
-rchk
-
-# a portable, but not absolutely safe, tmp file creator
-mytmp() {
- tf=$1
- if type mktemp > /dev/null 2>&1; then
- # if we have mktemp(1), use it:
- tf2="$tf.XXXXXX"
- tf2=`mktemp "$tf2"`
- if [ "X$tf2" != "X" -a -f "$tf2" ]; then
- if [ "X$DEBUG_MKTEMP" != "X" ]; then
- echo "mytmp-mktemp: $tf2" 1>&2
- fi
- echo "$tf2"
- return
- fi
- fi
- # fallback to multiple cmds:
- rm -rf "$tf" || exit 1
- if [ -d "$tf" ]; then
- echo "tmp file $tf still exists as a directory."
- exit 1
- elif [ $dL "$tf" ]; then
- echo "tmp file $tf still exists as a symlink."
- exit 1
- elif [ -f "$tf" ]; then
- echo "tmp file $tf still exists."
- exit 1
- fi
- touch "$tf" || exit 1
- chmod 600 "$tf" || exit 1
- rchk
- if [ "X$DEBUG_MKTEMP" != "X" ]; then
- echo "mytmp-touch: $tf" 1>&2
- fi
- echo "$tf"
-}
-
-# set up special case of ultravnc single click III mode:
-if echo "$proxy" | egrep "^sslrepeater://" > /dev/null; then
- pstr=`echo "$proxy" | sed -e 's,sslrepeater://,,'`
- pstr1=`echo "$pstr" | sed -e 's/+.*$//'`
- pstr2=`echo "$pstr" | sed -e 's/^[^+]*+//'`
- SSVNC_REPEATER="SCIII=$pstr2"; export SSVNC_REPEATER
- orig=$pstr1
- echo
- echo "reset: SSVNC_REPEATER=$SSVNC_REPEATER orig=$orig proxy=''"
- proxy=""
-fi
-if echo "$proxy" | egrep "vencrypt://" > /dev/null; then
- vtmp="/tmp/ss_handshake${RANDOM}.$$.txt"
- vtmp=`mytmp "$vtmp"`
- SSVNC_PREDIGESTED_HANDSHAKE="$vtmp"
- export SSVNC_PREDIGESTED_HANDSHAKE
- if [ "X$SSVNC_USE_OURS" = "X" ]; then
- NEED_VENCRYPT_VIEWER_BRIDGE=1
- fi
-fi
-if [ "X$SSVNC_USE_OURS" = "X" ]; then
- VNCVIEWERCMD_EXTRA_OPTS=""
-fi
-
-
-# check -ssh and -mycert/-verify conflict:
-if [ "X$use_ssh" = "X1" -a "X$use_sshssl" = "X" ]; then
- if [ "X$mycert" != "X" -o "X$verify" != "X" ]; then
- echo "-mycert and -verify cannot be used in -ssh mode"
- exit 1
- fi
-fi
-
-# direct mode Vnc:// means show no warnings.
-# direct mode vnc:// will show warnings.
-if echo "$orig" | grep '^V[Nn][Cc]://' > /dev/null; then
- SSVNC_NO_ENC_WARN=1
- export SSVNC_NO_ENC_WARN
- orig=`echo "$orig" | sed -e 's/^...:/vnc:/'`
-fi
-
-# interprest the pseudo URL proto:// strings:
-if echo "$orig" | grep '^vnc://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vnc://,,'`
- verify=""
- mycert=""
- crl=""
- use_ssh=""
- use_sshssl=""
- direct_connect=1
-elif echo "$orig" | grep '^vncs://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vncs://,,'`
-elif echo "$orig" | grep '^vncssl://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vncssl://,,'`
-elif echo "$orig" | grep '^vnc+ssl://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vnc.ssl://,,'`
-elif echo "$orig" | grep '^vncssh://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vncssh://,,'`
- use_ssh=1
-elif echo "$orig" | grep '^vnc+ssh://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vnc.ssh://,,'`
- use_ssh=1
-fi
-
-if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
- verify=""
- mycert=""
- crl=""
- use_ssh=""
- use_sshssl=""
- direct_connect=1
- if echo "$SSVNC_ULTRA_DSM" | grep 'noultra:' > /dev/null; then
- SSVNC_NO_ULTRA_DSM=1; export SSVNC_NO_ULTRA_DSM
- fi
-fi
-
-# rsh mode is an internal/secret thing only I use.
-rsh=""
-if echo "$orig" | grep '^rsh://' > /dev/null; then
- use_ssh=1
- rsh=1
- orig=`echo "$orig" | sed -e 's,rsh://,,'`
-elif echo "$orig" | grep '^rsh:' > /dev/null; then
- use_ssh=1
- rsh=1
- orig=`echo "$orig" | sed -e 's,rsh:,,'`
-fi
-
-# play around with host:display port:
-if echo "$orig" | grep ':' > /dev/null; then
- :
-else
- # add or assume :0 if no ':'
- if [ "X$reverse" = "X" ]; then
- orig="$orig:0"
- elif [ "X$orig" = "X" ]; then
- orig=":0"
- fi
-fi
-
-# extract host and disp number:
-
-# try to see if it is ipv6 address:
-ipv6=0
-if echo "$orig" | grep '\[' > /dev/null; then
- # ipv6 [fe80::219:dbff:fee5:3f92%eth1]:5900
- host=`echo "$orig" | sed -e 's/\].*$//' -e 's/\[//'`
- disp=`echo "$orig" | sed -e 's/^.*\]://'`
- ipv6=1
-elif echo "$orig" | grep ':..*:' > /dev/null; then
- # ipv6 fe80::219:dbff:fee5:3f92%eth1:5900
- host=`echo "$orig" | sed -e 's/:[^:]*$//'`
- disp=`echo "$orig" | sed -e 's/^.*://'`
- ipv6=1
-else
- # regular host:port
- host=`echo "$orig" | awk -F: '{print $1}'`
- disp=`echo "$orig" | awk -F: '{print $2}'`
-fi
-
-if [ "X$reverse" != "X" -a "X$STUNNEL_LISTEN" = "X" -a "X$host" != "X" ]; then
- STUNNEL_LISTEN=$host
- echo "set STUNNEL_LISTEN=$STUNNEL_LISTEN"
-fi
-
-if [ "X$host" = "X" ]; then
- host=$localhost
-fi
-
-if [ "X$SSVNC_IPV6" = "X0" ]; then
- # disable checking for it.
- ipv6=0
-#elif [ "X$reverse" != "X" -a "X$ipv6" = "X1" ]; then
-# ipv6=0
-elif [ "X$ipv6" = "X1" ]; then
- :
-elif echo "$host" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null; then
- :
-else
- # regular hostname, can't be sure...
- gout=""
- if type getent > /dev/null 2>/dev/null; then
- gout=`getent hosts "$host" 2>/dev/null`
- fi
- if echo "$gout" | grep ':.*:' > /dev/null; then
- if echo "$gout" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null; then
- :
- else
- echo "ipv6: "`echo "$gout" | grep ':.*:' | head -n 1`
- ipv6=1
- fi
- fi
- if [ "X$ipv6" = "X0" ]; then
- hout=""
- if type host > /dev/null 2>/dev/null; then
- host "$host" >/dev/null 2>&1
- host "$host" >/dev/null 2>&1
- hout=`host "$host" 2>/dev/null`
- fi
- if echo "$hout" | grep -i 'has ipv6 address' > /dev/null; then
- if echo "$hout" | grep -i 'has address' > /dev/null; then
- :
- else
- echo "ipv6: "`echo "$hout" | grep -i 'has ipv6 address' | head -n 1`
- ipv6=1
- fi
- fi
- fi
- if [ "X$ipv6" = "X0" ]; then
- dout=""
- if type dig > /dev/null 2>/dev/null; then
- dout=`dig -t any "$host" 2>/dev/null`
- fi
- if echo "$dout" | grep -i "^$host" | grep '[ ]AAAA[ ]' > /dev/null; then
- if echo "$dout" | grep -i "^$host" | grep '[ ]A[ ]' > /dev/null; then
- :
- else
- echo "ipv6: "`echo "$dout" | grep -i '[ ]AAAA[ ]' | head -n 1`
- ipv6=1
- fi
- fi
- fi
- if [ "X$ipv6" = "X0" ]; then
- sout=`env LOOKUP="$host" \
- perl -e ' eval {use Socket}; exit 0 if $@;
- eval {use Socket6}; exit 0 if $@;
- @res = getaddrinfo($ENV{LOOKUP}, "daytime", AF_UNSPEC, SOCK_STREAM);
- $ipv4 = 0;
- $ipv6 = 0;
- $ip6 = "";
- while (scalar(@res) >= 5) {
- ($family, $socktype, $proto, $saddr, $canon, @res) = @res;
- $ipv4 = 1 if $family == AF_INET;
- $ipv6 = 1 if $family == AF_INET6;
- if ($family == AF_INET6 && $ip6 eq "") {
- my ($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV);
- $ip6 = $host;
- }
- }
- if (! $ipv4 && $ipv6) {
- print "AF_INET6_ONLY: $ENV{LOOKUP}: $ip6\n";
- }
- exit 0;
- ' 2>/dev/null`
- if echo "$sout" | grep AF_INET6_ONLY > /dev/null; then
- echo "$sout"
- ipv6=1
- fi
- fi
-fi
-if [ "X$ipv6" = "X1" ]; then
- echo "ipv6: addr=$host disp=$disp"
-fi
-if [ "X$disp" = "X" ]; then
- port="" # probably -listen mode.
-elif [ $disp -lt 0 ]; then
- # negative means use |n| without question:
- port=`expr 0 - $disp`
-elif [ $disp -lt 200 ]; then
- # less than 200 means 5900+n
- if [ "X$reverse" = "X" ]; then
- port=`expr $disp + 5900`
- else
- port=`expr $disp + 5500`
- fi
-else
- # otherwise use the number directly, e.g. 443, 2345
- port=$disp
-fi
-
-if [ "X$ipv6" = "X1" -a "X$direct_connect" = "X1" ]; then
- if [ "X$proxy" = "X" -a "X$reverse" = "X" ]; then
- if [ "X$SSVNC_ULTRA_DSM" != "X" -a "X$have_uvnc_dsm_helper_ipv6" = "X1" ]; then
- :
- elif [ "X$SSVNC_NO_IPV6_PROXY" != "X" ]; then
- :
- elif [ "X$SSVNC_NO_IPV6_PROXY_DIRECT" != "X" ]; then
- :
- else
- proxy="ipv6://$host:$port"
- echo "direct connect: set proxy=$proxy"
- fi
- fi
-fi
-
-# (possibly) tell the vncviewer to only listen on lo:
-if [ "X$reverse" != "X" ]; then
- if [ "X$direct_connect" = "X" -o "X$proxy" != "X" -o "X$STUNNEL_LISTEN" != "X" ]; then
- VNCVIEWER_LISTEN_LOCALHOST=1
- export VNCVIEWER_LISTEN_LOCALHOST
- fi
-fi
-
-# try to find an open listening port via netstat(1):
-inuse=""
-if uname | grep Linux > /dev/null; then
- inuse=`netstat -ant | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*://'`
-elif uname | grep SunOS > /dev/null; then
- inuse=`netstat -an -f inet -P tcp | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $1}' | sed 's/^.*\.//'`
-elif uname | egrep -i 'bsd|darwin' > /dev/null; then
- inuse=`netstat -ant -f inet | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*\.//'`
-# add others...
-fi
-
-# this is a crude attempt for unique ports tags, etc.
-date_sec=`date +%S`
-
-# these are special cases of no vnc, e.g. sleep or xmessage.
-# these are for using ssvnc as a general port redirector.
-if echo "$VNCVIEWERCMD" | grep '^sleep[ ][ ]*[0-9][0-9]*' > /dev/null; then
- if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then
- p=`echo "$VNCVIEWERCMD" | awk '{print $3}'`
- if [ "X$p" != "X" ]; then
- SS_VNCVIEWER_LISTEN_PORT=$p
- fi
- fi
- p2=`echo "$VNCVIEWERCMD" | awk '{print $2}'`
- VNCVIEWERCMD="eval sleep $p2; echo Local "
-elif echo "$VNCVIEWERCMD" | grep '^xmessage[ ][ ]*[0-9][0-9]*' > /dev/null; then
- if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then
- p=`echo "$VNCVIEWERCMD" | awk '{print $2}'`
- SS_VNCVIEWER_LISTEN_PORT=$p
- fi
-fi
-
-# utility to find a free port to listen on.
-findfree() {
- try0=$1
- try=$try0
- use0=""
-
- if [ "X$SS_VNCVIEWER_LISTEN_PORT" != "X" ]; then
- echo "$SS_VNCVIEWER_LISTEN_PORT"
- return
- fi
- if [ $try -ge 6000 ]; then
- fmax=`expr $try + 1000`
- else
- fmax=6000
- fi
-
- while [ $try -lt $fmax ]
- do
- if [ "X$inuse" = "X" ]; then
- break
- fi
- if echo "$inuse" | grep -w $try > /dev/null; then
- :
- else
- use0=$try
- break
- fi
- try=`expr $try + 1`
- done
- if [ "X$use0" = "X" ]; then
- use0=`expr $date_sec + $try0`
- fi
-
- echo $use0
-}
-
-# utility for exiting; kills some helper processes,
-# removes files, etc.
-final() {
- echo ""
- if [ "X$tmp_cfg" != "X" ]; then
- rm -f $tmp_cfg
- fi
- if [ "X$SS_VNCVIEWER_RM" != "X" ]; then
- rm -f $SS_VNCVIEWER_RM 2>/dev/null
- fi
- if [ "X$tcert" != "X" ]; then
- rm -f $tcert
- fi
- if [ "X$pssh" != "X" ]; then
- echo "Terminating background ssh process"
- echo kill -TERM "$pssh"
- kill -TERM "$pssh" 2>/dev/null
- sleep 1
- kill -KILL "$pssh" 2>/dev/null
- pssh=""
- fi
- if [ "X$stunnel_pid" != "X" ]; then
- echo "Terminating background stunnel process"
- echo kill -TERM "$stunnel_pid"
- kill -TERM "$stunnel_pid" 2>/dev/null
- sleep 1
- kill -KILL "$stunnel_pid" 2>/dev/null
- stunnel_pid=""
- fi
- if [ "X$dsm_pid" != "X" ]; then
- echo "Terminating background ultravnc_dsm_helper process"
- echo kill -TERM "$dsm_pid"
- kill -TERM "$dsm_pid" 2>/dev/null
- sleep 1
- kill -KILL "$dsm_pid" 2>/dev/null
- stunnel_pid=""
- fi
- if [ "X$tail_pid" != "X" ]; then
- kill -TERM $tail_pid
- fi
- if [ "X$tail_pid2" != "X" ]; then
- kill -TERM $tail_pid2
- fi
-}
-
-if [ "X$reverse" = "X" ]; then
- # normal connections try 5930-5999:
- if [ "X$showcert" = "X" ]; then
- use=`findfree 5930`
- else
- # move away from normal place for (possibly many) -showcert
- pstart=`date +%S`
- pstart=`expr 6130 + $pstart + $pstart`
- use=`findfree $pstart`
- fi
- if [ $use -ge 5900 ]; then
- N=`expr $use - 5900`
- else
- N=$use
- fi
-else
- # reverse connections:
- p2=`expr $port + 30`
- use=`findfree $p2`
- if [ $use -ge 5500 ]; then
- N=`expr $use - 5500`
- else
- N=$use
- fi
-fi
-
-# this is for my special use of ss_vncip -> vncip viewer.
-if echo "$0" | grep vncip > /dev/null; then
- VNCVIEWERCMD="$VNCIPCMD"
-fi
-
-if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
- :
-elif [ "X$VNCVIEWERCMD_EXTRA_OPTS" != "X" ]; then
- VNCVIEWERCMD="$VNCVIEWERCMD $VNCVIEWERCMD_EXTRA_OPTS"
-fi
-
-# trick for the undocumented rsh://host:port method.
-rsh_setup() {
- if echo "$ssh_host" | grep '@' > /dev/null; then
- ul=`echo "$ssh_host" | awk -F@ '{print $1}'`
- ul="-l $ul"
- ssh_host=`echo "$ssh_host" | awk -F@ '{print $2}'`
- else
- ul=""
- fi
- ssh_cmd=`echo "$ssh_cmd" | sed -e 's/ -localhost/ /g'`
-}
-
-# trick for the undocumented rsh://host:port method.
-rsh_viewer() {
- trap "final" 0 2 15
- if [ "X$PORT" = "X" ]; then
- exit 1
- elif [ $PORT -ge 5900 ]; then
- vdpy=`expr $PORT - 5900`
- else
- vdpy=":$PORT"
- fi
- stty sane
- echo "$VNCVIEWERCMD" "$@" $ssh_host:$vdpy
- echo ""
- $VNCVIEWERCMD "$@" $ssh_host:$vdpy
- if [ $? != 0 ]; then
- sleep 2
- $VNCVIEWERCMD "$@" $ssh_host:$vdpy
- fi
-}
-
-check_perl() {
- if type "$1" > /dev/null 2>&1; then
- :
- elif [ ! -x "$1" ]; then
- echo ""
- echo "*******************************************************"
- echo "** Problem finding the Perl command '$1': **"
- echo ""
- type "perl"
- echo ""
- echo "** Perhaps you need to install the Perl package. **"
- echo "*******************************************************"
- echo ""
- sleep 5
- fi
-}
-
-# this is the PPROXY tool. used only here for now...
-pcode() {
- tf=$1
- PPROXY_PROXY=$proxy; export PPROXY_PROXY
- PPROXY_DEST="$host:$port"; export PPROXY_DEST
- check_perl /usr/bin/perl
-
- cod='#!/usr/bin/perl
-
-# A hack to glue stunnel to a Web or SOCKS proxy, UltraVNC repeater for
-# client connections.
-# Also acts as a VeNCrypt bridge (by redirecting to stunnel.)
-
-use IO::Socket::INET;
-
-my $have_inet6 = "";
-eval "use IO::Socket::INET6;";
-$have_inet6 = 1 if $@ eq "";
-
-#my $have_sock6 = "";
-#eval "use Socket; use Socket6;";
-#$have_sock6 = 1 if $@ eq "";
-
-if (exists $ENV{PPROXY_LOOP_THYSELF}) {
- # used for reverse vnc, run a repeating outer loop.
- print STDERR "PPROXY_LOOP: $ENV{PPROXY_LOOP_THYSELF}\n";
- my $rm = $ENV{PPROXY_REMOVE};
- my $lp = $ENV{PPROXY_LOOP_THYSELF};
- delete $ENV{PPROXY_REMOVE};
- delete $ENV{PPROXY_LOOP_THYSELF};
- $ENV{PPROXY_LOOP_THYSELF_MASTER} = $$;
- my $pid = $$;
- my $dbg = 0;
- my $c = 0;
- use POSIX ":sys_wait_h";
- while (1) {
- $pid = fork();
- last if ! defined $pid;
- if ($pid eq "0") {
- last;
- }
- $c++;
- print STDERR "\nPPROXY_LOOP: pid=$$ child=$pid count=$c\n";
- while (1) {
- waitpid(-1, WNOHANG);
- fsleep(0.25);
- if (! kill 0, $pid) {
- print STDERR "PPROXY_LOOP: child=$pid gone.\n";
- last;
- }
- print STDERR "PPROXY_LOOP: child=$pid alive.\n" if $dbg;
- if (! -f $lp) {
- print STDERR "PPROXY_LOOP: flag file $lp gone, killing $pid\n";
- kill TERM, $pid;
- fsleep(0.1);
- wait;
- last;
- }
- print STDERR "PPROXY_LOOP: file exists $lp\n" if $dbg;
- }
- last if ! -f $lp;
- fsleep(0.25);
- }
- if ($pid ne "0") {
- unlink($0) if $rm;
- exit 0;
- }
-}
-
-if (exists $ENV{PPROXY_SLEEP} && $ENV{PPROXY_SLEEP} > 0) {
- print STDERR "PPROXY_PID: $$\n";
- sleep $ENV{PPROXY_SLEEP};
-}
-
-foreach my $var (qw(
- PPROXY_DEST
- PPROXY_KILLPID
- PPROXY_LISTEN
- PPROXY_PROXY
- PPROXY_REMOVE
- PPROXY_REPEATER
- PPROXY_REVERSE
- PPROXY_SLEEP
- PPROXY_SOCKS
- PPROXY_VENCRYPT
- PPROXY_VENCRYPT_VIEWER_BRIDGE
- )) {
- if (0 || $ENV{SS_DEBUG} || $ENV{SSVNC_VENCRYPT_DEBUG}) {
- print STDERR "$var: $ENV{$var}\n";
- }
-}
-
-if ($ENV{PPROXY_SOCKS} ne "" && $ENV{PPROXY_PROXY} !~ m,^socks5?://,i) {
- if ($ENV{PPROXY_SOCKS} eq "5") {
- $ENV{PPROXY_PROXY} = "socks5://$ENV{PPROXY_PROXY}";
- } else {
- $ENV{PPROXY_PROXY} = "socks://$ENV{PPROXY_PROXY}";
- }
-}
-
-my $rfbSecTypeAnonTls = 18;
-my $rfbSecTypeVencrypt = 19;
-
-my $rfbVencryptPlain = 256;
-my $rfbVencryptTlsNone = 257;
-my $rfbVencryptTlsVnc = 258;
-my $rfbVencryptTlsPlain = 259;
-my $rfbVencryptX509None = 260;
-my $rfbVencryptX509Vnc = 261;
-my $rfbVencryptX509Plain = 262;
-
-my $handshake_file = "";
-if (exists $ENV{SSVNC_PREDIGESTED_HANDSHAKE}) {
- $handshake_file = $ENV{SSVNC_PREDIGESTED_HANDSHAKE};
-}
-
-my $have_gettimeofday = 0;
-eval "use Time::HiRes;";
-if ($@ eq "") {
- $have_gettimeofday = 1;
-}
-sub gettime {
- my $t = "0.0";
- if ($have_gettimeofday) {
- $t = Time::HiRes::gettimeofday();
- }
- return $t;
-}
-
-my $listen_handle = "";
-my $sock = "";
-my $parent = $$;
-
-my $initial_data = "";
-
-if ($ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}) {
- my ($from, $to) = split(/,/, $ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE});
- do_vencrypt_viewer_bridge($from, $to);
- exit 0;
-}
-
-my ($first, $second, $third) = split(/,/, $ENV{PPROXY_PROXY}, 3);
-my ($mode_1st, $mode_2nd, $mode_3rd) = ("", "", "");
-
-($first, $mode_1st) = url_parse($first);
-
-my ($proxy_host, $proxy_port) = ($first, "");
-if ($proxy_host =~ /^(.*):(\d+)$/) {
- $proxy_host = $1;
- $proxy_port = $2;
-}
-my $connect = $ENV{PPROXY_DEST};
-
-if ($second ne "") {
- ($second, $mode_2nd) = url_parse($second);
-}
-
-if ($third ne "") {
- ($third, $mode_3rd) = url_parse($third);
-}
-
-
-print STDERR "\n";
-print STDERR "PPROXY v0.4: a tool for Web, SOCKS, and UltraVNC proxies and for\n";
-print STDERR "PPROXY v0.4: IPv6 and VNC VeNCrypt bridging.\n";
-print STDERR "proxy_host: $proxy_host\n";
-print STDERR "proxy_port: $proxy_port\n";
-print STDERR "proxy_connect: $connect\n";
-print STDERR "pproxy_params: $ENV{PPROXY_PROXY}\n";
-print STDERR "pproxy_listen: $ENV{PPROXY_LISTEN}\n";
-print STDERR "pproxy_reverse: $ENV{PPROXY_REVERSE}\n";
-print STDERR "io_socket_inet6: $have_inet6\n";
-print STDERR "\n";
-if (! $have_inet6) {
- print STDERR "PPROXY: To enable IPv6 connections, install the IO::Socket::INET6 perl module.\n\n";
-}
-
-if (1) {
- print STDERR "pproxy 1st: $first\t- $mode_1st\n";
- print STDERR "pproxy 2nd: $second\t- $mode_2nd\n";
- print STDERR "pproxy 3rd: $third\t- $mode_3rd\n";
- print STDERR "\n";
-}
-
-sub pdie {
- my $msg = shift;
- kill_proxy_pids();
- die "$msg";
-}
-
-if ($ENV{PPROXY_REVERSE} ne "") {
- my ($rhost, $rport) = ($ENV{PPROXY_REVERSE}, "");
- if ($rhost =~ /^(.*):(\d+)$/) {
- $rhost = $1;
- $rport = $2;
- }
- $rport = 5900 unless $rport;
- my $emsg = "";
- $listen_handle = IO::Socket::INET->new(
- PeerAddr => $rhost,
- PeerPort => $rport,
- Proto => "tcp"
- );
- $emsg = $!;
- if (! $listen_handle && $have_inet6) {
- eval {$listen_handle = IO::Socket::INET6->new(
- PeerAddr => $rhost,
- PeerPort => $rport,
- Proto => "tcp"
- );};
- $emsg .= " / $!";
- }
- if (! $listen_handle) {
- pdie "pproxy: $emsg -- PPROXY_REVERSE\n";
- }
- print STDERR "PPROXY_REVERSE: connected to $rhost $rport\n";
-
-} elsif ($ENV{PPROXY_LISTEN} ne "") {
- my $listen_sock = "";
- my $maxtry = 12;
- my $sleep = 5;
- my $p2 = "";
- my $emsg = "";
- for (my $i=0; $i < $maxtry; $i++) {
- my ($if, $p) = ("", $ENV{PPROXY_LISTEN});
- if ($p =~ /^(.*):(\d+)$/) {
- $if = $1;
- $p = $2;
- }
- $p2 = "*:$p";
- if ($if eq "") {
- $if = "localhost";
- }
- print STDERR "pproxy interface: $if\n";
-
- $emsg = "";
- if (($if eq "INADDR_ANY6" || $if eq "::") && $have_inet6) {
- eval {$listen_sock = IO::Socket::INET6->new(
- Listen => 2,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => "::",
- LocalPort => $p,
- Proto => "tcp"
- );};
- $p2 = ":::$p";
- } elsif ($if =~ /^INADDR_ANY/) {
- $listen_sock = IO::Socket::INET->new(
- Listen => 2,
- ReuseAddr => 1,
- LocalPort => $p,
- Proto => "tcp"
- );
- } elsif (($if eq "INADDR_LOOPBACK6" || $if eq "::1") && $have_inet6) {
- $p2 = "::1:$p";
- eval {$listen_sock = IO::Socket::INET6->new(
- Listen => 2,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => "::1",
- LocalPort => $p,
- Proto => "tcp"
- );};
- $p2 = "::1:$p";
- } else {
- $p2 = "$if:$p";
- $listen_sock = IO::Socket::INET->new(
- Listen => 2,
- ReuseAddr => 1,
- LocalAddr => $if,
- LocalPort => $p,
- Proto => "tcp"
- );
- $emsg = $!;
-
- if (! $listen_sock && $have_inet6) {
- print STDERR "PPROXY_LISTEN: retry with INET6\n";
- eval {$listen_sock = IO::Socket::INET6->new(
- Listen => 2,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => $if,
- LocalPort => $p,
- Proto => "tcp"
- );};
- $emsg .= " / $!";
- }
- }
- if (! $listen_sock) {
- if ($i < $maxtry - 1) {
- warn "pproxy: $emsg $!\n";
- warn "Could not listen on port $p2, retrying in $sleep seconds... (Ctrl-C to quit)\n";
- sleep $sleep;
- }
- } else {
- last;
- }
- }
- if (! $listen_sock) {
- pdie "pproxy: $emsg -- PPROXY_LISTEN\n";
- }
- print STDERR "pproxy: listening on $p2\n";
- my $ip;
- ($listen_handle, $ip) = $listen_sock->accept();
- my $err = $!;
- close $listen_sock;
- if (! $listen_handle) {
- pdie "pproxy: $err\n";
- }
-
- if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) {
- my $sml = $ENV{SSVNC_MULTIPLE_LISTEN};
- if ($sml ne "" && $sml ne "0") {
- setpgrp(0, 0);
- if (fork()) {
- close $viewer_sock;
- wait;
- exit 0;
- }
- if (fork()) {
- close $viewer_sock;
- exit 0;
- }
- setpgrp(0, 0);
- $parent = $$;
- }
- }
-}
-
-$sock = IO::Socket::INET->new(
- PeerAddr => $proxy_host,
- PeerPort => $proxy_port,
- Proto => "tcp"
-);
-
-my $err = "";
-
-if (! $sock && $have_inet6) {
- $err = $!;
-
- eval {$sock = IO::Socket::INET6->new(
- PeerAddr => $proxy_host,
- PeerPort => $proxy_port,
- Proto => "tcp"
- );};
- $err .= " / $!";
-}
-
-if (! $sock) {
- unlink($0) if $ENV{PPROXY_REMOVE};
- pdie "pproxy: $err\n";
-}
-
-unlink($0) if $ENV{PPROXY_REMOVE};
-
-if ($ENV{PPROXY_PROXY} =~ /^vencrypt:/ && $ENV{PPROXY_VENCRYPT_REVERSE}) {
- print STDERR "\nPPROXY: vencrypt+reverse: swapping listen socket with connect socket.\n";
- my $tmp_swap = $sock;
- $sock = $listen_handle;
- $listen_handle = $tmp_swap;
-}
-
-$cur_proxy = $first;
-setmode($mode_1st);
-
-if ($second ne "") {
- connection($second, 1);
-
- setmode($mode_2nd);
- $cur_proxy = $second;
-
- if ($third ne "") {
- connection($third, 2);
- setmode($mode_3rd);
- $cur_proxy = $third;
- connection($connect, 3);
- } else {
- connection($connect, 2);
- }
-} else {
- connection($connect, 1);
-}
-
-sub kill_proxy_pids() {
- if ($ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}) {
- return;
- }
- if ($ENV{PPROXY_KILLPID}) {
- foreach my $p (split(/,/, $ENV{PPROXY_KILLPID})) {
- if ($p =~ /^(\+|-)/) {
- $p = $parent + $p;
- }
- print STDERR "kill TERM, $p (PPROXY_KILLPID)\n";
- kill "TERM", $p;
- }
- }
-}
-
-sub xfer {
- my($in, $out) = @_;
- $RIN = $WIN = $EIN = "";
- $ROUT = "";
- vec($RIN, fileno($in), 1) = 1;
- vec($WIN, fileno($in), 1) = 1;
- $EIN = $RIN | $WIN;
-
- while (1) {
- my $nf = 0;
- while (! $nf) {
- $nf = select($ROUT=$RIN, undef, undef, undef);
- }
- my $len = sysread($in, $buf, 8192);
- if (! defined($len)) {
- next if $! =~ /^Interrupted/;
- print STDERR "pproxy[$$]: $!\n";
- last;
- } elsif ($len == 0) {
- print STDERR "pproxy[$$]: Input is EOF.\n";
- last;
- }
- my $offset = 0;
- my $quit = 0;
- while ($len) {
- my $written = syswrite($out, $buf, $len, $offset);
- if (! defined $written) {
- print STDERR "pproxy[$$]: Output is EOF. $!\n";
- $quit = 1;
- last;
- }
- $len -= $written;
- $offset += $written;
- }
- last if $quit;
- }
- close($out);
- close($in);
- print STDERR "pproxy[$$]: finished xfer.\n";
-}
-
-sub handler {
- print STDERR "pproxy[$$]: got SIGTERM.\n";
- close $listen_handle if $listen_handle;
- close $sock if $sock;
- exit;
-}
-
-sub xfer_both {
- $child = fork;
-
- if (! defined $child) {
- kill_proxy_pids();
- exit 1;
- }
-
- $SIG{TERM} = "handler";
-
- if ($child) {
- if ($listen_handle) {
- print STDERR "pproxy parent[$$] listen_handle -> socket\n";
- xfer($listen_handle, $sock);
- } else {
- print STDERR "pproxy parent[$$] STDIN -> socket\n";
- xfer(STDIN, $sock);
- }
- select(undef, undef, undef, 0.25);
- if (kill 0, $child) {
- select(undef, undef, undef, 0.9);
- if (kill 0, $child) {
- print STDERR "pproxy[$$]: kill TERM child $child\n";
- kill "TERM", $child;
- } else {
- print STDERR "pproxy[$$]: child $child gone.\n";
- }
- }
- } else {
- select(undef, undef, undef, 0.05);
- if ($listen_handle) {
- print STDERR "pproxy child [$$] socket -> listen_handle\n";
- if ($initial_data ne "") {
- my $len = length $initial_data;
- print STDERR "pproxy child [$$] sending initial_data, length $len\n\n";
- syswrite($listen_handle, $initial_data, $len);
- } else {
- print STDERR "\n";
- }
- xfer($sock, $listen_handle);
- } else {
- print STDERR "pproxy child [$$] socket -> STDOUT\n";
- if ($initial_data ne "") {
- my $len = length $initial_data;
- print STDERR "pproxy child [$$] sending initial_data, length $len\n\n";
- syswrite(STDOUT, $initial_data, $len);
- } else {
- print STDERR "\n";
- }
- xfer($sock, STDOUT);
- }
- select(undef, undef, undef, 0.25);
- if (kill 0, $parent) {
- select(undef, undef, undef, 0.8);
- if (kill 0, $parent) {
- print STDERR "pproxy[$$]: kill TERM parent $parent\n";
- kill "TERM", $parent;
- } else {
- print STDERR "pproxy[$$]: parent $parent gone.\n";
- }
- }
- }
-
- kill_proxy_pids();
-}
-
-xfer_both();
-
-exit;
-
-sub fsleep {
- select(undef, undef, undef, shift);
-}
-
-sub url_parse {
- my $hostport = shift;
- my $mode = "http";
- if ($hostport =~ m,^socks4?://(\S*)$,i) {
- $mode = "socks4";
- $hostport = $1;
- } elsif ($hostport =~ m,^socks5://(\S*)$,i) {
- $mode = "socks5";
- $hostport = $1;
- } elsif ($hostport =~ m,^https?://(\S*)$,i) {
- $mode = "http";
- $hostport = $1;
- } elsif ($hostport =~ m,^ipv6://(\S*)$,i) {
- $mode = "ipv6";
- $hostport = $1;
- } elsif ($hostport =~ m,^repeater://(\S*)\+(\S*)$,i) {
- # ultravnc repeater proxy.
- $hostport = $1;
- $mode = "repeater:$2";
- if ($hostport !~ /:\d+$/) {
- $hostport .= ":5900";
- }
- } elsif ($hostport =~ m,^vencrypt://(\S*)$,i) {
- # vencrypt handshake.
- $hostport = $1;
- my $m = "connect";
- if ($hostpost =~ /^(\S+)\+(\S+)$/) {
- $hostport = $1;
- $mode = $2;
- }
- $mode = "vencrypt:$m";
- if ($hostport !~ /:\d+$/) {
- $hostport .= ":5900";
- }
- }
- return ($hostport, $mode);
-}
-
-sub setmode {
- my $mode = shift;
- $ENV{PPROXY_REPEATER} = "";
- $ENV{PPROXY_VENCRYPT} = "";
- if ($mode =~ /^socks/) {
- if ($mode =~ /^socks5/) {
- $ENV{PPROXY_SOCKS} = 5;
- } else {
- $ENV{PPROXY_SOCKS} = 1;
- }
- } elsif ($mode =~ /^ipv6/i) {
- $ENV{PPROXY_SOCKS} = 0;
- } elsif ($mode =~ /^repeater:(.*)/) {
- $ENV{PPROXY_REPEATER} = $1;
- $ENV{PPROXY_SOCKS} = "";
- } elsif ($mode =~ /^vencrypt:(.*)/) {
- $ENV{PPROXY_VENCRYPT} = $1;
- $ENV{PPROXY_SOCKS} = "";
- } else {
- $ENV{PPROXY_SOCKS} = "";
- }
-}
-
-sub connection {
- my ($CONNECT, $w) = @_;
-
- my $con = "";
- my $msg = "";
-
- if ($ENV{PPROXY_SOCKS} eq "5") {
- # SOCKS5
- my ($h, $p) = ($CONNECT, "");
- if ($h =~ /^(.*):(\d+)$/) {
- $h = $1;
- $p = $2;
- }
- $con .= pack("C", 0x05);
- $con .= pack("C", 0x01);
- $con .= pack("C", 0x00);
-
- $msg = "SOCKS5 via $cur_proxy to $h:$p\n\n";
- print STDERR "proxy_request$w: $msg";
-
- syswrite($sock, $con, length($con));
-
- my ($n1, $n2, $n3, $n4, $n5, $n6);
- my ($r1, $r2, $r3, $r4, $r5, $r6);
- my ($s1, $s2, $s3, $s4, $s5, $s6);
-
- $n1 = sysread($sock, $r1, 1);
- $n2 = sysread($sock, $r2, 1);
-
- $s1 = unpack("C", $r1);
- $s2 = unpack("C", $r2);
- if ($s1 != 0x05 || $s2 != 0x00) {
- print STDERR "SOCKS5 fail s1=$s1 s2=$s2 n1=$n1 n2=$n2\n";
- close $sock;
- exit(1);
- }
-
- $con = "";
- $con .= pack("C", 0x05);
- $con .= pack("C", 0x01);
- $con .= pack("C", 0x00);
- $con .= pack("C", 0x03);
- $con .= pack("C", length($h));
- $con .= $h;
- $con .= pack("C", $p >> 8);
- $con .= pack("C", $p & 0xff);
-
- syswrite($sock, $con, length($con));
-
- $n1 = sysread($sock, $r1, 1);
- $n2 = sysread($sock, $r2, 1);
- $n3 = sysread($sock, $r3, 1);
- $n4 = sysread($sock, $r4, 1);
- $s1 = unpack("C", $r1);
- $s2 = unpack("C", $r2);
- $s3 = unpack("C", $r3);
- $s4 = unpack("C", $r4);
-
- if ($s4 == 0x1) {
- sysread($sock, $r5, 4 + 2);
- } elsif ($s4 == 0x3) {
- sysread($sock, $r5, 1);
- $s5 = unpack("C", $r5);
- sysread($sock, $r6, $s5 + 2);
- } elsif ($s4 == 0x4) {
- sysread($sock, $r5, 16 + 2);
- }
-
- if ($s1 != 0x5 || $s2 != 0x0 || $s3 != 0x0) {
- print STDERR "SOCKS5 failed: s1=$s1 s2=$s2 s3=$s3 s4=$s4 n1=$n1 n2=$n2 n3=$n3 n4=$n4\n";
- close $sock;
- exit(1);
- }
-
- } elsif ($ENV{PPROXY_SOCKS} eq "1") {
- # SOCKS4 SOCKS4a
- my ($h, $p) = ($CONNECT, "");
- if ($h =~ /^(.*):(\d+)$/) {
- $h = $1;
- $p = $2;
- }
- $con .= pack("C", 0x04);
- $con .= pack("C", 0x01);
- $con .= pack("n", $p);
-
- my $SOCKS_4a = 0;
- if ($h eq "localhost" || $h eq "127.0.0.1") {
- $con .= pack("C", 127);
- $con .= pack("C", 0);
- $con .= pack("C", 0);
- $con .= pack("C", 1);
- } elsif ($h =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
- $con .= pack("C", $1);
- $con .= pack("C", $2);
- $con .= pack("C", $3);
- $con .= pack("C", $4);
- } else {
- $con .= pack("C", 0);
- $con .= pack("C", 0);
- $con .= pack("C", 0);
- $con .= pack("C", 3);
- $SOCKS_4a = 1;
- }
-
- $con .= "nobody";
- $con .= pack("C", 0);
-
- $msg = "SOCKS4 via $cur_proxy to $h:$p\n\n";
- if ($SOCKS_4a) {
- $con .= $h;
- $con .= pack("C", 0);
- $msg =~ s/SOCKS4/SOCKS4a/;
- }
- print STDERR "proxy_request$w: $msg";
- syswrite($sock, $con, length($con));
-
- my $ok = 1;
- for (my $i = 0; $i < 8; $i++) {
- my $c;
- sysread($sock, $c, 1);
- my $s = unpack("C", $c);
- if ($i == 0) {
- $ok = 0 if $s != 0x0;
- } elsif ($i == 1) {
- $ok = 0 if $s != 0x5a;
- }
- }
- if (! $ok) {
- print STDERR "SOCKS4 failed.\n";
- close $sock;
- exit(1);
- }
- } elsif ($ENV{PPROXY_SOCKS} eq "0") {
- # hack for ipv6 "proxy", nothing to do, assume INET6 call worked.
- ;
- } elsif ($ENV{PPROXY_REPEATER} ne "") {
- my $rep = $ENV{PPROXY_REPEATER};
- print STDERR "repeater: $rep\n";
- $rep .= pack("x") x 250;
- syswrite($sock, $rep, 250);
-
- my $rfb = "";
-
- my $ok = 1;
- for (my $i = 0; $i < 12; $i++) {
- my $c;
- last if $ENV{PPROXY_GENERIC_REPEATER};
- sysread($sock, $c, 1);
- print STDERR $c;
- $rfb .= $c;
- }
- if ($rfb ne "" && $rfb !~ /^RFB 000\.000/) {
- $initial_data = $rfb;
- $rfb =~ s/\n//g;
- print STDERR "detected non-UltraVNC repeater; forwarding \"$rfb\"\nlength: ", length($initial_data), "\n";
- }
- } elsif ($ENV{PPROXY_VENCRYPT} ne "") {
- my $vencrypt = $ENV{PPROXY_VENCRYPT};
- vencrypt_dialog($vencrypt);
-
- } else {
- # Web Proxy:
- $con = "CONNECT $CONNECT HTTP/1.1\r\n";
- $con .= "Host: $CONNECT\r\n";
- $con .= "Connection: close\r\n\r\n";
- $msg = $con;
-
- print STDERR "proxy_request$w: via $cur_proxy:\n$msg";
- syswrite($sock, $con, length($con));
-
- my $rep = "";
- my $n = 0;
- while ($rep !~ /\r\n\r\n/ && $n < 30000) {
- my $c;
- sysread($sock, $c, 1);
- print STDERR $c;
- $rep .= $c;
- $n++;
- }
- if ($rep !~ m,HTTP/.* 200,) {
- print STDERR "HTTP CONNECT failed.\n";
- close $sock;
- exit(1);
- }
- }
-}
-
-sub vdie {
- append_handshake("done\n");
- close $sock;
- kill_proxy_pids();
- exit(1);
-}
-
-sub anontls_handshake {
- my ($vmode, $db) = @_;
-
- print STDERR "\nPPROXY: Doing ANONTLS Handshake\n";
-
- my $psec = pack("C", $rfbSecTypeAnonTls);
- syswrite($sock, $psec, 1);
-
- append_handshake("done\n");
-}
-
-sub vencrypt_handshake {
-
- my ($vmode, $db) = @_;
-
- print STDERR "\nPPROXY: Doing VeNCrypt Handshake\n";
-
- my $psec = pack("C", $rfbSecTypeVencrypt);
-
- if (exists $ENV{SSVNC_TEST_SEC_TYPE}) {
- my $fake = $ENV{SSVNC_TEST_SEC_TYPE};
- print STDERR "PPROXY: sending sec-type: $fake\n";
- $psec = pack("C", $fake);
- }
-
- syswrite($sock, $psec, 1);
-
- my $vmajor;
- my $vminor;
- sysread($sock, $vmajor, 1);
- sysread($sock, $vminor, 1);
-
- vdie if $vmajor eq "" || $vminor eq "";
-
- $vmajor = unpack("C", $vmajor);
- $vminor = unpack("C", $vminor);
- print STDERR "server vencrypt version $vmajor.$vminor\n" if $db;
-
- if (exists $ENV{SSVNC_TEST_SEC_TYPE}) {
- print STDERR "PPROXY: continuing on in test mode.\n";
- } else {
- vdie if $vmajor ne 0;
- vdie if $vminor < 2;
- }
-
- $vmajor = pack("C", 0);
- $vminor = pack("C", 2);
- append_handshake("subversion=0.2\n");
-
- syswrite($sock, $vmajor, 1);
- syswrite($sock, $vminor, 1);
-
- my $result;
- sysread($sock, $result, 1);
- print STDERR "result empty\n" if $db && $result eq "";
-
- vdie if $result eq "";
- $result = unpack("C", $result);
- print STDERR "result=$result\n" if $db;
-
- vdie if $result ne 0;
-
- my $nsubtypes;
- sysread($sock, $nsubtypes, 1);
-
- vdie if $nsubtypes eq "";
- $nsubtypes = unpack("C", $nsubtypes);
- print STDERR "nsubtypes=$nsubtypes\n" if $db;
-
- my %subtypes;
-
- for (my $i = 0; $i < $nsubtypes; $i++) {
- my $subtype = "";
- sysread($sock, $subtype, 4);
- vdie if length($subtype) != 4;
-
- # XXX fix 64bit.
- $subtype = unpack("N", $subtype);
- print STDERR "subtype: $subtype\n" if $db;
- $subtypes{$subtype} = 1;
- append_handshake("sst$i=$subtype\n");
- }
-
- my $subtype = 0;
- if (exists $subtypes{$rfbVencryptX509None}) {
- $subtype = $rfbVencryptX509None;
- print STDERR "selected rfbVencryptX509None\n" if $db;
- } elsif (exists $subtypes{$rfbVencryptX509Vnc}) {
- $subtype = $rfbVencryptX509Vnc;
- print STDERR "selected rfbVencryptX509Vnc\n" if $db;
- } elsif (exists $subtypes{$rfbVencryptX509Plain}) {
- $subtype = $rfbVencryptX509Plain;
- print STDERR "selected rfbVencryptX509Plain\n" if $db;
- } elsif (exists $subtypes{$rfbVencryptTlsNone}) {
- $subtype = $rfbVencryptTlsNone;
- print STDERR "selected rfbVencryptTlsNone\n" if $db;
- } elsif (exists $subtypes{$rfbVencryptTlsVnc}) {
- $subtype = $rfbVencryptTlsVnc;
- print STDERR "selected rfbVencryptTlsVnc\n" if $db;
- } elsif (exists $subtypes{$rfbVencryptTlsPlain}) {
- $subtype = $rfbVencryptTlsPlain;
- print STDERR "selected rfbVencryptTlsPlain\n" if $db;
- }
-
- if (exists $ENV{SSVNC_TEST_SEC_SUBTYPE}) {
- my $fake = $ENV{SSVNC_TEST_SEC_SUBTYPE};
- print STDERR "PPROXY: sending sec-subtype: $fake\n";
- $subtype = $fake;
- }
-
- append_handshake("subtype=$subtype\n");
-
- my $pst = pack("N", $subtype);
- syswrite($sock, $pst, 4);
-
- if (exists $ENV{SSVNC_TEST_SEC_SUBTYPE}) {
- print STDERR "PPROXY: continuing on in test mode.\n";
- } else {
- vdie if $subtype == 0;
- }
-
- my $ok;
- sysread($sock, $ok, 1);
- $ok = unpack("C", $ok);
- print STDERR "ok=$ok\n" if $db;
-
- append_handshake("done\n");
-
- vdie if $ok == 0;
-}
-
-sub vencrypt_dialog {
- my $vmode = shift;
- my $db = 0;
-
- $db = 1 if exists $ENV{SS_DEBUG};
- $db = 1 if exists $ENV{SSVNC_VENCRYPT_DEBUG};
-
- append_handshake("mode=$vmode\n");
-
- my $server_rfb = "";
- #syswrite($sock, $rep, 250);
- for (my $i = 0; $i < 12; $i++) {
- my $c;
- sysread($sock, $c, 1);
- $server_rfb .= $c;
- print STDERR $c;
- }
- print STDERR "server_rfb: $server_rfb\n" if $db;
- append_handshake("server=$server_rfb");
-
- my $minor = "";
- if ($server_rfb =~ /^RFB 003\.(\d+)/) {
- $minor = $1;
- } else {
- vdie;
- }
- my $viewer_rfb = "RFB 003.008\n";
- if ($minor < 7) {
- vdie;
- } elsif ($minor == 7) {
- $viewer_rfb = "RFB 003.007\n";
- }
- my $nsec;
- my $t1 = gettime();
- my $t0 = gettime();
-
- syswrite($sock, $viewer_rfb, 12);
- sysread($sock, $nsec, 1);
-
- $t1 = gettime();
- $t1 = sprintf("%.6f", $t1 - $t0);
-
- append_handshake("viewer=$viewer_rfb");
- append_handshake("latency=$t1\n");
-
- vdie if $nsec eq "";
-
- $nsec = unpack("C", $nsec);
-
- print STDERR "nsec: $nsec\n" if $db;
- vdie if $nsec eq 0 || $nsec > 100;
-
- my %sectypes = ();
-
- for (my $i = 0; $i < $nsec; $i++) {
- my $sec;
- sysread($sock, $sec, 1);
- vdie if $sec eq "";
- $sec = unpack("C", $sec);
- print STDERR "sec: $sec\n" if $db;
- $sectypes{$sec} = 1;
- }
-
- if (exists $sectypes{$rfbSecTypeVencrypt}) {
- print STDERR "found rfbSecTypeVencrypt\n" if $db;
- append_handshake("sectype=$rfbSecTypeVencrypt\n");
- vencrypt_handshake($vmode, $db);
- } elsif (exists $sectypes{$rfbSecTypeAnonTls}) {
- print STDERR "found rfbSecTypeAnonTls\n" if $db;
- append_handshake("sectype=$rfbSecTypeAnonTls\n");
- anontls_handshake($vmode, $db);
- } else {
- print STDERR "No supported sec-type found\n" if $db;
- vdie;
- }
-}
-
-sub append_handshake {
- my $str = shift;
- if ($handshake_file) {
- if (open(HSF, ">>$handshake_file")) {
- print HSF $str;
- close HSF;
- }
- }
-}
-
-sub do_vencrypt_viewer_bridge {
- my ($listen, $connect) = @_;
- print STDERR "\npproxy: starting vencrypt_viewer_bridge[$$]: $listen \-> $connect\n";
- my $db = 0;
- my $backwards = 0;
- if ($listen < 0) {
- $backwards = 1;
- $listen = -$listen;
- }
- if ($handshake_file eq "") {
- die "pproxy: vencrypt_viewer_bridge[$$]: no SSVNC_PREDIGESTED_HANDSHAKE\n";
- }
- my $listen_sock;
- my $maxtry = 12;
- my $sleep = 5;
- for (my $i=0; $i < $maxtry; $i++) {
- $listen_sock = IO::Socket::INET->new(
- Listen => 2,
- ReuseAddr => 1,
- LocalAddr => "127.0.0.1",
- LocalPort => $listen,
- Proto => "tcp"
- );
- if (! $listen_sock) {
- if ($i < $maxtry - 1) {
- warn "pproxy: vencrypt_viewer_bridge[$$]: $!\n";
- warn "Could not listen on port $listen, retrying in $sleep seconds... (Ctrl-C to quit)\n";
- sleep $sleep;
- }
- } else {
- last;
- }
- }
- if (! $listen_sock) {
- die "pproxy: vencrypt_viewer_bridge[$$]: $!\n";
- }
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: listening on port $listen\n\n";
- my ($viewer_sock, $ip) = $listen_sock->accept();
- my $err = $!;
- close $listen_sock;
- if (! $viewer_sock) {
- die "pproxy: vencrypt_viewer_bridge[$$]: $err\n";
- }
- if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) {
- my $sml = $ENV{SSVNC_MULTIPLE_LISTEN};
- if ($sml ne "" && $sml ne "0") {
- setpgrp(0, 0);
- if (fork()) {
- close $viewer_sock;
- wait;
- exit 0;
- }
- if (fork()) {
- close $viewer_sock;
- exit 0;
- }
- setpgrp(0, 0);
- $parent = $$;
- }
- }
- print STDERR "vencrypt_viewer_bridge[$$]: viewer_sock $viewer_sock\n" if $db;
-
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: connecting to 127.0.0.1:$connect\n";
- my $server_sock = IO::Socket::INET->new(
- PeerAddr => "127.0.0.1",
- PeerPort => $connect,
- Proto => "tcp"
- );
- print STDERR "vencrypt_viewer_bridge[$$]: server_sock $server_sock\n" if $db;
- if (! $server_sock) {
- my $err = $!;
- die "pproxy: vencrypt_viewer_bridge[$$]: $err\n";
- }
-
- if ($backwards) {
- print STDERR "vencrypt_viewer_bridge[$$]: reversing roles of viewer and server.\n";
- my $t = $viewer_sock;
- $viewer_sock = $server_sock;
- $server_sock = $t;
- }
-
- my %hs = ();
- my $dt = 0.2;
- my $slept = 0.0;
- while ($slept < 20.0) {
- select(undef, undef, undef, $dt);
- $slept += $dt;
- if (-f $handshake_file && open(HSF, "<$handshake_file")) {
- my $done = 0;
- %hs = ();
- my $str = "";
- while (<HSF>) {
- print STDERR "vencrypt_viewer_bridge[$$]: $_" if $ENV{VENCRYPT_VIEWER_BRIDGE_DEBUG};
- $str .= "vencrypt_viewer_bridge[$$]: $_";
- chomp;
- if ($_ eq "done") {
- $done = 1;
- } else {
- my ($k, $v) = split(/=/, $_, 2);
- if ($k ne "" && $v ne "") {
- $hs{$k} = $v;
- }
- }
- }
- close HSF;
- if ($done) {
- print STDERR "\n" . $str;
- last;
- }
- }
- }
- if (! exists $hs{server}) {
- $hs{server} = "RFB 003.008";
- }
- if (! exists $hs{sectype}) {
- unlink($handshake_file);
- die "pproxy: vencrypt_viewer_bridge[$$]: no sectype.\n";
- }
- syswrite($viewer_sock, "$hs{server}\n", length($hs{server}) + 1);
- my $viewer_rfb = "";
- for (my $i = 0; $i < 12; $i++) {
- my $c;
- sysread($viewer_sock, $c, 1);
- $viewer_rfb .= $c;
- print STDERR $c;
- }
- my $viewer_major = 3;
- my $viewer_minor = 8;
- if ($viewer_rfb =~ /RFB (\d+)\.(\d+)/) {
- $viewer_major = $1;
- $viewer_minor = $2;
- }
- my $u0 = pack("C", 0);
- my $u1 = pack("C", 1);
- my $u2 = pack("C", 2);
- if ($hs{sectype} == $rfbSecTypeAnonTls) {
- unlink($handshake_file);
- print STDERR "\npproxy: vencrypt_viewer_bridge[$$]: rfbSecTypeAnonTls\n";
- if ($viewer_major > 3 || $viewer_minor >= 7) {
- ; # setup ok, proceed to xfer.
- } else {
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: faking RFB version 3.3 to viewer.\n";
- my $n;
- sysread($server_sock, $n, 1);
- $n = unpack("C", $n);
- if ($n == 0) {
- die "pproxy: vencrypt_viewer_bridge[$$]: nsectypes == $n.\n";
- }
- my %types;
- for (my $i = 0; $i < $n; $i++) {
- my $t;
- sysread($server_sock, $t, 1);
- $t = unpack("C", $t);
- $types{$t} = 1;
- }
- my $use = 1; # None
- if (exists $types{1}) {
- $use = 1; # None
- } elsif (exists $types{2}) {
- $use = 2; # VncAuth
- } else {
- die "pproxy: vencrypt_viewer_bridge[$$]: no valid sectypes" . join(",", keys %types) . "\n";
- }
-
- # send 4 bytes sectype to viewer:
- # (note this should be MSB, network byte order...)
- my $up = pack("C", $use);
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $up, 1);
- # and tell server the one we selected:
- syswrite($server_sock, $up, 1);
- if ($use == 1) {
- # even None has security result, so read it here and discard it.
- my $sr = "";
- sysread($server_sock, $sr, 4);
- }
- }
- } elsif ($hs{sectype} == $rfbSecTypeVencrypt) {
- print STDERR "\npproxy: vencrypt_viewer_bridge[$$]: rfbSecTypeVencrypt\n";
- if (! exists $hs{subtype}) {
- unlink($handshake_file);
- die "pproxy: vencrypt_viewer_bridge[$$]: no subtype.\n";
- }
- my $fake_type = "None";
- my $plain = 0;
- my $sub_type = $hs{subtype};
- if ($sub_type == $rfbVencryptTlsNone) {
- $fake_type = "None";
- } elsif ($sub_type == $rfbVencryptTlsVnc) {
- $fake_type = "VncAuth";
- } elsif ($sub_type == $rfbVencryptTlsPlain) {
- $fake_type = "None";
- $plain = 1;
- } elsif ($sub_type == $rfbVencryptX509None) {
- $fake_type = "None";
- } elsif ($sub_type == $rfbVencryptX509Vnc) {
- $fake_type = "VncAuth";
- } elsif ($sub_type == $rfbVencryptX509Plain) {
- $fake_type = "None";
- $plain = 1;
- }
- if ($plain) {
- if (!open(W, ">$handshake_file")) {
- unlink($handshake_file);
- die "pproxy: vencrypt_viewer_bridge[$$]: $handshake_file $!\n";
- }
- print W <<"END";
-
- proc print_out {} {
- global user pass env
-
- if [info exists env(SSVNC_UP_DEBUG)] {
- toplevel .b
- button .b.b -text "user=\$user pass=\$pass" -command {destroy .b}
- pack .b.b
- update
- tkwait window .b
- }
-
- if [info exists env(SSVNC_UP_FILE)] {
- set fh ""
- catch {set fh [open \$env(SSVNC_UP_FILE) w]}
- if {\$fh != ""} {
- puts \$fh user=\$user\\npass=\$pass
- flush \$fh
- close \$fh
- return
- }
- }
- puts stdout user=\$user\\npass=\$pass
- flush stdout
- }
-
- proc center_win {w} {
- update
- set W [winfo screenwidth \$w]
- set W [expr \$W + 1]
- wm geometry \$w +\$W+0
- update
- set x [expr [winfo screenwidth \$w]/2 - [winfo width \$w]/2]
- set y [expr [winfo screenheight \$w]/2 - [winfo height \$w]/2]
-
- wm geometry \$w +\$x+\$y
- wm deiconify \$w
- update
- }
-
- wm withdraw .
-
- global env
- set up {}
- if [info exists env(SSVNC_UNIXPW)] {
- set rm 0
- set up \$env(SSVNC_UNIXPW)
- if [regexp {^rm:} \$up] {
- set rm 1
- regsub {^rm:} \$up {} up
- }
- if [file exists \$up] {
- set fh ""
- set f \$up
- catch {set fh [open \$up r]}
- if {\$fh != ""} {
- gets \$fh u
- gets \$fh p
- close \$fh
- set up "\$u@\$p"
- }
- if {\$rm} {
- catch {file delete \$f}
- }
- }
- } elseif [info exists env(SSVNC_VENCRYPT_USERPASS)] {
- set up \$env(SSVNC_VENCRYPT_USERPASS)
- }
- #puts stderr up=\$up
- if {\$up != ""} {
- if [regexp {@} \$up] {
- global user pass
- set user \$up
- set pass \$up
- regsub {@.*\$} \$user "" user
- regsub {^[^@]*@} \$pass "" pass
- print_out
- exit
- }
- }
-
- wm title . {VeNCrypt Viewer Bridge User/Pass}
-
- set user {}
- set pass {}
-
- label .l -text {SSVNC VeNCrypt Viewer Bridge}
-
- frame .f0
- frame .f0.fL
- label .f0.fL.la -text {Username: }
- label .f0.fL.lb -text {Password: }
-
- pack .f0.fL.la .f0.fL.lb -side top
-
- frame .f0.fR
- entry .f0.fR.ea -width 24 -textvariable user
- entry .f0.fR.eb -width 24 -textvariable pass -show *
-
- pack .f0.fR.ea .f0.fR.eb -side top -fill x
-
- pack .f0.fL -side left
- pack .f0.fR -side right -expand 1 -fill x
-
- button .no -text Cancel -command {destroy .}
- button .ok -text Done -command {print_out; destroy .}
-
- center_win .
- pack .l .f0 .no .ok -side top -fill x
- update
- wm deiconify .
-
- bind .f0.fR.ea <Return> {focus .f0.fR.eb}
- bind .f0.fR.eb <Return> {print_out; destroy .}
- focus .f0.fR.ea
-
- wm resizable . 1 0
- wm minsize . [winfo reqwidth .] [winfo reqheight .]
-END
- close W;
-
- #system("cat $handshake_file");
- my $w = "wish";
- if ($ENV{WISH}) {
- $w = $ENV{WISH};
- }
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: prompt VencryptPlain user and passwd.\n";
- my $res = "";
- if (`uname` =~ /Darwin/) {
- my $mtmp = `mktemp /tmp/hsup.XXXXXX`;
- chomp $mtmp;
- system("env SSVNC_UP_FILE=$mtmp $w $handshake_file");
- $res = `cat $mtmp`;
- unlink $mtmp;
- } else {
- $res = `$w $handshake_file`;
- }
- my $user = "";
- my $pass = "";
- if ($res =~ /user=(\S*)/) {
- $user = $1;
- }
- if ($res =~ /pass=(\S*)/) {
- $pass = $1;
- }
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: sending VencryptPlain user and passwd.\n";
- my $ulen = pack("C", length($user));
- my $plen = pack("C", length($pass));
- # (note this should be MSB, network byte order...)
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $ulen, 1);
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $plen, 1);
- syswrite($server_sock, $user, length($user));
- syswrite($server_sock, $pass, length($pass));
- }
- unlink($handshake_file);
-
- my $ft = 0;
- if ($fake_type eq "None") {
- $ft = 1;
- } elsif ($fake_type eq "VncAuth") {
- $ft = 2;
- } else {
- die "pproxy: vencrypt_viewer_bridge[$$]: unknown fake type: $fake_type\n";
- }
- my $fp = pack("C", $ft);
- if ($viewer_major > 3 || $viewer_minor >= 7) {
- syswrite($viewer_sock, $u1, 1);
- syswrite($viewer_sock, $fp, 1);
- my $cr;
- sysread($viewer_sock, $cr, 1);
- $cr = unpack("C", $cr);
- if ($cr != $ft) {
- die "pproxy: vencrypt_viewer_bridge[$$]: client selected wrong type: $cr / $ft\n";
- }
- } else {
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: faking RFB version 3.3 to viewer.\n";
- # send 4 bytes sect type to viewer:
- # (note this should be MSB, network byte order...)
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $fp, 1);
- if ($ft == 1) {
- # even None has security result, so read it here and discard it.
- my $sr = "";
- sysread($server_sock, $sr, 4);
- }
- }
- }
-
- $listen_handle = $viewer_sock;
- $sock = $server_sock;
-
- xfer_both();
-}
-'
- # '
- # xpg_echo will expand \n \r, etc.
- # try to unset and then test for it.
- if type shopt > /dev/null 2>&1; then
- shopt -u xpg_echo >/dev/null 2>&1
- fi
- v='print STDOUT "abc\n";'
- echo "$v" > $tf
- chmod 700 $tf
-
- lc=`wc -l $tf | awk '{print $1}'`
- if [ "X$lc" = "X1" ]; then
- echo "$cod" > $tf
- else
- printf "%s" "$cod" > $tf
- echo "" >> $tf
- fi
- # prime perl
- perl -e 'use IO::Socket::INET; select(undef, undef, undef, 0.01)' >/dev/null 2>&1
-}
-
-# make_tcert is no longer invoked via the ssvnc gui (Listen mode).
-# make_tcert is for testing only now via -mycert BUILTIN
-make_tcert() {
- tcert="/tmp/ss_vnc_viewer_tcert${RANDOM}.$$"
- tcert=`mytmp "$tcert"`
- cat > $tcert <<END
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAvkfXxb0wcxgrjV2ziFikjII+ze8iKcTBt47L0GM/c21efelN
-+zZpJUUXLu4zz8Ryq8Q+sQgfNy7uTOpN9bUUaOk1TnD7gaDQnQWiNHmqbW2kL+DS
-OKngJVPo9dETAS8hf7+D1e1DBZxjTc1a4RQqWJixwpYj99ixWzu8VC2m/xXsjvOs
-jp4+DLBB490nbkwvstmhmiWm1CmI5O5xOkgioVNQqHvQMdVKOSz9PpbjvZiRX1Uo
-qoMrk+2NOqwP90TB35yPASXb9zXKpO7DLhkube+yYGf+yk46aD707L07Eb7cosFP
-S84vNZ9gX7rQ0UOwm5rYA/oZTBskgaqhtIzkLwIDAQABAoIBAD4ot/sXt5kRn0Ca
-CIkU9AQWlC+v28grR2EQW9JiaZrqcoDNUzUqbCTJsi4ZkIFh2lf0TsqELbZYNW6Y
-6AjJM7al4E0UqYSKJTv2WCuuRxdiRs2BMwthqyBmjeanev7bB6V0ybt7u3Y8xU/o
-MrTuYnr4vrEjXPKdLirwk7AoDbKsRXHSIiHEIBOq1+dUQ32t36ukdnnza4wKDLZc
-PKHiCdCk/wOGhuDlxD6RspqUAlRnJ8/aEhrgWxadFXw1hRhRsf/v1shtB0T3DmTe
-Jchjwyiw9mryb9JZAcKxW+fUc4EVvj6VdQGqYInQJY5Yxm5JAlVQUJicuuJEvn6A
-rj5osQECgYEA552CaHpUiFlB4HGkjaH00kL+f0+gRF4PANCPk6X3UPDVYzKnzmuu
-yDvIdEETGFWBwoztUrOOKqVvPEQ+kBa2+DWWYaERZLtg2cI5byfDJxQ3ldzilS3J
-1S3WgCojqcsG/hlxoQJ1dZFanUy/QhUZ0B+wlC+Zp1Q8AyuGQvhHp68CgYEA0lBI
-eqq2GGCdJuNHMPFbi8Q0BnX55LW5C1hWjhuYiEkb3hOaIJuJrqvayBlhcQa2cGqp
-uP34e9UCfoeLgmoCQ0b4KpL2NGov/mL4i8bMgog4hcoYuIi3qxN18vVR14VKEh4U
-RLk0igAYPU+IK2QByaQlBo9OSaKkcfm7U1/pK4ECgYAxr6VpGk0GDvfF2Tsusv6d
-GIgV8ZP09qSLTTJvvxvF/lQYeqZq7sjI5aJD5i3de4JhpO/IXQJzfZfWOuGc8XKA
-3qYK/Y2IqXXGYRcHFGWV/Y1LFd55mCADHlk0l1WdOBOg8P5iRu/Br9PbiLpCx9oI
-vrOXpnp03eod1/luZmqguwKBgQCWFRSj9Q7ddpSvG6HCG3ro0qsNsUMTI1tZ7UBX
-SPogx4tLf1GN03D9ZUZLZVFUByZKMtPLX/Hi7K9K/A9ikaPrvsl6GEX6QYzeTGJx
-3Pw0amFrmDzr8ySewNR6/PXahxPEuhJcuI31rPufRRI3ZLah3rFNbRbBFX+klkJH
-zTnoAQKBgDbUK/aQFGduSy7WUT7LlM3UlGxJ2sA90TQh4JRQwzur0ACN5GdYZkqM
-YBts4sBJVwwJoxD9OpbvKu3uKCt41BSj0/KyoBzjT44S2io2tj1syujtlVUsyyBy
-/ca0A7WBB8lD1D7QMIhYUm2O9kYtSCLlUTHt5leqGaRG38DqlX36
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIDzDCCArQCCQDSzxzxqhyqLzANBgkqhkiG9w0BAQQFADCBpzELMAkGA1UEBhMC
-VVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcTBkJvc3RvbjETMBEG
-A1UEChMKTXkgQ29tcGFueTEcMBoGA1UECxMTUHJvZHVjdCBEZXZlbG9wbWVudDEZ
-MBcGA1UEAxMQd3d3Lm5vd2hlcmUubm9uZTEhMB8GCSqGSIb3DQEJARYSYWRtaW5A
-bm93aGVyZS5ub25lMB4XDTA3MDMyMzE4MDc0NVoXDTI2MDUyMjE4MDc0NVowgacx
-CzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQ8wDQYDVQQHEwZC
-b3N0b24xEzARBgNVBAoTCk15IENvbXBhbnkxHDAaBgNVBAsTE1Byb2R1Y3QgRGV2
-ZWxvcG1lbnQxGTAXBgNVBAMTEHd3dy5ub3doZXJlLm5vbmUxITAfBgkqhkiG9w0B
-CQEWEmFkbWluQG5vd2hlcmUubm9uZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAL5H18W9MHMYK41ds4hYpIyCPs3vIinEwbeOy9BjP3NtXn3pTfs2aSVF
-Fy7uM8/EcqvEPrEIHzcu7kzqTfW1FGjpNU5w+4Gg0J0FojR5qm1tpC/g0jip4CVT
-6PXREwEvIX+/g9XtQwWcY03NWuEUKliYscKWI/fYsVs7vFQtpv8V7I7zrI6ePgyw
-QePdJ25ML7LZoZolptQpiOTucTpIIqFTUKh70DHVSjks/T6W472YkV9VKKqDK5Pt
-jTqsD/dEwd+cjwEl2/c1yqTuwy4ZLm3vsmBn/spOOmg+9Oy9OxG+3KLBT0vOLzWf
-YF+60NFDsJua2AP6GUwbJIGqobSM5C8CAwEAATANBgkqhkiG9w0BAQQFAAOCAQEA
-vGomHEp6TVU83X2EBUgnbOhzKJ9u3fOI/Uf5L7p//Vxqow7OR1cguzh/YEzmXOIL
-ilMVnzX9nj/bvcLAuqEP7MR1A8f4+E807p/L/Sf49BiCcwQq5I966sGKYXjkve+T
-2GTBNwMSq+5kLSf6QY8VZI+qnrAudEQMeJByQhTZZ0dH8Njeq8EGl9KUio+VWaiW
-CQK6xJuAvAHqa06OjLmwu1fYD4GLGSrOIiRVkSXV8qLIUmzxdJaIRznkFWsrCEKR
-wAH966SAOvd2s6yOHMvyDRIL7WHxfESB6rDHsdIW/yny1fBePjv473KrxyXtbz7I
-dMw1yW09l+eEo4A7GzwOdw==
------END CERTIFICATE-----
-END
- chmod 600 $tcert
- echo "$tcert"
-}
-
-Kecho() {
- NO_KECHO=1
- if [ "X$USER" = "Xrunge" -a "X$NO_KECHO" = "X" ]; then
- echo "dbg: $*"
- fi
-}
-
-NHAFL_warning() {
- echo ""
- echo "** Warning: For the proxy: $proxy"
- echo "** Warning: the ssh(1) option: $ssh_NHAFL"
- echo "** Warning: will be used to avoid frequent 'ssh key has changed for localhost'"
- echo "** Warning: dialogs and connection failures (for example, ssh will exit asking"
- echo "** Warning: you to manually remove a key from ~/.ssh/known_hosts.)"
- echo "** Warning: "
- echo "** Warning: This decreases security: a Man-In-The-Middle attack is possible."
- echo "** Warning: For chained ssh connections the first ssh leg is secure but the"
- echo "** Warning: 2nd ssh leg is vulnerable. For an ssh connection going through"
- echo "** Warning: a HTTP or SOCKS proxy the ssh connection is vulnerable."
- echo "** Warning: "
- echo "** Warning: You can set the SSVNC_SSH_LOCALHOST_AUTH=1 env. var. to disable"
- echo "** Warning: using the NoHostAuthenticationForLocalhost=yes ssh option."
- echo "** Warning: "
- echo "** Warning: A better solution is to configure (in the SSVNC GUI) the setting:"
- echo "** Warning: 'Options -> Advanced -> Private SSH KnownHosts file' (or set"
- echo "** Warning: SSVNC_KNOWN_HOSTS_FILE directly) to a per-connection known hosts"
- echo "** Warning: file. That file holds the 'localhost' cert for this specific"
- echo "** Warning: connection. This yields a both secure and convenient solution."
- echo ""
-}
-
-space_expand() {
- str=`echo "$1" | sed -e 's/%SPACE/ /g' -e 's/%TAB/\t/g'`
- echo "$str"
-}
-
-# handle ssh case:
-#
-if [ "X$use_ssh" = "X1" ]; then
- #
- # USING SSH
- #
- ssh_port="22"
- ssh_host="$host"
- vnc_host="$localhost"
- ssh_UKHF=""
- localhost_extra=""
- # let user override ssh via $SSH
- ssh=${SSH:-"ssh -x"}
-
- sshword=`echo "$ssh" | awk '{print $1}'`
- if [ "X$sshword" != "X" ]; then
- if [ -x "$sshword" ]; then
- :
- elif type "$sshword" > /dev/null 2>&1; then
- :
- else
- echo ""
- echo "*********************************************************"
- echo "** Problem finding the SSH command '$sshword': **"
- echo ""
- type "$sshword"
- echo ""
- echo "** Perhaps you need to install the SSH client package. **"
- echo "*********************************************************"
- echo ""
- sleep 5
- fi
- fi
-
- ssh_NHAFL="-o NoHostAuthenticationForLocalhost=yes"
- if [ "X$SSVNC_SSH_LOCALHOST_AUTH" = "X1" ]; then
- ssh_NHAFL=""
- fi
- if [ "X$SSVNC_KNOWN_HOSTS_FILE" != "X" ]; then
- ssh_NHAFL=""
-
- ssh_UKHF="-o UserKnownHostsFile=$SSVNC_KNOWN_HOSTS_FILE"
- ssh_args="$ssh_args $ssh_UKHF"
- if [ ! -f "$SSVNC_KNOWN_HOSTS_FILE" ]; then
- touch "$SSVNC_KNOWN_HOSTS_FILE" >/dev/null 2>&1
- fi
- chmod 600 "$SSVNC_KNOWN_HOSTS_FILE" >/dev/null 2>&1
- fi
- did_ssh_NHAFL=""
-
- if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then
- SSVNC_LIM_ACCEPT_PRELOAD="$SSVNC_BASEDIR/$SSVNC_UNAME/$SSVNC_LIM_ACCEPT_PRELOAD"
- fi
- if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then
- echo ""
- echo "SSVNC_LIM_ACCEPT_PRELOAD=$SSVNC_LIM_ACCEPT_PRELOAD"
- fi
-
- if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" -a -f "$SSVNC_LIM_ACCEPT_PRELOAD" ]; then
- plvar=LD_PRELOAD
- if uname | grep Darwin >/dev/null; then
- plvar="DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES"
- fi
- ssh="env $plvar=$SSVNC_LIM_ACCEPT_PRELOAD $ssh"
- else
- SSVNC_LIM_ACCEPT_PRELOAD=""
- fi
-
- ssh_vencrypt_proxy=""
- # We handle vencrypt for SSH+SSL mode.
- if echo "$proxy" | grep 'vencrypt://' > /dev/null; then
- proxynew=""
- for part in `echo "$proxy" | tr ',' ' '`
- do
- if echo "$part" | egrep -i '^vencrypt://' > /dev/null; then
- ssh_vencrypt_proxy=$part
- else
- if [ "X$proxynew" = "X" ]; then
- proxynew="$part"
- else
- proxynew="$proxynew,$part"
- fi
- fi
- done
- proxy=$proxynew
- fi
- Kecho ssh_vencrypt_proxy=$ssh_vencrypt_proxy
-
- # note that user must supply http:// for web proxy in SSH and SSH+SSL.
- # No xxxx:// implies ssh server+port.
- #
- if echo "$proxy" | egrep '(http|https|socks|socks4|socks5)://' > /dev/null; then
- # Handle Web or SOCKS proxy(ies) for the initial connect.
- Kecho host=$host
- Kecho port=$port
- pproxy=""
- sproxy1=""
- sproxy_rest=""
- for part in `echo "$proxy" | tr ',' ' '`
- do
- Kecho proxy_part=$part
- if [ "X$part" = "X" ]; then
- continue
- elif echo "$part" | egrep -i '^(http|https|socks|socks4|socks5)://' > /dev/null; then
- pproxy="$pproxy,$part"
- else
- if [ "X$sproxy1" = "X" ]; then
- sproxy1="$part"
- else
- sproxy_rest="$sproxy_rest,$part"
- fi
- fi
- done
- pproxy=`echo "$pproxy" | sed -e 's/^,,*//' -e 's/,,*/,/g'`
- sproxy_rest=`echo "$sproxy_rest" | sed -e 's/^,,*//' -e 's/,,*/,/g'`
-
- Kecho pproxy=$pproxy
- Kecho sproxy1=$sproxy1
- Kecho sproxy_rest=$sproxy_rest
-
- sproxy1_host=""
- sproxy1_port=""
- sproxy1_user=""
-
- if [ "X$sproxy1" != "X" ]; then
- sproxy1_host=`echo "$sproxy1" | awk -F: '{print $1}'`
- sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'`
- sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'`
- if [ "X$sproxy1_host" = "X" ]; then
- sproxy1_host=$sproxy1_user
- sproxy1_user=""
- else
- sproxy1_user="${sproxy1_user}@"
- fi
- sproxy1_port=`echo "$sproxy1" | awk -F: '{print $2}'`
- if [ "X$sproxy1_port" = "X" ]; then
- sproxy1_port="22"
- fi
- else
- sproxy1_host=`echo "$host" | awk -F: '{print $1}'`
- sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'`
- sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'`
- if [ "X$sproxy1_host" = "X" ]; then
- sproxy1_host=$sproxy1_user
- sproxy1_user=""
- else
- sproxy1_user="${sproxy1_user}@"
- fi
- sproxy1_port=`echo "$host" | awk -F: '{print $2}'`
- if [ "X$sproxy1_port" = "X" ]; then
- sproxy1_port="22"
- fi
- fi
-
- Kecho sproxy1_host=$sproxy1_host
- Kecho sproxy1_port=$sproxy1_port
- Kecho sproxy1_user=$sproxy1_user
-
- ptmp="/tmp/ss_vncviewer_ssh${RANDOM}.$$.pl"
- ptmp=`mytmp "$ptmp"`
- PPROXY_REMOVE=1; export PPROXY_REMOVE
- proxy=$pproxy
- port_save=$port
- host_save=$host
- if [ "X$sproxy1_host" != "X" ]; then
- host=$sproxy1_host
- fi
- if [ "X$sproxy1_port" != "X" ]; then
- port=$sproxy1_port
- fi
- host=`echo "$host" | sed -e 's/^.*@//'`
- port=`echo "$port" | sed -e 's/^.*://'`
- pcode "$ptmp"
- port=$port_save
- host=$host_save
-
- nd=`findfree 6600`
- PPROXY_LISTEN=$nd; export PPROXY_LISTEN
- # XXX no reverse forever PPROXY_LOOP_THYSELF ...
- $ptmp &
- sleep 1
- if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then
- NHAFL_warning
- ssh_args="$ssh_args $ssh_NHAFL"
- did_ssh_NHAFL=1
- fi
- sleep 1
- if [ "X$sproxy1" = "X" ]; then
- u=""
- if echo "$host" | grep '@' > /dev/null; then
- u=`echo "$host" | sed -e 's/@.*$/@/'`
- fi
-
- proxy="${u}$localhost:$nd"
- else
- proxy="${sproxy1_user}$localhost:$nd"
- fi
- localhost_extra=".2"
- if [ "X$sproxy_rest" != "X" ]; then
- proxy="$proxy,$sproxy_rest"
- fi
- Kecho proxy=$proxy
- fi
-
- if echo "$proxy" | grep "," > /dev/null; then
-
- proxy1=`echo "$proxy" | awk -F, '{print $1}'`
- proxy2=`echo "$proxy" | awk -F, '{print $2}'`
-
- # user1@gw1.com:port1,user2@ws2:port2
- ssh_host1=`echo "$proxy1" | awk -F: '{print $1}'`
- ssh_port1=`echo "$proxy1" | awk -F: '{print $2}'`
- if [ "X$ssh_port1" != "X" ]; then
- ssh_port1="-p $ssh_port1"
- fi
- ssh_host2=`echo "$proxy2" | awk -F: '{print $1}'`
- ssh_user2=`echo "$ssh_host2" | awk -F@ '{print $1}'`
- ssh_host2=`echo "$ssh_host2" | awk -F@ '{print $2}'`
- if [ "X$ssh_host2" = "X" ]; then
- ssh_host2=$ssh_user2
- ssh_user2=""
- else
- ssh_user2="${ssh_user2}@"
- fi
- ssh_port2=`echo "$proxy2" | awk -F: '{print $2}'`
- if [ "X$ssh_port2" = "X" ]; then
- ssh_port2="22"
- fi
- proxport=`findfree 3500`
- if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then
- NHAFL_warning
- did_ssh_NHAFL=1
- sleep 1
- fi
- echo
- echo "Running 1st ssh proxy:"
- ukhf=""
- if [ "X$ssh_UKHF" != "X" ]; then
- ukhf="$ssh_UKHF$localhost_extra"
- fi
- if echo "$ssh_host1" | grep '%' > /dev/null; then
- uath=`space_expand "$ssh_host1"`
- else
- uath="$ssh_host1"
- fi
- echo "$ssh -f -x $ssh_port1 $targ -e none $ssh_NHAFL $ukhf -L $proxport:$ssh_host2:$ssh_port2 \"$uath\" \"sleep 30\""
- echo ""
- $ssh -f -x $ssh_port1 $targ -e none $ssh_NHAFL $ukhf -L $proxport:$ssh_host2:$ssh_port2 "$uath" "sleep 30"
- ssh_args="$ssh_args $ssh_NHAFL"
- sleep 1
- stty sane
- proxy="${ssh_user2}$localhost:$proxport"
- fi
-
- if [ "X$proxy" != "X" ]; then
- ssh_port=`echo "$proxy" | awk -F: '{print $2}'`
- if [ "X$ssh_port" = "X" ]; then
- ssh_port="22"
- fi
- ssh_host=`echo "$proxy" | awk -F: '{print $1}'`
- vnc_host="$host"
- fi
-
- echo ""
- echo "Running ssh:"
- sz=`echo "$ssh_cmd" | wc -c`
- if [ "$sz" -gt 300 ]; then
- info="..."
- else
- info="$ssh_cmd"
- fi
-
- C=""
- if [ "X$SS_VNCVIEWER_USE_C" != "X" ]; then
- C="-C"
- fi
-
- getport=""
- teeport=""
- if echo "$ssh_cmd" | egrep "(PORT=|P=) " > /dev/null; then
- getport=1
- if echo "$ssh_cmd" | egrep "P= " > /dev/null; then
- teeport=1
- fi
-
- PORT=""
- ssh_cmd=`echo "$ssh_cmd" | sed -e 's/PORT=[ ]*//' -e 's/P=//'`
- SSVNC_NO_ENC_WARN=1
- if [ "X$use_sshssl" = "X" ]; then
- direct_connect=1
- fi
- fi
- if [ "X$getport" != "X" ]; then
- ssh_redir="-D ${use}"
- elif [ "X$reverse" = "X" ]; then
- ssh_redir="-L ${use}:${vnc_host}:${port}"
- else
- ssh_redir="-R ${port}:${vnc_host}:${use}"
- fi
- pmark=`sh -c 'echo $$'`
-
- # the -t option actually speeds up typing response via VNC!!
- if [ "X$ssh_port" = "X22" ]; then
- ssh_port=""
- else
- ssh_port="-p $ssh_port"
- fi
-
- if echo "$ssh_host" | grep '%' > /dev/null; then
- uath=`space_expand "$ssh_host"`
- else
- uath="$ssh_host"
- fi
- if [ "X$SS_VNCVIEWER_SSH_ONLY" != "X" ]; then
- echo "$ssh -x $ssh_port $targ $C $ssh_args \"$uath\" \"$info\""
- echo ""
- $ssh -x $ssh_port $targ $C $ssh_args "$uath" "$ssh_cmd"
- exit $?
-
- elif [ "X$SS_VNCVIEWER_NO_F" != "X" ]; then
- echo "$ssh -x $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\""
- echo ""
- $ssh -x $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd"
- rc=$?
-
- elif [ "X$getport" != "X" ]; then
- tport=/tmp/ss_vncviewer_tport${RANDOM}.$$
- tport=`mytmp "$tport"`
- tport2=/tmp/ss_vncviewer_tport2${RANDOM}.$$
- tport2=`mytmp "$tport2"`
-
- if [ "X$rsh" != "X1" ]; then
- if echo "$ssh_cmd" | grep "sudo " > /dev/null; then
- echo ""
- echo "Initial ssh with 'sudo id' to prime sudo so hopefully the next one"
- echo "will require no password..."
- echo ""
- targ="-t"
- $ssh -x $ssh_port $targ $ssh_args "$uath" "sudo id; tty"
- echo ""
- fi
- echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\""
- echo ""
- $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd" > $tport 2> $tport2
- if [ "X$teeport" = "X1" ]; then
- tail -f $tport 1>&2 &
- tail_pid=$!
- tail -f $tport2 1>&2 &
- tail_pid2=$!
- fi
- rc=$?
- else
- rsh_setup
- echo "rsh $ul \"$ssh_host\" \"$ssh_cmd\""
- echo ""
- rsh $ul "$ssh_host" "$ssh_cmd" > $tport &
- sleep 1
- rc=0
- fi
-
- if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
- echo "sleep $SSVNC_EXTRA_SLEEP"
- sleep $SSVNC_EXTRA_SLEEP
- fi
-
- stty sane
- i=0
- if type perl > /dev/null 2>&1; then
- imax=50
- sleepit="perl -e 'select(undef, undef, undef, 0.20)'"
- else
- imax=10
- sleepit="sleep 1"
- fi
- while [ $i -lt $imax ]; do
- #echo $sleepit
- eval $sleepit
- PORT=`grep "^PORT=" $tport | tr '\r' ' ' | head -n 1 | sed -e 's/PORT=//' -e 's/\r//g' -e 's/ *$//'`
- if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then
- break
- fi
- vnss=`sed -e 's/\r//g' $tport $tport2 | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1 | awk '{print $NF}'`
- if [ "X$vnss" != "X" ]; then
- PORT=`echo "$vnss" | awk -F: '{print $2}'`
- if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then
- if [ $PORT -lt 100 ]; then
- PORT=`expr $PORT + 5900`
- fi
- fi
- if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then
- vnss=`sed -e 's/\r//g' $tport | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1`
- echo "vncserver string: $vnss" 1>&2
- break
- fi
- fi
- i=`expr $i + 1`
- done
-
- echo "found: PORT='$PORT'" 1>&2
- lh6=""
- if [ "X$SSVNC_PORT_IPV6" != "X" ]; then
- lh6=1
- elif egrep 'Info: listening on IPv6 only|Info: listening only on IPv6' $tport > /dev/null; then
- lh6=1
- fi
- if [ "X$lh6" = "X1" ]; then
- echo "set SOCKS5 localhost to ::1" 1>&2
- fi
- rm -f $tport $tport2
- if [ "X$rsh" = "X1" ]; then
- rsh_viewer "$@"
- exit $?
- fi
- PPROXY_SOCKS=5
- if [ "X$SSVNC_SOCKS5" != "X" ]; then
- PPROXY_SOCKS=5
- elif [ "X$SSVNC_SOCKS4" != "X" ]; then
- PPROXY_SOCKS=1
- fi
- export PPROXY_SOCKS
- if [ "X$lh6" = "X" ]; then
- host="$localhost"
- else
- host="::1"
- fi
- port="$PORT"
- proxy="$localhost:$use"
-
- else
- if [ "X$rsh" != "X1" ]; then
- echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\""
- echo ""
- $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd"
- rc=$?
- else
- rsh_setup
- echo "rsh $ul \"$ssh_host\" \"$ssh_cmd\""
- echo ""
- rsh $ul "$ssh_host" "$ssh_cmd" &
- sleep 1
- PORT=$port
- rsh_viewer "$@"
- exit $?
- fi
- fi
-
- if [ "$rc" != "0" ]; then
- echo ""
- echo "ssh to \"$uath\" failed."
- exit 1
- fi
- stty sane
-
- c=0
- pssh=""
- while [ $c -lt 40 ]
- do
- p=`expr $pmark + $c`
- pout=`ps -p "$p" 2>/dev/null | grep -v '^[ ]*PID' | sed -e 's/-L.*$//' -e 's/-x .*$//'`
- if echo "$pout" | grep "ssh" > /dev/null; then
- if echo "$pout" | egrep -i 'ssh.*(-add|-agent|-ask|-keygen|-argv0|vnc)' >/dev/null; then
- :
- elif echo "$pout" | egrep -i 'scp|sshd' >/dev/null; then
- :
- else
- pssh=$p
- break
- fi
- fi
- c=`expr $c + 1`
- done
- if [ "X$getport" != "X" ]; then
- :
- elif [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ] ; then
- sleep 2
- elif [ "X$ssh_cmd" = "Xsleep $ssh_sleep" ] ; then
- #echo T sleep 1
- sleep 1
- elif echo "$ssh_cmd" | grep '^sleep ' >/dev/null; then
- #echo T sleep 2
- sleep 2
- else
- # let any command get started a bit.
- #echo T sleep 5
- sleep 5
- fi
- echo ""
- #reset
- stty sane
- if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
- echo "sleep $SSVNC_EXTRA_SLEEP"
- sleep $SSVNC_EXTRA_SLEEP
- fi
- echo "ssh_pid='$pssh'"; echo
- if [ "X$use_sshssl" = "X" -a "X$getport" = "X" ]; then
- echo "Running viewer:"
-
- trap "final" 0 2 15
- if [ "X$reverse" = "X" ]; then
- echo "$VNCVIEWERCMD" "$@" $localhost:$N
- echo ""
- $VNCVIEWERCMD "$@" $localhost:$N
- if [ $? != 0 ]; then
- echo "vncviewer command failed: $?"
- if [ "X$secondtry" = "X1" ]; then
- sleep 2
- $VNCVIEWERCMD "$@" $localhost:$N
- fi
- fi
- else
- echo ""
- echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
- echo ""
- N2=$N
- if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then
- N2=`echo "$N2" | sed -e 's/://g'`
- if [ $N2 -le 200 ]; then
- N2=`expr $N2 + 5500`
- fi
- fi
- echo "$VNCVIEWERCMD" "$@" -listen $N2
- echo ""
- $VNCVIEWERCMD "$@" -listen $N2
- fi
-
- exit $?
- else
- use2=`findfree 5960`
- host0=$host
- port0=$port
- host=$localhost
- port=$use
- use=$use2
- N=`expr $use - 5900`
- if [ "X$getport" != "X" ]; then
- host="$host0"
- port="$port0"
- else
- proxy=""
- fi
- if [ "X$ssh_vencrypt_proxy" != "X" ]; then
- ssh_vencrypt_proxy="vencrypt://$host:$port"
- if [ "X$proxy" = "X" ]; then
- proxy=$ssh_vencrypt_proxy
- else
- proxy="$proxy,$ssh_vencrypt_proxy"
- fi
- Kecho "proxy_now=$proxy"
- unset PPROXY_LISTEN
- fi
- fi
-fi
-
-if [ "X$stunnel_set_here" = "X1" -a "X$showcert" = "X" ]; then
- if type $STUNNEL > /dev/null 2>&1; then
- :
- else
- echo ""
- echo "***************************************************************"
- echo "** Problem finding the Stunnel command '$STUNNEL': **"
- echo ""
- type $STUNNEL
- echo ""
- echo "** Perhaps you need to install the stunnel/stunnel4 package. **"
- echo "***************************************************************"
- echo ""
- sleep 5
- fi
-fi
-
-# create the stunnel config file:
-if [ "X$verify" != "X" ]; then
- if [ -d $verify ]; then
- verify="CApath = $verify"
- else
- verify="CAfile = $verify"
- fi
- verify="$verify
-verify = 2"
-fi
-if [ "X$SSVNC_STUNNEL_VERIFY3" != "X" ]; then
- verify=`echo "$verify" | sed -e 's/verify = 2/verify = 3/'`
-fi
-if [ "X$mycert" != "X" ]; then
- cert="cert = $mycert"
-fi
-if [ "X$crl" != "X" ]; then
- if [ -d $crl ]; then
- crl="CRLpath = $crl"
- else
- crl="CRLfile = $crl"
- fi
-fi
-
-if [ "X$showcert" = "X1" ]; then
- if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then
- :
- elif [ "X$SSVNC_NO_IPV6_PROXY" != "X" ]; then
- :
- elif [ "X$ipv6" = "X1" -a "X$proxy" = "X" ]; then
- proxy="ipv6://$host:$port"
- fi
-fi
-
-if [ "X$direct_connect" != "X" -a "X$STUNNEL_LISTEN" != "X" ]; then
- proxy=reverse_direct
-fi
-
-ptmp=""
-if [ "X$proxy" != "X" ]; then
- ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl"
- ptmp=`mytmp "$ptmp"`
- PPROXY_REMOVE=1; export PPROXY_REMOVE
- pcode "$ptmp"
- if [ "X$showcert" != "X1" -a "X$direct_connect" = "X" ]; then
- if uname | egrep 'Darwin|SunOS' >/dev/null; then
- vout=`echo "$proxy" | grep -i vencrypt`
- if [ "X$vout" != "X" -a "X$reverse" = "X1" ]; then
- # need to exec for reverse vencrypt
- connect="exec = $ptmp"
- else
- # on mac and solaris we need to listen on socket instead of stdio:
- nd=`findfree 6700`
- PPROXY_LISTEN=$nd
- export PPROXY_LISTEN
- if [ "X$reverse" = "X" ]; then
- $ptmp &
- fi
- sleep 2
- host="$localhost"
- port="$nd"
- connect="connect = $localhost:$nd"
- fi
- else
- # otherwise on unix we can exec it:
- connect="exec = $ptmp"
- fi
- else
- connect="exec = $ptmp"
- fi
-else
- connect="connect = $host:$port"
-fi
-
-# handle showcert case:
-#
-if [ "X$showcert" = "X1" ]; then
- if [ "X$proxy" != "X" ]; then
- PPROXY_LISTEN=$use
- export PPROXY_LISTEN
- if [ "X$SS_DEBUG" != "X" ]; then
- $ptmp &
- else
- $ptmp 2>/dev/null &
- fi
- sleep 1
- more_sleep=1
- if uname | grep Linux > /dev/null; then
- if netstat -ant | grep LISTEN | grep "127.0.0.1:$use" > /dev/null; then
- more_sleep=""
- fi
- elif uname | grep SunOS > /dev/null; then
- if netstat -an -f inet -P tcp | grep LISTEN | grep "127.0.0.1.$use" > /dev/null; then
- more_sleep=""
- fi
- elif uname | egrep -i 'bsd|darwin' > /dev/null; then
- if netstat -ant -f inet | grep LISTEN | grep "127.0.0.1.$use" > /dev/null; then
- more_sleep=""
- fi
- fi
- if [ "X$more_sleep" = "X1" ]; then
- sleep 1
- fi
- host="$localhost"
- port="$use"
- fi
- cipher_args=""
- if [ "X$ciphers" != "X" ]; then
- cipher_args=`echo "$ciphers" | sed -e 's/ciphers=/-cipher /'`
- fi
- if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then
- :
- elif type openssl > /dev/null 2>&1; then
- :
- else
- echo ""
- echo "********************************************************"
- echo "** Problem finding the OpenSSL command 'openssl': **"
- echo ""
- type openssl 2>&1
- echo ""
- echo "** Perhaps you need to install the 'openssl' package. **"
- echo "********************************************************"
- echo ""
- fi
- #echo "openssl s_client $cipher_args -connect $host:$port"
- if [ "X$reverse" = "X" ]; then
- if type host > /dev/null 2>/dev/null; then
- host $host >/dev/null 2>&1
- host $host >/dev/null 2>&1
- fi
- timeout=15
- if [ "X$SSVNC_FETCH_TIMEOUT" != "X" ]; then
- timeout=$SSVNC_FETCH_TIMEOUT
- fi
- if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then
- if type pkill >/dev/null 2>&1; then
- (sleep $timeout; if kill -0 $$; then pkill -TERM -f "ultravnc_dsm_helper.*$host.*$port"; fi) >/dev/null 2>&1 &
- fi
- ultravnc_dsm_helper showcert $host:$port 2>&1
- else
- if type pkill >/dev/null 2>&1; then
- (sleep $timeout; if kill -0 $$; then pkill -TERM -f "openssl.*s_client.*$host.*$port"; fi) >/dev/null 2>&1 &
- fi
- openssl s_client $cipher_args -prexit -connect $host:$port 2>&1 < /dev/null
- fi
- rc=$?
- else
- tcert=""
- if [ "X$mycert" = "X" ]; then
- tcert=`make_tcert`
- cert_args="-cert $tcert -CAfile $tcert"
- else
- cert_args="-cert $mycert -CAfile $mycert"
- fi
- tmp_out=/tmp/showcert_out${RANDOM}.$$
- tmp_out=`mytmp "$tmp_out"`
- tmp_err=/tmp/showcert_err${RANDOM}.$$
- tmp_err=`mytmp "$tmp_err"`
-
- #echo "openssl s_server $cipher_args $cert_args -accept $port -verify 2 > $tmp_out 2> $tmp_err" 1>&2
-
- # assume we have perl:
- check_perl perl
-
- perl -e "
- \$p = open(O, \"|openssl s_server $cipher_args $cert_args -accept $port -verify 2 1>$tmp_out 2> $tmp_err\");
- exit 1 unless \$p;
- while (1) {
- sleep 1;
- if (!open(F, \"<$tmp_out\")) {
- kill \$p;
- exit 1;
- }
- while (<F>) {
- if (/RFB 00/) {
- fsleep(0.25);
- print O \"RFB 000.000\\n\";
- fsleep(1.00);
- kill \$p;
- fsleep(0.25);
- exit 0;
- }
- }
- close F;
- }
- sub fsleep {
- select(undef, undef, undef, shift);
- }
- ";
-
- echo ""
- cat $tmp_out
- echo ""
- echo "----2----"
- cat $tmp_err
- if grep BEGIN.CERTIFICATE $tmp_out >/dev/null; then
- rc=0
- else
- rc=1
- fi
-
- rm -f $tmp_out $tmp_err
- fi
- if [ "X$SSVNC_PREDIGESTED_HANDSHAKE" != "X" ]; then
- rm -f $SSVNC_PREDIGESTED_HANDSHAKE
- fi
- if [ "X$SSVNC_SHOWCERT_EXIT_0" = "X1" ]; then
- exit 0
- else
- exit $rc
- fi
-fi
-
-# handle direct connect case:
-#
-if [ "X$direct_connect" != "X" ]; then
- if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
- SSVNC_NO_ENC_WARN=1
- echo ""
- echo "Using UltraVNC DSM Plugin key for encryption:"
- echo ""
- ustr=`echo "$SSVNC_ULTRA_DSM" | sed -e 's/pw=[^ ]*/pw=******/g'`
- echo " $ustr PORT HOST:PORT"
- echo ""
- elif [ "X$getport" = "X" ]; then
- echo ""
- echo "Running viewer for direct connection:"
- if echo X"$@" | grep chatonly > /dev/null; then
- :
- else
- echo ""
- echo "** WARNING: THERE WILL BE NO SSL OR SSH ENCRYPTION **"
- echo ""
- fi
- fi
- x=""
- if [ "X$SSVNC_NO_ENC_WARN" != "X" ]; then
- if [ "X$getport" = "X" ]; then
- sleep 1
- fi
- elif type printf > /dev/null 2>&1; then
- printf "Are you sure you want to continue? [y]/n "
- read x
- else
- echo -n "Are you sure you want to continue? [y]/n "
- read x
- fi
- if [ "X$x" = "Xn" ]; then
- exit 1
- fi
- echo ""
- if [ "X$ptmp" != "X" ]; then
- if [ "X$reverse" = "X" ]; then
- PPROXY_LISTEN=$use
- export PPROXY_LISTEN
- else
- if [ "X$proxy" = "Xreverse_direct" ]; then
- PPROXY_LISTEN="$STUNNEL_LISTEN:`expr 5500 + $disp`"
- PPROXY_DEST="$localhost:$use"
- PPROXY_PROXY="ipv6://$localhost:$use" # not always ipv6..
- export PPROXY_LISTEN PPROXY_DEST PPROXY_PROXY
- pps=1
- else
- PPROXY_REVERSE="$localhost:$use"
- export PPROXY_LISTEN
- pps=3
- fi
- if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then
- PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself.${RANDOM}.$$"`
- export PPROXY_LOOP_THYSELF
- pps=2
- fi
- if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
- pps=`expr $pps + $SSVNC_EXTRA_SLEEP`
- fi
- PPROXY_SLEEP=$pps; export PPROXY_SLEEP;
- PPROXY_KILLPID=+1; export PPROXY_KILLPID;
- fi
-
- $ptmp &
-
- if [ "X$reverse" = "X" ]; then
- #sleep 2
- #echo T sleep 1
- sleep 1
- fi
- host="$localhost"
- disp="$N"
- port=`expr $disp + 5900`
- fi
- if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
- echo "T sleep $SSVNC_EXTRA_SLEEP"
- sleep $SSVNC_EXTRA_SLEEP
- fi
- if [ "X$reverse" = "X" ]; then
- hostdisp="$host:$disp"
- if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
- if [ "X$SSVNC_USE_OURS" = "X1" ]; then
- hostdisp="exec=$SSVNC_ULTRA_DSM 0 $host:$port"
- else
- pf=`findfree 5970`
- cmd="$SSVNC_ULTRA_DSM -$pf $host:$port"
- pf=`expr $pf - 5900`
- hostdisp="$localhost:$pf"
- ustr=`echo "$cmd" | sed -e 's/pw=[^ ]*/pw=******/g'`
- echo "Running:"
- echo
- echo "$ustr &"
- echo
- $cmd &
- dsm_pid=$!
- sleep 2
- fi
- fi
- hostdisp2=`echo "$hostdisp" | sed -e 's/pw=[^ ]*/pw=******/g'`
- echo "$VNCVIEWERCMD" "$@" "$hostdisp2"
- trap "final" 0 2 15
- echo ""
- $VNCVIEWERCMD "$@" "$hostdisp"
- if [ $? != 0 ]; then
- echo "vncviewer command failed: $?"
- if [ "X$secondtry" = "X1" ]; then
- sleep 2
- $VNCVIEWERCMD "$@" "$hostdisp"
- fi
- fi
- else
- echo ""
- echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
- echo ""
- trap "final" 0 2 15
- if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
- if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then
- echo "NOTE: The ultravnc_dsm_helper only runs once. So after the first LISTEN"
- echo " ends you must restart the Listening mode. You may also need to"
- echo " Press Ctrl-C to stop the viewer and restart for another connection."
- echo ""
- fi
- #SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
- VNCVIEWER_LISTEN_LOCALHOST=1
- export VNCVIEWER_LISTEN_LOCALHOST
- dport=`expr 5500 + $disp`
- cmd="$SSVNC_ULTRA_DSM $dport $localhost:$use"
- ustr=`echo "$cmd" | sed -e 's/pw=[^ ]*/pw=******/g'`
- echo "Running:"
- echo
- echo "$ustr &"
- echo
- if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then
- $cmd &
- dsm_pid=$!
- else
- while [ 1 ]; do $cmd; sleep 1; done &
- dsm_pid=$!
- fi
- sleep 2
- disp=$use
- if [ $disp -ge 5500 ]; then
- disp=`expr $disp - 5500`
- fi
- fi
- disp2=$disp
- if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then
- disp2=`echo "$disp2" | sed -e 's/://g'`
- if [ $disp2 -le 200 ]; then
- disp2=`expr $disp2 + 5500`
- fi
- fi
- echo "$VNCVIEWERCMD" "$@" -listen $disp2
- echo ""
- $VNCVIEWERCMD "$@" -listen $disp2
- if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then
- rm -f $PPROXY_LOOP_THYSELF
- fi
- fi
- exit $?
-fi
-
-tmp_cfg=/tmp/ss_vncviewer${RANDOM}.$$
-tmp_cfg=`mytmp "$tmp_cfg"`
-
-stunnel_exec=""
-if [ "X$SSVNC_USE_OURS" != "X1" ]; then
- :
-elif echo $STUNNEL_EXTRA_SVC_OPTS | grep '#stunnel-exec' > /dev/null; then
- stunnel_exec="#"
-fi
-
-if [ "X$reverse" = "X" ]; then
-
- if echo "$proxy" | grep "^repeater://" > /dev/null; then
- if [ "X$cert" = "XBUILTIN" ]; then
- ttcert=`make_tcert`
- cert="cert = $ttcert"
- fi
- # Note for listen mode, an empty cert will cause stunnel to fail.
- # The ssvnc gui will have already taken care of this.
- fi
-
- cat > "$tmp_cfg" <<END
-foreground = yes
-pid =
-client = yes
-debug = $stunnel_debug
-$ciphers
-$STUNNEL_EXTRA_OPTS
-$STUNNEL_EXTRA_OPTS_USER
-$cert
-$crl
-$verify
-
-${stunnel_exec}[vnc_stunnel]
-${stunnel_exec}accept = $localhost:$use
-$connect
-$STUNNEL_EXTRA_SVC_OPTS
-$STUNNEL_EXTRA_SVC_OPTS_USER
-
-END
-
-else
- # REVERSE case:
-
- stunnel_exec="" # doesn't work for listening.
-
- p2=`expr 5500 + $N`
- connect="connect = $localhost:$p2"
- if [ "X$cert" = "XBUILTIN" ]; then
- ttcert=`make_tcert`
- cert="cert = $ttcert"
- fi
- # Note for listen mode, an empty cert will cause stunnel to fail.
- # The ssvnc gui will have already taken care of this.
-
-
- hloc=""
- if [ "X$use_ssh" = "X1" ]; then
- hloc="$localhost:"
- elif [ "X$STUNNEL_LISTEN" != "X" ]; then
- hloc="$STUNNEL_LISTEN:"
- fi
- if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then
- hloc="$localhost:"
- pv=`findfree 5570`
- proxy="vencrypt:$pv:$port"
- port=$pv
- if [ "X$anondh_set" = "X1" ]; then
- # not needed for ANONDH in this mode
- #ciphers="ciphers = ADH:@STRENGTH"
- :
- fi
- fi
- cat > "$tmp_cfg" <<END
-foreground = yes
-pid =
-client = no
-debug = $stunnel_debug
-$ciphers
-$STUNNEL_EXTRA_OPTS
-$STUNNEL_EXTRA_OPTS_USER
-$cert
-$crl
-$verify
-
-[vnc_stunnel]
-accept = $hloc$port
-$connect
-$STUNNEL_EXTRA_SVC_OPTS
-$STUNNEL_EXTRA_SVC_OPTS_USER
-
-END
-
-fi
-
-echo ""
-echo "Using this stunnel configuration:"
-echo ""
-cat "$tmp_cfg" | uniq
-echo ""
-if egrep -i '^[ ]*(CApath|CAfile) =' "$tmp_cfg" > /dev/null ; then
- :
-else
- echo "** WARNING: THE STUNNEL CONFIG HAS NO SERVER CERTIFICATE SPECIFIED **"
- echo "** WARNING: (the CApath or CAfile stunnel option) THE VNC SERVER WILL **"
- echo "** WARNING: NOT BE AUTHENTICATED. A MAN-IN-THE-MIDDLE ATTACK IS POSSIBLE **"
- echo ""
-fi
-sleep 1
-
-if [ "X$stunnel_exec" = "X" ]; then
- echo ""
- echo "Running stunnel:"
- echo "$STUNNEL $tmp_cfg"
- st=`echo "$STUNNEL" | awk '{print $1}'`
- $st -help > /dev/null 2>&1
- $STUNNEL "$tmp_cfg" < /dev/tty > /dev/tty &
- stunnel_pid=$!
- echo ""
-
- # pause here to let the user supply a possible passphrase for the
- # mycert key:
- if [ "X$mycert" != "X" ]; then
- nsl=10
- dsl=0
- if [ ! -f $mycert ]; then
- dsl=0
- elif grep -i 'Proc-Type.*ENCRYPTED' "$mycert" > /dev/null 2>/dev/null; then
- dsl=1
- fi
- if [ "X$dsl" = "X1" ]; then
- echo ""
- echo "(** pausing $nsl secs for possible certificate passphrase dialog **)"
- echo ""
- sleep $nsl
- echo "(** done pausing for passphrase **)"
- echo ""
- fi
- fi
- #echo T sleep 1
- sleep 1
- rm -f "$tmp_cfg"
-fi
-
-
-echo ""
-if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
- echo "sleep $SSVNC_EXTRA_SLEEP"
- sleep $SSVNC_EXTRA_SLEEP
-fi
-
-if [ "X$reverse" = "X" ]; then
- if [ "X$NEED_VENCRYPT_VIEWER_BRIDGE" = "X1" -a "X$ptmp" != "X" ] ; then
- port1=`expr 5900 + $N` # stunnel port
- port2=`findfree 5970` # bridge port (viewer connects to it.)
- N=`expr $port2 - 5900`
- env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="$port2,$port1" $ptmp &
- sleep 1
- fi
- echo "Running viewer:"
- vnc_hp=$localhost:$N
- if [ "X$stunnel_exec" != "X" ]; then
- vnc_hp="exec=$STUNNEL $tmp_cfg"
- fi
- echo "$VNCVIEWERCMD" "$@" "$vnc_hp"
- trap "final" 0 2 15
- echo ""
- $VNCVIEWERCMD "$@" "$vnc_hp"
- if [ $? != 0 ]; then
- echo "vncviewer command failed: $?"
- if [ "X$secondtry" = "X1" ]; then
- sleep 2
- $VNCVIEWERCMD "$@" "$vnc_hp"
- fi
- fi
-else
- echo "Running viewer:"
- echo ""
- echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
- echo ""
- trap "final" 0 2 15
- N2=$N
- N2_trim=`echo "$N2" | sed -e 's/://g'`
- if [ $N2_trim -le 200 ]; then
- N2_trim=`expr $N2_trim + 5500`
- fi
- if [ "X$proxy" != "X" ]; then
- if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then
- pstunnel=`echo "$proxy" | awk -F: '{print $2}'`
- plisten=`echo "$proxy" | awk -F: '{print $3}'`
- IF=INADDR_ANY
- if [ "X$STUNNEL_LISTEN" != "X" ]; then
- IF=$STUNNEL_LISTEN
- fi
- PPROXY_VENCRYPT_REVERSE=1; export PPROXY_VENCRYPT_REVERSE
- PPROXY_LISTEN="$IF:$plisten"; export PPROXY_LISTEN
- PPROXY_PROXY="vencrypt://$localhost:$pstunnel"; export PPROXY_PROXY
- PPROXY_DEST="$localhost:$pstunnel"; export PPROXY_DEST
- STUNNEL_ONCE=1; export STUNNEL_ONCE
- STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS
- if [ "X$NEED_VENCRYPT_VIEWER_BRIDGE" = "X1" -a "X$ptmp" != "X" ] ; then
- port1=`expr 5500 + $N2`
- port2=`findfree 5580`
- N2=`expr $port2 - 5500`
- N2_trim=`echo "$N2" | sed -e 's/://g'`
- if [ $N2_trim -le 200 ]; then
- N2_trim=`expr $N2_trim + 5500`
- fi
- if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then
- PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself1.${RANDOM}.$$"`
- export PPROXY_LOOP_THYSELF
- PPROXY_LOOP_THYSELF0=$PPROXY_LOOP_THYSELF
- fi
- env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="-$port1,$port2" $ptmp &
- sleep 1
- fi
- else
- PPROXY_REVERSE="$localhost:$port"; export PPROXY_REVERSE
- PPROXY_SLEEP=1; export PPROXY_SLEEP;
- fi
- PPROXY_KILLPID=+1; export PPROXY_KILLPID;
- if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then
- PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself2.${RANDOM}.$$"`
- export PPROXY_LOOP_THYSELF
- fi
- $ptmp &
- # Important to have no extra pids generated between here and VNCVIEWERCMD
- fi
- if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then
- N2=$N2_trim
- fi
- echo "$VNCVIEWERCMD" "$@" -listen $N2
- echo ""
- $VNCVIEWERCMD "$@" -listen $N2
-
- if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then
- rm -f $PPROXY_LOOP_THYSELF
- fi
- if [ "X$PPROXY_LOOP_THYSELF0" != "X" ]; then
- rm -f $PPROXY_LOOP_THYSELF0
- fi
-fi
-
-sleep 1
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl
deleted file mode 100755
index fefb143..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl
+++ /dev/null
@@ -1,19041 +0,0 @@
-#!/bin/sh
-# the next line restarts using wish \
-exec wish "$0" "$@"
-
-#
-# Copyright (c) 2006-2010 by Karl J. Runge <runge@karlrunge.com>
-#
-# ssvnc.tcl: gui wrapper to the programs in this
-# package. Also sets up service port forwarding.
-#
-set version 1.0.28
-
-set buck_zero $argv0
-
-proc center_win {w} {
- global is_windows
- update
- set W [winfo screenwidth $w]
- set W [expr $W + 1]
- wm geometry $w +$W+0
- update
- set x [expr [winfo screenwidth $w]/2 - [winfo width $w]/2]
- set y [expr [winfo screenheight $w]/2 - [winfo height $w]/2]
-
- if {$is_windows} {
- set y [expr "$y - 30"]
- if {$y <= 0} {
- set y 1
- }
- }
- wm geometry $w +$x+$y
- wm deiconify $w
- update
-}
-
-proc small_height {} {
- set H [winfo screenheight .]
- if {$H < 700} {
- return 1
- } else {
- return 0
- }
-}
-
-proc mac_raise {} {
- global uname
- if {$uname == "Darwin"} {
- catch {exec /bin/sh -c {osascript -e 'tell application "Wish Shell" to activate' >/dev/null 2>&1 &}}
- after 150
- update
- update idletasks
- }
-}
-
-proc toplev {w} {
- catch {destroy $w}
- toplevel $w
- catch {wm withdraw $w}
-}
-
-proc apply_bg {w} {
- global is_windows system_button_face
- if {$is_windows && $system_button_face != ""} {
- catch {$w configure -bg "$system_button_face"}
- }
-}
-
-proc line_count {{str ""} {pad 0}} {
- set n $pad
- foreach l [split $str "\n"] {
- incr n
- }
- return $n
-}
-
-proc scroll_text {fr {w 80} {h 35}} {
- global help_font is_windows scroll_text_focus
-
- if {$h == 35 && [small_height]} {
- set h 28
- }
- catch {destroy $fr}
-
- frame $fr -bd 0
-
- eval text $fr.t -width $w -height $h $help_font \
- -setgrid 1 -bd 2 -yscrollcommand {"$fr.y set"} -relief ridge
-
- apply_bg $fr.t
-
- scrollbar $fr.y -orient v -relief sunken -command "$fr.t yview"
- pack $fr.y -side right -fill y
- pack $fr.t -side top -fill both -expand 1
-
- if {$scroll_text_focus} {
- focus $fr.t
- }
-}
-
-proc scroll_text_dismiss {fr {w 80} {h 35}} {
- global help_font
-
- if {$h == 35 && [small_height]} {
- set h 28
- }
- scroll_text $fr $w $h
-
- set up $fr
- regsub {\.[^.]*$} $up "" up
-
- button $up.d -text "Dismiss" -command "destroy $up"
- bind $up <Escape> "destroy $up"
- pack $up.d -side bottom -fill x
- pack $fr -side top -fill both -expand 1
-}
-
-proc jiggle_text {w} {
- global uname
- if {$uname == "Darwin"} {
- $w yview scroll 1 pages
- update idletasks
- $w yview scroll -1 pages
- update idletasks
- }
-}
-
-proc ts_help {} {
- toplev .h
-
- scroll_text_dismiss .h.f
-
- center_win .h
- wm title .h "Terminal Services VNC Viewer Help"
-
- set msg {
- Terminal Services:
-
- The Terminal Services VNC Viewer uses SSH to establish an encrypted
- and authenticated connection to the remote server.
-
- Through the SSH channel, it automatically starts x11vnc in terminal
- services mode on the remote server to find or create your desktop
- session. x11vnc is used for both the session management and the
- VNC transport.
-
- You MUST be able to log in via SSH to the remote terminal server.
- Ask your administrator to set this up for you if it isn't already.
- x11vnc must also be installed on the remote server machine.
- See "Requirements" below.
-
- This mode is started by the commands 'tsvnc' or 'ssvnc -ts' or
- toggled by pressing Ctrl-t. "SSVNC Mode" under Options -> Advanced
- will also return to the full SSVNC.
-
- Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc"
- to have the tool always start up in that mode. To constrain the UI,
- run with -tso or SSVNC_TS_ALWAYS set to prevent leaving the Terminal
- Services mode.
-
-
- Hosts and Displays:
-
- Enter the remote VNC Terminal Services hostname in the
- 'VNC Terminal Server' entry.
-
- Examples:
-
- 24.67.132.27
- far-away.east
- fred@someplace.no
-
- Then click on "Connect".
-
- Once the SSH is running (you may need to type a password or accept
- a new ssh key in the terminal window that pops up), the VNC Viewer
- will be automatically started directed to the local port of the SSH
- tunnel which, in turn, encrypts and redirects the connection to the
- remote VNC server.
-
- x11vnc is run remotely to find or create your terminal services desktop
- session. It must be installed and accessible on the remote system.
-
- Enter "user@hostname.com" in 'VNC Terminal Server' if the remote
- username is different from the yours on this machine. On Windows
- you *MUST* supply the remote username due to a deficiency in Plink.
- This entry is passed to SSH; it could also be an SSH alias you have
- created (in ~/.ssh/config).
-
- If the remote SSH server is run on a non-standard port, e.g. 2222, use
- something like one of these:
-
- far-away.east:2222
- fred@someplace.no:2222
-
- (unlike SSVNC mode, the number is the SSH port, not the VNC display)
-
- If you find yourself in the unfortunate circumstance that your ssh
- username has a space in it, use %SPACE (or %TAB) like this:
-
- fred%SPACEflintstone@xyzzy.net
-
-
- Zeroconf/Bonjour:
-
- On Unix or Mac OS X, if the 'avahi-browse' or 'dns-sd' command is
- available on the system and in your PATH, a 'Find' button is placed by
- 'VNC Host:Display'. Clicking on Find will try to find VNC Servers
- on your Local Network that advertize via the Zeroconf protocol.
- A menu of found hosts is presented for you to select from.
-
-
- Profiles:
-
- Use "Save" to save a profile (i.e. a host:display and its specific
- settings) with a name. The "TS-" prefix will be suggested to help
- you distinguish between Terminal Services and regular profiles.
-
- To load in a saved Options profile, click on the "Load" button,
- and choose which one you want.
-
- To list your profiles from the command line use:
-
- tsvnc -profiles (or -list)
-
- To launch profile1 directly from the command-line, or to a server
- use things like:
-
- tsvnc profile1
- tsvnc /path/to/profile1.vnc
- tsvnc hostname
- tsvnc user@hostname
-
- Note that the 'Verify All Certs' setting is NOT saved in profiles.
-
-
- Proxies/Gateways:
-
- Proxy/Gateway is usually a gateway machine to log into via SSH that is
- not the machine running the VNC terminal services. However, Web and
- SOCKS proxies can also be used (see below).
-
- For example if a company had a central login server: "ssh.company.com"
- (accessible from the internet) and the internal server name was
- "ts-server", one could put in
-
- VNC Terminal Server: ts-server
- Proxy/Gateway: ssh.company.com
-
- It is OK if the hostname "ts-server" only resolves inside the firewall.
-
- The 2nd host, ts-server in this example, MUST also be running an SSH
- server and you must be able to log into it. You may need to supply
- a 2nd password to it to login.
-
- Use username@host (e.g. joe@ts-server or jsmith@ssh.company.com)
- if the user name differs between machines.
-
- NOTE: On Windows you MUST always supply the username@ because putty's
- plink requires it.
-
-
- NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other
- than 22) you need to use the Proxy/Gateways as well. E.g. something
- like this for port 2222:
-
- VNC Terminal Server: ts-server
- Proxy/Gateway: jsmith@ssh.company.com:2222
-
- On Unix/MacOSX the username@ is not needed if it is the same as on this
- machine.
-
-
- A Web or SOCKS proxy can also be used. Use this if you are inside a
- firewall that prohibits direct connections to remote SSH servers.
- In Terminal Services SSH mode, the "http://" prefix is required for
- web proxies.
-
- VNC Terminal Server: fred@someplace.no
- Proxy/Gateway: http://myproxy.west:8080
-
- or for SOCKS:
-
- VNC Terminal Server: fred@someplace.no
- Proxy/Gateway: socks://mysocks.west:1080
-
- use socks5://... to force the SOCKS5 version. For a non-standard
- port the above would be, e.g., fred@someplace.no:2222
-
- As with a username that contains a space, use %SPACE (or %TAB) to
- indicate it in the SSH proxies, e.g. john%SPACEsmith@ssh.company.com
-
- One can also chain proxies and other things. See the section
- "SSH Proxies/Gateways" in the Main SSVNC Help for full details.
-
-
- Options:
-
- Click on Options to get to dialog boxes to:
-
- - Desktop Type (kde, gnome, failsafe, twm...)
- - Desktop Size (Geometry WxH and pixel depth)
- - X Server Type (Xvfb, Xdummy, Xvnc)
- - Enable Printing (CUPS and/or SMB/Windows)
- - Enable Sound (TBD, ESD partially working)
- - File Transfer (Ultra or TightVNC filexfer)
- - View Only (View only client)
- - Change VNC Viewer (Realvnc, ultra, etc...)
- - X11 viewer MacOSX (use bundled X11 vncviewer)
- - Delete Profile... (Delete a saved profile)
-
- - Advanced Options:
-
- - VNC Shared (optional traditional VNC sharing)
- - Multiple Sessions (more than 1 session per server)
- - X Login Greeter (Connect to Login/Greeter Display)
- - Other VNC Server (redirect to 3rd party VNC Server)
- - Use unixpw (optional x11vnc login mode)
- - Client 8bit Color (VNC Viewer requests low color mode)
- - Client-Side Caching (experimental x11vnc speedup)
- - X11VNC Options (set any extra x11vnc options)
- - Extra Sleep (delay a bit before starting viewer)
- - Putty Args (Windows: string for plink/putty cmd)
- - Putty Agent (Windows: launch pageant)
- - Putty Key-Gen (Windows: launch puttygen)
- - SSH Local Protections (a bit of safety on local side)
- - SSH KnownHosts file (to avoid SSH 'localhost' collisions)
- - SSVNC Mode (Return to full SSVNC mode)
-
- - Unix ssvncviewer (set options for supplied Unix viewer)
-
-
- Requirements:
-
- When running this application on Unix/MacOSX the ssh(1) program must
- be installed locally. On Windows a plink/putty binary is included.
-
- On the remote VNC Terminal Services host, x11vnc must be installed
- (0.9.3 or higher), and at least one virtual X server: Xvfb, Xdummy,
- or Xvnc must be available. Xvfb is the most often used one. All of
- these programs must be available in $PATH on the remote server when
- logged in via SSH.
-
- The VNC terminal services administrator can make "x11vnc" be a wrapper
- script that sets everything up correctly and then runs the real x11vnc.
-
-
- Real X servers:
-
- As a *BONUS*, if on the remote host, say a workstation, you have a
- regular X session running on the physical hardware that you are
- ALREADY logged into you can access to that display as well (x11vnc
- will find it).
-
- So this tool can be used as a simple way to launch x11vnc to find
- your real X display on your workstation and connect to it.
-
- The Printing and Sound redirection won't work for this mode however.
- You will need to use the full SSVNC application to attempt that.
-
- If you (mistakenly) have not logged into an X session on the real
- X server on the workstation, a VIRTUAL (Xvfb, etc.) server will be
- created for you (that may or may not be what you want).
-
- The X Login Advanced setting can be used to connect to a X Display
- Manger Greeter login panel (no one is logged in yet). This requires
- sudo(1) privileges on the remote machine.
-
- More Info:
-
- See these links for more information:
-
- http://www.karlrunge.com/x11vnc/#tunnelling
-}
-
- global version
- set msg " SSVNC version: $version\n$msg"
-
- .h.f.t insert end $msg
- jiggle_text .h.f.t
-}
-
-proc help {} {
- global ts_only
- if {$ts_only} {
- ts_help
- return
- }
- toplev .h
-
- set h 37
- if [small_height] {
- set h 26
- }
- scroll_text_dismiss .h.f 82 $h
-
- center_win .h
- wm title .h "SSL/SSH VNC Viewer Help"
-
- global help_main help_prox help_misc help_tips
-
- set help_main {
- Hosts and Displays:
-
- Enter the VNC host and display in the 'VNC Host:Display' entry box.
-
- It is of the form "host:number", where "host" is the hostname of the
- machine running the VNC Server and "number" is the VNC display number;
- it is often "0". Some Examples:
-
- snoopy:0
-
- far-away.east:0
-
- sunray-srv1.west:17
-
- 24.67.132.27:0
-
- Then click on "Connect". When you do the STUNNEL program will be started
- locally to provide you with an outgoing SSL tunnel.
-
- Once the STUNNEL is running, the TightVNC Viewer (Or perhaps Chicken of
- the VNC on Mac OS X, or one you set under Options) will be automatically
- started and directed to the local port of the SSL tunnel which, in turn,
- encrypts and redirects the connection to the remote VNC server.
-
- The remote VNC server **MUST** support an initial SSL/TLS handshake before
- using the VNC protocol (i.e. VNC is tunnelled through the SSL channel
- after it is established). "x11vnc -ssl ..." does this, and any VNC server
- can be made to do this by using, e.g., STUNNEL or socat on the remote side.
- SSVNC also supports VeNCrypt and ANONTLS SSL/TLS VNC servers (see below.)
-
- * Automatic SSH Tunnels are described below.
-
- * The 'No Encryption' / 'None' option provides a direct connection without
- encryption (disable the button with the -enc option, or Options menu.)
- More info in Tip 5.
-
- Port numbers:
-
- If you are using a port less than the default VNC port 5900 (usually
- the VNC display = port - 5900), use the full port number itself, e.g.:
-
- 24.67.132.27:443
-
- Note, however, if the number n after the colon is < 200, then a
- port number 5900 + n is assumed; i.e. n is the VNC display number.
- If you must use a TCP port less than 200, specify a negative value,
- e.g.: 24.67.132.27:-80
-
- For Reverse VNC connections (listening viewer, See Tip 2 and
- Options -> Help), the port mapping is similar, except "listening
- display :0" corresponds to port 5500, :1 to 5501, etc.
- Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel
- listen on that interface only. Listening on IPv6 can also be done, use
- e.g. :::0 or ::1:0 This listening on IPv6 (:::0) works for UN-encrypted
- reverse connections as well (mode 'None').
-
-
- Zeroconf/Bonjour:
-
- On Unix or Mac OS X, if the 'avahi-browse' or 'dns-sd' command is
- available on the system and in your PATH, a 'Find' button is placed by
- 'VNC Host:Display'. Clicking on Find will try to find VNC Servers on
- your Local Network that advertize via the Zeroconf protocol. A menu of
- found hosts is presented for you to select from.
-
-
- VNC Password:
-
- On Unix or MacOSX IF there is a VNC password for the server you can
- enter it in the "VNC Password:" entry box.
-
- This is *REQUIRED* on MacOSX when Chicken of the VNC is used, because
- that viewer does not put up a user password prompt when it learns
- that a password is needed.
-
- On Unix (including MacOSX using the X11 viewer) if you choose not to
- enter the password you will simply be prompted for it in the terminal
- window running TightVNC viewer if one is required.
-
- On Windows TightVNC viewer will prompt you if a password is required.
-
- NOTE: when you Save a VNC profile, the password is NOT saved (you need
- to enter it each time). Nor is the 'Verify All Certs' setting.
-
-
- Profiles:
-
- Use "Save" to save a profile (i.e. a host:display and its specific
- settings) with a name.
-
- To load in a saved Options profile, click on the "Load" button.
-
- To list your profiles from the command line use:
-
- ssvnc -profiles (or -list)
-
- You can launch ssvnc and have it immediately connect to the server
- by invoking it something like this:
-
- ssvnc profile1 (launches profile named "profile1")
- ssvnc /path/to/profile.vnc (loads the profile file, no launching)
- ssvnc hostname:0 (connect to hostname VNC disp 0 via SSL)
- ssvnc vnc+ssl://hostname:0 (same)
- ssvnc vnc+ssh://hostname:0 (connect to hostname VNC disp 0 via SSH)
-
- see the Tips 5 and 7 for more about the URL-like syntax.
-
- If you don't want "ssvnc profile1" to immediately launch the connection
- to the VNC server set the SSVNC_PROFILE_LOADONLY env. var. to 1.
- (or specify the full path to the profile.vnc as shown above.)
-
-
- SSL Certificate Verification:
-
- *** IMPORTANT ***: If you do not take the steps to VERIFY the VNC Server's
- SSL Certificate, you are in principle vulnerable to a Man-In-The-Middle
- attack. Without SSL Certificate verification, only passive network
- sniffing attacks will be guaranteed to be prevented. There are hacker
- tools like dsniff/webmitm and cain that implement SSL Man-In-The-Middle
- attacks. They rely on the client user not bothering to check the cert.
-
- Some people may be confused by the above because they are familiar with
- their Web Browser using SSL (i.e. https://... websites) and those sites
- are authenticated securely without the user's need to verify anything
- manually. The reason why this happens automatically is because 1) their
- web browser comes with a bundle of Certificate Authority certificates
- and 2) the https sites have paid money to the Certificate Authorities to
- have their website certificate signed by them. When using SSL in VNC we
- normally do not do something this sophisticated, and so we have to verify
- the certificates manually. However, it is possible to use Certificate
- Authorities with SSVNC; that method is described below.
-
- You can use the "Fetch Cert" button to retrieve the Cert and then
- after you check it is OK (say, via comparing the MD5 or other info)
- you can "Save" it and use it to verify future connections to servers.
- (However, see the note at the end of this section about CA certificates.)
-
- When "Verify All Certs" is checked, this check is always enforced,
- and so the first time you connect to a new server you may need to
- follow a few dialogs to inspect and save the server certificate.
- See the "Certs... -> Help" for information on how to manage certificates.
-
- "Verify All Certs" is on by default.
-
- Note, however, "Fetch Cert" and "Verify All Certs" are currently disabled
- in the very rare "SSH + SSL" usage mode to avoid SSHing in twice.
- You can manually set a ServerCert or CertsDir in this case if you like.
-
-
- Advanced Method: Certificate Authority (CA):
-
- If you, or your site administrator, goes though the steps of setting up
- a Certificate Authority (CA) to sign the VNC server and/or VNC client
- Certs, that can be used instead and avoids the need to manually verify
- every cert while still authenticating every connection. More info:
- http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca
-
- See the cmdline option -cacert file below in 'SSL Certificates'
- for setting a default ServerCert/CA Cert.
-
- You may also Import the CA Cert and save it to the 'Accepted Certs'
- directory so the "Verify All Certs" automatic checking will find it.
-
- Note that if a Server is using a CA signed certificate instead of
- its own Self-Signed one, then the default "Verify All Certs/Fetch Cert"
- saving mechanism will NOT succeed. You must obtain the CA certificate
- and explicitly set it as the ServerCert or Import it to Accepted Certs.
-
-
- SSL/TLS Variants; VeNCrypt and ANONTLS:
-
- SSVNC can also connect to VNC SSL/TLS variants; namely the VeNCrypt and
- "TLS" VNC Security types. Vino uses the latter (we call it "ANONTLS");
- and a growing number use VeNCrypt (QEMU, ggi, virt-manager, VeNCrypt, Xen.)
-
- Via the VeNCrypt bridge that SSVNC provides, the VeNCrypt/ANONTLS
- support ALSO works with ANY 3rd party VNC Viewers you specify via
- 'Change VNC Viewer' (e.g. RealVNC, TightVNC, UltraVNC, etc.) that do
- not directly support VeNCrypt or ANONTLS. This works on all platforms:
- Unix, MacOSX, and Windows.
-
-
- Notes on VeNCrypt/ANONTLS Auto-detection:
-
- IMPORTANT: VeNCrypt Server Auto-detection *ONLY* occurs in SSL mode
- and when an initial fetch-cert action takes place.
-
- While the initial certificate fetch is taking place SSVNC applies
- heuristics to try to automatically detect the VeNCrypt or ANONTLS
- protocol use by the VNC server. This way it learns that the server
- is using it and then knows to switch to VeNCrypt encrypted SSL/TLS at
- the right point. Then SSVNC makes a second (the real) connection to
- VNC server and connects the VNC viewer to it.
-
- In the default "Verify All Certs" mode, a fetch cert action always
- takes place, and so VeNCrypt/ANONTLS will be autodected.
-
- However, if you have specified an explicit ServerCert or disabled
- "Verify All Certs" then even though the initial fetch cert action is no
- longer needed, it is performed anyway because it allows VeNCrypt/ANONTLS
- auto-detection.
-
- To disabled this initial fetch (e.g. you know the VNC server is normal
- SSL and not VeNCrypt/ANONTLS and want to connect more quickly) then
- select "Do not Probe for VeNCrypt" in the Advanced Options menu.
-
- On the other hand, if you know the VNC server ONLY supports VeNCrypt or
- ANONTLS, to improve the accuracy and speed with which the connection
- takes place, you can specify the one or both of the 'Server uses
- VeNCrypt SSL encryption' and 'Server uses Anonymous Diffie-Hellman'
- in the 'Advanced' options panel. That way guessing via an initial
- probe is not needed or performed. See each options's Advanced Options
- Help for more info.
-
- Note that if you are using VeNCrypt or ANONTLS for REVERSE connections
- (Listen) then you *MUST* set the 'Server uses VeNCrypt SSL encryption'
- (and the ANON-DH if it applies) option in Advanced. Note also that
- REVERSE VeNCrypt and ANONTLS connections currently do not work on
- Windows.
-
- Also, if you are using the "Use SSH+SSL" double tunnel, you MUST set
- 'Server uses VeNCrypt SSL encryption' (and the ANON-DH if it applies)
- because the initial fetch cert is disabled in SSH+SSL mode.
-
-
- Deciphering SSL Negotiation Success or Failure:
-
- Since SSVNC is a "glue program", in this case gluing VNCViewer and stunnel
- together (with possibly a proxy helper) reporting is clumsy at best.
- (In SSH encryption mode, it glues to ssh instead of stunnel.) In most
- cases the programs being "glued" are run in a terminal window where you
- can see the program's output. On Windows you will need to double click
- on the stunnel tray icon to view its log.
-
- Although the output is quite cryptic, you are encouraged to learn to
- recognize some of the errors reported in it.
-
- Here is stunnel output for a case of successfully verifying the VNC
- Server's Certificate:
-
- 2008.11.20 08:09:39 LOG5[1472]: VERIFY OK: depth=0, /C=AU/L=...
- 2008.11.20 08:09:39 LOG6[1472]: SSL connected: new session negotiated
- 2008.11.20 08:09:39 LOG6[1472]: Negotiated ciphers: AES256-SHA SSLv3 ...
-
- Here is a case where the Server's Cert did not match the ServerCert
- we set:
-
- 2008.11.20 08:12:31 LOG4[1662]: VERIFY ERROR: depth=0, error=self ...
- 2008.11.20 08:12:31 LOG3[1662]: SSL_connect: 14090086: error:14090086:SSL
- routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
-
- Here is a case where the Server's Cert has expired:
-
- 2009.12.27 12:20:25 LOG4[25500]: VERIFY ERROR: depth=0, error=certificate
- has expired: /C=AU/L=...
- 2009.12.27 12:20:25 LOG3[25500]: SSL_connect: 14090086: error:14090086:SSL
- routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
-
-
- If you disable "Verify All Certs" and do not supply a ServerCert,
- then there will be no 'VERIFY ...' in the output because the SSVNC
- stunnel accepts the server's cert without question (this is insecure.)
-
- Also in the output will be messages about whether the SSL VNC server
- rejected your connection because it requires you to authenticate
- yourself with a certificate (MyCert). Here is the case when you
- supplied no MyCert:
-
- 2008.11.20 08:16:29 LOG3[1746]: SSL_connect: 14094410: error:14094410:
- SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
-
- or you used a certificate the server did not recognize:
-
- 2008.11.20 08:18:46 LOG3[1782]: SSL_connect: 14094412: error:14094412:
- SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate
-
- or your certificate has been revoked:
-
- 2008.11.20 08:20:08 LOG3[1913]: SSL_connect: 14094414: error:14094414:
- SSL routines:SSL3_READ_BYTES:sslv3 alert certificate revoked
-
-
- SSH:
-
- Click on "Use SSH" if you want to use an *SSH* tunnel instead of SSL
- (then the VNC Server does not need to speak SSL or use STUNNEL or socat).
-
- You will need to be able to login to your account on the remote host
- via SSH (e.g. via password, ssh keys, or ssh-agent).
-
- Specify the SSH hostname and VNC display in the VNC Host:Display entry.
- Use something like:
-
- username@far-away.east:0
-
- if your remote username is different from the one on the local viewer
- machine.
-
- On Windows you *MUST* supply the "username@" part because Putty/Plink
- needs it to work correctly.
-
- "SSH + SSL" is similar but its use is more rare because it requires 2
- encrypted tunnels to reach the VNC server. See the Help under Options
- for more info.
-
- To connect to a non-standard SSH port, see SSH Proxies/Gateways section.
-
- See Tip 8) for how to make this application be SSH-only with the -ssh
- command line option or "sshvnc".
-
- If you find yourself in the unfortunate circumstance that your ssh
- username has a space in it, use %SPACE (or %TAB) like this:
-
- fred%SPACEflintstone@xyzzy.net:0
-
- Remote SSH Command:
-
- In SSH or SSH + SSL mode you can also specify a remote command to run
- on the remote ssh host in the "Remote SSH Command" entry. The default
- is just to sleep a bit (e.g. sleep 15) to make sure the tunnel ports
- are established. Alternatively you could have the remote command start
- the VNC server, e.g.
-
- x11vnc -display :0 -rfbport 5900 -localhost -nopw
-
- When starting the VNC server this way, note that sometimes you will need
- to correlate the VNC Display number with the "-rfbport" (or similar)
- option of the server. E.g. for VNC display :2
-
- VNC Host:Display username@somehost.com:2
- Remote SSH Command: x11vnc -find -rfbport 5902 -nopw
-
- See the Tip 18) for using x11vnc PORT=NNNN feature (or vncserver(1)
- output) to not need to specify the VNC display number or the x11vnc
- -rfbport option.
-
- Windows SSH SERVER: if you are ssh'ing INTO Windows (e.g. CYGWIN SSHD
- server) there may be no "sleep" command so put in something like
- "ping localhost" or "ping -n 10 -w 1000 localhost" to set a short
- delay to let the tunnel ports get established.
-
-
- SSL Certificates:
-
- If you want to use a SSL Certificate (PEM) file to authenticate YOURSELF to
- the VNC server ("MyCert") and/or to verify the identity of the VNC Server
- ("ServerCert" or "CertsDir") select the certificate file by clicking the
- "Certs ..." button before connecting.
-
- Certificate verification is needed to prevent Man-In-The-Middle attacks;
- if it is not done then only passive network sniffing attacks are prevented.
- There are hacker tools like dsniff/webmitm and cain that implement SSL
- Man-In-The-Middle attacks. They rely on the client user not bothering to
- check the cert.
-
-
- See the x11vnc documentation:
-
- http://www.karlrunge.com/x11vnc/ssl.html
-
- for how to create and use PEM SSL certificate files. An easy way is:
-
- x11vnc -ssl SAVE ...
-
- where it will print out its automatically generated certificate to the
- screen and that can be copied safely to the viewer side.
-
- You can also use the "Create Certificate" feature of this program under
- "Certs ...". Just click on it and follow the instructions in the dialog.
- Then copy the cert file to the VNC Server and specify the other one in
- the "Certs ..." dialog.
-
- Alternatively you can use the "Import Certificate" action to paste in a
- certificate or read one in from a file. Or you can use the "Fetch Cert"
- button on the main panel. If "Verify All Certs" is checked, you will
- be forced to check Certs of any new servers the first time you connect.
-
- Note that "Verify All Certs" is on by default so that users who do not
- understand the SSL Man-In-The-Middle problem will not be left completely
- vulnerable to it (everyone still must make the effort to verify new
- certificates by an external method to be completely safe).
-
- To have "Verify All Certs" toggled off at startup, use "ssvnc -nv" or
- set SSVNC_NO_VERIFY_ALL=1 before starting. If you do not even want to
- see the button, use "ssvnc -nvb" or SSVNC_NO_VERIFY_ALL_BUTTON=1.
-
- Use the "-mycert file" option (same as "-cert file") to set a default
- MyCert. This is the same as "mycert=file" (also "cert=file") in the
- ~/.ssvncrc file. See Certs -> Help for more info.
-
- Use the "-cacert file" option (same as "-ca file") to set a default
- ServerCert (or CA). This is the same as "cacert=file" (also "ca=file")
- in the ~/.ssvncrc file. See Certs -> Help for more info.
-
- Use the "-crl file" option to set a default CRL File. This is the same
- as "crl=file" in the ~/.ssvncrc file. See Certs -> Help for more info.
-
- Prefix any of these files with "FORCE:" to make them immutable.
-
-
-
- More Options:
-
- To set other Options, e.g. for View-Only usage or to limit the number
- of colors used, click on the "Options ..." button and read the Help there.
-
- More Info:
-
- Press the 'Proxies', 'Misc', and 'Tips' buttons below.
-
- See also these links for more information:
-
- http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext
- http://stunnel.mirt.net
- http://www.tightvnc.com
-}
-
- set help_misc {
- Windows STUNNEL problems:
-
- Note that on Windows when the Viewer connection is finished by default
- SSVNC will try to kill the STUNNEL process for you.
-
- If Options -> Kill Stunnel Automatically is not set you will be
- prompted if you want SSVNC to try to kill the STUNNEL process for you.
- Usually you will say Yes, however if there are problems connecting
- you may want to look at the STUNNEL Log first.
-
- Before it is killed, double clicking the STUNNEL tray icon (dark green)
- will show you its Log file (useful for debugging connection problems).
-
- Even though SSVNC will kill the STUNNEL process for you, you will
- still need to move the mouse over the icon to make the little picture
- go away!!! This is unfortunate but there does not seem to be a way
- to avoid it.
-
- In some cases you may need to terminate STUNNEL manually from the System
- Tray (right click on dark green icon) and selecting "Exit".
-
- Use -nokillstunnel or killstunnel=0 in ~/.ssvncrc to have SSVNC
- start up with stunnel killing disabled.
-
- Untrusted Local Users:
-
- *IMPORTANT WARNING*: If you run SSVNC on a workstation or computer
- that other users can log into and you DO NOT TRUST these users
- (it is a shame but sometimes one has to work in an environment like
- this), then please note the following warning.
-
- By 'do not trust' we mean they might try to gain access to remote
- machines you connect to via SSVNC. Note that an untrusted local
- user can often obtain root access in a short amount of time; if a
- user has achieved that, then all bets are off for ANYTHING that you
- do on the workstation. It is best to get rid of Untrusted Local
- Users as soon as possible.
-
- Both the SSL and SSH tunnels set up by SSVNC listen on certain ports
- on the 'localhost' address and redirect TCP connections to the remote
- machine; usually the VNC server running there (but it could also be
- another service, e.g. CUPS printing). These are the stunnel(8) SSL
- redirection and the ssh(1) '-L' port redirection. Because 'localhost'
- is used only users or programs on the same workstation that is
- running SSVNC can connect to these ports, however this includes any
- local users (not just the user running SSVNC.)
-
- If the untrusted local user tries to connect to these ports, he may
- succeed by varying degrees to gain access to the remote machine.
- We now list some safeguards one can put in place to try to make this
- more difficult to achieve.
-
- It probably pays to have the VNC server require a password, even
- though there has already been SSL or SSH authentication (via
- certificates or passwords). In general if the VNC Server requires
- SSL authentication of the viewer that helps, unless the untrusted
- local user has gained access to your SSVNC certificate keys.
-
- If the VNC server is configured to only allow one viewer connection
- at a time, then the window of opportunity that the untrusted local
- user can use is greatly reduced: he might only have a second or two
- between the tunnel being set up and the SSVNC vncviewer connecting
- to it (i.e. if the VNC server only allows a single connection, the
- untrusted local user cannot connect once your session is established).
- Similarly, when you disconnect the tunnel is torn down quickly and
- there is little or no window of opportunity to connect (e.g. x11vnc
- in its default mode exits after the first client disconnects).
-
- Also for SSL tunnelling with stunnel(8) on Unix using one of the SSVNC
- prebuilt 'bundles', a patched stunnel is provided that denies all
- connections after the first one, and exits when the first one closes.
- This is not true if the system installed stunnel(8) is used and is
- not true when using SSVNC on Windows.
-
- The following are experimental features that are added to SSVNC to
- improve the situation for the SSL/stunnel and SSH cases. Set them
- via Options -> Advanced -> "STUNNEL Local Port Protections" or
- "SSH Local Port Protections".
-
- STUNNEL:
-
- 1) For SSL tunnelling with stunnel(8) on Unix there is a setting
- 'Use stunnel EXEC mode' that will try to exec(2) stunnel
- instead of using a listening socket. This will require using
- the specially modified vncviewer unix viewer provided by SSVNC.
- The mode works well and is currently set as the default.
- Disable it if it causes problems or conflicts.
-
- 2) For SSL tunnelling with stunnel(8) on Unix there is a setting
- 'Use stunnel IDENT check' (experimental) to limit socket
- connections to be from you (this assumes the untrusted local
- user has not become root on your workstation and has modified
- your local IDENT check service; if he has you have much bigger
- problems to worry about...)
-
- Neither of the above methods are available on Windows.
-
- SSH:
-
- 1) There is also a simple LD_PRELOAD trick for SSH to limit the
- number of accepted port redirection connections. This makes the
- window of time the untrusted local user can connect to the tunnel
- much smaller. Enable it via Options -> Advanced -> "SSH Local
- Port Protections". You will need to have the lim_accept.so file
- in your SSVNC package. The mode works well and is currently set
- as the default. Disable it if it causes problems or conflicts.
-
- The above method is not available on Windows.
-
- The main message is to 'Watch your Back' when you connect via the
- SSVNC tunnels and there are users you don't trust on your workstation.
- The same applies to ANY use of SSH '-L' port redirections or outgoing
- stunnel SSL redirection services.
-}
-
- set help_prox {
- Here are a number of long sections on all sorts of proxies, Web, SOCKS,
- SSH tunnels/gateways, UltraVNC, Single Click, etc., etc.
-
-
- Proxies/Gateways:
-
- If an intermediate proxy is needed to make the SSL connection
- (e.g. a web gateway out of a firewall) enter it in the "Proxy/Gateway"
- entry box:
-
- VNC Host-Display: host:number
- Proxy/Gateway: proxy-host:port
- e.g.:
- VNC Host-Display: far-away.east:0
- Proxy/Gateway: myproxy.west:8080
-
-
- If the "double proxy" case is required (e.g. coming out of a web
- proxied firewall environment and then INTO a 2nd proxy to ultimately
- reach the VNC server), separate them via a comma, e.g.:
-
- VNC Host-Display: far-away:0
- Proxy/Gateway: myproxy.west:8080,myhome.net:443
-
- So it goes: viewer -> myproxy.west -> myhome.net -> far-away (VNC)
-
- The proxies are assumed to be Web proxies. To use SOCKS proxies:
-
- VNC Host-Display: far-away.east:0
- Proxy/Gateway: socks://mysocks.west:1080
-
- Use socks5:// to force the SOCKS5 proxy protocol (e.g. for ssh -D).
-
- You can prefix web proxies with http:// in SSL mode but it doesn't matter
- since that is the default for a proxy. (NOTE that in SSH or SSH+SSL
- mode you MUST supply the http:// prefix for web proxies because in those
- modes an SSH tunnel is the default proxy type: see the next section.)
-
- Note that Web proxies are often configured to ONLY allow outgoing
- connections to ports 443 (HTTPS) and 563 (SNEWS), so you might
- have run the VNC server (or router port redirector) on those ports.
- SOCKS proxies usually have no restrictions on port number.
-
- You can chain up to 3 proxies (any combination of web (http://) and
- socks://) by separating them with commas (i.e. first,second,third).
-
- Proxies also work for un-encrypted connections ("None" or vnc://, Tip 5)
-
- See the ss_vncviewer description and x11vnc FAQ for info on proxies:
-
- http://www.karlrunge.com/x11vnc/faq.html#ss_vncviewer
- http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-java-viewer-proxy
-
-
- SSH Proxies/Gateways:
-
- Proxy/Gateway also applies to SSH mode, it is a usually a gateway SSH
- machine to log into via ssh that is not the workstation running the
- VNC server. However, Web and SOCKS proxies can also be used (see below).
-
- For example if a company had a central login server: "ssh.company.com"
- (accessible from the internet) and the internal workstation with VNC was
- named "joes-pc", then to create an SSH tunnel one could put this in:
-
- VNC Host:Display: joes-pc:0
- Proxy/Gateway: ssh.company.com
-
- It is OK if the hostname "joes-pc" only resolves inside the firewall.
-
- The 2nd leg, from ssh.company.com -> joes-pc is done by a ssh -L
- redir and is not encrypted (but the viewer -> ssh.company.com 1st leg is
- an encrypted tunnel).
-
- To SSH encrypt BOTH legs, try the "double SSH gateway" method using
- the "comma" notation:
-
- VNC Host:Display: localhost:0
- Proxy/Gateway: ssh.company.com,joes-pc
-
- this requires an SSH server also running on joes-pc. So an initial SSH
- login is done to ssh.company.com, then a 2nd SSH is performed (through
- port a redirection of the first) to login straight to joes-pc where
- the VNC server is running.
-
- Use username@host (e.g. joe@joes-pc jsmith@ssh.company.com) if the
- user names differ between the various machines.
-
- NOTE: On Windows you MUST always supply the username@ because putty's
- plink requires it.
-
-
- NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other
- than 22) you need to use the Proxy/Gateways as well. E.g. something
- like this for port 2222:
-
- VNC Host:Display: localhost:0
- Proxy/Gateway: joe@far-away.east:2222
-
- On Unix/MacOSX the username@ is not needed if it is the same as on
- the client. This will also work going to a different internal machine,
- e.g. "joes-pc:0" instead of "localhost:0", as in the first example.
-
-
- A Web or SOCKS proxy can also be used with SSH. Use this if you are
- inside a firewall that prohibits direct connections to remote SSH servers.
-
- VNC Host:Display: joe@far-away.east:0
- Proxy/Gateway: http://myproxy.west:8080
-
- or for SOCKS:
-
- VNC Host:Display: joe@far-away.east:0
- Proxy/Gateway: socks://mysocks.west:1080
-
- Use socks5://... to force the SOCKS5 version. Note that the http://
- prefix is REQUIRED for web proxies in SSH or SSH+SSL modes (but it is
- the default proxy type in SSL mode.)
-
- You can chain up to 3 proxies (any combination of http://, socks://
- and ssh) by separating them with commas (i.e. first,second,third).
-
- Note: the Web and/or SOCKS proxies must come before any SSH gateways.
-
- For a non-standard SSH port and a Web or SOCKS proxy try:
-
- VNC Host:Display: localhost:0
- Proxy/Gateway: http://myproxy.west:8080,joe@far-away.east:2222
-
- Even the "double SSH gateway" method (2 SSH encrypted legs) described
- above works with an initial Web or SOCKS proxy, e.g.:
-
- VNC Host:Display: localhost:0
- Proxy/Gateway: socks://mysocks.west:1080,ssh.company.com,joes-pc
-
-
-
- Some Notes on SSH localhost tunnelling with SSH options
- NoHostAuthenticationForLocalhost=yes and UserKnownHostsFile=file:
-
- Warning: Note that for proxy use with ssh(1), tunnels going through
- 'localhost' are used. This means ssh(1) thinks the remote hostname is
- 'localhost', which may cause collisions and confusion when storing
- and checking SSH keys.
-
- By default on Unix when a 'localhost' ssh host is involved the
- ssh option -o NoHostAuthenticationForLocalhost=yes is applied (see
- ssh_config(1) for details.) This avoids the warnings and ssh refusing
- to connect, but it reduces security. A man in the middle attack may
- be possible. SSVNC prints out a warning in the terminal every time
- the NoHostAuthenticationForLocalhost option is used.
-
- On Unix to disable the use of NoHostAuthenticationForLocalhost set the env.
- variable SSVNC_SSH_LOCALHOST_AUTH=1. This may induce extra ssh(1) dialogs.
-
- On Unix a MUCH SAFER and more convenient way to proceed is to set the
- known hosts option in Options -> Advanced -> 'Private SSH KnownHosts file'
- Then, only for the host in the current profile, a private known_hosts
- file will be used and so there will be no 'localhost' collisions.
- This method is secure (assuming you verify the SSH key fingerprint)
- and avoids the man in the middle attack.
-
- On Windows, Putty/Plink is used and does not have the UserKnownHosts
- or NoHostAuthenticationForLocalhost features. Keys are stored in
- the registry as localhost:port pairs and so it is possible to use the
- 'Port Slot' option to keep the keys separate to avoid the dialogs and
- also maintain good security.
-
- Note that for the "double SSH gateway" method the risk from using
- NoHostAuthenticationForLocalhost is significantly less because the first
- ssh connection does not use the option (it connects directly to the remote
- host) and the second one is only exposed for the leg inside the first
- gateway (but is still vulnerable there when NoHostAuthenticationForLocalhost
- is used.)
-
- As with a username that contains a space, use %SPACE (or %TAB) to
- indicate it in the SSH proxies, e.g. john%SPACEsmith@ssh.company.com
-
- UltraVNC Proxies/Gateways:
-
- UltraVNC has a "repeater" tool (http://www.uvnc.com/addons/repeater.html
- and http://koti.mbnet.fi/jtko/) that acts as a VNC proxy. SSVNC can
- work with both mode I and mode II schemes of this repeater.
-
- For Unix and MacOS X there is another re-implementation of the
- UltraVNC repeater:
-
- http://www.karlrunge.com/x11vnc/ultravnc_repeater.pl
-
- So one does not need to run the repeater on a Windows machine.
-
- Note that even though the UltraVNC repeater tool is NOT SSL enabled,
- it can nevertheless act as a proxy for SSVNC SSL connections.
- This is because, just as with a Web proxy, the proxy negotiations
- occur before the SSL traffic starts. (There is a separate UltraVNC
- tool, repeater_SSL.exe, that is SSL enabled and is discussed below.)
-
- Note: it seems only SSL SSVNC connections make sense with the
- UltraVNC repeater. SSH connections (previous section) do not seem to
- and so are not enabled to (let us know if you find a way to use it.)
-
- Unencrypted (aka Direct) SSVNC VNC connections (Vnc:// prefix in
- 'VNC Host:Display'; see Tip 5) also work with the UltraVNC repeater.
-
- MODE I REPEATER:
-
- For the mode I UltraVNC repeater the Viewer initiates the connection
- and passes a string that is the VNC server's IP address (or hostname)
- and port or display to the repeater (the repeater then makes the
- connection to the server host and then exchanges data back and forth.)
- To do this in SSVNC:
-
- VNC Host:Display: :0
- Proxy/Gateway: repeater://myuvncrep.west:5900+joes-pc:1
-
- Where "myuvncrep.west" is running the UltraVNC repeater and
- "joes-pc:1" is the VNC server the repeater will connect us to.
-
- Note here that the VNC Host:Display can be anything because it is
- not used; we choose :0. You cannot leave VNC Host:Display empty.
-
- The Proxy/Gateway format is repeater://proxy:port+vncserver:display.
- The string after the "+" sign is passed to the repeater server for
- it to interpret (and so does not have to be the UltraVNC repeater;
- you could create your own if you wanted to.) For this example,
- instead of joes-pc:1 it could be joes-pc:5901 or 192.168.1.4:1,
- 192.168.1.4:5901, etc.
-
- If you do not supply a proxy port, then the default 5900 is assumed,
- e.g. use repeater://myuvncrep.west+joes-pc:1 for port 5900 on
- myuvncrep.west then connecting to port 5901 on joes-pc.
-
- X11VNC: For mode I operation the VNC server x11vnc simply runs as
- a normal SSL/VNC server:
-
- x11vnc -ssl SAVE
-
- because the repeater will connect to it as a VNC client would.
- For mode II operation additional options are needed (see below.)
-
-
- MODE II REPEATER:
-
- For the mode II repeater both the VNC viewer and VNC server initiate
- TCP connections to the repeater proxy. In this case they pass a string
- that identifies their mutual connection via "ID:NNNN", for example:
-
- VNC Host:Display: :0
- Proxy/Gateway: repeater://myuvncrep.west:5900+ID:2345
-
- again, the default proxy port is 5900 if not supplied. And we need
- to supply a placeholder display ":0".
-
- The fact that BOTH the VNC viewer and VNC server initiate outgoing
- TCP connections to the repeater makes some things tricky, especially
- for the SSL aspect. In SSL one side takes the 'client' role and
- the other side must take the 'server' role. These roles must be
- coordinated correctly or otherwise the SSL handshake will fail.
-
- We now describe two scenarios: 1) SSVNC in Listening mode with STUNNEL
- in 'SSL server' role; and 2) SSVNC in Forward mode with STUNNEL in
- 'SSL client' role. For both cases we show how the corresponding
- VNC server x11vnc would be run.
-
- SSVNC Listening mode / STUNNEL 'SSL server' role:
-
- By default, when using SSL over a reverse connection the x11vnc VNC
- server will take the 'SSL client' role. This way it can connect to a
- standard STUNNEL (SSL server) redirecting connections to a VNC viewer
- in Listen mode. This is how SSVNC with SSL is normally intended to
- be used for reverse connections (i.e. without the UltraVNC Repeater.)
-
- To do it this way with the mode II UltraVNC Repeater; you set
- Options -> Reverse VNC Connection, i.e. a "Listening Connection".
- You should disable 'Verify All Certs' unless you have already
- saved the VNC Server's certificate to Accepted Certs. Or you can
- set ServerCert to the saved certificate. Then click 'Listen'.
- In this case an outgoing connection is made to the UltraVNC
- repeater, but everything else is as for a Reverse connection.
-
- Note that in Listening SSL mode you must supply a MyCert or use the
- "listen.pem" one you are prompted by SSVNC to create.
-
- X11VNC command:
-
- x11vnc -ssl -connect_or_exit repeater://myuvncrep.west+ID:2345
-
-
- SSVNC Forward mode / STUNNEL 'SSL client' role:
-
- x11vnc 0.9.10 and later can act in the 'SSL server' role for Reverse
- connections (i.e. as it does for forward connections.) Set these
- x11vnc options: '-env X11VNC_DISABLE_SSL_CLIENT_MODE=1 -sslonly'
-
- The -sslonly option is to prevent x11vnc from thinking the delay in
- connection implies VeNCrypt instead of VNC over SSL. With x11vnc
- in X11VNC_DISABLE_SSL_CLIENT_MODE mode, you can then have SSVNC make
- a regular forward connection to the UltraVNC repeater.
-
- Note that SSVNC may attempt to do a 'Fetch Cert' action in forward
- connection mode to either retrieve the certificate or probe for
- VeNCrypt and/or ANONDH. After that 'Fetch Cert' is done the
- connection to the UltraVNC repeater will be dropped. This is a
- problem for the subsequent real VNC connection. You can disable
- 'Verify All Certs' AND also set 'Do not Probe for VeNCrypt'
- to avoid the 'Fetch Cert' action. Or, perhaps better, add to
- x11vnc command line '-connect_or_exit repeater://... -loop300,2'
- (in addition to the options in the previous paragraphs.) That way
- x11vnc will reconnect once to the Repeater after the 'Fetch Cert'
- action. Then things should act pretty much as a normal forward
- SSL connection.
-
- X11VNC 0.9.10 command (split into two lines):
-
- x11vnc -ssl -connect_or_exit repeater://myuvncrep.west+ID:2345 \
- -env X11VNC_DISABLE_SSL_CLIENT_MODE=1 -loop300,2 -sslonly
-
- We recommend using "SSVNC Forward mode / STUNNEL 'SSL client' role"
- if you are connecting to x11vnc 0.9.10 or later. Since this does
- not use Listen mode it should be less error prone and less confusing
- and more compatible with other features. Be sure to use all of
- the x11vnc options in the above command line. To enable VeNCrypt,
- replace '-sslonly' with '-vencrypt force'. If you do not indicate
- them explicitly to SSVNC, SSVNC may have to probe multiple times for
- VeNCrypt and/or ANONDH. So you may need '-loop300,4' on the x11vnc
- cmdline so it will reconnect to the UltraVNC repeater 3 times.
-
-
- Note that for UNENCRYPTED (i.e. direct) SSVNC connections (see vnc://
- in Tip 5) using the UltraVNC Repeater mode II there is no need to
- use a reverse "Listening connection" and so you might as well use
- a forward connection.
-
- For Listening connections, on Windows after the VNC connection you
- MUST manually terminate the listening VNC Viewer (and connect again
- if desired.) Do this by going to the System Tray and terminating
- the Listening VNC Viewer. Subsequent connection attempts using the
- repeater will fail unless you do this and restart the Listen.
-
- On Unix and MacOS X after the VNC connection the UltraVNC repeater
- proxy script will automatically restart and reconnect to the repeater
- for another connection. So you do not need to manually restart it.
- To stop the listening, kill the listening VNC Viewer with Ctrl-C.
-
- In the previous sections it was mentioned one can chain up to 3
- proxies together by separating them with commas: proxy1,proxy2,proxy3.
- Except where explicitly noted below this should work for "repeater://..."
- as the final proxy. E.g. you could use a web proxy to get out of a
- firewall, and then connect to a remote repeater.
-
- The UltraVNC SSL enabled repeater_SSL.exe is discussed below.
-
-
- UltraVNC Single Click:
-
- UltraVNC has Single Click (SC) Windows VNC servers that allow naive
- users to get them running very easily (a EXE download and a few
- mouse clicks). See http://sc.uvnc.com/ for details on how to create
- these binaries. Also there is a how-to here:
- http://www.simply-postcode-lookup.com/SingleClickUltraVNC/SingleClickVNC.htm
-
- The SC EXE is a VNC *server* that starts up a Reverse VNC connection
- to a Listening Viewer (e.g. the viewer address/port/ID is hardwired
- into the SC EXE). So SC is not really a proxy, but it can be used
- with UltraVNC repeater proxies and so we describe it here.
-
- One important point for SC III binary creation: do NOT include
- "-id N" in the helpdesk.txt config file. This is because the with
- SSVNC the Ultra VNC repeater IS NOT USED (see below for how to
- use it). Use something like for helpdesk.txt:
-
- [TITLE]
- My UltraVNC SC III
-
- [HOST]
- Internet Support XYZ
- -sslproxy -connect xx.xx.xx.xx:5500 -noregistry
-
- (replace xx.xx.xx.xx with IP address or hostname of the SSVNC machine.)
-
- The Unix SSVNC vncviewer supports the both the unencrypted "SC I"
- mode and the SSL encrypted "SC III" mode. For both cases SSVNC
- must be run in Listening mode (Options -> Reverse VNC Connection)
-
- For SC I, enable Reverse VNC Connection and put Vnc://0 (see Tip 5
- below) in the VNC Host:Display to disable encryption (use a different
- number if you are not using the default listening port 5500).
- Then click on the "Listen" button and finally have the user run your
- Single Click I EXE.
-
- BTW, we used this for a SC I helpdesk.txt:
-
- [TITLE]
- My UltraVNC SC I
-
- [HOST]
- Internet Support XYZ
- -connect xx.xx.xx.xx:5500 -noregistry
-
- For SC III (SSL), enable Reverse VNC Connection and then UNSET "Verify
- All Certs" (this is required). Let the VNC Host:Display be ":0"
- (use a different number if you are not using the default listening
- port 5500). Then click on the "Listen" button and finally have the
- user run your Single Click III EXE.
-
- Note that in Listening SSL mode you MUST supply a MyCert or use the
- "listen.pem" one you are prompted by SSVNC to create.
-
-
- UltraVNC repeater_SSL.exe proxy:
-
- For repeater_SSL.exe SSL usage, with Single Click III or otherwise
- (available at http://www.uvnc.com/pchelpware/SCIII/index.html)
- it helps to realize that the ENTIRE connection is SSL encrypted,
- even the proxy host:port/ID:NNNN negotiation, and so a different
- approach needs to be taken from that described above in 'UltraVNC
- Proxies/Gateways'. In this case do something like this:
-
- VNC Host:Display: :0
- Proxy/Gateway: sslrepeater://myuvncrep.west:443+ID:2345
-
- The sslrepeater:// part indicates the entire ID:XYZ negotiation must
- occur inside the SSL tunnel. Listening mode is not required in this
- case: a forward VNC connection works fine (and is recommended).
- As before, the ":0" is simply a placeholder and is not used.
- Note that the UltraVNC repeater_SSL.exe listens on port 443 (HTTPS),
- (it is not clear that it can be modified to use another port.)
-
- Non-ID connections sslrepeater://myuvncrep.west:443+host:disp also
- work, but the 2nd leg repeater <-> host:disp must be unencrypted.
- The first leg SSVNC <-> repeater is, however, SSL encrypted.
-
- sslrepeater:// only works on Unix or MacOSX using the provided
- SSVNC vncviewer. The modified viewer is needed; stock VNC viewers
- will not work. Also, proxy chaining (bouncing off of more than one
- proxy) currently does not work for repeater_SSL.exe.
-
-
- VeNCrypt is treated as a proxy:
-
- SSVNC supports the VeNCrypt VNC security type. You will find out more
- about this security type in the other parts of the Help documentation.
- In short, it does a bit of plain-text VNC protocol negotiation before
- switching to SSL/TLS encryption and authentication.
-
- SSVNC implements its VeNCrypt support as final proxy in a chain
- of proxies. You don't need to know this or specify anything, but
- it is good to know since it uses up one of the 3 proxies you are
- allowed to chain together. If you watch the command output you will
- see the vencrypt:// proxy item.
-
- You can specify that a VNC server uses VeNCrypt (Options -> Advanced)
- or you can let SSVNC try to autodetect VeNCrypt.
-
-
- IPv6 can be treated as a proxy for UN-ENCRYPTED connections:
-
- Read Tip 20 about SSVNC's IPv6 (128 bit IP addresses) support.
- In short, because stunnel and ssh support IPv6 hostnames and
- addresses, SSVNC does too without you needing to do anything.
-
- However, in some rare usage modes you will need to specify the IPv6
- server destination in the Proxy/Gateway entry box. The only case
- this appears to be needed is when making an un-encrypted connection
- to an IPv6 VNC server. In this case neither stunnel nor ssh are
- used and you need to specify something like this:
-
- VNC Host:Display: localhost:0
- Proxy/Gateway: ipv6://2001:4860:b009::68:5900
-
- and then select 'None' as the encryption type. Note that the above
- 'localhost:0' setting can be anything; it is basically ignored.
-
- Note that on Unix, MacOSX, and Windows un-encrypted ipv6 connections
- are AUTODETECTED and so you likely NEVER need to supply ipv6://
- Only try it if you encounter problems. Also note that the ipv6://
- proxy type does not work on Windows, so only the autodetection is
- available there.
-
- Note that if there is some other proxy, e.g. SOCKS or HTTP and that
- proxy server is an IPv6 host (or will connect you to one) then any
- sort of connection through that proxy will work OK: un-encrypted as
- well as SSL or SSH connections, etc.
-
- Unencrypted connection is the only special case where you may need
- to specify an ipv6:// proxy. If you find another use let us know.
-
- See Tip 20 for more info.
-}
-
- set help_tips {
- Tips and Tricks:
-
- Table of Contents:
-
- 1) Connect to Non-Standard SSH port.
- 2) Reverse VNC connections (Listening)
- 3) Global options in ~/.ssvncrc
- 4) Fonts
- 5) vnc://host for un-encrypted connection
- 6) Home directory for memory stick usage, etc.
- 7) vncs:// vncssl:// vnc+ssl:// vnc+ssh:// URL-like prefixes
- 8) sshvnc / -ssh SSH only GUI
- 9) tsvnc / -ts Terminal services only GUI (SSH+x11vnc)
- 10) 2nd GUI window on Unix/MacOSX
- 11) Ctrl-L or Button3 to Load profile
- 12) SHELL command or Ctrl-S for SSH terminal w/o VNC
- 13) KNOCK command for port-knock sequence
- 14) Unix/MacOSX general SSL redirector (not just VNC)
- 15) Environment variables
- 16) Bigger "Open File" dialog window
- 17) Unix/MacOSX extra debugging output
- 18) Dynamic VNC Server Port determination with SSH
- 19) No -t ssh cmdline option for older sshd
- 20) IPv6 support.
-
- 1) To connect in SSH-Mode to a server running SSH on a non-standard
- port (22 is the standard port) you need to use the Proxy/Gateway
- setting. The following is from the Proxies Help panel:
-
- NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other
- than 22) you need to use the Proxy/Gateways as well. E.g. something
- like this for port 2222:
-
- VNC Host:Display: localhost:0
- Proxy/Gateway: joe@far-away.east:2222
-
- The username@ is not needed if it is the same as on the client. This
- will also work going to a different internal machine, e.g. "joes-pc:0"
- instead of "localhost:0", as in the first example.
-
- 2) Reverse VNC connections (Listening) are possible as well.
- In this case the VNC Server initiates the connection to your
- waiting (i.e. listening) SSVNC viewer.
-
- Go to Options and select "Reverse VNC connection". In the 'VNC
- Host:Display' entry box put in the number (e.g. "0" or ":0", or
- ":1", etc) that corresponds to the Listening display (0 -> port
- 5500, 1 -> port 5501, etc.) you want to use. Then clicking on
- 'Listen' puts your SSVNC viewer in a "listening" state on that
- port number, waiting for a connection from the VNC Server.
-
- On Windows or using a 3rd party VNC Viewer multiple, simultaneous
- reverse connections are always enabled. On Unix/MacOSX with the
- provided ssvncviewer they are disabled by default. To enable them:
- Options -> Advanced -> Unix ssvncviewer -> Multiple LISTEN Connections
-
- Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel
- only listen on that interface. IPv6 works too, e.g. :::0 or ::1:0
- This also works for UN-encrypted reverse connections as well ('None').
-
- See the Options Help for more info.
-
- 3) You can put global options in your ~/.ssvncrc file (ssvnc_rc on
- Windows). Currently they are:
-
- Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have
- the application start up in the given mode.
-
- desktop_type=wmaker (e.g.) to switch the default Desktop Type.
-
- desktop_size=1280x1024 (e.g.) to switch the default Desktop Size.
-
- desktop_depth=24 (e.g.) to switch the default Desktop Color Depth
-
- xserver_type=Xdummy (e.g.) to switch the default X Server Type.
-
- (The above 4 settings apply only to the Terminal Services Mode.)
-
- noenc=1 (same as the -noenc option for a 'No Encryption' option)
- noenc=0 (do not show the 'No Encryption' option)
-
- killstunnel=1 (same as -killstunnel), on Windows automatically kills
- the STUNNEL process when the viewer exits. Disable via killstunnel=0
- and -nokillstunnel.
-
- ipv6=0 act as though IPv6 was not detected.
- ipv6=1 act as though IPv6 was detected.
-
- cotvnc=1 have the default vncviewer on Mac OS X be the Chicken of
- the VNC. By default the included ssvnc X11 vncviewer is used
- (requires Mac OS X X11 server to be running.)
-
- mycert=file (same as -mycert file option). Set your default MyCert
- to "file". If file does not exist ~/.vnc/certs/file is used.
-
- cacert=file (same as -cacert file option). Set your default ServerCert
- to "file". If file does not exist ~/.vnc/certs/file is used. If
- file is "CA" then ~/.vnc/certs/CA/cacert.pem is used.
-
- crl=file (same as -crl file option). Set your default CRL File
- to "file". If file does not exist ~/.vnc/certs/file is used.
-
- Prefix any of these cert/key files with "FORCE:" to make them
- immutable, e.g. "cacert=FORCE:CA".
-
- You can set any environment variable in ~/.ssvncrc by using a line
- like env=VAR=value, for example: env=SSVNC_FINISH_SLEEP=2
-
- To change the fonts (see Tip 4 below for examples):
-
- font_default=tk-font-name (sets the font for menus and buttons)
- font_fixed=tk-font-name (sets the font for help text)
-
- 4) Fonts: To change the tk fonts, set these environment variables
- before starting up ssvnc: SSVNC_FONT_DEFAULT and SSVNC_FONT_FIXED.
- For example:
-
- % env SSVNC_FONT_DEFAULT='helvetica -20 bold' ssvnc
- % env SSVNC_FONT_FIXED='courier -14' ssvnc
-
- or set both of them at once. You can also set 'font_default' and
- 'font_fixed' in your ~/.ssvncrc. E.g.:
-
- font_default=helvetica -16 bold
- font_fixed=courier -12
-
- 5) If you want to make a Direct VNC connection, WITH *NO* SSL OR
- SSH ENCRYPTION or authentication, use the "vnc://" prefix in the
- VNC Host:Display entry box, e.g. "vnc://far-away.east:0" This
- also works for reverse connections, e.g. vnc://0
-
- Use Vnc:// (i.e. capital 'V') to avoid being prompted if you are
- sure you want no encryption. For example, "Vnc://far-away.east:0"
- Shift+Ctrl-E in the entry box is a short-cut to add or remove
- the prefix "Vnc://" from the host:disp string.
-
- You can also run ssvnc with the '-noenc' cmdline option (now
- the default) to have a check option 'None' that lets you turn off
- Encryption (and profiles will store this setting). Pressing Ctrl-E
- on the main panel is a short-cut to toggle between the -noenc 'No
- Encryption' mode and normal mode. The option "Show 'No Encryption'
- Option" under Options also toggles it.
-
- The '-enc' option disables the button (and so makes it less obvious
- to naive users how to disable encryption.)
-
- Note as of SSVNC 1.0.25 the '-noenc' mode is now the default. I.e.
- the 'No Encryption' option ('None') is shown by default. When
- you select 'None' you do not need to supply the "vnc://" prefix.
- To disable the button supply the '-enc' cmdline option.
-
- Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=1 in your environment is
- the same as -noenc. You can also put noenc=1 in your ~/.ssvncrc file.
-
- Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=0 in your environment is
- the same as -enc. You can also put noenc=0 in your ~/.ssvncrc file.
-
- Please be cautious/thoughtful when you make a VNC connection with
- encryption disabled. You may send sensitive information (e.g. a
- password) over the network that can be sniffed.
-
- It is also possible (although difficult) for someone to hijack an
- existing unencrypted VNC session.
-
- Often SSVNC is used to connect to x11vnc where the Unix username and
- password is sent over the channel. It would be a very bad idea to
- let that data be sent over an unencrypted connection! In general,
- it is not wise to have a plaintext VNC connection.
-
- Note that even the VNC Password challenge-response method (the password
- is not sent in plaintext) leaves your VNC password susceptible to a
- dictionary attack unless encryption is used to hide it.
-
- So (well, before we made the button visible by default!) we forced
- you to learn about and supply the "vnc://" or "Vnc://" prefix to
- the host:port or use -noenc or the "Show 'No Encryption' Option"
- to disable encryption. This is a small hurdle, but maybe someone
- will think twice. It is a shame that VNC has been around for
- over 10 years and still does not have built-in strong encryption.
-
- Note the Vnc:// or vnc:// prefix will be stored in any profile that
- you save so you do not have to enter it every time.
-
- Set the env var SSVNC_NO_ENC_WARN=1 to skip the warning prompts the
- same as the capitalized Vnc:// does.
-
- 6) Mobile USB memory stick / flash drive usage: You can unpack
- ssvnc to a flash drive for impromptu usage (e.g. from a friends
- computer).
-
- If you create a directory "Home" in the toplevel ssvnc directory,
- then that will be the default location for your VNC profiles
- and certs. So they follow the drive this way. If you run like
- this: "ssvnc ." or "ssvnc.exe ." the "Home" directory will be
- created for you.
-
- WARNING: if you use ssvnc from an "Internet Cafe", i.e. an
- untrusted computer, an unscrupulous person may be capturing
- keystrokes, etc.!
-
- You can also set the SSVNC_HOME env. var. to point to any
- directory you want. It can be set after starting ssvnc by putting
- HOME=/path/to/dir in the Host:Display box and clicking "Connect".
-
- For a Windows BAT file to get the "Home" directory correct
- something like this might be needed:
-
- cd \ssvnc\Windows
- start \ssvnc\Windows\ssvnc.exe
-
- 7) In the VNC Host:Display entry you can also use these "URL-like"
- prefixes:
-
- vncs://host:0, vncssl://host:0, vnc+ssl://host:0 for SSL
-
- and
-
- vncssh://host:0, vnc+ssh://host:0 for SSH
-
- There is no need to toggle the SSL/SSH setting. These also work
- from the command line, e.g.: ssvnc vnc+ssh://mymachine:10
-
- 8) If you want this application to be SSH only, then supply the
- command line option "-ssh" or set the env. var SSVNC_SSH_ONLY=1.
-
- Then no GUI elements specific to SSL will appear (the
- documentation wills still refer to the SSL mode, however).
- To convert a running app to ssh-only select "Mode: SSH-Only"
- in Options.
-
- The wrapper scripts "sshvnc" and "sshvnc.bat" will start it up
- automatically this way.
-
- Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=sshvnc"
- to have the tool always start up in that mode.
-
- 9) For an even simpler "Terminal Services" mode use "tsvnc" or
- "tsvnc.bat" (or "-ts" option). This mode automatically launches
- x11vnc on the remote side to find or create your Desktop session
- (usually the Xvfb X server). So x11vnc must be available on the
- remote server machines under "Terminal Services" mode.
-
- From a full ssvnc you can press Ctrl-h to go into ssh-only mode
- and Ctrl-t to toggle between "tsvnc" and "ssvnc" modes. The
- Options Mode menu also let you switch.
-
- Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc"
- to have the tool always start up in that mode.
-
- 10) On Unix to get a 2nd GUI (e.g. for a 2nd connection) press Ctrl-N
- on the GUI. If only the xterm window is visible you can press
- Ctrl-N or try Ctrl-LeftButton -> New SSVNC_GUI. On Windows you
- will have to manually Start a new one: Start -> Run ..., etc.
-
- 11) Pressing the "Load" button or pressing Ctrl-L or Clicking the Right
- mouse button on the main GUI will invoke the Load dialog.
-
- Pressing Ctrl-O on the main GUI will bring up the Options Panel.
- Pressing Ctrl-A on the main GUI will bring up the Advanced Options.
-
- 12) If you use "SHELL" for the "Remote SSH Command" (or in the display
- line: "user@hostname cmd=SHELL") then you get an SSH shell only:
- no VNC viewer will be launched. On Windows "PUTTY" will try
- to use putty.exe (better terminal emulation than plink.exe).
-
- A ShortCut for this is Ctrl-S with user@hostname in the entry box.
-
- 13) If you use "KNOCK" for the "Remote SSH Command" (or in the display
- line "user@hostname cmd=KNOCK") then only the port-knocking is done.
-
- A ShortCut for this is Ctrl-P with hostname the entry box.
-
- If it is KNOCKF, i.e. an extra "F", then the port-knocking
- "FINISH" sequence is sent, if any. A ShortCut for this
- Shift-Ctrl-P as long as hostname is present.
-
- 14) On Unix to have SSVNC act as a general STUNNEL redirector (i.e. no
- VNC), put the desired host:port in VNC Host:Display (use a
- negative port value if it is to be less than 200), then go to
- Options -> Advanced -> Change VNC Viewer. Change the "viewer"
- command to be "xmessage OK" or "xmessage <port>" (or sleep) where
- port is the desired local listening port. Then click Connect.
- If you didn't set the local port look for it in the terminal output.
-
- On Windows set 'viewer' to "NOTEPAD" or similar; you can't
- control the port though. It is usually 5930, 5931, ... Watch
- the messages or look at the stunnel log.
-
- 15) Tricks with environment variables:
-
- You can change the X DISPLAY variable by typing DISPLAY=... into
- VNC Host:Display and hitting Return or clicking Connect. Same
- for HOME=. On Mac, you can set DYLD_LIBRARY_PATH=... too.
- It should propagate down the viewer.
-
- Setting SLEEP=n increases the amount of time waited before
- starting the viewer. The env. var. SSVNC_EXTRA_SLEEP also does
- this (and also Sleep: Option setting) Setting FINISH=n sets the
- amount of time slept before the Terminal window exits on Unix
- and MacOS X. (same as SSVNC_FINISH_SLEEP env. var.)
-
- Full list of parameters HOME/SSVNC_HOME, DISPLAY/SSVNC_DISPLAY
- DYLD_LIBRARY_PATH/SSVNC_DYLD_LIBRARY_PATH, SLEEP/SSVNC_EXTRA_SLEEP
- FINISH/SSVNC_FINISH_SLEEP, DEBUG_NETSTAT, REPEATER_FORCE,
- SSH_ONLY, TS_ONLY, NO_DELETE, BAT_SLEEP, IPV6/SSVNC_IPV6=0 or 1.
- See below for more info. (the ones joined by "/" are equivalent
- names, and the latter can be set as an env. var. as well.)
-
- After you set the parameter, clear out the 'VNC Host:Display'
- entry and replace it with the actual host and display number.
-
- To replace the xterm terminal where most of the external commands
- are run set SSVNC_XTERM_REPLACEMENT to a command that will run
- a command in a terminal. I.e.: "$SSVNC_XTERM_REPLACEMENT cmd"
- will run cmd. If present, %GEOMETRY is expanded to a desired
- +X+Y geometry. If present, %TITLE is expanded to a desired title.
- Examples: SSVNC_XTERM_REPLACEMENT='gnome-terminal -e'
- SSVNC_XTERM_REPLACEMENT='gnome-terminal -t "%TITLE" -e'
- SSVNC_XTERM_REPLACEMENT='konsole -e'
-
- More info: EXTRA_SLEEP: seconds of extra sleep in scripts;
- FINISH_SLEEP: final extra sleep at end; DEBUG_NETSTAT put up a
- window showing what netstat reports; NO_DELETE: do not delete tmp
- bat files on Windows (for debugging); BAT_SLEEP: sleep this many
- seconds at the end of each Windows bat file (for debugging.)
-
- You can also set any environment variable by entering in something
- like ENV=VAR=VAL e.g. ENV=SSH_AUTH_SOCK=/tmp/ssh-BF2297/agent.2297
- Use an empty VAL to unset the variable.
-
- There are also a HUGE number of env. vars. that apply to the Unix
- and MacOS X wrapper script 'ss_vncviewer' and/or the ssvncviewer
- binary. See Options -> Advanced -> Unix ssvncviewer -> Help for
- all of them.
-
- 16) On Unix you can make the "Open File" and "Save File" dialogs
- bigger by setting the env. var. SSVNC_BIGGER_DIALOG=1 or
- supplying the -bigger option. If you set it to a Width x Height,
- e.g. SSVNC_BIGGER_DIALOG=500x200, that size will be used.
-
- 17) On Unix / MacOSX to enable debug output you can set these env.
- vars to 1: SSVNC_STUNNEL_DEBUG, SSVNC_VENCRYPT_DEBUG, and
- SS_DEBUG (very verbose)
-
- 18) Dynamic VNC Server Port determination and redirection: If you
- are running SSVNC on Unix and are using SSH to start the remote
- VNC server and the VNC server prints out the line "PORT=NNNN"
- to indicate which dynamic port it is using (x11vnc does this),
- then if you prefix the SSH command with "PORT=" SSVNC will watch
- for the PORT=NNNN line and uses ssh's built in SOCKS proxy
- (ssh -D ...) to connect to the dynamic VNC server port through
- the SSH tunnel. For example:
-
- VNC Host:Display user@somehost.com
- Remote SSH Command: PORT= x11vnc -find -nopw
-
- or "PORT= x11vnc -display :0 -localhost", etc. Or use "P= ..."
-
- There is also code to detect the display of the regular Unix
- vncserver(1). It extracts the display (and hence port) from
- the lines "New 'X' desktop is hostname:4" and also
- "VNC server is already running as :4". So you can use
- something like:
-
- PORT= vncserver; sleep 15
- or: PORT= vncserver :4; sleep 15
-
- the latter is preferred because when you reconnect with it will
- find the already running one. The former one will keep creating
- new X sessions if called repeatedly.
-
- On Windows if PORT= is supplied SOCKS proxying is not used, but
- rather a high, random value of the VNC port is chosen (e.g. 8453)
- and assumed to be free, and is passed to x11vnc's -rfbport option.
- This only works with x11vnc (not vncserver).
-
- 19) On Unix if you are going to an older SSH server (e.g. Solaris 10),
- you will probably need to set the env. var. SS_VNCVIEWER_NO_T=1
- to disable the ssh "-t" option being used (that can prevent the
- command from being run).
-
- 20) SSVNC is basically a wrapper for the stunnel and ssh programs,
- and because those two programs have good IPv6 support SSVNC will
- for most usage modes support it as well. IPv6 is 128 bit internet
- addresses (as opposed to IPv4 with its 32 bit xxx.yyy.zzz.nnn IPs.
-
- So for basic SSL and SSH connections if you type in an IPv6 IP
- address, e.g. '2001:4860:b009::68', or a hostname with only an
- IPv6 lookup, e.g. ipv6.l.google.com, the connection will work
- because stunnel and ssh handle these properly.
-
- Note that you often need to supply a display number or port after
- the address so put it, e.g. ':0' at the end: 2001:4860:b009::68:0
- You can also use the standard notation [2001:4860:b009::68]:0
- that is more clear. You MUST specify the display if you use
- the IPv6 address notation (but :0 is still the default for a
- non-numeric hostname string.)
-
- IPv4 addresses encoded in IPv6 notation also work, e.g.
- ::ffff:192.168.1.100 should work for the most part.
-
- SSVNC on Unix and MacOSX also has its own Proxy helper tool
- (pproxy) This script has been modified to handle IPv6 hostnames
- and addresses as long as the IO::Socket::INET6 Perl module
- is available. On Windows the relay6.exe tool is used.
-
- So for the most part IPv6 should work without you having to do
- anything special. However, for rare usage, the proxy helper tool
- can also treat and IPv6 address as a special sort of 'proxy'.
- So in the entry Proxy/Gateway you can include ipv6://host:port
- and the IPv6 host will simply be connected to and the data
- transferred. In this usage mode, set the VNC Host:Display
- to anything, e.g. 'localhost:0'; it is ignored if the ipv6://
- endpoint is specified as a proxy. Need for ipv6:// usage proxy
- should be rare.
-
- Note that for link local (not global) IPv6 addresses you may
- need to include the network interface at the end of the address,
- e.g. fe80::a00:20ff:fefd:53d4%eth0
-
- Note that one can use a 3rd party VNC Viewer with SSVNC (see
- Options -> Advanced -> Change VNC Viewer.) IPv6 will work for
- them as well even if they do not support IPv6.
-
- IPv6 support on Unix, MacOSX, and Windows is essentially complete
- for all types of connections (including proxied, unencrypted and
- reverse connections.) Let us know if you find a scenario that
- does not work (see the known exception for putty/plink below.)
-
- You can set ipv6=0 in your ssvncrc, then no special relaying for
- IPv6 will be done (do this if there are problems or slowness in
- trying to relay ipv6 and you know you will not connect to any
- such hosts.) Set ipv6=1 to force the special processing even if
- IPv6 was not autodetected. To change this dynamically, you also
- enter IPV6=... in the VNC Host:Display entry box and press Enter.
- Also on Unix or MacOSX you can set the env. var. SSVNC_IPV6=0
- to disable the wrapper script from checking if hosts have ipv6
- addresses (this is the same as setting ipv6=0 in ssvncrc or by
- the setting ipv6 in the Entry box.)
-
- On Windows plink.exe (SSH client) currently doesn't work for
- IPv6 address strings (e.g. 2001:4860:b009::68) but it does work
- for hostname strings that resolve to IPv6 addresses.
-
- Note that one can make a home-brew SOCKS5 ipv4-to-ipv6 gateway
- proxy using ssh like this:
-
- ssh -D '*:1080' localhost "printf 'Press Enter to Exit: '; read x"
-
- then specify a proxy like socks5://hostname:1080 where hostname
- is the machine running the above ssh command. Add '-v' to the
- ssh cmdline for verbose output. See also the x11vnc inet6to4 tool
- (a direct ipv4/6 relay, not socks.)
-}
-
- global version
- set help_main " SSVNC version: $version\n$help_main"
- set help_misc " SSVNC version: $version\n$help_misc"
- set help_prox " SSVNC version: $version\n$help_prox"
- set help_tips " SSVNC version: $version\n$help_tips"
-
- frame .h.w
- button .h.w.b1 -text "Main" -command {help_text main}
- button .h.w.b2 -text "Proxies" -command {help_text prox}
- button .h.w.b3 -text "Misc" -command {help_text misc}
- button .h.w.b4 -text "Tips" -command {help_text tips}
-
- pack .h.w.b1 .h.w.b2 .h.w.b3 .h.w.b4 -side left -fill x -expand 1
-
- pack .h.w -side bottom -after .h.d -fill x
-
- .h.f.t insert end $help_main
- jiggle_text .h.f.t
-}
-
-proc help_text {which} {
- global help_main help_misc help_prox help_tips
- set txt ""
- if {$which == "main"} {
- set txt $help_main
- }
- if {$which == "misc"} {
- set txt $help_misc
- }
- if {$which == "prox"} {
- set txt $help_prox
- }
- if {$which == "tips"} {
- set txt $help_tips
- }
- catch {.h.f.t delete 0.0 end; .h.f.t insert end $txt; jiggle_text .h.f.t}
-}
-
-proc ssvnc_escape_help {} {
- toplev .ekh
-
- scroll_text_dismiss .ekh.f
-
- center_win .ekh
- wm title .ekh "SSVNC Escape Keys Help"
-
- set msg {
- SSVNC Escape Keys:
-
- The Unix SSVNC VNC Viewer, ssvncviewer(1), has an 'Escape Keys'
- mechanism that enables using keystrokes that are bound as 'Hot Keys'
- to specific actions.
-
- So, when you have all of the modifier keys ('escape keys') pressed down,
- then subsequent keystrokes are interpreted as local special actions
- instead of being sent to the remote VNC server.
-
- This enables quick parameter changing and also panning of the viewport.
- E.g. the keystroke 'r' is mapped to refresh the screen.
-
- Enter 'default' in the entry box to enable this feature and to use the
- default modifier list (Alt_L,Super_L on unix and Control_L,Meta_L on
- macosx) or set it to a list of modifier keys, e.g. Alt_L,Control_L.
- Note that _L means left side of keyboard and _R means right side.
-
- Alt_L is the 'Alt' key on the left side of the keyboard, and Super_L
- is usually the 'WindowsFlaggie(TM)' on the left side of the keyboard,
- so when both of those are pressed, the escape keys mapping take effect.
-
-
- Here is info from the ssvncviewer(1) manual page:
-
- -escape str This sets the 'Escape Keys' modifier sequence and enables
- escape keys mode. When the modifier keys escape sequence
- is held down, the next keystroke is interpreted locally
- to perform a special action instead of being sent to the
- remote VNC server.
-
- Use '-escape default' for the default modifier sequence.
- (Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L)
-
- Here are the 'Escape Keys: Help+Set' instructions from the Popup Menu:
-
- Escape Keys: Enter a comma separated list of modifier keys to be the
- 'escape sequence'. When these keys are held down, the next keystroke is
- interpreted locally to invoke a special action instead of being sent to
- the remote VNC server. In other words, a set of 'Hot Keys'.
-
- To enable or disable this, click on 'Escape Keys: Toggle' in the Popup.
-
- Here is the list of hot-key mappings to special actions:
-
- r: refresh desktop b: toggle bell c: toggle full-color
- f: file transfer x: x11cursor z: toggle Tight/ZRLE
- l: full screen g: graball e: escape keys dialog
- s: scale dialog +: scale up (=) -: scale down (_)
- t: text chat a: alphablend cursor
- V: toggle viewonly Q: quit viewer 1 2 3 4 5 6: UltraVNC scale 1/n
-
- Arrow keys: pan the viewport about 10% for each keypress.
- PageUp / PageDown: pan the viewport by a screenful vertically.
- Home / End: pan the viewport by a screenful horizontally.
- KeyPad Arrow keys: pan the viewport by 1 pixel for each keypress.
- Dragging the Mouse with Button1 pressed also pans the viewport.
- Clicking Mouse Button3 brings up the Popup Menu.
-
- The above mappings are *always* active in ViewOnly mode, unless you set the
- Escape Keys value to 'never'.
-
- If the Escape Keys value below is set to 'default' then a default list of
- of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it
- is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag
- on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side
- of the keyboard.
-
- On Unix the default is Alt and Windows keys on Left side of keyboard.
- On MacOSX the default is Control and Command keys on Left side of keyboard.
-
- Example: Press and hold the Alt and Windows keys on the LEFT side of the
- keyboard and then press 'c' to toggle the full-color state. Or press 't'
- to toggle the ultravnc Text Chat window, etc.
-
- To use something besides the default, supply a comma separated list (or a
- single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L
- Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.
-}
-
- .ekh.f.t insert end $msg
- jiggle_text .ekh.f.t
-}
-
-# Or Alternatively one can supply both hosts separated by
-# spaces (with the proxy second) in the VNC Host:Display box:
-#
-# VNC Host-Display: far-away.east:0 theproxy.net:8080
-#
-# This looks a little strange, but it actually how SSVNC stores the
-# host info internally.
-
-# You can also specify the remote SSH command by putting a string like
-#
-# cmd=x11vnc -nopw -display :0 -rfbport 5900 -localhost
-#
-# (use any command you wish to run) at the END of the VNC Host:Display
-# entry. In general, you can cram it all in the VNC Host:Display if
-# you like: host:disp proxy:port cmd=... (this is the way it is
-# stored internally).
-
-proc help_certs {} {
- toplev .ch
-
- set h 33
- if [small_height] {
- set h 28
- }
- scroll_text_dismiss .ch.f 87 $h
-
- center_win .ch
- wm resizable .ch 1 0
-
- wm title .ch "SSL Certificates Help"
-
- set msg {
- Description:
-
- *** IMPORTANT ***: Only with SSL Certificate verification (either manually
- or via a Certificate Authority certificate) can Man-In-The-Middle attacks be
- prevented. Otherwise, only passive network sniffing attacks are prevented.
- There are hacker tools like dsniff/webmitm and cain that implement SSL
- Man-In-The-Middle attacks. They rely on the client user not bothering to
- check the cert.
-
- Some people may be confused by the above because they are familiar with
- their Web Browser using SSL (i.e. https://... websites) and those sites
- are authenticated securely without the user's need to verify anything
- manually. The reason why this happens automatically is because 1) their
- web browser comes with a bundle of Certificate Authority certificates
- and 2) the https sites have paid money to the Certificate Authorities to
- have their website certificate signed by them. When using SSL in VNC we
- normally do not do something this sophisticated, and so we have to verify
- the certificates manually. However, it is possible to use Certificate
- Authorities with SSVNC; that method is described below.
-
- The SSL Certificate files described below may have been created externally
- (e.g. by x11vnc or openssl): you can import them via "Import Certificate".
- OR you can click on "Create Certificate ..." to use THIS program to generate
- a Certificate + Private Key pair for you (in this case you will need to
- distribute one of the generated files to the VNC Server).
-
- Then you associate the Saved cert with the VNC server, see the panel entry
- box description below. Then click Connect. You will usually want to Save
- this association in a VNC Server profile for the next time you connect.
-
- Expiration:
-
- SSL Certificates will Expire after a certain period (usually 1-2 years;
- if you create a cert with this tool you can set it to any length you want).
- So if for a particular Cert you find you can no longer connect, check the
- STUNNEL log output to see if the cert has expired. Then create and distribute
- a new one.
-
- Fetch Cert:
-
- You can also retrieve and view the VNC Server's Cert via the "Fetch Cert"
- button on the main panel. After you check that it is the correct Cert (e.g. by
- comparing MD5 hash or other info), you can save it. The file it was saved
- as will be set as the "ServerCert" to verify against for the next connection.
- To make this verification check permanent, you will need to save the profile
- via 'Save'.
-
- NOTE: See the CA section below for how "Fetch Cert/Verify All Certs" WILL NOT
- WORK when a Certificate Authority (CA) is used (i.e. you need to save the CA's
- cert instead.) It will work if the certificate is Self-Signed.
-
- Verify All Certs:
-
- If "Verify All Certs" is checked on the main panel, you are always forced
- to check unrecognized server certs, and so the first time you connect to
- a new server you may need to follow a few dialogs to inspect and save the
- server certificate.
-
- Under "Verify All Certs", new certificates are saved in the 'Accepted Certs'
- directory. When the checkbox is set all host profiles with "CertsDir" set to
- "ACCEPTED_CERTS" (and an empty "ServerCert" setting) will be checked against
- the pool of accepted certificates in the 'Accepted Certs' directory.
-
- Note that we have "Verify All Certs" on by default so that users who do not
- understand the SSL Man-In-The-Middle problem will not be left completely
- vulnerable to it. Everyone still must make the effort to verify new
- certificates by an external method to be completely safe.
-
- To have "Verify All Certs" toggled off at startup, use "ssvnc -nv" or set
- SSVNC_NO_VERIFY_ALL=1 before starting. If you do not even want to see the
- button, use "ssvnc -nvb" or SSVNC_NO_VERIFY_ALL_BUTTON=1.
-
- Note: "Fetch Cert" and "Verify All Certs" are currently not implemented in
- "SSH + SSL" mode. In this case to have server authentication "ServerCert"
- must be set explicitly to a file (or "CertsDir" to a directory).
-
- Also note that "Fetch Cert" only works in a limited fashion in "Listen"
- mode (it is the VNC Server that initiates the connection), and so you
- may need to be set via "ServerCert" as well.
-
- NOTE: See the CA section below for how "Fetch Cert/Verify All Certs"
- WILL NOT WORK when a Certificate Authority (CA) is used (i.e. you need
- to save the CA's cert instead.) The "Fetch Cert" saving method will
- work if the certificate is Self-Signed.
-
- CA:
-
- One can make SSL VNC server authentication more "automatic" as it is in
- Web Browsers going to HTTPS sites, by using a Certificate Authority (CA)
- cert (e.g. a professional one like Verisign or Thawte, or one your company
- or organization creates) for the "ServerCert". This is described in detail
- here: http://www.karlrunge.com/x11vnc/ssl.html
-
- CA's are not often used, but if the number of VNC Servers scales up it can
- be very convenient because the viewers (i.e. SSVNC) only need the CA cert,
- not all of the Server certs.
-
- IMPORTANT NOTE: if a VNC Server is using a CA signed certificate instead
- of its own Self-Signed one, then "Fetch Cert", etc. saving mechanism
- WILL NOT WORK. You must obtain the CA certificate and explicitly set
- it as the ServerCert or import it to 'Accepted Certs'.
-
-
- Now what goes into the panel's entry boxes is described.
-
-
- Your Certificate + Key (MyCert):
-
- You can specify YOUR own SSL certificate (PEM) file in "MyCert" in which
- case it is used to authenticate YOU (the viewer) to the remote VNC Server.
- If this fails the remote VNC Server will drop the connection.
-
- So the Server could use this method to authenticate Viewers instead of the
- more common practice of using a VNC password or x11vnc's -unixpw mode.
-
-
- Server Certificates (ServerCert/CertsDir):
-
- Server certs can be specified in one of two ways:
-
- - A single certificate (PEM) file for a single server
- or a single Certificate Authority (CA)
-
- - A directory of certificate (PEM) files stored in
- the special OpenSSL hash fashion.
-
- The former is set via "ServerCert" in this gui.
- The latter is set via "CertsDir" in this gui.
-
- The former corresponds to the "CAfile" STUNNEL parameter.
- The latter corresponds to the "CApath" STUNNEL parameter.
-
- See stunnel(8) or stunnel.mirt.net for more information.
-
- If the remote VNC Server fails to authenticate itself with respect to the
- specified certificate(s), then the VNC Viewer (your side) will drop the
- connection.
-
- Select which file or directory by clicking on the appropriate "Browse..."
- button. Once selected, if you click Info or the Right Mouse button on
- "Browse..." then information about the certificate will be displayed.
-
- If, as is the default, "CertsDir" is set to the token "ACCEPTED_CERTS"
- (and "ServerCert" is unset) then the certificates accumulated in the special
- 'Accepted Certs' directory will be used. "ACCEPTED_CERTS" is the default for
- every server ("Verify All Certs"). Note that if you ever need to clean this
- directory, each cert is saved in two files, for example:
-
- hostname-0=bf-d0-d6-9c-68-5a-fe-24-c6-60-ba-b4-14-e6-66-14.crt
- and
- 9eb7c8be.0
-
- This is because of the way OpenSSL must use hash-based filenames in Cert dirs.
- The file will have a "full filename:" line indicating the fingerprint and
- hostname associated with it. Be sure to remove both files. The Delete Certs
- dialog should automatically find the matching one for you and prompt you to
- remove it as well.
-
- Certificate Revocation List (CRL File):
-
- For large scale deployments, usually involving a CA Cert, it is worthwhile
- to be able to revoke individual certs (so that a new CA cert does not need to
- be created and new keys distributed). Set CRL File to the path to the
- file containing the revoked certificates (or a directory containing
- OpenSSL style hash-based filenames.) See the x11vnc -sslCRL documentation
- for how to create CRL's. In short, the commands 'openssl ca -revoke ...'
- and 'openssl ca -gencrl ...' are the ones to look for; See the ca(1) manpage.
-
- Create Certificate:
-
- A simple dialog to create a Self-Signed Certificate. See the x11vnc
- -sslGenCA, -sslGenCert options for creating a CA Cert and signing with it.
-
- Import Certificate:
-
- You can paste in a Certificate or read one in from a file to add to your
- list of Server Certificates. If (also) saved in the 'Accepted Certs'
- directory, it will be automatically used to verify any Server when in
- 'Verify All Certs' Mode.
-
- Deleting Certificates:
-
- To delete a Certificate+private_key pair click on "Delete Certificate"
- and select one in the menu. You will be prompted to remove it,
- and also any corresponding .pem or .crt file. For "ACCEPTED_CERTS"
- it will find the matching "HASH" file and prompt you to remove that too.
-
-
- Default Certs and Keys:
-
- Use the "-mycert file" option (same as "-cert file") to set a default
- MyCert. The user will then have to manually clear the field to not
- use a certificate. This is the same as "mycert=file" (also "cert=file")
- in the ~/.ssvncrc file. If "file" does not exist, then ~/.vnc/certs is
- prepended to it.
-
- Use the "-cacert file" option (same as "-ca file") to set a default
- ServerCert. The user will then have to manually clear the field to not
- set a server cert. This is the same as "cacert=file" (also "ca=file")
- in the ~/.ssvncrc file. If "file" does not exist, then ~/.vnc/certs is
- prepended to it. Use "-cacert CA" to set it to ~/.vnc/certs/CA/cacert.pem
-
- Use the "-crl file" option to set a default CRL File. The user will
- then have to manually clear the field to not use a CRL. This is the
- same as "crl=file" in the ~/.ssvncrc file. If "file" does not exist,
- then ~/.vnc/certs is prepended to it.
-
- A sys-admin might set up an SSVNC deployment for user's workstations or
- laptops using one or more of -cacert (authenticate VNC server to the
- user) or -mycert (authenticate user to VNC server) or -crl (supply a
- list of revoked certificates). Prefix either one with "FORCE:" to make
- the setting unchangable.
-
-
- Notes:
-
- If "Use SSH" has been selected then SSL certs are disabled.
-
- See the x11vnc and STUNNEL documentation for how to create and use PEM
- certificate files:
-
- http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext
- http://www.karlrunge.com/x11vnc/ssl.html
- http://stunnel.mirt.net
-
- A common way to create and use a VNC Server certificate is:
-
- x11vnc -ssl SAVE ...
-
- and then copy the Server certificate to the local (viewer-side) machine.
- x11vnc prints out to the screen the Server certificate it generates
- (stored in ~/.vnc/certs/server.crt). You can set "ServerCert" to it
- directly or use the "Import Certificate" action to save it to a file.
- Or use the "Fetch Cert" method to retrieve it (be sure to verify the
- MD5 fingerprint, etc).
-
- x11vnc also has command line utilities to create server, client, and CA
- (Certificate Authority) certificates and sign with it. See the above URLs.
-}
-
- .ch.f.t insert end $msg
- jiggle_text .ch.f.t
-}
-
-proc help_ts_opts {} {
- toplev .oh
-
- scroll_text_dismiss .oh.f
-
- center_win .oh
-
- wm title .oh "Terminal Services VNC Options Help"
-
-set msg {
- Options: Click on a checkbox to enable a feature and bring up its Dialog.
- Deselecting a checkbox will disable the feature (but settings from the
- Dialog are remembered). Click on it again to re-enable.
-
-
- Desktop Type:
-
- The default type of remote Desktop type is the "kde" (The K Desktop
- Environment) You can choose a different type: gnome, failsafe,
- twm, etc.
-
- This setting will ONLY be used if the desktop needs to be created.
- If an existing session of yours is found it will be used instead
- (log out of that session if you want to create a new Desktop type
- or see the Multiple Sessions option under Advanced).
-
- Desktop Size:
-
- The default size of remote Desktop type is the "1280x1024" with a
- Color depth of 16 bits per pixel (BPP). Choose one of the standard
- WxH values or enter a custom one (TBD).
-
- This setting will ONLY be used if the desktop needs to be created.
- If an existing session of yours is found it will be used instead
- (log out of that session if you want to create a new Desktop size
- or see the Multiple Sessions option under Advanced).
-
- Some X servers, Xdummy or a real X server, will allow dynamic screen
- size changing after the session has started via a GUI configuration
- tool (or xrandr(1) from the command line).
-
- X Server Type:
-
- The default type of remote X session is the "Xvfb" (X virtual frame
- buffer) X server. It is available on most systems. To choose a
- different type, select "Xdummy", "Xvnc", "Xvnc.redirect".
-
- Xdummy is part of the x11vnc project and is a virtual X server with
- some nice features, but it Linux only and requires root permission
- to run. One user put 'ALL ALL = NOPASSWD: /usr/local/bin/Xdummy*'
- in his sudo(1) configuration (via visudo).
-
- For Xvnc that server is started up, and x11vnc polls it in its
- normal way. Use Xvnc.redirect if you want x11vnc to find and/or
- create the Xvnc session, but after that merely transfer packets back
- and forth between VNC viewer and Xvnc (I.e. x11vnc does no polling
- or VNC protocol).
-
-
- Enable Printing:
-
- This sets up a SSH port redirection for you from your remote session
- to your local print server. The CUPS mechanism is used. The local
- print server can also be SMB/Windows.
-
- Enable Sound:
-
- Not completely implemented yet. A partially working ESD method
- is provided. It may change over to http://nas.sourceforge.net in
- the future. As with printing, it uses a SSH port redirection to a
- server running locally.
-
- File Transfer:
-
- x11vnc supports both the UltraVNC and TightVNC file transfer
- extensions. On Windows both viewers support their file transfer
- protocol. On Unix only the SSVNC VNC Viewer has filexfer support;
- it supports the UltraVNC flavor via a Java helper program.
-
- Choose the one you want based on VNC viewer you will use.
- The defaults for the SSVNC viewer package are TightVNC on Windows
- and UltraVNC on Unix.
-
- View Only:
-
- Start the VNC Viewer in View-Only mode (it may be switched to full
- access later in the session).
-
- Change VNC Viewer:
-
- If you do not like the VNC Viewer bundled in the package, you can
- indicate another one here.
-
- X11 viewer MacOSX:
-
- On MacOSX try to use the bundled X11 vncviewer instead of the
- Chicken of the VNC viewer; the Xquartz X server must be installed
- (it is by default on 10.5.x) and the DISPLAY variable must be set
- (see Tip 15 of SSVNC Help to do this manually.)
-
-
- Advanced Options:
-
- VNC Shared:
-
- Normal use of this program, 'tsvnc', *ALREADY* allows simultaneous
- shared access of the remote desktop: You simply log in as many
- times from as many different locations with 'tsvnc' as you like.
-
- Select this option for the traditional VNC server shared mode of
- operation using a single x11vnc server. SSH access is still required.
-
- Multiple Sessions:
-
- To enable one user to have more than one Terminal Services Desktop
- X session on a single machine, this option lets you create Tags for
- multiple ones (e.g. KDE_BIG, TWM_800x600)
-
- X Login Greeter:
-
- If you have root (sudo(1)) permission on the remote machine,
- you can have x11vnc try to connect to X displays that have nobody
- logged in yet. This is most likely the login greeter running on
- the Physical console. sudo(1) is used to run x11vnc with FD_XDM=1.
-
- An initial ssh running 'sudo id' is performed to try to 'prime'
- sudo so the 2nd one that starts x11vnc does not need a password.
-
- Note that if someone is already logged into the console of the XDM
- display you will see their X session.
-
- Other VNC Server:
-
- The x11vnc program running on the remote machine can be instructed to
- immediately redirect to some other (3rd party, e.g. Xvnc or vnc.so)
- VNC server.
-
- Use unixpw:
-
- This enables the x11vnc unixpw mode. A Login: and Password: dialog
- will be presented in the VNC Viewer for the user to provide any Unix
- username and password whose session he wants to connect to.
-
- This mode is useful if a shared terminal services user (e.g. 'tsuser')
- is used for the SSH login part (say via the SSH authorized_keys
- mechanism and all users share the same private SSH key for 'tsuser').
-
- In normal usage the per-user SSH login should be the simplest and
- sufficient, in which case the unixpw option should NOT be selected.
-
- Client 8bit Color:
-
- Have the VNC Viewer request low color mode (8 bits per pixel) for
- slow links. This may be disabled or further tuned (e.g. 64 color
- mode) in the viewer during the session.
-
- Client-Side Caching:
-
- x11vnc has an experiment Client-Side caching scheme "-ncache n"
- that can give nice speedups. But there are some drawbacks
- because the cache-region is visible and uses much RAM.
- http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching
-
- X11VNC Options:
-
- If you are familiar with x11vnc, you can specify any of its features
- that you would like enabled.
-
- SSVNC Mode:
-
- Clicking on this button will return you to the full SSVNC Mode.
-
- Unix ssvncviewer:
-
- Clicking on this button will popup a menu for setting options
- of the Unix (and Mac OS X) provided SSVNC vncviewer.
-
-
- ~/.ssvncrc file:
-
- You can put global options in your ~/.ssvncrc file (ssvnc_rc on
- Windows). Currently they are:
-
- Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have
- the application start up in the given mode.
-
- desktop_type=wmaker (e.g.) to switch the default Desktop Type.
-
- desktop_size=1280x1024 (e.g.) to switch the default Desktop Size.
-
- desktop_depth=24 (e.g.) to switch the default Desktop Color Depth.
-
- xserver_type=Xdummy (e.g.) to switch the default X Server Type.
-
- (The above 4 settings apply only to the Terminal Services Mode.)
-
- noenc=1 (same as the -noenc option for a 'No Encryption' option)
- noenc=0 (do not show the 'No Encryption' option)
-
- font_default=tk-font-name (sets the font for menus and buttons)
- font_fixed=tk-font-name (sets the font for help text)
-}
- .oh.f.t insert end $msg
- jiggle_text .oh.f.t
-}
-
-proc help_opts {} {
- toplev .oh
-
- scroll_text_dismiss .oh.f
-
- center_win .oh
-
- wm title .oh "SSL/SSH Viewer Options Help"
-
-set msg {
- Use SSL: The default, use SSL via STUNNEL (this requires SSL aware VNC
- server, e.g. x11vnc -ssl SAVE ...) See the description in the
- main Help panel.
-
- Use SSH: Instead of using STUNNEL SSL, use ssh(1) for the encrypted
- tunnel. You must be able to log in via ssh to the remote host.
-
- On Unix the cmdline ssh(1) program (it must already be installed)
- will be run in an xterm for passphrase authentication, prompts
- about RSA keys, etc. On Windows the cmdline plink.exe program
- will be launched in a Windows Console window. (Apologies for
- the klunkiness..)
-
- You can set the "VNC Host:Display" to "user@host:disp" to
- indicate ssh should log in as "user" on "host". NOTE: On
- Windows you *MUST* always supply the "user@" part (due to a
- plink deficiency). E.g.:
-
- VNC Host:Display: fred@far-away.east:0
-
-
- Gateway: If an intermediate gateway machine must be used
- (e.g. to enter a firewall; the VNC Server is not running on it),
- put it in the Proxy/Gateway entry, e.g.:
-
- VNC Host:Display: workstation:0
- Proxy/Gateway: user@gateway-host:port
-
- ssh is used to login to user@gateway-host and then a -L port
- redirection is set up to go to workstation:0 from gateway-host.
- ":port" is optional, use it if the gateway-host SSH port is
- not the default value 22.
-
- Chaining 2 ssh's: One can also do a "double ssh", i.e. a
- first SSH to the gateway login machine then a 2nd ssh to the
- destination machine (presumably it is running the vnc server).
-
- Unlike the above example, the "last leg" (gateway-host ->
- workstation) is also encrypted by SSH this way. Do this by
- splitting the gateway in two with a comma, the part before it
- is the first SSH:
-
- VNC Host:Display: localhost:0
- Proxy/Gateway: user@gateway-host:port,user@workstation:port
-
- Web and SOCKS proxies can also be used with SSH:
-
- VNC Host:Display: user@workstation:0
- Proxy/Gateway: socks://socks.server:1080
-
- See the "SSH Proxies/Gateways" in the Main Help document for full
- details.
-
-
- Remote Command: In the "Remote SSH Command" entry you can to
- indicate that a remote command to be run. The default is
- "sleep 15" to make sure port redirections get established. But you
- can run anything else, for example, to run x11vnc on your X :0
- workstation display:
-
- x11vnc -display :0 -nopw
-
-
- Windows SSH SERVER: if you are ssh'ing INTO Windows (e.g. CYGWIN
- SSHD server) there may be no "sleep" command so put in something
- like "ping localhost" or "ping -n 10 -w 1000 localhost" to
- set a short delay to let the port redir get established.
-
-
- Trick: If you use "SHELL" asl the "Remote SSH Command" then
- you get an SSH shell only: no VNC viewer will be launched.
- On Windows "PUTTY" will try to use putty.exe (better terminal
- emulation than plink.exe) A shortcut for this is Ctrl-S as
- long as user@hostname is present in the "VNC Host:Display" box.
-
-
- Use SSH + SSL:
-
- Tunnel the SSL connection through a SSH tunnel. Use this
- if you want end-to-end SSL and must use a SSH gateway (e.g. to
- enter a firewall) or if additional SSH port redirs are required
- (CUPS, Sound, SMB tunnelling: See Advanced Options).
-
- This is a RARELY used mode, but included in case the need arises.
-
-
- No Encryption:
-
- In '-noenc' mode, which is now the default, (Ctrl-E also toggles
- this mode), use this to make a Direct connection to the VNC Server
- with no encryption whatsoever. (Be careful about passwords, etc.)
-
- The -noenc mode is now the default since SSVNC 1.0.25, use
- the '-enc' cmdline option to disable the button.
-
-
- Automatically Find X Session:
-
- When using SSH mode to connect, you can select this option. It
- simply sets the Remote SSH Command to:
-
- PORT= x11vnc -find -localhost
-
- This requires that x11vnc is installed on the remote computer
- and is available in $PATH for the ssh login. The command
- "x11vnc -find -localhost" command is run on the remote
- machine.
-
- The -find option causes x11vnc to try to find an existing X
- session owned by the user (i.e. who you ssh in as). If it
- does it attaches to it; otherwise the x11vnc VNC server exits
- immediately followed by your VNC Viewer.
-
- The PORT= option just means to let x11vnc pick its own
- VNC port and then connect to whatever it picked. Use P=
- for more debugging output.
-
- The idea for this mode is you simply type 'username@workstation'
- in the VNC Host:Display box, Select 'Options -> Automatically
- Find X Session', and then click Connect. The tsvnc mode is
- similar (it runs x11vnc on the remote side with the intent
- of automatically finding, or creating, your desktop).
-
-
- Unix Username & Password:
-
- This is only available on Unix and MacOSX and when using
- the SSVNC enhanced TightVNC viewer (it has been modified to
- do Unix logins). It supports a login dialog with servers
- doing something like x11vnc's "-unixpw" mode. After any
- regular VNC authentication takes place (VNC Password), then
- it sends the Unix Username, a Return, the Unix Password and
- a final Return. This saves you from typing them into the
- "login:" and "Password:" prompts in the viewer window.
-
- Note that the x11vnc -unixpw login mode is external to the
- VNC protocol, so you need to be sure the VNC server is in
- this mode and will be waiting for the dialog. Otherwise the
- username and password will be typed directly into the desktop
- application that happens to have the focus!
-
- When you select this option "Unix Username:" and "Unix
- Password:" entry boxes appear on the main panel where you can
- type them in. x11vnc has settings that can be specified after
- a ":" in the Unix username; they may be used here as well.
- (For example: username:3/4,nc for a smaller screen and -nocache)
-
- If the Unix Username is not set when you click Connect, then
- any SSH username@host is used. Otherwise the environment
- variable $USER or $LOGNAME and finally whoami(1) is used.
-
- Also Note that the Unix Password is never saved in a VNC
- profile (so you have to type it each time). Also, the remote
- x11vnc server is instructed to not echo the Username string
- by sending an initial Escape. Set the SSVNC_UNIXPW_NOESC=1
- environment variable to override this.
-
- Reverse VNC Connection:
-
- Reverse (listening) VNC connections are possible as well.
- Enable with this button "Reverse VNC Connection (-LISTEN)"
-
- In this case the VNC Server initiates the connection to your
- waiting (i.e. listening) SSVNC viewer.
-
- For SSL connections in the 'VNC Host:Display' entry box put in
- the number (e.g. "0" or ":0" or ":1", etc.) that corresponds to
- the Listening display (0 -> port 5500, 1 -> port 5501, etc.) you
- want to use. For example x11vnc can then be used via:
- "x11vnc ... -ssl SAVE -connect hostname:port" using the "port"
- with the one you chose.
-
- Clicking on the 'Listen' button puts your SSVNC viewer
- in a "listening" state on that port number, waiting for a
- connection from the VNC Server.
-
- Then a VNC server should establish a reverse connection to
- that port on this machine (e.g. -connect this-machine:5500
- or -connect this-machine:5503, etc.)
-
- Server SSL certificates will be verified, however you WILL
- NOT be prompted about unrecognized ones; rather, you MUST
- set up the correct Server certificate (e.g. by importing).
- prior to any connections.
-
- If the connection is failing in Reverse VNC (listening) mode,
- check the STUNNEL log output to see if STUNNEL is unable to
- authenticate the VNC Server. If you want to allow in a
- reverse connection with NO Server authentication, unset the
- 'Verify All Certs' option.
-
- When listening in SSL, you will ALSO need to specify YOUR
- OWN SSL cert, "MyCert", or otherwise let the GUI prompt you
- to create a "listen.pem" and use that.
-
- The "listen.pem" will be reused in later SSL Listening
- connections unless you specify a different one with MyCert.
-
- On Windows or using a 3rd party VNC Viewer multiple,
- simultaneous reverse connections are always enabled.
- On Unix/MacOSX with the provided ssvncviewer they are disabled
- by default. To enable them:
- Options -> Advanced -> Unix ssvncviewer -> Multiple LISTEN Conns.
-
- For reverse connections in SSH or SSH + SSL modes it is a
- little trickier. The SSH tunnel (with -R tunnel) must be
- established and remain up waiting for reverse connections.
- The default time is "sleep 1800", i.e. 30 mins. You can put
- a longer or shorter sleep in "Remote SSH Command" (perhaps
- after your command runs: cmd; sleep 3600).
-
- For SSH reverse connections put "hostname:n" in
- 'VNC Host:Display' or "user@hostname:n". The "n" will be the
- listening display on the *REMOTE* side. So to have the remote
- x11vnc connect use: "x11vnc ... -connect localhost:n" or
- "x11vnc -R connect:localhost:n" (-ssl will be needed for SSH+SSL
- mode). If the -R port cannot be opened because it is in use
- by another program you will have to kill everything and start
- over using a different port.
-
- In reverse connections mode be careful to protect the listening
- VNC Viewer from direct connections (neither SSL nor SSH)
- connecting directly to its listening port thereby bypassing
- the tunnel. This can be done by a host-level firewall that
- only lets in, say, port 5500 (the default one ":0" for stunnel
- to listen on). Or for SSH reverse connections allow NO 5500+n
- ports in. For reverse connections, the Unix enhanced tightvnc
- viewers supplied in the SSVNC package will only listen on
- localhost so these precautions are not needed.
-
- Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel
- only listen on that interface. IPv6 works too, e.g. :::0 or ::1:0
- Also works for UN-encrypted reverse connections as well ('None').
-
- Note that for SSL connections use of "Proxy/Gateway" does not
- make sense: the remote side cannot initiate its reverse connection
- via the Proxy.
-
- Note that for SSH or SSH+SSL connections use of "Proxy/Gateway"
- does not make sense (the ssh cannot do a -R on a remote host:port),
- unless it is a double proxy where the 2nd host is the machine with
- the VNC server.
-
-
- View Only: Have VNC Viewer ignore mouse and keyboard input.
-
- Fullscreen: Start the VNC Viewer in fullscreen mode.
-
- Raise On Beep: Deiconify viewer when bell rings.
-
- Use 8bit color: Request a very low-color pixel format.
-
- Do not use JPEG: Do not use the jpeg aspect of the tight encoding.
-
- Use X11 vncviewer on MacOSX:
- On MacOSX try to use the bundled X11 vncviewer
- instead of the Chicken of the VNC viewer;
- The Xquartz X server must be installed (it is by
- default on 10.5.x) and the DISPLAY variable must
- be set (see Tip 15 of Help to do this manually.)
- Put cotvnc=1 in ~/.ssvncrc to switch the default.
-
- Kill Stunnel Automatically:
- On Windows, automatically try to kill the STUNNEL
- process when the VNC Viewer exits. This is a
- global setting (not per-profile); it can be also
- set via either the -killstunnel cmdline option,
- or killstunnel=1 in ssvnc_rc. To disable it supply
- -nokillstunnel or put killstunnel=0 in ssvnc_rc.
- As of 1/2009 this option is on by default.
-
- The main drawback to having STUNNEL automatically
- killed is that you will not be able to view its
- logfile. If you are having trouble connecting via
- SSL, disable this option and double click on the
- dark green STUNNEL icon in the tray to view the log.
-
-
- Compress Level/Quality: Set TightVNC encoding parameters.
-
-
- Putty PW: On Windows only: use the supplied password for plink SSH
- logins. Unlike the other options the value is not saved
- when 'Save' is performed. This feature is useful when
- options under "Advanced" are set that require TWO SSH's:
- you just have to type the password once in this entry box.
- The bundled pageant.exe and puttygen.exe programs can also
- be used to avoid repeatedly entering passwords (note this
- requires setting up and distributing SSH keys). Start up
- pageant.exe or puttygen.exe and read the instructions there.
-
- Note, that there is a small exposure to someone seeing the
- putty password on the plink command line.
-
- Note that the Putty PW is not cleared if you load in a
- new VNC profile.
-
-
- Port Slot: On Windows ports cannot be selected or checked as easily as
- on Unix. So listening ports for ssh redirs, proxy tunnelling,
- and etc. things are picked via finding a free "slot".
- The slots run from 30 to 99 and are locked based on the
- existence of a file with the slot number in it. When the
- connection is about to be made, a free slot is found and used
- to work out some ports (e.g. 5930 for the local VNC port,
- etc.) This way simultaneous SSVNC connections can take place.
-
- One drawback of this is that Putty/Plink stores SSH keys based
- on hostname:port, and with a proxy tunnel the hostname is
- "localhost". So the Putty key store may have key collisions
- for the localhost tunnels, and plink will prompt you to
- resolve the conflict WRT a different SSH key being discovered.
-
- To work around this to some degree you can select a unique
- Port Slot (in the range 50-99) for a specific host. Then the
- ssh redir port to this host will never change and so the
- Putty localhost:fixed-port key should remain valid.
-
-
- Mode: To change the GUI Mode, select between the full SSVNC
- (i.e. SSL and SSH), SSHVNC (i.e. SSH-Only), and Terminal
- Services mode (TSVNC; uses x11vnc)
-
- Note: You can put "mode=tsvnc" or "mode=sshvnc" in your
- ~/.ssvncrc file (ssvnc_rc on Windows) to have the application
- start up in the given mode.
-
-
- Show 'No Encryption' Option:
-
- Note: since SSVNC 1.0.25 the 'No Encryption' Option is
- enabled by default.
-
- Select this to display a button that disables both SSL and
- SSH encryption. This is the same as Ctrl+E. This puts
- a check item "None" on the main panel and also a "No
- Encryption" check item in the "Options" panel. If you
- select this item, there will be NO encryption for the VNC
- connection (use cautiously) See Tip 5) under Help for more
- information about disabling encryption.
-
-
- Buttons:
-
- Use Defaults: Set all options to their defaults (i.e. unset).
-
- Delete Profile: Delete a saved profile.
-
- Advanced: Bring up the Advanced Options dialog.
-
- Save and Load:
-
- You can Save the current settings by clicking on Save
- (.vnc file) and you can also read in a saved one with Load
- Profile. Use the Browse... button to select the filename
- via the GUI.
-
- Pressing Ctrl-L or Clicking the Right mouse button on the
- main GUI will invoke the Load dialog.
-
- Note: On Windows since the TightVNC Viewer will save its own
- settings in the Registry, some unexpected behavior is possible
- because the viewer is nearly always directed to the VNC host
- "localhost:30". E.g. if you specify "View Only" in this gui
- once but not next time the Windows VNC Viewer may remember
- the setting. Unfortunately there is not a /noreg option for
- the Viewer.
-}
- .oh.f.t insert end $msg
- jiggle_text .oh.f.t
-}
-
-proc help_fetch_cert {{selfsigned 1}} {
- toplev .fh
-
- set h 35
- if [small_height] {
- set h 28
- }
- scroll_text_dismiss .fh.f 85 $h
-
- center_win .fh
- wm resizable .fh 1 0
-
- wm title .fh "Fetch Certificates Help"
-
- set msg {
- The displayed SSL Certificate has been retrieved from the VNC Server via the
- "Fetch Cert" action.
-
- It has merely been downloaded via the SSL Protocol:
-
- *** IT HAS NOT BEEN VERIFIED OR AUTHENTICATED IN ANY WAY ***
-
- So, in principle, it could be a fake certificate being inserted by a bad
- person attempting to perform a Man-In-The-Middle attack on your SSL connection.
-
- If, however, by some external means you can verify the authenticity of this SSL
- Certificate you can use it for your VNC SSL connection to the VNC server you
- wish to connect to. It will provide an authenticated and encrypted connection.
-
- You can verify the SSL Certificate by comparing the MD5 or SHA1 hash value
- via a method/channel you know is safe (i.e. not also under control of a
- Man-In-The-Middle attacker). You could also check the text between the
- -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- tags, etc.
-
- Once you are sure it is correct, you can press the Save button to save the
- certificate to a file on the local machine for use when you connect via VNC
- tunneled through SSL. If you save it, then that file will be set as the
- Certificate to verify the VNC server against. You can see this in the dialog
- started via the "Certs..." button on the main panel.
-
- NOTE: If you want to make Permanent the association of the saved SSL certificate
- file with the VNC server host, you MUST save the setting as a profile for
- loading later. To Save a Profile, click on Options -> Save Profile ...,
- and choose a name for the profile and then click on Save.
-
- If "Verify All Certs" is checked, then you are forced to check all new certs.
- In this case the certs are saved in the 'Accepted Certs' directory against
- which all servers will be checked unless "ServerCert" or "CertsDir" has been
- set to something else.
-
- To reload the profile at a later time, click on the "Load" button on the
- main panel and then select the name and click "Open". If you want to be
- sure the certificate is still associated with the loaded in host, click on
- "Certs..." button and make sure the "ServerCert" points to the desired SSL
- filename.
-
- See the Certs... Help for more information. A sophisticated method can be set
- up using a Certificate Authority key to verify never before seen certificates
- (i.e. like your web browser does).
-}
-
- set msg2 {
- --------------------------------------------------------------------------
- NOTE: The certificate that was just downloaded IS NOT a Self-Signed
- certificate. It was signed by a Certificate Authority (CA) instead.
- So saving it does not make sense because it cannot be used to authenticate
- anything.
-
- You need to Obtain and Save the CA's certificate instead.
-
- The remainder of this Help description applies ONLY to Self-Signed
- certificates (i.e. NOT the most recently downloaded one.)
- --------------------------------------------------------------------------
-
-
-}
-
- if {!$selfsigned} {
- regsub { If, however,} $msg "$msg2 If, however," msg
- }
-
- .fh.f.t insert end $msg
- jiggle_text .fh.f.t
-}
-
-proc win_nokill_msg {} {
- global help_font is_windows system_button_face
- toplev .w
-
- eval text .w.t -width 60 -height 11 $help_font
- button .w.d -text "Dismiss" -command {destroy .w}
- pack .w.t .w.d -side top -fill x
-
- apply_bg .w.t
-
- center_win .w
- wm resizable .w 1 0
-
- wm title .w "SSL/SSH Viewer: Warning"
-
- set msg {
- The VNC Viewer has exited.
-
- You will need to terminate STUNNEL manually.
-
- To do this go to the System Tray and right-click on the STUNNEL
- icon (dark green). Then click "Exit".
-
- You can also double click on the STUNNEL icon to view the log
- for error messages and other information.
-}
- .w.t insert end $msg
-}
-
-proc win_kill_msg {pids} {
- global terminate_pids
- global help_font
-
- toplev .w
-
- eval text .w.t -width 72 -height 21 $help_font
- button .w.d -text "Dismiss" -command {destroy .w; set terminate_pids no}
- button .w.k -text "Terminate STUNNEL" -command {destroy .w; set terminate_pids yes}
- pack .w.t .w.k .w.d -side top -fill x
-
- apply_bg .w.t
-
- center_win .w
- wm resizable .w 1 0
-
- wm title .w "SSL/SSH Viewer: Warning"
-
- set msg {
- The VNC Viewer has exited.
-
- We can terminate the following still running STUNNEL process(es):
-
-}
- append msg " $pids\n"
-
- append msg {
- Click on the "Terminate STUNNEL" button below to do so.
-
- Before terminating STUNNEL you can double click on the STUNNEL
- Tray icon to view its log for error messages and other information.
-
- Note: You may STILL need to terminate STUNNEL manually if we are
- unable to kill it. To do this go to the System Tray and right-click
- on the STUNNEL icon (dark green). Then click "Exit". You will
- probably also need to hover the mouse over the STUNNEL Tray Icon to
- make the Tray notice STUNNEL is gone...
-
- To have STUNNEL automatically killed when the Viewer exits use the
- -killstunnel cmdline option, or set it under Options or in ssvnc_rc.
-}
- .w.t insert end $msg
-}
-
-proc win9x_plink_msg {file} {
- global help_font win9x_plink_msg_done
- toplev .pl
-
- eval text .pl.t -width 90 -height 26 $help_font
- button .pl.d -text "OK" -command {destroy .pl; set win9x_plink_msg_done 1}
- wm protocol .pl WM_DELETE_WINDOW {catch {destroy .pl}; set win9x_plink_msg_done 1}
- pack .pl.t .pl.d -side top -fill x
-
- apply_bg .pl.t
-
- center_win .pl
- wm resizable .pl 1 0
-
- wm title .pl "SSL/SSH Viewer: Win9x Warning"
-
- set msg {
- Due to limitations on Window 9x you will have to manually start up
- a COMMAND.COM terminal and paste in the following command:
-
-}
- set pwd [pwd]
- regsub -all {/} $pwd "\\" pwd
- append msg " $pwd\\$file\n"
-
- append msg {
- The reason for this is a poor Console application implementation that
- affects many text based applications.
-
- To start up a COMMAND.COM terminal, click on the Start -> Run, and then
- type COMMAND in the entry box and hit Return or click OK.
-
- To select the above command, highlight it with the mouse and then press
- Ctrl-C. Then go over to the COMMAND.COM window and click on the
- Clipboard paste button. Once pasted in, press Return to run the script.
-
- This will start up a PLINK.EXE ssh login to the remote computer,
- and after you log in successfully and indicate (QUICKLY!!) that the
- connection is OK by clicking OK in this dialog. If the SSH connection
- cannot be autodetected you will ALSO need to click "Success" in the
- "plink ssh status?" dialog, the VNC Viewer will be started going
- through the SSH tunnel.
-}
- .pl.t insert end $msg
- wm deiconify .pl
-}
-
-proc mesg {str} {
- set maxx 60
- if [regexp {^INFO: without Certificate} $str] {
- set maxx 72
- }
- if {[string length $str] > $maxx} {
- set lend [expr $maxx - 1]
- set str [string range $str 0 $lend]
- append str " ..."
- }
- .l configure -text $str
- update
- global env
- if [info exists env(SSVNC_MESG_DELAY)] {
- after $env(SSVNC_MESG_DELAY)
- }
-}
-
-proc get_ssh_hp {str} {
- regsub {cmd=.*$} $str "" str
- set str [string trim $str]
- regsub {[ ].*$} $str "" str
- return $str
-}
-
-proc get_ssh_cmd {str} {
- set str [string trim $str]
- global ts_only
- if {$ts_only} {
- return [ts_x11vnc_cmd]
- }
- if [regexp {cmd=(.*$)} $str m cmd] {
- set cmd [string trim $cmd]
- regsub -nocase {^%x11vncr$} $cmd "x11vnc -nopw -display none -rawfb rand" cmd
- regsub -nocase {^%x11vnc$} $cmd "x11vnc -nopw -display none -rawfb null" cmd
- return $cmd
- } else {
- return ""
- }
-}
-
-proc get_ssh_proxy {str} {
- set str [string trim $str]
- regsub {cmd=.*$} $str "" str
- set str [string trim $str]
- if { ![regexp {[ ]} $str]} {
- return ""
- }
- regsub {^.*[ ][ ]*} $str "" str
- return $str
-}
-
-proc ts_x11vnc_cmd {} {
- global is_windows
- global ts_xserver_type choose_xserver ts_desktop_type choose_desktop ts_unixpw ts_vncshared
- global ts_desktop_size ts_desktop_depth choose_desktop_geom
- global choose_filexfer ts_filexfer
- global ts_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport choose_x11vnc_opts
- global ts_othervnc choose_othervnc ts_xlogin
- global choose_sleep extra_sleep
-
- set cmd ""
- if {$choose_x11vnc_opts && $ts_x11vnc_path != ""} {
- set cmd $ts_x11vnc_path
- } else {
- set cmd "x11vnc"
- }
- if {! $is_windows} {
- set cmd "PORT= $cmd"
- } else {
- set cmd "PORT= $cmd"
- }
-
- set type $ts_xserver_type;
- if {! $choose_xserver} {
- set type ""
- }
- if {$choose_othervnc && $ts_othervnc == "find"} {
- set type "Xvnc.redirect"
- }
-
- if [info exists choose_sleep] {
- if {! $choose_sleep} {
- set extra_sleep ""
- }
- }
-
- if {$choose_othervnc && $ts_othervnc != "find"} {
- set cmd "$cmd -redirect $ts_othervnc"
- } elseif {$type == ""} {
- global ts_xserver_type_def
- if {$ts_xserver_type_def != ""} {
- set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-$ts_xserver_type_def";
- } else {
- set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb";
- }
- } elseif {$type == "Xvfb"} {
- set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb";
- } elseif {$type == "Xdummy"} {
- set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xdummy";
- } elseif {$type == "Xvnc"} {
- set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvnc";
- } elseif {$type == "Xvnc.redirect"} {
- set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvnc.redirect";
- }
-
- # TBD: Cups + sound
-
- set cmd "$cmd -localhost";
- set cmd "$cmd -nopw";
- global ts_ncache choose_ncache
- if {$choose_ncache && [regexp {^[0-9][0-9]*$} $ts_ncache]} {
- set cmd "$cmd -ncache $ts_ncache";
- } else {
- #set cmd "$cmd -nonc";
- }
- set cmd "$cmd -timeout 120";
- global ts_multisession choose_multisession
- regsub -all {[^A-z0-9_-]} $ts_multisession "" ts_multisession
- if {$choose_multisession && $ts_multisession != ""} {
- set cmd "$cmd -env FD_TAG='$ts_multisession'";
- }
- if {$choose_filexfer && $ts_filexfer != ""} {
- if {$ts_filexfer == "tight"} {
- set cmd "$cmd -tightfilexfer";
- } else {
- set cmd "$cmd -ultrafilexfer";
- }
- }
- if {$ts_unixpw} {
- set cmd "$cmd -unixpw";
- }
- if {$ts_vncshared} {
- set cmd "$cmd -shared";
- }
- set u "unknown"
- global env
- if {[info exists env(USER)]} {
- regsub -all {[^A-z]} $env(USER) "_" u
- }
- set cmd "$cmd -o \$HOME/.tsvnc.log.$u"; # XXX perms
-
- set sess "kde"
- global ts_desktop_type_def
- if {$ts_desktop_type_def != ""} {
- set sess $ts_desktop_type_def
- }
- if {$choose_desktop && $ts_desktop_type != ""} {
- set sess $ts_desktop_type
- }
- set cmd "$cmd -env FD_SESS=$sess";
-
- if {$choose_desktop_geom} {
- set geom "1280x1024"
- set dep 16
- global ts_desktop_size_def ts_desktop_depth_def
- if {$ts_desktop_size_def != ""} {
- set geom $ts_desktop_size_def
- }
- if {$ts_desktop_depth_def != ""} {
- set dep $ts_desktop_depth_def
- }
- if {$ts_desktop_size != ""} {
- if [regexp {^[0-9][0-9]*x[0-9][0-9]*$} $ts_desktop_size] {
- set geom $ts_desktop_size
- }
- if {$ts_desktop_depth != ""} {
- set geom "${geom}x$ts_desktop_depth"
- } else {
- set geom "${geom}x$dep"
- }
- } else {
- set geom "${geom}x$dep"
- }
- set cmd "$cmd -env FD_GEOM=$geom";
- }
- if {$is_windows} {
- ;
- } elseif {$choose_x11vnc_opts && $ts_x11vnc_autoport != "" && [regexp {^[0-9][0-9]*$} $ts_x11vnc_autoport]} {
- set cmd "$cmd -autoport $ts_x11vnc_autoport";
- } else {
- set cmd "$cmd -env AUTO_PORT=5950";
- }
- if {$choose_x11vnc_opts && $ts_x11vnc_opts != ""} {
- set cmd "$cmd $ts_x11vnc_opts";
- }
- if {$ts_xlogin} {
- regsub {PORT= } $cmd "PORT= sudo " cmd
- regsub {P= } $cmd "P= sudo " cmd
- regsub { -o [^ ][^ ]*} $cmd "" cmd
-
- set cmd "$cmd -env FD_XDM=1";
- }
-
- return $cmd
-}
-
-proc set_defaults {} {
- global defs env
-
- global mycert svcert crtdir crlfil
- global use_alpha use_turbovnc disable_pipeline use_grab use_ssl use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233
- global use_send_clipboard use_send_always
- global disable_all_encryption
- global use_nojpeg use_raise_on_beep use_compresslevel use_quality use_x11_macosx
- global compresslevel_text quality_text
- global use_cups use_sound use_smbmnt
- global cups_local_server cups_remote_port cups_manage_rcfile ts_cups_manage_rcfile cups_x11vnc
- global cups_local_smb_server cups_remote_smb_port
- global change_vncviewer change_vncviewer_path vncviewer_realvnc4
- global choose_xserver ts_xserver_type choose_desktop ts_desktop_type ts_unixpw ts_vncshared
- global choose_filexfer ts_filexfer
- global ts_x11vnc_opts choose_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport ts_xlogin
- global ts_othervnc choose_othervnc choose_sleep
- global choose_ncache ts_ncache choose_multisession ts_multisession
- global ts_mode ts_desktop_size ts_desktop_depth choose_desktop_geom
- global additional_port_redirs additional_port_redirs_list
- global stunnel_local_protection stunnel_local_protection_type ssh_local_protection multiple_listen listen_once listen_accept_popup listen_accept_popup_sc
- global ssh_known_hosts ssh_known_hosts_filename
- global ultra_dsm ultra_dsm_type ultra_dsm_file ultra_dsm_noultra ultra_dsm_salt
- global sound_daemon_remote_cmd sound_daemon_remote_port sound_daemon_kill sound_daemon_restart
- global sound_daemon_local_cmd sound_daemon_local_port sound_daemon_local_kill sound_daemon_x11vnc sound_daemon_local_start
- global smb_su_mode smb_mount_list
- global use_port_knocking port_knocking_list port_slot putty_args
- global ycrop_string ssvnc_scale ssvnc_escape sbwid_string rfbversion ssvnc_encodings ssvnc_extra_opts use_x11cursor use_nobell use_rawlocal use_notty use_popupfix extra_sleep use_listen use_unixpw use_x11vnc_find unixpw_username
- global disable_ssl_workarounds disable_ssl_workarounds_type
- global no_probe_vencrypt server_vencrypt server_anondh
- global include_list
- global svcert_default mycert_default crlfil_default
-
-
- set defs(use_viewonly) 0
- set defs(use_listen) 0
- set defs(disable_ssl_workarounds) 0
- set defs(disable_ssl_workarounds_type) "none"
- set defs(use_unixpw) 0
- set defs(unixpw_username) ""
- set defs(use_x11vnc_find) 0
- set defs(use_fullscreen) 0
- set defs(use_raise_on_beep) 0
- set defs(use_bgr233) 0
- set defs(use_alpha) 0
- set defs(use_send_clipboard) 0
- set defs(use_send_always) 0
- set defs(use_turbovnc) 0
- set defs(disable_pipeline) 0
- set defs(no_probe_vencrypt) 0
- set defs(server_vencrypt) 0
- set defs(server_anondh) 0
- set defs(use_grab) 0
- set defs(use_nojpeg) 0
- set defs(use_x11_macosx) 1
- if [info exists env(SSVNC_COTVNC)] {
- if {$env(SSVNC_COTVNC) != 0} {
- set defs(use_x11_macosx) 0
- }
- } elseif {![info exists env(DISPLAY)]} {
- set defs(use_x11_macosx) 0
- }
- set defs(use_compresslevel) "default"
- set defs(use_quality) "default"
- set defs(compresslevel_text) "Compress Level: default"
- set defs(quality_text) "Quality: default"
-
- set defs(mycert) $mycert_default
- set defs(svcert) $svcert_default
- set defs(crtdir) "ACCEPTED_CERTS"
- set defs(crlfil) $crlfil_default
-
- set defs(use_cups) 0
- set defs(use_sound) 0
- set defs(use_smbmnt) 0
-
- set defs(choose_xserver) 0
- set defs(ts_xserver_type) ""
- set defs(choose_desktop) 0
- set defs(ts_desktop_type) ""
- set defs(ts_desktop_size) ""
- set defs(ts_desktop_depth) ""
- set defs(choose_desktop_geom) 0
- set defs(ts_unixpw) 0
- set defs(ts_vncshared) 0
- set defs(ts_ncache) 8
- set defs(choose_ncache) 0
- set defs(ts_multisession) ""
- set defs(choose_multisession) 0
- set defs(ts_filexfer) ""
- set defs(choose_filexfer) 0
- set defs(choose_x11vnc_opts) 0
- set defs(ts_x11vnc_opts) ""
- set defs(ts_x11vnc_path) ""
- set defs(ts_x11vnc_autoport) ""
- set defs(ts_othervnc) ""
- set defs(choose_othervnc) 0
- set defs(ts_xlogin) 0
- set defs(ts_mode) 0
-
- set defs(change_vncviewer) 0
- set defs(change_vncviewer_path) ""
- set defs(cups_manage_rcfile) 1
- set defs(ts_cups_manage_rcfile) 0
- set defs(cups_x11vnc) 0
- set defs(vncviewer_realvnc4) 0
-
- set defs(additional_port_redirs) 0
- set defs(additional_port_redirs_list) ""
-
- set defs(stunnel_local_protection) 1
- set defs(stunnel_local_protection_type) "exec"
- set defs(ssh_local_protection) 1
- set defs(ssh_known_hosts) 0
- set defs(ssh_known_hosts_filename) ""
- set defs(multiple_listen) 0
- set defs(listen_once) 0
- set defs(listen_accept_popup) 0
- set defs(listen_accept_popup_sc) 0
-
- set defs(ultra_dsm) 0
- set defs(ultra_dsm_file) ""
- set defs(ultra_dsm_type) "guess"
- set defs(ultra_dsm_noultra) 0
- set defs(ultra_dsm_salt) ""
-
- set defs(port_slot) ""
- set defs(putty_args) ""
-
- set defs(cups_local_server) ""
- set defs(cups_remote_port) ""
- set defs(cups_local_smb_server) ""
- set defs(cups_remote_smb_port) ""
-
- set defs(smb_su_mode) "sudo"
- set defs(smb_mount_list) ""
-
- set defs(sound_daemon_remote_cmd) ""
- set defs(sound_daemon_remote_port) ""
- set defs(sound_daemon_kill) 0
- set defs(sound_daemon_restart) 0
-
- set defs(sound_daemon_local_cmd) ""
- set defs(sound_daemon_local_port) ""
- set defs(sound_daemon_local_start) 0
- set defs(sound_daemon_local_kill) 0
- set defs(sound_daemon_x11vnc) 0
-
- set defs(ycrop_string) ""
- set defs(ssvnc_scale) ""
- set defs(ssvnc_escape) ""
- set defs(sbwid_string) ""
- set defs(rfbversion) ""
- set defs(ssvnc_encodings) ""
- set defs(ssvnc_extra_opts) ""
- set defs(use_x11cursor) 0
- set defs(use_nobell) 0
- set defs(use_rawlocal) 0
- set defs(use_notty) 0
- set defs(use_popupfix) 0
- set defs(extra_sleep) ""
- set defs(use_port_knocking) 0
- set defs(port_knocking_list) ""
-
- set defs(include_list) ""
-
- set dir [get_profiles_dir]
- set deffile ""
- if [file exists "$dir/defaults"] {
- set deffile "$dir/defaults"
- } elseif [file exists "$dir/defaults.vnc"] {
- set deffile "$dir/defaults.vnc"
- }
- if {$deffile != ""} {
- set fh ""
- catch {set fh [open $deffile "r"]}
- if {$fh != ""} {
- while {[gets $fh line] > -1} {
- set line [string trim $line]
- if [regexp {^#} $line] {
- continue
- }
- if [regexp {^([^=]*)=(.*)$} $line m var val] {
- if {$var == "disp"} {
- continue
- }
- if [info exists defs($var)] {
- set pct 0
- if {$var == "smb_mount_list"} {
- set pct 1
- }
- if {$var == "port_knocking_list"} {
- set pct 1
- }
- if {$pct} {
- regsub -all {%%%} $val "\n" val
- }
- set defs($var) $val
- }
- }
- }
- close $fh
- }
- }
-
- global ssh_only ts_only
- if {$ssh_only || $ts_only} {
- set defs(use_ssl) 0
- set defs(use_ssh) 1
- set defs(use_sshssl) 0
- } else {
- set defs(use_ssl) 1
- set defs(use_ssh) 0
- set defs(use_sshssl) 0
- }
- set defs(disable_all_encryption) 0
-
- foreach var [array names defs] {
- set $var $defs($var)
- }
-
- global vncauth_passwd unixpw_passwd
- set vncauth_passwd ""
- set unixpw_passwd ""
-
- if {$ssh_only || $ts_only} {
- ssl_ssh_adjust ssh
- } else {
- ssl_ssh_adjust ssl
- }
- listen_adjust
- unixpw_adjust
-
- global last_load
- set last_load ""
-}
-
-proc windows_listening_message {n} {
- global did_listening_message
-
- global extra_cmd
- set extra_cmd ""
- set cmd [get_cmd $n]
-
- if {$did_listening_message < 2} {
- incr did_listening_message
- global listening_name
-
- set ln $listening_name
- if {$ln == ""} {
- set ln "this-computer:$n"
- }
-
- set msg "
- About to start the Listening VNC Viewer (Reverse Connection).
-
- The VNC Viewer command to be run is:
-
- $cmd
-
- After the Viewer starts listening, the VNC server should
- then Reverse connect to:
-
- $ln
-
- When the VNC Connection has ended **YOU MUST MANUALLY STOP**
- the Listening VNC Viewer.
-
- To stop the Listening Viewer: right click on the VNC Icon in
- the tray and select 'Close listening daemon' (or similar).
-
- ONLY AFTER THAT will you return to the SSVNC GUI.
-
- Click OK now to start the Listening VNC Viewer.$extra_cmd
-"
- global use_ssh use_sshssl
- if {$use_ssh || $use_sshssl} {
- set msg "${msg} NOTE: You will probably also need to kill the SSH in the\n terminal via Ctrl-C"
- }
-
- global help_font is_windows system_button_face
- toplev .wll
- global wll_done
-
- set wll_done 0
-
- eval text .wll.t -width 64 -height 22 $help_font
- button .wll.d -text "OK" -command {destroy .wll; set wll_done 1}
- pack .wll.t .wll.d -side top -fill x
-
- apply_bg .wll.t
-
- center_win .wll
- wm resizable .wll 1 0
-
- wm title .wll "SSL/SSH Viewer: Listening VNC Info"
-
- .wll.t insert end $msg
-
- vwait wll_done
- }
-}
-
-proc get_cmd {n} {
- global use_alpha use_grab use_x11cursor use_nobell use_ssh
- global use_sshssl use_viewonly use_fullscreen use_bgr233
- global use_nojpeg use_raise_on_beep use_compresslevel use_quality
- global use_send_clipboard use_send_always change_vncviewer
- global change_vncviewer_path vncviewer_realvnc4 use_listen
- global disable_ssl_workarounds disable_ssl_workarounds_type env
-
- set cmd "vncviewer"
- if {$change_vncviewer && $change_vncviewer_path != ""} {
- set cmd [string trim $change_vncviewer_path]
- regsub -all {\\} $cmd {/} cmd
- if {[regexp {[ \t]} $cmd]} {
- if {[regexp -nocase {\.exe$} $cmd]} {
- if {! [regexp {["']} $cmd]} { #"
- # hmmm, not following instructions, are they?
- set cmd "\"$cmd\""
- }
- }
- }
- }
- if {$use_viewonly} {
- if {$vncviewer_realvnc4} {
- append cmd " viewonly=1"
- } else {
- append cmd " /viewonly"
- }
- }
- if {$use_fullscreen} {
- if {$vncviewer_realvnc4} {
- append cmd " fullscreen=1"
- } else {
- append cmd " /fullscreen"
- }
- }
- if {$use_bgr233} {
- if {$vncviewer_realvnc4} {
- append cmd " lowcolourlevel=1"
- } else {
- append cmd " /8bit"
- }
- }
- if {$use_nojpeg} {
- if {! $vncviewer_realvnc4} {
- append cmd " /nojpeg"
- }
- }
- if {$use_raise_on_beep} {
- if {! $vncviewer_realvnc4} {
- append cmd " /belldeiconify"
- }
- }
- if {$use_compresslevel != "" && $use_compresslevel != "default"} {
- if {$vncviewer_realvnc4} {
- append cmd " zliblevel=$use_compresslevel"
- } else {
- append cmd " /compresslevel $use_compresslevel"
- }
- }
- if {$use_quality != "" && $use_quality != "default"} {
- if {! $vncviewer_realvnc4} {
- append cmd " /quality $use_quality"
- }
- }
-
- global extra_cmd
- set extra_cmd ""
- if {$use_listen} {
- if {$vncviewer_realvnc4} {
- append cmd " listen=1"
- } else {
- append cmd " /listen"
- }
- set nn $n
- if {$nn < 100} {
- set nn [expr "$nn + 5500"]
- }
- global direct_connect_reverse_host_orig is_win9x
- if {![info exists direct_connect_reverse_host_orig]} {
- set direct_connect_reverse_host_orig ""
- }
- if {$direct_connect_reverse_host_orig != "" && !$is_win9x} {
- set nn2 [expr $nn + 15]
- set h0 $direct_connect_reverse_host_orig
- global win_localhost
- set extra_cmd "\n\nrelay6.exe $nn $win_localhost $nn2 /b:$h0"
- set nn $nn2
- }
-
- append cmd " $nn"
-
- } else {
- if [regexp {^[0-9][0-9]*$} $n] {
- global win_localhost
- append cmd " $win_localhost:$n"
- } else {
- append cmd " $n"
- }
- }
- return $cmd
-}
-
-proc do_viewer_windows {n} {
- global use_listen env
-
- set cmd [get_cmd $n]
-
- set ipv6_pid2 ""
- if {$use_listen} {
- set nn $n
- if {$nn < 100} {
- set nn [expr "$nn + 5500"]
- }
- global direct_connect_reverse_host_orig is_win9x
- if {![info exists direct_connect_reverse_host_orig]} {
- set direct_connect_reverse_host_orig ""
- }
- if {$direct_connect_reverse_host_orig != "" && !$is_win9x} {
- set nn2 [expr $nn + 15]
- set h0 $direct_connect_reverse_host_orig
- global win_localhost
- set ipv6_pid2 [exec relay6.exe $nn $win_localhost $nn2 /b:$h0 &]
- set nn $nn2
- }
- }
-
- if [info exists env(SSVNC_EXTRA_SLEEP)] {
- set t $env(SSVNC_EXTRA_SLEEP)
- mesg "sleeping an extra $t seconds..."
- set t [expr "$t * 1000"]
- after $t
- }
- global extra_sleep
- if {$extra_sleep != ""} {
- set t $extra_sleep
- mesg "sleeping an extra $t seconds..."
- set t [expr "$t * 1000"]
- after $t
- }
-
- mesg $cmd
- set emess ""
- set rc [catch {eval exec $cmd} emess]
-
- if {$ipv6_pid2 != ""} {
- winkill $ipv6_pid2
- }
-
- if {$rc != 0} {
- raise .
- tk_messageBox -type ok -icon error -message $emess -title "Error: $cmd"
- }
-}
-
-proc get_netstat {} {
- set ns ""
- catch {set ns [exec netstat -an]}
- return $ns
-}
-
-proc get_ipconfig {} {
- global is_win9x
- set ip ""
- if {! $is_win9x} {
- catch {set ip [exec ipconfig]}
- return $ip
- }
-
- set file "ip"
- append file [pid]
- append file ".txt"
-
- # VF
- catch {[exec winipcfg /Batch $file]}
-
- if [file exists $file] {
- set fh [open $file "r"]
- while {[gets $fh line] > -1} {
- append ip "$line\n"
- }
- close $fh
- catch {file delete $file}
- }
- return $ip
-}
-
-proc read_file {file} {
- set str ""
- if [file exists $file] {
- set fh ""
- catch {set fh [open $file "r"]}
- if {$fh != ""} {
- while {[gets $fh line] > -1} {
- append str "$line\n"
- }
- close $fh
- }
- }
- return $str
-}
-
-proc guess_nat_ip {} {
- global save_nat last_save_nat
- set s ""
-
- if {! [info exists save_nat]} {
- set save_nat ""
- set last_save_nat 0
- }
- if {$save_nat != ""} {
- set now [clock seconds]
- if {$now < $last_save_nat + 45} {
- return $save_nat
- }
- }
- set s ""
- catch {set s [socket "www.whatismyip.com" 80]}
- set ip "unknown"
- if {$s != ""} {
- fconfigure $s -buffering none
- #puts $s "GET / HTTP/1.1"
- puts $s "GET /automation/n09230945.asp HTTP/1.1"
- puts $s "Host: www.whatismyip.com"
- puts $s "Connection: close"
- puts $s ""
- flush $s
- set on 0
- while { [gets $s line] > -1 } {
- if {! $on && [regexp {<HEAD>} $line]} {set on 1}
- if {! $on && [regexp {<HTML>} $line]} {set on 1}
- if {! $on && [regexp {<TITLE>} $line]} {set on 1}
- if {! $on && [regexp {^[0-9][0-9]*\.[0-9]} $line]} {set on 1}
- if {! $on} {
- continue;
- }
- if [regexp {([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*)} $line ip] {
- break
- }
- }
- close $s
- }
- if {$ip != "unknown"} {
- set save_nat $ip
- set last_save_nat [clock seconds]
- }
- return $ip
-}
-
-proc check_for_ipv6 {} {
- global is_windows have_ipv6
- if {$have_ipv6 != ""} {
- return
- }
- if {! $is_windows} {
- set out ""
- catch {set out [exec netstat -an]}
- if [regexp {tcp6} $out] {
- set have_ipv6 1
- } elseif [regexp {udp6} $out] {
- set have_ipv6 1
- } elseif [regexp {:::} $out] {
- set have_ipv6 1
- } elseif [regexp {::1} $out] {
- set have_ipv6 1
- } elseif [regexp {TCP: IPv6.*LISTEN} $out] {
- set have_ipv6 1
- } else {
- set have_ipv6 0
- }
- } else {
- set out [get_ipconfig]
- set out [string trim $out]
- if {$out == ""} {
- catch {set out [exec ping6 -n 1 -w 2000 ::1]}
- if [regexp {Reply from.*bytes} $out] {
- if [regexp {Received = 1} $out] {
- set have_ipv6 1
- return
- }
- }
- set have_ipv6 0
- return
- }
- foreach line [split $out "\n\r"] {
- if {[regexp -nocase {IP Address.*:[ \t]*[a-f0-9]*:[a-f0-9]*:} $line]} {
- set have_ipv6 1
- return
- }
- }
- set have_ipv6 0
- }
-}
-proc guess_ip {} {
- global is_windows
- if {! $is_windows} {
- set out ""
- set out [get_hostname]
- if {$out != ""} {
- set hout ""
- catch {set hout [exec host $out]}
- if {$hout != ""} {
- if [regexp {has address ([.0-9][.0-9]*)} $hout mvar ip] {
- set ip [string trim $ip]
- return $ip
- }
- }
- }
- return ""
- } else {
- set out [get_ipconfig]
- set out [string trim $out]
- if {$out == ""} {
- return ""
- }
- foreach line [split $out "\n\r"] {
- if {[regexp -nocase {IP Address.*:[ \t]*([.0-9][.0-9]*)} $line mvar ip]} {
- set ip [string trim $ip]
- if [regexp {^[.0]*$} $ip] {
- continue
- }
- if [regexp {127\.0\.0\.1} $ip] {
- continue
- }
- if {$ip != ""} {
- return $ip
- }
- }
- }
- foreach line [split $out "\n\r"] {
- if {[regexp -nocase {IP Address.*:[ \t]*([:a-f0-9][%:a-f0-9]*)} $line mvar ip]} {
- set ip [string trim $ip]
- if [regexp {^[.0]*$} $ip] {
- continue
- }
- if [regexp {127\.0\.0\.1} $ip] {
- continue
- }
- if {$ip != ""} {
- return $ip
- }
- }
- }
- }
-}
-
-proc bat_sleep {fh} {
- global env
- if [info exists env(SSVNC_BAT_SLEEP)] {
- puts $fh "@echo ."
- puts $fh "@echo -----"
- puts $fh "@echo Debug: BAT SLEEP for $env(SSVNC_BAT_SLEEP) seconds ..."
- puts $fh "@ping -n $env(SSVNC_BAT_SLEEP) -w 1000 0.0.0.1 > NUL"
- puts $fh "@echo BAT SLEEP done."
- }
-}
-
-proc windows_start_sound_daemon {file} {
- global env
- global use_sound sound_daemon_local_cmd sound_daemon_local_start
-
- # VF
- regsub {\.bat} $file "snd.bat" file2
- set fh2 [open $file2 "w"]
-
- puts $fh2 $sound_daemon_local_cmd
- bat_sleep $fh2
- puts $fh2 "del $file2"
- close $fh2
-
- mesg "Starting SOUND daemon..."
- if [info exists env(COMSPEC)] {
- if [info exists env(SSVNC_BAT_SLEEP)] {
- exec $env(COMSPEC) /c start $env(COMSPEC) /c $file2 &
- } else {
- exec $env(COMSPEC) /c $file2 &
- }
- } else {
- if [info exists env(SSVNC_BAT_SLEEP)] {
- exec cmd.exe /c start cmd.exe /c $file2 &
- } else {
- exec cmd.exe /c $file2 &
- }
- }
- after 1500
-}
-
-proc winkill {pid} {
- global is_win9x
-
- if {$pid == ""} {
- return
- }
- if {! $is_win9x} {
- catch {exec tskill.exe $pid}
- after 100
- catch {exec taskkill.exe /PID $pid}
- after 100
- }
- catch {exec w98/kill.exe /f $pid}
-}
-
-proc windows_stop_sound_daemon {} {
- global use_sound sound_daemon_local_cmd sound_daemon_local_start
-
- set cmd [string trim $sound_daemon_local_cmd]
-
- regsub {[ \t].*$} $cmd "" cmd
- regsub {^.*\\} $cmd "" cmd
- regsub {^.*/} $cmd "" cmd
-
- if {$cmd == ""} {
- return
- }
-
- set output [get_task_list]
-
- foreach line [split $output "\n\r"] {
- if [regexp "$cmd" $line] {
- if [regexp {(-?[0-9][0-9]*)} $line m p] {
- set pids($p) $line
- }
- }
- }
-
- set count 0
- foreach pid [array names pids] {
- mesg "Stopping SOUND pid: $pid"
- winkill $pid
- if {$count == 0} {
- after 1200
- } else {
- after 500
- }
- incr count
- }
-}
-
-proc contag {} {
- global concount
- if {! [info exists concount]} {
- set concount 0
- }
- incr concount
- set str [pid]
- set str "-$str-$concount"
-}
-
-proc make_plink {} {
- toplev .plink
- #wm geometry .plink +700+500
- wm geometry .plink -40-40
- wm title .plink "plink SSH status?"
- set wd 37
- label .plink.l1 -anchor w -text "Login via plink/ssh to the remote server" -width $wd
- label .plink.l2 -anchor w -text "(supply username and password as needed)." -width $wd
- label .plink.l3 -anchor w -text "" -width $wd
- label .plink.l4 -anchor w -text "After ssh is set up, AND if the connection" -width $wd
- label .plink.l5 -anchor w -text "success is not autodetected, please click" -width $wd
- label .plink.l6 -anchor w -text "one of these buttons:" -width $wd
- global plink_status
- button .plink.fail -text "Failed" -command {destroy .plink; set plink_status no}
- button .plink.ok -text "Success" -command {destroy .plink; set plink_status yes}
- pack .plink.l1 .plink.l2 .plink.l3 .plink.l4 .plink.l5 .plink.l6 .plink.fail .plink.ok -side top -fill x
-
- update
-}
-
-proc ssh_split {str} {
- regsub { .*$} $str "" str
- if {! [regexp {:[0-9][0-9]*$} $str]} {
- append str ":22"
- }
- regsub {:[0-9][0-9]*$} $str "" ssh_host
- regsub {^.*:} $str "" ssh_port
- if {$ssh_port == ""} {
- set ssh_port 22
- }
- if [regexp {@} $ssh_host] {
- regsub {@.*$} $ssh_host "" ssh_user
- regsub {^.*@} $ssh_host "" ssh_host
- } else {
- set ssh_user ""
- }
- return [list $ssh_user $ssh_host $ssh_port]
-}
-
-proc check_debug_netstat {port str wn} {
- global debug_netstat
- if {! [info exists debug_netstat]} {
- return
- }
- if {$debug_netstat == "0" || $debug_netstat == ""} {
- return
- }
- mesg "DBG: $wn"
-
- toplev .dbns
-
- set h 35
- if [small_height] {
- set h 28
- }
- scroll_text_dismiss .dbns.f 82 $h
- center_win .dbns
- .dbns.f.t insert end "LOOKING FOR PORT: $port\n\n$str"
- jiggle_text .dbns.f.t
- update
- after 1000
-}
-
-proc launch_windows_ssh {hp file n} {
- global is_win9x env
- global use_sshssl use_ssh putty_pw putty_args
- global port_knocking_list
- global use_listen listening_name
- global disable_ssl_workarounds disable_ssl_workarounds_type
- global ts_only
- global debug_netstat
-
- set hpnew [get_ssh_hp $hp]
- set proxy [get_ssh_proxy $hp]
- set sshcmd [get_ssh_cmd $hp]
-
- global win_localhost
-
- set vnc_host $win_localhost
- set vnc_disp $hpnew
- regsub {^.*:} $vnc_disp "" vnc_disp
-
- regsub {\.bat} $file ".flg" flag
-
- if {$ts_only} {
- regsub {:0$} $hpnew "" hpnew
- if {$proxy == ""} {
- if {[regexp {^(.*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} {
- set proxy "$sshhst:$sshpt"
- set hpnew $win_localhost
- }
- } else {
- if {![regexp {,} $proxy]} {
- if {$hpnew != $win_localhost} {
- set proxy "$proxy,$hpnew"
- set hpnew $win_localhost
- }
- }
- }
- } elseif {![regexp {^-?[0-9][0-9]*$} $vnc_disp]} {
- if {[regexp {cmd=SHELL} $hp]} {
- ;
- } elseif {[regexp {cmd=PUTTY} $hp]} {
- ;
- } else {
- # XXX add :0 instead?
- if {1} {
- set vnc_disp "vnc_disp:0"
- mesg "Added :0 to $vnc_disp"
- } else {
- mesg "Bad vncdisp, missing :0 ?, $vnc_disp"
- bell
- return 0
- }
- }
- }
-
- if {$use_listen} {
- set vnc_port 5500
- } else {
- set vnc_port 5900
- }
-
- if {$ts_only || [regexp {PORT= .*x11vnc} $sshcmd] || [regexp {P= .*x11vnc} $sshcmd]} {
- regsub {PORT= [ ]*} $sshcmd "" sshcmd
- regsub {P= [ ]*} $sshcmd "" sshcmd
- set vnc_port [expr "8100 + int(4000 * rand())"]
- set sshcmd "$sshcmd -rfbport $vnc_port"
- } elseif {[regexp {^-[0-9][0-9]*$} $vnc_disp]} {
- set vnc_port [expr "- $vnc_disp"]
- } elseif {![regexp {^[0-9][0-9]*$} $vnc_disp]} {
- ;
- } elseif {$vnc_disp < 200} {
- if {$use_listen} {
- set vnc_port [expr $vnc_disp + 5500]
- } else {
- set vnc_port [expr $vnc_disp + 5900]
- }
- } else {
- set vnc_port $vnc_disp
- }
-
- global ssh_ipv6_pid
- set ssh_ipv6_pid ""
-
- set ssh_port 22
- set ssh_host [host_part $hpnew]
-
- set double_ssh ""
- set p_port ""
- if {$proxy != ""} {
- if [regexp -nocase {(http|https|socks|socks4|socks5|repeater)://} $proxy] {
- set pproxy ""
- set sproxy1 ""
- set sproxy_rest ""
- set sproxy1_host ""
- set sproxy1_user ""
- set sproxy1_port ""
- foreach part [split $proxy ","] {
- if {[regexp {^[ ]*$} $part]} {
- continue
- }
- if [regexp -nocase {^(http|https|socks|socks4|socks5|repeater)://} $part] {
- if {$pproxy == ""} {
- set pproxy $part
- } else {
- set pproxy "$pproxy,$part"
- }
- } else {
- if {$sproxy1 == ""} {
- set sproxy1 $part
- } else {
- if {$sproxy_rest == ""} {
- set sproxy_rest $part
- } else {
- set sproxy_rest "$sproxy_rest,$part"
- }
- }
- }
- }
-
-#mesg "pproxy: $pproxy"; after 2000
-#mesg "sproxy1: $sproxy1"; after 2000
-#mesg "sproxy_rest: $sproxy_rest"; after 2000
-#mesg "ssh_host: $ssh_host"; after 2000
-#mesg "ssh_port: $ssh_port"; after 2000
-
- if {$sproxy1 != ""} {
- regsub {:[0-9][0-9]*$} $sproxy1 "" sproxy1_host
- regsub {^.*@} $sproxy1_host "" sproxy1_host
- regsub {@.*$} $sproxy1 "" sproxy1_user
- regsub {^.*:} $sproxy1 "" sproxy1_port
- } else {
- regsub {:[0-9][0-9]*$} $ssh_host "" sproxy1_host
- regsub {^.*@} $sproxy1_host "" sproxy1_host
- regsub {@.*$} $ssh_host "" sproxy1_user
- regsub {^.*:} $ssh_host "" sproxy1_port
- }
- if {![regexp {^[0-9][0-9]*$} $sproxy1_port]} {
- set sproxy1_port 22
- }
- if {$sproxy1_user != ""} {
- set sproxy1_user "$sproxy1_user@"
- }
-
-#mesg "sproxy1_host: $sproxy1_host"; after 2000
-#mesg "sproxy1_user: $sproxy1_user"; after 2000
-#mesg "sproxy1_port: $sproxy1_port"; after 2000
-
- set port2 ""
- if [regexp -- {-([0-9][0-9]*)} [file tail $file] mv dport] {
- set port2 [expr 21000 + $dport]
- } else {
- set port2 [rand_port]
- }
-
- global have_ipv6
- if {$have_ipv6} {
- set res [ipv6_proxy $pproxy "" ""]
- set pproxy [lindex $res 0]
- set ssh_ipv6_pid [lindex $res 3]
- }
-
- set env(SSVNC_PROXY) $pproxy
- set env(SSVNC_LISTEN) $port2
- set env(SSVNC_DEST) "$sproxy1_host:$sproxy1_port"
-
- mesg "Starting Proxy TCP helper on port $port2 ..."
- after 300
- # ssh br case:
- set proxy_pid [exec "connect_br.exe" &]
-
- catch { unset env(SSVNC_PROXY) }
- catch { unset env(SSVNC_LISTEN) }
- catch { unset env(SSVNC_DEST) }
-
- if {$sproxy1 == ""} {
- set proxy "$win_localhost:$port2"
- if [regexp {^(.*)@} $ssh_host mv u] {
- set proxy "$u@$proxy"
- }
- } else {
- set proxy "${sproxy1_user}$win_localhost:$port2"
- }
- if {$sproxy_rest != ""} {
- set proxy "$proxy,$sproxy_rest"
- }
- mesg "Set proxy to: $proxy"
- after 300
- }
- if [regexp {,} $proxy] {
- if {$is_win9x} {
- mesg "Double proxy does not work on Win9x"
- bell
- winkill $ssh_ipv6_pid
- set ssh_ipv6_pid ""
- return 0
- }
- # user1@gateway:port1,user2@workstation:port2
- set proxy1 ""
- set proxy2 ""
- set s [split $proxy ","]
- set proxy1 [lindex $s 0]
- set proxy2 [lindex $s 1]
-
- set p_port ""
- if [regexp -- {-([0-9][0-9]*)} [file tail $file] mv dport] {
- set p_port [expr 4000 + $dport]
- } else {
- set p_port [expr 3000 + 1000 * rand()]
- set p_port [expr round($p_port)]
- }
-
- set s [ssh_split $proxy1]
- set ssh_user1 [lindex $s 0]
- set ssh_host1 [lindex $s 1]
- set ssh_port1 [lindex $s 2]
-
- set s [ssh_split $proxy2]
- set ssh_user2 [lindex $s 0]
- set ssh_host2 [lindex $s 1]
- set ssh_port2 [lindex $s 2]
-
- if {! [regexp {^[0-9][0-9]*$} $ssh_port1]} {
- set ssh_port1 22
- }
- if {! [regexp {^[0-9][0-9]*$} $ssh_port2]} {
- set ssh_port2 22
- }
-
- set u1 ""
- if {$ssh_user1 != ""} {
- set u1 "${ssh_user1}@"
- }
- set u2 ""
- if {$ssh_user2 != ""} {
- set u2 "${ssh_user2}@"
- }
-
- set double_ssh "-L $p_port:$ssh_host2:$ssh_port2 -P $ssh_port1 $u1$ssh_host1"
- set proxy_use "${u2}$win_localhost:$p_port"
-
- } else {
- # user1@gateway:port1
- set proxy_use $proxy
- }
-
- set ssh_host [host_part $proxy_use]
-
- set ssh_port [port_part $proxy_use]
- if {! [regexp {^[0-9][0-9]*$} $ssh_port]} {
- set ssh_port 22
- }
-
- set vnc_host [host_part $hpnew]
- if {$vnc_host == ""} {
- set vnc_host $win_localhost
- }
- }
-
- if {![regexp {^[^ ][^ ]*@} $ssh_host]} {
- mesg "You must supply a username: user@host..."
- bell
- winkill $ssh_ipv6_pid
- set ssh_ipv6_pid ""
- return 0
- }
-
- set verb "-v"
-
- set pwd ""
- if {$is_win9x} {
- set pwd [pwd]
- regsub -all {/} $pwd "\\" pwd
- }
- if {! [regexp {^[0-9][0-9]*$} $n]} {
- set n 0
- }
-
- if {$use_listen} {
- set use [expr $n + 5500]
- } else {
- set use [expr $n + 5900]
- }
-
- set_smb_mounts
-
- global use_smbmnt use_sound sound_daemon_kill
- set do_pre 0
- if {$use_smbmnt} {
- set do_pre 1
- } elseif {$use_sound && $sound_daemon_kill} {
- set do_pre 1
- }
-
- global skip_pre
- if {$skip_pre} {
- set do_pre 0
- set skip_pre 0
- }
-
- set pw ""
- if {$putty_pw != ""} {
- if {! [regexp {"} $putty_pw]} { #"
- set pw " -pw \"$putty_pw\""
- }
- }
-
- set tag [contag]
-
- set file_double ""
-
- set file_pre ""
- set file_pre_cmd ""
- if {$do_pre} {
- set setup_cmds [ugly_setup_scripts pre $tag]
-
- if {$setup_cmds != ""} {
- # VF
- regsub {\.bat} $file "pre.cmd" file_pre_cmd
- set fh [open $file_pre_cmd "w"]
- puts $fh "$setup_cmds sleep 10; "
- bat_sleep $fh
- close $fh
-
- # VF
- regsub {\.bat} $file "pre.bat" file_pre
- set fh [open $file_pre "w"]
- set plink_str "plink.exe -ssh -C -P $ssh_port -m $file_pre_cmd $verb -t"
- if {$putty_args != ""} {
- append plink_str " $putty_args"
- }
-
- global smb_redir_0
- if {$smb_redir_0 != ""} {
- append plink_str " $smb_redir_0"
- }
-
- if [regexp {%} $ssh_host] {
- set uath ""
- regsub -all {%SPACE} $ssh_host " " uath
- regsub -all {%TAB} $uath " " uath
- append plink_str "$pw \"$uath\""
- } else {
- append plink_str "$pw $ssh_host"
- }
-
- if {$pw != ""} {
- puts $fh "echo off"
- }
- puts $fh $plink_str
-
- bat_sleep $fh
- if {![info exists env(SSVNC_NO_DELETE)]} {
- if {$file_pre_cmd != ""} {
- puts $fh "del $file_pre_cmd"
- }
- puts $fh "del $file_pre"
- }
- close $fh
- }
- }
-
- if {$is_win9x} {
- set sleep 35
- } else {
- set sleep 20
- }
- if {$use_listen} {
- set sleep 1800
- }
-
- set setup_cmds [ugly_setup_scripts post $tag]
-
- set do_shell 0
- if {$sshcmd == "SHELL"} {
- set setup_cmds ""
- set sshcmd {$SHELL}
- set do_shell 1
- } elseif {$sshcmd == "PUTTY"} {
- set setup_cmds ""
- set do_shell 1
- }
-
- if {$sshcmd != "SHELL" && [regexp -nocase {x11vnc} $sshcmd]} {
- global use_cups cups_x11vnc cups_remote_port
- global cups_remote_smb_port
- global use_sound sound_daemon_x11vnc sound_daemon_remote_port
- global ts_only
- if {$ts_only} {
- set cups_x11vnc 1
- set sound_daemon_x11vnc 1
- }
- if {$use_cups && $cups_x11vnc && $cups_remote_port != ""} {
- set crp $cups_remote_port
- if {$ts_only} {
- set cups_remote_port [rand_port]
- set crp "DAEMON-$cups_remote_port"
- }
- set sshcmd "$sshcmd -env FD_CUPS=$crp"
- }
- if {$use_cups && $cups_x11vnc && $cups_remote_smb_port != ""} {
- set csp $cups_remote_smb_port
- if {$ts_only} {
- set cups_remote_smb_port [rand_port]
- set csp "DAEMON-$cups_remote_smb_port"
- }
- set sshcmd "$sshcmd -env FD_SMB=$csp"
- }
- if {$use_sound && $sound_daemon_x11vnc && $sound_daemon_remote_port != ""} {
- set srp $sound_daemon_remote_port
- if {$ts_only} {
- set sound_daemon_remote_port [rand_port]
- set srp "DAEMON-$sound_daemon_remote_port"
- }
- set sshcmd "$sshcmd -env FD_ESD=$srp"
- }
- }
-
- set file_cmd ""
- if {$setup_cmds != ""} {
- # VF
- regsub {\.bat} $file ".cmd" file_cmd
- set fh_cmd [open $file_cmd "w"]
-
- set str $setup_cmds
- if {$sshcmd != ""} {
- append str " $sshcmd; "
- } else {
- append str " sleep $sleep; "
- }
- puts $fh_cmd $str
- bat_sleep $fh_cmd
- close $fh_cmd
-
- set sshcmd $setup_cmds
- }
-
- if {$sshcmd == ""} {
- set pcmd "echo; echo SSH connected OK.; echo If this state is not autodetected,; echo Go Click the Success button."
- set sshcmd "$pcmd; sleep $sleep"
- }
-
- global use_sound sound_daemon_local_cmd sound_daemon_local_start
- if {! $do_shell && ! $is_win9x && $use_sound && $sound_daemon_local_start && $sound_daemon_local_cmd != ""} {
- windows_start_sound_daemon $file
- }
-
- # VF
- set fh [open $file "w"]
- if {$is_win9x} {
- puts $fh "cd $pwd"
- if {$file_pre != ""} {
- puts $fh "echo Press Ctrl-C --HERE-- when done with the Pre-Command shell work."
- puts $fh "start /w command.com /c $file_pre"
- }
- }
-
- global use_cups use_smbmnt
- set extra_redirs ""
- if {$use_cups} {
- append extra_redirs [get_cups_redir]
- }
- if {$use_sound} {
- append extra_redirs [get_sound_redir]
- }
- global additional_port_redirs
- if {$additional_port_redirs} {
- append extra_redirs [get_additional_redir]
- }
-
- if {$vnc_host == ""} {
- set vnc_host $win_localhost
- }
- regsub {^.*@} $vnc_host "" vnc_host
-
- set redir "-L $use:$vnc_host:$vnc_port"
- if {$use_listen} {
- set redir "-R $vnc_port:$vnc_host:$use"
- set listening_name "localhost:$vnc_port (on remote SSH side)"
- }
-
- set plink_str "plink.exe -ssh -P $ssh_port $verb $redir $extra_redirs -t"
- if {$putty_args != ""} {
- append plink_str " $putty_args"
- }
- if {$extra_redirs != ""} {
- regsub {exe} $plink_str "exe -C" plink_str
- } else {
- # hmm we used to have it off... why?
- # ssh typing response?
- regsub {exe} $plink_str "exe -C" plink_str
- }
- set uath $ssh_host
- if [regexp {%} $uath] {
- regsub -all {%SPACE} $uath " " uath
- regsub -all {%TAB} $uath " " uath
- set uath "\"$uath\""
- }
- if {$do_shell} {
- if {$sshcmd == "PUTTY"} {
- if [regexp {^".*@} $uath] { #"
- regsub {@} $uath {" "} uath
- set uath "-l $uath"
- }
- if {$is_win9x} {
- set plink_str "putty.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath"
- } else {
- set plink_str "start \"putty $ssh_host\" putty.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath"
- if [regexp {FINISH} $port_knocking_list] {
- regsub {start} $plink_str "start /wait" plink_str
- }
- }
- } else {
- set plink_str "plink.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath"
- append plink_str { "$SHELL"}
- }
- } elseif {$file_cmd != ""} {
- append plink_str " -m $file_cmd$pw $uath"
- } else {
- append plink_str "$pw $uath \"$sshcmd\""
- }
-
- if {$pw != ""} {
- puts $fh "echo off"
- }
- if {$ts_only && [regexp {sudo } $sshcmd]} {
- puts $fh "echo \" \""
- puts $fh "echo \"Doing Initial SSH with sudo id to prime sudo...\""
- puts $fh "echo \" \""
- puts $fh "plink.exe -ssh $putty_args -t $uath \"sudo id; tty\""
- puts $fh "echo \" \""
- }
- puts $fh $plink_str
- bat_sleep $fh
- puts $fh "del $flag"
- if {![info exists env(SSVNC_NO_DELETE)]} {
- if {$file_cmd != ""} {
- puts $fh "del $file_cmd"
- }
- puts $fh "del $file"
- }
- close $fh
-
- catch {destroy .o}
- catch {destroy .oa}
- catch {destroy .os}
-
- if { ![do_port_knock $ssh_host start]} {
- if {![info exists env(SSVNC_NO_DELETE)]} {
- catch {file delete $file}
- if {$file_cmd != ""} {
- catch {file delete $file_cmd}
- }
- if {$file_pre != ""} {
- catch {file delete $file_pre}
- }
- }
- winkill $ssh_ipv6_pid
- set ssh_ipv6_pid ""
- return 0
- }
-
- if {$double_ssh != ""} {
- set plink_str_double_ssh "plink.exe -ssh $putty_args -t $pw $double_ssh \"echo sleep 60 ...; sleep 60; echo done.\""
-
- # VF
- regsub {\.bat} $file "dob.bat" file_double
- set fhdouble [open $file_double "w"]
- puts $fhdouble $plink_str_double_ssh
- bat_sleep $fhdouble
- puts $fhdouble "del $flag"
- if {![info exists env(SSVNC_NO_DELETE)]} {
- puts $fhdouble "del $file_double"
- }
- close $fhdouble
-
- set com "cmd.exe"
- if [info exists env(COMSPEC)] {
- set com $env(COMSPEC)
- }
-
- set ff [open $flag "w"]
- puts $ff "flag"
- close $ff
-
- global env
- if [info exists env(SSVNC_BAT_SLEEP)] {
- exec $com /c start $com /c $file_double &
- } else {
- exec $com /c $file_double &
- }
-
- set waited 0
- set gotit 0
- while {$waited < 30000} {
- after 500
- update
- if {$use_listen} {
- set gotit 1
- break;
- }
- set ns [get_netstat]
- set re ":$p_port"
- check_debug_netstat $p_port $ns $waited
- append re {[ ][ ]*[0:.][0:.]*[ ][ ]*LISTEN}
- if [regexp $re $ns] {
- set gotit 1
- break
- }
- set waited [expr "$waited + 500"]
- if {![file exists $flag]} {
- break
- }
- }
- catch {file delete $flag}
- if {! $gotit} {
- after 5000
- }
- }
-
- vencrypt_tutorial_mesg
-
- set wdraw 1
- #set wdraw 0
- if [info exists debug_netstat] {
- if {$debug_netstat != "" && $debug_netstat != "0"} {
- set wdraw 0
- }
- }
-
- set ff [open $flag "w"]
- puts $ff "flag"
- close $ff
-
- if {$is_win9x} {
- if {$wdraw} {
- wm withdraw .
- }
- update
- win9x_plink_msg $file
- global win9x_plink_msg_done
- set win9x_plink_msg_done 0
- vwait win9x_plink_msg_done
- } else {
- set com "cmd.exe"
- if [info exists env(COMSPEC)] {
- set com $env(COMSPEC)
- }
-
- if {$file_pre != ""} {
- set sl 0
- if {$use_smbmnt} {
- global smb_su_mode
- if {$smb_su_mode == "su"} {
- set sl [expr $sl + 15]
- } elseif {$smb_su_mode == "sudo"} {
- set sl [expr $sl + 15]
- } else {
- set sl [expr $sl + 3]
- }
- }
- if {$pw == ""} {
- set sl [expr $sl + 5]
- }
-
- set sl [expr $sl + 5]
- set st [clock seconds]
- set dt 0
- global entered_gui_top button_gui_top
- set entered_gui_top 0
- set button_gui_top 0
-
- catch {wm geometry . "-40-40"}
- catch {wm withdraw .; update; wm deiconify .; raise .; update}
- mesg "Click on *This* Label when done with 1st SSH 0/$sl"
- after 600
-
- global env
- if [info exists env(SSVNC_BAT_SLEEP)] {
- exec $com /c start $com /c $file_pre &
- } else {
- exec $com /c $file_pre &
- }
-
- catch {lower .; update; raise .; update}
-
- while {$dt < $sl} {
- after 100
- set dt [clock seconds]
- set dt [expr $dt - $st]
- mesg "Click on *This* Label when done with 1st SSH $dt/$sl"
- update
- update idletasks
- if {$dt <= 1} {
- set button_gui_top 0
- }
- if {$button_gui_top != 0 && $dt >= 3} {
- mesg "Running 2nd SSH now ..."
- after 1000
- break
- }
- }
- mesg "Running 2nd SSH ..."
- }
-
- if {! $do_shell} {
- make_plink
- }
- if {$wdraw} {
- wm withdraw .
- }
-
- update
- if {$do_shell && [regexp {FINISH} $port_knocking_list]} {
- catch {exec $com /c $file}
- } else {
- global env
- if [info exists env(SSVNC_BAT_SLEEP)] {
- exec $com /c start $com /c $file &
- } else {
- exec $com /c $file &
- }
- }
- after 1000
- }
-
- if {$do_shell} {
- wm deiconify .
- update
- if {[regexp {FINISH} $port_knocking_list]} {
- do_port_knock $ssh_host finish
- }
- return 1
- }
- set made_plink 0
- if {$is_win9x} {
- make_plink
- set made_plink 1
- }
- global plink_status
- set plink_status ""
- set waited 0
- set cnt 0
- while {$waited < 30000} {
- after 500
- update
- if {$use_listen} {
- set plink_status yes
- break;
- }
- set ns [get_netstat]
- set re ":$use"
- check_debug_netstat $use $ns $waited
- append re {[ ][ ]*[0:.][0:.]*[ ][ ]*LISTEN}
- if [regexp $re $ns] {
- set plink_status yes
- }
- if {$plink_status != ""} {
- catch {destroy .plink}
- break
- }
-
- if {$waited == 0} {
- #wm deiconify .plink
- }
- set waited [expr "$waited + 500"]
-
- incr cnt
- if {$cnt >= 12} {
- set cnt 0
- }
- if {![file exists $flag]} {
- set plink_status flag_gone
- break
- }
- }
- catch {file delete $flag}
- if {$plink_status == ""} {
- if {! $made_plink} {
- make_plink
- set made_plink 1
- }
- vwait plink_status
- }
-
- if {$use_sshssl} {
- global launch_windows_ssh_files
- if {$file != ""} {
- append launch_windows_ssh_files "$file "
- }
- if {$file_pre != ""} {
- append launch_windows_ssh_files "$file_pre "
- }
- if {$file_pre_cmd != ""} {
- append launch_windows_ssh_files "$file_pre_cmd "
- }
- regsub { *$} $launch_windows_ssh_files "" launch_windows_ssh_files
- return 1
- }
-
- if {$plink_status != "yes"} {
- set m "unknown"
- if {$plink_status == "flag_gone"} {
- set m "plink script failed"
- } elseif {$plink_status == ""} {
- set m "timeout"
- }
- mesg "Error ($m) to $hp"
- wm deiconify .
- } else {
- after 1000
- do_viewer_windows $n
- wm deiconify .
- mesg "Disconnected from $hp"
- }
- update
- if [regexp {FINISH} $port_knocking_list] {
- do_port_knock $ssh_host finish
- }
-
- if {![info exists env(SSVNC_NO_DELETE)]} {
- if {$file != ""} {
- catch {file delete $file}
- }
- if {$file_pre != ""} {
- catch {file delete $file_pre}
- }
- if {$file_pre_cmd != ""} {
- catch {file delete $file_pre_cmd}
- }
- if {$file_double != ""} {
- catch {file delete $file_double}
- }
- }
-
- winkill $ssh_ipv6_pid
- set ssh_ipv6_pid ""
-
- global sound_daemon_local_kill
- if {! $is_win9x && $use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} {
- windows_stop_sound_daemon
- }
- return 1
-}
-
-proc check_ssh_needed {} {
- globalize
-
- if {$use_ssh || $use_sshssl} {
- return
- }
- set must_cups 0
- set must_snd 0
- set must_smb 0
- set must_addl 0
- if {$use_cups} {
- if {$cups_local_server != ""} {set must_cups 1}
- if {$cups_remote_port != ""} {set must_cups 1}
- if {$cups_local_smb_server != ""} {set must_cups 1}
- if {$cups_remote_smb_port != ""} {set must_cups 1}
- if {$cups_manage_rcfile != ""} {set must_cups 1}
- }
- if {$use_sound} {
- if {$sound_daemon_remote_cmd != ""} {set must_snd 1}
- if {$sound_daemon_remote_port != ""} {set must_snd 1}
- if {$sound_daemon_kill} {set must_snd 1}
- if {$sound_daemon_restart} {set must_snd 1}
- if {$sound_daemon_local_cmd != ""} {set must_snd 1}
- if {$sound_daemon_local_port != ""} {set must_snd 1}
- if {$sound_daemon_local_kill} {set must_snd 1}
- if {$sound_daemon_local_start} {set must_snd 1}
- }
- if {$use_smbmnt} {
- if {[regexp {//} $smb_mount_list]} {set must_smb 1}
- }
- if {$additional_port_redirs} {
- set must_addl 1
- }
- if {$must_cups || $must_snd || $must_smb || $must_addl} {
- mesg "Cannot do Port redirs in non-SSH mode (SSL)"
- set msg ""
- if {$must_smb} {
- append msg " - SMB Mount Port Redirection\n"
- }
- if {$must_snd} {
- append msg " - ESD Sound Port Redirection\n"
- }
- if {$must_cups} {
- append msg " - CUPS Port Redirection\n"
- }
- if {$must_addl} {
- append msg " - Additional Port Redirections\n"
- }
- set msg "\"Use SSL\" mode selected (no SSH)\nThe following options will be disabled:\n\n$msg"
- bell
- update
- raise .
- tk_messageBox -type ok -icon info -message $msg
- }
-}
-
-proc set_smb_mounts {} {
- global smb_redir_0 smb_mounts use_smbmnt
-
- set smb_redir_0 ""
- set smb_mounts ""
- if {$use_smbmnt} {
- set l2 [get_smb_redir]
- set smb_redir_0 [lindex $l2 0]
- set smb_redir_0 [string trim $smb_redir_0]
- set smb_mounts [lindex $l2 1]
- }
-}
-
-proc mytmp {tmp} {
- global is_windows mktemp env
-
- if {$is_windows} {
- return $tmp
- }
-
- if {! [info exists mktemp]} {
- set mktemp ""
- foreach dir {/bin /usr/bin /usr/local/bin} {
- if [file exists "$dir/mktemp"] {
- set mktemp "$dir/mktemp"
- break
- }
- }
- }
- if {$mktemp != ""} {
- set tmp2 ""
- catch {set tmp2 [exec $mktemp "$tmp.XXXXXX"]}
- if [file exists $tmp2] {
- if [info exists env(DEBUG_MKTEMP)] {
- puts stderr "mytmp: $tmp2"
- }
- return $tmp2
- }
- }
- catch {exec rm -f $tmp}
- catch {file delete $tmp}
- if [file exists $tmp] {
- puts stderr "tmp file still exists: $tmp"
- exit 1
- }
- catch {exec touch $tmp}
- catch {exec chmod 600 $tmp}
- if [info exists env(DEBUG_MKTEMP)] {
- puts stderr "mytmp: $tmp"
- }
- return $tmp
-}
-
-proc darwin_terminal_cmd {{title ""} {cmd ""} {bg 0}} {
- global darwin_terminal
-
- set tries ""
- lappend tries "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal"
-
- if {! [info exists darwin_terminal]} {
- foreach try $tries {
- if [file exists $try] {
- if [file executable $try] {
- set darwin_terminal $try
- break
- }
- }
- }
- if {! [info exists darwin_terminal]} {
- set fh ""
- catch {set fh [open "| find /Applications -type f -name Terminal" "r"]}
- if {$fh != ""} {
- while {[gets $fh line] > -1} {
- if {! [file exists $line]} {
- continue
- }
- if {[file isdirectory $line]} {
- continue
- }
- if {! [regexp {/Terminal$} $line]} {
- continue
- }
- if {! [file executable $line]} {
- continue
- }
- set darwin_terminal $line
- break
- }
- close $fh
- }
- }
- }
- if {! [info exists darwin_terminal]} {
- raise .
- tk_messageBox -type ok -icon error -message "Cannot find Darwin Terminal program." -title "Cannot find Terminal program"
- mac_raise
- return
- }
-
- global darwin_terminal_cnt
- set tmp /tmp/darwin_terminal_cmd.[tpid]
- if {! [info exists darwin_terminal_cnt]} {
- set darwin_terminal_cnt 0
- }
- incr darwin_terminal_cnt
- append tmp ".$darwin_terminal_cnt"
- set tmp [mytmp $tmp]
-
- set fh ""
- catch {set fh [open $tmp w 0755]}
- catch {[exec chmod 755 $tmp]}
- if {$fh == ""} {
- raise .
- tk_messageBox -type ok -icon error -message "Cannot open temporary file: $tmp" -title "Cannot open file"
- mac_raise
- return
- }
- global env
- puts $fh "#!/bin/sh"
- puts $fh "PATH=$env(PATH)"
- puts $fh "export PATH"
- puts $fh "tmp=$tmp"
- puts $fh "sleep 1"
- puts $fh {if [ "X$DDDBG" != "X" ]; then ps www; fi}
- puts $fh {termpid=`ps www | grep -w Terminal | grep $tmp | grep -v grep | awk '{print $1}' | sort -n | tail -1`}
- puts $fh {echo try-1: termpid=$termpid mypid=$$}
- puts $fh {if [ "X$termpid" = "X" ]; then}
- puts $fh { termpid=`ps www | grep -w Terminal | grep -v grep | awk '{print $1}' | sort -n | tail -1`}
- puts $fh { echo try-2: termpid=$termpid mypid=$$}
- puts $fh {fi}
- puts $fh {if [ "X$termpid" = "X" ]; then}
- puts $fh { termpid=`ps wwwwaux | grep -w Terminal | grep $tmp | grep -v grep | awk '{print $2}' | sort -n | tail -1`}
- puts $fh { echo try-3: termpid=$termpid mypid=$$}
- puts $fh {fi}
- puts $fh {if [ "X$termpid" = "X" ]; then}
- puts $fh { termpid=$$}
- puts $fh { echo termpid-find-fail: termpid=$termpid mypid=$$}
- puts $fh {fi}
- puts $fh {trap "rm -f $tmp; kill -TERM $termpid; kill -TERM $mypid; kill -KILL $mypid; exit 0" 0 2 15}
- puts $fh {osascript -e 'tell application "Terminal" to activate' >/dev/null 2>&1 &}
- puts $fh "$cmd"
- puts $fh "sleep 1"
- puts $fh {rm -f $tmp}
- puts $fh {kill -TERM $termpid}
- puts $fh {kill -TERM $mypid}
- puts $fh {kill -KILL $mypid}
- puts $fh "exit 0"
- close $fh
- if {$bg} {
- catch {exec $darwin_terminal $tmp &}
- } else {
- catch {exec $darwin_terminal $tmp}
- }
-}
-
-proc unix_terminal_cmd {{geometry "+100+100"} {title "xterm-command"} {cmd "echo test"} {bg 0} {xrm1 ""} {xrm2 ""} {xrm3 ""}} {
- global uname env
- if {$uname == "Darwin"} {
- global env
- set doX 0;
- if {! $doX} {
- darwin_terminal_cmd $title $cmd $bg
- return
- }
- }
-
- global checked_for_xterm
- if {![info exists checked_for_xterm]} {
- set p ""
- set r [catch {set p [exec /bin/sh -c {type xterm}]}]
- set checked_for_xterm 1
- if {$r != 0} {
- set p [exec /bin/sh -c {type xterm 2>&1; exit 0}]
- set txt "Problem finding the 'xterm' command:\n\n$p\n\n"
- append txt "Perhaps you need to install a package containing 'xterm' (Sigh...)\n\n"
- fetch_dialog $txt "xterm" "xterm" 0 [line_count $txt]
- update
- after 1000
- catch {tkwait window .fetch}
- update
- }
- }
-
- if [info exists env(SSVNC_XTERM_REPLACEMENT)] {
- set tcmd $env(SSVNC_XTERM_REPLACEMENT)
- if {$tcmd != ""} {
- regsub -all {%GEOMETRY} $tcmd $geometry tcmd
- regsub -all {%TITLE} $tcmd $title tcmd
-
- set tmp1 /tmp/xterm_replacement1.[tpid]
- set tmp1 [mytmp $tmp1]
- set fh1 ""
- catch {set fh1 [open $tmp1 "w"]}
-
- set tmp2 /tmp/xterm_replacement2.[tpid]
- set tmp2 [mytmp $tmp2]
- set fh2 ""
- catch {set fh2 [open $tmp2 "w"]}
- if {$fh1 != "" && $fh2 != ""} {
- puts $fh1 "#!/bin/sh";
- puts $fh1 "$cmd"
- puts $fh1 "rm -f $tmp1"
- close $fh1
- catch {exec chmod 755 $tmp1}
- puts $fh2 "#!/bin/sh"
- puts $fh2 "$tcmd $tmp1"
- puts $fh2 "rm -f $tmp2"
- close $fh2
- catch {exec chmod 755 $tmp2}
- if {$bg} {
- exec $tmp2 2>@stdout &
- } else {
- exec $tmp2 2>@stdout
- }
- return
- }
- catch {close $fh1}
- catch {close $fh2}
- }
- }
-
- if {$bg} {
- if {$xrm1 == ""} {
- exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout &
- } else {
- exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout &
- }
- } else {
- if {$xrm1 == ""} {
- exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout
- } else {
- exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout
- }
- }
-}
-
-proc xterm_center_geometry {} {
- set sh [winfo screenheight .]
- set sw [winfo screenwidth .]
- set gw 500
- set gh 300
- set x [expr $sw/2 - $gw/2]
- set y [expr $sh/2 - $gh/2]
- if {$x < 0} {
- set x 10
- }
- if {$y < 0} {
- set y 10
- }
-
- return "+$x+$y"
-}
-
-proc smbmnt_wait {tee} {
- if {$tee != ""} {
- set start [clock seconds]
- set cut 30
- while {1} {
- set now [clock seconds]
- if {$now > $start + $cut} {
- break;
- }
- if [file exists $tee] {
- set sz 0
- catch {set sz [file size $tee]}
- if {$sz > 50} {
- set cut 50
- }
- }
- set g ""
- catch {set g [exec grep main-vnc-helper-finished $tee]}
- if [regexp {main-vnc-helper-finished} $g] {
- break
- }
- after 1000
- }
- catch {file delete $tee}
- } else {
- global smb_su_mode
- if {$smb_su_mode == "su"} {
- after 15000
- } elseif {$smb_su_mode == "sudo"} {
- after 10000
- }
- }
-}
-
-proc do_unix_pre {tag proxy hp pk_hp} {
- global env smb_redir_0 use_smbmnt
- global did_port_knock
-
- set setup_cmds [ugly_setup_scripts pre $tag]
- set c "ss_vncviewer -ssh"
-
- if {$proxy == ""} {
- set pxy $hp
- regsub {:[0-9][0-9]*$} $pxy "" pxy
- set c "$c -proxy '$pxy'"
- } else {
- set c "$c -proxy '$proxy'"
- }
-
- if {$setup_cmds != ""} {
- set env(SS_VNCVIEWER_SSH_CMD) "$setup_cmds sleep 10"
- set env(SS_VNCVIEWER_SSH_ONLY) 1
- if {$smb_redir_0 != ""} {
- set c "$c -sshargs '$smb_redir_0'"
- }
-
- if {! [do_port_knock $pk_hp start]} {
- return
- }
- set did_port_knock 1
-
- if {$use_smbmnt} {
- set title "SSL/SSH VNC Viewer $hp -- SMB MOUNTS"
- } else {
- set title "SSL/SSH VNC Viewer $hp -- Pre Commands"
- }
-
- set tee ""
- if {$use_smbmnt} {
- set tee $env(SSVNC_HOME)
- append tee "/.tee-etv$tag"
- set fh ""
- catch {set fh [open $tee "w"]}
- if {$fh == ""} {
- set tee ""
- } else {
- close $fh
- set c "$c | tee $tee"
- }
- }
-
- unix_terminal_cmd "80x25+100+100" "$title" "set -xv; $c" 1
-
- set env(SS_VNCVIEWER_SSH_CMD) ""
- set env(SS_VNCVIEWER_SSH_ONLY) ""
-
- if {$use_smbmnt} {
- smbmnt_wait $tee
- } else {
- after 2000
- }
- }
-}
-proc init_vncdisplay {} {
- global vncdisplay vncproxy remote_ssh_cmd
- set vncdisplay [string trim $vncdisplay]
-
- if {$vncdisplay == ""} {
- set vncproxy ""
- set remote_ssh_cmd ""
- return
- }
-
- set hpnew [get_ssh_hp $vncdisplay]
- set proxy [get_ssh_proxy $vncdisplay]
- set sshcmd [get_ssh_cmd $vncdisplay]
-
- set vncdisplay $hpnew
- set vncproxy $proxy
- set remote_ssh_cmd $sshcmd
-
- global ssh_only ts_only
- if {$sshcmd != "" || $ssh_only || $ts_only} {
- global use_ssl use_ssh use_sshssl
- set use_ssl 0
- if {! $use_ssh && ! $use_sshssl} {
- set use_ssh 1
- }
- }
- # ssl_ssh_adjust will be called.
-}
-
-proc get_vncdisplay {} {
- global vncdisplay vncproxy remote_ssh_cmd
- set vncdisplay [string trim $vncdisplay]
-
- set t $vncdisplay
- regsub {[ \t]*cmd=.*$} $t "" t
- set t [string trim $t]
-
- set str ""
- if [regexp {[ \t]} $t] {
- set str $t
- } else {
- if {$vncproxy != "" && $t == ""} {
- set str "--nohost-- $vncproxy"
- } else {
- set str "$t $vncproxy"
- }
- }
- if [regexp {cmd=.*$} $vncdisplay match] {
- if {$str == ""} {
- set str "--nohost--"
- }
- set str "$str $match"
- } else {
- if {$remote_ssh_cmd != ""} {
- if {$str == ""} {
- set str "--nohost--"
- }
- set str "$str cmd=$remote_ssh_cmd"
- }
- }
- set str [string trim $str]
- return $str
-}
-
-proc port_knock_only {hp {mode KNOCK}} {
- if {$hp == ""} {
- set hp [get_vncdisplay]
- if {$hp == ""} {
- mesg "No host port found"
- bell
- return
- }
- }
- set hpnew [get_ssh_hp $hp]
- set proxy [get_ssh_proxy $hp]
- set sshcmd [get_ssh_cmd $hp]
- set hp $hpnew
-
- set pk_hp ""
- if {$proxy != ""} {
- set pk_hp $proxy
- }
- if {$pk_hp == ""} {
- set pk_hp $hp
- }
- if {$mode == "KNOCK"} {
- do_port_knock $pk_hp start
- } elseif {$mode == "FINISH"} {
- do_port_knock $pk_hp finish
- }
-}
-
-proc direct_connect_msg {} {
- set msg ""
- global env
- globalize
- if {$use_sshssl} {
- append msg " - SSH + SSL tunnelling\n"
- } elseif {$use_ssh} {
- append msg " - SSH tunnelling\n"
- } else {
- append msg " - SSL tunnelling\n"
- }
- if [info exists env(SSVNC_NO_ENC_WARN)] {
- set msg ""
- }
- if {$use_smbmnt} {
- append msg " - SMB Mount Port Redirection\n"
- }
- if {$use_sound} {
- append msg " - ESD Sound Port Redirection\n"
- }
- if {$use_cups} {
- append msg " - CUPS Port Redirection\n"
- }
- if {$additional_port_redirs} {
- append msg " - Additional Port Redirections\n"
- }
- if {$mycert != "" || $svcert != "" || $crtdir != ""} {
- append msg " - SSL certificate authentication\n"
- }
- if {$msg != ""} {
- set msg "Direct connect via vnc://hostname\nThe following options will be disabled:\n\n$msg"
- raise .
- tk_messageBox -type ok -icon info -message $msg
- }
-}
-
-proc fetch_cert {save} {
- global env vncdisplay is_windows
- set hp [get_vncdisplay]
-
- global vencrypt_detected
- set vencrypt_detected ""
-
- global use_listen
- if {$use_listen} {
- if {$is_windows} {
- mesg "Fetch Cert not enabled for Reverse Connections"
- bell
- catch {raise .}
- mac_raise
- return
- }
- toplev .fcr
- global help_font
- wm title .fcr "Fetch Cert for Reverse Connections"
- global fcr_result
- set fcr_result 0
- eval text .fcr.t -width 55 -height 17 $help_font
- .fcr.t insert end {
- In Reverse VNC Connections (-LISTEN) mode, the
- Fetch Cert operation requires that the Remote
- VNC Server makes an initial connection NOW so
- we can collect its SSL Certificate. Note that
- this method does not work for VeNCrypt servers.
- (If there are problems Fetching, one can always
- copy and import the Cert file manually.)
-
- Do you want to Continue with this operation?
- If so, press "Continue" and Then instruct the
- remote VNC Server to make a Reverse Connection
- to us.
-
- Otherwise, press "Cancel" to cancel the Fetch
- Cert operation.
-}
-
- button .fcr.cancel -text Cancel -command {set fcr_result 0; destroy .fcr}
- button .fcr.continue -text Continue -command {set fcr_result 1; destroy .fcr}
- button .fcr.continu2 -text Continue -command {set fcr_result 1; destroy .fcr}
- global uname
- if {$uname == "Darwin"} {
- pack .fcr.t .fcr.continu2 .fcr.continue .fcr.cancel -side top -fill x
-
- } else {
- pack .fcr.t .fcr.continue .fcr.cancel -side top -fill x
- }
- center_win .fcr
-
- tkwait window .fcr
- update
- after 50
-
- if {$fcr_result != 1} {
- return
- }
- update idletasks
- after 50
- }
-
- regsub {[ ]*cmd=.*$} $hp "" tt
- if {[regexp {^[ ]*$} $tt]} {
- mesg "No host:disp supplied."
- bell
- catch {raise .}
- mac_raise
- return
- }
- if {[regexp -- {--nohost--} $tt]} {
- mesg "No host:disp supplied."
- bell
- catch {raise .}
- mac_raise
- return
- }
- if {! [regexp ":" $hp]} {
- if {! [regexp {cmd=} $hp]} {
- append hp ":0"
- }
- }
- set hpnew [get_ssh_hp $hp]
- set proxy [get_ssh_proxy $hp]
-
-
- set pstr 1
- mesg "Fetching $hpnew Cert..."
- global cert_text
- set cert_text ""
- .f4.getcert configure -state disabled
- update
- if {! $is_windows} {
- catch {set cert_text [fetch_cert_unix $hp]}
- } else {
- set cert_text [fetch_cert_windows $hp]
- }
-
- if [info exists env(CERTDBG)] {puts "\nFetch-0-\n$cert_text"}
-
- set vencrypt 0
- set anondh 0
- if {![regexp {BEGIN CERTIFICATE} $cert_text]} {
- if [regexp {CONNECTED} $cert_text] {
- set m 0
- if {![regexp -nocase {GET_SERVER_HELLO} $cert_text]} {
- set m 1
- }
- if [regexp -nocase -line {GET_SERVER_HELLO.*unknown protocol} $cert_text] {
- set m 1
- }
- if {![regexp -nocase {show_cert: SSL_connect failed} $cert_text]} {
- set m 1
- }
- if {!$m && $is_windows} {
- if [regexp -nocase {write:errno} $cert_text] {
- if [regexp -nocase {no peer certificate} $cert_text] {
- set m 1
- }
- }
- }
- if {$m} {
- # suspect VeNCrypt or ANONTLS plaintext RFB
- set cert_text ""
- set vencrypt 1
- incr pstr
- mesg "#${pstr} Fetching $hpnew Cert... $vencrypt/$anondh"
- if {! $is_windows} {
- catch {set cert_text [fetch_cert_unix $hp $vencrypt $anondh]}
- } else {
- after 600
- catch {set cert_text [fetch_cert_windows $hp $vencrypt $anondh]}
- }
- if [info exists env(CERTDBG)] {puts "\nFetch-1-\n$cert_text"}
- }
- }
- }
- if {![regexp {BEGIN CERTIFICATE} $cert_text]} {
- if [regexp {CONNECTED} $cert_text] {
- set m 0
- if [regexp -nocase -line {error.*handshake failure} $cert_text] {
- set m 1
- }
- if [regexp -nocase -line {error.*unknown protocol} $cert_text] {
- set m 1
- }
- if {![regexp -nocase {show_cert: SSL_connect failed} $cert_text]} {
- set m 1
- }
- if {!$m && $is_windows} {
- if [regexp -nocase {no peer certificate} $cert_text] {
- set m 1
- }
- }
- if {$m} {
- # suspect Anonymous Diffie Hellman
- set cert_text ""
- set anondh 1
- incr pstr
- mesg "#${pstr} Fetching $hpnew Cert... $vencrypt/$anondh"
- if {! $is_windows} {
- catch {set cert_text [fetch_cert_unix $hp $vencrypt $anondh]}
- } else {
- after 600
- catch {set cert_text [fetch_cert_windows $hp $vencrypt $anondh]}
- }
- if [info exists env(CERTDBG)] {puts "\nFetch-2-\n$cert_text"}
- }
- }
- }
- if {![regexp {BEGIN CERTIFICATE} $cert_text]} {
- if [regexp {CONNECTED} $cert_text] {
- if {[regexp -nocase -line {cipher.*ADH} $cert_text]} {
- # it is Anonymous Diffie Hellman
- mesg "WARNING: Anonymous Diffie Hellman Server detected (NO CERT)"
- after 300
- .f4.getcert configure -state normal
- return $cert_text
- } else {
- global vencrypt_detected
- set vencrypt_detected ""
- }
- }
- }
-
- global vencrypt_detected server_vencrypt
- if {$vencrypt_detected != "" && !$server_vencrypt} {
- mesg "VeNCrypt or ANONTLS server detected."
- after 600
- }
-
- .f4.getcert configure -state normal
- mesg "Fetched $hpnew Cert"
-
- set n 47
- set ok 1
- if {$cert_text == ""} {
- set cert_text "An Error occurred in fetching SSL Certificate from $hp"
- set ok 0
- set n 4
- } elseif {! [regexp {BEGIN CERTIFICATE} $cert_text]} {
- set cert_text "An Error occurred in fetching $hp\n\n$cert_text"
- set n [line_count $cert_text 1]
- set ok 0
- } else {
- if [regexp -- {-----BEGIN SSL SESSION PARAMETERS-----} $cert_text] {
- set new ""
- set off 0
- foreach line [split $cert_text "\n"] {
- if [regexp -- {RFB 00} $line] {
- continue
- }
- if [regexp -- {Using default temp} $line] {
- continue
- }
- if [regexp -- {-----BEGIN SSL SESSION PARAMETERS-----} $line] {
- set off 1
- }
- if [regexp -- {-----END SSL SESSION PARAMETERS-----} $line] {
- set off 0
- continue
- }
- if {$off} {
- continue;
- }
- append new "$line\n"
- }
- if [regexp -- {-----BEGIN CERTIFICATE-----} $new] {
- set cert_text $new
- }
- }
- set text ""
- set on 0
- set subject ""
- set curr_subject ""
- set chain_n -1
- set chain(__empty__) ""
- foreach line [split $cert_text "\n"] {
- if [regexp -- {-----BEGIN CERTIFICATE-----} $line] {
- incr on
- }
- if {$chain_n < -1} {
- ;
- } elseif [regexp {^ *([0-9]) *s:(.*/[A-Z][A-Z]*=.*$)} $line m cn sb] {
- set cn [string trim $cn]
- set sb [string trim $sb]
- #puts cn=$cn
- #puts sb=$sb
- if {$subject == ""} {
- set subject $sb
- }
- if {$cn > $chain_n} {
- set chain_n $cn
- set curr_subject $sb
- } else {
- set chain_n -2
- }
- } elseif [regexp {^ *i:(.*/[A-Z][A-Z]*=.*$)} $line m is] {
- set is [string trim $is]
- #puts is=$is
- if {$curr_subject != ""} {
- set chain($curr_subject) $is
- }
- }
- if {$on != 1} {
- continue;
- }
- append text "$line\n"
- if [regexp -- {-----END CERTIFICATE-----} $line] {
- set on 2
- }
- }
- set chain_str "subject: not-known\n"
- set curr_subject $subject
- set self_signed 0
- set top_issuer ""
- for {set i 0} {$i < 10} {incr i} {
- if {$curr_subject != ""} {
- if {$i == 0} {
- set chain_str "- subject: $curr_subject\n\n"
- } else {
- set chain_str "${chain_str}- issuer$i: $curr_subject\n\n"
- set top_issuer $curr_subject;
- }
- if {![info exists chain($curr_subject)]} {
- break
- } elseif {$chain($curr_subject) == ""} {
- break
- } elseif {$curr_subject == $chain($curr_subject)} {
- set j [expr $i + 1]
- set chain_str "${chain_str}- issuer$j: $curr_subject\n\n"
- set top_issuer $curr_subject;
- if {$i == 0} {
- set self_signed 1
- }
- break;
- }
- set curr_subject $chain($curr_subject)
- }
- }
- set chain_str "${chain_str}INFO: SELF_SIGNED=$self_signed\n\n"
- if {$self_signed} {
- set chain_str "${chain_str}INFO: Certificate is Self-Signed.\n"
- set chain_str "${chain_str}INFO: It will successfully authenticate when used as a ServerCert or Accepted-Cert.\n"
- set chain_str "${chain_str}INFO: Be sure to check carefully that you trust this certificate before saving it.\n"
- } else {
- set chain_str "${chain_str}INFO: Certificate is signed by a Certificate Authority (CA).\n"
- set chain_str "${chain_str}INFO: It *WILL NOT* successfully authenticate when used as a ServerCert or Accepted-Cert.\n"
- set chain_str "${chain_str}INFO: You need to Obtain and Save the CA's Certificate (issuer) instead"
- if {$top_issuer != ""} {
- set chain_str "${chain_str}:\nINFO: CA: $top_issuer\n"
- } else {
- set chain_str "${chain_str}.\n"
- }
- }
- #puts "\n$chain_str\n"
-
- global is_windows
- set tmp "/tmp/cert.hsh.[tpid]"
- set tmp [mytmp $tmp]
- if {$is_windows} {
- # VF
- set tmp cert.hsh
- }
- set fh ""
- catch {set fh [open $tmp "w"]}
- if {$fh != ""} {
- puts $fh $text
- close $fh
- set info ""
- catch {set info [get_x509_info $tmp]}
- catch {file delete $tmp}
- if [regexp -nocase {MD5 Finger[^\n]*} $info mvar] {
- set cert_text "$mvar\n\n$cert_text"
- }
- if [regexp -nocase {SHA. Finger[^\n]*} $info mvar] {
- set cert_text "$mvar\n\n$cert_text"
- }
- set cert_text "$cert_text\n\n----------------------------------\nOutput of openssl x509 -text -fingerprint:\n\n$info"
- }
- set cert_text "==== SSL Certificate from $hp ====\n\n$chain_str\n$cert_text"
- }
-
- if {! $save} {
- return $cert_text
- }
-
- fetch_dialog $cert_text $hp $hpnew $ok $n
-}
-
-proc skip_non_self_signed {w hp} {
- set msg "Certificate from $hp is not Self-Signed, it was signed by a Certificate Authority (CA). Saving it does not make sense because it cannot be used to authenticate anything. You need to Obtain and Save the CA Certificate instead. Save it anyway?"
- set reply [tk_messageBox -type okcancel -default cancel -parent $w -icon warning -message $msg -title "CA Signed Certificate"]
- if {$reply == "cancel"} {
- return 1
- } else {
- return 0
- }
-}
-
-proc fetch_dialog {cert_text hp hpnew ok n} {
- toplev .fetch
-
- if [small_height] {
- set n 28
- }
-
- scroll_text_dismiss .fetch.f 90 $n
-
- if {$ok} {
- set ss 0
- if [regexp {INFO: SELF_SIGNED=1} $cert_text] {
- button .fetch.save -text Save -command "destroy .fetch; save_cert {$hpnew}"
- set ss 1
- } else {
- button .fetch.save -text Save -command "if \[skip_non_self_signed .fetch {$hpnew}\] {return} else {destroy .fetch; save_cert {$hpnew}}"
- set ss 0
- }
- button .fetch.help -text Help -command "help_fetch_cert $ss"
- pack .fetch.help .fetch.save -side bottom -fill x
- .fetch.d configure -text "Cancel"
- }
-
- center_win .fetch
- wm title .fetch "$hp Certificate"
-
- .fetch.f.t insert end $cert_text
- jiggle_text .fetch.f.t
-}
-
-
-proc host_part {hp} {
- regsub {^ *} $hp "" hp
- regsub { .*$} $hp "" hp
- if [regexp {^[0-9][0-9]*$} $hp] {
- return ""
- }
- set h $hp
- regsub {:[0-9][0-9]*$} $hp "" h
- return $h
-}
-
-proc port_part {hp} {
- regsub { .*$} $hp "" hp
- set p ""
- if [regexp {:([0-9][0-9]*)$} $hp m val] {
- set p $val
- }
- return $p
-}
-
-proc get_vencrypt_proxy {hpnew} {
- if [regexp -nocase {^vnc://} $hpnew] {
- return ""
- }
- set hpnew [get_ssh_hp $hpnew]
- regsub -nocase {^[a-z0-9+]*://} $hpnew "" hpnew
- set h [host_part $hpnew]
- set p [port_part $hpnew]
-
- if {$p == ""} {
- # might not matter, i.e. SSH+SSL only...
- set p 5900
- }
- set hp2 $h
- if {$p < 0} {
- set hp2 "$hp2:[expr - $p]"
- } elseif {$p < 200} {
- set hp2 "$hp2:[expr $p + 5900]"
- } else {
- set hp2 "$hp2:$p"
- }
- return "vencrypt://$hp2"
-}
-
-proc fetch_cert_unix {hp {vencrypt 0} {anondh 0}} {
- global use_listen
-
- set hpnew [get_ssh_hp $hp]
- set proxy [get_ssh_proxy $hp]
-
- if {$vencrypt} {
- global vencrypt_detected
- set vencrypt_detected [get_vencrypt_proxy $hpnew]
- if {$proxy != ""} {
- set proxy "$proxy,$vencrypt_detected"
- } else {
- set proxy $vencrypt_detected
- }
- }
-
- set cmd [list ss_vncviewer]
- if {$anondh} {
- lappend cmd "-anondh"
- }
- if {$proxy != ""} {
- lappend cmd "-proxy"
- lappend cmd $proxy
- }
- if {$use_listen} {
- lappend cmd "-listen"
- }
- lappend cmd "-showcert"
- lappend cmd $hpnew
-
- if {$proxy != ""} {
- lappend cmd "2>/dev/null"
- }
- global env
- if [info exists env(CERTDBG)] {puts "\nFetch-cmd: $cmd"}
- set env(SSVNC_SHOWCERT_EXIT_0) 1
-
- return [eval exec $cmd]
-}
-
-proc win_nslookup {host} {
- global win_nslookup_cache
- if [info exists win_nslookup_cache($host)] {
- return $win_nslookup_cache($host)
- }
- if [regexp -nocase {[^a-z0-9:._-]} $host] {
- set win_nslookup_cache($host) "invalid"
- return $win_nslookup_cache($host)
- }
- if [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $host] {
- set win_nslookup_cache($host) $host
- return $win_nslookup_cache($host)
- }
- if [regexp -nocase {^[a-f0-9]*:[a-f0-9:]*:[a-f0-9:]*$} $host] {
- set win_nslookup_cache($host) $host
- return $win_nslookup_cache($host)
- }
- set nsout ""
- catch {set nsout [exec nslookup $host]}
- if {$nsout == "" || [regexp -nocase {server failed} $nsout]} {
- after 250
- set nsout ""
- catch {set nsout [exec nslookup $host]}
- }
- if {$nsout == "" || [regexp -nocase {server failed} $nsout]} {
- set win_nslookup_cache($host) "unknown"
- return $win_nslookup_cache($host)
- }
- regsub -all {Server:[^\n]*\nAddress:[^\n]*} $nsout "" nsout
- regsub {^.*Name:} $nsout "" nsout
- if [regexp {Address:[ \t]*([^\n]+)} $nsout mv addr] {
- set addr [string trim $addr]
- if {$addr != ""} {
- set win_nslookup_cache($host) $addr
- return $win_nslookup_cache($host)
- }
- }
- set win_nslookup_cache($host) "unknown"
- return $win_nslookup_cache($host)
-}
-
-proc win_ipv4 {host} {
- global win_localhost
- set ip [win_nslookup $host];
- if [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $ip] {
- return 1
- }
- return 0
-}
-
-proc ipv6_proxy {proxy host port} {
- global is_windows win_localhost have_ipv6
-
- if {!$have_ipv6} {
- return [list $proxy $host $port ""]
- } elseif {!$is_windows} {
- return [list $proxy $host $port ""]
- } else {
- set h0 ""
- set p0 ""
- set port3 ""
- set ipv6_pid ""
- set proxy0 $proxy
- if {$proxy == ""} {
- if [win_ipv4 $host] {
- return [list $proxy $host $port ""]
- }
- set port3 [rand_port]
- set h0 $host
- set p0 $port
- set host $win_localhost
- set port $port3
- } else {
- set parts [split $proxy ","]
- set n [llength $parts]
- for {set i 0} {$i < $n} {incr i} {
- set part [lindex $parts $i]
- set prefix ""
- set repeater 0
- regexp -nocase {^[a-z0-9+]*://} $part prefix
- regsub -nocase {^[a-z0-9+]*://} $part "" part
- if [regexp {^repeater://} $prefix] {
- regsub {\+.*$} $part "" part
- if {![regexp {:([0-9][0-9]*)$} $part]} {
- set part "$part:5900"
- }
- }
- set modit 0
- set h1 ""
- set p1 ""
- if [regexp {^(.*):([0-9][0-9]*)$} $part mvar h1 p1] {
- if {$h1 == "localhost" || $h1 == $win_localhost} {
- continue
- } elseif [win_ipv4 $h1] {
- break
- }
- set modit 1
- } else {
- break
- }
- if {$modit} {
- set port3 [rand_port]
- set h0 $h1
- set p0 $p1
- lset parts $i "$prefix$win_localhost:$port3"
- break
- }
- }
- if {$h0 != "" && $p0 != "" && $port3 != ""} {
- set proxy [join $parts ","]
- #mesg "Reset proxy: $proxy"; after 3000
- }
- }
- if {$h0 != "" && $p0 != "" && $port3 != ""} {
- mesg "Starting IPV6 helper on port $port3 ..."
- set ipv6_pid [exec relay6.exe $port3 "$h0" "$p0" /b:$win_localhost &]
- after 400
- #mesg "r6 $port3 $h0 $p0"; after 3000
- }
- return [list $proxy $host $port $ipv6_pid]
- }
-}
-
-proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} {
- global have_ipv6
-
- regsub {^vnc.*://} $hp "" hp
-
- set hpnew [get_ssh_hp $hp]
- set proxy [get_ssh_proxy $hp]
-
- if {$vencrypt} {
- global vencrypt_detected
- set vencrypt_detected [get_vencrypt_proxy $hpnew]
- if {$proxy != ""} {
- set proxy "$proxy,$vencrypt_detected"
- } else {
- set proxy $vencrypt_detected
- }
- }
-
- set host [host_part $hpnew]
-
- global win_localhost
-
- if {$host == ""} {
- set host $win_localhost
- }
-
- if [regexp {^.*@} $host match] {
- mesg "Trimming \"$match\" from hostname"
- regsub {^.*@} $host "" host
- }
-
- set disp [port_part $hpnew]
-
- if {[regexp {^-[0-9][0-9]*$} $disp]} {
- ;
- } elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} {
- set disp 0
- }
- if {$disp < 0} {
- set port [expr "- $disp"]
- } elseif {$disp < 200} {
- set port [expr "$disp + 5900"]
- } else {
- set port $disp
- }
-
- set ipv6_pid ""
- if {$have_ipv6} {
- set res [ipv6_proxy $proxy $host $port]
- set proxy [lindex $res 0]
- set host [lindex $res 1]
- set port [lindex $res 2]
- set ipv6_pid [lindex $res 3]
- }
-
- if {$proxy != ""} {
- global env
-
- set port2 [rand_port]
-
- set sp ""
- if [info exists env(SSVNC_PROXY)] {
- set sp $env(SSVNC_PROXY)
- }
- set sl ""
- if [info exists env(SSVNC_LISTEN)] {
- set sl $env(SSVNC_LISTEN)
- }
- set sd ""
- if [info exists env(SSVNC_DEST)] {
- set sd $env(SSVNC_DEST)
- }
-
- set env(SSVNC_PROXY) $proxy
- set env(SSVNC_LISTEN) $port2
- set env(SSVNC_DEST) "$host:$port"
-
- set host $win_localhost
- set port $port2
-
- mesg "Starting Proxy TCP helper on port $port2 ..."
- after 300
- # fetch cert br case:
- set proxy_pid [exec "connect_br.exe" &]
-
- if {$sp == ""} {
- catch { unset env(SSVNC_PROXY) }
- } else {
- set env(SSVNC_PROXY) $sp
- }
- if {$sl == ""} {
- catch { unset env(SSVNC_LISTEN) }
- } else {
- set env(SSVNC_LISTEN) $sl
- }
- if {$sd == ""} {
- catch { unset env(SSVNC_DEST) }
- } else {
- set env(SSVNC_DEST) $sd
- }
- }
-
- set ossl [get_openssl]
- update
- # VF
- set tin tmpin.txt
- set tou tmpout.txt
- set fh ""
- catch {set fh [open $tin "w"]}
- if {$fh != ""} {
- puts $fh "Q"
- puts $fh "GET /WOMBAT HTTP/1.1\r\nHost: wombat.com\r\n\r\n\r\n"
- close $fh
- }
-
- if {1} {
- set ph ""
- if {$anondh} {
- set ph [open "| $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH < $tin 2>NUL" "r"]
- } else {
- set ph [open "| $ossl s_client -prexit -connect $host:$port < $tin 2>NUL" "r"]
- }
-
- set text ""
- if {$ph != ""} {
- set pids [pid $ph]
- set got 0
- while {[gets $ph line] > -1} {
- append text "$line\n"
- if [regexp {END CERT} $line] {
- set got 1
- }
- if {$anondh && [regexp -nocase {cipher.*ADH} $line]} {
- set got 1
- }
- if {$got && [regexp {^ *Verify return code} $line]} {
- break
- }
- if [regexp {^RFB } $line] {
- break
- }
- if [regexp {^DONE} $line] {
- break
- }
- }
- foreach pid $pids {
- winkill $pid
- }
- if {$ipv6_pid != ""} {
- winkill $ipv6_pid
- }
-
- catch {close $ph}
- catch {file delete $tin $tou}
- return $text
- }
- } else {
- set pids ""
-
- if {1} {
- if {$anondh} {
- set ph2 [open "| $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH > $tou 2>NUL" "w"]
- } else {
- set ph2 [open "| $ossl s_client -prexit -connect $host:$port > $tou 2>NUL" "w"]
- }
- set pids [pid $ph2]
- after 500
- for {set i 0} {$i < 128} {incr i} {
- puts $ph2 "Q"
- }
- catch {close $ph2}
- } else {
- if {$anondh} {
- set pids [exec $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH < $tin >& $tou &]
- } else {
- set pids [exec $ossl s_client -prexit -connect $host:$port < $tin >& $tou &]
- }
- }
-
- for {set i 0} {$i < 10} {incr i} {
- after 500
- set got 0
- set ph ""
- catch {set ph [open $tou "r"]}
- if {$ph != ""} {
- while {[gets $ph line] > -1} {
- if [regexp {END CERT} $line] {
- set got 1
- break
- }
- }
- close $ph
- }
- if {$got} {
- break
- }
- }
- foreach pid $pids {
- winkill $pid
- }
- after 500
- set ph ""
- catch {set ph [open $tou "r"]}
- }
- set text ""
- if {$ph != ""} {
- while {[gets $ph line] > -1} {
- append text "$line\n"
- }
- close $ph
- }
- catch {file delete $tin $tou}
- if {$ipv6_pid != ""} {
- winkill $ipv6_pid
- }
- return $text
-}
-
-proc check_accepted_certs {{probe_only 0}} {
- global cert_text always_verify_ssl
- global skip_verify_accepted_certs use_listen
- global ultra_dsm env
- global server_vencrypt server_anondh no_probe_vencrypt
-
- if {! $always_verify_ssl} {
- set skip_verify_accepted_certs 1
- if {$server_vencrypt} {
- return 1
- }
- if {$no_probe_vencrypt} {
- return 1
- }
- }
- if {$server_anondh} {
- mesg "WARNING: Anonymous Diffie Hellman (SKIPPING CERT CHECK)"
- after 1000
- set skip_verify_accepted_certs 1
- return 1
- }
- if {$ultra_dsm} {
- return 1;
- }
- if {$use_listen} {
- return 1;
- }
-
- global anon_dh_detected
- set anon_dh_detected 0
-
- set cert_text [fetch_cert 0]
-
- set mvar ""
- if {[regexp -nocase -line {cipher.*ADH} $cert_text mvar]} {
-
- if [info exists env(CERTDBG)] {puts "\nFetch-MSG-\n$cert_text"}
- if [info exists env(CERTDBG)] {puts "\nBEGIN_MVAR: $mvar\nEND_MVAR\n"}
-
- set msg "Anonymous Diffie-Hellman server detected. There will be encryption, but no SSL/TLS authentication. Continue?"
- set reply [tk_messageBox -type okcancel -default ok -icon warning -message $msg -title "Anonymous Diffie-Hellman Detected"]
- set anon_dh_detected 1
- if {$reply == "cancel"} {
- return 0
- } else {
- global skip_verify_accepted_certs
- set skip_verify_accepted_certs 1
- return 1
- }
- }
-
- if {$probe_only} {
- return 1
- }
- if {! $always_verify_ssl} {
- return 1
- }
-
- set from ""
- set fingerprint ""
- set fingerline ""
- set self_signed 1
- set subject_issuer ""
- set subject ""
- set issuer ""
-
- set i 0
- foreach line [split $cert_text "\n"] {
- incr i
- if {$i > 50} {
- break
- }
- if [regexp {^- subject: *(.*)$} $line m val] {
- set val [string trim $val]
- set subject_issuer "${subject_issuer}subject:$val\n"
- set subject $val
- }
- if [regexp {^- (issuer[0-9][0-9]*): *(.*)$} $line m is val] {
- set val [string trim $val]
- set subject_issuer "${subject_issuer}$is:$val\n"
- set issuer $val
- }
- if [regexp {^INFO: SELF_SIGNED=(.*)$} $line m val] {
- set subject_issuer "${subject_issuer}SELF_SIGNED:$val\n"
- }
- if [regexp {^depth=} $line] {
- break
- }
- if [regexp {^verify } $line] {
- break
- }
- if [regexp {^CONNECTED} $line] {
- break
- }
- if [regexp {^Certificate chain} $line] {
- break
- }
- if [regexp {^==== SSL Certificate from (.*) ====} $line mv str] {
- set from [string trim $str]
- }
- if [regexp -nocase {Fingerprint=(.*)} $line mv str] {
- set fingerline $line
- set fingerprint [string trim $str]
- }
- if [regexp -nocase {^INFO: SELF_SIGNED=([01])} $line mv str] {
- set self_signed $str
- }
- }
-
- set fingerprint [string tolower $fingerprint]
- regsub -all {:} $fingerprint "-" fingerprint
- regsub -all {[\\/=]} $fingerprint "_" fingerprint
-
- set from [string tolower $from]
- regsub -all {[\[\]]} $from "" from
- regsub -all {^[+a-z]*://} $from "" from
- regsub -all {:} $from "-" from
- regsub -all {[\\/=]} $from "_" from
- regsub -all {[ ]} $from "_" from
-
- if {$from == "" || $fingerprint == ""} {
- bell
- catch {raise .; update}
- mesg "WARNING: Error fetching Server Cert"
- after 500
- set hp [get_vncdisplay]
- set n [line_count $cert_text 1]
- fetch_dialog $cert_text $hp $hp 0 $n
- update
- after 2000
- return 0
- }
-
- set hp [get_vncdisplay]
-
- set adir [get_idir_certs ""]
- catch {file mkdir $adir}
- set adir "$adir/accepted"
- catch {file mkdir $adir}
-
- set crt "$adir/$from=$fingerprint.crt"
-
- if [file exists $crt] {
- if {$self_signed} {
- mesg "OK: Certificate found in ACCEPTED_CERTS"
- after 750
- return 1
- }
- }
-
- set cnt 0
- foreach f [glob -nocomplain -directory $adir "*$fingerprint*.crt"] {
- mesg "CERT: $f"
- after 150
- if {$self_signed} {
- incr cnt
- }
- }
-
- set oth 0
- set others [list]
- foreach f [glob -nocomplain -directory $adir "*$from*.crt"] {
- if {$f == $crt} {
- continue
- }
- set fb [file tail $f]
- mesg "OTHER CERT: $fb"
- if {$cnt > 0} {
- after 400
- } else {
- bell
- after 800
- }
- lappend others $f
- incr oth
- }
-
- foreach f [glob -nocomplain -directory $adir "*.crt"] {
- if {$f == $crt} {
- continue
- }
- set saw 0
- foreach o $others {
- if {$f == $o} {
- set saw 1
- break
- }
- }
- if {$saw} {
- continue
- }
- set fh [open $f "r"]
- if {$fh == ""} {
- continue
- }
- set same 0
- set sub ""
- set iss ""
- set isn -1;
- while {[gets $fh line] > -1} {
- if [regexp {^Host-Display: (.*)$} $line mv hd] {
- if {$hd == $hp || $hd == $from} {
- set same 1
- }
- }
- if [regexp {^subject:(.*)$} $line mv val] {
- set sub $val
- }
- if [regexp {^issue([0-9][0-9]*):(.*)$} $line mv in val] {
- if {$in > $isn} {
- set isn $in
- set iss $val
- }
- }
- }
- close $fh;
-
- if {!$self_signed} {
- if {$sub == ""} {
- set ossl [get_openssl]
- set si_txt [exec $ossl x509 -subject -issuer -noout -in $f]
- foreach line [split $si_txt "\n"] {
- if [regexp -nocase {^subject= *(.*)$} $line mv str] {
- set str [string trim $str]
- if {$str != ""} {
- set sub $str
- }
- } elseif [regexp -nocase {^issuer= *(.*)$} $line mv str] {
- set str [string trim $str]
- if {$iss != ""} {
- set iss $str
- }
- }
- }
- }
- if {$issuer != "" && $sub != ""} {
- global env
- if [info exists env(CERTDBG)] {
- puts "f: $f"
- puts "s: $sub"
- puts "i: $issuer"
- puts "==================="
- }
- if {$issuer == $sub} {
- set fb [file tail $f]
- mesg "Certificate Authority (CA) CERT: $fb"
- incr cnt
- after 500
- }
- }
- continue
- }
-
- if {! $same} {
- continue
- }
-
- set fb [file tail $f]
- mesg "OTHER CERT: $fb"
- if {$cnt > 0} {
- after 400
- } else {
- bell
- after 800
- }
- lappend others $f
- incr oth
- }
-
- if {$cnt > 0} {
- if {$self_signed} {
- mesg "OK: Server Certificate found in ACCEPTED_CERTS"
- after 400
- } else {
- mesg "OK: CA Certificate found in ACCEPTED_CERTS"
- after 800
- }
- return 1
- }
-
- set hp2 [get_vncdisplay]
- set msg "
- The Self-Signed SSL Certificate from host:
-
- $hp2
-
- Fingerprint: $fingerprint
-
- Subject: $subject
-
- is not present in the 'Accepted Certs' directory:
-
- $adir
-%WARN
- You will need to verify on your own that this is a certificate from a
- VNC server that you trust (e.g. by checking the fingerprint with that
- sent to you by the server administrator).
-
-
- THE QUESTION: Do you want this certificate to be saved in the Accepted Certs
- directory and then used to SSL authenticate VNC servers?
-
-
- By clicking 'Inspect and maybe Save Cert' you will be given the opportunity
- to inspect the certificate before deciding to save it or not.
-"
-
- set msg_bottom "
- Choose 'Ignore Cert for One Connection' to connect a single time to the
- server with *NO* certificate authentication. You will see this dialog again
- the next time you connect to the same server.
-
- Choose 'Continue as though I saved it' to launch stunnel and the VNC viewer.
- Do this if you know the correct Certificate is in the 'Accepted Certs'
- directory. If it is not, stunnel will fail and report 'VERIFY ERROR:...'
-
- Choose 'Cancel' to not connect to the VNC Server at all.
-"
-
- set msg_ca "
- The CA-signed SSL Certificate from host:
-
- $hp2
-
- Fingerprint: $fingerprint
-
- Subject: $subject
-
- Issuer: $issuer
-
- is signed by a Certificate Authority (CA) (the 'Issuer' above.)
-
- However, the certificate of the CA 'Issuer' is not present in the
- 'Accepted Certs' directory:
-
- $adir
-
- You will need to obtain the certificate of the CA 'Issuer' via some means
- (perhaps ask the VNC server administrator for it.) Then, after you have
- verified that the CA certificate is one that you trust, import the
- certificate via Certs -> Import Certificate. Be sure to select to also
- save it to the Accepted Certs directory so it will automatically be used.
-"
- set msg "$msg$msg_bottom"
- set msg_ca "$msg_ca$msg_bottom"
-
- if {!$self_signed} {
- set msg $msg_ca
- }
-
- if {$oth == 0} {
- regsub {%WARN} $msg "" msg
- } else {
- set warn ""
- set wfp ""
- if {$oth == 1} {
- set warn "
-**WARNING** The Following Cert was previously saved FOR THE SAME HOST-DISPLAY:
-
-"
- set wfp "BUT WITH A DIFFERENT FINGERPRINT."
-
- } else {
- set warn "
-**WARNING** The Following Certs were previously saved FOR THE SAME HOST-DISPLAY:
-
-"
- set wfp "BUT WITH DIFFERENT FINGERPRINTS."
- }
-
- foreach o $others {
- set fb [file tail $o]
- set warn "$warn $fb\n"
- }
- set warn "$warn\n $wfp\n"
- set warn "$warn\n This could be a Man-In-The-Middle attack, or simply that the Server changed"
- set warn "$warn\n its Certificate. *PLEASE CHECK* before proceeding!\n"
- regsub {%WARN} $msg $warn msg
- bell
- }
-
- set n 0
- foreach l [split $msg "\n"] {
- incr n
- }
- if {!$self_signed} {
- set n [expr $n + 2]
- } else {
- set n [expr $n + 1]
- }
- if [small_height] {
- if {$n > 26} {
- set n 26
- }
- }
- toplev .acert
- scroll_text .acert.f 83 $n
-
- button .acert.inspect -text "Inspect and maybe Save Cert ..." -command "destroy .acert; set accept_cert_dialog 1"
- button .acert.accept -text "Ignore Cert for One Connection " -command "destroy .acert; set accept_cert_dialog 2"
- button .acert.continue -text "Continue as though I saved it " -command "destroy .acert; set accept_cert_dialog 3"
- button .acert.cancel -text "Cancel" -command "destroy .acert; set accept_cert_dialog 0"
-
- wm title .acert "Unrecognized SSL Cert!"
-
- .acert.f.t insert end $msg
-
- pack .acert.cancel .acert.continue .acert.accept .acert.inspect -side bottom -fill x
- pack .acert.f -side top -fill both -expand 1
-
- if {! $self_signed} {
- catch {.acert.inspect configure -state disabled}
- }
-
- center_win .acert
-
- global accept_cert_dialog
- set accept_cert_dialog ""
-
- jiggle_text .acert.f.t
-
- tkwait window .acert
-
- if {$accept_cert_dialog == 2} {
- set skip_verify_accepted_certs 1
- return 1
- }
- if {$accept_cert_dialog == 3} {
- return 1
- }
- if {$accept_cert_dialog != 1} {
- return 0
- }
-
- global accepted_cert_dialog_in_progress
- set accepted_cert_dialog_in_progress 1
-
- global fetch_cert_filename
- set fetch_cert_filename $crt
-
- global do_save_saved_it
- set do_save_saved_it 0
- global do_save_saved_hash_it
- set do_save_saved_hash_it 0
-
- fetch_dialog $cert_text $hp $hp 1 47
- update; after 150
-
- catch {tkwait window .fetch}
- update; after 250
- catch {tkwait window .scrt}
- update; after 250
- if [winfo exists .scrt] {
- catch {tkwait window .scrt}
- }
-
- set fetch_cert_filename ""
- set accepted_cert_dialog_in_progress 0
-
- if {!$do_save_saved_hash_it} {
- save_hash $crt $adir $hp $fingerline $from $fingerprint $subject_issuer
- }
-
- if {$do_save_saved_it} {
- return 1
- } else {
- return 0
- }
-}
-
-proc save_hash {crt adir hp fingerline from fingerprint {subject_issuer ""}} {
- if ![file exists $crt] {
- return
- }
- set ossl [get_openssl]
- set hash [exec $ossl x509 -hash -noout -in $crt]
- set hash [string trim $hash]
- if [regexp {^([0-9a-f][0-9a-f]*)} $hash mv h] {
- set hashfile "$adir/$h.0"
- set hn "$h.0"
- if [file exists $hashfile] {
- set hashfile "$adir/$h.1"
- set hn "$h.1"
- if [file exists $hashfile] {
- set hashfile "$adir/$h.2"
- set hn "$h.2"
- }
- }
- set fh [open $crt "a"]
- if {$fh != ""} {
- puts $fh ""
- puts $fh "SSVNC-info:"
- puts $fh "Host-Display: $hp"
- puts $fh "$fingerline"
- puts $fh "hash-filename: $hn"
- puts $fh "full-filename: $from=$fingerprint.crt"
- puts -nonewline $fh $subject_issuer
- close $fh
- }
- catch {file copy -force $crt $hashfile}
- if [file exists $hashfile] {
- return 1
- }
- }
-}
-
-proc tpid {} {
- global is_windows
- set p ""
-
- if {!$is_windows} {
- catch {set p [exec sh -c {echo $$}]}
- }
- if {$p == ""} {
- set p [pid];
- }
- append p [clock clicks]
- return $p
-}
-
-proc repeater_proxy_check {proxy} {
- if [regexp {^repeater://.*\+ID:[0-9]} $proxy] {
- global env rpc_m1 rpc_m2
- if {![info exists rpc_m1]} {
- set rpc_m1 0
- set rpc_m2 0
- }
- set force 0
- if [info exists env(REPEATER_FORCE)] {
- if {$env(REPEATER_FORCE) != "" && $env(REPEATER_FORCE) != "0"} {
- # no longer makes a difference.
- set force 1
- }
- }
- global use_listen ultra_dsm
- if {! $use_listen} {
- if {$ultra_dsm} {
- return 1;
- } else {
- if {0} {
- mesg "WARNING: repeater:// ID:nnn proxy might need Listen Mode"
- incr rpc_m1
- if {$rpc_m1 <= 2} {
- after 1000
- } else {
- after 200
- }
- }
- if {0} {
- # no longer required by x11vnc (X11VNC_DISABLE_SSL_CLIENT_MODE)
- bell
- mesg "ERROR: repeater:// ID:nnn proxy must use Listen Mode"
- after 1000
- return 0
- }
- }
- }
- global always_verify_ssl
- if [info exists always_verify_ssl] {
- if {$always_verify_ssl} {
- mesg "WARNING: repeater:// ID:nnn Verify All Certs may fail"
- incr rpc_m2
- if {$rpc_m2 == 1} {
- after 1500
- } elseif {$rpc_m2 == 2} {
- after 500
- } else {
- after 200
- }
- }
- }
- }
- return 1
-}
-
-proc fini_unixpw {} {
- global named_pipe_fh unixpw_tmp
-
- if {$named_pipe_fh != ""} {
- catch {close $named_pipe_fh}
- }
- if {$unixpw_tmp != ""} {
- catch {file delete $unixpw_tmp}
- }
-}
-
-proc init_unixpw {hp} {
- global use_unixpw unixpw_username unixpw_passwd
- global named_pipe_fh unixpw_tmp env
-
- set named_pipe_fh ""
- set unixpw_tmp ""
-
- if {$use_unixpw} {
- set name $unixpw_username
- set env(SSVNC_UNIXPW) ""
- if {$name == ""} {
- regsub {^.*://} $hp "" hp
- set hptmp [get_ssh_hp $hp]
- if [regexp {^(.*)@} $hptmp mv m1] {
- set name $m1
- }
- }
- if {$name == ""} {
- if [info exists env(USER)] {
- set name $env(USER)
- }
- }
- if {$name == ""} {
- if [info exists env(LOGNAME)] {
- set name $env(LOGNAME)
- }
- }
- if {$name == ""} {
- set name [exec whoami]
- }
- if {$name == ""} {
- set name "unknown"
- }
-
- set tmp "/tmp/unixpipe.[tpid]"
- set tmp [mytmp $tmp]
- # need to make it a pipe
- catch {file delete $tmp}
- if {[file exists $tmp]} {
- mesg "file still exists: $tmp"
- bell
- return
- }
-
- catch {exec mknod $tmp p}
- set fh ""
- if {! [file exists $tmp]} {
- catch {set fh [open $tmp "w"]}
- } else {
- catch {set fh [open $tmp "r+"]}
- set named_pipe_fh $fh
- }
- catch {exec chmod 600 $tmp}
- if {! [file exists $tmp]} {
- mesg "cannot create: $tmp"
- if {$named_pipe_fh != ""} {catch close $named_pipe_fh}
- bell
- return
- }
- #puts [exec ls -l $tmp]
- set unixpw_tmp $tmp
- puts $fh $name
- puts $fh $unixpw_passwd
- if {$named_pipe_fh != ""} {
- flush $fh
- } else {
- close $fh
- }
- exec sh -c "sleep 60; /bin/rm -f $tmp" &
- if {$unixpw_passwd == ""} {
- set env(SSVNC_UNIXPW) "."
- } else {
- set env(SSVNC_UNIXPW) "rm:$tmp"
- }
- } else {
- if [info exists env(SSVNC_UNIXPW)] {
- set env(SSVNC_UNIXPW) ""
- }
- }
-}
-
-proc check_for_listen_ssl_cert {} {
- global mycert use_listen use_ssh ultra_dsm
- if {! $use_listen} {
- return 1
- }
- if {$use_ssh} {
- return 1
- }
- if {$ultra_dsm} {
- return 1
- }
- if {$mycert != ""} {
- return 1
- }
-
- set name [get_idir_certs ""]
- set name "$name/listen.pem"
- if {[file exists $name]} {
- set mycert $name
- mesg "Using Listen Cert: $name"
- after 700
- return 1
- }
-
- set title "SSL Listen requires MyCert";
- set msg "In SSL Listen mode a cert+key is required, but you have not specified 'MyCert'.\n\nCreate a cert+key 'listen' now?"
- set reply [tk_messageBox -type okcancel -default ok -icon warning -message $msg -title $msg]
- if {$reply == "cancel"} {
- return 0
- }
- create_cert $name
- tkwait window .ccrt
- if {[file exists $name]} {
- set mycert $name
- mesg "Using Listen Cert: $name"
- after 700
- return 1
- }
- return 0
-}
-
-proc listen_verify_all_dialog {hp} {
- global use_listen always_verify_ssl
- global did_listen_verify_all_dialog
- global svcert
- global sshssl_sw ultra_dsm
-
- if {!$use_listen} {
- return 1
- }
- if {!$always_verify_ssl} {
- return 1
- }
- if {$svcert != ""} {
- return 1
- }
- if {$ultra_dsm} {
- return 1
- }
- if [regexp -nocase {^vnc://} $hp] {
- return 1
- }
- if [info exists sshssl_sw] {
- if {$sshssl_sw == "none"} {
- return 1
- }
- if {$sshssl_sw == "ssh"} {
- return 1
- }
- }
- if [info exists did_listen_verify_all_dialog] {
- return 1
- }
-
- toplev .lvd
- global help_font
- wm title .lvd "Verify All Certs for Reverse Connections"
- eval text .lvd.t -width 55 -height 22 $help_font
- .lvd.t insert end {
- Information:
-
- You have the 'Verify All Certs' option enabled
- in Reverse VNC Connections (-LISTEN) mode.
-
- For this to work, you must have ALREADY saved
- the remote VNC Server's Certificate to the
- 'Accepted Certs' directory. Otherwise the
- incoming Reverse connection will be rejected.
-
- You can save the Server's Certificate by using
- the 'Import Certificate' dialog or on Unix
- and MacOSX by pressing 'Fetch Cert' and then
- have the Server make an initial connection.
-
- If you do not want to save the certificate of
- the VNC Server making the Reverse connection,
- you must disable 'Verify All Certs' (note that
- this means the server authenticity will not be
- checked.)
-}
-
- button .lvd.ok -text OK -command {destroy .lvd}
- button .lvd.ok2 -text OK -command {destroy .lvd}
- button .lvd.disable -text "Disable 'Verify All Certs'" -command {set always_verify_ssl 0; destroy .lvd}
- global uname
- if {$uname == "Darwin"} {
- pack .lvd.t .lvd.ok2 .lvd.disable .lvd.ok -side top -fill x
- } else {
- pack .lvd.t .lvd.disable .lvd.ok -side top -fill x
- }
- center_win .lvd
- update
-
- tkwait window .lvd
- update
- after 50
- update
-
- set did_listen_verify_all_dialog 1
- return 1
-}
-
-proc reset_stunnel_extra_opts {} {
- global stunnel_extra_opts0 stunnel_extra_svc_opts0 env
- global ssvnc_multiple_listen0
- if {$stunnel_extra_opts0 != "none"} {
- set env(STUNNEL_EXTRA_OPTS) $stunnel_extra_opts0
- }
- if {$stunnel_extra_svc_opts0 != "none"} {
- set env(STUNNEL_EXTRA_SVC_OPTS) $stunnel_extra_svc_opts0
- }
- set env(SSVNC_LIM_ACCEPT_PRELOAD) ""
- if {$ssvnc_multiple_listen0 != "none"} {
- set env(SSVNC_MULTIPLE_LISTEN) $ssvnc_multiple_listen0
- }
- set env(SSVNC_ULTRA_DSM) ""
- set env(SSVNC_TURBOVNC) ""
- catch { unset env(VNCVIEWER_NO_PIPELINE_UPDATES) }
- catch { unset env(VNCVIEWER_NOTTY) }
- catch { unset env(SSVNC_ACCEPT_POPUP) }
- catch { unset env(SSVNC_ACCEPT_POPUP_SC) }
- catch { unset env(SSVNC_KNOWN_HOSTS_FILE) }
-}
-
-proc maybe_add_vencrypt {proxy hp} {
- global vencrypt_detected server_vencrypt
- set vpd ""
- if {$vencrypt_detected != ""} {
- set vpd $vencrypt_detected
- set vencrypt_detected ""
- } elseif {$server_vencrypt} {
- set vpd [get_vencrypt_proxy $hp]
- }
- if {$vpd != ""} {
- mesg "vencrypt proxy: $vpd"
- if {$proxy != ""} {
- set proxy "$proxy,$vpd"
- } else {
- set proxy "$vpd"
- }
- }
- return $proxy
-}
-
-proc no_certs_tutorial_mesg {} {
- global svcert crtdir
- global server_anondh
- global always_verify_ssl
-
- set doit 0
- if {!$always_verify_ssl} {
- if {$svcert == ""} {
- if {$crtdir == "" || $crtdir == "ACCEPTED_CERTS"} {
- set doit 1
- }
- }
- } elseif {$server_anondh} {
- set doit 1
- }
- if {$doit} {
- mesg "INFO: without Certificate checking man-in-the-middle attack is possible."
- } else {
- set str ""
- catch {set str [.l cget -text]}
- if {$str != "" && [regexp {^INFO: without Certificate} $str]} {
- mesg ""
- }
- }
-}
-
-proc vencrypt_tutorial_mesg {} {
- global use_ssh use_sshssl use_listen
- global server_vencrypt no_probe_vencrypt
- global ultra_dsm
-
- set m ""
- if {$use_ssh} {
- ;
- } elseif {$server_vencrypt} {
- ;
- } elseif {$ultra_dsm} {
- ;
- } elseif {$use_listen} {
- set m "No VeNCrypt Auto-Detection: Listen mode."
- } elseif {$use_sshssl} {
- set m "No VeNCrypt Auto-Detection: SSH+SSL mode."
- } elseif {$no_probe_vencrypt} {
- set m "No VeNCrypt Auto-Detection: Disabled."
- }
- if {$m != ""} {
- mesg $m
- after 1000
- }
- return $m
-
- #global svcert always_verify_ssl
- #$svcert != "" || !$always_verify_ssl
- # set m "No VeNCrypt Auto-Detection: 'Verify All Certs' disabled"
-}
-
-proc launch_unix {hp} {
- global smb_redir_0 smb_mounts env
- global vncauth_passwd use_unixpw unixpw_username unixpw_passwd
- global ssh_only ts_only use_x11cursor use_nobell use_rawlocal use_notty use_popupfix ssvnc_scale ssvnc_escape
- global ssvnc_encodings ssvnc_extra_opts
-
- globalize
-
- set cmd ""
-
- if {[regexp {^vncssh://} $hp] || [regexp {^vnc\+ssh://} $hp]} {
- set use_ssl 0
- set use_ssh 1
- sync_use_ssl_ssh
- } elseif {[regexp {^vncs://} $hp] || [regexp {^vncssl://} $hp] || [regexp {^vnc\+ssl://} $hp]} {
- set use_ssl 1
- set use_ssh 0
- sync_use_ssl_ssh
- }
- if {[regexp {^rsh:/?/?} $hp]} {
- set use_ssl 0
- set use_ssh 1
- sync_use_ssl_ssh
- }
-
- check_ssh_needed
-
- set_smb_mounts
-
- global did_port_knock
- set did_port_knock 0
- set pk_hp ""
-
- set skip_ssh 0
- set do_direct 0
-
- if [regexp {vnc://} $hp] {
- set skip_ssh 1
- set do_direct 1
- if {! [info exists env(SSVNC_NO_ENC_WARN)]} {
- direct_connect_msg
- }
- }
-
- listen_verify_all_dialog $hp
-
- if {! $do_direct} {
- if {! [check_for_listen_ssl_cert]} {
- return
- }
- }
-
- global stunnel_extra_opts0 stunnel_extra_svc_opts0
- set stunnel_extra_opts0 ""
- set stunnel_extra_svc_opts0 ""
- global ssvnc_multiple_listen0
- set ssvnc_multiple_listen0 ""
-
- if {[regexp -nocase {sslrepeater://} $hp]} {
- if {$disable_ssl_workarounds} {
- set disable_ssl_workarounds 0
- mesg "Disabling SSL workarounds for 'UVNC Single Click III Bug'"
- after 400
- }
- }
-
- if [info exists env(STUNNEL_EXTRA_OPTS)] {
- set stunnel_extra_opts0 $env(STUNNEL_EXTRA_OPTS)
- if {$disable_ssl_workarounds} {
- if {$disable_ssl_workarounds_type == "none"} {
- ;
- } elseif {$disable_ssl_workarounds_type == "noempty"} {
- set env(STUNNEL_EXTRA_OPTS) "$env(STUNNEL_EXTRA_OPTS)\noptions = DONT_INSERT_EMPTY_FRAGMENTS"
- }
- } else {
- set env(STUNNEL_EXTRA_OPTS) "$env(STUNNEL_EXTRA_OPTS)\noptions = ALL"
- }
- } else {
- if {$disable_ssl_workarounds} {
- if {$disable_ssl_workarounds_type == "none"} {
- ;
- } elseif {$disable_ssl_workarounds_type == "noempty"} {
- set env(STUNNEL_EXTRA_OPTS) "options = DONT_INSERT_EMPTY_FRAGMENTS"
- }
- } else {
- set env(STUNNEL_EXTRA_OPTS) "options = ALL"
- }
- }
- if {$stunnel_local_protection && ! $use_listen} {
- if {$stunnel_local_protection_type == "ident"} {
- set user ""
- if {[info exists env(USER)]} {
- set user $env(USER)
- } elseif {[info exists env(LOGNAME)]} {
- set user $env(USER)
- }
- if {$user != ""} {
- if [info exists env(STUNNEL_EXTRA_SVC_OPTS)] {
- set stunnel_extra_svc_opts0 $env(STUNNEL_EXTRA_SVC_OPTS)
- set env(STUNNEL_EXTRA_SVC_OPTS) "$env(STUNNEL_EXTRA_SVC_OPTS)\nident = $user"
- } else {
- set env(STUNNEL_EXTRA_SVC_OPTS) "ident = $user"
- }
- }
- } elseif {$stunnel_local_protection_type == "exec"} {
- if [info exists env(STUNNEL_EXTRA_SVC_OPTS)] {
- set stunnel_extra_svc_opts0 $env(STUNNEL_EXTRA_SVC_OPTS)
- set env(STUNNEL_EXTRA_SVC_OPTS) "$env(STUNNEL_EXTRA_SVC_OPTS)\n#stunnel-exec"
- } else {
- set env(STUNNEL_EXTRA_SVC_OPTS) "#stunnel-exec"
- }
- }
- }
- if {$ultra_dsm} {
- if {$ultra_dsm_type == "securevnc"} {
- ;
- } elseif {![file exists $ultra_dsm_file] && ![regexp {pw=} $ultra_dsm_file]} {
- mesg "DSM key file does exist: $ultra_dsm_file"
- bell
- after 1000
- return
- }
- global vncauth_passwd
- if {$ultra_dsm_file == "pw=VNCPASSWORD" || $ultra_dsm_file == "pw=VNCPASSWD"} {
- if {![info exists vncauth_passwd] || $vncauth_passwd == ""} {
- mesg "For DSM pw=VNCPASSWD you must supply the VNC Password"
- bell
- after 1000
- return
- }
- if [regexp {'} $vncauth_passwd] {
- mesg "For DSM pw=VNCPASSWD password must not contain single quotes."
- bell
- after 1000
- return
- }
- }
- set dsm "ultravnc_dsm_helper "
- if {$ultra_dsm_noultra} {
- append dsm "noultra:"
- }
- if {$use_listen} {
- append dsm "rev:"
- }
- if {$ultra_dsm_type == "guess"} {
- append dsm "."
- } else {
- append dsm $ultra_dsm_type
- }
- if {$ultra_dsm_noultra} {
- if {$ultra_dsm_salt != ""} {
- append dsm "@$ultra_dsm_salt"
- }
- }
- if {$ultra_dsm_file == "pw=VNCPASSWORD" || $ultra_dsm_file == "pw=VNCPASSWD"} {
- append dsm " pw='$vncauth_passwd'"
- } else {
- if {$ultra_dsm_file == "" && $ultra_dsm_type == "securevnc"} {
- append dsm " none"
- } else {
- append dsm " $ultra_dsm_file"
- }
- }
- set env(SSVNC_ULTRA_DSM) $dsm
- }
- if {$multiple_listen && $use_listen} {
- if [info exists env(SSVNC_MULTIPLE_LISTEN)] {
- set ssvnc_multiple_listen0 $env(SSVNC_MULTIPLE_LISTEN)
- }
- set env(SSVNC_MULTIPLE_LISTEN) "1"
- }
-
- if {$use_ssh} {
- ;
- } elseif {$use_sshssl} {
- ;
- } elseif {$use_ssl} {
- set prox [get_ssh_proxy $hp]
- if {$prox != "" && [regexp {@} $prox]} {
- mesg "Error: proxy contains '@' Did you mean to use SSH mode?"
- bell
- return
- }
- if [regexp {@} $hp] {
- mesg "Error: host contains '@' Did you mean to use SSH mode?"
- bell
- return
- }
- }
-
- if {$use_ssh || $use_sshssl} {
- if {$ssh_local_protection} {
- if {![info exists env(LIM_ACCEPT)]} {
- set env(LIM_ACCEPT) 1
- }
- if {![info exists env(LIM_ACCEPT_TIME)]} {
- set env(LIM_ACCEPT_TIME) 35
- }
- set env(SSVNC_LIM_ACCEPT_PRELOAD) "lim_accept.so"
- mesg "SSH LIM_ACCEPT($env(LIM_ACCEPT),$env(LIM_ACCEPT_TIME)): lim_accept.so"
- after 700
- }
- if {$skip_ssh || $ultra_dsm} {
- set cmd "ss_vncviewer"
- } elseif {$use_ssh} {
- set cmd "ss_vncviewer -ssh"
- } else {
- set cmd "ss_vncviewer -sshssl"
- if {$mycert != ""} {
- set cmd "$cmd -mycert '$mycert'"
- }
- if {$crlfil != ""} {
- set cmd "$cmd -crl '$crlfil'"
- }
- if {$svcert != ""} {
- set cmd "$cmd -verify '$svcert'"
- } elseif {$crtdir != "" && $crtdir != "ACCEPTED_CERTS"} {
- set cmd "$cmd -verify '$crtdir'"
- }
- }
- if {$use_listen} {
- set cmd "$cmd -listen"
- }
- if {$ssh_local_protection} {
- regsub {ss_vncviewer} $cmd "ssvnc_cmd" cmd
- }
- set hpnew [get_ssh_hp $hp]
- set proxy [get_ssh_proxy $hp]
- set sshcmd [get_ssh_cmd $hp]
-
- if {$use_sshssl} {
- if {!$do_direct} {
- set proxy [maybe_add_vencrypt $proxy $hp]
- }
- }
-
- if {$ts_only} {
- regsub {:0$} $hpnew "" hpnew
- if {$proxy == ""} {
- # XXX host_part
- if {[regexp {^([^:]*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} {
- set proxy "$sshhst:$sshpt"
- set hpnew "localhost"
- }
- } else {
- if {![regexp {,} $proxy]} {
- if {$hpnew != "localhost"} {
- set proxy "$proxy,$hpnew"
- set hpnew "localhost"
- }
- }
- }
- }
-
-#puts hp=$hp
-#puts hpn=$hpnew
-#puts pxy=$proxy
-#puts cmd=$sshcmd
-
- set hp $hpnew
-
- if {$proxy != ""} {
- set cmd "$cmd -proxy '$proxy'"
- set pk_hp $proxy
- }
- if {$pk_hp == ""} {
- set pk_hp $hp
- }
-
- set do_pre 0
- if {$use_smbmnt} {
- set do_pre 1
- } elseif {$use_sound && $sound_daemon_kill} {
- set do_pre 1
- }
- global skip_pre
- if {$skip_pre || $skip_ssh} {
- set do_pre 0
- set skip_pre 0
- }
-
- set tag [contag]
-
- if {$do_pre} {
- do_unix_pre $tag $proxy $hp $pk_hp
- }
-
-
- set setup_cmds [ugly_setup_scripts post $tag]
-
- if {$skip_ssh} {
- set setup_cmds ""
- }
- if {$sshcmd != "SHELL" && [regexp -nocase {x11vnc} $sshcmd]} {
- global use_cups cups_x11vnc cups_remote_port
- global cups_remote_smb_port
- global use_sound sound_daemon_x11vnc sound_daemon_remote_port
- global ts_only
- if {$ts_only} {
- set cups_x11vnc 1
- set sound_daemon_x11vnc 1
- }
- if {$use_cups && $cups_x11vnc && $cups_remote_port != ""} {
- set crp $cups_remote_port
- if {$ts_only} {
- set cups_remote_port [rand_port]
- set crp "DAEMON-$cups_remote_port"
- }
- set sshcmd "$sshcmd -env FD_CUPS=$crp"
- }
- if {$use_cups && $cups_x11vnc && $cups_remote_smb_port != ""} {
- set csp $cups_remote_smb_port
- if {$ts_only} {
- set cups_remote_smb_port [rand_port]
- set csp "DAEMON-$cups_remote_smb_port"
- }
- set sshcmd "$sshcmd -env FD_SMB=$csp"
- }
- if {$use_sound && $sound_daemon_x11vnc && $sound_daemon_remote_port != ""} {
- set srp $sound_daemon_remote_port
- if {$ts_only} {
- set sound_daemon_remote_port [rand_port]
- set srp "DAEMON-$sound_daemon_remote_port"
- }
- set sshcmd "$sshcmd -env FD_ESD=$srp"
- }
- }
-
- if {$sshcmd == "SHELL"} {
- set env(SS_VNCVIEWER_SSH_CMD) {$SHELL}
- set env(SS_VNCVIEWER_SSH_ONLY) 1
- } elseif {$setup_cmds != ""} {
- if {$sshcmd == ""} {
- set sshcmd "sleep 15"
- }
- set env(SS_VNCVIEWER_SSH_CMD) "$setup_cmds$sshcmd"
- } else {
- if {$sshcmd != ""} {
- set cmd "$cmd -sshcmd '$sshcmd'"
- }
- }
-
- set sshargs ""
- if {$use_cups} {
- append sshargs [get_cups_redir]
- }
- if {$use_sound} {
- append sshargs [get_sound_redir]
- }
- if {$additional_port_redirs} {
- append sshargs [get_additional_redir]
- }
-
- set sshargs [string trim $sshargs]
- if {$skip_ssh} {
- set sshargs ""
- }
- if {$sshargs != ""} {
- set cmd "$cmd -sshargs '$sshargs'"
- set env(SS_VNCVIEWER_USE_C) 1
- } else {
- # hmm we used to have it off... why?
- # ssh typing response?
- set env(SS_VNCVIEWER_USE_C) 1
- }
- if {$sshcmd == "SHELL"} {
- set env(SS_VNCVIEWER_SSH_ONLY) 1
- if {$proxy == ""} {
- set hpt $hpnew
- # XXX host_part
- regsub {:[0-9][0-9]*$} $hpt "" hpt
- set cmd "$cmd -proxy '$hpt'"
- }
- set geometry [xterm_center_geometry]
- if {$pk_hp == ""} {
- set pk_hp $hp
- }
- if {! $did_port_knock} {
- if {! [do_port_knock $pk_hp start]} {
- reset_stunnel_extra_opts
- return
- }
- set did_port_knock 1
- }
-
- if {[regexp {FINISH} $port_knocking_list]} {
- wm withdraw .
- update
- unix_terminal_cmd $geometry "SHELL to $hp" "$cmd"
- wm deiconify .
- update
- do_port_knock $pk_hp finish
- } else {
- unix_terminal_cmd $geometry "SHELL to $hp" "$cmd" 1
- }
- set env(SS_VNCVIEWER_SSH_CMD) ""
- set env(SS_VNCVIEWER_SSH_ONLY) ""
- set env(SS_VNCVIEWER_USE_C) ""
- reset_stunnel_extra_opts
- return
- }
- } else {
- set cmd "ssvnc_cmd"
- set hpnew [get_ssh_hp $hp]
- set proxy [get_ssh_proxy $hp]
-
- if {!$do_direct && ![repeater_proxy_check $proxy]} {
- reset_stunnel_extra_opts
- return
- }
-
- if {! $do_direct && ! $ultra_dsm && ![regexp -nocase {ssh://} $hpnew]} {
- set did_check 0
- if {$mycert != ""} {
- set cmd "$cmd -mycert '$mycert'"
- }
- if {$crlfil != ""} {
- set cmd "$cmd -crl '$crlfil'"
- }
- if {$svcert != ""} {
- set cmd "$cmd -verify '$svcert'"
- } elseif {$crtdir != ""} {
- if {$crtdir == "ACCEPTED_CERTS"} {
- global skip_verify_accepted_certs
- set skip_verify_accepted_certs 0
-
- set did_check 1
- if {! [check_accepted_certs 0]} {
- reset_stunnel_extra_opts
- return
- }
- if {! $skip_verify_accepted_certs} {
- set adir [get_idir_certs ""]
- set adir "$adir/accepted"
- catch {file mkdir $adir}
- set cmd "$cmd -verify '$adir'"
- }
-
- } else {
- set cmd "$cmd -verify '$crtdir'"
- }
- }
- if {! $did_check} {
- check_accepted_certs 1
- }
- }
-
- if {!$do_direct} {
- set proxy [maybe_add_vencrypt $proxy $hp]
- }
-
- if {$proxy != ""} {
- set cmd "$cmd -proxy '$proxy'"
- }
- set hp $hpnew
- if [regexp {^.*@} $hp match] {
- catch {raise .; update}
- mesg "Trimming \"$match\" from hostname"
- after 700
- regsub {^.*@} $hp "" hp
- }
- if [regexp {@} $proxy] {
- bell
- catch {raise .; update}
- mesg "WARNING: SSL proxy contains \"@\" sign"
- after 1500
- }
- }
-
- global anon_dh_detected
- if {$anon_dh_detected || $server_anondh} {
- if {!$do_direct} {
- set cmd "$cmd -anondh"
- }
- set anon_dh_detected 0
- }
- if {$use_alpha} {
- set cmd "$cmd -alpha"
- }
- if {$use_send_clipboard} {
- set cmd "$cmd -sendclipboard"
- }
- if {$use_send_always} {
- set cmd "$cmd -sendalways"
- }
- if {$use_turbovnc} {
- set env(SSVNC_TURBOVNC) 1
- }
- if {$disable_pipeline} {
- set env(VNCVIEWER_NO_PIPELINE_UPDATES) 1
- }
- if {$ssh_known_hosts_filename != ""} {
- set env(SSVNC_KNOWN_HOSTS_FILE) $ssh_known_hosts_filename
- }
- if {$use_grab} {
- set cmd "$cmd -grab"
- }
- if {$use_x11cursor} {
- set cmd "$cmd -x11cursor"
- }
- if {$use_nobell} {
- set cmd "$cmd -nobell"
- }
- if {$use_rawlocal} {
- set cmd "$cmd -rawlocal"
- }
- if {$use_notty} {
- set env(VNCVIEWER_NOTTY) 1
- }
- if {$use_popupfix} {
- set cmd "$cmd -popupfix"
- }
- if {$ssvnc_scale != ""} {
- set cmd "$cmd -scale '$ssvnc_scale'"
- }
- if {$ssvnc_escape != ""} {
- set cmd "$cmd -escape '$ssvnc_escape'"
- }
- if {$ssvnc_encodings != ""} {
- set cmd "$cmd -ssvnc_encodings '$ssvnc_encodings'"
- }
- if {$ssvnc_extra_opts != ""} {
- set cmd "$cmd -ssvnc_extra_opts '$ssvnc_extra_opts'"
- }
- if {$rfbversion != ""} {
- set cmd "$cmd -rfbversion '$rfbversion'"
- }
- if {$vncviewer_realvnc4} {
- set cmd "$cmd -realvnc4"
- }
- if {$use_listen} {
- set cmd "$cmd -listen"
- if {$listen_once} {
- set cmd "$cmd -onelisten"
- }
- if {$listen_accept_popup} {
- if {$listen_accept_popup_sc} {
- set env(SSVNC_ACCEPT_POPUP_SC) 1
- } else {
- set env(SSVNC_ACCEPT_POPUP) 1
- }
- }
- }
-
- global darwin_cotvnc
- if {$darwin_cotvnc} {
- set env(DARWIN_COTVNC) 1
- } else {
- if [info exists env(DISPLAY)] {
- if {$env(DISPLAY) != ""} {
- set env(DARWIN_COTVNC) 0
- } else {
- set env(DARWIN_COTVNC) 1
- }
- } else {
- set env(DARWIN_COTVNC) 1
- }
- }
-
- set do_vncspacewrapper 0
- if {$change_vncviewer && $change_vncviewer_path != ""} {
- set path [string trim $change_vncviewer_path]
- if [regexp {^["'].} $path] { # "
- set tmp "/tmp/vncspacewrapper.[tpid]"
- set tmp [mytmp $tmp]
- set do_vncspacewrapper 1
- if {0} {
- catch {file delete $tmp}
- if {[file exists $tmp]} {
- catch {destroy .c}
- mesg "file still exists: $tmp"
- bell
- reset_stunnel_extra_opts
- return
- }
- }
- catch {set fh [open $tmp "w"]}
- catch {exec chmod 700 $tmp}
- if {! [file exists $tmp]} {
- catch {destroy .c}
- mesg "cannot create: $tmp"
- bell
- reset_stunnel_extra_opts
- return
- }
- puts $fh "#!/bin/sh"
- puts $fh "echo $tmp; set -xv"
- puts $fh "$path \"\$@\""
- puts $fh "sleep 1; rm -f $tmp"
- close $fh
- set path $tmp
- }
- set env(VNCVIEWERCMD) $path
- } else {
- if [info exists env(VNCVIEWERCMD_OVERRIDE)] {
- set env(VNCVIEWERCMD) $env(VNCVIEWERCMD_OVERRIDE)
- } else {
- set env(VNCVIEWERCMD) ""
- }
- }
-
- set realvnc4 $vncviewer_realvnc4
- set realvnc3 0
- set flavor ""
- if {! $darwin_cotvnc} {
- set done 0
- if {$do_vncspacewrapper} {
- if [regexp -nocase {ultra} $change_vncviewer_path] {
- set done 1
- set flavor "ultravnc"
- } elseif [regexp -nocase {chicken.of} $change_vncviewer_path] {
- set done 1
- set flavor "cotvnc"
- }
- }
- if {! $done} {
- catch {set flavor [exec ss_vncviewer -viewerflavor 2>/dev/null]}
- }
- }
- if [regexp {realvnc4} $flavor] {
- set realvnc4 1
- }
- if [regexp {tightvnc} $flavor] {
- set realvnc4 0
- }
- if [regexp {realvnc3} $flavor] {
- set realvnc4 0
- set realvnc3 1
- }
- if {$realvnc4} {
- set cmd "$cmd -realvnc4"
- }
-
- set cmd "$cmd $hp"
-
- set passwdfile ""
- if {$vncauth_passwd != ""} {
- global use_listen
- set footest [mytmp /tmp/.check.[tpid]]
- catch {file delete $footest}
- global mktemp
- set passwdfile "/tmp/.vncauth_tmp.[tpid]"
- if {$mktemp == ""} {
- set passwdfile "$env(SSVNC_HOME)/.vncauth_tmp.[tpid]"
- }
-
- set passwdfile [mytmp $passwdfile]
- catch {exec vncstorepw $vncauth_passwd $passwdfile}
- catch {exec chmod 600 $passwdfile}
- if {$use_listen} {
- global env
- set env(SS_VNCVIEWER_RM) $passwdfile
- } else {
- if {$darwin_cotvnc} {
- catch {exec sh -c "sleep 60; rm $passwdfile 2>/dev/null" &}
- } else {
- catch {exec sh -c "sleep 20; rm $passwdfile 2>/dev/null" &}
- }
- }
- if {$darwin_cotvnc} {
- set cmd "$cmd --PasswordFile $passwdfile"
- } elseif {$flavor == "unknown"} {
- ;
- } else {
- set cmd "$cmd -passwd $passwdfile"
- }
- }
-
- if {$use_viewonly} {
- if {$darwin_cotvnc} {
- set cmd "$cmd --ViewOnly"
- } elseif {$flavor == "unknown"} {
- ;
- } elseif {$flavor == "ultravnc"} {
- set cmd "$cmd /viewonly"
- } else {
- set cmd "$cmd -viewonly"
- }
- }
- if {$use_fullscreen} {
- if {$darwin_cotvnc} {
- set cmd "$cmd --FullScreen"
- } elseif {$flavor == "ultravnc"} {
- set cmd "$cmd /fullscreen"
- } elseif {$flavor == "unknown"} {
- if [regexp {vinagre} $change_vncviewer_path] {
- set cmd "$cmd -f"
- }
- } else {
- set cmd "$cmd -fullscreen"
- }
- }
- if {$use_bgr233} {
- if {$realvnc4} {
- set cmd "$cmd -lowcolourlevel 1"
- } elseif {$flavor == "ultravnc"} {
- set cmd "$cmd /8bit"
- } elseif {$flavor == "ultravnc"} {
- ;
- } elseif {$flavor == "unknown"} {
- ;
- } else {
- set cmd "$cmd -bgr233"
- }
- }
- if {$use_nojpeg} {
- if {$darwin_cotvnc} {
- ;
- } elseif {$flavor == "ultravnc"} {
- ;
- } elseif {$flavor == "unknown"} {
- ;
- } elseif {! $realvnc4 && ! $realvnc3} {
- set cmd "$cmd -nojpeg"
- }
- }
- if {! $use_raise_on_beep} {
- if {$darwin_cotvnc} {
- ;
- } elseif {$flavor == "ultravnc"} {
- ;
- } elseif {$flavor == "unknown"} {
- ;
- } elseif {! $realvnc4 && ! $realvnc3} {
- set cmd "$cmd -noraiseonbeep"
- }
- }
- if {$use_compresslevel != "" && $use_compresslevel != "default"} {
- if {$realvnc3} {
- ;
- } elseif {$flavor == "ultravnc"} {
- ;
- } elseif {$flavor == "unknown"} {
- ;
- } elseif {$realvnc4} {
- set cmd "$cmd -zliblevel '$use_compresslevel'"
- } else {
- set cmd "$cmd -compresslevel '$use_compresslevel'"
- }
- }
- if {$use_quality != "" && $use_quality != "default"} {
- if {$darwin_cotvnc} {
- ;
- } elseif {$flavor == "ultravnc"} {
- ;
- } elseif {$flavor == "unknown"} {
- ;
- } elseif {! $realvnc4 && ! $realvnc3} {
- set cmd "$cmd -quality '$use_quality'"
- }
- }
- if {$use_ssh || $use_sshssl} {
- # realvnc4 -preferredencoding zrle
- if {$darwin_cotvnc} {
- ;
- } elseif {$flavor == "ultravnc"} {
- ;
- } elseif {$flavor == "unknown"} {
- ;
- } elseif {$realvnc4} {
- set cmd "$cmd -preferredencoding zrle"
- } else {
- set cmd "$cmd -encodings 'copyrect tight zrle zlib hextile'"
- }
- }
-
- global ycrop_string
- global sbwid_string
- catch {unset env(VNCVIEWER_SBWIDTH)}
- catch {unset env(VNCVIEWER_YCROP)}
- if {[info exists ycrop_string] && $ycrop_string != ""} {
- set t $ycrop_string
- if [regexp {,sb=([0-9][0-9]*)} $t m mv1] {
- set env(VNCVIEWER_SBWIDTH) $mv1
- }
- regsub {,sb=([0-9][0-9]*)} $t "" t
- if {$t != ""} {
- set env(VNCVIEWER_YCROP) $t
- }
- }
- if {[info exists sbwid_string] && $sbwid_string != ""} {
- set t $sbwid_string
- set env(VNCVIEWER_SBWIDTH) $sbwid_string
- if {$t != ""} {
- set env(VNCVIEWER_SBWIDTH) $t
- }
- }
-
- catch {destroy .o}
- catch {destroy .oa}
- catch {destroy .os}
- update
-
- if {$use_sound && $sound_daemon_local_start && $sound_daemon_local_cmd != ""} {
- mesg "running: $sound_daemon_local_cmd"
- global sound_daemon_local_pid
- set sound_daemon_local_pid ""
- #exec sh -c "$sound_daemon_local_cmd " >& /dev/null </dev/null &
- set sound_daemon_local_pid [exec sh -c "echo \$\$; exec $sound_daemon_local_cmd </dev/null 1>/dev/null 2>/dev/null &"]
- update
- after 500
- }
-
- if {$pk_hp == ""} {
- set pk_hp $hp
- }
- if {! $did_port_knock} {
- if {! [do_port_knock $pk_hp start]} {
- wm deiconify .
- update
- reset_stunnel_extra_opts
- return
- }
- set did_port_knock 1
- }
-
- init_unixpw $hp
-
- if {! $do_direct} {
- vencrypt_tutorial_mesg
- }
-
- wm withdraw .
- update
-
- set geometry [xterm_center_geometry]
- set xrm1 "*.srinterCommand:true"
- set xrm2 $xrm1
- set xrm3 $xrm1
- if {[info exists env(SSVNC_GUI_CMD)]} {
- set xrm1 "*.printerCommand:env XTERM_PRINT=1 $env(SSVNC_GUI_CMD)"
- set xrm2 "XTerm*VT100*translations:#override Shift<Btn3Down>:print()\\nCtrl<Key>N:print()"
- set xrm3 "*mainMenu*print*Label: New SSVNC_GUI"
- }
- set m "Done. You Can X-out or Ctrl-C this Terminal if you like. Use Ctrl-\\\\ to pause."
- global uname
- if {$uname == "Darwin"} {
- regsub {X-out or } $m "" m
- }
- set te "set -xv; "
- if {$ts_only} {
- set te ""
- }
-
- global extra_sleep
- set ssvnc_extra_sleep_save ""
- if {$extra_sleep != ""} {
- if [info exists env(SSVNC_EXTRA_SLEEP)] {
- set ssvnc_extra_sleep_save $env(SSVNC_EXTRA_SLEEP)
- }
- set env(SSVNC_EXTRA_SLEEP) $extra_sleep
- }
-
- set sstx "SSL/SSH VNC Viewer"
- set hptx $hp
- global use_listen
- if {$use_listen} {
- set sstx "SSVNC"
- set hptx "$hp (Press Ctrl-C to Stop Listening)"
- }
-
-
- set s1 5
- set s2 4
- if [info exists env(SSVNC_FINISH_SLEEP)] {
- set s1 $env(SSVNC_FINISH_SLEEP);
- set s2 $s1
- }
-
- unix_terminal_cmd $geometry "$sstx $hptx" \
- "$te$cmd; set +xv; ulimit -c 0; trap 'printf \"Paused. Press Enter to exit:\"; read x' QUIT; echo; echo $m; echo; echo sleep $s1; echo; sleep $s2" 0 $xrm1 $xrm2 $xrm3
-
- set env(SS_VNCVIEWER_SSH_CMD) ""
- set env(SS_VNCVIEWER_USE_C) ""
-
- if {$extra_sleep != ""} {
- if {$ssvnc_extra_sleep_save != ""} {
- set env(SSVNC_EXTRA_SLEEP) $ssvnc_extra_sleep_save
- } else {
- catch {unset env(SSVNC_EXTRA_SLEEP)}
- }
- }
-
- if {$use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} {
- # XXX need to kill just one...
- set daemon [string trim $sound_daemon_local_cmd]
- regsub {^gw[ \t]*} $daemon "" daemon
- regsub {[ \t].*$} $daemon "" daemon
- regsub {^.*/} $daemon "" daemon
- mesg "killing sound daemon: $daemon"
- global sound_daemon_local_pid
- if {$sound_daemon_local_pid != ""} {
-#puts pid=$sound_daemon_local_pid
- catch {exec sh -c "kill $sound_daemon_local_pid" >/dev/null 2>/dev/null </dev/null &}
- incr sound_daemon_local_pid
- catch {exec sh -c "kill $sound_daemon_local_pid" >/dev/null 2>/dev/null </dev/null &}
- set sound_daemon_local_pid ""
- } elseif {$daemon != ""} {
- catch {exec sh -c "killall $daemon" >/dev/null 2>/dev/null </dev/null &}
- catch {exec sh -c "pkill -x $daemon" >/dev/null 2>/dev/null </dev/null &}
- }
- }
- if {$passwdfile != ""} {
- catch {file delete $passwdfile}
- }
- wm deiconify .
- mac_raise
- mesg "Disconnected from $hp"
- if {[regexp {FINISH} $port_knocking_list]} {
- do_port_knock $pk_hp finish
- }
-
- reset_stunnel_extra_opts
-
- fini_unixpw
-}
-
-proc kill_stunnel {pids} {
- set count 0
- foreach pid $pids {
- mesg "killing STUNNEL pid: $pid"
- winkill $pid
- if {$count == 0} {
- after 600
- } else {
- after 300
- }
- incr count
- }
-}
-
-proc get_task_list {} {
- global is_win9x
-
- set output1 ""
- set output2 ""
- if {! $is_win9x} {
- # try for tasklist on XP pro
- catch {set output1 [exec tasklist.exe]}
- }
- catch {set output2 [exec w98/tlist.exe]}
-
- set output $output1
- append output "\n"
- append output $output2
-
- return $output
-}
-
-proc note_stunnel_pids {when} {
- global is_win9x pids_before pids_after pids_new
-
- if {$when == "before"} {
- array unset pids_before
- array unset pids_after
- set pids_new {}
- set pids_before(none) "none"
- set pids_after(none) "none"
- }
-
- set output [get_task_list]
-
- foreach line [split $output "\n\r"] {
- set m 0
- if [regexp -nocase {stunnel} $line] {
- set m 1
- } elseif [regexp -nocase {connect_br} $line] {
- set m 1
- }
- if {$m} {
- if [regexp {(-?[0-9][0-9]*)} $line m p] {
- if {$when == "before"} {
- set pids_before($p) $line
- } else {
- set pids_after($p) $line
- }
- }
- }
- }
- if {$when == "after"} {
- foreach new [array names pids_after] {
- if {! [info exists pids_before($new)]} {
- lappend pids_new $new
- }
- }
- }
-}
-
-proc del_launch_windows_ssh_files {} {
- global launch_windows_ssh_files
- global env
-
- if {[info exists env(SSVNC_NO_DELETE)]} {
- return
- }
-
- if {$launch_windows_ssh_files != ""} {
- foreach tf [split $launch_windows_ssh_files] {
- if {$tf == ""} {
- continue
- }
- catch {file delete $tf}
- }
- }
-}
-
-proc launch_shell_only {} {
- global is_windows
- global skip_pre
- global use_ssl use_ssh use_sshssl
-
- set hp [get_vncdisplay]
- regsub {cmd=.*$} $hp "" hp
- set hp [string trim $hp]
- if {$is_windows} {
- append hp " cmd=PUTTY"
- } else {
- append hp " cmd=SHELL"
- }
- set use_ssl_save $use_ssl
- set use_ssh_save $use_ssh
- set use_sshssl_save $use_sshssl
- set skip_pre 1
- if {! $use_ssh && ! $use_sshssl} {
- set use_ssh 1
- set use_ssl 1
- }
- launch $hp
-
- set use_ssl $use_ssl_save
- set use_ssh $use_ssh_save
- set use_sshssl $use_sshssl_save
-}
-
-proc to_sshonly {} {
- global ssh_only ts_only env
- global showing_no_encryption
- #if {$showing_no_encryption} {
- # toggle_no_encryption
- #}
- if {$ssh_only && !$ts_only} {
- return
- }
- if {[info exists env(SSVNC_TS_ALWAYS)]} {
- return
- }
- set ssh_only 1
- set ts_only 0
-
- set t "SSH VNC Viewer"
- wm title . $t
- catch {pack forget .f4}
- catch {pack forget .b.certs}
- catch {.l configure -text $t}
-
- global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd
- set vncdisplay ""
- set vncauth_passwd ""
- set unixpw_username ""
- set vncproxy ""
- set remote_ssh_cmd ""
-
- set_defaults
-}
-
-proc toggle_tsonly {} {
- global ts_only env
- if {$ts_only} {
- if {![info exists env(SSVNC_TS_ALWAYS)]} {
- to_ssvnc
- }
- } else {
- to_tsonly
- }
-}
-
-proc toggle_sshonly {} {
- global ssh_only env
- if {$ssh_only} {
- to_ssvnc
- } else {
- to_sshonly
- }
-}
-
-proc to_tsonly {} {
- global ts_only
- global showing_no_encryption
- #if {$showing_no_encryption} {
- # toggle_no_encryption
- #}
- if {$ts_only} {
- return
- }
- set ts_only 1
- set ssh_only 1
-
- set t "Terminal Services VNC Viewer"
- wm title . $t
- catch {pack forget .f4}
- catch {pack forget .f3}
- catch {pack forget .f1}
- catch {pack forget .b.certs}
- catch {.l configure -text $t}
- catch {.f0.l configure -text "VNC Terminal Server:"}
-
- global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd
- set vncdisplay ""
- set vncauth_passwd ""
- set unixpw_username ""
- set vncproxy ""
- set remote_ssh_cmd ""
-
- set_defaults
-}
-
-proc to_ssvnc {} {
- global ts_only ssh_only env
-
- if {!$ts_only && !$ssh_only} {
- return;
- }
- if {[info exists env(SSVNC_TS_ALWAYS)]} {
- return
- }
- set ts_only 0
- set ssh_only 0
-
- set t "SSL/SSH VNC Viewer"
- wm title . $t
- catch {pack configure .f1 -after .f0 -side top -fill x}
- catch {pack configure .f3 -after .f2 -side top -fill x}
- catch {pack configure .f4 -after .f3 -side top -fill x}
- catch {pack configure .b.certs -before .b.opts -side left -expand 1 -fill x}
- catch {.l configure -text $t}
- catch {.f0.l configure -text "VNC Host:Display"}
-
- #global started_with_noenc
- #if {$started_with_noenc} {
- # toggle_no_encryption
- #}
-
- global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd
- set vncdisplay ""
- set vncauth_passwd ""
- set unixpw_username ""
- set vncproxy ""
- set remote_ssh_cmd ""
-
- set_defaults
-}
-
-proc launch {{hp ""}} {
- global tcl_platform is_windows
- global mycert svcert crtdir crlfil
- global pids_before pids_after pids_new
- global env
- global use_ssl use_ssh use_sshssl sshssl_sw use_listen disable_ssl_workarounds
- global vncdisplay
-
- set debug 0
- if {$hp == ""} {
- set hp [get_vncdisplay]
- }
-
- set hpt [string trim $hp]
- regsub {[ ].*$} $hpt "" hpt
-
-
- if {[regexp {^HOME=} $hpt] || [regexp {^SSVNC_HOME=} $hpt]} {
- set t $hpt
- regsub {^.*HOME=} $t "" t
- set t [string trim $t]
- set env(SSVNC_HOME) $t
- mesg "Set SSVNC_HOME to $t"
- set vncdisplay ""
- return 0
- }
- if {[regexp {^DISPLAY=} $hpt] || [regexp {^SSVNC_DISPLAY=} $hpt]} {
- set t $hpt
- regsub {^.*DISPLAY=} $t "" t
- set t [string trim $t]
- set env(DISPLAY) $t
- mesg "Set DISPLAY to $t"
- set vncdisplay ""
- global uname darwin_cotvnc
- if {$uname == "Darwin"} {
- if {$t != ""} {
- set darwin_cotvnc 0
- } else {
- set darwin_cotvnc 1
- }
- }
- return 0
- }
- if {[regexp {^DYLD_LIBRARY_PATH=} $hpt] || [regexp {^SSVNC_DYLD_LIBRARY_PATH=} $hpt]} {
- set t $hpt
- regsub {^.*DYLD_LIBRARY_PATH=} $t "" t
- set t [string trim $t]
- set env(DYLD_LIBRARY_PATH) $t
- set env(SSVNC_DYLD_LIBRARY_PATH) $t
- mesg "Set DYLD_LIBRARY_PATH to $t"
- set vncdisplay ""
- return 0
- }
- if {[regexp {^SLEEP=} $hpt] || [regexp {^SSVNC_EXTRA_SLEEP=} $hpt]} {
- set t $hpt
- regsub {^.*SLEEP=} $t "" t
- set t [string trim $t]
- set env(SSVNC_EXTRA_SLEEP) $t
- mesg "Set SSVNC_EXTRA_SLEEP to $t"
- set vncdisplay ""
- return 0
- }
- if {[regexp {^SSH=} $hpt]} {
- set t $hpt
- regsub {^.*SSH=} $t "" t
- set t [string trim $t]
- set env(SSH) $t
- mesg "Set SSH to $t"
- set vncdisplay ""
- return 0
- }
- if {[regexp {^FINISH=} $hpt] || [regexp {^SSVNC_FINISH_SLEEP=} $hpt]} {
- set t $hpt
- regsub {^.*=} $t "" t
- set t [string trim $t]
- set env(SSVNC_FINISH_SLEEP) $t
- mesg "Set SSVNC_FINISH_SLEEP to $t"
- set vncdisplay ""
- return 0
- }
- if {[regexp {^NO_DELETE=} $hpt] || [regexp {^SSVNC_NO_DELETE=} $hpt]} {
- set t $hpt
- regsub {^.*=} $t "" t
- set t [string trim $t]
- set env(SSVNC_NO_DELETE) $t
- mesg "Set SSVNC_NO_DELETE to $t"
- set vncdisplay ""
- return 0
- }
- if {[regexp {^BAT_SLEEP=} $hpt] || [regexp {^SSVNC_BAT_SLEEP=} $hpt]} {
- set t $hpt
- regsub {^.*=} $t "" t
- set t [string trim $t]
- set env(SSVNC_BAT_SLEEP) $t
- mesg "Set SSVNC_BAT_SLEEP to $t"
- set vncdisplay ""
- return 0
- }
- if {[regexp {^DEBUG_NETSTAT=} $hpt]} {
- set t $hpt
- regsub {^.*DEBUG_NETSTAT=} $t "" t
- global debug_netstat
- set debug_netstat $t
- mesg "Set DEBUG_NETSTAT to $t"
- set vncdisplay ""
- return 0
- }
- if {[regexp {^REPEATER_FORCE=} $hpt]} {
- set t $hpt
- regsub {^.*REPEATER_FORCE=} $t "" t
- set env(REPEATER_FORCE) $t
- mesg "Set REPEATER_FORCE to $t"
- set vncdisplay ""
- return 0
- }
- if {[regexp -nocase {^SSH.?ONLY} $hpt]} {
- global ssh_only
- if {$ssh_only} {
- return 0;
- }
- to_sshonly
-
- return 0
- }
- if {[regexp -nocase {^TS.?ONLY} $hpt]} {
- global ts_only
- if {$ts_only} {
- return 0;
- }
- to_tsonly
-
- return 0
- }
- if {[regexp -nocase {^IPV6=([01])} $hpt mv val]} {
- global env have_ipv6
- set have_ipv6 $val
- set env(SSVNC_IPV6) $val
- mesg "Set have_ipv6 to $val"
- set vncdisplay ""
- return 0
- }
- if {[regexp {^ENV=([A-z0-9][A-z0-9]*)=(.*)$} $hpt mv var val]} {
- global env
- if {$val == ""} {
- catch {unset env($var)}
- mesg "Unset $var"
- } else {
- set env($var) "$val"
- mesg "Set $var to $val"
- }
- set vncdisplay ""
- return 0
- }
-
- regsub {[ ]*cmd=.*$} $hp "" tt
-
- if {[regexp {^[ ]*$} $tt]} {
- mesg "No host:disp supplied."
- bell
- catch {raise .}
- mac_raise
- return
- }
- if {[regexp -- {--nohost--} $tt]} {
- mesg "No host:disp supplied."
- bell
- catch {raise .}
- mac_raise
- return
- }
- # XXX host_part
- if {! [regexp ":" $hp]} {
- if {! [regexp {cmd=} $hp]} {
- set s [string trim $hp]
- if {! [regexp { } $s]} {
- append hp ":0"
- } else {
- regsub { } $hp ":0 " hp
- }
- }
- }
-
- if {!$use_ssl && !$use_ssh && !$use_sshssl && $sshssl_sw == "none"} {
- regsub -nocase {^[a-z0-9+]*://} $hp "" hp
- set hp "Vnc://$hp"
- }
-
- mesg "Using: $hp"
- after 600
-
- set sc [get_ssh_cmd $hp]
- if {[regexp {^KNOCK} $sc]} {
- if [regexp {^KNOCKF} $sc] {
- port_knock_only $hp "FINISH"
- } else {
- port_knock_only $hp "KNOCK"
- }
- return
- }
-
- if {$debug} {
- mesg "\"$tcl_platform(os)\" | \"$tcl_platform(osVersion)\""
- after 1000
- }
-
- if [regexp {V[Nn][Cc]://} $hp] {
- set env(SSVNC_NO_ENC_WARN) 1
- regsub {V[Nn][Cc]://} $hp "vnc://" hp
- }
- regsub -nocase {^vnc://} $hp "vnc://" hp
- regsub -nocase {^vncs://} $hp "vncs://" hp
- regsub -nocase {^vncssl://} $hp "vncssl://" hp
- regsub -nocase {^vnc\+ssl://} $hp "vnc+ssl://" hp
- regsub -nocase {^vncssh://} $hp "vncssh://" hp
- regsub -nocase {^vnc\+ssh://} $hp "vnc+ssh://" hp
-
- if {! $is_windows} {
- launch_unix $hp
- return
- }
-
- ##############################################################
- # WINDOWS BELOW:
-
- if [regexp {^vnc://} $hp] {
- if {! [info exists env(SSVNC_NO_ENC_WARN)]} {
- direct_connect_msg
- }
- regsub {^vnc://} $hp "" hp
- direct_connect_windows $hp
- return
- } elseif [regexp {^vncs://} $hp] {
- set use_ssl 1
- set use_ssh 0
- regsub {^vncs://} $hp "" hp
- sync_use_ssl_ssh
- } elseif [regexp {^vncssl://} $hp] {
- set use_ssl 1
- set use_ssh 0
- regsub {^vncssl://} $hp "" hp
- sync_use_ssl_ssh
- } elseif [regexp {^vnc\+ssl://} $hp] {
- set use_ssl 1
- set use_ssh 0
- regsub {^vnc\+ssl://} $hp "" hp
- sync_use_ssl_ssh
- } elseif [regexp {^vncssh://} $hp] {
- set use_ssh 1
- set use_ssl 0
- regsub {vncssh://} $hp "" hp
- sync_use_ssl_ssh
- } elseif [regexp {^vnc\+ssh://} $hp] {
- set use_ssh 1
- set use_ssl 0
- regsub {^vnc\+ssh://} $hp "" hp
- sync_use_ssl_ssh
- }
-
- check_ssh_needed
-
- if {! $use_ssh} {
- if {$mycert != ""} {
- if {! [file exists $mycert]} {
- mesg "MyCert does not exist: $mycert"
- bell
- return
- }
- }
- if {$svcert != ""} {
- if {! [file exists $svcert]} {
- mesg "ServerCert does not exist: $svcert"
- bell
- return
- }
- } elseif {$crtdir != ""} {
- if {! [file exists $crtdir] && $crtdir != "ACCEPTED_CERTS"} {
- mesg "CertsDir does not exist: $crtdir"
- bell
- return
- }
- }
- if {$crlfil != ""} {
- if {! [file exists $crlfil]} {
- mesg "CRL File does not exist: $crlfil"
- bell
- return
- }
- }
- }
-
- # VF
- set prefix "stunnel-vnc"
- set suffix "conf"
- if {$use_ssh || $use_sshssl} {
- set prefix "plink_vnc"
- set suffix "bat"
- }
-
- set file1 ""
- set n1 ""
- set file2 ""
- set n2 ""
- set n3 ""
- set n4 ""
- set now [clock seconds]
-
- set proxy [get_ssh_proxy $hp]
- if {$use_sshssl} {
- set proxy ""
- }
- if {! [repeater_proxy_check $proxy]} {
- return
- }
-
- global port_slot
- if {$port_slot != ""} {
- set file1 "$prefix-$port_slot.$suffix"
- set n1 $port_slot
- set ps [expr $port_slot + 200]
- set file2 "$prefix-$ps.$suffix"
- set n2 $ps
- mesg "Using Port Slot: $port_slot"
- after 700
- }
-
- for {set i 30} {$i <= 99} {incr i} {
- set try "$prefix-$i.$suffix"
- if {$i == $port_slot} {
- continue
- }
- if {[file exists $try]} {
- set mt [file mtime $try]
- set age [expr "$now - $mt"]
- set week [expr "7 * 3600 * 24"]
- if {$age > $week} {
- catch {file delete $try}
- }
- }
- if {! [file exists $try]} {
- if {$file1 == ""} {
- set file1 $try
- set n1 $i
- } elseif {$file2 == ""} {
- set file2 $try
- set n2 $i
- } else {
- break
- }
- }
- }
-
- if {$file1 == ""} {
- mesg "could not find free stunnel file"
- bell
- return
- }
-
- if {$n1 == ""} {
- set n1 10
- }
- if {$n2 == ""} {
- set n2 11
- }
- set n3 [expr $n1 + 100]
- set n4 [expr $n2 + 100]
-
- global launch_windows_ssh_files
- set launch_windows_ssh_files ""
-
- set did_port_knock 0
-
- global listening_name
- set listening_name ""
-
- if {$use_ssh} {
- ;
- } elseif {$use_sshssl} {
- ;
- } elseif {$use_ssl} {
- if {$proxy != "" && [regexp {@} $proxy]} {
- mesg "Error: proxy contains '@' Did you mean to use SSH mode?"
- bell
- return
- }
- if [regexp {@} $hp] {
- mesg "Error: host contains '@' Did you mean to use SSH mode?"
- bell
- return
- }
- }
-
- global ssh_ipv6_pid
- set ssh_ipv6_pid ""
-
- if {$use_sshssl} {
- set rc [launch_windows_ssh $hp $file2 $n2]
- if {$rc == 0} {
- if {![info exists env(SSVNC_NO_DELETE)]} {
- catch {file delete $file1}
- catch {file delete $file2}
- }
- del_launch_windows_ssh_files
- return
- }
- set did_port_knock 1
- } elseif {$use_ssh} {
- launch_windows_ssh $hp $file1 $n1
- # WE ARE DONE.
- return
- }
-
- set host [host_part $hp];
- set host_orig $host
-
- global win_localhost
-
- if {$host == ""} {
- set host $win_localhost
- }
-
- if [regexp {^.*@} $host match] {
- catch {raise .; update}
- mesg "Trimming \"$match\" from hostname"
- after 700
- regsub {^.*@} $host "" host
- }
-
- set disp [port_part $hp]
- if {[regexp {^-[0-9][0-9]*$} $disp]} {
- ;
- } elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} {
- set disp 0
- }
-
- if {$disp < 0} {
- set port [expr "- $disp"]
- } elseif {$disp < 200} {
- if {$use_listen} {
- set port [expr "$disp + 5500"]
- } else {
- set port [expr "$disp + 5900"]
- }
- } else {
- set port $disp
- }
-
- if {$debug} {
- mesg "file: $file1"
- after 1000
- }
-
- listen_verify_all_dialog $hp
-
- if {$use_listen && $mycert == ""} {
- if {! [check_for_listen_ssl_cert]} {
- return;
- }
- }
-
- set fail 0
-
- set fh [open $file1 "w"]
-
- if {$use_listen} {
- puts $fh "client = no"
- } else {
- puts $fh "client = yes"
- }
- global disable_ssl_workarounds disable_ssl_workarounds_type
- if {$disable_ssl_workarounds} {
- if {$disable_ssl_workarounds_type == "noempty"} {
- puts $fh "options = DONT_INSERT_EMPTY_FRAGMENTS"
- }
- } else {
- puts $fh "options = ALL"
- }
-
- puts $fh "taskbar = yes"
- puts $fh "RNDbytes = 2048"
- puts $fh "RNDfile = bananarand.bin"
- puts $fh "RNDoverwrite = yes"
- puts $fh "debug = 6"
-
- if {$mycert != ""} {
- if {! [file exists $mycert]} {
- mesg "MyCert does not exist: $mycert"
- bell
- set fail 1
- }
- puts $fh "cert = $mycert"
- } elseif {$use_listen} {
- # see above, this should not happen.
- puts $fh "cert = _nocert_"
- }
- if {$crlfil != ""} {
- if [file isdirectory $crlfil] {
- puts $fh "CRLpath = $crlfil"
- } else {
- puts $fh "CRLfile = $crlfil"
- }
- }
-
- set did_check 0
-
- if {$svcert != ""} {
- if {! [file exists $svcert]} {
- mesg "ServerCert does not exist: $svcert"
- bell
- set fail 1
- }
- puts $fh "CAfile = $svcert"
- puts $fh "verify = 2"
- } elseif {$crtdir != ""} {
- if {$crtdir == "ACCEPTED_CERTS"} {
- global skip_verify_accepted_certs
- set skip_verify_accepted_certs 0
- set did_check 1
- if {$use_sshssl} {
- set skip_verify_accepted_certs 1
- set did_check 0
- } elseif {! [check_accepted_certs 0]} {
- set fail 1
- }
- if {! $skip_verify_accepted_certs} {
- set adir [get_idir_certs ""]
- set adir "$adir/accepted"
- catch {file mkdir $adir}
- puts $fh "CApath = $adir"
- puts $fh "verify = 2"
- }
- } else {
- if {! [file exists $crtdir]} {
- mesg "CertsDir does not exist: $crtdir"
- bell
- set fail 1
- }
- puts $fh "CApath = $crtdir"
- puts $fh "verify = 2"
- }
- }
-
- if {!$did_check} {
- check_accepted_certs 1
- }
-
- if {$use_sshssl} {
- set p [expr "$n2 + 5900"]
- set proxy [maybe_add_vencrypt $proxy "$win_localhost:$p"]
- } else {
- set proxy [maybe_add_vencrypt $proxy $hp]
- }
-
- set ipv6_pid ""
- global have_ipv6
- if {$have_ipv6} {
- if {$proxy == "" && $use_ssl} {
- # stunnel can handle ipv6
- } else {
- set res [ipv6_proxy $proxy $host $port]
- set proxy [lindex $res 0]
- set host [lindex $res 1]
- set port [lindex $res 2]
- set ipv6_pid [lindex $res 3]
- }
- }
-
- set p_reverse 0
-
- if {$proxy != ""} {
- if {$use_sshssl} {
- ;
- } elseif [regexp {@} $proxy] {
- bell
- catch {raise .; update}
- mesg "WARNING: SSL proxy contains \"@\" sign"
- after 1500
- }
- set env(SSVNC_PROXY) $proxy
- set env(SSVNC_DEST) "$host:$port"
- if {$use_listen} {
- set env(SSVNC_REVERSE) "$win_localhost:$port"
- set env(CONNECT_BR_SLEEP) 3
- set p_reverse 1
- } else {
- if {$use_sshssl && [regexp {vencrypt:} $proxy]} {
- set env(SSVNC_LISTEN) [expr "$n4 + 5900"]
- } else {
- set env(SSVNC_LISTEN) [expr "$n2 + 5900"]
- }
- }
- if {[info exists env(PROXY_DEBUG)]} {
- foreach var [list SSVNC_PROXY SSVNC_DEST SSVNC_REVERSE CONNECT_BR_SLEEP SSVNC_LISTEN] {
- if [info exists env($var)] {
- mesg "$var $env($var)"; after 2500;
- }
- }
- }
- }
-
- global anon_dh_detected server_anondh
- if {$anon_dh_detected || $server_anondh} {
- puts $fh "ciphers = ALL:RC4+RSA:+SSLv2:@STRENGTH"
- set anon_dh_detected 0
- }
-
-
- puts $fh "\[vnc$n1\]"
- set port2 ""
- set port3 ""
- if {! $use_listen} {
- set port2 [expr "$n1 + 5900"]
- if [regexp {vencrypt:} $proxy] {
- set port3 [expr "$n3 + 5900"]
- set port2 $port3
- puts $fh "accept = $win_localhost:$port3"
- } else {
- puts $fh "accept = $win_localhost:$port2"
- }
-
- if {$use_sshssl && [regexp {vencrypt:} $proxy]} {
- set port [expr "$n4 + 5900"]
- puts $fh "connect = $win_localhost:$port"
- } elseif {$use_sshssl || $proxy != ""} {
- set port [expr "$n2 + 5900"]
- puts $fh "connect = $win_localhost:$port"
- } else {
- puts $fh "connect = $host:$port"
- }
- } else {
- set port2 [expr "$n1 + 5500"]
- set hloc ""
- if {$use_ssh} {
- # not reached?
- set hloc "$win_localhost:"
- set listening_name "$win_localhost:$port (on remote SSH side)"
- } else {
- set hn [get_hostname]
- if {$hn == ""} {
- set hn "this-computer"
- }
- set listening_name "$hn:$port (or nn.nn.nn.nn:$port, etc.)"
- }
- if {$host_orig != "" && $hloc == ""} {
- set hloc "$host_orig:"
- }
- puts $fh "accept = $hloc$port"
- puts $fh "connect = $win_localhost:$port2"
- }
-
- puts $fh "delay = no"
- puts $fh ""
- close $fh
-
- if {! $did_port_knock} {
- if {! [do_port_knock $host start]} {
- set fail 1
- }
- set did_port_knock 1
- }
-
- if {$fail} {
- if {![info exists env(SSVNC_NO_DELETE)]} {
- catch {file delete $file1}
- }
- catch { unset env(SSVNC_PROXY) }
- catch { unset env(SSVNC_LISTEN) }
- catch { unset env(SSVNC_REVERSE) }
- catch { unset env(SSVNC_DEST) }
- catch { unset env(SSVNC_PREDIGESTED_HANDSHAKE) }
- catch { unset env(CONNECT_BR_SLEEP) }
- winkill $ipv6_pid
- winkill $ssh_ipv6_pid
- set ssh_ipv6_pid ""
- return
- }
-
- note_stunnel_pids "before"
-
- set proxy_pid ""
- set proxy_pid2 ""
-
- if {$use_listen} {
- windows_listening_message $n1
- }
-
- if {$proxy != ""} {
- if [regexp {vencrypt:} $proxy] {
- set vport [expr "$n1 + 5900"]
- mesg "Starting VeNCrypt helper on port $vport,$port3 ..."
- after 500
- if {![info exists env(SSVNC_NO_DELETE)]} {
- catch {file delete "$file1.pre"}
- }
- set env(SSVNC_PREDIGESTED_HANDSHAKE) "$file1.pre"
- set env(SSVNC_VENCRYPT_VIEWER_BRIDGE) "$vport,$port3"
- set proxy_pid2 [exec "connect_br.exe" &]
- catch { unset env(SSVNC_VENCRYPT_VIEWER_BRIDGE) }
- }
- mesg "Starting TCP helper on port $port ..."
- after 400
- # ssl br case:
- set proxy_pid [exec "connect_br.exe" &]
- catch { unset env(SSVNC_PROXY) }
- catch { unset env(SSVNC_LISTEN) }
- catch { unset env(SSVNC_REVERSE) }
- catch { unset env(SSVNC_DEST) }
- catch { unset env(SSVNC_PREDIGESTED_HANDSHAKE) }
- catch { unset env(CONNECT_BR_SLEEP) }
- }
-
- mesg "Starting STUNNEL on port $port2 ..."
- after 500
-
- set pids [exec stunnel $file1 &]
-
- if {! $p_reverse} {
- after 300
- set vtm [vencrypt_tutorial_mesg]
- if {$vtm == ""} {
- after 300
- }
- }
-
- note_stunnel_pids "after"
-
- if {$debug} {
- after 1000
- mesg "pids $pids"
- after 1000
- } else {
- catch {destroy .o}
- catch {destroy .oa}
- catch {destroy .os}
- wm withdraw .
- }
-
- do_viewer_windows $n1
-
- del_launch_windows_ssh_files
-
- if {![info exists env(SSVNC_NO_DELETE)]} {
- catch {file delete $file1}
- }
-
- if {$debug} {
- ;
- } else {
- wm deiconify .
- }
- mesg "Disconnected from $hp."
-
- global port_knocking_list
- if [regexp {FINISH} $port_knocking_list] {
- do_port_knock $host finish
- }
-
- if {[llength $pids_new] > 0} {
- set plist [join $pids_new ", "]
- global terminate_pids
- set terminate_pids ""
- global kill_stunnel
- if {$kill_stunnel} {
- set terminate_pids yes
- } else {
- win_kill_msg $plist
- update
- vwait terminate_pids
- }
- if {$terminate_pids == "yes"} {
- kill_stunnel $pids_new
- }
- } else {
- win_nokill_msg
- }
- mesg "Disconnected from $hp."
- winkill $ipv6_pid
- winkill $ssh_ipv6_pid
- set ssh_ipv6_pid ""
-
- global is_win9x use_sound sound_daemon_local_kill sound_daemon_local_cmd
- if {! $is_win9x && $use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} {
- windows_stop_sound_daemon
- }
-}
-
-proc direct_connect_windows {{hp ""}} {
- global tcl_platform is_windows
- global env use_listen
-
- set proxy [get_ssh_proxy $hp]
-
- set did_port_knock 0
-
- global listening_name
- set listening_name ""
-
- set host [host_part $hp]
-
- set host_orig $host
-
- global win_localhost
- if {$host == ""} {
- set host $win_localhost
- }
-
- if [regexp {^.*@} $host match] {
- catch {raise .; update}
- mesg "Trimming \"$match\" from hostname"
- after 700
- regsub {^.*@} $host "" host
- }
-
- set disp [port_part $hp]
- if {[regexp {^-[0-9][0-9]*$} $disp]} {
- ;
- } elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} {
- set disp 0
- }
-
- if {$disp < 0} {
- set port [expr "- $disp"]
- } elseif {$disp < 200} {
- if {$use_listen} {
- set port [expr "$disp + 5500"]
- } else {
- set port [expr "$disp + 5900"]
- }
- } else {
- set port $disp
- }
-
- global have_ipv6
- set ipv6_pid ""
- if {$have_ipv6 && !$use_listen} {
- set res [ipv6_proxy $proxy $host $port]
- set proxy [lindex $res 0]
- set host [lindex $res 1]
- set port [lindex $res 2]
- set ipv6_pid [lindex $res 3]
- }
-
- if {$proxy != ""} {
- if [regexp {@} $proxy] {
- bell
- catch {raise .; update}
- mesg "WARNING: SSL proxy contains \"@\" sign"
- after 1500
- }
- set n2 45
-
- set env(SSVNC_PROXY) $proxy
- set env(SSVNC_LISTEN) [expr "$n2 + 5900"]
- set env(SSVNC_DEST) "$host:$port"
-
- set port [expr $n2 + 5900]
- set host $win_localhost
- }
-
- set fail 0
- if {! $did_port_knock} {
- if {! [do_port_knock $host start]} {
- set fail 1
- }
- set did_port_knock 1
- }
-
- if {$fail} {
- catch { unset env(SSVNC_PROXY) }
- catch { unset env(SSVNC_LISTEN) }
- catch { unset env(SSVNC_DEST) }
- winkill $ipv6_pid
- return
- }
-
- set proxy_pid ""
- if {$proxy != ""} {
- mesg "Starting Proxy TCP helper on port $port ..."
- after 400
- # unencrypted br case:
- set proxy_pid [exec "connect_br.exe" &]
- catch { unset env(SSVNC_PROXY) }
- catch { unset env(SSVNC_LISTEN) }
- catch { unset env(SSVNC_DEST) }
- }
-
- vencrypt_tutorial_mesg
-
- catch {destroy .o}
- catch {destroy .oa}
- catch {destroy .os}
- wm withdraw .
-
- if {$use_listen} {
- set n $port
- if {$n >= 5500} {
- set n [expr $n - 5500]
- }
- global direct_connect_reverse_host_orig
- set direct_connect_reverse_host_orig $host_orig
-
- do_viewer_windows "$n"
-
- set direct_connect_reverse_host_orig ""
- } else {
- if {$port >= 5900 && $port < 6100} {
- set port [expr $port - 5900]
- }
- do_viewer_windows "$host:$port"
- }
-
- wm deiconify .
-
- mesg "Disconnected from $hp."
-
- winkill $ipv6_pid
-
- global port_knocking_list
- if [regexp {FINISH} $port_knocking_list] {
- do_port_knock $host finish
- }
-
- mesg "Disconnected from $hp."
-}
-
-proc get_idir_certs {str} {
- global is_windows env
- set idir ""
- if {$str != ""} {
- if [file isdirectory $str] {
- set idir $str
- } else {
- set idir [file dirname $str]
- }
- if {$is_windows} {
- regsub -all {\\} $idir "/" idir
- regsub -all {//*} $idir "/" idir
- }
- }
- if {$idir == ""} {
- if {$is_windows} {
- if [info exists env(SSVNC_HOME)] {
- set t "$env(SSVNC_HOME)/ss_vnc"
- regsub -all {\\} $t "/" t
- regsub -all {//*} $t "/" t
- if {! [file isdirectory $t]} {
- catch {file mkdir $t}
- }
- set t "$env(SSVNC_HOME)/ss_vnc/certs"
- regsub -all {\\} $t "/" t
- regsub -all {//*} $t "/" t
- if {! [file isdirectory $t]} {
- catch {file mkdir $t}
- }
- if [file isdirectory $t] {
- set idir $t
- }
- }
- if {$idir == ""} {
- set t [file dirname [pwd]]
- set t "$t/certs"
- if [file isdirectory $t] {
- set idir $t
- }
- }
- }
- if {$idir == ""} {
- if [info exists env(SSVNC_HOME)] {
- set t "$env(SSVNC_HOME)/.vnc"
- if {! [file isdirectory $t]} {
- catch {file mkdir $t}
- }
- set t "$env(SSVNC_HOME)/.vnc/certs"
- if {! [file isdirectory $t]} {
- catch {file mkdir $t}
- }
- if [file isdirectory $t] {
- set idir $t
- }
- }
- }
- }
- if {$idir == ""} {
- if {$is_windows} {
- set idir [get_profiles_dir]
- }
- if {$idir == ""} {
- set idir [pwd]
- }
- }
- return $idir
-}
-
-proc delete_cert {{parent "."}} {
- set idir [get_idir_certs ""]
- set f ""
- unix_dialog_resize $parent
- if {$idir != ""} {
- set f [tk_getOpenFile -parent $parent -initialdir $idir]
- } else {
- set f [tk_getOpenFile -parent $parent]
- }
- if {$f != "" && [file exists $f]} {
- set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Cert" -message "Delete $f"]
- if {$reply == "yes"} {
- global mycert svcert crlfil
- set f_text [read_file $f]
- set f2 ""
- catch {file delete $f}
- if {$f == $mycert} { set mycert "" }
- if {$f == $svcert} { set svcert "" }
- if {$f == $crlfil} { set crlfil "" }
- if [regexp {\.crt$} $f] {
- regsub {\.crt$} $f ".pem" f2
- } elseif [regexp {\.pem$} $f] {
- regsub {\.pem$} $f ".crt" f2
- }
- if {$f2 != "" && [file exists $f2]} {
- set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Cert" -message "Delete $f2"]
- if {$reply == "yes"} {
- catch {file delete $f2}
- if {$f2 == $mycert} { set mycert "" }
- if {$f2 == $svcert} { set svcert "" }
- if {$f2 == $crlfil} { set crlfil "" }
- }
- }
- set dir [file dirname $f]
- if {$f_text != "" && [regexp {accepted$} $dir]} {
- foreach crt [glob -nocomplain -directory $dir {*.crt} {*.pem} {*.[0-9]}] {
- #puts "try $crt"
- set c_text [read_file $crt]
- if {$c_text == ""} {
- continue
- }
- if {$c_text != $f_text} {
- continue
- }
- set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Identical Cert" -message "Delete Identical $crt"]
- if {$reply == "yes"} {
- catch {file delete $crt}
- }
- }
- }
- }
- }
- catch {wm deiconify .c}
- update
-}
-
-proc set_mycert {{parent "."}} {
- global mycert
- set idir [get_idir_certs $mycert]
- set t ""
- unix_dialog_resize $parent
- if {$idir != ""} {
- set t [tk_getOpenFile -parent $parent -initialdir $idir]
- } else {
- set t [tk_getOpenFile -parent $parent]
- }
- if {$t != ""} {
- set mycert $t
- }
- catch {wm deiconify .c}
- v_mycert
- update
-}
-
-proc set_crlfil {{parent "."}} {
- global crlfil
- set idir [get_idir_certs $crlfil]
- set t ""
- unix_dialog_resize $parent
- if {$idir != ""} {
- set t [tk_getOpenFile -parent $parent -initialdir $idir]
- } else {
- set t [tk_getOpenFile -parent $parent]
- }
- if {$t != ""} {
- set crlfil $t
- }
- catch {wm deiconify .c}
- v_crlfil
- update
-}
-
-proc set_ultra_dsm_file {{parent "."}} {
- global ultra_dsm_file
- set idir [get_idir_certs $ultra_dsm_file]
- set t ""
- unix_dialog_resize $parent
- if {$idir != ""} {
- set t [tk_getOpenFile -parent $parent -initialdir $idir]
- } else {
- set t [tk_getOpenFile -parent $parent]
- }
- if {$t != ""} {
- set ultra_dsm_file $t
- }
- update
-}
-
-proc set_ssh_known_hosts_file {{parent "."}} {
- global ssh_known_hosts_filename is_windows uname
-
- if {$ssh_known_hosts_filename == ""} {
- set pdir [get_profiles_dir]
- set pdir "$pdir/ssh_known_hosts"
- catch {file mkdir $pdir}
-
- global last_load
- if {![info exists last_load]} {
- set last_load ""
- }
- if {$last_load != ""} {
- set dispf [string trim $last_load]
- set dispf [file tail $dispf]
-
- regsub {\.vnc$} $dispf "" dispf
- if {![regexp {\.known$} $dispf]} {
- set dispf "$dispf.known"
- }
- set guess $dispf
- } else {
- set vncdisp [get_vncdisplay]
- set dispf [string trim $vncdisp]
- if {$dispf != ""} {
- regsub {[ ].*$} $dispf "" dispf
- regsub -all {/} $dispf "" dispf
- } else {
- set dispf "unique-name-here"
- }
- if {$is_windows || $uname == "Darwin"} {
- regsub -all {:} $dispf "-" dispf
- } else {
- regsub -all {:} $dispf "-" dispf
- }
- if {![regexp {\.known$} $dispf]} {
- set dispf "$dispf.known"
- }
- set guess $dispf
- }
- } else {
- set pdir [file dirname $ssh_known_hosts_filename]
- set guess [file tail $ssh_known_hosts_filename]
- }
-
- set t ""
- unix_dialog_resize $parent
- if {$pdir != ""} {
- set t [tk_getSaveFile -parent $parent -initialdir $pdir -initialfile $guess]
- } else {
- set t [tk_getSaveFile -parent $parent -initialfile $guess]
- }
- if {$t != ""} {
- set ssh_known_hosts_filename $t
- }
- update
-}
-
-proc show_cert {crt} {
- if {$crt == ""} {
- bell
- return
- }
- if {! [file exists $crt]} {
- bell
- return
- }
- set info ""
- catch {set info [get_x509_info $crt]}
- if {$info == ""} {
- bell
- return
- }
-
- set w .show_certificate
- toplev $w
- scroll_text $w.f
- button $w.b -text Dismiss -command "destroy $w"
- bind $w <Escape> "destroy $w"
- $w.f.t insert end $info
-
- pack $w.b -side bottom -fill x
- pack $w.f -side top -fill both -expand 1
- center_win $w
- catch {raise $w}
-}
-
-proc show_crl {crl} {
- if {$crl == ""} {
- bell
- return
- }
- if {! [file exists $crl]} {
- bell
- return
- }
-
- set flist [list]
-
- if [file isdirectory $crl] {
- foreach cfile [glob -nocomplain -directory $crl "*"] {
- if [file isfile $cfile] {
- lappend flist $cfile
- }
- }
- } else {
- lappend flist $crl
- }
-
- set ossl [get_openssl]
- set info ""
-
- foreach cfile $flist {
- catch {
- set ph [open "| $ossl crl -fingerprint -text -noout -in \"$cfile\"" "r"]
- while {[gets $ph line] > -1} {
- append info "$line\n"
- }
- close $ph
- append info "\n"
- }
- }
-
- set w .show_crl
- toplev $w
- scroll_text $w.f
- button $w.b -text Dismiss -command "destroy $w"
- bind $w <Escape> "destroy $w"
- $w.f.t insert end $info
-
- pack $w.b -side bottom -fill x
- pack $w.f -side top -fill both -expand 1
- center_win $w
- catch {raise $w}
-}
-
-proc v_svcert {} {
- global svcert
- if {$svcert == "" || ! [file exists $svcert]} {
- catch {.c.svcert.i configure -state disabled}
- } else {
- catch {.c.svcert.i configure -state normal}
- }
- no_certs_tutorial_mesg
- return 1
-}
-
-proc v_mycert {} {
- global mycert
- if {$mycert == "" || ! [file exists $mycert]} {
- catch {.c.mycert.i configure -state disabled}
- } else {
- catch {.c.mycert.i configure -state normal}
- }
- return 1
-}
-
-proc v_crlfil {} {
- global crlfil
- if {$crlfil == "" || ! [file exists $crlfil]} {
- catch {.c.crlfil.i configure -state disabled}
- } else {
- catch {.c.crlfil.i configure -state normal}
- }
- return 1
-}
-
-proc show_mycert {} {
- global mycert
- show_cert $mycert
-}
-
-proc show_svcert {} {
- global svcert
- show_cert $svcert
-}
-
-proc show_crlfil {} {
- global crlfil
- show_crl $crlfil
-}
-
-proc set_svcert {{parent "."}} {
- global svcert crtdir
- set idir [get_idir_certs $svcert]
- set t ""
- unix_dialog_resize $parent
- if {$idir != ""} {
- set t [tk_getOpenFile -parent $parent -initialdir $idir]
- } else {
- set t [tk_getOpenFile -parent $parent]
- }
- if {$t != ""} {
- set crtdir ""
- set svcert $t
- }
- catch {wm deiconify .c}
- v_svcert
- update
-}
-
-proc set_crtdir {{parent "."}} {
- global svcert crtdir
- set idir ""
- if {$crtdir == "ACCEPTED_CERTS"} {
- set idir [get_idir_certs ""]
- } else {
- set idir [get_idir_certs $crtdir]
- }
- set t ""
- unix_dialog_resize $parent
- if {$idir != ""} {
- set t [tk_chooseDirectory -parent $parent -initialdir $idir]
- } else {
- set t [tk_chooseDirectory -parent $parent]
- }
- if {$t != ""} {
- set svcert ""
- set crtdir $t
- }
- catch {wm deiconify .c}
- update
-}
-
-proc set_createcert_file {} {
- global ccert
- if {[info exists ccert(FILE)]} {
- set idir [get_idir_certs $ccert(FILE)]
- }
- unix_dialog_resize .ccrt
- if {$idir != ""} {
- set t [tk_getSaveFile -parent .ccrt -defaultextension ".pem" -initialdir $idir]
- } else {
- set t [tk_getSaveFile -parent .ccrt -defaultextension ".pem"]
- }
- if {$t != ""} {
- set ccert(FILE) $t
- }
- catch {raise .ccrt}
- update
-}
-
-proc check_pp {} {
- global ccert
- if {$ccert(ENC)} {
- catch {.ccrt.pf.e configure -state normal}
- catch {focus .ccrt.pf.e}
- catch {.ccrt.pf.e icursor end}
- } else {
- catch {.ccrt.pf.e configure -state disabled}
- }
-}
-
-proc get_openssl {} {
- global is_windows
- if {$is_windows} {
- set ossl "openssl.exe"
- } else {
- set ossl "openssl"
- }
-}
-
-proc get_x509_info {crt} {
- set ossl [get_openssl]
- set info ""
- update
- set ph [open "| $ossl x509 -text -fingerprint -in \"$crt\"" "r"]
- while {[gets $ph line] > -1} {
- append info "$line\n"
- }
- close $ph
- return $info
-}
-
-proc do_oss_create {} {
- global is_windows is_win9x
-
- set cfg {
-[ req ]
-default_bits = 2048
-encrypt_key = yes
-distinguished_name = req_distinguished_name
-
-[ req_distinguished_name ]
-countryName = Country Name (2 letter code)
-countryName_default = %CO
-countryName_min = 2
-countryName_max = 2
-
-stateOrProvinceName = State or Province Name (full name)
-stateOrProvinceName_default = %ST
-
-localityName = Locality Name (eg, city)
-localityName_default = %LOC
-
-0.organizationName = Organization Name (eg, company)
-0.organizationName_default = %ON
-
-organizationalUnitName = Organizational Unit Name (eg, section)
-organizationalUnitName_default = %OUN
-
-commonName = Common Name (eg, YOUR name)
-commonName_default = %CN
-commonName_max = 64
-
-emailAddress = Email Address
-emailAddress_default = %EM
-emailAddress_max = 64
-}
-
- global ccert
-
- if {$ccert(FILE) == ""} {
- catch {destroy .c}
- mesg "No output cert file supplied"
- bell
- return
- }
- if {! [regexp {\.pem$} $ccert(FILE)]} {
- append ccert(FILE) ".pem"
- }
- set pem $ccert(FILE)
- regsub {\.pem$} $ccert(FILE) ".crt" crt
-
- if {$ccert(ENC)} {
- if {[string length $ccert(PASS)] < 4} {
- catch {destroy .c}
- mesg "Passphrase must be at least 4 characters long."
- bell
- return
- }
- }
- if {[string length $ccert(CO)] != 2} {
- catch {destroy .c}
- mesg "Country Name must be at exactly 2 characters long."
- bell
- return
- }
- if {[string length $ccert(CN)] > 64} {
- catch {destroy .c}
- mesg "Common Name must be less than 65 characters long."
- bell
- return
- }
- if {[string length $ccert(EM)] > 64} {
- catch {destroy .c}
- mesg "Email Address must be less than 65 characters long."
- bell
- return
- }
-
- foreach t {EM CN OUN ON LOC ST CO} {
-
- set val $ccert($t)
- if {$val == ""} {
- set val "none"
- }
- regsub "%$t" $cfg "$val" cfg
- }
-
- global is_windows
-
- if {$is_windows} {
- # VF
- set tmp "cert.cfg"
- } else {
- set tmp "/tmp/cert.cfg.[tpid]"
- set tmp [mytmp $tmp]
- catch {set fh [open $tmp "w"]}
- catch {exec chmod 600 $tmp}
- if {! [file exists $tmp]} {
- catch {destroy .c}
- mesg "cannot create: $tmp"
- bell
- return
- }
- }
- set fh ""
- catch {set fh [open $tmp "w"]}
- if {$fh == ""} {
- catch {destroy .c}
- mesg "cannot create: $tmp"
- bell
- catch {file delete $tmp}
- return
- }
-
- puts $fh $cfg
- close $fh
-
- set ossl [get_openssl]
-
- set cmd "$ossl req -config $tmp -nodes -new -newkey rsa:2048 -x509 -batch"
- if {$ccert(DAYS) != ""} {
- set cmd "$cmd -days $ccert(DAYS)"
- }
- if {$is_windows} {
- set cmd "$cmd -keyout {$pem} -out {$crt}"
- } else {
- set cmd "$cmd -keyout \"$pem\" -out \"$crt\""
- }
-
- if {$is_windows} {
- set emess ""
- if {$is_win9x} {
- catch {file delete $pem}
- catch {file delete $crt}
- update
- eval exec $cmd &
- catch {raise .}
- set sl 0
- set max 100
- #if {$ccert(ENC)} {
- # set max 100
- #}
- set maxms [expr $max * 1000]
- while {$sl < $maxms} {
- set s2 [expr $sl / 1000]
- mesg "running openssl ... $s2/$max"
- if {[file exists $pem] && [file exists $crt]} {
- after 2000
- break
- }
- after 500
- set sl [expr $sl + 500]
- }
- mesg ""
- } else {
- update
- set rc [catch {eval exec $cmd} emess]
- if {$rc != 0 && [regexp -nocase {error:} $emess]} {
- raise .
- tk_messageBox -type ok -icon error -message $emess -title "OpenSSL req command failed"
- return
- }
- }
- } else {
- set geometry [xterm_center_geometry]
- update
- unix_terminal_cmd $geometry "Running OpenSSL" "$cmd"
- catch {file attributes $pem -permissions go-rw}
- catch {file attributes $crt -permissions go-w}
- }
- catch {file delete $tmp}
-
- set bad ""
- if {! [file exists $pem]} {
- set bad "$pem "
- }
- if {! [file exists $crt]} {
- set bad "$crt"
- }
- if {$bad != ""} {
- raise .
- tk_messageBox -type ok -icon error -message "Not created: $bad" -title "OpenSSL could not create cert"
- catch {raise .c}
- return
- }
-
- if {$ccert(ENC) && $ccert(PASS) != ""} {
- set cmd "$ossl rsa -in \"$pem\" -des3 -out \"$pem\" -passout stdin"
- set ph ""
- set emess ""
- update
- set rc [catch {set ph [open "| $cmd" "w"]} emess]
- if {$rc != 0 || $ph == ""} {
- raise .
- tk_messageBox -type ok -icon error -message $emess -title "Could not encrypt private key"
- catch {file delete $pem}
- catch {file delete $crt}
- return
- }
- puts $ph $ccert(PASS)
- set emess ""
- set rc [catch {close $ph} emess]
- #puts $emess
- #puts $rc
- }
-
- set in [open $crt "r"]
- set out [open $pem "a"]
- while {[gets $in line] > -1} {
- puts $out $line
- }
- close $in
- close $out
-
- catch {raise .c}
- set p .
- if [winfo exists .c] {
- set p .c
- }
-
- set reply [tk_messageBox -parent $p -type yesno -title "View Cert" -message "View Certificate and Info?"]
- catch {raise .c}
- if {$reply == "yes"} {
- set w .view_cert
- toplev $w
- scroll_text $w.f
- set cert ""
- set fh ""
- catch {set fh [open $crt "r"]}
- if {$fh != ""} {
- while {[gets $fh line] > -1} {
- append cert "$line\n"
- }
- catch {close $fh}
- }
-
- global yegg
- set yegg ""
- button $w.b -text Dismiss -command "destroy $w; set yegg 1"
- pack $w.b -side bottom -fill x
- bind $w <Escape> "destroy $w; set yegg 1"
-
- $w.f.t insert end "\n"
- $w.f.t insert end "$crt:\n"
- $w.f.t insert end "\n"
- $w.f.t insert end $cert
- $w.f.t insert end "\n"
-
- set info [get_x509_info $crt]
- $w.f.t insert end $info
-
- pack $w.f -side top -fill both -expand 1
- center_win $w
- catch {raise $w}
- vwait yegg
- catch {raise .c}
- }
-
- set p .
- if [winfo exists .c] {
- set p .c
- }
- set reply [tk_messageBox -parent $p -type yesno -title "View Private Key" -message "View Private Key?"]
- catch {raise .c}
- if {$reply == "yes"} {
- set w .view_key
- toplev $w
- scroll_text $w.f
- set key ""
- set fh [open $pem "r"]
- while {[gets $fh line] > -1} {
- append key "$line\n"
- }
- close $fh
-
- global yegg
- set yegg ""
- button $w.b -text Dismiss -command "destroy $w; set yegg 1"
- pack $w.b -side bottom -fill x
- bind $w <Escape> "destroy $w; set yegg 1"
-
- $w.f.t insert end "\n"
- $w.f.t insert end "$pem:\n"
- $w.f.t insert end "\n"
- $w.f.t insert end $key
- $w.f.t insert end "\n"
-
- pack $w.f -side top -fill both -expand 1
- center_win $w
- catch {raise $w}
- vwait yegg
- catch {raise .c}
- }
-}
-
-proc create_cert {{name ""}} {
-
- toplev .ccrt
- wm title .ccrt "Create SSL Certificate"
-
- global uname
- set h 27
- if [small_height] {
- set h 14
- } elseif {$uname == "Darwin"} {
- set h 20
- }
- scroll_text .ccrt.f 80 $h
-
- set msg {
- This dialog helps you to create a simple Self-Signed SSL certificate.
-
- On Unix the openssl(1) program must be installed and in $PATH.
- On Windows, a copy of the openssl program is provided for convenience.
-
- The resulting certificate files can be used for either:
-
- 1) authenticating yourself (VNC Viewer) to a VNC Server
- or 2) your verifying the identity of a remote VNC Server.
-
- In either case you will need to safely copy one of the generated key or
- certificate files to the remote VNC Server and have the VNC Server use
- it. Or you could send it to the system administrator of the VNC Server.
-
- For the purpose of description, assume that the filename selected in the
- "Save to file" entry is "vnccert.pem". That file will be generated
- by this process and so will the "vnccert.crt" file. "vnccert.pem"
- contains both the Private Key and the Public Certificate. "vnccert.crt"
- only contains the Public Certificate.
-
- For case 1) you would copy "vnccert.crt" to the VNC Server side and
- instruct the server to use it. For x11vnc it would be for example:
-
- x11vnc -sslverify /path/to/vnccert.crt -ssl SAVE ...
-
- (it is also possible to handle many client certs at once in a directory,
- see the -sslverify documentation). Then you would use "vnccert.pem"
- as the MyCert entry in the SSL Certificates dialog.
-
- For case 2) you would copy "vnccert.pem" to the VNC Server side and
- instruct the server to use it. For x11vnc it would be for example:
-
- x11vnc -ssl /path/to/vnccert.pem
-
- Then you would use "vnccert.crt" as the as the ServerCert entry in the
- "SSL Certificates" dialog.
-
-
- Creating the Certificate:
-
- Choose a output filename (ending in .pem) in the "Save to file" entry.
-
- Then fill in the identification information (Country, State or Province,
- etc).
-
- The click on "Create" to generate the certificate files.
-
- Encrypting the Private Key: It is a very good idea to encrypt the
- Private Key that goes in the "vnccert.pem". The downside is that
- whenever that key is used (e.g. starting up x11vnc using it) then
- the passphrase will need to be created. If you do not encrypt it and
- somebody steals a copy of the "vnccert.pem" file then they can pretend
- to be you.
-
- After you have created the certificate files, you must copy and import
- either "vnccert.pem" or "vnccert.pem" to the remote VNC Server and
- also select the other file in the "SSL Certificates" dialog.
- See the description above.
-
- For more information see:
-
- http://www.karlrunge.com/x11vnc/ssl.html
- http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-int
-
- The first one describes how to use x11vnc to create Certificate
- Authority (CA) certificates in addition to Self-Signed ones.
-
-
- Tip: if you choose the "Common Name" to be the internet hostname
- (e.g. gateway.mydomain.com) that connections will be made to or
- from that will avoid many dialogs when connecting mentioning that
- the hostname does not match the Common Name.
-}
- .ccrt.f.t insert end $msg
-
- global ccert ccert_init tcert
-
-
- if {! [info exists ccert_init]} {
- set ccert_init 1
- set ccert(CO) "US"
- set ccert(ST) "Massachusetts"
- set ccert(LOC) "Boston"
- set ccert(ON) "My Company"
- set ccert(OUN) "Product Development"
- set ccert(CN) "www.nowhere.none"
- set ccert(EM) "admin@nowhere.none"
- set ccert(DAYS) "730"
- set ccert(FILE) ""
- }
-
- set ccert(ENC) 0
- set ccert(PASS) ""
-
- set tcert(CO) "Country Name (2 letter code):"
- set tcert(ST) "State or Province Name (full name):"
- set tcert(LOC) "Locality Name (eg, city):"
- set tcert(ON) "Organization Name (eg, company):"
- set tcert(OUN) "Organizational Unit Name (eg, section):"
- set tcert(CN) "Common Name (eg, YOUR name):"
- set tcert(EM) "Email Address:"
- set tcert(DAYS) "Days until expiration:"
-
- set idir [get_idir_certs ""]
- if {$name != ""} {
- if {[regexp {/} $name] || [regexp {\.pem$} $name] || [regexp {\.crt$} $name]} {
- set ccert(FILE) $name
- } else {
- set ccert(FILE) "$idir/$name.pem"
- }
- } elseif {$ccert(FILE) == ""} {
- set ccert(FILE) "$idir/vnccert.pem"
- }
-
- button .ccrt.cancel -text "Cancel" -command {destroy .ccrt; catch {raise .c}}
- bind .ccrt <Escape> {destroy .ccrt; catch {raise .c}}
- wm protocol .ccrt WM_DELETE_WINDOW {destroy .ccrt; catch {raise .c}}
-
- button .ccrt.create -text "Generate Cert" -command {destroy .ccrt; catch {raise .c}; do_oss_create}
-
- pack .ccrt.create .ccrt.cancel -side bottom -fill x
-
- set ew 40
-
- set w .ccrt.pf
- frame $w
- checkbutton $w.check -anchor w -variable ccert(ENC) -text \
- "Encrypt Key with Passphrase" -command {check_pp}
-
- entry $w.e -width $ew -textvariable ccert(PASS) -state disabled \
- -show *
-
- pack $w.e -side right
- pack $w.check -side left -expand 1 -fill x
- pack $w -side bottom -fill x
-
- set w .ccrt.fl
- frame $w
- label $w.l -anchor w -text "Save to file:"
-
- entry $w.e -width $ew -textvariable ccert(FILE)
- button $w.b -text "Browse..." -command {set_createcert_file; catch {raise .ccrt}}
- if {$name != ""} {
- $w.b configure -state disabled
- }
-
- pack $w.e -side right
- pack $w.b -side right
- pack $w.l -side left -expand 1 -fill x
- pack $w -side bottom -fill x
-
- set i 0
- foreach t {DAYS EM CN OUN ON LOC ST CO} {
- set w .ccrt.f$i
- frame $w
- label $w.l -anchor w -text "$tcert($t)"
- entry $w.e -width $ew -textvariable ccert($t)
- pack $w.e -side right
- pack $w.l -side left -expand 1 -fill x
- pack $w -side bottom -fill x
- incr i
- }
-
- pack .ccrt.f -side top -fill both -expand 1
-
- center_win .ccrt
-}
-
-proc import_check_mode {w} {
- global import_mode
- if {$import_mode == "paste"} {
- $w.mf.b configure -state disabled
- $w.mf.e configure -state disabled
- $w.plab configure -state normal
- $w.paste.t configure -state normal
- } else {
- $w.mf.b configure -state normal
- $w.mf.e configure -state normal
- $w.plab configure -state disabled
- $w.paste.t configure -state disabled
- }
-}
-
-proc import_browse {par} {
- global import_file
-
- set idir ""
- if {$import_file != ""} {
- set idir [get_idir_certs $import_file]
- }
- unix_dialog_resize $par
- if {$idir != ""} {
- set t [tk_getOpenFile -parent $par -initialdir $idir]
- } else {
- set t [tk_getOpenFile -parent $par]
- }
- if {$t != ""} {
- set import_file $t
- }
- catch {raise $par}
- update
-}
-
-proc import_save_browse {{par ".icrt"}} {
- global import_save_file
-
- set idir ""
- if {$import_save_file != ""} {
- set idir [get_idir_certs $import_save_file]
- }
- if {$idir == ""} {
- set idir [get_idir_certs ""]
- }
- unix_dialog_resize $par
- if {$idir != ""} {
- set t [tk_getSaveFile -parent $par -defaultextension ".crt" -initialdir $idir]
- } else {
- set t [tk_getSaveFile -parent $par -defaultextension ".crt"]
- }
- if {$t != ""} {
- set import_save_file $t
- }
- catch {raise $par}
- update
-}
-
-proc do_save {par} {
- global import_mode import_file import_save_file
- global also_save_to_accepted_certs
-
- if {![info exists also_save_to_accepted_certs]} {
- set also_save_to_accepted_certs 0
- }
-
- if {$import_save_file == "" && ! $also_save_to_accepted_certs} {
- tk_messageBox -parent $par -type ok -icon error \
- -message "No Save File supplied" -title "Save File"
- return
- }
-
- set str ""
- set subject_issuer ""
- if {$import_mode == "save_cert_text"} {
- global save_cert_text
- set str $save_cert_text
- set i 0
- foreach line [split $str "\n"] {
- incr i
- if {$i > 50} {
- break
- }
- if [regexp {^- subject: *(.*)$} $line m val] {
- set subject_issuer "${subject_issuer}subject:$val\n"
- }
- if [regexp {^- (issuer[0-9][0-9]*): *(.*)$} $line m is val] {
- set subject_issuer "${subject_issuer}$is:$val\n"
- }
- if [regexp {^INFO: SELF_SIGNED=(.*)$} $line m val] {
- set subject_issuer "${subject_issuer}SELF_SIGNED:$val\n"
- }
- }
- } elseif {$import_mode == "paste"} {
- set str [$par.paste.t get 1.0 end]
- } else {
- if {! [file exists $import_file]} {
- tk_messageBox -parent $par -type ok -icon error \
- -message "Input file \"$import_file\" does not exist." -title "Import File"
- return
- }
- set fh ""
- set emess ""
- set rc [catch {set fh [open $import_file "r"]} emess]
- if {$rc != 0 || $fh == ""} {
- tk_messageBox -parent $par -type ok -icon error \
- -message $emess -title "Import File: $import_file"
- return
- }
- while {[gets $fh line] > -1} {
- append str "$line\n"
- }
- close $fh
- }
-
- if {! [regexp {BEGIN CERTIFICATE} $str]} {
- tk_messageBox -parent $par -type ok -icon error \
- -message "Import Text does not contain \"BEGIN CERTIFICATE\"" -title "Imported Text"
- return
- }
- if {! [regexp {END CERTIFICATE} $str]} {
- tk_messageBox -parent $par -type ok -icon error \
- -message "Import Text does not contain \"END CERTIFICATE\"" -title "Imported Text"
- return
- }
-
- global is_windows
- set fh ""
- set emess ""
- set deltmp ""
- if {$import_save_file == ""} {
- if {! $is_windows} {
- set deltmp /tmp/import.[tpid]
- } else {
- set deltmp import.[tpid]
- }
- set deltmp [mytmp $deltmp]
- set import_save_file $deltmp
- }
- set rc [catch {set fh [open $import_save_file "w"]} emess]
- if {$rc != 0 || $fh == ""} {
- tk_messageBox -parent $par -type ok -icon error \
- -message $emess -title "Save File: $import_save_file"
- return
- }
- if {! $is_windows} {
- catch {file attributes $import_save_file -permissions go-w}
- if {[regexp {PRIVATE} $str] || [regexp {\.pem$} $import_save_file]} {
- catch {file attributes $import_save_file -permissions go-rw}
- }
- }
-
- puts -nonewline $fh $str
- close $fh
-
- global do_save_saved_it
- set do_save_saved_it 1
-
- if {$also_save_to_accepted_certs} {
- set ossl [get_openssl]
- set fp_txt ""
- set fp_txt [exec $ossl x509 -fingerprint -noout -in $import_save_file]
-
- set adir [get_idir_certs ""]
- set adir "$adir/accepted"
- catch {file mkdir $adir}
-
- set fingerprint ""
- set fingerline ""
-
- set i 0
- foreach line [split $fp_txt "\n"] {
- incr i
- if {$i > 5} {
- break
- }
- if [regexp -nocase {Fingerprint=(.*)} $line mv str] {
- set fingerline $line
- set fingerprint [string trim $str]
- }
- }
-
- set fingerprint [string tolower $fingerprint]
- regsub -all {:} $fingerprint "-" fingerprint
- regsub -all {[\\/=]} $fingerprint "_" fingerprint
-
- if {$subject_issuer == ""} {
- set si_txt ""
- set si_txt [exec $ossl x509 -subject -issuer -noout -in $import_save_file]
- set sub ""
- set iss ""
- foreach line [split $si_txt "\n"] {
- if [regexp -nocase {^subject= *(.*)$} $line mv str] {
- set str [string trim $str]
- set sub $str
- } elseif [regexp -nocase {^issuer= *(.*)$} $line mv str] {
- set str [string trim $str]
- set iss $str
- }
- }
- if {$sub != "" && $iss != ""} {
- set subject_issuer "subject:$sub\nissuer1:$iss\n"
- if {$sub == $iss} {
- set subject_issuer "${subject_issuer}SELF_SIGNED:1\n"
- } else {
- set subject_issuer "${subject_issuer}SELF_SIGNED:0\n"
- }
- }
- }
-
- global vncdisplay
- set from [get_ssh_hp $vncdisplay]
- if {$from == ""} {
- set from [file tail $import_save_file]
- regsub {\..*$} $from "" from
- }
- if {$from == ""} {
- set from "import"
- }
- if [regexp -- {^:[0-9][0-9]*$} $from] {
- set from "listen$from"
- }
- set hp $from
-
- set from [string tolower $from]
- regsub -all {^[+a-z]*://} $from "" from
- regsub -all {:} $from "-" from
- regsub -all {[\\/=]} $from "_" from
- regsub -all {[ ]} $from "_" from
-
- set crt "$adir/$from=$fingerprint.crt"
- catch {file copy -force $import_save_file $crt}
-
- global do_save_saved_hash_it
- set do_save_saved_hash_it 1
- save_hash $crt $adir $hp $fingerline $from $fingerprint $subject_issuer
- }
-
- catch {destroy $par}
- set p .c
- if {![winfo exists .c]} {
- global accepted_cert_dialog_in_progress
- if {! $accepted_cert_dialog_in_progress} {
- if {$deltmp == ""} {
- getcerts
- update
- }
- }
- }
- if {![winfo exists .c]} {
- set p .
- }
- catch {raise .c}
- catch {destroy .scrt}
- if {$deltmp != ""} {
- catch {file delete $deltmp}
- set import_save_file ""
- return;
- }
- tk_messageBox -parent $p -type ok -icon info \
- -message "Saved to file: $import_save_file" -title "Save File: $import_save_file"
-}
-
-proc import_cert {} {
-
- toplev .icrt
- wm title .icrt "Import SSL Certificate"
-
- global scroll_text_focus
- set scroll_text_focus 0
- global uname
- set h 19
- if [small_height] {
- set h 12
- } elseif {$uname == "Darwin"} {
- set h 16
- }
- scroll_text .icrt.f 90 $h
- set scroll_text_focus 1
-
- set msg {
- This dialog lets you import a SSL Certificate by either pasting one in or by
- loading from another file. Choose which input mode you want to use by the toggle
- "Paste / Read from File".
-
- There are two types of files we use 1) Certificate only, and 2) Private Key
- and Certificate.
-
- Type 1) would be used to verify the identity of a remote VNC Server, whereas
- type 2) would be used to authenticate ourselves to the remote VNC Server.
-
- A type 1) by convention ends with file suffix ".crt" and looks like:
-
------BEGIN CERTIFICATE-----
-MIID2jCCAsKgAwIBAgIJALKypfV8BItCMA0GCSqGSIb3DQEBBAUAMIGgMQswCQYD
-(more lines) ...
-TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam
------END CERTIFICATE-----
-
- A type 2) by convention ends with file suffix ".pem" and looks like:
-
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA4sApd7WaPKQRWnFe9T04D4pglQB0Ti0/dCVHxg8WEVQ8OdcW
-(more lines) ...
-9kBmNotUiTpvRM+e7E/zRemhvY9qraFooqMWzi9JrgYfeLfSvvFfGw==
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIID2jCCAsKgAwIBAgIJALKypfV8BItCMA0GCSqGSIb3DQEBBAUAMIGgMQswCQYD
-(more lines) ...
-TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam
------END CERTIFICATE-----
-
- You do not need to use the ".crt" or ".pem" convention if you do not want to.
-
- First, either paste in the text or set the "Read from File" filename.
-
- Next, set the "Save to File" name to the file where the imported certificate
- will be saved.
-
- Then, click on "Save" to save the imported Certificate.
-
- After you have imported the Certificate (or Key + Certificate), select it to
- use for a connection via the "MyCert" or "ServerCert" dialog.
-}
- .icrt.f.t insert end $msg
-
- global icert import_mode
-
- set import_mode "paste"
-
- set w .icrt.mf
- frame $w
-
- radiobutton $w.p -pady 1 -anchor w -variable import_mode -value paste \
- -text "Paste" -command "import_check_mode .icrt"
-
- radiobutton $w.f -pady 1 -anchor w -variable import_mode -value file \
- -text "Read from File:" -command "import_check_mode .icrt"
-
- global import_file
- set import_file ""
- entry $w.e -width 40 -textvariable import_file
-
- button $w.b -pady 1 -anchor w -text "Browse..." -command {import_browse .icrt}
- pack $w.b -side right
- pack $w.p $w.f -side left
- pack $w.e -side left -expand 1 -fill x
-
- $w.b configure -state disabled
- $w.e configure -state disabled
-
- label .icrt.plab -anchor w -text "Paste Certificate here: (extra blank lines above or below are OK)"
- set h 22
- if [small_height] {
- set h 11
- } elseif {$uname == "Darwin"} {
- set h 11
- }
- scroll_text .icrt.paste 90 $h
-
- button .icrt.cancel -text "Cancel" -command {destroy .icrt; catch {raise .c}}
- bind .icrt <Escape> {destroy .icrt; catch {raise .c}}
- wm protocol .icrt WM_DELETE_WINDOW {destroy .icrt; catch {raise .c}}
-
- button .icrt.save -text "Save" -command {do_save .icrt}
-
- set w .icrt.sf
- frame $w
-
- label $w.l -text "Save to File:" -anchor w
- global import_save_file
- set import_save_file ""
- entry $w.e -width 40 -textvariable import_save_file
- button $w.b -pady 1 -anchor w -text "Browse..." -command import_save_browse
-
- global also_save_to_accepted_certs
- set also_save_to_accepted_certs 0
- checkbutton .icrt.ac -anchor w -variable also_save_to_accepted_certs -text \
- "Also Save to the 'Accepted Certs' directory" -relief raised
-
- pack $w.b -side right
- pack $w.l -side left
- pack $w.e -side left -expand 1 -fill x
-
- pack .icrt.save .icrt.cancel .icrt.ac .icrt.sf .icrt.mf -side bottom -fill x
- pack .icrt.paste .icrt.plab -side bottom -fill x
-
- pack .icrt.f -side top -fill both -expand 1
-
- .icrt.paste.t insert end ""
-
- focus .icrt.paste.t
-
- center_win .icrt
-}
-
-proc save_cert {hp} {
-
- global cert_text
-
- toplev .scrt
- wm title .scrt "Import/Save SSL Certificate"
-
- global scroll_text_focus
- set scroll_text_focus 0
- global uname
-
- global accepted_cert_dialog_in_progress
- set h 20
- if {$accepted_cert_dialog_in_progress} {
- set mode "accepted"
- set h 15
- if [small_height] {
- set h 11
- }
- } else {
- set mode "normal"
- set h 20
- if [small_height] {
- set h 16
- }
- }
- scroll_text .scrt.f 90 $h
-
- set scroll_text_focus 1
-
- set msg1 {
- This dialog lets you import a SSL Certificate retrieved from a VNC server.
-
- Be sure to have verified its authenticity via an external means (checking
- the MD5 hash value sent to you by the administrator, etc)
-
- Set "Save to File" to the filename where the imported cert will be saved.
-
- If you also want the Certificate to be saved to the pool of certs in the
- 'Accepted Certs' directory, select the checkbox. By default all Servers are
- verified against the certificates in this pool.
-
- Then, click on "Save" to save the imported Certificate.
-
- After you have imported the Certificate it will be automatically selected as
- the "ServerCert" for the next connection to this host: %HOST
-
- To make the ServerCert setting to the imported cert file PERMANENT, select
- 'Save' to save it in the profile for this host.
-}
-
- set msg2 {
- This dialog lets you import a SSL Certificate retrieved from a VNC server.
-
- Be sure to have verified its authenticity via an external means (checking
- the MD5 hash value sent to you by the administrator, etc)
-
- It will be added to the 'Accepted Certs' directory. The "Save to File"
- below is already set to the correct directory and file name.
-
- Click on "Save" to add it to the Accepted Certs.
-
- It, and the other certs in that directory, will be used to authenticate
- any VNC Server that has "ACCEPTED_CERTS" as the "CertsDir" value in the
- "Certs..." dialog. This is the default checking policy.
-}
-
- set msg ""
- if {$mode == "normal"} {
- set msg $msg1
- } else {
- set msg $msg2
- }
-
- regsub {%HOST} $msg "$hp" msg
- .scrt.f.t insert end $msg
-
- set w .scrt.mf
- frame $w
-
- global import_file
- set import_file ""
- entry $w.e -width 40 -textvariable import_file
-
- set h 22
- if [small_height] {
- set h 10
- }
- scroll_text .scrt.paste 90 $h
-
- button .scrt.cancel -text "Cancel" -command {destroy .scrt; catch {raise .c}}
- bind .scrt <Escape> {destroy .scrt; catch {raise .c}}
- wm protocol .scrt WM_DELETE_WINDOW {destroy .scrt; catch {raise .c}}
-
- global import_save_file
- if {$mode == "normal"} {
- button .scrt.save -text "Save" -command {do_save .scrt; set svcert $import_save_file}
- } else {
- button .scrt.save -text "Save" -command {do_save .scrt}
- }
-
- if [regexp -nocase -- {ACCEPT} $cert_text] {
- if [regexp -nocase -- {Client certificate} $cert_text] {
- if [regexp -- {^:[0-9][0-9]*$} $hp] {
- if [regexp -nocase {subject=.*CN=([^/][^/]*)/} $cert_text mv0 mv1] {
- regsub -all {[ ]} $mv1 "" mv1
- set hp "$mv1$hp"
- } else {
- set hp "listen$hp"
- }
- }
- }
- }
-
- set w .scrt.sf
- frame $w
-
- label $w.l -text "Save to File:" -anchor w
- set import_save_file "server:$hp.crt"
- global is_windows
- regsub -all {:} $import_save_file "-" import_save_file
-
- set import_save_file [get_idir_certs ""]/$import_save_file
-
- global fetch_cert_filename
- if {$fetch_cert_filename != ""} {
- set import_save_file $fetch_cert_filename
- }
-
- entry $w.e -width 40 -textvariable import_save_file
- button $w.b -pady 1 -anchor w -text "Browse..." -command {import_save_browse .scrt}
-
- pack $w.b -side right
- pack $w.l -side left
- pack $w.e -side left -expand 1 -fill x
-
- global also_save_to_accepted_certs
- set also_save_to_accepted_certs 0
- if [regexp -nocase -- {ACCEPT} $cert_text] {
- if [regexp -nocase -- {Client certificate} $cert_text] {
- set also_save_to_accepted_certs 1
- }
- }
- checkbutton .scrt.ac -anchor w -variable also_save_to_accepted_certs -text \
- "Also Save to the 'Accepted Certs' directory" -relief raised
-
- if {$mode == "normal"} {
- pack .scrt.cancel .scrt.save .scrt.sf .scrt.ac .scrt.mf -side bottom -fill x
- } else {
- pack .scrt.cancel .scrt.save .scrt.sf .scrt.mf -side bottom -fill x
- }
- pack .scrt.paste -side bottom -fill x
-
- pack .scrt.f -side top -fill both -expand 1
-
- set text ""
- set on 0
- foreach line [split $cert_text "\n"] {
- if [regexp -- {-----BEGIN CERTIFICATE-----} $line] {
- incr on
- }
- if {$on != 1} {
- continue;
- }
- append text "$line\n"
- if [regexp -- {-----END CERTIFICATE-----} $line] {
- set on 2
- }
- }
- global save_cert_text
- set save_cert_text $text
- .scrt.paste.t insert end "$text"
- global import_mode
- set import_mode "save_cert_text"
-
- focus .scrt.paste.t
-
- center_win .scrt
-}
-
-
-proc getcerts {} {
- global mycert svcert crtdir crlfil
- global use_ssh use_sshssl
- toplev .c
- wm title .c "SSL Certificates"
- frame .c.mycert
- frame .c.svcert
- frame .c.crtdir
- frame .c.crlfil
- label .c.mycert.l -anchor w -width 12 -text "MyCert:"
- label .c.svcert.l -anchor w -width 12 -text "ServerCert:"
- label .c.crtdir.l -anchor w -width 12 -text "CertsDir:"
- label .c.crlfil.l -anchor w -width 12 -text "CRL File:"
-
- entry .c.mycert.e -width 32 -textvariable mycert -vcmd v_mycert
- entry .c.svcert.e -width 32 -textvariable svcert -vcmd v_svcert
- entry .c.crtdir.e -width 32 -textvariable crtdir
- entry .c.crlfil.e -width 32 -textvariable crlfil -vcmd v_crlfil
-
- bind .c.mycert.e <Enter> {.c.mycert.e validate}
- bind .c.mycert.e <Leave> {.c.mycert.e validate}
- bind .c.svcert.e <Enter> {.c.svcert.e validate}
- bind .c.svcert.e <Leave> {.c.svcert.e validate}
-
- button .c.mycert.b -text "Browse..." -command {set_mycert .c; catch {raise .c}}
- button .c.svcert.b -text "Browse..." -command {set_svcert .c; catch {raise .c}}
- button .c.crtdir.b -text "Browse..." -command {set_crtdir .c; catch {raise .c}}
- button .c.crlfil.b -text "Browse..." -command {set_crlfil .c; catch {raise .c}}
-
- button .c.mycert.i -text "Info" -command {show_mycert}
- button .c.svcert.i -text "Info" -command {show_svcert}
- button .c.crtdir.i -text "Info" -command {}
- button .c.crlfil.i -text "Info" -command {show_crlfil}
-
- bind .c.mycert.b <Enter> "v_mycert"
- bind .c.svcert.b <Enter> "v_svcert"
- bind .c.crlfil.b <Enter> "v_crlfil"
-
- .c.mycert.i configure -state disabled
- .c.svcert.i configure -state disabled
- .c.crtdir.i configure -state disabled
- .c.crlfil.i configure -state disabled
-
- bind .c.mycert.b <B3-ButtonRelease> "show_mycert"
- bind .c.svcert.b <B3-ButtonRelease> "show_svcert"
- bind .c.crlfil.b <B3-ButtonRelease> "show_crlfil"
-
- set do_crl 1
- set do_row 1
-
- set c .c
- if {$do_row} {
- frame .c.b0
- set c .c.b0
- }
-
- button $c.create -text "Create Certificate ..." -command {create_cert}
- button $c.import -text "Import Certificate ..." -command {import_cert}
- button $c.delete -text "Delete Certificate ..." -command {delete_cert .c}
-
- if {$c != ".c"} {
- pack $c.create $c.import $c.delete -fill x -expand 1 -side left
- }
-
- frame .c.b
- button .c.b.done -text "Done" -command {catch {destroy .c}}
- bind .c <Escape> {destroy .c}
- button .c.b.help -text "Help" -command help_certs
- pack .c.b.help .c.b.done -fill x -expand 1 -side left
-
- set wlist [list mycert svcert crtdir]
- lappend wlist crlfil
-
- foreach w $wlist {
- pack .c.$w.l -side left
- pack .c.$w.e -side left -expand 1 -fill x
- pack .c.$w.b -side left
- pack .c.$w.i -side left
- bind .c.$w.e <Return> ".c.$w.b invoke"
- if {$use_ssh} {
- .c.$w.l configure -state disabled
- .c.$w.e configure -state disabled
- .c.$w.b configure -state disabled
- }
- }
-
- global svcert_default_force mycert_default_force crlfil_default_force
- if {$mycert_default_force} {
- .c.mycert.e configure -state readonly
- .c.mycert.b configure -state disabled
- }
- if {$svcert_default_force} {
- .c.svcert.e configure -state readonly
- .c.svcert.b configure -state disabled
- .c.crtdir.e configure -state readonly
- .c.crtdir.b configure -state disabled
- }
- if {$crlfil_default_force} {
- .c.crlfil.e configure -state readonly
- .c.crlfil.b configure -state disabled
- }
-
- if {$mycert != ""} {
- v_mycert
- }
- if {$svcert != ""} {
- v_svcert
- }
- if {$crlfil != ""} {
- v_crlfil
- }
-
- set wlist [list .c.mycert .c.svcert .c.crtdir]
- if {$do_crl} {
- lappend wlist .c.crlfil
- }
- if {$c != ".c"} {
- lappend wlist $c
- } else {
- lappend wlist .c.create .c.import .c.delete
- }
- lappend wlist .c.b
-
- eval pack $wlist -side top -fill x
-
- center_win .c
- wm resizable .c 1 0
-
- focus .c
-}
-
-proc get_profiles_dir {} {
- global env is_windows
-
- set dir ""
- if {$is_windows} {
- if [info exists env(SSVNC_HOME)] {
- set t "$env(SSVNC_HOME)/ss_vnc"
- regsub -all {\\} $t "/" t
- regsub -all {//*} $t "/" t
- if {! [file isdirectory $t]} {
- catch {file mkdir $t}
- }
- if [file isdirectory $t] {
- set dir $t
- set s "$t/profiles"
- if {! [file exists $s]} {
- catch {file mkdir $s}
- }
- }
- }
- if {$dir == ""} {
- set t [file dirname [pwd]]
- set t "$t/profiles"
- if [file isdirectory $t] {
- set dir $t
- }
- }
- } elseif [info exists env(SSVNC_HOME)] {
- set t "$env(SSVNC_HOME)/.vnc"
- catch {file mkdir $t}
- if [file isdirectory $t] {
- set dir $t
- set s "$t/profiles"
- if {! [file exists $s]} {
- catch {file mkdir $s}
- }
- }
- }
-
- if {$dir != ""} {
-
- } elseif [info exists env(SSVNC_BASEDIR)] {
- set dir $env(SSVNC_BASEDIR)
- } else {
- set dir [pwd]
- }
- if [file isdirectory "$dir/profiles"] {
- set dir "$dir/profiles"
- }
- return $dir
-}
-
-proc globalize {} {
- global defs
- foreach var [array names defs] {
- uplevel global $var
- }
-}
-
-proc load_include {include dir} {
- global include_vars defs
-
- if [info exists include_vars] {
- unset include_vars
- }
-
- foreach inc [split $include ", "] {
- set f [string trim $inc]
-#puts "f=$f";
- if {$f == ""} {
- continue
- }
- set try ""
- if {[regexp {/} $f] || [regexp {\\} $f]} {
- set try $f;
- } else {
- set try "$dir/$f"
- }
- if {! [file exists $try]} {
- set try "$dir/$f.vnc"
- }
-#puts "try: $try"
- if [file exists $try] {
- set fh ""
- catch {set fh [open $try "r"]}
- if {$fh == ""} {
- continue
- }
- mesg "Applying template: $inc"
- after 100
- while {[gets $fh line] > -1} {
- append inc_str "$line\n"
- if [regexp {^([^=]*)=(.*)$} $line m var val] {
- if {! [info exists defs($var)]} {
- continue
- }
- if {$var == "include_list"} {
- continue
- }
- set pct 0
- if {$var == "smb_mount_list"} {
- set pct 1
- }
- if {$var == "port_knocking_list"} {
- set pct 1
- }
- if {$pct} {
- regsub -all {%%%} $val "\n" val
- }
- if {$val != $defs($var)} {
-#puts "include_vars $var $val"
- set include_vars($var) $val
- }
- }
- }
- catch {close $fh}
- }
- }
-}
-
-proc unix_dialog_resize {{w .}} {
- global env is_windows uname unix_dialog_size
- set ok 0
- set width 600
- set height 300
- if {[info exists env(SSVNC_BIGGER_DIALOG)]} {
- set ok 1
- if {[regexp {([0-9][0-9]*)x([0-9][0-9]*)} $env(SSVNC_BIGGER_DIALOG) m wi he]} {
- set width $wi;
- set height $he;
- }
- } elseif {[info exists env(USER)] && $env(USER) == "runge"} {
- set ok 1
- }
- if {$ok} {
- # this is a personal hack because tk_getOpenFile size is not configurable.
- if {!$is_windows && $uname != "Darwin"} {
- if {$w == "."} {
- set w2 .__tk_filedialog
- } else {
- set w2 $w.__tk_filedialog
- }
- set w3 $w2.icons.canvas
- global udr_w4
- set udr_w4 $w2.f2.cancel
- if {! [info exists unix_dialog_size($w)]} {
- after 50 {global udr_w4; catch {$udr_w4 invoke}}
- tk_getOpenFile -parent $w -initialdir /
- set unix_dialog_size($w) 1
- }
- if [winfo exists $w3] {
- catch {$w3 configure -width $width}
- catch {$w3 configure -height $height}
- }
- }
- }
-}
-
-proc delete_profile {{parent "."}} {
-
- globalize
-
- set dir [get_profiles_dir]
-
- unix_dialog_resize $parent
- set file [tk_getOpenFile -parent $parent -initialdir $dir -title "DELETE VNC Profile"]
-
- if {$file == ""} {
- return
- }
-
- set tail [file tail $file]
-
- set ans [tk_messageBox -type okcancel -title "Delete $tail" -message "Really Delete $file?" -icon warning]
-
- if {$ans == "ok"} {
- catch {file delete $file}
- mesg "Deleted $tail"
- } else {
- mesg "Delete Skipped."
- }
-}
-
-proc load_profile {{parent "."} {infile ""}} {
- global profdone
- global vncdisplay
-
- globalize
-
- set dir [get_profiles_dir]
-
- if {$infile != ""} {
- set file $infile
- } else {
- unix_dialog_resize
- set file [tk_getOpenFile -parent $parent -defaultextension \
- ".vnc" -initialdir $dir -title "Load VNC Profile"]
- }
-
- if {$file == ""} {
- set profdone 1
- return
- }
- set fh [open $file "r"]
- if {! [info exists fh]} {
- set profdone 1
- return
- }
-
- set goto_mode "";
- set str ""
- set include ""
- set sw 1
- while {[gets $fh line] > -1} {
- append str "$line\n"
- if [regexp {^include_list=(.*)$} $line m val] {
- set include $val
- }
- global ssh_only ts_only
- if {$ssh_only || $ts_only} {
- if [regexp {use_ssh=0} $line] {
- if {$sw} {
- mesg "Switching to SSVNC mode."
- set goto_mode "ssvnc"
- update
- after 300
- } else {
- bell
- mesg "Cannot Load an SSL profile in SSH-ONLY mode."
- set profdone 1
- close $fh
- return
- }
- }
- }
- if {! $ts_only} {
- if [regexp {ts_mode=1} $line] {
- if {$sw} {
- mesg "Switching to Terminal Services mode."
- set goto_mode "tsonly"
- update
- after 300
- } else {
- bell
- mesg "Cannot Load a Terminal Svcs profile SSVNC mode."
- set profdone 1
- close $fh
- return
- }
- }
- } else {
- if [regexp {ts_mode=0} $line] {
- if {$sw} {
- mesg "Switching to SSVNC mode."
- set goto_mode "ssvnc"
- update
- after 300
- } else {
- bell
- mesg "Cannot Load a Terminal Svcs profile SSVNC mode."
- set profdone 1
- close $fh
- return
- }
- }
- }
- }
- close $fh
-
- if {$include != ""} {
- load_include $include $dir
- }
-
- if {$goto_mode == "tsonly"} {
- to_tsonly
- } elseif {$goto_mode == "ssvnc"} {
- to_ssvnc
- } elseif {$goto_mode == "sshvnc"} {
- to_sshvnc
- }
- set_defaults
-
- global include_vars
- if [info exists include_vars] {
- foreach var [array names include_vars] {
- set $var $include_vars($var)
- }
- }
-
-
- global use_ssl use_ssh use_sshssl
- set use_ssl 0
- set use_ssh 0
- set use_sshssl 0
-
- global defs
- foreach line [split $str "\n"] {
- set line [string trim $line]
- if [regexp {^#} $line] {
- continue
- }
- if [regexp {^([^=]*)=(.*)$} $line m var val] {
- if {$var == "disp"} {
- set vncdisplay $val
- continue
- }
- if [info exists defs($var)] {
- set pct 0
- if {$var == "smb_mount_list"} {
- set pct 1
- }
- if {$var == "port_knocking_list"} {
- set pct 1
- }
- if {$pct} {
- regsub -all {%%%} $val "\n" val
- }
- set $var $val
- }
- }
- }
-
- init_vncdisplay
- if {! $use_ssl && ! $use_ssh && ! $use_sshssl} {
- if {! $disable_all_encryption} {
- set use_ssl 1
- }
- }
- if {$use_ssl} {
- set use_ssh 0
- set use_sshssl 0
- } elseif {$use_ssh && $use_sshssl} {
- set use_ssh 0
- }
- sync_use_ssl_ssh
-
- set compresslevel_text "Compress Level: $use_compresslevel"
- set quality_text "Quality: $use_quality"
-
- set profdone 1
- putty_pw_entry check
- listen_adjust
- unixpw_adjust
-
- global last_load
- set last_load [file tail $file]
-
- global uname darwin_cotvnc
- if {$uname == "Darwin"} {
- if {$use_x11_macosx} {
- set darwin_cotvnc 0;
- } else {
- set darwin_cotvnc 1;
- }
- }
-
- mesg "Loaded [file tail $file]"
-}
-
-proc sync_use_ssl_ssh {} {
- global use_ssl use_ssh use_sshssl
- global disable_all_encryption
- if {$use_ssl} {
- ssl_ssh_adjust ssl
- } elseif {$use_ssh} {
- ssl_ssh_adjust ssh
- } elseif {$use_sshssl} {
- ssl_ssh_adjust sshssl
- } elseif {$disable_all_encryption} {
- ssl_ssh_adjust none
- } else {
- ssl_ssh_adjust ssl
- }
-}
-
-proc save_profile {{parent "."}} {
- global is_windows uname
- global profdone
- global include_vars defs
- global ts_only
- global last_load
-
- globalize
-
- set dir [get_profiles_dir]
-
- set vncdisp [get_vncdisplay]
-
- set dispf [string trim $vncdisp]
- if {$dispf != ""} {
- regsub {[ ].*$} $dispf "" dispf
- regsub -all {/} $dispf "" dispf
- } else {
- global ts_only
- if {$ts_only} {
- mesg "No VNC Terminal Server supplied."
- } else {
- mesg "No VNC Host:Disp supplied."
- }
- bell
- return
- }
- if {$is_windows || $uname == "Darwin"} {
- regsub -all {:} $dispf "-" dispf
- } else {
- regsub -all {:} $dispf "-" dispf
- }
- regsub -all {[\[\]]} $dispf "" dispf
- if {$ts_only && ![regexp {^TS-} $dispf]} {
- set dispf "TS-$dispf"
- }
- if {![regexp {\.vnc$} $dispf]} {
- set dispf "$dispf.vnc"
- }
-
- set guess $dispf
- if {$last_load != ""} {
- set guess $last_load
- }
-
- unix_dialog_resize
- set file [tk_getSaveFile -parent $parent -defaultextension ".vnc" \
- -initialdir $dir -initialfile "$guess" -title "Save VNC Profile"]
- if {$file == ""} {
- set profdone 1
- return
- }
- set fh [open $file "w"]
- if {! [info exists fh]} {
- set profdone 1
- return
- }
- set h [string trim $vncdisp]
- set p $h
- # XXX host_part
- regsub {:[0-9][0-9]*$} $h "" h
- set host $h
- regsub {[ ].*$} $p "" p
- regsub {^.*:} $p "" p
- regsub { .*$} $p "" p
- if {$p == ""} {
- set p 0
- } elseif {![regexp {^[-0-9][0-9]*$} $p]} {
- set p 0
- }
- if {$p < 0} {
- set port $p
- } elseif {$p < 200} {
- set port [expr $p + 5900]
- } else {
- set port $p
- }
-
- set h [string trim $vncdisp]
- regsub {cmd=.*$} $h "" h
- set h [string trim $h]
- if {! [regexp {[ ]} $h]} {
- set h ""
- } else {
- regsub {^.*[ ]} $h "" h
- }
- if {$h == ""} {
- set proxy ""
- set proxyport ""
- } else {
- set p $h
- regsub {:[0-9][0-9]*$} $h "" h
- set proxy $h
- regsub {[ ].*$} $p "" p
- regsub {^.*:} $p "" p
- if {$p == ""} {
- set proxyport 0
- } else {
- set proxyport $p
- }
- }
-
- puts $fh "\[connection\]"
- puts $fh "host=$host"
- puts $fh "port=$port"
- puts $fh "proxyhost=$proxy"
- puts $fh "proxyport=$proxyport"
- puts $fh "disp=$vncdisp"
- puts $fh "\n\[options\]"
- puts $fh "# parameters commented out with '#' indicate the default setting."
-
- if {$include_list != ""} {
- load_include $include_list [get_profiles_dir]
- }
- global sshssl_sw
- if {! $use_ssl && ! $use_ssh && ! $use_sshssl} {
- if {$sshssl_sw == "none"} {
- set disable_all_encryption 1
- }
- }
-
- global ts_only ssh_only
- if {$ts_only} {
- set ts_mode 1
- } else {
- set ts_mode 0
- }
- foreach var [lsort [array names defs]] {
- eval set val \$$var
- set pre ""
- if {$val == $defs($var)} {
- set pre "#"
- }
- if {$ssh_only && $var == "use_ssh"} {
- set pre ""
- }
- set pct 0
- if {$var == "smb_mount_list"} {
- set pct 1
- }
- if {$var == "port_knocking_list"} {
- set pct 1
- }
- if {$include_list != "" && [info exists include_vars($var)]} {
- if {$val == $include_vars($var)} {
- if {$pct} {
- regsub -all "\n" $val "%%%" val
- }
- puts $fh "#from include: $var=$val"
- continue
- }
- }
- if {$pct} {
- regsub -all "\n" $val "%%%" val
- }
- puts $fh "$pre$var=$val"
- }
-
- close $fh
-
- mesg "Saved Profile: [file tail $file]"
-
- set last_load [file tail $file]
-
- set profdone 1
-}
-
-proc set_ssh {} {
- global use_ssl
- if {$use_ssl} {
- ssl_ssh_adjust ssh
- }
-}
-
-proc expand_IP {redir} {
- if {! [regexp {:IP:} $redir]} {
- return $redir
- }
- if {! [regexp {(-R).*:IP:} $redir]} {
- return $redir
- }
-
- set ip [guess_ip]
- set ip [string trim $ip]
- if {$ip == ""} {
- return $redir
- }
-
- regsub -all {:IP:} $redir ":$ip:" redir
- return $redir
-}
-
-proc rand_port {} {
- global rand_port_list
-
- set p ""
- for {set i 0} {$i < 30} {incr i} {
- set p [expr 25000 + 35000 * rand()]
- set p [expr round($p)]
- if {![info exists rand_port_list($p)]} {
- break
- }
- }
- if {$p == ""} {
- unset rand_port_list
- set p [expr 25000 + 35000 * rand()]
- set p [expr round($p)]
- }
- set rand_port_list($p) 1
- return $p
-}
-
-proc get_cups_redir {} {
- global cups_local_server cups_remote_port
- global cups_local_smb_server cups_remote_smb_port
-
- regsub -all {[ ]} $cups_local_server "" cups_local_server
- regsub -all {[ ]} $cups_remote_port "" cups_remote_port
- regsub -all {[ ]} $cups_local_smb_server "" cups_local_smb_server
- regsub -all {[ ]} $cups_remote_smb_port "" cups_remote_smb_port
-
- set redir ""
-
- if {$cups_local_server != "" && $cups_remote_port != ""} {
- set redir "$cups_remote_port:$cups_local_server"
- regsub -all {['" ]} $redir {} redir; #"
- set redir " -R $redir"
- }
- if {$cups_local_smb_server != "" && $cups_remote_smb_port != ""} {
- set redir2 "$cups_remote_smb_port:$cups_local_smb_server"
- regsub -all {['" ]} $redir2 {} redir2; #"
- set redir "$redir -R $redir2"
- }
- set redir [expand_IP $redir]
- return $redir
-}
-
-proc get_additional_redir {} {
- global additional_port_redirs additional_port_redirs_list
- global ts_only choose_x11vnc_opts
- if {! $additional_port_redirs || $additional_port_redirs_list == ""} {
- return ""
- }
- if {$ts_only && !$choose_x11vnc_opts} {
- return ""
- }
- set redir [string trim $additional_port_redirs_list]
- regsub -all {['"]} $redir {} redir; #"
- set redir " $redir"
- set redir [expand_IP $redir]
- return $redir
-}
-
-proc get_sound_redir {} {
- global sound_daemon_remote_port sound_daemon_local_port
- global sound_daemon_x11vnc
-
- regsub -all {[ ]} $sound_daemon_remote_port "" sound_daemon_remote_port
- regsub -all {[ ]} $sound_daemon_local_port "" sound_daemon_local_port
-
- set redir ""
- if {$sound_daemon_local_port == "" || $sound_daemon_remote_port == ""} {
- return $redir
- }
-
- set loc $sound_daemon_local_port
- if {! [regexp {:} $loc]} {
- global uname
- if {$uname == "Darwin"} {
- set loc "127.0.0.1:$loc"
- } else {
- global is_windows
- if {$is_windows} {
- global win_localhost
- set loc "$win_localhost:$loc"
- } else {
- set loc "localhost:$loc"
- }
- }
- }
- set redir "$sound_daemon_remote_port:$loc"
- regsub -all {['" ]} $redir {} redir; #"
- set redir " -R $redir"
- set redir [expand_IP $redir]
- return $redir
-}
-
-proc get_smb_redir {} {
- global smb_mount_list
-
- set s [string trim $smb_mount_list]
- if {$s == ""} {
- return ""
- }
-
- set did(0) 1
- set redir ""
- set mntlist ""
-
- foreach line [split $s "\r\n"] {
- set str [string trim $line]
- if {$str == ""} {
- continue
- }
- if {[regexp {^#} $str]} {
- continue
- }
-
- set port ""
- if [regexp {^([0-9][0-9]*)[ \t][ \t]*(.*)} $str mvar port rest] {
- # leading port
- set str [string trim $rest]
- }
-
- # grab: //share /dest [host[:port]]
- set share ""
- set dest ""
- set hostport ""
- foreach item [split $str] {
- if {$item == ""} {
- continue
- }
- if {$share == ""} {
- set share [string trim $item]
- } elseif {$dest == ""} {
- set dest [string trim $item]
- } elseif {$hostport == ""} {
- set hostport [string trim $item]
- }
- }
-
- regsub {^~/} $dest {$HOME/} dest
-
- # work out the local host:port
- set lhost ""
- set lport ""
- if {$hostport != ""} {
- if [regexp {(.*):([0-9][0-9]*)} $hostport mvar lhost lport] {
- ;
- } else {
- set lhost $hostport
- set lport 139
- }
- } else {
- if [regexp {//([^/][^/]*)/} $share mvar h] {
- if [regexp {(.*):([0-9][0-9]*)} $h mvar lhost lport] {
- ;
- } else {
- set lhost $h
- set lport 139
- }
- } else {
- global is_windows win_localhost
- set lhost "localhost"
- if {$is_windows} {
- set lhost $win_localhost
- }
- set lport 139
- }
- }
-
- if {$port == ""} {
- if [info exists did("$lhost:$lport")] {
- # reuse previous one:
- set port $did("$lhost:$lport")
- } else {
- # choose one at random:
- for {set i 0} {$i < 3} {incr i} {
- set port [expr 20100 + 9000 * rand()]
- set port [expr round($port)]
- if { ! [info exists did($port)] } {
- break
- }
- }
- }
- set did($port) 1
- }
-
- if {$mntlist != ""} {
- append mntlist " "
- }
- append mntlist "$share,$dest,$port"
-
- if { ! [info exists did("$lhost:$lport")] } {
- append redir " -R $port:$lhost:$lport"
- set did("$lhost:$lport") $port
- }
- }
-
- regsub -all {['"]} $redir {} redir; #"
- set redir [expand_IP $redir]
-
- regsub -all {['"]} $mntlist {} mntlist; #"
-
- set l [list]
- lappend l $redir
- lappend l $mntlist
- return $l
-}
-
-proc ugly_setup_scripts {mode tag} {
-
-set cmd(1) {
- SSHD_PID=""
- FLAG=$HOME/.vnc-helper-flag__PID__
-
- if [ "X$USER" = "X" ]; then
- USER=$LOGNAME
- fi
-
- DO_CUPS=0
- cups_dir=$HOME/.cups
- cups_cfg=$cups_dir/client.conf
- cups_host=localhost
- cups_port=NNNN
-
- DO_SMB=0
- DO_SMB_SU=0
- DO_SMB_WAIT=0
- smb_mounts=
- DONE_PORT_CHECK=NNNN
- smb_script=$HOME/.smb-mounts__PID__.sh
-
- DO_SOUND=0
- DO_SOUND_KILL=0
- DO_SOUND_RESTART=0
- sound_daemon_remote_prog=
- sound_daemon_remote_args=
-
- findpid() {
- db=0
- back=30
- touch $FLAG
- tty=`tty | sed -e "s,/dev/,,"`
-
- if [ "X$TOPPID" = "X" ]; then
- TOPPID=$$
- if [ $db = 1 ]; then echo "set TOPPID to $TOPPID"; fi
- back=70
- fi
- #back=5
- if [ $db = 1 ]; then echo "TOPPID=$TOPPID THISPID=$$ back=$back"; fi
-
- i=1
- while [ $i -lt $back ]
- do
- try=`expr $TOPPID - $i`
- if [ $try -lt 1 ]; then
- try=`expr 32768 + $try`
- fi
- if [ $db = 1 ]; then echo try-1=$try; ps $try; fi
- if ps $try 2>/dev/null | grep "sshd.*$USER" | grep "$tty" >/dev/null; then
- if [ $db = 1 ]; then echo Found=$try; fi
- SSHD_PID="$try"
- echo
- ps $try
- echo
- break
- fi
- i=`expr $i + 1`
- done
-
- if [ "X$SSHD_PID" = "X" ]; then
- back=`expr $back + 20`
- #back=5
-
- for fallback in 2 3
- do
- i=1
- while [ $i -lt $back ]
- do
- try=`expr $TOPPID - $i`
- if [ $try -lt 1 ]; then
- try=`expr 32768 + $try`
- fi
- match="sshd.*$USER"
- if [ $fallback = 3 ]; then
- match="sshd"
- fi
- if [ $db = 1 ]; then echo "try-$fallback=$try match=$match"; ps $try; fi
- if ps $try 2>/dev/null | grep "$match" >/dev/null; then
- if [ $db = 1 ]; then echo Found=$try; fi
- SSHD_PID="$try"
- echo
- ps $try
- echo
- break
- fi
- i=`expr $i + 1`
- done
- if [ "X$SSHD_PID" != "X" ]; then
- break
- fi
- done
- fi
- #curlie}
-};
-
-set cmd(2) {
- #curlie{
- if [ "X$SSHD_PID" = "X" ]; then
- if [ $db = 1 ]; then
- echo
- pstr=`ps -elf | grep "$USER" | grep "$tty" | grep -v grep | grep -v PID | grep -v "ps -elf"`
- echo "$pstr"
- fi
- plist=`ps -elf | grep "$USER" | grep "$tty" | grep -v grep | grep -v PID | grep -v "ps -elf" | awk "{print \\\$4}" | sort -n`
- if [ $db = 1 ]; then
- echo
- echo "$plist"
- fi
- for try in $plist
- do
- if [ $db = 1 ]; then echo try-final=$try; ps $try; fi
- if echo "$try" | grep "^[0-9][0-9]*\\\$" > /dev/null; then
- :
- else
- continue
- fi
- if ps $try | egrep vnc-helper > /dev/null; then
- :
- else
- if [ $db = 1 ]; then echo Found=$try; fi
- SSHD_PID=$try
- echo
- ps $try
- echo
- break
- fi
- done
- fi
- if [ "X$SSHD_PID" = "X" ]; then
- #ugh
- SSHD_PID=$$
- fi
-
- echo "vnc-helper: [for cups/smb/esd] SSHD_PID=$SSHD_PID MY_PID=$$ TTY=$tty"
- echo "vnc-helper: To force me to finish: rm $FLAG"
- }
-
- wait_til_ssh_gone() {
- try_perl=""
- if type perl >/dev/null 2>&1; then
- if [ -d /proc -a -e /proc/$$ ]; then
- try_perl="1"
- fi
- fi
- if [ "X$try_perl" = "X1" ]; then
- # try to avoid wasting pids:
- perl -e "while (1) {if(-d \"/proc\" && ! -e \"/proc/$SSHD_PID\"){exit} if(! -f \"$FLAG\"){exit} sleep 1;}"
- else
- while [ 1 ]
- do
- ps $SSHD_PID > /dev/null 2>&1
- if [ $? != 0 ]; then
- break
- fi
- if [ ! -f $FLAG ]; then
- break
- fi
- sleep 1
- done
- fi
- rm -f $FLAG
- if [ "X$DO_SMB_WAIT" = "X1" ]; then
- rm -f $smb_script
- fi
- }
-};
-
-set cmd(3) {
- update_client_conf() {
- mkdir -p $cups_dir
-
- if [ ! -f $cups_cfg.back ]; then
- touch $cups_cfg.back
- fi
- if [ ! -f $cups_cfg ]; then
- touch $cups_cfg
- fi
-
- if grep ssvnc-auto $cups_cfg > /dev/null; then
- :
- else
- cp -p $cups_cfg $cups_cfg.back
- fi
-
- echo "#-ssvnc-auto:" > $cups_cfg
- sed -e "s/^ServerName/#-ssvnc-auto-#ServerName/" $cups_cfg.back >> $cups_cfg
- echo "ServerName $cups_host:$cups_port" >> $cups_cfg
-
- echo
- echo "-----------------------------------------------------------------"
- echo "On `hostname`:"
- echo
- echo "The CUPS $cups_cfg config file has been set to:"
- echo
- cat $cups_cfg | grep -v "^#-ssvnc-auto:" | sed -e "s/^/ /"
- echo
- echo "If there are problems automatically restoring it, edit or remove"
- echo "the file to go back to the local CUPS settings."
- echo
- echo "A backup has been placed in: $cups_cfg.back"
- echo
- echo "See the SSVNC CUPS dialog for more details on printing."
- if type lpstat >/dev/null 2>&1; then
- echo
- echo "lpstat -a output:"
- echo
- (lpstat -a 2>&1 | sed -e "s/^/ /") &
- sleep 0.5 >/dev/null 2>&1
- fi
- echo "-----------------------------------------------------------------"
- echo
- }
-
- reset_client_conf() {
- cp $cups_cfg $cups_cfg.tmp
- grep -v "^ServerName" $cups_cfg.tmp | grep -v "^#-ssvnc-auto:" | sed -e "s/^#-ssvnc-auto-#ServerName/ServerName/" > $cups_cfg
- rm -f $cups_cfg.tmp
- }
-
- cupswait() {
- trap "" INT QUIT HUP
- trap "reset_client_conf; rm -f $FLAG; exit" TERM
- wait_til_ssh_gone
- reset_client_conf
- }
-};
-
-# if [ "X$DONE_PORT_CHECK" != "X" ]; then
-# if type perl >/dev/null 2>&1; then
-# perl -e "use IO::Socket::INET; \$SIG{INT} = \"IGNORE\"; \$SIG{QUIT} = \"IGNORE\"; \$SIG{HUP} = \"INGORE\"; my \$client = IO::Socket::INET->new(Listen => 5, LocalAddr => \"localhost\", LocalPort => $DONE_PORT_CHECK, Proto => \"tcp\")->accept(); \$line = <\$client>; close \$client; unlink \"$smb_script\";" </dev/null >/dev/null 2>/dev/null &
-# if [ $? = 0 ]; then
-# have_perl_done="1"
-# fi
-# fi
-# fi
-
-set cmd(4) {
- smbwait() {
- trap "" INT QUIT HUP
- wait_til_ssh_gone
- }
- do_smb_mounts() {
- if [ "X$smb_mounts" = "X" ]; then
- return
- fi
- echo > $smb_script
- have_perl_done=""
- echo "echo" >> $smb_script
- dests=""
- for mnt in $smb_mounts
- do
- smfs=`echo "$mnt" | awk -F, "{print \\\$1}"`
- dest=`echo "$mnt" | awk -F, "{print \\\$2}"`
- port=`echo "$mnt" | awk -F, "{print \\\$3}"`
- dest=`echo "$dest" | sed -e "s,__USER__,$USER,g" -e "s,__HOME__,$HOME,g"`
- if [ ! -d $dest ]; then
- mkdir -p $dest
- fi
- echo "echo SMBMOUNT:" >> $smb_script
- echo "echo smbmount $smfs $dest -o uid=$USER,ip=127.0.0.1,port=$port" >> $smb_script
- echo "smbmount \"$smfs\" \"$dest\" -o uid=$USER,ip=127.0.0.1,port=$port" >> $smb_script
- echo "echo; df \"$dest\"; echo" >> $smb_script
- dests="$dests $dest"
- done
- #curlie}
-};
-
-set cmd(5) {
- echo "(" >> $smb_script
- echo "un_mnt() {" >> $smb_script
- for dest in $dests
- do
- echo " echo smbumount $dest" >> $smb_script
- echo " smbumount \"$dest\"" >> $smb_script
- done
- echo "}" >> $smb_script
- echo "trap \"\" INT QUIT HUP" >> $smb_script
- echo "trap \"un_mnt; exit\" TERM" >> $smb_script
-
- try_perl=""
- if type perl >/dev/null 2>&1; then
- try_perl=1
- fi
- uname=`uname`
- if [ "X$uname" != "XLinux" -a "X$uname" != "XSunOS" -a "X$uname" != "XDarwin" ]; then
- try_perl=""
- fi
-
- if [ "X$try_perl" = "X" ]; then
- echo "while [ -f $smb_script ]" >> $smb_script
- echo "do" >> $smb_script
- echo " sleep 1" >> $smb_script
- echo "done" >> $smb_script
- else
- echo "perl -e \"while (-f \\\"$smb_script\\\") {sleep 1;} exit 0;\"" >> $smb_script
- fi
- echo "un_mnt" >> $smb_script
- echo ") &" >> $smb_script
- echo "-----------------------------------------------------------------"
- echo "On `hostname`:"
- echo
- if [ "$DO_SMB_SU" = "0" ]; then
- echo "We now run the smbmount script as user $USER"
- echo
- echo sh $smb_script
- sh $smb_script
- rc=0
- elif [ "$DO_SMB_SU" = "1" ]; then
- echo "We now run the smbmount script via su(1)"
- echo
- echo "The first \"Password:\" will be for that of root to run the smbmount script."
- echo
- echo "Subsequent \"Password:\" will be for the SMB share(s) (hit Return if no passwd)"
- echo
- echo SU:
- echo "su root -c \"sh $smb_script\""
- su root -c "sh $smb_script"
- rc=$?
- elif [ "$DO_SMB_SU" = "2" ]; then
- echo "We now run the smbmount script via sudo(8)"
- echo
- echo "The first \"Password:\" will be for that of the sudo(8) password."
- echo
- echo "Subsequent \"Password:\" will be for the SMB shares (hit enter if no passwd)"
- echo
- echo SUDO:
- sd="sudo"
- echo "$sd sh $smb_script"
- $sd sh $smb_script
- rc=$?
- fi
-};
-
-set cmd(6) {
- #curlie{
- echo
- if [ "$rc" = 0 ]; then
- if [ "X$have_perl_done" = "X1" -o 1 = 1 ] ; then
- echo
- echo "Your SMB shares will be unmounted when the VNC connection closes,"
- echo "*AS LONG AS* No Applications have any of the share files opened or are"
- echo "cd-ed into any of the share directories."
- echo
- echo "Try to make sure nothing is accessing the SMB shares before disconnecting"
- echo "the VNC session. If you fail to do that follow these instructions:"
- fi
- echo
- echo "To unmount your SMB shares make sure no applications are still using any of"
- echo "the files and no shells are still cd-ed into the share area, then type:"
- echo
- echo " rm -f $smb_script"
- echo
- echo "In the worst case run: smbumount /path/to/mount/point for each mount as root"
- echo
- echo "Even with the remote redirection gone the kernel should umount after a timeout."
- else
- echo
- if [ "$DO_SMB_SU" = "1" ]; then
- echo "su(1) to run smbmount(8) failed."
- elif [ "$DO_SMB_SU" = "2" ]; then
- echo "sudo(8) to run smbmount(8) failed."
- fi
- rm -f $smb_script
- fi
- echo "-----------------------------------------------------------------"
- echo
- }
-};
-
-set cmd(7) {
-
- setup_sound() {
- dpid=""
- d=$sound_daemon_remote_prog
- if type pgrep >/dev/null 2>/dev/null; then
- dpid=`pgrep -U $USER -x $d | head -1`
- else
- dpid=`env PATH=/usr/ucb:$PATH ps wwwwaux | grep -w $USER | grep -w $d | grep -v grep | head -1`
- fi
- echo "-----------------------------------------------------------------"
- echo "On `hostname`:"
- echo
- echo "Setting up Sound: pid=$dpid"
- if [ "X$dpid" != "X" ]; then
- dcmd=`env PATH=/usr/ucb:$PATH ps wwwwaux | grep -w $USER | grep -w $d | grep -w $dpid | grep -v grep | head -1 | sed -e "s/^.*$d/$d/"`
- if [ "X$DO_SOUND_KILL" = "X1" ]; then
- echo "Stopping sound daemon: $sound_daemon_remote_prog $dpid"
- echo "sound cmd: $dcmd"
- kill -TERM $dpid
- fi
- fi
- echo "-----------------------------------------------------------------"
- echo
- }
-
- reset_sound() {
- if [ "X$DO_SOUND_RESTART" = "X1" ]; then
- d=$sound_daemon_remote_prog
- a=$sound_daemon_remote_args
- echo "Restaring sound daemon: $d $a"
- $d $a </dev/null >/dev/null 2>&1 &
- fi
- }
-
- soundwait() {
- trap "" INT QUIT HUP
- trap "reset_sound; rm -f $FLAG; exit" TERM
- wait_til_ssh_gone
- reset_sound
- }
-
-
- findpid
-
- if [ $DO_SMB = 1 ]; then
- do_smb_mounts
- fi
-
- waiter=0
-
- if [ $DO_CUPS = 1 ]; then
- update_client_conf
- cupswait </dev/null >/dev/null 2>/dev/null &
- waiter=1
- fi
-
- if [ $DO_SOUND = 1 ]; then
- setup_sound
- soundwait </dev/null >/dev/null 2>/dev/null &
- waiter=1
- fi
- if [ $DO_SMB_WAIT = 1 ]; then
- if [ $waiter != 1 ]; then
- smbwait </dev/null >/dev/null 2>/dev/null &
- waiter=1
- fi
- fi
-
-
- #FINMSG
- echo "--main-vnc-helper-finished--"
- #cat $0
- rm -f $0
- exit 0
-};
-
- set cmdall ""
-
- for {set i 1} {$i <= 7} {incr i} {
- set v $cmd($i);
- regsub -all "\n" $v "%" v
- regsub -all {.curlie.} $v "" v
- set cmd($i) $v
- append cmdall "echo "
- if {$i == 1} {
- append cmdall {TOPPID=$$ %}
- }
- append cmdall {'}
- append cmdall $cmd($i)
- append cmdall {' | tr '%' '\n'}
- if {$i == 1} {
- append cmdall {>}
- } else {
- append cmdall {>>}
- }
- append cmdall {$HOME/.vnc-helper-cmd__PID__; }
- }
- append cmdall {sh $HOME/.vnc-helper-cmd__PID__; }
-
- regsub -all {vnc-helper-cmd} $cmdall "vnc-helper-cmd-$mode" cmdall
- if {$tag == ""} {
- set tag [pid]
- }
- regsub -all {__PID__} $cmdall "$tag" cmdall
-
- set orig $cmdall
-
- global use_cups cups_local_server cups_remote_port cups_manage_rcfile ts_only ts_cups_manage_rcfile cups_x11vnc
- regsub -all {[ ]} $cups_local_server "" cups_local_server
- regsub -all {[ ]} $cups_remote_port "" cups_remote_port
- if {$use_cups} {
- set dorc 0
- if {$ts_only} {
- if {$ts_cups_manage_rcfile} {
- set dorc 1
- }
- } else {
- if {$cups_manage_rcfile} {
- set dorc 1
- }
- }
- if {$dorc && $mode == "post"} {
- if {$cups_local_server != "" && $cups_remote_port != ""} {
- regsub {DO_CUPS=0} $cmdall {DO_CUPS=1} cmdall
- regsub {cups_port=NNNN} $cmdall "cups_port=$cups_remote_port" cmdall
- }
- }
- }
-
- global use_smbmnt smb_su_mode smb_mounts
- if {$use_smbmnt} {
- if {$smb_mounts != ""} {
- set smbm $smb_mounts
- regsub -all {%USER} $smbm "__USER__" smbm
- regsub -all {%HOME} $smbm "__HOME__" smbm
- if {$mode == "pre"} {
- regsub {DO_SMB=0} $cmdall {DO_SMB=1} cmdall
- if {$smb_su_mode == "su"} {
- regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=1} cmdall
- } elseif {$smb_su_mode == "sudo"} {
- regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=2} cmdall
- } elseif {$smb_su_mode == "none"} {
- regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=0} cmdall
- } else {
- regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=1} cmdall
- }
- regsub {smb_mounts=} $cmdall "smb_mounts=\"$smbm\"" cmdall
- } elseif {$mode == "post"} {
- regsub {DO_SMB_WAIT=0} $cmdall {DO_SMB_WAIT=1} cmdall
- }
- }
- }
-
- global use_sound
- if {$use_sound} {
- if {$mode == "pre"} {
- global sound_daemon_remote_cmd sound_daemon_kill sound_daemon_restart
- if {$sound_daemon_kill} {
- regsub {DO_SOUND_KILL=0} $cmdall {DO_SOUND_KILL=1} cmdall
- regsub {DO_SOUND=0} $cmdall {DO_SOUND=1} cmdall
- }
- if {$sound_daemon_restart} {
- regsub {DO_SOUND_RESTART=0} $cmdall {DO_SOUND_RESTART=1} cmdall
- regsub {DO_SOUND=0} $cmdall {DO_SOUND=1} cmdall
- }
- set sp [string trim $sound_daemon_remote_cmd]
- regsub {[ \t].*$} $sp "" sp
- set sa [string trim $sound_daemon_remote_cmd]
- regsub {^[^ \t][^ \t]*[ \t][ \t]*} $sa "" sa
- regsub {sound_daemon_remote_prog=} $cmdall "sound_daemon_remote_prog=\"$sp\"" cmdall
- regsub {sound_daemon_remote_args=} $cmdall "sound_daemon_remote_args=\"$sa\"" cmdall
- }
- }
-
- if {$mode == "pre"} {
- set dopre 0
- if {$use_smbmnt && $smb_mounts != ""} {
- set dopre 1
- }
- if {$use_sound && $sound_daemon_kill} {
- set dopre 1
- }
- if {$dopre} {
- global is_windows
- if {$is_windows} {
- regsub {#FINMSG} $cmdall {echo "Now Go Click on the Label to Start the 2nd SSH"} cmdall
- } else {
- regsub {#FINMSG} $cmdall {echo "Finished with the 1st SSH tasks, the 2nd SSH should start shortly..."} cmdall
- }
- }
- }
-
- set cmdstr $cmdall
-
- if {"$orig" == "$cmdall"} {
- set cmdstr ""
- }
- global env
- if [info exists env(SSVNC_DEBUG_CUPS)] {
- regsub -all {db=0} $cmdstr "db=1" cmdstr
- set pout ""
- regsub -all {%} $cmdstr "\n" pout
- puts stderr "\nSERVICE REDIR COMMAND:\n\n$pout\n"
- }
- return $cmdstr
-}
-
-proc ts_unixpw_dialog {} {
-
- toplev .uxpw
- wm title .uxpw "Use unixpw"
-
- scroll_text .uxpw.f 80 14
-
- global ts_unixpw
-
- set msg {
- This enables the x11vnc unixpw mode. A Login: and Password: dialog
- will be presented in the VNC Viewer for the user to provide any Unix
- username and password whose session he wants to connect to. So this
- may require typing in the password a 2nd time after the one for SSH.
-
- This mode is useful if a shared terminal services user (e.g. 'tsuser')
- is used for the SSH login part (say via the SSH authorized_keys
- mechanism and all users share the same private SSH key for 'tsuser').
-
- Note, However that the default usage of a per-user SSH login should
- be the simplest and also sufficient for most situations, in which
- case this "Use unixpw" option should NOT be selected.
-}
- .uxpw.f.t insert end $msg
-
- button .uxpw.cancel -text "Cancel" -command {destroy .uxpw; set ts_unixpw 0}
- bind .uxpw <Escape> {destroy .uxpw; set ts_unixpw 0}
- wm protocol .uxpw WM_DELETE_WINDOW {destroy .uxpw; set ts_unixpw 0}
-
- button .uxpw.done -text "Done" -command {destroy .uxpw; set ts_unixpw 1}
-
- pack .uxpw.done .uxpw.cancel -side bottom -fill x
- pack .uxpw.f -side top -fill both -expand 1
-
- center_win .uxpw
-}
-
-proc ts_vncshared_dialog {} {
-
- toplev .vncs
- wm title .vncs "VNC Shared"
-
- scroll_text .vncs.f 80 23
-
- global ts_vncshared
-
- set msg {
- Normal use of this program, 'tsvnc', *ALREADY* allows simultaneous
- shared access of the remote desktop: You simply log in as many
- times from as many different locations with 'tsvnc' as you like.
-
- However, doing it that way starts up a new x11vnc for each connection.
- In some circumstances you may want a single x11vnc running but allow
- multiple VNC viewers to access it simultaneously.
-
- This option (VNC Shared) enables that rarer usage case by passing
- '-shared' to the remote x11vnc command.
-
- With this option enabled, the new shared connections must
- still connect to the Terminal Server via SSH for encryption and
- authentication. They must also do the normal SSH port redirection
- to access the x11vnc port (usually 5900, but look for the PORT=
- output for the actual value).
-
- They could use SSVNC for that, or do it manually in terminal
- windows, more information:
-
- http://www.karlrunge.com/x11vnc/#tunnelling
-}
- .vncs.f.t insert end $msg
-
- button .vncs.cancel -text "Cancel" -command {destroy .vncs; set ts_vncshared 0}
- bind .vncs <Escape> {destroy .vncs; set ts_vncshared 0}
- wm protocol .vncs WM_DELETE_WINDOW {destroy .vncs; set ts_vncshared 0}
- button .vncs.done -text "Done" -command {destroy .vncs; set ts_vncshared 1}
-
- pack .vncs.done .vncs.cancel -side bottom -fill x
- pack .vncs.f -side top -fill both -expand 1
-
- center_win .vncs
-}
-
-proc ts_multi_dialog {} {
-
- toplev .mult
- wm title .mult "Multiple Sessions"
-
- scroll_text .mult.f 80 21
-
- global ts_multisession choose_multisession
-
- set msg {
- Normally in Terminal Services mode (tsvnc) your user account (the
- one you SSH in as) can only have a single Terminal Services X session
- running at a time on one server machine.
-
- This is simply because x11vnc chooses the first Desktop (X session)
- of yours that it can find. It will never create a 2nd X session
- because it keeps finding the 1st one.
-
- To have Multiple Sessions for one username on a single machine,
- choose a unique Session "Tag", that will be associated with the X
- session and x11vnc will only choose the one that has this Tag.
-
- For this to work ALL of your sessions on the server machine must
- have a different tag (that is, if you have an existing session with
- no tag, x11vnc might find a tagged one first instead of it).
-
- The tag must be made of only letters, numbers, dash, or underscore.
-
- Examples: KDE_SMALL, gnome-2, test1
-}
- .mult.f.t insert end $msg
-
- frame .mult.c
- label .mult.c.l -anchor w -text "Tag:"
- entry .mult.c.e -width 20 -textvariable ts_multisession
- pack .mult.c.l -side left
- pack .mult.c.e -side left -expand 1 -fill x
-
- button .mult.cancel -text "Cancel" -command {destroy .mult; set choose_multisession 0}
- bind .mult <Escape> {destroy .mult; set choose_multisession 0}
- wm protocol .mult WM_DELETE_WINDOW {destroy .mult; set choose_multisession 0}
-
- bind .mult.c.e <Return> {destroy .mult; set choose_multisession 1}
- button .mult.done -text "Done" -command {destroy .mult; set choose_multisession 1}
-
- pack .mult.done .mult.cancel .mult.c -side bottom -fill x
- pack .mult.f -side top -fill both -expand 1
-
- center_win .mult
- focus .mult.c.e
-}
-
-proc ts_xlogin_dialog {} {
-
- toplev .xlog
- wm title .xlog "X Login Greeter"
-
- set h 33
- if [small_height] {
- set h 28
- }
- scroll_text .xlog.f 80 $h
-
- global ts_xlogin
-
- set msg {
- If you have root (sudo(1)) permission on the remote machine, you
- can have x11vnc try to connect to a X display(s) that has No One
- Logged In Yet. This is most likely the login greeter running on
- the Physical console. sudo(1) is used to run x11vnc with FD_XDM=1.
-
- This is different from tsvnc's regular Terminal Services mode where
- usually a virtual (RAM only, e.g. Xvfb) X server used. With this option
- it is the physical graphics hardware that will be connected to.
-
- Note that if your user is ALREADY logged into the physical display,
- you don't need to use this X Login option because x11vnc should find
- it in its normal find-display procedure and not need sudo(1).
-
- An initial ssh running 'sudo id' is performed to try to 'prime'
- sudo so the 2nd one that runs x11vnc does not need a password.
- This may not always succeed...
-
- Note that if someone is already logged into the display console
- via XDM (GDM, KDM etc.) you will see and control their X session.
-
- Otherwise, you will get the Greeter X login screen where you can
- log in via username and password. Your SSVNC 'Terminal Services'
- Desktop Type, Size, Printing etc. settings will be ignored in this
- case of course because XDM, GDM, or KDM is creating your X session,
- not x11vnc.
-
- Note that the GDM display manager has a setting KillInitClients in
- gdm.conf that will kill x11vnc right after you log in, and so you would
- have to repeat the whole process ('Connect' button) to attach to your
- session. See http://www.karlrunge.com/x11vnc/faq.html#faq-display-manager
- for more info.
-}
- .xlog.f.t insert end $msg
-
- button .xlog.cancel -text "Cancel" -command {destroy .xlog; set ts_xlogin 0}
- bind .xlog <Escape> {destroy .xlog; set ts_xlogin 0}
- wm protocol .xlog WM_DELETE_WINDOW {destroy .xlog; set ts_xlogin 0}
-
- button .xlog.done -text "Done" -command {destroy .xlog; set ts_xlogin 1}
-
- pack .xlog.done .xlog.cancel -side bottom -fill x
- pack .xlog.f -side top -fill both -expand 1
-
- center_win .xlog
-}
-
-
-proc ts_othervnc_dialog {} {
-
- toplev .ovnc
- wm title .ovnc "Other VNC Server"
-
- scroll_text .ovnc.f 80 21
-
- global ts_othervnc choose_othervnc
-
- set msg {
- The x11vnc program running on the remote machine can be instructed to
- immediately redirect to some other (3rd party, e.g. Xvnc or vnc.so)
- VNC server.
-
- It should be a little faster to have x11vnc forward the VNC protocol
- rather than having it poll the corresponding X server for changes
- in the way it normally does and translate to VNC.
-
- This mode also enables a simple way to add SSL or find X display
- support to a 3rd party VNC Server lacking these features.
-
- In the entry box put the other vnc display, e.g. "localhost:0" or
- "somehost:5".
-
- The string "find" in the entry will have x11vnc try to find an X
- display in its normal way, and then redirect to the corresponding VNC
- server port. This assumes if the X display is, say, :2 (i.e. port
- 6002) then the VNC display is also :2 (i.e. port 5902). This mode is
- the same as an "X Server Type" of "Xvnc.redirect" (and overrides it).
-}
- .ovnc.f.t insert end $msg
-
- frame .ovnc.c
- label .ovnc.c.l -anchor w -text "Other VNC Server:"
- entry .ovnc.c.e -width 20 -textvariable ts_othervnc
- pack .ovnc.c.l -side left
- pack .ovnc.c.e -side left -expand 1 -fill x
-
- button .ovnc.cancel -text "Cancel" -command {destroy .ovnc; set choose_othervnc 0}
- bind .ovnc <Escape> {destroy .ovnc; set choose_othervnc 0}
- wm protocol .ovnc WM_DELETE_WINDOW {destroy .ovnc; set choose_othervnc 0}
- button .ovnc.done -text "Done" -command {destroy .ovnc; set choose_othervnc 1}
- bind .ovnc.c.e <Return> {destroy .ovnc; set choose_othervnc 1}
-
- if {$ts_othervnc == ""} {
- set ts_othervnc "find"
- }
-
- pack .ovnc.done .ovnc.cancel .ovnc.c -side bottom -fill x
- pack .ovnc.f -side top -fill both -expand 1
-
- center_win .ovnc
- focus .ovnc.c.e
-}
-
-proc ts_sleep_dialog {} {
-
- toplev .eslp
- wm title .eslp "Extra Sleep"
-
- scroll_text .eslp.f 80 5
-
- global extra_sleep
-
- set msg {
- Sleep: Enter a number to indicate how many extra seconds to sleep
- while waiting for the VNC viewer to start up. On Windows this
- can give extra time to enter the Putty/Plink password, etc.
-}
- .eslp.f.t insert end $msg
-
- frame .eslp.c
- label .eslp.c.l -anchor w -text "Extra Sleep:"
- entry .eslp.c.e -width 20 -textvariable extra_sleep
- pack .eslp.c.l -side left
- pack .eslp.c.e -side left -expand 1 -fill x
-
- button .eslp.cancel -text "Cancel" -command {destroy .eslp; set choose_sleep 0}
- bind .eslp <Escape> {destroy .eslp; set choose_sleep 0}
- wm protocol .eslp WM_DELETE_WINDOW {destroy .eslp; set choose_sleep 0}
- button .eslp.done -text "Done" -command {destroy .eslp; set choose_sleep 1}
- bind .eslp.c.e <Return> {destroy .eslp; set choose_sleep 1}
-
- global choose_sleep
- if {! $choose_sleep} {
- set extra_sleep ""
- }
-
- pack .eslp.done .eslp.cancel .eslp.c -side bottom -fill x
- pack .eslp.f -side top -fill both -expand 1
-
- center_win .eslp
- focus .eslp.c.e
-}
-
-proc ts_putty_args_dialog {} {
-
- toplev .parg
- wm title .parg "Putty Args"
-
- scroll_text .parg.f 80 5
-
- global putty_args
-
- set msg {
- Putty Args: Enter a string to be added to every plink.exe and putty.exe
- command line. For example: -i C:\mykey.ppk
-}
- .parg.f.t insert end $msg
-
- frame .parg.c
- label .parg.c.l -anchor w -text "Putty Args:"
- entry .parg.c.e -width 20 -textvariable putty_args
- pack .parg.c.l -side left
- pack .parg.c.e -side left -expand 1 -fill x
-
- button .parg.cancel -text "Cancel" -command {destroy .parg; set choose_parg 0}
- bind .parg <Escape> {destroy .parg; set choose_parg 0}
- wm protocol .parg WM_DELETE_WINDOW {destroy .parg; set choose_parg 0}
- button .parg.done -text "Done" -command {destroy .parg; set choose_parg 1}
- bind .parg.c.e <Return> {destroy .parg; set choose_parg 1}
-
- global choose_parg
- if {! $choose_parg} {
- set putty_args ""
- }
-
- pack .parg.done .parg.cancel .parg.c -side bottom -fill x
- pack .parg.f -side top -fill both -expand 1
-
- center_win .parg
- focus .parg.c.e
-}
-
-proc ts_ncache_dialog {} {
-
- toplev .nche
- wm title .nche "Client-Side Caching"
-
- scroll_text .nche.f 80 22
-
- global ts_ncache choose_ncache
-
- set msg {
- This enables the *experimental* x11vnc client-side caching mode.
- It often gives nice speedups, but can sometimes lead to painting
- errors or window "flashing". (you can repaint the screen by tapping
- the Left Alt key 3 times in a row)
-
- It is a very simple but hoggy method: uncompressed image pixmaps are
- stored in the viewer in a large (20-100MB) display region beneath
- the actual display screen. You may need also to adjust your VNC Viewer
- to not show this region (the SSVNC Unix viewer does it automatically).
-
- The scheme uses a lot of RAM, but at least it has the advantage that
- it works with every VNC Viewer. Otherwise the VNC protocol would
- need to be modified, changing both the server and the viewer.
-
- Set the x11vnc "-ncache" parameter to an even integer between 2
- and 20. This is the increase in area factor over the normal screen
- for the caching region. So 10 means use 10 times the RAM to store
- pixmaps. The default is 8.
-
- More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching
-}
- .nche.f.t insert end $msg
-
- frame .nche.c
- label .nche.c.l -anchor w -text "ncache:"
- radiobutton .nche.c.r2 -text "2" -variable ts_ncache -value "2"
- radiobutton .nche.c.r4 -text "4" -variable ts_ncache -value "4"
- radiobutton .nche.c.r6 -text "6" -variable ts_ncache -value "6"
- radiobutton .nche.c.r8 -text "8" -variable ts_ncache -value "8"
- radiobutton .nche.c.r10 -text "10" -variable ts_ncache -value "10"
- radiobutton .nche.c.r12 -text "12" -variable ts_ncache -value "12"
- radiobutton .nche.c.r14 -text "14" -variable ts_ncache -value "14"
- radiobutton .nche.c.r16 -text "16" -variable ts_ncache -value "16"
- radiobutton .nche.c.r18 -text "18" -variable ts_ncache -value "18"
- radiobutton .nche.c.r20 -text "20" -variable ts_ncache -value "20"
- pack .nche.c.l -side left
- pack .nche.c.r2 .nche.c.r4 .nche.c.r6 .nche.c.r8 .nche.c.r10 \
- .nche.c.r12 .nche.c.r14 .nche.c.r16 .nche.c.r18 .nche.c.r20 -side left
- button .nche.cancel -text "Cancel" -command {destroy .nche; set choose_ncache 0}
- bind .nche <Escape> {destroy .nche; set choose_ncache 0}
- wm protocol .nche WM_DELETE_WINDOW {destroy .nche; set choose_ncache 0}
- button .nche.done -text "Done" -command {destroy .nche; set choose_ncache 1}
-
- pack .nche.done .nche.cancel .nche.c -side bottom -fill x
- pack .nche.f -side top -fill both -expand 1
-
- center_win .nche
-}
-
-proc ts_x11vnc_opts_dialog {} {
-
- toplev .x11v
- wm title .x11v "x11vnc Options"
-
- set h 23
- if [small_height] {
- set h 21
- }
- scroll_text .x11v.f 80 $h
-
- global ts_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport choose_x11vnc_opts
- global additional_port_redirs_list
-
- set msg {
- If you are an expert with x11vnc's endless options and tweaking
- parameters feel free to specify any you want here in "Options".
-
- Also, if you need to specify the path to the x11vnc program on the
- remote side because it will not be in $PATH, put it in the "Full
- Path" entry.
-
- Port Redirs are additional SSH "-L port:host:port" or "-R port:host:port"
- (forward or reverse, resp.) port redirections you want. In SSVNC mode,
- see the detailed description under: Options -> Advanced -> Port Redirs.
-
- Some potentially useful options:
-
- -solid -scale -scale_cursor
- -passwd -rfbauth -http
- -xrandr -rotate -noxdamage
- -xkb -skip_lockkeys -nomodtweak
- -repeat -cursor -wmdt
- -nowireframe -ncache_cr -speeds
-
- More info: http://www.karlrunge.com/x11vnc/faq.html#faq-cmdline-opts
-}
-# In Auto Port put a starting port for x11vnc to try autoprobing
-# instead of the default 5900. It starts at the value you supply and
-# works upward until a free one is found. (x11vnc 0.9.3 or later).
-
- .x11v.f.t insert end $msg
-
- frame .x11v.c
- label .x11v.c.l -width 10 -anchor w -text "Options:"
- entry .x11v.c.e -textvariable ts_x11vnc_opts
- pack .x11v.c.l -side left
- pack .x11v.c.e -side left -expand 1 -fill x
-
- frame .x11v.c2
- label .x11v.c2.l -width 10 -anchor w -text "Full Path:"
- entry .x11v.c2.e -textvariable ts_x11vnc_path
- pack .x11v.c2.l -side left
- pack .x11v.c2.e -side left -expand 1 -fill x
-
-# frame .x11v.c3
-# label .x11v.c3.l -width 10 -anchor w -text "Auto Port:"
-# entry .x11v.c3.e -textvariable ts_x11vnc_autoport
-# pack .x11v.c3.l -side left
-# pack .x11v.c3.e -side left -expand 1 -fill x
-
- frame .x11v.c4
- label .x11v.c4.l -width 10 -anchor w -text "Port Redirs:"
- entry .x11v.c4.e -textvariable additional_port_redirs_list
- pack .x11v.c4.l -side left
- pack .x11v.c4.e -side left -expand 1 -fill x
-
- button .x11v.cancel -text "Cancel" -command {destroy .x11v; set choose_x11vnc_opts 0}
- bind .x11v <Escape> {destroy .x11v; set choose_x11vnc_opts 0}
- wm protocol .x11v WM_DELETE_WINDOW {destroy .x11v; set choose_x11vnc_opts 0}
- button .x11v.done -text "Done" -command {destroy .x11v; set choose_x11vnc_opts 1;
- if {$additional_port_redirs_list != ""} {set additional_port_redirs 1} else {set additional_port_redirs 0}}
-
-# pack .x11v.done .x11v.cancel .x11v.c4 .x11v.c3 .x11v.c2 .x11v.c -side bottom -fill x
- pack .x11v.done .x11v.cancel .x11v.c4 .x11v.c2 .x11v.c -side bottom -fill x
- pack .x11v.f -side top -fill both -expand 1
-
- center_win .x11v
- focus .x11v.c.e
-}
-
-
-proc ts_filexfer_dialog {} {
-
- toplev .xfer
- wm title .xfer "File Transfer"
- global choose_filexfer ts_filexfer
-
- scroll_text .xfer.f 70 13
-
- set msg {
- x11vnc supports both the UltraVNC and TightVNC file transfer
- extensions. On Windows both viewers support their file transfer
- protocol. On Unix only the SSVNC VNC Viewer can do filexfer; it
- supports the UltraVNC flavor via a Java helper program (and so
- java(1) is required on the viewer-side).
-
- Choose the one you want based on VNC viewer you will use.
- The defaults for the SSVNC viewer package are TightVNC on
- Windows and UltraVNC on Unix.
-
- For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-filexfer
-}
- .xfer.f.t insert end $msg
-
- global is_windows
- if {$ts_filexfer == ""} {
- if {$is_windows} {
- set ts_filexfer "tight"
- } else {
- set ts_filexfer "ultra"
- }
- }
-
- frame .xfer.c
- radiobutton .xfer.c.tight -text "TightVNC" -variable ts_filexfer -value "tight" -relief ridge
- radiobutton .xfer.c.ultra -text "UltraVNC" -variable ts_filexfer -value "ultra" -relief ridge
-
- pack .xfer.c.ultra .xfer.c.tight -side left -fill x -expand 1
-
- button .xfer.cancel -text "Cancel" -command {destroy .xfer; set choose_filexfer 0}
- bind .xfer <Escape> {destroy .xfer; set choose_filexfer 0}
- wm protocol .xfer WM_DELETE_WINDOW {destroy .xfer; set choose_filexfer 0}
- button .xfer.done -text "Done" -command {destroy .xfer; set choose_filexfer 1}
-
- pack .xfer.done .xfer.cancel -side bottom -fill x
- pack .xfer.c -side bottom -fill x -expand 1
- pack .xfer.f -side top -fill both -expand 1
-
- center_win .xfer
-}
-
-proc ts_cups_dialog {} {
-
- toplev .cups
- wm title .cups "CUPS and SMB Printing"
- global cups_local_server cups_remote_port cups_manage_rcfile ts_cups_manage_rcfile cups_x11vnc
- global cups_local_smb_server cups_remote_smb_port
-
- set h 30
- if [small_height] {
- set h 24
- }
- scroll_text .cups.f 80 $h
-
-
- set msg {
- This method requires a working CUPS Desktop setup on the remote side
- of the connection and working CUPS (or possibly Windows SMB or IPP)
- printing on the local viewer-side of the connection.
-
- For CUPS printing redirection to work properly, you MUST enable it for
- the connection that *creates* your terminal services X session (i.e. the
- first connection.) You cannot retroactively enable CUPS redirection
- on an already existing terminal services X session. (See CUPS printing
- for normal SSVNC mode for how you might do that.)
-
- Enter the VNC Viewer side (i.e. where you are sitting) CUPS server
- under "Local CUPS Server". Use "localhost:631" if there is one
- on your viewer machine (normally the case if you set up a printer
- on your unix or macosx system), or, e.g., "my-print-srv:631" for a
- nearby CUPS print server. Note that 631 is the default CUPS port.
-
- (On MacOSX it seems better to use "127.0.0.1" instead of "localhost".)
-
- The SSVNC Terminal Services created remote Desktop session will have
- the variables CUPS_SERVER and IPP_PORT set so all printing applications
- will be redirected to your local CUPS server. So your locally available
- printers should appear in the remote print dialogs.
-
-
- Windows/SMB Printers: Under "Local SMB Print Server" you can set a
- port redirection for a Windows (non-CUPS) SMB printer. If localhost:139
- does not work, try the literal string "IP:139", or use the known value
- of the IP address manually. 139 is the default SMB port; nowadays 445
- might be a better possibility.
-
- For Windows/SMB Printers if there is no local CUPS print server, it is
- usually a very good idea to make the CUPS Server setting EMPTY (to avoid
- desktop apps trying incessantly to reach the nonexistent CUPS server.)
-
- On the remote side, in the Desktop session the variables $SMB_SERVER,
- $SMB_HOST, and $SMB_PORT will be set for you to use.
-
- Unfortunately, printing to Windows may only ve partially functional due
- to the general lack PostScript support on Windows.
-
- If you have print admin permission on the remote machine you can
- configure CUPS to know about your Windows printer via lpadmin(8) or
- a GUI tool. You give it the URI:
-
- smb://localhost:port/printername
-
- or possibly:
-
- smb://localhost:port/computer/printername
-
- "port" will be found in the $SMB_PORT. You also need to identify
- the printer type. NOTE: You will leave "Local CUPS Server" blank in
- this case. The smbspool(1) command should also work as well, at least
- for PostScript printers.
-
- A similar thing can be done with CUPS printers if you are having problems
- with the above default mechanism. Use
-
- http://localhost:port/printers/printername
-
- For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-cups
-}
-
-# The "Manage 'ServerName' in .cups/client.conf for me" setting is usually
-# NOT needed unless you are using Terminal Services to connect to an
-# existing Session that did NOT have CUPS print redirection set at session
-# start time (i.e. IPP_PORT and CUPS_SERVER were not set up). In that
-# case, select this option as a workaround: NOTE that the client.conf
-# setting will REDIRECT ALL PRINTING for apps with the same $HOME/.cups
-# directory (which you probably do not want), however it will be reset
-# when the SSVNC viewer disconnects.
-
- .cups.f.t insert end $msg
-
- global uname
- if {$cups_local_server == ""} {
- if {$uname == "Darwin"} {
- set cups_local_server "127.0.0.1:631"
- } else {
- set cups_local_server "localhost:631"
- }
- }
- if {$cups_remote_port == ""} {
- set cups_remote_port [expr "6731 + int(1000 * rand())"]
- }
- if {$cups_local_smb_server == ""} {
- global is_windows
- if {$is_windows} {
- set cups_local_smb_server "IP:139"
- } elseif {$uname == "Darwin"} {
- set cups_local_smb_server "127.0.0.1:139"
- } else {
- set cups_local_smb_server "localhost:139"
- }
- }
- if {$cups_remote_smb_port == ""} {
- set cups_remote_smb_port [expr "7731 + int(1000 * rand())"]
- }
-
- frame .cups.serv
- label .cups.serv.l -anchor w -text "Local CUPS Server: "
- entry .cups.serv.e -width 40 -textvariable cups_local_server
- pack .cups.serv.e -side right
- pack .cups.serv.l -side left -expand 1 -fill x
-
- frame .cups.smbs
- label .cups.smbs.l -anchor w -text "Local SMB Print Server: "
- entry .cups.smbs.e -width 40 -textvariable cups_local_smb_server
- pack .cups.smbs.e -side right
- pack .cups.smbs.l -side left -expand 1 -fill x
-
- # not working with x11vnc:
- checkbutton .cups.cupsrc -anchor w -variable ts_cups_manage_rcfile -text \
- "Manage 'ServerName' in the remote \$HOME/.cups/client.conf file for me"
-
- button .cups.cancel -text "Cancel" -command {destroy .cups; set use_cups 0}
- bind .cups <Escape> {destroy .cups; set use_cups 0}
- wm protocol .cups WM_DELETE_WINDOW {destroy .cups; set use_cups 0}
- button .cups.done -text "Done" -command {destroy .cups; if {$use_cups} {set_ssh}}
-
- pack .cups.done .cups.cancel .cups.smbs .cups.serv -side bottom -fill x
- pack .cups.f -side top -fill both -expand 1
-
- center_win .cups
- focus .cups.serv.e
-}
-
-
-proc cups_dialog {} {
-
- toplev .cups
- wm title .cups "CUPS Tunnelling"
- global cups_local_server cups_remote_port cups_manage_rcfile cups_x11vnc
- global cups_local_smb_server cups_remote_smb_port
- global ts_only
- if {$ts_only} {
- ts_cups_dialog
- return
- }
-
- global uname
- set h 33
- if [small_height] {
- set h 17
- } elseif {$uname == "Darwin"} {
- set h 24
- }
- scroll_text .cups.f 80 $h
-
-
- set msg {
- CUPS Printing requires SSH be used to set up the CUPS Print service TCP
- port redirection. This will be either of the "Use SSH" or "SSH+SSL" modes.
- NOTE: For pure SSL tunnelling it currently will not work.
-
- This method requires working CUPS software setups on BOTH the remote
- and local sides of the connection.
-
- If the remote VNC server is Windows you probably cannot SSH into it
- anyway... If you can, you will still need to set up a special printer
- TCP port redirection on your own. Perhaps adding and configuring a
- "Unix Printer" under Windows (like Method #2 below) will work.
-
- If the local machine (SSVNC side) is Windows, see the bottom of this
- help for redirecting to SMB printers.
-
- If the remote VNC server is Mac OS X this method may or may not work.
- Sometimes applications need to be restarted to get them to notice the
- new printers. Adding and configuring a special "Unix Printer",
- (Method #2) below, might yield more reliable results at the cost of
- additional setup and permissions.
-
- For Unix/Linux remote VNC servers, applications may also need to be
- restarted to notice the new printers. The only case known to work
- well is the one where the remote side has no CUPS printers configured.
- As mentioned above, see Method #2 for another method.
-
- *************************************************************************
- *** Directions:
-
- You choose your own remote CUPS redir port below under "Use Remote
- CUPS Port". 6631 is our default and is used in the examples below.
- Use it or some random value greater than 1024. Note that the standard
- CUPS server port is 631.
-
- The port you choose must be unused on the VNC server machine (it is NOT
- checked for you). Print requests connecting to it are redirected to
- your local VNC viewer-side CUPS server through the SSH tunnel.
-
- (Note: root SSH login permission is needed for ports less than 1024,
- e.g. 631; this is not recommended, use something around 6631 instead).
-
- Then enter the VNC Viewer side (i.e. where you are sitting) CUPS server
- into "Local CUPS Server". A good choice is the default "localhost:631"
- if there is a cups server on your viewer machine (this is usually the case
- if you have set up a printer). Otherwise enter, e.g., "my-print-srv:631"
- for your nearby (viewer-side) CUPS print server.
-
-
- The "Manage 'ServerName' in the $HOME/.cups/client.conf file for me"
- setting below is enabled by default. It should handle most situations.
-
- What it does is modify the .cups/client.conf file on the VNC server-side
- to redirect the print requests while the SSVNC viewer is connected. When
- SSVNC disconnects .cups/client.conf is restored to its previous setting.
-
- If, for some reason, the SSVNC CUPS script fails to restore this file
- after SSVNC disconnects, run this command on the remote machine:
-
- cp $HOME/.cups/client.conf.back $HOME/.cups/client.conf
-
- to regain your initial printing configuration.
-
-
- You can also use CUPS on the VNC server-side to redirect to Windows
- (SMB) printers. See the additional info for Windows Printing at the
- bottom of this help.
-
-
- In case the default method (automatic .cups/client.conf modification)
- fails, we describe below all of the possible methods that can be tried.
-
- As noted above, you may need to restart applications for them to notice
- the new printers or for them to revert to the original printers. If this
- is not acceptable, consider Method #2 below if you have the permission
- and ability to alter the print queues for this.
-
-
- *************************************************************************
- *** Method #1: Manually create or edit the file $HOME/.cups/client.conf
- on the VNC server side by putting in something like this in it:
-
- ServerName localhost:6631
-
- based on the port you set in this dialog's entry box.
-
- After the remote VNC Connection is finished, to go back to the non-SSH
- tunnelled CUPS server and either remove the client.conf file or comment
- out the ServerName line. This restores the normal CUPS server for
- you on the remote VNC server machine.
-
- Select "Manage 'ServerName' in the $HOME/.cups/client.conf file for me"
- to do this editing of the VNC server-side CUPS config file for you
- automatically. NOTE: It is now on by default (deselect it if you want
- to manage the file manually; e.g. you print through the tunnel only very
- rarely, or often print locally when the tunnel is up, etc.)
-
- Select "Pass -env FD_CUPS=<Port> to x11vnc command line" if you are
- starting x11vnc as the Remote SSH Command, and x11vnc is running in
- -create mode (i.e. FINDCREATEDISPLAY). That way, when your X session
- is created IPP_PORT will be set correctly for the entire session.
- This is the mode used for 'Terminal Services' printing.
-
- NOTE: You probably would never select both of the above two options
- at the same time, since they conflict with each other to some degree.
-
-
- *************************************************************************
- *** Method #2: If you have admin permission on the VNC Server machine
- you can likely "Add a Printer" via a GUI dialog, a Wizard, CUPS Web
- interface (i.e. http://localhost:631/), lpadmin(8), etc.
-
- You will need to tell the dialog that the network printer located
- is at, e.g., localhost:6631, and anything else needed to identify
- the printer (type, model, etc). NOTE: sometimes it is best to set
- the model/type as "Generic / Postscript Printer" to avoid problems
- with garbage being printed out.
-
- For the URI to use, we have successfully used ones like this with CUPS:
-
- http://localhost:6631/printers/Deskjet-3840
- ipp://localhost:6631/printers/Deskjet-3840
-
- for an HP Deskjet-3840 printer. See the CUPS documentation for more
- about the URI syntax and pathname.
-
- This mode makes the client.conf ServerName parameter unnecessary
- (BE SURE TO DISABLE the "Manage 'ServerName' ... for me" option.)
-
-
- *************************************************************************
- *** Method #3: Restarting individual applications with the IPP_PORT
- set will enable redirected printing for them, e.g.:
-
- env IPP_PORT=6631 firefox
-
- If you can only get this method to work, an extreme application would
- be to run the whole desktop, e.g. "env IPP_PORT=6631 gnome-session", but
- then you would need some sort of TCP redirector (ssh -L comes to mind),
- to direct it to 631 when not connected remotely.
-
-
- *************************************************************************
- *** Windows/SMB Printers: Under "Local SMB Print Server" you can set
- a port redirection for a Windows (non-CUPS) SMB printer. E.g. port
- 6632 -> localhost:139.
-
- If localhost:139 does not work, try the literal string "IP:139", or
- insert the actual IP address manually. NOTE: Nowadays on Windows port
- 445 might be a better choice.
-
- For Windows printers, if there is no local CUPS print server, set the
- 'Local CUPS Server' and 'Use Remote CUPS Port' to be EMPTY (to avoid
- desktop apps trying incessantly to reach the nonexistent CUPS server.)
-
- You must enable Sharing for your local Windows Printer. Use Windows
- Printer configuration dialogs to do this.
-
- Next, you need to have sudo or print admin permission so that you can
- configure the *remote* CUPS to know about this Windows printer via
- lpadmin(8) or GUI Printer Configuration dialog, etc (Method #2 above).
- You basically give it the URI:
-
- smb://localhost:6632/printername
-
- For example, we have had success with GNOME CUPS printing configuration
- using:
-
- smb://localhost:6632/HPOffice
- smb://localhost:6632/COMPUTERNAME/HPOffice
-
- where "HPOffice" was the name Windows shares the printer as.
-
- Also with this SMB port redir mode, as a last resort you can often print
- using the smbspool(8) program like this:
-
- smbspool smb://localhost:6632/printer job user title 1 "" myfile.ps
-
- You could put this in a script. For this URI, it appears only the number
- of copies ("1" above) and the file itself are important.
-
- If on the local (SSVNC viewer) side there is some nearby CUPS print server
- that knows about your Windows printer, you might have better luck with
- that instead of using SMB. Set 'Local CUPS Server' to it.
-
- For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-cups
-}
- .cups.f.t insert end $msg
-
- global uname
- set something_set 0
-
- if {$cups_local_server != ""} {
- set something_set 1
- }
- if {$cups_local_smb_server != ""} {
- set something_set 1
- }
-
- if {$cups_local_server == "" && ! $something_set} {
- if {$uname == "Darwin"} {
- set cups_local_server "127.0.0.1:631"
- } else {
- set cups_local_server "localhost:631"
- }
- }
- if {$cups_remote_port == "" && ! $something_set} {
- set cups_remote_port "6631"
- }
- if {$cups_local_smb_server == "" && ! $something_set} {
- global is_windows
- if {$is_windows} {
- set cups_local_smb_server "IP:139"
- } elseif {$uname == "Darwin"} {
- set cups_local_smb_server "127.0.0.1:139"
- } else {
- set cups_local_smb_server "localhost:139"
- }
- }
- if {$cups_remote_smb_port == "" && ! $something_set} {
- set cups_remote_smb_port "6632"
- }
-
- frame .cups.serv
- label .cups.serv.l -anchor w -text "Local CUPS Server: "
- entry .cups.serv.e -width 40 -textvariable cups_local_server
- pack .cups.serv.e -side right
- pack .cups.serv.l -side left -expand 1 -fill x
-
- frame .cups.port
- label .cups.port.l -anchor w -text "Use Remote CUPS Port:"
- entry .cups.port.e -width 40 -textvariable cups_remote_port
- pack .cups.port.e -side right
- pack .cups.port.l -side left -expand 1 -fill x
-
- frame .cups.smbs
- label .cups.smbs.l -anchor w -text "Local SMB Print Server: "
- entry .cups.smbs.e -width 40 -textvariable cups_local_smb_server
- pack .cups.smbs.e -side right
- pack .cups.smbs.l -side left -expand 1 -fill x
-
- frame .cups.smbp
- label .cups.smbp.l -anchor w -text "Use Remote SMB Print Port:"
- entry .cups.smbp.e -width 40 -textvariable cups_remote_smb_port
- pack .cups.smbp.e -side right
- pack .cups.smbp.l -side left -expand 1 -fill x
-
- checkbutton .cups.cupsrc -anchor w -variable cups_manage_rcfile -text \
- "Manage 'ServerName' in the remote \$HOME/.cups/client.conf file for me"
-
- checkbutton .cups.x11vnc -anchor w -variable cups_x11vnc -text \
- "Pass -env FD_CUPS=<Port> to x11vnc command line."
-
- button .cups.cancel -text "Cancel" -command {destroy .cups; set use_cups 0}
- bind .cups <Escape> {destroy .cups; set use_cups 0}
- wm protocol .cups WM_DELETE_WINDOW {destroy .cups; set use_cups 0}
- button .cups.done -text "Done" -command {destroy .cups; if {$use_cups} {set_ssh}}
-
- button .cups.guess -text "Help me decide ..." -command {}
- .cups.guess configure -state disabled
-
- pack .cups.done .cups.cancel .cups.guess .cups.x11vnc .cups.cupsrc .cups.smbp .cups.smbs .cups.port .cups.serv -side bottom -fill x
- pack .cups.f -side top -fill both -expand 1
-
- center_win .cups
- focus .cups.serv.e
-}
-
-proc ts_sound_dialog {} {
-
- global is_windows
- global ts_only
-
- toplev .snd
- wm title .snd "Sound Tunnelling"
-
- scroll_text .snd.f 80 21
-
- set msg {
- Your remote Desktop will be started in an Enlightenment Sound Daemon
- (ESD) environment (esddsp(1), which must be installed on the remote
- machine), and a local ESD sound daemon (esd(1)) will be started to
- play the sounds for you to hear.
-
- In the entry box below you can choose the port that the local esd
- will use to listen on. The default ESD port is 16001. You will
- need to choose different values if you will have more than one esd
- running locally.
-
- The command run (with port replaced by your choice) will be:
-
- %RCMD
-
- Note: Unfortunately not all applications work with ESD.
- And esd's LD_PRELOAD is broken on 64+32bit Linux (x86_64).
- And so this mode is not working well currently...
-
- For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-sound
-}
-
-
- global sound_daemon_remote_port sound_daemon_local_port sound_daemon_local_cmd
- global sound_daemon_local_start sound_daemon_local_kill
-
- set sound_daemon_local_start 1
- set sound_daemon_local_kill 1
-
- if {$sound_daemon_remote_port == ""} {
- set sound_daemon_remote_port 16010
- }
- if {$sound_daemon_local_port == ""} {
- set sound_daemon_local_port 16010
- }
-
- if {$sound_daemon_local_cmd == ""} {
- global is_windows
- if {$is_windows} {
- set sound_daemon_local_cmd {esound\esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
- } else {
- set sound_daemon_local_cmd {esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
- }
- }
- regsub {%PORT} $sound_daemon_local_cmd $sound_daemon_local_port sound_daemon_local_cmd
-
- regsub {%RCMD} $msg $sound_daemon_local_cmd msg
- .snd.f.t insert end $msg
-
- frame .snd.lport
- label .snd.lport.l -anchor w -text "Local Sound Port: "
- entry .snd.lport.e -width 45 -textvariable sound_daemon_local_port
- pack .snd.lport.e -side right
- pack .snd.lport.l -side left -expand 1 -fill x
-
- button .snd.cancel -text "Cancel" -command {destroy .snd; set use_sound 0}
- bind .snd <Escape> {destroy .snd; set use_sound 0}
- wm protocol .snd WM_DELETE_WINDOW {destroy .snd; set use_sound 0}
- button .snd.done -text "Done" -command {destroy .snd; if {$use_sound} {set_ssh}}
- bind .snd.lport.e <Return> {destroy .snd; if {$use_sound} {set_ssh}}
-
- pack .snd.done .snd.cancel .snd.lport -side bottom -fill x
- pack .snd.f -side bottom -fill both -expand 1
-
- center_win .snd
- focus .snd.lport.e
-}
-
-proc sound_dialog {} {
-
- global is_windows
- global ts_only
- if {$ts_only} {
- ts_sound_dialog;
- return
- }
-
- toplev .snd
- wm title .snd "ESD/ARTSD Sound Tunnelling"
-
- global uname
- set h 28
- if [small_height] {
- set h 14
- } elseif {$uname == "Darwin"} {
- set h 20
- }
- scroll_text .snd.f 80 $h
-
- set msg {
- Sound tunnelling to a sound daemon requires SSH be used to set up the
- service port redirection. This will be either of the "Use SSH" or
- "SSH+SSL" modes. NOTE: For pure SSL tunnelling it currently will not work.
-
- This method requires working Sound daemon (e.g. ESD or ARTSD) software
- setups on BOTH the remote and local sides of the connection.
-
- Often this means you want to run your ENTIRE remote desktop with ALL
- applications instructed to use the sound daemon's network port. E.g.
-
- esddsp -s localhost:16001 startkde
- esddsp -s localhost:16001 gnome-session
-
- and similarly for artsdsp, etc. You put this in your ~/.xession,
- or other startup file. This is non standard. If you do not want to
- do this you still can direct *individual* sound applications through
- the tunnel, for example "esddsp -s localhost:16001 soundapp", where
- "soundapp" is some application that makes noise (say xmms or mpg123).
-
- Select "Pass -env FD_ESD=<Port> to x11vnc command line." if you are
- starting x11vnc as the Remote SSH Command, and x11vnc is running in
- -create mode (i.e. FINDCREATEDISPLAY). That way, your X session is
- started via "esddsp -s ... <session>" and the ESD variables will be
- set correctly for the entire session. (This mode make most sense for
- a virtual, e.g. Xvfb or Xdummy session, not one a physical display).
-
- Also, usually the remote Sound daemon must be killed BEFORE the SSH port
- redir is established (because it is listening on the port we want to use
- for the SSH redir), and, presumably, restarted when the VNC connection
- finished.
-
- One may also want to start and kill a local sound daemon that will
- play the sound received over the network on the local machine.
-
- You can indicate the remote and local Sound daemon commands below and
- how they should be killed and/or restart. Some examples:
-
- esd -promiscuous -as 5 -port 16001 -tcp -bind 127.0.0.1
- artsd -n -p 7265 -F 10 -S 4096 -n -s 5 -m artsmessage -l 3 -f
-
- or you can leave some or all blank and kill/start them manually.
-
- For convenience, a Windows port of ESD is provided in the util/esound
- directory, and so this might work for a Local command:
-
- esound\esd -promiscuous -as 5 -port 16001 -tcp -bind 127.0.0.1
-
- NOTE: If you indicate "Remote Sound daemon: Kill at start." below,
- then THERE WILL BE TWO SSH'S: THE FIRST ONE TO KILL THE DAEMON.
- So you may need to supply TWO SSH PASSWORDS, unless you are using
- something like ssh-agent(1), the Putty PW setting, etc.
-
- You will also need to supply the remote and local sound ports for
- the SSH redirs. For esd the default port is 16001, but you can choose
- another one if you prefer.
-
- For "Local Sound Port" you can also supply "host:port" instead of just
- a numerical port to specify non-localhost connections, e.g. to another
- nearby machine.
-
- For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-sound
-}
- .snd.f.t insert end $msg
-
- global sound_daemon_remote_port sound_daemon_local_port sound_daemon_local_cmd
- if {$sound_daemon_remote_port == ""} {
- set sound_daemon_remote_port 16001
- }
- if {$sound_daemon_local_port == ""} {
- set sound_daemon_local_port 16001
- }
-
- if {$sound_daemon_local_cmd == ""} {
- global is_windows
- if {$is_windows} {
- set sound_daemon_local_cmd {esound\esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
- } else {
- set sound_daemon_local_cmd {esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
- }
- regsub {%PORT} $sound_daemon_local_cmd $sound_daemon_local_port sound_daemon_local_cmd
- }
-
-
- frame .snd.remote
- label .snd.remote.l -anchor w -text "Remote Sound daemon cmd: "
- entry .snd.remote.e -width 45 -textvariable sound_daemon_remote_cmd
- pack .snd.remote.e -side right
- pack .snd.remote.l -side left -expand 1 -fill x
-
- frame .snd.local
- label .snd.local.l -anchor w -text "Local Sound daemon cmd: "
- entry .snd.local.e -width 45 -textvariable sound_daemon_local_cmd
- pack .snd.local.e -side right
- pack .snd.local.l -side left -expand 1 -fill x
-
- frame .snd.rport
- label .snd.rport.l -anchor w -text "Remote Sound Port: "
- entry .snd.rport.e -width 45 -textvariable sound_daemon_remote_port
- pack .snd.rport.e -side right
- pack .snd.rport.l -side left -expand 1 -fill x
-
- frame .snd.lport
- label .snd.lport.l -anchor w -text "Local Sound Port: "
- entry .snd.lport.e -width 45 -textvariable sound_daemon_local_port
- pack .snd.lport.e -side right
- pack .snd.lport.l -side left -expand 1 -fill x
-
-
- checkbutton .snd.sdk -anchor w -variable sound_daemon_kill -text \
- "Remote Sound daemon: Kill at start."
-
- checkbutton .snd.sdr -anchor w -variable sound_daemon_restart -text \
- "Remote Sound daemon: Restart at end."
-
- checkbutton .snd.sdsl -anchor w -variable sound_daemon_local_start -text \
- "Local Sound daemon: Run at start."
-
- checkbutton .snd.sdkl -anchor w -variable sound_daemon_local_kill -text \
- "Local Sound daemon: Kill at end."
-
- checkbutton .snd.x11vnc -anchor w -variable sound_daemon_x11vnc -text \
- "Pass -env FD_ESD=<Port> to x11vnc command line."
-
- button .snd.guess -text "Help me decide ..." -command {}
- .snd.guess configure -state disabled
-
- global is_win9x
- if {$is_win9x} {
- .snd.local.e configure -state disabled
- .snd.local.l configure -state disabled
- .snd.sdsl configure -state disabled
- .snd.sdkl configure -state disabled
- }
-
- button .snd.cancel -text "Cancel" -command {destroy .snd; set use_sound 0}
- bind .snd <Escape> {destroy .snd; set use_sound 0}
- wm protocol .snd WM_DELETE_WINDOW {destroy .snd; set use_sound 0}
- button .snd.done -text "Done" -command {destroy .snd; if {$use_sound} {set_ssh}}
-
- pack .snd.done .snd.cancel .snd.guess .snd.x11vnc .snd.sdkl .snd.sdsl .snd.sdr .snd.sdk .snd.lport .snd.rport \
- .snd.local .snd.remote -side bottom -fill x
- pack .snd.f -side bottom -fill both -expand 1
-
- center_win .snd
- focus .snd.remote.e
-}
-
-# Share ideas.
-#
-# Unix:
-#
-# if type smbclient
-# first parse smbclient -L localhost -N
-# and/or smbclient -L `hostname` -N
-# Get Sharenames and Servers and Domain.
-#
-# loop over servers, doing smbclient -L server -N
-# pile this into a huge list, sep by disk and printers.
-#
-# WinXP:
-#
-# parse "NET VIEW" output similarly.
-#
-# Have checkbox for each disk. Set default root to /var/tmp/${USER}-mnts
-# Let them change that at once and have it populate.
-#
-# use //hostname/share /var/tmp/runge-mnts/hostname/share
-#
-#
-# Printers, hmmm. Can't add to remote cups list... I guess have the list
-# ready for CUPS dialog to suggest which SMB servers they want to redirect
-# to...
-
-proc get_hostname {} {
- global is_windows is_win9x
- set str ""
- if {$is_windows} {
- if {1} {
- catch {set str [exec hostname]}
- regsub -all {[\r]} $str "" str
- } else {
- catch {set str [exec net config]}
- if [regexp -nocase {Computer name[ \t]+\\\\([^ \t]+)} $str mv str] {
- ;
- } else {
- set str ""
- }
- }
- } else {
- catch {set str [exec hostname]}
- }
- set str [string trim $str]
- return $str
-}
-
-proc smb_list_windows {smbhost} {
- global smb_local smb_local_hosts smb_this_host
- global is_win9x
- set dbg 0
-
- set domain ""
-
- if {$is_win9x} {
- # exec net view ... doesn't work.
- set smb_this_host "unknown"
- return
- }
-
- set this_host [get_hostname]
- set This_host [string toupper $this_host]
- set smb_this_host $This_host
-
- if {$smbhost == $smb_this_host} {
- catch {set out0 [exec net view]}
- regsub -all {[\r]} $out0 "" out0
- foreach line [split $out0 "\n"] {
- if [regexp -nocase {in workgroup ([^ \t]+)} $line mv wg] {
- regsub -all {[.]} $wg "" wg
- set domain $wg
- } elseif [regexp {^\\\\([^ \t]+)[ \t]*(.*)} $line mv host comment] {
- set smb_local($smbhost:server:$host) $comment
- }
- }
- }
-
- set out1 ""
- set h "\\\\$smbhost"
- catch {set out1 [exec net view $h]}
- regsub -all {[\r]} $out1 "" out1
-
- if {$dbg} {puts "SMBHOST: $smbhost"}
-
- set mode ""
- foreach line [split $out1 "\n"] {
- if [regexp {^[ \t]*---} $line] {
- continue
- }
- if [regexp -nocase {The command} $line] {
- continue
- }
- if [regexp -nocase {Shared resources} $line] {
- continue
- }
- if [regexp -nocase {^[ \t]*Share[ \t]*name} $line] {
- set mode "shares"
- continue
- }
- set line [string trim $line]
- if {$line == ""} {
- continue
- }
- if {$mode == "shares"} {
- if [regexp {^([^ \t]+)[ \t]+([^ \t]+)[ \t]*(.*)$} $line mv name type comment] {
- if {$dbg} {
- puts "SHR: $name"
- puts "---: $type"
- puts "---: $comment"
- }
- if [regexp -nocase {^Disk$} $type] {
- set smb_local($smbhost:disk:$name) $comment
- } elseif [regexp -nocase {^Print} $type] {
- set smb_local($smbhost:printer:$name) $comment
- }
- }
- }
- }
-
- set smb_local($smbhost:domain) $domain
-}
-
-proc smb_list_unix {smbhost} {
- global smb_local smb_local_hosts smb_this_host
- set smbclient [in_path smbclient]
- if {[in_path smbclient] == ""} {
- return ""
- }
- set dbg 0
-
- set this_host [get_hostname]
- set This_host [string toupper $this_host]
- set smb_this_host $This_host
-
- set out1 ""
- catch {set out1 [exec smbclient -N -L $smbhost 2>@ stdout]}
-
- if {$dbg} {puts "SMBHOST: $smbhost"}
- if {$smbhost == $this_host || $smbhost == $This_host} {
- if {$out1 == ""} {
- catch {set out1 [exec smbclient -N -L localhost 2>@ stdout]}
- }
- }
-
- set domain ""
- set mode ""
- foreach line [split $out1 "\n"] {
- if [regexp {^[ \t]*---} $line] {
- continue
- }
- if [regexp {Anonymous login} $line] {
- continue
- }
- if {$domain == "" && [regexp {Domain=\[([^\]]+)\]} $line mv domain]} {
- if {$dbg} {puts "DOM: $domain"}
- continue
- }
- if [regexp {^[ \t]*Sharename} $line] {
- set mode "shares"
- continue
- }
- if [regexp {^[ \t]*Server} $line] {
- set mode "server"
- continue
- }
- if [regexp {^[ \t]*Workgroup} $line] {
- set mode "workgroup"
- continue
- }
- set line [string trim $line]
- if {$mode == "shares"} {
- if [regexp {^([^ \t]+)[ \t]+([^ \t]+)[ \t]*(.*)$} $line mv name type comment] {
- if {$dbg} {
- puts "SHR: $name"
- puts "---: $type"
- puts "---: $comment"
- }
- if [regexp -nocase {^Disk$} $type] {
- set smb_local($smbhost:disk:$name) $comment
- } elseif [regexp -nocase {^Printer$} $type] {
- set smb_local($smbhost:printer:$name) $comment
- }
- }
- } elseif {$mode == "server"} {
- if [regexp {^([^ \t]+)[ \t]*(.*)$} $line mv host comment] {
- if {$dbg} {
- puts "SVR: $host"
- puts "---: $comment"
- }
- set smb_local($smbhost:server:$host) $comment
- }
- } elseif {$mode == "workgroup"} {
- if [regexp {^([^ \t]+)[ \t]+(.*)$} $line mv work host] {
- if {$dbg} {
- puts "WRK: $work"
- puts "---: $host"
- }
- if {$host != ""} {
- set smb_local($smbhost:master:$work) $host
- }
- }
- }
- }
-
- set smb_local($smbhost:domain) $domain
-}
-
-proc smb_list {} {
- global is_windows smb_local smb_local_hosts
- global smb_host_list
-
- set smb_local(null) ""
-
- if {! [info exists smb_host_list]} {
- set smb_host_list ""
- }
- if [info exists smb_local] {
- unset smb_local
- }
- if [info exists smb_local_hosts] {
- unset smb_local_hosts
- }
-
- set this_host [get_hostname]
- set this_host [string toupper $this_host]
- if {$is_windows} {
- smb_list_windows $this_host
- } else {
- smb_list_unix $this_host
- }
- set did($this_host) 1
- set keys [array names smb_local]
- foreach item [split $smb_host_list] {
- if {$item != ""} {
- set item [string toupper $item]
- lappend keys "$this_host:server:$item"
- }
- }
- foreach key $keys {
- if [regexp "^$this_host:server:(.*)\$" $key mv host] {
- if {$host == ""} {
- continue
- }
- set smb_local_hosts($host) 1
- if {! [info exists did($host)]} {
- if {$is_windows} {
- smb_list_windows $host
- } else {
- smb_list_unix $host
- }
- set did($host) 1
- }
- }
- }
-}
-
-proc smb_check_selected {} {
- global smbmount_exists smbmount_sumode
- global smb_selected smb_selected_mnt smb_selected_cb smb_selected_en
-
- set ok 0
- if {$smbmount_exists && $smbmount_sumode != "dontknow"} {
- set ok 1
- }
- set state disabled
- if {$ok} {
- set state normal
- }
-
- foreach cb [array names smb_selected_cb] {
- catch {$cb configure -state $state}
- }
- foreach en [array names smb_selected_en] {
- catch {$en configure -state $state}
- }
-}
-
-proc make_share_widgets {w} {
-
- set share_label $w.f.hl
- catch {$share_label configure -text "Share Name: PROBING ..."}
- update
-
- smb_list
-
- set saw_f 0
- foreach child [winfo children $w] {
- if {$child == "$w.f"} {
- set saw_f 1
- continue
- }
- catch {destroy $child}
- }
-
- set w1 47
- set w2 44
-
- if {! $saw_f} {
- set wf $w.f
- frame $wf
- label $wf.hl -width $w1 -text "Share Name:" -anchor w
- label $wf.hr -width $w2 -text " Mount Point:" -anchor w
-
- pack $wf.hl $wf.hr -side left -expand 1
- pack $wf -side top -fill x
-
- .smbwiz.f.t window create end -window $w
- }
-
- global smb_local smb_local_hosts smb_this_host smb_selected smb_selected_mnt
- global smb_selected_host smb_selected_name
- global smb_selected_cb smb_selected_en
- global smb_host_list
- if [info exists smb_selected] {array unset smb_selected }
- if [info exists smb_selected_mnt] {array unset smb_selected_mnt}
- if [info exists smb_selected_cb] {array unset smb_selected_cb}
- if [info exists smb_selected_en] {array unset smb_selected_en}
- if [info exists smb_selected_host] {array unset smb_selected_host}
- if [info exists smb_selected_name] {array unset smb_selected_name}
-
- set hosts [list $smb_this_host]
- lappend hosts [lsort [array names smb_local_hosts]]
-
- set smb_host_list ""
- set i 0
-
- global smb_mount_prefix
- set smb_mount_prefix "/var/tmp/%USER-mnts"
-
- foreach host [lsort [array names smb_local_hosts]] {
-
- if [info exists did($host)] {
- continue
- }
- set did($host) 1
-
- append smb_host_list "$host "
-
- foreach key [lsort [array names smb_local]] {
- if [regexp {^([^:]+):([^:]+):(.*)$} $key mv host2 type name] {
- if {$host2 != $host} {
- continue
- }
- if {$type != "disk"} {
- continue
- }
- set wf $w.f$i
- frame $wf
- checkbutton $wf.c -anchor w -width $w1 -variable smb_selected($i) \
- -text "//$host/$name" -relief ridge
- if {! [info exists smb_selected($i)]} {
- set smb_selected($i) 0
- }
-
- entry $wf.e -width $w2 -textvariable smb_selected_mnt($i)
- set smb_selected_mnt($i) "$smb_mount_prefix/$host/$name"
-
- set smb_selected_host($i) $host
- set smb_selected_name($i) $name
-
- set smb_selected_cb($wf.c) $i
- set smb_selected_en($wf.e) $i
- set comment $smb_local($key)
-
- bind $wf.c <Enter> "$share_label configure -text {Share Name: $comment}"
- bind $wf.c <Leave> "$share_label configure -text {Share Name:}"
-
- $wf.c configure -state disabled
- $wf.e configure -state disabled
-
- pack $wf.c $wf.e -side left -expand 1
- pack $wf -side top -fill x
- incr i
- }
- }
- }
- if {$i == 0} {
- global is_win9x
- $share_label configure -text {Share Name: No SMB Share Hosts were found!}
- if {$is_win9x} {
- .smbwiz.f.t insert end "\n(this feature does not work on Win9x you have have to enter them manually: //HOST/share /var/tmp/mymnt)\n"
- }
- } else {
- $share_label configure -text "Share Name: Found $i SMB Shares"
- }
- smb_check_selected
-}
-
-proc smb_help_me_decide {} {
- global is_windows
- global smb_local smb_local_hosts smb_this_host smb_selected smb_selected_mnt
- global smb_selected_host smb_selected_name
- global smb_selected_cb smb_selected_en
- global smb_host_list
-
- toplev .smbwiz
- set title "SMB Filesystem Tunnelling -- Help Me Decide"
- wm title .smbwiz $title
- set id " "
-
- set h 40
- if [small_height] {
- set h 30
- }
- scroll_text .smbwiz.f 100 $h
-
- set msg {
-For now you will have to verify the following information manually.
-
-You can do this by either logging into the remote machine to find the info or asking the sysadmin for it.
-
-}
-
- if {! $is_windows} {
- .smbwiz.f.t configure -font {Helvetica -12 bold}
- }
- .smbwiz.f.t insert end $msg
-
- set w .smbwiz.f.t.f1
- frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
-
- .smbwiz.f.t insert end "\n"
-
- .smbwiz.f.t insert end "1) Indicate the existence of the 'smbmount' command on the remote system:\n"
- .smbwiz.f.t insert end "\n$id"
- global smbmount_exists
- set smbmount_exists 0
-
- checkbutton $w.smbmount_exists -pady 1 -anchor w -variable smbmount_exists \
- -text "Yes, the 'smbmount' command exists on the remote system." \
- -command smb_check_selected
-
- pack $w.smbmount_exists
- .smbwiz.f.t window create end -window $w
-
- .smbwiz.f.t insert end "\n\n\n"
-
- set w .smbwiz.f.t.f2
- frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
-
- .smbwiz.f.t insert end "2) Indicate your authorization to run 'smbmount' on the remote system:\n"
- .smbwiz.f.t insert end "\n$id"
- global smbmount_sumode
- set smbmount_sumode "dontknow"
-
- radiobutton $w.dk -pady 1 -anchor w -variable smbmount_sumode -value dontknow \
- -text "I do not know if I can mount SMB shares on the remote system via 'smbmount'" \
- -command smb_check_selected
- pack $w.dk -side top -fill x
-
- radiobutton $w.su -pady 1 -anchor w -variable smbmount_sumode -value su \
- -text "I know the Password to run commands as root on the remote system via 'su'" \
- -command smb_check_selected
- pack $w.su -side top -fill x
-
- radiobutton $w.sudo -pady 1 -anchor w -variable smbmount_sumode -value sudo \
- -text "I know the Password to run commands as root on the remote system via 'sudo'" \
- -command smb_check_selected
- pack $w.sudo -side top -fill x
-
- radiobutton $w.ru -pady 1 -anchor w -variable smbmount_sumode -value none \
- -text "I do not need to be root on the remote system to mount SMB shares via 'smbmount'" \
- -command smb_check_selected
- pack $w.ru -side top -fill x
-
- .smbwiz.f.t window create end -window $w
-
- global smb_wiz_done
- set smb_wiz_done 0
-
- button .smbwiz.cancel -text "Cancel" -command {set smb_wiz_done 1}
- button .smbwiz.done -text "Done" -command {set smb_wiz_done 1}
- pack .smbwiz.done -side bottom -fill x
- pack .smbwiz.f -side top -fill both -expand 1
-
- wm protocol .smbwiz WM_DELETE_WINDOW {set smb_wiz_done 1}
- center_win .smbwiz
-
- wm title .smbwiz "Searching for Local SMB shares..."
- update
- wm title .smbwiz $title
-
- global smb_local smb_this_host
- .smbwiz.f.t insert end "\n\n\n"
-
- set w .smbwiz.f.t.f3
- catch {destroy $w}
- frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
-
- .smbwiz.f.t insert end "3) Select SMB shares to mount and their mount point on the remote system:\n"
- .smbwiz.f.t insert end "\n${id}"
-
- make_share_widgets $w
-
- .smbwiz.f.t insert end "\n(%USER will be expanded to the username on the remote system and %HOME the home directory)\n"
-
- .smbwiz.f.t insert end "\n\n\n"
-
- .smbwiz.f.t insert end "You can change the list of Local SMB hosts to probe and the mount point prefix here:\n"
- .smbwiz.f.t insert end "\n$id"
- set w .smbwiz.f.t.f4
- frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
- set wf .smbwiz.f.t.f4.f
- frame $wf
- label $wf.l -text "SMB Hosts: " -anchor w
- entry $wf.e -textvariable smb_host_list -width 60
- button $wf.b -text "Apply" -command {make_share_widgets .smbwiz.f.t.f3}
- bind $wf.e <Return> "$wf.b invoke"
- pack $wf.l $wf.e $wf.b -side left
- pack $wf
- pack $w
-
- .smbwiz.f.t window create end -window $w
-
- .smbwiz.f.t insert end "\n$id"
-
- set w .smbwiz.f.t.f5
- frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
- set wf .smbwiz.f.t.f5.f
- frame $wf
- label $wf.l -text "Mount Prefix:" -anchor w
- entry $wf.e -textvariable smb_mount_prefix -width 60
- button $wf.b -text "Apply" -command {apply_mount_point_prefix .smbwiz.f.t.f5.f.e}
- bind $wf.e <Return> "$wf.b invoke"
- pack $wf.l $wf.e $wf.b -side left
- pack $wf
- pack $w
-
- .smbwiz.f.t window create end -window $w
-
- .smbwiz.f.t insert end "\n\n\n"
-
- .smbwiz.f.t see 1.0
- .smbwiz.f.t configure -state disabled
- update
-
- vwait smb_wiz_done
- catch {destroy .smbwiz}
-
- if {! $smbmount_exists || $smbmount_sumode == "dontknow"} {
- tk_messageBox -type ok -parent .oa -icon warning -message "Sorry we couldn't help out!\n'smbmount' info on the remote system is required for SMB mounting" -title "SMB mounting -- aborting"
- global use_smbmnt
- set use_smbmnt 0
- catch {raise .oa}
- return
- }
- global smb_su_mode
- set smb_su_mode $smbmount_sumode
-
- set max 0
- foreach en [array names smb_selected_en] {
- set i $smb_selected_en($en)
- set host $smb_selected_host($i)
- set name $smb_selected_name($i)
-
- set len [string length "//$host/$name"]
- if {$len > $max} {
- set max $len
- }
- }
-
- set max [expr $max + 8]
-
- set strs ""
- foreach en [array names smb_selected_en] {
- set i $smb_selected_en($en)
- if {! $smb_selected($i)} {
- continue
- }
- set host $smb_selected_host($i)
- set name $smb_selected_name($i)
- set mnt $smb_selected_mnt($i)
-
- set share "//$host/$name"
- set share [format "%-${max}s" $share]
-
- lappend strs "$share $mnt"
- }
- set text ""
- foreach str [lsort $strs] {
- append text "$str\n"
- }
-
- global smb_mount_list
- set smb_mount_list $text
-
- smb_dialog
-}
-
-proc apply_mount_point_prefix {w} {
- global smb_selected_host smb_selected_name
- global smb_selected_en smb_selected_mnt
-
- set prefix ""
- catch {set prefix [$w get]}
- if {$prefix == ""} {
- mesg "No mount prefix."
- bell
- return
- }
-
- foreach en [array names smb_selected_en] {
- set i $smb_selected_en($en)
- set host $smb_selected_host($i)
- set name $smb_selected_name($i)
- set smb_selected_mnt($i) "$prefix/$host/$name"
- }
-}
-
-proc smb_dialog {} {
- toplev .smb
- wm title .smb "SMB Filesystem Tunnelling"
- global smb_su_mode smb_mount_list
- global use_smbmnt
-
- global help_font
-
- global uname
- set h 33
- if [small_height] {
- set h 17
- } elseif {$uname == "Darwin"} {
- set h 24
- }
- scroll_text .smb.f 80 $h
-
- set msg {
- Windows/Samba Filesystem mounting requires SSH be used to set up the SMB
- service port redirection. This will be either of the "Use SSH" or
- "SSH+SSL" modes. NOTE: For pure SSL tunnelling it currently will not work.
-
- This method requires a working Samba software setup on the remote
- side of the connection (VNC server) and existing Samba or Windows file
- server(s) on the local side (VNC viewer).
-
- The smbmount(8) program MUST be installed on the remote side. This
- evidently limits the mounting to Linux systems. Let us know of similar
- utilities on other Unixes. Mounting onto remote Windows machines is
- currently not supported (our SSH mode with services setup only works
- to Unix). On Debian and Ubuntu the smbmount program is currently in
- the package named 'smbfs'.
-
- Depending on how smbmount is configured you may be able to run it
- as a regular user, or it may require running under su(1) or sudo(8)
- (root password or user password required, respectively). You select
- which one you want via the checkbuttons below.
-
- In addition to a possible su(1) or sudo(8) password, you may ALSO
- need to supply passwords to mount each SMB share. This is an SMB passwd.
- If it has no password just hit enter after the "Password:" prompt.
-
- The passwords are supplied when the 1st SSH connection starts up;
- be prepared to respond to them.
-
- NOTE: USE OF SMB TUNNELLING MODE WILL REQUIRE TWO SSH'S, AND SO YOU
- MAY NEED TO SUPPLY TWO LOGIN PASSWORDS UNLESS YOU ARE USING SOMETHING
- LIKE ssh-agent(1) or the Putty PW setting.
- %WIN
-
- To indicate the Windows/Samba shares to mount enter them one per line
- in one of the forms:
-
- //machine1/share ~/Desktop/my-mount1
- //machine2/fubar /var/tmp/my-foobar2 192.168.100.53:3456
- 1139 //machine3/baz /var/tmp/baz [...]
-
- The first part is the standard SMB host and share name //hostname/dir
- (note this share is on the local viewer-side not on the remote end).
- A leading '#' will cause the entire line to be skipped.
-
- The second part, e.g. /var/tmp/my-foobar2, is the directory to mount
- the share on the remote (VNC Server) side. You must be able to
- write to this directory. It will be created if it does not exist.
- A leading character ~ will be expanded to $HOME. So will the string
- %HOME. The string %USER will get expanded to the remote username.
-
- An optional part like 192.168.100.53:3456 is used to specify the real
- hostname or IP address, and possible non-standard port, on the local
- side if for some reason the //hostname is not sufficient.
-
- An optional leading numerical value, 1139 in the above example, indicates
- which port to use on the Remote side to SSH redirect to the local side.
- Otherwise a random one is tried (a unique one is needed for each SMB
- server:port combination). A fixed one is preferred: choose a free
- remote port.
-
- The standard SMB service ports (local side) are 445 and 139. 139 is
- used by this application.
-
- Sometimes "localhost" will not work on Windows machines for a share
- hostname, and you will have to specify a different network interface
- (e.g. the machine's IP address). If you use the literal string "IP"
- it will be attempted to replace it with the numerical IP address, e.g.:
-
- //machine1/share ~/Desktop/my-mount1 IP
-
- VERY IMPORTANT: Before terminating the VNC Connection, make sure no
- applications are using any of the SMB shares (or shells are cd-ed
- into the share). This way the shares will be automatically unmounted.
- Otherwise you will need to log in again, stop processes from using
- the share, become root and umount the shares manually ("smbumount
- /path/to/share", etc.)
-
- For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-smb-shares
-}
-
- set msg2 {
- To speed up moving to the next step, iconify the first SSH console
- when you are done entering passwords, etc. and then click on the
- main panel 'VNC Host:Display' label.
-}
-
- global is_windows
- if {! $is_windows} {
- regsub { *%WIN} $msg "" msg
- } else {
- set msg2 [string trim $msg2]
- regsub { *%WIN} $msg " $msg2" msg
- }
- .smb.f.t insert end $msg
-
- frame .smb.r
- label .smb.r.l -text "smbmount(8) auth mode:" -relief ridge
- radiobutton .smb.r.none -text "None" -variable smb_su_mode -value "none"
- radiobutton .smb.r.su -text "su(1)" -variable smb_su_mode -value "su"
- radiobutton .smb.r.sudo -text "sudo(8)" -variable smb_su_mode -value "sudo"
-
- pack .smb.r.l .smb.r.none .smb.r.sudo .smb.r.su -side left -fill x
-
- label .smb.info -text "Supply the mounts (one per line) below:" -anchor w -relief ridge
-
- eval text .smb.mnts -width 80 -height 5 $help_font
- .smb.mnts insert end $smb_mount_list
-
- button .smb.guess -text "Help me decide ..." -command {destroy .smb; smb_help_me_decide}
-
- button .smb.cancel -text "Cancel" -command {set use_smbmnt 0; destroy .smb}
- bind .smb <Escape> {set use_smbmnt 0; destroy .smb}
- wm protocol .smb WM_DELETE_WINDOW {set use_smbmnt 0; destroy .smb}
- button .smb.done -text "Done" -command {if {$use_smbmnt} {set_ssh; set smb_mount_list [.smb.mnts get 1.0 end]}; destroy .smb}
-
- pack .smb.done .smb.cancel .smb.guess .smb.mnts .smb.info .smb.r -side bottom -fill x
- pack .smb.f -side top -fill both -expand 1
-
- center_win .smb
-}
-
-proc help_advanced_opts {} {
- toplev .ah
-
- scroll_text_dismiss .ah.f
-
- center_win .ah
-
- wm title .ah "Advanced Options Help"
-
- set msg {
- These Advanced Options that may require extra software installed on
- the VNC server-side (the remote server machine) and/or on the VNC
- client-side (where this gui is running).
-
- The Service redirection options, CUPS, ESD/ARTSD, and SMB will
- require that you use SSH for tunneling so that they can use the -R
- port redirection will be enabled for each service. I.e. "Use SSH"
- or "SSH + SSL" mode.
-
- These options may also require additional configuration to get them
- to work properly. Please submit bug reports if it appears it should
- be working for your setup but is not.
-
- Brief (and some not so brief) descriptions:
-
- CUPS Print tunnelling:
-
- Redirect localhost:6631 (say) on the VNC server to your local
- CUPS server. SSH mode is required.
-
- ESD/ARTSD Audio tunnelling:
-
- Redirect localhost:16001 (say) on the VNC server to your local
- ESD, etc. sound server. SSH mode is required.
-
- SMB mount tunnelling:
-
- Redirect localhost:1139 (say) on the VNC server and through that
- mount SMB file shares from your local server. The remote machine
- must be Linux with smbmount installed. SSH mode is required.
-
- Additional Port Redirs (via SSH):
-
- Specify additional -L port:host:port and -R port:host:port
- cmdline options for SSH to enable additional services.
- SSH mode is required.
-
- Automatically Find X Login/Greeter:
-
- This mode is similar to "Automatically Find X Session" except
- that it will attach to a X Login/Greeter screen that no one
- has logged into yet. It requires root privileges via sudo(1)
- on the remote machine. SSH mode is required.
-
- As with "Automatically Find X Session" it works only with SSH
- mode and requires x11vnc be installed on the remote computer.
-
- It simply sets the Remote SSH Command to:
-
- PORT= sudo x11vnc -find -localhost -env FD_XDM=1
-
- An initial ssh running 'sudo id' is performed to try to
- 'prime' sudo so the 2nd one that runs x11vnc does not need
- a password. This may not always succeed... please mail us
- the details if it doesn't.
-
- See the 'X Login' description in 'Terminal Services' Mode
- Help for more info.
-
- Private SSH KnownHosts file:
-
- On Unix in SSH mode, let the user specify a non-default
- ssh known_hosts file to be used only by the current profile.
- This is the UserKnownHostsFile ssh option and is described in the
- ssh_config(1) man page. This is useful to avoid proxy 'localhost'
- SSH key collisions.
-
- Normally one should simply let ssh use its default file
- ~/.ssh/known_hosts for tracking SSH keys. The only problem that
- happens is when multiple SSVNC connections use localhost tunnel
- port redirections. These make ssh connect to 'localhost' on some
- port (where the proxy is listening.) Then the different keys
- from the multiple ssh servers collide when ssh saves them under
- 'localhost' in ~/.ssh/known_hosts.
-
- So if you are using a proxy with SSVNC or doing a "double SSH
- gateway" your ssh will connect to a proxy port on localhost, and you
- should set a private KnownHosts file for that connection profile.
- This is secure and avoids man-in-the-middle attack (as long as
- you actually verify the initial save of the SSH key!)
-
- The default file location will be:
-
- ~/.vnc/ssh_known_hosts/profile-name.known
-
- but you can choose any place you like. It must of course be
- unique and not shared with another ssh connection otherwise they
- both may complain about the key for 'localhost' changing, etc.
-
- SSH Local Port Protections:
-
- An LD_PRELOAD hack to limit the number of SSH port redirections
- to 1 and within the first 35 seconds. So there is a smaller
- window when the user can try to use your tunnel compared to
- the duration of your session. SSH mode is required.
-
- STUNNEL Local Port Protections:
-
- Try to prevent Untrusted Local Users (see the main Help panel)
- from using your STUNNEL tunnel to connect to the remote VNC
- Server.
-
- Change VNC Viewer:
-
- Specify a non-bundled VNC Viewer (e.g. UltraVNC or RealVNC)
- to run instead of the bundled TightVNC Viewer.
-
- Port Knocking:
-
- For "closed port" services, first "knock" on the firewall ports
- in a certain way to open the door for SSH or SSL. The port
- can also be closed when the encrypted VNC connection finishes.
-
- UltraVNC DSM Encryption Plugin:
-
- On Unix only, by using the supplied tool, ultravnc_dsm_helper,
- encrypted connections to UltraVNC servers using their plugins
- is enabled. Support for secret key encryption to Non-UltraVNC
- DSM servers is also supported, e.g. x11vnc -enc blowfish:my.key
-
- Do not Probe for VeNCrypt:
-
- Disable VeNCrypt auto-detection probe when not needed.
-
- By default in SSL mode an initial probe for the use of the
- VeNCrypt or ANONTLS protocol is performed. This is done
- during the initial fetch-cert action. Once auto-detected in
- the initial probe, the real connection to the VNC Server will
- use this information to switch to SSL/TLS at the right point in
- the VeNCrypt/ANONTLS handshake.
-
- In "Verify All Certs" mode initial the fetch-cert action is
- required so the automatic probing for VeNCrypt is always done.
- The fetch-cert is not needed if you specified a ServerCert or if
- you disabled "Verify All Certs". But by default the fetch-cert
- is done anyway to try to auto-detect VeNCrypt/ANONTLS.
-
- Set 'Do not Probe for VeNCrypt' to skip this unneeded fetch-cert
- action (and hence speed up connecting.) Use this if you
- know the VNC Server uses normal SSL and not VeNCrypt/ANONTLS.
-
- See also the next option, 'Server uses VeNCrypt SSL encryption'
- to if you know it uses VeNCrypt/ANONTLS (the probing will also
- be skipped if that option is set.)
-
- Server uses VeNCrypt SSL encryption:
-
- Indicate that the VNC server uses the VeNCrypt extension to VNC;
- it switches to an SSL/TLS tunnel at a certain point in the
- VNC Handshake. This is in constrast to the default ssvnc/x11vnc
- SSL tunnel behavior where the *entire* VNC traffic goes through
- SSL (i.e. it is vncs:// in the way https:// uses SSL)
-
- Enable this option if you know the server supports VeNCrypt.
- Also use this option for the older ANONTLS extension (vino).
- Doing so will give the quickest and most reliable connection
- to VeNCrypt/ANONTLS servers. If set, any probing to try to
- auto-detect VeNCrypt/ANONTLS will be skipped.
-
- Some VNC servers supporting VeNCrypt: VeNCrypt, QEMU, ggi,
- virt-manager, and Xen. Vino supports ANONTLS.
-
- The SSVNC VeNCrypt/ANONTLS support even works with 3rd party
- VNC Viewers you specify via 'Change VNC Viewer' (e.g. RealVNC,
- TightVNC, UltraVNC etc.) that do not directly support it.
-
- Note: many VeNCrypt servers only support Anonymous Diffie Hellman
- TLS which has NO built in authentication and you will also need
- to set the option described in the next section.
-
- If you are using VeNCrypt or ANONTLS for REVERSE connections
- (Listen) then you *MUST* set this 'Server uses VeNCrypt SSL
- encryption' option. Note also that REVERSE connections using
- VeNCrypt/ANONTLS currently do not work on Windows.
-
- Also, if you are using the "Use SSH+SSL" double tunnel to a
- VeNCrypt/ANONTLS server, you MUST set 'Server uses VeNCrypt
- SSL encryption' because "Verify All Certs" is disabled in
- SSH+SSL mode.
-
- Server uses Anonymous Diffie-Hellman
-
- Anonymous Diffie-Hellman can be used for SSL/TLS connections but
- there are no Certificates for authentication. Therefore only
- passive eavesdropping attacks are prevented, not Man-In-The-Middle
- attacks. Not recommended; try to use verified X509 certs instead.
-
- Enable this option if you know the server only supports Anon DH.
- When you do so, remember that ALL Certificate checking will be
- skipped (even if you have 'Verify All Certs' selected or set
- a ServerCert.)
-
- SSVNC may be able to autodetect Anon DH even if you haven't
- selected 'Server uses Anonymous Diffie-Hellman'. Once detected, it
- will prompt you whether it should continue. Set the 'Server uses
- Anonymous Diffie-Hellman' option to avoid trying autodetection
- (i.e. forcing the issue.)
-
- Note that most Anonymous Diffie-Hellman VNC Servers do so
- via the VeNCrypt or ANONTLS VNC extensions (see the previous
- section.) For these servers if you select 'Server uses Anonymous
- Diffie-Hellman' you *MUST* ALSO select 'Server uses VeNCrypt SSL
- encryption', otherwise SSVNC may have no chance to auto-detect
- the VeNCrypt/ANONTLS protocol.
-
- Also note, if you are using the "Use SSH+SSL" double tunnel to
- a VeNCrypt/ANONTLS server using Anon DH you MUST set 'Server
- uses Anonymous Diffie-Hellman' because "Verify All Certs"
- is disabled in SSH+SSL mode.
-
- Include:
-
- Default settings and Include Templates:
-
- Before explaining how Include works, first note that if you
- do not prefer some of SSVNC's default settings you can start
- up SSVNC and then change the settings for the options that you
- want to have a different default value. Then type "defaults"
- in VNC Host:Display entry box and press "Save" to save them in
- the "defaults.vnc" profile. After this, SSVNC will initialize
- all of the default values and then apply your override values
- in "defaults".
-
- For example, suppose you always want to use a different, 3rd
- party VNC Viewer. Set Options -> Advanced -> Change VNC Viewer
- to what you want, and then save it as the "defaults" profile.
- Now that default setting will apply to all profiles, and SSVNC
- in its startup state.
-
- To edit the defaults Load it, make changes, and then Save it.
- Delete the "defaults" profile to go back to no modifications.
- Note that defaults created and saved while defaults.vnc existed
- will NOT be automatically adjusted.
-
- Include Templates:
-
- Now suppose you have a certain class of settings that you do
- not want to always be applied, but you want them to apply to a
- group of profiles.
-
- For example, suppose you have some settings for very low
- bandwidth connections (e.g. low color modes and/or aggressive
- compression and quality settings.) Set these values in SSVNC
- and then in the VNC Host:Display entry box type in, say,
- "slowlink" and then press Save. This will save those settings
- in the template profile named "slowlink.vnc".
-
- Now to create a real profile that uses this template type the
- host:disp in "VNC Host:Display" and in Options -> Advanced
- -> Includes type in "slowlink". Then press Save to save the
- host profile. Then re-Load it. The "slowlink" settings will
- be applied after the defaults. Make any other changes to the
- setting for this profile and Save it again. Next time you load
- it in, the Include template settings will override the defaults
- and then the profile itself is read in.
-
- You may supply a comma or space separated list of templates
- to include. They are applied in the order listed. They can be
- full path names or basenames relative to the profiles directory.
- You do not need to supply the .vnc suffix. The non-default
- settings in them will be applied first, and then any values in
- the loaded Profile will override them.
-
- Sleep:
-
- Enter a number to indicate how many extra seconds to sleep
- while waiting for the VNC viewer to start up. On Windows this
- can give extra time to enter the Putty/Plink password, etc.
-
- Putty Args:
-
- Windows only, supply a string to be added to all plink.exe
- and putty.exe commands. Example: -i C:\mykey.ppk
-
- Launch Putty Pagent:
-
- Windows only, launch the Putty key agent tool (pageant) to hold
- your SSH private keys for automatic logging in by putty/plink.
-
- Launch Putty Key-Gen:
-
- Windows only, launch the Putty key generation tool (puttygen)
- to create new SSH private keys.
-
- Unix ssvncviewer:
-
- Display a popup menu with options that apply to the special
- Unix SSVNC VNC Viewer (perhaps called 'ssvncviewer') provided by
- this SSVNC package. This only applies to Unix or Mac OS X.
-
- Use ssh-agent:
-
- On Unix only: restart the GUI in the presence of ssh-agent(1)
- (e.g. in case you forgot to start your agent before starting
- this GUI). An xterm will be used to enter passphrases, etc.
- This can avoid repeatedly entering passphrases for the SSH logins
- (note this requires setting up and distributing SSH keys).
-
-
- About the CheckButtons:
-
- Ahem, Well...., yes quite a klunky UI: you have to toggle the
- CheckButton to pull up the Dialog box a 2nd, etc. time... don't
- worry your settings will still be there!
-}
-
- .ah.f.t insert end $msg
- jiggle_text .ah.f.t
-}
-
-proc help_ssvncviewer_opts {} {
- toplev .av
-
- scroll_text_dismiss .av.f
-
- center_win .av
-
- wm title .av "Unix SSVNC viewer Options Help"
-
- set msg {
- These Unix SSVNC VNC Viewer Options apply only on Unix or Mac OS X
- when using the viewer (ssvncviewer) supplied by this SSVNC package.
-
- Brief descriptions:
-
- Multiple LISTEN Connections:
-
- Allow multiple VNC servers to reverse connect at the same time
- and so display each of their desktops on your screen at the
- same time.
-
- Listen Once:
-
- Try to have the VNC Viewer exit after the first listening
- connection. (It may not always be detected; use Ctrl-C to exit)
-
- Listen Accept Popup Dialog:
-
- In -listen (reverse connection listening) mode when a reverse
- VNC connection comes in show a popup asking whether to Accept
- or Reject the connection. (-acceptpopup vncviewer option.)
-
- Accept Popup UltraVNC Single Click:
-
- As in 'Listen Accept Popup Dialog', except assume the remote
- VNC server is UltraVNC Single Click and force the execution of
- the protocol to retrieve the extra remote-side info (Windows
- User, ComputerName, etc) which is then also displayed in the
- Popup window. (-acceptpopupsc vncviewer option.)
-
- Use X11 Cursor:
-
- When drawing the mouse cursor shape locally, use an X11 cursor
- instead of drawing it directly into the framebuffer. This
- can sometimes give better response, and avoid problems under
- 'Scaling'.
-
- Disable Bell:
-
- Disable beeps coming from remote side.
-
- Use Raw Local:
-
- Use the VNC Raw encoding for 'localhost' connections (instead
- of assuming there is a local tunnel, SSL or SSH, going to the
- remote machine.
-
- Avoid Using Terminal:
-
- By default the Unix ssvncviewer will prompt for usernames,
- passwords, etc. in the terminal it is running inside of.
- Set this option to use windows for messages and prompting as
- much as possible. Messages will also go to the terminal, but
- all prompts will be done via popup window.
-
- Note that stunnel(1) may prompt for a passphrase to unlock a
- private SSL key. This is fairly rare because it is usually
- for Client-side SSL authentication. stunnel will prompt from
- the terminal; there seems to be no way around this.
-
- Also, note that ssh(1) may prompt for an ssh key passphrase
- or Unix password. This can be avoided in a number of ways,
- the simplest one is to use ssh-agent(1) and ssh-add(1).
- However ssh(1) may also prompt you to accept a new public key
- for a host or warn you if the key has changed, etc.
-
- Use Popup Fix:
-
- Enable a fix that warps the popup (F8) to the mouse pointer.
-
- Use XGrabServer (for fullscreen):
-
- On Unix only, use the XGrabServer workaround for older window
- managers. Sometimes also needed on recent (2008) GNOME. This
- workaround can make going into/out-of Fullscreen work better.
-
- Cursor Alphablending:
-
- Use the x11vnc alpha hack for translucent cursors (requires Unix,
- 32bpp and same endianness)
-
- TurboVNC:
-
- If available on your platform, use a ssvncviewer compiled with
- TurboVNC support. This is based on the VirtualGL project:
- http://www.sourceforge.net/projects/virtualgl You will need
- to install the VirtualGL's TurboJPEG library too.
-
- Currently (May/2009) only Linux.i686, Linux.x86_64, and
- Darwin.i386 have vncviewer.turbovnc binaries shipped in the
- ssvnc bundles. See the build instructions for how you might
- compile your own.
-
- Disable Pipelined Updates:
-
- Disable the TurboVNC-like pipelined updates mode. Pipelined
- updates is the default even when not TurboVNC enabled. They
- ask for the next screen update before the current one has
- finished downloading, and so this might reduce the slowdown
- due to high latency or low bandwidth by 2X or so. Disable
- them if they cause problems with the remote VNC Server or
- use too much bandwidth.
-
- Send CLIPBOARD not PRIMARY:
-
- When sending locally selected text to the VNC server side,
- send the CLIPBOARD selection instead of the PRIMARY selection.
-
- Send Selection Every time:
-
- Send selected text to the VNC server side every time the mouse
- focus enters the main VNC Viewer window instead only when it
- appears to have changed since the last send.
-
- Scaling:
-
- Use viewer-side (i.e. local) scaling of the VNC screen. Supply
- a fraction, e.g. 0.75 or 3/4, or a WxH geometry, e.g. 1280x1024,
- or the string 'fit' to fill the current screen. Use 'auto'
- to scale the desktop to match the viewer window size.
-
- If you observe mouse trail painting errors try using X11 Cursor.
-
- Note that since the local scaling is done in software it can
- be slow. Since ZRLE is better than Tight in this regard, when
- scaling is detected, the encoding will be switched to ZRLE.
- Use the Popup to go back to Tight if you want to, or set the
- env. var. SSVNC_PRESERVE_ENCODING=1 to disable the switch.
-
- For additional speedups under local scaling: try having a solid
- desktop background on the remote side (either manually or using
- 'x11vnc -solid ...'); and also consider using client side caching
- 'x11vnc -ncache 10 ...' if the remote server is x11vnc.
-
- Escape Keys:
-
- Enable 'Escape Keys', a set of modifier keys that, if all are
- pressed down, enable local Hot Key actions. Set to 'default'
- to use the default (Alt_L,Super_L on unix, Control_L,Meta_L
- on macosx) or set to a list of modifier keys.
-
- Y Crop:
-
- This is for x11vnc's -ncache client side caching scheme with our
- Unix TightVNC viewer. Sets the Y value to "crop" the viewer
- size at (below the cut is the pixel cache region you do not
- want to see). If the screen is tall (H > 2*W) ycropping will
- be autodetected, or you can set to -1 to force autodection.
- Otherwise, set it to the desired Y value. You can also set
- the scrollbar width (very thin by default) by appending ",sb=N"
- (or use ",sb=N" by itself to just set the scrollbar width).
-
- ScrollBar Width:
-
- This is for x11vnc's -ncache client side caching scheme with our
- Unix TightVNC viewer. For Y-Crop mode, set the size of the
- scrollbars (often one want it to be very narrow, e.g. 2 pixels
- to be less distracting.
-
- RFB Version:
-
- Set the numerical version of RFB (VNC) protocol to pretend to
- be, 3.x. Usually only needed with UltraVNC servers.
-
- Encodings:
-
- List encodings in preferred order, for example
- 'copyrect zrle tight' The list of encodings is:
- copyrect tight zrle zywrle hextile zlib corre rre raw
-
- Extra Options:
-
- String of extra Unix ssvncviewer command line options. I.e. for
- ones like -16bpp that cannot be set inside this SSVNC GUI. For a
- list click Help then 'SSVNC vncviewer -help Output'.
-
-
- These are environment variables one may set to affect the options
- of the SSVNC vncviewer and also the ss_vncviewer wrapper script
- (and hence may apply to 3rd party vncviewers too)
-
- VNCVIEWER_ALPHABLEND (-alpha, see Cursor Alphablending above)
- VNCVIEWER_POPUP_FIX (-popupfix, warp popup to mouse location)
- VNCVIEWER_GRAB_SERVER (-graball, see Use XGrabServer above)
- VNCVIEWER_YCROP (-ycrop, see Y Crop above)
- VNCVIEWER_SBWIDTH (-sbwidth, see ScrollBar Width above)
- VNCVIEWER_RFBVERSION (-rfbversion, e.g. 3.6)
- VNCVIEWER_ENCODINGS (-encodings, e.g. "copyrect zrle hextile")
- VNCVIEWER_NOBELL (-nobell)
- VNCVIEWER_X11CURSOR (-x11cursor, see Use X11 Cursor above)
- VNCVIEWER_RAWLOCAL (-rawlocal, see Use Raw Local above)
- VNCVIEWER_NOTTY (-notty, see Avoid Using Terminal above)
- VNCVIEWER_ESCAPE (-escape, see Escape Keys above)
- VNCVIEWER_ULTRADSM (-ultradsm)
- VNCVIEWER_PIPELINE_UPDATES (-pipeline, see above)
- VNCVIEWER_SEND_CLIPBOARD (-sendclipboard)
- VNCVIEWER_SEND_ALWAYS (-sendalways)
- VNCVIEWER_RECV_TEXT (-recvtext clipboard/primary/both)
- VNCVIEWER_NO_CUTBUFFER (do not send CUTBUFFER0 as fallback)
- VNCVIEWER_NO_PIPELINE_UPDATES (-nopipeline)
- VNCVIEWER_ALWAYS_RECENTER (set to avoid(?) recentering on resize)
- VNCVIEWER_IS_REALVNC4 (indicate vncviewer is realvnc4 flavor.)
- VNCVIEWER_NO_IPV4 (-noipv4)
- VNCVIEWER_NO_IPV6 (-noipv6)
- VNCVIEWER_FORCE_UP (force raise on fullscreen graball)
- VNCVIEWER_PASSWORD (danger: set vnc passwd via env. var.)
- VNCVIEWER_MIN_TITLE (minimum window title (appshare))
-
- VNCVIEWERCMD (unix viewer command, default vncviewer)
- VNCVIEWERCMD_OVERRIDE (force override of VNCVIEWERCMD)
- VNCVIEWERCMD_EXTRA_OPTS (extra options to pass to VNCVIEWERCMD)
- VNCVIEWER_LISTEN_LOCALHOST (force ssvncviewer to -listen on localhost)
- VNCVIEWER_NO_SEC_TYPE_TIGHT(force ssvncviewer to skip rfbSecTypeTight)
- HEXTILE_YCROP_TOO (testing: nosync_ycrop for hextile updates.)
-
- SS_DEBUG (very verbose debug printout by script.)
- SS_VNCVIEWER_LISTEN_PORT (force listen port.)
- SS_VNCVIEWER_NO_F (no -f for SSH.)
- SS_VNCVIEWER_NO_T (no -t for SSH.)
- SS_VNCVIEWER_USE_C (force -C compression for SSH.)
- SS_VNCVIEWER_SSH_CMD (override SSH command to run.)
- SS_VNCVIEWER_NO_MAXCONN (no maxconn for stunnel (obsolete))
- SS_VNCVIEWER_RM (file containing vnc passwd to remove.)
- SS_VNCVIEWER_SSH_ONLY (run the SSH command, then exit.)
-
- SSVNC_MULTIPLE_LISTEN (-multilisten, see Multiple LISTEN above)
- SSVNC_ACCEPT_POPUP (-acceptpopup, see Accept Popup Dialog)
- SSVNC_ACCEPT_POPUP_SC (-acceptpopupsc, see Accept Popup Dialog)
- SSVNC_TURBOVNC (see TurboVNC above)
- SSVNC_UNIXPW (-unixpw)
- SSVNC_UNIXPW_NOESC (do not send escape in -unixpw mode)
- SSVNC_SCALE (-scale, see Scaling above)
- SSVNC_NOSOLID (do not do solid region speedup in
- scaling mode.)
- SSVNC_PRESERVE_ENCODING (do not switch to ZRLE when scaling)
- SSVNC_FINISH_SLEEP (on unix/macosx sleep this many seconds
- before exiting the terminal, default 5)
-
- Misc (special usage or debugging or ss_vncviewer settings):
-
- SSVNC_MESG_DELAY (sleep this many millisec between messages)
- SSVNC_NO_ENC_WARN (do not print out a NO ENCRYPTION warning)
- SSVNC_EXTRA_SLEEP (same as Sleep: window)
- SSVNC_NO_ULTRA_DSM (disable ultravnc dsm encryption)
- SSVNC_ULTRA_DSM (the ultravnc_dsm_helper command)
- SSVNC_ULTRA_FTP_JAR (file location of ultraftp.jar jar file)
- SSVNC_KNOWN_HOSTS_FILE (file for per-connection ssh known hosts)
- SSVNC_SCALE_STATS (print scaling stats)
- SSVNC_NOSOLID (disable solid special case while scaling)
- SSVNC_DEBUG_RELEASE (debug printout for keyboard modifiers.)
- SSVNC_DEBUG_ESCAPE_KEYS (debug printout for escape keys)
- SSVNC_NO_MAYBE_SYNC (skip XSync() calls in certain painting)
- SSVNC_MAX_LISTEN (number of time to listen for reverse conn.)
- SSVNC_LISTEN_ONCE (listen for reverse conn. only once)
- STUNNEL_LISTEN (stunnel interface for reverse conn.
- SSVNC_NO_MESSAGE_POPUP (do not place info messages in popup.)
- SSVNC_SET_SECURITY_TYPE (force VeNCrypt security type)
- SSVNC_PREDIGESTED_HANDSHAKE (string used for VeNCrypt, etc. connect)
- SSVNC_SKIP_RFB_PROTOCOL_VERSION (force viewer to be RFB 3.8)
- SSVNC_DEBUG_SEC_TYPES (debug security types for VeNCrypt)
- SSVNC_DEBUG_MSLOGON (extra printout for ultravnc mslogon proto)
- SSVNC_DEBUG_RECTS (printout debug for RFB rectangles.)
- SSVNC_DEBUG_CHAT (printout debug info for chat mode.)
- SSVNC_DELAY_SYNC (faster local drawing delaying XSync)
- SSVNC_DEBUG_SELECTION (printout debug for selection/clipboard)
- SSVNC_REPEATER (URL-ish sslrepeater:// thing for UltraVNC)
- SSVNC_VENCRYPT_DEBUG (debug printout for VeNCrypt mode.)
- SSVNC_VENCRYPT_USERPASS (force VeNCrypt user:pass)
- SSVNC_STUNNEL_DEBUG (increase stunnel debugging printout)
- SSVNC_STUNNEL_VERIFY3 (increase stunnel verify from 2 to 3)
- SSVNC_LIM_ACCEPT_PRELOAD (preload library to limit accept(2))
- SSVNC_SOCKS5 (socks5 for x11vnc PORT= mode, default)
- SSVNC_SOCKS4 (socks4 for x11vnc PORT= mode)
- SSVNC_NO_IPV6_PROXY (do not setup a ipv6:// proxy)
- SSVNC_NO_IPV6_PROXY_DIRECT (do not setup a ipv6:// proxy unencrypted)
- SSVNC_PORT_IPV6 (x11vnc PORT= mode is to ipv6-only)
- SSVNC_IPV6 (0 to disable ss_vncviewer ipv6 check)
- SSVNC_FETCH_TIMEOUT (ss_vncviewer cert fetch timeout)
- SSVNC_USE_S_CLIENT (force cert fetch to be 'openssl s_client')
- SSVNC_SHOWCERT_EXIT_0 (force showcert to exit with success)
- SSVNC_SSH_LOCALHOST_AUTH (force SSH localhost auth check.)
- SSVNC_TEST_SEC_TYPE (force PPROXY VeNCrypt type; testing)
- SSVNC_TEST_SEC_SUBTYPE (force PPROXY VeNCrypt subtype; testing)
- SSVNC_EXIT_DEBUG (testing: prompt to exit at end.)
- SSVNC_UP_DEBUG (gui user/passwd debug mode.)
- SSVNC_UP_FILE (gui user/passwd file.)
-
- STUNNEL_EXTRA_OPTS (extra options for stunnel.)
-
- X11VNC_APPSHARE_DEBUG (for debugging -appshare mode.)
- NO_X11VNC_APPSHARE (shift down for escape keys.)
- DEBUG_HandleFileXfer (ultravnc filexfer)
- DEBUG_RFB_SMSG (RFB server message debug.)
-}
-
- .av.f.t insert end $msg
- button .av.htext -text "SSVNC vncviewer -help Output" -command show_viewer_help
- pack .av.htext -side bottom -fill x
- jiggle_text .av.f.t
-}
-
-proc show_viewer_help {} {
- toplev .vhlp
-
- set h 35
- if [small_height] {
- set h 30
- }
- scroll_text_dismiss .vhlp.f 83 $h
-
- center_win .vhlp
- wm resizable .vhlp 1 0
-
- wm title .vhlp "SSVNC vncviewer -help Output"
-
- set msg "-- No Help Output --"
- catch {set msg [exec ss_vncviewer -viewerhelp 2>/dev/null]}
-
- .vhlp.f.t insert end $msg
- jiggle_text .vhlp.f.t
-}
-
-proc set_viewer_path {} {
- global change_vncviewer_path
- unix_dialog_resize .chviewer
- set change_vncviewer_path [tk_getOpenFile -parent .chviewer]
- catch {raise .chviewer}
- update
-}
-
-proc change_vncviewer_dialog {} {
- global change_vncviewer change_vncviewer_path vncviewer_realvnc4
- global ts_only
-
- toplev .chviewer
- wm title .chviewer "Change VNC Viewer"
-
- global help_font
- if {$ts_only} {
- eval text .chviewer.t -width 90 -height 16 $help_font
- } else {
- eval text .chviewer.t -width 90 -height 27 $help_font
- }
- apply_bg .chviewer.t
-
- set msg {
- To use your own VNC Viewer (i.e. one installed by you, not included in this
- package), e.g. UltraVNC or RealVNC, type in the program name, or browse for
- the full path to it. You can put command line arguments after the program.
-
- Note that due to incompatibilities with respect to command line options
- there may be issues, especially if many command line options are supplied.
- You can specify your own command line options below if you like (and try to
- avoid setting any others in this GUI under "Options").
-
- If the path to the program name has spaces it in, surround it with double quotes:
-
- "C:\Program Files\My Vnc Viewer\VNCVIEWER.EXE"
-
- Make sure the very first character is a quote. You should quote the command
- even if it is only the command line arguments that need extra protection:
-
- "wine" -- "/home/fred/Program Flies/UltraVNC-1.0.2.exe" /64colors
-
- Since the command line options differ between them greatly, if you know it
- is of the RealVNC 4.x flavor, indicate on the check box. Otherwise we guess.
-
- To have SSVNC act as a general STUNNEL redirector (no VNC) set the viewer to be
- "xmessage OK" or "xmessage <port>" or "sleep n" or "sleep n <port>" (or "NOTEPAD"
- on Windows). The default listen port is 5930. The destination is set in "VNC
- Host:Display" (for a remote port less than 200 use the negative of the port value).
-}
-
- if {$ts_only} {
- regsub {Note that due(.|\n)*If the} $msg "If the" msg
- regsub {To have SSVNC act(.|\n)*} $msg "" msg
- }
- .chviewer.t insert end $msg
-
- frame .chviewer.path
- label .chviewer.path.l -text "VNC Viewer:"
- entry .chviewer.path.e -width 40 -textvariable change_vncviewer_path
- button .chviewer.path.b -text "Browse..." -command set_viewer_path
- checkbutton .chviewer.path.r -anchor w -variable vncviewer_realvnc4 -text \
- "RealVNC 4.x"
-
- pack .chviewer.path.l -side left
- pack .chviewer.path.e -side left -expand 1 -fill x
- pack .chviewer.path.b -side left
- pack .chviewer.path.r -side left
-
- button .chviewer.cancel -text "Cancel" -command {destroy .chviewer; set change_vncviewer 0}
- bind .chviewer <Escape> {destroy .chviewer; set change_vncviewer 0}
- wm protocol .chviewer WM_DELETE_WINDOW {destroy .chviewer; set change_vncviewer 0}
- button .chviewer.done -text "Done" -command {destroy .chviewer; catch {raise .oa}}
- bind .chviewer.path.e <Return> {destroy .chviewer; catch {raise .oa}}
-
- pack .chviewer.t .chviewer.path .chviewer.cancel .chviewer.done -side top -fill x
-
- center_win .chviewer
- wm resizable .chviewer 1 0
-
- focus .chviewer.path.e
-}
-
-proc port_redir_dialog {} {
- global additional_port_redirs additional_port_redirs_list
-
- toplev .redirs
- wm title .redirs "Additional Port Redirections (via SSH)"
-
- global help_font uname
- set h 35
- if [small_height] {
- set h 27
- }
- eval text .redirs.t -width 80 -height $h $help_font
- apply_bg .redirs.t
-
- set msg {
- Specify any additional SSH port redirections you desire for the
- connection. Put as many as you want separated by spaces. These only
- apply to SSH and SSH+SSL connections, they do not apply to Pure SSL
- connections.
-
- -L port1:host:port2 will listen on port1 on the local machine (where
- you are sitting) and redirect them to port2 on
- "host". "host" is relative to the remote side
- (VNC Server). Use "localhost" for the remote
- machine itself.
-
- -R port1:host:port2 will listen on port1 on the remote machine
- (where the VNC server is running) and redirect
- them to port2 on "host". "host" is relative
- to the local side (where you are sitting).
- Use "localhost" for this machine.
-
- Perhaps you want a redir to a web server inside an intranet:
-
- -L 8001:web-int:80
-
- Or to redir a remote port to your local SSH daemon:
-
- -R 5022:localhost:22
-
- etc. There are many interesting possibilities.
-
- Sometimes, especially for Windows Shares, you cannot do a -R redir to
- localhost, but need to supply the IP address of the network interface
- (e.g. by default the Shares do not listen on localhost:139). As a
- convenience you can do something like -R 1139:IP:139 (for any port
- numbers) and the IP will be attempted to be expanded. If this fails
- for some reason you will have to use the actual numerical IP address.
-}
- .redirs.t insert end $msg
-
- frame .redirs.path
- label .redirs.path.l -text "Port Redirs:"
- entry .redirs.path.e -width 40 -textvariable additional_port_redirs_list
-
- pack .redirs.path.l -side left
- pack .redirs.path.e -side left -expand 1 -fill x
-
- button .redirs.cancel -text "Cancel" -command {set additional_port_redirs 0; destroy .redirs}
- bind .redirs <Escape> {set additional_port_redirs 0; destroy .redirs}
- wm protocol .redirs WM_DELETE_WINDOW {set additional_port_redirs 0; destroy .redirs}
- button .redirs.done -text "Done" -command {destroy .redirs}
-
- pack .redirs.t .redirs.path .redirs.cancel .redirs.done -side top -fill x
-
- center_win .redirs
- wm resizable .redirs 1 0
-
- focus .redirs.path.e
-}
-
-proc stunnel_sec_dialog {} {
- global stunnel_local_protection
-
- toplev .stlsec
- wm title .stlsec "STUNNEL Local Port Protections"
-
- global help_font uname
-
- set h 37
- if [small_height] {
- set h 26
- }
- scroll_text .stlsec.f 82 $h
-
- apply_bg .stlsec.f
-
- set msg {
- See the discussion of "Untrusted Local Users" in the main 'Help'
- panel for info about users who are able to log into the workstation
- you run SSVNC on and might try to use your encrypted tunnel to gain
- access to the remote VNC machine.
-
- On Unix, for STUNNEL SSL tunnels we provide two options as extra
- safeguards against untrusted local users. Both only apply to Unix/MacOSX.
- Note that Both options are *IGNORED* in reverse connection (Listen) mode.
-
- 1) The first one 'Use stunnel EXEC mode' (it is mutually exclusive with
- option 2). For this case the modified SSVNC Unix viewer must be
- used: it execs the stunnel program instead of connecting to it via
- TCP/IP. Thus there is no localhost listening port involved at all.
-
- This is the best solution for SSL stunnel tunnels, it works well and
- is currently enabled by default. Disable it if there are problems.
-
- 2) The second one 'Use stunnel IDENT check', uses the stunnel(8)
- 'ident = username' to use the local identd daemon (IDENT RFC 1413
- http://www.ietf.org/rfc/rfc1413.txt) to check that the locally
- connecting program (the SSVNC vncviewer) is being run by your userid.
- See the stunnel(8) man page for details.
-
- Normally the IDENT check service cannot be trusted much when used
- *remotely* (the remote host may be have installed a modified daemon).
- However when using the IDENT check service *locally* it should be
- reliable. If not, it means the local machine (where you run SSVNC)
- has already been root compromised and you have a serious problem.
-
- Enabling 'Use stunnel IDENT check' requires a working identd on the
- local machine. Often it is not installed or enabled (because it is not
- deemed to be useful, etc). identd is usually run out of the inetd(8)
- super-server. Even when installed and running it is often configured
- incorrectly. On a Debian/lenny system we actually found that the
- kernel module 'tcp_diag' needed to be loaded! ('modprobe tcp_diag')
-}
- .stlsec.f.t insert end $msg
-
- radiobutton .stlsec.ident -relief ridge -anchor w -variable stunnel_local_protection_type -value "ident" -text "Use stunnel IDENT check"
- radiobutton .stlsec.exec -relief ridge -anchor w -variable stunnel_local_protection_type -value "exec" -text "Use stunnel EXEC mode"
-
- button .stlsec.cancel -text "Cancel" -command {set stunnel_local_protection 0; destroy .stlsec}
- bind .stlsec <Escape> {set stunnel_local_protection 0; destroy .stlsec}
- wm protocol .stlsec WM_DELETE_WINDOW {set stunnel_local_protection 0; destroy .stlsec}
- button .stlsec.done -text "Done" -command {if {$stunnel_local_protection_type == "none"} {set stunnel_local_protection 0}; destroy .stlsec}
-
- pack .stlsec.f .stlsec.exec .stlsec.ident .stlsec.cancel .stlsec.done -side top -fill x
-
- center_win .stlsec
- wm resizable .stlsec 1 0
-}
-
-proc disable_ssl_workarounds_dialog {} {
- global disable_ssl_workarounds disable_ssl_workarounds_type
-
- toplev .sslwrk
- wm title .sslwrk "Disable SSL Workarounds"
-
- global help_font uname
- set h 36
- if [small_height] {
- set h 24
- }
- scroll_text .sslwrk.f 86 $h
-
- apply_bg .sslwrk.f
-
- set msg {
- Some SSL implementations are incomplete or buggy or do not work properly
- with other implementations. SSVNC uses STUNNEL for its SSL encryption,
- and STUNNEL uses the OpenSSL SSL implementation.
-
- This causes some problems with non-OpenSSL implementations on the VNC server
- side. The most noticable one is the UltraVNC Single Click III (SSL) server:
-
- http://www.uvnc.com/pchelpware/SCIII/index.html
-
- It can make a reverse connection to SSVNC via an encrypted SSL tunnel.
-
- Unfortunately, in the default operation with STUNNEL the connection will be
- dropped after 2-15 minutes due to an unexpected packet.
-
- Because of this, by default SSVNC will enable some SSL workarounds to make
- connections like these work. This is the STUNNEL 'options = ALL' setting:
- it enables a basic set of SSL workarounds.
-
- You can read all about these workarounds in the stunnel(8) manpage and the
- OpenSSL SSL_CTX_set_options(3) manpage.
-
- Why are we mentioning this? STUNNELS's 'options = ALL' lowers the SSL
- security a little bit. If you know you do not have an incompatible SSL
- implementation on the server side (e.g. any one using OpenSSL is compatible,
- x11vnc in particular), then you can regain that little bit of security by
- selecting the "Disable SSL Workarounds" option.
-
- "Disable All SSL Workarounds" selected below will do that. On the other hand,
- choose "Keep the DONT_INSERT_EMPTY_FRAGMENTS Workaround" to retain that one,
- commonly needed workaround.
-
- BTW, you can set the environment variable STUNNEL_EXTRA_OPTS_USER to add
- any lines to the STUNNEL global config that you want to. See the stunnel(8)
- man page for more details.
-}
- .sslwrk.f.t insert end $msg
-
- radiobutton .sslwrk.none -relief ridge -anchor w -variable disable_ssl_workarounds_type -value "none" -text "Disable All Workarounds"
- radiobutton .sslwrk.noempty -relief ridge -anchor w -variable disable_ssl_workarounds_type -value "noempty" -text "Keep the DONT_INSERT_EMPTY_FRAGMENTS Workaround"
-
- button .sslwrk.cancel -text "Cancel" -command {set disable_ssl_workarounds 0; destroy .sslwrk}
- bind .sslwrk <Escape> {set disable_ssl_workarounds 0; destroy .sslwrk}
- wm protocol .sslwrk WM_DELETE_WINDOW {set disable_ssl_workarounds 0; destroy .sslwrk}
- button .sslwrk.done -text "Done" -command {destroy .sslwrk}
-
- pack .sslwrk.f .sslwrk.none .sslwrk.noempty .sslwrk.cancel .sslwrk.done -side top -fill x
-
- center_win .sslwrk
- wm resizable .sslwrk 1 0
-}
-
-proc update_no_ultra_dsm {} {
- global ultra_dsm_noultra
- global ultra_dsm_type
-
- foreach b {bf des3 aes aes256 l e} {
- if {! $ultra_dsm_noultra} {
- .ultradsm.nou.$b configure -state disabled
- } else {
- .ultradsm.nou.$b configure -state normal
- }
- }
- if {! $ultra_dsm_noultra} {
- if {$ultra_dsm_type == "arc4"} {
- ;
- } elseif {$ultra_dsm_type == "aesv2"} {
- ;
- } elseif {$ultra_dsm_type == "msrc4"} {
- ;
- } elseif {$ultra_dsm_type == "msrc4_sc"} {
- ;
- } elseif {$ultra_dsm_type == "securevnc"} {
- ;
- } else {
- set ultra_dsm_type guess
- }
- catch {.ultradsm.key.securevnc configure -state normal}
- catch {.ultradsm.key.msrc4_sc configure -state normal}
- } else {
- catch {.ultradsm.key.securevnc configure -state disabled}
- catch {.ultradsm.key.msrc4_sc configure -state disabled}
- }
-}
-
-proc ultra_dsm_dialog {} {
- global ultra_dsm ultra_dsm_file ultra_dsm_type
-
- toplev .ultradsm
- wm title .ultradsm "UltraVNC DSM Encryption Plugin"
-
- global help_font
- set h 40
- if [small_height] {
- set h 22
- }
- scroll_text .ultradsm.f 85 $h
-
- set msg {
- On Unix and MacOSX with the provided SSVNC vncviewer, you can connect to an
- UltraVNC server that is using one of its DSM encryption plugins: MSRC4, ARC4,
- AESV2, and SecureVNC. More info at: http://www.uvnc.com/features/encryption.html
-
- IMPORTANT: The UltraVNC DSM MSRC4, ARC4, and AESV2 implementations contain
- unfixed errors that could allow an eavesdropper to recover the session
- key or traffic easily. They often do not provide strong encryption, but
- only provide basic obscurity instead. Do not use them with critical data.
- The newer SecureVNC Plugin does not suffer from these problems.
-
- See the bottom of this help text for how to use symmetric encryption with
- Non-UltraVNC servers (for example, x11vnc 0.9.5 or later). This mode does not
- suffer the shortcomings of the UltraVNC MSRC4, ARC4, and AESV2 implementations.
-
- You will need to specify the corresponding UltraVNC encryption key (created
- by you using an UltraVNC server or viewer). It is usually called 'rc4.key'
- (for MSRC4), 'arc4.key' (for ARC4), and 'aesv2.key' (for AESV2). Specify the
- path to it or Browse for it. Also, specify which type of plugin it is (or use
- 'guess' to have it guess via the before mentioned filenames).
-
- The choice "UVNC SC" enables a special workaround for use with UltraVNC Single
- Click and the MSRC4 plugin. It may not be needed on recent SC (e.g. from
- ~2009 and later; select "MSRC4" for these newer ones.)
-
- You can also specify pw=my-password instead of a keyfile. Use single quotes
- pw='....' if the password contains shell meta-characters `!$&*(){}[]|;<>?
-
- Use the literal string 'pw=VNCPASSWD' to have the VNC password that you
- entered into the 'VNC Password:' be used for the pw=...
-
- SSL and SSH tunnels do not apply in this mode (any settings are ignored.)
-
- Proxying works in this mode, as well as Reverse Connections (Listen)
-
- The choice "SecureVNC" refers to the SecureVNC Plugin using 128 bit AES or
- ARC4 with 2048 bit RSA key exchange described here:
-
- http://adamwalling.com/SecureVNC
-
- Note in its default mode SecureVNC is *Vulnerable* to Man-In-The-Middle attacks
- (encryption but no server authentication) so do not use it with critical data.
- In SecureVNC mode you do not need to supply a 'Ultra DSM Keyfile'. However,
- if you DO supply a keyfile filename (recommended) if that file does not exist
- you will be prompted if you want to save the UltraVNC server's RSA key in it.
- The key's MD5 checksum is displayed so that you can verify that the key is
- trusted. One way to print out the SecureVNC public key MD5 checksum is:
-
- openssl rsa -inform DER -outform DER -pubout -in ./Server_SecureVNC.pkey | dd bs=1 skip=24 | md5sum
-
- Then on subsequent connections, if you continue to specify this filename, the
- SecureVNCPlugin server's RSA key will be checked against the file's contents
- and if they differ the connection will be dropped.
-
- NOTE, However, if the SecureVNC keyfile ends in the string 'ClientAuth.pkey'
- then its contents are used for SecureVNC's normal Client Authentication dialog
- (you need to use Windows SecureVNCPlugin to generate this file on the server
- side, it is usually called "Viewer_ClientAuth.pkey", and then safely copy it
- to the viewer side.) If you want to do BOTH Client Auth and server RSA key
- storing (recommended), have the keyfile end in 'ClientAuth.pkey.rsa'; that way
- the file will be used for storing the server RSA key and then the '.rsa' is
- trimmed off and the remainder used for the SecureVNC Client Auth data filename.
-
- Note that despite its intentions, Client Authentication in the FIRST release of
- SecureVNC is still susceptible to Man-In-The-Middle attacks. Even when that
- is fixed, SecureVNC Client Authentication is still susceptible to "spoofing"
- attacks where the viewer user may be tricked into revealing his VNC or MS-Logon
- password if his connection is intercepted. It is recommended you verify and
- save the Server key (see above) in addition to using Client Authentication.
-
- UltraVNC DSM encryption modes are currently experimental because unfortunately
- the UltraVNC DSM plugin also modifies the RFB protocol(!), and so the SSVNC
- vncviewer had to be modified to support it. The tight, zlib, and some minor
- encodings currently do not work in this mode and are disabled.
-
- Note that this mode also requires the utility tool named 'ultravnc_dsm_helper'
- that should be included in your SSVNC kit.
-
- Select 'Non-Ultra DSM' to use symmetric encryption to a Non-UltraVNC server via
- a supported symmetric key cipher. x11vnc supports symmetric encryption via,
- e.g., "x11vnc -enc aesv2:./my.key". Extra ciphers are enabled for this mode
- (e.g. blowfish and 3des). 'UVNC SC' and SecureVNC do not apply in this mode.
-
- Note for the Non-Ultra DSM case it will also work with any VNC Viewer
- (i.e. selected by Options -> Advanced -> Change VNC Viewer) not only the
- supplied SSVNC vncviewer.
-
- For experts: You can also set the random salt size and initialization vector
- size in Salt,IV for example "8,16". See the x11vnc and 'ultravnc_dsm_helper
- -help' documentation for more info on this.
-}
-
- .ultradsm.f.t insert end $msg
-
- frame .ultradsm.path
- label .ultradsm.path.l -text "Ultra DSM Keyfile:"
- entry .ultradsm.path.e -width 40 -textvariable ultra_dsm_file
- button .ultradsm.path.b -text "Browse..." -command {set_ultra_dsm_file .ultradsm}
-
- pack .ultradsm.path.l -side left
- pack .ultradsm.path.e -side left -expand 1 -fill x
- pack .ultradsm.path.b -side left
-
- frame .ultradsm.key
- label .ultradsm.key.l -text "Type of Key: "
- radiobutton .ultradsm.key.guess -pady 1 -anchor w -variable ultra_dsm_type -value guess \
- -text "Guess"
- radiobutton .ultradsm.key.arc4 -pady 1 -anchor w -variable ultra_dsm_type -value arc4 \
- -text "ARC4"
-
- radiobutton .ultradsm.key.aesv2 -pady 1 -anchor w -variable ultra_dsm_type -value aesv2 \
- -text "AESV2"
-
- radiobutton .ultradsm.key.msrc4 -pady 1 -anchor w -variable ultra_dsm_type -value msrc4 \
- -text "MSRC4"
-
- radiobutton .ultradsm.key.msrc4_sc -pady 1 -anchor w -variable ultra_dsm_type -value msrc4_sc \
- -text "UVNC SC"
-
- radiobutton .ultradsm.key.securevnc -pady 1 -anchor w -variable ultra_dsm_type -value securevnc \
- -text "SecureVNC"
-
- pack .ultradsm.key.l -side left
- pack .ultradsm.key.guess -side left
- pack .ultradsm.key.arc4 -side left
- pack .ultradsm.key.aesv2 -side left
- pack .ultradsm.key.msrc4 -side left
- pack .ultradsm.key.msrc4_sc -side left
- pack .ultradsm.key.securevnc -side left
-
- frame .ultradsm.nou
- checkbutton .ultradsm.nou.cb -text "Non-Ultra DSM" -variable ultra_dsm_noultra -command update_no_ultra_dsm
- radiobutton .ultradsm.nou.bf -pady 1 -anchor w -variable ultra_dsm_type -value blowfish \
- -text "Blowfish"
-
- radiobutton .ultradsm.nou.des3 -pady 1 -anchor w -variable ultra_dsm_type -value 3des \
- -text "3DES"
-
- radiobutton .ultradsm.nou.aes -pady 1 -anchor w -variable ultra_dsm_type -value "aes-cfb" \
- -text "AES-CFB"
-
- radiobutton .ultradsm.nou.aes256 -pady 1 -anchor w -variable ultra_dsm_type -value "aes256" \
- -text "AES-256"
-
- label .ultradsm.nou.l -text " Salt,IV"
- entry .ultradsm.nou.e -width 6 -textvariable ultra_dsm_salt
-
- pack .ultradsm.nou.cb -side left
- pack .ultradsm.nou.bf -side left
- pack .ultradsm.nou.des3 -side left
- pack .ultradsm.nou.aes -side left
- pack .ultradsm.nou.aes256 -side left
- pack .ultradsm.nou.l -side left
- pack .ultradsm.nou.e -side left -expand 0
-
- update_no_ultra_dsm
-
- button .ultradsm.cancel -text "Cancel" -command {destroy .ultradsm; set ultra_dsm 0}
- bind .ultradsm <Escape> {destroy .ultradsm; set ultra_dsm 0}
- wm protocol .ultradsm WM_DELETE_WINDOW {destroy .ultradsm; set ultra_dsm 0}
- button .ultradsm.done -text "Done" -command {destroy .ultradsm; catch {raise .oa}}
- bind .ultradsm.path.e <Return> {destroy .ultradsm; catch {raise .oa}}
-
- pack .ultradsm.f .ultradsm.path .ultradsm.key .ultradsm.nou .ultradsm.cancel .ultradsm.done -side top -fill x
-
- center_win .ultradsm
- wm resizable .ultradsm 1 0
-
- focus .ultradsm.path.e
-}
-
-proc ssh_known_hosts_dialog {} {
- global ssh_known_hosts ssh_known_hosts_filename
-
- toplev .sshknownhosts
- wm title .sshknownhosts "Private SSH KnownHosts file"
-
- global help_font
- set h 31
- if [small_height] {
- set h 23
- }
- scroll_text .sshknownhosts.f 80 $h
-
- set msg {
- Private SSH KnownHosts file:
-
- On Unix in SSH mode, let the user specify a non-default
- ssh known_hosts file to be used only by the current profile.
- This is the UserKnownHostsFile ssh option and is described in the
- ssh_config(1) man page. This is useful to avoid proxy 'localhost'
- SSH key collisions.
-
- Normally one should simply let ssh use its default file
- ~/.ssh/known_hosts for tracking SSH keys. The only problem with
- that happens when multiple SSVNC connections use localhost tunnel
- port redirections. These make ssh connect to 'localhost' on some
- port (where the proxy is listening.) Then the different keys
- from the multiple ssh servers collide when ssh saves them under
- 'localhost' in ~/.ssh/known_hosts.
-
- So if you are using a proxy with SSVNC or doing a "double SSH
- gateway" your ssh will connect to a proxy port on localhost, and you
- should set a private KnownHosts file for that connection profile.
- This is secure and avoids man-in-the-middle attack (as long as
- you actually verify the initial save of the SSH key!)
-
- The default file location will be:
-
- ~/.vnc/ssh_known_hosts/profile-name.known
-
- but you can choose any place you like. It must of course be
- unique and not shared with another ssh connection otherwise they
- both may complain about the key for 'localhost' changing, etc.
-}
-
- .sshknownhosts.f.t insert end $msg
-
- frame .sshknownhosts.path
- label .sshknownhosts.path.l -text "SSH KnownHosts file:"
- entry .sshknownhosts.path.e -width 40 -textvariable ssh_known_hosts_filename
- button .sshknownhosts.path.b -text "Browse..." -command {set_ssh_known_hosts_file .sshknownhosts}
-
- pack .sshknownhosts.path.l -side left
- pack .sshknownhosts.path.e -side left -expand 1 -fill x
- pack .sshknownhosts.path.b -side left
-
- button .sshknownhosts.cancel -text "Cancel" -command {destroy .sshknownhosts; set ssh_known_hosts 0}
- bind .sshknownhosts <Escape> {destroy .sshknownhosts; set ssh_known_hosts 0}
- wm protocol .sshknownhosts WM_DELETE_WINDOW {destroy .sshknownhosts; set ssh_known_hosts 0}
- button .sshknownhosts.done -text "Done" -command {destroy .sshknownhosts; catch {raise .oa}}
- bind .sshknownhosts.path.e <Return> {destroy .sshknownhosts; catch {raise .oa}}
-
- pack .sshknownhosts.f .sshknownhosts.path .sshknownhosts.cancel .sshknownhosts.done -side top -fill x
-
- center_win .sshknownhosts
- wm resizable .sshknownhosts 1 0
-
- focus .sshknownhosts.path.e
-}
-
-proc ssh_sec_dialog {} {
- global ssh_local_protection
-
- toplev .sshsec
- wm title .sshsec "SSH Local Port Protections"
-
- global help_font
- eval text .sshsec.t -width 80 -height 28 $help_font
-
- apply_bg .sshsec.t
-
- set msg {
- See the discussion of "Untrusted Local Users" in the main 'Help'
- panel for info about users who are able to log into the workstation
- you run SSVNC on and might try to use your encrypted tunnel to gain
- access to the remote VNC machine.
-
- On Unix, for SSH tunnels we have an LD_PRELOAD hack (lim_accept.so)
- that will limit ssh from accepting any local redirection connections
- after the first one or after 35 seconds, whichever comes first.
- The first SSH port redirection connection is intended to be the one
- that tunnels your VNC Viewer to reach the remote server.
-
- You can adjust these defaults LIM_ACCEPT=1 LIM_ACCEPT_TIME=35 by
- setting those env. vars. to different values.
-
- Note that there is still a window of a few seconds the Untrusted
- Local User can try to connect before your VNC Viewer does. So this
- method is far from perfect. But once your VNC session is established,
- he should be blocked out. Test to make sure blocking is taking place.
-
- Do not use this option if you are doing SSH Service redirections
- 'Additional Port Redirections (via SSH)' that redirect a local port
- to the remote server via ssh -L.
-
- Note that if the shared object "lim_accept.so" cannot be found,
- this option has no effect. Watch the output in the terminal for
- the "SSVNC_LIM_ACCEPT_PRELOAD" setting.
-}
- .sshsec.t insert end $msg
-
- button .sshsec.cancel -text "Cancel" -command {set ssh_local_protection 0; destroy .sshsec}
- bind .sshsec <Escape> {set ssh_local_protection 0; destroy .sshsec}
- wm protocol .sshsec WM_DELETE_WINDOW {set ssh_local_protection 0; destroy .sshsec}
- button .sshsec.done -text "Done" -command {destroy .sshsec}
-
- pack .sshsec.t .sshsec.cancel .sshsec.done -side top -fill x
-
- center_win .sshsec
- wm resizable .sshsec 1 0
-}
-
-proc multilisten_dialog {} {
- global multiple_listen
-
- toplev .multil
- wm title .multil "Multiple LISTEN Connections"
-
- global help_font
- set h 36
- if [small_height] {
- set h 30
- }
- eval text .multil.t -width 84 -height $h $help_font
-
- apply_bg .multil.t
-
- set msg {
- Set this option to allow SSVNC (when in LISTEN / Reverse connections
- mode) to allow multiple VNC servers to connect at the same time and
- so display each of their desktops on your screen at the same time.
-
- This option only applies on Unix or MaOSX when using the supplied
- SSVNC vncviewer. If you specify your own VNC Viewer it has no effect.
-
- On Windows (only the stock TightVNC viewer is provided) it has no effect
- because the Windows SSVNC can ONLY do "Multiple LISTEN Connections".
- Similarly on MacOSX if the COTVNC viewer is used there is no effect.
-
- Rationale: To play it safe, the Unix vncviewer provided by SSVNC
- (ssvncviewer) only allows one LISTEN reverse connection at a time.
- This is to prohibit malicious people on the network from depositing
- as many desktops on your screen as he likes, even if you are already
- connected to VNC server you desire.
-
- For example, perhaps the malicious user could trick you into typing
- a password into the desktop he displays on your screen.
-
- This protection is not perfect, because the malicious user could
- try to reverse connect to you before the correct VNC server reverse
- connects to you. This is even more of a problem if you keep your
- SSVNC viewer in LISTEN mode but unconnected for long periods of time.
- Pay careful attention in this case if you are to supplying sensitive
- information to the remote desktop.
-
- Enable 'Multiple LISTEN Connections' if you want to disable the default
- protection in the Unix SSVNC vncviewer; i.e. allow multiple reverse
- connections simultaneously (all vnc viewers we know of do this by default)
-
- For more control, do not select 'Multiple LISTEN Connections', but
- rather set the env. var SSVNC_MULTIPLE_LISTEN=MAX:n to limit the number
- of simultaneous reverse connections to "n"
-}
- .multil.t insert end $msg
-
- button .multil.cancel -text "Cancel" -command {set multiple_listen 0; destroy .multil}
- bind .multil <Escape> {set multiple_listen 0; destroy .multil}
- wm protocol .multil WM_DELETE_WINDOW {set multiple_listen 0; destroy .multil}
- button .multil.done -text "Done" -command {destroy .multil}
-
- pack .multil.t .multil.cancel .multil.done -side top -fill x
-
- center_win .multil
- wm resizable .multil 1 0
-}
-
-proc use_grab_dialog {} {
- global usg_grab
-
- toplev .usegrb
- wm title .usegrb "Use XGrabServer (for fullscreen)"
-
- global help_font
- eval text .usegrb.t -width 85 -height 29 $help_font
-
- apply_bg .usegrb.t
-
- set msg {
- On Unix, some Window managers and some Desktops make it difficult for the
- SSVNC Unix VNC viewer to go into full screen mode (F9) and/or return.
-
- Sometimes one can go into full screen mode, but then your keystrokes or
- Mouse actions do not get through. This can leave you trapped because you
- cannot inject input (F9 again) to get out of full screen mode. (Tip:
- press Ctrl-Alt-F2 for a console login shell; then kill your vncviewer
- process, e.g. pkill vncviewer; then Alt-F7 to get back to your desktop)
-
- We have seen this in some very old Window managers (e.g. fvwm2 circa
- 1998) and some very new Desktops (e.g. GNOME circa 2008). We try
- to work around the problem on recent desktops by using the NEW_WM
- interface, but if you use Fullscreen, you may need to use this option.
-
- The default for the SSVNC Unix VNC viewer is '-grabkbd' mode where it will
- try to exclusively grab the keyboard. This often works correctly.
-
- However if Fullscreen is not working properly, try setting this
- 'Use XGrabServer' option to enable '-graball' mode where it tries to grab
- the entire X server. This usually works, but can be a bit flakey.
-
- Sometimes toggling F9 a few times gets lets the vncviewer fill the whole
- screen. Sometimes tapping F9 very quickly gets it to snap in. If GNOME
- (or whatever desktop) is still showing its taskbars, it is recommended
- you toggle F9 until it isn't. Otherwise, it is not clear who gets the input.
-
- Best of luck.
-}
- .usegrb.t insert end $msg
-
- button .usegrb.cancel -text "Cancel" -command {set use_grab 0; destroy .usegrb}
- bind .usegrb <Escape> {set use_grab 0; destroy .usegrb}
- wm protocol .usegrb WM_DELETE_WINDOW {set use_grab 0; destroy .usegrb}
- button .usegrb.done -text "Done" -command {destroy .usegrb}
-
- pack .usegrb.t .usegrb.cancel .usegrb.done -side top -fill x
-
- center_win .usegrb
- wm resizable .usegrb 1 0
-}
-
-
-proc find_netcat {} {
- global is_windows
-
- set nc ""
-
- if {! $is_windows} {
- set nc [in_path "netcat"]
- if {$nc == ""} {
- set nc [in_path "nc"]
- }
- } else {
- set try "netcat.exe"
- if [file exists $try] {
- set nc $try
- }
- }
- return $nc
-}
-
-proc pk_expand {cmd host} {
- global tcl_platform
- set secs [clock seconds]
- set msecs [clock clicks -milliseconds]
- set user $tcl_platform(user)
- if [regexp {%IP} $cmd] {
- set ip [guess_ip]
- if {$ip == ""} {
- set ip "unknown"
- }
- regsub -all {%IP} $cmd $ip cmd
- }
- if [regexp {%NAT} $cmd] {
- set ip [guess_nat_ip]
- regsub -all {%NAT} $cmd $ip cmd
- }
- regsub -all {%HOST} $cmd $host cmd
- regsub -all {%USER} $cmd $user cmd
- regsub -all {%SECS} $cmd $secs cmd
- regsub -all {%MSECS} $cmd $msecs cmd
-
- return $cmd
-}
-
-proc backtick_expand {str} {
- set str0 $str
- set collect ""
- set count 0
- while {[regexp {^(.*)`([^`]+)`(.*)$} $str mv p1 cmd p2]} {
- set out [eval exec $cmd]
- set str "$p1$out$p2"
- incr count
- if {$count > 10} {
- break
- }
- }
- return $str
-}
-
-proc read_from_pad {file} {
- set fh ""
- if {[catch {set fh [open $file "r"]}] != 0} {
- return "FAIL"
- }
-
- set accum ""
- set match ""
- while {[gets $fh line] > -1} {
- if [regexp {^[ \t]*#} $line] {
- append accum "$line\n"
- } elseif [regexp {^[ \t]*$} $line] {
- append accum "$line\n"
- } elseif {$match == ""} {
- set match $line
- append accum "# $line\n"
- } else {
- append accum "$line\n"
- }
- }
-
- close $fh
-
- if {$match == ""} {
- return "FAIL"
- }
-
- if {[catch {set fh [open $file "w"]}] != 0} {
- return "FAIL"
- }
-
- puts -nonewline $fh $accum
-
- return $match
-}
-
-proc do_port_knock {hp mode} {
- global use_port_knocking port_knocking_list
- global is_windows
-
- if {! $use_port_knocking} {
- return 1
- }
- if {$port_knocking_list == ""} {
- return 1
- }
- set list $port_knocking_list
-
- if {$mode == "finish"} {
- if {! [regexp {FINISH} $list]} {
- mesg "PortKnock(finish): done"
- return 1
- } else {
- regsub {^.*FINISH} $list "" list
- }
- } elseif {$mode == "start"} {
- if {[regexp {FINISH} $list]} {
- regsub {FINISH.*$} $list "" list
- }
- }
-
- set default_delay 150
-
- set host [string trim $hp]
- # XXX host_part
- regsub {^vnc://} $host "" host
- regsub {^.*@} $host "" host
- regsub {:[0-9][0-9]*$} $host "" host
- set host0 [string trim $host]
-
- if {$host0 == ""} {
- bell
- mesg "PortKnock: No host: $hp"
- return 0
- }
-
- set m ""
-
- if [regexp {PAD=([^\n]+)} $list mv padfile] {
- set tlist [read_from_pad $padfile]
- set tlist [string trim $tlist]
- if {$tlist == "" || $tlist == "FAIL"} {
- raise .
- tk_messageBox -type ok -icon error \
- -message "Failed to read entry from $padfile" \
- -title "Error: Padfile $padfile"
- return 0
- }
- regsub -all {PAD=([^\n]+)} $list $tlist list
- }
-
- set spl ",\n\r"
- if [regexp {CMD=} $list] {set spl "\n\r"}
- if [regexp {CMDX=} $list] {set spl "\n\r"}
- if [regexp {SEND=} $list] {set spl "\n\r"}
- if [regexp {SENDX=} $list] {set spl "\n\r"}
-
- set i 0
- set pi 0
-
- foreach line [split $list $spl] {
- set line [string trim $line]
- set line0 $line
-
- if {$line == ""} {
- continue
- }
- if [regexp {^#} $line] {
- continue
- }
-
- if [regexp {^sleep[ \t][ \t]*([0-9][0-9]*)} $line mv sl] {
- set m "PortKnock: sleep $sl"
- mesg $m
- after $sl
- continue
- }
- if [regexp {^delay[ \t][ \t]*([0-9][0-9]*)} $line mv sl] {
- set m "PortKnock: delay=$sl"
- mesg $m
- set default_delay $sl
- continue
- }
-
- if [regexp {^CMD=(.*)} $line mv cmd] {
- set m "PortKnock: CMD: $cmd"
- mesg $m
- eval exec $cmd
- continue
- }
- if [regexp {^CMDX=(.*)} $line mv cmd] {
- set cmd [pk_expand $cmd $host0]
- set m "PortKnock: CMDX: $cmd"
- mesg $m
- eval exec $cmd
- continue
- }
-
- if [regexp {`} $line] {
- #set line [backtick_expand $line]
- }
-
- set snd ""
- if [regexp {^(.*)SEND=(.*)$} $line mv line snd] {
- set line [string trim $line]
- set snd [string trim $snd]
- regsub -all {%NEWLINE} $snd "\n" snd
- } elseif [regexp {^(.*)SENDX=(.*)$} $line mv line snd] {
- set line [string trim $line]
- set snd [string trim $snd]
- set snd [pk_expand $snd $host0]
- regsub -all {%NEWLINE} $snd "\n" snd
- }
-
- set udp 0
- if [regexp -nocase {[/:]udp} $line] {
- set udp 1
- regsub -all -nocase {[/:]udp} $line " " line
- set line [string trim $line]
- }
- regsub -all -nocase {[/:]tcp} $line " " line
- set line [string trim $line]
-
- set delay 0
- if [regexp {^(.*)[ \t][ \t]*([0-9][0-9]*)$} $line mv first delay] {
- set line [string trim $first]
- }
-
- if {[regexp {^(.*):([0-9][0-9]*)$} $line mv host port]} {
- ;
- } else {
- set host $host0
- set port $line
- }
- set host [string trim $host]
- set port [string trim $port]
-
- if {$host == ""} {
- set host $host0
- }
-
- if {$port == ""} {
- bell
- set m "PortKnock: No port found: \"$line0\""
- mesg $m
- return 0
- }
- if {! [regexp {^[0-9][0-9]*$} $port]} {
- bell
- set m "PortKnock: Invalid port: \"$port\""
- mesg $m
- return 0
- }
- regsub {,.*$} $host "" host
- if {[regexp {[ \t]} $host]} {
- bell
- set m "PortKnock: Invalid host: \"$host\""
- mesg $m
- return 0
- }
- if {! [regexp {^[-A-z0-9_.][-A-z0-9_.]*$} $host]} {
- bell
- set m "PortKnock: Invalid host: \"$host\""
- mesg $m
- return 0
- }
-
- set nc ""
- if {$udp || $snd != ""} {
- set nc [find_netcat]
- if {$nc == ""} {
- bell
- set m "PortKnock: UDP: netcat(1) not found"
- mesg $m
- after 1000
- continue
- }
- }
-
- if {$snd != ""} {
- global env
- set pfile "payload$pi.txt"
- if {! $is_windows} {
- set pfile "$env(SSVNC_HOME)/.$pfile"
- }
- set pfiles($pi) $pfile
- incr pi
- set fh [open $pfile "w"]
- puts -nonewline $fh "$snd"
- close $fh
-
- set m "PortKnock: SEND: $host $port"
- mesg $m
- if {$is_windows} {
- if {$udp} {
- catch {exec $nc -d -u -w 1 "$host" "$port" < $pfile &}
- } else {
- catch {exec $nc -d -w 1 "$host" "$port" < $pfile &}
- }
- } else {
- if {$udp} {
- catch {exec $nc -u -w 1 "$host" "$port" < $pfile &}
- } else {
- catch {exec $nc -w 1 "$host" "$port" < $pfile &}
- }
- }
- catch {after 50; file delete $pfile}
-
- } elseif {$udp} {
- set m "PortKnock: UDP: $host $port"
- mesg $m
- if {! $is_windows} {
- catch {exec echo a | $nc -u -w 1 "$host" "$port" &}
- } else {
- set fh [open "nc_in.txt" "w"]
- puts $fh "a"
- close $fh
- catch {exec $nc -d -u -w 1 "$host" "$port" < "nc_in.txt" &}
- }
- } else {
- set m "PortKnock: TCP: $host $port"
- mesg $m
- set s ""
- set emess ""
- set rc [catch {set s [socket -async $host $port]} emess]
- if {$rc != 0} {
- raise .
- tk_messageBox -type ok -icon error -message $emess -title "Error: socket -async $host $port"
- }
- set sockets($i) $s
- # seems we have to close it immediately to avoid multiple SYN's.
- # does not help on Win9x.
- catch {after 30; close $s};
- incr i
- }
-
- if {$delay == 0} {
- if {$default_delay > 0} {
- after $default_delay
- }
- } elseif {$delay > 0} {
- after $delay
- }
- }
-
- if {0} {
- for {set j 0} {$j < $i} {incr j} {
- set $s $sockets($j)
- if {$s != ""} {
- catch {close $s}
- }
- }
- }
- for {set j 0} {$j < $pi} {incr j} {
- set f $pfiles($j)
- if {$f != ""} {
- if [file exists $f] {
- after 100
- }
- catch {file delete $f}
- }
- }
- if {$is_windows} {
- catch {file delete "nc_in.txt"}
- }
- if {$m != ""} {
- set m "$m,"
- }
- if {$mode == "finish"} {
- mesg "PortKnock(finish): done"
- } else {
- mesg "PortKnock: done"
- }
- return 1
-}
-
-proc port_knocking_dialog {} {
- toplev .pk
- wm title .pk "Port Knocking"
- global use_port_knocking port_knocking_list
-
- global help_font
-
- global uname
-
- set h 35
- if [small_height] {
- set h 22
- } elseif {$uname == "Darwin"} {
- set h 25
- }
- scroll_text .pk.f 85 $h
-
- set msg {
- Description:
-
- Port Knocking is where a network connection to a service is not provided
- to just any client, but rather only to those that immediately prior to
- connecting send a more or less secret pattern of connections to other
- ports on the firewall.
-
- Somewhat like "knocking" on the door with the correct sequence before it
- being opened (but not necessarily letting you in yet). It is also possible
- to have a single encrypted packet (e.g. UDP) payload communicate with the
- firewall instead of knocking on a sequence of ports.
-
- Only after the correct sequence of ports is observed by the firewall does
- it allow the IP address of the client to attempt to connect to the service.
-
- So, for example, instead of allowing any host on the internet to connect
- to your SSH service and then try to login with a username and password, the
- client first must "tickle" your firewall with the correct sequence of ports.
- Only then will it be allowed to connect to your SSH service at all.
-
- This does not replace the authentication and security of SSH, it merely
- puts another layer of protection around it. E.g., suppose an exploit for
- SSH was discovered, you would most likely have more time to fix/patch
- the problem than if any client could directly connect to your SSH server.
-
- For more information http://www.portknocking.org/ and
- http://www.linuxjournal.com/article/6811
-
-
- Tip:
-
- If you just want to use the Port Knocking for an SSH shell and not
- for a VNC tunnel, then specify something like "user@hostname cmd=SHELL"
- (or "user@hostname cmd=PUTTY" on Windows) in the VNC Host:Display entry box
- on the main panel. This will do everything short of starting the viewer.
- A shortcut for this is Ctrl-S as long as user@hostname is present.
-
-
- Specifying the Knocks:
-
- In the text area below "Supply port knocking pattern" you put in the pattern
- of "knocks" needed for this connection. You can separate the knocks by
- commas or put them one per line.
-
- Each "knock" is of this form:
-
- [host:]port[/udp] [delay]
-
- In the simplest form just a numerical port, e.g. 5433, is supplied.
- Items inside [...] are optional and described below.
-
- The packet is sent to the same host that the VNC (or SSH) connection will
- be made to. If you want it to go to a different host or IP use the [host:]
- prefix. It can be either a hostname or numerical IP.
-
- A TCP packet is sent by default.
-
- If you need to send a UDP packet, the netcat (aka "nc") program must be
- installed on Unix (tcl/tk does not support udp connections). Indicate this
- with "/udp" following the port number (you can also use "/tcp", but since
- it is the default it is not necessary). (You can also use ":udp" to match
- the knockd syntax). See the example below. For convenience a Windows netcat
- binary is supplied.
-
- The last field, [delay], is an optional number of milliseconds to delay
- before continuing on to the next knock.
-
-
- Examples:
-
- 5433, 12321, 1661
-
- fw.example.com:5433, 12321/udp 3000, 1661 2000
-
- fw.example.com:5433
- 12321/udp 3000
- 1661 2000
-
- Note how the first two examples separate their knocks via commas ",".
- The 3rd example is equivalent to the 2nd and splits them up by new lines.
-
- Note for each knock any second number (e.g. the "2000" in "1661 2000") is
- a DELAY in milliseconds, not a port number. If you had a comma separating
- them: "1661, 2000" that would mean two separate knocks: one to port 1661
- followed by one to 2000 (with basically no delay between them).
-
- In examples 2 and 3, "fw.example.com" represents some machine other than
- the VNC/SSH host. By default, the VNC/SSH host is the one the packet is
- sent to.
-
- If one of the items is the string "FINISH", then the part before it is
- used prior to connecting and the part after is used once the connection
- is finished. This can be used, say, to close the firewall port. Example:
-
- 5433, 12321, FINISH, 7659, 2314
-
- (or one can split them up via lines as above.)
-
-
- Advanced port knock actions:
-
- If the string in the text field contains anywhere the strings "CMD=", "CMDX=",
- or "SEND=", then splitting on commas is not done: it is only split on lines.
-
- Then, if a line begins CMD=... the string after the = is run as an
- external command. The command could be anything you want, e.g. it could
- be a port-knocking client that does the knocking, perhaps encrypting the
- "knocks" pattern somehow or using a Single Packet Authorization method such
- as http://www.cipherdyne.com/fwknop/
-
- Extra quotes (sometimes "'foo bar'") may be needed to preserve spaces in
- command line arguments because the tcl/tk eval(n) command is used. You
- can also use {...} for quoting strings with spaces.
-
- If a line begins CMDX=... then before the command is run the following
- tokens are expanded to strings:
-
- %IP Current machine's IP address (NAT may make this not useful).
- %NAT Try to get effective IP by contacting http://www.whatismyip.com
- %HOST The remote host of the connection.
- %USER The current user.
- %SECS The current time in seconds (platform dependent).
- %MSECS Platform dependent time having at least millisecond granularity.
-
- Lines not matching CMD= or CMDX= are treated as normal port knocks but with
- one exception. If a line ends in SEND=... (i.e. after the [host:]port,
- etc., part) then the string after the = is sent as a payload for the tcp
- or udp connection to [host:]port. netcat is used for these SEND cases
- (and must be available on Unix). If newlines (\n) are needed in the
- SEND string, use %NEWLINE. Sending binary data is not yet supported;
- use CMD= with your own program.
-
-
- Advanced Examples:
-
- CMD=port_knock_client -password wombat33
- CMDX=port_knock_client -password wombat33 -host %HOST -src %NAT
-
- fw.example.com:5433/udp SEND=ASDLFKSJDF
-
-
- More tricks:
-
- To temporarily "comment out" a knock, insert a leading "#" character.
-
- Use "sleep N" to insert a raw sleep for N milliseconds (e.g. between
- CMD=... items or at the very end of the knocks to wait).
-
- If a knock entry matches "delay N" the default delay is set to
- N milliseconds (it is 150 initially).
-
-
- One Time Pads:
-
- If the text contains a (presumably single) line of the form:
-
- PAD=/path/to/a/one/time/pad/file
-
- then that file is opened and the first non-blank line not beginning
- with "#" is used as the knock pattern. The pad file is rewritten
- with that line starting with a "#" (so it will be skipped next time).
-
- The PAD=... string is replaced with the read-in knock pattern line.
- So, if needed, one can preface the PAD=... with "delay N" to set the
- default delay, and one can also put a "sleep N" after the PAD=...
- line to indicate a final sleep. One can also surround the PAD=
- line with other knock and CMD= CMDX= lines, but that usage sounds
- a bit rare. Example:
-
- delay 1000
- PAD=C:\My Pads\work-pad1.txt
- sleep 4000
-
-
- Port knock only:
-
- If, in the 'VNC Host:Display' entry, you use "user@hostname cmd=KNOCK"
- then only the port-knocking is performed. A shortcut for this is
- Ctrl-P as long as hostname is present in the entry box. If it
- matches cmd=KNOCKF, i.e. an extra "F", then the port-knocking
- "FINISH" sequence is sent, if any. A shortcut for this Shift-Ctrl-P
- as long as hostname is present.
-}
- .pk.f.t insert end $msg
-
- label .pk.info -text "Supply port knocking pattern:" -anchor w -relief ridge
-
- eval text .pk.rule -width 80 -height 5 $help_font
- .pk.rule insert end $port_knocking_list
-
- button .pk.cancel -text "Cancel" -command {set use_port_knocking 0; destroy .pk}
- bind .pk <Escape> {set use_port_knocking 0; destroy .pk}
- wm protocol .pk WM_DELETE_WINDOW {set use_port_knocking 0; destroy .pk}
- button .pk.done -text "Done" -command {if {$use_port_knocking} {set port_knocking_list [.pk.rule get 1.0 end]}; destroy .pk}
-
- pack .pk.done .pk.cancel .pk.rule .pk.info -side bottom -fill x
- pack .pk.f -side top -fill both -expand 1
-
- center_win .pk
-}
-
-proc choose_desktop_dialog {} {
- toplev .sd
- wm title .sd "Desktop Type"
- global ts_desktop_type choose_desktop
-
- global ts_desktop_type_def
- set def "kde"
- if {$ts_desktop_type_def != ""} {
- set def $ts_desktop_type_def
- }
-
- if {$ts_desktop_type == ""} {
- set ts_desktop_type $def
- }
-
- label .sd.l1 -anchor w -text "Select the type of remote Desktop"
- label .sd.l2 -anchor w -text "for your session (default: $def)"
-
- radiobutton .sd.b1 -anchor w -variable ts_desktop_type -value kde -text kde
- radiobutton .sd.b2 -anchor w -variable ts_desktop_type -value gnome -text gnome
- radiobutton .sd.b3 -anchor w -variable ts_desktop_type -value Xsession -text cde
- radiobutton .sd.b4 -anchor w -variable ts_desktop_type -value mwm -text mwm
- radiobutton .sd.b5 -anchor w -variable ts_desktop_type -value wmaker -text wmaker
- radiobutton .sd.b6 -anchor w -variable ts_desktop_type -value xfce -text xfce
- radiobutton .sd.b7 -anchor w -variable ts_desktop_type -value enlightenment -text enlightenment
- radiobutton .sd.b8 -anchor w -variable ts_desktop_type -value twm -text twm
- radiobutton .sd.b9 -anchor w -variable ts_desktop_type -value failsafe -text failsafe
-
- button .sd.cancel -text "Cancel" -command {destroy .sd; set choose_desktop 0; set ts_desktop_type ""}
- bind .sd <Escape> {destroy .sd; set choose_desktop 0; set ts_desktop_type ""}
- wm protocol .sd WM_DELETE_WINDOW {destroy .sd; set choose_desktop 0; set ts_desktop_type ""}
- button .sd.done -text "Done" -command {destroy .sd}
-
- pack .sd.l1 .sd.l2 .sd.b1 .sd.b2 .sd.b3 .sd.b4 .sd.b5 .sd.b6 .sd.b7 .sd.b8 .sd.b9 .sd.cancel .sd.done -side top -fill x
-
- center_win .sd
-}
-
-proc choose_size_dialog {} {
- toplev .sz
- wm title .sz "Desktop Size"
- global ts_desktop_size ts_desktop_depth choose_desktop_geom
-
- set def1 "1280x1024"
- set def2 "16"
-
- global ts_desktop_size_def ts_desktop_depth_def
- if {$ts_desktop_size_def != ""} {
- set def1 $ts_desktop_size_def
- }
- if {$ts_desktop_depth_def != ""} {
- set def2 $ts_desktop_depth_def
- }
-
- if {$ts_desktop_size == ""} {
- set ts_desktop_size $def1
- }
- if {$ts_desktop_depth == ""} {
- set ts_desktop_depth $def2
- }
-
- label .sz.l1 -anchor w -text "Select the Size and Color depth"
- label .sz.l2 -anchor w -text "for your Desktop session."
- label .sz.l3 -anchor w -text "Default: $def1 and $def2 bits/pixel."
-
- label .sz.g0 -anchor w -text "Width x Height:" -relief groove
-
- radiobutton .sz.g1 -anchor w -variable ts_desktop_size -value "640x480" -text " 640x480"
- radiobutton .sz.g2 -anchor w -variable ts_desktop_size -value "800x600" -text " 800x600"
- radiobutton .sz.g3 -anchor w -variable ts_desktop_size -value "1024x768" -text " 1024x768"
- radiobutton .sz.g4 -anchor w -variable ts_desktop_size -value "1280x1024" -text "1280x1024"
- radiobutton .sz.g5 -anchor w -variable ts_desktop_size -value "1400x1050" -text "1400x1050"
- radiobutton .sz.g6 -anchor w -variable ts_desktop_size -value "1600x1200" -text "1600x1200"
- radiobutton .sz.g7 -anchor w -variable ts_desktop_size -value "1920x1200" -text "1920x1200"
-
- frame .sz.c
- label .sz.c.l -anchor w -text "Custom:"
- entry .sz.c.e -width 10 -textvariable ts_desktop_size
- pack .sz.c.l -side left
- pack .sz.c.e -side left -expand 1 -fill x
- bind .sz.c.e <Return> {destroy .sz}
-
- label .sz.d0 -anchor w -text "Color Depth:" -relief groove
-
- radiobutton .sz.d1 -anchor w -variable ts_desktop_depth -value "8" -text " 8 bits/pixel"
- radiobutton .sz.d2 -anchor w -variable ts_desktop_depth -value "16" -text "16 bits/pixel"
- radiobutton .sz.d3 -anchor w -variable ts_desktop_depth -value "24" -text "24 bits/pixel"
-
- button .sz.cancel -text "Cancel" -command {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""}
- bind .sz <Escape> {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""}
- wm protocol .sz WM_DELETE_WINDOW {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""}
- button .sz.done -text "Done" -command {destroy .sz}
-
- pack .sz.l1 .sz.l2 .sz.l3 \
- .sz.g0 .sz.g1 .sz.g2 .sz.g3 .sz.g4 .sz.g5 .sz.g6 .sz.g7 \
- .sz.c \
- .sz.d0 .sz.d1 .sz.d2 .sz.d3 \
- .sz.cancel .sz.done -side top -fill x
-
- center_win .sz
- focus .sz.c.e
-}
-
-proc choose_xserver_dialog {} {
- toplev .st
- wm title .st "X Server Type"
- global ts_xserver_type choose_xserver
-
- set def "Xvfb"
- global ts_xserver_type_def
- if {$ts_xserver_type_def != ""} {
- set def $ts_xserver_type_def
- }
-
- if {$ts_xserver_type == ""} {
- set ts_xserver_type $def
- }
-
- label .st.l1 -anchor w -text "Select the type of remote X server"
- label .st.l2 -anchor w -text "for your session (default: $def)"
-
- radiobutton .st.b1 -anchor w -variable ts_xserver_type -value Xvfb -text "Xvfb"
-
- radiobutton .st.b2 -anchor w -variable ts_xserver_type -value Xdummy -text "Xdummy"
-
- radiobutton .st.b3 -anchor w -variable ts_xserver_type -value Xvnc -text "Xvnc"
-
- radiobutton .st.b4 -anchor w -variable ts_xserver_type -value Xvnc.redirect -text "Xvnc.redirect"
-
- button .st.cancel -text "Cancel" -command {destroy .st; set choose_xserver 0; set ts_xserver_type ""}
- bind .st <Escape> {destroy .st; set choose_xserver 0; set ts_xserver_type ""}
- wm protocol .st WM_DELETE_WINDOW {destroy .st; set choose_xserver 0; set ts_xserver_type ""}
- button .st.done -text "Done" -command {destroy .st}
-
- pack .st.l1 .st.l2 .st.b1 .st.b2 .st.b3 .st.b4 .st.cancel .st.done -side top -fill x
-
- center_win .st
-}
-
-proc set_ts_options {} {
- global use_cups use_sound use_smbmnt
- global change_vncviewer choose_xserver
- global ts_only is_windows
- global darwin_cotvnc use_x11_macosx uname
- if {! $ts_only} {
- return
- }
- catch {destroy .o}
- toplev .ot
- wm title .ot "Options"
-
- set i 1
-
- checkbutton .ot.b$i -anchor w -variable choose_desktop -text \
- "Desktop Type" \
- -command {if {$choose_desktop} {choose_desktop_dialog}}
- incr i
-
- checkbutton .ot.b$i -anchor w -variable choose_desktop_geom -text \
- "Desktop Size" \
- -command {if {$choose_desktop_geom} {choose_size_dialog}}
- incr i
-
- checkbutton .ot.b$i -anchor w -variable choose_xserver -text \
- "X Server Type" \
- -command {if {$choose_xserver} {choose_xserver_dialog}}
- incr i
-
- checkbutton .ot.b$i -anchor w -variable use_cups -text \
- "Enable Printing" \
- -command {if {$use_cups} {cups_dialog}}
- incr i
-
- checkbutton .ot.b$i -anchor w -variable use_sound -text \
- "Enable Sound" \
- -command {if {$use_sound} {sound_dialog}}
- incr i
-
-# checkbutton .ot.b$i -anchor w -variable use_smbmnt -text \
-# "Enable SMB mount tunnelling" \
-# -command {if {$use_smbmnt} {smb_dialog}}
-# incr i
-
- checkbutton .ot.b$i -anchor w -variable choose_filexfer -text \
- "File Transfer" \
- -command {if {$choose_filexfer} {ts_filexfer_dialog}}
- incr i
-
- checkbutton .ot.b$i -anchor w -variable use_viewonly -text \
- "View Only"
- incr i
-
- checkbutton .ot.b$i -anchor w -variable change_vncviewer -text \
- "Change VNC Viewer" \
- -command change_vncviewer_dialog_wrap
- incr i
-
- if {!$is_windows && $uname == "Darwin"} {
- checkbutton .ot.b$i -anchor w -variable use_x11_macosx -text \
- "X11 viewer MacOSX" \
- -command {if {$use_x11_macosx} {set darwin_cotvnc 0} else {set darwin_cotvnc 1}; set_darwin_cotvnc_buttons}
- incr i
- }
-
- button .ot.b$i -anchor w -text " Delete Profile..." \
- -command {destroy .ot; delete_profile}
- incr i
-
- button .ot.b$i -anchor w -text " Advanced ..." -command {set_ts_adv_options}
- incr i
-
- for {set j 1} {$j < $i} {incr j} {
- pack .ot.b$j -side top -fill x
- }
-
- frame .ot.b
- button .ot.b.done -text "Done" -command {destroy .ot}
- button .ot.b.help -text "Help" -command help_ts_opts
- pack .ot.b.help .ot.b.done -fill x -expand 1 -side left
-
- bind .ot <Escape> {destroy .ot}
- wm protocol .ot WM_DELETE_WINDOW {destroy .ot}
-
- pack .ot.b -side top -fill x
-
- center_win .ot
- wm resizable .ot 1 0
- focus .ot
-}
-
-proc set_ts_adv_options {} {
- global ts_only ts_unixpw ts_vncshared
- global ts_ncache ts_multisession
- global choose_othervnc darwin_cotvnc choose_sleep
- global is_windows
-
- if {! $ts_only} {
- return
- }
- catch {destroy .ot}
- toplev .ot2
- wm title .ot2 "Advanced"
-
- set i 1
-
- checkbutton .ot2.b$i -anchor w -variable ts_vncshared -text \
- "VNC Shared" \
- -command {if {$ts_vncshared} {ts_vncshared_dialog}}
- incr i
-
- checkbutton .ot2.b$i -anchor w -variable choose_multisession -text \
- "Multiple Sessions" \
- -command {if {$choose_multisession} {ts_multi_dialog}}
- incr i
-
- checkbutton .ot2.b$i -anchor w -variable ts_xlogin -text \
- "X Login Greeter" \
- -command {if {$ts_xlogin} {ts_xlogin_dialog}}
- incr i
-
- checkbutton .ot2.b$i -anchor w -variable choose_othervnc -text \
- "Other VNC Server" \
- -command {if {$choose_othervnc} {ts_othervnc_dialog}}
- incr i
-
- checkbutton .ot2.b$i -anchor w -variable ts_unixpw -text \
- "Use unixpw" \
- -command {if {$ts_unixpw} {ts_unixpw_dialog}}
- incr i
-
- checkbutton .ot2.b$i -anchor w -variable use_bgr233 -text \
- "Client 8bit Color"
- if {$darwin_cotvnc} {.ot2.b$i configure -state disabled}
- global darwin_cotvnc_blist
- set darwin_cotvnc_blist(.ot2.b$i) 1
- incr i
-
- checkbutton .ot2.b$i -anchor w -variable choose_ncache -text \
- "Client-Side Caching" \
- -command {if {$choose_ncache} {ts_ncache_dialog}}
- incr i
-
- checkbutton .ot2.b$i -anchor w -variable choose_x11vnc_opts -text \
- "X11VNC Options" \
- -command {if {$choose_x11vnc_opts} {ts_x11vnc_opts_dialog}}
- incr i
-
- checkbutton .ot2.b$i -anchor w -variable choose_sleep -text \
- "Extra Sleep" \
- -command {if {$choose_sleep} {ts_sleep_dialog}}
- incr i
-
- if {$is_windows} {
- checkbutton .ot2.b$i -anchor w -variable choose_parg -text \
- "Putty Args" \
- -command {if {$choose_parg} {ts_putty_args_dialog}}
- incr i
- }
-
- if {!$is_windows} {
- checkbutton .ot2.b$i -anchor w -variable ssh_local_protection -text \
- "SSH Local Protections" \
- -command {if {$ssh_local_protection} {ssh_sec_dialog}}
- if {$is_windows} {.ot2.b$i configure -state disabled}
- incr i
-
- checkbutton .ot2.b$i -anchor w -variable ssh_known_hosts -text \
- "SSH KnownHosts file" \
- -command {if {$ssh_known_hosts} {ssh_known_hosts_dialog}}
- if {$is_windows} {.ot2.b$i configure -state disabled}
- incr i
- }
-
- if {$is_windows} {
- button .ot2.b$i -anchor w -text " Putty Agent" \
- -command {catch {exec pageant.exe &}}
- incr i
-
- button .ot2.b$i -anchor w -text " Putty Key-Gen" \
- -command {catch {exec puttygen.exe &}}
- incr i
- }
-
- global env
- if {![info exists env(SSVNC_TS_ALWAYS)]} {
- button .ot2.b$i -anchor w -text " SSVNC Mode" \
- -command {destroy .ot2; to_ssvnc}
- incr i
- }
-
- if {!$is_windows} {
- button .ot2.b$i -anchor w -text " Unix ssvncviewer ..." \
- -command {set_ssvncviewer_options}
- if {$is_windows} {
- .ot2.b$i configure -state disabled
- }
- global change_vncviewer
- if {$change_vncviewer} {
- .ot2.b$i configure -state disabled
- }
- global ts_uss_button
- set ts_uss_button .ot2.b$i
- incr i
- }
-
- for {set j 1} {$j < $i} {incr j} {
- pack .ot2.b$j -side top -fill x
- }
-
- frame .ot2.b
- button .ot2.b.done -text "Done" -command {destroy .ot2}
- button .ot2.b.help -text "Help" -command help_ts_opts
- pack .ot2.b.help .ot2.b.done -fill x -expand 1 -side left
-
- bind .ot2 <Escape> {destroy .ot2}
- wm protocol .ot2 WM_DELETE_WINDOW {destroy .ot2}
-
- pack .ot2.b -side top -fill x
-
- center_win .ot2
- wm resizable .ot2 1 0
- focus .ot2
-}
-
-proc change_vncviewer_dialog_wrap {} {
- global change_vncviewer ts_uss_button is_windows
- if {$change_vncviewer} {
- change_vncviewer_dialog
- catch {tkwait window .chviewer}
- }
- if {$change_vncviewer || $is_windows} {
- catch {.oa.ss configure -state disabled}
- } else {
- catch {.oa.ss configure -state normal}
- }
- if [info exists ts_uss_button] {
- if {$change_vncviewer || $is_windows} {
- catch {$ts_uss_button configure -state disabled}
- } else {
- catch {$ts_uss_button configure -state normal}
- }
- }
-}
-
-proc set_advanced_options {} {
- global use_cups use_sound use_smbmnt
- global change_vncviewer
- global use_port_knocking port_knocking_list
- global is_windows darwin_cotvnc
- global use_ssh use_sshssl
- global use_x11_macosx
- global adv_ssh
- global showing_no_encryption
- global x11vnc_xlogin_widget
-
- catch {destroy .o}
- toplev .oa
- wm title .oa "Advanced Options"
-
- set i 1
-
- checkbutton .oa.b$i -anchor w -variable use_cups -text \
- "Enable CUPS Print tunnelling" \
- -command {if {$use_cups} {cups_dialog}}
- if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
- set adv_ssh(cups) .oa.b$i
- incr i
-
- checkbutton .oa.b$i -anchor w -variable use_sound -text \
- "Enable ESD/ARTSD Audio tunnelling" \
- -command {if {$use_sound} {sound_dialog}}
- if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
- set adv_ssh(snd) .oa.b$i
- incr i
-
- checkbutton .oa.b$i -anchor w -variable use_smbmnt -text \
- "Enable SMB mount tunnelling" \
- -command {if {$use_smbmnt} {smb_dialog}}
- if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
- set adv_ssh(smb) .oa.b$i
- incr i
-
- checkbutton .oa.b$i -anchor w -variable use_x11vnc_xlogin -text \
- "Automatically Find X Login/Greeter" -command {x11vnc_find_adjust "xlogin"}
- if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
- set x11vnc_xlogin_widget ".oa.b$i"
- incr i
-
- checkbutton .oa.b$i -anchor w -variable additional_port_redirs -text \
- "Additional Port Redirs (via SSH)" \
- -command {if {$additional_port_redirs} {port_redir_dialog}}
- if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
- set adv_ssh(redirs) .oa.b$i
- incr i
-
- global use_ssl use_ssh use_sshssl
-
- if {!$is_windows} {
- checkbutton .oa.b$i -anchor w -variable ssh_known_hosts -text \
- "Private SSH KnownHosts file" \
- -command {if {$ssh_known_hosts} {ssh_known_hosts_dialog}}
- set adv_ssh(knownhosts) .oa.b$i
- if {$use_ssl} {.oa.b$i configure -state disabled}
- if {$is_windows} {.oa.b$i configure -state disabled}
- incr i
-
- checkbutton .oa.b$i -anchor w -variable ssh_local_protection -text \
- "SSH Local Port Protections" \
- -command {if {$ssh_local_protection} {ssh_sec_dialog}}
- global ssh_local_protection_button
- set ssh_local_protection_button .oa.b$i
- if {$use_ssl} {.oa.b$i configure -state disabled}
- if {$is_windows} {.oa.b$i configure -state disabled}
- incr i
- }
-
- global ssh_only
- if {!$ssh_only} {
- if {!$is_windows} {
- checkbutton .oa.b$i -anchor w -variable stunnel_local_protection -text \
- "STUNNEL Local Port Protections" \
- -command {if {$stunnel_local_protection} {stunnel_sec_dialog}}
- global stunnel_local_protection_button
- set stunnel_local_protection_button .oa.b$i
- if {$use_ssh} {.oa.b$i configure -state disabled}
- if {$is_windows} {.oa.b$i configure -state disabled}
- incr i
- }
-
- checkbutton .oa.b$i -anchor w -variable disable_ssl_workarounds -text \
- "Disable SSL Workarounds" \
- -command {if {$disable_ssl_workarounds} {disable_ssl_workarounds_dialog}}
- global disable_ssl_workarounds_button
- set disable_ssl_workarounds_button .oa.b$i
- if {$use_ssh} {.oa.b$i configure -state disabled}
- incr i
-
- if {!$is_windows} {
- checkbutton .oa.b$i -anchor w -variable ultra_dsm -text \
- "UltraVNC DSM Encryption Plugin" \
- -command {if {$ultra_dsm} {ultra_dsm_dialog}}
- global ultra_dsm_button
- set ultra_dsm_button .oa.b$i
- if {$is_windows} {.oa.b$i configure -state disabled}
- if {$use_ssh} {.oa.b$i configure -state disabled}
- incr i
- }
-
- checkbutton .oa.b$i -anchor w -variable no_probe_vencrypt -text \
- "Do not Probe for VeNCrypt"
- global no_probe_vencrypt_button
- set no_probe_vencrypt_button .oa.b$i
- if {$use_ssh} {.oa.b$i configure -state disabled}
- incr i
-
- checkbutton .oa.b$i -anchor w -variable server_vencrypt -text \
- "Server uses VeNCrypt SSL encryption"
- global vencrypt_button
- set vencrypt_button .oa.b$i
- if {$use_ssh} {.oa.b$i configure -state disabled}
- incr i
-
- checkbutton .oa.b$i -anchor w -variable server_anondh -text \
- "Server uses Anonymous Diffie-Hellman" -command no_certs_tutorial_mesg
- global anondh_button
- set anondh_button .oa.b$i
- if {$use_ssh} {.oa.b$i configure -state disabled}
- incr i
- }
-
- checkbutton .oa.b$i -anchor w -variable change_vncviewer -text \
- "Change VNC Viewer" \
- -command change_vncviewer_dialog_wrap
- incr i
-
- checkbutton .oa.b$i -anchor w -variable use_port_knocking -text \
- "Port Knocking" \
- -command {if {$use_port_knocking} {port_knocking_dialog}}
- incr i
-
- for {set j 1} {$j < $i} {incr j} {
- pack .oa.b$j -side top -fill x
- }
-
- global include_list extra_sleep
- frame .oa.fis
- frame .oa.fis.fL
- frame .oa.fis.fR
- label .oa.fis.fL.la -anchor w -text "Include:"
- label .oa.fis.fL.lb -anchor w -text "Sleep:"
- if {$is_windows} {
- label .oa.fis.fL.lc -anchor w -text "Putty Args:"
- pack .oa.fis.fL.la .oa.fis.fL.lb .oa.fis.fL.lc -side top -fill x
- } else {
- pack .oa.fis.fL.la .oa.fis.fL.lb -side top -fill x
- }
-
- entry .oa.fis.fR.ea -width 10 -textvariable include_list
- entry .oa.fis.fR.eb -width 10 -textvariable extra_sleep
- if {$is_windows} {
- entry .oa.fis.fR.ec -width 10 -textvariable putty_args
- pack .oa.fis.fR.ea .oa.fis.fR.eb .oa.fis.fR.ec -side top -fill x
- } else {
- pack .oa.fis.fR.ea .oa.fis.fR.eb -side top -fill x
- }
-
- pack .oa.fis.fL -side left
- pack .oa.fis.fR -side right -expand 1 -fill x
-
- pack .oa.fis -side top -fill x
-
-
- if {!$is_windows} {
- global uname
- set t1 " Unix ssvncviewer ..."
- if {$uname == "Darwin" } { regsub {^ *} $t1 "" t1 }
- button .oa.ss -anchor w -text $t1 -command set_ssvncviewer_options
- pack .oa.ss -side top -fill x
- if {$is_windows} {
- .oa.ss configure -state disabled
- }
- global change_vncviewer
- if {$change_vncviewer} {
- .oa.ss configure -state disabled
- }
-
- set t2 " Use ssh-agent"
- if {$uname == "Darwin" } { regsub {^ *} $t2 "" t2 }
-
- button .oa.sa -anchor w -text $t2 -command ssh_agent_restart
- pack .oa.sa -side top -fill x
- if {$is_windows} {
- .oa.sa configure -state disabled
- }
- } else {
- set t1 " Launch Putty Agent"
- button .oa.pa -anchor w -text $t1 -command {catch {exec pageant.exe &}}
- pack .oa.pa -side top -fill x
-
- set t2 " Launch Putty Key-Gen"
- button .oa.pg -anchor w -text $t2 -command {catch {exec puttygen.exe &}}
- pack .oa.pg -side top -fill x
- }
-
- frame .oa.b
- button .oa.b.done -text "Done" -command {destroy .oa}
- bind .oa <Escape> {destroy .oa}
- wm protocol .oa WM_DELETE_WINDOW {destroy .oa}
- button .oa.b.help -text "Help" -command help_advanced_opts
-
- global use_listen
- if {$use_listen} {
- button .oa.b.connect -text "Listen" -command launch
- } else {
- button .oa.b.connect -text "Connect" -command launch
- }
-
- pack .oa.b.help .oa.b.connect .oa.b.done -fill x -expand 1 -side left
-
- pack .oa.b -side top -fill x
-
- center_win .oa
- wm resizable .oa 1 0
- focus .oa
-}
-
-proc set_ssvncviewer_options {} {
- global is_windows darwin_cotvnc
- global use_ssh use_sshssl use_x11cursor use_rawlocal use_notty use_popupfix use_alpha use_turbovnc disable_pipeline use_grab use_nobell
- global use_send_clipboard use_send_always
- global ssvnc_scale ssvnc_escape
- global server_vencrypt server_anondh
-
- if {$is_windows} {
- return
- }
-
- catch {destroy .oa}
- toplev .os
- wm title .os "Unix ssvncviewer Options"
-
- set darwinlist [list]
-
- set f0 .os.f
- frame $f0
- set fl $f0.fl
- frame $fl
- set fr $f0.fr
- frame $fr
-
- set i 1
- set j 1
-
- checkbutton $fl.b$i -anchor w -variable multiple_listen -text \
- "Multiple LISTEN Connections" \
- -command {if {$multiple_listen} {multilisten_dialog}}
- global multiple_listen_button use_listen
- set multiple_listen_button $fl.b$i
- if {$is_windows} {$fl.b$i configure -state disabled}
- if {!$use_listen} {$fl.b$i configure -state disabled}
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable listen_once -text \
- "Listen Once"
- global listen_once_button
- set listen_once_button $fl.b$i
- if {!$use_listen} {$fl.b$i configure -state disabled}
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable listen_accept_popup -text \
- "Listen Accept Popup Dialog" \
- -command { if {$listen_accept_popup} { catch {$listen_accept_popup_button_sc configure -state normal} } else { catch {$listen_accept_popup_button_sc configure -state disabled} } }
- global listen_accept_popup_button
- set listen_accept_popup_button $fl.b$i
- if {!$use_listen} {$fl.b$i configure -state disabled}
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- global listen_accept_popup
- checkbutton $fl.b$i -anchor w -variable listen_accept_popup_sc -text \
- " Accept Popup UltraVNC Single Click"
- global listen_accept_popup_button_sc
- set listen_accept_popup_button_sc $fl.b$i
- if {!$use_listen} {$fl.b$i configure -state disabled}
- if {!$listen_accept_popup} {$fl.b$i configure -state disabled}
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable use_x11cursor -text \
- "Use X11 Cursor"
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable use_nobell -text \
- "Disable Bell"
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable use_rawlocal -text \
- "Use Raw Local"
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable use_notty -text \
- "Avoid Using Terminal"
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable use_popupfix -text \
- "Use Popup Fix"
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable use_grab -text \
- "Use XGrabServer (for fullscreen)" \
- -command {if {$use_grab} {use_grab_dialog}}
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable use_alpha -text \
- "Cursor Alphablending (32bpp required) "
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable use_turbovnc -text \
- "TurboVNC (if available on platform)"
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable disable_pipeline -text \
- "Disable Pipelined Updates"
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable use_send_clipboard -text \
- "Send CLIPBOARD not PRIMARY"
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- checkbutton $fl.b$i -anchor w -variable use_send_always -text \
- "Send Selection Every time"
- lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
- incr i
-
- set relief ridge
-
- frame $fr.b$j -height 2; incr j
-
- frame $fr.b$j -relief $relief -borderwidth 2
-
- global ffont
- label $fr.b$j.l -font $ffont -anchor w -text "Examples: '0.75', '1024x768', 'fit' (fill screen), or 'auto' ";
-
- global ssvnc_scale
- frame $fr.b$j.f
- label $fr.b$j.f.l -text "Scaling: "
- lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
- entry $fr.b$j.f.e -width 10 -textvariable ssvnc_scale
- lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
- pack $fr.b$j.f.l -side left
- pack $fr.b$j.f.e -side right -expand 1 -fill x
-
- pack $fr.b$j.f $fr.b$j.l -side top -fill x
-
- incr j
-
- frame $fr.b$j -height 2; incr j
-
- frame $fr.b$j -relief $relief -borderwidth 2
-
- label $fr.b$j.l -font $ffont -anchor w -text "Examples: 'default', 'Control_L,Alt_L', 'never'";
-
- global ssvnc_escape
- frame $fr.b$j.f
- label $fr.b$j.f.l -text "Escape Keys: "
- lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
- entry $fr.b$j.f.e -width 10 -textvariable ssvnc_escape
- lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
- button $fr.b$j.f.b -relief ridge -text Help -command ssvnc_escape_help
- lappend darwinlist $fr.b$j.f.b; if {$darwin_cotvnc} {$fr.b$j.f.b configure -state disabled}
- pack $fr.b$j.f.l -side left
- pack $fr.b$j.f.b -side right
- pack $fr.b$j.f.e -side right -expand 1 -fill x
-
- pack $fr.b$j.f $fr.b$j.l -side top -fill x
-
- incr j
-
- frame $fr.b$j -height 2; incr j
-
- frame $fr.b$j -relief $relief -borderwidth 2
-
- label $fr.b$j.l -font $ffont -anchor w -text "Enter the max height in pixels, e.g. '900'";
-
- global ycrop_string
- frame $fr.b$j.f
- label $fr.b$j.f.l -text "Y Crop: "
- lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
- entry $fr.b$j.f.e -width 10 -textvariable ycrop_string
- lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
- pack $fr.b$j.f.l -side left
- pack $fr.b$j.f.e -side right -expand 1 -fill x
-
- pack $fr.b$j.f $fr.b$j.l -side top -fill x
-
- incr j
-
- frame $fr.b$j -height 2; incr j
-
- frame $fr.b$j -relief $relief -borderwidth 2
-
- label $fr.b$j.l -font $ffont -anchor w -text "Enter the scrollbar width in pixels, e.g. '4'";
-
- global sbwid_string
- frame $fr.b$j.f
- label $fr.b$j.f.l -text "ScrollBar Width: "
- lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
- entry $fr.b$j.f.e -width 10 -textvariable sbwid_string
- lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
- pack $fr.b$j.f.l -side left
- pack $fr.b$j.f.e -side right -expand 1 -fill x
-
- pack $fr.b$j.f $fr.b$j.l -side top -fill x
-
- incr j
-
- frame $fr.b$j -height 2; incr j
-
- frame $fr.b$j -relief $relief -borderwidth 2
-
- label $fr.b$j.l -font $ffont -anchor w -text "Enter the RFB version to pretend to be using, e.g. '3.4'";
- label $fr.b$j.l2 -font $ffont -anchor w -text "Sometimes needed for UltraVNC: 3.4, 3.6, 3.14, 3.16";
-
- global rfbversion
- frame $fr.b$j.f
- label $fr.b$j.f.l -text "RFB Version: "
- lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
- entry $fr.b$j.f.e -width 10 -textvariable rfbversion
- lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
- pack $fr.b$j.f.l -side left
- pack $fr.b$j.f.e -side right -expand 1 -fill x
-
- pack $fr.b$j.f $fr.b$j.l $fr.b$j.l2 -side top -fill x
-
- incr j
-
- frame $fr.b$j -height 2; incr j
-
- frame $fr.b$j -relief $relief -borderwidth 2
-
- label $fr.b$j.l1 -font $ffont -anchor w -text "List encodings in preferred order, for example";
- label $fr.b$j.l2 -font $ffont -anchor w -text "'copyrect zrle tight' The full list of encodings is:";
- label $fr.b$j.l3 -font $ffont -anchor w -text "copyrect tight zrle zywrle hextile zlib corre rre raw";
-
- global ssvnc_encodings
- frame $fr.b$j.f
- label $fr.b$j.f.l -text "Encodings: "
- lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
- entry $fr.b$j.f.e -width 10 -textvariable ssvnc_encodings
- lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
- pack $fr.b$j.f.l -side left
- pack $fr.b$j.f.e -side right -expand 1 -fill x
-
- pack $fr.b$j.f $fr.b$j.l1 $fr.b$j.l2 $fr.b$j.l3 -side top -fill x
-
- incr j
-
- frame $fr.b$j -height 2; incr j
-
- frame $fr.b$j -relief $relief -borderwidth 2
-
- label $fr.b$j.l1 -font $ffont -anchor w -text "Add any extra options for ssvncviewer that you want.";
- label $fr.b$j.l2 -font $ffont -anchor w -text "For example: -16bpp -appshare -noshm etc. See Help for a list.";
-
- global ssvnc_extra_opts
- frame $fr.b$j.f
- label $fr.b$j.f.l -text "Extra Options: "
- lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
- entry $fr.b$j.f.e -width 10 -textvariable ssvnc_extra_opts
- lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
- pack $fr.b$j.f.l -side left
- pack $fr.b$j.f.e -side right -expand 1 -fill x
-
- pack $fr.b$j.f $fr.b$j.l1 $fr.b$j.l2 -side top -fill x
-
- incr j
-
- frame $fr.b$j -height 2; incr j
-
- for {set k 1} {$k < $i} {incr k} {
- pack $fl.b$k -side top -fill x
- }
- for {set k 1} {$k < $j} {incr k} {
- pack $fr.b$k -side top -fill x
- }
-
- pack $fl -side left -fill both
- pack $fr -side left -fill both -expand 1
-
- pack $f0 -side top -fill both
-
- frame .os.b
- button .os.b.done -text "Done" -command {destroy .os}
- bind .os <Escape> {destroy .os}
- wm protocol .os WM_DELETE_WINDOW {destroy .os}
- button .os.b.help -text "Help" -command help_ssvncviewer_opts
-
- global use_listen
- if {$use_listen} {
- button .os.b.connect -text "Listen" -command launch
- } else {
- button .os.b.connect -text "Connect" -command launch
- }
-
- pack .os.b.help .os.b.connect .os.b.done -fill x -expand 1 -side left
-
- pack .os.b -side top -fill x
-
- global darwin_cotvnc_blist
- foreach b $darwinlist {
- set darwin_cotvnc_blist($b) 1
- }
-
- center_win .os
- wm resizable .os 1 0
- wm minsize .os [winfo reqwidth .os] [winfo reqheight .os]
- focus .os
-}
-
-
-proc in_path {cmd} {
- global env
- set p $env(PATH)
- foreach dir [split $p ":"] {
- set try "$dir/$cmd"
- if [file exists $try] {
- return "$try"
- }
- }
- return ""
-}
-
-proc ssh_agent_restart {} {
- global env
-
- set got_ssh_agent 0
- set got_ssh_add 0
- set got_ssh_agent2 0
- set got_ssh_add2 0
-
- if {[in_path "ssh-agent"] != ""} {set got_ssh_agent 1}
- if {[in_path "ssh-agent2"] != ""} {set got_ssh_agent2 1}
- if {[in_path "ssh-add"] != ""} {set got_ssh_add 1}
- if {[in_path "ssh-add2"] != ""} {set got_ssh_add2 1}
-
- set ssh_agent ""
- set ssh_add ""
- if {[info exists env(USER)] && $env(USER) == "runge"} {
- if {$got_ssh_agent2} {
- set ssh_agent "ssh-agent2"
- }
- if {$got_ssh_add2} {
- set ssh_add "ssh-add2"
- }
- }
- if {$ssh_agent == "" && $got_ssh_agent} {
- set ssh_agent "ssh-agent"
- }
- if {$ssh_add == "" && $got_ssh_add} {
- set ssh_add "ssh-add"
- }
- if {$ssh_agent == ""} {
- bell
- mesg "could not find ssh-agent in PATH"
- return
- }
- if {$ssh_add == ""} {
- bell
- mesg "could not find ssh-add in PATH"
- return
- }
- set tmp $env(SSVNC_HOME)/.vnc-sa[tpid]
- set tmp [mytmp $tmp]
- set fh ""
- catch {set fh [open $tmp "w"]}
- if {$fh == ""} {
- bell
- mesg "could not open tmp file $tmp"
- return
- }
-
- puts $fh "#!/bin/sh"
- puts $fh "eval `$ssh_agent -s`"
- puts $fh "$ssh_add"
- puts $fh "SSVNC_GUI_CHILD=\"\""
- puts $fh "export SSVNC_GUI_CHILD"
-
- global buck_zero
- set cmd $buck_zero
-
- if [info exists env(SSVNC_GUI_CMD)] {
- set cmd $env(SSVNC_GUI_CMD)
- }
- #puts $fh "$cmd </dev/null 1>/dev/null 2>/dev/null &"
- puts $fh "nohup $cmd &"
- puts $fh "sleep 1"
- puts $fh "rm -f $tmp"
- close $fh
-
- wm withdraw .
- catch {wm withdraw .o}
- catch {wm withdraw .oa}
-
- unix_terminal_cmd "+200+200" "Restarting with ssh-agent/ssh-add" "sh $tmp" 1
- after 10000
- destroy .
- exit
-}
-
-proc putty_pw_entry {mode} {
- if {$mode == "check"} {
- global use_sshssl use_ssh
- if {$use_sshssl || $use_ssh} {
- putty_pw_entry enable
- } else {
- putty_pw_entry disable
- }
- return
- }
- if {$mode == "disable"} {
- catch {.o.pw.l configure -state disabled}
- catch {.o.pw.e configure -state disabled}
- } else {
- catch {.o.pw.l configure -state normal}
- catch {.o.pw.e configure -state normal}
- }
-}
-proc adv_ssh_tog {on} {
- global adv_ssh
- foreach b {cups snd smb redirs knownhosts} {
- if [info exists adv_ssh($b)] {
- if {$on} {
- catch {$adv_ssh($b) configure -state normal}
- } else {
- catch {$adv_ssh($b) configure -state disabled}
- }
- }
- }
-}
-
-proc adv_listen_ssl_tog {on} {
- global stunnel_local_protection_button is_windows
- global disable_ssl_workarounds_button
- global vencrypt_button no_probe_vencrypt_button anondh_button ultra_dsm_button
-
- set blist [list]
- if [info exists stunnel_local_protection_button] {
- lappend blist $stunnel_local_protection_button
- }
- if [info exists disable_ssl_workarounds_button] {
- lappend blist $disable_ssl_workarounds_button
- }
- if [info exists ultra_dsm_button] {
- lappend blist $ultra_dsm_button
- }
- if [info exists no_probe_vencrypt_button] {
- lappend blist $no_probe_vencrypt_button
- }
- if [info exists vencrypt_button] {
- lappend blist $vencrypt_button
- }
- if [info exists anondh_button] {
- lappend blist $anondh_button
- }
- foreach b $blist {
- if {$on} {
- catch {$b configure -state normal}
- } else {
- catch {$b configure -state disabled}
- }
- }
-
- if {$is_windows} {
- catch {$stunnel_local_protection_button configure -state disabled}
- catch {$ultra_dsm_button configure -state disabled}
- }
-}
-
-proc adv_listen_ssh_tog {on} {
- global ssh_local_protection_button is_windows
- if [info exists ssh_local_protection_button] {
- if {$on} {
- catch {$ssh_local_protection_button configure -state normal}
- } else {
- catch {$ssh_local_protection_button configure -state disabled}
- }
- }
- if {$is_windows} {
- catch {$ssh_local_protection_button configure -state disabled}
- }
-}
-
-proc ssl_ssh_adjust {which} {
- global use_ssl use_ssh use_sshssl sshssl_sw
- global remote_ssh_cmd_list
- global x11vnc_find_widget x11vnc_xlogin_widget uvnc_bug_widget
-
- if {$which == "ssl"} {
- set use_ssl 1
- set use_ssh 0
- set use_sshssl 0
- set sshssl_sw "ssl"
- catch {.f4.getcert configure -state normal}
- catch {.f4.always configure -state normal}
- if [info exists x11vnc_find_widget] {
- catch {$x11vnc_find_widget configure -state disabled}
- }
- if [info exists x11vnc_xlogin_widget] {
- catch {$x11vnc_xlogin_widget configure -state disabled}
- }
- if [info exists uvnc_bug_widget] {
- catch {$uvnc_bug_widget configure -state normal}
- }
- adv_ssh_tog 0
- adv_listen_ssl_tog 1
- adv_listen_ssh_tog 0
- } elseif {$which == "none"} {
- set use_ssl 0
- set use_ssh 0
- set use_sshssl 0
- set sshssl_sw "none"
- catch {.f4.getcert configure -state disabled}
- catch {.f4.always configure -state disabled}
- if [info exists x11vnc_find_widget] {
- catch {$x11vnc_find_widget configure -state disabled}
- }
- if [info exists x11vnc_xlogin_widget] {
- catch {$x11vnc_xlogin_widget configure -state disabled}
- }
- if [info exists uvnc_bug_widget] {
- catch {$uvnc_bug_widget configure -state normal}
- }
- adv_ssh_tog 0
- adv_listen_ssl_tog 0
- adv_listen_ssh_tog 0
- } elseif {$which == "ssh"} {
- set use_ssl 0
- set use_ssh 1
- set use_sshssl 0
- set sshssl_sw "ssh"
- catch {.f4.getcert configure -state disabled}
- catch {.f4.always configure -state disabled}
- if [info exists x11vnc_find_widget] {
- catch {$x11vnc_find_widget configure -state normal}
- }
- if [info exists x11vnc_xlogin_widget] {
- catch {$x11vnc_xlogin_widget configure -state normal}
- }
- if [info exists uvnc_bug_widget] {
- catch {$uvnc_bug_widget configure -state disabled}
- }
- adv_ssh_tog 1
- adv_listen_ssl_tog 0
- adv_listen_ssh_tog 1
- } elseif {$which == "sshssl"} {
- set use_ssl 0
- set use_ssh 0
- set use_sshssl 1
- set sshssl_sw "sshssl"
- catch {.f4.getcert configure -state disabled}
- catch {.f4.always configure -state disabled}
- if [info exists x11vnc_find_widget] {
- catch {$x11vnc_find_widget configure -state normal}
- }
- if [info exists x11vnc_xlogin_widget] {
- catch {$x11vnc_xlogin_widget configure -state normal}
- }
- if [info exists uvnc_bug_widget] {
- catch {$uvnc_bug_widget configure -state normal}
- }
- adv_ssh_tog 1
- adv_listen_ssl_tog 1
- adv_listen_ssh_tog 1
- }
-
- if [info exists remote_ssh_cmd_list] {
- if {$use_ssh || $use_sshssl} {
- foreach w $remote_ssh_cmd_list {
- $w configure -state normal
- }
- }
- if {$use_ssl || $sshssl_sw == "none"} {
- foreach w $remote_ssh_cmd_list {
- $w configure -state disabled
- }
- }
- }
-
- if {! $use_ssl && ! $use_ssh && ! $use_sshssl} {
- if {$sshssl_sw != "none"} {
- set use_ssl 1
- set sshssl_sw "ssl"
- }
- }
- global ssh_only ts_only
- if {$ssh_only || $ts_only} {
- set use_ssl 0
- set use_sshssl 0
- set use_ssh 1
- set sshssl_sw "ssh"
- }
-
- putty_pw_entry check
-}
-
-proc listen_adjust {} {
- global use_listen revs_button multiple_listen_button is_windows
- global listen_once_button listen_accept_popup_button listen_accept_popup_button_sc
- if {![info exists multiple_listen_button]} {
- set multiple_listen_button "none"
- }
- if {$use_listen} {
- catch {.b.conn configure -text "Listen"}
- catch {.o.b.connect configure -text "Listen"}
- catch {$multiple_listen_button configure -state normal}
- catch {$listen_once_button configure -state normal}
- catch {$listen_accept_popup_button configure -state normal}
- catch {$listen_accept_popup_button_sc configure -state normal}
- catch {mesg "Listen :N -> Port 5500+N, i.e. :0 -> 5500, :1 -> 5501, :2 -> 5502 ..."}
- } else {
- catch {.b.conn configure -text "Connect"}
- catch {.o.b.connect configure -text "Connect"}
- catch {$multiple_listen_button configure -state disabled}
- catch {$listen_once_button configure -state disabled}
- catch {$listen_accept_popup_button configure -state disabled}
- catch {$listen_accept_popup_button_sc configure -state disabled}
- catch {mesg "Switched to Forward Connection mode."}
- }
- if {$is_windows} {
- catch {$multiple_listen_button configure -state disabled}
- catch {$listen_once_button configure -state disabled}
- catch {$listen_accept_popup_button configure -state disabled}
- catch {$listen_accept_popup_button_sc configure -state disabled}
- }
-}
-
-proc unixpw_adjust {} {
- global is_windows use_unixpw darwin_cotvnc
- if {$is_windows || $darwin_cotvnc} {
- return;
- }
- if {$use_unixpw} {
- pack configure .fu -after .f1 -fill x
- catch {focus .fu.e}
- } else {
- pack forget .fu
- }
-}
-
-proc x11vnc_find_adjust {which} {
- global remote_ssh_cmd
- global use_x11vnc_find x11vnc_find_widget
- global use_x11vnc_xlogin x11vnc_xlogin_widget
-
- if {$which == "find"} {
- if {$use_x11vnc_find} {
- set use_x11vnc_xlogin 0
- }
- } elseif {$which == "xlogin"} {
- if {$use_x11vnc_xlogin} {
- set use_x11vnc_find 0
- }
- }
- if {! $use_x11vnc_find && ! $use_x11vnc_xlogin} {
- set remote_ssh_cmd "";
- return
- }
- if {![regexp {x11vnc} $remote_ssh_cmd]} {
- set remote_ssh_cmd "";
- }
- regsub {^[ ]*PORT= [ ]*} $remote_ssh_cmd "" remote_ssh_cmd
- regsub {^[ ]*P= [ ]*} $remote_ssh_cmd "" remote_ssh_cmd
- regsub {^[ ]*sudo x11vnc[ ]*} $remote_ssh_cmd "" remote_ssh_cmd
- regsub {^[ ]*x11vnc[ ]*} $remote_ssh_cmd "" remote_ssh_cmd
- regsub -all {[ ]*-find[ ]*} $remote_ssh_cmd " " remote_ssh_cmd
- regsub -all {[ ]*-localhost[ ]*} $remote_ssh_cmd " " remote_ssh_cmd
- regsub -all {[ ]*-env FD_XDM=1[ ]*} $remote_ssh_cmd " " remote_ssh_cmd
- if {$use_x11vnc_find} {
- set remote_ssh_cmd "PORT= x11vnc -find -localhost -nopw $remote_ssh_cmd"
- } else {
- set remote_ssh_cmd "PORT= sudo x11vnc -find -localhost -env FD_XDM=1 -nopw $remote_ssh_cmd"
- }
- regsub {[ ]*$} $remote_ssh_cmd "" remote_ssh_cmd
- regsub {^[ ]*} $remote_ssh_cmd "" remote_ssh_cmd
- regsub -all {[ ][ ]*} $remote_ssh_cmd " " remote_ssh_cmd
-}
-
-proc set_darwin_cotvnc_buttons {} {
- global darwin_cotvnc uname darwin_cotvnc_blist
-
- if {$uname == "Darwin" && [info exists darwin_cotvnc_blist]} {
- foreach b [array names darwin_cotvnc_blist] {
- if {$darwin_cotvnc} {
- catch {$b configure -state disabled}
- } else {
- catch {$b configure -state normal}
- }
- }
- }
-}
-
-proc disable_encryption {} {
- global env
- if {[info exists env(SSVNC_DISABLE_ENCRYPTION_BUTTON)]} {
- set s $env(SSVNC_DISABLE_ENCRYPTION_BUTTON)
- if {$s != "" && $s != "0"} {
- return 1;
- }
- }
- return 0;
-}
-proc set_options {} {
- global use_alpha use_grab use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233
- global use_nojpeg use_raise_on_beep use_compresslevel use_quality use_x11_macosx
- global use_send_clipboard use_send_always
- global compresslevel_text quality_text
- global env is_windows darwin_cotvnc uname
- global use_listen
- global use_x11vnc_find x11vnc_find_widget
- global use_x11vnc_xlogin x11vnc_xlogin_widget uvnc_bug_widget
- global ts_only
- global darwin_cotvnc_blist
- global showing_no_encryption no_enc_button no_enc_prev
-
- if {$ts_only} {
- set_ts_options
- return
- }
-
- toplev .o
- wm title .o "SSL/SSH VNC Options"
-
- set i 1
-
- radiobutton .o.b$i -anchor w -variable sshssl_sw -value ssl -text \
- "Use SSL" -command {ssl_ssh_adjust ssl}
- incr i
-
- radiobutton .o.b$i -anchor w -variable sshssl_sw -value ssh -text \
- "Use SSH" -command {ssl_ssh_adjust ssh}
- incr i
-
- radiobutton .o.b$i -anchor w -variable sshssl_sw -value sshssl -text \
- "Use SSH+SSL" -command {ssl_ssh_adjust sshssl}
- set iss $i
- set no_enc_prev .o.b$i
- incr i
-
- radiobutton .o.b$i -anchor w -variable sshssl_sw -value none -text \
- "No Encryption" -command {ssl_ssh_adjust none}
- set no_enc_button .o.b$i
- set ine $i
- incr i
-
- checkbutton .o.b$i -anchor w -variable use_x11vnc_find -text \
- "Automatically Find X Session" -command {x11vnc_find_adjust "find"}
- if {!$use_ssh && !$use_sshssl} {.o.b$i configure -state disabled}
- set x11vnc_find_widget ".o.b$i"
- incr i
-
- if {! $is_windows} {
- checkbutton .o.b$i -anchor w -variable use_unixpw -text \
- "Unix Username & Password" -command {unixpw_adjust}
- if {$darwin_cotvnc} {.o.b$i configure -state disabled}
- set darwin_cotvnc_blist(.o.b$i) 1
- incr i
- }
-
- checkbutton .o.b$i -anchor w -variable use_listen -text \
- "Reverse VNC Connection (-LISTEN)" -command {listen_adjust; if {$vncdisplay == ""} {set vncdisplay ":0"} else {set vncdisplay ""}; if {0 && $use_listen} {destroy .o}}
- #if {$is_windows} {.o.b$i configure -state disabled}
- #if {$darwin_cotvnc} {.o.b$i configure -state disabled}
- #set darwin_cotvnc_blist(.o.b$i) 1
- incr i
-
- checkbutton .o.b$i -anchor w -variable use_viewonly -text \
- "View Only"
- incr i
-
- checkbutton .o.b$i -anchor w -variable use_fullscreen -text \
- "Fullscreen"
- incr i
-
- checkbutton .o.b$i -anchor w -variable use_raise_on_beep -text \
- "Raise On Beep"
- if {$darwin_cotvnc} {.o.b$i configure -state disabled}
- set darwin_cotvnc_blist(.o.b$i) 1
- incr i
-
- checkbutton .o.b$i -anchor w -variable use_bgr233 -text \
- "Use 8bit color (-bgr233)"
- if {$darwin_cotvnc} {.o.b$i configure -state disabled}
- set darwin_cotvnc_blist(.o.b$i) 1
- incr i
-
- checkbutton .o.b$i -anchor w -variable use_nojpeg -text \
- "Do not use JPEG (-nojpeg)"
- if {$darwin_cotvnc} {.o.b$i configure -state disabled}
- set darwin_cotvnc_blist(.o.b$i) 1
- incr i
-
- if {$uname == "Darwin"} {
- checkbutton .o.b$i -anchor w -variable use_x11_macosx -text \
- "Use X11 vncviewer on MacOSX" \
- -command {if {$use_x11_macosx} {set darwin_cotvnc 0} else {set darwin_cotvnc 1}; set_darwin_cotvnc_buttons}
- if {$uname != "Darwin"} {.o.b$i configure -state disabled}
- incr i
- }
-
- if {$is_windows} {
- global kill_stunnel
- checkbutton .o.b$i -anchor w -variable kill_stunnel -text \
- "Kill Stunnel Automatically"
- incr i
- }
-
-
- menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable compresslevel_text -relief groove
- set compresslevel_text "Compress Level: $use_compresslevel"
- if {$darwin_cotvnc} {.o.b$i configure -state disabled}
- set darwin_cotvnc_blist(.o.b$i) 1
-
- menu .o.b$i.m -tearoff 0
- for {set j -1} {$j < 10} {incr j} {
- set v $j
- set l $j
- if {$j == -1} {
- set v "default"
- set l "default"
- }
- .o.b$i.m add radiobutton -variable use_compresslevel \
- -value $v -label $l -command \
- {set compresslevel_text "Compress Level: $use_compresslevel"}
- }
- incr i
-
- menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable quality_text -relief groove
- set quality_text "Quality: $use_quality"
- if {$darwin_cotvnc} {.o.b$i configure -state disabled}
- set darwin_cotvnc_blist(.o.b$i) 1
-
- menu .o.b$i.m -tearoff 0
- for {set j -1} {$j < 10} {incr j} {
- set v $j
- set l $j
- if {$j == -1} {
- set v "default"
- set l "default"
- }
- .o.b$i.m add radiobutton -variable use_quality \
- -value $v -label $l -command \
- {set quality_text "Quality: $use_quality"}
- }
- incr i
-
- global use_mode ts_only ssh_only
- if {$ts_only} {
- set use_mode "Terminal Services (tsvnc)"
- } elseif {$ssh_only} {
- set use_mode "SSH-Only (sshvnc)"
- } else {
- set use_mode "SSVNC"
- }
- global mode_text
- set mode_text "Mode: $use_mode"
-
- menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable mode_text -relief groove
-
- menu .o.b$i.m -tearoff 0
- .o.b$i.m add radiobutton -variable use_mode -value "SSVNC" \
- -label "SSVNC" -command { if {$ts_only || $ssh_only} {to_ssvnc; set mode_text "Mode: SSVNC"; destroy .o}}
- .o.b$i.m add radiobutton -variable use_mode -value "SSH-Only (sshvnc)" \
- -label "SSH-Only (sshvnc)" -command { if {$ts_only || ! $ssh_only} {to_sshonly; set mode_text "Mode: SSH-Only (sshvnc)"; destroy .o}}
- .o.b$i.m add radiobutton -variable use_mode -value "Terminal Services (tsvnc)" \
- -label "Terminal Services (tsvnc)" -command {to_tsonly; set mode_text "Mode: Terminal Services (tsvnc)"; destroy .o}
- incr i
-
- global started_with_noenc
-
- if {0 && $started_with_noenc && $showing_no_encryption} {
- ;
- } elseif {$ssh_only} {
- ;
- } else {
- checkbutton .o.b$i -anchor w -variable showing_no_encryption -text \
- "Show 'No Encryption' Option" -pady 5 \
- -command {toggle_no_encryption 1}
- # -relief raised
- incr i
- }
-
- for {set j 1} {$j < $i} {incr j} {
- global ssh_only ts_only
- if {$ssh_only && $j <= 3} {
- continue;
- }
- if {$ts_only && $j <= 3} {
- continue;
- }
- if {!$showing_no_encryption && $j == $ine} {
- continue;
- }
-
- pack .o.b$j -side top -fill x
- }
-
- if {$is_windows} {
- global port_slot putty_pw
-
- frame .o.pp
- frame .o.pp.fL
- frame .o.pp.fR
- label .o.pp.fL.la -anchor w -text "Putty PW:"
- label .o.pp.fL.lb -anchor w -text "Port Slot:"
- pack .o.pp.fL.la .o.pp.fL.lb -side top -fill x
-
- entry .o.pp.fR.ea -width 10 -show * -textvariable putty_pw
- entry .o.pp.fR.eb -width 10 -textvariable port_slot
- pack .o.pp.fR.ea .o.pp.fR.eb -side top -fill x
-
- pack .o.pp.fL -side left
- pack .o.pp.fR -side right -expand 1 -fill x
-
- pack .o.pp -side top -fill x
-
- putty_pw_entry check
- }
-
- global uname
- set t1 " Advanced ..."
- set t2 " Use Defaults"
- set t3 " Delete Profile ..."
- if {$uname == "Darwin"} {
- regsub {^ *} $t1 "" t1
- regsub {^ *} $t2 "" t2
- regsub {^ *} $t3 "" t3
- }
-
- button .o.advanced -anchor w -text $t1 -command set_advanced_options
- button .o.clear -anchor w -text $t2 -command {set_defaults; init_vncdisplay}
- button .o.delete -anchor w -text $t3 -command {destroy .o; delete_profile}
-
- pack .o.clear -side top -fill x
- pack .o.delete -side top -fill x
- pack .o.advanced -side top -fill x
-
-# pack .o.s_prof -side top -fill x
-# pack .o.l_prof -side top -fill x
-
- frame .o.b
- button .o.b.done -text "Done" -command {destroy .o}
- bind .o <Escape> {destroy .o}
- wm protocol .o WM_DELETE_WINDOW {destroy .o}
- button .o.b.help -text "Help" -command help_opts
- global use_listen
- if {$use_listen} {
- button .o.b.connect -text "Listen" -command launch
- } else {
- button .o.b.connect -text "Connect" -command launch
- }
-
- pack .o.b.help .o.b.connect .o.b.done -fill x -expand 1 -side left
-
- pack .o.b -side top -fill x
-
- center_win .o
- wm resizable .o 1 0
- focus .o
-}
-
-proc check_writable {} {
- set test test[pid].txt
- catch {set f [open $test "w"]; puts $f "test"; close $f}
-
- ###catch {file delete -force $test} # testing.
-
- if ![file exists $test] {
- global env
- if [info exists env(SSVNC_HOME)] {
- set dir "$env(SSVNC_HOME)/ss_vnc/cache"
- catch {file mkdir $dir}
- if ![file exists $dir] {
- return
- }
- foreach f [glob -type f * */* */*/*] {
- set dest "$dir/$f"
- set dirn [file dirname $dest]
- catch {file mkdir $dirn}
- catch {file copy -force -- $f $dest}
- }
- cd $dir
- ###catch {set f [open $test "w"]; puts $f "test"; close $f}
- }
- } else {
- catch {file delete -force $test}
- }
-}
-
-proc print_help {} {
-
- global help_main help_prox help_misc help_tips
- set b "\n============================================================================\n"
- help
- #set str [.h.f.t get 1.0 end]
- #puts "${b}Help:\n$str"
- puts "${b}Help Main:\n$help_main"
- puts "${b}Help Proxies:\n$help_prox"
- puts "${b}Help Misc:\n$help_misc"
- puts "${b}Help Tips:\n$help_tips"
- destroy .h
-
- help_opts
- set str [.oh.f.t get 1.0 end]
- puts "${b}SSL/SSH Viewer Options Help:\n$str"
- destroy .oh
-
- help_advanced_opts
- set str [.ah.f.t get 1.0 end]
- puts "${b}Advanced Options Help:\n$str"
- destroy .ah
-
- help_ssvncviewer_opts
- set str [.av.f.t get 1.0 end]
- puts "${b}ssvncviewer Options Help:\n$str"
- destroy .av
-
- help_certs
- set str [.ch.f.t get 1.0 end]
- puts "${b}SSL Certificates Help:\n$str"
- destroy .ch
-
- help_fetch_cert
- set str [.fh.f.t get 1.0 end]
- puts "${b}Fetch Certificates Help:\n$str"
- destroy .fh
-
- create_cert
- set str [.ccrt.f.t get 1.0 end]
- puts "${b}Create SSL Certificate Dialog:\n$str"
- destroy .ccrt
-
- import_cert
- set str [.icrt.f.t get 1.0 end]
- puts "${b}Import SSL Certificate Dialog:\n$str"
- destroy .icrt
-
- global cert_text
- set cert_text "empty"
- save_cert "help:0"
- set str [.scrt.f.t get 1.0 end]
- puts "${b}Save SSL Certificate Dialog:\n$str"
- destroy .scrt
-
- ts_help
- set str [.h.f.t get 1.0 end]
- puts "${b}Terminal Services Help:\n$str"
- destroy .h
-
- help_ts_opts
- set str [.oh.f.t get 1.0 end]
- puts "${b}Terminal Services VNC Options Help:\n$str"
- destroy .oh
-
- ts_unixpw_dialog
- set str [.uxpw.f.t get 1.0 end]
- puts "${b}Terminal Services Use unixpw Dialog:\n$str"
- destroy .uxpw
-
- ts_vncshared_dialog
- set str [.vncs.f.t get 1.0 end]
- puts "${b}Terminal Services VNC Shared Dialog:\n$str"
- destroy .vncs
-
- ts_multi_dialog
- set str [.mult.f.t get 1.0 end]
- puts "${b}Terminal Services Multiple Sessions Dialog:\n$str"
- destroy .mult
-
- ts_xlogin_dialog
- set str [.xlog.f.t get 1.0 end]
- puts "${b}Terminal Services X Login Dialog:\n$str"
- destroy .xlog
-
- ts_othervnc_dialog
- set str [.ovnc.f.t get 1.0 end]
- puts "${b}Terminal Services Other VNC Server Dialog:\n$str"
- destroy .ovnc
-
- ts_ncache_dialog
- set str [.nche.f.t get 1.0 end]
- puts "${b}Terminal Services Client-Side Caching Dialog:\n$str"
- destroy .nche
-
- ts_x11vnc_opts_dialog
- set str [.x11v.f.t get 1.0 end]
- puts "${b}Terminal Services x11vnc Options Dialog:\n$str"
- destroy .x11v
-
- ts_filexfer_dialog
- set str [.xfer.f.t get 1.0 end]
- puts "${b}Terminal Services File Transfer Dialog:\n$str"
- destroy .xfer
-
- ts_sound_dialog
- set str [.snd.f.t get 1.0 end]
- puts "${b}Terminal Services Sound Tunnelling Dialog:\n$str"
- destroy .snd
-
- ts_cups_dialog
- set str [.cups.f.t get 1.0 end]
- puts "${b}Terminal Services CUPS Dialog:\n$str"
- destroy .cups
-
- help_ssvncviewer_opts
- set str [.av.f.t get 1.0 end]
- puts "${b}Unix SSVNC viewer Options Help:\n$str"
- destroy .av
-
- change_vncviewer_dialog
- set str [.chviewer.t get 1.0 end]
- puts "${b}Unix Change VNC Viewer Dialog:\n$str"
- destroy .chviewer
-
- cups_dialog
- set str [.cups.f.t get 1.0 end]
- puts "${b}CUPS Dialog:\n$str"
- destroy .cups
-
- sound_dialog
- set str [.snd.f.t get 1.0 end]
- puts "${b}ESD Audio Tunnelling Dialog:\n$str"
- destroy .snd
-
- smb_dialog
- set str [.smb.f.t get 1.0 end]
- puts "${b}SMB Mounting Dialog:\n$str"
- destroy .smb
-
- port_redir_dialog
- set str [.redirs.t get 1.0 end]
- puts "${b}Additional Port Redirections Dialog:\n$str"
- destroy .redirs
-
- port_knocking_dialog
- set str [.pk.f.t get 1.0 end]
- puts "${b}Port Knocking Dialog:\n$str"
- destroy .pk
-
- ssvnc_escape_help
- set str [.ekh.f.t get 1.0 end]
- puts "${b}SSVNC Escape Keys Help:\n$str"
- destroy .ekh
-
- stunnel_sec_dialog
- set str [.stlsec.f.t get 1.0 end]
- puts "${b}STUNNEL Local Port Protections Dialog:\n$str"
- destroy .stlsec
-
- disable_ssl_workarounds_dialog
- set str [.sslwrk.f.t get 1.0 end]
- puts "${b}Disable SSL Workarounds Dialog:\n$str"
- destroy .sslwrk
-
- ultra_dsm_dialog
- set str [.ultradsm.f.t get 1.0 end]
- puts "${b}UltraVNC DSM Encryption Plugin Dialog:\n$str"
- destroy .ultradsm
-
- ssh_known_hosts_dialog
- set str [.sshknownhosts.f.t get 1.0 end]
- puts "${b}Private SSH KnownHosts file Dialog:\n$str"
- destroy .sshknownhosts
-
- ssh_sec_dialog
- set str [.sshsec.t get 1.0 end]
- puts "${b}SSH Local Port Protections Dialog:\n$str"
- destroy .sshsec
-
- multilisten_dialog
- set str [.multil.t get 1.0 end]
- puts "${b}Multiple LISTEN Connections Dialog:\n$str"
- destroy .multil
-
- use_grab_dialog
- set str [.usegrb.t get 1.0 end]
- puts "${b}Use XGrabServer (for fullscreen) Dialog:\n$str"
- destroy .usegrb
-}
-
-proc zeroconf_fill {b m} {
- global is_windows zeroconf_command last_post
-
- if {$is_windows} {
- return;
- }
-
- if {![info exists last_post]} {
- set last_post 0
- }
- set now [clock seconds]
- if {$now < [expr $last_post + 10]} {
- # cache menu for 10 secs.
- return
- }
-
- . config -cursor {watch}
- $b config -cursor {watch}
- $b configure -state disabled
-
- $m delete 0 end
- update
-
- set emsg ""
- set output ""
- set none "No VNC servers detected"
-
- set rc 1
- set rd 0
- if {$zeroconf_command == "avahi-browse"} {
- set rc [catch {set output [exec avahi-browse -r -t -p -k _rfb._tcp 2>/dev/null]} emsg]
- } elseif {$zeroconf_command == "dns-sd"} {
- set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec dns-sd -B _rfb._tcp} 2>/dev/null]} emsg]
- set rd 1
- } elseif {$zeroconf_command == "mDNS"} {
- set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec mDNS -B _rfb._tcp} 2>/dev/null]} emsg]
- set rd 1
- }
-
- #puts "rc=$rc output=$output"
- if {$rd == 1 && $rc != 0} {
- if [regexp {_rfb} $emsg] {
- set rc 0
- set output $emsg
- }
- }
-
- set count 0
-
- if {$rc != 0} {
- $m add command -label $none
- incr count
-
- } elseif {$output == "" || [regexp {^[ \t\n]*$} $output]} {
- $m add command -label $none
- incr count
-
- } elseif {$zeroconf_command == "avahi-browse"} {
- set lines [split $output "\n"]
- set saw("__none__") 1
- foreach line $lines {
- set items [split $line ";"]
- if {[llength $items] != 10} {
- continue
- }
- if {[lindex $items 0] != "="} {
- continue
- }
-
- # =;eth0;IPv4;tmp2\0582;_rfb._tcp;local;tmp2.local;10.0.2.252;5902;
- set eth [lindex $items 1]
- set ipv [lindex $items 2]
- set name [lindex $items 3]
- set type [lindex $items 4]
- set loc [lindex $items 5]
- set host [lindex $items 6]
- set ip [lindex $items 7]
- set port [lindex $items 8]
-
- if {![regexp -nocase {ipv4} $ipv]} {
- continue
- }
-
- set name0 $name
- regsub -all {\\\\} $name "__bockslosh__" name
- regsub -all {\\\.} $name "." name
-
- set n 0
- while {1} {
- incr n
- if {$n > 100} {
- break
- }
- if {[regexp {\\[0-9][0-9][0-9]} $name match]} {
- #puts "match1=$match"
- regsub {\\} $match "" match
- set d $match
- regsub {^0*} $d "" d
- set c [format "%c" $d]
- if {"$c" == "&"} {
- set c "\\$c"
- }
- regsub "\\\\$match" $name $c name
- #puts "match: $match c='$c'\nname=$name"
- } else {
- break
- }
- }
-
- regsub -all {__bockslosh__} $name "\\" name
-
- set hp $host
- if {$port >= 5900 && $port <= 6100} {
- set d [expr $port - 5900]
- set hp "$host:$d"
- } else {
- set hp "$host:$port"
- }
- if {![info exists saw($name)]} {
- regsub -all {[^[:alnum:],./:@%_=+-]} $hp "" hp
- $m add command -label "$name - $hp" -command "set vncdisplay \"$hp\""
- incr count
- set p $port
- if {$p <= 200} {
- set p "-$port"
- }
- regsub -all {[^[:alnum:],./:@%_=+-]} "$ip:$p" "" ipp
- $m add command -label "$name - $ipp" -command "set vncdisplay \"$ipp\""
- incr count
- set saw($name) 1
- }
- }
- } else {
- set lines [split $output "\n"]
- set saw("__none__") 1
- global dns_sd_cache last_dns_sd
- if {![info exists last_dns_sd]} {
- set last_dns_sd 0
- }
- if {[clock seconds] > [expr $last_dns_sd + 1800]} {
- catch { unset dns_sd_cache }
- set last_dns_sd [clock seconds]
- }
- foreach line $lines {
- if [regexp -nocase {^Browsing} $line] {
- continue;
- }
- if [regexp -nocase {^Timestamp} $line] {
- continue;
- }
- if [regexp -nocase {killed:} $line] {
- continue;
- }
- if {![regexp {_rfb\._tcp} $line]} {
- continue;
- }
- regsub {[ \t\n]*$} $line "" line
- regsub {^.*_rfb\._tcp[^ ]* *} $line "" name
-
- if {[info exists saw($name)]} {
- continue
- }
- set saw($name) 1
-
- set hp "$name"
- if {[info exists dns_sd_cache($name)]} {
- set hp $dns_sd_cache($name)
- } else {
- global env
- regsub -all {"} $name "" name2
- set env(DNS_SD_LU) $name2
- set emsg ""
- if {$zeroconf_command == "dns-sd"} {
- set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec dns-sd -L "$DNS_SD_LU" _rfb._tcp .} 2>/dev/null]} emsg]
- } elseif {$zeroconf_command == "mDNS"} {
- set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec mDNS -L "$DNS_SD_LU" _rfb._tcp .} 2>/dev/null]} emsg]
- regsub -all {[ \t][ \t]*:} $emsg ":" emsg
- }
- regsub -all { *} $emsg " " emsg
- if [regexp -nocase {be reached at *([^ \t\n][^ \t\n]*)} $emsg match hpm] {
- if [regexp {^(.*):([0-9][0-9]*)$} $hpm mv hm pm] {
- if {$pm >= 5900 && $pm <= 6100} {
- set pm [expr $pm - 5900]
- }
- set hp "$hm:$pm"
- } else {
- set hp $hpm
- }
- set dns_sd_cache($name) $hp
- } else {
- set hp "$name"
- if {![regexp {:[0-9][0-9]*$} $hp]} {
- set hp "$name:0"
- }
- }
- }
- regsub -all {[^[:alnum:],./:@%_=+-]} $hp "" hp
- $m add command -label "$name - $hp" -command "set vncdisplay \"$hp\""
- incr count
- }
- }
- $b configure -state normal
- . config -cursor {}
- $b config -cursor {}
- if {$count == 0} {
- $m add command -label $none
- }
- set last_post [clock seconds]
-}
-
-proc check_zeroconf_browse {} {
- global is_windows zeroconf_command
-
- set zeroconf_command ""
- if {$is_windows} {
- return 0;
- }
- set p ""
- set r [catch {set p [exec /bin/sh -c {type avahi-browse}]}]
- if {$r == 0} {
- regsub {^.* is *} $p "" p
- regsub -all {[ \t\n\r]} $p "" p
- if [file exists $p] {
- set zeroconf_command "avahi-browse"
- return 1
- }
- }
- set p ""
- set r [catch {set p [exec /bin/sh -c {type dns-sd}]}]
- if {$r == 0} {
- regsub {^.* is *} $p "" p
- regsub -all {[ \t\n\r]} $p "" p
- if [file exists $p] {
- set zeroconf_command "dns-sd"
- global env
- if [info exists env(USE_MDNS)] {
- # testing
- set zeroconf_command "mDNS"
- }
- return 1
- }
- }
- set p ""
- set r [catch {set p [exec /bin/sh -c {type mDNS}]}]
- if {$r == 0} {
- regsub {^.* is *} $p "" p
- regsub -all {[ \t\n\r]} $p "" p
- if [file exists $p] {
- set zeroconf_command "mDNS"
- return 1
- }
- }
- return 0
-}
-
-proc toggle_no_encryption {{rev 0}} {
- global showing_no_encryption
- global no_enc_button no_enc_prev
- global ts_only ssh_only
- global use_ssl use_ssh use_sshssl
-
- if {$rev} {
- # reverse it first
- if {$showing_no_encryption} {
- set showing_no_encryption 0
- } else {
- set showing_no_encryption 1
- }
- }
-
- if {$showing_no_encryption} {
- catch {pack forget .f4.none}
- catch {pack forget $no_enc_button}
- if {!$use_ssl && !$use_ssh && !$use_sshssl} {
- set use_ssl 1
- sync_use_ssl_ssh
- }
- set showing_no_encryption 0
- } else {
- if {$ts_only || $ssh_only} {
- return
- }
- catch {pack .f4.none -side left}
- if {![info exists no_enc_button]} {
- catch {destroy .o}
- } elseif {![winfo exists $no_enc_button]} {
- catch {destroy .o}
- } else {
- catch {pack $no_enc_button -after $no_enc_prev -fill x}
- }
- set showing_no_encryption 1
- }
-}
-
-proc toggle_vnc_prefix {} {
- global vncdisplay
- if [regexp -nocase {^vnc://} $vncdisplay] {
- regsub -nocase {^vnc://} $vncdisplay "" vncdisplay
- } else {
- regsub -nocase {^[a-z0-9+]*://} $vncdisplay "" vncdisplay
- set vncdisplay "Vnc://$vncdisplay"
- }
- catch {.f0.e icursor end}
-}
-
-############################################
-
-global env
-
-if {[regexp -nocase {Windows.9} $tcl_platform(os)]} {
- set is_win9x 1
-} else {
- set is_win9x 0
-}
-
-set is_windows 0
-if { [regexp -nocase {Windows} $tcl_platform(os)]} {
- set is_windows 1
-}
-
-set uname ""
-if {! $is_windows} {
- catch {set uname [exec uname]}
-}
-
-set ffont "fixed"
-
-global have_ipv6
-set have_ipv6 ""
-check_for_ipv6
-
-# need to check if "fixed" font under XFT on tk8.5 is actually fixed width!!
-if {$tcl_platform(platform) == "unix"} {
- set ls ""
- catch {set ls [font metrics $ffont -linespace]}
- set fs ""
- catch {set fs [font metrics $ffont -fixed]}
- set redo 0
- if {$fs != "" && $fs != "1"} {
- set redo 1
- }
- if {$ls != "" && $ls > 14} {
- set redo 1
- }
- if {$redo} {
- foreach fn [font names] {
- if {$fn == "TkFixedFont"} {
- set ffont $fn
- break
- }
- }
- }
- catch {option add *Dialog.msg.font {helvetica -14 bold}}
- catch {option add *Dialog.msg.wrapLength 4i}
-}
-
-if {$uname == "Darwin"} {
- set ffont "Monaco 10"
-
- #option add *Button.font Helvetica widgetDefault
- catch {option add *Button.font {System 10} widgetDefault}
-}
-
-# set SSVNC_HOME to HOME in case we modify it for mobile use:
-if [info exists env(HOME)] {
- if {! [info exists env(SSVNC_HOME)]} {
- set env(SSVNC_HOME) $env(HOME)
- }
-}
-
-# For mobile use, e.g. from a USB flash drive, we look for a "home" or "Home"
-# directory relative to this script where the profiles and certs will be kept
-# by default.
-if [file exists $buck_zero] {
- #puts "$buck_zero"
- set up [file dirname $buck_zero]
-
- if {$up == "."} {
- # this is actually bad news on windows because we cd'd to util.
- set up ".."
- } else {
- set up [file dirname $up]
- }
- set dirs [list $up]
-
- if {! $is_windows && $up != ".."} {
- # get rid of bin
- set up [file dirname $up]
- lappend dirs $up
- }
-
- for {set i 0} {$i < $argc} {incr i} {
- set it0 [lindex $argv $i]
- if {$it0 == "."} {
- if {![file isdirectory "$up/home"] && ![file isdirectory "$up/Home"]} {
- catch {file mkdir "$up/Home"}
- }
- break
- }
- }
-
- set gotone 0
-
- foreach d $dirs {
- set try "$d/home"
- #puts "$try"
- if [file isdirectory $try] {
- set env(SSVNC_HOME) $try
- set gotone 1
- break
- }
- set try "$d/Home"
- #puts "$try"
- if [file isdirectory $try] {
- set env(SSVNC_HOME) $try
- set gotone 1
- break
- }
- }
- if {$gotone} {
- set b ""
- if {$is_windows} {
- set b "$env(SSVNC_HOME)/ss_vnc"
- } else {
- set b "$env(SSVNC_HOME)/.vnc"
- }
- catch {file mkdir $b}
- catch {file mkdir "$b/certs"}
- catch {file mkdir "$b/profiles"}
- }
- #puts "HOME: $env(SSVNC_HOME)"
-}
-
-global svcert_default mycert_default crlfil_default
-global svcert_default_force mycert_default_force crlfil_default_force
-set svcert_default ""
-set mycert_default ""
-set crlfil_default ""
-set svcert_default_force 0
-set mycert_default_force 0
-set crlfil_default_force 0
-
-set saw_ts_only 0
-set saw_ssh_only 0
-
-set ssvncrc $env(SSVNC_HOME)/.ssvncrc
-if {$is_windows} {
- set ssvncrc $env(SSVNC_HOME)/ssvnc_rc
-}
-
-global ts_desktop_size_def ts_desktop_depth_def ts_desktop_type_def ts_xserver_type_def
-set ts_desktop_size_def ""
-set ts_desktop_depth_def ""
-set ts_desktop_type_def ""
-set ts_xserver_type_def ""
-
-global win_localhost
-set win_localhost "127.0.0.1"
-
-global kill_stunnel
-set kill_stunnel 1
-
-global started_with_noenc
-
-if {! [info exists env(SSVNC_DISABLE_ENCRYPTION_BUTTON)]} {
- set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
- set started_with_noenc 1
-} else {
- if {$env(SSVNC_DISABLE_ENCRYPTION_BUTTON) == "0"} {
- set started_with_noenc 0
- } elseif {$env(SSVNC_DISABLE_ENCRYPTION_BUTTON) == "1"} {
- set started_with_noenc 1
- } else {
- set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
- set started_with_noenc 1
- }
-}
-
-if [file exists $ssvncrc] {
- set fh ""
- catch {set fh [open $ssvncrc "r"]}
- if {$fh != ""} {
- while {[gets $fh line] > -1} {
- set str [string trim $line]
- if [regexp {^#} $str] {
- continue
- }
- if [regexp {^mode=tsvnc} $str] {
- set saw_ts_only 1
- set saw_ssh_only 0
- } elseif [regexp {^mode=sshvnc} $str] {
- set saw_ts_only 0
- set saw_ssh_only 1
- } elseif [regexp {^mode=ssvnc} $str] {
- set saw_ts_only 0
- set saw_ssh_only 0
- }
- if [regexp {^desktop_type=(.*)$} $str m val] {
- set val [string trim $val]
- set ts_desktop_type_def $val
- }
- if [regexp {^desktop_size=(.*)$} $str m val] {
- set val [string trim $val]
- set ts_desktop_size_def $val
- }
- if [regexp {^desktop_depth=(.*)$} $str m val] {
- set val [string trim $val]
- set ts_desktop_depth_def $val
- }
- if [regexp {^xserver_type=(.*)$} $str m val] {
- set val [string trim $val]
- set ts_xserver_type_def $val
- }
- if [regexp {^font_default=(.*)$} $str m val] {
- set val [string trim $val]
- catch {option add *font $val}
- catch {option add *Dialog.msg.font $val}
- }
- if [regexp {^font_fixed=(.*)$} $str m val] {
- set val [string trim $val]
- set ffont $val
- }
- if [regexp {^noenc=1} $str] {
- global env
- set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
- set started_with_noenc 1
- }
- if [regexp {^noenc=0} $str] {
- global env
- set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 0
- set started_with_noenc 0
- }
- if [regexp {^cotvnc=1} $str] {
- global env
- set env(SSVNC_COTVNC) 1
- }
- if [regexp {^cotvnc=0} $str] {
- global env
- set env(SSVNC_COTVNC) 0
- }
- if [regexp {^killstunnel=1} $str] {
- set kill_stunnel 1
- }
- if [regexp {^killstunnel=0} $str] {
- set kill_stunnel 0
- }
- global have_ipv6
- if [regexp {^ipv6=1} $str] {
- set have_ipv6 1
- set env(SSVNC_IPV6) 1
- }
- if [regexp {^ipv6=0} $str] {
- set have_ipv6 0
- set env(SSVNC_IPV6) 0
- }
- if [regexp {^mycert=(.*)$} $str m val] {
- set val [string trim $val]
- set mycert_default $val
- }
- if [regexp {^cert=(.*)$} $str m val] {
- set val [string trim $val]
- set mycert_default $val
- }
- if [regexp {^cacert=(.*)$} $str m val] {
- set val [string trim $val]
- set svcert_default $val
- }
- if [regexp {^ca=(.*)$} $str m val] {
- set val [string trim $val]
- set svcert_default $val
- }
- if [regexp {^crl=(.*)$} $str m val] {
- set val [string trim $val]
- set crlfil_default $val
- }
- if [regexp {^env=([^=]*)=(.*)$} $str m var val] {
- global env
- set env($var) $val
- }
- }
- close $fh
- }
-}
-
-for {set i 0} {$i < $argc} {incr i} {
- set item [lindex $argv $i]
- regsub {^--} $item "-" item
- if {$item == "-profiles" || $item == "-list"} {
- set dir [get_profiles_dir]
- #puts stderr "VNC Profiles:"
- #puts stderr " "
- if {[info exists env(SSVNC_TS_ONLY)]} {
- set saw_ts_only 1
- } elseif {[info exists env(SSVNC_SSH_ONLY)]} {
- set saw_ssh_only 1
- }
- set profs [list]
- foreach prof [glob -nocomplain -directory $dir "*.vnc"] {
- set s [file tail $prof]
- regsub {\.vnc$} $s "" s
- if {$saw_ts_only || $saw_ssh_only} {
- set ok 0;
- set tsok 0;
- set fh ""
- catch {set fh [open $prof "r"]}
- if {$fh != ""} {
- while {[gets $fh line] > -1} {
- if {[regexp {use_ssh=1} $line]} {
- set ok 1
- }
- if {[regexp {ts_mode=1} $line]} {
- set tsok 1
- }
- }
- close $fh
- }
- if {$saw_ts_only && !$tsok} {
- continue;
- } elseif {! $ok} {
- continue
- }
- }
- lappend profs $s
- }
- foreach prof [lsort $profs] {
- puts "$prof"
- }
- exit
- } elseif {$item == "-nvb"} {
- global env
- set env(SSVNC_NO_VERIFY_ALL_BUTTON) 1
- } elseif {$item == "-noenc"} {
- global env
- set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
- set started_with_noenc 1
- } elseif {$item == "-enc"} {
- global env
- set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 0
- } elseif {$item == "-bigger"} {
- global env
- if {![info exists env(SSVNC_BIGGER_DIALOG)]} {
- set env(SSVNC_BIGGER_DIALOG) 1
- }
- } elseif {$item == "-ssh"} {
- set saw_ssh_only 1
- set saw_ts_only 0
- } elseif {$item == "-ts"} {
- set saw_ts_only 1
- set saw_ssh_only 0
- } elseif {$item == "-ssl" || $item == "-ss"} {
- set saw_ts_only 0
- set saw_ssh_only 0
- } elseif {$item == "-tso"} {
- global env
- set env(SSVNC_TS_ALWAYS) 1
- set saw_ts_only 1
- } elseif {$item == "-killstunnel"} {
- set kill_stunnel 1
- } elseif {$item == "-nokillstunnel"} {
- set kill_stunnel 0
- } elseif {$item == "-mycert" || $item == "-cert"} {
- incr i
- set mycert_default [lindex $argv $i]
- } elseif {$item == "-cacert" || $item == "-ca"} {
- incr i
- set svcert_default [lindex $argv $i]
- } elseif {$item == "-crl"} {
- incr i
- set crlfil_default [lindex $argv $i]
- }
-}
-
-if [info exists env(SSVNC_FONT_FIXED)] {
- set ffont $env(SSVNC_FONT_FIXED)
-}
-
-if [info exists env(SSVNC_FONT_DEFAULT)] {
- catch {option add *font $env(SSVNC_FONT_DEFAULT)}
- catch {option add *Dialog.msg.font $env(SSVNC_FONT_DEFAULT)}
-}
-
-if [regexp {[ ]} $ffont] {
- set help_font "-font \"$ffont\""
-} else {
- set help_font "-font $ffont"
-}
-
-if { [regexp -nocase {Windows} $tcl_platform(os)]} {
- cd util
- if {$help_font == "-font fixed"} {
- set help_font ""
- }
-}
-
-if {$saw_ts_only && $saw_ssh_only} {
- set saw_ssh_only 0
-}
-
-global ssh_only
-set ssh_only 0
-if {[info exists env(SSVNC_SSH_ONLY)] || $saw_ssh_only} {
- set ssh_only 1
-}
-
-global ts_only
-set ts_only 0
-if {[info exists env(SSVNC_TS_ONLY)] || $saw_ts_only} {
- set ts_only 1
-}
-
-if {$mycert_default != ""} {
- if [regexp -nocase {^FORCE:} $mycert_default] {
- set mycert_default_force 1
- regsub -nocase {^FORCE:} $mycert_default "" mycert_default
- }
- if {![file exists $mycert_default]} {
- set idir [get_idir_certs ""]
- set mycert_default "$idir/$mycert_default"
- }
-}
-
-if {$svcert_default != ""} {
- if [regexp -nocase {^FORCE:} $svcert_default] {
- set svcert_default_force 1
- regsub -nocase {^FORCE:} $svcert_default "" svcert_default
- }
- if {![file exists $svcert_default]} {
- set idir [get_idir_certs ""]
- if {$svcert_default == "CA"} {
- set svcert_default "$idir/CA/cacert.pem"
- } else {
- set svcert_default "$idir/$svcert_default"
- }
- }
-}
-
-if {$crlfil_default != ""} {
- if [regexp -nocase {^FORCE:} $crlfil_default] {
- set crlfil_default_force 1
- regsub -nocase {^FORCE:} $crlfil_default "" crlfil_default
- }
- if {![file exists $crlfil_default]} {
- set idir [get_idir_certs ""]
- set crlfil_default "$idir/$crlfil_default"
- }
-}
-
-if {$is_windows} {
- check_writable
-}
-
-
-set darwin_cotvnc 0
-if {$uname == "Darwin"} {
- if {! [info exists env(DISPLAY)]} {
- set darwin_cotvnc 1
- } elseif {[regexp {/tmp/} $env(DISPLAY)]} {
- set darwin_cotvnc 1
- }
- if [info exists env(SSVNC_HOME)] {
- set t "$env(SSVNC_HOME)/.vnc"
- if {! [file exists $t]} {
- catch {file mkdir $t}
- }
- }
-}
-
-##for testing macosx
-if [info exists env(FORCE_DARWIN)] {
- set uname Darwin
- set darwin_cotvnc 1
-}
-
-set putty_pw ""
-
-global scroll_text_focus
-set scroll_text_focus 1
-
-set multientry 1
-
-wm withdraw .
-if {$ssh_only} {
- wm title . "SSH VNC Viewer"
-} elseif {$ts_only} {
- wm title . "Terminal Services VNC Viewer"
-} else {
- wm title . "SSL/SSH VNC Viewer"
-}
-
-wm resizable . 1 0
-
-set_defaults
-if {$uname == "Darwin"} {
- if [info exists use_x11_macosx] {
- if {$use_x11_macosx} {
- set darwin_cotvnc 0
- }
- }
-}
-set skip_pre 0
-
-set vncdisplay ""
-set last_load ""
-set vncproxy ""
-set remote_ssh_cmd ""
-set vncauth_passwd ""
-
-global did_listening_message
-set did_listening_message 0
-
-global accepted_cert_dialog_in_progress
-set accepted_cert_dialog_in_progress 0
-
-global fetch_cert_filename
-set fetch_cert_filename ""
-
-set vhd "VNC Host:Display"
-if {$ssh_only} {
- label .l -text "SSH VNC Viewer" -relief ridge
-} elseif {$ts_only} {
- label .l -text "Terminal Services VNC Viewer" -relief ridge
- set vhd "VNC Terminal Server:"
-} else {
- label .l -text "SSL/SSH VNC Viewer" -relief ridge
-}
-
-set wl 21
-set we 40
-frame .f0
-if {$multientry} {
- label .f0.l -width $wl -anchor w -text "$vhd" -relief ridge
-} else {
- label .f0.l -anchor w -text "$vhd" -relief ridge
-}
-entry .f0.e -width $we -textvariable vncdisplay
-pack .f0.l -side left
-bind .f0.e <Return> launch
-bind .f0.e <Control-E> {toggle_vnc_prefix}
-pack .f0.e -side left -expand 1 -fill x
-
-if {[check_zeroconf_browse]} {
- menubutton .f0.mb -relief ridge -menu .f0.mb.m -text "Find"
- menu .f0.mb.m -tearoff 0 -postcommand {zeroconf_fill .f0.mb .f0.mb.m}
- pack .f0.mb -side left
-}
-
-frame .f1
-label .f1.l -width $wl -anchor w -text "VNC Password:" -relief ridge
-entry .f1.e -width $we -textvariable vncauth_passwd -show *
-pack .f1.l -side left
-pack .f1.e -side left -expand 1 -fill x
-bind .f1.e <Return> launch
-
-frame .fu
-label .fu.l -width $wl -anchor w -text "Unix Username:" -relief ridge
-entry .fu.e -width 14 -textvariable unixpw_username
-label .fu.m -anchor w -text "Unix Password:" -relief ridge
-entry .fu.f -textvariable unixpw_passwd -show *
-pack .fu.l -side left
-pack .fu.e .fu.m -side left
-pack .fu.f -side left -expand 1 -fill x
-bind .fu.f <Return> launch
-
-frame .f2
-label .f2.l -width $wl -anchor w -text "Proxy/Gateway:" -relief ridge
-entry .f2.e -width $we -textvariable vncproxy
-pack .f2.l -side left
-pack .f2.e -side left -expand 1 -fill x
-bind .f2.e <Return> launch
-
-frame .f3
-label .f3.l -width $wl -anchor w -text "Remote SSH Command:" -relief ridge
-entry .f3.e -width $we -textvariable remote_ssh_cmd
-pack .f3.l -side left
-pack .f3.e -side left -expand 1 -fill x
-.f3.l configure -state disabled
-.f3.e configure -state disabled
-bind .f3.e <Return> launch
-
-set remote_ssh_cmd_list {.f3.e .f3.l}
-
-frame .f4
-radiobutton .f4.ssl -anchor w -variable sshssl_sw -value ssl -command {ssl_ssh_adjust ssl} -text "Use SSL"
-radiobutton .f4.ssh -anchor w -variable sshssl_sw -value ssh -command {ssl_ssh_adjust ssh} -text "Use SSH"
-radiobutton .f4.sshssl -anchor w -variable sshssl_sw -value sshssl -command {ssl_ssh_adjust sshssl} -text "SSH+SSL"
-pack .f4.ssl .f4.ssh .f4.sshssl -side left -fill x
-
-set showing_no_encryption 0
-radiobutton .f4.none -anchor w -variable sshssl_sw -value none -command {ssl_ssh_adjust none} -text "None "
-if [disable_encryption] {
- pack .f4.none -side left
- set showing_no_encryption 1
-}
-
-global skip_verify_accepted_certs
-set skip_verify_accepted_certs 0
-global anon_dh_detected
-set anon_dh_detected 0
-global vencrypt_detected
-set vencrypt_detected ""
-
-global always_verify_ssl
-set always_verify_ssl 1;
-if {[info exists env(SSVNC_NO_VERIFY_ALL)]} {
- set always_verify_ssl 0;
-}
-
-if {$uname == "Darwin"} {
- button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert"
-} else {
- button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert" -padx 3
-}
-checkbutton .f4.always -variable always_verify_ssl -text "Verify All Certs" -command no_certs_tutorial_mesg
-pack .f4.getcert -side right -fill x
-if {[info exists env(SSVNC_NO_VERIFY_ALL_BUTTON)]} {
- set always_verify_ssl 0;
-} else {
- pack .f4.always -side right -fill x
-}
-
-if {$ssh_only || $ts_only} {
- ssl_ssh_adjust ssh
-} else {
- ssl_ssh_adjust ssl
-}
-
-frame .b
-button .b.help -text "Help" -command help
-button .b.certs -text "Certs ..." -command getcerts
-button .b.opts -text "Options ..." -command set_options
-button .b.load -text "Load" -command {load_profile}
-button .b.save -text "Save" -command {save_profile}
-button .b.conn -text "Connect" -command launch
-button .b.exit -text "Exit" -command {destroy .; exit}
-
-
-if {$ssh_only || $ts_only} {
- pack .b.opts .b.save .b.load .b.conn .b.help .b.exit -side left -expand 1 -fill x
-} else {
- pack .b.certs .b.opts .b.save .b.load .b.conn .b.help .b.exit -side left -expand 1 -fill x
-}
-
-if {$multientry} {
- if {! $is_windows} {
- if {$ssh_only} {
- pack .l .f0 .f1 .f2 .f3 .b -side top -fill x
- } elseif {$ts_only} {
- pack .l .f0 .f2 .b -side top -fill x
- } else {
- pack .l .f0 .f1 .f2 .f3 .f4 .b -side top -fill x
- }
- } else {
- if {$ssh_only} {
- pack .l .f0 .f2 .f3 .b -side top -fill x
- } elseif {$ts_only} {
- pack .l .f0 .f2 .b -side top -fill x
- } else {
- pack .l .f0 .f2 .f3 .f4 .b -side top -fill x
- }
- }
-} else {
- pack .l .f0 .b -side top -fill x
-}
-if {![info exists env(SSVNC_GUI_CHILD)] || $env(SSVNC_GUI_CHILD) == ""} {
- center_win .
-}
-focus .f0.e
-
-wm deiconify .
-
-global system_button_face
-set system_button_face ""
-foreach item [.b.help configure -bg] {
- set system_button_face $item
-}
-
-if {[info exists env(SSVNC_GUI_CMD)]} {
- set env(SSVNC_GUI_CHILD) 1
- bind . <Control-n> "exec $env(SSVNC_GUI_CMD) &"
-}
-bind . <Control-q> "destroy .; exit"
-bind . <Shift-Escape> "destroy .; exit"
-bind . <Control-s> "launch_shell_only"
-bind . <Control-p> {port_knock_only "" "KNOCK"}
-bind . <Control-P> {port_knock_only "" "FINISH"}
-bind . <Control-l> {load_profile}
-bind . <B3-ButtonRelease> {load_profile}
-
-bind . <Control-t> {toggle_tsonly}
-bind . <Control-d> {delete_profile}
-bind . <Shift-B3-ButtonRelease> {toggle_tsonly}
-bind . <Shift-B2-ButtonRelease> {toggle_tsonly}
-bind .l <Shift-ButtonRelease> {toggle_tsonly}
-bind . <Control-h> {toggle_sshonly}
-bind . <Control-T> {to_ssvnc}
-bind . <Control-a> {set_advanced_options}
-bind . <Control-o> {set_options}
-bind . <Control-u> {set_ssvncviewer_options}
-bind . <Control-e> {toggle_no_encryption}
-
-global entered_gui_top button_gui_top
-set entered_gui_top 0
-set button_gui_top 0
-bind . <Enter> {set entered_gui_top 1}
-bind .l <ButtonPress> {set button_gui_top 1}
-bind .f0.l <ButtonPress> {set button_gui_top 1}
-
-update
-
-mac_raise
-
-set didload 0
-
-for {set i 0} {$i < $argc} {incr i} {
- set item [lindex $argv $i]
- regsub {^--} $item "-" item
- if {$item == "."} {
- ;
- } elseif {$item == "-nv"} {
- set always_verify_ssl 0
- } elseif {$item == "-help"} {
- help
- } elseif {$item == "-ssh"} {
- ;
- } elseif {$item == "-bigger"} {
- ;
- } elseif {$item == "-ts"} {
- ;
- } elseif {$item == "-ss"} {
- ;
- } elseif {$item == "-ssl"} {
- ;
- } elseif {$item == "-tso"} {
- ;
- } elseif {$item == "-mycert" || $item == "-cert"} {
- incr i
- } elseif {$item == "-cacert" || $item == "-ca"} {
- incr i
- } elseif {$item == "-crl"} {
- incr i
- } elseif {$item == "-printhelp"} {
- print_help
- exit;
- } elseif {$item != ""} {
- if {[file exists $item] && [file isfile $item]} {
- set didload 1
- load_profile . $item
- } else {
- set ok 0
- set dir [get_profiles_dir]
- set try "$dir/$item"
- foreach try [list $dir/$item $dir/$item.vnc] {
- if {[file exists $try] && [file isfile $try]} {
- load_profile . $try
- set ok 1
- break;
- }
- }
- if {! $ok && [regexp {:[0-9][0-9]*$} $item]} {
- global vncdisplay
- set vncdisplay $item
- set ok 1
- }
-
- if {! $ok} {
- if {$ts_only || $ssh_only} {
- global vncdisplay
- set vncdisplay $item
- set ok 1
- }
- }
- if {$ok} {
- update
- set didload 1
- if [info exists env(SSVNC_PROFILE_LOADONLY)] {
- if {$env(SSVNC_PROFILE_LOADONLY) == "1"} {
- set ok 0
- }
- }
- if {$ok} {
- after 750
- launch
- }
- }
- }
- }
-}
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf
deleted file mode 100644
index 327327a..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# Example SSL stunnel SERVER configuration file. (e.g. for your VNC
-# server on this same machine.)
-#
-# To use this file you may need to edit it. Then you will need
-# to manually start up stunnel using it.
-# (e.g. /path/to/stunnel stunnel-server.conf)
-#
-# NOTE: You MUST specify a cert = PEM file line for server mode.
-# SSVNC or x11vnc can be used to create one if you like.
-#
-# This is just an example and is not used by the tools in this package.
-# It is here in case you wanted to see how to add SSL support to any
-# VNC server you have.
-#
-RNDbytes = 2048
-RNDfile = bananarand.bin
-RNDoverwrite = yes
-#
-# Remote client certs could go here:
-# CApath = /path/to/.../crt-dir
-# CAfile = /path/to/.../foo.crt
-# verify = 2
-#
-# The server cert goes here (**IT MUST BE SPECIFIED IN SERVER MODE**):
-# cert = /path/to/.../my.pem
-#
-[vnc]
-#
-# Set to local listening port number (e.g. 5901 for vnc display 1):
-# so the remote viewers would connect to: yourmachine:1
-#
-accept = 5901
-#
-# Set to localhost:port to connect to VNC server on this same machine:
-# (E.g. you run WinVNC on :0, preferably listening on localhost).
-#
-connect = localhost:5900
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/build.unix b/x11vnc/misc/enhanced_tightvnc_viewer/build.unix
deleted file mode 100755
index f84ef78..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/build.unix
+++ /dev/null
@@ -1,482 +0,0 @@
-#!/bin/sh
-
-# See the README in this directory for more info on using this script
-# (build.unix). Search for SSVNC_BUILD.
-#
-# Notes: to customize locations, e.g. for libjpeg, set LDFLAGS_OS and/or
-# CPPFLAGS_OS
-#
-# e.g. on Darwin we did:
-#
-# env LDFLAGS_OS="-L/Volumes/someplace/common/lib" CPPFLAGS_OS="-I /Volumes/someplace/common/include" ./build.unix
-#
-
-
-# Add useful directories to PATH:
-#
-PATH=$PATH:/usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/opt/SUNWspro/bin:/usr/sfw/bin:/usr/ccs/bin
-export PATH
-
-# Check location:
-#
-thisdir=`dirname "$0"`
-if [ ! -d ./bin -o ! -d src/patches -o ! -f ./build.unix ]; then
- echo ""
- echo "You must run this script from: $thisdir"
- echo ""
- echo "Maybe:"
- echo ""
- echo " cd $thisdir"
- echo " ./build.unix"
- if [ "X$BUILD_UNIX" != "X" ]; then
- sleep 2
- exit 1
- fi
- echo ""
- sleep 1
- printf "Do you want me to run those for you? y/[n] "
- read x
- if [ "X$x" = "Xy" ]; then
- BUILD_UNIX=1
- export BUILD_UNIX
- cd "$thisdir" || exit 1
- echo "pwd:"
- pwd
- sleep 1
- ./build.unix
- fi
-
- exit $?
-fi
-
-pline() {
- echo "------------------------------------------------------------------"
-}
-
-# Try to find osname.arch
-#
-name=$UNAME
-if [ "X$name" = "X" ]; then
- name=`uname -sm | sed -e 's/ /./g' -e 's/Linux\.i.86/Linux.i686/'`
-fi
-if [ "X$name" = "X" ]; then
- echo "cannot determine platform: os.arch, e.g. Linux.i686"
- echo "set \$UNAME manually and retry."
- exit 1
-fi
-
-LDD="ldd"
-if [ `uname` = "Darwin" ]; then
- LDD="otool -L"
-fi
-
-# Create a tmp dir for this build:
-#
-tmp=./src/tmp/$name.$$
-if [ "X$TMPDIR" != "X" ]; then
- tmp="$TMPDIR/$tmp"
-fi
-mkdir -p $tmp || exit 1
-
-# Do ultraftp Java viewer (only):
-#
-if [ "X$SSVNC_BUILD_ULTRAFTP" != "X" ]; then
- ultraftp_tar=`ls -td ./src/zips/ultraftp.tar* | head -1`
- if [ ! -f $ultraftp_tar ]; then
- echo "could not locate ultraftp java vnc viewer source"
- exit 1
- fi
- echo ""
- pline
- echo "BUILDING THE ULTRAFTP HELPER JAR"
- echo ""
- sleep 1
-
- cat $ultraftp_tar | (cd $tmp; tar xvf -) || exit 1
- cd $tmp/ultraftp || exit 1
- pwd
- echo
- make install
-
- exit 0 # DONE
-fi
-
-# Work out main destination:
-#
-dest=./bin/$name
-if [ -d $dest ]; then
- if [ "X$SSVNC_BUILD_FORCE_OVERWRITE" = "X" ]; then
- printf "$dest exists. overwrite in it? [y]/n "
- read x
- if [ "X$x" = "Xn" ]; then
- exit
- fi
- else
- echo "$dest exists. overwriting in it."
- fi
- if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" ]; then
- if [ `uname` = "Darwin" ]; then
- rm -f $dest/vncviewer.x11*
- else
- rm -f $dest/vncviewer*
- fi
- fi
- if [ "X$SSVNC_BUILD_SKIP_STUNNEL" = "X" ]; then
- rm -f $dest/stunnel*
- fi
-fi
-mkdir -p $dest || exit 1
-
-
-# Try to find some static archives of various libraries:
-#
-libs="$tmp/libs"
-mkdir -p $libs || exit 1
-for liba in libz.a libjpeg.a libssl.a libcrypto.a
-do
- if [ "X$SSVNC_BUILD_STATIC" = "X" ]; then
- break
- fi
- for dir in $SSVNC_STATIC_DIRS /usr/lib /lib /usr/local/lib /usr/pkg/lib /usr/sfw/lib /usr/openwin/lib
- do
- if [ "X$dir" = "X" ]; then
- continue
- fi
- if [ "$name" = "Linux.x86_64" -o "$name" = "Linux.ppc64" ] ; then
- dir64=`echo "$dir" | sed -e 's,lib,lib64,'`
- if [ "X$SSVNC_BUILD_NO_LINUX64" != "X" ]; then
- :
- elif [ -d $dir64 ]; then
- dir=$dir64
- fi
- fi
- try="$dir/$liba"
- if [ -f $try ]; then
- echo cp -p "$try" $libs
- cp -p "$try" $libs
- break
- fi
- done
-done
-if [ "X$SSVNC_BUILD_STATIC" != "X" ]; then
- echo "Found these static archive libraries, will try to use them..."
- ls -ld $libs
- ls -l $libs
- echo
-fi
-
-have_gcc=""
-if type gcc > /dev/null; then
- have_gcc=1
-fi
-have_cc=""
-if type cc > /dev/null; then
- have_cc=1
-fi
-
-if [ "X$have_cc" = "X" ]; then
- if [ "X$have_gcc" = "X1" ]; then
- cat > $tmp/cc <<END
-#!/bin/sh
-gcc "\$@"
-END
- chmod 755 $tmp/cc
- PATH=$PATH:`pwd`/$tmp
- type cc
- type gcc
- fi
-fi
-
-if [ -d /var/tmp/LIBS -a "X$SSVNC_BUILD_STATIC" != "X" ]; then
- LDFLAGS_OS="$LDFLAGS_OS -L/var/tmp/LIBS"
-fi
-
-if [ `uname` = "SunOS" ]; then
- LDFLAGS_OS="$LDFLAGS_OS -L/usr/sfw/lib -R/usr/sfw/lib"
- CPPFLAGS_OS="$CPPFLAGS_OS -I /usr/sfw/include"
-elif uname | grep -i bsd > /dev/null; then
- LDFLAGS_OS="$LDFLAGS_OS -L/usr/local/lib -L/usr/pkg/lib"
- CPPFLAGS_OS="$CPPFLAGS_OS -I /usr/local/include -I /usr/pkg/include"
-fi
-
-cnt=`ls ./src/patches/*.patch | wc -c`
-if [ $cnt -lt 1 ]; then
- echo "Could not find any patches in ./src/patches. Is your tarball missing them?"
- exit 1
-fi
-
-pline() {
- echo "------------------------------------------------------------------"
-}
-
-# Do tightvnc viewer:
-#
-if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" ]; then
- tight_src=`ls -td ./src/vnc_unixsrc* | head -1`
- if [ ! -d $tight_src ]; then
- echo "could not locate tight vnc viewer source"
- exit 1
- fi
- echo ""
- pline
- echo "BUILDING THE VNCVIEWER"
- echo ""
- sleep 1
-
- cp -pR "$tight_src" "$tmp/vnc_unixsrc" || exit 1
-
- echo "applying tight vnc patches:"
- start=`pwd`
- cd $tmp;
- failed=0
- count=0
- patches="../../patches/tight-vncviewer-full.patch"
- if [ ! -f "$patches" ]; then
- patches=`ls ../../patches/tight* | grep -v 'tight-vncviewer-full.patch'`
- fi
- for patch in $patches
- do
- if [ ! -f "$patch" ]; then
- continue
- fi
- if [ "X$PATCH_FAIL" != "X" ]; then
- failed=1
- break
- fi
- echo PATCHING WITH: "$patch"
- ls -l "$patch"
- sleep 1
- patch -p0 < "$patch"
- if [ $? != 0 ]; then
- failed=`expr $failed + 1`
- else
- count=`expr $count + 1`
- fi
- done
- sleep 1
- cd "$start"
- if [ $failed != 0 -o $count = 0 ]; then
- ball=src/zips/vnc_unixsrc_vncviewer.patched.tar
- echo "patches failed, trying to use backup tarball:"
- ls -l $ball
- sleep 2
- cat $ball | (cd $tmp; tar -xvf -)
- fi
- echo
-
-
- cd $tmp/vnc_unixsrc
- xmkmf
- make Makefiles
- mv vncviewer/Makefile vncviewer/Makefile.orig
- sed -e "s,EXTRA_LDOPTIONS =,EXTRA_LDOPTIONS = -L$start/$libs $LDFLAGS_OS," \
- -e "s,CCOPTIONS =,CCOPTIONS = $CPPFLAGS_OS," \
- vncviewer/Makefile.orig > vncviewer/Makefile
-
- if [ `uname` = "SunOS" ]; then
- for d in vncviewer libvncauth vncconnect vncpasswd
- do
- mv $d/Makefile $d/Makefile.orig
- sed -e "s,CCOPTIONS =.*\$,CCOPTIONS = $CPPFLAGS_OS," \
- $d/Makefile.orig > $d/Makefile
- done
- fi
-
- make depend
- echo $PATH
- if [ "X$TURBOVNC" = "X" ]; then
- make all
- else
- make CCOPTIONS="-DTURBOVNC $CPPFLAGS_OS" EXTRA_LIBRARIES="$TURBOVNC" all
- fi
- ls -l vncviewer/vncviewer
- cd "$start"
- src=$tmp/vnc_unixsrc/vncviewer/vncviewer
- sync
- sleep 2
- sync
- strip $src
- sync
- sleep 2
- sync
- wc $src
- sum $src
- sleep 2
-
- suff=""
- if [ `uname` = "Darwin" ]; then
- suff=".x11"
- fi
- if [ "X$TURBOVNC" != "X" ]; then
- suff="$suff.turbovnc"
- fi
- echo cp -p $src $dest/vncviewer$suff
- sleep 1
- cp -p $src $dest/vncviewer$suff || exit 1
-
- echo
- pline
- echo "LISTING, HELP, and LDD THE VNCVIEWER:"
- echo
- sleep 1
-
- ls -l $src $dest/vncviewer$suff
- echo
- echo $dest/vncviewer$suff -h
- echo
- $dest/vncviewer$suff -h
- echo
- echo $LDD $dest/vncviewer$suff
- echo
- $LDD $dest/vncviewer$suff
- echo ""
-fi
-
-# Do stunnel:
-#
-if [ "X$SSVNC_BUILD_SKIP_STUNNEL" = "X" ]; then
- stunnel_src=`ls -td ./src/stunnel* | head -1`
- if [ ! -d $stunnel_src ]; then
- echo "could not locate stunnel source"
- exit 1
- fi
- echo ""
- pline
- echo "BUILDING THE STUNNEL"
- echo ""
- sleep 1
-
- cp -pR "$stunnel_src" "$tmp/stunnel" || exit 1
-
- echo "applying stunnel patches:"
- start=`pwd`
- cd $tmp;
- failed=0
- count=0
- for patch in ../../patches/stunnel*
- do
- if [ ! -f "$patch" ]; then
- continue
- fi
- if [ "X$PATCH_FAIL" != "X" ]; then
- failed=1
- break
- fi
- echo PATCHING WITH: "$patch"
- ls -l "$patch"
- sleep 1
- patch -p0 < $patch
- if [ $? != 0 ]; then
- failed=`expr $failed + 1`
- else
- count=`expr $count + 1`
- fi
- done
- sleep 1
- cd "$start"
- if [ $failed != 0 -o $count = 0 ]; then
- ball=src/zips/stunnel.patched.tar
- echo "patches failed, trying to use backup tarball:"
- ls -l $ball
- sleep 2
- cat $ball | (cd $tmp; tar -xvf -)
- fi
- echo
-
-
- cd $tmp/stunnel
- if [ `uname` = "SunOS" ]; then
- cp configure configure.orig
- sed -e "s,maindir in,maindir in /usr/sfw," configure.orig > configure
- fi
- env LDFLAGS="-L$start/$libs $LDFLAGS_OS" CPPFLAGS="$CPPFLAGS_OS" ./configure --disable-libwrap --enable-ipv6
- make
- ls -l src/stunnel
- cd "$start"
- src=$tmp/stunnel/src/stunnel
- sync
- sleep 2
- sync
- strip $src
- sync
- sleep 2
- sync
- wc $src
- sum $src
- sleep 2
- echo cp -p $src $dest/stunnel
- cp -p $src $dest/stunnel || exit 1
- sleep 1
- cp -p $src $dest/stunnel || exit 1
-
- echo
- pline
- echo "LISTING, HELP, and LDD THE STUNNEL:"
- echo
- sleep 1
-
- ls -l $src $dest/stunnel
- echo
- echo $dest/stunnel -help
- echo
- $dest/stunnel -help
- echo
- echo $LDD $dest/stunnel
- echo
- $LDD $dest/stunnel
- echo ""
-fi
-
-# Do vncstorepw and ld preload friends:
-#
-if [ "X$SSVNC_BUILD_SKIP_VNCSTOREPW" = "X" ]; then
- vncpw_tar=`ls -td ./src/zips/vncstorepw* | head -1`
- if [ ! -f $vncpw_tar ]; then
- echo "could not locate vncstorepw source"
- exit 1
- fi
- echo ""
- pline
- echo "BUILDING THE VNCSTOREPW AND FRIENDS"
- echo ""
- sleep 1
-
- cat "$vncpw_tar" | (cd $tmp; tar xvf -)
-
- cd $tmp/vncstorepw
- make
-
- cd "$start"
- cp -p $tmp/vncstorepw/vncstorepw $tmp/vncstorepw/lim_accept.so $dest
- echo ""
-
- cd $tmp/vncstorepw
- make clean
-
- env LD_SSL="-L$start/$libs $LDFLAGS_OS $LD_SSL" CPP_SSL="$CPPFLAGS_OS" make ultravnc_dsm_helper
-
- cd "$start"
- cp -p $tmp/vncstorepw/ultravnc_dsm_helper $dest
- echo ""
-fi
-
-
-if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" -a "X$SSVNC_BUILD_SKIP_STUNNEL" = "X" ]; then
- # list the viewer again.
-
- echo
- pline
- echo "LISTING, HELP, and LDD THE VNCVIEWER (again):"
- echo
- sleep 1
-
- ls -l $dest/vncviewer$suff
- echo
- echo $dest/vncviewer$suff -h
- echo
- $dest/vncviewer$suff -h
- echo
- echo $LDD $dest/vncviewer$suff
- echo
- $LDD $dest/vncviewer$suff
-fi
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt b/x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt
deleted file mode 100644
index d104f25..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt
+++ /dev/null
@@ -1,280 +0,0 @@
-3277703 4 drwxr-xr-x 6 runge runge 4096 Sep 13 21:28 .
-3277704 4 drwxr-xr-x 7 runge runge 4096 Aug 2 10:05 ./src
-3277781 4 drwxr-xr-x 2 runge runge 4096 Aug 2 10:09 ./src/zips
-3277782 484 -rw-r--r-- 1 runge runge 488512 Jul 25 15:09 ./src/zips/stunnel-4.14.tar.gz
-3277783 212 -rw-r--r-- 1 runge runge 209149 Jul 25 15:10 ./src/zips/tightvnc-1.3dev7_x86_viewer.zip
-3277784 2136 -rw-r--r-- 1 runge runge 2182134 Jul 25 15:11 ./src/zips/tightvnc-1.3dev7_unixsrc.tar.gz
-3277792 4 -rw-r--r-- 1 runge runge 753 Aug 2 10:09 ./src/zips/README
-3277786 364 -rw-r--r-- 1 runge runge 368640 Jul 27 19:06 ./src/zips/vnc_unixsrc_vncviewer.patched.tar
-3277787 1996 -rw-r--r-- 1 runge runge 2037760 Jul 31 23:42 ./src/zips/stunnel.patched.tar
-2982849 4 drwxr-xr-x 2 runge runge 4096 Sep 10 14:37 ./src/patches
-2982852 4 -rw-r--r-- 1 runge runge 3750 Feb 5 2005 ./src/patches/tight-vncviewer-alphahack.patch
-2982854 4 -rw-r--r-- 1 runge runge 1143 Jul 25 15:25 ./src/patches/tight-vncviewer-fullscreen.patch
-2982865 8 -rw-r--r-- 1 runge runge 7633 Jul 27 19:01 ./src/patches/tight-vncviewer-newfbsize.patch
-2982955 4 -rwxr-xr-x 1 runge runge 1529 Sep 10 12:07 ./src/patches/_bundle
-2982877 4 -rwxr-xr-x 1 runge runge 78 Jul 27 14:41 ./src/patches/_getpatches
-2983012 4 -rw-r--r-- 1 runge runge 4072 Jul 31 22:59 ./src/patches/stunnel-maxconn.patch
-2982878 4 -rwxr-xr-x 1 runge runge 117 Jul 27 19:06 ./src/patches/_vncpatchapplied
-2982880 4 -rw-r--r-- 1 runge runge 223 Aug 24 10:11 ./src/patches/README
-2982850 4 drwxr-xr-x 8 runge runge 4096 Jul 25 15:21 ./src/vnc_unixsrc
-2982885 4 -rw-r--r-- 1 runge runge 356 Apr 30 2002 ./src/vnc_unixsrc/Imakefile
-2982886 20 -rw-r--r-- 1 runge runge 18000 Jun 11 2000 ./src/vnc_unixsrc/LICENCE.TXT
-2982887 12 -rw-r--r-- 1 runge runge 8341 Jul 4 2005 ./src/vnc_unixsrc/README
-2982888 12 -rw-r--r-- 1 runge runge 9682 Jul 4 2005 ./src/vnc_unixsrc/tightvnc.spec
-2982889 4 -rw-r--r-- 1 runge runge 486 Aug 30 2002 ./src/vnc_unixsrc/vnc-xclients.patch
-2982890 4 -rwxr-xr-x 1 runge runge 2042 Mar 19 2002 ./src/vnc_unixsrc/vncinstall
-2982891 16 -rwxr-xr-x 1 runge runge 15239 Jul 4 2005 ./src/vnc_unixsrc/vncserver
-2982892 4 -rwxr-xr-x 1 runge runge 1726 Aug 30 2002 ./src/vnc_unixsrc/vncserver.init
-2982893 4 -rw-r--r-- 1 runge runge 3070 Aug 7 2002 ./src/vnc_unixsrc/vncserver.man
-4359127 4 drwxr-xr-x 2 runge runge 4096 Jul 27 16:25 ./src/vnc_unixsrc/classes
-2851413 4 drwxr-xr-x 2 runge runge 4096 Jul 5 2005 ./src/vnc_unixsrc/include
-2851414 44 -rw-r--r-- 1 runge runge 43296 May 27 2004 ./src/vnc_unixsrc/include/rfbproto.h
-2851415 4 -rw-r--r-- 1 runge runge 1166 Jun 11 2000 ./src/vnc_unixsrc/include/vncauth.h
-2851416 4 drwxr-xr-x 2 runge runge 4096 Jul 5 2005 ./src/vnc_unixsrc/libvncauth
-2851417 4 -rw-r--r-- 1 runge runge 199 Apr 30 2002 ./src/vnc_unixsrc/libvncauth/Imakefile
-2851418 16 -rw-r--r-- 1 runge runge 15487 Jun 11 2000 ./src/vnc_unixsrc/libvncauth/d3des.c
-2851419 4 -rw-r--r-- 1 runge runge 1618 Jun 11 2000 ./src/vnc_unixsrc/libvncauth/d3des.h
-2851420 8 -rw-r--r-- 1 runge runge 5879 Mar 1 2003 ./src/vnc_unixsrc/libvncauth/vncauth.c
-2851421 4 drwxr-xr-x 2 runge runge 4096 Jul 5 2005 ./src/vnc_unixsrc/vncconnect
-2851422 4 -rw-r--r-- 1 runge runge 163 Apr 30 2002 ./src/vnc_unixsrc/vncconnect/Imakefile
-2851423 4 -rw-r--r-- 1 runge runge 1167 Nov 10 2000 ./src/vnc_unixsrc/vncconnect/vncconnect.c
-2851424 4 -rw-r--r-- 1 runge runge 1083 Feb 5 2003 ./src/vnc_unixsrc/vncconnect/vncconnect.man
-2851425 4 drwxr-xr-x 2 runge runge 4096 Jul 5 2005 ./src/vnc_unixsrc/vncpasswd
-2851426 4 -rw-r--r-- 1 runge runge 256 Apr 30 2002 ./src/vnc_unixsrc/vncpasswd/Imakefile
-2851427 8 -rw-r--r-- 1 runge runge 7681 Mar 1 2003 ./src/vnc_unixsrc/vncpasswd/vncpasswd.c
-2851428 4 -rw-r--r-- 1 runge runge 3222 Mar 1 2003 ./src/vnc_unixsrc/vncpasswd/vncpasswd.man
-2851429 4 drwxr-xr-x 2 runge runge 4096 Aug 3 19:10 ./src/vnc_unixsrc/vncviewer
-2851430 4 -rw-r--r-- 1 runge runge 1057 Mar 12 2003 ./src/vnc_unixsrc/vncviewer/Imakefile
-2851431 16 -rw-r--r-- 1 runge runge 12375 Jul 4 2005 ./src/vnc_unixsrc/vncviewer/README
-2851432 4 -rw-r--r-- 1 runge runge 3198 Feb 7 2003 ./src/vnc_unixsrc/vncviewer/Vncviewer
-2851433 16 -rw-r--r-- 1 runge runge 14159 Jul 4 2005 ./src/vnc_unixsrc/vncviewer/argsresources.c
-2851434 8 -rw-r--r-- 1 runge runge 5362 Apr 1 2003 ./src/vnc_unixsrc/vncviewer/caps.c
-2851435 4 -rw-r--r-- 1 runge runge 2074 Apr 1 2003 ./src/vnc_unixsrc/vncviewer/caps.h
-2851436 16 -rw-r--r-- 1 runge runge 15568 Apr 30 2002 ./src/vnc_unixsrc/vncviewer/colour.c
-2851437 4 -rw-r--r-- 1 runge runge 2295 Jun 11 2000 ./src/vnc_unixsrc/vncviewer/corre.c
-2851438 16 -rw-r--r-- 1 runge runge 14504 Jan 15 2003 ./src/vnc_unixsrc/vncviewer/cursor.c
-2851439 12 -rw-r--r-- 1 runge runge 11832 May 28 2004 ./src/vnc_unixsrc/vncviewer/desktop.c
-2851440 4 -rw-r--r-- 1 runge runge 2621 Oct 26 2000 ./src/vnc_unixsrc/vncviewer/dialogs.c
-2851441 12 -rw-r--r-- 1 runge runge 11671 Oct 9 2003 ./src/vnc_unixsrc/vncviewer/fullscreen.c
-2851442 4 -rw-r--r-- 1 runge runge 3639 Jun 11 2000 ./src/vnc_unixsrc/vncviewer/hextile.c
-2851443 8 -rw-r--r-- 1 runge runge 7463 Jan 16 2001 ./src/vnc_unixsrc/vncviewer/listen.c
-2851444 12 -rw-r--r-- 1 runge runge 9120 Jan 15 2003 ./src/vnc_unixsrc/vncviewer/misc.c
-2851445 4 -rw-r--r-- 1 runge runge 2749 Jun 11 2000 ./src/vnc_unixsrc/vncviewer/popup.c
-2851446 40 -rw-r--r-- 1 runge runge 38923 Mar 11 2004 ./src/vnc_unixsrc/vncviewer/rfbproto.c
-2851447 4 -rw-r--r-- 1 runge runge 2411 Jun 11 2000 ./src/vnc_unixsrc/vncviewer/rre.c
-2851448 12 -rw-r--r-- 1 runge runge 9985 Mar 3 2004 ./src/vnc_unixsrc/vncviewer/selection.c
-2851449 4 -rw-r--r-- 1 runge runge 2439 Jun 11 2000 ./src/vnc_unixsrc/vncviewer/shm.c
-2851450 12 -rw-r--r-- 1 runge runge 9253 Jan 14 2001 ./src/vnc_unixsrc/vncviewer/sockets.c
-2851451 16 -rw-r--r-- 1 runge runge 16069 Apr 30 2002 ./src/vnc_unixsrc/vncviewer/tight.c
-2851452 8 -rw-r--r-- 1 runge runge 6695 Jul 31 2003 ./src/vnc_unixsrc/vncviewer/tunnel.c
-2851453 4 -rw-r--r-- 1 runge runge 4040 Jan 13 2004 ./src/vnc_unixsrc/vncviewer/vncviewer.c
-2851454 8 -rw-r--r-- 1 runge runge 7236 Mar 11 2004 ./src/vnc_unixsrc/vncviewer/vncviewer.h
-2851455 16 -rw-r--r-- 1 runge runge 14478 Mar 11 2004 ./src/vnc_unixsrc/vncviewer/vncviewer.man
-2851456 8 -rw-r--r-- 1 runge runge 4437 Jan 16 2001 ./src/vnc_unixsrc/vncviewer/zlib.c
-2982894 36 -rw-r--r-- 1 runge runge 34369 Jul 5 2005 ./src/vnc_unixsrc/WhatsNew
-2982895 84 -rw-r--r-- 1 runge runge 80366 Jul 5 2005 ./src/vnc_unixsrc/ChangeLog
-2670933 4 drwxr-xr-x 6 runge runge 4096 Aug 2 09:03 ./src/stunnel-4.14
-3621575 4 drwxr-xr-x 2 runge runge 4096 Nov 2 2005 ./src/stunnel-4.14/auto
-3621576 44 -rwxr-xr-x 1 runge runge 43609 Aug 10 2004 ./src/stunnel-4.14/auto/config.guess
-3621577 32 -rwxr-xr-x 1 runge runge 31160 Aug 10 2004 ./src/stunnel-4.14/auto/config.sub
-3621578 16 -rwxr-xr-x 1 runge runge 13866 Aug 10 2004 ./src/stunnel-4.14/auto/depcomp
-3621579 8 -rwxr-xr-x 1 runge runge 7122 Aug 10 2004 ./src/stunnel-4.14/auto/install-sh
-3621580 184 -rw-r--r-- 1 runge runge 184019 Aug 10 2004 ./src/stunnel-4.14/auto/ltmain.sh
-3621581 12 -rwxr-xr-x 1 runge runge 10266 Aug 10 2004 ./src/stunnel-4.14/auto/missing
-3621582 4 -rwxr-xr-x 1 runge runge 1988 Aug 10 2004 ./src/stunnel-4.14/auto/mkinstalldirs
-5456722 4 drwxr-xr-x 2 runge runge 4096 Jul 31 22:47 ./src/stunnel-4.14/src
-5456723 4 -rw-r--r-- 1 runge runge 1594 Oct 15 2005 ./src/stunnel-4.14/src/Makefile.am
-5456724 20 -rw-r--r-- 1 runge runge 19314 Oct 25 2005 ./src/stunnel-4.14/src/Makefile.in
-5456725 4 -rwxr-xr-x 1 runge runge 2954 Apr 20 2005 ./src/stunnel-4.14/src/stunnel3.in
-5456727 4 -rw-r--r-- 1 runge runge 2376 Dec 31 2004 ./src/stunnel-4.14/src/env.c
-5456728 8 -rw-r--r-- 1 runge runge 7878 Oct 21 2005 ./src/stunnel-4.14/src/common.h
-5456775 12 -rw-r--r-- 1 runge runge 10893 Oct 27 2005 ./src/stunnel-4.14/src/prototypes.h
-5456776 40 -rw-r--r-- 1 runge runge 36917 Oct 24 2005 ./src/stunnel-4.14/src/client.c
-5456777 12 -rw-r--r-- 1 runge runge 9827 Sep 28 2005 ./src/stunnel-4.14/src/log.c
-5456778 44 -rw-r--r-- 1 runge runge 43728 Oct 20 2005 ./src/stunnel-4.14/src/options.c
-5456779 12 -rw-r--r-- 1 runge runge 9137 Apr 11 2005 ./src/stunnel-4.14/src/protocol.c
-5456780 20 -rw-r--r-- 1 runge runge 19335 Oct 30 2005 ./src/stunnel-4.14/src/network.c
-5456781 16 -rw-r--r-- 1 runge runge 12947 Feb 28 2005 ./src/stunnel-4.14/src/resolver.c
-5456782 28 -rw-r--r-- 1 runge runge 25216 Oct 27 2005 ./src/stunnel-4.14/src/ssl.c
-5456783 12 -rw-r--r-- 1 runge runge 9935 Oct 19 2005 ./src/stunnel-4.14/src/sthreads.c
-5456784 16 -rw-r--r-- 1 runge runge 14074 Nov 2 2005 ./src/stunnel-4.14/src/stunnel.c
-5456785 12 -rw-r--r-- 1 runge runge 8254 Jun 13 2005 ./src/stunnel-4.14/src/pty.c
-5456786 32 -rw-r--r-- 1 runge runge 28682 Sep 29 2005 ./src/stunnel-4.14/src/gui.c
-5456787 4 -rw-r--r-- 1 runge runge 227 Nov 5 2002 ./src/stunnel-4.14/src/resources.h
-5456788 4 -rw-r--r-- 1 runge runge 1441 Oct 21 2005 ./src/stunnel-4.14/src/resources.rc
-5456789 8 -rw-r--r-- 1 runge runge 4710 Jul 18 2002 ./src/stunnel-4.14/src/stunnel.ico
-5456791 4 -rw-r--r-- 1 runge runge 76 Jul 18 2002 ./src/stunnel-4.14/src/make.bat
-5456792 4 -rw-r--r-- 1 runge runge 1001 Oct 15 2005 ./src/stunnel-4.14/src/Makefile.w32
-3670989 4 drwxr-xr-x 2 runge runge 4096 Nov 2 2005 ./src/stunnel-4.14/tools
-3670990 4 -rw-r--r-- 1 runge runge 1448 Sep 14 2005 ./src/stunnel-4.14/tools/Makefile.am
-3670991 12 -rw-r--r-- 1 runge runge 12178 Oct 25 2005 ./src/stunnel-4.14/tools/Makefile.in
-3670992 4 -rw-r--r-- 1 runge runge 1436 Sep 22 2005 ./src/stunnel-4.14/tools/stunnel.conf-sample.in
-3670993 4 -rw-r--r-- 1 runge runge 966 Oct 25 2005 ./src/stunnel-4.14/tools/stunnel.init.in
-3670994 4 -rw-r--r-- 1 runge runge 1121 Jul 18 2002 ./src/stunnel-4.14/tools/ca.html
-3670995 4 -rwxr-xr-x 1 runge runge 1793 Jul 18 2002 ./src/stunnel-4.14/tools/ca.pl
-3670996 4 -rw-r--r-- 1 runge runge 409 Jul 18 2002 ./src/stunnel-4.14/tools/importCA.html
-3670997 4 -rwxr-xr-x 1 runge runge 105 Jul 18 2002 ./src/stunnel-4.14/tools/importCA.sh
-3670998 4 -rwxr-xr-x 1 runge runge 223 Apr 23 2004 ./src/stunnel-4.14/tools/script.sh
-3670999 4 -rw-r--r-- 1 runge runge 2618 Oct 21 2005 ./src/stunnel-4.14/tools/stunnel.spec
-3671000 4 -rw-r--r-- 1 runge runge 2989 Jul 6 2005 ./src/stunnel-4.14/tools/stunnel.mak
-3671001 4 -rw-r--r-- 1 runge runge 1175 Sep 1 2002 ./src/stunnel-4.14/tools/stunnel.cnf
-3671002 4 -rw-r--r-- 1 runge runge 3285 Oct 21 2005 ./src/stunnel-4.14/tools/stunnel.nsi
-3671003 4 -rw-r--r-- 1 runge runge 1148 Sep 22 2005 ./src/stunnel-4.14/tools/stunnel.conf
-2670934 4 -rw-r--r-- 1 runge runge 725 Aug 12 2002 ./src/stunnel-4.14/README
-2670935 12 -rw-r--r-- 1 runge runge 8824 Oct 25 2005 ./src/stunnel-4.14/configure.ac
-2670936 240 -rw-r--r-- 1 runge runge 239347 Oct 25 2005 ./src/stunnel-4.14/aclocal.m4
-2670937 4 -rw-r--r-- 1 runge runge 1273 Sep 14 2005 ./src/stunnel-4.14/Makefile.am
-2670938 24 -rw-r--r-- 1 runge runge 20876 Oct 25 2005 ./src/stunnel-4.14/Makefile.in
-2670939 768 -rwxr-xr-x 1 runge runge 780103 Oct 25 2005 ./src/stunnel-4.14/configure
-2670940 4 -rw-r--r-- 1 runge runge 99 Aug 12 2002 ./src/stunnel-4.14/AUTHORS
-2670941 4 -rw-r--r-- 1 runge runge 788 Sep 13 2002 ./src/stunnel-4.14/COPYING
-2670942 28 -rw-r--r-- 1 runge runge 25682 Nov 2 2005 ./src/stunnel-4.14/ChangeLog
-2670943 4 -rw-r--r-- 1 runge runge 1066 Aug 10 2002 ./src/stunnel-4.14/INSTALL
-2670944 4 -rw-r--r-- 1 runge runge 955 Aug 12 2002 ./src/stunnel-4.14/NEWS
-2670945 4 -rw-r--r-- 1 runge runge 1461 Jul 27 2005 ./src/stunnel-4.14/TODO
-2670946 4 -rw-r--r-- 1 runge runge 222 Jul 18 2002 ./src/stunnel-4.14/PORTS
-2670947 4 -rw-r--r-- 1 runge runge 270 Aug 9 2004 ./src/stunnel-4.14/BUGS
-2671491 20 -rw-r--r-- 1 runge runge 17982 Jul 18 2002 ./src/stunnel-4.14/COPYRIGHT.GPL
-2671492 4 -rw-r--r-- 1 runge runge 199 Jul 18 2002 ./src/stunnel-4.14/CREDITS
-2671493 4 -rw-r--r-- 1 runge runge 687 Jul 21 2005 ./src/stunnel-4.14/INSTALL.W32
-5653462 4 drwxr-xr-x 4 runge runge 4096 Jul 30 17:46 ./src/stunnel-4.14/doc
-5653463 4 -rw-r--r-- 1 runge runge 1009 Jan 15 2005 ./src/stunnel-4.14/doc/Makefile.am
-5653464 12 -rw-r--r-- 1 runge runge 12152 Oct 25 2005 ./src/stunnel-4.14/doc/Makefile.in
-5653465 16 -rw-r--r-- 1 runge runge 16341 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.pod
-5653466 20 -rw-r--r-- 1 runge runge 18829 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.pl.pod
-5653467 20 -rw-r--r-- 1 runge runge 17798 Dec 25 2004 ./src/stunnel-4.14/doc/stunnel.fr.pod
-5653468 24 -rw-r--r-- 1 runge runge 23885 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.8
-5653469 28 -rw-r--r-- 1 runge runge 26536 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.pl.8
-5653470 28 -rw-r--r-- 1 runge runge 24864 Jan 15 2005 ./src/stunnel-4.14/doc/stunnel.fr.8
-5653471 28 -rw-r--r-- 1 runge runge 26128 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.html
-5653472 32 -rw-r--r-- 1 runge runge 28753 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.pl.html
-5653473 28 -rw-r--r-- 1 runge runge 27205 Jan 15 2005 ./src/stunnel-4.14/doc/stunnel.fr.html
-4342742 4 drwxr-xr-x 2 runge runge 4096 Jul 18 2002 ./src/stunnel-4.14/doc/en
-4342743 12 -rw-r--r-- 1 runge runge 8414 Jul 18 2002 ./src/stunnel-4.14/doc/en/VNC_StunnelHOWTO.html
-4342744 4 -rw-r--r-- 1 runge runge 4045 Jul 18 2002 ./src/stunnel-4.14/doc/en/transproxy.txt
-4342745 4 drwxr-xr-x 2 runge runge 4096 Jul 18 2002 ./src/stunnel-4.14/doc/pl
-4342746 36 -rw-r--r-- 1 runge runge 36360 Jul 18 2002 ./src/stunnel-4.14/doc/pl/tworzenie_certyfikatow.html
-4342747 8 -rw-r--r-- 1 runge runge 5068 Jul 18 2002 ./src/stunnel-4.14/doc/pl/faq.stunnel-2.html
-3653836 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:44 ./src/tmp
-3277788 4 -rw-r--r-- 1 runge runge 301 Aug 2 10:05 ./src/README
-2851457 4 drwxr-xr-x 12 runge runge 4096 Aug 29 16:32 ./bin
-2261930 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:00 ./bin/Linux.i686
-2261967 196 -rwxr-xr-x 1 runge runge 193076 Jul 31 22:59 ./bin/Linux.i686/vncviewer
-2261999 80 -rwxr-xr-x 1 runge runge 77148 Jul 31 23:00 ./bin/Linux.i686/stunnel
-5538622 4 drwxr-xr-x 2 runge runge 4096 Sep 12 21:24 ./bin/util
-5538759 12 -rwxr-xr-x 1 runge runge 12148 Sep 12 21:24 ./bin/util/ss_vncviewer
-5538760 136 -rwxr-xr-x 1 runge runge 132853 Sep 12 21:17 ./bin/util/ssvnc.tcl
-5538641 4 -rw-r--r-- 1 runge runge 981 Aug 4 09:27 ./bin/util/stunnel-server.conf
-2851794 4 -rwxr-xr-x 1 runge runge 3581 Jul 31 23:00 ./bin/ssvnc_cmd
-2851592 4 -rwxr-xr-x 1 runge runge 3752 Jul 31 23:01 ./bin/tightvncviewer
-2425590 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:30 ./bin/Linux.alpha
-2425595 100 -rwxr-xr-x 1 runge runge 97504 Jul 31 23:30 ./bin/Linux.alpha/stunnel
-2425596 272 -rwxr-xr-x 1 runge runge 274312 Jul 31 23:24 ./bin/Linux.alpha/vncviewer
-3883808 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:24 ./bin/Linux.x86_64
-3883809 84 -rwxr-xr-x 1 runge runge 77896 Jul 31 23:24 ./bin/Linux.x86_64/stunnel
-3883810 112 -rwxr-xr-x 1 runge runge 109656 Jul 31 23:23 ./bin/Linux.x86_64/vncviewer
-3883811 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:27 ./bin/FreeBSD.i386
-3883812 68 -rwxr-xr-x 1 runge runge 64660 Jul 31 23:27 ./bin/FreeBSD.i386/stunnel
-3883813 180 -rwxr-xr-x 1 runge runge 176796 Jul 31 23:24 ./bin/FreeBSD.i386/vncviewer
-3687167 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:27 ./bin/OpenBSD.i386
-3687164 76 -rwxr-xr-x 1 runge runge 72260 Jul 31 23:27 ./bin/OpenBSD.i386/stunnel
-3687165 180 -rwxr-xr-x 1 runge runge 179036 Jul 31 23:24 ./bin/OpenBSD.i386/vncviewer
-4359128 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:27 ./bin/NetBSD.i386
-4359129 72 -rwxr-xr-x 1 runge runge 69064 Jul 31 23:27 ./bin/NetBSD.i386/stunnel
-4359130 176 -rwxr-xr-x 1 runge runge 172624 Jul 31 23:24 ./bin/NetBSD.i386/vncviewer
-2851458 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:25 ./bin/Linux.ppc64
-2851459 76 -rwxr-xr-x 1 runge runge 72856 Jul 31 23:25 ./bin/Linux.ppc64/stunnel
-2851460 196 -rwxr-xr-x 1 runge runge 196112 Jul 31 23:24 ./bin/Linux.ppc64/vncviewer
-3064794 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:47 ./bin/SunOS.sun4u
-3064795 108 -rwxr-xr-x 1 runge runge 106260 Jul 31 23:45 ./bin/SunOS.sun4u/vncviewer
-3064796 76 -rwxr-xr-x 1 runge runge 71748 Jul 31 23:47 ./bin/SunOS.sun4u/stunnel
-2851711 4 -rwxr-xr-x 1 runge runge 1310 Aug 29 16:29 ./bin/ssvnc
-2851793 4 -rwxr-xr-x 1 runge runge 640 Jul 31 17:22 ./bin/.linkin
-3293942 4 drwxr-xr-x 2 runge runge 4096 Aug 1 22:14 ./bin/profiles
-3277791 8 -rwxr-xr-x 1 runge runge 4814 Jul 30 17:54 ./build.unix
-3277785 20 -rw-r--r-- 1 runge runge 18043 Aug 1 2001 ./COPYING
-3277827 8 -rw-r--r-- 1 runge runge 7222 Sep 10 16:04 ./README
-5063553 4 drwxr-xr-x 3 runge runge 4096 Jul 27 16:32 ./man
-5063554 4 drwxr-xr-x 2 runge runge 4096 Jul 27 16:33 ./man/man1
-5063556 16 -rw-r--r-- 1 runge runge 14478 Jul 27 16:32 ./man/man1/vncviewer.1
-5063557 24 -rw-r--r-- 1 runge runge 23885 Jul 27 16:33 ./man/man1/stunnel.1
-5538624 4 drwxr-xr-x 4 runge runge 4096 Sep 6 16:30 ./Windows
-5538633 2312 -rw-r--r-- 1 runge runge 2361922 Sep 12 22:27 ./Windows/ssvnc.exe
-5538576 4 -rw-r--r-- 1 runge runge 2149 Aug 2 09:42 ./Windows/README.txt
-3293943 4 drwxr-xr-x 2 runge runge 4096 Aug 1 22:14 ./Windows/profiles
-4621136 4 drwxr-xr-x 5 runge runge 4096 Sep 6 16:30 ./Windows/util
-5096237 4 drwxr-xr-x 2 runge runge 4096 Sep 2 16:06 ./Windows/util/esound
-5096238 148 -rw-rw-rw- 1 runge runge 146432 Jun 26 2004 ./Windows/util/esound/cygaudiofile.dll
-5096239 60 -rw-rw-rw- 1 runge runge 53270 Feb 19 2003 ./Windows/util/esound/cygesd.dll
-5096241 1132 -rw-rw-rw- 1 runge runge 1153417 May 26 2004 ./Windows/util/esound/cygwin1.dll
-5096242 68 -rw-r--r-- 1 runge runge 65385 Feb 19 2003 ./Windows/util/esound/esd.exe
-5096248 24 -rw-r--r-- 1 runge runge 21282 Feb 19 2003 ./Windows/util/esound/esdcat.exe
-5096249 32 -rw-r--r-- 1 runge runge 32330 Feb 19 2003 ./Windows/util/esound/esdctl.exe
-5096251 24 -rw-r--r-- 1 runge runge 21428 Feb 19 2003 ./Windows/util/esound/esdfilt.exe
-5096252 24 -rw-r--r-- 1 runge runge 22643 Feb 19 2003 ./Windows/util/esound/esdloop.exe
-5096253 24 -rw-r--r-- 1 runge runge 21264 Feb 19 2003 ./Windows/util/esound/esdmon.exe
-5096254 28 -rw-r--r-- 1 runge runge 24835 Feb 19 2003 ./Windows/util/esound/esdplay.exe
-5096255 24 -rw-r--r-- 1 runge runge 21288 Feb 19 2003 ./Windows/util/esound/esdrec.exe
-5096256 28 -rw-r--r-- 1 runge runge 25151 Feb 19 2003 ./Windows/util/esound/esdsample.exe
-5096258 4 -rw-r--r-- 1 runge runge 51 Sep 2 16:05 ./Windows/util/esound/example.bat
-4621144 1132 -rwxr-xr-x 1 runge runge 1153024 Mar 23 2005 ./Windows/util/openssl.exe
-5538626 1548 -rwxr-xr-x 1 runge runge 1578787 Mar 23 2005 ./Windows/util/libeay32.dll
-5538629 624 -rwxr-xr-x 1 runge runge 632226 Mar 23 2005 ./Windows/util/libssl32.dll
-4621310 128 -rw-r--r-- 1 runge runge 126976 Sep 4 10:56 ./Windows/util/pageant.exe
-4621311 164 -rw-r--r-- 1 runge runge 163840 Sep 4 10:57 ./Windows/util/puttygen.exe
-5538631 76 -rwxr-xr-x 1 runge runge 73728 Feb 26 2006 ./Windows/util/stunnel.exe
-5538625 360 -rwxr-xr-x 1 runge runge 364544 Jul 5 2005 ./Windows/util/vncviewer.exe
-4621143 260 -rw-r--r-- 1 runge runge 262144 Sep 2 21:19 ./Windows/util/plink.exe
-3293944 4 drwxr-xr-x 8 runge runge 4096 Sep 5 20:57 ./Windows/util/info
-3293945 4 drwxr-xr-x 2 runge runge 4096 Aug 2 09:40 ./Windows/util/info/vncviewer
-5538627 20 -rw-r--r-- 1 runge runge 18340 Jul 6 2005 ./Windows/util/info/vncviewer/LICENCE.txt
-5538628 4 -rw-r--r-- 1 runge runge 1238 Jul 6 2005 ./Windows/util/info/vncviewer/README.txt
-3294015 4 -rw-r--r-- 1 runge runge 24 Aug 2 09:39 ./Windows/util/info/vncviewer/location.url
-3294016 4 -rw-r--r-- 1 runge runge 38 Aug 2 09:39 ./Windows/util/info/vncviewer/download.url
-3293947 4 drwxr-xr-x 2 runge runge 4096 Aug 2 09:38 ./Windows/util/info/stunnel
-3293948 4 -rw-r--r-- 1 runge runge 99 Aug 12 2002 ./Windows/util/info/stunnel/AUTHORS
-3293949 4 -rw-r--r-- 1 runge runge 788 Sep 13 2002 ./Windows/util/info/stunnel/COPYING
-3293950 20 -rw-r--r-- 1 runge runge 17982 Jul 18 2002 ./Windows/util/info/stunnel/COPYRIGHT.GPL
-3293951 4 -rw-r--r-- 1 runge runge 199 Jul 18 2002 ./Windows/util/info/stunnel/CREDITS
-3293952 4 -rw-r--r-- 1 runge runge 687 Jul 21 2005 ./Windows/util/info/stunnel/INSTALL.W32
-3293953 4 -rw-r--r-- 1 runge runge 725 Aug 12 2002 ./Windows/util/info/stunnel/README
-3293954 28 -rw-r--r-- 1 runge runge 25682 Nov 2 2005 ./Windows/util/info/stunnel/ChangeLog
-3293955 4 -rw-r--r-- 1 runge runge 1066 Aug 10 2002 ./Windows/util/info/stunnel/INSTALL
-3293956 4 -rw-r--r-- 1 runge runge 955 Aug 12 2002 ./Windows/util/info/stunnel/NEWS
-3293958 4 -rw-r--r-- 1 runge runge 222 Jul 18 2002 ./Windows/util/info/stunnel/PORTS
-3293959 4 -rw-r--r-- 1 runge runge 1461 Jul 27 2005 ./Windows/util/info/stunnel/TODO
-3293960 28 -rw-r--r-- 1 runge runge 26128 Sep 29 2005 ./Windows/util/info/stunnel/stunnel.html
-3293969 16 -rw-r--r-- 1 runge runge 14638 Aug 2 09:37 ./Windows/util/info/stunnel/download.html
-3294011 4 -rw-r--r-- 1 runge runge 47 Aug 2 09:15 ./Windows/util/info/stunnel/download.url
-3294012 24 -rw-r--r-- 1 runge runge 21815 Aug 2 09:13 ./Windows/util/info/stunnel/location.html
-3294013 4 -rw-r--r-- 1 runge runge 46 Aug 2 09:13 ./Windows/util/info/stunnel/location.url
-3293961 4 drwxr-xr-x 2 runge runge 4096 Aug 2 09:37 ./Windows/util/info/openssl
-3293965 4 -rw-r--r-- 1 runge runge 47 Aug 2 09:15 ./Windows/util/info/openssl/download.url
-3293963 4 -rw-r--r-- 1 runge runge 46 Aug 2 09:13 ./Windows/util/info/openssl/location.url
-3293964 4 -rw-r--r-- 1 runge runge 3489 Nov 28 2005 ./Windows/util/info/openssl/COPYRIGHT.SSLeay
-3293967 16 -rw-r--r-- 1 runge runge 14638 Aug 2 09:37 ./Windows/util/info/openssl/download.html
-3293962 24 -rw-r--r-- 1 runge runge 21815 Aug 2 09:13 ./Windows/util/info/openssl/location.html
-2261824 4 drwxr-xr-x 2 runge runge 4096 Aug 2 09:36 ./Windows/util/info/plink
-3293966 4 -rw-r--r-- 1 runge runge 3549 Aug 2 09:35 ./Windows/util/info/plink/licence.html
-3293968 4 -rw-r--r-- 1 runge runge 65 Aug 2 09:35 ./Windows/util/info/plink/licence.url
-2261825 28 -rw-r--r-- 1 runge runge 24744 Aug 2 09:35 ./Windows/util/info/plink/download.html
-2261826 4 -rw-r--r-- 1 runge runge 66 Aug 2 09:35 ./Windows/util/info/plink/download.url
-2229126 4 drwxr-xr-x 2 runge runge 4096 Sep 3 12:09 ./Windows/util/info/esound
-2229127 20 -rw-r--r-- 1 runge runge 17992 Sep 3 12:09 ./Windows/util/info/esound/COPYING
-2229128 4 -rw-r--r-- 1 runge runge 40 Sep 3 12:07 ./Windows/util/info/esound/download.url
-2229129 28 -rw-r--r-- 1 runge runge 25265 Sep 3 12:09 ./Windows/util/info/esound/COPYING.LIB
-2229130 4 -rw-r--r-- 1 runge runge 2153 Sep 3 12:09 ./Windows/util/info/esound/AUTHORS
-2229131 4 -rw-r--r-- 1 runge runge 1936 Sep 3 12:09 ./Windows/util/info/esound/README
-2229132 4 -rw-r--r-- 1 runge runge 178 Sep 3 12:09 ./Windows/util/info/esound/MAINTAINERS
-3113803 4 drwxr-xr-x 2 runge runge 4096 Sep 5 20:58 ./Windows/util/info/netcat
-3113804 8 -rw-r--r-- 1 runge runge 6833 Dec 27 2004 ./Windows/util/info/netcat/readme.txt
-3113805 20 -rw-r--r-- 1 runge runge 18009 Dec 27 2004 ./Windows/util/info/netcat/license.txt
-3064790 4 drwxr-xr-x 2 runge runge 4096 Aug 2 09:40 ./Windows/util/w98
-4621137 120 -rw-r--r-- 1 runge runge 118524 Feb 26 1997 ./Windows/util/w98/kill.exe
-4621138 116 -rw-r--r-- 1 runge runge 114240 Feb 26 1997 ./Windows/util/w98/tlist.exe
-3064797 24 -rw-r--r-- 1 runge runge 24576 Apr 30 1998 ./Windows/util/w98/README.DOC
-3064799 4 -rw-r--r-- 1 runge runge 75 Aug 2 08:56 ./Windows/util/w98/location.url
-4621140 4 -rw-r--r-- 1 runge runge 981 Aug 4 09:27 ./Windows/util/stunnel-server.conf
-4621142 4 -rw-r--r-- 1 runge runge 1173 Aug 4 09:27 ./Windows/util/stunnel-client.conf
-4621312 64 -rw-r--r-- 1 runge runge 61440 Dec 29 2004 ./Windows/util/netcat.exe
-5538607 416 -rw-r--r-- 1 runge runge 421888 Sep 6 14:14 ./Windows/util/putty.exe
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1 b/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1
deleted file mode 100644
index 60c60de..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1
+++ /dev/null
@@ -1,233 +0,0 @@
-'\" t
-.\" ** The above line should force tbl to be a preprocessor **
-.\" Man page for the SSVNC vncviewer
-.\"
-.\" Copyright (C) 2006-2009 Karl J. Runge <runge@karlrunge.com>
-.\"
-.\" You may distribute under the terms of the GNU General Public
-.\" License as specified in the file LICENCE.TXT that comes with the
-.\" TightVNC distribution.
-.\"
-.TH ssvnc 1 "December 2009" "" "SSVNC"
-.SH NAME
-ssvnc \- a GUI wrapper for SSL and SSH VNC connections.
-.SH SYNOPSIS
-.B ssvnc
-.br
-.B ssvnc
-.RI [\| host \|][\| :display \|]
-.br
-.B ssvnc
-.RI [\| saved-profile-name \|]
-.br
-.B ssvnc
-.RI [\| options \|]\ [\| host-or-profile \]
-.br
-.B ssvnc
-.IR \-cmd
-.RI [\| ssvnc_cmd-args \|]
-.br
-.B ssvnc
-.IR \--help
-.br
-.SH DESCRIPTION
-.B ssvnc
-is a tcl/tk gui wrapper that runs on Unix, MacOSX, and Windows.
-It sets up an SSL or SSH tunnel to the remote VNC Server and then launches
-the VNC viewer (either the one provided or another one that you have
-specified) to use that encrypted tunnel to connect to the VNC Server.
-The use of Proxies and Gateways to make the connections is implemented.
-
-Once you have started the SSVNC gui, you can click on the buttons
-"Help", "Options -> Help", "Certs -> Help", etc. for much information
-on how to use and configure the tool.
-
-In short, you supply a VNC server "hostname:display" in the
-"VNC Host:Display" entry box and then press the "Connect" button to
-connect to the server via SSL (stunnel). E.g. "far-away.east:0".
-Port numbers are also allowed, e.g. far-away.east:5905.
-
-Or supply user@hostname:display and click on the "Use SSH" option, then
-press the "Connect" button to connect to the server via an SSH tunnel.
-E.g. "fred@far-away.east:0".
-
-Note it is also possible to disable the use of SSL/SSH
-encryption tunnels by using a vnc:// or Vnc:// prefix before
-host:display. Shift+Ctrl-E is a short-cut to add/remove it.
-See also the \fB-noenc\fR option below for the 'No Encryption' button.
-
-Normally you do not specify any command line options. You simply
-run \fBssvnc\fR and use the GUI that starts up.
-
-However, as shortcuts you can supply a VNC host:display (or host:port)
-on the command line to connect to immediately (the GUI is started
-and the connection is initiated). For example, "\fBssvnc far-away.east:0\fR"
-Instead of a host:display, you can specify the name of a saved profile to
-automatically load that profile and then connect to its server.
-For example "\fBssvnc far\fR", if you named the profile "far".
-You can use the \fB-profiles\fR option to list the profiles you have saved.
-
-The related commands \fBsshvnc\fR and \fBtsvnc\fR start up the GUI in
-simplified modes: SSH Only Mode, and Terminal Services Mode, respectively.
-See below and the application Help for more information on the modes.
-
-You can also place certain settings in your ~/.ssvncrc, see the
-SSVNC Help panel ('Tips') for more info.
-
-The \fB-cmd\fR option does not start the GUI, it runs the command
-line utility \fBssvnc_cmd\fR directly with the given arguments.
-\fBssvnc_cmd\fR can launch the viewer directly (\fB-viewer ...\fR)
-or, by default, the \fBss_vncviewer\fR SSL/SSH tunnel wrapper script.
-See its help output for more information.
-
-There are also some command line options described as follows.
-.SH OPTIONS
-.TP
-\fB\-help\fR, \fB\-h\fR
-Prints out to the terminal a brief description and the options.
-.TP
-\fB\--help\fR
-Starts up the GUI as though the 'Help' button was pressed to show the
-main Help panel.
-.TP
-\fB\-cmd\fR \fI[ssvnc_cmd-args]\fR
-Launch the ssvnc_cmd utility command directly (no GUI) with the given
-arguments (for use when ssvnc_cmd is not in one's PATH.) If neither
-ssvnc_cmd nor ssvncviewer is in PATH, one can launch the viewer
-directly via: ssvnc -cmd -viewer [viewer-args]
-.TP
-\fB\-profiles\fR
-List the saved SSVNC profiles you have created. A profile
-is a destination host with specific parameter settings.
-.TP
-\fB\-list\fR
-Same as \fB\-profiles\fR
-.TP
-\fB\-ssh\fR
-Start in "SSH Only Mode". No SSL aspects are shown.
-Same as running the command \fBsshvnc\fR
-.TP
-\fB\-ts\fR
-Start in "Terminal Services Mode". This is like "SSH Only Mode", but
-simpler and assumes \fBx11vnc\fR is available on the remote side
-to start and manage X and VNC sessions.
-Same as running the command \fBtsvnc\fR
-.TP
-\fB\-tso\fR
-Same as \fB-ts\fR "Terminal Services Mode", however never let the
-user leave this mode (no button to switch modes is provided.)
-Same as SSVNC_TS_ALWAYS=1.
-.TP
-\fB\-ssl\fR
-Force the full GUI Mode: both SSL and SSH. This is the default.
-Same as \fB-ss\fR.
-.TP
-\fB\-nv\fR
-Toggle the "Verify All Certs" button to be off at startup.
-.TP
-\fB\-nvb\fR
-Never show the "Verify All Certs" button.
-Same as SSVNC_NO_VERIFY_ALL_BUTTON=1.
-.TP
-\fB\-bigger\fR
-Make the Profile Selection Dialog window bigger.
-Same as SSVNC_BIGGER_DIALOG=1.
-.TP
-\fB\-noenc\fR
-Start off in a mode where a 'No Encryption' check button is present.
-You can toggle the mode with Ctrl-E.
-Same as SSVNC_DISABLE_ENCRYPTION_BUTTON=1. Or \fInoenc=1\fR in ~/.ssvncrc.
-Selecting no encryption is the same as the vnc:// and Vnc:// prefixes
-described below. The \fB\-noenc\fR mode is now the default, use \fB-enc\fR
-or \fInoenc=0\fR for the opposite behavior.
-.TP
-\fB\-killstunnel\fR
-On Windows, automatically terminate the STUNNEL process when the viewer
-exits instead of prompting you (same as \fIkillstunnel=1\fR in ssvnc_rc or
-toggle in Options menu)
-.TP
-\fB\-nokillstunnel\fR
-On Windows, disable \fB-killstunnel\fR mode.
-Same as \fIkillstunnel=0\fR in ssvnc_rc or
-toggle in Options menu. Note that \fB-killstunnel\fR mode is now the default.
-.TP
-\fB\-mycert\fR \fI/path/to/mycert.pem\fR
-Set the default "MyCert" to be \fI/path/to/mycert.pem\fR.
-Same as \fB-cert\fR.
-If the file does not exist, ~/.vnc/certs is prefixed and tried.
-You can also set \fImycert=/path/to/mycert.pem\fR in ~/.ssvncrc.
-.TP
-\fB\-cacert\fR \fI/path/to/cacert.crt\fR
-Set the default "ServerCert" to be \fI/path/to/cacert.crt\fR.
-Same as \fB-ca\fR.
-If the file does not exist, ~/.vnc/certs is prefixed and tried.
-You can also set \fIcacert=/path/to/cacert.crt\fR in ~/.ssvncrc.
-.TP
-\fB\-crl\fR \fI/path/to/mycrl.pem\fR
-Set the default Certificate Revocation List to be \fI/path/to/mycrl.pem\fR.
-If the file does not exist, ~/.vnc/certs is prefixed and tried.
-You can also set \fIcrl=/path/to/mycrl.pem\fR in ~/.ssvncrc.
-.SH URL NOTATION
-Here are all of our URL-like prefixes that you can put in front of
-host:display (or host:port):
-
-For SSL: vncs:// vncssl:// and vnc+ssl://
-
-For SSH: vncssh:// and vnc+ssh://
-
-For No Encryption: vnc:// and Vnc://
-
-Examples:
-
-To quickly make an SSL connection: \fBssvnc vncs://snoopy.com:0\fR
-
-To quickly make an SSH connection: \fBssvnc vnc+ssh://fred@snoopy.com:0\fR
-
-To quickly make a direct connection: \fBssvnc Vnc://snoopy.com:0\fR
-
-The above will also work in the "VNC Host:Display" entry box in the GUI.
-Press the "Connect" button after entering them.
-
-The difference between vnc:// and Vnc:// is that the latter one will not
-prompt you whether you really want to make an unencrypted connection
-or not.
-.SH FILES
-Your SSVNC vnc profiles are stored in the \fB$HOME/.vnc/profiles\fR
-directory. They end in suffix \fB.vnc\fR
-
-Your SSVNC vnc certificates and keys are stored in the \fB$HOME/.vnc/certs\fR
-directory. They typically end in \fB.pem\fR (both certificate and
-private key) or \fB.crt\fR (certificate only).
-
-You can put a few global parameters (e.g. mode=sshvnc) in your
-\fB$HOME/.ssvncrc\fR file (\fBssvnc_rc\fR on Windows); see the
-application Help for more information.
-
-.SH FONTS
-
-The following is from Tip 18 in the Help panel.
-
-Fonts: To change the tk fonts, set these environment variables
-before starting up ssvnc: SSVNC_FONT_DEFAULT and SSVNC_FONT_FIXED.
-For example:
-
-% env SSVNC_FONT_DEFAULT='helvetica -20 bold' ssvnc
-
-% env SSVNC_FONT_FIXED='courier -14' ssvnc
-
-or set both of them at once.
-
-To achieve the same effect, you can also
-set parameters in your ~/.ssvncrc file, for example:
-
-font_default=helvetica -20 bold
-
-font_fixed=courier -14
-
-.SH SEE ALSO
-\fBssvncviewer\fB(1), \fBvncviewer\fR(1), \fBstunnel\fR(8), \fBssh\fR(1), \fBx11vnc\fR(1), \fBvncserver\fR(1)
-http://www.karlrunge.com/x11vnc http://www.karlrunge.com/x11vnc/ssvnc.html
-.SH AUTHORS
-Karl J. Runge <runge@karlrunge.com> wrote the SSVNC gui (tcl/tk) and
-associated wrapper scripts, and added features to the unix vncviewer
-source code.
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 b/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1
deleted file mode 100644
index cdfc7ae..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1
+++ /dev/null
@@ -1,829 +0,0 @@
-'\" t
-.\" ** The above line should force tbl to be a preprocessor **
-.\" Man page for X vncviewer
-.\"
-.\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de
-.\" Copyright (C) 2000,2001 Red Hat, Inc.
-.\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru>
-.\" Copyright (C) 2006-2010 Karl J. Runge <runge@karlrunge.com>
-.\"
-.\" You may distribute under the terms of the GNU General Public
-.\" License as specified in the file LICENCE.TXT that comes with the
-.\" TightVNC distribution.
-.\"
-.TH ssvncviewer 1 "April 2010" "" "SSVNC"
-.SH NAME
-ssvncviewer \- an X viewer client for VNC
-.SH SYNOPSIS
-.B ssvncviewer
-.RI [\| options \|]
-.RI [\| host \|][\| :display \|]
-.br
-.B ssvncviewer
-.RI [\| options \|]
-.RI [\| host \|][\| ::port \|]
-.br
-.B ssvncviewer
-.RI [\| options \|]
-.RI exec=[\| cmd+args... \|]
-.br
-.B ssvncviewer
-.RI [\| options \|]
-.RI fd=n
-.br
-.B ssvncviewer
-.RI [\| options \|]
-.RI /path/to/unix/socket
-.br
-.B ssvncviewer
-.RI [\| options \|]
-.IR \-listen
-.RI [\| display \|]
-.br
-.B ssvncviewer
-.IR \-help
-.br
-.SH DESCRIPTION
-.B ssvncviewer
-is an Xt\-based client application for the VNC (Virtual Network
-Computing) system. It can connect to any VNC\-compatible server such
-as \fBXvnc\fR, WinVNC, or \fBx11vnc\fR, allowing you to control desktop environment
-of a different machine.
-
-ssvncviewer is an enhanced version of the tightvnc unix viewer that can
-take advantage of features in the \fBx11vnc\fR and UltraVNC VNC servers.
-See below for the description of these features.
-
-You can use F8 to display a pop\-up utility menu. Press F8 twice to
-pass single F8 to the remote side.
-.SH OPTIONS
-.TP
-\fB\-help\fR
-Prints a short usage notice to stderr.
-.TP
-\fB\-listen\fR
-Make the viewer listen on port 5500+\fIdisplay\fR for reverse
-connections from a server. WinVNC supports reverse connections using
-the "Add New Client" menu option, or the \-connect command line
-option. \fBXvnc\fR requires the use of the helper program
-\fBvncconnect\fR.
-.TP
-\fB\-via\fR \fIgateway\fR
-Automatically create encrypted TCP tunnel to the \fIgateway\fR machine
-before connection, connect to the \fIhost\fR through that tunnel
-(TightVNC\-specific). By default, this option invokes SSH local port
-forwarding, assuming that SSH client binary can be accessed as
-/usr/bin/ssh. Note that when using the \fB\-via\fR option, the host
-machine name should be specified as known to the gateway machine, e.g.
-"localhost" denotes the \fIgateway\fR, not the machine where vncviewer
-was launched. See the ENVIRONMENT section below for the information on
-configuring the \fB\-via\fR option.
-.TP
-\fB\-shared\fR
-When connecting, specify that a shared connection is requested. In
-TightVNC, this is the default mode, allowing you to share the desktop
-with other clients already using it.
-.TP
-\fB\-noshared\fR
-When connecting, specify that the session may not be shared. This
-would either disconnect other connected clients or refuse your
-connection, depending on the server configuration.
-.TP
-\fB\-viewonly\fR
-Disable transfer of mouse and keyboard events from the client to the
-server.
-.TP
-\fB\-fullscreen\fR
-Start in full\-screen mode. Please be aware that operating in
-full\-screen mode may confuse X window managers. Typically, such
-conflicts cause incorrect handling of input focus or make the viewer
-window disappear mysteriously. See the grabKeyboard setting in the
-RESOURCES section below for a method to solve input focus problem.
-.TP
-\fB\-noraiseonbeep\fR
-By default, the viewer shows and raises its window on remote beep
-(bell) event. This option disables such behaviour
-(TightVNC\-specific).
-.TP
-\fB\-user\fR \fIusername\fR
-User name for Unix login authentication. Default is to use current
-Unix user name. If this option was given, the viewer will prefer Unix
-login authentication over the standard VNC authentication.
-.TP
-\fB\-passwd\fR \fIpasswd\-file\fR
-File from which to get the password (as generated by the
-\fBvncpasswd\fR(1) program). This option affects only the standard VNC
-authentication.
-.TP
-\fB\-encodings\fR \fIencoding\-list\fR
-TightVNC supports several different compression methods to encode
-screen updates; this option specifies a set of them to use in order of
-preference. Encodings are specified separated with spaces, and must
-thus be enclosed in quotes if more than one is specified. Commas may be used to avoid spaces.
-Available encodings, in default order for a remote connection, are
-"copyrect tight hextile zlib corre rre raw". For a local connection
-(to the same machine), the default order to try is "raw copyrect tight
-hextile zlib corre rre". Raw encoding is always assumed as a last option
-if no other encoding can be used for some reason. For more information
-on encodings, see the section ENCODINGS below.
-.TP
-\fB\-bgr233\fR
-Always use the BGR233 format to encode pixel data. This reduces
-network traffic, but colors may be represented inaccurately. The
-bgr233 format is an 8\-bit "true color" format, with 2 bits blue, 3
-bits green, and 3 bits red.
-.TP
-\fB\-owncmap\fR
-Try to use a PseudoColor visual and a private colormap. This allows
-the VNC server to control the colormap.
-.TP
-\fB\-truecolour\fR, \fB\-truecolor\fR
-Try to use a TrueColor visual.
-.TP
-\fB\-depth\fR \fIdepth\fR
-On an X server which supports multiple TrueColor visuals of different
-depths, attempt to use the specified one (in bits per pixel); if
-successful, this depth will be requested from the VNC server.
-.TP
-\fB\-compresslevel \fIlevel\fR
-Use specified compression \fIlevel\fR (0..9) for "tight" and "zlib"
-encodings (TightVNC\-specific). Level 1 uses minimum of CPU time and
-achieves weak compression ratios, while level 9 offers best
-compression but is slow in terms of CPU time consumption on the server
-side. Use high levels with very slow network connections, and low
-levels when working over high\-speed LANs. It's not recommended to use
-compression level 0, reasonable choices start from the level 1.
-.TP
-\fB\-quality \fIlevel\fR
-Use the specified JPEG quality \fIlevel\fR (0..9) for the "tight"
-encoding (TightVNC\-specific). Quality level 0 denotes bad image
-quality but very impressive compression ratios, while level 9 offers
-very good image quality at lower compression ratios. Note that the
-"tight" encoder uses JPEG to encode only those screen areas that look
-suitable for lossy compression, so quality level 0 does not always
-mean unacceptable image quality.
-.TP
-\fB\-nojpeg\fR
-Disable lossy JPEG compression in Tight encoding (TightVNC\-specific).
-Disabling JPEG compression is not a good idea in typical cases, as
-that makes the Tight encoder less efficient. You might want to use
-this option if it's absolutely necessary to achieve perfect image
-quality (see also the \fB\-quality\fR option).
-.TP
-\fB\-nocursorshape\fR
-Disable cursor shape updates, protocol extensions used to handle
-remote cursor movements locally on the client side
-(TightVNC\-specific). Using cursor shape updates decreases delays with
-remote cursor movements, and can improve bandwidth usage dramatically.
-.TP
-\fB\-x11cursor\fR
-Use a real X11 cursor with X-style cursor shape updates, instead of
-drawing the remote cursor on the framebuffer. This option also
-disables the dot cursor, and disables cursor position updates in
-non-fullscreen mode.
-.TP
-\fB\-autopass\fR
-Read a plain-text password from stdin. This option affects only the
-standard VNC authentication.
-
-.SH Enhanced TightVNC Viewer (SSVNC) OPTIONS
-.TP
-Enhanced TightVNC Viewer (SSVNC) web page is located at:
-.TP
-http://www.karlrunge.com/x11vnc/ssvnc.html
-.TP
-Note: ZRLE and ZYWRLE encodings are now supported.
-.TP
-Note: F9 is shortcut to Toggle FullScreen mode.
-.TP
-Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1
-to allow more than one incoming VNC server at a time.
-This is the same as -multilisten described below. Set
-SSVNC_MULTIPLE_LISTEN=MAX:n to allow no more than "n"
-simultaneous reverse connections.
-
-If the host:port is specified as "exec=command args..."
-then instead of making a TCP/IP socket connection to the
-remote VNC server, "command args..." is executed and the
-viewer is attached to its stdio. This enables tunnelling
-established via an external command, e.g. an stunnel(8)
-that does not involve a listening socket.
-This mode does not work for -listen reverse connections.
-
-If the host:port is specified as "fd=n" then it is assumed
-n is an already opened file descriptor to the socket. (i.e
-the parent did fork+exec)
-
-If the host:port contains a '/' it is interpreted as a
-unix-domain socket (AF_LOCAL insead of AF_INET)
-.TP
-\fB\-multilisten\fR
-As in -listen (reverse connection listening) except
-allow more than one incoming VNC server to be connected
-at a time. The default for -listen of only one at a
-time tries to play it safe by not allowing anyone on
-the network to put (many) desktops on your screen over
-a long window of time. Use -multilisten for no limit.
-.TP
-\fB\-acceptpopup\fR
-In \fB\-listen\fR (reverse connection listening) mode when
-a reverse VNC connection comes in show a popup asking
-whether to Accept or Reject the connection. The IP
-address of the connecting host is shown. Same as
-setting the env. var. SSVNC_ACCEPT_POPUP=1.
-.TP
-\fB\-acceptpopupsc\fR
-As in \fB\-acceptpopup\fR except assume UltraVNC Single
-Click (SC) server. Retrieve User and ComputerName
-info from UltraVNC Server and display in the Popup.
-.TP
-\fB\-use64\fR
-In \fB\-bgr233\fR mode, use 64 colors instead of 256.
-.TP
-\fB\-bgr222\fR
-Same as \fB\-use64\fR.
-.TP
-\fB\-use8\fR
-In \fB\-bgr233\fR mode, use 8 colors instead of 256.
-.TP
-\fB\-bgr111\fR
-Same as \fB\-use8\fR.
-.TP
-\fB\-16bpp\fR
-If the vnc viewer X display is depth 24 at 32bpp
-request a 16bpp format from the VNC server to cut
-network traffic by up to 2X, then tranlate the
-pixels to 32bpp locally.
-.TP
-\fB\-bgr565\fR
-Same as \fB\-16bpp\fR.
-.TP
-\fB\-grey\fR
-Use a grey scale for the 16- and 8\fB\-bpp\fR modes.
-.TP
-\fB\-alpha\fR
-Use alphablending transparency for local cursors
-requires: x11vnc server, both client and server
-must be 32bpp and same endianness.
-.TP
-\fB\-scale\fR \fIstr\fR
-Scale the desktop locally. The string "str" can
-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. "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 \fB\-x11cursor\fR.)
-
-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 \fB\-solid\fR ...)
-
-If the remote server is x11vnc, try client
-side caching: x11vnc \fB\-ncache\fR 10 ...
-.TP
-\fB\-ycrop\fR n
-Only show the top n rows of the framebuffer. For
-use with x11vnc \fB\-ncache\fR client caching option
-to help "hide" the pixel cache region.
-Use a negative value (e.g. \fB\-1\fR) for autodetection.
-Autodetection will always take place if the remote
-fb height is more than 2 times the width.
-.TP
-\fB\-sbwidth\fR n
-Scrollbar width for x11vnc \fB\-ncache\fR mode (\fB\-ycrop\fR),
-default is very narrow: 2 pixels, it is narrow to
-avoid distraction in \fB\-ycrop\fR mode.
-.TP
-\fB\-nobell\fR
-Disable bell.
-.TP
-\fB\-rawlocal\fR
-Prefer raw encoding for localhost, default is
-no, i.e. assumes you have a SSH tunnel instead.
-.TP
-\fB\-notty\fR
-Try to avoid using the terminal for interactive
-responses: use windows for messages and prompting
-instead. Messages will also be printed to terminal.
-.TP
-\fB\-sendclipboard\fR
-Send the X CLIPBOARD selection (i.e. Ctrl+C,
-Ctrl+V) instead of the X PRIMARY selection (mouse
-select and middle button paste.)
-.TP
-\fB\-sendalways\fR
-Whenever the mouse enters the VNC viewer main
-window, send the selection to the VNC server even if
-it has not changed. This is like the Xt resource
-translation SelectionToVNC(always)
-.TP
-\fB\-recvtext\fR
-str When cut text is received from the VNC server,
-ssvncviewer will set both the X PRIMARY and the
-X CLIPBOARD local selections. To control which
-is set, specify 'str' as 'primary', 'clipboard',
-or 'both' (the default.)
-.TP
-\fB\-graball\fR
-Grab the entire X server when in fullscreen mode,
-needed by some old window managers like fvwm2.
-.TP
-\fB\-popupfix\fR
-Warp the popup back to the pointer position,
-needed by some old window managers like fvwm2.
-.TP
-\fB\-grabkbd\fR
-Grab the X keyboard when in fullscreen mode,
-needed by some window managers. Same as \fB\-grabkeyboard\fR.
-\fB\-grabkbd\fR is the default, use \fB\-nograbkbd\fR to disable.
-.TP
-\fB\-bs\fR, \fB\-nobs\fR
-Whether or not to use X server Backingstore for the
-main viewer window. The default is to not, mainly
-because most Linux, etc, systems X servers disable
-*all* Backingstore by default. To re\fB\-enable\fR it put
-
-Option "Backingstore"
-
-in the Device section of /etc/X11/xorg.conf.
-In \fB\-bs\fR mode with no X server backingstore, whenever an
-area of the screen is re\fB\-exposed\fR it must go out to the
-VNC server to retrieve the pixels. This is too slow.
-
-In \fB\-nobs\fR mode, memory is allocated by the viewer to
-provide its own backing of the main viewer window. This
-actually makes some activities faster (changes in large
-regions) but can appear to "flash" too much.
-.TP
-\fB\-noshm\fR
-Disable use of MIT shared memory extension (not recommended)
-.TP
-\fB\-termchat\fR
-Do the UltraVNC chat in the terminal vncviewer is in
-instead of in an independent window.
-.TP
-\fB\-unixpw\fR \fIstr\fR
-Useful for logging into x11vnc in \fB\-unixpw\fR mode. "str" is a
-string that allows many ways to enter the Unix Username
-and Unix Password. These characters: username, newline,
-password, newline are sent to the VNC server after any VNC
-authentication has taken place. Under x11vnc they are
-used for the \fB\-unixpw\fR login. Other VNC servers could do
-something similar.
-
-You can also indicate "str" via the environment
-variable SSVNC_UNIXPW.
-
-Note that the Escape key is actually sent first to tell
-x11vnc to not echo the Unix Username back to the VNC
-viewer. Set SSVNC_UNIXPW_NOESC=1 to override this.
-
-If str is ".", then you are prompted at the command line
-for the username and password in the normal way. If str is
-"-" the stdin is read via getpass(3) for username@password.
-Otherwise if str is a file, it is opened and the first line
-read is taken as the Unix username and the 2nd as the
-password. If str prefixed by "rm:" the file is removed
-after reading. Otherwise, if str has a "@" character,
-it is taken as username@password. Otherwise, the program
-exits with an error. Got all that?
-.TP
-\fB-repeater\fR \fIstr\fR
-This is for use with UltraVNC repeater proxy described
-here: http://www.uvnc.com/addons/repeater.html. The "str"
-is the ID string to be sent to the repeater. E.g. ID:1234
-It can also be the hostname and port or display of the VNC
-server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when
-using -repeater, the host:dpy on the cmdline is the repeater
-server, NOT the VNC server. The repeater will connect you.
-
-Example: vncviewer ... -repeater ID:3333 repeat.host:5900
-
-Example: vncviewer ... -repeater vhost:0 repeat.host:5900
-
-Use, e.g., '-repeater SCIII=ID:3210' if the repeater is a
-Single Click III (SSL) repeater (repeater_SSL.exe) and you
-are passing the SSL part of the connection through stunnel, socat, etc.
-This way the magic UltraVNC string 'testB' needed to work with the
-repeater is sent to it.
-.TP
-\fB-rfbversion\fR \fIstr\fR
-Set the advertised RFB version. E.g.: -rfbversion 3.6 For some
-servers, e.g. UltraVNC this needs to be done.
-.TP
-\fB-ultradsm\fR
-UltraVNC has symmetric private encryption DSM plugins. See
-http://www.uvnc.com/features/encryption.html. It is assumed
-you are using a unix program (e.g. our ultravnc_dsm_helper) to
-encrypt and decrypt the UltraVNC DSM stream. IN ADDITION TO
-THAT supply -ultradsm to tell THIS viewer to modify the RFB
-data sent so as to work with the UltraVNC Server. For some
-reason, each RFB msg type must be sent twice under DSM.
-.TP
-\fB\-mslogon\fR \fIuser\fR
-Use Windows MS Logon to an UltraVNC server. Supply the
-username or "1" to be prompted. The default is to
-autodetect the UltraVNC MS Logon server and prompt for
-the username and password.
-
-IMPORTANT NOTE: The UltraVNC MS-Logon Diffie-Hellman
-exchange is very weak and can be brute forced to recover
-your username and password in a few seconds of CPU
-time. To be safe, be sure to use an additional encrypted
-tunnel (e.g. SSL or SSH) for the entire VNC session.
-.TP
-\fB\-chatonly\fR
-Try to be a client that only does UltraVNC text chat. This
-mode is used by x11vnc to present a chat window on the physical
-X11 console (i.e. to chat with the person at the display).
-.TP
-\fB-env\fR \fIVAR=VALUE\fR
-To save writing a shell script to set environment
-variables, specify as many as you need on the command line. For example,
--env SSVNC_MULTIPLE_LISTEN=MAX:5 -env EDITOR=vi
-.TP
-\fB\-noipv6\fR
-Disable all IPv6 sockets. Same as VNCVIEWER_NO_IPV6=1.
-.TP
-\fB\-noipv4\fR
-Disable all IPv4 sockets. Same as VNCVIEWER_NO_IPV4=1.
-.TP
-\fB\-printres\fR
-Print out the Ssvnc X resources (appdefaults) and
-then exit. You can save them to a file and customize them (e.g. the
-keybindings and Popup menu) Then point to the file via
-XENVIRONMENT or XAPPLRESDIR.
-.TP
-\fB\-pipeline\fR
-Like TurboVNC, request the next framebuffer update as soon
-as possible instead of waiting until the end of the current
-framebuffer update coming in. Helps 'pipeline' the updates.
-This is currently the default, use \fB-nopipeline\fR to disable.
-.TP
-\fB\-appshare\fR
-Enable features for use with x11vnc's \fB\-appshare\fR mode where
-instead of sharing the full desktop only the application's
-windows are shared. Viewer multilisten mode is used to
-create the multiple windows: \fB\-multilisten\fR is implied.
-See 'x11vnc \fB\-appshare\fR \fB\-help\fR' more information on the mode.
-Features enabled in the viewer under \fB\-appshare\fR are:
-Minimum extra text in the title, auto \fB\-ycrop\fR is disabled,
-x11vnc \fB\-remote_prefix\fR X11VNC_APPSHARE_CMD: message channel,
-x11vnc initial window position hints. See also Escape Keys
-below for additional key and mouse bindings.
-.TP
-\fB\-escape \fR\fIstr\fR
-This sets the 'Escape Keys' modifier sequence and enables
-escape keys mode. When the modifier keys escape sequence
-is held down, the next keystroke is interpreted locally
-to perform a special action instead of being sent to the
-remote VNC server.
-
-Use '\fB\-escape\fR default' for the default modifier sequence.
-(Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L)
-
-Here are the 'Escape Keys: Help+Set' instructions from the Popup:
-
-Escape Keys: Enter a comma separated list of modifier keys to be the 'escape
-sequence'. When these keys are held down, the next keystroke is
-interpreted locally to invoke a special action instead of being sent to
-the remote VNC server. In other words, a set of 'Hot Keys'.
-
-Here is the list of local key mappings to special actions:
-
-r: refresh desktop b: toggle bell c: toggle full-color
-
-f: file transfer x: x11cursor z: toggle Tight/ZRLE
-
-l: full screen g: graball e: escape keys dialog
-
-s: scale dialog +: scale up (=) -: scale down (_)
-
-t: text chat a: alphablend cursor
-
-V: toggle viewonly Q: quit viewer 123456: UltraVNC scale 1/n
-
-Arrow keys: pan the viewport about 10% for each keypress.
-
-PageUp/PageDown: pan the viewport by a screenful vertically.
-
-Home/End: pan the viewport by a screenful horizontally.
-
-KeyPad Arrows: pan the viewport by 1 pixel for each keypress.
-
-Dragging the Mouse with Button1 pressed also pans the viewport.
-
-Clicking Mouse Button3 brings up the Popup Menu.
-
-The above mappings are \fBalways\fR active in ViewOnly mode, unless you set
-the Escape Keys value to 'never'.
-
-x11vnc -appshare hot-keys: x11vnc has a simple application sharing mode
-that enables the viewer-side to move, resize, or raise the remote toplevel
-windows. To enable it, hold down Shift + the Escape Keys and press these:
-
-Arrow keys: move the remote window around in its desktop.
-
-PageUp/PageDn/Home/End: resize the remote window.
-
-+/-: raise or lower the remote window.
-
-M or Button1 move win to local position; D or Button3: delete remote win.
-
-If the Escape Keys value below is set to 'default' then a default list of
-of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it
-is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag
-on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side
-of the keyboard.
-
-On Unix the default is Alt and Windows keys on Left side of keyboard.
-On MacOSX the default is Control and Command keys on Left side of keyboard.
-
-Example: Press and hold the Alt and Windows keys on the LEFT side of the
-keyboard and then press 'c' to toggle the full-color state. Or press 't'
-to toggle the ultravnc Text Chat window, etc.
-
-To use something besides the default, supply a comma separated list (or a
-single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L
-Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.
-.TP
-\fB New Popup actions:\fR
-
- ViewOnly: ~ -viewonly
- Disable Bell: ~ -nobell
- Cursor Shape: ~ -nocursorshape
- X11 Cursor: ~ -x11cursor
- Cursor Alphablend: ~ -alpha
- Toggle Tight/Hextile: ~ -encodings hextile...
- Toggle Tight/ZRLE: ~ -encodings zrle...
- Toggle ZRLE/ZYWRLE: ~ -encodings zywrle...
- Quality Level ~ -quality (both Tight and ZYWRLE)
- Compress Level ~ -compresslevel
- Disable JPEG: ~ -nojpeg (Tight)
- Pipeline Updates ~ -pipeline
-
- Full Color as many colors as local screen allows.
- Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.
- 16 bit color (BGR565) ~ -16bpp / -bgr565
- 8 bit color (BGR233) ~ -bgr233
- 256 colors ~ -bgr233 default # of colors.
- 64 colors ~ -bgr222 / -use64
- 8 colors ~ -bgr111 / -use8
- Scale Viewer ~ -scale
- Escape Keys: Toggle ~ -escape
- Escape Keys: Help+Set ~ -escape
- Set Y Crop (y-max) ~ -ycrop
- Set Scrollbar Width ~ -sbwidth
- XGrabServer ~ -graball
-
- UltraVNC Extensions:
-
- Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.
- Text Chat Ultravnc ext. Do Text Chat.
- File Transfer Ultravnc ext. File xfer via Java helper.
- Single Window Ultravnc ext. Grab and view a single window.
- (select then click on the window you want).
- Disable Remote Input Ultravnc ext. Try to prevent input and
- viewing of monitor at physical display.
-
- Note: the Ultravnc extensions only apply to servers that support
- them. x11vnc/libvncserver supports some of them.
-
- Send Clipboard not Primary ~ -sendclipboard
- Send Selection Every time ~ -sendalways
-
-.SH ENCODINGS
-The server supplies information in whatever format is desired by the
-client, in order to make the client as easy as possible to implement.
-If the client represents itself as able to use multiple formats, the
-server will choose one.
-
-.I Pixel format
-refers to the representation of an individual pixel. The most common
-formats are 24 and 16 bit "true\-color" values, and 8\-bit "color map"
-representations, where an arbitrary map converts the color number to
-RGB values.
-
-.I Encoding
-refers to how a rectangle of pixels are sent (all pixel information in
-VNC is sent as rectangles). All rectangles come with a header giving
-the location and size of the rectangle and an encoding type used by
-the data which follows. These types are listed below.
-.TP
-.B Raw
-The raw encoding simply sends width*height pixel values. All clients
-are required to support this encoding type. Raw is also the fastest
-when the server and viewer are on the same machine, as the connection
-speed is essentially infinite and raw encoding minimizes processing
-time.
-.TP
-.B CopyRect
-The Copy Rectangle encoding is efficient when something is being
-moved; the only data sent is the location of a rectangle from which
-data should be copied to the current location. Copyrect could also be
-used to efficiently transmit a repeated pattern.
-.TP
-.B RRE
-The Rise\-and\-Run\-length\-Encoding is basically a 2D version of
-run\-length encoding (RLE). In this encoding, a sequence of identical
-pixels are compressed to a single value and repeat count. In VNC, this
-is implemented with a background color, and then specifications of an
-arbitrary number of subrectangles and color for each. This is an
-efficient encoding for large blocks of constant color.
-.TP
-.B CoRRE
-This is a minor variation on RRE, using a maximum of 255x255 pixel
-rectangles. This allows for single\-byte values to be used, reducing
-packet size. This is in general more efficient, because the savings
-from sending 1\-byte values generally outweighs the losses from the
-(relatively rare) cases where very large regions are painted the same
-color.
-.TP
-.B Hextile
-Here, rectangles are split up in to 16x16 tiles, which are sent in a
-predetermined order. The data within the tiles is sent either raw or
-as a variant on RRE. Hextile encoding is usually the best choice for
-using in high\-speed network environments (e.g. Ethernet local\-area
-networks).
-.TP
-.B Zlib
-Zlib is a very simple encoding that uses zlib library to compress raw
-pixel data. This encoding achieves good compression, but consumes a
-lot of CPU time. Support for this encoding is provided for
-compatibility with VNC servers that might not understand Tight
-encoding which is more efficient than Zlib in nearly all real\-life
-situations.
-.TP
-.B Tight
-Like Zlib encoding, Tight encoding uses zlib library to compress the
-pixel data, but it pre\-processes data to maximize compression ratios,
-and to minimize CPU usage on compression. Also, JPEG compression may
-be used to encode color\-rich screen areas (see the description of
-\-quality and \-nojpeg options above). Tight encoding is usually the
-best choice for low\-bandwidth network environments (e.g. slow modem
-connections).
-.TP
-.B ZRLE
-The SSVNC viewer has ported the RealVNC (www.realvnc.com) ZRLE encoding
-to the unix tightvnc viewer.
-.TP
-.B ZYWRLE
-The SSVNC viewer has ported the Hitachi lossy wavelet based ZRLE
-encoding from http://mobile.hitachi-system.co.jp/publications/ZYWRLE/
-to the unix tightvnc viewer.
-.SH RESOURCES
-X resources that \fBvncviewer\fR knows about, aside from the
-normal Xt resources, are as follows:
-.TP
-.B shareDesktop
-Equivalent of \fB\-shared\fR/\fB\-noshared\fR options. Default true.
-.TP
-.B viewOnly
-Equivalent of \fB\-viewonly\fR option. Default false.
-.TP
-.B fullScreen
-Equivalent of \fB\-fullscreen\fR option. Default false.
-.TP
-.B grabKeyboard
-Grab keyboard in full-screen mode. This can help to solve problems
-with losing keyboard focus. Default false.
-.TP
-.B raiseOnBeep
-Equivalent of \fB\-noraiseonbeep\fR option, when set to false. Default
-true.
-.TP
-.B passwordFile
-Equivalent of \fB\-passwd\fR option.
-.TP
-.B userLogin
-Equivalent of \fB\-user\fR option.
-.TP
-.B passwordDialog
-Whether to use a dialog box to get the password (true) or get it from
-the tty (false). Irrelevant if \fBpasswordFile\fR is set. Default
-false.
-.TP
-.B encodings
-Equivalent of \fB\-encodings\fR option.
-.TP
-.B compressLevel
-Equivalent of \fB\-compresslevel\fR option (TightVNC\-specific).
-.TP
-.B qualityLevel
-Equivalent of \fB\-quality\fR option (TightVNC\-specific).
-.TP
-.B enableJPEG
-Equivalent of \fB\-nojpeg\fR option, when set to false. Default true.
-.TP
-.B useRemoteCursor
-Equivalent of \fB\-nocursorshape\fR option, when set to false
-(TightVNC\-specific). Default true.
-.TP
-.B useBGR233
-Equivalent of \fB\-bgr233\fR option. Default false.
-.TP
-.B nColours
-When using BGR233, try to allocate this many "exact" colors from the
-BGR233 color cube. When using a shared colormap, setting this resource
-lower leaves more colors for other X clients. Irrelevant when using
-truecolor. Default is 256 (i.e. all of them).
-.TP
-.B useSharedColours
-If the number of "exact" BGR233 colors successfully allocated is less
-than 256 then the rest are filled in using the "nearest" colors
-available. This resource says whether to only use the "exact" BGR233
-colors for this purpose, or whether to use other clients' "shared"
-colors as well. Default true (i.e. use other clients' colors).
-.TP
-.B forceOwnCmap
-Equivalent of \fB\-owncmap\fR option. Default false.
-.TP
-.B forceTrueColour
-Equivalent of \fB\-truecolour\fR option. Default false.
-.TP
-.B requestedDepth
-Equivalent of \fB\-depth\fR option.
-.TP
-.B useSharedMemory
-Use MIT shared memory extension if on the same machine as the X
-server. Default true.
-.TP
-.B wmDecorationWidth, wmDecorationHeight
-The total width and height taken up by window manager decorations.
-This is used to calculate the maximum size of the VNC viewer window.
-Default is width 4, height 24.
-.TP
-.B bumpScrollTime, bumpScrollPixels
-When in full screen mode and the VNC desktop is bigger than the X
-display, scrolling happens whenever the mouse hits the edge of the
-screen. The maximum speed of scrolling is bumpScrollPixels pixels
-every bumpScrollTime milliseconds. The actual speed of scrolling will
-be slower than this, of course, depending on how fast your machine is.
-Default 20 pixels every 25 milliseconds.
-.TP
-.B popupButtonCount
-The number of buttons in the popup window. See the README file for
-more information on how to customize the buttons.
-.TP
-.B debug
-For debugging. Default false.
-.TP
-.B rawDelay, copyRectDelay
-For debugging, see the README file for details. Default 0 (off).
-.SH ENVIRONMENT
-When started with the \fB\-via\fR option, vncviewer reads the
-\fBVNC_VIA_CMD\fR environment variable, expands patterns beginning
-with the "%" character, and executes result as a command assuming that
-it would create TCP tunnel that should be used for VNC connection. If
-not set, this environment variable defaults to "/usr/bin/ssh -f -L
-%L:%H:%R %G sleep 20".
-
-The following patterns are recognized in the \fBVNC_VIA_CMD\fR (note
-that all the patterns %G, %H, %L and %R must be present in the command
-template):
-.TP
-.B %%
-A literal "%";
-.TP
-.B %G
-gateway host name;
-.TP
-.B %H
-remote VNC host name, as known to the gateway;
-.TP
-.B %L
-local TCP port number;
-.TP
-.B %R
-remote TCP port number.
-.SH SEE ALSO
-\fBvncserver\fR(1), \fBx11vnc\fR(1), \fBssvnc\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1),
-\fBvncconnect\fR(1), \fBssh\fR(1), http://www.karlrunge.com/x11vnc, http://www.karlrunge.com/x11vnc/ssvnc.html
-.SH AUTHORS
-Original VNC was developed in AT&T Laboratories Cambridge. TightVNC
-additions was implemented by Constantin Kaplinsky. Many other people
-participated in development, testing and support. Karl J. Runge
-added all of the SSVNC related features and improvements.
-
-\fBMan page authors:\fR
-.br
-Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de>,
-.br
-Terran Melconian <terran@consistent.org>,
-.br
-Tim Waugh <twaugh@redhat.com>,
-.br
-Constantin Kaplinsky <const@ce.cctpu.edu.ru>
-.br
-Karl J. Runge <runge@karlrunge.com>
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/README b/x11vnc/misc/enhanced_tightvnc_viewer/src/README
deleted file mode 100644
index 6630db9..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/src/README
+++ /dev/null
@@ -1,7 +0,0 @@
-
-In this directory we have source zip/tgz files in zip/, the patches
-we created in patches/, a temporary build dir (used by build.unix)
-in tmp/, and unpacked sources in vnc_unixsrc/ and stunnel-4.14/ (used
-by the build.unix script).
-
-See the README in the directory one level up for more information.
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/README b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/README
deleted file mode 100644
index 9451e7e..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/README
+++ /dev/null
@@ -1,6 +0,0 @@
-All of the patch files and scripts in this directory are
-
- Copyright (c) 2006 by Karl J. Runge <runge@karlrunge.com>
-
-and are licensed by the GPL. See the README and COPYING files two
-directories up for more information.
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle
deleted file mode 100755
index 60fc7c3..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/bin/sh
-
-rm -rf ./src/tmp/* || exit 1
-vers=1.0.28
-
-cd .. || exit 1
-
-cp -p ssvnc/bin/ssvnc_cmd ssvnc/bin/tightvncviewer
-
-###########################################
-dest=./t.unix_only
-rm -rf $dest
-mkdir -p $dest || exit 1
-
-tar cvf - ssvnc/{README,COPYING,ssvnc.desktop} ssvnc/bin ssvnc/Unix | (cd $dest; tar xvf -)
-rm -f $dest/ssvnc/bin/.linkin
-
-tar=ssvnc_unix_only-${vers}.tar.gz
-(cd $dest; tar czvf ../$tar ssvnc)
-ls -l $tar
-rm -rf $dest
-
-###########################################
-dest=./t.unix_minimal
-rm -rf $dest
-mkdir -p $dest || exit 1
-
-tar cvf - ssvnc/{README,COPYING,ssvnc.desktop} ssvnc/bin/{ss*,util/ss*} | (cd $dest; tar xvf -)
-
-tar=ssvnc_unix_minimal-${vers}.tar.gz
-(cd $dest; tar czvf ../$tar ssvnc)
-ls -l $tar
-rm -rf $dest
-
-top='#!/bin/sh
-n=11
-tmp=`mktemp -d "/tmp/ssvnc.XXXXXX"` || exit 1
-if [ "X$tmp" = "X" -o ! -d "$tmp" ]; then exit 1; fi
-trap "cd /tmp; rm -rf $tmp" 0 2 15
-
-tail +$n "$0" | (cd $tmp; tar xf -) || exit 1
-$tmp/bin/ssvnc "$@"
-exit 0
-data__() {'
-
-scr=./ssvnc.sh
-echo "$top" > $scr
-(cd ssvnc; tar cvf - README COPYING ssvnc.desktop bin/{ss*,util/ss*}) >> $scr
-chmod 755 $scr
-ls -l $scr
-
-if [ "X$1" = "Xquick" ]; then
- exit 0
-fi
-
-###########################################
-rm -f ssvnc_all-$vers.zip
-rm -f ssvnc-$vers.zip
-zip -9 -r ssvnc_all-$vers.zip ssvnc
-zip -9 -r ssvnc-$vers.zip ssvnc -x '*.zip' '*.tar.gz'
-tar cvf - --exclude='*.zip' --exclude='*.tar.gz' ssvnc | gzip -9 > ssvnc-$vers.tar.gz
-tar cvf - --exclude='*.zip' --exclude='*.tar.gz' --exclude='*.dll' --exclude='*.exe' --exclude ssvnc/Windows/util ssvnc | gzip -9 > ssvnc_no_windows-$vers.tar.gz
-
-echo
-ls -l ssvnc*-$vers.*
-echo
-
-
-###########################################
-dest=./t.windows_only
-rm -rf ${dest}
-mkdir -p $dest || exit 1
-
-cp -pR ssvnc $dest
-rm -rf $dest/ssvnc/{src,bin,man}
-rm -rf $dest/ssvnc/MacOSX
-rm -rf $dest/ssvnc/Unix
-rm -f $dest/ssvnc/build.unix
-rm -f $dest/ssvnc/filelist.txt
-cp -p ssvnc/bin/util/ssvnc.tcl $dest/ssvnc/Windows/util
-
-zip=ssvnc_windows_only-${vers}.zip
-rm -f $zip
-(cd $dest; zip -9 -r ../$zip ssvnc)
-
-ls -l $zip
-rm -rf $dest
-
-
-sync
-echo
-for g in ssvnc*-$vers*.gz
-do
- md5sum $g
- gzip -t $g || (tput bel; sleep 2)
-done
-for g in ssvnc*-$vers*.zip
-do
- md5sum $g
-done
-
-sleep 3
-echo
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches
deleted file mode 100755
index d12e1d1..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-if [ ! -f ./_getpatches ]; then
- ls -l ./_getpatches
- exit 1
-fi
-
-cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/tight-vncviewer*patch .
-cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/vnc_unixsrc_vncviewer.patched.tar ../zips/
-
-cp -p /dist/src/apps/VNC/etc/libvncserver_cvs/expts/java_ssl/ultra/ultraftp.tar ../zips/
-cp -p /dist/src/apps/VNC/etc/libvncserver_cvs/expts/vncstorepw.tar ../zips/
-
-cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/vnc_unixsrc/vncviewer/vncviewer.man ../../man/man1/ssvncviewer.1
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_vncpatchapplied b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_vncpatchapplied
deleted file mode 100755
index 0ff1931..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_vncpatchapplied
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-make clean
-rm -f *.o
-cd ../..
-tar -cvf ../../zips/vnc_unixsrc_vncviewer.patched.tar vnc_unixsrc/vncviewer
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.patch b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.patch
deleted file mode 100644
index 42657d8..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-diff -Naur stunnel.orig/src/client.c stunnel/src/client.c
---- stunnel.orig/src/client.c 2010-04-04 17:00:29.000000000 -0400
-+++ stunnel/src/client.c 2010-04-12 17:12:47.000000000 -0400
-@@ -187,6 +187,7 @@
- enter_critical_section(CRIT_CLIENTS); /* for multi-cpu machines */
- s_log(LOG_DEBUG, "Service %s finished (%d left)", c->opt->servname,
- --num_clients);
-+ if (getenv("STUNNEL_ONCE")) {fprintf(stderr, "stunnel: exiting.\n"); exit(0);}
- leave_critical_section(CRIT_CLIENTS);
- #endif
- }
-diff -Naur stunnel.orig/src/network.c stunnel/src/network.c
---- stunnel.orig/src/network.c 2010-02-04 05:31:45.000000000 -0500
-+++ stunnel/src/network.c 2010-04-12 17:13:53.000000000 -0400
-@@ -437,6 +437,7 @@
- if((pid=wait(&status))>0) {
- --num_clients; /* one client less */
- #endif
-+ if (getenv("STUNNEL_ONCE")) exit(0);
- #ifdef WIFSIGNALED
- if(WIFSIGNALED(status)) {
- s_log(LOG_DEBUG, "Process %d terminated on signal %d (%d left)",
-diff -Naur stunnel.orig/src/options.c stunnel/src/options.c
---- stunnel.orig/src/options.c 2010-04-05 14:44:43.000000000 -0400
-+++ stunnel/src/options.c 2010-04-12 17:19:18.000000000 -0400
-@@ -470,6 +470,7 @@
- switch(cmd) {
- case CMD_INIT:
- new_global_options.option.syslog=1;
-+ if (getenv("STUNNEL_NO_SYSLOG")) new_global_options.option.syslog=0;
- break;
- case CMD_EXEC:
- if(strcasecmp(opt, "syslog"))
-diff -Naur stunnel.orig/src/stunnel.c stunnel/src/stunnel.c
---- stunnel.orig/src/stunnel.c 2010-02-25 04:57:11.000000000 -0500
-+++ stunnel/src/stunnel.c 2010-04-12 17:16:33.000000000 -0400
-@@ -306,6 +306,7 @@
- max_clients=0;
- s_log(LOG_NOTICE, "No limit detected for the number of clients");
- }
-+ if (getenv("STUNNEL_MAX_CLIENTS")) max_clients = atoi(getenv("STUNNEL_MAX_CLIENTS"));
- }
-
- #ifdef HAVE_CHROOT
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch
deleted file mode 100644
index e37dd31..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch
+++ /dev/null
@@ -1,24370 +0,0 @@
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/Vncviewer vnc_unixsrc/vncviewer/Vncviewer
---- vnc_unixsrc.orig/vncviewer/Vncviewer 2003-02-07 05:30:57.000000000 -0500
-+++ vnc_unixsrc/vncviewer/Vncviewer 2008-08-24 16:26:01.000000000 -0400
-@@ -1,20 +1,22 @@
- !
--! Application defaults file for vncviewer.
-+! Application defaults file for SSVNC vncviewer.
-+!
-+! N.B.: You will need to rename this file to be "Ssvnc" instead of "Vncviewer"
- !
-
-
- !
- ! The title of the main window. "%s" will be replaced by the desktop name.
--!
-+!
-
--Vncviewer.title: TightVNC: %s
-+Ssvnc.title: SSVNC: %s Press F8 for Menu
-
-
- !
- ! Translations on the main window.
- !
-
--Vncviewer.translations:\
-+Ssvnc.translations:\
- <Enter>: SelectionToVNC()\n\
- <Leave>: SelectionFromVNC()
-
-@@ -23,7 +25,7 @@
- ! Uncomment to grab the keyboard in full-screen mode.
- !
-
--! Vncviewer.grabKeyboard: True
-+! Ssvnc.grabKeyboard: True
-
-
- !
-@@ -43,6 +45,9 @@
- *viewport.useRight: True
- *viewport*Scrollbar*thumb: None
-
-+*viewport.horizontal.height: 6
-+*viewport.vertical.width: 6
-+
-
- !
- ! Default translations on desktop window.
-@@ -50,89 +55,591 @@
-
- *desktop.baseTranslations:\
- <Key>F8: ShowPopup()\n\
-+ <Key>F9: ToggleFullScreen()\n\
- <ButtonPress>: SendRFBEvent()\n\
- <ButtonRelease>: SendRFBEvent()\n\
- <Motion>: SendRFBEvent()\n\
- <KeyPress>: SendRFBEvent()\n\
- <KeyRelease>: SendRFBEvent()
-
-+*viewport.horizontal.translations: #override\n\
-+ <KeyPress>Right: StartScroll(Forward)\n\
-+ <KeyRelease>Right: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>Left: StartScroll(Backward)\n\
-+ <KeyRelease>Left: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>Next: StartScroll(Forward)\n\
-+ <KeyRelease>Next: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>Prior: StartScroll(Backward)\n\
-+ <KeyRelease>Prior: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>z: StartScroll(Forward)\n\
-+ <KeyRelease>z: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>a: StartScroll(Backward)\n\
-+ <KeyRelease>a: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>f: StartScroll(Forward)\n\
-+ <KeyRelease>f: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>b: StartScroll(Backward)\n\
-+ <KeyRelease>b: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>Down: StartScroll(Forward)\n\
-+ <KeyRelease>Down: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>Up: StartScroll(Backward)\n\
-+ <KeyRelease>Up: NotifyScroll(FullLength) EndScroll()
-+
-+*viewport.vertical.translations: #override\n\
-+ <KeyPress>Down: StartScroll(Forward)\n\
-+ <KeyRelease>Down: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>Up: StartScroll(Backward)\n\
-+ <KeyRelease>Up: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>Next: StartScroll(Forward)\n\
-+ <KeyRelease>Next: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>Prior: StartScroll(Backward)\n\
-+ <KeyRelease>Prior: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>z: StartScroll(Forward)\n\
-+ <KeyRelease>z: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>a: StartScroll(Backward)\n\
-+ <KeyRelease>a: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>f: StartScroll(Forward)\n\
-+ <KeyRelease>f: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>b: StartScroll(Backward)\n\
-+ <KeyRelease>b: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>Right: StartScroll(Forward)\n\
-+ <KeyRelease>Right: NotifyScroll(FullLength) EndScroll()\n\
-+ <KeyPress>Left: StartScroll(Backward)\n\
-+ <KeyRelease>Left: NotifyScroll(FullLength) EndScroll()
-+
-
- !
- ! Dialog boxes
- !
-
- *serverDialog.dialog.label: VNC server:
-+
- *serverDialog.dialog.value:
-+
- *serverDialog.dialog.value.translations: #override\n\
-- <Key>Return: ServerDialogDone()
-+ <Key>Return: ServerDialogDone()
-+
-+*ycropDialog.dialog.label: Y Crop (max-height in pixels):
-+
-+*ycropDialog.dialog.value:
-+
-+*ycropDialog.dialog.value.translations: #override\n\
-+ <Key>Return: YCropDialogDone()
-+
-+*scbarDialog.dialog.label: Scroll Bars width:
-+
-+*scbarDialog.dialog.value:
-+
-+*scbarDialog.dialog.value.translations: #override\n\
-+ <Key>Return: ScbarDialogDone()
-+
-+*scaleDialog.dialog.label: Integer n for 1/n server scaling:
-+
-+*scaleDialog.dialog.value:
-+
-+*scaleDialog.dialog.value.translations: #override\n\
-+ <Key>Return: ScaleDialogDone()
-
- *passwordDialog.dialog.label: Password:
-+
- *passwordDialog.dialog.value:
-+
- *passwordDialog.dialog.value.AsciiSink.echo: False
-+
- *passwordDialog.dialog.value.translations: #override\n\
-- <Key>Return: PasswordDialogDone()
-+ <Key>Return: PasswordDialogDone()
-
-
- !
- ! Popup window appearance
- !
-
--*popup.title: TightVNC popup
-+*popup.title: SSVNC popup
-+
- *popup*background: grey
--*popup*font: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-*
--*popup.buttonForm.Command.borderWidth: 0
--*popup.buttonForm.Toggle.borderWidth: 0
-+
-+*popup*font_old: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-*
-+
-+*popup*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*
-+
-+*popup.buttonForm*.Command.borderWidth: 0
-+
-+*popup.buttonForm*.Toggle.borderWidth: 0
-+
-+*scaleN.title: 1/n scale
-+
-+*scaleN*background: grey
-+
-+*scaleN*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*
-+
-+*scaleN.buttonForm.Command.borderWidth: 0
-+
-+*scaleN.buttonForm.Toggle.borderWidth: 0
-+
-+*quality.title: quality
-+
-+*quality*background: grey
-+
-+*quality*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*
-+
-+*quality.buttonForm.Command.borderWidth: 0
-+
-+*quality.buttonForm.Toggle.borderWidth: 0
-+
-+*compress.title: compress
-+
-+*compress*background: grey
-+
-+*compress*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*
-+
-+*compress.buttonForm.Command.borderWidth: 0
-+
-+*compress.buttonForm.Toggle.borderWidth: 0
-+
-
- !
- ! Translations on popup window - send key presses through
- !
-
- *popup.translations: #override <Message>WM_PROTOCOLS: HidePopup()
-+
- *popup.buttonForm.translations: #override\n\
-- <KeyPress>: SendRFBEvent() HidePopup()
-+ <KeyPress>: SendRFBEvent() HidePopup()
-
-
- !
- ! Popup buttons
- !
-
--*popupButtonCount: 8
-+*popupButtonCount: 38
-+
-+*popupButtonBreak: 19
-
- *popup*button1.label: Dismiss popup
-+
- *popup*button1.translations: #override\n\
-- <Btn1Down>,<Btn1Up>: HidePopup()
-+ <Btn1Down>,<Btn1Up>: HidePopup()
-
- *popup*button2.label: Quit viewer
-+
- *popup*button2.translations: #override\n\
-- <Btn1Down>,<Btn1Up>: Quit()
-+ <Btn1Down>,<Btn1Up>: Quit()
-+
-+*popup*button3.label: Full screen (also F9)
-
--*popup*button3.label: Full screen
- *popup*button3.type: toggle
-+
- *popup*button3.translations: #override\n\
-- <Visible>: SetFullScreenState()\n\
-- <Btn1Down>,<Btn1Up>: toggle() HidePopup() ToggleFullScreen()
-+ <Visible>: SetFullScreenState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleFullScreen() HidePopup()
-
- *popup*button4.label: Clipboard: local -> remote
-+
- *popup*button4.translations: #override\n\
-- <Btn1Down>,<Btn1Up>: SelectionToVNC(always) HidePopup()
-+ <Btn1Down>,<Btn1Up>: SelectionToVNC(always) HidePopup()
-
- *popup*button5.label: Clipboard: local <- remote
-+
- *popup*button5.translations: #override\n\
-- <Btn1Down>,<Btn1Up>: SelectionFromVNC(always) HidePopup()
-+ <Btn1Down>,<Btn1Up>: SelectionFromVNC(always) HidePopup()
-
- *popup*button6.label: Request refresh
-+
- *popup*button6.translations: #override\n\
-- <Btn1Down>,<Btn1Up>: SendRFBEvent(fbupdate) HidePopup()
-+ <Btn1Down>,<Btn1Up>: SendRFBEvent(fbupdate) HidePopup()
-
- *popup*button7.label: Send ctrl-alt-del
-+
- *popup*button7.translations: #override\n\
-- <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L)\
-- SendRFBEvent(keydown,Alt_L)\
-- SendRFBEvent(key,Delete)\
-- SendRFBEvent(keyup,Alt_L)\
-- SendRFBEvent(keyup,Control_L)\
-- HidePopup()
-+ <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L) SendRFBEvent(keydown,Alt_L) SendRFBEvent(key,Delete) SendRFBEvent(keyup,Alt_L) SendRFBEvent(keyup,Control_L) HidePopup()
-
- *popup*button8.label: Send F8
-+
- *popup*button8.translations: #override\n\
-- <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup()
-+ <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup()
-+
-+*popup*button9.label: Send F9
-+
-+*popup*button9.translations: #override\n\
-+ <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F9) HidePopup()
-+
-+*popup*button10.label: ViewOnly
-+
-+*popup*button10.type: toggle
-+
-+*popup*button10.translations: #override\n\
-+ <Visible>: SetViewOnlyState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleViewOnly() HidePopup()
-+
-+*popup*button11.label: Disable Bell
-+
-+*popup*button11.type: toggle
-+
-+*popup*button11.translations: #override\n\
-+ <Visible>: SetBellState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleBell() HidePopup()
-+
-+*popup*button12.label: Cursor Shape
-+
-+*popup*button12.type: toggle
-+
-+*popup*button12.translations: #override\n\
-+ <Visible>: SetCursorShapeState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorShape() HidePopup()
-+
-+*popup*button13.label: X11 Cursor
-+
-+*popup*button13.type: toggle
-+
-+*popup*button13.translations: #override\n\
-+ <Visible>: SetX11CursorState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleX11Cursor() HidePopup()
-+
-+*popup*button14.label: Cursor Alphablend
-+
-+*popup*button14.type: toggle
-+
-+*popup*button14.translations: #override\n\
-+ <Visible>: SetCursorAlphaState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorAlpha() HidePopup()
-+
-+*popup*button15.label: Toggle Tight/ZRLE
-+
-+*popup*button15.type: toggle
-+
-+*popup*button15.translations: #override\n\
-+ <Visible>: SetZRLEState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleTightZRLE() HidePopup()
-+
-+*popup*button16.label: Toggle ZRLE/ZYWRLE
-+
-+*popup*button16.type: toggle
-+
-+*popup*button16.translations: #override\n\
-+ <Visible>: SetZYWRLEState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleZRLEZYWRLE() HidePopup()
-+
-+*popup*button17.label: Quality Level
-+
-+*popup*button17.translations: #override\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() ShowQuality()
-+
-+*popup*button18.label: Compress Level
-+
-+*popup*button18.translations: #override\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() ShowCompress()
-+
-+*popup*button19.label: Disable JPEG
-+
-+*popup*button19.type: toggle
-+
-+*popup*button19.translations: #override\n\
-+ <Visible>: SetNOJPEGState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleJPEG() HidePopup()
-+
-+*popup*button20.label: Full Color
-+
-+*popup*button20.type: toggle
-+
-+*popup*button20.translations: #override\n\
-+ <Visible>: SetFullColorState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleFullColor() HidePopup()
-+
-+*popup*button21.label: Grey Scale (16 & 8-bpp)
-+
-+*popup*button21.type: toggle
-+
-+*popup*button21.translations: #override\n\
-+ <Visible>: SetGreyScaleState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleGreyScale() HidePopup()
-+
-+*popup*button22.label: 16 bit color (BGR565)
-+
-+*popup*button22.type: toggle
-+
-+*popup*button22.translations: #override\n\
-+ <Visible>: Set16bppState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() Toggle16bpp() HidePopup()
-+
-+*popup*button23.label: 8 bit color (BGR233)
-+
-+*popup*button23.type: toggle
-+
-+*popup*button23.translations: #override\n\
-+ <Visible>: Set8bppState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() Toggle8bpp() HidePopup()
-+
-+*popup*button24.label: - 256 colors
-+
-+*popup*button24.type: toggle
-+
-+*popup*button24.translations: #override\n\
-+ <Visible>: Set256ColorsState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() Toggle256Colors() HidePopup()
-+
-+*popup*button25.label: - 64 colors
-+
-+*popup*button25.type: toggle
-+
-+*popup*button25.translations: #override\n\
-+ <Visible>: Set64ColorsState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() Toggle64Colors() HidePopup()
-+
-+*popup*button26.label: - 8 colors
-+
-+*popup*button26.type: toggle
-+
-+*popup*button26.translations: #override\n\
-+ <Visible>: Set8ColorsState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() Toggle8Colors() HidePopup()
-+
-+*popup*button27.label: Set Y Crop (y-max)
-+
-+*popup*button27.translations: #override\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() SetYCrop()
-+
-+*popup*button28.label: Set Scrollbar Width
-+
-+*popup*button28.translations: #override\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() SetScbar()
-+
-+*popup*button29.label: UltraVNC Extensions:
-+
-+*popup*button29.translations: #override\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup()
-+
-+*popup*button30.label: - Set 1/n Server Scale
-+
-+*popup*button30.translations: #override\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() ShowScaleN()
-+
-+*popup*button31.label: - Text Chat
-+
-+*popup*button31.type: toggle
-+
-+*popup*button31.translations: #override\n\
-+ <Visible>: SetTextChatState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleTextChat() HidePopup()
-+
-+*popup*button32.label: - File Transfer
-+
-+*popup*button32.type: toggle
-+
-+*popup*button32.translations: #override\n\
-+ <Visible>: SetFileXferState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleFileXfer() HidePopup()
-+
-+*popup*button33.label: - Single Window
-+
-+*popup*button33.type: toggle
-+
-+*popup*button33.translations: #override\n\
-+ <Visible>: SetSingleWindowState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleSingleWindow() HidePopup()
-+
-+*popup*button34.label: - Disable Remote Input
-+
-+*popup*button34.type: toggle
-+
-+*popup*button34.translations: #override\n\
-+ <Visible>: SetServerInputState()\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleServerInput() HidePopup()
-+
-+*popup*button35.label:
-+
-+*popup*button36.label:
-+
-+*popup*button37.label:
-+
-+*popup*button38.label:
-+
-+*scaleN*button0.label: Dismiss
-+
-+*scaleN*button0.translations: #override\n\
-+ <Btn1Down>,<Btn1Up>: HideScaleN()
-+
-+*scaleN*button1.label: 1/1
-+
-+*scaleN*button1.translations: #override\n\
-+ <Visible>: SetScaleNState(1)\n\
-+ <Btn1Down>,<Btn1Up>: SetScaleN(1) HideScaleN()
-+
-+*scaleN*button2.label: 1/2
-+
-+*scaleN*button2.translations: #override\n\
-+ <Visible>: SetScaleNState(2)\n\
-+ <Btn1Down>,<Btn1Up>: SetScaleN(2) HideScaleN()
-+
-+*scaleN*button3.label: 1/3
-+
-+*scaleN*button3.translations: #override\n\
-+ <Visible>: SetScaleNState(3)\n\
-+ <Btn1Down>,<Btn1Up>: SetScaleN(3) HideScaleN()
-+
-+*scaleN*button4.label: 1/4
-+
-+*scaleN*button4.translations: #override\n\
-+ <Visible>: SetScaleNState(4)\n\
-+ <Btn1Down>,<Btn1Up>: SetScaleN(4) HideScaleN()
-+
-+*scaleN*button5.label: 1/5
-+
-+*scaleN*button5.translations: #override\n\
-+ <Visible>: SetScaleNState(5)\n\
-+ <Btn1Down>,<Btn1Up>: SetScaleN(5) HideScaleN()
-+
-+*scaleN*button6.label: Other
-+
-+*scaleN*button6.translations: #override\n\
-+ <Visible>: SetScaleNState(6)\n\
-+ <Btn1Down>,<Btn1Up>: HideScaleN() DoServerScale()
-+
-+*quality*buttonD.label: Dismiss
-+
-+*quality*buttonD.translations: #override\n\
-+ <Btn1Down>,<Btn1Up>: HideQuality()
-+
-+*quality*button0.label: 0
-+
-+*quality*button0.type: toggle
-+
-+*quality*button0.translations: #override\n\
-+ <Visible>: SetQualityState(0)\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(0) HideQuality()
-+
-+*quality*button1.label: 1
-+
-+*quality*button1.type: toggle
-+
-+*quality*button1.translations: #override\n\
-+ <Visible>: SetQualityState(1)\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(1) HideQuality()
-+
-+*quality*button2.label: 2
-+
-+*quality*button2.type: toggle
-+
-+*quality*button2.translations: #override\n\
-+ <Visible>: SetQualityState(2)\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(2) HideQuality()
-+
-+*quality*button3.label: 3
-+
-+*quality*button3.type: toggle
-+
-+*quality*button3.translations: #override\n\
-+ <Visible>: SetQualityState(3)\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(3) HideQuality()
-+
-+*quality*button4.label: 4
-+
-+*quality*button4.type: toggle
-+
-+*quality*button4.translations: #override\n\
-+ <Visible>: SetQualityState(4)\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(4) HideQuality()
-+
-+*quality*button5.label: 5
-+
-+*quality*button5.type: toggle
-+
-+*quality*button5.translations: #override\n\
-+ <Visible>: SetQualityState(5)\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(5) HideQuality()
-+
-+*quality*button6.label: 6
-+
-+*quality*button6.type: toggle
-+
-+*quality*button6.translations: #override\n\
-+ <Visible>: SetQualityState(6)\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(6) HideQuality()
-+
-+*quality*button7.label: 7
-+
-+*quality*button7.type: toggle
-+
-+*quality*button7.translations: #override\n\
-+ <Visible>: SetQualityState(7)\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(7) HideQuality()
-+
-+*quality*button8.label: 8
-+
-+*quality*button8.type: toggle
-+
-+*quality*button8.translations: #override\n\
-+ <Visible>: SetQualityState(8)\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(8) HideQuality()
-+
-+*quality*button9.label: 9
-+
-+*quality*button9.type: toggle
-+
-+*quality*button9.translations: #override\n\
-+ <Visible>: SetQualityState(9)\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(9) HideQuality()
-+
-+*compress*buttonD.label: Dismiss
-+
-+*compress*buttonD.translations: #override\n\
-+ <Btn1Down>,<Btn1Up>: HideCompress()
-+
-+*compress*button0.label: 0
-+
-+*compress*button0.translations: #override\n\
-+ <Visible>: SetCompressState(0)\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(0) HideCompress()
-+
-+*compress*button1.label: 1
-+
-+*compress*button1.translations: #override\n\
-+ <Visible>: SetCompressState(1)\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(1) HideCompress()
-+
-+*compress*button2.label: 2
-+
-+*compress*button2.translations: #override\n\
-+ <Visible>: SetCompressState(2)\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(2) HideCompress()
-+
-+*compress*button3.label: 3
-+
-+*compress*button3.translations: #override\n\
-+ <Visible>: SetCompressState(3)\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(3) HideCompress()
-+
-+*compress*button4.label: 4
-+
-+*compress*button4.translations: #override\n\
-+ <Visible>: SetCompressState(4)\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(4) HideCompress()
-+
-+*compress*button5.label: 5
-+
-+*compress*button5.translations: #override\n\
-+ <Visible>: SetCompressState(5)\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(5) HideCompress()
-+
-+*compress*button6.label: 6
-+
-+*compress*button6.translations: #override\n\
-+ <Visible>: SetCompressState(6)\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(6) HideCompress()
-+
-+*compress*button7.label: 7
-+
-+*compress*button7.translations: #override\n\
-+ <Visible>: SetCompressState(7)\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(7) HideCompress()
-+
-+*compress*button8.label: 8
-+
-+*compress*button8.translations: #override\n\
-+ <Visible>: SetCompressState(8)\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(8) HideCompress()
-+
-+*compress*button9.label: 9
-+
-+*compress*button9.translations: #override\n\
-+ <Visible>: SetCompressState(9)\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(9) HideCompress()
-+
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/vncviewer/argsresources.c
---- vnc_unixsrc.orig/vncviewer/argsresources.c 2007-02-04 17:10:31.000000000 -0500
-+++ vnc_unixsrc/vncviewer/argsresources.c 2010-04-18 12:39:55.000000000 -0400
-@@ -31,9 +31,9 @@
-
- char *fallback_resources[] = {
-
-- "Vncviewer.title: TightVNC: %s",
-+ "Ssvnc.title: SSVNC: %s - Press F8 for Menu",
-
-- "Vncviewer.translations:\
-+ "Ssvnc.translations:\
- <Enter>: SelectionToVNC()\\n\
- <Leave>: SelectionFromVNC()",
-
-@@ -45,8 +45,60 @@
- "*viewport.useRight: True",
- "*viewport*Scrollbar*thumb: None",
-
-+ "*viewport.horizontal.height: 6 ",
-+ "*viewport.vertical.width: 6 ",
-+ "ssvnc*viewport.horizontal.height: 6 ",
-+ "ssvnc*viewport.vertical.width: 6 ",
-+
-+ "*viewport.horizontal.translations: #override\\n\
-+ <KeyPress>Right: StartScroll(Forward)\\n\
-+ <KeyRelease>Right: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>Left: StartScroll(Backward)\\n\
-+ <KeyRelease>Left: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>Next: StartScroll(Forward)\\n\
-+ <KeyRelease>Next: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>Prior: StartScroll(Backward)\\n\
-+ <KeyRelease>Prior: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>z: StartScroll(Forward)\\n\
-+ <KeyRelease>z: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>a: StartScroll(Backward)\\n\
-+ <KeyRelease>a: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>f: StartScroll(Forward)\\n\
-+ <KeyRelease>f: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>b: StartScroll(Backward)\\n\
-+ <KeyRelease>b: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>Down: StartScroll(Forward)\\n\
-+ <KeyRelease>Down: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>Up: StartScroll(Backward)\\n\
-+ <KeyRelease>Up: NotifyScroll(FullLength) EndScroll()",
-+
-+ "*viewport.vertical.translations: #override\\n\
-+ <KeyPress>Down: StartScroll(Forward)\\n\
-+ <KeyRelease>Down: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>Up: StartScroll(Backward)\\n\
-+ <KeyRelease>Up: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>Next: StartScroll(Forward)\\n\
-+ <KeyRelease>Next: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>Prior: StartScroll(Backward)\\n\
-+ <KeyRelease>Prior: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>z: StartScroll(Forward)\\n\
-+ <KeyRelease>z: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>a: StartScroll(Backward)\\n\
-+ <KeyRelease>a: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>f: StartScroll(Forward)\\n\
-+ <KeyRelease>f: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>b: StartScroll(Backward)\\n\
-+ <KeyRelease>b: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>Right: StartScroll(Forward)\\n\
-+ <KeyRelease>Right: NotifyScroll(FullLength) EndScroll()\\n\
-+ <KeyPress>Left: StartScroll(Backward)\\n\
-+ <KeyRelease>Left: NotifyScroll(FullLength) EndScroll()",
-+
- "*desktop.baseTranslations:\
-- <Key>F8: ShowPopup()\\n\
-+ <KeyPress>F8: ShowPopup()\\n\
-+ <KeyRelease>F8: Noop()\\n\
-+ <KeyPress>F9: ToggleFullScreen()\\n\
-+ <KeyRelease>F9: Noop()\\n\
- <ButtonPress>: SendRFBEvent()\\n\
- <ButtonRelease>: SendRFBEvent()\\n\
- <Motion>: SendRFBEvent()\\n\
-@@ -55,26 +107,137 @@
-
- "*serverDialog.dialog.label: VNC server:",
- "*serverDialog.dialog.value:",
-+ "*serverDialog.dialog.value.width: 150",
- "*serverDialog.dialog.value.translations: #override\\n\
- <Key>Return: ServerDialogDone()",
-
-- "*passwordDialog.dialog.label: Password:",
-+ "*userDialog.dialog.label: SSVNC: Enter Username",
-+ "*userDialog.dialog.value:",
-+ "*userDialog.dialog.value.width: 150",
-+ "*userDialog.dialog.value.translations: #override\\n\
-+ <Key>Return: UserDialogDone()",
-+
-+ "*scaleDialog.dialog.label: Scale: Enter 'none' (same as '1' or '1.0'),\\na geometry WxH (e.g. 1280x1024), or\\na fraction (e.g. 0.75 or 3/4).\\nUse 'fit' for full screen size.\\nUse 'auto' to match window size.\\nCurrent value:",
-+ "*scaleDialog.dialog.value:",
-+ "*scaleDialog.dialog.value.translations: #override\\n\
-+ <KeyRelease>Return: ScaleDialogDone()",
-+
-+ "*escapeDialog.dialog.label: Escape Keys: Enter a comma separated list of modifier keys to be the\\n"
-+ "'escape sequence'. When these keys are held down, the next keystroke is\\n"
-+ "interpreted locally to invoke a special action instead of being sent to\\n"
-+ "the remote VNC server. In other words, a set of 'Hot Keys'.\\n"
-+ "\\n"
-+ "To enable or disable this, click on 'Escape Keys: Toggle' in the Popup.\\n"
-+ "\\n"
-+ "Here is the list of hot-key mappings to special actions:\\n"
-+ "\\n"
-+ " r: refresh desktop b: toggle bell c: toggle full-color\\n"
-+ " f: file transfer x: x11cursor z: toggle Tight/ZRLE\\n"
-+ " l: full screen g: graball e: escape keys dialog\\n"
-+ " s: scale dialog +: scale up (=) -: scale down (_)\\n"
-+ " t: text chat a: alphablend cursor\\n"
-+ " V: toggle viewonly Q: quit viewer 1 2 3 4 5 6: UltraVNC scale 1/n\\n"
-+ "\\n"
-+ " Arrow keys: pan the viewport about 10% for each keypress.\\n"
-+ " PageUp / PageDown: pan the viewport by a screenful vertically.\\n"
-+ " Home / End: pan the viewport by a screenful horizontally.\\n"
-+ " KeyPad Arrow keys: pan the viewport by 1 pixel for each keypress.\\n"
-+ " Dragging the Mouse with Button1 pressed also pans the viewport.\\n"
-+ " Clicking Mouse Button3 brings up the Popup Menu.\\n"
-+ "\\n"
-+ "The above mappings are *always* active in ViewOnly mode, unless you set the\\n"
-+ "Escape Keys value to 'never'.\\n"
-+ "\\n"
-+ "x11vnc -appshare hot-keys: x11vnc has a simple application sharing mode\\n"
-+ "that enables the viewer-side to move, resize, or raise the remote toplevel\\n"
-+ "windows. To enable it, hold down Shift + the Escape Keys and press these:\\n"
-+ "\\n"
-+ " Arrow keys: move the remote window around in its desktop.\\n"
-+ " PageUp/PageDn/Home/End: resize the remote window.\\n"
-+ " +/- raise or lower the remote window.\\n"
-+ " M or Button1 move win to local position; D or Button3: delete remote win.\\n"
-+ "\\n"
-+ "If the Escape Keys value below is set to 'default' then a fixed list of\\n"
-+ "modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it is\\n"
-+ "Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag.\\n"
-+ "Also note the _L and _R mean the key is on the LEFT or RIGHT side of keyboard.\\n"
-+ "\\n"
-+ "On Unix the default is Alt and Windows keys on Left side of keyboard.\\n"
-+ "On MacOSX the default is Control and Command keys on Left side of keyboard.\\n"
-+ "\\n"
-+ "Example: Press and hold the Alt and Windows keys on the LEFT side of the\\n"
-+ "keyboard and then press 'c' to toggle the full-color state. Or press 't'\\n"
-+ "to toggle the ultravnc Text Chat window, etc.\\n"
-+ "\\n"
-+ "To use something besides the default, supply a comma separated list (or a\\n"
-+ "single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L\\n"
-+ "Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.\\n"
-+ "\\n"
-+ "Current Escape Keys Value:",
-+ "*escapeDialog.dialog.value:",
-+ "*escapeDialog.dialog.value.width: 280",
-+ "*escapeDialog.dialog.value.translations: #override\\n\
-+ <KeyRelease>Return: EscapeDialogDone()",
-+
-+ "*ycropDialog.dialog.label: Y Crop (max-height in pixels):",
-+ "*ycropDialog.dialog.value:",
-+ "*ycropDialog.dialog.value.translations: #override\\n\
-+ <KeyRelease>Return: YCropDialogDone()",
-+
-+ "*scbarDialog.dialog.label: Scroll Bars width:",
-+ "*scbarDialog.dialog.value:",
-+ "*scbarDialog.dialog.value.translations: #override\\n\
-+ <KeyRelease>Return: ScbarDialogDone()",
-+
-+ "*scaleNDialog.dialog.label: Integer n for 1/n server scaling:",
-+ "*scaleNDialog.dialog.value:",
-+ "*scaleNDialog.dialog.value.translations: #override\\n\
-+ <KeyRelease>Return: ScaleNDialogDone()",
-+
-+ "*passwordDialog.dialog.label: SSVNC: Enter Password",
- "*passwordDialog.dialog.value:",
-+ "*passwordDialog.dialog.value.width: 150",
- "*passwordDialog.dialog.value.AsciiSink.echo: False",
- "*passwordDialog.dialog.value.translations: #override\\n\
- <Key>Return: PasswordDialogDone()",
-
-- "*popup.title: TightVNC popup",
-+ "*popup.title: SSVNC popup",
- "*popup*background: grey",
-- "*popup*font: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-*",
-- "*popup.buttonForm.Command.borderWidth: 0",
-- "*popup.buttonForm.Toggle.borderWidth: 0",
-+ "*popup*font_old: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-*",
-+ "*popup*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*",
-+ "*popup.buttonForm*.Command.borderWidth: 0",
-+ "*popup.buttonForm*.Toggle.borderWidth: 0",
-+
-+ "*scaleN.title: 1/n scale",
-+ "*scaleN*background: grey",
-+ "*scaleN*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*",
-+ "*scaleN.buttonForm.Command.borderWidth: 0",
-+ "*scaleN.buttonForm.Toggle.borderWidth: 0",
-+
-+ "*turboVNC.title: TurboVNC",
-+ "*turboVNC*background: grey",
-+ "*turboVNC*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*",
-+ "*turboVNC.buttonForm.Command.borderWidth: 0",
-+ "*turboVNC.buttonForm.Toggle.borderWidth: 0",
-+
-+ "*quality.title: quality",
-+ "*quality*background: grey",
-+ "*quality*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*",
-+ "*quality.buttonForm.Command.borderWidth: 0",
-+ "*quality.buttonForm.Toggle.borderWidth: 0",
-+
-+ "*compress.title: compress",
-+ "*compress*background: grey",
-+ "*compress*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*",
-+ "*compress.buttonForm.Command.borderWidth: 0",
-+ "*compress.buttonForm.Toggle.borderWidth: 0",
-
- "*popup.translations: #override <Message>WM_PROTOCOLS: HidePopup()",
- "*popup.buttonForm.translations: #override\\n\
- <KeyPress>: SendRFBEvent() HidePopup()",
-
-- "*popupButtonCount: 8",
-+ "*popupButtonCount: 44",
-+ "*popupButtonBreak: 22",
-
- "*popup*button1.label: Dismiss popup",
- "*popup*button1.translations: #override\\n\
-@@ -84,7 +247,7 @@
- "*popup*button2.translations: #override\\n\
- <Btn1Down>,<Btn1Up>: Quit()",
-
-- "*popup*button3.label: Full screen",
-+ "*popup*button3.label: Full screen (also F9)",
- "*popup*button3.type: toggle",
- "*popup*button3.translations: #override\\n\
- <Visible>: SetFullScreenState()\\n\
-@@ -105,16 +268,426 @@
- "*popup*button7.label: Send ctrl-alt-del",
- "*popup*button7.translations: #override\\n\
- <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L)\
-- SendRFBEvent(keydown,Alt_L)\
-- SendRFBEvent(key,Delete)\
-- SendRFBEvent(keyup,Alt_L)\
-- SendRFBEvent(keyup,Control_L)\
-- HidePopup()",
-+ SendRFBEvent(keydown,Alt_L)\
-+ SendRFBEvent(key,Delete)\
-+ SendRFBEvent(keyup,Alt_L)\
-+ SendRFBEvent(keyup,Control_L)\
-+ HidePopup()",
-
- "*popup*button8.label: Send F8",
- "*popup*button8.translations: #override\\n\
- <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup()",
-
-+ "*popup*button9.label: Send F9",
-+ "*popup*button9.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F9) HidePopup()",
-+
-+ "*popup*button10.label: ViewOnly",
-+ "*popup*button10.type: toggle",
-+ "*popup*button10.translations: #override\\n\
-+ <Visible>: SetViewOnlyState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleViewOnly() HidePopup()",
-+
-+ "*popup*button11.label: Disable Bell",
-+ "*popup*button11.type: toggle",
-+ "*popup*button11.translations: #override\\n\
-+ <Visible>: SetBellState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleBell() HidePopup()",
-+
-+ "*popup*button12.label: Cursor Shape",
-+ "*popup*button12.type: toggle",
-+ "*popup*button12.translations: #override\\n\
-+ <Visible>: SetCursorShapeState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorShape() HidePopup()",
-+
-+ "*popup*button13.label: X11 Cursor",
-+ "*popup*button13.type: toggle",
-+ "*popup*button13.translations: #override\\n\
-+ <Visible>: SetX11CursorState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleX11Cursor() HidePopup()",
-+
-+ "*popup*button14.label: Cursor Alphablend",
-+ "*popup*button14.type: toggle",
-+ "*popup*button14.translations: #override\\n\
-+ <Visible>: SetCursorAlphaState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorAlpha() HidePopup()",
-+
-+ "*popup*button15.label: Toggle Tight/Hextile",
-+ "*popup*button15.type: toggle",
-+ "*popup*button15.translations: #override\\n\
-+ <Visible>: SetHextileState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleTightHextile() HidePopup()",
-+
-+ "*popup*button16.label: Toggle Tight/ZRLE",
-+ "*popup*button16.type: toggle",
-+ "*popup*button16.translations: #override\\n\
-+ <Visible>: SetZRLEState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleTightZRLE() HidePopup()",
-+
-+ "*popup*button17.label: Toggle ZRLE/ZYWRLE",
-+ "*popup*button17.type: toggle",
-+ "*popup*button17.translations: #override\\n\
-+ <Visible>: SetZYWRLEState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleZRLEZYWRLE() HidePopup()",
-+
-+ "*popup*button18.label: Quality Level",
-+ "*popup*button18.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() ShowQuality()",
-+
-+ "*popup*button19.label: Compress Level",
-+ "*popup*button19.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() ShowCompress()",
-+
-+ "*popup*button20.label: Disable JPEG",
-+ "*popup*button20.type: toggle",
-+ "*popup*button20.translations: #override\\n\
-+ <Visible>: SetNOJPEGState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleJPEG() HidePopup()",
-+
-+ "*popup*button21.label: TurboVNC Settings",
-+ "*popup*button21.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() ShowTurboVNC()",
-+
-+ "*popup*button22.label: Pipeline Updates",
-+ "*popup*button22.type: toggle",
-+ "*popup*button22.translations: #override\\n\
-+ <Visible>: SetPipelineUpdates()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() TogglePipelineUpdates() HidePopup()",
-+
-+ "*popup*button23.label: Full Color",
-+ "*popup*button23.type: toggle",
-+ "*popup*button23.translations: #override\\n\
-+ <Visible>: SetFullColorState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleFullColor() HidePopup()",
-+
-+ "*popup*button24.label: Grey Scale (16 & 8-bpp)",
-+ "*popup*button24.type: toggle",
-+ "*popup*button24.translations: #override\\n\
-+ <Visible>: SetGreyScaleState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleGreyScale() HidePopup()",
-+
-+ "*popup*button25.label: 16 bit color (BGR565)",
-+ "*popup*button25.type: toggle",
-+ "*popup*button25.translations: #override\\n\
-+ <Visible>: Set16bppState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() Toggle16bpp() HidePopup()",
-+
-+ "*popup*button26.label: 8 bit color (BGR233)",
-+ "*popup*button26.type: toggle",
-+ "*popup*button26.translations: #override\\n\
-+ <Visible>: Set8bppState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() Toggle8bpp() HidePopup()",
-+
-+ "*popup*button27.label: - 256 colors",
-+ "*popup*button27.type: toggle",
-+ "*popup*button27.translations: #override\\n\
-+ <Visible>: Set256ColorsState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() Toggle256Colors() HidePopup()",
-+
-+ "*popup*button28.label: - 64 colors",
-+ "*popup*button28.type: toggle",
-+ "*popup*button28.translations: #override\\n\
-+ <Visible>: Set64ColorsState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() Toggle64Colors() HidePopup()",
-+
-+ "*popup*button29.label: - 8 colors",
-+ "*popup*button29.type: toggle",
-+ "*popup*button29.translations: #override\\n\
-+ <Visible>: Set8ColorsState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() Toggle8Colors() HidePopup()",
-+
-+ "*popup*button30.label: Scale Viewer",
-+ "*popup*button30.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() SetScale()",
-+
-+ "*popup*button31.label: Escape Keys: Toggle",
-+ "*popup*button31.type: toggle",
-+ "*popup*button31.translations: #override\\n\
-+ <Visible>: SetEscapeKeysState()\\n\
-+ <Btn1Down>, <Btn1Up>: toggle() ToggleEscapeActive() HidePopup()",
-+
-+ "*popup*button32.label: Escape Keys: Help+Set",
-+ "*popup*button32.translations: #override\\n\
-+ <Btn1Down>, <Btn1Up>: HidePopup() SetEscapeKeys()",
-+
-+ "*popup*button33.label: Set Y Crop (y-max)",
-+ "*popup*button33.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() SetYCrop()",
-+
-+ "*popup*button34.label: Set Scrollbar Width",
-+ "*popup*button34.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() SetScbar()",
-+
-+ "*popup*button35.label: XGrabServer",
-+ "*popup*button35.type: toggle",
-+ "*popup*button35.translations: #override\\n\
-+ <Visible>: SetXGrabState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleXGrab() HidePopup()",
-+
-+ "*popup*button36.label: UltraVNC Extensions:",
-+ "*popup*button36.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup()",
-+
-+ "*popup*button37.label: - Set 1/n Server Scale",
-+ "*popup*button37.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HidePopup() ShowScaleN()",
-+
-+ "*popup*button38.label: - Text Chat",
-+ "*popup*button38.type: toggle",
-+ "*popup*button38.translations: #override\\n\
-+ <Visible>: SetTextChatState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleTextChat() HidePopup()",
-+
-+ "*popup*button39.label: - File Transfer",
-+ "*popup*button39.type: toggle",
-+ "*popup*button39.translations: #override\\n\
-+ <Visible>: SetFileXferState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleFileXfer() HidePopup()",
-+
-+ "*popup*button40.label: - Single Window",
-+ "*popup*button40.type: toggle",
-+ "*popup*button40.translations: #override\\n\
-+ <Visible>: SetSingleWindowState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleSingleWindow() HidePopup()",
-+
-+ "*popup*button41.label: - Disable Remote Input",
-+ "*popup*button41.type: toggle",
-+ "*popup*button41.translations: #override\\n\
-+ <Visible>: SetServerInputState()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleServerInput() HidePopup()",
-+
-+ "*popup*button42.label: Send Clipboard not Primary",
-+ "*popup*button42.type: toggle",
-+ "*popup*button42.translations: #override\\n\
-+ <Visible>: SetSendClipboard()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleSendClipboard() HidePopup()",
-+
-+ "*popup*button43.label: Send Selection Every time",
-+ "*popup*button43.type: toggle",
-+ "*popup*button43.translations: #override\\n\
-+ <Visible>: SetSendAlways()\\n\
-+ <Btn1Down>,<Btn1Up>: toggle() ToggleSendAlways() HidePopup()",
-+
-+ "*popup*button44.label: ",
-+
-+ "*turboVNC*button0.label: Dismiss",
-+ "*turboVNC*button0.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HideTurboVNC()",
-+
-+ "*turboVNC*button1.label: High Quality (LAN)",
-+ "*turboVNC*button1.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SetTurboVNC(1)",
-+
-+ "*turboVNC*button2.label: Medium Quality",
-+ "*turboVNC*button2.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SetTurboVNC(2)",
-+
-+ "*turboVNC*button3.label: Low Quality (WAN)",
-+ "*turboVNC*button3.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SetTurboVNC(3)",
-+
-+ "*turboVNC*button4.label: Lossless (Gigabit)",
-+ "*turboVNC*button4.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SetTurboVNC(4)",
-+
-+ "*turboVNC*button5.label: Lossless Zlib (WAN)",
-+ "*turboVNC*button5.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SetTurboVNC(5)",
-+
-+ "*turboVNC*button6.label: Subsampling:",
-+
-+ "*turboVNC*button7.label: - None",
-+ "*turboVNC*button7.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SetTurboVNC(6)",
-+
-+ "*turboVNC*button8.label: - 2X",
-+ "*turboVNC*button8.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SetTurboVNC(7)",
-+
-+ "*turboVNC*button9.label: - 4X",
-+ "*turboVNC*button9.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SetTurboVNC(8)",
-+
-+ "*turboVNC*button10.label: - Gray",
-+ "*turboVNC*button10.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SetTurboVNC(9)",
-+
-+ "*turboVNC*button11.label: Lossless Refresh",
-+ "*turboVNC*button11.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SetTurboVNC(10)",
-+
-+ "*turboVNC*button12.label: Lossy Refresh",
-+ "*turboVNC*button12.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: SendRFBEvent(fbupdate)",
-+
-+ "*turboVNC*buttonNone.label: Not Compiled with\\nTurboVNC Support.",
-+ "*turboVNC*buttonNone.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HideTurboVNC()",
-+
-+ "*qualLabel.label: JPEG Image Quality:",
-+ "*qualBar.length: 100",
-+ "*qualBar.width: 130",
-+ "*qualBar.orientation: horizontal",
-+ "*qualBar.translations: #override\\n\
-+ <Btn1Down>: StartScroll(Continuous) MoveThumb() NotifyThumb()\\n\
-+ <Btn1Motion>: MoveThumb() NotifyThumb()\\n\
-+ <Btn3Down>: StartScroll(Continuous) MoveThumb() NotifyThumb()\\n\
-+ <Btn3Motion>: MoveThumb() NotifyThumb()",
-+
-+ "*qualText.label: 000",
-+
-+ "*scaleN*button0.label: Dismiss",
-+ "*scaleN*button0.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HideScaleN()",
-+
-+ "*scaleN*button1.label: 1/1",
-+ "*scaleN*button1.translations: #override\\n\
-+ <Visible>: SetScaleNState(1)\\n\
-+ <Btn1Down>,<Btn1Up>: SetScaleN(1) HideScaleN()",
-+
-+ "*scaleN*button2.label: 1/2",
-+ "*scaleN*button2.translations: #override\\n\
-+ <Visible>: SetScaleNState(2)\\n\
-+ <Btn1Down>,<Btn1Up>: SetScaleN(2) HideScaleN()",
-+
-+ "*scaleN*button3.label: 1/3",
-+ "*scaleN*button3.translations: #override\\n\
-+ <Visible>: SetScaleNState(3)\\n\
-+ <Btn1Down>,<Btn1Up>: SetScaleN(3) HideScaleN()",
-+
-+ "*scaleN*button4.label: 1/4",
-+ "*scaleN*button4.translations: #override\\n\
-+ <Visible>: SetScaleNState(4)\\n\
-+ <Btn1Down>,<Btn1Up>: SetScaleN(4) HideScaleN()",
-+
-+ "*scaleN*button5.label: 1/5",
-+ "*scaleN*button5.translations: #override\\n\
-+ <Visible>: SetScaleNState(5)\\n\
-+ <Btn1Down>,<Btn1Up>: SetScaleN(5) HideScaleN()",
-+
-+ "*scaleN*button6.label: Other",
-+ "*scaleN*button6.translations: #override\\n\
-+ <Visible>: SetScaleNState(6)\\n\
-+ <Btn1Down>,<Btn1Up>: HideScaleN() DoServerScale()",
-+
-+ "*quality*buttonD.label: Dismiss",
-+ "*quality*buttonD.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HideQuality()",
-+
-+ "*quality*button0.label: 0",
-+ "*quality*button0.type: toggle",
-+ "*quality*button0.translations: #override\\n\
-+ <Visible>: SetQualityState(0)\\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(0) HideQuality()",
-+
-+ "*quality*button1.label: 1",
-+ "*quality*button1.type: toggle",
-+ "*quality*button1.translations: #override\\n\
-+ <Visible>: SetQualityState(1)\\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(1) HideQuality()",
-+
-+ "*quality*button2.label: 2",
-+ "*quality*button2.type: toggle",
-+ "*quality*button2.translations: #override\\n\
-+ <Visible>: SetQualityState(2)\\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(2) HideQuality()",
-+
-+ "*quality*button3.label: 3",
-+ "*quality*button3.type: toggle",
-+ "*quality*button3.translations: #override\\n\
-+ <Visible>: SetQualityState(3)\\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(3) HideQuality()",
-+
-+ "*quality*button4.label: 4",
-+ "*quality*button4.type: toggle",
-+ "*quality*button4.translations: #override\\n\
-+ <Visible>: SetQualityState(4)\\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(4) HideQuality()",
-+
-+ "*quality*button5.label: 5",
-+ "*quality*button5.type: toggle",
-+ "*quality*button5.translations: #override\\n\
-+ <Visible>: SetQualityState(5)\\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(5) HideQuality()",
-+
-+ "*quality*button6.label: 6",
-+ "*quality*button6.type: toggle",
-+ "*quality*button6.translations: #override\\n\
-+ <Visible>: SetQualityState(6)\\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(6) HideQuality()",
-+
-+ "*quality*button7.label: 7",
-+ "*quality*button7.type: toggle",
-+ "*quality*button7.translations: #override\\n\
-+ <Visible>: SetQualityState(7)\\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(7) HideQuality()",
-+
-+ "*quality*button8.label: 8",
-+ "*quality*button8.type: toggle",
-+ "*quality*button8.translations: #override\\n\
-+ <Visible>: SetQualityState(8)\\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(8) HideQuality()",
-+
-+ "*quality*button9.label: 9",
-+ "*quality*button9.type: toggle",
-+ "*quality*button9.translations: #override\\n\
-+ <Visible>: SetQualityState(9)\\n\
-+ <Btn1Down>,<Btn1Up>: SetQuality(9) HideQuality()",
-+
-+ "*compress*buttonD.label: Dismiss",
-+ "*compress*buttonD.translations: #override\\n\
-+ <Btn1Down>,<Btn1Up>: HideCompress()",
-+
-+ "*compress*button0.label: 0",
-+ "*compress*button0.translations: #override\\n\
-+ <Visible>: SetCompressState(0)\\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(0) HideCompress()",
-+
-+ "*compress*button1.label: 1",
-+ "*compress*button1.translations: #override\\n\
-+ <Visible>: SetCompressState(1)\\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(1) HideCompress()",
-+
-+ "*compress*button2.label: 2",
-+ "*compress*button2.translations: #override\\n\
-+ <Visible>: SetCompressState(2)\\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(2) HideCompress()",
-+
-+ "*compress*button3.label: 3",
-+ "*compress*button3.translations: #override\\n\
-+ <Visible>: SetCompressState(3)\\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(3) HideCompress()",
-+
-+ "*compress*button4.label: 4",
-+ "*compress*button4.translations: #override\\n\
-+ <Visible>: SetCompressState(4)\\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(4) HideCompress()",
-+
-+ "*compress*button5.label: 5",
-+ "*compress*button5.translations: #override\\n\
-+ <Visible>: SetCompressState(5)\\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(5) HideCompress()",
-+
-+ "*compress*button6.label: 6",
-+ "*compress*button6.translations: #override\\n\
-+ <Visible>: SetCompressState(6)\\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(6) HideCompress()",
-+
-+ "*compress*button7.label: 7",
-+ "*compress*button7.translations: #override\\n\
-+ <Visible>: SetCompressState(7)\\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(7) HideCompress()",
-+
-+ "*compress*button8.label: 8",
-+ "*compress*button8.translations: #override\\n\
-+ <Visible>: SetCompressState(8)\\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(8) HideCompress()",
-+
-+ "*compress*button9.label: 9",
-+ "*compress*button9.translations: #override\\n\
-+ <Visible>: SetCompressState(9)\\n\
-+ <Btn1Down>,<Btn1Up>: SetCompress(9) HideCompress()",
-+
- NULL
- };
-
-@@ -124,7 +697,7 @@
- * from a dialog box.
- */
-
--char vncServerHost[256];
-+char vncServerHost[1024];
- int vncServerPort = 0;
-
-
-@@ -135,6 +708,7 @@
- */
-
- AppData appData;
-+AppData appDataNew;
-
- static XtResource appDataResourceList[] = {
- {"shareDesktop", "ShareDesktop", XtRBool, sizeof(Bool),
-@@ -155,14 +729,44 @@
- {"userLogin", "UserLogin", XtRString, sizeof(String),
- XtOffsetOf(AppData, userLogin), XtRImmediate, (XtPointer) 0},
-
-+ {"unixPW", "UnixPW", XtRString, sizeof(String),
-+ XtOffsetOf(AppData, unixPW), XtRImmediate, (XtPointer) 0},
-+
-+ {"msLogon", "MSLogon", XtRString, sizeof(String),
-+ XtOffsetOf(AppData, msLogon), XtRImmediate, (XtPointer) 0},
-+
-+ {"repeaterUltra", "RepeaterUltra", XtRString, sizeof(String),
-+ XtOffsetOf(AppData, repeaterUltra), XtRImmediate, (XtPointer) 0},
-+
-+ {"ultraDSM", "UltraDSM", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, ultraDSM), XtRImmediate, (XtPointer) False},
-+
-+ {"acceptPopup", "AcceptPopup", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, acceptPopup), XtRImmediate, (XtPointer) False},
-+
-+ {"rfbVersion", "RfbVersion", XtRString, sizeof(String),
-+ XtOffsetOf(AppData, rfbVersion), XtRImmediate, (XtPointer) 0},
-+
- {"passwordDialog", "PasswordDialog", XtRBool, sizeof(Bool),
- XtOffsetOf(AppData, passwordDialog), XtRImmediate, (XtPointer) False},
-
- {"encodings", "Encodings", XtRString, sizeof(String),
- XtOffsetOf(AppData, encodingsString), XtRImmediate, (XtPointer) 0},
-
-- {"useBGR233", "UseBGR233", XtRBool, sizeof(Bool),
-- XtOffsetOf(AppData, useBGR233), XtRImmediate, (XtPointer) False},
-+ {"useBGR233", "UseBGR233", XtRInt, sizeof(int),
-+ XtOffsetOf(AppData, useBGR233), XtRImmediate, (XtPointer) 0},
-+
-+ {"useBGR565", "UseBGR565", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, useBGR565), XtRImmediate, (XtPointer) False},
-+
-+ {"useGreyScale", "UseGreyScale", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, useGreyScale), XtRImmediate, (XtPointer) False},
-+
-+ {"yCrop", "yCrop", XtRInt, sizeof(int),
-+ XtOffsetOf(AppData, yCrop), XtRImmediate, (XtPointer) 0},
-+
-+ {"sbWidth", "sbWidth", XtRInt, sizeof(int),
-+ XtOffsetOf(AppData, sbWidth), XtRImmediate, (XtPointer) 2},
-
- {"nColours", "NColours", XtRInt, sizeof(int),
- XtOffsetOf(AppData, nColours), XtRImmediate, (XtPointer) 256},
-@@ -179,9 +783,12 @@
- {"requestedDepth", "RequestedDepth", XtRInt, sizeof(int),
- XtOffsetOf(AppData, requestedDepth), XtRImmediate, (XtPointer) 0},
-
-- {"useSharedMemory", "UseSharedMemory", XtRBool, sizeof(Bool),
-+ {"useShm", "UseShm", XtRBool, sizeof(Bool),
- XtOffsetOf(AppData, useShm), XtRImmediate, (XtPointer) True},
-
-+ {"termChat", "TermChat", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, termChat), XtRImmediate, (XtPointer) False},
-+
- {"wmDecorationWidth", "WmDecorationWidth", XtRInt, sizeof(int),
- XtOffsetOf(AppData, wmDecorationWidth), XtRImmediate, (XtPointer) 4},
-
-@@ -191,6 +798,9 @@
- {"popupButtonCount", "PopupButtonCount", XtRInt, sizeof(int),
- XtOffsetOf(AppData, popupButtonCount), XtRImmediate, (XtPointer) 0},
-
-+ {"popupButtonBreak", "PopupButtonBreak", XtRInt, sizeof(int),
-+ XtOffsetOf(AppData, popupButtonBreak), XtRImmediate, (XtPointer) 0},
-+
- {"debug", "Debug", XtRBool, sizeof(Bool),
- XtOffsetOf(AppData, debug), XtRImmediate, (XtPointer) False},
-
-@@ -206,11 +816,13 @@
- {"bumpScrollPixels", "BumpScrollPixels", XtRInt, sizeof(int),
- XtOffsetOf(AppData, bumpScrollPixels), XtRImmediate, (XtPointer) 20},
-
-+ /* hardwired compress -1 vs . 7 */
- {"compressLevel", "CompressionLevel", XtRInt, sizeof(int),
- XtOffsetOf(AppData, compressLevel), XtRImmediate, (XtPointer) -1},
-
-+ /* hardwired quality was 6 */
- {"qualityLevel", "QualityLevel", XtRInt, sizeof(int),
-- XtOffsetOf(AppData, qualityLevel), XtRImmediate, (XtPointer) 6},
-+ XtOffsetOf(AppData, qualityLevel), XtRImmediate, (XtPointer) -1},
-
- {"enableJPEG", "EnableJPEG", XtRBool, sizeof(Bool),
- XtOffsetOf(AppData, enableJPEG), XtRImmediate, (XtPointer) True},
-@@ -218,14 +830,97 @@
- {"useRemoteCursor", "UseRemoteCursor", XtRBool, sizeof(Bool),
- XtOffsetOf(AppData, useRemoteCursor), XtRImmediate, (XtPointer) True},
-
-+ {"useCursorAlpha", "UseCursorAlpha", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, useCursorAlpha), XtRImmediate, (XtPointer) False},
-+
-+ {"useRawLocal", "UseRawLocal", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, useRawLocal), XtRImmediate, (XtPointer) False},
-+
-+ {"notty", "NoTty", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, notty), XtRImmediate, (XtPointer) False},
-+
- {"useX11Cursor", "UseX11Cursor", XtRBool, sizeof(Bool),
- XtOffsetOf(AppData, useX11Cursor), XtRImmediate, (XtPointer) False},
-
-+ {"useBell", "UseBell", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, useBell), XtRImmediate, (XtPointer) True},
-+
- {"grabKeyboard", "GrabKeyboard", XtRBool, sizeof(Bool),
-- XtOffsetOf(AppData, grabKeyboard), XtRImmediate, (XtPointer) False},
-+ XtOffsetOf(AppData, grabKeyboard), XtRImmediate, (XtPointer) True},
-
- {"autoPass", "AutoPass", XtRBool, sizeof(Bool),
-- XtOffsetOf(AppData, autoPass), XtRImmediate, (XtPointer) False}
-+ XtOffsetOf(AppData, autoPass), XtRImmediate, (XtPointer) False},
-+
-+ {"grabAll", "GrabAll", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, grabAll), XtRImmediate, (XtPointer) False},
-+
-+ {"useXserverBackingStore", "UseXserverBackingStore", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, useXserverBackingStore), XtRImmediate, (XtPointer) False},
-+
-+ {"overrideRedir", "OverrideRedir", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, overrideRedir), XtRImmediate, (XtPointer) True},
-+
-+ {"serverInput", "ServerInput", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, serverInput), XtRImmediate, (XtPointer) True},
-+
-+ {"singleWindow", "SingleWindow", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, singleWindow), XtRImmediate, (XtPointer) False},
-+
-+ {"serverScale", "ServerScale", XtRInt, sizeof(int),
-+ XtOffsetOf(AppData, serverScale), XtRImmediate, (XtPointer) 1},
-+
-+ {"chatActive", "ChatActive", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, chatActive), XtRImmediate, (XtPointer) False},
-+
-+ {"chatOnly", "ChatOnly", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, chatOnly), XtRImmediate, (XtPointer) False},
-+
-+ {"fileActive", "FileActive", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, fileActive), XtRImmediate, (XtPointer) False},
-+
-+ {"popupFix", "PopupFix", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, popupFix), XtRImmediate, (XtPointer) False},
-+
-+ {"scale", "Scale", XtRString, sizeof(String),
-+ XtOffsetOf(AppData, scale), XtRImmediate, (XtPointer) 0},
-+
-+ {"pipelineUpdates", "PipelineUpdates", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, pipelineUpdates), XtRImmediate, (XtPointer)
-+#ifdef TURBOVNC
-+ True},
-+#else
-+#if 0
-+ False},
-+#else
-+ True},
-+#endif
-+#endif
-+
-+ {"noipv4", "noipv4", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, noipv4), XtRImmediate, (XtPointer) False},
-+
-+ {"noipv6", "noipv6", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, noipv6), XtRImmediate, (XtPointer) False},
-+
-+ {"sendClipboard", "SendClipboard", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, sendClipboard), XtRImmediate, (XtPointer) False},
-+
-+ {"sendAlways", "SendAlways", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, sendAlways), XtRImmediate, (XtPointer) False},
-+
-+ {"recvText", "RecvText", XtRString, sizeof(String),
-+ XtOffsetOf(AppData, recvText), XtRImmediate, (XtPointer) 0},
-+
-+ {"appShare", "AppShare", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, appShare), XtRImmediate, (XtPointer) False},
-+
-+ {"escapeKeys", "EscapeKeys", XtRString, sizeof(String),
-+ XtOffsetOf(AppData, escapeKeys), XtRImmediate, (XtPointer) 0},
-+
-+ {"escapeActive", "EscapeActive", XtRBool, sizeof(Bool),
-+ XtOffsetOf(AppData, escapeActive), XtRImmediate, (XtPointer) False}
-+
-+ /* check commas */
- };
-
-
-@@ -242,8 +937,29 @@
- {"-noraiseonbeep", "*raiseOnBeep", XrmoptionNoArg, "False"},
- {"-passwd", "*passwordFile", XrmoptionSepArg, 0},
- {"-user", "*userLogin", XrmoptionSepArg, 0},
-+ {"-unixpw", "*unixPW", XrmoptionSepArg, 0},
-+ {"-mslogon", "*msLogon", XrmoptionSepArg, 0},
-+ {"-repeater", "*repeaterUltra", XrmoptionSepArg, 0},
-+ {"-ultradsm", "*ultraDSM", XrmoptionNoArg, "True"},
-+ {"-acceptpopup", "*acceptPopup", XrmoptionNoArg, "True"},
-+ {"-acceptpopupsc", "*acceptPopup", XrmoptionNoArg, "True"},
-+ {"-rfbversion", "*rfbVersion", XrmoptionSepArg, 0},
- {"-encodings", "*encodings", XrmoptionSepArg, 0},
-- {"-bgr233", "*useBGR233", XrmoptionNoArg, "True"},
-+ {"-bgr233", "*useBGR233", XrmoptionNoArg, "256"},
-+ {"-use64", "*useBGR233", XrmoptionNoArg, "64"},
-+ {"-bgr222", "*useBGR233", XrmoptionNoArg, "64"},
-+ {"-use8", "*useBGR233", XrmoptionNoArg, "8"},
-+ {"-bgr111", "*useBGR233", XrmoptionNoArg, "8"},
-+ {"-16bpp", "*useBGR565", XrmoptionNoArg, "True"},
-+ {"-bgr565", "*useBGR565", XrmoptionNoArg, "True"},
-+ {"-grey", "*useGreyScale", XrmoptionNoArg, "True"},
-+ {"-gray", "*useGreyScale", XrmoptionNoArg, "True"},
-+ {"-sbwidth", "*sbwidth", XrmoptionSepArg, 0},
-+ {"-env", "*envDummy", XrmoptionSepArg, 0},
-+ {"-ycrop", "*yCrop", XrmoptionSepArg, 0},
-+ {"-rawlocal", "*useRawLocal", XrmoptionNoArg, "True"},
-+ {"-notty", "*notty", XrmoptionNoArg, "True"},
-+ {"-alpha", "*useCursorAlpha", XrmoptionNoArg, "True"},
- {"-owncmap", "*forceOwnCmap", XrmoptionNoArg, "True"},
- {"-truecolor", "*forceTrueColour", XrmoptionNoArg, "True"},
- {"-truecolour", "*forceTrueColour", XrmoptionNoArg, "True"},
-@@ -253,8 +969,30 @@
- {"-nojpeg", "*enableJPEG", XrmoptionNoArg, "False"},
- {"-nocursorshape", "*useRemoteCursor", XrmoptionNoArg, "False"},
- {"-x11cursor", "*useX11Cursor", XrmoptionNoArg, "True"},
-- {"-autopass", "*autoPass", XrmoptionNoArg, "True"}
--
-+ {"-nobell", "*useBell", XrmoptionNoArg, "False"},
-+ {"-autopass", "*autoPass", XrmoptionNoArg, "True"},
-+ {"-graball", "*grabAll", XrmoptionNoArg, "True"},
-+ {"-grabkbd", "*grabKeyboard", XrmoptionNoArg, "True"},
-+ {"-nograbkbd", "*grabKeyboard", XrmoptionNoArg, "False"},
-+ {"-grabkeyboard", "*grabKeyboard", XrmoptionNoArg, "True"},
-+ {"-nograbkeyboard","*grabKeyboard", XrmoptionNoArg, "False"},
-+ {"-nooverride", "*overrideRedir", XrmoptionNoArg, "False"},
-+ {"-bs", "*useXserverBackingStore", XrmoptionNoArg, "True"},
-+ {"-nobs", "*useXserverBackingStore", XrmoptionNoArg, "False"},
-+ {"-popupfix", "*popupFix", XrmoptionNoArg, "True"},
-+ {"-noshm", "*useShm", XrmoptionNoArg, "False"},
-+ {"-termchat", "*termChat", XrmoptionNoArg, "True"},
-+ {"-chatonly", "*chatOnly", XrmoptionNoArg, "True"},
-+ {"-scale", "*scale", XrmoptionSepArg, 0},
-+ {"-appshare", "*appShare", XrmoptionNoArg, "True"},
-+ {"-escape", "*escapeKeys", XrmoptionSepArg, 0},
-+ {"-sendclipboard", "*sendClipboard", XrmoptionNoArg, "True"},
-+ {"-sendalways", "*sendAlways", XrmoptionNoArg, "True"},
-+ {"-recvtext", "*recvText", XrmoptionSepArg, 0},
-+ {"-pipeline", "*pipelineUpdates", XrmoptionNoArg, "True"},
-+ {"-nopipeline", "*pipelineUpdates", XrmoptionNoArg, "False"},
-+ {"-noipv4", "*noipv4", XrmoptionNoArg, "True"},
-+ {"-noipv6", "*noipv6", XrmoptionNoArg, "True"}
- };
-
- int numCmdLineOptions = XtNumber(cmdLineOptions);
-@@ -267,16 +1005,100 @@
- static XtActionsRec actions[] = {
- {"SendRFBEvent", SendRFBEvent},
- {"ShowPopup", ShowPopup},
-+ {"Noop", Noop},
- {"HidePopup", HidePopup},
-+ {"HideScaleN", HideScaleN},
-+ {"HideTurboVNC", HideTurboVNC},
-+ {"HideQuality", HideQuality},
-+ {"HideCompress", HideCompress},
- {"ToggleFullScreen", ToggleFullScreen},
-+ {"JumpLeft", JumpLeft},
-+ {"JumpRight", JumpRight},
-+ {"JumpUp", JumpUp},
-+ {"JumpDown", JumpDown},
- {"SetFullScreenState", SetFullScreenState},
- {"SelectionFromVNC", SelectionFromVNC},
- {"SelectionToVNC", SelectionToVNC},
- {"ServerDialogDone", ServerDialogDone},
-+ {"UserDialogDone", UserDialogDone},
-+ {"YCropDialogDone", YCropDialogDone},
-+ {"ScbarDialogDone", ScbarDialogDone},
-+ {"ScaleNDialogDone", ScaleNDialogDone},
-+ {"ScaleDialogDone", ScaleDialogDone},
- {"PasswordDialogDone", PasswordDialogDone},
- {"Pause", Pause},
- {"RunCommand", RunCommand},
- {"Quit", Quit},
-+ {"HideChat", HideChat},
-+ {"Toggle8bpp", Toggle8bpp},
-+ {"Toggle16bpp", Toggle16bpp},
-+ {"ToggleFullColor", ToggleFullColor},
-+ {"Toggle256Colors", Toggle256Colors},
-+ {"Toggle64Colors", Toggle64Colors},
-+ {"Toggle8Colors", Toggle8Colors},
-+ {"ToggleGreyScale", ToggleGreyScale},
-+ {"ToggleTightZRLE", ToggleTightZRLE},
-+ {"ToggleTightHextile", ToggleTightHextile},
-+ {"ToggleZRLEZYWRLE", ToggleZRLEZYWRLE},
-+ {"ToggleViewOnly", ToggleViewOnly},
-+ {"ToggleJPEG", ToggleJPEG},
-+ {"ToggleCursorShape", ToggleCursorShape},
-+ {"ToggleCursorAlpha", ToggleCursorAlpha},
-+ {"ToggleX11Cursor", ToggleX11Cursor},
-+ {"ToggleBell", ToggleBell},
-+ {"ToggleRawLocal", ToggleRawLocal},
-+ {"ToggleServerInput", ToggleServerInput},
-+ {"TogglePipelineUpdates", TogglePipelineUpdates},
-+ {"ToggleSendClipboard", ToggleSendClipboard},
-+ {"ToggleSendAlways", ToggleSendAlways},
-+ {"ToggleSingleWindow", ToggleSingleWindow},
-+ {"ToggleTextChat", ToggleTextChat},
-+ {"ToggleFileXfer", ToggleFileXfer},
-+ {"ToggleXGrab", ToggleXGrab},
-+ {"DoServerScale", DoServerScale},
-+ {"SetScale", SetScale},
-+ {"SetYCrop", SetYCrop},
-+ {"SetScbar", SetScbar},
-+ {"ShowScaleN", ShowScaleN},
-+ {"ShowTurboVNC", ShowTurboVNC},
-+ {"ShowQuality", ShowQuality},
-+ {"ShowCompress", ShowCompress},
-+ {"SetScaleN", SetScaleN},
-+ {"SetTurboVNC", SetTurboVNC},
-+ {"SetQuality", SetQuality},
-+ {"SetCompress", SetCompress},
-+ {"Set8bppState", Set8bppState},
-+ {"Set16bppState", Set16bppState},
-+ {"SetFullColorState", SetFullColorState},
-+ {"Set256ColorsState", Set256ColorsState},
-+ {"Set64ColorsState", Set64ColorsState},
-+ {"Set8ColorsState", Set8ColorsState},
-+ {"SetGreyScaleState", SetGreyScaleState},
-+ {"SetZRLEState", SetZRLEState},
-+ {"SetHextileState", SetHextileState},
-+ {"SetZYWRLEState", SetZYWRLEState},
-+ {"SetNOJPEGState", SetNOJPEGState},
-+ {"SetScaleNState", SetScaleNState},
-+ {"SetQualityState", SetQualityState},
-+ {"SetCompressState", SetCompressState},
-+ {"SetViewOnlyState", SetViewOnlyState},
-+ {"SetCursorShapeState", SetCursorShapeState},
-+ {"SetCursorAlphaState", SetCursorAlphaState},
-+ {"SetX11CursorState", SetX11CursorState},
-+ {"SetBellState", SetBellState},
-+ {"SetRawLocalState", SetRawLocalState},
-+ {"SetServerInputState", SetServerInputState},
-+ {"SetPipelineUpdates", SetPipelineUpdates},
-+ {"SetSendClipboard", SetSendClipboard},
-+ {"SetSendAlways", SetSendAlways},
-+ {"SetSingleWindowState", SetSingleWindowState},
-+ {"SetTextChatState", SetTextChatState},
-+ {"SetFileXferState", SetFileXferState},
-+ {"SetXGrabState", SetXGrabState},
-+ {"SetEscapeKeysState", SetEscapeKeysState},
-+ {"ToggleEscapeActive", ToggleEscapeActive},
-+ {"EscapeDialogDone", EscapeDialogDone},
-+ {"SetEscapeKeys", SetEscapeKeys}
- };
-
-
-@@ -302,11 +1124,14 @@
- void
- usage(void)
- {
-- fprintf(stderr,
-- "TightVNC viewer version 1.3dev7\n"
-+ fprintf(stdout,
-+ "SSVNC Viewer (based on TightVNC viewer version 1.3.9)\n"
- "\n"
- "Usage: %s [<OPTIONS>] [<HOST>][:<DISPLAY#>]\n"
- " %s [<OPTIONS>] [<HOST>][::<PORT#>]\n"
-+ " %s [<OPTIONS>] exec=[CMD ARGS...]\n"
-+ " %s [<OPTIONS>] fd=n\n"
-+ " %s [<OPTIONS>] /path/to/unix/socket\n"
- " %s [<OPTIONS>] -listen [<DISPLAY#>]\n"
- " %s -help\n"
- "\n"
-@@ -319,7 +1144,7 @@
- " -noraiseonbeep\n"
- " -passwd <PASSWD-FILENAME> (standard VNC authentication)\n"
- " -user <USERNAME> (Unix login authentication)\n"
-- " -encodings <ENCODING-LIST> (e.g. \"tight copyrect\")\n"
-+ " -encodings <ENCODING-LIST> (e.g. \"tight,copyrect\")\n"
- " -bgr233\n"
- " -owncmap\n"
- " -truecolour\n"
-@@ -332,10 +1157,390 @@
- " -autopass\n"
- "\n"
- "Option names may be abbreviated, e.g. -bgr instead of -bgr233.\n"
-- "See the manual page for more information."
-- "\n", programName, programName, programName, programName);
-+ "See the manual page for more information.\n"
-+ "\n"
-+ "\n"
-+ "Enhanced TightVNC viewer (SSVNC) options:\n"
-+ "\n"
-+ " URL http://www.karlrunge.com/x11vnc/ssvnc.html\n"
-+ "\n"
-+ " Note: ZRLE and ZYWRLE encodings are now supported.\n"
-+ "\n"
-+ " Note: F9 is shortcut to Toggle FullScreen mode.\n"
-+ "\n"
-+ " Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1\n"
-+ " to allow more than one incoming VNC server at a time.\n"
-+ " This is the same as -multilisten described below. Set\n"
-+ " SSVNC_MULTIPLE_LISTEN=MAX:n to allow no more than \"n\"\n"
-+ " simultaneous reverse connections.\n"
-+ "\n"
-+ " Note: If the host:port is specified as \"exec=command args...\"\n"
-+ " then instead of making a TCP/IP socket connection to the\n"
-+ " remote VNC server, \"command args...\" is executed and the\n"
-+ " viewer is attached to its stdio. This enables tunnelling\n"
-+ " established via an external command, e.g. an stunnel(8)\n"
-+ " that does not involve a listening socket. This mode does\n"
-+ " not work for -listen reverse connections.\n"
-+ "\n"
-+ " If the host:port is specified as \"fd=n\" then it is assumed\n"
-+ " n is an already opened file descriptor to the socket. (i.e\n"
-+ " the parent did fork+exec)\n"
-+ "\n"
-+ " If the host:port contains a '/' it is interpreted as a\n"
-+ " unix-domain socket (AF_LOCAL insead of AF_INET)\n"
-+ "\n"
-+ " -multilisten As in -listen (reverse connection listening) except\n"
-+ " allow more than one incoming VNC server to be connected\n"
-+ " at a time. The default for -listen of only one at a\n"
-+ " time tries to play it safe by not allowing anyone on\n"
-+ " the network to put (many) desktops on your screen over\n"
-+ " a long window of time. Use -multilisten for no limit.\n"
-+ "\n"
-+ " -acceptpopup In -listen (reverse connection listening) mode when\n"
-+ " a reverse VNC connection comes in show a popup asking\n"
-+ " whether to Accept or Reject the connection. The IP\n"
-+ " address of the connecting host is shown. Same as\n"
-+ " setting the env. var. SSVNC_ACCEPT_POPUP=1.\n"
-+ "\n"
-+ " -acceptpopupsc As in -acceptpopup except assume UltraVNC Single\n"
-+ " Click (SC) server. Retrieve User and ComputerName\n"
-+ " info from UltraVNC Server and display in the Popup.\n"
-+ "\n"
-+ " -use64 In -bgr233 mode, use 64 colors instead of 256.\n"
-+ " -bgr222 Same as -use64.\n"
-+ "\n"
-+ " -use8 In -bgr233 mode, use 8 colors instead of 256.\n"
-+ " -bgr111 Same as -use8.\n"
-+ "\n"
-+ " -16bpp If the vnc viewer X display is depth 24 at 32bpp\n"
-+ " request a 16bpp format from the VNC server to cut\n"
-+ " network traffic by up to 2X, then tranlate the\n"
-+ " pixels to 32bpp locally.\n"
-+ " -bgr565 Same as -16bpp.\n"
-+ "\n"
-+ " -grey Use a grey scale for the 16- and 8-bpp modes.\n"
-+ "\n"
-+ " -alpha Use alphablending transparency for local cursors\n"
-+ " requires: x11vnc server, both client and server\n"
-+ " must be 32bpp and same endianness.\n"
-+ "\n"
-+ " -scale str Scale the desktop locally. The string \"str\" can\n"
-+ " a floating point ratio, e.g. \"0.9\", or a fraction,\n"
-+ " e.g. \"3/4\", or WxH, e.g. 1280x1024. Use \"fit\"\n"
-+ " to fit in the current screen size. Use \"auto\" to\n"
-+ " fit in the window size. \"str\" can also be set by\n"
-+ " the env. var. SSVNC_SCALE.\n"
-+ "\n"
-+ " If you observe mouse trail painting errors, enable\n"
-+ " X11 Cursor mode (either via Popup or -x11cursor.)\n"
-+ "\n"
-+ " Note that scaling is done in software and so can be\n"
-+ " slow and requires more memory. Some speedup Tips:\n"
-+ "\n"
-+ " ZRLE is faster than Tight in this mode. When\n"
-+ " scaling is first detected, the encoding will\n"
-+ " be automatically switched to ZRLE. Use the\n"
-+ " Popup menu if you want to go back to Tight.\n"
-+ " Set SSVNC_PRESERVE_ENCODING=1 to disable this.\n"
-+ "\n"
-+ " Use a solid background on the remote side.\n"
-+ " (e.g. manually or via x11vnc -solid ...)\n"
-+ "\n"
-+ " If the remote server is x11vnc, try client\n"
-+ " side caching: x11vnc -ncache 10 ...\n"
-+ "\n"
-+ " -ycrop n Only show the top n rows of the framebuffer. For\n"
-+ " use with x11vnc -ncache client caching option\n"
-+ " to help \"hide\" the pixel cache region.\n"
-+ " Use a negative value (e.g. -1) for autodetection.\n"
-+ " Autodetection will always take place if the remote\n"
-+ " fb height is more than 2 times the width.\n"
-+ "\n"
-+ " -sbwidth n Scrollbar width for x11vnc -ncache mode (-ycrop),\n"
-+ " default is very narrow: 2 pixels, it is narrow to\n"
-+ " avoid distraction in -ycrop mode.\n"
-+ "\n"
-+ " -nobell Disable bell.\n"
-+ "\n"
-+ " -rawlocal Prefer raw encoding for localhost, default is\n"
-+ " no, i.e. assumes you have a SSH tunnel instead.\n"
-+ "\n"
-+ " -notty Try to avoid using the terminal for interactive\n"
-+ " responses: use windows for messages and prompting\n"
-+ " instead. Messages will also be printed to terminal.\n"
-+ "\n"
-+ " -sendclipboard Send the X CLIPBOARD selection (i.e. Ctrl+C,\n"
-+ " Ctrl+V) instead of the X PRIMARY selection (mouse\n"
-+ " select and middle button paste.)\n"
-+ "\n"
-+ " -sendalways Whenever the mouse enters the VNC viewer main\n"
-+ " window, send the selection to the VNC server even if\n"
-+ " it has not changed. This is like the Xt resource\n"
-+ " translation SelectionToVNC(always)\n"
-+ "\n"
-+ " -recvtext str When cut text is received from the VNC server,\n"
-+ " ssvncviewer will set both the X PRIMARY and the\n"
-+ " X CLIPBOARD local selections. To control which\n"
-+ " is set, specify 'str' as 'primary', 'clipboard',\n"
-+ " or 'both' (the default.)\n"
-+ "\n"
-+ " -graball Grab the entire X server when in fullscreen mode,\n"
-+ " needed by some old window managers like fvwm2.\n"
-+ "\n"
-+ " -popupfix Warp the popup back to the pointer position,\n"
-+ " needed by some old window managers like fvwm2.\n"
-+ " -sendclipboard Send the X CLIPBOARD selection (i.e. Ctrl+C,\n"
-+ " Ctrl+V) instead of the X PRIMARY selection (mouse\n"
-+ " select and middle button paste.)\n"
-+ "\n"
-+ " -sendalways Whenever the mouse enters the VNC viewer main\n"
-+ " window, send the selection to the VNC server even if\n"
-+ " it has not changed. This is like the Xt resource\n"
-+ " translation SelectionToVNC(always)\n"
-+ "\n"
-+ " -recvtext str When cut text is received from the VNC server,\n"
-+ " ssvncviewer will set both the X PRIMARY and the\n"
-+ " X CLIPBOARD local selections. To control which\n"
-+ " is set, specify 'str' as 'primary', 'clipboard',\n"
-+ " or 'both' (the default.)\n"
-+ "\n"
-+ " -graball Grab the entire X server when in fullscreen mode,\n"
-+ " needed by some old window managers like fvwm2.\n"
-+ "\n"
-+ " -popupfix Warp the popup back to the pointer position,\n"
-+ " needed by some old window managers like fvwm2.\n"
-+ "\n"
-+ " -grabkbd Grab the X keyboard when in fullscreen mode,\n"
-+ " needed by some window managers. Same as -grabkeyboard.\n"
-+ " -grabkbd is the default, use -nograbkbd to disable.\n"
-+ "\n"
-+ " -bs, -nobs Whether or not to use X server Backingstore for the\n"
-+ " main viewer window. The default is to not, mainly\n"
-+ " because most Linux, etc, systems X servers disable\n"
-+ " *all* Backingstore by default. To re-enable it put\n"
-+ "\n"
-+ " Option \"Backingstore\"\n"
-+ "\n"
-+ " in the Device section of /etc/X11/xorg.conf.\n"
-+ " In -bs mode with no X server backingstore, whenever an\n"
-+ " area of the screen is re-exposed it must go out to the\n"
-+ " VNC server to retrieve the pixels. This is too slow.\n"
-+ "\n"
-+ " In -nobs mode, memory is allocated by the viewer to\n"
-+ " provide its own backing of the main viewer window. This\n"
-+ " actually makes some activities faster (changes in large\n"
-+ " regions) but can appear to \"flash\" too much.\n"
-+ "\n"
-+ " -noshm Disable use of MIT shared memory extension (not recommended)\n"
-+ "\n"
-+ " -termchat Do the UltraVNC chat in the terminal vncviewer is in\n"
-+ " instead of in an independent window.\n"
-+ "\n"
-+ " -unixpw str Useful for logging into x11vnc in -unixpw mode. \"str\" is a\n"
-+ " string that allows many ways to enter the Unix Username\n"
-+ " and Unix Password. These characters: username, newline,\n"
-+ " password, newline are sent to the VNC server after any VNC\n"
-+ " authentication has taken place. Under x11vnc they are\n"
-+ " used for the -unixpw login. Other VNC servers could do\n"
-+ " something similar.\n"
-+ "\n"
-+ " You can also indicate \"str\" via the environment\n"
-+ " variable SSVNC_UNIXPW.\n"
-+ "\n"
-+ " Note that the Escape key is actually sent first to tell\n"
-+ " x11vnc to not echo the Unix Username back to the VNC\n"
-+ " viewer. Set SSVNC_UNIXPW_NOESC=1 to override this.\n"
-+ "\n"
-+ " If str is \".\", then you are prompted at the command line\n"
-+ " for the username and password in the normal way. If str is\n"
-+ " \"-\" the stdin is read via getpass(3) for username@password.\n"
-+ " Otherwise if str is a file, it is opened and the first line\n"
-+ " read is taken as the Unix username and the 2nd as the\n"
-+ " password. If str prefixed by \"rm:\" the file is removed\n"
-+ " after reading. Otherwise, if str has a \"@\" character,\n"
-+ " it is taken as username@password. Otherwise, the program\n"
-+ " exits with an error. Got all that?\n"
-+ "\n"
-+ " -repeater str This is for use with UltraVNC repeater proxy described\n"
-+ " here: http://www.uvnc.com/addons/repeater.html. The \"str\"\n"
-+ " is the ID string to be sent to the repeater. E.g. ID:1234\n"
-+ " It can also be the hostname and port or display of the VNC\n"
-+ " server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when\n"
-+ " using -repeater, the host:dpy on the cmdline is the repeater\n"
-+ " server, NOT the VNC server. The repeater will connect you.\n"
-+ "\n"
-+ " Example: vncviewer ... -repeater ID:3333 repeat.host:5900\n"
-+ " Example: vncviewer ... -repeater vhost:0 repeat.host:5900\n"
-+ "\n"
-+ " Use, e.g., '-repeater SCIII=ID:3210' if the repeater is a\n"
-+ " Single Click III (SSL) repeater (repeater_SSL.exe) and you\n"
-+ " are passing the SSL part of the connection through stunnel,\n"
-+ " socat, etc. This way the magic UltraVNC string 'testB'\n"
-+ " needed to work with the repeater is sent to it.\n"
-+ "\n"
-+ " -rfbversion str Set the advertised RFB version. E.g.: -rfbversion 3.6\n"
-+ " For some servers, e.g. UltraVNC this needs to be done.\n"
-+ "\n"
-+ " -ultradsm UltraVNC has symmetric private key encryption DSM plugins:\n"
-+ " http://www.uvnc.com/features/encryption.html. It is assumed\n"
-+ " you are using a unix program (e.g. our ultravnc_dsm_helper)\n"
-+ " to encrypt and decrypt the UltraVNC DSM stream. IN ADDITION\n"
-+ " TO THAT supply -ultradsm to tell THIS viewer to modify the\n"
-+ " RFB data sent so as to work with the UltraVNC Server. For\n"
-+ " some reason, each RFB msg type must be sent twice under DSM.\n"
-+ "\n"
-+ " -mslogon user Use Windows MS Logon to an UltraVNC server. Supply the\n"
-+ " username or \"1\" to be prompted. The default is to\n"
-+ " autodetect the UltraVNC MS Logon server and prompt for\n"
-+ " the username and password.\n"
-+ "\n"
-+ " IMPORTANT NOTE: The UltraVNC MS-Logon Diffie-Hellman\n"
-+ " exchange is very weak and can be brute forced to recover\n"
-+ " your username and password in a few seconds of CPU time.\n"
-+ " To be safe, be sure to use an additional encrypted tunnel\n"
-+ " (e.g. SSL or SSH) for the entire VNC session.\n"
-+ "\n"
-+ " -chatonly Try to be a client that only does UltraVNC text chat. This\n"
-+ " mode is used by x11vnc to present a chat window on the\n"
-+ " physical X11 console (i.e. chat with the person at the\n"
-+ " display).\n"
-+ "\n"
-+ " -env VAR=VALUE To save writing a shell script to set environment variables,\n"
-+ " specify as many as you need on the command line. For\n"
-+ " example, -env SSVNC_MULTIPLE_LISTEN=MAX:5 -env EDITOR=vi\n"
-+ "\n"
-+ " -noipv6 Disable all IPv6 sockets. Same as VNCVIEWER_NO_IPV6=1.\n"
-+ "\n"
-+ " -noipv4 Disable all IPv4 sockets. Same as VNCVIEWER_NO_IPV4=1.\n"
-+ "\n"
-+ " -printres Print out the Ssvnc X resources (appdefaults) and then exit\n"
-+ " You can save them to a file and customize them (e.g. the\n"
-+ " keybindings and Popup menu) Then point to the file via\n"
-+ " XENVIRONMENT or XAPPLRESDIR.\n"
-+ "\n"
-+ " -pipeline Like TurboVNC, request the next framebuffer update as soon\n"
-+ " as possible instead of waiting until the end of the current\n"
-+ " framebuffer update coming in. Helps 'pipeline' the updates.\n"
-+ " This is currently the default, use -nopipeline to disable.\n"
-+ "\n"
-+ " -appshare Enable features for use with x11vnc's -appshare mode where\n"
-+ " instead of sharing the full desktop only the application's\n"
-+ " windows are shared. Viewer multilisten mode is used to\n"
-+ " create the multiple windows: -multilisten is implied.\n"
-+ " See 'x11vnc -appshare -help' more information on the mode.\n"
-+ "\n"
-+ " Features enabled in the viewer under -appshare are:\n"
-+ " Minimum extra text in the title, auto -ycrop is disabled,\n"
-+ " x11vnc -remote_prefix X11VNC_APPSHARE_CMD: message channel,\n"
-+ " x11vnc initial window position hints. See also Escape Keys\n"
-+ " below for additional key and mouse bindings.\n"
-+ "\n"
-+ " -escape str This sets the 'Escape Keys' modifier sequence and enables\n"
-+ " escape keys mode. When the modifier keys escape sequence\n"
-+ " is held down, the next keystroke is interpreted locally\n"
-+ " to perform a special action instead of being sent to the\n"
-+ " remote VNC server.\n"
-+ "\n"
-+ " Use '-escape default' for the default modifier sequence.\n"
-+ " (Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L)\n"
-+ "\n"
-+ " Here are the 'Escape Keys: Help+Set' instructions from the Popup Menu:\n"
-+ "\n"
-+ " Escape Keys: Enter a comma separated list of modifier keys to be the\n"
-+ " 'escape sequence'. When these keys are held down, the next keystroke is\n"
-+ " interpreted locally to invoke a special action instead of being sent to\n"
-+ " the remote VNC server. In other words, a set of 'Hot Keys'.\n"
-+ " \n"
-+ " To enable or disable this, click on 'Escape Keys: Toggle' in the Popup.\n"
-+ " \n"
-+ " Here is the list of hot-key mappings to special actions:\n"
-+ " \n"
-+ " r: refresh desktop b: toggle bell c: toggle full-color\n"
-+ " f: file transfer x: x11cursor z: toggle Tight/ZRLE\n"
-+ " l: full screen g: graball e: escape keys dialog\n"
-+ " s: scale dialog +: scale up (=) -: scale down (_)\n"
-+ " t: text chat a: alphablend cursor\n"
-+ " V: toggle viewonly Q: quit viewer 1 2 3 4 5 6: UltraVNC scale 1/n\n"
-+ " \n"
-+ " Arrow keys: pan the viewport about 10%% for each keypress.\n"
-+ " PageUp / PageDown: pan the viewport by a screenful vertically.\n"
-+ " Home / End: pan the viewport by a screenful horizontally.\n"
-+ " KeyPad Arrow keys: pan the viewport by 1 pixel for each keypress.\n"
-+ " Dragging the Mouse with Button1 pressed also pans the viewport.\n"
-+ " Clicking Mouse Button3 brings up the Popup Menu.\n"
-+ " \n"
-+ " The above mappings are *always* active in ViewOnly mode, unless you set the\n"
-+ " Escape Keys value to 'never'.\n"
-+ " \n"
-+ " If the Escape Keys value below is set to 'default' then a default list of\n"
-+ " of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it\n"
-+ " is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag\n"
-+ " on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side\n"
-+ " of the keyboard.\n"
-+ " \n"
-+ " On Unix the default is Alt and Windows keys on Left side of keyboard.\n"
-+ " On MacOSX the default is Control and Command keys on Left side of keyboard.\n"
-+ " \n"
-+ " Example: Press and hold the Alt and Windows keys on the LEFT side of the\n"
-+ " keyboard and then press 'c' to toggle the full-color state. Or press 't'\n"
-+ " to toggle the ultravnc Text Chat window, etc.\n"
-+ " \n"
-+ " To use something besides the default, supply a comma separated list (or a\n"
-+ " single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L\n"
-+ " Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.\n"
-+ "\n"
-+ "\n"
-+ " New Popup actions:\n"
-+ "\n"
-+ " ViewOnly: ~ -viewonly\n"
-+ " Disable Bell: ~ -nobell\n"
-+ " Cursor Shape: ~ -nocursorshape\n"
-+ " X11 Cursor: ~ -x11cursor\n"
-+ " Cursor Alphablend: ~ -alpha\n"
-+ " Toggle Tight/Hextile: ~ -encodings hextile...\n"
-+ " Toggle Tight/ZRLE: ~ -encodings zrle...\n"
-+ " Toggle ZRLE/ZYWRLE: ~ -encodings zywrle...\n"
-+ " Quality Level ~ -quality (both Tight and ZYWRLE)\n"
-+ " Compress Level ~ -compresslevel\n"
-+ " Disable JPEG: ~ -nojpeg (Tight)\n"
-+ " Pipeline Updates ~ -pipeline\n"
-+ "\n"
-+ " Full Color as many colors as local screen allows.\n"
-+ " Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.\n"
-+ " 16 bit color (BGR565) ~ -16bpp / -bgr565\n"
-+ " 8 bit color (BGR233) ~ -bgr233\n"
-+ " 256 colors ~ -bgr233 default # of colors.\n"
-+ " 64 colors ~ -bgr222 / -use64\n"
-+ " 8 colors ~ -bgr111 / -use8\n"
-+ " Scale Viewer ~ -scale\n"
-+ " Escape Keys: Toggle ~ -escape\n"
-+ " Escape Keys: Help+Set ~ -escape\n"
-+ " Set Y Crop (y-max) ~ -ycrop\n"
-+ " Set Scrollbar Width ~ -sbwidth\n"
-+ " XGrabServer ~ -graball\n"
-+ "\n"
-+ " UltraVNC Extensions:\n"
-+ "\n"
-+ " Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.\n"
-+ " Text Chat Ultravnc ext. Do Text Chat.\n"
-+ " File Transfer Ultravnc ext. File xfer via Java helper.\n"
-+ " Single Window Ultravnc ext. Grab and view a single window.\n"
-+ " (select then click on the window you want).\n"
-+ " Disable Remote Input Ultravnc ext. Try to prevent input and\n"
-+ " viewing of monitor at physical display.\n"
-+ "\n"
-+ " Note: the Ultravnc extensions only apply to servers that support\n"
-+ " them. x11vnc/libvncserver supports some of them.\n"
-+ "\n"
-+ " Send Clipboard not Primary ~ -sendclipboard\n"
-+ " Send Selection Every time ~ -sendalways\n"
-+ "\n"
-+ "\n", programName, programName, programName, programName, programName, programName, programName);
- exit(1);
- }
-+#if 0
-+ " -nooverride Do not apply OverrideRedirect in fullscreen mode.\n"
-+#endif
-
-
- /*
-@@ -343,77 +1548,247 @@
- * not already processed by XtVaAppInitialize(). It sets vncServerHost and
- * vncServerPort and all the fields in appData.
- */
-+extern int saw_appshare;
-
- void
- GetArgsAndResources(int argc, char **argv)
- {
-- int i;
-- char *vncServerName, *colonPos;
-- int len, portOffset;
-+ char *vncServerName = NULL, *colonPos, *bracketPos;
-+ int len, portOffset;
-+ int disp;
-
- /* Turn app resource specs into our appData structure for the rest of the
- program to use */
-
-- XtGetApplicationResources(toplevel, &appData, appDataResourceList,
-- XtNumber(appDataResourceList), 0, 0);
-+ XtGetApplicationResources(toplevel, &appData, appDataResourceList,
-+ XtNumber(appDataResourceList), 0, 0);
-+
-+ /*
-+ * we allow setting of some by env, to avoid clash with other
-+ * viewer's cmdlines (e.g. change viewer in SSVNC).
-+ */
-+ if (getenv("VNCVIEWER_ALPHABLEND")) {
-+ appData.useCursorAlpha = True;
-+ }
-+ if (getenv("VNCVIEWER_POPUP_FIX")) {
-+ if (getenv("NOPOPUPFIX")) {
-+ ;
-+ } else if (!strcmp(getenv("VNCVIEWER_POPUP_FIX"), "0")) {
-+ ;
-+ } else {
-+ appData.popupFix = True;
-+ }
-+ }
-+ if (getenv("VNCVIEWER_GRAB_SERVER")) {
-+ appData.grabAll = True;
-+ }
-+ if (getenv("VNCVIEWER_YCROP")) {
-+ int n = atoi(getenv("VNCVIEWER_YCROP"));
-+ if (n != 0) {
-+ appData.yCrop = n;
-+ }
-+ }
-+ if (getenv("VNCVIEWER_RFBVERSION") && strcmp(getenv("VNCVIEWER_RFBVERSION"), "")) {
-+ appData.rfbVersion = strdup(getenv("VNCVIEWER_RFBVERSION"));
-+ }
-+ if (getenv("VNCVIEWER_ENCODINGS") && strcmp(getenv("VNCVIEWER_ENCODINGS"), "")) {
-+ appData.encodingsString = strdup(getenv("VNCVIEWER_ENCODINGS"));
-+ }
-+ if (getenv("VNCVIEWER_NOBELL")) {
-+ appData.useBell = False;
-+ }
-+ if (getenv("VNCVIEWER_X11CURSOR")) {
-+ appData.useX11Cursor = True;
-+ }
-+ if (getenv("VNCVIEWER_RAWLOCAL")) {
-+ appData.useRawLocal = True;
-+ }
-+ if (getenv("VNCVIEWER_NOTTY") || getenv("SSVNC_VNCVIEWER_NOTTY")) {
-+ appData.notty = True;
-+ }
-+ if (getenv("VNCVIEWER_SBWIDTH")) {
-+ int n = atoi(getenv("VNCVIEWER_SBWIDTH"));
-+ if (n != 0) {
-+ appData.sbWidth = n;
-+ }
-+ }
-+ if (getenv("VNCVIEWER_ULTRADSM")) {
-+ appData.ultraDSM = True;
-+ }
-+ if (getenv("SSVNC_ULTRA_DSM") && strcmp(getenv("SSVNC_ULTRA_DSM"), "")) {
-+ appData.ultraDSM = True;
-+ }
-+ if (getenv("SSVNC_NO_ULTRA_DSM")) {
-+ appData.ultraDSM = False;
-+ }
-+ if (getenv("SSVNC_SCALE") && strcmp(getenv("SSVNC_SCALE"), "")) {
-+ if (appData.scale == NULL) {
-+ appData.scale = strdup(getenv("SSVNC_SCALE"));
-+ }
-+ }
-+ if (getenv("VNCVIEWER_ESCAPE") && strcmp(getenv("VNCVIEWER_ESCAPE"), "")) {
-+ if (appData.escapeKeys == NULL) {
-+ appData.escapeKeys = strdup(getenv("VNCVIEWER_ESCAPE"));
-+ }
-+ }
-+ if (saw_appshare) {
-+ appData.appShare = True;
-+ }
-+ if (appData.appShare && appData.escapeKeys == NULL) {
-+ appData.escapeKeys = strdup("default");
-+ }
-+ if (appData.escapeKeys != NULL) {
-+ appData.escapeActive = True;
-+ }
-+ if (getenv("VNCVIEWER_SEND_CLIPBOARD")) {
-+ appData.sendClipboard = True;
-+ }
-+ if (getenv("VNCVIEWER_SEND_ALWAYS")) {
-+ appData.sendAlways = True;
-+ }
-+ if (getenv("VNCVIEWER_RECV_TEXT")) {
-+ char *s = getenv("VNCVIEWER_RECV_TEXT");
-+ if (!strcasecmp(s, "clipboard")) {
-+ appData.recvText = strdup("clipboard");
-+ } else if (!strcasecmp(s, "primary")) {
-+ appData.recvText = strdup("primary");
-+ } else if (!strcasecmp(s, "both")) {
-+ appData.recvText = strdup("both");
-+ }
-+ }
-+ if (getenv("VNCVIEWER_PIPELINE_UPDATES")) {
-+ appData.pipelineUpdates = True;
-+ } else if (getenv("VNCVIEWER_NO_PIPELINE_UPDATES")) {
-+ appData.pipelineUpdates = False;
-+ }
-+
-+ if (getenv("VNCVIEWER_NO_IPV4")) {
-+ appData.noipv4 = True;
-+ }
-+ if (getenv("VNCVIEWER_NO_IPV6")) {
-+ appData.noipv6 = True;
-+ }
-+
-+ if (appData.useBGR233 && appData.useBGR565) {
-+ appData.useBGR233 = 0;
-+ }
-+
-+ if (getenv("SSVNC_ULTRA_FTP_JAR") == NULL && programName != NULL) {
-+ int len = strlen(programName) + 200;
-+ char *q, *jar = (char *) malloc(len);
-+
-+ sprintf(jar, "%s", programName);
-+ q = strrchr(jar, '/');
-+ if (q) {
-+ struct stat sb;
-+ *(q+1) = '\0';
-+ strcat(jar, "../lib/ssvnc/util/ultraftp.jar");
-+ if (stat(jar, &sb) == 0) {
-+ char *put = (char *) malloc(len);
-+ sprintf(put, "SSVNC_ULTRA_FTP_JAR=%s", jar);
-+ fprintf(stderr, "Setting: %s\n\n", put);
-+ putenv(put);
-+ } else {
-+ sprintf(jar, "%s", programName);
-+ q = strrchr(jar, '/');
-+ *(q+1) = '\0';
-+ strcat(jar, "util/ultraftp.jar");
-+ if (stat(jar, &sb) == 0) {
-+ char *put = (char *) malloc(len);
-+ sprintf(put, "SSVNC_ULTRA_FTP_JAR=%s", jar);
-+ fprintf(stderr, "Setting: %s\n\n", put);
-+ putenv(put);
-+ }
-+ }
-+ }
-+ free(jar);
-+ }
-+
-
- /* Add our actions to the actions table so they can be used in widget
- resource specs */
-
-- XtAppAddActions(appContext, actions, XtNumber(actions));
-+ XtAppAddActions(appContext, actions, XtNumber(actions));
-
- /* Check any remaining command-line arguments. If -listen was specified
- there should be none. Otherwise the only argument should be the VNC
- server name. If not given then pop up a dialog box and wait for the
- server name to be entered. */
-
-- if (listenSpecified) {
-- if (argc != 1) {
-- fprintf(stderr,"\n%s -listen: invalid command line argument: %s\n",
-- programName, argv[1]);
-- usage();
-- }
-- return;
-- }
--
-- if (argc == 1) {
-- vncServerName = DoServerDialog();
-- appData.passwordDialog = True;
-- } else if (argc != 2) {
-- usage();
-- } else {
-- vncServerName = argv[1];
--
-- if (!isatty(0))
-- appData.passwordDialog = True;
-- if (vncServerName[0] == '-')
-- usage();
-- }
--
-- if (strlen(vncServerName) > 255) {
-- fprintf(stderr,"VNC server name too long\n");
-- exit(1);
-- }
--
-- colonPos = strchr(vncServerName, ':');
-- if (colonPos == NULL) {
-- /* No colon -- use default port number */
-- strcpy(vncServerHost, vncServerName);
-- vncServerPort = SERVER_PORT_OFFSET;
-- } else {
-- memcpy(vncServerHost, vncServerName, colonPos - vncServerName);
-- vncServerHost[colonPos - vncServerName] = '\0';
-- len = strlen(colonPos + 1);
-- portOffset = SERVER_PORT_OFFSET;
-- if (colonPos[1] == ':') {
-- /* Two colons -- interpret as a port number */
-- colonPos++;
-- len--;
-- portOffset = 0;
-- }
-- if (!len || strspn(colonPos + 1, "0123456789") != len) {
-- usage();
-- }
-- vncServerPort = atoi(colonPos + 1) + portOffset;
-- }
-+ if (listenSpecified) {
-+ if (argc != 1) {
-+ fprintf(stderr,"\n%s -listen: invalid command line argument: %s\n",
-+ programName, argv[1]);
-+ usage();
-+ }
-+ return;
-+ }
-+
-+ if (argc == 1) {
-+ vncServerName = DoServerDialog();
-+ if (!use_tty()) {
-+ appData.passwordDialog = True;
-+ }
-+ } else if (argc != 2) {
-+ usage();
-+ } else {
-+ vncServerName = argv[1];
-+
-+ if (!use_tty()) {
-+ appData.passwordDialog = True;
-+ }
-+ if (vncServerName[0] == '-') {
-+ usage();
-+ }
-+ }
-+
-+ if (strlen(vncServerName) > 255) {
-+ fprintf(stderr,"VNC server name too long\n");
-+ exit(1);
-+ }
-+
-+ colonPos = strrchr(vncServerName, ':');
-+ bracketPos = strrchr(vncServerName, ']');
-+ if (strstr(vncServerName, "exec=") == vncServerName) {
-+ /* special exec-external-command case */
-+ strcpy(vncServerHost, vncServerName);
-+ vncServerPort = SERVER_PORT_OFFSET;
-+ } else if (strstr(vncServerName, "fd=") == vncServerName) {
-+ /* special exec-external-command case */
-+ strcpy(vncServerHost, vncServerName);
-+ vncServerPort = SERVER_PORT_OFFSET;
-+ } else if (colonPos == NULL) {
-+ /* No colon -- use default port number */
-+ strcpy(vncServerHost, vncServerName);
-+ vncServerPort = SERVER_PORT_OFFSET;
-+ } else if (bracketPos != NULL && colonPos < bracketPos) {
-+ strcpy(vncServerHost, vncServerName);
-+ vncServerPort = SERVER_PORT_OFFSET;
-+ } else {
-+ if (colonPos > vncServerName && *(colonPos - 1) == ':') {
-+ colonPos--;
-+ }
-+ memcpy(vncServerHost, vncServerName, colonPos - vncServerName);
-+ vncServerHost[colonPos - vncServerName] = '\0';
-+ len = strlen(colonPos + 1);
-+ portOffset = SERVER_PORT_OFFSET;
-+ if (colonPos[1] == ':') {
-+ /* Two colons -- interpret as a port number */
-+ colonPos++;
-+ len--;
-+ portOffset = 0;
-+ }
-+ if (!len || strspn(colonPos + 1, "0123456789") != (size_t) len) {
-+ usage();
-+ }
-+#if 0
-+ vncServerPort = atoi(colonPos + 1) + portOffset;
-+#else
-+ disp = atoi(colonPos + 1);
-+ if (portOffset != 0 && disp >= 100) {
-+ portOffset = 0;
-+ }
-+ vncServerPort = disp + portOffset;
-+#endif
-+ }
- }
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/colour.c vnc_unixsrc/vncviewer/colour.c
---- vnc_unixsrc.orig/vncviewer/colour.c 2002-04-30 09:07:31.000000000 -0400
-+++ vnc_unixsrc/vncviewer/colour.c 2010-02-25 22:02:19.000000000 -0500
-@@ -31,9 +31,12 @@
- #define BGR233_SIZE 256
- unsigned long BGR233ToPixel[BGR233_SIZE];
-
-+#define BGR565_SIZE 65536
-+unsigned long BGR565ToPixel[BGR565_SIZE];
-+
- Colormap cmap;
- Visual *vis;
--unsigned int visdepth, visbpp;
-+unsigned int visdepth, visbpp, isLSB;
- Bool allocColorFailed = False;
-
- static int nBGR233ColoursAllocated;
-@@ -45,6 +48,8 @@
- static void AllocateExactBGR233Colours();
- static Bool AllocateBGR233Colour(int r, int g, int b);
-
-+static void SetupBGR565Map(unsigned long red_mask, unsigned long green_mask, unsigned long blue_mask);
-+
-
- /*
- * SetVisualAndCmap() deals with the wonderful world of X "visuals" (which are
-@@ -97,6 +102,44 @@
- visbpp = GetBPPForDepth(visdepth);
- cmap = DefaultColormap(dpy,DefaultScreen(dpy));
-
-+ if (ImageByteOrder(dpy) == LSBFirst) {
-+ isLSB = 1;
-+ } else {
-+ isLSB = 0;
-+ }
-+ if (visbpp == 24) {
-+ if (!appData.useBGR233) {
-+ fprintf(stderr, "Warning: for 24bpp enabling -bgr565 -- Don't use FullColor!\n");
-+ appData.useBGR565 = True;
-+ } else {
-+ fprintf(stderr, "Warning: for 24bpp using -bgr233 -- Don't use FullColor!\n");
-+ }
-+ }
-+
-+ if (appData.useBGR565) {
-+ if (visdepth < 24 || visbpp < 24 || vis->class != TrueColor) {
-+ fprintf(stderr, "disabling -16bpp BGR565 on non-depth 24 machine\n");
-+ appData.useBGR565 = False;
-+ } else {
-+ myFormat.bitsPerPixel = 16;
-+ myFormat.depth = 16;
-+ myFormat.trueColour = 1;
-+ myFormat.bigEndian = 0;
-+ myFormat.redMax = 31;
-+ myFormat.greenMax = 63;
-+ myFormat.blueMax = 31;
-+ myFormat.redShift = 11;
-+ myFormat.greenShift = 5;
-+ myFormat.blueShift = 0;
-+
-+ fprintf(stderr, "Using default colormap and translating from BGR565 (65536 colors). Pixel format:\n");
-+ PrintPixelFormat(&myFormat);
-+
-+ SetupBGR565Map(vis->red_mask, vis->green_mask, vis->blue_mask);
-+ return;
-+ }
-+ }
-+
- if (!appData.useBGR233 && (vis->class == TrueColor)) {
-
- myFormat.bitsPerPixel = visbpp;
-@@ -116,21 +159,42 @@
- return;
- }
-
-- appData.useBGR233 = True;
-+ if (appData.useBGR233 == 0) {
-+ appData.useBGR233 = 256;
-+ }
-
- myFormat.bitsPerPixel = 8;
- myFormat.depth = 8;
- myFormat.trueColour = 1;
- myFormat.bigEndian = 0;
-- myFormat.redMax = 7;
-+ myFormat.redMax = 7;
- myFormat.greenMax = 7;
-- myFormat.blueMax = 3;
-- myFormat.redShift = 0;
-+ myFormat.blueMax = 3;
-+ myFormat.redShift = 0;
- myFormat.greenShift = 3;
-- myFormat.blueShift = 6;
-+ myFormat.blueShift = 6;
-+
-+ if (appData.useBGR233 == 64) {
-+ /* BGR222 */
-+ myFormat.redMax = 3;
-+ myFormat.greenMax = 3;
-+ myFormat.blueMax = 3;
-+ myFormat.redShift = 0;
-+ myFormat.greenShift = 2;
-+ myFormat.blueShift = 4;
-+ }
-+ if (appData.useBGR233 == 8) {
-+ /* BGR111 */
-+ myFormat.redMax = 2;
-+ myFormat.greenMax = 2;
-+ myFormat.blueMax = 2;
-+ myFormat.redShift = 0;
-+ myFormat.greenShift = 1;
-+ myFormat.blueShift = 2;
-+ }
-
- fprintf(stderr,
-- "Using default colormap and translating from BGR233. Pixel format:\n");
-+ "Using default colormap and translating from BGR233 (%d colors). Pixel format:\n", appData.useBGR233);
- PrintPixelFormat(&myFormat);
-
- SetupBGR233Map();
-@@ -282,8 +346,12 @@
- XFree(format);
-
- if (bpp != 1 && bpp != 8 && bpp != 16 && bpp != 32) {
-- fprintf(stderr,"Can't cope with %d bits-per-pixel. Sorry.\n", bpp);
-- exit(1);
-+ if (bpp == 24) {
-+ fprintf(stderr,"Warning: 24 bits-per-pixel may have problems...\n");
-+ } else {
-+ fprintf(stderr,"Can't cope with %d bits-per-pixel. Sorry.\n", bpp);
-+ exit(1);
-+ }
- }
-
- return bpp;
-@@ -374,7 +442,7 @@
- if (!exactBGR233[i] &&
- XAllocColor(dpy, cmap, &cmapEntry[i])) {
-
-- if (cmapEntry[i].pixel == i) {
-+ if ((long) cmapEntry[i].pixel == i) {
-
- shared[i] = True; /* probably shared */
-
-@@ -394,16 +462,43 @@
- for (r = 0; r < 8; r++) {
- for (g = 0; g < 8; g++) {
- for (b = 0; b < 4; b++) {
-- if (BGR233ToPixel[(b<<6) | (g<<3) | r] == INVALID_PIXEL) {
-+ int bs = 6, gs = 3, rs = 0;
-+ int bm = 3, gm = 7, rm = 7;
-+ if (appData.useBGR233 == 64) {
-+ bs = 4; gs = 2; rs = 0;
-+ bm = 3; gm = 3; rm = 3;
-+ }
-+ if (appData.useBGR233 == 8) {
-+ bs = 2; gs = 1; rs = 0;
-+ bm = 1; gm = 1; rm = 1;
-+ }
-+ if ((b > bm || g > gm || r > rm)) {
-+ continue;
-+ }
-+ if (BGR233ToPixel[(b<<bs) | (g<<gs) | (r<<rs)] == INVALID_PIXEL) {
-
- unsigned long minDistance = ULONG_MAX;
-
- for (i = 0; i < cmapSize; i++) {
- if (exactBGR233[i] || shared[i]) {
-- unsigned long distance
-- = (abs(cmapEntry[i].red - r * 65535 / 7)
-- + abs(cmapEntry[i].green - g * 65535 / 7)
-- + abs(cmapEntry[i].blue - b * 65535 / 3));
-+ unsigned long distance;
-+ int r1, g1, b1;
-+ if (appData.useGreyScale) {
-+ int ave;
-+ ave = (r + g + 2*b)/3;
-+ r1 = ave;
-+ g1 = ave;
-+ b1 = ave/2;
-+ } else {
-+ r1 = r;
-+ g1 = g;
-+ b1 = b;
-+ }
-+ distance
-+ = ( abs(cmapEntry[i].red - r1 * 65535 / rm)
-+ + abs(cmapEntry[i].green - g1 * 65535 / gm)
-+ + abs(cmapEntry[i].blue - b1 * 65535 / bm));
-+
-
- if (distance < minDistance) {
- minDistance = distance;
-@@ -412,7 +507,7 @@
- }
- }
-
-- BGR233ToPixel[(b<<6) | (g<<3) | r] = nearestPixel;
-+ BGR233ToPixel[(b<<bs) | (g<<gs) | (r<<rs)] = nearestPixel;
- if (shared[nearestPixel] && !usedAsNearest[nearestPixel])
- nSharedUsed++;
- usedAsNearest[nearestPixel] = True;
-@@ -433,6 +528,59 @@
- }
- }
-
-+static void
-+SetupBGR565Map(unsigned long red_mask, unsigned long green_mask, unsigned long blue_mask)
-+{
-+ int r, g, b;
-+ int r2, g2, b2;
-+ long idx;
-+ int cnt = 0;
-+ unsigned long pixel = 0;
-+
-+ for (r = 0; r < 32; r++) {
-+ for (g = 0; g < 64; g++) {
-+ for (b = 0; b < 32; b++) {
-+ int bs = 0, gs = 5, rs = 11;
-+ int bm = 31, gm = 63, rm = 31;
-+ if ((b > bm || g > gm || r > rm)) {
-+ continue;
-+ }
-+ r2 = (255 * r) / rm;
-+ g2 = (255 * g) / gm;
-+ b2 = (255 * b) / bm;
-+
-+ pixel = (r2 << 16) | (g2 << 8) | (b2 << 0);
-+ if (appData.useGreyScale) {
-+ int ave;
-+ int r1, g1, b1;
-+ ave = (2*r + g + 2*b)/3;
-+ r1 = ave/2;
-+ g1 = ave;
-+ b1 = ave/2;
-+
-+ r2 = (255 * r1) / rm;
-+ g2 = (255 * g1) / gm;
-+ b2 = (255 * b1) / bm;
-+
-+ pixel = (r2 << 16) | (g2 << 8) | (b2 << 0);
-+ }
-+
-+ if (red_mask == 0xff) {
-+ idx = (r<<bs) | (g<<gs) | (b<<rs);
-+ } else {
-+ idx = (b<<bs) | (g<<gs) | (r<<rs);
-+ }
-+ if (0) fprintf(stderr, "cnt: %5d idx: %lu pixel: 0x%08x\n", cnt, idx, (unsigned int) pixel);
-+ BGR565ToPixel[idx] = pixel;
-+ cnt++;
-+ }
-+ }
-+ }
-+ green_mask = 0;
-+ blue_mask = 0;
-+}
-+
-+
-
- /*
- * AllocateExactBGR233Colours() attempts to allocate each of the colours in the
-@@ -484,8 +632,13 @@
- ri = rn;
- for (gi = 0; gi < gn; gi++) {
- for (bi = 0; bi < bn; bi++) {
-- if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi]))
-- return;
-+ if (appData.useBGR233 == 64 && (bv[bi] > 3 || gv[gi] > 3 || rv[ri] > 3)) {
-+ nBGR233ColoursAllocated++;
-+ } else if (appData.useBGR233 == 8 && (bv[bi] > 1 || gv[gi] > 1 || rv[ri] > 1)) {
-+ nBGR233ColoursAllocated++;
-+ } else if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) {
-+ return;
-+ }
- }
- }
- rn++;
-@@ -496,8 +649,13 @@
- gi = gn;
- for (ri = 0; ri < rn; ri++) {
- for (bi = 0; bi < bn; bi++) {
-- if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi]))
-- return;
-+ if (appData.useBGR233 == 64 && (bv[bi] > 3 || gv[gi] > 3 || rv[ri] > 3)) {
-+ nBGR233ColoursAllocated++;
-+ } else if (appData.useBGR233 == 8 && (bv[bi] > 1 || gv[gi] > 1 || rv[ri] > 1)) {
-+ nBGR233ColoursAllocated++;
-+ } else if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) {
-+ return;
-+ }
- }
- }
- gn++;
-@@ -507,8 +665,13 @@
- bi = bn;
- for (ri = 0; ri < rn; ri++) {
- for (gi = 0; gi < gn; gi++) {
-- if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi]))
-- return;
-+ if (appData.useBGR233 == 64 && (bv[bi] > 3 || gv[gi] > 3 || rv[ri] > 3)) {
-+ nBGR233ColoursAllocated++;
-+ } else if (appData.useBGR233 == 8 && (bv[bi] > 1 || gv[gi] > 1 || rv[ri] > 1)) {
-+ nBGR233ColoursAllocated++;
-+ } else if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) {
-+ return;
-+ }
- }
- }
- bn++;
-@@ -529,18 +692,36 @@
- AllocateBGR233Colour(int r, int g, int b)
- {
- XColor c;
-+ int bs = 6, gs = 3, rs = 0;
-+ int bm = 3, gm = 7, rm = 7;
-
- if (nBGR233ColoursAllocated >= appData.nColours)
- return False;
-
-- c.red = r * 65535 / 7;
-- c.green = g * 65535 / 7;
-- c.blue = b * 65535 / 3;
-+ if (appData.useBGR233 == 64) {
-+ bs = 4; gs = 2, rs = 0;
-+ bm = 3; gm = 3; rm = 3;
-+ }
-+ if (appData.useBGR233 == 8) {
-+ bs = 2; gs = 1, rs = 0;
-+ bm = 1; gm = 1; rm = 1;
-+ }
-+
-+ c.red = r * 65535 / rm;
-+ c.green = g * 65535 / gm;
-+ c.blue = b * 65535 / bm;
-+ if (appData.useGreyScale) {
-+ int ave;
-+ ave = (c.red + c.green + c.blue)/3;
-+ c.red = ave;
-+ c.green = ave;
-+ c.blue = ave;
-+ }
-
- if (!XAllocColor(dpy, cmap, &c))
- return False;
-
-- BGR233ToPixel[(b<<6) | (g<<3) | r] = c.pixel;
-+ BGR233ToPixel[(b<<bs) | (g<<gs) | r] = c.pixel;
-
- nBGR233ColoursAllocated++;
-
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/corre.c vnc_unixsrc/vncviewer/corre.c
---- vnc_unixsrc.orig/vncviewer/corre.c 2000-06-11 08:00:53.000000000 -0400
-+++ vnc_unixsrc/vncviewer/corre.c 2008-10-05 15:16:01.000000000 -0400
-@@ -29,6 +29,18 @@
- #define HandleCoRREBPP CONCAT2E(HandleCoRRE,BPP)
- #define CARDBPP CONCAT2E(CARD,BPP)
-
-+#define FillRectangle(x, y, w, h, color) \
-+ { \
-+ XGCValues _gcv; \
-+ _gcv.foreground = color; \
-+ if (!appData.useXserverBackingStore) { \
-+ FillScreen(x, y, w, h, _gcv.foreground); \
-+ } else { \
-+ XChangeGC(dpy, gc, GCForeground, &_gcv); \
-+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \
-+ } \
-+ }
-+
- static Bool
- HandleCoRREBPP (int rx, int ry, int rw, int rh)
- {
-@@ -50,11 +62,19 @@
- #if (BPP == 8)
- gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
- #else
-+#if (BPP == 16)
-+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix);
-+#else
- gcv.foreground = pix;
- #endif
-+#endif
-
-+#if 0
- XChangeGC(dpy, gc, GCForeground, &gcv);
- XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);
-+#else
-+ FillRectangle(rx, ry, rw, rh, gcv.foreground);
-+#endif
-
- if (!ReadFromRFBServer(buffer, hdr.nSubrects * (4 + (BPP / 8))))
- return False;
-@@ -72,12 +92,22 @@
- #if (BPP == 8)
- gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
- #else
-+#if (BPP == 16)
-+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix);
-+#else
- gcv.foreground = pix;
- #endif
-+#endif
-
-+#if 0
- XChangeGC(dpy, gc, GCForeground, &gcv);
- XFillRectangle(dpy, desktopWin, gc, rx + x, ry + y, w, h);
-+#else
-+ FillRectangle(rx + x, ry + y, w, h, gcv.foreground);
-+#endif
- }
-
- return True;
- }
-+
-+#undef FillRectangle
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/cp_it vnc_unixsrc/vncviewer/cp_it
---- vnc_unixsrc.orig/vncviewer/cp_it 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/cp_it 2009-03-06 20:02:05.000000000 -0500
-@@ -0,0 +1,18 @@
-+#!/bin/sh
-+
-+dest=/dist/bin/vncviewerz-1.3dev5-resize
-+suc "cp -p $dest $dest.back; mv $dest $dest.unlink; mv $dest.back $dest; rm $dest.unlink"
-+strip ./vncviewer
-+cat ./vncviewer > $dest
-+touch -r ./vncviewer $dest
-+yy=/dist/src/apps/VNC/etc/libvncserver_cvs/expts/etv/ssvnc/bin/Linux.i686/vncviewer
-+mv $yy $yy.unlink
-+cp -p ./vncviewer $yy
-+mv $yy.turbovnc $yy.unlink.turbovnc
-+cp -p ./vncviewer $HOME/etv_col/Linux.i686
-+cp -p ./vncviewer.turbovnc $yy.turbovnc
-+cp -p ./vncviewer.turbovnc $HOME/etv_col/Linux.i686/vncviewer.turbovnc
-+chmod 755 $yy*
-+
-+rm -f $yy.unlink*
-+ls -l ./vncviewer* $dest $yy* $HOME/etv_col/Linux.i686/vncviewer*
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/cursor.c vnc_unixsrc/vncviewer/cursor.c
---- vnc_unixsrc.orig/vncviewer/cursor.c 2003-01-15 04:46:52.000000000 -0500
-+++ vnc_unixsrc/vncviewer/cursor.c 2010-02-25 22:04:28.000000000 -0500
-@@ -38,8 +38,11 @@
-
-
- static Bool prevSoftCursorSet = False;
--static Pixmap rcSavedArea;
--static CARD8 *rcSource, *rcMask;
-+static Pixmap rcSavedArea, rcSavedArea_0;
-+static int rcSavedArea_w = -1, rcSavedArea_h = -1;
-+static char *rcSavedScale = NULL;
-+static int rcSavedScale_len = 0;
-+static CARD8 *rcSource = NULL, *rcMask;
- static int rcHotX, rcHotY, rcWidth, rcHeight;
- static int rcCursorX = 0, rcCursorY = 0;
- static int rcLockX, rcLockY, rcLockWidth, rcLockHeight;
-@@ -48,8 +51,13 @@
- static Bool SoftCursorInLockedArea(void);
- static void SoftCursorCopyArea(int oper);
- static void SoftCursorDraw(void);
--static void FreeSoftCursor(void);
--static void FreeX11Cursor();
-+void FreeSoftCursor(void);
-+void FreeX11Cursor();
-+
-+extern XImage *image;
-+extern XImage *image_scale;
-+extern int scale_x, scale_y;
-+int scale_round(int n, double factor);
-
- /* Copied from Xvnc/lib/font/util/utilbitmap.c */
- static unsigned char _reverse_byte[0x100] = {
-@@ -91,6 +99,8 @@
- static Bool prevXCursorSet = False;
- static Cursor prevXCursor;
-
-+extern double scale_factor_x;
-+extern double scale_factor_y;
-
- Bool HandleXCursor(int xhot, int yhot, int width, int height)
- {
-@@ -124,7 +134,7 @@
- XQueryBestCursor(dpy, dr, width, height, &wret, &hret);
- }
-
-- if (width * height == 0 || wret < width || hret < height) {
-+ if (width * height == 0 || (int) wret < width || (int) hret < height) {
- /* Free resources */
- if (buf != NULL)
- free(buf);
-@@ -139,7 +149,7 @@
- fg.green = (unsigned short)colors.foreGreen << 8 | colors.foreGreen;
- fg.blue = (unsigned short)colors.foreBlue << 8 | colors.foreBlue;
-
-- for (i = 0; i < bytesData * 2; i++)
-+ for (i = 0; (size_t) i < bytesData * 2; i++)
- buf[i] = (char)_reverse_byte[(int)buf[i] & 0xFF];
-
- source = XCreateBitmapFromData(dpy, dr, buf, width, height);
-@@ -167,148 +177,179 @@
-
- Bool HandleCursorShape(int xhot, int yhot, int width, int height, CARD32 enc)
- {
-- int bytesPerPixel;
-- size_t bytesPerRow, bytesMaskData;
-- Drawable dr;
-- rfbXCursorColors rgb;
-- CARD32 colors[2];
-- char *buf;
-- CARD8 *ptr;
-- int x, y, b;
--
-- bytesPerPixel = myFormat.bitsPerPixel / 8;
-- bytesPerRow = (width + 7) / 8;
-- bytesMaskData = bytesPerRow * height;
-- dr = DefaultRootWindow(dpy);
--
-- FreeSoftCursor();
-+ int bytesPerPixel;
-+ size_t bytesPerRow, bytesMaskData;
-+ Drawable dr;
-+ rfbXCursorColors rgb;
-+ CARD32 colors[2];
-+ char *buf;
-+ CARD8 *ptr;
-+ int x, y, b;
-+
-+ bytesPerPixel = myFormat.bitsPerPixel / 8;
-+ bytesPerRow = (width + 7) / 8;
-+ bytesMaskData = bytesPerRow * height;
-+ dr = DefaultRootWindow(dpy);
-
-- if (width * height == 0)
-- return True;
--
-- /* Allocate memory for pixel data and temporary mask data. */
-+ FreeSoftCursor();
-
-- rcSource = malloc(width * height * bytesPerPixel);
-- if (rcSource == NULL)
-- return False;
--
-- buf = malloc(bytesMaskData);
-- if (buf == NULL) {
-- free(rcSource);
-- return False;
-- }
-+ if (width * height == 0) {
-+ return True;
-+ }
-
-- /* Read and decode cursor pixel data, depending on the encoding type. */
-+ /* Allocate memory for pixel data and temporary mask data. */
-
-- if (enc == rfbEncodingXCursor) {
-- if (appData.useX11Cursor) {
-- HandleXCursor(xhot, yhot, width, height);
-- return True;
-- }
-+ rcSource = malloc(width * height * bytesPerPixel);
-+ if (rcSource == NULL) {
-+ return False;
-+ }
-
-- /* Read and convert background and foreground colors. */
-- if (!ReadFromRFBServer((char *)&rgb, sz_rfbXCursorColors)) {
-- free(rcSource);
-- free(buf);
-- return False;
-- }
-- colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue);
-- colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue);
-+ buf = malloc(bytesMaskData);
-+ if (buf == NULL) {
-+ free(rcSource);
-+ rcSource = NULL;
-+ return False;
-+ }
-
-- /* Read 1bpp pixel data into a temporary buffer. */
-- if (!ReadFromRFBServer(buf, bytesMaskData)) {
-- free(rcSource);
-- free(buf);
-- return False;
-- }
-+ /* Read and decode cursor pixel data, depending on the encoding type. */
-
-- /* Convert 1bpp data to byte-wide color indices. */
-- ptr = rcSource;
-- for (y = 0; y < height; y++) {
-- for (x = 0; x < width / 8; x++) {
-- for (b = 7; b >= 0; b--) {
-- *ptr = buf[y * bytesPerRow + x] >> b & 1;
-- ptr += bytesPerPixel;
-- }
-- }
-- for (b = 7; b > 7 - width % 8; b--) {
-- *ptr = buf[y * bytesPerRow + x] >> b & 1;
-- ptr += bytesPerPixel;
-- }
-- }
-+ if (enc == rfbEncodingXCursor) {
-+ if (appData.useX11Cursor) {
-+ HandleXCursor(xhot, yhot, width, height);
-+ return True;
-+ }
-+
-+ /* Read and convert background and foreground colors. */
-+ if (!ReadFromRFBServer((char *)&rgb, sz_rfbXCursorColors)) {
-+ free(rcSource);
-+ rcSource = NULL;
-+ free(buf);
-+ return False;
-+ }
-+ colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue);
-+ colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue);
-+
-+ /* Read 1bpp pixel data into a temporary buffer. */
-+ if (!ReadFromRFBServer(buf, bytesMaskData)) {
-+ free(rcSource);
-+ rcSource = NULL;
-+ free(buf);
-+ return False;
-+ }
-+
-+ /* Convert 1bpp data to byte-wide color indices. */
-+ ptr = rcSource;
-+ for (y = 0; y < height; y++) {
-+ for (x = 0; x < width / 8; x++) {
-+ for (b = 7; b >= 0; b--) {
-+ *ptr = buf[y * bytesPerRow + x] >> b & 1;
-+ ptr += bytesPerPixel;
-+ }
-+ }
-+ for (b = 7; b > 7 - width % 8; b--) {
-+ *ptr = buf[y * bytesPerRow + x] >> b & 1;
-+ ptr += bytesPerPixel;
-+ }
-+ }
-+
-+ /* Convert indices into the actual pixel values. */
-+ switch (bytesPerPixel) {
-+ case 1:
-+ for (x = 0; x < width * height; x++) {
-+ rcSource[x] = (CARD8)colors[rcSource[x]];
-+ }
-+ break;
-+ case 2:
-+ for (x = 0; x < width * height; x++) {
-+ ((CARD16 *)rcSource)[x] = (CARD16)colors[rcSource[x * 2]];
-+ }
-+ break;
-+ case 4:
-+ for (x = 0; x < width * height; x++) {
-+ ((CARD32 *)rcSource)[x] = colors[rcSource[x * 4]];
-+ }
-+ break;
-+ }
-+
-+ } else { /* enc == rfbEncodingRichCursor */
-+ if (!ReadFromRFBServer((char *)rcSource, width * height * bytesPerPixel)) {
-+ free(rcSource);
-+ rcSource = NULL;
-+ free(buf);
-+ return False;
-+ }
-+ }
-
-- /* Convert indices into the actual pixel values. */
-- switch (bytesPerPixel) {
-- case 1:
-- for (x = 0; x < width * height; x++)
-- rcSource[x] = (CARD8)colors[rcSource[x]];
-- break;
-- case 2:
-- for (x = 0; x < width * height; x++)
-- ((CARD16 *)rcSource)[x] = (CARD16)colors[rcSource[x * 2]];
-- break;
-- case 4:
-- for (x = 0; x < width * height; x++)
-- ((CARD32 *)rcSource)[x] = colors[rcSource[x * 4]];
-- break;
-- }
-+ /* Read and decode mask data. */
-
-- } else { /* enc == rfbEncodingRichCursor */
-+ if (!ReadFromRFBServer(buf, bytesMaskData)) {
-+ free(rcSource);
-+ rcSource = NULL;
-+ free(buf);
-+ return False;
-+ }
-
-- if (!ReadFromRFBServer((char *)rcSource, width * height * bytesPerPixel)) {
-- free(rcSource);
-- free(buf);
-- return False;
-- }
-+ rcMask = malloc(width * height);
-+ if (rcMask == NULL) {
-+ free(rcSource);
-+ rcSource = NULL;
-+ free(buf);
-+ return False;
-+ }
-
-- }
-+ ptr = rcMask;
-+ for (y = 0; y < height; y++) {
-+ for (x = 0; x < width / 8; x++) {
-+ for (b = 7; b >= 0; b--) {
-+ *ptr++ = buf[y * bytesPerRow + x] >> b & 1;
-+ }
-+ }
-+ for (b = 7; b > 7 - width % 8; b--) {
-+ *ptr++ = buf[y * bytesPerRow + x] >> b & 1;
-+ }
-+ }
-
-- /* Read and decode mask data. */
-+ free(buf);
-
-- if (!ReadFromRFBServer(buf, bytesMaskData)) {
-- free(rcSource);
-- free(buf);
-- return False;
-- }
-+ /* Set remaining data associated with cursor. */
-
-- rcMask = malloc(width * height);
-- if (rcMask == NULL) {
-- free(rcSource);
-- free(buf);
-- return False;
-- }
-+ dr = DefaultRootWindow(dpy);
-
-- ptr = rcMask;
-- for (y = 0; y < height; y++) {
-- for (x = 0; x < width / 8; x++) {
-- for (b = 7; b >= 0; b--) {
-- *ptr++ = buf[y * bytesPerRow + x] >> b & 1;
-- }
-- }
-- for (b = 7; b > 7 - width % 8; b--) {
-- *ptr++ = buf[y * bytesPerRow + x] >> b & 1;
-- }
-- }
-+ if (scale_x > 0) {
-+ int w = scale_round(width, scale_factor_x) + 2;
-+ int h = scale_round(height, scale_factor_y) + 2;
-+ rcSavedArea = XCreatePixmap(dpy, dr, w, h, visdepth);
-+ rcSavedArea_w = w;
-+ rcSavedArea_h = h;
-+ } else {
-+ rcSavedArea = XCreatePixmap(dpy, dr, width, height, visdepth);
-+ rcSavedArea_w = width;
-+ rcSavedArea_h = height;
-+ }
-+ rcSavedArea_0 = XCreatePixmap(dpy, dr, width, height, visdepth);
-
-- free(buf);
-+if (0) fprintf(stderr, "rcSavedArea_wh: %d %d scale_x: %d\n", rcSavedArea_w, rcSavedArea_h, scale_x);
-
-- /* Set remaining data associated with cursor. */
-+ if (rcSavedScale_len < 4 * width * height + 4096) {
-+ if (rcSavedScale) {
-+ free(rcSavedScale);
-+ }
-+ rcSavedScale = (char *) malloc(2 * 4 * width * height + 4096);
-+ }
-
-- dr = DefaultRootWindow(dpy);
-- rcSavedArea = XCreatePixmap(dpy, dr, width, height, visdepth);
-- rcHotX = xhot;
-- rcHotY = yhot;
-- rcWidth = width;
-- rcHeight = height;
-+ rcHotX = xhot;
-+ rcHotY = yhot;
-+ rcWidth = width;
-+ rcHeight = height;
-
-- SoftCursorCopyArea(OPER_SAVE);
-- SoftCursorDraw();
-+ SoftCursorCopyArea(OPER_SAVE);
-+ SoftCursorDraw();
-
-- rcCursorHidden = False;
-- rcLockSet = False;
-+ rcCursorHidden = False;
-+ rcLockSet = False;
-
-- prevSoftCursorSet = True;
-- return True;
-+ prevSoftCursorSet = True;
-+ return True;
- }
-
- /*********************************************************************
-@@ -319,20 +360,27 @@
-
- Bool HandleCursorPos(int x, int y)
- {
-- if (appData.useX11Cursor) {
-- if (appData.fullScreen)
-- XWarpPointer(dpy, None, desktopWin, 0, 0, 0, 0, x, y);
--
-- return True;
-- }
-+ if (x < 0) x = 0;
-+ if (y < 0) y = 0;
-
-- if (x >= si.framebufferWidth)
-- x = si.framebufferWidth - 1;
-- if (y >= si.framebufferHeight)
-- y = si.framebufferHeight - 1;
-+ /* fprintf(stderr, "xy: %d %d\n", x, y); */
-
-- SoftCursorMove(x, y);
-- return True;
-+ if (x >= si.framebufferWidth) {
-+ x = si.framebufferWidth - 1;
-+ }
-+ if (y >= si.framebufferHeight) {
-+ y = si.framebufferHeight - 1;
-+ }
-+
-+ if (appData.useX11Cursor) {
-+ if (appData.fullScreen) {
-+ XWarpPointer(dpy, None, desktopWin, 0, 0, 0, 0, x, y);
-+ }
-+ return True;
-+ }
-+
-+ SoftCursorMove(x, y);
-+ return True;
- }
-
- /*********************************************************************
-@@ -348,30 +396,31 @@
- {
- int newX, newY;
-
-- if (!prevSoftCursorSet)
-- return;
-+ if (!prevSoftCursorSet) {
-+ return;
-+ }
-
-- if (!rcLockSet) {
-- rcLockX = x;
-- rcLockY = y;
-- rcLockWidth = w;
-- rcLockHeight = h;
-- rcLockSet = True;
-- } else {
-- newX = (x < rcLockX) ? x : rcLockX;
-- newY = (y < rcLockY) ? y : rcLockY;
-- rcLockWidth = (x + w > rcLockX + rcLockWidth) ?
-- (x + w - newX) : (rcLockX + rcLockWidth - newX);
-- rcLockHeight = (y + h > rcLockY + rcLockHeight) ?
-- (y + h - newY) : (rcLockY + rcLockHeight - newY);
-- rcLockX = newX;
-- rcLockY = newY;
-- }
-+ if (!rcLockSet) {
-+ rcLockX = x;
-+ rcLockY = y;
-+ rcLockWidth = w;
-+ rcLockHeight = h;
-+ rcLockSet = True;
-+ } else {
-+ newX = (x < rcLockX) ? x : rcLockX;
-+ newY = (y < rcLockY) ? y : rcLockY;
-+ rcLockWidth = (x + w > rcLockX + rcLockWidth) ?
-+ (x + w - newX) : (rcLockX + rcLockWidth - newX);
-+ rcLockHeight = (y + h > rcLockY + rcLockHeight) ?
-+ (y + h - newY) : (rcLockY + rcLockHeight - newY);
-+ rcLockX = newX;
-+ rcLockY = newY;
-+ }
-
-- if (!rcCursorHidden && SoftCursorInLockedArea()) {
-- SoftCursorCopyArea(OPER_RESTORE);
-- rcCursorHidden = True;
-- }
-+ if (!rcCursorHidden && SoftCursorInLockedArea()) {
-+ SoftCursorCopyArea(OPER_RESTORE);
-+ rcCursorHidden = True;
-+ }
- }
-
- /*********************************************************************
-@@ -381,15 +430,16 @@
-
- void SoftCursorUnlockScreen(void)
- {
-- if (!prevSoftCursorSet)
-- return;
-+ if (!prevSoftCursorSet) {
-+ return;
-+ }
-
-- if (rcCursorHidden) {
-- SoftCursorCopyArea(OPER_SAVE);
-- SoftCursorDraw();
-- rcCursorHidden = False;
-- }
-- rcLockSet = False;
-+ if (rcCursorHidden) {
-+ SoftCursorCopyArea(OPER_SAVE);
-+ SoftCursorDraw();
-+ rcCursorHidden = False;
-+ }
-+ rcLockSet = False;
- }
-
- /*********************************************************************
-@@ -401,19 +451,19 @@
-
- void SoftCursorMove(int x, int y)
- {
-- if (prevSoftCursorSet && !rcCursorHidden) {
-- SoftCursorCopyArea(OPER_RESTORE);
-- rcCursorHidden = True;
-- }
-+ if (prevSoftCursorSet && !rcCursorHidden) {
-+ SoftCursorCopyArea(OPER_RESTORE);
-+ rcCursorHidden = True;
-+ }
-
-- rcCursorX = x;
-- rcCursorY = y;
-+ rcCursorX = x;
-+ rcCursorY = y;
-
-- if (prevSoftCursorSet && !(rcLockSet && SoftCursorInLockedArea())) {
-- SoftCursorCopyArea(OPER_SAVE);
-- SoftCursorDraw();
-- rcCursorHidden = False;
-- }
-+ if (prevSoftCursorSet && !(rcLockSet && SoftCursorInLockedArea())) {
-+ SoftCursorCopyArea(OPER_SAVE);
-+ SoftCursorDraw();
-+ rcCursorHidden = False;
-+ }
- }
-
-
-@@ -429,41 +479,169 @@
- rcLockY + rcLockHeight > rcCursorY - rcHotY);
- }
-
--static void SoftCursorCopyArea(int oper)
--{
-- int x, y, w, h;
-+void new_pixmap(int w, int h) {
-
-- x = rcCursorX - rcHotX;
-- y = rcCursorY - rcHotY;
-- if (x >= si.framebufferWidth || y >= si.framebufferHeight)
-- return;
--
-- w = rcWidth;
-- h = rcHeight;
-- if (x < 0) {
-- w += x;
-- x = 0;
-- } else if (x + w > si.framebufferWidth) {
-- w = si.framebufferWidth - x;
-- }
-- if (y < 0) {
-- h += y;
-- y = 0;
-- } else if (y + h > si.framebufferHeight) {
-- h = si.framebufferHeight - y;
-- }
-+ XFreePixmap(dpy, rcSavedArea);
-
-- if (oper == OPER_SAVE) {
-- /* Save screen area in memory. */
--#ifdef MITSHM
-- if (appData.useShm)
-- XSync(dpy, False);
--#endif
-- XCopyArea(dpy, desktopWin, rcSavedArea, gc, x, y, w, h, 0, 0);
-- } else {
-- /* Restore screen area. */
-- XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, w, h, x, y);
-- }
-+ if (w > 0 && h > 0) {
-+ rcSavedArea = XCreatePixmap(dpy, DefaultRootWindow(dpy), w, h, visdepth);
-+ rcSavedArea_w = w;
-+ rcSavedArea_h = h;
-+
-+ } else if (image_scale != NULL && scale_x > 0) {
-+ int w2 = scale_round(rcWidth, scale_factor_x) + 2;
-+ int h2 = scale_round(rcHeight, scale_factor_y) + 2;
-+ rcSavedArea = XCreatePixmap(dpy, DefaultRootWindow(dpy), w2, h2, visdepth);
-+ rcSavedArea_w = w2;
-+ rcSavedArea_h = h2;
-+ } else {
-+ rcSavedArea = XCreatePixmap(dpy, DefaultRootWindow(dpy), rcWidth, rcHeight, visdepth);
-+ rcSavedArea_w = rcWidth;
-+ rcSavedArea_h = rcHeight;
-+ }
-+}
-+
-+extern int XError_ign;
-+
-+static void SoftCursorCopyArea(int oper) {
-+ int x, y, w, h;
-+ int xs = 0, ys = 0, ws = 0, hs = 0;
-+ static int scale_saved = 0, ss_w, ss_h;
-+ int db = 0;
-+
-+ x = rcCursorX - rcHotX;
-+ y = rcCursorY - rcHotY;
-+ if (x >= si.framebufferWidth || y >= si.framebufferHeight) {
-+ return;
-+ }
-+
-+ w = rcWidth;
-+ h = rcHeight;
-+ if (x < 0) {
-+ w += x;
-+ x = 0;
-+ } else if (x + w > si.framebufferWidth) {
-+ w = si.framebufferWidth - x;
-+ }
-+ if (y < 0) {
-+ h += y;
-+ y = 0;
-+ } else if (y + h > si.framebufferHeight) {
-+ h = si.framebufferHeight - y;
-+ }
-+
-+ if (image_scale != NULL && scale_x > 0) {
-+ xs = (int) (x * scale_factor_x);
-+ ys = (int) (y * scale_factor_y);
-+ ws = scale_round(w, scale_factor_x);
-+ hs = scale_round(h, scale_factor_y);
-+
-+ if (xs > 0) xs -= 1;
-+ if (ys > 0) ys -= 1;
-+ ws += 2;
-+ hs += 2;
-+ }
-+
-+ XError_ign = 1;
-+
-+ if (oper == OPER_SAVE) {
-+ /* Save screen area in memory. */
-+ scale_saved = 0;
-+ if (appData.useXserverBackingStore) {
-+ XSync(dpy, False);
-+ XCopyArea(dpy, desktopWin, rcSavedArea, gc, x, y, w, h, 0, 0);
-+ } else {
-+ if (image_scale != NULL && scale_x > 0) {
-+ int Bpp = image_scale->bits_per_pixel / 8;
-+ int Bpl = image_scale->bytes_per_line;
-+ int i;
-+ char *src = image_scale->data + y * Bpl + x * Bpp;
-+ char *dst = rcSavedScale;
-+
-+ if (ws > rcSavedArea_w || hs > rcSavedArea_h) {
-+ new_pixmap(0, 0);
-+ }
-+
-+if (db) fprintf(stderr, "save: %dx%d+%d+%d\n", ws, hs, xs, ys);
-+
-+ XPutImage(dpy, rcSavedArea, gc, image, xs, ys, 0, 0, ws, hs);
-+
-+ XPutImage(dpy, rcSavedArea_0, gc, image_scale, x, y, 0, 0, w, h);
-+
-+ scale_saved = 1;
-+ ss_w = ws;
-+ ss_h = hs;
-+
-+ for (i=0; i < h; i++) {
-+ memcpy(dst, src, Bpp * w);
-+ src += Bpl;
-+ dst += Bpp * w;
-+ }
-+ } else {
-+if (db) fprintf(stderr, "SAVE: %dx%d+%d+%d\n", w, h, x, y);
-+ if (w > rcSavedArea_w || h > rcSavedArea_h) {
-+ new_pixmap(0, 0);
-+ }
-+
-+ XPutImage(dpy, rcSavedArea, gc, image, x, y, 0, 0, w, h);
-+ }
-+ }
-+ } else {
-+
-+#define XE(s) if (XError_ign > 1) {fprintf(stderr, "X-%d\n", (s)); db = 1;}
-+
-+ /* Restore screen area. */
-+ if (appData.useXserverBackingStore) {
-+ XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, w, h, x, y);
-+XE(1)
-+ XGetSubImage(dpy, rcSavedArea, 0, 0, w, h, AllPlanes, ZPixmap, image, x, y);
-+XE(2)
-+
-+ } else {
-+ if (image_scale != NULL && scale_x > 0) {
-+ int Bpp = image_scale->bits_per_pixel / 8;
-+ int Bpl = image_scale->bytes_per_line;
-+ int i;
-+ char *dst = image_scale->data + y * Bpl + x * Bpp;
-+ char *src = rcSavedScale;
-+
-+ XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, ws, hs, xs, ys);
-+XE(3)
-+ XGetSubImage(dpy, rcSavedArea, 0, 0, ws, hs, AllPlanes, ZPixmap, image, xs, ys);
-+XE(4)
-+if (db) fprintf(stderr, "rstr: %dx%d+%d+%d\n", ws, hs, xs, ys);
-+
-+ for (i=0; i < h; i++) {
-+ memcpy(dst, src, Bpp * w);
-+ src += Bpp * w;
-+ dst += Bpl;
-+ }
-+ } else {
-+
-+ if (scale_saved) {
-+ XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, ss_w, ss_h, x, y);
-+XE(5)
-+ XGetSubImage(dpy, rcSavedArea, 0, 0, ss_w, ss_h, AllPlanes, ZPixmap, image, x, y);
-+XE(6)
-+ new_pixmap(w, h);
-+ } else {
-+ XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, w, h, x, y);
-+XE(7)
-+ XGetSubImage(dpy, rcSavedArea, 0, 0, w, h, AllPlanes, ZPixmap, image, x, y);
-+XE(8)
-+ }
-+
-+if (db) fprintf(stderr, "RSTR: %dx%d+%d+%d\n", w, h, x, y);
-+
-+ }
-+ }
-+ }
-+
-+ if (XError_ign > 1) {
-+ fprintf(stderr, "XError_ign: %d, oper: %s\n", XError_ign, oper ? "restore" : "save");
-+ }
-+
-+ XError_ign = 0;
- }
-
- static void SoftCursorDraw(void)
-@@ -472,43 +650,182 @@
- int offset, bytesPerPixel;
- char *pos;
-
-+#define alphahack
-+#ifdef alphahack
-+ /* hack to have cursor transparency at 32bpp <runge@karlrunge.com> */
-+ int alphablend = 0;
-+
-+ if (!rcSource) {
-+ return;
-+ }
-+
-+ if (appData.useCursorAlpha) {
-+ alphablend = 1;
-+ }
-+
- bytesPerPixel = myFormat.bitsPerPixel / 8;
-
-- /* FIXME: Speed optimization is possible. */
-- for (y = 0; y < rcHeight; y++) {
-- y0 = rcCursorY - rcHotY + y;
-- if (y0 >= 0 && y0 < si.framebufferHeight) {
-- for (x = 0; x < rcWidth; x++) {
-- x0 = rcCursorX - rcHotX + x;
-- if (x0 >= 0 && x0 < si.framebufferWidth) {
-- offset = y * rcWidth + x;
-- if (rcMask[offset]) {
-- pos = (char *)&rcSource[offset * bytesPerPixel];
-- CopyDataToScreen(pos, x0, y0, 1, 1);
-- }
-+ if (alphablend && bytesPerPixel == 4) {
-+ unsigned long pixel, put, *upos, *upix;
-+ int got_alpha = 0, rsX, rsY, rsW, rsH;
-+ static XImage *alpha_image = NULL;
-+ static int iwidth = 192;
-+
-+ if (! alpha_image) {
-+ /* watch out for tiny fb (rare) */
-+ if (iwidth > si.framebufferWidth) {
-+ iwidth = si.framebufferWidth;
-+ }
-+ if (iwidth > si.framebufferHeight) {
-+ iwidth = si.framebufferHeight;
-+ }
-+
-+ /* initialize an XImage with a chunk of desktopWin */
-+ alpha_image = XGetImage(dpy, desktopWin, 0, 0, iwidth, iwidth,
-+ AllPlanes, ZPixmap);
- }
-- }
-- }
-+
-+ /* first check if there is any non-zero alpha channel data at all: */
-+ for (y = 0; y < rcHeight; y++) {
-+ for (x = 0; x < rcWidth; x++) {
-+ int alpha;
-+
-+ offset = y * rcWidth + x;
-+ pos = (char *)&rcSource[offset * bytesPerPixel];
-+
-+ upos = (unsigned long *) pos;
-+ alpha = (*upos & 0xff000000) >> 24;
-+ if (alpha) {
-+ got_alpha = 1;
-+ break;
-+ }
-+ }
-+ if (got_alpha) {
-+ break;
-+ }
-+ }
-+
-+ if (!got_alpha) {
-+ /* no alpha channel data, fallback to the old way */
-+ goto oldway;
-+ }
-+
-+ /* load the saved fb patch in to alpha_image (faster way?) */
-+ if (image_scale != NULL && scale_x > 0) {
-+ XGetSubImage(dpy, rcSavedArea_0, 0, 0, rcWidth, rcHeight, AllPlanes, ZPixmap, alpha_image, 0, 0);
-+ } else {
-+ XGetSubImage(dpy, rcSavedArea, 0, 0, rcWidth, rcHeight, AllPlanes, ZPixmap, alpha_image, 0, 0);
-+ }
-+
-+ upix = (unsigned long *)alpha_image->data;
-+
-+ /* if the richcursor is clipped, the fb patch will be smaller */
-+ rsW = rcWidth;
-+ rsX = 0; /* used to denote a shift from the left side */
-+ x = rcCursorX - rcHotX;
-+ if (x < 0) {
-+ rsW += x;
-+ rsX = -x;
-+ } else if (x + rsW > si.framebufferWidth) {
-+ rsW = si.framebufferWidth - x;
-+ }
-+ rsH = rcHeight;
-+ rsY = 0; /* used to denote a shift from the top side */
-+ y = rcCursorY - rcHotY;
-+ if (y < 0) {
-+ rsH += y;
-+ rsY = -y;
-+ } else if (y + rsH > si.framebufferHeight) {
-+ rsH = si.framebufferHeight - y;
-+ }
-+
-+ /*
-+ * now loop over the cursor data, blend in the fb values,
-+ * and then overwrite the fb (CopyDataToScreen())
-+ */
-+ for (y = 0; y < rcHeight; y++) {
-+ y0 = rcCursorY - rcHotY + y;
-+ if (y0 < 0 || y0 >= si.framebufferHeight) {
-+ continue; /* clipped */
-+ }
-+ for (x = 0; x < rcWidth; x++) {
-+ int alpha, color_curs, color_fb, i;
-+
-+ x0 = rcCursorX - rcHotX + x;
-+ if (x0 < 0 || x0 >= si.framebufferWidth) {
-+ continue; /* clipped */
-+ }
-+
-+ offset = y * rcWidth + x;
-+ pos = (char *)&rcSource[offset * bytesPerPixel];
-+
-+ /* extract secret alpha byte from rich cursor: */
-+ upos = (unsigned long *) pos;
-+ alpha = (*upos & 0xff000000) >> 24; /* XXX MSB? */
-+
-+ /* extract the pixel from the fb: */
-+ pixel = *(upix + (y-rsY)*iwidth + (x-rsX));
-+
-+ put = 0;
-+ /* for simplicity, blend all 4 bytes */
-+ for (i = 0; i < 4; i++) {
-+ int sh = i*8;
-+ color_curs = ((0xff << sh) & *upos) >> sh;
-+ color_fb = ((0xff << sh) & pixel) >> sh;
-+
-+ /* XXX assumes pre-multipled color_curs */
-+ color_fb = color_curs
-+ + ((0xff - alpha) * color_fb)/0xff;
-+ put |= color_fb << sh;
-+ }
-+ /* place in the fb: */
-+ CopyDataToScreen((char *)&put, x0, y0, 1, 1);
-+ }
-+ }
-+ return;
- }
-+oldway:
-+#endif
-+
-+ bytesPerPixel = myFormat.bitsPerPixel / 8;
-+
-+ /* FIXME: Speed optimization is possible. */
-+ for (y = 0; y < rcHeight; y++) {
-+ y0 = rcCursorY - rcHotY + y;
-+ if (y0 >= 0 && y0 < si.framebufferHeight) {
-+ for (x = 0; x < rcWidth; x++) {
-+ x0 = rcCursorX - rcHotX + x;
-+ if (x0 >= 0 && x0 < si.framebufferWidth) {
-+ offset = y * rcWidth + x;
-+ if (rcMask[offset]) {
-+ pos = (char *)&rcSource[offset * bytesPerPixel];
-+ CopyDataToScreen(pos, x0, y0, 1, 1);
-+ }
-+ }
-+ }
-+ }
-+ }
-+ XSync(dpy, False);
- }
-
--static void FreeSoftCursor(void)
-+void FreeSoftCursor(void)
- {
-- if (prevSoftCursorSet) {
-- SoftCursorCopyArea(OPER_RESTORE);
-- XFreePixmap(dpy, rcSavedArea);
-- free(rcSource);
-- free(rcMask);
-- prevSoftCursorSet = False;
-- }
-+ if (prevSoftCursorSet) {
-+ SoftCursorCopyArea(OPER_RESTORE);
-+ XFreePixmap(dpy, rcSavedArea);
-+ XFreePixmap(dpy, rcSavedArea_0);
-+ free(rcSource);
-+ rcSource = NULL;
-+ free(rcMask);
-+ prevSoftCursorSet = False;
-+ }
- }
-
-
--static void FreeX11Cursor()
-+void FreeX11Cursor()
- {
-- if (prevXCursorSet) {
-- XFreeCursor(dpy, prevXCursor);
-- prevXCursorSet = False;
-- }
-+ if (prevXCursorSet) {
-+ XFreeCursor(dpy, prevXCursor);
-+ prevXCursorSet = False;
-+ }
- }
--
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncviewer/desktop.c
---- vnc_unixsrc.orig/vncviewer/desktop.c 2004-05-28 13:29:29.000000000 -0400
-+++ vnc_unixsrc/vncviewer/desktop.c 2010-02-25 22:32:49.000000000 -0500
-@@ -28,28 +28,497 @@
- #include <X11/extensions/XShm.h>
- #endif
-
-+#include <X11/cursorfont.h>
-+
- GC gc;
- GC srcGC, dstGC; /* used for debugging copyrect */
- Window desktopWin;
--Cursor dotCursor;
-+Cursor dotCursor3 = None;
-+Cursor dotCursor4 = None;
-+Cursor bogoCursor = None;
-+Cursor waitCursor = None;
- Widget form, viewport, desktop;
-
-+int appshare_0_hint = -10000;
-+int appshare_x_hint = -10000;
-+int appshare_y_hint = -10000;
-+
- static Bool modifierPressed[256];
-
--static XImage *image = NULL;
-+XImage *image = NULL;
-+XImage *image_ycrop = NULL;
-+XImage *image_scale = NULL;
-+
-+int image_is_shm = 0;
-
- static Cursor CreateDotCursor();
- static void CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width,int height);
- static void HandleBasicDesktopEvent(Widget w, XtPointer ptr, XEvent *ev,
- Boolean *cont);
-
-+static void CopyBGR565ToScreen(CARD16 *buf, int x, int y, int width,int height);
-+
- static XtResource desktopBackingStoreResources[] = {
- {
-- XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof(int), 0,
-- XtRImmediate, (XtPointer) Always,
-+ XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof(int), 0,
-+ XtRImmediate, (XtPointer) Always,
- },
- };
-
-+double scale_factor_x = 0.0;
-+double scale_factor_y = 0.0;
-+int scale_x = 0, scale_y = 0;
-+int scale_round(int len, double fac);
-+
-+double last_rescale = 0.0;
-+double last_fullscreen = 0.0;
-+double start_time = 0.0;
-+
-+int prev_fb_width = -1;
-+int prev_fb_height = -1;
-+
-+void get_scale_values(double *fx, double *fy) {
-+ char *s = appData.scale;
-+ double f, frac_x = -1.0, frac_y = -1.0;
-+ int n, m;
-+ int xmax = si.framebufferWidth;
-+ int ymax = si.framebufferHeight;
-+
-+ if (appData.yCrop > 0) {
-+ ymax = appData.yCrop;
-+ }
-+
-+ if (sscanf(s, "%d/%d", &n, &m) == 2) {
-+ if (m == 0) {
-+ frac_x = 1.0;
-+ } else {
-+ frac_x = ((double) n) / ((double) m);
-+ }
-+ }
-+ if (sscanf(s, "%dx%d", &n, &m) == 2) {
-+ frac_x = ((double) n) / ((double) xmax);
-+ frac_y = ((double) m) / ((double) ymax);
-+ }
-+ if (!strcasecmp(s, "fit")) {
-+ frac_x = ((double) dpyWidth) / ((double) xmax);
-+ frac_y = ((double) dpyHeight) / ((double) ymax);
-+ }
-+ if (!strcasecmp(s, "auto")) {
-+ Dimension w, h;
-+ XtVaGetValues(toplevel, XtNheight, &h, XtNwidth, &w, NULL);
-+ fprintf(stderr, "auto: %dx%d\n", w, h);
-+ if (w > 32 && h > 32) {
-+ frac_x = ((double) w) / ((double) xmax);
-+ frac_y = ((double) h) / ((double) ymax);
-+ }
-+ }
-+ if (frac_x < 0.0 && sscanf(s, "%lf", &f) == 1) {
-+ if (f > 0.0) {
-+ frac_x = f;
-+ }
-+ }
-+
-+ if (frac_y < 0.0) {
-+ frac_y = frac_x;
-+ }
-+
-+ if (frac_y > 0.0 && frac_x > 0.0) {
-+ if (fx != NULL) {
-+ *fx = frac_x;
-+ }
-+ if (fy != NULL) {
-+ *fy = frac_y;
-+ }
-+ } else {
-+ if (appData.scale) {
-+ fprintf(stderr, "Invalid scale string: '%s'\n", appData.scale);
-+ } else {
-+ fprintf(stderr, "Invalid scale string.\n");
-+ }
-+ appData.scale = NULL;
-+ }
-+}
-+
-+void try_create_image(void);
-+void put_image(int src_x, int src_y, int dst_x, int dst_y, int width, int height, int solid);
-+void create_image();
-+
-+/* toplevel -> form -> viewport -> desktop */
-+
-+void adjust_Xt_win(int w, int h) {
-+ int x, y, dw, dh, h0 = h;
-+ int mw = w, mh = h;
-+ int autoscale = 0;
-+
-+ if (!appData.fullScreen && appData.scale != NULL && !strcmp(appData.scale, "auto")) {
-+ autoscale = 1;
-+ mw = dpyWidth;
-+ mh = dpyHeight;
-+ }
-+
-+ if (appData.yCrop > 0) {
-+ int ycrop = appData.yCrop;
-+ if (image_scale && scale_factor_y > 0.0) {
-+ ycrop = scale_round(ycrop, scale_factor_y);
-+ if (!autoscale) {
-+ mh = ycrop;
-+ }
-+ }
-+ XtVaSetValues(toplevel, XtNmaxWidth, mw, XtNmaxHeight, mh, XtNwidth, w, XtNheight, ycrop, NULL);
-+ XtVaSetValues(form, XtNmaxWidth, mw, XtNmaxHeight, mh, XtNwidth, w, XtNheight, ycrop, NULL);
-+ h0 = ycrop;
-+ } else {
-+ XtVaSetValues(toplevel, XtNmaxWidth, mw, XtNmaxHeight, mh, XtNwidth, w, XtNheight, h, NULL);
-+ }
-+
-+ fprintf(stderr, "adjust_Xt_win: %dx%d & %dx%d\n", w, h, w, h0);
-+
-+ XtVaSetValues(desktop, XtNwidth, w, XtNheight, h, NULL);
-+
-+ XtResizeWidget(desktop, w, h, 0);
-+
-+ if (!autoscale) {
-+ dw = appData.wmDecorationWidth;
-+ dh = appData.wmDecorationHeight;
-+
-+ x = (dpyWidth - w - dw)/2;
-+ y = (dpyHeight - h0 - dh)/2;
-+
-+ XtConfigureWidget(toplevel, x + dw, y + dh, w, h0, 0);
-+ }
-+}
-+
-+void rescale_image(void) {
-+ double frac_x, frac_y;
-+ int w, h;
-+
-+ if (image == NULL) {
-+ create_image();
-+ return;
-+ }
-+
-+ if (appData.useXserverBackingStore) {
-+ create_image();
-+ return;
-+ }
-+
-+ if (image == NULL && image_scale == NULL) {
-+ create_image();
-+ return;
-+ }
-+
-+ if (appData.scale == NULL) {
-+ /* switching to not scaled */
-+ frac_x = frac_y = 1.0;
-+ } else {
-+ get_scale_values(&frac_x, &frac_y);
-+ if (frac_x < 0.0 || frac_y < 0.0) {
-+ create_image();
-+ return;
-+ }
-+ }
-+
-+ last_rescale = dnow();
-+
-+ SoftCursorLockArea(0, 0, si.framebufferWidth, si.framebufferHeight);
-+
-+ if (image_scale == NULL) {
-+ /* switching from not scaled */
-+ int i;
-+ int Bpl = image->bytes_per_line;
-+ char *dst, *src = image->data;
-+
-+ image_scale = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
-+ si.framebufferWidth, si.framebufferHeight, BitmapPad(dpy), 0);
-+
-+ image_scale->data = (char *) malloc(image_scale->bytes_per_line * image_scale->height);
-+
-+ fprintf(stderr, "rescale_image: switching from not scaled. created image_scale %dx%d\n", image_scale->width, image_scale->height);
-+ fprintf(stderr, "rescale_image: copying image -> image_scale %dx%d -> %dx%d\n", image->width, image->height, image_scale->width, image_scale->height);
-+
-+ dst = image_scale->data;
-+
-+ /* copy from image->data */
-+ for (i=0; i < image->height; i++) {
-+ memcpy(dst, src, Bpl);
-+ dst += Bpl;
-+ src += Bpl;
-+ }
-+ }
-+
-+ /* now destroy image */
-+ if (image && image->data) {
-+ if (UsingShm()) {
-+ ShmDetach();
-+ }
-+ XDestroyImage(image);
-+ fprintf(stderr, "rescale_image: destroyed 'image'\n");
-+ if (UsingShm()) {
-+ ShmCleanup();
-+ }
-+ image = NULL;
-+ }
-+ if (image_ycrop && image_ycrop->data) {
-+ XDestroyImage(image_ycrop);
-+ fprintf(stderr, "rescale_image: destroyed 'image_ycrop'\n");
-+ image_ycrop = NULL;
-+ }
-+
-+ if (frac_x == 1.0 && frac_y == 1.0) {
-+ /* switching to not scaled */
-+ fprintf(stderr, "rescale_image: switching to not scaled.\n");
-+ w = si.framebufferWidth;
-+ h = si.framebufferHeight;
-+
-+ scale_factor_x = 0.0;
-+ scale_factor_y = 0.0;
-+ scale_x = 0;
-+ scale_y = 0;
-+ } else {
-+ w = scale_round(si.framebufferWidth, frac_x);
-+ h = scale_round(si.framebufferHeight, frac_y);
-+
-+ scale_factor_x = frac_x;
-+ scale_factor_y = frac_y;
-+ scale_x = w;
-+ scale_y = h;
-+ }
-+
-+ adjust_Xt_win(w, h);
-+
-+ fprintf(stderr, "rescale: %dx%d %.4f %.4f\n", w, h, scale_factor_x, scale_factor_y);
-+
-+ try_create_image();
-+
-+ if (image && image->data && image_scale && frac_x == 1.0 && frac_y == 1.0) {
-+ /* switched to not scaled */
-+ int i;
-+ int Bpl = image->bytes_per_line;
-+ char *dst = image->data;
-+ char *src = image_scale->data;
-+
-+ fprintf(stderr, "rescale_image: switching to not scaled.\n");
-+
-+ for (i=0; i < image->height; i++) {
-+ memcpy(dst, src, Bpl);
-+ dst += Bpl;
-+ src += Bpl;
-+ }
-+ XDestroyImage(image_scale);
-+ fprintf(stderr, "rescale_image: destroyed 'image_scale'\n");
-+ image_scale = NULL;
-+ }
-+
-+ if (appData.yCrop > 0) {
-+ int ycrop = appData.yCrop;
-+ /* do the top part first so they can see it earlier */
-+ put_image(0, 0, 0, 0, si.framebufferWidth, ycrop, 0);
-+ if (si.framebufferHeight > ycrop) {
-+ /* this is a big fb and so will take a long time */
-+ if (waitCursor != None) {
-+ XDefineCursor(dpy, desktopWin, waitCursor);
-+ XSync(dpy, False);
-+ }
-+ put_image(0, 0, 0, 0, si.framebufferWidth, si.framebufferHeight - ycrop, 0);
-+ if (waitCursor != None) {
-+ Xcursors(1);
-+ if (appData.useX11Cursor) {
-+ XSetWindowAttributes attr;
-+ unsigned long valuemask = 0;
-+ if (appData.viewOnly) {
-+ attr.cursor = dotCursor4;
-+ } else {
-+ attr.cursor = dotCursor3;
-+ }
-+ valuemask |= CWCursor;
-+ XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr);
-+ }
-+ }
-+ }
-+ } else {
-+ put_image(0, 0, 0, 0, si.framebufferWidth, si.framebufferHeight, 0);
-+ }
-+
-+ SoftCursorUnlockScreen();
-+
-+ fprintf(stderr, "rescale: image_scale=%p image=%p image_ycrop=%p\n", (void *) image_scale, (void *) image, (void *) image_ycrop);
-+ last_rescale = dnow();
-+
-+}
-+
-+void try_create_image(void) {
-+
-+ image_is_shm = 0;
-+ if (appData.useShm) {
-+#ifdef MITSHM
-+ image = CreateShmImage(0);
-+ if (!image) {
-+ if (appData.yCrop > 0) {
-+ if (appData.scale != NULL && scale_x > 0) {
-+ ;
-+ } else {
-+ image_ycrop = CreateShmImage(1);
-+ if (!image_ycrop) {
-+ appData.useShm = False;
-+ } else {
-+ fprintf(stderr, "created smaller image_ycrop shm image: %dx%d\n",
-+ image_ycrop->width, image_ycrop->height);
-+ }
-+ }
-+ } else {
-+ appData.useShm = False;
-+ }
-+ } else {
-+ image_is_shm = 1;
-+ fprintf(stderr, "created shm image: %dx%d\n", image->width, image->height);
-+ }
-+#endif
-+ }
-+
-+ if (!image) {
-+ fprintf(stderr, "try_create_image: shm image create fail: image == NULL\n");
-+ if (scale_x > 0) {
-+ image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
-+ scale_x, scale_y, BitmapPad(dpy), 0);
-+ } else {
-+ image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
-+ si.framebufferWidth, si.framebufferHeight, BitmapPad(dpy), 0);
-+ }
-+
-+ image->data = malloc(image->bytes_per_line * image->height);
-+
-+ if (!image->data) {
-+ fprintf(stderr, "try_create_image: malloc failed\n");
-+ exit(1);
-+ } else {
-+ fprintf(stderr, "try_create_image: created *non-shm* image: %dx%d\n", image->width, image->height);
-+ }
-+ }
-+ fprintf(stderr, "try_create_image: image->bytes_per_line: %d\n", image->bytes_per_line);
-+}
-+
-+void create_image() {
-+ image = NULL;
-+ image_ycrop = NULL;
-+ image_scale = NULL;
-+
-+ fprintf(stderr, "create_image()\n");
-+
-+ if (CreateShmImage(-1) == NULL) {
-+ appData.useShm = False;
-+ }
-+ if (appData.scale != NULL) {
-+ if (appData.useXserverBackingStore) {
-+ fprintf(stderr, "Cannot scale when using X11 backingstore.\n");
-+ } else {
-+ double frac_x = -1.0, frac_y = -1.0;
-+
-+ get_scale_values(&frac_x, &frac_y);
-+
-+ if (frac_x < 0.0 || frac_y < 0.0) {
-+ fprintf(stderr, "Cannot figure out scale factor!\n");
-+ goto bork;
-+ }
-+
-+ scale_factor_x = 0.0;
-+ scale_factor_y = 0.0;
-+ scale_x = 0;
-+ scale_y = 0;
-+
-+
-+ if (1) {
-+ int w, h, hyc;
-+
-+ w = scale_round(si.framebufferWidth, frac_x);
-+ h = scale_round(si.framebufferHeight, frac_y);
-+ hyc = h;
-+ if (appData.yCrop > 0) {
-+ hyc = scale_round(appData.yCrop, frac_y);
-+ }
-+
-+ /* image scale is full framebuffer */
-+ image_scale = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
-+ si.framebufferWidth, si.framebufferHeight, BitmapPad(dpy), 0);
-+
-+ image_scale->data = (char *) malloc(image_scale->bytes_per_line * image_scale->height);
-+
-+ fprintf(stderr, "create_image: created image_scale %dx%d\n", image_scale->width, image_scale->height);
-+
-+ if (!image_scale->data) {
-+ fprintf(stderr, "create_image: malloc failed\n");
-+ XDestroyImage(image_scale);
-+ fprintf(stderr, "create_image: destroyed 'image_scale'\n");
-+ image_scale = NULL;
-+ } else {
-+ int h2;
-+ scale_factor_x = frac_x;
-+ scale_factor_y = frac_y;
-+ scale_x = w;
-+ scale_y = h;
-+
-+ XtVaSetValues(toplevel, XtNmaxWidth, w, XtNmaxHeight, hyc, NULL);
-+
-+ h2 = scale_round(si.framebufferHeight, frac_y);
-+ XtVaSetValues(desktop, XtNwidth, w, XtNheight, h2, NULL);
-+
-+ }
-+ fprintf(stderr, "create_image: scale: %dx%d %.4f %.4f\n", w, h,
-+ scale_factor_x, scale_factor_y);
-+ }
-+ }
-+ }
-+ bork:
-+ try_create_image();
-+}
-+
-+int old_width = 0;
-+int old_height = 0;
-+
-+int guessCrop(void) {
-+ int w = si.framebufferWidth;
-+
-+ if (w == 320) {
-+ return 240;
-+ } else if (w == 400) {
-+ return 300;
-+ } else if (w == 640) {
-+ return 480;
-+ } else if (w == 800) {
-+ return 600;
-+ } else if (w == 1024) {
-+ return 768;
-+ } else if (w == 1152) {
-+ return 864;
-+ } else if (w == 1280) {
-+ return 1024;
-+ } else if (w == 1440) {
-+ return 900;
-+ } else if (w == 1600) {
-+ return 1200;
-+ } else if (w == 1680) {
-+ return 1050;
-+ } else if (w == 1920) {
-+ return 1200;
-+ } else {
-+ int h = (3 * w) / 4;
-+ return h;
-+ }
-+}
-+
-+void check_tall(void) {
-+ if (appData.appShare) {
-+ return;
-+ }
-+ if (! appData.yCrop) {
-+ int w = si.framebufferWidth;
-+ int h = si.framebufferHeight;
-+ if (h > 2 * w) {
-+ fprintf(stderr, "Tall display (%dx%d) suspect 'x11vnc -ncache' mode,\n", w, h);
-+ fprintf(stderr, " setting auto -ycrop detection.\n");
-+ appData.yCrop = -1;
-+ }
-+ }
-+}
-
- /*
- * DesktopInitBeforeRealization creates the "desktop" widget and the viewport
-@@ -59,91 +528,1023 @@
- void
- DesktopInitBeforeRealization()
- {
-- int i;
-+ int i;
-+ int h = si.framebufferHeight;
-+ int w = si.framebufferWidth;
-+ double frac_x = 1.0, frac_y = 1.0;
-+
-+ start_time = dnow();
-+
-+ prev_fb_width = si.framebufferWidth;
-+ prev_fb_height = si.framebufferHeight;
-+
-+ if (appData.scale != NULL) {
-+ get_scale_values(&frac_x, &frac_y);
-+ if (frac_x > 0.0 && frac_y > 0.0) {
-+ w = scale_round(w, frac_x);
-+ h = scale_round(h, frac_y);
-+ } else {
-+ appData.scale = NULL;
-+ }
-+ }
-
-- form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel,
-- XtNborderWidth, 0,
-- XtNdefaultDistance, 0, NULL);
-+ form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel,
-+ XtNborderWidth, 0, XtNdefaultDistance, 0, NULL);
-
-- viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form,
-- XtNborderWidth, 0,
-- NULL);
-+ viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form,
-+ XtNborderWidth, 0, NULL);
-
-- desktop = XtVaCreateManagedWidget("desktop", coreWidgetClass, viewport,
-- XtNborderWidth, 0,
-- NULL);
-+ desktop = XtVaCreateManagedWidget("desktop", coreWidgetClass, viewport,
-+ XtNborderWidth, 0, NULL);
-
-- XtVaSetValues(desktop, XtNwidth, si.framebufferWidth,
-- XtNheight, si.framebufferHeight, NULL);
-+ XtVaSetValues(desktop, XtNwidth, w, XtNheight, h, NULL);
-
-- XtAddEventHandler(desktop, LeaveWindowMask|ExposureMask,
-- True, HandleBasicDesktopEvent, NULL);
-+ XtAddEventHandler(desktop, LeaveWindowMask|EnterWindowMask|ExposureMask,
-+ True, HandleBasicDesktopEvent, NULL);
-
-- for (i = 0; i < 256; i++)
-- modifierPressed[i] = False;
-+ if (appData.yCrop) {
-+ int hm;
-+ if (appData.yCrop < 0) {
-+ appData.yCrop = guessCrop();
-+ fprintf(stderr, "Set -ycrop to: %d\n", appData.yCrop);
-+ }
-+ hm = appData.yCrop;
-
-- image = NULL;
-+ fprintf(stderr, "ycrop h: %d -> %d\n", hm, (int) (hm*frac_y));
-
--#ifdef MITSHM
-- if (appData.useShm) {
-- image = CreateShmImage();
-- if (!image)
-- appData.useShm = False;
-- }
-+ hm *= frac_y;
-+
-+ XtVaSetValues(toplevel, XtNmaxHeight, hm, XtNheight, hm, NULL);
-+ XtVaSetValues(form, XtNmaxHeight, hm, XtNheight, hm, NULL);
-+ XtVaSetValues(viewport, XtNforceBars, False, NULL);
-+ XSync(dpy, False);
-+ }
-+
-+ old_width = si.framebufferWidth;
-+ old_height = si.framebufferHeight;
-+
-+ for (i = 0; i < 256; i++) {
-+ modifierPressed[i] = False;
-+ }
-+
-+ create_image();
-+}
-+
-+#if 0
-+static Widget scrollbar_y = NULL;
-+static int xsst = 2;
- #endif
-
-- if (!image) {
-- image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
-- si.framebufferWidth, si.framebufferHeight,
-- BitmapPad(dpy), 0);
--
-- image->data = malloc(image->bytes_per_line * image->height);
-- if (!image->data) {
-- fprintf(stderr,"malloc failed\n");
-- exit(1);
-- }
-- }
-+#include <X11/Xaw/Scrollbar.h>
-+
-+#if 0
-+static XtCallbackProc Scrolled(Widget w, XtPointer closure, XtPointer call_data) {
-+ Position x, y;
-+ XtVaGetValues(desktop, XtNx, &x, XtNy, &y, NULL);
-+ if (0) fprintf(stderr, "scrolled by %d pixels x=%d y=%d\n", (int) call_data, x, y);
-+ if (xsst == 2) {
-+ x = 0;
-+ y = 0;
-+ XtVaSetValues(desktop, XtNx, x, XtNy, y, NULL);
-+ } else if (xsst) {
-+ XawScrollbarSetThumb(w, 0.0, 0.0);
-+ } else {
-+ float t = 0.0;
-+ XtVaSetValues(w, XtNtopOfThumb, &t, NULL);
-+ }
-+ if (closure) {}
- }
-
-+static XtCallbackProc Jumped(Widget w, XtPointer closure, XtPointer call_data) {
-+ float top = *((float *) call_data);
-+ Position x, y;
-+ XtVaGetValues(desktop, XtNx, &x, XtNy, &y, NULL);
-+ if (0) fprintf(stderr, "thumb value: %.4f x=%d y=%d\n", top, x, y);
-+ if (top > 0.01) {
-+ if (xsst == 2) {
-+ x = 0;
-+ y = 0;
-+ XtVaSetValues(desktop, XtNx, x, XtNy, y, NULL);
-+ } else if (xsst) {
-+ XawScrollbarSetThumb(w, 0.0, 0.0);
-+ } else {
-+ float t = 0.0, s = 1.0;
-+ XtVaSetValues(w, XtNtopOfThumb, *(XtArgVal*)&t, XtNshown, *(XtArgVal*)&s, NULL);
-+ }
-+ }
-+ if (closure) {}
-+}
-+#endif
-+
-+extern double dnow(void);
-+
-+void check_things() {
-+ static int first = 1;
-+ static double last_scrollbar = 0.0;
-+ int w = si.framebufferWidth;
-+ int h = si.framebufferHeight;
-+ double now = dnow();
-+ static double last = 0;
-+ double fac = image_scale ? scale_factor_y : 1.0;
-+
-+ if (first) {
-+ first = 0;
-+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, False);
-+ }
-+ if (appData.yCrop > 0 && appData.yCrop * fac < dpyHeight && h > 2*w && now > last_scrollbar + 0.25) {
-+ Widget wv, wh, wc;
-+ Position x0, y0;
-+ Position x1, y1;
-+ Dimension w0, h0, b0;
-+ Dimension w1, h1, b1;
-+ Dimension w2, h2, b2;
-+
-+ wc = XtNameToWidget(viewport, "clip");
-+ wv = XtNameToWidget(viewport, "vertical");
-+ wh = XtNameToWidget(viewport, "horizontal");
-+ if (wc && wv && wh) {
-+ int sb = appData.sbWidth;
-+ XtVaGetValues(wv, XtNwidth, &w0, XtNheight, &h0, XtNborderWidth, &b0, XtNx, &x0, XtNy, &y0, NULL);
-+ XtVaGetValues(wh, XtNwidth, &w1, XtNheight, &h1, XtNborderWidth, &b1, XtNx, &x1, XtNy, &y1, NULL);
-+ XtVaGetValues(wc, XtNwidth, &w2, XtNheight, &h2, XtNborderWidth, &b2, NULL);
-+ if (!sb) {
-+ sb = 2;
-+ }
-+ if (w0 != sb || h1 != sb) {
-+ fprintf(stderr, "Very tall (-ncache) fb, setting scrollbar thickness to: %d pixels (%d/%d)\n\n", sb, w0, h1);
-+
-+ XtUnmanageChild(wv);
-+ XtUnmanageChild(wh);
-+ XtUnmanageChild(wc);
-+
-+ XtVaSetValues(wv, XtNwidth, sb, XtNx, x0 + (w0 - sb), NULL);
-+ XtVaSetValues(wh, XtNheight, sb, XtNy, y1 + (h1 - sb), NULL);
-+ w2 = w2 + (w0 - sb);
-+ h2 = h2 + (h1 - sb);
-+ if (w2 > 10 && h2 > 10) {
-+ XtVaSetValues(wc, XtNwidth, w2, XtNheight, h2, NULL);
-+ }
-+
-+ XtManageChild(wv);
-+ XtManageChild(wh);
-+ XtManageChild(wc);
-+
-+ appData.sbWidth = sb;
-+ }
-+ }
-+ last_scrollbar = dnow();
-+ }
-+
-+ if (now <= last + 0.25) {
-+ return;
-+ }
-+
-+ if (image_scale) {
-+ scale_check_zrle();
-+ }
-+
-+ /* e.g. xrandr resize */
-+ dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy));
-+ dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy));
-+
-+ if (appData.scale != NULL) {
-+ static Dimension last_w = 0, last_h = 0;
-+ static double last_resize = 0.0;
-+ Dimension w, h;
-+ if (last_w == 0) {
-+ XtVaGetValues(toplevel, XtNwidth, &last_w, XtNheight, &last_h, NULL);
-+ last_resize = now;
-+ }
-+ if (now < last_resize + 0.5) {
-+ ;
-+ } else if (appData.fullScreen) {
-+ ;
-+ } else if (!strcmp(appData.scale, "auto")) {
-+ XtVaGetValues(toplevel, XtNwidth, &w, XtNheight, &h, NULL);
-+ if (w < 32 || h < 32) {
-+ ;
-+ } else if (last_w != w || last_h != h) {
-+ Window rr, cr, r = DefaultRootWindow(dpy);
-+ int rx, ry, wx, wy;
-+ unsigned int mask;
-+ /* make sure mouse buttons not pressed */
-+ if (XQueryPointer(dpy, r, &rr, &cr, &rx, &ry, &wx, &wy, &mask)) {
-+ if (mask == 0) {
-+ rescale_image();
-+ last_w = w;
-+ last_h = h;
-+ last_resize = dnow();
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ last = dnow();
-+}
-
- /*
- * DesktopInitAfterRealization does things which require the X windows to
- * exist. It creates some GCs and sets the dot cursor.
- */
-
-+void Xcursors(int set) {
-+ if (dotCursor3 == None) {
-+ dotCursor3 = CreateDotCursor(3);
-+ }
-+ if (dotCursor4 == None) {
-+ dotCursor4 = CreateDotCursor(4);
-+ }
-+ if (set) {
-+ XSetWindowAttributes attr;
-+ unsigned long valuemask = 0;
-+
-+ if (!appData.useX11Cursor) {
-+ if (appData.viewOnly) {
-+ attr.cursor = dotCursor4;
-+ } else {
-+ attr.cursor = dotCursor3;
-+ }
-+ valuemask |= CWCursor;
-+ XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr);
-+ }
-+ }
-+}
-+
- void
- DesktopInitAfterRealization()
- {
-- XGCValues gcv;
-- XSetWindowAttributes attr;
-- unsigned long valuemask;
--
-- desktopWin = XtWindow(desktop);
--
-- gc = XCreateGC(dpy,desktopWin,0,NULL);
--
-- gcv.function = GXxor;
-- gcv.foreground = 0x0f0f0f0f;
-- srcGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv);
-- gcv.foreground = 0xf0f0f0f0;
-- dstGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv);
--
-- XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
-- NULL, 0);
--
-- XtVaGetApplicationResources(desktop, (XtPointer)&attr.backing_store,
-- desktopBackingStoreResources, 1, NULL);
-- valuemask = CWBackingStore;
--
-- if (!appData.useX11Cursor) {
-- dotCursor = CreateDotCursor();
-- attr.cursor = dotCursor;
-- valuemask |= CWCursor;
-- }
-+ XGCValues gcv;
-+ XSetWindowAttributes attr;
-+ XWindowAttributes gattr;
-+ unsigned long valuemask = 0;
-+
-+ desktopWin = XtWindow(desktop);
-+
-+ gc = XCreateGC(dpy,desktopWin,0,NULL);
-+
-+ gcv.function = GXxor;
-+ gcv.foreground = 0x0f0f0f0f;
-+ srcGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv);
-+ gcv.foreground = 0xf0f0f0f0;
-+ dstGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv);
-+
-+ XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
-+ NULL, 0);
-+
-+ if (appData.useXserverBackingStore) {
-+ Screen *s = DefaultScreenOfDisplay(dpy);
-+ if (DoesBackingStore(s) != Always) {
-+ fprintf(stderr, "X server does not do backingstore, disabling it.\n");
-+ appData.useXserverBackingStore = False;
-+ }
-+ }
-+
-+ if (appData.useXserverBackingStore) {
-+ XtVaGetApplicationResources(desktop, (XtPointer)&attr.backing_store,
-+ desktopBackingStoreResources, 1, NULL);
-+ valuemask |= CWBackingStore;
-+ } else {
-+ attr.background_pixel = BlackPixel(dpy, DefaultScreen(dpy));
-+ valuemask |= CWBackPixel;
-+ }
-+
-+ Xcursors(0);
-+ if (!appData.useX11Cursor) {
-+ if (appData.viewOnly) {
-+ attr.cursor = dotCursor4;
-+ } else {
-+ attr.cursor = dotCursor3;
-+ }
-+ valuemask |= CWCursor;
-+ }
-+ bogoCursor = XCreateFontCursor(dpy, XC_bogosity);
-+ waitCursor = XCreateFontCursor(dpy, XC_watch);
-+
-+ XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr);
-+
-+ if (XGetWindowAttributes(dpy, desktopWin, &gattr)) {
-+#if 0
-+ fprintf(stderr, "desktopWin backingstore: %d save_under: %d\n", gattr.backing_store, gattr.save_under);
-+#endif
-+ }
-+ fprintf(stderr, "\n");
-+}
-+
-+extern void FreeX11Cursor(void);
-+extern void FreeSoftCursor(void);
-
-- XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr);
-+void
-+DesktopCursorOff()
-+{
-+ if (dotCursor3 == None) {
-+ dotCursor3 = CreateDotCursor(3);
-+ dotCursor4 = CreateDotCursor(4);
-+ }
-+ if (appData.viewOnly) {
-+ XDefineCursor(dpy, desktopWin, dotCursor4);
-+ } else {
-+ XDefineCursor(dpy, desktopWin, dotCursor3);
-+ }
-+ FreeX11Cursor();
-+ FreeSoftCursor();
-+}
-+
-+
-+#define CEIL(x) ( (double) ((int) (x)) == (x) ? \
-+ (double) ((int) (x)) : (double) ((int) (x) + 1) )
-+#define FLOOR(x) ( (double) ((int) (x)) )
-+
-+#if 0
-+static int nfix(int i, int n) {
-+ if (i < 0) {
-+ i = 0;
-+ } else if (i >= n) {
-+ i = n - 1;
-+ }
-+ return i;
- }
-+#else
-+#define nfix(i, n) ( i < 0 ? 0 : ( (i >= n) ? (n - 1) : i ) )
-+#endif
-+
-+int scale_round(int len, double fac) {
-+ double eps = 0.000001;
-+
-+ len = (int) (len * fac + eps);
-+ if (len < 1) {
-+ len = 1;
-+ }
-+ return len;
-+}
-+
-+static void scale_rect(double factor_x, double factor_y, int blend, int interpolate,
-+ int *px, int *py, int *pw, int *ph, int solid) {
-+
-+ int i, j, i1, i2, j1, j2; /* indices for scaled fb (dest) */
-+ int I, J, I1, I2, J1, J2; /* indices for main fb (source) */
-+
-+ double w, wx, wy, wtot; /* pixel weights */
-+
-+ double x1 = 0, y1, x2 = 0, y2; /* x-y coords for destination pixels edges */
-+ double dx, dy; /* size of destination pixel */
-+ double ddx=0, ddy=0; /* for interpolation expansion */
-+
-+ char *src, *dest; /* pointers to the two framebuffers */
-+
-+ unsigned short us = 0;
-+ unsigned char uc = 0;
-+ unsigned int ui = 0;
-+
-+ int use_noblend_shortcut = 1;
-+ int shrink; /* whether shrinking or expanding */
-+ static int constant_weights = -1, mag_int = -1;
-+ static int last_Nx = -1, last_Ny = -1, cnt = 0;
-+ static double last_factor = -1.0;
-+ int b, k;
-+ double pixave[4]; /* for averaging pixel values */
-+
-+ /* internal */
-+
-+ int X1, X2, Y1, Y2;
-
-+ int Nx = si.framebufferWidth;
-+ int Ny = si.framebufferHeight;
-+
-+ int nx = scale_round(Nx, factor_x);
-+ int ny = scale_round(Ny, factor_y);
-+
-+ int Bpp = image->bits_per_pixel / 8;
-+ int dst_bytes_per_line = image->bytes_per_line;
-+ int src_bytes_per_line = image_scale->bytes_per_line;
-+
-+ unsigned long main_red_mask = image->red_mask;
-+ unsigned long main_green_mask = image->green_mask;
-+ unsigned long main_blue_mask = image->blue_mask;
-+ int mark = 1;
-+
-+ char *src_fb = image_scale->data;
-+ char *dst_fb = image->data;
-+
-+ static int nosolid = -1;
-+ int sbdy = 3;
-+ double fmax = factor_x > factor_y ? factor_x : factor_y;
-+#if 0
-+ double fmin = factor_x < factor_y ? factor_x : factor_y;
-+#endif
-+
-+ X1 = *px;
-+ X2 = *px + *pw;
-+ Y1 = *py;
-+ Y2 = *py + *ph;
-+
-+ if (fmax > 1.0) {
-+ /* try to avoid problems with bleeding... */
-+ sbdy = (int) (2.0 * fmax * sbdy);
-+ }
-+
-+ /* fprintf(stderr, "scale_rect: %dx%d+%d+%d\n", *pw, *ph, *px, *py); */
-+
-+ *px = (int) (*px * factor_x);
-+ *py = (int) (*py * factor_y);
-+ *pw = scale_round(*pw, factor_x);
-+ *ph = scale_round(*ph, factor_y);
-+
-+ if (nosolid < 0) {
-+ if (getenv("SSVNC_NOSOLID")) {
-+ nosolid = 1;
-+ } else {
-+ nosolid = 0;
-+ }
-+ }
-+ if (nosolid) solid = 0;
-+
-+#define rfbLog printf
-+/* Begin taken from x11vnc scale: */
-+
-+ if (factor_x <= 1.0 || factor_y <= 1.0) {
-+ shrink = 1;
-+ } else {
-+ shrink = 0;
-+ interpolate = 1;
-+ }
-+
-+ /*
-+ * N.B. width and height (real numbers) of a scaled pixel.
-+ * both are > 1 (e.g. 1.333 for -scale 3/4)
-+ * they should also be equal but we don't assume it.
-+ *
-+ * This new way is probably the best we can do, take the inverse
-+ * of the scaling factor to double precision.
-+ */
-+ dx = 1.0/factor_x;
-+ dy = 1.0/factor_y;
-+
-+ /*
-+ * There is some speedup if the pixel weights are constant, so
-+ * let's special case these.
-+ *
-+ * If scale = 1/n and n divides Nx and Ny, the pixel weights
-+ * are constant (e.g. 1/2 => equal on 2x2 square).
-+ */
-+ if (factor_x != last_factor || Nx != last_Nx || Ny != last_Ny) {
-+ constant_weights = -1;
-+ mag_int = -1;
-+ last_Nx = Nx;
-+ last_Ny = Ny;
-+ last_factor = factor_x;
-+ }
-+
-+ if (constant_weights < 0 && factor_x != factor_y) {
-+ constant_weights = 0;
-+ mag_int = 0;
-+ } else if (constant_weights < 0) {
-+ int n = 0;
-+ double factor = factor_x;
-+
-+ constant_weights = 0;
-+ mag_int = 0;
-+
-+ for (i = 2; i<=128; i++) {
-+ double test = ((double) 1)/ i;
-+ double diff, eps = 1.0e-7;
-+ diff = factor - test;
-+ if (-eps < diff && diff < eps) {
-+ n = i;
-+ break;
-+ }
-+ }
-+ if (! blend || ! shrink || interpolate) {
-+ ;
-+ } else if (n != 0) {
-+ if (Nx % n == 0 && Ny % n == 0) {
-+ static int didmsg = 0;
-+ if (mark && ! didmsg) {
-+ didmsg = 1;
-+ rfbLog("scale_and_mark_rect: using "
-+ "constant pixel weight speedup "
-+ "for 1/%d\n", n);
-+ }
-+ constant_weights = 1;
-+ }
-+ }
-+
-+ n = 0;
-+ for (i = 2; i<=32; i++) {
-+ double test = (double) i;
-+ double diff, eps = 1.0e-7;
-+ diff = factor - test;
-+ if (-eps < diff && diff < eps) {
-+ n = i;
-+ break;
-+ }
-+ }
-+ if (! blend && factor > 1.0 && n) {
-+ mag_int = n;
-+ }
-+ }
-+if (0) fprintf(stderr, "X1: %d Y1: %d X2: %d Y2: %d\n", X1, Y1, X2, Y2);
-+
-+ if (mark && !shrink && blend) {
-+ /*
-+ * kludge: correct for interpolating blurring leaking
-+ * up or left 1 destination pixel.
-+ */
-+ if (X1 > 0) X1--;
-+ if (Y1 > 0) Y1--;
-+ }
-+
-+ /*
-+ * find the extent of the change the input rectangle induces in
-+ * the scaled framebuffer.
-+ */
-+
-+ /* Left edges: find largest i such that i * dx <= X1 */
-+ i1 = FLOOR(X1/dx);
-+
-+ /* Right edges: find smallest i such that (i+1) * dx >= X2+1 */
-+ i2 = CEIL( (X2+1)/dx ) - 1;
-+
-+ /* To be safe, correct any overflows: */
-+ i1 = nfix(i1, nx);
-+ i2 = nfix(i2, nx) + 1; /* add 1 to make a rectangle upper boundary */
-+
-+ /* Repeat above for y direction: */
-+ j1 = FLOOR(Y1/dy);
-+ j2 = CEIL( (Y2+1)/dy ) - 1;
-+
-+ j1 = nfix(j1, ny);
-+ j2 = nfix(j2, ny) + 1;
-+
-+ /*
-+ * special case integer magnification with no blending.
-+ * vision impaired magnification usage is interested in this case.
-+ */
-+ if (mark && ! blend && mag_int && Bpp != 3) {
-+ int jmin, jmax, imin, imax;
-+
-+ /* outer loop over *source* pixels */
-+ for (J=Y1; J < Y2; J++) {
-+ jmin = J * mag_int;
-+ jmax = jmin + mag_int;
-+ for (I=X1; I < X2; I++) {
-+ /* extract value */
-+ src = src_fb + J*src_bytes_per_line + I*Bpp;
-+ if (Bpp == 4) {
-+ ui = *((unsigned int *)src);
-+ } else if (Bpp == 2) {
-+ us = *((unsigned short *)src);
-+ } else if (Bpp == 1) {
-+ uc = *((unsigned char *)src);
-+ }
-+ imin = I * mag_int;
-+ imax = imin + mag_int;
-+ /* inner loop over *dest* pixels */
-+ for (j=jmin; j<jmax; j++) {
-+ dest = dst_fb + j*dst_bytes_per_line + imin*Bpp;
-+ for (i=imin; i<imax; i++) {
-+ if (Bpp == 4) {
-+ *((unsigned int *)dest) = ui;
-+ } else if (Bpp == 2) {
-+ *((unsigned short *)dest) = us;
-+ } else if (Bpp == 1) {
-+ *((unsigned char *)dest) = uc;
-+ }
-+ dest += Bpp;
-+ }
-+ }
-+ }
-+ }
-+ goto markit;
-+ }
-+
-+ /* set these all to 1.0 to begin with */
-+ wx = 1.0;
-+ wy = 1.0;
-+ w = 1.0;
-+
-+ /*
-+ * Loop over destination pixels in scaled fb:
-+ */
-+ for (j=j1; j<j2; j++) {
-+ int jbdy = 1, I1_solid = 0;
-+
-+ y1 = j * dy; /* top edge */
-+ if (y1 > Ny - 1) {
-+ /* can go over with dy = 1/scale_fac */
-+ y1 = Ny - 1;
-+ }
-+ y2 = y1 + dy; /* bottom edge */
-+
-+ /* Find main fb indices covered by this dest pixel: */
-+ J1 = (int) FLOOR(y1);
-+ J1 = nfix(J1, Ny);
-+
-+ if (shrink && ! interpolate) {
-+ J2 = (int) CEIL(y2) - 1;
-+ J2 = nfix(J2, Ny);
-+ } else {
-+ J2 = J1 + 1; /* simple interpolation */
-+ ddy = y1 - J1;
-+ }
-+
-+ /* destination char* pointer: */
-+ dest = dst_fb + j*dst_bytes_per_line + i1*Bpp;
-+
-+ if (solid) {
-+ if (j1+sbdy <= j && j < j2-sbdy) {
-+ jbdy = 0;
-+ x1 = (i1+sbdy) * dx;
-+ if (x1 > Nx - 1) {
-+ x1 = Nx - 1;
-+ }
-+ I1_solid = (int) FLOOR(x1);
-+ if (I1_solid >= Nx) I1_solid = Nx - 1;
-+ }
-+ }
-+
-+ for (i=i1; i<i2; i++) {
-+ int solid_skip = 0;
-+
-+ if (solid) {
-+ /* if the region is solid, we can use the noblend speedup */
-+ if (!jbdy && i1+sbdy <= i && i < i2-sbdy) {
-+ solid_skip = 1;
-+ /* pixels all the same so use X1: */
-+ I1 = I1_solid;
-+ goto jsolid;
-+ }
-+ }
-+
-+ x1 = i * dx; /* left edge */
-+ if (x1 > Nx - 1) {
-+ /* can go over with dx = 1/scale_fac */
-+ x1 = Nx - 1;
-+ }
-+ x2 = x1 + dx; /* right edge */
-+
-+ /* Find main fb indices covered by this dest pixel: */
-+ I1 = (int) FLOOR(x1);
-+ if (I1 >= Nx) I1 = Nx - 1;
-+
-+ jsolid:
-+ cnt++;
-+
-+ if ((!blend && use_noblend_shortcut) || solid_skip) {
-+ /*
-+ * The noblend case involves no weights,
-+ * and 1 pixel, so just copy the value
-+ * directly.
-+ */
-+ src = src_fb + J1*src_bytes_per_line + I1*Bpp;
-+ if (Bpp == 4) {
-+ *((unsigned int *)dest)
-+ = *((unsigned int *)src);
-+ } else if (Bpp == 2) {
-+ *((unsigned short *)dest)
-+ = *((unsigned short *)src);
-+ } else if (Bpp == 1) {
-+ *(dest) = *(src);
-+ } else if (Bpp == 3) {
-+ /* rare case */
-+ for (k=0; k<=2; k++) {
-+ *(dest+k) = *(src+k);
-+ }
-+ }
-+ dest += Bpp;
-+ continue;
-+ }
-+
-+ if (shrink && ! interpolate) {
-+ I2 = (int) CEIL(x2) - 1;
-+ if (I2 >= Nx) I2 = Nx - 1;
-+ } else {
-+ I2 = I1 + 1; /* simple interpolation */
-+ ddx = x1 - I1;
-+ }
-+#if 0
-+if (first) fprintf(stderr, " I1=%d I2=%d J1=%d J2=%d\n", I1, I2, J1, J2);
-+#endif
-+
-+ /* Zero out accumulators for next pixel average: */
-+ for (b=0; b<4; b++) {
-+ pixave[b] = 0.0; /* for RGB weighted sums */
-+ }
-+
-+ /*
-+ * wtot is for accumulating the total weight.
-+ * It should always sum to 1/(scale_fac * scale_fac).
-+ */
-+ wtot = 0.0;
-+
-+ /*
-+ * Loop over source pixels covered by this dest pixel.
-+ *
-+ * These "extra" loops over "J" and "I" make
-+ * the cache/cacheline performance unclear.
-+ * For example, will the data brought in from
-+ * src for j, i, and J=0 still be in the cache
-+ * after the J > 0 data have been accessed and
-+ * we are at j, i+1, J=0? The stride in J is
-+ * main_bytes_per_line, and so ~4 KB.
-+ *
-+ * Typical case when shrinking are 2x2 loop, so
-+ * just two lines to worry about.
-+ */
-+ for (J=J1; J<=J2; J++) {
-+ /* see comments for I, x1, x2, etc. below */
-+ if (constant_weights) {
-+ ;
-+ } else if (! blend) {
-+ if (J != J1) {
-+ continue;
-+ }
-+ wy = 1.0;
-+
-+ /* interpolation scheme: */
-+ } else if (! shrink || interpolate) {
-+ if (J >= Ny) {
-+ continue;
-+ } else if (J == J1) {
-+ wy = 1.0 - ddy;
-+ } else if (J != J1) {
-+ wy = ddy;
-+ }
-+
-+ /* integration scheme: */
-+ } else if (J < y1) {
-+ wy = J+1 - y1;
-+ } else if (J+1 > y2) {
-+ wy = y2 - J;
-+ } else {
-+ wy = 1.0;
-+ }
-+
-+ src = src_fb + J*src_bytes_per_line + I1*Bpp;
-+
-+ for (I=I1; I<=I2; I++) {
-+
-+ /* Work out the weight: */
-+
-+ if (constant_weights) {
-+ ;
-+ } else if (! blend) {
-+ /*
-+ * Ugh, PseudoColor colormap is
-+ * bad news, to avoid random
-+ * colors just take the first
-+ * pixel. Or user may have
-+ * specified :nb to fraction.
-+ * The :fb will force blending
-+ * for this case.
-+ */
-+ if (I != I1) {
-+ continue;
-+ }
-+ wx = 1.0;
-+
-+ /* interpolation scheme: */
-+ } else if (! shrink || interpolate) {
-+ if (I >= Nx) {
-+ continue; /* off edge */
-+ } else if (I == I1) {
-+ wx = 1.0 - ddx;
-+ } else if (I != I1) {
-+ wx = ddx;
-+ }
-+
-+ /* integration scheme: */
-+ } else if (I < x1) {
-+ /*
-+ * source left edge (I) to the
-+ * left of dest left edge (x1):
-+ * fractional weight
-+ */
-+ wx = I+1 - x1;
-+ } else if (I+1 > x2) {
-+ /*
-+ * source right edge (I+1) to the
-+ * right of dest right edge (x2):
-+ * fractional weight
-+ */
-+ wx = x2 - I;
-+ } else {
-+ /*
-+ * source edges (I and I+1) completely
-+ * inside dest edges (x1 and x2):
-+ * full weight
-+ */
-+ wx = 1.0;
-+ }
-+
-+ w = wx * wy;
-+ wtot += w;
-+
-+ /*
-+ * We average the unsigned char value
-+ * instead of char value: otherwise
-+ * the minimum (char 0) is right next
-+ * to the maximum (char -1)! This way
-+ * they are spread between 0 and 255.
-+ */
-+ if (Bpp == 4) {
-+ /* unroll the loops, can give 20% */
-+ pixave[0] += w * ((unsigned char) *(src ));
-+ pixave[1] += w * ((unsigned char) *(src+1));
-+ pixave[2] += w * ((unsigned char) *(src+2));
-+ pixave[3] += w * ((unsigned char) *(src+3));
-+ } else if (Bpp == 2) {
-+ /*
-+ * 16bpp: trickier with green
-+ * split over two bytes, so we
-+ * use the masks:
-+ */
-+ us = *((unsigned short *) src);
-+ pixave[0] += w*(us & main_red_mask);
-+ pixave[1] += w*(us & main_green_mask);
-+ pixave[2] += w*(us & main_blue_mask);
-+ } else if (Bpp == 1) {
-+ pixave[0] += w *
-+ ((unsigned char) *(src));
-+ } else {
-+ for (b=0; b<Bpp; b++) {
-+ pixave[b] += w *
-+ ((unsigned char) *(src+b));
-+ }
-+ }
-+ src += Bpp;
-+ }
-+ }
-+
-+ if (wtot <= 0.0) {
-+ wtot = 1.0;
-+ }
-+ wtot = 1.0/wtot; /* normalization factor */
-+
-+ /* place weighted average pixel in the scaled fb: */
-+ if (Bpp == 4) {
-+ *(dest ) = (char) (wtot * pixave[0]);
-+ *(dest+1) = (char) (wtot * pixave[1]);
-+ *(dest+2) = (char) (wtot * pixave[2]);
-+ *(dest+3) = (char) (wtot * pixave[3]);
-+ } else if (Bpp == 2) {
-+ /* 16bpp / 565 case: */
-+ pixave[0] *= wtot;
-+ pixave[1] *= wtot;
-+ pixave[2] *= wtot;
-+ us = (main_red_mask & (int) pixave[0])
-+ | (main_green_mask & (int) pixave[1])
-+ | (main_blue_mask & (int) pixave[2]);
-+ *( (unsigned short *) dest ) = us;
-+ } else if (Bpp == 1) {
-+ *(dest) = (char) (wtot * pixave[0]);
-+ } else {
-+ for (b=0; b<Bpp; b++) {
-+ *(dest+b) = (char) (wtot * pixave[b]);
-+ }
-+ }
-+ dest += Bpp;
-+ }
-+ }
-+ markit:
-+/* End taken from x11vnc scale: */
-+ if (0) {}
-+}
-+
-+void do_scale_stats(int width, int height) {
-+ static double calls = 0.0, sum = 0.0, var = 0.0, last = 0.0;
-+ double A = width * height;
-+
-+ if (last == 0.0) {
-+ last = dnow();
-+ }
-+
-+ calls += 1.0;
-+ sum += A;
-+ var += A*A;
-+
-+ if (dnow() > last + 4.0) {
-+ double cnt = calls;
-+ if (cnt <= 0.0) cnt = 1.0;
-+ var /= cnt;
-+ sum /= cnt;
-+ var = var - sum * sum;
-+ if (sum > 0.0) {
-+ var = var / (sum*sum);
-+ }
-+ fprintf(stderr, "scale_rect stats: %10d %10.1f ave: %10.3f var-rat: %10.3f\n", (int) calls, sum * cnt, sum, var);
-+
-+ calls = 0.0;
-+ sum = 0.0;
-+ var = 0.0;
-+ last = dnow();
-+ }
-+}
-+
-+void put_image(int src_x, int src_y, int dst_x, int dst_y, int width,
-+ int height, int solid) {
-+ int db = 0;
-+ int xmax = si.framebufferWidth;
-+ int ymax = si.framebufferHeight;
-+
-+if (db || 0) fprintf(stderr, "put_image(%d %d %d %d %d %d)\n", src_x, src_y, dst_x, dst_y, width, height);
-+
-+ if (image_scale) {
-+ int i;
-+ static int scale_stats = -1;
-+
-+ for (i=0; i < 2; i++) {
-+ if (src_x > 0) src_x--;
-+ if (src_y > 0) src_y--;
-+ }
-+ for (i=0; i < 4; i++) {
-+ if (src_x + width < xmax) width++;
-+ if (src_y + height < ymax) height++;
-+ }
-+
-+ if (db) fprintf(stderr, "put_image(%d %d %d %d %d %d)\n", src_x, src_y, dst_x, dst_y, width, height);
-+ if (db) fprintf(stderr, "scale_rect(%d %d %d %d)\n", src_x, src_y, width, height);
-+
-+ if (scale_stats < 0) {
-+ if (getenv("SSVNC_SCALE_STATS")) {
-+ scale_stats = 1;
-+ } else {
-+ scale_stats = 0;
-+ }
-+ }
-+ if (scale_stats) {
-+ do_scale_stats(width, height);
-+ }
-+
-+ scale_rect(scale_factor_x, scale_factor_y, 1, 0, &src_x, &src_y, &width, &height, solid);
-+ dst_x = src_x;
-+ dst_y = src_y;
-+ }
-+
-+#ifdef MITSHM
-+ if (appData.useShm) {
-+ double fac = image_scale ? scale_factor_y : 1.0;
-+ if (image_ycrop == NULL) {
-+ if (image_is_shm) {
-+ XShmPutImage(dpy, desktopWin, gc, image, src_x, src_y,
-+ dst_x, dst_y, width, height, False);
-+ } else {
-+ XPutImage(dpy, desktopWin, gc, image, src_x, src_y,
-+ dst_x, dst_y, width, height);
-+ }
-+ } else if ((width < 32 && height < 32) || height > appData.yCrop * fac) {
-+ XPutImage(dpy, desktopWin, gc, image, src_x, src_y,
-+ dst_x, dst_y, width, height);
-+ } else {
-+ char *src, *dst;
-+ int Bpp = image->bits_per_pixel / 8;
-+ int Bpl = image->bytes_per_line, h;
-+ int Bpl2 = image_ycrop->bytes_per_line;
-+ src = image->data + src_y * Bpl + src_x * Bpp;
-+ dst = image_ycrop->data;
-+ for (h = 0; h < height; h++) {
-+ memcpy(dst, src, width * Bpp);
-+ src += Bpl;
-+ dst += Bpl2;
-+ }
-+ XShmPutImage(dpy, desktopWin, gc, image_ycrop, 0, 0,
-+ dst_x, dst_y, width, height, False);
-+ }
-+ } else
-+#endif
-+ {
-+ XPutImage(dpy, desktopWin, gc, image, src_x, src_y,
-+ dst_x, dst_y, width, height);
-+ }
-+}
-+
-+#if 0
-+fprintf(stderr, "non-shmB image %d %d %d %d %d %d\n", src_x, src_y, dst_x, dst_y, width, height);
-+fprintf(stderr, "shm image_ycrop %d %d %d %d %d %d\n", 0, 0, dst_x, dst_y, width, height);
-+fprintf(stderr, "non-shmA image %d %d %d %d %d %d\n", src_x, src_y, dst_x, dst_y, width, height);
-+#endif
-+
-+void releaseAllPressedModifiers(void) {
-+ int i;
-+ static int debug_release = -1;
-+ if (debug_release < 0) {
-+ if (getenv("SSVNC_DEBUG_RELEASE")) {
-+ debug_release = 1;
-+ } else {
-+ debug_release = 0;
-+ }
-+ }
-+ if (debug_release) fprintf(stderr, "into releaseAllPressedModifiers()\n");
-+ for (i = 0; i < 256; i++) {
-+ if (modifierPressed[i]) {
-+ SendKeyEvent(XKeycodeToKeysym(dpy, i, 0), False);
-+ modifierPressed[i] = False;
-+ if (debug_release) fprintf(stderr, "releasing[%d] %s\n", i, XKeysymToString(XKeycodeToKeysym(dpy, i, 0)));
-+ }
-+ }
-+}
-+
-+#define PR_EXPOSE fprintf(stderr, "Expose: %04dx%04d+%04d+%04d %04d/%04d/%04d now: %8.4f rescale: %8.4f fullscreen: %8.4f\n", width, height, x, y, si.framebufferWidth, appData.yCrop, si.framebufferHeight, now - start_time, now - last_rescale, now - last_fullscreen);
-
- /*
- * HandleBasicDesktopEvent - deal with expose and leave events.
-@@ -152,42 +1553,529 @@
- static void
- HandleBasicDesktopEvent(Widget w, XtPointer ptr, XEvent *ev, Boolean *cont)
- {
-- int i;
-+ int x, y, width, height;
-+ double now = dnow();
-
-- switch (ev->type) {
-+ if (w || ptr || cont) {}
-+
-+ if (0) {
-+ PR_EXPOSE;
-+ }
-
-+
-+ switch (ev->type) {
- case Expose:
- case GraphicsExpose:
- /* sometimes due to scrollbars being added/removed we get an expose outside
- the actual desktop area. Make sure we don't pass it on to the RFB
- server. */
-+ x = ev->xexpose.x;
-+ y = ev->xexpose.y;
-+ width = ev->xexpose.width;
-+ height = ev->xexpose.height;
-+
-+ if (image_scale) {
-+ int i;
-+ x /= scale_factor_x;
-+ y /= scale_factor_y;
-+ width /= scale_factor_x;
-+ height /= scale_factor_y;
-+ /* make them a little wider to avoid painting errors */
-+ for (i=0; i < 3; i++) {
-+ if (x > 0) x--;
-+ if (y > 0) y--;
-+ }
-+ for (i=0; i < 6; i++) {
-+ if (x + width < si.framebufferWidth) width++;
-+ if (y + height < si.framebufferHeight) height++;
-+ }
-+ }
-
-- if (ev->xexpose.x + ev->xexpose.width > si.framebufferWidth) {
-- ev->xexpose.width = si.framebufferWidth - ev->xexpose.x;
-- if (ev->xexpose.width <= 0) break;
-- }
--
-- if (ev->xexpose.y + ev->xexpose.height > si.framebufferHeight) {
-- ev->xexpose.height = si.framebufferHeight - ev->xexpose.y;
-- if (ev->xexpose.height <= 0) break;
-- }
--
-- SendFramebufferUpdateRequest(ev->xexpose.x, ev->xexpose.y,
-- ev->xexpose.width, ev->xexpose.height, False);
-- break;
-+ if (x + width > si.framebufferWidth) {
-+ width = si.framebufferWidth - x;
-+ if (width <= 0) {
-+ break;
-+ }
-+ }
-+
-+ if (y + height > si.framebufferHeight) {
-+ height = si.framebufferHeight - y;
-+ if (height <= 0) {
-+ break;
-+ }
-+ }
-+
-+ if (appData.useXserverBackingStore) {
-+ SendFramebufferUpdateRequest(x, y, width, height, False);
-+ } else {
-+ int ok = 1;
-+ double delay = 2.5;
-+ if (appData.fullScreen && now < last_fullscreen + delay) {
-+ int xmax = si.framebufferWidth;
-+ int ymax = si.framebufferHeight;
-+ if (appData.yCrop > 0) {
-+ ymax = appData.yCrop;
-+ }
-+ xmax = scale_round(xmax, scale_factor_x);
-+ ymax = scale_round(ymax, scale_factor_y);
-+ if (dpyWidth < xmax) {
-+ xmax = dpyWidth;
-+ }
-+ if (dpyHeight < ymax) {
-+ ymax = dpyHeight;
-+ }
-+ if (x != 0 && y != 0) {
-+ ok = 0;
-+ }
-+ if (width < 0.9 * xmax) {
-+ ok = 0;
-+ }
-+ if (height < 0.9 * ymax) {
-+ ok = 0;
-+ }
-+ }
-+ if (appData.yCrop > 0) {
-+ if (now < last_fullscreen + delay || now < last_rescale + delay) {
-+ if (y + height > appData.yCrop) {
-+ height = appData.yCrop - y;
-+ }
-+ }
-+ }
-+ if (ok) {
-+ put_image(x, y, x, y, width, height, 0);
-+ XSync(dpy, False);
-+ } else {
-+ fprintf(stderr, "Skip ");
-+ PR_EXPOSE;
-+ }
-+ }
-+ break;
-
- case LeaveNotify:
-- for (i = 0; i < 256; i++) {
-- if (modifierPressed[i]) {
-- SendKeyEvent(XKeycodeToKeysym(dpy, i, 0), False);
-- modifierPressed[i] = False;
-- }
-- }
-- break;
-+ releaseAllPressedModifiers();
-+ if (appData.fullScreen) {
-+ fs_ungrab(1);
-+ }
-+ break;
-+ case EnterNotify:
-+ if (appData.fullScreen) {
-+ fs_grab(1);
-+ }
-+ break;
-+ case ClientMessage:
-+ if (ev->xclient.window == XtWindow(desktop) && ev->xclient.message_type == XA_INTEGER &&
-+ ev->xclient.format == 8 && !strcmp(ev->xclient.data.b, "SendRFBUpdate")) {
-+ SendIncrementalFramebufferUpdateRequest();
-+ }
-+ break;
- }
-+ check_things();
-+}
-+
-+extern Position desktopX, desktopY;
-+
-+void x11vnc_appshare(char *cmd) {
-+ char send[200], str[100];
-+ char *id = "cmd=id_cmd";
-+ int m_big = 80, m_fine = 15;
-+ int resize = 100, db = 0;
-+
-+ if (getenv("X11VNC_APPSHARE_DEBUG")) {
-+ db = atoi(getenv("X11VNC_APPSHARE_DEBUG"));
-+ }
-+
-+ if (db) fprintf(stderr, "x11vnc_appshare: cmd=%s\n", cmd);
-+
-+ str[0] = '\0';
-+
-+ if (!strcmp(cmd, "left")) {
-+ sprintf(str, "%s:move:-%d+0", id, m_big);
-+ } else if (!strcmp(cmd, "right")) {
-+ sprintf(str, "%s:move:+%d+0", id, m_big);
-+ } else if (!strcmp(cmd, "up")) {
-+ sprintf(str, "%s:move:+0-%d", id, m_big);
-+ } else if (!strcmp(cmd, "down")) {
-+ sprintf(str, "%s:move:+0+%d", id, m_big);
-+ } else if (!strcmp(cmd, "left-fine")) {
-+ sprintf(str, "%s:move:-%d+0", id, m_fine);
-+ } else if (!strcmp(cmd, "right-fine")) {
-+ sprintf(str, "%s:move:+%d+0", id, m_fine);
-+ } else if (!strcmp(cmd, "up-fine")) {
-+ sprintf(str, "%s:move:+0-%d", id, m_fine);
-+ } else if (!strcmp(cmd, "down-fine")) {
-+ sprintf(str, "%s:move:+0+%d", id, m_fine);
-+ } else if (!strcmp(cmd, "taller")) {
-+ sprintf(str, "%s:resize:+0+%d", id, resize);
-+ } else if (!strcmp(cmd, "shorter")) {
-+ sprintf(str, "%s:resize:+0-%d", id, resize);
-+ } else if (!strcmp(cmd, "wider")) {
-+ sprintf(str, "%s:resize:+%d+0", id, resize);
-+ } else if (!strcmp(cmd, "narrower")) {
-+ sprintf(str, "%s:resize:-%d+0", id, resize);
-+ } else if (!strcmp(cmd, "lower")) {
-+ sprintf(str, "%s:lower", id);
-+ } else if (!strcmp(cmd, "raise")) {
-+ sprintf(str, "%s:raise", id);
-+ } else if (!strcmp(cmd, "delete")) {
-+ sprintf(str, "%s:wm_delete", id);
-+ } else if (!strcmp(cmd, "position")) {
-+ Position x, y;
-+ int xi, yi;
-+
-+ XtVaGetValues(toplevel, XtNx, &x, XtNy, &y, NULL);
-+ xi = (int) x;
-+ yi = (int) y;
-+ if (appData.scale) {
-+ double fx = 1.0, fy = 1.0;
-+ get_scale_values(&fx, &fy);
-+ if (fx > 0.0 && fy > 0.0) {
-+ xi /= fx;
-+ yi /= fx;
-+ }
-+ }
-+ sprintf(str, "%s:geom:0x0+%d+%d", id, xi, yi);
-+ fprintf(stderr, "str=%s\n", str);
-+ }
-+ if (strcmp(str, "")) {
-+ Bool vo = appData.viewOnly;
-+ strcpy(send, "X11VNC_APPSHARE_CMD:");
-+ strcat(send, str);
-+ if (db) fprintf(stderr, "x11vnc_appshare: send=%s\n", send);
-+ if (vo) appData.viewOnly = False;
-+ SendClientCutText(send, strlen(send));
-+ if (vo) appData.viewOnly = True;
-+ }
-+}
-+
-+void scroll_desktop(int horiz, int vert, double amount) {
-+ Dimension h, w;
-+ Position x, y;
-+ Position x2, y2;
-+ static int db = -1;
-+
-+ if (db < 0) {
-+ if (getenv("SSVNC_DEBUG_ESCAPE_KEYS")) {
-+ db = 1;
-+ } else {
-+ db = 0;
-+ }
-+ }
-+
-+ XtVaGetValues(form, XtNheight, &h, XtNwidth, &w, NULL);
-+ XtVaGetValues(desktop, XtNx, &x, XtNy, &y, NULL);
-+
-+ x2 = -x;
-+ y2 = -y;
-+
-+ if (amount == -1.0) {
-+ int dx = horiz;
-+ int dy = vert;
-+ if (dx == 0 && dy == 0) {
-+ return;
-+ }
-+ x2 -= dx;
-+ y2 -= dy;
-+ } else {
-+ if (horiz) {
-+ int dx = (int) (amount * w);
-+ if (dx < 0) dx = -dx;
-+ if (amount == 0.0) dx = 1;
-+ if (horiz > 0) {
-+ x2 += dx;
-+ } else {
-+ x2 -= dx;
-+ }
-+ if (x2 < 0) x2 = 0;
-+ }
-+ if (vert) {
-+ int dy = (int) (amount * h);
-+ if (amount == 0.0) dy = 1;
-+ if (dy < 0) dy = -dy;
-+ if (vert < 0) {
-+ y2 += dy;
-+ } else {
-+ y2 -= dy;
-+ }
-+ if (y2 < 0) y2 = 0;
-+ }
-+ }
-+
-+ if (db) fprintf(stderr, "%d %d %f viewport(%dx%d): %d %d -> %d %d\n", horiz, vert, amount, w, h, -x, -y, x2, y2);
-+ XawViewportSetCoordinates(viewport, x2, y2);
-+
-+ if (appData.fullScreen) {
-+ XSync(dpy, False);
-+ XtVaGetValues(desktop, XtNx, &x, XtNy, &y, NULL);
-+ desktopX = -x;
-+ desktopY = -y;
-+ } else if (amount == -1.0) {
-+ XSync(dpy, False);
-+ }
- }
-
-+void scale_desktop(int bigger, double frac) {
-+ double current, new;
-+ char tmp[100];
-+ char *s;
-+ int fs;
-+
-+ if (appData.scale == NULL) {
-+ s = "1.0";
-+ } else {
-+ s = appData.scale;
-+ }
-+ if (!strcmp(s, "auto")) {
-+ fprintf(stderr, "scale_desktop: skipping scale mode '%s'\n", s);
-+ return;
-+ } else if (!strcmp(s, "fit")) {
-+ fprintf(stderr, "scale_desktop: skipping scale mode '%s'\n", s);
-+ return;
-+ } else if (strstr(s, "x")) {
-+ fprintf(stderr, "scale_desktop: skipping scale mode '%s'\n", s);
-+ return;
-+ } else if (!strcmp(s, "none")) {
-+ s = "1.0";
-+ }
-+
-+ if (sscanf(s, "%lf", &current) != 1) {
-+ fprintf(stderr, "scale_desktop: skipping scale mode '%s'\n", s);
-+ return;
-+ }
-+ if (bigger) {
-+ new = current * (1.0 + frac);
-+ } else {
-+ new = current / (1.0 + frac);
-+ }
-+ if (0.99 < new && new < 1.01) {
-+ new = 1.0;
-+ }
-
-+ if (new > 5.0) {
-+ fprintf(stderr, "scale_desktop: not scaling > 5.0: %f\n", new);
-+ return;
-+ } else if (new < 0.05) {
-+ fprintf(stderr, "scale_desktop: not scaling < 0.05: %f\n", new);
-+ return;
-+ }
-+ sprintf(tmp, "%.16f", new);
-+ appData.scale = strdup(tmp);
-+
-+ fs = 0;
-+ if (appData.fullScreen) {
-+ fs = 1;
-+ FullScreenOff();
-+ }
-+ if (1) {
-+ double fx, fy;
-+ get_scale_values(&fx, &fy);
-+ if (fx > 0.0 && fy > 0.0) {
-+ rescale_image();
-+ }
-+ }
-+ if (fs) {
-+ FullScreenOn();
-+ }
-+}
-+
-+static int escape_mods[8];
-+static int escape_drag_in_progress = 0, last_x = 0, last_y = 0;
-+static double last_drag = 0.0;
-+static double last_key = 0.0;
-+
-+static int escape_sequence_pressed(void) {
-+ static char *prev = NULL;
-+ char *str = "default";
-+ int sum, i, init = 0, pressed;
-+ static int db = -1;
-+
-+ if (db < 0) {
-+ if (getenv("SSVNC_DEBUG_ESCAPE_KEYS")) {
-+ db = 1;
-+ } else {
-+ db = 0;
-+ }
-+ }
-+
-+ if (appData.escapeKeys != NULL) {
-+ str = appData.escapeKeys;
-+ }
-+ if (prev == NULL) {
-+ init = 1;
-+ prev = strdup(str);
-+ } else {
-+ if (strcmp(prev, str)) {
-+ init = 1;
-+ free(prev);
-+ prev = strdup(str);
-+ }
-+ }
-+ if (db) fprintf(stderr, "str: %s\n", str);
-+
-+ if (init) {
-+ char *p, *s;
-+ KeySym ks;
-+ int k = 0, failed = 0;
-+
-+ for (i = 0; i < 8; i++) {
-+ escape_mods[i] = -1;
-+ }
-+
-+ if (!strcasecmp(str, "default")) {
-+#if (defined(__MACH__) && defined(__APPLE__))
-+ s = strdup("Control_L,Meta_L");
-+#else
-+ s = strdup("Alt_L,Super_L");
-+#endif
-+ } else {
-+ s = strdup(str);
-+ }
-+
-+ p = strtok(s, ",+ ");
-+ while (p) {
-+ ks = XStringToKeysym(p);
-+ if (ks == XK_Shift_L || ks == XK_Shift_R) {
-+ putenv("NO_X11VNC_APPSHARE=1");
-+ }
-+ if (k >= 8) {
-+ fprintf(stderr, "EscapeKeys: more than 8 modifier keys.\n");
-+ failed = 1;
-+ break;
-+ }
-+ if (ks == NoSymbol) {
-+ fprintf(stderr, "EscapeKeys: failed lookup for '%s'\n", p);
-+ failed = 1;
-+ break;
-+ } else if (!IsModifierKey(ks)) {
-+ fprintf(stderr, "EscapeKeys: not a modifier key '%s'\n", p);
-+ failed = 1;
-+ break;
-+ } else {
-+ KeyCode kc = XKeysymToKeycode(dpy, ks);
-+ if (kc == NoSymbol) {
-+ fprintf(stderr, "EscapeKeys: no keycode for modifier key '%s'\n", p);
-+ failed = 1;
-+ break;
-+ }
-+ if (db) fprintf(stderr, "set: %d %d\n", k, kc);
-+ escape_mods[k++] = kc;
-+ }
-+
-+ p = strtok(NULL, ",+ ");
-+ }
-+ free(s);
-+
-+ if (failed) {
-+ for (i = 0; i < 8; i++) {
-+ escape_mods[i] = -1;
-+ }
-+ }
-+ }
-+
-+ pressed = 1;
-+ sum = 0;
-+ for (i = 0; i < 8; i++) {
-+ int kc = escape_mods[i];
-+ if (kc != -1 && kc < 256) {
-+ if (db) fprintf(stderr, "try1: %d %d = %d\n", i, kc, modifierPressed[kc]);
-+ if (!modifierPressed[kc]) {
-+ pressed = 0;
-+ break;
-+ } else {
-+ sum++;
-+ }
-+ }
-+ }
-+ if (sum == 0) pressed = 0;
-+
-+ if (!pressed) {
-+ /* user may have dragged mouse outside of toplevel window */
-+ int i, k;
-+ int keystate[256];
-+ char keys[32];
-+
-+ /* so query server instead of modifierPressed[] */
-+ XQueryKeymap(dpy, keys);
-+ for (i=0; i<32; i++) {
-+ char c = keys[i];
-+
-+ for (k=0; k < 8; k++) {
-+ if (c & 0x1) {
-+ keystate[8*i + k] = 1;
-+ } else {
-+ keystate[8*i + k] = 0;
-+ }
-+ c = c >> 1;
-+ }
-+ }
-+
-+ /* check again using keystate[] */
-+ pressed = 2;
-+ sum = 0;
-+ for (i = 0; i < 8; i++) {
-+ int kc = escape_mods[i];
-+ if (kc != -1 && kc < 256) {
-+ if (db) fprintf(stderr, "try2: %d %d = %d\n", i, kc, keystate[kc]);
-+ if (!keystate[kc]) {
-+ pressed = 0;
-+ break;
-+ } else {
-+ sum++;
-+ }
-+ }
-+ }
-+ if (sum == 0) pressed = 0;
-+ }
-+
-+ return pressed;
-+}
-+
-+static int shift_is_down(void) {
-+ int shift_down = 0;
-+ KeyCode kc;
-+
-+ if (appData.viewOnly) {
-+ int i, k;
-+ char keys[32];
-+ int keystate[256];
-+
-+ XQueryKeymap(dpy, keys);
-+ for (i=0; i<32; i++) {
-+ char c = keys[i];
-+
-+ for (k=0; k < 8; k++) {
-+ if (c & 0x1) {
-+ keystate[8*i + k] = 1;
-+ } else {
-+ keystate[8*i + k] = 0;
-+ }
-+ c = c >> 1;
-+ }
-+ }
-+
-+ kc = XKeysymToKeycode(dpy, XK_Shift_L);
-+ if (kc != NoSymbol && keystate[kc]) {
-+ shift_down = 1;
-+ } else {
-+ kc = XKeysymToKeycode(dpy, XK_Shift_R);
-+ if (kc != NoSymbol && keystate[kc]) {
-+ shift_down = 1;
-+ }
-+ }
-+ return shift_down;
-+ } else {
-+ kc = XKeysymToKeycode(dpy, XK_Shift_L);
-+ if (kc != NoSymbol && modifierPressed[kc]) {
-+ shift_down = 1;
-+ } else {
-+ kc = XKeysymToKeycode(dpy, XK_Shift_R);
-+ if (kc != NoSymbol && modifierPressed[kc]) {
-+ shift_down = 1;
-+ }
-+ }
-+ return shift_down;
-+ }
-+}
-+
- /*
- * SendRFBEvent is an action which sends an RFB event. It can be used in two
- * ways. Without any parameters it simply sends an RFB event corresponding to
-@@ -201,127 +2089,406 @@
- * button2 down, 3 for both, etc).
- */
-
-+extern Bool selectingSingleWindow;
-+
-+extern Cursor dotCursor3;
-+extern Cursor dotCursor4;
-+
-+extern void set_server_scale(int);
-+
- void
- SendRFBEvent(Widget w, XEvent *ev, String *params, Cardinal *num_params)
- {
-- KeySym ks;
-- char keyname[256];
-- int buttonMask, x, y;
--
-- if (appData.fullScreen && ev->type == MotionNotify) {
-- if (BumpScroll(ev))
-- return;
-- }
-+ KeySym ks;
-+ char keyname[256];
-+ int buttonMask, x, y;
-+ int do_escape;
-+ static int db = -1;
-+ char *ek = appData.escapeKeys;
-+
-+ if (db < 0) {
-+ if (getenv("SSVNC_DEBUG_ESCAPE_KEYS")) {
-+ db = 1;
-+ } else {
-+ db = 0;
-+ }
-+ }
-+
-+ if (ev->type == MotionNotify || ev->type == KeyRelease) {
-+ static double last = 0.0;
-+ double now = dnow();
-+ if (now > last + 0.25) {
-+ check_things();
-+ last = now;
-+ }
-+ }
-+
-+ if (selectingSingleWindow && ev->type == ButtonPress) {
-+ selectingSingleWindow = False;
-+ SendSingleWindow(ev->xbutton.x, ev->xbutton.y);
-+ if (appData.viewOnly) {
-+ XDefineCursor(dpy, desktopWin, dotCursor4);
-+ } else {
-+ XDefineCursor(dpy, desktopWin, dotCursor3);
-+ }
-+ return;
-+ }
-
-- if (appData.viewOnly) return;
-+ if (appData.fullScreen && ev->type == MotionNotify && !escape_drag_in_progress) {
-+ if (BumpScroll(ev)) {
-+ return;
-+ }
-+ }
-+
-+ do_escape = 0;
-+ if (ek != NULL && (ek[0] == 'n' || ek[0] == 'N') && !strcasecmp(ek, "never")) {
-+ ;
-+ } else if (appData.viewOnly) {
-+ do_escape = 1;
-+ } else if (appData.escapeActive) {
-+ int skip = 0, is_key = 0;
-+
-+ if (ev->type == KeyPress || ev->type == KeyRelease) {
-+ is_key = 1;
-+ XLookupString(&ev->xkey, keyname, 256, &ks, NULL);
-+ if (IsModifierKey(ks)) {
-+ skip = 1;
-+ }
-+ }
-+ if (!skip) {
-+ int es = escape_sequence_pressed();
-+ if (es == 1) {
-+ do_escape = 1;
-+ } else if (es == 2) {
-+ if (is_key) {
-+ if (dnow() < last_key + 5.0) {
-+ do_escape = 1;
-+ }
-+ } else {
-+ if (dnow() < last_drag + 5.0) {
-+ do_escape = 1;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ if (!do_escape) {
-+ escape_drag_in_progress = 0;
-+ }
-+ if (db) fprintf(stderr, "do_escape: %d\n", do_escape);
-+
-+ if (do_escape) {
-+ int W = si.framebufferWidth;
-+ int H = si.framebufferHeight;
-+ int shift_down = 0;
-+
-+ if (!getenv("NO_X11VNC_APPSHARE")) {
-+ shift_down = shift_is_down();
-+ }
-+ if (db) fprintf(stderr, "shift_down: %d\n", shift_down);
-+
-+ if (*num_params != 0) {
-+ if (strcasecmp(params[0],"fbupdate") == 0) {
-+ SendFramebufferUpdateRequest(0, 0, W, H, False);
-+ }
-+ }
-+ if (ev->type == ButtonRelease) {
-+ XButtonEvent *b = (XButtonEvent *) ev;
-+ if (db) fprintf(stderr, "ButtonRelease: %d %d %d\n", b->x_root, b->y_root, b->state);
-+ if (b->button == 3) {
-+ if (shift_down) {
-+ x11vnc_appshare("delete");
-+ } else {
-+ ShowPopup(w, ev, params, num_params);
-+ }
-+ } else if (escape_drag_in_progress && b->button == 1) {
-+ escape_drag_in_progress = 0;
-+ }
-+ } else if (ev->type == ButtonPress) {
-+ XButtonEvent *b = (XButtonEvent *) ev;
-+ if (db) fprintf(stderr, "ButtonPress: %d %d %d\n", b->x_root, b->y_root, b->state);
-+ if (b->button == 1) {
-+ if (shift_down) {
-+ x11vnc_appshare("position");
-+ } else {
-+ escape_drag_in_progress = 1;
-+ last_x = b->x_root;
-+ last_y = b->y_root;
-+ }
-+ } else {
-+ escape_drag_in_progress = 0;
-+ }
-+ } else if (ev->type == MotionNotify) {
-+ XMotionEvent *m = (XMotionEvent *) ev;
-+ if (escape_drag_in_progress) {
-+ if (db) fprintf(stderr, "MotionNotify: %d %d %d\n", m->x_root, m->y_root, m->state);
-+ scroll_desktop(m->x_root - last_x, m->y_root - last_y, -1.0);
-+ last_x = m->x_root;
-+ last_y = m->y_root;
-+ }
-+ } else if (ev->type == KeyRelease) {
-+ int did = 1;
-+
-+ XLookupString(&ev->xkey, keyname, 256, &ks, NULL);
-+ if (ks == XK_1 || ks == XK_KP_1) {
-+ set_server_scale(1);
-+ } else if (ks == XK_2 || ks == XK_KP_2) {
-+ set_server_scale(2);
-+ } else if (ks == XK_3 || ks == XK_KP_3) {
-+ set_server_scale(3);
-+ } else if (ks == XK_4 || ks == XK_KP_4) {
-+ set_server_scale(4);
-+ } else if (ks == XK_5 || ks == XK_KP_5) {
-+ set_server_scale(5);
-+ } else if (ks == XK_6 || ks == XK_KP_6) {
-+ set_server_scale(6);
-+ } else if (ks == XK_r || ks == XK_R) {
-+ SendFramebufferUpdateRequest(0, 0, W, H, False);
-+ } else if (ks == XK_b || ks == XK_B) {
-+ ToggleBell(w, ev, params, num_params);
-+ } else if (ks == XK_c || ks == XK_C) {
-+ Toggle8bpp(w, ev, params, num_params);
-+ } else if (ks == XK_x || ks == XK_X) {
-+ ToggleX11Cursor(w, ev, params, num_params);
-+ } else if (ks == XK_z || ks == XK_Z) {
-+ ToggleTightZRLE(w, ev, params, num_params);
-+ } else if (ks == XK_h || ks == XK_H) {
-+ ToggleTightHextile(w, ev, params, num_params);
-+ } else if (ks == XK_f || ks == XK_F) {
-+ ToggleFileXfer(w, ev, params, num_params);
-+ } else if (ks == XK_V) {
-+ ToggleViewOnly(w, ev, params, num_params);
-+ } else if (ks == XK_Q) {
-+ Quit(w, ev, params, num_params);
-+ } else if (ks == XK_l || ks == XK_L) {
-+ ToggleFullScreen(w, ev, params, num_params);
-+ } else if (ks == XK_a || ks == XK_A) {
-+ ToggleCursorAlpha(w, ev, params, num_params);
-+ } else if (ks == XK_s || ks == XK_S) {
-+ SetScale(w, ev, params, num_params);
-+ } else if (ks == XK_t || ks == XK_T) {
-+ ToggleTextChat(w, ev, params, num_params);
-+ } else if (ks == XK_e || ks == XK_E) {
-+ SetEscapeKeys(w, ev, params, num_params);
-+ } else if (ks == XK_g || ks == XK_G) {
-+ ToggleXGrab(w, ev, params, num_params);
-+ } else if (ks == XK_D) {
-+ if (shift_down || appData.appShare) {
-+ x11vnc_appshare("delete");
-+ }
-+ } else if (ks == XK_M) {
-+ if (shift_down || appData.appShare) {
-+ x11vnc_appshare("position");
-+ }
-+ } else if (ks == XK_Left) {
-+ if (shift_down) {
-+ x11vnc_appshare("left");
-+ } else {
-+ scroll_desktop(-1, 0, 0.1);
-+ }
-+ } else if (ks == XK_Right) {
-+ if (shift_down) {
-+ x11vnc_appshare("right");
-+ } else {
-+ scroll_desktop(+1, 0, 0.1);
-+ }
-+ } else if (ks == XK_Up) {
-+ if (shift_down) {
-+ x11vnc_appshare("up");
-+ } else {
-+ scroll_desktop(0, +1, 0.1);
-+ }
-+ } else if (ks == XK_Down) {
-+ if (shift_down) {
-+ x11vnc_appshare("down");
-+ } else {
-+ scroll_desktop(0, -1, 0.1);
-+ }
-+ } else if (ks == XK_KP_Left) {
-+ if (shift_down) {
-+ x11vnc_appshare("left-fine");
-+ } else {
-+ scroll_desktop(-1, 0, 0.0);
-+ }
-+ } else if (ks == XK_KP_Right) {
-+ if (shift_down) {
-+ x11vnc_appshare("right-fine");
-+ } else {
-+ scroll_desktop(+1, 0, 0.0);
-+ }
-+ } else if (ks == XK_KP_Up) {
-+ if (shift_down) {
-+ x11vnc_appshare("up-fine");
-+ } else {
-+ scroll_desktop(0, +1, 0.0);
-+ }
-+ } else if (ks == XK_KP_Down) {
-+ if (shift_down) {
-+ x11vnc_appshare("down-fine");
-+ } else {
-+ scroll_desktop(0, -1, 0.0);
-+ }
-+ } else if (ks == XK_Next || ks == XK_KP_Next) {
-+ if (shift_down && ks == XK_Next) {
-+ x11vnc_appshare("shorter");
-+ } else {
-+ scroll_desktop(0, -1, 1.0);
-+ }
-+ } else if (ks == XK_Prior || ks == XK_KP_Prior) {
-+ if (shift_down && ks == XK_Prior) {
-+ x11vnc_appshare("taller");
-+ } else {
-+ scroll_desktop(0, +1, 1.0);
-+ }
-+ } else if (ks == XK_End || ks == XK_KP_End) {
-+ if (shift_down && ks == XK_End) {
-+ x11vnc_appshare("narrower");
-+ } else {
-+ scroll_desktop(+1, 0, 1.0);
-+ }
-+ } else if (ks == XK_Home || ks == XK_KP_Home) {
-+ if (shift_down && ks == XK_Home) {
-+ x11vnc_appshare("wider");
-+ } else {
-+ scroll_desktop(-1, 0, 1.0);
-+ }
-+ } else if (ks == XK_equal || ks == XK_plus) {
-+ if (shift_down) {
-+ x11vnc_appshare("raise");
-+ } else {
-+ scale_desktop(1, 0.1);
-+ }
-+ } else if (ks == XK_underscore || ks == XK_minus) {
-+ if (shift_down) {
-+ x11vnc_appshare("lower");
-+ } else {
-+ scale_desktop(0, 0.1);
-+ }
-+ } else {
-+ did = 0;
-+ }
-+ if (did) {
-+ last_key = dnow();
-+ }
-+ }
-+ if (escape_drag_in_progress) {
-+ last_drag = dnow();
-+ }
-+ return;
-+ }
-+ if (appData.viewOnly) {
-+ return;
-+ }
-+
-+ if (*num_params != 0) {
-+ if (strncasecmp(params[0],"key",3) == 0) {
-+ if (*num_params != 2) {
-+ fprintf(stderr, "Invalid params: "
-+ "SendRFBEvent(key|keydown|keyup,<keysym>)\n");
-+ return;
-+ }
-+ ks = XStringToKeysym(params[1]);
-+ if (ks == NoSymbol) {
-+ fprintf(stderr,"Invalid keysym '%s' passed to "
-+ "SendRFBEvent\n", params[1]);
-+ return;
-+ }
-+ if (strcasecmp(params[0],"keydown") == 0) {
-+ SendKeyEvent(ks, 1);
-+ } else if (strcasecmp(params[0],"keyup") == 0) {
-+ SendKeyEvent(ks, 0);
-+ } else if (strcasecmp(params[0],"key") == 0) {
-+ SendKeyEvent(ks, 1);
-+ SendKeyEvent(ks, 0);
-+ } else {
-+ fprintf(stderr,"Invalid event '%s' passed to "
-+ "SendRFBEvent\n", params[0]);
-+ return;
-+ }
-+ } else if (strcasecmp(params[0],"fbupdate") == 0) {
-+ if (*num_params != 1) {
-+ fprintf(stderr, "Invalid params: "
-+ "SendRFBEvent(fbupdate)\n");
-+ return;
-+ }
-+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
-+ si.framebufferHeight, False);
-+
-+ } else if (strcasecmp(params[0],"ptr") == 0) {
-+ if (*num_params == 4) {
-+ x = atoi(params[1]);
-+ y = atoi(params[2]);
-+ buttonMask = atoi(params[3]);
-+ SendPointerEvent(x, y, buttonMask);
-+ } else if (*num_params == 2) {
-+ switch (ev->type) {
-+ case ButtonPress:
-+ case ButtonRelease:
-+ x = ev->xbutton.x;
-+ y = ev->xbutton.y;
-+ break;
-+ case KeyPress:
-+ case KeyRelease:
-+ x = ev->xkey.x;
-+ y = ev->xkey.y;
-+ break;
-+ default:
-+ fprintf(stderr, "Invalid event caused "
-+ "SendRFBEvent(ptr,<buttonMask>)\n");
-+ return;
-+ }
-+ buttonMask = atoi(params[1]);
-+ SendPointerEvent(x, y, buttonMask);
-+ } else {
-+ fprintf(stderr, "Invalid params: "
-+ "SendRFBEvent(ptr,<x>,<y>,<buttonMask>)\n"
-+ " or SendRFBEvent(ptr,<buttonMask>)\n");
-+ return;
-+ }
-+ } else {
-+ fprintf(stderr,"Invalid event '%s' passed to "
-+ "SendRFBEvent\n", params[0]);
-+ }
-+ return;
-+ }
-
-- if (*num_params != 0) {
-- if (strncasecmp(params[0],"key",3) == 0) {
-- if (*num_params != 2) {
-- fprintf(stderr,
-- "Invalid params: SendRFBEvent(key|keydown|keyup,<keysym>)\n");
-- return;
-- }
-- ks = XStringToKeysym(params[1]);
-- if (ks == NoSymbol) {
-- fprintf(stderr,"Invalid keysym '%s' passed to SendRFBEvent\n",
-- params[1]);
-- return;
-- }
-- if (strcasecmp(params[0],"keydown") == 0) {
-- SendKeyEvent(ks, 1);
-- } else if (strcasecmp(params[0],"keyup") == 0) {
-- SendKeyEvent(ks, 0);
-- } else if (strcasecmp(params[0],"key") == 0) {
-- SendKeyEvent(ks, 1);
-- SendKeyEvent(ks, 0);
-- } else {
-- fprintf(stderr,"Invalid event '%s' passed to SendRFBEvent\n",
-- params[0]);
-- return;
-- }
-- } else if (strcasecmp(params[0],"fbupdate") == 0) {
-- if (*num_params != 1) {
-- fprintf(stderr, "Invalid params: SendRFBEvent(fbupdate)\n");
-- return;
-- }
-- SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
-- si.framebufferHeight, False);
-- } else if (strcasecmp(params[0],"ptr") == 0) {
-- if (*num_params == 4) {
-- x = atoi(params[1]);
-- y = atoi(params[2]);
-- buttonMask = atoi(params[3]);
-- SendPointerEvent(x, y, buttonMask);
-- } else if (*num_params == 2) {
- switch (ev->type) {
-+ case MotionNotify:
-+ while (XCheckTypedWindowEvent(dpy, desktopWin, MotionNotify, ev)) {
-+ ; /* discard all queued motion notify events */
-+ }
-+
-+ SendPointerEvent(ev->xmotion.x, ev->xmotion.y,
-+ (ev->xmotion.state & 0x1f00) >> 8);
-+ return;
-+
- case ButtonPress:
-+ SendPointerEvent(ev->xbutton.x, ev->xbutton.y,
-+ (((ev->xbutton.state & 0x1f00) >> 8) |
-+ (1 << (ev->xbutton.button - 1))));
-+ return;
-+
- case ButtonRelease:
-- x = ev->xbutton.x;
-- y = ev->xbutton.y;
-- break;
-+ SendPointerEvent(ev->xbutton.x, ev->xbutton.y,
-+ (((ev->xbutton.state & 0x1f00) >> 8) &
-+ ~(1 << (ev->xbutton.button - 1))));
-+ return;
-+
- case KeyPress:
- case KeyRelease:
-- x = ev->xkey.x;
-- y = ev->xkey.y;
-- break;
-- default:
-- fprintf(stderr,
-- "Invalid event caused SendRFBEvent(ptr,<buttonMask>)\n");
-- return;
-- }
-- buttonMask = atoi(params[1]);
-- SendPointerEvent(x, y, buttonMask);
-- } else {
-- fprintf(stderr,
-- "Invalid params: SendRFBEvent(ptr,<x>,<y>,<buttonMask>)\n"
-- " or SendRFBEvent(ptr,<buttonMask>)\n");
-- return;
-- }
--
-- } else {
-- fprintf(stderr,"Invalid event '%s' passed to SendRFBEvent\n", params[0]);
-- }
-- return;
-- }
--
-- switch (ev->type) {
-+ XLookupString(&ev->xkey, keyname, 256, &ks, NULL);
-
-- case MotionNotify:
-- while (XCheckTypedWindowEvent(dpy, desktopWin, MotionNotify, ev))
-- ; /* discard all queued motion notify events */
--
-- SendPointerEvent(ev->xmotion.x, ev->xmotion.y,
-- (ev->xmotion.state & 0x1f00) >> 8);
-- return;
--
-- case ButtonPress:
-- SendPointerEvent(ev->xbutton.x, ev->xbutton.y,
-- (((ev->xbutton.state & 0x1f00) >> 8) |
-- (1 << (ev->xbutton.button - 1))));
-- return;
--
-- case ButtonRelease:
-- SendPointerEvent(ev->xbutton.x, ev->xbutton.y,
-- (((ev->xbutton.state & 0x1f00) >> 8) &
-- ~(1 << (ev->xbutton.button - 1))));
-- return;
--
-- case KeyPress:
-- case KeyRelease:
-- XLookupString(&ev->xkey, keyname, 256, &ks, NULL);
--
-- if (IsModifierKey(ks)) {
-- ks = XKeycodeToKeysym(dpy, ev->xkey.keycode, 0);
-- modifierPressed[ev->xkey.keycode] = (ev->type == KeyPress);
-- }
-+ if (IsModifierKey(ks)) {
-+ ks = XKeycodeToKeysym(dpy, ev->xkey.keycode, 0);
-+ modifierPressed[ev->xkey.keycode] = (ev->type == KeyPress);
-+ }
-
-- SendKeyEvent(ks, (ev->type == KeyPress));
-- return;
-+ SendKeyEvent(ks, (ev->type == KeyPress));
-+ return;
-
-- default:
-- fprintf(stderr,"Invalid event passed to SendRFBEvent\n");
-- }
-+ default:
-+ fprintf(stderr,"Invalid event passed to SendRFBEvent\n");
-+ }
- }
-
-
-@@ -329,68 +2496,255 @@
- * CreateDotCursor.
- */
-
-+#ifndef very_small_dot_cursor
- static Cursor
--CreateDotCursor()
-+CreateDotCursor(int which)
- {
-- Cursor cursor;
-- Pixmap src, msk;
-- static char srcBits[] = { 0, 14,14,14, 0 };
-- static char mskBits[] = { 14,31,31,31,14 };
-- XColor fg, bg;
--
-- src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits, 5, 5);
-- msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits, 5, 5);
-- XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "black",
-- &fg, &fg);
-- XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "white",
-- &bg, &bg);
-- cursor = XCreatePixmapCursor(dpy, src, msk, &fg, &bg, 2, 2);
-- XFreePixmap(dpy, src);
-- XFreePixmap(dpy, msk);
-+ Cursor cursor;
-+ Pixmap src, msk;
-+ static char srcBits3[] = { 0x00, 0x02, 0x00 };
-+ static char mskBits3[] = { 0x02, 0x07, 0x02 };
-+ static char srcBits4[] = { 0x00, 0x06, 0x06, 0x00 };
-+ static char mskBits4[] = { 0x06, 0x0f, 0x0f, 0x06 };
-+ XColor fg, bg;
-+
-+ if (which == 3) {
-+ src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits3, 3, 3);
-+ msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits3, 3, 3);
-+ } else {
-+ src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits4, 4, 4);
-+ msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits4, 4, 4);
-+ }
-+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "black",
-+ &fg, &fg);
-+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "white",
-+ &bg, &bg);
-+ cursor = XCreatePixmapCursor(dpy, src, msk, &fg, &bg, 1, 1);
-+ XFreePixmap(dpy, src);
-+ XFreePixmap(dpy, msk);
-
-- return cursor;
-+ return cursor;
- }
-+#else
-+static Cursor
-+CreateDotCursor()
-+{
-+ Cursor cursor;
-+ Pixmap src, msk;
-+ static char srcBits[] = { 0, 14, 0 };
-+ static char mskBits[] = { 14,31,14 };
-+ XColor fg, bg;
-+
-+ src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits, 3, 3);
-+ msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits, 3, 3);
-+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "black",
-+ &fg, &fg);
-+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "white",
-+ &bg, &bg);
-+ cursor = XCreatePixmapCursor(dpy, src, msk, &fg, &bg, 1, 1);
-+ XFreePixmap(dpy, src);
-+ XFreePixmap(dpy, msk);
-
-+ return cursor;
-+}
-+#endif
-
-+int skip_maybe_sync = 0;
-+void maybe_sync(int width, int height) {
-+ static int singles = 0, always_skip = -1;
-+ int singles_max = 64;
-+
-+ if (always_skip < 0) {
-+ if (getenv("SSVNC_NO_MAYBE_SYNC")) {
-+ always_skip = 1;
-+ } else {
-+ always_skip = 0;
-+ }
-+ }
-+ if (skip_maybe_sync || always_skip) {
-+ return;
-+ }
-+#if 0
-+ if (width > 1 || height > 1) {
-+ XSync(dpy, False);
-+ singles = 0;
-+ } else {
-+ if (++singles >= singles_max) {
-+ singles = 0;
-+ XSync(dpy, False);
-+ }
-+ }
-+#else
-+ if (width * height >= singles_max) {
-+ XSync(dpy, False);
-+ singles = 0;
-+ } else {
-+ singles += width * height;
-+ if (singles >= singles_max) {
-+ XSync(dpy, False);
-+ singles = 0;
-+ }
-+ }
-+#endif
-+}
- /*
-- * CopyDataToScreen.
-+ * FillImage.
- */
-
- void
--CopyDataToScreen(char *buf, int x, int y, int width, int height)
-+FillScreen(int x, int y, int width, int height, unsigned long fill)
- {
-- if (appData.rawDelay != 0) {
-- XFillRectangle(dpy, desktopWin, gc, x, y, width, height);
-+ XImage *im = image_scale ? image_scale : image;
-+ int bpp = im->bits_per_pixel;
-+ int Bpp = im->bits_per_pixel / 8;
-+ int Bpl = im->bytes_per_line;
-+ int h, widthInBytes = width * Bpp;
-+ static char *buf = NULL;
-+ static int buflen = 0;
-+ unsigned char *ucp;
-+ unsigned short *usp;
-+ unsigned int *uip;
-+ char *scr;
-+ int b0, b1, b2;
-
-- XSync(dpy,False);
-+#if 0
-+fprintf(stderr, "FillImage bpp=%d %04dx%04d+%04d+%04d -- 0x%x\n", bpp, width, height, x, y, fill);
-+#endif
-+ if (appData.chatOnly) {
-+ return;
-+ }
-
-- usleep(appData.rawDelay * 1000);
-- }
-+ if (widthInBytes > buflen || !buf) {
-+ if (buf) {
-+ free(buf);
-+ }
-+ buflen = widthInBytes * 2;
-+ buf = (char *)malloc(buflen);
-+ }
-+ ucp = (unsigned char*) buf;
-+ usp = (unsigned short*) buf;
-+ uip = (unsigned int*) buf;
-+
-+ if (isLSB) {
-+ b0 = 0; b1 = 1; b2 = 2;
-+ } else {
-+ b0 = 2; b1 = 1; b2 = 0;
-+ }
-
-- if (!appData.useBGR233) {
-- int h;
-- int widthInBytes = width * myFormat.bitsPerPixel / 8;
-- int scrWidthInBytes = si.framebufferWidth * myFormat.bitsPerPixel / 8;
--
-- char *scr = (image->data + y * scrWidthInBytes
-- + x * myFormat.bitsPerPixel / 8);
--
-- for (h = 0; h < height; h++) {
-- memcpy(scr, buf, widthInBytes);
-- buf += widthInBytes;
-- scr += scrWidthInBytes;
-- }
-- } else {
-- CopyBGR233ToScreen((CARD8 *)buf, x, y, width, height);
-- }
-+ for (h = 0; h < width; h++) {
-+ if (bpp == 8) {
-+ *(ucp+h) = (unsigned char) fill;
-+ } else if (bpp == 16) {
-+ *(usp+h) = (unsigned short) fill;
-+ } else if (bpp == 24) {
-+ *(ucp + 3*h + b0) = (unsigned char) ((fill & 0x0000ff) >> 0);
-+ *(ucp + 3*h + b1) = (unsigned char) ((fill & 0x00ff00) >> 8);
-+ *(ucp + 3*h + b2) = (unsigned char) ((fill & 0xff0000) >> 16);
-+ } else if (bpp == 32) {
-+ *(uip+h) = (unsigned int) fill;
-+ }
-+ }
-
--#ifdef MITSHM
-- if (appData.useShm) {
-- XShmPutImage(dpy, desktopWin, gc, image, x, y, x, y, width, height, False);
-- return;
-- }
-+ scr = im->data + y * Bpl + x * Bpp;
-+
-+ for (h = 0; h < height; h++) {
-+ memcpy(scr, buf, widthInBytes);
-+ scr += Bpl;
-+ }
-+ put_image(x, y, x, y, width, height, 1);
-+ maybe_sync(width, height);
-+}
-+
-+void copy_rect(int x, int y, int width, int height, int src_x, int src_y) {
-+ char *src, *dst;
-+ int i;
-+ XImage *im = image_scale ? image_scale : image;
-+ int Bpp = im->bits_per_pixel / 8;
-+ int Bpl = im->bytes_per_line;
-+ int did2 = 0;
-+
-+#if 0
-+fprintf(stderr, "copy_rect: %04dx%04d+%04d+%04d -- %04d %04d Bpp=%d Bpl=%d\n", width, height, x, y, src_x, src_y, Bpp, Bpl);
- #endif
-- XPutImage(dpy, desktopWin, gc, image, x, y, x, y, width, height);
-+ copyrect2:
-+
-+ if (y < src_y) {
-+ src = im->data + src_y * Bpl + src_x * Bpp;
-+ dst = im->data + y * Bpl + x * Bpp;
-+ for (i = 0; i < height; i++) {
-+ memmove(dst, src, Bpp * width);
-+ src += Bpl;
-+ dst += Bpl;
-+ }
-+ } else {
-+ src = im->data + (src_y + height - 1) * Bpl + src_x * Bpp;
-+ dst = im->data + (y + height - 1) * Bpl + x * Bpp;
-+ for (i = 0; i < height; i++) {
-+ memmove(dst, src, Bpp * width);
-+ src -= Bpl;
-+ dst -= Bpl;
-+ }
-+ }
-+
-+ if (image_scale && !did2) {
-+ im = image;
-+ Bpp = im->bits_per_pixel / 8;
-+ Bpl = im->bytes_per_line;
-+
-+ x *= scale_factor_x;
-+ y *= scale_factor_y;
-+ src_x *= scale_factor_x;
-+ src_y *= scale_factor_y;
-+ width = scale_round(width, scale_factor_x);
-+ height = scale_round(height, scale_factor_y);
-+
-+ did2 = 1;
-+ goto copyrect2;
-+ }
-+}
-+
-+
-+/*
-+ * CopyDataToScreen.
-+ */
-+
-+void
-+CopyDataToScreen(char *buf, int x, int y, int width, int height)
-+{
-+ if (appData.chatOnly) {
-+ return;
-+ }
-+ if (appData.rawDelay != 0) {
-+ XFillRectangle(dpy, desktopWin, gc, x, y, width, height);
-+ XSync(dpy,False);
-+ usleep(appData.rawDelay * 1000);
-+ }
-+
-+ if (appData.useBGR233) {
-+ CopyBGR233ToScreen((CARD8 *)buf, x, y, width, height);
-+ } else if (appData.useBGR565) {
-+ CopyBGR565ToScreen((CARD16 *)buf, x, y, width, height);
-+ } else {
-+ int h;
-+ int widthInBytes = width * myFormat.bitsPerPixel / 8;
-+ int scrWidthInBytes = si.framebufferWidth * myFormat.bitsPerPixel / 8;
-+ char *scr;
-+ XImage *im = image_scale ? image_scale : image;
-+
-+ if (scrWidthInBytes != im->bytes_per_line) scrWidthInBytes = im->bytes_per_line;
-+
-+ scr = (im->data + y * scrWidthInBytes
-+ + x * myFormat.bitsPerPixel / 8);
-+
-+ for (h = 0; h < height; h++) {
-+ memcpy(scr, buf, widthInBytes);
-+ buf += widthInBytes;
-+ scr += scrWidthInBytes;
-+ }
-+ }
-+
-+ put_image(x, y, x, y, width, height, 0);
-+ maybe_sync(width, height);
- }
-
-
-@@ -401,62 +2755,338 @@
- static void
- CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height)
- {
-- int p, q;
-- int xoff = 7 - (x & 7);
-- int xcur;
-- int fbwb = si.framebufferWidth / 8;
-- CARD8 *scr1 = ((CARD8 *)image->data) + y * fbwb + x / 8;
-- CARD8 *scrt;
-- CARD8 *scr8 = ((CARD8 *)image->data) + y * si.framebufferWidth + x;
-- CARD16 *scr16 = ((CARD16 *)image->data) + y * si.framebufferWidth + x;
-- CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x;
-+ XImage *im = image_scale ? image_scale : image;
-+ int p, q;
-+ int xoff = 7 - (x & 7);
-+ int xcur;
-+ int fbwb = si.framebufferWidth / 8;
-+ int src_width8 = im->bytes_per_line/1;
-+ int src_width16 = im->bytes_per_line/2;
-+ int src_width32 = im->bytes_per_line/4;
-+ CARD8 *src1 = ((CARD8 *)im->data) + y * fbwb + x / 8;
-+ CARD8 *srct;
-+ CARD8 *src8 = ( (CARD8 *)im->data) + y * src_width8 + x;
-+ CARD16 *src16 = ((CARD16 *)im->data) + y * src_width16 + x;
-+ CARD32 *src32 = ((CARD32 *)im->data) + y * src_width32 + x;
-+ int b0, b1, b2;
-
-- switch (visbpp) {
-+ switch (visbpp) {
-
- /* thanks to Chris Hooper for single bpp support */
-
-- case 1:
-- for (q = 0; q < height; q++) {
-- xcur = xoff;
-- scrt = scr1;
-- for (p = 0; p < width; p++) {
-- *scrt = ((*scrt & ~(1 << xcur))
-- | (BGR233ToPixel[*(buf++)] << xcur));
--
-- if (xcur-- == 0) {
-- xcur = 7;
-- scrt++;
-- }
-- }
-- scr1 += fbwb;
-- }
-- break;
--
-- case 8:
-- for (q = 0; q < height; q++) {
-- for (p = 0; p < width; p++) {
-- *(scr8++) = BGR233ToPixel[*(buf++)];
-- }
-- scr8 += si.framebufferWidth - width;
-- }
-- break;
--
-- case 16:
-- for (q = 0; q < height; q++) {
-- for (p = 0; p < width; p++) {
-- *(scr16++) = BGR233ToPixel[*(buf++)];
-- }
-- scr16 += si.framebufferWidth - width;
-- }
-- break;
--
-- case 32:
-- for (q = 0; q < height; q++) {
-- for (p = 0; p < width; p++) {
-- *(scr32++) = BGR233ToPixel[*(buf++)];
-- }
-- scr32 += si.framebufferWidth - width;
-- }
-- break;
-- }
-+ case 1:
-+ for (q = 0; q < height; q++) {
-+ xcur = xoff;
-+ srct = src1;
-+ for (p = 0; p < width; p++) {
-+ *srct = ((*srct & ~(1 << xcur))
-+ | (BGR233ToPixel[*(buf++)] << xcur));
-+
-+ if (xcur-- == 0) {
-+ xcur = 7;
-+ srct++;
-+ }
-+ }
-+ src1 += fbwb;
-+ }
-+ break;
-+
-+ case 8:
-+ for (q = 0; q < height; q++) {
-+ for (p = 0; p < width; p++) {
-+ *(src8++) = BGR233ToPixel[*(buf++)];
-+ }
-+ src8 += src_width8 - width;
-+ }
-+ break;
-+
-+ case 16:
-+ for (q = 0; q < height; q++) {
-+ for (p = 0; p < width; p++) {
-+ *(src16++) = BGR233ToPixel[*(buf++)];
-+ }
-+ src16 += src_width16 - width;
-+ }
-+ break;
-+
-+ case 24:
-+ if (isLSB) {
-+ b0 = 0; b1 = 1; b2 = 2;
-+ } else {
-+ b0 = 2; b1 = 1; b2 = 0;
-+ }
-+ src8 = ((CARD8 *)im->data) + (y * si.framebufferWidth + x) * 3;
-+ for (q = 0; q < height; q++) {
-+ for (p = 0; p < width; p++) {
-+ CARD32 v = BGR233ToPixel[*(buf++)];
-+ *(src8 + b0) = (unsigned char) ((v & 0x0000ff) >> 0);
-+ *(src8 + b1) = (unsigned char) ((v & 0x00ff00) >> 8);
-+ *(src8 + b2) = (unsigned char) ((v & 0xff0000) >> 16);
-+ src8 += 3;
-+ }
-+ src8 += (si.framebufferWidth - width) * 3;
-+ }
-+ break;
-+
-+ case 32:
-+ for (q = 0; q < height; q++) {
-+ for (p = 0; p < width; p++) {
-+ *(src32++) = BGR233ToPixel[*(buf++)];
-+ }
-+ src32 += src_width32 - width;
-+ }
-+ break;
-+ }
-+}
-+
-+static void
-+BGR565_24bpp(CARD16 *buf, int x, int y, int width, int height)
-+{
-+ int p, q;
-+ int b0, b1, b2;
-+ XImage *im = image_scale ? image_scale : image;
-+ unsigned char *src= (unsigned char *)im->data + (y * si.framebufferWidth + x) * 3;
-+
-+ if (isLSB) {
-+ b0 = 0; b1 = 1; b2 = 2;
-+ } else {
-+ b0 = 2; b1 = 1; b2 = 0;
-+ }
-+
-+ /* case 24: */
-+ for (q = 0; q < height; q++) {
-+ for (p = 0; p < width; p++) {
-+ CARD32 v = BGR565ToPixel[*(buf++)];
-+ *(src + b0) = (unsigned char) ((v & 0x0000ff) >> 0);
-+ *(src + b1) = (unsigned char) ((v & 0x00ff00) >> 8);
-+ *(src + b2) = (unsigned char) ((v & 0xff0000) >> 16);
-+ src += 3;
-+ }
-+ src += (si.framebufferWidth - width) * 3;
-+ }
-+}
-+
-+static void
-+CopyBGR565ToScreen(CARD16 *buf, int x, int y, int width, int height)
-+{
-+ int p, q;
-+ XImage *im = image_scale ? image_scale : image;
-+ int src_width32 = im->bytes_per_line/4;
-+ CARD32 *src32 = ((CARD32 *)im->data) + y * src_width32 + x;
-+
-+ if (visbpp == 24) {
-+ BGR565_24bpp(buf, x, y, width, height);
-+ return;
-+ }
-+
-+ /* case 32: */
-+ for (q = 0; q < height; q++) {
-+ for (p = 0; p < width; p++) {
-+ *(src32++) = BGR565ToPixel[*(buf++)];
-+ }
-+ src32 += src_width32 - width;
-+ }
-+}
-+
-+static void reset_image(void) {
-+ if (UsingShm()) {
-+ ShmDetach();
-+ }
-+ if (image && image->data) {
-+ XDestroyImage(image);
-+ fprintf(stderr, "reset_image: destroyed 'image'\n");
-+ }
-+ image = NULL;
-+ if (image_ycrop && image_ycrop->data) {
-+ XDestroyImage(image_ycrop);
-+ fprintf(stderr, "reset_image: destroyed 'image_ycrop'\n");
-+ }
-+ image_ycrop = NULL;
-+ if (image_scale && image_scale->data) {
-+ XDestroyImage(image_scale);
-+ fprintf(stderr, "reset_image: destroyed 'image_scale'\n");
-+ }
-+ image_scale = NULL;
-+
-+ if (UsingShm()) {
-+ ShmCleanup();
-+ }
-+ create_image();
-+ XFlush(dpy);
-+}
-+
-+void ReDoDesktop(void) {
-+ int w, w0, h, h0, x, y, dw, dh;
-+ int fs = 0;
-+ int autoscale = 0;
-+ Position x_orig, y_orig;
-+ Dimension w_orig, h_orig;
-+
-+ if (!appData.fullScreen && appData.scale != NULL && !strcmp(appData.scale, "auto")) {
-+ autoscale = 1;
-+ }
-+
-+ fprintf(stderr, "ReDoDesktop: ycrop: %d\n", appData.yCrop);
-+
-+ XtVaGetValues(toplevel, XtNx, &x_orig, XtNy, &y_orig, NULL);
-+ XtVaGetValues(toplevel, XtNheight, &h_orig, XtNwidth, &w_orig, NULL);
-+
-+ check_tall();
-+
-+ if (appData.yCrop) {
-+ if (appData.yCrop < 0 || old_width <= 0) {
-+ appData.yCrop = guessCrop();
-+ fprintf(stderr, "Set -ycrop to: %d\n", appData.yCrop);
-+ } else {
-+ int w1 = si.framebufferWidth;
-+ appData.yCrop = (w1 * appData.yCrop) / old_width;
-+ if (appData.yCrop <= 100) {
-+ appData.yCrop = guessCrop();
-+ fprintf(stderr, "Set small -ycrop to: %d\n", appData.yCrop);
-+ }
-+ }
-+ fprintf(stderr, "Using -ycrop: %d\n", appData.yCrop);
-+ }
-+
-+ old_width = si.framebufferWidth;
-+ old_height = si.framebufferHeight;
-+
-+ if (appData.fullScreen) {
-+ if (prev_fb_width != si.framebufferWidth || prev_fb_height != si.framebufferHeight) {
-+ int xmax = si.framebufferWidth;
-+ int ymax = si.framebufferHeight;
-+ if (appData.yCrop > 0) {
-+ ymax = appData.yCrop;
-+ }
-+ if (scale_x > 0) {
-+ xmax = scale_round(xmax, scale_factor_x);
-+ ymax = scale_round(ymax, scale_factor_y);
-+ }
-+ if (xmax < dpyWidth || ymax < dpyHeight) {
-+ FullScreenOff();
-+ fs = 1;
-+ }
-+ }
-+ }
-+
-+ prev_fb_width = si.framebufferWidth;
-+ prev_fb_height = si.framebufferHeight;
-+
-+ if (appData.fullScreen) {
-+
-+ int xmax = si.framebufferWidth;
-+ int ymax = si.framebufferHeight;
-+ if (scale_x > 0) {
-+ xmax = scale_round(xmax, scale_factor_x);
-+ ymax = scale_round(ymax, scale_factor_y);
-+ }
-+
-+ if (image && image->data) {
-+ int len;
-+ int h = image->height;
-+ int w = image->width;
-+ len = image->bytes_per_line * image->height;
-+ /* black out window first: */
-+ memset(image->data, 0, len);
-+ XPutImage(dpy, XtWindow(desktop), gc, image, 0, 0, 0, 0, w, h);
-+ XFlush(dpy);
-+ }
-+
-+ /* XXX scaling?? */
-+ XtResizeWidget(desktop, xmax, ymax, 0);
-+
-+ XSync(dpy, False);
-+ usleep(100*1000);
-+ FullScreenOn();
-+ XSync(dpy, False);
-+ usleep(100*1000);
-+ reset_image();
-+ return;
-+ }
-+
-+ dw = appData.wmDecorationWidth;
-+ dh = appData.wmDecorationHeight;
-+
-+ w = si.framebufferWidth;
-+ h = si.framebufferHeight;
-+ w0 = w;
-+ h0 = h;
-+ if (appData.yCrop > 0) {
-+ h = appData.yCrop;
-+ }
-+ if (image_scale) {
-+ w = scale_round(w, scale_factor_x);
-+ h = scale_round(h, scale_factor_y);
-+ w0 = scale_round(w0, scale_factor_x);
-+ h0 = scale_round(h0, scale_factor_y);
-+ }
-+
-+ if (w + dw >= dpyWidth) {
-+ w = dpyWidth - dw;
-+ }
-+ if (h + dh >= dpyHeight) {
-+ h = dpyHeight - dh;
-+ }
-+
-+ if (!autoscale) {
-+ XtVaSetValues(toplevel, XtNmaxWidth, w, XtNmaxHeight, h, NULL);
-+ } else {
-+ XtVaSetValues(toplevel, XtNmaxWidth, dpyWidth, XtNmaxHeight, dpyHeight, NULL);
-+ }
-+
-+ XtVaSetValues(desktop, XtNwidth, w0, XtNheight, h0, NULL);
-+
-+ XtResizeWidget(desktop, w0, h0, 0);
-+
-+ if (appData.yCrop > 0) {
-+ int ycrop = appData.yCrop;
-+ if (image_scale) {
-+ ycrop *= scale_factor_y;
-+ }
-+ XtVaSetValues(toplevel, XtNmaxHeight, ycrop, NULL);
-+ XtVaSetValues(form, XtNmaxHeight, ycrop, NULL);
-+ }
-+
-+ x = (dpyWidth - w - dw)/2;
-+ y = (dpyHeight - h - dh)/2;
-+
-+ if (!autoscale) {
-+
-+ if (!getenv("VNCVIEWER_ALWAYS_RECENTER")) {
-+ int x_cm_old, y_cm_old;
-+ int x_cm_new, y_cm_new;
-+ int x_try, y_try;
-+
-+ x_cm_old = (int) x_orig + ((int) w_orig)/2;
-+ y_cm_old = (int) y_orig + ((int) h_orig)/2;
-+
-+ x_cm_new = dpyWidth/2;
-+ y_cm_new = dpyHeight/2;
-+
-+ x_try = x + (x_cm_old - x_cm_new);
-+ y_try = y + (y_cm_old - y_cm_new);
-+ if (x_try < 0) {
-+ x_try = 0;
-+ }
-+ if (y_try < 0) {
-+ y_try = 0;
-+ }
-+ if (x_try + w + dw > dpyWidth) {
-+ x_try = dpyWidth - w - dw;
-+ }
-+ if (y_try + h + dh > dpyHeight) {
-+ y_try = dpyHeight - h - dh;
-+ }
-+ x = x_try;
-+ y = y_try;
-+ }
-+
-+ XtConfigureWidget(toplevel, x + dw, y + dh, w, h, 0);
-+ }
-+
-+ reset_image();
-+
-+ if (fs) {
-+ FullScreenOn();
-+ }
- }
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncviewer/dialogs.c
---- vnc_unixsrc.orig/vncviewer/dialogs.c 2000-10-26 15:19:19.000000000 -0400
-+++ vnc_unixsrc/vncviewer/dialogs.c 2010-02-25 22:33:06.000000000 -0500
-@@ -25,75 +25,564 @@
- #include <X11/Xaw/Dialog.h>
-
- static Bool serverDialogDone = False;
-+static Bool userDialogDone = False;
- static Bool passwordDialogDone = False;
-+static Bool ycropDialogDone = False;
-+static Bool scaleDialogDone = False;
-+static Bool escapeDialogDone = False;
-+static Bool scbarDialogDone = False;
-+static Bool scaleNDialogDone = False;
-+static Bool qualityDialogDone = False;
-+static Bool compressDialogDone = False;
-+
-+extern void popupFixer(Widget wid);
-+
-+int use_tty(void) {
-+ if (appData.notty) {
-+ return 0;
-+ } else if (!isatty(0)) {
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+void
-+ScaleDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ scaleDialogDone = True;
-+ if (w || event || params || num_params) {}
-+}
-+
-+void
-+EscapeDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ escapeDialogDone = True;
-+ if (w || event || params || num_params) {}
-+}
-+
-+void dialog_over(Widget wid) {
-+ if (appData.fullScreen) {
-+ if (!net_wm_supported()) {
-+ XtVaSetValues(wid, XtNoverrideRedirect, True, NULL);
-+ XSync(dpy, True);
-+ }
-+ }
-+}
-+
-+extern int XError_ign;
-+
-+void dialog_input(Widget wid) {
-+ XError_ign = 1;
-+ XSetInputFocus(dpy, XtWindow(wid), RevertToParent, CurrentTime);
-+ XSync(dpy, False);
-+ usleep(30 * 1000);
-+ XSync(dpy, False);
-+ usleep(20 * 1000);
-+ XSync(dpy, False);
-+ XError_ign = 0;
-+}
-+
-+static void rmNL(char *s) {
-+ int len;
-+ if (s == NULL) {
-+ return;
-+ }
-+ len = strlen(s);
-+ if (len > 0 && s[len-1] == '\n') {
-+ s[len-1] = '\0';
-+ }
-+}
-+
-+static void wm_delete(Widget w, char *func) {
-+ char str[1024];
-+ Atom wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
-+ XSetWMProtocols(dpy, XtWindow(w), &wmDeleteWindow, 1);
-+ if (func) {
-+ sprintf(str, "<Message>WM_PROTOCOLS: %s", func);
-+ XtOverrideTranslations(w, XtParseTranslationTable (str));
-+ }
-+}
-+
-+static void xtmove(Widget w) {
-+ XtMoveWidget(w, WidthOfScreen(XtScreen(w))*2/5, HeightOfScreen(XtScreen(w))*2/5);
-+}
-+
-+char *
-+DoScaleDialog()
-+{
-+ Widget pshell, dialog;
-+ char *scaleValue;
-+ char *valueString;
-+
-+ pshell = XtVaCreatePopupShell("scaleDialog", transientShellWidgetClass,
-+ toplevel, NULL);
-+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-+
-+ dialog_over(pshell);
-+
-+ if (0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5);
-+ XtPopup(pshell, XtGrabNonexclusive);
-+ XtRealizeWidget(pshell);
-+
-+ if (appData.scale != NULL) {
-+ String label;
-+ char tmp[410];
-+ XtVaGetValues(dialog, XtNlabel, &label, NULL);
-+ if (strlen(label) + strlen(appData.scale) < 400) {
-+ sprintf(tmp, "%s %s", label, appData.scale);
-+ XtVaSetValues(dialog, XtNlabel, tmp, NULL);
-+ }
-+ }
-+
-+
-+ if (1 && appData.popupFix) {
-+ popupFixer(pshell);
-+ } else {
-+ xtmove(pshell);
-+ }
-+ dialog_input(pshell);
-+ wm_delete(pshell, "ScaleDialogDone()");
-+
-+ scaleDialogDone = False;
-+
-+ while (!scaleDialogDone) {
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+
-+ valueString = XawDialogGetValueString(dialog);
-+ rmNL(valueString);
-+ scaleValue = XtNewString(valueString);
-+
-+ XtPopdown(pshell);
-+ return scaleValue;
-+}
-+
-+char *
-+DoEscapeKeysDialog()
-+{
-+ Widget pshell, dialog;
-+ char *escapeValue;
-+ char *valueString;
-+ char *curr = appData.escapeKeys ? appData.escapeKeys : "default";
-+
-+ pshell = XtVaCreatePopupShell("escapeDialog", transientShellWidgetClass,
-+ toplevel, NULL);
-+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-+
-+ dialog_over(pshell);
-+
-+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5);
-+ XtPopup(pshell, XtGrabNonexclusive);
-+ XtRealizeWidget(pshell);
-+
-+ if (curr != NULL) {
-+ String label;
-+ char tmp[3010];
-+ XtVaGetValues(dialog, XtNlabel, &label, NULL);
-+ if (strlen(label) + strlen(curr) < 3000) {
-+ sprintf(tmp, "%s %s", label, curr);
-+ XtVaSetValues(dialog, XtNlabel, tmp, NULL);
-+ }
-+ }
-+
-+ if (appData.popupFix) {
-+ popupFixer(pshell);
-+ } else {
-+ /* too big */
-+ if (0) xtmove(pshell);
-+ }
-+ dialog_input(pshell);
-+ wm_delete(pshell, "EscapeDialogDone()");
-+
-+ escapeDialogDone = False;
-+
-+ while (!escapeDialogDone) {
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+
-+ valueString = XawDialogGetValueString(dialog);
-+ rmNL(valueString);
-+ escapeValue = XtNewString(valueString);
-+
-+ XtPopdown(pshell);
-+ return escapeValue;
-+}
-+
-+void
-+YCropDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ ycropDialogDone = True;
-+ if (w || event || params || num_params) {}
-+}
-+
-+char *
-+DoYCropDialog()
-+{
-+ Widget pshell, dialog;
-+ char *ycropValue;
-+ char *valueString;
-+
-+ pshell = XtVaCreatePopupShell("ycropDialog", transientShellWidgetClass,
-+ toplevel, NULL);
-+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-+
-+ dialog_over(pshell);
-+
-+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5);
-+ XtPopup(pshell, XtGrabNonexclusive);
-+ XtRealizeWidget(pshell);
-+
-+ if (1 && appData.popupFix) {
-+ popupFixer(pshell);
-+ } else {
-+ xtmove(pshell);
-+ }
-+ dialog_input(pshell);
-+ wm_delete(pshell, "YCropDialogDone()");
-+
-+ ycropDialogDone = False;
-+
-+ while (!ycropDialogDone) {
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+
-+ valueString = XawDialogGetValueString(dialog);
-+ rmNL(valueString);
-+ ycropValue = XtNewString(valueString);
-+
-+ XtPopdown(pshell);
-+ return ycropValue;
-+}
-+
-+void
-+ScbarDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ scbarDialogDone = True;
-+ if (w || event || params || num_params) {}
-+}
-+
-+char *
-+DoScbarDialog()
-+{
-+ Widget pshell, dialog;
-+ char *scbarValue;
-+ char *valueString;
-+
-+ pshell = XtVaCreatePopupShell("scbarDialog", transientShellWidgetClass,
-+ toplevel, NULL);
-+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-+
-+ dialog_over(pshell);
-+
-+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5);
-+ XtPopup(pshell, XtGrabNonexclusive);
-+ XtRealizeWidget(pshell);
-+
-+ if (1 && appData.popupFix) {
-+ popupFixer(pshell);
-+ } else {
-+ xtmove(pshell);
-+ }
-+ dialog_input(pshell);
-+ wm_delete(pshell, "ScbarDialogDone()");
-+
-+ scbarDialogDone = False;
-+
-+ while (!scbarDialogDone) {
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+
-+ valueString = XawDialogGetValueString(dialog);
-+ rmNL(valueString);
-+ scbarValue = XtNewString(valueString);
-+
-+ XtPopdown(pshell);
-+ return scbarValue;
-+}
-+
-+void
-+ScaleNDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ scaleNDialogDone = True;
-+ if (w || event || params || num_params) {}
-+}
-+
-+char *
-+DoScaleNDialog()
-+{
-+ Widget pshell, dialog;
-+ char *scaleNValue;
-+ char *valueString;
-+
-+ pshell = XtVaCreatePopupShell("scaleNDialog", transientShellWidgetClass,
-+ toplevel, NULL);
-+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-+
-+ dialog_over(pshell);
-+ wm_delete(pshell, "ScaleNDialogDone()");
-+
-+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5);
-+ XtPopup(pshell, XtGrabNonexclusive);
-+ XtRealizeWidget(pshell);
-+
-+ if (appData.popupFix) {
-+ popupFixer(pshell);
-+ } else {
-+ xtmove(pshell);
-+ }
-+ dialog_input(pshell);
-+ wm_delete(pshell, "ScaleNDialogDone()");
-+
-+ scaleNDialogDone = False;
-+
-+ while (!scaleNDialogDone) {
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+
-+ valueString = XawDialogGetValueString(dialog);
-+ rmNL(valueString);
-+ scaleNValue = XtNewString(valueString);
-+
-+ XtPopdown(pshell);
-+ return scaleNValue;
-+}
-+
-+void
-+QualityDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ qualityDialogDone = True;
-+ if (w || event || params || num_params) {}
-+}
-+
-+char *
-+DoQualityDialog()
-+{
-+ Widget pshell, dialog;
-+ char *qualityValue;
-+ char *valueString;
-+
-+ pshell = XtVaCreatePopupShell("qualityDialog", transientShellWidgetClass,
-+ toplevel, NULL);
-+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-+
-+ dialog_over(pshell);
-+
-+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5);
-+ XtPopup(pshell, XtGrabNonexclusive);
-+ XtRealizeWidget(pshell);
-+
-+ if (1 && appData.popupFix) {
-+ popupFixer(pshell);
-+ } else {
-+ xtmove(pshell);
-+ }
-+ dialog_input(pshell);
-+ wm_delete(pshell, "QualityDialogDone() HideQuality()");
-+
-+ qualityDialogDone = False;
-+
-+ while (!qualityDialogDone) {
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+
-+ valueString = XawDialogGetValueString(dialog);
-+ rmNL(valueString);
-+ qualityValue = XtNewString(valueString);
-+
-+ XtPopdown(pshell);
-+ return qualityValue;
-+}
-+
-+void
-+CompressDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ compressDialogDone = True;
-+ if (w || event || params || num_params) {}
-+}
-+
-+char *
-+DoCompressDialog()
-+{
-+ Widget pshell, dialog;
-+ char *compressValue;
-+ char *valueString;
-+
-+ fprintf(stderr, "compress start:\n");
-+
-+ pshell = XtVaCreatePopupShell("compressDialog", transientShellWidgetClass,
-+ toplevel, NULL);
-+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-+
-+ dialog_over(pshell);
-+
-+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5);
-+ XtPopup(pshell, XtGrabNonexclusive);
-+ XtRealizeWidget(pshell);
-+
-+ if (1 && appData.popupFix) {
-+ popupFixer(pshell);
-+ } else {
-+ xtmove(pshell);
-+ }
-+ dialog_input(pshell);
-+ wm_delete(pshell, "CompressDialogDone() HideCompress()");
-+
-+ compressDialogDone = False;
-+
-+ while (!compressDialogDone) {
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+
-+ valueString = XawDialogGetValueString(dialog);
-+ rmNL(valueString);
-+ compressValue = XtNewString(valueString);
-+
-+ fprintf(stderr, "compress done: %s\n", compressValue);
-+
-+ XtPopdown(pshell);
-+ return compressValue;
-+}
-
- void
- ServerDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params)
- {
-- serverDialogDone = True;
-+ serverDialogDone = True;
-+ if (w || event || params || num_params) {}
- }
-
- char *
- DoServerDialog()
- {
-- Widget pshell, dialog;
-- char *vncServerName;
-- char *valueString;
-+ Widget pshell, dialog;
-+ char *vncServerName;
-+ char *valueString;
-
-- pshell = XtVaCreatePopupShell("serverDialog", transientShellWidgetClass,
-+ pshell = XtVaCreatePopupShell("serverDialog", transientShellWidgetClass,
- toplevel, NULL);
-- dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-
-- XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5,
-- HeightOfScreen(XtScreen(pshell))*2/5);
-- XtPopup(pshell, XtGrabNonexclusive);
-- XtRealizeWidget(pshell);
-+ dialog_over(pshell);
-
-- serverDialogDone = False;
-+ if (0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5);
-+ XtPopup(pshell, XtGrabNonexclusive);
-+ XtRealizeWidget(pshell);
-+
-+ if (0 && appData.popupFix) {
-+ popupFixer(pshell);
-+ } else {
-+ xtmove(pshell);
-+ }
-+#if 0
-+ dialog_input(pshell);
-+#endif
-+ wm_delete(pshell, "ServerDialogDone()");
-+
-+ serverDialogDone = False;
-+
-+ while (!serverDialogDone) {
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+
-+ valueString = XawDialogGetValueString(dialog);
-+ rmNL(valueString);
-+ vncServerName = XtNewString(valueString);
-
-- while (!serverDialogDone) {
-- XtAppProcessEvent(appContext, XtIMAll);
-- }
-+ XtPopdown(pshell);
-+ return vncServerName;
-+}
-
-- valueString = XawDialogGetValueString(dialog);
-- vncServerName = XtNewString(valueString);
-+void
-+UserDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ userDialogDone = True;
-+ if (w || event || params || num_params) {}
-+}
-
-- XtPopdown(pshell);
-- return vncServerName;
-+char *
-+DoUserDialog()
-+{
-+ Widget pshell, dialog;
-+ char *userName;
-+ char *valueString;
-+
-+ pshell = XtVaCreatePopupShell("userDialog", transientShellWidgetClass,
-+ toplevel, NULL);
-+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-+
-+ dialog_over(pshell);
-+
-+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5);
-+ XtPopup(pshell, XtGrabNonexclusive);
-+ XtRealizeWidget(pshell);
-+
-+ if (0 && appData.popupFix) {
-+ popupFixer(pshell);
-+ } else {
-+ xtmove(pshell);
-+ }
-+#if 0
-+ dialog_input(pshell);
-+#endif
-+ wm_delete(pshell, "UserDialogDone()");
-+
-+ userDialogDone = False;
-+
-+ while (!userDialogDone) {
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+
-+ valueString = XawDialogGetValueString(dialog);
-+ rmNL(valueString);
-+ userName = XtNewString(valueString);
-+
-+ XtPopdown(pshell);
-+ return userName;
- }
-
- void
--PasswordDialogDone(Widget w, XEvent *event, String *params,
-- Cardinal *num_params)
-+PasswordDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params)
- {
-- passwordDialogDone = True;
-+ passwordDialogDone = True;
-+ if (w || event || params || num_params) {}
- }
-
- char *
- DoPasswordDialog()
- {
-- Widget pshell, dialog;
-- char *password;
-- char *valueString;
-+ Widget pshell, dialog;
-+ char *password;
-+ char *valueString;
-
-- pshell = XtVaCreatePopupShell("passwordDialog", transientShellWidgetClass,
-+ pshell = XtVaCreatePopupShell("passwordDialog", transientShellWidgetClass,
- toplevel, NULL);
-- dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
--
-- XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5,
-- HeightOfScreen(XtScreen(pshell))*2/5);
-- XtPopup(pshell, XtGrabNonexclusive);
-- XtRealizeWidget(pshell);
--
-- passwordDialogDone = False;
-+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL);
-
-- while (!passwordDialogDone) {
-- XtAppProcessEvent(appContext, XtIMAll);
-- }
-+ dialog_over(pshell);
-
-- valueString = XawDialogGetValueString(dialog);
-- password = XtNewString(valueString);
-+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5);
-+ XtPopup(pshell, XtGrabNonexclusive);
-+ XtRealizeWidget(pshell);
-+
-+ if (0 && appData.popupFix) {
-+ popupFixer(pshell);
-+ } else {
-+ xtmove(pshell);
-+ }
-+#if 0
-+ dialog_input(pshell);
-+#endif
-+ wm_delete(pshell, "PasswordDialogDone()");
-+
-+ passwordDialogDone = False;
-+
-+ while (!passwordDialogDone) {
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+
-+ valueString = XawDialogGetValueString(dialog);
-+ rmNL(valueString);
-+ password = XtNewString(valueString);
-
-- XtPopdown(pshell);
-- return password;
-+ XtPopdown(pshell);
-+ return password;
- }
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/fullscreen.c vnc_unixsrc/vncviewer/fullscreen.c
---- vnc_unixsrc.orig/vncviewer/fullscreen.c 2003-10-09 05:23:49.000000000 -0400
-+++ vnc_unixsrc/vncviewer/fullscreen.c 2010-02-25 22:37:49.000000000 -0500
-@@ -22,20 +22,24 @@
- */
-
- #include <vncviewer.h>
-+#include <time.h>
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/Viewport.h>
- #include <X11/Xaw/Toggle.h>
-
- static Bool DoBumpScroll();
-+static Bool DoJumpScroll();
- static void BumpScrollTimerCallback(XtPointer clientData, XtIntervalId *id);
-+static void JumpScrollTimerCallback(XtPointer clientData, XtIntervalId *id);
- static XtIntervalId timer;
- static Bool timerSet = False;
- static Bool scrollLeft, scrollRight, scrollUp, scrollDown;
--static Position desktopX, desktopY;
-+Position desktopX, desktopY;
- static Dimension viewportWidth, viewportHeight;
- static Dimension scrollbarWidth, scrollbarHeight;
-
-
-+int scale_round(int len, double fac);
-
- /*
- * FullScreenOn goes into full-screen mode. It makes the toplevel window
-@@ -78,112 +82,456 @@
- * variables so that FullScreenOff can use them.
- */
-
--void
--FullScreenOn()
--{
-- Dimension toplevelWidth, toplevelHeight;
-- Dimension oldViewportWidth, oldViewportHeight, clipWidth, clipHeight;
-- Position viewportX, viewportY;
--
-- appData.fullScreen = True;
--
-- if (si.framebufferWidth > dpyWidth || si.framebufferHeight > dpyHeight) {
--
-- XtVaSetValues(viewport, XtNforceBars, True, NULL);
-- XtVaGetValues(viewport, XtNwidth, &oldViewportWidth,
-- XtNheight, &oldViewportHeight, NULL);
-- XtVaGetValues(XtNameToWidget(viewport, "clip"),
-- XtNwidth, &clipWidth, XtNheight, &clipHeight, NULL);
--
-- scrollbarWidth = oldViewportWidth - clipWidth;
-- scrollbarHeight = oldViewportHeight - clipHeight;
--
-- if (si.framebufferWidth > dpyWidth) {
-- viewportWidth = toplevelWidth = dpyWidth + scrollbarWidth;
-- } else {
-- viewportWidth = si.framebufferWidth + scrollbarWidth;
-- toplevelWidth = dpyWidth;
-- }
--
-- if (si.framebufferHeight > dpyHeight) {
-- viewportHeight = toplevelHeight = dpyHeight + scrollbarHeight;
-- } else {
-- viewportHeight = si.framebufferHeight + scrollbarHeight;
-- toplevelHeight = dpyHeight;
-- }
--
-- } else {
-- viewportWidth = si.framebufferWidth;
-- viewportHeight = si.framebufferHeight;
-- toplevelWidth = dpyWidth;
-- toplevelHeight = dpyHeight;
-- }
-+int net_wm_supported(void) {
-+ unsigned char *data;
-+ unsigned long items_read, items_left, i;
-+ int ret, format;
-+ Window wm;
-+ Atom type;
-+ Atom _NET_SUPPORTING_WM_CHECK;
-+ Atom _NET_SUPPORTED;
-+ Atom _NET_WM_STATE;
-+ Atom _NET_WM_STATE_FULLSCREEN;
-+
-+ static time_t last_check = 0;
-+ static int fs_supported = -1;
-+
-+ if (fs_supported >= 0 && time(NULL) < last_check + 600) {
-+ static int first = 1;
-+ if (first) {
-+ fprintf(stderr, "fs_supported: %d\n", fs_supported);
-+ }
-+ first = 0;
-+ return fs_supported;
-+ }
-+ last_check = time(NULL);
-+
-+ fs_supported = 0;
-+
-+ _NET_SUPPORTING_WM_CHECK = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
-+ _NET_SUPPORTED = XInternAtom(dpy, "_NET_SUPPORTED", False);
-+ _NET_WM_STATE = XInternAtom(dpy, "_NET_WM_STATE", False);
-+ _NET_WM_STATE_FULLSCREEN = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
-+
-+ ret = XGetWindowProperty(dpy, DefaultRootWindow(dpy), _NET_SUPPORTING_WM_CHECK,
-+ 0L, 1L, False, XA_WINDOW, &type, &format, &items_read, &items_left, &data);
-+
-+ if (ret != Success || !items_read) {
-+ if (ret == Success) {
-+ XFree(data);
-+ }
-+ return fs_supported;
-+ }
-+
-+ wm = ((Window*) data)[0];
-+ XFree(data);
-+
-+ ret = XGetWindowProperty(dpy, wm, _NET_SUPPORTING_WM_CHECK,
-+ 0L, 1L, False, XA_WINDOW, &type, &format, &items_read, &items_left, &data);
-+
-+ if (ret != Success || !items_read) {
-+ if (ret == Success) {
-+ XFree(data);
-+ }
-+ return fs_supported;
-+ }
-+
-+ if (wm != ((Window*) data)[0]) {
-+ XFree(data);
-+ return fs_supported;
-+ }
-+
-+ ret = XGetWindowProperty(dpy, DefaultRootWindow(dpy), _NET_SUPPORTED,
-+ 0L, 8192L, False, XA_ATOM, &type, &format, &items_read, &items_left, &data);
-+
-+ if (ret != Success || !items_read) {
-+ if (ret == Success) {
-+ XFree(data);
-+ }
-+ return fs_supported;
-+ }
-+
-+ for (i=0; i < items_read; i++) {
-+ if ( ((Atom*) data)[i] == _NET_WM_STATE_FULLSCREEN) {
-+ fs_supported = 1;
-+ }
-+ }
-+ XFree(data);
-
-- viewportX = (toplevelWidth - viewportWidth) / 2;
-- viewportY = (toplevelHeight - viewportHeight) / 2;
-+ return fs_supported;
-+}
-
-+static void net_wm_fullscreen(int to_fs) {
-+
-+ int _NET_WM_STATE_REMOVE = 0;
-+ int _NET_WM_STATE_ADD = 1;
-+#if 0
-+ int _NET_WM_STATE_TOGGLE = 2;
-+#endif
-+ Atom _NET_WM_STATE = XInternAtom(dpy, "_NET_WM_STATE", False);
-+ Atom _NET_WM_STATE_FULLSCREEN = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
-+ XEvent xev;
-+
-+ if (to_fs == 2) {
-+ XChangeProperty(dpy, XtWindow(toplevel), _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char*)&_NET_WM_STATE_FULLSCREEN, 1);
-+ } else {
-+ xev.xclient.type = ClientMessage;
-+ xev.xclient.window = XtWindow(toplevel);
-+ xev.xclient.message_type = _NET_WM_STATE;
-+ xev.xclient.serial = 0;
-+ xev.xclient.display = dpy;
-+ xev.xclient.send_event = True;
-+ xev.xclient.format = 32;
-+ xev.xclient.data.l[0] = to_fs ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
-+ xev.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
-+ xev.xclient.data.l[2] = 0;
-+ xev.xclient.data.l[3] = 0;
-+ xev.xclient.data.l[4] = 0;
-+ XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
-+ }
-
-- /* We want to stop the window manager from managing our toplevel window.
-- This is not really a nice thing to do, so may not work properly with every
-- window manager. We do this simply by setting overrideRedirect and
-- reparenting our window to the root. The window manager will get a
-- ReparentNotify and hopefully clean up its frame window. */
-+ XSync(dpy, False);
-+}
-
-- XtVaSetValues(toplevel, XtNoverrideRedirect, True, NULL);
-+time_t main_grab = 0;
-
-- XReparentWindow(dpy, XtWindow(toplevel), DefaultRootWindow(dpy), 0, 0);
-+void fs_ungrab(int check) {
-+ if (check) {
-+ if (time(NULL) <= main_grab + 2) {
-+ return;
-+ }
-+ if (net_wm_supported()) {
-+ return;
-+ }
-+ }
-+ fprintf(stderr, "calling fs_ungrab()\n");
-+ if (appData.grabAll) { /* runge top of FullScreenOff */
-+ fprintf(stderr, "calling XUngrabServer(dpy)\n");
-+ XUngrabServer(dpy);
-+ }
-+ if (appData.grabKeyboard) {
-+ fprintf(stderr, "calling XUngrabKeyboard(dpy)\n");
-+ XtUngrabKeyboard(desktop, CurrentTime);
-+ }
-+}
-
-- /* Some WMs does not obey x,y values of XReparentWindow; the window
-- is not placed in the upper, left corner. The code below fixes
-- this: It manually moves the window, after the Xserver is done
-- with XReparentWindow. The last XSync seems to prevent losing
-- focus, but I don't know why. */
-- XSync(dpy, False);
-- XMoveWindow(dpy, XtWindow(toplevel), 0, 0);
-- XSync(dpy, False);
--
-- /* Now we want to fix the size of "viewport". We shouldn't just change it
-- directly. Instead we set "toplevel" to the required size (which should
-- propagate through "form" to "viewport"). Then we remove "viewport" from
-- being managed by "form", change its resources to position it and make sure
-- that "form" won't attempt to resize it, then ask "form" to manage it
-- again. */
--
-- XtResizeWidget(toplevel, viewportWidth, viewportHeight, 0);
--
-- XtUnmanageChild(viewport);
--
-- XtVaSetValues(viewport,
-- XtNhorizDistance, viewportX,
-- XtNvertDistance, viewportY,
-- XtNleft, XtChainLeft,
-- XtNright, XtChainLeft,
-- XtNtop, XtChainTop,
-- XtNbottom, XtChainTop,
-- NULL);
-+void fs_grab(int check) {
-+ if (check) {
-+ if (time(NULL) <= main_grab + 2) {
-+ return;
-+ }
-+ if (net_wm_supported()) {
-+ return;
-+ }
-+ }
-+
-+ main_grab = time(NULL);
-+
-+ fprintf(stderr, "calling fs_grab()\n");
-+
-+#define FORCE_UP \
-+ XSync(dpy, False); \
-+ XUnmapWindow(dpy, XtWindow(toplevel)); \
-+ XSync(dpy, False); \
-+ XMapWindow(dpy, XtWindow(toplevel)); \
-+ XRaiseWindow(dpy, XtWindow(toplevel)); \
-+ XSync(dpy, False);
-+
-+ if (appData.grabKeyboard && XtGrabKeyboard(desktop, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) {
-+ fprintf(stderr, "XtGrabKeyboard() failed.\n");
-+ XSync(dpy, False);
-+ usleep(100 * 1000);
-+ FORCE_UP
-+
-+ if (XtGrabKeyboard(desktop, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) {
-+ fprintf(stderr, "XtGrabKeyboard() failed again.\n");
-+ usleep(200 * 1000);
-+ XSync(dpy, False);
-+ if (XtGrabKeyboard(desktop, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) {
-+ fprintf(stderr, "XtGrabKeyboard() failed 3rd time.\n");
-+ } else {
-+ fprintf(stderr, "XtGrabKeyboard() OK 3rd try.\n");
-+ }
-+ } else {
-+ fprintf(stderr, "XtGrabKeyboard() OK 2nd try.\n");
-+ }
-+ XRaiseWindow(dpy, XtWindow(toplevel));
-+ }
-+
-+ if (appData.grabAll) {
-+ fprintf(stderr, "calling XGrabServer(dpy)\n");
-+ if (! XGrabServer(dpy)) {
-+ XSync(dpy, False);
-+ usleep(100 * 1000);
-+ fprintf(stderr, "calling XGrabServer(dpy) 2nd time\n");
-+ if (!XGrabServer(dpy)) {
-+ XSync(dpy, False);
-+ usleep(200 * 1000);
-+ fprintf(stderr, "calling XGrabServer(dpy) 3rd time\n");
-+ if (XGrabServer(dpy)) {
-+ fprintf(stderr, "XGrabServer(dpy) OK 3rd time\n");
-+ }
-+ } else {
-+ fprintf(stderr, "XGrabServer(dpy) OK 2nd time\n");
-+ }
-+ XSync(dpy, False);
-+ }
-+ if (getenv("VNCVIEWER_FORCE_UP")) {
-+ fprintf(stderr, "FORCE_UP\n");
-+ FORCE_UP
-+ }
-+ }
-+}
-+
-+extern int fullscreen_startup;
-+extern double last_fullscreen;
-+
-+#define set_size_hints() \
-+{ \
-+ long supplied; \
-+ XSizeHints *sizehints = XAllocSizeHints(); \
-+ XGetWMSizeHints(dpy, topwin, sizehints, &supplied, XA_WM_NORMAL_HINTS); \
-+ if (sizehints->base_width < toplevelWidth) { \
-+ sizehints->base_width = toplevelWidth; \
-+ } \
-+ if (sizehints->base_height < toplevelHeight) { \
-+ sizehints->base_height = toplevelHeight; \
-+ } \
-+ if (sizehints->max_width < toplevelWidth) { \
-+ sizehints->max_width = toplevelWidth; \
-+ } \
-+ if (sizehints->max_height < toplevelHeight) { \
-+ sizehints->max_height = toplevelHeight; \
-+ } \
-+ XSetWMSizeHints(dpy, topwin, sizehints, XA_WM_NORMAL_HINTS); \
-+ XFree(sizehints); \
-+}
-
-- XtManageChild(viewport);
-+extern int scale_x, scale_y;
-+extern double scale_factor_y;
-+
-+void
-+FullScreenOn()
-+{
-+ Dimension toplevelWidth, toplevelHeight;
-+ Dimension oldViewportWidth, oldViewportHeight, clipWidth, clipHeight;
-+ Position viewportX, viewportY;
-+ int do_net_wm = net_wm_supported();
-+ int fbW = si.framebufferWidth;
-+ int fbH = si.framebufferHeight;
-+ int eff_height;
-+
-+ Bool fsAlready = appData.fullScreen, toobig = False;
-+ Window topwin = XtWindow(toplevel);
-+
-+ appData.fullScreen = True;
-+
-+ last_fullscreen = dnow();
-+
-+ if (scale_x > 0) {
-+ fbW = scale_x;
-+ fbH = scale_y;
-+ }
-+
-+ eff_height = fbH;
-+ if (appData.yCrop > 0) {
-+ eff_height = appData.yCrop;
-+ if (scale_y > 0) {
-+ eff_height = scale_round(eff_height, scale_factor_y);
-+ }
-+ }
-+
-+ if (fbW > dpyWidth || eff_height > dpyHeight) {
-+
-+ toobig = True;
-+
-+ /*
-+ * This is a crazy thing to have the scrollbars hang
-+ * just a bit offscreen to the right and below. the user
-+ * will not see them and bumpscroll will work.
-+ */
-+
-+ XtVaSetValues(viewport, XtNforceBars, True, NULL);
-+ XtVaGetValues(viewport, XtNwidth, &oldViewportWidth, XtNheight, &oldViewportHeight, NULL);
-+ XtVaGetValues(XtNameToWidget(viewport, "clip"), XtNwidth, &clipWidth, XtNheight, &clipHeight, NULL);
-+
-+ scrollbarWidth = oldViewportWidth - clipWidth;
-+ scrollbarHeight = oldViewportHeight - clipHeight;
-+
-+ if (fbW > dpyWidth) {
-+ viewportWidth = toplevelWidth = dpyWidth + scrollbarWidth;
-+ } else {
-+ viewportWidth = fbW + scrollbarWidth;
-+ toplevelWidth = dpyWidth;
-+ }
-+
-+ if (eff_height > dpyHeight) {
-+ viewportHeight = toplevelHeight = dpyHeight + scrollbarHeight;
-+ } else {
-+ viewportHeight = eff_height + scrollbarHeight;
-+ toplevelHeight = dpyHeight;
-+ }
-+ if (do_net_wm) {
-+ /* but for _NET_WM we make toplevel be correct dpy size */
-+ toplevelWidth = dpyWidth;
-+ toplevelHeight = dpyHeight;
-+ }
-+
-+ } else {
-+ viewportWidth = fbW;
-+ viewportHeight = eff_height;
-+ toplevelWidth = dpyWidth;
-+ toplevelHeight = dpyHeight;
-+ }
-
-- /* Now we can set "toplevel" to its proper size. */
-+ viewportX = (toplevelWidth - viewportWidth) / 2;
-+ viewportY = (toplevelHeight - viewportHeight) / 2;
-
-- XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0);
-+ if (viewportX < 0) viewportX = 0;
-+ if (viewportY < 0) viewportY = 0;
-
-- /* Set the popup to overrideRedirect too */
-
-- XtVaSetValues(popup, XtNoverrideRedirect, True, NULL);
-+ /* We want to stop the window manager from managing our toplevel window.
-+ This is not really a nice thing to do, so may not work properly with every
-+ window manager. We do this simply by setting overrideRedirect and
-+ reparenting our window to the root. The window manager will get a
-+ ReparentNotify and hopefully clean up its frame window. */
-
-- /* Try to get the input focus. */
-+ if (! fsAlready) {
-+ if (!do_net_wm) {
-+ /* added to try to raise it on top for some cirumstances */
-+ XUnmapWindow(dpy, topwin);
-+
-+ XtVaSetValues(toplevel, XtNoverrideRedirect, True, NULL);
-+#if 0
-+ XtVaSetValues(viewport, XtNoverrideRedirect, True, NULL);
-+ XtVaSetValues(desktop, XtNoverrideRedirect, True, NULL);
-+#endif
-+ XtVaSetValues(popup, XtNoverrideRedirect, True, NULL);
-+
-+ XReparentWindow(dpy, topwin, DefaultRootWindow(dpy), 0, 0);
-+
-+ /* Some WMs does not obey x,y values of XReparentWindow; the window
-+ is not placed in the upper, left corner. The code below fixes
-+ this: It manually moves the window, after the Xserver is done
-+ with XReparentWindow. The last XSync seems to prevent losing
-+ focus, but I don't know why. */
-+
-+ XSync(dpy, False);
-+
-+ /* added to try to raise it on top for some cirumstances */
-+ XMapRaised(dpy, topwin);
-+
-+ XMoveWindow(dpy, topwin, 0, 0);
-+ XSync(dpy, False);
-+ }
-+
-+ /* Now we want to fix the size of "viewport". We shouldn't just change it
-+ directly. Instead we set "toplevel" to the required size (which should
-+ propagate through "form" to "viewport"). Then we remove "viewport" from
-+ being managed by "form", change its resources to position it and make sure
-+ that "form" won't attempt to resize it, then ask "form" to manage it
-+ again. */
-+
-+ XtResizeWidget(toplevel, viewportWidth, viewportHeight, 0);
-+
-+ XtUnmanageChild(viewport);
-+
-+ XtVaSetValues(viewport,
-+ XtNhorizDistance, viewportX,
-+ XtNvertDistance, viewportY,
-+ XtNleft, XtChainLeft,
-+ XtNright, XtChainLeft,
-+ XtNtop, XtChainTop,
-+ XtNbottom, XtChainTop,
-+ NULL);
-+
-+ XtManageChild(viewport);
-+ XSync(dpy, False);
-+ } else {
-+ XSync(dpy, False);
-+ }
-+
-+ /* Now we can set "toplevel" to its proper size. */
-+
-+#if 0
-+ XtVaSetValues(toplevel, XtNwidth, toplevelWidth, XtNheight, toplevelHeight, NULL);
-+ XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0);
-+#endif
-+ XResizeWindow(dpy, topwin, toplevelWidth, toplevelHeight);
-+
-+ if (do_net_wm) {
-+ XWindowAttributes attr;
-+ int ok = 0, i, delay = 20;
-+
-+ usleep(delay * 1000);
-+
-+#define GSIZE() \
-+ XGetWindowAttributes(dpy, topwin, &attr);
-+
-+#define PSIZE(s) \
-+ XSync(dpy, False); \
-+ XGetWindowAttributes(dpy, topwin, &attr); \
-+ fprintf(stderr, "%s %dx%d+%d+%d\n", s, attr.width, attr.height, attr.x, attr.y);
-+
-+ PSIZE("size-A:");
-+
-+ set_size_hints();
-+
-+ net_wm_fullscreen(1);
-+
-+ PSIZE("size-B:");
-+
-+ for (i=0; i < 30; i++) {
-+ usleep(delay * 1000);
-+ GSIZE();
-+ fprintf(stderr, "size[%d] %dx%d+%d+%d\n", i, attr.width, attr.height, attr.x, attr.y);
-+ if (attr.width == toplevelWidth && attr.height == toplevelHeight) {
-+ ok = 1;
-+ fprintf(stderr, "size ok.\n");
-+ XSync(dpy, False);
-+ break;
-+ }
-+ set_size_hints();
-+ XResizeWindow(dpy, topwin, toplevelWidth, toplevelHeight);
-+ XMoveWindow(dpy, topwin, 0, 0);
-+ XSync(dpy, False);
-+ }
-+
-+ PSIZE("size-C:");
-+ }
-+
-+ fprintf(stderr, "\ntoplevel: %dx%d viewport: %dx%d\n", toplevelWidth, toplevelHeight, viewportWidth, viewportHeight);
-+
-+#if defined (__SVR4) && defined (__sun)
-+ if (!do_net_wm) {
-+ /* CDE */
-+ XSync(dpy, False);
-+ usleep(200 * 1000);
-+ XMoveWindow(dpy, topwin, 0, 0);
-+ XMapRaised(dpy, topwin);
-+ XSync(dpy, False);
-+ }
-+#endif
-+
-+ if (fsAlready) {
-+ XtResizeWidget(viewport, viewportWidth, viewportHeight, 0);
-+ if (! toobig) {
-+ XtVaSetValues(viewport, XtNforceBars, False, NULL);
-+ }
-+ XMoveWindow(dpy, topwin, viewportX, viewportY);
-+ XSync(dpy, False);
-+ }
-+
-+ /* Try to get the input focus. */
-
-- XSetInputFocus(dpy, DefaultRootWindow(dpy), RevertToPointerRoot,
-- CurrentTime);
-+ /* original vnc: DefaultRootWindow(dpy) instead of PointerRoot */
-+ XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
-
-- /* Optionally, grab the keyboard. */
-+ /* Optionally, grab the keyboard. */
-+ fs_grab(0);
-
-- if (appData.grabKeyboard &&
-- XtGrabKeyboard(desktop, True, GrabModeAsync,
-- GrabModeAsync, CurrentTime) != GrabSuccess) {
-- fprintf(stderr, "XtGrabKeyboard() failed.\n");
-- }
-+ /* finally done. */
- }
-
-
-@@ -205,28 +553,52 @@
- void
- FullScreenOff()
- {
-- int toplevelWidth = si.framebufferWidth;
-- int toplevelHeight = si.framebufferHeight;
--
-- appData.fullScreen = False;
-+ int toplevelWidth, toplevelHeight;
-+ int do_net_wm = net_wm_supported();
-+ int fbW = si.framebufferWidth;
-+ int fbH = si.framebufferHeight;
-+ int eff_height;
-+
-+ appData.fullScreen = False;
-+
-+ last_fullscreen = dnow();
-+
-+ if (scale_x > 0) {
-+ fbW = scale_x;
-+ fbH = scale_y;
-+ }
-+
-+ eff_height = fbH;
-+ if (appData.yCrop > 0) {
-+ eff_height = appData.yCrop;
-+ if (scale_y > 0) {
-+ eff_height = scale_round(eff_height, scale_factor_y);
-+ }
-+ }
-+
-+ toplevelWidth = fbW;
-+ toplevelHeight = eff_height;
-+
-+ fs_ungrab(0);
-+
-+ if (do_net_wm) {
-+ net_wm_fullscreen(0);
-+ } else {
-+ XtUnmapWidget(toplevel);
-+ }
-
-- if (appData.grabKeyboard)
-- XtUngrabKeyboard(desktop, CurrentTime);
--
-- XtUnmapWidget(toplevel);
--
-- XtResizeWidget(toplevel,
-+ XtResizeWidget(toplevel,
- viewportWidth - scrollbarWidth,
- viewportHeight - scrollbarHeight, 0);
-- XtResizeWidget(viewport,
-+ XtResizeWidget(viewport,
- viewportWidth - scrollbarWidth,
- viewportHeight - scrollbarHeight, 0);
-
-- XtVaSetValues(viewport, XtNforceBars, False, NULL);
-+ XtVaSetValues(viewport, XtNforceBars, False, NULL);
-
-- XtUnmanageChild(viewport);
-+ XtUnmanageChild(viewport);
-
-- XtVaSetValues(viewport,
-+ XtVaSetValues(viewport,
- XtNhorizDistance, 0,
- XtNvertDistance, 0,
- XtNleft, XtChainLeft,
-@@ -235,24 +607,42 @@
- XtNbottom, XtChainBottom,
- NULL);
-
-- XtManageChild(viewport);
--
-- XtVaSetValues(toplevel, XtNoverrideRedirect, False, NULL);
--
-- if ((toplevelWidth + appData.wmDecorationWidth) >= dpyWidth)
-- toplevelWidth = dpyWidth - appData.wmDecorationWidth;
--
-- if ((toplevelHeight + appData.wmDecorationHeight) >= dpyHeight)
-- toplevelHeight = dpyHeight - appData.wmDecorationHeight;
--
-- XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0);
--
-- XtMapWidget(toplevel);
-- XSync(dpy, False);
-+ XtManageChild(viewport);
-
-- /* Set the popup back to non-overrideRedirect */
--
-- XtVaSetValues(popup, XtNoverrideRedirect, False, NULL);
-+ if (!do_net_wm) {
-+ XtVaSetValues(toplevel, XtNoverrideRedirect, False, NULL);
-+#if 0
-+ XtVaSetValues(viewport, XtNoverrideRedirect, False, NULL);
-+ XtVaSetValues(desktop, XtNoverrideRedirect, False, NULL);
-+#endif
-+ XtVaSetValues(popup, XtNoverrideRedirect, False, NULL);
-+ }
-+
-+ if ((toplevelWidth + appData.wmDecorationWidth) >= dpyWidth)
-+ toplevelWidth = dpyWidth - appData.wmDecorationWidth;
-+
-+ if ((toplevelHeight + appData.wmDecorationHeight) >= dpyHeight)
-+ toplevelHeight = dpyHeight - appData.wmDecorationHeight;
-+
-+ XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0);
-+
-+ if (!do_net_wm) {
-+ XtMapWidget(toplevel);
-+ }
-+ XSync(dpy, False);
-+
-+ /* Set the popup back to non-overrideRedirect */
-+
-+ XtVaSetValues(popup, XtNoverrideRedirect, False, NULL);
-+
-+ if (!do_net_wm) {
-+ int x = (dpyWidth - toplevelWidth) / 2;
-+ int y = (dpyHeight - toplevelHeight) / 2;
-+ if (x > 0 && y > 0) {
-+ XSync(dpy, False);
-+ XMoveWindow(dpy, XtWindow(toplevel), x, y);
-+ }
-+ }
- }
-
-
-@@ -264,10 +654,12 @@
- void
- SetFullScreenState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
- {
-- if (appData.fullScreen)
-- XtVaSetValues(w, XtNstate, True, NULL);
-- else
-- XtVaSetValues(w, XtNstate, False, NULL);
-+ if (appData.fullScreen) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
- }
-
-
-@@ -278,11 +670,12 @@
- void
- ToggleFullScreen(Widget w, XEvent *ev, String *params, Cardinal *num_params)
- {
-- if (appData.fullScreen) {
-- FullScreenOff();
-- } else {
-- FullScreenOn();
-- }
-+ if (appData.fullScreen) {
-+ FullScreenOff();
-+ } else {
-+ FullScreenOn();
-+ }
-+ if (w || ev || params || num_params) {}
- }
-
-
-@@ -294,84 +687,226 @@
- Bool
- BumpScroll(XEvent *ev)
- {
-- scrollLeft = scrollRight = scrollUp = scrollDown = False;
-+ scrollLeft = scrollRight = scrollUp = scrollDown = False;
-
-- if (ev->xmotion.x_root >= dpyWidth - 3)
-- scrollRight = True;
-- else if (ev->xmotion.x_root <= 2)
-- scrollLeft = True;
--
-- if (ev->xmotion.y_root >= dpyHeight - 3)
-- scrollDown = True;
-- else if (ev->xmotion.y_root <= 2)
-- scrollUp = True;
--
-- if (scrollLeft || scrollRight || scrollUp || scrollDown) {
-- if (timerSet)
-- return True;
--
-- XtVaGetValues(desktop, XtNx, &desktopX, XtNy, &desktopY, NULL);
-- desktopX = -desktopX;
-- desktopY = -desktopY;
--
-- return DoBumpScroll();
-- }
--
-- if (timerSet) {
-- XtRemoveTimeOut(timer);
-- timerSet = False;
-- }
-+ if (ev->xmotion.x_root >= dpyWidth - 3)
-+ scrollRight = True;
-+ else if (ev->xmotion.x_root <= 2)
-+ scrollLeft = True;
-+
-+ if (ev->xmotion.y_root >= dpyHeight - 3)
-+ scrollDown = True;
-+ else if (ev->xmotion.y_root <= 2)
-+ scrollUp = True;
-+
-+ if (scrollLeft || scrollRight || scrollUp || scrollDown) {
-+ if (timerSet)
-+ return True;
-+
-+ XtVaGetValues(desktop, XtNx, &desktopX, XtNy, &desktopY, NULL);
-+ desktopX = -desktopX;
-+ desktopY = -desktopY;
-+
-+ return DoBumpScroll();
-+ }
-+
-+ if (timerSet) {
-+ XtRemoveTimeOut(timer);
-+ timerSet = False;
-+ }
-
-- return False;
-+ return False;
- }
-
- static Bool
- DoBumpScroll()
- {
-- int oldx = desktopX, oldy = desktopY;
--
-- if (scrollRight) {
-- if (desktopX < si.framebufferWidth - dpyWidth) {
-- desktopX += appData.bumpScrollPixels;
-- if (desktopX > si.framebufferWidth - dpyWidth)
-- desktopX = si.framebufferWidth - dpyWidth;
-- }
-- } else if (scrollLeft) {
-- if (desktopX > 0) {
-- desktopX -= appData.bumpScrollPixels;
-- if (desktopX < 0)
-- desktopX = 0;
-- }
-- }
--
-- if (scrollDown) {
-- if (desktopY < si.framebufferHeight - dpyHeight) {
-- desktopY += appData.bumpScrollPixels;
-- if (desktopY > si.framebufferHeight - dpyHeight)
-- desktopY = si.framebufferHeight - dpyHeight;
-- }
-- } else if (scrollUp) {
-- if (desktopY > 0) {
-- desktopY -= appData.bumpScrollPixels;
-- if (desktopY < 0)
-- desktopY = 0;
-- }
-- }
--
-- if (oldx != desktopX || oldy != desktopY) {
-- XawViewportSetCoordinates(viewport, desktopX, desktopY);
-- timer = XtAppAddTimeOut(appContext, appData.bumpScrollTime,
-- BumpScrollTimerCallback, NULL);
-- timerSet = True;
-- return True;
-- }
-+ int oldx = desktopX, oldy = desktopY;
-+ int fbW = si.framebufferWidth;
-+ int fbH = si.framebufferHeight;
-+
-+ if (scale_x > 0) {
-+ fbW = scale_x;
-+ fbH = scale_y;
-+ }
-+
-+ if (scrollRight) {
-+ if (desktopX < fbW - dpyWidth) {
-+ desktopX += appData.bumpScrollPixels;
-+ if (desktopX > fbW - dpyWidth) {
-+ desktopX = fbW - dpyWidth;
-+ }
-+ }
-+ } else if (scrollLeft) {
-+ if (desktopX > 0) {
-+ desktopX -= appData.bumpScrollPixels;
-+ if (desktopX < 0) {
-+ desktopX = 0;
-+ }
-+ }
-+ }
-+
-+ if (scrollDown) {
-+ int ycrop = appData.yCrop;
-+ if (scale_y > 0) {
-+ ycrop = scale_round(ycrop, scale_factor_y);
-+ }
-+ if (ycrop > 0 && desktopY + dpyHeight >= ycrop) {
-+ ;
-+ } else if (desktopY < fbH - dpyHeight) {
-+ desktopY += appData.bumpScrollPixels;
-+ if (desktopY > fbH - dpyHeight) {
-+ desktopY = fbH - dpyHeight;
-+ }
-+ }
-+ } else if (scrollUp) {
-+ if (desktopY > 0) {
-+ desktopY -= appData.bumpScrollPixels;
-+ if (desktopY < 0) {
-+ desktopY = 0;
-+ }
-+ }
-+ }
-+
-+ if (oldx != desktopX || oldy != desktopY) {
-+ XawViewportSetCoordinates(viewport, desktopX, desktopY);
-+ timer = XtAppAddTimeOut(appContext, appData.bumpScrollTime, BumpScrollTimerCallback, NULL);
-+ timerSet = True;
-+ return True;
-+ }
-
-- timerSet = False;
-- return False;
-+ timerSet = False;
-+ return False;
- }
-
- static void
- BumpScrollTimerCallback(XtPointer clientData, XtIntervalId *id)
- {
-- DoBumpScroll();
-+ DoBumpScroll();
-+ if (clientData || id) {}
-+}
-+
-+/* not working: */
-+
-+Bool
-+JumpScroll(int up, int vert) {
-+ scrollLeft = scrollRight = scrollUp = scrollDown = False;
-+
-+
-+ if (appData.fullScreen) {
-+ return True;
-+ }
-+ fprintf(stderr, "JumpScroll(%d, %d)\n", up, vert);
-+
-+ if (vert) {
-+ if (up) {
-+ scrollUp = True;
-+ } else {
-+ scrollDown = True;
-+ }
-+ } else {
-+ if (up) {
-+ scrollRight = True;
-+ } else {
-+ scrollLeft = True;
-+ }
-+ }
-+
-+ if (scrollLeft || scrollRight || scrollUp || scrollDown) {
-+ if (timerSet) {
-+ return True;
-+ }
-+
-+ XtVaGetValues(desktop, XtNx, &desktopX, XtNy, &desktopY, NULL);
-+ desktopX = -desktopX;
-+ desktopY = -desktopY;
-+ return DoJumpScroll();
-+ }
-+
-+ if (timerSet) {
-+ XtRemoveTimeOut(timer);
-+ timerSet = False;
-+ }
-+
-+ return False;
-+}
-+
-+static Bool
-+DoJumpScroll() {
-+ int oldx = desktopX, oldy = desktopY;
-+ int jumpH, jumpV;
-+ int fbW = si.framebufferWidth;
-+ int fbH = si.framebufferHeight;
-+
-+ if (scale_x > 0) {
-+ fbW = scale_x;
-+ fbH = scale_y;
-+ }
-+ jumpH = fbW / 4;
-+ jumpV = fbH / 4;
-+
-+ if (scrollRight) {
-+ if (desktopX < fbW - dpyWidth) {
-+ desktopX += jumpH;
-+ if (desktopX > fbW - dpyWidth)
-+ desktopX = fbW - dpyWidth;
-+ }
-+ } else if (scrollLeft) {
-+ if (desktopX > 0) {
-+ desktopX -= jumpH;
-+ if (desktopX < 0)
-+ desktopX = 0;
-+ }
-+ }
-+
-+ if (scrollDown) {
-+ if (appData.yCrop > 0 && desktopY + dpyHeight >= appData.yCrop) {
-+ ;
-+ } else if (desktopY < fbH - dpyHeight) {
-+ desktopY += jumpV;
-+ if (desktopY > fbH - dpyHeight)
-+ desktopY = fbH - dpyHeight;
-+ }
-+ } else if (scrollUp) {
-+ if (desktopY > 0) {
-+ desktopY -= jumpV;
-+ if (desktopY < 0)
-+ desktopY = 0;
-+ }
-+ }
-+
-+ if (oldx != desktopX || oldy != desktopY) {
-+ XawViewportSetCoordinates(viewport, desktopX, desktopY);
-+ timer = XtAppAddTimeOut(appContext, appData.bumpScrollTime,
-+ JumpScrollTimerCallback, NULL);
-+ timerSet = True;
-+ return True;
-+ }
-+
-+ timerSet = False;
-+ return False;
-+}
-+
-+static void
-+JumpScrollTimerCallback(XtPointer clientData, XtIntervalId *id) {
-+ DoJumpScroll();
-+ if (clientData || id) {}
-+}
-+void JumpRight(Widget w, XEvent *ev, String *params, Cardinal *num_params) {
-+ JumpScroll(1, 0);
-+ if (w || ev || params || num_params) {}
-+}
-+void JumpLeft(Widget w, XEvent *ev, String *params, Cardinal *num_params) {
-+ JumpScroll(0, 0);
-+ if (w || ev || params || num_params) {}
-+}
-+void JumpUp(Widget w, XEvent *ev, String *params, Cardinal *num_params) {
-+ JumpScroll(1, 1);
-+ if (w || ev || params || num_params) {}
- }
-+void JumpDown(Widget w, XEvent *ev, String *params, Cardinal *num_params) {
-+ JumpScroll(0, 1);
-+ if (w || ev || params || num_params) {}
-+}
-+
-+
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/h2html.pl vnc_unixsrc/vncviewer/h2html.pl
---- vnc_unixsrc.orig/vncviewer/h2html.pl 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/h2html.pl 2008-08-30 20:34:45.000000000 -0400
-@@ -0,0 +1,10 @@
-+#!/usr/bin/perl
-+
-+open(HELP, "./vncviewer -help|");
-+
-+while (<HELP>) {
-+ $_ =~ s/&/&amp;/g;
-+ $_ =~ s/</&lt;/g;
-+ $_ =~ s/>/&gt;/g;
-+ print;
-+}
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncviewer/hextile.c
---- vnc_unixsrc.orig/vncviewer/hextile.c 2007-02-17 22:33:46.000000000 -0500
-+++ vnc_unixsrc/vncviewer/hextile.c 2009-10-16 22:54:40.000000000 -0400
-@@ -30,6 +30,21 @@
- #define CARDBPP CONCAT2E(CARD,BPP)
- #define GET_PIXEL CONCAT2E(GET_PIXEL,BPP)
-
-+#define FillRectangle(x, y, w, h, color) \
-+ { \
-+ XGCValues _gcv; \
-+ _gcv.foreground = color; \
-+ if (!appData.useXserverBackingStore) { \
-+ FillScreen(x, y, w, h, _gcv.foreground); \
-+ } else { \
-+ XChangeGC(dpy, gc, GCForeground, &_gcv); \
-+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \
-+ } \
-+ }
-+
-+extern int skip_maybe_sync;
-+extern void maybe_sync(int w, int h);
-+
- static Bool
- HandleHextileBPP (int rx, int ry, int rw, int rh)
- {
-@@ -41,21 +56,43 @@
- int sx, sy, sw, sh;
- CARD8 subencoding;
- CARD8 nSubrects;
-+ int irect = 0, nrects = (rw * rh) / (16 * 16);
-+ static int nosync_ycrop = -1;
-+
-+ if (nosync_ycrop < 0) {
-+ nosync_ycrop = 0;
-+ if (getenv("HEXTILE_YCROP_TOO")) {
-+ nosync_ycrop = 1;
-+ }
-+ }
-
- for (y = ry; y < ry+rh; y += 16) {
- for (x = rx; x < rx+rw; x += 16) {
- w = h = 16;
-- if (rx+rw - x < 16)
-+ if (rx+rw - x < 16) {
- w = rx+rw - x;
-- if (ry+rh - y < 16)
-+ }
-+ if (ry+rh - y < 16) {
- h = ry+rh - y;
-+ }
-+
-+ if (nrects > 400 && (appData.yCrop == 0 || nosync_ycrop)) {
-+ skip_maybe_sync = 0;
-+ if (irect++ % 2000 != 0) {
-+ if (x < rx+rw-16 || y < ry+rh-16) {
-+ skip_maybe_sync = 1;
-+ }
-+ }
-+ }
-
-- if (!ReadFromRFBServer((char *)&subencoding, 1))
-+ if (!ReadFromRFBServer((char *)&subencoding, 1)) {
- return False;
-+ }
-
- if (subencoding & rfbHextileRaw) {
-- if (!ReadFromRFBServer(buffer, w * h * (BPP / 8)))
-+ if (!ReadFromRFBServer(buffer, w * h * (BPP / 8))) {
- return False;
-+ }
-
- CopyDataToScreen(buffer, x, y, w, h);
- continue;
-@@ -66,14 +103,25 @@
- return False;
-
- #if (BPP == 8)
-- if (appData.useBGR233)
-+ if (appData.useBGR233) {
- gcv.foreground = BGR233ToPixel[bg];
-- else
-+ } else
-+#endif
-+#if (BPP == 16)
-+ if (appData.useBGR565) {
-+ gcv.foreground = BGR565ToPixel[bg];
-+ } else
- #endif
-+ {
- gcv.foreground = bg;
-+ }
-
-- XChangeGC(dpy, gc, GCForeground, &gcv);
-- XFillRectangle(dpy, desktopWin, gc, x, y, w, h);
-+#if 0
-+ XChangeGC(dpy, gc, GCForeground, &gcv);
-+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h);
-+#else
-+ FillRectangle(x, y, w, h, gcv.foreground);
-+#endif
-
- if (subencoding & rfbHextileForegroundSpecified)
- if (!ReadFromRFBServer((char *)&fg, sizeof(fg)))
-@@ -101,14 +149,25 @@
- sh = rfbHextileExtractH(*ptr);
- ptr++;
- #if (BPP == 8)
-- if (appData.useBGR233)
-+ if (appData.useBGR233) {
- gcv.foreground = BGR233ToPixel[fg];
-- else
-+ } else
- #endif
-+#if (BPP == 16)
-+ if (appData.useBGR565) {
-+ gcv.foreground = BGR565ToPixel[fg];
-+ } else
-+#endif
-+ {
- gcv.foreground = fg;
-+ }
-
-- XChangeGC(dpy, gc, GCForeground, &gcv);
-- XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh);
-+#if 0
-+ XChangeGC(dpy, gc, GCForeground, &gcv);
-+ XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh);
-+#else
-+ FillRectangle(x+sx, y+sy, sw, sh, gcv.foreground);
-+#endif
- }
-
- } else {
-@@ -116,13 +175,22 @@
- return False;
-
- #if (BPP == 8)
-- if (appData.useBGR233)
-+ if (appData.useBGR233) {
- gcv.foreground = BGR233ToPixel[fg];
-- else
-+ } else
- #endif
-+#if (BPP == 16)
-+ if (appData.useBGR565) {
-+ gcv.foreground = BGR565ToPixel[fg];
-+ } else
-+#endif
-+ {
- gcv.foreground = fg;
-+ }
-
-+#if 0
- XChangeGC(dpy, gc, GCForeground, &gcv);
-+#endif
-
- for (i = 0; i < nSubrects; i++) {
- sx = rfbHextileExtractX(*ptr);
-@@ -131,7 +199,11 @@
- sw = rfbHextileExtractW(*ptr);
- sh = rfbHextileExtractH(*ptr);
- ptr++;
-+#if 0
- XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh);
-+#else
-+ FillRectangle(x+sx, y+sy, sw, sh, gcv.foreground);
-+#endif
- }
- }
- }
-@@ -139,3 +211,5 @@
-
- return True;
- }
-+
-+#undef FillRectangle
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewer/listen.c
---- vnc_unixsrc.orig/vncviewer/listen.c 2001-01-16 03:07:57.000000000 -0500
-+++ vnc_unixsrc/vncviewer/listen.c 2010-04-11 23:14:21.000000000 -0400
-@@ -32,14 +32,88 @@
- #define FLASHDELAY 1 /* seconds */
-
- Bool listenSpecified = False;
-+pid_t listenParent = 0;
- int listenPort = 0, flashPort = 0;
-
-+#if 0
- static Font flashFont;
--
- static void getFlashFont(Display *d);
- static void flashDisplay(Display *d, char *user);
-+#endif
-+
- static Bool AllXEventsPredicate(Display *d, XEvent *ev, char *arg);
-
-+void raiseme(int force);
-+
-+static int accept_popup_check(int *argc, char **argv, char *sip, char *sih) {
-+ char line[16];
-+ char msg[1000];
-+ int dopopup = 1;
-+
-+ if (!getenv("SSVNC_ACCEPT_POPUP")) {
-+ return 1;
-+ }
-+
-+ if (!dopopup && use_tty()) {
-+ raiseme(1);
-+ fprintf(stderr, "Accept VNC connection? y/[n] ");
-+ fgets(line, sizeof(line), stdin);
-+ if (!strchr(line, 'y') && !strchr(line, 'Y')) {
-+ fprintf(stderr, "Refusing connection.\n");
-+ return 0;
-+ } else {
-+ fprintf(stderr, "Accepting connection.\n");
-+ return 1;
-+ }
-+ } else {
-+ int pid, pid2, accept_it = 0;
-+
-+ pid = fork();
-+ if (pid == -1) {
-+ perror("fork");
-+ exit(1);
-+ }
-+ if (pid == 0) {
-+ char *geometry = "2x2+0+0";
-+ String fb[] = { "*message.Scroll: whenNeeded", NULL};
-+ close(rfbsock);
-+
-+ toplevel = XtAppInitialize(&appContext, "Ssvnc", cmdLineOptions, numCmdLineOptions,
-+ argc, argv, fb, NULL, 0);
-+ XtVaSetValues(toplevel, XtNmaxWidth, 2, XtNmaxHeight, 2, NULL);
-+ XtVaSetValues(toplevel, XtNgeometry, geometry, NULL);
-+ XtRealizeWidget(toplevel);
-+ dpy = XtDisplay(toplevel);
-+ sprintf(msg, "\n(LISTEN) Reverse VNC connection from IP: %s\n Hostname: %s\n\n", sip, sih);
-+ strcat(msg, "Accept or Reject VNC connection?");
-+ if (CreateMsg(msg, 2)) {
-+ XCloseDisplay(dpy);
-+ exit(0);
-+ } else {
-+ XCloseDisplay(dpy);
-+ exit(1);
-+ }
-+ } else {
-+ int status;
-+ pid2 = waitpid(pid, &status, 0);
-+ fprintf(stderr, "waitpid: %d/%d status: %d\n", pid, pid2, status);
-+ if (pid2 == pid) {
-+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
-+ accept_it = 1;
-+ }
-+ }
-+ }
-+ if (accept_it) {
-+ fprintf(stderr, "Accepting connection.\n");
-+ return 1;
-+ } else {
-+ fprintf(stderr, "Refusing connection.\n");
-+ return 0;
-+ }
-+ }
-+ return 0;
-+}
-+
- /*
- * listenForIncomingConnections() - listen for incoming connections from
- * servers, and fork a new process to deal with each connection. We must do
-@@ -47,145 +121,291 @@
- * cope with forking very well.
- */
-
-+extern char *accept6_hostname;
-+extern char *accept6_ipaddr;
-+
- void
- listenForIncomingConnections(int *argc, char **argv, int listenArgIndex)
- {
-- Display *d;
-- XEvent ev;
-- int listenSocket, flashSocket, sock;
-- fd_set fds;
-- char flashUser[256];
-- int n;
-- int i;
-- char *displayname = NULL;
--
-- listenSpecified = True;
--
-- for (i = 1; i < *argc; i++) {
-- if (strcmp(argv[i], "-display") == 0 && i+1 < *argc) {
-- displayname = argv[i+1];
-- }
-- }
-+ Display *d;
-+ XEvent ev;
-+ int listenSocket, listenSocket6, flashSocket, sock;
-+ fd_set fds;
-+ char flashUser[256];
-+ int n;
-+ int i;
-+ char *displayname = NULL;
-+ int children = 0;
-+ int totalconn = 0, maxconn = 0;
-+
-+ listenSpecified = True;
-+ listenParent = getpid();
-+
-+ for (i = 1; i < *argc; i++) {
-+ if (strcmp(argv[i], "-display") == 0 && i+1 < *argc) {
-+ displayname = argv[i+1];
-+ }
-+ }
-+ if (sock || flashUser || n) {}
-
-- if (listenArgIndex+1 < *argc && argv[listenArgIndex+1][0] >= '0' &&
-+ if (listenArgIndex+1 < *argc && argv[listenArgIndex+1][0] >= '0' &&
- argv[listenArgIndex+1][0] <= '9') {
-
-- listenPort = LISTEN_PORT_OFFSET + atoi(argv[listenArgIndex+1]);
-- flashPort = FLASH_PORT_OFFSET + atoi(argv[listenArgIndex+1]);
-- removeArgs(argc, argv, listenArgIndex, 2);
-+ listenPort = LISTEN_PORT_OFFSET + atoi(argv[listenArgIndex+1]);
-+ flashPort = FLASH_PORT_OFFSET + atoi(argv[listenArgIndex+1]);
-+ removeArgs(argc, argv, listenArgIndex, 2);
-
-- } else {
-+ } else {
-
-- char *display;
-- char *colonPos;
-- struct utsname hostinfo;
-+ char *display;
-+ char *colonPos;
-+ struct utsname hostinfo;
-
-- removeArgs(argc, argv, listenArgIndex, 1);
-+ removeArgs(argc, argv, listenArgIndex, 1);
-
-- display = XDisplayName(displayname);
-- colonPos = strchr(display, ':');
-+ display = XDisplayName(displayname);
-+ colonPos = strchr(display, ':');
-
-- uname(&hostinfo);
-+ uname(&hostinfo);
-
-- if (colonPos && ((colonPos == display) ||
-- (strncmp(hostinfo.nodename, display,
-- strlen(hostinfo.nodename)) == 0))) {
-+ if (colonPos && ((colonPos == display) ||
-+ (strncmp(hostinfo.nodename, display,
-+ strlen(hostinfo.nodename)) == 0))) {
-
-- listenPort = LISTEN_PORT_OFFSET + atoi(colonPos+1);
-- flashPort = FLASH_PORT_OFFSET + atoi(colonPos+1);
-+ listenPort = LISTEN_PORT_OFFSET + atoi(colonPos+1);
-+ flashPort = FLASH_PORT_OFFSET + atoi(colonPos+1);
-
-- } else {
-- fprintf(stderr,"%s: cannot work out which display number to "
-- "listen on.\n", programName);
-- fprintf(stderr,"Please specify explicitly with -listen <num>\n");
-- exit(1);
-- }
-- }
-+ } else {
-+ fprintf(stderr,"%s: cannot work out which display number to "
-+ "listen on.\n", programName);
-+ fprintf(stderr,"Please specify explicitly with -listen <num>\n");
-+ exit(1);
-+ }
-
-- if (!(d = XOpenDisplay(displayname))) {
-- fprintf(stderr,"%s: unable to open display %s\n",
-- programName, XDisplayName(displayname));
-- exit(1);
-- }
-+ }
-
-- getFlashFont(d);
-+ if (!(d = XOpenDisplay(displayname))) {
-+ fprintf(stderr,"%s: unable to open display %s\n",
-+ programName, XDisplayName(displayname));
-+ exit(1);
-+ }
-
-- listenSocket = ListenAtTcpPort(listenPort);
-- flashSocket = ListenAtTcpPort(flashPort);
-+#if 0
-+ getFlashFont(d);
-+#endif
-
-- if ((listenSocket < 0) || (flashSocket < 0)) exit(1);
-+ listenSocket = ListenAtTcpPort(listenPort);
-+ listenSocket6 = ListenAtTcpPort6(listenPort);
-+
-+#if 0
-+ flashSocket = ListenAtTcpPort(flashPort);
-+#endif
-+ flashSocket = 1234;
-+
-+ if (listenSocket < 0 && listenSocket6 < 0) {
-+ fprintf(stderr,"%s -listen: could not obtain a listening socket on port %d\n",
-+ programName, listenPort);
-+ exit(1);
-+ }
-
-- fprintf(stderr,"%s -listen: Listening on port %d (flash port %d)\n",
-- programName,listenPort,flashPort);
-- fprintf(stderr,"%s -listen: Command line errors are not reported until "
-+ fprintf(stderr,"%s -listen: Listening on port %d ipv4_fd: %d ipv6_fd: %d\n",
-+ programName, listenPort, listenSocket, listenSocket6);
-+ fprintf(stderr,"%s -listen: Cmdline errors are not reported until "
- "a connection comes in.\n", programName);
-
-- while (True) {
-+ /* this will only work if X events drives this loop -- they don't */
-+ if (getenv("SSVNC_MAX_LISTEN")) {
-+ maxconn = atoi(getenv("SSVNC_MAX_LISTEN"));
-+ }
-
-- /* reap any zombies */
-- int status, pid;
-- while ((pid= wait3(&status, WNOHANG, (struct rusage *)0))>0);
--
-- /* discard any X events */
-- while (XCheckIfEvent(d, &ev, AllXEventsPredicate, NULL))
-- ;
--
-- FD_ZERO(&fds);
--
-- FD_SET(flashSocket, &fds);
-- FD_SET(listenSocket, &fds);
-- FD_SET(ConnectionNumber(d), &fds);
--
-- select(FD_SETSIZE, &fds, NULL, NULL, NULL);
--
-- if (FD_ISSET(flashSocket, &fds)) {
--
-- sock = AcceptTcpConnection(flashSocket);
-- if (sock < 0) exit(1);
-- n = read(sock, flashUser, 255);
-- if (n > 0) {
-- flashUser[n] = 0;
-- flashDisplay(d, flashUser);
-- } else {
-- flashDisplay(d, NULL);
-- }
-- close(sock);
-- }
-+ while (True) {
-+ int lsock = -1;
-
-- if (FD_ISSET(listenSocket, &fds)) {
-- rfbsock = AcceptTcpConnection(listenSocket);
-- if (rfbsock < 0) exit(1);
-- if (!SetNonBlocking(rfbsock)) exit(1);
-+ /* reap any zombies */
-+ int status, pid;
-+ while ((pid = wait3(&status, WNOHANG, (struct rusage *)0))>0) {
-+ if (pid > 0 && children > 0) {
-+ children--;
-+ /* this will only work if X events drives this loop -- they don't */
-+ if (maxconn > 0 && totalconn >= maxconn) {
-+ fprintf(stderr,"%s -listen: Finished final connection %d\n",
-+ programName, maxconn);
-+ exit(0);
-+ }
-+ }
-+ }
-
-- XCloseDisplay(d);
-+ /* discard any X events */
-+ while (XCheckIfEvent(d, &ev, AllXEventsPredicate, NULL)) {
-+ ;
-+ }
-
-- /* Now fork off a new process to deal with it... */
-+ FD_ZERO(&fds);
-
-- switch (fork()) {
-+#if 0
-+ FD_SET(flashSocket, &fds);
-+#endif
-+ if (listenSocket >= 0) {
-+ FD_SET(listenSocket, &fds);
-+ }
-+ if (listenSocket6 >= 0) {
-+ FD_SET(listenSocket6, &fds);
-+ }
-+ FD_SET(ConnectionNumber(d), &fds);
-
-- case -1:
-- perror("fork");
-- exit(1);
-+ select(FD_SETSIZE, &fds, NULL, NULL, NULL);
-
-- case 0:
-- /* child - return to caller */
-- close(listenSocket);
-- close(flashSocket);
-- return;
-+ while ((pid = wait3(&status, WNOHANG, (struct rusage *)0))>0) {
-+ if (pid > 0 && children > 0) {
-+ children--;
-+ if (maxconn > 0 && totalconn >= maxconn) {
-+ fprintf(stderr,"%s -listen: Finished final connection %d\n",
-+ programName, maxconn);
-+ exit(0);
-+ }
-+ }
-+ }
-
-- default:
-- /* parent - go round and listen again */
-- close(rfbsock);
-- if (!(d = XOpenDisplay(displayname))) {
-- fprintf(stderr,"%s: unable to open display %s\n",
-- programName, XDisplayName(displayname));
-- exit(1);
-+#if 0
-+ if (FD_ISSET(flashSocket, &fds)) {
-+ sock = AcceptTcpConnection(flashSocket);
-+ if (sock < 0) exit(1);
-+ n = read(sock, flashUser, 255);
-+ if (n > 0) {
-+ flashUser[n] = 0;
-+ flashDisplay(d, flashUser);
-+ } else {
-+ flashDisplay(d, NULL);
-+ }
-+ close(sock);
-+ }
-+#endif
-+
-+ lsock = -1;
-+ if (listenSocket >= 0 && FD_ISSET(listenSocket, &fds)) {
-+ lsock = listenSocket;
-+ } else if (listenSocket6 >= 0 && FD_ISSET(listenSocket6, &fds)) {
-+ lsock = listenSocket6;
-+ }
-+
-+ if (lsock >= 0) {
-+ int multi_ok = 0;
-+ char *sml = getenv("SSVNC_MULTIPLE_LISTEN");
-+ char *sip = NULL;
-+ char *sih = NULL;
-+
-+ if (lsock == listenSocket) {
-+ rfbsock = AcceptTcpConnection(lsock);
-+ } else {
-+ rfbsock = AcceptTcpConnection6(lsock);
-+ }
-+
-+ if (sml != NULL) {
-+ if (strstr(sml, "MAX:") == sml || strstr(sml, "max:") == sml) {
-+ char *q = strchr(sml, ':');
-+ int maxc = atoi(q+1);
-+ if (maxc == 0 && strcmp(q+1, "0")) {
-+ maxc = -99;
-+ }
-+ if (maxc < 0) {
-+ fprintf(stderr, "invalid SSVNC_MULTIPLE_LISTEN=MAX:n, %s, must be 0 or positive, using 1\n", sml);
-+ } else if (maxc == 0) {
-+ multi_ok = 1;
-+ } else if (children < maxc) {
-+ multi_ok = 1;
-+ }
-+ } else if (strcmp(sml, "") && strcmp(sml, "0")) {
-+ multi_ok = 1;
-+ }
-+ }
-+
-+ if (rfbsock < 0) exit(1);
-+ if (!SetNonBlocking(rfbsock)) exit(1);
-+
-+ if (children > 0 && !multi_ok) {
-+ fprintf(stderr,"\n");
-+ fprintf(stderr,"%s: denying extra incoming connection (%d already)\n",
-+ programName, children);
-+ fprintf(stderr,"%s: to override: use '-multilisten' or set SSVNC_MULTIPLE_LISTEN=1\n",
-+ programName);
-+ fprintf(stderr,"\n");
-+ close(rfbsock);
-+ rfbsock = -1;
-+ continue;
-+ }
-+
-+ if (lsock == listenSocket) {
-+ sip = get_peer_ip(rfbsock);
-+ if (strlen(sip) > 100) sip = "0.0.0.0";
-+ sih = ip2host(sip);
-+ if (strlen(sih) > 300) sih = "unknown";
-+ } else {
-+ if (accept6_hostname != NULL) {
-+ sip = accept6_ipaddr;
-+ accept6_ipaddr = NULL;
-+ sih = accept6_hostname;
-+ accept6_hostname = NULL;
-+ } else {
-+ sip = "unknown";
-+ sih = "unknown";
-+ }
-+ }
-+
-+ fprintf(stderr, "\n");
-+ fprintf(stderr, "(LISTEN) Reverse VNC connection from IP: %s\n", sip);
-+ fprintf(stderr, " Hostname: %s\n\n", sih);
-+
-+ if (sml == NULL && !accept_popup_check(argc, argv, sip, sih)) {
-+ close(rfbsock);
-+ rfbsock = -1;
-+ continue;
-+ }
-+
-+ totalconn++;
-+
-+ XCloseDisplay(d);
-+
-+ /* Now fork off a new process to deal with it... */
-+
-+ switch (fork()) {
-+
-+ case -1:
-+ perror("fork");
-+ exit(1);
-+
-+ case 0:
-+ /* child - return to caller */
-+ close(listenSocket);
-+#if 0
-+ close(flashSocket);
-+#endif
-+ if (sml != NULL && !accept_popup_check(argc, argv, sip, sih)) {
-+ close(rfbsock);
-+ rfbsock = -1;
-+ exit(0);
-+ }
-+ return;
-+
-+ default:
-+ /* parent - go round and listen again */
-+ children++;
-+ close(rfbsock);
-+ if (!(d = XOpenDisplay(displayname))) {
-+ fprintf(stderr,"%s: unable to open display %s\n",
-+ programName, XDisplayName(displayname));
-+ exit(1);
-+ }
-+#if 0
-+ getFlashFont(d);
-+#endif
-+ fprintf(stderr,"\n\n%s -listen: Listening on port %d\n",
-+ programName,listenPort);
-+ fprintf(stderr,"%s -listen: Cmdline errors are not reported until "
-+ "a connection comes in.\n\n", programName);
-+ break;
-+ }
- }
-- getFlashFont(d);
-- break;
-- }
- }
-- }
- }
-
-
-@@ -193,9 +413,16 @@
- * getFlashFont
- */
-
-+#if 0
- static void
- getFlashFont(Display *d)
- {
-+
-+#if 1
-+ /* no longer used */
-+ if (d) {}
-+ return;
-+#else
- char fontName[256];
- char **fontNames;
- int nFontNames;
-@@ -209,6 +436,9 @@
- sprintf(fontName,"fixed");
- }
- flashFont = XLoadFont(d, fontName);
-+
-+#endif
-+
- }
-
-
-@@ -219,6 +449,11 @@
- static void
- flashDisplay(Display *d, char *user)
- {
-+#if 1
-+ /* no longer used */
-+ if (d || user) {}
-+ return;
-+#else
- Window w1, w2, w3, w4;
- XSetWindowAttributes attr;
-
-@@ -284,7 +519,11 @@
- XDestroyWindow(d, w3);
- XDestroyWindow(d, w4);
- XFlush(d);
-+
-+#endif
-+
- }
-+#endif
-
- /*
- * AllXEventsPredicate is needed to make XCheckIfEvent return all events.
-@@ -293,5 +532,6 @@
- static Bool
- AllXEventsPredicate(Display *d, XEvent *ev, char *arg)
- {
-- return True;
-+ if (d || ev || arg) {}
-+ return True;
- }
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/misc.c vnc_unixsrc/vncviewer/misc.c
---- vnc_unixsrc.orig/vncviewer/misc.c 2003-01-15 02:58:32.000000000 -0500
-+++ vnc_unixsrc/vncviewer/misc.c 2010-02-25 22:44:09.000000000 -0500
-@@ -23,6 +23,7 @@
-
- #include <vncviewer.h>
- #include <signal.h>
-+#include <sys/wait.h>
- #include <fcntl.h>
-
- static void CleanupSignalHandler(int sig);
-@@ -33,12 +34,20 @@
-
- Dimension dpyWidth, dpyHeight;
- Atom wmDeleteWindow, wmState;
-+int fullscreen_startup = 0;
-
- static Bool xloginIconified = False;
- static XErrorHandler defaultXErrorHandler;
- static XIOErrorHandler defaultXIOErrorHandler;
- static XtErrorHandler defaultXtErrorHandler;
-
-+int XError_ign = 0;
-+
-+void check_tall(void);
-+int guessCrop(void);
-+void get_scale_values(double *fx, double *fy);
-+int scale_round(int n, double factor);
-+Bool SendTextChatFinished(void);
-
- /*
- * ToplevelInitBeforeRealization sets the title, geometry and other resources
-@@ -48,87 +57,122 @@
- void
- ToplevelInitBeforeRealization()
- {
-- char *titleFormat;
-- char *title;
-- char *geometry;
--
-- XtVaGetValues(toplevel, XtNtitle, &titleFormat, NULL);
-- title = XtMalloc(strlen(titleFormat) + strlen(desktopName) + 1);
-- sprintf(title, titleFormat, desktopName);
-- XtVaSetValues(toplevel, XtNtitle, title, XtNiconName, title, NULL);
--
-- XtVaSetValues(toplevel, XtNmaxWidth, si.framebufferWidth,
-- XtNmaxHeight, si.framebufferHeight, NULL);
--
-- dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy));
-- dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy));
--
-- if (appData.fullScreen) {
--
-- /* full screen - set position to 0,0, but defer size calculation until
-- widgets are realized */
--
-- XtVaSetValues(toplevel, XtNoverrideRedirect, True,
-- XtNgeometry, "+0+0", NULL);
--
-- } else {
--
-- /* not full screen - work out geometry for middle of screen unless
-- specified by user */
--
-- XtVaGetValues(toplevel, XtNgeometry, &geometry, NULL);
--
-- if (geometry == NULL) {
-- Dimension toplevelX, toplevelY;
-- Dimension toplevelWidth = si.framebufferWidth;
-- Dimension toplevelHeight = si.framebufferHeight;
--
-- if ((toplevelWidth + appData.wmDecorationWidth) >= dpyWidth)
-- toplevelWidth = dpyWidth - appData.wmDecorationWidth;
--
-- if ((toplevelHeight + appData.wmDecorationHeight) >= dpyHeight)
-- toplevelHeight = dpyHeight - appData.wmDecorationHeight;
--
-- toplevelX = (dpyWidth - toplevelWidth - appData.wmDecorationWidth) / 2;
--
-- toplevelY = (dpyHeight - toplevelHeight - appData.wmDecorationHeight) /2;
--
-- /* set position via "geometry" so that window manager thinks it's a
-- user-specified position and therefore honours it */
--
-- geometry = XtMalloc(256);
--
-- sprintf(geometry, "%dx%d+%d+%d",
-- toplevelWidth, toplevelHeight, toplevelX, toplevelY);
-- XtVaSetValues(toplevel, XtNgeometry, geometry, NULL);
-- }
-- }
-+ char *titleFormat;
-+ char *title;
-+ char *geometry;
-+ int h = si.framebufferHeight;
-+ int w = si.framebufferWidth;
-+
-+ check_tall();
-+ if (appData.yCrop < 0) {
-+ appData.yCrop = guessCrop();
-+ fprintf(stderr, "Set -ycrop to: %d\n", appData.yCrop);
-+ if (appData.yCrop > 0) {
-+ h = appData.yCrop;
-+ }
-+ }
-+
-+ XtVaGetValues(toplevel, XtNtitle, &titleFormat, NULL);
-+ title = XtMalloc(strlen(titleFormat) + strlen(desktopName) + 1);
-+ sprintf(title, titleFormat, desktopName);
-+ XtVaSetValues(toplevel, XtNtitle, title, XtNiconName, title, NULL);
-+
-+ if (appData.scale != NULL) {
-+ /* switched to not scaled */
-+ double frac_x, frac_y;
-+ get_scale_values(&frac_x, &frac_y);
-+ if (frac_x > 0.0 && frac_y > 0.0) {
-+ w = scale_round(w, frac_x);
-+ h = scale_round(h, frac_y);
-+ }
-+ }
-+ XtVaSetValues(toplevel, XtNmaxWidth, w, XtNmaxHeight, h, NULL);
-+
-+ dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy));
-+ dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy));
-+
-+ if (appData.fullScreen) {
-+ /* full screen - set position to 0,0, but defer size calculation until widgets are realized */
-+
-+ if (!net_wm_supported()) {
-+ XtVaSetValues(toplevel, XtNoverrideRedirect, True, XtNgeometry, "+0+0", NULL);
-+ } else {
-+ fullscreen_startup = 1;
-+ }
-+
-+ } else {
-+
-+ /* not full screen - work out geometry for middle of screen unless specified by user */
-+
-+ XtVaGetValues(toplevel, XtNgeometry, &geometry, NULL);
-+
-+ if (geometry == NULL) {
-+ Dimension toplevelX, toplevelY;
-+ Dimension toplevelWidth = w;
-+ Dimension toplevelHeight = h;
-+
-+ if ((toplevelWidth + appData.wmDecorationWidth) >= dpyWidth) {
-+ toplevelWidth = dpyWidth - appData.wmDecorationWidth;
-+ }
-+
-+ if ((toplevelHeight + appData.wmDecorationHeight) >= dpyHeight) {
-+ toplevelHeight = dpyHeight - appData.wmDecorationHeight;
-+ }
-+
-+ toplevelX = (dpyWidth - toplevelWidth - appData.wmDecorationWidth) / 2;
-+ toplevelY = (dpyHeight - toplevelHeight - appData.wmDecorationHeight) /2;
-+
-+ if (appData.appShare) {
-+ int X = appshare_x_hint;
-+ int Y = appshare_y_hint;
-+ if (appData.scale) {
-+ double fx = 1.0, fy = 1.0;
-+ get_scale_values(&fx, &fy);
-+ if (fx > 0.0 && fy > 0.0) {
-+ X *= fx;
-+ Y *= fy;
-+ }
-+ }
-+ if (appshare_x_hint != appshare_0_hint) {
-+ toplevelX = X;
-+ }
-+ if (appshare_y_hint != appshare_0_hint) {
-+ toplevelY = Y;
-+ }
-+ }
-+
-+ /* set position via "geometry" so that window manager thinks it's a
-+ user-specified position and therefore honours it */
-+
-+ geometry = XtMalloc(256);
-+
-+ sprintf(geometry, "%dx%d+%d+%d", toplevelWidth, toplevelHeight, toplevelX, toplevelY);
-+ fprintf(stderr, "geometry: %s ycrop: %d\n", geometry, appData.yCrop);
-+ XtVaSetValues(toplevel, XtNgeometry, geometry, NULL);
-+ }
-+ }
-
- /* Test if the keyboard is grabbed. If so, it's probably because the
- XDM login window is up, so try iconifying it to release the grab */
-
-- if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), False, GrabModeSync,
-- GrabModeSync, CurrentTime) == GrabSuccess) {
-- XUngrabKeyboard(dpy, CurrentTime);
-- } else {
-- wmState = XInternAtom(dpy, "WM_STATE", False);
--
-- if (IconifyNamedWindow(DefaultRootWindow(dpy), "xlogin", False)) {
-- xloginIconified = True;
-- XSync(dpy, False);
-- sleep(1);
-- }
-- }
--
-- /* Set handlers for signals and X errors to perform cleanup */
--
-- signal(SIGHUP, CleanupSignalHandler);
-- signal(SIGINT, CleanupSignalHandler);
-- signal(SIGTERM, CleanupSignalHandler);
-- defaultXErrorHandler = XSetErrorHandler(CleanupXErrorHandler);
-- defaultXIOErrorHandler = XSetIOErrorHandler(CleanupXIOErrorHandler);
-- defaultXtErrorHandler = XtAppSetErrorHandler(appContext,
-- CleanupXtErrorHandler);
-+ if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), False, GrabModeSync, GrabModeSync, CurrentTime) == GrabSuccess) {
-+ XUngrabKeyboard(dpy, CurrentTime);
-+ } else {
-+ wmState = XInternAtom(dpy, "WM_STATE", False);
-+ if (IconifyNamedWindow(DefaultRootWindow(dpy), "xlogin", False)) {
-+ xloginIconified = True;
-+ XSync(dpy, False);
-+ sleep(1);
-+ }
-+ }
-+
-+ /* Set handlers for signals and X errors to perform cleanup */
-+ signal(SIGHUP, CleanupSignalHandler);
-+ signal(SIGINT, CleanupSignalHandler);
-+ signal(SIGTERM, CleanupSignalHandler);
-+ defaultXErrorHandler = XSetErrorHandler(CleanupXErrorHandler);
-+ defaultXIOErrorHandler = XSetIOErrorHandler(CleanupXIOErrorHandler);
-+ defaultXtErrorHandler = XtAppSetErrorHandler(appContext, CleanupXtErrorHandler);
- }
-
-
-@@ -141,14 +185,22 @@
- void
- ToplevelInitAfterRealization()
- {
-- if (appData.fullScreen) {
-- FullScreenOn();
-- }
--
-- wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
-- XSetWMProtocols(dpy, XtWindow(toplevel), &wmDeleteWindow, 1);
-- XtOverrideTranslations
-- (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
-+ if (appData.fullScreen) {
-+ FullScreenOn();
-+ if (net_wm_supported()) {
-+ /* problem with scroll bars sticking: */
-+ XSync(dpy, False);
-+ usleep(50 * 1000);
-+ FullScreenOff();
-+ XSync(dpy, False);
-+ usleep(50 * 1000);
-+ FullScreenOn();
-+ }
-+ }
-+
-+ wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
-+ XSetWMProtocols(dpy, XtWindow(toplevel), &wmDeleteWindow, 1);
-+ XtOverrideTranslations(toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
- }
-
-
-@@ -157,9 +209,7 @@
- * CurrentTime if the event has no time field.
- */
-
--Time
--TimeFromEvent(XEvent *ev)
--{
-+Time TimeFromEvent(XEvent *ev) {
- switch (ev->type) {
- case KeyPress:
- case KeyRelease:
-@@ -192,18 +242,16 @@
- * generated by SendRFBEvent.
- */
-
--void
--Pause(Widget w, XEvent *event, String *params, Cardinal *num_params)
--{
-- int msec;
-+void Pause(Widget w, XEvent *event, String *params, Cardinal *num_params) {
-+ int msec;
-
-- if (*num_params == 0) {
-- msec = 100;
-- } else {
-- msec = atoi(params[0]);
-- }
--
-- usleep(msec * 1000);
-+ if (*num_params == 0) {
-+ msec = 100;
-+ } else {
-+ msec = atoi(params[0]);
-+ }
-+ usleep(msec * 1000);
-+ if (w || event || params || num_params) {}
- }
-
-
-@@ -256,6 +304,7 @@
- /* Wait for Child 1 to die */
- wait(&childstatus);
-
-+ if (w || event || params || num_params) {}
- return;
- }
-
-@@ -264,11 +313,10 @@
- * Quit action - called when we get a "delete window" message.
- */
-
--void
--Quit(Widget w, XEvent *event, String *params, Cardinal *num_params)
--{
-- Cleanup();
-- exit(0);
-+void Quit(Widget w, XEvent *event, String *params, Cardinal *num_params) {
-+ Cleanup();
-+ if (w || event || params || num_params) {}
-+ exit(0);
- }
-
-
-@@ -276,49 +324,94 @@
- * Cleanup - perform any cleanup operations prior to exiting.
- */
-
--void
--Cleanup()
--{
-- if (xloginIconified) {
-- IconifyNamedWindow(DefaultRootWindow(dpy), "xlogin", True);
-- XFlush(dpy);
-- }
-+void Cleanup() {
-+
-+ if (appData.chatActive) {
-+ appData.chatActive = False;
-+ fprintf(stderr,"Sending SendTextChatClose()\n");
-+ SendTextChatClose();
-+ SendTextChatFinished();
-+ }
-+
-+ if (xloginIconified) {
-+ IconifyNamedWindow(DefaultRootWindow(dpy), "xlogin", True);
-+ XFlush(dpy);
-+ }
- #ifdef MITSHM
-- if (appData.useShm)
-- ShmCleanup();
-+ if (appData.useShm) {
-+ if (UsingShm()) {
-+ ShmDetach();
-+ }
-+ ShmCleanup();
-+ }
- #endif
-+
-+ releaseAllPressedModifiers();
-+
-+ fprintf(stderr,"\nVNC Viewer exiting.\n\n");
-+ if (listenSpecified) {
-+ if (listenParent != 0 && getenv("SSVNC_LISTEN_ONCE") && listenParent != getpid()) {
-+ fprintf(stderr, "SSVNC_LISTEN_ONCE: Trying to kill Listening Parent: %d\n", (int) listenParent);
-+ fprintf(stderr, "SSVNC_LISTEN_ONCE: Press Ctrl-C if it continues to Listen.\n\n");
-+ kill(listenParent, SIGTERM);
-+ } else {
-+ fprintf(stderr,"(NOTE: You may need to Press Ctrl-C to make the Viewer Stop Listening.)\n\n");
-+ }
-+ }
-+}
-+
-+static void check_dbg(void) {
-+ if (getenv("SSVNC_EXIT_DEBUG")) {
-+ fprintf(stderr, "Press any key to continue: ");
-+ getc(stdin);
-+ }
- }
-
- static int
- CleanupXErrorHandler(Display *dpy, XErrorEvent *error)
- {
-- fprintf(stderr,"CleanupXErrorHandler called\n");
-- Cleanup();
-- return (*defaultXErrorHandler)(dpy, error);
-+ if (XError_ign) {
-+ char str[4096];
-+ XError_ign++;
-+ fprintf(stderr,"XError_ign called.\n");
-+ str[0] = '\0';
-+ if (XGetErrorText(dpy, error->error_code, str, 4096)) {
-+ fprintf(stderr, "%s", str);
-+ }
-+ return 0;
-+ }
-+ fprintf(stderr,"CleanupXErrorHandler called\n");
-+ check_dbg();
-+ Cleanup();
-+ return (*defaultXErrorHandler)(dpy, error);
- }
-
- static int
- CleanupXIOErrorHandler(Display *dpy)
- {
-- fprintf(stderr,"CleanupXIOErrorHandler called\n");
-- Cleanup();
-- return (*defaultXIOErrorHandler)(dpy);
-+ fprintf(stderr,"CleanupXIOErrorHandler called\n");
-+ check_dbg();
-+ Cleanup();
-+ return (*defaultXIOErrorHandler)(dpy);
- }
-
- static void
- CleanupXtErrorHandler(String message)
- {
-- fprintf(stderr,"CleanupXtErrorHandler called\n");
-- Cleanup();
-- (*defaultXtErrorHandler)(message);
-+ fprintf(stderr,"CleanupXtErrorHandler called\n");
-+ check_dbg();
-+ Cleanup();
-+ (*defaultXtErrorHandler)(message);
- }
-
- static void
- CleanupSignalHandler(int sig)
- {
-- fprintf(stderr,"CleanupSignalHandler called\n");
-- Cleanup();
-- exit(1);
-+ fprintf(stderr,"CleanupSignalHandler called\n");
-+ check_dbg();
-+ Cleanup();
-+ if (sig) {}
-+ exit(1);
- }
-
-
-@@ -362,7 +455,7 @@
- if (!XQueryTree(dpy, w, &dummy, &dummy, &children, &nchildren))
- return False;
-
-- for (i = 0; i < nchildren; i++) {
-+ for (i = 0; i < (int) nchildren; i++) {
- if (IconifyNamedWindow(children[i], name, undo)) {
- XFree ((char *)children);
- return True;
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer/popup.c
---- vnc_unixsrc.orig/vncviewer/popup.c 2000-06-11 08:00:53.000000000 -0400
-+++ vnc_unixsrc/vncviewer/popup.c 2010-04-11 22:03:32.000000000 -0400
-@@ -22,25 +22,69 @@
- */
-
- #include "vncviewer.h"
-+#include <time.h>
-+#include <sys/wait.h>
-
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/Command.h>
-+#include <X11/Xaw/AsciiText.h>
- #include <X11/Xaw/Toggle.h>
-
-+#include <X11/Xaw/Box.h>
-+#include <X11/Xaw/Scrollbar.h>
-+
- Widget popup, fullScreenToggle;
-
-+Bool SendTextChatFinished(void);
-+
-+void popupFixer(Widget wid) {
-+ Window rr, cr;
-+ unsigned int m;
-+ int x0 = 500, y0 = 500;
-+ int xr, yr, wxr, wyr;
-+ Dimension ph;
-+ if (XQueryPointer(dpy, DefaultRootWindow(dpy), &rr, &cr, &xr, &yr, &wxr, &wyr, &m)) {
-+ x0 = xr;
-+ y0 = yr;
-+ }
-+ XtPopup(wid, XtGrabNone);
-+ XtVaGetValues(wid, XtNheight, &ph, NULL);
-+ if (y0 + (int) ph > dpyHeight) {
-+ y0 = dpyHeight - (int) ph;
-+ if (y0 < 0) {
-+ y0 = 0;
-+ }
-+ }
-+ XtMoveWidget(wid, x0, y0);
-+}
-+
-+void Noop(Widget w, XEvent *event, String *params, Cardinal *num_params) {
-+ if (0) fprintf(stderr, "No-op\n");
-+ if (w || event || params || num_params) {}
-+}
-+
- void
- ShowPopup(Widget w, XEvent *event, String *params, Cardinal *num_params)
- {
-- XtMoveWidget(popup, event->xbutton.x_root, event->xbutton.y_root);
-- XtPopup(popup, XtGrabNone);
-- XSetWMProtocols(dpy, XtWindow(popup), &wmDeleteWindow, 1);
-+ if (appData.popupFix) {
-+ popupFixer(popup);
-+ } else {
-+ XtMoveWidget(popup, event->xbutton.x_root, event->xbutton.y_root);
-+ XtPopup(popup, XtGrabNone);
-+ }
-+ if (appData.grabAll) {
-+ XSync(dpy, False);
-+ XRaiseWindow(dpy, XtWindow(popup));
-+ }
-+ XSetWMProtocols(dpy, XtWindow(popup), &wmDeleteWindow, 1);
-+ XtOverrideTranslations(popup, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HidePopup()"));
-+ if (w || event || params || num_params) {}
- }
-
- void
--HidePopup(Widget w, XEvent *event, String *params, Cardinal *num_params)
--{
-- XtPopdown(popup);
-+HidePopup(Widget w, XEvent *event, String *params, Cardinal *num_params) {
-+ XtPopdown(popup);
-+ if (w || event || params || num_params) {}
- }
-
-
-@@ -52,42 +96,808 @@
- };
-
- void
--CreatePopup()
-+CreatePopup() {
-+ Widget buttonForm1, buttonForm2, twoForm, button = 0, prevButton = NULL;
-+ int i;
-+ char buttonName[12];
-+ String buttonType;
-+
-+ popup = XtVaCreatePopupShell("popup", transientShellWidgetClass, toplevel, NULL);
-+
-+ twoForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, popup, NULL);
-+ buttonForm1 = XtVaCreateManagedWidget("buttonForm", formWidgetClass, twoForm, NULL);
-+ buttonForm2 = XtVaCreateManagedWidget("buttonForm", formWidgetClass, twoForm, XtNfromHoriz, (XtArgVal) buttonForm1, NULL);
-+
-+ if (appData.popupButtonCount > 100) {
-+ fprintf(stderr,"Too many popup buttons\n");
-+ exit(1);
-+ }
-+
-+ for (i = 1; i <= appData.popupButtonCount; i++) {
-+ Widget bform;
-+ sprintf(buttonName, "button%d", i);
-+
-+ if (i <= appData.popupButtonBreak) {
-+ bform = buttonForm1;
-+ } else {
-+ if (i == appData.popupButtonBreak+1) {
-+ prevButton = NULL;
-+ }
-+ bform = buttonForm2;
-+ }
-+ XtVaGetSubresources(bform, (XtPointer)&buttonType, buttonName, "Button", resources, 1, NULL);
-+
-+ if (strcmp(buttonType, "command") == 0) {
-+ button = XtVaCreateManagedWidget(buttonName, commandWidgetClass, bform, NULL);
-+ XtVaSetValues(button, XtNfromVert, prevButton, XtNleft, XawChainLeft, XtNright, XawChainRight, NULL);
-+ } else if (strcmp(buttonType, "toggle") == 0) {
-+ button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass, bform, NULL);
-+ XtVaSetValues(button, XtNfromVert, prevButton, XtNleft, XawChainLeft, XtNright, XawChainRight, NULL);
-+ } else {
-+ fprintf(stderr,"unknown button type '%s'\n", buttonType);
-+ }
-+ prevButton = button;
-+ }
-+}
-+
-+
-+Widget scaleN;
-+
-+void
-+ShowScaleN(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ if (appData.popupFix) {
-+ popupFixer(scaleN);
-+ } else {
-+ XtMoveWidget(scaleN, event->xbutton.x_root, event->xbutton.y_root);
-+ XtPopup(scaleN, XtGrabNone);
-+ }
-+ if (appData.grabAll) {
-+ XRaiseWindow(dpy, XtWindow(scaleN));
-+ }
-+ XSetWMProtocols(dpy, XtWindow(scaleN), &wmDeleteWindow, 1);
-+ XtOverrideTranslations(scaleN, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HideScaleN()"));
-+ if (w || event || params || num_params) {}
-+}
-+
-+void
-+HideScaleN(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ XtPopdown(scaleN);
-+ if (w || event || params || num_params) {}
-+}
-+
-+
-+void
-+CreateScaleN()
- {
- Widget buttonForm, button, prevButton = NULL;
- int i;
-- char buttonName[12];
-+ char buttonName[32];
- String buttonType;
-
-- popup = XtVaCreatePopupShell("popup", transientShellWidgetClass, toplevel,
-+ scaleN = XtVaCreatePopupShell("scaleN", transientShellWidgetClass, toplevel,
- NULL);
-
-- buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, popup,
-+ buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, scaleN,
- NULL);
-
-- if (appData.popupButtonCount > 100) {
-- fprintf(stderr,"Too many popup buttons\n");
-- exit(1);
-- }
--
-- for (i = 1; i <= appData.popupButtonCount; i++) {
-+ for (i = 0; i <= 6; i++) {
- sprintf(buttonName, "button%d", i);
- XtVaGetSubresources(buttonForm, (XtPointer)&buttonType, buttonName,
- "Button", resources, 1, NULL);
-
-- if (strcmp(buttonType, "command") == 0) {
-- button = XtVaCreateManagedWidget(buttonName, commandWidgetClass,
-+ button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass,
- buttonForm, NULL);
-- XtVaSetValues(button, XtNfromVert, prevButton,
-+ XtVaSetValues(button, XtNfromVert, prevButton,
- XtNleft, XawChainLeft, XtNright, XawChainRight, NULL);
-- } else if (strcmp(buttonType, "toggle") == 0) {
-- button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass,
-+ prevButton = button;
-+ }
-+}
-+
-+Widget turbovncW;
-+
-+static Widget turboButtons[32];
-+
-+Widget qualtext, qualslider;
-+
-+void UpdateQualSlider(void) {
-+#ifdef TURBOVNC
-+ char text[16];
-+ XawScrollbarSetThumb(qualslider, (float)appData.qualityLevel/100., 0.);
-+ sprintf(text, "%3d", appData.qualityLevel);
-+ XtVaSetValues(qualtext, XtNlabel, text, NULL);
-+#endif
-+}
-+
-+void qualScrollProc(Widget w, XtPointer client, XtPointer p) {
-+#ifdef TURBOVNC
-+ float size, val; int qual, pos=(int)p;
-+ XtVaGetValues(w, XtNshown, &size, XtNtopOfThumb, &val, 0);
-+ if(pos<0) val-=.1; else val+=.1;
-+ qual=(int)(val*100.); if(qual<1) qual=1; if(qual>100) qual=100;
-+ XawScrollbarSetThumb(w, val, 0.);
-+ appData.qualityLevel=qual;
-+ UpdateQual();
-+#endif
-+ if (w || client || p) {}
-+}
-+
-+void qualJumpProc(Widget w, XtPointer client, XtPointer p) {
-+#ifdef TURBOVNC
-+ float val=*(float *)p; int qual;
-+ qual=(int)(val*100.); if(qual<1) qual=1; if(qual>100) qual=100;
-+ appData.qualityLevel=qual;
-+ UpdateQual();
-+#endif
-+ if (w || client || p) {}
-+}
-+
-+void UpdateSubsampButtons(void) {
-+#ifdef TURBOVNC
-+ int i;
-+ for (i=7; i <= 10; i++) {
-+ XtVaSetValues(turboButtons[i], XtNstate, 0, NULL);
-+ }
-+ if (appData.subsampLevel==TVNC_1X) {
-+ i = 7;
-+ } else if (appData.subsampLevel==TVNC_2X) {
-+ i = 8;
-+ } else if (appData.subsampLevel==TVNC_4X) {
-+ i = 9;
-+ } else if (appData.subsampLevel==TVNC_GRAY) {
-+ i = 10;
-+ } else {
-+ return;
-+ }
-+ XtVaSetValues(turboButtons[i], XtNstate, 1, NULL);
-+#endif
-+}
-+
-+void
-+ShowTurboVNC(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ UpdateSubsampButtons();
-+ UpdateQualSlider();
-+ if (appData.popupFix) {
-+ popupFixer(turbovncW);
-+ } else {
-+ XtMoveWidget(turbovncW, event->xbutton.x_root, event->xbutton.y_root);
-+ XtPopup(turbovncW, XtGrabNone);
-+ }
-+ if (appData.grabAll) {
-+ XRaiseWindow(dpy, XtWindow(turbovncW));
-+ }
-+ XSetWMProtocols(dpy, XtWindow(turbovncW), &wmDeleteWindow, 1);
-+ XtOverrideTranslations(turbovncW, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HideTurboVNC()"));
-+ if (w || event || params || num_params) {}
-+}
-+
-+void
-+HideTurboVNC(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ XtPopdown(turbovncW);
-+ if (w || event || params || num_params) {}
-+}
-+
-+void
-+CreateTurboVNC() {
-+ Widget buttonForm, button, prevButton = NULL;
-+ Widget label;
-+ int i;
-+ char buttonName[32];
-+ String buttonType;
-+
-+ turbovncW = XtVaCreatePopupShell("turboVNC", transientShellWidgetClass, toplevel, NULL);
-+
-+ buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, turbovncW, NULL);
-+
-+ for (i = 0; i <= 12; i++) {
-+ sprintf(buttonName, "button%d", i);
-+#ifndef TURBOVNC
-+ if (i == 0) {
-+ sprintf(buttonName, "buttonNone");
-+ } else if (i > 0) {
-+ return;
-+ }
-+#endif
-+ XtVaGetSubresources(buttonForm, (XtPointer)&buttonType, buttonName,
-+ "Button", resources, 1, NULL);
-+
-+ button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass,
-+ buttonForm, NULL);
-+ turboButtons[i] = button;
-+ XtVaSetValues(button, XtNfromVert, prevButton,
-+ XtNleft, XawChainLeft, XtNright, XawChainRight, NULL);
-+ prevButton = button;
-+ }
-+
-+ label = XtCreateManagedWidget("qualLabel", toggleWidgetClass, buttonForm, NULL, 0);
-+ XtVaSetValues(label, XtNfromVert, prevButton, XtNleft, XawChainLeft, XtNright, XawChainRight, NULL);
-+
-+ qualslider = XtCreateManagedWidget("qualBar", scrollbarWidgetClass, buttonForm, NULL, 0);
-+ XtVaSetValues(qualslider, XtNfromVert, label, XtNleft, XawChainLeft, NULL);
-+ XtAddCallback(qualslider, XtNscrollProc, qualScrollProc, NULL) ;
-+ XtAddCallback(qualslider, XtNjumpProc, qualJumpProc, NULL) ;
-+
-+ qualtext = XtCreateManagedWidget("qualText", labelWidgetClass, buttonForm, NULL, 0);
-+ XtVaSetValues(qualtext, XtNfromVert, label, XtNfromHoriz, qualslider, XtNright, XawChainRight, NULL);
-+}
-+
-+Widget qualityW;
-+
-+void
-+ShowQuality(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ if (appData.popupFix) {
-+ popupFixer(qualityW);
-+ } else {
-+ XtMoveWidget(qualityW, event->xbutton.x_root, event->xbutton.y_root);
-+ XtPopup(qualityW, XtGrabNone);
-+ }
-+ if (appData.grabAll) {
-+ XRaiseWindow(dpy, XtWindow(qualityW));
-+ }
-+ XSetWMProtocols(dpy, XtWindow(qualityW), &wmDeleteWindow, 1);
-+ XtOverrideTranslations(qualityW, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HideQuality()"));
-+ if (w || event || params || num_params) {}
-+}
-+
-+void
-+HideQuality(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ XtPopdown(qualityW);
-+ if (w || event || params || num_params) {}
-+}
-+
-+
-+void
-+CreateQuality()
-+{
-+ Widget buttonForm, button, prevButton = NULL;
-+ int i;
-+ char buttonName[32];
-+ String buttonType;
-+
-+ qualityW = XtVaCreatePopupShell("quality", transientShellWidgetClass, toplevel,
-+ NULL);
-+
-+ buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, qualityW,
-+ NULL);
-+
-+ for (i = -1; i <= 9; i++) {
-+ if (i < 0) {
-+ sprintf(buttonName, "buttonD");
-+ } else {
-+ sprintf(buttonName, "button%d", i);
-+ }
-+ XtVaGetSubresources(buttonForm, (XtPointer)&buttonType, buttonName,
-+ "Button", resources, 1, NULL);
-+
-+ button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass,
- buttonForm, NULL);
-- XtVaSetValues(button, XtNfromVert, prevButton,
-+ XtVaSetValues(button, XtNfromVert, prevButton,
- XtNleft, XawChainLeft, XtNright, XawChainRight, NULL);
-+ prevButton = button;
-+ }
-+}
-+
-+Widget compressW;
-+
-+void
-+ShowCompress(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ if (appData.popupFix) {
-+ popupFixer(compressW);
-+ } else {
-+ XtMoveWidget(compressW, event->xbutton.x_root, event->xbutton.y_root);
-+ XtPopup(compressW, XtGrabNone);
-+ }
-+ if (appData.grabAll) {
-+ XRaiseWindow(dpy, XtWindow(compressW));
-+ }
-+ XSetWMProtocols(dpy, XtWindow(compressW), &wmDeleteWindow, 1);
-+ XtOverrideTranslations(compressW, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HideCompress()"));
-+ if (w || event || params || num_params) {}
-+}
-+
-+void
-+HideCompress(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ XtPopdown(compressW);
-+ if (w || event || params || num_params) {}
-+}
-+
-+
-+void
-+CreateCompress()
-+{
-+ Widget buttonForm, button, prevButton = NULL;
-+ int i;
-+ char buttonName[32];
-+ String buttonType;
-+
-+ compressW = XtVaCreatePopupShell("compress", transientShellWidgetClass, toplevel,
-+ NULL);
-+
-+ buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, compressW,
-+ NULL);
-+
-+ for (i = -1; i <= 9; i++) {
-+ if (i < 0) {
-+ sprintf(buttonName, "buttonD");
- } else {
-- fprintf(stderr,"unknown button type '%s'\n",buttonType);
-+ sprintf(buttonName, "button%d", i);
- }
-+ XtVaGetSubresources(buttonForm, (XtPointer)&buttonType, buttonName,
-+ "Button", resources, 1, NULL);
-+
-+ button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass,
-+ buttonForm, NULL);
-+ XtVaSetValues(button, XtNfromVert, prevButton,
-+ XtNleft, XawChainLeft, XtNright, XawChainRight, NULL);
- prevButton = button;
- }
- }
-+
-+
-+int filexfer_sock = -1;
-+int filexfer_listen = -1;
-+
-+void HideFile(Widget w, XEvent *event, String *params, Cardinal *num_params) {
-+ if (filexfer_sock >= 0) {
-+ close(filexfer_sock);
-+ filexfer_sock = -1;
-+ }
-+ if (filexfer_listen >= 0) {
-+ close(filexfer_listen);
-+ filexfer_listen = -1;
-+ }
-+ if (w || event || params || num_params) {}
-+}
-+
-+extern int use_loopback;
-+time_t start_listen = 0;
-+pid_t java_helper = 0;
-+
-+void ShowFile(Widget w, XEvent *event, String *params, Cardinal *num_params) {
-+ int i, port0 = 7200, port, sock = -1;
-+ char *cmd, *jar;
-+ char fmt[] = "java -cp '%s' VncViewer HOST localhost PORT %d delayAuthPanel yes ignoreMSLogonCheck yes disableSSL yes ftpOnly yes graftFtp yes dsmActive no &";
-+
-+ if (getenv("SSVNC_ULTRA_FTP_JAR")) {
-+ jar = getenv("SSVNC_ULTRA_FTP_JAR");
-+ cmd = (char *) malloc(strlen(fmt) + strlen(jar) + 100);
-+ } else {
-+ fprintf(stderr, "Cannot find UltraVNC FTP jar file.\n");
-+ return;
-+ }
-+
-+ use_loopback = 1;
-+ for (i = 0; i < 100; i++) {
-+ port = port0 + i;
-+ sock = ListenAtTcpPort(port);
-+ if (sock < 0) {
-+ sock = ListenAtTcpPort6(port);
-+ }
-+ if (sock >= 0) {
-+ fprintf(stderr, "listening for filexfer on port: %d sock: %d\n", port, sock);
-+ break;
-+ }
-+ }
-+ use_loopback = 0;
-+
-+ if (sock >= 0) {
-+ int st;
-+ pid_t pid = fork();
-+ if (pid < 0) {
-+ free(cmd);
-+ return;
-+ } else if (pid == 0) {
-+ int i;
-+ sprintf(cmd, fmt, jar, port);
-+ if (appData.ultraDSM) {
-+ char *q = strstr(cmd, "dsmActive");
-+ if (q) {
-+ q = strstr(q, "no ");
-+ if (q) {
-+ q[0] = 'y';
-+ q[1] = 'e';
-+ q[2] = 's';
-+ }
-+ }
-+ }
-+ for (i = 3; i < 100; i++) {
-+ close(i);
-+ }
-+ fprintf(stderr, "\n-- Experimental UltraVNC File Transfer --\n\nRunning cmd:\n\n %s\n\n", cmd);
-+ system(cmd);
-+ exit(0);
-+ }
-+ fprintf(stderr, "java helper pid is: %d\n", (int) pid);
-+ waitpid(pid, &st, 0);
-+ java_helper = pid;
-+ start_listen = time(NULL);
-+ }
-+ free(cmd);
-+ filexfer_listen = sock;
-+ if (w || event || params || num_params) {}
-+}
-+
-+Widget chat, entry, text;
-+
-+static int chat_visible = 0;
-+
-+void
-+ShowChat(Widget w, XEvent *event, String *params, Cardinal *num_params)
-+{
-+ if (appData.termChat) {
-+ return;
-+ }
-+ if (! chat_visible) {
-+ XtPopup(chat, XtGrabNone);
-+ chat_visible = 1;
-+ wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
-+ XSetWMProtocols(dpy, XtWindow(chat), &wmDeleteWindow, 1);
-+ if (appData.chatOnly) {
-+ XtOverrideTranslations(chat, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
-+ } else {
-+ XtOverrideTranslations(chat, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HideChat()"));
-+ }
-+ XSync(dpy, False);
-+ usleep(200 * 1000);
-+ }
-+ if (w || event || params || num_params) {}
-+}
-+
-+void hidechat(void) {
-+ appData.chatActive = False;
-+ if (appData.termChat) {
-+ return;
-+ }
-+ if (chat_visible) {
-+ XtPopdown(chat);
-+ chat_visible = 0;
-+ XSync(dpy, False);
-+ usleep(200 * 1000);
-+ }
-+ if (appData.chatOnly) {
-+ Quit(0, NULL, NULL, NULL);
-+ }
-+}
-+
-+void HideChat(Widget w, XEvent *event, String *params, Cardinal *num_params) {
-+ SendTextChatClose();
-+ SendTextChatFinished();
-+ hidechat();
-+ if (w || event || params || num_params) {}
-+}
-+
-+void dismiss_proc(Widget w, XtPointer client_data, XtPointer call_data) {
-+ SendTextChatClose();
-+ SendTextChatFinished();
-+ hidechat();
-+ if (w || client_data || call_data) {}
-+}
-+
-+extern void printChat(char *, Bool);
-+
-+static void ChatTextCallback(XtPointer clientData, XtIntervalId *id);
-+static XtIntervalId timer;
-+static Bool timerSet = False;
-+
-+void CheckTextInput(void);
-+extern double start_time;
-+
-+static void ChatTextCallback(XtPointer clientData, XtIntervalId *id) {
-+ static int db = -1;
-+ if (db < 0) {
-+ if (getenv("SSVNC_DEBUG_CHAT")) {
-+ db = 1;
-+ } else {
-+ db = 0;
-+ }
-+ }
-+ if (db) fprintf(stderr, "ChatTextCallback: %.4f\n", dnow() - start_time);
-+ CheckTextInput();
-+ if (clientData || id) {}
-+}
-+
-+void CheckTextInput(void) {
-+ Arg args[2];
-+ String str;
-+ int len;
-+ static int db = -1;
-+
-+ if (timerSet) {
-+ XtRemoveTimeOut(timer);
-+ timerSet = False;
-+ }
-+ if (appData.chatActive) {
-+ timer = XtAppAddTimeOut(appContext, 333, ChatTextCallback, NULL);
-+ timerSet = True;
-+ }
-+ if (appData.chatOnly && !appData.chatActive) {
-+ Quit(0, NULL, NULL, NULL);
-+ }
-+
-+ if (appData.termChat) {
-+ return;
-+ }
-+#if 0
-+ if (!appData.chatActive) {
-+ return;
-+ }
-+#endif
-+
-+ if (db < 0) {
-+ if (getenv("SSVNC_DEBUG_CHAT")) {
-+ db = 1;
-+ } else {
-+ db = 0;
-+ }
-+ }
-+
-+ XtSetArg(args[0], XtNstring, &str);
-+ XtGetValues(entry, args, 1);
-+
-+ if (db) fprintf(stderr, "CheckTextInput\n");
-+
-+ if (str == NULL || str[0] == '\0') {
-+ return;
-+ } else {
-+ char *q;
-+ len = strlen(str);
-+ if (db) fprintf(stderr, "CheckTextInput: len: %d '%s'\n", len, str);
-+ if (len <= 0) {
-+ return;
-+ }
-+ q = strrchr(str, '\n');
-+ if (q) {
-+ char *send, save[2];
-+ save[0] = *(q+1);
-+ *(q+1) = '\0';
-+ send = strdup(str);
-+ *(q+1) = save[0];
-+ if (send) {
-+ SendTextChat(send);
-+ printChat("Send: ", True);
-+ printChat(send, True);
-+ free(send);
-+ if (save[0] == '\0') {
-+ XtVaSetValues(entry, XtNtype, XawAsciiString, XtNstring, "", NULL);
-+ } else {
-+ char *leak = strdup(q+1);
-+ XtVaSetValues(entry, XtNtype, XawAsciiString, XtNstring, leak, NULL);
-+ if (strlen(leak) > 0) {
-+ XSync(dpy, False);
-+ XtVaSetValues(entry, XtNinsertPosition, strlen(leak), NULL);
-+ }
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+void AppendChatInput0(char *in) {
-+ Arg args[10];
-+ int n;
-+ String str;
-+ int len;
-+ static char *s = NULL;
-+ static int slen = -1;
-+ XawTextPosition pos;
-+
-+ fprintf(stderr, "AppendChatInput: in= '%s'\n", in);
-+
-+ XtSetArg(args[0], XtNstring, &str);
-+ XtGetValues(text, args, 1);
-+ fprintf(stderr, "AppendChatInput: str='%s'\n", str);
-+
-+ len = strlen(str) + strlen(in);
-+
-+ if (slen <= len) {
-+ slen = 2 * (len + 10);
-+ if (s) free(s);
-+ s = (char *) malloc(slen+1);
-+ }
-+
-+ s[0] = '\0';
-+ strcat(s, str);
-+ strcat(s, in);
-+ fprintf(stderr, "AppendChatInput s= '%s'\n", s);
-+ pos = (XawTextPosition) (len-1);
-+ n = 0;
-+ XtSetArg(args[n], XtNtype, XawAsciiString); n++;
-+ XtSetArg(args[n], XtNstring, s); n++;
-+ XtSetArg(args[n], XtNdisplayPosition, pos); n++;
-+ XtSetArg(args[n], XtNinsertPosition, pos); n++;
-+ XtSetValues(text, args, n);
-+ fprintf(stderr, "AppendChatInput done\n");
-+}
-+
-+void AppendChatInput(char *in) {
-+ XawTextPosition beg, end;
-+ static XawTextPosition pos = 0;
-+ XawTextBlock txt;
-+
-+ if (appData.termChat) {
-+ return;
-+ }
-+
-+ XawTextSetInsertionPoint(text, pos);
-+ beg = XawTextGetInsertionPoint(text);
-+ end = beg;
-+#if 0
-+ fprintf(stderr, "AppendChatInput: pos=%d in= '%s'\n", beg, in);
-+#endif
-+
-+ txt.firstPos = 0;
-+ txt.length = strlen(in);
-+ txt.ptr = in;
-+ txt.format = FMT8BIT;
-+
-+ XawTextReplace(text, beg, end, &txt);
-+ XawTextSetInsertionPoint(text, beg + txt.length);
-+
-+ pos = XawTextGetInsertionPoint(text);
-+#if 0
-+ fprintf(stderr, "AppendChatInput done pos=%d\n", pos);
-+#endif
-+}
-+
-+#if 0
-+static char errorbuf[1] = {0};
-+#endif
-+
-+void CreateChat(void) {
-+
-+ Widget myform, dismiss;
-+ Dimension w = 400, h = 300;
-+
-+ chat = XtVaCreatePopupShell("chat", topLevelShellWidgetClass, toplevel, XtNmappedWhenManaged, False, NULL);
-+
-+ myform = XtVaCreateManagedWidget("myform", formWidgetClass, chat, NULL);
-+
-+ text = XtVaCreateManagedWidget("text", asciiTextWidgetClass, myform,
-+ XtNresize, XawtextResizeBoth, XtNresizable, True, XtNwrap, XawtextWrapWord,
-+ XtNscrollHorizontal, XawtextScrollNever, XtNscrollVertical, XawtextScrollAlways,
-+ XtNwidth, w, XtNheight, h, XtNdisplayCaret, False,
-+ XtNeditType, XawtextAppend, XtNtype, XawAsciiString,
-+ XtNuseStringInPlace, False, NULL);
-+
-+ entry = XtVaCreateManagedWidget("entry", asciiTextWidgetClass, myform,
-+ XtNresize, XawtextResizeWidth, XtNresizable, True, XtNwrap, XawtextWrapNever,
-+ XtNscrollHorizontal, XawtextScrollNever, XtNscrollVertical, XawtextScrollNever,
-+ XtNheight, 20, XtNwidth, 400, XtNfromVert, text, XtNeditType, XawtextEdit,
-+ XtNdisplayCaret, True, XtNeditType, XawtextEdit, NULL);
-+
-+ dismiss = XtVaCreateManagedWidget("dismiss", commandWidgetClass, myform, XtNlabel, "Close Chat", XtNfromVert, entry, NULL);
-+
-+ AppendChatInput("");
-+
-+ XtAddCallback(dismiss, XtNcallback, dismiss_proc, NULL);
-+
-+ XtRealizeWidget(chat);
-+
-+ XtSetKeyboardFocus(chat, entry);
-+}
-+
-+Widget msgwin, msgtext;
-+
-+void AppendMsg(char *in) {
-+ XawTextPosition beg, end;
-+ static XawTextPosition pos = 0;
-+ XawTextBlock txt;
-+
-+ XawTextSetInsertionPoint(msgtext, pos);
-+ beg = XawTextGetInsertionPoint(msgtext);
-+ end = beg;
-+
-+ txt.firstPos = 0;
-+ txt.length = strlen(in);
-+ txt.ptr = in;
-+ txt.format = FMT8BIT;
-+
-+ XawTextReplace(msgtext, beg, end, &txt);
-+ XawTextSetInsertionPoint(msgtext, beg + txt.length);
-+
-+ pos = XawTextGetInsertionPoint(msgtext);
-+}
-+
-+static int msg_visible = 0;
-+static int msg_NO_clicked = 0;
-+
-+void msg_dismiss_proc(Widget w, XtPointer client_data, XtPointer call_data) {
-+ XtPopdown(msgwin);
-+ msg_visible = 0;
-+ XSync(dpy, False);
-+ usleep(200 * 1000);
-+ if (w || client_data || call_data) {}
-+}
-+
-+void msg_NO_proc(Widget w, XtPointer client_data, XtPointer call_data) {
-+ XtPopdown(msgwin);
-+ msg_visible = 0;
-+ msg_NO_clicked = 1;
-+ XSync(dpy, False);
-+ usleep(200 * 1000);
-+ if (w || client_data || call_data) {}
-+}
-+
-+int CreateMsg(char *msg, int wait) {
-+
-+ Widget myform, dismiss, reject;
-+ char *p;
-+ int n, run, wmax = 0;
-+ int ret = 1;
-+ Dimension w, h;
-+
-+
-+ n = 0;
-+ run = 0;
-+ p = msg;
-+ while (*p != '\0') {
-+ if (*p == '\n') {
-+ run = 0;
-+ n++;
-+ }
-+ run++;
-+ if (run > wmax) wmax = run;
-+ p++;
-+ }
-+ if (wmax > 80) {
-+ if (wmax > 120) n++;
-+ if (wmax > 80) n++;
-+ wmax = 80;
-+ }
-+ h = (Dimension) (n+2) * 14;
-+ w = (Dimension) (wmax+10) * 8;
-+
-+ msgwin = XtVaCreatePopupShell("Message", topLevelShellWidgetClass, toplevel, XtNmappedWhenManaged, False, NULL);
-+
-+ myform = XtVaCreateManagedWidget("myform", formWidgetClass, msgwin, NULL);
-+
-+ msgtext = XtVaCreateManagedWidget("msgtext", asciiTextWidgetClass, myform,
-+ XtNresize, XawtextResizeBoth, XtNresizable, True, XtNwrap, XawtextWrapWord,
-+ XtNscrollHorizontal, XawtextScrollNever, XtNscrollVertical, XawtextScrollAlways,
-+ XtNwidth, w, XtNheight, h, XtNdisplayCaret, False,
-+ XtNeditType, XawtextAppend, XtNtype, XawAsciiString,
-+ XtNuseStringInPlace, False, NULL);
-+
-+ if (wait == 2) {
-+ msg_NO_clicked = 0;
-+
-+ dismiss = XtVaCreateManagedWidget("dismiss", commandWidgetClass, myform, XtNlabel, "Accept", XtNfromVert, msgtext, NULL);
-+ XtAddCallback(dismiss, XtNcallback, msg_dismiss_proc, NULL);
-+
-+ reject = XtVaCreateManagedWidget("reject", commandWidgetClass, myform, XtNlabel, "Reject", XtNfromVert, dismiss, NULL);
-+ XtAddCallback(reject, XtNcallback, msg_NO_proc, NULL);
-+ } else {
-+ dismiss = XtVaCreateManagedWidget("dismiss", commandWidgetClass, myform, XtNlabel, "OK", XtNfromVert, msgtext, NULL);
-+ XtAddCallback(dismiss, XtNcallback, msg_dismiss_proc, NULL);
-+
-+ }
-+
-+ AppendMsg("");
-+ AppendMsg(msg);
-+
-+ XtRealizeWidget(msgwin);
-+
-+ XtPopup(msgwin, XtGrabNone);
-+
-+ XSync(dpy, False);
-+ msg_visible = 1;
-+ while (wait && msg_visible) {
-+ if (0) fprintf(stderr, "mv: %d\n", msg_visible);
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+ if (wait == 2) {
-+ if (msg_NO_clicked) {
-+ ret = 0;
-+ } else {
-+ ret = 1;
-+ }
-+ }
-+ return ret;
-+}
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup_ad vnc_unixsrc/vncviewer/popup_ad
---- vnc_unixsrc.orig/vncviewer/popup_ad 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/popup_ad 2008-02-17 13:32:34.000000000 -0500
-@@ -0,0 +1,20 @@
-+#!/usr/bin/perl
-+
-+$ok = 0;
-+
-+open(A, "<argsresources.c") || die;
-+
-+while (<A>) {
-+ if (/popupButtonCount:/) {
-+ $on = 1;
-+ } elsif (/^\s*NULL/) {
-+ $on = 0;
-+ }
-+ next unless $on;
-+ chomp;
-+ last if /NULL/;
-+ $_ =~ s/^\s*"//;
-+ $_ =~ s/",//;
-+ $_ .= "\n" unless $_ =~ /\n/;
-+ print;
-+}
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncviewer/rfbproto.c
---- vnc_unixsrc.orig/vncviewer/rfbproto.c 2008-09-05 19:51:24.000000000 -0400
-+++ vnc_unixsrc/vncviewer/rfbproto.c 2010-04-17 22:34:38.000000000 -0400
-@@ -23,7 +23,10 @@
- * rfbproto.c - functions to deal with client side of RFB protocol.
- */
-
-+#include <sys/stat.h>
- #include <unistd.h>
-+#include <time.h>
-+#include <ctype.h>
- #include <errno.h>
- #include <pwd.h>
- #include <vncviewer.h>
-@@ -31,6 +34,9 @@
- #include <zlib.h>
- #include <jpeglib.h>
-
-+int server_major = 0, server_minor = 0;
-+int viewer_major = 0, viewer_minor = 0;
-+
- static void InitCapabilities(void);
- static Bool SetupTunneling(void);
- static int ReadSecurityType(void);
-@@ -57,6 +63,47 @@
- static Bool HandleTight16(int rx, int ry, int rw, int rh);
- static Bool HandleTight32(int rx, int ry, int rw, int rh);
-
-+/* runge add zrle */
-+static Bool HandleZRLE8(int rx, int ry, int rw, int rh);
-+static Bool HandleZRLE15(int rx, int ry, int rw, int rh);
-+static Bool HandleZRLE16(int rx, int ry, int rw, int rh);
-+static Bool HandleZRLE24(int rx, int ry, int rw, int rh);
-+static Bool HandleZRLE24Up(int rx, int ry, int rw, int rh);
-+static Bool HandleZRLE24Down(int rx, int ry, int rw, int rh);
-+static Bool HandleZRLE32(int rx, int ry, int rw, int rh);
-+
-+extern Bool HandleCursorPos(int x, int y);
-+extern void printChat(char *, Bool);
-+
-+typedef struct {
-+ unsigned long length;
-+} rfbZRLEHeader;
-+
-+#define sz_rfbZRLEHeader 4
-+
-+#define rfbZRLETileWidth 64
-+#define rfbZRLETileHeight 64
-+
-+#define DO_ZYWRLE 1
-+
-+#if DO_ZYWRLE
-+
-+#ifndef ZRLE_ONCE
-+#define ZRLE_ONCE
-+
-+static const int bitsPerPackedPixel[] = {
-+ 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-+};
-+
-+int zywrle_level;
-+int zywrleBuf[rfbZRLETileWidth*rfbZRLETileHeight];
-+
-+#include "zrlepalettehelper.h"
-+static zrlePaletteHelper paletteHelper;
-+
-+#endif /* ZRLE_ONCE */
-+#endif /* DO_ZYWRLE */
-+
- static void ReadConnFailedReason(void);
- static long ReadCompactLen (void);
-
-@@ -67,6 +114,25 @@
- static void JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData,
- int compressedLen);
-
-+extern void deskey(unsigned char *, int);
-+extern void des(unsigned char *, unsigned char *);
-+
-+extern int currentMsg;
-+extern double scale_factor_x;
-+extern double scale_factor_y;
-+
-+extern int skip_maybe_sync;
-+
-+int sent_FBU = 0;
-+int skip_XtUpdate = 0;
-+int skip_XtUpdateAll = 0;
-+
-+static double dt_out = 0.0;
-+static double dt_out_sc = 0.0;
-+double latency = 0.0;
-+double connect_time = 0.0;
-+
-+void raiseme(int force);
-
- int rfbsock;
- char *desktopName;
-@@ -75,6 +141,14 @@
- char *serverCutText = NULL;
- Bool newServerCutText = False;
-
-+/* ultravnc mslogon */
-+#define rfbUltraVncMsLogon 0xfffffffa
-+static Bool AuthUltraVncMsLogon(void);
-+extern void UvncEncryptPasswd_MSLOGON(unsigned char *encryptedPasswd, char *passwd);
-+extern void UvncEncryptBytes2(unsigned char *where, int length, unsigned char *key);
-+extern void UvncDecryptBytes2(unsigned char *where, int length, unsigned char *key);
-+extern unsigned int urandom(void);
-+
- int endianTest = 1;
-
- static Bool tightVncProtocol = False;
-@@ -177,8 +251,26 @@
- sig_rfbEncodingPointerPos, "Pointer position update");
- CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor,
- sig_rfbEncodingLastRect, "LastRect protocol extension");
-+
-+ CapsAdd(encodingCaps, rfbEncodingNewFBSize, rfbTightVncVendor,
-+ sig_rfbEncodingNewFBSize, "New FB size protocol extension");
-+
-+#ifdef TURBOVNC
-+ CapsAdd(encodingCaps, rfbJpegQualityLevel1, rfbTurboVncVendor,
-+ sig_rfbEncodingNewFBSize, "TurboJPEG quality level");
-+ CapsAdd(encodingCaps, rfbJpegSubsamp1X, rfbTurboVncVendor,
-+ sig_rfbEncodingNewFBSize, "TurboJPEG subsampling level");
-+#endif
- }
-
-+static char msgbuf[10000];
-+
-+static void wmsg(char *msg, int wait) {
-+ fprintf(stderr, "%s", msg);
-+ if (!use_tty() && !getenv("SSVNC_NO_MESSAGE_POPUP")) {
-+ CreateMsg(msg, wait);
-+ }
-+}
-
- /*
- * ConnectToRFBServer.
-@@ -187,24 +279,179 @@
- Bool
- ConnectToRFBServer(const char *hostname, int port)
- {
-- unsigned int host;
--
-- if (!StringToIPAddr(hostname, &host)) {
-- fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname);
-- return False;
-- }
-+ char *q, *cmd = NULL;
-+ Bool setnb;
-+ struct stat sb;
-+
-+ if (strstr(hostname, "exec=") == hostname) {
-+ cmd = strdup(hostname);
-+ q = strchr(cmd, '=');
-+ *q = ' ';
-+ if (getenv("SSVNC_BASEDIR")) {
-+ char *base = getenv("SSVNC_BASEDIR");
-+ char *newcmd = (char *)malloc(strlen(base) + strlen(cmd) + 1000);
-+ sprintf(newcmd, "%s/unwrap.so", base);
-+ if (stat(newcmd, &sb) == 0) {
-+#if (defined(__MACH__) && defined(__APPLE__))
-+ sprintf(newcmd, "DYLD_FORCE_FLAT_NAMESPACE=1; export DYLD_FORCE_FLAT_NAMESPACE; DYLD_INSERT_LIBRARIES='%s/unwrap.so'; export DYLD_INSERT_LIBRARIES; %s", base, cmd);
-+#else
-+ sprintf(newcmd, "LD_PRELOAD='%s/unwrap.so'; export LD_PRELOAD; %s", base, cmd);
-+#endif
-+ cmd = newcmd;
-+ }
-+ }
-+ }
-
-- rfbsock = ConnectToTcpAddr(host, port);
-+ if (cmd != NULL) {
-+ int sfd[2];
-+ char *q, *cmd2 = strdup(cmd);
-+ pid_t pid;
-+
-+ q = strstr(cmd2, "pw=");
-+ if (q && !getenv("SSVNC_SHOW_ULTRAVNC_DSM_PASSWORD")) {
-+ q += strlen("pw=");
-+ while (*q != '\0' && !isspace(*q)) {
-+ *q = '*';
-+ q++;
-+ }
-+ }
-+
-+ fprintf(stderr, "exec-cmd: %s\n\n", cmd2);
-+ free(cmd2);
-+
-+ if (! SocketPair(sfd)) {
-+ return False;
-+ }
-+ if (0) {
-+ fprintf(stderr, "sfd: %d %d\n", sfd[0], sfd[1]);
-+ fflush(stderr);
-+ }
-+
-+ pid = fork();
-+ if (pid == -1) {
-+ perror("fork");
-+ return False;
-+ }
-+ if (pid == 0) {
-+ char *args[4];
-+ int d;
-+ args[0] = "/bin/sh";
-+ args[1] = "-c";
-+ args[2] = cmd;
-+ args[3] = NULL;
-+
-+ close(sfd[1]);
-+ dup2(sfd[0], 0);
-+ dup2(sfd[0], 1);
-+ for (d=3; d < 256; d++) {
-+ if (d != sfd[0]) {
-+ close(d);
-+ }
-+ }
-+ execvp(args[0], args);
-+ perror("exec");
-+ exit(1);
-+ } else {
-+ close(sfd[0]);
-+ rfbsock = sfd[1];
-+ }
-+ if (rfbsock < 0) {
-+ sprintf(msgbuf,"Unable to connect to exec'd command: %s\n", cmd);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+ } else if (strstr(hostname, "fd=") == hostname) {
-+ rfbsock = atoi(hostname + strlen("fd="));
-+ } else if (strchr(hostname, '/') && stat(hostname, &sb) == 0) {
-+ /* assume unix domain socket */
-+ char *thost = strdup(hostname);
-+
-+ rfbsock = ConnectToUnixSocket(thost);
-+ free(thost);
-+
-+ if (rfbsock < 0) {
-+ sprintf(msgbuf,"Unable to connect to VNC server (unix-domain socket: %s)\n", hostname);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+
-+ } else {
-+ rfbsock = ConnectToTcpAddr(hostname, port);
-+
-+ if (rfbsock < 0 && !appData.noipv4) {
-+ char *q, *hosttmp;
-+ if (hostname[0] == '[') {
-+ hosttmp = strdup(hostname+1);
-+ } else {
-+ hosttmp = strdup(hostname);
-+ }
-+ q = strrchr(hosttmp, ']');
-+ if (q) *q = '\0';
-+ if (strstr(hosttmp, "::ffff:") == hosttmp || strstr(hosttmp, "::FFFF:") == hosttmp) {
-+ char *host = hosttmp + strlen("::ffff:");
-+ if (dotted_ip(host, 0)) {
-+ fprintf(stderr, "ConnectToTcpAddr[ipv4]: re-trying connection using '%s'\n", host);
-+ rfbsock = ConnectToTcpAddr(host, port);
-+ }
-+ }
-+ free(hosttmp);
-+ }
-+
-+ if (rfbsock < 0) {
-+ sprintf(msgbuf,"Unable to connect to VNC server (%s:%d)\n", hostname, port);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+ }
-
-- if (rfbsock < 0) {
-- fprintf(stderr,"Unable to connect to VNC server\n");
-- return False;
-- }
-+ setnb = SetNonBlocking(rfbsock);
-+ return setnb;
-+}
-
-- return SetNonBlocking(rfbsock);
-+static void printFailureReason(void) {
-+ CARD32 reasonLen;
-+ ReadFromRFBServer((char *)&reasonLen, 4);
-+ reasonLen = Swap32IfLE(reasonLen);
-+ if (reasonLen < 4096) {
-+ char *reason = (char *) malloc(reasonLen+1);
-+ memset(reason, 0, reasonLen+1);
-+ ReadFromRFBServer(reason, reasonLen);
-+ sprintf(msgbuf, "Reason: %s\n", reason);
-+ wmsg(msgbuf, 1);
-+ free(reason);
-+ }
- }
-
-+static char *pr_sec_type(int type) {
-+ char *str = "unknown";
-+ if (type == rfbSecTypeInvalid) str = "rfbSecTypeInvalid";
-+ if (type == rfbSecTypeNone) str = "rfbSecTypeNone";
-+ if (type == rfbSecTypeVncAuth) str = "rfbSecTypeVncAuth";
-+ if (type == rfbSecTypeRA2) str = "rfbSecTypeRA2";
-+ if (type == rfbSecTypeRA2ne) str = "rfbSecTypeRA2ne";
-+ if (type == rfbSecTypeTight) str = "rfbSecTypeTight";
-+ if (type == rfbSecTypeUltra) str = "rfbSecTypeUltra";
-+
-+ if (type == rfbSecTypeAnonTls) str = "rfbSecTypeAnonTls";
-+ if (type == rfbSecTypeVencrypt) str = "rfbSecTypeVencrypt";
-+
-+ if (type == (int) rfbUltraVncMsLogon) str = "rfbUltraVncMsLogon";
-+ return str;
-+}
-+
-+static char *pr_sec_subtype(int type) {
-+ char *str = "unknown";
-+ if (type == rfbVencryptPlain) str = "rfbVencryptPlain";
-+ if (type == rfbVencryptTlsNone) str = "rfbVencryptTlsNone";
-+ if (type == rfbVencryptTlsVnc) str = "rfbVencryptTlsVnc";
-+ if (type == rfbVencryptTlsPlain) str = "rfbVencryptTlsPlain";
-+ if (type == rfbVencryptX509None) str = "rfbVencryptX509None";
-+ if (type == rfbVencryptX509Vnc) str = "rfbVencryptX509Vnc";
-+ if (type == rfbVencryptX509Plain) str = "rfbVencryptX509Plain";
-+ return str;
-+}
-
-+extern void ProcessXtEvents(void);
- /*
- * InitialiseRFBConnection.
- */
-@@ -212,211 +459,654 @@
- Bool
- InitialiseRFBConnection(void)
- {
-- rfbProtocolVersionMsg pv;
-- int server_major, server_minor;
-- int viewer_major, viewer_minor;
-- rfbClientInitMsg ci;
-- int secType;
-+ rfbProtocolVersionMsg pv;
-+ rfbClientInitMsg ci;
-+ int i, secType, anon_dh = 0, accept_uvnc = 0;
-+ FILE *pd;
-+ char *hsfile = NULL;
-+ char *hsparam[128];
-+ char *envsetsec = getenv("SSVNC_SET_SECURITY_TYPE");
-+ char line[128];
-+ double dt = 0.0;
-
-- /* if the connection is immediately closed, don't report anything, so
-- that pmw's monitor can make test connections */
-+ /* if the connection is immediately closed, don't report anything, so
-+ that pmw's monitor can make test connections */
-
-- if (listenSpecified)
-- errorMessageOnReadFailure = False;
-+ if (listenSpecified) {
-+ errorMessageOnReadFailure = False;
-+ }
-
-- if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg))
-- return False;
-+ for (i=0; i < 128; i++) {
-+ hsparam[i] = NULL;
-+ }
-
-- errorMessageOnReadFailure = True;
-+ skip_XtUpdateAll = 1;
-+ ProcessXtEvents();
-+ skip_XtUpdateAll = 0;
-+
-+ if (getenv("SSVNC_PREDIGESTED_HANDSHAKE")) {
-+ double start = dnow();
-+ hsfile = getenv("SSVNC_PREDIGESTED_HANDSHAKE");
-+ while (dnow() < start + 10.0) {
-+ int done = 0;
-+ usleep(100 * 1000);
-+ if ((pd = fopen(hsfile, "r")) != NULL) {
-+ while (fgets(line, 128, pd) != NULL) {
-+ if (strstr(line, "done") == line) {
-+ done = 1;
-+ usleep(100 * 1000);
-+ break;
-+ }
-+ }
-+ fclose(pd);
-+ }
-+ if (done) {
-+ break;
-+ }
-+ }
-+ if ((pd = fopen(hsfile, "r")) != NULL) {
-+ i = 0;
-+ while (fgets(line, 128, pd) != NULL) {
-+ hsparam[i] = strdup(line);
-+ fprintf(stderr, "%s", line);
-+ if (i++ > 100) break;
-+ }
-+ fclose(pd);
-+ }
-+ unlink(hsfile);
-+ }
-
-- pv[sz_rfbProtocolVersionMsg] = 0;
-+ if (getenv("SSVNC_SKIP_RFB_PROTOCOL_VERSION")) {
-+ viewer_major = 3;
-+ viewer_minor = 8;
-+ goto end_of_proto_msg;
-+ } else if (hsfile) {
-+ int k = 0;
-+ while (hsparam[k] != NULL) {
-+ char *str = hsparam[k++];
-+ if (strstr(str, "server=") == str) {
-+ sprintf(pv, "%s", str + strlen("server="));
-+ goto readed_pv;
-+ }
-+ }
-+ }
-
-- if (sscanf(pv, rfbProtocolVersionFormat,
-- &server_major, &server_minor) != 2) {
-- fprintf(stderr,"Not a valid VNC server\n");
-- return False;
-- }
-+ dt = dnow();
-+ if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg)) {
-+ return False;
-+ }
-+ if (getenv("PRINT_DELAY1")) fprintf(stderr, "delay1: %.3f ms\n", (dnow() - dt) * 1000);
-+ dt = 0.0;
-
-- viewer_major = rfbProtocolMajorVersion;
-- if (server_major == 3 && server_minor >= rfbProtocolMinorVersion) {
-- /* the server supports at least the standard protocol 3.7 */
-- viewer_minor = rfbProtocolMinorVersion;
-- } else {
-- /* any other server version, request the standard 3.3 */
-- viewer_minor = rfbProtocolFallbackMinorVersion;
-- }
-+ readed_pv:
-
-- fprintf(stderr, "Connected to RFB server, using protocol version %d.%d\n",
-- viewer_major, viewer_minor);
-+ errorMessageOnReadFailure = True;
-
-- sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor);
-+ pv[sz_rfbProtocolVersionMsg] = 0;
-
-- if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg))
-- return False;
-+ if (strstr(pv, "ID:") == pv) {
-+ ;
-+ } else if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) != 2) {
-+ if (strstr(pv, "test") == pv) {
-+ /* now some hacks for ultraVNC SC III (SSL) ... testA, etc */
-+ int i;
-+ char *se = NULL;
-+
-+ fprintf(stderr,"Trying UltraVNC Single Click III workaround: %s\n", pv);
-+ for (i=0; i < 7 ; i++) {
-+ pv[i] = pv[i+5];
-+ }
-+ if (!ReadFromRFBServer(pv+7, 5)) {
-+ return False;
-+ }
-+
-+ se = getenv("STUNNEL_EXTRA_OPTS");
-+ if (se == NULL) {
-+ se = getenv("STUNNEL_EXTRA_OPTS_USER");
-+ }
-+ if (se != NULL) {
-+ if (strstr(se, "options")) {
-+ if (strstr(se, "ALL") || strstr(se, "DONT_INSERT_EMPTY_FRAGMENTS")) {
-+ ; /* good */
-+ } else {
-+ se = NULL;
-+ }
-+ } else {
-+ se = NULL;
-+ }
-+ }
-+ if (se == NULL) {
-+ msgbuf[0] = '\0';
-+ strcat(msgbuf, "\n");
-+ strcat(msgbuf, "***************************************************************\n");
-+ strcat(msgbuf, "To work around UltraVNC SC III SSL dropping after a few minutes\n");
-+ strcat(msgbuf, "you may need to set STUNNEL_EXTRA_OPTS_USER='options = ALL'.\n");
-+ strcat(msgbuf, "***************************************************************\n");
-+ strcat(msgbuf, "\n");
-+ wmsg(msgbuf, 0);
-+ }
-+ if (strstr(pv, "ID:") == pv) {
-+ goto check_ID_string;
-+ }
-+ if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) == 2) {
-+ goto ultra_vnc_nonsense;
-+ }
-+ }
-+ sprintf(msgbuf, "Not a valid VNC server: '%s'\n", pv);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-
-- /* Read or select the security type. */
-- if (viewer_minor == rfbProtocolMinorVersion) {
-- secType = SelectSecurityType();
-- } else {
-- secType = ReadSecurityType();
-- }
-- if (secType == rfbSecTypeInvalid)
-- return False;
-+ check_ID_string:
-+ if (strstr(pv, "ID:") == pv) {
-+ char tmp[256];
-+ fprintf(stderr, "UltraVNC Repeater string detected: %s\n", pv);
-+ fprintf(stderr, "Pretending to be UltraVNC repeater: reading 250 bytes...\n\n");
-+ if (!ReadFromRFBServer(tmp, 250 - 12)) {
-+ return False;
-+ }
-+ if (!ReadFromRFBServer(pv, 12)) {
-+ return False;
-+ }
-+ if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) != 2) {
-+ sprintf(msgbuf,"Not a valid VNC server: '%s'\n", pv);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+ }
-
-- switch (secType) {
-- case rfbSecTypeNone:
-- fprintf(stderr, "No authentication needed\n");
-- break;
-- case rfbSecTypeVncAuth:
-- if (!AuthenticateVNC())
-- return False;
-- break;
-- case rfbSecTypeTight:
-- tightVncProtocol = True;
-- InitCapabilities();
-- if (!SetupTunneling())
-- return False;
-- if (!PerformAuthenticationTight())
-- return False;
-- break;
-- default: /* should never happen */
-- fprintf(stderr, "Internal error: Invalid security type\n");
-- return False;
-- }
-+ ultra_vnc_nonsense:
-+ fprintf(stderr,"\nProto: %s\n", pv);
-
-- ci.shared = (appData.shareDesktop ? 1 : 0);
-+ viewer_major = 3;
-
-- if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg))
-- return False;
-+ if (appData.rfbVersion != NULL && sscanf(appData.rfbVersion, "%d.%d", &viewer_major, &viewer_minor) == 2) {
-+ fprintf(stderr,"Setting RFB version to %d.%d from -rfbversion.\n\n", viewer_major, viewer_minor);
-
-- if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg))
-- return False;
-+ } else if (getenv("SSVNC_RFB_VERSION") != NULL && sscanf(getenv("SSVNC_RFB_VERSION"), "%d.%d", &viewer_major, &viewer_minor) == 2) {
-+ fprintf(stderr,"Setting RFB version to %d.%d from SSVNC_RFB_VERSION.\n\n", viewer_major, viewer_minor);
-+
-+ } else if (server_major > 3) {
-+ viewer_minor = 8;
-+ } else if (server_major == 3 && (server_minor == 14 || server_minor == 16)) {
-+ /* hack for UltraVNC Single Click. They misuse rfb proto version */
-+ fprintf(stderr,"Setting RFB version to 3.3 for UltraVNC Single Click.\n\n");
-+ viewer_minor = 3;
-+
-+ } else if (server_major == 3 && server_minor >= 8) {
-+ /* the server supports at least the standard protocol 3.8 */
-+ viewer_minor = 8;
-+
-+ } else if (server_major == 3 && server_minor == 7) {
-+ /* the server supports at least the standard protocol 3.7 */
-+ viewer_minor = 7;
-+
-+ } else {
-+ /* any other server version, request the standard 3.3 */
-+ viewer_minor = 3;
-+ }
-+ /* n.b. Apple Remote Desktop uses 003.889, but we should be OK with 3.8 */
-
-- si.framebufferWidth = Swap16IfLE(si.framebufferWidth);
-- si.framebufferHeight = Swap16IfLE(si.framebufferHeight);
-- si.format.redMax = Swap16IfLE(si.format.redMax);
-- si.format.greenMax = Swap16IfLE(si.format.greenMax);
-- si.format.blueMax = Swap16IfLE(si.format.blueMax);
-- si.nameLength = Swap32IfLE(si.nameLength);
--
-- /* FIXME: Check arguments to malloc() calls. */
-- desktopName = malloc(si.nameLength + 1);
-- if (!desktopName) {
-- fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n",
-- (unsigned long)si.nameLength);
-- return False;
-- }
-+ if (appData.msLogon) {
-+ if (server_minor == 4) {
-+ fprintf(stderr,"Setting RFB version to 3.4 for UltraVNC MS Logon.\n\n");
-+ viewer_minor = 4;
-+ }
-+ }
-+ if (getenv("SSVNC_ACCEPT_POPUP_SC")) {
-+ if (server_minor == -4 || server_minor == -6 || server_minor == 14 || server_minor == 16) {
-+ /* 4 and 6 work too? */
-+ viewer_minor = server_minor;
-+ accept_uvnc = 1;
-+ fprintf(stderr,"Reset RFB version to 3.%d for UltraVNC SSVNC_ACCEPT_POPUP_SC.\n\n", viewer_minor);
-+ }
-+ }
-
-- if (!ReadFromRFBServer(desktopName, si.nameLength)) return False;
-+ fprintf(stderr, "Connected to RFB server, using protocol version %d.%d\n", viewer_major, viewer_minor);
-
-- desktopName[si.nameLength] = 0;
-+ if (hsfile) {
-+ int k = 0;
-+ while (hsparam[k] != NULL) {
-+ char *str = hsparam[k++];
-+ if (strstr(str, "latency=") == str) {
-+ latency = 1000. * atof(str + strlen("latency="));
-+ }
-+ }
-+ k = 0;
-+ while (hsparam[k] != NULL) {
-+ char *str = hsparam[k++];
-+ int v1, v2;
-+ if (sscanf(str, "viewer=RFB %d.%d\n", &v1, &v2) == 2) {
-+ viewer_major = v1;
-+ viewer_minor = v2;
-+ fprintf(stderr, "\nPre-Handshake set protocol version to: %d.%d Latency: %.2f ms\n", viewer_major, viewer_minor, latency);
-+ goto end_of_proto_msg;
-+ }
-+ }
-+ }
-+ sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor);
-
-- fprintf(stderr,"Desktop name \"%s\"\n",desktopName);
-+ if (!appData.appShare) {
-+ usleep(100*1000);
-+ }
-+ dt = dnow();
-+ if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) {
-+ return False;
-+ }
-
-- fprintf(stderr,"VNC server default format:\n");
-- PrintPixelFormat(&si.format);
-+ end_of_proto_msg:
-
-- if (tightVncProtocol) {
-- /* Read interaction capabilities (protocol 3.7t) */
-- if (!ReadInteractionCaps())
-- return False;
-- }
-+ if (envsetsec) {
-+ secType = atoi(getenv("SSVNC_SET_SECURITY_TYPE"));
-+ goto sec_type;
-+ }
-+ if (hsfile) {
-+ int k = 0;
-+ while (hsparam[k] != NULL) {
-+ char *str = hsparam[k++];
-+ int st;
-+ if (sscanf(str, "sectype=%d\n", &st) == 1) {
-+ secType = st;
-+ fprintf(stderr, "Pre-Handshake set Security-Type to: %d (%s)\n", st, pr_sec_type(st));
-+ if (secType == rfbSecTypeVencrypt) {
-+ goto sec_type;
-+ } else if (secType == rfbSecTypeAnonTls) {
-+ break;
-+ }
-+ }
-+ }
-+ }
-
-- return True;
-+ if (accept_uvnc) {
-+ unsigned int msg_sz = 0;
-+ unsigned int nimmer = 0;
-+ char msg[3000];
-+ char *msg_buf, *sip = NULL, *sih = NULL;
-+
-+ if (!ReadFromRFBServer((char *) &msg_sz, 4)) {
-+ return False;
-+ }
-+ dt_out_sc = dnow();
-+ msg_sz = Swap32IfBE(msg_sz);
-+ if (msg_sz > 1024) {
-+ fprintf(stderr, "UVNC msg size too big: %d\n", msg_sz);
-+ exit(1);
-+ }
-+ msg_buf = (char *)calloc(msg_sz + 100, 1);
-+ if (!ReadFromRFBServer(msg_buf, msg_sz)) {
-+ return False;
-+ }
-+
-+ if (0) {
-+ fprintf(stderr, "msg_buf: ");
-+ write(2, msg_buf, msg_sz);
-+ fprintf(stderr, "\n");
-+ }
-+
-+ sip = get_peer_ip(rfbsock);
-+ if (strlen(sip) > 100) sip = "0.0.0.0";
-+ sih = ip2host(sip);
-+ if (strlen(sih) > 300) sih = "unknown";
-+
-+ sprintf(msg, "\n(LISTEN) Reverse VNC connection from IP: %s\n Hostname: %s\n\n", sip, sih);
-+ strcat(msg, "UltraVNC Server Message:\n");
-+ strcat(msg, msg_buf);
-+ free(msg_buf);
-+ strcat(msg, "\n\n");
-+ strcat(msg, "Accept or Reject VNC connection?");
-+ if (CreateMsg(msg, 2)) {
-+ nimmer = 1;
-+ fprintf(stderr, "Accepting connection.\n\n");
-+ } else {
-+ nimmer = 0;
-+ fprintf(stderr, "Refusing connection.\n\n");
-+ }
-+ if (!WriteExact(rfbsock, (char *) &nimmer, 4)) {
-+ return False;
-+ }
-+ }
-+
-+ /* Read or select the security type. */
-+ dt_out = 0.0;
-+
-+ skip_XtUpdateAll = 1;
-+ if (viewer_minor >= 7 && !accept_uvnc) {
-+ secType = SelectSecurityType();
-+ } else {
-+ secType = ReadSecurityType();
-+ }
-+ skip_XtUpdateAll = 0;
-+
-+ if (accept_uvnc) {
-+ dt_out = dt_out_sc;
-+ }
-+
-+ if (dt > 0.0 && dt_out > dt) {
-+ latency = (dt_out - dt) * 1000;
-+ }
-+
-+ fprintf(stderr, "Security-Type: %d (%s) Latency: %.2f ms\n", (int) secType, pr_sec_type(secType), latency);
-+ if (secType == rfbSecTypeInvalid) {
-+ return False;
-+ }
-+
-+ sec_type:
-+
-+ if (hsfile) {
-+ int subsectype = 0;
-+ int k = 0;
-+ while (hsparam[k] != NULL) {
-+ char *str = hsparam[k++];
-+ int st;
-+ if (sscanf(str, "subtype=%d\n", &st) == 1) {
-+ subsectype = st;
-+ fprintf(stderr, "Pre-Handshake set Sub-Security-Type to: %d (%s)\n\n", st, pr_sec_subtype(st));
-+ break;
-+ }
-+ }
-+
-+ if (!subsectype) {
-+ ;
-+ } else if (secType == rfbSecTypeVencrypt) {
-+ if (subsectype == rfbVencryptTlsNone) {
-+ anon_dh = 1;
-+ secType = rfbSecTypeNone;
-+ } else if (subsectype == rfbVencryptTlsVnc) {
-+ anon_dh = 1;
-+ secType = rfbSecTypeVncAuth;
-+ } else if (subsectype == rfbVencryptTlsPlain) {
-+ anon_dh = 1;
-+ secType = rfbSecTypeNone;
-+ } else if (subsectype == rfbVencryptX509None) {
-+ secType = rfbSecTypeNone;
-+ } else if (subsectype == rfbVencryptX509Vnc) {
-+ secType = rfbSecTypeVncAuth;
-+ } else if (subsectype == rfbVencryptX509Plain) {
-+ secType = rfbSecTypeNone;
-+ }
-+ if (subsectype == rfbVencryptTlsPlain || subsectype == rfbVencryptX509Plain) {
-+ usleep(300*1000);
-+ }
-+ if (subsectype == rfbVencryptTlsNone || subsectype == rfbVencryptTlsVnc || subsectype == rfbVencryptTlsPlain) {
-+ char tmp[1000], line[100];
-+ tmp[0] = '\0';
-+ strcat(tmp, "\n");
-+ sprintf(line, "WARNING: Anonymous Diffie-Hellman TLS used (%s),\n", pr_sec_subtype(subsectype));
-+ strcat(tmp, line);
-+ strcat(tmp, "WARNING: there will be *NO* Authentication of the VNC Server.\n");
-+ strcat(tmp, "WARNING: I.e. a Man-In-The-Middle attack is possible.\n");
-+ strcat(tmp, "WARNING: Configure the server to use X509 certs and verify them.\n\n");
-+ wmsg(tmp, 1);
-+ }
-+ if (subsectype == rfbVencryptTlsPlain || subsectype == rfbVencryptX509Plain) {
-+ fprintf(stderr, "\nVeNCrypt Plain (username + passwd) selected.\n\n");
-+ if (appData.unixPW != NULL) {
-+ unixpw(appData.unixPW, 1);
-+ } else if (getenv("SSVNC_UNIXPW")) {
-+ unixpw(getenv("SSVNC_UNIXPW"), 1);
-+ } else {
-+ unixpw(".", 1);
-+ }
-+ }
-+ }
-+ }
-+
-+ switch (secType) {
-+ case rfbSecTypeNone:
-+ fprintf(stderr, "No VNC authentication needed\n");
-+ if (viewer_minor >= 8) {
-+ CARD32 authResult;
-+
-+ if (!ReadFromRFBServer((char *)&authResult, 4)) {
-+ return False;
-+ }
-+
-+ authResult = Swap32IfLE(authResult);
-+
-+ if (authResult == rfbVncAuthOK) {
-+ fprintf(stderr, "VNC authentication succeeded (%d) for rfbSecTypeNone (RFB 3.8)\n", (int) authResult);
-+ } else {
-+ sprintf(msgbuf, "VNC authentication failed (%d) for rfbSecTypeNone (RFB 3.8)\n\n", (int) authResult);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+ }
-+ fprintf(stderr, "\n");
-+ break;
-+ case rfbSecTypeVncAuth:
-+ if (!AuthenticateVNC()) {
-+ return False;
-+ }
-+ break;
-+ case rfbSecTypeTight:
-+ tightVncProtocol = True;
-+ InitCapabilities();
-+ if (!SetupTunneling()) {
-+ return False;
-+ }
-+ if (!PerformAuthenticationTight()) {
-+ return False;
-+ }
-+ break;
-+ case rfbUltraVncMsLogon:
-+ if (!AuthUltraVncMsLogon()) {
-+ return False;
-+ }
-+ break;
-+ default: /* should never happen */
-+ sprintf(msgbuf, "Internal error: Invalid security type: %d\n", secType);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+
-+ connect_time = dnow();
-+
-+ ci.shared = (appData.shareDesktop ? 1 : 0);
-+
-+ if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) {
-+ return False;
-+ }
-+
-+ if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) {
-+ return False;
-+ }
-+
-+ si.framebufferWidth = Swap16IfLE(si.framebufferWidth);
-+ si.framebufferHeight = Swap16IfLE(si.framebufferHeight);
-+ si.format.redMax = Swap16IfLE(si.format.redMax);
-+ si.format.greenMax = Swap16IfLE(si.format.greenMax);
-+ si.format.blueMax = Swap16IfLE(si.format.blueMax);
-+ si.nameLength = Swap32IfLE(si.nameLength);
-+
-+ if (appData.chatOnly) {
-+ si.framebufferWidth = 32;
-+ si.framebufferHeight = 32;
-+ }
-+
-+ /* FIXME: Check arguments to malloc() calls. */
-+ desktopName = malloc(si.nameLength + 1);
-+ memset(desktopName, 0, si.nameLength + 1);
-+ if (!desktopName) {
-+ fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n",
-+ (unsigned long)si.nameLength);
-+ return False;
-+ }
-+
-+ if (!ReadFromRFBServer(desktopName, si.nameLength)) {
-+ return False;
-+ }
-+
-+ desktopName[si.nameLength] = 0;
-+
-+ if (appData.appShare) {
-+ int x_hint, y_hint;
-+ char *p, *q = NULL;
-+ p = desktopName;
-+ while (*p != '\0') {
-+ char *t = strstr(p, " XY=");
-+ if (t) q = t;
-+ p++;
-+ }
-+ if (q) {
-+ int ok = 1;
-+ p = q + strlen(" XY=");
-+ while (*p != '\0') {
-+ if (!strpbrk(p, "0123456789,+-")) {
-+ ok = 0;
-+ }
-+ p++;
-+ }
-+ if (ok && sscanf(q+1, "XY=%d,%d", &x_hint, &y_hint) == 2) {
-+ fprintf(stderr,"Using x11vnc appshare position: %s\n\n", q);
-+ *q = '\0';
-+ appshare_x_hint = x_hint;
-+ appshare_y_hint = y_hint;
-+ }
-+ }
-+ }
-+
-+ fprintf(stderr,"Desktop name \"%s\"\n\n", desktopName);
-+
-+ fprintf(stderr,"VNC server default format:\n");
-+ PrintPixelFormat(&si.format);
-+
-+ if (tightVncProtocol) {
-+ /* Read interaction capabilities (protocol 3.7t) */
-+ if (!ReadInteractionCaps()) {
-+ return False;
-+ }
-+ }
-+
-+ return True;
- }
-
-
- /*
-- * Read security type from the server (protocol version 3.3)
-+ * Read security type from the server (protocol 3.3)
- */
-
- static int
- ReadSecurityType(void)
- {
-- CARD32 secType;
-+ CARD32 secType;
-
-- /* Read the security type */
-- if (!ReadFromRFBServer((char *)&secType, sizeof(secType)))
-- return rfbSecTypeInvalid;
-+ /* Read the security type */
-+ if (!ReadFromRFBServer((char *)&secType, sizeof(secType))) {
-+ return rfbSecTypeInvalid;
-+ }
-+ dt_out = dnow();
-
-- secType = Swap32IfLE(secType);
-+ secType = Swap32IfLE(secType);
-
-- if (secType == rfbSecTypeInvalid) {
-- ReadConnFailedReason();
-- return rfbSecTypeInvalid;
-- }
-+ if (secType == rfbSecTypeInvalid) {
-+ ReadConnFailedReason();
-+ return rfbSecTypeInvalid;
-+ }
-
-- if (secType != rfbSecTypeNone && secType != rfbSecTypeVncAuth) {
-- fprintf(stderr, "Unknown security type from RFB server: %d\n",
-- (int)secType);
-- return rfbSecTypeInvalid;
-- }
-+ if (secType == rfbSecTypeNone) {
-+ ; /* OK */
-+ } else if (secType == rfbSecTypeVncAuth) {
-+ ; /* OK */
-+ } else if (secType == rfbUltraVncMsLogon) {
-+ ; /* OK */
-+ } else {
-+ sprintf(msgbuf, "Unknown security type from RFB server: %d\n", (int)secType);
-+ wmsg(msgbuf, 1);
-+ return rfbSecTypeInvalid;
-+ }
-
-- return (int)secType;
-+ return (int)secType;
- }
-
-
- /*
-- * Select security type from the server's list (protocol version 3.7)
-+ * Select security type from the server's list (protocol 3.7)
- */
-
- static int
- SelectSecurityType(void)
- {
-- CARD8 nSecTypes;
-- char *secTypeNames[] = {"None", "VncAuth"};
-- CARD8 knownSecTypes[] = {rfbSecTypeNone, rfbSecTypeVncAuth};
-- int nKnownSecTypes = sizeof(knownSecTypes);
-- CARD8 *secTypes;
-- CARD8 secType = rfbSecTypeInvalid;
-- int i, j;
--
-- /* Read the list of secutiry types. */
-- if (!ReadFromRFBServer((char *)&nSecTypes, sizeof(nSecTypes)))
-- return rfbSecTypeInvalid;
--
-- if (nSecTypes == 0) {
-- ReadConnFailedReason();
-- return rfbSecTypeInvalid;
-- }
-+ CARD8 nSecTypes;
-+ char *secTypeNames[] = {"None", "VncAuth"};
-+ CARD8 knownSecTypes[] = {rfbSecTypeNone, rfbSecTypeVncAuth};
-+ int nKnownSecTypes = sizeof(knownSecTypes);
-+ CARD8 *secTypes;
-+ CARD8 secType = rfbSecTypeInvalid;
-+ int i, j;
-+
-+ if (secTypeNames) {}
-+
-+ /* Read the list of security types. */
-+ if (!ReadFromRFBServer((char *)&nSecTypes, sizeof(nSecTypes))) {
-+ return rfbSecTypeInvalid;
-+ }
-+ dt_out = dnow();
-
-- secTypes = malloc(nSecTypes);
-- if (!ReadFromRFBServer((char *)secTypes, nSecTypes))
-- return rfbSecTypeInvalid;
--
-- /* Find out if the server supports TightVNC protocol extensions */
-- for (j = 0; j < (int)nSecTypes; j++) {
-- if (secTypes[j] == rfbSecTypeTight) {
-- free(secTypes);
-- secType = rfbSecTypeTight;
-- if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType)))
-- return rfbSecTypeInvalid;
-- fprintf(stderr, "Enabling TightVNC protocol extensions\n");
-- return rfbSecTypeTight;
-- }
-- }
-+ if (nSecTypes == 0) {
-+ ReadConnFailedReason();
-+ return rfbSecTypeInvalid;
-+ }
-
-- /* Find first supported security type */
-- for (j = 0; j < (int)nSecTypes; j++) {
-- for (i = 0; i < nKnownSecTypes; i++) {
-- if (secTypes[j] == knownSecTypes[i]) {
-- secType = secTypes[j];
-- if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) {
-- free(secTypes);
-- return rfbSecTypeInvalid;
-- }
-- break;
-- }
-- }
-- if (secType != rfbSecTypeInvalid) break;
-- }
-+ secTypes = malloc(nSecTypes);
-+ if (!ReadFromRFBServer((char *)secTypes, nSecTypes)) {
-+ return rfbSecTypeInvalid;
-+ }
-+
-+ if (getenv("SSVNC_DEBUG_SEC_TYPES")) {
-+ for (j = 0; j < (int)nSecTypes; j++) {
-+ fprintf(stderr, "sec-type[%d] %d\n", j, (int) secTypes[j]);
-+ }
-+ }
-+
-+ /* Find out if the server supports TightVNC protocol extensions */
-+ for (j = 0; j < (int)nSecTypes; j++) {
-+ if (getenv("VNCVIEWER_NO_SEC_TYPE_TIGHT")) {
-+ break;
-+ }
-+ if (getenv("SSVNC_NO_SEC_TYPE_TIGHT")) {
-+ break;
-+ }
-+#ifdef TURBOVNC
-+ break;
-+#endif
-+ if (secTypes[j] == rfbSecTypeTight) {
-+ free(secTypes);
-+ secType = rfbSecTypeTight;
-+ if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) {
-+ return rfbSecTypeInvalid;
-+ }
-+ fprintf(stderr, "Enabling TightVNC protocol extensions\n");
-+ return rfbSecTypeTight;
-+ }
-+ }
-+
-+ /* Find first supported security type */
-+ for (j = 0; j < (int)nSecTypes; j++) {
-+ for (i = 0; i < nKnownSecTypes; i++) {
-+ if (secTypes[j] == knownSecTypes[i]) {
-+ secType = secTypes[j];
-+ if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) {
-+ free(secTypes);
-+ return rfbSecTypeInvalid;
-+ }
-+ break;
-+ }
-+ }
-+ if (secType != rfbSecTypeInvalid) {
-+ break;
-+ }
-+ }
-
-- free(secTypes);
-+ if (secType == rfbSecTypeInvalid) {
-+ fprintf(stderr, "Server did not offer supported security type:\n");
-+ for (j = 0; j < (int)nSecTypes; j++) {
-+ fprintf(stderr, " sectype[%d] %d\n", j, (int) secTypes[j]);
-+ }
-+ }
-
-- if (secType == rfbSecTypeInvalid)
-- fprintf(stderr, "Server did not offer supported security type\n");
-+ free(secTypes);
-
-- return (int)secType;
-+ return (int)secType;
- }
-
-
-@@ -451,6 +1141,9 @@
- return True;
- }
-
-+static char *restart_session_pw = NULL;
-+static int restart_session_len = 0;
-+
-
- /*
- * Negotiate authentication scheme (protocol version 3.7t)
-@@ -459,58 +1152,406 @@
- static Bool
- PerformAuthenticationTight(void)
- {
-- rfbAuthenticationCapsMsg caps;
-- CARD32 authScheme;
-- int i;
-+ rfbAuthenticationCapsMsg caps;
-+ CARD32 authScheme;
-+ int i;
-
-- /* In the protocol version 3.7t, the server informs us about supported
-- authentication schemes. Here we read this information. */
-+ /* In the protocol version 3.7t, the server informs us about supported
-+ authentication schemes. Here we read this information. */
-
-- if (!ReadFromRFBServer((char *)&caps, sz_rfbAuthenticationCapsMsg))
-- return False;
-+ if (!ReadFromRFBServer((char *)&caps, sz_rfbAuthenticationCapsMsg)) {
-+ return False;
-+ }
-
-- caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes);
-+ caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes);
-
-- if (!caps.nAuthTypes) {
-- fprintf(stderr, "No authentication needed\n");
-- return True;
-- }
-+ if (!caps.nAuthTypes) {
-+ fprintf(stderr, "No VNC authentication needed\n\n");
-+ if (viewer_minor >= 8) {
-+ CARD32 authResult;
-+
-+ if (!ReadFromRFBServer((char *)&authResult, 4)) {
-+ return False;
-+ }
-+
-+ authResult = Swap32IfLE(authResult);
-+
-+ if (authResult == rfbVncAuthOK) {
-+ fprintf(stderr, "VNC authentication succeeded (%d) for PerformAuthenticationTight rfbSecTypeNone (RFB 3.8)\n", (int) authResult);
-+ } else {
-+ sprintf(msgbuf, "VNC authentication failed (%d) for PerformAuthenticationTight rfbSecTypeNone (RFB 3.8)\n\n", (int) authResult);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+ }
-+ return True;
-+ }
-
-- if (!ReadCapabilityList(authCaps, caps.nAuthTypes))
-- return False;
-+ if (!ReadCapabilityList(authCaps, caps.nAuthTypes)) {
-+ return False;
-+ }
-
-- /* Prefer Unix login authentication if a user name was given. */
-- if (appData.userLogin && CapsIsEnabled(authCaps, rfbAuthUnixLogin)) {
-- authScheme = Swap32IfLE(rfbAuthUnixLogin);
-- if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme)))
-- return False;
-- return AuthenticateUnixLogin();
-- }
-+ /* Prefer Unix login authentication if a user name was given. */
-+ if (appData.userLogin && CapsIsEnabled(authCaps, rfbAuthUnixLogin)) {
-+ authScheme = Swap32IfLE(rfbAuthUnixLogin);
-+ if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme))) {
-+ return False;
-+ }
-+ return AuthenticateUnixLogin();
-+ }
-
-- /* Otherwise, try server's preferred authentication scheme. */
-- for (i = 0; i < CapsNumEnabled(authCaps); i++) {
-- authScheme = CapsGetByOrder(authCaps, i);
-- if (authScheme != rfbAuthUnixLogin && authScheme != rfbAuthVNC)
-- continue; /* unknown scheme - cannot use it */
-- authScheme = Swap32IfLE(authScheme);
-- if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme)))
-- return False;
-- authScheme = Swap32IfLE(authScheme); /* convert it back */
-- if (authScheme == rfbAuthUnixLogin) {
-- return AuthenticateUnixLogin();
-- } else if (authScheme == rfbAuthVNC) {
-- return AuthenticateVNC();
-- } else {
-- /* Should never happen. */
-- fprintf(stderr, "Assertion failed: unknown authentication scheme\n");
-- return False;
-- }
-- }
-+ /* Otherwise, try server's preferred authentication scheme. */
-+ for (i = 0; i < CapsNumEnabled(authCaps); i++) {
-+ authScheme = CapsGetByOrder(authCaps, i);
-+ if (authScheme != rfbAuthUnixLogin && authScheme != rfbAuthVNC) {
-+ continue; /* unknown scheme - cannot use it */
-+ }
-+ authScheme = Swap32IfLE(authScheme);
-+ if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme))) {
-+ return False;
-+ }
-+ authScheme = Swap32IfLE(authScheme); /* convert it back */
-+ if (authScheme == rfbAuthUnixLogin) {
-+ return AuthenticateUnixLogin();
-+ } else if (authScheme == rfbAuthVNC) {
-+ return AuthenticateVNC();
-+ } else {
-+ /* Should never happen. */
-+ fprintf(stderr, "Assertion failed: unknown authentication scheme\n");
-+ return False;
-+ }
-+ }
-
-- fprintf(stderr, "No suitable authentication schemes offered by server\n");
-- return False;
-+ sprintf(msgbuf, "No suitable authentication schemes offered by server\n");
-+ wmsg(msgbuf, 1);
-+ return False;
-+}
-+
-+#if 0
-+unsigned char encPasswd[8];
-+unsigned char encPasswd_MSLOGON[32];
-+char clearPasswd_MSLOGIN[256];
-+static Bool old_ultravnc_mslogon_code(void) {
-+ char *passwd = NULL;
-+ CARD8 challenge_mslogon[CHALLENGESIZE_MSLOGON];
-+
-+ /* code from the old uvnc way (1.0.2?) that would go into AuthenticateVNC() template */
-+
-+ if (appData.msLogon != NULL) {
-+ raiseme(1);
-+ if (!strcmp(appData.msLogon, "1")) {
-+ char tmp[256];
-+ fprintf(stderr, "\nUltraVNC MS Logon Username[@Domain]: ");
-+ if (fgets(tmp, 256, stdin) == NULL) {
-+ exit(1);
-+ }
-+ appData.msLogon = strdup(tmp);
-+ }
-+ passwd = getpass("UltraVNC MS Logon Password: ");
-+ if (! passwd) {
-+ exit(1);
-+ }
-+ fprintf(stderr, "\n");
-+
-+ UvncEncryptPasswd_MSLOGON(encPasswd_MSLOGON, passwd);
-+ }
-+ if (appData.msLogon) {
-+ if (!ReadFromRFBServer((char *)challenge_mslogon, CHALLENGESIZE_MSLOGON)) {
-+ return False;
-+ }
-+ }
-+ if (appData.msLogon) {
-+ int i;
-+ char tmp[256];
-+ char *q, *domain = ".";
-+ for (i=0; i < 32; i++) {
-+ challenge_mslogon[i] = encPasswd_MSLOGON[i] ^ challenge_mslogon[i];
-+ }
-+ q = strchr(appData.msLogon, '@');
-+ if (q) {
-+ *q = '\0';
-+ domain = strdup(q+1);
-+ }
-+ memset(tmp, 0, sizeof(tmp));
-+ strcat(tmp, appData.msLogon);
-+ if (!WriteExact(rfbsock, tmp, 256)) {
-+ return False;
-+ }
-+ memset(tmp, 0, sizeof(tmp));
-+ strcat(tmp, domain);
-+ if (!WriteExact(rfbsock, tmp, 256)) {
-+ return False;
-+ }
-+ memset(tmp, 0, sizeof(tmp));
-+ strcat(tmp, passwd);
-+ if (!WriteExact(rfbsock, tmp, CHALLENGESIZE_MSLOGON)) {
-+ return False;
-+ }
-+ }
- }
-+#endif
-
-+static void hexprint(char *label, char *data, int len) {
-+ int i;
-+ fprintf(stderr, "%s: ", label);
-+ for (i=0; i < len; i++) {
-+ unsigned char c = (unsigned char) data[i];
-+ fprintf(stderr, "%02x ", (int) c);
-+ if ((i+1) % 20 == 0) {
-+ fprintf(stderr, "\n%s: ", label);
-+ }
-+ }
-+ fprintf(stderr, "\n");
-+}
-+
-+#define DH_MAX_BITS 31
-+static unsigned long long max_dh = ((unsigned long long) 1) << DH_MAX_BITS;
-+
-+static unsigned long long bytes_to_uint64(char *bytes) {
-+ unsigned long long result = 0;
-+ int i;
-+
-+ for (i=0; i < 8; i++) {
-+ result <<= 8;
-+ result += (unsigned char) bytes[i];
-+ }
-+ return result;
-+}
-+
-+static void uint64_to_bytes(unsigned long long n, char *bytes) {
-+ int i;
-+
-+ for (i=0; i < 8; i++) {
-+ bytes[i] = (unsigned char) (n >> (8 * (7 - i)));
-+ }
-+}
-+
-+static void try_invert(char *wireuser, char *wirepass, unsigned long long actual_key) {
-+ if (wireuser || wirepass || actual_key) {}
-+ return;
-+}
-+
-+
-+static unsigned long long XpowYmodN(unsigned long long x, unsigned long long y, unsigned long long N) {
-+ unsigned long long result = 1;
-+ unsigned long long oneShift63 = ((unsigned long long) 1) << 63;
-+ int i;
-+
-+ for (i = 0; i < 64; y <<= 1, i++) {
-+ result = result * result % N;
-+ if (y & oneShift63) {
-+ result = result * x % N;
-+ }
-+ }
-+ return result;
-+}
-+
-+/*
-+ * UltraVNC MS-Logon authentication (for v1.0.5 and later.)
-+ */
-+
-+/*
-+ * NOTE: The UltraVNC MS-Logon username and password exchange is
-+ * VERY insecure. It can be brute forced in ~2e+9 operations.
-+ * It's not clear we should support it... It is only worth using
-+ * in an environment where no one is sniffing the network, in which
-+ * case all of this DH exchange secrecy is unnecessary...
-+ */
-+
-+static Bool AuthUltraVncMsLogon(void) {
-+ CARD32 authResult;
-+ char gen[8], mod[8], pub[8], rsp[8];
-+ char user[256], passwd[64], *gpw;
-+ unsigned char key[8];
-+ unsigned long long ugen, umod, ursp, upub, uprv, ukey;
-+ double now = dnow();
-+ int db = 0;
-+
-+ if (getenv("SSVNC_DEBUG_MSLOGON")) {
-+ db = atoi(getenv("SSVNC_DEBUG_MSLOGON"));
-+ }
-+
-+ fprintf(stderr, "\nAuthUltraVncMsLogon()\n");
-+
-+ if (!ReadFromRFBServer(gen, sizeof(gen))) {
-+ return False;
-+ }
-+ if (db) hexprint("gen", gen, sizeof(gen));
-+
-+ if (!ReadFromRFBServer(mod, sizeof(mod))) {
-+ return False;
-+ }
-+ if (db) hexprint("mod", mod, sizeof(mod));
-+
-+ if (!ReadFromRFBServer(rsp, sizeof(rsp))) {
-+ return False;
-+ }
-+ if (db) hexprint("rsp", rsp, sizeof(rsp));
-+
-+ ugen = bytes_to_uint64(gen);
-+ umod = bytes_to_uint64(mod);
-+ ursp = bytes_to_uint64(rsp);
-+
-+ if (db) {
-+ fprintf(stderr, "ugen: 0x%016llx %12llu\n", ugen, ugen);
-+ fprintf(stderr, "umod: 0x%016llx %12llu\n", umod, umod);
-+ fprintf(stderr, "ursp: 0x%016llx %12llu\n", ursp, ursp);
-+ }
-+
-+ if (ugen > max_dh) {
-+ fprintf(stderr, "ugen: too big: 0x%016llx\n", ugen);
-+ return False;
-+ }
-+
-+ if (umod > max_dh) {
-+ fprintf(stderr, "umod: too big: 0x%016llx\n", umod);
-+ return False;
-+ }
-+
-+ /* make a random long long: */
-+ uprv = 0xffffffff * (now - (unsigned int) now);
-+ uprv = uprv << 32;
-+ uprv |= (unsigned long long) urandom();
-+ uprv = uprv % max_dh;
-+
-+ if (db) fprintf(stderr, "uprv: 0x%016llx %12llu\n", uprv, uprv);
-+
-+ upub = XpowYmodN(ugen, uprv, umod);
-+
-+ if (db) fprintf(stderr, "upub: 0x%016llx %12llu\n", upub, upub);
-+
-+ uint64_to_bytes(upub, pub);
-+
-+ if (db) hexprint("pub", pub, sizeof(pub));
-+
-+ if (!WriteExact(rfbsock, (char *)pub, sizeof(pub))) {
-+ return False;
-+ }
-+ if (db) fprintf(stderr, "wrote pub.\n");
-+
-+ if (ursp > max_dh) {
-+ fprintf(stderr, "ursp: too big: 0x%016llx\n", ursp);
-+ return False;
-+ }
-+
-+ ukey = XpowYmodN(ursp, uprv, umod);
-+
-+ if (db) fprintf(stderr, "ukey: 0x%016llx %12llu\n", ukey, ukey);
-+
-+ if (1) {
-+ char tmp[10000];
-+ tmp[0] = '\0';
-+ strcat(tmp, "\n");
-+ strcat(tmp, "WARNING: The UltraVNC Diffie-Hellman Key is weak (key < 2e+9, i.e. 31 bits)\n");
-+ strcat(tmp, "WARNING: and so an eavesdropper could recover your MS-Logon username and\n");
-+ strcat(tmp, "WARNING: password via brute force in a few seconds of CPU time. \n");
-+ strcat(tmp, "WARNING: If this connection is NOT being tunnelled through a separate SSL or\n");
-+ strcat(tmp, "WARNING: SSH encrypted tunnel, consider things carefully before proceeding...\n");
-+ strcat(tmp, "WARNING: Do not enter an important username+password when prompted below if\n");
-+ strcat(tmp, "WARNING: there is a risk of an eavesdropper sniffing this connection.\n");
-+ strcat(tmp, "WARNING: UltraVNC MSLogon encryption is VERY weak. You've been warned!\n");
-+ wmsg(tmp, 1);
-+ }
-+
-+ uint64_to_bytes(ukey, (char *) key);
-+
-+ if (appData.msLogon == NULL || !strcmp(appData.msLogon, "1")) {
-+ char tmp[256], *q, *s;
-+ if (!use_tty()) {
-+ fprintf(stderr, "\nEnter UltraVNC MS-Logon Username[@Domain] in the popup.\n");
-+ s = DoUserDialog();
-+ } else {
-+ raiseme(1);
-+ fprintf(stderr, "\nUltraVNC MS-Logon Username[@Domain]: ");
-+ if (fgets(tmp, 256, stdin) == NULL) {
-+ exit(1);
-+ }
-+ s = strdup(tmp);
-+ }
-+ q = strchr(s, '\n');
-+ if (q) *q = '\0';
-+ appData.msLogon = strdup(s);
-+ }
-+
-+ if (!use_tty()) {
-+ gpw = DoPasswordDialog();
-+ } else {
-+ raiseme(1);
-+ gpw = getpass("UltraVNC MS-Logon Password: ");
-+ }
-+ if (! gpw) {
-+ return False;
-+ }
-+ fprintf(stderr, "\n");
-+
-+ memset(user, 0, sizeof(user));
-+ strncpy(user, appData.msLogon, 255);
-+
-+ memset(passwd, 0, sizeof(passwd));
-+ strncpy(passwd, gpw, 63);
-+
-+ if (db > 1) {
-+ fprintf(stderr, "user='%s'\n", user);
-+ fprintf(stderr, "pass='%s'\n", passwd);
-+ }
-+
-+ UvncEncryptBytes2((unsigned char *) user, sizeof(user), key);
-+ UvncEncryptBytes2((unsigned char *) passwd, sizeof(passwd), key);
-+
-+ if (getenv("TRY_INVERT")) {
-+ try_invert(user, passwd, ukey);
-+ exit(0);
-+ }
-+
-+ if (db) {
-+ hexprint("user", user, sizeof(user));
-+ hexprint("pass", passwd, sizeof(passwd));
-+ }
-+
-+ if (!WriteExact(rfbsock, user, sizeof(user))) {
-+ return False;
-+ }
-+ if (db) fprintf(stderr, "wrote user.\n");
-+
-+ if (!WriteExact(rfbsock, passwd, sizeof(passwd))) {
-+ return False;
-+ }
-+ if (db) fprintf(stderr, "wrote passwd.\n");
-+
-+ if (!ReadFromRFBServer((char *) &authResult, 4)) {
-+ return False;
-+ }
-+ authResult = Swap32IfLE(authResult);
-+
-+ if (db) fprintf(stderr, "authResult: %d\n", (int) authResult);
-+
-+ switch (authResult) {
-+ case rfbVncAuthOK:
-+ fprintf(stderr, "UVNC MS-Logon authentication succeeded.\n\n");
-+ break;
-+ case rfbVncAuthFailed:
-+ fprintf(stderr, "UVNC MS-Logon authentication failed.\n");
-+ if (viewer_minor >= 8) {
-+ printFailureReason();
-+ } else {
-+ sprintf(msgbuf, "UVNC MS-Logon authentication failed.\n");
-+ wmsg(msgbuf, 1);
-+ }
-+ fprintf(stderr, "\n");
-+ return False;
-+ case rfbVncAuthTooMany:
-+ sprintf(msgbuf, "UVNC MS-Logon authentication failed - too many tries.\n\n");
-+ wmsg(msgbuf, 1);
-+ return False;
-+ default:
-+ sprintf(msgbuf, "Unknown UVNC MS-Logon authentication result: %d\n\n",
-+ (int)authResult);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+
-+ return True;
-+}
-
- /*
- * Standard VNC authentication.
-@@ -519,80 +1560,119 @@
- static Bool
- AuthenticateVNC(void)
- {
-- CARD32 authScheme, authResult;
-- CARD8 challenge[CHALLENGESIZE];
-- char *passwd;
-- char buffer[64];
-- char* cstatus;
-- int len;
-+ CARD32 authScheme, authResult;
-+ CARD8 challenge[CHALLENGESIZE];
-+ char *passwd = NULL;
-+ char buffer[64];
-+ char* cstatus;
-+ int len;
-+ int restart = 0;
-
-- fprintf(stderr, "Performing standard VNC authentication\n");
-+ if (authScheme) {}
-
-- if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE))
-- return False;
-+ fprintf(stderr, "\nPerforming standard VNC authentication\n");
-
-- if (appData.passwordFile) {
-- passwd = vncDecryptPasswdFromFile(appData.passwordFile);
-- if (!passwd) {
-- fprintf(stderr, "Cannot read valid password from file \"%s\"\n",
-- appData.passwordFile);
-- return False;
-- }
-- } else if (appData.autoPass) {
-- passwd = buffer;
-- cstatus = fgets(buffer, sizeof buffer, stdin);
-- if (cstatus == NULL)
-- buffer[0] = '\0';
-- else
-- {
-- len = strlen(buffer);
-- if (len > 0 && buffer[len - 1] == '\n')
-- buffer[len - 1] = '\0';
-- }
-- } else if (appData.passwordDialog) {
-- passwd = DoPasswordDialog();
-- } else {
-- passwd = getpass("Password: ");
-- }
-+ if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE)) {
-+ return False;
-+ }
-+
-+ if (restart_session_pw != NULL) {
-+ passwd = restart_session_pw;
-+ restart_session_pw = NULL;
-+ restart = 1;
-+ } else if (appData.passwordFile) {
-+ passwd = vncDecryptPasswdFromFile(appData.passwordFile);
-+ if (!passwd) {
-+ sprintf(msgbuf, "Cannot read valid password from file \"%s\"\n", appData.passwordFile);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+ } else if (appData.autoPass) {
-+ passwd = buffer;
-+ raiseme(1);
-+ cstatus = fgets(buffer, sizeof buffer, stdin);
-+ if (cstatus == NULL) {
-+ buffer[0] = '\0';
-+ } else {
-+ len = strlen(buffer);
-+ if (len > 0 && buffer[len - 1] == '\n') {
-+ buffer[len - 1] = '\0';
-+ }
-+ }
-+ } else if (getenv("VNCVIEWER_PASSWORD")) {
-+ passwd = strdup(getenv("VNCVIEWER_PASSWORD"));
-+ } else if (appData.passwordDialog || !use_tty()) {
-+ passwd = DoPasswordDialog();
-+ } else {
-+ raiseme(1);
-+ passwd = getpass("VNC Password: ");
-+ }
-
-- if (!passwd || strlen(passwd) == 0) {
-- fprintf(stderr, "Reading password failed\n");
-- return False;
-- }
-- if (strlen(passwd) > 8) {
-- passwd[8] = '\0';
-- }
-+ if (getenv("VNCVIEWER_PASSWORD")) {
-+ putenv("VNCVIEWER_PASSWORD=none");
-+ }
-
-- vncEncryptBytes(challenge, passwd);
-+ if (restart) {
-+#define EN0 0
-+#define DE1 1
-+ unsigned char s_fixedkey[8] = {23,82,107,6,35,78,88,7};
-+ deskey(s_fixedkey, DE1);
-+ des(passwd, passwd);
-+ } else {
-+ if (!passwd || strlen(passwd) == 0) {
-+ sprintf(msgbuf, "Reading password failed\n\n");
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+ if (strlen(passwd) > 8) {
-+ passwd[8] = '\0';
-+ }
-+ }
-
-- /* Lose the password from memory */
-- memset(passwd, '\0', strlen(passwd));
-+ vncEncryptBytes(challenge, passwd);
-+
-
-- if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE))
-- return False;
-
-- if (!ReadFromRFBServer((char *)&authResult, 4))
-- return False;
-+#if 0
-+ /* Lose the password from memory */
-+ memset(passwd, '\0', strlen(passwd));
-+#endif
-
-- authResult = Swap32IfLE(authResult);
-+ if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE)) {
-+ return False;
-+ }
-
-- switch (authResult) {
-- case rfbVncAuthOK:
-- fprintf(stderr, "VNC authentication succeeded\n");
-- break;
-- case rfbVncAuthFailed:
-- fprintf(stderr, "VNC authentication failed\n");
-- return False;
-- case rfbVncAuthTooMany:
-- fprintf(stderr, "VNC authentication failed - too many tries\n");
-- return False;
-- default:
-- fprintf(stderr, "Unknown VNC authentication result: %d\n",
-- (int)authResult);
-- return False;
-- }
-+ if (!ReadFromRFBServer((char *)&authResult, 4)) {
-+ return False;
-+ }
-
-- return True;
-+ authResult = Swap32IfLE(authResult);
-+
-+ switch (authResult) {
-+ case rfbVncAuthOK:
-+ fprintf(stderr, "VNC authentication succeeded\n\n");
-+ break;
-+ case rfbVncAuthFailed:
-+ fprintf(stderr, "VNC authentication failed.\n");
-+ if (viewer_minor >= 8) {
-+ printFailureReason();
-+ } else {
-+ sprintf(msgbuf, "VNC authentication failed.\n");
-+ wmsg(msgbuf, 1);
-+ }
-+ fprintf(stderr, "\n");
-+ return False;
-+ case rfbVncAuthTooMany:
-+ sprintf(msgbuf, "VNC authentication failed - too many tries\n\n");
-+ wmsg(msgbuf, 1);
-+ return False;
-+ default:
-+ sprintf(msgbuf, "Unknown VNC authentication result: %d\n\n", (int)authResult);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-+
-+ return True;
- }
-
- /*
-@@ -602,68 +1682,77 @@
- static Bool
- AuthenticateUnixLogin(void)
- {
-- CARD32 loginLen, passwdLen, authResult;
-- char *login;
-- char *passwd;
-- struct passwd *ps;
--
-- fprintf(stderr, "Performing Unix login-style authentication\n");
--
-- if (appData.userLogin) {
-- login = appData.userLogin;
-- } else {
-- ps = getpwuid(getuid());
-- login = ps->pw_name;
-- }
-+ CARD32 loginLen, passwdLen, authResult;
-+ char *login;
-+ char *passwd;
-+ struct passwd *ps;
-+
-+ fprintf(stderr, "\nPerforming Unix login-style authentication\n");
-+
-+ if (appData.userLogin) {
-+ login = appData.userLogin;
-+ } else {
-+ ps = getpwuid(getuid());
-+ login = ps->pw_name;
-+ }
-
-- fprintf(stderr, "Using user name \"%s\"\n", login);
-+ fprintf(stderr, "Using user name \"%s\"\n", login);
-
-- if (appData.passwordDialog) {
-- passwd = DoPasswordDialog();
-- } else {
-- passwd = getpass("Password: ");
-- }
-- if (!passwd || strlen(passwd) == 0) {
-- fprintf(stderr, "Reading password failed\n");
-- return False;
-- }
-+ if (appData.passwordDialog || !use_tty()) {
-+ passwd = DoPasswordDialog();
-+ } else {
-+ raiseme(1);
-+ passwd = getpass("VNC Password: ");
-+ }
-+ if (!passwd || strlen(passwd) == 0) {
-+ fprintf(stderr, "Reading password failed\n");
-+ return False;
-+ }
-
-- loginLen = Swap32IfLE((CARD32)strlen(login));
-- passwdLen = Swap32IfLE((CARD32)strlen(passwd));
-+ loginLen = Swap32IfLE((CARD32)strlen(login));
-+ passwdLen = Swap32IfLE((CARD32)strlen(passwd));
-
-- if (!WriteExact(rfbsock, (char *)&loginLen, sizeof(loginLen)) ||
-- !WriteExact(rfbsock, (char *)&passwdLen, sizeof(passwdLen)))
-- return False;
-+ if (!WriteExact(rfbsock, (char *)&loginLen, sizeof(loginLen)) ||
-+ !WriteExact(rfbsock, (char *)&passwdLen, sizeof(passwdLen))) {
-+ return False;
-+ }
-
-- if (!WriteExact(rfbsock, login, strlen(login)) ||
-- !WriteExact(rfbsock, passwd, strlen(passwd)))
-- return False;
-+ if (!WriteExact(rfbsock, login, strlen(login)) ||
-+ !WriteExact(rfbsock, passwd, strlen(passwd))) {
-+ return False;
-+ }
-
-- /* Lose the password from memory */
-- memset(passwd, '\0', strlen(passwd));
-+#if 0
-+ /* Lose the password from memory */
-+ memset(passwd, '\0', strlen(passwd));
-+#endif
-
-- if (!ReadFromRFBServer((char *)&authResult, sizeof(authResult)))
-- return False;
-+ if (!ReadFromRFBServer((char *)&authResult, sizeof(authResult))) {
-+ return False;
-+ }
-
-- authResult = Swap32IfLE(authResult);
-+ authResult = Swap32IfLE(authResult);
-
-- switch (authResult) {
-- case rfbVncAuthOK:
-- fprintf(stderr, "Authentication succeeded\n");
-- break;
-- case rfbVncAuthFailed:
-- fprintf(stderr, "Authentication failed\n");
-- return False;
-- case rfbVncAuthTooMany:
-- fprintf(stderr, "Authentication failed - too many tries\n");
-- return False;
-- default:
-- fprintf(stderr, "Unknown authentication result: %d\n",
-- (int)authResult);
-- return False;
-- }
-+ switch (authResult) {
-+ case rfbVncAuthOK:
-+ fprintf(stderr, "Authentication succeeded\n\n");
-+ break;
-+ case rfbVncAuthFailed:
-+ sprintf(msgbuf, "Authentication failed\n\n");
-+ wmsg(msgbuf, 1);
-+ return False;
-+ case rfbVncAuthTooMany:
-+ sprintf(msgbuf, "Authentication failed - too many tries\n\n");
-+ wmsg(msgbuf, 1);
-+ return False;
-+ default:
-+ sprintf(msgbuf, "Unknown authentication result: %d\n\n",
-+ (int)authResult);
-+ wmsg(msgbuf, 1);
-+ return False;
-+ }
-
-- return True;
-+ return True;
- }
-
-
-@@ -675,19 +1764,20 @@
- static Bool
- ReadInteractionCaps(void)
- {
-- rfbInteractionCapsMsg intr_caps;
-+ rfbInteractionCapsMsg intr_caps;
-
-- /* Read the counts of list items following */
-- if (!ReadFromRFBServer((char *)&intr_caps, sz_rfbInteractionCapsMsg))
-- return False;
-- intr_caps.nServerMessageTypes = Swap16IfLE(intr_caps.nServerMessageTypes);
-- intr_caps.nClientMessageTypes = Swap16IfLE(intr_caps.nClientMessageTypes);
-- intr_caps.nEncodingTypes = Swap16IfLE(intr_caps.nEncodingTypes);
--
-- /* Read the lists of server- and client-initiated messages */
-- return (ReadCapabilityList(serverMsgCaps, intr_caps.nServerMessageTypes) &&
-- ReadCapabilityList(clientMsgCaps, intr_caps.nClientMessageTypes) &&
-- ReadCapabilityList(encodingCaps, intr_caps.nEncodingTypes));
-+ /* Read the counts of list items following */
-+ if (!ReadFromRFBServer((char *)&intr_caps, sz_rfbInteractionCapsMsg)) {
-+ return False;
-+ }
-+ intr_caps.nServerMessageTypes = Swap16IfLE(intr_caps.nServerMessageTypes);
-+ intr_caps.nClientMessageTypes = Swap16IfLE(intr_caps.nClientMessageTypes);
-+ intr_caps.nEncodingTypes = Swap16IfLE(intr_caps.nEncodingTypes);
-+
-+ /* Read the lists of server- and client-initiated messages */
-+ return (ReadCapabilityList(serverMsgCaps, intr_caps.nServerMessageTypes) &&
-+ ReadCapabilityList(clientMsgCaps, intr_caps.nClientMessageTypes) &&
-+ ReadCapabilityList(encodingCaps, intr_caps.nEncodingTypes));
- }
-
-
-@@ -697,22 +1787,70 @@
- * many records to read from the socket.
- */
-
--static Bool
--ReadCapabilityList(CapsContainer *caps, int count)
--{
-- rfbCapabilityInfo msginfo;
-- int i;
-+static Bool
-+ReadCapabilityList(CapsContainer *caps, int count)
-+{
-+ rfbCapabilityInfo msginfo;
-+ int i;
-+
-+ for (i = 0; i < count; i++) {
-+ if (!ReadFromRFBServer((char *)&msginfo, sz_rfbCapabilityInfo)) {
-+ return False;
-+ }
-+ msginfo.code = Swap32IfLE(msginfo.code);
-+ CapsEnable(caps, &msginfo);
-+ }
-+
-+ return True;
-+}
-+
-
-- for (i = 0; i < count; i++) {
-- if (!ReadFromRFBServer((char *)&msginfo, sz_rfbCapabilityInfo))
-- return False;
-- msginfo.code = Swap32IfLE(msginfo.code);
-- CapsEnable(caps, &msginfo);
-- }
-+/* used to have !tunnelSpecified */
-
-- return True;
-+static int guess_compresslevel(void) {
-+ int n;
-+ if (latency > 200.0) {
-+ n = 8;
-+ } else if (latency > 100.0) {
-+ n = 7;
-+ } else if (latency > 60.0) {
-+ n = 6;
-+ } else if (latency > 15.0) {
-+ n = 4;
-+ } else if (latency > 8.0) {
-+ n = 2;
-+ } else if (latency > 0.0) {
-+ n = 1;
-+ } else {
-+ /* no latency measurement */
-+ n = 3;
-+ }
-+ return n;
- }
-
-+static int guess_qualitylevel(void) {
-+ int n;
-+ if (latency > 200.0) {
-+ n = 4;
-+ } else if (latency > 100.0) {
-+ n = 5;
-+ } else if (latency > 60.0) {
-+ n = 6;
-+ } else if (latency > 15.0) {
-+ n = 7;
-+ } else if (latency > 8.0) {
-+ n = 8;
-+ } else if (latency > 0.0) {
-+ n = 9;
-+ } else {
-+ /* no latency measurement */
-+ n = 6;
-+ }
-+#ifdef TURBOVNC
-+ n *= 10;
-+#endif
-+ return n;
-+}
-
- /*
- * SetFormatAndEncodings.
-@@ -729,6 +1867,21 @@
- Bool requestCompressLevel = False;
- Bool requestQualityLevel = False;
- Bool requestLastRectEncoding = False;
-+ Bool requestNewFBSizeEncoding = True;
-+ Bool requestTextChatEncoding = True;
-+ Bool requestSubsampLevel = False;
-+ int dsm = 0;
-+ int tQL, tQLmax = 9;
-+ static int qlmsg = 0, clmsg = 0;
-+#ifdef TURBOVNC
-+ tQLmax = 100;
-+#endif
-+
-+ if (requestTextChatEncoding || requestSubsampLevel || tQL) {}
-+
-+#if 0
-+ fprintf(stderr, "SetFormatAndEncodings: sent_FBU state: %2d\n", sent_FBU);
-+#endif
-
- spf.type = rfbSetPixelFormat;
- spf.format = myFormat;
-@@ -736,15 +1889,32 @@
- spf.format.greenMax = Swap16IfLE(spf.format.greenMax);
- spf.format.blueMax = Swap16IfLE(spf.format.blueMax);
-
-+
-+ currentMsg = rfbSetPixelFormat;
- if (!WriteExact(rfbsock, (char *)&spf, sz_rfbSetPixelFormatMsg))
- return False;
-
- se->type = rfbSetEncodings;
- se->nEncodings = 0;
-
-+ if (appData.ultraDSM) {
-+ dsm = 1;
-+ }
-+
- if (appData.encodingsString) {
- char *encStr = appData.encodingsString;
- int encStrLen;
-+ if (strchr(encStr, ',')) {
-+ char *p;
-+ encStr = strdup(encStr);
-+ p = encStr;
-+ while (*p != '\0') {
-+ if (*p == ',') {
-+ *p = ' ';
-+ }
-+ p++;
-+ }
-+ }
- do {
- char *nextEncStr = strchr(encStr, ' ');
- if (nextEncStr) {
-@@ -754,50 +1924,102 @@
- encStrLen = strlen(encStr);
- }
-
-+if (getenv("DEBUG_SETFORMAT")) {
-+ fprintf(stderr, "encs: ");
-+ write(2, encStr, encStrLen);
-+ fprintf(stderr, "\n");
-+}
-+
- if (strncasecmp(encStr,"raw",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
- } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
-- } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
-+ } else if (strncasecmp(encStr,"tight",encStrLen) == 0 && !dsm) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
- requestLastRectEncoding = True;
-- if (appData.compressLevel >= 0 && appData.compressLevel <= 9)
-- requestCompressLevel = True;
-- if (appData.enableJPEG)
-- requestQualityLevel = True;
-+ if (appData.compressLevel >= 0 && appData.compressLevel <= 9) {
-+ requestCompressLevel = True;
-+ }
-+ if (appData.enableJPEG) {
-+ requestQualityLevel = True;
-+ }
-+#ifdef TURBOVNC
-+ requestSubsampLevel = True;
-+#endif
- } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
-- } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
-+ } else if (strncasecmp(encStr,"zlib",encStrLen) == 0 && !dsm) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
-- if (appData.compressLevel >= 0 && appData.compressLevel <= 9)
-- requestCompressLevel = True;
-- } else if (strncasecmp(encStr,"corre",encStrLen) == 0) {
-+ if (appData.compressLevel >= 0 && appData.compressLevel <= 9) {
-+ requestCompressLevel = True;
-+ }
-+ } else if (strncasecmp(encStr,"corre",encStrLen) == 0 && !dsm) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
- } else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE);
-+ } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) {
-+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZRLE);
-+#if DO_ZYWRLE
-+ } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) {
-+ int qlevel = appData.qualityLevel;
-+ if (qlevel < 0 || qlevel > tQLmax) qlevel = guess_qualitylevel();
-+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZYWRLE);
-+ requestQualityLevel = True;
-+ if (qlevel < 3) {
-+ zywrle_level = 3;
-+ } else if (qlevel < 6) {
-+ zywrle_level = 2;
-+ } else {
-+ zywrle_level = 1;
-+ }
-+#endif
- } else {
- fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr);
-+ if (dsm && strstr(encStr, "tight") == encStr) fprintf(stderr, "tight encoding does not yet work with ultraDSM, skipping it.\n");
-+ if (dsm && strstr(encStr, "corre") == encStr) fprintf(stderr, "corre encoding does not yet work with ultraDSM, skipping it.\n");
-+ if (dsm && strstr(encStr, "zlib" ) == encStr) fprintf(stderr, "zlib encoding does not yet work with ultraDSM, skipping it.\n");
- }
-
- encStr = nextEncStr;
- } while (encStr && se->nEncodings < MAX_ENCODINGS);
-
- if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
-- encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel +
-- rfbEncodingCompressLevel0);
-+ ;
-+ } else if (se->nEncodings < MAX_ENCODINGS) {
-+ appData.compressLevel = guess_compresslevel();
-+ if (clmsg++ == 0) fprintf(stderr, "guessed: -compresslevel %d\n", appData.compressLevel);
- }
-+ encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + rfbEncodingCompressLevel0);
-
- if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
-- if (appData.qualityLevel < 0 || appData.qualityLevel > 9)
-- appData.qualityLevel = 5;
-- encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
-- rfbEncodingQualityLevel0);
-+ if (appData.qualityLevel < 0 || appData.qualityLevel > tQLmax) {
-+ appData.qualityLevel = guess_qualitylevel();
-+ if (qlmsg++ == 0) fprintf(stderr, "guessed: -qualitylevel %d\n", appData.qualityLevel);
-+ }
-+ } else if (se->nEncodings < MAX_ENCODINGS) {
-+ appData.qualityLevel = guess_qualitylevel();
-+ if (qlmsg++ == 0) fprintf(stderr, "guessed: -qualitylevel %d\n", appData.qualityLevel);
-+ }
-+#ifdef TURBOVNC
-+ tQL = appData.qualityLevel / 10;
-+ if (tQL < 0) tQL = 1;
-+ if (tQL > 9) tQL = 9;
-+ encs[se->nEncodings++] = Swap32IfLE(tQL + rfbEncodingQualityLevel0);
-+ encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + rfbJpegQualityLevel1 - 1);
-+ if (se->nEncodings < MAX_ENCODINGS && requestSubsampLevel) {
-+ if (appData.subsampLevel < 0 || appData.subsampLevel > TVNC_SAMPOPT - 1) {
-+ appData.subsampLevel = TVNC_1X;
-+ }
-+ encs[se->nEncodings++] = Swap32IfLE(appData.subsampLevel + rfbJpegSubsamp1X);
- }
-+#else
-+ encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + rfbEncodingQualityLevel0);
-+#endif
-
- if (appData.useRemoteCursor) {
- if (se->nEncodings < MAX_ENCODINGS)
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
-- if (se->nEncodings < MAX_ENCODINGS)
-+ if (se->nEncodings < MAX_ENCODINGS && !appData.useX11Cursor)
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
- if (se->nEncodings < MAX_ENCODINGS)
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
-@@ -806,10 +2028,16 @@
- if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
- }
-- }
-- else {
-+
-+ if (se->nEncodings < MAX_ENCODINGS && requestNewFBSizeEncoding) {
-+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize);
-+ }
-+
-+ } else {
-+ /* DIFFERENT CASE */
-+
- if (SameMachine(rfbsock)) {
-- if (!tunnelSpecified) {
-+ if (!tunnelSpecified && appData.useRawLocal) {
- fprintf(stderr,"Same machine: preferring raw encoding\n");
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
- } else {
-@@ -818,44 +2046,84 @@
- }
-
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
-- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
-+ if (!dsm) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
-+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZRLE);
-+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZYWRLE);
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
-- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
-- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
-+ if (!dsm) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
-+ if (!dsm) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE);
-
-- if (appData.compressLevel >= 0 && appData.compressLevel <= 9) {
-- encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel +
-- rfbEncodingCompressLevel0);
-- } else if (!tunnelSpecified) {
-- /* If -tunnel option was provided, we assume that server machine is
-- not in the local network so we use default compression level for
-- tight encoding instead of fast compression. Thus we are
-- requesting level 1 compression only if tunneling is not used. */
-- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCompressLevel1);
-- }
--
-- if (appData.enableJPEG) {
-- if (appData.qualityLevel < 0 || appData.qualityLevel > 9)
-- appData.qualityLevel = 5;
-- encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
-- rfbEncodingQualityLevel0);
-+ if (!dsm && appData.compressLevel >= 0 && appData.compressLevel <= 9) {
-+ encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + rfbEncodingCompressLevel0);
-+ } else {
-+ /*
-+ * OUT OF DATE: If -tunnel option was provided, we assume that server machine is
-+ * not in the local network so we use default compression level for
-+ * tight encoding instead of fast compression. Thus we are
-+ * requesting level 1 compression only if tunneling is not used.
-+ */
-+ appData.compressLevel = guess_compresslevel();
-+ if (clmsg++ == 0) fprintf(stderr, "guessed: -compresslevel %d\n", appData.compressLevel);
-+ encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + rfbEncodingCompressLevel0);
-+ }
-+
-+ if (!dsm && appData.enableJPEG) {
-+ if (appData.qualityLevel < 0 || appData.qualityLevel > tQLmax) {
-+ appData.qualityLevel = guess_qualitylevel();
-+ if (qlmsg++ == 0) fprintf(stderr, "guessed: -qualitylevel %d\n", appData.qualityLevel);
-+ }
-+
-+#ifdef TURBOVNC
-+ requestSubsampLevel = True;
-+ tQL = appData.qualityLevel / 10;
-+ if (tQL < 0) tQL = 1;
-+ if (tQL > 9) tQL = 9;
-+ encs[se->nEncodings++] = Swap32IfLE(tQL + rfbEncodingQualityLevel0);
-+ encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + rfbJpegQualityLevel1 - 1);
-+ if (se->nEncodings < MAX_ENCODINGS && requestSubsampLevel) {
-+ if (appData.subsampLevel < 0 || appData.subsampLevel > TVNC_SAMPOPT - 1) {
-+ appData.subsampLevel = TVNC_1X;
-+ }
-+ encs[se->nEncodings++] = Swap32IfLE(appData.subsampLevel + rfbJpegSubsamp1X);
-+ }
-+#else
-+ encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + rfbEncodingQualityLevel0);
-+#endif
-+
- }
-
- if (appData.useRemoteCursor) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
-- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
-+ if (!appData.useX11Cursor) {
-+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
-+ }
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
- }
-
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
-+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize);
- }
-
- len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
-
-- se->nEncodings = Swap16IfLE(se->nEncodings);
-+ if (!appData.ultraDSM) {
-+ se->nEncodings = Swap16IfLE(se->nEncodings);
-
-- if (!WriteExact(rfbsock, buf, len)) return False;
-+ if (!WriteExact(rfbsock, buf, len)) return False;
-+ } else {
-+ /* for UltraVNC encryption DSM we have to send each encoding separately (why?) */
-+ int i, errs = 0, nenc = se->nEncodings;
-+
-+ se->nEncodings = Swap16IfLE(se->nEncodings);
-+
-+ currentMsg = rfbSetEncodings;
-+ if (!WriteExact(rfbsock, buf, sz_rfbSetEncodingsMsg)) errs++;
-+ for (i=0; i < nenc; i++) {
-+ if (!WriteExact(rfbsock, (char *)&encs[i], sizeof(CARD32))) errs++;
-+ }
-+ if (errs) return False;
-+ }
-
- return True;
- }
-@@ -868,31 +2136,86 @@
- Bool
- SendIncrementalFramebufferUpdateRequest()
- {
-- return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
-- si.framebufferHeight, True);
-+ return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
-+ si.framebufferHeight, True);
- }
-
-+time_t last_filexfer = 0;
-+int delay_filexfer = 3;
-+extern void CheckFileXfer(void);
-+extern int rfbsock_is_ready(void);
-+
-+
-+static int dyn = -1;
-+extern int filexfer_sock;
-+extern int filexfer_listen;
-
- /*
- * SendFramebufferUpdateRequest.
- */
--
- Bool
- SendFramebufferUpdateRequest(int x, int y, int w, int h, Bool incremental)
- {
-- rfbFramebufferUpdateRequestMsg fur;
-+ rfbFramebufferUpdateRequestMsg fur;
-+ static int db = -1;
-
-- fur.type = rfbFramebufferUpdateRequest;
-- fur.incremental = incremental ? 1 : 0;
-- fur.x = Swap16IfLE(x);
-- fur.y = Swap16IfLE(y);
-- fur.w = Swap16IfLE(w);
-- fur.h = Swap16IfLE(h);
-+ if (db < 0) {
-+ if (getenv("SSVNC_DEBUG_RECTS")) {
-+ db = atoi(getenv("SSVNC_DEBUG_RECTS"));
-+ } else {
-+ db = 0;
-+ }
-+ }
-
-- if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
-- return False;
-+ if (db) fprintf(stderr, "SendFramebufferUpdateRequest(%d, %d, %d, %d, incremental=%d)\n", x, y, w, h, (int) incremental);
-
-- return True;
-+ if (dyn < 0) {
-+ struct stat sb;
-+ if (getenv("USER") && !strcmp(getenv("USER"), "runge")) {
-+ if (stat("/tmp/nodyn", &sb) == 0) {
-+ putenv("NOFTFBUPDATES=1");
-+ unlink("/tmp/nodyn");
-+ }
-+ }
-+ if (getenv("NOFTFBUPDATES")) {
-+ dyn = 0;
-+ } else {
-+ dyn = 1;
-+ }
-+ }
-+
-+ if (appData.fileActive && filexfer_sock >= 0) {
-+ static int first = 1;
-+ if (first) {
-+ fprintf(stderr, "SFU: dynamic fb updates during filexfer: %d\n", dyn);
-+ first = 0;
-+ }
-+if (db > 2 || 0) fprintf(stderr, "A sfur: %d %d %d %d d_last: %d\n", x, y, w, h, (int) (time(NULL) - last_filexfer));
-+ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) {
-+ return True;
-+ }
-+ }
-+if (db > 1) fprintf(stderr, "B sfur: %d %d %d %d\n", x, y, w, h);
-+
-+ fur.type = rfbFramebufferUpdateRequest;
-+ fur.incremental = incremental ? 1 : 0;
-+ fur.x = Swap16IfLE(x);
-+ fur.y = Swap16IfLE(y);
-+ fur.w = Swap16IfLE(w);
-+ fur.h = Swap16IfLE(h);
-+
-+ if (incremental) {
-+ sent_FBU = 1;
-+ } else {
-+ sent_FBU = 2;
-+ }
-+
-+ currentMsg = rfbFramebufferUpdateRequest;
-+ if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg)) {
-+ return False;
-+ }
-+
-+ return True;
- }
-
-
-@@ -903,19 +2226,38 @@
- Bool
- SendPointerEvent(int x, int y, int buttonMask)
- {
-- rfbPointerEventMsg pe;
-+ rfbPointerEventMsg pe;
-+
-+ if (appData.fileActive) {
-+ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) {
-+#if 0
-+ fprintf(stderr, "skip SendPointerEvent: %d - %d\n", last_filexfer, time(NULL));
-+#endif
-+ return True;
-+ }
-+ }
-
-- pe.type = rfbPointerEvent;
-- pe.buttonMask = buttonMask;
-- if (x < 0) x = 0;
-- if (y < 0) y = 0;
--
-- if (!appData.useX11Cursor)
-- SoftCursorMove(x, y);
--
-- pe.x = Swap16IfLE(x);
-- pe.y = Swap16IfLE(y);
-- return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg);
-+ pe.type = rfbPointerEvent;
-+ pe.buttonMask = buttonMask;
-+
-+ if (scale_factor_x > 0.0 && scale_factor_x != 1.0) {
-+ x /= scale_factor_x;
-+ }
-+ if (scale_factor_y > 0.0 && scale_factor_y != 1.0) {
-+ y /= scale_factor_y;
-+ }
-+
-+ if (x < 0) x = 0;
-+ if (y < 0) y = 0;
-+
-+ if (!appData.useX11Cursor) {
-+ SoftCursorMove(x, y);
-+ }
-+
-+ pe.x = Swap16IfLE(x);
-+ pe.y = Swap16IfLE(y);
-+ currentMsg = rfbPointerEvent;
-+ return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg);
- }
-
-
-@@ -926,12 +2268,22 @@
- Bool
- SendKeyEvent(CARD32 key, Bool down)
- {
-- rfbKeyEventMsg ke;
-+ rfbKeyEventMsg ke;
-+
-+ if (appData.fileActive) {
-+ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) {
-+#if 0
-+ fprintf(stderr, "skip SendPointerEvent: %d - %d\n", last_filexfer, time(NULL));
-+#endif
-+ return True;
-+ }
-+ }
-
-- ke.type = rfbKeyEvent;
-- ke.down = down ? 1 : 0;
-- ke.key = Swap32IfLE(key);
-- return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg);
-+ ke.type = rfbKeyEvent;
-+ ke.down = down ? 1 : 0;
-+ ke.key = Swap32IfLE(key);
-+ currentMsg = rfbKeyEvent;
-+ return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg);
- }
-
-
-@@ -942,281 +2294,1025 @@
- Bool
- SendClientCutText(char *str, int len)
- {
-- rfbClientCutTextMsg cct;
-+ rfbClientCutTextMsg cct;
-+
-+ if (serverCutText) {
-+ free(serverCutText);
-+ }
-+ serverCutText = NULL;
-+
-+ if (appData.fileActive) {
-+ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) {
-+ /* ultravnc java viewer lets this one through. */
-+ return True;
-+ }
-+ }
-+
-+ if (appData.viewOnly) {
-+ return True;
-+ }
-
-- if (serverCutText)
-- free(serverCutText);
-- serverCutText = NULL;
--
-- cct.type = rfbClientCutText;
-- cct.length = Swap32IfLE(len);
-- return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) &&
-- WriteExact(rfbsock, str, len));
-+ cct.type = rfbClientCutText;
-+ cct.length = Swap32IfLE((unsigned int) len);
-+ currentMsg = rfbClientCutText;
-+ return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) &&
-+ WriteExact(rfbsock, str, len));
- }
-
-+static int ultra_scale = 0;
-
--/*
-- * HandleRFBServerMessage.
-- */
-+Bool
-+SendServerScale(int nfac)
-+{
-+ rfbSetScaleMsg ssc;
-+ if (nfac < 0 || nfac > 100) {
-+ return True;
-+ }
-+
-+ ultra_scale = nfac;
-+ ssc.type = rfbSetScale;
-+ ssc.scale = nfac;
-+ currentMsg = rfbSetScale;
-+ return WriteExact(rfbsock, (char *)&ssc, sz_rfbSetScaleMsg);
-+}
-
- Bool
--HandleRFBServerMessage()
-+SendServerInput(Bool enabled)
- {
-- rfbServerToClientMsg msg;
-+ rfbSetServerInputMsg sim;
-
-- if (!ReadFromRFBServer((char *)&msg, 1))
-- return False;
-+ sim.type = rfbSetServerInput;
-+ sim.status = enabled;
-+ currentMsg = rfbSetServerInput;
-+ return WriteExact(rfbsock, (char *)&sim, sz_rfbSetServerInputMsg);
-+}
-
-- switch (msg.type) {
-+Bool
-+SendSingleWindow(int x, int y)
-+{
-+ static int w_old = -1, h_old = -1;
-+ rfbSetSWMsg sw;
-
-- case rfbSetColourMapEntries:
-- {
-- int i;
-- CARD16 rgb[3];
-- XColor xc;
-+ fprintf(stderr, "SendSingleWindow: %d %d\n", x, y);
-
-- if (!ReadFromRFBServer(((char *)&msg) + 1,
-- sz_rfbSetColourMapEntriesMsg - 1))
-- return False;
-+ if (x == -1 && y == -1) {
-+ sw.type = rfbSetSW;
-+ sw.x = Swap16IfLE(1);
-+ sw.y = Swap16IfLE(1);
-+ if (w_old > 0) {
-+ si.framebufferWidth = w_old;
-+ si.framebufferHeight = h_old;
-+ ReDoDesktop();
-+ }
-+ w_old = h_old = -1;
-+ } else {
-+ sw.type = rfbSetSW;
-+ sw.x = Swap16IfLE(x);
-+ sw.y = Swap16IfLE(y);
-+ w_old = si.framebufferWidth;
-+ h_old = si.framebufferHeight;
-+
-+ }
-+ sw.status = True;
-+ currentMsg = rfbSetSW;
-+ return WriteExact(rfbsock, (char *)&sw, sz_rfbSetSWMsg);
-+}
-
-- msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
-- msg.scme.nColours = Swap16IfLE(msg.scme.nColours);
-+Bool
-+SendTextChat(char *str)
-+{
-+ static int db = -1;
-+ rfbTextChatMsg chat;
-
-- for (i = 0; i < msg.scme.nColours; i++) {
-- if (!ReadFromRFBServer((char *)rgb, 6))
-- return False;
-- xc.pixel = msg.scme.firstColour + i;
-- xc.red = Swap16IfLE(rgb[0]);
-- xc.green = Swap16IfLE(rgb[1]);
-- xc.blue = Swap16IfLE(rgb[2]);
-- xc.flags = DoRed|DoGreen|DoBlue;
-- XStoreColor(dpy, cmap, &xc);
-- }
-+ if (db < 0) {
-+ if (getenv("SSVNC_DEBUG_CHAT")) {
-+ db = 1;
-+ } else {
-+ db = 0;
-+ }
-+ }
-+ if (!appData.chatActive) {
-+ SendTextChatOpen();
-+ appData.chatActive = True;
-+ }
-
-- break;
-- }
-+ chat.type = rfbTextChat;
-+ chat.pad1 = 0;
-+ chat.pad2 = 0;
-+ chat.length = (unsigned int) strlen(str);
-+ if (db) fprintf(stderr, "SendTextChat: %d '%s'\n", (int) chat.length, str);
-+ chat.length = Swap32IfLE(chat.length);
-+ if (!WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg)) {
-+ return False;
-+ }
-+ currentMsg = rfbTextChat;
-+ return WriteExact(rfbsock, str, strlen(str));
-+}
-
-- case rfbFramebufferUpdate:
-- {
-- rfbFramebufferUpdateRectHeader rect;
-- int linesToRead;
-- int bytesPerLine;
-- int i;
-- int usecs;
-+extern void raiseme(int force);
-
-- if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
-- sz_rfbFramebufferUpdateMsg - 1))
-- return False;
-+Bool
-+SendTextChatOpen(void)
-+{
-+ rfbTextChatMsg chat;
-
-- msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
-+ raiseme(0);
-+ chat.type = rfbTextChat;
-+ chat.pad1 = 0;
-+ chat.pad2 = 0;
-+ chat.length = Swap32IfLE(rfbTextChatOpen);
-+ return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg);
-+}
-
-- for (i = 0; i < msg.fu.nRects; i++) {
-- if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
-- return False;
-+Bool
-+SendTextChatClose(void)
-+{
-+ rfbTextChatMsg chat;
-+ chat.type = rfbTextChat;
-+ chat.pad1 = 0;
-+ chat.pad2 = 0;
-+ chat.length = Swap32IfLE(rfbTextChatClose);
-+ appData.chatActive = False;
-+ return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg);
-+}
-
-- rect.encoding = Swap32IfLE(rect.encoding);
-- if (rect.encoding == rfbEncodingLastRect)
-- break;
-+Bool
-+SendTextChatFinished(void)
-+{
-+ rfbTextChatMsg chat;
-+ chat.type = rfbTextChat;
-+ chat.pad1 = 0;
-+ chat.pad2 = 0;
-+ chat.length = Swap32IfLE(rfbTextChatFinished);
-+ appData.chatActive = False;
-+ return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg);
-+}
-+
-+extern int do_format_change;
-+extern int do_cursor_change;
-+extern double do_fb_update;
-+extern void cutover_format_change(void);
-+
-+double dtime(double *t_old) {
-+ /*
-+ * usage: call with 0.0 to initialize, subsequent calls give
-+ * the time difference since last call.
-+ */
-+ double t_now, dt;
-+ struct timeval now;
-+
-+ gettimeofday(&now, NULL);
-+ t_now = now.tv_sec + ( (double) now.tv_usec/1000000. );
-+ if (*t_old == 0.0) {
-+ *t_old = t_now;
-+ return t_now;
-+ }
-+ dt = t_now - *t_old;
-+ *t_old = t_now;
-+ return(dt);
-+}
-+
-+/* common dtime() activities: */
-+double dtime0(double *t_old) {
-+ *t_old = 0.0;
-+ return dtime(t_old);
-+}
-+
-+double dnow(void) {
-+ double t;
-+ return dtime0(&t);
-+}
-+
-+static char fxfer[65536];
-+
-+Bool HandleFileXfer(void) {
-+ unsigned char hdr[12];
-+ unsigned int len;
-+
-+ int rfbDirContentRequest = 1;
-+ int rfbDirPacket = 2; /* Full directory name or full file name. */
-+ int rfbFileTransferRequest = 3;
-+ int rfbFileHeader = 4;
-+ int rfbFilePacket = 5; /* One slice of the file */
-+ int rfbEndOfFile = 6;
-+ int rfbAbortFileTransfer = 7;
-+ int rfbFileTransferOffer = 8;
-+ int rfbFileAcceptHeader = 9; /* The server accepts or rejects the file */
-+ int rfbCommand = 10;
-+ int rfbCommandReturn = 11;
-+ int rfbFileChecksums = 12;
-+
-+ int rfbRDirContent = 1; /* Request a Server Directory contents */
-+ int rfbRDrivesList = 2; /* Request the server's drives list */
-+
-+ int rfbADirectory = 1; /* Reception of a directory name */
-+ int rfbAFile = 2; /* Reception of a file name */
-+ int rfbADrivesList = 3; /* Reception of a list of drives */
-+ int rfbADirCreate = 4; /* Response to a create dir command */
-+ int rfbADirDelete = 5; /* Response to a delete dir command */
-+ int rfbAFileCreate = 6; /* Response to a create file command */
-+ int rfbAFileDelete = 7; /* Response to a delete file command */
-+
-+ int rfbCDirCreate = 1; /* Request the server to create the given directory */
-+ int rfbCDirDelete = 2; /* Request the server to delete the given directory */
-+ int rfbCFileCreate = 3; /* Request the server to create the given file */
-+ int rfbCFileDelete = 4; /* Request the server to delete the given file */
-+
-+ int rfbRErrorUnknownCmd = 1; /* Unknown FileTransfer command. */
-+#define rfbRErrorCmd 0xFFFFFFFF
-+
-+ static int db = -1;
-+ static int guess_x11vnc = 0;
-+
-+#if 0
-+ if (filexfer_sock < 0) {
-+ return True;
-+ }
-+ /* instead, we read and discard the ft msg data. */
-+#endif
-+
-+/*fprintf(stderr, "In HandleFileXfer\n"); */
-
-- rect.r.x = Swap16IfLE(rect.r.x);
-- rect.r.y = Swap16IfLE(rect.r.y);
-- rect.r.w = Swap16IfLE(rect.r.w);
-- rect.r.h = Swap16IfLE(rect.r.h);
--
-- if (rect.encoding == rfbEncodingXCursor ||
-- rect.encoding == rfbEncodingRichCursor) {
-- if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h,
-- rect.encoding)) {
-- return False;
-+ if (db < 0) {
-+ if (getenv("DEBUG_HandleFileXfer")) {
-+ db = 1;
-+ } else {
-+ db = 0;
-+ }
- }
-- continue;
-- }
-
-- if (rect.encoding == rfbEncodingPointerPos) {
-- if (!HandleCursorPos(rect.r.x, rect.r.y)) {
-- return False;
-+ last_filexfer = time(NULL);
-+ /*fprintf(stderr, "last_filexfer-1: %d\n", last_filexfer); */
-+
-+ /* load first byte to send to Java be the FT msg number: */
-+ hdr[0] = rfbFileTransfer;
-+
-+ /* this is to avoid XtAppProcessEvent() calls induce by our ReadFromRFBServer calls below: */
-+ skip_XtUpdateAll = 1;
-+ if (!ReadFromRFBServer(&hdr[1], 11)) {
-+ skip_XtUpdateAll = 0;
-+ return False;
-+ }
-+ if (filexfer_sock >= 0) {
-+ write(filexfer_sock, hdr, 12);
-+ } else {
-+ fprintf(stderr, "filexfer_sock closed, discarding 12 bytes\n");
-+ }
-+ if (db) fprintf(stderr, "\n");
-+ if (db) fprintf(stderr, "Got rfbFileTransfer hdr\n");
-+ if (db > 1) write(2, hdr, 12);
-+
-+ if (db) {
-+ int i;
-+ fprintf(stderr, "HFX HDR:");
-+ for (i=0; i < 12; i++) {
-+ fprintf(stderr, " %d", (int) hdr[i]);
-+ }
-+ fprintf(stderr, "\n");
- }
-- continue;
-- }
-
-- if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
-- (rect.r.y + rect.r.h > si.framebufferHeight))
-- {
-- fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
-- rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-- return False;
-+ if (hdr[1] == rfbEndOfFile) {
-+ goto read_no_more;
-+ } else if (hdr[1] == rfbAbortFileTransfer) {
-+ goto read_no_more;
- }
-
-- if (rect.r.h * rect.r.w == 0) {
-- fprintf(stderr,"Zero size rect - ignoring\n");
-- continue;
-- }
-+ if (hdr[1] == rfbDirPacket && hdr[3] == rfbADirectory) {
-+
-+ }
-+
-+ len = (hdr[8] << 24) | (hdr[9] << 16) | (hdr[10] << 8) | hdr[11];
-+ if (db) fprintf(stderr, "Got rfbFileTransfer: len1 %u\n", len);
-+ if (len > 0) {
-+ if (!ReadFromRFBServer(fxfer, len)) {
-+ skip_XtUpdateAll = 0;
-+ return False;
-+ }
-+ if (db > 1) write(2, fxfer, len);
-+ if (len >= 12 && hdr[1] == rfbDirPacket) {
-+ /* try to guess if x11vnc or not... */
-+ if (db) {
-+ int i;
-+ fprintf(stderr, "HFX DIR PKT (attr, timeL, timeH):");
-+ for (i=0; i < 12; i++) {
-+ fprintf(stderr, " %d", (unsigned char) fxfer[i]);
-+ }
-+ fprintf(stderr, "\n");
-+ }
-+ if (hdr[2] == 1) {
-+ int dattr = (unsigned char) fxfer[0];
-+ int timeL1 = (unsigned char) fxfer[4];
-+ int timeL2 = (unsigned char) fxfer[5];
-+ int timeL3 = (unsigned char) fxfer[6];
-+ int timeL4 = (unsigned char) fxfer[7];
-+ int timeH1 = (unsigned char) fxfer[8];
-+ int timeH2 = (unsigned char) fxfer[9];
-+ int timeH3 = (unsigned char) fxfer[10];
-+ int timeH4 = (unsigned char) fxfer[11];
-+ if (dattr != 0) {
-+ if (timeH1 == 0 && timeH2 == 0 && timeH3 == 0 && timeH4 == 0) {
-+ if ((timeL1 != 0 || timeL2 != 0) && timeL3 != 0 && timeL4 != 0) {
-+ if (!guess_x11vnc) fprintf(stderr, "guessed x11vnc server\n");
-+ guess_x11vnc = 1;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ if (db && 0) fprintf(stderr, "\n");
-+ if (filexfer_sock >= 0) {
-+ write(filexfer_sock, fxfer, len);
-+ } else {
-+ fprintf(stderr, "filexfer_sock closed, discarding %d bytes\n", len);
-+ }
-+ }
-+
-+ len = (hdr[4] << 24) | (hdr[5] << 16) | (hdr[6] << 8) | hdr[7];
-+ if (db) fprintf(stderr, "Got rfbFileTransfer: len2 %u\n", len);
-+
-+#if 0
-+ if (hdr[1] == rfbFileHeader && len != rfbRErrorCmd)
-+#else
-+ /* the extra 4 bytes get send on rfbRErrorCmd as well. */
-+ if (hdr[1] == rfbFileHeader) {
-+#endif
-+ int is_err = 0;
-+ if (len == rfbRErrorCmd) {
-+ is_err = 1;
-+ }
-+ if (db) fprintf(stderr, "Got rfbFileTransfer: rfbFileHeader\n");
-+ if (is_err && guess_x11vnc) {
-+ fprintf(stderr, "rfbRErrorCmd x11vnc skip read 4 bytes.\n");
-+ goto read_no_more;
-+ }
-+ len = 4;
-+ if (!ReadFromRFBServer(fxfer, len)) {
-+ skip_XtUpdateAll = 0;
-+ return False;
-+ }
-+ if (db > 1) write(2, fxfer, len);
-+ if (db && 0) fprintf(stderr, "\n");
-+ if (is_err) {
-+ fprintf(stderr, "rfbRErrorCmd skip write 4 bytes.\n");
-+ goto read_no_more;
-+ }
-+ if (filexfer_sock >= 0) {
-+ write(filexfer_sock, fxfer, len);
-+ } else {
-+ fprintf(stderr, "filexfer_sock closed, discarding %d bytes\n", len);
-+ }
-+ }
-
-- /* If RichCursor encoding is used, we should prevent collisions
-- between framebuffer updates and cursor drawing operations. */
-- SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);
-+ read_no_more:
-
-- switch (rect.encoding) {
-+ if (filexfer_sock < 0) {
-+ int stop = 0;
-+ static time_t last_stop = 0;
-+#if 0
-+ /* this isn't working */
-+ if (hdr[1] == rfbFilePacket || hdr[1] == rfbFileHeader) {
-+ fprintf(stderr, "filexfer_sock closed, trying to abort receive\n");
-+ stop = 1;
-+ }
-+#endif
-+ if (stop && time(NULL) > last_stop+1) {
-+ unsigned char rpl[12];
-+ int k;
-+ rpl[0] = rfbFileTransfer;
-+ rpl[1] = rfbAbortFileTransfer;
-+ for (k=2; k < 12; k++) {
-+ rpl[k] = 0;
-+ }
-+ WriteExact(rfbsock, rpl, 12);
-+ last_stop = time(NULL);
-+ }
-+ }
-
-- case rfbEncodingRaw:
-+ if (db) fprintf(stderr, "Got rfbFileTransfer done.\n");
-+ skip_XtUpdateAll = 0;
-
-- bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
-- linesToRead = BUFFER_SIZE / bytesPerLine;
-+ if (db) fprintf(stderr, "CFX: B\n");
-+ CheckFileXfer();
-+/*fprintf(stderr, "Out HandleFileXfer\n"); */
-+ return True;
-+}
-
-- while (rect.r.h > 0) {
-- if (linesToRead > rect.r.h)
-- linesToRead = rect.r.h;
-+/*
-+ * HandleRFBServerMessage.
-+ */
-
-- if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
-- return False;
-
-- CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
-- linesToRead);
-+Bool
-+HandleRFBServerMessage()
-+{
-+ static int db = -1;
-+ rfbServerToClientMsg msg;
-
-- rect.r.h -= linesToRead;
-- rect.r.y += linesToRead;
-+ if (db < 0) {
-+ if (getenv("DEBUG_RFB_SMSG")) {
-+ db = 1;
-+ } else {
-+ db = 0;
-+ }
-+ }
-
-+ if (!ReadFromRFBServer((char *)&msg, 1)) {
-+ return False;
- }
-- break;
-+ if (appData.ultraDSM) {
-+ if (!ReadFromRFBServer((char *)&msg, 1)) {
-+ return False;
-+ }
-+ }
-+
-+/*fprintf(stderr, "msg.type: %d\n", msg.type); */
-
-- case rfbEncodingCopyRect:
-- {
-- rfbCopyRect cr;
--
-- if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
-- return False;
--
-- cr.srcX = Swap16IfLE(cr.srcX);
-- cr.srcY = Swap16IfLE(cr.srcY);
--
-- /* If RichCursor encoding is used, we should extend our
-- "cursor lock area" (previously set to destination
-- rectangle) to the source rectangle as well. */
-- SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);
--
-- if (appData.copyRectDelay != 0) {
-- XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
-- rect.r.w, rect.r.h);
-- XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
-- rect.r.w, rect.r.h);
-- XSync(dpy,False);
-- usleep(appData.copyRectDelay * 1000);
-- XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
-- rect.r.w, rect.r.h);
-- XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
-- rect.r.w, rect.r.h);
-+ if (msg.type == rfbFileTransfer) {
-+ return HandleFileXfer();
- }
-
-- XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY,
-- rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-+ switch (msg.type) {
-
-- break;
-- }
-+ case rfbSetColourMapEntries:
-+ {
-+ int i;
-+ CARD16 rgb[3];
-+ XColor xc;
-
-- case rfbEncodingRRE:
-- {
-- switch (myFormat.bitsPerPixel) {
-- case 8:
-- if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-- case 16:
-- if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-- case 32:
-- if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-+ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbSetColourMapEntriesMsg - 1)) {
-+ return False;
- }
-- break;
-- }
-
-- case rfbEncodingCoRRE:
-- {
-- switch (myFormat.bitsPerPixel) {
-- case 8:
-- if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-- case 16:
-- if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-- case 32:
-- if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-+ msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
-+ msg.scme.nColours = Swap16IfLE(msg.scme.nColours);
-+
-+ for (i = 0; i < msg.scme.nColours; i++) {
-+ if (!ReadFromRFBServer((char *)rgb, 6)) {
-+ return False;
-+ }
-+ xc.pixel = msg.scme.firstColour + i;
-+ xc.red = Swap16IfLE(rgb[0]);
-+ xc.green = Swap16IfLE(rgb[1]);
-+ xc.blue = Swap16IfLE(rgb[2]);
-+ if (appData.useGreyScale) {
-+ int ave = (xc.red + xc.green + xc.blue)/3;
-+ xc.red = ave;
-+ xc.green = ave;
-+ xc.blue = ave;
-+ }
-+ xc.flags = DoRed|DoGreen|DoBlue;
-+ XStoreColor(dpy, cmap, &xc);
- }
-+
- break;
-- }
-+ }
-+
-+ case rfbFramebufferUpdate:
-+ {
-+ rfbFramebufferUpdateRectHeader rect;
-+ int linesToRead;
-+ int bytesPerLine;
-+ int i;
-+
-+ int area_copyrect = 0;
-+ int area_tight = 0;
-+ int area_zrle = 0;
-+ int area_raw = 0;
-+ static int rdb = -1;
-+ static int delay_sync = -1;
-+ static int delay_sync_env = -1;
-+ int try_delay_sync = 0;
-+ int cnt_pseudo = 0;
-+ int cnt_image = 0;
-+
-+ int skip_incFBU = 0;
-+
-+ if (db) fprintf(stderr, "FBU-0: %.6f\n", dnow());
-+ if (rdb < 0) {
-+ if (getenv("SSVNC_DEBUG_RECTS")) {
-+ rdb = atoi(getenv("SSVNC_DEBUG_RECTS"));
-+ } else {
-+ rdb = 0;
-+ }
-+ }
-+ if (delay_sync < 0) {
-+ if (getenv("SSVNC_DELAY_SYNC")) {
-+ delay_sync = atoi(getenv("SSVNC_DELAY_SYNC"));
-+ delay_sync_env = delay_sync;
-+ } else {
-+ delay_sync = 0;
-+ }
-+ }
-+
-+ sent_FBU = -1;
-
-- case rfbEncodingHextile:
-- {
-- switch (myFormat.bitsPerPixel) {
-- case 8:
-- if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-- case 16:
-- if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-- case 32:
-- if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-+ if (appData.pipelineUpdates) {
-+ /* turbovnc speed idea */
-+ XEvent ev;
-+ memset(&ev, 0, sizeof(ev));
-+ ev.xclient.type = ClientMessage;
-+ ev.xclient.window = XtWindow(desktop);
-+ ev.xclient.message_type = XA_INTEGER;
-+ ev.xclient.format = 8;
-+ strcpy(ev.xclient.data.b, "SendRFBUpdate");
-+ XSendEvent(dpy, XtWindow(desktop), False, 0, &ev);
- }
-- break;
-- }
-
-- case rfbEncodingZlib:
-- {
-- switch (myFormat.bitsPerPixel) {
-- case 8:
-- if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-- case 16:
-- if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-- case 32:
-- if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-+ if (!ReadFromRFBServer(((char *)&msg.fu) + 1, sz_rfbFramebufferUpdateMsg - 1)) {
-+ return False;
- }
-- break;
-- }
-
-- case rfbEncodingTight:
-- {
-- switch (myFormat.bitsPerPixel) {
-- case 8:
-- if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-- case 16:
-- if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-- case 32:
-- if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
-- return False;
-- break;
-+ msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
-+
-+ if (rdb) fprintf(stderr, "Begin rect loop %d\n", msg.fu.nRects);
-+
-+ if (delay_sync) {
-+ try_delay_sync = 1;
-+ } else {
-+ if (delay_sync_env != -1 && delay_sync_env == 0) {
-+ ;
-+ } else if (appData.yCrop > 0) {
-+ ;
-+ } else if (scale_factor_x > 0.0 && scale_factor_x != 1.0) {
-+ ;
-+ } else if (scale_factor_y > 0.0 && scale_factor_y != 1.0) {
-+ ;
-+ } else {
-+ static int msg = 0;
-+ /* fullScreen? */
-+ /* useXserverBackingStore? */
-+ /* useX11Cursor & etc? */
-+ /* scrollbars? */
-+ if (!msg) {
-+ fprintf(stderr, "enabling 'delay_sync' mode for faster local drawing,\ndisable via env SSVNC_DELAY_SYNC=0 if there are painting errors.\n");
-+ msg = 1;
-+ }
-+ try_delay_sync = 1;
-+ }
-+ }
-+ if (try_delay_sync) {
-+ skip_maybe_sync = 1;
-+ }
-+#define STOP_DELAY_SYNC \
-+ if (try_delay_sync) { \
-+ if (cnt_image && skip_maybe_sync) { \
-+ XSync(dpy, False); \
-+ } \
-+ try_delay_sync = 0; \
-+ skip_maybe_sync = 0; \
- }
-- break;
-- }
-
-- default:
-- fprintf(stderr,"Unknown rect encoding %d\n",
-- (int)rect.encoding);
-- return False;
-- }
-+ for (i = 0; i < msg.fu.nRects; i++) {
-+ if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader)) {
-+ return False;
-+ }
-+
-+ rect.encoding = Swap32IfLE(rect.encoding);
-+ if (rect.encoding == rfbEncodingLastRect) {
-+ break;
-+ }
-+
-+ rect.r.x = Swap16IfLE(rect.r.x);
-+ rect.r.y = Swap16IfLE(rect.r.y);
-+ rect.r.w = Swap16IfLE(rect.r.w);
-+ rect.r.h = Swap16IfLE(rect.r.h);
-+
-+ if (rdb > 1) fprintf(stderr, "nRects: %d i=%d enc: %d %dx%d+%d+%d\n", msg.fu.nRects, i, (int) rect.encoding, rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-+
-+ if (rect.encoding == rfbEncodingXCursor || rect.encoding == rfbEncodingRichCursor) {
-+ cnt_pseudo++;
-+ STOP_DELAY_SYNC
-+
-+ if (db) fprintf(stderr, "FBU-Cur1 %.6f\n", dnow());
-+ if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, rect.encoding)) {
-+ return False;
-+ }
-+ if (db) fprintf(stderr, "FBU-Cur2 %.6f\n", dnow());
-+ continue;
-+ }
-+
-+ if (rect.encoding == rfbEncodingPointerPos) {
-+ cnt_pseudo++;
-+ STOP_DELAY_SYNC
-+ if (db) fprintf(stderr, "FBU-Pos1 %.6f\n", dnow());
-+ if (0) fprintf(stderr, "CursorPos: %d %d / %d %d\n", rect.r.x, rect.r.y, rect.r.w, rect.r.h);
-+ if (ultra_scale > 0) {
-+ int f = ultra_scale;
-+ if (!HandleCursorPos(rect.r.x/f, rect.r.y/f)) {
-+ return False;
-+ }
-+ } else {
-+ if (!HandleCursorPos(rect.r.x, rect.r.y)) {
-+ return False;
-+ }
-+ }
-+ if (db) fprintf(stderr, "FBU-Pos2 %.6f\n", dnow());
-+ continue;
-+ }
-+ if (rect.encoding == rfbEncodingNewFBSize) {
-+ cnt_pseudo++;
-+ STOP_DELAY_SYNC
-+ if (appData.chatOnly) {
-+ continue;
-+ }
-+ fprintf(stderr,"New Size: %dx%d at (%d, %d)\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-+ si.framebufferWidth = rect.r.w;
-+ si.framebufferHeight = rect.r.h;
-+ /*fprintf(stderr, "si: %d %d\n", si.framebufferWidth, si.framebufferHeight); */
-+ ReDoDesktop();
-+ continue;
-+ }
-+ if (rdb) fprintf(stderr,"Rect: %dx%d at (%d, %d)\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-+ cnt_image++;
-+
-+ if (appData.ultraDSM) {
-+ /*
-+ * What a huge mess the UltraVNC DSM plugin is!!!
-+ * We read and ignore their little "this much data" hint...
-+ */
-+ switch (rect.encoding)
-+ {
-+ case rfbEncodingRaw:
-+ case rfbEncodingRRE:
-+ case rfbEncodingCoRRE:
-+ case rfbEncodingHextile:
-+ /*case rfbEncodingUltra: */
-+/* case rfbEncodingZlib: */
-+ /*case rfbEncodingXOR_Zlib: */
-+ /*case rfbEncodingXORMultiColor_Zlib: */
-+ /*case rfbEncodingXORMonoColor_Zlib: */
-+ /*case rfbEncodingSolidColor: */
-+ case rfbEncodingTight:
-+ case rfbEncodingZlibHex:
-+ case rfbEncodingZRLE:
-+ case rfbEncodingZYWRLE:
-+ {
-+ CARD32 discard;
-+ ReadFromRFBServer((char *)&discard, sizeof(CARD32));
-+ }
-+ break;
-+ }
-+ }
-+
-+ if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
-+ (rect.r.y + rect.r.h > si.framebufferHeight)) {
-+ if (!appData.chatOnly) {
-+ fprintf(stderr,"Rect too large: %dx%d at (%d, %d) encoding=%d\n",
-+ rect.r.w, rect.r.h, rect.r.x, rect.r.y, (int) rect.encoding);
-+ return False;
-+ }
-+ }
-+
-+ if (rect.r.h * rect.r.w == 0) {
-+ fprintf(stderr,"*** Warning *** Zero size rect: %dx%d+%d+%d encoding=%d\n",
-+ rect.r.w, rect.r.h, rect.r.x, rect.r.y, (int) rect.encoding);
-+ if (0) continue;
-+ }
-+
-+ /* If RichCursor encoding is used, we should prevent collisions
-+ between framebuffer updates and cursor drawing operations. */
-+ if (db) fprintf(stderr, "FBU-SCL1 %.6f\n", dnow());
-+
-+ SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);
-+
-+ if (db) fprintf(stderr, "FBU-SCL2 %.6f\n", dnow());
-+
-+
-+ switch (rect.encoding) {
-+
-+ case rfbEncodingRaw:
-+
-+ bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
-+ linesToRead = BUFFER_SIZE / bytesPerLine;
-+
-+ if (db) fprintf(stderr, "Raw: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-+ area_raw += rect.r.w * rect.r.h;
-+
-+ while (rect.r.h > 0) {
-+ if (linesToRead > rect.r.h) {
-+ linesToRead = rect.r.h;
-+ }
-+
-+ if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead)) {
-+ return False;
-+ }
-+
-+ CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, linesToRead);
-+
-+ rect.r.h -= linesToRead;
-+ rect.r.y += linesToRead;
-+ }
-+ break;
-+
-+ case rfbEncodingCopyRect:
-+ {
-+ rfbCopyRect cr;
-+
-+ STOP_DELAY_SYNC
-+ XSync(dpy, False);
-+
-+ if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect)) {
-+ return False;
-+ }
-+ if (appData.chatOnly) {
-+ break;
-+ }
-+
-+ cr.srcX = Swap16IfLE(cr.srcX);
-+ cr.srcY = Swap16IfLE(cr.srcY);
-+
-+ if (db) fprintf(stderr, "Copy: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-+ area_copyrect += rect.r.w * rect.r.h;
-+
-+ /* If RichCursor encoding is used, we should extend our
-+ "cursor lock area" (previously set to destination
-+ rectangle) to the source rectangle as well. */
-+
-+ if (db) fprintf(stderr, "FBU-SCL3 %.6f\n", dnow());
-+
-+ SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);
-+
-+ if (db) fprintf(stderr, "FBU-SCL4 %.6f\n", dnow());
-+
-+ if (appData.copyRectDelay != 0) {
-+ XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h);
-+ XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
-+ XSync(dpy,False);
-+ usleep(appData.copyRectDelay * 1000);
-+ XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
-+ XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h);
-+ }
-+
-+ if (db) fprintf(stderr, "FBU-CPA1 %.6f\n", dnow());
-+ if (!appData.useXserverBackingStore) {
-+ copy_rect(rect.r.x, rect.r.y, rect.r.w, rect.r.h, cr.srcX, cr.srcY);
-+ put_image(rect.r.x, rect.r.y, rect.r.x, rect.r.y, rect.r.w, rect.r.h, 0);
-+ XSync(dpy, False);
-+ } else {
-+ XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY,
-+ rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-+ }
-+ if (db) fprintf(stderr, "FBU-CPA2 %.6f\n", dnow());
-+
-+ break;
-+ }
-+
-+ case rfbEncodingRRE:
-+ {
-+ switch (myFormat.bitsPerPixel) {
-+ case 8:
-+ if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 16:
-+ if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 32:
-+ if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ }
-+ break;
-+ }
-+
-+ case rfbEncodingCoRRE:
-+ {
-+ switch (myFormat.bitsPerPixel) {
-+ case 8:
-+ if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 16:
-+ if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 32:
-+ if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ }
-+ break;
-+ }
-+
-+ case rfbEncodingHextile:
-+ {
-+ switch (myFormat.bitsPerPixel) {
-+ case 8:
-+ if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 16:
-+ if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 32:
-+ if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ }
-+ break;
-+ }
-+
-+ case rfbEncodingZlib:
-+ {
-+ switch (myFormat.bitsPerPixel) {
-+ case 8:
-+ if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 16:
-+ if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 32:
-+ if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ }
-+ break;
-+ }
-+
-+ case rfbEncodingTight:
-+ {
-+ if (db) fprintf(stderr, "Tight: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-+ area_tight += rect.r.w * rect.r.h;
-+ if (db) fprintf(stderr, "FBU-TGH1 %.6f\n", dnow());
-+
-+ switch (myFormat.bitsPerPixel) {
-+ case 8:
-+ if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 16:
-+ if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 32:
-+ if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ }
-+ if (db) fprintf(stderr, "FBU-TGH2 %.6f\n", dnow());
-+ break;
-+ }
-+
-+ /* runge adds zrle and zywrle: */
-+ case rfbEncodingZRLE:
-+#if DO_ZYWRLE
-+ zywrle_level = 0;
-+ case rfbEncodingZYWRLE:
-+#endif
-+ {
-+ if (db) fprintf(stderr, "ZRLE: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-+ area_zrle += rect.r.w * rect.r.h;
-+ switch (myFormat.bitsPerPixel) {
-+ case 8:
-+ if (!HandleZRLE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ case 16:
-+ if (myFormat.greenMax > 0x1f) {
-+ if (!HandleZRLE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ } else {
-+ if (!HandleZRLE15(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ }
-+ break;
-+ case 32:
-+ {
-+ unsigned int maxColor=(myFormat.redMax<<myFormat.redShift)|
-+ (myFormat.greenMax<<myFormat.greenShift)|
-+ (myFormat.blueMax<<myFormat.blueShift);
-+ static int ZRLE32 = -1;
-+
-+ if (ZRLE32 < 0) {
-+ /* for debugging or workaround e.g. BE display to LE */
-+ if (getenv("ZRLE32")) {
-+ if (strstr(getenv("ZRLE32"), "24Up")) {
-+ ZRLE32 = 3;
-+ } else if (strstr(getenv("ZRLE32"), "24Down")) {
-+ ZRLE32 = 2;
-+ } else {
-+ ZRLE32 = 1;
-+ }
-+ } else {
-+ ZRLE32 = 0;
-+ }
-+ }
-+
-+if (db) fprintf(stderr, "maxColor: 0x%x mfbigEnding: %d\n", maxColor, myFormat.bigEndian);
-+
-+ if (ZRLE32 == 1) {
-+if (db) fprintf(stderr, "HandleZRLE32\n");
-+ if (!HandleZRLE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ } else if (ZRLE32 == 2) {
-+if (db) fprintf(stderr, "HandleZRLE24Down\n");
-+ if (!HandleZRLE24Down(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ } else if (ZRLE32 == 3) {
-+if (db) fprintf(stderr, "HandleZRLE24Up\n");
-+ if (!HandleZRLE24Up(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ } else if ((myFormat.bigEndian && (maxColor&0xff)==0) || (!myFormat.bigEndian && (maxColor&0xff000000)==0)) {
-+if (db) fprintf(stderr, "HandleZRLE24\n");
-+ if (!HandleZRLE24(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ } else if (!myFormat.bigEndian && (maxColor&0xff)==0) {
-+if (db) fprintf(stderr, "HandleZRLE24Up\n");
-+ if (!HandleZRLE24Up(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ } else if (myFormat.bigEndian && (maxColor&0xff000000)==0) {
-+if (db) fprintf(stderr, "HandleZRLE24Down\n");
-+ if (!HandleZRLE24Down(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ } else if (!HandleZRLE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) {
-+ return False;
-+ }
-+ break;
-+ }
-+ }
-+ break;
-+ }
-+
-+ default:
-+ fprintf(stderr,"Unknown rect encoding %d\n", (int)rect.encoding);
-+ return False;
-+ }
-
-- /* Now we may discard "soft cursor locks". */
-- SoftCursorUnlockScreen();
-- }
-+ /* Now we may discard "soft cursor locks". */
-+ if (db) fprintf(stderr, "FBU-SUL1 %.6f\n", dnow());
-+
-+ SoftCursorUnlockScreen();
-+
-+ if (db) fprintf(stderr, "FBU-SUL2 %.6f\n", dnow());
-+ }
-+
-+ if (try_delay_sync) {
-+ skip_maybe_sync = 0;
-+ }
-+
-+ if (1 || area_copyrect) {
-+ /* we always do this now for some reason... */
-+ if (db) fprintf(stderr, "FBU-XSN1 %.6f\n", dnow());
-+ XSync(dpy, False);
-+ if (db) fprintf(stderr, "FBU-XSN2 %.6f\n", dnow());
-+ }
-+ sent_FBU = 0;
-+ /*
-+ * we need to be careful since Xt events are processed
-+ * usually in the middle of FBU. So we do any scheduled ones now
-+ * which is pretty safe but not absolutely safe.
-+ */
-+ if (do_format_change) {
-+ cutover_format_change();
-+ do_format_change = 0;
-+ SetVisualAndCmap();
-+ SetFormatAndEncodings();
-+ if (do_cursor_change) {
-+ if (do_cursor_change == 1) {
-+ DesktopCursorOff();
-+ }
-+ do_cursor_change = 0;
-+ } else {
-+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
-+ si.framebufferHeight, False);
-+ skip_incFBU = 1;
-+ }
-+ }
-+ if (do_fb_update != 0.0) {
-+ if (dnow() > do_fb_update + 1.1) {
-+ do_fb_update = 0.0;
-+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
-+ si.framebufferHeight, False);
-+ }
-+ }
-
- #ifdef MITSHM
- /* if using shared memory PutImage, make sure that the X server has
-@@ -1224,59 +3320,168 @@
- mainly to avoid copyrect using invalid screen contents - not sure
- if we'd need it otherwise. */
-
-- if (appData.useShm)
-- XSync(dpy, False);
-+ if (appData.useShm) {
-+ XSync(dpy, False);
-+ } else
- #endif
-+ {
-+ /* we do it always now. */
-+ XSync(dpy, False);
-+ }
-+
-+ if (skip_XtUpdate || skip_incFBU) {
-+ ;
-+ } else if (appData.pipelineUpdates) {
-+ ;
-+ } else if (!SendIncrementalFramebufferUpdateRequest()) {
-+ return False;
-+ }
-
-- if (!SendIncrementalFramebufferUpdateRequest())
-- return False;
--
-- break;
-+ break;
- }
-
- case rfbBell:
- {
-- Window toplevelWin;
-+ Window toplevelWin;
-
-- XBell(dpy, 0);
-+ if (appData.useBell) {
-+ XBell(dpy, 0);
-+ }
-+
-+ if (appData.raiseOnBeep) {
-+ toplevelWin = XtWindow(toplevel);
-+ XMapRaised(dpy, toplevelWin);
-+ }
-
-- if (appData.raiseOnBeep) {
-- toplevelWin = XtWindow(toplevel);
-- XMapRaised(dpy, toplevelWin);
-+ break;
- }
-
-- break;
-- }
-+ case rfbServerCutText:
-+ {
-+ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbServerCutTextMsg - 1)) {
-+ return False;
-+ }
-
-- case rfbServerCutText:
-- {
-- if (!ReadFromRFBServer(((char *)&msg) + 1,
-- sz_rfbServerCutTextMsg - 1))
-- return False;
-+ msg.sct.length = Swap32IfLE(msg.sct.length);
-
-- msg.sct.length = Swap32IfLE(msg.sct.length);
-+ if (serverCutText) {
-+ free(serverCutText);
-+ }
-
-- if (serverCutText)
-- free(serverCutText);
-+ serverCutText = malloc(msg.sct.length+1);
-
-- serverCutText = malloc(msg.sct.length+1);
-+ if (!ReadFromRFBServer(serverCutText, msg.sct.length)) {
-+ return False;
-+ }
-
-- if (!ReadFromRFBServer(serverCutText, msg.sct.length))
-- return False;
-+ serverCutText[msg.sct.length] = 0;
-
-- serverCutText[msg.sct.length] = 0;
-+ newServerCutText = True;
-
-- newServerCutText = True;
-+ break;
-+ }
-
-- break;
-- }
-+ case rfbTextChat:
-+ {
-+ char *buffer = NULL;
-+ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbTextChatMsg - 1)) {
-+ return False;
-+ }
-+ msg.tc.length = Swap32IfLE(msg.tc.length);
-+ switch(msg.tc.length) {
-+ case rfbTextChatOpen:
-+ if (appData.termChat) {
-+ printChat("\n*ChatOpen*\n\nSend: ", True);
-+ } else {
-+ printChat("\n*ChatOpen*\n", True);
-+ }
-+ appData.chatActive = True;
-+ break;
-+ case rfbTextChatClose:
-+ printChat("\n*ChatClose*\n", False);
-+ appData.chatActive = False;
-+ break;
-+ case rfbTextChatFinished:
-+ printChat("\n*ChatFinished*\n", False);
-+ appData.chatActive = False;
-+ break;
-+ default:
-+ buffer = (char *)malloc(msg.tc.length+1);
-+ if (!ReadFromRFBServer(buffer, msg.tc.length)) {
-+ free(buffer);
-+ return False;
-+ }
-+ buffer[msg.tc.length] = '\0';
-+ appData.chatActive = True;
-+ GotChatText(buffer, msg.tc.length);
-+ free(buffer);
-+ }
-+ break;
-+ }
-
-- default:
-- fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
-- return False;
-- }
-+ case rfbResizeFrameBuffer:
-+ {
-+ rfbResizeFrameBufferMsg rsmsg;
-+ if (!ReadFromRFBServer(((char *)&rsmsg) + 1, sz_rfbResizeFrameBufferMsg - 1)) {
-+ return False;
-+ }
-+ si.framebufferWidth = Swap16IfLE(rsmsg.framebufferWidth);
-+ si.framebufferHeight = Swap16IfLE(rsmsg.framebufferHeight);
-+ fprintf(stderr,"UltraVNC ReSize: %dx%d\n", si.framebufferWidth, si.framebufferHeight);
-+ ReDoDesktop();
-+ break;
-+ }
-
-- return True;
-+ case rfbRestartConnection:
-+ {
-+ rfbRestartConnectionMsg rc;
-+ int len;
-+ char *rs_str;
-+ char buf[5] = "\xff\xff\xff\xff";
-+ fprintf(stderr, "rfbRestartConnection. type=%d\n", (int) rc.type);
-+ if (!ReadFromRFBServer((char *)&rc + 1, sz_rfbRestartConnectionMsg - 1)) {
-+ return False;
-+ }
-+ len = Swap32IfLE(rc.length);
-+ fprintf(stderr, "rfbRestartConnection. pad1=%d\n", (int) rc.pad1);
-+ fprintf(stderr, "rfbRestartConnection. pad2=%d\n", (int) rc.pad2);
-+ fprintf(stderr, "rfbRestartConnection. len=%d\n", len);
-+ if (len) {
-+ rs_str = (char *)malloc(2*len);
-+ if (!ReadFromRFBServer(rs_str, len)) {
-+ return False;
-+ }
-+ restart_session_pw = rs_str;
-+ restart_session_len = len;
-+ }
-+ if (!WriteExact(rfbsock, buf, 4)) {
-+ return False;
-+ }
-+ InitialiseRFBConnection();
-+ SetVisualAndCmap();
-+ SetFormatAndEncodings();
-+ DesktopCursorOff();
-+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, False);
-+
-+ break;
-+ }
-+
-+ default:
-+ fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
-+ return False;
-+ }
-+
-+ if (appData.fileActive) {
-+ if (filexfer_sock < 0 && filexfer_listen < 0) {
-+ appData.fileActive = False;
-+ SendFramebufferUpdateRequest(0, 0, 1, 1, False);
-+ } else {
-+/*fprintf(stderr, "CFX: A\n"); */
-+ CheckFileXfer();
-+ }
-+ }
-+
-+ return True;
- }
-
-
-@@ -1296,26 +3501,93 @@
- #define CONCAT2(a,b) a##b
- #define CONCAT2E(a,b) CONCAT2(a,b)
-
-+#define CONCAT3(a,b,c) a##b##c
-+#define CONCAT3E(a,b,c) CONCAT3(a,b,c)
-+
-+static unsigned char* frameBuffer = NULL;
-+static int frameBufferLen = 0;
-+
-+#ifdef TURBOVNC
-+#include "turbovnc/turbojpeg.h"
-+tjhandle tjhnd=NULL;
-+static char *compressedData = NULL;
-+static char *uncompressedData = NULL;
-+#define CopyDataToImage CopyDataToScreen
-+static void turbovnc_FillRectangle(XGCValues *gcv, int rx, int ry, int rw, int rh) {
-+ if (!appData.useXserverBackingStore) {
-+ FillScreen(rx, ry, rw, rh, gcv->foreground);
-+ } else {
-+ XChangeGC(dpy, gc, GCForeground, gcv);
-+ XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);
-+ }
-+}
-+static void CopyImageToScreen(int x, int y, int w, int h) {
-+ put_image(x, y, x, y, w, h, 0);
-+}
-+#endif
-+
- #define BPP 8
- #include "rre.c"
- #include "corre.c"
- #include "hextile.c"
- #include "zlib.c"
-+
-+#ifdef TURBOVNC
-+#undef FillRectangle
-+#define FillRectangle turbovnc_FillRectangle
-+#include "turbovnc/tight.c"
-+#undef FillRectangle
-+#else
- #include "tight.c"
-+#endif
-+
-+#include "zrle.c"
- #undef BPP
-+
- #define BPP 16
- #include "rre.c"
- #include "corre.c"
- #include "hextile.c"
- #include "zlib.c"
-+
-+#ifdef TURBOVNC
-+#undef FillRectangle
-+#define FillRectangle turbovnc_FillRectangle
-+#include "turbovnc/tight.c"
-+#undef FillRectangle
-+#else
- #include "tight.c"
-+#endif
-+
-+#include "zrle.c"
-+#define REALBPP 15
-+#include "zrle.c"
- #undef BPP
-+
- #define BPP 32
- #include "rre.c"
- #include "corre.c"
- #include "hextile.c"
- #include "zlib.c"
-+
-+#ifdef TURBOVNC
-+#undef FillRectangle
-+#define FillRectangle turbovnc_FillRectangle
-+#include "turbovnc/tight.c"
-+#undef FillRectangle
-+#else
- #include "tight.c"
-+#endif
-+
-+#include "zrle.c"
-+#define REALBPP 24
-+#include "zrle.c"
-+#define REALBPP 24
-+#define UNCOMP 8
-+#include "zrle.c"
-+#define REALBPP 24
-+#define UNCOMP -8
-+#include "zrle.c"
- #undef BPP
-
- /*
-@@ -1325,23 +3597,27 @@
- static void
- ReadConnFailedReason(void)
- {
-- CARD32 reasonLen;
-- char *reason = NULL;
-+ CARD32 reasonLen;
-+ char *reason = NULL;
-
-- if (ReadFromRFBServer((char *)&reasonLen, sizeof(reasonLen))) {
-- reasonLen = Swap32IfLE(reasonLen);
-- if ((reason = malloc(reasonLen)) != NULL &&
-- ReadFromRFBServer(reason, reasonLen)) {
-- fprintf(stderr,"VNC connection failed: %.*s\n", (int)reasonLen, reason);
-- free(reason);
-- return;
-- }
-- }
-+ if (ReadFromRFBServer((char *)&reasonLen, sizeof(reasonLen))) {
-+ reasonLen = Swap32IfLE(reasonLen);
-+ if ((reason = malloc(reasonLen)) != NULL &&
-+ ReadFromRFBServer(reason, reasonLen)) {
-+ int len = (int) reasonLen < sizeof(msgbuf) - 10 ? (int) reasonLen : sizeof(msgbuf) - 10;
-+ sprintf(msgbuf,"VNC connection failed: %.*s\n", len, reason);
-+ wmsg(msgbuf, 1);
-+ free(reason);
-+ return;
-+ }
-+ }
-
-- fprintf(stderr, "VNC connection failed\n");
-+ sprintf(msgbuf, "VNC connection failed\n");
-+ wmsg(msgbuf, 1);
-
-- if (reason != NULL)
-- free(reason);
-+ if (reason != NULL) {
-+ free(reason);
-+ }
- }
-
- /*
-@@ -1358,9 +3634,9 @@
- " %s significant bit in each byte is leftmost on the screen.\n",
- (format->bigEndian ? "Most" : "Least"));
- } else {
-- fprintf(stderr," %d bits per pixel.\n",format->bitsPerPixel);
-+ fprintf(stderr," %d bits per pixel. ",format->bitsPerPixel);
- if (format->bitsPerPixel != 8) {
-- fprintf(stderr," %s significant byte first in each pixel.\n",
-+ fprintf(stderr,"%s significant byte first in each pixel.\n",
- (format->bigEndian ? "Most" : "Least"));
- }
- if (format->trueColour) {
-@@ -1462,4 +3738,3 @@
-
- cinfo->src = &jpegSrcManager;
- }
--
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rre.c vnc_unixsrc/vncviewer/rre.c
---- vnc_unixsrc.orig/vncviewer/rre.c 2000-06-11 08:00:53.000000000 -0400
-+++ vnc_unixsrc/vncviewer/rre.c 2008-10-05 15:16:30.000000000 -0400
-@@ -29,6 +29,18 @@
- #define HandleRREBPP CONCAT2E(HandleRRE,BPP)
- #define CARDBPP CONCAT2E(CARD,BPP)
-
-+#define FillRectangle(x, y, w, h, color) \
-+ { \
-+ XGCValues _gcv; \
-+ _gcv.foreground = color; \
-+ if (!appData.useXserverBackingStore) { \
-+ FillScreen(x, y, w, h, _gcv.foreground); \
-+ } else { \
-+ XChangeGC(dpy, gc, GCForeground, &_gcv); \
-+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \
-+ } \
-+ }
-+
- static Bool
- HandleRREBPP (int rx, int ry, int rw, int rh)
- {
-@@ -49,11 +61,19 @@
- #if (BPP == 8)
- gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
- #else
-+#if (BPP == 16)
-+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix);
-+#else
- gcv.foreground = pix;
- #endif
-+#endif
-
-+#if 0
- XChangeGC(dpy, gc, GCForeground, &gcv);
- XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);
-+#else
-+ FillRectangle(rx, ry, rw, rh, gcv.foreground);
-+#endif
-
- for (i = 0; i < hdr.nSubrects; i++) {
- if (!ReadFromRFBServer((char *)&pix, sizeof(pix)))
-@@ -70,13 +90,23 @@
- #if (BPP == 8)
- gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
- #else
-+#if (BPP == 16)
-+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix);
-+#else
- gcv.foreground = pix;
- #endif
-+#endif
-
-+#if 0
- XChangeGC(dpy, gc, GCForeground, &gcv);
- XFillRectangle(dpy, desktopWin, gc, rx + subrect.x, ry + subrect.y,
- subrect.w, subrect.h);
-+#else
-+ FillRectangle(rx + subrect.x, ry + subrect.y, subrect.w, subrect.h, gcv.foreground);
-+#endif
- }
-
- return True;
- }
-+
-+#undef FillRectangle
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/selection.c vnc_unixsrc/vncviewer/selection.c
---- vnc_unixsrc.orig/vncviewer/selection.c 2004-03-03 04:11:52.000000000 -0500
-+++ vnc_unixsrc/vncviewer/selection.c 2010-02-25 23:28:48.000000000 -0500
-@@ -43,13 +43,16 @@
- unsigned long* length, int* format);
- static void LoseSelection(Widget w, Atom *selection);
-
--static Bool iAmSelectionOwner = False;
-+static Bool PrimarySelectionOwner = False;
-+static Bool ClipboardSelectionOwner = False;
- static Time prevSelectionTime = 0L;
- static Time cutBufferTime = 0L;
-
- #define TIME_LATER(a, b) ((a) != 0 && ((b) == 0 || (INT32)((a) - (b)) > 0))
-
-
-+static Atom clipboard_atom = None;
-+
- /*
- * InitialiseSelection() must be called after realizing widgets (because
- * otherwise XtGetSelectionValue() fails). We register events on the root
-@@ -62,22 +65,28 @@
- * available.
- */
-
--void
--InitialiseSelection()
--{
-+static int dbg_sel = -1;
-+
-+void InitialiseSelection() {
- #if XtSpecificationRelease >= 6
-- XtRegisterDrawable(dpy, DefaultRootWindow(dpy), toplevel);
-+ XtRegisterDrawable(dpy, DefaultRootWindow(dpy), toplevel);
- #else
-- _XtRegisterWindow(DefaultRootWindow(dpy), toplevel);
-+ _XtRegisterWindow(DefaultRootWindow(dpy), toplevel);
- #endif
-- XSelectInput(dpy, DefaultRootWindow(dpy), PropertyChangeMask);
-+ XSelectInput(dpy, DefaultRootWindow(dpy), PropertyChangeMask);
-
-- XtAddRawEventHandler(toplevel, PropertyChangeMask, False, CutBufferChange,
-- NULL);
-+ XtAddRawEventHandler(toplevel, PropertyChangeMask, False, CutBufferChange, NULL);
-
-- XtGetSelectionValue(toplevel, XA_PRIMARY,
-+ clipboard_atom = XInternAtom(dpy, "CLIPBOARD", False);
-+
-+ XtGetSelectionValue(toplevel, XA_PRIMARY,
- XInternAtom(dpy, "TIMESTAMP", False),
- GetInitialSelectionTimeCallback, NULL, CurrentTime);
-+
-+ if (dbg_sel < 0) {
-+ dbg_sel = 0;
-+ if (getenv("SSVNC_DEBUG_SELECTION")) dbg_sel = 1;
-+ }
- }
-
-
-@@ -93,13 +102,16 @@
- Atom* selection, Atom* type, XtPointer value,
- unsigned long* length, int* format)
- {
-- if (value && *format == 32 && *length == 1)
-- prevSelectionTime = *(CARD32 *)value;
-- else
-- prevSelectionTime = 0L;
--
-- if (value)
-- XtFree(value);
-+ if (value && *format == 32 && *length == 1) {
-+ prevSelectionTime = *(CARD32 *)value;
-+ } else {
-+ prevSelectionTime = 0L;
-+ }
-+
-+ if (value) {
-+ XtFree(value);
-+ }
-+ if (w || clientData || selection || type || value || length || format) {}
- }
-
-
-@@ -121,26 +133,30 @@
- void
- SelectionToVNC(Widget w, XEvent *event, String *params, Cardinal *num_params)
- {
-- Bool always = False;
-+ Bool always = appData.sendAlways;
-+ Atom sendsel = XA_PRIMARY;
-
-- if (*num_params != 0) {
-- if (strcmp(params[0],"always") == 0) {
-- always = True;
-- } else if (strcmp(params[0],"new") == 0) {
-- always = False;
-- } else {
-- fprintf(stderr,"Invalid params: SelectionToVNC(always|new)\n");
-- return;
-- }
-- }
--
-- if (always) {
-- XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, GetSelectionCallback, NULL,
-- TimeFromEvent(event));
-- } else {
-- XtGetSelectionValue(w, XA_PRIMARY, XInternAtom(dpy, "TIMESTAMP", False),
-- GetSelectionTimeCallback, NULL, TimeFromEvent(event));
-- }
-+ if (*num_params != 0) {
-+ if (strcmp(params[0],"always") == 0) {
-+ always = True;
-+ } else if (strcmp(params[0],"new") == 0) {
-+ always = False;
-+ } else {
-+ fprintf(stderr,"Invalid params: SelectionToVNC(always|new)\n");
-+ return;
-+ }
-+ }
-+ if (appData.sendClipboard && clipboard_atom != None) {
-+ sendsel = clipboard_atom;
-+ }
-+ if (dbg_sel) fprintf(stderr, "SelectionToVNC %s\n", sendsel == XA_PRIMARY ? "PRIMARY" : "CLIPBOARD");
-+
-+ if (always) {
-+ XtGetSelectionValue(w, sendsel, XA_STRING, GetSelectionCallback, NULL, TimeFromEvent(event));
-+ } else {
-+ XtGetSelectionValue(w, sendsel, XInternAtom(dpy, "TIMESTAMP", False), GetSelectionTimeCallback, NULL, TimeFromEvent(event));
-+ }
-+ if (w || event || params || num_params) {}
- }
-
-
-@@ -158,10 +174,13 @@
- int len = *length;
- char *str = (char *)value;
-
-- if (str)
-- SendClientCutText(str, len);
-- else
-- SendCutBuffer();
-+ if (str) {
-+ if (dbg_sel) fprintf(stderr, "SendClientCutText len: %d\n", len);
-+ SendClientCutText(str, len);
-+ } else if (!getenv("VNCVIEWER_NO_CUTBUFFER")) {
-+ SendCutBuffer();
-+ }
-+ if (w || clientData || selection || type || value || length || format) {}
- }
-
-
-@@ -180,26 +199,24 @@
- Atom* type, XtPointer value, unsigned long* length,
- int* format)
- {
-- if (value && *format == 32 && *length == 1) {
-+ if (value && *format == 32 && *length == 1) {
-+ Time t = *(CARD32 *)value;
-
-- Time t = *(CARD32 *)value;
--
-- if (TIME_LATER(t, prevSelectionTime)) {
-- prevSelectionTime = t;
-- XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, GetSelectionCallback, NULL,
-- CurrentTime);
-- }
--
-- } else {
--
-- if (TIME_LATER(cutBufferTime, prevSelectionTime)) {
-- prevSelectionTime = cutBufferTime;
-- SendCutBuffer();
-- }
-- }
--
-- if (value)
-- XtFree(value);
-+ if (TIME_LATER(t, prevSelectionTime)) {
-+ prevSelectionTime = t;
-+ XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, GetSelectionCallback, NULL, CurrentTime);
-+ }
-+ } else if (!getenv("VNCVIEWER_NO_CUTBUFFER")) {
-+ if (TIME_LATER(cutBufferTime, prevSelectionTime)) {
-+ prevSelectionTime = cutBufferTime;
-+ SendCutBuffer();
-+ }
-+ }
-+
-+ if (value) {
-+ XtFree(value);
-+ }
-+ if (w || clientData || selection || type || value || length || format) {}
- }
-
-
-@@ -209,16 +226,17 @@
- */
-
- static void
--SendCutBuffer()
--{
-- char *str;
-- int len;
-+SendCutBuffer() {
-+ char *str;
-+ int len;
-
-- str = XFetchBytes(dpy, &len);
-- if (!str) return;
-+ if (dbg_sel) fprintf(stderr, "SendCutBuffer len: %d\n", len);
-
-- SendClientCutText(str, len);
-- XFree(str);
-+ str = XFetchBytes(dpy, &len);
-+ if (!str) return;
-+
-+ SendClientCutText(str, len);
-+ XFree(str);
- }
-
-
-@@ -230,10 +248,12 @@
- static void
- CutBufferChange(Widget w, XtPointer ptr, XEvent *ev, Boolean *cont)
- {
-- if (ev->type != PropertyNotify || ev->xproperty.atom != XA_CUT_BUFFER0)
-- return;
-+ if (ev->type != PropertyNotify || ev->xproperty.atom != XA_CUT_BUFFER0) {
-+ return;
-+ }
-
-- cutBufferTime = ev->xproperty.time;
-+ cutBufferTime = ev->xproperty.time;
-+ if (w || ptr || cont) {}
- }
-
-
-@@ -249,36 +269,69 @@
- void
- SelectionFromVNC(Widget w, XEvent *event, String *params, Cardinal *num_params)
- {
-- Bool always = False;
-- Time t = TimeFromEvent(event);
--
-- if (*num_params != 0) {
-- if (strcmp(params[0],"always") == 0) {
-- always = True;
-- } else if (strcmp(params[0],"new") == 0) {
-- always = False;
-- } else {
-- fprintf(stderr,"Invalid params: SelectionFromVNC(always|new)\n");
-- return;
-- }
-- }
--
-- if (t == CurrentTime) {
-- fprintf(stderr,"Error in translations: SelectionFromVNC() must act on "
-- "event with time field\n");
-- return;
-- }
--
-- if (!serverCutText || (!always && !newServerCutText))
-- return;
--
-- newServerCutText = False;
--
-- XStoreBytes(dpy, serverCutText, strlen(serverCutText));
-- if (XtOwnSelection(desktop, XA_PRIMARY, t, ConvertSelection, LoseSelection,
-- NULL)) {
-- iAmSelectionOwner = True;
-- }
-+ Bool always = False;
-+ Time t = TimeFromEvent(event);
-+ int hold_primary = 0;
-+ int hold_clipboard = 0;
-+
-+ if (dbg_sel) fprintf(stderr, "SelectionFromVNC\n");
-+
-+ if (*num_params != 0) {
-+ if (strcmp(params[0],"always") == 0) {
-+ always = True;
-+ } else if (strcmp(params[0],"new") == 0) {
-+ always = False;
-+ } else {
-+ fprintf(stderr,"Invalid params: SelectionFromVNC(always|new)\n");
-+ return;
-+ }
-+ }
-+
-+ if (t == CurrentTime) {
-+ fprintf(stderr,"Error in translations: SelectionFromVNC() must act on "
-+ "event with time field\n");
-+ return;
-+ }
-+
-+ if (!serverCutText || (!always && !newServerCutText)) {
-+ return;
-+ }
-+
-+ newServerCutText = False;
-+
-+ if (appData.appShare) {
-+ if (strstr(serverCutText, "X11VNC_APPSHARE_CMD:") == serverCutText) {
-+ /* do something with it? */
-+ return;
-+ }
-+ }
-+
-+ XStoreBytes(dpy, serverCutText, strlen(serverCutText));
-+
-+ if (appData.recvText == NULL) {
-+ appData.recvText = strdup("both");
-+ }
-+ if (!strcasecmp(appData.recvText, "primary")) {
-+ hold_primary = 1;
-+ } else if (!strcasecmp(appData.recvText, "clipboard")) {
-+ hold_clipboard = 1;
-+ } else {
-+ hold_primary = hold_clipboard = 1;
-+ }
-+
-+ if (!hold_primary) {
-+ ;
-+ } else if (XtOwnSelection(desktop, XA_PRIMARY, t, ConvertSelection, LoseSelection, NULL)) {
-+ PrimarySelectionOwner = True;
-+ if (dbg_sel) fprintf(stderr, "Own PRIMARY\n");
-+ }
-+ if (!hold_clipboard || clipboard_atom == None) {
-+ ;
-+ } else if (XtOwnSelection(desktop, clipboard_atom, t, ConvertSelection, LoseSelection, NULL)) {
-+ ClipboardSelectionOwner = True;
-+ if (dbg_sel) fprintf(stderr, "Own CLIPBOARD\n");
-+ }
-+ if (w || event || params || num_params) {}
- }
-
-
-@@ -293,37 +346,36 @@
- XtPointer* value, unsigned long* length, int* format)
- {
-
-- if (*target == XA_STRING && serverCutText != NULL) {
-- *type = XA_STRING;
-- *length = strlen(serverCutText);
-- *value = (XtPointer)XtMalloc(*length);
-- memcpy((char*)*value, serverCutText, *length);
-- *format = 8;
-- return True;
-- }
-+ if (*target == XA_STRING && serverCutText != NULL) {
-+ *type = XA_STRING;
-+ *length = strlen(serverCutText);
-+ *value = (XtPointer)XtMalloc(*length);
-+ memcpy((char*)*value, serverCutText, *length);
-+ *format = 8;
-+ return True;
-+ }
-
-- if (XmuConvertStandardSelection(w, CurrentTime, selection, target, type,
-+ if (XmuConvertStandardSelection(w, CurrentTime, selection, target, type,
- (XPointer*)value, length, format)) {
-- if (*target == XInternAtom(dpy, "TARGETS", False)) {
-- /* add STRING to list of standard targets */
-- Atom* targetP;
-- Atom* std_targets = (Atom*)*value;
-- unsigned long std_length = *length;
--
-- *length = std_length + 1;
-- *value = (XtPointer)XtMalloc(sizeof(Atom)*(*length));
-- targetP = *(Atom**)value;
-- *targetP++ = XA_STRING;
-- memmove((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
-- XtFree((char*)std_targets);
-- *type = XA_ATOM;
-- *format = 32;
-- return True;
-- }
--
-- return True;
-- }
-- return False;
-+ if (*target == XInternAtom(dpy, "TARGETS", False)) {
-+ /* add STRING to list of standard targets */
-+ Atom* targetP;
-+ Atom* std_targets = (Atom*)*value;
-+ unsigned long std_length = *length;
-+
-+ *length = std_length + 1;
-+ *value = (XtPointer)XtMalloc(sizeof(Atom)*(*length));
-+ targetP = *(Atom**)value;
-+ *targetP++ = XA_STRING;
-+ memmove((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
-+ XtFree((char*)std_targets);
-+ *type = XA_ATOM;
-+ *format = 32;
-+ return True;
-+ }
-+ return True;
-+ }
-+ return False;
- }
-
-
-@@ -332,7 +384,13 @@
- */
-
- static void
--LoseSelection(Widget w, Atom *selection)
--{
-- iAmSelectionOwner = False;
-+LoseSelection(Widget w, Atom *selection) {
-+ if (*selection == XA_PRIMARY) {
-+ if (dbg_sel) fprintf(stderr, "lost PRIMARY\n");
-+ PrimarySelectionOwner = False;
-+ } else if (clipboard_atom != None && *selection == clipboard_atom) {
-+ if (dbg_sel) fprintf(stderr, "lost CLIPBOARD\n");
-+ ClipboardSelectionOwner = False;
-+ }
-+ if (w) {}
- }
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/shm.c vnc_unixsrc/vncviewer/shm.c
---- vnc_unixsrc.orig/vncviewer/shm.c 2000-06-11 08:00:53.000000000 -0400
-+++ vnc_unixsrc/vncviewer/shm.c 2010-02-25 23:40:58.000000000 -0500
-@@ -30,71 +30,113 @@
- static Bool caughtShmError = False;
- static Bool needShmCleanup = False;
-
--void
--ShmCleanup()
--{
-- fprintf(stderr,"ShmCleanup called\n");
-- if (needShmCleanup) {
-- shmdt(shminfo.shmaddr);
-- shmctl(shminfo.shmid, IPC_RMID, 0);
-- needShmCleanup = False;
-- }
-+static int ShmCreationXErrorHandler(Display *dpy, XErrorEvent *error) {
-+ caughtShmError = True;
-+ if (dpy || error) {}
-+ return 0;
- }
-
--static int
--ShmCreationXErrorHandler(Display *dpy, XErrorEvent *error)
--{
-- caughtShmError = True;
-- return 0;
-+void ShmDetach() {
-+ if (needShmCleanup) {
-+ XErrorHandler oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler);
-+ fprintf(stderr,"ShmDetach called.\n");
-+ XShmDetach(dpy, &shminfo);
-+ XSync(dpy, False);
-+ XSetErrorHandler(oldXErrorHandler);
-+ }
- }
-
--XImage *
--CreateShmImage()
--{
-- XImage *image;
-- XErrorHandler oldXErrorHandler;
--
-- if (!XShmQueryExtension(dpy))
-- return NULL;
--
-- image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &shminfo,
-- si.framebufferWidth, si.framebufferHeight);
-- if (!image) return NULL;
--
-- shminfo.shmid = shmget(IPC_PRIVATE,
-- image->bytes_per_line * image->height,
-- IPC_CREAT|0777);
-+void ShmCleanup() {
-+ if (needShmCleanup) {
-+ fprintf(stderr,"ShmCleanup called.\n");
-+ XSync(dpy, False);
-+ shmdt(shminfo.shmaddr);
-+ shmctl(shminfo.shmid, IPC_RMID, 0);
-
-- if (shminfo.shmid == -1) {
-- XDestroyImage(image);
-- return NULL;
-- }
--
-- shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
--
-- if (shminfo.shmaddr == (char *)-1) {
-- XDestroyImage(image);
-- shmctl(shminfo.shmid, IPC_RMID, 0);
-- return NULL;
-- }
-+ needShmCleanup = False;
-+ }
-+}
-
-- shminfo.readOnly = True;
-+Bool UsingShm() {
-+ return needShmCleanup;
-+}
-
-- oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler);
-- XShmAttach(dpy, &shminfo);
-- XSync(dpy, False);
-- XSetErrorHandler(oldXErrorHandler);
-+int scale_round(int len, double fac);
-+extern int scale_x, scale_y;
-+extern double scale_factor_x, scale_factor_y;
-
-- if (caughtShmError) {
-- XDestroyImage(image);
-- shmdt(shminfo.shmaddr);
-- shmctl(shminfo.shmid, IPC_RMID, 0);
-- return NULL;
-- }
-+XImage *
-+CreateShmImage(int do_ycrop)
-+{
-+ XImage *image;
-+ XErrorHandler oldXErrorHandler;
-+ int ymax = si.framebufferHeight;
-+ int xmax = si.framebufferWidth;
-+
-+ if (!XShmQueryExtension(dpy)) {
-+ return NULL;
-+ }
-+ if (!appData.useShm) {
-+ return NULL;
-+ }
-+ if (do_ycrop == -1) {
-+ /* kludge to test for shm prescence */
-+ return (XImage *) 0x1;
-+ }
-+
-+ if (do_ycrop) {
-+ ymax = appData.yCrop;
-+ }
-+
-+ if (scale_x > 0) {
-+ xmax = scale_round(xmax, scale_factor_x);
-+ ymax = scale_round(ymax, scale_factor_y);
-+ }
-+
-+ image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &shminfo, xmax, ymax);
-+ if (!image) {
-+ return NULL;
-+ }
-+
-+ shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT|0777);
-+
-+ if (shminfo.shmid == -1) {
-+ XDestroyImage(image);
-+ if (0) fprintf(stderr, "CreateShmImage: destroyed 'image' (1)\n");
-+ return NULL;
-+ }
-+
-+ shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
-+
-+ if (shminfo.shmaddr == (char *)-1) {
-+ XDestroyImage(image);
-+#if 0
-+ fprintf(stderr, "CreateShmImage: destroyed 'image' (2)\n");
-+#endif
-+ shmctl(shminfo.shmid, IPC_RMID, 0);
-+ return NULL;
-+ }
-+
-+ shminfo.readOnly = True;
-+
-+ oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler);
-+ XShmAttach(dpy, &shminfo);
-+ XSync(dpy, False);
-+ XSetErrorHandler(oldXErrorHandler);
-+
-+ if (caughtShmError) {
-+ XDestroyImage(image);
-+#if 0
-+ fprintf(stderr, "CreateShmImage: destroyed 'image' (3)\n");
-+#endif
-+ shmdt(shminfo.shmaddr);
-+ shmctl(shminfo.shmid, IPC_RMID, 0);
-+ return NULL;
-+ }
-
-- needShmCleanup = True;
-+ needShmCleanup = True;
-
-- fprintf(stderr,"Using shared memory PutImage\n");
-+ fprintf(stderr,"Using shared memory (PutImage ycrop=%d, Size %dx%d)\n", do_ycrop, xmax, ymax);
-
-- return image;
-+ return image;
- }
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/smake vnc_unixsrc/vncviewer/smake
---- vnc_unixsrc.orig/vncviewer/smake 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/smake 2007-02-19 12:28:05.000000000 -0500
-@@ -0,0 +1,11 @@
-+#!/bin/sh
-+
-+PATH=`pwd`/../..:/usr/sfw/bin:/usr/ccs/bin:$PATH
-+export PATH
-+if [ "X$1" != "X" ]; then
-+ "$@"
-+else
-+ make
-+ strip vncviewer
-+ ls -l vncviewer
-+fi
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncviewer/sockets.c
---- vnc_unixsrc.orig/vncviewer/sockets.c 2001-01-14 22:54:18.000000000 -0500
-+++ vnc_unixsrc/vncviewer/sockets.c 2010-04-18 11:41:07.000000000 -0400
-@@ -22,17 +22,31 @@
- */
-
- #include <unistd.h>
-+#include <time.h>
- #include <sys/socket.h>
- #include <errno.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <arpa/inet.h>
-+#include <sys/un.h>
- #include <netdb.h>
- #include <fcntl.h>
- #include <assert.h>
- #include <vncviewer.h>
-
-+#ifndef SOL_IPV6
-+#ifdef IPPROTO_IPV6
-+#define SOL_IPV6 IPPROTO_IPV6
-+#endif
-+#endif
-+
-+/* Solaris (sysv?) needs INADDR_NONE */
-+#ifndef INADDR_NONE
-+#define INADDR_NONE ((in_addr_t) 0xffffffff)
-+#endif
-+
- void PrintInHex(char *buf, int len);
-+extern void printChat(char *, Bool);
-
- Bool errorMessageOnReadFailure = True;
-
-@@ -56,31 +70,396 @@
- */
-
- static Bool rfbsockReady = False;
-+static Bool xfrsockReady = False;
-+static XtInputId rfbsockId = 0;
-+static XtInputId xfrsockId = 0;
-+static int do_rfbsockId = 0;
-+static int do_xfrsockId = 0;
-+
- static void
- rfbsockReadyCallback(XtPointer clientData, int *fd, XtInputId *id)
- {
-- rfbsockReady = True;
-- XtRemoveInput(*id);
-+ rfbsockReady = True;
-+#if 0
-+ XtRemoveInput(*id);
-+#endif
-+ XtRemoveInput(rfbsockId);
-+ if (do_xfrsockId) {
-+ XtRemoveInput(xfrsockId);
-+ }
-+ if (clientData || fd || id) {}
- }
-
- static void
--ProcessXtEvents()
-+xfrsockReadyCallback(XtPointer clientData, int *fd, XtInputId *id)
- {
-- rfbsockReady = False;
-- XtAppAddInput(appContext, rfbsock, (XtPointer)XtInputReadMask,
-- rfbsockReadyCallback, NULL);
-- while (!rfbsockReady) {
-- XtAppProcessEvent(appContext, XtIMAll);
-- }
-+ xfrsockReady = True;
-+ XtRemoveInput(xfrsockId);
-+ if (do_rfbsockId) {
-+ XtRemoveInput(rfbsockId);
-+ }
-+ if (clientData || fd || id) {}
-+}
-+
-+
-+extern int skip_XtUpdate;
-+extern int skip_XtUpdateAll;
-+extern int filexfer_sock, filexfer_listen;
-+extern time_t start_listen;
-+extern void CheckTextInput(void);
-+extern time_t last_filexfer;
-+
-+static char fxfer[65536];
-+int fxfer_size = 65536;
-+
-+int rfbsock_is_ready(void) {
-+ fd_set fds;
-+ struct timeval tv;
-+
-+ if (rfbsock < 0) {
-+ return 0;
-+ }
-+ FD_ZERO(&fds);
-+ FD_SET(rfbsock,&fds);
-+ tv.tv_sec = 0;
-+ tv.tv_usec = 0;
-+ if (select(rfbsock+1, &fds, NULL, NULL, &tv) > 0) {
-+ if (FD_ISSET(rfbsock, &fds)) {
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+time_t filexfer_start = 0;
-+
-+void CheckFileXfer() {
-+ fd_set fds;
-+ struct timeval tv;
-+ int i, icnt = 0, igot = 0, bytes0 = 0, bytes = 0, grace = 0, n, list = 0;
-+ int db = 0;
-+
-+ if (!appData.fileActive || (filexfer_sock < 0 && filexfer_listen < 0)) {
-+ return;
-+ }
-+
-+ if (filexfer_listen >= 0 && time(NULL) > start_listen + 30) {
-+ fprintf(stderr, "filexfer closing aging listen socket.\n");
-+ close(filexfer_listen);
-+ filexfer_listen = -1;
-+ return;
-+ }
-+if (0) fprintf(stderr, "In CheckFileXfer\n");
-+
-+ if (filexfer_listen >=0) {
-+ n = filexfer_listen;
-+ list = 1;
-+ } else {
-+ n = filexfer_sock;
-+ }
-+
-+ while (1) {
-+ icnt++;
-+ FD_ZERO(&fds);
-+ FD_SET(n,&fds);
-+ tv.tv_sec = 0;
-+ tv.tv_usec = 0;
-+ if (select(n+1, &fds, NULL, NULL, &tv) > 0) {
-+ if (FD_ISSET(n, &fds)) {
-+ if (list) {
-+ if (filexfer_sock >= 0) {
-+ fprintf(stderr, "filexfer close stale(?) filexfer_sock.\n");
-+ close(filexfer_sock);
-+ filexfer_sock = -1;
-+ }
-+ filexfer_sock = AcceptTcpConnection(filexfer_listen);
-+ if (filexfer_sock >= 0) {
-+ fprintf(stderr, "filexfer accept OK.\n");
-+ close(filexfer_listen);
-+ filexfer_listen = -1;
-+ filexfer_start = last_filexfer = time(NULL);
-+ } else {
-+ fprintf(stderr, "filexfer accept failed.\n");
-+ }
-+ break;
-+ } else {
-+ ssize_t rn;
-+ unsigned char hdr[12];
-+ unsigned int len;
-+ if (db) fprintf(stderr, "try read filexfer...\n");
-+ if (hdr || len || i) {}
-+#if 1
-+ rn = read(n, fxfer, 1*8192);
-+if (db) {
-+ int i;
-+ fprintf(stderr, "CFX HDR:");
-+ for (i=0; i < 12; i++) {
-+ fprintf(stderr, " %d", (int) fxfer[i]);
-+ }
-+ fprintf(stderr, " ?\n");
-+}
-+ if (0 || db) fprintf(stderr, "filexfer read[%d] %d.\n", icnt, rn);
-+ if (rn < 0) {
-+ fprintf(stderr, "filexfer bad read: %d\n", errno);
-+ break;
-+ } else if (rn == 0) {
-+ fprintf(stderr, "filexfer gone.\n");
-+ close(n);
-+ filexfer_sock = -1;
-+ last_filexfer = time(NULL);
-+#if 0
-+ fprintf(stderr, "last_filexfer-2a: %d\n", last_filexfer);
-+#endif
-+ appData.fileActive = False;
-+ SendFramebufferUpdateRequest(0, 0, 1, 1, False);
-+ return;
-+ } else if (rn > 0) {
-+ if (db > 1) write(2, fxfer, rn);
-+ if (db) fprintf(stderr, "\n");
-+ bytes += rn;
-+ last_filexfer = time(NULL);
-+#if 0
-+ fprintf(stderr, "last_filexfer-2b: %d\n", last_filexfer);
-+#endif
-+
-+ if (0) {
-+ /* WE TRY TO FIX THIS IN THE JAVA NOW */
-+ if (appData.ultraDSM) {
-+ unsigned char msg = rfbFileTransfer;
-+ unsigned char hdc = (unsigned char) fxfer[0];
-+ if (msg == hdc) {
-+ /* cross your fingers... */
-+ WriteExact(rfbsock, (char *)&msg, 1);
-+ }
-+ }
-+ }
-+ if (!WriteExact(rfbsock, fxfer, rn)) {
-+ return;
-+ }
-+ igot = 1;
-+ }
-+#else
-+ /* not working, not always 7 msg type. */
-+ rn = read(n, hdr, 12);
-+ if (db) fprintf(stderr, "filexfer read %d.\n", rn);
-+ if (rn == 0) {
-+ fprintf(stderr, "filexfer gone.\n");
-+ close(n);
-+ filexfer_sock = -1;
-+ last_filexfer = time(NULL);
-+ return;
-+ }
-+ if (rn == 12) {
-+ len = (hdr[8] << 24) | (hdr[9] << 16) | (hdr[10] << 8) | hdr[11];
-+ if (db) fprintf(stderr, "n=%d len=%d\n", rn, len);
-+ if (db > 1) write(2, hdr, rn);
-+ if (db) fprintf(stderr, "\n");
-+ WriteExact(rfbsock, hdr, rn);
-+ if (len > 0) {
-+ rn = read(len, fxfer, len);
-+ if (!WriteExact(rfbsock, fxfer, len)) {
-+ last_filexfer = time(NULL);
-+ return;
-+ }
-+ if (db > 1) write(2, fxfer, len);
-+ }
-+ if (db) fprintf(stderr, "\n");
-+ } else {
-+ if (db) fprintf(stderr, "bad rn: %d\n", rn);
-+ }
-+ igot = 1;
-+#endif
-+ }
-+ }
-+ } else {
-+ if (bytes >= 8192) {
-+ int ok = 0;
-+ if (bytes0 == 0) {
-+ ok = 1;
-+ } else if (bytes >= bytes0 + 12) {
-+ ok = 1;
-+ } else if (grace < 20) {
-+ ok = 1;
-+ }
-+ if (ok) {
-+ grace++;
-+ bytes0 = bytes;
-+#if 0
-+ fprintf(stderr, "grace: %d\n", grace);
-+ /* forgot that this is about... */
-+#endif
-+ usleep(10 * 1000);
-+ continue;
-+ }
-+ }
-+ break;
-+ }
-+ }
-+ if (igot) {
-+ last_filexfer = time(NULL);
-+#if 0
-+ fprintf(stderr, "last_filexfer-2c: %d\n", last_filexfer);
-+#endif
-+ }
-+#if 0
-+fprintf(stderr, "Out CheckFileXfer\n");
-+#endif
-+ return;
-+}
-+
-+static void check_term_chat(void) {
-+ fd_set fds;
-+ struct timeval tv;
-+ int i, igot = -1, n = fileno(stdin);
-+ char strs[100][512];
-+ char buf[rfbTextMaxSize];
-+
-+ for (i=0; i < 100; i++) {
-+ FD_ZERO(&fds);
-+ FD_SET(n,&fds);
-+ tv.tv_sec = 0;
-+ tv.tv_usec = 0;
-+ if (select(n+1, &fds, NULL, NULL, &tv) > 0) {
-+ if (FD_ISSET(n, &fds)) {
-+ fgets(strs[i], 512, stdin);
-+ igot = i;
-+ } else {
-+ break;
-+ }
-+ } else {
-+ break;
-+ }
-+ }
-+ buf[0] = '\0';
-+ for (i=0; i <= igot; i++) {
-+ if (strlen(buf) + strlen(strs[i]) < rfbTextMaxSize) {
-+ strcat(buf, strs[i]);
-+ } else {
-+ SendTextChat(buf);
-+ buf[0] = '0';
-+ }
-+ }
-+ if (buf[0] != '\0') {
-+ SendTextChat(buf);
-+ }
-+ if (igot >= 0) printChat("Send: ", False);
-+}
-+
-+static time_t time_mark;
-+extern int delay_filexfer;
-+#include <sys/stat.h>
-+
-+extern double start_time;
-+
-+void ProcessXtEvents()
-+{
-+ int db = 0;
-+ static int dyn = -1;
-+ static int chat_was_active = 0;
-+ int check_chat = 0;
-+
-+ if (dyn < 0) {
-+ struct stat sb;
-+ if (getenv("USER") && !strcmp(getenv("USER"), "runge")) {
-+ if (stat("/tmp/nodyn", &sb) == 0) {
-+ putenv("NOFTFBUPDATES=1");
-+ unlink("/tmp/nodyn");
-+ }
-+ }
-+ if (getenv("NOFTFBUPDATES")) {
-+ dyn = 0;
-+ } else {
-+ dyn = 1;
-+ }
-+ }
-+
-+#if 0
-+ if (0) fprintf(stderr, "ProcessXtEvents: %d %.4f\n", skip_XtUpdateAll, dnow() - start_time);
-+#endif
-+
-+ if (skip_XtUpdateAll) {
-+ return;
-+ }
-+
-+ /* text chat */
-+ if (appData.chatActive ) {
-+ check_chat = 1;
-+ } else if (chat_was_active) {
-+ static double last_check = 0.0;
-+ double now = dnow();
-+ if (now > last_check + 0.75) {
-+ check_chat = 1;
-+ last_check = now;
-+ }
-+ }
-+ if (check_chat) {
-+ if (appData.chatActive) {
-+ chat_was_active = 1;
-+ }
-+ if (!appData.termChat) {
-+ CheckTextInput();
-+ } else {
-+ check_term_chat();
-+ }
-+ }
-+
-+ if (skip_XtUpdate) {
-+ return;
-+ }
-+
-+ rfbsockReady = False;
-+ xfrsockReady = False;
-+ do_rfbsockId = 1;
-+ rfbsockId = XtAppAddInput(appContext, rfbsock, (XtPointer)XtInputReadMask,
-+ rfbsockReadyCallback, NULL);
-+
-+ do_xfrsockId = 0;
-+ if (filexfer_sock >= 0) {
-+ do_xfrsockId = 1;
-+ xfrsockId = XtAppAddInput(appContext, filexfer_sock, (XtPointer)XtInputReadMask,
-+ xfrsockReadyCallback, NULL);
-+ }
-+
-+ time_mark = time(NULL);
-+
-+ if (appData.fileActive) {
-+ static int first = 1;
-+ if (first) {
-+ fprintf(stderr, "PXT: dynamic fb updates during filexfer: %d\n", dyn);
-+ first = 0;
-+ }
-+ }
-+
-+ if (db) fprintf(stderr, "XtAppAddInput: ");
-+ while (!rfbsockReady && !xfrsockReady) {
-+ int w = si.framebufferWidth;
-+ int h = si.framebufferHeight;
-+ if (db) fprintf(stderr, ".");
-+ if (dyn && filexfer_sock >= 0 && time(NULL) > time_mark + delay_filexfer) {
-+ SendFramebufferUpdateRequest(0, 0, w, h, False);
-+ }
-+ XtAppProcessEvent(appContext, XtIMAll);
-+ }
-+ if (db) fprintf(stderr, " done. r: %d x: %d\n", rfbsockReady, xfrsockReady);
-+
-+ if (xfrsockReady) {
-+ CheckFileXfer();
-+ }
- }
-
- Bool
- ReadFromRFBServer(char *out, unsigned int n)
- {
-+#if 0
-+ double start = dnow(), dn = n;
-+#endif
- if (n <= buffered) {
- memcpy(out, bufoutptr, n);
- bufoutptr += n;
- buffered -= n;
-+#if 0
-+fprintf(stderr, "R0: %06d\n", (int) dn);
-+#endif
- return True;
- }
-
-@@ -119,6 +498,9 @@
- memcpy(out, bufoutptr, n);
- bufoutptr += n;
- buffered -= n;
-+#if 0
-+fprintf(stderr, "R1: %06d %06d %10.2f KB/sec\n", (int) dn, buffered+n, 1e-3 * (buffered+n)/(dnow() - start));
-+#endif
- return True;
-
- } else {
-@@ -146,11 +528,16 @@
- n -= i;
- }
-
-+#if 0
-+fprintf(stderr, "R2: %06d %06d %10.2f KB/sec\n", (int) dn, (int) dn, 1e-3 * (dn)/(dnow() - start));
-+#endif
- return True;
- }
- }
-
-
-+int currentMsg = -1;
-+
- /*
- * Write an exact number of bytes, and don't return until you've sent them.
- */
-@@ -158,81 +545,321 @@
- Bool
- WriteExact(int sock, char *buf, int n)
- {
-- fd_set fds;
-- int i = 0;
-- int j;
--
-- while (i < n) {
-- j = write(sock, buf + i, (n - i));
-- if (j <= 0) {
-- if (j < 0) {
-- if (errno == EWOULDBLOCK || errno == EAGAIN) {
-- FD_ZERO(&fds);
-- FD_SET(rfbsock,&fds);
-+ fd_set fds;
-+ int i = 0;
-+ int j;
-+
-+ if (appData.ultraDSM && currentMsg >= 0) {
-+ /* this is for goofy UltraVNC DSM send RFB msg char twice: */
-+ unsigned char msg = (unsigned char) currentMsg;
-+ currentMsg = -1;
-+ if (!WriteExact(sock, (char *)&msg, sizeof(msg))) {
-+ return False;
-+ }
-+ }
-+ currentMsg = -1;
-
-- if (select(rfbsock+1, NULL, &fds, NULL, NULL) <= 0) {
-- fprintf(stderr,programName);
-- perror(": select");
-- return False;
-- }
-- j = 0;
-- } else {
-- fprintf(stderr,programName);
-- perror(": write");
-- return False;
-+ while (i < n) {
-+ j = write(sock, buf + i, (n - i));
-+ if (j <= 0) {
-+ if (j < 0) {
-+ if (errno == EWOULDBLOCK || errno == EAGAIN) {
-+ FD_ZERO(&fds);
-+ FD_SET(rfbsock,&fds);
-+
-+ if (select(rfbsock+1, NULL, &fds, NULL, NULL) <= 0) {
-+ fprintf(stderr,programName);
-+ perror(": select");
-+ return False;
-+ }
-+ j = 0;
-+ } else {
-+ fprintf(stderr,programName);
-+ perror(": write");
-+ return False;
-+ }
-+ } else {
-+ fprintf(stderr,"%s: write failed\n",programName);
-+ return False;
-+ }
-+ }
-+ i += j;
- }
-- } else {
-- fprintf(stderr,"%s: write failed\n",programName);
-- return False;
-- }
-- }
-- i += j;
-- }
-- return True;
-+ return True;
- }
-
-+int
-+ConnectToUnixSocket(char *file) {
-+ int sock;
-+ struct sockaddr_un addr;
-+ int i;
-+
-+ memset(&addr, 0, sizeof(struct sockaddr_un));
-+
-+ addr.sun_family = AF_UNIX;
-+
-+ for (i=0; i < 108; i++) {
-+ addr.sun_path[i] = file[i];
-+ if (file[i] == '\0') {
-+ break;
-+ }
-+ }
-+
-+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
-+ if (sock < 0) {
-+ fprintf(stderr,programName);
-+ perror(": ConnectToUnixSocket: socket");
-+ return -1;
-+ }
-+
-+ if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-+ fprintf(stderr, programName);
-+ perror(": ConnectToUnixSocket: connect");
-+ close(sock);
-+ return -1;
-+ }
-+
-+ return sock;
-+}
-+
-+char *ipv6_getipaddr(struct sockaddr *paddr, int addrlen) {
-+#if defined(AF_INET6) && defined(NI_NUMERICHOST)
-+ char name[200];
-+ if (appData.noipv6) {
-+ return strdup("unknown");
-+ }
-+ if (getnameinfo(paddr, addrlen, name, sizeof(name), NULL, 0, NI_NUMERICHOST) == 0) {
-+ return strdup(name);
-+ }
-+#endif
-+ if (paddr || addrlen) {}
-+ return strdup("unknown");
-+}
-+
-+char *ipv6_getnameinfo(struct sockaddr *paddr, int addrlen) {
-+#if defined(AF_INET6)
-+ char name[200];
-+ if (appData.noipv6) {
-+ return strdup("unknown");
-+ }
-+ if (getnameinfo(paddr, addrlen, name, sizeof(name), NULL, 0, 0) == 0) {
-+ return strdup(name);
-+ }
-+#endif
-+ if (paddr || addrlen) {}
-+ return strdup("unknown");
-+}
-+
-+int dotted_ip(char *host, int partial) {
-+ int len, dots = 0;
-+ char *p = host;
-+
-+ if (!host) {
-+ return 0;
-+ }
-+
-+ if (!isdigit((unsigned char) host[0])) {
-+ return 0;
-+ }
-+
-+ len = strlen(host);
-+ if (!partial && !isdigit((unsigned char) host[len-1])) {
-+ return 0;
-+ }
-+
-+ while (*p != '\0') {
-+ if (*p == '.') dots++;
-+ if (*p == '.' || isdigit((unsigned char) (*p))) {
-+ p++;
-+ continue;
-+ }
-+ return 0;
-+ }
-+ if (!partial && dots != 3) {
-+ return 0;
-+ }
-+ return 1;
-+}
-
- /*
- * ConnectToTcpAddr connects to the given TCP port.
- */
-
--int
--ConnectToTcpAddr(unsigned int host, int port)
--{
-- int sock;
-- struct sockaddr_in addr;
-- int one = 1;
--
-- addr.sin_family = AF_INET;
-- addr.sin_port = htons(port);
-- addr.sin_addr.s_addr = host;
-+int ConnectToTcpAddr(const char *hostname, int port) {
-+ int sock = -1, one = 1;
-+ unsigned int host;
-+ struct sockaddr_in addr;
-+
-+ if (appData.noipv4) {
-+ fprintf(stderr, "ipv4 is disabled via VNCVIEWER_NO_IPV4/-noipv4.\n");
-+ goto try6;
-+ }
-
-- sock = socket(AF_INET, SOCK_STREAM, 0);
-- if (sock < 0) {
-- fprintf(stderr,programName);
-- perror(": ConnectToTcpAddr: socket");
-- return -1;
-- }
-+ if (!StringToIPAddr(hostname, &host)) {
-+ fprintf(stderr, "Could not convert '%s' to ipv4 host address.\n", hostname);
-+ goto try6;
-+ }
-
-- if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-- fprintf(stderr,programName);
-- perror(": ConnectToTcpAddr: connect");
-- close(sock);
-- return -1;
-- }
-+ memset(&addr, 0, sizeof(struct sockaddr_in));
-
-- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
-- (char *)&one, sizeof(one)) < 0) {
-- fprintf(stderr,programName);
-- perror(": ConnectToTcpAddr: setsockopt");
-- close(sock);
-- return -1;
-- }
-+ addr.sin_family = AF_INET;
-+ addr.sin_port = htons(port);
-+ addr.sin_addr.s_addr = host;
-+
-+ sock = socket(AF_INET, SOCK_STREAM, 0);
-+ if (sock < 0) {
-+ perror("ConnectToTcpAddr[ipv4]: socket");
-+ sock = -1;
-+ goto try6;
-+ }
-+
-+ if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-+ perror("ConnectToTcpAddr[ipv4]: connect");
-+ close(sock);
-+ sock = -1;
-+ goto try6;
-+ }
-+
-+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) {
-+ perror("ConnectToTcpAddr[ipv4]: setsockopt");
-+ close(sock);
-+ sock = -1;
-+ goto try6;
-+ }
-
-- return sock;
-+ if (sock >= 0) {
-+ return sock;
-+ }
-+
-+ try6:
-+
-+#ifdef AF_INET6
-+ if (!appData.noipv6) {
-+ int err;
-+ struct addrinfo *ai;
-+ struct addrinfo hints;
-+ char service[32], *host2, *q;
-+
-+ fprintf(stderr, "Trying ipv6 connection to '%s'\n", hostname);
-+
-+ memset(&hints, 0, sizeof(hints));
-+ sprintf(service, "%d", port);
-+
-+ hints.ai_family = AF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+#ifdef AI_ADDRCONFIG
-+ hints.ai_flags |= AI_ADDRCONFIG;
-+#endif
-+#ifdef AI_NUMERICSERV
-+ hints.ai_flags |= AI_NUMERICSERV;
-+#endif
-+ if (!strcmp(hostname, "localhost")) {
-+ host2 = strdup("::1");
-+ } else if (!strcmp(hostname, "127.0.0.1")) {
-+ host2 = strdup("::1");
-+ } else if (hostname[0] == '[') {
-+ host2 = strdup(hostname+1);
-+ } else {
-+ host2 = strdup(hostname);
-+ }
-+ q = strrchr(host2, ']');
-+ if (q) {
-+ *q = '\0';
-+ }
-+
-+ err = getaddrinfo(host2, service, &hints, &ai);
-+ if (err != 0) {
-+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: getaddrinfo[%d]: %s\n", err, gai_strerror(err));
-+ usleep(100 * 1000);
-+ err = getaddrinfo(host2, service, &hints, &ai);
-+ }
-+ free(host2);
-+
-+ if (err != 0) {
-+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: getaddrinfo[%d]: %s (2nd try)\n", err, gai_strerror(err));
-+ } else {
-+ struct addrinfo *ap = ai;
-+ while (ap != NULL) {
-+ int fd = -1;
-+ char *s = ipv6_getipaddr(ap->ai_addr, ap->ai_addrlen);
-+ if (s) {
-+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: trying ip-addr: '%s'\n", s);
-+ free(s);
-+ }
-+ if (appData.noipv4) {
-+ struct sockaddr_in6 *s6ptr;
-+ if (ap->ai_family != AF_INET6) {
-+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: skipping AF_INET address under VNCVIEWER_NO_IPV4/-noipv4\n");
-+ ap = ap->ai_next;
-+ continue;
-+ }
-+#ifdef IN6_IS_ADDR_V4MAPPED
-+ s6ptr = (struct sockaddr_in6 *) ap->ai_addr;
-+ if (IN6_IS_ADDR_V4MAPPED(&(s6ptr->sin6_addr))) {
-+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: skipping V4MAPPED address under VNCVIEWER_NO_IPV4/-noipv4\n");
-+ ap = ap->ai_next;
-+ continue;
-+ }
-+#endif
-+ }
-+
-+ fd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
-+ if (fd == -1) {
-+ perror("ConnectToTcpAddr[ipv6]: socket");
-+ } else {
-+ int dmsg = 0;
-+ int res = connect(fd, ap->ai_addr, ap->ai_addrlen);
-+#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
-+ if (res != 0) {
-+ int zero = 0;
-+ perror("ConnectToTcpAddr[ipv6]: connect");
-+ dmsg = 1;
-+ if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, (char *)&zero, sizeof(zero)) == 0) {
-+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: trying again with IPV6_V6ONLY=0\n");
-+ res = connect(fd, ap->ai_addr, ap->ai_addrlen);
-+ dmsg = 0;
-+ }
-+ }
-+#endif
-+ if (res == 0) {
-+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: connect OK\n");
-+ sock = fd;
-+ break;
-+ } else {
-+ if (!dmsg) perror("ConnectToTcpAddr[ipv6]: connect");
-+ close(fd);
-+ }
-+ }
-+ ap = ap->ai_next;
-+ }
-+ freeaddrinfo(ai);
-+ }
-+ if (sock >= 0 && setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) {
-+ perror("ConnectToTcpAddr: setsockopt");
-+ close(sock);
-+ sock = -1;
-+ }
-+ }
-+#endif
-+ return sock;
- }
-
-+Bool SocketPair(int fd[2]) {
-+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, fd) == -1) {
-+ perror("socketpair");
-+ return False;
-+ }
-+ return True;
-+}
-
-+Bool SetNoDelay(int sock) {
-+ const int one = 1;
-+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) {
-+ perror("setsockopt");
-+ return False;
-+ }
-+ return True;
-+}
-
- /*
- * FindFreeTcpPort tries to find unused TCP port in the range
-@@ -242,29 +869,31 @@
- int
- FindFreeTcpPort(void)
- {
-- int sock, port;
-- struct sockaddr_in addr;
-+ int sock, port;
-+ struct sockaddr_in addr;
-
-- addr.sin_family = AF_INET;
-- addr.sin_addr.s_addr = INADDR_ANY;
-+ memset(&addr, 0, sizeof(struct sockaddr_in));
-
-- sock = socket(AF_INET, SOCK_STREAM, 0);
-- if (sock < 0) {
-- fprintf(stderr,programName);
-- perror(": FindFreeTcpPort: socket");
-- return 0;
-- }
-+ addr.sin_family = AF_INET;
-+ addr.sin_addr.s_addr = INADDR_ANY;
-
-- for (port = TUNNEL_PORT_OFFSET + 99; port > TUNNEL_PORT_OFFSET; port--) {
-- addr.sin_port = htons((unsigned short)port);
-- if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
-- close(sock);
-- return port;
-- }
-- }
-+ sock = socket(AF_INET, SOCK_STREAM, 0);
-+ if (sock < 0) {
-+ fprintf(stderr,programName);
-+ perror(": FindFreeTcpPort: socket");
-+ return 0;
-+ }
-+
-+ for (port = TUNNEL_PORT_OFFSET + 99; port > TUNNEL_PORT_OFFSET; port--) {
-+ addr.sin_port = htons((unsigned short)port);
-+ if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
-+ close(sock);
-+ return port;
-+ }
-+ }
-
-- close(sock);
-- return 0;
-+ close(sock);
-+ return 0;
- }
-
-
-@@ -272,47 +901,110 @@
- * ListenAtTcpPort starts listening at the given TCP port.
- */
-
--int
--ListenAtTcpPort(int port)
--{
-- int sock;
-- struct sockaddr_in addr;
-- int one = 1;
--
-- addr.sin_family = AF_INET;
-- addr.sin_port = htons(port);
-- addr.sin_addr.s_addr = INADDR_ANY;
-+int use_loopback = 0;
-
-- sock = socket(AF_INET, SOCK_STREAM, 0);
-- if (sock < 0) {
-- fprintf(stderr,programName);
-- perror(": ListenAtTcpPort: socket");
-- return -1;
-- }
-+int ListenAtTcpPort(int port) {
-+ int sock;
-+ struct sockaddr_in addr;
-+ int one = 1;
-+
-+ if (appData.noipv4) {
-+ fprintf(stderr, "ipv4 is disabled via VNCVIEWER_NO_IPV4/-noipv4.\n");
-+ return -1;
-+ }
-
-- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
-- (const char *)&one, sizeof(one)) < 0) {
-- fprintf(stderr,programName);
-- perror(": ListenAtTcpPort: setsockopt");
-- close(sock);
-- return -1;
-- }
-+ memset(&addr, 0, sizeof(struct sockaddr_in));
-
-- if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-- fprintf(stderr,programName);
-- perror(": ListenAtTcpPort: bind");
-- close(sock);
-- return -1;
-- }
-+ addr.sin_family = AF_INET;
-+ addr.sin_port = htons(port);
-+ addr.sin_addr.s_addr = INADDR_ANY;
-
-- if (listen(sock, 5) < 0) {
-- fprintf(stderr,programName);
-- perror(": ListenAtTcpPort: listen");
-- close(sock);
-- return -1;
-- }
-+ if (getenv("VNCVIEWER_LISTEN_LOCALHOST") || use_loopback) {
-+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-+ }
-+
-+ sock = socket(AF_INET, SOCK_STREAM, 0);
-+ if (sock < 0) {
-+ perror("ListenAtTcpPort: socket");
-+ return -1;
-+ }
-
-- return sock;
-+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one)) < 0) {
-+ perror("ListenAtTcpPort: setsockopt");
-+ close(sock);
-+ return -1;
-+ }
-+
-+ if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-+ perror("ListenAtTcpPort: bind");
-+ close(sock);
-+ return -1;
-+ }
-+
-+ if (listen(sock, 32) < 0) {
-+ perror("ListenAtTcpPort: listen");
-+ close(sock);
-+ return -1;
-+ }
-+
-+ return sock;
-+}
-+
-+int ListenAtTcpPort6(int port) {
-+ int sock = -1;
-+#ifdef AF_INET6
-+ struct sockaddr_in6 sin;
-+ int one = 1;
-+
-+ if (appData.noipv6) {
-+ fprintf(stderr, "ipv6 is disabled via VNCVIEWER_NO_IPV6/-noipv6.\n");
-+ return -1;
-+ }
-+
-+ sock = socket(AF_INET6, SOCK_STREAM, 0);
-+ if (sock < 0) {
-+ perror("ListenAtTcpPort[ipv6]: socket");
-+ return -1;
-+ }
-+
-+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
-+ perror("ListenAtTcpPort[ipv6]: setsockopt1");
-+ close(sock);
-+ return -1;
-+ }
-+
-+#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
-+ if (setsockopt(sock, SOL_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
-+ perror("ListenAtTcpPort[ipv6]: setsockopt2");
-+ close(sock);
-+ return -1;
-+ }
-+#endif
-+
-+ memset((char *)&sin, 0, sizeof(sin));
-+ sin.sin6_family = AF_INET6;
-+ sin.sin6_port = htons(port);
-+ sin.sin6_addr = in6addr_any;
-+
-+ if (getenv("VNCVIEWER_LISTEN_LOCALHOST") || use_loopback) {
-+ sin.sin6_addr = in6addr_loopback;
-+ }
-+
-+ if (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
-+ perror("ListenAtTcpPort[ipv6]: bind");
-+ close(sock);
-+ return -1;
-+ }
-+
-+ if (listen(sock, 32) < 0) {
-+ perror("ListenAtTcpPort[ipv6]: listen");
-+ close(sock);
-+ return -1;
-+ }
-+
-+#endif
-+ if (port) {}
-+ return sock;
- }
-
-
-@@ -320,33 +1012,69 @@
- * AcceptTcpConnection accepts a TCP connection.
- */
-
--int
--AcceptTcpConnection(int listenSock)
--{
-- int sock;
-- struct sockaddr_in addr;
-- int addrlen = sizeof(addr);
-- int one = 1;
-+int AcceptTcpConnection(int listenSock) {
-+ int sock;
-+ struct sockaddr_in addr;
-+ int addrlen = sizeof(addr);
-+ int one = 1;
-+
-+ sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen);
-+ if (sock < 0) {
-+ perror("AcceptTcpConnection: accept");
-+ return -1;
-+ }
-
-- sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen);
-- if (sock < 0) {
-- fprintf(stderr,programName);
-- perror(": AcceptTcpConnection: accept");
-- return -1;
-- }
-+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) {
-+ perror("AcceptTcpConnection: setsockopt");
-+ close(sock);
-+ return -1;
-+ }
-
-- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
-- (char *)&one, sizeof(one)) < 0) {
-- fprintf(stderr,programName);
-- perror(": AcceptTcpConnection: setsockopt");
-- close(sock);
-- return -1;
-- }
-+ return sock;
-+}
-+
-+char *accept6_ipaddr = NULL;
-+char *accept6_hostname = NULL;
-+
-+int AcceptTcpConnection6(int listenSock) {
-+ int sock = -1;
-+#ifdef AF_INET6
-+ struct sockaddr_in6 addr;
-+ socklen_t addrlen = sizeof(addr);
-+ int one = 1;
-+ char *name;
-+
-+ if (appData.noipv6) {
-+ return -1;
-+ }
-+
-+ sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen);
-+ if (sock < 0) {
-+ perror("AcceptTcpConnection[ipv6]: accept");
-+ return -1;
-+ }
-+
-+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) {
-+ perror("AcceptTcpConnection[ipv6]: setsockopt");
-+ close(sock);
-+ return -1;
-+ }
-
-- return sock;
-+ name = ipv6_getipaddr((struct sockaddr *) &addr, addrlen);
-+ if (!name) name = strdup("unknown");
-+ accept6_ipaddr = name;
-+ fprintf(stderr, "AcceptTcpConnection6: ipv6 connection from: '%s'\n", name);
-+
-+ name = ipv6_getnameinfo((struct sockaddr *) &addr, addrlen);
-+ if (!name) name = strdup("unknown");
-+ accept6_hostname = name;
-+#endif
-+ if (listenSock) {}
-+ return sock;
- }
-
-
-+
- /*
- * SetNonBlocking sets a socket into non-blocking mode.
- */
-@@ -379,7 +1107,7 @@
-
- *addr = inet_addr(str);
-
-- if (*addr != -1)
-+ if (*addr != (unsigned int) -1)
- return True;
-
- hp = gethostbyname(str);
-@@ -392,6 +1120,42 @@
- return False;
- }
-
-+char *get_peer_ip(int sock) {
-+ struct sockaddr_in saddr;
-+ unsigned int saddr_len;
-+ int saddr_port;
-+ char *saddr_ip_str = NULL;
-+
-+ saddr_len = sizeof(saddr);
-+ memset(&saddr, 0, sizeof(saddr));
-+ saddr_port = -1;
-+ if (!getpeername(sock, (struct sockaddr *)&saddr, &saddr_len)) {
-+ saddr_ip_str = inet_ntoa(saddr.sin_addr);
-+ }
-+ if (! saddr_ip_str) {
-+ saddr_ip_str = "unknown";
-+ }
-+ return strdup(saddr_ip_str);
-+}
-+
-+char *ip2host(char *ip) {
-+ char *str;
-+ struct hostent *hp;
-+ in_addr_t iaddr;
-+
-+ iaddr = inet_addr(ip);
-+ if (iaddr == htonl(INADDR_NONE)) {
-+ return strdup("unknown");
-+ }
-+
-+ hp = gethostbyaddr((char *)&iaddr, sizeof(in_addr_t), AF_INET);
-+ if (!hp) {
-+ return strdup("unknown");
-+ }
-+ str = strdup(hp->h_name);
-+ return str;
-+}
-+
-
- /*
- * Test if the other end of a socket is on the same machine.
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tight.c vnc_unixsrc/vncviewer/tight.c
---- vnc_unixsrc.orig/vncviewer/tight.c 2002-04-30 09:07:31.000000000 -0400
-+++ vnc_unixsrc/vncviewer/tight.c 2008-10-05 15:16:35.000000000 -0400
-@@ -129,14 +129,21 @@
- #endif
-
- #if (BPP == 8)
-- gcv.foreground = (appData.useBGR233) ?
-- BGR233ToPixel[fill_colour] : fill_colour;
-+ gcv.foreground = (appData.useBGR233) ? BGR233ToPixel[fill_colour] : fill_colour;
-+#else
-+#if (BPP == 16)
-+ gcv.foreground = (appData.useBGR565) ? BGR565ToPixel[fill_colour] : fill_colour;
- #else
- gcv.foreground = fill_colour;
- #endif
-+#endif
-
-- XChangeGC(dpy, gc, GCForeground, &gcv);
-- XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);
-+ if (!appData.useXserverBackingStore) {
-+ FillScreen(rx, ry, rw, rh, gcv.foreground);
-+ } else {
-+ XChangeGC(dpy, gc, GCForeground, &gcv);
-+ XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);
-+ }
- return True;
- }
-
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tmake vnc_unixsrc/vncviewer/tmake
---- vnc_unixsrc.orig/vncviewer/tmake 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/tmake 2009-10-25 10:31:22.000000000 -0400
-@@ -0,0 +1,17 @@
-+#!/bin/sh
-+TURBOVNC_DIR=/home/runge/turbojpeg
-+make clean
-+(cd ../libvncauth || exit 1; make)
-+if [ "X$1" = "X-a" ]; then
-+ exit
-+fi
-+make CCOPTIONS=-DTURBOVNC EXTRA_LIBRARIES="-L$TURBOVNC_DIR -Xlinker --rpath=$TURBOVNC_DIR -Xlinker --rpath=/usr/local/lib -lturbojpeg"
-+cp -p vncviewer vncviewer.turbovnc
-+strip vncviewer.turbovnc
-+ls -l vncviewer.turbovnc
-+ldd vncviewer.turbovnc
-+
-+echo
-+make clean all
-+ls -l vncviewer
-+ldd vncviewer
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tunnel.c vnc_unixsrc/vncviewer/tunnel.c
---- vnc_unixsrc.orig/vncviewer/tunnel.c 2003-07-31 04:03:49.000000000 -0400
-+++ vnc_unixsrc/vncviewer/tunnel.c 2010-02-25 23:39:24.000000000 -0500
-@@ -100,7 +100,6 @@
- int *pargc, char **argv, int tunnelArgIndex)
- {
- char *pdisplay;
-- int port;
-
- if (tunnelArgIndex >= *pargc - 1)
- usage();
-@@ -132,6 +131,7 @@
- {
- char *colonPos;
- int len, portOffset;
-+ int disp;
-
- if (tunnelArgIndex >= *pargc - 2)
- usage();
-@@ -150,10 +150,17 @@
- len--;
- portOffset = 0;
- }
-- if (!len || strspn(colonPos, "-0123456789") != len) {
-+ if (!len || (int) strspn(colonPos, "-0123456789") != len) {
- usage();
- }
-+#if 0
- *remotePort = atoi(colonPos) + portOffset;
-+#else
-+ disp = atoi(colonPos);
-+ if (portOffset != 0 && disp >= 100)
-+ portOffset = 0;
-+ *remotePort = disp + portOffset;
-+#endif
- }
-
- sprintf(lastArgv, "localhost::%d", localPort);
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/turbovnc/tight.c vnc_unixsrc/vncviewer/turbovnc/tight.c
---- vnc_unixsrc.orig/vncviewer/turbovnc/tight.c 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/turbovnc/tight.c 2008-08-20 13:35:58.000000000 -0400
-@@ -0,0 +1,613 @@
-+/*
-+ * Copyright (C) 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
-+ * Copyright (C) 2004 Landmark Graphics Corporation. All Rights Reserved.
-+ * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
-+ *
-+ * This is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this software; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ */
-+
-+/*
-+ * tight.c - handle ``tight'' encoding.
-+ *
-+ * This file shouldn't be compiled directly. It is included multiple
-+ * times by rfbproto.c, each time with a different definition of the
-+ * macro BPP. For each value of BPP, this file defines a function
-+ * which handles a tight-encoded rectangle with BPP bits per pixel.
-+ *
-+ */
-+
-+#define TIGHT_MIN_TO_COMPRESS 12
-+
-+#define CARDBPP CONCAT2E(CARD,BPP)
-+#define filterPtrBPP CONCAT2E(filterPtr,BPP)
-+
-+#define HandleTightBPP CONCAT2E(HandleTight,BPP)
-+#define InitFilterCopyBPP CONCAT2E(InitFilterCopy,BPP)
-+#define InitFilterPaletteBPP CONCAT2E(InitFilterPalette,BPP)
-+#define InitFilterGradientBPP CONCAT2E(InitFilterGradient,BPP)
-+#define FilterCopyBPP CONCAT2E(FilterCopy,BPP)
-+#define FilterPaletteBPP CONCAT2E(FilterPalette,BPP)
-+#define FilterGradientBPP CONCAT2E(FilterGradient,BPP)
-+
-+#if BPP != 8
-+#define DecompressJpegRectBPP CONCAT2E(DecompressJpegRect,BPP)
-+#endif
-+
-+#ifndef RGB_TO_PIXEL
-+
-+#define RGB_TO_PIXEL(bpp,r,g,b) \
-+ (((CARD##bpp)(r) & myFormat.redMax) << myFormat.redShift | \
-+ ((CARD##bpp)(g) & myFormat.greenMax) << myFormat.greenShift | \
-+ ((CARD##bpp)(b) & myFormat.blueMax) << myFormat.blueShift)
-+
-+#define RGB24_TO_PIXEL(bpp,r,g,b) \
-+ ((((CARD##bpp)(r) & 0xFF) * myFormat.redMax + 127) / 255 \
-+ << myFormat.redShift | \
-+ (((CARD##bpp)(g) & 0xFF) * myFormat.greenMax + 127) / 255 \
-+ << myFormat.greenShift | \
-+ (((CARD##bpp)(b) & 0xFF) * myFormat.blueMax + 127) / 255 \
-+ << myFormat.blueShift)
-+
-+#define RGB24_TO_PIXEL32(r,g,b) \
-+ (((CARD32)(r) & 0xFF) << myFormat.redShift | \
-+ ((CARD32)(g) & 0xFF) << myFormat.greenShift | \
-+ ((CARD32)(b) & 0xFF) << myFormat.blueShift)
-+
-+#endif
-+
-+extern XImage *image;
-+
-+/* Type declarations */
-+
-+typedef void (*filterPtrBPP)(int, int, int);
-+
-+/* Prototypes */
-+
-+static int InitFilterCopyBPP (int rw, int rh);
-+static int InitFilterPaletteBPP (int rw, int rh);
-+static int InitFilterGradientBPP (int rw, int rh);
-+static void FilterCopyBPP (int srcx, int srcy, int numRows);
-+static void FilterPaletteBPP (int srcx, int srcy, int numRows);
-+static void FilterGradientBPP (int srcx, int srcy, int numRows);
-+
-+static Bool DecompressJpegRectBPP(int x, int y, int w, int h);
-+
-+/* Definitions */
-+
-+static Bool
-+HandleTightBPP (int rx, int ry, int rw, int rh)
-+{
-+ CARDBPP fill_colour;
-+ XGCValues gcv;
-+ CARD8 comp_ctl;
-+ CARD8 filter_id;
-+ filterPtrBPP filterFn;
-+ z_streamp zs;
-+ int err, stream_id, compressedLen, bitsPixel;
-+ int bufferSize, rowSize, numRows;
-+ Bool readUncompressed = False;
-+ CARDBPP *rawData;
-+
-+ if (!ReadFromRFBServer((char *)&comp_ctl, 1))
-+ return False;
-+
-+ /* Flush zlib streams if we are told by the server to do so. */
-+ for (stream_id = 0; stream_id < 4; stream_id++) {
-+ if ((comp_ctl & 1) && zlibStreamActive[stream_id]) {
-+ if (inflateEnd (&zlibStream[stream_id]) != Z_OK &&
-+ zlibStream[stream_id].msg != NULL)
-+ fprintf(stderr, "inflateEnd: %s\n", zlibStream[stream_id].msg);
-+ zlibStreamActive[stream_id] = False;
-+ }
-+ comp_ctl >>= 1;
-+ }
-+
-+ if ((comp_ctl & rfbTightNoZlib) == rfbTightNoZlib) {
-+ comp_ctl &= ~(rfbTightNoZlib);
-+ readUncompressed = True;
-+ }
-+
-+ /* Handle solid rectangles. */
-+ if (comp_ctl == rfbTightFill) {
-+#if BPP == 32
-+ if (myFormat.depth == 24 && myFormat.redMax == 0xFF &&
-+ myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) {
-+ if (!ReadFromRFBServer(buffer, 3))
-+ return False;
-+ fill_colour = RGB24_TO_PIXEL32(buffer[0], buffer[1], buffer[2]);
-+ } else {
-+ if (!ReadFromRFBServer((char*)&fill_colour, sizeof(fill_colour)))
-+ return False;
-+ }
-+#else
-+ if (!ReadFromRFBServer((char*)&fill_colour, sizeof(fill_colour)))
-+ return False;
-+#endif
-+
-+#if (BPP == 8)
-+ gcv.foreground = (appData.useBGR233) ?
-+ BGR233ToPixel[fill_colour] : fill_colour;
-+#else
-+ gcv.foreground = fill_colour;
-+#endif
-+
-+ FillRectangle(&gcv, rx, ry, rw, rh);
-+ return True;
-+ }
-+
-+#if BPP == 8
-+ if (comp_ctl == rfbTightJpeg) {
-+ fprintf(stderr, "Tight encoding: JPEG is not supported in 8 bpp mode.\n");
-+ return False;
-+ }
-+#else
-+ if (comp_ctl == rfbTightJpeg) {
-+ return DecompressJpegRectBPP(rx, ry, rw, rh);
-+ }
-+#endif
-+
-+ /* Quit on unsupported subencoding value. */
-+ if (comp_ctl > rfbTightMaxSubencoding) {
-+ fprintf(stderr, "Tight encoding: bad subencoding value received.\n");
-+ return False;
-+ }
-+
-+ /*
-+ * Here primary compression mode handling begins.
-+ * Data was processed with optional filter + zlib compression.
-+ */
-+
-+ /* First, we should identify a filter to use. */
-+ if ((comp_ctl & rfbTightExplicitFilter) != 0) {
-+ if (!ReadFromRFBServer((char*)&filter_id, 1))
-+ return False;
-+
-+ switch (filter_id) {
-+ case rfbTightFilterCopy:
-+ filterFn = FilterCopyBPP;
-+ bitsPixel = InitFilterCopyBPP(rw, rh);
-+ break;
-+ case rfbTightFilterPalette:
-+ filterFn = FilterPaletteBPP;
-+ bitsPixel = InitFilterPaletteBPP(rw, rh);
-+ break;
-+ case rfbTightFilterGradient:
-+ filterFn = FilterGradientBPP;
-+ bitsPixel = InitFilterGradientBPP(rw, rh);
-+ break;
-+ default:
-+ fprintf(stderr, "Tight encoding: unknown filter code received.\n");
-+ return False;
-+ }
-+ } else {
-+ filterFn = FilterCopyBPP;
-+ bitsPixel = InitFilterCopyBPP(rw, rh);
-+ }
-+ if (bitsPixel == 0) {
-+ fprintf(stderr, "Tight encoding: error receiving palette.\n");
-+ return False;
-+ }
-+
-+ /* Determine if the data should be decompressed or just copied. */
-+ rowSize = (rw * bitsPixel + 7) / 8;
-+ bufferSize = -1;
-+ if (rh * rowSize < TIGHT_MIN_TO_COMPRESS)
-+ bufferSize = rh * rowSize;
-+ else if (readUncompressed) {
-+ bufferSize = (int)ReadCompactLen();
-+ }
-+ if (bufferSize != -1) {
-+ uncompressedData = (char *)realloc(uncompressedData, bufferSize);
-+ if (!uncompressedData) {
-+ fprintf(stderr, "Memory allocation error\n");
-+ return False;
-+ }
-+ if (!ReadFromRFBServer(uncompressedData, bufferSize))
-+ return False;
-+ filterFn(rx, ry, rh);
-+ if (appData.useBGR233) CopyDataToImage(buffer, rx, ry, rw, rh);
-+ if (!appData.doubleBuffer) CopyImageToScreen(rx, ry, rw, rh);
-+
-+ return True;
-+ }
-+
-+ /* Read the length (1..3 bytes) of compressed data following. */
-+ compressedLen = (int)ReadCompactLen();
-+ if (compressedLen <= 0) {
-+ fprintf(stderr, "Incorrect data received from the server.\n");
-+ return False;
-+ }
-+
-+ /* Now let's initialize compression stream if needed. */
-+ stream_id = comp_ctl & 0x03;
-+ zs = &zlibStream[stream_id];
-+ if (!zlibStreamActive[stream_id]) {
-+ zs->zalloc = Z_NULL;
-+ zs->zfree = Z_NULL;
-+ zs->opaque = Z_NULL;
-+ err = inflateInit(zs);
-+ if (err != Z_OK) {
-+ if (zs->msg != NULL)
-+ fprintf(stderr, "InflateInit error: %s.\n", zs->msg);
-+ return False;
-+ }
-+ zlibStreamActive[stream_id] = True;
-+ }
-+
-+ /* Read, decode and draw actual pixel data in a loop. */
-+
-+ compressedData = (char *)realloc(compressedData, compressedLen);
-+ if (!compressedData) {
-+ fprintf(stderr, "Memory allocation error\n");
-+ return False;
-+ }
-+ uncompressedData = (char *)realloc(uncompressedData, rh * rowSize);
-+ if (!uncompressedData) {
-+ fprintf(stderr, "Memory allocation error\n");
-+ return False;
-+ }
-+
-+ if (!ReadFromRFBServer(compressedData, compressedLen))
-+ return False;
-+ zs->next_in = (Bytef *)compressedData;
-+ zs->avail_in = compressedLen;
-+ zs->next_out = (Bytef *)uncompressedData;
-+ zs->avail_out = rh * rowSize;
-+
-+ err = inflate(zs, Z_SYNC_FLUSH);
-+ if (err != Z_OK && err != Z_STREAM_END) {
-+ if (zs->msg != NULL) {
-+ fprintf(stderr, "Inflate error: %s.\n", zs->msg);
-+ } else {
-+ fprintf(stderr, "Inflate error: %d.\n", err);
-+ }
-+ return False;
-+ }
-+
-+ filterFn(rx, ry, rh);
-+ if (appData.useBGR233) CopyDataToImage(buffer, rx, ry, rw, rh);
-+ if (!appData.doubleBuffer) CopyImageToScreen(rx, ry, rw, rh);
-+
-+ return True;
-+}
-+
-+/*----------------------------------------------------------------------------
-+ *
-+ * Filter stuff.
-+ *
-+ */
-+
-+/*
-+ The following variables are defined in rfbproto.c:
-+ static Bool cutZeros;
-+ static int rectWidth, rectColors;
-+ static CARD8 tightPalette[256*4];
-+ static CARD8 tightPrevRow[2048*3*sizeof(CARD16)];
-+*/
-+
-+static int
-+InitFilterCopyBPP (int rw, int rh)
-+{
-+ rectWidth = rw;
-+
-+#if BPP == 32
-+ if (myFormat.depth == 24 && myFormat.redMax == 0xFF &&
-+ myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) {
-+ cutZeros = True;
-+ return 24;
-+ } else {
-+ cutZeros = False;
-+ }
-+#endif
-+
-+ return BPP;
-+}
-+
-+static void
-+FilterCopyBPP (int srcx, int srcy, int numRows)
-+{
-+ CARDBPP *dst = (CARDBPP *)&image->data[srcy * image->bytes_per_line
-+ + srcx * image->bits_per_pixel/8];
-+ int dstw = image->bytes_per_line / (image->bits_per_pixel / 8);
-+ int y;
-+#if BPP == 32
-+ int x;
-+#endif
-+
-+ if (appData.useBGR233) {
-+ dst = (CARDBPP *)buffer;
-+ dstw = rectWidth;
-+ }
-+
-+#if BPP == 32
-+ if (cutZeros) {
-+ for (y = 0; y < numRows; y++) {
-+ for (x = 0; x < rectWidth; x++) {
-+ dst[y*dstw+x] =
-+ RGB24_TO_PIXEL32(uncompressedData[(y*rectWidth+x)*3],
-+ uncompressedData[(y*rectWidth+x)*3+1],
-+ uncompressedData[(y*rectWidth+x)*3+2]);
-+ }
-+ }
-+ return;
-+ }
-+#endif
-+
-+ for (y = 0; y < numRows; y++)
-+ memcpy (&dst[y*dstw], &uncompressedData[y*rectWidth], rectWidth * (BPP / 8));
-+}
-+
-+static int
-+InitFilterGradientBPP (int rw, int rh)
-+{
-+ int bits;
-+
-+ bits = InitFilterCopyBPP(rw, rh);
-+ if (cutZeros)
-+ memset(tightPrevRow, 0, rw * 3);
-+ else
-+ memset(tightPrevRow, 0, rw * 3 * sizeof(CARD16));
-+
-+ return bits;
-+}
-+
-+#if BPP == 32
-+
-+static void
-+FilterGradient24 (int srcx, int srcy, int numRows)
-+{
-+ CARDBPP *dst = (CARDBPP *)&image->data[srcy * image->bytes_per_line
-+ + srcx * image->bits_per_pixel/8];
-+ int dstw = image->bytes_per_line / (image->bits_per_pixel / 8);
-+ int x, y, c;
-+ CARD8 thisRow[2048*3];
-+ CARD8 pix[3];
-+ int est[3];
-+
-+ if (appData.useBGR233) {
-+ dst = (CARDBPP *)buffer;
-+ dstw = rectWidth;
-+ }
-+
-+ for (y = 0; y < numRows; y++) {
-+
-+ /* First pixel in a row */
-+ for (c = 0; c < 3; c++) {
-+ pix[c] = tightPrevRow[c] + uncompressedData[y*rectWidth*3+c];
-+ thisRow[c] = pix[c];
-+ }
-+ dst[y*dstw] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]);
-+
-+ /* Remaining pixels of a row */
-+ for (x = 1; x < rectWidth; x++) {
-+ for (c = 0; c < 3; c++) {
-+ est[c] = (int)tightPrevRow[x*3+c] + (int)pix[c] -
-+ (int)tightPrevRow[(x-1)*3+c];
-+ if (est[c] > 0xFF) {
-+ est[c] = 0xFF;
-+ } else if (est[c] < 0x00) {
-+ est[c] = 0x00;
-+ }
-+ pix[c] = (CARD8)est[c] + buffer[(y*rectWidth+x)*3+c];
-+ thisRow[x*3+c] = pix[c];
-+ }
-+ dst[y*dstw+x] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]);
-+ }
-+
-+ memcpy(tightPrevRow, thisRow, rectWidth * 3);
-+ }
-+}
-+
-+#endif
-+
-+static void
-+FilterGradientBPP (int srcx, int srcy, int numRows)
-+{
-+ int x, y, c;
-+ CARDBPP *dst = (CARDBPP *)&image->data[srcy * image->bytes_per_line
-+ + srcx * image->bits_per_pixel/8];
-+ int dstw = image->bytes_per_line / (image->bits_per_pixel / 8);
-+ CARDBPP *src = (CARDBPP *)uncompressedData;
-+ CARD16 *thatRow = (CARD16 *)tightPrevRow;
-+ CARD16 thisRow[2048*3];
-+ CARD16 pix[3];
-+ CARD16 max[3];
-+ int shift[3];
-+ int est[3];
-+
-+ if (appData.useBGR233) {
-+ dst = (CARDBPP *)buffer;
-+ dstw = rectWidth;
-+ }
-+
-+#if BPP == 32
-+ if (cutZeros) {
-+ FilterGradient24(srcx, srcy, numRows);
-+ return;
-+ }
-+#endif
-+
-+ max[0] = myFormat.redMax;
-+ max[1] = myFormat.greenMax;
-+ max[2] = myFormat.blueMax;
-+
-+ shift[0] = myFormat.redShift;
-+ shift[1] = myFormat.greenShift;
-+ shift[2] = myFormat.blueShift;
-+
-+ for (y = 0; y < numRows; y++) {
-+
-+ /* First pixel in a row */
-+ for (c = 0; c < 3; c++) {
-+ pix[c] = (CARD16)((src[y*rectWidth] >> shift[c]) + thatRow[c] & max[c]);
-+ thisRow[c] = pix[c];
-+ }
-+ dst[y*dstw] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]);
-+
-+ /* Remaining pixels of a row */
-+ for (x = 1; x < rectWidth; x++) {
-+ for (c = 0; c < 3; c++) {
-+ est[c] = (int)thatRow[x*3+c] + (int)pix[c] - (int)thatRow[(x-1)*3+c];
-+ if (est[c] > (int)max[c]) {
-+ est[c] = (int)max[c];
-+ } else if (est[c] < 0) {
-+ est[c] = 0;
-+ }
-+ pix[c] = (CARD16)((src[y*rectWidth+x] >> shift[c]) + est[c] & max[c]);
-+ thisRow[x*3+c] = pix[c];
-+ }
-+ dst[y*dstw+x] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]);
-+ }
-+ memcpy(thatRow, thisRow, rectWidth * 3 * sizeof(CARD16));
-+ }
-+}
-+
-+static int
-+InitFilterPaletteBPP (int rw, int rh)
-+{
-+ int i;
-+ CARD8 numColors;
-+ CARDBPP *palette = (CARDBPP *)tightPalette;
-+
-+ rectWidth = rw;
-+
-+ if (!ReadFromRFBServer((char*)&numColors, 1))
-+ return 0;
-+
-+ rectColors = (int)numColors;
-+ if (++rectColors < 2)
-+ return 0;
-+
-+#if BPP == 32
-+ if (myFormat.depth == 24 && myFormat.redMax == 0xFF &&
-+ myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) {
-+ if (!ReadFromRFBServer((char*)&tightPalette, rectColors * 3))
-+ return 0;
-+ for (i = rectColors - 1; i >= 0; i--) {
-+ palette[i] = RGB24_TO_PIXEL32(tightPalette[i*3],
-+ tightPalette[i*3+1],
-+ tightPalette[i*3+2]);
-+ }
-+ return (rectColors == 2) ? 1 : 8;
-+ }
-+#endif
-+
-+ if (!ReadFromRFBServer((char*)&tightPalette, rectColors * (BPP / 8)))
-+ return 0;
-+
-+ return (rectColors == 2) ? 1 : 8;
-+}
-+
-+static void
-+FilterPaletteBPP (int srcx, int srcy, int numRows)
-+{
-+ int x, y, b, w;
-+ CARDBPP *dst = (CARDBPP *)&image->data[srcy * image->bytes_per_line
-+ + srcx * image->bits_per_pixel/8];
-+ int dstw = image->bytes_per_line / (image->bits_per_pixel / 8);
-+ CARD8 *src = (CARD8 *)uncompressedData;
-+ CARDBPP *palette = (CARDBPP *)tightPalette;
-+
-+ if (appData.useBGR233) {
-+ dst = (CARDBPP *)buffer;
-+ dstw = rectWidth;
-+ }
-+
-+ if (rectColors == 2) {
-+ w = (rectWidth + 7) / 8;
-+ for (y = 0; y < numRows; y++) {
-+ for (x = 0; x < rectWidth / 8; x++) {
-+ for (b = 7; b >= 0; b--)
-+ dst[y*dstw+x*8+7-b] = palette[src[y*w+x] >> b & 1];
-+ }
-+ for (b = 7; b >= 8 - rectWidth % 8; b--) {
-+ dst[y*dstw+x*8+7-b] = palette[src[y*w+x] >> b & 1];
-+ }
-+ }
-+ } else {
-+ for (y = 0; y < numRows; y++)
-+ for (x = 0; x < rectWidth; x++)
-+ dst[y*dstw+x] = palette[(int)src[y*rectWidth+x]];
-+ }
-+}
-+
-+#if BPP != 8
-+
-+/*----------------------------------------------------------------------------
-+ *
-+ * JPEG decompression.
-+ *
-+ */
-+
-+/*
-+ The following variables are defined in rfbproto.c:
-+ static Bool jpegError;
-+ static struct jpeg_source_mgr jpegSrcManager;
-+ static JOCTET *jpegBufferPtr;
-+ static size_t *jpegBufferLen;
-+*/
-+
-+static Bool
-+DecompressJpegRectBPP(int x, int y, int w, int h)
-+{
-+ int compressedLen;
-+ char *dstptr;
-+ int ps, flags=0;
-+
-+ compressedLen = (int)ReadCompactLen();
-+ if (compressedLen <= 0) {
-+ fprintf(stderr, "Incorrect data received from the server.\n");
-+ return False;
-+ }
-+
-+ compressedData = (char *)realloc(compressedData, compressedLen);
-+ if (compressedData == NULL) {
-+ fprintf(stderr, "Memory allocation error.\n");
-+ return False;
-+ }
-+
-+ if (!ReadFromRFBServer(compressedData, compressedLen)) {
-+ return False;
-+ }
-+
-+ if(!tjhnd) {
-+ if((tjhnd=tjInitDecompress())==NULL) {
-+ fprintf(stderr, "TurboJPEG error: %s\n", tjGetErrorStr());
-+ return False;
-+ }
-+ }
-+
-+ ps=image->bits_per_pixel/8;
-+ if(myFormat.bigEndian && ps==4) flags|=TJ_ALPHAFIRST;
-+ if(myFormat.redShift==16 && myFormat.blueShift==0)
-+ flags|=TJ_BGR;
-+ if(myFormat.bigEndian) flags^=TJ_BGR;
-+
-+ dstptr=&image->data[image->bytes_per_line*y+x*ps];
-+ if(tjDecompress(tjhnd, (unsigned char *)compressedData, (unsigned long)compressedLen,
-+ (unsigned char *)dstptr, w, image->bytes_per_line, h, ps, flags)==-1) {
-+ fprintf(stderr, "TurboJPEG error: %s\n", tjGetErrorStr());
-+ return False;
-+ }
-+
-+ if (!appData.doubleBuffer)
-+ CopyImageToScreen(x, y, w, h);
-+
-+ return True;
-+}
-+
-+#endif
-+
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/turbovnc/turbojpeg.h vnc_unixsrc/vncviewer/turbovnc/turbojpeg.h
---- vnc_unixsrc.orig/vncviewer/turbovnc/turbojpeg.h 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/turbovnc/turbojpeg.h 2008-04-03 04:28:56.000000000 -0400
-@@ -0,0 +1,229 @@
-+/* Copyright (C)2004 Landmark Graphics
-+ * Copyright (C)2005, 2006 Sun Microsystems, Inc.
-+ *
-+ * This library is free software and may be redistributed and/or modified under
-+ * the terms of the wxWindows Library License, Version 3.1 or (at your option)
-+ * any later version. The full license is in the LICENSE.txt file included
-+ * with this distribution.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * wxWindows Library License for more details.
-+ */
-+
-+#if (defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)) && defined(_WIN32) && defined(DLLDEFINE)
-+#define DLLEXPORT __declspec(dllexport)
-+#else
-+#define DLLEXPORT
-+#endif
-+
-+#define DLLCALL
-+
-+/* Subsampling */
-+#define NUMSUBOPT 4
-+
-+enum {TJ_444=0, TJ_422, TJ_411, TJ_GRAYSCALE};
-+
-+/* Flags */
-+#define TJ_BGR 1
-+#define TJ_BOTTOMUP 2
-+#define TJ_FORCEMMX 8 /* Force IPP to use MMX code even if SSE available */
-+#define TJ_FORCESSE 16 /* Force IPP to use SSE1 code even if SSE2 available */
-+#define TJ_FORCESSE2 32 /* Force IPP to use SSE2 code (useful if auto-detect is not working properly) */
-+#define TJ_ALPHAFIRST 64 /* BGR buffer is ABGR and RGB buffer is ARGB */
-+#define TJ_FORCESSE3 128 /* Force IPP to use SSE3 code (useful if auto-detect is not working properly) */
-+
-+typedef void* tjhandle;
-+
-+#define TJPAD(p) (((p)+3)&(~3))
-+#ifndef max
-+ #define max(a,b) ((a)>(b)?(a):(b))
-+#endif
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* API follows */
-+
-+
-+/*
-+ tjhandle tjInitCompress(void)
-+
-+ Creates a new JPEG compressor instance, allocates memory for the structures,
-+ and returns a handle to the instance. Most applications will only
-+ need to call this once at the beginning of the program or once for each
-+ concurrent thread. Don't try to create a new instance every time you
-+ compress an image, because this will cause performance to suffer.
-+
-+ RETURNS: NULL on error
-+*/
-+DLLEXPORT tjhandle DLLCALL tjInitCompress(void);
-+
-+
-+/*
-+ int tjCompress(tjhandle j,
-+ unsigned char *srcbuf, int width, int pitch, int height, int pixelsize,
-+ unsigned char *dstbuf, unsigned long *size,
-+ int jpegsubsamp, int jpegqual, int flags)
-+
-+ [INPUT] j = instance handle previously returned from a call to
-+ tjInitCompress()
-+ [INPUT] srcbuf = pointer to user-allocated image buffer containing pixels in
-+ RGB(A) or BGR(A) form
-+ [INPUT] width = width (in pixels) of the source image
-+ [INPUT] pitch = bytes per line of the source image (width*pixelsize if the
-+ bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the bitmap
-+ is padded to the nearest 32-bit boundary, such as is the case for Windows
-+ bitmaps. You can also be clever and use this parameter to skip lines, etc.,
-+ as long as the pitch is greater than 0.)
-+ [INPUT] height = height (in pixels) of the source image
-+ [INPUT] pixelsize = size (in bytes) of each pixel in the source image
-+ RGBA and BGRA: 4, RGB and BGR: 3
-+ [INPUT] dstbuf = pointer to user-allocated image buffer which will receive
-+ the JPEG image. Use the macro TJBUFSIZE(width, height) to determine
-+ the appropriate size for this buffer based on the image width and height.
-+ [OUTPUT] size = pointer to unsigned long which receives the size (in bytes)
-+ of the compressed image
-+ [INPUT] jpegsubsamp = Specifies either 4:1:1, 4:2:2, or 4:4:4 subsampling.
-+ When the image is converted from the RGB to YCbCr colorspace as part of the
-+ JPEG compression process, every other Cb and Cr (chrominance) pixel can be
-+ discarded to produce a smaller image with little perceptible loss of
-+ image clarity (the human eye is more sensitive to small changes in
-+ brightness than small changes in color.)
-+
-+ TJ_411: 4:1:1 subsampling. Discards every other Cb, Cr pixel in both
-+ horizontal and vertical directions.
-+ TJ_422: 4:2:2 subsampling. Discards every other Cb, Cr pixel only in
-+ the horizontal direction.
-+ TJ_444: no subsampling.
-+ TJ_GRAYSCALE: Generate grayscale JPEG image
-+
-+ [INPUT] jpegqual = JPEG quality (an integer between 0 and 100 inclusive.)
-+ [INPUT] flags = the bitwise OR of one or more of the following
-+
-+ TJ_BGR: The components of each pixel in the source image are stored in
-+ B,G,R order, not R,G,B
-+ TJ_BOTTOMUP: The source image is stored in bottom-up (Windows) order,
-+ not top-down
-+ TJ_FORCEMMX: Valid only for the Intel Performance Primitives implementation
-+ of this codec-- force IPP to use MMX code (bypass CPU auto-detection)
-+ TJ_FORCESSE: Valid only for the Intel Performance Primitives implementation
-+ of this codec-- force IPP to use SSE code (bypass CPU auto-detection)
-+ TJ_FORCESSE2: Valid only for the Intel Performance Primitives implementation
-+ of this codec-- force IPP to use SSE2 code (bypass CPU auto-detection)
-+ TJ_FORCESSE3: Valid only for the Intel Performance Primitives implementation
-+ of this codec-- force IPP to use SSE3 code (bypass CPU auto-detection)
-+
-+ RETURNS: 0 on success, -1 on error
-+*/
-+DLLEXPORT int DLLCALL tjCompress(tjhandle j,
-+ unsigned char *srcbuf, int width, int pitch, int height, int pixelsize,
-+ unsigned char *dstbuf, unsigned long *size,
-+ int jpegsubsamp, int jpegqual, int flags);
-+
-+DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height);
-+
-+/*
-+ tjhandle tjInitDecompress(void)
-+
-+ Creates a new JPEG decompressor instance, allocates memory for the
-+ structures, and returns a handle to the instance. Most applications will
-+ only need to call this once at the beginning of the program or once for each
-+ concurrent thread. Don't try to create a new instance every time you
-+ decompress an image, because this will cause performance to suffer.
-+
-+ RETURNS: NULL on error
-+*/
-+DLLEXPORT tjhandle DLLCALL tjInitDecompress(void);
-+
-+
-+/*
-+ int tjDecompressHeader(tjhandle j,
-+ unsigned char *srcbuf, unsigned long size,
-+ int *width, int *height)
-+
-+ [INPUT] j = instance handle previously returned from a call to
-+ tjInitDecompress()
-+ [INPUT] srcbuf = pointer to a user-allocated buffer containing the JPEG image
-+ to decompress
-+ [INPUT] size = size of the JPEG image buffer (in bytes)
-+ [OUTPUT] width = width (in pixels) of the JPEG image
-+ [OUTPUT] height = height (in pixels) of the JPEG image
-+
-+ RETURNS: 0 on success, -1 on error
-+*/
-+DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle j,
-+ unsigned char *srcbuf, unsigned long size,
-+ int *width, int *height);
-+
-+
-+/*
-+ int tjDecompress(tjhandle j,
-+ unsigned char *srcbuf, unsigned long size,
-+ unsigned char *dstbuf, int width, int pitch, int height, int pixelsize,
-+ int flags)
-+
-+ [INPUT] j = instance handle previously returned from a call to
-+ tjInitDecompress()
-+ [INPUT] srcbuf = pointer to a user-allocated buffer containing the JPEG image
-+ to decompress
-+ [INPUT] size = size of the JPEG image buffer (in bytes)
-+ [INPUT] dstbuf = pointer to user-allocated image buffer which will receive
-+ the bitmap image. This buffer should normally be pitch*height
-+ bytes in size, although this pointer may also be used to decompress into
-+ a specific region of a larger buffer.
-+ [INPUT] width = width (in pixels) of the destination image
-+ [INPUT] pitch = bytes per line of the destination image (width*pixelsize if the
-+ bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the bitmap
-+ is padded to the nearest 32-bit boundary, such as is the case for Windows
-+ bitmaps. You can also be clever and use this parameter to skip lines, etc.,
-+ as long as the pitch is greater than 0.)
-+ [INPUT] height = height (in pixels) of the destination image
-+ [INPUT] pixelsize = size (in bytes) of each pixel in the destination image
-+ RGBA/RGBx and BGRA/BGRx: 4, RGB and BGR: 3
-+ [INPUT] flags = the bitwise OR of one or more of the following
-+
-+ TJ_BGR: The components of each pixel in the destination image should be
-+ written in B,G,R order, not R,G,B
-+ TJ_BOTTOMUP: The destination image should be stored in bottom-up
-+ (Windows) order, not top-down
-+ TJ_FORCEMMX: Valid only for the Intel Performance Primitives implementation
-+ of this codec-- force IPP to use MMX code (bypass CPU auto-detection)
-+ TJ_FORCESSE: Valid only for the Intel Performance Primitives implementation
-+ of this codec-- force IPP to use SSE code (bypass CPU auto-detection)
-+ TJ_FORCESSE2: Valid only for the Intel Performance Primitives implementation
-+ of this codec-- force IPP to use SSE2 code (bypass CPU auto-detection)
-+
-+ RETURNS: 0 on success, -1 on error
-+*/
-+DLLEXPORT int DLLCALL tjDecompress(tjhandle j,
-+ unsigned char *srcbuf, unsigned long size,
-+ unsigned char *dstbuf, int width, int pitch, int height, int pixelsize,
-+ int flags);
-+
-+
-+/*
-+ int tjDestroy(tjhandle h)
-+
-+ Frees structures associated with a compression or decompression instance
-+
-+ [INPUT] h = instance handle (returned from a previous call to
-+ tjInitCompress() or tjInitDecompress()
-+
-+ RETURNS: 0 on success, -1 on error
-+*/
-+DLLEXPORT int DLLCALL tjDestroy(tjhandle h);
-+
-+
-+/*
-+ char *tjGetErrorStr(void)
-+
-+ Returns a descriptive error message explaining why the last command failed
-+*/
-+DLLEXPORT char* DLLCALL tjGetErrorStr(void);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vncviewer/vncviewer._man
---- vnc_unixsrc.orig/vncviewer/vncviewer._man 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/vncviewer._man 2010-04-11 23:30:24.000000000 -0400
-@@ -0,0 +1,829 @@
-+'\" t
-+.\" ** The above line should force tbl to be a preprocessor **
-+.\" Man page for X vncviewer
-+.\"
-+.\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de
-+.\" Copyright (C) 2000,2001 Red Hat, Inc.
-+.\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru>
-+.\" Copyright (C) 2006-2010 Karl J. Runge <runge@karlrunge.com>
-+.\"
-+.\" You may distribute under the terms of the GNU General Public
-+.\" License as specified in the file LICENCE.TXT that comes with the
-+.\" TightVNC distribution.
-+.\"
-+.TH ssvncviewer 1 "April 2010" "" "SSVNC"
-+.SH NAME
-+ssvncviewer \- an X viewer client for VNC
-+.SH SYNOPSIS
-+.B ssvncviewer
-+.RI [\| options \|]
-+.RI [\| host \|][\| :display \|]
-+.br
-+.B ssvncviewer
-+.RI [\| options \|]
-+.RI [\| host \|][\| ::port \|]
-+.br
-+.B ssvncviewer
-+.RI [\| options \|]
-+.RI exec=[\| cmd+args... \|]
-+.br
-+.B ssvncviewer
-+.RI [\| options \|]
-+.RI fd=n
-+.br
-+.B ssvncviewer
-+.RI [\| options \|]
-+.RI /path/to/unix/socket
-+.br
-+.B ssvncviewer
-+.RI [\| options \|]
-+.IR \-listen
-+.RI [\| display \|]
-+.br
-+.B ssvncviewer
-+.IR \-help
-+.br
-+.SH DESCRIPTION
-+.B ssvncviewer
-+is an Xt\-based client application for the VNC (Virtual Network
-+Computing) system. It can connect to any VNC\-compatible server such
-+as \fBXvnc\fR, WinVNC, or \fBx11vnc\fR, allowing you to control desktop environment
-+of a different machine.
-+
-+ssvncviewer is an enhanced version of the tightvnc unix viewer that can
-+take advantage of features in the \fBx11vnc\fR and UltraVNC VNC servers.
-+See below for the description of these features.
-+
-+You can use F8 to display a pop\-up utility menu. Press F8 twice to
-+pass single F8 to the remote side.
-+.SH OPTIONS
-+.TP
-+\fB\-help\fR
-+Prints a short usage notice to stderr.
-+.TP
-+\fB\-listen\fR
-+Make the viewer listen on port 5500+\fIdisplay\fR for reverse
-+connections from a server. WinVNC supports reverse connections using
-+the "Add New Client" menu option, or the \-connect command line
-+option. \fBXvnc\fR requires the use of the helper program
-+\fBvncconnect\fR.
-+.TP
-+\fB\-via\fR \fIgateway\fR
-+Automatically create encrypted TCP tunnel to the \fIgateway\fR machine
-+before connection, connect to the \fIhost\fR through that tunnel
-+(TightVNC\-specific). By default, this option invokes SSH local port
-+forwarding, assuming that SSH client binary can be accessed as
-+/usr/bin/ssh. Note that when using the \fB\-via\fR option, the host
-+machine name should be specified as known to the gateway machine, e.g.
-+"localhost" denotes the \fIgateway\fR, not the machine where vncviewer
-+was launched. See the ENVIRONMENT section below for the information on
-+configuring the \fB\-via\fR option.
-+.TP
-+\fB\-shared\fR
-+When connecting, specify that a shared connection is requested. In
-+TightVNC, this is the default mode, allowing you to share the desktop
-+with other clients already using it.
-+.TP
-+\fB\-noshared\fR
-+When connecting, specify that the session may not be shared. This
-+would either disconnect other connected clients or refuse your
-+connection, depending on the server configuration.
-+.TP
-+\fB\-viewonly\fR
-+Disable transfer of mouse and keyboard events from the client to the
-+server.
-+.TP
-+\fB\-fullscreen\fR
-+Start in full\-screen mode. Please be aware that operating in
-+full\-screen mode may confuse X window managers. Typically, such
-+conflicts cause incorrect handling of input focus or make the viewer
-+window disappear mysteriously. See the grabKeyboard setting in the
-+RESOURCES section below for a method to solve input focus problem.
-+.TP
-+\fB\-noraiseonbeep\fR
-+By default, the viewer shows and raises its window on remote beep
-+(bell) event. This option disables such behaviour
-+(TightVNC\-specific).
-+.TP
-+\fB\-user\fR \fIusername\fR
-+User name for Unix login authentication. Default is to use current
-+Unix user name. If this option was given, the viewer will prefer Unix
-+login authentication over the standard VNC authentication.
-+.TP
-+\fB\-passwd\fR \fIpasswd\-file\fR
-+File from which to get the password (as generated by the
-+\fBvncpasswd\fR(1) program). This option affects only the standard VNC
-+authentication.
-+.TP
-+\fB\-encodings\fR \fIencoding\-list\fR
-+TightVNC supports several different compression methods to encode
-+screen updates; this option specifies a set of them to use in order of
-+preference. Encodings are specified separated with spaces, and must
-+thus be enclosed in quotes if more than one is specified. Commas may be used to avoid spaces.
-+Available encodings, in default order for a remote connection, are
-+"copyrect tight hextile zlib corre rre raw". For a local connection
-+(to the same machine), the default order to try is "raw copyrect tight
-+hextile zlib corre rre". Raw encoding is always assumed as a last option
-+if no other encoding can be used for some reason. For more information
-+on encodings, see the section ENCODINGS below.
-+.TP
-+\fB\-bgr233\fR
-+Always use the BGR233 format to encode pixel data. This reduces
-+network traffic, but colors may be represented inaccurately. The
-+bgr233 format is an 8\-bit "true color" format, with 2 bits blue, 3
-+bits green, and 3 bits red.
-+.TP
-+\fB\-owncmap\fR
-+Try to use a PseudoColor visual and a private colormap. This allows
-+the VNC server to control the colormap.
-+.TP
-+\fB\-truecolour\fR, \fB\-truecolor\fR
-+Try to use a TrueColor visual.
-+.TP
-+\fB\-depth\fR \fIdepth\fR
-+On an X server which supports multiple TrueColor visuals of different
-+depths, attempt to use the specified one (in bits per pixel); if
-+successful, this depth will be requested from the VNC server.
-+.TP
-+\fB\-compresslevel \fIlevel\fR
-+Use specified compression \fIlevel\fR (0..9) for "tight" and "zlib"
-+encodings (TightVNC\-specific). Level 1 uses minimum of CPU time and
-+achieves weak compression ratios, while level 9 offers best
-+compression but is slow in terms of CPU time consumption on the server
-+side. Use high levels with very slow network connections, and low
-+levels when working over high\-speed LANs. It's not recommended to use
-+compression level 0, reasonable choices start from the level 1.
-+.TP
-+\fB\-quality \fIlevel\fR
-+Use the specified JPEG quality \fIlevel\fR (0..9) for the "tight"
-+encoding (TightVNC\-specific). Quality level 0 denotes bad image
-+quality but very impressive compression ratios, while level 9 offers
-+very good image quality at lower compression ratios. Note that the
-+"tight" encoder uses JPEG to encode only those screen areas that look
-+suitable for lossy compression, so quality level 0 does not always
-+mean unacceptable image quality.
-+.TP
-+\fB\-nojpeg\fR
-+Disable lossy JPEG compression in Tight encoding (TightVNC\-specific).
-+Disabling JPEG compression is not a good idea in typical cases, as
-+that makes the Tight encoder less efficient. You might want to use
-+this option if it's absolutely necessary to achieve perfect image
-+quality (see also the \fB\-quality\fR option).
-+.TP
-+\fB\-nocursorshape\fR
-+Disable cursor shape updates, protocol extensions used to handle
-+remote cursor movements locally on the client side
-+(TightVNC\-specific). Using cursor shape updates decreases delays with
-+remote cursor movements, and can improve bandwidth usage dramatically.
-+.TP
-+\fB\-x11cursor\fR
-+Use a real X11 cursor with X-style cursor shape updates, instead of
-+drawing the remote cursor on the framebuffer. This option also
-+disables the dot cursor, and disables cursor position updates in
-+non-fullscreen mode.
-+.TP
-+\fB\-autopass\fR
-+Read a plain-text password from stdin. This option affects only the
-+standard VNC authentication.
-+
-+.SH Enhanced TightVNC Viewer (SSVNC) OPTIONS
-+.TP
-+Enhanced TightVNC Viewer (SSVNC) web page is located at:
-+.TP
-+http://www.karlrunge.com/x11vnc/ssvnc.html
-+.TP
-+Note: ZRLE and ZYWRLE encodings are now supported.
-+.TP
-+Note: F9 is shortcut to Toggle FullScreen mode.
-+.TP
-+Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1
-+to allow more than one incoming VNC server at a time.
-+This is the same as -multilisten described below. Set
-+SSVNC_MULTIPLE_LISTEN=MAX:n to allow no more than "n"
-+simultaneous reverse connections.
-+
-+If the host:port is specified as "exec=command args..."
-+then instead of making a TCP/IP socket connection to the
-+remote VNC server, "command args..." is executed and the
-+viewer is attached to its stdio. This enables tunnelling
-+established via an external command, e.g. an stunnel(8)
-+that does not involve a listening socket.
-+This mode does not work for -listen reverse connections.
-+
-+If the host:port is specified as "fd=n" then it is assumed
-+n is an already opened file descriptor to the socket. (i.e
-+the parent did fork+exec)
-+
-+If the host:port contains a '/' it is interpreted as a
-+unix-domain socket (AF_LOCAL insead of AF_INET)
-+.TP
-+\fB\-multilisten\fR
-+As in -listen (reverse connection listening) except
-+allow more than one incoming VNC server to be connected
-+at a time. The default for -listen of only one at a
-+time tries to play it safe by not allowing anyone on
-+the network to put (many) desktops on your screen over
-+a long window of time. Use -multilisten for no limit.
-+.TP
-+\fB\-acceptpopup\fR
-+In \fB\-listen\fR (reverse connection listening) mode when
-+a reverse VNC connection comes in show a popup asking
-+whether to Accept or Reject the connection. The IP
-+address of the connecting host is shown. Same as
-+setting the env. var. SSVNC_ACCEPT_POPUP=1.
-+.TP
-+\fB\-acceptpopupsc\fR
-+As in \fB\-acceptpopup\fR except assume UltraVNC Single
-+Click (SC) server. Retrieve User and ComputerName
-+info from UltraVNC Server and display in the Popup.
-+.TP
-+\fB\-use64\fR
-+In \fB\-bgr233\fR mode, use 64 colors instead of 256.
-+.TP
-+\fB\-bgr222\fR
-+Same as \fB\-use64\fR.
-+.TP
-+\fB\-use8\fR
-+In \fB\-bgr233\fR mode, use 8 colors instead of 256.
-+.TP
-+\fB\-bgr111\fR
-+Same as \fB\-use8\fR.
-+.TP
-+\fB\-16bpp\fR
-+If the vnc viewer X display is depth 24 at 32bpp
-+request a 16bpp format from the VNC server to cut
-+network traffic by up to 2X, then tranlate the
-+pixels to 32bpp locally.
-+.TP
-+\fB\-bgr565\fR
-+Same as \fB\-16bpp\fR.
-+.TP
-+\fB\-grey\fR
-+Use a grey scale for the 16- and 8\fB\-bpp\fR modes.
-+.TP
-+\fB\-alpha\fR
-+Use alphablending transparency for local cursors
-+requires: x11vnc server, both client and server
-+must be 32bpp and same endianness.
-+.TP
-+\fB\-scale\fR \fIstr\fR
-+Scale the desktop locally. The string "str" can
-+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. "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 \fB\-x11cursor\fR.)
-+
-+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 \fB\-solid\fR ...)
-+
-+If the remote server is x11vnc, try client
-+side caching: x11vnc \fB\-ncache\fR 10 ...
-+.TP
-+\fB\-ycrop\fR n
-+Only show the top n rows of the framebuffer. For
-+use with x11vnc \fB\-ncache\fR client caching option
-+to help "hide" the pixel cache region.
-+Use a negative value (e.g. \fB\-1\fR) for autodetection.
-+Autodetection will always take place if the remote
-+fb height is more than 2 times the width.
-+.TP
-+\fB\-sbwidth\fR n
-+Scrollbar width for x11vnc \fB\-ncache\fR mode (\fB\-ycrop\fR),
-+default is very narrow: 2 pixels, it is narrow to
-+avoid distraction in \fB\-ycrop\fR mode.
-+.TP
-+\fB\-nobell\fR
-+Disable bell.
-+.TP
-+\fB\-rawlocal\fR
-+Prefer raw encoding for localhost, default is
-+no, i.e. assumes you have a SSH tunnel instead.
-+.TP
-+\fB\-notty\fR
-+Try to avoid using the terminal for interactive
-+responses: use windows for messages and prompting
-+instead. Messages will also be printed to terminal.
-+.TP
-+\fB\-sendclipboard\fR
-+Send the X CLIPBOARD selection (i.e. Ctrl+C,
-+Ctrl+V) instead of the X PRIMARY selection (mouse
-+select and middle button paste.)
-+.TP
-+\fB\-sendalways\fR
-+Whenever the mouse enters the VNC viewer main
-+window, send the selection to the VNC server even if
-+it has not changed. This is like the Xt resource
-+translation SelectionToVNC(always)
-+.TP
-+\fB\-recvtext\fR
-+str When cut text is received from the VNC server,
-+ssvncviewer will set both the X PRIMARY and the
-+X CLIPBOARD local selections. To control which
-+is set, specify 'str' as 'primary', 'clipboard',
-+or 'both' (the default.)
-+.TP
-+\fB\-graball\fR
-+Grab the entire X server when in fullscreen mode,
-+needed by some old window managers like fvwm2.
-+.TP
-+\fB\-popupfix\fR
-+Warp the popup back to the pointer position,
-+needed by some old window managers like fvwm2.
-+.TP
-+\fB\-grabkbd\fR
-+Grab the X keyboard when in fullscreen mode,
-+needed by some window managers. Same as \fB\-grabkeyboard\fR.
-+\fB\-grabkbd\fR is the default, use \fB\-nograbkbd\fR to disable.
-+.TP
-+\fB\-bs\fR, \fB\-nobs\fR
-+Whether or not to use X server Backingstore for the
-+main viewer window. The default is to not, mainly
-+because most Linux, etc, systems X servers disable
-+*all* Backingstore by default. To re\fB\-enable\fR it put
-+
-+Option "Backingstore"
-+
-+in the Device section of /etc/X11/xorg.conf.
-+In \fB\-bs\fR mode with no X server backingstore, whenever an
-+area of the screen is re\fB\-exposed\fR it must go out to the
-+VNC server to retrieve the pixels. This is too slow.
-+
-+In \fB\-nobs\fR mode, memory is allocated by the viewer to
-+provide its own backing of the main viewer window. This
-+actually makes some activities faster (changes in large
-+regions) but can appear to "flash" too much.
-+.TP
-+\fB\-noshm\fR
-+Disable use of MIT shared memory extension (not recommended)
-+.TP
-+\fB\-termchat\fR
-+Do the UltraVNC chat in the terminal vncviewer is in
-+instead of in an independent window.
-+.TP
-+\fB\-unixpw\fR \fIstr\fR
-+Useful for logging into x11vnc in \fB\-unixpw\fR mode. "str" is a
-+string that allows many ways to enter the Unix Username
-+and Unix Password. These characters: username, newline,
-+password, newline are sent to the VNC server after any VNC
-+authentication has taken place. Under x11vnc they are
-+used for the \fB\-unixpw\fR login. Other VNC servers could do
-+something similar.
-+
-+You can also indicate "str" via the environment
-+variable SSVNC_UNIXPW.
-+
-+Note that the Escape key is actually sent first to tell
-+x11vnc to not echo the Unix Username back to the VNC
-+viewer. Set SSVNC_UNIXPW_NOESC=1 to override this.
-+
-+If str is ".", then you are prompted at the command line
-+for the username and password in the normal way. If str is
-+"-" the stdin is read via getpass(3) for username@password.
-+Otherwise if str is a file, it is opened and the first line
-+read is taken as the Unix username and the 2nd as the
-+password. If str prefixed by "rm:" the file is removed
-+after reading. Otherwise, if str has a "@" character,
-+it is taken as username@password. Otherwise, the program
-+exits with an error. Got all that?
-+.TP
-+\fB-repeater\fR \fIstr\fR
-+This is for use with UltraVNC repeater proxy described
-+here: http://www.uvnc.com/addons/repeater.html. The "str"
-+is the ID string to be sent to the repeater. E.g. ID:1234
-+It can also be the hostname and port or display of the VNC
-+server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when
-+using -repeater, the host:dpy on the cmdline is the repeater
-+server, NOT the VNC server. The repeater will connect you.
-+
-+Example: vncviewer ... -repeater ID:3333 repeat.host:5900
-+
-+Example: vncviewer ... -repeater vhost:0 repeat.host:5900
-+
-+Use, e.g., '-repeater SCIII=ID:3210' if the repeater is a
-+Single Click III (SSL) repeater (repeater_SSL.exe) and you
-+are passing the SSL part of the connection through stunnel, socat, etc.
-+This way the magic UltraVNC string 'testB' needed to work with the
-+repeater is sent to it.
-+.TP
-+\fB-rfbversion\fR \fIstr\fR
-+Set the advertised RFB version. E.g.: -rfbversion 3.6 For some
-+servers, e.g. UltraVNC this needs to be done.
-+.TP
-+\fB-ultradsm\fR
-+UltraVNC has symmetric private encryption DSM plugins. See
-+http://www.uvnc.com/features/encryption.html. It is assumed
-+you are using a unix program (e.g. our ultravnc_dsm_helper) to
-+encrypt and decrypt the UltraVNC DSM stream. IN ADDITION TO
-+THAT supply -ultradsm to tell THIS viewer to modify the RFB
-+data sent so as to work with the UltraVNC Server. For some
-+reason, each RFB msg type must be sent twice under DSM.
-+.TP
-+\fB\-mslogon\fR \fIuser\fR
-+Use Windows MS Logon to an UltraVNC server. Supply the
-+username or "1" to be prompted. The default is to
-+autodetect the UltraVNC MS Logon server and prompt for
-+the username and password.
-+
-+IMPORTANT NOTE: The UltraVNC MS-Logon Diffie-Hellman
-+exchange is very weak and can be brute forced to recover
-+your username and password in a few seconds of CPU
-+time. To be safe, be sure to use an additional encrypted
-+tunnel (e.g. SSL or SSH) for the entire VNC session.
-+.TP
-+\fB\-chatonly\fR
-+Try to be a client that only does UltraVNC text chat. This
-+mode is used by x11vnc to present a chat window on the physical
-+X11 console (i.e. to chat with the person at the display).
-+.TP
-+\fB-env\fR \fIVAR=VALUE\fR
-+To save writing a shell script to set environment
-+variables, specify as many as you need on the command line. For example,
-+-env SSVNC_MULTIPLE_LISTEN=MAX:5 -env EDITOR=vi
-+.TP
-+\fB\-noipv6\fR
-+Disable all IPv6 sockets. Same as VNCVIEWER_NO_IPV6=1.
-+.TP
-+\fB\-noipv4\fR
-+Disable all IPv4 sockets. Same as VNCVIEWER_NO_IPV4=1.
-+.TP
-+\fB\-printres\fR
-+Print out the Ssvnc X resources (appdefaults) and
-+then exit. You can save them to a file and customize them (e.g. the
-+keybindings and Popup menu) Then point to the file via
-+XENVIRONMENT or XAPPLRESDIR.
-+.TP
-+\fB\-pipeline\fR
-+Like TurboVNC, request the next framebuffer update as soon
-+as possible instead of waiting until the end of the current
-+framebuffer update coming in. Helps 'pipeline' the updates.
-+This is currently the default, use \fB-nopipeline\fR to disable.
-+.TP
-+\fB\-appshare\fR
-+Enable features for use with x11vnc's \fB\-appshare\fR mode where
-+instead of sharing the full desktop only the application's
-+windows are shared. Viewer multilisten mode is used to
-+create the multiple windows: \fB\-multilisten\fR is implied.
-+See 'x11vnc \fB\-appshare\fR \fB\-help\fR' more information on the mode.
-+Features enabled in the viewer under \fB\-appshare\fR are:
-+Minimum extra text in the title, auto \fB\-ycrop\fR is disabled,
-+x11vnc \fB\-remote_prefix\fR X11VNC_APPSHARE_CMD: message channel,
-+x11vnc initial window position hints. See also Escape Keys
-+below for additional key and mouse bindings.
-+.TP
-+\fB\-escape \fR\fIstr\fR
-+This sets the 'Escape Keys' modifier sequence and enables
-+escape keys mode. When the modifier keys escape sequence
-+is held down, the next keystroke is interpreted locally
-+to perform a special action instead of being sent to the
-+remote VNC server.
-+
-+Use '\fB\-escape\fR default' for the default modifier sequence.
-+(Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L)
-+
-+Here are the 'Escape Keys: Help+Set' instructions from the Popup:
-+
-+Escape Keys: Enter a comma separated list of modifier keys to be the 'escape
-+sequence'. When these keys are held down, the next keystroke is
-+interpreted locally to invoke a special action instead of being sent to
-+the remote VNC server. In other words, a set of 'Hot Keys'.
-+
-+Here is the list of local key mappings to special actions:
-+
-+r: refresh desktop b: toggle bell c: toggle full-color
-+
-+f: file transfer x: x11cursor z: toggle Tight/ZRLE
-+
-+l: full screen g: graball e: escape keys dialog
-+
-+s: scale dialog +: scale up (=) -: scale down (_)
-+
-+t: text chat a: alphablend cursor
-+
-+V: toggle viewonly Q: quit viewer 123456: UltraVNC scale 1/n
-+
-+Arrow keys: pan the viewport about 10% for each keypress.
-+
-+PageUp/PageDown: pan the viewport by a screenful vertically.
-+
-+Home/End: pan the viewport by a screenful horizontally.
-+
-+KeyPad Arrows: pan the viewport by 1 pixel for each keypress.
-+
-+Dragging the Mouse with Button1 pressed also pans the viewport.
-+
-+Clicking Mouse Button3 brings up the Popup Menu.
-+
-+The above mappings are \fBalways\fR active in ViewOnly mode, unless you set
-+the Escape Keys value to 'never'.
-+
-+x11vnc -appshare hot-keys: x11vnc has a simple application sharing mode
-+that enables the viewer-side to move, resize, or raise the remote toplevel
-+windows. To enable it, hold down Shift + the Escape Keys and press these:
-+
-+Arrow keys: move the remote window around in its desktop.
-+
-+PageUp/PageDn/Home/End: resize the remote window.
-+
-++/-: raise or lower the remote window.
-+
-+M or Button1 move win to local position; D or Button3: delete remote win.
-+
-+If the Escape Keys value below is set to 'default' then a default list of
-+of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it
-+is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag
-+on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side
-+of the keyboard.
-+
-+On Unix the default is Alt and Windows keys on Left side of keyboard.
-+On MacOSX the default is Control and Command keys on Left side of keyboard.
-+
-+Example: Press and hold the Alt and Windows keys on the LEFT side of the
-+keyboard and then press 'c' to toggle the full-color state. Or press 't'
-+to toggle the ultravnc Text Chat window, etc.
-+
-+To use something besides the default, supply a comma separated list (or a
-+single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L
-+Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.
-+.TP
-+\fB New Popup actions:\fR
-+
-+ ViewOnly: ~ -viewonly
-+ Disable Bell: ~ -nobell
-+ Cursor Shape: ~ -nocursorshape
-+ X11 Cursor: ~ -x11cursor
-+ Cursor Alphablend: ~ -alpha
-+ Toggle Tight/Hextile: ~ -encodings hextile...
-+ Toggle Tight/ZRLE: ~ -encodings zrle...
-+ Toggle ZRLE/ZYWRLE: ~ -encodings zywrle...
-+ Quality Level ~ -quality (both Tight and ZYWRLE)
-+ Compress Level ~ -compresslevel
-+ Disable JPEG: ~ -nojpeg (Tight)
-+ Pipeline Updates ~ -pipeline
-+
-+ Full Color as many colors as local screen allows.
-+ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.
-+ 16 bit color (BGR565) ~ -16bpp / -bgr565
-+ 8 bit color (BGR233) ~ -bgr233
-+ 256 colors ~ -bgr233 default # of colors.
-+ 64 colors ~ -bgr222 / -use64
-+ 8 colors ~ -bgr111 / -use8
-+ Scale Viewer ~ -scale
-+ Escape Keys: Toggle ~ -escape
-+ Escape Keys: Help+Set ~ -escape
-+ Set Y Crop (y-max) ~ -ycrop
-+ Set Scrollbar Width ~ -sbwidth
-+ XGrabServer ~ -graball
-+
-+ UltraVNC Extensions:
-+
-+ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.
-+ Text Chat Ultravnc ext. Do Text Chat.
-+ File Transfer Ultravnc ext. File xfer via Java helper.
-+ Single Window Ultravnc ext. Grab and view a single window.
-+ (select then click on the window you want).
-+ Disable Remote Input Ultravnc ext. Try to prevent input and
-+ viewing of monitor at physical display.
-+
-+ Note: the Ultravnc extensions only apply to servers that support
-+ them. x11vnc/libvncserver supports some of them.
-+
-+ Send Clipboard not Primary ~ -sendclipboard
-+ Send Selection Every time ~ -sendalways
-+
-+.SH ENCODINGS
-+The server supplies information in whatever format is desired by the
-+client, in order to make the client as easy as possible to implement.
-+If the client represents itself as able to use multiple formats, the
-+server will choose one.
-+
-+.I Pixel format
-+refers to the representation of an individual pixel. The most common
-+formats are 24 and 16 bit "true\-color" values, and 8\-bit "color map"
-+representations, where an arbitrary map converts the color number to
-+RGB values.
-+
-+.I Encoding
-+refers to how a rectangle of pixels are sent (all pixel information in
-+VNC is sent as rectangles). All rectangles come with a header giving
-+the location and size of the rectangle and an encoding type used by
-+the data which follows. These types are listed below.
-+.TP
-+.B Raw
-+The raw encoding simply sends width*height pixel values. All clients
-+are required to support this encoding type. Raw is also the fastest
-+when the server and viewer are on the same machine, as the connection
-+speed is essentially infinite and raw encoding minimizes processing
-+time.
-+.TP
-+.B CopyRect
-+The Copy Rectangle encoding is efficient when something is being
-+moved; the only data sent is the location of a rectangle from which
-+data should be copied to the current location. Copyrect could also be
-+used to efficiently transmit a repeated pattern.
-+.TP
-+.B RRE
-+The Rise\-and\-Run\-length\-Encoding is basically a 2D version of
-+run\-length encoding (RLE). In this encoding, a sequence of identical
-+pixels are compressed to a single value and repeat count. In VNC, this
-+is implemented with a background color, and then specifications of an
-+arbitrary number of subrectangles and color for each. This is an
-+efficient encoding for large blocks of constant color.
-+.TP
-+.B CoRRE
-+This is a minor variation on RRE, using a maximum of 255x255 pixel
-+rectangles. This allows for single\-byte values to be used, reducing
-+packet size. This is in general more efficient, because the savings
-+from sending 1\-byte values generally outweighs the losses from the
-+(relatively rare) cases where very large regions are painted the same
-+color.
-+.TP
-+.B Hextile
-+Here, rectangles are split up in to 16x16 tiles, which are sent in a
-+predetermined order. The data within the tiles is sent either raw or
-+as a variant on RRE. Hextile encoding is usually the best choice for
-+using in high\-speed network environments (e.g. Ethernet local\-area
-+networks).
-+.TP
-+.B Zlib
-+Zlib is a very simple encoding that uses zlib library to compress raw
-+pixel data. This encoding achieves good compression, but consumes a
-+lot of CPU time. Support for this encoding is provided for
-+compatibility with VNC servers that might not understand Tight
-+encoding which is more efficient than Zlib in nearly all real\-life
-+situations.
-+.TP
-+.B Tight
-+Like Zlib encoding, Tight encoding uses zlib library to compress the
-+pixel data, but it pre\-processes data to maximize compression ratios,
-+and to minimize CPU usage on compression. Also, JPEG compression may
-+be used to encode color\-rich screen areas (see the description of
-+\-quality and \-nojpeg options above). Tight encoding is usually the
-+best choice for low\-bandwidth network environments (e.g. slow modem
-+connections).
-+.TP
-+.B ZRLE
-+The SSVNC viewer has ported the RealVNC (www.realvnc.com) ZRLE encoding
-+to the unix tightvnc viewer.
-+.TP
-+.B ZYWRLE
-+The SSVNC viewer has ported the Hitachi lossy wavelet based ZRLE
-+encoding from http://mobile.hitachi-system.co.jp/publications/ZYWRLE/
-+to the unix tightvnc viewer.
-+.SH RESOURCES
-+X resources that \fBvncviewer\fR knows about, aside from the
-+normal Xt resources, are as follows:
-+.TP
-+.B shareDesktop
-+Equivalent of \fB\-shared\fR/\fB\-noshared\fR options. Default true.
-+.TP
-+.B viewOnly
-+Equivalent of \fB\-viewonly\fR option. Default false.
-+.TP
-+.B fullScreen
-+Equivalent of \fB\-fullscreen\fR option. Default false.
-+.TP
-+.B grabKeyboard
-+Grab keyboard in full-screen mode. This can help to solve problems
-+with losing keyboard focus. Default false.
-+.TP
-+.B raiseOnBeep
-+Equivalent of \fB\-noraiseonbeep\fR option, when set to false. Default
-+true.
-+.TP
-+.B passwordFile
-+Equivalent of \fB\-passwd\fR option.
-+.TP
-+.B userLogin
-+Equivalent of \fB\-user\fR option.
-+.TP
-+.B passwordDialog
-+Whether to use a dialog box to get the password (true) or get it from
-+the tty (false). Irrelevant if \fBpasswordFile\fR is set. Default
-+false.
-+.TP
-+.B encodings
-+Equivalent of \fB\-encodings\fR option.
-+.TP
-+.B compressLevel
-+Equivalent of \fB\-compresslevel\fR option (TightVNC\-specific).
-+.TP
-+.B qualityLevel
-+Equivalent of \fB\-quality\fR option (TightVNC\-specific).
-+.TP
-+.B enableJPEG
-+Equivalent of \fB\-nojpeg\fR option, when set to false. Default true.
-+.TP
-+.B useRemoteCursor
-+Equivalent of \fB\-nocursorshape\fR option, when set to false
-+(TightVNC\-specific). Default true.
-+.TP
-+.B useBGR233
-+Equivalent of \fB\-bgr233\fR option. Default false.
-+.TP
-+.B nColours
-+When using BGR233, try to allocate this many "exact" colors from the
-+BGR233 color cube. When using a shared colormap, setting this resource
-+lower leaves more colors for other X clients. Irrelevant when using
-+truecolor. Default is 256 (i.e. all of them).
-+.TP
-+.B useSharedColours
-+If the number of "exact" BGR233 colors successfully allocated is less
-+than 256 then the rest are filled in using the "nearest" colors
-+available. This resource says whether to only use the "exact" BGR233
-+colors for this purpose, or whether to use other clients' "shared"
-+colors as well. Default true (i.e. use other clients' colors).
-+.TP
-+.B forceOwnCmap
-+Equivalent of \fB\-owncmap\fR option. Default false.
-+.TP
-+.B forceTrueColour
-+Equivalent of \fB\-truecolour\fR option. Default false.
-+.TP
-+.B requestedDepth
-+Equivalent of \fB\-depth\fR option.
-+.TP
-+.B useSharedMemory
-+Use MIT shared memory extension if on the same machine as the X
-+server. Default true.
-+.TP
-+.B wmDecorationWidth, wmDecorationHeight
-+The total width and height taken up by window manager decorations.
-+This is used to calculate the maximum size of the VNC viewer window.
-+Default is width 4, height 24.
-+.TP
-+.B bumpScrollTime, bumpScrollPixels
-+When in full screen mode and the VNC desktop is bigger than the X
-+display, scrolling happens whenever the mouse hits the edge of the
-+screen. The maximum speed of scrolling is bumpScrollPixels pixels
-+every bumpScrollTime milliseconds. The actual speed of scrolling will
-+be slower than this, of course, depending on how fast your machine is.
-+Default 20 pixels every 25 milliseconds.
-+.TP
-+.B popupButtonCount
-+The number of buttons in the popup window. See the README file for
-+more information on how to customize the buttons.
-+.TP
-+.B debug
-+For debugging. Default false.
-+.TP
-+.B rawDelay, copyRectDelay
-+For debugging, see the README file for details. Default 0 (off).
-+.SH ENVIRONMENT
-+When started with the \fB\-via\fR option, vncviewer reads the
-+\fBVNC_VIA_CMD\fR environment variable, expands patterns beginning
-+with the "%" character, and executes result as a command assuming that
-+it would create TCP tunnel that should be used for VNC connection. If
-+not set, this environment variable defaults to "/usr/bin/ssh -f -L
-+%L:%H:%R %G sleep 20".
-+
-+The following patterns are recognized in the \fBVNC_VIA_CMD\fR (note
-+that all the patterns %G, %H, %L and %R must be present in the command
-+template):
-+.TP
-+.B %%
-+A literal "%";
-+.TP
-+.B %G
-+gateway host name;
-+.TP
-+.B %H
-+remote VNC host name, as known to the gateway;
-+.TP
-+.B %L
-+local TCP port number;
-+.TP
-+.B %R
-+remote TCP port number.
-+.SH SEE ALSO
-+\fBvncserver\fR(1), \fBx11vnc\fR(1), \fBssvnc\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1),
-+\fBvncconnect\fR(1), \fBssh\fR(1), http://www.karlrunge.com/x11vnc, http://www.karlrunge.com/x11vnc/ssvnc.html
-+.SH AUTHORS
-+Original VNC was developed in AT&T Laboratories Cambridge. TightVNC
-+additions was implemented by Constantin Kaplinsky. Many other people
-+participated in development, testing and support. Karl J. Runge
-+added all of the SSVNC related features and improvements.
-+
-+\fBMan page authors:\fR
-+.br
-+Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de>,
-+.br
-+Terran Melconian <terran@consistent.org>,
-+.br
-+Tim Waugh <twaugh@redhat.com>,
-+.br
-+Constantin Kaplinsky <const@ce.cctpu.edu.ru>
-+.br
-+Karl J. Runge <runge@karlrunge.com>
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncviewer/vncviewer.c
---- vnc_unixsrc.orig/vncviewer/vncviewer.c 2004-01-13 09:22:05.000000000 -0500
-+++ vnc_unixsrc/vncviewer/vncviewer.c 2010-04-18 12:43:47.000000000 -0400
-@@ -22,6 +22,8 @@
- */
-
- #include "vncviewer.h"
-+#include <ctype.h>
-+#include <X11/Xaw/Toggle.h>
-
- char *programName;
- XtAppContext appContext;
-@@ -29,11 +31,274 @@
-
- Widget toplevel;
-
-+extern void raiseme(int force);
-+extern void CreateChat(void);
-+
-+void set_sbwidth(int sbw) {
-+ char *q, *p, t[5];
-+ int i, k, N = 4;
-+ int db = 0;
-+
-+ if (sbw < 1) {
-+ sbw = 2;
-+ } else if (sbw > 100) {
-+ sbw = 100;
-+ }
-+ if (db) fprintf(stderr, "sbw: %d\n", sbw);
-+
-+ sprintf(t, "%4d", sbw);
-+ k = 0;
-+ while (fallback_resources[k] != NULL) {
-+ q = strstr(fallback_resources[k], "horizontal.height: ");
-+ if (!q) {
-+ q = strstr(fallback_resources[k], "vertical.width: ");
-+ }
-+ if (q) {
-+ p = strdup(fallback_resources[k]);
-+ q = strstr(p, ": ");
-+ if (q) {
-+ q++;
-+ q++;
-+ for (i=0; i < N; i++) {
-+ *(q+i) = t[i];
-+ }
-+ fallback_resources[k] = p;
-+ if (db) fprintf(stderr, "res: %s\n\n", p);
-+ }
-+ }
-+ k++;
-+ }
-+}
-+
-+void min_title(void) {
-+ char *q;
-+ int k;
-+
-+ k = 0;
-+ while (fallback_resources[k] != NULL) {
-+ q = strstr(fallback_resources[k], "Ssvnc.title: ");
-+ if (q) {
-+ fallback_resources[k] = strdup("Ssvnc.title: %s");
-+ }
-+ k++;
-+ }
-+}
-+
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <unistd.h>
-+
-+void unixpw(char *instr, int vencrypt_plain) {
-+ char *str, *q, *infile = NULL;
-+ FILE *in;
-+ int i, rmfile = 0;
-+ struct stat sb;
-+ int N = 99;
-+ char username[100], passwd[100];
-+ static int did = 0;
-+
-+ if (did) {
-+ return;
-+ }
-+ did = 1;
-+
-+ for (i=0; i<100; i++) {
-+ username[i] = '\0';
-+ passwd[i] = '\0';
-+ }
-+
-+ if (instr == NULL) {
-+ return;
-+ } else if (!strcmp(instr, "")) {
-+ return;
-+ }
-+
-+ str = strdup(instr);
-+
-+ if (strstr(str, "rm:") == str) {
-+ rmfile = 1;
-+ infile = str + strlen("rm:");
-+ } else if (stat(str, &sb) == 0) {
-+ infile = str;
-+ }
-+ if (!strcmp(str, ".")) {
-+ char *p;
-+ if (!use_tty()) {
-+ char *u;
-+ fprintf(stderr, "\nEnter Unix Username and Password in the popups.\n");
-+ u = DoUserDialog();
-+ if (strlen(u) >= 100) {
-+ exit(1);
-+ }
-+ sprintf(username, u);
-+ p = DoPasswordDialog();
-+ } else {
-+ raiseme(1);
-+ fprintf(stderr, "\nUnix Username: ");
-+ if (fgets(username, N, stdin) == NULL) {
-+ exit(1);
-+ }
-+ p = getpass("Unix Password: ");
-+ }
-+ if (! p) {
-+ exit(1);
-+ }
-+ strncpy(passwd, p, N);
-+ fprintf(stderr, "\n");
-+
-+ } else if (!strcmp(str, "-")) {
-+ char *p, *q;
-+ if (!use_tty()) {
-+ fprintf(stderr, "\nEnter unixuser@unixpasswd in the popup.\n");
-+ p = DoPasswordDialog();
-+ } else {
-+ raiseme(1);
-+ p = getpass("unixuser@unixpasswd: ");
-+ }
-+ if (! p) {
-+ exit(1);
-+ }
-+ q = strchr(p, '@');
-+ if (! q) {
-+ exit(1);
-+ }
-+ *q = '\0';
-+ strncpy(username, p, N);
-+ strncpy(passwd, q+1, N);
-+
-+ } else if (infile) {
-+ in = fopen(infile, "r");
-+ if (in == NULL) {
-+ fprintf(stderr, "failed to open -unixpw file.\n");
-+ exit(1);
-+ }
-+ if (fgets(username, N, in) == NULL) {
-+ exit(1);
-+ }
-+ if (fgets(passwd, N, in) == NULL) {
-+ exit(1);
-+ }
-+ fclose(in);
-+ fprintf(stderr, "read username@passwd from file: %s\n", infile);
-+ if (rmfile) {
-+ fprintf(stderr, "deleting username@passwd file: %s\n", infile);
-+ unlink(infile);
-+ }
-+ } else if (strchr(str, '@')) {
-+ char *q = strchr(str, '@');
-+ *q = '\0';
-+ strncpy(username, str, N);
-+ strncpy(passwd, q+1, N);
-+ } else {
-+ exit(1);
-+ }
-+
-+ free(str);
-+
-+ if (vencrypt_plain) {
-+ CARD32 ulen, plen;
-+ char *q;
-+
-+ q = strrchr(username, '\n');
-+ if (q) *q = '\0';
-+ q = strrchr(passwd, '\n');
-+ if (q) *q = '\0';
-+
-+ ulen = Swap32IfLE((CARD32)strlen(username));
-+ plen = Swap32IfLE((CARD32)strlen(passwd));
-+
-+ if (!WriteExact(rfbsock, (char *)&ulen, 4) ||
-+ !WriteExact(rfbsock, (char *)&plen, 4)) {
-+ return;
-+ }
-+
-+ if (!WriteExact(rfbsock, username, strlen(username)) ||
-+ !WriteExact(rfbsock, passwd, strlen(passwd))) {
-+ return;
-+ }
-+ return;
-+ }
-+
-+
-+ if (! getenv("SSVNC_UNIXPW_NOESC")) {
-+ SendKeyEvent(XK_Escape, 1);
-+ SendKeyEvent(XK_Escape, 0);
-+ }
-+
-+ q = username;
-+ while (*q != '\0' && *q != '\n') {
-+ char c = *q;
-+ if (c >= 0x20 && c <= 0x07e) {
-+ KeySym ks = (KeySym) c;
-+ SendKeyEvent(ks, 1);
-+ SendKeyEvent(ks, 0);
-+ }
-+ q++;
-+ }
-+
-+ SendKeyEvent(XK_Return, 1);
-+ SendKeyEvent(XK_Return, 0);
-+
-+ q = passwd;
-+ while (*q != '\0' && *q != '\n') {
-+ char c = *q;
-+ if (c >= 0x20 && c <= 0x07e) {
-+ KeySym ks = (KeySym) c;
-+ SendKeyEvent(ks, 1);
-+ SendKeyEvent(ks, 0);
-+ }
-+ q++;
-+ }
-+
-+ SendKeyEvent(XK_Return, 1);
-+ SendKeyEvent(XK_Return, 0);
-+}
-+
-+static void chat_window_only(void) {
-+ if (appData.chatOnly) {
-+ static double last_time = 0.0;
-+ if (dnow() > last_time + 1.5) {
-+ XSync(dpy, False);
-+ XUnmapWindow(dpy, XtWindow(toplevel));
-+ }
-+ }
-+}
-+
-+int saw_appshare = 0;
-+
- int
- main(int argc, char **argv)
- {
-- int i;
-- programName = argv[0];
-+ int i, save_sbw, saw_listen = 0;
-+ char *pw_loc = NULL;
-+ programName = argv[0];
-+
-+ if (strrchr(programName, '/') != NULL) {
-+ programName = strrchr(programName, '/') + 1;
-+ }
-+
-+ for (i = 1; i < argc; i++) {
-+ if (!strcmp(argv[i], "-env")) {
-+ if (i+1 < argc) {
-+ char *estr = argv[i+1];
-+ if (strchr(estr, '=')) {
-+ putenv(estr);
-+ }
-+ }
-+ }
-+ if (!strcmp(argv[i], "-noipv4")) {
-+ putenv("VNCVIEWER_NO_IPV4=1");
-+ }
-+ if (!strcmp(argv[i], "-noipv6")) {
-+ putenv("VNCVIEWER_NO_IPV6=1");
-+ }
-+ }
-+ if (getenv("VNCVIEWER_NO_IPV4")) {
-+ appData.noipv4 = True;
-+ }
-+ if (getenv("VNCVIEWER_NO_IPV6")) {
-+ appData.noipv6 = True;
-+ }
-
- /* The -listen option is used to make us a daemon process which listens for
- incoming connections from servers, rather than actively connecting to a
-@@ -45,89 +310,1744 @@
- listenForIncomingConnections() returns, setting the listenSpecified
- flag. */
-
-- for (i = 1; i < argc; i++) {
-- if (strcmp(argv[i], "-listen") == 0) {
-- listenForIncomingConnections(&argc, argv, i);
-- break;
-- }
-- if (strcmp(argv[i], "-tunnel") == 0 || strcmp(argv[i], "-via") == 0) {
-- if (!createTunnel(&argc, argv, i))
-- exit(1);
-- break;
-- }
-- }
-+ for (i = 1; i < argc; i++) {
-+ if (!strcmp(argv[i], "-appshare")) {
-+ putenv("SSVNC_MULTIPLE_LISTEN=1");
-+ fprintf(stderr, "Enabling -multilisten mode for 'x11vnc -appshare' usage.\n\n");
-+ saw_appshare = 1;
-+ }
-+ if (!strcmp(argv[i], "-multilisten")) {
-+ putenv("SSVNC_MULTIPLE_LISTEN=1");
-+ saw_listen = 2;
-+ }
-+ if (!strcmp(argv[i], "-listen")) {
-+ saw_listen = 1;
-+ }
-+ if (!strcmp(argv[i], "-acceptpopup")) {
-+ putenv("SSVNC_ACCEPT_POPUP=1");
-+ }
-+ if (!strcmp(argv[i], "-acceptpopupsc")) {
-+ putenv("SSVNC_ACCEPT_POPUP_SC=1");
-+ }
-+ if (strstr(argv[i], " pw=") != NULL) {
-+ pw_loc = strstr(argv[i], " pw=") + 1;
-+ }
-+ }
-+
-+ for (i = 1; i < argc; i++) {
-+ if (!strcmp(argv[i], "-appshare") && !saw_listen) {
-+ listenForIncomingConnections(&argc, argv, i);
-+ break;
-+ }
-+ if (!strcmp(argv[i], "-multilisten")) {
-+ listenForIncomingConnections(&argc, argv, i);
-+ break;
-+ }
-+ if (!strcmp(argv[i], "-listen")) {
-+ listenForIncomingConnections(&argc, argv, i);
-+ break;
-+ }
-+ if (!strcmp(argv[i], "-tunnel") || !strcmp(argv[i], "-via")) {
-+ if (!createTunnel(&argc, argv, i)) {
-+ exit(1);
-+ }
-+ break;
-+ }
-+ if (!strcmp(argv[i], "-printres") || !strcmp(argv[i], "-res")) {
-+ int j = 0;
-+ fprintf(stdout, "\n! Ssvnc fallback X resources:\n\n");
-+ while (1) {
-+ char *p = fallback_resources[j++];
-+ int k = 0;
-+ if (p == NULL) break;
-+ while (*p != '\0') {
-+ fprintf(stdout, "%c", *p);
-+ if (k > 0 && *p == 'n' && *(p-1) == '\\') {
-+ fprintf(stdout, "\\\n");
-+ }
-+ p++; k++;
-+ }
-+ fprintf(stdout, "\n\n");
-+ }
-+ exit(0);
-+ }
-+ }
-+
-+
-+ if (argc > 1 && strstr(argv[1], "-h") == argv[1]) {
-+ usage();
-+ return 0;
-+ }
-
- /* Call the main Xt initialisation function. It parses command-line options,
- generating appropriate resource specs, and makes a connection to the X
- display. */
-
-- toplevel = XtVaAppInitialize(&appContext, "Vncviewer",
-- cmdLineOptions, numCmdLineOptions,
-- &argc, argv, fallback_resources,
-- XtNborderWidth, 0, NULL);
-+ if (saw_appshare || getenv("VNCVIEWER_MIN_TITLE")) {
-+ min_title();
-+ }
-+ appData.sbWidth = 0;
-+ if (getenv("VNCVIEWER_SBWIDTH")) {
-+ int sbw = atoi(getenv("VNCVIEWER_SBWIDTH"));
-+ if (sbw > 0) {
-+ appData.sbWidth = sbw;
-+ }
-+ }
-+ if (appData.sbWidth == 0) {
-+ int i, sbw = 0;
-+ for (i = 1; i < argc - 1; i++) {
-+ if (!strcmp(argv[i], "-sbwidth")) {
-+ sbw = atoi(argv[i+1]);
-+ }
-+ }
-+ if (sbw > 0) {
-+ appData.sbWidth = sbw;
-+ }
-+ }
-+ save_sbw = appData.sbWidth;
-+ if (save_sbw > 0) {
-+ set_sbwidth(save_sbw);
-+ } else {
-+ set_sbwidth(6);
-+ }
-+
-+ toplevel = XtVaAppInitialize(&appContext, "Ssvnc", cmdLineOptions,
-+ numCmdLineOptions, &argc, argv, fallback_resources,
-+ XtNborderWidth, 0, NULL);
-
-- dpy = XtDisplay(toplevel);
-+ dpy = XtDisplay(toplevel);
-
- /* Interpret resource specs and process any remaining command-line arguments
- (i.e. the VNC server name). If the server name isn't specified on the
- command line, getArgsAndResources() will pop up a dialog box and wait
- for one to be entered. */
-
-- GetArgsAndResources(argc, argv);
-+ GetArgsAndResources(argc, argv);
-+
-+ if (saw_appshare) {
-+ appData.appShare = True;
-+ }
-+
-+ if (save_sbw) {
-+ appData.sbWidth = save_sbw;
-+ }
-+
-+ if (appData.chatOnly) {
-+ appData.encodingsString = "raw hextile";
-+ }
-+
-+ if (pw_loc != NULL) {
-+ char *q = pw_loc;
-+ while (*q != '\0' && !isspace(*q)) {
-+ *q = ' ';
-+ q++;
-+ }
-+ }
-
- /* Unless we accepted an incoming connection, make a TCP connection to the
- given VNC server */
-
-- if (!listenSpecified) {
-- if (!ConnectToRFBServer(vncServerHost, vncServerPort)) exit(1);
-- }
-+ if (appData.repeaterUltra == NULL) {
-+ if (getenv("SSVNC_REPEATER") != NULL) {
-+ appData.repeaterUltra = strdup(getenv("SSVNC_REPEATER"));
-+ }
-+ }
-+
-+ if (!listenSpecified) {
-+ if (!ConnectToRFBServer(vncServerHost, vncServerPort)) {
-+ exit(1);
-+ }
-+ if (appData.repeaterUltra != NULL) {
-+ char tmp[256];
-+ if (strstr(appData.repeaterUltra, "SCIII=") == appData.repeaterUltra) {
-+ appData.repeaterUltra = strdup(appData.repeaterUltra + strlen("SCIII="));
-+ fprintf(stderr, "sending 'testB' to ultravnc SC III SSL repeater...\n");
-+ WriteExact(rfbsock, "testB" , 5);
-+ }
-+ if (ReadFromRFBServer(tmp, 12)) {
-+ tmp[12] = '\0';
-+ fprintf(stderr, "repeater 1st proto line: '%s'\n", tmp);
-+ if (strstr(tmp, "RFB 000.000") == tmp) {
-+ int i;
-+ for (i=0; i<256; i++) {
-+ tmp[i] = '\0';
-+ }
-+ for (i=0; i<250; i++) {
-+ if (i >= (int) strlen(appData.repeaterUltra)) {
-+ break;
-+ }
-+ tmp[i] = appData.repeaterUltra[i];
-+ }
-+ fprintf(stderr, "sending '%s' to repeater...\n", tmp);
-+ WriteExact(rfbsock, tmp, 250);
-+ }
-+ } else {
-+ fprintf(stderr, "repeater NO proto line!\n");
-+ }
-+ }
-+ }
-
- /* Initialise the VNC connection, including reading the password */
-
-- if (!InitialiseRFBConnection()) exit(1);
-+ if (!InitialiseRFBConnection()) {
-+ Cleanup();
-+ exit(1);
-+ }
-+ if (appData.unixPW != NULL) {
-+ unixpw(appData.unixPW, 0);
-+ } else if (getenv("SSVNC_UNIXPW")) {
-+ unixpw(getenv("SSVNC_UNIXPW"), 0);
-+ }
-
- /* Create the "popup" widget - this won't actually appear on the screen until
- some user-defined event causes the "ShowPopup" action to be invoked */
-
-- CreatePopup();
-+ CreatePopup();
-+ CreateScaleN();
-+ CreateTurboVNC();
-+ CreateQuality();
-+ CreateCompress();
-+ CreateChat();
-
- /* Find the best pixel format and X visual/colormap to use */
-
-- SetVisualAndCmap();
-+ SetVisualAndCmap();
-
- /* Create the "desktop" widget, and perform initialisation which needs doing
- before the widgets are realized */
-
-- ToplevelInitBeforeRealization();
-+ ToplevelInitBeforeRealization();
-
-- DesktopInitBeforeRealization();
-+ DesktopInitBeforeRealization();
-
- /* "Realize" all the widgets, i.e. actually create and map their X windows */
-
-- XtRealizeWidget(toplevel);
-+ XtRealizeWidget(toplevel);
-
- /* Perform initialisation that needs doing after realization, now that the X
- windows exist */
-
-- InitialiseSelection();
-+ InitialiseSelection();
-
-- ToplevelInitAfterRealization();
-+ ToplevelInitAfterRealization();
-
-- DesktopInitAfterRealization();
-+ DesktopInitAfterRealization();
-
- /* Tell the VNC server which pixel format and encodings we want to use */
-
-- SetFormatAndEncodings();
-+ SetFormatAndEncodings();
-+
-+ if (appData.chatOnly) {
-+ chat_window_only();
-+ ToggleTextChat(0, NULL, NULL, NULL);
-+ }
-
- /* Now enter the main loop, processing VNC messages. X events will
- automatically be processed whenever the VNC connection is idle. */
-
-- while (1) {
-- if (!HandleRFBServerMessage())
-- break;
-- }
-+ while (1) {
-+ if (!HandleRFBServerMessage()) {
-+ break;
-+ }
-+ if (appData.chatOnly) {
-+ chat_window_only();
-+ }
-+ }
-+
-+ Cleanup();
-+
-+ return 0;
-+}
-+
-+/*
-+ * Toggle8bpp
-+ */
-+
-+static int last_ncolors = 0;
-+static int save_useBGR233 = 0;
-+static Bool save_useBGR565 = False;
-+
-+static Widget b8 = NULL;
-+static Widget b16 = NULL;
-+static Widget bfull = NULL;
-+
-+int do_format_change = 0;
-+int do_cursor_change = 0;
-+double do_fb_update = 0.0;
-+static void schedule_format_change(void) {
-+ do_format_change = 1;
-+ do_cursor_change = 0;
-+}
-+extern double dnow(void);
-+static void schedule_fb_update(void) {
-+ do_fb_update = dnow();
-+}
-+static void init_format_change(void) {
-+ appDataNew.useBGR233 = appData.useBGR233;
-+ appDataNew.useBGR565 = appData.useBGR565;
-+ appDataNew.useGreyScale = appData.useGreyScale;
-+ appDataNew.enableJPEG = appData.enableJPEG;
-+ appDataNew.encodingsString = appData.encodingsString;
-+ appDataNew.useRemoteCursor = appData.useRemoteCursor;
-+ appDataNew.useX11Cursor = appData.useX11Cursor;
-+ appDataNew.useRawLocal = appData.useRawLocal;
-+ appDataNew.qualityLevel = appData.qualityLevel;
-+ appDataNew.compressLevel = appData.compressLevel;
-+}
-+void cutover_format_change(void) {
-+ appData.useBGR233 = appDataNew.useBGR233;
-+ appData.useBGR565 = appDataNew.useBGR565;
-+ appData.useGreyScale = appDataNew.useGreyScale;
-+ appData.enableJPEG = appDataNew.enableJPEG;
-+ appData.encodingsString = appDataNew.encodingsString;
-+ appData.useRemoteCursor = appDataNew.useRemoteCursor;
-+ appData.useX11Cursor = appDataNew.useX11Cursor;
-+ appData.useRawLocal = appDataNew.useRawLocal;
-+ appData.qualityLevel = appDataNew.qualityLevel;
-+ appData.compressLevel = appDataNew.compressLevel;
-+}
-+
-+void
-+Toggle8bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ fprintf(stderr, "Toggle8bpp: %d\n", appData.useBGR233);
-+ b8 = w;
-+ init_format_change();
-+ if (appData.useBGR233) {
-+ last_ncolors = appData.useBGR233;
-+ appDataNew.useBGR233 = 0;
-+ appDataNew.useBGR565 = save_useBGR565;
-+ fprintf(stderr, "8bpp: off\n");
-+ } else {
-+ if (!last_ncolors) last_ncolors = 256;
-+ appDataNew.useBGR233 = last_ncolors;
-+ save_useBGR565 = appData.useBGR565;
-+ appDataNew.useBGR565 = False;
-+ fprintf(stderr, "8bpp: on (%d colors)\n", appDataNew.useBGR233);
-+ }
-+ schedule_format_change();
-+ if (w || ev || params || num_params) {}
-+}
-+
-+
-+void
-+Toggle16bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ fprintf(stderr, "Toggle16bpp: %d\n", appData.useBGR565);
-+ b16 = w;
-+ init_format_change();
-+ if (appData.useBGR565) {
-+ appDataNew.useBGR565 = False;
-+ appDataNew.useBGR233 = save_useBGR233;
-+ fprintf(stderr, "16bpp: off\n");
-+ } else {
-+ appDataNew.useBGR565 = True;
-+ save_useBGR233 = appData.useBGR233;
-+ appDataNew.useBGR233 = 0;
-+ fprintf(stderr, "16bpp: on\n");
-+ }
-+ schedule_format_change();
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleFullColor(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ fprintf(stderr, "ToggleFullColor\n");
-+ bfull = w;
-+ init_format_change();
-+ if (appData.useBGR565 || appData.useBGR233) {
-+ save_useBGR565 = appData.useBGR565;
-+ appDataNew.useBGR565 = False;
-+ save_useBGR233 = appData.useBGR233;
-+ appDataNew.useBGR233 = 0;
-+ fprintf(stderr, "FullColor: on\n");
-+ } else {
-+ if (save_useBGR565) {
-+ appDataNew.useBGR565 = True;
-+ appDataNew.useBGR233 = 0;
-+ fprintf(stderr, "FullColor off -> 16bpp.\n");
-+ } else {
-+ appDataNew.useBGR565 = False;
-+ if (!save_useBGR233) save_useBGR233 = 256;
-+ appDataNew.useBGR233 = save_useBGR233;
-+ fprintf(stderr, "FullColor off -> 8bpp.\n");
-+ }
-+ }
-+ schedule_format_change();
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleXGrab(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.grabAll) {
-+ appData.grabAll = False;
-+ } else {
-+ appData.grabAll = True;
-+ }
-+ fprintf(stderr, "ToggleXGrab, current=%d\n", appData.grabAll);
-+ /* always ungrab to be sure, fullscreen will handle the rest */
-+ XUngrabServer(dpy);
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleEscapeActive(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.escapeActive) {
-+ appData.escapeActive = False;
-+ } else {
-+ appData.escapeActive = True;
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+/*
-+ * ToggleNColors
-+ */
-+
-+static Widget w256 = NULL;
-+static Widget w64 = NULL;
-+static Widget w8 = NULL;
-+
-+void
-+Toggle256Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ w256 = w;
-+ if (appData.useBGR233 != 256) {
-+ fprintf(stderr, "256 colors: on\n");
-+ init_format_change();
-+ last_ncolors = appDataNew.useBGR233 = 256;
-+ save_useBGR565 = appData.useBGR565;
-+ appDataNew.useBGR565 = False;
-+ schedule_format_change();
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+Toggle64Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ w64 = w;
-+ if (appData.useBGR233 != 64) {
-+ fprintf(stderr, "64 colors: on\n");
-+ init_format_change();
-+ last_ncolors = appDataNew.useBGR233 = 64;
-+ save_useBGR565 = appData.useBGR565;
-+ appDataNew.useBGR565 = False;
-+ schedule_format_change();
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+Toggle8Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ w8 = w;
-+ if (appData.useBGR233 != 8) {
-+ fprintf(stderr, "8 colors: on\n");
-+ init_format_change();
-+ last_ncolors = appDataNew.useBGR233 = 8;
-+ save_useBGR565 = appData.useBGR565;
-+ appDataNew.useBGR565 = False;
-+ schedule_format_change();
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleGreyScale(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ fprintf(stderr, "ToggleGreyScale\n");
-+ init_format_change();
-+ if (appData.useGreyScale) {
-+ appDataNew.useGreyScale = False;
-+ fprintf(stderr, "greyscale: off\n");
-+ } else {
-+ appDataNew.useGreyScale = True;
-+ fprintf(stderr, "greyscale: on\n");
-+ }
-+ schedule_format_change();
-+ if (w || ev || params || num_params) {}
-+}
-+
-+/*
-+ * ToggleJPEG
-+ */
-+
-+void
-+ToggleJPEG(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ init_format_change();
-+ if (appData.enableJPEG) {
-+ appDataNew.enableJPEG = False;
-+ fprintf(stderr, "JPEG: off\n");
-+ } else {
-+ appDataNew.enableJPEG = True;
-+ fprintf(stderr, "JPEG: on\n");
-+ }
-+ schedule_format_change();
-+ if (w || ev || params || num_params) {}
-+}
-+
-+/*
-+ * ToggleTightZRLE
-+ */
-+
-+static Bool usingZRLE = False;
-+static Bool usingZYWRLE = False;
-+static Bool usingHextile = False;
-+extern int skip_maybe_sync;
-+
-+void
-+ToggleTightZRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ char prefTight[] = "copyrect tight zrle zywrle zlib hextile corre rre raw";
-+ char prefZRLE[] = "copyrect zrle zywrle tight zlib hextile corre rre raw";
-+ init_format_change();
-+ usingHextile = False;
-+ if (! appData.encodingsString) {
-+ appDataNew.encodingsString = strdup(prefZRLE);
-+ usingZRLE = True;
-+ fprintf(stderr, "prefer: ZRLE\n");
-+ } else {
-+ char *t, *z;
-+ static int first = 1;
-+ t = strstr(appData.encodingsString, "tight");
-+ z = strstr(appData.encodingsString, "zrle");
-+ if (first && usingZRLE) {
-+ appDataNew.encodingsString = strdup(prefTight);
-+ usingZRLE = False;
-+ usingZYWRLE = False;
-+ } else if (! t) {
-+ appDataNew.encodingsString = strdup(prefZRLE);
-+ usingZRLE = True;
-+ fprintf(stderr, "prefer: ZRLE\n");
-+ } else if (! z) {
-+ appDataNew.encodingsString = strdup(prefTight);
-+ usingZRLE = False;
-+ usingZYWRLE = False;
-+ skip_maybe_sync = 0;
-+ fprintf(stderr, "prefer: Tight\n");
-+ } else {
-+ if (t < z) {
-+ appDataNew.encodingsString = strdup(prefZRLE);
-+ usingZRLE = True;
-+ fprintf(stderr, "prefer: ZRLE\n");
-+ } else {
-+ appDataNew.encodingsString = strdup(prefTight);
-+ usingZRLE = False;
-+ usingZYWRLE = False;
-+ skip_maybe_sync = 0;
-+ fprintf(stderr, "prefer: Tight\n");
-+ }
-+ }
-+ first = 0;
-+ }
-+ schedule_format_change();
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleZRLEZYWRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ char prefZYWRLE[] = "copyrect zywrle zrle tight zlib hextile corre rre raw";
-+ char prefZRLE[] = "copyrect zrle zywrle tight zlib hextile corre rre raw";
-+ init_format_change();
-+ usingZRLE = True;
-+ usingHextile = False;
-+ if (! appData.encodingsString) {
-+ appDataNew.encodingsString = strdup(prefZYWRLE);
-+ usingZYWRLE = True;
-+ fprintf(stderr, "prefer: ZYWRLE\n");
-+ } else {
-+ char *z, *w;
-+ w = strstr(appData.encodingsString, "zywrle");
-+ z = strstr(appData.encodingsString, "zrle");
-+ if (usingZYWRLE) {
-+ appDataNew.encodingsString = strdup(prefZRLE);
-+ fprintf(stderr, "prefer: ZRLE\n");
-+ usingZYWRLE = False;
-+ skip_maybe_sync = 0;
-+ } else {
-+ appDataNew.encodingsString = strdup(prefZYWRLE);
-+ fprintf(stderr, "prefer: ZYWRLE\n");
-+ usingZYWRLE = True;
-+ }
-+ }
-+ schedule_format_change();
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleTightHextile(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ char prefTight[] = "copyrect tight zrle zywrle zlib hextile corre rre raw";
-+ char prefHextile[] = "copyrect hextile tight zrle zywrle zlib corre rre raw";
-+ init_format_change();
-+ usingZRLE = False;
-+ usingZYWRLE = False;
-+ if (! appData.encodingsString) {
-+ appDataNew.encodingsString = strdup(prefHextile);
-+ usingHextile = True;
-+ fprintf(stderr, "prefer: Hextile\n");
-+ } else {
-+ char *t, *z;
-+ static int first = 1;
-+ t = strstr(appData.encodingsString, "tight");
-+ z = strstr(appData.encodingsString, "hextile");
-+ if (first && usingHextile) {
-+ appDataNew.encodingsString = strdup(prefTight);
-+ usingHextile = False;
-+ } else if (! t) {
-+ appDataNew.encodingsString = strdup(prefHextile);
-+ usingHextile = True;
-+ fprintf(stderr, "prefer: Hextile\n");
-+ } else if (! z) {
-+ appDataNew.encodingsString = strdup(prefTight);
-+ usingHextile = False;
-+ skip_maybe_sync = 0;
-+ fprintf(stderr, "prefer: Tight\n");
-+ } else {
-+ if (t < z) {
-+ appDataNew.encodingsString = strdup(prefHextile);
-+ usingHextile = True;
-+ fprintf(stderr, "prefer: Hextile\n");
-+ } else {
-+ appDataNew.encodingsString = strdup(prefTight);
-+ usingHextile = False;
-+ skip_maybe_sync = 0;
-+ fprintf(stderr, "prefer: Tight\n");
-+ }
-+ }
-+ first = 0;
-+ }
-+ schedule_format_change();
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void scale_check_zrle(void) {
-+ static int didit = 0;
-+ if (didit) {
-+ return;
-+ }
-+ didit = 1;
-+ if (getenv("SSVNC_PRESERVE_ENCODING")) {
-+ return;
-+ }
-+ if (!usingZRLE && !usingHextile) {
-+ Widget w = 0;
-+ fprintf(stderr, "\nSwitching to faster ZRLE encoding in client-side scaling mode.\n");
-+ fprintf(stderr, "Switch back to Tight via the Popup menu if you prefer it.\n\n");
-+ ToggleTightZRLE(w, NULL, NULL, NULL);
-+ }
-+}
-+
-+/*
-+ * ToggleViewOnly
-+ */
-+
-+void
-+ToggleViewOnly(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.viewOnly) {
-+ appData.viewOnly = False;
-+ fprintf(stderr, "viewonly: off\n");
-+ } else {
-+ appData.viewOnly = True;
-+ fprintf(stderr, "viewonly: on\n");
-+ }
-+ Xcursors(1);
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleCursorShape(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ init_format_change();
-+ if (appData.useRemoteCursor) {
-+ appDataNew.useRemoteCursor = False;
-+ fprintf(stderr, "useRemoteCursor: off\n");
-+ } else {
-+ appDataNew.useRemoteCursor = True;
-+ fprintf(stderr, "useRemoteCursor: on\n");
-+ }
-+ schedule_format_change();
-+ if (!appDataNew.useRemoteCursor) {
-+ do_cursor_change = 1;
-+ } else {
-+ do_cursor_change = -1;
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleCursorAlpha(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useCursorAlpha) {
-+ appData.useCursorAlpha = False;
-+ fprintf(stderr, "useCursorAlpha: off\n");
-+ } else {
-+ appData.useCursorAlpha = True;
-+ fprintf(stderr, "useCursorAlpha: on\n");
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleX11Cursor(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ init_format_change();
-+ if (appData.useX11Cursor) {
-+ appDataNew.useX11Cursor = False;
-+ fprintf(stderr, "useX11Cursor: off\n");
-+ } else {
-+ appDataNew.useX11Cursor = True;
-+ fprintf(stderr, "useX11Cursor: on\n");
-+ }
-+ schedule_format_change();
-+ do_cursor_change = 1;
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleBell(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useBell) {
-+ appData.useBell = False;
-+ fprintf(stderr, "useBell: off\n");
-+ } else {
-+ appData.useBell = True;
-+ fprintf(stderr, "useBell: on\n");
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleRawLocal(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ init_format_change();
-+ if (appData.useRawLocal) {
-+ appDataNew.useRawLocal = False;
-+ fprintf(stderr, "useRawLocal: off\n");
-+ } else {
-+ appDataNew.useRawLocal = True;
-+ fprintf(stderr, "useRawLocal: on\n");
-+ }
-+ schedule_format_change();
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleServerInput(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.serverInput) {
-+ appData.serverInput= False;
-+ fprintf(stderr, "serverInput: off\n");
-+ SendServerInput(True);
-+ } else {
-+ appData.serverInput = True;
-+ fprintf(stderr, "serverInput: on\n");
-+ SendServerInput(False);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+TogglePipelineUpdates(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.pipelineUpdates) {
-+ appData.pipelineUpdates= False;
-+ fprintf(stderr, "pipeline-update: off\n");
-+ } else {
-+ appData.pipelineUpdates = True;
-+ fprintf(stderr, "pipeline-update: on\n");
-+ }
-+ /* XXX request one to be sure? */
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleSendClipboard(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.sendClipboard) {
-+ appData.sendClipboard= False;
-+ fprintf(stderr, "Send CLIPBOARD Selection: off (send PRIMARY instead)\n");
-+ } else {
-+ appData.sendClipboard = True;
-+ fprintf(stderr, "Send CLIPBOARD Selection: on (do not send PRIMARY)\n");
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+ToggleSendAlways(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.sendAlways) {
-+ appData.sendAlways= False;
-+ fprintf(stderr, "Send Selection Always: off\n");
-+ } else {
-+ appData.sendAlways = True;
-+ fprintf(stderr, "Send Selection Always: on\n");
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+
-+Bool _sw1_ = False; /* XXX this is a weird bug... */
-+Bool _sw2_ = False;
-+Bool _sw3_ = False;
-+Bool selectingSingleWindow = False;
-+
-+extern Cursor bogoCursor;
-+
-+void
-+ToggleSingleWindow(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.singleWindow) {
-+ appData.singleWindow= False;
-+ fprintf(stderr, "singleWindow: off\n");
-+ SendSingleWindow(-1, -1);
-+ } else {
-+ appData.singleWindow = True;
-+ selectingSingleWindow = True;
-+ fprintf(stderr, "singleWindow: on\n");
-+ if (bogoCursor != None) {
-+ XDefineCursor(dpy, desktopWin, bogoCursor);
-+ }
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void raiseme(int force);
-+void AppendChatInput(char *);
-+
-+extern void ShowChat(Widget w, XEvent *event, String *params, Cardinal *num_params);
-+extern void ShowFile(Widget w, XEvent *event, String *params, Cardinal *num_params);
-+extern Bool SendTextChatFinished(void);
-+
-+
-+void printChat(char *str, Bool raise) {
-+ if (appData.termChat) {
-+ if (raise) {
-+ raiseme(0);
-+ }
-+ fprintf(stderr, str);
-+ } else {
-+ if (raise) {
-+ ShowChat(0, 0, 0, 0);
-+ }
-+ AppendChatInput(str);
-+ }
-+}
-+
-+void
-+ToggleTextChat(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.chatActive) {
-+ printChat("\n*SentClose*\n\n", False);
-+ SendTextChatClose();
-+ SendTextChatFinished();
-+ HideChat(0, NULL, NULL, NULL);
-+ appData.chatActive= False;
-+ } else {
-+ ShowChat(0, 0, 0, 0);
-+ SendTextChatOpen();
-+ if (appData.termChat) {
-+ printChat("\n*SentOpen*\n\nSend: ", True);
-+ } else {
-+ printChat("\n*SentOpen*\n", True);
-+ }
-+ appData.chatActive = True;
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+extern int filexfer_sock;
-+extern pid_t java_helper;
-+#define KILLJAVA
-+#ifdef KILLJAVA
-+#include <signal.h>
-+#endif
-+
-+void
-+ToggleFileXfer(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ static double last_start = 0.0;
-+ if (appData.fileActive) {
-+#if 0
-+ HideFile(w, ev, params, num_params);
-+ appData.fileActive = False;
-+#endif
-+#ifndef KILLJAVA
-+ if (filexfer_sock >= 0) {
-+ close(filexfer_sock);
-+ }
-+#else
-+ if (java_helper != 0) {
-+ int i;
-+ if (dnow() < last_start + 6.0) {
-+ fprintf(stderr, "skipping early kill of java helper (less than 5 secs)\n");
-+ } else {
-+ for (i=1; i<=5; i++) {
-+ pid_t p = java_helper + i;
-+ fprintf(stderr, "trying to kill java helper: %d\n", p);
-+ if (kill(p, SIGTERM) == 0) {
-+ java_helper = 0;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+#endif
-+ } else {
-+ ShowFile(w, ev, params, num_params);
-+ appData.fileActive = True;
-+ last_start = dnow();
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+static int fooHandler(Display *dpy, XErrorEvent *error) {
-+ if (dpy || error) {}
-+ return 0;
-+}
-+
-+void raiseme(int force) {
-+ if ((force || appData.termChat) && getenv("WINDOWID")) {
-+ unsigned long w;
-+ if (sscanf(getenv("WINDOWID"), "%lu", &w) == 1) {
-+ ;
-+ } else if (sscanf(getenv("WINDOWID"), "0x%lx", &w) == 1) {
-+ ;
-+ } else {
-+ w = 0;
-+ }
-+ if (w != 0) {
-+ XErrorHandler old = XSetErrorHandler(fooHandler);
-+ XMapRaised(dpy, (Window) w);
-+ XSync(dpy, False);
-+ XSetErrorHandler(old);
-+ }
-+ }
-+}
-+
-+void set_server_scale(int n) {
-+ if (n >= 1 && n < 100) {
-+ int w = si.framebufferWidth;
-+ int h = si.framebufferHeight;
-+ appData.serverScale = n;
-+ SendServerScale(n);
-+ if (0) SendFramebufferUpdateRequest(0, 0, w, h, False);
-+ schedule_fb_update();
-+ }
-+}
-+
-+void
-+DoServerScale(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ char str[100], *s, *q;
-+ int n;
-+ if (1) {
-+ s = DoScaleNDialog();
-+ } else {
-+ raiseme(1);
-+ fprintf(stderr, "\n\n\a\nEnter integer n for 1/n server scaling: ");
-+ str[0] = '\0';
-+ fgets(str, 100, stdin);
-+ s = str;
-+ q = strstr(str, "\n");
-+ if (q) *q = '\0';
-+ }
-+ if (s[0] != '\0') {
-+ n = atoi(s);
-+ set_server_scale(n);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void set_server_quality(int n) {
-+ fprintf(stderr, "set_quality: %d\n", n);
-+ if (n >= 0 && n <= 9) {
-+ int w = si.framebufferWidth;
-+ int h = si.framebufferHeight;
-+ init_format_change();
-+ appDataNew.qualityLevel = n;
-+ SendFramebufferUpdateRequest(0, 0, w, h, False);
-+ schedule_format_change();
-+ }
-+}
-+
-+void
-+DoServerQuality(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ char str[100], *s, *q;
-+ int n;
-+ if (1) {
-+ s = DoQualityDialog();
-+ } else {
-+ raiseme(1);
-+ fprintf(stderr, "\n\n\a\nEnter integer 1 <= n <= 9 for quality setting: ");
-+ str[0] = '\0';
-+ fgets(str, 100, stdin);
-+ s = str;
-+ q = strstr(str, "\n");
-+ if (q) *q = '\0';
-+ }
-+ if (s[0] != '\0') {
-+ n = atoi(s);
-+ set_server_quality(n);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void set_server_compress(int n) {
-+ fprintf(stderr, "set_compress: %d\n", n);
-+ if (n >= 0 && n <= 9) {
-+ int w = si.framebufferWidth;
-+ int h = si.framebufferHeight;
-+ init_format_change();
-+ appDataNew.compressLevel = n;
-+ SendFramebufferUpdateRequest(0, 0, w, h, False);
-+ schedule_format_change();
-+ }
-+}
-+
-+void
-+DoServerCompress(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ char str[100], *s, *q;
-+ int n;
-+ if (1) {
-+ s = DoCompressDialog();
-+ } else {
-+ raiseme(1);
-+ fprintf(stderr, "\n\n\a\nEnter integer 1 <= n <= 9 for compress level setting: ");
-+ str[0] = '\0';
-+ fgets(str, 100, stdin);
-+ s = str;
-+ q = strstr(str, "\n");
-+ if (q) *q = '\0';
-+ }
-+ if (s[0] != '\0') {
-+ n = atoi(s);
-+ set_server_compress(n);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+extern void rescale_image(void);
-+extern void get_scale_values(double *fx, double *fy);
-+
-+void
-+SetScale(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ char *s;
-+ s = DoScaleDialog();
-+ if (s[0] != '\0') {
-+#if 0
-+ int w = si.framebufferWidth;
-+ int h = si.framebufferHeight;
-+#endif
-+ double fx, fy;
-+ int fs = 0;
-+ if (appData.scale != NULL && !strcmp(s, appData.scale)) {
-+ return;
-+ }
-+
-+ if (!strcasecmp(s, "none")) {
-+ appData.scale = NULL;
-+ } else if (!strcmp(s, "1.0")) {
-+ appData.scale = NULL;
-+ } else if (!strcmp(s, "1")) {
-+ appData.scale = NULL;
-+ } else {
-+ appData.scale = strdup(s);
-+ }
-+ if (appData.scale != NULL) {
-+ get_scale_values(&fx, &fy);
-+ if (fx <= 0.0 || fy <= 0.0) {
-+ appData.scale = NULL;
-+ return;
-+ }
-+ }
-+
-+ if (appData.fullScreen) {
-+ fs = 1;
-+ FullScreenOff();
-+ }
-+ rescale_image();
-+ if (fs) {
-+ FullScreenOn();
-+ }
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetEscapeKeys(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ char *s;
-+ s = DoEscapeKeysDialog();
-+ fprintf(stderr, "set escape keys: '%s'\n", s);
-+ if (s[0] != '\0') {
-+ appData.escapeKeys = strdup(s);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void set_ycrop(int n) {
-+ if (n >= 1) {
-+ int w = si.framebufferWidth;
-+ int h = si.framebufferHeight;
-+ appData.yCrop = n;
-+ ReDoDesktop();
-+ SendFramebufferUpdateRequest(0, 0, w, h, False);
-+ schedule_fb_update();
-+ }
-+}
-
-- Cleanup();
-+void
-+SetYCrop(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ char str[100], *q, *s;
-+ int n;
-+ if (1) {
-+ s = DoYCropDialog();
-+ } else {
-+ raiseme(1);
-+ fprintf(stderr, "\n\n\a\nEnter pixel size n -ycrop maximum y-height: ");
-+ str[0] = '\0';
-+ fgets(str, 100, stdin);
-+ s = str;
-+ q = strstr(str, "\n");
-+ if (q) *q = '\0';
-+ }
-+ if (s[0] != '\0') {
-+ n = atoi(s);
-+ set_ycrop(n);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void set_scbar(int n) {
-+ if (n >= 1) {
-+ int w = si.framebufferWidth;
-+ int h = si.framebufferHeight;
-+fprintf(stderr, "set_scbat: %d\n", n);
-+ appData.sbWidth = n;
-+ ReDoDesktop();
-+ SendFramebufferUpdateRequest(0, 0, w, h, False);
-+ schedule_fb_update();
-+ }
-+}
-+
-+void
-+SetScbar(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ char str[100], *q, *s;
-+ int n;
-+ if (1) {
-+ s = DoScbarDialog();
-+ } else {
-+ raiseme(1);
-+ fprintf(stderr, "\n\n\a\nEnter pixel size n scrollbar width: ");
-+ str[0] = '\0';
-+ fgets(str, 100, stdin);
-+ s = str;
-+ q = strstr(str, "\n");
-+ if (q) *q = '\0';
-+ }
-+ if (s[0] != '\0') {
-+ n = atoi(s);
-+ set_scbar(n);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetScaleN(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (*num_params != 0) {
-+ int n = atoi(params[0]);
-+ set_server_scale(n);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void UpdateQual(void) {
-+ SetFormatAndEncodings();
-+ UpdateSubsampButtons();
-+ UpdateQualSlider();
-+}
-+
-+extern double latency;
-+
-+static void LosslessRefresh(void) {
-+ String encodings = appData.encodingsString;
-+ int compressLevel = appData.compressLevel;
-+ int qual = appData.qualityLevel;
-+ Bool enableJPEG = appData.enableJPEG;
-+ appData.qualityLevel = -1;
-+ appData.enableJPEG = False;
-+ appData.encodingsString = "tight copyrect";
-+ appData.compressLevel = 1;
-+ SetFormatAndEncodings();
-+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, False);
-+ if (latency > 0.0) {
-+ if (0) usleep((int) latency * 1000);
-+ }
-+ appData.qualityLevel = qual;
-+ appData.enableJPEG = enableJPEG;
-+ appData.encodingsString = encodings;
-+ appData.compressLevel = compressLevel;
-+ SetFormatAndEncodings();
-+}
-+
-+static void QualHigh(void) {
-+ appData.encodingsString = "tight copyrect";
-+ if(appData.useBGR233 || appDataNew.useBGR565) {
-+ fprintf(stderr, "WARNING: Cannot enable JPEG because BGR233/BGR565 is enabled.\n");
-+ } else {
-+ appData.enableJPEG = True;
-+ }
-+ appData.subsampLevel = TVNC_1X;
-+ appData.qualityLevel = 95;
-+ UpdateQual();
-+}
-+
-+static void QualMed(void) {
-+ appData.encodingsString = "tight copyrect";
-+ if(appData.useBGR233 || appDataNew.useBGR565) {
-+ fprintf(stderr, "WARNING: Cannot enable JPEG because BGR233/BGR565 is enabled.\n");
-+ } else {
-+ appData.enableJPEG = True;
-+ }
-+ appData.subsampLevel = TVNC_2X;
-+ appData.qualityLevel = 80;
-+ UpdateQual();
-+}
-+
-+static void QualLow(void) {
-+ appData.encodingsString = "tight copyrect";
-+ if(appData.useBGR233 || appDataNew.useBGR565) {
-+ fprintf(stderr, "WARNING: Cannot enable JPEG because BGR233/BGR565 is enabled.\n");
-+ } else {
-+ appData.enableJPEG = True;
-+ }
-+ appData.subsampLevel = TVNC_4X;
-+ appData.qualityLevel = 30;
-+ UpdateQual();
-+}
-+
-+static void QualLossless(void) {
-+ appData.encodingsString = "tight copyrect";
-+ appData.enableJPEG = False;
-+ appData.compressLevel = 0;
-+ UpdateQual();
-+}
-
-- return 0;
-+static void QualLosslessWAN(void) {
-+ appData.encodingsString = "tight copyrect";
-+ appData.enableJPEG = False;
-+ appData.compressLevel = 1;
-+ UpdateQual();
-+}
-+
-+void
-+SetTurboVNC(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (*num_params != 0) {
-+ int n = atoi(params[0]);
-+ if (0) fprintf(stderr, "SetTurboVNC: %d\n", n);
-+ if (n == 1) {
-+ QualHigh();
-+ } else if (n == 2) {
-+ QualMed();
-+ } else if (n == 3) {
-+ QualLow();
-+ } else if (n == 4) {
-+ QualLossless();
-+ } else if (n == 5) {
-+ QualLosslessWAN();
-+ } else if (n == 6) {
-+ appData.subsampLevel = TVNC_1X;
-+ UpdateQual();
-+ } else if (n == 7) {
-+ appData.subsampLevel = TVNC_2X;
-+ UpdateQual();
-+ } else if (n == 8) {
-+ appData.subsampLevel = TVNC_4X;
-+ UpdateQual();
-+ } else if (n == 9) {
-+ appData.subsampLevel = TVNC_GRAY;
-+ UpdateQual();
-+ } else if (n == 10) {
-+ LosslessRefresh();
-+ }
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetQuality(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (*num_params != 0) {
-+ int n = atoi(params[0]);
-+ set_server_quality(n);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetCompress(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (*num_params != 0) {
-+ int n = atoi(params[0]);
-+ set_server_compress(n);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+GotChatText(char *str, int len)
-+{
-+ static char *b = NULL;
-+ static int blen = -1;
-+ int i, k;
-+ if (appData.termChat) {
-+ printChat("\nChat: ", True);
-+ } else {
-+ printChat("Chat: ", True);
-+ }
-+
-+ if (len < 0) len = 0;
-+
-+ if (blen < len+1) {
-+ if (b) free(b);
-+ blen = 2 * (len + 10);
-+ b = (char *) malloc(blen);
-+ }
-+
-+ k = 0;
-+ for (i=0; i < len; i++) {
-+ if (str[i] != '\r') {
-+ b[k++] = str[i];
-+ }
-+ }
-+ b[k] = '\0';
-+ b[len] = '\0';
-+ printChat(b, True);
-+
-+ if (appData.termChat) {
-+ if (strstr(str, "\n")) {
-+ printChat("Send: ", True);
-+ } else {
-+ printChat("\nSend: ", True);
-+ }
-+ }
-+}
-+
-+void
-+SetViewOnlyState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.viewOnly) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetNOJPEGState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.enableJPEG) {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetQualityState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (*num_params != 0) {
-+ int n = atoi(params[0]);
-+ if (appData.qualityLevel == n) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetCompressState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (*num_params != 0) {
-+ int n = atoi(params[0]);
-+ if (appData.compressLevel == n) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetScaleNState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (*num_params != 0) {
-+ int n = atoi(params[0]);
-+ if (appData.serverScale == n || (appData.serverScale >= 6 && n >= 6)) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+Set8bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useBGR233) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ if (b16 != NULL) {
-+ XtVaSetValues(b16, XtNstate, False, NULL);
-+ }
-+ if (bfull != NULL) {
-+ XtVaSetValues(bfull, XtNstate, False, NULL);
-+ }
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+Set16bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useBGR565) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ if (b8 != NULL) {
-+ XtVaSetValues(b8, XtNstate, False, NULL);
-+ }
-+ if (bfull != NULL) {
-+ XtVaSetValues(bfull, XtNstate, False, NULL);
-+ }
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetFullColorState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useBGR565 || appData.useBGR233) {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ if (b8 != NULL) {
-+ XtVaSetValues(b8, XtNstate, False, NULL);
-+ }
-+ if (b16 != NULL) {
-+ XtVaSetValues(b16, XtNstate, False, NULL);
-+ }
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetXGrabState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.grabAll) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetEscapeKeysState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.escapeActive) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+Set256ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useBGR233 == 256) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ if (w64 != NULL) {
-+ XtVaSetValues(w64 , XtNstate, False, NULL);
-+ }
-+ if (w8 != NULL) {
-+ XtVaSetValues(w8 , XtNstate, False, NULL);
-+ }
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+Set64ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useBGR233 == 64) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ if (w256 != NULL) {
-+ XtVaSetValues(w256, XtNstate, False, NULL);
-+ }
-+ if (w8 != NULL) {
-+ XtVaSetValues(w8 , XtNstate, False, NULL);
-+ }
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+Set8ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useBGR233 == 8) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ if (w256 != NULL) {
-+ XtVaSetValues(w256, XtNstate, False, NULL);
-+ }
-+ if (w64 != NULL) {
-+ XtVaSetValues(w64 , XtNstate, False, NULL);
-+ }
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetGreyScaleState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useGreyScale) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+static void init_state(void) {
-+ static int first = 1;
-+ if (first && appData.encodingsString) {
-+ char *t, *z, *y, *h;
-+ char *str = appData.encodingsString;
-+ int len = strlen(str);
-+
-+ t = strstr(str, "tight");
-+ z = strstr(str, "zrle");
-+ y = strstr(str, "zywrle");
-+ h = strstr(str, "hextile");
-+
-+ if (!t) t = str + len;
-+ if (!z) z = str + len;
-+ if (!y) y = str + len;
-+ if (!h) h = str + len;
-+
-+ usingZRLE = False;
-+ usingZYWRLE = False;
-+ usingHextile = False;
-+
-+ if (t < z && t < y && t < h) {
-+ ;
-+ } else if (z < t && z < y && z < h) {
-+ usingZRLE = True;
-+ } else if (y < t && y < z && y < h) {
-+ usingZYWRLE = True;
-+ usingZRLE = True;
-+ } else if (h < t && h < z && h < y) {
-+ usingHextile = True;
-+ }
-+ }
-+ first = 0;
-+
-+}
-+
-+void
-+SetZRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ init_state();
-+ if (usingZRLE) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetHextileState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ init_state();
-+ if (usingHextile) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetZYWRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ init_state();
-+ if (usingZYWRLE) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetCursorShapeState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useRemoteCursor) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetCursorAlphaState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useCursorAlpha) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetX11CursorState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useX11Cursor) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetBellState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useBell) {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetRawLocalState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.useRawLocal) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetServerInputState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (!appData.serverInput) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetPipelineUpdates(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (!appData.pipelineUpdates) {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetSendClipboard(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (!appData.sendClipboard) {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetSendAlways(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (!appData.sendAlways) {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetSingleWindowState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.singleWindow) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetTextChatState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.chatActive) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
-+}
-+
-+void
-+SetFileXferState(Widget w, XEvent *ev, String *params, Cardinal *num_params)
-+{
-+ if (appData.fileActive) {
-+ XtVaSetValues(w, XtNstate, True, NULL);
-+ } else {
-+ XtVaSetValues(w, XtNstate, False, NULL);
-+ }
-+ if (w || ev || params || num_params) {}
- }
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncviewer/vncviewer.h
---- vnc_unixsrc.orig/vncviewer/vncviewer.h 2004-03-11 13:14:40.000000000 -0500
-+++ vnc_unixsrc/vncviewer/vncviewer.h 2010-04-17 22:29:42.000000000 -0400
-@@ -28,6 +28,7 @@
- #include <string.h>
- #include <sys/time.h>
- #include <sys/types.h>
-+#include <sys/stat.h>
- #include <unistd.h>
- #include <pwd.h>
- #include <X11/IntrinsicP.h>
-@@ -51,7 +52,13 @@
- (((l) & 0x0000ff00) << 8) | \
- (((l) & 0x000000ff) << 24)) : (l))
-
--#define MAX_ENCODINGS 20
-+#define Swap32IfBE(l) \
-+ (*(char *)&endianTest ? (l) : ((((l) & 0xff000000) >> 24) | \
-+ (((l) & 0x00ff0000) >> 8) | \
-+ (((l) & 0x0000ff00) << 8) | \
-+ (((l) & 0x000000ff) << 24)) )
-+
-+#define MAX_ENCODINGS 24
-
- #define FLASH_PORT_OFFSET 5400
- #define LISTEN_PORT_OFFSET 5500
-@@ -64,60 +71,133 @@
- #define DEFAULT_VIA_CMD \
- (DEFAULT_SSH_CMD " -f -L %L:%H:%R %G sleep 20")
-
-+#define TVNC_SAMPOPT 4
-+enum {TVNC_1X=0, TVNC_4X, TVNC_2X, TVNC_GRAY};
-
--/* argsresources.c */
--
--typedef struct {
-- Bool shareDesktop;
-- Bool viewOnly;
-- Bool fullScreen;
-- Bool grabKeyboard;
-- Bool raiseOnBeep;
--
-- String encodingsString;
--
-- Bool useBGR233;
-- int nColours;
-- Bool useSharedColours;
-- Bool forceOwnCmap;
-- Bool forceTrueColour;
-- int requestedDepth;
--
-- Bool useShm;
--
-- int wmDecorationWidth;
-- int wmDecorationHeight;
--
-- char *userLogin;
--
-- char *passwordFile;
-- Bool passwordDialog;
--
-- int rawDelay;
-- int copyRectDelay;
-+#if 0
-+static const char *subsampLevel2str[TVNC_SAMPOPT] = {
-+ "1X", "4X", "2X", "Gray"
-+};
-+#endif
-+#ifdef TURBOVNC
-+#define rfbTightNoZlib 0x0A
-+#define rfbTurboVncVendor "TRBO"
-+#define rfbJpegQualityLevel1 0xFFFFFE01
-+#define rfbJpegQualityLevel100 0xFFFFFE64
-+#define rfbJpegSubsamp1X 0xFFFFFD00
-+#define rfbJpegSubsamp4X 0xFFFFFD01
-+#define rfbJpegSubsamp2X 0xFFFFFD02
-+#define rfbJpegSubsampGray 0xFFFFFD03
-+#endif
-+
-+/* for debugging width, height, etc */
-+#if 0
-+#define XtVaSetValues printf("%s:%d\n", __FILE__, __LINE__); XtVaSetValues
-+#endif
-
-- Bool debug;
-
-- int popupButtonCount;
-+/* argsresources.c */
-
-- int bumpScrollTime;
-- int bumpScrollPixels;
-+typedef struct {
-+ Bool shareDesktop;
-+ Bool viewOnly;
-+ Bool fullScreen;
-+ Bool grabKeyboard;
-+ Bool raiseOnBeep;
-+
-+ String encodingsString;
-+
-+ int useBGR233;
-+ int nColours;
-+ Bool useSharedColours;
-+ Bool forceOwnCmap;
-+ Bool forceTrueColour;
-+ int requestedDepth;
-+ Bool useBGR565;
-+ Bool useGreyScale;
-+
-+ Bool grabAll;
-+ Bool useXserverBackingStore;
-+ Bool overrideRedir;
-+ Bool popupFix;
-+
-+ Bool useShm;
-+ Bool termChat;
-+
-+ int wmDecorationWidth;
-+ int wmDecorationHeight;
-+
-+ char *userLogin;
-+ char *unixPW;
-+ char *msLogon;
-+ char *repeaterUltra;
-+ Bool ultraDSM;
-+ Bool acceptPopup;
-+ char *rfbVersion;
-+
-+ char *passwordFile;
-+ Bool passwordDialog;
-+ Bool notty;
-+
-+ int rawDelay;
-+ int copyRectDelay;
-+
-+ int yCrop;
-+ int sbWidth;
-+ Bool useCursorAlpha;
-+ Bool useRawLocal;
-+
-+ Bool debug;
-+
-+ int popupButtonCount;
-+ int popupButtonBreak;
-+
-+ int bumpScrollTime;
-+ int bumpScrollPixels;
-+
-+ int compressLevel;
-+ int qualityLevel;
-+ Bool enableJPEG;
-+ Bool useRemoteCursor;
-+ Bool useX11Cursor;
-+ Bool useBell;
-+ Bool autoPass;
-+
-+ Bool serverInput;
-+ Bool singleWindow;
-+ int serverScale;
-+ Bool chatActive;
-+ Bool chatOnly;
-+ Bool fileActive;
-+
-+ char *scale;
-+ char *escapeKeys;
-+ Bool appShare;
-+ Bool escapeActive;
-+ Bool pipelineUpdates;
-+
-+ Bool sendClipboard;
-+ Bool sendAlways;
-+ char *recvText;
-+
-+ /* only for turbovnc mode */
-+ String subsampString;
-+ int subsampLevel;
-+ Bool doubleBuffer;
-
-- int compressLevel;
-- int qualityLevel;
-- Bool enableJPEG;
-- Bool useRemoteCursor;
-- Bool useX11Cursor;
-- Bool autoPass;
-+ Bool noipv4;
-+ Bool noipv6;
-
- } AppData;
-
- extern AppData appData;
-+extern AppData appDataNew;
-
- extern char *fallback_resources[];
- extern char vncServerHost[];
- extern int vncServerPort;
- extern Bool listenSpecified;
-+extern pid_t listenParent;
- extern int listenPort, flashPort;
-
- extern XrmOptionDescRec cmdLineOptions[];
-@@ -130,10 +210,11 @@
- /* colour.c */
-
- extern unsigned long BGR233ToPixel[];
-+extern unsigned long BGR565ToPixel[];
-
- extern Colormap cmap;
- extern Visual *vis;
--extern unsigned int visdepth, visbpp;
-+extern unsigned int visdepth, visbpp, isLSB;
-
- extern void SetVisualAndCmap();
-
-@@ -155,15 +236,60 @@
- extern GC srcGC, dstGC;
- extern Dimension dpyWidth, dpyHeight;
-
-+extern int appshare_0_hint;
-+extern int appshare_x_hint;
-+extern int appshare_y_hint;
-+
- extern void DesktopInitBeforeRealization();
- extern void DesktopInitAfterRealization();
-+extern void Xcursors(int set);
- extern void SendRFBEvent(Widget w, XEvent *event, String *params,
- Cardinal *num_params);
- extern void CopyDataToScreen(char *buf, int x, int y, int width, int height);
-+extern void FillScreen(int x, int y, int width, int height, unsigned long fill);
- extern void SynchroniseScreen();
-
-+extern void ReDoDesktop();
-+extern void DesktopCursorOff();
-+extern void put_image(int x1, int y1, int x2, int y2, int width, int height, int solid);
-+extern void copy_rect(int x, int y, int width, int height, int src_x, int src_y);
-+
-+extern void releaseAllPressedModifiers(void);
-+extern void fs_grab(int check);
-+extern void fs_ungrab(int check);
-+
- /* dialogs.c */
-
-+extern int use_tty(void);
-+
-+extern void ScaleDialogDone(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern char *DoScaleDialog();
-+
-+extern void EscapeDialogDone(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern char *DoEscapeKeysDialog();
-+
-+extern void YCropDialogDone(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern char *DoYCropDialog();
-+
-+extern void ScbarDialogDone(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern char *DoScbarDialog();
-+
-+extern void ScaleNDialogDone(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern char *DoScaleNDialog();
-+
-+extern void QualityDialogDone(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern char *DoQualityDialog();
-+
-+extern void CompressDialogDone(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern char *DoCompressDialog();
-+
- extern void ServerDialogDone(Widget w, XEvent *event, String *params,
- Cardinal *num_params);
- extern char *DoServerDialog();
-@@ -171,6 +297,10 @@
- Cardinal *num_params);
- extern char *DoPasswordDialog();
-
-+extern void UserDialogDone(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern char *DoUserDialog();
-+
- /* fullscreen.c */
-
- extern void ToggleFullScreen(Widget w, XEvent *event, String *params,
-@@ -181,6 +311,13 @@
- extern void FullScreenOn();
- extern void FullScreenOff();
-
-+extern int net_wm_supported(void);
-+
-+extern void JumpLeft(Widget w, XEvent *event, String *params, Cardinal *num_params);
-+extern void JumpRight(Widget w, XEvent *event, String *params, Cardinal *num_params);
-+extern void JumpUp(Widget w, XEvent *event, String *params, Cardinal *num_params);
-+extern void JumpDown(Widget w, XEvent *event, String *params, Cardinal *num_params);
-+
- /* listen.c */
-
- extern void listenForIncomingConnections();
-@@ -196,6 +333,8 @@
- Cardinal *num_params);
- extern void Quit(Widget w, XEvent *event, String *params,
- Cardinal *num_params);
-+extern void HideChat(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
- extern void Cleanup();
-
- /* popup.c */
-@@ -207,6 +346,29 @@
- Cardinal *num_params);
- extern void CreatePopup();
-
-+extern void HideScaleN(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern void CreateScaleN();
-+
-+extern void HideTurboVNC(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern void CreateTurboVNC();
-+extern void UpdateSubsampButtons();
-+extern void UpdateQualSlider();
-+extern void UpdateQual();
-+
-+extern void HideQuality(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern void CreateQuality();
-+
-+extern void HideCompress(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+extern void CreateCompress();
-+
-+extern void Noop(Widget w, XEvent *event, String *params,
-+ Cardinal *num_params);
-+
-+extern int CreateMsg(char *msg, int wait);
- /* rfbproto.c */
-
- extern int rfbsock;
-@@ -229,8 +391,19 @@
- extern Bool SendClientCutText(char *str, int len);
- extern Bool HandleRFBServerMessage();
-
-+extern Bool SendServerInput(Bool enabled);
-+extern Bool SendSingleWindow(int x, int y);
-+extern Bool SendServerScale(int n);
-+
-+extern Bool SendTextChat(char *str);
-+extern Bool SendTextChatOpen(void);
-+extern Bool SendTextChatClose(void);
-+extern Bool SendTextChatFinish(void);
-+
- extern void PrintPixelFormat(rfbPixelFormat *format);
-
-+extern double dnow(void);
-+
- /* selection.c */
-
- extern void InitialiseSelection();
-@@ -241,8 +414,10 @@
-
- /* shm.c */
-
--extern XImage *CreateShmImage();
-+extern XImage *CreateShmImage(int do_ycrop);
- extern void ShmCleanup();
-+extern void ShmDetach();
-+extern Bool UsingShm();
-
- /* sockets.c */
-
-@@ -252,11 +427,19 @@
- extern Bool WriteExact(int sock, char *buf, int n);
- extern int FindFreeTcpPort(void);
- extern int ListenAtTcpPort(int port);
--extern int ConnectToTcpAddr(unsigned int host, int port);
-+extern int ListenAtTcpPort6(int port);
-+extern int dotted_ip(char *host, int partial);
-+extern int ConnectToTcpAddr(const char *hostname, int port);
-+extern int ConnectToUnixSocket(char *file);
- extern int AcceptTcpConnection(int listenSock);
-+extern int AcceptTcpConnection6(int listenSock);
- extern Bool SetNonBlocking(int sock);
-+extern Bool SetNoDelay(int sock);
-+extern Bool SocketPair(int fd[2]);
-
- extern int StringToIPAddr(const char *str, unsigned int *addr);
-+extern char *get_peer_ip(int sock);
-+extern char *ip2host(char *ip);
- extern Bool SameMachine(int sock);
-
- /* tunnel.c */
-@@ -271,3 +454,82 @@
- extern XtAppContext appContext;
- extern Display* dpy;
- extern Widget toplevel;
-+
-+extern void GotChatText(char *str, int len);
-+extern void unixpw(char *instr, int vencrypt_plain);
-+
-+extern void Toggle8bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void Toggle16bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleFullColor(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void Toggle256Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void Toggle64Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void Toggle8Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleGreyScale(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleTightZRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleTightHextile(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleZRLEZYWRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleViewOnly(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleJPEG(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleCursorShape(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleCursorAlpha(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleX11Cursor(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleBell(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleRawLocal(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleServerInput(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void TogglePipelineUpdates(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleSendClipboard(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleSendAlways(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleSingleWindow(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleXGrab(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleEscapeActive(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetEscapeKeys(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void DoServerScale(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void DoServerQuality(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void DoServerCompress(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetScale(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetYCrop(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetScbar(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ShowScaleN(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ShowTurboVNC(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ShowQuality(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ShowCompress(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetScaleN(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetTurboVNC(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetQuality(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetCompress(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleTextChat(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleFileXfer(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void ToggleTermTextChat(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+
-+extern void scale_check_zrle(void);
-+
-+extern void SetViewOnlyState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetNOJPEGState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetScaleNState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetQualityState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetCompressState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void Set8bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void Set16bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetFullColorState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void Set256ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void Set64ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void Set8ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetGreyScaleState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetZRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetHextileState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetZYWRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetCursorShapeState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetCursorAlphaState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetX11CursorState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetBellState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetRawLocalState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetServerInputState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetPipelineUpdates(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetSendClipboard(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetSendAlways(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetSingleWindowState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetTextChatState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetTermTextChatState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetFileXferState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetXGrabState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-+extern void SetEscapeKeysState(Widget w, XEvent *ev, String *params, Cardinal *num_params);
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vncviewer/vncviewer.man
---- vnc_unixsrc.orig/vncviewer/vncviewer.man 2004-03-11 13:14:40.000000000 -0500
-+++ vnc_unixsrc/vncviewer/vncviewer.man 2010-04-11 23:30:24.000000000 -0400
-@@ -5,38 +5,55 @@
- .\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de
- .\" Copyright (C) 2000,2001 Red Hat, Inc.
- .\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru>
-+.\" Copyright (C) 2006-2010 Karl J. Runge <runge@karlrunge.com>
- .\"
- .\" You may distribute under the terms of the GNU General Public
- .\" License as specified in the file LICENCE.TXT that comes with the
- .\" TightVNC distribution.
- .\"
--.TH vncviewer 1 "January 2003" "" "TightVNC"
-+.TH ssvncviewer 1 "April 2010" "" "SSVNC"
- .SH NAME
--vncviewer \- an X viewer client for VNC
-+ssvncviewer \- an X viewer client for VNC
- .SH SYNOPSIS
--.B vncviewer
-+.B ssvncviewer
- .RI [\| options \|]
- .RI [\| host \|][\| :display \|]
- .br
--.B vncviewer
-+.B ssvncviewer
- .RI [\| options \|]
- .RI [\| host \|][\| ::port \|]
- .br
--.B vncviewer
-+.B ssvncviewer
-+.RI [\| options \|]
-+.RI exec=[\| cmd+args... \|]
-+.br
-+.B ssvncviewer
-+.RI [\| options \|]
-+.RI fd=n
-+.br
-+.B ssvncviewer
-+.RI [\| options \|]
-+.RI /path/to/unix/socket
-+.br
-+.B ssvncviewer
- .RI [\| options \|]
- .IR \-listen
- .RI [\| display \|]
- .br
--.B vncviewer
-+.B ssvncviewer
- .IR \-help
- .br
- .SH DESCRIPTION
--.B vncviewer
-+.B ssvncviewer
- is an Xt\-based client application for the VNC (Virtual Network
- Computing) system. It can connect to any VNC\-compatible server such
--as \fBXvnc\fR or WinVNC, allowing you to control desktop environment
-+as \fBXvnc\fR, WinVNC, or \fBx11vnc\fR, allowing you to control desktop environment
- of a different machine.
-
-+ssvncviewer is an enhanced version of the tightvnc unix viewer that can
-+take advantage of features in the \fBx11vnc\fR and UltraVNC VNC servers.
-+See below for the description of these features.
-+
- You can use F8 to display a pop\-up utility menu. Press F8 twice to
- pass single F8 to the remote side.
- .SH OPTIONS
-@@ -102,13 +119,13 @@
- TightVNC supports several different compression methods to encode
- screen updates; this option specifies a set of them to use in order of
- preference. Encodings are specified separated with spaces, and must
--thus be enclosed in quotes if more than one is specified. Available
--encodings, in default order for a remote connection, are "copyrect
--tight hextile zlib corre rre raw". For a local connection (to the same
--machine), the default order to try is "raw copyrect tight hextile zlib
--corre rre". Raw encoding is always assumed as a last option if no
--other encoding can be used for some reason. For more information on
--encodings, see the section ENCODINGS below.
-+thus be enclosed in quotes if more than one is specified. Commas may be used to avoid spaces.
-+Available encodings, in default order for a remote connection, are
-+"copyrect tight hextile zlib corre rre raw". For a local connection
-+(to the same machine), the default order to try is "raw copyrect tight
-+hextile zlib corre rre". Raw encoding is always assumed as a last option
-+if no other encoding can be used for some reason. For more information
-+on encodings, see the section ENCODINGS below.
- .TP
- \fB\-bgr233\fR
- Always use the BGR233 format to encode pixel data. This reduces
-@@ -168,6 +185,424 @@
- \fB\-autopass\fR
- Read a plain-text password from stdin. This option affects only the
- standard VNC authentication.
-+
-+.SH Enhanced TightVNC Viewer (SSVNC) OPTIONS
-+.TP
-+Enhanced TightVNC Viewer (SSVNC) web page is located at:
-+.TP
-+http://www.karlrunge.com/x11vnc/ssvnc.html
-+.TP
-+Note: ZRLE and ZYWRLE encodings are now supported.
-+.TP
-+Note: F9 is shortcut to Toggle FullScreen mode.
-+.TP
-+Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1
-+to allow more than one incoming VNC server at a time.
-+This is the same as -multilisten described below. Set
-+SSVNC_MULTIPLE_LISTEN=MAX:n to allow no more than "n"
-+simultaneous reverse connections.
-+
-+If the host:port is specified as "exec=command args..."
-+then instead of making a TCP/IP socket connection to the
-+remote VNC server, "command args..." is executed and the
-+viewer is attached to its stdio. This enables tunnelling
-+established via an external command, e.g. an stunnel(8)
-+that does not involve a listening socket.
-+This mode does not work for -listen reverse connections.
-+
-+If the host:port is specified as "fd=n" then it is assumed
-+n is an already opened file descriptor to the socket. (i.e
-+the parent did fork+exec)
-+
-+If the host:port contains a '/' it is interpreted as a
-+unix-domain socket (AF_LOCAL insead of AF_INET)
-+.TP
-+\fB\-multilisten\fR
-+As in -listen (reverse connection listening) except
-+allow more than one incoming VNC server to be connected
-+at a time. The default for -listen of only one at a
-+time tries to play it safe by not allowing anyone on
-+the network to put (many) desktops on your screen over
-+a long window of time. Use -multilisten for no limit.
-+.TP
-+\fB\-acceptpopup\fR
-+In \fB\-listen\fR (reverse connection listening) mode when
-+a reverse VNC connection comes in show a popup asking
-+whether to Accept or Reject the connection. The IP
-+address of the connecting host is shown. Same as
-+setting the env. var. SSVNC_ACCEPT_POPUP=1.
-+.TP
-+\fB\-acceptpopupsc\fR
-+As in \fB\-acceptpopup\fR except assume UltraVNC Single
-+Click (SC) server. Retrieve User and ComputerName
-+info from UltraVNC Server and display in the Popup.
-+.TP
-+\fB\-use64\fR
-+In \fB\-bgr233\fR mode, use 64 colors instead of 256.
-+.TP
-+\fB\-bgr222\fR
-+Same as \fB\-use64\fR.
-+.TP
-+\fB\-use8\fR
-+In \fB\-bgr233\fR mode, use 8 colors instead of 256.
-+.TP
-+\fB\-bgr111\fR
-+Same as \fB\-use8\fR.
-+.TP
-+\fB\-16bpp\fR
-+If the vnc viewer X display is depth 24 at 32bpp
-+request a 16bpp format from the VNC server to cut
-+network traffic by up to 2X, then tranlate the
-+pixels to 32bpp locally.
-+.TP
-+\fB\-bgr565\fR
-+Same as \fB\-16bpp\fR.
-+.TP
-+\fB\-grey\fR
-+Use a grey scale for the 16- and 8\fB\-bpp\fR modes.
-+.TP
-+\fB\-alpha\fR
-+Use alphablending transparency for local cursors
-+requires: x11vnc server, both client and server
-+must be 32bpp and same endianness.
-+.TP
-+\fB\-scale\fR \fIstr\fR
-+Scale the desktop locally. The string "str" can
-+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. "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 \fB\-x11cursor\fR.)
-+
-+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 \fB\-solid\fR ...)
-+
-+If the remote server is x11vnc, try client
-+side caching: x11vnc \fB\-ncache\fR 10 ...
-+.TP
-+\fB\-ycrop\fR n
-+Only show the top n rows of the framebuffer. For
-+use with x11vnc \fB\-ncache\fR client caching option
-+to help "hide" the pixel cache region.
-+Use a negative value (e.g. \fB\-1\fR) for autodetection.
-+Autodetection will always take place if the remote
-+fb height is more than 2 times the width.
-+.TP
-+\fB\-sbwidth\fR n
-+Scrollbar width for x11vnc \fB\-ncache\fR mode (\fB\-ycrop\fR),
-+default is very narrow: 2 pixels, it is narrow to
-+avoid distraction in \fB\-ycrop\fR mode.
-+.TP
-+\fB\-nobell\fR
-+Disable bell.
-+.TP
-+\fB\-rawlocal\fR
-+Prefer raw encoding for localhost, default is
-+no, i.e. assumes you have a SSH tunnel instead.
-+.TP
-+\fB\-notty\fR
-+Try to avoid using the terminal for interactive
-+responses: use windows for messages and prompting
-+instead. Messages will also be printed to terminal.
-+.TP
-+\fB\-sendclipboard\fR
-+Send the X CLIPBOARD selection (i.e. Ctrl+C,
-+Ctrl+V) instead of the X PRIMARY selection (mouse
-+select and middle button paste.)
-+.TP
-+\fB\-sendalways\fR
-+Whenever the mouse enters the VNC viewer main
-+window, send the selection to the VNC server even if
-+it has not changed. This is like the Xt resource
-+translation SelectionToVNC(always)
-+.TP
-+\fB\-recvtext\fR
-+str When cut text is received from the VNC server,
-+ssvncviewer will set both the X PRIMARY and the
-+X CLIPBOARD local selections. To control which
-+is set, specify 'str' as 'primary', 'clipboard',
-+or 'both' (the default.)
-+.TP
-+\fB\-graball\fR
-+Grab the entire X server when in fullscreen mode,
-+needed by some old window managers like fvwm2.
-+.TP
-+\fB\-popupfix\fR
-+Warp the popup back to the pointer position,
-+needed by some old window managers like fvwm2.
-+.TP
-+\fB\-grabkbd\fR
-+Grab the X keyboard when in fullscreen mode,
-+needed by some window managers. Same as \fB\-grabkeyboard\fR.
-+\fB\-grabkbd\fR is the default, use \fB\-nograbkbd\fR to disable.
-+.TP
-+\fB\-bs\fR, \fB\-nobs\fR
-+Whether or not to use X server Backingstore for the
-+main viewer window. The default is to not, mainly
-+because most Linux, etc, systems X servers disable
-+*all* Backingstore by default. To re\fB\-enable\fR it put
-+
-+Option "Backingstore"
-+
-+in the Device section of /etc/X11/xorg.conf.
-+In \fB\-bs\fR mode with no X server backingstore, whenever an
-+area of the screen is re\fB\-exposed\fR it must go out to the
-+VNC server to retrieve the pixels. This is too slow.
-+
-+In \fB\-nobs\fR mode, memory is allocated by the viewer to
-+provide its own backing of the main viewer window. This
-+actually makes some activities faster (changes in large
-+regions) but can appear to "flash" too much.
-+.TP
-+\fB\-noshm\fR
-+Disable use of MIT shared memory extension (not recommended)
-+.TP
-+\fB\-termchat\fR
-+Do the UltraVNC chat in the terminal vncviewer is in
-+instead of in an independent window.
-+.TP
-+\fB\-unixpw\fR \fIstr\fR
-+Useful for logging into x11vnc in \fB\-unixpw\fR mode. "str" is a
-+string that allows many ways to enter the Unix Username
-+and Unix Password. These characters: username, newline,
-+password, newline are sent to the VNC server after any VNC
-+authentication has taken place. Under x11vnc they are
-+used for the \fB\-unixpw\fR login. Other VNC servers could do
-+something similar.
-+
-+You can also indicate "str" via the environment
-+variable SSVNC_UNIXPW.
-+
-+Note that the Escape key is actually sent first to tell
-+x11vnc to not echo the Unix Username back to the VNC
-+viewer. Set SSVNC_UNIXPW_NOESC=1 to override this.
-+
-+If str is ".", then you are prompted at the command line
-+for the username and password in the normal way. If str is
-+"-" the stdin is read via getpass(3) for username@password.
-+Otherwise if str is a file, it is opened and the first line
-+read is taken as the Unix username and the 2nd as the
-+password. If str prefixed by "rm:" the file is removed
-+after reading. Otherwise, if str has a "@" character,
-+it is taken as username@password. Otherwise, the program
-+exits with an error. Got all that?
-+.TP
-+\fB-repeater\fR \fIstr\fR
-+This is for use with UltraVNC repeater proxy described
-+here: http://www.uvnc.com/addons/repeater.html. The "str"
-+is the ID string to be sent to the repeater. E.g. ID:1234
-+It can also be the hostname and port or display of the VNC
-+server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when
-+using -repeater, the host:dpy on the cmdline is the repeater
-+server, NOT the VNC server. The repeater will connect you.
-+
-+Example: vncviewer ... -repeater ID:3333 repeat.host:5900
-+
-+Example: vncviewer ... -repeater vhost:0 repeat.host:5900
-+
-+Use, e.g., '-repeater SCIII=ID:3210' if the repeater is a
-+Single Click III (SSL) repeater (repeater_SSL.exe) and you
-+are passing the SSL part of the connection through stunnel, socat, etc.
-+This way the magic UltraVNC string 'testB' needed to work with the
-+repeater is sent to it.
-+.TP
-+\fB-rfbversion\fR \fIstr\fR
-+Set the advertised RFB version. E.g.: -rfbversion 3.6 For some
-+servers, e.g. UltraVNC this needs to be done.
-+.TP
-+\fB-ultradsm\fR
-+UltraVNC has symmetric private encryption DSM plugins. See
-+http://www.uvnc.com/features/encryption.html. It is assumed
-+you are using a unix program (e.g. our ultravnc_dsm_helper) to
-+encrypt and decrypt the UltraVNC DSM stream. IN ADDITION TO
-+THAT supply -ultradsm to tell THIS viewer to modify the RFB
-+data sent so as to work with the UltraVNC Server. For some
-+reason, each RFB msg type must be sent twice under DSM.
-+.TP
-+\fB\-mslogon\fR \fIuser\fR
-+Use Windows MS Logon to an UltraVNC server. Supply the
-+username or "1" to be prompted. The default is to
-+autodetect the UltraVNC MS Logon server and prompt for
-+the username and password.
-+
-+IMPORTANT NOTE: The UltraVNC MS-Logon Diffie-Hellman
-+exchange is very weak and can be brute forced to recover
-+your username and password in a few seconds of CPU
-+time. To be safe, be sure to use an additional encrypted
-+tunnel (e.g. SSL or SSH) for the entire VNC session.
-+.TP
-+\fB\-chatonly\fR
-+Try to be a client that only does UltraVNC text chat. This
-+mode is used by x11vnc to present a chat window on the physical
-+X11 console (i.e. to chat with the person at the display).
-+.TP
-+\fB-env\fR \fIVAR=VALUE\fR
-+To save writing a shell script to set environment
-+variables, specify as many as you need on the command line. For example,
-+-env SSVNC_MULTIPLE_LISTEN=MAX:5 -env EDITOR=vi
-+.TP
-+\fB\-noipv6\fR
-+Disable all IPv6 sockets. Same as VNCVIEWER_NO_IPV6=1.
-+.TP
-+\fB\-noipv4\fR
-+Disable all IPv4 sockets. Same as VNCVIEWER_NO_IPV4=1.
-+.TP
-+\fB\-printres\fR
-+Print out the Ssvnc X resources (appdefaults) and
-+then exit. You can save them to a file and customize them (e.g. the
-+keybindings and Popup menu) Then point to the file via
-+XENVIRONMENT or XAPPLRESDIR.
-+.TP
-+\fB\-pipeline\fR
-+Like TurboVNC, request the next framebuffer update as soon
-+as possible instead of waiting until the end of the current
-+framebuffer update coming in. Helps 'pipeline' the updates.
-+This is currently the default, use \fB-nopipeline\fR to disable.
-+.TP
-+\fB\-appshare\fR
-+Enable features for use with x11vnc's \fB\-appshare\fR mode where
-+instead of sharing the full desktop only the application's
-+windows are shared. Viewer multilisten mode is used to
-+create the multiple windows: \fB\-multilisten\fR is implied.
-+See 'x11vnc \fB\-appshare\fR \fB\-help\fR' more information on the mode.
-+Features enabled in the viewer under \fB\-appshare\fR are:
-+Minimum extra text in the title, auto \fB\-ycrop\fR is disabled,
-+x11vnc \fB\-remote_prefix\fR X11VNC_APPSHARE_CMD: message channel,
-+x11vnc initial window position hints. See also Escape Keys
-+below for additional key and mouse bindings.
-+.TP
-+\fB\-escape \fR\fIstr\fR
-+This sets the 'Escape Keys' modifier sequence and enables
-+escape keys mode. When the modifier keys escape sequence
-+is held down, the next keystroke is interpreted locally
-+to perform a special action instead of being sent to the
-+remote VNC server.
-+
-+Use '\fB\-escape\fR default' for the default modifier sequence.
-+(Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L)
-+
-+Here are the 'Escape Keys: Help+Set' instructions from the Popup:
-+
-+Escape Keys: Enter a comma separated list of modifier keys to be the 'escape
-+sequence'. When these keys are held down, the next keystroke is
-+interpreted locally to invoke a special action instead of being sent to
-+the remote VNC server. In other words, a set of 'Hot Keys'.
-+
-+Here is the list of local key mappings to special actions:
-+
-+r: refresh desktop b: toggle bell c: toggle full-color
-+
-+f: file transfer x: x11cursor z: toggle Tight/ZRLE
-+
-+l: full screen g: graball e: escape keys dialog
-+
-+s: scale dialog +: scale up (=) -: scale down (_)
-+
-+t: text chat a: alphablend cursor
-+
-+V: toggle viewonly Q: quit viewer 123456: UltraVNC scale 1/n
-+
-+Arrow keys: pan the viewport about 10% for each keypress.
-+
-+PageUp/PageDown: pan the viewport by a screenful vertically.
-+
-+Home/End: pan the viewport by a screenful horizontally.
-+
-+KeyPad Arrows: pan the viewport by 1 pixel for each keypress.
-+
-+Dragging the Mouse with Button1 pressed also pans the viewport.
-+
-+Clicking Mouse Button3 brings up the Popup Menu.
-+
-+The above mappings are \fBalways\fR active in ViewOnly mode, unless you set
-+the Escape Keys value to 'never'.
-+
-+x11vnc -appshare hot-keys: x11vnc has a simple application sharing mode
-+that enables the viewer-side to move, resize, or raise the remote toplevel
-+windows. To enable it, hold down Shift + the Escape Keys and press these:
-+
-+Arrow keys: move the remote window around in its desktop.
-+
-+PageUp/PageDn/Home/End: resize the remote window.
-+
-++/-: raise or lower the remote window.
-+
-+M or Button1 move win to local position; D or Button3: delete remote win.
-+
-+If the Escape Keys value below is set to 'default' then a default list of
-+of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it
-+is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag
-+on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side
-+of the keyboard.
-+
-+On Unix the default is Alt and Windows keys on Left side of keyboard.
-+On MacOSX the default is Control and Command keys on Left side of keyboard.
-+
-+Example: Press and hold the Alt and Windows keys on the LEFT side of the
-+keyboard and then press 'c' to toggle the full-color state. Or press 't'
-+to toggle the ultravnc Text Chat window, etc.
-+
-+To use something besides the default, supply a comma separated list (or a
-+single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L
-+Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.
-+.TP
-+\fB New Popup actions:\fR
-+
-+ ViewOnly: ~ -viewonly
-+ Disable Bell: ~ -nobell
-+ Cursor Shape: ~ -nocursorshape
-+ X11 Cursor: ~ -x11cursor
-+ Cursor Alphablend: ~ -alpha
-+ Toggle Tight/Hextile: ~ -encodings hextile...
-+ Toggle Tight/ZRLE: ~ -encodings zrle...
-+ Toggle ZRLE/ZYWRLE: ~ -encodings zywrle...
-+ Quality Level ~ -quality (both Tight and ZYWRLE)
-+ Compress Level ~ -compresslevel
-+ Disable JPEG: ~ -nojpeg (Tight)
-+ Pipeline Updates ~ -pipeline
-+
-+ Full Color as many colors as local screen allows.
-+ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.
-+ 16 bit color (BGR565) ~ -16bpp / -bgr565
-+ 8 bit color (BGR233) ~ -bgr233
-+ 256 colors ~ -bgr233 default # of colors.
-+ 64 colors ~ -bgr222 / -use64
-+ 8 colors ~ -bgr111 / -use8
-+ Scale Viewer ~ -scale
-+ Escape Keys: Toggle ~ -escape
-+ Escape Keys: Help+Set ~ -escape
-+ Set Y Crop (y-max) ~ -ycrop
-+ Set Scrollbar Width ~ -sbwidth
-+ XGrabServer ~ -graball
-+
-+ UltraVNC Extensions:
-+
-+ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.
-+ Text Chat Ultravnc ext. Do Text Chat.
-+ File Transfer Ultravnc ext. File xfer via Java helper.
-+ Single Window Ultravnc ext. Grab and view a single window.
-+ (select then click on the window you want).
-+ Disable Remote Input Ultravnc ext. Try to prevent input and
-+ viewing of monitor at physical display.
-+
-+ Note: the Ultravnc extensions only apply to servers that support
-+ them. x11vnc/libvncserver supports some of them.
-+
-+ Send Clipboard not Primary ~ -sendclipboard
-+ Send Selection Every time ~ -sendalways
-+
- .SH ENCODINGS
- The server supplies information in whatever format is desired by the
- client, in order to make the client as easy as possible to implement.
-@@ -238,6 +673,15 @@
- \-quality and \-nojpeg options above). Tight encoding is usually the
- best choice for low\-bandwidth network environments (e.g. slow modem
- connections).
-+.TP
-+.B ZRLE
-+The SSVNC viewer has ported the RealVNC (www.realvnc.com) ZRLE encoding
-+to the unix tightvnc viewer.
-+.TP
-+.B ZYWRLE
-+The SSVNC viewer has ported the Hitachi lossy wavelet based ZRLE
-+encoding from http://mobile.hitachi-system.co.jp/publications/ZYWRLE/
-+to the unix tightvnc viewer.
- .SH RESOURCES
- X resources that \fBvncviewer\fR knows about, aside from the
- normal Xt resources, are as follows:
-@@ -364,12 +808,13 @@
- .B %R
- remote TCP port number.
- .SH SEE ALSO
--\fBvncserver\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1),
--\fBvncconnect\fR(1), \fBssh\fR(1)
-+\fBvncserver\fR(1), \fBx11vnc\fR(1), \fBssvnc\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1),
-+\fBvncconnect\fR(1), \fBssh\fR(1), http://www.karlrunge.com/x11vnc, http://www.karlrunge.com/x11vnc/ssvnc.html
- .SH AUTHORS
- Original VNC was developed in AT&T Laboratories Cambridge. TightVNC
- additions was implemented by Constantin Kaplinsky. Many other people
--participated in development, testing and support.
-+participated in development, testing and support. Karl J. Runge
-+added all of the SSVNC related features and improvements.
-
- \fBMan page authors:\fR
- .br
-@@ -380,3 +825,5 @@
- Tim Waugh <twaugh@redhat.com>,
- .br
- Constantin Kaplinsky <const@ce.cctpu.edu.ru>
-+.br
-+Karl J. Runge <runge@karlrunge.com>
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrle.c vnc_unixsrc/vncviewer/zrle.c
---- vnc_unixsrc.orig/vncviewer/zrle.c 2007-02-04 18:59:50.000000000 -0500
-+++ vnc_unixsrc/vncviewer/zrle.c 2010-02-25 23:24:28.000000000 -0500
-@@ -0,0 +1,620 @@
-+/*
-+ * Copyright (C) 2005 Johannes E. Schindelin. All Rights Reserved.
-+ *
-+ * This is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this software; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ */
-+
-+/*
-+ * zrle.c - handle zrle encoding.
-+ *
-+ * This file shouldn't be compiled directly. It is included multiple times by
-+ * rfbproto.c, each time with a different definition of the macro BPP. For
-+ * each value of BPP, this file defines a function which handles an zrle
-+ * encoded rectangle with BPP bits per pixel.
-+ */
-+
-+#ifndef REALBPP
-+#define REALBPP BPP
-+#endif
-+
-+#if !defined(UNCOMP) || UNCOMP==0
-+#define HandleZRLE CONCAT2E(HandleZRLE,REALBPP)
-+#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
-+#elif UNCOMP>0
-+#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Down)
-+#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Down)
-+#else
-+#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Up)
-+#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Up)
-+#endif
-+#undef CARDBPP
-+#undef CARDREALBPP
-+#define CARDBPP CONCAT2E(CARD, BPP)
-+#define CARDREALBPP CONCAT2E(CARD,REALBPP)
-+
-+#define FillRectangle(x, y, w, h, color) \
-+ { \
-+ XGCValues _gcv; \
-+ _gcv.foreground = color; \
-+ if (!appData.useXserverBackingStore) { \
-+ FillScreen(x, y, w, h, _gcv.foreground); \
-+ } else { \
-+ XChangeGC(dpy, gc, GCForeground, &_gcv); \
-+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \
-+ } \
-+ }
-+
-+#if defined(__sparc) || defined(__sparc__) || defined(__ppc__) || defined(__POWERPC__) || defined(__BIG_ENDIAN__) || defined(_BIG_ENDIAN)
-+#define IS_BIG_ENDIAN 1
-+#else
-+#define IS_BIG_ENDIAN 0
-+#endif
-+
-+#if DO_ZYWRLE
-+
-+#define ENDIAN_LITTLE 0
-+#define ENDIAN_BIG 1
-+#define ENDIAN_NO 2
-+#if IS_BIG_ENDIAN
-+#define ZYWRLE_ENDIAN ENDIAN_BIG
-+#else
-+#define ZYWRLE_ENDIAN ENDIAN_LITTLE
-+#endif
-+#undef END_FIX
-+#if ZYWRLE_ENDIAN == ENDIAN_LITTLE
-+# define END_FIX LE
-+#elif ZYWRLE_ENDIAN == ENDIAN_BIG
-+# define END_FIX BE
-+#else
-+# define END_FIX NE
-+#endif
-+#define __RFB_CONCAT3E(a,b,c) CONCAT3E(a,b,c)
-+#define __RFB_CONCAT2E(a,b) CONCAT2E(a,b)
-+#undef CPIXEL
-+#if REALBPP != BPP
-+#if UNCOMP == 0
-+#define CPIXEL REALBPP
-+#elif UNCOMP>0
-+#define CPIXEL CONCAT2E(REALBPP,Down)
-+#else
-+#define CPIXEL CONCAT2E(REALBPP,Up)
-+#endif
-+#endif
-+#define PIXEL_T CARDBPP
-+#if BPP!=8
-+#define ZYWRLE_DECODE 1
-+#include "zywrletemplate.c"
-+#endif
-+#undef CPIXEL
-+
-+#endif /* DO_ZYWRLE */
-+
-+static int HandleZRLETile(
-+ unsigned char* buffer,size_t buffer_length,
-+ int x,int y,int w,int h);
-+
-+static Bool
-+HandleZRLE (int rx, int ry, int rw, int rh)
-+{
-+ rfbZRLEHeader header;
-+ int remaining;
-+ int inflateResult;
-+ int toRead;
-+ int min_buffer_size = rw * rh * (REALBPP / 8) * 2;
-+
-+ /* First make sure we have a large enough raw buffer to hold the
-+ * decompressed data. In practice, with a fixed REALBPP, fixed frame
-+ * buffer size and the first update containing the entire frame
-+ * buffer, this buffer allocation should only happen once, on the
-+ * first update.
-+ */
-+ if ( raw_buffer_size < min_buffer_size) {
-+
-+ if ( raw_buffer != NULL ) {
-+
-+ free( raw_buffer );
-+
-+ }
-+
-+ raw_buffer_size = min_buffer_size;
-+ raw_buffer = (char*) malloc( raw_buffer_size );
-+
-+ }
-+
-+ if (!ReadFromRFBServer((char *)&header, sz_rfbZRLEHeader))
-+ return False;
-+
-+ remaining = Swap32IfLE(header.length);
-+
-+ /* Need to initialize the decompressor state. */
-+ decompStream.next_in = ( Bytef * )buffer;
-+ decompStream.avail_in = 0;
-+ decompStream.next_out = ( Bytef * )raw_buffer;
-+ decompStream.avail_out = raw_buffer_size;
-+ decompStream.data_type = Z_BINARY;
-+
-+ /* Initialize the decompression stream structures on the first invocation. */
-+ if ( decompStreamInited == False ) {
-+
-+ inflateResult = inflateInit( &decompStream );
-+
-+ if ( inflateResult != Z_OK ) {
-+ fprintf(stderr,
-+ "inflateInit returned error: %d, msg: %s\n",
-+ inflateResult,
-+ decompStream.msg);
-+ return False;
-+ }
-+
-+ decompStreamInited = True;
-+
-+ }
-+
-+ inflateResult = Z_OK;
-+
-+ /* Process buffer full of data until no more to process, or
-+ * some type of inflater error, or Z_STREAM_END.
-+ */
-+ while (( remaining > 0 ) &&
-+ ( inflateResult == Z_OK )) {
-+
-+ if ( remaining > BUFFER_SIZE ) {
-+ toRead = BUFFER_SIZE;
-+ }
-+ else {
-+ toRead = remaining;
-+ }
-+
-+ /* Fill the buffer, obtaining data from the server. */
-+ if (!ReadFromRFBServer(buffer,toRead))
-+ return False;
-+
-+ decompStream.next_in = ( Bytef * )buffer;
-+ decompStream.avail_in = toRead;
-+
-+ /* Need to uncompress buffer full. */
-+ inflateResult = inflate( &decompStream, Z_SYNC_FLUSH );
-+
-+ /* We never supply a dictionary for compression. */
-+ if ( inflateResult == Z_NEED_DICT ) {
-+ fprintf(stderr, "zlib inflate needs a dictionary!\n");
-+ return False;
-+ }
-+ if ( inflateResult < 0 ) {
-+ fprintf(stderr,
-+ "zlib inflate returned error: %d, msg: %s\n",
-+ inflateResult,
-+ decompStream.msg);
-+ return False;
-+ }
-+
-+ /* Result buffer allocated to be at least large enough. We should
-+ * never run out of space!
-+ */
-+ if (( decompStream.avail_in > 0 ) &&
-+ ( decompStream.avail_out <= 0 )) {
-+ fprintf(stderr, "zlib inflate ran out of space!\n");
-+ return False;
-+ }
-+
-+ remaining -= toRead;
-+
-+ } /* while ( remaining > 0 ) */
-+
-+ if ( inflateResult == Z_OK ) {
-+ void* buf=raw_buffer;
-+ int i,j;
-+
-+ remaining = raw_buffer_size-decompStream.avail_out;
-+
-+ for(j=0; j<rh; j+=rfbZRLETileHeight)
-+ for(i=0; i<rw; i+=rfbZRLETileWidth) {
-+ int subWidth=(i+rfbZRLETileWidth>rw)?rw-i:rfbZRLETileWidth;
-+ int subHeight=(j+rfbZRLETileHeight>rh)?rh-j:rfbZRLETileHeight;
-+ int result=HandleZRLETile(buf,remaining,rx+i,ry+j,subWidth,subHeight);
-+
-+ if(result<0) {
-+ fprintf(stderr, "ZRLE decoding failed (%d)\n",result);
-+return True;
-+ return False;
-+ }
-+
-+ buf+=result;
-+ remaining-=result;
-+ }
-+ }
-+ else {
-+
-+ fprintf(stderr,
-+ "zlib inflate returned error: %d, msg: %s\n",
-+ inflateResult,
-+ decompStream.msg);
-+ return False;
-+
-+ }
-+
-+ return True;
-+}
-+
-+#if REALBPP!=BPP && defined(UNCOMP) && UNCOMP!=0
-+# if BPP == 32 && IS_BIG_ENDIAN
-+# define UncompressCPixel(p) ( (*p << myFormat.redShift) | (*(p+1) << myFormat.greenShift) | (*(p+2) << myFormat.blueShift) )
-+# else
-+# if UNCOMP>0
-+# define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)>>UNCOMP)
-+# else
-+# define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)<<(-(UNCOMP)))
-+# endif
-+# endif
-+#else
-+# define UncompressCPixel(pointer) (*(CARDBPP*)pointer)
-+#endif
-+
-+extern XImage *image;
-+extern XImage *image_scale;
-+extern int skip_maybe_sync;
-+
-+static int HandleZRLETile(
-+ unsigned char* buffer,size_t buffer_length,
-+ int x,int y,int w,int h) {
-+ unsigned char* buffer_copy = buffer;
-+ unsigned char* buffer_end = buffer+buffer_length;
-+ unsigned char type;
-+
-+ if(buffer_length<1)
-+ return -2;
-+
-+ if (frameBufferLen < w * h * BPP/8) {
-+ if(frameBuffer) {
-+ free(frameBuffer);
-+ }
-+ frameBufferLen = w * h * BPP/8 * 2;
-+ frameBuffer = (unsigned char *) malloc(frameBufferLen);
-+ }
-+
-+zywrle_top:
-+ type = *buffer;
-+ buffer++;
-+ switch(type) {
-+ case 0: /* raw */
-+ {
-+#if DO_ZYWRLE && BPP != 8
-+ if (zywrle_level > 0 && !(zywrle_level & 0x80) ) {
-+ zywrle_level |= 0x80;
-+ goto zywrle_top;
-+ } else
-+#endif
-+ {
-+#if REALBPP!=BPP
-+ int m0 = 0, i,j;
-+
-+
-+ if(1+w*h*REALBPP/8>buffer_length) {
-+ fprintf(stderr, "expected %d bytes, got only %d (%dx%d)\n",1+w*h*REALBPP/8,buffer_length,w,h);
-+ return -3;
-+ }
-+
-+ for(j=y*si.framebufferWidth; j<(y+h)*si.framebufferWidth; j+=si.framebufferWidth) {
-+ for(i=x; i<x+w; i++,buffer+=REALBPP/8) {
-+# if 0
-+ ((CARDBPP*)frameBuffer)[j+i] = UncompressCPixel(buffer);
-+ /* alt */
-+ CARDBPP color = UncompressCPixel(buffer);
-+ CopyDataToScreen((char *)&color, i, j/si.framebufferWidth, 1, 1);
-+# else
-+ ((CARDBPP*)frameBuffer)[m0++] = UncompressCPixel(buffer);
-+# endif
-+ }
-+ }
-+ CopyDataToScreen((char *)frameBuffer, x, y, w, h);
-+if (0) fprintf(stderr, "cha1: %dx%d+%d+%d\n", w, h, x, y);
-+
-+#else
-+# if 0
-+ CopyRectangle(buffer, x, y, w, h);
-+# else
-+ CopyDataToScreen((char *)buffer, x, y, w, h);
-+# endif
-+ buffer+=w*h*REALBPP/8;
-+#endif
-+ }
-+ break;
-+ }
-+ case 1: /* solid */
-+ {
-+ CARDBPP color = UncompressCPixel(buffer);
-+
-+ if(1+REALBPP/8>buffer_length)
-+ return -4;
-+
-+ if ((BPP == 8 && appData.useBGR233) || (BPP == 16 && appData.useBGR565)) {
-+ int m0;
-+ for (m0=0; m0 < w*h; m0++) {
-+ ((CARDBPP*)frameBuffer)[m0] = color;
-+ }
-+ CopyDataToScreen((char *)frameBuffer, x, y, w, h);
-+ } else {
-+ FillRectangle(x, y, w, h, color);
-+ }
-+if (0) fprintf(stderr, "cha2: %dx%d+%d+%d\n", w, h, x, y);
-+
-+ buffer+=REALBPP/8;
-+
-+ break;
-+ }
-+ case 2 ... 127: /* packed Palette */
-+ {
-+ CARDBPP palette[16];
-+ int m0, i,j,shift,
-+ bpp=(type>4?(type>16?8:4):(type>2?2:1)),
-+ mask=(1<<bpp)-1,
-+ divider=(8/bpp);
-+
-+ if(1+type*REALBPP/8+((w+divider-1)/divider)*h>buffer_length)
-+ return -5;
-+
-+ /* read palette */
-+ for(i=0; i<type; i++,buffer+=REALBPP/8)
-+ palette[i] = UncompressCPixel(buffer);
-+
-+ m0 = 0;
-+ /* read palettized pixels */
-+ for(j=y*si.framebufferWidth; j<(y+h)*si.framebufferWidth; j+=si.framebufferWidth) {
-+ for(i=x,shift=8-bpp; i<x+w; i++) {
-+# if 0
-+ ((CARDBPP*)frameBuffer)[j+i] = palette[((*buffer)>>shift)&mask];
-+ /* alt */
-+ CARDBPP color = palette[((*buffer)>>shift)&mask];
-+ CopyDataToScreen((char *)&color, i, j/si.framebufferWidth, 1, 1);
-+# else
-+ ((CARDBPP*)frameBuffer)[m0++] = palette[((*buffer)>>shift)&mask];
-+# endif
-+ shift-=bpp;
-+ if(shift<0) {
-+ shift=8-bpp;
-+ buffer++;
-+ }
-+ }
-+ if(shift<8-bpp)
-+ buffer++;
-+ }
-+ CopyDataToScreen((char *)frameBuffer, x, y, w, h);
-+if (0) fprintf(stderr, "cha3: %dx%d+%d+%d\n", w, h, x, y);
-+
-+ break;
-+ }
-+ /* case 17 ... 127: not used, but valid */
-+ case 128: /* plain RLE */
-+ {
-+ int m0=0, i=0,j=0;
-+ while(j<h) {
-+ int color,length;
-+ /* read color */
-+ if(buffer+REALBPP/8+1>buffer_end)
-+ return -7;
-+ color = UncompressCPixel(buffer);
-+ buffer+=REALBPP/8;
-+ /* read run length */
-+ length=1;
-+ while(*buffer==0xff) {
-+ if(buffer+1>=buffer_end)
-+ return -8;
-+ length+=*buffer;
-+ buffer++;
-+ }
-+ length+=*buffer;
-+ buffer++;
-+ while(j<h && length>0) {
-+# if 0
-+ ((CARDBPP*)frameBuffer)[(y+j)*si.framebufferWidth+x+i] = color;
-+ /* alt */
-+ CopyDataToScreen((char *)&color, x+i, y+j, 1, 1);
-+# else
-+ ((CARDBPP*)frameBuffer)[m0++] = color;
-+# endif
-+ length--;
-+ i++;
-+ if(i>=w) {
-+ i=0;
-+ j++;
-+ }
-+ }
-+ if(length>0)
-+ fprintf(stderr, "Warning: possible ZRLE corruption\n");
-+ }
-+ CopyDataToScreen((char *)frameBuffer, x, y, w, h);
-+if (0) fprintf(stderr, "cha4: %dx%d+%d+%d\n", w, h, x, y);
-+
-+ break;
-+ }
-+ case 129: /* unused */
-+ {
-+ return -8;
-+ }
-+ case 130 ... 255: /* palette RLE */
-+ {
-+ CARDBPP palette[128];
-+ int m0 = 0, i,j;
-+
-+ if(2+(type-128)*REALBPP/8>buffer_length)
-+ return -9;
-+
-+ /* read palette */
-+ for(i=0; i<type-128; i++,buffer+=REALBPP/8)
-+ palette[i] = UncompressCPixel(buffer);
-+ /* read palettized pixels */
-+ i=j=0;
-+ while(j<h) {
-+ int color,length;
-+ /* read color */
-+ if(buffer>=buffer_end)
-+ return -10;
-+ color = palette[(*buffer)&0x7f];
-+ length=1;
-+ if(*buffer&0x80) {
-+ if(buffer+1>=buffer_end)
-+ return -11;
-+ buffer++;
-+ /* read run length */
-+ while(*buffer==0xff) {
-+ if(buffer+1>=buffer_end)
-+ return -8;
-+ length+=*buffer;
-+ buffer++;
-+ }
-+ length+=*buffer;
-+ }
-+ buffer++;
-+ while(j<h && length>0) {
-+# if 0
-+ ((CARDBPP*)frameBuffer)[(y+j)*si.framebufferWidth+x+i] = color;
-+ /* alt */
-+ CopyDataToScreen((char *)&color, x+i, y+j, 1, 1);
-+# else
-+ ((CARDBPP*)frameBuffer)[m0++] = color;
-+# endif
-+ length--;
-+ i++;
-+ if(i>=w) {
-+ i=0;
-+ j++;
-+ }
-+ }
-+ if(length>0)
-+ fprintf(stderr, "Warning: possible ZRLE corruption\n");
-+ }
-+ CopyDataToScreen((char *)frameBuffer, x, y, w, h);
-+if (0) fprintf(stderr, "cha5: %dx%d+%d+%d\n", w, h, x, y);
-+
-+ break;
-+ }
-+ }
-+
-+#if DO_ZYWRLE && BPP != 8
-+ if (zywrle_level & 0x80) {
-+ int th, tx;
-+ int widthInBytes = w * BPP / 8;
-+ int scrWidthInBytes;
-+ char *scr, *buf;
-+ static CARDBPP *ptmp = NULL;
-+ static int ptmp_len = 0;
-+ XImage *im = image_scale ? image_scale : image;
-+
-+ if (w * h > ptmp_len) {
-+ ptmp_len = w * h;
-+ if (ptmp_len < rfbZRLETileWidth*rfbZRLETileHeight) {
-+ ptmp_len = rfbZRLETileWidth*rfbZRLETileHeight;
-+ }
-+ if (ptmp) {
-+ free(ptmp);
-+ }
-+ ptmp = (CARDBPP *) malloc(ptmp_len * sizeof(CARDBPP));
-+ }
-+
-+ zywrle_level &= 0x7F;
-+ /* Reverse copy: screen to buf/ptmp: */
-+ /* make this CopyDataFromScreen() or something. */
-+ if (!appData.useBGR565) {
-+ scrWidthInBytes = si.framebufferWidth * myFormat.bitsPerPixel / 8;
-+ if (scrWidthInBytes != im->bytes_per_line) scrWidthInBytes = im->bytes_per_line;
-+ scr = im->data + y * scrWidthInBytes + x * myFormat.bitsPerPixel / 8;
-+ buf = (char *) ptmp;
-+
-+ for (th = 0; th < h; th++) {
-+ memcpy(buf, scr, widthInBytes);
-+ buf += widthInBytes;
-+ scr += scrWidthInBytes;
-+ }
-+ } else {
-+ scrWidthInBytes = si.framebufferWidth * 4;
-+ if (scrWidthInBytes != im->bytes_per_line) scrWidthInBytes = im->bytes_per_line;
-+ scr = im->data + y * scrWidthInBytes + x * 4;
-+ buf = (char *) ptmp;
-+
-+ for (th = 0; th < h; th++) {
-+ for (tx = 0; tx < w; tx++) {
-+ unsigned long pix = *((unsigned int *)scr + tx);
-+ unsigned int r1 = (pix & 0xff0000) >> 16;
-+ unsigned int g1 = (pix & 0x00ff00) >> 8;
-+ unsigned int b1 = (pix & 0x0000ff) >> 0;
-+ int r2, g2, b2, idx;
-+ int rok = 0, gok = 0, bok = 0, is0, sh = 10;
-+ r2 = (31 * r1)/255;
-+ g2 = (63 * g1)/255;
-+ b2 = (31 * b1)/255;
-+ for (is0 = 0; is0 < sh; is0++) {
-+ int is, i, t;
-+ for (i = 0; i < 2; i++) {
-+ if (i == 0) {
-+ is = -is0;
-+ } else {
-+ is = +is0;
-+ }
-+ if (!rok) {
-+ t = r2 + is;
-+ if (r1 == (255 * t)/31) {
-+ r2 = t; rok = 1;
-+ }
-+ }
-+ if (!gok) {
-+ t = g2 + is;
-+ if (g1 == (255 * t)/63) {
-+ g2 = t; gok = 1;
-+ }
-+ }
-+ if (!bok) {
-+ t = b2 + is;
-+ if (b1 == (255 * t)/31) {
-+ b2 = t; bok = 1;
-+ }
-+ }
-+ }
-+ if (rok && gok && bok) {
-+ break;
-+ }
-+ }
-+ idx = (r2 << 11) | (g2 << 5) | (b2 << 0);
-+ *((CARDBPP *)buf + tx) = (CARDBPP) idx;
-+ }
-+ buf += widthInBytes;
-+ scr += scrWidthInBytes;
-+ }
-+ }
-+ ZYWRLE_SYNTHESIZE((PIXEL_T *)ptmp, (PIXEL_T *)ptmp, w, h, w, zywrle_level, zywrleBuf );
-+ skip_maybe_sync = 1;
-+
-+ if (appData.yCrop > 0) {
-+ skip_maybe_sync = 0;
-+ }
-+ CopyDataToScreen((char *)ptmp, x, y, w, h);
-+
-+ }
-+#endif
-+
-+ return buffer-buffer_copy;
-+}
-+
-+#undef CARDBPP
-+#undef CARDREALBPP
-+#undef HandleZRLE
-+#undef HandleZRLETile
-+#undef UncompressCPixel
-+#undef REALBPP
-+
-+#undef UNCOMP
-+
-+#undef FillRectangle
-+#undef IS_BIG_ENDIAN
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrleencodetemplate.c vnc_unixsrc/vncviewer/zrleencodetemplate.c
---- vnc_unixsrc.orig/vncviewer/zrleencodetemplate.c 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/zrleencodetemplate.c 2007-02-04 23:18:09.000000000 -0500
-@@ -0,0 +1,317 @@
-+/*
-+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
-+ * Copyright (C) 2003 Sun Microsystems, Inc.
-+ *
-+ * This is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this software; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ */
-+
-+/*
-+ * Before including this file, you must define a number of CPP macros.
-+ *
-+ * BPP should be 8, 16 or 32 depending on the bits per pixel.
-+ * GET_IMAGE_INTO_BUF should be some code which gets a rectangle of pixel data
-+ * into the given buffer. EXTRA_ARGS can be defined to pass any other
-+ * arguments needed by GET_IMAGE_INTO_BUF.
-+ *
-+ * Note that the buf argument to ZRLE_ENCODE needs to be at least one pixel
-+ * bigger than the largest tile of pixel data, since the ZRLE encoding
-+ * algorithm writes to the position one past the end of the pixel data.
-+ */
-+
-+#include "zrleoutstream.h"
-+#include "zrlepalettehelper.h"
-+#include <assert.h>
-+
-+/* __RFB_CONCAT2 concatenates its two arguments. __RFB_CONCAT2E does the same
-+ but also expands its arguments if they are macros */
-+
-+#ifndef __RFB_CONCAT2E
-+#define __RFB_CONCAT2(a,b) a##b
-+#define __RFB_CONCAT2E(a,b) __RFB_CONCAT2(a,b)
-+#endif
-+
-+#ifndef __RFB_CONCAT3E
-+#define __RFB_CONCAT3(a,b,c) a##b##c
-+#define __RFB_CONCAT3E(a,b,c) __RFB_CONCAT3(a,b,c)
-+#endif
-+
-+#undef END_FIX
-+#if ZYWRLE_ENDIAN == ENDIAN_LITTLE
-+# define END_FIX LE
-+#elif ZYWRLE_ENDIAN == ENDIAN_BIG
-+# define END_FIX BE
-+#else
-+# define END_FIX NE
-+#endif
-+
-+#ifdef CPIXEL
-+#define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP)
-+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,CPIXEL)
-+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,CPIXEL,END_FIX)
-+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,CPIXEL,END_FIX)
-+#define BPPOUT 24
-+#elif BPP==15
-+#define PIXEL_T __RFB_CONCAT2E(zrle_U,16)
-+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,16)
-+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX)
-+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX)
-+#define BPPOUT 16
-+#else
-+#define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP)
-+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,BPP)
-+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX)
-+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX)
-+#define BPPOUT BPP
-+#endif
-+
-+#ifndef ZRLE_ONCE
-+#define ZRLE_ONCE
-+
-+static const int bitsPerPackedPixel[] = {
-+ 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-+};
-+
-+int zywrle_level;
-+int zywrleBuf[rfbZRLETileWidth*rfbZRLETileHeight];
-+
-+static zrlePaletteHelper paletteHelper;
-+
-+#endif /* ZRLE_ONCE */
-+
-+void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os);
-+
-+#if BPP!=8
-+#define ZYWRLE_ENCODE
-+#include "zywrletemplate.c"
-+#endif
-+
-+static void ZRLE_ENCODE (int x, int y, int w, int h,
-+ zrleOutStream* os, void* buf
-+ EXTRA_ARGS
-+ )
-+{
-+ int ty;
-+ for (ty = y; ty < y+h; ty += rfbZRLETileHeight) {
-+ int tx, th = rfbZRLETileHeight;
-+ if (th > y+h-ty) th = y+h-ty;
-+ for (tx = x; tx < x+w; tx += rfbZRLETileWidth) {
-+ int tw = rfbZRLETileWidth;
-+ if (tw > x+w-tx) tw = x+w-tx;
-+
-+ GET_IMAGE_INTO_BUF(tx,ty,tw,th,buf);
-+
-+ ZRLE_ENCODE_TILE((PIXEL_T*)buf, tw, th, os);
-+ }
-+ }
-+ zrleOutStreamFlush(os);
-+}
-+
-+
-+void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os)
-+{
-+ /* First find the palette and the number of runs */
-+
-+ zrlePaletteHelper *ph;
-+
-+ int runs = 0;
-+ int singlePixels = 0;
-+
-+ rfbBool useRle;
-+ rfbBool usePalette;
-+
-+ int estimatedBytes;
-+ int plainRleBytes;
-+ int i;
-+
-+ PIXEL_T* ptr = data;
-+ PIXEL_T* end = ptr + h * w;
-+ *end = ~*(end-1); /* one past the end is different so the while loop ends */
-+
-+ ph = &paletteHelper;
-+ zrlePaletteHelperInit(ph);
-+
-+ while (ptr < end) {
-+ PIXEL_T pix = *ptr;
-+ if (*++ptr != pix) {
-+ singlePixels++;
-+ } else {
-+ while (*++ptr == pix) ;
-+ runs++;
-+ }
-+ zrlePaletteHelperInsert(ph, pix);
-+ }
-+
-+ /* Solid tile is a special case */
-+
-+ if (ph->size == 1) {
-+ zrleOutStreamWriteU8(os, 1);
-+ zrleOutStreamWRITE_PIXEL(os, ph->palette[0]);
-+ return;
-+ }
-+
-+ /* Try to work out whether to use RLE and/or a palette. We do this by
-+ estimating the number of bytes which will be generated and picking the
-+ method which results in the fewest bytes. Of course this may not result
-+ in the fewest bytes after compression... */
-+
-+ useRle = FALSE;
-+ usePalette = FALSE;
-+
-+ estimatedBytes = w * h * (BPPOUT/8); /* start assuming raw */
-+
-+#if BPP!=8
-+ if( (zywrle_level>0)&& !(zywrle_level & 0x80) ){
-+ estimatedBytes >>= zywrle_level;
-+ }
-+#endif
-+
-+ plainRleBytes = ((BPPOUT/8)+1) * (runs + singlePixels);
-+
-+ if (plainRleBytes < estimatedBytes) {
-+ useRle = TRUE;
-+ estimatedBytes = plainRleBytes;
-+ }
-+
-+ if (ph->size < 128) {
-+ int paletteRleBytes = (BPPOUT/8) * ph->size + 2 * runs + singlePixels;
-+
-+ if (paletteRleBytes < estimatedBytes) {
-+ useRle = TRUE;
-+ usePalette = TRUE;
-+ estimatedBytes = paletteRleBytes;
-+ }
-+
-+ if (ph->size < 17) {
-+ int packedBytes = ((BPPOUT/8) * ph->size +
-+ w * h * bitsPerPackedPixel[ph->size-1] / 8);
-+
-+ if (packedBytes < estimatedBytes) {
-+ useRle = FALSE;
-+ usePalette = TRUE;
-+ estimatedBytes = packedBytes;
-+ }
-+ }
-+ }
-+
-+ if (!usePalette) ph->size = 0;
-+
-+ zrleOutStreamWriteU8(os, (useRle ? 128 : 0) | ph->size);
-+
-+ for (i = 0; i < ph->size; i++) {
-+ zrleOutStreamWRITE_PIXEL(os, ph->palette[i]);
-+ }
-+
-+ if (useRle) {
-+
-+ PIXEL_T* ptr = data;
-+ PIXEL_T* end = ptr + w * h;
-+ PIXEL_T* runStart;
-+ PIXEL_T pix;
-+ while (ptr < end) {
-+ int len;
-+ runStart = ptr;
-+ pix = *ptr++;
-+ while (*ptr == pix && ptr < end)
-+ ptr++;
-+ len = ptr - runStart;
-+ if (len <= 2 && usePalette) {
-+ int index = zrlePaletteHelperLookup(ph, pix);
-+ if (len == 2)
-+ zrleOutStreamWriteU8(os, index);
-+ zrleOutStreamWriteU8(os, index);
-+ continue;
-+ }
-+ if (usePalette) {
-+ int index = zrlePaletteHelperLookup(ph, pix);
-+ zrleOutStreamWriteU8(os, index | 128);
-+ } else {
-+ zrleOutStreamWRITE_PIXEL(os, pix);
-+ }
-+ len -= 1;
-+ while (len >= 255) {
-+ zrleOutStreamWriteU8(os, 255);
-+ len -= 255;
-+ }
-+ zrleOutStreamWriteU8(os, len);
-+ }
-+
-+ } else {
-+
-+ /* no RLE */
-+
-+ if (usePalette) {
-+ int bppp;
-+ PIXEL_T* ptr = data;
-+
-+ /* packed pixels */
-+
-+ assert (ph->size < 17);
-+
-+ bppp = bitsPerPackedPixel[ph->size-1];
-+
-+ for (i = 0; i < h; i++) {
-+ zrle_U8 nbits = 0;
-+ zrle_U8 byte = 0;
-+
-+ PIXEL_T* eol = ptr + w;
-+
-+ while (ptr < eol) {
-+ PIXEL_T pix = *ptr++;
-+ zrle_U8 index = zrlePaletteHelperLookup(ph, pix);
-+ byte = (byte << bppp) | index;
-+ nbits += bppp;
-+ if (nbits >= 8) {
-+ zrleOutStreamWriteU8(os, byte);
-+ nbits = 0;
-+ }
-+ }
-+ if (nbits > 0) {
-+ byte <<= 8 - nbits;
-+ zrleOutStreamWriteU8(os, byte);
-+ }
-+ }
-+ } else {
-+
-+ /* raw */
-+
-+#if BPP!=8
-+ if( (zywrle_level>0)&& !(zywrle_level & 0x80) ){
-+ ZYWRLE_ANALYZE( data, data, w, h, w, zywrle_level, zywrleBuf );
-+ zywrle_level |= 0x80;
-+ ZRLE_ENCODE_TILE( data, w, h, os );
-+ zywrle_level &= 0x7F;
-+ }else
-+#endif
-+ {
-+#ifdef CPIXEL
-+ PIXEL_T *ptr;
-+ for (ptr = data; ptr < data+w*h; ptr++) {
-+ zrleOutStreamWRITE_PIXEL(os, *ptr);
-+ }
-+#else
-+ zrleOutStreamWriteBytes(os, (zrle_U8 *)data, w*h*(BPP/8));
-+#endif
-+ }
-+ }
-+ }
-+}
-+
-+#undef PIXEL_T
-+#undef zrleOutStreamWRITE_PIXEL
-+#undef ZRLE_ENCODE
-+#undef ZRLE_ENCODE_TILE
-+#undef ZYWRLE_ENCODE_TILE
-+#undef BPPOUT
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrleoutstream.c vnc_unixsrc/vncviewer/zrleoutstream.c
---- vnc_unixsrc.orig/vncviewer/zrleoutstream.c 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/zrleoutstream.c 2005-05-15 10:57:54.000000000 -0400
-@@ -0,0 +1,275 @@
-+/*
-+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
-+ * Copyright (C) 2003 Sun Microsystems, Inc.
-+ *
-+ * This is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this software; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ */
-+
-+#include "zrleoutstream.h"
-+#include <stdlib.h>
-+
-+#define ZRLE_IN_BUFFER_SIZE 16384
-+#define ZRLE_OUT_BUFFER_SIZE 1024
-+#undef ZRLE_DEBUG
-+
-+static rfbBool zrleBufferAlloc(zrleBuffer *buffer, int size)
-+{
-+ buffer->ptr = buffer->start = malloc(size);
-+ if (buffer->start == NULL) {
-+ buffer->end = NULL;
-+ return FALSE;
-+ }
-+
-+ buffer->end = buffer->start + size;
-+
-+ return TRUE;
-+}
-+
-+static void zrleBufferFree(zrleBuffer *buffer)
-+{
-+ if (buffer->start)
-+ free(buffer->start);
-+ buffer->start = buffer->ptr = buffer->end = NULL;
-+}
-+
-+static rfbBool zrleBufferGrow(zrleBuffer *buffer, int size)
-+{
-+ int offset;
-+
-+ size += buffer->end - buffer->start;
-+ offset = ZRLE_BUFFER_LENGTH (buffer);
-+
-+ buffer->start = realloc(buffer->start, size);
-+ if (!buffer->start) {
-+ return FALSE;
-+ }
-+
-+ buffer->end = buffer->start + size;
-+ buffer->ptr = buffer->start + offset;
-+
-+ return TRUE;
-+}
-+
-+zrleOutStream *zrleOutStreamNew(void)
-+{
-+ zrleOutStream *os;
-+
-+ os = malloc(sizeof(zrleOutStream));
-+ if (os == NULL)
-+ return NULL;
-+
-+ if (!zrleBufferAlloc(&os->in, ZRLE_IN_BUFFER_SIZE)) {
-+ free(os);
-+ return NULL;
-+ }
-+
-+ if (!zrleBufferAlloc(&os->out, ZRLE_OUT_BUFFER_SIZE)) {
-+ zrleBufferFree(&os->in);
-+ free(os);
-+ return NULL;
-+ }
-+
-+ os->zs.zalloc = Z_NULL;
-+ os->zs.zfree = Z_NULL;
-+ os->zs.opaque = Z_NULL;
-+ if (deflateInit(&os->zs, Z_DEFAULT_COMPRESSION) != Z_OK) {
-+ zrleBufferFree(&os->in);
-+ free(os);
-+ return NULL;
-+ }
-+
-+ return os;
-+}
-+
-+void zrleOutStreamFree (zrleOutStream *os)
-+{
-+ deflateEnd(&os->zs);
-+ zrleBufferFree(&os->in);
-+ zrleBufferFree(&os->out);
-+ free(os);
-+}
-+
-+rfbBool zrleOutStreamFlush(zrleOutStream *os)
-+{
-+ os->zs.next_in = os->in.start;
-+ os->zs.avail_in = ZRLE_BUFFER_LENGTH (&os->in);
-+
-+#ifdef ZRLE_DEBUG
-+ rfbLog("zrleOutStreamFlush: avail_in %d\n", os->zs.avail_in);
-+#endif
-+
-+ while (os->zs.avail_in != 0) {
-+ do {
-+ int ret;
-+
-+ if (os->out.ptr >= os->out.end &&
-+ !zrleBufferGrow(&os->out, os->out.end - os->out.start)) {
-+ rfbLog("zrleOutStreamFlush: failed to grow output buffer\n");
-+ return FALSE;
-+ }
-+
-+ os->zs.next_out = os->out.ptr;
-+ os->zs.avail_out = os->out.end - os->out.ptr;
-+
-+#ifdef ZRLE_DEBUG
-+ rfbLog("zrleOutStreamFlush: calling deflate, avail_in %d, avail_out %d\n",
-+ os->zs.avail_in, os->zs.avail_out);
-+#endif
-+
-+ if ((ret = deflate(&os->zs, Z_SYNC_FLUSH)) != Z_OK) {
-+ rfbLog("zrleOutStreamFlush: deflate failed with error code %d\n", ret);
-+ return FALSE;
-+ }
-+
-+#ifdef ZRLE_DEBUG
-+ rfbLog("zrleOutStreamFlush: after deflate: %d bytes\n",
-+ os->zs.next_out - os->out.ptr);
-+#endif
-+
-+ os->out.ptr = os->zs.next_out;
-+ } while (os->zs.avail_out == 0);
-+ }
-+
-+ os->in.ptr = os->in.start;
-+
-+ return TRUE;
-+}
-+
-+static int zrleOutStreamOverrun(zrleOutStream *os,
-+ int size)
-+{
-+#ifdef ZRLE_DEBUG
-+ rfbLog("zrleOutStreamOverrun\n");
-+#endif
-+
-+ while (os->in.end - os->in.ptr < size && os->in.ptr > os->in.start) {
-+ os->zs.next_in = os->in.start;
-+ os->zs.avail_in = ZRLE_BUFFER_LENGTH (&os->in);
-+
-+ do {
-+ int ret;
-+
-+ if (os->out.ptr >= os->out.end &&
-+ !zrleBufferGrow(&os->out, os->out.end - os->out.start)) {
-+ rfbLog("zrleOutStreamOverrun: failed to grow output buffer\n");
-+ return FALSE;
-+ }
-+
-+ os->zs.next_out = os->out.ptr;
-+ os->zs.avail_out = os->out.end - os->out.ptr;
-+
-+#ifdef ZRLE_DEBUG
-+ rfbLog("zrleOutStreamOverrun: calling deflate, avail_in %d, avail_out %d\n",
-+ os->zs.avail_in, os->zs.avail_out);
-+#endif
-+
-+ if ((ret = deflate(&os->zs, 0)) != Z_OK) {
-+ rfbLog("zrleOutStreamOverrun: deflate failed with error code %d\n", ret);
-+ return 0;
-+ }
-+
-+#ifdef ZRLE_DEBUG
-+ rfbLog("zrleOutStreamOverrun: after deflate: %d bytes\n",
-+ os->zs.next_out - os->out.ptr);
-+#endif
-+
-+ os->out.ptr = os->zs.next_out;
-+ } while (os->zs.avail_out == 0);
-+
-+ /* output buffer not full */
-+
-+ if (os->zs.avail_in == 0) {
-+ os->in.ptr = os->in.start;
-+ } else {
-+ /* but didn't consume all the data? try shifting what's left to the
-+ * start of the buffer.
-+ */
-+ rfbLog("zrleOutStreamOverrun: out buf not full, but in data not consumed\n");
-+ memmove(os->in.start, os->zs.next_in, os->in.ptr - os->zs.next_in);
-+ os->in.ptr -= os->zs.next_in - os->in.start;
-+ }
-+ }
-+
-+ if (size > os->in.end - os->in.ptr)
-+ size = os->in.end - os->in.ptr;
-+
-+ return size;
-+}
-+
-+static int zrleOutStreamCheck(zrleOutStream *os, int size)
-+{
-+ if (os->in.ptr + size > os->in.end) {
-+ return zrleOutStreamOverrun(os, size);
-+ }
-+ return size;
-+}
-+
-+void zrleOutStreamWriteBytes(zrleOutStream *os,
-+ const zrle_U8 *data,
-+ int length)
-+{
-+ const zrle_U8* dataEnd = data + length;
-+ while (data < dataEnd) {
-+ int n = zrleOutStreamCheck(os, dataEnd - data);
-+ memcpy(os->in.ptr, data, n);
-+ os->in.ptr += n;
-+ data += n;
-+ }
-+}
-+
-+void zrleOutStreamWriteU8(zrleOutStream *os, zrle_U8 u)
-+{
-+ zrleOutStreamCheck(os, 1);
-+ *os->in.ptr++ = u;
-+}
-+
-+void zrleOutStreamWriteOpaque8(zrleOutStream *os, zrle_U8 u)
-+{
-+ zrleOutStreamCheck(os, 1);
-+ *os->in.ptr++ = u;
-+}
-+
-+void zrleOutStreamWriteOpaque16 (zrleOutStream *os, zrle_U16 u)
-+{
-+ zrleOutStreamCheck(os, 2);
-+ *os->in.ptr++ = ((zrle_U8*)&u)[0];
-+ *os->in.ptr++ = ((zrle_U8*)&u)[1];
-+}
-+
-+void zrleOutStreamWriteOpaque32 (zrleOutStream *os, zrle_U32 u)
-+{
-+ zrleOutStreamCheck(os, 4);
-+ *os->in.ptr++ = ((zrle_U8*)&u)[0];
-+ *os->in.ptr++ = ((zrle_U8*)&u)[1];
-+ *os->in.ptr++ = ((zrle_U8*)&u)[2];
-+ *os->in.ptr++ = ((zrle_U8*)&u)[3];
-+}
-+
-+void zrleOutStreamWriteOpaque24A(zrleOutStream *os, zrle_U32 u)
-+{
-+ zrleOutStreamCheck(os, 3);
-+ *os->in.ptr++ = ((zrle_U8*)&u)[0];
-+ *os->in.ptr++ = ((zrle_U8*)&u)[1];
-+ *os->in.ptr++ = ((zrle_U8*)&u)[2];
-+}
-+
-+void zrleOutStreamWriteOpaque24B(zrleOutStream *os, zrle_U32 u)
-+{
-+ zrleOutStreamCheck(os, 3);
-+ *os->in.ptr++ = ((zrle_U8*)&u)[1];
-+ *os->in.ptr++ = ((zrle_U8*)&u)[2];
-+ *os->in.ptr++ = ((zrle_U8*)&u)[3];
-+}
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrleoutstream.h vnc_unixsrc/vncviewer/zrleoutstream.h
---- vnc_unixsrc.orig/vncviewer/zrleoutstream.h 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/zrleoutstream.h 2004-05-25 06:05:15.000000000 -0400
-@@ -0,0 +1,62 @@
-+/*
-+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
-+ * Copyright (C) 2003 Sun Microsystems, Inc.
-+ *
-+ * This is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this software; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ */
-+
-+#ifndef __ZRLE_OUT_STREAM_H__
-+#define __ZRLE_OUT_STREAM_H__
-+
-+#include <zlib.h>
-+#include "zrletypes.h"
-+#include "rfb/rfb.h"
-+
-+typedef struct {
-+ zrle_U8 *start;
-+ zrle_U8 *ptr;
-+ zrle_U8 *end;
-+} zrleBuffer;
-+
-+typedef struct {
-+ zrleBuffer in;
-+ zrleBuffer out;
-+
-+ z_stream zs;
-+} zrleOutStream;
-+
-+#define ZRLE_BUFFER_LENGTH(b) ((b)->ptr - (b)->start)
-+
-+zrleOutStream *zrleOutStreamNew (void);
-+void zrleOutStreamFree (zrleOutStream *os);
-+rfbBool zrleOutStreamFlush (zrleOutStream *os);
-+void zrleOutStreamWriteBytes (zrleOutStream *os,
-+ const zrle_U8 *data,
-+ int length);
-+void zrleOutStreamWriteU8 (zrleOutStream *os,
-+ zrle_U8 u);
-+void zrleOutStreamWriteOpaque8 (zrleOutStream *os,
-+ zrle_U8 u);
-+void zrleOutStreamWriteOpaque16 (zrleOutStream *os,
-+ zrle_U16 u);
-+void zrleOutStreamWriteOpaque32 (zrleOutStream *os,
-+ zrle_U32 u);
-+void zrleOutStreamWriteOpaque24A(zrleOutStream *os,
-+ zrle_U32 u);
-+void zrleOutStreamWriteOpaque24B(zrleOutStream *os,
-+ zrle_U32 u);
-+
-+#endif /* __ZRLE_OUT_STREAM_H__ */
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrlepalettehelper.c vnc_unixsrc/vncviewer/zrlepalettehelper.c
---- vnc_unixsrc.orig/vncviewer/zrlepalettehelper.c 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/zrlepalettehelper.c 2004-05-25 06:05:15.000000000 -0400
-@@ -0,0 +1,62 @@
-+/*
-+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
-+ * Copyright (C) 2003 Sun Microsystems, Inc.
-+ *
-+ * This is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this software; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ */
-+
-+#include "zrlepalettehelper.h"
-+#include <assert.h>
-+#include <string.h>
-+
-+#define ZRLE_HASH(pix) (((pix) ^ ((pix) >> 17)) & 4095)
-+
-+void zrlePaletteHelperInit(zrlePaletteHelper *helper)
-+{
-+ memset(helper->palette, 0, sizeof(helper->palette));
-+ memset(helper->index, 255, sizeof(helper->index));
-+ memset(helper->key, 0, sizeof(helper->key));
-+ helper->size = 0;
-+}
-+
-+void zrlePaletteHelperInsert(zrlePaletteHelper *helper, zrle_U32 pix)
-+{
-+ if (helper->size < ZRLE_PALETTE_MAX_SIZE) {
-+ int i = ZRLE_HASH(pix);
-+
-+ while (helper->index[i] != 255 && helper->key[i] != pix)
-+ i++;
-+ if (helper->index[i] != 255) return;
-+
-+ helper->index[i] = helper->size;
-+ helper->key[i] = pix;
-+ helper->palette[helper->size] = pix;
-+ }
-+ helper->size++;
-+}
-+
-+int zrlePaletteHelperLookup(zrlePaletteHelper *helper, zrle_U32 pix)
-+{
-+ int i = ZRLE_HASH(pix);
-+
-+ assert(helper->size <= ZRLE_PALETTE_MAX_SIZE);
-+
-+ while (helper->index[i] != 255 && helper->key[i] != pix)
-+ i++;
-+ if (helper->index[i] != 255) return helper->index[i];
-+
-+ return -1;
-+}
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrlepalettehelper.h vnc_unixsrc/vncviewer/zrlepalettehelper.h
---- vnc_unixsrc.orig/vncviewer/zrlepalettehelper.h 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/zrlepalettehelper.h 2004-05-25 06:05:15.000000000 -0400
-@@ -0,0 +1,46 @@
-+/*
-+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
-+ * Copyright (C) 2003 Sun Microsystems, Inc.
-+ *
-+ * This is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this software; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ */
-+
-+/*
-+ * The PaletteHelper class helps us build up the palette from pixel data by
-+ * storing a reverse index using a simple hash-table
-+ */
-+
-+#ifndef __ZRLE_PALETTE_HELPER_H__
-+#define __ZRLE_PALETTE_HELPER_H__
-+
-+#include "zrletypes.h"
-+
-+#define ZRLE_PALETTE_MAX_SIZE 127
-+
-+typedef struct {
-+ zrle_U32 palette[ZRLE_PALETTE_MAX_SIZE];
-+ zrle_U8 index[ZRLE_PALETTE_MAX_SIZE + 4096];
-+ zrle_U32 key[ZRLE_PALETTE_MAX_SIZE + 4096];
-+ int size;
-+} zrlePaletteHelper;
-+
-+void zrlePaletteHelperInit (zrlePaletteHelper *helper);
-+void zrlePaletteHelperInsert(zrlePaletteHelper *helper,
-+ zrle_U32 pix);
-+int zrlePaletteHelperLookup(zrlePaletteHelper *helper,
-+ zrle_U32 pix);
-+
-+#endif /* __ZRLE_PALETTE_HELPER_H__ */
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrletypes.h vnc_unixsrc/vncviewer/zrletypes.h
---- vnc_unixsrc.orig/vncviewer/zrletypes.h 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/zrletypes.h 2004-05-25 06:05:15.000000000 -0400
-@@ -0,0 +1,30 @@
-+/*
-+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
-+ *
-+ * This is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this software; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ */
-+
-+#ifndef __ZRLE_TYPES_H__
-+#define __ZRLE_TYPES_H__
-+
-+typedef unsigned char zrle_U8;
-+typedef unsigned short zrle_U16;
-+typedef unsigned int zrle_U32;
-+typedef signed char zrle_S8;
-+typedef signed short zrle_S16;
-+typedef signed int zrle_S32;
-+
-+#endif /* __ZRLE_TYPES_H__ */
-diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zywrletemplate.c vnc_unixsrc/vncviewer/zywrletemplate.c
---- vnc_unixsrc.orig/vncviewer/zywrletemplate.c 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_unixsrc/vncviewer/zywrletemplate.c 2008-02-15 23:33:13.000000000 -0500
-@@ -0,0 +1,824 @@
-+
-+/********************************************************************
-+ * *
-+ * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE. *
-+ * *
-+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
-+ * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE. *
-+ * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
-+ * *
-+ * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006 *
-+ * BY Hitachi Systems & Services, Ltd. *
-+ * (Noriaki Yamazaki, Research & Developement Center) * *
-+ * *
-+ ********************************************************************
-+Redistribution and use in source and binary forms, with or without
-+modification, are permitted provided that the following conditions
-+are met:
-+
-+- Redistributions of source code must retain the above copyright
-+notice, this list of conditions and the following disclaimer.
-+
-+- Redistributions in binary form must reproduce the above copyright
-+notice, this list of conditions and the following disclaimer in the
-+documentation and/or other materials provided with the distribution.
-+
-+- Neither the name of the Hitachi Systems & Services, Ltd. nor
-+the names of its contributors may be used to endorse or promote
-+products derived from this software without specific prior written
-+permission.
-+
-+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
-+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ ********************************************************************/
-+
-+/* Change Log:
-+ V0.02 : 2008/02/04 : Fix mis encode/decode when width != scanline
-+ (Thanks Johannes Schindelin, author of LibVNC
-+ Server/Client)
-+ V0.01 : 2007/02/06 : Initial release
-+*/
-+
-+/* #define ZYWRLE_ENCODE */
-+/* #define ZYWRLE_DECODE */
-+#define ZYWRLE_QUANTIZE
-+
-+/*
-+[References]
-+ PLHarr:
-+ Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy, "An Improved N-Bit to N-Bit Reversible Haar-Like Transform," Pacific Graphics 2004, October 2004, pp. 371-380.
-+ EZW:
-+ Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet Coefficients, IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993).
-+*/
-+
-+
-+/* Template Macro stuffs. */
-+#undef ZYWRLE_ANALYZE
-+#undef ZYWRLE_SYNTHESIZE
-+#define ZYWRLE_ANALYZE __RFB_CONCAT3E(zywrleAnalyze,BPP,END_FIX)
-+#define ZYWRLE_SYNTHESIZE __RFB_CONCAT3E(zywrleSynthesize,BPP,END_FIX)
-+
-+#define ZYWRLE_RGBYUV __RFB_CONCAT3E(zywrleRGBYUV,BPP,END_FIX)
-+#define ZYWRLE_YUVRGB __RFB_CONCAT3E(zywrleYUVRGB,BPP,END_FIX)
-+#define ZYWRLE_YMASK __RFB_CONCAT2E(ZYWRLE_YMASK,BPP)
-+#define ZYWRLE_UVMASK __RFB_CONCAT2E(ZYWRLE_UVMASK,BPP)
-+#define ZYWRLE_LOAD_PIXEL __RFB_CONCAT2E(ZYWRLE_LOAD_PIXEL,BPP)
-+#define ZYWRLE_SAVE_PIXEL __RFB_CONCAT2E(ZYWRLE_SAVE_PIXEL,BPP)
-+
-+/* Packing/Unpacking pixel stuffs.
-+ Endian conversion stuffs. */
-+#undef S_0
-+#undef S_1
-+#undef L_0
-+#undef L_1
-+#undef L_2
-+#if ZYWRLE_ENDIAN == ENDIAN_BIG
-+# define S_0 1
-+# define S_1 0
-+# define L_0 3
-+# define L_1 2
-+# define L_2 1
-+#else
-+# define S_0 0
-+# define S_1 1
-+# define L_0 0
-+# define L_1 1
-+# define L_2 2
-+#endif
-+
-+/* Load/Save pixel stuffs. */
-+#define ZYWRLE_YMASK15 0xFFFFFFF8
-+#define ZYWRLE_UVMASK15 0xFFFFFFF8
-+#define ZYWRLE_LOAD_PIXEL15(pSrc,R,G,B) { \
-+ R = (((unsigned char*)pSrc)[S_1]<< 1)& 0xF8; \
-+ G = ((((unsigned char*)pSrc)[S_1]<< 6)|(((unsigned char*)pSrc)[S_0]>> 2))& 0xF8; \
-+ B = (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8; \
-+}
-+#define ZYWRLE_SAVE_PIXEL15(pDst,R,G,B) { \
-+ R &= 0xF8; \
-+ G &= 0xF8; \
-+ B &= 0xF8; \
-+ ((unsigned char*)pDst)[S_1] = (unsigned char)( (R>>1)|(G>>6) ); \
-+ ((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<2))& 0xFF); \
-+}
-+#define ZYWRLE_YMASK16 0xFFFFFFFC
-+#define ZYWRLE_UVMASK16 0xFFFFFFF8
-+#define ZYWRLE_LOAD_PIXEL16(pSrc,R,G,B) { \
-+ R = ((unsigned char*)pSrc)[S_1] & 0xF8; \
-+ G = ((((unsigned char*)pSrc)[S_1]<< 5)|(((unsigned char*)pSrc)[S_0]>> 3))& 0xFC; \
-+ B = (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8; \
-+}
-+#define ZYWRLE_SAVE_PIXEL16(pDst,R,G,B) { \
-+ R &= 0xF8; \
-+ G &= 0xFC; \
-+ B &= 0xF8; \
-+ ((unsigned char*)pDst)[S_1] = (unsigned char)( R |(G>>5) ); \
-+ ((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<3))& 0xFF); \
-+}
-+#define ZYWRLE_YMASK32 0xFFFFFFFF
-+#define ZYWRLE_UVMASK32 0xFFFFFFFF
-+#define ZYWRLE_LOAD_PIXEL32(pSrc,R,G,B) { \
-+ R = ((unsigned char*)pSrc)[L_2]; \
-+ G = ((unsigned char*)pSrc)[L_1]; \
-+ B = ((unsigned char*)pSrc)[L_0]; \
-+}
-+#define ZYWRLE_SAVE_PIXEL32(pDst,R,G,B) { \
-+ ((unsigned char*)pDst)[L_2] = (unsigned char)R; \
-+ ((unsigned char*)pDst)[L_1] = (unsigned char)G; \
-+ ((unsigned char*)pDst)[L_0] = (unsigned char)B; \
-+}
-+
-+#ifndef ZYWRLE_ONCE
-+#define ZYWRLE_ONCE
-+
-+#ifdef WIN32
-+#define InlineX __inline
-+#else
-+#define InlineX inline
-+#endif
-+
-+#ifdef ZYWRLE_ENCODE
-+/* Tables for Coefficients filtering. */
-+# ifndef ZYWRLE_QUANTIZE
-+/* Type A:lower bit omitting of EZW style. */
-+const static unsigned int zywrleParam[3][3]={
-+ {0x0000F000,0x00000000,0x00000000},
-+ {0x0000C000,0x00F0F0F0,0x00000000},
-+ {0x0000C000,0x00C0C0C0,0x00F0F0F0},
-+/* {0x0000FF00,0x00000000,0x00000000},
-+ {0x0000FF00,0x00FFFFFF,0x00000000},
-+ {0x0000FF00,0x00FFFFFF,0x00FFFFFF}, */
-+};
-+# else
-+/* Type B:Non liner quantization filter. */
-+static const signed char zywrleConv[4][256]={
-+{ /* bi=5, bo=5 r=0.0:PSNR=24.849 */
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+},
-+{ /* bi=5, bo=5 r=2.0:PSNR=74.031 */
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 32,
-+ 32, 32, 32, 32, 32, 32, 32, 32,
-+ 32, 32, 32, 32, 32, 32, 32, 32,
-+ 48, 48, 48, 48, 48, 48, 48, 48,
-+ 48, 48, 48, 56, 56, 56, 56, 56,
-+ 56, 56, 56, 56, 64, 64, 64, 64,
-+ 64, 64, 64, 64, 72, 72, 72, 72,
-+ 72, 72, 72, 72, 80, 80, 80, 80,
-+ 80, 80, 88, 88, 88, 88, 88, 88,
-+ 88, 88, 88, 88, 88, 88, 96, 96,
-+ 96, 96, 96, 104, 104, 104, 104, 104,
-+ 104, 104, 104, 104, 104, 112, 112, 112,
-+ 112, 112, 112, 112, 112, 112, 120, 120,
-+ 120, 120, 120, 120, 120, 120, 120, 120,
-+ 0, -120, -120, -120, -120, -120, -120, -120,
-+ -120, -120, -120, -112, -112, -112, -112, -112,
-+ -112, -112, -112, -112, -104, -104, -104, -104,
-+ -104, -104, -104, -104, -104, -104, -96, -96,
-+ -96, -96, -96, -88, -88, -88, -88, -88,
-+ -88, -88, -88, -88, -88, -88, -88, -80,
-+ -80, -80, -80, -80, -80, -72, -72, -72,
-+ -72, -72, -72, -72, -72, -64, -64, -64,
-+ -64, -64, -64, -64, -64, -56, -56, -56,
-+ -56, -56, -56, -56, -56, -56, -48, -48,
-+ -48, -48, -48, -48, -48, -48, -48, -48,
-+ -48, -32, -32, -32, -32, -32, -32, -32,
-+ -32, -32, -32, -32, -32, -32, -32, -32,
-+ -32, -32, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+},
-+{ /* bi=5, bo=4 r=2.0:PSNR=64.441 */
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 48, 48, 48, 48, 48, 48, 48, 48,
-+ 48, 48, 48, 48, 48, 48, 48, 48,
-+ 48, 48, 48, 48, 48, 48, 48, 48,
-+ 64, 64, 64, 64, 64, 64, 64, 64,
-+ 64, 64, 64, 64, 64, 64, 64, 64,
-+ 80, 80, 80, 80, 80, 80, 80, 80,
-+ 80, 80, 80, 80, 80, 88, 88, 88,
-+ 88, 88, 88, 88, 88, 88, 88, 88,
-+ 104, 104, 104, 104, 104, 104, 104, 104,
-+ 104, 104, 104, 112, 112, 112, 112, 112,
-+ 112, 112, 112, 112, 120, 120, 120, 120,
-+ 120, 120, 120, 120, 120, 120, 120, 120,
-+ 0, -120, -120, -120, -120, -120, -120, -120,
-+ -120, -120, -120, -120, -120, -112, -112, -112,
-+ -112, -112, -112, -112, -112, -112, -104, -104,
-+ -104, -104, -104, -104, -104, -104, -104, -104,
-+ -104, -88, -88, -88, -88, -88, -88, -88,
-+ -88, -88, -88, -88, -80, -80, -80, -80,
-+ -80, -80, -80, -80, -80, -80, -80, -80,
-+ -80, -64, -64, -64, -64, -64, -64, -64,
-+ -64, -64, -64, -64, -64, -64, -64, -64,
-+ -64, -48, -48, -48, -48, -48, -48, -48,
-+ -48, -48, -48, -48, -48, -48, -48, -48,
-+ -48, -48, -48, -48, -48, -48, -48, -48,
-+ -48, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+},
-+{ /* bi=5, bo=2 r=2.0:PSNR=43.175 */
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 88, 88, 88, 88, 88, 88, 88, 88,
-+ 88, 88, 88, 88, 88, 88, 88, 88,
-+ 88, 88, 88, 88, 88, 88, 88, 88,
-+ 88, 88, 88, 88, 88, 88, 88, 88,
-+ 88, 88, 88, 88, 88, 88, 88, 88,
-+ 88, 88, 88, 88, 88, 88, 88, 88,
-+ 88, 88, 88, 88, 88, 88, 88, 88,
-+ 88, 88, 88, 88, 88, 88, 88, 88,
-+ 0, -88, -88, -88, -88, -88, -88, -88,
-+ -88, -88, -88, -88, -88, -88, -88, -88,
-+ -88, -88, -88, -88, -88, -88, -88, -88,
-+ -88, -88, -88, -88, -88, -88, -88, -88,
-+ -88, -88, -88, -88, -88, -88, -88, -88,
-+ -88, -88, -88, -88, -88, -88, -88, -88,
-+ -88, -88, -88, -88, -88, -88, -88, -88,
-+ -88, -88, -88, -88, -88, -88, -88, -88,
-+ -88, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0,
-+}
-+};
-+const static signed char* zywrleParam[3][3][3]={
-+ {{zywrleConv[0],zywrleConv[2],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}},
-+ {{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}},
-+ {{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[2],zywrleConv[2],zywrleConv[2]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]}},
-+};
-+# endif
-+#endif
-+
-+static InlineX void Harr(signed char* pX0, signed char* pX1)
-+{
-+ /* Piecewise-Linear Harr(PLHarr) */
-+ int X0 = (int)*pX0, X1 = (int)*pX1;
-+ int orgX0 = X0, orgX1 = X1;
-+ if ((X0 ^ X1) & 0x80) {
-+ /* differ sign */
-+ X1 += X0;
-+ if (((X1^orgX1)&0x80)==0) {
-+ /* |X1| > |X0| */
-+ X0 -= X1; /* H = -B */
-+ }
-+ } else {
-+ /* same sign */
-+ X0 -= X1;
-+ if (((X0 ^ orgX0) & 0x80) == 0) {
-+ /* |X0| > |X1| */
-+ X1 += X0; /* L = A */
-+ }
-+ }
-+ *pX0 = (signed char)X1;
-+ *pX1 = (signed char)X0;
-+}
-+/*
-+ 1D-Wavelet transform.
-+
-+ In coefficients array, the famous 'pyramid' decomposition is well used.
-+
-+ 1D Model:
-+ |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0
-+ |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1
-+
-+ But this method needs line buffer because H/L is different position from X0/X1.
-+ So, I used 'interleave' decomposition instead of it.
-+
-+ 1D Model:
-+ |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0
-+ |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1
-+
-+ In this method, H/L and X0/X1 is always same position.
-+ This lead us to more speed and less memory.
-+ Of cause, the result of both method is quite same
-+ because it's only difference that coefficient position.
-+*/
-+static InlineX void WaveletLevel(int* data, int size, int l, int SkipPixel)
-+{
-+ int s, ofs;
-+ signed char* pX0;
-+ signed char* end;
-+
-+ pX0 = (signed char*)data;
-+ s = (8<<l)*SkipPixel;
-+ end = pX0+(size>>(l+1))*s;
-+ s -= 2;
-+ ofs = (4<<l)*SkipPixel;
-+ while (pX0 < end) {
-+ Harr(pX0, pX0+ofs);
-+ pX0++;
-+ Harr(pX0, pX0+ofs);
-+ pX0++;
-+ Harr(pX0, pX0+ofs);
-+ pX0 += s;
-+ }
-+}
-+#define InvWaveletLevel(d,s,l,pix) WaveletLevel(d,s,l,pix)
-+
-+#ifdef ZYWRLE_ENCODE
-+# ifndef ZYWRLE_QUANTIZE
-+/* Type A:lower bit omitting of EZW style. */
-+static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l)
-+{
-+ int r, s;
-+ int x, y;
-+ int* pH;
-+ const unsigned int* pM;
-+
-+ pM = &(zywrleParam[level-1][l]);
-+ s = 2<<l;
-+ for (r = 1; r < 4; r++) {
-+ pH = pBuf;
-+ if (r & 0x01)
-+ pH += s>>1;
-+ if (r & 0x02)
-+ pH += (s>>1)*width;
-+ for (y = 0; y < height / s; y++) {
-+ for (x = 0; x < width / s; x++) {
-+ /*
-+ these are same following code.
-+ pH[x] = pH[x] / (~pM[x]+1) * (~pM[x]+1);
-+ ( round pH[x] with pM[x] bit )
-+ '&' operator isn't 'round' but is 'floor'.
-+ So, we must offset when pH[x] is negative.
-+ */
-+ if (((signed char*)pH)[0] & 0x80)
-+ ((signed char*)pH)[0] += ~((signed char*)pM)[0];
-+ if (((signed char*)pH)[1] & 0x80)
-+ ((signed char*)pH)[1] += ~((signed char*)pM)[1];
-+ if (((signed char*)pH)[2] & 0x80)
-+ ((signed char*)pH)[2] += ~((signed char*)pM)[2];
-+ *pH &= *pM;
-+ pH += s;
-+ }
-+ pH += (s-1)*width;
-+ }
-+ }
-+}
-+# else
-+/*
-+ Type B:Non liner quantization filter.
-+
-+ Coefficients have Gaussian curve and smaller value which is
-+ large part of coefficients isn't more important than larger value.
-+ So, I use filter of Non liner quantize/dequantize table.
-+ In general, Non liner quantize formula is explained as following.
-+
-+ y=f(x) = sign(x)*round( ((abs(x)/(2^7))^ r )* 2^(bo-1) )*2^(8-bo)
-+ x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi)
-+ ( r:power coefficient bi:effective MSB in input bo:effective MSB in output )
-+
-+ r < 1.0 : Smaller value is more important than larger value.
-+ r > 1.0 : Larger value is more important than smaller value.
-+ r = 1.0 : Liner quantization which is same with EZW style.
-+
-+ r = 0.75 is famous non liner quantization used in MP3 audio codec.
-+ In contrast to audio data, larger value is important in wavelet coefficients.
-+ So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ).
-+
-+ As compared with EZW style liner quantization, this filter tended to be
-+ more sharp edge and be more compression rate but be more blocking noise and be less quality.
-+ Especially, the surface of graphic objects has distinguishable noise in middle quality mode.
-+
-+ We need only quantized-dequantized(filtered) value rather than quantized value itself
-+ because all values are packed or palette-lized in later ZRLE section.
-+ This lead us not to need to modify client decoder when we change
-+ the filtering procedure in future.
-+ Client only decodes coefficients given by encoder.
-+*/
-+static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l)
-+{
-+ int r, s;
-+ int x, y;
-+ int* pH;
-+ const signed char** pM;
-+
-+ pM = zywrleParam[level-1][l];
-+ s = 2<<l;
-+ for (r = 1; r < 4; r++) {
-+ pH = pBuf;
-+ if (r & 0x01)
-+ pH += s>>1;
-+ if (r & 0x02)
-+ pH += (s>>1)*width;
-+ for (y = 0; y < height / s; y++) {
-+ for (x = 0; x < width / s; x++) {
-+ ((signed char*)pH)[0] = pM[0][((unsigned char*)pH)[0]];
-+ ((signed char*)pH)[1] = pM[1][((unsigned char*)pH)[1]];
-+ ((signed char*)pH)[2] = pM[2][((unsigned char*)pH)[2]];
-+ pH += s;
-+ }
-+ pH += (s-1)*width;
-+ }
-+ }
-+}
-+# endif
-+
-+static InlineX void Wavelet(int* pBuf, int width, int height, int level)
-+{
-+ int l, s;
-+ int* pTop;
-+ int* pEnd;
-+
-+ for (l = 0; l < level; l++) {
-+ pTop = pBuf;
-+ pEnd = pBuf+height*width;
-+ s = width<<l;
-+ while (pTop < pEnd) {
-+ WaveletLevel(pTop, width, l, 1);
-+ pTop += s;
-+ }
-+ pTop = pBuf;
-+ pEnd = pBuf+width;
-+ s = 1<<l;
-+ while (pTop < pEnd) {
-+ WaveletLevel(pTop, height,l, width);
-+ pTop += s;
-+ }
-+ FilterWaveletSquare(pBuf, width, height, level, l);
-+ }
-+}
-+#endif
-+#ifdef ZYWRLE_DECODE
-+static InlineX void InvWavelet(int* pBuf, int width, int height, int level)
-+{
-+ int l, s;
-+ int* pTop;
-+ int* pEnd;
-+
-+ for (l = level - 1; l >= 0; l--) {
-+ pTop = pBuf;
-+ pEnd = pBuf+width;
-+ s = 1<<l;
-+ while (pTop < pEnd) {
-+ InvWaveletLevel(pTop, height,l, width);
-+ pTop += s;
-+ }
-+ pTop = pBuf;
-+ pEnd = pBuf+height*width;
-+ s = width<<l;
-+ while (pTop < pEnd) {
-+ InvWaveletLevel(pTop, width, l, 1);
-+ pTop += s;
-+ }
-+ }
-+}
-+#endif
-+
-+/* Load/Save coefficients stuffs.
-+ Coefficients manages as 24 bits little-endian pixel. */
-+#define ZYWRLE_LOAD_COEFF(pSrc,R,G,B) { \
-+ R = ((signed char*)pSrc)[2]; \
-+ G = ((signed char*)pSrc)[1]; \
-+ B = ((signed char*)pSrc)[0]; \
-+}
-+#define ZYWRLE_SAVE_COEFF(pDst,R,G,B) { \
-+ ((signed char*)pDst)[2] = (signed char)R; \
-+ ((signed char*)pDst)[1] = (signed char)G; \
-+ ((signed char*)pDst)[0] = (signed char)B; \
-+}
-+
-+/*
-+ RGB <=> YUV conversion stuffs.
-+ YUV coversion is explained as following formula in strict meaning:
-+ Y = 0.299R + 0.587G + 0.114B ( 0<=Y<=255)
-+ U = -0.169R - 0.331G + 0.500B (-128<=U<=127)
-+ V = 0.500R - 0.419G - 0.081B (-128<=V<=127)
-+
-+ I use simple conversion RCT(reversible color transform) which is described
-+ in JPEG-2000 specification.
-+ Y = (R + 2G + B)/4 ( 0<=Y<=255)
-+ U = B-G (-256<=U<=255)
-+ V = R-G (-256<=V<=255)
-+*/
-+#define ROUND(x) (((x)<0)?0:(((x)>255)?255:(x)))
-+ /* RCT is N-bit RGB to N-bit Y and N+1-bit UV.
-+ For make Same N-bit, UV is lossy.
-+ More exact PLHarr, we reduce to odd range(-127<=x<=127). */
-+#define ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ymask,uvmask) { \
-+ Y = (R+(G<<1)+B)>>2; \
-+ U = B-G; \
-+ V = R-G; \
-+ Y -= 128; \
-+ U >>= 1; \
-+ V >>= 1; \
-+ Y &= ymask; \
-+ U &= uvmask; \
-+ V &= uvmask; \
-+ if (Y == -128) \
-+ Y += (0xFFFFFFFF-ymask+1); \
-+ if (U == -128) \
-+ U += (0xFFFFFFFF-uvmask+1); \
-+ if (V == -128) \
-+ V += (0xFFFFFFFF-uvmask+1); \
-+}
-+#define ZYWRLE_YUVRGB1(R,G,B,Y,U,V) { \
-+ Y += 128; \
-+ U <<= 1; \
-+ V <<= 1; \
-+ G = Y-((U+V)>>2); \
-+ B = U+G; \
-+ R = V+G; \
-+ G = ROUND(G); \
-+ B = ROUND(B); \
-+ R = ROUND(R); \
-+}
-+
-+/*
-+ coefficient packing/unpacking stuffs.
-+ Wavelet transform makes 4 sub coefficient image from 1 original image.
-+
-+ model with pyramid decomposition:
-+ +------+------+
-+ | | |
-+ | L | Hx |
-+ | | |
-+ +------+------+
-+ | | |
-+ | H | Hxy |
-+ | | |
-+ +------+------+
-+
-+ So, we must transfer each sub images individually in strict meaning.
-+ But at least ZRLE meaning, following one decompositon image is same as
-+ avobe individual sub image. I use this format.
-+ (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L)
-+ for simplified procedure for any wavelet level.)
-+
-+ +------+------+
-+ | L |
-+ +------+------+
-+ | Hx |
-+ +------+------+
-+ | Hy |
-+ +------+------+
-+ | Hxy |
-+ +------+------+
-+*/
-+#define INC_PTR(data) \
-+ data++; \
-+ if( data-pData >= (w+uw) ){ \
-+ data += scanline-(w+uw); \
-+ pData = data; \
-+ }
-+
-+#define ZYWRLE_TRANSFER_COEFF(pBuf,data,r,w,h,scanline,level,TRANS) \
-+ pH = pBuf; \
-+ s = 2<<level; \
-+ if (r & 0x01) \
-+ pH += s>>1; \
-+ if (r & 0x02) \
-+ pH += (s>>1)*w; \
-+ pEnd = pH+h*w; \
-+ while (pH < pEnd) { \
-+ pLine = pH+w; \
-+ while (pH < pLine) { \
-+ TRANS \
-+ INC_PTR(data) \
-+ pH += s; \
-+ } \
-+ pH += (s-1)*w; \
-+ }
-+
-+#define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,scanline,level) \
-+ ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_COEFF(pH,R,G,B);ZYWRLE_SAVE_PIXEL(data,R,G,B);)
-+
-+#define ZYWRLE_UNPACK_COEFF(pBuf,data,r,width,height,scanline,level) \
-+ ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_PIXEL(data,R,G,B);ZYWRLE_SAVE_COEFF(pH,R,G,B);)
-+
-+#define ZYWRLE_SAVE_UNALIGN(data,TRANS) \
-+ pTop = pBuf+w*h; \
-+ pEnd = pBuf + (w+uw)*(h+uh); \
-+ while (pTop < pEnd) { \
-+ TRANS \
-+ INC_PTR(data) \
-+ pTop++; \
-+ }
-+
-+#define ZYWRLE_LOAD_UNALIGN(data,TRANS) \
-+ pTop = pBuf+w*h; \
-+ if (uw) { \
-+ pData= data + w; \
-+ pEnd = (int*)(pData+ h*scanline); \
-+ while (pData < (PIXEL_T*)pEnd) { \
-+ pLine = (int*)(pData + uw); \
-+ while (pData < (PIXEL_T*)pLine) { \
-+ TRANS \
-+ pData++; \
-+ pTop++; \
-+ } \
-+ pData += scanline-uw; \
-+ } \
-+ } \
-+ if (uh) { \
-+ pData= data + h*scanline; \
-+ pEnd = (int*)(pData+ uh*scanline); \
-+ while (pData < (PIXEL_T*)pEnd) { \
-+ pLine = (int*)(pData + w); \
-+ while (pData < (PIXEL_T*)pLine) { \
-+ TRANS \
-+ pData++; \
-+ pTop++; \
-+ } \
-+ pData += scanline-w; \
-+ } \
-+ } \
-+ if (uw && uh) { \
-+ pData= data + w+ h*scanline; \
-+ pEnd = (int*)(pData+ uh*scanline); \
-+ while (pData < (PIXEL_T*)pEnd) { \
-+ pLine = (int*)(pData + uw); \
-+ while (pData < (PIXEL_T*)pLine) { \
-+ TRANS \
-+ pData++; \
-+ pTop++; \
-+ } \
-+ pData += scanline-uw; \
-+ } \
-+ }
-+
-+static InlineX void zywrleCalcSize(int* pW, int* pH, int level)
-+{
-+ *pW &= ~((1<<level)-1);
-+ *pH &= ~((1<<level)-1);
-+}
-+
-+#endif /* ZYWRLE_ONCE */
-+
-+#ifndef CPIXEL
-+#ifdef ZYWRLE_ENCODE
-+static InlineX void ZYWRLE_RGBYUV(int* pBuf, PIXEL_T* data, int width, int height, int scanline)
-+{
-+ int R, G, B;
-+ int Y, U, V;
-+ int* pLine;
-+ int* pEnd;
-+ pEnd = pBuf+height*width;
-+ while (pBuf < pEnd) {
-+ pLine = pBuf+width;
-+ while (pBuf < pLine) {
-+ ZYWRLE_LOAD_PIXEL(data,R,G,B);
-+ ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ZYWRLE_YMASK,ZYWRLE_UVMASK);
-+ ZYWRLE_SAVE_COEFF(pBuf,V,Y,U);
-+ pBuf++;
-+ data++;
-+ }
-+ data += scanline-width;
-+ }
-+}
-+#endif
-+#ifdef ZYWRLE_DECODE
-+static InlineX void ZYWRLE_YUVRGB(int* pBuf, PIXEL_T* data, int width, int height, int scanline) {
-+ int R, G, B;
-+ int Y, U, V;
-+ int* pLine;
-+ int* pEnd;
-+ pEnd = pBuf+height*width;
-+ while (pBuf < pEnd) {
-+ pLine = pBuf+width;
-+ while (pBuf < pLine) {
-+ ZYWRLE_LOAD_COEFF(pBuf,V,Y,U);
-+ ZYWRLE_YUVRGB1(R,G,B,Y,U,V);
-+ ZYWRLE_SAVE_PIXEL(data,R,G,B);
-+ pBuf++;
-+ data++;
-+ }
-+ data += scanline-width;
-+ }
-+}
-+#endif
-+
-+#ifdef ZYWRLE_ENCODE
-+PIXEL_T* ZYWRLE_ANALYZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf) {
-+ int l;
-+ int uw = w;
-+ int uh = h;
-+ int* pTop;
-+ int* pEnd;
-+ int* pLine;
-+ PIXEL_T* pData;
-+ int R, G, B;
-+ int s;
-+ int* pH;
-+
-+ zywrleCalcSize(&w, &h, level);
-+ if (w == 0 || h == 0)
-+ return NULL;
-+ uw -= w;
-+ uh -= h;
-+
-+ pData = dst;
-+ ZYWRLE_LOAD_UNALIGN(src,*(PIXEL_T*)pTop=*pData;)
-+ ZYWRLE_RGBYUV(pBuf, src, w, h, scanline);
-+ Wavelet(pBuf, w, h, level);
-+ for (l = 0; l < level; l++) {
-+ ZYWRLE_PACK_COEFF(pBuf, dst, 3, w, h, scanline, l);
-+ ZYWRLE_PACK_COEFF(pBuf, dst, 2, w, h, scanline, l);
-+ ZYWRLE_PACK_COEFF(pBuf, dst, 1, w, h, scanline, l);
-+ if (l == level - 1) {
-+ ZYWRLE_PACK_COEFF(pBuf, dst, 0, w, h, scanline, l);
-+ }
-+ }
-+ ZYWRLE_SAVE_UNALIGN(dst,*dst=*(PIXEL_T*)pTop;)
-+ return dst;
-+}
-+#endif
-+#ifdef ZYWRLE_DECODE
-+PIXEL_T* ZYWRLE_SYNTHESIZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf)
-+{
-+ int l;
-+ int uw = w;
-+ int uh = h;
-+ int* pTop;
-+ int* pEnd;
-+ int* pLine;
-+ PIXEL_T* pData;
-+ int R, G, B;
-+ int s;
-+ int* pH;
-+
-+ zywrleCalcSize(&w, &h, level);
-+ if (w == 0 || h == 0)
-+ return NULL;
-+ uw -= w;
-+ uh -= h;
-+
-+ pData = src;
-+ for (l = 0; l < level; l++) {
-+ ZYWRLE_UNPACK_COEFF(pBuf, src, 3, w, h, scanline, l);
-+ ZYWRLE_UNPACK_COEFF(pBuf, src, 2, w, h, scanline, l);
-+ ZYWRLE_UNPACK_COEFF(pBuf, src, 1, w, h, scanline, l);
-+ if (l == level - 1) {
-+ ZYWRLE_UNPACK_COEFF(pBuf, src, 0, w, h, scanline, l);
-+ }
-+ }
-+ ZYWRLE_SAVE_UNALIGN(src,*(PIXEL_T*)pTop=*src;)
-+ InvWavelet(pBuf, w, h, level);
-+ ZYWRLE_YUVRGB(pBuf, dst, w, h, scanline);
-+ ZYWRLE_LOAD_UNALIGN(dst,*pData=*(PIXEL_T*)pTop;)
-+ return src;
-+}
-+#endif
-+#endif /* CPIXEL */
-+
-+#undef ZYWRLE_RGBYUV
-+#undef ZYWRLE_YUVRGB
-+#undef ZYWRLE_LOAD_PIXEL
-+#undef ZYWRLE_SAVE_PIXEL
-diff -Naur -X ./exclude vnc_unixsrc.orig/include/rfbproto.h vnc_unixsrc/include/rfbproto.h
---- vnc_unixsrc.orig/include/rfbproto.h 2004-05-27 03:02:02.000000000 -0400
-+++ vnc_unixsrc/include/rfbproto.h 2010-02-25 21:54:58.000000000 -0500
-@@ -205,7 +205,22 @@
- #define rfbSecTypeInvalid 0
- #define rfbSecTypeNone 1
- #define rfbSecTypeVncAuth 2
-+#define rfbSecTypeRA2 5
-+#define rfbSecTypeRA2ne 6
- #define rfbSecTypeTight 16
-+#define rfbSecTypeUltra 17
-+
-+/* try to support VeNCrypt and TLS */
-+#define rfbSecTypeAnonTls 18
-+#define rfbSecTypeVencrypt 19
-+
-+#define rfbVencryptPlain 256
-+#define rfbVencryptTlsNone 257
-+#define rfbVencryptTlsVnc 258
-+#define rfbVencryptTlsPlain 259
-+#define rfbVencryptX509None 260
-+#define rfbVencryptX509Vnc 261
-+#define rfbVencryptX509Plain 262
-
-
- /*-----------------------------------------------------------------------------
-@@ -381,6 +396,11 @@
- #define rfbBell 2
- #define rfbServerCutText 3
-
-+#define rfbResizeFrameBuffer 4 /* Modif sf@2002 */
-+
-+/* http://sourceforge.net/projects/vncsessmgr */
-+#define rfbRestartConnection 82
-+
- #define rfbFileListData 130
- #define rfbFileDownloadData 131
- #define rfbFileUploadCancel 132
-@@ -403,6 +423,18 @@
- #define rfbPointerEvent 5
- #define rfbClientCutText 6
-
-+/* ultra */
-+
-+#define rfbFileTransfer 7
-+#define rfbSetScale 8
-+#define rfbSetServerInput 9
-+#define rfbSetSW 10
-+#define rfbTextChat 11
-+#define rfbKeyFrameRequest 12
-+#define rfbPalmVNCSetScaleFactor 0xF
-+
-+
-+
- #define rfbFileListRequest 130
- #define rfbFileDownloadRequest 131
- #define rfbFileUploadRequest 132
-@@ -435,6 +467,13 @@
- #define rfbEncodingTight 7
- #define rfbEncodingZlibHex 8
-
-+#define rfbEncodingZRLE 16
-+/*
-+nyama/2006/08/02:new YUV-Wavlet lossy codec based on ZRLE (ZYWRLE)
-+ */
-+#define rfbEncodingZYWRLE 17
-+
-+
- /* signatures for basic encoding types */
- #define sig_rfbEncodingRaw "RAW_____"
- #define sig_rfbEncodingCopyRect "COPYRECT"
-@@ -955,6 +994,51 @@
- #define sz_rfbFileDownloadFailedMsg 4
-
- /*-----------------------------------------------------------------------------
-+ * RestartConnection - the server has restarted the client connection.
-+ */
-+
-+typedef struct _rfbRestartConnectionMsg {
-+ CARD8 type; /* always rfbRestartConnection */
-+ CARD8 pad1;
-+ CARD16 pad2;
-+ CARD32 length;
-+ /* followed by char text[length] */
-+} rfbRestartConnectionMsg;
-+
-+#define sz_rfbRestartConnectionMsg 8
-+
-+
-+typedef struct _rfbTextChatMsg {
-+ CARD8 type; /* always rfbTextChat */
-+ CARD8 pad1; /* Could be used later as an additionnal param */
-+ CARD16 pad2; /* Could be used later as text offset, for instance */
-+ CARD32 length; /* Specific values for Open, close, finished (-1, -2, -3) */
-+ /* followed by char text[length] */
-+} rfbTextChatMsg;
-+
-+#define sz_rfbTextChatMsg 8
-+
-+#define rfbTextMaxSize 4096
-+#define rfbTextChatOpen 0xFFFFFFFF
-+#define rfbTextChatClose 0xFFFFFFFE
-+#define rfbTextChatFinished 0xFFFFFFFD
-+
-+/*-----------------------------------------------------------------------------
-+ * Modif sf@2002
-+ * ResizeFrameBuffer - The Client must change the size of its framebuffer
-+ */
-+
-+typedef struct _rfbResizeFrameBufferMsg {
-+ CARD8 type; /* always rfbResizeFrameBuffer */
-+ CARD8 pad1;
-+ CARD16 framebufferWidth; /* FrameBuffer width */
-+ CARD16 framebufferHeight; /* FrameBuffer height */
-+} rfbResizeFrameBufferMsg;
-+
-+#define sz_rfbResizeFrameBufferMsg 6
-+
-+
-+/*-----------------------------------------------------------------------------
- * Union of all server->client messages.
- */
-
-@@ -968,6 +1052,8 @@
- rfbFileDownloadDataMsg fdd;
- rfbFileUploadCancelMsg fuc;
- rfbFileDownloadFailedMsg fdf;
-+ rfbRestartConnectionMsg rc;
-+ rfbTextChatMsg tc;
- } rfbServerToClientMsg;
-
-
-@@ -1221,6 +1307,41 @@
-
- #define sz_rfbFileCreateDirRequestMsg 4
-
-+/* ultra */
-+typedef struct _rfbSetScaleMsg {
-+ CARD8 type; /* always rfbSetScale */
-+ CARD8 scale; /* Scale value 1<sv<n */
-+ CARD16 pad;
-+} rfbSetScaleMsg;
-+
-+#define sz_rfbSetScaleMsg 4
-+
-+typedef struct {
-+ CARD8 type; /* always rfbSetScaleFactor */
-+
-+ CARD8 scale; /* Scale factor (positive non-zero integer) */
-+ CARD16 pad2;
-+} rfbPalmVNCSetScaleFactorMsg;
-+
-+#define sz_rfbPalmVNCSetScaleFactorMsg (4)
-+
-+typedef struct _rfbSetServerInputMsg {
-+ CARD8 type; /* always rfbSetServerInputMsg */
-+ CARD8 status; /* on or off */
-+ CARD16 pad;
-+} rfbSetServerInputMsg;
-+
-+#define sz_rfbSetServerInputMsg 4
-+
-+typedef struct _rfbSetSWMsg {
-+ CARD8 type; /* always rfbSetSW */
-+ CARD8 status;
-+ CARD16 x;
-+ CARD16 y;
-+} rfbSetSWMsg;
-+
-+#define sz_rfbSetSWMsg 6
-+
- /*-----------------------------------------------------------------------------
- * Union of all client->server messages.
- */
-@@ -1241,4 +1362,9 @@
- rfbFileDownloadCancelMsg fdc;
- rfbFileUploadFailedMsg fuf;
- rfbFileCreateDirRequestMsg fcdr;
-+ rfbSetScaleMsg ssc;
-+ rfbPalmVNCSetScaleFactorMsg pssf;
-+ rfbSetServerInputMsg sim;
-+ rfbSetSWMsg sw;
-+ rfbTextChatMsg tc;
- } rfbClientToServerMsg;
-diff -Naur -X ./exclude vnc_unixsrc.orig/include/vncauth.h vnc_unixsrc/include/vncauth.h
---- vnc_unixsrc.orig/include/vncauth.h 2000-06-11 08:00:53.000000000 -0400
-+++ vnc_unixsrc/include/vncauth.h 2009-03-21 00:37:23.000000000 -0400
-@@ -23,8 +23,11 @@
-
- #define MAXPWLEN 8
- #define CHALLENGESIZE 16
-+#define CHALLENGESIZE_MSLOGON 64
-
- extern int vncEncryptAndStorePasswd(char *passwd, char *fname);
- extern char *vncDecryptPasswdFromFile(char *fname);
- extern void vncRandomBytes(unsigned char *bytes);
- extern void vncEncryptBytes(unsigned char *bytes, char *passwd);
-+
-+extern void vncEncryptPasswd_MSLOGON(unsigned char *encryptedPasswd, char *passwd);
-diff -Naur -X ./exclude vnc_unixsrc.orig/libvncauth/d3des.c vnc_unixsrc/libvncauth/d3des.c
---- vnc_unixsrc.orig/libvncauth/d3des.c 2000-06-11 08:00:53.000000000 -0400
-+++ vnc_unixsrc/libvncauth/d3des.c 2010-02-25 21:49:02.000000000 -0500
-@@ -34,12 +34,15 @@
- static void cookey(unsigned long *);
-
- static unsigned long KnL[32] = { 0L };
-+/* no londer used: */
-+#if 0
- static unsigned long KnR[32] = { 0L };
- static unsigned long Kn3[32] = { 0L };
- static unsigned char Df_Key[24] = {
- 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
- 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
- 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
-+#endif
-
- static unsigned short bytebit[8] = {
- 01, 02, 04, 010, 020, 040, 0100, 0200 };
-diff -Naur -X ./exclude vnc_unixsrc.orig/libvncauth/vncauth.c vnc_unixsrc/libvncauth/vncauth.c
---- vnc_unixsrc.orig/libvncauth/vncauth.c 2003-03-01 11:48:06.000000000 -0500
-+++ vnc_unixsrc/libvncauth/vncauth.c 2010-02-25 21:47:25.000000000 -0500
-@@ -27,9 +27,11 @@
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
-+#include <time.h>
- #include <vncauth.h>
- #include <d3des.h>
-
-+#include <fcntl.h>
-
- /*
- * Make sure we call srandom() only once.
-@@ -45,6 +47,8 @@
-
- static unsigned char s_fixedkey[8] = {23,82,107,6,35,78,88,7};
-
-+int vncEncryptAndStorePasswd2(char *passwd, char *passwdViewOnly, char *fname);
-+int vncDecryptPasswdFromFile2(char *fname, char *passwdFullControl, char *passwdViewOnly);
-
- /*
- * Encrypt a password and store it in a file. Returns 0 if successful,
-@@ -73,7 +77,7 @@
- vncEncryptAndStorePasswd2(char *passwd, char *passwdViewOnly, char *fname)
- {
- FILE *fp;
-- int i, bytesToWrite, bytesWrote;
-+ int bytesToWrite, bytesWrote;
- unsigned char encryptedPasswd[16] = {
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0
-@@ -195,6 +199,44 @@
- return (i < 16) ? 1 : 2;
- }
-
-+unsigned int urandom(void) {
-+ unsigned int val = 0;
-+ struct stat sb;
-+ int fd = -1;
-+ if (fd < 0 && stat("/dev/urandom", &sb) == 0) {
-+ fd = open("/dev/urandom", O_RDONLY);
-+ }
-+ if (fd < 0 && stat("/dev/random", &sb) == 0) {
-+ fd = open("/dev/random", O_RDONLY);
-+ }
-+ if (fd < 0 && stat("/proc/loadavg", &sb) == 0) {
-+ fd = open("/proc/loadavg", O_RDONLY);
-+ }
-+ if (fd < 0 && stat("/bin/bash", &sb) == 0) {
-+ fd = open("/bin/bash", O_RDONLY);
-+ lseek(fd, (off_t) (unsigned int) getpid(), SEEK_SET);
-+ }
-+ if (fd >= 0) {
-+ int i;
-+ for (i=0; i < 3; i++) {
-+ char buf[2];
-+ if (read(fd, buf, 1) > 0) {
-+ unsigned char uc = (unsigned char) buf[0];
-+ if (i==0) {
-+ val += uc;
-+ } else if (i==1) {
-+ val += uc * 256;
-+ } else if (i==2) {
-+ val += uc * 256 * 256;
-+ }
-+ }
-+ }
-+ close(fd);
-+ } else {
-+ val = (unsigned int) getpid();
-+ }
-+ return val;
-+}
-
- /*
- * Generate CHALLENGESIZE random bytes for use in challenge-response
-@@ -207,11 +249,13 @@
- int i;
- unsigned int seed;
-
-- if (!s_srandom_called) {
-- seed = (unsigned int)time(0) ^ (unsigned int)getpid();
-- srandom(seed);
-- s_srandom_called = 1;
-- }
-+ if (!s_srandom_called) {
-+ seed = (unsigned int)time(0) ^ (unsigned int)getpid();
-+ seed += urandom();
-+
-+ srandom(seed);
-+ s_srandom_called = 1;
-+ }
-
- for (i = 0; i < CHALLENGESIZE; i++) {
- bytes[i] = (unsigned char)(random() & 255);
-@@ -245,3 +289,48 @@
- des(bytes+i, bytes+i);
- }
- }
-+
-+void UvncEncryptPasswd_MSLOGON(unsigned char *encryptedPasswd, char *passwd) {
-+ unsigned int i;
-+ for (i=0; i < 32; i++) {
-+ if (i < strlen(passwd)) {
-+ encryptedPasswd[i] = passwd[i];
-+ } else {
-+ encryptedPasswd[i] = '\0';
-+ }
-+ }
-+ deskey(s_fixedkey, EN0);
-+ des(encryptedPasswd, encryptedPasswd);
-+}
-+
-+void UvncEncryptBytes2(unsigned char *where, int length, unsigned char *key) {
-+ int i, j;
-+ deskey(key, EN0);
-+ for (i=0; i < 8; i++) {
-+ where[i] ^= key[i];
-+ }
-+ des(where, where);
-+ for (i=8; i < length; i += 8) {
-+ for (j=0; j < 8; j++) {
-+ where[i+j] ^= where[i+j-8];
-+ }
-+ des(where+i, where+i);
-+ }
-+}
-+
-+void UvncDecryptBytes2(unsigned char *where, int length, unsigned char *key) {
-+ int i, j;
-+ deskey(key, DE1);
-+ for (i = length - 8; i > 0; i -= 8) {
-+ des(where + i, where + i);
-+ for (j=0; j < 8; j++) {
-+ where[i+j] ^= where[i+j-8];
-+ }
-+ }
-+ /* i=0 */
-+ des(where, where);
-+ for (i=0; i < 8; i++) {
-+ where[i] ^= key[i];
-+ }
-+}
-+
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fullscreen.patch b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fullscreen.patch
deleted file mode 100644
index 97494ee..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fullscreen.patch
+++ /dev/null
@@ -1,42 +0,0 @@
---- vnc_unixsrc.orig/vncviewer/fullscreen.c 2003-10-09 05:23:49.000000000 -0400
-+++ vnc_unixsrc/vncviewer/fullscreen.c 2004-12-26 21:21:44.000000000 -0500
-@@ -173,9 +173,15 @@
- XtVaSetValues(popup, XtNoverrideRedirect, True, NULL);
-
- /* Try to get the input focus. */
--
-+
-+#if 0
- XSetInputFocus(dpy, DefaultRootWindow(dpy), RevertToPointerRoot,
- CurrentTime);
-+#else
-+ XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot,
-+ CurrentTime);
-+#endif
-+
-
- /* Optionally, grab the keyboard. */
-
-@@ -184,6 +190,10 @@
- GrabModeAsync, CurrentTime) != GrabSuccess) {
- fprintf(stderr, "XtGrabKeyboard() failed.\n");
- }
-+if (getenv("VNCVIEWER_GRAB_SERVER") != NULL) { /* runge bot of FullScreenOn */
-+ fprintf(stderr, "calling XGrabServer(dpy)\n");
-+ XGrabServer(dpy);
-+}
- }
-
-
-@@ -210,6 +220,11 @@
-
- appData.fullScreen = False;
-
-+if (getenv("VNCVIEWER_GRAB_SERVER") != NULL) { /* runge top of FullScreenOff */
-+ fprintf(stderr, "calling XUngrabServer(dpy)\n");
-+ XUngrabServer(dpy);
-+}
-+
- if (appData.grabKeyboard)
- XtUngrabKeyboard(desktop, CurrentTime);
-
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-newfbsize.patch b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-newfbsize.patch
deleted file mode 100644
index 9e2c811..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-newfbsize.patch
+++ /dev/null
@@ -1,286 +0,0 @@
---- vnc_unixsrc.orig/vncviewer/desktop.c 2004-05-28 13:29:29.000000000 -0400
-+++ vnc_unixsrc/vncviewer/desktop.c 2007-01-13 13:59:51.000000000 -0500
-@@ -50,6 +50,30 @@
- },
- };
-
-+void create_image() {
-+ image = NULL;
-+
-+#ifdef MITSHM
-+ if (appData.useShm) {
-+ image = CreateShmImage();
-+ if (!image)
-+ appData.useShm = False;
-+ }
-+#endif
-+
-+ if (!image) {
-+ image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
-+ si.framebufferWidth, si.framebufferHeight,
-+ BitmapPad(dpy), 0);
-+
-+ image->data = malloc(image->bytes_per_line * image->height);
-+ if (!image->data) {
-+ fprintf(stderr,"malloc failed\n");
-+ exit(1);
-+ }
-+ }
-+}
-+
-
- /*
- * DesktopInitBeforeRealization creates the "desktop" widget and the viewport
-@@ -82,30 +106,9 @@
- for (i = 0; i < 256; i++)
- modifierPressed[i] = False;
-
-- image = NULL;
--
--#ifdef MITSHM
-- if (appData.useShm) {
-- image = CreateShmImage();
-- if (!image)
-- appData.useShm = False;
-- }
--#endif
--
-- if (!image) {
-- image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
-- si.framebufferWidth, si.framebufferHeight,
-- BitmapPad(dpy), 0);
--
-- image->data = malloc(image->bytes_per_line * image->height);
-- if (!image->data) {
-- fprintf(stderr,"malloc failed\n");
-- exit(1);
-- }
-- }
-+ create_image();
- }
-
--
- /*
- * DesktopInitAfterRealization does things which require the X windows to
- * exist. It creates some GCs and sets the dot cursor.
-@@ -460,3 +463,70 @@
- break;
- }
- }
-+
-+static void reset_image(void) {
-+ if (UsingShm()) {
-+ ShmCleanup();
-+ } else {
-+ if (image && image->data) {
-+ free(image->data);
-+ /* see manpage XDestroyImage may also free data, so we skip and have a tiny leak instead */
-+ if (0) XDestroyImage(image);
-+ image = NULL;
-+ }
-+ }
-+ create_image();
-+ XFlush(dpy);
-+}
-+
-+void ReDoDesktop(void) {
-+ int w, h, x, y, dw, dh;
-+
-+ if (appData.fullScreen) {
-+ if (image && image->data) {
-+ int len;
-+ int h = image->height;
-+ int w = image->width;
-+ len = image->bytes_per_line * image->height;
-+ /* black out window first: */
-+ memset(image->data, 0, len);
-+ XPutImage(dpy, XtWindow(desktop), gc, image, 0, 0, 0, 0, w, h);
-+ XFlush(dpy);
-+ }
-+ XtResizeWidget(desktop, si.framebufferWidth, si.framebufferHeight, 0);
-+ XSync(dpy, False);
-+ usleep(100*1000);
-+ FullScreenOn();
-+ XSync(dpy, False);
-+ usleep(100*1000);
-+ reset_image();
-+ return;
-+ }
-+
-+ dw = appData.wmDecorationWidth;
-+ dh = appData.wmDecorationHeight;
-+
-+ w = si.framebufferWidth;
-+ h = si.framebufferHeight;
-+
-+ if (w + dw >= dpyWidth) {
-+ w = dpyWidth - dw;
-+ }
-+ if (h + dh >= dpyHeight) {
-+ h = dpyHeight - dh;
-+ }
-+
-+ XtVaSetValues(toplevel, XtNmaxWidth, w, XtNmaxHeight, h, NULL);
-+
-+ XtVaSetValues(desktop, XtNwidth, si.framebufferWidth,
-+ XtNheight, si.framebufferHeight, NULL);
-+
-+ x = (dpyWidth - w - dw)/2;
-+ y = (dpyHeight - h - dh)/2;
-+
-+ XtResizeWidget(desktop, si.framebufferWidth, si.framebufferHeight, 0);
-+
-+ XtConfigureWidget(toplevel, x + dw, y + dh, w, h, 0);
-+
-+ reset_image();
-+}
---- vnc_unixsrc.orig/vncviewer/fullscreen.c 2003-10-09 05:23:49.000000000 -0400
-+++ vnc_unixsrc/vncviewer/fullscreen.c 2006-07-27 14:36:06.000000000 -0400
-@@ -85,10 +85,13 @@
- Dimension oldViewportWidth, oldViewportHeight, clipWidth, clipHeight;
- Position viewportX, viewportY;
-
-+ Bool fsAlready = appData.fullScreen, toobig = False;
-+
- appData.fullScreen = True;
-
- if (si.framebufferWidth > dpyWidth || si.framebufferHeight > dpyHeight) {
-
-+ toobig = True;
- XtVaSetValues(viewport, XtNforceBars, True, NULL);
- XtVaGetValues(viewport, XtNwidth, &oldViewportWidth,
- XtNheight, &oldViewportHeight, NULL);
-@@ -129,6 +132,7 @@
- reparenting our window to the root. The window manager will get a
- ReparentNotify and hopefully clean up its frame window. */
-
-+if (! fsAlready) {
- XtVaSetValues(toplevel, XtNoverrideRedirect, True, NULL);
-
- XReparentWindow(dpy, XtWindow(toplevel), DefaultRootWindow(dpy), 0, 0);
-@@ -164,10 +168,22 @@
-
- XtManageChild(viewport);
-
-- /* Now we can set "toplevel" to its proper size. */
-+} else {
-+ XSync(dpy, False);
-+}
-
-+ /* Now we can set "toplevel" to its proper size. */
- XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0);
-
-+if (fsAlready) {
-+ XtResizeWidget(viewport, viewportWidth, viewportHeight, 0);
-+ if (! toobig) {
-+ XtVaSetValues(viewport, XtNforceBars, False, NULL);
-+ }
-+ XMoveWindow(dpy, XtWindow(viewport), viewportX, viewportY);
-+ XSync(dpy, False);
-+}
-+
- /* Set the popup to overrideRedirect too */
-
- XtVaSetValues(popup, XtNoverrideRedirect, True, NULL);
---- vnc_unixsrc.orig/vncviewer/rfbproto.c 2004-03-11 13:14:39.000000000 -0500
-+++ vnc_unixsrc/vncviewer/rfbproto.c 2006-07-25 21:51:20.000000000 -0400
-@@ -177,6 +177,9 @@
- sig_rfbEncodingPointerPos, "Pointer position update");
- CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor,
- sig_rfbEncodingLastRect, "LastRect protocol extension");
-+
-+ CapsAdd(encodingCaps, rfbEncodingNewFBSize, rfbTightVncVendor,
-+ sig_rfbEncodingNewFBSize, "New FB size protocol extension");
- }
-
-
-@@ -729,6 +732,7 @@
- Bool requestCompressLevel = False;
- Bool requestQualityLevel = False;
- Bool requestLastRectEncoding = False;
-+ Bool requestNewFBSizeEncoding = True;
-
- spf.type = rfbSetPixelFormat;
- spf.format = myFormat;
-@@ -806,6 +810,10 @@
- if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
- }
-+
-+ if (se->nEncodings < MAX_ENCODINGS && requestNewFBSizeEncoding) {
-+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize);
-+ }
- }
- else {
- if (SameMachine(rfbsock)) {
-@@ -849,6 +857,7 @@
- }
-
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
-+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize);
- }
-
- len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
-@@ -1038,6 +1047,16 @@
- }
- continue;
- }
-+ if (rect.encoding == rfbEncodingNewFBSize) {
-+ fprintf(stderr,"New Size: %dx%d at (%d, %d)\n",
-+ rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-+ si.framebufferWidth = rect.r.w;
-+ si.framebufferHeight = rect.r.h;
-+ fprintf(stderr, "si: %d %d\n", si.framebufferWidth, si.framebufferHeight);
-+ ReDoDesktop();
-+
-+ continue;
-+ }
-
- if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
- (rect.r.y + rect.r.h > si.framebufferHeight))
---- vnc_unixsrc.orig/vncviewer/shm.c 2000-06-11 08:00:53.000000000 -0400
-+++ vnc_unixsrc/vncviewer/shm.c 2006-07-26 23:30:42.000000000 -0400
-@@ -41,6 +41,10 @@
- }
- }
-
-+Bool UsingShm() {
-+ return needShmCleanup;
-+}
-+
- static int
- ShmCreationXErrorHandler(Display *dpy, XErrorEvent *error)
- {
---- vnc_unixsrc.orig/vncviewer/vncviewer.h 2004-03-11 13:14:40.000000000 -0500
-+++ vnc_unixsrc/vncviewer/vncviewer.h 2006-07-26 23:31:25.000000000 -0400
-@@ -162,6 +162,8 @@
- extern void CopyDataToScreen(char *buf, int x, int y, int width, int height);
- extern void SynchroniseScreen();
-
-+extern void ReDoDesktop();
-+
- /* dialogs.c */
-
- extern void ServerDialogDone(Widget w, XEvent *event, String *params,
-@@ -243,6 +245,7 @@
-
- extern XImage *CreateShmImage();
- extern void ShmCleanup();
-+extern Bool UsingShm();
-
- /* sockets.c */
-
---- vnc_unixsrc.orig/vncviewer/vncviewer.c 2004-01-13 09:22:05.000000000 -0500
-+++ vnc_unixsrc/vncviewer/vncviewer.c 2006-07-27 19:00:25.000000000 -0400
-@@ -57,6 +57,11 @@
- }
- }
-
-+ if (argc > 1 && strstr(argv[1], "-h") == argv[1]) {
-+ usage();
-+ return 0;
-+ }
-+
- /* Call the main Xt initialisation function. It parses command-line options,
- generating appropriate resource specs, and makes a connection to the X
- display. */
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README b/x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README
deleted file mode 100644
index a211377..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README
+++ /dev/null
@@ -1,16 +0,0 @@
-This is where we keep the 3rd party source zip and tar.gz files used
-to build this package.
-
-www.stunnel.org source 488512 Jul 25 15:09 stunnel-4.14.tar.gz
-http://stunnel.mirt.net
-www.tightvnc.com source 2182134 Jul 25 15:11 tightvnc-1.3dev7_unixsrc.tar.gz
-www.tightvnc.com windows
- standalone viewer binary: 209149 Jul 25 15:10 tightvnc-1.3dev7_x86_viewer.zip
-
-To save space they may not be included in the package you downloaded.
-The should be included in the "ssvnc_all-<version>.zip" file.
-Go to the websites indicated above or contact me if you cannot find them.
-
-The stunnel.patched.tar vnc_unixsrc_vncviewer.patched.tar
-files are tarballs of the original sources above with patches applied
-(used by build.unix script when patching fails).
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/ssvnc.desktop b/x11vnc/misc/enhanced_tightvnc_viewer/ssvnc.desktop
deleted file mode 100644
index 2ff26b6..0000000
--- a/x11vnc/misc/enhanced_tightvnc_viewer/ssvnc.desktop
+++ /dev/null
@@ -1,11 +0,0 @@
-[Desktop Entry]
-# Copy this file to "/usr/shared/applications/ssvnc.desktop" then SSVNC will
-# appear in desktop menus (once they are updated; e.g. update-menus command).
-Name=SSL/SSH VNC Viewer
-Comment=SSVNC - access remote VNC desktops
-Exec=ssvnc -noenc
-Icon=computer
-Terminal=false
-Type=Application
-StartupWMClass=Ssvnc.tcl
-Categories=Network;RemoteAccess;
diff --git a/x11vnc/misc/inet6to4 b/x11vnc/misc/inet6to4
deleted file mode 100755
index 0067a99..0000000
--- a/x11vnc/misc/inet6to4
+++ /dev/null
@@ -1,420 +0,0 @@
-#!/usr/bin/perl
-#
-# inet6to4: Act as an ipv6-to-ipv4 relay for tcp applications that
-# do not support ipv6.
-#
-# Usage: inet6to4 <ipv6-listen-port> <ipv4-host:port>
-# inet6to4 -r <ipv4-listen-port> <ipv6-host:port>
-#
-# Examples: inet6to4 5900 localhost:5900
-# inet6to4 8080 web1:80
-# inet6to4 -r 5900 fe80::217:f2ff:fee6:6f5a%eth0:5900
-#
-# The -r option reverses the direction of translation (e.g. for ipv4
-# clients that need to connect to ipv6 servers.) Reversing is the default
-# if this script is named 'inet4to6' (e.g. by a symlink.)
-#
-# Use Ctrl-C to stop this program. You can also supply '-c n' as the
-# first option to only handle that many connections.
-#
-# Also set the env. vars INET6TO4_LOOP=1 or INET6TO4_LOOP=BG
-# to have an outer loop restarting this program (BG means do that
-# in the background), and INET6TO4_LOGFILE for a log file.
-# Also set INET6TO4_VERBOSE to verbosity level and INET6TO4_WAITTIME
-# and INET6TO4_PIDFILE (see below.)
-#
-
-#-------------------------------------------------------------------------
-# Copyright (c) 2010 by Karl J. Runge <runge@karlrunge.com>
-#
-# inet6to4 is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# inet6to4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with inet6to4; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-# or see <http://www.gnu.org/licenses/>.
-#-------------------------------------------------------------------------
-
-my $program = "inet6to4";
-
-# Set up logging:
-#
-if (exists $ENV{INET6TO4_LOGFILE}) {
- close STDOUT;
- if (!open(STDOUT, ">>$ENV{INET6TO4_LOGFILE}")) {
- die "$program: $ENV{INET6TO4_LOGFILE} $!\n";
- }
- close STDERR;
- open(STDERR, ">&STDOUT");
-}
-select(STDERR); $| = 1;
-select(STDOUT); $| = 1;
-
-# interrupt handler:
-#
-my $looppid = '';
-my $pidfile = '';
-my $listen_sock = ''; # declared here for get_out()
-#
-sub get_out {
- print STDERR "$_[0]:\t$$ looppid=$looppid\n";
- close $listen_sock if $listen_sock;
- if ($looppid) {
- kill 'TERM', $looppid;
- fsleep(0.2);
- }
- unlink $pidfile if $pidfile;
- exit 0;
-}
-$SIG{INT} = \&get_out;
-$SIG{TERM} = \&get_out;
-
-# pidfile:
-#
-sub open_pidfile {
- if (exists $ENV{INET6TO4_PIDFILE}) {
- my $pf = $ENV{INET6TO4_PIDFILE};
- if (open(PID, ">$pf")) {
- print PID "$$\n";
- close PID;
- $pidfile = $pf;
- } else {
- print STDERR "could not open pidfile: $pf - $! - continuing...\n";
- }
- delete $ENV{INET6TO4_PIDFILE};
- }
-}
-
-####################################################################
-# Set INET6TO4_LOOP=1 to have this script create an outer loop
-# restarting itself if it ever exits. Set INET6TO4_LOOP=BG to
-# do this in the background as a daemon.
-
-if (exists $ENV{INET6TO4_LOOP}) {
- my $csl = $ENV{INET6TO4_LOOP};
- if ($csl ne 'BG' && $csl ne '1') {
- die "$program: invalid INET6TO4_LOOP.\n";
- }
- if ($csl eq 'BG') {
- # go into bg as "daemon":
- setpgrp(0, 0);
- my $pid = fork();
- if (! defined $pid) {
- die "$program: $!\n";
- } elsif ($pid) {
- wait;
- exit 0;
- }
- if (fork) {
- exit 0;
- }
- setpgrp(0, 0);
- close STDIN;
- if (! $ENV{INET6TO4_LOGFILE}) {
- close STDOUT;
- close STDERR;
- }
- }
- delete $ENV{INET6TO4_LOOP};
-
- if (exists $ENV{INET6TO4_PIDFILE}) {
- open_pidfile();
- }
-
- print STDERR "$program: starting service at ", scalar(localtime), " master-pid=$$\n";
- while (1) {
- $looppid = fork;
- if (! defined $looppid) {
- sleep 10;
- } elsif ($looppid) {
- wait;
- } else {
- exec $0, @ARGV;
- exit 1;
- }
- print STDERR "$program: re-starting service at ", scalar(localtime), " master-pid=$$\n";
- sleep 1;
- }
- exit 0;
-}
-if (exists $ENV{INET6TO4_PIDFILE}) {
- open_pidfile();
-}
-
-use IO::Socket::INET6;
-use strict;
-use warnings;
-
-# some settings:
-#
-my $verbose = 1; # set to 0 for no messages, 2 for more.
-my $killpid = 1; # does kill(2) at end of connection.
-my $waittime = 0.25; # time to wait between connections.
-my $reverse = 0; # -r switch (or file named inet4to6)
-
-if (exists $ENV{INET6TO4_VERBOSE}) {
- $verbose = $ENV{INET6TO4_VERBOSE};
-}
-if (exists $ENV{INET6TO4_WAITTIME}) {
- $waittime = $ENV{INET6TO4_WAITTIME};
-}
-
-# process command line args:
-
-if (! @ARGV || $ARGV[0] =~ '^-+h') { # -help
- open(ME, "<$0");
- while (<ME>) {
- last unless /^#/;
- next if /usr.bin.perl/;
- $_ =~ s/# ?//;
- print;
- }
- exit;
-}
-
-my $cmax = 0;
-if ($ARGV[0] eq '-c') { # -c
- shift;
- $cmax = shift;
-}
-
-if ($ARGV[0] eq '-r') { # -r
- shift;
- $reverse = 1;
-} elsif ($0 =~ /inet4to6$/) {
- $reverse = 1;
-}
-
-my $listen_port = shift; # ipv6-listen-port
-my $connect_to = shift; # ipv4-host:port
-
-die "no listen port or connect-to-host:port\n" if ! $listen_port || ! $connect_to;
-
-# connect to host:
-#
-my $host = '';
-my $port = '';
-if ($connect_to =~ /^(.*):(\d+)$/) {
- $host = $1;
- $port = $2;
-}
-die "invalid connect-to-host:port\n" if ! $host || ! $port;
-
-setpgrp(0, 0);
-
-# create listening socket:
-#
-my %opts;
-$opts{Listen} = 10;
-$opts{Proto} = "tcp";
-$opts{ReuseAddr} = 1;
-if ($listen_port =~ /^(.*):(\d+)$/) {
- $opts{LocalAddr} = $1;
- $listen_port = $2;
-}
-$opts{LocalPort} = $listen_port;
-
-if (!$reverse) {
- # force ipv6 interface:
- $opts{Domain} = AF_INET6;
- $listen_sock = IO::Socket::INET6->new(%opts);
-} else {
- $listen_sock = IO::Socket::INET->new(%opts);
- if (! $listen_sock && $! =~ /invalid/i) {
- warn "$program: $!, retrying with AF_UNSPEC:\n";
- $opts{Domain} = AF_UNSPEC;
- $listen_sock = IO::Socket::INET6->new(%opts);
- }
-}
-if (! $listen_sock) {
- die "$program: $!\n";
-}
-
-# for use by the xfer helper processes' interrupt handlers:
-#
-my $current_fh1 = '';
-my $current_fh2 = '';
-
-# connection counter:
-#
-my $conn = 0;
-
-# loop forever waiting for connections:
-#
-while (1) {
- $conn++;
- if ($cmax > 0 && $conn > $cmax) {
- print STDERR "last connection ($cmax)\n" if $verbose;
- last;
- }
- print STDERR "listening for connection: $conn\n" if $verbose;
- my ($client, $ip) = $listen_sock->accept();
-
- if ($client && !$reverse && $port == $listen_port) {
- # This happens on Darwin 'tcp46'
- if ($client->peerhost() =~ /^::ffff:/) {
- print STDERR "closing client we think is actually us: ",
- $client->peerhost(), "\n";
- close $client;
- $client = undef;
- }
- }
- if (! $client) {
- # to throttle runaways
- fsleep(2 * $waittime);
- next;
- }
- print STDERR "conn: $conn -- ", $client->peerhost(), " at ", scalar(localtime), "\n" if $verbose;
-
- # spawn helper:
- #
- my $pid = fork();
- if (! defined $pid) {
- die "$program: $!\n";
- } elsif ($pid) {
- wait;
- # to throttle runaways
- fsleep($waittime);
- next;
- } else {
- # this is to avoid zombies:
- close $listen_sock;
- if (fork) {
- exit 0;
- }
- setpgrp(0, 0);
- handle_conn($client);
- }
-}
-
-exit 0;
-
-sub handle_conn {
- my $client = shift;
-
- my $start = time();
-
- print STDERR "connecting to: $host:$port\n" if $verbose;
-
- my $sock = '';
- my %opts;
- $opts{PeerAddr} = $host;
- $opts{PeerPort} = $port;
- $opts{Proto} = "tcp";
- if (!$reverse) {
- $sock = IO::Socket::INET->new(%opts);
- } else {
- $opts{Domain} = AF_INET6;
- $sock = IO::Socket::INET6->new(%opts);
- }
- if (! $sock) {
- warn "$program: $!, retrying with AF_UNSPEC:\n";
- $opts{Domain} = AF_UNSPEC;
- $sock = IO::Socket::INET6->new(%opts);
- }
-
- if (! $sock) {
- close $client;
- die "$program: $!\n";
- }
-
- $current_fh1 = $client;
- $current_fh2 = $sock;
-
- # interrupt handler:
- #
- $SIG{TERM} = sub {print STDERR "got sigterm\[$$]\n" if $verbose; close $current_fh1; close $current_fh2; exit 0};
-
- # spawn another helper and transfer the data:
- #
- my $parent = $$;
- if (my $child = fork()) {
- xfer($sock, $client, 'S->C');
- if ($killpid) {
- fsleep(0.5);
- kill 'TERM', $child;
- }
- } else {
- xfer($client, $sock, 'C->S');
- if ($killpid) {
- fsleep(0.75);
- kill 'TERM', $parent;
- }
- }
-
- # done.
- #
- if ($verbose > 1) {
- my $dt = time() - $start;
- print STDERR "dt\[$$]: $dt\n";
- }
- exit 0;
-}
-
-# transfers data in one direction:
-#
-sub xfer {
- my($in, $out, $lab) = @_;
- my ($RIN, $WIN, $EIN, $ROUT);
- $RIN = $WIN = $EIN = "";
- $ROUT = "";
- vec($RIN, fileno($in), 1) = 1;
- vec($WIN, fileno($in), 1) = 1;
- $EIN = $RIN | $WIN;
- my $buf;
-
- while (1) {
- my $nf = 0;
- while (! $nf) {
- $nf = select($ROUT=$RIN, undef, undef, undef);
- }
- my $len = sysread($in, $buf, 8192);
- if (! defined($len)) {
- next if $! =~ /^Interrupted/;
- print STDERR "$program\[$lab/$conn/$$]: $!\n";
- last;
- } elsif ($len == 0) {
- print STDERR "$program\[$lab/$conn/$$]: "
- . "Input is EOF.\n";
- last;
- }
-
- if ($verbose > 4) {
- # verbose debugging of data:
- syswrite(STDERR , "\n$lab: ", 6);
- syswrite(STDERR , $buf, $len);
- }
-
- my $offset = 0;
- my $quit = 0;
- while ($len) {
- my $written = syswrite($out, $buf, $len, $offset);
- if (! defined $written) {
- print STDERR "$program\[$lab/$conn/$$]: "
- . "Output is EOF. $!\n";
- $quit = 1;
- last;
- }
- $len -= $written;
- $offset += $written;
- }
- last if $quit;
- }
- close($in);
- close($out);
-}
-
-# sleep a fraction of a second:
-#
-sub fsleep {
- my ($time) = @_;
- select(undef, undef, undef, $time) if $time;
-}
diff --git a/x11vnc/misc/panner.pl b/x11vnc/misc/panner.pl
deleted file mode 100755
index 344beee..0000000
--- a/x11vnc/misc/panner.pl
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/usr/bin/perl
-#
-# panner.pl: start up x11vnc in '-clip' mode viewing a small (WxH)
-# rectangular region of the screen. Allow the viewer user
-# to 'pan' around the display region by moving the mouse.
-#
-# Remote interaction with applications, e.g. clicking a
-# button though the VNC viewer, will be very difficult.
-# This may be useful in a 'demo' mode where the user sitting
-# at the physical display is the only one moving the mouse.
-# Depending on your usage the following x11vnc options may
-# be useful: -nonap
-#
-# Usage: panner.pl WxH <x11vnc-args> (e.g. -display ...)
-# or panner.pl WxH:0.05 <x11vnc-args> (e.g. 0.05 is polling time in secs.)
-
-use strict;
-
-my $WxH = shift;
-my $poll_time;
-
-# split off poll time:
-#
-($WxH, $poll_time) = split(/:/, $WxH);
-my ($W, $H) = split(/x/, $WxH);
-
-$poll_time = 0.1 unless $poll_time ne '';
-
-# set to x11vnc command (e.g. full PATH)
-#
-my $x11vnc = "x11vnc";
-
-# check if display was given:
-#
-my $query_args = "";
-for (my $i=0; $i < @ARGV; $i++) {
- if ($ARGV[$i] eq '-display') {
- $query_args = "-display $ARGV[$i+1]";
- }
-}
-
-# find the size of display and the current mouse position:
-my %v;
-vset("DIRECT:wdpy_x,wdpy_y,pointer_x,pointer_y,pointer_same");
-
-# set a -clip argument based on the above:
-#
-my $clip = '';
-clip_set();
-$clip = "${W}x${H}+0+0" unless $v{pointer_same};
-
-# launch x11vnc with -clip in the background:
-#
-my $cmd = "$x11vnc -clip $clip -bg " . join(" ", @ARGV);
-print STDERR "running: $cmd\n";
-system $cmd;
-
-# user can hit Ctrl-C or kill this script to quit (and stop x11vnc)
-#
-sub quit {
- system("$x11vnc $query_args -R stop");
- exit 0;
-}
-
-$SIG{INT} = \&quit;
-$SIG{TERM} = \&quit;
-
-# loop forever waiting for mouse position to change, then shift -clip:
-#
-my $clip_old = $clip;
-while (1) {
- fsleep($poll_time);
- vset("pointer_x,pointer_y,pointer_same");
- next unless $v{pointer_same};
- clip_set();
- if ($clip ne $clip_old) {
- system("$x11vnc $query_args -R clip:$clip");
- $clip_old = $clip
- }
-}
-
-exit 0;
-
-# short sleep:
-#
-sub fsleep {
- my ($time) = @_;
- select(undef, undef, undef, $time) if $time;
-}
-
-# set the -clip string, making sure view doesn't go off edges of display:
-#
-sub clip_set {
- my $x = int($v{pointer_x} - $W/2);
- my $y = int($v{pointer_y} - $H/2);
- $x = 0 if $x < 0;
- $y = 0 if $y < 0;
- $x = $v{wdpy_x} - $W if $x + $W > $v{wdpy_x};
- $y = $v{wdpy_y} - $H if $y + $H > $v{wdpy_y};
- $clip = "${W}x${H}+$x+$y";
-}
-
-# query x11vnc for values, put results in the %v hash:
-#
-sub vset {
- my $str = shift;
- my $out = `$x11vnc $query_args -Q $str 2>/dev/null`;
- chomp $out;
- foreach my $pair (split(/,/, $out)) {
- $pair =~ s/^a..=//;
- my ($k, $v) = split(/:/, $pair, 2);
- if ($k ne '' && $v ne '') {
- print STDERR "k=$k v=$v\n" if $ENV{DEBUG};
- $v{$k} = $v;
- }
- }
-}
diff --git a/x11vnc/misc/qt_tslib_inject.pl b/x11vnc/misc/qt_tslib_inject.pl
deleted file mode 100755
index d69d174..0000000
--- a/x11vnc/misc/qt_tslib_inject.pl
+++ /dev/null
@@ -1,1064 +0,0 @@
-#!/usr/bin/perl
-#
-# qt_tslib_inject.pl:
-#
-# touch screen input injection tool for use with x11vnc.
-#
-# example usage:
-#
-# x11vnc ... -rawfb console -pipeinput ./qt_tslib_inject_input.pl -env INJECT_OPTIONS=cal=/etc/pointercal
-#
-# See options below.
-#
-# tested on qtmoko (neo freerunner) with tslib.
-
-#
-# Copyright (c) 2010 by Karl J. Runge <runge@karlrunge.com>
-#
-# qt_tslib_inject.pl is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# qt_tslib_inject.pl is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with qt_tslib_inject.pl; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-# or see <http://www.gnu.org/licenses/>.
-#
-
-set_constants();
-
-# one can set these env. vars. before running:
-
-# the device file to inject the events into:
-#
-$dev = $ENV{INJECT_DEV};
-$dev = "/dev/input/event1" unless $dev;
-
-# options, see below. useful: cal=/etc/pointercal
-#
-$options = $ENV{INJECT_OPTIONS};
-$options = '' unless $options ne '';
-
-$debug = 0; # enable debugging output:
-$pressure = 1; # level of touch pad pressure for click.
-$btn_touch = 0; # send BTN_TOUCH on clicks instead of pressure changes.
-$absalways = 0; # send a zero pressure absolute position event whenever mouse moves.
-$dragskip = 0; # how often to skip injecting motion event while dragging.
-
-$a_xform = ''; # tslib's calibration coefficients.
-@a = ();
-
-%keycmds = (); # user defined hotkeys to run external commands.
-
-# separate the options by comma, e.g. pressure=5,cal=/etc/pointercal
-
-if ($options =~ /absalways/i) {
- # set to always send a zero pressure ABS event when mouse moves
- $absalways = 1;
-}
-if ($options =~ /btn_touch/i) {
- # send BTN_TOUCH on clicks.
- $btn_touch = 1;
-}
-if ($options =~ /pressure=(\d+)/i) {
- # level of touchpad pressure to use on a touch.
- $pressure = $1;
-}
-if ($options =~ /dragskip=(\d+)/i) {
- # when dragging with pressure, skip this many events.
- $dragskip = $1;
-}
-if ($options =~ /cal=([^,]+)/i) {
- # tslib's /etc/pointercal linear transform:
- $a_xform = $1;
- if (-f $a_xform) {
- $a_xform = `head -n 1 '$a_xform'`;
- chomp $a_xform;
- $a_xform =~ s/^\s*//;
- $a_xform =~ s/\s*$//;
- }
-}
-if ($options =~ /keycmds=([^,]+)/i) {
- # format: keysym1:command1+keysym2:command2+...
- # e.g.: keycmds=F6:date+F7:'./x11vnc-0.9.10 -connect ./ctl.txt -R reset'
- my $str = $1;
- if (-f $str && open(F, "<$str")) {
- $str = '';
- while (<F>) {
- chomp;
- $_ =~ s/^\s*//;
- $_ =~ s/\s*$//;
- next if /^#/;
- next if $_ eq "";
- $str .= '+' if $str ne '';
- $str .= $_;
- }
- close F;
- }
- foreach my $part (split(/\+/, $str)) {
- my ($key, $cmd) = split(/:/, $part, 2);
- if ($key !~ /^\s*$/) {
- $keycmds{$key} = $cmd;
- }
- }
-}
-if ($options =~ /debug=(\d+)/i) {
- # debug printout
- $debug = $1;
-} elsif ($options =~ /debug/i) {
- $debug = 1;
-}
-
-# end of the top part that user should read and understand
-# for setting options, etc.
-######################################################################
-
-$start = time();
-
-# open the device for writing:
-#
-$modes = $O_WRONLY;
-printf("open modes: 0x%x\n", $modes) if $debug;
-
-sysopen(FD, $dev, $modes) || die "$dev: $!";
-
-my $curr_mask = 0;
-my $curr_x = 0;
-my $curr_y = 0;
-my $down_count = 0;
-
-# read input events from x11vnc through STDIN:
-#
-while (<>) {
- chomp;
- if (/^Pointer/) {
- my ($p, $client, $x, $y, $mask, $hint) = split(' ', $_, 6);
- do_pointer($client, $x, $y, $mask, $hint);
- } elsif (/^Keysym/) {
- my ($k, $client, $down, $keysym, $name, $hint) = split(' ', $_, 6);
- do_keysym($client, $down, $keysym, $name, $hint);
- }
-}
-
-close(FD);
-
-exit(0);
-
-sub do_keysym {
- # qtmoko/neo does not support keystroke input. so these will be ignored.
- # (one possibility would to be enable qtmoko to read from /dev/tty0.
- # but the injection mechanism would need to be modified.)
- my ($client, $down, $keysym, $name, $hint) = @_;
-
- $ENV{DO_KEYSYM} = "$client $down $keysym $name $hint";
-
- # one could implement his own 'hot keys' here.
-
- # process any keycmds:
- if (%keycmds && (exists $keycmds{$name} || exists $keycmds{ALL})) {
- my $cmd = $keycmds{$name};
- if (!exists $keycmds{$name}) {
- $cmd = $keycmds{ALL};
- print STDERR "keycmds: $name/ALL: running: $cmd\n";
- system("$cmd");
- } elsif ($down) {
- print STDERR "keycmds: $name: running: $cmd\n";
- system("$cmd");
- }
- return;
- }
-
- $name = "XK_$name";
- my $nolookup = 0;
- if (! exists $key_lookup{$name}) {
- $nolookup = 1;
- } elsif (! defined $key_lookup{$name}) {
- $nolookup = 2;
- } elsif ($key_lookup{$name} =~ /^\s*$/) {
- $nolookup = 3;
- }
- if ($nolookup) {
- print STDERR "do_keysym: key not implemented-$nolookup $down $keysym $name $hint.\n" if $debug;
- return;
- }
-
- print STDERR gettime() . " do_keysym: $name\n" if $debug;
- do_key($key_lookup{$name}, $down);
-}
-
-sub do_pointer {
- my ($client, $x, $y, $mask, $hint) = @_;
- my $x2 = $x;
- my $y2 = $y;
- if ($a_xform ne '') {
- # this is tslib's /etc/pointercal format.
- if (! @a) {
- # -528 33408 -3417516 -44200 408 40292028 56541
- @a = split(' ', $a_xform);
- foreach my $a (@a) {
- $a += 0.0;
- }
- }
- # this is the inverse of the tslib transformation:
- #
- $x2 = ( $a[4] * ($a[6] * $x - $a[2]) - $a[1] * ($a[6] * $y - $a[5]) )
- / ( $a[4] * $a[0] - $a[1] * $a[3]);
- $y2 = ( $a[0] * ($a[6] * $y - $a[5]) - $a[3] * ($a[6] * $x - $a[2]) )
- / ( $a[4] * $a[0] - $a[1] * $a[3]);
- $x2 = int($x2);
- $y2 = int($y2);
- }
-
- print STDERR gettime() . " do_pointer $x $y (=> $x2 $y2) $mask $hint.\n" if $debug;
-
- if (! $btn_touch) {
- if ($curr_mask == 0 && $mask == 0) {
- do_abs($x2, $y2, 0) if $absalways;
- } elsif ($curr_mask == 0 && $mask != 0) {
- do_abs($x2, $y2, $pressure);
- $down_count = 0;
- } elsif ($curr_mask != 0 && $mask == 0) {
- do_abs($x2, $y2, 0);
- } elsif ($curr_mask != 0 && $mask != 0) {
- $down_count++;
- if ($dragskip > 0) {
- if ($down_count % $dragskip == 0) {
- do_abs($x2, $y2, $pressure);
- } else {
- print STDERR "dragskip $down_count $dragskip\n" if $debug;
- }
- } else {
- do_abs($x2, $y2, $pressure);
- }
- }
- } else {
- if ($curr_mask == 0 && $mask == 0) {
- do_abs($x2, $y2, 0) if $absalways;
- } elsif ($curr_mask == 0 && $mask != 0) {
- do_abs($x2, $y2, 0);
- do_btn($BTN_TOUCH, 1);
- } elsif ($curr_mask != 0 && $mask == 0) {
- do_abs($x2, $y2, 0);
- do_btn($BTN_TOUCH, 0);
- } elsif ($curr_mask != 0 && $mask != 0) {
- ;
- }
- }
-
- $curr_mask = $mask;
- $curr_x = $x2;
- $curr_y = $y2;
-}
-
-# struct input_event {
-# struct timeval time;
-# __u16 type;
-# __u16 code;
-# __s32 value;
-# };
-
-sub do_syn {
- my $ev = gtod();
- $ev .= pack("S", $EV_SYN);
- $ev .= pack("S", $SYN_REPORT);
- $ev .= pack("i", 0);
- print STDERR "do_syn EV_SYN\n" if $debug;
- my $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_syn: $!\n";
- }
-}
-
-sub do_key {
- # not supported by qtmoko
- my ($key, $down) = @_;
- my $ev = gtod();
- $ev .= pack("S", $EV_KEY);
- $ev .= pack("S", $key);
- $ev .= pack("i", $down);
- print STDERR "do_key $key $down\n" if $debug;
- my $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_key: $!\n";
- }
- do_syn();
-}
-
-sub do_btn {
- # only BTN_TOUCH supported by qtmoko (but it seems to be ignored??)
- my ($button, $down) = @_;
- my $ev = gtod();
- $ev .= pack("S", $EV_KEY);
- $ev .= pack("S", $button);
- $ev .= pack("i", $down);
- print STDERR "do_btn $button $down\n" if $debug;
- my $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_btn: $!\n";
- }
- do_syn();
-}
-
-sub do_abs {
- # absolute method is the workhorse for the touchscreen.
- my ($x, $y, $p) = @_;
- my $ev = gtod();
- $ev .= pack("S", $EV_ABS);
- $ev .= pack("S", $ABS_Y);
- $ev .= pack("i", $y);
- print STDERR "do_abs y=$y\n" if $debug;
- my $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_abs: $!\n";
- }
- $ev = gtod();
- $ev .= pack("S", $EV_ABS);
- $ev .= pack("S", $ABS_X);
- $ev .= pack("i", $x);
- print STDERR "do_abs x=$x\n" if $debug;
- $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_abs: $!\n";
- }
- $ev = gtod();
- $ev .= pack("S", $EV_ABS);
- $ev .= pack("S", $ABS_PRESSURE);
- $ev .= pack("i", $p);
- print STDERR "do_abs p=$p\n" if $debug;
- $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_abs: $!\n";
- }
- do_syn();
-}
-
-sub do_rel {
- # not supported by qtmoko
- my ($dx, $dy) = @_;
- my $ev = gtod();
- $ev .= pack("S", $EV_REL);
- $ev .= pack("S", $REL_Y);
- $ev .= pack("i", $dy);
- print STDERR "do_rel dy=$dy\n" if $debug;
- my $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_rel: $!\n";
- }
- $ev = gtod();
- $ev .= pack("S", $EV_REL);
- $ev .= pack("S", $REL_X);
- $ev .= pack("i", $dx);
- print STDERR "do_rel dx=$dx\n";
- $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_rel: $!\n";
- }
- do_syn();
-}
-
-sub gtod {
- # 32 bit machines. TBD use perl module Time:HiRes.
- $tv = ("\0" x 4) x 2; # assumes long is 4 bytes. should use pack.
- $tz = ("\0" x 4) x 2;
- syscall($linux_gettimeofday_syscall, $tv, $tz);
- return $tv;
-}
-
-sub gettime {
- my $tv = gtod();
- my ($tv_sec, $tv_usec) = unpack("L2", $tv);
- $tv_usec2 = sprintf("%8.6f", $tv_usec/1000000.0);
- if ( $tv_usec2 =~ /^0\./ ) {
- $tv_usec2 =~ s/^0\././;
- $tv_sec = "$tv_sec$tv_usec2";
- } else {
- $tv_sec = $tv_sec + ($tv_usec/1000000.0);
- }
- return sprintf("%.3f", $tv_sec - $start);
-}
-
-sub fsleep {
- my ($time) = @_;
- select(undef, undef, undef, $time) if $time;
-}
-
-sub set_constants {
-
-# from /usr/include/linux/uinput.h /usr/include/linux/input.h and x11vnc.
-
-# #define ABS_MAX 0x3f = 63
-#
-# #define UINPUT_MAX_NAME_SIZE 80
-#
-# struct input_id {
-# __u16 bustype;
-# __u16 vendor;
-# __u16 product;
-# __u16 version;
-# };
-#
-# struct uinput_user_dev {
-# char name[UINPUT_MAX_NAME_SIZE];
-# struct input_id id;
-# int ff_effects_max;
-# int absmax[ABS_MAX + 1];
-# int absmin[ABS_MAX + 1];
-# int absfuzz[ABS_MAX + 1];
-# int absflat[ABS_MAX + 1];
-# };
-# #endif /* __UINPUT_H_ */
-
-$EV_SYN = 0x00;
-$EV_KEY = 0x01;
-$EV_REL = 0x02;
-$EV_ABS = 0x03;
-$EV_MSC = 0x04;
-$EV_SW = 0x05;
-$EV_LED = 0x11;
-$EV_SND = 0x12;
-$EV_REP = 0x14;
-$EV_FF = 0x15;
-$EV_PWR = 0x16;
-$EV_FF_STATUS = 0x17;
-$EV_MAX = 0x1f;
-
-$ID_BUS = 0;
-$ID_VENDOR = 1;
-$ID_PRODUCT = 2;
-$ID_VERSION = 3;
-
-$BUS_PCI = 0x01;
-$BUS_ISAPNP = 0x02;
-$BUS_USB = 0x03;
-$BUS_HIL = 0x04;
-$BUS_BLUETOOTH = 0x05;
-$BUS_VIRTUAL = 0x06;
-
-$BUS_ISA = 0x10;
-$BUS_I8042 = 0x11;
-$BUS_XTKBD = 0x12;
-$BUS_RS232 = 0x13;
-$BUS_GAMEPORT = 0x14;
-$BUS_PARPORT = 0x15;
-$BUS_AMIGA = 0x16;
-$BUS_ADB = 0x17;
-$BUS_I2C = 0x18;
-$BUS_HOST = 0x19;
-$BUS_GSC = 0x1A;
-$BUS_ATARI = 0x1B;
-
-$REL_X = 0x00;
-$REL_Y = 0x01;
-$REL_Z = 0x02;
-$REL_RX = 0x03;
-$REL_RY = 0x04;
-$REL_RZ = 0x05;
-$REL_HWHEEL = 0x06;
-$REL_DIAL = 0x07;
-$REL_WHEEL = 0x08;
-$REL_MISC = 0x09;
-
-$ABS_X = 0x00;
-$ABS_Y = 0x01;
-$ABS_Z = 0x02;
-$ABS_RX = 0x03;
-$ABS_RY = 0x04;
-$ABS_RZ = 0x05;
-$ABS_THROTTLE = 0x06;
-$ABS_RUDDER = 0x07;
-$ABS_WHEEL = 0x08;
-$ABS_GAS = 0x09;
-$ABS_BRAKE = 0x0a;
-$ABS_HAT0X = 0x10;
-$ABS_HAT0Y = 0x11;
-$ABS_HAT1X = 0x12;
-$ABS_HAT1Y = 0x13;
-$ABS_HAT2X = 0x14;
-$ABS_HAT2Y = 0x15;
-$ABS_HAT3X = 0x16;
-$ABS_HAT3Y = 0x17;
-$ABS_PRESSURE = 0x18;
-$ABS_DISTANCE = 0x19;
-$ABS_TILT_X = 0x1a;
-$ABS_TILT_Y = 0x1b;
-$ABS_TOOL_WIDTH = 0x1c;
-$ABS_VOLUME = 0x20;
-$ABS_MISC = 0x28;
-$ABS_MT_TOUCH_MAJOR = 0x30;
-$ABS_MT_TOUCH_MINOR = 0x31;
-$ABS_MT_WIDTH_MAJOR = 0x32;
-$ABS_MT_WIDTH_MINOR = 0x33;
-$ABS_MT_ORIENTATION = 0x34;
-$ABS_MT_POSITION_X = 0x35;
-$ABS_MT_POSITION_Y = 0x36;
-$ABS_MT_TOOL_TYPE = 0x37;
-$ABS_MT_BLOB_ID = 0x38;
-$ABS_MT_TRACKING_ID = 0x39;
-#$ABS_MAX = 0x3f;
-
-
-$BTN_MISC = 0x100;
-$BTN_0 = 0x100;
-$BTN_1 = 0x101;
-$BTN_2 = 0x102;
-$BTN_3 = 0x103;
-$BTN_4 = 0x104;
-$BTN_5 = 0x105;
-$BTN_6 = 0x106;
-$BTN_7 = 0x107;
-$BTN_8 = 0x108;
-$BTN_9 = 0x109;
-
-$BTN_MOUSE = 0x110;
-$BTN_LEFT = 0x110;
-$BTN_RIGHT = 0x111;
-$BTN_MIDDLE = 0x112;
-$BTN_SIDE = 0x113;
-$BTN_EXTRA = 0x114;
-$BTN_FORWARD = 0x115;
-$BTN_BACK = 0x116;
-$BTN_TASK = 0x117;
-
-$BTN_JOYSTICK = 0x120;
-$BTN_TRIGGER = 0x120;
-$BTN_THUMB = 0x121;
-$BTN_THUMB2 = 0x122;
-$BTN_TOP = 0x123;
-$BTN_TOP2 = 0x124;
-$BTN_PINKIE = 0x125;
-$BTN_BASE = 0x126;
-$BTN_BASE2 = 0x127;
-$BTN_BASE3 = 0x128;
-$BTN_BASE4 = 0x129;
-$BTN_BASE5 = 0x12a;
-$BTN_BASE6 = 0x12b;
-$BTN_DEAD = 0x12f;
-
-$BTN_GAMEPAD = 0x130;
-$BTN_A = 0x130;
-$BTN_B = 0x131;
-$BTN_C = 0x132;
-$BTN_X = 0x133;
-$BTN_Y = 0x134;
-$BTN_Z = 0x135;
-$BTN_TL = 0x136;
-$BTN_TR = 0x137;
-$BTN_TL2 = 0x138;
-$BTN_TR2 = 0x139;
-$BTN_SELECT = 0x13a;
-$BTN_START = 0x13b;
-$BTN_MODE = 0x13c;
-$BTN_THUMBL = 0x13d;
-$BTN_THUMBR = 0x13e;
-
-$BTN_DIGI = 0x140;
-$BTN_TOOL_PEN = 0x140;
-$BTN_TOOL_RUBBER = 0x141;
-$BTN_TOOL_BRUSH = 0x142;
-$BTN_TOOL_PENCIL = 0x143;
-$BTN_TOOL_AIRBRUSH = 0x144;
-$BTN_TOOL_FINGER = 0x145;
-$BTN_TOOL_MOUSE = 0x146;
-$BTN_TOOL_LENS = 0x147;
-$BTN_TOUCH = 0x14a;
-$BTN_STYLUS = 0x14b;
-$BTN_STYLUS2 = 0x14c;
-$BTN_TOOL_DOUBLETAP = 0x14d;
-$BTN_TOOL_TRIPLETAP = 0x14e;
-
-$BTN_WHEEL = 0x150;
-$BTN_GEAR_DOWN = 0x150;
-$BTN_GEAR_UP = 0x151;
-
-$SYN_REPORT = 0;
-$SYN_CONFIG = 1;
-$SYN_MT_REPORT = 2;
-
-$KEY_RESERVED = 0;
-$KEY_ESC = 1;
-$KEY_1 = 2;
-$KEY_2 = 3;
-$KEY_3 = 4;
-$KEY_4 = 5;
-$KEY_5 = 6;
-$KEY_6 = 7;
-$KEY_7 = 8;
-$KEY_8 = 9;
-$KEY_9 = 10;
-$KEY_0 = 11;
-$KEY_MINUS = 12;
-$KEY_EQUAL = 13;
-$KEY_BACKSPACE = 14;
-$KEY_TAB = 15;
-$KEY_Q = 16;
-$KEY_W = 17;
-$KEY_E = 18;
-$KEY_R = 19;
-$KEY_T = 20;
-$KEY_Y = 21;
-$KEY_U = 22;
-$KEY_I = 23;
-$KEY_O = 24;
-$KEY_P = 25;
-$KEY_LEFTBRACE = 26;
-$KEY_RIGHTBRACE = 27;
-$KEY_ENTER = 28;
-$KEY_LEFTCTRL = 29;
-$KEY_A = 30;
-$KEY_S = 31;
-$KEY_D = 32;
-$KEY_F = 33;
-$KEY_G = 34;
-$KEY_H = 35;
-$KEY_J = 36;
-$KEY_K = 37;
-$KEY_L = 38;
-$KEY_SEMICOLON = 39;
-$KEY_APOSTROPHE = 40;
-$KEY_GRAVE = 41;
-$KEY_LEFTSHIFT = 42;
-$KEY_BACKSLASH = 43;
-$KEY_Z = 44;
-$KEY_X = 45;
-$KEY_C = 46;
-$KEY_V = 47;
-$KEY_B = 48;
-$KEY_N = 49;
-$KEY_M = 50;
-$KEY_COMMA = 51;
-$KEY_DOT = 52;
-$KEY_SLASH = 53;
-$KEY_RIGHTSHIFT = 54;
-$KEY_KPASTERISK = 55;
-$KEY_LEFTALT = 56;
-$KEY_SPACE = 57;
-$KEY_CAPSLOCK = 58;
-$KEY_F1 = 59;
-$KEY_F2 = 60;
-$KEY_F3 = 61;
-$KEY_F4 = 62;
-$KEY_F5 = 63;
-$KEY_F6 = 64;
-$KEY_F7 = 65;
-$KEY_F8 = 66;
-$KEY_F9 = 67;
-$KEY_F10 = 68;
-$KEY_NUMLOCK = 69;
-$KEY_SCROLLLOCK = 70;
-$KEY_KP7 = 71;
-$KEY_KP8 = 72;
-$KEY_KP9 = 73;
-$KEY_KPMINUS = 74;
-$KEY_KP4 = 75;
-$KEY_KP5 = 76;
-$KEY_KP6 = 77;
-$KEY_KPPLUS = 78;
-$KEY_KP1 = 79;
-$KEY_KP2 = 80;
-$KEY_KP3 = 81;
-$KEY_KP0 = 82;
-$KEY_KPDOT = 83;
-$KEY_103RD = 84;
-$KEY_F13 = 85;
-$KEY_102ND = 86;
-$KEY_F11 = 87;
-$KEY_F12 = 88;
-$KEY_F14 = 89;
-$KEY_F15 = 90;
-$KEY_F16 = 91;
-$KEY_F17 = 92;
-$KEY_F18 = 93;
-$KEY_F19 = 94;
-$KEY_F20 = 95;
-$KEY_KPENTER = 96;
-$KEY_RIGHTCTRL = 97;
-$KEY_KPSLASH = 98;
-$KEY_SYSRQ = 99;
-$KEY_RIGHTALT = 100;
-$KEY_LINEFEED = 101;
-$KEY_HOME = 102;
-$KEY_UP = 103;
-$KEY_PAGEUP = 104;
-$KEY_LEFT = 105;
-$KEY_RIGHT = 106;
-$KEY_END = 107;
-$KEY_DOWN = 108;
-$KEY_PAGEDOWN = 109;
-$KEY_INSERT = 110;
-$KEY_DELETE = 111;
-$KEY_MACRO = 112;
-$KEY_MUTE = 113;
-$KEY_VOLUMEDOWN = 114;
-$KEY_VOLUMEUP = 115;
-$KEY_POWER = 116;
-$KEY_KPEQUAL = 117;
-$KEY_KPPLUSMINUS = 118;
-$KEY_PAUSE = 119;
-$KEY_F21 = 120;
-$KEY_F22 = 121;
-$KEY_F23 = 122;
-$KEY_F24 = 123;
-$KEY_KPCOMMA = 124;
-$KEY_LEFTMETA = 125;
-$KEY_RIGHTMETA = 126;
-$KEY_COMPOSE = 127;
-$KEY_STOP = 128;
-$KEY_AGAIN = 129;
-$KEY_PROPS = 130;
-$KEY_UNDO = 131;
-$KEY_FRONT = 132;
-$KEY_COPY = 133;
-$KEY_OPEN = 134;
-$KEY_PASTE = 135;
-$KEY_FIND = 136;
-$KEY_CUT = 137;
-$KEY_HELP = 138;
-$KEY_MENU = 139;
-$KEY_CALC = 140;
-$KEY_SETUP = 141;
-$KEY_SLEEP = 142;
-$KEY_WAKEUP = 143;
-$KEY_FILE = 144;
-$KEY_SENDFILE = 145;
-$KEY_DELETEFILE = 146;
-$KEY_XFER = 147;
-$KEY_PROG1 = 148;
-$KEY_PROG2 = 149;
-$KEY_WWW = 150;
-$KEY_MSDOS = 151;
-$KEY_COFFEE = 152;
-$KEY_DIRECTION = 153;
-$KEY_CYCLEWINDOWS = 154;
-$KEY_MAIL = 155;
-$KEY_BOOKMARKS = 156;
-$KEY_COMPUTER = 157;
-$KEY_BACK = 158;
-$KEY_FORWARD = 159;
-$KEY_CLOSECD = 160;
-$KEY_EJECTCD = 161;
-$KEY_EJECTCLOSECD = 162;
-$KEY_NEXTSONG = 163;
-$KEY_PLAYPAUSE = 164;
-$KEY_PREVIOUSSONG = 165;
-$KEY_STOPCD = 166;
-$KEY_RECORD = 167;
-$KEY_REWIND = 168;
-$KEY_PHONE = 169;
-$KEY_ISO = 170;
-$KEY_CONFIG = 171;
-$KEY_HOMEPAGE = 172;
-$KEY_REFRESH = 173;
-$KEY_EXIT = 174;
-$KEY_MOVE = 175;
-$KEY_EDIT = 176;
-$KEY_SCROLLUP = 177;
-$KEY_SCROLLDOWN = 178;
-$KEY_KPLEFTPAREN = 179;
-$KEY_KPRIGHTPAREN = 180;
-$KEY_INTL1 = 181;
-$KEY_INTL2 = 182;
-$KEY_INTL3 = 183;
-$KEY_INTL4 = 184;
-$KEY_INTL5 = 185;
-$KEY_INTL6 = 186;
-$KEY_INTL7 = 187;
-$KEY_INTL8 = 188;
-$KEY_INTL9 = 189;
-$KEY_LANG1 = 190;
-$KEY_LANG2 = 191;
-$KEY_LANG3 = 192;
-$KEY_LANG4 = 193;
-$KEY_LANG5 = 194;
-$KEY_LANG6 = 195;
-$KEY_LANG7 = 196;
-$KEY_LANG8 = 197;
-$KEY_LANG9 = 198;
-$KEY_PLAYCD = 200;
-$KEY_PAUSECD = 201;
-$KEY_PROG3 = 202;
-$KEY_PROG4 = 203;
-$KEY_SUSPEND = 205;
-$KEY_CLOSE = 206;
-$KEY_PLAY = 207;
-$KEY_FASTFORWARD = 208;
-$KEY_BASSBOOST = 209;
-$KEY_PRINT = 210;
-$KEY_HP = 211;
-$KEY_CAMERA = 212;
-$KEY_SOUND = 213;
-$KEY_QUESTION = 214;
-$KEY_EMAIL = 215;
-$KEY_CHAT = 216;
-$KEY_SEARCH = 217;
-$KEY_CONNECT = 218;
-$KEY_FINANCE = 219;
-$KEY_SPORT = 220;
-$KEY_SHOP = 221;
-$KEY_ALTERASE = 222;
-$KEY_CANCEL = 223;
-$KEY_BRIGHTNESSDOWN = 224;
-$KEY_BRIGHTNESSUP = 225;
-$KEY_MEDIA = 226;
-$KEY_UNKNOWN = 240;
-$KEY_OK = 0x160;
-$KEY_SELECT = 0x161;
-$KEY_GOTO = 0x162;
-$KEY_CLEAR = 0x163;
-$KEY_POWER2 = 0x164;
-$KEY_OPTION = 0x165;
-$KEY_INFO = 0x166;
-$KEY_TIME = 0x167;
-$KEY_VENDOR = 0x168;
-$KEY_ARCHIVE = 0x169;
-$KEY_PROGRAM = 0x16a;
-$KEY_CHANNEL = 0x16b;
-$KEY_FAVORITES = 0x16c;
-$KEY_EPG = 0x16d;
-$KEY_PVR = 0x16e;
-$KEY_MHP = 0x16f;
-$KEY_LANGUAGE = 0x170;
-$KEY_TITLE = 0x171;
-$KEY_SUBTITLE = 0x172;
-$KEY_ANGLE = 0x173;
-$KEY_ZOOM = 0x174;
-$KEY_MODE = 0x175;
-$KEY_KEYBOARD = 0x176;
-$KEY_SCREEN = 0x177;
-$KEY_PC = 0x178;
-$KEY_TV = 0x179;
-$KEY_TV2 = 0x17a;
-$KEY_VCR = 0x17b;
-$KEY_VCR2 = 0x17c;
-$KEY_SAT = 0x17d;
-$KEY_SAT2 = 0x17e;
-$KEY_CD = 0x17f;
-$KEY_TAPE = 0x180;
-$KEY_RADIO = 0x181;
-$KEY_TUNER = 0x182;
-$KEY_PLAYER = 0x183;
-$KEY_TEXT = 0x184;
-$KEY_DVD = 0x185;
-$KEY_AUX = 0x186;
-$KEY_MP3 = 0x187;
-$KEY_AUDIO = 0x188;
-$KEY_VIDEO = 0x189;
-$KEY_DIRECTORY = 0x18a;
-$KEY_LIST = 0x18b;
-$KEY_MEMO = 0x18c;
-$KEY_CALENDAR = 0x18d;
-$KEY_RED = 0x18e;
-$KEY_GREEN = 0x18f;
-$KEY_YELLOW = 0x190;
-$KEY_BLUE = 0x191;
-$KEY_CHANNELUP = 0x192;
-$KEY_CHANNELDOWN = 0x193;
-$KEY_FIRST = 0x194;
-$KEY_LAST = 0x195;
-$KEY_AB = 0x196;
-$KEY_NEXT = 0x197;
-$KEY_RESTART = 0x198;
-$KEY_SLOW = 0x199;
-$KEY_SHUFFLE = 0x19a;
-$KEY_BREAK = 0x19b;
-$KEY_PREVIOUS = 0x19c;
-$KEY_DIGITS = 0x19d;
-$KEY_TEEN = 0x19e;
-$KEY_TWEN = 0x19f;
-$KEY_DEL_EOL = 0x1c0;
-$KEY_DEL_EOS = 0x1c1;
-$KEY_INS_LINE = 0x1c2;
-$KEY_DEL_LINE = 0x1c3;
-$KEY_MAX = 0x1ff;
-
-
- $key_lookup{XK_Escape} = $KEY_ESC;
- $key_lookup{XK_1} = $KEY_1;
- $key_lookup{XK_2} = $KEY_2;
- $key_lookup{XK_3} = $KEY_3;
- $key_lookup{XK_4} = $KEY_4;
- $key_lookup{XK_5} = $KEY_5;
- $key_lookup{XK_6} = $KEY_6;
- $key_lookup{XK_7} = $KEY_7;
- $key_lookup{XK_8} = $KEY_8;
- $key_lookup{XK_9} = $KEY_9;
- $key_lookup{XK_0} = $KEY_0;
- $key_lookup{XK_exclam} = $KEY_1;
- $key_lookup{XK_at} = $KEY_2;
- $key_lookup{XK_numbersign} = $KEY_3;
- $key_lookup{XK_dollar} = $KEY_4;
- $key_lookup{XK_percent} = $KEY_5;
- $key_lookup{XK_asciicircum} = $KEY_6;
- $key_lookup{XK_ampersand} = $KEY_7;
- $key_lookup{XK_asterisk} = $KEY_8;
- $key_lookup{XK_parenleft} = $KEY_9;
- $key_lookup{XK_parenright} = $KEY_0;
- $key_lookup{XK_minus} = $KEY_MINUS;
- $key_lookup{XK_underscore} = $KEY_MINUS;
- $key_lookup{XK_equal} = $KEY_EQUAL;
- $key_lookup{XK_plus} = $KEY_EQUAL;
- $key_lookup{XK_BackSpace} = $KEY_BACKSPACE;
- $key_lookup{XK_Tab} = $KEY_TAB;
- $key_lookup{XK_q} = $KEY_Q;
- $key_lookup{XK_Q} = $KEY_Q;
- $key_lookup{XK_w} = $KEY_W;
- $key_lookup{XK_W} = $KEY_W;
- $key_lookup{XK_e} = $KEY_E;
- $key_lookup{XK_E} = $KEY_E;
- $key_lookup{XK_r} = $KEY_R;
- $key_lookup{XK_R} = $KEY_R;
- $key_lookup{XK_t} = $KEY_T;
- $key_lookup{XK_T} = $KEY_T;
- $key_lookup{XK_y} = $KEY_Y;
- $key_lookup{XK_Y} = $KEY_Y;
- $key_lookup{XK_u} = $KEY_U;
- $key_lookup{XK_U} = $KEY_U;
- $key_lookup{XK_i} = $KEY_I;
- $key_lookup{XK_I} = $KEY_I;
- $key_lookup{XK_o} = $KEY_O;
- $key_lookup{XK_O} = $KEY_O;
- $key_lookup{XK_p} = $KEY_P;
- $key_lookup{XK_P} = $KEY_P;
- $key_lookup{XK_braceleft} = $KEY_LEFTBRACE;
- $key_lookup{XK_braceright} = $KEY_RIGHTBRACE;
- $key_lookup{XK_bracketleft} = $KEY_LEFTBRACE;
- $key_lookup{XK_bracketright} = $KEY_RIGHTBRACE;
- $key_lookup{XK_Return} = $KEY_ENTER;
- $key_lookup{XK_Control_L} = $KEY_LEFTCTRL;
- $key_lookup{XK_a} = $KEY_A;
- $key_lookup{XK_A} = $KEY_A;
- $key_lookup{XK_s} = $KEY_S;
- $key_lookup{XK_S} = $KEY_S;
- $key_lookup{XK_d} = $KEY_D;
- $key_lookup{XK_D} = $KEY_D;
- $key_lookup{XK_f} = $KEY_F;
- $key_lookup{XK_F} = $KEY_F;
- $key_lookup{XK_g} = $KEY_G;
- $key_lookup{XK_G} = $KEY_G;
- $key_lookup{XK_h} = $KEY_H;
- $key_lookup{XK_H} = $KEY_H;
- $key_lookup{XK_j} = $KEY_J;
- $key_lookup{XK_J} = $KEY_J;
- $key_lookup{XK_k} = $KEY_K;
- $key_lookup{XK_K} = $KEY_K;
- $key_lookup{XK_l} = $KEY_L;
- $key_lookup{XK_L} = $KEY_L;
- $key_lookup{XK_semicolon} = $KEY_SEMICOLON;
- $key_lookup{XK_colon} = $KEY_SEMICOLON;
- $key_lookup{XK_apostrophe} = $KEY_APOSTROPHE;
- $key_lookup{XK_quotedbl} = $KEY_APOSTROPHE;
- $key_lookup{XK_grave} = $KEY_GRAVE;
- $key_lookup{XK_asciitilde} = $KEY_GRAVE;
- $key_lookup{XK_Shift_L} = $KEY_LEFTSHIFT;
- $key_lookup{XK_backslash} = $KEY_BACKSLASH;
- $key_lookup{XK_bar} = $KEY_BACKSLASH;
- $key_lookup{XK_z} = $KEY_Z;
- $key_lookup{XK_Z} = $KEY_Z;
- $key_lookup{XK_x} = $KEY_X;
- $key_lookup{XK_X} = $KEY_X;
- $key_lookup{XK_c} = $KEY_C;
- $key_lookup{XK_C} = $KEY_C;
- $key_lookup{XK_v} = $KEY_V;
- $key_lookup{XK_V} = $KEY_V;
- $key_lookup{XK_b} = $KEY_B;
- $key_lookup{XK_B} = $KEY_B;
- $key_lookup{XK_n} = $KEY_N;
- $key_lookup{XK_N} = $KEY_N;
- $key_lookup{XK_m} = $KEY_M;
- $key_lookup{XK_M} = $KEY_M;
- $key_lookup{XK_comma} = $KEY_COMMA;
- $key_lookup{XK_less} = $KEY_COMMA;
- $key_lookup{XK_period} = $KEY_DOT;
- $key_lookup{XK_greater} = $KEY_DOT;
- $key_lookup{XK_slash} = $KEY_SLASH;
- $key_lookup{XK_question} = $KEY_SLASH;
- $key_lookup{XK_Shift_R} = $KEY_RIGHTSHIFT;
- $key_lookup{XK_KP_Multiply} = $KEY_KPASTERISK;
- $key_lookup{XK_Alt_L} = $KEY_LEFTALT;
- $key_lookup{XK_space} = $KEY_SPACE;
- $key_lookup{XK_Caps_Lock} = $KEY_CAPSLOCK;
- $key_lookup{XK_F1} = $KEY_F1;
- $key_lookup{XK_F2} = $KEY_F2;
- $key_lookup{XK_F3} = $KEY_F3;
- $key_lookup{XK_F4} = $KEY_F4;
- $key_lookup{XK_F5} = $KEY_F5;
- $key_lookup{XK_F6} = $KEY_F6;
- $key_lookup{XK_F7} = $KEY_F7;
- $key_lookup{XK_F8} = $KEY_F8;
- $key_lookup{XK_F9} = $KEY_F9;
- $key_lookup{XK_F10} = $KEY_F10;
- $key_lookup{XK_Num_Lock} = $KEY_NUMLOCK;
- $key_lookup{XK_Scroll_Lock} = $KEY_SCROLLLOCK;
- $key_lookup{XK_KP_7} = $KEY_KP7;
- $key_lookup{XK_KP_8} = $KEY_KP8;
- $key_lookup{XK_KP_9} = $KEY_KP9;
- $key_lookup{XK_KP_Subtract} = $KEY_KPMINUS;
- $key_lookup{XK_KP_4} = $KEY_KP4;
- $key_lookup{XK_KP_5} = $KEY_KP5;
- $key_lookup{XK_KP_6} = $KEY_KP6;
- $key_lookup{XK_KP_Add} = $KEY_KPPLUS;
- $key_lookup{XK_KP_1} = $KEY_KP1;
- $key_lookup{XK_KP_2} = $KEY_KP2;
- $key_lookup{XK_KP_3} = $KEY_KP3;
- $key_lookup{XK_KP_0} = $KEY_KP0;
- $key_lookup{XK_KP_Decimal} = $KEY_KPDOT;
- $key_lookup{XK_F13} = $KEY_F13;
- $key_lookup{XK_F11} = $KEY_F11;
- $key_lookup{XK_F12} = $KEY_F12;
- $key_lookup{XK_F14} = $KEY_F14;
- $key_lookup{XK_F15} = $KEY_F15;
- $key_lookup{XK_F16} = $KEY_F16;
- $key_lookup{XK_F17} = $KEY_F17;
- $key_lookup{XK_F18} = $KEY_F18;
- $key_lookup{XK_F19} = $KEY_F19;
- $key_lookup{XK_F20} = $KEY_F20;
- $key_lookup{XK_KP_Enter} = $KEY_KPENTER;
- $key_lookup{XK_Control_R} = $KEY_RIGHTCTRL;
- $key_lookup{XK_KP_Divide} = $KEY_KPSLASH;
- $key_lookup{XK_Sys_Req} = $KEY_SYSRQ;
- $key_lookup{XK_Alt_R} = $KEY_RIGHTALT;
- $key_lookup{XK_Linefeed} = $KEY_LINEFEED;
- $key_lookup{XK_Home} = $KEY_HOME;
- $key_lookup{XK_Up} = $KEY_UP;
- $key_lookup{XK_Page_Up} = $KEY_PAGEUP;
- $key_lookup{XK_Left} = $KEY_LEFT;
- $key_lookup{XK_Right} = $KEY_RIGHT;
- $key_lookup{XK_End} = $KEY_END;
- $key_lookup{XK_Down} = $KEY_DOWN;
- $key_lookup{XK_Page_Down} = $KEY_PAGEDOWN;
- $key_lookup{XK_Insert} = $KEY_INSERT;
- $key_lookup{XK_Delete} = $KEY_DELETE;
- $key_lookup{XK_KP_Equal} = $KEY_KPEQUAL;
- $key_lookup{XK_Pause} = $KEY_PAUSE;
- $key_lookup{XK_F21} = $KEY_F21;
- $key_lookup{XK_F22} = $KEY_F22;
- $key_lookup{XK_F23} = $KEY_F23;
- $key_lookup{XK_F24} = $KEY_F24;
- $key_lookup{XK_KP_Separator} = $KEY_KPCOMMA;
- $key_lookup{XK_Meta_L} = $KEY_LEFTMETA;
- $key_lookup{XK_Meta_R} = $KEY_RIGHTMETA;
- $key_lookup{XK_Multi_key} = $KEY_COMPOSE;
-
-$ABS_MAX = 63;
-
-$UI_DEV_CREATE = 0x5501;
-$UI_DEV_DESTROY = 0x5502;
-$UI_SET_EVBIT = 0x40045564;
-$UI_SET_KEYBIT = 0x40045565;
-$UI_SET_RELBIT = 0x40045566;
-$UI_SET_ABSBIT = 0x40045567;
-
-# FIXME: time hires, etc.
-$linux_gettimeofday_syscall = 78;
-
-$O_RDONLY = 00;
-$O_WRONLY = 01;
-$O_RDWR = 02;
-$O_NDELAY = 04000;
-
-}
diff --git a/x11vnc/misc/ranfb.pl b/x11vnc/misc/ranfb.pl
deleted file mode 100755
index d6aa49d..0000000
--- a/x11vnc/misc/ranfb.pl
+++ /dev/null
@@ -1,157 +0,0 @@
- #!/bin/sh -- # A comment mentioning perl
-eval 'exec perl -S $0 ${1+"$@"}'
- if 0;
-
-# ranfb.pl: example -rawfb setup program.
-# E.g. x11vnc -rawfb setup:./ranfb.pl
-
-# can supply WxH or W H on cmd line:
-if ($ARGV[0] =~ /^(\d+)x(\d+)$/) {
- $W = $1;
- $H = $2;
-} else {
- $W = shift;
- $H = shift;
-}
-
-$W = 480 unless $W;
-$H = 360 unless $H;
-
-$fb = "/tmp/ranfb.$$";
-open(FB, ">$fb") || die "$!";
-
-$ones = "\377" x ($W * 4);
-for ($y = 0; $y < $H; $y++) {
- print FB $ones;
-}
-
-if (fork) {
- print "map:$fb\@${W}x${H}x32\n";
- exit 0;
-}
-
-srand();
-while (1) {
- showpic();
- if (! kill 0, $ENV{X11VNC_PID}) {
- print STDERR "PID $ENV{X11VNC_PID} gone\n";
- unlink($fb);
- exit;
- }
-}
-
-sub showpic {
-
- # 0 < x,y < 1; R1, R2, ... B4 random & scaled so R,G,B < 255:
- # R(x,y) = R1 + R2 * x + R3 * y + R4 * x * y
- # G(x,y) = G1 + G2 * x + G3 * y + G4 * x * y
- # B(x,y) = B1 + B2 * x + B3 * y + B4 * x * y
-
- $minfac = 0.25;
- foreach $c ('R', 'G', 'B') {
- $a1 = rand() * $minfac;
- $a2 = rand();
- $a3 = rand();
- $a4 = rand();
- $at = $a1 + $a2 + $a3 + $a4;
- $a1 = 255 * ($a1/$at);
- $a2 = 255 * ($a2/$at);
- $a3 = 255 * ($a3/$at);
- $a4 = 255 * ($a4/$at);
- # invert axes randomly
- $ax = 0; $ax = 1 if rand() < 0.5;
- $ay = 0; $ay = 1 if rand() < 0.5;
- eval "\$${c}1 = \$a1";
- eval "\$${c}2 = \$a2";
- eval "\$${c}3 = \$a3";
- eval "\$${c}4 = \$a4";
- eval "\$${c}x = \$ax";
- eval "\$${c}y = \$ay";
- }
-
- for ($i = 0; $i < 256; $i++) {
- $p[$i] = pack("c", $i);
- }
-
- $Winv = 1.0/$W;
- $Hinv = 1.0/$H;
-
- $str = '';
- for ($y = 0; $y < $H; $y++) {
- $yr = $yg = $yb = $y;
- $yr = $H - $yr if $Ry;
- $yg = $H - $yg if $Gy;
- $yb = $H - $yb if $By;
- $yr = $yr * $Hinv;
- $yg = $yg * $Hinv;
- $yb = $yb * $Hinv;
-
- $Y[3*$y+0] = $yr;
- $Y[3*$y+1] = $yg;
- $Y[3*$y+2] = $yb;
- }
-
- for ($x = 0; $x < $W; $x++) {
- $xr = $xg = $xb = $x;
- $xr = $W - $xr if $Rx;
- $xg = $W - $xg if $Gx;
- $xb = $W - $xb if $Bx;
- $xr = $xr * $Winv;
- $xg = $xg * $Winv;
- $xb = $xb * $Winv;
-
- $X[3*$x+0] = $xr;
- $X[3*$x+1] = $xg;
- $X[3*$x+2] = $xb;
- }
-
- for ($y = 0; $y < $H; $y++) {
- #$yr = $yg = $yb = $y;
- #$yr = $H - $yr if $Ry;
- #$yg = $H - $yg if $Gy;
- #$yb = $H - $yb if $By;
- #$yr = $yr * $Hinv;
- #$yg = $yg * $Hinv;
- #$yb = $yb * $Hinv;
-
- $yr = $Y[3*$y+0];
- $yg = $Y[3*$y+1];
- $yb = $Y[3*$y+2];
-
- $RY1 = $R1 + $yr * $R3;
- $GY1 = $G1 + $yg * $G3;
- $BY1 = $B1 + $yb * $B3;
-
- $RY2 = $R2 + $yr * $R4;
- $GY2 = $G2 + $yg * $G4;
- $BY2 = $B2 + $yb * $B4;
-
- for ($x = 0; $x < $W; $x++) {
- #$xr = $xg = $xb = $x;
- #$xr = $W - $xr if $Rx;
- #$xg = $W - $xg if $Gx;
- #$xb = $W - $xb if $Bx;
- #$xr = $xr * $Winv;
- #$xg = $xg * $Winv;
- #$xb = $xb * $Winv;
-
- $n = 3 * $x;
-
- #$v = int($R1 + $xr*$R2 + $yr*$R3 + $xr*$yr*$R4);
- $v = int($RY1 + $X[$n]*$RY2);
- $str .= $p[$v];
-
- #$v = int($G1 + $xg*$G2 + $yg*$G3 + $xg*$yg*$G4);
- $v = int($GY1 + $X[$n+1]*$GY2);
- $str .= $p[$v];
-
- #$v = int($B1 + $xb*$B2 + $yb*$B3 + $xb*$yb*$B4);
- $v = int($BY1 + $X[$n+2]*$BY2);
- $str .= $p[$v];
-
- $str .= "\0";
- }
- }
- seek(FB, 0, 0);
- print FB $str;
-}
diff --git a/x11vnc/misc/rx11vnc b/x11vnc/misc/rx11vnc
deleted file mode 100755
index cf9c78b..0000000
--- a/x11vnc/misc/rx11vnc
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/bin/sh
-#
-# usage: rx11vnc [-s] <host>:<xdisplay>
-# rx11vnc [-s] <host> (assumes xdisplay is 0)
-#
-# -s means use ssh instead of rsh.
-# -S tries to tunnel the vnc traffic thru ssh. (experimental...)
-#
-#set -xv
-
-#
-# Place your x11vnc cmd + options here (must have -bg and -display
-# with -display as the last one)
-#
-cmd="x11vnc -nap -q -bg -display"
-viewer="vncviewer"
-rsh=rsh
-
-#
-# The following two settings are only used under -S (ssh tunnel)
-#
-# Unfortunately, we have to set up the ssh port redirection *before*
-# x11vnc has started and selected its listening port.
-# tunnel_ports is a list of ports we expect/hope to be free on both
-# the local and remote machines:
-#
-tunnel_ports="5900 5901 5902 5903"
-#
-# VNC has a poor default in that if the client appears to be emanating
-# from the local machine, then raw encoding is preferred. With ssh port
-# redirection we appear to be coming from the localhost, but we are not.
-# We pass this encoding list to the viewer to give lowest preference to
-# raw encoding:
-#
-tunnel_encodings="copyrect tight zrle hextile zlib corre rre"
-
-if [ "$USER" = "runge" ]; then
- cmd="x11vnc.expt -nap -q -bg -rfbauth .vnc/passwd -display"
- viewer="vncviewerz"
-fi
-
-if [ "X$1" = "X-s" ]; then
- shift
- rsh=ssh
-elif [ "X$1" = "X-S" ]; then
- shift
- rsh=ssh
- tunnel=1
- cmd=`echo "$cmd" | sed -e 's/ / -localhost /'`
-fi
-
-remote=$1
-if echo "$remote" | grep ':' > /dev/null; then
- :
-else
- remote="$remote:0"
-fi
-
-host=`echo "$remote" | awk -F: '{print $1}'`
-disp=`echo "$remote" | awk -F: '{print $2}'`
-disp=":$disp"
-if [ "X$host" = "X" ]; then
- echo "bad host."
- exit 1
-fi
-
-# start the remote x11vnc:
-if [ $tunnel ]; then
- # much more kludgy for tunnelling:
- tmp=/tmp/rx11vnc.$$
- redir=""
- used_ports=`netstat -an | egrep '(ESTABLISHED|LISTEN) *$' \
- | sed -e 's/^[ ]*//' -e 's/^tcp[ 0-9][ 0-9]*//' \
- -e 's/[ ].*$//' -e 's/^.*[^0-9]//' | sort -nu`
- for p in $tunnel_ports
- do
- ok=1
- for u in $used_ports
- do
- if [ "X$p" = "X$u" ]; then
- echo "port $u is in use. skipping it"
- ok=
- break
- fi
- done
- if [ $ok ]; then
- redir="$redir -L $p:localhost:$p"
- fi
- done
- #
- # Have ssh put the command in the bg, then we look for PORT=
- # in the tmp file. The sleep at the end is to give us enough
- # time to connect thru the port redir, otherwise ssh will exit
- # before we can connect.
- #
- time=15
- $rsh -t -f $redir $host "$cmd $disp; echo END; sleep $time" > $tmp
-
- i=0
- while [ $i -lt $time ]
- do
- sleep 1
- if grep '^PORT=' $tmp > /dev/null; then
- port=`grep '^PORT=' $tmp | sed -e 's/PORT=//'`
- if [ "X$port" != "X" ]; then
- break
- fi
- fi
- i=`expr $i + 1`
- done
- cat $tmp
- rm -f $tmp
-else
- port=`$rsh $host "$cmd $disp" | grep '^PORT=' | sed -e 's/PORT=//'`
-fi
-
-echo "x11vnc port is '$port'"
-
-# now start up the viewer on this end:
-if echo "$port" | grep '^[0-9][0-9]*$' > /dev/null; then
- if [ $port -lt 6000 -a $port -ge 5900 ]; then
- # vncviewer special cases 0-99
- port=`expr $port - 5900`
- fi
- if [ $tunnel ]; then
- $viewer -encodings "$tunnel_encodings" "localhost:$port"
- else
- $viewer "$host:$port"
- fi
-else
- echo "bad port."
- exit 1
-fi
diff --git a/x11vnc/misc/rx11vnc.pl b/x11vnc/misc/rx11vnc.pl
deleted file mode 100755
index e6ab0a1..0000000
--- a/x11vnc/misc/rx11vnc.pl
+++ /dev/null
@@ -1,199 +0,0 @@
- #!/bin/sh -- # A comment mentioning perl
-eval 'exec perl -S $0 ${1+"$@"}'
- if 0;
-#
-# Here is the remote x11vnc command.
-# Modify to your needs, required to have %DISP item that expands to X display
-# and the -bg option to go into the background.
-#
-$x11vnc_cmd = "x11vnc -localhost -nap -q -bg -display %DISP";
-
-#
-# We will redir local ports to these remote ports hoping the remote
-# x11vnc selects one of them:
-#
-@tunnel_ports = qw(5900 5901 5902 5903 5904);
-
-#
-# We need to specify the encoding preferences since vncviewer will
-# mistakeningly prefer "raw" encoding for local connection. required to
-# have %VNC_ITEM to expand to localhost:<port>
-
-# One really needs an -encodings option otherwise the vncviewer will
-# prefer 'raw' which is very slow.
-#
-$viewer_cmd = "vncviewer -encodings 'copyrect tight zrle hextile zlib corre rre' %VNC_DISP";
-$sleep_time = 15;
-
-if ($ENV{USER} eq 'runge') {
- # my personal kludges:
- $viewer_cmd =~ s/vncviewer/vncviewerz/; # for tight
- $x11vnc_cmd .= ' -rfbauth .vnc/passwd'; # I always want rfbauth
-}
-
-chop($Program = `basename $0`);
-
-$Usage = <<"END";
-
-$Program: wrapper to tunnel vncviewer <-> x11vnc VNC traffic through a ssh
- encrypted tunnel port redirection.
-
-Usage: $Program <options> <remote-Xdisplay>
-
-Options:
- -l <user> ssh login as remote user <user>
-
- -rfbauth <remote-auth-file> this option is passed to the remote
- x11vnc command for passwd file.
-
-Notes:
-
-Example: $Program snoopy:0
-
-END
-
-LOOP:
-while (@ARGV) {
- $_ = shift;
- CASE: {
- /^-display$/ && ($remote_xdisplay = shift, last CASE);
- /^-rfbauth$/ && ($x11vnc_cmd .= ' -rfbauth ' . shift, last CASE);
- /^-l$/ && ($remote_user = ' -l ' . shift, last CASE);
- /^--$/ && (last LOOP); # -- means end of switches
- /^-(-.*)$/ && (unshift(@ARGV, $1), last CASE);
- /^(-h|-help)$/ && ((print STDOUT $Usage), exit 0, last CASE);
- if ( /^-(..+)$/ ) { # split bundled switches:
- local($y, $x) = ($1, '');
- (unshift(@ARGV, $y), last CASE) if $y =~ /^-/;
- foreach $x (reverse(split(//, $y))) { unshift(@ARGV,"-$x") };
- last CASE;
- }
- /^-/ && ((print STDERR "Invalid arg: $_\n$Usage"), exit 1, last CASE);
- unshift(@ARGV,$_);
- last LOOP;
- }
-}
-
-select(STDERR); $| = 1;
-select(STDOUT); $| = 1;
-
-# Determine the remote X display to connect to:
-$remote_xdisplay = shift if $remote_xdisplay eq '';
-if ($remote_xdisplay !~ /:/) {
- $remote_xdisplay .= ':0'; # assume they mean :0 over there.
-}
-if ($remote_xdisplay =~ /:/) {
- $host = $`;
- $disp = ':' . $';
-} else {
- die "bad X display: $remote_xdisplay, must be <host>:<display>\n";
-}
-
-#
-# Get list of local ports in use so we can avoid them:
-# (tested on Linux and Solaris)
-#
-open(NETSTAT, "netstat -an|") || die "netstat -an: $!";
-while (<NETSTAT>) {
- chomp ($line = $_);
- next unless $line =~ /(ESTABLISHED|LISTEN|WAIT2?)\s*$/;
- $line =~ s/^\s*//;
- $line =~ s/^tcp[\s\d]*//;
- $line =~ s/\s.*$//;
- $line =~ s/^.*\D//;
- if ($line !~ /^\d+$/) {
- die "bad netstat line: $line from $_";
- }
- $used_port{$line} = 1;
-}
-close(NETSTAT);
-
-#
-# Now match up free local ports with the desired remote ports
-# (note that the remote ones could be in use but that won't stop
-# the ssh with port redirs from succeeding)
-#
-$lport = 5900;
-$cnt = 0;
-foreach $rport (@tunnel_ports) {
- while ($used_port{$lport}) {
- $lport++;
- $cnt++;
- die "too hard to find local ports 5900-$lport" if $cnt > 200;
- }
- $port_map{$rport} = $lport;
- $lport++;
-}
-
-$redir = '';
-foreach $rport (@tunnel_ports) {
- $redir .= " -L $port_map{$rport}:localhost:$rport";
-}
-
-#
-# Have ssh put the command in the bg, then we look for PORT= in the
-# tmp file. The sleep at the end is to give us enough time to connect
-# thru the port redir, otherwise ssh will exit before we can connect.
-#
-
-# This is the x11vnc cmd for the remote side:
-$cmd = $x11vnc_cmd;
-$cmd =~ s/%DISP/$disp/;
-
-# This is the ssh cmd for the local side (this machine):
-$ssh_cmd = "ssh -t -f $remote_user $redir $host '$cmd; echo END; sleep $sleep_time'";
-$ssh_cmd =~ s/ / /g;
-print STDERR "running ssh command:\n\n$ssh_cmd\n\n";
-
-#
-# Run ssh and redir into a tmp file (assumes ssh will use /dev/tty
-# for password/passphrase dialog)
-#
-$tmp = "/tmp/rx.$$";
-system("$ssh_cmd > $tmp");
-
-# Now watch for the PORT=XXXX message:
-$sleep = 0;
-$rport = '';
-print STDERR "\nWaiting for x11vnc to indicate its port ..";
-while ($sleep < $sleep_time + 10) {
- print STDERR ".";
- sleep(1);
- $sleep++;
- if (`cat $tmp` =~ /PORT=(\d+)/) {
- $rport = $1;
- # wait 1 more second for output:
- sleep(1);
- if (`cat $tmp` =~ /PORT=(\d+)/) {
- $rport = $1;
- }
- last;
- }
-}
-print STDERR "\n";
-
-if (! $rport) {
- print STDERR `cat $tmp`;
- unlink($tmp);
- die "could not determine remote port.\n";
-}
-unlink($tmp);
-
-# Find the remote to local mapping:
-$lport = $port_map{$rport};
-print STDERR "remote port is: $rport (corresponds to port $lport here)\n";
-if (! $lport) {
- die "could not determine local port redir.\n";
-}
-
-# Apply the special casing vncviewer does for 5900 <= port < 6000
-if ($lport < 6000 && $lport >= 5900) {
- $lport = $lport - 5900;
-}
-
-# Finally, run the viewer.
-$cmd = $viewer_cmd;
-$cmd =~ s/%VNC_DISP/localhost:$lport/;
-
-print STDERR "running vncviewer command:\n\n$cmd\n\n";
-system($cmd);
diff --git a/x11vnc/misc/shm_clear b/x11vnc/misc/shm_clear
deleted file mode 100755
index 16d5cb6..0000000
--- a/x11vnc/misc/shm_clear
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/bin/sh
-#
-# shm_clear: clean out unattached (NATTACH=0) shm segments.
-# See ipcs(1) and ipcrm(1). Tested on Linux and Solaris.
-#
-# Usage:
-# shm_clear list and prompt for removal of your unattached shm segments.
-# shm_clear -y assume "yes" to all the removal prompts.
-# shm_clear -l only list (all of) your shm segments and exit.
-#
-
-#set -xv
-if echo "$1" | grep '^-h' > /dev/null; then
- # -h or -help
- tail +3 $0 | head -9
- exit
-fi
-
-if [ "X$USER" = "X" ]; then
- USER=$LOGNAME
-fi
-l_arg="shmid.*owner|CREATOR|$USER"
-
-# set up OS dependent cmdline opts, etc.
-if [ `uname` = "Linux" ]; then
- m_arg="-m"
- r_arg="shm"
- g_arg="^0x"
- s_cmd="ipcs $m_arg -i %ID"
- awkcut='{print $2, $6}'
-elif [ `uname` = "SunOS" ]; then
- m_arg="-ma"
- r_arg="-m"
- g_arg="^m"
- s_cmd="ipcs $m_arg | egrep ' %ID |CREATOR' | grep -v IPC.status"
- awkcut='{print $2, $9}'
-else
- echo unsupported OS: `uname`
- exit 1
-fi
-
-list() {
- if [ "X$1" = "X-L" ]; then
- l_arg="$l_arg|."
- echo "All shm segments for all:"
- else
- echo "All shm segments for $USER:"
- fi
- ipcs $m_arg | egrep "$l_arg"
- echo
-}
-
-show() {
- cmd=`echo "$s_cmd" | sed -e "s/%ID/$1/g"`
- eval $cmd
-}
-
-remove() {
- echo ipcrm $r_arg $1
- ipcrm $r_arg $1
-}
-
-if [ "X$1" = "X-l" -o "X$1" = "X-L" ]; then
- # list only. both attached and unattached listed.
- list $1
- exit 0
-fi
-
-if [ "X$1" = "X-y" ]; then
- shift
- yes=1 # assume "yes" to all delete questions.
-else
- yes=""
-fi
-
-list
-
-ids=`ipcs $m_arg | grep "$g_arg" | grep $USER | awk "$awkcut" | grep ' 0$' | awk '{print $1}'`
-if [ "X$ids" = "X" ]; then
- echo "No unattached shmids for $USER."
-fi
-
-for id in $ids
-do
- if [ $yes ]; then
- :
- else
- echo "-------------------------------------"
- show $id
- printf "\nDelete? [y]/n "
- read x
- if echo "$x" | grep -i n > /dev/null; then
- continue
- fi
- fi
- remove $id
-done
diff --git a/x11vnc/misc/slide.pl b/x11vnc/misc/slide.pl
deleted file mode 100755
index b8f284e..0000000
--- a/x11vnc/misc/slide.pl
+++ /dev/null
@@ -1,112 +0,0 @@
- #!/bin/sh -- # A comment mentioning perl
-eval 'exec perl -S $0 ${1+"$@"}'
- if 0;
-#
-# slide.pl: amusing example slideshow program for use with x11vnc -rawfb mode.
-#
-# E.g. x11vnc -rawfb map:/tmp/foo@640x480x32:ff/ff00/ff0000 -pipeinput slide.pl
-#
-# requires: jpegtopnm(1), (maybe LSB too).
-#
-
-@jpegs = qw(
- dr_fun_new.jpg canon.jpg go_microsoft.jpg jonathan2.jpg
- michelle1.jpg novm.jpg photo-008.jpg presrange.jpg
-);
-
-# Or:
-# @jpegs = @ARGV;
-# @jpegs = <*.jpg>;
-
-# this is x11vnc's -rawfb value:
-if ($ENV{X11VNC_RAWFB_STR} =~ m,:(.*)@(\d+)x(\d+)x(\d+),) {
- $fb = $1; # filename
- $W = $2; # width
- $H = $3; # height
-} else {
- die "No usable X11VNC_RAWFB_STR\n";
-}
-
-open(FB, ">$fb") || die "$!";
-
-# make a solid background:
-$ones = "\377" x ($W * 4);
-$grey = "\340" x ($W * 4);
-for ($y = 0; $y < $H; $y++) {
- print FB $grey;
-}
-
-# this is rather slow with many jpegs... oh well.
-foreach $pic (@jpegs) {
- print STDERR "loading '$pic' please wait ...\n";
- open(JPEG, "jpegtopnm '$pic' 2>/dev/null|") || die "$!";
- while (<JPEG>) {
- next if /^P\d/;
- if (/^(\d+)\s+(\d+)\s*$/) {
- $Jpeg{$pic}{w} = $1;
- $Jpeg{$pic}{h} = $2;
- }
- last if /^255$/;
- }
- $data = '';
- while (<JPEG>) {
- $data .= $_;
- }
- close(JPEG);
-
- # need to put in a 4th 0 byte after RGB for 32bpp. 24bpp doesn't work.
- # (MSB might be other way around).
-
- $new = '';
- for ($l = 0; $l < int(length($data)/3); $l++) {
- $new .= substr($data, $l * 3, 3) . "\0";
- }
- $Jpeg{$pic}{data} = $new;
- $data = ''; $new = '';
-
- if ($pic eq $jpegs[0]) {
- showpic(0);
- }
-}
-
-$N = scalar(@jpegs);
-print STDERR "\nFinished loading $N images. Click Button or Spacebar for next.\n";
-$I = 0;
-
-while (<>) {
- # read the next user input event, watch for button press or spacebar:
- ###last if /^Keysym.* [qQ] /;
- next unless /^(Pointer.*ButtonPress|Keysym.*space.*KeyPress)/;
- $I = ($I + 1) % $N;
- showpic($I);
-}
-
-sub showpic {
- my($i) = @_;
-
- my $pic = $jpegs[$i];
- my $h = $Jpeg{$pic}{h};
- my $w = $Jpeg{$pic}{w};
-
- my $dy = int(($H - $h)/2);
- my $dx = int(($W - $w)/2);
-
- print STDERR "showing pic $i: $pic\t$w x $h +$dy+$dx\n";
-
- # clear screen:
- seek(FB, 0, 0);
- for ($y = 0; $y < $H; $y++) {
- print FB $ones;
- }
-
- # insert new picture:
- for ($y = 0; $y < $h; $y++) {
- seek(FB, (($y + $dy) * $W + $dx) * 4, 0);
- $line = substr($Jpeg{$pic}{data}, $y * $w * 4, $w * 4);
- print FB $line;
- }
-}
-
-close(FB);
-###unlink($fb); # this (probably) won't kill x11vnc
-print STDERR "$0 done.\n";
diff --git a/x11vnc/misc/turbovnc/Makefile.am b/x11vnc/misc/turbovnc/Makefile.am
deleted file mode 100644
index 3c6edc6..0000000
--- a/x11vnc/misc/turbovnc/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-# This file has been (or is hereby) released into the public domain by
-# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide.
-#
-# In case this is not legally possible: Karl J. Runge grants anyone the
-# right to use this work for any purpose, without any conditions, unless
-# such conditions are required by law.
-
-EXTRA_DIST=README apply_turbovnc convert convert_rfbserver tight.c turbojpeg.h undo_turbovnc
diff --git a/x11vnc/misc/turbovnc/README b/x11vnc/misc/turbovnc/README
deleted file mode 100644
index 328929c..0000000
--- a/x11vnc/misc/turbovnc/README
+++ /dev/null
@@ -1,159 +0,0 @@
-#
-# This work has been (or is hereby) released into the public domain by
-# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide.
-#
-# In case this is not legally possible: Karl J. Runge grants anyone the
-# right to use this work for any purpose, without any conditions, unless
-# such conditions are required by law.
-#
-
-INTRO:
-------
-
-This is a "patch" to make x11vnc/libvncserver work with TurboVNC:
-
- http://www.virtualgl.org/About/TurboVNC
- http://www.karlrunge.com/x11vnc/faq.html#faq-turbovnc
-
-It is very experimental/kludgy. Not all TurboVNC features may be enabled.
-We are currently evaluating whether TurboVNC support should be officially
-put into x11vnc/libvncserver.
-
-TurboVNC is an optimized VNC for fast refresh rates on fast networks.
-
-It does pretty well on good broadband as well. But it is not as fast
-as regular TightVNC on slow links.
-
-
-TURBOJPEG:
----------
-
-TurboVNC uses the TurboJPEG library based on a fast proprietary JPEG
-implementation. You will need to download it from the VirtualGL
-sourceforge site:
-
- http://sourceforge.net/project/showfiles.php?group_id=117509&package_id=166100
-
-Either install it or simply unpack the .deb or .rpm file into a directory.
-
-N.B. you can unpack a .deb via 'ar x package.deb' and the extracting
-from the data.tar.gz file. rpm2cpio can be used to unpack .rpm's.
-
-
-QUICK-START:
-------------
-
-For those in a hurry:
-
- cd x11vnc-x.y.z/x11vnc/misc/turbovnc
- ./apply_turbovnc
- cd ../../..
- env LDFLAGS='-L/DIR -Xlinker --rpath=/DIR' ./configure
- make AM_LDFLAGS='-lturbojpeg'
-
-where you replace /DIR with your directory containing libturbojpeg.so.
-
-
-PATCHING AND BUILDING:
-----------------------
-
-After unpacking your x11vnc-x.y.z.tar.gz tarball cd to the
-x11vnc-x.y.z/x11vnc/misc/turbovnc (where this README file is) and from
-that directory run:
-
- ./apply_turbovnc
-
-that will modify files in the libvncserver and x11vnc directories above
-this directory. (To undo these changes run: ./undo_turbovnc) The input
-sources, tight.c and turbojpeg.h are from the TurboVNC source package.
-
-After applying, go back to the top level source directory and run:
-
- env LDFLAGS='-L/path/to/turbojpeg -Xlinker --rpath=/path/to/turbojpeg' ./configure
-
-where the turbojpeg library is:
-
- /path/to/turbojpeg/libturbojpeg.so
-
-(change /path/to/turbojpeg to the directory where you installed or
-unpacked it.)
-
-If you are not using gnu gcc and gnu linker the options may be a little
-different (e.g. -R instead of -Xlinker --rpath).
-
-If you need additional ./configure options or env. var. settings,
-add them too.
-
-
-Next, run this make command:
-
- make AM_LDFLAGS='-lturbojpeg'
-
-This is a hack and may not always work, if it doesn't edit x11vnc/Makefile
-and add '-lturbojpeg' to the LIBS variable.
-
-This should create a binary:
-
- ./x11vnc/x11vnc
-
-that supports VirtualGL's TurboVNC.
-
-You will need a TurboVNC viewer, you can get one here:
-
- http://sourceforge.net/project/showfiles.php?group_id=117509&package_id=128130
-
-Let us know how it goes.
-
-
-PERFORMANCE:
-------------
-
-Note that x11vnc has to read the display's screen pixels from the
-graphics card memory. This can be slow, e.g. 10 MB/sec.
-
-There is not a big need for graphics card manufacturers to optimize the
-read rate; the write rate is the one they optimize greatly.
-
- http://www.karlrunge.com/x11vnc/#limitations
-
-If you run x11vnc and see lines like this:
-
- 28/02/2009 00:52:07 Autoprobing selected port 5900
- 28/02/2009 00:52:07 fb read rate: 10 MB/sec
- 28/02/2009 00:52:07 screen setup finished.
-
-you have a typical slow one.
-
-Whereas if you see this:
-
- 28/02/2009 00:54:46 Autoprobing selected port 5900
- 28/02/2009 00:54:46 fb read rate: 321 MB/sec
- 28/02/2009 00:54:46 fast read: reset wait ms to: 10
- 28/02/2009 00:54:46 fast read: reset defer ms to: 10
- 28/02/2009 00:54:46 screen setup finished.
-
-that is very fast. In such a situation you may want to dial down
-x11vnc's delay, e.g.: -wait 5 -defer 5, or even smaller to push things
-out more quickly.
-
-We have only seen it this fast on Linux by using the nvidia proprietary
-graphics drivers. The Xorg drivers are typically slow 10 MB/sec.
-
-It will also be fast if the X server is virtual: Xvfb or Xdummy
-since the screen pixels are stored in RAM:
-
- http://www.karlrunge.com/x11vnc/faq.html#faq-xvfb
-
-And it will be fast if the ShadowFB xorg.conf option is enabled (if the
-card supports it.)
-
-
-The point we are trying to make is that even though TurboVNC uses a
-wicked fast JPEG implementation, and cuts out overhead in its attempt to
-pump out as many frames per second as it can, if it is slow for x11vnc
-to read the screen pixels in the first place then you might not even
-notice the TurboVNC speedup.
-
-So TurboVNC+x11vnc will be faster than TightVNC+x11vnc, but if there is
-a large overhead/bottleneck from reading the graphics card framebuffer,
-then the speedup will be marginal.
diff --git a/x11vnc/misc/turbovnc/apply_turbovnc b/x11vnc/misc/turbovnc/apply_turbovnc
deleted file mode 100755
index 45e4700..0000000
--- a/x11vnc/misc/turbovnc/apply_turbovnc
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-#
-# This script has been (or is hereby) released into the public domain by
-# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide.
-#
-# In case this is not legally possible: Karl J. Runge grants anyone the
-# right to use this work for any purpose, without any conditions, unless
-# such conditions are required by law.
-
-ldir="../../../libvncserver"
-
-fail=""
-if [ ! -f "./tight.c" ]; then
- fail=1
-fi
-if [ ! -f "./turbojpeg.h" ]; then
- fail=1
-fi
-if [ ! -f "./convert" ]; then
- fail=1
-fi
-if [ ! -f "$ldir/tight.c" ]; then
- ls -l "$ldir/tight.c"
- fail=1
-fi
-if [ ! -f "$ldir/rfbserver.c" ]; then
- ls -l "$ldir/rfbserver.c"
- fail=1
-fi
-if [ "X$fail" = "X1" ]; then
- echo "Must be run from inside the directory containing 'apply_turbovnc'"
- exit 1
-fi
-
-set -x
-if [ ! -f "$ldir/tight.c.ORIG" ]; then
- cp -p "$ldir/tight.c" "$ldir/tight.c.ORIG"
-fi
-if [ ! -f "$ldir/rfbserver.c.ORIG" ]; then
- cp -p "$ldir/rfbserver.c" "$ldir/rfbserver.c.ORIG"
-fi
-
-perl ./convert ./tight.c > "$ldir/tight.c"
-perl ./convert_rfbserver $ldir/rfbserver.c.ORIG > "$ldir/rfbserver.c"
-cp -p ./turbojpeg.h "$ldir"
-ls -l $ldir/tight.c* $ldir/rfbserver.c* $ldir/turbojpeg.h
diff --git a/x11vnc/misc/turbovnc/convert b/x11vnc/misc/turbovnc/convert
deleted file mode 100755
index f218f84..0000000
--- a/x11vnc/misc/turbovnc/convert
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/perl
-#
-# This script has been (or is hereby) released into the public domain by
-# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide.
-#
-# In case this is not legally possible: Karl J. Runge grants anyone the
-# right to use this work for any purpose, without any conditions, unless
-# such conditions are required by law.
-
-while (<>) {
- if (/^#include.*"rfb.h"/) {
- print <<END;
-#include <rfb/rfb.h>
-#define Bool rfbBool
-#define CARD32 uint32_t
-#define CARD16 uint16_t
-#define CARD8 uint8_t
-#define xalloc malloc
-#define xrealloc realloc
-#define rfbTightNoZlib 0x0A
-#define tightSubsampLevel correMaxWidth
-
-#if LIBVNCSERVER_HAVE_LIBPTHREAD && LIBVNCSERVER_HAVE_TLS
-#define TLS __thread
-#else
-#define TLS
-#endif
-
-END
- next;
- }
- foreach $func (qw(FindBestSolidArea ExtendSolidArea CheckSolidTile CheckSolidTile##bpp CheckSolidTile8 CheckSolidTile16 CheckSolidTile32 Pack24)) {
- if (/static.*\b\Q$func\E\b/ && !exists $did_static{$func}) {
- $_ =~ s/\b\Q$func\E\b(\s*)\(/$func$1(rfbClientPtr cl, /;
- $did_static{$func} = 1;
- } elsif (/\b\Q$func\E\b\s*\(/) {
- $_ =~ s/\b\Q$func\E\b(\s*)\(/$func$1(cl, /;
- }
- }
-
-# if (/^\s*subsampLevel\s*=\s*cl/) {
-# $_ = "//$_";
-# print "subsampLevel = 0;\n";
-# }
-
-# $_ =~ s/cl->tightQualityLevel;/cl->tightQualityLevel * 10;/;
-
- if (/^static\s+(Bool|int|CARD32|PALETTE|char|unsigned|tjhandle)\s+[^()]*;\s*$/) {
- $_ =~ s/^static/static TLS /;
- }
-
- $_ =~ s/rfbScreen.pfbMemory/cl->scaledScreen->frameBuffer/g;
- $_ =~ s/rfbScreen.paddedWidthInBytes/cl->scaledScreen->paddedWidthInBytes/g;
- $_ =~ s/rfbScreen.bitsPerPixel/cl->scaledScreen->bitsPerPixel/g;
- $_ =~ s/rfbServerFormat/cl->screen->serverFormat/g;
-
- if (/^(FindBestSolidArea|ExtendSolidArea|static void Pack24|CheckSolidTile)\(cl/) {
- $_ .= "rfbClientPtr cl;\n";
- }
- if (/^(CheckSolidTile##bpp)\(cl/) {
- $_ .= "rfbClientPtr cl; \\\n";
- }
- $_ =~ s/\bublen\b/cl->ublen/;
- $_ =~ s/\bupdateBuf\b/cl->updateBuf/;
-
- if (/cl->(rfbRectanglesSent|rfbBytesSent)/) {
- $_ = "//$_";
- }
- print;
-}
-
-print <<END;
-
-void rfbTightCleanup(rfbScreenInfoPtr screen) {
-}
-
-END
-
-
diff --git a/x11vnc/misc/turbovnc/convert_rfbserver b/x11vnc/misc/turbovnc/convert_rfbserver
deleted file mode 100755
index 81267ac..0000000
--- a/x11vnc/misc/turbovnc/convert_rfbserver
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/perl
-#
-# This script has been (or is hereby) released into the public domain by
-# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide.
-#
-# In case this is not legally possible: Karl J. Runge grants anyone the
-# right to use this work for any purpose, without any conditions, unless
-# such conditions are required by law.
-
-$saw_mark = 0;
-$done = 0;
-
-while (<>) {
- if (! $saw_mark && /case rfbEncodingServerIdentity:/) {
- $saw_mark = 1;
- }
- if ($saw_mark && !$done && /default:/) {
- print;
-
- print <<END;
- /* for turbovnc */
-#define rfbJpegQualityLevel1 0xFFFFFE01
-#define rfbJpegQualityLevel100 0xFFFFFE64
-#define rfbJpegSubsamp1X 0xFFFFFD00
-#define rfbJpegSubsamp4X 0xFFFFFD01
-#define rfbJpegSubsamp2X 0xFFFFFD02
-#define rfbJpegSubsampGray 0xFFFFFD03
-
- if ( enc >= (uint32_t)rfbJpegSubsamp1X &&
- enc <= (uint32_t)rfbJpegSubsampGray ) {
- /* XXX member really should be tightSubsample not correMaxWidth */
- cl->correMaxWidth = enc & 0xFF;
- rfbLog("Using JPEG subsampling %d for client %s\\n",
- cl->correMaxWidth, cl->host);
- } else if ( enc >= (uint32_t)rfbEncodingQualityLevel0 &&
- enc <= (uint32_t)rfbEncodingQualityLevel9 ) {
- static int JPEG_QUAL[10] = {
- 5, 10, 15, 25, 37, 50, 60, 70, 75, 80
- };
- cl->tightQualityLevel = JPEG_QUAL[enc & 0x0F];
- /* XXX member really should be tightSubsample not correMaxWidth */
- cl->correMaxWidth = 2;
- rfbLog("Using image level Subsample %d Quality %d for client %s\\n",
- cl->correMaxWidth, cl->tightQualityLevel, cl->host);
- } else if ( enc >= (uint32_t)rfbJpegQualityLevel1 &&
- enc <= (uint32_t)rfbJpegQualityLevel100 ) {
- cl->tightQualityLevel = enc & 0xFF;
- rfbLog("Using image quality level %d for client %s\\n",
- cl->tightQualityLevel, cl->host);
- } else
-END
- $done = 1;
- next;
- }
- print;
-}
diff --git a/x11vnc/misc/turbovnc/tight.c b/x11vnc/misc/turbovnc/tight.c
deleted file mode 100644
index e7b4dbd..0000000
--- a/x11vnc/misc/turbovnc/tight.c
+++ /dev/null
@@ -1,1502 +0,0 @@
-/*
- * tight.c
- *
- * Routines to implement Tight Encoding
- */
-
-/*
- * Copyright (C) 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (C) 2004 Landmark Graphics Corporation. All Rights Reserved.
- * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "rfb.h"
-#include "turbojpeg.h"
-
-/* Note: The following constant should not be changed. */
-#define TIGHT_MIN_TO_COMPRESS 12
-
-/* The parameters below may be adjusted. */
-#define MIN_SPLIT_RECT_SIZE 4096
-#define MIN_SOLID_SUBRECT_SIZE 2048
-#define MAX_SPLIT_TILE_SIZE 16
-
-/* This variable is set on every rfbSendRectEncodingTight() call. */
-static Bool usePixelFormat24;
-
-
-/* Compression level stuff. The following array contains various
- encoder parameters for each of 10 compression levels (0..9).
- Last three parameters correspond to JPEG quality levels (0..9). */
-
-typedef struct TIGHT_CONF_s {
- int maxRectSize, maxRectWidth;
- int monoMinRectSize;
- int idxZlibLevel, monoZlibLevel, rawZlibLevel;
- int idxMaxColorsDivisor;
-} TIGHT_CONF;
-
-static TIGHT_CONF tightConf[2] = {
- { 65536, 2048, 6, 0, 0, 0, 4 },
-#if 0
- { 2048, 128, 6, 1, 1, 1, 8 },
- { 6144, 256, 8, 3, 3, 2, 24 },
- { 10240, 1024, 12, 5, 5, 3, 32 },
- { 16384, 2048, 12, 6, 6, 4, 32 },
- { 32768, 2048, 12, 7, 7, 5, 32 },
- { 65536, 2048, 16, 7, 7, 6, 48 },
- { 65536, 2048, 16, 8, 8, 7, 64 },
- { 65536, 2048, 32, 9, 9, 8, 64 },
-#endif
- { 65536, 2048, 32, 1, 1, 1, 96 }
-};
-
-static int compressLevel;
-static int qualityLevel;
-static int subsampLevel;
-
-static const int subsampLevel2tjsubsamp[4] = {
- TJ_444, TJ_411, TJ_422, TJ_GRAYSCALE
-};
-
-/* Stuff dealing with palettes. */
-
-typedef struct COLOR_LIST_s {
- struct COLOR_LIST_s *next;
- int idx;
- CARD32 rgb;
-} COLOR_LIST;
-
-typedef struct PALETTE_ENTRY_s {
- COLOR_LIST *listNode;
- int numPixels;
-} PALETTE_ENTRY;
-
-typedef struct PALETTE_s {
- PALETTE_ENTRY entry[256];
- COLOR_LIST *hash[256];
- COLOR_LIST list[256];
-} PALETTE;
-
-static int paletteNumColors, paletteMaxColors;
-static CARD32 monoBackground, monoForeground;
-static PALETTE palette;
-
-/* Pointers to dynamically-allocated buffers. */
-
-static int tightBeforeBufSize = 0;
-static char *tightBeforeBuf = NULL;
-
-static int tightAfterBufSize = 0;
-static char *tightAfterBuf = NULL;
-
-static int *prevRowBuf = NULL;
-
-
-/* Prototypes for static functions. */
-
-static void FindBestSolidArea (int x, int y, int w, int h,
- CARD32 colorValue, int *w_ptr, int *h_ptr);
-static void ExtendSolidArea (int x, int y, int w, int h,
- CARD32 colorValue,
- int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr);
-static Bool CheckSolidTile (int x, int y, int w, int h,
- CARD32 *colorPtr, Bool needSameColor);
-static Bool CheckSolidTile8 (int x, int y, int w, int h,
- CARD32 *colorPtr, Bool needSameColor);
-static Bool CheckSolidTile16 (int x, int y, int w, int h,
- CARD32 *colorPtr, Bool needSameColor);
-static Bool CheckSolidTile32 (int x, int y, int w, int h,
- CARD32 *colorPtr, Bool needSameColor);
-
-static Bool SendRectSimple (rfbClientPtr cl, int x, int y, int w, int h);
-static Bool SendSubrect (rfbClientPtr cl, int x, int y, int w, int h);
-static Bool SendTightHeader (rfbClientPtr cl, int x, int y, int w, int h);
-
-static Bool SendSolidRect (rfbClientPtr cl);
-static Bool SendMonoRect (rfbClientPtr cl, int w, int h);
-static Bool SendIndexedRect (rfbClientPtr cl, int w, int h);
-static Bool SendFullColorRect (rfbClientPtr cl, int w, int h);
-
-static Bool CompressData(rfbClientPtr cl, int streamId, int dataLen,
- int zlibLevel, int zlibStrategy);
-static Bool SendCompressedData(rfbClientPtr cl, char *buf, int compressedLen);
-
-static void FillPalette8(int count);
-static void FillPalette16(int count);
-static void FillPalette32(int count);
-static void FastFillPalette16(rfbClientPtr cl, CARD16 *data, int w, int pitch,
- int h);
-static void FastFillPalette32(rfbClientPtr cl, CARD32 *data, int w, int pitch,
- int h);
-
-static void PaletteReset(void);
-static int PaletteInsert(CARD32 rgb, int numPixels, int bpp);
-
-static void Pack24(char *buf, rfbPixelFormat *fmt, int count);
-
-static void EncodeIndexedRect16(CARD8 *buf, int count);
-static void EncodeIndexedRect32(CARD8 *buf, int count);
-
-static void EncodeMonoRect8(CARD8 *buf, int w, int h);
-static void EncodeMonoRect16(CARD8 *buf, int w, int h);
-static void EncodeMonoRect32(CARD8 *buf, int w, int h);
-
-static Bool SendJpegRect(rfbClientPtr cl, int x, int y, int w, int h,
- int quality);
-
-/*
- * Tight encoding implementation.
- */
-
-int
-rfbNumCodedRectsTight(cl, x, y, w, h)
- rfbClientPtr cl;
- int x, y, w, h;
-{
- int maxRectSize, maxRectWidth;
- int subrectMaxWidth, subrectMaxHeight;
-
- /* No matter how many rectangles we will send if LastRect markers
- are used to terminate rectangle stream. */
- if (cl->enableLastRectEncoding && w * h >= MIN_SPLIT_RECT_SIZE)
- return 0;
-
- maxRectSize = tightConf[compressLevel].maxRectSize;
- maxRectWidth = tightConf[compressLevel].maxRectWidth;
-
- if (w > maxRectWidth || w * h > maxRectSize) {
- subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w;
- subrectMaxHeight = maxRectSize / subrectMaxWidth;
- return (((w - 1) / maxRectWidth + 1) *
- ((h - 1) / subrectMaxHeight + 1));
- } else {
- return 1;
- }
-}
-
-Bool
-rfbSendRectEncodingTight(cl, x, y, w, h)
- rfbClientPtr cl;
- int x, y, w, h;
-{
- int nMaxRows;
- CARD32 colorValue;
- int dx, dy, dw, dh;
- int x_best, y_best, w_best, h_best;
- char *fbptr;
-
- compressLevel = cl->tightCompressLevel > 0 ? 1 : 0;
- qualityLevel = cl->tightQualityLevel;
- if (qualityLevel != -1) {
- compressLevel = 1;
- tightConf[compressLevel].idxZlibLevel = 1;
- tightConf[compressLevel].monoZlibLevel = 1;
- tightConf[compressLevel].rawZlibLevel = 1;
- } else {
- tightConf[compressLevel].idxZlibLevel = cl->tightCompressLevel;
- tightConf[compressLevel].monoZlibLevel = cl->tightCompressLevel;
- tightConf[compressLevel].rawZlibLevel = cl->tightCompressLevel;
- }
- subsampLevel = cl->tightSubsampLevel;
-
- if ( cl->format.depth == 24 && cl->format.redMax == 0xFF &&
- cl->format.greenMax == 0xFF && cl->format.blueMax == 0xFF ) {
- usePixelFormat24 = TRUE;
- } else {
- usePixelFormat24 = FALSE;
- }
-
- if (!cl->enableLastRectEncoding || w * h < MIN_SPLIT_RECT_SIZE)
- return SendRectSimple(cl, x, y, w, h);
-
- /* Make sure we can write at least one pixel into tightBeforeBuf. */
-
- if (tightBeforeBufSize < 4) {
- tightBeforeBufSize = 4;
- if (tightBeforeBuf == NULL)
- tightBeforeBuf = (char *)xalloc(tightBeforeBufSize);
- else
- tightBeforeBuf = (char *)xrealloc(tightBeforeBuf,
- tightBeforeBufSize);
- }
-
- /* Calculate maximum number of rows in one non-solid rectangle. */
-
- {
- int maxRectSize, maxRectWidth, nMaxWidth;
-
- maxRectSize = tightConf[compressLevel].maxRectSize;
- maxRectWidth = tightConf[compressLevel].maxRectWidth;
- nMaxWidth = (w > maxRectWidth) ? maxRectWidth : w;
- nMaxRows = maxRectSize / nMaxWidth;
- }
-
- /* Try to find large solid-color areas and send them separately. */
-
- for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) {
-
- /* If a rectangle becomes too large, send its upper part now. */
-
- if (dy - y >= nMaxRows) {
- if (!SendRectSimple(cl, x, y, w, nMaxRows))
- return 0;
- y += nMaxRows;
- h -= nMaxRows;
- }
-
- dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ?
- MAX_SPLIT_TILE_SIZE : (y + h - dy);
-
- for (dx = x; dx < x + w; dx += MAX_SPLIT_TILE_SIZE) {
-
- dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w) ?
- MAX_SPLIT_TILE_SIZE : (x + w - dx);
-
- if (CheckSolidTile(dx, dy, dw, dh, &colorValue, FALSE)) {
-
- if (subsampLevel == TJ_GRAYSCALE && qualityLevel != -1) {
- CARD32 r=(colorValue>>16)&0xFF;
- CARD32 g=(colorValue>>8)&0xFF;
- CARD32 b=(colorValue)&0xFF;
- double y=(0.257*(double)r)+(0.504*(double)g)
- +(0.098*(double)b)+16.;
- colorValue=(int)y+(((int)y)<<8)+(((int)y)<<16);
- }
-
- /* Get dimensions of solid-color area. */
-
- FindBestSolidArea(dx, dy, w - (dx - x), h - (dy - y),
- colorValue, &w_best, &h_best);
-
- /* Make sure a solid rectangle is large enough
- (or the whole rectangle is of the same color). */
-
- if ( w_best * h_best != w * h &&
- w_best * h_best < MIN_SOLID_SUBRECT_SIZE )
- continue;
-
- /* Try to extend solid rectangle to maximum size. */
-
- x_best = dx; y_best = dy;
- ExtendSolidArea(x, y, w, h, colorValue,
- &x_best, &y_best, &w_best, &h_best);
-
- /* Send rectangles at top and left to solid-color area. */
-
- if ( y_best != y &&
- !SendRectSimple(cl, x, y, w, y_best-y) )
- return FALSE;
- if ( x_best != x &&
- !rfbSendRectEncodingTight(cl, x, y_best,
- x_best-x, h_best) )
- return FALSE;
-
- /* Send solid-color rectangle. */
-
- if (!SendTightHeader(cl, x_best, y_best, w_best, h_best))
- return FALSE;
-
- fbptr = (rfbScreen.pfbMemory +
- (rfbScreen.paddedWidthInBytes * y_best) +
- (x_best * (rfbScreen.bitsPerPixel / 8)));
-
- (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat,
- &cl->format, fbptr, tightBeforeBuf,
- rfbScreen.paddedWidthInBytes, 1, 1);
-
- if (!SendSolidRect(cl))
- return FALSE;
-
- /* Send remaining rectangles (at right and bottom). */
-
- if ( x_best + w_best != x + w &&
- !rfbSendRectEncodingTight(cl, x_best+w_best, y_best,
- w-(x_best-x)-w_best, h_best) )
- return FALSE;
- if ( y_best + h_best != y + h &&
- !rfbSendRectEncodingTight(cl, x, y_best+h_best,
- w, h-(y_best-y)-h_best) )
- return FALSE;
-
- /* Return after all recursive calls are done. */
-
- return TRUE;
- }
-
- }
-
- }
-
- /* No suitable solid-color rectangles found. */
-
- return SendRectSimple(cl, x, y, w, h);
-}
-
-static void
-FindBestSolidArea(x, y, w, h, colorValue, w_ptr, h_ptr)
- int x, y, w, h;
- CARD32 colorValue;
- int *w_ptr, *h_ptr;
-{
- int dx, dy, dw, dh;
- int w_prev;
- int w_best = 0, h_best = 0;
-
- w_prev = w;
-
- for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) {
-
- dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ?
- MAX_SPLIT_TILE_SIZE : (y + h - dy);
- dw = (w_prev > MAX_SPLIT_TILE_SIZE) ?
- MAX_SPLIT_TILE_SIZE : w_prev;
-
- if (!CheckSolidTile(x, dy, dw, dh, &colorValue, TRUE))
- break;
-
- for (dx = x + dw; dx < x + w_prev;) {
- dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w_prev) ?
- MAX_SPLIT_TILE_SIZE : (x + w_prev - dx);
- if (!CheckSolidTile(dx, dy, dw, dh, &colorValue, TRUE))
- break;
- dx += dw;
- }
-
- w_prev = dx - x;
- if (w_prev * (dy + dh - y) > w_best * h_best) {
- w_best = w_prev;
- h_best = dy + dh - y;
- }
- }
-
- *w_ptr = w_best;
- *h_ptr = h_best;
-}
-
-static void
-ExtendSolidArea(x, y, w, h, colorValue, x_ptr, y_ptr, w_ptr, h_ptr)
- int x, y, w, h;
- CARD32 colorValue;
- int *x_ptr, *y_ptr, *w_ptr, *h_ptr;
-{
- int cx, cy;
-
- /* Try to extend the area upwards. */
- for ( cy = *y_ptr - 1;
- cy >= y && CheckSolidTile(*x_ptr, cy, *w_ptr, 1, &colorValue, TRUE);
- cy-- );
- *h_ptr += *y_ptr - (cy + 1);
- *y_ptr = cy + 1;
-
- /* ... downwards. */
- for ( cy = *y_ptr + *h_ptr;
- cy < y + h &&
- CheckSolidTile(*x_ptr, cy, *w_ptr, 1, &colorValue, TRUE);
- cy++ );
- *h_ptr += cy - (*y_ptr + *h_ptr);
-
- /* ... to the left. */
- for ( cx = *x_ptr - 1;
- cx >= x && CheckSolidTile(cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE);
- cx-- );
- *w_ptr += *x_ptr - (cx + 1);
- *x_ptr = cx + 1;
-
- /* ... to the right. */
- for ( cx = *x_ptr + *w_ptr;
- cx < x + w &&
- CheckSolidTile(cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE);
- cx++ );
- *w_ptr += cx - (*x_ptr + *w_ptr);
-}
-
-/*
- * Check if a rectangle is all of the same color. If needSameColor is
- * set to non-zero, then also check that its color equals to the
- * *colorPtr value. The result is 1 if the test is successfull, and in
- * that case new color will be stored in *colorPtr.
- */
-
-static Bool
-CheckSolidTile(x, y, w, h, colorPtr, needSameColor)
- int x, y, w, h;
- CARD32 *colorPtr;
- Bool needSameColor;
-{
- switch(rfbServerFormat.bitsPerPixel) {
- case 32:
- return CheckSolidTile32(x, y, w, h, colorPtr, needSameColor);
- case 16:
- return CheckSolidTile16(x, y, w, h, colorPtr, needSameColor);
- default:
- return CheckSolidTile8(x, y, w, h, colorPtr, needSameColor);
- }
-}
-
-#define DEFINE_CHECK_SOLID_FUNCTION(bpp) \
- \
-static Bool \
-CheckSolidTile##bpp(x, y, w, h, colorPtr, needSameColor) \
- int x, y, w, h; \
- CARD32 *colorPtr; \
- Bool needSameColor; \
-{ \
- CARD##bpp *fbptr; \
- CARD##bpp colorValue; \
- int dx, dy; \
- \
- fbptr = (CARD##bpp *) \
- &rfbScreen.pfbMemory[y * rfbScreen.paddedWidthInBytes + x * (bpp/8)]; \
- \
- colorValue = *fbptr; \
- if (needSameColor && (CARD32)colorValue != *colorPtr) \
- return FALSE; \
- \
- for (dy = 0; dy < h; dy++) { \
- for (dx = 0; dx < w; dx++) { \
- if (colorValue != fbptr[dx]) \
- return FALSE; \
- } \
- fbptr = (CARD##bpp *)((CARD8 *)fbptr + rfbScreen.paddedWidthInBytes); \
- } \
- \
- *colorPtr = (CARD32)colorValue; \
- return TRUE; \
-}
-
-DEFINE_CHECK_SOLID_FUNCTION(8)
-DEFINE_CHECK_SOLID_FUNCTION(16)
-DEFINE_CHECK_SOLID_FUNCTION(32)
-
-static Bool
-SendRectSimple(cl, x, y, w, h)
- rfbClientPtr cl;
- int x, y, w, h;
-{
- int maxBeforeSize, maxAfterSize;
- int maxRectSize, maxRectWidth;
- int subrectMaxWidth, subrectMaxHeight;
- int dx, dy;
- int rw, rh;
-
- maxRectSize = tightConf[compressLevel].maxRectSize;
- maxRectWidth = tightConf[compressLevel].maxRectWidth;
-
- maxBeforeSize = maxRectSize * (cl->format.bitsPerPixel / 8);
- maxAfterSize = maxBeforeSize + (maxBeforeSize + 99) / 100 + 12;
-
- if (tightBeforeBufSize < maxBeforeSize) {
- tightBeforeBufSize = maxBeforeSize;
- if (tightBeforeBuf == NULL)
- tightBeforeBuf = (char *)xalloc(tightBeforeBufSize);
- else
- tightBeforeBuf = (char *)xrealloc(tightBeforeBuf,
- tightBeforeBufSize);
- }
-
- if (tightAfterBufSize < maxAfterSize) {
- tightAfterBufSize = maxAfterSize;
- if (tightAfterBuf == NULL)
- tightAfterBuf = (char *)xalloc(tightAfterBufSize);
- else
- tightAfterBuf = (char *)xrealloc(tightAfterBuf,
- tightAfterBufSize);
- }
-
- if (w > maxRectWidth || w * h > maxRectSize) {
- subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w;
- subrectMaxHeight = maxRectSize / subrectMaxWidth;
-
- for (dy = 0; dy < h; dy += subrectMaxHeight) {
- for (dx = 0; dx < w; dx += maxRectWidth) {
- rw = (dx + maxRectWidth < w) ? maxRectWidth : w - dx;
- rh = (dy + subrectMaxHeight < h) ? subrectMaxHeight : h - dy;
- if (!SendSubrect(cl, x+dx, y+dy, rw, rh))
- return FALSE;
- }
- }
- } else {
- if (!SendSubrect(cl, x, y, w, h))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static Bool
-SendSubrect(cl, x, y, w, h)
- rfbClientPtr cl;
- int x, y, w, h;
-{
- char *fbptr;
- Bool success = FALSE;
-
- /* Send pending data if there is more than 128 bytes. */
- if (ublen > 128) {
- if (!rfbSendUpdateBuf(cl))
- return FALSE;
- }
-
- if (!SendTightHeader(cl, x, y, w, h))
- return FALSE;
-
- fbptr = (rfbScreen.pfbMemory + (rfbScreen.paddedWidthInBytes * y)
- + (x * (rfbScreen.bitsPerPixel / 8)));
-
- if (subsampLevel == TJ_GRAYSCALE && qualityLevel != -1)
- return SendJpegRect(cl, x, y, w, h, qualityLevel);
-
- paletteMaxColors = w * h / tightConf[compressLevel].idxMaxColorsDivisor;
- if(qualityLevel != -1)
- paletteMaxColors = 24;
- if ( paletteMaxColors < 2 &&
- w * h >= tightConf[compressLevel].monoMinRectSize ) {
- paletteMaxColors = 2;
- }
-
- if (cl->format.bitsPerPixel == rfbServerFormat.bitsPerPixel &&
- cl->format.redMax == rfbServerFormat.redMax &&
- cl->format.greenMax == rfbServerFormat.greenMax &&
- cl->format.blueMax == rfbServerFormat.blueMax &&
- cl->format.bitsPerPixel >= 16) {
-
- /* This is so we can avoid translating the pixels when compressing
- with JPEG, since it is unnecessary */
- switch (cl->format.bitsPerPixel) {
- case 16:
- FastFillPalette16(cl, (CARD16 *)fbptr, w,
- rfbScreen.paddedWidthInBytes/2, h);
- break;
- default:
- FastFillPalette32(cl, (CARD32 *)fbptr, w,
- rfbScreen.paddedWidthInBytes/4, h);
- }
-
- if(paletteNumColors != 0 || qualityLevel == -1) {
- (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat,
- &cl->format, fbptr, tightBeforeBuf,
- rfbScreen.paddedWidthInBytes, w, h);
- }
- }
- else {
- (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat,
- &cl->format, fbptr, tightBeforeBuf,
- rfbScreen.paddedWidthInBytes, w, h);
-
- switch (cl->format.bitsPerPixel) {
- case 8:
- FillPalette8(w * h);
- break;
- case 16:
- FillPalette16(w * h);
- break;
- default:
- FillPalette32(w * h);
- }
- }
-
- switch (paletteNumColors) {
- case 0:
- /* Truecolor image */
- if (qualityLevel != -1) {
- success = SendJpegRect(cl, x, y, w, h, qualityLevel);
- } else {
- success = SendFullColorRect(cl, w, h);
- }
- break;
- case 1:
- /* Solid rectangle */
- success = SendSolidRect(cl);
- break;
- case 2:
- /* Two-color rectangle */
- success = SendMonoRect(cl, w, h);
- break;
- default:
- /* Up to 256 different colors */
- success = SendIndexedRect(cl, w, h);
- }
- return success;
-}
-
-static Bool
-SendTightHeader(cl, x, y, w, h)
- rfbClientPtr cl;
- int x, y, w, h;
-{
- rfbFramebufferUpdateRectHeader rect;
-
- if (ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
- if (!rfbSendUpdateBuf(cl))
- return FALSE;
- }
-
- rect.r.x = Swap16IfLE(x);
- rect.r.y = Swap16IfLE(y);
- rect.r.w = Swap16IfLE(w);
- rect.r.h = Swap16IfLE(h);
- rect.encoding = Swap32IfLE(rfbEncodingTight);
-
- memcpy(&updateBuf[ublen], (char *)&rect,
- sz_rfbFramebufferUpdateRectHeader);
- ublen += sz_rfbFramebufferUpdateRectHeader;
-
- cl->rfbRectanglesSent[rfbEncodingTight]++;
- cl->rfbBytesSent[rfbEncodingTight] += sz_rfbFramebufferUpdateRectHeader;
-
- return TRUE;
-}
-
-/*
- * Subencoding implementations.
- */
-
-static Bool
-SendSolidRect(cl)
- rfbClientPtr cl;
-{
- int len;
-
- if (usePixelFormat24) {
- Pack24(tightBeforeBuf, &cl->format, 1);
- len = 3;
- } else
- len = cl->format.bitsPerPixel / 8;
-
- if (ublen + 1 + len > UPDATE_BUF_SIZE) {
- if (!rfbSendUpdateBuf(cl))
- return FALSE;
- }
-
- updateBuf[ublen++] = (char)(rfbTightFill << 4);
- memcpy (&updateBuf[ublen], tightBeforeBuf, len);
- ublen += len;
-
- cl->rfbBytesSent[rfbEncodingTight] += len + 1;
-
- return TRUE;
-}
-
-static Bool
-SendMonoRect(cl, w, h)
- rfbClientPtr cl;
- int w, h;
-{
- int streamId = 1;
- int paletteLen, dataLen;
-
- if ( (ublen + TIGHT_MIN_TO_COMPRESS + 6 +
- 2 * cl->format.bitsPerPixel / 8) > UPDATE_BUF_SIZE ) {
- if (!rfbSendUpdateBuf(cl))
- return FALSE;
- }
-
- /* Prepare tight encoding header. */
- dataLen = (w + 7) / 8;
- dataLen *= h;
-
- if (tightConf[compressLevel].monoZlibLevel == 0)
- updateBuf[ublen++] = (char)((rfbTightNoZlib | rfbTightExplicitFilter) << 4);
- else
- updateBuf[ublen++] = (streamId | rfbTightExplicitFilter) << 4;
- updateBuf[ublen++] = rfbTightFilterPalette;
- updateBuf[ublen++] = 1;
-
- /* Prepare palette, convert image. */
- switch (cl->format.bitsPerPixel) {
-
- case 32:
- EncodeMonoRect32((CARD8 *)tightBeforeBuf, w, h);
-
- ((CARD32 *)tightAfterBuf)[0] = monoBackground;
- ((CARD32 *)tightAfterBuf)[1] = monoForeground;
- if (usePixelFormat24) {
- Pack24(tightAfterBuf, &cl->format, 2);
- paletteLen = 6;
- } else
- paletteLen = 8;
-
- memcpy(&updateBuf[ublen], tightAfterBuf, paletteLen);
- ublen += paletteLen;
- cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteLen;
- break;
-
- case 16:
- EncodeMonoRect16((CARD8 *)tightBeforeBuf, w, h);
-
- ((CARD16 *)tightAfterBuf)[0] = (CARD16)monoBackground;
- ((CARD16 *)tightAfterBuf)[1] = (CARD16)monoForeground;
-
- memcpy(&updateBuf[ublen], tightAfterBuf, 4);
- ublen += 4;
- cl->rfbBytesSent[rfbEncodingTight] += 7;
- break;
-
- default:
- EncodeMonoRect8((CARD8 *)tightBeforeBuf, w, h);
-
- updateBuf[ublen++] = (char)monoBackground;
- updateBuf[ublen++] = (char)monoForeground;
- cl->rfbBytesSent[rfbEncodingTight] += 5;
- }
-
- return CompressData(cl, streamId, dataLen,
- tightConf[compressLevel].monoZlibLevel,
- Z_DEFAULT_STRATEGY);
-}
-
-static Bool
-SendIndexedRect(cl, w, h)
- rfbClientPtr cl;
- int w, h;
-{
- int streamId = 2;
- int i, entryLen;
-
- if ( (ublen + TIGHT_MIN_TO_COMPRESS + 6 +
- paletteNumColors * cl->format.bitsPerPixel / 8) > UPDATE_BUF_SIZE ) {
- if (!rfbSendUpdateBuf(cl))
- return FALSE;
- }
-
- /* Prepare tight encoding header. */
- if (tightConf[compressLevel].idxZlibLevel == 0)
- updateBuf[ublen++] = (char)((rfbTightNoZlib | rfbTightExplicitFilter) << 4);
- else
- updateBuf[ublen++] = (streamId | rfbTightExplicitFilter) << 4;
- updateBuf[ublen++] = rfbTightFilterPalette;
- updateBuf[ublen++] = (char)(paletteNumColors - 1);
-
- /* Prepare palette, convert image. */
- switch (cl->format.bitsPerPixel) {
-
- case 32:
- EncodeIndexedRect32((CARD8 *)tightBeforeBuf, w * h);
-
- for (i = 0; i < paletteNumColors; i++) {
- ((CARD32 *)tightAfterBuf)[i] =
- palette.entry[i].listNode->rgb;
- }
- if (usePixelFormat24) {
- Pack24(tightAfterBuf, &cl->format, paletteNumColors);
- entryLen = 3;
- } else
- entryLen = 4;
-
- memcpy(&updateBuf[ublen], tightAfterBuf, paletteNumColors * entryLen);
- ublen += paletteNumColors * entryLen;
- cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteNumColors * entryLen;
- break;
-
- case 16:
- EncodeIndexedRect16((CARD8 *)tightBeforeBuf, w * h);
-
- for (i = 0; i < paletteNumColors; i++) {
- ((CARD16 *)tightAfterBuf)[i] =
- (CARD16)palette.entry[i].listNode->rgb;
- }
-
- memcpy(&updateBuf[ublen], tightAfterBuf, paletteNumColors * 2);
- ublen += paletteNumColors * 2;
- cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteNumColors * 2;
- break;
-
- default:
- return FALSE; /* Should never happen. */
- }
-
- return CompressData(cl, streamId, w * h,
- tightConf[compressLevel].idxZlibLevel,
- Z_DEFAULT_STRATEGY);
-}
-
-static Bool
-SendFullColorRect(cl, w, h)
- rfbClientPtr cl;
- int w, h;
-{
- int streamId = 0;
- int len;
-
- if (ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) {
- if (!rfbSendUpdateBuf(cl))
- return FALSE;
- }
-
- if (tightConf[compressLevel].rawZlibLevel == 0)
- updateBuf[ublen++] = (char)(rfbTightNoZlib << 4);
- else
- updateBuf[ublen++] = 0x00; /* stream id = 0, no flushing, no filter */
- cl->rfbBytesSent[rfbEncodingTight]++;
-
- if (usePixelFormat24) {
- Pack24(tightBeforeBuf, &cl->format, w * h);
- len = 3;
- } else
- len = cl->format.bitsPerPixel / 8;
-
- return CompressData(cl, streamId, w * h * len,
- tightConf[compressLevel].rawZlibLevel,
- Z_DEFAULT_STRATEGY);
-}
-
-static Bool
-CompressData(cl, streamId, dataLen, zlibLevel, zlibStrategy)
- rfbClientPtr cl;
- int streamId, dataLen, zlibLevel, zlibStrategy;
-{
- z_streamp pz;
- int err, i;
-
- if (dataLen < TIGHT_MIN_TO_COMPRESS) {
- memcpy(&updateBuf[ublen], tightBeforeBuf, dataLen);
- ublen += dataLen;
- cl->rfbBytesSent[rfbEncodingTight] += dataLen;
- return TRUE;
- }
-
- if (zlibLevel == 0)
- return SendCompressedData (cl, tightBeforeBuf, dataLen);
-
- pz = &cl->zsStruct[streamId];
-
- /* Initialize compression stream if needed. */
- if (!cl->zsActive[streamId]) {
- pz->zalloc = Z_NULL;
- pz->zfree = Z_NULL;
- pz->opaque = Z_NULL;
-
- err = deflateInit2 (pz, zlibLevel, Z_DEFLATED, MAX_WBITS,
- MAX_MEM_LEVEL, zlibStrategy);
- if (err != Z_OK)
- return FALSE;
-
- cl->zsActive[streamId] = TRUE;
- cl->zsLevel[streamId] = zlibLevel;
- }
-
- /* Prepare buffer pointers. */
- pz->next_in = (Bytef *)tightBeforeBuf;
- pz->avail_in = dataLen;
- pz->next_out = (Bytef *)tightAfterBuf;
- pz->avail_out = tightAfterBufSize;
-
- /* Change compression parameters if needed. */
- if (zlibLevel != cl->zsLevel[streamId]) {
- if (deflateParams (pz, zlibLevel, zlibStrategy) != Z_OK) {
- return FALSE;
- }
- cl->zsLevel[streamId] = zlibLevel;
- }
-
- /* Actual compression. */
- if ( deflate (pz, Z_SYNC_FLUSH) != Z_OK ||
- pz->avail_in != 0 || pz->avail_out == 0 ) {
- return FALSE;
- }
-
- return SendCompressedData(cl, tightAfterBuf,
- tightAfterBufSize - pz->avail_out);
-}
-
-static Bool SendCompressedData(cl, buf, compressedLen)
- rfbClientPtr cl;
- char *buf;
- int compressedLen;
-{
- int i, portionLen;
-
- updateBuf[ublen++] = compressedLen & 0x7F;
- cl->rfbBytesSent[rfbEncodingTight]++;
- if (compressedLen > 0x7F) {
- updateBuf[ublen-1] |= 0x80;
- updateBuf[ublen++] = compressedLen >> 7 & 0x7F;
- cl->rfbBytesSent[rfbEncodingTight]++;
- if (compressedLen > 0x3FFF) {
- updateBuf[ublen-1] |= 0x80;
- updateBuf[ublen++] = compressedLen >> 14 & 0xFF;
- cl->rfbBytesSent[rfbEncodingTight]++;
- }
- }
-
- portionLen = UPDATE_BUF_SIZE;
- for (i = 0; i < compressedLen; i += portionLen) {
- if (i + portionLen > compressedLen) {
- portionLen = compressedLen - i;
- }
- if (ublen + portionLen > UPDATE_BUF_SIZE) {
- if (!rfbSendUpdateBuf(cl))
- return FALSE;
- }
- memcpy(&updateBuf[ublen], &buf[i], portionLen);
- ublen += portionLen;
- }
- cl->rfbBytesSent[rfbEncodingTight] += compressedLen;
- return TRUE;
-}
-
-/*
- * Code to determine how many different colors used in rectangle.
- */
-
-static void
-FillPalette8(count)
- int count;
-{
- CARD8 *data = (CARD8 *)tightBeforeBuf;
- CARD8 c0, c1;
- int i, n0, n1;
-
- paletteNumColors = 0;
-
- c0 = data[0];
- for (i = 1; i < count && data[i] == c0; i++);
- if (i == count) {
- paletteNumColors = 1;
- return; /* Solid rectangle */
- }
-
- if (paletteMaxColors < 2)
- return;
-
- n0 = i;
- c1 = data[i];
- n1 = 0;
- for (i++; i < count; i++) {
- if (data[i] == c0) {
- n0++;
- } else if (data[i] == c1) {
- n1++;
- } else
- break;
- }
- if (i == count) {
- if (n0 > n1) {
- monoBackground = (CARD32)c0;
- monoForeground = (CARD32)c1;
- } else {
- monoBackground = (CARD32)c1;
- monoForeground = (CARD32)c0;
- }
- paletteNumColors = 2; /* Two colors */
- }
-}
-
-#define DEFINE_FILL_PALETTE_FUNCTION(bpp) \
- \
-static void \
-FillPalette##bpp(count) \
- int count; \
-{ \
- CARD##bpp *data = (CARD##bpp *)tightBeforeBuf; \
- CARD##bpp c0, c1, ci; \
- int i, n0, n1, ni; \
- \
- c0 = data[0]; \
- for (i = 1; i < count && data[i] == c0; i++); \
- if (i >= count) { \
- paletteNumColors = 1; /* Solid rectangle */ \
- return; \
- } \
- \
- if (paletteMaxColors < 2) { \
- paletteNumColors = 0; /* Full-color encoding preferred */ \
- return; \
- } \
- \
- n0 = i; \
- c1 = data[i]; \
- n1 = 0; \
- for (i++; i < count; i++) { \
- ci = data[i]; \
- if (ci == c0) { \
- n0++; \
- } else if (ci == c1) { \
- n1++; \
- } else \
- break; \
- } \
- if (i >= count) { \
- if (n0 > n1) { \
- monoBackground = (CARD32)c0; \
- monoForeground = (CARD32)c1; \
- } else { \
- monoBackground = (CARD32)c1; \
- monoForeground = (CARD32)c0; \
- } \
- paletteNumColors = 2; /* Two colors */ \
- return; \
- } \
- \
- PaletteReset(); \
- PaletteInsert (c0, (CARD32)n0, bpp); \
- PaletteInsert (c1, (CARD32)n1, bpp); \
- \
- ni = 1; \
- for (i++; i < count; i++) { \
- if (data[i] == ci) { \
- ni++; \
- } else { \
- if (!PaletteInsert (ci, (CARD32)ni, bpp)) \
- return; \
- ci = data[i]; \
- ni = 1; \
- } \
- } \
- PaletteInsert (ci, (CARD32)ni, bpp); \
-}
-
-DEFINE_FILL_PALETTE_FUNCTION(16)
-DEFINE_FILL_PALETTE_FUNCTION(32)
-
-#define DEFINE_FAST_FILL_PALETTE_FUNCTION(bpp) \
- \
-static void \
-FastFillPalette##bpp(cl, data, w, pitch, h) \
- rfbClientPtr cl; \
- CARD##bpp *data; \
- int w, pitch, h; \
-{ \
- CARD##bpp c0, c1, ci, mask, c0t, c1t, cit; \
- int i, j, i2, j2, n0, n1, ni; \
- \
- if (cl->translateFn != rfbTranslateNone) { \
- mask = rfbServerFormat.redMax << rfbServerFormat.redShift; \
- mask |= rfbServerFormat.greenMax << rfbServerFormat.greenShift; \
- mask |= rfbServerFormat.blueMax << rfbServerFormat.blueShift; \
- } else mask = ~0; \
- \
- c0 = data[0] & mask; \
- for (j = 0; j < h; j++) { \
- for (i = 0; i < w; i++) { \
- if ((data[j * pitch + i] & mask) != c0) \
- goto done; \
- } \
- } \
- done: \
- if (j >= h) { \
- paletteNumColors = 1; /* Solid rectangle */ \
- return; \
- } \
- if (paletteMaxColors < 2) { \
- paletteNumColors = 0; /* Full-color encoding preferred */ \
- return; \
- } \
- \
- n0 = j * w + i; \
- c1 = data[j * pitch + i] & mask; \
- n1 = 0; \
- i++; if (i >= w) {i = 0; j++;} \
- for (j2 = j; j2 < h; j2++) { \
- for (i2 = i; i2 < w; i2++) { \
- ci = data[j2 * pitch + i2] & mask; \
- if (ci == c0) { \
- n0++; \
- } else if (ci == c1) { \
- n1++; \
- } else \
- goto done2; \
- } \
- i = 0; \
- } \
- done2: \
- (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat, \
- &cl->format, (char *)&c0, (char *)&c0t, bpp/8, \
- 1, 1); \
- (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat, \
- &cl->format, (char *)&c1, (char *)&c1t, bpp/8, \
- 1, 1); \
- if (j2 >= h) { \
- if (n0 > n1) { \
- monoBackground = (CARD32)c0t; \
- monoForeground = (CARD32)c1t; \
- } else { \
- monoBackground = (CARD32)c1t; \
- monoForeground = (CARD32)c0t; \
- } \
- paletteNumColors = 2; /* Two colors */ \
- return; \
- } \
- \
- PaletteReset(); \
- PaletteInsert (c0t, (CARD32)n0, bpp); \
- PaletteInsert (c1t, (CARD32)n1, bpp); \
- \
- ni = 1; \
- i2++; if (i2 >= w) {i2 = 0; j2++;} \
- for (j = j2; j < h; j++) { \
- for (i = i2; i < w; i++) { \
- if ((data[j * pitch + i] & mask) == ci) { \
- ni++; \
- } else { \
- (*cl->translateFn)(cl->translateLookupTable, \
- &rfbServerFormat, &cl->format, \
- (char *)&ci, (char *)&cit, bpp/8, \
- 1, 1); \
- if (!PaletteInsert (cit, (CARD32)ni, bpp)) \
- return; \
- ci = data[j * pitch + i] & mask; \
- ni = 1; \
- } \
- } \
- i2 = 0; \
- } \
- \
- (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat, \
- &cl->format, (char *)&ci, (char *)&cit, bpp/8, \
- 1, 1); \
- PaletteInsert (cit, (CARD32)ni, bpp); \
-}
-
-DEFINE_FAST_FILL_PALETTE_FUNCTION(16)
-DEFINE_FAST_FILL_PALETTE_FUNCTION(32)
-
-
-/*
- * Functions to operate with palette structures.
- */
-
-#define HASH_FUNC16(rgb) ((int)((((rgb) >> 8) + (rgb)) & 0xFF))
-#define HASH_FUNC32(rgb) ((int)((((rgb) >> 16) + ((rgb) >> 8)) & 0xFF))
-
-static void
-PaletteReset(void)
-{
- paletteNumColors = 0;
- memset(palette.hash, 0, 256 * sizeof(COLOR_LIST *));
-}
-
-static int
-PaletteInsert(rgb, numPixels, bpp)
- CARD32 rgb;
- int numPixels;
- int bpp;
-{
- COLOR_LIST *pnode;
- COLOR_LIST *prev_pnode = NULL;
- int hash_key, idx, new_idx, count;
-
- hash_key = (bpp == 16) ? HASH_FUNC16(rgb) : HASH_FUNC32(rgb);
-
- pnode = palette.hash[hash_key];
-
- while (pnode != NULL) {
- if (pnode->rgb == rgb) {
- /* Such palette entry already exists. */
- new_idx = idx = pnode->idx;
- count = palette.entry[idx].numPixels + numPixels;
- if (new_idx && palette.entry[new_idx-1].numPixels < count) {
- do {
- palette.entry[new_idx] = palette.entry[new_idx-1];
- palette.entry[new_idx].listNode->idx = new_idx;
- new_idx--;
- }
- while (new_idx && palette.entry[new_idx-1].numPixels < count);
- palette.entry[new_idx].listNode = pnode;
- pnode->idx = new_idx;
- }
- palette.entry[new_idx].numPixels = count;
- return paletteNumColors;
- }
- prev_pnode = pnode;
- pnode = pnode->next;
- }
-
- /* Check if palette is full. */
- if (paletteNumColors == 256 || paletteNumColors == paletteMaxColors) {
- paletteNumColors = 0;
- return 0;
- }
-
- /* Move palette entries with lesser pixel counts. */
- for ( idx = paletteNumColors;
- idx > 0 && palette.entry[idx-1].numPixels < numPixels;
- idx-- ) {
- palette.entry[idx] = palette.entry[idx-1];
- palette.entry[idx].listNode->idx = idx;
- }
-
- /* Add new palette entry into the freed slot. */
- pnode = &palette.list[paletteNumColors];
- if (prev_pnode != NULL) {
- prev_pnode->next = pnode;
- } else {
- palette.hash[hash_key] = pnode;
- }
- pnode->next = NULL;
- pnode->idx = idx;
- pnode->rgb = rgb;
- palette.entry[idx].listNode = pnode;
- palette.entry[idx].numPixels = numPixels;
-
- return (++paletteNumColors);
-}
-
-
-/*
- * Converting 32-bit color samples into 24-bit colors.
- * Should be called only when redMax, greenMax and blueMax are 255.
- * Color components assumed to be byte-aligned.
- */
-
-static void Pack24(buf, fmt, count)
- char *buf;
- rfbPixelFormat *fmt;
- int count;
-{
- CARD32 *buf32;
- CARD32 pix;
- int r_shift, g_shift, b_shift;
-
- buf32 = (CARD32 *)buf;
-
- if (!rfbServerFormat.bigEndian == !fmt->bigEndian) {
- r_shift = fmt->redShift;
- g_shift = fmt->greenShift;
- b_shift = fmt->blueShift;
- } else {
- r_shift = 24 - fmt->redShift;
- g_shift = 24 - fmt->greenShift;
- b_shift = 24 - fmt->blueShift;
- }
-
- while (count--) {
- pix = *buf32++;
- *buf++ = (char)(pix >> r_shift);
- *buf++ = (char)(pix >> g_shift);
- *buf++ = (char)(pix >> b_shift);
- }
-}
-
-
-/*
- * Converting truecolor samples into palette indices.
- */
-
-#define DEFINE_IDX_ENCODE_FUNCTION(bpp) \
- \
-static void \
-EncodeIndexedRect##bpp(buf, count) \
- CARD8 *buf; \
- int count; \
-{ \
- COLOR_LIST *pnode; \
- CARD##bpp *src; \
- CARD##bpp rgb; \
- int rep = 0; \
- \
- src = (CARD##bpp *) buf; \
- \
- while (count--) { \
- rgb = *src++; \
- while (count && *src == rgb) { \
- rep++, src++, count--; \
- } \
- pnode = palette.hash[HASH_FUNC##bpp(rgb)]; \
- while (pnode != NULL) { \
- if ((CARD##bpp)pnode->rgb == rgb) { \
- *buf++ = (CARD8)pnode->idx; \
- while (rep) { \
- *buf++ = (CARD8)pnode->idx; \
- rep--; \
- } \
- break; \
- } \
- pnode = pnode->next; \
- } \
- } \
-}
-
-DEFINE_IDX_ENCODE_FUNCTION(16)
-DEFINE_IDX_ENCODE_FUNCTION(32)
-
-#define DEFINE_MONO_ENCODE_FUNCTION(bpp) \
- \
-static void \
-EncodeMonoRect##bpp(buf, w, h) \
- CARD8 *buf; \
- int w, h; \
-{ \
- CARD##bpp *ptr; \
- CARD##bpp bg; \
- unsigned int value, mask; \
- int aligned_width; \
- int x, y, bg_bits; \
- \
- ptr = (CARD##bpp *) buf; \
- bg = (CARD##bpp) monoBackground; \
- aligned_width = w - w % 8; \
- \
- for (y = 0; y < h; y++) { \
- for (x = 0; x < aligned_width; x += 8) { \
- for (bg_bits = 0; bg_bits < 8; bg_bits++) { \
- if (*ptr++ != bg) \
- break; \
- } \
- if (bg_bits == 8) { \
- *buf++ = 0; \
- continue; \
- } \
- mask = 0x80 >> bg_bits; \
- value = mask; \
- for (bg_bits++; bg_bits < 8; bg_bits++) { \
- mask >>= 1; \
- if (*ptr++ != bg) { \
- value |= mask; \
- } \
- } \
- *buf++ = (CARD8)value; \
- } \
- \
- mask = 0x80; \
- value = 0; \
- if (x >= w) \
- continue; \
- \
- for (; x < w; x++) { \
- if (*ptr++ != bg) { \
- value |= mask; \
- } \
- mask >>= 1; \
- } \
- *buf++ = (CARD8)value; \
- } \
-}
-
-DEFINE_MONO_ENCODE_FUNCTION(8)
-DEFINE_MONO_ENCODE_FUNCTION(16)
-DEFINE_MONO_ENCODE_FUNCTION(32)
-
-/*
- * JPEG compression stuff.
- */
-
-static unsigned long jpegDstDataLen;
-static tjhandle j=NULL;
-
-static Bool
-SendJpegRect(cl, x, y, w, h, quality)
- rfbClientPtr cl;
- int x, y, w, h;
- int quality;
-{
- int dy;
- unsigned char *srcbuf;
- int ps=rfbServerFormat.bitsPerPixel/8;
- int subsamp=subsampLevel2tjsubsamp[subsampLevel];
- unsigned long size=0;
- int flags=0, pitch;
- unsigned char *tmpbuf=NULL;
-
- if (rfbServerFormat.bitsPerPixel == 8)
- return SendFullColorRect(cl, w, h);
-
-
- if(ps<2) {
- rfbLog("Error: JPEG requires 16-bit, 24-bit, or 32-bit pixel format.\n");
- return 0;
- }
- if(!j) {
- if((j=tjInitCompress())==NULL) {
- rfbLog("JPEG Error: %s\n", tjGetErrorStr()); return 0;
- }
- }
-
- if (tightAfterBufSize < TJBUFSIZE(w,h)) {
- if (tightAfterBuf == NULL)
- tightAfterBuf = (char *)xalloc(TJBUFSIZE(w,h));
- else
- tightAfterBuf = (char *)xrealloc(tightAfterBuf,
- TJBUFSIZE(w,h));
- if(!tightAfterBuf) {
- rfbLog("Memory allocation failure!\n");
- return 0;
- }
- tightAfterBufSize = TJBUFSIZE(w,h);
- }
-
- if (ps == 2) {
- CARD16 *srcptr, pix;
- unsigned char *dst;
- int inRed, inGreen, inBlue, i, j;
-
- if((tmpbuf=(unsigned char *)malloc(w*h*3))==NULL)
- rfbLog("Memory allocation failure!\n");
- srcptr = (CARD16 *)
- &rfbScreen.pfbMemory[y * rfbScreen.paddedWidthInBytes +
- x * ps];
- dst = tmpbuf;
- for(j=0; j<h; j++) {
- CARD16 *srcptr2=srcptr;
- unsigned char *dst2=dst;
- for(i=0; i<w; i++) {
- pix = *srcptr2++;
- inRed = (int)
- (pix >> rfbServerFormat.redShift & rfbServerFormat.redMax);
- inGreen = (int)
- (pix >> rfbServerFormat.greenShift & rfbServerFormat.greenMax);
- inBlue = (int)
- (pix >> rfbServerFormat.blueShift & rfbServerFormat.blueMax);
- *dst2++ = (CARD8)((inRed * 255 + rfbServerFormat.redMax / 2) /
- rfbServerFormat.redMax);
- *dst2++ = (CARD8)((inGreen * 255 + rfbServerFormat.greenMax / 2) /
- rfbServerFormat.greenMax);
- *dst2++ = (CARD8)((inBlue * 255 + rfbServerFormat.blueMax / 2) /
- rfbServerFormat.blueMax);
- }
- srcptr+=rfbScreen.paddedWidthInBytes/ps;
- dst+=w*3;
- }
- srcbuf = tmpbuf;
- pitch = w*3;
- ps = 3;
- } else {
- if(rfbServerFormat.bigEndian && ps==4) flags|=TJ_ALPHAFIRST;
- if(rfbServerFormat.redShift==16 && rfbServerFormat.blueShift==0)
- flags|=TJ_BGR;
- if(rfbServerFormat.bigEndian) flags^=TJ_BGR;
- srcbuf=(unsigned char *)&rfbScreen.pfbMemory[y *
- rfbScreen.paddedWidthInBytes + x * ps];
- pitch=rfbScreen.paddedWidthInBytes;
- }
-
- if(tjCompress(j, srcbuf, w, pitch, h, ps, (unsigned char *)tightAfterBuf,
- &size, subsamp, quality, flags)==-1) {
- rfbLog("JPEG Error: %s\n", tjGetErrorStr());
- if(tmpbuf) {free(tmpbuf); tmpbuf=NULL;}
- return 0;
- }
- jpegDstDataLen=(int)size;
-
- if(tmpbuf) {free(tmpbuf); tmpbuf=NULL;}
-
- if (ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) {
- if (!rfbSendUpdateBuf(cl))
- return FALSE;
- }
-
- updateBuf[ublen++] = (char)(rfbTightJpeg << 4);
- cl->rfbBytesSent[rfbEncodingTight]++;
-
- return SendCompressedData(cl, tightAfterBuf, jpegDstDataLen);
-}
diff --git a/x11vnc/misc/turbovnc/turbojpeg.h b/x11vnc/misc/turbovnc/turbojpeg.h
deleted file mode 100644
index 8a6af05..0000000
--- a/x11vnc/misc/turbovnc/turbojpeg.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/* Copyright (C)2004 Landmark Graphics
- * Copyright (C)2005, 2006 Sun Microsystems, Inc.
- *
- * This library is free software and may be redistributed and/or modified under
- * the terms of the wxWindows Library License, Version 3 or (at your option)
- * any later version. The full license is in the LICENSE.txt file included
- * with this distribution.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * wxWindows Library License for more details.
- */
-
-#if (defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)) && defined(_WIN32) && defined(DLLDEFINE)
-#define DLLEXPORT __declspec(dllexport)
-#else
-#define DLLEXPORT
-#endif
-
-#define DLLCALL
-
-/* Subsampling */
-#define NUMSUBOPT 4
-
-enum {TJ_444=0, TJ_422, TJ_411, TJ_GRAYSCALE};
-
-/* Flags */
-#define TJ_BGR 1
-#define TJ_BOTTOMUP 2
-#define TJ_FORCEMMX 8 /* Force IPP to use MMX code even if SSE available */
-#define TJ_FORCESSE 16 /* Force IPP to use SSE1 code even if SSE2 available */
-#define TJ_FORCESSE2 32 /* Force IPP to use SSE2 code (useful if auto-detect is not working properly) */
-#define TJ_ALPHAFIRST 64 /* BGR buffer is ABGR and RGB buffer is ARGB */
-#define TJ_FORCESSE3 128 /* Force IPP to use SSE3 code (useful if auto-detect is not working properly) */
-
-typedef void* tjhandle;
-
-#define TJPAD(p) (((p)+3)&(~3))
-#ifndef max
- #define max(a,b) ((a)>(b)?(a):(b))
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* API follows */
-
-
-/*
- tjhandle tjInitCompress(void)
-
- Creates a new JPEG compressor instance, allocates memory for the structures,
- and returns a handle to the instance. Most applications will only
- need to call this once at the beginning of the program or once for each
- concurrent thread. Don't try to create a new instance every time you
- compress an image, because this will cause performance to suffer.
-
- RETURNS: NULL on error
-*/
-DLLEXPORT tjhandle DLLCALL tjInitCompress(void);
-
-
-/*
- int tjCompress(tjhandle j,
- unsigned char *srcbuf, int width, int pitch, int height, int pixelsize,
- unsigned char *dstbuf, unsigned long *size,
- int jpegsubsamp, int jpegqual, int flags)
-
- [INPUT] j = instance handle previously returned from a call to
- tjInitCompress()
- [INPUT] srcbuf = pointer to user-allocated image buffer containing pixels in
- RGB(A) or BGR(A) form
- [INPUT] width = width (in pixels) of the source image
- [INPUT] pitch = bytes per line of the source image (width*pixelsize if the
- bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the bitmap
- is padded to the nearest 32-bit boundary, such as is the case for Windows
- bitmaps. You can also be clever and use this parameter to skip lines, etc.,
- as long as the pitch is greater than 0.)
- [INPUT] height = height (in pixels) of the source image
- [INPUT] pixelsize = size (in bytes) of each pixel in the source image
- RGBA and BGRA: 4, RGB and BGR: 3
- [INPUT] dstbuf = pointer to user-allocated image buffer which will receive
- the JPEG image. Use the macro TJBUFSIZE(width, height) to determine
- the appropriate size for this buffer based on the image width and height.
- [OUTPUT] size = pointer to unsigned long which receives the size (in bytes)
- of the compressed image
- [INPUT] jpegsubsamp = Specifies either 4:1:1, 4:2:2, or 4:4:4 subsampling.
- When the image is converted from the RGB to YCbCr colorspace as part of the
- JPEG compression process, every other Cb and Cr (chrominance) pixel can be
- discarded to produce a smaller image with little perceptible loss of
- image clarity (the human eye is more sensitive to small changes in
- brightness than small changes in color.)
-
- TJ_411: 4:1:1 subsampling. Discards every other Cb, Cr pixel in both
- horizontal and vertical directions.
- TJ_422: 4:2:2 subsampling. Discards every other Cb, Cr pixel only in
- the horizontal direction.
- TJ_444: no subsampling.
- TJ_GRAYSCALE: Generate grayscale JPEG image
-
- [INPUT] jpegqual = JPEG quality (an integer between 0 and 100 inclusive.)
- [INPUT] flags = the bitwise OR of one or more of the following
-
- TJ_BGR: The components of each pixel in the source image are stored in
- B,G,R order, not R,G,B
- TJ_BOTTOMUP: The source image is stored in bottom-up (Windows) order,
- not top-down
- TJ_FORCEMMX: Valid only for the Intel Performance Primitives implementation
- of this codec-- force IPP to use MMX code (bypass CPU auto-detection)
- TJ_FORCESSE: Valid only for the Intel Performance Primitives implementation
- of this codec-- force IPP to use SSE code (bypass CPU auto-detection)
- TJ_FORCESSE2: Valid only for the Intel Performance Primitives implementation
- of this codec-- force IPP to use SSE2 code (bypass CPU auto-detection)
- TJ_FORCESSE3: Valid only for the Intel Performance Primitives implementation
- of this codec-- force IPP to use SSE3 code (bypass CPU auto-detection)
-
- RETURNS: 0 on success, -1 on error
-*/
-DLLEXPORT int DLLCALL tjCompress(tjhandle j,
- unsigned char *srcbuf, int width, int pitch, int height, int pixelsize,
- unsigned char *dstbuf, unsigned long *size,
- int jpegsubsamp, int jpegqual, int flags);
-
-DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height);
-
-/*
- tjhandle tjInitDecompress(void)
-
- Creates a new JPEG decompressor instance, allocates memory for the
- structures, and returns a handle to the instance. Most applications will
- only need to call this once at the beginning of the program or once for each
- concurrent thread. Don't try to create a new instance every time you
- decompress an image, because this will cause performance to suffer.
-
- RETURNS: NULL on error
-*/
-DLLEXPORT tjhandle DLLCALL tjInitDecompress(void);
-
-
-/*
- int tjDecompressHeader(tjhandle j,
- unsigned char *srcbuf, unsigned long size,
- int *width, int *height)
-
- [INPUT] j = instance handle previously returned from a call to
- tjInitDecompress()
- [INPUT] srcbuf = pointer to a user-allocated buffer containing the JPEG image
- to decompress
- [INPUT] size = size of the JPEG image buffer (in bytes)
- [OUTPUT] width = width (in pixels) of the JPEG image
- [OUTPUT] height = height (in pixels) of the JPEG image
-
- RETURNS: 0 on success, -1 on error
-*/
-DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle j,
- unsigned char *srcbuf, unsigned long size,
- int *width, int *height);
-
-
-/*
- int tjDecompress(tjhandle j,
- unsigned char *srcbuf, unsigned long size,
- unsigned char *dstbuf, int width, int pitch, int height, int pixelsize,
- int flags)
-
- [INPUT] j = instance handle previously returned from a call to
- tjInitDecompress()
- [INPUT] srcbuf = pointer to a user-allocated buffer containing the JPEG image
- to decompress
- [INPUT] size = size of the JPEG image buffer (in bytes)
- [INPUT] dstbuf = pointer to user-allocated image buffer which will receive
- the bitmap image. This buffer should normally be pitch*height
- bytes in size, although this pointer may also be used to decompress into
- a specific region of a larger buffer.
- [INPUT] width = width (in pixels) of the destination image
- [INPUT] pitch = bytes per line of the destination image (width*pixelsize if the
- bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the bitmap
- is padded to the nearest 32-bit boundary, such as is the case for Windows
- bitmaps. You can also be clever and use this parameter to skip lines, etc.,
- as long as the pitch is greater than 0.)
- [INPUT] height = height (in pixels) of the destination image
- [INPUT] pixelsize = size (in bytes) of each pixel in the destination image
- RGBA/RGBx and BGRA/BGRx: 4, RGB and BGR: 3
- [INPUT] flags = the bitwise OR of one or more of the following
-
- TJ_BGR: The components of each pixel in the destination image should be
- written in B,G,R order, not R,G,B
- TJ_BOTTOMUP: The destination image should be stored in bottom-up
- (Windows) order, not top-down
- TJ_FORCEMMX: Valid only for the Intel Performance Primitives implementation
- of this codec-- force IPP to use MMX code (bypass CPU auto-detection)
- TJ_FORCESSE: Valid only for the Intel Performance Primitives implementation
- of this codec-- force IPP to use SSE code (bypass CPU auto-detection)
- TJ_FORCESSE2: Valid only for the Intel Performance Primitives implementation
- of this codec-- force IPP to use SSE2 code (bypass CPU auto-detection)
-
- RETURNS: 0 on success, -1 on error
-*/
-DLLEXPORT int DLLCALL tjDecompress(tjhandle j,
- unsigned char *srcbuf, unsigned long size,
- unsigned char *dstbuf, int width, int pitch, int height, int pixelsize,
- int flags);
-
-
-/*
- int tjDestroy(tjhandle h)
-
- Frees structures associated with a compression or decompression instance
-
- [INPUT] h = instance handle (returned from a previous call to
- tjInitCompress() or tjInitDecompress()
-
- RETURNS: 0 on success, -1 on error
-*/
-DLLEXPORT int DLLCALL tjDestroy(tjhandle h);
-
-
-/*
- char *tjGetErrorStr(void)
-
- Returns a descriptive error message explaining why the last command failed
-*/
-DLLEXPORT char* DLLCALL tjGetErrorStr(void);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/x11vnc/misc/turbovnc/undo_turbovnc b/x11vnc/misc/turbovnc/undo_turbovnc
deleted file mode 100755
index e16691f..0000000
--- a/x11vnc/misc/turbovnc/undo_turbovnc
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-#
-# This script has been (or is hereby) released into the public domain by
-# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide.
-#
-# In case this is not legally possible: Karl J. Runge grants anyone the
-# right to use this work for any purpose, without any conditions, unless
-# such conditions are required by law.
-
-ldir="../../../libvncserver"
-
-if [ ! -f "$ldir/tight.c.ORIG" ]; then
- ls -l "$ldir/tight.c.ORIG"
- exit 1
-fi
-if [ ! -f "$ldir/rfbserver.c.ORIG" ]; then
- ls -l "$ldir/rfbserver.c.ORIG"
- exit 1
-fi
-
-set -xv
-rm -f "$ldir/tight.c" "$ldir/turbojpeg.h"
-mv "$ldir/tight.c.ORIG" "$ldir/tight.c"
-mv "$ldir/rfbserver.c.ORIG" "$ldir/rfbserver.c"
-ls -l $ldir/tight.c* $ldir/rfbserver.c*
diff --git a/x11vnc/misc/uinput.pl b/x11vnc/misc/uinput.pl
deleted file mode 100755
index 9620140..0000000
--- a/x11vnc/misc/uinput.pl
+++ /dev/null
@@ -1,946 +0,0 @@
-#!/usr/bin/perl
-
-# This is a test injection script for Linux uinput.
-# It can be handy working out / troubleshooting Linux uinput injection on a new device.
-
-#
-# Copyright (c) 2010 by Karl J. Runge <runge@karlrunge.com>
-#
-# uinput.pl is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# uinput.pl is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with uinput.pl; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-# or see <http://www.gnu.org/licenses/>.
-#
-
-set_constants();
-
-# options for what injection to handle:
-$rel = 1;
-$abs = 1;
-$touch = 1;
-$allkeys = 1;
-
-# these can be set via env:
-
-$WIDTH = $ENV{WIDTH};
-$WIDTH = 480 unless $WIDTH;
-$HEIGHT = $ENV{HEIGHT};
-$HEIGHT = 640 unless $HEIGHT;
-$DEV = $ENV{DEV};
-$DEV = "/dev/input/uinput" unless $DEV;
-
-# this fills in name and input type part of uinput_user_dev struct:
-
-$udev = "uinput.pl";
-$n = 80 - length($udev);
-$udev .= "\0" x $n;
-
-$udev .= "\0" x 2; # bus
-$udev .= "\0" x 2; # vendor
-$udev .= "\0" x 2; # product
-$udev .= "\0" x 2; # version
-
-$udev .= "\0" x 4; # ff_effects_max
-
-# this fills in the abs arrays:
-#
-foreach $type (qw(absmax absmin absfuzz absflat)) {
- $n = $ABS_MAX + 1;
- for ($j = 0; $j < $n; $j++) {
- if ($abs && $type eq 'absmax' && $j == $ABS_X) {
- $udev .= pack("i", $WIDTH-1);
- } elsif ($abs && $type eq 'absmax' && $j == $ABS_Y) {
- $udev .= pack("i", $HEIGHT-1);
- } else {
- $udev .= "\0" x 4;
- }
- }
-}
-
-print "udev: ", length($udev) . " '$udev'\n";
-
-$modes = $O_RDWR;
-$modes = $O_WRONLY | $O_NDELAY;
-printf("open modes: 0x%x\n", $modes);
-
-sysopen(FD, $DEV, $modes) || die "$DEV: $!";
-
-if ($rel) {
- io_ctl($UI_SET_EVBIT, $EV_REL);
- io_ctl($UI_SET_RELBIT, $REL_X);
- io_ctl($UI_SET_RELBIT, $REL_Y);
-}
-
-io_ctl($UI_SET_EVBIT, $EV_KEY);
-
-io_ctl($UI_SET_EVBIT, $EV_SYN);
-
-for ($i=0; $i < 256; $i++) {
- last unless $allkeys;
- io_ctl($UI_SET_KEYBIT, $i);
-}
-
-io_ctl($UI_SET_KEYBIT, $BTN_MOUSE);
-io_ctl($UI_SET_KEYBIT, $BTN_LEFT);
-io_ctl($UI_SET_KEYBIT, $BTN_MIDDLE);
-io_ctl($UI_SET_KEYBIT, $BTN_RIGHT);
-io_ctl($UI_SET_KEYBIT, $BTN_FORWARD);
-io_ctl($UI_SET_KEYBIT, $BTN_BACK);
-
-if ($abs) {
- io_ctl($UI_SET_KEYBIT, $BTN_TOUCH) if $touch;
- io_ctl($UI_SET_EVBIT, $EV_ABS);
- io_ctl($UI_SET_ABSBIT, $ABS_X);
- io_ctl($UI_SET_ABSBIT, $ABS_Y);
-}
-
-$ret = syswrite(FD, $udev, length($udev));
-print "syswrite: $ret\n";
-
-io_ctl($UI_DEV_CREATE);
-fsleep(0.25);
-
-# this should show our new virtual device:
-#
-system("cat /proc/bus/input/devices 1>&2");
-print STDERR "\n";
-
-#################################################
-# put in your various test injection events here:
-
-#do_key($KEY_A, 1, 0.1);
-#do_key($KEY_A, 0, 0.1);
-
-#do_key($KEY_POWER, 1, 0.1);
-#do_key($KEY_POWER, 0, 0.1);
-
-do_abs(118, 452, 0, 0.1);
-
-do_abs(110, 572, 1, 0.1);
-
-do_btn($BTN_TOUCH, 1, 0.1);
-do_btn($BTN_TOUCH, 0, 0.1);
-
-do_btn($BTN_MOUSE, 1, 0.1);
-do_btn($BTN_MOUSE, 0, 0.1);
-#################################################
-
-fsleep(0.25);
-io_ctl($UI_DEV_DESTROY);
-
-close(FD);
-
-exit(0);
-
-sub io_ctl {
- my ($cmd, $val) = @_;
- if (defined $val) {
- my $ret = syscall($linux_ioctl_syscall, fileno(FD), $cmd, $val);
- my $err = $!; $err = '' if $ret == 0;
- print STDERR "io_ctl(FD, $cmd, $val) = $ret $err\n";
- } else {
- my $ret = syscall($linux_ioctl_syscall, fileno(FD), $cmd);
- my $err = $!; $err = '' if $ret == 0;
- print STDERR "io_ctl(FD, $cmd) = $ret $err\n";
- }
-}
-
-sub do_syn {
- my $ev = gtod();
- $ev .= pack("S", $EV_SYN);
- $ev .= pack("S", $SYN_REPORT);
- $ev .= pack("i", 0);
- print STDERR "do_syn EV_SYN\n";
- my $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_syn: $!\n";
- }
-}
-
-sub do_key {
- my ($key, $down, $sleep) = @_;
- my $ev = gtod();
- $ev .= pack("S", $EV_KEY);
- $ev .= pack("S", $key);
- $ev .= pack("i", $down);
- print STDERR "do_key $key $down\n";
- my $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_key: $!\n";
- }
- do_syn();
- fsleep($sleep);
- print STDERR "\n";
-}
-
-sub do_btn {
- my ($button, $down, $sleep) = @_;
- my $ev = gtod();
- $ev .= pack("S", $EV_KEY);
- $ev .= pack("S", $button);
- $ev .= pack("i", $down);
- print STDERR "do_btn $button $down\n";
- my $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_btn: $!\n";
- }
- do_syn();
- fsleep($sleep);
- print STDERR "\n";
-}
-
-sub do_abs {
- my ($x, $y, $p, $sleep) = @_;
- my $ev = gtod();
- $ev .= pack("S", $EV_ABS);
- $ev .= pack("S", $ABS_Y);
- $ev .= pack("i", $y);
- print STDERR "do_abs y=$y\n";
- my $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_abs: $!\n";
- }
- $ev = gtod();
- $ev .= pack("S", $EV_ABS);
- $ev .= pack("S", $ABS_X);
- $ev .= pack("i", $x);
- print STDERR "do_abs x=$x\n";
- $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_abs: $!\n";
- }
- $ev = gtod();
- $ev .= pack("S", $EV_ABS);
- $ev .= pack("S", $ABS_PRESSURE);
- $ev .= pack("i", $p);
- print STDERR "do_abs p=$p\n";
- $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_abs: $!\n";
- }
- do_syn();
- fsleep($sleep);
- print STDERR "\n";
-}
-
-sub do_rel {
- my ($dx, $dy, $sleep) = @_;
- my $ev = gtod();
- $ev .= pack("S", $EV_REL);
- $ev .= pack("S", $REL_Y);
- $ev .= pack("i", $dy);
- print STDERR "do_rel dy=$dy\n";
- my $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_rel: $!\n";
- }
- $ev = gtod();
- $ev .= pack("S", $EV_REL);
- $ev .= pack("S", $REL_X);
- $ev .= pack("i", $dx);
- print STDERR "do_rel dx=$dx\n";
- $ret = syswrite(FD, $ev, length($ev));
- if (!defined $ret) {
- print STDERR "do_rel: $!\n";
- }
- do_syn();
- fsleep($sleep);
- print STDERR "\n";
-}
-
-sub gtod {
- $tv = ("\0" x 4) x 2; # assumes long is 4 bytes. FIXME: use pack.
- $tz = ("\0" x 4) x 2;
- syscall($linux_gettimeofday_syscall, $tv, $tz);
- return $tv;
-}
-
-sub fsleep {
- my ($time) = @_;
- select(undef, undef, undef, $time) if $time;
-}
-
-sub set_constants {
-
-# from /usr/include/linux/uinput.h /usr/include/linux/input.h and x11vnc.
-
-# #define ABS_MAX 0x3f = 63
-#
-# #define UINPUT_MAX_NAME_SIZE 80
-#
-# struct input_id {
-# __u16 bustype;
-# __u16 vendor;
-# __u16 product;
-# __u16 version;
-# };
-#
-# struct uinput_user_dev {
-# char name[UINPUT_MAX_NAME_SIZE];
-# struct input_id id;
-# int ff_effects_max;
-# int absmax[ABS_MAX + 1];
-# int absmin[ABS_MAX + 1];
-# int absfuzz[ABS_MAX + 1];
-# int absflat[ABS_MAX + 1];
-# };
-# #endif /* __UINPUT_H_ */
-
-$EV_SYN = 0x00;
-$EV_KEY = 0x01;
-$EV_REL = 0x02;
-$EV_ABS = 0x03;
-$EV_MSC = 0x04;
-$EV_SW = 0x05;
-$EV_LED = 0x11;
-$EV_SND = 0x12;
-$EV_REP = 0x14;
-$EV_FF = 0x15;
-$EV_PWR = 0x16;
-$EV_FF_STATUS = 0x17;
-$EV_MAX = 0x1f;
-
-$ID_BUS = 0;
-$ID_VENDOR = 1;
-$ID_PRODUCT = 2;
-$ID_VERSION = 3;
-
-$BUS_PCI = 0x01;
-$BUS_ISAPNP = 0x02;
-$BUS_USB = 0x03;
-$BUS_HIL = 0x04;
-$BUS_BLUETOOTH = 0x05;
-$BUS_VIRTUAL = 0x06;
-
-$BUS_ISA = 0x10;
-$BUS_I8042 = 0x11;
-$BUS_XTKBD = 0x12;
-$BUS_RS232 = 0x13;
-$BUS_GAMEPORT = 0x14;
-$BUS_PARPORT = 0x15;
-$BUS_AMIGA = 0x16;
-$BUS_ADB = 0x17;
-$BUS_I2C = 0x18;
-$BUS_HOST = 0x19;
-$BUS_GSC = 0x1A;
-$BUS_ATARI = 0x1B;
-
-$REL_X = 0x00;
-$REL_Y = 0x01;
-$REL_Z = 0x02;
-$REL_RX = 0x03;
-$REL_RY = 0x04;
-$REL_RZ = 0x05;
-$REL_HWHEEL = 0x06;
-$REL_DIAL = 0x07;
-$REL_WHEEL = 0x08;
-$REL_MISC = 0x09;
-
-$ABS_X = 0x00;
-$ABS_Y = 0x01;
-$ABS_Z = 0x02;
-$ABS_RX = 0x03;
-$ABS_RY = 0x04;
-$ABS_RZ = 0x05;
-$ABS_THROTTLE = 0x06;
-$ABS_RUDDER = 0x07;
-$ABS_WHEEL = 0x08;
-$ABS_GAS = 0x09;
-$ABS_BRAKE = 0x0a;
-$ABS_HAT0X = 0x10;
-$ABS_HAT0Y = 0x11;
-$ABS_HAT1X = 0x12;
-$ABS_HAT1Y = 0x13;
-$ABS_HAT2X = 0x14;
-$ABS_HAT2Y = 0x15;
-$ABS_HAT3X = 0x16;
-$ABS_HAT3Y = 0x17;
-$ABS_PRESSURE = 0x18;
-$ABS_DISTANCE = 0x19;
-$ABS_TILT_X = 0x1a;
-$ABS_TILT_Y = 0x1b;
-$ABS_TOOL_WIDTH = 0x1c;
-$ABS_VOLUME = 0x20;
-$ABS_MISC = 0x28;
-$ABS_MT_TOUCH_MAJOR = 0x30;
-$ABS_MT_TOUCH_MINOR = 0x31;
-$ABS_MT_WIDTH_MAJOR = 0x32;
-$ABS_MT_WIDTH_MINOR = 0x33;
-$ABS_MT_ORIENTATION = 0x34;
-$ABS_MT_POSITION_X = 0x35;
-$ABS_MT_POSITION_Y = 0x36;
-$ABS_MT_TOOL_TYPE = 0x37;
-$ABS_MT_BLOB_ID = 0x38;
-$ABS_MT_TRACKING_ID = 0x39;
-#$ABS_MAX = 0x3f;
-
-
-$BTN_MISC = 0x100;
-$BTN_0 = 0x100;
-$BTN_1 = 0x101;
-$BTN_2 = 0x102;
-$BTN_3 = 0x103;
-$BTN_4 = 0x104;
-$BTN_5 = 0x105;
-$BTN_6 = 0x106;
-$BTN_7 = 0x107;
-$BTN_8 = 0x108;
-$BTN_9 = 0x109;
-
-$BTN_MOUSE = 0x110;
-$BTN_LEFT = 0x110;
-$BTN_RIGHT = 0x111;
-$BTN_MIDDLE = 0x112;
-$BTN_SIDE = 0x113;
-$BTN_EXTRA = 0x114;
-$BTN_FORWARD = 0x115;
-$BTN_BACK = 0x116;
-$BTN_TASK = 0x117;
-
-$BTN_JOYSTICK = 0x120;
-$BTN_TRIGGER = 0x120;
-$BTN_THUMB = 0x121;
-$BTN_THUMB2 = 0x122;
-$BTN_TOP = 0x123;
-$BTN_TOP2 = 0x124;
-$BTN_PINKIE = 0x125;
-$BTN_BASE = 0x126;
-$BTN_BASE2 = 0x127;
-$BTN_BASE3 = 0x128;
-$BTN_BASE4 = 0x129;
-$BTN_BASE5 = 0x12a;
-$BTN_BASE6 = 0x12b;
-$BTN_DEAD = 0x12f;
-
-$BTN_GAMEPAD = 0x130;
-$BTN_A = 0x130;
-$BTN_B = 0x131;
-$BTN_C = 0x132;
-$BTN_X = 0x133;
-$BTN_Y = 0x134;
-$BTN_Z = 0x135;
-$BTN_TL = 0x136;
-$BTN_TR = 0x137;
-$BTN_TL2 = 0x138;
-$BTN_TR2 = 0x139;
-$BTN_SELECT = 0x13a;
-$BTN_START = 0x13b;
-$BTN_MODE = 0x13c;
-$BTN_THUMBL = 0x13d;
-$BTN_THUMBR = 0x13e;
-
-$BTN_DIGI = 0x140;
-$BTN_TOOL_PEN = 0x140;
-$BTN_TOOL_RUBBER = 0x141;
-$BTN_TOOL_BRUSH = 0x142;
-$BTN_TOOL_PENCIL = 0x143;
-$BTN_TOOL_AIRBRUSH = 0x144;
-$BTN_TOOL_FINGER = 0x145;
-$BTN_TOOL_MOUSE = 0x146;
-$BTN_TOOL_LENS = 0x147;
-$BTN_TOUCH = 0x14a;
-$BTN_STYLUS = 0x14b;
-$BTN_STYLUS2 = 0x14c;
-$BTN_TOOL_DOUBLETAP = 0x14d;
-$BTN_TOOL_TRIPLETAP = 0x14e;
-
-$BTN_WHEEL = 0x150;
-$BTN_GEAR_DOWN = 0x150;
-$BTN_GEAR_UP = 0x151;
-
-$SYN_REPORT = 0;
-$SYN_CONFIG = 1;
-$SYN_MT_REPORT = 2;
-
-$KEY_RESERVED = 0;
-$KEY_ESC = 1;
-$KEY_1 = 2;
-$KEY_2 = 3;
-$KEY_3 = 4;
-$KEY_4 = 5;
-$KEY_5 = 6;
-$KEY_6 = 7;
-$KEY_7 = 8;
-$KEY_8 = 9;
-$KEY_9 = 10;
-$KEY_0 = 11;
-$KEY_MINUS = 12;
-$KEY_EQUAL = 13;
-$KEY_BACKSPACE = 14;
-$KEY_TAB = 15;
-$KEY_Q = 16;
-$KEY_W = 17;
-$KEY_E = 18;
-$KEY_R = 19;
-$KEY_T = 20;
-$KEY_Y = 21;
-$KEY_U = 22;
-$KEY_I = 23;
-$KEY_O = 24;
-$KEY_P = 25;
-$KEY_LEFTBRACE = 26;
-$KEY_RIGHTBRACE = 27;
-$KEY_ENTER = 28;
-$KEY_LEFTCTRL = 29;
-$KEY_A = 30;
-$KEY_S = 31;
-$KEY_D = 32;
-$KEY_F = 33;
-$KEY_G = 34;
-$KEY_H = 35;
-$KEY_J = 36;
-$KEY_K = 37;
-$KEY_L = 38;
-$KEY_SEMICOLON = 39;
-$KEY_APOSTROPHE = 40;
-$KEY_GRAVE = 41;
-$KEY_LEFTSHIFT = 42;
-$KEY_BACKSLASH = 43;
-$KEY_Z = 44;
-$KEY_X = 45;
-$KEY_C = 46;
-$KEY_V = 47;
-$KEY_B = 48;
-$KEY_N = 49;
-$KEY_M = 50;
-$KEY_COMMA = 51;
-$KEY_DOT = 52;
-$KEY_SLASH = 53;
-$KEY_RIGHTSHIFT = 54;
-$KEY_KPASTERISK = 55;
-$KEY_LEFTALT = 56;
-$KEY_SPACE = 57;
-$KEY_CAPSLOCK = 58;
-$KEY_F1 = 59;
-$KEY_F2 = 60;
-$KEY_F3 = 61;
-$KEY_F4 = 62;
-$KEY_F5 = 63;
-$KEY_F6 = 64;
-$KEY_F7 = 65;
-$KEY_F8 = 66;
-$KEY_F9 = 67;
-$KEY_F10 = 68;
-$KEY_NUMLOCK = 69;
-$KEY_SCROLLLOCK = 70;
-$KEY_KP7 = 71;
-$KEY_KP8 = 72;
-$KEY_KP9 = 73;
-$KEY_KPMINUS = 74;
-$KEY_KP4 = 75;
-$KEY_KP5 = 76;
-$KEY_KP6 = 77;
-$KEY_KPPLUS = 78;
-$KEY_KP1 = 79;
-$KEY_KP2 = 80;
-$KEY_KP3 = 81;
-$KEY_KP0 = 82;
-$KEY_KPDOT = 83;
-$KEY_103RD = 84;
-$KEY_F13 = 85;
-$KEY_102ND = 86;
-$KEY_F11 = 87;
-$KEY_F12 = 88;
-$KEY_F14 = 89;
-$KEY_F15 = 90;
-$KEY_F16 = 91;
-$KEY_F17 = 92;
-$KEY_F18 = 93;
-$KEY_F19 = 94;
-$KEY_F20 = 95;
-$KEY_KPENTER = 96;
-$KEY_RIGHTCTRL = 97;
-$KEY_KPSLASH = 98;
-$KEY_SYSRQ = 99;
-$KEY_RIGHTALT = 100;
-$KEY_LINEFEED = 101;
-$KEY_HOME = 102;
-$KEY_UP = 103;
-$KEY_PAGEUP = 104;
-$KEY_LEFT = 105;
-$KEY_RIGHT = 106;
-$KEY_END = 107;
-$KEY_DOWN = 108;
-$KEY_PAGEDOWN = 109;
-$KEY_INSERT = 110;
-$KEY_DELETE = 111;
-$KEY_MACRO = 112;
-$KEY_MUTE = 113;
-$KEY_VOLUMEDOWN = 114;
-$KEY_VOLUMEUP = 115;
-$KEY_POWER = 116;
-$KEY_KPEQUAL = 117;
-$KEY_KPPLUSMINUS = 118;
-$KEY_PAUSE = 119;
-$KEY_F21 = 120;
-$KEY_F22 = 121;
-$KEY_F23 = 122;
-$KEY_F24 = 123;
-$KEY_KPCOMMA = 124;
-$KEY_LEFTMETA = 125;
-$KEY_RIGHTMETA = 126;
-$KEY_COMPOSE = 127;
-$KEY_STOP = 128;
-$KEY_AGAIN = 129;
-$KEY_PROPS = 130;
-$KEY_UNDO = 131;
-$KEY_FRONT = 132;
-$KEY_COPY = 133;
-$KEY_OPEN = 134;
-$KEY_PASTE = 135;
-$KEY_FIND = 136;
-$KEY_CUT = 137;
-$KEY_HELP = 138;
-$KEY_MENU = 139;
-$KEY_CALC = 140;
-$KEY_SETUP = 141;
-$KEY_SLEEP = 142;
-$KEY_WAKEUP = 143;
-$KEY_FILE = 144;
-$KEY_SENDFILE = 145;
-$KEY_DELETEFILE = 146;
-$KEY_XFER = 147;
-$KEY_PROG1 = 148;
-$KEY_PROG2 = 149;
-$KEY_WWW = 150;
-$KEY_MSDOS = 151;
-$KEY_COFFEE = 152;
-$KEY_DIRECTION = 153;
-$KEY_CYCLEWINDOWS = 154;
-$KEY_MAIL = 155;
-$KEY_BOOKMARKS = 156;
-$KEY_COMPUTER = 157;
-$KEY_BACK = 158;
-$KEY_FORWARD = 159;
-$KEY_CLOSECD = 160;
-$KEY_EJECTCD = 161;
-$KEY_EJECTCLOSECD = 162;
-$KEY_NEXTSONG = 163;
-$KEY_PLAYPAUSE = 164;
-$KEY_PREVIOUSSONG = 165;
-$KEY_STOPCD = 166;
-$KEY_RECORD = 167;
-$KEY_REWIND = 168;
-$KEY_PHONE = 169;
-$KEY_ISO = 170;
-$KEY_CONFIG = 171;
-$KEY_HOMEPAGE = 172;
-$KEY_REFRESH = 173;
-$KEY_EXIT = 174;
-$KEY_MOVE = 175;
-$KEY_EDIT = 176;
-$KEY_SCROLLUP = 177;
-$KEY_SCROLLDOWN = 178;
-$KEY_KPLEFTPAREN = 179;
-$KEY_KPRIGHTPAREN = 180;
-$KEY_INTL1 = 181;
-$KEY_INTL2 = 182;
-$KEY_INTL3 = 183;
-$KEY_INTL4 = 184;
-$KEY_INTL5 = 185;
-$KEY_INTL6 = 186;
-$KEY_INTL7 = 187;
-$KEY_INTL8 = 188;
-$KEY_INTL9 = 189;
-$KEY_LANG1 = 190;
-$KEY_LANG2 = 191;
-$KEY_LANG3 = 192;
-$KEY_LANG4 = 193;
-$KEY_LANG5 = 194;
-$KEY_LANG6 = 195;
-$KEY_LANG7 = 196;
-$KEY_LANG8 = 197;
-$KEY_LANG9 = 198;
-$KEY_PLAYCD = 200;
-$KEY_PAUSECD = 201;
-$KEY_PROG3 = 202;
-$KEY_PROG4 = 203;
-$KEY_SUSPEND = 205;
-$KEY_CLOSE = 206;
-$KEY_PLAY = 207;
-$KEY_FASTFORWARD = 208;
-$KEY_BASSBOOST = 209;
-$KEY_PRINT = 210;
-$KEY_HP = 211;
-$KEY_CAMERA = 212;
-$KEY_SOUND = 213;
-$KEY_QUESTION = 214;
-$KEY_EMAIL = 215;
-$KEY_CHAT = 216;
-$KEY_SEARCH = 217;
-$KEY_CONNECT = 218;
-$KEY_FINANCE = 219;
-$KEY_SPORT = 220;
-$KEY_SHOP = 221;
-$KEY_ALTERASE = 222;
-$KEY_CANCEL = 223;
-$KEY_BRIGHTNESSDOWN = 224;
-$KEY_BRIGHTNESSUP = 225;
-$KEY_MEDIA = 226;
-$KEY_UNKNOWN = 240;
-$KEY_OK = 0x160;
-$KEY_SELECT = 0x161;
-$KEY_GOTO = 0x162;
-$KEY_CLEAR = 0x163;
-$KEY_POWER2 = 0x164;
-$KEY_OPTION = 0x165;
-$KEY_INFO = 0x166;
-$KEY_TIME = 0x167;
-$KEY_VENDOR = 0x168;
-$KEY_ARCHIVE = 0x169;
-$KEY_PROGRAM = 0x16a;
-$KEY_CHANNEL = 0x16b;
-$KEY_FAVORITES = 0x16c;
-$KEY_EPG = 0x16d;
-$KEY_PVR = 0x16e;
-$KEY_MHP = 0x16f;
-$KEY_LANGUAGE = 0x170;
-$KEY_TITLE = 0x171;
-$KEY_SUBTITLE = 0x172;
-$KEY_ANGLE = 0x173;
-$KEY_ZOOM = 0x174;
-$KEY_MODE = 0x175;
-$KEY_KEYBOARD = 0x176;
-$KEY_SCREEN = 0x177;
-$KEY_PC = 0x178;
-$KEY_TV = 0x179;
-$KEY_TV2 = 0x17a;
-$KEY_VCR = 0x17b;
-$KEY_VCR2 = 0x17c;
-$KEY_SAT = 0x17d;
-$KEY_SAT2 = 0x17e;
-$KEY_CD = 0x17f;
-$KEY_TAPE = 0x180;
-$KEY_RADIO = 0x181;
-$KEY_TUNER = 0x182;
-$KEY_PLAYER = 0x183;
-$KEY_TEXT = 0x184;
-$KEY_DVD = 0x185;
-$KEY_AUX = 0x186;
-$KEY_MP3 = 0x187;
-$KEY_AUDIO = 0x188;
-$KEY_VIDEO = 0x189;
-$KEY_DIRECTORY = 0x18a;
-$KEY_LIST = 0x18b;
-$KEY_MEMO = 0x18c;
-$KEY_CALENDAR = 0x18d;
-$KEY_RED = 0x18e;
-$KEY_GREEN = 0x18f;
-$KEY_YELLOW = 0x190;
-$KEY_BLUE = 0x191;
-$KEY_CHANNELUP = 0x192;
-$KEY_CHANNELDOWN = 0x193;
-$KEY_FIRST = 0x194;
-$KEY_LAST = 0x195;
-$KEY_AB = 0x196;
-$KEY_NEXT = 0x197;
-$KEY_RESTART = 0x198;
-$KEY_SLOW = 0x199;
-$KEY_SHUFFLE = 0x19a;
-$KEY_BREAK = 0x19b;
-$KEY_PREVIOUS = 0x19c;
-$KEY_DIGITS = 0x19d;
-$KEY_TEEN = 0x19e;
-$KEY_TWEN = 0x19f;
-$KEY_DEL_EOL = 0x1c0;
-$KEY_DEL_EOS = 0x1c1;
-$KEY_INS_LINE = 0x1c2;
-$KEY_DEL_LINE = 0x1c3;
-$KEY_MAX = 0x1ff;
-
-
- $key_lookup{XK_Escape} = $KEY_ESC;
- $key_lookup{XK_1} = $KEY_1;
- $key_lookup{XK_2} = $KEY_2;
- $key_lookup{XK_3} = $KEY_3;
- $key_lookup{XK_4} = $KEY_4;
- $key_lookup{XK_5} = $KEY_5;
- $key_lookup{XK_6} = $KEY_6;
- $key_lookup{XK_7} = $KEY_7;
- $key_lookup{XK_8} = $KEY_8;
- $key_lookup{XK_9} = $KEY_9;
- $key_lookup{XK_0} = $KEY_0;
- $key_lookup{XK_exclam} = $KEY_1;
- $key_lookup{XK_at} = $KEY_2;
- $key_lookup{XK_numbersign} = $KEY_3;
- $key_lookup{XK_dollar} = $KEY_4;
- $key_lookup{XK_percent} = $KEY_5;
- $key_lookup{XK_asciicircum} = $KEY_6;
- $key_lookup{XK_ampersand} = $KEY_7;
- $key_lookup{XK_asterisk} = $KEY_8;
- $key_lookup{XK_parenleft} = $KEY_9;
- $key_lookup{XK_parenright} = $KEY_0;
- $key_lookup{XK_minus} = $KEY_MINUS;
- $key_lookup{XK_underscore} = $KEY_MINUS;
- $key_lookup{XK_equal} = $KEY_EQUAL;
- $key_lookup{XK_plus} = $KEY_EQUAL;
- $key_lookup{XK_BackSpace} = $KEY_BACKSPACE;
- $key_lookup{XK_Tab} = $KEY_TAB;
- $key_lookup{XK_q} = $KEY_Q;
- $key_lookup{XK_Q} = $KEY_Q;
- $key_lookup{XK_w} = $KEY_W;
- $key_lookup{XK_W} = $KEY_W;
- $key_lookup{XK_e} = $KEY_E;
- $key_lookup{XK_E} = $KEY_E;
- $key_lookup{XK_r} = $KEY_R;
- $key_lookup{XK_R} = $KEY_R;
- $key_lookup{XK_t} = $KEY_T;
- $key_lookup{XK_T} = $KEY_T;
- $key_lookup{XK_y} = $KEY_Y;
- $key_lookup{XK_Y} = $KEY_Y;
- $key_lookup{XK_u} = $KEY_U;
- $key_lookup{XK_U} = $KEY_U;
- $key_lookup{XK_i} = $KEY_I;
- $key_lookup{XK_I} = $KEY_I;
- $key_lookup{XK_o} = $KEY_O;
- $key_lookup{XK_O} = $KEY_O;
- $key_lookup{XK_p} = $KEY_P;
- $key_lookup{XK_P} = $KEY_P;
- $key_lookup{XK_braceleft} = $KEY_LEFTBRACE;
- $key_lookup{XK_braceright} = $KEY_RIGHTBRACE;
- $key_lookup{XK_bracketleft} = $KEY_LEFTBRACE;
- $key_lookup{XK_bracketright} = $KEY_RIGHTBRACE;
- $key_lookup{XK_Return} = $KEY_ENTER;
- $key_lookup{XK_Control_L} = $KEY_LEFTCTRL;
- $key_lookup{XK_a} = $KEY_A;
- $key_lookup{XK_A} = $KEY_A;
- $key_lookup{XK_s} = $KEY_S;
- $key_lookup{XK_S} = $KEY_S;
- $key_lookup{XK_d} = $KEY_D;
- $key_lookup{XK_D} = $KEY_D;
- $key_lookup{XK_f} = $KEY_F;
- $key_lookup{XK_F} = $KEY_F;
- $key_lookup{XK_g} = $KEY_G;
- $key_lookup{XK_G} = $KEY_G;
- $key_lookup{XK_h} = $KEY_H;
- $key_lookup{XK_H} = $KEY_H;
- $key_lookup{XK_j} = $KEY_J;
- $key_lookup{XK_J} = $KEY_J;
- $key_lookup{XK_k} = $KEY_K;
- $key_lookup{XK_K} = $KEY_K;
- $key_lookup{XK_l} = $KEY_L;
- $key_lookup{XK_L} = $KEY_L;
- $key_lookup{XK_semicolon} = $KEY_SEMICOLON;
- $key_lookup{XK_colon} = $KEY_SEMICOLON;
- $key_lookup{XK_apostrophe} = $KEY_APOSTROPHE;
- $key_lookup{XK_quotedbl} = $KEY_APOSTROPHE;
- $key_lookup{XK_grave} = $KEY_GRAVE;
- $key_lookup{XK_asciitilde} = $KEY_GRAVE;
- $key_lookup{XK_Shift_L} = $KEY_LEFTSHIFT;
- $key_lookup{XK_backslash} = $KEY_BACKSLASH;
- $key_lookup{XK_bar} = $KEY_BACKSLASH;
- $key_lookup{XK_z} = $KEY_Z;
- $key_lookup{XK_Z} = $KEY_Z;
- $key_lookup{XK_x} = $KEY_X;
- $key_lookup{XK_X} = $KEY_X;
- $key_lookup{XK_c} = $KEY_C;
- $key_lookup{XK_C} = $KEY_C;
- $key_lookup{XK_v} = $KEY_V;
- $key_lookup{XK_V} = $KEY_V;
- $key_lookup{XK_b} = $KEY_B;
- $key_lookup{XK_B} = $KEY_B;
- $key_lookup{XK_n} = $KEY_N;
- $key_lookup{XK_N} = $KEY_N;
- $key_lookup{XK_m} = $KEY_M;
- $key_lookup{XK_M} = $KEY_M;
- $key_lookup{XK_comma} = $KEY_COMMA;
- $key_lookup{XK_less} = $KEY_COMMA;
- $key_lookup{XK_period} = $KEY_DOT;
- $key_lookup{XK_greater} = $KEY_DOT;
- $key_lookup{XK_slash} = $KEY_SLASH;
- $key_lookup{XK_question} = $KEY_SLASH;
- $key_lookup{XK_Shift_R} = $KEY_RIGHTSHIFT;
- $key_lookup{XK_KP_Multiply} = $KEY_KPASTERISK;
- $key_lookup{XK_Alt_L} = $KEY_LEFTALT;
- $key_lookup{XK_space} = $KEY_SPACE;
- $key_lookup{XK_Caps_Lock} = $KEY_CAPSLOCK;
- $key_lookup{XK_F1} = $KEY_F1;
- $key_lookup{XK_F2} = $KEY_F2;
- $key_lookup{XK_F3} = $KEY_F3;
- $key_lookup{XK_F4} = $KEY_F4;
- $key_lookup{XK_F5} = $KEY_F5;
- $key_lookup{XK_F6} = $KEY_F6;
- $key_lookup{XK_F7} = $KEY_F7;
- $key_lookup{XK_F8} = $KEY_F8;
- $key_lookup{XK_F9} = $KEY_F9;
- $key_lookup{XK_F10} = $KEY_F10;
- $key_lookup{XK_Num_Lock} = $KEY_NUMLOCK;
- $key_lookup{XK_Scroll_Lock} = $KEY_SCROLLLOCK;
- $key_lookup{XK_KP_7} = $KEY_KP7;
- $key_lookup{XK_KP_8} = $KEY_KP8;
- $key_lookup{XK_KP_9} = $KEY_KP9;
- $key_lookup{XK_KP_Subtract} = $KEY_KPMINUS;
- $key_lookup{XK_KP_4} = $KEY_KP4;
- $key_lookup{XK_KP_5} = $KEY_KP5;
- $key_lookup{XK_KP_6} = $KEY_KP6;
- $key_lookup{XK_KP_Add} = $KEY_KPPLUS;
- $key_lookup{XK_KP_1} = $KEY_KP1;
- $key_lookup{XK_KP_2} = $KEY_KP2;
- $key_lookup{XK_KP_3} = $KEY_KP3;
- $key_lookup{XK_KP_0} = $KEY_KP0;
- $key_lookup{XK_KP_Decimal} = $KEY_KPDOT;
- $key_lookup{XK_F13} = $KEY_F13;
- $key_lookup{XK_F11} = $KEY_F11;
- $key_lookup{XK_F12} = $KEY_F12;
- $key_lookup{XK_F14} = $KEY_F14;
- $key_lookup{XK_F15} = $KEY_F15;
- $key_lookup{XK_F16} = $KEY_F16;
- $key_lookup{XK_F17} = $KEY_F17;
- $key_lookup{XK_F18} = $KEY_F18;
- $key_lookup{XK_F19} = $KEY_F19;
- $key_lookup{XK_F20} = $KEY_F20;
- $key_lookup{XK_KP_Enter} = $KEY_KPENTER;
- $key_lookup{XK_Control_R} = $KEY_RIGHTCTRL;
- $key_lookup{XK_KP_Divide} = $KEY_KPSLASH;
- $key_lookup{XK_Sys_Req} = $KEY_SYSRQ;
- $key_lookup{XK_Alt_R} = $KEY_RIGHTALT;
- $key_lookup{XK_Linefeed} = $KEY_LINEFEED;
- $key_lookup{XK_Home} = $KEY_HOME;
- $key_lookup{XK_Up} = $KEY_UP;
- $key_lookup{XK_Page_Up} = $KEY_PAGEUP;
- $key_lookup{XK_Left} = $KEY_LEFT;
- $key_lookup{XK_Right} = $KEY_RIGHT;
- $key_lookup{XK_End} = $KEY_END;
- $key_lookup{XK_Down} = $KEY_DOWN;
- $key_lookup{XK_Page_Down} = $KEY_PAGEDOWN;
- $key_lookup{XK_Insert} = $KEY_INSERT;
- $key_lookup{XK_Delete} = $KEY_DELETE;
- $key_lookup{XK_KP_Equal} = $KEY_KPEQUAL;
- $key_lookup{XK_Pause} = $KEY_PAUSE;
- $key_lookup{XK_F21} = $KEY_F21;
- $key_lookup{XK_F22} = $KEY_F22;
- $key_lookup{XK_F23} = $KEY_F23;
- $key_lookup{XK_F24} = $KEY_F24;
- $key_lookup{XK_KP_Separator} = $KEY_KPCOMMA;
- $key_lookup{XK_Meta_L} = $KEY_LEFTMETA;
- $key_lookup{XK_Meta_R} = $KEY_RIGHTMETA;
- $key_lookup{XK_Multi_key} = $KEY_COMPOSE;
-
-$ABS_MAX = 63;
-
-$UI_DEV_CREATE = 0x5501;
-$UI_DEV_DESTROY = 0x5502;
-$UI_SET_EVBIT = 0x40045564;
-$UI_SET_KEYBIT = 0x40045565;
-$UI_SET_RELBIT = 0x40045566;
-$UI_SET_ABSBIT = 0x40045567;
-
-# FIXME: time hires, etc.
-$linux_gettimeofday_syscall = 78;
-
-$O_RDONLY = 00;
-$O_WRONLY = 01;
-$O_RDWR = 02;
-$O_NDELAY = 04000;
-
-}
diff --git a/x11vnc/misc/ultravnc_repeater.pl b/x11vnc/misc/ultravnc_repeater.pl
deleted file mode 100755
index 0c44a05..0000000
--- a/x11vnc/misc/ultravnc_repeater.pl
+++ /dev/null
@@ -1,741 +0,0 @@
-#!/usr/bin/env perl
-#
-# Copyright (c) 2009-2010 by Karl J. Runge <runge@karlrunge.com>
-#
-# ultravnc_repeater.pl is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# ultravnc_repeater.pl is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with ultravnc_repeater.pl; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-# or see <http://www.gnu.org/licenses/>.
-#
-
-my $usage = '
-ultravnc_repeater.pl:
- perl script implementing the ultravnc repeater
- proxy protocol.
-
-protocol: Listen on one port for vnc clients (default 5900.)
- Listen on one port for vnc servers (default 5500.)
- Read 250 bytes from connecting vnc client or server.
- Accept ID:<string> from clients and servers, connect them
- together once both are present.
-
- The string "RFB 000.000\n" is sent to the client (the client
- must understand this means send ID:... or host:port.)
- Also accept <host>:<port> from clients and make the
- connection to the vnc server immediately.
-
- Note there is no authentication or security WRT ID names or
- identities; it is up to the client and server to completely
- manage that aspect and whether to encrypt the session, etc.
-
-usage: ultravnc_repeater.pl [-r] [client_port [server_port]]
-
-Use -r to refuse new server/client connections when there is an existing
-server/client ID. The default is to close the previous one.
-
-To write to a log file set the env. var ULTRAVNC_REPEATER_LOGFILE.
-
-To run in a loop restarting the server if it exits set the env. var.
-ULTRAVNC_REPEATER_LOOP=1 or ULTRAVNC_REPEATER_LOOP=BG, the latter
-forks into the background. Set ULTRAVNC_REPEATER_PIDFILE to a file
-to store the master pid in.
-
-Set ULTRAVNC_REPEATER_NO_RFB=1 to disable sending "RFB 000.000" to
-the client. Then this program acts as general TCP rendezvous tool.
-
-Examples:
-
- ultravnc_repeater.pl
- ultravnc_repeater.pl -r
- ultravnc_repeater.pl 5901
- ultravnc_repeater.pl 5901 5501
-
- env ULTRAVNC_REPEATER_LOOP=BG ULTRAVNC_REPEATER_LOGFILE=/tmp/u.log ultravnc_repeater.pl ...
-
-';
-
-use strict;
-
-# Set up logging:
-#
-if (exists $ENV{ULTRAVNC_REPEATER_LOGFILE}) {
- close STDOUT;
- if (!open(STDOUT, ">>$ENV{ULTRAVNC_REPEATER_LOGFILE}")) {
- die "ultravnc_repeater.pl: $ENV{ULTRAVNC_REPEATER_LOGFILE} $!\n";
- }
- close STDERR;
- open(STDERR, ">&STDOUT");
-}
-select(STDERR); $| = 1;
-select(STDOUT); $| = 1;
-
-# interrupt handler:
-#
-my $looppid = '';
-my $pidfile = '';
-#
-sub get_out {
- lprint("$_[0]:\t$$ looppid=$looppid");
- if ($looppid) {
- kill 'TERM', $looppid;
- fsleep(0.2);
- }
- unlink $pidfile if $pidfile;
- cleanup();
- exit 0;
-}
-
-sub lprint {
- print STDERR scalar(localtime), ": ", @_, "\n";
-}
-
-# These are overridden in actual server thread:
-#
-$SIG{INT} = \&get_out;
-$SIG{TERM} = \&get_out;
-
-# pidfile:
-#
-sub open_pidfile {
- if (exists $ENV{ULTRAVNC_REPEATER_PIDFILE}) {
- my $pf = $ENV{ULTRAVNC_REPEATER_PIDFILE};
- if (open(PID, ">$pf")) {
- print PID "$$\n";
- close PID;
- $pidfile = $pf;
- } else {
- lprint("could not open pidfile: $pf - $! - continuing...");
- }
- delete $ENV{ULTRAVNC_REPEATER_PIDFILE};
- }
-}
-
-####################################################################
-# Set ULTRAVNC_REPEATER_LOOP=1 to have this script create an outer loop
-# restarting itself if it ever exits. Set ULTRAVNC_REPEATER_LOOP=BG to
-# do this in the background as a daemon.
-
-if (exists $ENV{ULTRAVNC_REPEATER_LOOP}) {
- my $csl = $ENV{ULTRAVNC_REPEATER_LOOP};
- if ($csl ne 'BG' && $csl ne '1') {
- die "ultravnc_repeater.pl: invalid ULTRAVNC_REPEATER_LOOP.\n";
- }
- if ($csl eq 'BG') {
- # go into bg as "daemon":
- setpgrp(0, 0);
- my $pid = fork();
- if (! defined $pid) {
- die "ultravnc_repeater.pl: $!\n";
- } elsif ($pid) {
- wait;
- exit 0;
- }
- if (fork) {
- exit 0;
- }
- setpgrp(0, 0);
- close STDIN;
- if (! $ENV{ULTRAVNC_REPEATER_LOGFILE}) {
- close STDOUT;
- close STDERR;
- }
- }
- delete $ENV{ULTRAVNC_REPEATER_LOOP};
-
- if (exists $ENV{ULTRAVNC_REPEATER_PIDFILE}) {
- open_pidfile();
- }
-
- lprint("ultravnc_repeater.pl: starting service. master-pid=$$");
- while (1) {
- $looppid = fork;
- if (! defined $looppid) {
- sleep 10;
- } elsif ($looppid) {
- wait;
- } else {
- exec $0, @ARGV;
- exit 1;
- }
- lprint("ultravnc_repeater.pl: re-starting service. master-pid=$$");
- sleep 1;
- }
- exit 0;
-}
-if (exists $ENV{ULTRAVNC_REPEATER_PIDFILE}) {
- open_pidfile();
-}
-
-# End of background/daemon stuff.
-####################################################################
-
-use warnings;
-use IO::Socket::INET;
-use IO::Select;
-
-# Test for INET6 support:
-#
-my $have_inet6 = 0;
-eval "use IO::Socket::INET6;";
-$have_inet6 = 1 if $@ eq "";
-print "perl module IO::Socket::INET6 not available: no IPv6 support.\n" if ! $have_inet6;
-
-my $prog = 'ultravnc_repeater';
-my %ID;
-
-my $refuse = 0;
-my $init_timeout = 5;
-
-if (@ARGV && $ARGV[0] =~ /-h/) {
- print $usage;
- exit 0;
-}
-if (@ARGV && $ARGV[0] eq '-r') {
- $refuse = 1;
- lprint("enabling refuse mode (-r).");
- shift;
-}
-
-my $client_port = shift;
-my $server_port = shift;
-
-$client_port = 5900 unless $client_port;
-$server_port = 5500 unless $server_port;
-
-my $uname = `uname`;
-
-my $repeater_bufsize = 250;
-$repeater_bufsize = $ENV{BUFSIZE} if exists $ENV{BUFSIZE};
-
-my ($RIN, $WIN, $EIN, $ROUT);
-
-my $client_listen = IO::Socket::INET->new(
- Listen => 10,
- LocalPort => $client_port,
- ReuseAddr => 1,
- Proto => "tcp"
-);
-my $err1 = $!;
-my $err2 = '';
-$client_listen = '' if ! $client_listen;
-
-my $client_listen6 = '';
-if ($have_inet6) {
- eval {$client_listen6 = IO::Socket::INET6->new(
- Listen => 10,
- LocalPort => $client_port,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => "::",
- Proto => "tcp"
- );};
- $err2 = $!;
-}
-if (! $client_listen && ! $client_listen6) {
- cleanup();
- die "$prog: error: client listen on port $client_port: $err1 - $err2\n";
-}
-
-my $server_listen = IO::Socket::INET->new(
- Listen => 10,
- LocalPort => $server_port,
- ReuseAddr => 1,
- Proto => "tcp"
-);
-$err1 = $!;
-$err2 = '';
-$server_listen = '' if ! $server_listen;
-
-my $server_listen6 = '';
-if ($have_inet6) {
- eval {$server_listen6 = IO::Socket::INET6->new(
- Listen => 10,
- LocalPort => $server_port,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => "::",
- Proto => "tcp"
- );};
- $err2 = $!;
-}
-if (! $server_listen && ! $server_listen6) {
- cleanup();
- die "$prog: error: server listen on port $server_port: $err1 - $err2\n";
-}
-
-my $select = new IO::Select();
-if (! $select) {
- cleanup();
- die "$prog: select $!\n";
-}
-
-$select->add($client_listen) if $client_listen;
-$select->add($client_listen6) if $client_listen6;
-$select->add($server_listen) if $server_listen;
-$select->add($server_listen6) if $server_listen6;
-
-$SIG{INT} = sub {cleanup(); exit;};
-$SIG{TERM} = sub {cleanup(); exit;};
-
-my $SOCK1 = '';
-my $SOCK2 = '';
-my $CURR = '';
-
-lprint("$prog: starting up. pid: $$");
-lprint("watching for IPv4 connections on $client_port/client.") if $client_listen;
-lprint("watching for IPv4 connections on $server_port/server.") if $server_listen;
-lprint("watching for IPv6 connections on $client_port/client.") if $client_listen6;
-lprint("watching for IPv6 connections on $server_port/server.") if $server_listen6;
-
-my $alarm_sock = '';
-my $got_alarm = 0;
-sub alarm_handler {
- lprint("$prog: got sig alarm.");
- if ($alarm_sock ne '') {
- close $alarm_sock;
- }
- $alarm_sock = '';
- $got_alarm = 1;
-}
-
-while (my @ready = $select->can_read()) {
- foreach my $fh (@ready) {
- if (($client_listen && $fh == $client_listen) || ($client_listen6 && $fh == $client_listen6)) {
- lprint("new vnc client connecting.");
- } elsif (($server_listen && $fh == $server_listen) || ($server_listen6 && $fh == $server_listen6)) {
- lprint("new vnc server connecting.");
- }
- my $sock = $fh->accept();
- if (! $sock) {
- lprint("$prog: accept $!");
- next;
- }
-
- if (($client_listen && $fh == $client_listen) || ($client_listen6 && $fh == $client_listen6)) {
- if (exists $ENV{ULTRAVNC_REPEATER_NO_RFB} && $ENV{ULTRAVNC_REPEATER_NO_RFB}) {
- lprint("ULTRAVNC_REPEATER_NO_RFB: not sending RFB 000.000");
- } else {
- my $str = "RFB 000.000\n";
- my $len = length $str;
- my $n = syswrite($sock, $str, $len, 0);
- if ($n != $len) {
- lprint("$prog: bad $str write: $n != $len $!");
- close $sock;
- }
- }
- }
-
- my $buf = '';
- my $size = $repeater_bufsize;
- $size = 1024 unless $size;
-
- $SIG{ALRM} = "alarm_handler";
- $alarm_sock = $sock;
- $got_alarm = 0;
- alarm($init_timeout);
- my $n = sysread($sock, $buf, $size);
- alarm(0);
-
- if ($got_alarm) {
- lprint("$prog: read timed out: $!");
- } elsif (! defined $n) {
- lprint("$prog: read error: $!");
- } elsif ($repeater_bufsize > 0 && $n != $size) {
- lprint("$prog: short read $n != $size $!");
- close $sock;
- } elsif (($client_listen && $fh == $client_listen) || ($client_listen6 && $fh == $client_listen6)) {
- do_new_client($sock, $buf);
- } elsif (($server_listen && $fh == $server_listen) || ($server_listen6 && $fh == $server_listen6)) {
- do_new_server($sock, $buf);
- }
- }
-}
-
-sub do_new_client {
- my ($sock, $buf) = @_;
-
- if ($buf =~ /^ID:(\w+)/) {
- my $id = $1;
- if (exists $ID{$id} && exists $ID{$id}{client} && $ID{$id}{client} eq "0") {
- if (!established($ID{$id}{sock})) {
- lprint("server socket for ID:$id is no longer established, closing it.");
- close $ID{$id}{sock};
- delete $ID{$id};
- } else {
- lprint("server socket for ID:$id is still established.");
- }
- }
- if (exists $ID{$id}) {
- if ($ID{$id}{client}) {
- my $ref = $refuse;
- if ($ref && !established($ID{$id}{sock})) {
- lprint("socket for ID:$id is no longer established, closing it.");
- $ref = 0;
- }
- if ($ref) {
- lprint("refusing extra vnc client for ID:$id.");
- close $sock;
- return;
- } else {
- lprint("closing and deleting previous vnc client with ID:$id.");
- close $ID{$id}{sock};
-
- lprint("storing new vnc client with ID:$id.");
- $ID{$id}{client} = 1;
- $ID{$id}{sock} = $sock;
- }
- } else {
- lprint("hooking up new vnc client with existing vnc server for ID:$id.");
- my $sock2 = $ID{$id}{sock};
- delete $ID{$id};
- hookup($sock, $sock2, "ID:$id");
- }
- } else {
- lprint("storing new vnc client with ID:$id.");
- $ID{$id}{client} = 1;
- $ID{$id}{sock} = $sock;
- }
- } else {
- my $str = sprintf("%s", $buf);
- $str =~ s/\s*$//g;
- $str =~ s/\0*$//g;
- my $host = '';
- my $port = '';
- if ($str =~ /^(.+):(\d+)$/) {
- $host = $1;
- $port = $2;
- } else {
- $host = $str;
- $port = 5900;
- }
- if ($port < 0) {
- my $pnew = -$port;
- lprint("resetting port from $port to $pnew.");
- $port = $pnew;
- } elsif ($port < 200) {
- my $pnew = $port + 5900;
- lprint("resetting port from $port to $pnew.");
- $port = $pnew;
- }
- lprint("making vnc client connection directly to vnc server host='$host' port='$port'.");
- my $sock2 = IO::Socket::INET->new(
- PeerAddr => $host,
- PeerPort => $port,
- Proto => "tcp"
- );
- if (! $sock2 && $have_inet6) {
- lprint("IPv4 connect error: $!, trying IPv6 ...");
- eval{$sock2 = IO::Socket::INET6->new(
- PeerAddr => $host,
- PeerPort => $port,
- Proto => "tcp"
- );};
- lprint("IPv6 connect error: $!") if !$sock2;
- } else {
- lprint("IPv4 connect error: $!") if !$sock2;
- }
- if (!$sock2) {
- lprint("failed to connect to $host:$port.");
- close $sock;
- return;
- }
- hookup($sock, $sock2, "$host:$port");
- }
-}
-
-sub do_new_server {
- my ($sock, $buf) = @_;
-
- if ($buf =~ /^ID:(\w+)/) {
- my $id = $1;
- my $store = 1;
- if (exists $ID{$id} && exists $ID{$id}{client} && $ID{$id}{client} eq "1") {
- if (!established($ID{$id}{sock})) {
- lprint("client socket for ID:$id is no longer established, closing it.");
- close $ID{$id}{sock};
- delete $ID{$id};
- } else {
- lprint("client socket for ID:$id is still established.");
- }
- }
- if (exists $ID{$id}) {
- if (! $ID{$id}{client}) {
- my $ref = $refuse;
- if ($ref && !established($ID{$id}{sock})) {
- lprint("socket for ID:$id is no longer established, closing it.");
- $ref = 0;
- }
- if ($ref) {
- lprint("refusing extra vnc server for ID:$id.");
- close $sock;
- return;
- } else {
- lprint("closing and deleting previous vnc server with ID:$id.");
- close $ID{$id}{sock};
-
- lprint("storing new vnc server with ID:$id.");
- $ID{$id}{client} = 0;
- $ID{$id}{sock} = $sock;
- }
- } else {
- lprint("hooking up new vnc server with existing vnc client for ID:$id.");
- my $sock2 = $ID{$id}{sock};
- delete $ID{$id};
- hookup($sock, $sock2, "ID:$id");
- }
- } else {
- lprint("storing new vnc server with ID:$id.");
- $ID{$id}{client} = 0;
- $ID{$id}{sock} = $sock;
- }
- } else {
- lprint("invalid ID:NNNNN string for vnc server: $buf");
- close $sock;
- return;
- }
-}
-
-sub established {
- my $fh = shift;
-
- return established_linux_proc($fh);
-
- # not working:
- my $est = 1;
- my $str = "Z";
- my $res;
- #$res = recv($fh, $str, 1, MSG_PEEK | MSG_DONTWAIT);
- if (defined($res)) {
- lprint("established OK: $! '$str'.");
- $est = 1;
- } else {
- # would check for EAGAIN here to decide ...
- lprint("established err: $! '$str'.");
- $est = 1;
- }
- return $est;
-}
-
-
-sub established_linux_proc {
- # hack for Linux to see if remote side has gone away:
- my $fh = shift;
-
- # if we can't figure things out, we must return true.
- if ($uname !~ /Linux/) {
- return 1;
- }
-
- my @proc_net_tcp = ();
- if (-e "/proc/net/tcp") {
- push @proc_net_tcp, "/proc/net/tcp";
- }
- if (-e "/proc/net/tcp6") {
- push @proc_net_tcp, "/proc/net/tcp6";
- }
- if (! @proc_net_tcp) {
- return 1;
- }
-
- my $n = fileno($fh);
- if (!defined($n)) {
- return 1;
- }
-
- my $proc_fd = "/proc/$$/fd/$n";
- if (! -e $proc_fd) {
- return 1;
- }
-
- my $val = readlink($proc_fd);
- if (! defined $val || $val !~ /socket:\[(\d+)\]/) {
- return 1;
- }
- my $num = $1;
-
- my $st = '';
-
- foreach my $tcp (@proc_net_tcp) {
- if (! open(TCP, "<$tcp")) {
- next;
- }
- while (<TCP>) {
- next if /^\s*[A-z]/;
- chomp;
- # sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
- # 170: 0102000A:170C FE02000A:87FA 01 00000000:00000000 00:00000000 00000000 1001 0 423294766 1 f6fa4100 21 4 4 2 -1
- # 172: 0102000A:170C FE02000A:87FA 08 00000000:00000001 00:00000000 00000000 1001 0 423294766 1 f6fa4100 21 4 4 2 -1
- my @items = split(' ', $_);
- my $state = $items[3];
- my $inode = $items[9];
- if (!defined $state || $state !~ /^\d+$/) {
- next;
- }
- if (!defined $inode || $inode !~ /^\d+$/) {
- next;
- }
- if ($inode == $num) {
- $st = $state;
- last;
- }
- }
- close TCP;
- last if $st ne '';
- }
-
- if ($st ne '' && $st != 1) {
- return 0;
- }
- return 1;
-}
-
-sub handler {
- lprint("\[$$/$CURR] got SIGTERM.");
- close $SOCK1 if $SOCK1;
- close $SOCK2 if $SOCK2;
- exit;
-}
-
-sub hookup {
- my ($sock1, $sock2, $tag) = @_;
-
- my $worker = fork();
-
- if (! defined $worker) {
- lprint("failed to fork worker: $!");
- close $sock1;
- close $sock2;
- return;
- } elsif ($worker) {
- close $sock1;
- close $sock2;
- wait;
- } else {
- cleanup();
- if (fork) {
- exit 0;
- }
- setpgrp(0, 0);
- $SOCK1 = $sock1;
- $SOCK2 = $sock2;
- $CURR = $tag;
- $SIG{TERM} = "handler";
- $SIG{INT} = "handler";
- xfer_both($sock1, $sock2);
- exit 0;
- }
-}
-
-sub xfer {
- my ($in, $out) = @_;
-
- $RIN = $WIN = $EIN = "";
- $ROUT = "";
- vec($RIN, fileno($in), 1) = 1;
- vec($WIN, fileno($in), 1) = 1;
- $EIN = $RIN | $WIN;
-
- my $buf;
-
- while (1) {
- my $nf = 0;
- while (! $nf) {
- $nf = select($ROUT=$RIN, undef, undef, undef);
- }
- my $len = sysread($in, $buf, 8192);
- if (! defined($len)) {
- next if $! =~ /^Interrupted/;
- lprint("\[$$/$CURR] $!");
- last;
- } elsif ($len == 0) {
- lprint("\[$$/$CURR] Input is EOF.");
- last;
- }
- my $offset = 0;
- my $quit = 0;
- while ($len) {
- my $written = syswrite($out, $buf, $len, $offset);
- if (! defined $written) {
- lprint("\[$$/$CURR] Output is EOF. $!");
- $quit = 1;
- last;
- }
- $len -= $written;
- $offset += $written;
- }
- last if $quit;
- }
- close($out);
- close($in);
- lprint("\[$$/$CURR] finished xfer.");
-}
-
-sub xfer_both {
- my ($sock1, $sock2) = @_;
-
- my $parent = $$;
-
- my $child = fork();
-
- if (! defined $child) {
- lprint("$prog\[$$/$CURR] failed to fork: $!");
- return;
- }
-
- $SIG{TERM} = "handler";
- $SIG{INT} = "handler";
-
- if ($child) {
- lprint("[$$/$CURR] parent 1 -> 2.");
- xfer($sock1, $sock2);
- select(undef, undef, undef, 0.25);
- if (kill 0, $child) {
- select(undef, undef, undef, 0.9);
- if (kill 0, $child) {
- lprint("\[$$/$CURR] kill TERM child $child");
- kill "TERM", $child;
- } else {
- lprint("\[$$/$CURR] child $child gone.");
- }
- }
- } else {
- select(undef, undef, undef, 0.05);
- lprint("[$$/$CURR] child 2 -> 1.");
- xfer($sock2, $sock1);
- select(undef, undef, undef, 0.25);
- if (kill 0, $parent) {
- select(undef, undef, undef, 0.8);
- if (kill 0, $parent) {
- lprint("\[$$/$CURR] kill TERM parent $parent.");
- kill "TERM", $parent;
- } else {
- lprint("\[$$/$CURR] parent $parent gone.");
- }
- }
- }
-}
-
-sub fsleep {
- my ($time) = @_;
- select(undef, undef, undef, $time) if $time;
-}
-
-sub cleanup {
- close $client_listen if $client_listen;
- close $client_listen6 if $client_listen6;
- close $server_listen if $server_listen;
- close $server_listen6 if $server_listen6;
- foreach my $id (keys %ID) {
- close $ID{$id}{sock};
- }
-}
diff --git a/x11vnc/misc/vcinject.pl b/x11vnc/misc/vcinject.pl
deleted file mode 100755
index b371d4e..0000000
--- a/x11vnc/misc/vcinject.pl
+++ /dev/null
@@ -1,113 +0,0 @@
- #!/bin/sh -- # A comment mentioning perl
-eval 'exec perl -S $0 ${1+"$@"}'
- if 0;
-#
-# vcinject.pl: simple hack to inject keystrokes into Linux VC tty.
-# See LinuxVNC.c for a more careful treatment using C and public API.
-#
-# Usage: vcinject.pl <N> (or /dev/ttyN)
-#
-# This is an example x11vnc -pipeinput program E.g.:
-#
-# x11vnc -rawfb map:/dev/fb0@1024x768x16 -pipeinput "vcinject.pl /dev/tty3"
-#
-# (see fbset(8) for obtaining fb info).
-#
-# It reads lines like this from STDIN:
-#
-# Keysym <id> <down> <n> <Keysym> ...
-#
-# <id> is ignored, it uses the rest to deduce the keystrokes to send
-# to the console.
-#
-
-$tty = shift;
-$tty = "/dev/tty$tty" if $tty =~ /^\d+$/;
-
-warn "strange tty device: $tty\n" if $tty !~ m,^/dev/tty\d+$,;
-
-open(TTY, ">$tty") || die "open $tty: $!\n";
-$fd = fileno(TTY);
-
-$linux_ioctl_syscall = 54; # common knowledge, eh? :-)
-$TIOCSTI = 0x5412;
-
-%Map = qw(
- Escape 27
- Tab 9
- Return 13
- BackSpace 8
- Home 1
- End 5
- Up 16
- Down 14
- Right 6
- Left 2
- Next 6
- Prior 2
-);
-# the latter few above seem to be vi specials. (since they are normally
-# escape sequences, e.g. ESC [ 5 ~)
-
-sub lookup {
- my($down, $key, $name) = @_;
-
- my $n = -1;
- $name =~ s/^KP_//;
-
- # algorithm borrowed from LinuxVNC.c:
- if (! $down) {
- if ($name =~ /^Control/) {
- $control--;
- }
- return $n;
- }
-
- if ($name =~ /^Control/) {
- $control++;
- } else {
- if (exists($Map{$name})) {
- $n = $Map{$name};
- }
- if ($control && $name =~ /^[A-z]$/) {
- $n = ord($name);
- # shift down to the Control zone:
- if ($name =~ /[a-z]/) {
- $n -= (ord("a") - 1);
- } else {
- $n -= (ord("A") - 1);
- }
- }
- if ($n < 0 && $key < 256) {
- $n = $key;
- }
- }
- return $n;
-}
-
-$control = 0;
-$debug = 0;
-
-while (<>) {
- chomp;
- if (/^\w+$/) {
- # for debugging, you type the keysym in manually.
- $_ = "Keysym 1 0 999 $_ None";
- }
- next unless /^Keysym/;
-
- my ($j, $id, $down, $k, $keysym, $rest) = split(' ', $_);
-
- $n = lookup($down, $k, $keysym);
- if ($n < 0 || $n > 255) {
- print STDERR "skip: '$keysym' -> $n\n" if $down && $debug;
- next;
- }
-
- $n_p = pack("c", $n);
- $ret = syscall($linux_ioctl_syscall, $fd, $TIOCSTI, $n_p);
-
- print STDERR "ctrl=$control $keysym/$k syscall(" .
- "$linux_ioctl_syscall, $fd, $TIOCSTI, $n) = $ret\n" if $debug;
-
-}
diff --git a/x11vnc/misc/x11vnc_loop b/x11vnc/misc/x11vnc_loop
deleted file mode 100755
index 1a3e0a2..0000000
--- a/x11vnc/misc/x11vnc_loop
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/sh
-#
-# x11vnc_loop:
-#
-# Example startup script for connecting x11vnc to an X display
-# at system boot up and having it reconnect when the X server restarts.
-#
-# Run, in rc.local say, via, e.g.:
-#
-# /path/to/x11vnc_loop 1>> /var/tmp/x11vnc_loop.log 2>&1 &
-#
-# call with argument "once" or a number to limit the number of loops.
-#
-##########################################################################
-# The following needs to be customized:
-x11vnc_cmd=x11vnc # or use full path (or set PATH).
-pwfile=/path/to/vnc/passwd # always use a password
-display=:0 # display of interest
-restart_sleep=5 # pause between X server restarts.
-
-# modify cmdline args if desired:
-x11vnc_args="-display $display -rfbauth $pwfile -forever -nap"
-
-# you may need to customize the "grep", etc, below in get_xauthority_file()
-##########################################################################
-
-if [ "X$1" != "X" ]; then
- max=$1
- shift
-fi
-
-get_xauthority_file() {
- #
- # We need to find the MIT-COOKIE file... this not portable at all,
- # depends on OS, distro, desktop, phase of moon, etc...
- #
- # If the cookie file was fixed and you knew it, you could just
- # return it here e.g.:
- #
- ## echo "/var/gdm/:0.Xauth"; return
- #
- # or, if you knew the directory, you could look for the youngest
- # file there and return it e.g.:
- #
- ## echo `ls -t /var/lib/xdm/authdir/authfiles/* | head -1`; return
-
- # this hack tries to grep it out of ps output...
- xauth=""
- for i in 1 2 3
- do
- # very linux specific, and you likely need to tweak..
- patt="X11R6.*/X.*-auth"
- xauth=`ps wwwaux | grep "$patt" \
- | egrep -v 'grep|Xprt' | head -1 \
- | sed -e 's/^.*-auth//' | awk '{print $1}'`
-
- if [ "X$xauth" != "X" ]; then
- break
- fi
- sleep 2 # wait a bit in case X server is restarting slowly.
- done
- echo $xauth
-}
-
-try=1
-while [ 1 ]
-do
- echo "`date` $0 try number: $try"; try=`expr $try + 1`
-
- auth=`get_xauthority_file`
- if [ ! -r "$auth" ]; then
- echo "`date` bad auth file: \"$auth\""
- else
- cmd="$x11vnc_cmd $x11vnc_args"
- sleep 1
- echo "`date` running: $cmd -auth $auth"
- # run x11vnc:
- $cmd -auth $auth
- if [ "X$max" = "Xonce" ]; then
- exit $?
- fi
- fi
- if echo "$max" | grep '[0-9]' > /dev/null; then
- if [ $try -gt $max ]; then
- exit
- fi
- fi
- sleep $restart_sleep
-done
diff --git a/x11vnc/misc/x11vnc_pw b/x11vnc/misc/x11vnc_pw
deleted file mode 100755
index 04ea1e3..0000000
--- a/x11vnc/misc/x11vnc_pw
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-# usage: x11vnc_pw [file] (default: ~/.vnc/passwd)
-
-if [ "X$1" = "X" ]; then
- file=$HOME/.vnc/passwd
-else
- file=$1
-fi
-
-stty -echo
-printf "Password: "
-read pw1; echo ""
-printf "Verify: "
-read pw2; echo ""
-stty echo
-
-if [ "X$pw1" != "X$pw2" ]; then
- echo "passwords do not match."
- exit 1
-fi
-
-x11vnc -help > /dev/null 2>&1
-x11vnc -storepasswd "$pw1" "$file"
-ls -l "$file"
diff --git a/x11vnc/nox11.h b/x11vnc/nox11.h
deleted file mode 100644
index 1dcc974..0000000
--- a/x11vnc/nox11.h
+++ /dev/null
@@ -1,6671 +0,0 @@
-#undef LIBVNCSERVER_HAVE_XSHM
-#define LIBVNCSERVER_HAVE_XSHM 0
-#undef LIBVNCSERVER_HAVE_XTEST
-#define LIBVNCSERVER_HAVE_XTEST 0
-#undef LIBVNCSERVER_HAVE_XTESTGRABCONTROL
-#define LIBVNCSERVER_HAVE_XTESTGRABCONTROL 0
-#undef LIBVNCSERVER_HAVE_XKEYBOARD
-#define LIBVNCSERVER_HAVE_XKEYBOARD 0
-#undef LIBVNCSERVER_HAVE_LIBXINERAMA
-#define LIBVNCSERVER_HAVE_LIBXINERAMA 0
-#undef LIBVNCSERVER_HAVE_LIBXRANDR
-#define LIBVNCSERVER_HAVE_LIBXRANDR 0
-#undef LIBVNCSERVER_HAVE_LIBXFIXES
-#define LIBVNCSERVER_HAVE_LIBXFIXES 0
-#undef LIBVNCSERVER_HAVE_LIBXDAMAGE
-#define LIBVNCSERVER_HAVE_LIBXDAMAGE 0
-#undef LIBVNCSERVER_HAVE_RECORD
-#define LIBVNCSERVER_HAVE_RECORD 0
-#undef LIBVNCSERVER_HAVE_LIBXTRAP
-#define LIBVNCSERVER_HAVE_LIBXTRAP 0
-#undef LIBVNCSERVER_HAVE_SOLARIS_XREADSCREEN
-#define LIBVNCSERVER_HAVE_SOLARIS_XREADSCREEN 0
-#undef LIBVNCSERVER_HAVE_IRIX_XREADDISPLAY
-#define LIBVNCSERVER_HAVE_IRIX_XREADDISPLAY 0
-#undef LIBVNCSERVER_HAVE_FBPM
-#define LIBVNCSERVER_HAVE_FBPM 0
-
-/* default keysyms */
-#if 0
-/* XXX go with the subset in rfb/keysym.h for now */
-#define XK_MISCELLANY
-#define XK_XKB_KEYS
-#define XK_LATIN1
-#define XK_LATIN2
-#define XK_LATIN3
-#define XK_LATIN4
-#define XK_LATIN8
-#define XK_LATIN9
-#define XK_CAUCASUS
-#define XK_GREEK
-#define XK_KATAKANA
-#define XK_ARABIC
-#define XK_CYRILLIC
-#define XK_HEBREW
-#define XK_THAI
-#define XK_KOREAN
-#define XK_ARMENIAN
-#define XK_GEORGIAN
-#define XK_VIETNAMESE
-#define XK_CURRENCY
-#endif
-
-/*
- * $Xorg: X.h,v 1.4 2001/02/09 02:03:22 xorgcvs Exp $
- */
-
-/* Definitions for the X window system likely to be used by applications */
-
-#ifndef X_H
-#define X_H
-
-/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-/* $XFree86: xc/include/X.h,v 1.5 2001/12/14 19:53:25 dawes Exp $ */
-
-#define X_PROTOCOL 11 /* current protocol version */
-#define X_PROTOCOL_REVISION 0 /* current minor version */
-
-/* Resources */
-
-/*
- * _XSERVER64 must ONLY be defined when compiling X server sources on
- * systems where unsigned long is not 32 bits, must NOT be used in
- * client or library code.
- */
-#ifndef _XSERVER64
-# ifndef _XTYPEDEF_XID
-# define _XTYPEDEF_XID
-typedef unsigned long XID;
-# endif
-# ifndef _XTYPEDEF_MASK
-# define _XTYPEDEF_MASK
-typedef unsigned long Mask;
-# endif
-# ifndef _XTYPEDEF_ATOM
-# define _XTYPEDEF_ATOM
-typedef unsigned long Atom; /* Also in Xdefs.h */
-# endif
-typedef unsigned long VisualID;
-typedef unsigned long Time;
-#else
-# include <X11/Xmd.h>
-# ifndef _XTYPEDEF_XID
-# define _XTYPEDEF_XID
-typedef CARD32 XID;
-# endif
-# ifndef _XTYPEDEF_MASK
-# define _XTYPEDEF_MASK
-typedef CARD32 Mask;
-# endif
-# ifndef _XTYPEDEF_ATOM
-# define _XTYPEDEF_ATOM
-typedef CARD32 Atom;
-# endif
-typedef CARD32 VisualID;
-typedef CARD32 Time;
-#endif
-
-typedef XID Window;
-typedef XID Drawable;
-#ifndef _XTYPEDEF_FONT
-# define _XTYPEDEF_FONT
-typedef XID Font;
-#endif
-typedef XID Pixmap;
-typedef XID Cursor;
-typedef XID Colormap;
-typedef XID GContext;
-typedef XID KeySym;
-
-typedef unsigned char KeyCode;
-
-/*****************************************************************
- * RESERVED RESOURCE AND CONSTANT DEFINITIONS
- *****************************************************************/
-
-#ifndef None
-#define None 0L /* universal null resource or null atom */
-#endif
-
-#define ParentRelative 1L /* background pixmap in CreateWindow
- and ChangeWindowAttributes */
-
-#define CopyFromParent 0L /* border pixmap in CreateWindow
- and ChangeWindowAttributes
- special VisualID and special window
- class passed to CreateWindow */
-
-#define PointerWindow 0L /* destination window in SendEvent */
-#define InputFocus 1L /* destination window in SendEvent */
-
-#define PointerRoot 1L /* focus window in SetInputFocus */
-
-#define AnyPropertyType 0L /* special Atom, passed to GetProperty */
-
-#define AnyKey 0L /* special Key Code, passed to GrabKey */
-
-#define AnyButton 0L /* special Button Code, passed to GrabButton */
-
-#define AllTemporary 0L /* special Resource ID passed to KillClient */
-
-#define CurrentTime 0L /* special Time */
-
-#define NoSymbol 0L /* special KeySym */
-
-/*****************************************************************
- * EVENT DEFINITIONS
- *****************************************************************/
-
-/* Input Event Masks. Used as event-mask window attribute and as arguments
- to Grab requests. Not to be confused with event names. */
-
-#define NoEventMask 0L
-#define KeyPressMask (1L<<0)
-#define KeyReleaseMask (1L<<1)
-#define ButtonPressMask (1L<<2)
-#define ButtonReleaseMask (1L<<3)
-#define EnterWindowMask (1L<<4)
-#define LeaveWindowMask (1L<<5)
-#define PointerMotionMask (1L<<6)
-#define PointerMotionHintMask (1L<<7)
-#define Button1MotionMask (1L<<8)
-#define Button2MotionMask (1L<<9)
-#define Button3MotionMask (1L<<10)
-#define Button4MotionMask (1L<<11)
-#define Button5MotionMask (1L<<12)
-#define ButtonMotionMask (1L<<13)
-#define KeymapStateMask (1L<<14)
-#define ExposureMask (1L<<15)
-#define VisibilityChangeMask (1L<<16)
-#define StructureNotifyMask (1L<<17)
-#define ResizeRedirectMask (1L<<18)
-#define SubstructureNotifyMask (1L<<19)
-#define SubstructureRedirectMask (1L<<20)
-#define FocusChangeMask (1L<<21)
-#define PropertyChangeMask (1L<<22)
-#define ColormapChangeMask (1L<<23)
-#define OwnerGrabButtonMask (1L<<24)
-
-/* Event names. Used in "type" field in XEvent structures. Not to be
-confused with event masks above. They start from 2 because 0 and 1
-are reserved in the protocol for errors and replies. */
-
-#define KeyPress 2
-#define KeyRelease 3
-#define ButtonPress 4
-#define ButtonRelease 5
-#define MotionNotify 6
-#define EnterNotify 7
-#define LeaveNotify 8
-#define FocusIn 9
-#define FocusOut 10
-#define KeymapNotify 11
-#define Expose 12
-#define GraphicsExpose 13
-#define NoExpose 14
-#define VisibilityNotify 15
-#define CreateNotify 16
-#define DestroyNotify 17
-#define UnmapNotify 18
-#define MapNotify 19
-#define MapRequest 20
-#define ReparentNotify 21
-#define ConfigureNotify 22
-#define ConfigureRequest 23
-#define GravityNotify 24
-#define ResizeRequest 25
-#define CirculateNotify 26
-#define CirculateRequest 27
-#define PropertyNotify 28
-#define SelectionClear 29
-#define SelectionRequest 30
-#define SelectionNotify 31
-#define ColormapNotify 32
-#define ClientMessage 33
-#define MappingNotify 34
-#define LASTEvent 35 /* must be bigger than any event # */
-
-
-/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer,
- state in various key-, mouse-, and button-related events. */
-
-#define ShiftMask (1<<0)
-#define LockMask (1<<1)
-#define ControlMask (1<<2)
-#define Mod1Mask (1<<3)
-#define Mod2Mask (1<<4)
-#define Mod3Mask (1<<5)
-#define Mod4Mask (1<<6)
-#define Mod5Mask (1<<7)
-
-/* modifier names. Used to build a SetModifierMapping request or
- to read a GetModifierMapping request. These correspond to the
- masks defined above. */
-#define ShiftMapIndex 0
-#define LockMapIndex 1
-#define ControlMapIndex 2
-#define Mod1MapIndex 3
-#define Mod2MapIndex 4
-#define Mod3MapIndex 5
-#define Mod4MapIndex 6
-#define Mod5MapIndex 7
-
-
-/* button masks. Used in same manner as Key masks above. Not to be confused
- with button names below. */
-
-#define Button1Mask (1<<8)
-#define Button2Mask (1<<9)
-#define Button3Mask (1<<10)
-#define Button4Mask (1<<11)
-#define Button5Mask (1<<12)
-
-#define AnyModifier (1<<15) /* used in GrabButton, GrabKey */
-
-
-/* button names. Used as arguments to GrabButton and as detail in ButtonPress
- and ButtonRelease events. Not to be confused with button masks above.
- Note that 0 is already defined above as "AnyButton". */
-
-#define Button1 1
-#define Button2 2
-#define Button3 3
-#define Button4 4
-#define Button5 5
-
-/* Notify modes */
-
-#define NotifyNormal 0
-#define NotifyGrab 1
-#define NotifyUngrab 2
-#define NotifyWhileGrabbed 3
-
-#define NotifyHint 1 /* for MotionNotify events */
-
-/* Notify detail */
-
-#define NotifyAncestor 0
-#define NotifyVirtual 1
-#define NotifyInferior 2
-#define NotifyNonlinear 3
-#define NotifyNonlinearVirtual 4
-#define NotifyPointer 5
-#define NotifyPointerRoot 6
-#define NotifyDetailNone 7
-
-/* Visibility notify */
-
-#define VisibilityUnobscured 0
-#define VisibilityPartiallyObscured 1
-#define VisibilityFullyObscured 2
-
-/* Circulation request */
-
-#define PlaceOnTop 0
-#define PlaceOnBottom 1
-
-/* protocol families */
-
-#define FamilyInternet 0
-#define FamilyDECnet 1
-#define FamilyChaos 2
-
-/* Property notification */
-
-#define PropertyNewValue 0
-#define PropertyDelete 1
-
-/* Color Map notification */
-
-#define ColormapUninstalled 0
-#define ColormapInstalled 1
-
-/* GrabPointer, GrabButton, GrabKeyboard, GrabKey Modes */
-
-#define GrabModeSync 0
-#define GrabModeAsync 1
-
-/* GrabPointer, GrabKeyboard reply status */
-
-#define GrabSuccess 0
-#define AlreadyGrabbed 1
-#define GrabInvalidTime 2
-#define GrabNotViewable 3
-#define GrabFrozen 4
-
-/* AllowEvents modes */
-
-#define AsyncPointer 0
-#define SyncPointer 1
-#define ReplayPointer 2
-#define AsyncKeyboard 3
-#define SyncKeyboard 4
-#define ReplayKeyboard 5
-#define AsyncBoth 6
-#define SyncBoth 7
-
-/* Used in SetInputFocus, GetInputFocus */
-
-#define RevertToNone (int)None
-#define RevertToPointerRoot (int)PointerRoot
-#define RevertToParent 2
-
-/*****************************************************************
- * ERROR CODES
- *****************************************************************/
-
-#define Success 0 /* everything's okay */
-#define BadRequest 1 /* bad request code */
-#define BadValue 2 /* int parameter out of range */
-#define BadWindow 3 /* parameter not a Window */
-#define BadPixmap 4 /* parameter not a Pixmap */
-#define BadAtom 5 /* parameter not an Atom */
-#define BadCursor 6 /* parameter not a Cursor */
-#define BadFont 7 /* parameter not a Font */
-#define BadMatch 8 /* parameter mismatch */
-#define BadDrawable 9 /* parameter not a Pixmap or Window */
-#define BadAccess 10 /* depending on context:
- - key/button already grabbed
- - attempt to free an illegal
- cmap entry
- - attempt to store into a read-only
- color map entry.
- - attempt to modify the access control
- list from other than the local host.
- */
-#define BadAlloc 11 /* insufficient resources */
-#define BadColor 12 /* no such colormap */
-#define BadGC 13 /* parameter not a GC */
-#define BadIDChoice 14 /* choice not in range or already used */
-#define BadName 15 /* font or color name doesn't exist */
-#define BadLength 16 /* Request length incorrect */
-#define BadImplementation 17 /* server is defective */
-
-#define FirstExtensionError 128
-#define LastExtensionError 255
-
-/*****************************************************************
- * WINDOW DEFINITIONS
- *****************************************************************/
-
-/* Window classes used by CreateWindow */
-/* Note that CopyFromParent is already defined as 0 above */
-
-#define InputOutput 1
-#define InputOnly 2
-
-/* Window attributes for CreateWindow and ChangeWindowAttributes */
-
-#define CWBackPixmap (1L<<0)
-#define CWBackPixel (1L<<1)
-#define CWBorderPixmap (1L<<2)
-#define CWBorderPixel (1L<<3)
-#define CWBitGravity (1L<<4)
-#define CWWinGravity (1L<<5)
-#define CWBackingStore (1L<<6)
-#define CWBackingPlanes (1L<<7)
-#define CWBackingPixel (1L<<8)
-#define CWOverrideRedirect (1L<<9)
-#define CWSaveUnder (1L<<10)
-#define CWEventMask (1L<<11)
-#define CWDontPropagate (1L<<12)
-#define CWColormap (1L<<13)
-#define CWCursor (1L<<14)
-
-/* ConfigureWindow structure */
-
-#define CWX (1<<0)
-#define CWY (1<<1)
-#define CWWidth (1<<2)
-#define CWHeight (1<<3)
-#define CWBorderWidth (1<<4)
-#define CWSibling (1<<5)
-#define CWStackMode (1<<6)
-
-
-/* Bit Gravity */
-
-#define ForgetGravity 0
-#define NorthWestGravity 1
-#define NorthGravity 2
-#define NorthEastGravity 3
-#define WestGravity 4
-#define CenterGravity 5
-#define EastGravity 6
-#define SouthWestGravity 7
-#define SouthGravity 8
-#define SouthEastGravity 9
-#define StaticGravity 10
-
-/* Window gravity + bit gravity above */
-
-#define UnmapGravity 0
-
-/* Used in CreateWindow for backing-store hint */
-
-#define NotUseful 0
-#define WhenMapped 1
-#define Always 2
-
-/* Used in GetWindowAttributes reply */
-
-#define IsUnmapped 0
-#define IsUnviewable 1
-#define IsViewable 2
-
-/* Used in ChangeSaveSet */
-
-#define SetModeInsert 0
-#define SetModeDelete 1
-
-/* Used in ChangeCloseDownMode */
-
-#define DestroyAll 0
-#define RetainPermanent 1
-#define RetainTemporary 2
-
-/* Window stacking method (in configureWindow) */
-
-#define Above 0
-#define Below 1
-#define TopIf 2
-#define BottomIf 3
-#define Opposite 4
-
-/* Circulation direction */
-
-#define RaiseLowest 0
-#define LowerHighest 1
-
-/* Property modes */
-
-#define PropModeReplace 0
-#define PropModePrepend 1
-#define PropModeAppend 2
-
-/*****************************************************************
- * GRAPHICS DEFINITIONS
- *****************************************************************/
-
-/* graphics functions, as in GC.alu */
-
-#define GXclear 0x0 /* 0 */
-#define GXand 0x1 /* src AND dst */
-#define GXandReverse 0x2 /* src AND NOT dst */
-#define GXcopy 0x3 /* src */
-#define GXandInverted 0x4 /* NOT src AND dst */
-#define GXnoop 0x5 /* dst */
-#define GXxor 0x6 /* src XOR dst */
-#define GXor 0x7 /* src OR dst */
-#define GXnor 0x8 /* NOT src AND NOT dst */
-#define GXequiv 0x9 /* NOT src XOR dst */
-#define GXinvert 0xa /* NOT dst */
-#define GXorReverse 0xb /* src OR NOT dst */
-#define GXcopyInverted 0xc /* NOT src */
-#define GXorInverted 0xd /* NOT src OR dst */
-#define GXnand 0xe /* NOT src OR NOT dst */
-#define GXset 0xf /* 1 */
-
-/* LineStyle */
-
-#define LineSolid 0
-#define LineOnOffDash 1
-#define LineDoubleDash 2
-
-/* capStyle */
-
-#define CapNotLast 0
-#define CapButt 1
-#define CapRound 2
-#define CapProjecting 3
-
-/* joinStyle */
-
-#define JoinMiter 0
-#define JoinRound 1
-#define JoinBevel 2
-
-/* fillStyle */
-
-#define FillSolid 0
-#define FillTiled 1
-#define FillStippled 2
-#define FillOpaqueStippled 3
-
-/* fillRule */
-
-#define EvenOddRule 0
-#define WindingRule 1
-
-/* subwindow mode */
-
-#define ClipByChildren 0
-#define IncludeInferiors 1
-
-/* SetClipRectangles ordering */
-
-#define Unsorted 0
-#define YSorted 1
-#define YXSorted 2
-#define YXBanded 3
-
-/* CoordinateMode for drawing routines */
-
-#define CoordModeOrigin 0 /* relative to the origin */
-#define CoordModePrevious 1 /* relative to previous point */
-
-/* Polygon shapes */
-
-#define Complex 0 /* paths may intersect */
-#define Nonconvex 1 /* no paths intersect, but not convex */
-#define Convex 2 /* wholly convex */
-
-/* Arc modes for PolyFillArc */
-
-#define ArcChord 0 /* join endpoints of arc */
-#define ArcPieSlice 1 /* join endpoints to center of arc */
-
-/* GC components: masks used in CreateGC, CopyGC, ChangeGC, OR'ed into
- GC.stateChanges */
-
-#define GCFunction (1L<<0)
-#define GCPlaneMask (1L<<1)
-#define GCForeground (1L<<2)
-#define GCBackground (1L<<3)
-#define GCLineWidth (1L<<4)
-#define GCLineStyle (1L<<5)
-#define GCCapStyle (1L<<6)
-#define GCJoinStyle (1L<<7)
-#define GCFillStyle (1L<<8)
-#define GCFillRule (1L<<9)
-#define GCTile (1L<<10)
-#define GCStipple (1L<<11)
-#define GCTileStipXOrigin (1L<<12)
-#define GCTileStipYOrigin (1L<<13)
-#define GCFont (1L<<14)
-#define GCSubwindowMode (1L<<15)
-#define GCGraphicsExposures (1L<<16)
-#define GCClipXOrigin (1L<<17)
-#define GCClipYOrigin (1L<<18)
-#define GCClipMask (1L<<19)
-#define GCDashOffset (1L<<20)
-#define GCDashList (1L<<21)
-#define GCArcMode (1L<<22)
-
-#define GCLastBit 22
-/*****************************************************************
- * FONTS
- *****************************************************************/
-
-/* used in QueryFont -- draw direction */
-
-#define FontLeftToRight 0
-#define FontRightToLeft 1
-
-#define FontChange 255
-
-/*****************************************************************
- * IMAGING
- *****************************************************************/
-
-/* ImageFormat -- PutImage, GetImage */
-
-#define XYBitmap 0 /* depth 1, XYFormat */
-#define XYPixmap 1 /* depth == drawable depth */
-#define ZPixmap 2 /* depth == drawable depth */
-
-/*****************************************************************
- * COLOR MAP STUFF
- *****************************************************************/
-
-/* For CreateColormap */
-
-#define AllocNone 0 /* create map with no entries */
-#define AllocAll 1 /* allocate entire map writeable */
-
-
-/* Flags used in StoreNamedColor, StoreColors */
-
-#define DoRed (1<<0)
-#define DoGreen (1<<1)
-#define DoBlue (1<<2)
-
-/*****************************************************************
- * CURSOR STUFF
- *****************************************************************/
-
-/* QueryBestSize Class */
-
-#define CursorShape 0 /* largest size that can be displayed */
-#define TileShape 1 /* size tiled fastest */
-#define StippleShape 2 /* size stippled fastest */
-
-/*****************************************************************
- * KEYBOARD/POINTER STUFF
- *****************************************************************/
-
-#define AutoRepeatModeOff 0
-#define AutoRepeatModeOn 1
-#define AutoRepeatModeDefault 2
-
-#define LedModeOff 0
-#define LedModeOn 1
-
-/* masks for ChangeKeyboardControl */
-
-#define KBKeyClickPercent (1L<<0)
-#define KBBellPercent (1L<<1)
-#define KBBellPitch (1L<<2)
-#define KBBellDuration (1L<<3)
-#define KBLed (1L<<4)
-#define KBLedMode (1L<<5)
-#define KBKey (1L<<6)
-#define KBAutoRepeatMode (1L<<7)
-
-#define MappingSuccess 0
-#define MappingBusy 1
-#define MappingFailed 2
-
-#define MappingModifier 0
-#define MappingKeyboard 1
-#define MappingPointer 2
-
-/*****************************************************************
- * SCREEN SAVER STUFF
- *****************************************************************/
-
-#define DontPreferBlanking 0
-#define PreferBlanking 1
-#define DefaultBlanking 2
-
-#define DisableScreenSaver 0
-#define DisableScreenInterval 0
-
-#define DontAllowExposures 0
-#define AllowExposures 1
-#define DefaultExposures 2
-
-/* for ForceScreenSaver */
-
-#define ScreenSaverReset 0
-#define ScreenSaverActive 1
-
-/*****************************************************************
- * HOSTS AND CONNECTIONS
- *****************************************************************/
-
-/* for ChangeHosts */
-
-#define HostInsert 0
-#define HostDelete 1
-
-/* for ChangeAccessControl */
-
-#define EnableAccess 1
-#define DisableAccess 0
-
-/* Display classes used in opening the connection
- * Note that the statically allocated ones are even numbered and the
- * dynamically changeable ones are odd numbered */
-
-#define StaticGray 0
-#define GrayScale 1
-#define StaticColor 2
-#define PseudoColor 3
-#define TrueColor 4
-#define DirectColor 5
-
-
-/* Byte order used in imageByteOrder and bitmapBitOrder */
-
-#define LSBFirst 0
-#define MSBFirst 1
-
-#endif /* X_H */
-
-
-/* $Xorg: Xlib.h,v 1.6 2001/02/09 02:03:38 xorgcvs Exp $ */
-/*
-
-Copyright 1985, 1986, 1987, 1991, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-/* $XFree86: xc/lib/X11/Xlib.h,v 3.23 2002/05/31 18:45:42 dawes Exp $ */
-
-
-/*
- * Xlib.h - Header definition and support file for the C subroutine
- * interface library (Xlib) to the X Window System Protocol (V11).
- * Structures and symbols starting with "_" are private to the library.
- */
-#ifndef _XLIB_H_
-#define _XLIB_H_
-
-#define XlibSpecificationRelease 6
-
-#ifdef USG
-#ifndef __TYPES__
-#include <sys/types.h> /* forgot to protect it... */
-#define __TYPES__
-#endif /* __TYPES__ */
-#else
-#if defined(_POSIX_SOURCE) && defined(MOTOROLA)
-#undef _POSIX_SOURCE
-#include <sys/types.h>
-#define _POSIX_SOURCE
-#else
-#include <sys/types.h>
-#endif
-#endif /* USG */
-
-#if 0
-#include <X11/X.h>
-
-/* applications should not depend on these two headers being included! */
-#include <X11/Xfuncproto.h>
-#include <X11/Xosdefs.h>
-
-#endif /* if 0 */
-
-#ifndef X_WCHAR
-#ifdef X_NOT_STDC_ENV
-#ifndef SCO324
-#ifndef ISC
-#define X_WCHAR
-#endif
-#endif
-#endif
-#endif
-
-#ifndef X_WCHAR
-#include <stddef.h>
-#else
-#ifdef __UNIXOS2__
-#include <stdlib.h>
-#else
-/* replace this with #include or typedef appropriate for your system */
-typedef unsigned long wchar_t;
-#endif
-#endif
-
-#if defined(ISC) && defined(USE_XMBTOWC)
-#define wctomb(a,b) _Xwctomb(a,b)
-#define mblen(a,b) _Xmblen(a,b)
-#ifndef USE_XWCHAR_STRING
-#define mbtowc(a,b,c) _Xmbtowc(a,b,c)
-#endif
-#endif
-
-/* API mentioning "UTF8" or "utf8" is an XFree86 extension, introduced in
- November 2000. Its presence is indicated through the following macro. */
-#define X_HAVE_UTF8_STRING 1
-
-typedef char *XPointer;
-
-#define Bool int
-#define Status int
-#define True 1
-#define False 0
-
-#define QueuedAlready 0
-#define QueuedAfterReading 1
-#define QueuedAfterFlush 2
-
-#define ConnectionNumber(dpy) (((_XPrivDisplay)dpy)->fd)
-#define RootWindow(dpy, scr) (ScreenOfDisplay(dpy,scr)->root)
-#define DefaultScreen(dpy) (((_XPrivDisplay)dpy)->default_screen)
-#define DefaultRootWindow(dpy) (ScreenOfDisplay(dpy,DefaultScreen(dpy))->root)
-#define DefaultVisual(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_visual)
-#define DefaultGC(dpy, scr) (ScreenOfDisplay(dpy,scr)->default_gc)
-#define BlackPixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->black_pixel)
-#define WhitePixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->white_pixel)
-#define AllPlanes ((unsigned long)~0L)
-#define QLength(dpy) (((_XPrivDisplay)dpy)->qlen)
-#define DisplayWidth(dpy, scr) (ScreenOfDisplay(dpy,scr)->width)
-#define DisplayHeight(dpy, scr) (ScreenOfDisplay(dpy,scr)->height)
-#define DisplayWidthMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mwidth)
-#define DisplayHeightMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mheight)
-#define DisplayPlanes(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth)
-#define DisplayCells(dpy, scr) (DefaultVisual(dpy,scr)->map_entries)
-#define ScreenCount(dpy) (((_XPrivDisplay)dpy)->nscreens)
-#define ServerVendor(dpy) (((_XPrivDisplay)dpy)->vendor)
-#define ProtocolVersion(dpy) (((_XPrivDisplay)dpy)->proto_major_version)
-#define ProtocolRevision(dpy) (((_XPrivDisplay)dpy)->proto_minor_version)
-#define VendorRelease(dpy) (((_XPrivDisplay)dpy)->release)
-#define DisplayString(dpy) (((_XPrivDisplay)dpy)->display_name)
-#define DefaultDepth(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth)
-#define DefaultColormap(dpy, scr)(ScreenOfDisplay(dpy,scr)->cmap)
-#define BitmapUnit(dpy) (((_XPrivDisplay)dpy)->bitmap_unit)
-#define BitmapBitOrder(dpy) (((_XPrivDisplay)dpy)->bitmap_bit_order)
-#define BitmapPad(dpy) (((_XPrivDisplay)dpy)->bitmap_pad)
-#define ImageByteOrder(dpy) (((_XPrivDisplay)dpy)->byte_order)
-#ifdef CRAY /* unable to get WORD64 without pulling in other symbols */
-#define NextRequest(dpy) XNextRequest(dpy)
-#else
-#define NextRequest(dpy) (((_XPrivDisplay)dpy)->request + 1)
-#endif
-#define LastKnownRequestProcessed(dpy) (((_XPrivDisplay)dpy)->last_request_read)
-
-/* macros for screen oriented applications (toolkit) */
-#define ScreenOfDisplay(dpy, scr)(&((_XPrivDisplay)dpy)->screens[scr])
-#define DefaultScreenOfDisplay(dpy) ScreenOfDisplay(dpy,DefaultScreen(dpy))
-#define DisplayOfScreen(s) ((s)->display)
-#define RootWindowOfScreen(s) ((s)->root)
-#define BlackPixelOfScreen(s) ((s)->black_pixel)
-#define WhitePixelOfScreen(s) ((s)->white_pixel)
-#define DefaultColormapOfScreen(s)((s)->cmap)
-#define DefaultDepthOfScreen(s) ((s)->root_depth)
-#define DefaultGCOfScreen(s) ((s)->default_gc)
-#define DefaultVisualOfScreen(s)((s)->root_visual)
-#define WidthOfScreen(s) ((s)->width)
-#define HeightOfScreen(s) ((s)->height)
-#define WidthMMOfScreen(s) ((s)->mwidth)
-#define HeightMMOfScreen(s) ((s)->mheight)
-#define PlanesOfScreen(s) ((s)->root_depth)
-#define CellsOfScreen(s) (DefaultVisualOfScreen((s))->map_entries)
-#define MinCmapsOfScreen(s) ((s)->min_maps)
-#define MaxCmapsOfScreen(s) ((s)->max_maps)
-#define DoesSaveUnders(s) ((s)->save_unders)
-#define DoesBackingStore(s) ((s)->backing_store)
-#define EventMaskOfScreen(s) ((s)->root_input_mask)
-
-/*
- * Extensions need a way to hang private data on some structures.
- */
-typedef struct _XExtData {
- int number; /* number returned by XRegisterExtension */
- struct _XExtData *next; /* next item on list of data for structure */
- int (*free_private)( /* called to free private storage */
-#if NeedFunctionPrototypes
- struct _XExtData *extension
-#endif
- );
- XPointer private_data; /* data private to this extension. */
-} XExtData;
-
-/*
- * This file contains structures used by the extension mechanism.
- */
-typedef struct { /* public to extension, cannot be changed */
- int extension; /* extension number */
- int major_opcode; /* major op-code assigned by server */
- int first_event; /* first event number for the extension */
- int first_error; /* first error number for the extension */
-} XExtCodes;
-
-/*
- * Data structure for retrieving info about pixmap formats.
- */
-
-typedef struct {
- int depth;
- int bits_per_pixel;
- int scanline_pad;
-} XPixmapFormatValues;
-
-
-/*
- * Data structure for setting graphics context.
- */
-typedef struct {
- int function; /* logical operation */
- unsigned long plane_mask;/* plane mask */
- unsigned long foreground;/* foreground pixel */
- unsigned long background;/* background pixel */
- int line_width; /* line width */
- int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */
- int cap_style; /* CapNotLast, CapButt,
- CapRound, CapProjecting */
- int join_style; /* JoinMiter, JoinRound, JoinBevel */
- int fill_style; /* FillSolid, FillTiled,
- FillStippled, FillOpaeueStippled */
- int fill_rule; /* EvenOddRule, WindingRule */
- int arc_mode; /* ArcChord, ArcPieSlice */
- Pixmap tile; /* tile pixmap for tiling operations */
- Pixmap stipple; /* stipple 1 plane pixmap for stipping */
- int ts_x_origin; /* offset for tile or stipple operations */
- int ts_y_origin;
- Font font; /* default text font for text operations */
- int subwindow_mode; /* ClipByChildren, IncludeInferiors */
- Bool graphics_exposures;/* boolean, should exposures be generated */
- int clip_x_origin; /* origin for clipping */
- int clip_y_origin;
- Pixmap clip_mask; /* bitmap clipping; other calls for rects */
- int dash_offset; /* patterned/dashed line information */
- char dashes;
-} XGCValues;
-
-/*
- * Graphics context. The contents of this structure are implementation
- * dependent. A GC should be treated as opaque by application code.
- */
-
-typedef struct _XGC
-#ifdef XLIB_ILLEGAL_ACCESS
-{
- XExtData *ext_data; /* hook for extension to hang data */
- GContext gid; /* protocol ID for graphics context */
- /* there is more to this structure, but it is private to Xlib */
-}
-#endif
-*GC;
-
-/*
- * Visual structure; contains information about colormapping possible.
- */
-typedef struct {
- XExtData *ext_data; /* hook for extension to hang data */
- VisualID visualid; /* visual id of this visual */
-#if defined(__cplusplus) || defined(c_plusplus)
- int c_class; /* C++ class of screen (monochrome, etc.) */
-#else
- int class; /* class of screen (monochrome, etc.) */
-#endif
- unsigned long red_mask, green_mask, blue_mask; /* mask values */
- int bits_per_rgb; /* log base 2 of distinct color values */
- int map_entries; /* color map entries */
-} Visual;
-
-/*
- * Depth structure; contains information for each possible depth.
- */
-typedef struct {
- int depth; /* this depth (Z) of the depth */
- int nvisuals; /* number of Visual types at this depth */
- Visual *visuals; /* list of visuals possible at this depth */
-} Depth;
-
-/*
- * Information about the screen. The contents of this structure are
- * implementation dependent. A Screen should be treated as opaque
- * by application code.
- */
-
-struct _XDisplay; /* Forward declare before use for C++ */
-
-typedef struct {
- XExtData *ext_data; /* hook for extension to hang data */
- struct _XDisplay *display;/* back pointer to display structure */
- Window root; /* Root window id. */
- int width, height; /* width and height of screen */
- int mwidth, mheight; /* width and height of in millimeters */
- int ndepths; /* number of depths possible */
- Depth *depths; /* list of allowable depths on the screen */
- int root_depth; /* bits per pixel */
- Visual *root_visual; /* root visual */
- GC default_gc; /* GC for the root root visual */
- Colormap cmap; /* default color map */
- unsigned long white_pixel;
- unsigned long black_pixel; /* White and Black pixel values */
- int max_maps, min_maps; /* max and min color maps */
- int backing_store; /* Never, WhenMapped, Always */
- Bool save_unders;
- long root_input_mask; /* initial root input mask */
-} Screen;
-
-/*
- * Format structure; describes ZFormat data the screen will understand.
- */
-typedef struct {
- XExtData *ext_data; /* hook for extension to hang data */
- int depth; /* depth of this image format */
- int bits_per_pixel; /* bits/pixel at this depth */
- int scanline_pad; /* scanline must padded to this multiple */
-} ScreenFormat;
-
-/*
- * Data structure for setting window attributes.
- */
-typedef struct {
- Pixmap background_pixmap; /* background or None or ParentRelative */
- unsigned long background_pixel; /* background pixel */
- Pixmap border_pixmap; /* border of the window */
- unsigned long border_pixel; /* border pixel value */
- int bit_gravity; /* one of bit gravity values */
- int win_gravity; /* one of the window gravity values */
- int backing_store; /* NotUseful, WhenMapped, Always */
- unsigned long backing_planes;/* planes to be preseved if possible */
- unsigned long backing_pixel;/* value to use in restoring planes */
- Bool save_under; /* should bits under be saved? (popups) */
- long event_mask; /* set of events that should be saved */
- long do_not_propagate_mask; /* set of events that should not propagate */
- Bool override_redirect; /* boolean value for override-redirect */
- Colormap colormap; /* color map to be associated with window */
- Cursor cursor; /* cursor to be displayed (or None) */
-} XSetWindowAttributes;
-
-typedef struct {
- int x, y; /* location of window */
- int width, height; /* width and height of window */
- int border_width; /* border width of window */
- int depth; /* depth of window */
- Visual *visual; /* the associated visual structure */
- Window root; /* root of screen containing window */
-#if defined(__cplusplus) || defined(c_plusplus)
- int c_class; /* C++ InputOutput, InputOnly*/
-#else
- int class; /* InputOutput, InputOnly*/
-#endif
- int bit_gravity; /* one of bit gravity values */
- int win_gravity; /* one of the window gravity values */
- int backing_store; /* NotUseful, WhenMapped, Always */
- unsigned long backing_planes;/* planes to be preserved if possible */
- unsigned long backing_pixel;/* value to be used when restoring planes */
- Bool save_under; /* boolean, should bits under be saved? */
- Colormap colormap; /* color map to be associated with window */
- Bool map_installed; /* boolean, is color map currently installed*/
- int map_state; /* IsUnmapped, IsUnviewable, IsViewable */
- long all_event_masks; /* set of events all people have interest in*/
- long your_event_mask; /* my event mask */
- long do_not_propagate_mask; /* set of events that should not propagate */
- Bool override_redirect; /* boolean value for override-redirect */
- Screen *screen; /* back pointer to correct screen */
-} XWindowAttributes;
-
-/*
- * Data structure for host setting; getting routines.
- *
- */
-
-typedef struct {
- int family; /* for example FamilyInternet */
- int length; /* length of address, in bytes */
- char *address; /* pointer to where to find the bytes */
-} XHostAddress;
-
-/*
- * Data structure for "image" data, used by image manipulation routines.
- */
-typedef struct _XImage {
- int width, height; /* size of image */
- int xoffset; /* number of pixels offset in X direction */
- int format; /* XYBitmap, XYPixmap, ZPixmap */
- char *data; /* pointer to image data */
- int byte_order; /* data byte order, LSBFirst, MSBFirst */
- int bitmap_unit; /* quant. of scanline 8, 16, 32 */
- int bitmap_bit_order; /* LSBFirst, MSBFirst */
- int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */
- int depth; /* depth of image */
- int bytes_per_line; /* accelarator to next line */
- int bits_per_pixel; /* bits per pixel (ZPixmap) */
- unsigned long red_mask; /* bits in z arrangment */
- unsigned long green_mask;
- unsigned long blue_mask;
- XPointer obdata; /* hook for the object routines to hang on */
- struct funcs { /* image manipulation routines */
-#if NeedFunctionPrototypes
- struct _XImage *(*create_image)(
- struct _XDisplay* /* display */,
- Visual* /* visual */,
- unsigned int /* depth */,
- int /* format */,
- int /* offset */,
- char* /* data */,
- unsigned int /* width */,
- unsigned int /* height */,
- int /* bitmap_pad */,
- int /* bytes_per_line */);
- int (*destroy_image) (struct _XImage *);
- unsigned long (*get_pixel) (struct _XImage *, int, int);
- int (*put_pixel) (struct _XImage *, int, int, unsigned long);
- struct _XImage *(*sub_image)(struct _XImage *, int, int, unsigned int, unsigned int);
- int (*add_pixel) (struct _XImage *, long);
-#else
- struct _XImage *(*create_image)();
- int (*destroy_image)();
- unsigned long (*get_pixel)();
- int (*put_pixel)();
- struct _XImage *(*sub_image)();
- int (*add_pixel)();
-#endif
- } f;
-} XImage;
-
-/*
- * Data structure for XReconfigureWindow
- */
-typedef struct {
- int x, y;
- int width, height;
- int border_width;
- Window sibling;
- int stack_mode;
-} XWindowChanges;
-
-/*
- * Data structure used by color operations
- */
-typedef struct {
- unsigned long pixel;
- unsigned short red, green, blue;
- char flags; /* do_red, do_green, do_blue */
- char pad;
-} XColor;
-
-/*
- * Data structures for graphics operations. On most machines, these are
- * congruent with the wire protocol structures, so reformatting the data
- * can be avoided on these architectures.
- */
-typedef struct {
- short x1, y1, x2, y2;
-} XSegment;
-
-typedef struct {
- short x, y;
-} XPoint;
-
-typedef struct {
- short x, y;
- unsigned short width, height;
-} XRectangle;
-
-typedef struct {
- short x, y;
- unsigned short width, height;
- short angle1, angle2;
-} XArc;
-
-
-/* Data structure for XChangeKeyboardControl */
-
-typedef struct {
- int key_click_percent;
- int bell_percent;
- int bell_pitch;
- int bell_duration;
- int led;
- int led_mode;
- int key;
- int auto_repeat_mode; /* On, Off, Default */
-} XKeyboardControl;
-
-/* Data structure for XGetKeyboardControl */
-
-typedef struct {
- int key_click_percent;
- int bell_percent;
- unsigned int bell_pitch, bell_duration;
- unsigned long led_mask;
- int global_auto_repeat;
- char auto_repeats[32];
-} XKeyboardState;
-
-/* Data structure for XGetMotionEvents. */
-
-typedef struct {
- Time time;
- short x, y;
-} XTimeCoord;
-
-/* Data structure for X{Set,Get}ModifierMapping */
-
-typedef struct {
- int max_keypermod; /* The server's max # of keys per modifier */
- KeyCode *modifiermap; /* An 8 by max_keypermod array of modifiers */
-} XModifierKeymap;
-
-
-/*
- * Display datatype maintaining display specific data.
- * The contents of this structure are implementation dependent.
- * A Display should be treated as opaque by application code.
- */
-#ifndef XLIB_ILLEGAL_ACCESS
-typedef struct _XDisplay Display;
-#endif
-
-struct _XPrivate; /* Forward declare before use for C++ */
-struct _XrmHashBucketRec;
-
-typedef struct
-#ifdef XLIB_ILLEGAL_ACCESS
-_XDisplay
-#endif
-{
- XExtData *ext_data; /* hook for extension to hang data */
- struct _XPrivate *private1;
- int fd; /* Network socket. */
- int private2;
- int proto_major_version;/* major version of server's X protocol */
- int proto_minor_version;/* minor version of servers X protocol */
- char *vendor; /* vendor of the server hardware */
- XID private3;
- XID private4;
- XID private5;
- int private6;
- XID (*resource_alloc)( /* allocator function */
-#if NeedFunctionPrototypes
- struct _XDisplay*
-#endif
- );
- int byte_order; /* screen byte order, LSBFirst, MSBFirst */
- int bitmap_unit; /* padding and data requirements */
- int bitmap_pad; /* padding requirements on bitmaps */
- int bitmap_bit_order; /* LeastSignificant or MostSignificant */
- int nformats; /* number of pixmap formats in list */
- ScreenFormat *pixmap_format; /* pixmap format list */
- int private8;
- int release; /* release of the server */
- struct _XPrivate *private9, *private10;
- int qlen; /* Length of input event queue */
- unsigned long last_request_read; /* seq number of last event read */
- unsigned long request; /* sequence number of last request. */
- XPointer private11;
- XPointer private12;
- XPointer private13;
- XPointer private14;
- unsigned max_request_size; /* maximum number 32 bit words in request*/
- struct _XrmHashBucketRec *db;
- int (*private15)(
-#if NeedFunctionPrototypes
- struct _XDisplay*
-#endif
- );
- char *display_name; /* "host:display" string used on this connect*/
- int default_screen; /* default screen for operations */
- int nscreens; /* number of screens on this server*/
- Screen *screens; /* pointer to list of screens */
- unsigned long motion_buffer; /* size of motion buffer */
- unsigned long private16;
- int min_keycode; /* minimum defined keycode */
- int max_keycode; /* maximum defined keycode */
- XPointer private17;
- XPointer private18;
- int private19;
- char *xdefaults; /* contents of defaults from server */
- /* there is more to this structure, but it is private to Xlib */
-}
-#ifdef XLIB_ILLEGAL_ACCESS
-Display,
-#endif
-*_XPrivDisplay;
-
-#if NeedFunctionPrototypes /* prototypes require event type definitions */
-#undef _XEVENT_
-#endif
-#ifndef _XEVENT_
-/*
- * Definitions of specific events.
- */
-typedef struct {
- int type; /* of event */
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window; /* "event" window it is reported relative to */
- Window root; /* root window that the event occurred on */
- Window subwindow; /* child window */
- Time time; /* milliseconds */
- int x, y; /* pointer x, y coordinates in event window */
- int x_root, y_root; /* coordinates relative to root */
- unsigned int state; /* key or button mask */
- unsigned int keycode; /* detail */
- Bool same_screen; /* same screen flag */
-} XKeyEvent;
-typedef XKeyEvent XKeyPressedEvent;
-typedef XKeyEvent XKeyReleasedEvent;
-
-typedef struct {
- int type; /* of event */
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window; /* "event" window it is reported relative to */
- Window root; /* root window that the event occurred on */
- Window subwindow; /* child window */
- Time time; /* milliseconds */
- int x, y; /* pointer x, y coordinates in event window */
- int x_root, y_root; /* coordinates relative to root */
- unsigned int state; /* key or button mask */
- unsigned int button; /* detail */
- Bool same_screen; /* same screen flag */
-} XButtonEvent;
-typedef XButtonEvent XButtonPressedEvent;
-typedef XButtonEvent XButtonReleasedEvent;
-
-typedef struct {
- int type; /* of event */
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window; /* "event" window reported relative to */
- Window root; /* root window that the event occurred on */
- Window subwindow; /* child window */
- Time time; /* milliseconds */
- int x, y; /* pointer x, y coordinates in event window */
- int x_root, y_root; /* coordinates relative to root */
- unsigned int state; /* key or button mask */
- char is_hint; /* detail */
- Bool same_screen; /* same screen flag */
-} XMotionEvent;
-typedef XMotionEvent XPointerMovedEvent;
-
-typedef struct {
- int type; /* of event */
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window; /* "event" window reported relative to */
- Window root; /* root window that the event occurred on */
- Window subwindow; /* child window */
- Time time; /* milliseconds */
- int x, y; /* pointer x, y coordinates in event window */
- int x_root, y_root; /* coordinates relative to root */
- int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */
- int detail;
- /*
- * NotifyAncestor, NotifyVirtual, NotifyInferior,
- * NotifyNonlinear,NotifyNonlinearVirtual
- */
- Bool same_screen; /* same screen flag */
- Bool focus; /* boolean focus */
- unsigned int state; /* key or button mask */
-} XCrossingEvent;
-typedef XCrossingEvent XEnterWindowEvent;
-typedef XCrossingEvent XLeaveWindowEvent;
-
-typedef struct {
- int type; /* FocusIn or FocusOut */
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window; /* window of event */
- int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */
- int detail;
- /*
- * NotifyAncestor, NotifyVirtual, NotifyInferior,
- * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer,
- * NotifyPointerRoot, NotifyDetailNone
- */
-} XFocusChangeEvent;
-typedef XFocusChangeEvent XFocusInEvent;
-typedef XFocusChangeEvent XFocusOutEvent;
-
-/* generated on EnterWindow and FocusIn when KeyMapState selected */
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window;
- char key_vector[32];
-} XKeymapEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window;
- int x, y;
- int width, height;
- int count; /* if non-zero, at least this many more */
-} XExposeEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Drawable drawable;
- int x, y;
- int width, height;
- int count; /* if non-zero, at least this many more */
- int major_code; /* core is CopyArea or CopyPlane */
- int minor_code; /* not defined in the core */
-} XGraphicsExposeEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Drawable drawable;
- int major_code; /* core is CopyArea or CopyPlane */
- int minor_code; /* not defined in the core */
-} XNoExposeEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window;
- int state; /* Visibility state */
-} XVisibilityEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window parent; /* parent of the window */
- Window window; /* window id of window created */
- int x, y; /* window location */
- int width, height; /* size of window */
- int border_width; /* border width */
- Bool override_redirect; /* creation should be overridden */
-} XCreateWindowEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window event;
- Window window;
-} XDestroyWindowEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window event;
- Window window;
- Bool from_configure;
-} XUnmapEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window event;
- Window window;
- Bool override_redirect; /* boolean, is override set... */
-} XMapEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window parent;
- Window window;
-} XMapRequestEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window event;
- Window window;
- Window parent;
- int x, y;
- Bool override_redirect;
-} XReparentEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window event;
- Window window;
- int x, y;
- int width, height;
- int border_width;
- Window above;
- Bool override_redirect;
-} XConfigureEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window event;
- Window window;
- int x, y;
-} XGravityEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window;
- int width, height;
-} XResizeRequestEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window parent;
- Window window;
- int x, y;
- int width, height;
- int border_width;
- Window above;
- int detail; /* Above, Below, TopIf, BottomIf, Opposite */
- unsigned long value_mask;
-} XConfigureRequestEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window event;
- Window window;
- int place; /* PlaceOnTop, PlaceOnBottom */
-} XCirculateEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window parent;
- Window window;
- int place; /* PlaceOnTop, PlaceOnBottom */
-} XCirculateRequestEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window;
- Atom atom;
- Time time;
- int state; /* NewValue, Deleted */
-} XPropertyEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window;
- Atom selection;
- Time time;
-} XSelectionClearEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window owner;
- Window requestor;
- Atom selection;
- Atom target;
- Atom property;
- Time time;
-} XSelectionRequestEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window requestor;
- Atom selection;
- Atom target;
- Atom property; /* ATOM or None */
- Time time;
-} XSelectionEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window;
- Colormap colormap; /* COLORMAP or None */
-#if defined(__cplusplus) || defined(c_plusplus)
- Bool c_new; /* C++ */
-#else
- Bool new;
-#endif
- int state; /* ColormapInstalled, ColormapUninstalled */
-} XColormapEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window;
- Atom message_type;
- int format;
- union {
- char b[20];
- short s[10];
- long l[5];
- } data;
-} XClientMessageEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window; /* unused */
- int request; /* one of MappingModifier, MappingKeyboard,
- MappingPointer */
- int first_keycode; /* first keycode */
- int count; /* defines range of change w. first_keycode*/
-} XMappingEvent;
-
-typedef struct {
- int type;
- Display *display; /* Display the event was read from */
- XID resourceid; /* resource id */
- unsigned long serial; /* serial number of failed request */
- unsigned char error_code; /* error code of failed request */
- unsigned char request_code; /* Major op-code of failed request */
- unsigned char minor_code; /* Minor op-code of failed request */
-} XErrorEvent;
-
-typedef struct {
- int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* true if this came from a SendEvent request */
- Display *display;/* Display the event was read from */
- Window window; /* window on which event was requested in event mask */
-} XAnyEvent;
-
-/*
- * this union is defined so Xlib can always use the same sized
- * event structure internally, to avoid memory fragmentation.
- */
-typedef union _XEvent {
- int type; /* must not be changed; first element */
- XAnyEvent xany;
- XKeyEvent xkey;
- XButtonEvent xbutton;
- XMotionEvent xmotion;
- XCrossingEvent xcrossing;
- XFocusChangeEvent xfocus;
- XExposeEvent xexpose;
- XGraphicsExposeEvent xgraphicsexpose;
- XNoExposeEvent xnoexpose;
- XVisibilityEvent xvisibility;
- XCreateWindowEvent xcreatewindow;
- XDestroyWindowEvent xdestroywindow;
- XUnmapEvent xunmap;
- XMapEvent xmap;
- XMapRequestEvent xmaprequest;
- XReparentEvent xreparent;
- XConfigureEvent xconfigure;
- XGravityEvent xgravity;
- XResizeRequestEvent xresizerequest;
- XConfigureRequestEvent xconfigurerequest;
- XCirculateEvent xcirculate;
- XCirculateRequestEvent xcirculaterequest;
- XPropertyEvent xproperty;
- XSelectionClearEvent xselectionclear;
- XSelectionRequestEvent xselectionrequest;
- XSelectionEvent xselection;
- XColormapEvent xcolormap;
- XClientMessageEvent xclient;
- XMappingEvent xmapping;
- XErrorEvent xerror;
- XKeymapEvent xkeymap;
- long pad[24];
-} XEvent;
-#endif
-
-#define XAllocID(dpy) ((*((_XPrivDisplay)dpy)->resource_alloc)((dpy)))
-
-/*
- * per character font metric information.
- */
-typedef struct {
- short lbearing; /* origin to left edge of raster */
- short rbearing; /* origin to right edge of raster */
- short width; /* advance to next char's origin */
- short ascent; /* baseline to top edge of raster */
- short descent; /* baseline to bottom edge of raster */
- unsigned short attributes; /* per char flags (not predefined) */
-} XCharStruct;
-
-/*
- * To allow arbitrary information with fonts, there are additional properties
- * returned.
- */
-typedef struct {
- Atom name;
- unsigned long card32;
-} XFontProp;
-
-typedef struct {
- XExtData *ext_data; /* hook for extension to hang data */
- Font fid; /* Font id for this font */
- unsigned direction; /* hint about direction the font is painted */
- unsigned min_char_or_byte2;/* first character */
- unsigned max_char_or_byte2;/* last character */
- unsigned min_byte1; /* first row that exists */
- unsigned max_byte1; /* last row that exists */
- Bool all_chars_exist;/* flag if all characters have non-zero size*/
- unsigned default_char; /* char to print for undefined character */
- int n_properties; /* how many properties there are */
- XFontProp *properties; /* pointer to array of additional properties*/
- XCharStruct min_bounds; /* minimum bounds over all existing char*/
- XCharStruct max_bounds; /* maximum bounds over all existing char*/
- XCharStruct *per_char; /* first_char to last_char information */
- int ascent; /* log. extent above baseline for spacing */
- int descent; /* log. descent below baseline for spacing */
-} XFontStruct;
-
-/*
- * PolyText routines take these as arguments.
- */
-typedef struct {
- char *chars; /* pointer to string */
- int nchars; /* number of characters */
- int delta; /* delta between strings */
- Font font; /* font to print it in, None don't change */
-} XTextItem;
-
-typedef struct { /* normal 16 bit characters are two bytes */
- unsigned char byte1;
- unsigned char byte2;
-} XChar2b;
-
-typedef struct {
- XChar2b *chars; /* two byte characters */
- int nchars; /* number of characters */
- int delta; /* delta between strings */
- Font font; /* font to print it in, None don't change */
-} XTextItem16;
-
-
-typedef union { Display *display;
- GC gc;
- Visual *visual;
- Screen *screen;
- ScreenFormat *pixmap_format;
- XFontStruct *font; } XEDataObject;
-
-typedef struct {
- XRectangle max_ink_extent;
- XRectangle max_logical_extent;
-} XFontSetExtents;
-
-/* unused:
-typedef void (*XOMProc)();
- */
-
-typedef struct _XOM *XOM;
-typedef struct _XOC *XOC, *XFontSet;
-
-typedef struct {
- char *chars;
- int nchars;
- int delta;
- XFontSet font_set;
-} XmbTextItem;
-
-typedef struct {
- wchar_t *chars;
- int nchars;
- int delta;
- XFontSet font_set;
-} XwcTextItem;
-
-#define XNRequiredCharSet "requiredCharSet"
-#define XNQueryOrientation "queryOrientation"
-#define XNBaseFontName "baseFontName"
-#define XNOMAutomatic "omAutomatic"
-#define XNMissingCharSet "missingCharSet"
-#define XNDefaultString "defaultString"
-#define XNOrientation "orientation"
-#define XNDirectionalDependentDrawing "directionalDependentDrawing"
-#define XNContextualDrawing "contextualDrawing"
-#define XNFontInfo "fontInfo"
-
-typedef struct {
- int charset_count;
- char **charset_list;
-} XOMCharSetList;
-
-typedef enum {
- XOMOrientation_LTR_TTB,
- XOMOrientation_RTL_TTB,
- XOMOrientation_TTB_LTR,
- XOMOrientation_TTB_RTL,
- XOMOrientation_Context
-} XOrientation;
-
-typedef struct {
- int num_orientation;
- XOrientation *orientation; /* Input Text description */
-} XOMOrientation;
-
-typedef struct {
- int num_font;
- XFontStruct **font_struct_list;
- char **font_name_list;
-} XOMFontInfo;
-
-typedef struct _XIM *XIM;
-typedef struct _XIC *XIC;
-
-typedef void (*XIMProc)(
-#if NeedFunctionPrototypes
- XIM,
- XPointer,
- XPointer
-#endif
-);
-
-typedef Bool (*XICProc)(
-#if NeedFunctionPrototypes
- XIC,
- XPointer,
- XPointer
-#endif
-);
-
-typedef void (*XIDProc)(
-#if NeedFunctionPrototypes
- Display*,
- XPointer,
- XPointer
-#endif
-);
-
-typedef unsigned long XIMStyle;
-
-typedef struct {
- unsigned short count_styles;
- XIMStyle *supported_styles;
-} XIMStyles;
-
-#define XIMPreeditArea 0x0001L
-#define XIMPreeditCallbacks 0x0002L
-#define XIMPreeditPosition 0x0004L
-#define XIMPreeditNothing 0x0008L
-#define XIMPreeditNone 0x0010L
-#define XIMStatusArea 0x0100L
-#define XIMStatusCallbacks 0x0200L
-#define XIMStatusNothing 0x0400L
-#define XIMStatusNone 0x0800L
-
-#define XNVaNestedList "XNVaNestedList"
-#define XNQueryInputStyle "queryInputStyle"
-#define XNClientWindow "clientWindow"
-#define XNInputStyle "inputStyle"
-#define XNFocusWindow "focusWindow"
-#define XNResourceName "resourceName"
-#define XNResourceClass "resourceClass"
-#define XNGeometryCallback "geometryCallback"
-#define XNDestroyCallback "destroyCallback"
-#define XNFilterEvents "filterEvents"
-#define XNPreeditStartCallback "preeditStartCallback"
-#define XNPreeditDoneCallback "preeditDoneCallback"
-#define XNPreeditDrawCallback "preeditDrawCallback"
-#define XNPreeditCaretCallback "preeditCaretCallback"
-#define XNPreeditStateNotifyCallback "preeditStateNotifyCallback"
-#define XNPreeditAttributes "preeditAttributes"
-#define XNStatusStartCallback "statusStartCallback"
-#define XNStatusDoneCallback "statusDoneCallback"
-#define XNStatusDrawCallback "statusDrawCallback"
-#define XNStatusAttributes "statusAttributes"
-#define XNArea "area"
-#define XNAreaNeeded "areaNeeded"
-#define XNSpotLocation "spotLocation"
-#define XNColormap "colorMap"
-#define XNStdColormap "stdColorMap"
-#define XNForeground "foreground"
-#define XNBackground "background"
-#define XNBackgroundPixmap "backgroundPixmap"
-#define XNFontSet "fontSet"
-#define XNLineSpace "lineSpace"
-#define XNCursor "cursor"
-
-#define XNQueryIMValuesList "queryIMValuesList"
-#define XNQueryICValuesList "queryICValuesList"
-#define XNVisiblePosition "visiblePosition"
-#define XNR6PreeditCallback "r6PreeditCallback"
-#define XNStringConversionCallback "stringConversionCallback"
-#define XNStringConversion "stringConversion"
-#define XNResetState "resetState"
-#define XNHotKey "hotKey"
-#define XNHotKeyState "hotKeyState"
-#define XNPreeditState "preeditState"
-#define XNSeparatorofNestedList "separatorofNestedList"
-
-#define XBufferOverflow -1
-#define XLookupNone 1
-#define XLookupChars 2
-#define XLookupKeySym 3
-#define XLookupBoth 4
-
-#if NeedFunctionPrototypes
-typedef void *XVaNestedList;
-#else
-typedef XPointer XVaNestedList;
-#endif
-
-typedef struct {
- XPointer client_data;
- XIMProc callback;
-} XIMCallback;
-
-typedef struct {
- XPointer client_data;
- XICProc callback;
-} XICCallback;
-
-typedef unsigned long XIMFeedback;
-
-#define XIMReverse 1L
-#define XIMUnderline (1L<<1)
-#define XIMHighlight (1L<<2)
-#define XIMPrimary (1L<<5)
-#define XIMSecondary (1L<<6)
-#define XIMTertiary (1L<<7)
-#define XIMVisibleToForward (1L<<8)
-#define XIMVisibleToBackword (1L<<9)
-#define XIMVisibleToCenter (1L<<10)
-
-typedef struct _XIMText {
- unsigned short length;
- XIMFeedback *feedback;
- Bool encoding_is_wchar;
- union {
- char *multi_byte;
- wchar_t *wide_char;
- } string;
-} XIMText;
-
-typedef unsigned long XIMPreeditState;
-
-#define XIMPreeditUnKnown 0L
-#define XIMPreeditEnable 1L
-#define XIMPreeditDisable (1L<<1)
-
-typedef struct _XIMPreeditStateNotifyCallbackStruct {
- XIMPreeditState state;
-} XIMPreeditStateNotifyCallbackStruct;
-
-typedef unsigned long XIMResetState;
-
-#define XIMInitialState 1L
-#define XIMPreserveState (1L<<1)
-
-typedef unsigned long XIMStringConversionFeedback;
-
-#define XIMStringConversionLeftEdge (0x00000001)
-#define XIMStringConversionRightEdge (0x00000002)
-#define XIMStringConversionTopEdge (0x00000004)
-#define XIMStringConversionBottomEdge (0x00000008)
-#define XIMStringConversionConcealed (0x00000010)
-#define XIMStringConversionWrapped (0x00000020)
-
-typedef struct _XIMStringConversionText {
- unsigned short length;
- XIMStringConversionFeedback *feedback;
- Bool encoding_is_wchar;
- union {
- char *mbs;
- wchar_t *wcs;
- } string;
-} XIMStringConversionText;
-
-typedef unsigned short XIMStringConversionPosition;
-
-typedef unsigned short XIMStringConversionType;
-
-#define XIMStringConversionBuffer (0x0001)
-#define XIMStringConversionLine (0x0002)
-#define XIMStringConversionWord (0x0003)
-#define XIMStringConversionChar (0x0004)
-
-typedef unsigned short XIMStringConversionOperation;
-
-#define XIMStringConversionSubstitution (0x0001)
-#define XIMStringConversionRetrieval (0x0002)
-
-typedef enum {
- XIMForwardChar, XIMBackwardChar,
- XIMForwardWord, XIMBackwardWord,
- XIMCaretUp, XIMCaretDown,
- XIMNextLine, XIMPreviousLine,
- XIMLineStart, XIMLineEnd,
- XIMAbsolutePosition,
- XIMDontChange
-} XIMCaretDirection;
-
-typedef struct _XIMStringConversionCallbackStruct {
- XIMStringConversionPosition position;
- XIMCaretDirection direction;
- XIMStringConversionOperation operation;
- unsigned short factor;
- XIMStringConversionText *text;
-} XIMStringConversionCallbackStruct;
-
-typedef struct _XIMPreeditDrawCallbackStruct {
- int caret; /* Cursor offset within pre-edit string */
- int chg_first; /* Starting change position */
- int chg_length; /* Length of the change in character count */
- XIMText *text;
-} XIMPreeditDrawCallbackStruct;
-
-typedef enum {
- XIMIsInvisible, /* Disable caret feedback */
- XIMIsPrimary, /* UI defined caret feedback */
- XIMIsSecondary /* UI defined caret feedback */
-} XIMCaretStyle;
-
-typedef struct _XIMPreeditCaretCallbackStruct {
- int position; /* Caret offset within pre-edit string */
- XIMCaretDirection direction; /* Caret moves direction */
- XIMCaretStyle style; /* Feedback of the caret */
-} XIMPreeditCaretCallbackStruct;
-
-typedef enum {
- XIMTextType,
- XIMBitmapType
-} XIMStatusDataType;
-
-typedef struct _XIMStatusDrawCallbackStruct {
- XIMStatusDataType type;
- union {
- XIMText *text;
- Pixmap bitmap;
- } data;
-} XIMStatusDrawCallbackStruct;
-
-typedef struct _XIMHotKeyTrigger {
- KeySym keysym;
- int modifier;
- int modifier_mask;
-} XIMHotKeyTrigger;
-
-typedef struct _XIMHotKeyTriggers {
- int num_hot_key;
- XIMHotKeyTrigger *key;
-} XIMHotKeyTriggers;
-
-typedef unsigned long XIMHotKeyState;
-
-#define XIMHotKeyStateON (0x0001L)
-#define XIMHotKeyStateOFF (0x0002L)
-
-typedef struct {
- unsigned short count_values;
- char **supported_values;
-} XIMValuesList;
-
-#if 0
-_XFUNCPROTOBEGIN
-
-#if defined(WIN32) && !defined(_XLIBINT_)
-#define _Xdebug (*_Xdebug_p)
-#endif
-
-extern int _Xdebug;
-
-extern XFontStruct *XLoadQueryFont(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* name */
-#endif
-);
-
-extern XFontStruct *XQueryFont(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XID /* font_ID */
-#endif
-);
-
-
-extern XTimeCoord *XGetMotionEvents(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Time /* start */,
- Time /* stop */,
- int* /* nevents_return */
-#endif
-);
-
-extern XModifierKeymap *XDeleteModifiermapEntry(
-#if NeedFunctionPrototypes
- XModifierKeymap* /* modmap */,
-#if NeedWidePrototypes
- unsigned int /* keycode_entry */,
-#else
- KeyCode /* keycode_entry */,
-#endif
- int /* modifier */
-#endif
-);
-
-extern XModifierKeymap *XGetModifierMapping(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern XModifierKeymap *XInsertModifiermapEntry(
-#if NeedFunctionPrototypes
- XModifierKeymap* /* modmap */,
-#if NeedWidePrototypes
- unsigned int /* keycode_entry */,
-#else
- KeyCode /* keycode_entry */,
-#endif
- int /* modifier */
-#endif
-);
-
-extern XModifierKeymap *XNewModifiermap(
-#if NeedFunctionPrototypes
- int /* max_keys_per_mod */
-#endif
-);
-
-extern XImage *XCreateImage(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Visual* /* visual */,
- unsigned int /* depth */,
- int /* format */,
- int /* offset */,
- char* /* data */,
- unsigned int /* width */,
- unsigned int /* height */,
- int /* bitmap_pad */,
- int /* bytes_per_line */
-#endif
-);
-extern Status XInitImage(
-#if NeedFunctionPrototypes
- XImage* /* image */
-#endif
-);
-extern XImage *XGetImage(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */,
- unsigned long /* plane_mask */,
- int /* format */
-#endif
-);
-extern XImage *XGetSubImage(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */,
- unsigned long /* plane_mask */,
- int /* format */,
- XImage* /* dest_image */,
- int /* dest_x */,
- int /* dest_y */
-#endif
-);
-
-/*
- * X function declarations.
- */
-extern Display *XOpenDisplay(
-#if NeedFunctionPrototypes
- _Xconst char* /* display_name */
-#endif
-);
-
-extern void XrmInitialize(
-#if NeedFunctionPrototypes
- void
-#endif
-);
-
-extern char *XFetchBytes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int* /* nbytes_return */
-#endif
-);
-extern char *XFetchBuffer(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int* /* nbytes_return */,
- int /* buffer */
-#endif
-);
-extern char *XGetAtomName(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Atom /* atom */
-#endif
-);
-extern Status XGetAtomNames(
-#if NeedFunctionPrototypes
- Display* /* dpy */,
- Atom* /* atoms */,
- int /* count */,
- char** /* names_return */
-#endif
-);
-extern char *XGetDefault(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* program */,
- _Xconst char* /* option */
-#endif
-);
-extern char *XDisplayName(
-#if NeedFunctionPrototypes
- _Xconst char* /* string */
-#endif
-);
-extern char *XKeysymToString(
-#if NeedFunctionPrototypes
- KeySym /* keysym */
-#endif
-);
-
-extern int (*XSynchronize(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Bool /* onoff */
-#endif
-))(
-#if NeedNestedPrototypes
- Display* /* display */
-#endif
-);
-extern int (*XSetAfterFunction(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int (*) (
-#if NeedNestedPrototypes
- Display* /* display */
-#endif
- ) /* procedure */
-#endif
-))(
-#if NeedNestedPrototypes
- Display* /* display */
-#endif
-);
-extern Atom XInternAtom(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* atom_name */,
- Bool /* only_if_exists */
-#endif
-);
-extern Status XInternAtoms(
-#if NeedFunctionPrototypes
- Display* /* dpy */,
- char** /* names */,
- int /* count */,
- Bool /* onlyIfExists */,
- Atom* /* atoms_return */
-#endif
-);
-extern Colormap XCopyColormapAndFree(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */
-#endif
-);
-extern Colormap XCreateColormap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Visual* /* visual */,
- int /* alloc */
-#endif
-);
-extern Cursor XCreatePixmapCursor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Pixmap /* source */,
- Pixmap /* mask */,
- XColor* /* foreground_color */,
- XColor* /* background_color */,
- unsigned int /* x */,
- unsigned int /* y */
-#endif
-);
-extern Cursor XCreateGlyphCursor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Font /* source_font */,
- Font /* mask_font */,
- unsigned int /* source_char */,
- unsigned int /* mask_char */,
- XColor _Xconst * /* foreground_color */,
- XColor _Xconst * /* background_color */
-#endif
-);
-extern Cursor XCreateFontCursor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- unsigned int /* shape */
-#endif
-);
-extern Font XLoadFont(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* name */
-#endif
-);
-extern GC XCreateGC(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- unsigned long /* valuemask */,
- XGCValues* /* values */
-#endif
-);
-extern GContext XGContextFromGC(
-#if NeedFunctionPrototypes
- GC /* gc */
-#endif
-);
-extern void XFlushGC(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */
-#endif
-);
-extern Pixmap XCreatePixmap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- unsigned int /* width */,
- unsigned int /* height */,
- unsigned int /* depth */
-#endif
-);
-extern Pixmap XCreateBitmapFromData(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- _Xconst char* /* data */,
- unsigned int /* width */,
- unsigned int /* height */
-#endif
-);
-extern Pixmap XCreatePixmapFromBitmapData(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- char* /* data */,
- unsigned int /* width */,
- unsigned int /* height */,
- unsigned long /* fg */,
- unsigned long /* bg */,
- unsigned int /* depth */
-#endif
-);
-extern Window XCreateSimpleWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* parent */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */,
- unsigned int /* border_width */,
- unsigned long /* border */,
- unsigned long /* background */
-#endif
-);
-extern Window XGetSelectionOwner(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Atom /* selection */
-#endif
-);
-extern Window XCreateWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* parent */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */,
- unsigned int /* border_width */,
- int /* depth */,
- unsigned int /* class */,
- Visual* /* visual */,
- unsigned long /* valuemask */,
- XSetWindowAttributes* /* attributes */
-#endif
-);
-extern Colormap *XListInstalledColormaps(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int* /* num_return */
-#endif
-);
-extern char **XListFonts(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* pattern */,
- int /* maxnames */,
- int* /* actual_count_return */
-#endif
-);
-extern char **XListFontsWithInfo(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* pattern */,
- int /* maxnames */,
- int* /* count_return */,
- XFontStruct** /* info_return */
-#endif
-);
-extern char **XGetFontPath(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int* /* npaths_return */
-#endif
-);
-extern char **XListExtensions(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int* /* nextensions_return */
-#endif
-);
-extern Atom *XListProperties(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int* /* num_prop_return */
-#endif
-);
-extern XHostAddress *XListHosts(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int* /* nhosts_return */,
- Bool* /* state_return */
-#endif
-);
-extern KeySym XKeycodeToKeysym(
-#if NeedFunctionPrototypes
- Display* /* display */,
-#if NeedWidePrototypes
- unsigned int /* keycode */,
-#else
- KeyCode /* keycode */,
-#endif
- int /* index */
-#endif
-);
-extern KeySym XLookupKeysym(
-#if NeedFunctionPrototypes
- XKeyEvent* /* key_event */,
- int /* index */
-#endif
-);
-extern KeySym *XGetKeyboardMapping(
-#if NeedFunctionPrototypes
- Display* /* display */,
-#if NeedWidePrototypes
- unsigned int /* first_keycode */,
-#else
- KeyCode /* first_keycode */,
-#endif
- int /* keycode_count */,
- int* /* keysyms_per_keycode_return */
-#endif
-);
-extern KeySym XStringToKeysym(
-#if NeedFunctionPrototypes
- _Xconst char* /* string */
-#endif
-);
-extern long XMaxRequestSize(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern long XExtendedMaxRequestSize(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern char *XResourceManagerString(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern char *XScreenResourceString(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-extern unsigned long XDisplayMotionBufferSize(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern VisualID XVisualIDFromVisual(
-#if NeedFunctionPrototypes
- Visual* /* visual */
-#endif
-);
-
-/* multithread routines */
-
-extern Status XInitThreads(
-#if NeedFunctionPrototypes
- void
-#endif
-);
-
-extern void XLockDisplay(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern void XUnlockDisplay(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-/* routines for dealing with extensions */
-
-extern XExtCodes *XInitExtension(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* name */
-#endif
-);
-
-extern XExtCodes *XAddExtension(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern XExtData *XFindOnExtensionList(
-#if NeedFunctionPrototypes
- XExtData** /* structure */,
- int /* number */
-#endif
-);
-extern XExtData **XEHeadOfExtensionList(
-#if NeedFunctionPrototypes
- XEDataObject /* object */
-#endif
-);
-
-/* these are routines for which there are also macros */
-extern Window XRootWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-extern Window XDefaultRootWindow(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern Window XRootWindowOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-extern Visual *XDefaultVisual(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-extern Visual *XDefaultVisualOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-extern GC XDefaultGC(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-extern GC XDefaultGCOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-extern unsigned long XBlackPixel(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-extern unsigned long XWhitePixel(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-extern unsigned long XAllPlanes(
-#if NeedFunctionPrototypes
- void
-#endif
-);
-extern unsigned long XBlackPixelOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-extern unsigned long XWhitePixelOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-extern unsigned long XNextRequest(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern unsigned long XLastKnownRequestProcessed(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern char *XServerVendor(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern char *XDisplayString(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern Colormap XDefaultColormap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-extern Colormap XDefaultColormapOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-extern Display *XDisplayOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-extern Screen *XScreenOfDisplay(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-extern Screen *XDefaultScreenOfDisplay(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-extern long XEventMaskOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern int XScreenNumberOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-typedef int (*XErrorHandler) ( /* WARNING, this type not in Xlib spec */
-#if NeedFunctionPrototypes
- Display* /* display */,
- XErrorEvent* /* error_event */
-#endif
-);
-
-extern XErrorHandler XSetErrorHandler (
-#if NeedFunctionPrototypes
- XErrorHandler /* handler */
-#endif
-);
-
-
-typedef int (*XIOErrorHandler) ( /* WARNING, this type not in Xlib spec */
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern XIOErrorHandler XSetIOErrorHandler (
-#if NeedFunctionPrototypes
- XIOErrorHandler /* handler */
-#endif
-);
-
-extern XPixmapFormatValues *XListPixmapFormats(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int* /* count_return */
-#endif
-);
-extern int *XListDepths(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */,
- int* /* count_return */
-#endif
-);
-
-/* ICCCM routines for things that don't require special include files; */
-/* other declarations are given in Xutil.h */
-extern Status XReconfigureWMWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int /* screen_number */,
- unsigned int /* mask */,
- XWindowChanges* /* changes */
-#endif
-);
-
-extern Status XGetWMProtocols(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Atom** /* protocols_return */,
- int* /* count_return */
-#endif
-);
-extern Status XSetWMProtocols(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Atom* /* protocols */,
- int /* count */
-#endif
-);
-extern Status XIconifyWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int /* screen_number */
-#endif
-);
-extern Status XWithdrawWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int /* screen_number */
-#endif
-);
-extern Status XGetCommand(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- char*** /* argv_return */,
- int* /* argc_return */
-#endif
-);
-extern Status XGetWMColormapWindows(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Window** /* windows_return */,
- int* /* count_return */
-#endif
-);
-extern Status XSetWMColormapWindows(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Window* /* colormap_windows */,
- int /* count */
-#endif
-);
-extern void XFreeStringList(
-#if NeedFunctionPrototypes
- char** /* list */
-#endif
-);
-extern int XSetTransientForHint(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Window /* prop_window */
-#endif
-);
-
-/* The following are given in alphabetical order */
-
-extern int XActivateScreenSaver(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XAddHost(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XHostAddress* /* host */
-#endif
-);
-
-extern int XAddHosts(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XHostAddress* /* hosts */,
- int /* num_hosts */
-#endif
-);
-
-extern int XAddToExtensionList(
-#if NeedFunctionPrototypes
- struct _XExtData** /* structure */,
- XExtData* /* ext_data */
-#endif
-);
-
-extern int XAddToSaveSet(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern Status XAllocColor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- XColor* /* screen_in_out */
-#endif
-);
-
-extern Status XAllocColorCells(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- Bool /* contig */,
- unsigned long* /* plane_masks_return */,
- unsigned int /* nplanes */,
- unsigned long* /* pixels_return */,
- unsigned int /* npixels */
-#endif
-);
-
-extern Status XAllocColorPlanes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- Bool /* contig */,
- unsigned long* /* pixels_return */,
- int /* ncolors */,
- int /* nreds */,
- int /* ngreens */,
- int /* nblues */,
- unsigned long* /* rmask_return */,
- unsigned long* /* gmask_return */,
- unsigned long* /* bmask_return */
-#endif
-);
-
-extern Status XAllocNamedColor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- _Xconst char* /* color_name */,
- XColor* /* screen_def_return */,
- XColor* /* exact_def_return */
-#endif
-);
-
-extern int XAllowEvents(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* event_mode */,
- Time /* time */
-#endif
-);
-
-extern int XAutoRepeatOff(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XAutoRepeatOn(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XBell(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* percent */
-#endif
-);
-
-extern int XBitmapBitOrder(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XBitmapPad(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XBitmapUnit(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XCellsOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern int XChangeActivePointerGrab(
-#if NeedFunctionPrototypes
- Display* /* display */,
- unsigned int /* event_mask */,
- Cursor /* cursor */,
- Time /* time */
-#endif
-);
-
-extern int XChangeGC(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- unsigned long /* valuemask */,
- XGCValues* /* values */
-#endif
-);
-
-extern int XChangeKeyboardControl(
-#if NeedFunctionPrototypes
- Display* /* display */,
- unsigned long /* value_mask */,
- XKeyboardControl* /* values */
-#endif
-);
-
-extern int XChangeKeyboardMapping(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* first_keycode */,
- int /* keysyms_per_keycode */,
- KeySym* /* keysyms */,
- int /* num_codes */
-#endif
-);
-
-extern int XChangePointerControl(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Bool /* do_accel */,
- Bool /* do_threshold */,
- int /* accel_numerator */,
- int /* accel_denominator */,
- int /* threshold */
-#endif
-);
-
-extern int XChangeProperty(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Atom /* property */,
- Atom /* type */,
- int /* format */,
- int /* mode */,
- _Xconst unsigned char* /* data */,
- int /* nelements */
-#endif
-);
-
-extern int XChangeSaveSet(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int /* change_mode */
-#endif
-);
-
-extern int XChangeWindowAttributes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- unsigned long /* valuemask */,
- XSetWindowAttributes* /* attributes */
-#endif
-);
-
-extern Bool XCheckIfEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XEvent* /* event_return */,
- Bool (*) (
-#if NeedNestedPrototypes
- Display* /* display */,
- XEvent* /* event */,
- XPointer /* arg */
-#endif
- ) /* predicate */,
- XPointer /* arg */
-#endif
-);
-
-extern Bool XCheckMaskEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- long /* event_mask */,
- XEvent* /* event_return */
-#endif
-);
-
-extern Bool XCheckTypedEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* event_type */,
- XEvent* /* event_return */
-#endif
-);
-
-extern Bool XCheckTypedWindowEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int /* event_type */,
- XEvent* /* event_return */
-#endif
-);
-
-extern Bool XCheckWindowEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- long /* event_mask */,
- XEvent* /* event_return */
-#endif
-);
-
-extern int XCirculateSubwindows(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int /* direction */
-#endif
-);
-
-extern int XCirculateSubwindowsDown(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XCirculateSubwindowsUp(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XClearArea(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */,
- Bool /* exposures */
-#endif
-);
-
-extern int XClearWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XCloseDisplay(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XConfigureWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- unsigned int /* value_mask */,
- XWindowChanges* /* values */
-#endif
-);
-
-extern int XConnectionNumber(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XConvertSelection(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Atom /* selection */,
- Atom /* target */,
- Atom /* property */,
- Window /* requestor */,
- Time /* time */
-#endif
-);
-
-extern int XCopyArea(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* src */,
- Drawable /* dest */,
- GC /* gc */,
- int /* src_x */,
- int /* src_y */,
- unsigned int /* width */,
- unsigned int /* height */,
- int /* dest_x */,
- int /* dest_y */
-#endif
-);
-
-extern int XCopyGC(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* src */,
- unsigned long /* valuemask */,
- GC /* dest */
-#endif
-);
-
-extern int XCopyPlane(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* src */,
- Drawable /* dest */,
- GC /* gc */,
- int /* src_x */,
- int /* src_y */,
- unsigned int /* width */,
- unsigned int /* height */,
- int /* dest_x */,
- int /* dest_y */,
- unsigned long /* plane */
-#endif
-);
-
-extern int XDefaultDepth(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-
-extern int XDefaultDepthOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern int XDefaultScreen(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XDefineCursor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Cursor /* cursor */
-#endif
-);
-
-extern int XDeleteProperty(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Atom /* property */
-#endif
-);
-
-extern int XDestroyWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XDestroySubwindows(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XDoesBackingStore(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern Bool XDoesSaveUnders(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern int XDisableAccessControl(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-
-extern int XDisplayCells(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-
-extern int XDisplayHeight(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-
-extern int XDisplayHeightMM(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-
-extern int XDisplayKeycodes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int* /* min_keycodes_return */,
- int* /* max_keycodes_return */
-#endif
-);
-
-extern int XDisplayPlanes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-
-extern int XDisplayWidth(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-
-extern int XDisplayWidthMM(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */
-#endif
-);
-
-extern int XDrawArc(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */,
- int /* angle1 */,
- int /* angle2 */
-#endif
-);
-
-extern int XDrawArcs(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- XArc* /* arcs */,
- int /* narcs */
-#endif
-);
-
-extern int XDrawImageString(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- _Xconst char* /* string */,
- int /* length */
-#endif
-);
-
-extern int XDrawImageString16(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- _Xconst XChar2b* /* string */,
- int /* length */
-#endif
-);
-
-extern int XDrawLine(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x1 */,
- int /* y1 */,
- int /* x2 */,
- int /* y2 */
-#endif
-);
-
-extern int XDrawLines(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- XPoint* /* points */,
- int /* npoints */,
- int /* mode */
-#endif
-);
-
-extern int XDrawPoint(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */
-#endif
-);
-
-extern int XDrawPoints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- XPoint* /* points */,
- int /* npoints */,
- int /* mode */
-#endif
-);
-
-extern int XDrawRectangle(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */
-#endif
-);
-
-extern int XDrawRectangles(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- XRectangle* /* rectangles */,
- int /* nrectangles */
-#endif
-);
-
-extern int XDrawSegments(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- XSegment* /* segments */,
- int /* nsegments */
-#endif
-);
-
-extern int XDrawString(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- _Xconst char* /* string */,
- int /* length */
-#endif
-);
-
-extern int XDrawString16(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- _Xconst XChar2b* /* string */,
- int /* length */
-#endif
-);
-
-extern int XDrawText(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- XTextItem* /* items */,
- int /* nitems */
-#endif
-);
-
-extern int XDrawText16(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- XTextItem16* /* items */,
- int /* nitems */
-#endif
-);
-
-extern int XEnableAccessControl(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XEventsQueued(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* mode */
-#endif
-);
-
-extern Status XFetchName(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- char** /* window_name_return */
-#endif
-);
-
-extern int XFillArc(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */,
- int /* angle1 */,
- int /* angle2 */
-#endif
-);
-
-extern int XFillArcs(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- XArc* /* arcs */,
- int /* narcs */
-#endif
-);
-
-extern int XFillPolygon(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- XPoint* /* points */,
- int /* npoints */,
- int /* shape */,
- int /* mode */
-#endif
-);
-
-extern int XFillRectangle(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */
-#endif
-);
-
-extern int XFillRectangles(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- XRectangle* /* rectangles */,
- int /* nrectangles */
-#endif
-);
-
-extern int XFlush(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XForceScreenSaver(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* mode */
-#endif
-);
-
-extern int XFree(
-#if NeedFunctionPrototypes
- void* /* data */
-#endif
-);
-
-extern int XFreeColormap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */
-#endif
-);
-
-extern int XFreeColors(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- unsigned long* /* pixels */,
- int /* npixels */,
- unsigned long /* planes */
-#endif
-);
-
-extern int XFreeCursor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Cursor /* cursor */
-#endif
-);
-
-extern int XFreeExtensionList(
-#if NeedFunctionPrototypes
- char** /* list */
-#endif
-);
-
-extern int XFreeFont(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XFontStruct* /* font_struct */
-#endif
-);
-
-extern int XFreeFontInfo(
-#if NeedFunctionPrototypes
- char** /* names */,
- XFontStruct* /* free_info */,
- int /* actual_count */
-#endif
-);
-
-extern int XFreeFontNames(
-#if NeedFunctionPrototypes
- char** /* list */
-#endif
-);
-
-extern int XFreeFontPath(
-#if NeedFunctionPrototypes
- char** /* list */
-#endif
-);
-
-extern int XFreeGC(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */
-#endif
-);
-
-extern int XFreeModifiermap(
-#if NeedFunctionPrototypes
- XModifierKeymap* /* modmap */
-#endif
-);
-
-extern int XFreePixmap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Pixmap /* pixmap */
-#endif
-);
-
-extern int XGeometry(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen */,
- _Xconst char* /* position */,
- _Xconst char* /* default_position */,
- unsigned int /* bwidth */,
- unsigned int /* fwidth */,
- unsigned int /* fheight */,
- int /* xadder */,
- int /* yadder */,
- int* /* x_return */,
- int* /* y_return */,
- int* /* width_return */,
- int* /* height_return */
-#endif
-);
-
-extern int XGetErrorDatabaseText(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* name */,
- _Xconst char* /* message */,
- _Xconst char* /* default_string */,
- char* /* buffer_return */,
- int /* length */
-#endif
-);
-
-extern int XGetErrorText(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* code */,
- char* /* buffer_return */,
- int /* length */
-#endif
-);
-
-extern Bool XGetFontProperty(
-#if NeedFunctionPrototypes
- XFontStruct* /* font_struct */,
- Atom /* atom */,
- unsigned long* /* value_return */
-#endif
-);
-
-extern Status XGetGCValues(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- unsigned long /* valuemask */,
- XGCValues* /* values_return */
-#endif
-);
-
-extern Status XGetGeometry(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- Window* /* root_return */,
- int* /* x_return */,
- int* /* y_return */,
- unsigned int* /* width_return */,
- unsigned int* /* height_return */,
- unsigned int* /* border_width_return */,
- unsigned int* /* depth_return */
-#endif
-);
-
-extern Status XGetIconName(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- char** /* icon_name_return */
-#endif
-);
-
-extern int XGetInputFocus(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window* /* focus_return */,
- int* /* revert_to_return */
-#endif
-);
-
-extern int XGetKeyboardControl(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XKeyboardState* /* values_return */
-#endif
-);
-
-extern int XGetPointerControl(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int* /* accel_numerator_return */,
- int* /* accel_denominator_return */,
- int* /* threshold_return */
-#endif
-);
-
-extern int XGetPointerMapping(
-#if NeedFunctionPrototypes
- Display* /* display */,
- unsigned char* /* map_return */,
- int /* nmap */
-#endif
-);
-
-extern int XGetScreenSaver(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int* /* timeout_return */,
- int* /* interval_return */,
- int* /* prefer_blanking_return */,
- int* /* allow_exposures_return */
-#endif
-);
-
-extern Status XGetTransientForHint(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Window* /* prop_window_return */
-#endif
-);
-
-extern int XGetWindowProperty(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Atom /* property */,
- long /* long_offset */,
- long /* long_length */,
- Bool /* delete */,
- Atom /* req_type */,
- Atom* /* actual_type_return */,
- int* /* actual_format_return */,
- unsigned long* /* nitems_return */,
- unsigned long* /* bytes_after_return */,
- unsigned char** /* prop_return */
-#endif
-);
-
-extern Status XGetWindowAttributes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XWindowAttributes* /* window_attributes_return */
-#endif
-);
-
-extern int XGrabButton(
-#if NeedFunctionPrototypes
- Display* /* display */,
- unsigned int /* button */,
- unsigned int /* modifiers */,
- Window /* grab_window */,
- Bool /* owner_events */,
- unsigned int /* event_mask */,
- int /* pointer_mode */,
- int /* keyboard_mode */,
- Window /* confine_to */,
- Cursor /* cursor */
-#endif
-);
-
-extern int XGrabKey(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* keycode */,
- unsigned int /* modifiers */,
- Window /* grab_window */,
- Bool /* owner_events */,
- int /* pointer_mode */,
- int /* keyboard_mode */
-#endif
-);
-
-extern int XGrabKeyboard(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* grab_window */,
- Bool /* owner_events */,
- int /* pointer_mode */,
- int /* keyboard_mode */,
- Time /* time */
-#endif
-);
-
-extern int XGrabPointer(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* grab_window */,
- Bool /* owner_events */,
- unsigned int /* event_mask */,
- int /* pointer_mode */,
- int /* keyboard_mode */,
- Window /* confine_to */,
- Cursor /* cursor */,
- Time /* time */
-#endif
-);
-
-extern int XGrabServer(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XHeightMMOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern int XHeightOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern int XIfEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XEvent* /* event_return */,
- Bool (*) (
-#if NeedNestedPrototypes
- Display* /* display */,
- XEvent* /* event */,
- XPointer /* arg */
-#endif
- ) /* predicate */,
- XPointer /* arg */
-#endif
-);
-
-extern int XImageByteOrder(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XInstallColormap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */
-#endif
-);
-
-extern KeyCode XKeysymToKeycode(
-#if NeedFunctionPrototypes
- Display* /* display */,
- KeySym /* keysym */
-#endif
-);
-
-extern int XKillClient(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XID /* resource */
-#endif
-);
-
-extern Status XLookupColor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- _Xconst char* /* color_name */,
- XColor* /* exact_def_return */,
- XColor* /* screen_def_return */
-#endif
-);
-
-extern int XLowerWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XMapRaised(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XMapSubwindows(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XMapWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XMaskEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- long /* event_mask */,
- XEvent* /* event_return */
-#endif
-);
-
-extern int XMaxCmapsOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern int XMinCmapsOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern int XMoveResizeWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */
-#endif
-);
-
-extern int XMoveWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- int /* x */,
- int /* y */
-#endif
-);
-
-extern int XNextEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XEvent* /* event_return */
-#endif
-);
-
-extern int XNoOp(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern Status XParseColor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- _Xconst char* /* spec */,
- XColor* /* exact_def_return */
-#endif
-);
-
-extern int XParseGeometry(
-#if NeedFunctionPrototypes
- _Xconst char* /* parsestring */,
- int* /* x_return */,
- int* /* y_return */,
- unsigned int* /* width_return */,
- unsigned int* /* height_return */
-#endif
-);
-
-extern int XPeekEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XEvent* /* event_return */
-#endif
-);
-
-extern int XPeekIfEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XEvent* /* event_return */,
- Bool (*) (
-#if NeedNestedPrototypes
- Display* /* display */,
- XEvent* /* event */,
- XPointer /* arg */
-#endif
- ) /* predicate */,
- XPointer /* arg */
-#endif
-);
-
-extern int XPending(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XPlanesOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-
-#endif
-);
-
-extern int XProtocolRevision(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XProtocolVersion(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-
-extern int XPutBackEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XEvent* /* event */
-#endif
-);
-
-extern int XPutImage(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- XImage* /* image */,
- int /* src_x */,
- int /* src_y */,
- int /* dest_x */,
- int /* dest_y */,
- unsigned int /* width */,
- unsigned int /* height */
-#endif
-);
-
-extern int XQLength(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern Status XQueryBestCursor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- unsigned int /* width */,
- unsigned int /* height */,
- unsigned int* /* width_return */,
- unsigned int* /* height_return */
-#endif
-);
-
-extern Status XQueryBestSize(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* class */,
- Drawable /* which_screen */,
- unsigned int /* width */,
- unsigned int /* height */,
- unsigned int* /* width_return */,
- unsigned int* /* height_return */
-#endif
-);
-
-extern Status XQueryBestStipple(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* which_screen */,
- unsigned int /* width */,
- unsigned int /* height */,
- unsigned int* /* width_return */,
- unsigned int* /* height_return */
-#endif
-);
-
-extern Status XQueryBestTile(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* which_screen */,
- unsigned int /* width */,
- unsigned int /* height */,
- unsigned int* /* width_return */,
- unsigned int* /* height_return */
-#endif
-);
-
-extern int XQueryColor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- XColor* /* def_in_out */
-#endif
-);
-
-extern int XQueryColors(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- XColor* /* defs_in_out */,
- int /* ncolors */
-#endif
-);
-
-extern Bool XQueryExtension(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* name */,
- int* /* major_opcode_return */,
- int* /* first_event_return */,
- int* /* first_error_return */
-#endif
-);
-
-extern int XQueryKeymap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- char [32] /* keys_return */
-#endif
-);
-
-extern Bool XQueryPointer(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Window* /* root_return */,
- Window* /* child_return */,
- int* /* root_x_return */,
- int* /* root_y_return */,
- int* /* win_x_return */,
- int* /* win_y_return */,
- unsigned int* /* mask_return */
-#endif
-);
-
-extern int XQueryTextExtents(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XID /* font_ID */,
- _Xconst char* /* string */,
- int /* nchars */,
- int* /* direction_return */,
- int* /* font_ascent_return */,
- int* /* font_descent_return */,
- XCharStruct* /* overall_return */
-#endif
-);
-
-extern int XQueryTextExtents16(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XID /* font_ID */,
- _Xconst XChar2b* /* string */,
- int /* nchars */,
- int* /* direction_return */,
- int* /* font_ascent_return */,
- int* /* font_descent_return */,
- XCharStruct* /* overall_return */
-#endif
-);
-
-extern Status XQueryTree(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Window* /* root_return */,
- Window* /* parent_return */,
- Window** /* children_return */,
- unsigned int* /* nchildren_return */
-#endif
-);
-
-extern int XRaiseWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XReadBitmapFile(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- _Xconst char* /* filename */,
- unsigned int* /* width_return */,
- unsigned int* /* height_return */,
- Pixmap* /* bitmap_return */,
- int* /* x_hot_return */,
- int* /* y_hot_return */
-#endif
-);
-
-extern int XReadBitmapFileData(
-#if NeedFunctionPrototypes
- _Xconst char* /* filename */,
- unsigned int* /* width_return */,
- unsigned int* /* height_return */,
- unsigned char** /* data_return */,
- int* /* x_hot_return */,
- int* /* y_hot_return */
-#endif
-);
-
-extern int XRebindKeysym(
-#if NeedFunctionPrototypes
- Display* /* display */,
- KeySym /* keysym */,
- KeySym* /* list */,
- int /* mod_count */,
- _Xconst unsigned char* /* string */,
- int /* bytes_string */
-#endif
-);
-
-extern int XRecolorCursor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Cursor /* cursor */,
- XColor* /* foreground_color */,
- XColor* /* background_color */
-#endif
-);
-
-extern int XRefreshKeyboardMapping(
-#if NeedFunctionPrototypes
- XMappingEvent* /* event_map */
-#endif
-);
-
-extern int XRemoveFromSaveSet(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XRemoveHost(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XHostAddress* /* host */
-#endif
-);
-
-extern int XRemoveHosts(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XHostAddress* /* hosts */,
- int /* num_hosts */
-#endif
-);
-
-extern int XReparentWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Window /* parent */,
- int /* x */,
- int /* y */
-#endif
-);
-
-extern int XResetScreenSaver(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XResizeWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- unsigned int /* width */,
- unsigned int /* height */
-#endif
-);
-
-extern int XRestackWindows(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window* /* windows */,
- int /* nwindows */
-#endif
-);
-
-extern int XRotateBuffers(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* rotate */
-#endif
-);
-
-extern int XRotateWindowProperties(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Atom* /* properties */,
- int /* num_prop */,
- int /* npositions */
-#endif
-);
-
-extern int XScreenCount(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XSelectInput(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- long /* event_mask */
-#endif
-);
-
-extern Status XSendEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Bool /* propagate */,
- long /* event_mask */,
- XEvent* /* event_send */
-#endif
-);
-
-extern int XSetAccessControl(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* mode */
-#endif
-);
-
-extern int XSetArcMode(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- int /* arc_mode */
-#endif
-);
-
-extern int XSetBackground(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- unsigned long /* background */
-#endif
-);
-
-extern int XSetClipMask(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- Pixmap /* pixmap */
-#endif
-);
-
-extern int XSetClipOrigin(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- int /* clip_x_origin */,
- int /* clip_y_origin */
-#endif
-);
-
-extern int XSetClipRectangles(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- int /* clip_x_origin */,
- int /* clip_y_origin */,
- XRectangle* /* rectangles */,
- int /* n */,
- int /* ordering */
-#endif
-);
-
-extern int XSetCloseDownMode(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* close_mode */
-#endif
-);
-
-extern int XSetCommand(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- char** /* argv */,
- int /* argc */
-#endif
-);
-
-extern int XSetDashes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- int /* dash_offset */,
- _Xconst char* /* dash_list */,
- int /* n */
-#endif
-);
-
-extern int XSetFillRule(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- int /* fill_rule */
-#endif
-);
-
-extern int XSetFillStyle(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- int /* fill_style */
-#endif
-);
-
-extern int XSetFont(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- Font /* font */
-#endif
-);
-
-extern int XSetFontPath(
-#if NeedFunctionPrototypes
- Display* /* display */,
- char** /* directories */,
- int /* ndirs */
-#endif
-);
-
-extern int XSetForeground(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- unsigned long /* foreground */
-#endif
-);
-
-extern int XSetFunction(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- int /* function */
-#endif
-);
-
-extern int XSetGraphicsExposures(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- Bool /* graphics_exposures */
-#endif
-);
-
-extern int XSetIconName(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- _Xconst char* /* icon_name */
-#endif
-);
-
-extern int XSetInputFocus(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* focus */,
- int /* revert_to */,
- Time /* time */
-#endif
-);
-
-extern int XSetLineAttributes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- unsigned int /* line_width */,
- int /* line_style */,
- int /* cap_style */,
- int /* join_style */
-#endif
-);
-
-extern int XSetModifierMapping(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XModifierKeymap* /* modmap */
-#endif
-);
-
-extern int XSetPlaneMask(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- unsigned long /* plane_mask */
-#endif
-);
-
-extern int XSetPointerMapping(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst unsigned char* /* map */,
- int /* nmap */
-#endif
-);
-
-extern int XSetScreenSaver(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* timeout */,
- int /* interval */,
- int /* prefer_blanking */,
- int /* allow_exposures */
-#endif
-);
-
-extern int XSetSelectionOwner(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Atom /* selection */,
- Window /* owner */,
- Time /* time */
-#endif
-);
-
-extern int XSetState(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- unsigned long /* foreground */,
- unsigned long /* background */,
- int /* function */,
- unsigned long /* plane_mask */
-#endif
-);
-
-extern int XSetStipple(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- Pixmap /* stipple */
-#endif
-);
-
-extern int XSetSubwindowMode(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- int /* subwindow_mode */
-#endif
-);
-
-extern int XSetTSOrigin(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- int /* ts_x_origin */,
- int /* ts_y_origin */
-#endif
-);
-
-extern int XSetTile(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- Pixmap /* tile */
-#endif
-);
-
-extern int XSetWindowBackground(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- unsigned long /* background_pixel */
-#endif
-);
-
-extern int XSetWindowBackgroundPixmap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Pixmap /* background_pixmap */
-#endif
-);
-
-extern int XSetWindowBorder(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- unsigned long /* border_pixel */
-#endif
-);
-
-extern int XSetWindowBorderPixmap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Pixmap /* border_pixmap */
-#endif
-);
-
-extern int XSetWindowBorderWidth(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- unsigned int /* width */
-#endif
-);
-
-extern int XSetWindowColormap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- Colormap /* colormap */
-#endif
-);
-
-extern int XStoreBuffer(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* bytes */,
- int /* nbytes */,
- int /* buffer */
-#endif
-);
-
-extern int XStoreBytes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* bytes */,
- int /* nbytes */
-#endif
-);
-
-extern int XStoreColor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- XColor* /* color */
-#endif
-);
-
-extern int XStoreColors(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- XColor* /* color */,
- int /* ncolors */
-#endif
-);
-
-extern int XStoreName(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- _Xconst char* /* window_name */
-#endif
-);
-
-extern int XStoreNamedColor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */,
- _Xconst char* /* color */,
- unsigned long /* pixel */,
- int /* flags */
-#endif
-);
-
-extern int XSync(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Bool /* discard */
-#endif
-);
-
-extern int XTextExtents(
-#if NeedFunctionPrototypes
- XFontStruct* /* font_struct */,
- _Xconst char* /* string */,
- int /* nchars */,
- int* /* direction_return */,
- int* /* font_ascent_return */,
- int* /* font_descent_return */,
- XCharStruct* /* overall_return */
-#endif
-);
-
-extern int XTextExtents16(
-#if NeedFunctionPrototypes
- XFontStruct* /* font_struct */,
- _Xconst XChar2b* /* string */,
- int /* nchars */,
- int* /* direction_return */,
- int* /* font_ascent_return */,
- int* /* font_descent_return */,
- XCharStruct* /* overall_return */
-#endif
-);
-
-extern int XTextWidth(
-#if NeedFunctionPrototypes
- XFontStruct* /* font_struct */,
- _Xconst char* /* string */,
- int /* count */
-#endif
-);
-
-extern int XTextWidth16(
-#if NeedFunctionPrototypes
- XFontStruct* /* font_struct */,
- _Xconst XChar2b* /* string */,
- int /* count */
-#endif
-);
-
-extern Bool XTranslateCoordinates(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* src_w */,
- Window /* dest_w */,
- int /* src_x */,
- int /* src_y */,
- int* /* dest_x_return */,
- int* /* dest_y_return */,
- Window* /* child_return */
-#endif
-);
-
-extern int XUndefineCursor(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XUngrabButton(
-#if NeedFunctionPrototypes
- Display* /* display */,
- unsigned int /* button */,
- unsigned int /* modifiers */,
- Window /* grab_window */
-#endif
-);
-
-extern int XUngrabKey(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* keycode */,
- unsigned int /* modifiers */,
- Window /* grab_window */
-#endif
-);
-
-extern int XUngrabKeyboard(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Time /* time */
-#endif
-);
-
-extern int XUngrabPointer(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Time /* time */
-#endif
-);
-
-extern int XUngrabServer(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XUninstallColormap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Colormap /* colormap */
-#endif
-);
-
-extern int XUnloadFont(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Font /* font */
-#endif
-);
-
-extern int XUnmapSubwindows(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XUnmapWindow(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern int XVendorRelease(
-#if NeedFunctionPrototypes
- Display* /* display */
-#endif
-);
-
-extern int XWarpPointer(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* src_w */,
- Window /* dest_w */,
- int /* src_x */,
- int /* src_y */,
- unsigned int /* src_width */,
- unsigned int /* src_height */,
- int /* dest_x */,
- int /* dest_y */
-#endif
-);
-
-extern int XWidthMMOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern int XWidthOfScreen(
-#if NeedFunctionPrototypes
- Screen* /* screen */
-#endif
-);
-
-extern int XWindowEvent(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- long /* event_mask */,
- XEvent* /* event_return */
-#endif
-);
-
-extern int XWriteBitmapFile(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* filename */,
- Pixmap /* bitmap */,
- unsigned int /* width */,
- unsigned int /* height */,
- int /* x_hot */,
- int /* y_hot */
-#endif
-);
-
-extern Bool XSupportsLocale (void);
-
-extern char *XSetLocaleModifiers(
- const char* /* modifier_list */
-);
-
-extern XOM XOpenOM(
-#if NeedFunctionPrototypes
- Display* /* display */,
- struct _XrmHashBucketRec* /* rdb */,
- _Xconst char* /* res_name */,
- _Xconst char* /* res_class */
-#endif
-);
-
-extern Status XCloseOM(
-#if NeedFunctionPrototypes
- XOM /* om */
-#endif
-);
-
-extern char *XSetOMValues(
-#if NeedVarargsPrototypes
- XOM /* om */,
- ...
-#endif
-);
-
-extern char *XGetOMValues(
-#if NeedVarargsPrototypes
- XOM /* om */,
- ...
-#endif
-);
-
-extern Display *XDisplayOfOM(
-#if NeedFunctionPrototypes
- XOM /* om */
-#endif
-);
-
-extern char *XLocaleOfOM(
-#if NeedFunctionPrototypes
- XOM /* om */
-#endif
-);
-
-extern XOC XCreateOC(
-#if NeedVarargsPrototypes
- XOM /* om */,
- ...
-#endif
-);
-
-extern void XDestroyOC(
-#if NeedFunctionPrototypes
- XOC /* oc */
-#endif
-);
-
-extern XOM XOMOfOC(
-#if NeedFunctionPrototypes
- XOC /* oc */
-#endif
-);
-
-extern char *XSetOCValues(
-#if NeedVarargsPrototypes
- XOC /* oc */,
- ...
-#endif
-);
-
-extern char *XGetOCValues(
-#if NeedVarargsPrototypes
- XOC /* oc */,
- ...
-#endif
-);
-
-extern XFontSet XCreateFontSet(
-#if NeedFunctionPrototypes
- Display* /* display */,
- _Xconst char* /* base_font_name_list */,
- char*** /* missing_charset_list */,
- int* /* missing_charset_count */,
- char** /* def_string */
-#endif
-);
-
-extern void XFreeFontSet(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XFontSet /* font_set */
-#endif
-);
-
-extern int XFontsOfFontSet(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */,
- XFontStruct*** /* font_struct_list */,
- char*** /* font_name_list */
-#endif
-);
-
-extern char *XBaseFontNameListOfFontSet(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */
-#endif
-);
-
-extern char *XLocaleOfFontSet(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */
-#endif
-);
-
-extern Bool XContextDependentDrawing(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */
-#endif
-);
-
-extern Bool XDirectionalDependentDrawing(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */
-#endif
-);
-
-extern Bool XContextualDrawing(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */
-#endif
-);
-
-extern XFontSetExtents *XExtentsOfFontSet(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */
-#endif
-);
-
-extern int XmbTextEscapement(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */,
- _Xconst char* /* text */,
- int /* bytes_text */
-#endif
-);
-
-extern int XwcTextEscapement(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */,
- _Xconst wchar_t* /* text */,
- int /* num_wchars */
-#endif
-);
-
-extern int Xutf8TextEscapement(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */,
- _Xconst char* /* text */,
- int /* bytes_text */
-#endif
-);
-
-extern int XmbTextExtents(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */,
- _Xconst char* /* text */,
- int /* bytes_text */,
- XRectangle* /* overall_ink_return */,
- XRectangle* /* overall_logical_return */
-#endif
-);
-
-extern int XwcTextExtents(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */,
- _Xconst wchar_t* /* text */,
- int /* num_wchars */,
- XRectangle* /* overall_ink_return */,
- XRectangle* /* overall_logical_return */
-#endif
-);
-
-extern int Xutf8TextExtents(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */,
- _Xconst char* /* text */,
- int /* bytes_text */,
- XRectangle* /* overall_ink_return */,
- XRectangle* /* overall_logical_return */
-#endif
-);
-
-extern Status XmbTextPerCharExtents(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */,
- _Xconst char* /* text */,
- int /* bytes_text */,
- XRectangle* /* ink_extents_buffer */,
- XRectangle* /* logical_extents_buffer */,
- int /* buffer_size */,
- int* /* num_chars */,
- XRectangle* /* overall_ink_return */,
- XRectangle* /* overall_logical_return */
-#endif
-);
-
-extern Status XwcTextPerCharExtents(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */,
- _Xconst wchar_t* /* text */,
- int /* num_wchars */,
- XRectangle* /* ink_extents_buffer */,
- XRectangle* /* logical_extents_buffer */,
- int /* buffer_size */,
- int* /* num_chars */,
- XRectangle* /* overall_ink_return */,
- XRectangle* /* overall_logical_return */
-#endif
-);
-
-extern Status Xutf8TextPerCharExtents(
-#if NeedFunctionPrototypes
- XFontSet /* font_set */,
- _Xconst char* /* text */,
- int /* bytes_text */,
- XRectangle* /* ink_extents_buffer */,
- XRectangle* /* logical_extents_buffer */,
- int /* buffer_size */,
- int* /* num_chars */,
- XRectangle* /* overall_ink_return */,
- XRectangle* /* overall_logical_return */
-#endif
-);
-
-extern void XmbDrawText(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- XmbTextItem* /* text_items */,
- int /* nitems */
-#endif
-);
-
-extern void XwcDrawText(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- XwcTextItem* /* text_items */,
- int /* nitems */
-#endif
-);
-
-extern void Xutf8DrawText(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- XmbTextItem* /* text_items */,
- int /* nitems */
-#endif
-);
-
-extern void XmbDrawString(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- XFontSet /* font_set */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- _Xconst char* /* text */,
- int /* bytes_text */
-#endif
-);
-
-extern void XwcDrawString(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- XFontSet /* font_set */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- _Xconst wchar_t* /* text */,
- int /* num_wchars */
-#endif
-);
-
-extern void Xutf8DrawString(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- XFontSet /* font_set */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- _Xconst char* /* text */,
- int /* bytes_text */
-#endif
-);
-
-extern void XmbDrawImageString(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- XFontSet /* font_set */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- _Xconst char* /* text */,
- int /* bytes_text */
-#endif
-);
-
-extern void XwcDrawImageString(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- XFontSet /* font_set */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- _Xconst wchar_t* /* text */,
- int /* num_wchars */
-#endif
-);
-
-extern void Xutf8DrawImageString(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Drawable /* d */,
- XFontSet /* font_set */,
- GC /* gc */,
- int /* x */,
- int /* y */,
- _Xconst char* /* text */,
- int /* bytes_text */
-#endif
-);
-
-extern XIM XOpenIM(
-#if NeedFunctionPrototypes
- Display* /* dpy */,
- struct _XrmHashBucketRec* /* rdb */,
- char* /* res_name */,
- char* /* res_class */
-#endif
-);
-
-extern Status XCloseIM(
-#if NeedFunctionPrototypes
- XIM /* im */
-#endif
-);
-
-extern char *XGetIMValues(
-#if NeedVarargsPrototypes
- XIM /* im */, ...
-#endif
-);
-
-extern char *XSetIMValues(
-#if NeedVarargsPrototypes
- XIM /* im */, ...
-#endif
-);
-
-extern Display *XDisplayOfIM(
-#if NeedFunctionPrototypes
- XIM /* im */
-#endif
-);
-
-extern char *XLocaleOfIM(
-#if NeedFunctionPrototypes
- XIM /* im*/
-#endif
-);
-
-extern XIC XCreateIC(
-#if NeedVarargsPrototypes
- XIM /* im */, ...
-#endif
-);
-
-extern void XDestroyIC(
-#if NeedFunctionPrototypes
- XIC /* ic */
-#endif
-);
-
-extern void XSetICFocus(
-#if NeedFunctionPrototypes
- XIC /* ic */
-#endif
-);
-
-extern void XUnsetICFocus(
-#if NeedFunctionPrototypes
- XIC /* ic */
-#endif
-);
-
-extern wchar_t *XwcResetIC(
-#if NeedFunctionPrototypes
- XIC /* ic */
-#endif
-);
-
-extern char *XmbResetIC(
-#if NeedFunctionPrototypes
- XIC /* ic */
-#endif
-);
-
-extern char *Xutf8ResetIC(
-#if NeedFunctionPrototypes
- XIC /* ic */
-#endif
-);
-
-extern char *XSetICValues(
-#if NeedVarargsPrototypes
- XIC /* ic */, ...
-#endif
-);
-
-extern char *XGetICValues(
-#if NeedVarargsPrototypes
- XIC /* ic */, ...
-#endif
-);
-
-extern XIM XIMOfIC(
-#if NeedFunctionPrototypes
- XIC /* ic */
-#endif
-);
-
-extern Bool XFilterEvent(
-#if NeedFunctionPrototypes
- XEvent* /* event */,
- Window /* window */
-#endif
-);
-
-extern int XmbLookupString(
-#if NeedFunctionPrototypes
- XIC /* ic */,
- XKeyPressedEvent* /* event */,
- char* /* buffer_return */,
- int /* bytes_buffer */,
- KeySym* /* keysym_return */,
- Status* /* status_return */
-#endif
-);
-
-extern int XwcLookupString(
-#if NeedFunctionPrototypes
- XIC /* ic */,
- XKeyPressedEvent* /* event */,
- wchar_t* /* buffer_return */,
- int /* wchars_buffer */,
- KeySym* /* keysym_return */,
- Status* /* status_return */
-#endif
-);
-
-extern int Xutf8LookupString(
-#if NeedFunctionPrototypes
- XIC /* ic */,
- XKeyPressedEvent* /* event */,
- char* /* buffer_return */,
- int /* bytes_buffer */,
- KeySym* /* keysym_return */,
- Status* /* status_return */
-#endif
-);
-
-extern XVaNestedList XVaCreateNestedList(
-#if NeedVarargsPrototypes
- int /*unused*/, ...
-#endif
-);
-
-/* internal connections for IMs */
-
-extern Bool XRegisterIMInstantiateCallback(
-#if NeedFunctionPrototypes
- Display* /* dpy */,
- struct _XrmHashBucketRec* /* rdb */,
- char* /* res_name */,
- char* /* res_class */,
- XIDProc /* callback */,
- XPointer /* client_data */
-#endif
-);
-
-extern Bool XUnregisterIMInstantiateCallback(
-#if NeedFunctionPrototypes
- Display* /* dpy */,
- struct _XrmHashBucketRec* /* rdb */,
- char* /* res_name */,
- char* /* res_class */,
- XIDProc /* callback */,
- XPointer /* client_data */
-#endif
-);
-
-typedef void (*XConnectionWatchProc)(
-#if NeedFunctionPrototypes
- Display* /* dpy */,
- XPointer /* client_data */,
- int /* fd */,
- Bool /* opening */, /* open or close flag */
- XPointer* /* watch_data */ /* open sets, close uses */
-#endif
-);
-
-
-extern Status XInternalConnectionNumbers(
-#if NeedFunctionPrototypes
- Display* /* dpy */,
- int** /* fd_return */,
- int* /* count_return */
-#endif
-);
-
-extern void XProcessInternalConnection(
-#if NeedFunctionPrototypes
- Display* /* dpy */,
- int /* fd */
-#endif
-);
-
-extern Status XAddConnectionWatch(
-#if NeedFunctionPrototypes
- Display* /* dpy */,
- XConnectionWatchProc /* callback */,
- XPointer /* client_data */
-#endif
-);
-
-extern void XRemoveConnectionWatch(
-#if NeedFunctionPrototypes
- Display* /* dpy */,
- XConnectionWatchProc /* callback */,
- XPointer /* client_data */
-#endif
-);
-
-extern void XSetAuthorization(
-#if NeedFunctionPrototypes
- char * /* name */,
- int /* namelen */,
- char * /* data */,
- int /* datalen */
-#endif
-);
-
-extern int _Xmbtowc(
-#if NeedFunctionPrototypes
- wchar_t * /* wstr */,
-#ifdef ISC
- char const * /* str */,
- size_t /* len */
-#else
- char * /* str */,
- int /* len */
-#endif
-#endif
-);
-
-extern int _Xwctomb(
-#if NeedFunctionPrototypes
- char * /* str */,
- wchar_t /* wc */
-#endif
-);
-
-_XFUNCPROTOEND
-#endif /* if 0 */
-
-#endif /* _XLIB_H_ */
-
-
-/* $Xorg: Xutil.h,v 1.8 2001/02/09 02:03:39 xorgcvs Exp $ */
-
-/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-/* $XFree86: xc/lib/X11/Xutil.h,v 3.5 2003/01/26 02:40:10 dawes Exp $ */
-
-#ifndef _XUTIL_H_
-#define _XUTIL_H_
-
-/* You must include <X11/Xlib.h> before including this file */
-#if 0
-#include <X11/Xlib.h>
-#endif
-
-/*
- * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
- * value (x, y, width, height) was found in the parsed string.
- */
-#define NoValue 0x0000
-#define XValue 0x0001
-#define YValue 0x0002
-#define WidthValue 0x0004
-#define HeightValue 0x0008
-#define AllValues 0x000F
-#define XNegative 0x0010
-#define YNegative 0x0020
-
-/*
- * new version containing base_width, base_height, and win_gravity fields;
- * used with WM_NORMAL_HINTS.
- */
-typedef struct {
- long flags; /* marks which fields in this structure are defined */
- int x, y; /* obsolete for new window mgrs, but clients */
- int width, height; /* should set so old wm's don't mess up */
- int min_width, min_height;
- int max_width, max_height;
- int width_inc, height_inc;
- struct {
- int x; /* numerator */
- int y; /* denominator */
- } min_aspect, max_aspect;
- int base_width, base_height; /* added by ICCCM version 1 */
- int win_gravity; /* added by ICCCM version 1 */
-} XSizeHints;
-
-/*
- * The next block of definitions are for window manager properties that
- * clients and applications use for communication.
- */
-
-/* flags argument in size hints */
-#define USPosition (1L << 0) /* user specified x, y */
-#define USSize (1L << 1) /* user specified width, height */
-
-#define PPosition (1L << 2) /* program specified position */
-#define PSize (1L << 3) /* program specified size */
-#define PMinSize (1L << 4) /* program specified minimum size */
-#define PMaxSize (1L << 5) /* program specified maximum size */
-#define PResizeInc (1L << 6) /* program specified resize increments */
-#define PAspect (1L << 7) /* program specified min and max aspect ratios */
-#define PBaseSize (1L << 8) /* program specified base for incrementing */
-#define PWinGravity (1L << 9) /* program specified window gravity */
-
-/* obsolete */
-#define PAllHints (PPosition|PSize|PMinSize|PMaxSize|PResizeInc|PAspect)
-
-
-
-typedef struct {
- long flags; /* marks which fields in this structure are defined */
- Bool input; /* does this application rely on the window manager to
- get keyboard input? */
- int initial_state; /* see below */
- Pixmap icon_pixmap; /* pixmap to be used as icon */
- Window icon_window; /* window to be used as icon */
- int icon_x, icon_y; /* initial position of icon */
- Pixmap icon_mask; /* icon mask bitmap */
- XID window_group; /* id of related window group */
- /* this structure may be extended in the future */
-} XWMHints;
-
-/* definition for flags of XWMHints */
-
-#define InputHint (1L << 0)
-#define StateHint (1L << 1)
-#define IconPixmapHint (1L << 2)
-#define IconWindowHint (1L << 3)
-#define IconPositionHint (1L << 4)
-#define IconMaskHint (1L << 5)
-#define WindowGroupHint (1L << 6)
-#define AllHints (InputHint|StateHint|IconPixmapHint|IconWindowHint| \
-IconPositionHint|IconMaskHint|WindowGroupHint)
-#define XUrgencyHint (1L << 8)
-
-/* definitions for initial window state */
-#define WithdrawnState 0 /* for windows that are not mapped */
-#define NormalState 1 /* most applications want to start this way */
-#define IconicState 3 /* application wants to start as an icon */
-
-/*
- * Obsolete states no longer defined by ICCCM
- */
-#define DontCareState 0 /* don't know or care */
-#define ZoomState 2 /* application wants to start zoomed */
-#define InactiveState 4 /* application believes it is seldom used; */
- /* some wm's may put it on inactive menu */
-
-
-/*
- * new structure for manipulating TEXT properties; used with WM_NAME,
- * WM_ICON_NAME, WM_CLIENT_MACHINE, and WM_COMMAND.
- */
-typedef struct {
- unsigned char *value; /* same as Property routines */
- Atom encoding; /* prop type */
- int format; /* prop data format: 8, 16, or 32 */
- unsigned long nitems; /* number of data items in value */
-} XTextProperty;
-
-#define XNoMemory -1
-#define XLocaleNotSupported -2
-#define XConverterNotFound -3
-
-typedef enum {
- XStringStyle, /* STRING */
- XCompoundTextStyle, /* COMPOUND_TEXT */
- XTextStyle, /* text in owner's encoding (current locale)*/
- XStdICCTextStyle, /* STRING, else COMPOUND_TEXT */
- /* The following is an XFree86 extension, introduced in November 2000 */
- XUTF8StringStyle /* UTF8_STRING */
-} XICCEncodingStyle;
-
-typedef struct {
- int min_width, min_height;
- int max_width, max_height;
- int width_inc, height_inc;
-} XIconSize;
-
-typedef struct {
- char *res_name;
- char *res_class;
-} XClassHint;
-
-/*
- * These macros are used to give some sugar to the image routines so that
- * naive people are more comfortable with them.
- */
-#define XDestroyImage(ximage) \
- ((*((ximage)->f.destroy_image))((ximage)))
-#define XGetPixel(ximage, x, y) \
- ((*((ximage)->f.get_pixel))((ximage), (x), (y)))
-#define XPutPixel(ximage, x, y, pixel) \
- ((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel)))
-#define XSubImage(ximage, x, y, width, height) \
- ((*((ximage)->f.sub_image))((ximage), (x), (y), (width), (height)))
-#define XAddPixel(ximage, value) \
- ((*((ximage)->f.add_pixel))((ximage), (value)))
-
-/*
- * Compose sequence status structure, used in calling XLookupString.
- */
-typedef struct _XComposeStatus {
- XPointer compose_ptr; /* state table pointer */
- int chars_matched; /* match state */
-} XComposeStatus;
-
-/*
- * Keysym macros, used on Keysyms to test for classes of symbols
- */
-#define IsKeypadKey(keysym) \
- (((KeySym)(keysym) >= XK_KP_Space) && ((KeySym)(keysym) <= XK_KP_Equal))
-
-#define IsPrivateKeypadKey(keysym) \
- (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF))
-
-#define IsCursorKey(keysym) \
- (((KeySym)(keysym) >= XK_Home) && ((KeySym)(keysym) < XK_Select))
-
-#define IsPFKey(keysym) \
- (((KeySym)(keysym) >= XK_KP_F1) && ((KeySym)(keysym) <= XK_KP_F4))
-
-#define IsFunctionKey(keysym) \
- (((KeySym)(keysym) >= XK_F1) && ((KeySym)(keysym) <= XK_F35))
-
-#define IsMiscFunctionKey(keysym) \
- (((KeySym)(keysym) >= XK_Select) && ((KeySym)(keysym) <= XK_Break))
-
-#define IsModifierKey(keysym) \
- ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \
- || (((KeySym)(keysym) >= XK_ISO_Lock) && \
- ((KeySym)(keysym) <= XK_ISO_Last_Group_Lock)) \
- || ((KeySym)(keysym) == XK_Mode_switch) \
- || ((KeySym)(keysym) == XK_Num_Lock))
-/*
- * opaque reference to Region data type
- */
-typedef struct _XRegion *Region;
-
-/* Return values from XRectInRegion() */
-
-#define RectangleOut 0
-#define RectangleIn 1
-#define RectanglePart 2
-
-
-/*
- * Information used by the visual utility routines to find desired visual
- * type from the many visuals a display may support.
- */
-
-typedef struct {
- Visual *visual;
- VisualID visualid;
- int screen;
- int depth;
-#if defined(__cplusplus) || defined(c_plusplus)
- int c_class; /* C++ */
-#else
- int class;
-#endif
- unsigned long red_mask;
- unsigned long green_mask;
- unsigned long blue_mask;
- int colormap_size;
- int bits_per_rgb;
-} XVisualInfo;
-
-#define VisualNoMask 0x0
-#define VisualIDMask 0x1
-#define VisualScreenMask 0x2
-#define VisualDepthMask 0x4
-#define VisualClassMask 0x8
-#define VisualRedMaskMask 0x10
-#define VisualGreenMaskMask 0x20
-#define VisualBlueMaskMask 0x40
-#define VisualColormapSizeMask 0x80
-#define VisualBitsPerRGBMask 0x100
-#define VisualAllMask 0x1FF
-
-/*
- * This defines a window manager property that clients may use to
- * share standard color maps of type RGB_COLOR_MAP:
- */
-typedef struct {
- Colormap colormap;
- unsigned long red_max;
- unsigned long red_mult;
- unsigned long green_max;
- unsigned long green_mult;
- unsigned long blue_max;
- unsigned long blue_mult;
- unsigned long base_pixel;
- VisualID visualid; /* added by ICCCM version 1 */
- XID killid; /* added by ICCCM version 1 */
-} XStandardColormap;
-
-#define ReleaseByFreeingColormap ((XID) 1L) /* for killid field above */
-
-
-/*
- * return codes for XReadBitmapFile and XWriteBitmapFile
- */
-#define BitmapSuccess 0
-#define BitmapOpenFailed 1
-#define BitmapFileInvalid 2
-#define BitmapNoMemory 3
-
-/****************************************************************
- *
- * Context Management
- *
- ****************************************************************/
-
-
-/* Associative lookup table return codes */
-
-#define XCSUCCESS 0 /* No error. */
-#define XCNOMEM 1 /* Out of memory */
-#define XCNOENT 2 /* No entry in table */
-
-typedef int XContext;
-
-#define XUniqueContext() ((XContext) XrmUniqueQuark())
-#define XStringToContext(string) ((XContext) XrmStringToQuark(string))
-
-#if 0
-_XFUNCPROTOBEGIN
-
-/* The following declarations are alphabetized. */
-
-extern XClassHint *XAllocClassHint (
-#if NeedFunctionPrototypes
- void
-#endif
-);
-
-extern XIconSize *XAllocIconSize (
-#if NeedFunctionPrototypes
- void
-#endif
-);
-
-extern XSizeHints *XAllocSizeHints (
-#if NeedFunctionPrototypes
- void
-#endif
-);
-
-extern XStandardColormap *XAllocStandardColormap (
-#if NeedFunctionPrototypes
- void
-#endif
-);
-
-extern XWMHints *XAllocWMHints (
-#if NeedFunctionPrototypes
- void
-#endif
-);
-
-extern int XClipBox(
-#if NeedFunctionPrototypes
- Region /* r */,
- XRectangle* /* rect_return */
-#endif
-);
-
-extern Region XCreateRegion(
-#if NeedFunctionPrototypes
- void
-#endif
-);
-
-extern const char *XDefaultString (void);
-
-extern int XDeleteContext(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XID /* rid */,
- XContext /* context */
-#endif
-);
-
-extern int XDestroyRegion(
-#if NeedFunctionPrototypes
- Region /* r */
-#endif
-);
-
-extern int XEmptyRegion(
-#if NeedFunctionPrototypes
- Region /* r */
-#endif
-);
-
-extern int XEqualRegion(
-#if NeedFunctionPrototypes
- Region /* r1 */,
- Region /* r2 */
-#endif
-);
-
-extern int XFindContext(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XID /* rid */,
- XContext /* context */,
- XPointer* /* data_return */
-#endif
-);
-
-extern Status XGetClassHint(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XClassHint* /* class_hints_return */
-#endif
-);
-
-extern Status XGetIconSizes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XIconSize** /* size_list_return */,
- int* /* count_return */
-#endif
-);
-
-extern Status XGetNormalHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XSizeHints* /* hints_return */
-#endif
-);
-
-extern Status XGetRGBColormaps(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XStandardColormap** /* stdcmap_return */,
- int* /* count_return */,
- Atom /* property */
-#endif
-);
-
-extern Status XGetSizeHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XSizeHints* /* hints_return */,
- Atom /* property */
-#endif
-);
-
-extern Status XGetStandardColormap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XStandardColormap* /* colormap_return */,
- Atom /* property */
-#endif
-);
-
-extern Status XGetTextProperty(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* window */,
- XTextProperty* /* text_prop_return */,
- Atom /* property */
-#endif
-);
-
-extern XVisualInfo *XGetVisualInfo(
-#if NeedFunctionPrototypes
- Display* /* display */,
- long /* vinfo_mask */,
- XVisualInfo* /* vinfo_template */,
- int* /* nitems_return */
-#endif
-);
-
-extern Status XGetWMClientMachine(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XTextProperty* /* text_prop_return */
-#endif
-);
-
-extern XWMHints *XGetWMHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */
-#endif
-);
-
-extern Status XGetWMIconName(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XTextProperty* /* text_prop_return */
-#endif
-);
-
-extern Status XGetWMName(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XTextProperty* /* text_prop_return */
-#endif
-);
-
-extern Status XGetWMNormalHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XSizeHints* /* hints_return */,
- long* /* supplied_return */
-#endif
-);
-
-extern Status XGetWMSizeHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XSizeHints* /* hints_return */,
- long* /* supplied_return */,
- Atom /* property */
-#endif
-);
-
-extern Status XGetZoomHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XSizeHints* /* zhints_return */
-#endif
-);
-
-extern int XIntersectRegion(
-#if NeedFunctionPrototypes
- Region /* sra */,
- Region /* srb */,
- Region /* dr_return */
-#endif
-);
-
-extern void XConvertCase(
-#if NeedFunctionPrototypes
- KeySym /* sym */,
- KeySym* /* lower */,
- KeySym* /* upper */
-#endif
-);
-
-extern int XLookupString(
-#if NeedFunctionPrototypes
- XKeyEvent* /* event_struct */,
- char* /* buffer_return */,
- int /* bytes_buffer */,
- KeySym* /* keysym_return */,
- XComposeStatus* /* status_in_out */
-#endif
-);
-
-extern Status XMatchVisualInfo(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen */,
- int /* depth */,
- int /* class */,
- XVisualInfo* /* vinfo_return */
-#endif
-);
-
-extern int XOffsetRegion(
-#if NeedFunctionPrototypes
- Region /* r */,
- int /* dx */,
- int /* dy */
-#endif
-);
-
-extern Bool XPointInRegion(
-#if NeedFunctionPrototypes
- Region /* r */,
- int /* x */,
- int /* y */
-#endif
-);
-
-extern Region XPolygonRegion(
-#if NeedFunctionPrototypes
- XPoint* /* points */,
- int /* n */,
- int /* fill_rule */
-#endif
-);
-
-extern int XRectInRegion(
-#if NeedFunctionPrototypes
- Region /* r */,
- int /* x */,
- int /* y */,
- unsigned int /* width */,
- unsigned int /* height */
-#endif
-);
-
-extern int XSaveContext(
-#if NeedFunctionPrototypes
- Display* /* display */,
- XID /* rid */,
- XContext /* context */,
- _Xconst char* /* data */
-#endif
-);
-
-extern int XSetClassHint(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XClassHint* /* class_hints */
-#endif
-);
-
-extern int XSetIconSizes(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XIconSize* /* size_list */,
- int /* count */
-#endif
-);
-
-extern int XSetNormalHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XSizeHints* /* hints */
-#endif
-);
-
-extern void XSetRGBColormaps(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XStandardColormap* /* stdcmaps */,
- int /* count */,
- Atom /* property */
-#endif
-);
-
-extern int XSetSizeHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XSizeHints* /* hints */,
- Atom /* property */
-#endif
-);
-
-extern int XSetStandardProperties(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- _Xconst char* /* window_name */,
- _Xconst char* /* icon_name */,
- Pixmap /* icon_pixmap */,
- char** /* argv */,
- int /* argc */,
- XSizeHints* /* hints */
-#endif
-);
-
-extern void XSetTextProperty(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XTextProperty* /* text_prop */,
- Atom /* property */
-#endif
-);
-
-extern void XSetWMClientMachine(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XTextProperty* /* text_prop */
-#endif
-);
-
-extern int XSetWMHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XWMHints* /* wm_hints */
-#endif
-);
-
-extern void XSetWMIconName(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XTextProperty* /* text_prop */
-#endif
-);
-
-extern void XSetWMName(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XTextProperty* /* text_prop */
-#endif
-);
-
-extern void XSetWMNormalHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XSizeHints* /* hints */
-#endif
-);
-
-extern void XSetWMProperties(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XTextProperty* /* window_name */,
- XTextProperty* /* icon_name */,
- char** /* argv */,
- int /* argc */,
- XSizeHints* /* normal_hints */,
- XWMHints* /* wm_hints */,
- XClassHint* /* class_hints */
-#endif
-);
-
-extern void XmbSetWMProperties(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- _Xconst char* /* window_name */,
- _Xconst char* /* icon_name */,
- char** /* argv */,
- int /* argc */,
- XSizeHints* /* normal_hints */,
- XWMHints* /* wm_hints */,
- XClassHint* /* class_hints */
-#endif
-);
-
-extern void Xutf8SetWMProperties(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- _Xconst char* /* window_name */,
- _Xconst char* /* icon_name */,
- char** /* argv */,
- int /* argc */,
- XSizeHints* /* normal_hints */,
- XWMHints* /* wm_hints */,
- XClassHint* /* class_hints */
-#endif
-);
-
-extern void XSetWMSizeHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XSizeHints* /* hints */,
- Atom /* property */
-#endif
-);
-
-extern int XSetRegion(
-#if NeedFunctionPrototypes
- Display* /* display */,
- GC /* gc */,
- Region /* r */
-#endif
-);
-
-extern void XSetStandardColormap(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XStandardColormap* /* colormap */,
- Atom /* property */
-#endif
-);
-
-extern int XSetZoomHints(
-#if NeedFunctionPrototypes
- Display* /* display */,
- Window /* w */,
- XSizeHints* /* zhints */
-#endif
-);
-
-extern int XShrinkRegion(
-#if NeedFunctionPrototypes
- Region /* r */,
- int /* dx */,
- int /* dy */
-#endif
-);
-
-extern Status XStringListToTextProperty(
-#if NeedFunctionPrototypes
- char** /* list */,
- int /* count */,
- XTextProperty* /* text_prop_return */
-#endif
-);
-
-extern int XSubtractRegion(
-#if NeedFunctionPrototypes
- Region /* sra */,
- Region /* srb */,
- Region /* dr_return */
-#endif
-);
-
-extern int XmbTextListToTextProperty(
- Display* display,
- char** list,
- int count,
- XICCEncodingStyle style,
- XTextProperty* text_prop_return
-);
-
-extern int XwcTextListToTextProperty(
- Display* display,
- wchar_t** list,
- int count,
- XICCEncodingStyle style,
- XTextProperty* text_prop_return
-);
-
-extern int Xutf8TextListToTextProperty(
- Display* display,
- char** list,
- int count,
- XICCEncodingStyle style,
- XTextProperty* text_prop_return
-);
-
-extern void XwcFreeStringList(
- wchar_t** list
-);
-
-extern Status XTextPropertyToStringList(
-#if NeedFunctionPrototypes
- XTextProperty* /* text_prop */,
- char*** /* list_return */,
- int* /* count_return */
-#endif
-);
-
-extern int XmbTextPropertyToTextList(
- Display* display,
- const XTextProperty* text_prop,
- char*** list_return,
- int* count_return
-);
-
-extern int XwcTextPropertyToTextList(
- Display* display,
- const XTextProperty* text_prop,
- wchar_t*** list_return,
- int* count_return
-);
-
-extern int Xutf8TextPropertyToTextList(
- Display* display,
- const XTextProperty* text_prop,
- char*** list_return,
- int* count_return
-);
-
-extern int XUnionRectWithRegion(
-#if NeedFunctionPrototypes
- XRectangle* /* rectangle */,
- Region /* src_region */,
- Region /* dest_region_return */
-#endif
-);
-
-extern int XUnionRegion(
-#if NeedFunctionPrototypes
- Region /* sra */,
- Region /* srb */,
- Region /* dr_return */
-#endif
-);
-
-extern int XWMGeometry(
-#if NeedFunctionPrototypes
- Display* /* display */,
- int /* screen_number */,
- _Xconst char* /* user_geometry */,
- _Xconst char* /* default_geometry */,
- unsigned int /* border_width */,
- XSizeHints* /* hints */,
- int* /* x_return */,
- int* /* y_return */,
- int* /* width_return */,
- int* /* height_return */,
- int* /* gravity_return */
-#endif
-);
-
-extern int XXorRegion(
-#if NeedFunctionPrototypes
- Region /* sra */,
- Region /* srb */,
- Region /* dr_return */
-#endif
-);
-
-_XFUNCPROTOEND
-#endif /* if 0 */
-
-#ifndef XATOM_H
-#define XATOM_H 1
-
-/* THIS IS A GENERATED FILE
- *
- * Do not change! Changing this file implies a protocol change!
- */
-
-#define XA_PRIMARY ((Atom) 1)
-#define XA_SECONDARY ((Atom) 2)
-#define XA_ARC ((Atom) 3)
-#define XA_ATOM ((Atom) 4)
-#define XA_BITMAP ((Atom) 5)
-#define XA_CARDINAL ((Atom) 6)
-#define XA_COLORMAP ((Atom) 7)
-#define XA_CURSOR ((Atom) 8)
-#define XA_CUT_BUFFER0 ((Atom) 9)
-#define XA_CUT_BUFFER1 ((Atom) 10)
-#define XA_CUT_BUFFER2 ((Atom) 11)
-#define XA_CUT_BUFFER3 ((Atom) 12)
-#define XA_CUT_BUFFER4 ((Atom) 13)
-#define XA_CUT_BUFFER5 ((Atom) 14)
-#define XA_CUT_BUFFER6 ((Atom) 15)
-#define XA_CUT_BUFFER7 ((Atom) 16)
-#define XA_DRAWABLE ((Atom) 17)
-#define XA_FONT ((Atom) 18)
-#define XA_INTEGER ((Atom) 19)
-#define XA_PIXMAP ((Atom) 20)
-#define XA_POINT ((Atom) 21)
-#define XA_RECTANGLE ((Atom) 22)
-#define XA_RESOURCE_MANAGER ((Atom) 23)
-#define XA_RGB_COLOR_MAP ((Atom) 24)
-#define XA_RGB_BEST_MAP ((Atom) 25)
-#define XA_RGB_BLUE_MAP ((Atom) 26)
-#define XA_RGB_DEFAULT_MAP ((Atom) 27)
-#define XA_RGB_GRAY_MAP ((Atom) 28)
-#define XA_RGB_GREEN_MAP ((Atom) 29)
-#define XA_RGB_RED_MAP ((Atom) 30)
-#define XA_STRING ((Atom) 31)
-#define XA_VISUALID ((Atom) 32)
-#define XA_WINDOW ((Atom) 33)
-#define XA_WM_COMMAND ((Atom) 34)
-#define XA_WM_HINTS ((Atom) 35)
-#define XA_WM_CLIENT_MACHINE ((Atom) 36)
-#define XA_WM_ICON_NAME ((Atom) 37)
-#define XA_WM_ICON_SIZE ((Atom) 38)
-#define XA_WM_NAME ((Atom) 39)
-#define XA_WM_NORMAL_HINTS ((Atom) 40)
-#define XA_WM_SIZE_HINTS ((Atom) 41)
-#define XA_WM_ZOOM_HINTS ((Atom) 42)
-#define XA_MIN_SPACE ((Atom) 43)
-#define XA_NORM_SPACE ((Atom) 44)
-#define XA_MAX_SPACE ((Atom) 45)
-#define XA_END_SPACE ((Atom) 46)
-#define XA_SUPERSCRIPT_X ((Atom) 47)
-#define XA_SUPERSCRIPT_Y ((Atom) 48)
-#define XA_SUBSCRIPT_X ((Atom) 49)
-#define XA_SUBSCRIPT_Y ((Atom) 50)
-#define XA_UNDERLINE_POSITION ((Atom) 51)
-#define XA_UNDERLINE_THICKNESS ((Atom) 52)
-#define XA_STRIKEOUT_ASCENT ((Atom) 53)
-#define XA_STRIKEOUT_DESCENT ((Atom) 54)
-#define XA_ITALIC_ANGLE ((Atom) 55)
-#define XA_X_HEIGHT ((Atom) 56)
-#define XA_QUAD_WIDTH ((Atom) 57)
-#define XA_WEIGHT ((Atom) 58)
-#define XA_POINT_SIZE ((Atom) 59)
-#define XA_RESOLUTION ((Atom) 60)
-#define XA_COPYRIGHT ((Atom) 61)
-#define XA_NOTICE ((Atom) 62)
-#define XA_FONT_NAME ((Atom) 63)
-#define XA_FAMILY_NAME ((Atom) 64)
-#define XA_FULL_NAME ((Atom) 65)
-#define XA_CAP_HEIGHT ((Atom) 66)
-#define XA_WM_CLASS ((Atom) 67)
-#define XA_WM_TRANSIENT_FOR ((Atom) 68)
-
-#define XA_LAST_PREDEFINED ((Atom) 68)
-#endif /* XATOM_H */
-
-#endif /* _XUTIL_H_ */
-
-extern KeyCode XKeysymToKeycode(
- Display* /* display */,
- KeySym /* keysym */
-);
-extern KeySym XKeycodeToKeysym(
- Display* /* display */,
- KeyCode /* keycode */,
- int /* index */
-);
-extern char *XKeysymToString(
- KeySym /* keysym */
-);
-extern KeySym XStringToKeysym(
- char* /* string */
-);
-
-typedef int (*XErrorHandler) ( /* WARNING, this type not in Xlib spec */
- Display* /* display */,
- XErrorEvent* /* error_event */
-);
-
-extern XErrorHandler XSetErrorHandler (
- XErrorHandler /* handler */
-);
-
-typedef int (*XIOErrorHandler) ( /* WARNING, this type not in Xlib spec */
- Display* /* display */
-);
-
-extern XIOErrorHandler XSetIOErrorHandler (
- XIOErrorHandler /* handler */
-);
-
-#define X_ShmQueryVersion 0
-#define X_ShmAttach 1
-#define X_ShmDetach 2
-#define X_ShmPutImage 3
-#define X_ShmGetImage 4
-#define X_ShmCreatePixmap 5
diff --git a/x11vnc/nox11_funcs.h b/x11vnc/nox11_funcs.h
deleted file mode 100644
index 6e3ac57..0000000
--- a/x11vnc/nox11_funcs.h
+++ /dev/null
@@ -1,2822 +0,0 @@
-#if 0
-generated by util script makekeysyms.pl:
-
------
-#!/usr/bin/perl
-
-print "#if 0\n";
-print "generated by util script makekeysyms.pl:\n\n";
-print "-----\n";
-system("cat $0");
-print "-----\n";
-print "#endif\n\n";
-
-# probably should use rfb/keysym.h:
-$file = shift;
-$file = "/usr/X11R6/include/X11/keysymdef.h" unless $file;
-
-open(KS, "<$file") || die "$file: $!";
-
-while (<KS>) {
- chomp;
- next if /^#define (XK_MISCELLANY|XK_XKB_KEYS|XK_LATIN1|XK_LATIN2|XK_LATIN3|XK_LATIN4|XK_GREEK)/;
- next if /^#define (XK_LATIN8|XK_LATIN9|XK_CAUCASUS|XK_KATAKANA|XK_ARABIC|XK_CYRILLIC|XK_HEBREW|XK_THAI|XK_KOREAN|XK_ARMENIAN|XK_GEORGIAN|XK_VIETNAMESE|XK_CURRENCY)/;
- if (/^#define\s+(XK_\w+)/) {
- push @xk, $1;
- } elsif (/^#(ifdef|ifndef|endif)/) {
- $_ =~ s/ifndef XK_0/ifndef XK_0_nosuch/;
- push @xk, $_;
- }
-}
-close(KS);
-
-print <<"END";
-
-KeySym XStringToKeysym(char *s) {
-END
-foreach $ks (@xk) {
- $s = $ks;
- if ($ks =~ /#/) {
- print "$ks\n";
- next;
- }
- $s =~ s/^XK_//;
- print " if (!strcmp(s, \"$s\")) return $ks;\n";
-}
-print <<"END";
- return NoSymbol;
-}
-
-END
-
-print <<"END";
-
-char *XKeysymToString(KeySym k) {
-END
-foreach $ks (@xk) {
- $s = $ks;
- if ($ks =~ /#/) {
- print "$ks\n";
- next;
- }
- $s =~ s/^XK_//;
- print " if (k == $ks) return \"$s\";\n";
-}
-print <<"END";
- return NULL;
-}
-
-KeySym XKeycodeToKeysym(Display *display, KeyCode keycode, int index) {
- return NoSymbol;
-}
-
-KeyCode XKeysymToKeycode(Display *display, KeySym keysym) {
- return NoSymbol;
-}
-
-XErrorHandler XSetErrorHandler (XErrorHandler h) {
- return h;
-}
-
-END
-
-exit 0;
------
-#endif
-
-
-KeySym XStringToKeysym(char *s) {
-#ifndef XK_0_nosuch
- if (!strcmp(s, "VoidSymbol")) return XK_VoidSymbol;
-#ifdef XK_MISCELLANY
- if (!strcmp(s, "BackSpace")) return XK_BackSpace;
- if (!strcmp(s, "Tab")) return XK_Tab;
- if (!strcmp(s, "Linefeed")) return XK_Linefeed;
- if (!strcmp(s, "Clear")) return XK_Clear;
- if (!strcmp(s, "Return")) return XK_Return;
- if (!strcmp(s, "Pause")) return XK_Pause;
- if (!strcmp(s, "Scroll_Lock")) return XK_Scroll_Lock;
- if (!strcmp(s, "Sys_Req")) return XK_Sys_Req;
- if (!strcmp(s, "Escape")) return XK_Escape;
- if (!strcmp(s, "Delete")) return XK_Delete;
- if (!strcmp(s, "Multi_key")) return XK_Multi_key;
- if (!strcmp(s, "SingleCandidate")) return XK_SingleCandidate;
- if (!strcmp(s, "MultipleCandidate")) return XK_MultipleCandidate;
- if (!strcmp(s, "PreviousCandidate")) return XK_PreviousCandidate;
- if (!strcmp(s, "Kanji")) return XK_Kanji;
- if (!strcmp(s, "Muhenkan")) return XK_Muhenkan;
- if (!strcmp(s, "Henkan_Mode")) return XK_Henkan_Mode;
- if (!strcmp(s, "Henkan")) return XK_Henkan;
- if (!strcmp(s, "Romaji")) return XK_Romaji;
- if (!strcmp(s, "Hiragana")) return XK_Hiragana;
- if (!strcmp(s, "Katakana")) return XK_Katakana;
- if (!strcmp(s, "Hiragana_Katakana")) return XK_Hiragana_Katakana;
- if (!strcmp(s, "Zenkaku")) return XK_Zenkaku;
- if (!strcmp(s, "Hankaku")) return XK_Hankaku;
- if (!strcmp(s, "Zenkaku_Hankaku")) return XK_Zenkaku_Hankaku;
- if (!strcmp(s, "Touroku")) return XK_Touroku;
- if (!strcmp(s, "Massyo")) return XK_Massyo;
- if (!strcmp(s, "Kana_Lock")) return XK_Kana_Lock;
- if (!strcmp(s, "Kana_Shift")) return XK_Kana_Shift;
- if (!strcmp(s, "Eisu_Shift")) return XK_Eisu_Shift;
- if (!strcmp(s, "Eisu_toggle")) return XK_Eisu_toggle;
- if (!strcmp(s, "Zen_Koho")) return XK_Zen_Koho;
- if (!strcmp(s, "Mae_Koho")) return XK_Mae_Koho;
- if (!strcmp(s, "Home")) return XK_Home;
- if (!strcmp(s, "Left")) return XK_Left;
- if (!strcmp(s, "Up")) return XK_Up;
- if (!strcmp(s, "Right")) return XK_Right;
- if (!strcmp(s, "Down")) return XK_Down;
- if (!strcmp(s, "Prior")) return XK_Prior;
- if (!strcmp(s, "Page_Up")) return XK_Page_Up;
- if (!strcmp(s, "Next")) return XK_Next;
- if (!strcmp(s, "Page_Down")) return XK_Page_Down;
- if (!strcmp(s, "End")) return XK_End;
- if (!strcmp(s, "Begin")) return XK_Begin;
- if (!strcmp(s, "Select")) return XK_Select;
- if (!strcmp(s, "Print")) return XK_Print;
- if (!strcmp(s, "Execute")) return XK_Execute;
- if (!strcmp(s, "Insert")) return XK_Insert;
- if (!strcmp(s, "Undo")) return XK_Undo;
- if (!strcmp(s, "Redo")) return XK_Redo;
- if (!strcmp(s, "Menu")) return XK_Menu;
- if (!strcmp(s, "Find")) return XK_Find;
- if (!strcmp(s, "Cancel")) return XK_Cancel;
- if (!strcmp(s, "Help")) return XK_Help;
- if (!strcmp(s, "Break")) return XK_Break;
- if (!strcmp(s, "Mode_switch")) return XK_Mode_switch;
- if (!strcmp(s, "script_switch")) return XK_script_switch;
- if (!strcmp(s, "Num_Lock")) return XK_Num_Lock;
- if (!strcmp(s, "KP_Space")) return XK_KP_Space;
- if (!strcmp(s, "KP_Tab")) return XK_KP_Tab;
- if (!strcmp(s, "KP_Enter")) return XK_KP_Enter;
- if (!strcmp(s, "KP_F1")) return XK_KP_F1;
- if (!strcmp(s, "KP_F2")) return XK_KP_F2;
- if (!strcmp(s, "KP_F3")) return XK_KP_F3;
- if (!strcmp(s, "KP_F4")) return XK_KP_F4;
- if (!strcmp(s, "KP_Home")) return XK_KP_Home;
- if (!strcmp(s, "KP_Left")) return XK_KP_Left;
- if (!strcmp(s, "KP_Up")) return XK_KP_Up;
- if (!strcmp(s, "KP_Right")) return XK_KP_Right;
- if (!strcmp(s, "KP_Down")) return XK_KP_Down;
- if (!strcmp(s, "KP_Prior")) return XK_KP_Prior;
- if (!strcmp(s, "KP_Page_Up")) return XK_KP_Page_Up;
- if (!strcmp(s, "KP_Next")) return XK_KP_Next;
- if (!strcmp(s, "KP_Page_Down")) return XK_KP_Page_Down;
- if (!strcmp(s, "KP_End")) return XK_KP_End;
- if (!strcmp(s, "KP_Begin")) return XK_KP_Begin;
- if (!strcmp(s, "KP_Insert")) return XK_KP_Insert;
- if (!strcmp(s, "KP_Delete")) return XK_KP_Delete;
- if (!strcmp(s, "KP_Equal")) return XK_KP_Equal;
- if (!strcmp(s, "KP_Multiply")) return XK_KP_Multiply;
- if (!strcmp(s, "KP_Add")) return XK_KP_Add;
- if (!strcmp(s, "KP_Separator")) return XK_KP_Separator;
- if (!strcmp(s, "KP_Subtract")) return XK_KP_Subtract;
- if (!strcmp(s, "KP_Decimal")) return XK_KP_Decimal;
- if (!strcmp(s, "KP_Divide")) return XK_KP_Divide;
- if (!strcmp(s, "KP_0")) return XK_KP_0;
- if (!strcmp(s, "KP_1")) return XK_KP_1;
- if (!strcmp(s, "KP_2")) return XK_KP_2;
- if (!strcmp(s, "KP_3")) return XK_KP_3;
- if (!strcmp(s, "KP_4")) return XK_KP_4;
- if (!strcmp(s, "KP_5")) return XK_KP_5;
- if (!strcmp(s, "KP_6")) return XK_KP_6;
- if (!strcmp(s, "KP_7")) return XK_KP_7;
- if (!strcmp(s, "KP_8")) return XK_KP_8;
- if (!strcmp(s, "KP_9")) return XK_KP_9;
- if (!strcmp(s, "F1")) return XK_F1;
- if (!strcmp(s, "F2")) return XK_F2;
- if (!strcmp(s, "F3")) return XK_F3;
- if (!strcmp(s, "F4")) return XK_F4;
- if (!strcmp(s, "F5")) return XK_F5;
- if (!strcmp(s, "F6")) return XK_F6;
- if (!strcmp(s, "F7")) return XK_F7;
- if (!strcmp(s, "F8")) return XK_F8;
- if (!strcmp(s, "F9")) return XK_F9;
- if (!strcmp(s, "F10")) return XK_F10;
- if (!strcmp(s, "F11")) return XK_F11;
- if (!strcmp(s, "L1")) return XK_L1;
- if (!strcmp(s, "F12")) return XK_F12;
- if (!strcmp(s, "L2")) return XK_L2;
- if (!strcmp(s, "F13")) return XK_F13;
- if (!strcmp(s, "L3")) return XK_L3;
- if (!strcmp(s, "F14")) return XK_F14;
- if (!strcmp(s, "L4")) return XK_L4;
- if (!strcmp(s, "F15")) return XK_F15;
- if (!strcmp(s, "L5")) return XK_L5;
- if (!strcmp(s, "F16")) return XK_F16;
- if (!strcmp(s, "L6")) return XK_L6;
- if (!strcmp(s, "F17")) return XK_F17;
- if (!strcmp(s, "L7")) return XK_L7;
- if (!strcmp(s, "F18")) return XK_F18;
- if (!strcmp(s, "L8")) return XK_L8;
- if (!strcmp(s, "F19")) return XK_F19;
- if (!strcmp(s, "L9")) return XK_L9;
- if (!strcmp(s, "F20")) return XK_F20;
- if (!strcmp(s, "L10")) return XK_L10;
- if (!strcmp(s, "F21")) return XK_F21;
- if (!strcmp(s, "R1")) return XK_R1;
- if (!strcmp(s, "F22")) return XK_F22;
- if (!strcmp(s, "R2")) return XK_R2;
- if (!strcmp(s, "F23")) return XK_F23;
- if (!strcmp(s, "R3")) return XK_R3;
- if (!strcmp(s, "F24")) return XK_F24;
- if (!strcmp(s, "R4")) return XK_R4;
- if (!strcmp(s, "F25")) return XK_F25;
- if (!strcmp(s, "R5")) return XK_R5;
- if (!strcmp(s, "F26")) return XK_F26;
- if (!strcmp(s, "R6")) return XK_R6;
- if (!strcmp(s, "F27")) return XK_F27;
- if (!strcmp(s, "R7")) return XK_R7;
- if (!strcmp(s, "F28")) return XK_F28;
- if (!strcmp(s, "R8")) return XK_R8;
- if (!strcmp(s, "F29")) return XK_F29;
- if (!strcmp(s, "R9")) return XK_R9;
- if (!strcmp(s, "F30")) return XK_F30;
- if (!strcmp(s, "R10")) return XK_R10;
- if (!strcmp(s, "F31")) return XK_F31;
- if (!strcmp(s, "R11")) return XK_R11;
- if (!strcmp(s, "F32")) return XK_F32;
- if (!strcmp(s, "R12")) return XK_R12;
- if (!strcmp(s, "F33")) return XK_F33;
- if (!strcmp(s, "R13")) return XK_R13;
- if (!strcmp(s, "F34")) return XK_F34;
- if (!strcmp(s, "R14")) return XK_R14;
- if (!strcmp(s, "F35")) return XK_F35;
- if (!strcmp(s, "R15")) return XK_R15;
- if (!strcmp(s, "Shift_L")) return XK_Shift_L;
- if (!strcmp(s, "Shift_R")) return XK_Shift_R;
- if (!strcmp(s, "Control_L")) return XK_Control_L;
- if (!strcmp(s, "Control_R")) return XK_Control_R;
- if (!strcmp(s, "Caps_Lock")) return XK_Caps_Lock;
- if (!strcmp(s, "Shift_Lock")) return XK_Shift_Lock;
- if (!strcmp(s, "Meta_L")) return XK_Meta_L;
- if (!strcmp(s, "Meta_R")) return XK_Meta_R;
- if (!strcmp(s, "Alt_L")) return XK_Alt_L;
- if (!strcmp(s, "Alt_R")) return XK_Alt_R;
- if (!strcmp(s, "Super_L")) return XK_Super_L;
- if (!strcmp(s, "Super_R")) return XK_Super_R;
- if (!strcmp(s, "Hyper_L")) return XK_Hyper_L;
- if (!strcmp(s, "Hyper_R")) return XK_Hyper_R;
-#endif /* XK_MISCELLANY */
-#ifdef XK_XKB_KEYS
- if (!strcmp(s, "ISO_Lock")) return XK_ISO_Lock;
- if (!strcmp(s, "ISO_Level2_Latch")) return XK_ISO_Level2_Latch;
- if (!strcmp(s, "ISO_Level3_Shift")) return XK_ISO_Level3_Shift;
- if (!strcmp(s, "ISO_Level3_Latch")) return XK_ISO_Level3_Latch;
- if (!strcmp(s, "ISO_Level3_Lock")) return XK_ISO_Level3_Lock;
- if (!strcmp(s, "ISO_Group_Shift")) return XK_ISO_Group_Shift;
- if (!strcmp(s, "ISO_Group_Latch")) return XK_ISO_Group_Latch;
- if (!strcmp(s, "ISO_Group_Lock")) return XK_ISO_Group_Lock;
- if (!strcmp(s, "ISO_Next_Group")) return XK_ISO_Next_Group;
- if (!strcmp(s, "ISO_Next_Group_Lock")) return XK_ISO_Next_Group_Lock;
- if (!strcmp(s, "ISO_Prev_Group")) return XK_ISO_Prev_Group;
- if (!strcmp(s, "ISO_Prev_Group_Lock")) return XK_ISO_Prev_Group_Lock;
- if (!strcmp(s, "ISO_First_Group")) return XK_ISO_First_Group;
- if (!strcmp(s, "ISO_First_Group_Lock")) return XK_ISO_First_Group_Lock;
- if (!strcmp(s, "ISO_Last_Group")) return XK_ISO_Last_Group;
- if (!strcmp(s, "ISO_Last_Group_Lock")) return XK_ISO_Last_Group_Lock;
- if (!strcmp(s, "ISO_Left_Tab")) return XK_ISO_Left_Tab;
- if (!strcmp(s, "ISO_Move_Line_Up")) return XK_ISO_Move_Line_Up;
- if (!strcmp(s, "ISO_Move_Line_Down")) return XK_ISO_Move_Line_Down;
- if (!strcmp(s, "ISO_Partial_Line_Up")) return XK_ISO_Partial_Line_Up;
- if (!strcmp(s, "ISO_Partial_Line_Down")) return XK_ISO_Partial_Line_Down;
- if (!strcmp(s, "ISO_Partial_Space_Left")) return XK_ISO_Partial_Space_Left;
- if (!strcmp(s, "ISO_Partial_Space_Right")) return XK_ISO_Partial_Space_Right;
- if (!strcmp(s, "ISO_Set_Margin_Left")) return XK_ISO_Set_Margin_Left;
- if (!strcmp(s, "ISO_Set_Margin_Right")) return XK_ISO_Set_Margin_Right;
- if (!strcmp(s, "ISO_Release_Margin_Left")) return XK_ISO_Release_Margin_Left;
- if (!strcmp(s, "ISO_Release_Margin_Right")) return XK_ISO_Release_Margin_Right;
- if (!strcmp(s, "ISO_Release_Both_Margins")) return XK_ISO_Release_Both_Margins;
- if (!strcmp(s, "ISO_Fast_Cursor_Left")) return XK_ISO_Fast_Cursor_Left;
- if (!strcmp(s, "ISO_Fast_Cursor_Right")) return XK_ISO_Fast_Cursor_Right;
- if (!strcmp(s, "ISO_Fast_Cursor_Up")) return XK_ISO_Fast_Cursor_Up;
- if (!strcmp(s, "ISO_Fast_Cursor_Down")) return XK_ISO_Fast_Cursor_Down;
- if (!strcmp(s, "ISO_Continuous_Underline")) return XK_ISO_Continuous_Underline;
- if (!strcmp(s, "ISO_Discontinuous_Underline")) return XK_ISO_Discontinuous_Underline;
- if (!strcmp(s, "ISO_Emphasize")) return XK_ISO_Emphasize;
- if (!strcmp(s, "ISO_Center_Object")) return XK_ISO_Center_Object;
- if (!strcmp(s, "ISO_Enter")) return XK_ISO_Enter;
- if (!strcmp(s, "dead_grave")) return XK_dead_grave;
- if (!strcmp(s, "dead_acute")) return XK_dead_acute;
- if (!strcmp(s, "dead_circumflex")) return XK_dead_circumflex;
- if (!strcmp(s, "dead_tilde")) return XK_dead_tilde;
- if (!strcmp(s, "dead_macron")) return XK_dead_macron;
- if (!strcmp(s, "dead_breve")) return XK_dead_breve;
- if (!strcmp(s, "dead_abovedot")) return XK_dead_abovedot;
- if (!strcmp(s, "dead_diaeresis")) return XK_dead_diaeresis;
- if (!strcmp(s, "dead_abovering")) return XK_dead_abovering;
- if (!strcmp(s, "dead_doubleacute")) return XK_dead_doubleacute;
- if (!strcmp(s, "dead_caron")) return XK_dead_caron;
- if (!strcmp(s, "dead_cedilla")) return XK_dead_cedilla;
- if (!strcmp(s, "dead_ogonek")) return XK_dead_ogonek;
- if (!strcmp(s, "dead_iota")) return XK_dead_iota;
- if (!strcmp(s, "dead_voiced_sound")) return XK_dead_voiced_sound;
- if (!strcmp(s, "dead_semivoiced_sound")) return XK_dead_semivoiced_sound;
- if (!strcmp(s, "dead_belowdot")) return XK_dead_belowdot;
- if (!strcmp(s, "First_Virtual_Screen")) return XK_First_Virtual_Screen;
- if (!strcmp(s, "Prev_Virtual_Screen")) return XK_Prev_Virtual_Screen;
- if (!strcmp(s, "Next_Virtual_Screen")) return XK_Next_Virtual_Screen;
- if (!strcmp(s, "Last_Virtual_Screen")) return XK_Last_Virtual_Screen;
- if (!strcmp(s, "Terminate_Server")) return XK_Terminate_Server;
- if (!strcmp(s, "AccessX_Enable")) return XK_AccessX_Enable;
- if (!strcmp(s, "AccessX_Feedback_Enable")) return XK_AccessX_Feedback_Enable;
- if (!strcmp(s, "RepeatKeys_Enable")) return XK_RepeatKeys_Enable;
- if (!strcmp(s, "SlowKeys_Enable")) return XK_SlowKeys_Enable;
- if (!strcmp(s, "BounceKeys_Enable")) return XK_BounceKeys_Enable;
- if (!strcmp(s, "StickyKeys_Enable")) return XK_StickyKeys_Enable;
- if (!strcmp(s, "MouseKeys_Enable")) return XK_MouseKeys_Enable;
- if (!strcmp(s, "MouseKeys_Accel_Enable")) return XK_MouseKeys_Accel_Enable;
- if (!strcmp(s, "Overlay1_Enable")) return XK_Overlay1_Enable;
- if (!strcmp(s, "Overlay2_Enable")) return XK_Overlay2_Enable;
- if (!strcmp(s, "AudibleBell_Enable")) return XK_AudibleBell_Enable;
- if (!strcmp(s, "Pointer_Left")) return XK_Pointer_Left;
- if (!strcmp(s, "Pointer_Right")) return XK_Pointer_Right;
- if (!strcmp(s, "Pointer_Up")) return XK_Pointer_Up;
- if (!strcmp(s, "Pointer_Down")) return XK_Pointer_Down;
- if (!strcmp(s, "Pointer_UpLeft")) return XK_Pointer_UpLeft;
- if (!strcmp(s, "Pointer_UpRight")) return XK_Pointer_UpRight;
- if (!strcmp(s, "Pointer_DownLeft")) return XK_Pointer_DownLeft;
- if (!strcmp(s, "Pointer_DownRight")) return XK_Pointer_DownRight;
- if (!strcmp(s, "Pointer_Button_Dflt")) return XK_Pointer_Button_Dflt;
- if (!strcmp(s, "Pointer_Button1")) return XK_Pointer_Button1;
- if (!strcmp(s, "Pointer_Button2")) return XK_Pointer_Button2;
- if (!strcmp(s, "Pointer_Button3")) return XK_Pointer_Button3;
- if (!strcmp(s, "Pointer_Button4")) return XK_Pointer_Button4;
- if (!strcmp(s, "Pointer_Button5")) return XK_Pointer_Button5;
- if (!strcmp(s, "Pointer_DblClick_Dflt")) return XK_Pointer_DblClick_Dflt;
- if (!strcmp(s, "Pointer_DblClick1")) return XK_Pointer_DblClick1;
- if (!strcmp(s, "Pointer_DblClick2")) return XK_Pointer_DblClick2;
- if (!strcmp(s, "Pointer_DblClick3")) return XK_Pointer_DblClick3;
- if (!strcmp(s, "Pointer_DblClick4")) return XK_Pointer_DblClick4;
- if (!strcmp(s, "Pointer_DblClick5")) return XK_Pointer_DblClick5;
- if (!strcmp(s, "Pointer_Drag_Dflt")) return XK_Pointer_Drag_Dflt;
- if (!strcmp(s, "Pointer_Drag1")) return XK_Pointer_Drag1;
- if (!strcmp(s, "Pointer_Drag2")) return XK_Pointer_Drag2;
- if (!strcmp(s, "Pointer_Drag3")) return XK_Pointer_Drag3;
- if (!strcmp(s, "Pointer_Drag4")) return XK_Pointer_Drag4;
- if (!strcmp(s, "Pointer_Drag5")) return XK_Pointer_Drag5;
- if (!strcmp(s, "Pointer_EnableKeys")) return XK_Pointer_EnableKeys;
- if (!strcmp(s, "Pointer_Accelerate")) return XK_Pointer_Accelerate;
- if (!strcmp(s, "Pointer_DfltBtnNext")) return XK_Pointer_DfltBtnNext;
- if (!strcmp(s, "Pointer_DfltBtnPrev")) return XK_Pointer_DfltBtnPrev;
-#endif
-#ifdef XK_3270
- if (!strcmp(s, "3270_Duplicate")) return XK_3270_Duplicate;
- if (!strcmp(s, "3270_FieldMark")) return XK_3270_FieldMark;
- if (!strcmp(s, "3270_Right2")) return XK_3270_Right2;
- if (!strcmp(s, "3270_Left2")) return XK_3270_Left2;
- if (!strcmp(s, "3270_BackTab")) return XK_3270_BackTab;
- if (!strcmp(s, "3270_EraseEOF")) return XK_3270_EraseEOF;
- if (!strcmp(s, "3270_EraseInput")) return XK_3270_EraseInput;
- if (!strcmp(s, "3270_Reset")) return XK_3270_Reset;
- if (!strcmp(s, "3270_Quit")) return XK_3270_Quit;
- if (!strcmp(s, "3270_PA1")) return XK_3270_PA1;
- if (!strcmp(s, "3270_PA2")) return XK_3270_PA2;
- if (!strcmp(s, "3270_PA3")) return XK_3270_PA3;
- if (!strcmp(s, "3270_Test")) return XK_3270_Test;
- if (!strcmp(s, "3270_Attn")) return XK_3270_Attn;
- if (!strcmp(s, "3270_CursorBlink")) return XK_3270_CursorBlink;
- if (!strcmp(s, "3270_AltCursor")) return XK_3270_AltCursor;
- if (!strcmp(s, "3270_KeyClick")) return XK_3270_KeyClick;
- if (!strcmp(s, "3270_Jump")) return XK_3270_Jump;
- if (!strcmp(s, "3270_Ident")) return XK_3270_Ident;
- if (!strcmp(s, "3270_Rule")) return XK_3270_Rule;
- if (!strcmp(s, "3270_Copy")) return XK_3270_Copy;
- if (!strcmp(s, "3270_Play")) return XK_3270_Play;
- if (!strcmp(s, "3270_Setup")) return XK_3270_Setup;
- if (!strcmp(s, "3270_Record")) return XK_3270_Record;
- if (!strcmp(s, "3270_ChangeScreen")) return XK_3270_ChangeScreen;
- if (!strcmp(s, "3270_DeleteWord")) return XK_3270_DeleteWord;
- if (!strcmp(s, "3270_ExSelect")) return XK_3270_ExSelect;
- if (!strcmp(s, "3270_CursorSelect")) return XK_3270_CursorSelect;
- if (!strcmp(s, "3270_PrintScreen")) return XK_3270_PrintScreen;
- if (!strcmp(s, "3270_Enter")) return XK_3270_Enter;
-#endif
-#ifdef XK_LATIN1
- if (!strcmp(s, "space")) return XK_space;
- if (!strcmp(s, "exclam")) return XK_exclam;
- if (!strcmp(s, "quotedbl")) return XK_quotedbl;
- if (!strcmp(s, "numbersign")) return XK_numbersign;
- if (!strcmp(s, "dollar")) return XK_dollar;
- if (!strcmp(s, "percent")) return XK_percent;
- if (!strcmp(s, "ampersand")) return XK_ampersand;
- if (!strcmp(s, "apostrophe")) return XK_apostrophe;
- if (!strcmp(s, "quoteright")) return XK_quoteright;
- if (!strcmp(s, "parenleft")) return XK_parenleft;
- if (!strcmp(s, "parenright")) return XK_parenright;
- if (!strcmp(s, "asterisk")) return XK_asterisk;
- if (!strcmp(s, "plus")) return XK_plus;
- if (!strcmp(s, "comma")) return XK_comma;
- if (!strcmp(s, "minus")) return XK_minus;
- if (!strcmp(s, "period")) return XK_period;
- if (!strcmp(s, "slash")) return XK_slash;
- if (!strcmp(s, "0")) return XK_0;
- if (!strcmp(s, "1")) return XK_1;
- if (!strcmp(s, "2")) return XK_2;
- if (!strcmp(s, "3")) return XK_3;
- if (!strcmp(s, "4")) return XK_4;
- if (!strcmp(s, "5")) return XK_5;
- if (!strcmp(s, "6")) return XK_6;
- if (!strcmp(s, "7")) return XK_7;
- if (!strcmp(s, "8")) return XK_8;
- if (!strcmp(s, "9")) return XK_9;
- if (!strcmp(s, "colon")) return XK_colon;
- if (!strcmp(s, "semicolon")) return XK_semicolon;
- if (!strcmp(s, "less")) return XK_less;
- if (!strcmp(s, "equal")) return XK_equal;
- if (!strcmp(s, "greater")) return XK_greater;
- if (!strcmp(s, "question")) return XK_question;
- if (!strcmp(s, "at")) return XK_at;
- if (!strcmp(s, "A")) return XK_A;
- if (!strcmp(s, "B")) return XK_B;
- if (!strcmp(s, "C")) return XK_C;
- if (!strcmp(s, "D")) return XK_D;
- if (!strcmp(s, "E")) return XK_E;
- if (!strcmp(s, "F")) return XK_F;
- if (!strcmp(s, "G")) return XK_G;
- if (!strcmp(s, "H")) return XK_H;
- if (!strcmp(s, "I")) return XK_I;
- if (!strcmp(s, "J")) return XK_J;
- if (!strcmp(s, "K")) return XK_K;
- if (!strcmp(s, "L")) return XK_L;
- if (!strcmp(s, "M")) return XK_M;
- if (!strcmp(s, "N")) return XK_N;
- if (!strcmp(s, "O")) return XK_O;
- if (!strcmp(s, "P")) return XK_P;
- if (!strcmp(s, "Q")) return XK_Q;
- if (!strcmp(s, "R")) return XK_R;
- if (!strcmp(s, "S")) return XK_S;
- if (!strcmp(s, "T")) return XK_T;
- if (!strcmp(s, "U")) return XK_U;
- if (!strcmp(s, "V")) return XK_V;
- if (!strcmp(s, "W")) return XK_W;
- if (!strcmp(s, "X")) return XK_X;
- if (!strcmp(s, "Y")) return XK_Y;
- if (!strcmp(s, "Z")) return XK_Z;
- if (!strcmp(s, "bracketleft")) return XK_bracketleft;
- if (!strcmp(s, "backslash")) return XK_backslash;
- if (!strcmp(s, "bracketright")) return XK_bracketright;
- if (!strcmp(s, "asciicircum")) return XK_asciicircum;
- if (!strcmp(s, "underscore")) return XK_underscore;
- if (!strcmp(s, "grave")) return XK_grave;
- if (!strcmp(s, "quoteleft")) return XK_quoteleft;
- if (!strcmp(s, "a")) return XK_a;
- if (!strcmp(s, "b")) return XK_b;
- if (!strcmp(s, "c")) return XK_c;
- if (!strcmp(s, "d")) return XK_d;
- if (!strcmp(s, "e")) return XK_e;
- if (!strcmp(s, "f")) return XK_f;
- if (!strcmp(s, "g")) return XK_g;
- if (!strcmp(s, "h")) return XK_h;
- if (!strcmp(s, "i")) return XK_i;
- if (!strcmp(s, "j")) return XK_j;
- if (!strcmp(s, "k")) return XK_k;
- if (!strcmp(s, "l")) return XK_l;
- if (!strcmp(s, "m")) return XK_m;
- if (!strcmp(s, "n")) return XK_n;
- if (!strcmp(s, "o")) return XK_o;
- if (!strcmp(s, "p")) return XK_p;
- if (!strcmp(s, "q")) return XK_q;
- if (!strcmp(s, "r")) return XK_r;
- if (!strcmp(s, "s")) return XK_s;
- if (!strcmp(s, "t")) return XK_t;
- if (!strcmp(s, "u")) return XK_u;
- if (!strcmp(s, "v")) return XK_v;
- if (!strcmp(s, "w")) return XK_w;
- if (!strcmp(s, "x")) return XK_x;
- if (!strcmp(s, "y")) return XK_y;
- if (!strcmp(s, "z")) return XK_z;
- if (!strcmp(s, "braceleft")) return XK_braceleft;
- if (!strcmp(s, "bar")) return XK_bar;
- if (!strcmp(s, "braceright")) return XK_braceright;
- if (!strcmp(s, "asciitilde")) return XK_asciitilde;
- if (!strcmp(s, "nobreakspace")) return XK_nobreakspace;
- if (!strcmp(s, "exclamdown")) return XK_exclamdown;
- if (!strcmp(s, "cent")) return XK_cent;
- if (!strcmp(s, "sterling")) return XK_sterling;
- if (!strcmp(s, "currency")) return XK_currency;
- if (!strcmp(s, "yen")) return XK_yen;
- if (!strcmp(s, "brokenbar")) return XK_brokenbar;
- if (!strcmp(s, "section")) return XK_section;
- if (!strcmp(s, "diaeresis")) return XK_diaeresis;
- if (!strcmp(s, "copyright")) return XK_copyright;
- if (!strcmp(s, "ordfeminine")) return XK_ordfeminine;
- if (!strcmp(s, "guillemotleft")) return XK_guillemotleft;
- if (!strcmp(s, "notsign")) return XK_notsign;
- if (!strcmp(s, "hyphen")) return XK_hyphen;
- if (!strcmp(s, "registered")) return XK_registered;
- if (!strcmp(s, "macron")) return XK_macron;
- if (!strcmp(s, "degree")) return XK_degree;
- if (!strcmp(s, "plusminus")) return XK_plusminus;
- if (!strcmp(s, "twosuperior")) return XK_twosuperior;
- if (!strcmp(s, "threesuperior")) return XK_threesuperior;
- if (!strcmp(s, "acute")) return XK_acute;
- if (!strcmp(s, "mu")) return XK_mu;
- if (!strcmp(s, "paragraph")) return XK_paragraph;
- if (!strcmp(s, "periodcentered")) return XK_periodcentered;
- if (!strcmp(s, "cedilla")) return XK_cedilla;
- if (!strcmp(s, "onesuperior")) return XK_onesuperior;
- if (!strcmp(s, "masculine")) return XK_masculine;
- if (!strcmp(s, "guillemotright")) return XK_guillemotright;
- if (!strcmp(s, "onequarter")) return XK_onequarter;
- if (!strcmp(s, "onehalf")) return XK_onehalf;
- if (!strcmp(s, "threequarters")) return XK_threequarters;
- if (!strcmp(s, "questiondown")) return XK_questiondown;
- if (!strcmp(s, "Agrave")) return XK_Agrave;
- if (!strcmp(s, "Aacute")) return XK_Aacute;
- if (!strcmp(s, "Acircumflex")) return XK_Acircumflex;
- if (!strcmp(s, "Atilde")) return XK_Atilde;
- if (!strcmp(s, "Adiaeresis")) return XK_Adiaeresis;
- if (!strcmp(s, "Aring")) return XK_Aring;
- if (!strcmp(s, "AE")) return XK_AE;
- if (!strcmp(s, "Ccedilla")) return XK_Ccedilla;
- if (!strcmp(s, "Egrave")) return XK_Egrave;
- if (!strcmp(s, "Eacute")) return XK_Eacute;
- if (!strcmp(s, "Ecircumflex")) return XK_Ecircumflex;
- if (!strcmp(s, "Ediaeresis")) return XK_Ediaeresis;
- if (!strcmp(s, "Igrave")) return XK_Igrave;
- if (!strcmp(s, "Iacute")) return XK_Iacute;
- if (!strcmp(s, "Icircumflex")) return XK_Icircumflex;
- if (!strcmp(s, "Idiaeresis")) return XK_Idiaeresis;
- if (!strcmp(s, "ETH")) return XK_ETH;
- if (!strcmp(s, "Eth")) return XK_Eth;
- if (!strcmp(s, "Ntilde")) return XK_Ntilde;
- if (!strcmp(s, "Ograve")) return XK_Ograve;
- if (!strcmp(s, "Oacute")) return XK_Oacute;
- if (!strcmp(s, "Ocircumflex")) return XK_Ocircumflex;
- if (!strcmp(s, "Otilde")) return XK_Otilde;
- if (!strcmp(s, "Odiaeresis")) return XK_Odiaeresis;
- if (!strcmp(s, "multiply")) return XK_multiply;
- if (!strcmp(s, "Ooblique")) return XK_Ooblique;
- if (!strcmp(s, "Ugrave")) return XK_Ugrave;
- if (!strcmp(s, "Uacute")) return XK_Uacute;
- if (!strcmp(s, "Ucircumflex")) return XK_Ucircumflex;
- if (!strcmp(s, "Udiaeresis")) return XK_Udiaeresis;
- if (!strcmp(s, "Yacute")) return XK_Yacute;
- if (!strcmp(s, "THORN")) return XK_THORN;
- if (!strcmp(s, "Thorn")) return XK_Thorn;
- if (!strcmp(s, "ssharp")) return XK_ssharp;
- if (!strcmp(s, "agrave")) return XK_agrave;
- if (!strcmp(s, "aacute")) return XK_aacute;
- if (!strcmp(s, "acircumflex")) return XK_acircumflex;
- if (!strcmp(s, "atilde")) return XK_atilde;
- if (!strcmp(s, "adiaeresis")) return XK_adiaeresis;
- if (!strcmp(s, "aring")) return XK_aring;
- if (!strcmp(s, "ae")) return XK_ae;
- if (!strcmp(s, "ccedilla")) return XK_ccedilla;
- if (!strcmp(s, "egrave")) return XK_egrave;
- if (!strcmp(s, "eacute")) return XK_eacute;
- if (!strcmp(s, "ecircumflex")) return XK_ecircumflex;
- if (!strcmp(s, "ediaeresis")) return XK_ediaeresis;
- if (!strcmp(s, "igrave")) return XK_igrave;
- if (!strcmp(s, "iacute")) return XK_iacute;
- if (!strcmp(s, "icircumflex")) return XK_icircumflex;
- if (!strcmp(s, "idiaeresis")) return XK_idiaeresis;
- if (!strcmp(s, "eth")) return XK_eth;
- if (!strcmp(s, "ntilde")) return XK_ntilde;
- if (!strcmp(s, "ograve")) return XK_ograve;
- if (!strcmp(s, "oacute")) return XK_oacute;
- if (!strcmp(s, "ocircumflex")) return XK_ocircumflex;
- if (!strcmp(s, "otilde")) return XK_otilde;
- if (!strcmp(s, "odiaeresis")) return XK_odiaeresis;
- if (!strcmp(s, "division")) return XK_division;
- if (!strcmp(s, "oslash")) return XK_oslash;
- if (!strcmp(s, "ugrave")) return XK_ugrave;
- if (!strcmp(s, "uacute")) return XK_uacute;
- if (!strcmp(s, "ucircumflex")) return XK_ucircumflex;
- if (!strcmp(s, "udiaeresis")) return XK_udiaeresis;
- if (!strcmp(s, "yacute")) return XK_yacute;
- if (!strcmp(s, "thorn")) return XK_thorn;
- if (!strcmp(s, "ydiaeresis")) return XK_ydiaeresis;
-#endif /* XK_LATIN1 */
-#ifdef XK_LATIN2
- if (!strcmp(s, "Aogonek")) return XK_Aogonek;
- if (!strcmp(s, "breve")) return XK_breve;
- if (!strcmp(s, "Lstroke")) return XK_Lstroke;
- if (!strcmp(s, "Lcaron")) return XK_Lcaron;
- if (!strcmp(s, "Sacute")) return XK_Sacute;
- if (!strcmp(s, "Scaron")) return XK_Scaron;
- if (!strcmp(s, "Scedilla")) return XK_Scedilla;
- if (!strcmp(s, "Tcaron")) return XK_Tcaron;
- if (!strcmp(s, "Zacute")) return XK_Zacute;
- if (!strcmp(s, "Zcaron")) return XK_Zcaron;
- if (!strcmp(s, "Zabovedot")) return XK_Zabovedot;
- if (!strcmp(s, "aogonek")) return XK_aogonek;
- if (!strcmp(s, "ogonek")) return XK_ogonek;
- if (!strcmp(s, "lstroke")) return XK_lstroke;
- if (!strcmp(s, "lcaron")) return XK_lcaron;
- if (!strcmp(s, "sacute")) return XK_sacute;
- if (!strcmp(s, "caron")) return XK_caron;
- if (!strcmp(s, "scaron")) return XK_scaron;
- if (!strcmp(s, "scedilla")) return XK_scedilla;
- if (!strcmp(s, "tcaron")) return XK_tcaron;
- if (!strcmp(s, "zacute")) return XK_zacute;
- if (!strcmp(s, "doubleacute")) return XK_doubleacute;
- if (!strcmp(s, "zcaron")) return XK_zcaron;
- if (!strcmp(s, "zabovedot")) return XK_zabovedot;
- if (!strcmp(s, "Racute")) return XK_Racute;
- if (!strcmp(s, "Abreve")) return XK_Abreve;
- if (!strcmp(s, "Lacute")) return XK_Lacute;
- if (!strcmp(s, "Cacute")) return XK_Cacute;
- if (!strcmp(s, "Ccaron")) return XK_Ccaron;
- if (!strcmp(s, "Eogonek")) return XK_Eogonek;
- if (!strcmp(s, "Ecaron")) return XK_Ecaron;
- if (!strcmp(s, "Dcaron")) return XK_Dcaron;
- if (!strcmp(s, "Dstroke")) return XK_Dstroke;
- if (!strcmp(s, "Nacute")) return XK_Nacute;
- if (!strcmp(s, "Ncaron")) return XK_Ncaron;
- if (!strcmp(s, "Odoubleacute")) return XK_Odoubleacute;
- if (!strcmp(s, "Rcaron")) return XK_Rcaron;
- if (!strcmp(s, "Uring")) return XK_Uring;
- if (!strcmp(s, "Udoubleacute")) return XK_Udoubleacute;
- if (!strcmp(s, "Tcedilla")) return XK_Tcedilla;
- if (!strcmp(s, "racute")) return XK_racute;
- if (!strcmp(s, "abreve")) return XK_abreve;
- if (!strcmp(s, "lacute")) return XK_lacute;
- if (!strcmp(s, "cacute")) return XK_cacute;
- if (!strcmp(s, "ccaron")) return XK_ccaron;
- if (!strcmp(s, "eogonek")) return XK_eogonek;
- if (!strcmp(s, "ecaron")) return XK_ecaron;
- if (!strcmp(s, "dcaron")) return XK_dcaron;
- if (!strcmp(s, "dstroke")) return XK_dstroke;
- if (!strcmp(s, "nacute")) return XK_nacute;
- if (!strcmp(s, "ncaron")) return XK_ncaron;
- if (!strcmp(s, "odoubleacute")) return XK_odoubleacute;
- if (!strcmp(s, "udoubleacute")) return XK_udoubleacute;
- if (!strcmp(s, "rcaron")) return XK_rcaron;
- if (!strcmp(s, "uring")) return XK_uring;
- if (!strcmp(s, "tcedilla")) return XK_tcedilla;
- if (!strcmp(s, "abovedot")) return XK_abovedot;
-#endif /* XK_LATIN2 */
-#ifdef XK_LATIN3
- if (!strcmp(s, "Hstroke")) return XK_Hstroke;
- if (!strcmp(s, "Hcircumflex")) return XK_Hcircumflex;
- if (!strcmp(s, "Iabovedot")) return XK_Iabovedot;
- if (!strcmp(s, "Gbreve")) return XK_Gbreve;
- if (!strcmp(s, "Jcircumflex")) return XK_Jcircumflex;
- if (!strcmp(s, "hstroke")) return XK_hstroke;
- if (!strcmp(s, "hcircumflex")) return XK_hcircumflex;
- if (!strcmp(s, "idotless")) return XK_idotless;
- if (!strcmp(s, "gbreve")) return XK_gbreve;
- if (!strcmp(s, "jcircumflex")) return XK_jcircumflex;
- if (!strcmp(s, "Cabovedot")) return XK_Cabovedot;
- if (!strcmp(s, "Ccircumflex")) return XK_Ccircumflex;
- if (!strcmp(s, "Gabovedot")) return XK_Gabovedot;
- if (!strcmp(s, "Gcircumflex")) return XK_Gcircumflex;
- if (!strcmp(s, "Ubreve")) return XK_Ubreve;
- if (!strcmp(s, "Scircumflex")) return XK_Scircumflex;
- if (!strcmp(s, "cabovedot")) return XK_cabovedot;
- if (!strcmp(s, "ccircumflex")) return XK_ccircumflex;
- if (!strcmp(s, "gabovedot")) return XK_gabovedot;
- if (!strcmp(s, "gcircumflex")) return XK_gcircumflex;
- if (!strcmp(s, "ubreve")) return XK_ubreve;
- if (!strcmp(s, "scircumflex")) return XK_scircumflex;
-#endif /* XK_LATIN3 */
-#ifdef XK_LATIN4
- if (!strcmp(s, "kra")) return XK_kra;
- if (!strcmp(s, "kappa")) return XK_kappa;
- if (!strcmp(s, "Rcedilla")) return XK_Rcedilla;
- if (!strcmp(s, "Itilde")) return XK_Itilde;
- if (!strcmp(s, "Lcedilla")) return XK_Lcedilla;
- if (!strcmp(s, "Emacron")) return XK_Emacron;
- if (!strcmp(s, "Gcedilla")) return XK_Gcedilla;
- if (!strcmp(s, "Tslash")) return XK_Tslash;
- if (!strcmp(s, "rcedilla")) return XK_rcedilla;
- if (!strcmp(s, "itilde")) return XK_itilde;
- if (!strcmp(s, "lcedilla")) return XK_lcedilla;
- if (!strcmp(s, "emacron")) return XK_emacron;
- if (!strcmp(s, "gcedilla")) return XK_gcedilla;
- if (!strcmp(s, "tslash")) return XK_tslash;
- if (!strcmp(s, "ENG")) return XK_ENG;
- if (!strcmp(s, "eng")) return XK_eng;
- if (!strcmp(s, "Amacron")) return XK_Amacron;
- if (!strcmp(s, "Iogonek")) return XK_Iogonek;
- if (!strcmp(s, "Eabovedot")) return XK_Eabovedot;
- if (!strcmp(s, "Imacron")) return XK_Imacron;
- if (!strcmp(s, "Ncedilla")) return XK_Ncedilla;
- if (!strcmp(s, "Omacron")) return XK_Omacron;
- if (!strcmp(s, "Kcedilla")) return XK_Kcedilla;
- if (!strcmp(s, "Uogonek")) return XK_Uogonek;
- if (!strcmp(s, "Utilde")) return XK_Utilde;
- if (!strcmp(s, "Umacron")) return XK_Umacron;
- if (!strcmp(s, "amacron")) return XK_amacron;
- if (!strcmp(s, "iogonek")) return XK_iogonek;
- if (!strcmp(s, "eabovedot")) return XK_eabovedot;
- if (!strcmp(s, "imacron")) return XK_imacron;
- if (!strcmp(s, "ncedilla")) return XK_ncedilla;
- if (!strcmp(s, "omacron")) return XK_omacron;
- if (!strcmp(s, "kcedilla")) return XK_kcedilla;
- if (!strcmp(s, "uogonek")) return XK_uogonek;
- if (!strcmp(s, "utilde")) return XK_utilde;
- if (!strcmp(s, "umacron")) return XK_umacron;
-#endif /* XK_LATIN4 */
-#ifdef XK_KATAKANA
- if (!strcmp(s, "overline")) return XK_overline;
- if (!strcmp(s, "kana_fullstop")) return XK_kana_fullstop;
- if (!strcmp(s, "kana_openingbracket")) return XK_kana_openingbracket;
- if (!strcmp(s, "kana_closingbracket")) return XK_kana_closingbracket;
- if (!strcmp(s, "kana_comma")) return XK_kana_comma;
- if (!strcmp(s, "kana_conjunctive")) return XK_kana_conjunctive;
- if (!strcmp(s, "kana_middledot")) return XK_kana_middledot;
- if (!strcmp(s, "kana_WO")) return XK_kana_WO;
- if (!strcmp(s, "kana_a")) return XK_kana_a;
- if (!strcmp(s, "kana_i")) return XK_kana_i;
- if (!strcmp(s, "kana_u")) return XK_kana_u;
- if (!strcmp(s, "kana_e")) return XK_kana_e;
- if (!strcmp(s, "kana_o")) return XK_kana_o;
- if (!strcmp(s, "kana_ya")) return XK_kana_ya;
- if (!strcmp(s, "kana_yu")) return XK_kana_yu;
- if (!strcmp(s, "kana_yo")) return XK_kana_yo;
- if (!strcmp(s, "kana_tsu")) return XK_kana_tsu;
- if (!strcmp(s, "kana_tu")) return XK_kana_tu;
- if (!strcmp(s, "prolongedsound")) return XK_prolongedsound;
- if (!strcmp(s, "kana_A")) return XK_kana_A;
- if (!strcmp(s, "kana_I")) return XK_kana_I;
- if (!strcmp(s, "kana_U")) return XK_kana_U;
- if (!strcmp(s, "kana_E")) return XK_kana_E;
- if (!strcmp(s, "kana_O")) return XK_kana_O;
- if (!strcmp(s, "kana_KA")) return XK_kana_KA;
- if (!strcmp(s, "kana_KI")) return XK_kana_KI;
- if (!strcmp(s, "kana_KU")) return XK_kana_KU;
- if (!strcmp(s, "kana_KE")) return XK_kana_KE;
- if (!strcmp(s, "kana_KO")) return XK_kana_KO;
- if (!strcmp(s, "kana_SA")) return XK_kana_SA;
- if (!strcmp(s, "kana_SHI")) return XK_kana_SHI;
- if (!strcmp(s, "kana_SU")) return XK_kana_SU;
- if (!strcmp(s, "kana_SE")) return XK_kana_SE;
- if (!strcmp(s, "kana_SO")) return XK_kana_SO;
- if (!strcmp(s, "kana_TA")) return XK_kana_TA;
- if (!strcmp(s, "kana_CHI")) return XK_kana_CHI;
- if (!strcmp(s, "kana_TI")) return XK_kana_TI;
- if (!strcmp(s, "kana_TSU")) return XK_kana_TSU;
- if (!strcmp(s, "kana_TU")) return XK_kana_TU;
- if (!strcmp(s, "kana_TE")) return XK_kana_TE;
- if (!strcmp(s, "kana_TO")) return XK_kana_TO;
- if (!strcmp(s, "kana_NA")) return XK_kana_NA;
- if (!strcmp(s, "kana_NI")) return XK_kana_NI;
- if (!strcmp(s, "kana_NU")) return XK_kana_NU;
- if (!strcmp(s, "kana_NE")) return XK_kana_NE;
- if (!strcmp(s, "kana_NO")) return XK_kana_NO;
- if (!strcmp(s, "kana_HA")) return XK_kana_HA;
- if (!strcmp(s, "kana_HI")) return XK_kana_HI;
- if (!strcmp(s, "kana_FU")) return XK_kana_FU;
- if (!strcmp(s, "kana_HU")) return XK_kana_HU;
- if (!strcmp(s, "kana_HE")) return XK_kana_HE;
- if (!strcmp(s, "kana_HO")) return XK_kana_HO;
- if (!strcmp(s, "kana_MA")) return XK_kana_MA;
- if (!strcmp(s, "kana_MI")) return XK_kana_MI;
- if (!strcmp(s, "kana_MU")) return XK_kana_MU;
- if (!strcmp(s, "kana_ME")) return XK_kana_ME;
- if (!strcmp(s, "kana_MO")) return XK_kana_MO;
- if (!strcmp(s, "kana_YA")) return XK_kana_YA;
- if (!strcmp(s, "kana_YU")) return XK_kana_YU;
- if (!strcmp(s, "kana_YO")) return XK_kana_YO;
- if (!strcmp(s, "kana_RA")) return XK_kana_RA;
- if (!strcmp(s, "kana_RI")) return XK_kana_RI;
- if (!strcmp(s, "kana_RU")) return XK_kana_RU;
- if (!strcmp(s, "kana_RE")) return XK_kana_RE;
- if (!strcmp(s, "kana_RO")) return XK_kana_RO;
- if (!strcmp(s, "kana_WA")) return XK_kana_WA;
- if (!strcmp(s, "kana_N")) return XK_kana_N;
- if (!strcmp(s, "voicedsound")) return XK_voicedsound;
- if (!strcmp(s, "semivoicedsound")) return XK_semivoicedsound;
- if (!strcmp(s, "kana_switch")) return XK_kana_switch;
-#endif /* XK_KATAKANA */
-#ifdef XK_ARABIC
- if (!strcmp(s, "Arabic_comma")) return XK_Arabic_comma;
- if (!strcmp(s, "Arabic_semicolon")) return XK_Arabic_semicolon;
- if (!strcmp(s, "Arabic_question_mark")) return XK_Arabic_question_mark;
- if (!strcmp(s, "Arabic_hamza")) return XK_Arabic_hamza;
- if (!strcmp(s, "Arabic_maddaonalef")) return XK_Arabic_maddaonalef;
- if (!strcmp(s, "Arabic_hamzaonalef")) return XK_Arabic_hamzaonalef;
- if (!strcmp(s, "Arabic_hamzaonwaw")) return XK_Arabic_hamzaonwaw;
- if (!strcmp(s, "Arabic_hamzaunderalef")) return XK_Arabic_hamzaunderalef;
- if (!strcmp(s, "Arabic_hamzaonyeh")) return XK_Arabic_hamzaonyeh;
- if (!strcmp(s, "Arabic_alef")) return XK_Arabic_alef;
- if (!strcmp(s, "Arabic_beh")) return XK_Arabic_beh;
- if (!strcmp(s, "Arabic_tehmarbuta")) return XK_Arabic_tehmarbuta;
- if (!strcmp(s, "Arabic_teh")) return XK_Arabic_teh;
- if (!strcmp(s, "Arabic_theh")) return XK_Arabic_theh;
- if (!strcmp(s, "Arabic_jeem")) return XK_Arabic_jeem;
- if (!strcmp(s, "Arabic_hah")) return XK_Arabic_hah;
- if (!strcmp(s, "Arabic_khah")) return XK_Arabic_khah;
- if (!strcmp(s, "Arabic_dal")) return XK_Arabic_dal;
- if (!strcmp(s, "Arabic_thal")) return XK_Arabic_thal;
- if (!strcmp(s, "Arabic_ra")) return XK_Arabic_ra;
- if (!strcmp(s, "Arabic_zain")) return XK_Arabic_zain;
- if (!strcmp(s, "Arabic_seen")) return XK_Arabic_seen;
- if (!strcmp(s, "Arabic_sheen")) return XK_Arabic_sheen;
- if (!strcmp(s, "Arabic_sad")) return XK_Arabic_sad;
- if (!strcmp(s, "Arabic_dad")) return XK_Arabic_dad;
- if (!strcmp(s, "Arabic_tah")) return XK_Arabic_tah;
- if (!strcmp(s, "Arabic_zah")) return XK_Arabic_zah;
- if (!strcmp(s, "Arabic_ain")) return XK_Arabic_ain;
- if (!strcmp(s, "Arabic_ghain")) return XK_Arabic_ghain;
- if (!strcmp(s, "Arabic_tatweel")) return XK_Arabic_tatweel;
- if (!strcmp(s, "Arabic_feh")) return XK_Arabic_feh;
- if (!strcmp(s, "Arabic_qaf")) return XK_Arabic_qaf;
- if (!strcmp(s, "Arabic_kaf")) return XK_Arabic_kaf;
- if (!strcmp(s, "Arabic_lam")) return XK_Arabic_lam;
- if (!strcmp(s, "Arabic_meem")) return XK_Arabic_meem;
- if (!strcmp(s, "Arabic_noon")) return XK_Arabic_noon;
- if (!strcmp(s, "Arabic_ha")) return XK_Arabic_ha;
- if (!strcmp(s, "Arabic_heh")) return XK_Arabic_heh;
- if (!strcmp(s, "Arabic_waw")) return XK_Arabic_waw;
- if (!strcmp(s, "Arabic_alefmaksura")) return XK_Arabic_alefmaksura;
- if (!strcmp(s, "Arabic_yeh")) return XK_Arabic_yeh;
- if (!strcmp(s, "Arabic_fathatan")) return XK_Arabic_fathatan;
- if (!strcmp(s, "Arabic_dammatan")) return XK_Arabic_dammatan;
- if (!strcmp(s, "Arabic_kasratan")) return XK_Arabic_kasratan;
- if (!strcmp(s, "Arabic_fatha")) return XK_Arabic_fatha;
- if (!strcmp(s, "Arabic_damma")) return XK_Arabic_damma;
- if (!strcmp(s, "Arabic_kasra")) return XK_Arabic_kasra;
- if (!strcmp(s, "Arabic_shadda")) return XK_Arabic_shadda;
- if (!strcmp(s, "Arabic_sukun")) return XK_Arabic_sukun;
- if (!strcmp(s, "Arabic_switch")) return XK_Arabic_switch;
-#endif /* XK_ARABIC */
-#ifdef XK_CYRILLIC
- if (!strcmp(s, "Serbian_dje")) return XK_Serbian_dje;
- if (!strcmp(s, "Macedonia_gje")) return XK_Macedonia_gje;
- if (!strcmp(s, "Cyrillic_io")) return XK_Cyrillic_io;
- if (!strcmp(s, "Ukrainian_ie")) return XK_Ukrainian_ie;
- if (!strcmp(s, "Ukranian_je")) return XK_Ukranian_je;
- if (!strcmp(s, "Macedonia_dse")) return XK_Macedonia_dse;
- if (!strcmp(s, "Ukrainian_i")) return XK_Ukrainian_i;
- if (!strcmp(s, "Ukranian_i")) return XK_Ukranian_i;
- if (!strcmp(s, "Ukrainian_yi")) return XK_Ukrainian_yi;
- if (!strcmp(s, "Ukranian_yi")) return XK_Ukranian_yi;
- if (!strcmp(s, "Cyrillic_je")) return XK_Cyrillic_je;
- if (!strcmp(s, "Serbian_je")) return XK_Serbian_je;
- if (!strcmp(s, "Cyrillic_lje")) return XK_Cyrillic_lje;
- if (!strcmp(s, "Serbian_lje")) return XK_Serbian_lje;
- if (!strcmp(s, "Cyrillic_nje")) return XK_Cyrillic_nje;
- if (!strcmp(s, "Serbian_nje")) return XK_Serbian_nje;
- if (!strcmp(s, "Serbian_tshe")) return XK_Serbian_tshe;
- if (!strcmp(s, "Macedonia_kje")) return XK_Macedonia_kje;
- if (!strcmp(s, "Byelorussian_shortu")) return XK_Byelorussian_shortu;
- if (!strcmp(s, "Cyrillic_dzhe")) return XK_Cyrillic_dzhe;
- if (!strcmp(s, "Serbian_dze")) return XK_Serbian_dze;
- if (!strcmp(s, "numerosign")) return XK_numerosign;
- if (!strcmp(s, "Serbian_DJE")) return XK_Serbian_DJE;
- if (!strcmp(s, "Macedonia_GJE")) return XK_Macedonia_GJE;
- if (!strcmp(s, "Cyrillic_IO")) return XK_Cyrillic_IO;
- if (!strcmp(s, "Ukrainian_IE")) return XK_Ukrainian_IE;
- if (!strcmp(s, "Ukranian_JE")) return XK_Ukranian_JE;
- if (!strcmp(s, "Macedonia_DSE")) return XK_Macedonia_DSE;
- if (!strcmp(s, "Ukrainian_I")) return XK_Ukrainian_I;
- if (!strcmp(s, "Ukranian_I")) return XK_Ukranian_I;
- if (!strcmp(s, "Ukrainian_YI")) return XK_Ukrainian_YI;
- if (!strcmp(s, "Ukranian_YI")) return XK_Ukranian_YI;
- if (!strcmp(s, "Cyrillic_JE")) return XK_Cyrillic_JE;
- if (!strcmp(s, "Serbian_JE")) return XK_Serbian_JE;
- if (!strcmp(s, "Cyrillic_LJE")) return XK_Cyrillic_LJE;
- if (!strcmp(s, "Serbian_LJE")) return XK_Serbian_LJE;
- if (!strcmp(s, "Cyrillic_NJE")) return XK_Cyrillic_NJE;
- if (!strcmp(s, "Serbian_NJE")) return XK_Serbian_NJE;
- if (!strcmp(s, "Serbian_TSHE")) return XK_Serbian_TSHE;
- if (!strcmp(s, "Macedonia_KJE")) return XK_Macedonia_KJE;
- if (!strcmp(s, "Byelorussian_SHORTU")) return XK_Byelorussian_SHORTU;
- if (!strcmp(s, "Cyrillic_DZHE")) return XK_Cyrillic_DZHE;
- if (!strcmp(s, "Serbian_DZE")) return XK_Serbian_DZE;
- if (!strcmp(s, "Cyrillic_yu")) return XK_Cyrillic_yu;
- if (!strcmp(s, "Cyrillic_a")) return XK_Cyrillic_a;
- if (!strcmp(s, "Cyrillic_be")) return XK_Cyrillic_be;
- if (!strcmp(s, "Cyrillic_tse")) return XK_Cyrillic_tse;
- if (!strcmp(s, "Cyrillic_de")) return XK_Cyrillic_de;
- if (!strcmp(s, "Cyrillic_ie")) return XK_Cyrillic_ie;
- if (!strcmp(s, "Cyrillic_ef")) return XK_Cyrillic_ef;
- if (!strcmp(s, "Cyrillic_ghe")) return XK_Cyrillic_ghe;
- if (!strcmp(s, "Cyrillic_ha")) return XK_Cyrillic_ha;
- if (!strcmp(s, "Cyrillic_i")) return XK_Cyrillic_i;
- if (!strcmp(s, "Cyrillic_shorti")) return XK_Cyrillic_shorti;
- if (!strcmp(s, "Cyrillic_ka")) return XK_Cyrillic_ka;
- if (!strcmp(s, "Cyrillic_el")) return XK_Cyrillic_el;
- if (!strcmp(s, "Cyrillic_em")) return XK_Cyrillic_em;
- if (!strcmp(s, "Cyrillic_en")) return XK_Cyrillic_en;
- if (!strcmp(s, "Cyrillic_o")) return XK_Cyrillic_o;
- if (!strcmp(s, "Cyrillic_pe")) return XK_Cyrillic_pe;
- if (!strcmp(s, "Cyrillic_ya")) return XK_Cyrillic_ya;
- if (!strcmp(s, "Cyrillic_er")) return XK_Cyrillic_er;
- if (!strcmp(s, "Cyrillic_es")) return XK_Cyrillic_es;
- if (!strcmp(s, "Cyrillic_te")) return XK_Cyrillic_te;
- if (!strcmp(s, "Cyrillic_u")) return XK_Cyrillic_u;
- if (!strcmp(s, "Cyrillic_zhe")) return XK_Cyrillic_zhe;
- if (!strcmp(s, "Cyrillic_ve")) return XK_Cyrillic_ve;
- if (!strcmp(s, "Cyrillic_softsign")) return XK_Cyrillic_softsign;
- if (!strcmp(s, "Cyrillic_yeru")) return XK_Cyrillic_yeru;
- if (!strcmp(s, "Cyrillic_ze")) return XK_Cyrillic_ze;
- if (!strcmp(s, "Cyrillic_sha")) return XK_Cyrillic_sha;
- if (!strcmp(s, "Cyrillic_e")) return XK_Cyrillic_e;
- if (!strcmp(s, "Cyrillic_shcha")) return XK_Cyrillic_shcha;
- if (!strcmp(s, "Cyrillic_che")) return XK_Cyrillic_che;
- if (!strcmp(s, "Cyrillic_hardsign")) return XK_Cyrillic_hardsign;
- if (!strcmp(s, "Cyrillic_YU")) return XK_Cyrillic_YU;
- if (!strcmp(s, "Cyrillic_A")) return XK_Cyrillic_A;
- if (!strcmp(s, "Cyrillic_BE")) return XK_Cyrillic_BE;
- if (!strcmp(s, "Cyrillic_TSE")) return XK_Cyrillic_TSE;
- if (!strcmp(s, "Cyrillic_DE")) return XK_Cyrillic_DE;
- if (!strcmp(s, "Cyrillic_IE")) return XK_Cyrillic_IE;
- if (!strcmp(s, "Cyrillic_EF")) return XK_Cyrillic_EF;
- if (!strcmp(s, "Cyrillic_GHE")) return XK_Cyrillic_GHE;
- if (!strcmp(s, "Cyrillic_HA")) return XK_Cyrillic_HA;
- if (!strcmp(s, "Cyrillic_I")) return XK_Cyrillic_I;
- if (!strcmp(s, "Cyrillic_SHORTI")) return XK_Cyrillic_SHORTI;
- if (!strcmp(s, "Cyrillic_KA")) return XK_Cyrillic_KA;
- if (!strcmp(s, "Cyrillic_EL")) return XK_Cyrillic_EL;
- if (!strcmp(s, "Cyrillic_EM")) return XK_Cyrillic_EM;
- if (!strcmp(s, "Cyrillic_EN")) return XK_Cyrillic_EN;
- if (!strcmp(s, "Cyrillic_O")) return XK_Cyrillic_O;
- if (!strcmp(s, "Cyrillic_PE")) return XK_Cyrillic_PE;
- if (!strcmp(s, "Cyrillic_YA")) return XK_Cyrillic_YA;
- if (!strcmp(s, "Cyrillic_ER")) return XK_Cyrillic_ER;
- if (!strcmp(s, "Cyrillic_ES")) return XK_Cyrillic_ES;
- if (!strcmp(s, "Cyrillic_TE")) return XK_Cyrillic_TE;
- if (!strcmp(s, "Cyrillic_U")) return XK_Cyrillic_U;
- if (!strcmp(s, "Cyrillic_ZHE")) return XK_Cyrillic_ZHE;
- if (!strcmp(s, "Cyrillic_VE")) return XK_Cyrillic_VE;
- if (!strcmp(s, "Cyrillic_SOFTSIGN")) return XK_Cyrillic_SOFTSIGN;
- if (!strcmp(s, "Cyrillic_YERU")) return XK_Cyrillic_YERU;
- if (!strcmp(s, "Cyrillic_ZE")) return XK_Cyrillic_ZE;
- if (!strcmp(s, "Cyrillic_SHA")) return XK_Cyrillic_SHA;
- if (!strcmp(s, "Cyrillic_E")) return XK_Cyrillic_E;
- if (!strcmp(s, "Cyrillic_SHCHA")) return XK_Cyrillic_SHCHA;
- if (!strcmp(s, "Cyrillic_CHE")) return XK_Cyrillic_CHE;
- if (!strcmp(s, "Cyrillic_HARDSIGN")) return XK_Cyrillic_HARDSIGN;
-#endif /* XK_CYRILLIC */
-#ifdef XK_GREEK
- if (!strcmp(s, "Greek_ALPHAaccent")) return XK_Greek_ALPHAaccent;
- if (!strcmp(s, "Greek_EPSILONaccent")) return XK_Greek_EPSILONaccent;
- if (!strcmp(s, "Greek_ETAaccent")) return XK_Greek_ETAaccent;
- if (!strcmp(s, "Greek_IOTAaccent")) return XK_Greek_IOTAaccent;
- if (!strcmp(s, "Greek_IOTAdieresis")) return XK_Greek_IOTAdieresis;
- if (!strcmp(s, "Greek_OMICRONaccent")) return XK_Greek_OMICRONaccent;
- if (!strcmp(s, "Greek_UPSILONaccent")) return XK_Greek_UPSILONaccent;
- if (!strcmp(s, "Greek_UPSILONdieresis")) return XK_Greek_UPSILONdieresis;
- if (!strcmp(s, "Greek_OMEGAaccent")) return XK_Greek_OMEGAaccent;
- if (!strcmp(s, "Greek_accentdieresis")) return XK_Greek_accentdieresis;
- if (!strcmp(s, "Greek_horizbar")) return XK_Greek_horizbar;
- if (!strcmp(s, "Greek_alphaaccent")) return XK_Greek_alphaaccent;
- if (!strcmp(s, "Greek_epsilonaccent")) return XK_Greek_epsilonaccent;
- if (!strcmp(s, "Greek_etaaccent")) return XK_Greek_etaaccent;
- if (!strcmp(s, "Greek_iotaaccent")) return XK_Greek_iotaaccent;
- if (!strcmp(s, "Greek_iotadieresis")) return XK_Greek_iotadieresis;
- if (!strcmp(s, "Greek_iotaaccentdieresis")) return XK_Greek_iotaaccentdieresis;
- if (!strcmp(s, "Greek_omicronaccent")) return XK_Greek_omicronaccent;
- if (!strcmp(s, "Greek_upsilonaccent")) return XK_Greek_upsilonaccent;
- if (!strcmp(s, "Greek_upsilondieresis")) return XK_Greek_upsilondieresis;
- if (!strcmp(s, "Greek_upsilonaccentdieresis")) return XK_Greek_upsilonaccentdieresis;
- if (!strcmp(s, "Greek_omegaaccent")) return XK_Greek_omegaaccent;
- if (!strcmp(s, "Greek_ALPHA")) return XK_Greek_ALPHA;
- if (!strcmp(s, "Greek_BETA")) return XK_Greek_BETA;
- if (!strcmp(s, "Greek_GAMMA")) return XK_Greek_GAMMA;
- if (!strcmp(s, "Greek_DELTA")) return XK_Greek_DELTA;
- if (!strcmp(s, "Greek_EPSILON")) return XK_Greek_EPSILON;
- if (!strcmp(s, "Greek_ZETA")) return XK_Greek_ZETA;
- if (!strcmp(s, "Greek_ETA")) return XK_Greek_ETA;
- if (!strcmp(s, "Greek_THETA")) return XK_Greek_THETA;
- if (!strcmp(s, "Greek_IOTA")) return XK_Greek_IOTA;
- if (!strcmp(s, "Greek_KAPPA")) return XK_Greek_KAPPA;
- if (!strcmp(s, "Greek_LAMDA")) return XK_Greek_LAMDA;
- if (!strcmp(s, "Greek_LAMBDA")) return XK_Greek_LAMBDA;
- if (!strcmp(s, "Greek_MU")) return XK_Greek_MU;
- if (!strcmp(s, "Greek_NU")) return XK_Greek_NU;
- if (!strcmp(s, "Greek_XI")) return XK_Greek_XI;
- if (!strcmp(s, "Greek_OMICRON")) return XK_Greek_OMICRON;
- if (!strcmp(s, "Greek_PI")) return XK_Greek_PI;
- if (!strcmp(s, "Greek_RHO")) return XK_Greek_RHO;
- if (!strcmp(s, "Greek_SIGMA")) return XK_Greek_SIGMA;
- if (!strcmp(s, "Greek_TAU")) return XK_Greek_TAU;
- if (!strcmp(s, "Greek_UPSILON")) return XK_Greek_UPSILON;
- if (!strcmp(s, "Greek_PHI")) return XK_Greek_PHI;
- if (!strcmp(s, "Greek_CHI")) return XK_Greek_CHI;
- if (!strcmp(s, "Greek_PSI")) return XK_Greek_PSI;
- if (!strcmp(s, "Greek_OMEGA")) return XK_Greek_OMEGA;
- if (!strcmp(s, "Greek_alpha")) return XK_Greek_alpha;
- if (!strcmp(s, "Greek_beta")) return XK_Greek_beta;
- if (!strcmp(s, "Greek_gamma")) return XK_Greek_gamma;
- if (!strcmp(s, "Greek_delta")) return XK_Greek_delta;
- if (!strcmp(s, "Greek_epsilon")) return XK_Greek_epsilon;
- if (!strcmp(s, "Greek_zeta")) return XK_Greek_zeta;
- if (!strcmp(s, "Greek_eta")) return XK_Greek_eta;
- if (!strcmp(s, "Greek_theta")) return XK_Greek_theta;
- if (!strcmp(s, "Greek_iota")) return XK_Greek_iota;
- if (!strcmp(s, "Greek_kappa")) return XK_Greek_kappa;
- if (!strcmp(s, "Greek_lamda")) return XK_Greek_lamda;
- if (!strcmp(s, "Greek_lambda")) return XK_Greek_lambda;
- if (!strcmp(s, "Greek_mu")) return XK_Greek_mu;
- if (!strcmp(s, "Greek_nu")) return XK_Greek_nu;
- if (!strcmp(s, "Greek_xi")) return XK_Greek_xi;
- if (!strcmp(s, "Greek_omicron")) return XK_Greek_omicron;
- if (!strcmp(s, "Greek_pi")) return XK_Greek_pi;
- if (!strcmp(s, "Greek_rho")) return XK_Greek_rho;
- if (!strcmp(s, "Greek_sigma")) return XK_Greek_sigma;
- if (!strcmp(s, "Greek_finalsmallsigma")) return XK_Greek_finalsmallsigma;
- if (!strcmp(s, "Greek_tau")) return XK_Greek_tau;
- if (!strcmp(s, "Greek_upsilon")) return XK_Greek_upsilon;
- if (!strcmp(s, "Greek_phi")) return XK_Greek_phi;
- if (!strcmp(s, "Greek_chi")) return XK_Greek_chi;
- if (!strcmp(s, "Greek_psi")) return XK_Greek_psi;
- if (!strcmp(s, "Greek_omega")) return XK_Greek_omega;
- if (!strcmp(s, "Greek_switch")) return XK_Greek_switch;
-#endif /* XK_GREEK */
-#ifdef XK_TECHNICAL
- if (!strcmp(s, "leftradical")) return XK_leftradical;
- if (!strcmp(s, "topleftradical")) return XK_topleftradical;
- if (!strcmp(s, "horizconnector")) return XK_horizconnector;
- if (!strcmp(s, "topintegral")) return XK_topintegral;
- if (!strcmp(s, "botintegral")) return XK_botintegral;
- if (!strcmp(s, "vertconnector")) return XK_vertconnector;
- if (!strcmp(s, "topleftsqbracket")) return XK_topleftsqbracket;
- if (!strcmp(s, "botleftsqbracket")) return XK_botleftsqbracket;
- if (!strcmp(s, "toprightsqbracket")) return XK_toprightsqbracket;
- if (!strcmp(s, "botrightsqbracket")) return XK_botrightsqbracket;
- if (!strcmp(s, "topleftparens")) return XK_topleftparens;
- if (!strcmp(s, "botleftparens")) return XK_botleftparens;
- if (!strcmp(s, "toprightparens")) return XK_toprightparens;
- if (!strcmp(s, "botrightparens")) return XK_botrightparens;
- if (!strcmp(s, "leftmiddlecurlybrace")) return XK_leftmiddlecurlybrace;
- if (!strcmp(s, "rightmiddlecurlybrace")) return XK_rightmiddlecurlybrace;
- if (!strcmp(s, "topleftsummation")) return XK_topleftsummation;
- if (!strcmp(s, "botleftsummation")) return XK_botleftsummation;
- if (!strcmp(s, "topvertsummationconnector")) return XK_topvertsummationconnector;
- if (!strcmp(s, "botvertsummationconnector")) return XK_botvertsummationconnector;
- if (!strcmp(s, "toprightsummation")) return XK_toprightsummation;
- if (!strcmp(s, "botrightsummation")) return XK_botrightsummation;
- if (!strcmp(s, "rightmiddlesummation")) return XK_rightmiddlesummation;
- if (!strcmp(s, "lessthanequal")) return XK_lessthanequal;
- if (!strcmp(s, "notequal")) return XK_notequal;
- if (!strcmp(s, "greaterthanequal")) return XK_greaterthanequal;
- if (!strcmp(s, "integral")) return XK_integral;
- if (!strcmp(s, "therefore")) return XK_therefore;
- if (!strcmp(s, "variation")) return XK_variation;
- if (!strcmp(s, "infinity")) return XK_infinity;
- if (!strcmp(s, "nabla")) return XK_nabla;
- if (!strcmp(s, "approximate")) return XK_approximate;
- if (!strcmp(s, "similarequal")) return XK_similarequal;
- if (!strcmp(s, "ifonlyif")) return XK_ifonlyif;
- if (!strcmp(s, "implies")) return XK_implies;
- if (!strcmp(s, "identical")) return XK_identical;
- if (!strcmp(s, "radical")) return XK_radical;
- if (!strcmp(s, "includedin")) return XK_includedin;
- if (!strcmp(s, "includes")) return XK_includes;
- if (!strcmp(s, "intersection")) return XK_intersection;
- if (!strcmp(s, "union")) return XK_union;
- if (!strcmp(s, "logicaland")) return XK_logicaland;
- if (!strcmp(s, "logicalor")) return XK_logicalor;
- if (!strcmp(s, "partialderivative")) return XK_partialderivative;
- if (!strcmp(s, "function")) return XK_function;
- if (!strcmp(s, "leftarrow")) return XK_leftarrow;
- if (!strcmp(s, "uparrow")) return XK_uparrow;
- if (!strcmp(s, "rightarrow")) return XK_rightarrow;
- if (!strcmp(s, "downarrow")) return XK_downarrow;
-#endif /* XK_TECHNICAL */
-#ifdef XK_SPECIAL
- if (!strcmp(s, "blank")) return XK_blank;
- if (!strcmp(s, "soliddiamond")) return XK_soliddiamond;
- if (!strcmp(s, "checkerboard")) return XK_checkerboard;
- if (!strcmp(s, "ht")) return XK_ht;
- if (!strcmp(s, "ff")) return XK_ff;
- if (!strcmp(s, "cr")) return XK_cr;
- if (!strcmp(s, "lf")) return XK_lf;
- if (!strcmp(s, "nl")) return XK_nl;
- if (!strcmp(s, "vt")) return XK_vt;
- if (!strcmp(s, "lowrightcorner")) return XK_lowrightcorner;
- if (!strcmp(s, "uprightcorner")) return XK_uprightcorner;
- if (!strcmp(s, "upleftcorner")) return XK_upleftcorner;
- if (!strcmp(s, "lowleftcorner")) return XK_lowleftcorner;
- if (!strcmp(s, "crossinglines")) return XK_crossinglines;
- if (!strcmp(s, "horizlinescan1")) return XK_horizlinescan1;
- if (!strcmp(s, "horizlinescan3")) return XK_horizlinescan3;
- if (!strcmp(s, "horizlinescan5")) return XK_horizlinescan5;
- if (!strcmp(s, "horizlinescan7")) return XK_horizlinescan7;
- if (!strcmp(s, "horizlinescan9")) return XK_horizlinescan9;
- if (!strcmp(s, "leftt")) return XK_leftt;
- if (!strcmp(s, "rightt")) return XK_rightt;
- if (!strcmp(s, "bott")) return XK_bott;
- if (!strcmp(s, "topt")) return XK_topt;
- if (!strcmp(s, "vertbar")) return XK_vertbar;
-#endif /* XK_SPECIAL */
-#ifdef XK_PUBLISHING
- if (!strcmp(s, "emspace")) return XK_emspace;
- if (!strcmp(s, "enspace")) return XK_enspace;
- if (!strcmp(s, "em3space")) return XK_em3space;
- if (!strcmp(s, "em4space")) return XK_em4space;
- if (!strcmp(s, "digitspace")) return XK_digitspace;
- if (!strcmp(s, "punctspace")) return XK_punctspace;
- if (!strcmp(s, "thinspace")) return XK_thinspace;
- if (!strcmp(s, "hairspace")) return XK_hairspace;
- if (!strcmp(s, "emdash")) return XK_emdash;
- if (!strcmp(s, "endash")) return XK_endash;
- if (!strcmp(s, "signifblank")) return XK_signifblank;
- if (!strcmp(s, "ellipsis")) return XK_ellipsis;
- if (!strcmp(s, "doubbaselinedot")) return XK_doubbaselinedot;
- if (!strcmp(s, "onethird")) return XK_onethird;
- if (!strcmp(s, "twothirds")) return XK_twothirds;
- if (!strcmp(s, "onefifth")) return XK_onefifth;
- if (!strcmp(s, "twofifths")) return XK_twofifths;
- if (!strcmp(s, "threefifths")) return XK_threefifths;
- if (!strcmp(s, "fourfifths")) return XK_fourfifths;
- if (!strcmp(s, "onesixth")) return XK_onesixth;
- if (!strcmp(s, "fivesixths")) return XK_fivesixths;
- if (!strcmp(s, "careof")) return XK_careof;
- if (!strcmp(s, "figdash")) return XK_figdash;
- if (!strcmp(s, "leftanglebracket")) return XK_leftanglebracket;
- if (!strcmp(s, "decimalpoint")) return XK_decimalpoint;
- if (!strcmp(s, "rightanglebracket")) return XK_rightanglebracket;
- if (!strcmp(s, "marker")) return XK_marker;
- if (!strcmp(s, "oneeighth")) return XK_oneeighth;
- if (!strcmp(s, "threeeighths")) return XK_threeeighths;
- if (!strcmp(s, "fiveeighths")) return XK_fiveeighths;
- if (!strcmp(s, "seveneighths")) return XK_seveneighths;
- if (!strcmp(s, "trademark")) return XK_trademark;
- if (!strcmp(s, "signaturemark")) return XK_signaturemark;
- if (!strcmp(s, "trademarkincircle")) return XK_trademarkincircle;
- if (!strcmp(s, "leftopentriangle")) return XK_leftopentriangle;
- if (!strcmp(s, "rightopentriangle")) return XK_rightopentriangle;
- if (!strcmp(s, "emopencircle")) return XK_emopencircle;
- if (!strcmp(s, "emopenrectangle")) return XK_emopenrectangle;
- if (!strcmp(s, "leftsinglequotemark")) return XK_leftsinglequotemark;
- if (!strcmp(s, "rightsinglequotemark")) return XK_rightsinglequotemark;
- if (!strcmp(s, "leftdoublequotemark")) return XK_leftdoublequotemark;
- if (!strcmp(s, "rightdoublequotemark")) return XK_rightdoublequotemark;
- if (!strcmp(s, "prescription")) return XK_prescription;
- if (!strcmp(s, "minutes")) return XK_minutes;
- if (!strcmp(s, "seconds")) return XK_seconds;
- if (!strcmp(s, "latincross")) return XK_latincross;
- if (!strcmp(s, "hexagram")) return XK_hexagram;
- if (!strcmp(s, "filledrectbullet")) return XK_filledrectbullet;
- if (!strcmp(s, "filledlefttribullet")) return XK_filledlefttribullet;
- if (!strcmp(s, "filledrighttribullet")) return XK_filledrighttribullet;
- if (!strcmp(s, "emfilledcircle")) return XK_emfilledcircle;
- if (!strcmp(s, "emfilledrect")) return XK_emfilledrect;
- if (!strcmp(s, "enopencircbullet")) return XK_enopencircbullet;
- if (!strcmp(s, "enopensquarebullet")) return XK_enopensquarebullet;
- if (!strcmp(s, "openrectbullet")) return XK_openrectbullet;
- if (!strcmp(s, "opentribulletup")) return XK_opentribulletup;
- if (!strcmp(s, "opentribulletdown")) return XK_opentribulletdown;
- if (!strcmp(s, "openstar")) return XK_openstar;
- if (!strcmp(s, "enfilledcircbullet")) return XK_enfilledcircbullet;
- if (!strcmp(s, "enfilledsqbullet")) return XK_enfilledsqbullet;
- if (!strcmp(s, "filledtribulletup")) return XK_filledtribulletup;
- if (!strcmp(s, "filledtribulletdown")) return XK_filledtribulletdown;
- if (!strcmp(s, "leftpointer")) return XK_leftpointer;
- if (!strcmp(s, "rightpointer")) return XK_rightpointer;
- if (!strcmp(s, "club")) return XK_club;
- if (!strcmp(s, "diamond")) return XK_diamond;
- if (!strcmp(s, "heart")) return XK_heart;
- if (!strcmp(s, "maltesecross")) return XK_maltesecross;
- if (!strcmp(s, "dagger")) return XK_dagger;
- if (!strcmp(s, "doubledagger")) return XK_doubledagger;
- if (!strcmp(s, "checkmark")) return XK_checkmark;
- if (!strcmp(s, "ballotcross")) return XK_ballotcross;
- if (!strcmp(s, "musicalsharp")) return XK_musicalsharp;
- if (!strcmp(s, "musicalflat")) return XK_musicalflat;
- if (!strcmp(s, "malesymbol")) return XK_malesymbol;
- if (!strcmp(s, "femalesymbol")) return XK_femalesymbol;
- if (!strcmp(s, "telephone")) return XK_telephone;
- if (!strcmp(s, "telephonerecorder")) return XK_telephonerecorder;
- if (!strcmp(s, "phonographcopyright")) return XK_phonographcopyright;
- if (!strcmp(s, "caret")) return XK_caret;
- if (!strcmp(s, "singlelowquotemark")) return XK_singlelowquotemark;
- if (!strcmp(s, "doublelowquotemark")) return XK_doublelowquotemark;
- if (!strcmp(s, "cursor")) return XK_cursor;
-#endif /* XK_PUBLISHING */
-#ifdef XK_APL
- if (!strcmp(s, "leftcaret")) return XK_leftcaret;
- if (!strcmp(s, "rightcaret")) return XK_rightcaret;
- if (!strcmp(s, "downcaret")) return XK_downcaret;
- if (!strcmp(s, "upcaret")) return XK_upcaret;
- if (!strcmp(s, "overbar")) return XK_overbar;
- if (!strcmp(s, "downtack")) return XK_downtack;
- if (!strcmp(s, "upshoe")) return XK_upshoe;
- if (!strcmp(s, "downstile")) return XK_downstile;
- if (!strcmp(s, "underbar")) return XK_underbar;
- if (!strcmp(s, "jot")) return XK_jot;
- if (!strcmp(s, "quad")) return XK_quad;
- if (!strcmp(s, "uptack")) return XK_uptack;
- if (!strcmp(s, "circle")) return XK_circle;
- if (!strcmp(s, "upstile")) return XK_upstile;
- if (!strcmp(s, "downshoe")) return XK_downshoe;
- if (!strcmp(s, "rightshoe")) return XK_rightshoe;
- if (!strcmp(s, "leftshoe")) return XK_leftshoe;
- if (!strcmp(s, "lefttack")) return XK_lefttack;
- if (!strcmp(s, "righttack")) return XK_righttack;
-#endif /* XK_APL */
-#ifdef XK_HEBREW
- if (!strcmp(s, "hebrew_doublelowline")) return XK_hebrew_doublelowline;
- if (!strcmp(s, "hebrew_aleph")) return XK_hebrew_aleph;
- if (!strcmp(s, "hebrew_bet")) return XK_hebrew_bet;
- if (!strcmp(s, "hebrew_beth")) return XK_hebrew_beth;
- if (!strcmp(s, "hebrew_gimel")) return XK_hebrew_gimel;
- if (!strcmp(s, "hebrew_gimmel")) return XK_hebrew_gimmel;
- if (!strcmp(s, "hebrew_dalet")) return XK_hebrew_dalet;
- if (!strcmp(s, "hebrew_daleth")) return XK_hebrew_daleth;
- if (!strcmp(s, "hebrew_he")) return XK_hebrew_he;
- if (!strcmp(s, "hebrew_waw")) return XK_hebrew_waw;
- if (!strcmp(s, "hebrew_zain")) return XK_hebrew_zain;
- if (!strcmp(s, "hebrew_zayin")) return XK_hebrew_zayin;
- if (!strcmp(s, "hebrew_chet")) return XK_hebrew_chet;
- if (!strcmp(s, "hebrew_het")) return XK_hebrew_het;
- if (!strcmp(s, "hebrew_tet")) return XK_hebrew_tet;
- if (!strcmp(s, "hebrew_teth")) return XK_hebrew_teth;
- if (!strcmp(s, "hebrew_yod")) return XK_hebrew_yod;
- if (!strcmp(s, "hebrew_finalkaph")) return XK_hebrew_finalkaph;
- if (!strcmp(s, "hebrew_kaph")) return XK_hebrew_kaph;
- if (!strcmp(s, "hebrew_lamed")) return XK_hebrew_lamed;
- if (!strcmp(s, "hebrew_finalmem")) return XK_hebrew_finalmem;
- if (!strcmp(s, "hebrew_mem")) return XK_hebrew_mem;
- if (!strcmp(s, "hebrew_finalnun")) return XK_hebrew_finalnun;
- if (!strcmp(s, "hebrew_nun")) return XK_hebrew_nun;
- if (!strcmp(s, "hebrew_samech")) return XK_hebrew_samech;
- if (!strcmp(s, "hebrew_samekh")) return XK_hebrew_samekh;
- if (!strcmp(s, "hebrew_ayin")) return XK_hebrew_ayin;
- if (!strcmp(s, "hebrew_finalpe")) return XK_hebrew_finalpe;
- if (!strcmp(s, "hebrew_pe")) return XK_hebrew_pe;
- if (!strcmp(s, "hebrew_finalzade")) return XK_hebrew_finalzade;
- if (!strcmp(s, "hebrew_finalzadi")) return XK_hebrew_finalzadi;
- if (!strcmp(s, "hebrew_zade")) return XK_hebrew_zade;
- if (!strcmp(s, "hebrew_zadi")) return XK_hebrew_zadi;
- if (!strcmp(s, "hebrew_qoph")) return XK_hebrew_qoph;
- if (!strcmp(s, "hebrew_kuf")) return XK_hebrew_kuf;
- if (!strcmp(s, "hebrew_resh")) return XK_hebrew_resh;
- if (!strcmp(s, "hebrew_shin")) return XK_hebrew_shin;
- if (!strcmp(s, "hebrew_taw")) return XK_hebrew_taw;
- if (!strcmp(s, "hebrew_taf")) return XK_hebrew_taf;
- if (!strcmp(s, "Hebrew_switch")) return XK_Hebrew_switch;
-#endif /* XK_HEBREW */
-#ifdef XK_THAI
- if (!strcmp(s, "Thai_kokai")) return XK_Thai_kokai;
- if (!strcmp(s, "Thai_khokhai")) return XK_Thai_khokhai;
- if (!strcmp(s, "Thai_khokhuat")) return XK_Thai_khokhuat;
- if (!strcmp(s, "Thai_khokhwai")) return XK_Thai_khokhwai;
- if (!strcmp(s, "Thai_khokhon")) return XK_Thai_khokhon;
- if (!strcmp(s, "Thai_khorakhang")) return XK_Thai_khorakhang;
- if (!strcmp(s, "Thai_ngongu")) return XK_Thai_ngongu;
- if (!strcmp(s, "Thai_chochan")) return XK_Thai_chochan;
- if (!strcmp(s, "Thai_choching")) return XK_Thai_choching;
- if (!strcmp(s, "Thai_chochang")) return XK_Thai_chochang;
- if (!strcmp(s, "Thai_soso")) return XK_Thai_soso;
- if (!strcmp(s, "Thai_chochoe")) return XK_Thai_chochoe;
- if (!strcmp(s, "Thai_yoying")) return XK_Thai_yoying;
- if (!strcmp(s, "Thai_dochada")) return XK_Thai_dochada;
- if (!strcmp(s, "Thai_topatak")) return XK_Thai_topatak;
- if (!strcmp(s, "Thai_thothan")) return XK_Thai_thothan;
- if (!strcmp(s, "Thai_thonangmontho")) return XK_Thai_thonangmontho;
- if (!strcmp(s, "Thai_thophuthao")) return XK_Thai_thophuthao;
- if (!strcmp(s, "Thai_nonen")) return XK_Thai_nonen;
- if (!strcmp(s, "Thai_dodek")) return XK_Thai_dodek;
- if (!strcmp(s, "Thai_totao")) return XK_Thai_totao;
- if (!strcmp(s, "Thai_thothung")) return XK_Thai_thothung;
- if (!strcmp(s, "Thai_thothahan")) return XK_Thai_thothahan;
- if (!strcmp(s, "Thai_thothong")) return XK_Thai_thothong;
- if (!strcmp(s, "Thai_nonu")) return XK_Thai_nonu;
- if (!strcmp(s, "Thai_bobaimai")) return XK_Thai_bobaimai;
- if (!strcmp(s, "Thai_popla")) return XK_Thai_popla;
- if (!strcmp(s, "Thai_phophung")) return XK_Thai_phophung;
- if (!strcmp(s, "Thai_fofa")) return XK_Thai_fofa;
- if (!strcmp(s, "Thai_phophan")) return XK_Thai_phophan;
- if (!strcmp(s, "Thai_fofan")) return XK_Thai_fofan;
- if (!strcmp(s, "Thai_phosamphao")) return XK_Thai_phosamphao;
- if (!strcmp(s, "Thai_moma")) return XK_Thai_moma;
- if (!strcmp(s, "Thai_yoyak")) return XK_Thai_yoyak;
- if (!strcmp(s, "Thai_rorua")) return XK_Thai_rorua;
- if (!strcmp(s, "Thai_ru")) return XK_Thai_ru;
- if (!strcmp(s, "Thai_loling")) return XK_Thai_loling;
- if (!strcmp(s, "Thai_lu")) return XK_Thai_lu;
- if (!strcmp(s, "Thai_wowaen")) return XK_Thai_wowaen;
- if (!strcmp(s, "Thai_sosala")) return XK_Thai_sosala;
- if (!strcmp(s, "Thai_sorusi")) return XK_Thai_sorusi;
- if (!strcmp(s, "Thai_sosua")) return XK_Thai_sosua;
- if (!strcmp(s, "Thai_hohip")) return XK_Thai_hohip;
- if (!strcmp(s, "Thai_lochula")) return XK_Thai_lochula;
- if (!strcmp(s, "Thai_oang")) return XK_Thai_oang;
- if (!strcmp(s, "Thai_honokhuk")) return XK_Thai_honokhuk;
- if (!strcmp(s, "Thai_paiyannoi")) return XK_Thai_paiyannoi;
- if (!strcmp(s, "Thai_saraa")) return XK_Thai_saraa;
- if (!strcmp(s, "Thai_maihanakat")) return XK_Thai_maihanakat;
- if (!strcmp(s, "Thai_saraaa")) return XK_Thai_saraaa;
- if (!strcmp(s, "Thai_saraam")) return XK_Thai_saraam;
- if (!strcmp(s, "Thai_sarai")) return XK_Thai_sarai;
- if (!strcmp(s, "Thai_saraii")) return XK_Thai_saraii;
- if (!strcmp(s, "Thai_saraue")) return XK_Thai_saraue;
- if (!strcmp(s, "Thai_sarauee")) return XK_Thai_sarauee;
- if (!strcmp(s, "Thai_sarau")) return XK_Thai_sarau;
- if (!strcmp(s, "Thai_sarauu")) return XK_Thai_sarauu;
- if (!strcmp(s, "Thai_phinthu")) return XK_Thai_phinthu;
- if (!strcmp(s, "Thai_maihanakat_maitho")) return XK_Thai_maihanakat_maitho;
- if (!strcmp(s, "Thai_baht")) return XK_Thai_baht;
- if (!strcmp(s, "Thai_sarae")) return XK_Thai_sarae;
- if (!strcmp(s, "Thai_saraae")) return XK_Thai_saraae;
- if (!strcmp(s, "Thai_sarao")) return XK_Thai_sarao;
- if (!strcmp(s, "Thai_saraaimaimuan")) return XK_Thai_saraaimaimuan;
- if (!strcmp(s, "Thai_saraaimaimalai")) return XK_Thai_saraaimaimalai;
- if (!strcmp(s, "Thai_lakkhangyao")) return XK_Thai_lakkhangyao;
- if (!strcmp(s, "Thai_maiyamok")) return XK_Thai_maiyamok;
- if (!strcmp(s, "Thai_maitaikhu")) return XK_Thai_maitaikhu;
- if (!strcmp(s, "Thai_maiek")) return XK_Thai_maiek;
- if (!strcmp(s, "Thai_maitho")) return XK_Thai_maitho;
- if (!strcmp(s, "Thai_maitri")) return XK_Thai_maitri;
- if (!strcmp(s, "Thai_maichattawa")) return XK_Thai_maichattawa;
- if (!strcmp(s, "Thai_thanthakhat")) return XK_Thai_thanthakhat;
- if (!strcmp(s, "Thai_nikhahit")) return XK_Thai_nikhahit;
- if (!strcmp(s, "Thai_leksun")) return XK_Thai_leksun;
- if (!strcmp(s, "Thai_leknung")) return XK_Thai_leknung;
- if (!strcmp(s, "Thai_leksong")) return XK_Thai_leksong;
- if (!strcmp(s, "Thai_leksam")) return XK_Thai_leksam;
- if (!strcmp(s, "Thai_leksi")) return XK_Thai_leksi;
- if (!strcmp(s, "Thai_lekha")) return XK_Thai_lekha;
- if (!strcmp(s, "Thai_lekhok")) return XK_Thai_lekhok;
- if (!strcmp(s, "Thai_lekchet")) return XK_Thai_lekchet;
- if (!strcmp(s, "Thai_lekpaet")) return XK_Thai_lekpaet;
- if (!strcmp(s, "Thai_lekkao")) return XK_Thai_lekkao;
-#endif /* XK_THAI */
-#ifdef XK_KOREAN
- if (!strcmp(s, "Hangul")) return XK_Hangul;
- if (!strcmp(s, "Hangul_Start")) return XK_Hangul_Start;
- if (!strcmp(s, "Hangul_End")) return XK_Hangul_End;
- if (!strcmp(s, "Hangul_Hanja")) return XK_Hangul_Hanja;
- if (!strcmp(s, "Hangul_Jamo")) return XK_Hangul_Jamo;
- if (!strcmp(s, "Hangul_Romaja")) return XK_Hangul_Romaja;
- if (!strcmp(s, "Hangul_Codeinput")) return XK_Hangul_Codeinput;
- if (!strcmp(s, "Hangul_Jeonja")) return XK_Hangul_Jeonja;
- if (!strcmp(s, "Hangul_Banja")) return XK_Hangul_Banja;
- if (!strcmp(s, "Hangul_PreHanja")) return XK_Hangul_PreHanja;
- if (!strcmp(s, "Hangul_PostHanja")) return XK_Hangul_PostHanja;
- if (!strcmp(s, "Hangul_SingleCandidate")) return XK_Hangul_SingleCandidate;
- if (!strcmp(s, "Hangul_MultipleCandidate")) return XK_Hangul_MultipleCandidate;
- if (!strcmp(s, "Hangul_PreviousCandidate")) return XK_Hangul_PreviousCandidate;
- if (!strcmp(s, "Hangul_Special")) return XK_Hangul_Special;
- if (!strcmp(s, "Hangul_switch")) return XK_Hangul_switch;
- if (!strcmp(s, "Hangul_Kiyeog")) return XK_Hangul_Kiyeog;
- if (!strcmp(s, "Hangul_SsangKiyeog")) return XK_Hangul_SsangKiyeog;
- if (!strcmp(s, "Hangul_KiyeogSios")) return XK_Hangul_KiyeogSios;
- if (!strcmp(s, "Hangul_Nieun")) return XK_Hangul_Nieun;
- if (!strcmp(s, "Hangul_NieunJieuj")) return XK_Hangul_NieunJieuj;
- if (!strcmp(s, "Hangul_NieunHieuh")) return XK_Hangul_NieunHieuh;
- if (!strcmp(s, "Hangul_Dikeud")) return XK_Hangul_Dikeud;
- if (!strcmp(s, "Hangul_SsangDikeud")) return XK_Hangul_SsangDikeud;
- if (!strcmp(s, "Hangul_Rieul")) return XK_Hangul_Rieul;
- if (!strcmp(s, "Hangul_RieulKiyeog")) return XK_Hangul_RieulKiyeog;
- if (!strcmp(s, "Hangul_RieulMieum")) return XK_Hangul_RieulMieum;
- if (!strcmp(s, "Hangul_RieulPieub")) return XK_Hangul_RieulPieub;
- if (!strcmp(s, "Hangul_RieulSios")) return XK_Hangul_RieulSios;
- if (!strcmp(s, "Hangul_RieulTieut")) return XK_Hangul_RieulTieut;
- if (!strcmp(s, "Hangul_RieulPhieuf")) return XK_Hangul_RieulPhieuf;
- if (!strcmp(s, "Hangul_RieulHieuh")) return XK_Hangul_RieulHieuh;
- if (!strcmp(s, "Hangul_Mieum")) return XK_Hangul_Mieum;
- if (!strcmp(s, "Hangul_Pieub")) return XK_Hangul_Pieub;
- if (!strcmp(s, "Hangul_SsangPieub")) return XK_Hangul_SsangPieub;
- if (!strcmp(s, "Hangul_PieubSios")) return XK_Hangul_PieubSios;
- if (!strcmp(s, "Hangul_Sios")) return XK_Hangul_Sios;
- if (!strcmp(s, "Hangul_SsangSios")) return XK_Hangul_SsangSios;
- if (!strcmp(s, "Hangul_Ieung")) return XK_Hangul_Ieung;
- if (!strcmp(s, "Hangul_Jieuj")) return XK_Hangul_Jieuj;
- if (!strcmp(s, "Hangul_SsangJieuj")) return XK_Hangul_SsangJieuj;
- if (!strcmp(s, "Hangul_Cieuc")) return XK_Hangul_Cieuc;
- if (!strcmp(s, "Hangul_Khieuq")) return XK_Hangul_Khieuq;
- if (!strcmp(s, "Hangul_Tieut")) return XK_Hangul_Tieut;
- if (!strcmp(s, "Hangul_Phieuf")) return XK_Hangul_Phieuf;
- if (!strcmp(s, "Hangul_Hieuh")) return XK_Hangul_Hieuh;
- if (!strcmp(s, "Hangul_A")) return XK_Hangul_A;
- if (!strcmp(s, "Hangul_AE")) return XK_Hangul_AE;
- if (!strcmp(s, "Hangul_YA")) return XK_Hangul_YA;
- if (!strcmp(s, "Hangul_YAE")) return XK_Hangul_YAE;
- if (!strcmp(s, "Hangul_EO")) return XK_Hangul_EO;
- if (!strcmp(s, "Hangul_E")) return XK_Hangul_E;
- if (!strcmp(s, "Hangul_YEO")) return XK_Hangul_YEO;
- if (!strcmp(s, "Hangul_YE")) return XK_Hangul_YE;
- if (!strcmp(s, "Hangul_O")) return XK_Hangul_O;
- if (!strcmp(s, "Hangul_WA")) return XK_Hangul_WA;
- if (!strcmp(s, "Hangul_WAE")) return XK_Hangul_WAE;
- if (!strcmp(s, "Hangul_OE")) return XK_Hangul_OE;
- if (!strcmp(s, "Hangul_YO")) return XK_Hangul_YO;
- if (!strcmp(s, "Hangul_U")) return XK_Hangul_U;
- if (!strcmp(s, "Hangul_WEO")) return XK_Hangul_WEO;
- if (!strcmp(s, "Hangul_WE")) return XK_Hangul_WE;
- if (!strcmp(s, "Hangul_WI")) return XK_Hangul_WI;
- if (!strcmp(s, "Hangul_YU")) return XK_Hangul_YU;
- if (!strcmp(s, "Hangul_EU")) return XK_Hangul_EU;
- if (!strcmp(s, "Hangul_YI")) return XK_Hangul_YI;
- if (!strcmp(s, "Hangul_I")) return XK_Hangul_I;
- if (!strcmp(s, "Hangul_J_Kiyeog")) return XK_Hangul_J_Kiyeog;
- if (!strcmp(s, "Hangul_J_SsangKiyeog")) return XK_Hangul_J_SsangKiyeog;
- if (!strcmp(s, "Hangul_J_KiyeogSios")) return XK_Hangul_J_KiyeogSios;
- if (!strcmp(s, "Hangul_J_Nieun")) return XK_Hangul_J_Nieun;
- if (!strcmp(s, "Hangul_J_NieunJieuj")) return XK_Hangul_J_NieunJieuj;
- if (!strcmp(s, "Hangul_J_NieunHieuh")) return XK_Hangul_J_NieunHieuh;
- if (!strcmp(s, "Hangul_J_Dikeud")) return XK_Hangul_J_Dikeud;
- if (!strcmp(s, "Hangul_J_Rieul")) return XK_Hangul_J_Rieul;
- if (!strcmp(s, "Hangul_J_RieulKiyeog")) return XK_Hangul_J_RieulKiyeog;
- if (!strcmp(s, "Hangul_J_RieulMieum")) return XK_Hangul_J_RieulMieum;
- if (!strcmp(s, "Hangul_J_RieulPieub")) return XK_Hangul_J_RieulPieub;
- if (!strcmp(s, "Hangul_J_RieulSios")) return XK_Hangul_J_RieulSios;
- if (!strcmp(s, "Hangul_J_RieulTieut")) return XK_Hangul_J_RieulTieut;
- if (!strcmp(s, "Hangul_J_RieulPhieuf")) return XK_Hangul_J_RieulPhieuf;
- if (!strcmp(s, "Hangul_J_RieulHieuh")) return XK_Hangul_J_RieulHieuh;
- if (!strcmp(s, "Hangul_J_Mieum")) return XK_Hangul_J_Mieum;
- if (!strcmp(s, "Hangul_J_Pieub")) return XK_Hangul_J_Pieub;
- if (!strcmp(s, "Hangul_J_PieubSios")) return XK_Hangul_J_PieubSios;
- if (!strcmp(s, "Hangul_J_Sios")) return XK_Hangul_J_Sios;
- if (!strcmp(s, "Hangul_J_SsangSios")) return XK_Hangul_J_SsangSios;
- if (!strcmp(s, "Hangul_J_Ieung")) return XK_Hangul_J_Ieung;
- if (!strcmp(s, "Hangul_J_Jieuj")) return XK_Hangul_J_Jieuj;
- if (!strcmp(s, "Hangul_J_Cieuc")) return XK_Hangul_J_Cieuc;
- if (!strcmp(s, "Hangul_J_Khieuq")) return XK_Hangul_J_Khieuq;
- if (!strcmp(s, "Hangul_J_Tieut")) return XK_Hangul_J_Tieut;
- if (!strcmp(s, "Hangul_J_Phieuf")) return XK_Hangul_J_Phieuf;
- if (!strcmp(s, "Hangul_J_Hieuh")) return XK_Hangul_J_Hieuh;
- if (!strcmp(s, "Hangul_RieulYeorinHieuh")) return XK_Hangul_RieulYeorinHieuh;
- if (!strcmp(s, "Hangul_SunkyeongeumMieum")) return XK_Hangul_SunkyeongeumMieum;
- if (!strcmp(s, "Hangul_SunkyeongeumPieub")) return XK_Hangul_SunkyeongeumPieub;
- if (!strcmp(s, "Hangul_PanSios")) return XK_Hangul_PanSios;
- if (!strcmp(s, "Hangul_KkogjiDalrinIeung")) return XK_Hangul_KkogjiDalrinIeung;
- if (!strcmp(s, "Hangul_SunkyeongeumPhieuf")) return XK_Hangul_SunkyeongeumPhieuf;
- if (!strcmp(s, "Hangul_YeorinHieuh")) return XK_Hangul_YeorinHieuh;
- if (!strcmp(s, "Hangul_AraeA")) return XK_Hangul_AraeA;
- if (!strcmp(s, "Hangul_AraeAE")) return XK_Hangul_AraeAE;
- if (!strcmp(s, "Hangul_J_PanSios")) return XK_Hangul_J_PanSios;
- if (!strcmp(s, "Hangul_J_KkogjiDalrinIeung")) return XK_Hangul_J_KkogjiDalrinIeung;
- if (!strcmp(s, "Hangul_J_YeorinHieuh")) return XK_Hangul_J_YeorinHieuh;
- if (!strcmp(s, "Korean_Won")) return XK_Korean_Won;
-#endif /* XK_KOREAN */
- if (!strcmp(s, "EuroSign")) return XK_EuroSign;
-#endif
- return NoSymbol;
-}
-
-
-char *XKeysymToString(KeySym k) {
-#ifndef XK_0_nosuch
- if (k == XK_VoidSymbol) return "VoidSymbol";
-#ifdef XK_MISCELLANY
- if (k == XK_BackSpace) return "BackSpace";
- if (k == XK_Tab) return "Tab";
- if (k == XK_Linefeed) return "Linefeed";
- if (k == XK_Clear) return "Clear";
- if (k == XK_Return) return "Return";
- if (k == XK_Pause) return "Pause";
- if (k == XK_Scroll_Lock) return "Scroll_Lock";
- if (k == XK_Sys_Req) return "Sys_Req";
- if (k == XK_Escape) return "Escape";
- if (k == XK_Delete) return "Delete";
- if (k == XK_Multi_key) return "Multi_key";
- if (k == XK_SingleCandidate) return "SingleCandidate";
- if (k == XK_MultipleCandidate) return "MultipleCandidate";
- if (k == XK_PreviousCandidate) return "PreviousCandidate";
- if (k == XK_Kanji) return "Kanji";
- if (k == XK_Muhenkan) return "Muhenkan";
- if (k == XK_Henkan_Mode) return "Henkan_Mode";
- if (k == XK_Henkan) return "Henkan";
- if (k == XK_Romaji) return "Romaji";
- if (k == XK_Hiragana) return "Hiragana";
- if (k == XK_Katakana) return "Katakana";
- if (k == XK_Hiragana_Katakana) return "Hiragana_Katakana";
- if (k == XK_Zenkaku) return "Zenkaku";
- if (k == XK_Hankaku) return "Hankaku";
- if (k == XK_Zenkaku_Hankaku) return "Zenkaku_Hankaku";
- if (k == XK_Touroku) return "Touroku";
- if (k == XK_Massyo) return "Massyo";
- if (k == XK_Kana_Lock) return "Kana_Lock";
- if (k == XK_Kana_Shift) return "Kana_Shift";
- if (k == XK_Eisu_Shift) return "Eisu_Shift";
- if (k == XK_Eisu_toggle) return "Eisu_toggle";
- if (k == XK_Zen_Koho) return "Zen_Koho";
- if (k == XK_Mae_Koho) return "Mae_Koho";
- if (k == XK_Home) return "Home";
- if (k == XK_Left) return "Left";
- if (k == XK_Up) return "Up";
- if (k == XK_Right) return "Right";
- if (k == XK_Down) return "Down";
- if (k == XK_Prior) return "Prior";
- if (k == XK_Page_Up) return "Page_Up";
- if (k == XK_Next) return "Next";
- if (k == XK_Page_Down) return "Page_Down";
- if (k == XK_End) return "End";
- if (k == XK_Begin) return "Begin";
- if (k == XK_Select) return "Select";
- if (k == XK_Print) return "Print";
- if (k == XK_Execute) return "Execute";
- if (k == XK_Insert) return "Insert";
- if (k == XK_Undo) return "Undo";
- if (k == XK_Redo) return "Redo";
- if (k == XK_Menu) return "Menu";
- if (k == XK_Find) return "Find";
- if (k == XK_Cancel) return "Cancel";
- if (k == XK_Help) return "Help";
- if (k == XK_Break) return "Break";
- if (k == XK_Mode_switch) return "Mode_switch";
- if (k == XK_script_switch) return "script_switch";
- if (k == XK_Num_Lock) return "Num_Lock";
- if (k == XK_KP_Space) return "KP_Space";
- if (k == XK_KP_Tab) return "KP_Tab";
- if (k == XK_KP_Enter) return "KP_Enter";
- if (k == XK_KP_F1) return "KP_F1";
- if (k == XK_KP_F2) return "KP_F2";
- if (k == XK_KP_F3) return "KP_F3";
- if (k == XK_KP_F4) return "KP_F4";
- if (k == XK_KP_Home) return "KP_Home";
- if (k == XK_KP_Left) return "KP_Left";
- if (k == XK_KP_Up) return "KP_Up";
- if (k == XK_KP_Right) return "KP_Right";
- if (k == XK_KP_Down) return "KP_Down";
- if (k == XK_KP_Prior) return "KP_Prior";
- if (k == XK_KP_Page_Up) return "KP_Page_Up";
- if (k == XK_KP_Next) return "KP_Next";
- if (k == XK_KP_Page_Down) return "KP_Page_Down";
- if (k == XK_KP_End) return "KP_End";
- if (k == XK_KP_Begin) return "KP_Begin";
- if (k == XK_KP_Insert) return "KP_Insert";
- if (k == XK_KP_Delete) return "KP_Delete";
- if (k == XK_KP_Equal) return "KP_Equal";
- if (k == XK_KP_Multiply) return "KP_Multiply";
- if (k == XK_KP_Add) return "KP_Add";
- if (k == XK_KP_Separator) return "KP_Separator";
- if (k == XK_KP_Subtract) return "KP_Subtract";
- if (k == XK_KP_Decimal) return "KP_Decimal";
- if (k == XK_KP_Divide) return "KP_Divide";
- if (k == XK_KP_0) return "KP_0";
- if (k == XK_KP_1) return "KP_1";
- if (k == XK_KP_2) return "KP_2";
- if (k == XK_KP_3) return "KP_3";
- if (k == XK_KP_4) return "KP_4";
- if (k == XK_KP_5) return "KP_5";
- if (k == XK_KP_6) return "KP_6";
- if (k == XK_KP_7) return "KP_7";
- if (k == XK_KP_8) return "KP_8";
- if (k == XK_KP_9) return "KP_9";
- if (k == XK_F1) return "F1";
- if (k == XK_F2) return "F2";
- if (k == XK_F3) return "F3";
- if (k == XK_F4) return "F4";
- if (k == XK_F5) return "F5";
- if (k == XK_F6) return "F6";
- if (k == XK_F7) return "F7";
- if (k == XK_F8) return "F8";
- if (k == XK_F9) return "F9";
- if (k == XK_F10) return "F10";
- if (k == XK_F11) return "F11";
- if (k == XK_L1) return "L1";
- if (k == XK_F12) return "F12";
- if (k == XK_L2) return "L2";
- if (k == XK_F13) return "F13";
- if (k == XK_L3) return "L3";
- if (k == XK_F14) return "F14";
- if (k == XK_L4) return "L4";
- if (k == XK_F15) return "F15";
- if (k == XK_L5) return "L5";
- if (k == XK_F16) return "F16";
- if (k == XK_L6) return "L6";
- if (k == XK_F17) return "F17";
- if (k == XK_L7) return "L7";
- if (k == XK_F18) return "F18";
- if (k == XK_L8) return "L8";
- if (k == XK_F19) return "F19";
- if (k == XK_L9) return "L9";
- if (k == XK_F20) return "F20";
- if (k == XK_L10) return "L10";
- if (k == XK_F21) return "F21";
- if (k == XK_R1) return "R1";
- if (k == XK_F22) return "F22";
- if (k == XK_R2) return "R2";
- if (k == XK_F23) return "F23";
- if (k == XK_R3) return "R3";
- if (k == XK_F24) return "F24";
- if (k == XK_R4) return "R4";
- if (k == XK_F25) return "F25";
- if (k == XK_R5) return "R5";
- if (k == XK_F26) return "F26";
- if (k == XK_R6) return "R6";
- if (k == XK_F27) return "F27";
- if (k == XK_R7) return "R7";
- if (k == XK_F28) return "F28";
- if (k == XK_R8) return "R8";
- if (k == XK_F29) return "F29";
- if (k == XK_R9) return "R9";
- if (k == XK_F30) return "F30";
- if (k == XK_R10) return "R10";
- if (k == XK_F31) return "F31";
- if (k == XK_R11) return "R11";
- if (k == XK_F32) return "F32";
- if (k == XK_R12) return "R12";
- if (k == XK_F33) return "F33";
- if (k == XK_R13) return "R13";
- if (k == XK_F34) return "F34";
- if (k == XK_R14) return "R14";
- if (k == XK_F35) return "F35";
- if (k == XK_R15) return "R15";
- if (k == XK_Shift_L) return "Shift_L";
- if (k == XK_Shift_R) return "Shift_R";
- if (k == XK_Control_L) return "Control_L";
- if (k == XK_Control_R) return "Control_R";
- if (k == XK_Caps_Lock) return "Caps_Lock";
- if (k == XK_Shift_Lock) return "Shift_Lock";
- if (k == XK_Meta_L) return "Meta_L";
- if (k == XK_Meta_R) return "Meta_R";
- if (k == XK_Alt_L) return "Alt_L";
- if (k == XK_Alt_R) return "Alt_R";
- if (k == XK_Super_L) return "Super_L";
- if (k == XK_Super_R) return "Super_R";
- if (k == XK_Hyper_L) return "Hyper_L";
- if (k == XK_Hyper_R) return "Hyper_R";
-#endif /* XK_MISCELLANY */
-#ifdef XK_XKB_KEYS
- if (k == XK_ISO_Lock) return "ISO_Lock";
- if (k == XK_ISO_Level2_Latch) return "ISO_Level2_Latch";
- if (k == XK_ISO_Level3_Shift) return "ISO_Level3_Shift";
- if (k == XK_ISO_Level3_Latch) return "ISO_Level3_Latch";
- if (k == XK_ISO_Level3_Lock) return "ISO_Level3_Lock";
- if (k == XK_ISO_Group_Shift) return "ISO_Group_Shift";
- if (k == XK_ISO_Group_Latch) return "ISO_Group_Latch";
- if (k == XK_ISO_Group_Lock) return "ISO_Group_Lock";
- if (k == XK_ISO_Next_Group) return "ISO_Next_Group";
- if (k == XK_ISO_Next_Group_Lock) return "ISO_Next_Group_Lock";
- if (k == XK_ISO_Prev_Group) return "ISO_Prev_Group";
- if (k == XK_ISO_Prev_Group_Lock) return "ISO_Prev_Group_Lock";
- if (k == XK_ISO_First_Group) return "ISO_First_Group";
- if (k == XK_ISO_First_Group_Lock) return "ISO_First_Group_Lock";
- if (k == XK_ISO_Last_Group) return "ISO_Last_Group";
- if (k == XK_ISO_Last_Group_Lock) return "ISO_Last_Group_Lock";
- if (k == XK_ISO_Left_Tab) return "ISO_Left_Tab";
- if (k == XK_ISO_Move_Line_Up) return "ISO_Move_Line_Up";
- if (k == XK_ISO_Move_Line_Down) return "ISO_Move_Line_Down";
- if (k == XK_ISO_Partial_Line_Up) return "ISO_Partial_Line_Up";
- if (k == XK_ISO_Partial_Line_Down) return "ISO_Partial_Line_Down";
- if (k == XK_ISO_Partial_Space_Left) return "ISO_Partial_Space_Left";
- if (k == XK_ISO_Partial_Space_Right) return "ISO_Partial_Space_Right";
- if (k == XK_ISO_Set_Margin_Left) return "ISO_Set_Margin_Left";
- if (k == XK_ISO_Set_Margin_Right) return "ISO_Set_Margin_Right";
- if (k == XK_ISO_Release_Margin_Left) return "ISO_Release_Margin_Left";
- if (k == XK_ISO_Release_Margin_Right) return "ISO_Release_Margin_Right";
- if (k == XK_ISO_Release_Both_Margins) return "ISO_Release_Both_Margins";
- if (k == XK_ISO_Fast_Cursor_Left) return "ISO_Fast_Cursor_Left";
- if (k == XK_ISO_Fast_Cursor_Right) return "ISO_Fast_Cursor_Right";
- if (k == XK_ISO_Fast_Cursor_Up) return "ISO_Fast_Cursor_Up";
- if (k == XK_ISO_Fast_Cursor_Down) return "ISO_Fast_Cursor_Down";
- if (k == XK_ISO_Continuous_Underline) return "ISO_Continuous_Underline";
- if (k == XK_ISO_Discontinuous_Underline) return "ISO_Discontinuous_Underline";
- if (k == XK_ISO_Emphasize) return "ISO_Emphasize";
- if (k == XK_ISO_Center_Object) return "ISO_Center_Object";
- if (k == XK_ISO_Enter) return "ISO_Enter";
- if (k == XK_dead_grave) return "dead_grave";
- if (k == XK_dead_acute) return "dead_acute";
- if (k == XK_dead_circumflex) return "dead_circumflex";
- if (k == XK_dead_tilde) return "dead_tilde";
- if (k == XK_dead_macron) return "dead_macron";
- if (k == XK_dead_breve) return "dead_breve";
- if (k == XK_dead_abovedot) return "dead_abovedot";
- if (k == XK_dead_diaeresis) return "dead_diaeresis";
- if (k == XK_dead_abovering) return "dead_abovering";
- if (k == XK_dead_doubleacute) return "dead_doubleacute";
- if (k == XK_dead_caron) return "dead_caron";
- if (k == XK_dead_cedilla) return "dead_cedilla";
- if (k == XK_dead_ogonek) return "dead_ogonek";
- if (k == XK_dead_iota) return "dead_iota";
- if (k == XK_dead_voiced_sound) return "dead_voiced_sound";
- if (k == XK_dead_semivoiced_sound) return "dead_semivoiced_sound";
- if (k == XK_dead_belowdot) return "dead_belowdot";
- if (k == XK_First_Virtual_Screen) return "First_Virtual_Screen";
- if (k == XK_Prev_Virtual_Screen) return "Prev_Virtual_Screen";
- if (k == XK_Next_Virtual_Screen) return "Next_Virtual_Screen";
- if (k == XK_Last_Virtual_Screen) return "Last_Virtual_Screen";
- if (k == XK_Terminate_Server) return "Terminate_Server";
- if (k == XK_AccessX_Enable) return "AccessX_Enable";
- if (k == XK_AccessX_Feedback_Enable) return "AccessX_Feedback_Enable";
- if (k == XK_RepeatKeys_Enable) return "RepeatKeys_Enable";
- if (k == XK_SlowKeys_Enable) return "SlowKeys_Enable";
- if (k == XK_BounceKeys_Enable) return "BounceKeys_Enable";
- if (k == XK_StickyKeys_Enable) return "StickyKeys_Enable";
- if (k == XK_MouseKeys_Enable) return "MouseKeys_Enable";
- if (k == XK_MouseKeys_Accel_Enable) return "MouseKeys_Accel_Enable";
- if (k == XK_Overlay1_Enable) return "Overlay1_Enable";
- if (k == XK_Overlay2_Enable) return "Overlay2_Enable";
- if (k == XK_AudibleBell_Enable) return "AudibleBell_Enable";
- if (k == XK_Pointer_Left) return "Pointer_Left";
- if (k == XK_Pointer_Right) return "Pointer_Right";
- if (k == XK_Pointer_Up) return "Pointer_Up";
- if (k == XK_Pointer_Down) return "Pointer_Down";
- if (k == XK_Pointer_UpLeft) return "Pointer_UpLeft";
- if (k == XK_Pointer_UpRight) return "Pointer_UpRight";
- if (k == XK_Pointer_DownLeft) return "Pointer_DownLeft";
- if (k == XK_Pointer_DownRight) return "Pointer_DownRight";
- if (k == XK_Pointer_Button_Dflt) return "Pointer_Button_Dflt";
- if (k == XK_Pointer_Button1) return "Pointer_Button1";
- if (k == XK_Pointer_Button2) return "Pointer_Button2";
- if (k == XK_Pointer_Button3) return "Pointer_Button3";
- if (k == XK_Pointer_Button4) return "Pointer_Button4";
- if (k == XK_Pointer_Button5) return "Pointer_Button5";
- if (k == XK_Pointer_DblClick_Dflt) return "Pointer_DblClick_Dflt";
- if (k == XK_Pointer_DblClick1) return "Pointer_DblClick1";
- if (k == XK_Pointer_DblClick2) return "Pointer_DblClick2";
- if (k == XK_Pointer_DblClick3) return "Pointer_DblClick3";
- if (k == XK_Pointer_DblClick4) return "Pointer_DblClick4";
- if (k == XK_Pointer_DblClick5) return "Pointer_DblClick5";
- if (k == XK_Pointer_Drag_Dflt) return "Pointer_Drag_Dflt";
- if (k == XK_Pointer_Drag1) return "Pointer_Drag1";
- if (k == XK_Pointer_Drag2) return "Pointer_Drag2";
- if (k == XK_Pointer_Drag3) return "Pointer_Drag3";
- if (k == XK_Pointer_Drag4) return "Pointer_Drag4";
- if (k == XK_Pointer_Drag5) return "Pointer_Drag5";
- if (k == XK_Pointer_EnableKeys) return "Pointer_EnableKeys";
- if (k == XK_Pointer_Accelerate) return "Pointer_Accelerate";
- if (k == XK_Pointer_DfltBtnNext) return "Pointer_DfltBtnNext";
- if (k == XK_Pointer_DfltBtnPrev) return "Pointer_DfltBtnPrev";
-#endif
-#ifdef XK_3270
- if (k == XK_3270_Duplicate) return "3270_Duplicate";
- if (k == XK_3270_FieldMark) return "3270_FieldMark";
- if (k == XK_3270_Right2) return "3270_Right2";
- if (k == XK_3270_Left2) return "3270_Left2";
- if (k == XK_3270_BackTab) return "3270_BackTab";
- if (k == XK_3270_EraseEOF) return "3270_EraseEOF";
- if (k == XK_3270_EraseInput) return "3270_EraseInput";
- if (k == XK_3270_Reset) return "3270_Reset";
- if (k == XK_3270_Quit) return "3270_Quit";
- if (k == XK_3270_PA1) return "3270_PA1";
- if (k == XK_3270_PA2) return "3270_PA2";
- if (k == XK_3270_PA3) return "3270_PA3";
- if (k == XK_3270_Test) return "3270_Test";
- if (k == XK_3270_Attn) return "3270_Attn";
- if (k == XK_3270_CursorBlink) return "3270_CursorBlink";
- if (k == XK_3270_AltCursor) return "3270_AltCursor";
- if (k == XK_3270_KeyClick) return "3270_KeyClick";
- if (k == XK_3270_Jump) return "3270_Jump";
- if (k == XK_3270_Ident) return "3270_Ident";
- if (k == XK_3270_Rule) return "3270_Rule";
- if (k == XK_3270_Copy) return "3270_Copy";
- if (k == XK_3270_Play) return "3270_Play";
- if (k == XK_3270_Setup) return "3270_Setup";
- if (k == XK_3270_Record) return "3270_Record";
- if (k == XK_3270_ChangeScreen) return "3270_ChangeScreen";
- if (k == XK_3270_DeleteWord) return "3270_DeleteWord";
- if (k == XK_3270_ExSelect) return "3270_ExSelect";
- if (k == XK_3270_CursorSelect) return "3270_CursorSelect";
- if (k == XK_3270_PrintScreen) return "3270_PrintScreen";
- if (k == XK_3270_Enter) return "3270_Enter";
-#endif
-#ifdef XK_LATIN1
- if (k == XK_space) return "space";
- if (k == XK_exclam) return "exclam";
- if (k == XK_quotedbl) return "quotedbl";
- if (k == XK_numbersign) return "numbersign";
- if (k == XK_dollar) return "dollar";
- if (k == XK_percent) return "percent";
- if (k == XK_ampersand) return "ampersand";
- if (k == XK_apostrophe) return "apostrophe";
- if (k == XK_quoteright) return "quoteright";
- if (k == XK_parenleft) return "parenleft";
- if (k == XK_parenright) return "parenright";
- if (k == XK_asterisk) return "asterisk";
- if (k == XK_plus) return "plus";
- if (k == XK_comma) return "comma";
- if (k == XK_minus) return "minus";
- if (k == XK_period) return "period";
- if (k == XK_slash) return "slash";
- if (k == XK_0) return "0";
- if (k == XK_1) return "1";
- if (k == XK_2) return "2";
- if (k == XK_3) return "3";
- if (k == XK_4) return "4";
- if (k == XK_5) return "5";
- if (k == XK_6) return "6";
- if (k == XK_7) return "7";
- if (k == XK_8) return "8";
- if (k == XK_9) return "9";
- if (k == XK_colon) return "colon";
- if (k == XK_semicolon) return "semicolon";
- if (k == XK_less) return "less";
- if (k == XK_equal) return "equal";
- if (k == XK_greater) return "greater";
- if (k == XK_question) return "question";
- if (k == XK_at) return "at";
- if (k == XK_A) return "A";
- if (k == XK_B) return "B";
- if (k == XK_C) return "C";
- if (k == XK_D) return "D";
- if (k == XK_E) return "E";
- if (k == XK_F) return "F";
- if (k == XK_G) return "G";
- if (k == XK_H) return "H";
- if (k == XK_I) return "I";
- if (k == XK_J) return "J";
- if (k == XK_K) return "K";
- if (k == XK_L) return "L";
- if (k == XK_M) return "M";
- if (k == XK_N) return "N";
- if (k == XK_O) return "O";
- if (k == XK_P) return "P";
- if (k == XK_Q) return "Q";
- if (k == XK_R) return "R";
- if (k == XK_S) return "S";
- if (k == XK_T) return "T";
- if (k == XK_U) return "U";
- if (k == XK_V) return "V";
- if (k == XK_W) return "W";
- if (k == XK_X) return "X";
- if (k == XK_Y) return "Y";
- if (k == XK_Z) return "Z";
- if (k == XK_bracketleft) return "bracketleft";
- if (k == XK_backslash) return "backslash";
- if (k == XK_bracketright) return "bracketright";
- if (k == XK_asciicircum) return "asciicircum";
- if (k == XK_underscore) return "underscore";
- if (k == XK_grave) return "grave";
- if (k == XK_quoteleft) return "quoteleft";
- if (k == XK_a) return "a";
- if (k == XK_b) return "b";
- if (k == XK_c) return "c";
- if (k == XK_d) return "d";
- if (k == XK_e) return "e";
- if (k == XK_f) return "f";
- if (k == XK_g) return "g";
- if (k == XK_h) return "h";
- if (k == XK_i) return "i";
- if (k == XK_j) return "j";
- if (k == XK_k) return "k";
- if (k == XK_l) return "l";
- if (k == XK_m) return "m";
- if (k == XK_n) return "n";
- if (k == XK_o) return "o";
- if (k == XK_p) return "p";
- if (k == XK_q) return "q";
- if (k == XK_r) return "r";
- if (k == XK_s) return "s";
- if (k == XK_t) return "t";
- if (k == XK_u) return "u";
- if (k == XK_v) return "v";
- if (k == XK_w) return "w";
- if (k == XK_x) return "x";
- if (k == XK_y) return "y";
- if (k == XK_z) return "z";
- if (k == XK_braceleft) return "braceleft";
- if (k == XK_bar) return "bar";
- if (k == XK_braceright) return "braceright";
- if (k == XK_asciitilde) return "asciitilde";
- if (k == XK_nobreakspace) return "nobreakspace";
- if (k == XK_exclamdown) return "exclamdown";
- if (k == XK_cent) return "cent";
- if (k == XK_sterling) return "sterling";
- if (k == XK_currency) return "currency";
- if (k == XK_yen) return "yen";
- if (k == XK_brokenbar) return "brokenbar";
- if (k == XK_section) return "section";
- if (k == XK_diaeresis) return "diaeresis";
- if (k == XK_copyright) return "copyright";
- if (k == XK_ordfeminine) return "ordfeminine";
- if (k == XK_guillemotleft) return "guillemotleft";
- if (k == XK_notsign) return "notsign";
- if (k == XK_hyphen) return "hyphen";
- if (k == XK_registered) return "registered";
- if (k == XK_macron) return "macron";
- if (k == XK_degree) return "degree";
- if (k == XK_plusminus) return "plusminus";
- if (k == XK_twosuperior) return "twosuperior";
- if (k == XK_threesuperior) return "threesuperior";
- if (k == XK_acute) return "acute";
- if (k == XK_mu) return "mu";
- if (k == XK_paragraph) return "paragraph";
- if (k == XK_periodcentered) return "periodcentered";
- if (k == XK_cedilla) return "cedilla";
- if (k == XK_onesuperior) return "onesuperior";
- if (k == XK_masculine) return "masculine";
- if (k == XK_guillemotright) return "guillemotright";
- if (k == XK_onequarter) return "onequarter";
- if (k == XK_onehalf) return "onehalf";
- if (k == XK_threequarters) return "threequarters";
- if (k == XK_questiondown) return "questiondown";
- if (k == XK_Agrave) return "Agrave";
- if (k == XK_Aacute) return "Aacute";
- if (k == XK_Acircumflex) return "Acircumflex";
- if (k == XK_Atilde) return "Atilde";
- if (k == XK_Adiaeresis) return "Adiaeresis";
- if (k == XK_Aring) return "Aring";
- if (k == XK_AE) return "AE";
- if (k == XK_Ccedilla) return "Ccedilla";
- if (k == XK_Egrave) return "Egrave";
- if (k == XK_Eacute) return "Eacute";
- if (k == XK_Ecircumflex) return "Ecircumflex";
- if (k == XK_Ediaeresis) return "Ediaeresis";
- if (k == XK_Igrave) return "Igrave";
- if (k == XK_Iacute) return "Iacute";
- if (k == XK_Icircumflex) return "Icircumflex";
- if (k == XK_Idiaeresis) return "Idiaeresis";
- if (k == XK_ETH) return "ETH";
- if (k == XK_Eth) return "Eth";
- if (k == XK_Ntilde) return "Ntilde";
- if (k == XK_Ograve) return "Ograve";
- if (k == XK_Oacute) return "Oacute";
- if (k == XK_Ocircumflex) return "Ocircumflex";
- if (k == XK_Otilde) return "Otilde";
- if (k == XK_Odiaeresis) return "Odiaeresis";
- if (k == XK_multiply) return "multiply";
- if (k == XK_Ooblique) return "Ooblique";
- if (k == XK_Ugrave) return "Ugrave";
- if (k == XK_Uacute) return "Uacute";
- if (k == XK_Ucircumflex) return "Ucircumflex";
- if (k == XK_Udiaeresis) return "Udiaeresis";
- if (k == XK_Yacute) return "Yacute";
- if (k == XK_THORN) return "THORN";
- if (k == XK_Thorn) return "Thorn";
- if (k == XK_ssharp) return "ssharp";
- if (k == XK_agrave) return "agrave";
- if (k == XK_aacute) return "aacute";
- if (k == XK_acircumflex) return "acircumflex";
- if (k == XK_atilde) return "atilde";
- if (k == XK_adiaeresis) return "adiaeresis";
- if (k == XK_aring) return "aring";
- if (k == XK_ae) return "ae";
- if (k == XK_ccedilla) return "ccedilla";
- if (k == XK_egrave) return "egrave";
- if (k == XK_eacute) return "eacute";
- if (k == XK_ecircumflex) return "ecircumflex";
- if (k == XK_ediaeresis) return "ediaeresis";
- if (k == XK_igrave) return "igrave";
- if (k == XK_iacute) return "iacute";
- if (k == XK_icircumflex) return "icircumflex";
- if (k == XK_idiaeresis) return "idiaeresis";
- if (k == XK_eth) return "eth";
- if (k == XK_ntilde) return "ntilde";
- if (k == XK_ograve) return "ograve";
- if (k == XK_oacute) return "oacute";
- if (k == XK_ocircumflex) return "ocircumflex";
- if (k == XK_otilde) return "otilde";
- if (k == XK_odiaeresis) return "odiaeresis";
- if (k == XK_division) return "division";
- if (k == XK_oslash) return "oslash";
- if (k == XK_ugrave) return "ugrave";
- if (k == XK_uacute) return "uacute";
- if (k == XK_ucircumflex) return "ucircumflex";
- if (k == XK_udiaeresis) return "udiaeresis";
- if (k == XK_yacute) return "yacute";
- if (k == XK_thorn) return "thorn";
- if (k == XK_ydiaeresis) return "ydiaeresis";
-#endif /* XK_LATIN1 */
-#ifdef XK_LATIN2
- if (k == XK_Aogonek) return "Aogonek";
- if (k == XK_breve) return "breve";
- if (k == XK_Lstroke) return "Lstroke";
- if (k == XK_Lcaron) return "Lcaron";
- if (k == XK_Sacute) return "Sacute";
- if (k == XK_Scaron) return "Scaron";
- if (k == XK_Scedilla) return "Scedilla";
- if (k == XK_Tcaron) return "Tcaron";
- if (k == XK_Zacute) return "Zacute";
- if (k == XK_Zcaron) return "Zcaron";
- if (k == XK_Zabovedot) return "Zabovedot";
- if (k == XK_aogonek) return "aogonek";
- if (k == XK_ogonek) return "ogonek";
- if (k == XK_lstroke) return "lstroke";
- if (k == XK_lcaron) return "lcaron";
- if (k == XK_sacute) return "sacute";
- if (k == XK_caron) return "caron";
- if (k == XK_scaron) return "scaron";
- if (k == XK_scedilla) return "scedilla";
- if (k == XK_tcaron) return "tcaron";
- if (k == XK_zacute) return "zacute";
- if (k == XK_doubleacute) return "doubleacute";
- if (k == XK_zcaron) return "zcaron";
- if (k == XK_zabovedot) return "zabovedot";
- if (k == XK_Racute) return "Racute";
- if (k == XK_Abreve) return "Abreve";
- if (k == XK_Lacute) return "Lacute";
- if (k == XK_Cacute) return "Cacute";
- if (k == XK_Ccaron) return "Ccaron";
- if (k == XK_Eogonek) return "Eogonek";
- if (k == XK_Ecaron) return "Ecaron";
- if (k == XK_Dcaron) return "Dcaron";
- if (k == XK_Dstroke) return "Dstroke";
- if (k == XK_Nacute) return "Nacute";
- if (k == XK_Ncaron) return "Ncaron";
- if (k == XK_Odoubleacute) return "Odoubleacute";
- if (k == XK_Rcaron) return "Rcaron";
- if (k == XK_Uring) return "Uring";
- if (k == XK_Udoubleacute) return "Udoubleacute";
- if (k == XK_Tcedilla) return "Tcedilla";
- if (k == XK_racute) return "racute";
- if (k == XK_abreve) return "abreve";
- if (k == XK_lacute) return "lacute";
- if (k == XK_cacute) return "cacute";
- if (k == XK_ccaron) return "ccaron";
- if (k == XK_eogonek) return "eogonek";
- if (k == XK_ecaron) return "ecaron";
- if (k == XK_dcaron) return "dcaron";
- if (k == XK_dstroke) return "dstroke";
- if (k == XK_nacute) return "nacute";
- if (k == XK_ncaron) return "ncaron";
- if (k == XK_odoubleacute) return "odoubleacute";
- if (k == XK_udoubleacute) return "udoubleacute";
- if (k == XK_rcaron) return "rcaron";
- if (k == XK_uring) return "uring";
- if (k == XK_tcedilla) return "tcedilla";
- if (k == XK_abovedot) return "abovedot";
-#endif /* XK_LATIN2 */
-#ifdef XK_LATIN3
- if (k == XK_Hstroke) return "Hstroke";
- if (k == XK_Hcircumflex) return "Hcircumflex";
- if (k == XK_Iabovedot) return "Iabovedot";
- if (k == XK_Gbreve) return "Gbreve";
- if (k == XK_Jcircumflex) return "Jcircumflex";
- if (k == XK_hstroke) return "hstroke";
- if (k == XK_hcircumflex) return "hcircumflex";
- if (k == XK_idotless) return "idotless";
- if (k == XK_gbreve) return "gbreve";
- if (k == XK_jcircumflex) return "jcircumflex";
- if (k == XK_Cabovedot) return "Cabovedot";
- if (k == XK_Ccircumflex) return "Ccircumflex";
- if (k == XK_Gabovedot) return "Gabovedot";
- if (k == XK_Gcircumflex) return "Gcircumflex";
- if (k == XK_Ubreve) return "Ubreve";
- if (k == XK_Scircumflex) return "Scircumflex";
- if (k == XK_cabovedot) return "cabovedot";
- if (k == XK_ccircumflex) return "ccircumflex";
- if (k == XK_gabovedot) return "gabovedot";
- if (k == XK_gcircumflex) return "gcircumflex";
- if (k == XK_ubreve) return "ubreve";
- if (k == XK_scircumflex) return "scircumflex";
-#endif /* XK_LATIN3 */
-#ifdef XK_LATIN4
- if (k == XK_kra) return "kra";
- if (k == XK_kappa) return "kappa";
- if (k == XK_Rcedilla) return "Rcedilla";
- if (k == XK_Itilde) return "Itilde";
- if (k == XK_Lcedilla) return "Lcedilla";
- if (k == XK_Emacron) return "Emacron";
- if (k == XK_Gcedilla) return "Gcedilla";
- if (k == XK_Tslash) return "Tslash";
- if (k == XK_rcedilla) return "rcedilla";
- if (k == XK_itilde) return "itilde";
- if (k == XK_lcedilla) return "lcedilla";
- if (k == XK_emacron) return "emacron";
- if (k == XK_gcedilla) return "gcedilla";
- if (k == XK_tslash) return "tslash";
- if (k == XK_ENG) return "ENG";
- if (k == XK_eng) return "eng";
- if (k == XK_Amacron) return "Amacron";
- if (k == XK_Iogonek) return "Iogonek";
- if (k == XK_Eabovedot) return "Eabovedot";
- if (k == XK_Imacron) return "Imacron";
- if (k == XK_Ncedilla) return "Ncedilla";
- if (k == XK_Omacron) return "Omacron";
- if (k == XK_Kcedilla) return "Kcedilla";
- if (k == XK_Uogonek) return "Uogonek";
- if (k == XK_Utilde) return "Utilde";
- if (k == XK_Umacron) return "Umacron";
- if (k == XK_amacron) return "amacron";
- if (k == XK_iogonek) return "iogonek";
- if (k == XK_eabovedot) return "eabovedot";
- if (k == XK_imacron) return "imacron";
- if (k == XK_ncedilla) return "ncedilla";
- if (k == XK_omacron) return "omacron";
- if (k == XK_kcedilla) return "kcedilla";
- if (k == XK_uogonek) return "uogonek";
- if (k == XK_utilde) return "utilde";
- if (k == XK_umacron) return "umacron";
-#endif /* XK_LATIN4 */
-#ifdef XK_KATAKANA
- if (k == XK_overline) return "overline";
- if (k == XK_kana_fullstop) return "kana_fullstop";
- if (k == XK_kana_openingbracket) return "kana_openingbracket";
- if (k == XK_kana_closingbracket) return "kana_closingbracket";
- if (k == XK_kana_comma) return "kana_comma";
- if (k == XK_kana_conjunctive) return "kana_conjunctive";
- if (k == XK_kana_middledot) return "kana_middledot";
- if (k == XK_kana_WO) return "kana_WO";
- if (k == XK_kana_a) return "kana_a";
- if (k == XK_kana_i) return "kana_i";
- if (k == XK_kana_u) return "kana_u";
- if (k == XK_kana_e) return "kana_e";
- if (k == XK_kana_o) return "kana_o";
- if (k == XK_kana_ya) return "kana_ya";
- if (k == XK_kana_yu) return "kana_yu";
- if (k == XK_kana_yo) return "kana_yo";
- if (k == XK_kana_tsu) return "kana_tsu";
- if (k == XK_kana_tu) return "kana_tu";
- if (k == XK_prolongedsound) return "prolongedsound";
- if (k == XK_kana_A) return "kana_A";
- if (k == XK_kana_I) return "kana_I";
- if (k == XK_kana_U) return "kana_U";
- if (k == XK_kana_E) return "kana_E";
- if (k == XK_kana_O) return "kana_O";
- if (k == XK_kana_KA) return "kana_KA";
- if (k == XK_kana_KI) return "kana_KI";
- if (k == XK_kana_KU) return "kana_KU";
- if (k == XK_kana_KE) return "kana_KE";
- if (k == XK_kana_KO) return "kana_KO";
- if (k == XK_kana_SA) return "kana_SA";
- if (k == XK_kana_SHI) return "kana_SHI";
- if (k == XK_kana_SU) return "kana_SU";
- if (k == XK_kana_SE) return "kana_SE";
- if (k == XK_kana_SO) return "kana_SO";
- if (k == XK_kana_TA) return "kana_TA";
- if (k == XK_kana_CHI) return "kana_CHI";
- if (k == XK_kana_TI) return "kana_TI";
- if (k == XK_kana_TSU) return "kana_TSU";
- if (k == XK_kana_TU) return "kana_TU";
- if (k == XK_kana_TE) return "kana_TE";
- if (k == XK_kana_TO) return "kana_TO";
- if (k == XK_kana_NA) return "kana_NA";
- if (k == XK_kana_NI) return "kana_NI";
- if (k == XK_kana_NU) return "kana_NU";
- if (k == XK_kana_NE) return "kana_NE";
- if (k == XK_kana_NO) return "kana_NO";
- if (k == XK_kana_HA) return "kana_HA";
- if (k == XK_kana_HI) return "kana_HI";
- if (k == XK_kana_FU) return "kana_FU";
- if (k == XK_kana_HU) return "kana_HU";
- if (k == XK_kana_HE) return "kana_HE";
- if (k == XK_kana_HO) return "kana_HO";
- if (k == XK_kana_MA) return "kana_MA";
- if (k == XK_kana_MI) return "kana_MI";
- if (k == XK_kana_MU) return "kana_MU";
- if (k == XK_kana_ME) return "kana_ME";
- if (k == XK_kana_MO) return "kana_MO";
- if (k == XK_kana_YA) return "kana_YA";
- if (k == XK_kana_YU) return "kana_YU";
- if (k == XK_kana_YO) return "kana_YO";
- if (k == XK_kana_RA) return "kana_RA";
- if (k == XK_kana_RI) return "kana_RI";
- if (k == XK_kana_RU) return "kana_RU";
- if (k == XK_kana_RE) return "kana_RE";
- if (k == XK_kana_RO) return "kana_RO";
- if (k == XK_kana_WA) return "kana_WA";
- if (k == XK_kana_N) return "kana_N";
- if (k == XK_voicedsound) return "voicedsound";
- if (k == XK_semivoicedsound) return "semivoicedsound";
- if (k == XK_kana_switch) return "kana_switch";
-#endif /* XK_KATAKANA */
-#ifdef XK_ARABIC
- if (k == XK_Arabic_comma) return "Arabic_comma";
- if (k == XK_Arabic_semicolon) return "Arabic_semicolon";
- if (k == XK_Arabic_question_mark) return "Arabic_question_mark";
- if (k == XK_Arabic_hamza) return "Arabic_hamza";
- if (k == XK_Arabic_maddaonalef) return "Arabic_maddaonalef";
- if (k == XK_Arabic_hamzaonalef) return "Arabic_hamzaonalef";
- if (k == XK_Arabic_hamzaonwaw) return "Arabic_hamzaonwaw";
- if (k == XK_Arabic_hamzaunderalef) return "Arabic_hamzaunderalef";
- if (k == XK_Arabic_hamzaonyeh) return "Arabic_hamzaonyeh";
- if (k == XK_Arabic_alef) return "Arabic_alef";
- if (k == XK_Arabic_beh) return "Arabic_beh";
- if (k == XK_Arabic_tehmarbuta) return "Arabic_tehmarbuta";
- if (k == XK_Arabic_teh) return "Arabic_teh";
- if (k == XK_Arabic_theh) return "Arabic_theh";
- if (k == XK_Arabic_jeem) return "Arabic_jeem";
- if (k == XK_Arabic_hah) return "Arabic_hah";
- if (k == XK_Arabic_khah) return "Arabic_khah";
- if (k == XK_Arabic_dal) return "Arabic_dal";
- if (k == XK_Arabic_thal) return "Arabic_thal";
- if (k == XK_Arabic_ra) return "Arabic_ra";
- if (k == XK_Arabic_zain) return "Arabic_zain";
- if (k == XK_Arabic_seen) return "Arabic_seen";
- if (k == XK_Arabic_sheen) return "Arabic_sheen";
- if (k == XK_Arabic_sad) return "Arabic_sad";
- if (k == XK_Arabic_dad) return "Arabic_dad";
- if (k == XK_Arabic_tah) return "Arabic_tah";
- if (k == XK_Arabic_zah) return "Arabic_zah";
- if (k == XK_Arabic_ain) return "Arabic_ain";
- if (k == XK_Arabic_ghain) return "Arabic_ghain";
- if (k == XK_Arabic_tatweel) return "Arabic_tatweel";
- if (k == XK_Arabic_feh) return "Arabic_feh";
- if (k == XK_Arabic_qaf) return "Arabic_qaf";
- if (k == XK_Arabic_kaf) return "Arabic_kaf";
- if (k == XK_Arabic_lam) return "Arabic_lam";
- if (k == XK_Arabic_meem) return "Arabic_meem";
- if (k == XK_Arabic_noon) return "Arabic_noon";
- if (k == XK_Arabic_ha) return "Arabic_ha";
- if (k == XK_Arabic_heh) return "Arabic_heh";
- if (k == XK_Arabic_waw) return "Arabic_waw";
- if (k == XK_Arabic_alefmaksura) return "Arabic_alefmaksura";
- if (k == XK_Arabic_yeh) return "Arabic_yeh";
- if (k == XK_Arabic_fathatan) return "Arabic_fathatan";
- if (k == XK_Arabic_dammatan) return "Arabic_dammatan";
- if (k == XK_Arabic_kasratan) return "Arabic_kasratan";
- if (k == XK_Arabic_fatha) return "Arabic_fatha";
- if (k == XK_Arabic_damma) return "Arabic_damma";
- if (k == XK_Arabic_kasra) return "Arabic_kasra";
- if (k == XK_Arabic_shadda) return "Arabic_shadda";
- if (k == XK_Arabic_sukun) return "Arabic_sukun";
- if (k == XK_Arabic_switch) return "Arabic_switch";
-#endif /* XK_ARABIC */
-#ifdef XK_CYRILLIC
- if (k == XK_Serbian_dje) return "Serbian_dje";
- if (k == XK_Macedonia_gje) return "Macedonia_gje";
- if (k == XK_Cyrillic_io) return "Cyrillic_io";
- if (k == XK_Ukrainian_ie) return "Ukrainian_ie";
- if (k == XK_Ukranian_je) return "Ukranian_je";
- if (k == XK_Macedonia_dse) return "Macedonia_dse";
- if (k == XK_Ukrainian_i) return "Ukrainian_i";
- if (k == XK_Ukranian_i) return "Ukranian_i";
- if (k == XK_Ukrainian_yi) return "Ukrainian_yi";
- if (k == XK_Ukranian_yi) return "Ukranian_yi";
- if (k == XK_Cyrillic_je) return "Cyrillic_je";
- if (k == XK_Serbian_je) return "Serbian_je";
- if (k == XK_Cyrillic_lje) return "Cyrillic_lje";
- if (k == XK_Serbian_lje) return "Serbian_lje";
- if (k == XK_Cyrillic_nje) return "Cyrillic_nje";
- if (k == XK_Serbian_nje) return "Serbian_nje";
- if (k == XK_Serbian_tshe) return "Serbian_tshe";
- if (k == XK_Macedonia_kje) return "Macedonia_kje";
- if (k == XK_Byelorussian_shortu) return "Byelorussian_shortu";
- if (k == XK_Cyrillic_dzhe) return "Cyrillic_dzhe";
- if (k == XK_Serbian_dze) return "Serbian_dze";
- if (k == XK_numerosign) return "numerosign";
- if (k == XK_Serbian_DJE) return "Serbian_DJE";
- if (k == XK_Macedonia_GJE) return "Macedonia_GJE";
- if (k == XK_Cyrillic_IO) return "Cyrillic_IO";
- if (k == XK_Ukrainian_IE) return "Ukrainian_IE";
- if (k == XK_Ukranian_JE) return "Ukranian_JE";
- if (k == XK_Macedonia_DSE) return "Macedonia_DSE";
- if (k == XK_Ukrainian_I) return "Ukrainian_I";
- if (k == XK_Ukranian_I) return "Ukranian_I";
- if (k == XK_Ukrainian_YI) return "Ukrainian_YI";
- if (k == XK_Ukranian_YI) return "Ukranian_YI";
- if (k == XK_Cyrillic_JE) return "Cyrillic_JE";
- if (k == XK_Serbian_JE) return "Serbian_JE";
- if (k == XK_Cyrillic_LJE) return "Cyrillic_LJE";
- if (k == XK_Serbian_LJE) return "Serbian_LJE";
- if (k == XK_Cyrillic_NJE) return "Cyrillic_NJE";
- if (k == XK_Serbian_NJE) return "Serbian_NJE";
- if (k == XK_Serbian_TSHE) return "Serbian_TSHE";
- if (k == XK_Macedonia_KJE) return "Macedonia_KJE";
- if (k == XK_Byelorussian_SHORTU) return "Byelorussian_SHORTU";
- if (k == XK_Cyrillic_DZHE) return "Cyrillic_DZHE";
- if (k == XK_Serbian_DZE) return "Serbian_DZE";
- if (k == XK_Cyrillic_yu) return "Cyrillic_yu";
- if (k == XK_Cyrillic_a) return "Cyrillic_a";
- if (k == XK_Cyrillic_be) return "Cyrillic_be";
- if (k == XK_Cyrillic_tse) return "Cyrillic_tse";
- if (k == XK_Cyrillic_de) return "Cyrillic_de";
- if (k == XK_Cyrillic_ie) return "Cyrillic_ie";
- if (k == XK_Cyrillic_ef) return "Cyrillic_ef";
- if (k == XK_Cyrillic_ghe) return "Cyrillic_ghe";
- if (k == XK_Cyrillic_ha) return "Cyrillic_ha";
- if (k == XK_Cyrillic_i) return "Cyrillic_i";
- if (k == XK_Cyrillic_shorti) return "Cyrillic_shorti";
- if (k == XK_Cyrillic_ka) return "Cyrillic_ka";
- if (k == XK_Cyrillic_el) return "Cyrillic_el";
- if (k == XK_Cyrillic_em) return "Cyrillic_em";
- if (k == XK_Cyrillic_en) return "Cyrillic_en";
- if (k == XK_Cyrillic_o) return "Cyrillic_o";
- if (k == XK_Cyrillic_pe) return "Cyrillic_pe";
- if (k == XK_Cyrillic_ya) return "Cyrillic_ya";
- if (k == XK_Cyrillic_er) return "Cyrillic_er";
- if (k == XK_Cyrillic_es) return "Cyrillic_es";
- if (k == XK_Cyrillic_te) return "Cyrillic_te";
- if (k == XK_Cyrillic_u) return "Cyrillic_u";
- if (k == XK_Cyrillic_zhe) return "Cyrillic_zhe";
- if (k == XK_Cyrillic_ve) return "Cyrillic_ve";
- if (k == XK_Cyrillic_softsign) return "Cyrillic_softsign";
- if (k == XK_Cyrillic_yeru) return "Cyrillic_yeru";
- if (k == XK_Cyrillic_ze) return "Cyrillic_ze";
- if (k == XK_Cyrillic_sha) return "Cyrillic_sha";
- if (k == XK_Cyrillic_e) return "Cyrillic_e";
- if (k == XK_Cyrillic_shcha) return "Cyrillic_shcha";
- if (k == XK_Cyrillic_che) return "Cyrillic_che";
- if (k == XK_Cyrillic_hardsign) return "Cyrillic_hardsign";
- if (k == XK_Cyrillic_YU) return "Cyrillic_YU";
- if (k == XK_Cyrillic_A) return "Cyrillic_A";
- if (k == XK_Cyrillic_BE) return "Cyrillic_BE";
- if (k == XK_Cyrillic_TSE) return "Cyrillic_TSE";
- if (k == XK_Cyrillic_DE) return "Cyrillic_DE";
- if (k == XK_Cyrillic_IE) return "Cyrillic_IE";
- if (k == XK_Cyrillic_EF) return "Cyrillic_EF";
- if (k == XK_Cyrillic_GHE) return "Cyrillic_GHE";
- if (k == XK_Cyrillic_HA) return "Cyrillic_HA";
- if (k == XK_Cyrillic_I) return "Cyrillic_I";
- if (k == XK_Cyrillic_SHORTI) return "Cyrillic_SHORTI";
- if (k == XK_Cyrillic_KA) return "Cyrillic_KA";
- if (k == XK_Cyrillic_EL) return "Cyrillic_EL";
- if (k == XK_Cyrillic_EM) return "Cyrillic_EM";
- if (k == XK_Cyrillic_EN) return "Cyrillic_EN";
- if (k == XK_Cyrillic_O) return "Cyrillic_O";
- if (k == XK_Cyrillic_PE) return "Cyrillic_PE";
- if (k == XK_Cyrillic_YA) return "Cyrillic_YA";
- if (k == XK_Cyrillic_ER) return "Cyrillic_ER";
- if (k == XK_Cyrillic_ES) return "Cyrillic_ES";
- if (k == XK_Cyrillic_TE) return "Cyrillic_TE";
- if (k == XK_Cyrillic_U) return "Cyrillic_U";
- if (k == XK_Cyrillic_ZHE) return "Cyrillic_ZHE";
- if (k == XK_Cyrillic_VE) return "Cyrillic_VE";
- if (k == XK_Cyrillic_SOFTSIGN) return "Cyrillic_SOFTSIGN";
- if (k == XK_Cyrillic_YERU) return "Cyrillic_YERU";
- if (k == XK_Cyrillic_ZE) return "Cyrillic_ZE";
- if (k == XK_Cyrillic_SHA) return "Cyrillic_SHA";
- if (k == XK_Cyrillic_E) return "Cyrillic_E";
- if (k == XK_Cyrillic_SHCHA) return "Cyrillic_SHCHA";
- if (k == XK_Cyrillic_CHE) return "Cyrillic_CHE";
- if (k == XK_Cyrillic_HARDSIGN) return "Cyrillic_HARDSIGN";
-#endif /* XK_CYRILLIC */
-#ifdef XK_GREEK
- if (k == XK_Greek_ALPHAaccent) return "Greek_ALPHAaccent";
- if (k == XK_Greek_EPSILONaccent) return "Greek_EPSILONaccent";
- if (k == XK_Greek_ETAaccent) return "Greek_ETAaccent";
- if (k == XK_Greek_IOTAaccent) return "Greek_IOTAaccent";
- if (k == XK_Greek_IOTAdieresis) return "Greek_IOTAdieresis";
- if (k == XK_Greek_OMICRONaccent) return "Greek_OMICRONaccent";
- if (k == XK_Greek_UPSILONaccent) return "Greek_UPSILONaccent";
- if (k == XK_Greek_UPSILONdieresis) return "Greek_UPSILONdieresis";
- if (k == XK_Greek_OMEGAaccent) return "Greek_OMEGAaccent";
- if (k == XK_Greek_accentdieresis) return "Greek_accentdieresis";
- if (k == XK_Greek_horizbar) return "Greek_horizbar";
- if (k == XK_Greek_alphaaccent) return "Greek_alphaaccent";
- if (k == XK_Greek_epsilonaccent) return "Greek_epsilonaccent";
- if (k == XK_Greek_etaaccent) return "Greek_etaaccent";
- if (k == XK_Greek_iotaaccent) return "Greek_iotaaccent";
- if (k == XK_Greek_iotadieresis) return "Greek_iotadieresis";
- if (k == XK_Greek_iotaaccentdieresis) return "Greek_iotaaccentdieresis";
- if (k == XK_Greek_omicronaccent) return "Greek_omicronaccent";
- if (k == XK_Greek_upsilonaccent) return "Greek_upsilonaccent";
- if (k == XK_Greek_upsilondieresis) return "Greek_upsilondieresis";
- if (k == XK_Greek_upsilonaccentdieresis) return "Greek_upsilonaccentdieresis";
- if (k == XK_Greek_omegaaccent) return "Greek_omegaaccent";
- if (k == XK_Greek_ALPHA) return "Greek_ALPHA";
- if (k == XK_Greek_BETA) return "Greek_BETA";
- if (k == XK_Greek_GAMMA) return "Greek_GAMMA";
- if (k == XK_Greek_DELTA) return "Greek_DELTA";
- if (k == XK_Greek_EPSILON) return "Greek_EPSILON";
- if (k == XK_Greek_ZETA) return "Greek_ZETA";
- if (k == XK_Greek_ETA) return "Greek_ETA";
- if (k == XK_Greek_THETA) return "Greek_THETA";
- if (k == XK_Greek_IOTA) return "Greek_IOTA";
- if (k == XK_Greek_KAPPA) return "Greek_KAPPA";
- if (k == XK_Greek_LAMDA) return "Greek_LAMDA";
- if (k == XK_Greek_LAMBDA) return "Greek_LAMBDA";
- if (k == XK_Greek_MU) return "Greek_MU";
- if (k == XK_Greek_NU) return "Greek_NU";
- if (k == XK_Greek_XI) return "Greek_XI";
- if (k == XK_Greek_OMICRON) return "Greek_OMICRON";
- if (k == XK_Greek_PI) return "Greek_PI";
- if (k == XK_Greek_RHO) return "Greek_RHO";
- if (k == XK_Greek_SIGMA) return "Greek_SIGMA";
- if (k == XK_Greek_TAU) return "Greek_TAU";
- if (k == XK_Greek_UPSILON) return "Greek_UPSILON";
- if (k == XK_Greek_PHI) return "Greek_PHI";
- if (k == XK_Greek_CHI) return "Greek_CHI";
- if (k == XK_Greek_PSI) return "Greek_PSI";
- if (k == XK_Greek_OMEGA) return "Greek_OMEGA";
- if (k == XK_Greek_alpha) return "Greek_alpha";
- if (k == XK_Greek_beta) return "Greek_beta";
- if (k == XK_Greek_gamma) return "Greek_gamma";
- if (k == XK_Greek_delta) return "Greek_delta";
- if (k == XK_Greek_epsilon) return "Greek_epsilon";
- if (k == XK_Greek_zeta) return "Greek_zeta";
- if (k == XK_Greek_eta) return "Greek_eta";
- if (k == XK_Greek_theta) return "Greek_theta";
- if (k == XK_Greek_iota) return "Greek_iota";
- if (k == XK_Greek_kappa) return "Greek_kappa";
- if (k == XK_Greek_lamda) return "Greek_lamda";
- if (k == XK_Greek_lambda) return "Greek_lambda";
- if (k == XK_Greek_mu) return "Greek_mu";
- if (k == XK_Greek_nu) return "Greek_nu";
- if (k == XK_Greek_xi) return "Greek_xi";
- if (k == XK_Greek_omicron) return "Greek_omicron";
- if (k == XK_Greek_pi) return "Greek_pi";
- if (k == XK_Greek_rho) return "Greek_rho";
- if (k == XK_Greek_sigma) return "Greek_sigma";
- if (k == XK_Greek_finalsmallsigma) return "Greek_finalsmallsigma";
- if (k == XK_Greek_tau) return "Greek_tau";
- if (k == XK_Greek_upsilon) return "Greek_upsilon";
- if (k == XK_Greek_phi) return "Greek_phi";
- if (k == XK_Greek_chi) return "Greek_chi";
- if (k == XK_Greek_psi) return "Greek_psi";
- if (k == XK_Greek_omega) return "Greek_omega";
- if (k == XK_Greek_switch) return "Greek_switch";
-#endif /* XK_GREEK */
-#ifdef XK_TECHNICAL
- if (k == XK_leftradical) return "leftradical";
- if (k == XK_topleftradical) return "topleftradical";
- if (k == XK_horizconnector) return "horizconnector";
- if (k == XK_topintegral) return "topintegral";
- if (k == XK_botintegral) return "botintegral";
- if (k == XK_vertconnector) return "vertconnector";
- if (k == XK_topleftsqbracket) return "topleftsqbracket";
- if (k == XK_botleftsqbracket) return "botleftsqbracket";
- if (k == XK_toprightsqbracket) return "toprightsqbracket";
- if (k == XK_botrightsqbracket) return "botrightsqbracket";
- if (k == XK_topleftparens) return "topleftparens";
- if (k == XK_botleftparens) return "botleftparens";
- if (k == XK_toprightparens) return "toprightparens";
- if (k == XK_botrightparens) return "botrightparens";
- if (k == XK_leftmiddlecurlybrace) return "leftmiddlecurlybrace";
- if (k == XK_rightmiddlecurlybrace) return "rightmiddlecurlybrace";
- if (k == XK_topleftsummation) return "topleftsummation";
- if (k == XK_botleftsummation) return "botleftsummation";
- if (k == XK_topvertsummationconnector) return "topvertsummationconnector";
- if (k == XK_botvertsummationconnector) return "botvertsummationconnector";
- if (k == XK_toprightsummation) return "toprightsummation";
- if (k == XK_botrightsummation) return "botrightsummation";
- if (k == XK_rightmiddlesummation) return "rightmiddlesummation";
- if (k == XK_lessthanequal) return "lessthanequal";
- if (k == XK_notequal) return "notequal";
- if (k == XK_greaterthanequal) return "greaterthanequal";
- if (k == XK_integral) return "integral";
- if (k == XK_therefore) return "therefore";
- if (k == XK_variation) return "variation";
- if (k == XK_infinity) return "infinity";
- if (k == XK_nabla) return "nabla";
- if (k == XK_approximate) return "approximate";
- if (k == XK_similarequal) return "similarequal";
- if (k == XK_ifonlyif) return "ifonlyif";
- if (k == XK_implies) return "implies";
- if (k == XK_identical) return "identical";
- if (k == XK_radical) return "radical";
- if (k == XK_includedin) return "includedin";
- if (k == XK_includes) return "includes";
- if (k == XK_intersection) return "intersection";
- if (k == XK_union) return "union";
- if (k == XK_logicaland) return "logicaland";
- if (k == XK_logicalor) return "logicalor";
- if (k == XK_partialderivative) return "partialderivative";
- if (k == XK_function) return "function";
- if (k == XK_leftarrow) return "leftarrow";
- if (k == XK_uparrow) return "uparrow";
- if (k == XK_rightarrow) return "rightarrow";
- if (k == XK_downarrow) return "downarrow";
-#endif /* XK_TECHNICAL */
-#ifdef XK_SPECIAL
- if (k == XK_blank) return "blank";
- if (k == XK_soliddiamond) return "soliddiamond";
- if (k == XK_checkerboard) return "checkerboard";
- if (k == XK_ht) return "ht";
- if (k == XK_ff) return "ff";
- if (k == XK_cr) return "cr";
- if (k == XK_lf) return "lf";
- if (k == XK_nl) return "nl";
- if (k == XK_vt) return "vt";
- if (k == XK_lowrightcorner) return "lowrightcorner";
- if (k == XK_uprightcorner) return "uprightcorner";
- if (k == XK_upleftcorner) return "upleftcorner";
- if (k == XK_lowleftcorner) return "lowleftcorner";
- if (k == XK_crossinglines) return "crossinglines";
- if (k == XK_horizlinescan1) return "horizlinescan1";
- if (k == XK_horizlinescan3) return "horizlinescan3";
- if (k == XK_horizlinescan5) return "horizlinescan5";
- if (k == XK_horizlinescan7) return "horizlinescan7";
- if (k == XK_horizlinescan9) return "horizlinescan9";
- if (k == XK_leftt) return "leftt";
- if (k == XK_rightt) return "rightt";
- if (k == XK_bott) return "bott";
- if (k == XK_topt) return "topt";
- if (k == XK_vertbar) return "vertbar";
-#endif /* XK_SPECIAL */
-#ifdef XK_PUBLISHING
- if (k == XK_emspace) return "emspace";
- if (k == XK_enspace) return "enspace";
- if (k == XK_em3space) return "em3space";
- if (k == XK_em4space) return "em4space";
- if (k == XK_digitspace) return "digitspace";
- if (k == XK_punctspace) return "punctspace";
- if (k == XK_thinspace) return "thinspace";
- if (k == XK_hairspace) return "hairspace";
- if (k == XK_emdash) return "emdash";
- if (k == XK_endash) return "endash";
- if (k == XK_signifblank) return "signifblank";
- if (k == XK_ellipsis) return "ellipsis";
- if (k == XK_doubbaselinedot) return "doubbaselinedot";
- if (k == XK_onethird) return "onethird";
- if (k == XK_twothirds) return "twothirds";
- if (k == XK_onefifth) return "onefifth";
- if (k == XK_twofifths) return "twofifths";
- if (k == XK_threefifths) return "threefifths";
- if (k == XK_fourfifths) return "fourfifths";
- if (k == XK_onesixth) return "onesixth";
- if (k == XK_fivesixths) return "fivesixths";
- if (k == XK_careof) return "careof";
- if (k == XK_figdash) return "figdash";
- if (k == XK_leftanglebracket) return "leftanglebracket";
- if (k == XK_decimalpoint) return "decimalpoint";
- if (k == XK_rightanglebracket) return "rightanglebracket";
- if (k == XK_marker) return "marker";
- if (k == XK_oneeighth) return "oneeighth";
- if (k == XK_threeeighths) return "threeeighths";
- if (k == XK_fiveeighths) return "fiveeighths";
- if (k == XK_seveneighths) return "seveneighths";
- if (k == XK_trademark) return "trademark";
- if (k == XK_signaturemark) return "signaturemark";
- if (k == XK_trademarkincircle) return "trademarkincircle";
- if (k == XK_leftopentriangle) return "leftopentriangle";
- if (k == XK_rightopentriangle) return "rightopentriangle";
- if (k == XK_emopencircle) return "emopencircle";
- if (k == XK_emopenrectangle) return "emopenrectangle";
- if (k == XK_leftsinglequotemark) return "leftsinglequotemark";
- if (k == XK_rightsinglequotemark) return "rightsinglequotemark";
- if (k == XK_leftdoublequotemark) return "leftdoublequotemark";
- if (k == XK_rightdoublequotemark) return "rightdoublequotemark";
- if (k == XK_prescription) return "prescription";
- if (k == XK_minutes) return "minutes";
- if (k == XK_seconds) return "seconds";
- if (k == XK_latincross) return "latincross";
- if (k == XK_hexagram) return "hexagram";
- if (k == XK_filledrectbullet) return "filledrectbullet";
- if (k == XK_filledlefttribullet) return "filledlefttribullet";
- if (k == XK_filledrighttribullet) return "filledrighttribullet";
- if (k == XK_emfilledcircle) return "emfilledcircle";
- if (k == XK_emfilledrect) return "emfilledrect";
- if (k == XK_enopencircbullet) return "enopencircbullet";
- if (k == XK_enopensquarebullet) return "enopensquarebullet";
- if (k == XK_openrectbullet) return "openrectbullet";
- if (k == XK_opentribulletup) return "opentribulletup";
- if (k == XK_opentribulletdown) return "opentribulletdown";
- if (k == XK_openstar) return "openstar";
- if (k == XK_enfilledcircbullet) return "enfilledcircbullet";
- if (k == XK_enfilledsqbullet) return "enfilledsqbullet";
- if (k == XK_filledtribulletup) return "filledtribulletup";
- if (k == XK_filledtribulletdown) return "filledtribulletdown";
- if (k == XK_leftpointer) return "leftpointer";
- if (k == XK_rightpointer) return "rightpointer";
- if (k == XK_club) return "club";
- if (k == XK_diamond) return "diamond";
- if (k == XK_heart) return "heart";
- if (k == XK_maltesecross) return "maltesecross";
- if (k == XK_dagger) return "dagger";
- if (k == XK_doubledagger) return "doubledagger";
- if (k == XK_checkmark) return "checkmark";
- if (k == XK_ballotcross) return "ballotcross";
- if (k == XK_musicalsharp) return "musicalsharp";
- if (k == XK_musicalflat) return "musicalflat";
- if (k == XK_malesymbol) return "malesymbol";
- if (k == XK_femalesymbol) return "femalesymbol";
- if (k == XK_telephone) return "telephone";
- if (k == XK_telephonerecorder) return "telephonerecorder";
- if (k == XK_phonographcopyright) return "phonographcopyright";
- if (k == XK_caret) return "caret";
- if (k == XK_singlelowquotemark) return "singlelowquotemark";
- if (k == XK_doublelowquotemark) return "doublelowquotemark";
- if (k == XK_cursor) return "cursor";
-#endif /* XK_PUBLISHING */
-#ifdef XK_APL
- if (k == XK_leftcaret) return "leftcaret";
- if (k == XK_rightcaret) return "rightcaret";
- if (k == XK_downcaret) return "downcaret";
- if (k == XK_upcaret) return "upcaret";
- if (k == XK_overbar) return "overbar";
- if (k == XK_downtack) return "downtack";
- if (k == XK_upshoe) return "upshoe";
- if (k == XK_downstile) return "downstile";
- if (k == XK_underbar) return "underbar";
- if (k == XK_jot) return "jot";
- if (k == XK_quad) return "quad";
- if (k == XK_uptack) return "uptack";
- if (k == XK_circle) return "circle";
- if (k == XK_upstile) return "upstile";
- if (k == XK_downshoe) return "downshoe";
- if (k == XK_rightshoe) return "rightshoe";
- if (k == XK_leftshoe) return "leftshoe";
- if (k == XK_lefttack) return "lefttack";
- if (k == XK_righttack) return "righttack";
-#endif /* XK_APL */
-#ifdef XK_HEBREW
- if (k == XK_hebrew_doublelowline) return "hebrew_doublelowline";
- if (k == XK_hebrew_aleph) return "hebrew_aleph";
- if (k == XK_hebrew_bet) return "hebrew_bet";
- if (k == XK_hebrew_beth) return "hebrew_beth";
- if (k == XK_hebrew_gimel) return "hebrew_gimel";
- if (k == XK_hebrew_gimmel) return "hebrew_gimmel";
- if (k == XK_hebrew_dalet) return "hebrew_dalet";
- if (k == XK_hebrew_daleth) return "hebrew_daleth";
- if (k == XK_hebrew_he) return "hebrew_he";
- if (k == XK_hebrew_waw) return "hebrew_waw";
- if (k == XK_hebrew_zain) return "hebrew_zain";
- if (k == XK_hebrew_zayin) return "hebrew_zayin";
- if (k == XK_hebrew_chet) return "hebrew_chet";
- if (k == XK_hebrew_het) return "hebrew_het";
- if (k == XK_hebrew_tet) return "hebrew_tet";
- if (k == XK_hebrew_teth) return "hebrew_teth";
- if (k == XK_hebrew_yod) return "hebrew_yod";
- if (k == XK_hebrew_finalkaph) return "hebrew_finalkaph";
- if (k == XK_hebrew_kaph) return "hebrew_kaph";
- if (k == XK_hebrew_lamed) return "hebrew_lamed";
- if (k == XK_hebrew_finalmem) return "hebrew_finalmem";
- if (k == XK_hebrew_mem) return "hebrew_mem";
- if (k == XK_hebrew_finalnun) return "hebrew_finalnun";
- if (k == XK_hebrew_nun) return "hebrew_nun";
- if (k == XK_hebrew_samech) return "hebrew_samech";
- if (k == XK_hebrew_samekh) return "hebrew_samekh";
- if (k == XK_hebrew_ayin) return "hebrew_ayin";
- if (k == XK_hebrew_finalpe) return "hebrew_finalpe";
- if (k == XK_hebrew_pe) return "hebrew_pe";
- if (k == XK_hebrew_finalzade) return "hebrew_finalzade";
- if (k == XK_hebrew_finalzadi) return "hebrew_finalzadi";
- if (k == XK_hebrew_zade) return "hebrew_zade";
- if (k == XK_hebrew_zadi) return "hebrew_zadi";
- if (k == XK_hebrew_qoph) return "hebrew_qoph";
- if (k == XK_hebrew_kuf) return "hebrew_kuf";
- if (k == XK_hebrew_resh) return "hebrew_resh";
- if (k == XK_hebrew_shin) return "hebrew_shin";
- if (k == XK_hebrew_taw) return "hebrew_taw";
- if (k == XK_hebrew_taf) return "hebrew_taf";
- if (k == XK_Hebrew_switch) return "Hebrew_switch";
-#endif /* XK_HEBREW */
-#ifdef XK_THAI
- if (k == XK_Thai_kokai) return "Thai_kokai";
- if (k == XK_Thai_khokhai) return "Thai_khokhai";
- if (k == XK_Thai_khokhuat) return "Thai_khokhuat";
- if (k == XK_Thai_khokhwai) return "Thai_khokhwai";
- if (k == XK_Thai_khokhon) return "Thai_khokhon";
- if (k == XK_Thai_khorakhang) return "Thai_khorakhang";
- if (k == XK_Thai_ngongu) return "Thai_ngongu";
- if (k == XK_Thai_chochan) return "Thai_chochan";
- if (k == XK_Thai_choching) return "Thai_choching";
- if (k == XK_Thai_chochang) return "Thai_chochang";
- if (k == XK_Thai_soso) return "Thai_soso";
- if (k == XK_Thai_chochoe) return "Thai_chochoe";
- if (k == XK_Thai_yoying) return "Thai_yoying";
- if (k == XK_Thai_dochada) return "Thai_dochada";
- if (k == XK_Thai_topatak) return "Thai_topatak";
- if (k == XK_Thai_thothan) return "Thai_thothan";
- if (k == XK_Thai_thonangmontho) return "Thai_thonangmontho";
- if (k == XK_Thai_thophuthao) return "Thai_thophuthao";
- if (k == XK_Thai_nonen) return "Thai_nonen";
- if (k == XK_Thai_dodek) return "Thai_dodek";
- if (k == XK_Thai_totao) return "Thai_totao";
- if (k == XK_Thai_thothung) return "Thai_thothung";
- if (k == XK_Thai_thothahan) return "Thai_thothahan";
- if (k == XK_Thai_thothong) return "Thai_thothong";
- if (k == XK_Thai_nonu) return "Thai_nonu";
- if (k == XK_Thai_bobaimai) return "Thai_bobaimai";
- if (k == XK_Thai_popla) return "Thai_popla";
- if (k == XK_Thai_phophung) return "Thai_phophung";
- if (k == XK_Thai_fofa) return "Thai_fofa";
- if (k == XK_Thai_phophan) return "Thai_phophan";
- if (k == XK_Thai_fofan) return "Thai_fofan";
- if (k == XK_Thai_phosamphao) return "Thai_phosamphao";
- if (k == XK_Thai_moma) return "Thai_moma";
- if (k == XK_Thai_yoyak) return "Thai_yoyak";
- if (k == XK_Thai_rorua) return "Thai_rorua";
- if (k == XK_Thai_ru) return "Thai_ru";
- if (k == XK_Thai_loling) return "Thai_loling";
- if (k == XK_Thai_lu) return "Thai_lu";
- if (k == XK_Thai_wowaen) return "Thai_wowaen";
- if (k == XK_Thai_sosala) return "Thai_sosala";
- if (k == XK_Thai_sorusi) return "Thai_sorusi";
- if (k == XK_Thai_sosua) return "Thai_sosua";
- if (k == XK_Thai_hohip) return "Thai_hohip";
- if (k == XK_Thai_lochula) return "Thai_lochula";
- if (k == XK_Thai_oang) return "Thai_oang";
- if (k == XK_Thai_honokhuk) return "Thai_honokhuk";
- if (k == XK_Thai_paiyannoi) return "Thai_paiyannoi";
- if (k == XK_Thai_saraa) return "Thai_saraa";
- if (k == XK_Thai_maihanakat) return "Thai_maihanakat";
- if (k == XK_Thai_saraaa) return "Thai_saraaa";
- if (k == XK_Thai_saraam) return "Thai_saraam";
- if (k == XK_Thai_sarai) return "Thai_sarai";
- if (k == XK_Thai_saraii) return "Thai_saraii";
- if (k == XK_Thai_saraue) return "Thai_saraue";
- if (k == XK_Thai_sarauee) return "Thai_sarauee";
- if (k == XK_Thai_sarau) return "Thai_sarau";
- if (k == XK_Thai_sarauu) return "Thai_sarauu";
- if (k == XK_Thai_phinthu) return "Thai_phinthu";
- if (k == XK_Thai_maihanakat_maitho) return "Thai_maihanakat_maitho";
- if (k == XK_Thai_baht) return "Thai_baht";
- if (k == XK_Thai_sarae) return "Thai_sarae";
- if (k == XK_Thai_saraae) return "Thai_saraae";
- if (k == XK_Thai_sarao) return "Thai_sarao";
- if (k == XK_Thai_saraaimaimuan) return "Thai_saraaimaimuan";
- if (k == XK_Thai_saraaimaimalai) return "Thai_saraaimaimalai";
- if (k == XK_Thai_lakkhangyao) return "Thai_lakkhangyao";
- if (k == XK_Thai_maiyamok) return "Thai_maiyamok";
- if (k == XK_Thai_maitaikhu) return "Thai_maitaikhu";
- if (k == XK_Thai_maiek) return "Thai_maiek";
- if (k == XK_Thai_maitho) return "Thai_maitho";
- if (k == XK_Thai_maitri) return "Thai_maitri";
- if (k == XK_Thai_maichattawa) return "Thai_maichattawa";
- if (k == XK_Thai_thanthakhat) return "Thai_thanthakhat";
- if (k == XK_Thai_nikhahit) return "Thai_nikhahit";
- if (k == XK_Thai_leksun) return "Thai_leksun";
- if (k == XK_Thai_leknung) return "Thai_leknung";
- if (k == XK_Thai_leksong) return "Thai_leksong";
- if (k == XK_Thai_leksam) return "Thai_leksam";
- if (k == XK_Thai_leksi) return "Thai_leksi";
- if (k == XK_Thai_lekha) return "Thai_lekha";
- if (k == XK_Thai_lekhok) return "Thai_lekhok";
- if (k == XK_Thai_lekchet) return "Thai_lekchet";
- if (k == XK_Thai_lekpaet) return "Thai_lekpaet";
- if (k == XK_Thai_lekkao) return "Thai_lekkao";
-#endif /* XK_THAI */
-#ifdef XK_KOREAN
- if (k == XK_Hangul) return "Hangul";
- if (k == XK_Hangul_Start) return "Hangul_Start";
- if (k == XK_Hangul_End) return "Hangul_End";
- if (k == XK_Hangul_Hanja) return "Hangul_Hanja";
- if (k == XK_Hangul_Jamo) return "Hangul_Jamo";
- if (k == XK_Hangul_Romaja) return "Hangul_Romaja";
- if (k == XK_Hangul_Codeinput) return "Hangul_Codeinput";
- if (k == XK_Hangul_Jeonja) return "Hangul_Jeonja";
- if (k == XK_Hangul_Banja) return "Hangul_Banja";
- if (k == XK_Hangul_PreHanja) return "Hangul_PreHanja";
- if (k == XK_Hangul_PostHanja) return "Hangul_PostHanja";
- if (k == XK_Hangul_SingleCandidate) return "Hangul_SingleCandidate";
- if (k == XK_Hangul_MultipleCandidate) return "Hangul_MultipleCandidate";
- if (k == XK_Hangul_PreviousCandidate) return "Hangul_PreviousCandidate";
- if (k == XK_Hangul_Special) return "Hangul_Special";
- if (k == XK_Hangul_switch) return "Hangul_switch";
- if (k == XK_Hangul_Kiyeog) return "Hangul_Kiyeog";
- if (k == XK_Hangul_SsangKiyeog) return "Hangul_SsangKiyeog";
- if (k == XK_Hangul_KiyeogSios) return "Hangul_KiyeogSios";
- if (k == XK_Hangul_Nieun) return "Hangul_Nieun";
- if (k == XK_Hangul_NieunJieuj) return "Hangul_NieunJieuj";
- if (k == XK_Hangul_NieunHieuh) return "Hangul_NieunHieuh";
- if (k == XK_Hangul_Dikeud) return "Hangul_Dikeud";
- if (k == XK_Hangul_SsangDikeud) return "Hangul_SsangDikeud";
- if (k == XK_Hangul_Rieul) return "Hangul_Rieul";
- if (k == XK_Hangul_RieulKiyeog) return "Hangul_RieulKiyeog";
- if (k == XK_Hangul_RieulMieum) return "Hangul_RieulMieum";
- if (k == XK_Hangul_RieulPieub) return "Hangul_RieulPieub";
- if (k == XK_Hangul_RieulSios) return "Hangul_RieulSios";
- if (k == XK_Hangul_RieulTieut) return "Hangul_RieulTieut";
- if (k == XK_Hangul_RieulPhieuf) return "Hangul_RieulPhieuf";
- if (k == XK_Hangul_RieulHieuh) return "Hangul_RieulHieuh";
- if (k == XK_Hangul_Mieum) return "Hangul_Mieum";
- if (k == XK_Hangul_Pieub) return "Hangul_Pieub";
- if (k == XK_Hangul_SsangPieub) return "Hangul_SsangPieub";
- if (k == XK_Hangul_PieubSios) return "Hangul_PieubSios";
- if (k == XK_Hangul_Sios) return "Hangul_Sios";
- if (k == XK_Hangul_SsangSios) return "Hangul_SsangSios";
- if (k == XK_Hangul_Ieung) return "Hangul_Ieung";
- if (k == XK_Hangul_Jieuj) return "Hangul_Jieuj";
- if (k == XK_Hangul_SsangJieuj) return "Hangul_SsangJieuj";
- if (k == XK_Hangul_Cieuc) return "Hangul_Cieuc";
- if (k == XK_Hangul_Khieuq) return "Hangul_Khieuq";
- if (k == XK_Hangul_Tieut) return "Hangul_Tieut";
- if (k == XK_Hangul_Phieuf) return "Hangul_Phieuf";
- if (k == XK_Hangul_Hieuh) return "Hangul_Hieuh";
- if (k == XK_Hangul_A) return "Hangul_A";
- if (k == XK_Hangul_AE) return "Hangul_AE";
- if (k == XK_Hangul_YA) return "Hangul_YA";
- if (k == XK_Hangul_YAE) return "Hangul_YAE";
- if (k == XK_Hangul_EO) return "Hangul_EO";
- if (k == XK_Hangul_E) return "Hangul_E";
- if (k == XK_Hangul_YEO) return "Hangul_YEO";
- if (k == XK_Hangul_YE) return "Hangul_YE";
- if (k == XK_Hangul_O) return "Hangul_O";
- if (k == XK_Hangul_WA) return "Hangul_WA";
- if (k == XK_Hangul_WAE) return "Hangul_WAE";
- if (k == XK_Hangul_OE) return "Hangul_OE";
- if (k == XK_Hangul_YO) return "Hangul_YO";
- if (k == XK_Hangul_U) return "Hangul_U";
- if (k == XK_Hangul_WEO) return "Hangul_WEO";
- if (k == XK_Hangul_WE) return "Hangul_WE";
- if (k == XK_Hangul_WI) return "Hangul_WI";
- if (k == XK_Hangul_YU) return "Hangul_YU";
- if (k == XK_Hangul_EU) return "Hangul_EU";
- if (k == XK_Hangul_YI) return "Hangul_YI";
- if (k == XK_Hangul_I) return "Hangul_I";
- if (k == XK_Hangul_J_Kiyeog) return "Hangul_J_Kiyeog";
- if (k == XK_Hangul_J_SsangKiyeog) return "Hangul_J_SsangKiyeog";
- if (k == XK_Hangul_J_KiyeogSios) return "Hangul_J_KiyeogSios";
- if (k == XK_Hangul_J_Nieun) return "Hangul_J_Nieun";
- if (k == XK_Hangul_J_NieunJieuj) return "Hangul_J_NieunJieuj";
- if (k == XK_Hangul_J_NieunHieuh) return "Hangul_J_NieunHieuh";
- if (k == XK_Hangul_J_Dikeud) return "Hangul_J_Dikeud";
- if (k == XK_Hangul_J_Rieul) return "Hangul_J_Rieul";
- if (k == XK_Hangul_J_RieulKiyeog) return "Hangul_J_RieulKiyeog";
- if (k == XK_Hangul_J_RieulMieum) return "Hangul_J_RieulMieum";
- if (k == XK_Hangul_J_RieulPieub) return "Hangul_J_RieulPieub";
- if (k == XK_Hangul_J_RieulSios) return "Hangul_J_RieulSios";
- if (k == XK_Hangul_J_RieulTieut) return "Hangul_J_RieulTieut";
- if (k == XK_Hangul_J_RieulPhieuf) return "Hangul_J_RieulPhieuf";
- if (k == XK_Hangul_J_RieulHieuh) return "Hangul_J_RieulHieuh";
- if (k == XK_Hangul_J_Mieum) return "Hangul_J_Mieum";
- if (k == XK_Hangul_J_Pieub) return "Hangul_J_Pieub";
- if (k == XK_Hangul_J_PieubSios) return "Hangul_J_PieubSios";
- if (k == XK_Hangul_J_Sios) return "Hangul_J_Sios";
- if (k == XK_Hangul_J_SsangSios) return "Hangul_J_SsangSios";
- if (k == XK_Hangul_J_Ieung) return "Hangul_J_Ieung";
- if (k == XK_Hangul_J_Jieuj) return "Hangul_J_Jieuj";
- if (k == XK_Hangul_J_Cieuc) return "Hangul_J_Cieuc";
- if (k == XK_Hangul_J_Khieuq) return "Hangul_J_Khieuq";
- if (k == XK_Hangul_J_Tieut) return "Hangul_J_Tieut";
- if (k == XK_Hangul_J_Phieuf) return "Hangul_J_Phieuf";
- if (k == XK_Hangul_J_Hieuh) return "Hangul_J_Hieuh";
- if (k == XK_Hangul_RieulYeorinHieuh) return "Hangul_RieulYeorinHieuh";
- if (k == XK_Hangul_SunkyeongeumMieum) return "Hangul_SunkyeongeumMieum";
- if (k == XK_Hangul_SunkyeongeumPieub) return "Hangul_SunkyeongeumPieub";
- if (k == XK_Hangul_PanSios) return "Hangul_PanSios";
- if (k == XK_Hangul_KkogjiDalrinIeung) return "Hangul_KkogjiDalrinIeung";
- if (k == XK_Hangul_SunkyeongeumPhieuf) return "Hangul_SunkyeongeumPhieuf";
- if (k == XK_Hangul_YeorinHieuh) return "Hangul_YeorinHieuh";
- if (k == XK_Hangul_AraeA) return "Hangul_AraeA";
- if (k == XK_Hangul_AraeAE) return "Hangul_AraeAE";
- if (k == XK_Hangul_J_PanSios) return "Hangul_J_PanSios";
- if (k == XK_Hangul_J_KkogjiDalrinIeung) return "Hangul_J_KkogjiDalrinIeung";
- if (k == XK_Hangul_J_YeorinHieuh) return "Hangul_J_YeorinHieuh";
- if (k == XK_Korean_Won) return "Korean_Won";
-#endif /* XK_KOREAN */
- if (k == XK_EuroSign) return "EuroSign";
-#endif
- return NULL;
-}
-
-KeySym XKeycodeToKeysym(Display *display, KeyCode keycode, int index) {
- if (!display || !keycode || !index) {}
- return NoSymbol;
-}
-
-KeyCode XKeysymToKeycode(Display *display, KeySym keysym) {
- if (!display || !keysym) {}
- return NoSymbol;
-}
-
-XErrorHandler XSetErrorHandler (XErrorHandler h) {
- return h;
-}
-
diff --git a/x11vnc/options.c b/x11vnc/options.c
deleted file mode 100644
index ab119b6..0000000
--- a/x11vnc/options.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- options.c -- */
-
-#define _X11VNC_OPTIONS_H
-#include "x11vnc.h"
-
-/*
- * variables for the command line options
- */
-int debug = 0;
-
-char *use_dpy = NULL; /* -display */
-int display_N = 0;
-int auto_port = 0;
-char *auth_file = NULL; /* -auth/-xauth */
-char *visual_str = NULL; /* -visual */
-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 */
-char *unixpw_list = NULL;
-char *unixpw_cmd = NULL;
-int unixpw_system_greeter = 0;
-int unixpw_system_greeter_active = 0;
-int use_stunnel = 0; /* -stunnel */
-int stunnel_port = 0;
-char *stunnel_pem = NULL;
-int use_openssl = 0;
-int http_ssl = 0;
-int ssl_no_fail = 0;
-char *openssl_pem = NULL;
-char *ssl_certs_dir = NULL;
-char *enc_str = NULL;
-int vencrypt_mode = VENCRYPT_SUPPORT;
-int vencrypt_kx = VENCRYPT_BOTH;
-int vencrypt_enable_plain_login = 0;
-int anontls_mode = ANONTLS_SUPPORT;
-int create_fresh_dhparams = 0;
-char *dhparams_file = NULL;
-int http_try_it = 0;
-int stunnel_http_port = 0;
-int https_port_num = -1;
-int https_port_redir = 0;
-char *ssl_verify = NULL;
-char *ssl_crl = NULL;
-int ssl_initialized = 0;
-int ssl_timeout_secs = -1;
-char *ssh_str = NULL;
-pid_t ssh_pid = 0;
-int usepw = USEPW;
-char *blackout_str = NULL; /* -blackout */
-int blackout_ptr = 0;
-char *clip_str = NULL; /* -clip */
-int use_solid_bg = 0; /* -solid */
-char *solid_str = NULL;
-char *solid_default = "cyan4";
-
-char *wmdt_str = NULL; /* -wmdt */
-
-char *speeds_str = NULL; /* -speeds */
-
-char *rc_rcfile = NULL; /* -rc */
-int rc_rcfile_default = 0;
-int rc_norc = 0;
-int got_norc = 0;
-int opts_bg = 0;
-
-#ifndef VNCSHARED
-int shared = 0; /* share vnc display. */
-#else
-int shared = 1;
-#endif
-#ifndef FOREVER
-int connect_once = 1; /* disconnect after first connection session. */
-#else
-int connect_once = 0;
-#endif
-int got_connect_once = 0;
-int got_findauth = 0;
-int deny_all = 0; /* global locking of new clients */
-#ifndef REMOTE_DEFAULT
-#define REMOTE_DEFAULT 1
-#endif
-int accept_remote_cmds = REMOTE_DEFAULT; /* -noremote */
-char *remote_prefix = NULL;
-int remote_direct = 0;
-int query_default = 0;
-int safe_remote_only = 1; /* -unsafe */
-int priv_remote = 0; /* -privremote */
-int more_safe = 0; /* -safer */
-#ifndef EXTERNAL_COMMANDS
-#define EXTERNAL_COMMANDS 1
-#endif
-#if EXTERNAL_COMMANDS
-int no_external_cmds = 0; /* -nocmds */
-#else
-int no_external_cmds = 1; /* cannot be turned back on. */
-#endif
-char *allowed_external_cmds = NULL;
-int started_as_root = 0;
-int host_lookup = 1;
-char *unix_sock = NULL;
-int unix_sock_fd = -1;
-#if X11VNC_LISTEN6
-int ipv6_listen = 1; /* -6 / -no6 */
-int got_ipv6_listen = 1;
-#else
-int ipv6_listen = 0; /* -6 / -no6 */
-int got_ipv6_listen = 0;
-#endif
-int ipv6_listen_fd = -1;
-int ipv6_http_fd = -1;
-int noipv6 = 0;
-int noipv4 = 0;
-char *ipv6_client_ip_str = NULL;
-char *users_list = NULL; /* -users */
-char **user2group = NULL;
-char *allow_list = NULL; /* for -allow and -localhost */
-char *listen_str = NULL;
-char *listen_str6 = NULL;
-char *allow_once = NULL; /* one time -allow */
-char *accept_cmd = NULL; /* for -accept */
-char *afteraccept_cmd = NULL; /* for -afteraccept */
-char *gone_cmd = NULL; /* for -gone */
-#ifndef VIEWONLY
-#define VIEWONLY 0
-#endif
-int view_only = VIEWONLY; /* clients can only watch. */
-char *allowed_input_view_only = NULL;
-char *allowed_input_normal = NULL;
-char *allowed_input_str = NULL;
-char *viewonly_passwd = NULL; /* view only passwd. */
-char **passwd_list = NULL; /* for -passwdfile */
-int begin_viewonly = -1;
-int inetd = 0; /* spawned from inetd(8) */
-#ifndef TIGHTFILEXFER
-#define TIGHTFILEXFER 0
-#endif
-int tightfilexfer = TIGHTFILEXFER;
-int got_ultrafilexfer = 0;
-int first_conn_timeout = 0; /* -timeout */
-int ping_interval = 0; /* -ping */
-int flash_cmap = 0; /* follow installed colormaps */
-int shift_cmap = 0; /* ncells < 256 and needs shift of pixel values */
-int force_indexed_color = 0; /* whether to force indexed color for 8bpp */
-int advertise_truecolor = 0;
-int advertise_truecolor_reset = 0;
-int cmap8to24 = 0; /* -8to24 */
-int xform24to32 = 0; /* -24to32 */
-char *cmap8to24_str = NULL;
-int launch_gui = 0; /* -gui */
-
-#ifndef AVAHI
-#define AVAHI 0
-#endif
-int avahi = AVAHI; /* -avahi, -mdns */
-int vnc_redirect = 0;
-int vnc_redirect_sock = -1;
-
-int use_modifier_tweak = 1; /* use the shift/altgr modifier tweak */
-int watch_capslock = 0; /* -capslock */
-int skip_lockkeys = 0; /* -skip_lockkeys */
-int use_iso_level3 = 0; /* ISO_Level3_Shift instead of Mode_switch */
-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;
-FILE *pipeinput_fh = NULL;
-int pipeinput_tee = 0;
-int pipeinput_int = 0;
-int pipeinput_cons_fd = -1;
-char *pipeinput_cons_dev = NULL;
-
-int macosx_nodimming = 0; /* Some native MacOSX server settings. */
-int macosx_nosleep = 0;
-int macosx_noscreensaver = 0;
-int macosx_wait_for_switch = 1;
-int macosx_mouse_wheel_speed = 5;
-int macosx_console = 0;
-int macosx_swap23 = 1;
-int macosx_resize = 1;
-int macosx_icon_anim_time = 450;
-int macosx_no_opengl = 0;
-int macosx_no_rawfb = 0;
-int macosx_read_opengl = 0;
-int macosx_read_rawfb = 0;
-
-unsigned long subwin = 0x0; /* -id, -sid */
-int subwin_wait_mapped = 0;
-int freeze_when_obscured = 0;
-int subwin_obscured = 0;
-
-int debug_xevents = 0; /* -R debug_xevents:1 */
-int debug_xdamage = 0; /* -R debug_xdamage:1 or 2 ... */
-int debug_wireframe = 0;
-int debug_tiles = 0;
-int debug_grabs = 0;
-int debug_sel = 0;
-
-int xtrap_input = 0; /* -xtrap for user input insertion */
-int xinerama = XINERAMA; /* -xinerama */
-int xrandr = 0; /* -xrandr */
-int xrandr_maybe = 1; /* check for events, but don't trap all calls */
-char *xrandr_mode = NULL;
-char *pad_geometry = NULL;
-time_t pad_geometry_time = 0;
-int use_snapfb = 0;
-
-int use_xrecord = 0;
-int noxrecord = 0;
-
-char *client_connect = NULL; /* strings for -connect option */
-char *client_connect_file = NULL;
-int connect_or_exit = 0;
-int vnc_connect = 1; /* -vncconnect option */
-char *connect_proxy = NULL;
-
-int show_cursor = 1; /* show cursor shapes */
-int show_multiple_cursors = 0; /* show X when on root background, etc */
-char *multiple_cursors_mode = NULL;
-#ifndef CURSOR_DRAG
-#define CURSOR_DRAG 0
-#endif
-int cursor_drag_changes = CURSOR_DRAG;
-int cursor_pos_updates = 1; /* cursor position updates -cursorpos */
-int cursor_shape_updates = 1; /* cursor shape updates -nocursorshape */
-int use_xwarppointer = 0; /* use XWarpPointer instead of XTestFake... */
-int always_inject = 0; /* inject new mouse coordinates even if dx=dy=0 */
-int show_dragging = 1; /* process mouse movement events */
-#ifndef WIREFRAME
-#define WIREFRAME 1
-#endif
-int wireframe = WIREFRAME; /* try to emulate wireframe wm moves */
-/* shade,linewidth,percent,T+B+L+R,t1+t2+t3+t4 */
-char *wireframe_str = NULL;
-char *wireframe_copyrect = NULL;
-#ifndef WIREFRAME_COPYRECT
-#define WIREFRAME_COPYRECT 1
-#endif
-#if WIREFRAME_COPYRECT
-char *wireframe_copyrect_default = "always";
-#else
-char *wireframe_copyrect_default = "never";
-#endif
-int wireframe_in_progress = 0;
-int wireframe_local = 1;
-
-#ifndef NCACHE
-#ifdef NO_NCACHE
-#define NCACHE 0
-#else
-#define xxNCACHE -12
-#define NCACHE -1
-#endif
-#endif
-
-#ifdef MACOSX
-int ncache = 0;
-int ncache_pad = 24;
-#else
-int ncache = NCACHE;
-int ncache_pad = 0;
-#endif
-
-#ifndef NCACHE_XROOTPMAP
-#define NCACHE_XROOTPMAP 1
-#endif
-int ncache_xrootpmap = NCACHE_XROOTPMAP;
-int ncache0 = 0;
-int ncache_default = 10;
-int ncache_copyrect = 0;
-int ncache_wf_raises = 1;
-int ncache_dt_change = 1;
-int ncache_keep_anims = 0;
-int ncache_old_wm = 0;
-int macosx_ncache_macmenu = 0;
-int macosx_us_kbd = 0;
-int ncache_beta_tester = 0;
-int ncdb = 0;
-
-Atom atom_NET_ACTIVE_WINDOW = None;
-Atom atom_NET_CURRENT_DESKTOP = None;
-Atom atom_NET_CLIENT_LIST_STACKING = None;
-Atom atom_XROOTPMAP_ID = None;
-double got_NET_ACTIVE_WINDOW = 0.0;
-double got_NET_CURRENT_DESKTOP = 0.0;
-double got_NET_CLIENT_LIST_STACKING = 0.0;
-double got_XROOTPMAP_ID = 0.0;
-
-/* T+B+L+R,tkey+presist_key,tmouse+persist_mouse */
-char *scroll_copyrect_str = NULL;
-#ifndef SCROLL_COPYRECT
-#define SCROLL_COPYRECT 1
-#endif
-char *scroll_copyrect = NULL;
-#if SCROLL_COPYRECT
-#if 1
-char *scroll_copyrect_default = "always"; /* -scrollcopyrect */
-#else
-char *scroll_copyrect_default = "keys";
-#endif
-#else
-char *scroll_copyrect_default = "never";
-#endif
-char *scroll_key_list_str = NULL;
-KeySym *scroll_key_list = NULL;
-
-#ifndef SCALING_COPYRECT
-#define SCALING_COPYRECT 1
-#endif
-int scaling_copyrect0 = SCALING_COPYRECT;
-int scaling_copyrect = SCALING_COPYRECT;
-
-int scrollcopyrect_min_area = 60000; /* minimum rectangle area */
-int debug_scroll = 0;
-double pointer_flush_delay = 0.0;
-double last_scroll_event = 0.0;
-int max_scroll_keyrate = 0;
-double max_keyrepeat_time = 0.0;
-char *max_keyrepeat_str = NULL;
-char *max_keyrepeat_str0 = "4-20";
-int max_keyrepeat_lo = 1, max_keyrepeat_hi = 40;
-
-char **scroll_good_all = NULL;
-char **scroll_good_key = NULL;
-char **scroll_good_mouse = NULL;
-char *scroll_good_str = NULL;
-char *scroll_good_str0 = "##Nomatch";
-/* "##Firefox-bin," */
-/* "##Gnome-terminal," */
-/* "##XTerm", */
-
-char **scroll_skip_all = NULL;
-char **scroll_skip_key = NULL;
-char **scroll_skip_mouse = NULL;
-char *scroll_skip_str = NULL;
-char *scroll_skip_str0 = "##Soffice.bin,##StarOffice,##OpenOffice";
-/* "##Konsole," * no problems, known heuristics do not work */
-
-char **scroll_term = NULL;
-char *scroll_term_str = NULL;
-char *scroll_term_str0 = "term";
-
-char* screen_fixup_str = NULL;
-double screen_fixup_V = 0.0;
-double screen_fixup_C = 0.0;
-double screen_fixup_X = 0.0;
-double screen_fixup_8 = 0.0;
-
-#ifndef NOREPEAT
-#define NOREPEAT 1
-#endif
-int no_autorepeat = NOREPEAT; /* turn off autorepeat with clients */
-int no_repeat_countdown = 2;
-int watch_bell = 1; /* watch for the bell using XKEYBOARD */
-int sound_bell = 1; /* actually send it */
-int xkbcompat = 0; /* ignore XKEYBOARD extension */
-int use_xkb_modtweak = 0; /* -xkb */
-#ifndef SKIPDUPS
-#define SKIPDUPS 0
-#endif
-int skip_duplicate_key_events = SKIPDUPS;
-char *skip_keycodes = NULL;
-int sloppy_keys = 0;
-#ifndef ADDKEYSYMS
-#define ADDKEYSYMS 1
-#endif
-int add_keysyms = ADDKEYSYMS; /* automatically add keysyms to X server */
-
-char *remap_file = NULL; /* -remap */
-char *pointer_remap = NULL;
-/* use the various ways of updating pointer */
-#ifndef POINTER_MODE_DEFAULT
-#define POINTER_MODE_DEFAULT 2
-#endif
-int pointer_mode = POINTER_MODE_DEFAULT;
-int pointer_mode_max = 4;
-int single_copytile = 0; /* use the old way copy_tiles() */
-int single_copytile_orig = 0;
-int single_copytile_count = 0;
-int tile_shm_count = 0;
-
-int using_shm = 1; /* whether mit-shm is used */
-int flip_byte_order = 0; /* sometimes needed when using_shm = 0 */
-/*
- * waitms is the msec to wait between screen polls. Not too old h/w shows
- * poll times of 10-35ms, so maybe this value cuts the idle load by 2 or so.
- */
-int waitms = 20;
-int got_waitms = 0;
-double wait_ui = 2.0;
-double slow_fb = 0.0;
-double xrefresh = 0.0;
-int wait_bog = 1;
-int extra_fbur = 1;
-int defer_update = 20; /* deferUpdateTime ms to wait before sends. */
-int set_defer = 1;
-int got_defer = 0;
-int got_deferupdate = 0;
-
-int screen_blank = 60; /* number of seconds of no activity to throttle */
- /* down the screen polls. zero to disable. */
-int no_fbu_blank = 30; /* nap if no client updates in this many secs. */
-int take_naps = 1; /* -nap/-nonap */
-int naptile = 4; /* tile change threshold per poll to take a nap */
-int napfac = 4; /* time = napfac*waitms, cut load with extra waits */
-int napmax = 1500; /* longest nap in ms. */
-int ui_skip = 10; /* see watchloop. negative means ignore input */
-int all_input = 0;
-int handle_events_eagerly = 0;
-
-
-#if LIBVNCSERVER_HAVE_FBPM
-int watch_fbpm = 1; /* -nofbpm */
-#else
-int watch_fbpm = 0;
-#endif
-
-int watch_dpms = 0; /* -dpms */
-int force_dpms = 0;
-int client_dpms = 0;
-int no_ultra_dpms = 0;
-int no_ultra_ext = 0;
-int saw_ultra_chat = 0;
-int saw_ultra_file = 0;
-int chat_window = 0;
-rfbClientPtr chat_window_client = NULL;
-
-int watch_selection = 1; /* normal selection/cutbuffer maintenance */
-int watch_primary = 1; /* more dicey, poll for changes in PRIMARY */
-int watch_clipboard = 1;
-char *sel_direction = NULL; /* "send" or "recv" for one-way */
-
-char *sigpipe = NULL; /* skip, ignore, exit */
-
-/* visual stuff for -visual override or -overlay */
-VisualID visual_id = (VisualID) 0;
-int visual_depth = 0;
-
-/* for -overlay mode on Solaris/IRIX. X server draws cursor correctly. */
-int overlay = 0;
-int overlay_cursor = 1;
-
-/* tile heuristics: */
-double fs_frac = 0.75; /* threshold tile fraction to do fullscreen updates. */
-int tile_fuzz = 2; /* tolerance for suspecting changed tiles touching */
- /* a known changed tile. */
-int grow_fill = 3; /* do the grow islands heuristic with this width. */
-int gaps_fill = 4; /* do a final pass to try to fill gaps between tiles. */
-
-int debug_pointer = 0;
-int debug_keyboard = 0;
-
-int quiet = 0;
-int verbose = 0;
-
-/* threaded vs. non-threaded (default) */
-int use_threads = 0;
-int started_rfbRunEventLoop = 0;
-int threads_drop_input = 0;
-
-/* info about command line opts */
-int got_noxwarppointer = 0;
-int got_rfbport = 0;
-int got_rfbport_val = -1;
-int got_alwaysshared = 0;
-int got_nevershared = 0;
-int got_cursorpos = 0;
-int got_pointer_mode = -1;
-int got_noviewonly = 0;
-int got_wirecopyrect = 0;
-int got_scrollcopyrect = 0;
-int got_noxkb = 0;
-int got_nomodtweak = 0;
-
diff --git a/x11vnc/options.h b/x11vnc/options.h
deleted file mode 100644
index 609f4ce..0000000
--- a/x11vnc/options.h
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_OPTIONS_H
-#define _X11VNC_OPTIONS_H
-
-/* -- options.h -- */
-
-/*
- * variables for the command line options
- */
-extern int debug;
-
-extern char *use_dpy;
-extern int display_N;
-extern int auto_port;
-extern char *auth_file;
-extern char *visual_str;
-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;
-extern char *unixpw_list;
-extern char *unixpw_cmd;
-extern int unixpw_system_greeter;
-extern int unixpw_system_greeter_active;
-extern int use_stunnel;
-extern int stunnel_port;
-extern char *stunnel_pem;
-extern int use_openssl;
-extern int http_ssl;
-extern int ssl_no_fail;
-extern char *openssl_pem;
-extern char *ssl_certs_dir;
-extern char *enc_str;
-extern int vencrypt_mode;
-extern int vencrypt_kx;
-extern int vencrypt_enable_plain_login;
-extern int anontls_mode;
-extern int create_fresh_dhparams;
-extern char *dhparams_file;
-extern int http_try_it;
-extern int stunnel_http_port;
-extern int https_port_num;
-extern int https_port_redir;
-extern char *ssl_verify;
-extern char *ssl_crl;
-extern int ssl_initialized;
-extern int ssl_timeout_secs;
-extern char *ssh_str;
-extern pid_t ssh_pid;
-extern int usepw;
-extern char *blackout_str;
-extern int blackout_ptr;
-extern char *clip_str;
-extern int use_solid_bg;
-extern char *solid_str;
-extern char *solid_default;
-
-extern char *wmdt_str;
-
-extern char *speeds_str;
-extern char *rc_rcfile;
-extern int rc_rcfile_default;
-extern int rc_norc;
-extern int got_norc;
-extern int opts_bg;
-
-extern int shared;
-extern int connect_once;
-extern int got_connect_once;
-extern int got_findauth;
-extern int deny_all;
-extern int accept_remote_cmds;
-extern char *remote_prefix;
-extern int remote_direct;
-extern int query_default;
-extern int safe_remote_only;
-extern int priv_remote;
-extern int more_safe;
-extern int no_external_cmds;
-extern char *allowed_external_cmds;
-extern int started_as_root;
-extern int host_lookup;
-extern char *unix_sock;
-extern int unix_sock_fd;
-extern int ipv6_listen;
-extern int got_ipv6_listen;
-extern int ipv6_listen_fd;
-extern int ipv6_http_fd;
-extern int noipv6;
-extern int noipv4;
-extern char *ipv6_client_ip_str;
-extern char *users_list;
-extern char **user2group;
-extern char *allow_list;
-extern char *listen_str;
-extern char *listen_str6;
-extern char *allow_once;
-extern char *accept_cmd;
-extern char *afteraccept_cmd;
-extern char *gone_cmd;
-extern int view_only;
-extern char *allowed_input_view_only;
-extern char *allowed_input_normal;
-extern char *allowed_input_str;
-extern char *viewonly_passwd;
-extern char **passwd_list;
-extern int begin_viewonly;
-extern int inetd;
-extern int tightfilexfer;
-extern int got_ultrafilexfer;
-extern int first_conn_timeout;
-extern int ping_interval;
-extern int flash_cmap;
-extern int shift_cmap;
-extern int force_indexed_color;
-extern int advertise_truecolor;
-extern int advertise_truecolor_reset;
-extern int cmap8to24;
-extern char *cmap8to24_str;
-extern int xform24to32;
-extern int launch_gui;
-
-extern int avahi;
-extern int vnc_redirect;
-extern int vnc_redirect_sock;
-
-extern int use_modifier_tweak;
-extern int watch_capslock;
-extern int skip_lockkeys;
-extern int use_iso_level3;
-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;
-extern FILE *pipeinput_fh;
-extern int pipeinput_tee;
-extern int pipeinput_int;
-extern int pipeinput_cons_fd;
-extern char *pipeinput_cons_dev;
-
-extern int macosx_nodimming;
-extern int macosx_nosleep;
-extern int macosx_noscreensaver;
-extern int macosx_wait_for_switch;
-extern int macosx_mouse_wheel_speed;
-extern int macosx_console;
-extern int macosx_swap23;
-extern int macosx_resize;
-extern int macosx_icon_anim_time;
-extern int macosx_no_opengl;
-extern int macosx_no_rawfb;
-extern int macosx_read_opengl;
-extern int macosx_read_rawfb;
-
-extern unsigned long subwin;
-extern int subwin_wait_mapped;
-extern int freeze_when_obscured;
-extern int subwin_obscured;
-
-extern int debug_xevents;
-extern int debug_xdamage;
-extern int debug_wireframe;
-extern int debug_tiles;
-extern int debug_grabs;
-extern int debug_sel;
-
-extern int xtrap_input;
-extern int xinerama;
-extern int xrandr;
-extern int xrandr_maybe;
-extern char *xrandr_mode;
-extern char *pad_geometry;
-extern time_t pad_geometry_time;
-extern int use_snapfb;
-
-extern int use_xrecord;
-extern int noxrecord;
-
-extern char *client_connect;
-extern char *client_connect_file;
-extern int connect_or_exit;
-extern int vnc_connect;
-extern char *connect_proxy;
-
-extern int show_cursor;
-extern int show_multiple_cursors;
-extern char *multiple_cursors_mode;
-extern int cursor_drag_changes;
-extern int cursor_pos_updates;
-extern int cursor_shape_updates;
-extern int use_xwarppointer;
-extern int always_inject;
-extern int show_dragging;
-extern int wireframe;
-extern int wireframe_local;
-
-extern char *wireframe_str;
-extern char *wireframe_copyrect;
-extern char *wireframe_copyrect_default;
-extern int wireframe_in_progress;
-
-extern int ncache;
-extern int ncache0;
-extern int ncache_default;
-extern int ncache_copyrect;
-extern int ncache_wf_raises;
-extern int ncache_dt_change;
-extern int ncache_pad;
-extern int ncache_xrootpmap;
-extern int ncache_keep_anims;
-extern int ncache_old_wm;
-extern int macosx_ncache_macmenu;
-extern int macosx_us_kbd;
-extern int ncache_beta_tester;
-extern int ncdb;
-
-extern Atom atom_NET_ACTIVE_WINDOW;
-extern Atom atom_NET_CURRENT_DESKTOP;
-extern Atom atom_NET_CLIENT_LIST_STACKING;
-extern Atom atom_XROOTPMAP_ID;
-extern double got_NET_ACTIVE_WINDOW;
-extern double got_NET_CURRENT_DESKTOP;
-extern double got_NET_CLIENT_LIST_STACKING;
-extern double got_XROOTPMAP_ID;
-
-extern char *scroll_copyrect_str;
-extern char *scroll_copyrect;
-extern char *scroll_copyrect_default;
-extern char *scroll_key_list_str;
-extern KeySym *scroll_key_list;
-
-extern int scaling_copyrect0;
-extern int scaling_copyrect;
-
-extern int scrollcopyrect_min_area;
-extern int debug_scroll;
-extern double pointer_flush_delay;
-extern double last_scroll_event;
-extern int max_scroll_keyrate;
-extern double max_keyrepeat_time;
-extern char *max_keyrepeat_str;
-extern char *max_keyrepeat_str0;
-extern int max_keyrepeat_lo, max_keyrepeat_hi;
-
-extern char **scroll_good_all;
-extern char **scroll_good_key;
-extern char **scroll_good_mouse;
-extern char *scroll_good_str;
-extern char *scroll_good_str0;
-
-extern char **scroll_skip_all;
-extern char **scroll_skip_key;
-extern char **scroll_skip_mouse;
-extern char *scroll_skip_str;
-extern char *scroll_skip_str0;
-
-extern char **scroll_term;
-extern char *scroll_term_str;
-extern char *scroll_term_str0;
-
-extern char* screen_fixup_str;
-extern double screen_fixup_V;
-extern double screen_fixup_C;
-extern double screen_fixup_X;
-extern double screen_fixup_8;
-
-extern int no_autorepeat;
-extern int no_repeat_countdown;
-extern int watch_bell;
-extern int sound_bell;
-extern int xkbcompat;
-extern int use_xkb_modtweak;
-extern int skip_duplicate_key_events;
-extern char *skip_keycodes;
-extern int sloppy_keys;
-extern int add_keysyms;
-
-extern char *remap_file;
-extern char *pointer_remap;
-extern int pointer_mode;
-extern int pointer_mode_max;
-extern int single_copytile;
-extern int single_copytile_orig;
-extern int single_copytile_count;
-extern int tile_shm_count;
-
-extern int using_shm;
-extern int flip_byte_order;
-extern int waitms;
-extern int got_waitms;
-extern double wait_ui;
-extern double slow_fb;
-extern double xrefresh;
-extern int wait_bog;
-extern int extra_fbur;
-extern int defer_update;
-extern int set_defer;
-extern int got_defer;
-extern int got_deferupdate;
-
-extern int screen_blank;
-
-extern int no_fbu_blank;
-extern int take_naps;
-extern int naptile;
-extern int napfac;
-extern int napmax;
-extern int ui_skip;
-extern int all_input;
-extern int handle_events_eagerly;
-
-extern int watch_fbpm;
-extern int watch_dpms;
-extern int force_dpms;
-extern int client_dpms;
-extern int no_ultra_dpms;
-extern int no_ultra_ext;
-extern int saw_ultra_chat;
-extern int saw_ultra_file;
-extern int chat_window;
-extern rfbClientPtr chat_window_client;
-
-extern int watch_selection;
-extern int watch_primary;
-extern int watch_clipboard;
-extern char *sel_direction;
-
-extern char *sigpipe;
-
-extern VisualID visual_id;
-extern int visual_depth;
-
-extern int overlay;
-extern int overlay_cursor;
-
-extern double fs_frac;
-extern int tile_fuzz;
-
-extern int grow_fill;
-extern int gaps_fill;
-
-extern int debug_pointer;
-extern int debug_keyboard;
-
-extern int quiet;
-extern int verbose;
-
-extern int use_threads;
-extern int started_rfbRunEventLoop;
-extern int threads_drop_input;
-
-extern int got_noxwarppointer;
-extern int got_rfbport;
-extern int got_rfbport_val;
-extern int got_alwaysshared;
-extern int got_nevershared;
-extern int got_cursorpos;
-extern int got_pointer_mode;
-extern int got_noviewonly;
-extern int got_wirecopyrect;
-extern int got_scrollcopyrect;
-extern int got_noxkb;
-extern int got_nomodtweak;
-
-#endif /* _X11VNC_OPTIONS_H */
diff --git a/x11vnc/params.h b/x11vnc/params.h
deleted file mode 100644
index a1690b9..0000000
--- a/x11vnc/params.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_PARAMS_H
-#define _X11VNC_PARAMS_H
-
-/* -- params.h -- */
-
-#define ICON_MODE_SOCKS 16
-
-/* had lw=3 for a long time */
-#ifndef WIREFRAME_PARMS
-#define WIREFRAME_PARMS "0xff,2,0,32+8+8+8,all,0.15+0.30+5.0+0.125"
-#endif
-
-#ifndef SCROLL_COPYRECT_PARMS
-#define SCROLL_COPYRECT_PARMS "0+64+32+32,0.02+0.10+0.9,0.03+0.06+0.5+0.1+5.0"
-#endif
-
-#ifndef POLL_8TO24_DELAY
-#define POLL_8TO24_DELAY 0.05
-#endif
-
-#define LATENCY0 20 /* 20ms */
-#define NETRATE0 20 /* 20KB/sec */
-
-#define POINTER_MODE_NOFB 2
-
-/* scan pattern jitter from x0rfbserver */
-#define NSCAN 32
-
-#define FB_COPY 0x1
-#define FB_MOD 0x2
-#define FB_REQ 0x4
-
-#define VNC_CONNECT_MAX 16384
-#define X11VNC_REMOTE_MAX 65536
-#define PROP_MAX (262144L)
-
-#define MAXN 256
-
-#define PIPEINPUT_NONE 0x0
-#define PIPEINPUT_VID 0x1
-#define PIPEINPUT_CONSOLE 0x2
-#define PIPEINPUT_UINPUT 0x3
-#define PIPEINPUT_MACOSX 0x4
-#define PIPEINPUT_VNC 0x5
-
-#define MAX_BUTTONS 5
-
-#define ROTATE_NONE 0
-#define ROTATE_X 1
-#define ROTATE_Y 2
-#define ROTATE_XY 3
-#define ROTATE_90 4
-#define ROTATE_90X 5
-#define ROTATE_90Y 6
-#define ROTATE_270 7
-
-#define VENCRYPT_NONE 0
-#define VENCRYPT_SUPPORT 1
-#define VENCRYPT_SOLE 2
-#define VENCRYPT_FORCE 3
-
-#define VENCRYPT_BOTH 0
-#define VENCRYPT_NODH 1
-#define VENCRYPT_NOX509 2
-
-#define ANONTLS_NONE 0
-#define ANONTLS_SUPPORT 1
-#define ANONTLS_SOLE 2
-#define ANONTLS_FORCE 3
-
-#endif /* _X11VNC_PARAMS_H */
diff --git a/x11vnc/pm.c b/x11vnc/pm.c
deleted file mode 100644
index 659c272..0000000
--- a/x11vnc/pm.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- pm.c -- */
-#include "x11vnc.h"
-#include "cleanup.h"
-
-void check_pm(void);
-void set_dpms_mode(char *mode);
-static void check_fbpm(void);
-static void check_dpms(void);
-
-#if LIBVNCSERVER_HAVE_FBPM
-#include <X11/Xmd.h>
-#include <X11/extensions/fbpm.h>
-#endif
-
-#if LIBVNCSERVER_HAVE_DPMS
-#include <X11/extensions/dpms.h>
-#endif
-
-void check_pm(void) {
- static int skip = -1;
- if (skip < 0) {
- skip = 0;
- if (getenv("X11VNC_NO_CHECK_PM")) {
- skip = 1;
- }
- }
- if (skip) {
- return;
- }
- check_fbpm();
- check_dpms();
- /* someday dpms activities? */
-}
-
-static void check_fbpm(void) {
- static int init_fbpm = 0;
-#if LIBVNCSERVER_HAVE_FBPM
- static int fbpm_capable = 0;
- static time_t last_fbpm = 0;
- int db = 0;
-
- CARD16 level;
- BOOL enabled;
-
- RAWFB_RET_VOID
-
- if (! init_fbpm) {
- if (getenv("FBPM_DEBUG")) {
- db = atoi(getenv("FBPM_DEBUG"));
- }
- if (FBPMCapable(dpy)) {
- fbpm_capable = 1;
- rfbLog("X display is capable of FBPM.\n");
- if (watch_fbpm) {
- rfbLog("Preventing low-power FBPM modes when"
- " clients are connected.\n");
- }
- } else {
- if (! raw_fb_str) {
- rfbLog("X display is not capable of FBPM.\n");
- }
- fbpm_capable = 0;
- }
- init_fbpm = 1;
- }
-
- if (! watch_fbpm) {
- return;
- }
- if (! fbpm_capable) {
- return;
- }
- if (! client_count) {
- return;
- }
- if (time(NULL) < last_fbpm + 5) {
- return;
- }
- last_fbpm = time(NULL);
-
- if (FBPMInfo(dpy, &level, &enabled)) {
- if (db) fprintf(stderr, "FBPMInfo level: %d enabled: %d\n", level, enabled);
-
- if (enabled && level != FBPMModeOn) {
- char *from = "unknown-fbpm-state";
- XErrorHandler old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
-
- if (level == FBPMModeStandby) {
- from = "FBPMModeStandby";
- } else if (level == FBPMModeSuspend) {
- from = "FBPMModeSuspend";
- } else if (level == FBPMModeOff) {
- from = "FBPMModeOff";
- }
-
- rfbLog("switching FBPM state from %s to FBPMModeOn\n", from);
-
- FBPMForceLevel(dpy, FBPMModeOn);
-
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
- }
- } else {
- if (db) fprintf(stderr, "FBPMInfo failed.\n");
- }
-#else
- RAWFB_RET_VOID
- if (! init_fbpm) {
- if (! raw_fb_str) {
- rfbLog("X FBPM extension not supported.\n");
- }
- init_fbpm = 1;
- }
-#endif
-}
-
-void set_dpms_mode(char *mode) {
-#if NO_X11
- return;
-#else
- RAWFB_RET_VOID
-#if LIBVNCSERVER_HAVE_DPMS
- if (dpy && DPMSCapable(dpy)) {
- CARD16 level;
- CARD16 want;
- BOOL enabled;
- if (!strcmp(mode, "off")) {
- want = DPMSModeOff;
- } else if (!strcmp(mode, "on")) {
- want = DPMSModeOn;
- } else if (!strcmp(mode, "standby")) {
- want = DPMSModeStandby;
- } else if (!strcmp(mode, "suspend")) {
- want = DPMSModeSuspend;
- } else if (!strcmp(mode, "enable")) {
- DPMSEnable(dpy);
- return;
- } else if (!strcmp(mode, "disable")) {
- DPMSDisable(dpy);
- return;
- } else {
- return;
- }
- if (DPMSInfo(dpy, &level, &enabled)) {
- char *from = "unk";
- if (enabled && level != want) {
- XErrorHandler old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
-
- rfbLog("DPMSInfo level: %d enabled: %d\n", level, enabled);
- if (level == DPMSModeStandby) {
- from = "DPMSModeStandby";
- } else if (level == DPMSModeSuspend) {
- from = "DPMSModeSuspend";
- } else if (level == DPMSModeOff) {
- from = "DPMSModeOff";
- } else if (level == DPMSModeOn) {
- from = "DPMSModeOn";
- }
-
- rfbLog("switching DPMS state from %s to %s\n", from, mode);
-
- DPMSForceLevel(dpy, want);
-
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
- }
- }
- }
-#endif
-#endif
-}
-
-static void check_dpms(void) {
- static int init_dpms = 0;
-#if LIBVNCSERVER_HAVE_DPMS
- static int dpms_capable = 0;
- static time_t last_dpms = 0;
- int db = 0;
-
- CARD16 level;
- BOOL enabled;
-
- RAWFB_RET_VOID
-
- if (! init_dpms) {
- if (getenv("DPMS_DEBUG")) {
- db = atoi(getenv("DPMS_DEBUG"));
- }
- if (DPMSCapable(dpy)) {
- dpms_capable = 1;
- rfbLog("X display is capable of DPMS.\n");
- if (watch_dpms) {
- rfbLog("Preventing low-power DPMS modes when"
- " clients are connected.\n");
- }
- } else {
- if (! raw_fb_str) {
- rfbLog("X display is not capable of DPMS.\n");
- }
- dpms_capable = 0;
- }
- init_dpms = 1;
- }
-
- if (force_dpms || (client_dpms && client_count)) {
- static int last_enable = 0;
- if (time(NULL) > last_enable) {
- set_dpms_mode("enable");
- last_enable = time(NULL);
- }
- set_dpms_mode("off");
- }
- if (! watch_dpms) {
- return;
- }
- if (! dpms_capable) {
- return;
- }
- if (! client_count) {
- return;
- }
- if (time(NULL) < last_dpms + 5) {
- return;
- }
- last_dpms = time(NULL);
-
- if (DPMSInfo(dpy, &level, &enabled)) {
- if (db) fprintf(stderr, "DPMSInfo level: %d enabled: %d\n", level, enabled);
-
- if (enabled && level != DPMSModeOn) {
- char *from = "unknown-dpms-state";
- XErrorHandler old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
-
- if (level == DPMSModeStandby) {
- from = "DPMSModeStandby";
- } else if (level == DPMSModeSuspend) {
- from = "DPMSModeSuspend";
- } else if (level == DPMSModeOff) {
- from = "DPMSModeOff";
- }
-
- rfbLog("switching DPMS state from %s to DPMSModeOn\n", from);
-
- DPMSForceLevel(dpy, DPMSModeOn);
-
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
- }
- } else {
- if (db) fprintf(stderr, "DPMSInfo failed.\n");
- }
-#else
- RAWFB_RET_VOID
- if (! init_dpms) {
- if (! raw_fb_str) {
- rfbLog("X DPMS extension not supported.\n");
- }
- init_dpms = 1;
- }
-#endif
-}
-
diff --git a/x11vnc/pm.h b/x11vnc/pm.h
deleted file mode 100644
index 01ef9a6..0000000
--- a/x11vnc/pm.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_PM_H
-#define _X11VNC_PM_H
-
-/* -- pm.h -- */
-extern void check_pm(void);
-extern void set_dpms_mode(char *mode);
-
-#endif /* _X11VNC_PM_H */
diff --git a/x11vnc/pointer.c b/x11vnc/pointer.c
deleted file mode 100644
index f2995c3..0000000
--- a/x11vnc/pointer.c
+++ /dev/null
@@ -1,1206 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- pointer.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "keyboard.h"
-#include "xinerama.h"
-#include "xrecord.h"
-#include "win_utils.h"
-#include "cursor.h"
-#include "userinput.h"
-#include "connections.h"
-#include "cleanup.h"
-#include "unixpw.h"
-#include "v4l.h"
-#include "linuxfb.h"
-#include "uinput.h"
-#include "scan.h"
-#include "macosx.h"
-#include "screen.h"
-
-int pointer_queued_sent = 0;
-
-void initialize_pointer_map(char *pointer_remap);
-void do_button_mask_change(int mask, int button);
-void pointer_event(int mask, int x, int y, rfbClientPtr client);
-void initialize_pipeinput(void);
-int check_pipeinput(void);
-void update_x11_pointer_position(int x, int y);
-
-
-static void buttonparse(int from, char **s);
-static void update_x11_pointer_mask(int mask);
-static void pipe_pointer(int mask, int x, int y, rfbClientPtr client);
-
-/*
- * pointer event (motion and button click) handling routines.
- */
-typedef struct ptrremap {
- KeySym keysym;
- KeyCode keycode;
- int end;
- int button;
- int down;
- int up;
-} prtremap_t;
-
-#define MAX_BUTTON_EVENTS 50
-static prtremap_t pointer_map[MAX_BUTTONS+1][MAX_BUTTON_EVENTS];
-
-/*
- * For parsing the -buttonmap sections, e.g. "4" or ":Up+Up+Up:"
- */
-static void buttonparse(int from, char **s) {
-#if (0 && NO_X11)
- if (!from || !s) {}
- return;
-#else
- char *q;
- int to, i;
- int modisdown[256];
-
- q = *s;
-
- for (i=0; i<256; i++) {
- modisdown[i] = 0;
- }
-
- if (*q == ':') {
- /* :sym1+sym2+...+symN: format */
- int l = 0, n = 0;
- char list[1000];
- char *t, *kp = q + 1;
- KeyCode kcode;
-
- while (*(kp+l) != ':' && *(kp+l) != '\0') {
- /* loop to the matching ':' */
- l++;
- if (l >= 1000) {
- rfbLog("buttonparse: keysym list too long: "
- "%s\n", q);
- break;
- }
- }
- *(kp+l) = '\0';
- strncpy(list, kp, l);
- list[l] = '\0';
- rfbLog("remap button %d using \"%s\"\n", from, list);
-
- /* loop over tokens separated by '+' */
- t = strtok(list, "+");
- while (t) {
- KeySym ksym;
- unsigned int ui;
- int i;
- if (n >= MAX_BUTTON_EVENTS - 20) {
- rfbLog("buttonparse: too many button map "
- "events: %s\n", list);
- break;
- }
- if (sscanf(t, "0x%x", &ui) == 1) {
- ksym = (KeySym) ui; /* hex value */
- } else {
- X_LOCK;
- ksym = XStringToKeysym(t); /* string value */
- X_UNLOCK;
- }
- if (ksym == NoSymbol) {
- /* see if Button<N> "keysym" was used: */
- if (sscanf(t, "Button%d", &i) == 1) {
- rfbLog(" event %d: button %d\n",
- from, n+1, i);
- if (i == 0) i = -1; /* bah */
- pointer_map[from][n].keysym = NoSymbol;
- pointer_map[from][n].keycode = NoSymbol;
- pointer_map[from][n].button = i;
- pointer_map[from][n].end = 0;
- pointer_map[from][n].down = 0;
- pointer_map[from][n].up = 0;
- } else {
- rfbLog("buttonparse: ignoring unknown "
- "keysym: %s\n", t);
- n--;
- }
- } else if (dpy) {
- /*
- * XXX may not work with -modtweak or -xkb
- */
- char *str;
- X_LOCK;
-#if NO_X11
- kcode = NoSymbol;
-#else
- kcode = XKeysymToKeycode(dpy, ksym);
-#endif
-
- pointer_map[from][n].keysym = ksym;
- pointer_map[from][n].keycode = kcode;
- pointer_map[from][n].button = 0;
- pointer_map[from][n].end = 0;
- if (! ismodkey(ksym) ) {
- /* do both down then up */
- pointer_map[from][n].down = 1;
- pointer_map[from][n].up = 1;
- } else {
- if (modisdown[kcode]) {
- pointer_map[from][n].down = 0;
- pointer_map[from][n].up = 1;
- modisdown[kcode] = 0;
- } else {
- pointer_map[from][n].down = 1;
- pointer_map[from][n].up = 0;
- modisdown[kcode] = 1;
- }
- }
- str = XKeysymToString(ksym);
- rfbLog(" event %d: keysym %s (0x%x) -> "
- "keycode 0x%x down=%d up=%d\n", n+1,
- str ? str : "null", ksym, kcode,
- pointer_map[from][n].down,
- pointer_map[from][n].up);
- X_UNLOCK;
- }
- t = strtok(NULL, "+");
- n++;
- }
-
- /* we must release any modifiers that are still down: */
- for (i=0; i<256; i++) {
- kcode = (KeyCode) i;
- if (n >= MAX_BUTTON_EVENTS) {
- rfbLog("buttonparse: too many button map "
- "events: %s\n", list);
- break;
- }
- if (modisdown[kcode]) {
- pointer_map[from][n].keysym = NoSymbol;
- pointer_map[from][n].keycode = kcode;
- pointer_map[from][n].button = 0;
- pointer_map[from][n].end = 0;
- pointer_map[from][n].down = 0;
- pointer_map[from][n].up = 1;
- modisdown[kcode] = 0;
- n++;
- }
- }
-
- /* advance the source pointer position */
- (*s) += l+2;
- } else {
- /* single digit format */
- char str[2];
- str[0] = *q;
- str[1] = '\0';
-
- to = atoi(str);
- if (to < 1) {
- rfbLog("skipping invalid remap button \"%d\" for button"
- " %d from string \"%s\"\n",
- to, from, str);
- } else {
- rfbLog("remap button %d using \"%s\"\n", from, str);
- rfbLog(" button: %d -> %d\n", from, to);
- pointer_map[from][0].keysym = NoSymbol;
- pointer_map[from][0].keycode = NoSymbol;
- pointer_map[from][0].button = to;
- pointer_map[from][0].end = 0;
- pointer_map[from][0].down = 0;
- pointer_map[from][0].up = 0;
- }
- /* advance the source pointer position */
- (*s)++;
- }
-#endif /* NO_X11 */
-}
-
-/*
- * process the -buttonmap string
- */
-void initialize_pointer_map(char *pointer_remap) {
- unsigned char map[MAX_BUTTONS];
- int i, k;
- /*
- * This routine counts the number of pointer buttons on the X
- * server (to avoid problems, even crashes, if a client has more
- * buttons). And also initializes any pointer button remapping
- * from -buttonmap option.
- */
-
- if (!raw_fb_str) {
-#if NO_X11
- num_buttons = 5;
-#else
- X_LOCK;
- num_buttons = XGetPointerMapping(dpy, map, MAX_BUTTONS);
- X_UNLOCK;
- rfbLog("The X server says there are %d mouse buttons.\n", num_buttons);
-#endif
- } else {
- num_buttons = 5;
- rfbLog("Manually set num_buttons to: %d\n", num_buttons);
- }
-
- if (num_buttons < 0) {
- num_buttons = 0;
- }
-
- /* FIXME: should use info in map[] */
- for (i=1; i<= MAX_BUTTONS; i++) {
- for (k=0; k < MAX_BUTTON_EVENTS; k++) {
- pointer_map[i][k].end = 1;
- }
- pointer_map[i][0].keysym = NoSymbol;
- pointer_map[i][0].keycode = NoSymbol;
- pointer_map[i][0].button = i;
- pointer_map[i][0].end = 0;
- pointer_map[i][0].down = 0;
- pointer_map[i][0].up = 0;
- }
-
- if (pointer_remap && *pointer_remap != '\0') {
- /* -buttonmap, format is like: 12-21=2 */
- char *p, *q, *remap = strdup(pointer_remap);
- int n;
-
- if ((p = strchr(remap, '=')) != NULL) {
- /* undocumented max button number */
- n = atoi(p+1);
- *p = '\0';
- if (n < num_buttons || num_buttons == 0) {
- num_buttons = n;
- } else {
- rfbLog("warning: increasing number of mouse "
- "buttons from %d to %d\n", num_buttons, n);
- num_buttons = n;
- }
- }
- if ((q = strchr(remap, '-')) != NULL) {
- /*
- * The '-' separates the 'from' and 'to' lists,
- * then it is kind of like tr(1).
- */
- char str[2];
- int from;
-
- rfbLog("remapping pointer buttons using string:\n");
- rfbLog(" \"%s\"\n", remap);
-
- p = remap;
- q++;
- i = 0;
- str[1] = '\0';
- while (*p != '-') {
- str[0] = *p;
- from = atoi(str);
- buttonparse(from, &q);
- p++;
- }
- }
- free(remap);
- }
-}
-
-/*
- * Send a pointer position event to the X server.
- */
-void update_x11_pointer_position(int x, int y) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!x || !y) {}
- return;
-#else
- int rc;
-
- RAWFB_RET_VOID
-
- X_LOCK;
- if (!always_inject && cursor_x == x && cursor_y == y) {
- ;
- } else if (use_xwarppointer) {
- /*
- * off_x and off_y not needed with XWarpPointer since
- * window is used:
- */
- XWarpPointer(dpy, None, window, 0, 0, 0, 0, x + coff_x,
- y + coff_y);
- } else {
- XTestFakeMotionEvent_wr(dpy, scr, x + off_x + coff_x,
- y + off_y + coff_y, CurrentTime);
- }
- X_UNLOCK;
-
- if (cursor_x != x || cursor_y != y) {
- last_pointer_motion_time = dnow();
- }
-
- cursor_x = x;
- cursor_y = y;
-
- /* record the x, y position for the rfb screen as well. */
- cursor_position(x, y);
-
- /* change the cursor shape if necessary */
- rc = set_cursor(x, y, get_which_cursor());
- cursor_changes += rc;
-
- last_event = last_input = last_pointer_input = time(NULL);
-#endif /* NO_X11 */
-}
-
-void do_button_mask_change(int mask, int button) {
-#if NO_X11
- if (!mask || !button) {}
- return;
-#else
- int mb, k, i = button-1;
-
- /*
- * this expands to any pointer_map button -> keystrokes
- * remappings. Usually just k=0 and we send one button event.
- */
- for (k=0; k < MAX_BUTTON_EVENTS; k++) {
- int bmask = (mask & (1<<i));
-
- if (pointer_map[i+1][k].end) {
- break;
- }
-
- if (pointer_map[i+1][k].button) {
- /* send button up or down */
-
- mb = pointer_map[i+1][k].button;
- if ((num_buttons && mb > num_buttons) || mb < 1) {
- rfbLog("ignoring mouse button out of "
- "bounds: %d>%d mask: 0x%x -> 0x%x\n",
- mb, num_buttons, button_mask, mask);
- continue;
- }
- if (debug_pointer) {
- rfbLog("pointer(): sending button %d"
- " %s (event %d)\n", mb, bmask
- ? "down" : "up", k+1);
- }
- XTestFakeButtonEvent_wr(dpy, mb, (mask & (1<<i))
- ? True : False, CurrentTime);
- } else {
- /* send keysym up or down */
- KeyCode key = pointer_map[i+1][k].keycode;
- int up = pointer_map[i+1][k].up;
- int down = pointer_map[i+1][k].down;
-
- if (! bmask) {
- /* do not send keysym on button up */
- continue;
- }
- if (debug_pointer && dpy) {
- char *str = XKeysymToString(XKeycodeToKeysym(
- dpy, key, 0));
- rfbLog("pointer(): sending button %d "
- "down as keycode 0x%x (event %d)\n",
- i+1, key, k+1);
- rfbLog(" down=%d up=%d keysym: "
- "%s\n", down, up, str ? str : "null");
- }
- if (down) {
- XTestFakeKeyEvent_wr(dpy, key, True,
- CurrentTime);
- }
- if (up) {
- XTestFakeKeyEvent_wr(dpy, key, False,
- CurrentTime);
- }
- }
- }
-#endif /* NO_X11 */
-}
-
-/*
- * Send a pointer button event to the X server.
- */
-static void update_x11_pointer_mask(int mask) {
-#if NO_X11
- last_event = last_input = last_pointer_input = time(NULL);
-
- RAWFB_RET_VOID
- if (!mask) {}
- return;
-#else
- int snapped = 0, xr_mouse = 1, i;
- last_event = last_input = last_pointer_input = time(NULL);
-
- RAWFB_RET_VOID
-
- if (mask != button_mask) {
- last_pointer_click_time = dnow();
- }
-
- if (nofb) {
- xr_mouse = 0;
- } else if (!strcmp(scroll_copyrect, "never")) {
- xr_mouse = 0;
- } else if (!strcmp(scroll_copyrect, "keys")) {
- xr_mouse = 0;
- } else if (skip_cr_when_scaling("scroll")) {
- xr_mouse = 0;
- } else if (xrecord_skip_button(mask, button_mask)) {
- xr_mouse = 0;
- }
-
- if (mask && use_xrecord && ! xrecording && xr_mouse) {
- static int px, py, x, y, w, h, got_wm_frame;
- static XWindowAttributes attr;
- Window frame = None, mwin = None;
- int skip = 0;
-
- if (!button_mask) {
- X_LOCK;
- if (get_wm_frame_pos(&px, &py, &x, &y, &w, &h,
- &frame, &mwin)) {
- got_wm_frame = 1;
-if (debug_scroll > 1) fprintf(stderr, "wm_win: 0x%lx\n", mwin);
- if (mwin != None) {
- if (!valid_window(mwin, &attr, 1)) {
- mwin = None;
- }
- }
- } else {
- got_wm_frame = 0;
- }
- X_UNLOCK;
- }
- if (got_wm_frame) {
- if (wireframe && near_wm_edge(x, y, w, h, px, py)) {
- /* step out of wireframe's way */
- skip = 1;
- } else {
- int ok = 0;
- int btn4 = (1<<3);
- int btn5 = (1<<4);
-
- if (near_scrollbar_edge(x, y, w, h, px, py)) {
- ok = 1;
- }
- if (mask & (btn4|btn5)) {
- /* scroll wheel mouse */
- ok = 1;
- }
- if (mwin != None) {
- /* skinny internal window */
- int w = attr.width;
- int h = attr.height;
- if (h > 10 * w || w > 10 * h) {
-if (debug_scroll > 1) fprintf(stderr, "internal scrollbar: %dx%d\n", w, h);
- ok = 1;
- }
- }
- if (! ok) {
- skip = 1;
- }
- }
- }
-
- if (! skip) {
- xrecord_watch(1, SCR_MOUSE);
- snapshot_stack_list(0, 0.50);
- snapped = 1;
- if (button_mask) {
- xrecord_set_by_mouse = 1;
- } else {
- update_stack_list();
- xrecord_set_by_mouse = 2;
- }
- }
- }
-
- if (mask && !button_mask) {
- /* button down, snapshot the stacking list before flushing */
- if (wireframe && !wireframe_in_progress &&
- strcmp(wireframe_copyrect, "never")) {
- if (! snapped) {
- snapshot_stack_list(0, 0.0);
- }
- }
- }
-
- X_LOCK;
-
- /* look for buttons that have be clicked or released: */
- for (i=0; i < MAX_BUTTONS; i++) {
- if ( (button_mask & (1<<i)) != (mask & (1<<i)) ) {
- if (debug_pointer) {
- rfbLog("pointer(): mask change: mask: 0x%x -> "
- "0x%x button: %d\n", button_mask, mask,i+1);
- }
- do_button_mask_change(mask, i+1); /* button # is i+1 */
- }
- }
-
- X_UNLOCK;
-
- /*
- * Remember the button state for next time and also for the
- * -nodragging case:
- */
- button_mask_prev = button_mask;
- button_mask = mask;
-#endif /* NO_X11 */
-}
-
-/* for -pipeinput */
-
-
-static void pipe_pointer(int mask, int x, int y, rfbClientPtr client) {
- int can_input = 0, uid = 0;
- allowed_input_t input;
- ClientData *cd = (ClientData *) client->clientData;
- char hint[MAX_BUTTONS * 20];
-
- if (pipeinput_int == PIPEINPUT_VID) {
- v4l_pointer_command(mask, x, y, client);
- } else if (pipeinput_int == PIPEINPUT_CONSOLE) {
- console_pointer_command(mask, x, y, client);
- } else if (pipeinput_int == PIPEINPUT_UINPUT) {
- uinput_pointer_command(mask, x, y, client);
- } else if (pipeinput_int == PIPEINPUT_MACOSX) {
- macosx_pointer_command(mask, x, y, client);
- } else if (pipeinput_int == PIPEINPUT_VNC) {
- vnc_reflect_send_pointer(x, y, mask);
- }
- if (pipeinput_fh == NULL) {
- return;
- }
-
- if (! view_only) {
- get_allowed_input(client, &input);
- if (input.motion || input.button) {
- can_input = 1; /* XXX distinguish later */
- }
- }
-
- if (cd) {
- uid = cd->uid;
- }
- if (! can_input) {
- uid = -uid;
- }
-
- hint[0] = '\0';
- if (mask == button_mask) {
- strcat(hint, "None");
- } else {
- int i, old, newb, m = 1, cnt = 0;
- for (i=0; i<MAX_BUTTONS; i++) {
- char s[20];
-
- old = button_mask & m;
- newb = mask & m;
- m = m << 1;
-
- if (old == newb) {
- continue;
- }
- if (hint[0] != '\0') {
- strcat(hint, ",");
- }
- if (newb && ! old) {
- sprintf(s, "ButtonPress-%d", i+1);
- cnt++;
- } else if (! newb && old) {
- sprintf(s, "ButtonRelease-%d", i+1);
- cnt++;
- }
- strcat(hint, s);
- }
- if (! cnt) {
- strcpy(hint, "None");
- }
- }
-
- fprintf(pipeinput_fh, "Pointer %d %d %d %d %s\n", uid, x, y,
- mask, hint);
- fflush(pipeinput_fh);
- check_pipeinput();
-}
-
-/*
- * Actual callback from libvncserver when it gets a pointer event.
- * This may queue pointer events rather than sending them immediately
- * to the X server. (see update_x11_pointer*())
- */
-void pointer_event(int mask, int x, int y, rfbClientPtr client) {
- allowed_input_t input;
- int sent = 0, buffer_it = 0;
- double now;
-
- if (threads_drop_input) {
- return;
- }
-
- if (mask >= 0) {
- got_pointer_calls++;
- }
-
- if (debug_pointer && mask >= 0) {
- static int show_motion = -1;
- static double last_pointer = 0.0;
- double tnow, dt;
- static int last_x, last_y;
- if (show_motion == -1) {
- if (getenv("X11VNC_DB_NOMOTION")) {
- show_motion = 0;
- } else {
- show_motion = 1;
- }
- }
- dtime0(&tnow);
- tnow -= x11vnc_start;
- dt = tnow - last_pointer;
- last_pointer = tnow;
- if (show_motion) {
- rfbLog("# pointer(mask: 0x%x, x:%4d, y:%4d) "
- "dx: %3d dy: %3d dt: %.4f t: %.4f\n", mask, x, y,
- x - last_x, y - last_y, dt, tnow);
- }
- last_x = x;
- last_y = y;
- }
-
- if (unixpw_in_progress) {
- return;
- }
-
- get_allowed_input(client, &input);
-
- if (rotating) {
- rotate_coords_inverse(x, y, &x, &y, -1, -1);
- }
-
- if (scaling) {
- /* map from rfb size to X11 size: */
- x = ((double) x / scaled_x) * dpy_x;
- x = nfix(x, dpy_x);
- y = ((double) y / scaled_y) * dpy_y;
- y = nfix(y, dpy_y);
- }
-
- INPUT_LOCK;
-
- if ((pipeinput_fh != NULL || pipeinput_int) && mask >= 0) {
- pipe_pointer(mask, x, y, client); /* MACOSX here. */
- if (! pipeinput_tee) {
- if (! view_only || raw_fb) { /* raw_fb hack */
- got_user_input++;
- got_pointer_input++;
- last_pointer_client = client;
- last_pointer_time = dnow();
- last_event = last_input = last_pointer_input = time(NULL);
- }
- if (input.motion) {
- /* raw_fb hack track button state */
- button_mask_prev = button_mask;
- button_mask = mask;
- }
- if (!view_only && (input.motion || input.button)) {
- last_rfb_ptr_injected = dnow();
- }
- INPUT_UNLOCK;
- return;
- }
- }
-
- if (view_only) {
- INPUT_UNLOCK;
- return;
- }
-
- now = dnow();
-
- if (mask >= 0) {
- /*
- * mask = -1 is a special case call from scan_for_updates()
- * to flush the event queue; there is no real pointer event.
- */
- if (! input.motion && ! input.button) {
- INPUT_UNLOCK;
- return;
- }
-
- got_user_input++;
- got_pointer_input++;
- last_pointer_client = client;
-
- last_pointer_time = now;
- last_rfb_ptr_injected = dnow();
-
- if (blackout_ptr && blackouts) {
- int b, ok = 1;
- /* see if it goes into the blacked out region */
- for (b=0; b < blackouts; b++) {
- if (x < blackr[b].x1 || x > blackr[b].x2) {
- continue;
- }
- if (y < blackr[b].y1 || y > blackr[b].y2) {
- continue;
- }
- /* x1 <= x <= x2 and y1 <= y <= y2 */
- ok = 0;
- break;
- }
- if (! ok) {
- if (debug_pointer) {
- rfbLog("pointer(): blackout_ptr skipping "
- "x=%d y=%d in rectangle %d,%d %d,%d\n", x, y,
- blackr[b].x1, blackr[b].y1,
- blackr[b].x2, blackr[b].y2);
- }
- INPUT_UNLOCK;
- return;
- }
- }
- }
-
- /*
- * The following is hopefully an improvement wrt response during
- * pointer user input (window drags) for the threaded case.
- * See check_user_input() for the more complicated things we do
- * in the non-threaded case.
- */
- if ((use_threads && pointer_mode != 1) || pointer_flush_delay > 0.0) {
-# define NEV 32
- /* storage for the event queue */
- static int nevents = 0;
- static int ev[NEV][3];
- int i;
- /* timer things */
- static double dt = 0.0, tmr = 0.0, maxwait = 0.4;
-
- if (pointer_flush_delay > 0.0) {
- maxwait = pointer_flush_delay;
- }
- if (mask >= 0) {
- if (fb_copy_in_progress || pointer_flush_delay > 0.0) {
- buffer_it = 1;
- }
- }
-
- POINTER_LOCK;
-
- /*
- * If the framebuffer is being copied in another thread
- * (scan_for_updates()), we will queue up to 32 pointer
- * events for later. The idea is by delaying these input
- * events, the screen is less likely to change during the
- * copying period, and so will give rise to less window
- * "tearing".
- *
- * Tearing is not completely eliminated because we do
- * not suspend work in the other libvncserver threads.
- * Maybe that is a possibility with a mutex...
- */
- if (buffer_it) {
- /*
- * mask = -1 is an all-clear signal from
- * scan_for_updates().
- *
- * dt is a timer in seconds; we only queue for so long.
- */
- dt += dtime(&tmr);
-
- if (nevents < NEV && dt < maxwait) {
- i = nevents++;
- ev[i][0] = mask;
- ev[i][1] = x;
- ev[i][2] = y;
- if (! input.button) {
- ev[i][0] = -1;
- }
- if (! input.motion) {
- ev[i][1] = -1;
- ev[i][2] = -1;
- }
- if (debug_pointer) {
- rfbLog("pointer(): deferring event %d"
- " %.4f\n", i, tmr - x11vnc_start);
- }
- POINTER_UNLOCK;
- INPUT_UNLOCK;
- return;
- }
- }
-
- /* time to send the queue */
- for (i=0; i<nevents; i++) {
- int sent = 0;
- if (mask < 0 && client != NULL) {
- /* hack to only push the latest event */
- if (i < nevents - 1) {
- if (debug_pointer) {
- rfbLog("- skip deferred event:"
- " %d\n", i);
- }
- continue;
- }
- }
- if (debug_pointer) {
- rfbLog("pointer(): sending event %d %.4f\n",
- i+1, dnowx());
- }
- if (ev[i][1] >= 0) {
- update_x11_pointer_position(ev[i][1], ev[i][2]);
- sent = 1;
- }
- if (ev[i][0] >= 0) {
- update_x11_pointer_mask(ev[i][0]);
- sent = 1;
- }
-
- if (sent) {
- pointer_queued_sent++;
- }
- }
- if (nevents && dt > maxwait) {
- if (dpy) { /* raw_fb hack */
- if (mask < 0) {
- if (debug_pointer) {
- rfbLog("pointer(): calling XFlush "
- "%.4f\n", dnowx());
- }
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- }
- }
- }
- nevents = 0; /* reset everything */
- dt = 0.0;
- dtime0(&tmr);
-
- POINTER_UNLOCK;
- }
- if (mask < 0) { /* -1 just means flush the event queue */
- if (debug_pointer) {
- rfbLog("pointer(): flush only. %.4f\n",
- dnowx());
- }
- INPUT_UNLOCK;
- return;
- }
-
- /* update the X display with the event: */
- if (input.motion) {
- update_x11_pointer_position(x, y);
- sent = 1;
- }
- if (input.button) {
- if (mask != button_mask) {
- button_change_x = cursor_x;
- button_change_y = cursor_y;
- }
- update_x11_pointer_mask(mask);
- sent = 1;
- }
-
- if (! dpy) {
- ;
- } else if (nofb && sent) {
- /*
- * nofb is for, e.g. Win2VNC, where fastest pointer
- * updates are desired.
- */
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- } else if (buffer_it) {
- if (debug_pointer) {
- rfbLog("pointer(): calling XFlush+"
- "%.4f\n", dnowx());
- }
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- }
- INPUT_UNLOCK;
-}
-
-void initialize_pipeinput(void) {
- char *p = NULL;
-
- if (pipeinput_fh != NULL) {
- rfbLog("closing pipeinput stream: %p\n", pipeinput_fh);
- pclose(pipeinput_fh);
- pipeinput_fh = NULL;
- }
-
- pipeinput_tee = 0;
- if (pipeinput_opts) {
- free(pipeinput_opts);
- pipeinput_opts = NULL;
- }
-
- if (! pipeinput_str) {
- return;
- }
-
- /* look for options: tee, reopen, ... */
- if (strstr(pipeinput_str, "UINPUT") == pipeinput_str) {
- ;
- } else {
- p = strchr(pipeinput_str, ':');
- }
- if (p != NULL) {
- char *str, *opt, *q;
- int got = 0;
- *p = '\0';
- str = strdup(pipeinput_str);
- opt = strdup(pipeinput_str);
- *p = ':';
- q = strtok(str, ",");
- while (q) {
- if (!strcmp(q, "key") || !strcmp(q, "keycodes")) {
- got = 1;
- }
- if (!strcmp(q, "reopen")) {
- got = 1;
- }
- if (!strcmp(q, "tee")) {
- pipeinput_tee = 1;
- got = 1;
- }
- q = strtok(NULL, ",");
- }
- if (got) {
- pipeinput_opts = opt;
- } else {
- free(opt);
- }
- free(str);
- p++;
- } else {
- p = pipeinput_str;
- }
-if (0) fprintf(stderr, "initialize_pipeinput: %s -- %s\n", pipeinput_str, p);
-
- if (!strcmp(p, "VID")) {
- pipeinput_int = PIPEINPUT_VID;
- return;
- } else if (strstr(p, "CONSOLE") == p) {
- int tty = 0, n;
- char dev[32];
- if (sscanf(p, "CONSOLE%d", &n) == 1) {
- tty = n;
- }
- sprintf(dev, "/dev/tty%d", tty);
- pipeinput_cons_fd = open(dev, O_WRONLY);
- if (pipeinput_cons_fd >= 0) {
- rfbLog("pipeinput: using linux console: %s\n", dev);
- if (pipeinput_cons_dev) {
- free(pipeinput_cons_dev);
- }
- pipeinput_cons_dev = strdup(dev);
- pipeinput_int = PIPEINPUT_CONSOLE;
- } 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) {
- char *q = strchr(p, ':');
- if (q) {
- parse_uinput_str(q+1);
- }
- pipeinput_int = PIPEINPUT_UINPUT;
- initialize_uinput();
- return;
- } else if (strstr(p, "MACOSX") == p) {
- pipeinput_int = PIPEINPUT_MACOSX;
- return;
- } else if (strstr(p, "VNC") == p) {
- pipeinput_int = PIPEINPUT_VNC;
- return;
- }
-
- set_child_info();
- /* pipeinput */
- if (no_external_cmds || !cmd_ok("pipeinput")) {
- rfbLogEnable(1);
- rfbLog("cannot run external commands in -nocmds mode:\n");
- rfbLog(" \"%s\"\n", p);
- rfbLog(" exiting.\n");
- clean_up_exit(1);
- }
- rfbLog("pipeinput: starting: \"%s\"...\n", p);
- close_exec_fds();
- pipeinput_fh = popen(p, "w");
-
- if (! pipeinput_fh) {
- rfbLog("popen(\"%s\", \"w\") failed.\n", p);
- rfbLogPerror("popen");
- rfbLog("Disabling -pipeinput mode.\n");
- return;
- }
-
- fprintf(pipeinput_fh, "%s",
-"# \n"
-"# Format of the -pipeinput stream:\n"
-"# --------------------------------\n"
-"#\n"
-"# Lines like these beginning with '#' are to be ignored.\n"
-"#\n"
-"# Pointer events (mouse motion and button clicks) come in the form:\n"
-"#\n"
-"#\n"
-"# Pointer <client#> <x> <y> <mask> <hint>\n"
-"#\n"
-"#\n"
-"# The <client#> is a decimal integer uniquely identifying the client\n"
-"# that generated the event. If it is negative that means this event\n"
-"# would have been discarded since the client was viewonly.\n"
-"#\n"
-"# <x> and <y> are decimal integers reflecting the position on the screen\n"
-"# the event took place at.\n"
-"#\n"
-"# <mask> is the button mask indicating the button press state, as normal\n"
-"# 0 means no buttons pressed, 1 means button 1 is down 3 (11) means buttons\n"
-"# 1 and 2 are down, etc.\n"
-"#\n"
-"# <hint> is a string containing no spaces and may be ignored.\n"
-"# It contains some interpretation about what has happened.\n"
-"# It can be:\n"
-"#\n"
-"# None (nothing to report)\n"
-"# ButtonPress-N (this event will cause button-N to be pressed) \n"
-"# ButtonRelease-N (this event will cause button-N to be released) \n"
-"#\n"
-"# if two more more buttons change state in one event they are listed\n"
-"# separated by commas.\n"
-"#\n"
-"# One might parse a Pointer line with:\n"
-"#\n"
-"# int client, x, y, mask; char hint[100];\n"
-"# sscanf(line, \"Pointer %d %d %d %d %s\", &client, &x, &y, &mask, hint);\n"
-"#\n"
-"#\n"
-"# Keysym events (keyboard presses and releases) come in the form:\n"
-"#\n"
-"#\n"
-"# Keysym <client#> <down> <keysym#> <keysym-name> <hint>\n"
-"#\n"
-"#\n"
-"# The <client#> is as with Pointer.\n"
-"#\n"
-"# <down> is a decimal either 1 or 0 indicating KeyPress or KeyRelease,\n"
-"# respectively.\n"
-"#\n"
-"# <keysym#> is a decimal integer incidating the Keysym of the event.\n"
-"#\n"
-"# <keysym-name> is the corresponding Keysym name.\n"
-"#\n"
-"# See the file /usr/include/X11/keysymdef.h for the mappings.\n"
-"# You basically remove the leading 'XK_' prefix from the macro name in\n"
-"# that file to get the Keysym name.\n"
-"#\n"
-"# One might parse a Keysym line with:\n"
-"#\n"
-"# int client, down, keysym; char name[100], hint[100];\n"
-"# sscanf(line, \"Keysym %d %d %d %s %s\", &client, &down, &keysym, name, hint);\n"
-"#\n"
-"# The <hint> value is currently just None, KeyPress, or KeyRelease.\n"
-"#\n"
-"# In the future <hint> will provide a hint for the sequence of KeyCodes\n"
-"# (i.e. keyboard scancodes) that x11vnc would inject to an X display to\n"
-"# simulate the Keysym.\n"
-"#\n"
-"# You see, some Keysyms will require more than one injected Keycode to\n"
-"# generate the symbol. E.g. the Keysym \"ampersand\" going down usually\n"
-"# requires a Shift key going down, then the key with the \"&\" on it going\n"
-"# down, and, perhaps, the Shift key going up (that is how x11vnc does it).\n"
-"#\n"
-"# The Keysym => Keycode(s) stuff gets pretty messy. Hopefully the Keysym\n"
-"# info will be enough for most purposes (having identical keyboards on\n"
-"# both sides helps).\n"
-"#\n"
-"# Parsing example for perl:\n"
-"#\n"
-"# while (<>) {\n"
-"# chomp;\n"
-"# if (/^Pointer/) {\n"
-"# my ($p, $client, $x, $y, $mask, $hint) = split(' ', $_, 6);\n"
-"# do_pointer($client, $x, $y, $mask, $hint);\n"
-"# } elsif (/^Keysym/) {\n"
-"# my ($k, $client, $down, $keysym, $name, $hint) = split(' ', $_, 6);\n"
-"# do_keysym($client, $down, $keysym, $name, $hint);\n"
-"# }\n"
-"# }\n"
-"#\n"
-"#\n"
-"# Here comes your stream. The following token will always indicate the\n"
-"# end of this informational text:\n"
-"# END_OF_TOP\n"
-);
- fflush(pipeinput_fh);
- if (raw_fb_str) {
- /* the pipe program may actually create the fb */
- sleep(1);
- }
-}
-
-int check_pipeinput(void) {
- if (! pipeinput_fh) {
- return 1;
- }
- if (ferror(pipeinput_fh)) {
- rfbLog("pipeinput pipe has ferror. %p\n", pipeinput_fh);
-
- if (pipeinput_opts && strstr(pipeinput_opts, "reopen")) {
- rfbLog("restarting -pipeinput pipe...\n");
- initialize_pipeinput();
- if (pipeinput_fh) {
- return 1;
- } else {
- return 0;
- }
- } else {
- rfbLog("closing -pipeinput pipe...\n");
- pclose(pipeinput_fh);
- pipeinput_fh = NULL;
- return 0;
- }
- }
- return 1;
-}
-
-
diff --git a/x11vnc/pointer.h b/x11vnc/pointer.h
deleted file mode 100644
index 1fe5e0b..0000000
--- a/x11vnc/pointer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_POINTER_H
-#define _X11VNC_POINTER_H
-
-/* -- pointer.h -- */
-
-extern int pointer_queued_sent;
-
-extern void initialize_pointer_map(char *pointer_remap);
-extern void do_button_mask_change(int mask, int button);
-extern void pointer_event(int mask, int x, int y, rfbClientPtr client);
-extern int check_pipeinput(void);
-extern void initialize_pipeinput(void);
-extern void update_x11_pointer_position(int x, int y);
-
-#endif /* _X11VNC_POINTER_H */
diff --git a/x11vnc/rates.c b/x11vnc/rates.c
deleted file mode 100644
index ee9ca05..0000000
--- a/x11vnc/rates.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- rates.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "scan.h"
-
-int measure_speeds = 1;
-int speeds_net_rate = 0;
-int speeds_net_rate_measured = 0;
-int speeds_net_latency = 0;
-int speeds_net_latency_measured = 0;
-int speeds_read_rate = 0;
-int speeds_read_rate_measured = 0;
-
-
-int get_cmp_rate(void);
-int get_raw_rate(void);
-void initialize_speeds(void);
-int get_read_rate(void);
-int link_rate(int *latency, int *netrate);
-int get_net_rate(void);
-int get_net_latency(void);
-void measure_send_rates(int init);
-
-
-static void measure_display_hook(rfbClientPtr cl);
-static int get_rate(int which);
-static int get_latency(void);
-
-
-static void measure_display_hook(rfbClientPtr cl) {
- ClientData *cd = (ClientData *) cl->clientData;
- if (! cd) {
- return;
- }
- dtime0(&cd->timer);
-}
-
-static int get_rate(int which) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int irate, irate_min = 1; /* 1 KB/sec */
- int irate_max = 100000; /* 100 MB/sec */
- int count = 0;
- double slowest = -1.0, rate;
- static double save_rate = 1000 * NETRATE0;
-
- if (!screen) {
- return 0;
- }
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd = (ClientData *) cl->clientData;
-
- if (! cd) {
- continue;
- }
- if (cl->state != RFB_NORMAL) {
- continue;
- }
- if (cd->send_cmp_rate == 0.0 || cd->send_raw_rate == 0.0) {
- continue;
- }
- count++;
-
- if (which == 0) {
- rate = cd->send_cmp_rate;
- } else {
- rate = cd->send_raw_rate;
- }
- if (slowest == -1.0 || rate < slowest) {
- slowest = rate;
- }
-
- }
- rfbReleaseClientIterator(iter);
-
- if (! count) {
- return NETRATE0;
- }
-
- if (slowest == -1.0) {
- slowest = save_rate;
- } else {
- save_rate = slowest;
- }
-
- irate = (int) (slowest/1000.0);
- if (irate < irate_min) {
- irate = irate_min;
- }
- if (irate > irate_max) {
- irate = irate_max;
- }
-if (0) fprintf(stderr, "get_rate(%d) %d %.3f/%.3f\n", which, irate, save_rate, slowest);
-
- return irate;
-}
-
-static int get_latency(void) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int ilat, ilat_min = 1; /* 1 ms */
- int ilat_max = 2000; /* 2 sec */
- double slowest = -1.0, lat;
- static double save_lat = ((double) LATENCY0)/1000.0;
- int count = 0;
-
- if (!screen) {
- return 0;
- }
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd = (ClientData *) cl->clientData;
-
- if (! cd) {
- continue;
- }
- if (cl->state != RFB_NORMAL) {
- continue;
- }
- if (cd->latency == 0.0) {
- continue;
- }
- count++;
-
- lat = cd->latency;
- if (slowest == -1.0 || lat > slowest) {
- slowest = lat;
- }
- }
- rfbReleaseClientIterator(iter);
-
- if (! count) {
- return LATENCY0;
- }
-
- if (slowest == -1.0) {
- slowest = save_lat;
- } else {
- save_lat = slowest;
- }
-
- ilat = (int) (slowest * 1000.0);
- if (ilat < ilat_min) {
- ilat = ilat_min;
- }
- if (ilat > ilat_max) {
- ilat = ilat_max;
- }
-
- return ilat;
-}
-
-int get_cmp_rate(void) {
- return get_rate(0);
-}
-
-int get_raw_rate(void) {
- return get_rate(1);
-}
-
-void initialize_speeds(void) {
- char *s, *s_in, *p;
- int i;
-
- speeds_read_rate = 0;
- speeds_net_rate = 0;
- speeds_net_latency = 0;
- if (! speeds_str || *speeds_str == '\0') {
- s_in = strdup("");
- } else {
- s_in = strdup(speeds_str);
- }
-
- if (!strcmp(s_in, "modem")) {
- s = strdup("6,4,200");
- } else if (!strcmp(s_in, "dsl")) {
- s = strdup("6,100,50");
- } else if (!strcmp(s_in, "lan")) {
- s = strdup("6,5000,1");
- } else {
- s = strdup(s_in);
- }
-
- p = strtok(s, ",");
- i = 0;
- while (p) {
- double val;
- if (*p != '\0') {
- val = atof(p);
- if (i==0) {
- speeds_read_rate = (int) 1000000 * val;
- } else if (i==1) {
- speeds_net_rate = (int) 1000 * val;
- } else if (i==2) {
- speeds_net_latency = (int) val;
- }
- }
- i++;
- p = strtok(NULL, ",");
- }
- free(s);
- free(s_in);
-
- if (! speeds_read_rate) {
- int n = 0;
- double dt, timer;
-#ifdef MACOSX
- if (macosx_console && macosx_read_opengl && fullscreen) {
- copy_image(fullscreen, 0, 0, 0, 0);
- usleep(10 * 1000);
- }
-#endif
-
- dtime0(&timer);
- if (fullscreen) {
- copy_image(fullscreen, 0, 0, 0, 0);
- n = fullscreen->bytes_per_line * fullscreen->height;
- } else if (scanline) {
- copy_image(scanline, 0, 0, 0, 0);
- n = scanline->bytes_per_line * scanline->height;
- }
- dt = dtime(&timer);
- if (n && dt > 0.0) {
- double rate = ((double) n) / dt;
- speeds_read_rate_measured = (int) (rate/1000000.0);
- if (speeds_read_rate_measured < 1) {
- speeds_read_rate_measured = 1;
- } else {
- rfbLog("fb read rate: %d MB/sec\n",
- speeds_read_rate_measured);
- }
- }
- }
-}
-
-int get_read_rate(void) {
- if (speeds_read_rate) {
- return speeds_read_rate;
- }
- if (speeds_read_rate_measured) {
- return speeds_read_rate_measured;
- }
- return 0;
-}
-
-int link_rate(int *latency, int *netrate) {
- *latency = get_net_latency();
- *netrate = get_net_rate();
-
- if (speeds_str) {
- if (!strcmp(speeds_str, "modem")) {
- return LR_DIALUP;
- } else if (!strcmp(speeds_str, "dsl")) {
- return LR_BROADBAND;
- } else if (!strcmp(speeds_str, "lan")) {
- return LR_LAN;
- }
- }
-
- if (*latency == LATENCY0 && *netrate == NETRATE0) {
- return LR_UNSET;
- } else if (*latency > 150 || *netrate < 20) {
- return LR_DIALUP;
- } else if (*latency > 50 || *netrate < 150) {
- return LR_BROADBAND;
- } else if (*latency < 10 && *netrate > 300) {
- return LR_LAN;
- } else {
- return LR_UNKNOWN;
- }
-}
-
-int get_net_rate(void) {
- int spm = speeds_net_rate_measured;
- if (speeds_net_rate) {
- return speeds_net_rate;
- }
- if (! spm || spm == NETRATE0) {
- speeds_net_rate_measured = get_cmp_rate();
- }
- if (speeds_net_rate_measured) {
- return speeds_net_rate_measured;
- }
- return 0;
-}
-
-int get_net_latency(void) {
- int spm = speeds_net_latency_measured;
- if (speeds_net_latency) {
- return speeds_net_latency;
- }
- if (! spm || spm == LATENCY0) {
- speeds_net_latency_measured = get_latency();
- }
- if (speeds_net_latency_measured) {
- return speeds_net_latency_measured;
- }
- return 0;
-}
-
-void measure_send_rates(int init) {
- double cmp_rate, raw_rate;
- static double now, start = 0.0;
- static rfbDisplayHookPtr orig_display_hook = NULL;
- double cmp_max = 1.0e+08; /* 100 MB/sec */
- double cmp_min = 1000.0; /* 9600baud */
- double lat_max = 5.0; /* 5 sec */
- double lat_min = .0005; /* 0.5 ms */
- int min_cmp = 10000, nclients;
- rfbClientIteratorPtr iter;
- rfbClientPtr cl0, cl;
- int msg = 0, clcnt0 = 0, cc;
- int db = 0, ouch_db = 0, ouch = 0;
-
- if (! measure_speeds) {
- return;
- }
- if (speeds_net_rate && speeds_net_latency) {
- return;
- }
- if (!client_count) {
- return;
- }
-
- if (! orig_display_hook) {
- orig_display_hook = screen->displayHook;
- }
-
- if (start == 0.0) {
- dtime(&start);
- }
-
- dtime0(&now);
- if (now < last_client_gone+4.0) {
- return;
- }
- now = now - start;
-
- nclients = 0;
-
- if (!screen) {
- return;
- }
-
- cl0 = NULL;
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd = (ClientData *) cl->clientData;
-
- if (! cd) {
- continue;
- }
- if (cd->send_cmp_rate > 0.0) {
- continue;
- }
- if (cl->onHold) {
- continue;
- }
- nclients++;
- if (cl0 == NULL) {
- cl0 = cl;
- }
- }
- rfbReleaseClientIterator(iter);
-
- cl = cl0;
- cc = 0;
-
- while (cl != NULL && cc++ == 0) {
- int defer, i, cbs, rbs;
- char *httpdir;
- double dt, dt1 = 0.0, dt2, dt3;
- double tm, spin_max = 15.0, spin_lat_max = 1.5;
- int got_t2 = 0, got_t3 = 0;
- ClientData *cd = (ClientData *) cl->clientData;
-
-#if 0
- for (i=0; i<MAX_ENCODINGS; i++) {
- cbs += cl->bytesSent[i];
- }
- rbs = cl->rawBytesEquivalent;
-#else
-#if LIBVNCSERVER_HAS_STATS
- cbs = rfbStatGetSentBytes(cl);
- rbs = rfbStatGetSentBytesIfRaw(cl);
-#endif
-#endif
-
- if (init) {
-
-if (db) fprintf(stderr, "%d client num rects req: %d mod: %d cbs: %d "
- "rbs: %d dt1: %.3f t: %.3f\n", init,
- (int) sraRgnCountRects(cl->requestedRegion),
- (int) sraRgnCountRects(cl->modifiedRegion), cbs, rbs, dt1, now);
-
- cd->timer = dnow();
- cd->cmp_bytes_sent = cbs;
- cd->raw_bytes_sent = rbs;
- continue;
- }
-
- /* first part of the bulk transfer of initial screen */
- dt1 = dtime(&cd->timer);
-
-if (db) fprintf(stderr, "%d client num rects req: %d mod: %d cbs: %d "
- "rbs: %d dt1: %.3f t: %.3f\n", init,
- (int) sraRgnCountRects(cl->requestedRegion),
- (int) sraRgnCountRects(cl->modifiedRegion), cbs, rbs, dt1, now);
-
- if (dt1 <= 0.0) {
- continue;
- }
-
- cbs = cbs - cd->cmp_bytes_sent;
- rbs = rbs - cd->raw_bytes_sent;
-
- if (cbs < min_cmp) {
- continue;
- }
-
- if (ouch_db) fprintf(stderr, "START-OUCH: %d\n", client_count);
- clcnt0 = client_count;
-#define OUCH ( ouch || (ouch = (!client_count || client_count != clcnt0 || dnow() < last_client_gone+4.0)) )
-
- rfbPE(1000);
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-A\n");
- if (OUCH) continue;
-
- if (use_threads) LOCK(cl->updateMutex);
-
- if (sraRgnCountRects(cl->modifiedRegion)) {
- rfbPE(1000);
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-B\n");
- if (use_threads) UNLOCK(cl->updateMutex);
- if (OUCH) continue;
- }
-
- if (use_threads) UNLOCK(cl->updateMutex);
-
- defer = screen->deferUpdateTime;
- httpdir = screen->httpDir;
- screen->deferUpdateTime = 0;
- screen->httpDir = NULL;
-
- /* mark a small rectangle: */
- mark_rect_as_modified(0, 0, 16, 16, 1);
-
- dtime0(&tm);
-
- dt2 = 0.0;
- dt3 = 0.0;
-
- if (dt1 < 0.25) {
- /* try to cut it down to avoid long pauses. */
- spin_max = 5.0;
- }
-
- /* when req1 = 1 mod1 == 0, end of 2nd part of bulk transfer */
- while (1) {
- int req0, req1, mod0, mod1;
-
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-C1\n");
- if (OUCH) break;
-
- if (use_threads) LOCK(cl->updateMutex);
-
- req0 = sraRgnCountRects(cl->requestedRegion);
- mod0 = sraRgnCountRects(cl->modifiedRegion);
-
- if (use_threads) UNLOCK(cl->updateMutex);
-
- if (use_threads) {
- usleep(1000);
- } else {
- if (mod0) {
- rfbPE(1000);
- } else {
- rfbCFD(1000);
- }
- }
- dt = dtime(&tm);
- dt2 += dt;
- if (dt2 > spin_max) {
- break;
- }
-
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-C2\n");
- if (OUCH) break;
-
- if (use_threads) LOCK(cl->updateMutex);
-
- req1 = sraRgnCountRects(cl->requestedRegion);
- mod1 = sraRgnCountRects(cl->modifiedRegion);
-
- if (use_threads) UNLOCK(cl->updateMutex);
-
-if (db) fprintf(stderr, "dt2 calc: num rects req: %d/%d mod: %d/%d "
- "fbu-sent: %d dt: %.4f dt2: %.4f tm: %.4f\n",
- req0, req1, mod0, mod1,
-#if 0
- cl->framebufferUpdateMessagesSent,
-#else
-#if LIBVNCSERVER_HAS_STATS
- rfbStatGetMessageCountSent(cl, rfbFramebufferUpdate),
-#endif
-#endif
- dt, dt2, tm);
- if (req1 != 0 && mod1 == 0) {
- got_t2 = 1;
- break;
- }
- }
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-D\n");
- if (OUCH) goto ouch;
-
- if (! got_t2) {
- dt2 = 0.0;
- } else {
- int tr, trm = 3;
- double dts[10];
-
- /*
- * Note: since often select(2) cannot sleep
- * less than 1/HZ (e.g. 10ms), the resolution
- * of the latency may be messed up by something
- * of this order. Effect may occur on both ends,
- * i.e. the viewer may not respond immediately.
- */
-
- for (tr = 0; tr < trm; tr++) {
- usleep(5000);
-
- /* mark a 2nd small rectangle: */
- mark_rect_as_modified(0, 0, 16, 16, 1);
- i = 0;
- dtime0(&tm);
- dt3 = 0.0;
-
- /*
- * when req1 > 0 and mod1 == 0, we say
- * that is the "ping" time.
- */
- while (1) {
- int req0, req1, mod0, mod1;
-
- if (use_threads) LOCK(cl->updateMutex);
-
- req0 = sraRgnCountRects(cl->requestedRegion);
- mod0 = sraRgnCountRects(cl->modifiedRegion);
-
- if (use_threads) UNLOCK(cl->updateMutex);
-
- if (i == 0) {
- rfbPE(0);
- } else {
- if (use_threads) {
- usleep(1000);
- } else {
- /* try to get it all */
- rfbCFD(1000*1000);
- }
- }
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-E\n");
- if (OUCH) goto ouch;
- dt = dtime(&tm);
- i++;
-
- dt3 += dt;
- if (dt3 > spin_lat_max) {
- break;
- }
-
- if (use_threads) LOCK(cl->updateMutex);
-
- req1 = sraRgnCountRects(cl->requestedRegion);
- mod1 = sraRgnCountRects(cl->modifiedRegion);
-
- if (use_threads) UNLOCK(cl->updateMutex);
-
-if (db) fprintf(stderr, "dt3 calc: num rects req: %d/%d mod: %d/%d "
- "fbu-sent: %d dt: %.4f dt3: %.4f tm: %.4f\n",
- req0, req1, mod0, mod1,
-#if 0
- cl->framebufferUpdateMessagesSent,
-#else
-#if LIBVNCSERVER_HAS_STATS
- rfbStatGetMessageCountSent(cl, rfbFramebufferUpdate),
-#endif
-#endif
- dt, dt3, tm);
-
- if (req1 != 0 && mod1 == 0) {
- dts[got_t3++] = dt3;
- break;
- }
- }
- }
-
- if (! got_t3) {
- dt3 = 0.0;
- } else {
- if (got_t3 == 1) {
- dt3 = dts[0];
- } else if (got_t3 == 2) {
- dt3 = dts[1];
- } else {
- if (dts[2] > 0.0) {
- double rat = dts[1]/dts[2];
- if (rat > 0.5 && rat < 2.0) {
- dt3 = dts[1]+dts[2];
- dt3 *= 0.5;
- } else {
- dt3 = dts[1];
- }
- } else {
- dt3 = dts[1];
- }
- }
- }
- }
-
- ouch:
-
- screen->deferUpdateTime = defer;
- screen->httpDir = httpdir;
-
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-F\n");
- if (OUCH) break;
-
- dt = dt1 + dt2;
-
-
- if (dt3 <= dt2/2.0) {
- /* guess only 1/2 a ping for reply... */
- dt = dt - dt3/2.0;
- }
-
- cmp_rate = cbs/dt;
- raw_rate = rbs/dt;
-
- if (cmp_rate > cmp_max) {
- cmp_rate = cmp_max;
- }
- if (cmp_rate <= cmp_min) {
- cmp_rate = cmp_min;
- }
-
- cd->send_cmp_rate = cmp_rate;
- cd->send_raw_rate = raw_rate;
-
- if (dt3 > lat_max) {
- dt3 = lat_max;
- }
- if (dt3 <= lat_min) {
- dt3 = lat_min;
- }
-
- cd->latency = dt3;
-
- rfbLog("client %d network rate %.1f KB/sec (%.1f eff KB/sec)\n",
- cd->uid, cmp_rate/1000.0, raw_rate/1000.0);
- rfbLog("client %d latency: %.1f ms\n", cd->uid, 1000.0*dt3);
- rfbLog("dt1: %.4f, dt2: %.4f dt3: %.4f bytes: %d\n",
- dt1, dt2, dt3, cbs);
- msg = 1;
- }
-
- if (msg) {
- int link, latency, netrate;
- char *str = "error";
-
- link = link_rate(&latency, &netrate);
- if (link == LR_UNSET) {
- str = "LR_UNSET";
- } else if (link == LR_UNKNOWN) {
- str = "LR_UNKNOWN";
- } else if (link == LR_DIALUP) {
- str = "LR_DIALUP";
- } else if (link == LR_BROADBAND) {
- str = "LR_BROADBAND";
- } else if (link == LR_LAN) {
- str = "LR_LAN";
- }
- rfbLog("link_rate: %s - %d ms, %d KB/s\n", str, latency,
- netrate);
- }
-
- if (init) {
- if (nclients) {
- screen->displayHook = measure_display_hook;
- }
- } else {
- screen->displayHook = orig_display_hook;
- }
-}
-
diff --git a/x11vnc/rates.h b/x11vnc/rates.h
deleted file mode 100644
index 3de8c4e..0000000
--- a/x11vnc/rates.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_RATES_H
-#define _X11VNC_RATES_H
-
-/* -- rates.h -- */
-
-extern int measure_speeds;
-extern int speeds_net_rate;
-extern int speeds_net_rate_measured;
-extern int speeds_net_latency;
-extern int speeds_net_latency_measured;
-extern int speeds_read_rate;
-extern int speeds_read_rate_measured;
-
-extern int get_cmp_rate(void);
-extern int get_raw_rate(void);
-extern void initialize_speeds(void);
-extern int get_read_rate(void);
-extern int link_rate(int *latency, int *netrate);
-extern int get_net_rate(void);
-extern int get_net_latency(void);
-extern void measure_send_rates(int init);
-
-#endif /* _X11VNC_RATES_H */
diff --git a/x11vnc/remote.c b/x11vnc/remote.c
deleted file mode 100644
index 3e9e5f8..0000000
--- a/x11vnc/remote.c
+++ /dev/null
@@ -1,6323 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- remote.c -- */
-
-#include "x11vnc.h"
-#include "inet.h"
-#include "xwrappers.h"
-#include "xevents.h"
-#include "xinerama.h"
-#include "xrandr.h"
-#include "xdamage.h"
-#include "xrecord.h"
-#include "xkb_bell.h"
-#include "win_utils.h"
-#include "screen.h"
-#include "cleanup.h"
-#include "gui.h"
-#include "solid.h"
-#include "user.h"
-#include "rates.h"
-#include "scan.h"
-#include "connections.h"
-#include "pointer.h"
-#include "cursor.h"
-#include "userinput.h"
-#include "keyboard.h"
-#include "selection.h"
-#include "unixpw.h"
-#include "uinput.h"
-#include "userinput.h"
-#include "avahi.h"
-#include "sslhelper.h"
-
-int send_remote_cmd(char *cmd, int query, int wait);
-int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync,
- int qdefault);
-void check_black_fb(void);
-int check_httpdir(void);
-void http_connections(int on);
-int remote_control_access_ok(void);
-char *process_remote_cmd(char *cmd, int stringonly);
-
-
-static char *add_item(char *instr, char *item);
-static char *delete_item(char *instr, char *item);
-static void if_8bpp_do_new_fb(void);
-static void reset_httpport(int old, int newp);
-static void reset_rfbport(int old, int newp) ;
-
-char *query_result = NULL;
-
-/*
- * for the wild-n-crazy -remote/-R interface.
- */
-int send_remote_cmd(char *cmd, int query, int wait) {
- FILE *in = NULL;
-
- if (query_result != NULL) {
- free(query_result);
- query_result = NULL;
- }
-
- if (client_connect_file) {
- umask(077);
- in = fopen(client_connect_file, "w");
- if (in == NULL) {
- fprintf(stderr, "send_remote_cmd: could not open "
- "connect file \"%s\" for writing\n",
- client_connect_file);
- perror("fopen");
- return 1;
- }
- } else if (x11vnc_remote_prop == None) {
- initialize_x11vnc_remote_prop();
- if (x11vnc_remote_prop == None) {
- fprintf(stderr, "send_remote_cmd: could not obtain "
- "X11VNC_REMOTE X property\n");
- return 1;
- }
- }
-
- if (in != NULL) {
- fprintf(stderr, ">>> sending remote command: \"%s\"\n via"
- " connect file: %s\n", cmd, client_connect_file);
- fprintf(in, "%s\n", cmd);
- fclose(in);
- } else {
- fprintf(stderr, ">>> sending remote command: \"%s\" via"
- " X11VNC_REMOTE X property.\n", cmd);
- set_x11vnc_remote_prop(cmd);
- if (dpy) {
- XFlush_wr(dpy);
- }
- }
-
- if (query || wait) {
- char line[X11VNC_REMOTE_MAX];
- int rc=1, i=0, max=140, ms_sl=25;
-
- if (!strcmp(cmd, "cmd=stop")) {
- max = 40;
- }
- if (strstr(cmd, "script:")) {
- max = 400;
- }
- if (strstr(cmd, "bcx_xattach:")) {
- max = 400;
- }
- if (getenv("X11VNC_SYNC_TIMEOUT")) {
- max = (int) ((1000. * atof(getenv("X11VNC_SYNC_TIMEOUT")))/ms_sl);
- }
- for (i=0; i<max; i++) {
- if (i==0) {
- usleep(10 * 1000);
- } else {
- usleep(ms_sl * 1000);
- }
- if (client_connect_file) {
- char *q;
- in = fopen(client_connect_file, "r");
- if (in == NULL) {
- fprintf(stderr, "send_remote_cmd: could"
- " not open connect file \"%s\" for"
- " writing\n", client_connect_file);
- perror("fopen");
- return 1;
- }
- fgets(line, X11VNC_REMOTE_MAX, in);
- fclose(in);
- q = line;
- while (*q != '\0') {
- if (*q == '\n') *q = '\0';
- q++;
- }
- } else {
- read_x11vnc_remote_prop(1);
- strncpy(line, x11vnc_remote_str,
- X11VNC_REMOTE_MAX);
- }
- if (strcmp(cmd, line)) {
- if (query || wait) {
- query_result = strdup(line);
- fprintf(stdout, "%s\n", line);
- fflush(stdout);
- }
- rc = 0;
- break;
- }
- }
- if (rc) {
- fprintf(stderr, "error: could not connect to "
- "an x11vnc server at %s (rc=%d)\n",
- client_connect_file ? client_connect_file
- : DisplayString(dpy), rc);
- }
- return rc;
- }
- return 0;
-}
-
-int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync,
- int qdefault) {
- char *rcmd = NULL, *qcmd = NULL;
- int rc = 1, direct = 0;
-
- if (qdefault && !query_cmd) {
- query_cmd = remote_cmd;
- remote_cmd = NULL;
- }
- if (remote_cmd && strstr(remote_cmd, "DIRECT:") == remote_cmd) {
- direct = 1;
- remote_cmd += strlen("DIRECT:");
- }
- if (query_cmd && strstr(query_cmd, "DIRECT:") == query_cmd) {
- direct = 1;
- query_cmd += strlen("DIRECT:");
- }
-
- if (remote_cmd) {
- rcmd = (char *) malloc(strlen(remote_cmd) + 5);
- strcpy(rcmd, "cmd=");
- strcat(rcmd, remote_cmd);
- }
- if (query_cmd) {
- qcmd = (char *) malloc(strlen(query_cmd) + 5);
- strcpy(qcmd, "qry=");
- strcat(qcmd, query_cmd);
- }
- if (direct) {
- char *res;
- if (rcmd) {
- res = process_remote_cmd(rcmd, 1);
- fprintf(stdout, "%s\n", res);
- }
- if (qcmd) {
- res = process_remote_cmd(qcmd, 1);
- fprintf(stdout, "%s\n", res);
- }
- fflush(stdout);
- return 0;
- }
- if (qdefault) {
- char *res;
- if (!qcmd) {
- return 1;
- }
- res = process_remote_cmd(qcmd, 1);
- fprintf(stdout, "%s\n", res);
- fflush(stdout);
- return 0;
- }
-
- if (rcmd && qcmd) {
- rc = send_remote_cmd(rcmd, 0, 1);
- if (rc) {
- free(rcmd);
- free(qcmd);
- return(rc);
- }
- rc = send_remote_cmd(qcmd, 1, 1);
- } else if (rcmd) {
- rc = send_remote_cmd(rcmd, 0, remote_sync);
- free(rcmd);
- } else if (qcmd) {
- rc = send_remote_cmd(qcmd, 1, 1);
- free(qcmd);
- }
- return rc;
-}
-
-static char *add_item(char *instr, char *item) {
- char *p, *str;
- int len, saw_item = 0;
-
- if (! instr || *instr == '\0') {
- str = strdup(item);
- return str;
- }
- len = strlen(instr) + 1 + strlen(item) + 1;
- str = (char *) malloc(len);
- str[0] = '\0';
-
- /* n.b. instr will be modified; caller replaces with returned string */
- p = strtok(instr, ",");
- while (p) {
- if (!strcmp(p, item)) {
- if (saw_item) {
- p = strtok(NULL, ",");
- continue;
- }
- saw_item = 1;
- } else if (*p == '\0') {
- p = strtok(NULL, ",");
- continue;
- }
- if (str[0]) {
- strcat(str, ",");
- }
- strcat(str, p);
- p = strtok(NULL, ",");
- }
- if (! saw_item) {
- if (str[0]) {
- strcat(str, ",");
- }
- strcat(str, item);
- }
- return str;
-}
-
-static char *delete_item(char *instr, char *item) {
- char *p, *str;
- int len;
-
- if (! instr || *instr == '\0') {
- str = strdup("");
- return str;
- }
- len = strlen(instr) + 1;
- str = (char *) malloc(len);
- str[0] = '\0';
-
- /* n.b. instr will be modified; caller replaces with returned string */
- p = strtok(instr, ",");
- while (p) {
- if (!strcmp(p, item) || *p == '\0') {
- p = strtok(NULL, ",");
- continue;
- }
- if (str[0]) {
- strcat(str, ",");
- }
- strcat(str, p);
- p = strtok(NULL, ",");
- }
- return str;
-}
-
-static void if_8bpp_do_new_fb(void) {
- if (bpp == 8) {
- do_new_fb(0);
- } else {
- rfbLog(" bpp(%d) is not 8bpp, not resetting fb\n", bpp);
- }
-}
-
-void check_black_fb(void) {
- if (!screen) {
- return;
- }
- if (new_fb_size_clients(screen) != client_count) {
- rfbLog("trying to send a black fb for non-newfbsize"
- " clients %d != %d\n", client_count,
- new_fb_size_clients(screen));
- push_black_screen(4);
- }
-}
-
-int check_httpdir(void) {
- if (http_dir && http_dir[0] != '\0') {
- return 1;
- } else {
- char *prog = NULL, *httpdir, *q;
- struct stat sbuf;
- int len;
-
- rfbLog("check_httpdir: trying to guess httpdir... %s\n", program_name);
- if (program_name[0] == '/') {
- prog = strdup(program_name);
- } else {
- char cwd[1024];
- getcwd(cwd, 1024);
- len = strlen(cwd) + 1 + strlen(program_name) + 1;
- prog = (char *) malloc(len);
- snprintf(prog, len, "%s/%s", cwd, program_name);
- if (stat(prog, &sbuf) != 0) {
- char *path = strdup(getenv("PATH"));
- char *p, *base;
- base = strrchr(program_name, '/');
- if (base) {
- base++;
- } else {
- base = program_name;
- }
-
- p = strtok(path, ":");
- while(p) {
- if (prog) {
- free(prog);
- prog = NULL;
- }
- len = strlen(p) + 1 + strlen(base) + 1;
- prog = (char *) malloc(len);
- snprintf(prog, len, "%s/%s", p, base);
- if (stat(prog, &sbuf) == 0) {
- break;
- }
- p = strtok(NULL, ":");
- }
- free(path);
- }
- }
- /*
- * /path/to/bin/x11vnc
- * /path/to/bin/../share/x11vnc/classes
- * 12345678901234567
- * /path/to/bin/../share/x11vnc/classes/ssl
- * 123456789012345678901
- * 21
- */
- if ((q = strrchr(prog, '/')) == NULL) {
- rfbLog("check_httpdir: bad program path: %s\n", prog);
- free(prog);
- rfbLog("check_httpdir: *HTTP disabled* Use -httpdir path\n");
- return 0;
- }
-
- len = strlen(prog) + 21 + 1;
- *q = '\0';
- httpdir = (char *) malloc(len);
- if (use_stunnel && http_ssl) {
- snprintf(httpdir, len, "%s/../share/x11vnc/classes/ssl", prog);
- } else if (!enc_str && (use_openssl || use_stunnel || http_ssl)) {
- snprintf(httpdir, len, "%s/../share/x11vnc/classes/ssl", prog);
- } else {
- snprintf(httpdir, len, "%s/../share/x11vnc/classes", prog);
- }
- if (stat(httpdir, &sbuf) != 0) {
- if (use_stunnel && http_ssl) {
- snprintf(httpdir, len, "%s/../classes/ssl", prog);
- } else if (!enc_str && (use_openssl || use_stunnel || http_ssl)) {
- snprintf(httpdir, len, "%s/../classes/ssl", prog);
- } else {
- snprintf(httpdir, len, "%s/../classes", prog);
- }
- }
- free(prog);
-
- if (stat(httpdir, &sbuf) == 0) {
- /* good enough for me */
- rfbLog("check_httpdir: guessed directory:\n");
- rfbLog(" %s\n", httpdir);
- http_dir = httpdir;
- return 1;
- } else {
- /* try some hardwires: */
- int i;
- char **use;
- char *list[] = {
- "/usr/local/share/x11vnc/classes",
- "/usr/share/x11vnc/classes",
- NULL
- };
- char *ssllist[] = {
- "/usr/local/share/x11vnc/classes/ssl",
- "/usr/share/x11vnc/classes/ssl",
- NULL
- };
- if (use_stunnel && http_ssl) {
- use = ssllist;
- } else if (!enc_str && (use_openssl || use_stunnel || http_ssl)) {
- use = ssllist;
- } else {
- use = list;
- }
- i = 0;
- while (use[i] != NULL) {
- if (stat(use[i], &sbuf) == 0) {
- http_dir = strdup(use[i]);
- return 1;
- }
- i++;
- }
-
- rfbLog("check_httpdir: bad guess:\n");
- rfbLog(" %s\n", httpdir);
- rfbLog("check_httpdir: *HTTP disabled* Use -httpdir path\n");
- return 0;
- }
- }
-}
-
-static void rfb_http_init_sockets(void) {
- in_addr_t iface;
- if (!screen) {
- return;
- }
- iface = screen->listenInterface;
- if (getenv("X11VNC_HTTP_LISTEN_LOCALHOST")) {
- rfbLog("http_connections: HTTP listen on localhost only. (not HTTPS)\n");
- screen->listenInterface = htonl(INADDR_LOOPBACK);
- }
- rfbHttpInitSockets(screen);
- if (noipv4 || getenv("IPV4_FAILS")) {
- if (getenv("IPV4_FAILS")) {
- rfbLog("TESTING: IPV4_FAILS for rfb_http_init_sockets()\n");
- }
- if (screen->httpListenSock > -1) {
- close(screen->httpListenSock);
- screen->httpListenSock = -1;
- }
- }
- screen->listenInterface = iface;
-}
-
-void http_connections(int on) {
- if (!screen) {
- return;
- }
- if (on) {
- rfbLog("http_connections: turning on http service.\n");
-
- if (inetd && use_openssl) {
- /*
- * try to work around rapid fire https requests
- * in inetd mode... ugh.
- */
- if (screen->httpPort == 0) {
- int port = find_free_port(5800, 5850);
- if (port) {
- /* mutex */
- screen->httpPort = port;
- }
- }
- }
- screen->httpInitDone = FALSE;
- if (check_httpdir()) {
- int fd6 = -1;
- char *save = listen_str6;
-
- screen->httpDir = http_dir;
-
- rfb_http_init_sockets();
-
- if (getenv("X11VNC_HTTP_LISTEN_LOCALHOST")) {
- listen_str6 = "localhost";
- }
-
- if (screen->httpPort != 0 && screen->httpListenSock < 0) {
- rfbLog("http_connections: failed to listen on http port: %d\n", screen->httpPort);
- if (ipv6_listen) {
- fd6 = listen6(screen->httpPort);
- }
- if (fd6 < 0) {
- clean_up_exit(1);
- }
- rfbLog("http_connections: trying IPv6 only mode.\n");
- }
- if (ipv6_listen && screen->httpPort > 0) {
- if (fd6 < 0) {
- fd6 = listen6(screen->httpPort);
- }
- ipv6_http_fd = fd6;
- if (ipv6_http_fd >= 0) {
- rfbLog("http_connections: Listening %s on IPv6 port %d (socket %d)\n",
- screen->httpListenSock < 0 ? "only" : "also",
- screen->httpPort, ipv6_http_fd);
- }
- }
- listen_str6 = save;
- }
- } else {
- rfbLog("http_connections: turning off http service.\n");
- if (screen->httpListenSock > -1) {
- close(screen->httpListenSock);
- screen->httpListenSock = -1;
- }
- screen->httpDir = NULL;
- if (ipv6_http_fd >= 0) {
- close(ipv6_http_fd);
- ipv6_http_fd = -1;
- }
- }
-}
-
-static void reset_httpport(int old, int newp) {
- int hp = newp;
-
- if (! screen->httpDir) {
- return;
- } else if (inetd) {
- rfbLog("reset_httpport: cannot set httpport: %d in inetd.\n", hp);
- return;
- } else if (!screen) {
- rfbLog("reset_httpport: no screen.\n");
- return;
- } else if (hp < 0) {
- rfbLog("reset_httpport: invalid httpport: %d\n", hp);
- return;
- } else if (hp == old) {
- rfbLog("reset_httpport: unchanged httpport: %d\n", hp);
- return;
- }
-
- if (screen->httpListenSock > -1) {
- close(screen->httpListenSock);
- screen->httpListenSock = -1;
- }
-
- screen->httpPort = hp;
- screen->httpInitDone = FALSE;
-
- rfbLog("reset_httpport: setting httpport %d -> %d.\n",
- old == -1 ? hp : old, hp);
-
- if (noipv4 || getenv("IPV4_FAILS")) {
- if (getenv("IPV4_FAILS")) {
- rfbLog("TESTING: IPV4_FAILS for reset_httpport()\n");
- }
- } else if (screen->httpPort == 0) {
- ;
- } else {
- rfb_http_init_sockets();
- }
-
- if (screen->httpPort != 0 && screen->httpListenSock < 0) {
- rfbLog("reset_httpport: failed to listen on http port: %d\n",
- screen->httpPort);
- }
-
- if (ipv6_http_fd >= 0) {
- close(ipv6_http_fd);
- ipv6_http_fd = -1;
- }
- if (ipv6_listen && screen->httpPort > 0) {
- ipv6_http_fd = listen6(screen->httpPort);
- rfbLog("reset_httpport: ipv6_http_fd: %d port: %d\n",
- ipv6_http_fd, screen->httpPort);
- }
-}
-
-static void reset_rfbport(int old, int newp) {
- int rp = newp;
-
- if (inetd) {
- rfbLog("reset_rfbport: cannot set rfbport: %d in inetd.\n", rp);
- return;
- } else if (!screen) {
- rfbLog("reset_rfbport: no screen.\n");
- return;
- } else if (rp < 0) {
- rfbLog("reset_rfbport: invalid rfbport: %d\n", rp);
- return;
- } else if (rp == old) {
- rfbLog("reset_rfbport: unchanged rfbport: %d\n", rp);
- return;
- }
-
- rfbLog("reset_rfbport: setting rfbport %d -> %d.\n", old == -1 ? rp : old, rp);
-
- screen->port = rp;
-
- if (use_openssl) {
- openssl_port(1);
- if (openssl_sock < 0 && openssl_sock6 < 0) {
- rfbLog("reset_rfbport: warning could not listen on port: %d\n",
- screen->port);
- } else {
- set_vnc_desktop_name();
- }
- if (https_port_num >= 0) {
- https_port(1);
- }
- return;
- }
-
- if (screen->listenSock >= 0) {
- FD_CLR(screen->listenSock, &(screen->allFds));
- close(screen->listenSock);
- screen->listenSock = -1;
- }
-
- if (noipv4 || getenv("IPV4_FAILS")) {
- if (getenv("IPV4_FAILS")) {
- rfbLog("TESTING: IPV4_FAILS for reset_rfbport()\n");
- }
- } else {
- screen->listenSock = listen_tcp(screen->port, screen->listenInterface, 0);
- if (screen->listenSock >= 0) {
- if (screen->listenSock > screen->maxFd) {
- screen->maxFd = screen->listenSock;
- }
- FD_SET(screen->listenSock, &(screen->allFds));
- }
- }
-
- if (ipv6_listen_fd >= 0) {
- close(ipv6_listen_fd);
- ipv6_listen_fd = -1;
- }
- if (ipv6_listen && screen->port > 0) {
- ipv6_listen_fd = listen6(screen->port);
- rfbLog("reset_rfbport: ipv6_listen_fd: %d port: %d\n",
- ipv6_listen_fd, screen->port);
- }
-
- if (screen->listenSock < 0 && ipv6_listen_fd < 0) {
- rfbLog("reset_rfbport: warning could not listen on port: %d\n", screen->port);
- } else {
- set_vnc_desktop_name();
- }
-}
-
-/*
- * Do some sanity checking of the permissions on the XAUTHORITY and the
- * -connect file. This is -privremote. What should be done is check
- * for an empty host access list, currently we lazily do not bring in
- * libXau yet.
- */
-int remote_control_access_ok(void) {
-#if NO_X11
- return 0;
-#else
- struct stat sbuf;
-
- if (client_connect_file) {
- if (stat(client_connect_file, &sbuf) == 0) {
- if (sbuf.st_mode & S_IWOTH) {
- rfbLog("connect file is writable by others.\n");
- rfbLog(" %s\n", client_connect_file);
- return 0;
- }
- if (sbuf.st_mode & S_IWGRP) {
- rfbLog("connect file is writable by group.\n");
- rfbLog(" %s\n", client_connect_file);
- return 0;
- }
- }
- }
-
- if (dpy) {
- char tmp[1000];
- char *home, *xauth;
- char *dpy_str = DisplayString(dpy);
- Display *dpy2;
- XHostAddress *xha;
- Bool enabled;
- int n;
-
- home = get_home_dir();
- if (getenv("XAUTHORITY") != NULL) {
- xauth = getenv("XAUTHORITY");
- } else if (home) {
- int len = 1000 - strlen("/.Xauthority") - 1;
- strncpy(tmp, home, len);
- strcat(tmp, "/.Xauthority");
- xauth = tmp;
- } else {
- rfbLog("cannot determine default XAUTHORITY.\n");
- return 0;
- }
- if (home) {
- free(home);
- }
- if (stat(xauth, &sbuf) == 0) {
- if (sbuf.st_mode & S_IWOTH) {
- rfbLog("XAUTHORITY is writable by others!!\n");
- rfbLog(" %s\n", xauth);
- return 0;
- }
- if (sbuf.st_mode & S_IWGRP) {
- rfbLog("XAUTHORITY is writable by group!!\n");
- rfbLog(" %s\n", xauth);
- return 0;
- }
- if (sbuf.st_mode & S_IROTH) {
- rfbLog("XAUTHORITY is readable by others.\n");
- rfbLog(" %s\n", xauth);
- return 0;
- }
- if (sbuf.st_mode & S_IRGRP) {
- rfbLog("XAUTHORITY is readable by group.\n");
- rfbLog(" %s\n", xauth);
- return 0;
- }
- }
-
- X_LOCK;
- xha = XListHosts(dpy, &n, &enabled);
- X_UNLOCK;
- if (! enabled) {
- rfbLog("X access control is disabled, X clients can\n");
- rfbLog(" connect from any host. Run 'xhost -'\n");
- return 0;
- }
- if (xha) {
- int i;
- rfbLog("The following hosts can connect w/o X11 "
- "auth:\n");
- for (i=0; i<n; i++) {
- if (xha[i].family == FamilyInternet) {
- char *str = raw2host(xha[i].address,
- xha[i].length);
- char *ip = raw2ip(xha[i].address);
- rfbLog(" %s/%s\n", str, ip);
- free(str);
- free(ip);
- } else {
- rfbLog(" unknown-%d\n", i+1);
- }
- }
- XFree_wr(xha);
- return 0;
- }
-
- if (getenv("XAUTHORITY")) {
- xauth = strdup(getenv("XAUTHORITY"));
- } else {
- xauth = NULL;
- }
- set_env("XAUTHORITY", "/impossible/xauthfile");
-
- fprintf(stderr, "\nChecking if display %s requires "
- "XAUTHORITY\n", dpy_str);
- fprintf(stderr, " -- (ignore any Xlib: errors that"
- " follow) --\n");
- dpy2 = XOpenDisplay_wr(dpy_str);
- fflush(stderr);
- fprintf(stderr, " -- (done checking) --\n\n");
-
- if (xauth) {
- set_env("XAUTHORITY", xauth);
- free(xauth);
- } else {
- xauth = getenv("XAUTHORITY");
- if (xauth) {
- *(xauth-2) = '_'; /* yow */
- }
- }
- if (dpy2) {
- rfbLog("XAUTHORITY is not required on display.\n");
- rfbLog(" %s\n", DisplayString(dpy));
- XCloseDisplay_wr(dpy2);
- dpy2 = NULL;
- return 0;
- }
-
- }
- return 1;
-#endif /* NO_X11 */
-}
-
-#ifdef MACOSX
-void macosxCG_keycode_inject(int down, int keycode);
-#endif
-
-int rc_npieces = 0;
-
-/*
- * Huge, ugly switch to handle all remote commands and queries
- * -remote/-R and -query/-Q.
- */
-char *process_remote_cmd(char *cmd, int stringonly) {
-#if REMOTE_CONTROL
- char *p = cmd;
- char *co = "";
- char buf[X11VNC_REMOTE_MAX];
- int bufn = X11VNC_REMOTE_MAX;
- int query = 0;
- static char *prev_cursors_mode = NULL;
-
- if (!query_default && !accept_remote_cmds) {
- rfbLog("remote commands disabled: %s\n", cmd);
- return NULL;
- }
- if (unixpw_in_progress) {
- rfbLog("skip remote command: %s unixpw_in_progress.\n", cmd);
- return NULL;
- }
-
- if (!query_default && priv_remote) {
- if (! remote_control_access_ok()) {
- rfbLog("** Disabling remote commands in -privremote "
- "mode.\n");
- accept_remote_cmds = 0;
- return NULL;
- }
- }
-
-
- strcpy(buf, "");
- if (strstr(cmd, "cmd=") == cmd) {
- p += strlen("cmd=");
- if (strstr(p, "script:") == p) {
- char *s, *q, **pieces, tmp[1024];
- int k = 0, n = 0, dp = 1;
-
- p += strlen("script:");
-
- if (strstr(p, "file=") == p) {
- FILE *f;
- struct stat sbuf;
-
- p += strlen("file=");
-
- rfbLog("reading script from file '%s'\n", p);
-
- if (stat(p, &sbuf) != 0) {
- rfbLogPerror("stat");
- return NULL;
- }
-
- f = fopen(p, "r");
- if (f == NULL) {
- rfbLogPerror("fopen");
- return NULL;
- }
-
- p = (char *) calloc(sbuf.st_size + 1, 1);
- dp = 0;
- while (fgets(tmp, 1024, f) != NULL) {
- char *c = strchr(tmp, '#');
- if (c) *c = '\0';
- if (strlen(p) + strlen(tmp) > (size_t) sbuf.st_size) {
- break;
- }
- strcat(p, tmp);
- }
- fclose(f);
- }
-
- pieces = (char **) malloc(strlen(p) * sizeof(char *));
- if (dp) {
- s = strdup(p);
- } else {
- s = p;
- }
- q = strtok(s, ";");
-
- while (q) {
- char *t = lblanks(q);
- if (strstr(t, "cmd=") != t && strstr(t, "qry=") != t) {
- strcpy(tmp, "cmd=");
- } else {
- strcpy(tmp, "");
- }
- strncat(tmp, t, 1000);
- pieces[n] = strdup(tmp);
- n++;
- q = strtok(NULL, ";");
- }
- free(s);
-
- for (k=0; k < n; k++) {
- char *c = pieces[k];
- char *t = c + strlen(c) - 1; /* shortest is "cmd=" */
- while (isspace((unsigned char) (*t))) {
- *t = '\0';
- if (t <= c) break;
- t--;
- }
- if (k < n - 1) {
- process_remote_cmd(c, 1);
- } else {
- process_remote_cmd(c, 0);
- }
- }
- for (k=0; k<n; k++) {
- free(pieces[k]);
- }
- free(pieces);
- return NULL;
- }
- } else if (strstr(cmd, "qry=") == cmd) {
- query = 1;
- if (strchr(cmd, ',')) {
- /* comma separated batch mode */
- char *s, *q, *res, **pieces, tmp[1024];
- int k = 0, n = 0;
-
- pieces = (char **) malloc(strlen(cmd) * sizeof(char *));
- s = strdup(cmd + strlen("qry="));
- q = strtok(s, ",");
-
- while (q) {
- strcpy(tmp, "qry=");
- strncat(tmp, q, 1000);
- pieces[n] = strdup(tmp);
- n++;
- q = strtok(NULL, ",");
- }
- free(s);
-
- rc_npieces = n;
- strcpy(buf, "");
- for (k=0; k < n; k++) {
- res = process_remote_cmd(pieces[k], 1);
- if (res && strlen(buf)+strlen(res)
- >= X11VNC_REMOTE_MAX - 1) {
- rfbLog("overflow in process_remote_cmd:"
- " %s -- %s\n", buf, res);
- free(res);
- break;
- }
- if (res) {
- strcat(buf, res);
- free(res);
- }
- if (k < n - 1) {
- strcat(buf, ",");
- }
- }
- for (k=0; k<n; k++) {
- free(pieces[k]);
- }
- free(pieces);
- rc_npieces = 0;
- goto qry;
- }
- p += strlen("qry=");
- } else {
- rfbLog("ignoring malformed command: %s\n", cmd);
- goto done;
- }
-
- /* allow var=val usage */
- if (!strchr(p, ':')) {
- char *q = strchr(p, '=');
- if (q) *q = ':';
- }
-
- /* always call like: COLON_CHECK("foobar:") */
-#define COLON_CHECK(str) \
- if (strstr(p, str) != p) { \
- co = ":"; \
- if (! query) { \
- goto done; \
- } \
- } else { \
- char *q = strchr(p, ':'); \
- if (query && q != NULL) { \
- *(q+1) = '\0'; \
- } \
- }
-
-#define NOTAPP \
- if (query) { \
- if (strchr(p, ':')) { \
- snprintf(buf, bufn, "ans=%sN/A", p); \
- } else { \
- snprintf(buf, bufn, "ans=%s:N/A", p); \
- } \
- goto qry; \
- }
-
-#define NOTAPPRO \
- if (query) { \
- if (strchr(p, ':')) { \
- snprintf(buf, bufn, "aro=%sN/A", p); \
- } else { \
- snprintf(buf, bufn, "aro=%s:N/A", p); \
- } \
- goto qry; \
- }
-
-/*
- * Maybe add: passwdfile logfile bg rfbauth passwd...
- */
- if (!strcmp(p, "")) { /* skip-cmd-list */
- NOTAPP
- rfbLog("remote_cmd: empty command.\n");
- goto done;
- }
- if (strstr(p, "CR:") == p) { /* skip-cmd-list */
- /* CR:WxH+X+Y,dx,dy */
- int w, h, x, y, dx, dy;
- NOTAPP
- if (sscanf(p+3, "%dx%d+%d+%d,%d,%d", &w, &h, &x, &y, &dx, &dy) == 6) {
- sraRegionPtr r;
- rfbLog("rfbDoCopyRect(screen, %d, %d, %d, %d, %d, %d)\n", x, y, x+w, y+h, dx, dy);
- r = sraRgnCreateRect(x, y, x+w, y+h);
- do_copyregion(r, dx, dy, 0);
- fb_push();
- sraRgnDestroy(r);
- rfbLog("did\n");
- } else {
- rfbLog("remote_cmd: bad CR string: %s\n", p);
- }
- goto done;
- }
- if (!strcmp(p, "stop") || !strcmp(p, "quit") ||
- !strcmp(p, "exit") || !strcmp(p, "shutdown")) {
- NOTAPP
- if (client_connect_file) {
- FILE *in = fopen(client_connect_file, "w");
- if (in) {
- fprintf(in, "cmd=noop\n");
- fclose(in);
- }
- }
- rfbLog("remote_cmd: setting shut_down flag\n");
- shut_down = 1;
- close_all_clients();
- goto done;
- }
- if (!strcmp(p, "ping")
- || strstr(p, "ping:") == p) { /* skip-cmd-list */
- query = 1;
- if (rfb_desktop_name) {
- snprintf(buf, bufn, "ans=%s:%s", p, rfb_desktop_name);
- } else {
- snprintf(buf, bufn, "ans=%s:%s", p, "unknown");
- }
- goto qry;
- goto done;
- }
- if (!strcmp(p, "resend_cutbuffer")) {
- NOTAPP
- resend_selection("cutbuffer");
- goto done;
- }
- if (!strcmp(p, "resend_clipboard")) {
- NOTAPP
- resend_selection("clipboard");
- goto done;
- }
- if (!strcmp(p, "resend_primary")) {
- NOTAPP
- resend_selection("primary");
- goto done;
- }
- if (!strcmp(p, "blacken") || !strcmp(p, "zero")) {
- NOTAPP
- push_black_screen(4);
- goto done;
- }
- if (!strcmp(p, "refresh")) {
- NOTAPP
- refresh_screen(1);
- goto done;
- }
- if (!strcmp(p, "reset")) {
- NOTAPP
- do_new_fb(1);
- goto done;
- }
- if (strstr(p, "zero:") == p) { /* skip-cmd-list */
- int x1, y1, x2, y2;
- NOTAPP
- p += strlen("zero:");
- if (sscanf(p, "%d,%d,%d,%d", &x1, &y1, &x2, &y2) == 4) {
- int mark = 1;
- rfbLog("zeroing rect: %s\n", p);
- if (x1 < 0 || x2 < 0) {
- x1 = nabs(x1);
- x2 = nabs(x2);
- mark = 0; /* hack for testing */
- }
-
- zero_fb(x1, y1, x2, y2);
- if (mark) {
- mark_rect_as_modified(x1, y1, x2, y2, 0);
- }
- push_sleep(4);
- }
- goto done;
- }
- if (strstr(p, "damagefb:") == p) { /* skip-cmd-list */
- int delay;
- NOTAPP
- p += strlen("damagefb:");
- if (sscanf(p, "%d", &delay) == 1) {
- rfbLog("damaging client fb's for %d secs "
- "(by not marking rects.)\n", delay);
- damage_time = time(NULL);
- damage_delay = delay;
- }
- goto done;
- }
- if (strstr(p, "close") == p) {
- NOTAPP
- COLON_CHECK("close:")
- p += strlen("close:");
- close_clients(p);
- goto done;
- }
- if (strstr(p, "disconnect") == p) {
- NOTAPP
- COLON_CHECK("disconnect:")
- p += strlen("disconnect:");
- close_clients(p);
- goto done;
- }
- if (strstr(p, "id_cmd") == p) {
- NOTAPP
- COLON_CHECK("id_cmd:")
- p += strlen("id_cmd:");
- id_cmd(p);
- goto done;
- }
- if (strstr(p, "id") == p) {
- int ok = 0;
- Window twin;
- COLON_CHECK("id:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s0x%lx", p, co,
- rootshift ? 0 : subwin);
- goto qry;
- }
- p += strlen("id:");
- if (*p == '\0' || !strcmp("root", p)) { /* skip-cmd-list */
- /* back to root win */
- twin = 0x0;
- ok = 1;
- } else if (!strcmp("pick", p)) {
- twin = 0x0;
- if (safe_remote_only) {
- rfbLog("unsafe: '-id pick'\n");
- } else if (pick_windowid(&twin)) {
- ok = 1;
- }
- } else if (! scan_hexdec(p, &twin)) {
- rfbLog("-id: skipping incorrect hex/dec number:"
- " %s\n", p);
- } else {
- ok = 1;
- }
- if (ok) {
- X_LOCK;
- if (twin && ! valid_window(twin, NULL, 0)) {
- rfbLog("skipping invalid sub-window: 0x%lx\n", twin);
- X_UNLOCK;
- } else {
- subwin = twin;
- rootshift = 0;
- X_UNLOCK;
- check_black_fb();
- do_new_fb(1);
- }
- }
- goto done;
- }
- if (strstr(p, "sid") == p) {
- int ok = 0;
- Window twin;
- COLON_CHECK("sid:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s0x%lx", p, co,
- !rootshift ? 0 : subwin);
- goto qry;
- }
- p += strlen("sid:");
- if (*p == '\0' || !strcmp("root", p)) { /* skip-cmd-list */
- /* back to root win */
- twin = 0x0;
- ok = 1;
- } else if (!strcmp("pick", p)) {
- twin = 0x0;
- if (safe_remote_only) {
- rfbLog("unsafe: '-sid pick'\n");
- } else if (pick_windowid(&twin)) {
- ok = 1;
- }
- } else if (! scan_hexdec(p, &twin)) {
- rfbLog("-sid: skipping incorrect hex/dec number: %s\n", p);
- } else {
- ok = 1;
- }
- if (ok) {
- X_LOCK;
- if (twin && ! valid_window(twin, NULL, 0)) {
- rfbLog("skipping invalid sub-window: 0x%lx\n", twin);
- X_UNLOCK;
- } else {
- subwin = twin;
- rootshift = 1;
- X_UNLOCK;
- check_black_fb();
- do_new_fb(1);
- }
- }
- goto done;
- }
- if (strstr(p, "waitmapped") == p) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- subwin_wait_mapped);
- goto qry;
- }
- subwin_wait_mapped = 1;
- goto done;
- }
- if (strstr(p, "nowaitmapped") == p) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- !subwin_wait_mapped);
- goto qry;
- }
- subwin_wait_mapped = 0;
- goto done;
- }
- if (!strcmp(p, "clip") ||
- strstr(p, "clip:") == p) { /* skip-cmd-list */
- COLON_CHECK("clip:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(clip_str));
- goto qry;
- }
- p += strlen("clip:");
- if (clip_str) {
- int w, h, x, y;
- free(clip_str);
- /* try to handle easy case where WxH is unchanged: */
- if (parse_geom(p, &w, &h, &x, &y, wdpy_x, wdpy_y)) {
- if (cdpy_x == w && cdpy_y == h) {
- if (x >= 0 && y >= 0) {
- if (x + w <= wdpy_x && y + h <= wdpy_y) {
- coff_x = x;
- coff_y = y;
- clip_str = strdup(p);
- goto done;
- }
- }
- }
- }
- }
- clip_str = strdup(p);
-
- /* OK, this requires a new fb... */
- do_new_fb(1);
- goto done;
- }
- if (!strcmp(p, "flashcmap")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, flash_cmap);
- goto qry;
- }
- rfbLog("remote_cmd: turning on flashcmap mode.\n");
- flash_cmap = 1;
- goto done;
- }
- if (!strcmp(p, "noflashcmap")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !flash_cmap);
- goto qry;
- }
- rfbLog("remote_cmd: turning off flashcmap mode.\n");
- flash_cmap = 0;
- goto done;
- }
- if (strstr(p, "shiftcmap") == p) {
- COLON_CHECK("shiftcmap:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, shift_cmap);
- goto qry;
- }
- p += strlen("shiftcmap:");
- shift_cmap = atoi(p);
- rfbLog("remote_cmd: set -shiftcmap %d\n", shift_cmap);
- do_new_fb(1);
- goto done;
- }
- if (!strcmp(p, "truecolor")) {
- int orig = force_indexed_color;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- !force_indexed_color);
- goto qry;
- }
- rfbLog("remote_cmd: turning off notruecolor mode.\n");
- force_indexed_color = 0;
- if (orig != force_indexed_color) {
- if_8bpp_do_new_fb();
- }
- goto done;
- }
- if (!strcmp(p, "notruecolor")) {
- int orig = force_indexed_color;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- force_indexed_color);
- goto qry;
- }
- rfbLog("remote_cmd: turning on notruecolor mode.\n");
- force_indexed_color = 1;
- if (orig != force_indexed_color) {
- if_8bpp_do_new_fb();
- }
- goto done;
- }
- if (!strcmp(p, "overlay")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, overlay);
- goto qry;
- }
- rfbLog("remote_cmd: turning on -overlay mode.\n");
- if (!overlay_present) {
- rfbLog("skipping: overlay extension not present.\n");
- } else if (overlay) {
- rfbLog("skipping: already in -overlay mode.\n");
- } else {
- int reset_mem = 0;
- /* here we go... */
- if (using_shm) {
- rfbLog("setting -noshm mode.\n");
- using_shm = 0;
- reset_mem = 1;
- }
- overlay = 1;
- do_new_fb(reset_mem);
- }
- goto done;
- }
- if (!strcmp(p, "nooverlay")) {
- int orig = overlay;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !overlay);
- goto qry;
- }
- rfbLog("remote_cmd: turning off overlay mode\n");
- overlay = 0;
- if (!overlay_present) {
- rfbLog("warning: overlay extension not present.\n");
- } else if (!orig) {
- rfbLog("skipping: already not in -overlay mode.\n");
- } else {
- /* here we go... */
- do_new_fb(0);
- }
- goto done;
- }
- if (!strcmp(p, "overlay_cursor") ||
- !strcmp(p, "overlay_yescursor") ||
- !strcmp(p, "nooverlay_nocursor")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, overlay_cursor);
- goto qry;
- }
- rfbLog("remote_cmd: turning on overlay_cursor mode.\n");
- overlay_cursor = 1;
- if (!overlay_present) {
- rfbLog("warning: overlay extension not present.\n");
- } else if (!overlay) {
- rfbLog("warning: not in -overlay mode.\n");
- } else {
- rfbLog("You may want to run -R noshow_cursor or\n");
- rfbLog(" -R cursor:none to disable any extra "
- "cursors.\n");
- }
- goto done;
- }
- if (!strcmp(p, "nooverlay_cursor") ||
- !strcmp(p, "nooverlay_yescursor") ||
- !strcmp(p, "overlay_nocursor")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !overlay_cursor);
- goto qry;
- }
- rfbLog("remote_cmd: turning off overlay_cursor mode\n");
- overlay_cursor = 0;
- if (!overlay_present) {
- rfbLog("warning: overlay extension not present.\n");
- } else if (!overlay) {
- rfbLog("warning: not in -overlay mode.\n");
- } else {
- rfbLog("You may want to run -R show_cursor or\n");
- rfbLog(" -R cursor:... to re-enable any cursors.\n");
- }
- goto done;
- }
- if (!strcmp(p, "8to24")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, cmap8to24);
- goto qry;
- }
- if (overlay) {
- rfbLog("disabling -overlay in -8to24 mode.\n");
- overlay = 0;
- }
- rfbLog("remote_cmd: turning on -8to24 mode.\n");
- cmap8to24 = 1;
- if (overlay) {
- rfbLog("disabling -overlay in -8to24 mode.\n");
- overlay = 0;
- }
- do_new_fb(0);
- goto done;
- }
- if (!strcmp(p, "no8to24")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !cmap8to24);
- goto qry;
- }
- rfbLog("remote_cmd: turning off -8to24 mode.\n");
- cmap8to24 = 0;
- do_new_fb(0);
- goto done;
- }
- if (strstr(p, "8to24_opts") == p) {
- COLON_CHECK("8to24_opts:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(cmap8to24_str));
- goto qry;
- }
- p += strlen("8to24_opts:");
- if (cmap8to24_str) {
- free(cmap8to24_str);
- }
- cmap8to24_str = strdup(p);
- if (*p == '\0') {
- cmap8to24 = 0;
- } else {
- cmap8to24 = 1;
- }
- rfbLog("remote_cmd: set cmap8to24_str to: %s\n", cmap8to24_str);
- do_new_fb(0);
- goto done;
- }
- if (!strcmp(p, "24to32")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, xform24to32);
- goto qry;
- }
- rfbLog("remote_cmd: turning on -24to32 mode.\n");
- xform24to32 = 1;
- do_new_fb(1);
- goto done;
- }
- if (!strcmp(p, "no24to32")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !xform24to32);
- goto qry;
- }
- rfbLog("remote_cmd: turning off -24to32 mode.\n");
- if (set_visual_str_to_something) {
- if (visual_str) {
- rfbLog("unsetting: %d %d/%d\n", visual_str,
- (int) visual_id, visual_depth);
- free(visual_str);
- }
- visual_str = NULL;
- visual_id = (VisualID) 0;
- visual_depth = 0;
- }
- xform24to32 = 0;
- do_new_fb(1);
- goto done;
- }
- if (strstr(p, "visual") == p) {
- COLON_CHECK("visual:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(visual_str));
- goto qry;
- }
- p += strlen("visual:");
- if (visual_str) free(visual_str);
- visual_str = strdup(p);
-
- /* OK, this requires a new fb... */
- do_new_fb(0);
- goto done;
- }
- if (!strcmp(p, "scale") ||
- strstr(p, "scale:") == p) { /* skip-cmd-list */
- COLON_CHECK("scale:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(scale_str));
- goto qry;
- }
- p += strlen("scale:");
- if (scale_str) free(scale_str);
- scale_str = strdup(p);
-
- /* OK, this requires a new fb... */
- check_black_fb();
- do_new_fb(0);
- goto done;
- }
- if (!strcmp(p, "scale_cursor") ||
- strstr(p, "scale_cursor:") == p) { /* skip-cmd-list */
- COLON_CHECK("scale_cursor:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(scale_cursor_str));
- goto qry;
- }
- p += strlen("scale_cursor:");
- if (scale_cursor_str) free(scale_cursor_str);
- if (*p == '\0') {
- scale_cursor_str = NULL;
- } else {
- scale_cursor_str = strdup(p);
- }
- setup_cursors_and_push();
- goto done;
- }
- if (!strcmp(p, "viewonly")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, view_only);
- goto qry;
- }
- rfbLog("remote_cmd: enable viewonly mode.\n");
- view_only = 1;
- goto done;
- }
- if (!strcmp(p, "noviewonly")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !view_only);
- goto qry;
- }
- rfbLog("remote_cmd: disable viewonly mode.\n");
- view_only = 0;
- if (raw_fb) set_raw_fb_params(0);
- goto done;
- }
- if (!strcmp(p, "shared")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, shared); goto qry;
- }
- rfbLog("remote_cmd: enable sharing.\n");
- shared = 1;
- if (screen) {
- /* mutex */
- screen->alwaysShared = TRUE;
- screen->neverShared = FALSE;
- }
- goto done;
- }
- if (!strcmp(p, "noshared")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !shared); goto qry;
- }
- rfbLog("remote_cmd: disable sharing.\n");
- shared = 0;
- if (screen) {
- /* mutex */
- screen->alwaysShared = FALSE;
- screen->neverShared = TRUE;
- }
- goto done;
- }
- if (!strcmp(p, "forever")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, 1-connect_once);
- goto qry;
- }
- rfbLog("remote_cmd: enable -forever mode.\n");
- connect_once = 0;
- goto done;
- }
- if (!strcmp(p, "noforever") || !strcmp(p, "once")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, connect_once);
- goto qry;
- }
- rfbLog("remote_cmd: disable -forever mode.\n");
- connect_once = 1;
- goto done;
- }
- if (strstr(p, "timeout") == p) {
- int to;
- COLON_CHECK("timeout:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- first_conn_timeout);
- goto qry;
- }
- p += strlen("timeout:");
- to = atoi(p);
- if (to > 0 ) {
- to = -to;
- }
- first_conn_timeout = to;
- rfbLog("remote_cmd: set -timeout to %d\n", -to);
- goto done;
- }
- if (!strcmp(p, "tightfilexfer")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, tightfilexfer);
- goto qry;
- }
-#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
- if (! tightfilexfer) {
- rfbLog("remote_cmd: enabling -tightfilexfer for *NEW* clients.\n");
- tightfilexfer = 1;
- rfbLog("rfbRegisterTightVNCFileTransferExtension: 4\n");
- rfbRegisterTightVNCFileTransferExtension();
- }
-#else
- rfbLog("remote_cmd: -tightfilexfer not supported in this binary.\n");
-#endif
- goto done;
- }
- if (!strcmp(p, "notightfilexfer")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !tightfilexfer);
- goto qry;
- }
-#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
- if (tightfilexfer) {
- rfbLog("remote_cmd: disabling -tightfilexfer for *NEW* clients.\n");
- tightfilexfer = 0;
- rfbLog("rfbUnregisterTightVNCFileTransferExtension: 2\n");
- rfbUnregisterTightVNCFileTransferExtension();
- }
-#else
- rfbLog("remote_cmd: -tightfilexfer not supported in this binary.\n");
-#endif
- goto done;
- }
- if (!strcmp(p, "ultrafilexfer")) {
- if (query) {
- if (screen) {
- snprintf(buf, bufn, "ans=%s:%d", p, screen->permitFileTransfer == TRUE);
- } else {
- snprintf(buf, bufn, "ans=%s:%d", p, 0);
- }
- goto qry;
- }
- if (! screen->permitFileTransfer) {
- rfbLog("remote_cmd: enabling -ultrafilexfer for clients.\n");
- /* mutex */
- screen->permitFileTransfer = TRUE;
- }
- goto done;
- }
- if (!strcmp(p, "noultrafilexfer")) {
- if (query) {
- if (screen) {
- snprintf(buf, bufn, "ans=%s:%d", p, screen->permitFileTransfer == FALSE);
- } else {
- snprintf(buf, bufn, "ans=%s:%d", p, 1);
- }
- goto qry;
- }
- if (screen->permitFileTransfer) {
- rfbLog("remote_cmd: disabling -ultrafilexfer for clients.\n");
- /* mutex */
- screen->permitFileTransfer = FALSE;
- }
- goto done;
- }
- if (strstr(p, "rfbversion") == p) {
- int maj, min;
- COLON_CHECK("rfbversion:")
- if (query) {
- if (screen) {
- snprintf(buf, bufn, "ans=%s:%d.%d", p, screen->protocolMajorVersion, screen->protocolMinorVersion);
- } else {
- snprintf(buf, bufn, "ans=%s:%d.%d", p, 3, 8);
- }
- goto qry;
- }
- p += strlen("rfbversion:");
-
- if (sscanf(p, "%d.%d", &maj, &min) == 2) {
- /* mutex */
- screen->protocolMajorVersion = maj;
- screen->protocolMinorVersion = min;
- rfbLog("remote_cmd: set rfbversion to: %d.%d\n", maj, min);
- } else {
- rfbLog("remote_cmd: invalid rfbversion: %s\n", p);
- }
- goto done;
- }
- if (!strcmp(p, "deny") || !strcmp(p, "lock")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, deny_all);
- goto qry;
- }
- rfbLog("remote_cmd: denying new connections.\n");
- deny_all = 1;
- goto done;
- }
- if (!strcmp(p, "nodeny") || !strcmp(p, "unlock")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !deny_all);
- goto qry;
- }
- rfbLog("remote_cmd: allowing new connections.\n");
- deny_all = 0;
- goto done;
- }
- if (!strcmp(p, "avahi") || !strcmp(p, "mdns") || !strcmp(p, "zeroconf")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, avahi);
- goto qry;
- }
- rfbLog("remote_cmd: enable -avahi mDNS mode.\n");
- if (!avahi) {
- avahi = 1;
- avahi_initialise();
- avahi_advertise(vnc_desktop_name, this_host(),
- screen->port);
- }
- goto done;
- }
- if (!strcmp(p, "noavahi") || !strcmp(p, "nomdns") || !strcmp(p, "nozeroconf")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !avahi);
- goto qry;
- }
- rfbLog("remote_cmd: disable -avahi mDNS mode.\n");
- if (avahi) {
- avahi = 0;
- avahi_reset();
- }
- goto done;
- }
- if (strstr(p, "connect") == p) {
- NOTAPP
- COLON_CHECK("connect:")
- p += strlen("connect:");
- /* this is a reverse connection */
- reverse_connect(p);
- goto done;
- }
- if (strstr(p, "proxy") == p) {
- COLON_CHECK("proxy:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(connect_proxy));
- goto qry;
- }
- p += strlen("proxy:");
- if (connect_proxy) {
- free(connect_proxy);
- connect_proxy = NULL;
- }
- if (!strcmp(p, "") || !strcasecmp(p, "none")) { /* skip-cmd-list */
- rfbLog("remote_cmd: disabled -proxy\n");
- } else {
- connect_proxy = strdup(p);
- rfbLog("remote_cmd: set -proxy %s\n", connect_proxy);
- }
- goto done;
- }
- if (strstr(p, "allowonce") == p) {
- COLON_CHECK("allowonce:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(allow_once));
- goto qry;
- }
- p += strlen("allowonce:");
- allow_once = strdup(p);
- rfbLog("remote_cmd: set allow_once %s\n", allow_once);
- goto done;
- }
- if (strstr(p, "allow") == p) {
- char *before, *old;
- COLON_CHECK("allow:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(allow_list));
- goto qry;
- }
-
- if (unixpw) {
- rfbLog("remote_cmd: cannot change allow in -unixpw\n");
- goto done;
- }
- p += strlen("allow:");
- if (allow_list && strchr(allow_list, '/')) {
- rfbLog("remote_cmd: cannot use allow:host\n");
- rfbLog("in '-allow %s' mode.\n", allow_list);
- goto done;
- }
- if (allow_list) {
- before = strdup(allow_list);
- } else {
- before = strdup("");
- }
-
- old = allow_list;
- if (*p == '+') {
- p++;
- allow_list = add_item(allow_list, p);
- } else if (*p == '-') {
- p++;
- allow_list = delete_item(allow_list, p);
- } else {
- allow_list = strdup(p);
- }
-
- if (strcmp(before, allow_list)) {
- rfbLog("remote_cmd: modified allow_list:\n");
- rfbLog(" from: \"%s\"\n", before);
- rfbLog(" to: \"%s\"\n", allow_list);
- }
- if (old) free(old);
- free(before);
- goto done;
- }
- if (!strcmp(p, "noipv6")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, noipv6);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -noipv6 mode for future sockets.\n");
- noipv6 = 1;
- goto done;
- }
- if (!strcmp(p, "ipv6")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !noipv6);
- goto qry;
- }
- rfbLog("remote_cmd: disabling -noipv6 mode for future sockets.\n");
- noipv6 = 0;
- goto done;
- }
- if (!strcmp(p, "noipv4")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, noipv4);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -noipv4 mode for future sockets.\n");
- noipv4 = 1;
- goto done;
- }
- if (!strcmp(p, "ipv4")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !noipv4);
- goto qry;
- }
- rfbLog("remote_cmd: disabling -noipv4 mode for future sockets.\n");
- noipv4 = 0;
- goto done;
- }
- if (!strcmp(p, "no6")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ipv6_listen);
- goto qry;
- }
- if (ipv6_listen) {
- ipv6_listen = 0;
- rfbLog("disabling -6 IPv6 listening mode.\n");
- reset_rfbport(-1, screen->port);
- reset_httpport(-1, screen->httpPort);
- if (https_port_num > 0) {
- https_port(1);
- }
- }
- goto done;
- }
- if (!strcmp(p, "6")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, ipv6_listen);
- goto qry;
- }
- if (!ipv6_listen) {
- ipv6_listen = 1;
- rfbLog("enabling -6 IPv6 listening mode.\n");
- reset_rfbport(-1, screen->port);
- reset_httpport(-1, screen->httpPort);
- if (https_port_num > 0) {
- https_port(1);
- }
- }
- goto done;
- }
- if (!strcmp(p, "localhost")) {
- char *before, *old;
- if (query) {
- int state = 0;
- char *s = allow_list;
- if (s && (!strcmp(s, "127.0.0.1") ||
- !strcmp(s, "localhost"))) {
- state = 1;
- }
- snprintf(buf, bufn, "ans=%s:%d", p, state);
- goto qry;
- }
- if (allow_list) {
- before = strdup(allow_list);
- } else {
- before = strdup("");
- }
- old = allow_list;
-
- allow_list = strdup("127.0.0.1");
-
- if (strcmp(before, allow_list)) {
- rfbLog("remote_cmd: modified allow_list:\n");
- rfbLog(" from: \"%s\"\n", before);
- rfbLog(" to: \"%s\"\n", allow_list);
- }
- if (old) free(old);
- free(before);
-
- if (listen_str) {
- free(listen_str);
- }
- listen_str = strdup("localhost");
-
- /* mutex */
- screen->listenInterface = htonl(INADDR_LOOPBACK);
- rfbLog("listening on loopback network only.\n");
- rfbLog("allow list is: '%s'\n", NONUL(allow_list));
- reset_rfbport(-1, screen->port);
- reset_httpport(-1, screen->httpPort);
- goto done;
- }
- if (!strcmp(p, "nolocalhost")) {
- char *before, *old;
- if (query) {
- int state = 0;
- char *s = allow_list;
- if (s && (!strcmp(s, "127.0.0.1") ||
- !strcmp(s, "localhost"))) {
- state = 1;
- }
- snprintf(buf, bufn, "ans=%s:%d", p, !state);
- goto qry;
- }
- if (unixpw) {
- rfbLog("remote_cmd: cannot change localhost in -unixpw\n");
- goto done;
- }
- if (allow_list) {
- before = strdup(allow_list);
- } else {
- before = strdup("");
- }
- old = allow_list;
-
- allow_list = strdup("");
-
- if (strcmp(before, allow_list)) {
- rfbLog("remote_cmd: modified allow_list:\n");
- rfbLog(" from: \"%s\"\n", before);
- rfbLog(" to: \"%s\"\n", allow_list);
- }
- if (old) free(old);
- free(before);
-
- if (listen_str) {
- free(listen_str);
- }
- listen_str = NULL;
-
- /* mutex */
- screen->listenInterface = htonl(INADDR_ANY);
- rfbLog("listening on ALL network interfaces.\n");
- rfbLog("allow list is: '%s'\n", NONUL(allow_list));
- reset_rfbport(-1, screen->port);
- reset_httpport(-1, screen->httpPort);
- goto done;
- }
- if (strstr(p, "listen") == p) {
- char *before;
- int ok, mod = 0;
-
- COLON_CHECK("listen:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(listen_str));
- goto qry;
- }
- if (unixpw) {
- rfbLog("remote_cmd: cannot change listen in -unixpw\n");
- goto done;
- }
- if (listen_str) {
- before = strdup(listen_str);
- } else {
- before = strdup("");
- }
- p += strlen("listen:");
-
- listen_str = strdup(p);
-
- if (strcmp(before, listen_str)) {
- rfbLog("remote_cmd: modified listen_str:\n");
- rfbLog(" from: \"%s\"\n", before);
- rfbLog(" to: \"%s\"\n", listen_str);
- mod = 1;
- }
-
- ok = 1;
- /* mutex */
- if (listen_str == NULL || *listen_str == '\0' ||
- !strcmp(listen_str, "any")) {
- screen->listenInterface = htonl(INADDR_ANY);
- } else if (!strcmp(listen_str, "localhost")) {
- screen->listenInterface = htonl(INADDR_LOOPBACK);
- } else {
- struct hostent *hp;
- in_addr_t iface = inet_addr(listen_str);
- if (iface == htonl(INADDR_NONE)) {
- if (!host_lookup) {
- ok = 0;
- } else if (!(hp = gethostbyname(listen_str))) {
- ok = 0;
- } else {
- iface = *(unsigned long *)hp->h_addr;
- }
- }
- if (ok) {
- screen->listenInterface = iface;
- }
- }
-
- if (ok && mod) {
- int is_loopback = 0;
- in_addr_t iface = screen->listenInterface;
-
- if (allow_list) {
- if (!strcmp(allow_list, "127.0.0.1") ||
- !strcmp(allow_list, "localhost")) {
- is_loopback = 1;
- }
- }
- if (iface != htonl(INADDR_LOOPBACK)) {
- if (is_loopback) {
- rfbLog("re-setting -allow list to all "
- "hosts for non-loopback listening.\n");
- if (allow_list) {
- free(allow_list);
- }
- allow_list = NULL;
- }
- } else {
- if (!is_loopback) {
- if (allow_list) {
- free(allow_list);
- }
- rfbLog("setting -allow list to 127.0.0.1\n");
- allow_list = strdup("127.0.0.1");
- }
- }
- }
- if (ok) {
- rfbLog("allow list is: '%s'\n", NONUL(allow_list));
- reset_rfbport(-1, screen->port);
- reset_httpport(-1, screen->httpPort);
- free(before);
- } else {
- rfbLog("invalid listen string: %s\n", listen_str);
- free(listen_str);
- listen_str = before;
- }
- goto done;
- }
- if (!strcmp(p, "lookup")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, host_lookup);
- goto qry;
- }
- rfbLog("remote_cmd: enabling hostname lookup.\n");
- host_lookup = 1;
- goto done;
- }
- if (!strcmp(p, "nolookup")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !host_lookup);
- goto qry;
- }
- rfbLog("remote_cmd: disabling hostname lookup.\n");
- host_lookup = 0;
- goto done;
- }
- if (strstr(p, "accept") == p) {
- int doit = 1, safe = 0;
- COLON_CHECK("accept:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(accept_cmd));
- goto qry;
- }
- p += strlen("accept:");
- if (!strcmp(p, "") || strstr(p, "popup") == p) { /* skip-cmd-list */
- safe = 1;
- }
- if (safe_remote_only && ! safe) {
- rfbLog("unsafe: %s\n", p);
- doit = 0;
- }
-
- if (doit) {
- if (accept_cmd) free(accept_cmd);
- accept_cmd = strdup(p);
- }
- goto done;
- }
- if (strstr(p, "afteraccept") == p) {
- int safe = 0;
- COLON_CHECK("afteraccept:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(afteraccept_cmd));
- goto qry;
- }
- p += strlen("afteraccept:");
- if (!strcmp(p, "")) { /* skip-cmd-list */
- safe = 1;
- }
- if (safe_remote_only && ! safe) {
- rfbLog("unsafe: %s\n", p);
- } else {
- if (afteraccept_cmd) free(afteraccept_cmd);
- afteraccept_cmd = strdup(p);
- }
- goto done;
- }
- if (strstr(p, "gone") == p) {
- int safe = 0;
- COLON_CHECK("gone:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(gone_cmd));
- goto qry;
- }
- p += strlen("gone:");
- if (!strcmp(p, "") || strstr(p, "popup") == p) { /* skip-cmd-list */
- safe = 1;
- }
- if (safe_remote_only && ! safe) {
- rfbLog("unsafe: %s\n", p);
- } else {
- if (gone_cmd) free(gone_cmd);
- gone_cmd = strdup(p);
- }
- goto done;
- }
- if (!strcmp(p, "shm")) {
- int orig = using_shm;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, using_shm);
- goto qry;
- }
- rfbLog("remote_cmd: turning off noshm mode.\n");
- using_shm = 1;
- if (raw_fb) set_raw_fb_params(0);
-
- if (orig != using_shm) {
- do_new_fb(1);
- } else {
- rfbLog(" already in shm mode.\n");
- }
- goto done;
- }
- if (!strcmp(p, "noshm")) {
- int orig = using_shm;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !using_shm);
- goto qry;
- }
- rfbLog("remote_cmd: turning on noshm mode.\n");
- using_shm = 0;
- if (orig != using_shm) {
- do_new_fb(1);
- } else {
- rfbLog(" already in noshm mode.\n");
- }
- goto done;
- }
- if (!strcmp(p, "flipbyteorder")) {
- int orig = flip_byte_order;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, flip_byte_order);
- goto qry;
- }
- rfbLog("remote_cmd: turning on flipbyteorder mode.\n");
- flip_byte_order = 1;
- if (orig != flip_byte_order) {
- if (! using_shm || xform24to32) {
- do_new_fb(1);
- } else {
- rfbLog(" using shm, not resetting fb\n");
- }
- }
- goto done;
- }
- if (!strcmp(p, "noflipbyteorder")) {
- int orig = flip_byte_order;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !flip_byte_order);
- goto qry;
- }
- rfbLog("remote_cmd: turning off flipbyteorder mode.\n");
- flip_byte_order = 0;
- if (orig != flip_byte_order) {
- if (! using_shm || xform24to32) {
- do_new_fb(1);
- } else {
- rfbLog(" using shm, not resetting fb\n");
- }
- }
- goto done;
- }
- if (!strcmp(p, "onetile")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, single_copytile);
- goto qry;
- }
- rfbLog("remote_cmd: enable -onetile mode.\n");
- single_copytile = 1;
- goto done;
- }
- if (!strcmp(p, "noonetile")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !single_copytile);
- goto qry;
- }
- rfbLog("remote_cmd: disable -onetile mode.\n");
- if (tile_shm_count < ntiles_x) {
- rfbLog(" this has no effect: tile_shm_count=%d"
- " ntiles_x=%d\n", tile_shm_count, ntiles_x);
-
- }
- single_copytile = 0;
- goto done;
- }
- if (strstr(p, "solid_color") == p) {
- /*
- * n.b. this solid stuff perhaps should reflect
- * safe_remote_only but at least the command names
- * are fixed.
- */
- char *newc;
- int doit = 1;
- COLON_CHECK("solid_color:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(solid_str));
- goto qry;
- }
- p += strlen("solid_color:");
- if (*p != '\0') {
- newc = strdup(p);
- } else {
- newc = strdup(solid_default);
- }
- rfbLog("remote_cmd: solid %s -> %s\n", NONUL(solid_str), newc);
-
- if (solid_str) {
- if (!strcmp(solid_str, newc)) {
- doit = 0;
- }
- free(solid_str);
- }
- solid_str = newc;
- use_solid_bg = 1;
- if (raw_fb && !macosx_console) set_raw_fb_params(0);
-
- if (doit && client_count) {
- solid_bg(0);
- }
- goto done;
- }
- if (!strcmp(p, "solid")) {
- int orig = use_solid_bg;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, use_solid_bg);
- goto qry;
- }
- rfbLog("remote_cmd: enable -solid mode\n");
- if (! solid_str) {
- solid_str = strdup(solid_default);
- }
- use_solid_bg = 1;
- if (raw_fb && !macosx_console) set_raw_fb_params(0);
- if (client_count && !orig) {
- solid_bg(0);
- }
- goto done;
- }
- if (!strcmp(p, "nosolid")) {
- int orig = use_solid_bg;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !use_solid_bg);
- goto qry;
- }
- rfbLog("remote_cmd: disable -solid mode\n");
- use_solid_bg = 0;
- if (client_count && orig) {
- solid_bg(1);
- }
- goto done;
- }
- if (strstr(p, "blackout") == p) {
- char *before, *old;
- COLON_CHECK("blackout:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(blackout_str));
- goto qry;
- }
- p += strlen("blackout:");
- if (blackout_str) {
- before = strdup(blackout_str);
- } else {
- before = strdup("");
- }
- old = blackout_str;
- if (*p == '+') {
- p++;
- blackout_str = add_item(blackout_str, p);
- } else if (*p == '-') {
- p++;
- blackout_str = delete_item(blackout_str, p);
- } else {
- blackout_str = strdup(p);
- }
- if (strcmp(before, blackout_str)) {
- rfbLog("remote_cmd: changing -blackout\n");
- rfbLog(" from: %s\n", before);
- rfbLog(" to: %s\n", blackout_str);
- if (0 && !strcmp(blackout_str, "") &&
- single_copytile_orig != single_copytile) {
- rfbLog("resetting single_copytile to: %d\n",
- single_copytile_orig);
- single_copytile = single_copytile_orig;
- }
- initialize_blackouts_and_xinerama();
- }
- if (old) free(old);
- free(before);
- goto done;
- }
- if (!strcmp(p, "xinerama")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, xinerama);
- goto qry;
- }
- rfbLog("remote_cmd: enable xinerama mode. (if applicable).\n");
- xinerama = 1;
- initialize_blackouts_and_xinerama();
- goto done;
- }
- if (!strcmp(p, "noxinerama")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !xinerama);
- goto qry;
- }
- rfbLog("remote_cmd: disable xinerama mode. (if applicable).\n");
- xinerama = 0;
- initialize_blackouts_and_xinerama();
- goto done;
- }
- if (!strcmp(p, "xtrap")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, xtrap_input);
- goto qry;
- }
- rfbLog("remote_cmd: enable xtrap input mode."
- "(if applicable).\n");
- if (! xtrap_input) {
- xtrap_input = 1;
- disable_grabserver(dpy, 1);
- }
- goto done;
- }
- if (!strcmp(p, "noxtrap")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !xtrap_input);
- goto qry;
- }
- rfbLog("remote_cmd: disable xtrap input mode."
- "(if applicable).\n");
- if (xtrap_input) {
- xtrap_input = 0;
- disable_grabserver(dpy, 1);
- }
- goto done;
- }
- if (!strcmp(p, "xrandr")) {
- int orig = xrandr;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, xrandr); goto qry;
- }
- if (xrandr_present) {
- rfbLog("remote_cmd: enable xrandr mode.\n");
- xrandr = 1;
- if (raw_fb) set_raw_fb_params(0);
- if (! xrandr_mode) {
- xrandr_mode = strdup("default");
- }
- if (orig != xrandr) {
- initialize_xrandr();
- }
- } else {
- rfbLog("remote_cmd: XRANDR ext. not present.\n");
- }
- goto done;
- }
- if (!strcmp(p, "noxrandr")) {
- int orig = xrandr;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !xrandr); goto qry;
- }
- xrandr = 0;
- xrandr_maybe = 0;
- if (xrandr_present) {
- rfbLog("remote_cmd: disable xrandr mode.\n");
- if (orig != xrandr) {
- initialize_xrandr();
- }
- } else {
- rfbLog("remote_cmd: XRANDR ext. not present.\n");
- }
- goto done;
- }
- if (strstr(p, "xrandr_mode") == p) {
- int orig = xrandr;
- COLON_CHECK("xrandr_mode:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(xrandr_mode));
- goto qry;
- }
- p += strlen("xrandr_mode:");
- if (!strcmp("none", p)) {
- xrandr = 0;
- xrandr_maybe = 0;
- } else {
- if (known_xrandr_mode(p)) {
- if (xrandr_mode) free(xrandr_mode);
- xrandr_mode = strdup(p);
- } else {
- rfbLog("skipping unknown xrandr mode: %s\n", p);
- goto done;
- }
- xrandr = 1;
- }
- if (xrandr_present) {
- if (xrandr) {
- rfbLog("remote_cmd: enable xrandr mode.\n");
- } else {
- rfbLog("remote_cmd: disable xrandr mode.\n");
- }
- if (! xrandr_mode) {
- xrandr_mode = strdup("default");
- }
- if (orig != xrandr) {
- initialize_xrandr();
- }
- } else {
- rfbLog("remote_cmd: XRANDR ext. not present.\n");
- }
- goto done;
- }
- if (strstr(p, "rotate") == p) {
- COLON_CHECK("rotate:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(rotating_str));
- goto qry;
- }
- p += strlen("rotate:");
- if (rotating_str) free(rotating_str);
- rotating_str = strdup(p);
- rfbLog("remote_cmd: set rotate to \"%s\"\n", rotating_str);
-
- do_new_fb(0);
- goto done;
- }
- if (strstr(p, "padgeom") == p) {
- COLON_CHECK("padgeom:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(pad_geometry));
- goto qry;
- }
- p += strlen("padgeom:");
- if (!strcmp("force", p) || !strcmp("do",p) || !strcmp("go",p)) {
- rfbLog("remote_cmd: invoking install_padded_fb()\n");
- install_padded_fb(pad_geometry);
- } else {
- if (pad_geometry) free(pad_geometry);
- pad_geometry = strdup(p);
- rfbLog("remote_cmd: set padgeom to: %s\n",
- pad_geometry);
- }
- goto done;
- }
- if (!strcmp(p, "quiet") || !strcmp(p, "q")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, quiet); goto qry;
- }
- rfbLog("remote_cmd: turning on quiet mode.\n");
- quiet = 1;
- goto done;
- }
- if (!strcmp(p, "noquiet")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !quiet); goto qry;
- }
- rfbLog("remote_cmd: turning off quiet mode.\n");
- quiet = 0;
- goto done;
- }
- if (!strcmp(p, "modtweak")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, use_modifier_tweak);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -modtweak mode.\n");
- if (! use_modifier_tweak) {
- use_modifier_tweak = 1;
- initialize_modtweak();
- }
- use_modifier_tweak = 1;
- goto done;
- }
- if (!strcmp(p, "nomodtweak")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- !use_modifier_tweak);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -nomodtweak mode.\n");
- got_nomodtweak = 1;
- use_modifier_tweak = 0;
- goto done;
- }
- if (!strcmp(p, "xkb")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, use_xkb_modtweak);
- goto qry;
- }
- if (! xkb_present) {
- rfbLog("remote_cmd: cannot enable -xkb "
- "modtweak mode (not supported on X display)\n");
- goto done;
- }
- rfbLog("remote_cmd: enabling -xkb modtweak mode"
- " (if supported).\n");
- if (! use_modifier_tweak || ! use_xkb_modtweak) {
- use_modifier_tweak = 1;
- use_xkb_modtweak = 1;
- initialize_modtweak();
- }
- use_modifier_tweak = 1;
- use_xkb_modtweak = 1;
- goto done;
- }
- if (!strcmp(p, "noxkb")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !use_xkb_modtweak);
- goto qry;
- }
- if (! xkb_present) {
- rfbLog("remote_cmd: cannot disable -xkb "
- "modtweak mode (not supported on X display)\n");
- goto done;
- }
- rfbLog("remote_cmd: disabling -xkb modtweak mode.\n");
- use_xkb_modtweak = 0;
- got_noxkb = 1;
- initialize_modtweak();
- goto done;
- }
- if (!strcmp(p, "capslock")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, watch_capslock);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -capslock mode\n");
- watch_capslock = 1;
- goto done;
- }
- if (!strcmp(p, "nocapslock")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !watch_capslock);
- goto qry;
- }
- rfbLog("remote_cmd: disabling -capslock mode\n");
- watch_capslock = 0;
- goto done;
- }
- if (!strcmp(p, "skip_lockkeys")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, skip_lockkeys);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -skip_lockkeys mode\n");
- skip_lockkeys = 1;
- goto done;
- }
- if (!strcmp(p, "noskip_lockkeys")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !skip_lockkeys);
- goto qry;
- }
- rfbLog("remote_cmd: disabling -skip_lockkeys mode\n");
- skip_lockkeys = 0;
- goto done;
- }
- if (strstr(p, "skip_keycodes") == p) {
- COLON_CHECK("skip_keycodes:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(skip_keycodes));
- goto qry;
- }
- p += strlen("skip_keycodes:");
- rfbLog("remote_cmd: setting xkb -skip_keycodes"
- " to:\n\t'%s'\n", p);
- if (! xkb_present) {
- rfbLog("remote_cmd: warning xkb not present\n");
- } else if (! use_xkb_modtweak) {
- rfbLog("remote_cmd: turning on xkb.\n");
- use_xkb_modtweak = 1;
- if (! use_modifier_tweak) {
- rfbLog("remote_cmd: turning on modtweak.\n");
- use_modifier_tweak = 1;
- }
- }
- if (skip_keycodes) free(skip_keycodes);
- skip_keycodes = strdup(p);
- initialize_modtweak();
- goto done;
- }
- if (!strcmp(p, "sloppy_keys")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, sloppy_keys);
- goto qry;
- }
- sloppy_keys += 1;
- rfbLog("remote_cmd: set sloppy_keys to: %d\n", sloppy_keys);
- goto done;
- }
- if (!strcmp(p, "nosloppy_keys")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !sloppy_keys);
- goto qry;
- }
- sloppy_keys = 0;
- rfbLog("remote_cmd: set sloppy_keys to: %d\n", sloppy_keys);
- goto done;
- }
- if (!strcmp(p, "skip_dups")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- skip_duplicate_key_events);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -skip_dups mode\n");
- skip_duplicate_key_events = 1;
- goto done;
- }
- if (!strcmp(p, "noskip_dups")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- !skip_duplicate_key_events);
- goto qry;
- }
- rfbLog("remote_cmd: disabling -skip_dups mode\n");
- skip_duplicate_key_events = 0;
- goto done;
- }
- if (!strcmp(p, "add_keysyms")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, add_keysyms);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -add_keysyms mode.\n");
- add_keysyms = 1;
- goto done;
- }
- if (!strcmp(p, "noadd_keysyms")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !add_keysyms);
- goto qry;
- }
- rfbLog("remote_cmd: disabling -add_keysyms mode.\n");
- add_keysyms = 0;
- goto done;
- }
- if (!strcmp(p, "clear_mods")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, clear_mods == 1);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -clear_mods mode.\n");
- clear_mods = 1;
- if (use_threads) {X_LOCK;}
- clear_modifiers(0);
- if (use_threads) {X_UNLOCK;}
- goto done;
- }
- if (!strcmp(p, "noclear_mods")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- !(clear_mods == 1));
- goto qry;
- }
- rfbLog("remote_cmd: disabling -clear_mods mode.\n");
- clear_mods = 0;
- goto done;
- }
- if (!strcmp(p, "clear_keys")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- clear_mods == 2);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -clear_keys mode.\n");
- clear_mods = 2;
- if (use_threads) {X_LOCK;}
- clear_keys();
- if (use_threads) {X_UNLOCK;}
- goto done;
- }
- if (!strcmp(p, "noclear_keys")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- !(clear_mods == 2));
- goto qry;
- }
- rfbLog("remote_cmd: disabling -clear_keys mode.\n");
- clear_mods = 0;
- goto done;
- }
- if (!strcmp(p, "clear_all")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- clear_mods == 3);
- goto qry;
- }
- rfbLog("remote_cmd: doing clear_all action.\n");
- clear_mods = 3;
- if (use_threads) {X_LOCK;}
- clear_keys();
- clear_locks();
- if (use_threads) {X_UNLOCK;}
- goto done;
- }
- if (!strcmp(p, "clear_locks")) {
- NOTAPP
- rfbLog("remote_cmd: doing clear_locks action.\n");
- if (use_threads) {X_LOCK;}
- clear_locks();
- if (use_threads) {X_UNLOCK;}
- goto done;
- }
- if (!strcmp(p, "keystate")) {
- int i, state[256];
- NOTAPP
- for (i=0; i<256; i++) {
- state[i] = 0;
- }
- if (use_threads) {X_LOCK;}
- get_keystate(state);
- if (use_threads) {X_UNLOCK;}
- for (i=0; i<256; i++) {
- fprintf(stderr, "keystate[%03d] %d\n", i, state[i]);
- }
- goto done;
- }
- if (strstr(p, "remap") == p) {
- char *before, *old;
- COLON_CHECK("remap:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(remap_file));
- goto qry;
- }
- p += strlen("remap:");
- if ((*p == '+' || *p == '-') && remap_file &&
- strchr(remap_file, '/')) {
- rfbLog("remote_cmd: cannot use remap:+/-\n");
- rfbLog("in '-remap %s' mode.\n", remap_file);
- goto done;
- }
- if (remap_file) {
- before = strdup(remap_file);
- } else {
- before = strdup("");
- }
- old = remap_file;
- if (*p == '+') {
- p++;
- remap_file = add_item(remap_file, p);
- } else if (*p == '-') {
- p++;
- remap_file = delete_item(remap_file, p);
- if (! strchr(remap_file, '-')) {
- *remap_file = '\0';
- }
- } else {
- remap_file = strdup(p);
- }
- if (strcmp(before, remap_file)) {
- rfbLog("remote_cmd: changed -remap\n");
- rfbLog(" from: %s\n", before);
- rfbLog(" to: %s\n", remap_file);
- initialize_remap(remap_file);
- }
- if (old) free(old);
- free(before);
- goto done;
- }
- if (!strcmp(p, "repeat")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !no_autorepeat);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -repeat mode.\n");
- autorepeat(1, 0); /* restore initial setting */
- no_autorepeat = 0;
- goto done;
- }
- if (!strcmp(p, "norepeat")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, no_autorepeat);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -norepeat mode.\n");
- no_autorepeat = 1;
- if (no_repeat_countdown >= 0) {
- no_repeat_countdown = 2;
- }
- if (client_count && ! view_only) {
- autorepeat(0, 0); /* disable if any clients */
- }
- goto done;
- }
- if (!strcmp(p, "fb")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !nofb);
- goto qry;
- }
- if (nofb) {
- rfbLog("remote_cmd: disabling nofb mode.\n");
- rfbLog(" you may need to these turn back on:\n");
- rfbLog(" xfixes, xdamage, solid, flashcmap\n");
- rfbLog(" overlay, shm, noonetile, nap, cursor\n");
- rfbLog(" cursorpos, cursorshape, bell.\n");
- nofb = 0;
- set_nofb_params(1);
- do_new_fb(1);
- }
- goto done;
- }
- if (!strcmp(p, "nofb")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, nofb);
- goto qry;
- }
- if (!nofb) {
- rfbLog("remote_cmd: enabling nofb mode.\n");
- if (main_fb) {
- push_black_screen(4);
- }
- nofb = 1;
- sound_bell = 0;
- initialize_watch_bell();
- set_nofb_params(0);
- do_new_fb(1);
- }
- goto done;
- }
- if (!strcmp(p, "bell")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, sound_bell);
- goto qry;
- }
- rfbLog("remote_cmd: enabling bell (if supported).\n");
- initialize_watch_bell();
- sound_bell = 1;
- goto done;
- }
- if (!strcmp(p, "nobell")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !sound_bell);
- goto qry;
- }
- rfbLog("remote_cmd: disabling bell.\n");
- initialize_watch_bell();
- sound_bell = 0;
- goto done;
- }
- if (!strcmp(p, "sendbell")) {
- NOTAPP
- rfbLog("remote_cmd: sendbell.\n");
- if (screen && client_count) {
- rfbSendBell(screen);
- }
- goto done;
- }
- if (!strcmp(p, "sel")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, watch_selection);
- goto qry;
- }
- rfbLog("remote_cmd: enabling watch selection+primary.\n");
- watch_selection = 1;
- watch_primary = 1;
- watch_clipboard = 1;
- goto done;
- }
- if (!strcmp(p, "nosel")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !watch_selection);
- goto qry;
- }
- rfbLog("remote_cmd: disabling watch selection+primary.\n");
- watch_selection = 0;
- watch_primary = 0;
- watch_clipboard = 0;
- goto done;
- }
- if (!strcmp(p, "primary")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, watch_primary);
- goto qry;
- }
- rfbLog("remote_cmd: enabling watch_primary.\n");
- watch_primary = 1;
- goto done;
- }
- if (!strcmp(p, "noprimary")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !watch_primary);
- goto qry;
- }
- rfbLog("remote_cmd: disabling watch_primary.\n");
- watch_primary = 0;
- goto done;
- }
- if (!strcmp(p, "setprimary")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, set_primary);
- goto qry;
- }
- rfbLog("remote_cmd: enabling set_primary.\n");
- set_primary = 1;
- goto done;
- }
- if (!strcmp(p, "nosetprimary")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !set_primary);
- goto qry;
- }
- rfbLog("remote_cmd: disabling set_primary.\n");
- set_primary = 0;
- goto done;
- }
- if (!strcmp(p, "clipboard")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, watch_clipboard);
- goto qry;
- }
- rfbLog("remote_cmd: enabling watch_clipboard.\n");
- watch_clipboard = 1;
- goto done;
- }
- if (!strcmp(p, "noclipboard")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !watch_clipboard);
- goto qry;
- }
- rfbLog("remote_cmd: disabling watch_clipboard.\n");
- watch_clipboard = 0;
- goto done;
- }
- if (!strcmp(p, "setclipboard")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, set_clipboard);
- goto qry;
- }
- rfbLog("remote_cmd: enabling set_clipboard.\n");
- set_clipboard = 1;
- goto done;
- }
- if (!strcmp(p, "nosetclipboard")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !set_clipboard);
- goto qry;
- }
- rfbLog("remote_cmd: disabling set_clipboard.\n");
- set_clipboard = 0;
- goto done;
- }
- if (strstr(p, "seldir") == p) {
- COLON_CHECK("seldir:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(sel_direction));
- goto qry;
- }
- p += strlen("seldir:");
- rfbLog("remote_cmd: setting -seldir to %s\n", p);
- if (sel_direction) free(sel_direction);
- sel_direction = strdup(p);
- goto done;
- }
- if (!strcmp(p, "set_no_cursor")) { /* skip-cmd-list */
- rfbLog("remote_cmd: calling set_no_cursor()\n");
- set_no_cursor();
- goto done;
- }
- if (!strcmp(p, "cursorshape")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- cursor_shape_updates);
- goto qry;
- }
- rfbLog("remote_cmd: turning on cursorshape mode.\n");
-
- set_no_cursor();
- cursor_shape_updates = 1;
- restore_cursor_shape_updates(screen);
- first_cursor();
- goto done;
- }
- if (!strcmp(p, "nocursorshape")) {
- int i, max = 5;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- !cursor_shape_updates);
- goto qry;
- }
- rfbLog("remote_cmd: turning off cursorshape mode.\n");
-
- set_no_cursor();
- for (i=0; i<max; i++) {
- /* XXX: try to force empty cursor back to client */
- rfbPE(-1);
- }
- cursor_shape_updates = 0;
- disable_cursor_shape_updates(screen);
- first_cursor();
- goto done;
- }
- if (!strcmp(p, "cursorpos")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- cursor_pos_updates);
- goto qry;
- }
- rfbLog("remote_cmd: turning on cursorpos mode.\n");
- cursor_pos_updates = 1;
- goto done;
- }
- if (!strcmp(p, "nocursorpos")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- !cursor_pos_updates);
- goto qry;
- }
- rfbLog("remote_cmd: turning off cursorpos mode.\n");
- cursor_pos_updates = 0;
- goto done;
- }
- if (!strcmp(p, "cursor_drag")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, cursor_drag_changes);
- goto qry;
- }
- cursor_drag_changes = 1;
- rfbLog("remote_cmd: setting cursor_drag_changes: %d.\n", cursor_drag_changes);
- goto done;
- }
- if (!strcmp(p, "nocursor_drag")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !cursor_drag_changes);
- goto qry;
- }
- cursor_drag_changes = 0;
- rfbLog("remote_cmd: setting cursor_drag_changes: %d.\n", cursor_drag_changes);
- goto done;
- }
- if (strstr(p, "cursor") == p) {
- COLON_CHECK("cursor:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(multiple_cursors_mode));
- goto qry;
- }
- p += strlen("cursor:");
- if (multiple_cursors_mode) {
- if (prev_cursors_mode) free(prev_cursors_mode);
- prev_cursors_mode = strdup(multiple_cursors_mode);
- free(multiple_cursors_mode);
- }
- multiple_cursors_mode = strdup(p);
-
- rfbLog("remote_cmd: changed -cursor mode "
- "to: %s\n", multiple_cursors_mode);
-
- if (strcmp(multiple_cursors_mode, "none") && !show_cursor) {
- show_cursor = 1;
- rfbLog("remote_cmd: changed show_cursor "
- "to: %d\n", show_cursor);
- }
- initialize_cursors_mode();
- first_cursor();
- goto done;
- }
- if (!strcmp(p, "show_cursor")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, show_cursor);
- goto qry;
- }
- rfbLog("remote_cmd: enabling show_cursor.\n");
- show_cursor = 1;
- if (multiple_cursors_mode && !strcmp(multiple_cursors_mode,
- "none")) {
- free(multiple_cursors_mode);
- if (prev_cursors_mode) {
- multiple_cursors_mode =
- strdup(prev_cursors_mode);
- } else {
- multiple_cursors_mode = strdup("default");
- }
- rfbLog("remote_cmd: changed -cursor mode "
- "to: %s\n", multiple_cursors_mode);
- }
- initialize_cursors_mode();
- first_cursor();
- goto done;
- }
- if (!strcmp(p, "noshow_cursor") || !strcmp(p, "nocursor")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !show_cursor);
- goto qry;
- }
- if (prev_cursors_mode) free(prev_cursors_mode);
- prev_cursors_mode = strdup(multiple_cursors_mode);
-
- rfbLog("remote_cmd: disabling show_cursor.\n");
- show_cursor = 0;
- initialize_cursors_mode();
- first_cursor();
- goto done;
- }
- if (strstr(p, "arrow") == p) {
- COLON_CHECK("arrow:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, alt_arrow);
- goto qry;
- }
- p += strlen("arrow:");
- alt_arrow = atoi(p);
- rfbLog("remote_cmd: setting alt_arrow: %d.\n", alt_arrow);
- setup_cursors_and_push();
- goto done;
- }
- if (!strcmp(p, "xfixes")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, use_xfixes);
- goto qry;
- }
- if (! xfixes_present) {
- rfbLog("remote_cmd: cannot enable xfixes "
- "(not supported on X display)\n");
- goto done;
- }
- rfbLog("remote_cmd: enabling -xfixes"
- " (if supported).\n");
- use_xfixes = 1;
- initialize_xfixes();
- first_cursor();
- goto done;
- }
- if (!strcmp(p, "noxfixes")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !use_xfixes);
- goto qry;
- }
- if (! xfixes_present) {
- rfbLog("remote_cmd: disabling xfixes "
- "(but not supported on X display)\n");
- goto done;
- }
- rfbLog("remote_cmd: disabling -xfixes.\n");
- use_xfixes = 0;
- initialize_xfixes();
- first_cursor();
- goto done;
- }
- if (!strcmp(p, "xdamage")) {
- int orig = use_xdamage;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, use_xdamage);
- goto qry;
- }
- if (! xdamage_present) {
- rfbLog("remote_cmd: cannot enable xdamage hints "
- "(not supported on X display)\n");
- goto done;
- }
- rfbLog("remote_cmd: enabling xdamage hints"
- " (if supported).\n");
- use_xdamage = 1;
- if (use_xdamage != orig) {
- initialize_xdamage();
- create_xdamage_if_needed(0);
- }
- goto done;
- }
- if (!strcmp(p, "noxdamage")) {
- int orig = use_xdamage;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !use_xdamage);
- goto qry;
- }
- if (! xdamage_present) {
- rfbLog("remote_cmd: disabling xdamage hints "
- "(but not supported on X display)\n");
- goto done;
- }
- rfbLog("remote_cmd: disabling xdamage hints.\n");
- use_xdamage = 0;
- if (use_xdamage != orig) {
- initialize_xdamage();
- destroy_xdamage_if_needed();
- }
- goto done;
- }
- if (strstr(p, "xd_area") == p) {
- int a;
- COLON_CHECK("xd_area:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- xdamage_max_area);
- goto qry;
- }
- p += strlen("xd_area:");
- a = atoi(p);
- if (a >= 0) {
- rfbLog("remote_cmd: setting xdamage_max_area "
- "%d -> %d.\n", xdamage_max_area, a);
- xdamage_max_area = a;
- }
- goto done;
- }
- if (strstr(p, "xd_mem") == p) {
- double a;
- COLON_CHECK("xd_mem:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%.3f", p, co,
- xdamage_memory);
- goto qry;
- }
- p += strlen("xd_mem:");
- a = atof(p);
- if (a >= 0.0) {
- rfbLog("remote_cmd: setting xdamage_memory "
- "%.3f -> %.3f.\n", xdamage_memory, a);
- xdamage_memory = a;
- }
- goto done;
- }
- if (strstr(p, "alphacut") == p) {
- int a;
- COLON_CHECK("alphacut:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- alpha_threshold);
- goto qry;
- }
- p += strlen("alphacut:");
- a = atoi(p);
- if (a < 0) a = 0;
- if (a > 256) a = 256; /* allow 256 for testing. */
- if (alpha_threshold != a) {
- rfbLog("remote_cmd: setting alphacut "
- "%d -> %d.\n", alpha_threshold, a);
- if (a == 256) {
- rfbLog("note: alphacut=256 leads to completely"
- " transparent cursors.\n");
- }
- alpha_threshold = a;
- setup_cursors_and_push();
- }
- goto done;
- }
- if (strstr(p, "alphafrac") == p) {
- double a;
- COLON_CHECK("alphafrac:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%f", p, co,
- alpha_frac);
- goto qry;
- }
- p += strlen("alphafrac:");
- a = atof(p);
- if (a < 0.0) a = 0.0;
- if (a > 1.0) a = 1.0;
- if (alpha_frac != a) {
- rfbLog("remote_cmd: setting alphafrac "
- "%f -> %f.\n", alpha_frac, a);
- alpha_frac = a;
- setup_cursors_and_push();
- }
- goto done;
- }
- if (strstr(p, "alpharemove") == p) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, alpha_remove);
- goto qry;
- }
- if (!alpha_remove) {
- rfbLog("remote_cmd: enable alpharemove\n");
- alpha_remove = 1;
- setup_cursors_and_push();
- }
- goto done;
- }
- if (strstr(p, "noalpharemove") == p) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !alpha_remove);
- goto qry;
- }
- if (alpha_remove) {
- rfbLog("remote_cmd: disable alpharemove\n");
- alpha_remove = 0;
- setup_cursors_and_push();
- }
- goto done;
- }
- if (strstr(p, "alphablend") == p) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, alpha_blend);
- goto qry;
- }
- if (!alpha_blend) {
- rfbLog("remote_cmd: enable alphablend\n");
- alpha_remove = 0;
- alpha_blend = 1;
- setup_cursors_and_push();
- }
- goto done;
- }
- if (strstr(p, "noalphablend") == p) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !alpha_blend);
- goto qry;
- }
- if (alpha_blend) {
- rfbLog("remote_cmd: disable alphablend\n");
- alpha_blend = 0;
- setup_cursors_and_push();
- }
- goto done;
- }
- if (strstr(p, "xwarppointer") == p || strstr(p, "xwarp") == p) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, use_xwarppointer);
- goto qry;
- }
- rfbLog("remote_cmd: turning on xwarppointer mode.\n");
- use_xwarppointer = 1;
- goto done;
- }
- if (strstr(p, "noxwarppointer") == p ||
- strstr(p, "noxwarp") == p) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !use_xwarppointer);
- goto qry;
- }
- rfbLog("remote_cmd: turning off xwarppointer mode.\n");
- use_xwarppointer = 0;
- goto done;
- }
- if (strstr(p, "always_inject") == p) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, always_inject);
- goto qry;
- }
- rfbLog("remote_cmd: turning on always_inject mode.\n");
- always_inject = 1;
- goto done;
- }
- if (strstr(p, "noalways_inject") == p) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !always_inject);
- goto qry;
- }
- rfbLog("remote_cmd: turning off always_inject mode.\n");
- always_inject = 0;
- goto done;
- }
- if (strstr(p, "buttonmap") == p) {
- COLON_CHECK("buttonmap:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(pointer_remap));
- goto qry;
- }
- p += strlen("buttonmap:");
- if (pointer_remap) free(pointer_remap);
- pointer_remap = strdup(p);
-
- rfbLog("remote_cmd: setting -buttonmap to:\n\t'%s'\n", p);
- initialize_pointer_map(p);
- goto done;
- }
- if (!strcmp(p, "dragging")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, show_dragging);
- goto qry;
- }
- rfbLog("remote_cmd: enabling mouse dragging mode.\n");
- show_dragging = 1;
- goto done;
- }
- if (!strcmp(p, "nodragging")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !show_dragging);
- goto qry;
- }
- rfbLog("remote_cmd: enabling mouse nodragging mode.\n");
- show_dragging = 0;
- goto done;
- }
-#ifndef NO_NCACHE
- if (!strcmp(p, "ncache_cr")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, ncache_copyrect);
- goto qry;
- }
- ncache_copyrect = 1;
- rfbLog("remote_cmd: set -ncache_cr %d\n", ncache_copyrect);
- goto done;
- }
- if (!strcmp(p, "noncache_cr")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ncache_copyrect);
- goto qry;
- }
- ncache_copyrect = 0;
- rfbLog("remote_cmd: disabled -ncache_cr %d\n", ncache_copyrect);
-
- goto done;
- }
- if (!strcmp(p, "ncache_no_moveraise")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ncache_wf_raises);
- goto qry;
- }
- ncache_wf_raises = 0;
- rfbLog("remote_cmd: set -ncache_no_moveraise\n");
- goto done;
- }
- if (!strcmp(p, "noncache_no_moveraise")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, ncache_wf_raises);
- goto qry;
- }
- ncache_wf_raises = 1;
- rfbLog("remote_cmd: disabled -ncache_no_moveraise\n");
- goto done;
- }
- if (!strcmp(p, "ncache_no_dtchange")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ncache_dt_change);
- goto qry;
- }
- ncache_dt_change = 0;
- rfbLog("remote_cmd: set -ncache_no_dt_change\n");
- goto done;
- }
- if (!strcmp(p, "noncache_no_dtchange")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, ncache_dt_change);
- goto qry;
- }
- ncache_dt_change = 1;
- rfbLog("remote_cmd: disabled -ncache_no_dt_change\n");
- goto done;
- }
- if (!strcmp(p, "ncache_no_rootpixmap")) {
- int orig = ncache_xrootpmap;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ncache_xrootpmap);
- goto qry;
- }
- ncache_xrootpmap = 0;
- rfbLog("remote_cmd: set -ncache_no_rootpixmap\n");
- if (orig != ncache_xrootpmap) {
- do_new_fb(1);
- }
- goto done;
- }
- if (!strcmp(p, "noncache_no_rootpixmap")) {
- int orig = ncache_xrootpmap;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, ncache_xrootpmap);
- goto qry;
- }
- ncache_xrootpmap = 1;
- rfbLog("remote_cmd: disabled -ncache_no_rootpixmap\n");
- if (orig != ncache_xrootpmap) {
- do_new_fb(1);
- }
- goto done;
- }
- if (!strcmp(p, "ncache_reset_rootpixmap") || !strcmp(p, "ncrp")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ncache_xrootpmap);
- goto qry;
- }
- if (ncache_xrootpmap) {
- rfbLog("remote_cmd: resetting root pixmap.\n");
- set_ncache_xrootpmap();
- }
- goto done;
- }
- if (!strcmp(p, "ncache_keep_anims")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, ncache_keep_anims);
- goto qry;
- }
- kde_no_animate(0);
- ncache_keep_anims = 1;
- rfbLog("remote_cmd: set -ncache_keep_anims\n");
- goto done;
- }
- if (!strcmp(p, "noncache_keep_anims")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ncache_keep_anims);
- goto qry;
- }
- ncache_keep_anims = 0;
- kde_no_animate(1);
- rfbLog("remote_cmd: disabled -ncache_keep_anims\n");
- goto done;
- }
- if (!strcmp(p, "ncache_old_wm")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, ncache_old_wm);
- goto qry;
- }
- ncache_old_wm = 1;
- rfbLog("remote_cmd: set -ncache_old_wm\n");
- goto done;
- }
- if (!strcmp(p, "noncache_old_wm")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ncache_old_wm);
- goto qry;
- }
- ncache_old_wm = 0;
- rfbLog("remote_cmd: disabled -ncache_old_wm\n");
- goto done;
- }
- if (strstr(p, "ncache_pad") == p) {
- int orig = ncache_pad, n;
- COLON_CHECK("ncache_pad:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, ncache_pad);
- goto qry;
- }
- p += strlen("ncache_pad:");
- n = atoi(p);
-
- rfbLog("remote_cmd: setting ncache_pad %d to: %d\n", orig, n);
- goto done;
- }
- if (!strcmp(p, "ncache")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !!ncache);
- goto qry;
- }
- ncache = ncache0;
- rfbLog("remote_cmd: set ncache %d\n", ncache);
- goto done;
- }
- if (!strcmp(p, "noncache")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ncache);
- goto qry;
- }
- ncache = 0;
- rfbLog("remote_cmd: disabled ncache %d\n", ncache);
- goto done;
- }
- if (strstr(p, "ncache_size") == p) {
- int orig = ncache, n;
- COLON_CHECK("ncache_size:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, ncache);
- goto qry;
- }
- p += strlen("ncache_size:");
- n = atoi(p);
-
- if (n >= 0 && n != ncache) {
- rfbLog("remote_cmd: setting ncache %d to: %d\n", orig, ncache);
- ncache = n;
- do_new_fb(1);
- if (client_count) {
- check_ncache(1,0);
- }
- }
- goto done;
- }
- if (!strcmp(p, "debug_ncache")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, ncdb);
- goto qry;
- }
- ncdb = 1;
- rfbLog("remote_cmd: enabled debug_ncache\n");
- goto done;
- }
- if (!strcmp(p, "nodebug_ncache")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ncdb);
- goto qry;
- }
- ncdb = 0;
- rfbLog("remote_cmd: disabled debug_ncache\n");
- goto done;
- }
-#endif
- if (strstr(p, "wireframe_mode") == p) {
- COLON_CHECK("wireframe_mode:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- wireframe_str ? wireframe_str : WIREFRAME_PARMS);
- goto qry;
- }
- p += strlen("wireframe_mode:");
- if (*p) {
- if (wireframe_str) {
- free(wireframe_str);
- }
- wireframe_str = strdup(p);
- parse_wireframe();
- }
- rfbLog("remote_cmd: enabling -wireframe mode.\n");
- wireframe = 1;
- goto done;
- }
- if (strstr(p, "wireframe:") == p) { /* skip-cmd-list */
- COLON_CHECK("wireframe:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, wireframe);
- goto qry;
- }
- p += strlen("wireframe:");
- if (*p) {
- if (wireframe_str) {
- free(wireframe_str);
- }
- wireframe_str = strdup(p);
- parse_wireframe();
- }
- rfbLog("remote_cmd: enabling -wireframe mode.\n");
- wireframe = 1;
- goto done;
- }
- if (strstr(p, "wf:") == p) { /* skip-cmd-list */
- COLON_CHECK("wf:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, wireframe);
- goto qry;
- }
- p += strlen("wf:");
- if (*p) {
- if (wireframe_str) {
- free(wireframe_str);
- }
- wireframe_str = strdup(p);
- parse_wireframe();
- }
- rfbLog("remote_cmd: enabling -wireframe mode.\n");
- wireframe = 1;
- goto done;
- }
- if (!strcmp(p, "wireframe") || !strcmp(p, "wf")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, wireframe);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -wireframe mode.\n");
- wireframe = 1;
- goto done;
- }
- if (!strcmp(p, "nowireframe") || !strcmp(p, "nowf")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !wireframe);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -nowireframe mode.\n");
- wireframe = 0;
- goto done;
- }
- if (!strcmp(p, "wireframelocal") || !strcmp(p, "wfl")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, wireframe_local);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -wireframelocal mode.\n");
- wireframe_local = 1;
- goto done;
- }
- if (!strcmp(p, "nowireframelocal") || !strcmp(p, "nowfl")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !wireframe_local);
- goto qry;
- }
- rfbLog("remote_cmd: enabling -nowireframelocal mode.\n");
- wireframe_local = 0;
- goto done;
- }
- if (strstr(p, "wirecopyrect") == p) {
- COLON_CHECK("wirecopyrect:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(wireframe_copyrect));
- goto qry;
- }
- p += strlen("wirecopyrect:");
-
- set_wirecopyrect_mode(p);
- rfbLog("remote_cmd: changed -wirecopyrect mode "
- "to: %s\n", NONUL(wireframe_copyrect));
- got_wirecopyrect = 1;
- goto done;
- }
- if (strstr(p, "wcr") == p) {
- COLON_CHECK("wcr:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(wireframe_copyrect));
- goto qry;
- }
- p += strlen("wcr:");
-
- set_wirecopyrect_mode(p);
- rfbLog("remote_cmd: changed -wirecopyrect mode "
- "to: %s\n", NONUL(wireframe_copyrect));
- got_wirecopyrect = 1;
- goto done;
- }
- if (!strcmp(p, "nowirecopyrect") || !strcmp(p, "nowcr")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%s", p,
- NONUL(wireframe_copyrect));
- goto qry;
- }
-
- set_wirecopyrect_mode("never");
- rfbLog("remote_cmd: changed -wirecopyrect mode "
- "to: %s\n", NONUL(wireframe_copyrect));
- goto done;
- }
- if (strstr(p, "scr_area") == p) {
- COLON_CHECK("scr_area:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- scrollcopyrect_min_area);
- goto qry;
- }
- p += strlen("scr_area:");
-
- scrollcopyrect_min_area = atoi(p);
- rfbLog("remote_cmd: changed -scr_area to: %d\n",
- scrollcopyrect_min_area);
- goto done;
- }
- if (strstr(p, "scr_skip") == p) {
- char *s = scroll_skip_str;
- COLON_CHECK("scr_skip:")
- if (!s || *s == '\0') s = scroll_skip_str0;
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s));
- goto qry;
- }
- p += strlen("scr_skip:");
- if (scroll_skip_str) {
- free(scroll_skip_str);
- }
-
- scroll_skip_str = strdup(p);
- rfbLog("remote_cmd: changed -scr_skip to: %s\n",
- scroll_skip_str);
- initialize_scroll_matches();
- goto done;
- }
- if (strstr(p, "scr_inc") == p) {
- char *s = scroll_good_str;
- if (!s || *s == '\0') s = scroll_good_str0;
- COLON_CHECK("scr_inc:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s));
- goto qry;
- }
- p += strlen("scr_inc:");
- if (scroll_good_str) {
- free(scroll_good_str);
- }
-
- scroll_good_str = strdup(p);
- rfbLog("remote_cmd: changed -scr_inc to: %s\n",
- scroll_good_str);
- initialize_scroll_matches();
- goto done;
- }
- if (strstr(p, "scr_keys") == p) {
- COLON_CHECK("scr_keys:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(scroll_key_list_str));
- goto qry;
- }
- p += strlen("scr_keys:");
- if (scroll_key_list_str) {
- free(scroll_key_list_str);
- }
-
- scroll_key_list_str = strdup(p);
- rfbLog("remote_cmd: changed -scr_keys to: %s\n",
- scroll_key_list_str);
- initialize_scroll_keys();
- goto done;
- }
- if (strstr(p, "scr_term") == p) {
- char *s = scroll_term_str;
- if (!s || *s == '\0') s = scroll_term_str0;
- COLON_CHECK("scr_term:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s));
- goto qry;
- }
- p += strlen("scr_term:");
- if (scroll_term_str) {
- free(scroll_term_str);
- }
-
- scroll_term_str = strdup(p);
- rfbLog("remote_cmd: changed -scr_term to: %s\n",
- scroll_term_str);
- initialize_scroll_term();
- goto done;
- }
- if (strstr(p, "scr_keyrepeat") == p) {
- char *s = max_keyrepeat_str;
- if (!s || *s == '\0') s = max_keyrepeat_str0;
- COLON_CHECK("scr_keyrepeat:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s));
- goto qry;
- }
- p += strlen("scr_keyrepeat:");
- if (max_keyrepeat_str) {
- free(max_keyrepeat_str);
- }
-
- max_keyrepeat_str = strdup(p);
- rfbLog("remote_cmd: changed -scr_keyrepeat to: %s\n",
- max_keyrepeat_str);
- initialize_max_keyrepeat();
- goto done;
- }
- if (strstr(p, "scr_parms") == p) {
- COLON_CHECK("scr_parms:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- scroll_copyrect_str ? scroll_copyrect_str
- : SCROLL_COPYRECT_PARMS);
- goto qry;
- }
- p += strlen("scr_parms:");
- if (*p) {
- if (scroll_copyrect_str) {
- free(scroll_copyrect_str);
- }
- set_scrollcopyrect_mode("always");
- scroll_copyrect_str = strdup(p);
- parse_scroll_copyrect();
- }
- rfbLog("remote_cmd: set -scr_parms %s.\n",
- NONUL(scroll_copyrect_str));
- got_scrollcopyrect = 1;
- goto done;
- }
- if (strstr(p, "scrollcopyrect") == p) {
- COLON_CHECK("scrollcopyrect:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(scroll_copyrect));
- goto qry;
- }
- p += strlen("scrollcopyrect:");
-
- set_scrollcopyrect_mode(p);
- rfbLog("remote_cmd: changed -scrollcopyrect mode "
- "to: %s\n", NONUL(scroll_copyrect));
- got_scrollcopyrect = 1;
- goto done;
- }
- if (!strcmp(p, "scr") ||
- strstr(p, "scr:") == p) { /* skip-cmd-list */
- COLON_CHECK("scr:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(scroll_copyrect));
- goto qry;
- }
- p += strlen("scr:");
-
- set_scrollcopyrect_mode(p);
- rfbLog("remote_cmd: changed -scrollcopyrect mode "
- "to: %s\n", NONUL(scroll_copyrect));
- got_scrollcopyrect = 1;
- goto done;
- }
- if (!strcmp(p, "noscrollcopyrect") || !strcmp(p, "noscr")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%s", p,
- NONUL(scroll_copyrect));
- goto qry;
- }
-
- set_scrollcopyrect_mode("never");
- rfbLog("remote_cmd: changed -scrollcopyrect mode "
- "to: %s\n", NONUL(scroll_copyrect));
- goto done;
- }
- if (strstr(p, "fixscreen") == p) {
- COLON_CHECK("fixscreen:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(screen_fixup_str));
- goto qry;
- }
- p += strlen("fixscreen:");
- if (screen_fixup_str) {
- free(screen_fixup_str);
- }
- screen_fixup_str = strdup(p);
- parse_fixscreen();
- rfbLog("remote_cmd: set -fixscreen %s.\n",
- NONUL(screen_fixup_str));
- goto done;
- }
- if (!strcmp(p, "noxrecord")) {
- int orig = noxrecord;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, noxrecord);
- goto qry;
- }
- noxrecord = 1;
- rfbLog("set noxrecord to: %d\n", noxrecord);
- if (orig != noxrecord) {
- shutdown_xrecord();
- }
- goto done;
- }
- if (!strcmp(p, "xrecord")) {
- int orig = noxrecord;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !noxrecord);
- goto qry;
- }
- noxrecord = 0;
- rfbLog("set noxrecord to: %d\n", noxrecord);
- if (orig != noxrecord) {
- initialize_xrecord();
- }
- goto done;
- }
- if (!strcmp(p, "reset_record")) {
- NOTAPP
- if (use_xrecord) {
- rfbLog("resetting RECORD\n");
- check_xrecord_reset(1);
- } else {
- rfbLog("RECORD is disabled, not resetting.\n");
- }
- goto done;
- }
- if (strstr(p, "pointer_mode") == p) {
- int pm;
- COLON_CHECK("pointer_mode:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, pointer_mode);
- goto qry;
- }
- p += strlen("pointer_mode:");
- pm = atoi(p);
- if (pm < 0 || pm > pointer_mode_max) {
- rfbLog("remote_cmd: pointer_mode out of range:"
- " 1-%d: %d\n", pointer_mode_max, pm);
- } else {
- rfbLog("remote_cmd: setting pointer_mode %d\n", pm);
- pointer_mode = pm;
- }
- goto done;
- }
- if (strstr(p, "pm") == p) {
- int pm;
- COLON_CHECK("pm:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, pointer_mode);
- goto qry;
- }
- p += strlen("pm:");
- pm = atoi(p);
- if (pm < 0 || pm > pointer_mode_max) {
- rfbLog("remote_cmd: pointer_mode out of range:"
- " 1-%d: %d\n", pointer_mode_max, pm);
- } else {
- rfbLog("remote_cmd: setting pointer_mode %d\n", pm);
- pointer_mode = pm;
- }
- goto done;
- }
- if (strstr(p, "input_skip") == p) {
- int is;
- COLON_CHECK("input_skip:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, ui_skip);
- goto qry;
- }
- p += strlen("input_skip:");
- is = atoi(p);
- rfbLog("remote_cmd: setting input_skip %d\n", is);
- ui_skip = is;
- goto done;
- }
- if (!strcmp(p, "allinput")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, all_input);
- goto qry;
- }
- all_input = 1;
- rfbLog("enabled allinput\n");
- if (handle_events_eagerly) {
- rfbLog("disabled input_eagerly\n");
- handle_events_eagerly = 0;
- }
- goto done;
- }
- if (!strcmp(p, "noallinput")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !all_input);
- goto qry;
- }
- all_input = 0;
- rfbLog("disabled allinput\n");
- goto done;
- }
- if (!strcmp(p, "input_eagerly")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, handle_events_eagerly);
- goto qry;
- }
- handle_events_eagerly = 1;
- rfbLog("enabled input_eagerly\n");
- if (all_input) {
- rfbLog("disabled allinput\n");
- all_input = 0;
- }
- goto done;
- }
- if (!strcmp(p, "noinput_eagerly")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !handle_events_eagerly);
- goto qry;
- }
- handle_events_eagerly = 0;
- rfbLog("disabled input_eagerly\n");
- goto done;
- }
- if (strstr(p, "input") == p) {
- int doit = 1;
- COLON_CHECK("input:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(allowed_input_str));
- goto qry;
- }
- p += strlen("input:");
- if (allowed_input_str && !strcmp(p, allowed_input_str)) { /* skip-cmd-list */
- doit = 0;
- }
- rfbLog("remote_cmd: setting input %s\n", p);
- if (allowed_input_str) free(allowed_input_str);
- if (*p == '\0') {
- allowed_input_str = NULL;
- } else {
- allowed_input_str = strdup(p);
- }
- if (doit) {
- initialize_allowed_input();
- }
- goto done;
- }
- if (!strcmp(p, "grabkbd")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, grab_kbd);
- goto qry;
- }
- grab_kbd = 1;
- if (grab_always) {
- adjust_grabs(1, 0);
- }
- rfbLog("enabled grab_kbd\n");
- goto done;
- }
- if (!strcmp(p, "nograbkbd")) {
- int orig = grab_kbd;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !grab_kbd);
- goto qry;
- }
- grab_kbd = 0;
- if (orig && dpy) {
-#if !NO_X11
- X_LOCK;
- XUngrabKeyboard(dpy, CurrentTime);
- X_UNLOCK;
-#endif
- }
- rfbLog("disabled grab_kbd\n");
-
- goto done;
- }
- if (!strcmp(p, "grabptr")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, grab_ptr);
- goto qry;
- }
- grab_ptr = 1;
- if (grab_always) {
- adjust_grabs(1, 0);
- }
- rfbLog("enabled grab_ptr\n");
- goto done;
- }
- if (!strcmp(p, "ungrabboth")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, ungrab_both);
- goto qry;
- }
- ungrab_both = 1;
- rfbLog("enabled ungrab_both\n");
- goto done;
- }
- if (!strcmp(p, "noungrabboth")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !ungrab_both);
- goto qry;
- }
- ungrab_both = 0;
- rfbLog("disabled ungrab_both\n");
- goto done;
- }
- if (!strcmp(p, "nograbptr")) {
- int orig = grab_ptr;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !grab_ptr);
- goto qry;
- }
- grab_ptr = 0;
- if (orig && dpy) {
-#if !NO_X11
- X_LOCK;
- XUngrabPointer(dpy, CurrentTime);
- X_UNLOCK;
-#endif
- }
- rfbLog("disabled grab_ptr\n");
- goto done;
- }
- if (!strcmp(p, "grabalways")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, grab_always);
- goto qry;
- }
- grab_ptr = 1;
- grab_kbd = 1;
- grab_always = 1;
- adjust_grabs(1, 0);
- rfbLog("enabled grab_always\n");
- goto done;
- }
- if (!strcmp(p, "nograbalways")) {
- int orig = grab_always;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !grab_always);
- goto qry;
- }
- grab_ptr = 0;
- grab_kbd = 0;
- grab_always = 0;
- if (orig && dpy) {
-#if !NO_X11
- X_LOCK;
- XUngrabKeyboard(dpy, CurrentTime);
- XUngrabPointer(dpy, CurrentTime);
- X_UNLOCK;
-#endif
- }
- adjust_grabs(0, 0);
- rfbLog("disabled grab_always\n");
- goto done;
- }
- if (strstr(p, "grablocal") == p) {
- COLON_CHECK("grablocal:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- grab_local);
- goto qry;
- }
- p += strlen("grablocal:");
-
- grab_local = atoi(p);
- rfbLog("remote_cmd: changed -grablocal to: %d\n",
- grab_local);
- goto done;
- }
- if (strstr(p, "client_input") == p) {
- NOTAPP
- COLON_CHECK("client_input:")
- p += strlen("client_input:");
- set_client_input(p);
- goto done;
- }
- if (strstr(p, "ssltimeout") == p) {
- int is;
- COLON_CHECK("ssltimeout:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- ssl_timeout_secs);
- goto qry;
- }
- p += strlen("ssltimeout:");
- is = atoi(p);
- rfbLog("remote_cmd: setting ssltimeout: %d\n", is);
- ssl_timeout_secs = is;
- goto done;
- }
- if (strstr(p, "speeds") == p) {
- COLON_CHECK("speeds:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(speeds_str));
- goto qry;
- }
- p += strlen("speeds:");
- if (speeds_str) free(speeds_str);
- speeds_str = strdup(p);
-
- rfbLog("remote_cmd: setting -speeds to:\n\t'%s'\n", p);
- initialize_speeds();
- goto done;
- }
- if (strstr(p, "wmdt") == p) {
- COLON_CHECK("wmdt:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(wmdt_str));
- goto qry;
- }
- p += strlen("wmdt:");
- if (wmdt_str) free(wmdt_str);
- wmdt_str = strdup(p);
-
- rfbLog("remote_cmd: setting -wmdt to: %s\n", p);
- goto done;
- }
- if (!strcmp(p, "debug_pointer") || !strcmp(p, "dp")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, debug_pointer);
- goto qry;
- }
- rfbLog("remote_cmd: turning on debug_pointer.\n");
- debug_pointer = 1;
- goto done;
- }
- if (!strcmp(p, "nodebug_pointer") || !strcmp(p, "nodp")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !debug_pointer);
- goto qry;
- }
- rfbLog("remote_cmd: turning off debug_pointer.\n");
- debug_pointer = 0;
- goto done;
- }
- if (!strcmp(p, "debug_keyboard") || !strcmp(p, "dk")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, debug_keyboard);
- goto qry;
- }
- rfbLog("remote_cmd: turning on debug_keyboard.\n");
- debug_keyboard = 1;
- goto done;
- }
- if (!strcmp(p, "nodebug_keyboard") || !strcmp(p, "nodk")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !debug_keyboard);
- goto qry;
- }
- rfbLog("remote_cmd: turning off debug_keyboard.\n");
- debug_keyboard = 0;
- goto done;
- }
- if (strstr(p, "keycode") == p) {
- int kc, down = -1;
- char *c;
- NOTAPP
- COLON_CHECK("keycode:")
- p += strlen("keycode:");
- kc = atoi(p);
- if (kc < 0) kc = 0;
- kc = kc % 256;
- c = strchr(p, ',');
- if (c) down = atoi(c+1);
- rfbLog("remote_cmd: insert keycode %d down=%d\n", kc, down);
-
- if (macosx_console) {
-#ifdef MACOSX
- if (down == -1) {
- macosxCG_keycode_inject(1, kc);
- usleep(50*1000);
- macosxCG_keycode_inject(0, kc);
- } else {
- macosxCG_keycode_inject(down, kc);
- }
-#endif
- } else {
- X_LOCK;
- if (down == -1) {
- XTestFakeKeyEvent_wr(dpy, kc, 1, CurrentTime);
- usleep(50*1000);
- XTestFakeKeyEvent_wr(dpy, kc, 0, CurrentTime);
- } else {
- XTestFakeKeyEvent_wr(dpy, kc, down, CurrentTime);
- }
- XFlush_wr(dpy);
- X_UNLOCK;
- }
- goto done;
- }
- if (strstr(p, "keysym") == p) {
- int down = -1;
- unsigned int in;
- KeySym ks;
- char *c, *str;
- NOTAPP
- COLON_CHECK("keysym:")
- p += strlen("keysym:");
-
- c = strchr(p, ',');
- if (c) {
- down = atoi(c+1);
- *c = '\0';
- }
-
- if (sscanf(p, "0x%x", &in) == 1) {
- ks = (KeySym) in;
- } else if (sscanf(p, "%u", &in) == 1) {
- ks = (KeySym) in;
- } else if ((ks = XStringToKeysym(p)) != NoSymbol) {
- ;
- } else {
- rfbLog("remote_cmd: bad keysym: %s\n", p);
- goto done;
- }
- str = XKeysymToString(ks);
- str = str ? str : "NoSymbol";
- rfbLog("remote_cmd: insert keysym %s 0x%x '%s' down=%d\n", p, ks, str, down);
- if (down == -1) {
- keyboard(1, ks, NULL);
- usleep(50*1000);
- keyboard(0, ks, NULL);
- } else {
- keyboard(down, ks, NULL);
- }
- goto done;
- }
- if (strstr(p, "ptr") == p) {
- int x, y, m = 0;
- NOTAPP
- COLON_CHECK("ptr:")
- p += strlen("ptr:");
- rfbLog("remote_cmd: insert pointer event: %s\n", p);
- if (sscanf(p, "%d,%d,%d", &x, &y, &m) == 3) {
- pointer_event(m, x, y, NULL);
- } else if (sscanf(p, "%d,%d", &x, &y) == 2) {
- pointer_event(m, x, y, NULL);
- } else {
- rfbLog("remote_cmd: bad ptr:x,y,mask\n");
- }
-
- goto done;
- }
- if (strstr(p, "fakebuttonevent") == p) {
- int mb, down = 0;
- NOTAPP
- COLON_CHECK("fakebuttonevent:")
- p += strlen("fakebuttonevent:");
- rfbLog("remote_cmd: insert fakebuttonevent: %s\n", p);
- if (sscanf(p, "%d,%d", &mb, &down) == 2) {
- X_LOCK;
- rfbLog("remote_cmd: XTestFakeButtonEvent(mb=%d, down=%d)\n", mb, down);
- XTestFakeButtonEvent_wr(dpy, mb, down ? True : False, CurrentTime);
- XFlush_wr(dpy);
- X_UNLOCK;
- }
-
- goto done;
- }
- if (strstr(p, "sleep") == p) {
- NOTAPP
- COLON_CHECK("sleep:")
- p += strlen("sleep:");
- rfbLog("remote_cmd: sleeping: %s\n", p);
- usleep((int) (1.0e+6 * atof(p)));
- rfbLog("remote_cmd: done sleeping.\n");
- goto done;
- }
- if (strstr(p, "get_xprop") == p) {
- char *res;
- unsigned long id;
- Window win = None; /* None implies root in get_xprop() */
-
- /* note we force query and assume the colon is there. */
- query = 1;
- if (strstr(p, "get_xprop:") != p) { /* skip-cmd-list */
- snprintf(buf, bufn, "ans=%s:N/A", p);
- goto qry;
- }
- p += strlen("get_xprop:");
-
- if (strstr(p, "id=") == p) { /* skip-cmd-list */
- p += strlen("id=");
- if (scan_hexdec(p, &id)) {
- win = (Window) id;
- }
- if (strchr(p, ':')) {
- p = strchr(p, ':') + 1;
- }
- }
-
- res = get_xprop(p, win);
- if (res == NULL) {
- res = strdup("NULL");
- }
- snprintf(buf, bufn, "ans=get_xprop:%s:%s", p, res);
- free(res);
-
- goto qry;
- }
- if (strstr(p, "set_xprop") == p) {
- char *q;
- int rc = -2;
- unsigned long id;
- Window win = None; /* None implies root in set_xprop() */
-
- /* note we force query and assume the colon is there. */
- query = 1;
- if (strstr(p, "set_xprop:") != p) { /* skip-cmd-list */
- snprintf(buf, bufn, "ans=%s:N/A", p);
- goto qry;
- }
- p += strlen("set_xprop:");
-
- if (strstr(p, "id=") == p) { /* skip-cmd-list */
- p += strlen("id=");
- if (scan_hexdec(p, &id)) {
- win = (Window) id;
- }
- if (strchr(p, ':')) {
- p = strchr(p, ':') + 1;
- }
- }
-
- q = strchr(p, ':');
- if (q) {
- *q = '\0';
- rc = set_xprop(p, win, q+1);
- *q = ':';
- }
- snprintf(buf, bufn, "ans=set_xprop:%s:%d", p, rc);
-
- goto qry;
- }
- if (strstr(p, "wininfo") == p) {
- char *res, *t = "";
- unsigned long id;
- Window win = None;
- int show_children = 0;
-
- /* note we force query and assume the colon is there. */
- query = 1;
- if (strstr(p, "wininfo:") != p) { /* skip-cmd-list */
- snprintf(buf, bufn, "ans=%s:N/A", p);
- goto qry;
- }
- p += strlen("wininfo:");
-
- if (p[0] == '+') {
- show_children = 1;
- t = "+";
- p++;
- }
- if (!strcmp(p, "root")) { /* skip-cmd-list */
- win = rootwin;
- } else if (scan_hexdec(p, &id)) {
- win = (Window) id;
- }
-
- res = wininfo(win, show_children);
- if (res == NULL) {
- res = strdup("NULL");
- }
- snprintf(buf, bufn, "ans=wininfo:%s%s:%s", t, p, res);
- free(res);
-
- goto qry;
- }
- if (strstr(p, "bcx_xattach") == p) {
- char *res;
- int pg_init = -1, kg_init = -1;
- int try = 0, max_tries = 4;
-
- /* note we force query and assume the colon is there. */
- query = 1;
- if (strstr(p, "bcx_xattach:") != p) { /* skip-cmd-list */
- snprintf(buf, bufn, "ans=%s:N/A", p);
- goto qry;
- }
- p += strlen("bcx_xattach:");
-
- if (strstr(p, "retry=")) { /* skip-cmd-list */
- int n;
- char *q = strstr(p, "retry="); /* skip-cmd-list */
- if (sscanf(q, "retry=%d", &n) == 1) {
- if (n < 0) n = 0;
- max_tries = 1 + n;
- }
- }
-
- try_again:
-
- res = bcx_xattach(p, &pg_init, &kg_init);
- try++;
- if (res == NULL) {
- res = strdup("NULL");
- } else if (strstr(res, "GRAB_FAIL_INIT")) {
- rfbLog("bcx_xattach: failed grab check for '%s': %s. Final state OK, not Retrying.\n", p, res);
- } else if (strstr(res, "GRAB_FAIL") && try < max_tries) {
- rfbLog("bcx_xattach: failed grab check for '%s': %s. Retrying[%d]...\n", p, res, try);
- free(res);
- pointer_event(0, dpy_x/2 + try, dpy_y/2 + try, NULL);
-#if !NO_X11
- X_LOCK;
- XFlush_wr(dpy);
- if (dpy) {
- if (try == 2) {
- XSync(dpy, False);
- } else if (try == 3) {
- XSync(dpy, True);
- }
- }
- X_UNLOCK;
-#endif
- if (try == 1) {
- usleep(250*1000);
- } else if (try <= 4) {
- usleep(try*400*1000);
- } else {
- usleep(4*500*1000);
- }
- goto try_again;
- }
-
- snprintf(buf, bufn, "ans=bcx_xattach:%s:%s", p, res);
- free(res);
-
- goto qry;
- }
- if (strstr(p, "deferupdate") == p) {
- int d;
- COLON_CHECK("deferupdate:")
- if (query) {
- if (!screen) {
- d = defer_update;
- } else {
- d = screen->deferUpdateTime;
- }
- snprintf(buf, bufn, "ans=%s%s%d", p, co, d);
- goto qry;
- }
- p += strlen("deferupdate:");
- d = atoi(p);
- if (d < 0) d = 0;
- rfbLog("remote_cmd: setting defer to %d ms.\n", d);
- defer_update = d;
- /* mutex */
- screen->deferUpdateTime = d;
- got_defer = 1;
- goto done;
- }
- if (strstr(p, "defer") == p) {
- int d;
- COLON_CHECK("defer:")
- if (query) {
- if (!screen) {
- d = defer_update;
- } else {
- d = screen->deferUpdateTime;
- }
- snprintf(buf, bufn, "ans=%s%s%d", p, co, d);
- goto qry;
- }
- p += strlen("defer:");
- d = atoi(p);
- if (d < 0) d = 0;
- rfbLog("remote_cmd: setting defer to %d ms.\n", d);
- defer_update = d;
- /* mutex */
- screen->deferUpdateTime = d;
- got_defer = 1;
- goto done;
- }
- if (strstr(p, "setdefer") == p) {
- COLON_CHECK("setdefer:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, set_defer);
- goto qry;
- }
- p += strlen("setdefer:");
- set_defer = atoi(p);
- rfbLog("remote_cmd: setting set_defer to %d\n", set_defer);
- goto done;
- }
- if (strstr(p, "extra_fbur") == p) {
- COLON_CHECK("extra_fbur:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, extra_fbur);
- goto qry;
- }
- p += strlen("extra_fbur:");
- extra_fbur = atoi(p);
- rfbLog("remote_cmd: setting extra_fbur to %d\n", extra_fbur);
- goto done;
- }
- if (strstr(p, "wait_ui") == p) {
- double w;
- COLON_CHECK("wait_ui:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%.2f", p, co, wait_ui);
- goto qry;
- }
- p += strlen("wait_ui:");
- w = atof(p);
- if (w <= 0) w = 1.0;
- rfbLog("remote_cmd: setting wait_ui factor %.2f -> %.2f\n",
- wait_ui, w);
- wait_ui = w;
- goto done;
- }
- if (!strcmp(p, "wait_bog")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, wait_bog);
- goto qry;
- }
- wait_bog = 1;
- rfbLog("remote_cmd: setting wait_bog to %d\n", wait_bog);
- goto done;
- }
- if (!strcmp(p, "nowait_bog")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !wait_bog);
- goto qry;
- }
- wait_bog = 0;
- rfbLog("remote_cmd: setting wait_bog to %d\n", wait_bog);
- goto done;
- }
- if (strstr(p, "slow_fb") == p) {
- double w;
- COLON_CHECK("slow_fb:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%.2f", p, co, slow_fb);
- goto qry;
- }
- p += strlen("slow_fb:");
- w = atof(p);
- if (w <= 0) w = 0.0;
- rfbLog("remote_cmd: setting slow_fb factor %.2f -> %.2f\n",
- slow_fb, w);
- slow_fb = w;
- goto done;
- }
- if (strstr(p, "xrefresh") == p) {
- double w;
- COLON_CHECK("xrefresh:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%.2f", p, co, xrefresh);
- goto qry;
- }
- p += strlen("xrefresh:");
- w = atof(p);
- if (w <= 0) w = 0.0;
- rfbLog("remote_cmd: setting xrefresh delay %.2f -> %.2f\n",
- xrefresh, w);
- xrefresh = w;
- goto done;
- }
- if (strstr(p, "wait") == p) {
- int w;
- COLON_CHECK("wait:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, waitms);
- goto qry;
- }
- p += strlen("wait:");
- w = atoi(p);
- if (w < 0) w = 0;
- rfbLog("remote_cmd: setting wait %d -> %d ms.\n", waitms, w);
- waitms = w;
- goto done;
- }
- if (strstr(p, "readtimeout") == p) {
- int w, orig = rfbMaxClientWait;
- COLON_CHECK("readtimeout:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- rfbMaxClientWait/1000);
- goto qry;
- }
- p += strlen("readtimeout:");
- w = atoi(p) * 1000;
- if (w <= 0) w = 0;
- rfbLog("remote_cmd: setting rfbMaxClientWait %d -> "
- "%d msec.\n", orig, w);
- rfbMaxClientWait = w;
- goto done;
- }
- if (!strcmp(p, "nap")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, take_naps);
- goto qry;
- }
- rfbLog("remote_cmd: turning on nap mode.\n");
- take_naps = 1;
- goto done;
- }
- if (!strcmp(p, "nonap")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !take_naps);
- goto qry;
- }
- rfbLog("remote_cmd: turning off nap mode.\n");
- take_naps = 0;
- goto done;
- }
- if (strstr(p, "sb") == p) {
- int w;
- COLON_CHECK("sb:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, screen_blank);
- goto qry;
- }
- p += strlen("sb:");
- w = atoi(p);
- if (w < 0) w = 0;
- rfbLog("remote_cmd: setting screen_blank %d -> %d sec.\n",
- screen_blank, w);
- screen_blank = w;
- goto done;
- }
- if (strstr(p, "screen_blank") == p) {
- int w;
- COLON_CHECK("screen_blank:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, screen_blank);
- goto qry;
- }
- p += strlen("screen_blank:");
- w = atoi(p);
- if (w < 0) w = 0;
- rfbLog("remote_cmd: setting screen_blank %d -> %d sec.\n",
- screen_blank, w);
- screen_blank = w;
- goto done;
- }
- if (!strcmp(p, "fbpm")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !watch_fbpm);
- goto qry;
- }
- rfbLog("remote_cmd: turning off -nofbpm mode.\n");
- watch_fbpm = 0;
- goto done;
- }
- if (!strcmp(p, "nofbpm")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, watch_fbpm);
- goto qry;
- }
- rfbLog("remote_cmd: turning on -nofbpm mode.\n");
- watch_fbpm = 1;
- goto done;
- }
- if (!strcmp(p, "dpms")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !watch_dpms);
- goto qry;
- }
- rfbLog("remote_cmd: turning off -nodpms mode.\n");
- watch_dpms = 0;
- goto done;
- }
- if (!strcmp(p, "nodpms")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, watch_dpms);
- goto qry;
- }
- rfbLog("remote_cmd: turning on -nodpms mode.\n");
- watch_dpms = 1;
- goto done;
- }
- if (!strcmp(p, "clientdpms")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, client_dpms);
- goto qry;
- }
- rfbLog("remote_cmd: turning on -clientdpms mode.\n");
- client_dpms = 1;
- goto done;
- }
- if (!strcmp(p, "noclientdpms")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !client_dpms);
- goto qry;
- }
- rfbLog("remote_cmd: turning off -clientdpms mode.\n");
- client_dpms = 0;
- goto done;
- }
- if (!strcmp(p, "forcedpms")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, force_dpms);
- goto qry;
- }
- rfbLog("remote_cmd: turning on -forcedpms mode.\n");
- force_dpms = 1;
- goto done;
- }
- if (!strcmp(p, "noforcedpms")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !force_dpms);
- goto qry;
- }
- rfbLog("remote_cmd: turning off -forcedpms mode.\n");
- force_dpms = 0;
- goto done;
- }
- if (!strcmp(p, "noserverdpms")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, no_ultra_dpms);
- goto qry;
- }
- rfbLog("remote_cmd: turning on -noserverdpms mode.\n");
- no_ultra_dpms = 1;
- goto done;
- }
- if (!strcmp(p, "serverdpms")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !no_ultra_dpms);
- goto qry;
- }
- rfbLog("remote_cmd: turning off -noserverdpms mode.\n");
- no_ultra_dpms = 0;
- goto done;
- }
- if (!strcmp(p, "noultraext")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, no_ultra_ext);
- goto qry;
- }
- rfbLog("remote_cmd: turning on -noultraext mode.\n");
- no_ultra_ext = 1;
- goto done;
- }
- if (!strcmp(p, "ultraext")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !no_ultra_ext);
- goto qry;
- }
- rfbLog("remote_cmd: turning off -noultraext mode.\n");
- no_ultra_ext = 0;
- goto done;
- }
- if (!strcmp(p, "chatwindow")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, chat_window);
- goto qry;
- }
- rfbLog("remote_cmd: enabling the local chat window.\n");
- chat_window = 1;
- goto done;
- }
- if (!strcmp(p, "nochatwindow")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !chat_window);
- goto qry;
- }
- rfbLog("remote_cmd: disabling the local chat window.\n");
- chat_window = 0;
- goto done;
- }
- if (!strcmp(p, "chaton")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, (chat_window_client != NULL));
- goto qry;
- }
- rfbLog("remote_cmd: turning local chat window on.\n");
- chat_window = 1;
- set_text_chat(NULL, rfbTextChatOpen, "");
- goto done;
- }
- if (!strcmp(p, "chatoff")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, (chat_window_client == NULL));
- goto qry;
- }
- rfbLog("remote_cmd: turning local chat window off.\n");
- set_text_chat(NULL, rfbTextChatClose, "");
- set_text_chat(NULL, rfbTextChatFinished, "");
- goto done;
- }
- if (strstr(p, "fs") == p) {
- COLON_CHECK("fs:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%f", p, co, fs_frac);
- goto qry;
- }
- p += strlen("fs:");
- fs_frac = atof(p);
- rfbLog("remote_cmd: setting -fs frac to %f\n", fs_frac);
- goto done;
- }
- if (strstr(p, "gaps") == p) {
- int g;
- COLON_CHECK("gaps:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, gaps_fill);
- goto qry;
- }
- p += strlen("gaps:");
- g = atoi(p);
- if (g < 0) g = 0;
- rfbLog("remote_cmd: setting gaps_fill %d -> %d.\n",
- gaps_fill, g);
- gaps_fill = g;
- goto done;
- }
- if (strstr(p, "grow") == p) {
- int g;
- COLON_CHECK("grow:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, grow_fill);
- goto qry;
- }
- p += strlen("grow:");
- g = atoi(p);
- if (g < 0) g = 0;
- rfbLog("remote_cmd: setting grow_fill %d -> %d.\n",
- grow_fill, g);
- grow_fill = g;
- goto done;
- }
- if (strstr(p, "fuzz") == p) {
- int f;
- COLON_CHECK("fuzz:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, tile_fuzz);
- goto qry;
- }
- p += strlen("fuzz:");
- f = atoi(p);
- if (f < 0) f = 0;
- rfbLog("remote_cmd: setting tile_fuzz %d -> %d.\n",
- tile_fuzz, f);
- grow_fill = f;
- goto done;
- }
- if (!strcmp(p, "snapfb")) {
- int orig = use_snapfb;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, use_snapfb);
- goto qry;
- }
- rfbLog("remote_cmd: turning on snapfb mode.\n");
- use_snapfb = 1;
- if (orig != use_snapfb) {
- do_new_fb(1);
- }
- goto done;
- }
- if (!strcmp(p, "nosnapfb")) {
- int orig = use_snapfb;
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !use_snapfb);
- goto qry;
- }
- rfbLog("remote_cmd: turning off snapfb mode.\n");
- use_snapfb = 0;
- if (orig != use_snapfb) {
- do_new_fb(1);
- }
-
- goto done;
- }
- if (strstr(p, "rawfb") == p) {
- COLON_CHECK("rawfb:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(raw_fb_str));
- goto qry;
- }
- p += strlen("rawfb:");
- if (raw_fb_str) free(raw_fb_str);
- raw_fb_str = strdup(p);
- if (safe_remote_only && strstr(p, "setup:") == p) { /* skip-cmd-list */
- /* n.b. we still allow filename, shm, of rawfb */
- fprintf(stderr, "unsafe rawfb setup: %s\n", p);
- exit(1);
- }
-
- rfbLog("remote_cmd: setting -rawfb to:\n\t'%s'\n", p);
-
- if (*raw_fb_str == '\0') {
- free(raw_fb_str);
- raw_fb_str = NULL;
- if (raw_fb_mmap) {
- munmap(raw_fb_addr, raw_fb_mmap);
- }
- if (raw_fb_fd >= 0) {
- close(raw_fb_fd);
- }
- raw_fb_fd = -1;
- raw_fb = NULL;
- raw_fb_addr = NULL;
- raw_fb_offset = 0;
- raw_fb_shm = 0;
- raw_fb_mmap = 0;
- raw_fb_seek = 0;
- rfbLog("restoring per-rawfb settings...\n");
- set_raw_fb_params(1);
- }
- rfbLog("hang on tight, here we go...\n");
- raw_fb_back_to_X = 1;
- do_new_fb(1);
- raw_fb_back_to_X = 0;
- goto done;
- }
- if (strstr(p, "uinput_accel") == p) {
- COLON_CHECK("uinput_accel:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(get_uinput_accel()));
- goto qry;
- }
- p += strlen("uinput_accel:");
- rfbLog("set_uinput_accel: %s\n", p);
- set_uinput_accel(p);
- goto done;
- }
- if (strstr(p, "uinput_thresh") == p) {
- COLON_CHECK("uinput_thresh:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(get_uinput_thresh()));
- goto qry;
- }
- p += strlen("uinput_thresh:");
- rfbLog("set_uinput_thresh: %s\n", p);
- set_uinput_thresh(p);
- goto done;
- }
- if (strstr(p, "uinput_reset") == p) {
- COLON_CHECK("uinput_reset:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- get_uinput_reset());
- goto qry;
- }
- p += strlen("uinput_reset:");
- rfbLog("set_uinput_reset: %s\n", p);
- set_uinput_reset(atoi(p));
- goto done;
- }
- if (strstr(p, "uinput_always") == p) {
- COLON_CHECK("uinput_always:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- get_uinput_always());
- goto qry;
- }
- p += strlen("uinput_always:");
- rfbLog("set_uinput_always: %s\n", p);
- set_uinput_always(atoi(p));
- goto done;
- }
- if (strstr(p, "progressive") == p) {
- int f;
- COLON_CHECK("progressive:")
- if (query) {
- if (!screen) {
- f = 0;
- } else {
- f = screen->progressiveSliceHeight;
- }
- snprintf(buf, bufn, "ans=%s%s%d", p, co, f);
- goto qry;
- }
- p += strlen("progressive:");
- f = atoi(p);
- if (f < 0) f = 0;
- rfbLog("remote_cmd: setting progressive %d -> %d.\n",
- screen->progressiveSliceHeight, f);
- /* mutex */
- screen->progressiveSliceHeight = f;
- goto done;
- }
- if (strstr(p, "rfbport") == p) {
- int rp, orig = screen ? screen->port : 5900;
- COLON_CHECK("rfbport:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, orig);
- goto qry;
- }
- p += strlen("rfbport:");
- rp = atoi(p);
- reset_rfbport(orig, rp);
- goto done;
- }
- if (!strcmp(p, "http")) {
- if (query) {
- int ls = screen ? screen->httpListenSock : -1;
- snprintf(buf, bufn, "ans=%s:%d", p, (ls > -1));
- goto qry;
- }
- if (screen->httpListenSock > -1 || ipv6_http_fd > -1) {
- rfbLog("already listening for http connections.\n");
- } else {
- rfbLog("turning on listening for http connections.\n");
- if (check_httpdir()) {
- http_connections(1);
- }
- }
- goto done;
- }
- if (!strcmp(p, "nohttp")) {
- if (query) {
- int ls = screen ? screen->httpListenSock : -1;
- snprintf(buf, bufn, "ans=%s:%d", p, !(ls > -1));
- goto qry;
- }
- if (screen->httpListenSock < 0 && ipv6_http_fd < 0) {
- rfbLog("already not listening for http connections.\n");
- } else {
- rfbLog("turning off listening for http connections.\n");
- if (check_httpdir()) {
- http_connections(0);
- }
- }
- goto done;
- }
- if (strstr(p, "httpport") == p) {
- int hp, orig = screen ? screen->httpPort : 0;
- COLON_CHECK("httpport:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, orig);
- goto qry;
- }
- p += strlen("httpport:");
- hp = atoi(p);
- reset_httpport(orig, hp);
- goto done;
- }
- if (strstr(p, "httpdir") == p) {
- COLON_CHECK("httpdir:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(http_dir));
- goto qry;
- }
- p += strlen("httpdir:");
- if (http_dir && !strcmp(http_dir, p)) {
- rfbLog("no change in httpdir: %s\n", http_dir);
- } else {
- if (http_dir) {
- free(http_dir);
- }
- http_dir = strdup(p);
- http_connections(0);
- if (*p != '\0') {
- http_connections(1);
- }
- }
- goto done;
- }
- if (!strcmp(p, "enablehttpproxy")) {
- if (query) {
- int ht = screen ? screen->httpEnableProxyConnect : 0;
- snprintf(buf, bufn, "ans=%s:%d", p, ht != 0);
- goto qry;
- }
- rfbLog("turning on enablehttpproxy.\n");
- /* mutex */
- screen->httpEnableProxyConnect = 1;
- goto done;
- }
- if (!strcmp(p, "noenablehttpproxy")) {
- if (query) {
- int ht = screen ? screen->httpEnableProxyConnect : 0;
- snprintf(buf, bufn, "ans=%s:%d", p, ht == 0);
- goto qry;
- }
- rfbLog("turning off enablehttpproxy.\n");
- screen->httpEnableProxyConnect = 0;
- goto done;
- }
- if (!strcmp(p, "alwaysshared")) {
- if (query) {
- int t = screen ? screen->alwaysShared : 0;
- snprintf(buf, bufn, "ans=%s:%d", p, t != 0);
- goto qry;
- }
- rfbLog("turning on alwaysshared.\n");
- screen->alwaysShared = 1;
- goto done;
- }
- if (!strcmp(p, "noalwaysshared")) {
- if (query) {
- int t = screen ? screen->alwaysShared : 0;
- snprintf(buf, bufn, "ans=%s:%d", p, t == 0);
- goto qry;
- }
- rfbLog("turning off alwaysshared.\n");
- screen->alwaysShared = 0;
- goto done;
- }
- if (!strcmp(p, "nevershared")) {
- if (query) {
- int t = screen ? screen->neverShared : 1;
- snprintf(buf, bufn, "ans=%s:%d", p, t != 0);
- goto qry;
- }
- rfbLog("turning on nevershared.\n");
- screen->neverShared = 1;
- goto done;
- }
- if (!strcmp(p, "noalwaysshared")) {
- if (query) {
- int t = screen ? screen->neverShared : 1;
- snprintf(buf, bufn, "ans=%s:%d", p, t == 0);
- goto qry;
- }
- rfbLog("turning off nevershared.\n");
- screen->neverShared = 0;
- goto done;
- }
- if (!strcmp(p, "dontdisconnect")) {
- if (query) {
- int t = screen ? screen->dontDisconnect : 1;
- snprintf(buf, bufn, "ans=%s:%d", p, t != 0);
- goto qry;
- }
- rfbLog("turning on dontdisconnect.\n");
- screen->dontDisconnect = 1;
- goto done;
- }
- if (!strcmp(p, "nodontdisconnect")) {
- if (query) {
- int t = screen ? screen->dontDisconnect : 1;
- snprintf(buf, bufn, "ans=%s:%d", p, t == 0);
- goto qry;
- }
- rfbLog("turning off dontdisconnect.\n");
- screen->dontDisconnect = 0;
- goto done;
- }
- if (!strcmp(p, "desktop") ||
- strstr(p, "desktop:") == p) { /* skip-cmd-list */
- COLON_CHECK("desktop:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%s", p, co,
- NONUL(rfb_desktop_name));
- goto qry;
- }
- p += strlen("desktop:");
- if (rfb_desktop_name) {
- free(rfb_desktop_name);
- }
- rfb_desktop_name = strdup(p);
- /* mutex */
- screen->desktopName = rfb_desktop_name;
- rfbLog("remote_cmd: setting desktop name to %s\n",
- rfb_desktop_name);
- goto done;
- }
- if (!strcmp(p, "debug_xevents")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, debug_xevents);
- goto qry;
- }
- debug_xevents = 1;
- rfbLog("set debug_xevents to: %d\n", debug_xevents);
- goto done;
- }
- if (!strcmp(p, "nodebug_xevents")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !debug_xevents);
- goto qry;
- }
- debug_xevents = 0;
- rfbLog("set debug_xevents to: %d\n", debug_xevents);
- goto done;
- }
- if (strstr(p, "debug_xevents") == p) {
- COLON_CHECK("debug_xevents:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_xevents);
- goto qry;
- }
- p += strlen("debug_xevents:");
- debug_xevents = atoi(p);
- rfbLog("set debug_xevents to: %d\n", debug_xevents);
- goto done;
- }
- if (!strcmp(p, "debug_xdamage")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, debug_xdamage);
- goto qry;
- }
- debug_xdamage = 1;
- rfbLog("set debug_xdamage to: %d\n", debug_xdamage);
- goto done;
- }
- if (!strcmp(p, "nodebug_xdamage")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !debug_xdamage);
- goto qry;
- }
- debug_xdamage = 0;
- rfbLog("set debug_xdamage to: %d\n", debug_xdamage);
- goto done;
- }
- if (strstr(p, "debug_xdamage") == p) {
- COLON_CHECK("debug_xdamage:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_xdamage);
- goto qry;
- }
- p += strlen("debug_xdamage:");
- debug_xdamage = atoi(p);
- rfbLog("set debug_xdamage to: %d\n", debug_xdamage);
- goto done;
- }
- if (!strcmp(p, "debug_wireframe")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, debug_wireframe);
- goto qry;
- }
- debug_wireframe = 1;
- rfbLog("set debug_wireframe to: %d\n", debug_wireframe);
- goto done;
- }
- if (!strcmp(p, "nodebug_wireframe")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !debug_wireframe);
- goto qry;
- }
- debug_wireframe = 0;
- rfbLog("set debug_wireframe to: %d\n", debug_wireframe);
- goto done;
- }
- if (strstr(p, "debug_wireframe") == p) {
- COLON_CHECK("debug_wireframe:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- debug_wireframe);
- goto qry;
- }
- p += strlen("debug_wireframe:");
- debug_wireframe = atoi(p);
- rfbLog("set debug_wireframe to: %d\n", debug_wireframe);
- goto done;
- }
- if (!strcmp(p, "debug_scroll")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, debug_scroll);
- goto qry;
- }
- debug_scroll = 1;
- rfbLog("set debug_scroll to: %d\n", debug_scroll);
- goto done;
- }
- if (!strcmp(p, "nodebug_scroll")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !debug_scroll);
- goto qry;
- }
- debug_scroll = 0;
- rfbLog("set debug_scroll to: %d\n", debug_scroll);
- goto done;
- }
- if (strstr(p, "debug_scroll") == p) {
- COLON_CHECK("debug_scroll:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- debug_scroll);
- goto qry;
- }
- p += strlen("debug_scroll:");
- debug_scroll = atoi(p);
- rfbLog("set debug_scroll to: %d\n", debug_scroll);
- goto done;
- }
- if (!strcmp(p, "debug_tiles") || !strcmp(p, "dbt")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, debug_tiles);
- goto qry;
- }
- debug_tiles = 1;
- rfbLog("set debug_tiles to: %d\n", debug_tiles);
- goto done;
- }
- if (!strcmp(p, "nodebug_tiles") || !strcmp(p, "nodbt")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !debug_tiles);
- goto qry;
- }
- debug_tiles = 0;
- rfbLog("set debug_tiles to: %d\n", debug_tiles);
- goto done;
- }
- if (strstr(p, "debug_tiles") == p) {
- COLON_CHECK("debug_tiles:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co,
- debug_tiles);
- goto qry;
- }
- p += strlen("debug_tiles:");
- debug_tiles = atoi(p);
- rfbLog("set debug_tiles to: %d\n", debug_tiles);
- goto done;
- }
- if (!strcmp(p, "debug_grabs")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, debug_grabs);
- goto qry;
- }
- debug_grabs = 1;
- rfbLog("set debug_grabs to: %d\n", debug_grabs);
- goto done;
- }
- if (!strcmp(p, "nodebug_grabs")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !debug_grabs);
- goto qry;
- }
- debug_grabs = 0;
- rfbLog("set debug_grabs to: %d\n", debug_grabs);
- goto done;
- }
- if (!strcmp(p, "debug_sel")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, debug_sel);
- goto qry;
- }
- debug_sel = 1;
- rfbLog("set debug_sel to: %d\n", debug_sel);
- goto done;
- }
- if (!strcmp(p, "nodebug_sel")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !debug_sel);
- goto qry;
- }
- debug_sel = 0;
- rfbLog("set debug_sel to: %d\n", debug_sel);
- goto done;
- }
- if (!strcmp(p, "dbg")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, crash_debug);
- goto qry;
- }
- crash_debug = 1;
- rfbLog("set crash_debug to: %d\n", crash_debug);
- goto done;
- }
- if (!strcmp(p, "nodbg")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !crash_debug);
- goto qry;
- }
- crash_debug = 0;
- rfbLog("set crash_debug to: %d\n", crash_debug);
- goto done;
- }
- if (!strcmp(p, "macnosaver")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, macosx_noscreensaver); goto qry;
- }
- rfbLog("remote_cmd: turn on macnosaver.\n");
- macosx_noscreensaver = 1;
- goto done;
- }
- if (!strcmp(p, "macsaver") || !strcmp(p, "nomacnosaver")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !macosx_noscreensaver); goto qry;
- }
- rfbLog("remote_cmd: turn off macnosaver.\n");
- macosx_noscreensaver = 0;
- goto done;
- }
- if (!strcmp(p, "macnowait")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !macosx_wait_for_switch); goto qry;
- }
- rfbLog("remote_cmd: disable macosx_wait_for_switch.\n");
- macosx_wait_for_switch = 0;
- goto done;
- }
- if (!strcmp(p, "macwait") || !strcmp(p, "nomacnowait")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, macosx_wait_for_switch); goto qry;
- }
- rfbLog("remote_cmd: enable macosx_wait_for_switch.\n");
- macosx_wait_for_switch = 1;
- goto done;
- }
- if (strstr(p, "macwheel") == p) {
- COLON_CHECK("macwheel:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, macosx_mouse_wheel_speed);
- goto qry;
- }
- p += strlen("macwheel:");
- macosx_mouse_wheel_speed = atoi(p);
- rfbLog("set macosx_mouse_wheel_speed to: %d\n", macosx_mouse_wheel_speed);
- goto done;
- }
- if (!strcmp(p, "macnoswap")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !macosx_swap23); goto qry;
- }
- rfbLog("remote_cmd: disable macosx_swap23.\n");
- macosx_swap23 = 0;
- goto done;
- }
- if (!strcmp(p, "macswap") || !strcmp(p, "nomacnoswap")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, macosx_swap23); goto qry;
- }
- rfbLog("remote_cmd: enable macosx_swap23.\n");
- macosx_swap23 = 1;
- goto done;
- }
- if (!strcmp(p, "macnoresize")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !macosx_resize); goto qry;
- }
- rfbLog("remote_cmd: disable macosx_resize.\n");
- macosx_resize = 0;
- goto done;
- }
- if (!strcmp(p, "macresize") || !strcmp(p, "nomacnoresize")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, macosx_resize); goto qry;
- }
- rfbLog("remote_cmd: enable macosx_resize.\n");
- macosx_resize = 1;
- goto done;
- }
- if (strstr(p, "maciconanim") == p) {
- COLON_CHECK("maciconanim:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, macosx_icon_anim_time);
- goto qry;
- }
- p += strlen("maciconanim:");
- macosx_icon_anim_time = atoi(p);
- rfbLog("set macosx_icon_anim_time to: %d\n", macosx_icon_anim_time);
- goto done;
- }
- if (!strcmp(p, "macmenu")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, macosx_ncache_macmenu); goto qry;
- }
- rfbLog("remote_cmd: enable macosx_ncache_macmenu.\n");
- macosx_ncache_macmenu = 1;
- goto done;
- }
- if (!strcmp(p, "macnomenu") || !strcmp(p, "nomacmenu")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !macosx_ncache_macmenu); goto qry;
- }
- rfbLog("remote_cmd: disable macosx_ncache_macmenu.\n");
- macosx_ncache_macmenu = 0;
- goto done;
- }
- if (!strcmp(p, "macuskbd")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, macosx_us_kbd); goto qry;
- }
- rfbLog("remote_cmd: enable macosx_us_kbd.\n");
- macosx_us_kbd = 1;
- goto done;
- }
- if (!strcmp(p, "nomacuskbd")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p, !macosx_us_kbd); goto qry;
- }
- rfbLog("remote_cmd: disable macosx_us_kbd.\n");
- macosx_us_kbd = 0;
- goto done;
- }
- if (strstr(p, "hack") == p) { /* skip-cmd-list */
- COLON_CHECK("hack:")
- if (query) {
- snprintf(buf, bufn, "ans=%s%s%d", p, co, hack_val);
- goto qry;
- }
- p += strlen("hack:");
- hack_val = atoi(p);
- rfbLog("set hack_val to: %d\n", hack_val);
- goto done;
- }
- if (!strcmp(p, "noremote")) {
- if (query) {
- snprintf(buf, bufn, "ans=%s:%d", p,
- !accept_remote_cmds);
- goto qry;
- }
- rfbLog("remote_cmd: disabling remote commands.\n");
- accept_remote_cmds = 0; /* cannot be turned back on. */
- goto done;
- }
- if (strstr(p, "client_info_sock") == p) { /* skip-cmd-list */
- NOTAPP
- p += strlen("client_info_sock:");
- if (*p != '\0') {
- start_client_info_sock(p);
- }
- goto done;
- }
- if (strstr(p, "noop") == p) {
- NOTAPP
- rfbLog("remote_cmd: noop\n");
- goto done;
- }
- if (icon_mode && !query && strstr(p, "passwd") == p) { /* skip-cmd-list */
- char **passwds_new = (char **) malloc(3*sizeof(char *));
- char **passwds_old = (char **) screen->authPasswdData;
-
- COLON_CHECK("passwd:")
- p += strlen("passwd:");
-
- passwds_new[0] = strdup(p);
-
- /* mutex */
- if (screen->authPasswdData &&
- screen->passwordCheck == rfbCheckPasswordByList) {
- passwds_new[1] = passwds_old[1];
- } else {
- passwds_new[1] = NULL;
- screen->passwordCheck = rfbCheckPasswordByList;
- }
- passwds_new[2] = NULL;
-
- screen->authPasswdData = (void*) passwds_new;
- if (*p == '\0') {
- screen->authPasswdData = (void*) NULL;
- }
- rfbLog("remote_cmd: changed full access passwd.\n");
- goto done;
- }
- if (icon_mode && !query && strstr(p, "viewpasswd") == p) { /* skip-cmd-list */
- char **passwds_new = (char **) malloc(3*sizeof(char *));
- char **passwds_old = (char **) screen->authPasswdData;
-
- COLON_CHECK("viewpasswd:")
- p += strlen("viewpasswd:");
-
- passwds_new[1] = strdup(p);
-
- if (screen->authPasswdData &&
- screen->passwordCheck == rfbCheckPasswordByList) {
- passwds_new[0] = passwds_old[0];
- } else {
- char *tmp = (char *) malloc(4 + CHALLENGESIZE);
- rfbRandomBytes((unsigned char*)tmp);
- passwds_new[0] = tmp;
- screen->passwordCheck = rfbCheckPasswordByList;
- }
- passwds_new[2] = NULL;
-
- if (*p == '\0') {
- passwds_new[1] = NULL;
- }
-
- screen->authPasswdData = (void*) passwds_new;
- rfbLog("remote_cmd: changed view only passwd.\n");
- goto done;
- }
- if (strstr(p, "trayembed") == p) { /* skip-cmd-list */
- unsigned long id;
- NOTAPP
-
- COLON_CHECK("trayembed:")
- p += strlen("trayembed:");
- if (scan_hexdec(p, &id)) {
- tray_request = (Window) id;
- tray_unembed = 0;
- rfbLog("remote_cmd: will try to embed 0x%x in"
- " the system tray.\n", id);
- }
- goto done;
- }
- if (strstr(p, "trayunembed") == p) { /* skip-cmd-list */
- unsigned long id;
- NOTAPP
-
- COLON_CHECK("trayunembed:")
- p += strlen("trayunembed:");
- if (scan_hexdec(p, &id)) {
- tray_request = (Window) id;
- tray_unembed = 1;
- rfbLog("remote_cmd: will try to unembed 0x%x out"
- " of the system tray.\n", id);
- }
- goto done;
- }
- if (query) {
- /* read-only variables that can only be queried: */
-
- if (!strcmp(p, "display")) {
- if (raw_fb) {
- snprintf(buf, bufn, "aro=%s:rawfb:%p",
- p, raw_fb_addr);
- } else if (! dpy) {
- snprintf(buf, bufn, "aro=%s:", p);
- } else {
- char *d;
- d = DisplayString(dpy);
- if (! d) d = "unknown";
- if (*d == ':') {
- snprintf(buf, bufn, "aro=%s:%s%s", p,
- this_host(), d);
- } else {
- snprintf(buf, bufn, "aro=%s:%s", p, d);
- }
- }
- goto qry;
- }
- if (!strcmp(p, "vncdisplay")) {
- snprintf(buf, bufn, "aro=%s:%s", p,
- NONUL(vnc_desktop_name));
- goto qry;
- }
- if (!strcmp(p, "icon_mode")) {
- snprintf(buf, bufn, "aro=%s:%d", p, icon_mode);
- goto qry;
- }
- if (!strcmp(p, "autoport")) {
- snprintf(buf, bufn, "aro=%s:%d", p, auto_port);
- goto qry;
- }
- if (!strcmp(p, "loop") || !strcmp(p, "loopbg")) {
- snprintf(buf, bufn, "aro=%s:%d", p, 0);
- goto qry;
- }
- if (!strcmp(p, "desktopname")) {
- snprintf(buf, bufn, "aro=%s:%s", p,
- NONUL(rfb_desktop_name));
- goto qry;
- }
- if (!strcmp(p, "guess_desktop")) {
- snprintf(buf, bufn, "aro=%s:%s", p,
- NONUL(guess_desktop()));
- goto qry;
- }
- if (!strcmp(p, "guess_dbus")) {
- snprintf(buf, bufn, "aro=%s:%s", p,
- NONUL(dbus_session()));
- goto qry;
- }
- if (!strcmp(p, "http_url")) {
- if (!screen) {
- snprintf(buf, bufn, "aro=%s:", p);
- } else if (screen->httpListenSock > -1) {
- snprintf(buf, bufn, "aro=%s:http://%s:%d", p,
- NONUL(screen->thisHost), screen->httpPort);
- } else {
- snprintf(buf, bufn, "aro=%s:%s", p,
- "http_not_active");
- }
- goto qry;
- }
- if (!strcmp(p, "auth") || !strcmp(p, "xauth")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(auth_file));
- goto qry;
- }
- if (!strcmp(p, "users")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(users_list));
- goto qry;
- }
- if (!strcmp(p, "rootshift")) {
- snprintf(buf, bufn, "aro=%s:%d", p, rootshift);
- goto qry;
- }
- if (!strcmp(p, "clipshift")) {
- snprintf(buf, bufn, "aro=%s:%d", p, clipshift);
- goto qry;
- }
- if (!strcmp(p, "scale_str")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(scale_str));
- goto qry;
- }
- if (!strcmp(p, "scaled_x")) {
- snprintf(buf, bufn, "aro=%s:%d", p, scaled_x);
- goto qry;
- }
- if (!strcmp(p, "scaled_y")) {
- snprintf(buf, bufn, "aro=%s:%d", p, scaled_y);
- goto qry;
- }
- if (!strcmp(p, "scale_numer")) {
- snprintf(buf, bufn, "aro=%s:%d", p, scale_numer);
- goto qry;
- }
- if (!strcmp(p, "scale_denom")) {
- snprintf(buf, bufn, "aro=%s:%d", p, scale_denom);
- goto qry;
- }
- if (!strcmp(p, "scale_fac_x")) {
- snprintf(buf, bufn, "aro=%s:%f", p, scale_fac_x);
- goto qry;
- }
- if (!strcmp(p, "scale_fac_y")) {
- snprintf(buf, bufn, "aro=%s:%f", p, scale_fac_y);
- goto qry;
- }
- if (!strcmp(p, "scaling_blend")) {
- snprintf(buf, bufn, "aro=%s:%d", p, scaling_blend);
- goto qry;
- }
- if (!strcmp(p, "scaling_nomult4")) {
- snprintf(buf, bufn, "aro=%s:%d", p, scaling_nomult4);
- goto qry;
- }
- if (!strcmp(p, "scaling_pad")) {
- snprintf(buf, bufn, "aro=%s:%d", p, scaling_pad);
- goto qry;
- }
- if (!strcmp(p, "scaling_interpolate")) {
- snprintf(buf, bufn, "aro=%s:%d", p,
- scaling_interpolate);
- goto qry;
- }
- if (!strcmp(p, "inetd")) {
- snprintf(buf, bufn, "aro=%s:%d", p, inetd);
- goto qry;
- }
- if (!strcmp(p, "privremote")) {
- snprintf(buf, bufn, "aro=%s:%d", p, priv_remote);
- goto qry;
- }
- if (!strcmp(p, "unsafe")) {
- snprintf(buf, bufn, "aro=%s:%d", p, !safe_remote_only);
- goto qry;
- }
- if (!strcmp(p, "safer")) {
- snprintf(buf, bufn, "aro=%s:%d", p, more_safe);
- goto qry;
- }
- if (!strcmp(p, "nocmds")) {
- snprintf(buf, bufn, "aro=%s:%d", p, no_external_cmds);
- goto qry;
- }
- if (!strcmp(p, "passwdfile")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(passwdfile));
- goto qry;
- }
- if (!strcmp(p, "unixpw")) {
- snprintf(buf, bufn, "aro=%s:%d", p, unixpw);
- goto qry;
- }
- if (!strcmp(p, "unixpw_nis")) {
- snprintf(buf, bufn, "aro=%s:%d", p, unixpw_nis);
- goto qry;
- }
- if (!strcmp(p, "unixpw_list")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(unixpw_list));
- goto qry;
- }
- if (!strcmp(p, "ssl")) {
- snprintf(buf, bufn, "aro=%s:%d", p, use_openssl);
- goto qry;
- }
- if (!strcmp(p, "ssl_pem")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(openssl_pem));
- goto qry;
- }
- if (!strcmp(p, "sslverify")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(ssl_verify));
- goto qry;
- }
- if (!strcmp(p, "stunnel")) {
- snprintf(buf, bufn, "aro=%s:%d", p, use_stunnel);
- goto qry;
- }
- if (!strcmp(p, "stunnel_pem")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(stunnel_pem));
- goto qry;
- }
- if (!strcmp(p, "https")) {
- snprintf(buf, bufn, "aro=%s:%d", p, https_port_num);
- goto qry;
- }
- if (!strcmp(p, "httpsredir")) {
- snprintf(buf, bufn, "aro=%s:%d", p, https_port_redir);
- goto qry;
- }
- if (!strcmp(p, "usepw")) {
- snprintf(buf, bufn, "aro=%s:%d", p, usepw);
- goto qry;
- }
- if (!strcmp(p, "using_shm")) {
- snprintf(buf, bufn, "aro=%s:%d", p, !using_shm);
- goto qry;
- }
- if (!strcmp(p, "logfile") || !strcmp(p, "o")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(logfile));
- goto qry;
- }
- if (!strcmp(p, "flag")) {
- 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) {
- s = NULL;
- }
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(s));
- goto qry;
- }
- if (!strcmp(p, "norc")) {
- snprintf(buf, bufn, "aro=%s:%d", p, got_norc);
- goto qry;
- }
- if (!strcmp(p, "h") || !strcmp(p, "help") ||
- !strcmp(p, "V") || !strcmp(p, "version") ||
- !strcmp(p, "lastmod")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(lastmod));
- goto qry;
- }
- if (!strcmp(p, "bg")) {
- snprintf(buf, bufn, "aro=%s:%d", p, opts_bg);
- goto qry;
- }
- if (!strcmp(p, "sigpipe")) {
- snprintf(buf, bufn, "aro=%s:%s", p, NONUL(sigpipe));
- goto qry;
- }
- if (!strcmp(p, "threads")) {
- snprintf(buf, bufn, "aro=%s:%d", p, use_threads);
- goto qry;
- }
- if (!strcmp(p, "readrate")) {
- snprintf(buf, bufn, "aro=%s:%d", p, get_read_rate());
- goto qry;
- }
- if (!strcmp(p, "netrate")) {
- snprintf(buf, bufn, "aro=%s:%d", p, get_net_rate());
- goto qry;
- }
- if (!strcmp(p, "netlatency")) {
- snprintf(buf, bufn, "aro=%s:%d", p, get_net_latency());
- goto qry;
- }
- if (!strcmp(p, "pipeinput")) {
- snprintf(buf, bufn, "aro=%s:%s", p,
- NONUL(pipeinput_str));
- goto qry;
- }
- if (!strcmp(p, "clients")) {
- char *str = list_clients();
- snprintf(buf, bufn, "aro=%s:%s", p, str);
- free(str);
- goto qry;
- }
- if (!strcmp(p, "client_count")) {
- snprintf(buf, bufn, "aro=%s:%d", p, client_count);
- goto qry;
- }
- if (!strcmp(p, "pid")) {
- snprintf(buf, bufn, "aro=%s:%d", p, (int) getpid());
- goto qry;
- }
- if (!strcmp(p, "ext_xtest")) {
- snprintf(buf, bufn, "aro=%s:%d", p, xtest_present);
- goto qry;
- }
- if (!strcmp(p, "ext_xtrap")) {
- snprintf(buf, bufn, "aro=%s:%d", p, xtrap_present);
- goto qry;
- }
- if (!strcmp(p, "ext_xrecord")) {
- snprintf(buf, bufn, "aro=%s:%d", p, xrecord_present);
- goto qry;
- }
- if (!strcmp(p, "ext_xkb")) {
- snprintf(buf, bufn, "aro=%s:%d", p, xkb_present);
- goto qry;
- }
- if (!strcmp(p, "ext_xshm")) {
- snprintf(buf, bufn, "aro=%s:%d", p, xshm_present);
- goto qry;
- }
- if (!strcmp(p, "ext_xinerama")) {
- snprintf(buf, bufn, "aro=%s:%d", p, xinerama_present);
- goto qry;
- }
- if (!strcmp(p, "ext_overlay")) {
- snprintf(buf, bufn, "aro=%s:%d", p, overlay_present);
- goto qry;
- }
- if (!strcmp(p, "ext_xfixes")) {
- snprintf(buf, bufn, "aro=%s:%d", p, xfixes_present);
- goto qry;
- }
- if (!strcmp(p, "ext_xdamage")) {
- snprintf(buf, bufn, "aro=%s:%d", p, xdamage_present);
- goto qry;
- }
- if (!strcmp(p, "ext_xrandr")) {
- snprintf(buf, bufn, "aro=%s:%d", p, xrandr_present);
- goto qry;
- }
- if (!strcmp(p, "rootwin")) {
- snprintf(buf, bufn, "aro=%s:0x%x", p,
- (unsigned int) rootwin);
- goto qry;
- }
- if (!strcmp(p, "num_buttons")) {
- snprintf(buf, bufn, "aro=%s:%d", p, num_buttons);
- goto qry;
- }
- if (!strcmp(p, "button_mask")) {
- snprintf(buf, bufn, "aro=%s:%d", p, button_mask);
- goto qry;
- }
- if (!strcmp(p, "mouse_x")) {
- snprintf(buf, bufn, "aro=%s:%d", p, cursor_x);
- goto qry;
- }
- if (!strcmp(p, "mouse_y")) {
- snprintf(buf, bufn, "aro=%s:%d", p, cursor_y);
- goto qry;
- }
- if (!strcmp(p, "grab_state")) {
- int ptr_grabbed, kbd_grabbed;
-
- grab_state(&ptr_grabbed, &kbd_grabbed);
- snprintf(buf, bufn, "aro=%s:%d,%d", p, ptr_grabbed, kbd_grabbed);
- if (dpy && rc_npieces < 10) {
- rfbLog("remote_cmd: ptr,kbd: %s\n", buf);
- }
- goto qry;
- }
- if (!strcmp(p, "pointer_pos") || !strcmp(p, "pointer_x") || !strcmp(p, "pointer_y") || !strcmp(p, "pointer_same") || !strcmp(p, "pointer_root") || !strcmp(p, "pointer_mask")) {
- int px = -1, py = -1;
- int wx, wy;
- unsigned int m = 0;
- Window r, c;
- Bool same_screen = True;
-
-
- if (!strcmp(p, "pointer_pos")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:%d,%d", p, px, py);
- } else if (!strcmp(p, "pointer_x")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:%d", p, px);
- } else if (!strcmp(p, "pointer_y")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:%d", p, py);
- } else if (!strcmp(p, "pointer_same")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:%d", p, same_screen);
- } else if (!strcmp(p, "pointer_root")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:0x%x", p, (unsigned int) rootwin);
- } else if (!strcmp(p, "pointer_mask")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:0x%x", p, m);
- }
- if (!dpy) {
- goto qry;
- }
-#if NO_X11
- goto qry;
-#else
- X_LOCK;
- same_screen = XQueryPointer_wr(dpy, rootwin, &r, &c, &px, &py, &wx, &wy, &m);
- X_UNLOCK;
-#endif
-
- if (!strcmp(p, "pointer_pos")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:%d,%d", p, px, py);
- } else if (!strcmp(p, "pointer_x")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:%d", p, px);
- } else if (!strcmp(p, "pointer_y")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:%d", p, py);
- } else if (!strcmp(p, "pointer_same")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:%d", p, same_screen);
- } else if (!strcmp(p, "pointer_root")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:0x%x", p, (unsigned int) r);
- } else if (!strcmp(p, "pointer_mask")) { /* skip-cmd-list */
- snprintf(buf, bufn, "aro=%s:0x%x", p, m);
- }
- if (rc_npieces < 10) {
- rfbLog("remote_cmd: %s: %s\n", p, buf);
- }
- goto qry;
- }
- if (!strcmp(p, "bpp")) {
- snprintf(buf, bufn, "aro=%s:%d", p, bpp);
- goto qry;
- }
- if (!strcmp(p, "depth")) {
- snprintf(buf, bufn, "aro=%s:%d", p, depth);
- goto qry;
- }
- if (!strcmp(p, "indexed_color")) {
- snprintf(buf, bufn, "aro=%s:%d", p, indexed_color);
- goto qry;
- }
- if (!strcmp(p, "dpy_x")) {
- snprintf(buf, bufn, "aro=%s:%d", p, dpy_x);
- goto qry;
- }
- if (!strcmp(p, "dpy_y")) {
- snprintf(buf, bufn, "aro=%s:%d", p, dpy_y);
- goto qry;
- }
- if (!strcmp(p, "wdpy_x")) {
- snprintf(buf, bufn, "aro=%s:%d", p, wdpy_x);
- goto qry;
- }
- if (!strcmp(p, "wdpy_y")) {
- snprintf(buf, bufn, "aro=%s:%d", p, wdpy_y);
- goto qry;
- }
- if (!strcmp(p, "off_x")) {
- snprintf(buf, bufn, "aro=%s:%d", p, off_x);
- goto qry;
- }
- if (!strcmp(p, "off_y")) {
- snprintf(buf, bufn, "aro=%s:%d", p, off_y);
- goto qry;
- }
- if (!strcmp(p, "cdpy_x")) {
- snprintf(buf, bufn, "aro=%s:%d", p, cdpy_x);
- goto qry;
- }
- if (!strcmp(p, "cdpy_y")) {
- snprintf(buf, bufn, "aro=%s:%d", p, cdpy_y);
- goto qry;
- }
- if (!strcmp(p, "coff_x")) {
- snprintf(buf, bufn, "aro=%s:%d", p, coff_x);
- goto qry;
- }
- if (!strcmp(p, "coff_y")) {
- snprintf(buf, bufn, "aro=%s:%d", p, coff_y);
- goto qry;
- }
- if (!strcmp(p, "rfbauth")) {
- NOTAPPRO
- goto qry;
- }
- if (!strcmp(p, "passwd")) {
- NOTAPPRO
- goto qry;
- }
- if (!strcmp(p, "viewpasswd")) {
- NOTAPPRO
- goto qry;
- }
- if (1) {
- NOTAPP
- goto qry;
- }
- goto done;
- }
- if (1) {
- char tmp[100];
- NOTAPP
- rfbLog("remote_cmd: warning unknown\n");
- strncpy(tmp, p, 90);
- rfbLog("command \"%s\"\n", tmp);
- goto done;
- }
-
- done:
-
- if (*buf == '\0') {
- sprintf(buf, "%s", "ack=1");
- }
-
- qry:
-
- if (stringonly) {
- return strdup(buf);
- } else if (client_connect_file) {
- FILE *out = fopen(client_connect_file, "w");
- if (out != NULL) {
- fprintf(out, "%s\n", buf);
- fclose(out);
- usleep(20*1000);
- }
- } else {
- if (dpy) { /* raw_fb hack */
- X_LOCK;
- set_x11vnc_remote_prop(buf);
- XFlush_wr(dpy);
- X_UNLOCK;
- }
- }
-#endif /* REMOTE_CONTROL */
- return NULL;
-}
-
-
diff --git a/x11vnc/remote.h b/x11vnc/remote.h
deleted file mode 100644
index 3a2dea2..0000000
--- a/x11vnc/remote.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_REMOTE_H
-#define _X11VNC_REMOTE_H
-
-/* -- remote.h -- */
-
-extern int send_remote_cmd(char *cmd, int query, int wait);
-extern int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync,
- int qdefault);
-extern void check_black_fb(void);
-extern int check_httpdir(void);
-extern void http_connections(int on);
-extern int remote_control_access_ok(void);
-extern char *process_remote_cmd(char *cmd, int stringonly);
-
-extern char *query_result;
-
-
-#endif /* _X11VNC_REMOTE_H */
diff --git a/x11vnc/scan.c b/x11vnc/scan.c
deleted file mode 100644
index 1fb7883..0000000
--- a/x11vnc/scan.c
+++ /dev/null
@@ -1,3687 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- scan.c -- */
-
-#include "x11vnc.h"
-#include "xinerama.h"
-#include "xwrappers.h"
-#include "xdamage.h"
-#include "xrandr.h"
-#include "win_utils.h"
-#include "8to24.h"
-#include "screen.h"
-#include "pointer.h"
-#include "cleanup.h"
-#include "unixpw.h"
-#include "screen.h"
-#include "macosx.h"
-#include "userinput.h"
-
-/*
- * routines for scanning and reading the X11 display for changes, and
- * for doing all the tile work (shm, etc).
- */
-void initialize_tiles(void);
-void free_tiles(void);
-void shm_delete(XShmSegmentInfo *shm);
-void shm_clean(XShmSegmentInfo *shm, XImage *xim);
-void initialize_polling_images(void);
-void scale_rect(double factor_x, double factor_y, int blend, int interpolate, int Bpp,
- char *src_fb, int src_bytes_per_line, char *dst_fb, int dst_bytes_per_line,
- int Nx, int Ny, int nx, int ny, int X1, int Y1, int X2, int Y2, int mark);
-void scale_and_mark_rect(int X1, int Y1, int X2, int Y2, int mark);
-void mark_rect_as_modified(int x1, int y1, int x2, int y2, int force);
-int copy_screen(void);
-int copy_snap(void);
-void nap_sleep(int ms, int split);
-void set_offset(void);
-int scan_for_updates(int count_only);
-void rotate_curs(char *dst_0, char *src_0, int Dx, int Dy, int Bpp);
-void rotate_coords(int x, int y, int *xo, int *yo, int dxi, int dyi);
-void rotate_coords_inverse(int x, int y, int *xo, int *yo, int dxi, int dyi);
-
-static void set_fs_factor(int max);
-static char *flip_ximage_byte_order(XImage *xim);
-static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
- char *name);
-static void create_tile_hint(int x, int y, int tw, int th, hint_t *hint);
-static void extend_tile_hint(int x, int y, int tw, int th, hint_t *hint);
-static void save_hint(hint_t hint, int loc);
-static void hint_updates(void);
-static void mark_hint(hint_t hint);
-static int copy_tiles(int tx, int ty, int nt);
-static int copy_all_tiles(void);
-static int copy_all_tile_runs(void);
-static int copy_tiles_backward_pass(void);
-static int copy_tiles_additional_pass(void);
-static int gap_try(int x, int y, int *run, int *saw, int along_x);
-static int fill_tile_gaps(void);
-static int island_try(int x, int y, int u, int v, int *run);
-static int grow_islands(void);
-static void blackout_regions(void);
-static void nap_set(int tile_cnt);
-static void nap_check(int tile_cnt);
-static void ping_clients(int tile_cnt);
-static int blackout_line_skip(int n, int x, int y, int rescan,
- int *tile_count);
-static int blackout_line_cmpskip(int n, int x, int y, char *dst, char *src,
- int w, int pixelsize);
-static int scan_display(int ystart, int rescan);
-
-
-/* array to hold the hints: */
-static hint_t *hint_list;
-
-/* nap state */
-int nap_ok = 0;
-static int nap_diff_count = 0;
-
-static int scan_count = 0; /* indicates which scan pattern we are on */
-static int scan_in_progress = 0;
-
-
-typedef struct tile_change_region {
- /* start and end lines, along y, of the changed area inside a tile. */
- unsigned short first_line, last_line;
- short first_x, last_x;
- /* info about differences along edges. */
- unsigned short left_diff, right_diff;
- unsigned short top_diff, bot_diff;
-} region_t;
-
-/* array to hold the tiles region_t-s. */
-static region_t *tile_region;
-
-
-
-
-/*
- * setup tile numbers and allocate the tile and hint arrays:
- */
-void initialize_tiles(void) {
-
- ntiles_x = (dpy_x - 1)/tile_x + 1;
- ntiles_y = (dpy_y - 1)/tile_y + 1;
- ntiles = ntiles_x * ntiles_y;
-
- tile_has_diff = (unsigned char *)
- calloc((size_t) (ntiles * sizeof(unsigned char)), 1);
- tile_has_xdamage_diff = (unsigned char *)
- calloc((size_t) (ntiles * sizeof(unsigned char)), 1);
- tile_row_has_xdamage_diff = (unsigned char *)
- calloc((size_t) (ntiles_y * sizeof(unsigned char)), 1);
- tile_tried = (unsigned char *)
- calloc((size_t) (ntiles * sizeof(unsigned char)), 1);
- tile_copied = (unsigned char *)
- calloc((size_t) (ntiles * sizeof(unsigned char)), 1);
- tile_blackout = (tile_blackout_t *)
- calloc((size_t) (ntiles * sizeof(tile_blackout_t)), 1);
- tile_region = (region_t *) calloc((size_t) (ntiles * sizeof(region_t)), 1);
-
- tile_row = (XImage **)
- calloc((size_t) ((ntiles_x + 1) * sizeof(XImage *)), 1);
- tile_row_shm = (XShmSegmentInfo *)
- calloc((size_t) ((ntiles_x + 1) * sizeof(XShmSegmentInfo)), 1);
-
- /* there will never be more hints than tiles: */
- hint_list = (hint_t *) calloc((size_t) (ntiles * sizeof(hint_t)), 1);
-}
-
-void free_tiles(void) {
- if (tile_has_diff) {
- free(tile_has_diff);
- tile_has_diff = NULL;
- }
- if (tile_has_xdamage_diff) {
- free(tile_has_xdamage_diff);
- tile_has_xdamage_diff = NULL;
- }
- if (tile_row_has_xdamage_diff) {
- free(tile_row_has_xdamage_diff);
- tile_row_has_xdamage_diff = NULL;
- }
- if (tile_tried) {
- free(tile_tried);
- tile_tried = NULL;
- }
- if (tile_copied) {
- free(tile_copied);
- tile_copied = NULL;
- }
- if (tile_blackout) {
- free(tile_blackout);
- tile_blackout = NULL;
- }
- if (tile_region) {
- free(tile_region);
- tile_region = NULL;
- }
- if (tile_row) {
- free(tile_row);
- tile_row = NULL;
- }
- if (tile_row_shm) {
- free(tile_row_shm);
- tile_row_shm = NULL;
- }
- if (hint_list) {
- free(hint_list);
- hint_list = NULL;
- }
-}
-
-/*
- * silly function to factor dpy_y until fullscreen shm is not bigger than max.
- * should always work unless dpy_y is a large prime or something... under
- * failure fs_factor remains 0 and no fullscreen updates will be tried.
- */
-static int fs_factor = 0;
-
-static void set_fs_factor(int max) {
- int f, fac = 1, n = dpy_y;
-
- fs_factor = 0;
- if ((bpp/8) * dpy_x * dpy_y <= max) {
- fs_factor = 1;
- return;
- }
- for (f=2; f <= 101; f++) {
- while (n % f == 0) {
- n = n / f;
- fac = fac * f;
- if ( (bpp/8) * dpy_x * (dpy_y/fac) <= max ) {
- fs_factor = fac;
- return;
- }
- }
- }
-}
-
-static char *flip_ximage_byte_order(XImage *xim) {
- char *order;
- if (xim->byte_order == LSBFirst) {
- order = "MSBFirst";
- xim->byte_order = MSBFirst;
- xim->bitmap_bit_order = MSBFirst;
- } else {
- order = "LSBFirst";
- xim->byte_order = LSBFirst;
- xim->bitmap_bit_order = LSBFirst;
- }
- return order;
-}
-
-/*
- * set up an XShm image, or if not using shm just create the XImage.
- */
-static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
- char *name) {
-
- XImage *xim;
- static int reported_flip = 0;
- int db = 0;
-
- shm->shmid = -1;
- shm->shmaddr = (char *) -1;
- *ximg_ptr = NULL;
-
- if (nofb) {
- return 1;
- }
-
- X_LOCK;
-
- if (! using_shm || xform24to32 || raw_fb) {
- /* we only need the XImage created */
- xim = XCreateImage_wr(dpy, default_visual, depth, ZPixmap,
- 0, NULL, w, h, raw_fb ? 32 : BitmapPad(dpy), 0);
-
- X_UNLOCK;
-
- if (xim == NULL) {
- rfbErr("XCreateImage(%s) failed.\n", name);
- if (quiet) {
- fprintf(stderr, "XCreateImage(%s) failed.\n",
- name);
- }
- return 0;
- }
- if (db) fprintf(stderr, "shm_create simple %d %d\t%p %s\n", w, h, (void *)xim, name);
- xim->data = (char *) malloc(xim->bytes_per_line * xim->height);
- if (xim->data == NULL) {
- rfbErr("XCreateImage(%s) data malloc failed.\n", name);
- if (quiet) {
- fprintf(stderr, "XCreateImage(%s) data malloc"
- " failed.\n", name);
- }
- return 0;
- }
- if (flip_byte_order) {
- char *order = flip_ximage_byte_order(xim);
- if (! reported_flip && ! quiet) {
- rfbLog("Changing XImage byte order"
- " to %s\n", order);
- reported_flip = 1;
- }
- }
-
- *ximg_ptr = xim;
- return 1;
- }
-
- if (! dpy) {
- X_UNLOCK;
- return 0;
- }
-
- xim = XShmCreateImage_wr(dpy, default_visual, depth, ZPixmap, NULL,
- shm, w, h);
-
- if (xim == NULL) {
- rfbErr("XShmCreateImage(%s) failed.\n", name);
- if (quiet) {
- fprintf(stderr, "XShmCreateImage(%s) failed.\n", name);
- }
- X_UNLOCK;
- return 0;
- }
-
- *ximg_ptr = xim;
-
-#if LIBVNCSERVER_HAVE_XSHM
- shm->shmid = shmget(IPC_PRIVATE,
- xim->bytes_per_line * xim->height, IPC_CREAT | 0777);
-
- if (shm->shmid == -1) {
- rfbErr("shmget(%s) failed.\n", name);
- rfbLogPerror("shmget");
-
- XDestroyImage(xim);
- *ximg_ptr = NULL;
-
- X_UNLOCK;
- return 0;
- }
-
- shm->shmaddr = xim->data = (char *) shmat(shm->shmid, 0, 0);
-
- if (shm->shmaddr == (char *)-1) {
- rfbErr("shmat(%s) failed.\n", name);
- rfbLogPerror("shmat");
-
- XDestroyImage(xim);
- *ximg_ptr = NULL;
-
- shmctl(shm->shmid, IPC_RMID, 0);
- shm->shmid = -1;
-
- X_UNLOCK;
- return 0;
- }
-
- shm->readOnly = False;
-
- if (! XShmAttach_wr(dpy, shm)) {
- rfbErr("XShmAttach(%s) failed.\n", name);
- XDestroyImage(xim);
- *ximg_ptr = NULL;
-
- shmdt(shm->shmaddr);
- shm->shmaddr = (char *) -1;
-
- shmctl(shm->shmid, IPC_RMID, 0);
- shm->shmid = -1;
-
- X_UNLOCK;
- return 0;
- }
-#endif
-
- X_UNLOCK;
- return 1;
-}
-
-void shm_delete(XShmSegmentInfo *shm) {
-#if LIBVNCSERVER_HAVE_XSHM
- if (getenv("X11VNC_SHM_DEBUG")) fprintf(stderr, "shm_delete: %p\n", (void *) shm);
- if (shm != NULL && shm->shmaddr != (char *) -1) {
- shmdt(shm->shmaddr);
- }
- if (shm != NULL && shm->shmid != -1) {
- shmctl(shm->shmid, IPC_RMID, 0);
- }
- if (shm != NULL) {
- shm->shmaddr = (char *) -1;
- shm->shmid = -1;
- }
-#else
- if (!shm) {}
-#endif
-}
-
-void shm_clean(XShmSegmentInfo *shm, XImage *xim) {
- int db = 0;
-
- if (db) fprintf(stderr, "shm_clean: called: %p\n", (void *)xim);
- X_LOCK;
-#if LIBVNCSERVER_HAVE_XSHM
- if (shm != NULL && shm->shmid != -1 && dpy) {
- if (db) fprintf(stderr, "shm_clean: XShmDetach_wr\n");
- XShmDetach_wr(dpy, shm);
- }
-#endif
- if (xim != NULL) {
- if (! raw_fb_back_to_X) { /* raw_fb hack */
- if (xim->bitmap_unit != -1) {
- if (db) fprintf(stderr, "shm_clean: XDestroyImage %p\n", (void *)xim);
- XDestroyImage(xim);
- } else {
- if (xim->data) {
- if (db) fprintf(stderr, "shm_clean: free xim->data %p %p\n", (void *)xim, (void *)(xim->data));
- free(xim->data);
- xim->data = NULL;
- }
- }
- }
- xim = NULL;
- }
- X_UNLOCK;
-
- shm_delete(shm);
-}
-
-void initialize_polling_images(void) {
- int i, MB = 1024 * 1024;
-
- /* set all shm areas to "none" before trying to create any */
- scanline_shm.shmid = -1;
- scanline_shm.shmaddr = (char *) -1;
- scanline = NULL;
- fullscreen_shm.shmid = -1;
- fullscreen_shm.shmaddr = (char *) -1;
- fullscreen = NULL;
- snaprect_shm.shmid = -1;
- snaprect_shm.shmaddr = (char *) -1;
- snaprect = NULL;
- for (i=1; i<=ntiles_x; i++) {
- tile_row_shm[i].shmid = -1;
- tile_row_shm[i].shmaddr = (char *) -1;
- tile_row[i] = NULL;
- }
-
- /* the scanline (e.g. 1280x1) shared memory area image: */
-
- if (! shm_create(&scanline_shm, &scanline, dpy_x, 1, "scanline")) {
- clean_up_exit(1);
- }
-
- /*
- * the fullscreen (e.g. 1280x1024/fs_factor) shared memory area image:
- * (we cut down the size of the shm area to try avoid and shm segment
- * limits, e.g. the default 1MB on Solaris)
- */
- if (UT.sysname && strstr(UT.sysname, "Linux")) {
- set_fs_factor(10 * MB);
- } else {
- set_fs_factor(1 * MB);
- }
- if (fs_frac >= 1.0) {
- fs_frac = 1.1;
- fs_factor = 0;
- }
- if (! fs_factor) {
- rfbLog("warning: fullscreen updates are disabled.\n");
- } else {
- if (! shm_create(&fullscreen_shm, &fullscreen, dpy_x,
- dpy_y/fs_factor, "fullscreen")) {
- clean_up_exit(1);
- }
- }
- if (use_snapfb) {
- if (! fs_factor) {
- rfbLog("warning: disabling -snapfb mode.\n");
- use_snapfb = 0;
- } else if (! shm_create(&snaprect_shm, &snaprect, dpy_x,
- dpy_y/fs_factor, "snaprect")) {
- clean_up_exit(1);
- }
- }
-
- /*
- * for copy_tiles we need a lot of shared memory areas, one for
- * each possible run length of changed tiles. 32 for 1024x768
- * and 40 for 1280x1024, etc.
- */
-
- tile_shm_count = 0;
- for (i=1; i<=ntiles_x; i++) {
- if (! shm_create(&tile_row_shm[i], &tile_row[i], tile_x * i,
- tile_y, "tile_row")) {
- if (i == 1) {
- clean_up_exit(1);
- }
- rfbLog("shm: Error creating shared memory tile-row for"
- " len=%d,\n", i);
- rfbLog("shm: reverting to -onetile mode. If this"
- " problem persists\n");
- rfbLog("shm: try using the -onetile or -noshm options"
- " to limit\n");
- rfbLog("shm: shared memory usage, or run ipcrm(1)"
- " to manually\n");
- rfbLog("shm: delete unattached shm segments.\n");
- single_copytile_count = i;
- single_copytile = 1;
- }
- tile_shm_count++;
- if (single_copytile && i >= 1) {
- /* only need 1x1 tiles */
- break;
- }
- }
- if (verbose) {
- if (using_shm && ! xform24to32) {
- rfbLog("created %d tile_row shm polling images.\n",
- tile_shm_count);
- } else {
- rfbLog("created %d tile_row polling images.\n",
- tile_shm_count);
- }
- }
-}
-
-/*
- * A hint is a rectangular region built from 1 or more adjacent tiles
- * glued together. Ultimately, this information in a single hint is sent
- * to libvncserver rather than sending each tile separately.
- */
-static void create_tile_hint(int x, int y, int tw, int th, hint_t *hint) {
- int w = dpy_x - x;
- int h = dpy_y - y;
-
- if (w > tw) {
- w = tw;
- }
- if (h > th) {
- h = th;
- }
-
- hint->x = x;
- hint->y = y;
- hint->w = w;
- hint->h = h;
-}
-
-static void extend_tile_hint(int x, int y, int tw, int th, hint_t *hint) {
- int w = dpy_x - x;
- int h = dpy_y - y;
-
- if (w > tw) {
- w = tw;
- }
- if (h > th) {
- h = th;
- }
-
- if (hint->x > x) { /* extend to the left */
- hint->w += hint->x - x;
- hint->x = x;
- }
- if (hint->y > y) { /* extend upward */
- hint->h += hint->y - y;
- hint->y = y;
- }
-
- if (hint->x + hint->w < x + w) { /* extend to the right */
- hint->w = x + w - hint->x;
- }
- if (hint->y + hint->h < y + h) { /* extend downward */
- hint->h = y + h - hint->y;
- }
-}
-
-static void save_hint(hint_t hint, int loc) {
- /* simply copy it to the global array for later use. */
- hint_list[loc].x = hint.x;
- hint_list[loc].y = hint.y;
- hint_list[loc].w = hint.w;
- hint_list[loc].h = hint.h;
-}
-
-/*
- * Glue together horizontal "runs" of adjacent changed tiles into one big
- * rectangle change "hint" to be passed to the vnc machinery.
- */
-static void hint_updates(void) {
- hint_t hint;
- int x, y, i, n, ty, th, tx, tw;
- int hint_count = 0, in_run = 0;
-
- hint.x = hint.y = hint.w = hint.h = 0;
-
- for (y=0; y < ntiles_y; y++) {
- for (x=0; x < ntiles_x; x++) {
- n = x + y * ntiles_x;
-
- if (tile_has_diff[n]) {
- ty = tile_region[n].first_line;
- th = tile_region[n].last_line - ty + 1;
-
- tx = tile_region[n].first_x;
- tw = tile_region[n].last_x - tx + 1;
- if (tx < 0) {
- tx = 0;
- tw = tile_x;
- }
-
- if (! in_run) {
- create_tile_hint( x * tile_x + tx,
- y * tile_y + ty, tw, th, &hint);
- in_run = 1;
- } else {
- extend_tile_hint( x * tile_x + tx,
- y * tile_y + ty, tw, th, &hint);
- }
- } else {
- if (in_run) {
- /* end of a row run of altered tiles: */
- save_hint(hint, hint_count++);
- in_run = 0;
- }
- }
- }
- if (in_run) { /* save the last row run */
- save_hint(hint, hint_count++);
- in_run = 0;
- }
- }
-
- for (i=0; i < hint_count; i++) {
- /* pass update info to vnc: */
- mark_hint(hint_list[i]);
- }
-}
-
-/*
- * kludge, simple ceil+floor for non-negative doubles:
- */
-#define CEIL(x) ( (double) ((int) (x)) == (x) ? \
- (double) ((int) (x)) : (double) ((int) (x) + 1) )
-#define FLOOR(x) ( (double) ((int) (x)) )
-
-/*
- * Scaling:
- *
- * For shrinking, a destination (scaled) pixel will correspond to more
- * than one source (i.e. main fb) pixel. Think of an x-y plane made with
- * graph paper. Each unit square in the graph paper (i.e. collection of
- * points (x,y) such that N < x < N+1 and M < y < M+1, N and M integers)
- * corresponds to one pixel in the unscaled fb. There is a solid
- * color filling the inside of such a square. A scaled pixel has width
- * 1/scale_fac, e.g. for "-scale 3/4" the width of the scaled pixel
- * is 1.333. The area of this scaled pixel is 1.333 * 1.333 (so it
- * obviously overlaps more than one source pixel, each which have area 1).
- *
- * We take the weight an unscaled pixel (source) contributes to a
- * scaled pixel (destination) as simply proportional to the overlap area
- * between the two pixels. One can then think of the value of the scaled
- * pixel as an integral over the portion of the graph paper it covers.
- * The thing being integrated is the color value of the unscaled source.
- * That color value is constant over a graph paper square (source pixel),
- * and changes discontinuously from one unit square to the next.
- *
-
-Here is an example for -scale 3/4, the solid lines are the source pixels
-(graph paper unit squares), while the dotted lines denote the scaled
-pixels (destination pixels):
-
- 0 1 4/3 2 8/3 3 4=12/3
- |---------|--.------|------.--|---------|.
- | | . | . | |.
- | A | . B | . | |.
- | | . | . | |.
- | | . | . | |.
- 1 |---------|--.------|------.--|---------|.
- 4/3|.........|.........|.........|.........|.
- | | . | . | |.
- | C | . D | . | |.
- | | . | . | |.
- 2 |---------|--.------|------.--|---------|.
- | | . | . | |.
- | | . | . | |.
- 8/3|.........|.........|.........|.........|.
- | | . | . | |.
- 3 |---------|--.------|------.--|---------|.
-
-So we see the first scaled pixel (0 < x < 4/3 and 0 < y < 4/3) mostly
-overlaps with unscaled source pixel "A". The integration (averaging)
-weights for this scaled pixel are:
-
- A 1
- B 1/3
- C 1/3
- D 1/9
-
- *
- * The Red, Green, and Blue color values must be averaged over separately
- * otherwise you can get a complete mess (except in solid regions),
- * because high order bits are averaged differently from the low order bits.
- *
- * So the algorithm is roughly:
- *
- * - Given as input a rectangle in the unscaled source fb with changes,
- * find the rectangle of pixels this affects in the scaled destination fb.
- *
- * - For each of the affected scaled (dest) pixels, determine all of the
- * unscaled (source) pixels it overlaps with.
- *
- * - Average those unscaled source values together, weighted by the area
- * overlap with the destination pixel. Average R, G, B separately.
- *
- * - Take this average value and convert to a valid pixel value if
- * necessary (e.g. rounding, shifting), and then insert it into the
- * destination framebuffer as the pixel value.
- *
- * - On to the next destination pixel...
- *
- * ========================================================================
- *
- * For expanding, e.g. -scale 1.1 (which we don't think people will do
- * very often... or at least so we hope, the framebuffer can become huge)
- * the situation is reversed and the destination pixel is smaller than a
- * "graph paper" unit square (source pixel). Some destination pixels
- * will be completely within a single unscaled source pixel.
- *
- * What we do here is a simple 4 point interpolation scheme:
- *
- * Let P00 be the source pixel closest to the destination pixel but with
- * x and y values less than or equal to those of the destination pixel.
- * (for simplicity, think of the upper left corner of a pixel defining the
- * x,y location of the pixel, the center would work just as well). So it
- * is the source pixel immediately to the upper left of the destination
- * pixel. Let P10 be the source pixel one to the right of P00. Let P01
- * be one down from P00. And let P11 be one down and one to the right
- * of P00. They form a 2x2 square we will interpolate inside of.
- *
- * Let V00, V10, V01, and V11 be the color values of those 4 source
- * pixels. Let dx be the displacement along x the destination pixel is
- * from P00. Note: 0 <= dx < 1 by definition of P00. Similarly let
- * dy be the displacement along y. The weighted average for the
- * interpolation is:
- *
- * V_ave = V00 * (1 - dx) * (1 - dy)
- * + V10 * dx * (1 - dy)
- * + V01 * (1 - dx) * dy
- * + V11 * dx * dy
- *
- * Note that the weights (1-dx)*(1-dy) + dx*(1-dy) + (1-dx)*dy + dx*dy
- * automatically add up to 1. It is also nice that all the weights are
- * positive (unsigned char stays unsigned char). The above formula can
- * be motivated by doing two 1D interpolations along x:
- *
- * VA = V00 * (1 - dx) + V10 * dx
- * VB = V01 * (1 - dx) + V11 * dx
- *
- * and then interpolating VA and VB along y:
- *
- * V_ave = VA * (1 - dy) + VB * dy
- *
- * VA
- * v |<-dx->|
- * -- V00 ------ V10
- * dy | |
- * -- | o...|... "o" denotes the position of the desired
- * ^ | . | . destination pixel relative to the P00
- * | . | . source pixel.
- * V10 ----.- V11 .
- * ........
- * |
- * VB
- *
- *
- * Of course R, G, B averages are done separately as in the shrinking
- * case. This gives reasonable results, and the implementation for
- * shrinking can simply be used with different choices for weights for
- * the loop over the 4 pixels.
- */
-
-void scale_rect(double factor_x, double factor_y, int blend, int interpolate, int Bpp,
- char *src_fb, int src_bytes_per_line, char *dst_fb, int dst_bytes_per_line,
- int Nx, int Ny, int nx, int ny, int X1, int Y1, int X2, int Y2, int mark) {
-/*
- * Notation:
- * "i" an x pixel index in the destination (scaled) framebuffer
- * "j" a y pixel index in the destination (scaled) framebuffer
- * "I" an x pixel index in the source (un-scaled, i.e. main) framebuffer
- * "J" a y pixel index in the source (un-scaled, i.e. main) framebuffer
- *
- * Similarly for nx, ny, Nx, Ny, etc. Lowercase: dest, Uppercase: source.
- */
- int i, j, i1, i2, j1, j2; /* indices for scaled fb (dest) */
- int I, J, I1, I2, J1, J2; /* indices for main fb (source) */
-
- double w, wx, wy, wtot; /* pixel weights */
-
- double x1, y1, x2, y2; /* x-y coords for destination pixels edges */
- double dx, dy; /* size of destination pixel */
- double ddx=0, ddy=0; /* for interpolation expansion */
-
- char *src, *dest; /* pointers to the two framebuffers */
-
-
- unsigned short us = 0;
- unsigned char uc = 0;
- unsigned int ui = 0;
-
- int use_noblend_shortcut = 1;
- int shrink; /* whether shrinking or expanding */
- static int constant_weights = -1, mag_int = -1;
- static int last_Nx = -1, last_Ny = -1, cnt = 0;
- static double last_factor = -1.0;
- int b, k;
- double pixave[4]; /* for averaging pixel values */
-
- if (factor_x <= 1.0 && factor_y <= 1.0) {
- shrink = 1;
- } else {
- shrink = 0;
- }
-
- /*
- * N.B. width and height (real numbers) of a scaled pixel.
- * both are > 1 (e.g. 1.333 for -scale 3/4)
- * they should also be equal but we don't assume it.
- *
- * This new way is probably the best we can do, take the inverse
- * of the scaling factor to double precision.
- */
- dx = 1.0/factor_x;
- dy = 1.0/factor_y;
-
- /*
- * There is some speedup if the pixel weights are constant, so
- * let's special case these.
- *
- * If scale = 1/n and n divides Nx and Ny, the pixel weights
- * are constant (e.g. 1/2 => equal on 2x2 square).
- */
- if (factor_x != last_factor || Nx != last_Nx || Ny != last_Ny) {
- constant_weights = -1;
- mag_int = -1;
- last_Nx = Nx;
- last_Ny = Ny;
- last_factor = factor_x;
- }
- if (constant_weights < 0 && factor_x != factor_y) {
- constant_weights = 0;
- mag_int = 0;
-
- } else if (constant_weights < 0) {
- int n = 0;
-
- constant_weights = 0;
- mag_int = 0;
-
- for (i = 2; i<=128; i++) {
- double test = ((double) 1)/ i;
- double diff, eps = 1.0e-7;
- diff = factor_x - test;
- if (-eps < diff && diff < eps) {
- n = i;
- break;
- }
- }
- if (! blend || ! shrink || interpolate) {
- ;
- } else if (n != 0) {
- if (Nx % n == 0 && Ny % n == 0) {
- static int didmsg = 0;
- if (mark && ! didmsg) {
- didmsg = 1;
- rfbLog("scale_and_mark_rect: using "
- "constant pixel weight speedup "
- "for 1/%d\n", n);
- }
- constant_weights = 1;
- }
- }
-
- n = 0;
- for (i = 2; i<=32; i++) {
- double test = (double) i;
- double diff, eps = 1.0e-7;
- diff = factor_x - test;
- if (-eps < diff && diff < eps) {
- n = i;
- break;
- }
- }
- if (! blend && factor_x > 1.0 && n) {
- mag_int = n;
- }
- }
-
- if (mark && factor_x > 1.0 && blend) {
- /*
- * kludge: correct for interpolating blurring leaking
- * up or left 1 destination pixel.
- */
- if (X1 > 0) X1--;
- if (Y1 > 0) Y1--;
- }
-
- /*
- * find the extent of the change the input rectangle induces in
- * the scaled framebuffer.
- */
-
- /* Left edges: find largest i such that i * dx <= X1 */
- i1 = FLOOR(X1/dx);
-
- /* Right edges: find smallest i such that (i+1) * dx >= X2+1 */
- i2 = CEIL( (X2+1)/dx ) - 1;
-
- /* To be safe, correct any overflows: */
- i1 = nfix(i1, nx);
- i2 = nfix(i2, nx) + 1; /* add 1 to make a rectangle upper boundary */
-
- /* Repeat above for y direction: */
- j1 = FLOOR(Y1/dy);
- j2 = CEIL( (Y2+1)/dy ) - 1;
-
- j1 = nfix(j1, ny);
- j2 = nfix(j2, ny) + 1;
-
- /*
- * special case integer magnification with no blending.
- * vision impaired magnification usage is interested in this case.
- */
- if (mark && ! blend && mag_int && Bpp != 3) {
- int jmin, jmax, imin, imax;
-
- /* outer loop over *source* pixels */
- for (J=Y1; J < Y2; J++) {
- jmin = J * mag_int;
- jmax = jmin + mag_int;
- for (I=X1; I < X2; I++) {
- /* extract value */
- src = src_fb + J*src_bytes_per_line + I*Bpp;
- if (Bpp == 4) {
- ui = *((unsigned int *)src);
- } else if (Bpp == 2) {
- us = *((unsigned short *)src);
- } else if (Bpp == 1) {
- uc = *((unsigned char *)src);
- }
- imin = I * mag_int;
- imax = imin + mag_int;
- /* inner loop over *dest* pixels */
- for (j=jmin; j<jmax; j++) {
- dest = dst_fb + j*dst_bytes_per_line + imin*Bpp;
- for (i=imin; i<imax; i++) {
- if (Bpp == 4) {
- *((unsigned int *)dest) = ui;
- } else if (Bpp == 2) {
- *((unsigned short *)dest) = us;
- } else if (Bpp == 1) {
- *((unsigned char *)dest) = uc;
- }
- dest += Bpp;
- }
- }
- }
- }
- goto markit;
- }
-
- /* set these all to 1.0 to begin with */
- wx = 1.0;
- wy = 1.0;
- w = 1.0;
-
- /*
- * Loop over destination pixels in scaled fb:
- */
- for (j=j1; j<j2; j++) {
- y1 = j * dy; /* top edge */
- if (y1 > Ny - 1) {
- /* can go over with dy = 1/scale_fac */
- y1 = Ny - 1;
- }
- y2 = y1 + dy; /* bottom edge */
-
- /* Find main fb indices covered by this dest pixel: */
- J1 = (int) FLOOR(y1);
- J1 = nfix(J1, Ny);
-
- if (shrink && ! interpolate) {
- J2 = (int) CEIL(y2) - 1;
- J2 = nfix(J2, Ny);
- } else {
- J2 = J1 + 1; /* simple interpolation */
- ddy = y1 - J1;
- }
-
- /* destination char* pointer: */
- dest = dst_fb + j*dst_bytes_per_line + i1*Bpp;
-
- for (i=i1; i<i2; i++) {
-
- x1 = i * dx; /* left edge */
- if (x1 > Nx - 1) {
- /* can go over with dx = 1/scale_fac */
- x1 = Nx - 1;
- }
- x2 = x1 + dx; /* right edge */
-
- cnt++;
-
- /* Find main fb indices covered by this dest pixel: */
- I1 = (int) FLOOR(x1);
- if (I1 >= Nx) I1 = Nx - 1;
-
- if (! blend && use_noblend_shortcut) {
- /*
- * The noblend case involves no weights,
- * and 1 pixel, so just copy the value
- * directly.
- */
- src = src_fb + J1*src_bytes_per_line + I1*Bpp;
- if (Bpp == 4) {
- *((unsigned int *)dest)
- = *((unsigned int *)src);
- } else if (Bpp == 2) {
- *((unsigned short *)dest)
- = *((unsigned short *)src);
- } else if (Bpp == 1) {
- *(dest) = *(src);
- } else if (Bpp == 3) {
- /* rare case */
- for (k=0; k<=2; k++) {
- *(dest+k) = *(src+k);
- }
- }
- dest += Bpp;
- continue;
- }
-
- if (shrink && ! interpolate) {
- I2 = (int) CEIL(x2) - 1;
- if (I2 >= Nx) I2 = Nx - 1;
- } else {
- I2 = I1 + 1; /* simple interpolation */
- ddx = x1 - I1;
- }
-
- /* Zero out accumulators for next pixel average: */
- for (b=0; b<4; b++) {
- pixave[b] = 0.0; /* for RGB weighted sums */
- }
-
- /*
- * wtot is for accumulating the total weight.
- * It should always sum to 1/(scale_fac * scale_fac).
- */
- wtot = 0.0;
-
- /*
- * Loop over source pixels covered by this dest pixel.
- *
- * These "extra" loops over "J" and "I" make
- * the cache/cacheline performance unclear.
- * For example, will the data brought in from
- * src for j, i, and J=0 still be in the cache
- * after the J > 0 data have been accessed and
- * we are at j, i+1, J=0? The stride in J is
- * main_bytes_per_line, and so ~4 KB.
- *
- * Typical case when shrinking are 2x2 loop, so
- * just two lines to worry about.
- */
- for (J=J1; J<=J2; J++) {
- /* see comments for I, x1, x2, etc. below */
- if (constant_weights) {
- ;
- } else if (! blend) {
- if (J != J1) {
- continue;
- }
- wy = 1.0;
-
- /* interpolation scheme: */
- } else if (! shrink || interpolate) {
- if (J >= Ny) {
- continue;
- } else if (J == J1) {
- wy = 1.0 - ddy;
- } else if (J != J1) {
- wy = ddy;
- }
-
- /* integration scheme: */
- } else if (J < y1) {
- wy = J+1 - y1;
- } else if (J+1 > y2) {
- wy = y2 - J;
- } else {
- wy = 1.0;
- }
-
- src = src_fb + J*src_bytes_per_line + I1*Bpp;
-
- for (I=I1; I<=I2; I++) {
-
- /* Work out the weight: */
-
- if (constant_weights) {
- ;
- } else if (! blend) {
- /*
- * Ugh, PseudoColor colormap is
- * bad news, to avoid random
- * colors just take the first
- * pixel. Or user may have
- * specified :nb to fraction.
- * The :fb will force blending
- * for this case.
- */
- if (I != I1) {
- continue;
- }
- wx = 1.0;
-
- /* interpolation scheme: */
- } else if (! shrink || interpolate) {
- if (I >= Nx) {
- continue; /* off edge */
- } else if (I == I1) {
- wx = 1.0 - ddx;
- } else if (I != I1) {
- wx = ddx;
- }
-
- /* integration scheme: */
- } else if (I < x1) {
- /*
- * source left edge (I) to the
- * left of dest left edge (x1):
- * fractional weight
- */
- wx = I+1 - x1;
- } else if (I+1 > x2) {
- /*
- * source right edge (I+1) to the
- * right of dest right edge (x2):
- * fractional weight
- */
- wx = x2 - I;
- } else {
- /*
- * source edges (I and I+1) completely
- * inside dest edges (x1 and x2):
- * full weight
- */
- wx = 1.0;
- }
-
- w = wx * wy;
- wtot += w;
-
- /*
- * We average the unsigned char value
- * instead of char value: otherwise
- * the minimum (char 0) is right next
- * to the maximum (char -1)! This way
- * they are spread between 0 and 255.
- */
- if (Bpp == 4) {
- /* unroll the loops, can give 20% */
- pixave[0] += w * ((unsigned char) *(src ));
- pixave[1] += w * ((unsigned char) *(src+1));
- pixave[2] += w * ((unsigned char) *(src+2));
- pixave[3] += w * ((unsigned char) *(src+3));
- } else if (Bpp == 2) {
- /*
- * 16bpp: trickier with green
- * split over two bytes, so we
- * use the masks:
- */
- us = *((unsigned short *) src);
- pixave[0] += w*(us & main_red_mask);
- pixave[1] += w*(us & main_green_mask);
- pixave[2] += w*(us & main_blue_mask);
- } else if (Bpp == 1) {
- pixave[0] += w *
- ((unsigned char) *(src));
- } else {
- for (b=0; b<Bpp; b++) {
- pixave[b] += w *
- ((unsigned char) *(src+b));
- }
- }
- src += Bpp;
- }
- }
-
- if (wtot <= 0.0) {
- wtot = 1.0;
- }
- wtot = 1.0/wtot; /* normalization factor */
-
- /* place weighted average pixel in the scaled fb: */
- if (Bpp == 4) {
- *(dest ) = (char) (wtot * pixave[0]);
- *(dest+1) = (char) (wtot * pixave[1]);
- *(dest+2) = (char) (wtot * pixave[2]);
- *(dest+3) = (char) (wtot * pixave[3]);
- } else if (Bpp == 2) {
- /* 16bpp / 565 case: */
- pixave[0] *= wtot;
- pixave[1] *= wtot;
- pixave[2] *= wtot;
- us = (main_red_mask & (int) pixave[0])
- | (main_green_mask & (int) pixave[1])
- | (main_blue_mask & (int) pixave[2]);
- *( (unsigned short *) dest ) = us;
- } else if (Bpp == 1) {
- *(dest) = (char) (wtot * pixave[0]);
- } else {
- for (b=0; b<Bpp; b++) {
- *(dest+b) = (char) (wtot * pixave[b]);
- }
- }
- dest += Bpp;
- }
- }
- markit:
- if (mark) {
- mark_rect_as_modified(i1, j1, i2, j2, 1);
- }
-}
-
-/*
- Framebuffers data flow:
-
- General case:
- -------- -------- -------- --------
- ----- |8to24_fb| |main_fb | |snap_fb | | X |
- |rfbfb| <== | | <== | | <== | | <== | Server |
- ----- -------- -------- -------- --------
- (to vnc) (optional) (usu = rfbfb) (optional) (read only)
-
- 8to24_fb mode will create side fbs: poll24_fb and poll8_fb for
- bookkeepping the different regions (merged into 8to24_fb).
-
- Normal case:
- -------- --------
- |main_fb | | X |
- |= rfb_fb| <== | Server |
- -------- --------
-
- Scaling case:
- -------- --------
- ----- |main_fb | | X |
- |rfbfb| <== | | <== | Server |
- ----- -------- --------
-
- Webcam/video case:
- -------- -------- --------
- |main_fb | |snap_fb | | Video |
- | | <== | | <== | device |
- -------- -------- --------
-
-If we ever do a -rr rotation/reflection tran, it probably should
-be done after any scaling (need a rr_fb for intermediate results)
-
--rr option: transformation:
-
- none x -> x;
- y -> y;
-
- x x -> w - x - 1;
- y -> y;
-
- y x -> x;
- x -> h - y - 1;
-
- xy x -> w - x - 1;
- y -> h - y - 1;
-
- +90 x -> h - y - 1;
- y -> x;
-
- +90x x -> y;
- y -> x;
-
- +90y x -> h - y - 1;
- y -> w - x - 1;
-
- -90 x -> y;
- y -> w - x - 1;
-
-some aliases:
-
- xy: yx, +180, -180, 180
- +90: 90
- +90x: 90x
- +90y: 90y
- -90: +270, 270
- */
-
-void scale_and_mark_rect(int X1, int Y1, int X2, int Y2, int mark) {
- char *dst_fb, *src_fb = main_fb;
- int dst_bpl, Bpp = bpp/8, fac = 1;
-
- if (!screen || !rfb_fb || !main_fb) {
- return;
- }
- if (! screen->serverFormat.trueColour) {
- /*
- * PseudoColor colormap... blending leads to random colors.
- * User can override with ":fb"
- */
- if (scaling_blend == 1) {
- /* :fb option sets it to 2 */
- if (default_visual->class == StaticGray) {
- /*
- * StaticGray can be blended OK, otherwise
- * user can disable with :nb
- */
- ;
- } else {
- scaling_blend = 0;
- }
- }
- }
-
- if (cmap8to24 && cmap8to24_fb) {
- src_fb = cmap8to24_fb;
- if (scaling) {
- if (depth <= 8) {
- fac = 4;
- } else if (depth <= 16) {
- fac = 2;
- }
- }
- }
- dst_fb = rfb_fb;
- dst_bpl = rfb_bytes_per_line;
-
- scale_rect(scale_fac_x, scale_fac_y, scaling_blend, scaling_interpolate, fac * Bpp,
- src_fb, fac * main_bytes_per_line, dst_fb, dst_bpl, dpy_x, dpy_y,
- scaled_x, scaled_y, X1, Y1, X2, Y2, mark);
-}
-
-void rotate_coords(int x, int y, int *xo, int *yo, int dxi, int dyi) {
- int xi = x, yi = y;
- int Dx, Dy;
-
- if (dxi >= 0) {
- Dx = dxi;
- Dy = dyi;
- } else if (scaling) {
- Dx = scaled_x;
- Dy = scaled_y;
- } else {
- Dx = dpy_x;
- Dy = dpy_y;
- }
-
- /* ncache?? */
-
- if (rotating == ROTATE_NONE) {
- *xo = xi;
- *yo = yi;
- } else if (rotating == ROTATE_X) {
- *xo = Dx - xi - 1;
- *yo = yi;
- } else if (rotating == ROTATE_Y) {
- *xo = xi;
- *yo = Dy - yi - 1;
- } else if (rotating == ROTATE_XY) {
- *xo = Dx - xi - 1;
- *yo = Dy - yi - 1;
- } else if (rotating == ROTATE_90) {
- *xo = Dy - yi - 1;
- *yo = xi;
- } else if (rotating == ROTATE_90X) {
- *xo = yi;
- *yo = xi;
- } else if (rotating == ROTATE_90Y) {
- *xo = Dy - yi - 1;
- *yo = Dx - xi - 1;
- } else if (rotating == ROTATE_270) {
- *xo = yi;
- *yo = Dx - xi - 1;
- }
-}
-
-void rotate_coords_inverse(int x, int y, int *xo, int *yo, int dxi, int dyi) {
- int xi = x, yi = y;
-
- int Dx, Dy;
-
- if (dxi >= 0) {
- Dx = dxi;
- Dy = dyi;
- } else if (scaling) {
- Dx = scaled_x;
- Dy = scaled_y;
- } else {
- Dx = dpy_x;
- Dy = dpy_y;
- }
- if (! rotating_same) {
- int t = Dx;
- Dx = Dy;
- Dy = t;
- }
-
- if (rotating == ROTATE_NONE) {
- *xo = xi;
- *yo = yi;
- } else if (rotating == ROTATE_X) {
- *xo = Dx - xi - 1;
- *yo = yi;
- } else if (rotating == ROTATE_Y) {
- *xo = xi;
- *yo = Dy - yi - 1;
- } else if (rotating == ROTATE_XY) {
- *xo = Dx - xi - 1;
- *yo = Dy - yi - 1;
- } else if (rotating == ROTATE_90) {
- *xo = yi;
- *yo = Dx - xi - 1;
- } else if (rotating == ROTATE_90X) {
- *xo = yi;
- *yo = xi;
- } else if (rotating == ROTATE_90Y) {
- *xo = Dy - yi - 1;
- *yo = Dx - xi - 1;
- } else if (rotating == ROTATE_270) {
- *xo = Dy - yi - 1;
- *yo = xi;
- }
-}
-
- /* unroll the Bpp loop to be used in each case: */
-#define ROT_COPY \
- src = src_0 + fbl*y + Bpp*x; \
- dst = dst_0 + rbl*yn + Bpp*xn; \
- if (Bpp == 1) { \
- *(dst) = *(src); \
- } else if (Bpp == 2) { \
- *(dst+0) = *(src+0); \
- *(dst+1) = *(src+1); \
- } else if (Bpp == 3) { \
- *(dst+0) = *(src+0); \
- *(dst+1) = *(src+1); \
- *(dst+2) = *(src+2); \
- } else if (Bpp == 4) { \
- *(dst+0) = *(src+0); \
- *(dst+1) = *(src+1); \
- *(dst+2) = *(src+2); \
- *(dst+3) = *(src+3); \
- }
-
-void rotate_fb(int x1, int y1, int x2, int y2) {
- int x, y, xn, yn, r_x1, r_y1, r_x2, r_y2, Bpp = bpp/8;
- int fbl = rfb_bytes_per_line;
- int rbl = rot_bytes_per_line;
- int Dx, Dy;
- char *src, *dst;
- char *src_0 = rfb_fb;
- char *dst_0 = rot_fb;
-
- if (! rotating || ! rot_fb) {
- return;
- }
-
- if (scaling) {
- Dx = scaled_x;
- Dy = scaled_y;
- } else {
- Dx = dpy_x;
- Dy = dpy_y;
- }
- rotate_coords(x1, y1, &r_x1, &r_y1, -1, -1);
- rotate_coords(x2, y2, &r_x2, &r_y2, -1, -1);
-
- dst = rot_fb;
-
- if (rotating == ROTATE_X) {
- for (y = y1; y < y2; y++) {
- for (x = x1; x < x2; x++) {
- xn = Dx - x - 1;
- yn = y;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_Y) {
- for (y = y1; y < y2; y++) {
- for (x = x1; x < x2; x++) {
- xn = x;
- yn = Dy - y - 1;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_XY) {
- for (y = y1; y < y2; y++) {
- for (x = x1; x < x2; x++) {
- xn = Dx - x - 1;
- yn = Dy - y - 1;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_90) {
- for (y = y1; y < y2; y++) {
- for (x = x1; x < x2; x++) {
- xn = Dy - y - 1;
- yn = x;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_90X) {
- for (y = y1; y < y2; y++) {
- for (x = x1; x < x2; x++) {
- xn = y;
- yn = x;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_90Y) {
- for (y = y1; y < y2; y++) {
- for (x = x1; x < x2; x++) {
- xn = Dy - y - 1;
- yn = Dx - x - 1;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_270) {
- for (y = y1; y < y2; y++) {
- for (x = x1; x < x2; x++) {
- xn = y;
- yn = Dx - x - 1;
- ROT_COPY
- }
- }
- }
-}
-
-void rotate_curs(char *dst_0, char *src_0, int Dx, int Dy, int Bpp) {
- int x, y, xn, yn;
- char *src, *dst;
- int fbl, rbl;
-
- if (! rotating) {
- return;
- }
-
- fbl = Dx * Bpp;
- if (rotating_same) {
- rbl = Dx * Bpp;
- } else {
- rbl = Dy * Bpp;
- }
-
- if (rotating == ROTATE_X) {
- for (y = 0; y < Dy; y++) {
- for (x = 0; x < Dx; x++) {
- xn = Dx - x - 1;
- yn = y;
- ROT_COPY
-if (0) fprintf(stderr, "rcurs: %d %d %d %d\n", x, y, xn, yn);
- }
- }
- } else if (rotating == ROTATE_Y) {
- for (y = 0; y < Dy; y++) {
- for (x = 0; x < Dx; x++) {
- xn = x;
- yn = Dy - y - 1;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_XY) {
- for (y = 0; y < Dy; y++) {
- for (x = 0; x < Dx; x++) {
- xn = Dx - x - 1;
- yn = Dy - y - 1;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_90) {
- for (y = 0; y < Dy; y++) {
- for (x = 0; x < Dx; x++) {
- xn = Dy - y - 1;
- yn = x;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_90X) {
- for (y = 0; y < Dy; y++) {
- for (x = 0; x < Dx; x++) {
- xn = y;
- yn = x;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_90Y) {
- for (y = 0; y < Dy; y++) {
- for (x = 0; x < Dx; x++) {
- xn = Dy - y - 1;
- yn = Dx - x - 1;
- ROT_COPY
- }
- }
- } else if (rotating == ROTATE_270) {
- for (y = 0; y < Dy; y++) {
- for (x = 0; x < Dx; x++) {
- xn = y;
- yn = Dx - x - 1;
- ROT_COPY
- }
- }
- }
-}
-
-void mark_wrapper(int x1, int y1, int x2, int y2) {
- int t, r_x1 = x1, r_y1 = y1, r_x2 = x2, r_y2 = y2;
-
- if (rotating) {
- /* well we hope rot_fb will always be the last one... */
- rotate_coords(x1, y1, &r_x1, &r_y1, -1, -1);
- rotate_coords(x2, y2, &r_x2, &r_y2, -1, -1);
- rotate_fb(x1, y1, x2, y2);
- if (r_x1 > r_x2) {
- t = r_x1;
- r_x1 = r_x2;
- r_x2 = t;
- }
- if (r_y1 > r_y2) {
- t = r_y1;
- r_y1 = r_y2;
- r_y2 = t;
- }
- /* painting errors */
- r_x1--;
- r_x2++;
- r_y1--;
- r_y2++;
- }
- rfbMarkRectAsModified(screen, r_x1, r_y1, r_x2, r_y2);
-}
-
-void mark_rect_as_modified(int x1, int y1, int x2, int y2, int force) {
-
- if (damage_time != 0) {
- /*
- * This is not XDAMAGE, rather a hack for testing
- * where we allow the framebuffer to be corrupted for
- * damage_delay seconds.
- */
- int debug = 0;
- if (time(NULL) > damage_time + damage_delay) {
- if (! quiet) {
- rfbLog("damaging turned off.\n");
- }
- damage_time = 0;
- damage_delay = 0;
- } else {
- if (debug) {
- rfbLog("damaging viewer fb by not marking "
- "rect: %d,%d,%d,%d\n", x1, y1, x2, y2);
- }
- return;
- }
- }
-
-
- if (rfb_fb == main_fb || force) {
- mark_wrapper(x1, y1, x2, y2);
- return;
- }
-
- if (cmap8to24) {
- bpp8to24(x1, y1, x2, y2);
- }
-
- if (scaling) {
- scale_and_mark_rect(x1, y1, x2, y2, 1);
- } else {
- mark_wrapper(x1, y1, x2, y2);
- }
-}
-
-/*
- * Notifies libvncserver of a changed hint rectangle.
- */
-static void mark_hint(hint_t hint) {
- int x = hint.x;
- int y = hint.y;
- int w = hint.w;
- int h = hint.h;
-
- mark_rect_as_modified(x, y, x + w, y + h, 0);
-}
-
-/*
- * copy_tiles() gives a slight improvement over copy_tile() since
- * adjacent runs of tiles are done all at once there is some savings
- * due to contiguous memory access. Not a great speedup, but in some
- * cases it can be up to 2X. Even more on a SunRay or ShadowFB where
- * no graphics hardware is involved in the read. Generally, graphics
- * devices are optimized for write, not read, so we are limited by the
- * read bandwidth, sometimes only 5 MB/sec on otherwise fast hardware.
- */
-static int *first_line = NULL, *last_line = NULL;
-static unsigned short *left_diff = NULL, *right_diff = NULL;
-
-static int copy_tiles(int tx, int ty, int nt) {
- int x, y, line;
- int size_x, size_y, width1, width2;
- int off, len, n, dw, dx, t;
- int w1, w2, dx1, dx2; /* tmps for normal and short tiles */
- int pixelsize = bpp/8;
- int first_min, last_max;
- int first_x = -1, last_x = -1;
- static int prev_ntiles_x = -1;
-
- char *src, *dst, *s_src, *s_dst, *m_src, *m_dst;
- char *h_src, *h_dst;
- if (unixpw_in_progress) return 0;
-
- if (ntiles_x != prev_ntiles_x && first_line != NULL) {
- free(first_line); first_line = NULL;
- free(last_line); last_line = NULL;
- free(left_diff); left_diff = NULL;
- free(right_diff); right_diff = NULL;
- }
-
- if (first_line == NULL) {
- /* allocate arrays first time in. */
- int n = ntiles_x + 1;
- rfbLog("copy_tiles: allocating first_line at size %d\n", n);
- first_line = (int *) malloc((size_t) (n * sizeof(int)));
- last_line = (int *) malloc((size_t) (n * sizeof(int)));
- left_diff = (unsigned short *)
- malloc((size_t) (n * sizeof(unsigned short)));
- right_diff = (unsigned short *)
- malloc((size_t) (n * sizeof(unsigned short)));
- }
- prev_ntiles_x = ntiles_x;
-
- x = tx * tile_x;
- y = ty * tile_y;
-
- size_x = dpy_x - x;
- if ( size_x > tile_x * nt ) {
- size_x = tile_x * nt;
- width1 = tile_x;
- width2 = tile_x;
- } else {
- /* short tile */
- width1 = tile_x; /* internal tile */
- width2 = size_x - (nt - 1) * tile_x; /* right hand tile */
- }
-
- size_y = dpy_y - y;
- if ( size_y > tile_y ) {
- size_y = tile_y;
- }
-
- n = tx + ty * ntiles_x; /* number of the first tile */
-
- if (blackouts && tile_blackout[n].cover == 2) {
- /*
- * If there are blackouts and this tile is completely covered
- * no need to poll screen or do anything else..
- * n.b. we are in single copy_tile mode: nt=1
- */
- tile_has_diff[n] = 0;
- return(0);
- }
-
- X_LOCK;
- XRANDR_SET_TRAP_RET(-1, "copy_tile-set");
- /* read in the whole tile run at once: */
- copy_image(tile_row[nt], x, y, size_x, size_y);
- XRANDR_CHK_TRAP_RET(-1, "copy_tile-chk");
-
-
- X_UNLOCK;
-
- if (blackouts && tile_blackout[n].cover == 1) {
- /*
- * If there are blackouts and this tile is partially covered
- * we should re-black-out the portion.
- * n.b. we are in single copy_tile mode: nt=1
- */
- int x1, x2, y1, y2, b;
- int w, s, fill = 0;
-
- for (b=0; b < tile_blackout[n].count; b++) {
- char *b_dst = tile_row[nt]->data;
-
- x1 = tile_blackout[n].bo[b].x1 - x;
- y1 = tile_blackout[n].bo[b].y1 - y;
- x2 = tile_blackout[n].bo[b].x2 - x;
- y2 = tile_blackout[n].bo[b].y2 - y;
-
- w = (x2 - x1) * pixelsize;
- s = x1 * pixelsize;
-
- for (line = 0; line < size_y; line++) {
- if (y1 <= line && line < y2) {
- memset(b_dst + s, fill, (size_t) w);
- }
- b_dst += tile_row[nt]->bytes_per_line;
- }
- }
- }
-
- src = tile_row[nt]->data;
- dst = main_fb + y * main_bytes_per_line + x * pixelsize;
-
- s_src = src;
- s_dst = dst;
-
- for (t=1; t <= nt; t++) {
- first_line[t] = -1;
- }
-
- /* find the first line with difference: */
- w1 = width1 * pixelsize;
- w2 = width2 * pixelsize;
-
- /* foreach line: */
- for (line = 0; line < size_y; line++) {
- /* foreach horizontal tile: */
- for (t=1; t <= nt; t++) {
- if (first_line[t] != -1) {
- continue;
- }
-
- off = (t-1) * w1;
- if (t == nt) {
- len = w2; /* possible short tile */
- } else {
- len = w1;
- }
-
- if (memcmp(s_dst + off, s_src + off, len)) {
- first_line[t] = line;
- }
- }
- s_src += tile_row[nt]->bytes_per_line;
- s_dst += main_bytes_per_line;
- }
-
- /* see if there were any differences for any tile: */
- first_min = -1;
- for (t=1; t <= nt; t++) {
- tile_tried[n+(t-1)] = 1;
- if (first_line[t] != -1) {
- if (first_min == -1 || first_line[t] < first_min) {
- first_min = first_line[t];
- }
- }
- }
- if (first_min == -1) {
- /* no tile has a difference, note this and get out: */
- for (t=1; t <= nt; t++) {
- tile_has_diff[n+(t-1)] = 0;
- }
- return(0);
- } else {
- /*
- * at least one tile has a difference. make sure info
- * is recorded (e.g. sometimes we guess tiles and they
- * came in with tile_has_diff 0)
- */
- for (t=1; t <= nt; t++) {
- if (first_line[t] == -1) {
- tile_has_diff[n+(t-1)] = 0;
- } else {
- tile_has_diff[n+(t-1)] = 1;
- }
- }
- }
-
- m_src = src + (tile_row[nt]->bytes_per_line * size_y);
- m_dst = dst + (main_bytes_per_line * size_y);
-
- for (t=1; t <= nt; t++) {
- last_line[t] = first_line[t];
- }
-
- /* find the last line with difference: */
- w1 = width1 * pixelsize;
- w2 = width2 * pixelsize;
-
- /* foreach line: */
- for (line = size_y - 1; line > first_min; line--) {
-
- m_src -= tile_row[nt]->bytes_per_line;
- m_dst -= main_bytes_per_line;
-
- /* foreach tile: */
- for (t=1; t <= nt; t++) {
- if (first_line[t] == -1
- || last_line[t] != first_line[t]) {
- /* tile has no changes or already done */
- continue;
- }
-
- off = (t-1) * w1;
- if (t == nt) {
- len = w2; /* possible short tile */
- } else {
- len = w1;
- }
- if (memcmp(m_dst + off, m_src + off, len)) {
- last_line[t] = line;
- }
- }
- }
-
- /*
- * determine the farthest down last changed line
- * will be used below to limit our memcpy() to the framebuffer.
- */
- last_max = -1;
- for (t=1; t <= nt; t++) {
- if (first_line[t] == -1) {
- continue;
- }
- if (last_max == -1 || last_line[t] > last_max) {
- last_max = last_line[t];
- }
- }
-
- /* look for differences on left and right hand edges: */
- for (t=1; t <= nt; t++) {
- left_diff[t] = 0;
- right_diff[t] = 0;
- }
-
- h_src = src;
- h_dst = dst;
-
- w1 = width1 * pixelsize;
- w2 = width2 * pixelsize;
-
- dx1 = (width1 - tile_fuzz) * pixelsize;
- dx2 = (width2 - tile_fuzz) * pixelsize;
- dw = tile_fuzz * pixelsize;
-
- /* foreach line: */
- for (line = 0; line < size_y; line++) {
- /* foreach tile: */
- for (t=1; t <= nt; t++) {
- if (first_line[t] == -1) {
- /* tile has no changes at all */
- continue;
- }
-
- off = (t-1) * w1;
- if (t == nt) {
- dx = dx2; /* possible short tile */
- if (dx <= 0) {
- break;
- }
- } else {
- dx = dx1;
- }
-
- if (! left_diff[t] && memcmp(h_dst + off,
- h_src + off, dw)) {
- left_diff[t] = 1;
- }
- if (! right_diff[t] && memcmp(h_dst + off + dx,
- h_src + off + dx, dw) ) {
- right_diff[t] = 1;
- }
- }
- h_src += tile_row[nt]->bytes_per_line;
- h_dst += main_bytes_per_line;
- }
-
- /* now finally copy the difference to the rfb framebuffer: */
- s_src = src + tile_row[nt]->bytes_per_line * first_min;
- s_dst = dst + main_bytes_per_line * first_min;
-
- for (line = first_min; line <= last_max; line++) {
- /* for I/O speed we do not do this tile by tile */
- memcpy(s_dst, s_src, size_x * pixelsize);
- if (nt == 1) {
- /*
- * optimization for tall skinny lines, e.g. wm
- * frame. try to find first_x and last_x to limit
- * the size of the hint. could help for a slow
- * link. Unfortunately we spent a lot of time
- * reading in the many tiles.
- *
- * BTW, we like to think the above memcpy leaves
- * the data we use below in the cache... (but
- * it could be two 128 byte segments at 32bpp)
- * so this inner loop is not as bad as it seems.
- */
- int k, kx;
- kx = pixelsize;
- for (k=0; k<size_x; k++) {
- if (memcmp(s_dst + k*kx, s_src + k*kx, kx)) {
- if (first_x == -1 || k < first_x) {
- first_x = k;
- }
- if (last_x == -1 || k > last_x) {
- last_x = k;
- }
- }
- }
- }
- s_src += tile_row[nt]->bytes_per_line;
- s_dst += main_bytes_per_line;
- }
-
- /* record all the info in the region array for this tile: */
- for (t=1; t <= nt; t++) {
- int s = t - 1;
-
- if (first_line[t] == -1) {
- /* tile unchanged */
- continue;
- }
- tile_region[n+s].first_line = first_line[t];
- tile_region[n+s].last_line = last_line[t];
-
- tile_region[n+s].first_x = first_x;
- tile_region[n+s].last_x = last_x;
-
- tile_region[n+s].top_diff = 0;
- tile_region[n+s].bot_diff = 0;
- if ( first_line[t] < tile_fuzz ) {
- tile_region[n+s].top_diff = 1;
- }
- if ( last_line[t] > (size_y - 1) - tile_fuzz ) {
- tile_region[n+s].bot_diff = 1;
- }
-
- tile_region[n+s].left_diff = left_diff[t];
- tile_region[n+s].right_diff = right_diff[t];
-
- tile_copied[n+s] = 1;
- }
-
- return(1);
-}
-
-/*
- * The copy_tile() call in the loop below copies the changed tile into
- * the rfb framebuffer. Note that copy_tile() sets the tile_region
- * struct to have info about the y-range of the changed region and also
- * whether the tile edges contain diffs (within distance tile_fuzz).
- *
- * We use this tile_region info to try to guess if the downward and right
- * tiles will have diffs. These tiles will be checked later in the loop
- * (since y+1 > y and x+1 > x).
- *
- * See copy_tiles_backward_pass() for analogous checking upward and
- * left tiles.
- */
-static int copy_all_tiles(void) {
- int x, y, n, m;
- int diffs = 0, ct;
-
- if (unixpw_in_progress) return 0;
-
- for (y=0; y < ntiles_y; y++) {
- for (x=0; x < ntiles_x; x++) {
- n = x + y * ntiles_x;
-
- if (tile_has_diff[n]) {
- ct = copy_tiles(x, y, 1);
- if (ct < 0) return ct; /* fatal */
- }
- if (! tile_has_diff[n]) {
- /*
- * n.b. copy_tiles() may have detected
- * no change and reset tile_has_diff to 0.
- */
- continue;
- }
- diffs++;
-
- /* neighboring tile downward: */
- if ( (y+1) < ntiles_y && tile_region[n].bot_diff) {
- m = x + (y+1) * ntiles_x;
- if (! tile_has_diff[m]) {
- tile_has_diff[m] = 2;
- }
- }
- /* neighboring tile to right: */
- if ( (x+1) < ntiles_x && tile_region[n].right_diff) {
- m = (x+1) + y * ntiles_x;
- if (! tile_has_diff[m]) {
- tile_has_diff[m] = 2;
- }
- }
- }
- }
- return diffs;
-}
-
-/*
- * Routine analogous to copy_all_tiles() above, but for horizontal runs
- * of adjacent changed tiles.
- */
-static int copy_all_tile_runs(void) {
- int x, y, n, m, i;
- int diffs = 0, ct;
- int in_run = 0, run = 0;
- int ntave = 0, ntcnt = 0;
-
- if (unixpw_in_progress) return 0;
-
- for (y=0; y < ntiles_y; y++) {
- for (x=0; x < ntiles_x + 1; x++) {
- n = x + y * ntiles_x;
-
- if (x != ntiles_x && tile_has_diff[n]) {
- in_run = 1;
- run++;
- } else {
- if (! in_run) {
- in_run = 0;
- run = 0;
- continue;
- }
- ct = copy_tiles(x - run, y, run);
- if (ct < 0) return ct; /* fatal */
-
- ntcnt++;
- ntave += run;
- diffs += run;
-
- /* neighboring tile downward: */
- for (i=1; i <= run; i++) {
- if ((y+1) < ntiles_y
- && tile_region[n-i].bot_diff) {
- m = (x-i) + (y+1) * ntiles_x;
- if (! tile_has_diff[m]) {
- tile_has_diff[m] = 2;
- }
- }
- }
-
- /* neighboring tile to right: */
- if (((x-1)+1) < ntiles_x
- && tile_region[n-1].right_diff) {
- m = ((x-1)+1) + y * ntiles_x;
- if (! tile_has_diff[m]) {
- tile_has_diff[m] = 2;
- }
-
- /* note that this starts a new run */
- in_run = 1;
- run = 1;
- } else {
- in_run = 0;
- run = 0;
- }
- }
- }
- /*
- * Could some activity go here, to emulate threaded
- * behavior by servicing some libvncserver tasks?
- */
- }
- return diffs;
-}
-
-/*
- * Here starts a bunch of heuristics to guess/detect changed tiles.
- * They are:
- * copy_tiles_backward_pass, fill_tile_gaps/gap_try, grow_islands/island_try
- */
-
-/*
- * Try to predict whether the upward and/or leftward tile has been modified.
- * copy_all_tiles() has already done downward and rightward tiles.
- */
-static int copy_tiles_backward_pass(void) {
- int x, y, n, m;
- int diffs = 0, ct;
-
- if (unixpw_in_progress) return 0;
-
- for (y = ntiles_y - 1; y >= 0; y--) {
- for (x = ntiles_x - 1; x >= 0; x--) {
- n = x + y * ntiles_x; /* number of this tile */
-
- if (! tile_has_diff[n]) {
- continue;
- }
-
- m = x + (y-1) * ntiles_x; /* neighboring tile upward */
-
- if (y >= 1 && ! tile_has_diff[m] && tile_region[n].top_diff) {
- if (! tile_tried[m]) {
- tile_has_diff[m] = 2;
- ct = copy_tiles(x, y-1, 1);
- if (ct < 0) return ct; /* fatal */
- }
- }
-
- m = (x-1) + y * ntiles_x; /* neighboring tile to left */
-
- if (x >= 1 && ! tile_has_diff[m] && tile_region[n].left_diff) {
- if (! tile_tried[m]) {
- tile_has_diff[m] = 2;
- ct = copy_tiles(x-1, y, 1);
- if (ct < 0) return ct; /* fatal */
- }
- }
- }
- }
- for (n=0; n < ntiles; n++) {
- if (tile_has_diff[n]) {
- diffs++;
- }
- }
- return diffs;
-}
-
-static int copy_tiles_additional_pass(void) {
- int x, y, n;
- int diffs = 0, ct;
-
- if (unixpw_in_progress) return 0;
-
- for (y=0; y < ntiles_y; y++) {
- for (x=0; x < ntiles_x; x++) {
- n = x + y * ntiles_x; /* number of this tile */
-
- if (! tile_has_diff[n]) {
- continue;
- }
- if (tile_copied[n]) {
- continue;
- }
-
- ct = copy_tiles(x, y, 1);
- if (ct < 0) return ct; /* fatal */
- }
- }
- for (n=0; n < ntiles; n++) {
- if (tile_has_diff[n]) {
- diffs++;
- }
- }
- return diffs;
-}
-
-static int gap_try(int x, int y, int *run, int *saw, int along_x) {
- int n, m, i, xt, yt, ct;
-
- n = x + y * ntiles_x;
-
- if (! tile_has_diff[n]) {
- if (*saw) {
- (*run)++; /* extend the gap run. */
- }
- return 0;
- }
- if (! *saw || *run == 0 || *run > gaps_fill) {
- *run = 0; /* unacceptable run. */
- *saw = 1;
- return 0;
- }
-
- for (i=1; i <= *run; i++) { /* iterate thru the run. */
- if (along_x) {
- xt = x - i;
- yt = y;
- } else {
- xt = x;
- yt = y - i;
- }
-
- m = xt + yt * ntiles_x;
- if (tile_tried[m]) { /* do not repeat tiles */
- continue;
- }
-
- ct = copy_tiles(xt, yt, 1);
- if (ct < 0) return ct; /* fatal */
- }
- *run = 0;
- *saw = 1;
- return 1;
-}
-
-/*
- * Look for small gaps of unchanged tiles that may actually contain changes.
- * E.g. when paging up and down in a web broswer or terminal there can
- * be a distracting delayed filling in of such gaps. gaps_fill is the
- * tweak parameter that sets the width of the gaps that are checked.
- *
- * BTW, grow_islands() is actually pretty successful at doing this too...
- */
-static int fill_tile_gaps(void) {
- int x, y, run, saw;
- int n, diffs = 0, ct;
-
- /* horizontal: */
- for (y=0; y < ntiles_y; y++) {
- run = 0;
- saw = 0;
- for (x=0; x < ntiles_x; x++) {
- ct = gap_try(x, y, &run, &saw, 1);
- if (ct < 0) return ct; /* fatal */
- }
- }
-
- /* vertical: */
- for (x=0; x < ntiles_x; x++) {
- run = 0;
- saw = 0;
- for (y=0; y < ntiles_y; y++) {
- ct = gap_try(x, y, &run, &saw, 0);
- if (ct < 0) return ct; /* fatal */
- }
- }
-
- for (n=0; n < ntiles; n++) {
- if (tile_has_diff[n]) {
- diffs++;
- }
- }
- return diffs;
-}
-
-static int island_try(int x, int y, int u, int v, int *run) {
- int n, m, ct;
-
- n = x + y * ntiles_x;
- m = u + v * ntiles_x;
-
- if (tile_has_diff[n]) {
- (*run)++;
- } else {
- *run = 0;
- }
-
- if (tile_has_diff[n] && ! tile_has_diff[m]) {
- /* found a discontinuity */
-
- if (tile_tried[m]) {
- return 0;
- } else if (*run < grow_fill) {
- return 0;
- }
-
- ct = copy_tiles(u, v, 1);
- if (ct < 0) return ct; /* fatal */
- }
- return 1;
-}
-
-/*
- * Scan looking for discontinuities in tile_has_diff[]. Try to extend
- * the boundary of the discontinuity (i.e. make the island larger).
- * Vertical scans are skipped since they do not seem to yield much...
- */
-static int grow_islands(void) {
- int x, y, n, run;
- int diffs = 0, ct;
-
- /*
- * n.b. the way we scan here should keep an extension going,
- * and so also fill in gaps effectively...
- */
-
- /* left to right: */
- for (y=0; y < ntiles_y; y++) {
- run = 0;
- for (x=0; x <= ntiles_x - 2; x++) {
- ct = island_try(x, y, x+1, y, &run);
- if (ct < 0) return ct; /* fatal */
- }
- }
- /* right to left: */
- for (y=0; y < ntiles_y; y++) {
- run = 0;
- for (x = ntiles_x - 1; x >= 1; x--) {
- ct = island_try(x, y, x-1, y, &run);
- if (ct < 0) return ct; /* fatal */
- }
- }
- for (n=0; n < ntiles; n++) {
- if (tile_has_diff[n]) {
- diffs++;
- }
- }
- return diffs;
-}
-
-/*
- * Fill the framebuffer with zeros for each blackout region
- */
-static void blackout_regions(void) {
- int i;
- for (i=0; i < blackouts; i++) {
- zero_fb(blackr[i].x1, blackr[i].y1, blackr[i].x2, blackr[i].y2);
- }
-}
-
-/*
- * copy the whole X screen to the rfb framebuffer. For a large enough
- * number of changed tiles, this is faster than tiles scheme at retrieving
- * the info from the X server. Bandwidth to client and compression time
- * are other issues... use -fs 1.0 to disable.
- */
-int copy_screen(void) {
- char *fbp;
- int i, y, block_size;
-
- if (! fs_factor) {
- return 0;
- }
- if (debug_tiles) fprintf(stderr, "copy_screen\n");
-
- if (unixpw_in_progress) return 0;
-
-
- if (! main_fb) {
- return 0;
- }
-
- block_size = ((dpy_y/fs_factor) * main_bytes_per_line);
-
- fbp = main_fb;
- y = 0;
-
- X_LOCK;
-
- /* screen may be too big for 1 shm area, so broken into fs_factor */
- for (i=0; i < fs_factor; i++) {
- XRANDR_SET_TRAP_RET(-1, "copy_screen-set");
- copy_image(fullscreen, 0, y, 0, 0);
- XRANDR_CHK_TRAP_RET(-1, "copy_screen-chk");
-
- memcpy(fbp, fullscreen->data, (size_t) block_size);
-
- y += dpy_y / fs_factor;
- fbp += block_size;
- }
-
- X_UNLOCK;
-
- if (blackouts) {
- blackout_regions();
- }
-
- mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
- return 0;
-}
-
-#include <rfb/default8x16.h>
-
-/*
- * 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;
- fake_screen->width = snap->width;
- fake_screen->height = snap->height;
-
- 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;
- char *dst;
- static char *unclipped_dst = NULL;
- static int unclipped_len = 0;
-
- dst = snap->data;
-
- if (xform24to32 && bpp == 32) {
- pixelsize = 3;
- }
- sz = dpy_y * snap->bytes_per_line;
-
- if (wdpy_x > dpy_x || wdpy_y > dpy_y) {
- sz = wdpy_x * wdpy_y * pixelsize;
- if (sz > unclipped_len || unclipped_dst == NULL) {
- if (unclipped_dst) {
- free(unclipped_dst);
- }
- unclipped_dst = (char *) malloc(sz+4);
- unclipped_len = sz;
- }
- dst = unclipped_dst;
- }
-
- if (! raw_fb_seek) {
- memcpy(dst, raw_fb_addr + raw_fb_offset, sz);
-
- } else {
- int len = sz, del = 0;
- off_t off = (off_t) raw_fb_offset;
-
- lseek(raw_fb_fd, off, SEEK_SET);
- while (len > 0) {
- n = read(raw_fb_fd, dst + del, len);
- if (n > 0) {
- del += n;
- len -= n;
- } else if (n == 0) {
- break;
- } else if (errno != EINTR && errno != EAGAIN) {
- break;
- }
- }
- }
-
- if (dst == unclipped_dst) {
- char *src;
- int h;
- int x = off_x + coff_x;
- int y = off_y + coff_y;
-
- src = unclipped_dst + y * wdpy_x * pixelsize +
- x * pixelsize;
- dst = snap->data;
-
- for (h = 0; h < dpy_y; h++) {
- memcpy(dst, src, dpy_x * pixelsize);
- src += wdpy_x * pixelsize;
- dst += snap->bytes_per_line;
- }
- }
-}
-
-int copy_snap(void) {
- int db = 1;
- char *fbp;
- int i, y, block_size;
- double dt;
- static int first = 1, snapcnt = 0;
-
- if (raw_fb_str) {
- int read_all_at_once = 1;
- double start = dnow();
- if (rawfb_reset < 0) {
- if (getenv("SNAPFB_RAWFB_RESET")) {
- rawfb_reset = 1;
- } else {
- rawfb_reset = 0;
- }
- }
- if (snap_fb == NULL || snap == NULL) {
- rfbLog("copy_snap: rawfb mode and null snap fb\n");
- clean_up_exit(1);
- }
- if (rawfb_reset) {
- initialize_raw_fb(1);
- }
- if (raw_fb_bytes_per_line != snap->bytes_per_line) {
- read_all_at_once = 0;
- }
- 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 */
- copy_raw_fb(snap, 0, 0, dpy_x, dpy_y);
- }
-if (db && snapcnt++ < 5) rfbLog("rawfb copy_snap took: %.5f secs\n", dnow() - start);
-
- return 0;
- }
-
- if (! fs_factor) {
- return 0;
- }
-
-
- if (! snap_fb || ! snap || ! snaprect) {
- return 0;
- }
- block_size = ((dpy_y/fs_factor) * snap->bytes_per_line);
-
- fbp = snap_fb;
- y = 0;
-
-
- dtime0(&dt);
- X_LOCK;
-
- /* screen may be too big for 1 shm area, so broken into fs_factor */
- for (i=0; i < fs_factor; i++) {
- XRANDR_SET_TRAP_RET(-1, "copy_snap-set");
- copy_image(snaprect, 0, y, 0, 0);
- XRANDR_CHK_TRAP_RET(-1, "copy_snap-chk");
-
- memcpy(fbp, snaprect->data, (size_t) block_size);
-
- y += dpy_y / fs_factor;
- fbp += block_size;
- }
-
- X_UNLOCK;
-
- dt = dtime(&dt);
- if (first) {
- rfbLog("copy_snap: time for -snapfb snapshot: %.3f sec\n", dt);
- first = 0;
- }
-
- return 0;
-}
-
-
-/*
- * debugging: print out a picture of the tiles.
- */
-static void print_tiles(void) {
- /* hack for viewing tile diffs on the screen. */
- static char *prev = NULL;
- int n, x, y, ms = 1500;
-
- ms = 1;
-
- if (! prev) {
- prev = (char *) malloc((size_t) ntiles);
- for (n=0; n < ntiles; n++) {
- prev[n] = 0;
- }
- }
- fprintf(stderr, " ");
- for (x=0; x < ntiles_x; x++) {
- fprintf(stderr, "%1d", x % 10);
- }
- fprintf(stderr, "\n");
- n = 0;
- for (y=0; y < ntiles_y; y++) {
- fprintf(stderr, "%2d ", y);
- for (x=0; x < ntiles_x; x++) {
- if (tile_has_diff[n]) {
- fprintf(stderr, "X");
- } else if (prev[n]) {
- fprintf(stderr, "o");
- } else {
- fprintf(stderr, ".");
- }
- n++;
- }
- fprintf(stderr, "\n");
- }
- for (n=0; n < ntiles; n++) {
- prev[n] = tile_has_diff[n];
- }
- usleep(ms * 1000);
-}
-
-/*
- * Utilities for managing the "naps" to cut down on amount of polling.
- */
-static void nap_set(int tile_cnt) {
- int nap_in = nap_ok;
- time_t now = time(NULL);
-
- if (scan_count == 0) {
- /* roll up check for all NSCAN scans */
- nap_ok = 0;
- if (naptile && nap_diff_count < 2 * NSCAN * naptile) {
- /* "2" is a fudge to permit a bit of bg drawing */
- nap_ok = 1;
- }
- nap_diff_count = 0;
- }
- if (nap_ok && ! nap_in && use_xdamage) {
- if (XD_skip > 0.8 * XD_tot) {
- /* X DAMAGE is keeping load low, so skip nap */
- nap_ok = 0;
- }
- }
- if (! nap_ok && client_count) {
- if(now > last_fb_bytes_sent + no_fbu_blank) {
- if (debug_tiles > 1) {
- fprintf(stderr, "nap_set: nap_ok=1: now: %d last: %d\n",
- (int) now, (int) last_fb_bytes_sent);
- }
- nap_ok = 1;
- }
- }
-
- if (show_cursor) {
- /* kludge for the up to 4 tiles the mouse patch could occupy */
- if ( tile_cnt > 4) {
- last_event = now;
- }
- } else if (tile_cnt != 0) {
- last_event = now;
- }
-}
-
-/*
- * split up a long nap to improve the wakeup time
- */
-void nap_sleep(int ms, int split) {
- int i, input = got_user_input;
- int gd = got_local_pointer_input;
-
- for (i=0; i<split; i++) {
- usleep(ms * 1000 / split);
- if (! use_threads && i != split - 1) {
- rfbPE(-1);
- }
- if (input != got_user_input) {
- break;
- }
- if (gd != got_local_pointer_input) {
- break;
- }
- }
-}
-
-static char *get_load(void) {
- static char tmp[64];
- static int count = 0;
-
- if (count++ % 5 == 0) {
- struct stat sb;
- memset(tmp, 0, sizeof(tmp));
- if (stat("/proc/loadavg", &sb) == 0) {
- int d = open("/proc/loadavg", O_RDONLY);
- if (d >= 0) {
- read(d, tmp, 60);
- close(d);
- }
- }
- if (tmp[0] == '\0') {
- strcat(tmp, "unknown");
- }
- }
- return tmp;
-}
-
-/*
- * see if we should take a nap of some sort between polls
- */
-static void nap_check(int tile_cnt) {
- time_t now;
-
- nap_diff_count += tile_cnt;
-
- if (! take_naps) {
- return;
- }
-
- now = time(NULL);
-
- if (screen_blank > 0) {
- int dt_ev, dt_fbu;
- static int ms = 0;
- if (ms == 0) {
- ms = 2000;
- if (getenv("X11VNC_SB_FACTOR")) {
- ms = ms * atof(getenv("X11VNC_SB_FACTOR"));
- }
- if (ms <= 0) {
- ms = 2000;
- }
- }
-
- /* if no activity, pause here for a second or so. */
- dt_ev = (int) (now - last_event);
- dt_fbu = (int) (now - last_fb_bytes_sent);
- if (dt_fbu > screen_blank) {
- /* sleep longer for no fb requests */
- if (debug_tiles > 1) {
- fprintf(stderr, "screen blank sleep1: %d ms / 16, load: %s\n", 2 * ms, get_load());
- }
- nap_sleep(2 * ms, 16);
- return;
- }
- if (dt_ev > screen_blank) {
- if (debug_tiles > 1) {
- fprintf(stderr, "screen blank sleep2: %d ms / 8, load: %s\n", ms, get_load());
- }
- nap_sleep(ms, 8);
- return;
- }
- }
- if (naptile && nap_ok && tile_cnt < naptile) {
- int ms = napfac * waitms;
- ms = ms > napmax ? napmax : ms;
- if (now - last_input <= 3) {
- nap_ok = 0;
- } else if (now - last_local_input <= 3) {
- nap_ok = 0;
- } else {
- if (debug_tiles > 1) {
- fprintf(stderr, "nap_check sleep: %d ms / 1, load: %s\n", ms, get_load());
- }
- nap_sleep(ms, 1);
- }
- }
-}
-
-/*
- * This is called to avoid a ~20 second timeout in libvncserver.
- * May no longer be needed.
- */
-static void ping_clients(int tile_cnt) {
- static time_t last_send = 0;
- time_t now = time(NULL);
-
- if (rfbMaxClientWait < 20000) {
- rfbMaxClientWait = 20000;
- rfbLog("reset rfbMaxClientWait to %d msec.\n",
- rfbMaxClientWait);
- }
- if (tile_cnt > 0) {
- last_send = now;
- } else if (tile_cnt < 0) {
- /* negative tile_cnt is -ping case */
- if (now >= last_send - tile_cnt) {
- mark_rect_as_modified(0, 0, 1, 1, 1);
- last_send = now;
- }
- } else if (now - last_send > 5) {
- /* Send small heartbeat to client */
- mark_rect_as_modified(0, 0, 1, 1, 1);
- last_send = now;
- }
-}
-
-/*
- * scan_display() wants to know if this tile can be skipped due to
- * blackout regions: (no data compare is done, just a quick geometric test)
- */
-static int blackout_line_skip(int n, int x, int y, int rescan,
- int *tile_count) {
-
- if (tile_blackout[n].cover == 2) {
- tile_has_diff[n] = 0;
- return 1; /* skip it */
-
- } else if (tile_blackout[n].cover == 1) {
- int w, x1, y1, x2, y2, b, hit = 0;
- if (x + NSCAN > dpy_x) {
- w = dpy_x - x;
- } else {
- w = NSCAN;
- }
-
- for (b=0; b < tile_blackout[n].count; b++) {
-
- /* n.b. these coords are in full display space: */
- x1 = tile_blackout[n].bo[b].x1;
- x2 = tile_blackout[n].bo[b].x2;
- y1 = tile_blackout[n].bo[b].y1;
- y2 = tile_blackout[n].bo[b].y2;
-
- if (x2 - x1 < w) {
- /* need to cover full width */
- continue;
- }
- if (y1 <= y && y < y2) {
- hit = 1;
- break;
- }
- }
- if (hit) {
- if (! rescan) {
- tile_has_diff[n] = 0;
- } else {
- *tile_count += tile_has_diff[n];
- }
- return 1; /* skip */
- }
- }
- return 0; /* do not skip */
-}
-
-static int blackout_line_cmpskip(int n, int x, int y, char *dst, char *src,
- int w, int pixelsize) {
-
- int i, x1, y1, x2, y2, b, hit = 0;
- int beg = -1, end = -1;
-
- if (tile_blackout[n].cover == 0) {
- return 0; /* 0 means do not skip it. */
- } else if (tile_blackout[n].cover == 2) {
- return 1; /* 1 means skip it. */
- }
-
- /* tile has partial coverage: */
-
- for (i=0; i < w * pixelsize; i++) {
- if (*(dst+i) != *(src+i)) {
- beg = i/pixelsize; /* beginning difference */
- break;
- }
- }
- for (i = w * pixelsize - 1; i >= 0; i--) {
- if (*(dst+i) != *(src+i)) {
- end = i/pixelsize; /* ending difference */
- break;
- }
- }
- if (beg < 0 || end < 0) {
- /* problem finding range... */
- return 0;
- }
-
- /* loop over blackout rectangles: */
- for (b=0; b < tile_blackout[n].count; b++) {
-
- /* y in full display space: */
- y1 = tile_blackout[n].bo[b].y1;
- y2 = tile_blackout[n].bo[b].y2;
-
- /* x relative to tile origin: */
- x1 = tile_blackout[n].bo[b].x1 - x;
- x2 = tile_blackout[n].bo[b].x2 - x;
-
- if (y1 > y || y >= y2) {
- continue;
- }
- if (x1 <= beg && end <= x2) {
- hit = 1;
- break;
- }
- }
- if (hit) {
- return 1;
- } else {
- return 0;
- }
-}
-
-/*
- * For the subwin case follows the window if it is moved.
- */
-void set_offset(void) {
- Window w;
- if (! subwin) {
- return;
- }
- X_LOCK;
- xtranslate(window, rootwin, 0, 0, &off_x, &off_y, &w, 0);
- X_UNLOCK;
-}
-
-static int xd_samples = 0, xd_misses = 0, xd_do_check = 0;
-
-/*
- * Loop over 1-pixel tall horizontal scanlines looking for changes.
- * Record the changes in tile_has_diff[]. Scanlines in the loop are
- * equally spaced along y by NSCAN pixels, but have a slightly random
- * starting offset ystart ( < NSCAN ) from scanlines[].
- */
-
-static int scan_display(int ystart, int rescan) {
- char *src, *dst;
- int pixelsize = bpp/8;
- int x, y, w, n;
- int tile_count = 0;
- int nodiffs = 0, diff_hint;
- int xd_check = 0, xd_freq = 1;
- static int xd_tck = 0;
-
- y = ystart;
-
- g_now = dnow();
-
- if (! main_fb) {
- rfbLog("scan_display: no main_fb!\n");
- return 0;
- }
-
- X_LOCK;
-
- while (y < dpy_y) {
-
- if (use_xdamage) {
- XD_tot++;
- xd_check = 0;
- if (xdamage_hint_skip(y)) {
- if (xd_do_check && dpy && use_xdamage == 1) {
- xd_tck++;
- xd_tck = xd_tck % xd_freq;
- if (xd_tck == 0) {
- xd_check = 1;
- xd_samples++;
- }
- }
- if (!xd_check) {
- XD_skip++;
- y += NSCAN;
- continue;
- }
- } else {
- if (xd_do_check && 0) {
- fprintf(stderr, "ns y=%d\n", y);
- }
- }
- }
-
- /* grab the horizontal scanline from the display: */
-
-#ifndef NO_NCACHE
-/* XXX Y test */
-if (ncache > 0) {
- int gotone = 0;
- if (macosx_console) {
- if (macosx_checkevent(NULL)) {
- gotone = 1;
- }
- } else {
-#if !NO_X11
- XEvent ev;
- if (raw_fb_str) {
- ;
- } else if (XEventsQueued(dpy, QueuedAlready) == 0) {
- ; /* XXX Y resp */
- } else if (XCheckTypedEvent(dpy, MapNotify, &ev)) {
- gotone = 1;
- } else if (XCheckTypedEvent(dpy, UnmapNotify, &ev)) {
- gotone = 2;
- } else if (XCheckTypedEvent(dpy, CreateNotify, &ev)) {
- gotone = 3;
- } else if (XCheckTypedEvent(dpy, ConfigureNotify, &ev)) {
- gotone = 4;
- } else if (XCheckTypedEvent(dpy, VisibilityNotify, &ev)) {
- gotone = 5;
- }
- if (gotone) {
- XPutBackEvent(dpy, &ev);
- }
-#endif
- }
- if (gotone) {
- static int nomsg = 1;
- if (nomsg) {
- if (dnowx() > 20) {
- nomsg = 0;
- }
- } else {
-if (ncdb) fprintf(stderr, "\n*** SCAN_DISPLAY CHECK_NCACHE/%d *** %d rescan=%d\n", gotone, y, rescan);
- }
- X_UNLOCK;
- check_ncache(0, 1);
- X_LOCK;
- }
-}
-#endif
-
- XRANDR_SET_TRAP_RET(-1, "scan_display-set");
- copy_image(scanline, 0, y, 0, 0);
- XRANDR_CHK_TRAP_RET(-1, "scan_display-chk");
-
- /* for better memory i/o try the whole line at once */
- src = scanline->data;
- dst = main_fb + y * main_bytes_per_line;
-
- if (! memcmp(dst, src, main_bytes_per_line)) {
- /* no changes anywhere in scan line */
- nodiffs = 1;
- if (! rescan) {
- y += NSCAN;
- continue;
- }
- }
- if (xd_check) {
- xd_misses++;
- }
-
- x = 0;
- while (x < dpy_x) {
- n = (x/tile_x) + (y/tile_y) * ntiles_x;
- diff_hint = 0;
-
- if (blackouts) {
- if (blackout_line_skip(n, x, y, rescan,
- &tile_count)) {
- x += NSCAN;
- continue;
- }
- }
-
- if (rescan) {
- if (nodiffs || tile_has_diff[n]) {
- tile_count += tile_has_diff[n];
- x += NSCAN;
- continue;
- }
- } else if (xdamage_tile_count &&
- tile_has_xdamage_diff[n]) {
- tile_has_xdamage_diff[n] = 2;
- diff_hint = 1;
- }
-
- /* set ptrs to correspond to the x offset: */
- src = scanline->data + x * pixelsize;
- dst = main_fb + y * main_bytes_per_line + x * pixelsize;
-
- /* compute the width of data to be compared: */
- if (x + NSCAN > dpy_x) {
- w = dpy_x - x;
- } else {
- w = NSCAN;
- }
-
- if (diff_hint || memcmp(dst, src, w * pixelsize)) {
- /* found a difference, record it: */
- if (! blackouts) {
- tile_has_diff[n] = 1;
- tile_count++;
- } else {
- if (blackout_line_cmpskip(n, x, y,
- dst, src, w, pixelsize)) {
- tile_has_diff[n] = 0;
- } else {
- tile_has_diff[n] = 1;
- tile_count++;
- }
- }
- }
- x += NSCAN;
- }
- y += NSCAN;
- }
-
- X_UNLOCK;
-
- return tile_count;
-}
-
-
-int scanlines[NSCAN] = {
- 0, 16, 8, 24, 4, 20, 12, 28,
- 10, 26, 18, 2, 22, 6, 30, 14,
- 1, 17, 9, 25, 7, 23, 15, 31,
- 19, 3, 27, 11, 29, 13, 5, 21
-};
-
-/*
- * toplevel for the scanning, rescanning, and applying the heuristics.
- * returns number of changed tiles.
- */
-int scan_for_updates(int count_only) {
- int i, tile_count, tile_diffs;
- int old_copy_tile;
- double frac1 = 0.1; /* tweak parameter to try a 2nd scan_display() */
- double frac2 = 0.35; /* or 3rd */
- double frac3 = 0.02; /* do scan_display() again after copy_tiles() */
- static double last_poll = 0.0;
- double dtmp = 0.0;
-
- if (unixpw_in_progress) return 0;
-
- if (slow_fb > 0.0) {
- double now = dnow();
- if (now < last_poll + slow_fb) {
- return 0;
- }
- last_poll = now;
- }
-
- for (i=0; i < ntiles; i++) {
- tile_has_diff[i] = 0;
- tile_has_xdamage_diff[i] = 0;
- tile_tried[i] = 0;
- tile_copied[i] = 0;
- }
- for (i=0; i < ntiles_y; i++) {
- /* could be useful, currently not used */
- tile_row_has_xdamage_diff[i] = 0;
- }
- xdamage_tile_count = 0;
-
- /*
- * n.b. this program has only been tested so far with
- * tile_x = tile_y = NSCAN = 32!
- */
-
- if (!count_only) {
- scan_count++;
- scan_count %= NSCAN;
-
- /* some periodic maintenance */
- if (subwin && scan_count % 4 == 0) {
- set_offset(); /* follow the subwindow */
- }
- if (indexed_color && scan_count % 4 == 0) {
- /* check for changed colormap */
- set_colormap(0);
- }
- if (cmap8to24 && scan_count % 1 == 0) {
- check_for_multivis();
- }
-#ifdef MACOSX
- if (macosx_console) {
- macosx_event_loop();
- }
-#endif
- if (use_xdamage) {
- /* first pass collecting DAMAGE events: */
-#ifdef MACOSX
- if (macosx_console) {
- collect_non_X_xdamage(-1, -1, -1, -1, 0);
- } else
-#endif
- {
- if (rawfb_vnc_reflect) {
- collect_non_X_xdamage(-1, -1, -1, -1, 0);
- } else {
- collect_xdamage(scan_count, 0);
- }
- }
- }
- }
-
-#define SCAN_FATAL(x) \
- if (x < 0) { \
- scan_in_progress = 0; \
- fb_copy_in_progress = 0; \
- return 0; \
- }
-
- /* scan with the initial y to the jitter value from scanlines: */
- scan_in_progress = 1;
- tile_count = scan_display(scanlines[scan_count], 0);
- SCAN_FATAL(tile_count);
-
- /*
- * we do the XDAMAGE here too since after scan_display()
- * there is a better chance we have received the events from
- * the X server (otherwise the DAMAGE events will be processed
- * in the *next* call, usually too late and wasteful since
- * the unchanged tiles are read in again).
- */
- if (use_xdamage) {
-#ifdef MACOSX
- if (macosx_console) {
- ;
- } else
-#endif
- {
- if (rawfb_vnc_reflect) {
- ;
- } else {
- collect_xdamage(scan_count, 1);
- }
- }
- }
- if (count_only) {
- scan_in_progress = 0;
- fb_copy_in_progress = 0;
- return tile_count;
- }
-
- if (xdamage_tile_count) {
- /* pick up "known" damaged tiles we missed in scan_display() */
- for (i=0; i < ntiles; i++) {
- if (tile_has_diff[i]) {
- continue;
- }
- if (tile_has_xdamage_diff[i]) {
- tile_has_diff[i] = 1;
- if (tile_has_xdamage_diff[i] == 1) {
- tile_has_xdamage_diff[i] = 2;
- tile_count++;
- }
- }
- }
- }
- if (dpy && use_xdamage == 1) {
- static time_t last_xd_check = 0;
- if (time(NULL) > last_xd_check + 2) {
- int cp = (scan_count + 3) % NSCAN;
- xd_do_check = 1;
- tile_count = scan_display(scanlines[cp], 0);
- xd_do_check = 0;
- SCAN_FATAL(tile_count);
- last_xd_check = time(NULL);
- if (xd_samples > 200) {
- static int bad = 0;
- if (xd_misses > (20 * xd_samples) / 100) {
- rfbLog("XDAMAGE is not working well... misses: %d/%d\n", xd_misses, xd_samples);
- rfbLog("Maybe an OpenGL app like Beryl or Compiz is the problem?\n");
- rfbLog("Use x11vnc -noxdamage or disable the Beryl/Compiz app.\n");
- rfbLog("To disable this check and warning specify -xdamage twice.\n");
- if (++bad >= 10) {
- rfbLog("XDAMAGE appears broken (OpenGL app?), turning it off.\n");
- use_xdamage = 0;
- initialize_xdamage();
- destroy_xdamage_if_needed();
- }
- }
- xd_samples = 0;
- xd_misses = 0;
- }
- }
- }
-
- nap_set(tile_count);
-
- if (fs_factor && frac1 >= fs_frac) {
- /* make frac1 < fs_frac if fullscreen updates are enabled */
- frac1 = fs_frac/2.0;
- }
-
- if (tile_count > frac1 * ntiles) {
- /*
- * many tiles have changed, so try a rescan (since it should
- * be short compared to the many upcoming copy_tiles() calls)
- */
-
- /* this check is done to skip the extra scan_display() call */
- if (! fs_factor || tile_count <= fs_frac * ntiles) {
- int cp, tile_count_old = tile_count;
-
- /* choose a different y shift for the 2nd scan: */
- cp = (NSCAN - scan_count) % NSCAN;
-
- tile_count = scan_display(scanlines[cp], 1);
- SCAN_FATAL(tile_count);
-
- if (tile_count >= (1 + frac2) * tile_count_old) {
- /* on a roll... do a 3rd scan */
- cp = (NSCAN - scan_count + 7) % NSCAN;
- tile_count = scan_display(scanlines[cp], 1);
- SCAN_FATAL(tile_count);
- }
- }
- scan_in_progress = 0;
-
- /*
- * At some number of changed tiles it is better to just
- * copy the full screen at once. I.e. time = c1 + m * r1
- * where m is number of tiles, r1 is the copy_tiles()
- * time, and c1 is the scan_display() time: for some m
- * it crosses the full screen update time.
- *
- * We try to predict that crossover with the fs_frac
- * fudge factor... seems to be about 1/2 the total number
- * of tiles. n.b. this ignores network bandwidth,
- * compression time etc...
- *
- * Use -fs 1.0 to disable on slow links.
- */
- if (fs_factor && tile_count > fs_frac * ntiles) {
- int cs;
- fb_copy_in_progress = 1;
- cs = copy_screen();
- fb_copy_in_progress = 0;
- SCAN_FATAL(cs);
- if (use_threads && pointer_mode != 1) {
- pointer_event(-1, 0, 0, NULL);
- }
- nap_check(tile_count);
- return tile_count;
- }
- }
- scan_in_progress = 0;
-
- /* copy all tiles with differences from display to rfb framebuffer: */
- fb_copy_in_progress = 1;
-
- if (single_copytile || tile_shm_count < ntiles_x) {
- /*
- * Old way, copy I/O one tile at a time.
- */
- old_copy_tile = 1;
- } else {
- /*
- * New way, does runs of horizontal tiles at once.
- * Note that below, for simplicity, the extra tile finding
- * (e.g. copy_tiles_backward_pass) is done the old way.
- */
- old_copy_tile = 0;
- }
-
- if (unixpw_in_progress) return 0;
-
-/* XXX Y */
-if (0 && tile_count > 20) print_tiles();
-#if 0
-dtmp = dnow();
-#else
-dtmp = 0.0;
-#endif
-
- if (old_copy_tile) {
- tile_diffs = copy_all_tiles();
- } else {
- tile_diffs = copy_all_tile_runs();
- }
- SCAN_FATAL(tile_diffs);
-
-#if 0
-if (tile_count) fprintf(stderr, "XX copytile: %.4f tile_count: %d\n", dnow() - dtmp, tile_count);
-#endif
-
- /*
- * This backward pass for upward and left tiles complements what
- * was done in copy_all_tiles() for downward and right tiles.
- */
- tile_diffs = copy_tiles_backward_pass();
- SCAN_FATAL(tile_diffs);
-
- if (tile_diffs > frac3 * ntiles) {
- /*
- * we spent a lot of time in those copy_tiles, run
- * another scan, maybe more of the screen changed.
- */
- int cp = (NSCAN - scan_count + 13) % NSCAN;
-
- scan_in_progress = 1;
- tile_count = scan_display(scanlines[cp], 1);
- SCAN_FATAL(tile_count);
- scan_in_progress = 0;
-
- tile_diffs = copy_tiles_additional_pass();
- SCAN_FATAL(tile_diffs);
- }
-
- /* Given enough tile diffs, try the islands: */
- if (grow_fill && tile_diffs > 4) {
- tile_diffs = grow_islands();
- }
- SCAN_FATAL(tile_diffs);
-
- /* Given enough tile diffs, try the gaps: */
- if (gaps_fill && tile_diffs > 4) {
- tile_diffs = fill_tile_gaps();
- }
- SCAN_FATAL(tile_diffs);
-
- fb_copy_in_progress = 0;
- if (use_threads && pointer_mode != 1) {
- /*
- * tell the pointer handler it can process any queued
- * pointer events:
- */
- pointer_event(-1, 0, 0, NULL);
- }
-
- if (blackouts) {
- /* ignore any diffs in completely covered tiles */
- int x, y, n;
- for (y=0; y < ntiles_y; y++) {
- for (x=0; x < ntiles_x; x++) {
- n = x + y * ntiles_x;
- if (tile_blackout[n].cover == 2) {
- tile_has_diff[n] = 0;
- }
- }
- }
- }
-
- hint_updates(); /* use x0rfbserver hints algorithm */
-
- /* Work around threaded rfbProcessClientMessage() calls timeouts */
- if (use_threads) {
- ping_clients(tile_diffs);
- } else if (saw_ultra_chat || saw_ultra_file) {
- ping_clients(-1);
- } else if (use_openssl && !tile_diffs) {
- ping_clients(0);
- }
- /* -ping option: */
- if (ping_interval) {
- int td = ping_interval > 0 ? ping_interval : -ping_interval;
- ping_clients(-td);
- }
-
-
- nap_check(tile_diffs);
- return tile_diffs;
-}
-
-
diff --git a/x11vnc/scan.h b/x11vnc/scan.h
deleted file mode 100644
index 32cf216..0000000
--- a/x11vnc/scan.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_SCAN_H
-#define _X11VNC_SCAN_H
-
-/* -- scan.h -- */
-
-extern int nap_ok;
-extern int scanlines[];
-
-extern void initialize_tiles(void);
-extern void free_tiles(void);
-extern void shm_delete(XShmSegmentInfo *shm);
-extern void shm_clean(XShmSegmentInfo *shm, XImage *xim);
-extern void initialize_polling_images(void);
-extern void scale_rect(double factor_x, double factor_y, int blend, int interpolate, int Bpp,
- char *src_fb, int src_bytes_per_line, char *dst_fb, int dst_bytes_per_line,
- int Nx, int Ny, int nx, int ny, int X1, int Y1, int X2, int Y2, int mark);
-extern void scale_and_mark_rect(int X1, int Y1, int X2, int Y2, int mark);
-extern void mark_rect_as_modified(int x1, int y1, int x2, int y2, int force);
-extern int copy_screen(void);
-extern int copy_snap(void);
-extern void nap_sleep(int ms, int split);
-extern void set_offset(void);
-extern int scan_for_updates(int count_only);
-extern void rotate_curs(char *dst_0, char *src_0, int Dx, int Dy, int Bpp);
-extern void rotate_coords(int x, int y, int *xo, int *yo, int dxi, int dyi);
-extern void rotate_coords_inverse(int x, int y, int *xo, int *yo, int dxi, int dyi);
-
-#endif /* _X11VNC_SCAN_H */
diff --git a/x11vnc/screen.c b/x11vnc/screen.c
deleted file mode 100644
index d0851f6..0000000
--- a/x11vnc/screen.c
+++ /dev/null
@@ -1,4705 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- screen.c -- */
-
-#include "x11vnc.h"
-#include "xevents.h"
-#include "xwrappers.h"
-#include "xinerama.h"
-#include "xdamage.h"
-#include "win_utils.h"
-#include "cleanup.h"
-#include "userinput.h"
-#include "scan.h"
-#include "user.h"
-#include "rates.h"
-#include "pointer.h"
-#include "keyboard.h"
-#include "cursor.h"
-#include "connections.h"
-#include "remote.h"
-#include "unixpw.h"
-#include "sslcmds.h"
-#include "sslhelper.h"
-#include "v4l.h"
-#include "linuxfb.h"
-#include "macosx.h"
-#include "macosxCG.h"
-#include "avahi.h"
-#include "solid.h"
-#include "inet.h"
-#include "xrandr.h"
-#include "xrecord.h"
-#include "pm.h"
-
-#include <rfb/rfbclient.h>
-
-void set_greyscale_colormap(void);
-void set_hi240_colormap(void);
-void unset_colormap(void);
-void set_colormap(int reset);
-void set_nofb_params(int restore);
-void set_raw_fb_params(int restore);
-void do_new_fb(int reset_mem);
-void free_old_fb(void);
-void check_padded_fb(void);
-void install_padded_fb(char *geom);
-XImage *initialize_xdisplay_fb(void);
-void parse_scale_string(char *str, double *factor_x, double *factor_y, int *scaling, int *blend,
- int *nomult4, int *pad, int *interpolate, int *numer, int *denom, int w_in, int h_in);
-int parse_rotate_string(char *str, int *mode);
-int scale_round(int len, double fac);
-void initialize_screen(int *argc, char **argv, XImage *fb);
-void set_vnc_desktop_name(void);
-void announce(int lport, int ssl, char *iface);
-
-char *vnc_reflect_guess(char *str, char **raw_fb_addr);
-void vnc_reflect_process_client(void);
-rfbBool vnc_reflect_send_pointer(int x, int y, int mask);
-rfbBool vnc_reflect_send_key(uint32_t key, rfbBool down);
-rfbBool vnc_reflect_send_cuttext(char *str, int len);
-
-static void debug_colormap(XImage *fb);
-static void set_visual(char *str);
-static void nofb_hook(rfbClientPtr cl);
-static void remove_fake_fb(void);
-static void install_fake_fb(int w, int h, int bpp);
-static void initialize_snap_fb(void);
-XImage *initialize_raw_fb(int);
-static void initialize_clipshift(void);
-static int wait_until_mapped(Window win);
-static void setup_scaling(int *width_in, int *height_in);
-
-static void check_filexfer(void);
-static void record_last_fb_update(void);
-static void check_cursor_changes(void);
-static int choose_delay(double dt);
-
-int rawfb_reset = -1;
-int rawfb_dev_video = 0;
-int rawfb_vnc_reflect = 0;
-
-/*
- * X11 and rfb display/screen related routines
- */
-
-/*
- * Some handling of 8bpp PseudoColor colormaps. Called for initializing
- * the clients and dynamically if -flashcmap is specified.
- */
-#define NCOLOR 256
-
-/* this is only for rawfb */
-void set_greyscale_colormap(void) {
- int i;
- if (! screen) {
- return;
- }
- /* mutex */
- if (screen->colourMap.data.shorts) {
- free(screen->colourMap.data.shorts);
- screen->colourMap.data.shorts = NULL;
- }
-
-if (0) fprintf(stderr, "set_greyscale_colormap: %s\n", raw_fb_pixfmt);
- screen->colourMap.count = NCOLOR;
- screen->serverFormat.trueColour = FALSE;
- screen->colourMap.is16 = TRUE;
- screen->colourMap.data.shorts = (unsigned short *)
- malloc(3*sizeof(unsigned short) * NCOLOR);
-
- for(i = 0; i < NCOLOR; i++) {
- unsigned short lvl = i * 256;
-
- screen->colourMap.data.shorts[i*3+0] = lvl;
- screen->colourMap.data.shorts[i*3+1] = lvl;
- screen->colourMap.data.shorts[i*3+2] = lvl;
- }
-
- rfbSetClientColourMaps(screen, 0, NCOLOR);
-}
-
-/* this is specific to bttv rf tuner card */
-void set_hi240_colormap(void) {
- int i;
- if (! screen) {
- return;
- }
- /* mutex */
-if (0) fprintf(stderr, "set_hi240_colormap: %s\n", raw_fb_pixfmt);
- if (screen->colourMap.data.shorts) {
- free(screen->colourMap.data.shorts);
- screen->colourMap.data.shorts = NULL;
- }
-
- screen->colourMap.count = 256;
- screen->serverFormat.trueColour = FALSE;
- screen->colourMap.is16 = TRUE;
- screen->colourMap.data.shorts = (unsigned short *)
- calloc(3*sizeof(unsigned short) * 256, 1);
-
- for(i = 0; i < 225; i++) {
- int r, g, b;
-
- r = ( (i/5) % 5 ) * 255.0 / 4 + 0.5;
- g = ( (i/25) ) * 255.0 / 8 + 0.5;
- b = ( i % 5 ) * 255.0 / 4 + 0.5;
-
- screen->colourMap.data.shorts[(i+16)*3+0] = (unsigned short) (r * 256);
- screen->colourMap.data.shorts[(i+16)*3+1] = (unsigned short) (g * 256);
- screen->colourMap.data.shorts[(i+16)*3+2] = (unsigned short) (b * 256);
- }
-
- rfbSetClientColourMaps(screen, 0, 256);
-}
-
-/* this is only for rawfb */
-void unset_colormap(void) {
- if (! screen) {
- return;
- }
- if (screen->colourMap.data.shorts) {
- free(screen->colourMap.data.shorts);
- screen->colourMap.data.shorts = NULL;
- }
- screen->serverFormat.trueColour = TRUE;
-if (0) fprintf(stderr, "unset_colormap: %s\n", raw_fb_pixfmt);
-}
-
-/* this is X11 case */
-void set_colormap(int reset) {
-
-#if NO_X11
- if (!reset) {}
- return;
-#else
- static int init = 1;
- static XColor *color = NULL, *prev = NULL;
- static int ncolor = 0;
- Colormap cmap;
- Visual *vis;
- int i, ncells, diffs = 0;
-
- if (reset) {
- init = 1;
- ncolor = 0;
- /* mutex */
- if (screen->colourMap.data.shorts) {
- free(screen->colourMap.data.shorts);
- screen->colourMap.data.shorts = NULL;
- }
- if (color) {
- free(color);
- color = NULL;
- }
- if (prev) {
- free(prev);
- prev = NULL;
- }
- }
-
- if (init) {
- if (depth > 16) {
- ncolor = NCOLOR;
- } else if (depth > 8) {
- ncolor = 1 << depth;
- } else {
- ncolor = NCOLOR;
- }
- /* mutex */
- screen->colourMap.count = ncolor;
- screen->serverFormat.trueColour = FALSE;
- screen->colourMap.is16 = TRUE;
- screen->colourMap.data.shorts = (unsigned short *)
- malloc(3*sizeof(unsigned short) * ncolor);
- }
- if (color == NULL) {
- color = (XColor *) calloc(ncolor * sizeof(XColor), 1);
- prev = (XColor *) calloc(ncolor * sizeof(XColor), 1);
- }
-
- for (i=0; i < ncolor; i++) {
- prev[i].red = color[i].red;
- prev[i].green = color[i].green;
- prev[i].blue = color[i].blue;
- }
-
- RAWFB_RET_VOID
-
- X_LOCK;
-
- cmap = DefaultColormap(dpy, scr);
- ncells = CellsOfScreen(ScreenOfDisplay(dpy, scr));
- vis = default_visual;
-
- if (subwin) {
- XWindowAttributes attr;
-
- if (XGetWindowAttributes(dpy, window, &attr)) {
- cmap = attr.colormap;
- vis = attr.visual;
- ncells = vis->map_entries;
- }
- }
-
- if (ncells != ncolor) {
- if (! shift_cmap) {
- screen->colourMap.count = ncells;
- }
- }
- if (init && ! quiet) {
- rfbLog("set_colormap: number of cells: %d, "
- "ncolor(%d) is %d.\n", ncells, depth, ncolor);
- }
-
- if (flash_cmap && ! init) {
- XWindowAttributes attr;
- Window c;
- int tries = 0;
-
- c = window;
- while (c && tries++ < 16) {
- c = query_pointer(c);
- if (valid_window(c, &attr, 0)) {
- if (attr.colormap && attr.map_installed) {
- cmap = attr.colormap;
- vis = attr.visual;
- ncells = vis->map_entries;
- break;
- }
- } else {
- break;
- }
- }
- }
- if (ncells > ncolor && ! quiet) {
- rfbLog("set_colormap: big problem: ncells=%d > %d\n",
- ncells, ncolor);
- }
-
- if (vis->class == TrueColor || vis->class == DirectColor) {
- /*
- * Kludge to make 8bpp TrueColor & DirectColor be like
- * the StaticColor map. The ncells = 8 is "8 per subfield"
- * mentioned in xdpyinfo. Looks OK... perhaps fortuitously.
- */
- if (ncells == 8 && ! shift_cmap) {
- ncells = ncolor;
- }
- }
-
- for (i=0; i < ncells; i++) {
- color[i].pixel = i;
- color[i].pad = 0;
- }
-
- XQueryColors(dpy, cmap, color, ncells);
-
- X_UNLOCK;
-
- for(i = ncells - 1; i >= 0; i--) {
- int k = i + shift_cmap;
-
- screen->colourMap.data.shorts[i*3+0] = color[i].red;
- screen->colourMap.data.shorts[i*3+1] = color[i].green;
- screen->colourMap.data.shorts[i*3+2] = color[i].blue;
-
- if (prev[i].red != color[i].red ||
- prev[i].green != color[i].green ||
- prev[i].blue != color[i].blue ) {
- diffs++;
- }
-
- if (shift_cmap && k >= 0 && k < ncolor) {
- /* kludge to copy the colors to higher pixel values */
- screen->colourMap.data.shorts[k*3+0] = color[i].red;
- screen->colourMap.data.shorts[k*3+1] = color[i].green;
- screen->colourMap.data.shorts[k*3+2] = color[i].blue;
- }
- }
-
- if (diffs && ! init) {
- if (! all_clients_initialized()) {
- rfbLog("set_colormap: warning: sending cmap "
- "with uninitialized clients.\n");
- }
- if (shift_cmap) {
- rfbSetClientColourMaps(screen, 0, ncolor);
- } else {
- rfbSetClientColourMaps(screen, 0, ncells);
- }
- }
-
- init = 0;
-#endif /* NO_X11 */
-}
-
-static void debug_colormap(XImage *fb) {
- static int debug_cmap = -1;
- int i, k, *histo;
- int ncolor;
-
- if (debug_cmap < 0) {
- if (getenv("DEBUG_CMAP") != NULL) {
- debug_cmap = 1;
- } else {
- debug_cmap = 0;
- }
- }
- if (! debug_cmap) {
- return;
- }
- if (! fb) {
- return;
- }
- if (fb->bits_per_pixel > 16) {
- return;
- }
- ncolor = screen->colourMap.count;
- histo = (int *) calloc(ncolor * sizeof(int), 1);
-
- for (i=0; i < ncolor; i++) {
- histo[i] = 0;
- }
- for (k = 0; k < fb->width * fb->height; k++) {
- unsigned char n;
- char c = *(fb->data + k);
-
- n = (unsigned char) c;
- histo[n]++;
- }
- fprintf(stderr, "\nColormap histogram for current screen contents:\n");
- for (i=0; i < ncolor; i++) {
- unsigned short r = screen->colourMap.data.shorts[i*3+0];
- unsigned short g = screen->colourMap.data.shorts[i*3+1];
- unsigned short b = screen->colourMap.data.shorts[i*3+2];
-
- fprintf(stderr, " %03d: %7d %04x/%04x/%04x", i, histo[i],
- r, g, b);
- if ((i+1) % 2 == 0) {
- fprintf(stderr, "\n");
- }
- }
- free(histo);
- fprintf(stderr, "\n");
-}
-
-/*
- * Experimental mode to force the visual of the window instead of querying
- * it. Used for testing, overriding some rare cases (win2vnc), and for
- * -overlay . Input string can be a decimal or 0x hex or something like
- * TrueColor or TrueColor:24 to force a depth as well.
- *
- * visual_id and possibly visual_depth are set.
- */
-static void set_visual(char *str) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!str) {}
- return;
-#else
- int vis, vdepth, defdepth;
- XVisualInfo vinfo;
- char *p, *vstring = strdup(str);
-
- RAWFB_RET_VOID
-
- defdepth = DefaultDepth(dpy, scr);
- visual_id = (VisualID) 0;
- visual_depth = 0;
-
- if (!strcmp(vstring, "ignore") || !strcmp(vstring, "default")
- || !strcmp(vstring, "")) {
- free(vstring);
- return;
- }
-
- /* set visual depth */
- if ((p = strchr(vstring, ':')) != NULL) {
- visual_depth = atoi(p+1);
- *p = '\0';
- vdepth = visual_depth;
- } else {
- vdepth = defdepth;
- }
- if (! quiet) {
- fprintf(stderr, "\nVisual Info:\n");
- fprintf(stderr, " set_visual(\"%s\")\n", str);
- fprintf(stderr, " visual_depth: %d\n", vdepth);
- }
-
- /* set visual id number */
- if (strcmp(vstring, "StaticGray") == 0) {
- vis = StaticGray;
- } else if (strcmp(vstring, "GrayScale") == 0) {
- vis = GrayScale;
- } else if (strcmp(vstring, "StaticColor") == 0) {
- vis = StaticColor;
- } else if (strcmp(vstring, "PseudoColor") == 0) {
- vis = PseudoColor;
- } else if (strcmp(vstring, "TrueColor") == 0) {
- vis = TrueColor;
- } else if (strcmp(vstring, "DirectColor") == 0) {
- vis = DirectColor;
- } else {
- unsigned int v_in;
- if (sscanf(vstring, "0x%x", &v_in) != 1) {
- if (sscanf(vstring, "%u", &v_in) == 1) {
- visual_id = (VisualID) v_in;
- return;
- }
- rfbLogEnable(1);
- rfbLog("invalid -visual arg: %s\n", vstring);
- X_UNLOCK;
- clean_up_exit(1);
- }
- visual_id = (VisualID) v_in;
- free(vstring);
- return;
- }
-
- if (! quiet) fprintf(stderr, " visual: %d\n", vis);
- if (XMatchVisualInfo(dpy, scr, visual_depth, vis, &vinfo)) {
- ;
- } else if (XMatchVisualInfo(dpy, scr, defdepth, vis, &vinfo)) {
- ;
- } else {
- rfbLogEnable(1);
- rfbLog("could not find visual: %s\n", vstring);
- X_UNLOCK;
- clean_up_exit(1);
- }
- free(vstring);
-
- /* set numerical visual id. */
- visual_id = vinfo.visualid;
-#endif /* NO_X11 */
-}
-
-void set_nofb_params(int restore) {
- static int first = 1;
- static int save[100];
- static char *scroll = NULL;
- int i = 0;
-
- if (first) {
- first = 0;
- save[i++] = use_xfixes;
- save[i++] = use_xdamage;
- save[i++] = use_xrecord;
- save[i++] = wireframe;
- save[i++] = use_solid_bg;
- save[i++] = overlay;
- save[i++] = overlay_cursor;
- save[i++] = using_shm;
- save[i++] = single_copytile;
- save[i++] = take_naps;
- save[i++] = measure_speeds;
- save[i++] = grab_buster;
- save[i++] = show_cursor;
- save[i++] = cursor_shape_updates;
- save[i++] = cursor_pos_updates;
- save[i++] = ncache;
-
- scroll = scroll_copyrect;
- }
- if (restore) {
- i = 0;
- use_xfixes = save[i++];
- use_xdamage = save[i++];
- use_xrecord = save[i++];
- wireframe = save[i++];
- use_solid_bg = save[i++];
- overlay = save[i++];
- overlay_cursor = save[i++];
- using_shm = save[i++];
- single_copytile = save[i++];
- take_naps = save[i++];
- measure_speeds = save[i++];
- grab_buster = save[i++];
- show_cursor = save[i++];
- cursor_shape_updates = save[i++];
- cursor_pos_updates = save[i++];
- ncache = save[i++];
-
- scroll_copyrect = scroll;
-
- if (cursor_shape_updates) {
- restore_cursor_shape_updates(screen);
- }
- initialize_cursors_mode();
-
- return;
- }
-
- use_xfixes = 0;
- use_xdamage = 0;
- use_xrecord = 0;
- wireframe = 0;
-
- use_solid_bg = 0;
- overlay = 0;
- overlay_cursor = 0;
-
- using_shm = 0;
- single_copytile = 1;
-
- take_naps = 0;
- measure_speeds = 0;
-
- /* got_grab_buster? */
- grab_buster = 0;
-
- show_cursor = 0;
- show_multiple_cursors = 0;
- cursor_shape_updates = 0;
- if (! got_cursorpos) {
- cursor_pos_updates = 0;
- }
-
- ncache = 0;
-
- scroll_copyrect = "never";
-
- if (! quiet) {
- rfbLog("disabling: xfixes, xdamage, solid, overlay, shm,\n");
- rfbLog(" wireframe, scrollcopyrect, ncache,\n");
- rfbLog(" noonetile, nap, cursor, %scursorshape\n",
- got_cursorpos ? "" : "cursorpos, " );
- rfbLog(" in -nofb mode.\n");
- }
-}
-
-static char *raw_fb_orig_dpy = NULL;
-
-void set_raw_fb_params(int restore) {
- static int first = 1;
- static int vo0, us0, sm0, ws0, wp0, wc0, wb0, na0, tn0;
- static int xr0, xrm0, sb0, re0;
- static char *mc0;
-
- /*
- * set turn off a bunch of parameters not compatible with
- * -rawfb mode: 1) ignoring the X server 2) ignoring user input.
- */
-
- if (first) {
- /* at least save the initial settings... */
- vo0 = view_only;
- ws0 = watch_selection;
- wp0 = watch_primary;
- wc0 = watch_clipboard;
- wb0 = watch_bell;
- na0 = no_autorepeat;
- sb0 = use_solid_bg;
-
- us0 = use_snapfb;
- sm0 = using_shm;
- tn0 = take_naps;
- xr0 = xrandr;
- xrm0 = xrandr_maybe;
- re0 = noxrecord;
- mc0 = multiple_cursors_mode;
-
- first = 0;
- }
-
- if (restore) {
- view_only = vo0;
- watch_selection = ws0;
- watch_primary = wp0;
- watch_clipboard = wc0;
- watch_bell = wb0;
- no_autorepeat = na0;
- use_solid_bg = sb0;
-
- use_snapfb = us0;
- using_shm = sm0;
- take_naps = tn0;
- xrandr = xr0;
- xrandr_maybe = xrm0;
- noxrecord = re0;
- multiple_cursors_mode = mc0;
-
- if (! dpy && raw_fb_orig_dpy) {
- dpy = XOpenDisplay_wr(raw_fb_orig_dpy);
- last_open_xdisplay = time(NULL);
- if (dpy) {
- if (! quiet) rfbLog("reopened DISPLAY: %s\n",
- raw_fb_orig_dpy);
- scr = DefaultScreen(dpy);
- rootwin = RootWindow(dpy, scr);
- check_xevents(1);
- } else {
- if (! quiet) rfbLog("WARNING: failed to reopen "
- "DISPLAY: %s\n", raw_fb_orig_dpy);
- }
- }
- return;
- }
-
- if (verbose) {
- rfbLog("set_raw_fb_params: modifying settings for "
- "-rawfb mode.\n");
- }
-
- if (got_noviewonly) {
- /*
- * The user input parameters are not unset under
- * -noviewonly... this usage should be very rare
- * (i.e. rawfb but also send user input to the X
- * display, most likely using /dev/fb0 for some reason...)
- */
- if (verbose) {
- rfbLog("rawfb: -noviewonly mode: still sending mouse and\n");
- rfbLog("rawfb: keyboard input to the X DISPLAY!!\n");
- }
- } else {
- /* Normal case: */
-#if 0
- if (! view_only && ! pipeinput_str) {
- if (! quiet) rfbLog(" rawfb: setting view_only\n");
- view_only = 1;
- }
-#endif
- if (raw_fb_str && strstr(raw_fb_str, "vnc") == raw_fb_str) {
- ;
- } else if (watch_selection) {
- if (verbose) rfbLog(" rawfb: turning off "
- "watch_selection\n");
- watch_selection = 0;
- }
- if (watch_primary) {
- if (verbose) rfbLog(" rawfb: turning off "
- "watch_primary\n");
- watch_primary = 0;
- }
- if (watch_clipboard) {
- if (verbose) rfbLog(" rawfb: turning off "
- "watch_clipboard\n");
- watch_clipboard = 0;
- }
- if (watch_bell) {
- if (verbose) rfbLog(" rawfb: turning off watch_bell\n");
- watch_bell = 0;
- }
- if (no_autorepeat) {
- if (verbose) rfbLog(" rawfb: turning off "
- "no_autorepeat\n");
- no_autorepeat = 0;
- }
- if (use_solid_bg) {
- if (verbose) rfbLog(" rawfb: turning off "
- "use_solid_bg\n");
- use_solid_bg = 0;
- }
-#ifndef MACOSX
- if (raw_fb_str && strstr(raw_fb_str, "vnc") == raw_fb_str) {
- ;
- } else {
- multiple_cursors_mode = strdup("arrow");
- }
-#endif
- }
- if (using_shm) {
- if (verbose) rfbLog(" rawfb: turning off using_shm\n");
- using_shm = 0;
- }
- if (take_naps) {
- if (verbose) rfbLog(" rawfb: turning off take_naps\n");
- take_naps = 0;
- }
- if (xrandr) {
- if (verbose) rfbLog(" rawfb: turning off xrandr\n");
- xrandr = 0;
- }
- if (xrandr_maybe) {
- if (verbose) rfbLog(" rawfb: turning off xrandr_maybe\n");
- xrandr_maybe = 0;
- }
- if (! noxrecord) {
- if (verbose) rfbLog(" rawfb: turning off xrecord\n");
- noxrecord = 1;
- }
-}
-
-/*
- * Presumably under -nofb the clients will never request the framebuffer.
- * However, we have gotten such a request... so let's just give them
- * the current view on the display. n.b. x2vnc and perhaps win2vnc
- * requests a 1x1 pixel for some workaround so sadly this evidently
- * nearly always happens.
- */
-static void nofb_hook(rfbClientPtr cl) {
- XImage *fb;
- XImage raw;
-
- rfbLog("framebuffer requested in -nofb mode by client %s\n", cl->host);
- /* ignore xrandr */
-
- if (raw_fb && ! dpy) {
- fb = &raw;
- fb->data = (char *)malloc(32);
- } else {
- int use_real_ximage = 0;
- if (use_real_ximage) {
- fb = XGetImage_wr(dpy, window, 0, 0, dpy_x, dpy_y, AllPlanes, ZPixmap);
- } else {
- fb = &raw;
- fb->data = (char *) calloc(dpy_x*dpy_y*bpp/8, 1);
- }
- }
- main_fb = fb->data;
- rfb_fb = main_fb;
- /* mutex */
- screen->frameBuffer = rfb_fb;
- screen->displayHook = NULL;
-}
-
-void free_old_fb(void) {
- char *fbs[16];
- int i, j, nfb = 0, db = 0;
-
- fbs[nfb++] = main_fb; main_fb = NULL;
- fbs[nfb++] = rfb_fb; rfb_fb = NULL;
- fbs[nfb++] = cmap8to24_fb; cmap8to24_fb = NULL;
- fbs[nfb++] = snap_fb; snap_fb = NULL;
- fbs[nfb++] = rot_fb; rot_fb = NULL;
- fbs[nfb++] = raw_fb; raw_fb = NULL;
-
- for (i=0; i < nfb; i++) {
- char *fb = fbs[i];
- int freeit = 1;
- if (! fb || fb < (char *) 0x10) {
- continue;
- }
- for (j=0; j < i; j++) {
- if (fb == fbs[j]) {
- freeit = 0;
- break;
- }
- }
- if (freeit) {
- if (db) fprintf(stderr, "free: %i %p\n", i, fb);
- free(fb);
- } else {
- if (db) fprintf(stderr, "skip: %i %p\n", i, fb);
- }
- }
-}
-
-static char _lcs_tmp[128];
-static int _bytes0_size = 128, _bytes0[128];
-
-static char *lcs(rfbClientPtr cl) {
- sprintf(_lcs_tmp, "%d/%d/%d/%d/%d-%d/%d/%d",
- !!(cl->newFBSizePending),
- !!(cl->cursorWasChanged),
- !!(cl->cursorWasMoved),
- !!(cl->reverseConnection),
- cl->state,
- cl->modifiedRegion ? !!(sraRgnEmpty(cl->modifiedRegion)) : 2,
- cl->requestedRegion ? !!(sraRgnEmpty(cl->requestedRegion)) : 2,
- cl->copyRegion ? !!(sraRgnEmpty(cl->copyRegion)) : 2
- );
- return _lcs_tmp;
-}
-
-static int lock_client_sends(int lock) {
- static rfbClientPtr *cls = NULL;
- static int cls_len = 0;
- static int blocked = 0;
- static int state = 0;
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- char *s;
-
- if (!use_threads || !screen) {
- return 0;
- }
- if (lock < 0) {
- return state;
- }
- state = lock;
-
- if (lock) {
- if (cls_len < client_count + 128) {
- if (cls != NULL) {
- free(cls);
- }
- cls_len = client_count + 256;
- cls = (rfbClientPtr *) calloc(cls_len * sizeof(rfbClientPtr), 1);
- }
-
- iter = rfbGetClientIterator(screen);
- blocked = 0;
- while ((cl = rfbClientIteratorNext(iter)) != NULL) {
- s = lcs(cl);
- SEND_LOCK(cl);
- rfbLog("locked client: %p %.6f %s\n", cl, dnowx(), s);
- cls[blocked++] = cl;
- }
- rfbReleaseClientIterator(iter);
- } else {
- int i;
- for (i=0; i < blocked; i++) {
- cl = cls[i];
- if (cl != NULL) {
- s = lcs(cl);
- SEND_UNLOCK(cl)
- rfbLog("unlocked client: %p %.6f %s\n", cl, dnowx(), s);
- }
- cls[i] = NULL;
- }
- blocked = 0;
- }
- return state;
-}
-
-static void settle_clients(int init) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int fb_pend, i, ms = 1000;
- char *s;
-
- if (!use_threads || !screen) {
- return;
- }
-
- if (init) {
- iter = rfbGetClientIterator(screen);
- i = 0;
- while ((cl = rfbClientIteratorNext(iter)) != NULL) {
- if (i < _bytes0_size) {
- _bytes0[i] = rfbStatGetSentBytesIfRaw(cl);
- }
- i++;
- }
- rfbReleaseClientIterator(iter);
-
- if (getenv("X11VNC_THREADS_NEW_FB_SLEEP")) {
- ms = atoi(getenv("X11VNC_THREADS_NEW_FB_SLEEP"));
- } else if (subwin) {
- ms = 250;
- } else {
- ms = 500;
- }
- usleep(ms * 1000);
- return;
- }
-
- if (getenv("X11VNC_THREADS_NEW_FB_SLEEP")) {
- ms = atoi(getenv("X11VNC_THREADS_NEW_FB_SLEEP"));
- } else if (subwin) {
- ms = 500;
- } else {
- ms = 1000;
- }
- usleep(ms * 1000);
-
- for (i=0; i < 5; i++) {
- fb_pend = 0;
- iter = rfbGetClientIterator(screen);
- while ((cl = rfbClientIteratorNext(iter)) != NULL) {
- s = lcs(cl);
- if (cl->newFBSizePending) {
- fb_pend++;
- rfbLog("pending fb size: %p %.6f %s\n", cl, dnowx(), s);
- }
- }
- rfbReleaseClientIterator(iter);
- if (fb_pend > 0) {
- rfbLog("do_new_fb: newFBSizePending extra -threads sleep (%d)\n", i+1);
- usleep(ms * 1000);
- } else {
- break;
- }
- }
- for (i=0; i < 5; i++) {
- int stuck = 0, tot = 0, j = 0;
- iter = rfbGetClientIterator(screen);
- while ((cl = rfbClientIteratorNext(iter)) != NULL) {
- if (j < _bytes0_size) {
- int db = rfbStatGetSentBytesIfRaw(cl) - _bytes0[j];
- int Bpp = cl->format.bitsPerPixel / 8;
-
- s = lcs(cl);
- rfbLog("addl bytes sent: %p %.6f %s %d %d\n",
- cl, dnowx(), s, db, _bytes0[j]);
-
- if (i==0) {
- if (db < Bpp * dpy_x * dpy_y) {
- stuck++;
- }
- } else if (i==1) {
- if (db < 0.5 * Bpp * dpy_x * dpy_y) {
- stuck++;
- }
- } else {
- if (db <= 0) {
- stuck++;
- }
- }
- }
- tot++;
- j++;
- }
- rfbReleaseClientIterator(iter);
- if (stuck > 0) {
- rfbLog("clients stuck: %d/%d sleep(%d)\n", stuck, tot, i);
- usleep(2 * ms * 1000);
- } else {
- break;
- }
- }
-}
-
-static void prep_clients_for_new_fb(void) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- if (!use_threads || !screen) {
- return;
- }
- iter = rfbGetClientIterator(screen);
- while ((cl = rfbClientIteratorNext(iter)) != NULL) {
- if (!cl->newFBSizePending) {
- rfbLog("** set_new_fb_size_pending client: %p\n", cl);
- cl->newFBSizePending = TRUE;
- }
- cl->cursorWasChanged = FALSE;
- cl->cursorWasMoved = FALSE;
- }
- rfbReleaseClientIterator(iter);
-}
-
-void do_new_fb(int reset_mem) {
- XImage *fb;
-
- /* for threaded we really should lock libvncserver out. */
- if (use_threads) {
- int ms = 1000;
- if (getenv("X11VNC_THREADS_NEW_FB_SLEEP")) {
- ms = atoi(getenv("X11VNC_THREADS_NEW_FB_SLEEP"));
- } else if (subwin) {
- ms = 500;
- } else {
- ms = 1000;
- }
- rfbLog("Warning: changing framebuffers in threaded mode may be unstable.\n");
- threads_drop_input = 1;
- usleep(ms * 1000);
- }
-
- INPUT_LOCK;
- lock_client_sends(1);
-
- if (use_threads) {
- settle_clients(1);
- }
-
-#ifdef MACOSX
- if (macosx_console) {
- macosxCG_fini();
- }
-#endif
- if (reset_mem == 1) {
- /* reset_mem == 2 is a hack for changing users... */
- clean_shm(0);
- free_tiles();
- }
-
- free_old_fb();
-
- fb = initialize_xdisplay_fb();
-
- initialize_screen(NULL, NULL, fb);
-
- if (reset_mem) {
- initialize_tiles();
- initialize_blackouts_and_xinerama();
- initialize_polling_images();
- }
- if (ncache) {
- check_ncache(1, 0);
- }
-
- prep_clients_for_new_fb();
- lock_client_sends(0);
- INPUT_UNLOCK;
-
- if (use_threads) {
- /* need to let things settle... */
- settle_clients(0);
- threads_drop_input = 0;
- }
-}
-
-static void remove_fake_fb(void) {
- if (! screen) {
- return;
- }
- rfbLog("removing fake fb: 0x%x\n", fake_fb);
-
- do_new_fb(1);
-
- /*
- * fake_fb is freed in do_new_fb(), but we set to NULL here to
- * indicate it is gone.
- */
- fake_fb = NULL;
-}
-
-static void rfb_new_framebuffer(rfbScreenInfoPtr rfbScreen, char *framebuffer,
- int width,int height, int bitsPerSample,int samplesPerPixel,
- int bytesPerPixel) {
-
- rfbNewFramebuffer(rfbScreen, framebuffer, width, height, bitsPerSample,
- samplesPerPixel, bytesPerPixel);
-
-}
-
-static void install_fake_fb(int w, int h, int bpp) {
- int bpc;
- if (! screen) {
- return;
- }
- lock_client_sends(1);
- if (fake_fb) {
- free(fake_fb);
- }
- fake_fb = (char *) calloc(w*h*bpp/8, 1);
- if (! fake_fb) {
- rfbLog("could not create fake fb: %dx%d %d\n", w, h, bpp);
- lock_client_sends(0);
- return;
- }
- bpc = guess_bits_per_color(bpp);
- rfbLog("installing fake fb: %dx%d %d\n", w, h, bpp);
- rfbLog("rfbNewFramebuffer(0x%x, 0x%x, %d, %d, %d, %d, %d)\n",
- screen, fake_fb, w, h, bpc, 1, bpp/8);
-
- rfb_new_framebuffer(screen, fake_fb, w, h, bpc, 1, bpp/8);
- lock_client_sends(0);
-}
-
-void check_padded_fb(void) {
- if (! fake_fb) {
- return;
- }
- if (unixpw_in_progress) return;
-
- if (time(NULL) > pad_geometry_time+1 && all_clients_initialized()) {
- remove_fake_fb();
- }
-}
-
-void install_padded_fb(char *geom) {
- int w, h;
- int ok = 1;
- if (! geom || *geom == '\0') {
- ok = 0;
- } else if (sscanf(geom, "%dx%d", &w, &h) != 2) {
- ok = 0;
- }
- w = nabs(w);
- h = nabs(h);
-
- if (w < 5) w = 5;
- if (h < 5) h = 5;
-
- if (!ok) {
- rfbLog("skipping invalid pad geometry: '%s'\n", NONUL(geom));
- return;
- }
- install_fake_fb(w, h, bpp);
- pad_geometry_time = time(NULL);
-}
-
-static void initialize_snap_fb(void) {
- RAWFB_RET_VOID
- if (snap_fb) {
- free(snap_fb);
- }
- snap = XGetImage_wr(dpy, window, 0, 0, dpy_x, dpy_y, AllPlanes,
- ZPixmap);
- snap_fb = snap->data;
-}
-
-static rfbClient* client = NULL;
-
-void vnc_reflect_bell(rfbClient *cl) {
- if (cl) {}
- if (sound_bell) {
- if (unixpw_in_progress) {
- return;
- }
- if (! all_clients_initialized()) {
- rfbLog("vnc_reflect_bell: not sending bell: "
- "uninitialized clients\n");
- } else {
- if (screen && client_count) {
- rfbSendBell(screen);
- }
- }
- }
-}
-
-void vnc_reflect_recv_cuttext(rfbClient *cl, const char *str, int len) {
- if (cl) {}
- if (unixpw_in_progress) {
- return;
- }
- if (! watch_selection) {
- return;
- }
- if (! all_clients_initialized()) {
- rfbLog("vnc_reflect_recv_cuttext: no send: uninitialized clients\n");
- return; /* some clients initializing, cannot send */
- }
- rfbSendServerCutText(screen, (char *)str, len);
-}
-
-void vnc_reflect_got_update(rfbClient *cl, int x, int y, int w, int h) {
- if (cl) {}
- if (use_xdamage) {
- static int first = 1;
- if (first) {
- collect_non_X_xdamage(-1, -1, -1, -1, 0);
- first = 0;
- }
- collect_non_X_xdamage(x, y, w, h, 1);
- }
-}
-
-void vnc_reflect_got_cursorshape(rfbClient *cl, int xhot, int yhot, int width, int height, int bytesPerPixel) {
- static int serial = 1;
- int i, j;
- char *pixels = NULL;
- unsigned long r, g, b;
- unsigned int ui = 0;
- unsigned long red_mask, green_mask, blue_mask;
-
- if (cl) {}
- if (unixpw_in_progress) {
- return;
- }
- if (! all_clients_initialized()) {
- rfbLog("vnc_reflect_got_copyshape: no send: uninitialized clients\n");
- return; /* some clients initializing, cannot send */
- }
- if (! client->rcSource) {
- return;
- }
- if (bytesPerPixel != 1 && bytesPerPixel != 2 && bytesPerPixel != 4) {
- return;
- }
-
- red_mask = (client->format.redMax << client->format.redShift);
- green_mask = (client->format.greenMax << client->format.greenShift);
- blue_mask = (client->format.blueMax << client->format.blueShift);
-
- pixels = (char *)malloc(4*width*height);
- for (j=0; j<height; j++) {
- for (i=0; i<width; i++) {
- unsigned int* uip;
- unsigned char* uic;
- int m;
- if (bytesPerPixel == 1) {
- unsigned char* p = (unsigned char *) client->rcSource;
- ui = (unsigned long) *(p + j * width + i);
- } else if (bytesPerPixel == 2) {
- unsigned short* p = (unsigned short *) client->rcSource;
- ui = (unsigned long) *(p + j * width + i);
- } else if (bytesPerPixel == 4) {
- unsigned int* p = (unsigned int *) client->rcSource;
- ui = (unsigned long) *(p + j * width + i);
- }
- r = (red_mask & ui) >> client->format.redShift;
- g = (green_mask & ui) >> client->format.greenShift;
- b = (blue_mask & ui) >> client->format.blueShift;
-
- r = (255 * r) / client->format.redMax;
- g = (255 * g) / client->format.greenMax;
- b = (255 * b) / client->format.blueMax;
-
- ui = (r << 16 | g << 8 | b << 0) ;
-
- uic = (unsigned char *)client->rcMask;
- m = (int) *(uic + j * width + i);
- if (m) {
- ui |= 0xff000000;
- }
- uip = (unsigned int *)pixels;
- *(uip + j * width + i) = ui;
- }
- }
-
- store_cursor(serial++, (unsigned long*) pixels, width, height, 32, xhot, yhot);
- free(pixels);
- set_cursor(cursor_x, cursor_y, get_which_cursor());
-}
-
-rfbBool vnc_reflect_cursor_pos(rfbClient *cl, int x, int y) {
- if (cl) {}
- if (debug_pointer) {
- rfbLog("vnc_reflect_cursor_pos: %d %d\n", x, y);
- }
- if (unixpw_in_progress) {
- if (debug_pointer) {
- rfbLog("vnc_reflect_cursor_pos: unixpw_in_progress%d\n", unixpw_in_progress);
- }
- return TRUE;
- }
- if (! all_clients_initialized()) {
- rfbLog("vnc_reflect_cursor_pos: no send: uninitialized clients\n");
- return TRUE; /* some clients initializing, cannot send */
- }
-
- cursor_position(x, y);
- set_cursor(x, y, get_which_cursor());
-
- return TRUE;
-}
-
-static void from_libvncclient_CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
- int i,j;
-
-#define COPY_RECT_FROM_RECT(BPP) \
- { \
- uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \
- if (dest_y < src_y) { \
- for(j = dest_y*client->width; j < (dest_y+h)*client->width; j += client->width) { \
- if (dest_x < src_x) { \
- for(i = dest_x; i < dest_x+w; i++) { \
- ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
- } \
- } else { \
- for(i = dest_x+w-1; i >= dest_x; i--) { \
- ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
- } \
- } \
- } \
- } else { \
- for(j = (dest_y+h-1)*client->width; j >= dest_y*client->width; j-=client->width) { \
- if (dest_x < src_x) { \
- for(i = dest_x; i < dest_x+w; i++) { \
- ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
- } \
- } else { \
- for(i = dest_x+w-1; i >= dest_x; i--) { \
- ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
- } \
- } \
- } \
- } \
- }
-
- switch(client->format.bitsPerPixel) {
- case 8: COPY_RECT_FROM_RECT(8); break;
- case 16: COPY_RECT_FROM_RECT(16); break;
- case 32: COPY_RECT_FROM_RECT(32); break;
- default:
- rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
- }
-}
-
-void vnc_reflect_got_copyrect(rfbClient *cl, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
- sraRegionPtr reg;
- int dx, dy, rc = -1;
- static int last_dx = 0, last_dy = 0;
- if (cl) {}
- if (unixpw_in_progress) {
- return;
- }
- if (! all_clients_initialized()) {
- rfbLog("vnc_reflect_got_copyrect: no send: uninitialized clients\n");
- return; /* some clients initializing, cannot send */
- }
- dx = dest_x - src_x;
- dy = dest_y - src_y;
- if (dx != last_dx || dy != last_dy) {
- rc = fb_push_wait(0.05, FB_COPY|FB_MOD);
- }
- if (0) fprintf(stderr, "vnc_reflect_got_copyrect: %03dx%03d+%03d+%03d %3d %3d rc=%d\n", dest_x, dest_y, w, h, dx, dy, rc);
- reg = sraRgnCreateRect(dest_x, dest_y, dest_x + w, dest_y + h);
- do_copyregion(reg, dx, dy, 0);
- sraRgnDestroy(reg);
-
- last_dx = dx;
- last_dy = dy;
-
- from_libvncclient_CopyRectangleFromRectangle(cl, src_x, src_y, w, h, dest_x, dest_y);
-}
-
-rfbBool vnc_reflect_resize(rfbClient *cl) {
- static int first = 1;
- if(cl->frameBuffer) {
- free(cl->frameBuffer);
- }
- cl->frameBuffer= malloc(cl->width * cl->height * cl->format.bitsPerPixel/8);
- rfbLog("vnc_reflect_resize: %dx%dx%d first=%d\n", cl->width, cl->height,
- cl->format.bitsPerPixel, first);
- if (!first) {
- do_new_fb(1);
- }
- first = 0;
- return cl->frameBuffer ? TRUE : FALSE;
-}
-
-#ifdef rfbCredentialTypeX509
-static rfbCredential* vnc_reflect_get_credential(rfbClient* client, int type) {
- char *pass = getenv("X11VNC_REFLECT_PASSWORD");
- char *user = getenv("X11VNC_REFLECT_USER");
- char *cert = getenv("X11VNC_REFLECT_CACERT");
- char *ccrl = getenv("X11VNC_REFLECT_CACRL");
- char *clic = getenv("X11VNC_REFLECT_CLIENTCERT");
- char *clik = getenv("X11VNC_REFLECT_CLIENTKEY");
- int db = 0;
- if (client) {}
-if (db) fprintf(stderr, "type: %d\n", type);
-#ifdef rfbCredentialTypeUser
- if (type == rfbCredentialTypeUser) {
- if (!pass && !user) {
- return NULL;
- } else {
- rfbCredential *rc = (rfbCredential *) calloc(sizeof(rfbCredential), 1);
- rc->userCredential.username = (user ? strdup(user) : NULL);
- rc->userCredential.password = (pass ? strdup(pass) : NULL);
- return rc;
- }
- }
-#endif
- if (type == rfbCredentialTypeX509) {
-if (db) fprintf(stderr, "cert: %s\n", cert);
-if (db) fprintf(stderr, "ccrl: %s\n", ccrl);
-if (db) fprintf(stderr, "clic: %s\n", clic);
-if (db) fprintf(stderr, "clik: %s\n", clik);
- if (!cert && !ccrl && !clic && !clik) {
- return NULL;
- } else {
- rfbCredential *rc = (rfbCredential *) calloc(sizeof(rfbCredential), 1);
- rc->x509Credential.x509CACertFile = (cert ? strdup(cert) : NULL);
- rc->x509Credential.x509CACrlFile = (ccrl ? strdup(ccrl) : NULL);
- rc->x509Credential.x509ClientCertFile = (clic ? strdup(clic) : NULL);
- rc->x509Credential.x509ClientKeyFile = (clik ? strdup(clik) : NULL);
- return rc;
- }
- }
- return NULL;
-}
-#endif
-
-static char* vnc_reflect_get_password(rfbClient* client) {
- char *q, *p, *str = getenv("X11VNC_REFLECT_PASSWORD");
- int len = 110;
-
- if (client) {}
-
- if (str) {
- len += 2*strlen(str);
- }
- p = (char *) calloc(len, 1);
- if (!str || strlen(str) == 0) {
- fprintf(stderr, "VNC Reflect Password: ");
- fgets(p, 100, stdin);
- } else {
- if (strstr(str, "file:") == str) {
- FILE *f = fopen(str + strlen("file:"), "r");
- if (f) {
- fgets(p, 100, f);
- fclose(f);
- }
- }
- if (p[0] == '\0') {
- strncpy(p, str, 100);
- }
- }
- q = p;
- while (*q != '\0') {
- if (*q == '\n') {
- *q = '\0';
- }
- q++;
- }
- return p;
-}
-
-char *vnc_reflect_guess(char *str, char **raw_fb_addr) {
-
- static int first = 1;
- char *hp = str + strlen("vnc:");
- char *at = NULL;
- int argc = 0, i;
- char *argv[16];
- char str2[256];
- char *str0 = strdup(str);
-
- if (client == NULL) {
- int bitsPerSample = 8;
- int samplesPerPixel = 3;
- int bytesPerPixel = 4;
- char *s;
- s = getenv("X11VNC_REFLECT_bitsPerSample");
- if (s) bitsPerSample = atoi(s);
- s = getenv("X11VNC_REFLECT_samplesPerPixel");
- if (s) samplesPerPixel = atoi(s);
- s = getenv("X11VNC_REFLECT_bytesPerPixel");
- if (s) bytesPerPixel = atoi(s);
- rfbLog("rfbGetClient(bitsPerSample=%d, samplesPerPixel=%d, bytesPerPixel=%d)\n",
- bitsPerSample, samplesPerPixel, bytesPerPixel);
- client = rfbGetClient(bitsPerSample, samplesPerPixel, bytesPerPixel);
- }
-
- rfbLog("rawfb: %s\n", str);
-
- at = strchr(hp, '@');
- if (at) {
- *at = '\0';
- at++;
- }
-
- client->appData.useRemoteCursor = TRUE;
- client->canHandleNewFBSize = TRUE;
-
- client->HandleCursorPos = vnc_reflect_cursor_pos;
- client->GotFrameBufferUpdate = vnc_reflect_got_update;
- client->MallocFrameBuffer = vnc_reflect_resize;
- client->Bell = vnc_reflect_bell;
-#if 0
- client->SoftCursorLockArea = NULL;
- client->SoftCursorUnlockScreen = NULL;
- client->FinishedFrameBufferUpdate = NULL;
- client->HandleKeyboardLedState = NULL;
- client->HandleTextChat = NULL;
-#endif
- client->GotXCutText = vnc_reflect_recv_cuttext;
- client->GotCursorShape = vnc_reflect_got_cursorshape;
- client->GotCopyRect = vnc_reflect_got_copyrect;
-
- if (getenv("X11VNC_REFLECT_PASSWORD")) {
- client->GetPassword = vnc_reflect_get_password;
- }
-#ifdef rfbCredentialTypeX509
- client->GetCredential = NULL;
- if (0 || getenv("LIBVNCCLIENT_GET_CREDENTIAL")) {
- client->GetCredential = vnc_reflect_get_credential;
- }
-#endif
-
- if (first) {
- argv[argc++] = "x11vnc_rawfb_vnc";
- if (strstr(hp, "listen") == hp) {
- char *q = strrchr(hp, ':');
- argv[argc++] = strdup("-listen");
- if (q) {
- client->listenPort = atoi(q+1);
- } else {
- client->listenPort = LISTEN_PORT_OFFSET;
- }
- } else {
- argv[argc++] = strdup(hp);
- }
-
- if (! rfbInitClient(client, &argc, argv)) {
- rfbLog("vnc_reflector failed for: %s\n", str0);
- clean_up_exit(1);
- }
- }
-
- if (at) {
- sprintf(str2, "map:/dev/null@%s", at);
- } else {
- unsigned long red_mask, green_mask, blue_mask;
- red_mask = (client->format.redMax << client->format.redShift);
- green_mask = (client->format.greenMax << client->format.greenShift);
- blue_mask = (client->format.blueMax << client->format.blueShift);
- sprintf(str2, "map:/dev/null@%dx%dx%d:0x%lx/0x%lx/0x%lx",
- client->width, client->height, client->format.bitsPerPixel,
- red_mask, green_mask, blue_mask);
- }
- *raw_fb_addr = (char *) client->frameBuffer;
- free(str0);
-
- if (first) {
- setup_cursors_and_push();
-
- for (i=0; i<10; i++) {
- vnc_reflect_process_client();
- }
- }
- first = 0;
-
- return strdup(str2);
-}
-
-rfbBool vnc_reflect_send_pointer(int x, int y, int mask) {
- int rc;
- if (mask >= 0) {
- got_user_input++;
- got_pointer_input++;
- last_pointer_time = time(NULL);
- }
-
- if (clipshift) {
- x += coff_x;
- y += coff_y;
- }
-
- if (cursor_x != x || cursor_y != y) {
- last_pointer_motion_time = dnow();
- }
-
- cursor_x = x;
- cursor_y = y;
-
- /* record the x, y position for the rfb screen as well. */
- cursor_position(x, y);
-
- /* change the cursor shape if necessary */
- rc = set_cursor(x, y, get_which_cursor());
- cursor_changes += rc;
-
- return SendPointerEvent(client, x, y, mask);
-}
-
-rfbBool vnc_reflect_send_key(uint32_t key, rfbBool down) {
- return SendKeyEvent(client, key, down);
-}
-
-rfbBool vnc_reflect_send_cuttext(char *str, int len) {
- return SendClientCutText(client, str, len);
-}
-
-void vnc_reflect_process_client(void) {
- int num;
- if (client == NULL) {
- return;
- }
- num = WaitForMessage(client, 1000);
- if (num > 0) {
- if (!HandleRFBServerMessage(client)) {
- rfbLog("vnc_reflect_process_client: read failure to server\n");
- shut_down = 1;
- }
- }
-}
-
-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
-
-XImage *initialize_raw_fb(int reset) {
- char *str, *rstr, *q;
- int w, h, b, shmid = 0;
- unsigned long rm = 0, gm = 0, bm = 0, tm;
- static XImage ximage_struct; /* n.b.: not (XImage *) */
- static XImage ximage_struct_snap;
- int closedpy = 1, i, m, db = 0;
- int do_macosx = 0;
- int do_reflect = 0;
- char *unlink_me = NULL;
-
- static char *last_file = NULL;
- static int last_mode = 0;
-
- if (reset && last_mode) {
- int fd;
- if (last_mode != RAWFB_MMAP && last_mode != RAWFB_FILE) {
- return NULL;
- }
- if (last_mode == RAWFB_MMAP) {
- munmap(raw_fb_addr, raw_fb_mmap);
- }
- if (raw_fb_fd >= 0) {
- close(raw_fb_fd);
- }
- raw_fb_fd = -1;
-if (db) fprintf(stderr, "initialize_raw_fb reset\n");
-
- fd = -1;
- if (rawfb_dev_video) {
- fd = open(last_file, O_RDWR);
- }
- if (fd < 0) {
- fd = open(last_file, O_RDONLY);
- }
- if (fd < 0) {
- rfbLogEnable(1);
- rfbLog("failed to rawfb file: %s\n", last_file);
- rfbLogPerror("open");
- clean_up_exit(1);
- }
- raw_fb_fd = fd;
- if (last_mode == RAWFB_MMAP) {
- raw_fb_addr = mmap(0, raw_fb_mmap, PROT_READ,
- MAP_SHARED, fd, 0);
-
- if (raw_fb_addr == MAP_FAILED || raw_fb_addr == NULL) {
- rfbLogEnable(1);
- rfbLog("failed to mmap file: %s\n", last_file);
- rfbLog(" raw_fb_addr: %p\n", raw_fb_addr);
- rfbLogPerror("mmap");
- clean_up_exit(1);
- }
- }
- return NULL;
- }
-
-#ifdef MACOSX
- if (raw_fb_addr != NULL && macosx_console && raw_fb_addr == macosx_get_fb_addr()) {
- raw_fb_addr = NULL;
- }
-#endif
-
- if (raw_fb_addr || raw_fb_seek) {
- if (raw_fb_shm) {
- shmdt(raw_fb_addr);
-#if LIBVNCSERVER_HAVE_MMAP
- } else if (raw_fb_mmap) {
- munmap(raw_fb_addr, raw_fb_mmap);
- if (raw_fb_fd >= 0) {
- close(raw_fb_fd);
- }
- raw_fb_fd = -1;
-#endif
- } else if (raw_fb_seek) {
- if (raw_fb_fd >= 0) {
- close(raw_fb_fd);
- }
- raw_fb_fd = -1;
- }
- raw_fb_addr = NULL;
- raw_fb_mmap = 0;
- raw_fb_seek = 0;
- }
- if (! raw_fb_str) {
- return NULL;
- }
-
- if (raw_fb_str[0] == '+') {
- rstr = strdup(raw_fb_str+1);
- closedpy = 0;
- if (! window) {
- window = rootwin;
- }
- } else {
- rstr = strdup(raw_fb_str);
- }
-
- /* testing aliases */
- if (!strcasecmp(rstr, "NULL") || !strcasecmp(rstr, "ZERO")
- || !strcasecmp(rstr, "NONE")) {
- rstr = strdup("map:/dev/zero@640x480x32");
- } else if (!strcasecmp(rstr, "NULLBIG") || !strcasecmp(rstr, "NONEBIG")) {
- rstr = strdup("map:/dev/zero@1024x768x32");
- }
- if (!strcasecmp(rstr, "RAND")) {
- rstr = strdup("file:/dev/urandom@128x128x16");
- } else if (!strcasecmp(rstr, "RANDBIG")) {
- rstr = strdup("file:/dev/urandom@640x480x16");
- } else if (!strcasecmp(rstr, "RANDHUGE")) {
- rstr = strdup("file:/dev/urandom@1024x768x16");
- }
- if (strstr(rstr, "solid=") == rstr) {
- char *n = rstr + strlen("solid=");
- char tmp[] = "/tmp/rawfb_solid.XXXXXX";
- char str[100];
- unsigned int vals[1024], val;
- int x, y, fd, w = 1024, h = 768;
- if (strstr(n, "0x")) {
- if (sscanf(n, "0x%x", &val) != 1) {
- val = 0;
- }
- }
- if (val == 0) {
- val = get_pixel(n);
- }
- if (val == 0) {
- val = 0xFF00FF;
- }
- fd = mkstemp(tmp);
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- vals[x] = val;
- }
- write(fd, (char *)vals, 4 * w);
- }
- close(fd);
- fd = open(tmp, O_WRONLY);
- unlink_me = strdup(tmp);
- sprintf(str, "map:%s@%dx%dx32", tmp, w, h);
- rstr = strdup(str);
- } else if (strstr(rstr, "swirl") == rstr) {
- char tmp[] = "/tmp/rawfb_swirl.XXXXXX";
- char str[100];
- unsigned int val[1024];
- unsigned int c1, c2, c3, c4;
- int x, y, fd, w = 1024, h = 768;
- fd = mkstemp(tmp);
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- c1 = 0;
- c2 = ((x+y)*128)/(w+h);
- c3 = (x*128)/w;
- c4 = (y*256)/h;
- val[x] = (c1 << 24) | (c2 << 16) | (c3 << 8) | (c4 << 0);
- }
- write(fd, (char *)val, 4 * w);
- }
- close(fd);
- fd = open(tmp, O_WRONLY);
- unlink_me = strdup(tmp);
- sprintf(str, "map:%s@%dx%dx32", tmp, w, h);
- rstr = strdup(str);
- }
-
-
- if ( (q = strstr(rstr, "setup:")) == rstr) {
- FILE *pipe;
- char line[1024], *t;
-
- set_child_info();
- q += strlen("setup:");
- /* rawfb-setup */
- if (no_external_cmds || !cmd_ok("rawfb-setup")) {
- rfbLogEnable(1);
- rfbLog("cannot run external commands in -nocmds "
- "mode:\n");
- rfbLog(" \"%s\"\n", q);
- rfbLog(" exiting.\n");
- clean_up_exit(1);
- }
- rfbLog("running command to setup rawfb: %s\n", q);
- close_exec_fds();
- pipe = popen(q, "r");
- if (! pipe) {
- rfbLogEnable(1);
- rfbLog("popen of setup command failed.\n");
- rfbLogPerror("popen");
- clean_up_exit(1);
- }
- line[0] = '\0';
- if (fgets(line, 1024, pipe) == NULL) {
- rfbLogEnable(1);
- rfbLog("read of setup command failed.\n");
- clean_up_exit(1);
- }
- pclose(pipe);
- str = strdup(line);
- t = str;
- while (*t != '\0') {
- if (*t == '\n') {
- *t = '\0';
- }
- t++;
- }
- rfbLog("setup command returned: %s\n", str);
-
- } else {
- str = strdup(rstr);
- }
-
- raw_fb_shm = 0;
- raw_fb_mmap = 0;
- raw_fb_seek = 0;
- raw_fb_fd = -1;
- raw_fb_addr = NULL;
- raw_fb_offset = 0;
- raw_fb_bytes_per_line = 0;
- rawfb_vnc_reflect = 0;
-
- last_mode = 0;
- if (last_file) {
- free(last_file);
- last_file = NULL;
- }
- if (strstr(str, "Video") == str) {
- if (pipeinput_str != NULL) {
- free(pipeinput_str);
- }
- pipeinput_str = strdup("VID");
- initialize_pipeinput();
- str[0] = 'v';
- }
-
- if (strstr(str, "video") == str || strstr(str, "/dev/video") == str) {
- char *str2 = v4l_guess(str, &raw_fb_fd);
- if (str2 == NULL) {
- rfbLog("v4l_guess failed for: %s\n", str);
- clean_up_exit(1);
- }
- str = str2;
- rfbLog("v4l_guess returned: %s\n", str);
- rawfb_dev_video = 1;
- } 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, "vt") == str) {
- char *str2 = console_guess(str, &raw_fb_fd);
- if (str2 == NULL) {
- rfbLog("console_guess failed for: %s\n", str);
- clean_up_exit(1);
- }
- str = str2;
- rfbLog("console_guess returned: %s\n", str);
- } else if (strstr(str, "vnc:") == str) {
- char *str2 = vnc_reflect_guess(str, &raw_fb_addr);
-
- rawfb_vnc_reflect = 1;
- do_reflect = 1;
-
- str = str2;
- rfbLog("vnc_reflector set rawfb str to: %s\n", str);
- if (pipeinput_str == NULL) {
- pipeinput_str = strdup("VNC");
- }
- initialize_pipeinput();
- }
-
- if (closedpy && !view_only && got_noviewonly) {
- rfbLog("not closing X DISPLAY under -noviewonly option.\n");
- closedpy = 0;
- if (! window) {
- window = rootwin;
- }
- }
-
- if (! raw_fb_orig_dpy && dpy) {
- raw_fb_orig_dpy = strdup(DisplayString(dpy));
- }
-#ifndef BOLDLY_CLOSE_DISPLAY
-#define BOLDLY_CLOSE_DISPLAY 1
-#endif
-#if BOLDLY_CLOSE_DISPLAY
- if (closedpy) {
- if (dpy) {
- rfbLog("closing X DISPLAY: %s in rawfb mode.\n",
- DisplayString(dpy));
- XCloseDisplay_wr(dpy); /* yow! */
- }
- dpy = NULL;
- }
-#endif
-
- /*
- * -rawfb shm:163938442@640x480x32:ff/ff00/ff0000+3000
- * -rawfb map:/path/to/file@640x480x32:ff/ff00/ff0000
- * -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) {
- if (sscanf(q, "+%d", &raw_fb_offset) == 1) {
- *q = '\0';
- } else {
- raw_fb_offset = 0;
- }
- }
- /* :R/G/B masks */
- if ((q = strrchr(str, ':')) != NULL) {
- if (sscanf(q, ":%lx/%lx/%lx", &rm, &gm, &bm) == 3) {
- *q = '\0';
- } else if (sscanf(q, ":0x%lx/0x%lx/0x%lx", &rm, &gm, &bm)== 3) {
- *q = '\0';
- } else if (sscanf(q, ":%lu/%lu/%lu", &rm, &gm, &bm) == 3) {
- *q = '\0';
- } else {
- rm = 0;
- gm = 0;
- bm = 0;
- }
- }
- if ((q = strrchr(str, '@')) == NULL) {
- rfbLogEnable(1);
- rfbLog("invalid rawfb str: %s\n", str);
- clean_up_exit(1);
- }
-
- if (strrchr(q, '-')) {
- char *q2 = strrchr(q, '-');
- raw_fb_bytes_per_line = atoi(q2+1);
- *q2 = '\0';
- }
- /* @WxHxB */
- if (sscanf(q, "@%dx%dx%d", &w, &h, &b) != 3) {
- rfbLogEnable(1);
- rfbLog("invalid rawfb str: %s\n", str);
- clean_up_exit(1);
- }
- *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;
- off_y = 0;
-
- if (rawfb_dev_video) {
- if (b == 24) {
- rfbLog("enabling -24to32 for 24bpp video\n");
- xform24to32 = 1;
- } else {
- if (xform24to32) {
- rfbLog("disabling -24to32 for 24bpp video\n");
- }
- xform24to32 = 0;
- }
- }
-
- if (xform24to32) {
- if (b != 24) {
- rfbLog("warning: -24to32 mode and bpp=%d\n", b);
- }
- b = 32;
- }
- if (strstr(str, "snap:") == str) {
- use_snapfb = 1;
- str[0] = 'f'; str[1] = 'i'; str[2] = 'l'; str[3] = 'e';
- }
-
- if (strstr(str, "shm:") != str && strstr(str, "mmap:") != str &&
- strstr(str, "map:") != str && strstr(str, "file:") != str) {
- /* hmmm, not following directions, see if map: applies */
- struct stat sbuf;
- if (stat(str, &sbuf) == 0) {
- char *newstr;
- int len = strlen("map:") + strlen(str) + 1;
- rfbLog("no type prefix: %s\n", raw_fb_str);
- rfbLog(" but file exists, so assuming: map:%s\n",
- raw_fb_str);
- newstr = (char *) malloc(len);
- strcpy(newstr, "map:");
- strcat(newstr, str);
- free(str);
- str = newstr;
- }
- }
-
- if (sscanf(str, "shm:%d", &shmid) == 1) {
- /* shm:N */
-#if LIBVNCSERVER_HAVE_XSHM || LIBVNCSERVER_HAVE_SHMAT
- raw_fb_addr = (char *) shmat(shmid, 0, SHM_RDONLY);
- if (! raw_fb_addr) {
- rfbLogEnable(1);
- rfbLog("failed to attach to shm: %d, %s\n", shmid, str);
- rfbLogPerror("shmat");
- clean_up_exit(1);
- }
- raw_fb_shm = 1;
- rfbLog("rawfb: shm: %d W: %d H: %d B: %d addr: %p\n",
- shmid, w, h, b, raw_fb_addr);
- last_mode = RAWFB_SHM;
-#else
- rfbLogEnable(1);
- rfbLog("x11vnc was compiled without shm support.\n");
- rfbLogPerror("shmat");
- clean_up_exit(1);
-#endif
- } else if (strstr(str, "map:") == str || strstr(str, "mmap:") == str
- || strstr(str, "file:") == str) {
- /* map:/path/... or file:/path */
- int fd, do_mmap = 1, size;
- struct stat sbuf;
-
- if (*str == 'f') {
- do_mmap = 0;
- }
- q = strchr(str, ':');
- q++;
-
- macosx_console = 0;
- if (strstr(q, "macosx:") == q) {
- /* mmap:macosx:/dev/null@... */
- q += strlen("macosx:");
- do_macosx = 1;
- do_mmap = 0;
- macosx_console = 1;
- }
-
- last_file = strdup(q);
-
- fd = raw_fb_fd;
- if (fd < 0 && rawfb_dev_video) {
- fd = open(q, O_RDWR);
- }
- if (fd < 0) {
- fd = open(q, O_RDONLY);
- }
- if (fd < 0) {
- 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 (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;
- }
- if (fstat(fd, &sbuf) == 0) {
- if (S_ISREG(sbuf.st_mode)) {
- if (0) size = sbuf.st_size;
- } else {
- rfbLog("raw fb is non-regular file: %s\n", q);
- }
- }
-
- if (do_macosx) {
- raw_fb_addr = macosx_get_fb_addr();
- raw_fb_mmap = size;
- rfbLog("rawfb: macosx fb: %s\n", q);
- rfbLog(" w: %d h: %d b: %d addr: %p sz: %d\n", w, h,
- b, raw_fb_addr, size);
- last_mode = 0;
- } else if (do_reflect) {
- raw_fb_mmap = size;
- rfbLog("rawfb: vnc fb: %s\n", q);
- rfbLog(" w: %d h: %d b: %d addr: %p sz: %d\n", w, h,
- b, raw_fb_addr, size);
- last_mode = 0;
-
- } else if (do_mmap) {
-#if LIBVNCSERVER_HAVE_MMAP
- raw_fb_addr = mmap(0, size, PROT_READ, MAP_SHARED,
- fd, 0);
-
- if (raw_fb_addr == MAP_FAILED || raw_fb_addr == NULL) {
- rfbLogEnable(1);
- rfbLog("failed to mmap file: %s, %s\n", q, str);
- rfbLog(" raw_fb_addr: %p\n", raw_fb_addr);
- rfbLogPerror("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");
- raw_fb_seek = size;
- last_mode = RAWFB_FILE;
-#endif
- } else {
- raw_fb_seek = size;
- last_mode = RAWFB_FILE;
-
- rfbLog("rawfb: seek file: %s\n", q);
- rfbLog(" W: %d H: %d B: %d sz: %d\n", w, h, b, size);
- }
- } else {
- rfbLogEnable(1);
- rfbLog("invalid rawfb str: %s\n", str);
- clean_up_exit(1);
- }
-
- if (unlink_me) {
- unlink(unlink_me);
- }
-
- if (! raw_fb_image) {
- raw_fb_image = &ximage_struct;
- }
-
- initialize_clipshift();
-
- if (raw_fb_bytes_per_line == 0) {
- raw_fb_bytes_per_line = dpy_x*b/8;
-
- /*
- * Put cases here were we can determine that
- * raw_bytes_per_line != dpy_x*b/8
- */
-#ifdef MACOSX
- if (do_macosx) {
- raw_fb_bytes_per_line = macosxCG_CGDisplayBytesPerRow();
- }
-#endif
- }
-
- raw_fb_image->bytes_per_line = dpy_x * b/8;
- raw_fb = (char *) malloc(dpy_y * dpy_x * b/8);
- raw_fb_image->data = raw_fb;
- raw_fb_image->format = ZPixmap;
- raw_fb_image->width = dpy_x;
- raw_fb_image->height = dpy_y;
- raw_fb_image->bits_per_pixel = b;
- raw_fb_image->bitmap_unit = -1;
-
-
- if (use_snapfb && (raw_fb_seek || raw_fb_mmap)) {
- int b_use = b;
- if (snap_fb) {
- free(snap_fb);
- }
- if (b_use == 32 && xform24to32) {
- /*
- * The actual framebuffer (e.g. mapped addr) and
- * snap fb must be the same bpp. E.g. both 24bpp.
- * Reading FROM snap to utility image will be
- * transformed 24->32 in copy_raw_fb_24_to_32.
- *
- * addr -> snap -> (scanline, fullscreen, ...)
- */
- b_use = 24;
- raw_fb_bytes_per_line = dpy_x * b_use/8;
- }
- snap_fb = (char *) malloc(dpy_y * dpy_x * b_use/8);
- snap = &ximage_struct_snap;
- snap->data = snap_fb;
- snap->format = ZPixmap;
- snap->width = dpy_x;
- snap->height = dpy_y;
- snap->bits_per_pixel = b_use;
- snap->bytes_per_line = dpy_x * b_use/8;
- snap->bitmap_unit = -1;
- }
-
-
- raw_fb_image->red_mask = rm;
- raw_fb_image->green_mask = gm;
- raw_fb_image->blue_mask = bm;
-
- raw_fb_image->depth = 0;
- m = 1;
- for (i=0; i<32; i++) {
- if (rm & m) {
- raw_fb_image->depth++;
- }
- if (gm & m) {
- raw_fb_image->depth++;
- }
- if (bm & m) {
- raw_fb_image->depth++;
- }
- 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;
- }
-
- depth = raw_fb_image->depth;
-
- if (raw_fb_image->depth == 15) {
- /* unresolved bug with RGB555... */
- depth++;
- }
-
- 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);
- } else {
- memset(raw_fb, 0xff, dpy_y * raw_fb_image->bytes_per_line);
- }
-
- if (verbose) {
- rfbLog("\n");
- rfbLog("rawfb: raw_fb %p\n", raw_fb);
- rfbLog(" format %d\n", raw_fb_image->format);
- rfbLog(" width %d\n", raw_fb_image->width);
- rfbLog(" height %d\n", raw_fb_image->height);
- rfbLog(" bpp %d\n", raw_fb_image->bits_per_pixel);
- rfbLog(" depth %d\n", raw_fb_image->depth);
- rfbLog(" bpl %d\n", raw_fb_image->bytes_per_line);
- if (use_snapfb && snap_fb) {
- rfbLog(" snap_fb %p\n", snap_fb);
- }
- }
-
- free(str);
-
- return raw_fb_image;
-}
-
-static void initialize_clipshift(void) {
- clipshift = 0;
- cdpy_x = cdpy_y = coff_x = coff_y = 0;
- if (clip_str) {
- int w, h, x, y, bad = 0;
- if (parse_geom(clip_str, &w, &h, &x, &y, wdpy_x, wdpy_y)) {
- if (x < 0) {
- x = 0;
- }
- if (y < 0) {
- y = 0;
- }
- if (x + w > wdpy_x) {
- w = wdpy_x - x;
- }
- if (y + h > wdpy_y) {
- h = wdpy_y - y;
- }
- if (w <= 0 || h <= 0) {
- bad = 1;
- }
- } else {
- bad = 1;
- }
- if (bad) {
- rfbLog("*** ignoring invalid -clip WxH+X+Y: %s\n",
- clip_str);
- } else {
- /* OK, change geom behind everyone's back... */
- cdpy_x = w;
- cdpy_y = h;
- coff_x = x;
- coff_y = y;
-
- clipshift = 1;
-
- dpy_x = cdpy_x;
- dpy_y = cdpy_y;
- }
- }
-}
-
-static int wait_until_mapped(Window win) {
-#if NO_X11
- if (!win) {}
- return 0;
-#else
- int ms = 50, waittime = 30;
- time_t start = time(NULL);
- XWindowAttributes attr;
-
- while (1) {
- if (! valid_window(win, NULL, 0)) {
- if (time(NULL) > start + waittime) {
- break;
- }
- usleep(ms * 1000);
- continue;
- }
- if (dpy && ! XGetWindowAttributes(dpy, win, &attr)) {
- return 0;
- }
- if (attr.map_state == IsViewable) {
- return 1;
- }
- usleep(ms * 1000);
- }
- return 0;
-#endif /* NO_X11 */
-}
-
-/*
- * initialize a fb for the X display
- */
-XImage *initialize_xdisplay_fb(void) {
-#if NO_X11
- if (raw_fb_str) {
- return initialize_raw_fb(0);
- }
- return NULL;
-#else
- XImage *fb;
- char *vis_str = visual_str;
- int try = 0, subwin_tries = 3;
- XErrorHandler old_handler = NULL;
- int subwin_bs;
-
- if (raw_fb_str) {
- return initialize_raw_fb(0);
- }
-
- X_LOCK;
- if (subwin) {
- if (subwin_wait_mapped) {
- wait_until_mapped(subwin);
- }
- if (!valid_window((Window) subwin, NULL, 0)) {
- rfbLogEnable(1);
- rfbLog("invalid sub-window: 0x%lx\n", subwin);
- X_UNLOCK;
- clean_up_exit(1);
- }
- }
-
- if (overlay) {
- /*
- * ideally we'd like to not have to cook up the
- * visual variables but rather let it all come out
- * of XReadScreen(), however there is no way to get
- * a default visual out of it, so we pretend -visual
- * TrueColor:NN was supplied with NN usually 24.
- */
- char str[32];
- Window twin = subwin ? subwin : rootwin;
- XImage *xi;
-
- xi = xreadscreen(dpy, twin, 0, 0, 8, 8, False);
- sprintf(str, "TrueColor:%d", xi->depth);
- if (xi->depth != 24 && ! quiet) {
- rfbLog("warning: overlay image has depth %d "
- "instead of 24.\n", xi->depth);
- }
- XDestroyImage(xi);
- if (visual_str != NULL && ! quiet) {
- rfbLog("warning: replacing '-visual %s' by '%s' "
- "for use with -overlay\n", visual_str, str);
- }
- vis_str = strdup(str);
- }
-
- if (xform24to32) {
- if (DefaultDepth(dpy, scr) == 24) {
- vis_str = strdup("TrueColor:32");
- rfbLog("initialize_xdisplay_fb: vis_str set to: %s\n",
- vis_str);
- visual_id = (VisualID) 0;
- visual_depth = 0;
- set_visual_str_to_something = 1;
- }
- } else if (DefaultDepth(dpy, scr) < 8) {
- /* check very low bpp case, e.g. mono or vga16 */
- Screen *s = DefaultScreenOfDisplay(dpy);
- XImage *xi = XGetImage_wr(dpy, DefaultRootWindow(dpy), 0, 0, 2, 2, AllPlanes,
- ZPixmap);
- if (xi && xi->bits_per_pixel < 8) {
- int lowbpp = xi->bits_per_pixel;
- if (!vis_str) {
- char tmp[32];
- sprintf(tmp, "0x%x:8", (int) s->root_visual->visualid);
- vis_str = strdup(tmp);
- rfbLog("initialize_xdisplay_fb: low bpp[%d], vis_str "
- "set to: %s\n", lowbpp, vis_str);
- }
- if (using_shm) {
- using_shm = 0;
- rfbLog("initialize_xdisplay_fb: low bpp[%d], "
- "disabling shm\n", lowbpp);
- }
- visual_id = (VisualID) 0;
- visual_depth = 0;
- set_visual_str_to_something = 1;
- }
- if (xi) {
- XDestroyImage(xi);
- }
- }
-
- if (vis_str != NULL) {
- set_visual(vis_str);
- if (vis_str != visual_str) {
- free(vis_str);
- }
- }
-if (0) fprintf(stderr, "vis_str %s\n", vis_str ? vis_str : "notset");
-
- /* set up parameters for subwin or non-subwin cases: */
-
- again:
-
- if (! subwin) {
- /* full screen */
- window = rootwin;
- dpy_x = wdpy_x = DisplayWidth(dpy, scr);
- dpy_y = wdpy_y = DisplayHeight(dpy, scr);
- off_x = 0;
- off_y = 0;
- /* this may be overridden via visual_id below */
- default_visual = DefaultVisual(dpy, scr);
- } else {
- /* single window */
- XWindowAttributes attr;
-
- window = (Window) subwin;
- if (! XGetWindowAttributes(dpy, window, &attr)) {
- rfbLogEnable(1);
- rfbLog("invalid window: 0x%lx\n", window);
- X_UNLOCK;
- clean_up_exit(1);
- }
- dpy_x = wdpy_x = attr.width;
- dpy_y = wdpy_y = attr.height;
-
- subwin_bs = attr.backing_store;
-
- /* this may be overridden via visual_id below */
- default_visual = attr.visual;
-
- X_UNLOCK;
- set_offset();
- X_LOCK;
- }
-
- initialize_clipshift();
-
- /* initialize depth to reasonable value, visual_id may override */
- depth = DefaultDepth(dpy, scr);
-
-if (0) fprintf(stderr, "DefaultDepth: %d visial_id: %d\n", depth, (int) visual_id);
-
- if (visual_id) {
- int n;
- XVisualInfo vinfo_tmpl, *vinfo;
-
- /*
- * we are in here from -visual or -overlay options
- * visual_id and visual_depth were set in set_visual().
- */
-
- vinfo_tmpl.visualid = visual_id;
- vinfo = XGetVisualInfo(dpy, VisualIDMask, &vinfo_tmpl, &n);
- if (vinfo == NULL || n == 0) {
- rfbLogEnable(1);
- rfbLog("could not match visual_id: 0x%x\n",
- (int) visual_id);
- X_UNLOCK;
- clean_up_exit(1);
- }
- default_visual = vinfo->visual;
- depth = vinfo->depth;
- if (visual_depth) {
- /* force it from -visual MooColor:NN */
- depth = visual_depth;
- }
- if (! quiet) {
- fprintf(stderr, " initialize_xdisplay_fb()\n");
- fprintf(stderr, " Visual*: %p\n",
- (void *) vinfo->visual);
- fprintf(stderr, " visualid: 0x%x\n",
- (int) vinfo->visualid);
- fprintf(stderr, " screen: %d\n", vinfo->screen);
- fprintf(stderr, " depth: %d\n", vinfo->depth);
- fprintf(stderr, " class: %d\n", vinfo->class);
- fprintf(stderr, " red_mask: 0x%08lx %s\n",
- vinfo->red_mask, bitprint(vinfo->red_mask, 32));
- fprintf(stderr, " green_mask: 0x%08lx %s\n",
- vinfo->green_mask, bitprint(vinfo->green_mask, 32));
- fprintf(stderr, " blue_mask: 0x%08lx %s\n",
- vinfo->blue_mask, bitprint(vinfo->blue_mask, 32));
- fprintf(stderr, " cmap_size: %d\n",
- vinfo->colormap_size);
- fprintf(stderr, " bits b/rgb: %d\n",
- vinfo->bits_per_rgb);
- fprintf(stderr, "\n");
- }
- XFree_wr(vinfo);
- }
-
- if (! quiet) {
- rfbLog("Default visual ID: 0x%x\n",
- (int) XVisualIDFromVisual(default_visual));
- }
-
- if (subwin) {
- int shift = 0, resize = 0;
- int subwin_x, subwin_y;
- int disp_x = DisplayWidth(dpy, scr);
- int disp_y = DisplayHeight(dpy, scr);
- Window twin;
- /* subwins can be a dicey if they are changing size... */
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror); /* reset in if(subwin) block below */
- XTranslateCoordinates(dpy, window, rootwin, 0, 0, &subwin_x,
- &subwin_y, &twin);
-
- if (wdpy_x > disp_x) {
- resize = 1;
- dpy_x = wdpy_x = disp_x - 4;
- }
- if (wdpy_y > disp_y) {
- resize = 1;
- dpy_y = wdpy_y = disp_y - 4;
- }
-
- if (subwin_x + wdpy_x > disp_x) {
- shift = 1;
- subwin_x = disp_x - wdpy_x - 3;
- }
- if (subwin_y + wdpy_y > disp_y) {
- shift = 1;
- subwin_y = disp_y - wdpy_y - 3;
- }
- if (subwin_x < 0) {
- shift = 1;
- subwin_x = 1;
- }
- if (subwin_y < 0) {
- shift = 1;
- subwin_y = 1;
- }
-
- if (resize) {
- XResizeWindow(dpy, window, wdpy_x, wdpy_y);
- }
- if (shift) {
- XMoveWindow(dpy, window, subwin_x, subwin_y);
- off_x = subwin_x;
- off_y = subwin_y;
- }
- XMapRaised(dpy, window);
- XRaiseWindow(dpy, window);
- XSync(dpy, False);
- }
- try++;
-
- if (nofb) {
- /*
- * For -nofb we do not allocate the framebuffer, so we
- * can save a few MB of memory.
- */
- fb = XCreateImage_wr(dpy, default_visual, depth, ZPixmap,
- 0, NULL, dpy_x, dpy_y, BitmapPad(dpy), 0);
-
- } else if (visual_id) {
- /*
- * we need to call XCreateImage to supply the visual
- */
- fb = XCreateImage_wr(dpy, default_visual, depth, ZPixmap,
- 0, NULL, dpy_x, dpy_y, BitmapPad(dpy), 0);
- if (fb) {
- fb->data = (char *) malloc(fb->bytes_per_line * fb->height);
- }
-
- } else {
- fb = XGetImage_wr(dpy, window, 0, 0, dpy_x, dpy_y, AllPlanes,
- ZPixmap);
- if (! quiet) {
- rfbLog("Read initial data from X display into"
- " framebuffer.\n");
- }
- }
-
- if (subwin) {
- XSetErrorHandler(old_handler);
- if (trapped_xerror || fb == NULL) {
- rfbLog("trapped GetImage at SUBWIN creation.\n");
- if (try < subwin_tries) {
- usleep(250 * 1000);
- if (!get_window_size(window, &wdpy_x, &wdpy_y)) {
- rfbLogEnable(1);
- rfbLog("could not get size of subwin "
- "0x%lx\n", subwin);
- X_UNLOCK;
- clean_up_exit(1);
- }
- goto again;
- }
- }
- trapped_xerror = 0;
-
- } else if (fb == NULL) {
- XEvent xev;
- rfbLog("initialize_xdisplay_fb: *** fb creation failed: 0x%x try: %d\n", fb, try);
-#if LIBVNCSERVER_HAVE_LIBXRANDR
- if (xrandr_present && xrandr_base_event_type) {
- int cnt = 0;
- while (XCheckTypedEvent(dpy, xrandr_base_event_type + RRScreenChangeNotify, &xev)) {
- XRRScreenChangeNotifyEvent *rev;
- rev = (XRRScreenChangeNotifyEvent *) &xev;
-
- rfbLog("initialize_xdisplay_fb: XRANDR event while redoing fb[%d]:\n", cnt++);
- rfbLog(" serial: %d\n", (int) rev->serial);
- rfbLog(" timestamp: %d\n", (int) rev->timestamp);
- rfbLog(" cfg_timestamp: %d\n", (int) rev->config_timestamp);
- rfbLog(" size_id: %d\n", (int) rev->size_index);
- rfbLog(" sub_pixel: %d\n", (int) rev->subpixel_order);
- rfbLog(" rotation: %d\n", (int) rev->rotation);
- rfbLog(" width: %d\n", (int) rev->width);
- rfbLog(" height: %d\n", (int) rev->height);
- rfbLog(" mwidth: %d mm\n", (int) rev->mwidth);
- rfbLog(" mheight: %d mm\n", (int) rev->mheight);
- rfbLog("\n");
- rfbLog("previous WxH: %dx%d\n", wdpy_x, wdpy_y);
-
- xrandr_width = rev->width;
- xrandr_height = rev->height;
- xrandr_timestamp = rev->timestamp;
- xrandr_cfg_time = rev->config_timestamp;
- xrandr_rotation = (int) rev->rotation;
-
- rfbLog("initialize_xdisplay_fb: updating XRANDR config...\n");
- XRRUpdateConfiguration(&xev);
- }
- }
-#endif
- if (try < 5) {
- XFlush_wr(dpy);
- usleep(250 * 1000);
- if (try < 3) {
- XSync(dpy, False);
- } else if (try >= 3) {
- XSync(dpy, True);
- }
- goto again;
- }
- }
- if (use_snapfb) {
- initialize_snap_fb();
- }
-
- X_UNLOCK;
-
- if (fb->bits_per_pixel == 24 && ! quiet) {
- rfbLog("warning: 24 bpp may have poor performance.\n");
- }
- return fb;
-#endif /* NO_X11 */
-}
-
-void parse_scale_string(char *str, double *factor_x, double *factor_y, int *scaling, int *blend,
- int *nomult4, int *pad, int *interpolate, int *numer, int *denom, int w_in, int h_in) {
-
- int m, n;
- char *p, *tstr;
- double f, f2;
-
- *factor_x = 1.0;
- *factor_y = 1.0;
- *scaling = 0;
- *blend = 1;
- *nomult4 = 0;
- *pad = 0;
- *interpolate = 0;
- *numer = 0, *denom = 0;
-
- if (str == NULL || str[0] == '\0') {
- return;
- }
- tstr = strdup(str);
-
- if ( (p = strchr(tstr, ':')) != NULL) {
- /* options */
- if (strstr(p+1, "nb") != NULL) {
- *blend = 0;
- }
- if (strstr(p+1, "fb") != NULL) {
- *blend = 2;
- }
- if (strstr(p+1, "n4") != NULL) {
- *nomult4 = 1;
- }
- if (strstr(p+1, "in") != NULL) {
- *interpolate = 1;
- }
- if (strstr(p+1, "pad") != NULL) {
- *pad = 1;
- }
- if (strstr(p+1, "nocr") != NULL) {
- /* global */
- scaling_copyrect = 0;
- } else if (strstr(p+1, "cr") != NULL) {
- /* global */
- scaling_copyrect = 1;
- }
- *p = '\0';
- }
-
- if (strchr(tstr, '.') != NULL) {
- double test, diff, eps = 1.0e-7;
- if (sscanf(tstr, "%lfx%lf", &f, &f2) == 2) {
- *factor_x = (double) f;
- *factor_y = (double) f2;
- } else if (sscanf(tstr, "%lf", &f) != 1) {
- rfbLogEnable(1);
- rfbLog("invalid -scale arg: %s\n", tstr);
- clean_up_exit(1);
- } else {
- *factor_x = (double) f;
- *factor_y = (double) f;
- }
- /* look for common fractions from small ints: */
- if (*factor_x == *factor_y) {
- for (n=2; n<=10; n++) {
- for (m=1; m<n; m++) {
- test = ((double) m)/ n;
- diff = *factor_x - test;
- if (-eps < diff && diff < eps) {
- *numer = m;
- *denom = n;
- break;
-
- }
- }
- if (*denom) {
- break;
- }
- }
- if (*factor_x < 0.01) {
- rfbLogEnable(1);
- rfbLog("-scale factor too small: %f\n", *factor_x);
- clean_up_exit(1);
- }
- }
- } else if (sscanf(tstr, "%dx%d", &m, &n) == 2 && w_in > 0 && h_in > 0) {
- *factor_x = ((double) m) / ((double) w_in);
- *factor_y = ((double) n) / ((double) h_in);
- } else {
- if (sscanf(tstr, "%d/%d", &m, &n) != 2) {
- if (sscanf(tstr, "%d", &m) != 1) {
- rfbLogEnable(1);
- rfbLog("invalid -scale arg: %s\n", tstr);
- clean_up_exit(1);
- } else {
- /* e.g. -scale 1 or -scale 2 */
- n = 1;
- }
- }
- if (n <= 0 || m <=0) {
- rfbLogEnable(1);
- rfbLog("invalid -scale arg: %s\n", tstr);
- clean_up_exit(1);
- }
- *factor_x = ((double) m)/ n;
- *factor_y = ((double) m)/ n;
- if (*factor_x < 0.01) {
- rfbLogEnable(1);
- rfbLog("-scale factor too small: %f\n", *factor_x);
- clean_up_exit(1);
- }
- *numer = m;
- *denom = n;
- }
- if (*factor_x == 1.0 && *factor_y == 1.0) {
- if (! quiet) {
- rfbLog("scaling disabled for factor %f %f\n", *factor_x, *factor_y);
- }
- } else {
- *scaling = 1;
- }
- free(tstr);
-}
-
-int parse_rotate_string(char *str, int *mode) {
- int m = ROTATE_NONE;
- if (str == NULL || !strcmp(str, "") || !strcmp(str, "0")) {
- m = ROTATE_NONE;
- } else if (!strcmp(str, "x")) {
- m = ROTATE_X;
- } else if (!strcmp(str, "y")) {
- m = ROTATE_Y;
- } else if (!strcmp(str, "xy") || !strcmp(str, "yx") ||
- !strcmp(str,"+180") || !strcmp(str,"-180") || !strcmp(str,"180")) {
- m = ROTATE_XY;
- } else if (!strcmp(str, "+90") || !strcmp(str, "90")) {
- m = ROTATE_90;
- } else if (!strcmp(str, "+90x") || !strcmp(str, "90x")) {
- m = ROTATE_90X;
- } else if (!strcmp(str, "+90y") || !strcmp(str, "90y")) {
- m = ROTATE_90Y;
- } else if (!strcmp(str, "-90") || !strcmp(str, "270") ||
- !strcmp(str, "+270")) {
- m = ROTATE_270;
- } else {
- rfbLog("invalid -rotate mode: %s\n", str);
- }
- if (mode) {
- *mode = m;
- }
- return m;
-}
-
-int scale_round(int len, double fac) {
- double eps = 0.000001;
-
- len = (int) (len * fac + eps);
- if (len < 1) {
- len = 1;
- }
- return len;
-}
-
-static void setup_scaling(int *width_in, int *height_in) {
- int width = *width_in;
- int height = *height_in;
-
- parse_scale_string(scale_str, &scale_fac_x, &scale_fac_y, &scaling, &scaling_blend,
- &scaling_nomult4, &scaling_pad, &scaling_interpolate,
- &scale_numer, &scale_denom, *width_in, *height_in);
-
- if (scaling) {
- width = scale_round(width, scale_fac_x);
- height = scale_round(height, scale_fac_y);
- if (scale_denom && scaling_pad) {
- /* it is not clear this padding is useful anymore */
- rfbLog("width %% denom: %d %% %d = %d\n", width,
- scale_denom, width % scale_denom);
- rfbLog("height %% denom: %d %% %d = %d\n", height,
- scale_denom, height % scale_denom);
- if (width % scale_denom != 0) {
- int w = width;
- w += scale_denom - (w % scale_denom);
- if (!scaling_nomult4 && w % 4 != 0) {
- /* need to make mult of 4 as well */
- int c = 0;
- while (w % 4 != 0 && c++ <= 5) {
- w += scale_denom;
- }
- }
- width = w;
- rfbLog("padded width to: %d (mult of %d%s\n",
- width, scale_denom, !scaling_nomult4 ?
- " and 4)" : ")");
- }
- if (height % scale_denom != 0) {
- height += scale_denom - (height % scale_denom);
- rfbLog("padded height to: %d (mult of %d)\n",
- height, scale_denom);
- }
- }
- if (!scaling_nomult4 && width % 4 != 0 && width > 2) {
- /* reset width to be multiple of 4 */
- int width0 = width;
- if ((width+1) % 4 == 0) {
- width = width+1;
- } else if ((width-1) % 4 == 0) {
- width = width-1;
- } else if ((width+2) % 4 == 0) {
- width = width+2;
- }
- rfbLog("reset scaled width %d -> %d to be a multiple of"
- " 4 (to\n", width0, width);
- rfbLog("make vncviewers happy). use -scale m/n:n4 to "
- "disable.\n");
- }
- scaled_x = width;
- scaled_y = height;
-
- *width_in = width;
- *height_in = height;
- }
-}
-
-static void setup_rotating(void) {
- char *rs = rotating_str;
-
- rotating_cursors = 1;
- if (rs && strstr(rs, "nc:") == rs) {
- rs += strlen("nc:");
- rotating_cursors = 0;
- }
-
- rotating = parse_rotate_string(rs, NULL);
- if (! rotating) {
- rotating_cursors = 0;
- }
-
- if (rotating == ROTATE_90 || rotating == ROTATE_90X ||
- rotating == ROTATE_90Y || rotating == ROTATE_270) {
- rotating_same = 0;
- } else {
- rotating_same = 1;
- }
-}
-
-static rfbBool set_xlate_wrapper(rfbClientPtr cl) {
- static int first = 1;
- if (first) {
- first = 0;
- } else if (ncache) {
- int save = ncache_xrootpmap;
- rfbLog("set_xlate_wrapper: clearing -ncache for new pixel format.\n");
- INPUT_LOCK;
- ncache_xrootpmap = 0;
- check_ncache(1, 0);
- ncache_xrootpmap = save;
- INPUT_UNLOCK;
- }
- return rfbSetTranslateFunction(cl);
-}
-
-/*
- * initialize the rfb framebuffer/screen
- */
-void initialize_screen(int *argc, char **argv, XImage *fb) {
- int have_masks = 0;
- int width = fb->width;
- int height = fb->height;
- int create_screen = screen ? 0 : 1;
- int bits_per_color;
- int fb_bpp, fb_Bpl, fb_depth;
- int locked_sends = 0;
-
- bpp = fb->bits_per_pixel;
-
- fb_bpp = (int) fb->bits_per_pixel;
- fb_Bpl = (int) fb->bytes_per_line;
- fb_depth = (int) fb->depth;
-
- rfbLog("initialize_screen: fb_depth/fb_bpp/fb_Bpl %d/%d/%d\n", fb_depth,
- fb_bpp, fb_Bpl);
-
- main_bytes_per_line = fb->bytes_per_line;
-
- if (cmap8to24) {
- if (raw_fb) {
- if (!quiet) rfbLog("disabling -8to24 mode"
- " in raw_fb mode.\n");
- cmap8to24 = 0;
- } else if (depth == 24) {
- if (fb_bpp != 32) {
- if (!quiet) rfbLog("disabling -8to24 mode:"
- " bpp != 32 with depth == 24\n");
- cmap8to24 = 0;
- }
- } else if (depth <= 16) {
- /* need to cook up the screen fb to be depth 24 */
- fb_bpp = 32;
- fb_depth = 24;
- } else {
- if (!quiet) rfbLog("disabling -8to24 mode:"
- " default depth not 16 or less\n");
- cmap8to24 = 0;
- }
- }
-
- setup_scaling(&width, &height);
-
- if (scaling) {
- rfbLog("scaling screen: %dx%d -> %dx%d\n", fb->width, fb->height, scaled_x, scaled_y);
- rfbLog("scaling screen: scale_fac_x=%.5f scale_fac_y=%.5f\n", scale_fac_x, scale_fac_y);
-
- rfb_bytes_per_line = (main_bytes_per_line / fb->width) * width;
- } else {
- rfb_bytes_per_line = main_bytes_per_line;
- }
-
- setup_rotating();
-
- if (rotating) {
- if (! rotating_same) {
- int t, b = main_bytes_per_line / fb->width;
- if (scaling) {
- rot_bytes_per_line = b * height;
- } else {
- rot_bytes_per_line = b * fb->height;
- }
- t = width;
- width = height; /* The big swap... */
- height = t;
- } else {
- rot_bytes_per_line = rfb_bytes_per_line;
- }
- }
-
-#ifndef NO_NCACHE
- if (ncache > 0 && !nofb) {
-# ifdef MACOSX
- if (! raw_fb_str || macosx_console) {
-# else
- if (! raw_fb_str) {
-# endif
-
- char *new_fb;
- int sz = fb->height * fb->bytes_per_line;
- int ns = 1+ncache;
-
- if (ncache_xrootpmap) {
- ns++;
- }
-
- new_fb = (char *) calloc((size_t) (sz * ns), 1);
- if (fb->data) {
- memcpy(new_fb, fb->data, sz);
- free(fb->data);
- }
- fb->data = new_fb;
- fb->height *= (ns);
- height *= (ns);
- ncache0 = ncache;
- }
- }
-#endif
-
- if (cmap8to24) {
- if (depth <= 8) {
- rfb_bytes_per_line *= 4;
- rot_bytes_per_line *= 4;
- } else if (depth <= 16) {
- rfb_bytes_per_line *= 2;
- rot_bytes_per_line *= 2;
- }
- }
-
- /*
- * These are just hints wrt pixel format just to let
- * rfbGetScreen/rfbNewFramebuffer proceed with reasonable
- * defaults. We manually set them in painful detail below.
- */
- bits_per_color = guess_bits_per_color(fb_bpp);
-
- if (lock_client_sends(-1) == 0) {
- lock_client_sends(1);
- locked_sends = 1;
- }
-
- /* n.b. samplesPerPixel (set = 1 here) seems to be unused. */
- if (create_screen) {
- if (use_stunnel) {
- setup_stunnel(0, argc, argv);
- }
- if (use_openssl) {
- if (use_stunnel && enc_str && !strcmp(enc_str, "none")) {
- /* emulating HTTPS oneport */
- ;
- } else {
- openssl_init(0);
- }
- }
- screen = rfbGetScreen(argc, argv, width, height,
- bits_per_color, 1, fb_bpp/8);
- if (screen && http_dir) {
- http_connections(1);
- }
- if (unix_sock) {
- unix_sock_fd = listen_unix(unix_sock);
- }
- } else {
- /* set set frameBuffer member below. */
- rfbLog("rfbNewFramebuffer(0x%x, 0x%x, %d, %d, %d, %d, %d)\n",
- screen, NULL, width, height, bits_per_color, 1, fb_bpp/8);
-
- /* these are probably overwritten, but just to be safe: */
- screen->bitsPerPixel = fb_bpp;
- screen->depth = fb_depth;
-
- rfb_new_framebuffer(screen, NULL, width, height,
- bits_per_color, 1, (int) fb_bpp/8);
- }
- if (! screen) {
- int i;
- rfbLogEnable(1);
- rfbLog("\n");
- rfbLog("failed to create rfb screen.\n");
- for (i=0; i< *argc; i++) {
- rfbLog("\t[%d] %s\n", i, argv[i]);
- }
- clean_up_exit(1);
- }
-
- if (create_screen && *argc != 1) {
- int i;
- rfbLogEnable(1);
- rfbLog("*** unrecognized option(s) ***\n");
- for (i=1; i< *argc; i++) {
- rfbLog("\t[%d] %s\n", i, argv[i]);
- }
- rfbLog("For a list of options run: x11vnc -opts\n");
- rfbLog("or for the full help: x11vnc -help\n");
- rfbLog("\n");
- rfbLog("Here is a list of removed or obsolete"
- " options:\n");
- rfbLog("\n");
- rfbLog("removed: -hints, -nohints\n");
- rfbLog("removed: -cursorposall\n");
- rfbLog("removed: -nofilexfer, now the default.\n");
- rfbLog("\n");
- rfbLog("renamed: -old_copytile, use -onetile\n");
- rfbLog("renamed: -mouse, use -cursor\n");
- rfbLog("renamed: -mouseX, use -cursor X\n");
- rfbLog("renamed: -X, use -cursor X\n");
- rfbLog("renamed: -nomouse, use -nocursor\n");
- rfbLog("renamed: -old_pointer, use -pointer_mode 1\n");
-
- clean_up_exit(1);
- }
-
- /* set up format from scratch: */
- if (rotating && ! rotating_same) {
- screen->paddedWidthInBytes = rot_bytes_per_line;
- } else {
- screen->paddedWidthInBytes = rfb_bytes_per_line;
- }
- screen->serverFormat.bitsPerPixel = fb_bpp;
- screen->serverFormat.depth = fb_depth;
- screen->serverFormat.trueColour = TRUE;
-
- screen->serverFormat.redShift = 0;
- screen->serverFormat.greenShift = 0;
- screen->serverFormat.blueShift = 0;
- screen->serverFormat.redMax = 0;
- screen->serverFormat.greenMax = 0;
- screen->serverFormat.blueMax = 0;
-
- /* these main_* formats are used generally. */
- main_red_shift = 0;
- main_green_shift = 0;
- main_blue_shift = 0;
- main_red_max = 0;
- main_green_max = 0;
- main_blue_max = 0;
- main_red_mask = fb->red_mask;
- main_green_mask = fb->green_mask;
- main_blue_mask = fb->blue_mask;
-
- have_masks = ((fb->red_mask|fb->green_mask|fb->blue_mask) != 0);
- if (force_indexed_color) {
- have_masks = 0;
- }
-
- if (cmap8to24 && depth <= 16 && dpy) {
- XVisualInfo vinfo;
- vinfo.red_mask = 0;
- vinfo.green_mask = 0;
- vinfo.blue_mask = 0;
- /* more cooking up... */
- have_masks = 2;
- /* need to fetch TrueColor visual */
- X_LOCK;
- if (dpy
-#if !NO_X11
- && XMatchVisualInfo(dpy, scr, 24, TrueColor, &vinfo)
-#endif
- ) {
- main_red_mask = vinfo.red_mask;
- main_green_mask = vinfo.green_mask;
- main_blue_mask = vinfo.blue_mask;
- } else if (fb->byte_order == LSBFirst) {
- main_red_mask = 0x00ff0000;
- main_green_mask = 0x0000ff00;
- main_blue_mask = 0x000000ff;
- } else {
- main_red_mask = 0x000000ff;
- main_green_mask = 0x0000ff00;
- main_blue_mask = 0x00ff0000;
- }
- X_UNLOCK;
- }
-
- if (raw_fb_str && raw_fb_pixfmt) {
- char *fmt = strdup(raw_fb_pixfmt);
- uppercase(fmt);
- if (strstr(fmt, "GREY")) {
- set_greyscale_colormap();
- } else if (strstr(fmt, "HI240")) {
- set_hi240_colormap();
- } else {
- unset_colormap();
- }
- free(fmt);
- }
-
- if (! have_masks && screen->serverFormat.bitsPerPixel <= 16
- && dpy && CellsOfScreen(ScreenOfDisplay(dpy, scr))) {
- /* indexed color. we let 1 <= bpp <= 16, but it is normally 8 */
- if (!quiet) {
- rfbLog("\n");
- rfbLog("X display %s is %dbpp indexed color, depth=%d\n",
- DisplayString(dpy), screen->serverFormat.bitsPerPixel,
- screen->serverFormat.depth);
- if (! flash_cmap && ! overlay) {
- rfbLog("\n");
- rfbLog("In 8bpp PseudoColor mode if you "
- "experience color\n");
- rfbLog("problems you may want to enable "
- "following the\n");
- rfbLog("changing colormap by using the "
- "-flashcmap option.\n");
- rfbLog("\n");
- }
- }
- if (screen->serverFormat.depth < 8) {
- rfbLog("resetting serverFormat.depth %d -> 8.\n",
- screen->serverFormat.depth);
- rfbLog("resetting serverFormat.bpp %d -> 8.\n",
- screen->serverFormat.bitsPerPixel);
- screen->serverFormat.depth = 8;
- screen->serverFormat.bitsPerPixel = 8;
- }
- if (screen->serverFormat.depth > 8) {
- rfbLog("WARNING: indexed color depth > 8, Tight encoding will crash.\n");
- }
-
- screen->serverFormat.trueColour = FALSE;
- indexed_color = 1;
- set_colormap(1);
- debug_colormap(fb);
- } else {
- /*
- * general case, we call it truecolor, but could be direct
- * color, static color, etc....
- */
- if (! quiet) {
- if (raw_fb) {
- rfbLog("\n");
- rfbLog("Raw fb at addr %p is %dbpp depth=%d "
- "true color\n", raw_fb_addr,
- fb_bpp, fb_depth);
- } else if (! dpy) {
- ;
- } else if (have_masks == 2) {
- rfbLog("\n");
- rfbLog("X display %s is %dbpp depth=%d indexed "
- "color (-8to24 mode)\n", DisplayString(dpy),
- fb->bits_per_pixel, fb->depth);
- } else {
- rfbLog("\n");
- rfbLog("X display %s is %dbpp depth=%d true "
- "color\n", DisplayString(dpy),
- fb_bpp, fb_depth);
- }
- }
-
- indexed_color = 0;
-
- if (!have_masks) {
- int M, B = bits_per_color;
-
- if (3*B > fb_bpp) B--;
- if (B < 1) B = 1;
- M = (1 << B) - 1;
-
- rfbLog("WARNING: all TrueColor RGB masks are zero!\n");
- rfbLog("WARNING: cooking something up for VNC fb... B=%d M=%d\n", B, M);
- main_red_mask = M;
- main_green_mask = M;
- main_blue_mask = M;
- main_red_mask = main_red_mask << (2*B);
- main_green_mask = main_green_mask << (1*B);
- main_blue_mask = main_blue_mask << (0*B);
- fprintf(stderr, " red_mask: 0x%08lx %s\n", main_red_mask,
- bitprint(main_red_mask, 32));
- fprintf(stderr, " green_mask: 0x%08lx %s\n", main_green_mask,
- bitprint(main_green_mask, 32));
- fprintf(stderr, " blue_mask: 0x%08lx %s\n", main_blue_mask,
- bitprint(main_blue_mask, 32));
- }
-
- /* convert masks to bit shifts and max # colors */
- if (main_red_mask) {
- while (! (main_red_mask
- & (1 << screen->serverFormat.redShift))) {
- screen->serverFormat.redShift++;
- }
- }
- if (main_green_mask) {
- while (! (main_green_mask
- & (1 << screen->serverFormat.greenShift))) {
- screen->serverFormat.greenShift++;
- }
- }
- if (main_blue_mask) {
- while (! (main_blue_mask
- & (1 << screen->serverFormat.blueShift))) {
- screen->serverFormat.blueShift++;
- }
- }
- screen->serverFormat.redMax
- = main_red_mask >> screen->serverFormat.redShift;
- screen->serverFormat.greenMax
- = main_green_mask >> screen->serverFormat.greenShift;
- screen->serverFormat.blueMax
- = main_blue_mask >> screen->serverFormat.blueShift;
-
- main_red_max = screen->serverFormat.redMax;
- main_green_max = screen->serverFormat.greenMax;
- main_blue_max = screen->serverFormat.blueMax;
-
- main_red_shift = screen->serverFormat.redShift;
- main_green_shift = screen->serverFormat.greenShift;
- main_blue_shift = screen->serverFormat.blueShift;
- }
-
-#if !SMALL_FOOTPRINT
- if (verbose) {
- fprintf(stderr, "\n");
- fprintf(stderr, "FrameBuffer Info:\n");
- fprintf(stderr, " width: %d\n", fb->width);
- fprintf(stderr, " height: %d\n", fb->height);
- fprintf(stderr, " scaled_width: %d\n", width);
- fprintf(stderr, " scaled_height: %d\n", height);
- fprintf(stderr, " indexed_color: %d\n", indexed_color);
- fprintf(stderr, " bits_per_pixel: %d\n", fb->bits_per_pixel);
- fprintf(stderr, " depth: %d\n", fb->depth);
- fprintf(stderr, " red_mask: 0x%08lx %s\n", fb->red_mask,
- bitprint(fb->red_mask, 32));
- fprintf(stderr, " green_mask: 0x%08lx %s\n", fb->green_mask,
- bitprint(fb->green_mask, 32));
- fprintf(stderr, " blue_mask: 0x%08lx %s\n", fb->blue_mask,
- bitprint(fb->blue_mask, 32));
- if (cmap8to24) {
- fprintf(stderr, " 8to24 info:\n");
- fprintf(stderr, " fb_bpp: %d\n", fb_bpp);
- fprintf(stderr, " fb_depth: %d\n", fb_depth);
- fprintf(stderr, " red_mask: 0x%08lx %s\n", main_red_mask,
- bitprint(main_red_mask, 32));
- fprintf(stderr, " green_mask: 0x%08lx %s\n", main_green_mask,
- bitprint(main_green_mask, 32));
- fprintf(stderr, " blue_mask: 0x%08lx %s\n", main_blue_mask,
- bitprint(main_blue_mask, 32));
- }
- fprintf(stderr, " red: max: %3d shift: %2d\n",
- main_red_max, main_red_shift);
- fprintf(stderr, " green: max: %3d shift: %2d\n",
- main_green_max, main_green_shift);
- fprintf(stderr, " blue: max: %3d shift: %2d\n",
- main_blue_max, main_blue_shift);
- fprintf(stderr, " mainfb_bytes_per_line: %d\n",
- main_bytes_per_line);
- fprintf(stderr, " rfb_fb_bytes_per_line: %d\n",
- rfb_bytes_per_line);
- fprintf(stderr, " rot_fb_bytes_per_line: %d\n",
- rot_bytes_per_line);
- fprintf(stderr, " raw_fb_bytes_per_line: %d\n",
- raw_fb_bytes_per_line);
- switch(fb->format) {
- case XYBitmap:
- fprintf(stderr, " format: XYBitmap\n"); break;
- case XYPixmap:
- fprintf(stderr, " format: XYPixmap\n"); break;
- case ZPixmap:
- fprintf(stderr, " format: ZPixmap\n"); break;
- default:
- fprintf(stderr, " format: %d\n", fb->format); break;
- }
- switch(fb->byte_order) {
- case LSBFirst:
- fprintf(stderr, " byte_order: LSBFirst\n"); break;
- case MSBFirst:
- fprintf(stderr, " byte_order: MSBFirst\n"); break;
- default:
- fprintf(stderr, " byte_order: %d\n", fb->byte_order);
- break;
- }
- fprintf(stderr, " bitmap_pad: %d\n", fb->bitmap_pad);
- fprintf(stderr, " bitmap_unit: %d\n", fb->bitmap_unit);
- switch(fb->bitmap_bit_order) {
- case LSBFirst:
- fprintf(stderr, " bitmap_bit_order: LSBFirst\n"); break;
- case MSBFirst:
- fprintf(stderr, " bitmap_bit_order: MSBFirst\n"); break;
- default:
- fprintf(stderr, " bitmap_bit_order: %d\n",
- fb->bitmap_bit_order); break;
- }
- }
- if (overlay && ! quiet) {
- rfbLog("\n");
- rfbLog("Overlay mode enabled: If you experience color\n");
- rfbLog("problems when popup menus are on the screen, try\n");
- rfbLog("disabling SaveUnders in your X server, one way is\n");
- rfbLog("to start the X server with the '-su' option, e.g.:\n");
- rfbLog("Xsun -su ... see Xserver(1), xinit(1) for more info.\n");
- rfbLog("\n");
- }
-#endif
- /* nofb is for pointer/keyboard only handling. */
- if (nofb) {
- main_fb = NULL;
- rfb_fb = main_fb;
- cmap8to24_fb = NULL;
- rot_fb = NULL;
- screen->displayHook = nofb_hook;
- } else {
- main_fb = fb->data;
- rfb_fb = NULL;
- cmap8to24_fb = NULL;
- rot_fb = NULL;
-
- if (cmap8to24) {
- int n = main_bytes_per_line * fb->height;
- if (depth <= 8) {
- n *= 4;
- } else if (depth <= 16) {
- n *= 2;
- }
- cmap8to24_fb = (char *) malloc(n);
- memset(cmap8to24_fb, 0, n);
- }
-
- if (rotating) {
- int n = rot_bytes_per_line * height;
- rot_fb = (char *) malloc(n);
- memset(rot_fb, 0, n);
- }
-
- if (scaling) {
- int n = rfb_bytes_per_line * height;
-
- if (rotating && ! rotating_same) {
- n = rot_bytes_per_line * height;
- }
-
- rfb_fb = (char *) malloc(n);
- memset(rfb_fb, 0, n);
-
- } else if (cmap8to24) {
- rfb_fb = cmap8to24_fb;
- } else {
- rfb_fb = main_fb;
- }
- }
- if (rot_fb) {
- screen->frameBuffer = rot_fb;
- } else {
- screen->frameBuffer = rfb_fb;
- }
- if (verbose) {
- fprintf(stderr, " rfb_fb: %p\n", rfb_fb);
- fprintf(stderr, " main_fb: %p\n", main_fb);
- fprintf(stderr, " 8to24_fb: %p\n", cmap8to24_fb);
- fprintf(stderr, " rot_fb: %p\n", rot_fb);
- fprintf(stderr, " snap_fb: %p\n", snap_fb);
- fprintf(stderr, " raw_fb: %p\n", raw_fb);
- fprintf(stderr, " fake_fb: %p\n", fake_fb);
- fprintf(stderr, "\n");
- }
-
- /* may need, bpp, main_red_max, etc. */
- parse_wireframe();
- parse_scroll_copyrect();
- setup_cursors_and_push();
-
- if (scaling || rotating || cmap8to24) {
- mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
- }
-
- if (! create_screen) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- /*
- * since bits_per_color above may have been approximate,
- * try to reset the individual translation tables...
- * we do not seem to need this with rfbGetScreen()...
- */
- if (!quiet) rfbLog("calling setTranslateFunction()...\n");
- iter = rfbGetClientIterator(screen);
- while ((cl = rfbClientIteratorNext(iter)) != NULL) {
- screen->setTranslateFunction(cl);
- }
- rfbReleaseClientIterator(iter);
- if (!quiet) rfbLog(" done.\n");
-
- /* done for framebuffer change case */
- if (locked_sends) {
- lock_client_sends(0);
- }
-
- do_copy_screen = 1;
- return;
- }
-
- /*
- * the rest is screen server initialization, etc, only needed
- * at screen creation time.
- */
-
- /* event callbacks: */
- screen->newClientHook = new_client;
- screen->kbdAddEvent = keyboard;
- screen->ptrAddEvent = pointer_event;
- screen->setXCutText = xcut_receive;
- screen->setTranslateFunction = set_xlate_wrapper;
-
- screen->kbdReleaseAllKeys = kbd_release_all_keys;
- screen->setSingleWindow = set_single_window;
- screen->setServerInput = set_server_input;
- screen->setTextChat = set_text_chat;
- screen->getFileTransferPermission = get_file_transfer_permitted;
-
- /* called from inetd, we need to treat stdio as our socket */
- if (inetd && use_openssl) {
- /* accept_openssl() called later */
- screen->port = 0;
- } else if (inetd) {
- int fd = dup(0);
- if (fd < 0) {
- rfbLogEnable(1);
- rfbErr("dup(0) = %d failed.\n", fd);
- rfbLogPerror("dup");
- clean_up_exit(1);
- }
- fclose(stdin);
- fclose(stdout);
- /* we keep stderr for logging */
- screen->inetdSock = fd;
- screen->port = 0;
-
- } else if (! got_rfbport && auto_port > 0) {
- int lport = find_free_port(auto_port, auto_port+200);
- screen->autoPort = FALSE;
- screen->port = lport;
- } else if (! got_rfbport) {
- screen->autoPort = TRUE;
- } else if (got_rfbport && got_rfbport_val == 0) {
- screen->autoPort = FALSE;
- screen->port = 0;
- }
-
- if (! got_nevershared && ! got_alwaysshared) {
- if (shared) {
- screen->alwaysShared = TRUE;
- } else {
- screen->neverShared = TRUE;
- }
- screen->dontDisconnect = TRUE;
- }
- if (! got_deferupdate) {
- screen->deferUpdateTime = defer_update;
- } else {
- defer_update = screen->deferUpdateTime;
- }
-
- if (noipv4 || getenv("IPV4_FAILS")) {
- rfbBool ap = screen->autoPort;
- int port = screen->port;
-
- if (getenv("IPV4_FAILS")) {
- rfbLog("TESTING: IPV4_FAILS for rfbInitServer()\n");
- }
-
- screen->autoPort = FALSE;
- screen->port = 0;
-
- rfbInitServer(screen);
-
- screen->autoPort = ap;
- screen->port = port;
-
- } else {
- rfbInitServer(screen);
- }
-
- if (use_openssl) {
- openssl_port(0);
- if (https_port_num >= 0) {
- https_port(0);
- }
- } else {
- if (ipv6_listen) {
- int fd = -1;
- if (screen->port <= 0) {
- if (got_rfbport) {
- screen->port = got_rfbport_val;
- } else {
- int ap = 5900;
- if (auto_port > 0) {
- ap = auto_port;
- }
- screen->port = find_free_port6(ap, ap+200);
- }
- }
- fd = listen6(screen->port);
- if (fd < 0) {
- ipv6_listen = 0;
- rfbLog("Not listening on IPv6 interface.\n");
- } else {
- rfbLog("Listening %s on IPv6 port %d (socket %d)\n",
- screen->listenSock < 0 ? "only" : "also",
- screen->port, fd);
- ipv6_listen_fd = fd;
- }
- }
- }
-
- install_passwds();
-
- if (locked_sends) {
- lock_client_sends(0);
- }
- return;
-}
-
-#define DO_AVAHI \
- if (avahi) { \
- avahi_initialise(); \
- avahi_advertise(vnc_desktop_name, host, lport); \
- usleep(1000*1000); \
- }
-
-void announce(int lport, int ssl, char *iface) {
-
- char *host = this_host();
- char *tvdt;
-
- if (remote_direct) {
- return;
- }
-
- if (! ssl) {
- tvdt = "The VNC desktop is: ";
- } else {
- if (enc_str && !strcmp(enc_str, "none")) {
- tvdt = "The VNC desktop is: ";
- } else if (enc_str) {
- tvdt = "The ENC VNC desktop is: ";
- } else {
- tvdt = "The SSL VNC desktop is: ";
- }
- }
-
- if (iface != NULL && *iface != '\0' && strcmp(iface, "any")) {
- host = iface;
- }
- if (host != NULL) {
- /* note that vncviewer special cases 5900-5999 */
- int sz = 256;
- if (inetd) {
- ; /* should not occur (port) */
- } else if (quiet) {
- if (lport >= 5900) {
- snprintf(vnc_desktop_name, sz, "%s:%d",
- host, lport - 5900);
- DO_AVAHI
- fprintf(stderr, "\n%s %s\n", tvdt,
- vnc_desktop_name);
- } else {
- snprintf(vnc_desktop_name, sz, "%s:%d",
- host, lport);
- DO_AVAHI
- fprintf(stderr, "\n%s %s\n", tvdt,
- vnc_desktop_name);
- }
- } else if (lport >= 5900) {
- snprintf(vnc_desktop_name, sz, "%s:%d",
- host, lport - 5900);
- DO_AVAHI
- fprintf(stderr, "\n%s %s\n", tvdt, vnc_desktop_name);
- if (lport >= 6000) {
- rfbLog("possible aliases: %s:%d, "
- "%s::%d\n", host, lport,
- host, lport);
- }
- } else {
- snprintf(vnc_desktop_name, sz, "%s:%d",
- host, lport);
- DO_AVAHI
- fprintf(stderr, "\n%s %s\n", tvdt, vnc_desktop_name);
- rfbLog("possible alias: %s::%d\n",
- host, lport);
- }
- }
-}
-
-static void announce_http(int lport, int ssl, char *iface, char *extra) {
-
- char *host = this_host();
- char *jvu;
- int http = 0;
-
- if (enc_str && !strcmp(enc_str, "none") && !use_stunnel) {
- jvu = "Java viewer URL: http";
- http = 1;
- } else if (ssl == 1) {
- jvu = "Java SSL viewer URL: https";
- } else if (ssl == 2) {
- jvu = "Java SSL viewer URL: http";
- http = 1;
- } else {
- jvu = "Java viewer URL: http";
- http = 1;
- }
-
- if (iface != NULL && *iface != '\0' && strcmp(iface, "any")) {
- host = iface;
- }
- if (http && getenv("X11VNC_HTTP_LISTEN_LOCALHOST")) {
- host = "localhost";
- }
- if (host != NULL) {
- if (! inetd) {
- fprintf(stderr, "%s://%s:%d/%s\n", jvu, host, lport, extra);
- }
- }
-}
-
-void do_announce_http(void) {
- if (!screen) {
- return;
- }
- if (remote_direct) {
- return;
- }
-
- /* XXX ipv6? */
- if ((screen->httpListenSock > -1 || ipv6_http_fd > -1) && screen->httpPort) {
- int enc_none = (enc_str && !strcmp(enc_str, "none"));
- char *SPORT = " (single port)";
- if (use_openssl && ! enc_none) {
- announce_http(screen->port, 1, listen_str, SPORT);
- if (https_port_num >= 0) {
- announce_http(https_port_num, 1,
- listen_str, "");
- }
- announce_http(screen->httpPort, 2, listen_str, "");
- } else if (use_stunnel) {
- char pmsg[100];
- pmsg[0] = '\0';
- if (stunnel_port) {
- sprintf(pmsg, "?PORT=%d", stunnel_port);
- }
- announce_http(screen->httpPort, 2, listen_str, pmsg);
- if (stunnel_http_port > 0) {
- announce_http(stunnel_http_port, 1, NULL, pmsg);
- }
- if (enc_none) {
- strcat(pmsg, SPORT);
- announce_http(stunnel_port, 1, NULL, pmsg);
- }
- } else {
- announce_http(screen->httpPort, 0, listen_str, "");
- if (enc_none) {
- announce_http(screen->port, 1, NULL, SPORT);
- }
- }
- }
-}
-
-void do_mention_java_urls(void) {
- if (! quiet && screen) {
- /* XXX ipv6? */
- if (screen->httpListenSock > -1 && screen->httpPort) {
- rfbLog("\n");
- rfbLog("The URLs printed out below ('Java ... viewer URL') can\n");
- rfbLog("be used for Java enabled Web browser connections.\n");
- if (!stunnel_port && enc_str && !strcmp(enc_str, "none")) {
- ;
- } else if (use_openssl || stunnel_port) {
- rfbLog("Here are some additional possibilities:\n");
- rfbLog("\n");
- rfbLog("https://host:port/proxy.vnc (MUST be used if Web Proxy used)\n");
- rfbLog("\n");
- rfbLog("https://host:port/ultra.vnc (Use UltraVNC Java Viewer)\n");
- rfbLog("https://host:port/ultraproxy.vnc (Web Proxy with UltraVNC)\n");
- rfbLog("https://host:port/ultrasigned.vnc (Signed UltraVNC Filexfer)\n");
- rfbLog("\n");
- rfbLog("Where you replace \"host:port\" with that printed below, or\n");
- rfbLog("whatever is needed to reach the host e.g. Internet IP number\n");
- rfbLog("\n");
- rfbLog("Append ?GET=1 to a URL for faster loading or supply:\n");
- rfbLog("-env X11VNC_EXTRA_HTTPS_PARAMS='?GET=1' to cmdline.\n");
- }
- }
- rfbLog("\n");
- }
-}
-
-void set_vnc_desktop_name(void) {
- sprintf(vnc_desktop_name, "unknown");
- if (inetd) {
- sprintf(vnc_desktop_name, "%s/inetd-no-further-clients",
- this_host());
- }
- if (remote_direct) {
- return;
- }
- if (screen->port) {
-
- do_mention_java_urls();
-
- if (use_openssl) {
- announce(screen->port, 1, listen_str);
- } else {
- announce(screen->port, 0, listen_str);
- }
- if (stunnel_port) {
- announce(stunnel_port, 1, NULL);
- }
-
- do_announce_http();
-
- fflush(stderr);
- if (inetd) {
- ; /* should not occur (port != 0) */
- } else {
- fprintf(stdout, "PORT=%d\n", screen->port);
- if (stunnel_port) {
- fprintf(stdout, "SSLPORT=%d\n", stunnel_port);
- } else if (use_openssl) {
- if (enc_str && !strcmp(enc_str, "none")) {
- ;
- } else if (enc_str) {
- fprintf(stdout, "ENCPORT=%d\n", screen->port);
- } else {
- fprintf(stdout, "SSLPORT=%d\n", screen->port);
- }
- }
- fflush(stdout);
- if (flagfile) {
- FILE *flag = fopen(flagfile, "w");
- if (flag) {
- fprintf(flag, "PORT=%d\n",screen->port);
- if (stunnel_port) {
- fprintf(flag, "SSL_PORT=%d\n",
- stunnel_port);
- }
- fflush(flag);
- fclose(flag);
- } else {
- rfbLog("could not open flag file: %s\n",
- 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);
- }
-}
-
-static void check_cursor_changes(void) {
- static double last_push = 0.0;
-
- if (unixpw_in_progress) return;
-
- cursor_changes += check_x11_pointer();
-
- if (cursor_changes) {
- double tm, max_push = 0.125, multi_push = 0.01, wait = 0.02;
- int cursor_shape, dopush = 0, link, latency, netrate;
-
- if (! all_clients_initialized()) {
- /* play it safe */
- return;
- }
-
- if (0) cursor_shape = cursor_shape_updates_clients(screen);
-
- dtime0(&tm);
- link = link_rate(&latency, &netrate);
- if (link == LR_DIALUP) {
- max_push = 0.2;
- wait = 0.05;
- } else if (link == LR_BROADBAND) {
- max_push = 0.075;
- wait = 0.05;
- } else if (link == LR_LAN) {
- max_push = 0.01;
- } else if (latency < 5 && netrate > 200) {
- max_push = 0.01;
- }
-
- if (tm > last_push + max_push) {
- dopush = 1;
- } else if (cursor_changes > 1 && tm > last_push + multi_push) {
- dopush = 1;
- }
-
- if (dopush) {
- mark_rect_as_modified(0, 0, 1, 1, 1);
- fb_push_wait(wait, FB_MOD);
- last_push = tm;
- } else {
- rfbPE(0);
- }
- }
- cursor_changes = 0;
-}
-
-/*
- * These watch_loop() releated were moved from x11vnc.c so we could try
- * to remove -O2 from its compilation. TDB new file, e.g. watch.c.
- */
-
-static void check_filexfer(void) {
- static time_t last_check = 0;
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int transferring = 0;
-
- if (time(NULL) <= last_check) {
- return;
- }
-
-#if 0
- if (getenv("NOFT")) {
- return;
- }
-#endif
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (cl->fileTransfer.receiving) {
- transferring = 1;
- break;
- }
- if (cl->fileTransfer.sending) {
- transferring = 1;
- break;
- }
- }
- rfbReleaseClientIterator(iter);
-
- if (transferring) {
- double start = dnow();
- while (dnow() < start + 0.5) {
- rfbCFD(5000);
- rfbCFD(1000);
- rfbCFD(0);
- }
- } else {
- last_check = time(NULL);
- }
-}
-
-static void record_last_fb_update(void) {
- static int rbs0 = -1;
- static time_t last_call = 0;
- time_t now = time(NULL);
- int rbs = -1;
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- if (last_fb_bytes_sent == 0) {
- last_fb_bytes_sent = now;
- last_call = now;
- }
-
- if (now <= last_call + 1) {
- /* check every second or so */
- return;
- }
-
- if (unixpw_in_progress) return;
-
- last_call = now;
-
- if (! screen) {
- return;
- }
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
-#if 0
- rbs += cl->rawBytesEquivalent;
-#else
-#if LIBVNCSERVER_HAS_STATS
- rbs += rfbStatGetSentBytesIfRaw(cl);
-#endif
-#endif
- }
- rfbReleaseClientIterator(iter);
-
- if (rbs != rbs0) {
- rbs0 = rbs;
- if (debug_tiles > 1) {
- fprintf(stderr, "record_last_fb_update: %d %d\n",
- (int) now, (int) last_fb_bytes_sent);
- }
- last_fb_bytes_sent = now;
- }
-}
-
-
-static int choose_delay(double dt) {
- static double t0 = 0.0, t1 = 0.0, t2 = 0.0, now;
- static int x0, y0, x1, y1, x2, y2, first = 1;
- int dx0, dy0, dx1, dy1, dm, i, msec = waitms;
- double cut1 = 0.15, cut2 = 0.075, cut3 = 0.25;
- double bogdown_time = 0.25, bave = 0.0;
- int bogdown = 1, bcnt = 0;
- int ndt = 8, nave = 3;
- double fac = 1.0;
- static int db = 0, did_set_defer = 0;
- static double dts[8];
- static int link = LR_UNSET, latency = -1, netrate = -1;
- static double last_link = 0.0;
-
- if (screen && did_set_defer) {
- /* reset defer in case we changed it */
- screen->deferUpdateTime = defer_update;
- }
- if (waitms == 0) {
- return waitms;
- }
- if (nofb) {
- return waitms;
- }
-
- if (first) {
- for(i=0; i<ndt; i++) {
- dts[i] = 0.0;
- }
- if (getenv("DEBUG_DELAY")) {
- db = atoi(getenv("DEBUG_DELAY"));
- }
- if (getenv("SET_DEFER")) {
- set_defer = atoi(getenv("SET_DEFER"));
- }
- first = 0;
- }
-
- now = dnow();
-
- if (now > last_link + 30.0 || link == LR_UNSET) {
- link = link_rate(&latency, &netrate);
- last_link = now;
- }
-
- /*
- * first check for bogdown, e.g. lots of activity, scrolling text
- * from command output, etc.
- */
- if (nap_ok) {
- dt = 0.0;
- }
- if (! wait_bog) {
- bogdown = 0;
-
- } else if (button_mask || now < last_keyboard_time + 2*bogdown_time) {
- /*
- * let scrolls & keyboard input through the normal way
- * otherwise, it will likely just annoy them.
- */
- bogdown = 0;
-
- } else if (dt > 0.0) {
- /*
- * inspect recent dt's:
- * 0 1 2 3 4 5 6 7 dt
- * ^ ^ ^
- */
- for (i = ndt - (nave - 1); i < ndt; i++) {
- bave += dts[i];
- bcnt++;
- if (dts[i] < bogdown_time) {
- bogdown = 0;
- break;
- }
- }
- bave += dt;
- bcnt++;
- bave = bave / bcnt;
- if (dt < bogdown_time) {
- bogdown = 0;
- }
- } else {
- bogdown = 0;
- }
- /* shift for next time */
- for (i = 0; i < ndt-1; i++) {
- dts[i] = dts[i+1];
- }
- dts[ndt-1] = dt;
-
-if (0 && dt > 0.0) fprintf(stderr, "dt: %.5f %.4f\n", dt, dnowx());
- if (bogdown) {
- if (use_xdamage) {
- /* DAMAGE can queue ~1000 rectangles for a scroll */
- clear_xdamage_mark_region(NULL, 0);
- }
- msec = (int) (1000 * 1.75 * bave);
- if (dts[ndt - nave - 1] > 0.75 * bave) {
- msec = 1.5 * msec;
- set_xdamage_mark(0, 0, dpy_x, dpy_y);
- }
- if (msec > 1500) {
- msec = 1500;
- }
- if (msec < waitms) {
- msec = waitms;
- }
- db = (db || debug_tiles);
- if (db) fprintf(stderr, "bogg[%d] %.3f %.3f %.3f %.3f\n",
- msec, dts[ndt-4], dts[ndt-3], dts[ndt-2], dts[ndt-1]);
-
- return msec;
- }
-
- /* next check for pointer motion, keystrokes, to speed up */
- t2 = dnow();
- x2 = cursor_x;
- y2 = cursor_y;
-
- dx0 = nabs(x1 - x0);
- dy0 = nabs(y1 - y0);
- dx1 = nabs(x2 - x1);
- dy1 = nabs(y2 - y1);
-
- /* bigger displacement for most recent dt: */
- if (dx1 > dy1) {
- dm = dx1;
- } else {
- dm = dy1;
- }
-
- if ((dx0 || dy0) && (dx1 || dy1)) {
- /* if mouse moved the previous two times: */
- if (t2 < t0 + cut1 || t2 < t1 + cut2 || dm > 20) {
- /*
- * if within 0.15s(0) or 0.075s(1) or mouse
- * moved > 20pixels, set and bump up the cut
- * down factor.
- */
- fac = wait_ui * 1.5;
- } else if ((dx1 || dy1) && dm > 40) {
- fac = wait_ui;
- } else {
- /* still 1.0? */
- if (db > 1) fprintf(stderr, "wait_ui: still 1.0\n");
- }
- } else if ((dx1 || dy1) && dm > 40) {
- /* if mouse moved > 40 last time: */
- fac = wait_ui;
- }
-
- if (fac == 1.0 && t2 < last_keyboard_time + cut3) {
- /* if typed in last 0.25s set wait_ui */
- fac = wait_ui;
- }
- if (fac != 1.0) {
- if (link == LR_LAN || latency <= 3) {
- fac *= 1.5;
- }
- }
-
- msec = (int) (((double) waitms) / fac);
- if (msec == 0) {
- msec = 1;
- }
-
- if (set_defer && fac != 1.0 && screen) {
- /* this is wait_ui mode, set defer to match wait: */
- if (set_defer >= 1) {
- screen->deferUpdateTime = msec;
- } else if (set_defer <= -1) {
- screen->deferUpdateTime = 0;
- }
- if (nabs(set_defer) == 2) {
- urgent_update = 1;
- }
- did_set_defer = 1;
- }
-
- x0 = x1;
- y0 = y1;
- t0 = t1;
-
- x1 = x2;
- y1 = y2;
- t1 = t2;
-
- if (db > 1) fprintf(stderr, "wait: %2d defer[%02d]: %2d\n", msec, defer_update, screen->deferUpdateTime);
-
- return msec;
-}
-
-/*
- * main x11vnc loop: polls, checks for events, iterate libvncserver, etc.
- */
-void watch_loop(void) {
- int cnt = 0, tile_diffs = 0, skip_pe = 0, wait;
- double tm, dtr, dt = 0.0;
- time_t start = time(NULL);
-
- if (use_threads && !started_rfbRunEventLoop) {
- started_rfbRunEventLoop = 1;
- rfbRunEventLoop(screen, -1, TRUE);
- }
-
- while (1) {
- char msg[] = "new client: %s taking unixpw client off hold.\n";
- int skip_scan_for_updates = 0;
-
- got_user_input = 0;
- got_pointer_input = 0;
- got_local_pointer_input = 0;
- got_pointer_calls = 0;
- got_keyboard_input = 0;
- got_keyboard_calls = 0;
- urgent_update = 0;
-
- x11vnc_current = dnow();
-
- if (! use_threads) {
- dtime0(&tm);
- if (! skip_pe) {
- if (unixpw_in_progress) {
- rfbClientPtr cl = unixpw_client;
- if (cl && cl->onHold) {
- rfbLog(msg, cl->host);
- unixpw_client->onHold = FALSE;
- }
- } else {
- measure_send_rates(1);
- }
-
- unixpw_in_rfbPE = 1;
-
- /*
- * do a few more since a key press may
- * have induced a small change we want to
- * see quickly (just 1 rfbPE will likely
- * only process the subsequent "up" event)
- */
- if (tm < last_keyboard_time + 0.20) {
- rfbPE(0);
- rfbPE(0);
- rfbPE(-1);
- rfbPE(0);
- rfbPE(0);
- } else {
- if (extra_fbur > 0) {
- int i;
- for (i=0; i < extra_fbur; i++) {
- rfbPE(0);
- }
- }
- rfbPE(-1);
- }
- if (x11vnc_current < last_new_client + 0.5) {
- urgent_update = 1;
- }
-
- unixpw_in_rfbPE = 0;
-
- if (unixpw_in_progress) {
- /* rfbPE loop until logged in. */
- skip_pe = 0;
- check_new_clients();
- continue;
- } else {
- measure_send_rates(0);
- fb_update_sent(NULL);
- }
- } else {
- if (unixpw_in_progress) {
- skip_pe = 0;
- check_new_clients();
- continue;
- }
- }
- dtr = dtime(&tm);
-
- if (! cursor_shape_updates) {
- /* undo any cursor shape requests */
- disable_cursor_shape_updates(screen);
- }
- if (screen && screen->clientHead) {
- int ret = check_user_input(dt, dtr, tile_diffs, &cnt);
- /* true: loop back for more input */
- if (ret == 2) {
- skip_pe = 1;
- }
- if (ret) {
- if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
- continue;
- }
- }
- /* watch for viewonly input piling up: */
- if ((got_pointer_calls > got_pointer_input) ||
- (got_keyboard_calls > got_keyboard_input)) {
- eat_viewonly_input(10, 3);
- }
- } else {
- /* -threads here. */
- if (unixpw_in_progress) {
- rfbClientPtr cl = unixpw_client;
- if (cl && cl->onHold) {
- rfbLog(msg, cl->host);
- unixpw_client->onHold = FALSE;
- }
- }
- if (use_xrecord) {
- check_xrecord();
- }
- if (wireframe && button_mask) {
- check_wireframe();
- }
- }
- skip_pe = 0;
-
- if (shut_down) {
- clean_up_exit(0);
- }
-
- if (unixpw_in_progress) {
- check_new_clients();
- continue;
- }
-
- if (! urgent_update) {
- if (do_copy_screen) {
- do_copy_screen = 0;
- copy_screen();
- }
-
- check_new_clients();
- check_ncache(0, 0);
- check_xevents(0);
- check_autorepeat();
- check_pm();
- check_filexfer();
- check_keycode_state();
- check_connect_inputs();
- check_gui_inputs();
- check_stunnel();
- check_openssl();
- check_https();
- record_last_fb_update();
- check_padded_fb();
- check_fixscreen();
- check_xdamage_state();
- check_xrecord_reset(0);
- check_add_keysyms();
- check_new_passwds(0);
-#ifdef ENABLE_GRABLOCAL
- if (grab_local) {
- check_local_grab();
- }
-#endif
- if (started_as_root) {
- check_switched_user();
- }
-
- if (first_conn_timeout < 0) {
- start = time(NULL);
- first_conn_timeout = -first_conn_timeout;
- }
- }
-
- if (rawfb_vnc_reflect) {
- static time_t lastone = 0;
- if (time(NULL) > lastone + 10) {
- lastone = time(NULL);
- vnc_reflect_process_client();
- }
- }
-
- if (first_conn_timeout) {
- int t = first_conn_timeout;
- if (!clients_served) {
- if (time(NULL) - start > first_conn_timeout) {
- rfbLog("No client after %d secs.\n", t);
- shut_down = 1;
- }
- } else {
- if (!client_normal_count) {
- if (time(NULL) - start > t + 3) {
- rfbLog("No valid client after %d secs.\n", t + 3);
- shut_down = 1;
- }
- }
- }
- }
-
- if (! screen || ! screen->clientHead) {
- /* waiting for a client */
- usleep(200 * 1000);
- continue;
- }
-
- if (first_conn_timeout && all_clients_initialized()) {
- first_conn_timeout = 0;
- }
-
- if (nofb) {
- /* no framebuffer polling needed */
- if (cursor_pos_updates) {
- check_x11_pointer();
- }
-#ifdef MACOSX
- else check_x11_pointer();
-#endif
- continue;
- }
- if (x11vnc_current < last_new_client + 0.5 && !all_clients_initialized()) {
- continue;
- }
- if (subwin && freeze_when_obscured) {
- /* XXX not working */
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- check_xevents(0);
- if (subwin_obscured) {
- skip_scan_for_updates = 1;
- }
- }
-
- if (skip_scan_for_updates) {
- ;
- } else if (button_mask && (!show_dragging || pointer_mode == 0)) {
- /*
- * if any button is pressed in this mode do
- * not update rfb screen, but do flush the
- * X11 display.
- */
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- dt = 0.0;
- } else {
- static double last_dt = 0.0;
- double xdamage_thrash = 0.4;
- static int tilecut = -1;
-
- check_cursor_changes();
-
- /* for timing the scan to try to detect thrashing */
-
- if (use_xdamage && last_dt > xdamage_thrash) {
- clear_xdamage_mark_region(NULL, 0);
- }
-
- if (unixpw_in_progress) continue;
-
- if (rawfb_vnc_reflect) {
- vnc_reflect_process_client();
- }
-
- dtime0(&tm);
-
-#if !NO_X11
- if (xrandr_present && !xrandr && xrandr_maybe) {
- int delay = 180;
- /* there may be xrandr right after xsession start */
- if (tm < x11vnc_start + delay || tm < last_client + delay) {
- int tw = 20;
- if (auth_file != NULL) {
- tw = 120;
- }
- X_LOCK;
- if (tm < x11vnc_start + tw || tm < last_client + tw) {
- XSync(dpy, False);
- } else {
- XFlush_wr(dpy);
- }
- X_UNLOCK;
- }
- X_LOCK;
- check_xrandr_event("before-scan");
- X_UNLOCK;
- }
-#endif
- if (use_snapfb) {
- int t, tries = 3;
- copy_snap();
- for (t=0; t < tries; t++) {
- tile_diffs = scan_for_updates(0);
- }
- } else {
- tile_diffs = scan_for_updates(0);
- }
- dt = dtime(&tm);
- if (! nap_ok) {
- last_dt = dt;
- }
-
- if (tilecut < 0) {
- if (getenv("TILECUT")) {
- tilecut = atoi(getenv("TILECUT"));
- }
- if (tilecut < 0) tilecut = 4;
- }
-
- if ((debug_tiles || debug_scroll > 1 || debug_wireframe > 1)
- && (tile_diffs > tilecut || debug_tiles > 1)) {
- double rate = (tile_x * tile_y * bpp/8 * tile_diffs) / dt;
- fprintf(stderr, "============================= TILES: %d dt: %.4f"
- " t: %.4f %.2f MB/s nap_ok: %d\n", tile_diffs, dt,
- tm - x11vnc_start, rate/1000000.0, nap_ok);
- }
-
- }
-
- /* sleep a bit to lessen load */
- wait = choose_delay(dt);
-
- if (urgent_update) {
- ;
- } else if (wait > 2*waitms) {
- /* bog case, break it up */
- nap_sleep(wait, 10);
- } else {
- double t1, t2;
- int idt;
- if (extra_fbur > 0) {
- int i;
- for (i=0; i <= extra_fbur; i++) {
- int r = rfbPE(0);
- if (!r) break;
- }
- }
-
- /* sometimes the sleep is too short, so measure it: */
- t1 = dnow();
- usleep(wait * 1000);
- t2 = dnow();
-
- idt = (int) (1000. * (t2 - t1));
- if (idt > 0 && idt < wait) {
- /* try to sleep the remainder */
- usleep((wait - idt) * 1000);
- }
- }
-
- cnt++;
- }
-}
-
-
diff --git a/x11vnc/screen.h b/x11vnc/screen.h
deleted file mode 100644
index e7376f4..0000000
--- a/x11vnc/screen.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_SCREEN_H
-#define _X11VNC_SCREEN_H
-
-/* -- screen.h -- */
-
-extern void set_greyscale_colormap(void);
-extern void set_hi240_colormap(void);
-extern void unset_colormap(void);
-extern void set_colormap(int reset);
-extern void set_nofb_params(int restore);
-extern void set_raw_fb_params(int restore);
-extern void do_new_fb(int reset_mem);
-extern void free_old_fb(void);
-extern void check_padded_fb(void);
-extern void install_padded_fb(char *geom);
-extern XImage *initialize_xdisplay_fb(void);
-extern XImage *initialize_raw_fb(int);
-extern void parse_scale_string(char *str, double *factor_x, double *factor_y, int *scaling, int *blend,
- int *nomult4, int *pad, int *interpolate, int *numer, int *denom, int w_in, int h_in);
-extern int parse_rotate_string(char *str, int *mode);
-extern int scale_round(int len, double fac);
-extern void initialize_screen(int *argc, char **argv, XImage *fb);
-extern void set_vnc_desktop_name(void);
-extern void announce(int lport, int ssl, char *iface);
-
-extern char *vnc_reflect_guess(char *str, char **raw_fb_addr);
-extern void vnc_reflect_process_client(void);
-extern rfbBool vnc_reflect_send_pointer(int x, int y, int mask);
-extern rfbBool vnc_reflect_send_key(uint32_t key, rfbBool down);
-extern rfbBool vnc_reflect_send_cuttext(char *str, int len);
-
-extern int rawfb_reset;
-extern int rawfb_dev_video;
-extern int rawfb_vnc_reflect;
-
-#endif /* _X11VNC_SCREEN_H */
diff --git a/x11vnc/scrollevent_t.h b/x11vnc/scrollevent_t.h
deleted file mode 100644
index e0ea951..0000000
--- a/x11vnc/scrollevent_t.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_SCROLLEVENT_T_H
-#define _X11VNC_SCROLLEVENT_T_H
-
-/* -- scrollevent_t.h -- */
-
-typedef struct scroll_event {
- Window win, frame;
- int dx, dy;
- int x, y, w, h;
- double t;
- int win_x, win_y, win_w, win_h;
- int new_x, new_y, new_w, new_h;
-} scroll_event_t;
-
-#endif /* _X11VNC_SCROLLEVENT_T_H */
diff --git a/x11vnc/selection.c b/x11vnc/selection.c
deleted file mode 100644
index a334586..0000000
--- a/x11vnc/selection.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- selection.c -- */
-
-#include "x11vnc.h"
-#include "cleanup.h"
-#include "connections.h"
-#include "unixpw.h"
-#include "win_utils.h"
-#include "xwrappers.h"
-
-/*
- * Selection/Cutbuffer/Clipboard handlers.
- */
-
-int own_primary = 0; /* whether we currently own PRIMARY or not */
-int set_primary = 1;
-int own_clipboard = 0; /* whether we currently own CLIPBOARD or not */
-int set_clipboard = 1;
-int set_cutbuffer = 0; /* to avoid bouncing the CutText right back */
-int sel_waittime = 15; /* some seconds to skip before first send */
-Window selwin = None; /* special window for our selection */
-Atom clipboard_atom = None;
-
-/*
- * This is where we keep our selection: the string sent TO us from VNC
- * clients, and the string sent BY us to requesting X11 clients.
- */
-char *xcut_str_primary = NULL;
-char *xcut_str_clipboard = NULL;
-
-
-void selection_request(XEvent *ev, char *type);
-int check_sel_direction(char *dir, char *label, char *sel, int len);
-void cutbuffer_send(void);
-void selection_send(XEvent *ev);
-void resend_selection(char *type);
-
-
-/*
- * Our callbacks instruct us to check for changes in the cutbuffer
- * and PRIMARY and CLIPBOARD selection on the local X11 display.
- *
- * TODO: check if malloc does not cause performance issues (esp. WRT
- * SelectionNotify handling).
- */
-static char cutbuffer_str[PROP_MAX+1];
-static char primary_str[PROP_MAX+1];
-static char clipboard_str[PROP_MAX+1];
-static int cutbuffer_len = 0;
-static int primary_len = 0;
-static int clipboard_len = 0;
-
-/*
- * An X11 (not VNC) client on the local display has requested the selection
- * from us (because we are the current owner).
- *
- * n.b.: our caller already has the X_LOCK.
- */
-void selection_request(XEvent *ev, char *type) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!ev || !type) {}
- return;
-#else
- XSelectionEvent notify_event;
- XSelectionRequestEvent *req_event;
- XErrorHandler old_handler;
- char *str;
- unsigned int length;
- unsigned char *data;
- static Atom xa_targets = None;
- static int sync_it = -1;
-# ifndef XA_LENGTH
- unsigned long XA_LENGTH;
-# endif
- RAWFB_RET_VOID
-
-# ifndef XA_LENGTH
- XA_LENGTH = XInternAtom(dpy, "LENGTH", True);
-# endif
-
- if (sync_it < 0) {
- if (getenv("X11VNC_SENDEVENT_SYNC")) {
- sync_it = 1;
- } else {
- sync_it = 0;
- }
- }
-
- req_event = &(ev->xselectionrequest);
- notify_event.type = SelectionNotify;
- notify_event.display = req_event->display;
- notify_event.requestor = req_event->requestor;
- notify_event.selection = req_event->selection;
- notify_event.target = req_event->target;
- notify_event.time = req_event->time;
-
- if (req_event->property == None) {
- notify_event.property = req_event->target;
- } else {
- notify_event.property = req_event->property;
- }
-
- if (!strcmp(type, "PRIMARY")) {
- str = xcut_str_primary;
- } else if (!strcmp(type, "CLIPBOARD")) {
- str = xcut_str_clipboard;
- } else {
- return;
- }
- if (str) {
- length = strlen(str);
- } else {
- length = 0;
- }
- if (debug_sel) {
- rfbLog("%s\trequest event: owner=0x%x requestor=0x%x sel=%03d targ=%d prop=%d\n",
- type, req_event->owner, req_event->requestor, req_event->selection,
- req_event->target, req_event->property);
- }
-
- if (xa_targets == None) {
- xa_targets = XInternAtom(dpy, "TARGETS", False);
- }
-
- /* the window may have gone away, so trap errors */
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
-
- if (ev->xselectionrequest.target == XA_LENGTH) {
- /* length request */
- int ret;
- long llength = (long) length;
-
- ret = XChangeProperty(ev->xselectionrequest.display,
- ev->xselectionrequest.requestor,
- ev->xselectionrequest.property,
- ev->xselectionrequest.target, 32, PropModeReplace,
- (unsigned char *) &llength, 1); /* had sizeof(unsigned int) = 4 before... */
- if (debug_sel) {
- rfbLog("LENGTH: XChangeProperty() -> %d\n", ret);
- }
-
- } else if (xa_targets != None && ev->xselectionrequest.target == xa_targets) {
- /* targets request */
- int ret;
- Atom targets[2];
- targets[0] = (Atom) xa_targets;
- targets[1] = (Atom) XA_STRING;
-
- ret = XChangeProperty(ev->xselectionrequest.display,
- ev->xselectionrequest.requestor,
- ev->xselectionrequest.property,
- ev->xselectionrequest.target, 32, PropModeReplace,
- (unsigned char *) targets, 2);
- if (debug_sel) {
- rfbLog("TARGETS: XChangeProperty() -> %d -- sz1: %d sz2: %d\n",
- ret, sizeof(targets[0]), sizeof(targets)/sizeof(targets[0]));
- }
-
- } else {
- /* data request */
- int ret;
-
- data = (unsigned char *)str;
-
- ret = XChangeProperty(ev->xselectionrequest.display,
- ev->xselectionrequest.requestor,
- ev->xselectionrequest.property,
- ev->xselectionrequest.target, 8, PropModeReplace,
- data, length);
- if (debug_sel) {
- rfbLog("DATA: XChangeProperty() -> %d\n", ret);
- }
- }
-
- if (! trapped_xerror) {
- int ret = -2, skip_it = 0, ms = 0;
- double now = dnow();
- static double last_check = 0.0;
-
- if (now > last_check + 0.2) {
- XFlush_wr(dpy);
- if (!valid_window(req_event->requestor , NULL, 1)) {
- sync_it = 1;
- skip_it = 1;
- if (debug_sel) {
- rfbLog("selection_request: not a valid window: 0x%x\n",
- req_event->requestor);
- }
- ms = 10;
- }
- if (trapped_xerror) {
- sync_it = 1;
- skip_it = 1;
- }
- last_check = dnow();
- }
-
- if (!skip_it) {
- ret = XSendEvent(req_event->display, req_event->requestor, False, 0,
- (XEvent *)&notify_event);
- }
- if (debug_sel) {
- rfbLog("XSendEvent() -> %d\n", ret);
- }
- if (ms > 0) {
- usleep(ms * 1000);
- }
- }
- if (trapped_xerror) {
- rfbLog("selection_request: ignored XError while sending "
- "%s selection to 0x%x.\n", type, req_event->requestor);
- }
-
- XFlush_wr(dpy);
- if (sync_it) {
- usleep(10 * 1000);
- XSync(dpy, False);
- }
-
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
-
-#endif /* NO_X11 */
-}
-
-int check_sel_direction(char *dir, char *label, char *sel, int len) {
- int db = 0, ok = 1;
- if (debug_sel) {
- db = 1;
- }
- if (sel_direction) {
- if (strstr(sel_direction, "debug")) {
- db = 1;
- }
- if (strcmp(sel_direction, "debug")) {
- if (strstr(sel_direction, dir) == NULL) {
- ok = 0;
- }
- }
- }
- if (db) {
- char str[40];
- int n = 40;
- strncpy(str, sel, n);
- str[n-1] = '\0';
- if (len < n) {
- str[len] = '\0';
- }
- rfbLog("%s: '%s'\n", label, str);
- if (ok) {
- rfbLog("%s: %s-ing it.\n", label, dir);
- } else {
- rfbLog("%s: NOT %s-ing it.\n", label, dir);
- }
- }
- return ok;
-}
-
-/*
- * CUT_BUFFER0 property on the local display has changed, we read and
- * store it and send it out to any connected VNC clients.
- *
- * n.b.: our caller already has the X_LOCK.
- */
-void cutbuffer_send(void) {
-#if NO_X11
- RAWFB_RET_VOID
- return;
-#else
- Atom type;
- int format, slen, dlen, len;
- unsigned long nitems = 0, bytes_after = 0;
- unsigned char* data = NULL;
-
- cutbuffer_str[0] = '\0';
- slen = 0;
-
- RAWFB_RET_VOID
-
- /* read the property value into cutbuffer_str: */
- do {
- if (XGetWindowProperty(dpy, DefaultRootWindow(dpy),
- XA_CUT_BUFFER0, nitems/4, PROP_MAX/16, False,
- AnyPropertyType, &type, &format, &nitems, &bytes_after,
- &data) == Success) {
-
- dlen = nitems * (format/8);
- if (slen + dlen > PROP_MAX) {
- /* too big */
- rfbLog("warning: truncating large CUT_BUFFER0"
- " selection > %d bytes.\n", PROP_MAX);
- XFree_wr(data);
- break;
- }
- memcpy(cutbuffer_str+slen, data, dlen);
- slen += dlen;
- cutbuffer_str[slen] = '\0';
- XFree_wr(data);
- }
- } while (bytes_after > 0);
-
- cutbuffer_str[PROP_MAX] = '\0';
-
- if (debug_sel) {
- rfbLog("cutbuffer_send: '%s'\n", cutbuffer_str);
- }
-
- if (! all_clients_initialized()) {
- rfbLog("cutbuffer_send: no send: uninitialized clients\n");
- return; /* some clients initializing, cannot send */
- }
- if (unixpw_in_progress) {
- return;
- }
-
- /* now send it to any connected VNC clients (rfbServerCutText) */
- if (!screen) {
- return;
- }
- cutbuffer_len = len = strlen(cutbuffer_str);
- if (check_sel_direction("send", "cutbuffer_send", cutbuffer_str, len)) {
- rfbSendServerCutText(screen, cutbuffer_str, len);
- }
-#endif /* NO_X11 */
-}
-
-/*
- * "callback" for our SelectionNotify polling. We try to determine if
- * the PRIMARY selection has changed (checking length and first CHKSZ bytes)
- * and if it has we store it and send it off to any connected VNC clients.
- *
- * n.b.: our caller already has the X_LOCK.
- *
- * TODO: if we were willing to use libXt, we could perhaps get selection
- * timestamps to speed up the checking... XtGetSelectionValue().
- *
- * Also: XFIXES has XFixesSelectSelectionInput().
- */
-#define CHKSZ 32
-
-void selection_send(XEvent *ev) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!ev) {}
- return;
-#else
- Atom type;
- int format, slen, dlen, oldlen, newlen, toobig = 0, len;
- static int err = 0, sent_one = 0;
- char before[CHKSZ], after[CHKSZ];
- unsigned long nitems = 0, bytes_after = 0;
- unsigned char* data = NULL;
- char *selection_str;
-
- RAWFB_RET_VOID
- /*
- * remember info about our last value of PRIMARY (or CUT_BUFFER0)
- * so we can check for any changes below.
- */
- if (ev->xselection.selection == XA_PRIMARY) {
- if (! watch_primary) {
- return;
- }
- selection_str = primary_str;
- if (debug_sel) {
- rfbLog("selection_send: event PRIMARY prop: %d requestor: 0x%x atom: %d\n",
- ev->xselection.property, ev->xselection.requestor, ev->xselection.selection);
- }
- } else if (clipboard_atom && ev->xselection.selection == clipboard_atom) {
- if (! watch_clipboard) {
- return;
- }
- selection_str = clipboard_str;
- if (debug_sel) {
- rfbLog("selection_send: event CLIPBOARD prop: %d requestor: 0x%x atom: %d\n",
- ev->xselection.property, ev->xselection.requestor, ev->xselection.selection);
- }
- } else {
- return;
- }
-
- oldlen = strlen(selection_str);
- strncpy(before, selection_str, CHKSZ);
-
- selection_str[0] = '\0';
- slen = 0;
-
- /* read in the current value of PRIMARY or CLIPBOARD: */
- do {
- if (XGetWindowProperty(dpy, ev->xselection.requestor,
- ev->xselection.property, nitems/4, PROP_MAX/16, True,
- AnyPropertyType, &type, &format, &nitems, &bytes_after,
- &data) == Success) {
-
- dlen = nitems * (format/8);
- if (slen + dlen > PROP_MAX) {
- /* too big */
- toobig = 1;
- XFree_wr(data);
- if (err) { /* cut down on messages */
- break;
- } else {
- err = 5;
- }
- rfbLog("warning: truncating large PRIMARY"
- "/CLIPBOARD selection > %d bytes.\n",
- PROP_MAX);
- break;
- }
-if (debug_sel) fprintf(stderr, "selection_send: data: '%s' dlen: %d nitems: %lu ba: %lu\n", data, dlen, nitems, bytes_after);
- memcpy(selection_str+slen, data, dlen);
- slen += dlen;
- selection_str[slen] = '\0';
- XFree_wr(data);
- }
- } while (bytes_after > 0);
-
- if (! toobig) {
- err = 0;
- } else if (err) {
- err--;
- }
-
- if (! sent_one) {
- /* try to force a send first time in */
- oldlen = -1;
- sent_one = 1;
- }
- if (debug_sel) {
- rfbLog("selection_send: %s '%s'\n",
- ev->xselection.selection == XA_PRIMARY ? "PRIMARY " : "CLIPBOARD",
- selection_str);
- }
-
- /* look for changes in the new value */
- newlen = strlen(selection_str);
- strncpy(after, selection_str, CHKSZ);
-
- if (oldlen == newlen && strncmp(before, after, CHKSZ) == 0) {
- /* evidently no change */
- if (debug_sel) {
- rfbLog("selection_send: no change.\n");
- }
- return;
- }
- if (newlen == 0) {
- /* do not bother sending a null string out */
- return;
- }
-
- if (! all_clients_initialized()) {
- rfbLog("selection_send: no send: uninitialized clients\n");
- return; /* some clients initializing, cannot send */
- }
-
- if (unixpw_in_progress) {
- return;
- }
-
- /* now send it to any connected VNC clients (rfbServerCutText) */
- if (!screen) {
- return;
- }
-
- len = newlen;
- if (ev->xselection.selection == XA_PRIMARY) {
- primary_len = len;
- } else if (clipboard_atom && ev->xselection.selection == clipboard_atom) {
- clipboard_len = len;
- }
- if (check_sel_direction("send", "selection_send", selection_str, len)) {
- rfbSendServerCutText(screen, selection_str, len);
- }
-#endif /* NO_X11 */
-}
-
-void resend_selection(char *type) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!type) {}
- return;
-#else
- char *selection_str = "";
- int len = 0;
-
- RAWFB_RET_VOID
-
- if (! all_clients_initialized()) {
- rfbLog("selection_send: no send: uninitialized clients\n");
- return; /* some clients initializing, cannot send */
- }
- if (unixpw_in_progress) {
- return;
- }
- if (!screen) {
- return;
- }
-
- if (!strcmp(type, "cutbuffer")) {
- selection_str = cutbuffer_str;
- len = cutbuffer_len;
- } else if (!strcmp(type, "clipboard")) {
- selection_str = clipboard_str;
- len = clipboard_len;
- } else if (!strcmp(type, "primary")) {
- selection_str = primary_str;
- len = primary_len;
- }
- if (check_sel_direction("send", "selection_send", selection_str, len)) {
- rfbSendServerCutText(screen, selection_str, len);
- }
-#endif /* NO_X11 */
-}
-
-
diff --git a/x11vnc/selection.h b/x11vnc/selection.h
deleted file mode 100644
index e528540..0000000
--- a/x11vnc/selection.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_SELECTION_H
-#define _X11VNC_SELECTION_H
-
-/* -- selection.h -- */
-
-extern char *xcut_str_primary;
-extern char *xcut_str_clipboard;
-extern int own_primary;
-extern int set_primary;
-extern int own_clipboard;
-extern int set_clipboard;
-extern int set_cutbuffer;
-extern int sel_waittime;
-extern Window selwin;
-extern Atom clipboard_atom;
-
-extern void selection_request(XEvent *ev, char *type);
-extern int check_sel_direction(char *dir, char *label, char *sel, int len);
-extern void cutbuffer_send(void);
-extern void selection_send(XEvent *ev);
-extern void resend_selection(char *type);
-
-#endif /* _X11VNC_SELECTION_H */
diff --git a/x11vnc/solid.c b/x11vnc/solid.c
deleted file mode 100644
index c78fb1f..0000000
--- a/x11vnc/solid.c
+++ /dev/null
@@ -1,1429 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- solid.c -- */
-
-#include "x11vnc.h"
-#include "win_utils.h"
-#include "xwrappers.h"
-#include "connections.h"
-#include "cleanup.h"
-#include "xevents.h"
-
-char *guess_desktop(void);
-void solid_bg(int restore);
-char *dbus_session(void);
-
-
-static void usr_bin_path(int restore);
-static int dt_cmd(char *cmd);
-static char *cmd_output(char *cmd);
-XImage *solid_root(char *color);
-static void solid_cde(char *color);
-static void solid_gnome(char *color);
-static void solid_kde(char *color);
-static void solid_macosx(int restore);
-
-static void usr_bin_path(int restore) {
- static char *oldpath = NULL;
- char *newpath;
- char addpath[] = "/usr/bin:/bin:";
-
- if (restore) {
- if (oldpath) {
- set_env("PATH", oldpath);
- free(oldpath);
- oldpath = NULL;
- }
- return;
- }
-
- if (getenv("PATH")) {
- oldpath = strdup(getenv("PATH"));
- } else {
- oldpath = strdup("/usr/bin");
- }
- newpath = (char *) malloc(strlen(oldpath) + strlen(addpath) + 1);
- newpath[0] = '\0';
- strcat(newpath, addpath);
- strcat(newpath, oldpath);
- set_env("PATH", newpath);
- free(newpath);
-}
-
-static int dt_cmd(char *cmd) {
- int rc;
-
- RAWFB_RET(0)
-
- if (!cmd || *cmd == '\0') {
- return 0;
- }
-
- /* dt */
- if (no_external_cmds || !cmd_ok("dt")) {
- rfbLog("cannot run external commands in -nocmds mode:\n");
- rfbLog(" \"%s\"\n", cmd);
- rfbLog(" dt_cmd: returning 1\n");
- return 1;
- }
-
- if (getenv("DISPLAY") == NULL) {
- set_env("DISPLAY", DisplayString(dpy));
- }
-
- rfbLog("running command:\n");
- if (!quiet) {
- fprintf(stderr, "\n %s\n\n", cmd);
- }
- usr_bin_path(0);
- close_exec_fds();
- rc = system(cmd);
- usr_bin_path(1);
-
- if (rc >= 256) {
- rc = rc/256;
- }
- return rc;
-}
-
-static char *cmd_output(char *cmd) {
- FILE *p;
- static char output[50000];
- char line[1024];
- int rc;
-
- if (!cmd || *cmd == '\0') {
- return "";
- }
-
- if (no_external_cmds) {
- rfbLog("cannot run external commands in -nocmds mode:\n");
- rfbLog(" \"%s\"\n", cmd);
- rfbLog(" cmd_output: null string.\n");
- return "";
- }
-
- rfbLog("running pipe:\n");
- if (!quiet) {
- fprintf(stderr, "\n %s\n\n", cmd);
- }
- usr_bin_path(0);
- close_exec_fds();
- p = popen(cmd, "r");
- usr_bin_path(1);
-
- output[0] = '\0';
-
- while (fgets(line, 1024, p) != NULL) {
- if (strlen(output) + strlen(line) + 1 < 50000) {
- strcat(output, line);
- }
- }
- rc = pclose(p);
- return(output);
-}
-
-static char *last_color = NULL;
-
-unsigned long get_pixel(char *color) {
-#if NO_X11
- return 0;
-#else
- XColor cdef;
- Colormap cmap;
- unsigned long pixel = BlackPixel(dpy, scr);
- if (depth > 8 || strcmp(color, solid_default)) {
- cmap = DefaultColormap (dpy, scr);
- if (XParseColor(dpy, cmap, color, &cdef) &&
- XAllocColor(dpy, cmap, &cdef)) {
- pixel = cdef.pixel;
- } else {
- rfbLog("error parsing/allocing color: %s\n", color);
- }
- }
- return pixel;
-#endif
-}
-
-XImage *solid_root(char *color) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!color) {}
- return NULL;
-#else
- Window expose;
- static XImage *image = NULL;
- Pixmap pixmap;
- XGCValues gcv;
- GC gc;
- XSetWindowAttributes swa;
- Visual visual;
- static unsigned long mask, pixel = 0;
-
- RAWFB_RET(NULL)
-
- if (subwin || window != rootwin) {
- rfbLog("cannot set subwin to solid color, must be rootwin\n");
- return NULL;
- }
-
- /* create the "clear" window just for generating exposures */
- swa.override_redirect = True;
- swa.backing_store = NotUseful;
- swa.save_under = False;
- swa.background_pixmap = None;
- visual.visualid = CopyFromParent;
- mask = (CWOverrideRedirect|CWBackingStore|CWSaveUnder|CWBackPixmap);
- expose = XCreateWindow(dpy, window, 0, 0, wdpy_x, wdpy_y, 0, depth,
- InputOutput, &visual, mask, &swa);
-
- if (! color) {
-
- if (! image) {
- /* whoops */
- XDestroyWindow(dpy, expose);
- rfbLog("no root snapshot available.\n");
- return NULL;
- }
-
- /* restore the root window from the XImage snapshot */
- pixmap = XCreatePixmap(dpy, window, wdpy_x, wdpy_y, depth);
-
- /* draw the image to a pixmap: */
- gcv.function = GXcopy;
- gcv.plane_mask = AllPlanes;
- gc = XCreateGC(dpy, window, GCFunction|GCPlaneMask, &gcv);
-
- XPutImage(dpy, pixmap, gc, image, 0, 0, 0, 0, wdpy_x, wdpy_y);
-
- gcv.foreground = gcv.background = BlackPixel(dpy, scr);
- gc = XCreateGC(dpy, window, GCForeground|GCBackground, &gcv);
-
- rfbLog("restoring root snapshot...\n");
- /* set the pixmap as the bg: */
- XSetWindowBackgroundPixmap(dpy, window, pixmap);
- XFreePixmap(dpy, pixmap);
- XClearWindow(dpy, window);
- XFlush_wr(dpy);
-
- /* generate exposures */
- XMapWindow(dpy, expose);
- XSync(dpy, False);
- XDestroyWindow(dpy, expose);
- return NULL;
- }
-
- if (! image) {
- /* need to retrieve a snapshot of the root background: */
- Window iwin;
- XSetWindowAttributes iswa;
-
- /* create image window: */
- iswa.override_redirect = True;
- iswa.backing_store = NotUseful;
- iswa.save_under = False;
- iswa.background_pixmap = ParentRelative;
-
- iwin = XCreateWindow(dpy, window, 0, 0, wdpy_x, wdpy_y, 0,
- depth, InputOutput, &visual, mask, &iswa);
-
- rfbLog("snapshotting background...\n");
-
- XMapWindow(dpy, iwin);
- XSync(dpy, False);
- image = XGetImage(dpy, iwin, 0, 0, wdpy_x, wdpy_y, AllPlanes,
- ZPixmap);
- XSync(dpy, False);
- XDestroyWindow(dpy, iwin);
- rfbLog("done.\n");
- }
- if (color == (char *) 0x1) {
- /* caller will XDestroyImage it: */
- XImage *xi = image;
- image = NULL;
- return xi;
- }
-
- /* use black for low colors or failure */
- pixel = get_pixel(color);
-
- rfbLog("setting solid background...\n");
- XSetWindowBackground(dpy, window, pixel);
- XMapWindow(dpy, expose);
- XSync(dpy, False);
- XDestroyWindow(dpy, expose);
-#endif /* NO_X11 */
- return NULL;
-}
-
-static void solid_cde(char *color) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!color) {}
- return;
-#else
- int wsmax = 16;
- static XImage *image[16];
- static Window ws_wins[16];
- static int nws = -1;
-
- Window expose;
- Pixmap pixmap;
- XGCValues gcv;
- GC gc;
- XSetWindowAttributes swa;
- Visual visual;
- unsigned long mask, pixel;
- XColor cdef;
- Colormap cmap;
- int n;
-
- RAWFB_RET_VOID
-
- if (subwin || window != rootwin) {
- rfbLog("cannot set subwin to solid color, must be rootwin\n");
- return;
- }
-
- /* create the "clear" window just for generating exposures */
- swa.override_redirect = True;
- swa.backing_store = NotUseful;
- swa.save_under = False;
- swa.background_pixmap = None;
- visual.visualid = CopyFromParent;
- mask = (CWOverrideRedirect|CWBackingStore|CWSaveUnder|CWBackPixmap);
- expose = XCreateWindow(dpy, window, 0, 0, wdpy_x, wdpy_y, 0, depth,
- InputOutput, &visual, mask, &swa);
-
- if (! color) {
- /* restore the backdrop windows from the XImage snapshots */
-
- for (n=0; n < nws; n++) {
- Window twin;
-
- if (! image[n]) {
- continue;
- }
-
- twin = ws_wins[n];
- if (! twin) {
- twin = rootwin;
- }
- if (! valid_window(twin, NULL, 0)) {
- continue;
- }
-
- pixmap = XCreatePixmap(dpy, twin, wdpy_x, wdpy_y,
- depth);
-
- /* draw the image to a pixmap: */
- gcv.function = GXcopy;
- gcv.plane_mask = AllPlanes;
- gc = XCreateGC(dpy, twin, GCFunction|GCPlaneMask, &gcv);
-
- XPutImage(dpy, pixmap, gc, image[n], 0, 0, 0, 0,
- wdpy_x, wdpy_y);
-
- gcv.foreground = gcv.background = BlackPixel(dpy, scr);
- gc = XCreateGC(dpy, twin, GCForeground|GCBackground,
- &gcv);
-
- rfbLog("restoring CDE ws%d snapshot to 0x%lx\n",
- n, twin);
- /* set the pixmap as the bg: */
- XSetWindowBackgroundPixmap(dpy, twin, pixmap);
- XFreePixmap(dpy, pixmap);
- XClearWindow(dpy, twin);
- XFlush_wr(dpy);
- }
-
- /* generate exposures */
- XMapWindow(dpy, expose);
- XSync(dpy, False);
- XDestroyWindow(dpy, expose);
- return;
- }
-
- if (nws < 0) {
- /* need to retrieve snapshots of the ws backgrounds: */
- Window iwin, wm_win;
- XSetWindowAttributes iswa;
- Atom dt_list, wm_info, type;
- int format;
- unsigned long length, after;
- unsigned char *data;
- unsigned long *dp; /* crash on 64bit with int */
-
- nws = 0;
-
- /* extract the hidden wm properties about backdrops: */
-
- wm_info = XInternAtom(dpy, "_MOTIF_WM_INFO", True);
- if (wm_info == None) {
- return;
- }
-
- XGetWindowProperty(dpy, rootwin, wm_info, 0L, 10L, False,
- AnyPropertyType, &type, &format, &length, &after, &data);
-
- /*
- * xprop -notype -root _MOTIF_WM_INFO
- * _MOTIF_WM_INFO = 0x2, 0x580028
- */
-
- if (length < 2 || format != 32 || after != 0) {
- return;
- }
-
- dp = (unsigned long *) data;
- wm_win = (Window) *(dp+1); /* 2nd item. */
-
-
- dt_list = XInternAtom(dpy, "_DT_WORKSPACE_LIST", True);
- if (dt_list == None) {
- return;
- }
-
- XGetWindowProperty(dpy, wm_win, dt_list, 0L, 10L, False,
- AnyPropertyType, &type, &format, &length, &after, &data);
-
- nws = length;
-
- if (nws > wsmax) {
- nws = wsmax;
- }
- if (nws < 0) {
- nws = 0;
- }
-
- rfbLog("special CDE win: 0x%lx, %d workspaces\n", wm_win, nws);
- if (nws == 0) {
- return;
- }
-
- for (n=0; n<nws; n++) {
- Atom ws_atom;
- char tmp[32];
- Window twin;
- XWindowAttributes attr;
- int i, cnt;
-
- image[n] = NULL;
- ws_wins[n] = 0x0;
-
- sprintf(tmp, "_DT_WORKSPACE_INFO_ws%d", n);
- ws_atom = XInternAtom(dpy, tmp, False);
- if (ws_atom == None) {
- continue;
- }
- XGetWindowProperty(dpy, wm_win, ws_atom, 0L, 100L,
- False, AnyPropertyType, &type, &format, &length,
- &after, &data);
-
- if (format != 8 || after != 0) {
- continue;
- }
- /*
- * xprop -notype -id wm_win
- * _DT_WORKSPACE_INFO_ws0 = "One", "3", "0x2f2f4a",
- * "0x63639c", "0x103", "1", "0x58044e"
- */
-
- cnt = 0;
- twin = 0x0;
- for (i=0; i< (int) length; i++) {
- if (*(data+i) != '\0') {
- continue;
- }
- cnt++; /* count nulls to indicate field */
- if (cnt == 6) {
- /* one past the null: */
- char *q = (char *) (data+i+1);
- unsigned long in;
- if (sscanf(q, "0x%lx", &in) == 1) {
- twin = (Window) in;
- break;
- }
- }
- }
- ws_wins[n] = twin;
-
- if (! twin) {
- twin = rootwin;
- }
-
- XGetWindowAttributes(dpy, twin, &attr);
- if (twin != rootwin) {
- if (attr.map_state != IsViewable) {
- XMapWindow(dpy, twin);
- }
- XRaiseWindow(dpy, twin);
- }
- XSync(dpy, False);
-
- /* create image window: */
- iswa.override_redirect = True;
- iswa.backing_store = NotUseful;
- iswa.save_under = False;
- iswa.background_pixmap = ParentRelative;
- visual.visualid = CopyFromParent;
-
- iwin = XCreateWindow(dpy, twin, 0, 0, wdpy_x, wdpy_y,
- 0, depth, InputOutput, &visual, mask, &iswa);
-
- rfbLog("snapshotting CDE backdrop ws%d 0x%lx -> "
- "0x%lx ...\n", n, twin, iwin);
- XMapWindow(dpy, iwin);
- XSync(dpy, False);
-
- image[n] = XGetImage(dpy, iwin, 0, 0, wdpy_x, wdpy_y,
- AllPlanes, ZPixmap);
- XSync(dpy, False);
- XDestroyWindow(dpy, iwin);
- if (twin != rootwin) {
- XLowerWindow(dpy, twin);
- if (attr.map_state != IsViewable) {
- XUnmapWindow(dpy, twin);
- }
- }
- }
- }
- if (nws == 0) {
- return;
- }
-
- /* use black for low colors or failure */
- pixel = BlackPixel(dpy, scr);
- if (depth > 8 || strcmp(color, solid_default)) {
- cmap = DefaultColormap (dpy, scr);
- if (XParseColor(dpy, cmap, color, &cdef) &&
- XAllocColor(dpy, cmap, &cdef)) {
- pixel = cdef.pixel;
- } else {
- rfbLog("error parsing/allocing color: %s\n", color);
- }
- }
-
- rfbLog("setting solid backgrounds...\n");
-
- for (n=0; n < nws; n++) {
- Window twin = ws_wins[n];
- if (image[n] == NULL) {
- continue;
- }
- if (! twin) {
- twin = rootwin;
- }
- XSetWindowBackground(dpy, twin, pixel);
- }
- XMapWindow(dpy, expose);
- XSync(dpy, False);
- XDestroyWindow(dpy, expose);
-#endif /* NO_X11 */
-}
-
-static char _dbus_str[1100];
-
-char *dbus_session(void) {
- char *dbus_env = getenv("DBUS_SESSION_BUS_ADDRESS");
- char tmp[1000];
-
- if (dbus_env != NULL && strlen(dbus_env) > 0) {
- return "";
- }
- if (!dpy) {
- return "";
- }
-#if NO_X11
- return "";
-#else
- {
- Atom dbus_prop, dbus_pid;
- Window r, w, *children;
- int sbest = -1;
- unsigned int ui;
- int rc, i;
-
- memset(_dbus_str, 0, sizeof(_dbus_str));
-
- X_LOCK;
- dbus_prop = XInternAtom(dpy, "_DBUS_SESSION_BUS_ADDRESS", True);
- dbus_pid = XInternAtom(dpy, "_DBUS_SESSION_BUS_PID", True);
- X_UNLOCK;
- if (dbus_prop == None) {
- return "";
- }
-
- X_LOCK;
- memset(tmp, 0, sizeof(tmp));
- get_prop(tmp, sizeof(tmp)-1, dbus_prop, None);
- X_UNLOCK;
- if (strcmp(tmp, "")) {
- if (!strchr(tmp, '\'')) {
- sprintf(_dbus_str, "env DBUS_SESSION_BUS_ADDRESS='%s'", tmp);
- return _dbus_str;
- }
- }
-
- X_LOCK;
- rc = XQueryTree_wr(dpy, rootwin, &r, &w, &children, &ui);
- X_UNLOCK;
- if (!rc || children == NULL || ui == 0) {
- return "";
- }
- for (i=0; i < (int) ui; i++) {
- int pid = -1;
-
- X_LOCK;
- memset(tmp, 0, sizeof(tmp));
- get_prop(tmp, sizeof(tmp)-1, dbus_prop, children[i]);
- if (dbus_pid != None) {
- Atom atype;
- int aformat;
- unsigned long nitems, bafter;
- unsigned char *prop;
- if (XGetWindowProperty(dpy, children[i], dbus_pid,
- 0, 1, False, XA_CARDINAL, &atype, &aformat,
- &nitems, &bafter, &prop) == Success
- && atype == XA_CARDINAL) {
- pid = *((int *) prop);
- XFree_wr(prop);
- }
- }
- X_UNLOCK;
-
- if (strcmp(tmp, "") && !strchr(tmp, '\'')) {
- int score = 0;
- if (1 < pid && pid < 10000000) {
- struct stat sb;
- char procfile[32];
-
- sprintf(procfile, "/proc/%d", pid);
- if (stat(procfile, &sb) == 0) {
- score += 10000000;
- }
- score += pid;
- }
- if (getenv("X11VNC_DBUS_DEBUG")) fprintf(stderr, "win: 0x%lx pid: %8d score: %8d str: %s\n", children[i], pid, score, tmp);
- if (score > sbest) {
- sprintf(_dbus_str, "env DBUS_SESSION_BUS_ADDRESS='%s'", tmp);
- sbest = score;
- }
- }
- }
- X_LOCK;
- XFree_wr(children);
- X_UNLOCK;
-
- return _dbus_str;
- }
-#endif
-}
-
-static void solid_gnome(char *color) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!color) {}
- return;
-#else
- char get_color[] = "%s gconftool-2 --get "
- "/desktop/gnome/background/primary_color";
- char set_color[] = "%s gconftool-2 --set --type string "
- "/desktop/gnome/background/primary_color '%s'";
- char get_option[] = "%s gconftool-2 --get "
- "/desktop/gnome/background/picture_options";
- char set_option[] = "%s gconftool-2 --set --type string "
- "/desktop/gnome/background/picture_options '%s'";
-#if 0
- char get_shading[] = "%s gconftool-2 --get "
- "/desktop/gnome/background/color_shading_type";
- char set_shading[] = "%s gconftool-2 --set --type string "
- "/desktop/gnome/background/color_shading_type '%s'";
- char get_filename[] = "%s gconftool-2 --get "
- "/desktop/gnome/background/picture_filename";
- char set_filename[] = "%s gconftool-2 --set --type string "
- "/desktop/gnome/background/picture_filename '%s'";
-#endif
- static char *orig_color = NULL;
- static char *orig_option = NULL;
- char *cmd, *dbus = "";
-
- RAWFB_RET_VOID
-
- dbus = dbus_session();
- rfbLog("guessed dbus: %s\n", dbus);
-
- if (! color) {
- if (! orig_color) {
- orig_color = strdup("#FFFFFF");
- }
- if (! orig_option) {
- orig_option = strdup("stretched");
- }
- if (strstr(orig_color, "'") != NULL) {
- rfbLog("invalid color: %s\n", orig_color);
- return;
- }
- if (strstr(orig_option, "'") != NULL) {
- rfbLog("invalid option: %s\n", orig_option);
- return;
- }
- cmd = (char *) malloc(strlen(set_option) - 2 + strlen(orig_option) + strlen(dbus) + 1);
- sprintf(cmd, set_option, dbus, orig_option);
- dt_cmd(cmd);
- free(cmd);
- cmd = (char *) malloc(strlen(set_color) - 2 + strlen(orig_color) + strlen(dbus) + 1);
- sprintf(cmd, set_color, dbus, orig_color);
- dt_cmd(cmd);
- free(cmd);
- return;
- }
-
- if (! orig_color) {
- char *q;
- if (cmd_ok("dt")) {
- cmd = (char *) malloc(strlen(get_color) + strlen(dbus) + 1);
- sprintf(cmd, get_color, dbus);
- orig_color = strdup(cmd_output(cmd));
- free(cmd);
- } else {
- orig_color = "";
- }
- if (*orig_color == '\0') {
- orig_color = strdup("#FFFFFF");
- }
- if ((q = strchr(orig_color, '\n')) != NULL) {
- *q = '\0';
- }
- }
- if (! orig_option) {
- char *q;
- if (cmd_ok("dt")) {
- cmd = (char *) malloc(strlen(get_option) + strlen(dbus) + 1);
- sprintf(cmd, get_option, dbus);
- orig_option = strdup(cmd_output(cmd));
- free(cmd);
- } else {
- orig_color = "";
- }
- if (*orig_option == '\0') {
- orig_option = strdup("stretched");
- }
- if ((q = strchr(orig_option, '\n')) != NULL) {
- *q = '\0';
- }
- }
- if (strstr(color, "'") != NULL) {
- rfbLog("invalid color: %s\n", color);
- return;
- }
- cmd = (char *) malloc(strlen(set_color) + strlen(color) + strlen(dbus) + 1);
- sprintf(cmd, set_color, dbus, color);
- dt_cmd(cmd);
- free(cmd);
-
- cmd = (char *) malloc(strlen(set_option) + strlen("none") + strlen(dbus) + 1);
- sprintf(cmd, set_option, dbus, "none");
- dt_cmd(cmd);
- free(cmd);
-
-#if 0
- cmd = (char *) malloc(strlen(set_filename) + strlen("none") + 1);
- sprintf(cmd, set_filename, dbus, "none");
- dt_cmd(cmd);
- free(cmd);
-#endif
-
-#endif /* NO_X11 */
-}
-
-static void solid_xfce(char *color) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!color) {}
- return;
-#else
- char get_image_show[] = "%s xfconf-query -v -c xfce4-desktop -p /backdrop/screen0/monitor0/image-show";
- char set_image_show[] = "%s xfconf-query -v -c xfce4-desktop -p /backdrop/screen0/monitor0/image-show -s '%s'";
- char get_color_style[] = "%s xfconf-query -v -c xfce4-desktop -p /backdrop/screen0/monitor0/color-style";
- char set_color_style[] = "%s xfconf-query -v -c xfce4-desktop -p /backdrop/screen0/monitor0/color-style -s '%s'";
-
- static char *orig_image_show = NULL;
- static char *orig_color_style = NULL;
- char *cmd, *dbus = "";
-
- RAWFB_RET_VOID
-
- dbus = dbus_session();
- rfbLog("guessed dbus: %s\n", dbus);
-
- if (! color) {
- if (! orig_image_show) {
- orig_image_show = "true";
- }
- if (! orig_color_style) {
- orig_color_style = "0";
- }
- if (strstr(orig_image_show, "'") != NULL) {
- rfbLog("invalid image show: %s\n", orig_image_show);
- return;
- }
- if (strstr(orig_color_style, "'") != NULL) {
- rfbLog("invalid color style: %s\n", orig_color_style);
- return;
- }
- if (orig_image_show[0] != '\0') {
- cmd = (char *) malloc(strlen(set_image_show) - 2 + strlen(orig_image_show) + strlen(dbus) + 1);
- sprintf(cmd, set_image_show, dbus, orig_image_show);
- dt_cmd(cmd);
- free(cmd);
- }
- if (orig_color_style[0] != '\0') {
- cmd = (char *) malloc(strlen(set_color_style) - 2 + strlen(orig_color_style) + strlen(dbus) + 1);
- sprintf(cmd, set_color_style, dbus, orig_color_style);
- dt_cmd(cmd);
- free(cmd);
- }
- return;
- }
-
- if (! orig_image_show) {
- char *q;
- orig_image_show = "";
- if (cmd_ok("dt")) {
- cmd = (char *) malloc(strlen(get_image_show) + strlen(dbus) + 1);
- sprintf(cmd, get_image_show, dbus);
- orig_image_show = strdup(cmd_output(cmd));
- if ((q = strrchr(orig_image_show, '\n')) != NULL) {
- *q = '\0';
- }
- fprintf(stderr, "get_image_show returned: '%s'\n\n", orig_image_show);
- free(cmd);
- if (strcasecmp(orig_image_show, "false") && strcasecmp(orig_image_show, "true")) {
- fprintf(stderr, "unrecognized image_show, disabling.\n");
- free(orig_image_show);
- orig_image_show = "";
- }
- }
- }
- if (! orig_color_style) {
- char *q;
- orig_color_style = "";
- if (cmd_ok("dt")) {
- cmd = (char *) malloc(strlen(get_color_style) + strlen(dbus) + 1);
- sprintf(cmd, get_color_style, dbus);
- orig_color_style = strdup(cmd_output(cmd));
- if ((q = strrchr(orig_color_style, '\n')) != NULL) {
- *q = '\0';
- }
- fprintf(stderr, "get_color_style returned: '%s'\n\n", orig_color_style);
- free(cmd);
- if (strlen(orig_color_style) > 1 || !isdigit((unsigned char) (*orig_color_style))) {
- fprintf(stderr, "unrecognized color_style, disabling.\n");
- free(orig_color_style);
- orig_color_style = "";
- }
- }
- }
-
- if (strstr(color, "'") != NULL) {
- rfbLog("invalid color: %s\n", color);
- return;
- }
-
- cmd = (char *) malloc(strlen(set_color_style) + strlen("0") + strlen(dbus) + 1);
- sprintf(cmd, set_color_style, dbus, "0");
- dt_cmd(cmd);
- free(cmd);
-
- cmd = (char *) malloc(strlen(set_image_show) + strlen("false") + strlen(dbus) + 1);
- sprintf(cmd, set_image_show, dbus, "false");
- dt_cmd(cmd);
- free(cmd);
-
-#endif /* NO_X11 */
-}
-
-
-static char *dcop_session(void) {
- char *empty = strdup("");
-#if NO_X11
- RAWFB_RET(empty);
- return empty;
-#else
- char list_sessions[] = "dcop --user '%s' --list-sessions";
- int len;
- char *cmd, *host, *user = NULL;
- char *out, *p, *ds, *dsn = NULL, *sess = NULL, *sess2 = NULL;
- int db = 0;
-
- RAWFB_RET(empty);
-
- if (getenv("SESSION_MANAGER")) {
- return empty;
- }
-
- user = get_user_name();
- if (strstr(user, "'") != NULL) {
- rfbLog("invalid user: %s\n", user);
- free(user);
- return empty;
- }
-
- len = strlen(list_sessions) + strlen(user) + 1;
- cmd = (char *) malloc(len);
- sprintf(cmd, list_sessions, user);
-
- out = strdup(cmd_output(cmd));
- free(cmd);
- free(user);
-
- ds = DisplayString(dpy);
- if (!ds || !strcmp(ds, "")) {
- ds = getenv("DISPLAY");
- }
- if (!ds) {
- ds = ":0";
- }
- ds = strdup(ds);
- p = strrchr(ds, '.');
- if (p) *p = '\0';
-
- dsn = strchr(ds, ':');
- if (dsn) {
- *dsn = '_';
- } else {
- free(ds);
- ds = strdup("_0");
- dsn = ds;
- }
- if (db) fprintf(stderr, "ds: %s\n", ds);
- if (db) fprintf(stderr, "dsn: %s\n", dsn);
-
- host = this_host();
- if (host) {
- char *h2 = (char *) malloc(strlen(host) + 2 + 1);
- sprintf(h2, "_%s_", host);
- free(host);
- host = h2;
- } else {
- host = strdup("");
- }
- if (db) fprintf(stderr, "host: %s\n", host);
-
- p = strtok(out, "\n");
- while (p) {
- char *q = strstr(p, ".DCOP");
- if (db) fprintf(stderr, "p: %s\n", p);
- if (q == NULL) {
- ;
- } else if (host) {
- if (strstr(q, host)) {
- char *r = strstr(p, dsn);
- int n = strlen(dsn);
- if(r && !isalnum((int) *(r+n))) {
- sess = strdup(q);
- break;
- } else {
- if (sess2) {
- free(sess2);
- }
- sess2 = strdup(q);
- }
- }
- } else {
- char *r = strstr(p, dsn);
- int n = strlen(dsn);
- if(r && !isalnum((int) *(r+n))) {
- sess = strdup(q);
- break;
- }
- }
- p = strtok(NULL, "\n");
- }
- free(ds);
- free(out);
- free(host);
- if (!sess && sess2) {
- sess = sess2;
- }
- if (!sess || strchr(sess, '\'')) {
- if (sess) free(sess);
- sess = strdup("--all-sessions");
- } else {
- len = strlen("--session ") + 2 + strlen(sess) + 1;
- cmd = (char *) malloc(len);
- sprintf(cmd, "--session '%s'", sess);
- free(sess);
- sess = cmd;
- }
- return sess;
-#endif
-}
-
-static void solid_kde(char *color) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!color) {}
- return;
-#else
- char set_color[] =
- "dcop --user '%s' %s kdesktop KBackgroundIface setColor '%s' 1";
- char bg_off[] =
- "dcop --user '%s' %s kdesktop KBackgroundIface setBackgroundEnabled 0";
- char bg_on[] =
- "dcop --user '%s' %s kdesktop KBackgroundIface setBackgroundEnabled 1";
- char *cmd, *user = NULL, *sess;
- int len;
-
- RAWFB_RET_VOID
-
- user = get_user_name();
- if (strstr(user, "'") != NULL) {
- rfbLog("invalid user: %s\n", user);
- free(user);
- return;
- }
-
- set_env("DISPLAY", DisplayString(dpy));
-
- if (! color) {
- sess = dcop_session();
- len = strlen(bg_on) + strlen(user) + strlen(sess) + 1;
- cmd = (char *) malloc(len);
- sprintf(cmd, bg_on, user, sess);
-
- dt_cmd(cmd);
-
- free(cmd);
- free(user);
- free(sess);
-
- return;
- }
-
- if (strstr(color, "'") != NULL) {
- rfbLog("invalid color: %s\n", color);
- return;
- }
-
- sess = dcop_session();
-
- len = strlen(set_color) + strlen(user) + strlen(sess) + strlen(color) + 1;
- cmd = (char *) malloc(len);
- sprintf(cmd, set_color, user, sess, color);
- dt_cmd(cmd);
- free(cmd);
-
- len = strlen(bg_off) + strlen(user) + strlen(sess) + 1;
- cmd = (char *) malloc(len);
- sprintf(cmd, bg_off, user, sess);
- dt_cmd(cmd);
- free(cmd);
- free(user);
-#endif /* NO_X11 */
-}
-
-void kde_no_animate(int restore) {
-#if NO_X11
- if (!restore) {}
- RAWFB_RET_VOID
- return;
-#else
- char query_setting[] =
- "kreadconfig --file kwinrc --group Windows --key AnimateMinimize";
- char kwinrc_off[] =
- "kwriteconfig --file kwinrc --group Windows --key AnimateMinimize --type bool false";
- char kwinrc_on[] =
- "kwriteconfig --file kwinrc --group Windows --key AnimateMinimize --type bool true";
- char kwin_reconfigure[] =
- "dcop --user '%s' %s kwin KWinInterface reconfigure";
- char *cmd, *cmd2, *out, *user = NULL, *sess;
- int len;
- static int anim_state = 1;
-
- RAWFB_RET_VOID
-
- if (ncache_keep_anims) {
- return;
- }
-
- if (restore) {
- if (anim_state == 1) {
- return;
- }
-
- user = get_user_name();
- if (strstr(user, "'") != NULL) {
- rfbLog("invalid user: %s\n", user);
- free(user);
- return;
- }
-
- sess = dcop_session();
-
- len = strlen(kwin_reconfigure) + strlen(user) + strlen(sess) + 1;
- cmd = (char *) malloc(len);
- sprintf(cmd, kwin_reconfigure, user, sess);
- rfbLog("\n");
- rfbLog("Restoring KDE kwinrc settings.\n");
- rfbLog("\n");
- dt_cmd(cmd);
- free(cmd);
- free(user);
- free(sess);
- anim_state = 1;
- return;
- } else {
- if (anim_state == 0) {
- return;
- }
- anim_state = 0;
- }
-
- user = get_user_name();
- if (strstr(user, "'") != NULL) {
- rfbLog("invalid user: %s\n", user);
- free(user);
- return;
- }
- out = cmd_output(query_setting);
-
-
- if (!out || strstr(out, "false")) {
- rfbLog("\n");
- rfbLog("********************************************************\n");
- rfbLog("KDE kwinrc AnimateMinimize is false. Good.\n");
- rfbLog("********************************************************\n");
- rfbLog("\n");
- free(user);
- return;
- }
-
- rfbLog("\n");
- rfbLog("********************************************************\n");
- rfbLog("To improve the -ncache client-side caching performance\n");
- rfbLog("temporarily setting KDE kwinrc AnimateMinimize to false.\n");
- rfbLog("It will be reset for the next session or when VNC client\n");
- rfbLog("disconnects. Or you can use the Control Center GUI to\n");
- rfbLog("change it now (toggle its setting a few times):\n");
- rfbLog(" Desktop -> Window Behavior -> Moving\n");
- rfbLog("********************************************************\n");
- rfbLog("\n");
-
- set_env("DISPLAY", DisplayString(dpy));
-
- sess = dcop_session();
- len = strlen(kwin_reconfigure) + strlen(user) + strlen(sess) + 1;
- cmd = (char *) malloc(len);
- sprintf(cmd, kwin_reconfigure, user, sess);
-
- len = 1 + strlen("sleep 10") + 2 + strlen(kwinrc_off) + 2 + strlen(cmd) + 2 + strlen("sleep 5") + 2 + strlen(kwinrc_on) + 3 + 1;
- cmd2 = (char *) malloc(len);
-
- sprintf(cmd2, "(sleep 10; %s; %s; sleep 5; %s) &", kwinrc_off, cmd, kwinrc_on);
-
- dt_cmd(cmd2);
- free(cmd);
- free(cmd2);
- free(user);
- free(sess);
-#endif /* NO_X11 */
-}
-
-void gnome_no_animate(void) {
- ;
-}
-
-static pid_t solid_macosx_pid = 0;
-extern char macosx_solid_background[];
-
-static void solid_macosx(int restore) {
- char tmp[] = "/tmp/macosx_solid_background.XXXXXX";
- pid_t pid, parent = getpid();
-
- if (restore) {
- rfbLog("restore pid: %d\n", (int) solid_macosx_pid);
- if (solid_macosx_pid > 0) {
-#if 0
- int i, status;
-#endif
- rfbLog("kill -TERM macosx_solid_background helper pid: %d\n", (int) solid_macosx_pid);
- kill(solid_macosx_pid, SIGTERM);
-#if 0
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H
-#if LIBVNCSERVER_HAVE_WAITPID
- for (i=0; i < 7; i++) {
- usleep(1000 * 1000);
- waitpid(solid_macosx_pid, &status, WNOHANG);
- if (kill(solid_macosx_pid, 0) != 0) {
- break;
- }
- }
-#endif
-#endif
-#endif
- solid_macosx_pid = 0;
- }
- return;
- }
- if (no_external_cmds || !cmd_ok("dt")) {
- return;
- }
-#if LIBVNCSERVER_HAVE_FORK
- pid = fork();
-
- if (pid == -1) {
- perror("fork");
- return;
- }
- if (pid == 0) {
- int fd = mkstemp(tmp);
-#if LIBVNCSERVER_HAVE_SETSID
- setsid();
-#else
- setpgrp();
-#endif
- if (fd >= 0) {
- char num[32];
- write(fd, macosx_solid_background, strlen(macosx_solid_background));
- close(fd);
- sprintf(num, "%d", (int) parent);
- set_env("SS_WATCH_PID", num);
- execlp("/bin/sh", "/bin/sh", tmp, (char *) NULL);
- }
- exit(1);
- }
- solid_macosx_pid = pid;
- rfbLog("macosx_solid_background helper pid: %d\n", (int) solid_macosx_pid);
- usleep(2750 * 1000);
- unlink(tmp);
-#endif
-}
-
-char *guess_desktop(void) {
-#if NO_X11
- RAWFB_RET("root")
- return "root";
-#else
- Atom prop;
-
- RAWFB_RET("root")
-
- if (wmdt_str && *wmdt_str != '\0') {
- char *s = wmdt_str;
- lowercase(s);
- if (strstr(s, "xfce")) {
- return "xfce";
- }
- if (strstr(s, "gnome") || strstr(s, "metacity")) {
- return "gnome";
- }
- if (strstr(s, "kde") || strstr(s, "kwin")) {
- return "kde";
- }
- if (strstr(s, "cde")) {
- return "cde";
- }
- return "root";
- }
-
- if (! dpy) {
- return "";
- }
-
- prop = XInternAtom(dpy, "XFCE_DESKTOP_WINDOW", True);
- if (prop != None) return "xfce";
-
- /* special case windowmaker */
- prop = XInternAtom(dpy, "_WINDOWMAKER_WM_PROTOCOLS", True);
- if (prop != None) return "root";
-
- prop = XInternAtom(dpy, "_WINDOWMAKER_COMMAND", True);
- if (prop != None) return "root";
-
- prop = XInternAtom(dpy, "NAUTILUS_DESKTOP_WINDOW_ID", True);
- if (prop != None) return "gnome";
-
- prop = XInternAtom(dpy, "KWIN_RUNNING", True);
- if (prop != None) {
- prop = XInternAtom(dpy, "_KDE_RUNNING", True);
- if (prop != None) {
- prop = XInternAtom(dpy, "KDE_DESKTOP_WINDOW", True);
- if (prop != None) return "kde";
- }
- }
-
- prop = XInternAtom(dpy, "_MOTIF_WM_INFO", True);
- if (prop != None) {
- prop = XInternAtom(dpy, "_DT_WORKSPACE_LIST", True);
- if (prop != None) return "cde";
- }
- return "root";
-#endif /* NO_X11 */
-}
-
-XImage *solid_image(char *color) {
-#if NO_X11
- RAWFB_RET(NULL)
- return NULL;
-#else
- XImage *image = NULL;
- unsigned long pixel = 0;
- int x, y;
-
- RAWFB_RET(NULL)
-
- if (!color) {
- color = last_color;
- }
-
- if (!color) {
- return NULL;
- }
-
- image = XGetImage(dpy, rootwin, 0, 0, wdpy_x, wdpy_y, AllPlanes,
- ZPixmap);
-
- if (!image) {
- return NULL;
- }
- pixel = get_pixel(color);
-
- for (y=0; y<wdpy_y; y++) {
- for (x=0; x<wdpy_x; x++) {
- XPutPixel(image, x, y, pixel);
- }
- }
- return image;
-#endif /* NO_X11 */
-}
-
-void solid_bg(int restore) {
- static int desktop = -1;
- static int solid_on = 0;
- static char *prev_str;
- char *dtname, *color;
-
- if (started_as_root == 1 && users_list) {
- /* we are still root, don't try. */
- return;
- }
-
- if (macosx_console) {
- solid_macosx(restore);
- return;
- }
-
- RAWFB_RET_VOID
-
- if (restore) {
- if (! solid_on) {
- return;
- }
- if (desktop == 0) {
- solid_root(NULL);
- } else if (desktop == 1) {
- solid_gnome(NULL);
- } else if (desktop == 2) {
- solid_kde(NULL);
- } else if (desktop == 3) {
- solid_cde(NULL);
- } else if (desktop == 4) {
- solid_xfce(NULL);
- }
- solid_on = 0;
- return;
- }
- if (! solid_str) {
- return;
- }
- if (solid_on && !strcmp(prev_str, solid_str)) {
- return;
- }
- if (strstr(solid_str, "guess:") == solid_str
- || !strchr(solid_str, ':')) {
- dtname = guess_desktop();
- rfbLog("guessed desktop: %s\n", dtname);
- } else {
- if (strstr(solid_str, "gnome:") == solid_str) {
- dtname = "gnome";
- } else if (strstr(solid_str, "kde:") == solid_str) {
- dtname = "kde";
- } else if (strstr(solid_str, "cde:") == solid_str) {
- dtname = "cde";
- } else if (strstr(solid_str, "xfce:") == solid_str) {
- dtname = "xfce";
- } else {
- dtname = "root";
- }
- }
-
- color = strchr(solid_str, ':');
- if (! color) {
- color = solid_str;
- } else {
- color++;
- if (*color == '\0') {
- color = solid_default;
- }
- }
- if (last_color) {
- free(last_color);
- }
- last_color = strdup(color);
-
- if (!strcmp(dtname, "gnome")) {
- desktop = 1;
- solid_gnome(color);
- } else if (!strcmp(dtname, "kde")) {
- desktop = 2;
- solid_kde(color);
- } else if (!strcmp(dtname, "cde")) {
- desktop = 3;
- solid_cde(color);
- } else if (!strcmp(dtname, "xfce")) {
- desktop = 4;
- solid_xfce(color);
- } else {
- desktop = 0;
- solid_root(color);
- }
- if (prev_str) {
- free(prev_str);
- }
- prev_str = strdup(solid_str);
- solid_on = 1;
-}
-
-
diff --git a/x11vnc/solid.h b/x11vnc/solid.h
deleted file mode 100644
index 4d45ace..0000000
--- a/x11vnc/solid.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_SOLID_H
-#define _X11VNC_SOLID_H
-
-/* -- solid.h -- */
-
-extern char *guess_desktop(void);
-extern unsigned long get_pixel(char *color);
-extern XImage *solid_image(char *color);
-extern void solid_bg(int restore);
-extern char *dbus_session(void);
-extern XImage *solid_root(char *color);
-extern void kde_no_animate(int restore);
-extern void gnome_no_animate(void);
-
-#endif /* _X11VNC_SOLID_H */
diff --git a/x11vnc/sslcmds.c b/x11vnc/sslcmds.c
deleted file mode 100644
index 7c4bdc1..0000000
--- a/x11vnc/sslcmds.c
+++ /dev/null
@@ -1,908 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- sslcmds.c -- */
-
-#include "x11vnc.h"
-#include "inet.h"
-#include "cleanup.h"
-#include "sslhelper.h"
-#include "ssltools.h"
-#include "connections.h"
-
-#if LIBVNCSERVER_HAVE_FORK
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H
-#if LIBVNCSERVER_HAVE_WAITPID
-#define SSLCMDS
-#endif
-#endif
-#endif
-
-
-void check_stunnel(void);
-int start_stunnel(int stunnel_port, int x11vnc_port, int hport, int x11vnc_hport);
-void stop_stunnel(void);
-void setup_stunnel(int rport, int *argc, char **argv);
-char *get_Cert_dir(char *cdir_in, char **tmp_in);
-void sslScripts(void);
-void sslGenCA(char *cdir);
-void sslGenCert(char *ty, char *nm);
-void sslEncKey(char *path, int info_only);
-
-static pid_t stunnel_pid = 0;
-
-void check_stunnel(void) {
- static time_t last_check = 0;
- time_t now = time(NULL);
-
- if (last_check + 3 >= now) {
- return;
- }
- last_check = now;
-
- /* double check that stunnel is still running: */
-
- if (stunnel_pid > 0) {
- int status;
-#ifdef SSLCMDS
- waitpid(stunnel_pid, &status, WNOHANG);
-#endif
- if (kill(stunnel_pid, 0) != 0) {
-#ifdef SSLCMDS
- waitpid(stunnel_pid, &status, WNOHANG);
-#endif
- rfbLog("stunnel subprocess %d died.\n", stunnel_pid);
- stunnel_pid = 0;
- clean_up_exit(1);
- }
- }
-}
-
-int start_stunnel(int stunnel_port, int x11vnc_port, int hport, int x11vnc_hport) {
-#ifdef SSLCMDS
- char extra[] = ":/usr/sbin:/usr/local/sbin:/dist/sbin";
- char *path, *p, *exe;
- char *stunnel_path = NULL;
- struct stat verify_buf;
- struct stat crl_buf;
- int status, tmp_pem = 0;
-
- if (stunnel_pid) {
- stop_stunnel();
- }
- stunnel_pid = 0;
-
- path = getenv("PATH");
- if (! path) {
- path = strdup(extra+1);
- } else {
- char *pt = path;
- path = (char *) malloc(strlen(path)+strlen(extra)+1);
- if (! path) {
- return 0;
- }
- strcpy(path, pt);
- strcat(path, extra);
- }
-
- exe = (char *) malloc(strlen(path) + 1 + strlen("stunnel4") + 1);
-
- p = strtok(path, ":");
-
- exe[0] = '\0';
-
- while (p) {
- struct stat sbuf;
-
- sprintf(exe, "%s/%s", p, "stunnel4");
- if (! stunnel_path && stat(exe, &sbuf) == 0) {
- if (! S_ISDIR(sbuf.st_mode)) {
- stunnel_path = exe;
- break;
- }
- }
-
- sprintf(exe, "%s/%s", p, "stunnel");
- if (! stunnel_path && stat(exe, &sbuf) == 0) {
- if (! S_ISDIR(sbuf.st_mode)) {
- stunnel_path = exe;
- break;
- }
- }
-
- p = strtok(NULL, ":");
- }
- if (path) {
- free(path);
- }
-
- if (getenv("STUNNEL_PROG")) {
- free(exe);
- exe = strdup(getenv("STUNNEL_PROG"));
- stunnel_path = exe;
- }
-
- if (! stunnel_path) {
- free(exe);
- return 0;
- }
- if (stunnel_path[0] == '\0') {
- free(exe);
- return 0;
- }
-
- /* stunnel */
- if (no_external_cmds || !cmd_ok("stunnel")) {
- rfbLogEnable(1);
- rfbLog("start_stunnel: cannot run external commands in -nocmds mode:\n");
- rfbLog(" \"%s\"\n", stunnel_path);
- rfbLog(" exiting.\n");
- clean_up_exit(1);
- }
-
- if (! quiet) {
- rfbLog("\n");
- rfbLog("starting ssl tunnel: %s %d -> %d\n", stunnel_path,
- stunnel_port, x11vnc_port);
- }
-
- if (stunnel_pem && strstr(stunnel_pem, "SAVE") == stunnel_pem) {
- stunnel_pem = get_saved_pem(stunnel_pem, 1);
- if (! stunnel_pem) {
- rfbLog("start_stunnel: could not create or open"
- " saved PEM.\n");
- clean_up_exit(1);
- }
- } else if (!stunnel_pem) {
- stunnel_pem = create_tmp_pem(NULL, 0);
- if (! stunnel_pem) {
- rfbLog("start_stunnel: could not create temporary,"
- " self-signed PEM.\n");
- clean_up_exit(1);
- }
- tmp_pem = 1;
- if (getenv("X11VNC_SHOW_TMP_PEM")) {
- FILE *in = fopen(stunnel_pem, "r");
- if (in != NULL) {
- char line[128];
- fprintf(stderr, "\n");
- while (fgets(line, 128, in) != NULL) {
- fprintf(stderr, "%s", line);
- }
- fprintf(stderr, "\n");
- fclose(in);
- }
- }
- }
-
- if (ssl_verify) {
- char *file = get_ssl_verify_file(ssl_verify);
- if (file) {
- ssl_verify = file;
- }
- if (stat(ssl_verify, &verify_buf) != 0) {
- rfbLog("stunnel: %s does not exist.\n", ssl_verify);
- clean_up_exit(1);
- }
- }
- if (ssl_crl) {
- if (stat(ssl_crl, &crl_buf) != 0) {
- rfbLog("stunnel: %s does not exist.\n", ssl_crl);
- clean_up_exit(1);
- }
- }
-
- stunnel_pid = fork();
-
- if (stunnel_pid < 0) {
- stunnel_pid = 0;
- free(exe);
- return 0;
- }
-
- if (stunnel_pid == 0) {
- FILE *in;
- char fd[20];
- int i;
- char *st_if = getenv("STUNNEL_LISTEN");
-
- if (st_if == NULL) {
- st_if = "";
- } else {
- st_if = (char *) malloc(strlen(st_if) + 2);
- sprintf(st_if, "%s:", getenv("STUNNEL_LISTEN"));
- }
-
-
- for (i=3; i<256; i++) {
- close(i);
- }
-
- if (use_stunnel == 3) {
- char sp[30], xp[30], *a = NULL;
- char *st = stunnel_path;
- char *pm = stunnel_pem;
- char *sv = ssl_verify;
-
- sprintf(sp, "%d", stunnel_port);
- sprintf(xp, "%d", x11vnc_port);
-
- if (ssl_verify) {
- if(S_ISDIR(verify_buf.st_mode)) {
- a = "-a";
- } else {
- a = "-A";
- }
- }
-
- if (ssl_crl) {
- rfbLog("stunnel: stunnel3 does not support CRL. %s\n", ssl_crl);
- clean_up_exit(1);
- }
-
- if (stunnel_pem && ssl_verify) {
- /* XXX double check -v 2 */
- execlp(st, st, "-f", "-d", sp, "-r", xp, "-P",
- "none", "-p", pm, a, sv, "-v", "2",
- (char *) NULL);
- } else if (stunnel_pem && !ssl_verify) {
- execlp(st, st, "-f", "-d", sp, "-r", xp, "-P",
- "none", "-p", pm,
- (char *) NULL);
- } else if (!stunnel_pem && ssl_verify) {
- execlp(st, st, "-f", "-d", sp, "-r", xp, "-P",
- "none", a, sv, "-v", "2",
- (char *) NULL);
- } else {
- execlp(st, st, "-f", "-d", sp, "-r", xp, "-P",
- "none", (char *) NULL);
- }
- exit(1);
- }
-
- in = tmpfile();
- if (! in) {
- exit(1);
- }
-
- fprintf(in, "foreground = yes\n");
- fprintf(in, "pid =\n");
- if (stunnel_pem) {
- fprintf(in, "cert = %s\n", stunnel_pem);
- }
- if (ssl_crl) {
- if(S_ISDIR(crl_buf.st_mode)) {
- fprintf(in, "CRLpath = %s\n", ssl_crl);
- } else {
- fprintf(in, "CRLfile = %s\n", ssl_crl);
- }
- }
- if (ssl_verify) {
- if(S_ISDIR(verify_buf.st_mode)) {
- fprintf(in, "CApath = %s\n", ssl_verify);
- } else {
- fprintf(in, "CAfile = %s\n", ssl_verify);
- }
- fprintf(in, "verify = 2\n");
- }
- fprintf(in, ";debug = 7\n\n");
- fprintf(in, "[x11vnc_stunnel]\n");
- fprintf(in, "accept = %s%d\n", st_if, stunnel_port);
- fprintf(in, "connect = %d\n", x11vnc_port);
-
- if (hport > 0 && x11vnc_hport > 0) {
- fprintf(in, "\n[x11vnc_http]\n");
- fprintf(in, "accept = %s%d\n", st_if, hport);
- fprintf(in, "connect = %d\n", x11vnc_hport);
- }
-
- fflush(in);
- rewind(in);
-
- if (getenv("STUNNEL_DEBUG")) {
- char line[1000];
- fprintf(stderr, "\nstunnel config contents:\n\n");
- while (fgets(line, sizeof(line), in) != NULL) {
- fprintf(stderr, "%s", line);
- }
- fprintf(stderr, "\n");
- rewind(in);
- }
-
- sprintf(fd, "%d", fileno(in));
- execlp(stunnel_path, stunnel_path, "-fd", fd, (char *) NULL);
- exit(1);
- }
-
- free(exe);
- usleep(750 * 1000);
-
- waitpid(stunnel_pid, &status, WNOHANG);
-
- if (ssl_verify && strstr(ssl_verify, "/sslverify-tmp-load-")) {
- /* temporary file */
- usleep(1000 * 1000);
- unlink(ssl_verify);
- }
- if (tmp_pem) {
- /* temporary cert */
- usleep(1500 * 1000);
- unlink(stunnel_pem);
- }
-
- if (kill(stunnel_pid, 0) != 0) {
- waitpid(stunnel_pid, &status, WNOHANG);
- stunnel_pid = 0;
- return 0;
- }
-
- if (! quiet) {
- rfbLog("stunnel pid is: %d\n", (int) stunnel_pid);
- }
-
- return 1;
-#else
- return 0;
-#endif
-}
-
-void stop_stunnel(void) {
- int status;
- if (! stunnel_pid) {
- return;
- }
-#ifdef SSLCMDS
- kill(stunnel_pid, SIGTERM);
- usleep (150 * 1000);
- kill(stunnel_pid, SIGKILL);
- usleep (50 * 1000);
- waitpid(stunnel_pid, &status, WNOHANG);
-#endif
- stunnel_pid = 0;
-}
-
-void setup_stunnel(int rport, int *argc, char **argv) {
- int i, xport = 0, hport = 0, xhport = 0;
-
- if (! rport && argc && argv) {
- for (i=0; i< *argc; i++) {
- if (argv[i] && !strcmp(argv[i], "-rfbport")) {
- if (i < *argc - 1) {
- rport = atoi(argv[i+1]);
- }
- }
- }
- }
-
- if (! rport) {
- /* we do our own autoprobing then... */
- rport = find_free_port(5900, 5999);
- if (! rport) {
- goto stunnel_fail;
- }
- }
-
- xport = find_free_port(5950, 5999);
- if (! xport) {
- goto stunnel_fail;
- }
-
- if (https_port_num > 0) {
- hport = https_port_num;
- }
-
- if (! hport && argc && argv) {
- for (i=0; i< *argc; i++) {
- if (argv[i] && !strcmp(argv[i], "-httpport")) {
- if (i < *argc - 1) {
- hport = atoi(argv[i+1]);
- }
- }
- }
- }
-
- if (! hport && http_try_it) {
- hport = find_free_port(rport-100, rport-1);
- if (! hport) {
- goto stunnel_fail;
- }
- }
- if (hport) {
- xhport = find_free_port(5850, 5899);
- if (! xhport) {
- goto stunnel_fail;
- }
- stunnel_http_port = hport;
- }
-
-
- if (start_stunnel(rport, xport, hport, xhport)) {
- int tweaked = 0;
- char tmp[30];
- sprintf(tmp, "%d", xport);
- if (argc && argv) {
- for (i=0; i < *argc; i++) {
- if (argv[i] && !strcmp(argv[i], "-rfbport")) {
- if (i < *argc - 1) {
- /* replace orig value */
- argv[i+i] = strdup(tmp);
- tweaked = 1;
- break;
- }
- }
- }
- if (! tweaked) {
- i = *argc;
- argv[i] = strdup("-rfbport");
- argv[i+1] = strdup(tmp);
- *argc += 2;
- got_rfbport = 1;
- got_rfbport_val = atoi(tmp);
- }
- }
- stunnel_port = rport;
- ssl_initialized = 1;
- return;
- }
-
- stunnel_fail:
- rfbLog("failed to start stunnel.\n");
- clean_up_exit(1);
-}
-
-char *get_Cert_dir(char *cdir_in, char **tmp_in) {
- char *cdir, *home, *tmp;
- struct stat sbuf;
- int i;
- char *cases1[] = {"/.vnc", "/.vnc/certs", "/.vnc/certs/CA"};
- char *cases2[] = {"", "/CA", "/tmp"};
-
- if (cdir_in != NULL) {
- cdir = cdir_in;
- } else {
- cdir = ssl_certs_dir;
- }
-
- if (cdir == NULL) {
- home = get_home_dir();
- if (! home) {
- return NULL;
- }
- cdir = (char *) malloc(strlen(home) + strlen("/.vnc/certs/CA") + 1);
- for (i=0; i<3; i++) {
- sprintf(cdir, "%s%s", home, cases1[i]);
- if (stat(cdir, &sbuf) != 0) {
- rfbLog("creating dir: %s\n", cdir);
- if (mkdir(cdir, 0755) != 0) {
- rfbLog("could not create directory %s\n", cdir);
- rfbLogPerror("mkdir");
- return NULL;
- }
- } else if (! S_ISDIR(sbuf.st_mode)) {
- rfbLog("not a directory: %s\n", cdir);
- return NULL;
- }
- }
- sprintf(cdir, "%s%s", home, cases1[1]);
- }
-
- tmp = (char *) malloc(strlen(cdir) + strlen("/tmp") + 1);
- for (i=0; i<3; i++) {
- int ret;
- sprintf(tmp, "%s%s", cdir, cases2[i]);
- if (stat(tmp, &sbuf) != 0) {
- rfbLog("creating dir: %s\n", tmp);
- if (! strcmp(cases2[i], "/tmp")) {
- ret = mkdir(tmp, 0700);
- } else {
- ret = mkdir(tmp, 0755);
- }
-
- if (ret != 0) {
- rfbLog("could not create directory %s\n", tmp);
- rfbLogPerror("mkdir");
- return NULL;
- }
- } else if (! S_ISDIR(sbuf.st_mode)) {
- rfbLog("not a directory: %s\n", tmp);
- return NULL;
- }
- }
- sprintf(tmp, "%s/tmp", cdir);
- *tmp_in = tmp;
- return cdir;
-}
-
-static char *getsslscript(char *cdir, char *name, char *script) {
- char *openssl = find_openssl_bin();
- char *tmp, *scr, *cdir_use;
- FILE *out;
-
- if (! openssl || openssl[0] == '\0') {
- exit(1);
- }
-
- if (!name || !script) {
- exit(1);
- }
-
- cdir_use = get_Cert_dir(cdir, &tmp);
- if (!cdir_use || !tmp) {
- exit(1);
- }
-
- scr = (char *) malloc(strlen(tmp) + 1 + strlen(name) + 30);
-
- sprintf(scr, "%s/%s.%d.sh", tmp, name, getpid());
- out = fopen(scr, "w");
- if (! out) {
- rfbLog("could not open: %s\n", scr);
- rfbLogPerror("fopen");
- exit(1);
- }
- fprintf(out, "%s", script);
- fclose(out);
-
- rfbLog("Using openssl: %s\n", openssl);
- rfbLog("Using certs dir: %s\n", cdir_use);
- fprintf(stderr, "\n");
-
- set_env("BASE_DIR", cdir_use);
- set_env("OPENSSL", openssl);
-
- return scr;
-}
-
-void sslScripts(void) {
- fprintf(stdout, "======================================================\n");
- fprintf(stdout, "genCA script for '-sslGenCA':\n\n");
- fprintf(stdout, "%s\n", genCA);
- fprintf(stdout, "======================================================\n");
- fprintf(stdout, "genCert script for '-sslGenCert', etc.:\n\n");
- fprintf(stdout, "%s\n", genCert);
-}
-
-void sslGenCA(char *cdir) {
- char *cmd, *scr = getsslscript(cdir, "genca", genCA);
-
- if (! scr) {
- exit(1);
- }
-
- cmd = (char *)malloc(strlen("/bin/sh ") + strlen(scr) + 1);
- sprintf(cmd, "/bin/sh %s", scr);
-
- system(cmd);
- unlink(scr);
-
- free(cmd);
- free(scr);
-}
-
-void sslGenCert(char *ty, char *nm) {
- char *cmd, *scr = getsslscript(NULL, "gencert", genCert);
-
- if (! scr) {
- exit(1);
- }
-
- cmd = (char *)malloc(strlen("/bin/sh ") + strlen(scr) + 1);
- sprintf(cmd, "/bin/sh %s", scr);
-
- if (! ty) {
- set_env("TYPE", "");
- } else {
- set_env("TYPE", ty);
- }
- if (! nm) {
- set_env("NAME", "");
- } else {
- char *q = strstr(nm, "SAVE-");
- if (!strcmp(nm, "SAVE")) {
- set_env("NAME", "");
- } else if (q == nm) {
- q += strlen("SAVE-");
- set_env("NAME", q);
- } else {
- set_env("NAME", nm);
- }
- }
-
- system(cmd);
- unlink(scr);
-
- free(cmd);
- free(scr);
-}
-
-void sslEncKey(char *path, int mode) {
- char *openssl = find_openssl_bin();
- char *scr, *cert = NULL, *tca, *cdir = NULL;
- char line[1024], tmp[] = "/tmp/x11vnc-tmp.XXXXXX";
- int tmp_fd, incert, info_only = 0, delete_only = 0, listlong = 0;
- struct stat sbuf;
- FILE *file;
- static int depth = 0;
-
- if (depth > 0) {
- /* get_saved_pem may call us back. */
- return;
- }
-
- if (! path) {
- return;
- }
-
- depth++;
-
- if (mode == 1) {
- info_only = 1;
- } else if (mode == 2) {
- delete_only = 1;
- }
-
- if (! openssl) {
- exit(1);
- }
-
- cdir = get_Cert_dir(NULL, &tca);
- if (! cdir || ! tca) {
- fprintf(stderr, "could not find Cert dir\n");
- exit(1);
- }
-
- if (!strcasecmp(path, "LL") || !strcasecmp(path, "LISTL")) {
- listlong = 1;
- path = "LIST";
- }
-
- if (strstr(path, "SAVE") == path) {
- char *p = get_saved_pem(path, 0);
- if (p == NULL) {
- fprintf(stderr, "could not find saved pem "
- "matching: %s\n", path);
- exit(1);
- }
- path = p;
-
- } else if (!strcmp(path, "CA")) {
- tca = (char *) malloc(strlen(cdir)+strlen("/CA/cacert.pem")+1);
- sprintf(tca, "%s/CA/cacert.pem", cdir);
- path = tca;
-
- } else if (info_only && (!strcasecmp(path, "LIST") ||
- !strcasecmp(path, "LS") || !strcasecmp(path, "ALL"))) {
-
- if (! program_name || strchr(program_name, ' ')) {
- fprintf(stderr, "bad program name.\n");
- exit(1);
- }
- if (strchr(cdir, '\'')) {
- fprintf(stderr, "bad certdir char: %s\n", cdir);
- exit(1);
- }
-
- tca = (char *) malloc(2*strlen(cdir)+strlen(program_name)+1000);
-
- sprintf(tca, "find '%s' | egrep '/(CA|tmp|clients)$|"
- "\\.(crt|pem|key|req)$' | grep -v CA/newcerts", cdir);
-
- if (!strcasecmp(path, "ALL")) {
- /* ugh.. */
- strcat(tca, " | egrep -v 'private/cakey.pem|"
- "(CA|tmp|clients)$' | xargs -n1 ");
- strcat(tca, program_name);
- strcat(tca, " -ssldir '");
- strcat(tca, cdir);
- strcat(tca, "' -sslCertInfo 2>&1 ");
- } else if (listlong) {
- strcat(tca, " | xargs ls -ld ");
- }
- system(tca);
- free(tca);
-
- depth--;
- return;
-
- } else if (info_only && (!strcasecmp(path, "HASHON")
- || !strcasecmp(path, "HASHOFF"))) {
-
- tmp_fd = mkstemp(tmp);
- if (tmp_fd < 0) {
- exit(1);
- }
-
- write(tmp_fd, genCert, strlen(genCert));
- close(tmp_fd);
-
- scr = (char *) malloc(strlen("/bin/sh ") + strlen(tmp) + 1);
- sprintf(scr, "/bin/sh %s", tmp);
-
- set_env("BASE_DIR", cdir);
- set_env("OPENSSL", openssl);
- set_env("TYPE", "server");
- if (!strcasecmp(path, "HASHON")) {
- set_env("HASHON", "1");
- } else {
- set_env("HASHOFF", "1");
- }
- system(scr);
- unlink(tmp);
- free(scr);
-
- depth--;
- return;
- }
-
-
- if (stat(path, &sbuf) != 0) {
- if (strstr(path, "client") || strchr(path, '/') == NULL) {
- int i;
- tca = (char *) malloc(strlen(cdir) + strlen(path) + 100);
- for (i = 1; i <= 15; i++) {
- tca[0] = '\0';
- if ( i == 1) {
- sprintf(tca, "%s/%s", cdir, path);
- } else if (i == 2 && mode > 0) {
- sprintf(tca, "%s/%s.crt", cdir, path);
- } else if (i == 3) {
- sprintf(tca, "%s/%s.pem", cdir, path);
- } else if (i == 4 && mode > 1) {
- sprintf(tca, "%s/%s.req", cdir, path);
- } else if (i == 5 && mode > 1) {
- sprintf(tca, "%s/%s.key", cdir, path);
- } else if (i == 6) {
- sprintf(tca, "%s/clients/%s", cdir, path);
- } else if (i == 7 && mode > 0) {
- sprintf(tca, "%s/clients/%s.crt", cdir, path);
- } else if (i == 8) {
- sprintf(tca, "%s/clients/%s.pem", cdir, path);
- } else if (i == 9 && mode > 1) {
- sprintf(tca, "%s/clients/%s.req", cdir, path);
- } else if (i == 10 && mode > 1) {
- sprintf(tca, "%s/clients/%s.key", cdir, path);
- } else if (i == 11) {
- sprintf(tca, "%s/server-%s", cdir, path);
- } else if (i == 12 && mode > 0) {
- sprintf(tca, "%s/server-%s.crt", cdir, path);
- } else if (i == 13) {
- sprintf(tca, "%s/server-%s.pem", cdir, path);
- } else if (i == 14 && mode > 1) {
- sprintf(tca, "%s/server-%s.req", cdir, path);
- } else if (i == 15 && mode > 1) {
- sprintf(tca, "%s/server-%s.key", cdir, path);
- }
- if (tca[0] == '\0') {
- continue;
- }
- if (stat(tca, &sbuf) == 0) {
- path = tca;
- break;
- }
- }
- }
- }
-
- if (stat(path, &sbuf) != 0) {
- rfbLog("sslEncKey: %s\n", path);
- rfbLogPerror("stat");
- exit(1);
- }
-
- if (! info_only) {
- cert = (char *) malloc(2*(sbuf.st_size + 1024));
- file = fopen(path, "r");
- if (file == NULL) {
- rfbLog("sslEncKey: %s\n", path);
- rfbLogPerror("fopen");
- exit(1);
- }
- incert = 0;
- cert[0] = '\0';
- while (fgets(line, 1024, file) != NULL) {
- if (strstr(line, "-----BEGIN CERTIFICATE-----")
- == line) {
- incert = 1;
- }
- if (incert) {
- if (strlen(cert)+strlen(line) <
- 2 * (size_t) sbuf.st_size) {
- strcat(cert, line);
- }
- }
- if (strstr(line, "-----END CERTIFICATE-----")
- == line) {
- incert = 0;
- }
- }
- fclose(file);
- }
-
- tmp_fd = mkstemp(tmp);
- if (tmp_fd < 0) {
- exit(1);
- }
-
- write(tmp_fd, genCert, strlen(genCert));
- close(tmp_fd);
-
- scr = (char *) malloc(strlen("/bin/sh ") + strlen(tmp) + 1);
- sprintf(scr, "/bin/sh %s", tmp);
-
- set_env("BASE_DIR", "/no/such/dir");
- set_env("OPENSSL", openssl);
- set_env("TYPE", "server");
- if (info_only) {
- set_env("INFO_ONLY", path);
- } else if (delete_only) {
- set_env("DELETE_ONLY", path);
- } else {
- set_env("ENCRYPT_ONLY", path);
- }
- system(scr);
- unlink(tmp);
-
- if (! mode && cert && cert[0] != '\0') {
- int got_cert = 0;
- file = fopen(path, "r");
- if (file == NULL) {
- rfbLog("sslEncKey: %s\n", path);
- rfbLogPerror("fopen");
- exit(1);
- }
- while (fgets(line, 1024, file) != NULL) {
- if (strstr(line, "-----BEGIN CERTIFICATE-----")
- == line) {
- got_cert++;
- }
- if (strstr(line, "-----END CERTIFICATE-----")
- == line) {
- got_cert++;
- }
- }
- fclose(file);
- if (got_cert < 2) {
- file = fopen(path, "a");
- if (file == NULL) {
- rfbLog("sslEncKey: %s\n", path);
- rfbLogPerror("fopen");
- exit(1);
- }
- fprintf(file, "%s", cert);
- fclose(file);
- }
- free(cert);
- }
-
- depth--;
-}
-
diff --git a/x11vnc/sslcmds.h b/x11vnc/sslcmds.h
deleted file mode 100644
index 68a12df..0000000
--- a/x11vnc/sslcmds.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_SSLCMDS_H
-#define _X11VNC_SSLCMDS_H
-
-/* -- sslcmds.h -- */
-
-extern void check_stunnel(void);
-extern int start_stunnel(int stunnel_port, int x11vnc_port, int hport, int x11vnc_hport);
-extern void stop_stunnel(void);
-extern void setup_stunnel(int rport, int *argc, char **argv);
-extern char *get_Cert_dir(char *cdir_in, char **tmp_in);
-extern void sslScripts(void);
-extern void sslGenCA(char *cdir);
-extern void sslGenCert(char *ty, char *nm);
-extern void sslEncKey(char *path, int info_only);
-
-
-#endif /* _X11VNC_SSLCMDS_H */
diff --git a/x11vnc/sslhelper.c b/x11vnc/sslhelper.c
deleted file mode 100644
index 7057615..0000000
--- a/x11vnc/sslhelper.c
+++ /dev/null
@@ -1,4345 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- sslhelper.c -- */
-
-#include "x11vnc.h"
-#include "inet.h"
-#include "cleanup.h"
-#include "screen.h"
-#include "scan.h"
-#include "connections.h"
-#include "sslcmds.h"
-#include "unixpw.h"
-#include "user.h"
-
-#define OPENSSL_INETD 1
-#define OPENSSL_VNC 2
-#define OPENSSL_VNC6 3
-#define OPENSSL_HTTPS 4
-#define OPENSSL_HTTPS6 5
-#define OPENSSL_REVERSE 6
-
-#define DO_DH 0
-
-#if LIBVNCSERVER_HAVE_FORK
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_WAITPID
-#define FORK_OK
-#endif
-#endif
-
-int openssl_sock = -1;
-int openssl_sock6 = -1;
-int openssl_port_num = 0;
-int https_sock = -1;
-int https_sock6 = -1;
-pid_t openssl_last_helper_pid = 0;
-char *openssl_last_ip = NULL;
-
-static char *certret = NULL;
-static int certret_fd = -1;
-static mode_t omode;
-char *certret_str = NULL;
-
-static char *dhret = NULL;
-static int dhret_fd = -1;
-char *dhret_str = NULL;
-char *new_dh_params = NULL;
-
-void raw_xfer(int csock, int s_in, int s_out);
-
-/* openssl(1) pem related functions: */
-char *get_saved_pem(char *string, int create);
-char *find_openssl_bin(void);
-char *get_ssl_verify_file(char *str_in);
-char *create_tmp_pem(char *path, int prompt);
-
-static char *get_input(char *tag, char **in);
-
-char *get_saved_pem(char *save, int create) {
- char *s = NULL, *path, *cdir, *tmp;
- int prompt = 0, len;
- struct stat sbuf;
-
- if (! save) {
- rfbLog("get_saved_pem: save string is null.\n");
- clean_up_exit(1);
- }
-
- if (strstr(save, "SAVE_PROMPT") == save) {
- prompt = 1;
- s = save + strlen("SAVE_PROMPT");
- } else if (strstr(save, "SAVE_NOPROMPT") == save) {
- set_env("GENCERT_NOPROMPT", "1");
- s = save + strlen("SAVE_NOPROMPT");
- } else if (strstr(save, "SAVE") == save) {
- s = save + strlen("SAVE");
- } else {
- rfbLog("get_saved_pem: invalid save string: %s\n", save);
- clean_up_exit(1);
- }
- if (strchr(s, '/')) {
- rfbLog("get_saved_pem: invalid save string: %s\n", s);
- clean_up_exit(1);
- }
-
-
- cdir = get_Cert_dir(NULL, &tmp);
- if (! cdir || ! tmp) {
- rfbLog("get_saved_pem: could not find Cert dir.\n");
- clean_up_exit(1);
- }
-
- len = strlen(cdir) + strlen("/server.pem") + strlen(s) + 1;
-
- path = (char *) malloc(len);
- sprintf(path, "%s/server%s.pem", cdir, s);
-
- if (stat(path, &sbuf) != 0) {
- char *new_name = NULL;
- if (create) {
- if (inetd || opts_bg) {
- set_env("GENCERT_NOPROMPT", "1");
- }
- new_name = create_tmp_pem(path, prompt);
- if (!getenv("X11VNC_SSL_NO_PASSPHRASE") && !inetd && !opts_bg) {
- sslEncKey(new_name, 0);
- }
- }
- return new_name;
- }
-
- if (! quiet) {
- char line[1024];
- int on = 0;
- FILE *in = fopen(path, "r");
- if (in != NULL) {
- rfbLog("\n");
- rfbLog("Using SSL Certificate:\n");
- fprintf(stderr, "\n");
- while (fgets(line, 1024, in) != NULL) {
- if (strstr(line, "BEGIN CERTIFICATE")) {
- on = 1;
- }
- if (on) {
- fprintf(stderr, "%s", line);
- }
- if (strstr(line, "END CERTIFICATE")) {
- on = 0;
- }
- if (strstr(line, "PRIVATE KEY")) {
- on = 0;
- }
- }
- fprintf(stderr, "\n");
- fclose(in);
- }
- }
- return strdup(path);
-}
-
-static char *get_input(char *tag, char **in) {
- char line[1024], *str;
-
- if (! tag || ! in || ! *in) {
- return NULL;
- }
-
- fprintf(stderr, "%s:\n [%s] ", tag, *in);
- if (fgets(line, 1024, stdin) == NULL) {
- rfbLog("could not read stdin!\n");
- rfbLogPerror("fgets");
- clean_up_exit(1);
- }
- if ((str = strrchr(line, '\n')) != NULL) {
- *str = '\0';
- }
- str = lblanks(line);
- if (!strcmp(str, "")) {
- return *in;
- } else {
- return strdup(line);
- }
-}
-
-char *find_openssl_bin(void) {
- char *path, *exe, *p, *gp;
- struct stat sbuf;
- int found_openssl = 0;
- char extra[] = ":/usr/bin:/bin:/usr/sbin:/usr/local/bin"
- ":/usr/local/sbin:/usr/sfw/bin";
-
- gp = getenv("PATH");
- if (! gp) {
- fprintf(stderr, "could not find openssl(1) program in PATH. (null)\n");
- return NULL;
- }
-
- path = (char *) malloc(strlen(gp) + strlen(extra) + 1);
- strcpy(path, gp);
- strcat(path, extra);
-
- /* find openssl binary: */
- exe = (char *) malloc(strlen(path) + strlen("/openssl") + 1);
- p = strtok(path, ":");
-
- while (p) {
- sprintf(exe, "%s/openssl", p);
- if (stat(exe, &sbuf) == 0) {
- if (! S_ISDIR(sbuf.st_mode)) {
- found_openssl = 1;
- break;
- }
- }
- p = strtok(NULL, ":");
- }
- free(path);
-
- if (! found_openssl) {
- fprintf(stderr, "could not find openssl(1) program in PATH.\n");
- fprintf(stderr, "PATH=%s\n", gp);
- fprintf(stderr, "(also checked: %s)\n", extra);
- return NULL;
- }
- return exe;
-}
-
-/* uses /usr/bin/openssl to create a tmp cert */
-
-char *create_tmp_pem(char *pathin, int prompt) {
- pid_t pid, pidw;
- FILE *in, *out;
- char cnf[] = "/tmp/x11vnc-cnf.XXXXXX";
- char pem[] = "/tmp/x11vnc-pem.XXXXXX";
- char str[8*1024], line[1024], *exe;
- int cnf_fd, pem_fd, status, show_cert = 1;
- char *days;
- char *C, *L, *OU, *O, *CN, *EM;
- char tmpl[] =
-"[ req ]\n"
-"prompt = no\n"
-"default_bits = 2048\n"
-"encrypt_key = yes\n"
-"distinguished_name = req_dn\n"
-"x509_extensions = cert_type\n"
-"\n"
-"[ req_dn ]\n"
-"countryName=%s\n"
-"localityName=%s\n"
-"organizationalUnitName=%s\n"
-"organizationName=%s\n"
-"commonName=%s\n"
-"emailAddress=%s\n"
-"\n"
-"[ cert_type ]\n"
-"nsCertType = server\n"
-;
-
- C = strdup("AU");
- L = strdup(UT.sysname ? UT.sysname : "unknown-os");
- snprintf(line, 1024, "%s-%f", UT.nodename ? UT.nodename :
- "unknown-node", dnow());
- line[1024-1] = '\0';
-
- OU = strdup(line);
- O = strdup("x11vnc");
- if (pathin) {
- snprintf(line, 1024, "x11vnc-SELF-SIGNED-CERT-%d", getpid());
- } else {
- snprintf(line, 1024, "x11vnc-SELF-SIGNED-TEMPORARY-CERT-%d",
- getpid());
- }
- line[1024-1] = '\0';
- CN = strdup(line);
- EM = strdup("x11vnc@server.nowhere");
-
- /* ssl */
- if (no_external_cmds || !cmd_ok("ssl")) {
- rfbLog("create_tmp_pem: cannot run external commands.\n");
- return NULL;
- }
-
- rfbLog("\n");
- if (pathin) {
- rfbLog("Creating a self-signed PEM certificate...\n");
- } else {
- rfbLog("Creating a temporary, self-signed PEM certificate...\n");
- }
-
- rfbLog("\n");
- rfbLog("This will NOT prevent Man-In-The-Middle attacks UNLESS you\n");
- rfbLog("get the certificate information to the VNC viewers SSL\n");
- rfbLog("tunnel configuration or you take the extra steps to sign it\n");
- rfbLog("with a CA key. However, it will prevent passive network\n");
- rfbLog("sniffing.\n");
- rfbLog("\n");
- rfbLog("The cert inside -----BEGIN CERTIFICATE-----\n");
- rfbLog(" ....\n");
- rfbLog(" -----END CERTIFICATE-----\n");
- rfbLog("printed below may be used on the VNC viewer-side to\n");
- rfbLog("authenticate this server for this session. See the -ssl\n");
- rfbLog("help output and the FAQ for how to create a permanent\n");
- rfbLog("server certificate.\n");
- rfbLog("\n");
-
- exe = find_openssl_bin();
- if (! exe) {
- return NULL;
- }
-
- /* create template file with our made up stuff: */
- if (prompt) {
- fprintf(stderr, "\nReply to the following prompts to set"
- " your Certificate parameters.\n");
- fprintf(stderr, "(press Enter to accept the default in [...], "
- "or type in the value you want)\n\n");
- C = get_input("CountryName", &C);
- L = get_input("LocalityName", &L);
- OU = get_input("OrganizationalUnitName", &OU);
- O = get_input("OrganizationalName", &O);
- CN = get_input("CommonName", &CN);
- EM = get_input("EmailAddress", &EM);
- }
- sprintf(str, tmpl, C, L, OU, O, CN, EM);
-
- cnf_fd = mkstemp(cnf);
- if (cnf_fd < 0) {
- return NULL;
- }
- pem_fd = mkstemp(pem);
- if (pem_fd < 0) {
- close(cnf_fd);
- return NULL;
- }
-
- close(pem_fd);
-
- write(cnf_fd, str, strlen(str));
- close(cnf_fd);
-
- if (pathin) {
- days = "365";
- } else {
- days = "30";
- }
-
-#ifndef FORK_OK
- rfbLog("not compiled with fork(2)\n");
- clean_up_exit(1);
-#else
- /* make RSA key */
- pid = fork();
- if (pid < 0) {
- return NULL;
- } else if (pid == 0) {
- int i;
- for (i=0; i<256; i++) {
- close(i);
- }
- execlp(exe, exe, "req", "-new", "-x509", "-nodes",
- "-days", days, "-config", cnf, "-out", pem,
- "-keyout", pem, (char *)0);
- exit(1);
- }
- pidw = waitpid(pid, &status, 0);
- if (pidw != pid) {
- return NULL;
- }
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- ;
- } else {
- return NULL;
- }
-
-#if DO_DH
- /* make DH parameters */
- pid = fork();
- if (pid < 0) {
- return NULL;
- } else if (pid == 0) {
- int i;
- for (i=0; i<256; i++) {
- close(i);
- }
- /* rather slow at 1024 */
- execlp(exe, exe, "dhparam", "-out", cnf, "512", (char *)0);
- exit(1);
- }
- pidw = waitpid(pid, &status, 0);
- if (pidw != pid) {
- return NULL;
- }
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- ;
- } else {
- return NULL;
- }
-
- /* append result: */
- in = fopen(cnf, "r");
- if (in == NULL) {
- return NULL;
- }
- out = fopen(pem, "a");
- if (out == NULL) {
- fclose(in);
- return NULL;
- }
- while (fgets(line, 1024, in) != NULL) {
- fprintf(out, "%s", line);
- }
- fclose(in);
- fclose(out);
-#endif
-
-#endif /* FORK_OK */
-
- unlink(cnf);
- free(exe);
-
- if (pathin != NULL) {
- char *q, *pathcrt = strdup(pathin);
- FILE *crt = NULL;
- int on = 0;
-
- q = strrchr(pathcrt, '/');
- if (q) {
- q = strstr(q, ".pem");
- if (q) {
- *(q+1) = 'c';
- *(q+2) = 'r';
- *(q+3) = 't';
- crt = fopen(pathcrt, "w");
- }
- }
- if (crt == NULL) {
- rfbLog("could not open: %s\n", pathcrt);
- rfbLogPerror("fopen");
- return NULL;
- }
-
- out = fopen(pathin, "w");
- chmod(pathin, 0600);
- if (out == NULL) {
- rfbLog("could not open: %s\n", pathin);
- rfbLogPerror("fopen");
- fclose(crt);
- return NULL;
- }
-
- in = fopen(pem, "r");
- if (in == NULL) {
- rfbLog("could not open: %s\n", pem);
- rfbLogPerror("fopen");
- fclose(out);
- fclose(crt);
- unlink(pathin);
- unlink(pathcrt);
- return NULL;
- }
- while (fgets(line, 1024, in) != NULL) {
- if (strstr(line, "BEGIN CERTIFICATE")) {
- on = 1;
- }
- fprintf(out, "%s", line);
- if (on) {
- fprintf(crt, "%s", line);
- if (!quiet) {
- fprintf(stderr, "%s", line);
- }
- }
- if (strstr(line, "END CERTIFICATE")) {
- on = 0;
- }
- if (strstr(line, "PRIVATE KEY")) {
- on = 0;
- }
- }
- fclose(in);
- fclose(out);
- fclose(crt);
- }
-
- if (show_cert) {
- exe = find_openssl_bin();
- if (!exe) {
- exe = strdup("openssl");
- }
- if (strlen(pem) + strlen(exe) < 4000) {
- char cmd[5000];
- if (inetd) {
- sprintf(cmd, "%s x509 -text -in '%s' 1>&2", exe, pem);
- } else {
- sprintf(cmd, "%s x509 -text -in '%s'", exe, pem);
- }
- fprintf(stderr, "\n");
- system(cmd);
- fprintf(stderr, "\n");
- }
- free(exe);
- }
-
- if (pathin) {
- unlink(pem);
- return strdup(pathin);
- } else {
- return strdup(pem);
- }
-}
-
-static int appendfile(FILE *out, char *infile) {
- char line[1024];
- FILE *in;
-
- if (! infile) {
- rfbLog("appendfile: null infile.\n");
- return 0;
- }
- if (! out) {
- rfbLog("appendfile: null out handle.\n");
- return 0;
- }
-
- in = fopen(infile, "r");
-
- if (in == NULL) {
- rfbLog("appendfile: %s\n", infile);
- rfbLogPerror("fopen");
- return 0;
- }
-
- while (fgets(line, 1024, in) != NULL) {
- fprintf(out, "%s", line);
- }
- fclose(in);
- return 1;
-}
-
-char *get_ssl_verify_file(char *str_in) {
- char *p, *str, *cdir, *tmp;
- char *tfile, *tfile2;
- FILE *file;
- struct stat sbuf;
- int count = 0, fd;
-
- if (! str_in) {
- rfbLog("get_ssl_verify_file: no filename\n");
- exit(1);
- }
-
- if (stat(str_in, &sbuf) == 0) {
- /* assume he knows what he is doing. */
- return str_in;
- }
-
- cdir = get_Cert_dir(NULL, &tmp);
- if (! cdir || ! tmp) {
- rfbLog("get_ssl_verify_file: invalid cert-dir.\n");
- exit(1);
- }
-
- tfile = (char *) malloc(strlen(tmp) + 1024);
- tfile2 = (char *) malloc(strlen(tmp) + 1024);
-
- sprintf(tfile, "%s/sslverify-tmp-load-%d.crts.XXXXXX", tmp, getpid());
-
- fd = mkstemp(tfile);
- if (fd < 0) {
- rfbLog("get_ssl_verify_file: %s\n", tfile);
- rfbLogPerror("mkstemp");
- exit(1);
- }
- close(fd);
-
- file = fopen(tfile, "w");
- chmod(tfile, 0600);
- if (file == NULL) {
- rfbLog("get_ssl_verify_file: %s\n", tfile);
- rfbLogPerror("fopen");
- exit(1);
- }
-
- str = strdup(str_in);
- p = strtok(str, ",");
-
- while (p) {
- if (!strcmp(p, "CA")) {
- sprintf(tfile2, "%s/CA/cacert.pem", cdir);
- if (! appendfile(file, tfile2)) {
- unlink(tfile);
- exit(1);
- }
- rfbLog("sslverify: loaded %s\n", tfile2);
- count++;
-
- } else if (!strcmp(p, "clients")) {
- DIR *dir;
- struct dirent *dp;
-
- sprintf(tfile2, "%s/clients", cdir);
- dir = opendir(tfile2);
- if (! dir) {
- rfbLog("get_ssl_verify_file: %s\n", tfile2);
- rfbLogPerror("opendir");
- unlink(tfile);
- exit(1);
- }
- while ( (dp = readdir(dir)) != NULL) {
- char *n = dp->d_name;
- char *q = strstr(n, ".crt");
-
- if (! q || strlen(q) != strlen(".crt")) {
- continue;
- }
- if (strlen(n) > 512) {
- continue;
- }
-
- sprintf(tfile2, "%s/clients/%s", cdir, n);
- if (! appendfile(file, tfile2)) {
- unlink(tfile);
- exit(1);
- }
- rfbLog("sslverify: loaded %s\n",
- tfile2);
- count++;
- }
- closedir(dir);
-
- } else {
- if (strlen(p) > 512) {
- unlink(tfile);
- exit(1);
- }
- sprintf(tfile2, "%s/clients/%s.crt", cdir, p);
- if (stat(tfile2, &sbuf) != 0) {
- sprintf(tfile2, "%s/clients/%s", cdir, p);
- }
- if (! appendfile(file, tfile2)) {
- unlink(tfile);
- exit(1);
- }
- rfbLog("sslverify: loaded %s\n", tfile2);
- count++;
- }
- p = strtok(NULL, ",");
- }
- fclose(file);
- free(tfile2);
- free(str);
-
- rfbLog("sslverify: using %d client certs in\n", count);
- rfbLog("sslverify: %s\n", tfile);
-
- return tfile;
-}
-
-int openssl_present(void);
-void openssl_init(int isclient);
-void openssl_port(int restart);
-void https_port(int restart);
-void check_openssl(void);
-void check_https(void);
-void ssl_helper_pid(pid_t pid, int sock);
-void accept_openssl(int mode, int presock);
-
-static void lose_ram(void);
-#define ABSIZE 16384
-
-static int vencrypt_selected = 0;
-static int anontls_selected = 0;
-
-/* to test no openssl libssl */
-#if 0
-#undef LIBVNCSERVER_HAVE_LIBSSL
-#define LIBVNCSERVER_HAVE_LIBSSL 0
-#endif
-
-#if !LIBVNCSERVER_HAVE_LIBSSL
-
-static void badnews(char *name) {
- use_openssl = 0;
- use_stunnel = 0;
- rfbLog("** %s: not compiled with libssl OpenSSL support **\n", name ? name : "???");
- clean_up_exit(1);
-}
-
-int openssl_present(void) {return 0;}
-void openssl_init(int isclient) {badnews("openssl_init");}
-
-#define SSL_ERROR_NONE 0
-
-static int ssl_init(int s_in, int s_out, int skip_vnc_tls, double last_https) {
- if (enc_str != NULL) {
- return 1;
- }
- badnews("ssl_init");
- return 0;
-}
-
-static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
- if (enc_str != NULL && !strcmp(enc_str, "none")) {
- usleep(250*1000);
- rfbLog("doing '-enc none' raw transfer (no encryption)\n");
- raw_xfer(csock, s_in, s_out);
- } else {
- badnews("ssl_xfer");
- }
-}
-
-#else /* LIBVNCSERVER_HAVE_LIBSSL */
-
-/*
- * This is because on older systems both zlib.h and ssl.h define
- * 'free_func' nothing we do below (currently) induces an external
- * dependency on 'free_func'.
- */
-#define free_func my_jolly_little_free_func
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-
-static SSL_CTX *ctx = NULL;
-static RSA *rsa_512 = NULL;
-static RSA *rsa_1024 = NULL;
-static SSL *ssl = NULL;
-static X509_STORE *revocation_store = NULL;
-
-
-static void init_prng(void);
-static void sslerrexit(void);
-static int ssl_init(int s_in, int s_out, int skip_vnc_tls, double last_https);
-static void ssl_xfer(int csock, int s_in, int s_out, int is_https);
-
-#ifndef FORK_OK
-void openssl_init(int isclient) {
- rfbLog("openssl_init: fork is not supported. cannot create"
- " ssl helper process.\n");
- clean_up_exit(1);
-}
-int openssl_present(void) {return 0;}
-
-#else
-
-int openssl_present(void) {return 1;}
-
-static void sslerrexit(void) {
- unsigned long err = ERR_get_error();
-
- if (err) {
- char str[256];
- ERR_error_string(err, str);
- fprintf(stderr, "ssl error: %s\n", str);
- }
- clean_up_exit(1);
-}
-
-static int pem_passwd_callback(char *buf, int size, int rwflag,
- void *userdata) {
- char *q, line[1024];
-
- if (! buf) {
- exit(1);
- }
-
- fprintf(stderr, "\nA passphrase is needed to unlock an OpenSSL "
- "private key (PEM file).\n");
- fprintf(stderr, "Enter passphrase> ");
- system("stty -echo");
- if(fgets(line, 1024, stdin) == NULL) {
- fprintf(stdout, "\n");
- system("stty echo");
- exit(1);
- }
- system("stty echo");
- fprintf(stdout, "\n\n");
- q = strrchr(line, '\n');
- if (q) {
- *q = '\0';
- }
- line[1024 - 1] = '\0';
- strncpy(buf, line, size);
- buf[size - 1] = '\0';
-
- if (0) rwflag = 0; /* compiler warning. */
- if (0) userdata = 0; /* compiler warning. */
-
- return strlen(buf);
-}
-
-/* based on mod_ssl */
-static int crl_callback(X509_STORE_CTX *callback_ctx) {
- X509_STORE_CTX store_ctx;
- X509_OBJECT obj;
- X509_NAME *subject;
- X509_NAME *issuer;
- X509 *xs;
- X509_CRL *crl;
- X509_REVOKED *revoked;
- EVP_PKEY *pubkey;
- long serial;
- BIO *bio;
- int i, n, rc;
- char *cp, *cp2;
- ASN1_TIME *t;
-
- /* Determine certificate ingredients in advance */
- xs = X509_STORE_CTX_get_current_cert(callback_ctx);
- subject = X509_get_subject_name(xs);
- issuer = X509_get_issuer_name(xs);
-
- /* Try to retrieve a CRL corresponding to the _subject_ of
- * the current certificate in order to verify it's integrity. */
- memset((char *)&obj, 0, sizeof(obj));
- X509_STORE_CTX_init(&store_ctx, revocation_store, NULL, NULL);
- rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj);
- X509_STORE_CTX_cleanup(&store_ctx);
- crl=obj.data.crl;
-
- if(rc>0 && crl) {
- /* Log information about CRL
- * (A little bit complicated because of ASN.1 and BIOs...) */
- bio=BIO_new(BIO_s_mem());
- BIO_printf(bio, "lastUpdate: ");
- ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl));
- BIO_printf(bio, ", nextUpdate: ");
- ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl));
- n=BIO_pending(bio);
- cp=malloc(n+1);
- n=BIO_read(bio, cp, n);
- cp[n]='\0';
- BIO_free(bio);
- cp2=X509_NAME_oneline(subject, NULL, 0);
- rfbLog("CA CRL: Issuer: %s, %s\n", cp2, cp);
- OPENSSL_free(cp2);
- free(cp);
-
- /* Verify the signature on this CRL */
- pubkey=X509_get_pubkey(xs);
- if(X509_CRL_verify(crl, pubkey)<=0) {
- rfbLog("Invalid signature on CRL\n");
- X509_STORE_CTX_set_error(callback_ctx,
- X509_V_ERR_CRL_SIGNATURE_FAILURE);
- X509_OBJECT_free_contents(&obj);
- if(pubkey)
- EVP_PKEY_free(pubkey);
- return 0; /* Reject connection */
- }
- if(pubkey)
- EVP_PKEY_free(pubkey);
-
- /* Check date of CRL to make sure it's not expired */
- t=X509_CRL_get_nextUpdate(crl);
- if(!t) {
- rfbLog("Found CRL has invalid nextUpdate field\n");
- X509_STORE_CTX_set_error(callback_ctx,
- X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
- X509_OBJECT_free_contents(&obj);
- return 0; /* Reject connection */
- }
- if(X509_cmp_current_time(t)<0) {
- rfbLog("Found CRL is expired - "
- "revoking all certificates until you get updated CRL\n");
- X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
- X509_OBJECT_free_contents(&obj);
- return 0; /* Reject connection */
- }
- X509_OBJECT_free_contents(&obj);
- }
-
- /* Try to retrieve a CRL corresponding to the _issuer_ of
- * the current certificate in order to check for revocation. */
- memset((char *)&obj, 0, sizeof(obj));
- X509_STORE_CTX_init(&store_ctx, revocation_store, NULL, NULL);
- rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj);
- X509_STORE_CTX_cleanup(&store_ctx);
- crl=obj.data.crl;
-
- if(rc>0 && crl) {
- /* Check if the current certificate is revoked by this CRL */
- n=sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
- for(i=0; i<n; i++) {
- revoked=sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
- if(ASN1_INTEGER_cmp(revoked->serialNumber,
- X509_get_serialNumber(xs)) == 0) {
- serial=ASN1_INTEGER_get(revoked->serialNumber);
- cp=X509_NAME_oneline(issuer, NULL, 0);
- rfbLog("Certificate with serial %ld (0x%lX) "
- "revoked per CRL from issuer %s\n", serial, serial, cp);
- OPENSSL_free(cp);
- X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REVOKED);
- X509_OBJECT_free_contents(&obj);
- return 0; /* Reject connection */
- }
- }
- X509_OBJECT_free_contents(&obj);
- }
-
- return 1; /* Accept connection */
-}
-
-static int verify_callback(int ok, X509_STORE_CTX *callback_ctx) {
- if (!ssl_verify) {
- rfbLog("CRL_check: skipped.\n");
- return ok;
- }
- if (!ssl_crl) {
- rfbLog("CRL_check: skipped.\n");
- return ok;
- }
- if (!ok) {
- rfbLog("CRL_check: client cert is already rejected.\n");
- return ok;
- }
- if (revocation_store) {
- if (crl_callback(callback_ctx)) {
- rfbLog("CRL_check: succeeded.\n");
- return 1;
- } else {
- rfbLog("CRL_check: did not pass.\n");
- return 0;
- }
- }
- /* NOTREACHED */
- return 1;
-}
-
-#define rfbSecTypeAnonTls 18
-#define rfbSecTypeVencrypt 19
-
-#define rfbVencryptPlain 256
-#define rfbVencryptTlsNone 257
-#define rfbVencryptTlsVnc 258
-#define rfbVencryptTlsPlain 259
-#define rfbVencryptX509None 260
-#define rfbVencryptX509Vnc 261
-#define rfbVencryptX509Plain 262
-
-static int ssl_client_mode = 0;
-
-static int switch_to_anon_dh(void);
-
-void openssl_init(int isclient) {
- int db = 0, tmp_pem = 0, do_dh;
- FILE *in;
- double ds;
- long mode;
- static int first = 1;
-
- do_dh = DO_DH;
-
- if (enc_str != NULL) {
- if (first) {
- init_prng();
- }
- first = 0;
- return;
- }
-
- if (! quiet) {
- rfbLog("\n");
- rfbLog("Initializing SSL (%s connect mode).\n", isclient ? "client":"server");
- }
- if (first) {
- if (db) fprintf(stderr, "\nSSL_load_error_strings()\n");
-
- SSL_load_error_strings();
-
- if (db) fprintf(stderr, "SSL_library_init()\n");
-
- SSL_library_init();
-
- if (db) fprintf(stderr, "init_prng()\n");
-
- init_prng();
-
- first = 0;
- }
-
- if (isclient) {
- ssl_client_mode = 1;
- } else {
- ssl_client_mode = 0;
- }
-
- if (ssl_client_mode) {
- if (db) fprintf(stderr, "SSLv23_client_method()\n");
- ctx = SSL_CTX_new( SSLv23_client_method() );
- } else {
- if (db) fprintf(stderr, "SSLv23_server_method()\n");
- ctx = SSL_CTX_new( SSLv23_server_method() );
- }
-
- if (ctx == NULL) {
- rfbLog("openssl_init: SSL_CTX_new failed.\n");
- sslerrexit();
- }
-
- ds = dnow();
- rsa_512 = RSA_generate_key(512, RSA_F4, NULL, NULL);
- if (rsa_512 == NULL) {
- rfbLog("openssl_init: RSA_generate_key(512) failed.\n");
- sslerrexit();
- }
-
- rfbLog("created 512 bit temporary RSA key: %.3fs\n", dnow() - ds);
-
- ds = dnow();
- rsa_1024 = RSA_generate_key(1024, RSA_F4, NULL, NULL);
- if (rsa_1024 == NULL) {
- rfbLog("openssl_init: RSA_generate_key(1024) failed.\n");
- sslerrexit();
- }
-
- rfbLog("created 1024 bit temporary RSA key: %.3fs\n", dnow() - ds);
-
- if (db) fprintf(stderr, "SSL_CTX_set_tmp_rsa()\n");
-
- if (! SSL_CTX_set_tmp_rsa(ctx, rsa_1024)) {
- rfbLog("openssl_init: SSL_CTX_set_tmp_rsa(1024) failed.\n");
- sslerrexit();
- }
-
- mode = 0;
- mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
- mode |= SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
- SSL_CTX_set_mode(ctx, mode);
-
-#define ssl_cache 0
-#if ssl_cache
- SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
- SSL_CTX_set_timeout(ctx, 300);
-#else
- SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
- SSL_CTX_set_timeout(ctx, 1);
-#endif
-
- ds = dnow();
- if (! openssl_pem) {
- openssl_pem = create_tmp_pem(NULL, 0);
- if (! openssl_pem) {
- rfbLog("openssl_init: could not create temporary,"
- " self-signed PEM.\n");
- clean_up_exit(1);
- }
- tmp_pem = 1;
-
- } else if (!strcmp(openssl_pem, "ANON")) {
- if (ssl_verify) {
- rfbLog("openssl_init: Anonymous Diffie-Hellman cannot"
- " be used in -sslverify mode.\n");
- clean_up_exit(1);
- }
- if (ssl_crl) {
- rfbLog("openssl_init: Anonymous Diffie-Hellman cannot"
- " 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");
- clean_up_exit(1);
- }
- } else if (strstr(openssl_pem, "SAVE") == openssl_pem) {
- openssl_pem = get_saved_pem(openssl_pem, 1);
- if (! openssl_pem) {
- rfbLog("openssl_init: could not create or open"
- " saved PEM: %s\n", openssl_pem);
- clean_up_exit(1);
- }
- tmp_pem = 0;
- }
-
- rfbLog("using PEM %s %.3fs\n", openssl_pem, dnow() - ds);
-
- SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_callback);
-
- if (do_dh) {
- DH *dh;
- BIO *bio;
-
- ds = dnow();
- in = fopen(openssl_pem, "r");
- if (in == NULL) {
- rfbLogPerror("fopen");
- clean_up_exit(1);
- }
- bio = BIO_new_fp(in, BIO_CLOSE|BIO_FP_TEXT);
- if (! bio) {
- rfbLog("openssl_init: BIO_new_fp() failed.\n");
- sslerrexit();
- }
- dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
- if (dh == NULL) {
- rfbLog("openssl_init: PEM_read_bio_DHparams() failed.\n");
- BIO_free(bio);
- sslerrexit();
- }
- BIO_free(bio);
- SSL_CTX_set_tmp_dh(ctx, dh);
- rfbLog("loaded Diffie Hellman %d bits, %.3fs\n",
- 8*DH_size(dh), dnow()-ds);
- DH_free(dh);
- }
-
- if (strcmp(openssl_pem, "ANON")) {
- if (! SSL_CTX_use_certificate_chain_file(ctx, openssl_pem)) {
- rfbLog("openssl_init: SSL_CTX_use_certificate_chain_file() failed.\n");
- sslerrexit();
- }
- if (! SSL_CTX_use_RSAPrivateKey_file(ctx, openssl_pem,
- SSL_FILETYPE_PEM)) {
- rfbLog("openssl_init: SSL_CTX_set_tmp_rsa(1024) failed.\n");
- sslerrexit();
- }
- if (! SSL_CTX_check_private_key(ctx)) {
- rfbLog("openssl_init: SSL_CTX_set_tmp_rsa(1024) failed.\n");
- sslerrexit();
- }
- }
-
- if (tmp_pem && ! getenv("X11VNC_KEEP_TMP_PEM")) {
- if (getenv("X11VNC_SHOW_TMP_PEM")) {
- FILE *in = fopen(openssl_pem, "r");
- if (in != NULL) {
- char line[128];
- fprintf(stderr, "\n");
- while (fgets(line, 128, in) != NULL) {
- fprintf(stderr, "%s", line);
- }
- fprintf(stderr, "\n");
- fclose(in);
- }
- }
- unlink(openssl_pem);
- free(openssl_pem);
- openssl_pem = NULL;
- }
-
- if (ssl_crl) {
- struct stat sbuf;
- X509_LOOKUP *lookup;
-
- if (stat(ssl_crl, &sbuf) != 0) {
- rfbLog("openssl_init: -sslCRL does not exist %s.\n",
- ssl_crl ? ssl_crl : "null");
- rfbLogPerror("stat");
- clean_up_exit(1);
- }
-
- revocation_store = X509_STORE_new();
- if (!revocation_store) {
- rfbLog("openssl_init: X509_STORE_new failed.\n");
- sslerrexit();
- }
- if (! S_ISDIR(sbuf.st_mode)) {
- lookup = X509_STORE_add_lookup(revocation_store, X509_LOOKUP_file());
- if (!lookup) {
- rfbLog("openssl_init: X509_STORE_add_lookup failed.\n");
- sslerrexit();
- }
- if (!X509_LOOKUP_load_file(lookup, ssl_crl, X509_FILETYPE_PEM)) {
- rfbLog("openssl_init: X509_LOOKUP_load_file failed.\n");
- sslerrexit();
- }
- } else {
- lookup = X509_STORE_add_lookup(revocation_store, X509_LOOKUP_hash_dir());
- if (!lookup) {
- rfbLog("openssl_init: X509_STORE_add_lookup failed.\n");
- sslerrexit();
- }
- if (!X509_LOOKUP_add_dir(lookup, ssl_crl, X509_FILETYPE_PEM)) {
- rfbLog("openssl_init: X509_LOOKUP_add_dir failed.\n");
- sslerrexit();
- }
- }
- rfbLog("loaded CRL file: %s\n", ssl_crl);
- }
-
- if (ssl_verify) {
- struct stat sbuf;
- char *file;
- int lvl;
-
- file = get_ssl_verify_file(ssl_verify);
-
- if (!file || stat(file, &sbuf) != 0) {
- rfbLog("openssl_init: -sslverify does not exist %s.\n",
- file ? file : "null");
- rfbLogPerror("stat");
- clean_up_exit(1);
- }
- if (! S_ISDIR(sbuf.st_mode)) {
- if (! SSL_CTX_load_verify_locations(ctx, file, NULL)) {
- rfbLog("openssl_init: SSL_CTX_load_verify_"
- "locations() failed.\n");
- sslerrexit();
- }
- } else {
- if (! SSL_CTX_load_verify_locations(ctx, NULL, file)) {
- rfbLog("openssl_init: SSL_CTX_load_verify_"
- "locations() failed.\n");
- sslerrexit();
- }
- }
-
- lvl = SSL_VERIFY_FAIL_IF_NO_PEER_CERT|SSL_VERIFY_PEER;
- if (ssl_crl == NULL) {
- SSL_CTX_set_verify(ctx, lvl, NULL);
- } else {
- SSL_CTX_set_verify(ctx, lvl, verify_callback);
- }
- if (strstr(file, "/sslverify-tmp-load-")) {
- /* temporary file */
- unlink(file);
- }
- } else {
- SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
- }
-
- rfbLog("\n");
-}
-
-static int read_exact(int sock, char *buf, int len) {
- int n, fail = 0;
- if (sock < 0) {
- return 0;
- }
- while (len > 0) {
- n = read(sock, buf, len);
- if (n > 0) {
- buf += n;
- len -= n;
- } else if (n == 0) {
- fail = 1;
- break;
- } else if (n < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
- usleep(10*1000);
- } else if (n < 0 && errno != EINTR) {
- fail = 1;
- break;
- }
- }
- if (fail) {
- return 0;
- } else {
- return 1;
- }
-}
-
-static int write_exact(int sock, char *buf, int len) {
- int n, fail = 0;
- if (sock < 0) {
- return 0;
- }
- while (len > 0) {
- n = write(sock, buf, len);
- if (n > 0) {
- buf += n;
- len -= n;
- } else if (n == 0) {
- fail = 1;
- break;
- } else if (n < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
- usleep(10*1000);
- } else if (n < 0 && errno != EINTR) {
- fail = 1;
- break;
- }
- }
- if (fail) {
- return 0;
- } else {
- return 1;
- }
-}
-
-/* XXX not in rfb.h: */
-void rfbClientSendString(rfbClientPtr cl, char *reason);
-
-static int finish_auth(rfbClientPtr client, char *type) {
- int security_result, ret;
-
- ret = 0;
-
-if (getenv("X11VNC_DEBUG_TLSPLAIN")) fprintf(stderr, "finish_auth type=%s\n", type);
-
- if (!strcmp(type, "None")) {
- security_result = 0; /* success */
- if (write_exact(client->sock, (char *) &security_result, 4)) {
- ret = 1;
- }
- rfbLog("finish_auth: using auth 'None'\n");
- client->state = RFB_INITIALISATION;
-
- } else if (!strcmp(type, "Vnc")) {
- RAND_bytes(client->authChallenge, CHALLENGESIZE);
- if (write_exact(client->sock, (char *) &client->authChallenge, CHALLENGESIZE)) {
- ret = 1;
- }
- rfbLog("finish_auth: using auth 'Vnc', sent challenge.\n");
- client->state = RFB_AUTHENTICATION;
-
- } else if (!strcmp(type, "Plain")) {
- if (!unixpw) {
- rfbLog("finish_auth: *Plain not allowed outside unixpw mode.\n");
- ret = 0;
- } else {
- char *un, *pw;
- int unlen, pwlen;
-
-if (getenv("X11VNC_DEBUG_TLSPLAIN")) fprintf(stderr, "*Plain begin: onHold=%d client=%p unixpw_client=%p\n", client->onHold, (void *) client, (void *) unixpw_client);
-
- if (!read_exact(client->sock, (char *)&unlen, 4)) goto fail;
- unlen = Swap32IfLE(unlen);
-
-if (getenv("X11VNC_DEBUG_TLSPLAIN")) fprintf(stderr, "unlen: %d\n", unlen);
-
- if (!read_exact(client->sock, (char *)&pwlen, 4)) goto fail;
- pwlen = Swap32IfLE(pwlen);
-
-if (getenv("X11VNC_DEBUG_TLSPLAIN")) fprintf(stderr, "pwlen: %d\n", pwlen);
-
- un = (char *) malloc(unlen+1);
- memset(un, 0, unlen+1);
-
- pw = (char *) malloc(pwlen+2);
- memset(pw, 0, pwlen+2);
-
- if (!read_exact(client->sock, un, unlen)) goto fail;
- if (!read_exact(client->sock, pw, pwlen)) goto fail;
-
-if (getenv("X11VNC_DEBUG_TLSPLAIN")) fprintf(stderr, "*Plain: %d %d '%s' ... \n", unlen, pwlen, un);
- strcat(pw, "\n");
-
- if (unixpw_verify(un, pw)) {
- security_result = 0; /* success */
- if (write_exact(client->sock, (char *) &security_result, 4)) {
- ret = 1;
- unixpw_verify_screen(un, pw);
- }
- client->onHold = FALSE;
- client->state = RFB_INITIALISATION;
- }
- if (ret == 0) {
- rfbClientSendString(client, "unixpw failed");
- }
-
- memset(un, 0, unlen+1);
- memset(pw, 0, pwlen+2);
- free(un);
- free(pw);
- }
- } else {
- rfbLog("finish_auth: unknown sub-type: %s\n", type);
- ret = 0;
- }
-
- fail:
- return ret;
-}
-
-static int finish_vencrypt_auth(rfbClientPtr client, int subtype) {
-
- if (subtype == rfbVencryptTlsNone || subtype == rfbVencryptX509None) {
- return finish_auth(client, "None");
- } else if (subtype == rfbVencryptTlsVnc || subtype == rfbVencryptX509Vnc) {
- return finish_auth(client, "Vnc");
- } else if (subtype == rfbVencryptTlsPlain || subtype == rfbVencryptX509Plain) {
- return finish_auth(client, "Plain");
- } else {
- rfbLog("finish_vencrypt_auth: unknown sub-type: %d\n", subtype);
- return 0;
- }
-}
-
-
-static int add_anon_dh(void) {
- pid_t pid, pidw;
- char cnf[] = "/tmp/x11vnc-dh.XXXXXX";
- char *infile = NULL;
- int status, cnf_fd;
- DH *dh;
- BIO *bio;
- FILE *in;
- double ds;
- /*
- * These are dh parameters (prime, generator), not dh keys.
- * Evidently it is ok for them to be publicly known.
- * openssl dhparam -out dh.out 1024
- */
- char *fixed_dh_params =
-"-----BEGIN DH PARAMETERS-----\n"
-"MIGHAoGBAL28w69ZnLYBvp8R2OeqtAIms+oatY19iBL4WhGI/7H1OMmkJjIe+OHs\n"
-"PXoJfe5ucrnvno7Xm+HJZYa1jnPGQuWoa/VJKXdVjYdJVNzazJKM2daKKcQA4GDc\n"
-"msFS5DxLbzUR5jy1n12K3EcbvpyFqDYVTJJXm7NuNuiWRfz3wTozAgEC\n"
-"-----END DH PARAMETERS-----\n";
-
- if (dhparams_file != NULL) {
- infile = dhparams_file;
- rfbLog("add_anon_dh: using %s\n", dhparams_file);
- goto readin;
- }
-
- cnf_fd = mkstemp(cnf);
- if (cnf_fd < 0) {
- return 0;
- }
- infile = cnf;
-
- if (create_fresh_dhparams) {
-
- if (new_dh_params != NULL) {
- write(cnf_fd, new_dh_params, strlen(new_dh_params));
- close(cnf_fd);
- } else {
- char *exe = find_openssl_bin();
- struct stat sbuf;
-
- if (no_external_cmds || !cmd_ok("ssl")) {
- rfbLog("add_anon_dh: cannot run external commands.\n");
- return 0;
- }
-
- close(cnf_fd);
- if (exe == NULL) {
- return 0;
- }
- ds = dnow();
- pid = fork();
- if (pid < 0) {
- return 0;
- } else if (pid == 0) {
- int i;
- for (i=0; i<256; i++) {
- if (i == 2) continue;
- close(i);
- }
- /* rather slow at 1024 */
- execlp(exe, exe, "dhparam", "-out", cnf, "1024", (char *)0);
- exit(1);
- }
- pidw = waitpid(pid, &status, 0);
- if (pidw != pid) {
- return 0;
- }
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- ;
- } else {
- return 0;
- }
- rfbLog("add_anon_dh: created new DH params in %.3f secs\n", dnow() - ds);
-
- if (stat(cnf, &sbuf) == 0 && sbuf.st_size > 0) {
- /* save it to reuse during our process's lifetime: */
- int d = open(cnf, O_RDONLY);
- if (d >= 0) {
- int n, len = sbuf.st_size;
- new_dh_params = (char *) calloc(len+1, 1);
- n = read(d, new_dh_params, len);
- close(d);
- if (n != len) {
- free(new_dh_params);
- new_dh_params = NULL;
- } else if (dhret != NULL) {
- d = open(dhret, O_WRONLY);
- if (d >= 0) {
- write(d, new_dh_params, strlen(new_dh_params));
- close(d);
- }
- }
- }
- }
- }
- } else {
- write(cnf_fd, fixed_dh_params, strlen(fixed_dh_params));
- close(cnf_fd);
- }
-
- readin:
-
- ds = dnow();
- in = fopen(infile, "r");
-
- if (in == NULL) {
- rfbLogPerror("fopen");
- unlink(cnf);
- return 0;
- }
- bio = BIO_new_fp(in, BIO_CLOSE|BIO_FP_TEXT);
- if (! bio) {
- rfbLog("openssl_init: BIO_new_fp() failed.\n");
- unlink(cnf);
- return 0;
- }
- dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
- if (dh == NULL) {
- rfbLog("openssl_init: PEM_read_bio_DHparams() failed.\n");
- unlink(cnf);
- BIO_free(bio);
- return 0;
- }
- BIO_free(bio);
- SSL_CTX_set_tmp_dh(ctx, dh);
- rfbLog("loaded Diffie Hellman %d bits, %.3fs\n", 8*DH_size(dh), dnow()-ds);
- DH_free(dh);
-
- unlink(cnf);
- return 1;
-}
-
-static int switch_to_anon_dh(void) {
- long mode;
-
- 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");
- 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;
- }
- if (!add_anon_dh()) {
- return 0;
- }
-
- mode = 0;
- mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
- mode |= SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
- SSL_CTX_set_mode(ctx, mode);
-
- SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
- SSL_CTX_set_timeout(ctx, 300);
- SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_callback);
- SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
-
- return 1;
-}
-
-static int anontls_dialog(int s_in, int s_out) {
-
- if (s_in || s_out) {}
- anontls_selected = 1;
-
- if (!switch_to_anon_dh()) {
- rfbLog("anontls: Anonymous Diffie-Hellman failed.\n");
- return 0;
- }
-
- /* continue with SSL/TLS */
- return 1;
-}
-
-/*
- * Using spec:
- * http://www.mail-archive.com/qemu-devel@nongnu.org/msg08681.html
- */
-static int vencrypt_dialog(int s_in, int s_out) {
- char buf[256], buf2[256];
- int subtypes[16];
- int n, i, ival, ok, nsubtypes = 0;
-
- vencrypt_selected = 0;
-
- /* send version 0.2 */
- buf[0] = 0;
- buf[1] = 2;
-
- if (!write_exact(s_out, buf, 2)) {
- close(s_in); close(s_out);
- return 0;
- }
-
- /* read client version 0.2 */
- memset(buf, 0, sizeof(buf));
- if (!read_exact(s_in, buf, 2)) {
- close(s_in); close(s_out);
- return 0;
- }
- rfbLog("vencrypt: received %d.%d client version.\n", (int) buf[0], (int) buf[1]);
-
- /* close 0.0 */
- if (buf[0] == 0 && buf[1] == 0) {
- rfbLog("vencrypt: received 0.0 version, closing connection.\n");
- close(s_in); close(s_out);
- return 0;
- }
-
- /* accept only 0.2 */
- if (buf[0] != 0 || buf[1] != 2) {
- rfbLog("vencrypt: unsupported VeNCrypt version, closing connection.\n");
- buf[0] = (char) 255;
- write_exact(s_out, buf, 1);
- close(s_in); close(s_out);
- return 0;
- }
-
- /* tell them OK */
- buf[0] = 0;
- if (!write_exact(s_out, buf, 1)) {
- close(s_in); close(s_out);
- return 0;
- }
-
- if (getenv("X11VNC_ENABLE_VENCRYPT_PLAIN_LOGIN")) {
- vencrypt_enable_plain_login = atoi(getenv("X11VNC_ENABLE_VENCRYPT_PLAIN_LOGIN"));
- }
-
- /* load our list of sub-types: */
- n = 0;
- if (!ssl_verify && vencrypt_kx != VENCRYPT_NODH) {
- if (screen->authPasswdData != NULL) {
- subtypes[n++] = rfbVencryptTlsVnc;
- } else {
- if (vencrypt_enable_plain_login && unixpw) {
- subtypes[n++] = rfbVencryptTlsPlain;
- } else {
- subtypes[n++] = rfbVencryptTlsNone;
- }
- }
- }
- if (vencrypt_kx != VENCRYPT_NOX509) {
- if (screen->authPasswdData != NULL) {
- subtypes[n++] = rfbVencryptX509Vnc;
- } else {
- if (vencrypt_enable_plain_login && unixpw) {
- subtypes[n++] = rfbVencryptX509Plain;
- } else {
- subtypes[n++] = rfbVencryptX509None;
- }
- }
- }
-
- nsubtypes = n;
- for (i = 0; i < nsubtypes; i++) {
- ((uint32_t *)buf)[i] = Swap32IfLE(subtypes[i]);
- }
-
- /* send number first: */
- buf2[0] = (char) nsubtypes;
- if (!write_exact(s_out, buf2, 1)) {
- close(s_in); close(s_out);
- return 0;
- }
- /* and now the list: */
- if (!write_exact(s_out, buf, 4*n)) {
- close(s_in); close(s_out);
- return 0;
- }
-
- /* read client's selection: */
- if (!read_exact(s_in, (char *)&ival, 4)) {
- close(s_in); close(s_out);
- return 0;
- }
- ival = Swap32IfLE(ival);
-
- /* zero means no dice: */
- if (ival == 0) {
- rfbLog("vencrypt: client selected no sub-type, closing connection.\n");
- close(s_in); close(s_out);
- return 0;
- }
-
- /* check if he selected a valid one: */
- ok = 0;
- for (i = 0; i < nsubtypes; i++) {
- if (ival == subtypes[i]) {
- ok = 1;
- }
- }
-
- if (!ok) {
- rfbLog("vencrypt: client selected invalid sub-type: %d\n", ival);
- close(s_in); close(s_out);
- return 0;
- } else {
- char *st = "unknown!!";
- if (ival == rfbVencryptTlsNone) st = "rfbVencryptTlsNone";
- if (ival == rfbVencryptTlsVnc) st = "rfbVencryptTlsVnc";
- if (ival == rfbVencryptTlsPlain) st = "rfbVencryptTlsPlain";
- if (ival == rfbVencryptX509None) st = "rfbVencryptX509None";
- if (ival == rfbVencryptX509Vnc) st = "rfbVencryptX509Vnc";
- if (ival == rfbVencryptX509Plain) st = "rfbVencryptX509Plain";
- rfbLog("vencrypt: client selected sub-type: %d (%s)\n", ival, st);
- }
-
- vencrypt_selected = ival;
-
- /* not documented in spec, send OK: */
- buf[0] = 1;
- if (!write_exact(s_out, buf, 1)) {
- close(s_in); close(s_out);
- return 0;
- }
-
- if (vencrypt_selected == rfbVencryptTlsNone ||
- vencrypt_selected == rfbVencryptTlsVnc ||
- vencrypt_selected == rfbVencryptTlsPlain) {
- /* these modes are Anonymous Diffie-Hellman */
- if (!switch_to_anon_dh()) {
- rfbLog("vencrypt: Anonymous Diffie-Hellman failed.\n");
- return 0;
- }
- }
-
- /* continue with SSL/TLS */
- return 1;
-}
-
-static int check_vnc_tls_mode(int s_in, int s_out, double last_https) {
- double waited = 0.0, waitmax = 1.4, dt = 0.01, start = dnow();
- struct timeval tv;
- int input = 0, i, n, ok;
- int major, minor, sectype = -1;
- char *proto = "RFB 003.008\n";
- char *stype = "unknown";
- char buf[256];
-
- vencrypt_selected = 0;
- anontls_selected = 0;
-
- if (vencrypt_mode == VENCRYPT_NONE && anontls_mode == ANONTLS_NONE) {
- /* only normal SSL */
- return 1;
- }
- if (ssl_client_mode) {
- if (vencrypt_mode == VENCRYPT_FORCE || anontls_mode == ANONTLS_FORCE) {
- rfbLog("check_vnc_tls_mode: VENCRYPT_FORCE/ANONTLS_FORCE in client\n");
- rfbLog("check_vnc_tls_mode: connect mode.\n");
- /* this is OK, continue on below for dialog. */
- } else {
- /* otherwise we must assume normal SSL (we send client hello) */
- 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");
- /* fallback to normal SSL */
- return 1;
- }
-
- if (last_https > 0.0) {
- double now = dnow();
- if (now < last_https + 5.0) {
- waitmax = 20.0;
- } else if (now < last_https + 15.0) {
- waitmax = 10.0;
- } else if (now < last_https + 30.0) {
- waitmax = 5.0;
- } else if (now < last_https + 60.0) {
- waitmax = 2.5;
- }
- }
-
- while (waited < waitmax) {
- fd_set rfds;
- FD_ZERO(&rfds);
- FD_SET(s_in, &rfds);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- select(s_in+1, &rfds, NULL, NULL, &tv);
- if (FD_ISSET(s_in, &rfds)) {
- input = 1;
- break;
- }
- usleep((int) (1000 * 1000 * dt));
- waited += dt;
- }
- rfbLog("check_vnc_tls_mode: waited: %f / %.2f input: %s\n",
- dnow() - start, waitmax, input ? "SSL Handshake" : "(future) RFB Handshake");
-
- if (input) {
- /* got SSL client hello, can only assume normal SSL */
- if (vencrypt_mode == VENCRYPT_FORCE || anontls_mode == ANONTLS_FORCE) {
- rfbLog("check_vnc_tls_mode: VENCRYPT_FORCE/ANONTLS_FORCE prevents normal SSL\n");
- return 0;
- }
- return 1;
- }
-
- /* send RFB 003.008 -- there is no turning back from this point... */
- if (!write_exact(s_out, proto, strlen(proto))) {
- close(s_in); close(s_out);
- return 0;
- }
-
- memset(buf, 0, sizeof(buf));
- if (!read_exact(s_in, buf, 12)) {
- close(s_in); close(s_out);
- return 0;
- }
-
- if (sscanf(buf, "RFB %03d.%03d\n", &major, &minor) != 2) {
- int i;
- rfbLog("check_vnc_tls_mode: abnormal handshake: '%s'\nbytes: ", buf);
- for (i=0; i < 12; i++) {
- fprintf(stderr, "%d.", (unsigned char) buf[i]);
- }
- fprintf(stderr, "\n");
- close(s_in); close(s_out);
- return 0;
- }
- rfbLog("check_vnc_tls_mode: version: %d.%d\n", major, minor);
- if (major != 3 || minor < 8) {
- rfbLog("check_vnc_tls_mode: invalid version: '%s'\n", buf);
- close(s_in); close(s_out);
- return 0;
- }
-
- n = 1;
- if (vencrypt_mode == VENCRYPT_FORCE) {
- buf[n++] = rfbSecTypeVencrypt;
- } else if (anontls_mode == ANONTLS_FORCE && !ssl_verify) {
- buf[n++] = rfbSecTypeAnonTls;
- } else if (vencrypt_mode == VENCRYPT_SOLE) {
- buf[n++] = rfbSecTypeVencrypt;
- } else if (anontls_mode == ANONTLS_SOLE && !ssl_verify) {
- buf[n++] = rfbSecTypeAnonTls;
- } else {
- if (vencrypt_mode == VENCRYPT_SUPPORT) {
- buf[n++] = rfbSecTypeVencrypt;
- }
- if (anontls_mode == ANONTLS_SUPPORT && !ssl_verify) {
- buf[n++] = rfbSecTypeAnonTls;
- }
- }
-
- n--;
- buf[0] = (char) n;
- if (!write_exact(s_out, buf, n+1)) {
- close(s_in); close(s_out);
- return 0;
- }
- if (0) fprintf(stderr, "wrote[%d] %d %d %d\n", n, buf[0], buf[1], buf[2]);
-
- buf[0] = 0;
- if (!read_exact(s_in, buf, 1)) {
- close(s_in); close(s_out);
- return 0;
- }
-
- if (buf[0] == rfbSecTypeVencrypt) stype = "VeNCrypt";
- if (buf[0] == rfbSecTypeAnonTls) stype = "ANONTLS";
-
- rfbLog("check_vnc_tls_mode: reply: %d (%s)\n", (int) buf[0], stype);
-
- ok = 0;
- for (i=1; i < n+1; i++) {
- if (buf[0] == buf[i]) {
- ok = 1;
- }
- }
- if (!ok) {
- char *msg = "check_vnc_tls_mode: invalid security-type";
- int len = strlen(msg);
- rfbLog("%s: %d\n", msg, (int) buf[0]);
- ((uint32_t *)buf)[0] = Swap32IfLE(len);
- write_exact(s_out, buf, 4);
- write_exact(s_out, msg, strlen(msg));
- close(s_in); close(s_out);
- return 0;
- }
-
- sectype = (int) buf[0];
-
- if (sectype == rfbSecTypeVencrypt) {
- return vencrypt_dialog(s_in, s_out);
- } else if (sectype == rfbSecTypeAnonTls) {
- return anontls_dialog(s_in, s_out);
- } else {
- return 0;
- }
-}
-
-static void pr_ssl_info(int verb) {
- SSL_CIPHER *c;
- SSL_SESSION *s;
- char *proto = "unknown";
-
- if (verb) {}
-
- if (ssl == NULL) {
- return;
- }
- c = SSL_get_current_cipher(ssl);
- s = SSL_get_session(ssl);
-
- if (s == NULL) {
- proto = "nosession";
- } else if (s->ssl_version == SSL2_VERSION) {
- proto = "SSLv2";
- } else if (s->ssl_version == SSL3_VERSION) {
- proto = "SSLv3";
- } else if (s->ssl_version == TLS1_VERSION) {
- proto = "TLSv1";
- }
- if (c != NULL) {
- rfbLog("SSL: ssl_helper[%d]: Cipher: %s %s Proto: %s\n", getpid(),
- SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c), proto);
- } else {
- rfbLog("SSL: ssl_helper[%d]: Proto: %s\n", getpid(),
- proto);
- }
-}
-
-static void ssl_timeout (int sig) {
- int i;
- rfbLog("sig: %d, ssl_init[%d] timed out.\n", sig, getpid());
- rfbLog("To increase the SSL initialization timeout use, e.g.:\n");
- rfbLog(" -env SSL_INIT_TIMEOUT=120 (for 120 seconds)\n");
- for (i=0; i < 256; i++) {
- close(i);
- }
- exit(1);
-}
-
-static int ssl_init(int s_in, int s_out, int skip_vnc_tls, double last_https) {
- unsigned char *sid = (unsigned char *) "x11vnc SID";
- char *name = NULL;
- int peerport = 0;
- int db = 0, rc, err;
- int ssock = s_in;
- double start = dnow();
- int timeout = 20;
-
- if (enc_str != NULL) {
- return 1;
- }
- if (getenv("SSL_DEBUG")) {
- db = atoi(getenv("SSL_DEBUG"));
- }
- usleep(100 * 1000);
- if (getenv("SSL_INIT_TIMEOUT")) {
- timeout = atoi(getenv("SSL_INIT_TIMEOUT"));
- } else if (client_connect != NULL && strstr(client_connect, "repeater")) {
- rfbLog("SSL: ssl_init[%d]: detected 'repeater' in connect string.\n", getpid());
- rfbLog("SSL: setting timeout to 1 hour: -env SSL_INIT_TIMEOUT=3600\n");
- rfbLog("SSL: use that option to set a different timeout value,\n");
- rfbLog("SSL: however note that with Windows UltraVNC repeater it\n");
- rfbLog("SSL: may timeout before your setting due to other reasons.\n");
- timeout = 3600;
- }
-
- if (skip_vnc_tls) {
- rfbLog("SSL: ssl_helper[%d]: HTTPS mode, skipping check_vnc_tls_mode()\n",
- getpid());
- } else if (!check_vnc_tls_mode(s_in, s_out, last_https)) {
- return 0;
- }
- rfbLog("SSL: ssl_init[%d]: %d/%d initialization timeout: %d secs.\n",
- getpid(), s_in, s_out, timeout);
-
- ssl = SSL_new(ctx);
- if (ssl == NULL) {
- fprintf(stderr, "SSL_new failed\n");
- return 0;
- }
- if (db > 1) fprintf(stderr, "ssl_init: 1\n");
-
- SSL_set_session_id_context(ssl, sid, strlen((char *)sid));
-
- if (s_in == s_out) {
- if (! SSL_set_fd(ssl, ssock)) {
- fprintf(stderr, "SSL_set_fd failed\n");
- return 0;
- }
- } else {
- if (! SSL_set_rfd(ssl, s_in)) {
- fprintf(stderr, "SSL_set_rfd failed\n");
- return 0;
- }
- if (! SSL_set_wfd(ssl, s_out)) {
- fprintf(stderr, "SSL_set_wfd failed\n");
- return 0;
- }
- }
- if (db > 1) fprintf(stderr, "ssl_init: 2\n");
-
- if (ssl_client_mode) {
- SSL_set_connect_state(ssl);
- } else {
- SSL_set_accept_state(ssl);
- }
-
- if (db > 1) fprintf(stderr, "ssl_init: 3\n");
-
- name = get_remote_host(ssock);
- peerport = get_remote_port(ssock);
-
- if (!strcmp(name, "0.0.0.0") && openssl_last_ip != NULL) {
- name = strdup(openssl_last_ip);
- }
-
- if (db > 1) fprintf(stderr, "ssl_init: 4\n");
-
- while (1) {
-
- 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);
-
- alarm(0);
- signal(SIGALRM, SIG_DFL);
-
- 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) {
-
- if (db) fprintf(stderr, "got SSL_ERROR_WANT_READ\n");
- rfbLog("SSL: ssl_helper[%d]: %s() failed for: %s:%d 1\n",
- getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept", name, peerport);
- pr_ssl_info(1);
- return 0;
-
- } else if (err == SSL_ERROR_WANT_WRITE) {
-
- if (db) fprintf(stderr, "got SSL_ERROR_WANT_WRITE\n");
- rfbLog("SSL: ssl_helper[%d]: %s() failed for: %s:%d 2\n",
- getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept", name, peerport);
- pr_ssl_info(1);
- return 0;
-
- } else if (err == SSL_ERROR_SYSCALL) {
-
- if (db) fprintf(stderr, "got SSL_ERROR_SYSCALL\n");
- rfbLog("SSL: ssl_helper[%d]: %s() failed for: %s:%d 3\n",
- getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept", name, peerport);
- pr_ssl_info(1);
- return 0;
-
- } else if (err == SSL_ERROR_ZERO_RETURN) {
-
- if (db) fprintf(stderr, "got SSL_ERROR_ZERO_RETURN\n");
- rfbLog("SSL: ssl_helper[%d]: %s() failed for: %s:%d 4\n",
- getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept", name, peerport);
- pr_ssl_info(1);
- return 0;
-
- } else if (rc < 0) {
- unsigned long err;
- int cnt = 0;
-
- rfbLog("SSL: ssl_helper[%d]: %s() *FATAL: %d SSL FAILED\n",
- getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept", rc);
- while ((err = ERR_get_error()) != 0) {
- rfbLog("SSL: %s\n", ERR_error_string(err, NULL));
- if (cnt++ > 100) {
- break;
- }
- }
- pr_ssl_info(1);
- return 0;
-
- } else if (dnow() > start + 3.0) {
-
- rfbLog("SSL: ssl_helper[%d]: timeout looping %s() "
- "fatal.\n", getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept");
- pr_ssl_info(1);
- return 0;
-
- } else {
- BIO *bio = SSL_get_rbio(ssl);
- if (bio == NULL) {
- rfbLog("SSL: ssl_helper[%d]: ssl BIO is null. "
- "fatal.\n", getpid());
- pr_ssl_info(1);
- return 0;
- }
- if (BIO_eof(bio)) {
- rfbLog("SSL: ssl_helper[%d]: ssl BIO is EOF. "
- "fatal.\n", getpid());
- pr_ssl_info(1);
- return 0;
- }
- }
- usleep(10 * 1000);
- }
-
- 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);
-
- if (SSL_get_verify_result(ssl) == X509_V_OK) {
- X509 *x;
- FILE *cr = NULL;
- if (certret != NULL) {
- cr = fopen(certret, "w");
- }
-
- x = SSL_get_peer_certificate(ssl);
- if (x == NULL) {
- rfbLog("SSL: ssl_helper[%d]: accepted client %s x509 peer cert is null\n", getpid(), name);
- if (cr != NULL) {
- fprintf(cr, "NOCERT\n");
- fclose(cr);
- }
- } else {
- rfbLog("SSL: ssl_helper[%d]: accepted client %s x509 cert is:\n", getpid(), name);
-#if LIBVNCSERVER_HAVE_X509_PRINT_EX_FP
- X509_print_ex_fp(stderr, x, 0, XN_FLAG_MULTILINE);
-#endif
- if (cr != NULL) {
-#if LIBVNCSERVER_HAVE_X509_PRINT_EX_FP
- X509_print_ex_fp(cr, x, 0, XN_FLAG_MULTILINE);
-#else
- rfbLog("** not compiled with libssl X509_print_ex_fp() function **\n");
- if (users_list && strstr(users_list, "sslpeer=")) {
- rfbLog("** -users sslpeer= will not work! **\n");
- }
-#endif
- fclose(cr);
- }
- }
- }
- free(name);
-
- return 1;
-}
-
-static void symmetric_encryption_xfer(int csock, int s_in, int s_out);
-
-static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
- int dbxfer = 0, db = 0, check_pending, fdmax, nfd, n, i, err;
- char cbuf[ABSIZE], sbuf[ABSIZE];
- int cptr, sptr, c_rd, c_wr, s_rd, s_wr;
- fd_set rd, wr;
- struct timeval tv;
- int ssock, cnt = 0, ndata = 0;
-
- /*
- * we want to switch to a longer timeout for long term VNC
- * connections (in case the network is not working for periods of
- * time), but we also want the timeout shorter at the beginning
- * in case the client went away.
- */
- double start, now;
- int tv_https_early = 60;
- int tv_https_later = 20;
- int tv_vnc_early = 40;
- int tv_vnc_later = 43200; /* was 300, stunnel: 43200 */
- int tv_cutover = 70;
- int tv_closing = 60;
- int tv_use;
-
- if (dbxfer) {
- raw_xfer(csock, s_in, s_out);
- return;
- }
- if (enc_str != NULL) {
- if (!strcmp(enc_str, "none")) {
- usleep(250*1000);
- rfbLog("doing '-enc none' raw transfer (no encryption)\n");
- raw_xfer(csock, s_in, s_out);
- } else {
- symmetric_encryption_xfer(csock, s_in, s_out);
- }
- return;
- }
-
- if (getenv("SSL_DEBUG")) {
- db = atoi(getenv("SSL_DEBUG"));
- }
-
- if (db) fprintf(stderr, "ssl_xfer begin\n");
-
- start = dnow();
- if (is_https) {
- tv_use = tv_https_early;
- } else {
- tv_use = tv_vnc_early;
- }
-
-
- /*
- * csock: clear text socket with libvncserver. "C"
- * ssock: ssl data socket with remote vnc viewer. "S"
- *
- * to cover inetd mode, we have s_in and s_out, but in non-inetd
- * mode they both ssock.
- *
- * cbuf[] is data from csock that we have read but not passed on to ssl
- * sbuf[] is data from ssl that we have read but not passed on to csock
- */
- for (i=0; i<ABSIZE; i++) {
- cbuf[i] = '\0';
- sbuf[i] = '\0';
- }
-
- if (s_out > s_in) {
- ssock = s_out;
- } else {
- ssock = s_in;
- }
-
- if (csock > ssock) {
- fdmax = csock;
- } else {
- fdmax = ssock;
- }
-
- c_rd = 1; /* clear text (libvncserver) socket open for reading */
- c_wr = 1; /* clear text (libvncserver) socket open for writing */
- s_rd = 1; /* ssl data (remote client) socket open for reading */
- s_wr = 1; /* ssl data (remote client) socket open for writing */
-
- cptr = 0; /* offsets into ABSIZE buffers */
- sptr = 0;
-
- if (vencrypt_selected > 0 || anontls_selected > 0) {
- char tmp[16];
- /* read and discard the extra RFB version */
- memset(tmp, 0, sizeof(tmp));
- read(csock, tmp, 12);
- if (0) fprintf(stderr, "extra: %s\n", tmp);
- }
-
- while (1) {
- int c_to_s, s_to_c, closing;
-
- if ( s_wr && (c_rd || cptr > 0) ) {
- /*
- * S is writable and
- * C is readable or some cbuf data remaining
- */
- c_to_s = 1;
- } else {
- c_to_s = 0;
- }
-
- if ( c_wr && (s_rd || sptr > 0) ) {
- /*
- * C is writable and
- * S is readable or some sbuf data remaining
- */
- s_to_c = 1;
- } else {
- s_to_c = 0;
- }
-
- if (! c_to_s && ! s_to_c) {
- /*
- * nothing can be sent either direction.
- * break out of the loop to finish all work.
- */
- break;
- }
- cnt++;
-
- /* set up the fd sets for the two sockets for read & write: */
-
- FD_ZERO(&rd);
-
- if (c_rd && cptr < ABSIZE) {
- /* we could read more from C since cbuf is not full */
- FD_SET(csock, &rd);
- }
- if (s_rd) {
- /*
- * we could read more from S since sbuf not full,
- * OR ssl is waiting for more BIO to be able to
- * read and we have some C data still buffered.
- */
- if (sptr < ABSIZE || (cptr > 0 && SSL_want_read(ssl))) {
- FD_SET(s_in, &rd);
- }
- }
-
- FD_ZERO(&wr);
-
- if (c_wr && sptr > 0) {
- /* we could write more to C since sbuf is not empty */
- FD_SET(csock, &wr);
- }
- if (s_wr) {
- /*
- * we could write more to S since cbuf not empty,
- * OR ssl is waiting for more BIO to be able
- * write and we haven't filled up sbuf yet.
- */
- if (cptr > 0 || (sptr < ABSIZE && SSL_want_write(ssl))) {
- FD_SET(s_out, &wr);
- }
- }
-
- now = dnow();
- if (tv_cutover && now > start + tv_cutover) {
- rfbLog("SSL: ssl_xfer[%d]: tv_cutover: %d\n", getpid(),
- tv_cutover);
- tv_cutover = 0;
- if (is_https) {
- tv_use = tv_https_later;
- } else {
- tv_use = tv_vnc_later;
- }
- /* try to clean out some zombies if we can. */
- ssl_helper_pid(0, -2);
- }
- if (ssl_timeout_secs > 0) {
- tv_use = ssl_timeout_secs;
- }
-
- if ( (s_rd && c_rd) || cptr || sptr) {
- closing = 0;
- } else {
- closing = 1;
- tv_use = tv_closing;
- }
-
- tv.tv_sec = tv_use;
- tv.tv_usec = 0;
-
- /* do the select, repeat if interrupted */
- do {
- if (ssl_timeout_secs == 0) {
- nfd = select(fdmax+1, &rd, &wr, NULL, NULL);
- } else {
- nfd = select(fdmax+1, &rd, &wr, NULL, &tv);
- }
- } while (nfd < 0 && errno == EINTR);
-
- if (db > 1) fprintf(stderr, "nfd: %d\n", nfd);
-
-if (0) fprintf(stderr, "nfd[%d]: %d w/r csock: %d %d s_in: %d %d\n", getpid(), nfd, FD_ISSET(csock, &wr), FD_ISSET(csock, &rd), FD_ISSET(s_out, &wr), FD_ISSET(s_in, &rd));
-
- if (nfd < 0) {
- rfbLog("SSL: ssl_xfer[%d]: select error: %d\n", getpid(), nfd);
- perror("select");
- /* connection finished */
- goto done;
- }
-
- if (nfd == 0) {
- if (!closing && tv_cutover && ndata > 25000) {
- static int cn = 0;
- /* probably ok, early windows iconify */
- if (cn++ < 2) {
- rfbLog("SSL: ssl_xfer[%d]: early time"
- "out: %d\n", getpid(), ndata);
- }
- continue;
- }
- rfbLog("SSL: ssl_xfer[%d]: connection timedout. %d tv_use: %d\n",
- getpid(), ndata, tv_use);
- /* connection finished */
- goto done;
- }
-
- /* used to see if SSL_pending() should be checked: */
- check_pending = 0;
-/* AUDIT */
-
- if (c_wr && FD_ISSET(csock, &wr)) {
-
- /* try to write some of our sbuf to C: */
- n = write(csock, sbuf, sptr);
-
- if (n < 0) {
- if (errno != EINTR) {
- /* connection finished */
- goto done;
- }
- /* proceed */
- } else if (n == 0) {
- /* connection finished XXX double check */
- goto done;
- } else {
- /* shift over the data in sbuf by n */
- memmove(sbuf, sbuf + n, sptr - n);
- if (sptr == ABSIZE) {
- check_pending = 1;
- }
- sptr -= n;
-
- if (! s_rd && sptr == 0) {
- /* finished sending last of sbuf */
- shutdown(csock, SHUT_WR);
- c_wr = 0;
- }
- ndata += n;
- }
- }
-
- if (s_wr) {
- if ((cptr > 0 && FD_ISSET(s_out, &wr)) ||
- (SSL_want_read(ssl) && FD_ISSET(s_in, &rd))) {
-
- /* try to write some of our cbuf to S: */
-
- n = SSL_write(ssl, cbuf, cptr);
- err = SSL_get_error(ssl, n);
-
- if (err == SSL_ERROR_NONE) {
- /* shift over the data in cbuf by n */
- memmove(cbuf, cbuf + n, cptr - n);
- cptr -= n;
-
- if (! c_rd && cptr == 0 && s_wr) {
- /* finished sending last cbuf */
- SSL_shutdown(ssl);
- s_wr = 0;
- }
- ndata += n;
-
- } else if (err == SSL_ERROR_WANT_WRITE
- || err == SSL_ERROR_WANT_READ
- || err == SSL_ERROR_WANT_X509_LOOKUP) {
-
- ; /* proceed */
-
- } else if (err == SSL_ERROR_SYSCALL) {
- if (n < 0 && errno != EINTR) {
- /* connection finished */
- goto done;
- }
- /* proceed */
- } else if (err == SSL_ERROR_ZERO_RETURN) {
- /* S finished */
- s_rd = 0;
- s_wr = 0;
- } else if (err == SSL_ERROR_SSL) {
- /* connection finished */
- goto done;
- }
- }
- }
-
- if (c_rd && FD_ISSET(csock, &rd)) {
-
-
- /* try to read some data from C into our cbuf */
-
- n = read(csock, cbuf + cptr, ABSIZE - cptr);
-
- if (n < 0) {
- if (errno != EINTR) {
- /* connection finished */
- goto done;
- }
- /* proceed */
- } else if (n == 0) {
- /* C is EOF */
- c_rd = 0;
- if (cptr == 0 && s_wr) {
- /* and no more in cbuf to send */
- SSL_shutdown(ssl);
- s_wr = 0;
- }
- } else {
- /* good */
-
- cptr += n;
- ndata += n;
- }
- }
-
- if (s_rd) {
- if ((sptr < ABSIZE && FD_ISSET(s_in, &rd)) ||
- (SSL_want_write(ssl) && FD_ISSET(s_out, &wr)) ||
- (check_pending && SSL_pending(ssl))) {
-
- /* try to read some data from S into our sbuf */
-
- n = SSL_read(ssl, sbuf + sptr, ABSIZE - sptr);
- err = SSL_get_error(ssl, n);
-
- if (err == SSL_ERROR_NONE) {
- /* good */
-
- sptr += n;
- ndata += n;
-
- } else if (err == SSL_ERROR_WANT_WRITE
- || err == SSL_ERROR_WANT_READ
- || err == SSL_ERROR_WANT_X509_LOOKUP) {
-
- ; /* proceed */
-
- } else if (err == SSL_ERROR_SYSCALL) {
- if (n < 0) {
- if(errno != EINTR) {
- /* connection finished */
- goto done;
- }
- /* proceed */
- } else {
- /* S finished */
- s_rd = 0;
- s_wr = 0;
- }
- } else if (err == SSL_ERROR_ZERO_RETURN) {
- /* S is EOF */
- s_rd = 0;
- if (cptr == 0 && s_wr) {
- /* and no more in cbuf to send */
- SSL_shutdown(ssl);
- s_wr = 0;
- }
- if (sptr == 0 && c_wr) {
- /* and no more in sbuf to send */
- shutdown(csock, SHUT_WR);
- c_wr = 0;
- }
- } else if (err == SSL_ERROR_SSL) {
- /* connection finished */
- goto done;
- }
- }
- }
- }
-
- done:
- rfbLog("SSL: ssl_xfer[%d]: closing sockets %d, %d, %d\n",
- getpid(), csock, s_in, s_out);
- close(csock);
- close(s_in);
- close(s_out);
- return;
-}
-
-#define MSZ 4096
-static void init_prng(void) {
- int db = 0, bytes, ubytes, fd;
- char file[MSZ], dtmp[100];
- unsigned int sr;
-
- RAND_file_name(file, MSZ);
-
- rfbLog("RAND_file_name: %s\n", file);
-
- bytes = RAND_load_file(file, -1);
- if (db) fprintf(stderr, "bytes read: %d\n", bytes);
-
- ubytes = RAND_load_file("/dev/urandom", 64);
- bytes += ubytes;
- if (db) fprintf(stderr, "bytes read: %d / %d\n", bytes, ubytes);
-
- /* mix in more predictable stuff as well for fallback */
- sprintf(dtmp, "/tmp/p%.8f.XXXXXX", dnow());
- fd = mkstemp(dtmp);
- RAND_add(dtmp, strlen(dtmp), 0);
- if (fd >= 0) {
- close(fd);
- unlink(dtmp);
- }
- sprintf(dtmp, "%d-%.8f", (int) getpid(), dnow());
- RAND_add(dtmp, strlen(dtmp), 0);
-
- if (!RAND_status()) {
- ubytes = -1;
- rfbLog("calling RAND_poll()\n");
- RAND_poll();
- }
-
- RAND_bytes((unsigned char *)&sr, 4);
- srand(sr);
-
- if (bytes > 0) {
- if (! quiet) {
- rfbLog("initialized PRNG with %d random bytes.\n",
- bytes);
- }
- if (ubytes > 32 && rnow() < 0.25) {
- RAND_write_file(file);
- }
- return;
- }
-
- bytes += RAND_load_file("/dev/random", 8);
- if (db) fprintf(stderr, "bytes read: %d\n", bytes);
- RAND_poll();
-
- if (! quiet) {
- rfbLog("initialized PRNG with %d random bytes.\n", bytes);
- }
-}
-#endif /* FORK_OK */
-#endif /* LIBVNCSERVER_HAVE_LIBSSL */
-
-void check_openssl(void) {
- fd_set fds;
- struct timeval tv;
- int nfds, nmax = openssl_sock;
- static time_t last_waitall = 0;
- static double last_check = 0.0;
- double now;
-
- if (! use_openssl) {
- return;
- }
-
- if (time(NULL) > last_waitall + 120) {
- last_waitall = time(NULL);
- ssl_helper_pid(0, -2); /* waitall */
- }
-
- if (openssl_sock < 0 && openssl_sock6 < 0) {
- return;
- }
-
- now = dnow();
- if (now < last_check + 0.5) {
- return;
- }
- last_check = now;
-
- FD_ZERO(&fds);
- if (openssl_sock >= 0) {
- FD_SET(openssl_sock, &fds);
- }
- if (openssl_sock6 >= 0) {
- FD_SET(openssl_sock6, &fds);
- if (openssl_sock6 > openssl_sock) {
- nmax = openssl_sock6;
- }
- }
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- nfds = select(nmax+1, &fds, NULL, NULL, &tv);
-
- if (nfds <= 0) {
- return;
- }
-
- if (openssl_sock >= 0 && FD_ISSET(openssl_sock, &fds)) {
- rfbLog("SSL: accept_openssl(OPENSSL_VNC)\n");
- accept_openssl(OPENSSL_VNC, -1);
- }
- if (openssl_sock6 >= 0 && FD_ISSET(openssl_sock6, &fds)) {
- rfbLog("SSL: accept_openssl(OPENSSL_VNC6)\n");
- accept_openssl(OPENSSL_VNC6, -1);
- }
-}
-
-void check_https(void) {
- fd_set fds;
- struct timeval tv;
- int nfds, nmax = https_sock;
- static double last_check = 0.0;
- double now;
-
- if (! use_openssl || (https_sock < 0 && https_sock6 < 0)) {
- return;
- }
-
- now = dnow();
- if (now < last_check + 0.5) {
- return;
- }
- last_check = now;
-
- FD_ZERO(&fds);
- if (https_sock >= 0) {
- FD_SET(https_sock, &fds);
- }
- if (https_sock6 >= 0) {
- FD_SET(https_sock6, &fds);
- if (https_sock6 > https_sock) {
- nmax = https_sock6;
- }
- }
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- nfds = select(nmax+1, &fds, NULL, NULL, &tv);
-
- if (nfds <= 0) {
- return;
- }
-
- if (https_sock >= 0 && FD_ISSET(https_sock, &fds)) {
- rfbLog("SSL: accept_openssl(OPENSSL_HTTPS)\n");
- accept_openssl(OPENSSL_HTTPS, -1);
- }
- if (https_sock6 >= 0 && FD_ISSET(https_sock6, &fds)) {
- rfbLog("SSL: accept_openssl(OPENSSL_HTTPS6)\n");
- accept_openssl(OPENSSL_HTTPS6, -1);
- }
-}
-
-void openssl_port(int restart) {
- int sock = -1, shutdown = 0;
- static int port = -1;
- static in_addr_t iface = INADDR_ANY;
- int db = 0, fd6 = -1;
-
- if (! screen) {
- rfbLog("openssl_port: no screen!\n");
- clean_up_exit(1);
- }
- if (inetd) {
- ssl_initialized = 1;
- return;
- }
-
- if (ipv6_listen && screen->port <= 0) {
- if (got_rfbport) {
- screen->port = got_rfbport_val;
- } else {
- int ap = 5900;
- if (auto_port > 0) {
- ap = auto_port;
- }
- screen->port = find_free_port6(ap, ap+200);
- }
- rfbLog("openssl_port: reset port from 0 => %d\n", screen->port);
- }
-
- if (restart) {
- port = screen->port;
- } else if (screen->listenSock > -1 && screen->port > 0) {
- port = screen->port;
- shutdown = 1;
- } else if (ipv6_listen && screen->port > 0) {
- port = screen->port;
- } else if (screen->port == 0) {
- port = screen->port;
- }
-
- iface = screen->listenInterface;
-
- if (shutdown) {
- if (db) fprintf(stderr, "shutting down %d/%d\n",
- port, screen->listenSock);
-#if LIBVNCSERVER_HAS_SHUTDOWNSOCKETS
- rfbShutdownSockets(screen);
-#endif
- }
-
- if (openssl_sock >= 0) {
- close(openssl_sock);
- openssl_sock = -1;
- }
- if (openssl_sock6 >= 0) {
- close(openssl_sock6);
- openssl_sock6 = -1;
- }
-
- if (port < 0) {
- rfbLog("openssl_port: could not obtain listening port %d\n", port);
- if (!got_rfbport && !got_ipv6_listen) {
- rfbLog("openssl_port: if this system is IPv6-only, use the -6 option\n");
- }
- clean_up_exit(1);
- } else if (port == 0) {
- /* no listen case, i.e. -connect */
- sock = -1;
- } else {
- sock = listen_tcp(port, iface, 0);
- if (ipv6_listen) {
- fd6 = listen6(port);
- } else if (!got_rfbport && !got_ipv6_listen) {
- if (sock < 0) {
- rfbLog("openssl_port: if this system is IPv6-only, use the -6 option\n");
- }
- }
- if (sock < 0) {
- if (fd6 < 0) {
- rfbLog("openssl_port: could not reopen port %d\n", port);
- if (!restart) {
- clean_up_exit(1);
- }
- } else {
- rfbLog("openssl_port: Info: listening on IPv6 only.\n");
- }
- }
- }
- rfbLog("openssl_port: listen on port/sock %d/%d\n", port, sock);
- if (ipv6_listen && port > 0) {
- if (fd6 < 0) {
- fd6 = listen6(port);
- }
- if (fd6 < 0) {
- ipv6_listen = 0;
- } else {
- rfbLog("openssl_port: listen on port/sock %d/%d (ipv6)\n",
- port, fd6);
- openssl_sock6 = fd6;
- }
- }
- if (!quiet && sock >=0) {
- announce(port, 1, NULL);
- }
- openssl_sock = sock;
- openssl_port_num = port;
-
- ssl_initialized = 1;
-}
-
-void https_port(int restart) {
- int sock, fd6 = -1;
- static int port = 0;
- static in_addr_t iface = INADDR_ANY;
-
- /* as openssl_port above: open a listening socket for pure https: */
- if (https_port_num < 0) {
- return;
- }
- if (! screen) {
- rfbLog("https_port: no screen!\n");
- clean_up_exit(1);
- }
- if (! screen->httpDir) {
- return;
- }
- if (screen->listenInterface) {
- iface = screen->listenInterface;
- }
-
- if (https_port_num == 0) {
- https_port_num = find_free_port(5801, 5851);
- }
- if (ipv6_listen && https_port_num <= 0) {
- https_port_num = find_free_port6(5801, 5851);
- }
- if (https_port_num <= 0) {
- rfbLog("https_port: could not find port %d\n", https_port_num);
- clean_up_exit(1);
- }
- port = https_port_num;
-
- if (port <= 0) {
- rfbLog("https_port: could not obtain listening port %d\n", port);
- if (!restart) {
- clean_up_exit(1);
- } else {
- return;
- }
- }
- if (https_sock >= 0) {
- close(https_sock);
- https_sock = -1;
- }
- if (https_sock6 >= 0) {
- close(https_sock6);
- https_sock6 = -1;
- }
- sock = listen_tcp(port, iface, 0);
- if (sock < 0) {
- rfbLog("https_port: could not open port %d\n", port);
- if (ipv6_listen) {
- fd6 = listen6(port);
- }
- if (fd6 < 0) {
- if (!restart) {
- clean_up_exit(1);
- }
- }
- rfbLog("https_port: trying IPv6 only mode.\n");
- }
- rfbLog("https_port: listen on port/sock %d/%d\n", port, sock);
- https_sock = sock;
-
- if (ipv6_listen) {
- if (fd6 < 0) {
- fd6 = listen6(port);
- }
- if (fd6 < 0) {
- ;
- } else {
- rfbLog("https_port: listen on port/sock %d/%d (ipv6)\n",
- port, fd6);
- https_sock6 = fd6;
- }
- if (fd6 < 0 && https_sock < 0) {
- rfbLog("https_port: could not listen on either IPv4 or IPv6.\n");
- if (!restart) {
- clean_up_exit(1);
- }
- }
- }
-}
-
-static void lose_ram(void) {
- /*
- * for a forked child that will be around for a long time
- * without doing exec(). we really should re-exec, but a pain
- * to redo all SSL ctx.
- */
- free_old_fb();
-
- free_tiles();
-}
-
-/* utility to keep track of existing helper processes: */
-
-void ssl_helper_pid(pid_t pid, int sock) {
-# define HPSIZE 256
- static pid_t helpers[HPSIZE];
- static int sockets[HPSIZE], first = 1;
- int i, empty, set, status;
- static int db = 0;
-
- if (first) {
- for (i=0; i < HPSIZE; i++) {
- helpers[i] = 0;
- sockets[i] = 0;
- }
- if (getenv("SSL_HELPER_PID_DB")) {
- db = 1;
- }
- first = 0;
- }
-
-
- if (pid == 0) {
- /* killall or waitall */
- for (i=0; i < HPSIZE; i++) {
- if (helpers[i] == 0) {
- sockets[i] = -1;
- continue;
- }
- if (kill(helpers[i], 0) == 0) {
- int kret = -2;
- pid_t wret;
- if (sock != -2) {
- if (sockets[i] >= 0) {
- close(sockets[i]);
- }
- kret = kill(helpers[i], SIGTERM);
- if (kret == 0) {
- usleep(20 * 1000);
- }
- }
-
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_WAITPID
- wret = waitpid(helpers[i], &status, WNOHANG);
-
-if (db) fprintf(stderr, "waitpid(%d)\n", helpers[i]);
-if (db) fprintf(stderr, " waitret1=%d\n", wret);
-
- if (kret == 0 && wret != helpers[i]) {
- int k;
- for (k=0; k < 10; k++) {
- usleep(100 * 1000);
- wret = waitpid(helpers[i], &status, WNOHANG);
-if (db) fprintf(stderr, " waitret2=%d\n", wret);
- if (wret == helpers[i]) {
- break;
- }
- }
- }
-#endif
- if (sock == -2) {
- continue;
- }
- }
- helpers[i] = 0;
- sockets[i] = -1;
- }
- return;
- }
-
-if (db) fprintf(stderr, "ssl_helper_pid(%d, %d)\n", pid, sock);
-
- /* add (or delete for sock == -1) */
- set = 0;
- empty = -1;
- for (i=0; i < HPSIZE; i++) {
- if (helpers[i] == pid) {
- if (sock == -1) {
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_WAITPID
- pid_t wret;
- wret = waitpid(helpers[i], &status, WNOHANG);
-
-if (db) fprintf(stderr, "waitpid(%d) 2\n", helpers[i]);
-if (db) fprintf(stderr, " waitret1=%d\n", wret);
-#endif
- helpers[i] = 0;
- }
- sockets[i] = sock;
- set = 1;
- } else if (empty == -1 && helpers[i] == 0) {
- empty = i;
- }
- }
- if (set || sock == -1) {
- return; /* done */
- }
-
- /* now try to store */
- if (empty >= 0) {
- helpers[empty] = pid;
- sockets[empty] = sock;
- return;
- }
- for (i=0; i < HPSIZE; i++) {
- if (helpers[i] == 0) {
- continue;
- }
- /* clear out stale pids: */
- if (kill(helpers[i], 0) != 0) {
- helpers[i] = 0;
- sockets[i] = -1;
-
- if (empty == -1) {
- empty = i;
- }
- }
- }
- if (empty >= 0) {
- helpers[empty] = pid;
- sockets[empty] = sock;
- }
-}
-
-static int is_ssl_readable(int s_in, double last_https, char *last_get,
- int mode) {
- int nfd, db = 0;
- struct timeval tv;
- fd_set rd;
-
- if (getenv("ACCEPT_OPENSSL_DEBUG")) {
- db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
- }
-
- /*
- * we'll do a select() on s_in for reading. this is not an
- * absolute proof that SSL_read is ready (XXX use SSL utility).
- */
- tv.tv_sec = 2;
- tv.tv_usec = 0;
-
- if (mode == OPENSSL_INETD) {
- /*
- * https via inetd is icky because x11vnc is restarted
- * for each socket (and some clients send requests
- * rapid fire).
- */
- tv.tv_sec = 4;
- }
-
- /*
- * increase the timeout if we know HTTP traffic has occurred
- * recently:
- */
- if (dnow() < last_https + 30.0) {
- tv.tv_sec = 10;
- if (last_get && strstr(last_get, "VncViewer")) {
- tv.tv_sec = 5;
- }
- }
- if (getenv("X11VNC_HTTPS_VS_VNC_TIMEOUT")) {
- tv.tv_sec = atoi(getenv("X11VNC_HTTPS_VS_VNC_TIMEOUT"));
- }
-if (db) fprintf(stderr, "tv_sec: %d - '%s'\n", (int) tv.tv_sec, last_get);
-
- FD_ZERO(&rd);
- FD_SET(s_in, &rd);
-
- if (db) fprintf(stderr, "is_ssl_readable: begin select(%d secs) %.6f\n", (int) tv.tv_sec, dnow());
- do {
- nfd = select(s_in+1, &rd, NULL, NULL, &tv);
- } while (nfd < 0 && errno == EINTR);
- if (db) fprintf(stderr, "is_ssl_readable: finish select(%d secs) %.6f\n", (int) tv.tv_sec, dnow());
-
- if (db) fprintf(stderr, "https nfd: %d\n", nfd);
-
- if (nfd <= 0 || ! FD_ISSET(s_in, &rd)) {
- return 0;
- }
- return 1;
-}
-
-static int watch_for_http_traffic(char *buf_a, int *n_a, int raw_sock) {
- int is_http, err, n, n2;
- char *buf;
- int db = 0;
- /*
- * sniff the first couple bytes of the stream and try to see
- * if it is http or not. if we read them OK, we must read the
- * rest of the available data otherwise we may deadlock.
- * what has been read is returned in buf_a and n_a.
- * *buf_a is ABSIZE+1 long and zeroed.
- */
- if (getenv("ACCEPT_OPENSSL_DEBUG")) {
- db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
- }
- if (! buf_a || ! n_a) {
- return 0;
- }
-
- buf = (char *) calloc((ABSIZE+1), 1);
- *n_a = 0;
-
- if (enc_str && !strcmp(enc_str, "none")) {
- n = read(raw_sock, buf, 2);
- err = SSL_ERROR_NONE;
- } else {
-#if LIBVNCSERVER_HAVE_LIBSSL
- n = SSL_read(ssl, buf, 2);
- err = SSL_get_error(ssl, n);
-#else
- err = n = 0;
- badnews("1 in watch_for_http_traffic");
-#endif
- }
-
- if (err != SSL_ERROR_NONE || n < 2) {
- if (n > 0) {
- strncpy(buf_a, buf, n);
- *n_a = n;
- }
- if (db) fprintf(stderr, "watch_for_http_traffic ssl err: %d/%d\n", err, n);
- return -1;
- }
-
- /* look for GET, HEAD, POST, CONNECT */
- is_http = 0;
- if (!strncmp("GE", buf, 2)) {
- is_http = 1;
- } else if (!strncmp("HE", buf, 2)) {
- is_http = 1;
- } else if (!strncmp("PO", buf, 2)) {
- is_http = 1;
- } else if (!strncmp("CO", buf, 2)) {
- is_http = 1;
- }
- if (db) fprintf(stderr, "watch_for_http_traffic read: '%s' %d\n", buf, n);
-
- /*
- * better read all we can and fwd it along to avoid blocking
- * in ssl_xfer().
- */
-
- if (enc_str && !strcmp(enc_str, "none")) {
- n2 = read(raw_sock, buf + n, ABSIZE - n);
- } else {
-#if LIBVNCSERVER_HAVE_LIBSSL
- n2 = SSL_read(ssl, buf + n, ABSIZE - n);
-#else
- n2 = 0;
- badnews("2 in watch_for_http_traffic");
-#endif
- }
- if (n2 >= 0) {
- n += n2;
- }
-
- *n_a = n;
-
- if (db) fprintf(stderr, "watch_for_http_traffic readmore: %d\n", n2);
-
- if (n > 0) {
- memcpy(buf_a, buf, n);
- }
- if (db > 1) {
- fprintf(stderr, "watch_for_http_traffic readmore: ");
- write(2, buf_a, *n_a);
- fprintf(stderr, "\n");
- }
- if (db) fprintf(stderr, "watch_for_http_traffic return: %d\n", is_http);
- return is_http;
-}
-
-static int csock_timeout_sock = -1;
-
-static void csock_timeout (int sig) {
- rfbLog("sig: %d, csock_timeout.\n", sig);
- if (csock_timeout_sock >= 0) {
- close(csock_timeout_sock);
- csock_timeout_sock = -1;
- }
-}
-
-static int check_ssl_access(char *addr) {
- static char *save_allow_once = NULL;
- static time_t time_allow_once = 0;
-
- /* due to "Fetch Cert" activities for SSL really need to "allow twice" */
- if (allow_once != NULL) {
- save_allow_once = strdup(allow_once);
- time_allow_once = time(NULL);
- } else if (save_allow_once != NULL) {
- if (getenv("X11VNC_NO_SSL_ALLOW_TWICE")) {
- ;
- } else if (time(NULL) < time_allow_once + 30) {
- /* give them 30 secs to check and save the fetched cert. */
- allow_once = save_allow_once;
- rfbLog("SSL: Permitting 30 sec grace period for allowonce.\n");
- rfbLog("SSL: Set X11VNC_NO_SSL_ALLOW_TWICE=1 to disable.\n");
- }
- save_allow_once = NULL;
- time_allow_once = 0;
- }
-
- return check_access(addr);
-}
-
-void accept_openssl(int mode, int presock) {
- int sock = -1, listen = -1, cport, csock, vsock;
- int peerport = 0;
- int status, n, i, db = 0;
- struct sockaddr_in addr;
-#ifdef __hpux
- int addrlen = sizeof(addr);
-#else
- socklen_t addrlen = sizeof(addr);
-#endif
- rfbClientPtr client;
- pid_t pid;
- char uniq[] = "_evilrats_";
- char cookie[256], rcookie[256], *name = NULL;
- int vencrypt_sel = 0;
- int anontls_sel = 0;
- char *ipv6_name = NULL;
- static double last_https = 0.0;
- static char last_get[256];
- static int first = 1;
- unsigned char *rb;
-
-#if !LIBVNCSERVER_HAVE_LIBSSL
- if (enc_str == NULL || strcmp(enc_str, "none")) {
- badnews("0 accept_openssl");
- }
-#endif
-
- openssl_last_helper_pid = 0;
-
- /* zero buffers for use below. */
- for (i=0; i<256; i++) {
- if (first) {
- last_get[i] = '\0';
- }
- cookie[i] = '\0';
- rcookie[i] = '\0';
- }
- first = 0;
-
- if (getenv("ACCEPT_OPENSSL_DEBUG")) {
- db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
- }
-
- /* do INETD, VNC, or HTTPS cases (result is client socket or pipe) */
- if (mode == OPENSSL_INETD) {
- ssl_initialized = 1;
-
- } else if (mode == OPENSSL_VNC) {
- sock = accept(openssl_sock, (struct sockaddr *)&addr, &addrlen);
- if (sock < 0) {
- rfbLog("SSL: accept_openssl: accept connection failed\n");
- rfbLogPerror("accept");
- if (ssl_no_fail) {
- clean_up_exit(1);
- }
- return;
- }
- listen = openssl_sock;
-
- } else if (mode == OPENSSL_VNC6 || mode == OPENSSL_HTTPS6) {
-#if X11VNC_IPV6
- struct sockaddr_in6 a6;
- socklen_t a6len = sizeof(a6);
- int fd = (mode == OPENSSL_VNC6 ? openssl_sock6 : https_sock6);
-
- sock = accept(fd, (struct sockaddr *)&a6, &a6len);
- if (sock < 0) {
- rfbLog("SSL: accept_openssl: accept connection failed\n");
- rfbLogPerror("accept");
- if (ssl_no_fail) {
- clean_up_exit(1);
- }
- return;
- }
- ipv6_name = ipv6_getipaddr((struct sockaddr *)&a6, a6len);
- if (!ipv6_name) ipv6_name = strdup("unknown");
- listen = fd;
-#endif
- } else if (mode == OPENSSL_REVERSE) {
- sock = presock;
- if (sock < 0) {
- rfbLog("SSL: accept_openssl: connection failed\n");
- if (ssl_no_fail) {
- clean_up_exit(1);
- }
- return;
- }
- if (getenv("OPENSSL_REVERSE_DEBUG")) fprintf(stderr, "OPENSSL_REVERSE: ipv6_client_ip_str: %s\n", ipv6_client_ip_str);
- if (ipv6_client_ip_str != NULL) {
- ipv6_name = strdup(ipv6_client_ip_str);
- }
- listen = -1;
-
- } else if (mode == OPENSSL_HTTPS) {
- sock = accept(https_sock, (struct sockaddr *)&addr, &addrlen);
- if (sock < 0) {
- rfbLog("SSL: accept_openssl: accept connection failed\n");
- rfbLogPerror("accept");
- if (ssl_no_fail) {
- clean_up_exit(1);
- }
- return;
- }
- listen = https_sock;
- }
- if (db) fprintf(stderr, "SSL: accept_openssl: sock: %d\n", sock);
-
- if (openssl_last_ip) {
- free(openssl_last_ip);
- openssl_last_ip = NULL;
- }
- if (mode == OPENSSL_INETD) {
- openssl_last_ip = get_remote_host(fileno(stdin));
- } else if (mode == OPENSSL_VNC6 || mode == OPENSSL_HTTPS6) {
- openssl_last_ip = ipv6_name;
- } else if (mode == OPENSSL_REVERSE && ipv6_name != NULL) {
- openssl_last_ip = ipv6_name;
- } else {
- openssl_last_ip = get_remote_host(sock);
- }
-
- if (!check_ssl_access(openssl_last_ip)) {
- rfbLog("SSL: accept_openssl: denying client %s\n", openssl_last_ip);
- rfbLog("SSL: accept_openssl: does not match -allow or other reason.\n");
- close(sock);
- sock = -1;
- if (ssl_no_fail) {
- clean_up_exit(1);
- }
- return;
- }
-
- /* now make a listening socket for child to connect back to us by: */
-
- cport = find_free_port(20000, 22000);
- if (! cport && ipv6_listen) {
- rfbLog("SSL: accept_openssl: seeking IPv6 port.\n");
- cport = find_free_port6(20000, 22000);
- rfbLog("SSL: accept_openssl: IPv6 port: %d\n", cport);
- }
- if (! cport) {
- rfbLog("SSL: accept_openssl: could not find open port.\n");
- close(sock);
- if (mode == OPENSSL_INETD || ssl_no_fail) {
- clean_up_exit(1);
- }
- return;
- }
- if (db) fprintf(stderr, "accept_openssl: cport: %d\n", cport);
-
- csock = listen_tcp(cport, htonl(INADDR_LOOPBACK), 1);
-
- if (csock < 0) {
- rfbLog("SSL: accept_openssl: could not listen on port %d.\n",
- cport);
- close(sock);
- if (mode == OPENSSL_INETD || ssl_no_fail) {
- clean_up_exit(1);
- }
- return;
- }
- if (db) fprintf(stderr, "accept_openssl: csock: %d\n", csock);
-
- fflush(stderr);
-
- /*
- * make a simple cookie to id the child socket, not foolproof
- * but hard to guess exactly (just worrying about local lusers
- * here, since we use INADDR_LOOPBACK).
- */
- rb = (unsigned char *) calloc(6, 1);
-#if LIBVNCSERVER_HAVE_LIBSSL
- RAND_bytes(rb, 6);
-#endif
- sprintf(cookie, "RB=%d%d%d%d%d%d/%f%f/%p",
- rb[0], rb[1], rb[2], rb[3], rb[4], rb[5],
- dnow() - x11vnc_start, x11vnc_start, (void *)rb);
-
- if (mode == OPENSSL_VNC6) {
- name = strdup(ipv6_name);
- peerport = get_remote_port(sock);
- } else if (mode == OPENSSL_REVERSE && ipv6_name != NULL) {
- name = strdup(ipv6_name);
- peerport = get_remote_port(sock);
- } else if (mode != OPENSSL_INETD) {
- name = get_remote_host(sock);
- peerport = get_remote_port(sock);
- } else {
- openssl_last_ip = get_remote_host(fileno(stdin));
- peerport = get_remote_port(fileno(stdin));
- if (openssl_last_ip) {
- name = strdup(openssl_last_ip);
- } else {
- name = strdup("unknown");
- }
- }
- if (name) {
- if (mode == OPENSSL_INETD) {
- rfbLog("SSL: (inetd) spawning helper process "
- "to handle: %s:%d\n", name, peerport);
- } else {
- rfbLog("SSL: spawning helper process to handle: "
- "%s:%d\n", name, peerport);
- }
- free(name);
- name = NULL;
- }
-
- if (certret) {
- free(certret);
- }
- if (certret_str) {
- free(certret_str);
- certret_str = NULL;
- }
- certret = strdup("/tmp/x11vnc-certret.XXXXXX");
- omode = umask(077);
- certret_fd = mkstemp(certret);
- umask(omode);
- if (certret_fd < 0) {
- free(certret);
- certret = NULL;
- certret_fd = -1;
- }
-
- if (dhret) {
- free(dhret);
- }
- if (dhret_str) {
- free(dhret_str);
- dhret_str = NULL;
- }
- dhret = strdup("/tmp/x11vnc-dhret.XXXXXX");
- omode = umask(077);
- dhret_fd = mkstemp(dhret);
- umask(omode);
- if (dhret_fd < 0) {
- free(dhret);
- dhret = NULL;
- dhret_fd = -1;
- }
-
- /* now fork the child to handle the SSL: */
- pid = fork();
-
- if (pid > 0) {
- rfbLog("SSL: helper for peerport %d is pid %d: \n",
- peerport, (int) pid);
- }
-
- if (pid < 0) {
- rfbLog("SSL: accept_openssl: could not fork.\n");
- rfbLogPerror("fork");
- close(sock);
- close(csock);
- if (mode == OPENSSL_INETD || ssl_no_fail) {
- clean_up_exit(1);
- }
- return;
-
- } else if (pid == 0) {
- int s_in, s_out, httpsock = -1;
- int vncsock;
- int i, have_httpd = 0;
- int f_in = fileno(stdin);
- int f_out = fileno(stdout);
- int skip_vnc_tls = mode == OPENSSL_HTTPS ? 1 : 0;
-
- if (db) fprintf(stderr, "helper pid in: %d %d %d %d\n", f_in, f_out, sock, listen);
-
- /* reset all handlers to default (no interrupted() calls) */
- unset_signals();
-
- /* close all non-essential fd's */
- for (i=0; i<256; i++) {
- if (mode == OPENSSL_INETD) {
- if (i == f_in || i == f_out) {
- continue;
- }
- }
- if (i == sock) {
- continue;
- }
- if (i == 2) {
- continue;
- }
- close(i);
- }
-
- /*
- * sadly, we are a long lived child and so the large
- * framebuffer memory areas will soon differ from parent.
- * try to free as much as possible.
- */
- lose_ram();
-
- /* now connect back to parent socket: */
- vncsock = connect_tcp("127.0.0.1", cport);
- if (vncsock < 0) {
- rfbLog("SSL: ssl_helper[%d]: could not connect"
- " back to: %d\n", getpid(), cport);
- rfbLog("SSL: ssl_helper[%d]: exit case 1 (no local vncsock)\n", getpid());
- exit(1);
- }
- if (db) fprintf(stderr, "vncsock %d\n", vncsock);
-
- /* try to initialize SSL with the remote client */
-
- if (mode == OPENSSL_INETD) {
- s_in = fileno(stdin);
- s_out = fileno(stdout);
- } else {
- s_in = s_out = sock;
- }
-
- if (! ssl_init(s_in, s_out, skip_vnc_tls, last_https)) {
- close(vncsock);
- rfbLog("SSL: ssl_helper[%d]: exit case 2 (ssl_init failed)\n", getpid());
- exit(1);
- }
-
- if (vencrypt_selected != 0) {
- char *tbuf;
- tbuf = (char *) malloc(strlen(cookie) + 100);
- sprintf(tbuf, "%s,VENCRYPT=%d,%s", uniq, vencrypt_selected, cookie);
- write(vncsock, tbuf, strlen(cookie));
- goto wrote_cookie;
- } else if (anontls_selected != 0) {
- char *tbuf;
- tbuf = (char *) malloc(strlen(cookie) + 100);
- sprintf(tbuf, "%s,ANONTLS=%d,%s", uniq, anontls_selected, cookie);
- write(vncsock, tbuf, strlen(cookie));
- goto wrote_cookie;
- }
-
- /*
- * things get messy below since we are trying to do
- * *both* VNC and Java applet httpd through the same
- * SSL socket.
- */
-
- if (! screen) {
- close(vncsock);
- exit(1);
- }
- if (screen->httpListenSock >= 0 && screen->httpPort > 0) {
- have_httpd = 1;
- } else if (ipv6_http_fd >= 0) {
- have_httpd = 1;
- } else if (screen->httpListenSock == -2) {
- have_httpd = 1;
- }
- if (mode == OPENSSL_HTTPS && ! have_httpd) {
- rfbLog("SSL: accept_openssl[%d]: no httpd socket for "
- "-https mode\n", getpid());
- close(vncsock);
- rfbLog("SSL: ssl_helper[%d]: exit case 3 (no httpd sock)\n", getpid());
- exit(1);
- }
-
- if (have_httpd) {
- int n = 0, is_http = 0;
- int hport = screen->httpPort;
- char *iface = NULL;
- char *buf, *tbuf;
-
- buf = (char *) calloc((ABSIZE+1), 1);
- tbuf = (char *) calloc((2*ABSIZE+1), 1);
-
- if (mode == OPENSSL_HTTPS) {
- /*
- * for this mode we know it is HTTP traffic
- * so we skip trying to guess.
- */
- is_http = 1;
- n = 0;
- goto connect_to_httpd;
- }
-
- /*
- * Check if there is stuff to read from remote end
- * if so it is likely a GET or HEAD.
- */
- if (! is_ssl_readable(s_in, last_https, last_get,
- mode)) {
- goto write_cookie;
- }
-
- /*
- * read first 2 bytes to try to guess. sadly,
- * the user is often pondering a "non-verified
- * cert" dialog for a long time before the GET
- * is ever sent. So often we timeout here.
- */
-
- if (db) fprintf(stderr, "watch_for_http_traffic\n");
-
- is_http = watch_for_http_traffic(buf, &n, s_in);
-
- if (is_http < 0 || is_http == 0) {
- /*
- * error or http not detected, fall back
- * to normal VNC socket.
- */
- if (db) fprintf(stderr, "is_http err: %d n: %d\n", is_http, n);
- write(vncsock, cookie, strlen(cookie));
- if (n > 0) {
- write(vncsock, buf, n);
- }
- goto wrote_cookie;
- }
-
- if (db) fprintf(stderr, "is_http: %d n: %d\n",
- is_http, n);
- if (db) fprintf(stderr, "buf: '%s'\n", buf);
-
- if (strstr(buf, "/request.https.vnc.connection")) {
- char reply[] = "HTTP/1.0 200 OK\r\n"
- "Content-Type: octet-stream\r\n"
- "Connection: Keep-Alive\r\n"
- "VNC-Server: x11vnc\r\n"
- "Pragma: no-cache\r\n\r\n";
- /*
- * special case proxy coming thru https
- * instead of a direct SSL connection.
- */
- rfbLog("Handling VNC request via https GET. [%d]\n", getpid());
- rfbLog("-- %s\n", buf);
-
- if (strstr(buf, "/reverse.proxy")) {
- char *buf2;
- int n, ptr;
-#if !LIBVNCSERVER_HAVE_LIBSSL
- write(s_out, reply, strlen(reply));
-#else
- SSL_write(ssl, reply, strlen(reply));
-#endif
-
- buf2 = (char *) calloc((8192+1), 1);
- n = 0;
- ptr = 0;
- while (ptr < 8192) {
-#if !LIBVNCSERVER_HAVE_LIBSSL
- n = read(s_in, buf2 + ptr, 1);
-#else
- n = SSL_read(ssl, buf2 + ptr, 1);
-#endif
- if (n > 0) {
- ptr += n;
- }
- if (db) fprintf(stderr, "buf2: '%s'\n", buf2);
-
- if (strstr(buf2, "\r\n\r\n")) {
- break;
- }
- }
- free(buf2);
- }
- goto write_cookie;
-
- } else if (strstr(buf, "/check.https.proxy.connection")) {
- char reply[] = "HTTP/1.0 200 OK\r\n"
- "Connection: close\r\n"
- "Content-Type: octet-stream\r\n"
- "VNC-Server: x11vnc\r\n"
- "Pragma: no-cache\r\n\r\n";
-
- rfbLog("Handling Check HTTPS request via https GET. [%d]\n", getpid());
- rfbLog("-- %s\n", buf);
-
-#if !LIBVNCSERVER_HAVE_LIBSSL
- write(s_out, reply, strlen(reply));
-#else
- SSL_write(ssl, reply, strlen(reply));
- SSL_shutdown(ssl);
-#endif
-
- strcpy(tbuf, uniq);
- strcat(tbuf, cookie);
- write(vncsock, tbuf, strlen(tbuf));
- close(vncsock);
-
- rfbLog("SSL: ssl_helper[%d]: exit case 4 (check.https.proxy.connection)\n", getpid());
- exit(0);
- }
- connect_to_httpd:
-
- /*
- * Here we go... no turning back. we have to
- * send failure to parent and close socket to have
- * http processed at all in a timely fashion...
- */
-
- /* send the failure tag: */
- strcpy(tbuf, uniq);
-
- if (https_port_redir < 0 || (strstr(buf, "PORT=") || strstr(buf, "port="))) {
- char *q = strstr(buf, "Host:");
- int fport = 443, match = 0;
- char num[16];
-
- if (q && strstr(q, "\n")) {
- q += strlen("Host:") + 1;
- while (*q != '\n') {
- int p;
- if (*q == ':' && sscanf(q, ":%d", &p) == 1) {
- if (p > 0 && p < 65536) {
- fport = p;
- match = 1;
- break;
- }
- }
- q++;
- }
- }
- if (!match || !https_port_redir) {
- int p;
- if (sscanf(buf, "PORT=%d,", &p) == 1) {
- if (p > 0 && p < 65536) {
- fport = p;
- }
- } else if (sscanf(buf, "port=%d,", &p) == 1) {
- if (p > 0 && p < 65536) {
- fport = p;
- }
- }
- }
- sprintf(num, "HP=%d,", fport);
- strcat(tbuf, num);
- }
-
- if (strstr(buf, "HTTP/") != NULL) {
- char *q, *str;
- /*
- * Also send back the GET line for heuristics.
- * (last_https, get file).
- */
- str = strdup(buf);
- q = strstr(str, "HTTP/");
- if (q != NULL) {
- *q = '\0';
- strcat(tbuf, str);
- }
- free(str);
- }
-
- /*
- * Also send the cookie to pad out the number of
- * bytes to more than the parent wants to read.
- * Since this is the failure case, it does not
- * matter that we send more than strlen(cookie).
- */
- strcat(tbuf, cookie);
- write(vncsock, tbuf, strlen(tbuf));
-
- usleep(150*1000);
- if (db) fprintf(stderr, "close vncsock: %d\n", vncsock);
- close(vncsock);
-
- /* now, finally, connect to the libvncserver httpd: */
- if (screen->listenInterface == htonl(INADDR_ANY) ||
- screen->listenInterface == htonl(INADDR_NONE)) {
- iface = "127.0.0.1";
- } else {
- struct in_addr in;
- in.s_addr = screen->listenInterface;
- iface = inet_ntoa(in);
- }
- if (iface == NULL || !strcmp(iface, "")) {
- iface = "127.0.0.1";
- }
- if (db) fprintf(stderr, "iface: %s:%d\n", iface, hport);
- usleep(150*1000);
-
- httpsock = connect_tcp(iface, hport);
-
- if (httpsock < 0) {
- /* UGH, after all of that! */
- rfbLog("Could not connect to httpd socket!\n");
- rfbLog("SSL: ssl_helper[%d]: exit case 5.\n", getpid());
- exit(1);
- }
- if (db) fprintf(stderr, "ssl_helper[%d]: httpsock: %d %d\n",
- getpid(), httpsock, n);
-
- /*
- * send what we read to httpd, and then connect
- * the rest of the SSL session to it:
- */
- if (n > 0) {
- char *s = getenv("X11VNC_EXTRA_HTTPS_PARAMS");
- int did_extra = 0;
-
- if (db) fprintf(stderr, "sending http buffer httpsock: %d n=%d\n'%s'\n", httpsock, n, buf);
- if (s != NULL) {
- char *q = strstr(buf, " HTTP/");
- if (q) {
- int m;
- *q = '\0';
- m = strlen(buf);
- write(httpsock, buf, m);
- write(httpsock, s, strlen(s));
- *q = ' ';
- write(httpsock, q, n-m);
- did_extra = 1;
- }
- }
- if (!did_extra) {
- write(httpsock, buf, n);
- }
- }
- ssl_xfer(httpsock, s_in, s_out, is_http);
- rfbLog("SSL: ssl_helper[%d]: exit case 6 (https ssl_xfer done)\n", getpid());
- exit(0);
- }
-
- /*
- * ok, back from the above https mess, simply send the
- * cookie back to the parent (who will attach us to
- * libvncserver), and connect the rest of the SSL session
- * to it.
- */
- write_cookie:
- write(vncsock, cookie, strlen(cookie));
-
- wrote_cookie:
- ssl_xfer(vncsock, s_in, s_out, 0);
- rfbLog("SSL: ssl_helper[%d]: exit case 7 (ssl_xfer done)\n", getpid());
- if (0) usleep(50 * 1000);
- exit(0);
- }
- /* parent here */
-
- if (mode != OPENSSL_INETD) {
- close(sock);
- }
- if (db) fprintf(stderr, "helper process is: %d\n", pid);
-
- /* accept connection from our child. */
- signal(SIGALRM, csock_timeout);
- csock_timeout_sock = csock;
- alarm(20);
-
- vsock = accept(csock, (struct sockaddr *)&addr, &addrlen);
-
- alarm(0);
- signal(SIGALRM, SIG_DFL);
- close(csock);
-
-
- if (vsock < 0) {
- rfbLog("SSL: accept_openssl: connection from ssl_helper[%d] FAILED.\n", pid);
- rfbLogPerror("accept");
-
- kill(pid, SIGTERM);
- waitpid(pid, &status, WNOHANG);
- if (mode == OPENSSL_INETD || ssl_no_fail) {
- clean_up_exit(1);
- }
- if (certret_fd >= 0) {
- close(certret_fd);
- certret_fd = -1;
- }
- if (certret) {
- unlink(certret);
- }
- if (dhret_fd >= 0) {
- close(dhret_fd);
- dhret_fd = -1;
- }
- if (dhret) {
- unlink(dhret);
- }
- return;
- }
- if (db) fprintf(stderr, "accept_openssl: vsock: %d\n", vsock);
-
- n = read(vsock, rcookie, strlen(cookie));
- if (n < 0 && errno != 0) {
- rfbLogPerror("read");
- }
-
- if (certret) {
- struct stat sbuf;
- sbuf.st_size = 0;
- if (certret_fd >= 0 && stat(certret, &sbuf) == 0 && sbuf.st_size > 0) {
- certret_str = (char *) calloc(sbuf.st_size+1, 1);
- read(certret_fd, certret_str, sbuf.st_size);
- close(certret_fd);
- certret_fd = -1;
- }
- if (certret_fd >= 0) {
- close(certret_fd);
- certret_fd = -1;
- }
- unlink(certret);
- if (certret_str && strstr(certret_str, "NOCERT") == certret_str) {
- free(certret_str);
- certret_str = NULL;
- }
- if (0 && certret_str) {
- fprintf(stderr, "certret_str[%d]:\n%s\n", (int) sbuf.st_size, certret_str);
- }
- }
-
- if (dhret) {
- struct stat sbuf;
- sbuf.st_size = 0;
- if (dhret_fd >= 0 && stat(dhret, &sbuf) == 0 && sbuf.st_size > 0) {
- dhret_str = (char *) calloc(sbuf.st_size+1, 1);
- read(dhret_fd, dhret_str, sbuf.st_size);
- close(dhret_fd);
- dhret_fd = -1;
- }
- if (dhret_fd >= 0) {
- close(dhret_fd);
- dhret_fd = -1;
- }
- unlink(dhret);
- if (dhret_str && strstr(dhret_str, "NOCERT") == dhret_str) {
- free(dhret_str);
- dhret_str = NULL;
- }
- if (dhret_str) {
- if (new_dh_params == NULL) {
- fprintf(stderr, "dhret_str[%d]:\n%s\n", (int) sbuf.st_size, dhret_str);
- new_dh_params = strdup(dhret_str);
- }
- }
- }
-
- if (0) {
- fprintf(stderr, "rcookie: %s\n", rcookie);
- fprintf(stderr, "cookie: %s\n", cookie);
- }
-
- if (strstr(rcookie, uniq) == rcookie) {
- char *q = strstr(rcookie, "RB=");
- if (q && strstr(cookie, q) == cookie) {
- vencrypt_sel = 0;
- anontls_sel = 0;
- q = strstr(rcookie, "VENCRYPT=");
- if (q && sscanf(q, "VENCRYPT=%d,", &vencrypt_sel) == 1) {
- if (vencrypt_sel != 0) {
- rfbLog("SSL: VENCRYPT mode=%d accepted. helper[%d]\n", vencrypt_sel, pid);
- goto accept_client;
- }
- }
- q = strstr(rcookie, "ANONTLS=");
- if (q && sscanf(q, "ANONTLS=%d,", &anontls_sel) == 1) {
- if (anontls_sel != 0) {
- rfbLog("SSL: ANONTLS mode=%d accepted. helper[%d]\n", anontls_sel, pid);
- goto accept_client;
- }
- }
- }
- }
-
- if (n != (int) strlen(cookie) || strncmp(cookie, rcookie, n)) {
- rfbLog("SSL: accept_openssl: cookie from ssl_helper[%d] FAILED. %d\n", pid, n);
- if (db) fprintf(stderr, "'%s'\n'%s'\n", cookie, rcookie);
- close(vsock);
-
- if (strstr(rcookie, uniq) == rcookie) {
- int i;
- double https_download_wait_time = 15.0;
-
- if (getenv("X11VNC_HTTPS_DOWNLOAD_WAIT_TIME")) {
- https_download_wait_time = atof(getenv("X11VNC_HTTPS_DOWNLOAD_WAIT_TIME"));
- }
-
- rfbLog("SSL: BUT WAIT! HTTPS for helper process[%d] succeeded. Good.\n", pid);
- if (mode != OPENSSL_HTTPS) {
- last_https = dnow();
- for (i=0; i<256; i++) {
- last_get[i] = '\0';
- }
- strncpy(last_get, rcookie, 100);
- if (db) fprintf(stderr, "last_get: '%s'\n", last_get);
- }
- if (rcookie && strstr(rcookie, "VncViewer.class")) {
- rfbLog("\n");
- rfbLog("helper[%d]:\n", pid);
- rfbLog("***********************************************************\n");
- rfbLog("SSL: WARNING CLIENT ASKED FOR NONEXISTENT 'VncViewer.class'\n");
- rfbLog("SSL: USER NEEDS TO MAKE SURE THE JAVA PLUGIN IS INSTALLED\n");
- rfbLog("SSL: AND WORKING PROPERLY (e.g. a test-java-plugin page.)\n");
- rfbLog("SSL: AND/OR USER NEEDS TO **RESTART** HIS WEB BROWSER.\n");
- rfbLog("SSL: SOMETIMES THE BROWSER 'REMEMBERS' FAILED APPLET DOWN-\n");
- rfbLog("SSL: LOADS AND RESTARTING IT IS THE ONLY WAY TO FIX THINGS.\n");
- rfbLog("***********************************************************\n");
- rfbLog("\n");
- }
- ssl_helper_pid(pid, -2);
-
- if (https_port_redir) {
- double start;
- int origport = screen->port;
- int useport = screen->port;
- int saw_httpsock = 0;
- /* to expand $PORT correctly in index.vnc */
- if (https_port_redir < 0) {
- char *q = strstr(rcookie, "HP=");
- if (q) {
- int p;
- if (sscanf(q, "HP=%d,", &p) == 1) {
- useport = p;
- }
- }
- } else {
- useport = https_port_redir;
- }
- screen->port = useport;
- if (origport != useport) {
- rfbLog("SSL: -httpsredir guess port: %d helper[%d]\n", screen->port, pid);
- }
-
- start = dnow();
- while (dnow() < start + https_download_wait_time) {
- if (screen->httpSock >= 0) saw_httpsock = 1;
- rfbPE(10000);
- usleep(10000);
- if (screen->httpSock >= 0) saw_httpsock = 1;
- waitpid(pid, &status, WNOHANG);
- if (kill(pid, 0) != 0) {
- rfbLog("SSL: helper[%d] pid finished\n", pid);
- break;
- }
- if (0 && saw_httpsock && screen->httpSock < 0) {
- /* this check can kill the helper too soon. */
- rfbLog("SSL: httpSock for helper[%d] went away\n", pid);
- break;
- }
- }
- rfbLog("SSL: guessing child helper[%d] https finished. dt=%.6f\n",
- pid, dnow() - start);
-
- rfbPE(10000);
- rfbPE(10000);
- rfbPE(10000);
-
- screen->port = origport;
- ssl_helper_pid(0, -2);
- if (mode == OPENSSL_INETD) {
- clean_up_exit(1);
- }
- } else if (mode == OPENSSL_INETD) {
- double start;
- int saw_httpsock = 0;
-
- /* to expand $PORT correctly in index.vnc */
- if (screen->port == 0) {
- int fd = fileno(stdin);
- if (getenv("X11VNC_INETD_PORT")) {
- /* mutex */
- screen->port = atoi(getenv(
- "X11VNC_INETD_PORT"));
- } else {
- int tport = get_local_port(fd);
- if (tport > 0) {
- screen->port = tport;
- }
- }
- }
- rfbLog("SSL: screen->port %d for helper[%d]\n", screen->port, pid);
-
- /* kludge for https fetch via inetd */
- start = dnow();
- while (dnow() < start + https_download_wait_time) {
- if (screen->httpSock >= 0) saw_httpsock = 1;
- rfbPE(10000);
- usleep(10000);
- if (screen->httpSock >= 0) saw_httpsock = 1;
- waitpid(pid, &status, WNOHANG);
- if (kill(pid, 0) != 0) {
- rfbLog("SSL: helper[%d] pid finished\n", pid);
- break;
- }
- if (0 && saw_httpsock && screen->httpSock < 0) {
- /* this check can kill the helper too soon. */
- rfbLog("SSL: httpSock for helper[%d] went away\n", pid);
- break;
- }
- }
- rfbLog("SSL: OPENSSL_INETD guessing "
- "child helper[%d] https finished. dt=%.6f\n",
- pid, dnow() - start);
-
- rfbPE(10000);
- rfbPE(10000);
- rfbPE(10000);
-
- ssl_helper_pid(0, -2);
- clean_up_exit(1);
- }
- /* this will actually only get earlier https */
- ssl_helper_pid(0, -2);
- return;
- }
- kill(pid, SIGTERM);
- waitpid(pid, &status, WNOHANG);
- if (mode == OPENSSL_INETD || ssl_no_fail) {
- clean_up_exit(1);
- }
- return;
- }
-
- accept_client:
-
- if (db) fprintf(stderr, "accept_openssl: cookie good: %s\n", cookie);
-
- rfbLog("SSL: handshake with helper process[%d] succeeded.\n", pid);
-
- openssl_last_helper_pid = pid;
- ssl_helper_pid(pid, vsock);
-
- if (vnc_redirect) {
- vnc_redirect_sock = vsock;
- openssl_last_helper_pid = 0;
- return;
- }
-
- client = create_new_client(vsock, 0);
- openssl_last_helper_pid = 0;
-
- if (client) {
- int swt = 0;
- if (mode == OPENSSL_VNC6 && openssl_last_ip != NULL) {
- swt = 1;
- } else if (mode == OPENSSL_REVERSE && ipv6_name != NULL && openssl_last_ip != NULL) {
- swt = 1;
- }
- if (swt) {
- if (client->host) {
- free(client->host);
- }
- client->host = strdup(openssl_last_ip);
- }
- if (db) fprintf(stderr, "accept_openssl: client %p\n", (void *) client);
- if (db) fprintf(stderr, "accept_openssl: new_client %p\n", (void *) screen->newClientHook);
- if (db) fprintf(stderr, "accept_openssl: new_client %p\n", (void *) new_client);
- if (mode == OPENSSL_INETD) {
- inetd_client = client;
- client->clientGoneHook = client_gone;
- }
- if (openssl_last_ip &&
- strpbrk(openssl_last_ip, "0123456789") == openssl_last_ip) {
- client->host = strdup(openssl_last_ip);
- }
- if (vencrypt_sel != 0) {
- client->protocolMajorVersion = 3;
- client->protocolMinorVersion = 8;
-#if LIBVNCSERVER_HAVE_LIBSSL
- if (!finish_vencrypt_auth(client, vencrypt_sel)) {
- rfbCloseClient(client);
- client = NULL;
- }
-#else
- badnews("3 accept_openssl");
-#endif
- } else if (anontls_sel != 0) {
- client->protocolMajorVersion = 3;
- client->protocolMinorVersion = 8;
- rfbAuthNewClient(client);
- }
- if (use_threads && client != NULL) {
- rfbStartOnHoldClient(client);
- }
- /* try to get RFB proto done now. */
- progress_client();
- } else {
- rfbLog("SSL: accept_openssl: rfbNewClient failed.\n");
- close(vsock);
-
- kill(pid, SIGTERM);
- waitpid(pid, &status, WNOHANG);
- if (mode == OPENSSL_INETD || ssl_no_fail) {
- clean_up_exit(1);
- }
- return;
- }
-}
-
-void raw_xfer(int csock, int s_in, int s_out) {
- char buf0[8192];
- int sz = 8192, n, m, status, db = 1;
- char *buf;
-#ifdef FORK_OK
- pid_t par = getpid();
- pid_t pid = fork();
-
- buf = buf0;
- if (vnc_redirect) {
- /* change buf size some direction. */
- }
-
- 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);
-
- while (1) {
- n = read(csock, buf, sz);
- if (n == 0 || (n < 0 && errno != EINTR) ) {
- break;
- } else if (n > 0) {
- int len = n;
- char *src = buf;
- if (db > 1) write(2, buf, n);
- while (len > 0) {
- m = write(s_out, src, len);
- if (m > 0) {
- src += m;
- len -= m;
- continue;
- }
- if (m < 0 && (errno == EINTR || errno == EAGAIN)) {
- continue;
- }
-if (db) rfbLog("raw_xfer bad write: %d -> %d | %d/%d errno=%d\n", csock, s_out, m, n, errno);
- break;
- }
- }
- }
- usleep(250*1000);
- kill(pid, SIGTERM);
- waitpid(pid, &status, WNOHANG);
- if (db) rfbLog("raw_xfer done: %d -> %d\n", csock, s_out);
-
- } else {
- if (db) usleep(50*1000);
- if (db) rfbLog("raw_xfer start: %d <- %d\n", csock, s_in);
-
- while (1) {
- n = read(s_in, buf, sz);
- if (n == 0 || (n < 0 && errno != EINTR) ) {
- break;
- } else if (n > 0) {
- int len = n;
- char *src = buf;
- if (db > 1) write(2, buf, n);
- while (len > 0) {
- m = write(csock, src, len);
- if (m > 0) {
- src += m;
- len -= m;
- continue;
- }
- if (m < 0 && (errno == EINTR || errno == EAGAIN)) {
- continue;
- }
- if (db) rfbLog("raw_xfer bad write: %d <- %d | %d/%d errno=%d\n", csock, s_in, m, n, errno);
- break;
- }
- }
- }
- usleep(250*1000);
- kill(par, SIGTERM);
- waitpid(par, &status, WNOHANG);
- if (db) rfbLog("raw_xfer done: %d <- %d\n", csock, s_in);
- }
- close(csock);
- close(s_in);
- close(s_out);
-#endif /* FORK_OK */
-}
-
-/* compile with -DENC_HAVE_OPENSSL=0 to disable enc stuff but still have ssl */
-
-#define ENC_MODULE
-
-#if LIBVNCSERVER_HAVE_LIBSSL
-#ifndef ENC_HAVE_OPENSSL
-#define ENC_HAVE_OPENSSL 1
-#endif
-#else
-#define ENC_HAVE_OPENSSL 0
-#endif
-
-#define ENC_DISABLE_SHOW_CERT
-
-#include "enc.h"
-
-static void symmetric_encryption_xfer(int csock, int s_in, int s_out) {
- char tmp[100];
- char *cipher, *keyfile, *q;
-
- if (! enc_str) {
- return;
- }
- cipher = (char *) malloc(strlen(enc_str) + 100);
- q = strchr(enc_str, ':');
- if (!q) return;
- *q = '\0';
- if (getenv("X11VNC_USE_ULTRADSM_IV")) {
- sprintf(cipher, "rev:%s", enc_str);
- } else {
- sprintf(cipher, "noultra:rev:%s", enc_str);
- }
- keyfile = strdup(q+1);
- *q = ':';
-
-
- /* TBD: s_in != s_out */
- if (s_out) {}
-
- sprintf(tmp, "fd=%d,%d", s_in, csock);
-
- enc_do(cipher, keyfile, "-1", tmp);
-}
-
diff --git a/x11vnc/sslhelper.h b/x11vnc/sslhelper.h
deleted file mode 100644
index 236db73..0000000
--- a/x11vnc/sslhelper.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_SSLHELPER_H
-#define _X11VNC_SSLHELPER_H
-
-/* -- sslhelper.h -- */
-
-
-#define OPENSSL_INETD 1
-#define OPENSSL_VNC 2
-#define OPENSSL_VNC6 3
-#define OPENSSL_HTTPS 4
-#define OPENSSL_HTTPS6 5
-#define OPENSSL_REVERSE 6
-
-extern int openssl_sock;
-extern int openssl_sock6;
-extern int openssl_port_num;
-extern int https_sock;
-extern int https_sock6;
-extern pid_t openssl_last_helper_pid;
-extern char *openssl_last_ip;
-extern char *certret_str;
-extern char *dhret_str;
-extern char *new_dh_params;
-
-extern void raw_xfer(int csock, int s_in, int s_out);
-
-extern int openssl_present(void);
-extern void openssl_init(int);
-extern void openssl_port(int);
-extern void https_port(int);
-extern void check_openssl(void);
-extern void check_https(void);
-extern void ssl_helper_pid(pid_t pid, int sock);
-extern void accept_openssl(int mode, int presock);
-extern char *find_openssl_bin(void);
-extern char *get_saved_pem(char *string, int create);
-extern char *get_ssl_verify_file(char *str_in);
-extern char *create_tmp_pem(char *path, int prompt);
-
-
-#endif /* _X11VNC_SSLHELPER_H */
diff --git a/x11vnc/ssltools.h b/x11vnc/ssltools.h
deleted file mode 100644
index b4ad7d0..0000000
--- a/x11vnc/ssltools.h
+++ /dev/null
@@ -1,2560 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _SSLTOOLS_H
-#define _SSLTOOLS_H
-
-/* quoted scripts, edit source not this file. */
-
-
-char genCA[] =
-"#!/bin/sh\n"
-"\n"
-"DIR=$BASE_DIR\n"
-"if [ \"x$DIR\" = \"x\" ]; then\n"
-" DIR=\"$HOME/dotkjr_vnc/certs\"\n"
-" rm -rf \"$DIR\"\n"
-"fi\n"
-"if echo \"$DIR\" | grep '^/' > /dev/null; then\n"
-" :\n"
-"else\n"
-" DIR=\"`pwd`/$DIR\"\n"
-"fi\n"
-"\n"
-"PATH=/usr/bin:/bin:/usr/sbin:$PATH; export PATH\n"
-"if [ \"x$OPENSSL\" = \"x\" ]; then\n"
-" OPENSSL=\"openssl\"\n"
-"fi\n"
-"\n"
-"type \"$OPENSSL\" > /dev/null || exit 1\n"
-"\n"
-"if [ -f \"$DIR/CA/cacert.pem\" ]; then\n"
-" echo \"Files will be overwritten in $DIR/CA\"\n"
-" printf \"Continue? [y]/n \"\n"
-" read x\n"
-" if [ \"x$x\" = \"xn\" ]; then\n"
-" exit 1;\n"
-" fi\n"
-"fi\n"
-"\n"
-"#mkdir -p \"$DIR/HASH\" || exit 1\n"
-"mkdir -p \"$DIR/clients\" || exit 1\n"
-"#mkdir -p \"$DIR/clients/HASH\" || exit 1\n"
-"mkdir -p \"$DIR/CA/certs\" || exit 1\n"
-"mkdir -p \"$DIR/CA/crl\" || exit 1\n"
-"mkdir -p \"$DIR/CA/newcerts\" || exit 1\n"
-"mkdir -p \"$DIR/CA/private\" || exit 1\n"
-"chmod go-rwx \"$DIR/CA/private\" || exit 1\n"
-"mkdir -p \"$DIR/tmp\" || exit 1\n"
-"chmod go-rwx \"$DIR/tmp\" || exit 1\n"
-"touch \"$DIR/CA/index.txt\" || exit 1\n"
-"if [ ! -f \"$DIR/CA/serial\" ]; then\n"
-" echo \"01\" > \"$DIR/CA/serial\" || exit 1\n"
-"fi\n"
-"\n"
-"cnf='\n"
-"HOME = .\n"
-"RANDFILE = $ENV::HOME/.rnd\n"
-"\n"
-"####################################################################\n"
-"[ ca ]\n"
-"default_ca = CA_default # The default ca section\n"
-"\n"
-"####################################################################\n"
-"[ CA_default ]\n"
-"\n"
-"dir = ./CA # Where everything is kept\n"
-"certs = $dir/certs # Where the issued certs are kept\n"
-"crl_dir = $dir/crl # Where the issued crl are kept\n"
-"database = $dir/index.txt # database index file.\n"
-"new_certs_dir = $dir/newcerts # default place for new certs.\n"
-"certificate = $dir/cacert.pem # The CA certificate\n"
-"serial = $dir/serial # The current serial number\n"
-"crl = $dir/crl.pem # The current CRL\n"
-"private_key = $dir/private/cakey.pem # The private key\n"
-"RANDFILE = $dir/private/.rand # private random number file\n"
-"\n"
-"x509_extensions = usr_cert # The extentions to add to the cert\n"
-"\n"
-"name_opt = ca_default # Subject Name options\n"
-"cert_opt = ca_default # Certificate field options\n"
-"\n"
-"default_days = 730 # how long to certify for\n"
-"default_crl_days= 30 # how long before next CRL\n"
-"default_md = md5 # which md to use.\n"
-"preserve = no # keep passed DN ordering\n"
-"\n"
-"policy = policy_match\n"
-"\n"
-"# For the CA policy\n"
-"[ policy_match ]\n"
-"countryName = match\n"
-"stateOrProvinceName = match\n"
-"organizationName = match\n"
-"organizationalUnitName = optional\n"
-"commonName = supplied\n"
-"emailAddress = optional\n"
-"\n"
-"[ policy_anything ]\n"
-"countryName = optional\n"
-"stateOrProvinceName = optional\n"
-"localityName = optional\n"
-"organizationName = optional\n"
-"organizationalUnitName = optional\n"
-"commonName = supplied\n"
-"emailAddress = optional\n"
-"\n"
-"####################################################################\n"
-"[ req ]\n"
-"default_bits = 2048\n"
-"default_keyfile = privkey.pem\n"
-"distinguished_name = req_distinguished_name\n"
-"attributes = req_attributes\n"
-"x509_extensions = v3_ca # The extentions to add to the self signed cert\n"
-"\n"
-"string_mask = nombstr\n"
-"\n"
-"# req_extensions = v3_req # The extensions to add to a certificate request\n"
-"\n"
-"[ req_distinguished_name ]\n"
-"countryName = Country Name (2 letter code)\n"
-"countryName_default = AU\n"
-"countryName_min = 2\n"
-"countryName_max = 2\n"
-"\n"
-"stateOrProvinceName = State or Province Name (full name)\n"
-"stateOrProvinceName_default = mystate\n"
-"\n"
-"localityName = Locality Name (eg, city)\n"
-"\n"
-"0.organizationName = Organization Name (eg, company)\n"
-"0.organizationName_default = x11vnc server CA\n"
-"\n"
-"organizationalUnitName = Organizational Unit Name (eg, section)\n"
-"\n"
-"commonName = Common Name (eg, YOUR name)\n"
-"commonName_default = %USER x11vnc server CA\n"
-"commonName_max = 64\n"
-"\n"
-"emailAddress = Email Address\n"
-"emailAddress_default = x11vnc@CA.nowhere\n"
-"emailAddress_max = 64\n"
-"\n"
-"[ req_attributes ]\n"
-"challengePassword = A challenge password\n"
-"challengePassword_min = 4\n"
-"challengePassword_max = 20\n"
-"\n"
-"unstructuredName = An optional company name\n"
-"\n"
-"[ usr_cert ]\n"
-"\n"
-"basicConstraints=CA:FALSE\n"
-"\n"
-"nsComment = \"OpenSSL Generated Certificate\"\n"
-"\n"
-"subjectKeyIdentifier=hash\n"
-"authorityKeyIdentifier=keyid,issuer:always\n"
-"\n"
-"[ v3_req ]\n"
-"\n"
-"basicConstraints = CA:FALSE\n"
-"keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
-"\n"
-"[ v3_ca ]\n"
-"\n"
-"subjectKeyIdentifier=hash\n"
-"\n"
-"authorityKeyIdentifier=keyid:always,issuer:always\n"
-"\n"
-"basicConstraints = CA:true\n"
-"\n"
-"[ crl_ext ]\n"
-"\n"
-"authorityKeyIdentifier=keyid:always,issuer:always\n"
-"\n"
-"'\n"
-"selfcnf='\n"
-"####################################################################\n"
-"[ req ]\n"
-"default_bits = 2048\n"
-"encrypt_key = yes\n"
-"distinguished_name = req_distinguished_name\n"
-"x509_extensions = cert_type\n"
-"\n"
-"[ req_distinguished_name ]\n"
-"countryName = Country Name (2 letter code)\n"
-"countryName_default = AU\n"
-"countryName_min = 2\n"
-"countryName_max = 2\n"
-"\n"
-"stateOrProvinceName = State or Province Name (full name)\n"
-"stateOrProvinceName_default = mystate\n"
-"\n"
-"localityName = Locality Name (eg, city)\n"
-"\n"
-"0.organizationName = Organization Name (eg, company)\n"
-"0.organizationName_default = x11vnc server self-signed\n"
-"\n"
-"organizationalUnitName = Organizational Unit Name (eg, section)\n"
-"\n"
-"commonName = Common Name (eg, YOUR name)\n"
-"commonName_default = x11vnc server self-signed %NAME\n"
-"commonName_max = 64\n"
-"\n"
-"emailAddress = Email Address\n"
-"emailAddress_default = x11vnc@self-signed.nowhere\n"
-"emailAddress_max = 64\n"
-"\n"
-"[ cert_type ]\n"
-"nsCertType = server\n"
-"\n"
-"'\n"
-"echo \"$cnf\" | sed -e \"s/%USER/$USER/\" \\\n"
-" > \"$DIR/CA/ssl.cnf\" || exit 1\n"
-"echo \"$cnf\" | sed -e \"s/%USER *//\" -e 's/server CA/server %NAME/g' -e 's/@CA/@server/' \\\n"
-" > \"$DIR/CA/ssl.cnf.server\" || exit 1\n"
-"echo \"$cnf\" | sed -e \"s/%USER *//\" -e 's/server CA/client %NAME/g' -e 's/@CA/@client/' \\\n"
-" > \"$DIR/CA/ssl.cnf.client\" || exit 1\n"
-"\n"
-"echo \"$selfcnf\" > \"$DIR/CA/self.cnf.server\" || exit 1\n"
-"echo \"$selfcnf\" | sed -e 's/ server/ client/g' \\\n"
-" > \"$DIR/CA/self.cnf.client\" || exit 1\n"
-"\n"
-"cd \"$DIR\" || exit 1\n"
-"\n"
-"echo \"\"\n"
-"echo \"----------------------------------------------------------------------\"\n"
-"echo \"Generating your x11vnc CA (certificate authority) key and certificate:\"\n"
-"echo \"\"\n"
-"echo \"Please supply a passphrase and any other information you care to.\"\n"
-"echo \"----------------------------------------------------------------------\"\n"
-"echo \"\"\n"
-"\n"
-"req_args=$REQ_ARGS\n"
-"if echo \"$req_args\" | grep 'days' > /dev/null; then\n"
-" :\n"
-"else\n"
-" req_args=\"$req_args -days 730\"\n"
-"fi\n"
-"\n"
-"\"$OPENSSL\" req -config \"$DIR/CA/ssl.cnf\" -new -x509 -days 730 $req_args \\\n"
-" -keyout \"$DIR/CA/private/cakey.pem\" \\\n"
-" -out \"$DIR/CA/cacert.pem\"\n"
-"\n"
-"if [ $? != 0 ]; then\n"
-" echo \"openssl failed.\"\n"
-" exit 1\n"
-"fi\n"
-"\n"
-"chmod go-rwx \"$DIR/CA/private/cakey.pem\"\n"
-"\n"
-"echo \"\"\n"
-"echo \"----------------------------------------------------------------------\"\n"
-"echo \"Your public x11vnc CA cert is:\"\n"
-"echo \"\"\n"
-"echo \" $DIR/CA/cacert.pem\"\n"
-"echo \"\"\n"
-"echo \" It may be copied to other applications, e.g. Web browser, Java\"\n"
-"echo \" Applet keystore, or stunnel cfg, to use to verify signed server\"\n"
-"echo \" or client certs, etc.\"\n"
-"echo \"\"\n"
-"echo \"Your private x11vnc CA key is:\"\n"
-"echo \"\"\n"
-"echo \" $DIR/CA/private/cakey.pem\"\n"
-"echo \"\"\n"
-"echo \" It will be used to sign server or client certs, keep it secret.\"\n"
-"echo \"----------------------------------------------------------------------\"\n"
-"echo \"\"\n"
-"printf \"Press Enter to print the cacert.pem certificate to the screen: \"\n"
-"read x\n"
-"echo \"\"\n"
-"cat \"$DIR/CA/cacert.pem\"\n"
-;
-
-char genCert[] =
-"#!/bin/sh\n"
-"\n"
-"direrror() {\n"
-" echo \"\"\n"
-" echo \"You need first to run:\"\n"
-" echo \"\"\n"
-" if echo \"$DIR\" | grep '/\\.vnc/certs' > /dev/null; then\n"
-" echo \" x11vnc -sslGenCA\"\n"
-" else\n"
-" echo \" x11vnc -sslGenCA $DIR\"\n"
-" fi\n"
-" echo \"\"\n"
-" echo \"to create the CA cert file and other needed config files and directories.\"\n"
-" echo \"\"\n"
-" echo \"Then you can run: x11vnc -sslGenCert $type $name0\"\n"
-" echo \"\"\n"
-" if [ \"X$1\" != \"X\" ]; then\n"
-" echo \"(missing file/dir: $1)\"\n"
-" echo \"\"\n"
-" fi\n"
-" exit 1\n"
-"}\n"
-"\n"
-"make_HASH() {\n"
-" crt=\"$1\"\n"
-" remove=\"$2\"\n"
-" if [ ! -f \"$crt\" ]; then\n"
-" return\n"
-" fi\n"
-" dirhash=`dirname \"$crt\"`/HASH\n"
-" bashash=`basename \"$crt\"`\n"
-" if [ ! -d \"$dirhash\" ]; then\n"
-" return\n"
-" fi\n"
-" hash=`\"$OPENSSL\" x509 -hash -noout -in \"$crt\" 2>/dev/null | head -1`\n"
-" if [ \"X$hash\" != \"X\" ]; then\n"
-" for i in 0 1 2 3 4 5 6 7 8 9\n"
-" do\n"
-" lnk=\"$dirhash/$hash.$i\"\n"
-" if [ \"X$remove\" = \"X1\" ]; then\n"
-" if [ -h \"$lnk\" ]; then\n"
-" if cmp \"$lnk\" \"$crt\" > /dev/null 2>&1; then\n"
-" ls -l \"$lnk\"\n"
-" rm -i \"$lnk\"\n"
-" fi\n"
-" fi\n"
-" else\n"
-" if [ -h \"$lnk\" ]; then\n"
-" if [ ! -f \"$lnk\" ]; then\n"
-" rm -f \"$lnk\" 1>/dev/null 2>&1\n"
-" else\n"
-" continue\n"
-" fi\n"
-" fi\n"
-" if [ \"x$HASH_verbose\" = \"x1\" ]; then\n"
-" echo \"creating: $lnk -> ../$bashash\"\n"
-" fi\n"
-" ln -s \"../$bashash\" \"$lnk\"\n"
-" break\n"
-" fi\n"
-" done\n"
-" fi\n"
-"}\n"
-"\n"
-"create_key() {\n"
-" \n"
-" echo \"----------------------------------------------------------------------\"\n"
-" echo \"Creating new x11vnc certificate and key for name: $type $name0\"\n"
-" echo \"\"\n"
-"\n"
-" req_args=$REQ_ARGS\n"
-" if echo \"$req_args\" | grep 'days' > /dev/null; then\n"
-" :\n"
-" else\n"
-" req_args=\"$req_args -days 730\"\n"
-" fi\n"
-"\n"
-" cnf=\"$DIR/tmp/cnf.$$\"\n"
-" trap \"rm -f \\\"$cnf\\\"\" 0 1 2 15\n"
-"\n"
-" rm -f \"$DIR/$dest.key\" \"$DIR/$dest.crt\" \"$DIR/$dest.req\"\n"
-"\n"
-" if [ \"x$self\" = \"x1\" ]; then\n"
-" if [ ! -f \"$DIR/CA/self.cnf.$type\" ]; then\n"
-" direrror \"$DIR/CA/self.cnf.$type\"\n"
-" fi\n"
-" cat \"$DIR/CA/self.cnf.$type\" | sed -e \"s/%NAME/$name0/\" > \"$cnf\" || exit 1\n"
-" \"$OPENSSL\" req -config \"$cnf\" -nodes -new -newkey rsa:2048 -x509 $req_args \\\n"
-" -keyout \"$DIR/$dest.key\" \\\n"
-" -out \"$DIR/$dest.crt\"\n"
-" else\n"
-" if [ ! -f \"$DIR/CA/ssl.cnf.$type\" ]; then\n"
-" direrror \"$DIR/CA/ssl.cnf.$type\"\n"
-" fi\n"
-" cat \"$DIR/CA/ssl.cnf.$type\" | sed -e \"s/%NAME/$name0/\" > \"$cnf\" || exit 1\n"
-" \"$OPENSSL\" req -config \"$cnf\" -nodes -new -newkey rsa:2048 $req_args \\\n"
-" -keyout \"$DIR/$dest.key\" \\\n"
-" -out \"$DIR/$dest.req\"\n"
-" fi\n"
-" rc=$?\n"
-" if [ -f \"$DIR/$dest.key\" ]; then\n"
-" chmod go-rwx \"$DIR/$dest.key\"\n"
-" fi\n"
-"\n"
-"\n"
-"\n"
-" if [ $rc != 0 ]; then\n"
-" echo \"openssl 'req' command failed\"\n"
-" rm -f \"$DIR/$dest.key\" \"$DIR/$dest.crt\" \"$DIR/$dest.req\"\n"
-" exit 1\n"
-" fi\n"
-"}\n"
-"\n"
-"enc_key() {\n"
-" \n"
-" echo \"\"\n"
-" echo \"----------------------------------------------------------------------\"\n"
-" echo \"Do you want to protect the generated private key with a passphrase?\"\n"
-" echo \"Doing so will significantly decrease the chances someone could steal\"\n"
-" if [ \"x$type\" = \"xserver\" ]; then\n"
-" echo \"the key and pretend to be your x11vnc server. The downside is it is\"\n"
-" else\n"
-" echo \"the key and pretend to be your VNC client. The downside is it is\"\n"
-" fi\n"
-" echo \"inconvenient because you will need to supply the passphrase EVERY\"\n"
-" if [ \"x$type\" = \"xserver\" ]; then\n"
-" echo \"time you start x11vnc using this key.\"\n"
-" else\n"
-" echo \"time you start the VNC viewer SSL tunnel using this key.\"\n"
-" fi\n"
-" echo \"\"\n"
-" if [ \"X$GENCERT_NOPROMPT\" = \"X\" ]; then\n"
-" x=\"\"\n"
-" for tp in 1 2 3\n"
-" do\n"
-" printf \"Protect key with a passphrase? y/n \"\n"
-" read x\n"
-" x=`echo \"$x\" | tr 'A-Z' 'a-z' | sed -e 's/[ ]//g'`\n"
-" if [ \"X$x\" = \"Xy\" -o \"X$x\" = \"Xn\" ]; then\n"
-" break;\n"
-" else \n"
-" echo \"Please reply with \\\"y\\\" or \\\"n\\\".\"\n"
-" fi\n"
-" done\n"
-" if [ \"X$x\" != \"Xy\" -a \"X$x\" != \"Xn\" ]; then\n"
-" echo \"Assuming reply \\\"n\\\".\"\n"
-" x=n\n"
-" fi\n"
-" else\n"
-" echo \"NOT protecting private key with passphrase.\"\n"
-" x=n\n"
-" fi\n"
-" estr=\" *unencrypted*\"\n"
-" if [ \"x$ENCRYPT_ONLY\" != \"x\" ]; then\n"
-" target=\"$ENCRYPT_ONLY\"\n"
-" else\n"
-" target=\"$DIR/$dest.key\"\n"
-" bdir=`dirname \"$DIR/$dest.key\"`\n"
-" if [ ! -d \"$bdir\" ]; then\n"
-" direrror \"$bdir\"\n"
-" fi\n"
-" fi\n"
-" if [ \"x$x\" != \"xn\" ]; then\n"
-" \"$OPENSSL\" rsa -in \"$target\" -des3 -out \"$target\"\n"
-" if [ $? != 0 ]; then\n"
-" echo \"openssl 'rsa' command failed\"\n"
-" rm -f \"$DIR/$dest.key\" \"$DIR/$dest.crt\" \"$DIR/$dest.req\"\n"
-" exit 1\n"
-" fi\n"
-" estr=\" encrypted\"\n"
-" fi\n"
-" echo \"\"\n"
-"}\n"
-"\n"
-"sign_key() {\n"
-" cd \"$DIR\" || exit 1\n"
-"\n"
-" if [ \"x$self\" = \"x1\" ]; then\n"
-" :\n"
-" else\n"
-" if echo \"$name0\" | grep '^req:' > /dev/null; then\n"
-" echo \"\"\n"
-" echo \"----------------------------------------------------------------------\"\n"
-" echo \"Your x11vnc $type certificate request is:\"\n"
-" echo \"\"\n"
-" echo \" $DIR/$dest.req\"\n"
-" echo \"\"\n"
-" echo \" It may be sent to an external CA for signing, afterward you can\"\n"
-" echo \" save the cert they send you in:\"\n"
-" echo \"\"\n"
-" echo \" $DIR/$dest.crt\"\n"
-" echo \"\"\n"
-" echo \"Your$estr private x11vnc $type key is:\"\n"
-" echo \"\"\n"
-" echo \" $DIR/$dest.key\"\n"
-" echo \"\"\n"
-" echo \" You should combine it and the received cert in the file:\"\n"
-" echo \"\"\n"
-" echo \" $DIR/$dest.pem\"\n"
-" echo \"\"\n"
-" echo \" It will be needed by applications to identify themselves.\"\n"
-" echo \" This file should be kept secret.\"\n"
-" echo \"----------------------------------------------------------------------\"\n"
-" echo \"\"\n"
-" if [ \"X$GENCERT_NOPROMPT\" = \"X\" ]; then\n"
-" printf \"Press Enter to print the $dest.req cert request to the screen: \"\n"
-" read x\n"
-" fi\n"
-" echo \"\"\n"
-" cat \"$DIR/$dest.req\"\n"
-" exit 0\n"
-" fi\n"
-" echo \"\"\n"
-" echo \"\"\n"
-" echo \"----------------------------------------------------------------------\"\n"
-" echo \"Now signing the new key with CA private key. You will need to supply\"\n"
-" echo \"the CA key passphrase and reply \\\"y\\\" to sign and commit the key.\"\n"
-" echo \"\"\n"
-" \"$OPENSSL\" ca -config \"$cnf\" -policy policy_anything -notext \\\n"
-" -in \"$DIR/$dest.req\" \\\n"
-" -out \"$DIR/$dest.crt\"\n"
-" if [ $? != 0 ]; then\n"
-" echo \"\"\n"
-" echo \"openssl 'ca' command failed\"\n"
-" echo \"\"\n"
-" echo \" You may have a duplicate DN entry for this name in:\"\n"
-" echo \"\"\n"
-" echo \" $DIR/CA/index.txt\"\n"
-" echo \"\"\n"
-" echo \" remove the duplicate in that file and try again.\"\n"
-" echo \"\"\n"
-" rm -f \"$DIR/$dest.key\" \"$DIR/$dest.crt\" \"$DIR/$dest.req\"\n"
-" exit 1\n"
-" fi\n"
-" fi\n"
-"\n"
-" cat \"$DIR/$dest.key\" \"$DIR/$dest.crt\" \\\n"
-" > \"$DIR/$dest.pem\" || exit 1 \n"
-"\n"
-" make_HASH \"$DIR/$dest.crt\" 0\n"
-"\n"
-" rm -f \"$DIR/$dest.key\" \"$DIR/$dest.req\" || exit 1\n"
-" chmod go-rwx \"$DIR/$dest.pem\" || exit 1\n"
-"\n"
-" if [ \"x$type\" = \"xserver\" -o \"x$type\" = \"xclient\" ]; then\n"
-" echo \"\"\n"
-" echo \"----------------------------------------------------------------------\"\n"
-" echo \"Your public x11vnc $type cert is:\"\n"
-" echo \"\"\n"
-" echo \" $DIR/$dest.crt\"\n"
-" echo \"\"\n"
-" echo \" It may be copied to other machines / applications to be used for\"\n"
-" echo \" authentication. However, since it is signed with the x11vnc CA\"\n"
-" echo \" key, all the applications need is the x11vnc CA certificate.\"\n"
-" echo \"\"\n"
-" echo \"Your$estr private x11vnc $type key is:\"\n"
-" echo \"\"\n"
-" echo \" $DIR/$dest.pem\"\n"
-" echo \"\"\n"
-" echo \" It will be needed by applications to identify themselves.\"\n"
-" echo \" This file should be kept secret.\"\n"
-" echo \"----------------------------------------------------------------------\"\n"
-" echo \"\"\n"
-" fi\n"
-"\n"
-" if [ \"X$GENCERT_NOPROMPT\" = \"X\" ]; then\n"
-" printf \"Press Enter to print the $dest.crt certificate to the screen: \"\n"
-" read x\n"
-" fi\n"
-" echo \"\"\n"
-" cat \"$DIR/$dest.crt\"\n"
-"}\n"
-"\n"
-"DIR=$BASE_DIR\n"
-"if [ \"x$DIR\" = \"x\" ]; then\n"
-" DIR=\"$HOME/dotkjr_vnc/certs\"\n"
-"fi\n"
-"if echo \"$DIR\" | grep '^/' > /dev/null; then\n"
-" :\n"
-"else\n"
-" DIR=\"`pwd`/$DIR\"\n"
-"fi\n"
-"\n"
-"if [ \"x$HASHON\" != \"x\" ]; then\n"
-" for dir in \"$DIR/HASH\" \"$DIR/clients/HASH\"\n"
-" do\n"
-" if [ -d \"$dir\" ]; then\n"
-" rm -rf \"$dir\"\n"
-" fi\n"
-" done\n"
-" dir=\"$DIR/HASH\"\n"
-" mkdir -p \"$dir\" || exit 1\n"
-" dir=\"$DIR/clients/HASH\"\n"
-" mkdir -p \"$dir\" || exit 1\n"
-" HASH_verbose=1\n"
-" for f in \"$DIR\"/*.crt \"$DIR\"/clients/*.crt\n"
-" do\n"
-" if [ -f \"$f\" ]; then\n"
-" make_HASH \"$f\" 0\n"
-" fi\n"
-" done\n"
-" exit\n"
-"fi\n"
-"if [ \"x$HASHOFF\" != \"x\" ]; then\n"
-" dir=\"$DIR/HASH\"\n"
-" for dir in \"$DIR/HASH\" \"$DIR/clients/HASH\"\n"
-" do\n"
-" if [ -d \"$dir\" ]; then\n"
-" for f in \"$dir\"/*\n"
-" do\n"
-" if [ -f \"$f\" ]; then\n"
-" echo \"deleting: $f\"\n"
-" rm -f \"$f\"\n"
-" fi\n"
-" done\n"
-" rm -rf \"$dir\"\n"
-" fi\n"
-" done\n"
-" exit\n"
-"fi\n"
-"\n"
-"PATH=/usr/bin:/bin:/usr/sbin:$PATH; export PATH\n"
-"if [ \"x$OPENSSL\" = \"x\" ]; then\n"
-" OPENSSL=\"openssl\"\n"
-"fi\n"
-"\n"
-"type \"$OPENSSL\" > /dev/null || exit 1\n"
-"\n"
-"self=\"\"\n"
-"if [ \"x$SELF\" != \"x\" ]; then\n"
-" self=1\n"
-"elif [ \"x$1\" = \"x-self\" ]; then\n"
-" shift\n"
-" self=1\n"
-"fi\n"
-"\n"
-"if [ \"x$TYPE\" != \"x\" ]; then\n"
-" type=\"$TYPE\"\n"
-"else\n"
-" if [ \"X$1\" != \"X\" ]; then\n"
-" type=\"$1\"\n"
-" shift\n"
-" fi\n"
-"fi\n"
-"if [ \"x$NAME\" != \"x\" ]; then\n"
-" name=\"$NAME\"\n"
-"else\n"
-" if [ \"X$1\" != \"X\" ]; then\n"
-" name=\"$1\"\n"
-" shift\n"
-" fi\n"
-"fi\n"
-"\n"
-"if echo \"$name\" | grep '^self:' > /dev/null; then\n"
-" self=1\n"
-"fi\n"
-"\n"
-"if [ \"x$type\" = \"xserver\" ]; then\n"
-" name0=\"$name\"\n"
-" if echo \"$name\" | grep '^-' > /dev/null; then\n"
-" :\n"
-" elif [ \"x$name\" != \"x\" ]; then\n"
-" name=\"-$name\";\n"
-" fi\n"
-" dest=\"server$name\"\n"
-"elif [ \"x$type\" = \"xclient\" ]; then\n"
-" if [ \"x$name\" = \"x\" ]; then\n"
-" name=\"nobody\"\n"
-" fi\n"
-" name0=\"$name\"\n"
-" dest=\"clients/$name\"\n"
-"else\n"
-" exit 1\n"
-"fi\n"
-"\n"
-"#set -xv\n"
-"\n"
-"if [ \"x$INFO_ONLY\" != \"x\" ]; then\n"
-" echo \"\"\n"
-" echo \"VNC Certificate file:\"\n"
-" echo \" $INFO_ONLY\"\n"
-" echo \"\"\n"
-" \"$OPENSSL\" x509 -text -in \"$INFO_ONLY\"\n"
-" exit \n"
-"elif [ \"x$DELETE_ONLY\" != \"x\" ]; then\n"
-" echo \"\"\n"
-" echo \"VNC Certificate file:\"\n"
-" echo \" $DELETE_ONLY\"\n"
-" echo \"\"\n"
-" \n"
-" base=`echo \"$DELETE_ONLY\" | sed -e 's/\\....$//'`\n"
-" for suff in crt pem key req\n"
-" do\n"
-" try=\"$base.$suff\"\n"
-" if [ -f \"$try\" ]; then\n"
-" make_HASH \"$try\" 1\n"
-" rm -i \"$try\"\n"
-" fi\n"
-" done\n"
-" if echo \"$base\" | grep 'CA/cacert$' > /dev/null; then\n"
-" base2=`echo \"$base\" | sed -e 's,cacert$,private/cakey,'`\n"
-" else\n"
-" echo \"\"\n"
-" exit\n"
-" fi\n"
-" echo \"\"\n"
-" for suff in crt pem key req\n"
-" do\n"
-" try=\"$base2.$suff\"\n"
-" if [ -f \"$try\" ]; then\n"
-" make_HASH \"$try\" 1\n"
-" rm -i \"$try\"\n"
-" fi\n"
-" done\n"
-" echo \"\"\n"
-" exit \n"
-"elif [ \"x$ENCRYPT_ONLY\" != \"x\" ]; then\n"
-" if [ \"x$type\" = \"x\" ]; then\n"
-" type=\"server\"\n"
-" fi\n"
-" echo \"\"\n"
-" echo \"Key PEM file:\"\n"
-" echo \" $ENCRYPT_ONLY\"\n"
-" enc_key\n"
-" exit\n"
-"fi\n"
-"\n"
-"if [ ! -d \"$DIR/tmp\" ]; then\n"
-" direrror \"$DIR/tmp\"\n"
-"fi\n"
-"bdir=`dirname \"$DIR/$dest.key\"`\n"
-"if [ ! -d \"$bdir\" ]; then\n"
-" direrror \"$bdir\"\n"
-"fi\n"
-"if [ ! -f \"$DIR/CA/cacert.pem\" ]; then\n"
-" direrror \"$DIR/CA/cacert.pem\"\n"
-"fi\n"
-"\n"
-"create_key\n"
-"enc_key\n"
-"sign_key\n"
-;
-
-char find_display[] =
-"#!/bin/sh\n"
-"#\n"
-"# Script for use in -display WAIT:cmd=FINDDISPLAY -unixpw mode.\n"
-"# Attempts to find 1) DISPLAY and 2) XAUTH data for the user and\n"
-"# returns them to caller.\n"
-"#\n"
-"# The idea is this script is run via su - user -c ... and returns\n"
-"# display + xauth info to caller (x11vnc running as root or nobody).\n"
-"# x11vnc then uses the info to open the display.\n"
-"#\n"
-"# If not called with -unixpw, root, etc. uses current $USER.\n"
-"\n"
-"#FIND_DISPLAY_OUTPUT=/tmp/fdo.$USER.txt\n"
-"\n"
-"if [ \"X$FIND_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
-" if [ \"X$FIND_DISPLAY_EXEC\" = \"X\" ]; then\n"
-" FIND_DISPLAY_EXEC=1\n"
-" export FIND_DISPLAY_EXEC\n"
-" # we rerun ourselves with verbose output to a file:\n"
-" #\n"
-" if [ \"X$FIND_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
-" /bin/sh $0 \"$@\" 2> $FIND_DISPLAY_OUTPUT\n"
-" else\n"
-" /bin/sh $0 \"$@\" 2> /dev/null\n"
-" fi\n"
-" exit $?\n"
-" fi\n"
-"fi\n"
-"\n"
-"if [ \"X$FIND_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
-" # turn on verbose output\n"
-" set -xv\n"
-"fi\n"
-"if [ \"X$FIND_DISPLAY_DEBUG\" != \"X\" ]; then\n"
-" # print environment and turn on verbose output\n"
-" env\n"
-" set -xv\n"
-"fi\n"
-"\n"
-"if [ \"X$X11VNC_SKIP_DISPLAY\" = \"Xall\" ]; then\n"
-" exit 1\n"
-"fi\n"
-"\n"
-"# Set PATH to pick up utilities we use below.\n"
-"PATH=$PATH:/bin:/usr/bin:/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/ucb\n"
-"export PATH\n"
-"\n"
-"# This is to try to trick ps(1) into writing wide lines: \n"
-"COLUMNS=256\n"
-"export COLUMNS\n"
-"\n"
-"# -n means no xauth, -f prescribes file to use.\n"
-"showxauth=1\n"
-"if [ \"X$1\" = \"X-n\" ]; then\n"
-" showxauth=\"\"\n"
-" shift\n"
-"fi\n"
-"if [ \"X$FIND_DISPLAY_NO_SHOW_XAUTH\" != \"X\" ]; then\n"
-" showxauth=\"\"\n"
-"fi\n"
-"\n"
-"# -f means use this xauthority file:\n"
-"if [ \"X$1\" = \"X-f\" ]; then\n"
-" shift\n"
-" if [ ! -r $1 ]; then\n"
-" echo \"\"\n"
-" exit 1\n"
-" fi\n"
-" export XAUTHORITY=\"$1\"\n"
-" shift\n"
-"fi\n"
-"\n"
-"# we need to set user:\n"
-"#\n"
-"user=\"$1\" # cmd line arg takes precedence\n"
-"if [ \"X$user\" = \"X\" ]; then\n"
-" user=$X11VNC_USER # then X11VNC_USER\n"
-"fi\n"
-"if [ \"X$user\" = \"X\" ]; then\n"
-" user=$USER # then USER\n"
-"fi\n"
-"if [ \"X$user\" = \"X\" ]; then\n"
-" user=$LOGNAME # then LOGNAME\n"
-"fi\n"
-"if [ \"X$user\" = \"X\" ]; then\n"
-" user=`whoami 2>/dev/null` # desperation whoami\n"
-"fi\n"
-"if [ \"X$user\" = \"X\" ]; then\n"
-" echo \"\" # failure\n"
-" exit 1\n"
-"fi\n"
-"\n"
-"LC_ALL=C\n"
-"export LC_ALL\n"
-"\n"
-"# util to try to match a display with a Linux VT and print\n"
-"# disp,VT=... etc. Otherwise just print out display.\n"
-"#\n"
-"prdpy () {\n"
-" d1=$1\n"
-" chvt0=\"\"\n"
-" if [ \"X$FIND_DISPLAY_NO_VT_FIND\" != \"X\" ]; then\n"
-" :\n"
-" # we can only do chvt on Linux:\n"
-" elif [ \"X$uname\" = \"XLinux\" ]; then\n"
-" d2=$d1\n"
-" d3=`echo \"$d2\" | sed -e 's/^.*:/:/' -e 's/\\..*$//'`\n"
-" d4=\"($d2|$d3)\"\n"
-"\n"
-" # vt is usually in X server line:\n"
-" #\n"
-" ps_tmp=`ps wwaux | grep X`\n"
-" vt=`echo \"$ps_tmp\" | grep X | egrep -v 'startx|xinit' | egrep \" $d4 \" | egrep ' vt([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -n 1`\n"
-"\n"
-" if [ \"X$vt\" != \"X\" ]; then\n"
-" # strip it out and add it.\n"
-" vt=`echo \"$vt\" | sed -e 's/^.* vt\\([0-9][0-9]*\\) .*$/\\1/'`\n"
-" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
-" chvt0=\",VT=$vt\"\n"
-" fi\n"
-" else\n"
-" # otherwise look for tty:\n"
-" vt=`echo \"$ps_tmp\" | grep X | egrep \" $d4 \" | egrep ' tty([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -n 1`\n"
-" if [ \"X$vt\" != \"X\" ]; then\n"
-" vt=`echo \"$vt\" | sed -e 's/^.* tty\\([0-9][0-9]*\\) .*$/\\1/'`\n"
-" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
-" chvt0=\",VT=$vt\"\n"
-" fi\n"
-" else\n"
-" # otherwise try lsof:\n"
-" pvt=`echo \"$ps_tmp\" | grep X | egrep -v 'startx|xinit' | egrep \" $d4 \" | head -n 1 | awk '{print $2}'`\n"
-" if [ \"X$FIND_DISPLAY_NO_LSOF\" != \"X\" ]; then\n"
-" if [ \"X$pvt\" != \"X\" ]; then\n"
-" chvt0=\",XPID=$pvt\"\n"
-" fi\n"
-" elif [ \"X$pvt\" != \"X\" ]; then\n"
-" vt=`lsof -b -p \"$pvt\" 2>/dev/null | egrep '/dev/tty([789]|[1-9][0-9][0-9]*)$' | grep -v grep | head -n 1 | awk '{print $NF}' | sed -e 's,/dev/tty,,'`\n"
-" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
-" chvt0=\",VT=$vt\"\n"
-" else\n"
-" # if this fails, at least tell them the XPID:\n"
-" chvt0=\",XPID=$pvt\"\n"
-" fi\n"
-" fi\n"
-" fi\n"
-" fi\n"
-" fi\n"
-"\n"
-" # return the string, possibly with ,VT=... appended:\n"
-" #\n"
-" echo \"$d1$chvt0\"\n"
-"}\n"
-"\n"
-"# save uname, netstat, and ps output:\n"
-"uname=`uname`\n"
-"is_bsd=\"\"\n"
-"if echo \"$uname\" | grep -i bsd > /dev/null; then\n"
-" is_bsd=1\n"
-"fi\n"
-"\n"
-"if [ \"X$uname\" = \"XDarwin\" ]; then\n"
-" psout=`ps aux 2>/dev/null | grep -wv PID | grep -v grep`\n"
-"elif [ \"X$uname\" = \"XLinux\" -o \"X$is_bsd\" = \"X1\" ]; then\n"
-" psout=`ps wwaux 2>/dev/null | grep -wv PID | grep -v grep`\n"
-"elif [ \"X$uname\" = \"XSunOS\" -a -x /usr/ucb/ps ]; then\n"
-" psout=`/usr/ucb/ps wwaux 2>/dev/null | grep -wv PID | grep -v grep`\n"
-"else\n"
-" psout=`ps -ef 2>/dev/null | grep -wv PID | grep -v grep`\n"
-"fi\n"
-"pslist=`echo \"$psout\" | awk '{print $2}'`\n"
-"\n"
-"nsout=`netstat -an`\n"
-"\n"
-"rchk() {\n"
-" rr=rr \n"
-"}\n"
-"\n"
-"dL=\"-L\"\n"
-"if uname -sr | egrep 'SunOS 5\\.[5-8]' > /dev/null; then\n"
-" dL=\"-h\"\n"
-"fi\n"
-"\n"
-"# a portable tmp file creator\n"
-"mytmp() {\n"
-" tf=$1\n"
-" if type mktemp > /dev/null 2>&1; then\n"
-" # if we have mktemp(1), use it:\n"
-" tf2=\"$tf.XXXXXX\"\n"
-" tf2=`mktemp \"$tf2\"`\n"
-" if [ \"X$tf2\" != \"X\" -a -f \"$tf2\" ]; then\n"
-" if [ \"X$DEBUG_MKTEMP\" != \"X\" ]; then\n"
-" echo \"mytmp-mktemp: $tf2\" 1>&2\n"
-" fi\n"
-" echo \"$tf2\"\n"
-" return\n"
-" fi\n"
-" fi\n"
-" # fallback to multiple cmds:\n"
-" rm -rf \"$tf\" || exit 1\n"
-" if [ -d \"$tf\" ]; then\n"
-" echo \"tmp file $tf still exists as a directory.\"\n"
-" exit 1\n"
-" elif [ $dL \"$tf\" ]; then\n"
-" echo \"tmp file $tf still exists as a symlink.\"\n"
-" exit 1\n"
-" elif [ -f \"$tf\" ]; then\n"
-" echo \"tmp file $tf still exists.\"\n"
-" exit 1\n"
-" fi\n"
-" touch \"$tf\" || exit 1\n"
-" chmod 600 \"$tf\" || exit 1\n"
-" rchk\n"
-" if [ \"X$DEBUG_MKTEMP\" != \"X\" ]; then\n"
-" echo \"mytmp-touch: $tf\" 1>&2\n"
-" fi\n"
-" echo \"$tf\"\n"
-"}\n"
-"\n"
-"skip_display() {\n"
-" dtry=$1\n"
-" dtry1=`echo \"$dtry\" | sed -e 's/^://'`\n"
-" dtry2=`echo \"$dtry\" | sed -e 's/\\.[0-9][0-9]*$//'`\n"
-"\n"
-" if [ \"X$X11VNC_SKIP_DISPLAY\" = \"X\" ]; then\n"
-" # no skip list, return display:\n"
-" echo \"$dtry\"\n"
-" else\n"
-" # user supplied skip list:\n"
-" mat=\"\"\n"
-" slist=\"\"\n"
-" for skip in `echo \"$X11VNC_SKIP_DISPLAY\" | tr ',' '\\n'`\n"
-" do\n"
-" if echo \"$skip\" | sed -e 's/://g' | grep '^[0-9][0-9]*-[0-9][0-9]*$' > /dev/null; then\n"
-" # a range n-m\n"
-" min=`echo \"$skip\" | sed -e 's/://g' | awk -F- '{print $1}'`\n"
-" max=`echo \"$skip\" | sed -e 's/://g' | awk -F- '{print $2}'`\n"
-" if [ \"$min\" -le \"$max\" ]; then\n"
-" while [ $min -le $max ]\n"
-" do\n"
-" if [ \"X$slist\" = \"X\" ]; then\n"
-" slist=\"$min\"\n"
-" else\n"
-" slist=\"$slist $min\"\n"
-" fi\n"
-" min=`expr $min + 1`\n"
-" done\n"
-" continue\n"
-" fi\n"
-" fi\n"
-" # a simple :n or n (or user supplied garbage).\n"
-" if [ \"X$slist\" = \"X\" ]; then\n"
-" slist=\"$skip\"\n"
-" else\n"
-" slist=\"$slist $skip\"\n"
-" fi\n"
-" done\n"
-"\n"
-" for skip in $slist\n"
-" do\n"
-" if echo \"$skip\" | grep \"^:\" > /dev/null; then\n"
-" :\n"
-" else\n"
-" skip=\":$skip\"\n"
-" fi\n"
-" skip2=`echo \"$skip\" | sed -e 's/\\.[0-9][0-9]*$//'`\n"
-"\n"
-" if echo \"$skip\" | grep \":$dtry1\\>\" > /dev/null; then\n"
-" mat=1\n"
-" break\n"
-" elif echo \"$skip\" | grep \":$dtry2\\>\" > /dev/null; then\n"
-" mat=1\n"
-" break\n"
-" elif [ \"X$skip2\" = \"X:$dtry1\" ]; then\n"
-" mat=1\n"
-" break\n"
-" elif [ \"X$skip2\" = \"X:$dtry2\" ]; then\n"
-" mat=1\n"
-" break\n"
-" fi\n"
-" done\n"
-" if [ \"X$X11VNC_SKIP_DISPLAY_NEGATE\" = \"X\" ]; then\n"
-" if [ \"X$mat\" = \"X1\" ]; then\n"
-" echo \"\"\n"
-" else\n"
-" echo \"$dtry\"\n"
-" fi\n"
-" else\n"
-" if [ \"X$mat\" = \"X1\" ]; then\n"
-" echo \"$dtry\"\n"
-" else\n"
-" echo \"\"\n"
-" fi\n"
-" fi\n"
-" fi\n"
-"}\n"
-"\n"
-"am_root=\"\"\n"
-"if id | sed -e 's/ gid.*$//' | grep -w root > /dev/null; then\n"
-" am_root=1\n"
-"fi\n"
-"am_gdm=\"\"\n"
-"if id | sed -e 's/ gid.*$//' | grep -w gdm > /dev/null; then\n"
-" am_gdm=1\n"
-"fi\n"
-"\n"
-"# this mode is to try to grab a display manager (gdm, kdm, xdm...) display\n"
-"# when we are run as root (e.g. no one is logged in yet). We look at the\n"
-"# -auth line in the X/Xorg commandline.\n"
-"#\n"
-"if [ \"X$FD_XDM\" != \"X\" ]; then\n"
-" list=\"\"\n"
-" for pair in `echo \"$psout\" | grep '/X.* :[0-9][0-9]* .*-auth' | egrep -v 'startx|xinit' | sed -e 's,^.*/X.* \\(:[0-9][0-9]*\\) .* -auth \\([^ ][^ ]*\\).*$,\\1\\,\\2,' | sort -u`\n"
-" do\n"
-" da=`echo \"$pair\" | awk -F, '{print $1}'`\n"
-" xa=`echo \"$pair\" | awk -F, '{print $2}'`\n"
-" da=`skip_display \"$da\"`\n"
-" if [ \"X$da\" = \"X\" ]; then\n"
-" continue\n"
-" fi\n"
-" if [ -f $xa -a -r $xa ]; then\n"
-" # if we have an xauth file, we proceed to test it:\n"
-" #\n"
-" env XAUTHORITY=\"$xa\" xdpyinfo -display \"$da\" >/dev/null 2>&1\n"
-" if [ $? = 0 ]; then\n"
-" si_root=\"\"\n"
-" si_gdm=\"\"\n"
-" # recent gdm seems to use SI:localuser: for xauth.\n"
-" if env DISPLAY=\"$da\" xhost 2>/dev/null | grep -i '^SI:localuser:root$' > /dev/null; then\n"
-" si_root=1\n"
-" fi\n"
-" if env DISPLAY=\"$da\" xhost 2>/dev/null | grep -i '^SI:localuser:gdm$' > /dev/null; then\n"
-" si_gdm=1\n"
-" fi\n"
-" env XAUTHORITY=/dev/null xdpyinfo -display \"$da\" >/dev/null 2>&1\n"
-" rc=$?\n"
-" if [ \"X$rc\" = \"X0\" ]; then\n"
-" # assume it is ok for server interpreted case.\n"
-" if [ \"X$am_root\" = \"X1\" -a \"X$si_root\" = \"X1\" ]; then\n"
-" rc=5\n"
-" elif [ \"X$am_gdm\" = \"X1\" -a \"X$si_gdm\" = \"X1\" ]; then\n"
-" rc=6\n"
-" fi\n"
-" fi\n"
-" if [ $rc != 0 ]; then\n"
-" y=`prdpy $da`\n"
-" if [ \"X$FIND_DISPLAY_NO_SHOW_DISPLAY\" = \"X\" ]; then\n"
-" echo \"DISPLAY=$y\"\n"
-" fi\n"
-" if [ \"X$FIND_DISPLAY_XAUTHORITY_PATH\" != \"X\" ]; then\n"
-" # caller wants XAUTHORITY printed out too.\n"
-" if [ \"X$xa\" != \"X\" -a -f \"$xa\" ]; then\n"
-" echo \"XAUTHORITY=$xa\"\n"
-" else\n"
-" echo \"XAUTHORITY=$XAUTHORITY\"\n"
-" fi\n"
-" fi\n"
-" if [ \"X$showxauth\" != \"X\" ]; then\n"
-" # copy the cookie:\n"
-" cook=`xauth -f \"$xa\" list | head -n 1 | awk '{print $NF}'`\n"
-" xtf=$HOME/.xat.$$\n"
-" xtf=`mytmp \"$xtf\"`\n"
-" if [ ! -f $xtf ]; then\n"
-" xtf=/tmp/.xat.$$\n"
-" xtf=`mytmp \"$xtf\"`\n"
-" fi\n"
-" if [ ! -f $xtf ]; then\n"
-" xtf=/tmp/.xatb.$$\n"
-" rm -f $xtf\n"
-" if [ -f $xtf ]; then\n"
-" exit 1\n"
-" fi\n"
-" touch $xtf 2>/dev/null\n"
-" chmod 600 $xtf 2>/dev/null\n"
-" if [ ! -f $xtf ]; then\n"
-" exit 1\n"
-" fi\n"
-" fi\n"
-" xauth -f $xtf add \"$da\" . $cook\n"
-" xauth -f $xtf extract - \"$da\" 2>/dev/null\n"
-" rm -f $xtf\n"
-" fi\n"
-" # DONE\n"
-" exit 0\n"
-" fi\n"
-" fi\n"
-" fi\n"
-" done\n"
-" if [ \"X$FIND_DISPLAY_XAUTHORITY_PATH\" = \"X\" ]; then\n"
-" echo \"\" # failure\n"
-" fi\n"
-" if [ \"X$showxauth\" != \"X\" ]; then\n"
-" echo \"\"\n"
-" fi\n"
-" # DONE\n"
-" exit 1\n"
-"fi\n"
-"\n"
-"# Normal case here (not xdm...).\n"
-"\n"
-"# Try to match X DISPLAY to user:\n"
-"\n"
-"# who(1) output column 2:\n"
-"#gone=`last $user | grep 'gone.*no.logout' | awk '{print $2}' | grep '^:' | sed -e 's,/.*,,' | tr '\\n' '|'`\n"
-"#gone=\"${gone}__quite_impossible__\"\n"
-"#display=`who 2>/dev/null | grep \"^${user}[ ][ ]*:[0-9]\" | egrep -v \" ($gone)\\>\" | head -n 1 \\\n"
-"# | awk '{print $2}' | sed -e 's,/.*$,,'`\n"
-"\n"
-"poss=\"\"\n"
-"list=`who 2>/dev/null | grep \"^${user}[ ][ ]*:[0-9]\" | awk '{print $2}' | sed -e 's,/.*$,,'`\n"
-"list=\"$list \"`w -h \"$user\" 2>/dev/null | grep \"^${user}[ ][ ]*:[0-9]\" | awk '{print $2}' | sed -e 's,/.*$,,'`\n"
-"list=\"$list \"`who 2>/dev/null | grep \"^${user}[ ]\" | awk '{print $NF}' | grep '(:[0-9]' | sed -e 's/[()]//g'`\n"
-"host=`hostname 2>/dev/null | sed -e 's/\\..*$//'`\n"
-"\n"
-"got_local_dm_file=\"\"\n"
-"\n"
-"if [ \"X$X11VNC_FINDDISPLAY_SKIP_XAUTH\" = \"X\" ]; then\n"
-" # do a normal xauth list:\n"
-" list=\"$list \"`xauth list | awk '{print $1}' | grep /unix | grep \"^${host}\" | sed -e 's/^.*:/:/' | sort -n | uniq`\n"
-"\n"
-" # check for gdm and kdm non-NFS cookies in /tmp: (and now /var/run/gdm)\n"
-" for xa in /tmp/.gdm* /tmp/.Xauth* /var/run/gdm*/auth-for-*/database /var/run/gdm*/auth-cookie-*-for-*\n"
-" do\n"
-" # try to be somewhat careful about the real owner of the file:\n"
-" if [ \"X$am_root\" = \"X1\" ]; then\n"
-" break\n"
-" fi\n"
-" if [ -f $xa -a -r $xa ]; then\n"
-" if ls -l \"$xa\" | sed -e 's,/tmp.*$,,' -e 's,/var.*$,,' | grep -w \"$user\" > /dev/null; then\n"
-" # append these too:\n"
-" if find \"$xa\" -user \"$user\" -perm 600 > /dev/null; then\n"
-" :\n"
-" else\n"
-" continue\n"
-" fi\n"
-" # it passes the ownership tests, add it:\n"
-" # since the directory is (evidently) local, \"localhost\" is good too. (but beware XAUTHLOCALHOSTNAME in libxcb)\n"
-" sav0=\"$list \"\n"
-" list=\"$list \"`xauth -f \"$xa\" list | awk '{print $1}' | grep /unix | egrep -i \"^${host}|^localhost\" | sed -e 's/^.*:/:/' | sort -n | uniq | sed -e \"s,\\$,\\,$xa,\"`\n"
-" if [ \"X$sav0\" != \"X$list\" ]; then\n"
-" got_local_dm_file=1\n"
-" fi\n"
-" fi\n"
-" fi\n"
-" done\n"
-"fi\n"
-"\n"
-"if [ \"X$uname\" = \"XDarwin\" ]; then\n"
-" # macosx uses \"console\" string (in leopard X11 runs/launched by default)\n"
-" if who 2>/dev/null | grep -i \"^${user}[ ][ ]*console[ ]\" > /dev/null; then\n"
-" echo \"DISPLAY=console\"\n"
-" if [ \"X$FIND_DISPLAY_ALL\" = \"X\" ]; then\n"
-" if [ \"X$showxauth\" != \"X\" ]; then\n"
-" echo \"\"\n"
-" fi\n"
-" exit 0\n"
-" fi\n"
-" fi\n"
-"fi\n"
-"\n"
-"# try the items in the list:\n"
-"#\n"
-"nsout_trim=`echo \"$nsout\" | grep \"/tmp/.X11-unix/\"`\n"
-"#\n"
-"for p in $list\n"
-"do\n"
-" xa=`echo \"$p\" | awk -F, '{print $2}'`\n"
-" d=`echo \"$p\" | sed -e 's/,.*$//' -e 's/://' -e 's/\\..*$//'`\n"
-" ok=\"\"\n"
-" d=`skip_display \"$d\"`\n"
-" if [ \"X$d\" = \"X\" ]; then\n"
-" continue;\n"
-" fi\n"
-"\n"
-" # check for the local X11 files:\n"
-" xd=\"/tmp/.X11-unix/X$d\"\n"
-" if [ -r \"$xd\" -o -w \"$xd\" -o -x \"$xd\" ]; then\n"
-" if echo \"$nsout_trim\" | grep \"/tmp/.X11-unix/X$d[ ]*\\$\" > /dev/null; then\n"
-" ok=1\n"
-" fi\n"
-" fi\n"
-" if [ \"X$ok\" = \"X\" ]; then\n"
-" # instead check for the lock:\n"
-" if [ -f \"/tmp/.X$d-lock\" ]; then\n"
-" pid=`cat \"/tmp/.X$d-lock\" | sed -e 's/[ ]//g'`\n"
-" if echo \"$pid\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
-" if [ \"X$uname\" = \"XLinux\" -o \"X$uname\" = \"XSunOS\" ]; then\n"
-" if [ -d \"/proc/$pid\" ]; then\n"
-" ok=1\n"
-" fi\n"
-" elif echo \"$pslist\" | grep -w \"$pid\" > /dev/null; then\n"
-" ok=1\n"
-" fi\n"
-" fi\n"
-" fi\n"
-" fi\n"
-"\n"
-" if [ \"X$ok\" = \"X1\" ]; then\n"
-" # ok, put it on the list\n"
-" poss=\"$poss $p\"\n"
-" fi\n"
-"done\n"
-"\n"
-"seenvalues=\"\"\n"
-"\n"
-"seen() {\n"
-" # simple util to skip repeats\n"
-" v=$1\n"
-" if [ \"X$seenvalues\" != \"X\" ]; then\n"
-" for v2 in $seenvalues\n"
-" do\n"
-" if [ \"X$v\" = \"X$v2\" ]; then\n"
-" seenret=1\n"
-" return\n"
-" fi\n"
-" done\n"
-" fi\n"
-" if [ \"X$seenvalues\" = \"X\" ]; then\n"
-" seenvalues=\"$v\"\n"
-" else\n"
-" seenvalues=\"$seenvalues $v\"\n"
-" fi\n"
-" seenret=0\n"
-"}\n"
-"\n"
-"# now get read to try each one in $poss\n"
-"#\n"
-"poss=`echo \"$poss\" | sed -e 's/^ *//' -e 's/ *$//'`\n"
-"display=\"\"\n"
-"xauth_use=\"\"\n"
-"\n"
-"if [ \"X$X11VNC_FINDDISPLAY_SKIP_XAUTH\" != \"X\" ]; then\n"
-" # we are not supposed to call xauth(1), simply report\n"
-" if [ \"X$FIND_DISPLAY_ALL\" != \"X\" ]; then\n"
-" for p in $poss\n"
-" do\n"
-" if [ \"X$p\" = \"X\" ]; then\n"
-" continue\n"
-" fi\n"
-" seen \"$p\"\n"
-" if [ \"X$seenret\" = \"X1\" ]; then\n"
-" continue\n"
-" fi\n"
-" # get rid of any ,xauth\n"
-" p=`echo \"$p\" | sed -e 's/,.*$//'`\n"
-" y=`prdpy $p`\n"
-" echo $y\n"
-" done\n"
-" exit 0\n"
-" fi\n"
-" display=`echo \"$poss\" | tr ' ' '\\n' | head -n 1`\n"
-"else\n"
-" freebie=\"\"\n"
-" xauth_freebie=\"\"\n"
-" for p in $poss\n"
-" do\n"
-" if [ \"X$p\" = \"X\" ]; then\n"
-" continue\n"
-" fi\n"
-" seen \"$p\"\n"
-" if [ \"X$seenret\" = \"X1\" ]; then\n"
-" continue\n"
-" fi\n"
-"\n"
-" # extract ,xauth if any.\n"
-" xa=\"\"\n"
-" xa=`echo \"$p\" | awk -F, '{print $2}'`\n"
-" p=`echo \"$p\" | sed -e 's/,.*$//'`\n"
-"\n"
-" # check xauth for it:\n"
-" if [ \"X$xa\" != \"X\" ]; then\n"
-" myenv=\"XAUTHORITY=$xa\"\n"
-" else\n"
-" myenv=\"FOO_BAR_=baz\"\n"
-" fi\n"
-" p=`skip_display \"$p\"`\n"
-" if [ \"X$p\" = \"X\" ]; then\n"
-" continue\n"
-" fi\n"
-"\n"
-" env \"$myenv\" xdpyinfo -display \"$p\" >/dev/null 2>&1\n"
-" rc=$?\n"
-"\n"
-" if [ $rc != 0 ]; then\n"
-" # guard against libxcb/desktop silliness: \n"
-" xalhn_save=$XAUTHLOCALHOSTNAME\n"
-"\n"
-" if [ \"X$xalhn_save\" != \"X\" ]; then\n"
-" # try it again unset\n"
-" unset XAUTHLOCALHOSTNAME\n"
-" env \"$myenv\" xdpyinfo -display \"$p\" >/dev/null 2>&1\n"
-" rc=$?\n"
-" if [ $rc != 0 ]; then\n"
-" # did not work; put it back\n"
-" XAUTHLOCALHOSTNAME=$xalhn_save\n"
-" export XAUTHLOCALHOSTNAME\n"
-" fi\n"
-" fi\n"
-" if [ $rc != 0 -a \"X$xalhn_save\" != \"Xlocalhost\" ]; then\n"
-" # try it again with localhost\n"
-" env \"$myenv\" XAUTHLOCALHOSTNAME=localhost xdpyinfo -display \"$p\" >/dev/null 2>&1\n"
-" rc=$?\n"
-" if [ $rc = 0 ]; then\n"
-" # better export it for cmds below...\n"
-" XAUTHLOCALHOSTNAME=localhost\n"
-" export XAUTHLOCALHOSTNAME\n"
-" fi\n"
-" fi\n"
-" fi\n"
-"\n"
-" if [ $rc = 0 ]; then\n"
-" if [ \"X$FD_TAG\" != \"X\" ]; then\n"
-" # look for x11vnc special FD_TAG property:\n"
-" if [ \"X$xa\" = \"X\" ]; then\n"
-" if xprop -display \"$p\" -root -len 128 FD_TAG | grep -iv no.such.atom \\\n"
-" | grep \"=[ ][ ]*\\\"$FD_TAG\\\"\" > /dev/null; then\n"
-" :\n"
-" else\n"
-" continue\n"
-" fi\n"
-" else\n"
-" if env XAUTHORITY=\"$xa\" xprop -display \"$p\" -root -len 128 FD_TAG | grep -iv no.such.atom \\\n"
-" | grep \"=[ ][ ]*\\\"$FD_TAG\\\"\" > /dev/null; then\n"
-" :\n"
-" else\n"
-" continue\n"
-" fi\n"
-" fi\n"
-" fi\n"
-"\n"
-" # Now try again with no authority:\n"
-" env XAUTHORITY=/dev/null xdpyinfo -display \"$p\" >/dev/null 2>&1\n"
-"\n"
-" # 0 means got in for free... skip it unless we don't find anything else.\n"
-" if [ $? != 0 ]; then\n"
-" # keep it\n"
-" display=\"$p\"\n"
-" xauth_use=\"$xa\"\n"
-" if [ \"X$FIND_DISPLAY_ALL\" != \"X\" ]; then\n"
-" y=`prdpy $p`\n"
-" echo \"DISPLAY=$y\"\n"
-" continue\n"
-" fi\n"
-" break\n"
-" else\n"
-" # store in freebie as fallback\n"
-" if [ \"X$FIND_DISPLAY_ALL\" != \"X\" ]; then\n"
-" y=`prdpy $p`\n"
-" echo \"$y,NOXAUTH\"\n"
-" continue\n"
-" fi\n"
-" if [ \"X$freebie\" = \"X\" ]; then\n"
-" freebie=\"$p\"\n"
-" xauth_freebie=\"$xa\"\n"
-" fi\n"
-" fi\n"
-" fi\n"
-" done\n"
-" if [ \"X$display\" = \"X\" -a \"X$freebie\" != \"X\" ]; then\n"
-" # fallback to the freebie (if any)\n"
-" display=\"$freebie\"\n"
-" xauth_use=\"$xauth_freebie\"\n"
-" fi\n"
-"fi\n"
-"\n"
-"if [ \"X$FIND_DISPLAY_ALL\" != \"X\" ]; then\n"
-" # we have listed everything, get out.\n"
-" exit\n"
-"fi\n"
-"if [ \"X$display\" = \"X\" ]; then\n"
-" if [ \"X$FINDDISPLAY_run\" = \"X\" ]; then\n"
-" echo \"\" # failure\n"
-" if [ \"X$showxauth\" != \"X\" ]; then\n"
-" echo \"\"\n"
-" fi\n"
-" fi\n"
-" exit 1\n"
-"fi\n"
-"\n"
-"# append ,VT=n if applicable:\n"
-"dpy2=`prdpy \"$display\"`\n"
-"\n"
-"if [ \"X$FIND_DISPLAY_NO_SHOW_DISPLAY\" = \"X\" ]; then\n"
-" echo \"DISPLAY=$dpy2\"\n"
-"fi\n"
-"if [ \"X$FIND_DISPLAY_XAUTHORITY_PATH\" != \"X\" ]; then\n"
-" # caller wants XAUTHORITY printed out too.\n"
-" if [ \"X$xauth_use\" != \"X\" -a -f \"$xauth_use\" ]; then\n"
-" echo \"XAUTHORITY=$xauth_use\"\n"
-" else\n"
-" echo \"XAUTHORITY=$XAUTHORITY\"\n"
-" fi\n"
-"fi\n"
-"if [ \"X$showxauth\" != \"X\" ]; then\n"
-" # show the (binary) xauth data:\n"
-" if [ \"X$xauth_use\" != \"X\" -a -f \"$xauth_use\" ]; then\n"
-" xauth -f \"$xauth_use\" extract - \"$display\" 2>/dev/null\n"
-" else\n"
-" xauth extract - \"$display\" 2>/dev/null\n"
-" fi\n"
-"fi\n"
-"\n"
-"exit 0\n"
-;
-
-char create_display[] =
-"#!/bin/sh\n"
-"\n"
-"#CREATE_DISPLAY_OUTPUT=/tmp/cdo.txt\n"
-"\n"
-"if echo \"$USER\" | egrep 'runge' > /dev/null ; then\n"
-" CREATE_DISPLAY_OUTPUT=/tmp/cdo.$USER.txt\n"
-" if [ -f $CREATE_DISPLAY_OUTPUT -a ! -w $CREATE_DISPLAY_OUTPUT ]; then\n"
-" CREATE_DISPLAY_OUTPUT=$CREATE_DISPLAY_OUTPUT.$$\n"
-" fi\n"
-"fi\n"
-"if [ \"X$CREATE_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
-" if [ \"X$CREATE_DISPLAY_EXEC\" = \"X\" ]; then\n"
-" CREATE_DISPLAY_EXEC=1\n"
-" export CREATE_DISPLAY_EXEC\n"
-" if [ \"X$CREATE_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
-" /bin/sh $0 \"$@\" 2> $CREATE_DISPLAY_OUTPUT\n"
-" else\n"
-" /bin/sh $0 \"$@\" 2> /dev/null\n"
-" fi\n"
-" exit $?\n"
-" fi\n"
-"fi\n"
-"if [ \"X$CREATE_DISPLAY_PERL_SETPGRP\" = \"X\" ]; then\n"
-" CREATE_DISPLAY_PERL_SETPGRP=1\n"
-" export CREATE_DISPLAY_PERL_SETPGRP\n"
-" if type perl >/dev/null 2>&1; then\n"
-" perl -e \"setpgrp(0,0); exec '/bin/sh $0 $*'\";\n"
-" exit $?\n"
-" fi\n"
-"fi\n"
-"\n"
-"\n"
-"if [ \"X$CREATE_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
-" set -xv\n"
-"fi\n"
-"\n"
-"COLUMNS=256\n"
-"export COLUMNS\n"
-"\n"
-"LC_ALL_save=$LC_ALL\n"
-"LC_ALL=C\n"
-"export LC_ALL\n"
-"\n"
-"findfree() {\n"
-" try=20\n"
-" dpymax=79\n"
-" if [ \"X$X11VNC_CREATE_STARTING_DISPLAY_NUMBER\" != \"X\" ]; then\n"
-" try=$X11VNC_CREATE_STARTING_DISPLAY_NUMBER\n"
-" fi\n"
-" if [ \"X$X11VNC_CREATE_MAX_DISPLAYS\" != \"X\" ]; then\n"
-" dpymax=$X11VNC_CREATE_MAX_DISPLAYS\n"
-" fi\n"
-" sry=`expr $try + $dpymax`\n"
-" n=\"\"\n"
-" nsout=\"\"\n"
-" if [ \"X$have_netstat\" != \"X\" ]; then\n"
-" nsout=`$have_netstat -an`\n"
-" fi\n"
-" nsout_trim=`echo \"$nsout\" | grep \"/tmp/.X11-unix/\"`\n"
-" while [ $try -lt $sry ]\n"
-" do\n"
-" tlock=\"/tmp/.X${try}-lock\"\n"
-" if [ -r $tlock ]; then\n"
-" if echo \"$nsout_trim\" | grep \"/tmp/.X11-unix/X${try}[ ]*\\$\" > /dev/null; then\n"
-" :\n"
-" else\n"
-" pid=`head -n 1 $tlock 2>/dev/null | sed -e 's/[ ]//g' | grep '^[0-9][0-9]*$'`\n"
-" if [ \"X$pid\" != \"X\" ]; then\n"
-" exists=0\n"
-" if [ -d /proc/$pid ]; then\n"
-" exists=1\n"
-" elif kill -0 $pid 2>/dev/null; then\n"
-" exists=1\n"
-" fi\n"
-" if [ \"X$exists\" = \"X0\" ]; then\n"
-" rm -f $tlock\n"
-" fi\n"
-" fi\n"
-" fi\n"
-" fi\n"
-" if [ ! -f $tlock ]; then\n"
-" if echo \"$nsout_trim\" | grep \"/tmp/.X11-unix/X${try}[ ]*\\$\" > /dev/null; then\n"
-" :\n"
-" else\n"
-" n=$try\n"
-" break\n"
-" fi\n"
-" fi\n"
-" try=`expr $try + 1`\n"
-" done\n"
-" echo \"$n\"\n"
-"}\n"
-"\n"
-"random() {\n"
-" if [ \"X$RANDOM\" != \"X\" ]; then\n"
-" echo \"$RANDOM\"\n"
-" else\n"
-" r1=`bash -c 'echo $RANDOM' 2>/dev/null`\n"
-" if echo \"$r1\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
-" echo \"$r1\"\n"
-" else\n"
-" r2=`sh -c 'echo $$; date; ps -elf' 2>&1 | sum -r 2>/dev/null | awk '{print $1}'`\n"
-" if echo \"$r2\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
-" echo \"$r2\"\n"
-" else\n"
-" r3=`sh -c 'echo $$'`\n"
-" echo \"$r3\"\n"
-" fi\n"
-" fi\n"
-" fi\n"
-"}\n"
-"\n"
-"findsession() {\n"
-" if [ \"X$FD_PROG\" != \"X\" ]; then\n"
-" echo \"$FD_PROG\"\n"
-" return\n"
-" fi\n"
-" if [ \"X$have_gnome_session\" != \"X\" -a \"X$FD_SESS\" = \"Xgnome\" ]; then\n"
-" if [ \"X$have_dbus_launch\" != \"X\" ]; then\n"
-" echo \"$have_dbus_launch --exit-with-session $have_gnome_session\"\n"
-" else\n"
-" echo \"$have_gnome_session\"\n"
-" fi\n"
-" return\n"
-" elif [ \"X$have_startkde\" != \"X\" -a \"X$FD_SESS\" = \"Xkde\" ]; then\n"
-" echo \"$have_startkde\"\n"
-" return\n"
-" elif [ \"X$have_startlxde\" != \"X\" -a \"X$FD_SESS\" = \"Xlxde\" ]; then\n"
-" echo \"$have_startlxde\"\n"
-" return\n"
-" elif [ \"X$have_twm\" != \"X\" -a \"X$FD_SESS\" = \"Xtwm\" ]; then\n"
-" echo \"$have_twm\"\n"
-" return\n"
-" elif [ \"X$have_fvwm2\" != \"X\" -a \"X$FD_SESS\" = \"Xfvwm\" ]; then\n"
-" echo \"$have_fvwm2\"\n"
-" return\n"
-" elif [ \"X$have_mwm\" != \"X\" -a \"X$FD_SESS\" = \"Xmwm\" ]; then\n"
-" echo \"$have_mwm\"\n"
-" return\n"
-" elif [ \"X$have_dtwm\" != \"X\" -a \"X$FD_SESS\" = \"Xdtwm\" ]; then\n"
-" echo \"$have_dtwm\"\n"
-" return\n"
-" elif [ \"X$have_windowmaker\" != \"X\" -a \"X$FD_SESS\" = \"Xwmaker\" ]; then\n"
-" echo \"$have_windowmaker\"\n"
-" return\n"
-" elif [ \"X$have_wmaker\" != \"X\" -a \"X$FD_SESS\" = \"Xwmaker\" ]; then\n"
-" echo \"$have_wmaker\"\n"
-" return\n"
-" elif [ \"X$have_startxfce\" != \"X\" -a \"X$FD_SESS\" = \"Xxfce\" ]; then\n"
-" echo \"$have_startxfce\"\n"
-" return\n"
-" elif [ \"X$have_startxfce4\" != \"X\" -a \"X$FD_SESS\" = \"Xxfce\" ]; then\n"
-" echo \"$have_startxfce4\"\n"
-" return\n"
-" elif [ \"X$have_enlightenment\" != \"X\" -a \"X$FD_SESS\" = \"Xenlightenment\" ]; then\n"
-" echo \"$have_enlightenment\"\n"
-" return\n"
-" elif [ \"X$have_Xsession\" != \"X\" -a \"X$FD_SESS\" = \"XXsession\" ]; then\n"
-" echo \"$have_Xsession\"\n"
-" return\n"
-" elif [ \"X$have_Xsession\" != \"X\" -a \"X$FD_SESS\" = \"Xcde\" ]; then\n"
-" echo \"$have_Xsession\"\n"
-" return\n"
-" elif [ \"X$have_xterm\" != \"X\" -a \"X$FD_SESS\" = \"Xfailsafe\" ]; then\n"
-" echo \"$have_xterm\"\n"
-" return\n"
-" elif [ \"X$have_xterm\" != \"X\" -a \"X$FD_SESS\" = \"Xxterm\" ]; then\n"
-" echo \"$have_xterm\"\n"
-" return\n"
-" fi\n"
-" if type csh > /dev/null 2>&1; then\n"
-" home=`csh -f -c \"echo ~$USER\"`\n"
-" elif type tcsh > /dev/null 2>&1; then\n"
-" home=`tcsh -f -c \"echo ~$USER\"`\n"
-" elif type bash > /dev/null 2>&1; then\n"
-" home=`bash -c \"echo ~$USER\"`\n"
-" else\n"
-" home=\"\"\n"
-" fi\n"
-" if [ \"X$home\" = \"X\" -o ! -d \"$home\" ]; then\n"
-" if [ \"X$have_root\" != \"X\" -a \"X$USER\" != \"Xroot\" ]; then\n"
-" home=`su - $USER -c 'echo $HOME'`\n"
-" fi\n"
-" fi\n"
-" if [ \"X$home\" = \"X\" -o ! -d \"$home\" ]; then\n"
-" if [ -d \"/home/$USER\" ]; then\n"
-" home=\"/home/$USER\"\n"
-" else \n"
-" home=__noplace__\n"
-" fi\n"
-" fi\n"
-" if [ -f \"$home/.dmrc\" ]; then\n"
-" if [ \"X$have_startkde\" != \"X\" ]; then\n"
-" if egrep -i 'Session=kde' \"$home/.dmrc\" > /dev/null; then\n"
-" echo \"$have_startkde\"\n"
-" return\n"
-" fi\n"
-" fi\n"
-" if [ \"X$have_startlxde\" != \"X\" ]; then\n"
-" if egrep -i 'Session=lxde' \"$home/.dmrc\" > /dev/null; then\n"
-" echo \"$have_startlxde\"\n"
-" return\n"
-" fi\n"
-" fi\n"
-" if [ \"X$have_gnome_session\" != \"X\" ]; then\n"
-" if egrep -i 'Session=gnome' \"$home/.dmrc\" > /dev/null; then\n"
-" echo \"$have_gnome_session\"\n"
-" return\n"
-" fi\n"
-" fi\n"
-" for wm in blackbox fvwm icewm wmw openbox twm mwm windowmaker enlightenment metacity startxfce4 startxfce\n"
-" do\n"
-" eval \"have=\\$have_$wm\"\n"
-" if [ \"X$have\" = \"X\" ]; then\n"
-" continue\n"
-" fi\n"
-" if grep -i \"Session=$wm\" \"$home/.dmrc\" > /dev/null; then\n"
-" echo \"$have\"\n"
-" return\n"
-" fi\n"
-" \n"
-" done\n"
-" if egrep -i 'Session=default' \"$home/.dmrc\" > /dev/null; then\n"
-" if [ \"X$have_gnome_session\" != \"X\" ]; then\n"
-" echo \"$have_gnome_session\"\n"
-" return\n"
-" elif [ \"X$have_startkde\" != \"X\" ]; then\n"
-" echo \"$have_startkde\"\n"
-" return\n"
-" elif [ \"X$have_startxfce\" != \"X\" ]; then\n"
-" echo \"$have_startxfce\"\n"
-" return\n"
-" fi\n"
-" fi\n"
-" fi\n"
-" if [ -f \"$home/.xsession\" ]; then\n"
-" echo \"$home/.xsession\"\n"
-" return\n"
-" elif [ -f \"$home/.xinitrc\" ]; then\n"
-" echo \"$home/.xinitrc\"\n"
-" return\n"
-" fi\n"
-" if [ \"X$have_xterm\" != \"X\" ]; then\n"
-" echo $have_xterm\n"
-" return\n"
-" else\n"
-" echo \".xinitrc\"\n"
-" fi\n"
-"}\n"
-"\n"
-"check_redir_services() {\n"
-" redir_daemon=\"\"\n"
-" need_env=\"\"\n"
-" if echo \"$sess\" | grep '^env ' > /dev/null; then\n"
-" sess=`echo \"$sess\" | sed -e 's/^env //'`\n"
-" need_env=1\n"
-" fi\n"
-" if [ \"X$FD_ESD\" != \"X\" -a \"X$have_esddsp\" != \"X\" ]; then\n"
-" if echo \"$FD_ESD\" | grep '^DAEMON-' > /dev/null; then\n"
-" FD_ESD=`echo \"$FD_ESD\" | sed -e 's/DAEMON-//'`\n"
-" rport=`echo \"$FD_ESD\" | sed -e 's/^.*://'`\n"
-" dport=`expr $rport + 1`\n"
-" dport=`freeport $dport`\n"
-" FD_ESD=$dport\n"
-" redir_daemon=\"$redir_daemon,TS_ESD_REDIR:$dport:$rport\"\n"
-" fi\n"
-" if echo \"$FD_ESD\" | grep ':' > /dev/null; then\n"
-" :\n"
-" else\n"
-" FD_ESD=\"localhost:$FD_ESD\"\n"
-" fi\n"
-" sess=\"ESPEAKER=$FD_ESD $have_esddsp -s $FD_ESD $sess\"\n"
-" need_env=1\n"
-" fi\n"
-" if [ \"X$FD_CUPS\" != \"X\" ]; then\n"
-" if echo \"$FD_CUPS\" | grep '^DAEMON-' > /dev/null; then\n"
-" FD_CUPS=`echo \"$FD_CUPS\" | sed -e 's/DAEMON-//'`\n"
-" rport=`echo \"$FD_CUPS\" | sed -e 's/^.*://'`\n"
-" dport=`expr $rport + 1`\n"
-" dport=`freeport $dport`\n"
-" FD_CUPS=$dport\n"
-" redir_daemon=\"$redir_daemon,TS_CUPS_REDIR:$dport:$rport\"\n"
-" fi\n"
-" if echo \"$FD_CUPS\" | grep ':' > /dev/null; then\n"
-" :\n"
-" else\n"
-" FD_CUPS=\"localhost:$FD_CUPS\"\n"
-" fi\n"
-" csr=`echo \"$FD_CUPS\" | awk -F: '{print $1}'`\n"
-" ipp=`echo \"$FD_CUPS\" | awk -F: '{print $2}'`\n"
-" old=`strings -a /usr/sbin/cupsd 2>/dev/null | grep 'CUPS.v1\\.[01]'`\n"
-" if [ \"X$old\" != \"X\" ]; then\n"
-" FD_CUPS=`echo \"$FD_CUPS\" | sed -e 's/:.*$//'`\n"
-" fi\n"
-" sess=\"CUPS_SERVER=$FD_CUPS IPP_PORT=$ipp $sess\"\n"
-" need_env=1\n"
-" fi\n"
-"\n"
-" if [ \"X$FD_SMB\" != \"X\" ]; then\n"
-" if echo \"$FD_SMB\" | grep '^DAEMON-' > /dev/null; then\n"
-" FD_SMB=`echo \"$FD_SMB\" | sed -e 's/DAEMON-//'`\n"
-" rport=`echo \"$FD_SMB\" | sed -e 's/^.*://'`\n"
-" dport=`expr $rport + 1`\n"
-" dport=`freeport $dport`\n"
-" FD_SMB=$dport\n"
-" redir_daemon=\"$redir_daemon,TS_SMB_REDIR:$dport:$rport\"\n"
-" fi\n"
-" if echo \"$FD_SMB\" | grep ':' > /dev/null; then\n"
-" :\n"
-" else\n"
-" FD_SMB=\"localhost:$FD_SMB\"\n"
-" fi\n"
-" smh=`echo \"$FD_SMB\" | awk -F: '{print $1}'`\n"
-" smp=`echo \"$FD_SMB\" | awk -F: '{print $2}'`\n"
-" if [ \"X$smh\" = \"X\" ]; then\n"
-" smh=localhost\n"
-" fi\n"
-" sess=\"SMB_SERVER=$FD_SMB SMB_HOST=$smh SMB_PORT=$smp $sess\"\n"
-" need_env=1\n"
-" fi\n"
-"\n"
-" if [ \"X$FD_NAS\" != \"X\" ]; then\n"
-" if echo \"$FD_NAS\" | grep '^DAEMON-' > /dev/null; then\n"
-" FD_NAS=`echo \"$FD_NAS\" | sed -e 's/DAEMON-//'`\n"
-" rport=`echo \"$FD_NAS\" | sed -e 's/^.*://'`\n"
-" dport=`expr $rport + 1`\n"
-" dport=`freeport $dport`\n"
-" FD_NAS=$dport\n"
-" redir_daemon=\"$redir_daemon,TS_NAS_REDIR:$dport:$rport\"\n"
-" fi\n"
-" if echo \"$FD_NAS\" | grep ':' > /dev/null; then\n"
-" :\n"
-" else\n"
-" FD_NAS=\"tcp/localhost:$FD_NAS\"\n"
-" fi\n"
-" sess=\"AUDIOSERVER=$FD_NAS $sess\"\n"
-" need_env=1\n"
-" fi\n"
-" if [ \"X$need_env\" != \"X\" ]; then\n"
-" sess=\"env $sess\"\n"
-" fi\n"
-" redir_daemon=`echo \"$redir_daemon\" | sed -e 's/^,*//'`\n"
-" echo \"redir_daemon=$redir_daemon\" 1>&2\n"
-"}\n"
-"\n"
-"rchk() {\n"
-" rr=rr\n"
-"}\n"
-"\n"
-"dL=\"-L\"\n"
-"if uname -sr | egrep 'SunOS 5\\.[5-8]' > /dev/null; then\n"
-" dL=\"-h\"\n"
-"fi\n"
-"\n"
-"# a portable tmp file creator\n"
-"mytmp() {\n"
-" tf=$1\n"
-" if type mktemp > /dev/null 2>&1; then\n"
-" # if we have mktemp(1), use it:\n"
-" tf2=\"$tf.XXXXXX\"\n"
-" tf2=`mktemp \"$tf2\"`\n"
-" if [ \"X$tf2\" != \"X\" -a -f \"$tf2\" ]; then\n"
-" if [ \"X$DEBUG_MKTEMP\" != \"X\" ]; then\n"
-" echo \"mytmp-mktemp: $tf2\" 1>&2\n"
-" fi\n"
-" echo \"$tf2\"\n"
-" return\n"
-" fi\n"
-" fi\n"
-" # fallback to multiple cmds:\n"
-" rm -rf \"$tf\" || exit 1\n"
-" if [ -d \"$tf\" ]; then\n"
-" echo \"tmp file $tf still exists as a directory.\"\n"
-" exit 1\n"
-" elif [ $dL \"$tf\" ]; then\n"
-" echo \"tmp file $tf still exists as a symlink.\"\n"
-" exit 1\n"
-" elif [ -f \"$tf\" ]; then\n"
-" echo \"tmp file $tf still exists.\"\n"
-" exit 1\n"
-" fi\n"
-" touch \"$tf\" || exit 1\n"
-" chmod 600 \"$tf\" || exit 1\n"
-" rchk\n"
-" if [ \"X$DEBUG_MKTEMP\" != \"X\" ]; then\n"
-" echo \"mytmp-touch: $tf\" 1>&2\n"
-" fi\n"
-" echo \"$tf\"\n"
-"}\n"
-"\n"
-"missing_mesg() {\n"
-" echo \"\" 1>&2\n"
-" echo \"The program \\\"$1\\\" could not be found in PATH and standard locations.\" 1>&2\n"
-" echo \"You probably need to install a package that provides the \\\"$1\\\" program.\" 1>&2\n"
-" echo \"\" 1>&2\n"
-"}\n"
-"\n"
-"put_back_LC_ALL() {\n"
-" if [ \"X$X11VNC_CREATE_LC_ALL_C_OK\" = \"X\" ]; then\n"
-" if [ \"X$LC_ALL_save\" = \"X\" ]; then\n"
-" unset LC_ALL\n"
-" else\n"
-" LC_ALL=\"$LC_ALL_save\"\n"
-" fi\n"
-" fi\n"
-"}\n"
-"\n"
-"server() {\n"
-" authfile=`auth`\n"
-" sess=`findsession`\n"
-" DISPLAY=:$N\n"
-" export DISPLAY\n"
-" stmp=\"\"\n"
-" noxauth=\"\"\n"
-" if [ \"X$have_root\" != \"X\" -a \"X$USER\" != \"Xroot\" ]; then\n"
-" sess=\"env DISPLAY=:$N $sess\"\n"
-" noxauth=\"1\"\n"
-" fi\n"
-"\n"
-" redir_daemon=\"\"\n"
-" check_redir_services\n"
-"\n"
-" rmf=\"/nosuch\"\n"
-" if echo \"$sess\" | grep '[ ]' > /dev/null; then\n"
-" stmp=/tmp/.cd$$`random`\n"
-" stmp=`mytmp \"$stmp\"`\n"
-" touch $stmp\n"
-" chmod 755 $stmp || exit 1\n"
-" echo \"#!/bin/sh\" > $stmp\n"
-" #echo \"(id; env; env | grep XAUTHORITY | sed -e 's/XAUTHORITY=//' | xargs ls -l) > /tmp/ENV.OUT.$$\" >> $stmp\n"
-" if [ \"X$SAVE_PATH\" != \"X\" ]; then\n"
-" echo \"PATH=\\\"$SAVE_PATH\\\"\" >> $stmp\n"
-" echo \"export PATH\" >> $stmp\n"
-" fi\n"
-" if [ \"X$noxauth\" = \"X1\" ]; then\n"
-" echo \"unset XAUTHORITY\" >> $stmp\n"
-" fi\n"
-" echo \"$sess\" >> $stmp\n"
-" echo \"sleep 1\" >> $stmp\n"
-" echo \"rm -f $stmp\" >> $stmp\n"
-" sess=$stmp\n"
-" rmf=\"$stmp\"\n"
-" fi\n"
-"\n"
-" if [ \"X$have_root\" != \"X\" -a \"X$USER\" != \"Xroot\" ]; then\n"
-" ctmp1=/tmp/.xat1_$$`random`\n"
-" ctmp1=`mytmp \"$ctmp1\"`\n"
-" ctmp2=/tmp/.xat2_$$`random`\n"
-" ctmp2=`mytmp \"$ctmp2\"`\n"
-" touch $ctmp1 $ctmp2\n"
-" $have_xauth -f $authfile nextract - :$N > $ctmp1\n"
-" $have_xauth -f $authfile nextract - `hostname`:$N > $ctmp2\n"
-" chown $USER $ctmp1 $ctmp2\n"
-" (unset XAUTHORITY; su - $USER -c \"$have_xauth nmerge - < $ctmp1\" 1>&2)\n"
-" (unset XAUTHORITY; su - $USER -c \"$have_xauth nmerge - < $ctmp2\" 1>&2)\n"
-" rm -f $ctmp1 $ctmp2\n"
-" XAUTHORITY=$authfile\n"
-" export XAUTHORITY\n"
-" sess=\"/bin/su - $USER -c $sess\"\n"
-" else\n"
-" $have_xauth -f $authfile nextract - :$N | $have_xauth nmerge -\n"
-" $have_xauth -f $authfile nextract - `hostname`:$N | $have_xauth nmerge -\n"
-" fi\n"
-"\n"
-" result=0\n"
-" #ns=4\n"
-" ns=0\n"
-" ns2=1\n"
-" #if uname | grep SunOS > /dev/null; then\n"
-" # ns=2\n"
-" #fi\n"
-"\n"
-"\n"
-" if [ \"X$use_xdmcp_query\" = \"X1\" ]; then\n"
-" # we cannot use -nolisten tcp\n"
-" if [ \"X$FD_XDMCP_IF\" != \"X\" ]; then\n"
-" lhost=$FD_XDMCP_IF\n"
-" elif [ \"X$have_netstat\" = \"X\" ]; then\n"
-" lhost=localhost\n"
-" elif $have_netstat -an | grep -w 177 | grep -w udp > /dev/null; then\n"
-" lhost=localhost\n"
-" elif $have_netstat -an | grep -w 177 | grep -w udp6 > /dev/null; then\n"
-" lhost=::1\n"
-" else\n"
-" lhost=localhost\n"
-" fi\n"
-" echo \"$* -once -query $lhost $FD_OPTS\" 1>&2\n"
-" put_back_LC_ALL\n"
-" if [ \"X$have_root\" != \"X\" ]; then\n"
-" if [ -r $authfile ]; then\n"
-" $have_nohup $* -once -query $lhost -auth $authfile $FD_OPTS 1>&2 &\n"
-" else\n"
-" # why did we have this?\n"
-" $have_nohup $* -once -query $lhost $FD_OPTS 1>&2 &\n"
-" fi\n"
-" else\n"
-" if [ \"X$ns\" = \"X0\" ]; then\n"
-" $have_nohup sh -c \"$* -once -query $lhost -auth $authfile $FD_OPTS\" 1>&2 &\n"
-" else\n"
-" $have_nohup sh -c \"(sleep $ns; $* -once -query $lhost -auth $authfile $FD_OPTS)\" 1>&2 &\n"
-" #result=1\n"
-" fi\n"
-" fi\n"
-" pid=$!\n"
-" sleep 10\n"
-" elif [ \"X$have_startx\" != \"X\" -o \"X$have_xinit\" != \"X\" ]; then\n"
-" if [ \"X$have_xinit\" != \"X\" ]; then\n"
-" sxcmd=$have_xinit\n"
-" else\n"
-" sxcmd=$have_startx\n"
-" fi\n"
-" echo \"$sxcmd $sess -- $* $nolisten -auth $authfile $FD_OPTS\" 1>&2\n"
-" put_back_LC_ALL\n"
-" if [ \"X$have_root\" != \"X\" ]; then\n"
-" $sxcmd $sess -- $* $nolisten -auth $authfile $FD_OPTS 1>&2 &\n"
-" else\n"
-" if [ \"X$ns\" = \"X0\" ]; then\n"
-" $have_nohup sh -c \"$sxcmd $sess -- $* $nolisten -auth $authfile $FD_OPTS\" 1>&2 &\n"
-" else\n"
-" # Why did we ever sleep before starting the server??\n"
-" $have_nohup sh -c \"(sleep $ns; $sxcmd $sess -- $* $nolisten -auth $authfile $FD_OPTS)\" 1>&2 &\n"
-" #result=1\n"
-" fi\n"
-" fi\n"
-" pid=$!\n"
-" else\n"
-" # need to emulate startx/xinit ourselves...\n"
-" echo \"$* $nolisten -auth $authfile $FD_OPTS\" 1>&2\n"
-" put_back_LC_ALL\n"
-" if [ \"X$have_root\" != \"X\" ]; then\n"
-" $have_nohup $* $nolisten -auth $authfile $FD_OPTS 1>&2 &\n"
-" pid=$!\n"
-" sleep 3\n"
-" $have_nohup $sess 1>&2 &\n"
-" else\n"
-" if [ \"X$ns\" = \"X0\" ]; then\n"
-" $have_nohup sh -c \"$* $nolisten -auth $authfile $FD_OPTS\" 1>&2 &\n"
-" else\n"
-" $have_nohup sh -c \"(sleep $ns; $* $nolisten -auth $authfile $FD_OPTS)\" 1>&2 &\n"
-" #result=1\n"
-" fi\n"
-" pid=$!\n"
-" sleep 3\n"
-" $have_nohup sh -c \"(sleep 3; $sess)\" 1>&2 &\n"
-" fi\n"
-" fi\n"
-"\n"
-" LC_ALL=C\n"
-" export LC_ALL\n"
-"\n"
-" if uname | grep SunOS > /dev/null; then\n"
-" $have_nohup sh -c \"(sleep 150; rm -f $rmf)\" 1>&2 &\n"
-" else\n"
-" $have_nohup sh -c \"(sleep 150; rm -f $rmf $authfile)\" 1>&2 &\n"
-" fi\n"
-"\n"
-" t=0\n"
-" tmax=5\n"
-" while [ $t -lt $tmax ]\n"
-" do\n"
-" t=`expr $t + 1`\n"
-" sleep $ns2\n"
-" pid2=`head -n 1 \"/tmp/.X$N-lock\" 2>/dev/null | sed -e 's/[ ]//g' | grep '^[0-9][0-9]*$'`\n"
-" if [ \"X$pid2\" = \"X\" ]; then\n"
-" pid2=9999999\n"
-" fi\n"
-" if [ \"X$result\" = \"X1\" ]; then\n"
-" break\n"
-" elif [ -d /proc/$pid2 ]; then\n"
-" result=1\n"
-" break\n"
-" elif kill -0 $pid2 2>/dev/null; then\n"
-" result=1\n"
-" break\n"
-" elif [ -d /proc/$pid ]; then\n"
-" result=1\n"
-" break\n"
-" elif kill -0 $pid 2>/dev/null; then\n"
-" result=1\n"
-" break\n"
-" else\n"
-" result=0\n"
-" fi\n"
-" if [ \"X$have_netstat\" != \"X\" ]; then\n"
-" if $have_netstat -an | grep \"/tmp/.X11-unix/X$N\\$\" > /dev/null; then\n"
-" result=1\n"
-" fi\n"
-" fi\n"
-" done\n"
-"\n"
-" if [ \"X$redir_daemon\" != \"X\" -a \"X$result\" = \"X1\" ]; then\n"
-" redir_daemon=`echo \"$redir_daemon\" | sed -e 's/[~!$&*()|;?<>\"]//g' -e \"s/'//g\"`\n"
-" xprog=$X11VNC_PROG\n"
-" if [ \"X$xprog\" = \"X\" ]; then\n"
-" xprog=x11vnc\n"
-" fi\n"
-" echo \"running: $xprog -sleepin 10 -auth $authfile -tsd '$redir_daemon'\" 1>&2\n"
-" $have_nohup sh -c \"$xprog -sleepin 10 -auth $authfile -tsd '$redir_daemon' &\" 2>.tsd.log.$USER 1>&2 &\n"
-" fi\n"
-"}\n"
-"\n"
-"try_X() {\n"
-" if [ \"X$use_xdmcp_query\" = \"X1\" ]; then\n"
-" if [ \"X$have_X\" != \"X\" ]; then\n"
-" server $have_X :$N\n"
-" elif [ \"X$have_Xorg\" != \"X\" ]; then\n"
-" server $have_Xorg :$N\n"
-" elif [ \"X$have_XFree86\" != \"X\" ]; then\n"
-" server $have_XFree86 :$N\n"
-" elif [ \"X$have_Xsun\" != \"X\" ]; then\n"
-" server $have_Xsun :$N\n"
-" fi\n"
-" elif [ \"X$have_xinit\" != \"X\" ]; then\n"
-" save_have_startx=$have_startx\n"
-" have_startx=\"\"\n"
-" server :$N\n"
-" have_startx=$save_have_startx\n"
-" else\n"
-" server :$N\n"
-" fi\n"
-"}\n"
-"\n"
-"try_Xvnc() {\n"
-" if [ \"X$have_Xvnc\" = \"X\" ]; then\n"
-" missing_mesg Xvnc\n"
-" return\n"
-" fi\n"
-"\n"
-" server $have_Xvnc :$N -geometry $geom -depth $depth\n"
-"}\n"
-"\n"
-"try_Xsrv() {\n"
-" if [ \"X$FD_XSRV\" = \"X\" ]; then\n"
-" return\n"
-" fi\n"
-"\n"
-" server $FD_XSRV :$N -geometry $geom -depth $depth\n"
-"}\n"
-"\n"
-"add_modmap() {\n"
-" if [ \"X$have_root\" = \"X\" ]; then\n"
-" $have_nohup sh -c \"(\n"
-" sleep 10;\n"
-" $have_xmodmap -display :$N -e 'keycode any = Shift_R' \\\n"
-" -e 'add Shift = Shift_L Shift_R' \\\n"
-" -e 'keycode any = Control_R' \\\n"
-" -e 'add Control = Control_L Control_R' \\\n"
-" -e 'keycode any = Alt_L' \\\n"
-" -e 'keycode any = Alt_R' \\\n"
-" -e 'keycode any = Meta_L' \\\n"
-" -e 'clear Mod1' \\\n"
-" -e 'add Mod1 = Alt_L Alt_R Meta_L';\n"
-" if uname | grep SunOS > /dev/null; then\n"
-" for sym in SunAudioMute SunAudioLowerVolume SunAudioRaiseVolume\n"
-" do\n"
-" if $have_xmodmap -pk | grep -w \\$sym > /dev/null; then\n"
-" :\n"
-" else\n"
-" $have_xmodmap -e \\\"keycode any = \\$sym\\\"\n"
-" fi\n"
-" done\n"
-" fi\n"
-"\n"
-" )\" 1>&2 &\n"
-" else\n"
-" (\n"
-" sleep 6;\n"
-" $have_xmodmap -display :$N -e 'keycode any = Shift_R' \\\n"
-" -e 'add Shift = Shift_L Shift_R' \\\n"
-" -e 'keycode any = Control_R' \\\n"
-" -e 'add Control = Control_L Control_R' \\\n"
-" -e 'keycode any = Alt_L' \\\n"
-" -e 'keycode any = Alt_R' \\\n"
-" -e 'keycode any = Meta_L' \\\n"
-" -e 'clear Mod1' \\\n"
-" -e 'add Mod1 = Alt_L Alt_R Meta_L';\n"
-" # this is to workaround a bug with JDS Solaris 10 gnome-session-daemon.\n"
-" if uname | grep SunOS > /dev/null; then\n"
-" for sym in SunAudioMute SunAudioLowerVolume SunAudioRaiseVolume\n"
-" do\n"
-" if $have_xmodmap -pk | grep -w $sym > /dev/null; then\n"
-" :\n"
-" else\n"
-" $have_xmodmap -e \"keycode any = $sym\"\n"
-" fi\n"
-" done\n"
-" fi\n"
-" ) 1>&2 &\n"
-" fi\n"
-"}\n"
-"\n"
-"try_Xvfb() {\n"
-" if [ \"X$have_Xvfb\" = \"X\" ]; then\n"
-" missing_mesg Xvfb\n"
-" return\n"
-" fi\n"
-"\n"
-" sarg=\"-screen\"\n"
-" if uname | grep SunOS > /dev/null; then\n"
-" if grep /usr/openwin/bin/Xsun $have_Xvfb > /dev/null; then\n"
-" sarg=\"screen\"\n"
-" fi\n"
-" fi\n"
-" margs=\"\"\n"
-" if $have_Xvfb -help 2>&1 | grep '^\\+kb[ ].*Keyboard Extension' >/dev/null; then\n"
-" margs=\"+kb\"\n"
-" fi\n"
-"\n"
-" # currently not enabled in Xvfb's we see.\n"
-"# if $have_Xvfb -extension MOOMOO 2>&1 | grep -w RANDR >/dev/null; then\n"
-"# margs=\"$margs +extension RANDR\"\n"
-"# fi\n"
-"\n"
-" if [ $depth -ge 16 ]; then\n"
-" # avoid DirectColor for default visual:\n"
-" margs=\"$margs -cc 4\"\n"
-" fi\n"
-" server $have_Xvfb :$N $sarg 0 ${geom}x${depth} $margs\n"
-"\n"
-" if [ \"X$result\" = \"X1\" -a \"X$have_xmodmap\" != \"X\" ]; then\n"
-" add_modmap\n"
-" fi\n"
-"}\n"
-"\n"
-"try_Xdummy() {\n"
-" if [ \"X$have_Xdummy\" = \"X\" ]; then\n"
-" missing_mesg Xdummy\n"
-" return\n"
-" fi\n"
-" if [ \"X$FD_XDUMMY_RUN_AS_ROOT\" != \"X\" -a \"X$have_root\" = \"X\" ]; then\n"
-" return\n"
-" fi\n"
-"\n"
-" server $have_Xdummy :$N -geometry $geom -depth $depth\n"
-" \n"
-" if [ \"X$result\" = \"X1\" -a \"X$have_xprop\" != \"X\" ]; then\n"
-" (sleep 1; $have_xprop -display :$N -root -f X11VNC_TRAP_XRANDR 8s -set X11VNC_TRAP_XRANDR 1 >/dev/null 2>&1) &\n"
-" sleep 1\n"
-" fi\n"
-"}\n"
-"\n"
-"\n"
-"cookie() {\n"
-" cookie=\"\"\n"
-" if [ \"X$have_mcookie\" != \"X\" ]; then\n"
-" cookie=`mcookie`\n"
-" elif [ \"X$have_md5sum\" != \"X\" ]; then\n"
-" if [ -c /dev/urandom ]; then\n"
-" cookie=`dd if=/dev/urandom count=32 2>/dev/null | md5sum | awk '{print $1}'`\n"
-" elif [ -c /dev/random ]; then\n"
-" cookie=`dd if=/dev/random count=32 2>/dev/null | md5sum | awk '{print $1}'`\n"
-" fi\n"
-" if [ \"X$cookie\" = \"X\" ]; then\n"
-" r=`random`\n"
-" cookie=`(echo $r; date; uptime; ps -ealf 2>&1) | md5sum | awk '{print $1}'`\n"
-" fi\n"
-" elif [ \"X$have_xauth\" != \"X\" ]; then\n"
-" if uname | grep SunOS > /dev/null; then\n"
-" cookie=`$have_xauth list | awk '{print $NF}' | tail -1`\n"
-" else\n"
-" cookie=`$have_xauth list | awk '{print $NF}' | tail -n 1`\n"
-" fi\n"
-" fi\n"
-" if [ \"X$cookie\" = \"X\" ]; then\n"
-" # oh well..\n"
-" for k in 1 2 3 4\n"
-" do\n"
-" r=`random`\n"
-" cookie=$cookie`printf \"%08x\" \"${r}$$\"`\n"
-" done\n"
-" fi\n"
-" echo \"$cookie\"\n"
-"}\n"
-"\n"
-"auth() {\n"
-" if [ \"X$have_xauth\" = \"X\" ]; then\n"
-" exit 1\n"
-" fi\n"
-" tmp=/tmp/.xas$$`random`\n"
-" tmp=`mytmp \"$tmp\"`\n"
-" touch $tmp\n"
-" chmod 600 $tmp || exit 1\n"
-" if [ ! -f $tmp ]; then\n"
-" exit 1\n"
-" fi\n"
-" cook=`cookie`\n"
-" $have_xauth -f $tmp add :$N . $cook 1>&2\n"
-" $have_xauth -f $tmp add `hostname`:$N . $cook 1>&2\n"
-" if [ \"X$CREATE_DISPLAY_EXEC\" != \"X\" ]; then\n"
-" ls -l $tmp 1>&2\n"
-" $have_xauth -f $tmp list 1>&2\n"
-" fi\n"
-" echo \"$tmp\"\n"
-"}\n"
-"\n"
-"freeport() {\n"
-" base=$1\n"
-" if [ \"X$have_uname\" != \"X\" -a \"X$have_netstat\" != \"X\" ]; then\n"
-" inuse=\"\"\n"
-" if $have_uname | grep Linux > /dev/null; then\n"
-" inuse=`$have_netstat -ant | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*://'`\n"
-" elif $have_uname | grep SunOS > /dev/null; then\n"
-" inuse=`$have_netstat -an -f inet -P tcp | grep LISTEN | awk '{print $1}' | sed 's/^.*\\.//'`\n"
-" elif $have_uname | grep -i bsd > /dev/null; then\n"
-" inuse=`$have_netstat -ant -f inet | grep LISTEN | awk '{print $4}' | sed 's/^.*\\.//'`\n"
-" # add others...\n"
-" fi\n"
-" fi\n"
-" i=0\n"
-" ok=\"\"\n"
-" while [ $i -lt 500 ]\n"
-" do\n"
-" tryp=`expr $base + $i`\n"
-" if echo \"$inuse\" | grep -w \"$tryp\" > /dev/null; then\n"
-" :\n"
-" elif echo \"$palloc\" | tr ' ' '\\n' | grep -w \"$tryp\" > /dev/null; then\n"
-" :\n"
-" else\n"
-" ok=$tryp\n"
-" break\n"
-" fi\n"
-" i=`expr $i + 1`\n"
-" done\n"
-" if [ \"X$ok\" != \"X\" ]; then\n"
-" base=$ok\n"
-" fi\n"
-" if [ \"X$palloc\" = \"X\" ]; then\n"
-" palloc=\"$base\"\n"
-" else\n"
-" palloc=\"$palloc $base\"\n"
-" fi\n"
-" echo \"$base\"\n"
-"}\n"
-"\n"
-"\n"
-"depth0=24\n"
-"geom0=1280x1024\n"
-"depth=${depth:-24}\n"
-"geom=${geom:-1280x1024}\n"
-"\n"
-"nolisten=${FD_NOLISTEN:-\"-nolisten tcp\"}\n"
-"\n"
-"if [ \"X$X11VNC_CREATE_GEOM\" != \"X\" -a \"X$FD_GEOM\" = \"X\" ]; then\n"
-" FD_GEOM=$X11VNC_CREATE_GEOM\n"
-"fi\n"
-"\n"
-"if [ \"X$FD_GEOM\" != \"X\" -a \"X$FD_GEOM\" != \"XNONE\" ]; then\n"
-" x1=`echo \"$FD_GEOM\" | awk -Fx '{print $1}'`\n"
-" y1=`echo \"$FD_GEOM\" | awk -Fx '{print $2}'`\n"
-" d1=`echo \"$FD_GEOM\" | awk -Fx '{print $3}'`\n"
-" if [ \"X$x1\" != \"X\" -a \"X$y1\" != \"X\" ]; then\n"
-" geom=\"${x1}x${y1}\"\n"
-" fi\n"
-" if [ \"X$d1\" != \"X\" ]; then\n"
-" depth=\"${d1}\"\n"
-" fi\n"
-"fi\n"
-"\n"
-"depth=`echo \"$depth\" | head -n 1`\n"
-"geom=`echo \"$geom\" | head -n 1`\n"
-"\n"
-"if echo \"$depth\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
-" :\n"
-"else\n"
-" depth=$depth0\n"
-"fi\n"
-"if echo \"$geom\" | grep '^[0-9][0-9]*x[0-9][0-9]*$' > /dev/null; then\n"
-" :\n"
-"else\n"
-" geom=$geom0\n"
-"fi\n"
-"\n"
-"if [ \"X$USER\" = \"X\" ]; then\n"
-" USER=$LOGNAME\n"
-"fi\n"
-"if [ \"X$USER\" = \"X\" ]; then\n"
-" USER=`whoami`\n"
-"fi\n"
-"\n"
-"# Set PATH to have a better chance of finding things:\n"
-"SAVE_PATH=$PATH\n"
-"PATH=$PATH:/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/dt/bin:/opt/kde4/bin:/opt/kde3/bin:/opt/gnome/bin:/usr/bin:/bin:/usr/sfw/bin:/usr/local/bin\n"
-"\n"
-"have_root=\"\"\n"
-"id0=`id`\n"
-"if id | sed -e 's/ gid.*$//' | grep -w root > /dev/null; then\n"
-" have_root=\"1\"\n"
-"fi\n"
-"\n"
-"p_ok=0\n"
-"if [ \"`type -p /bin/sh`\" = \"/bin/sh\" ]; then\n"
-" p_ok=1\n"
-"fi\n"
-"\n"
-"for prog in startx xinit xdm gdm kdm xterm Xdummy Xvfb Xvnc xauth xdpyinfo mcookie md5sum xmodmap startkde startlxde dbus-launch gnome-session blackbox fvwm2 mwm openbox twm windowmaker wmaker enlightenment metacity X Xorg XFree86 Xsun Xsession dtwm netstat nohup esddsp konsole gnome-terminal x-terminal-emulator perl startxfce4 startxfce xprop\n"
-"do\n"
-" p2=`echo \"$prog\" | sed -e 's/-/_/g'`\n"
-" eval \"have_$p2=''\"\n"
-" if type $prog > /dev/null 2>&1; then\n"
-" bpath=`which $prog | awk '{print $NF}'`\n"
-" if [ ! -x \"$bpath\" -o -d \"$bpath\" ]; then\n"
-" if [ \"X$p_ok\" = \"X1\" ]; then\n"
-" bpath=`type -p $prog | awk '{print $NF}'`\n"
-" fi\n"
-" if [ ! -x \"$bpath\" -o -d \"$bpath\" ]; then\n"
-" bpath=`type $prog | awk '{print $NF}'`\n"
-" fi\n"
-" fi\n"
-" eval \"have_$p2=$bpath\"\n"
-" fi\n"
-"done\n"
-"if [ \"X$have_xterm\" = \"X\" ]; then\n"
-" if [ \"X$have_gnome_terminal\" != \"X\" ]; then\n"
-" have_xterm=$have_gnome_terminal\n"
-" elif [ \"X$have_konsole\" != \"X\" ]; then\n"
-" have_xterm=$have_konsole\n"
-" elif [ \"X$have_x_terminal_emulator\" != \"X\" ]; then\n"
-" have_xterm=$have_x_terminal_emulator\n"
-" fi\n"
-"fi\n"
-"\n"
-"if [ \"X$have_nohup\" = \"X\" ]; then\n"
-" have_nohup=\"nohup\"\n"
-"fi\n"
-"\n"
-"N=`findfree`\n"
-"\n"
-"if [ \"X$N\" = \"X\" ]; then\n"
-" exit 1\n"
-"fi\n"
-"echo \"trying N=$N ...\" 1>&2\n"
-"\n"
-"if [ \"X$CREATE_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
-" set | grep \"^have_\" 1>&2\n"
-"fi\n"
-"\n"
-"TRY=\"$1\"\n"
-"if [ \"X$TRY\" = \"X\" ]; then\n"
-" TRY=Xvfb,Xdummy\n"
-"fi\n"
-"\n"
-"for curr_try in `echo \"$TRY\" | tr ',' ' '`\n"
-"do\n"
-" result=0\n"
-" use_xdmcp_query=0\n"
-" if echo \"$curr_try\" | egrep '[+.-]xdmcp' > /dev/null; then\n"
-" use_xdmcp_query=1\n"
-" fi\n"
-"\n"
-" if [ \"X$X11VNC_XDM_ONLY\" = \"X1\" -a \"X$use_xdmcp_query\" = \"X0\" ]; then\n"
-" echo \"SKIPPING NON-XDMCP item '$curr_try' in X11VNC_XDM_ONLY=1 mode.\" 1>&2\n"
-" continue\n"
-" fi\n"
-" \n"
-" curr_try=`echo \"$curr_try\" | sed -e 's/[+.-]xdmcp//'`\n"
-" curr_try=`echo \"$curr_try\" | sed -e 's/[+.-]redirect//'`\n"
-"\n"
-" if echo \"$curr_try\" | grep -i '^Xdummy\\>' > /dev/null; then\n"
-" try_Xdummy\n"
-" elif echo \"$curr_try\" | grep -i '^Xdummy$' > /dev/null; then\n"
-" try_Xdummy\n"
-" elif echo \"$curr_try\" | grep -i '^Xvfb\\>' > /dev/null; then\n"
-" try_Xvfb\n"
-" elif echo \"$curr_try\" | grep -i '^Xvfb$' > /dev/null; then\n"
-" try_Xvfb\n"
-" elif echo \"$curr_try\" | grep -i '^Xvnc\\>' > /dev/null; then\n"
-" try_Xvnc\n"
-" elif echo \"$curr_try\" | grep -i '^Xvnc$' > /dev/null; then\n"
-" try_Xvnc\n"
-" elif echo \"$curr_try\" | grep -i '^Xsrv\\>' > /dev/null; then\n"
-" try_Xsrv\n"
-" elif echo \"$curr_try\" | grep -i '^Xsrv$' > /dev/null; then\n"
-" try_Xsrv\n"
-" elif echo \"$curr_try\" | grep -i '^X\\>' > /dev/null; then\n"
-" try_X\n"
-" elif echo \"$curr_try\" | grep -i '^X$' > /dev/null; then\n"
-" try_X\n"
-" fi\n"
-" if [ \"X$result\" = \"X1\" ]; then\n"
-" echo \"DISPLAY=:$N\"\n"
-" $have_xauth -f $authfile extract - :$N\n"
-" if [ \"X$FD_EXTRA\" != \"X\" ]; then\n"
-" $have_nohup env DISPLAY=:$N sh -c \"(sleep 2; $FD_EXTRA) &\" 1>&2 &\n"
-" fi\n"
-" exit 0\n"
-" fi\n"
-"done\n"
-"\n"
-"exit 1\n"
-;
-
-char macosx_solid_background[] =
-"#!/bin/sh\n"
-"\n"
-"#set -xv\n"
-"\n"
-"# This is where the user's screen/slide savers are stored:\n"
-"#\n"
-"SS_DIR=\"$HOME/Library/Screen Savers\"\n"
-"\n"
-"if [ ! -d \"$SS_DIR\" ]; then\n"
-" exit\n"
-"fi\n"
-"\n"
-"PATH=/bin:/usr/bin:$PATH; export PATH\n"
-"\n"
-"# Check to see if our tarball has already been unpacked. If it has been\n"
-"# we don't unpack it again. This lets the user overwrite the png with\n"
-"# a different color if they want. At some point we could try to create\n"
-"# or own PPM file or something on the fly...\n"
-"#\n"
-"test_file=\"$SS_DIR/VncSolidColor.slideSaver/Contents/Resources/VncSolidColor01.png\"\n"
-"if [ ! -f \"$test_file\" ]; then\n"
-" # get the line number the tarball data starts at:\n"
-" N=`grep -n ^void_func \"$0\" | awk -F: '{print $1}' | head -n 1`\n"
-" if echo \"$N\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
-" :\n"
-" else\n"
-" exit\n"
-" fi\n"
-" N=`expr $N + 1`\n"
-"\n"
-" # pipe the bottom of this file through uudecode and tar:\n"
-" tail -n +$N \"$0\" | (cd \"$SS_DIR\" || exit 1; uudecode -o /dev/stdout | tar xzf -)\n"
-"fi\n"
-"if [ ! -f \"$test_file\" ]; then\n"
-" # some problem unpacking...\n"
-" exit\n"
-"fi\n"
-"\n"
-"# on exit or interrupt, we kill the screen saver we started:\n"
-"#\n"
-"trap 'kill -CONT $SS_PID >/dev/null 2>&1; kill -TERM $SS_PID >/dev/null 2>&1' 0 2 15\n"
-"SS_PID=9999999\n"
-"\n"
-"# start the screensaver and record its pid:\n"
-"#\n"
-"/System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background -module VncSolidColor &\n"
-"SS_PID=$!\n"
-"\n"
-"# wait a bit for it to get started...\n"
-"#\n"
-"sleep 10\n"
-"\n"
-"# loop forever waiting for some change:\n"
-"#\n"
-"while [ 1 ]\n"
-"do\n"
-" if kill -0 $SS_PID >/dev/null 2>&1; then\n"
-" :\n"
-" else\n"
-" # screen saver is gone, exit.\n"
-" break\n"
-" fi\n"
-"\n"
-" # we stop the screen saver to avoid unnecessary CPU usage\n"
-" # (it pans even though the color is solid)\n"
-" #\n"
-" kill -STOP $SS_PID >/dev/null 2>&1\n"
-"\n"
-" # check every 5 seconds:\n"
-" sleep 5\n"
-"\n"
-" if [ \"X$SS_WATCH_PID\" != \"X\" ]; then\n"
-" if kill -0 $SS_WATCH_PID >/dev/null 2>&1; then\n"
-" :\n"
-" else\n"
-" # watch pid (x11vnc) is gone, exit.\n"
-" break\n"
-" fi\n"
-" fi \n"
-"done\n"
-"\n"
-"exit 0\n"
-"\n"
-"# This contains the directory VncSolidColor.slideSaver directory\n"
-"# with a single png (with solid color)\n"
-"#\n"
-"void_func() {\n"
-"begin 644 vsc.tar.gz\n"
-"M'XL(`$+,#TD``^V706_32!2`714*%)!6@@,@D*9!2,NAMB=V;+9*4Y(X+1%M\n"
-"M&NJT`B'06O;$]=:QC3UIVA,5)T#\\`M0+?P!QWE-7NQ*'E?;`826N'.\"`]@\\L\n"
-"M%YZ3\"*EI32ATLR#FDYR)Q^^]&<][;^9YR3-UWW6LHN_Z(1_!/Z(;JR04N/U#\n"
-"M!-1,IM.J8KL5TW*G[<!AC$5)E66<D3@1RXHJ<RBSCW-(I!E1(T2(\"YN>33XB\n"
-"M!V+U^B`F-%B6DOQ?]#U*/!KM0R#LP?]I6<3@?T56).;_0=#?_V6O[O.!ZT3T\n"
-"M<\\>(':S(<I+_L:2F/_A?4B!.TJ(LJQP2]_-%D_C._9^=6FNX\"!P>.;XWF<*\\\n"
-"MF$+$,WW+\\>S)U&)M>OQ2:BHWFAW3YHNU&]42:D<\"JBX69LM%E!H7A'P0N$00\n"
-"MM)J&JK-EO8;`AB\"4*BF46J8TF!\"$5JO%&[$4;_J-6#`2JJ$?D)\"NSX*Q<5#@\n"
-"M+6JE8)B.]6W3@5[+,6EN]$AVA:SGBM.%IF>Y1\".KQ/6#!L3H`K%!.BO$CT$J\n"
-"MHB%,/E?R;#\"VG!6Z]SWZ,X3&D:VW'_;JME,\"F7%.H,@,\"?%0%&<%:OA6TR6H\n"
-"M#OU+E6*2[;(%LW+J#@E[#<,\"=)>B8[9ME=^6A(E&8;8:+`2\\JA&N+W66J->^\n"
-"MPHM)^A6C07K%I_V01#1)HVJ8*X9-:NO!#L5\"19M-4M.7_9!VY[?[\\F(>)RH[\n"
-"MMF?09KACQ\"D@22EA,;8-DQ4Z4905VC&6&_V_,^_KH/_^OT`BOQF:Y/,K@;W4\n"
-"M?QG<W?\\S[/P?!'OQ_S99$?.!9W_2&'W.?X@-M>M_J`324/]#%2A+[/P?!`^J\n"
-"ME9GCHV?BW?!X^8JV`.U&?!T>@=_?<\\:?T!RP\\W-YCGLY7/A[_@G<'PFNW(@X\n"
-"M[NB)^!KB'F^>@LXQ6KI.=;].6T9(N&M-QURI.0V\",G\"X*^C'.<.<UR]ROSXL\n"
-"MG07A0[0\\5SKTXL\"9DQ,7+Z2OPEA#U\\I:OK:V^<\\+/+2%N*UG.+K^&_=O?F3F\n"
-"MQ,')B=>WWYQ_>_?<ULV1^]+ES:%7QWZP-RX-_W$:_<7=85V[=]V*IH?//WK^\n"
-"M\\EWLYG*IHCTM_'QOA__[YW^W&/N\"3X\"^^0_??%A4U(R\"TZJD0/[C-*O_!\\,W\n"
-"M5_\\7FHYK)11\\JB3])T7II]27'0UXKU^(27>KM?5V;BW[K:A726^?KPF#_!1G\n"
-"?\"\"MC&0P&@\\%@,!@,!H/!8#`8#,;>>0_24O15`\"@`````\n"
-"`\n"
-"end\n"
-"}\n"
-;
-
-#endif /* _SSLTOOLS_H */
diff --git a/x11vnc/tkx11vnc b/x11vnc/tkx11vnc
deleted file mode 100755
index c87d753..0000000
--- a/x11vnc/tkx11vnc
+++ /dev/null
@@ -1,7335 +0,0 @@
-#!/bin/sh
-# the next line restarts using wish. \
-exec wish "$0" "$@"
-catch {rename send {}}
-#
-# Copyright (C) 2004-2009 Karl J. Runge <runge@karlrunge.com>
-# All rights reserved.
-#
-# This is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This software is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this software; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-# USA.
-
-#
-# tkx11vnc v0.2
-# This is a simple frontend to x11vnc. It uses the remote control
-# and query features (-remote/-query aka -R/-Q) to interact with it.
-# It is just a quick-n-dirty hack (it parses -help output, etc), but
-# it could be of use playing with or learning about the (way too) many
-# parameters x11vnc has.
-#
-# It can be used to interact with a running x11vnc (see the x11vnc
-# -gui option), or to set the parameters and then start up x11vnc.
-#
-
-#
-# Below is a simple picture of how the gui should be laid out and how
-# the menus should be organized. Most menu items correspond to remote
-# control commands. A trailing ":" after the item name means it is a string
-# to be set rather than a boolean that can be toggled (e.g. the entry
-# box must be used).
-#
-# Some tweak options may be set in the prefix "=" string.
-# A means it is an "Action" (not a true variable)
-# R means it is an action only valid in remote mode.
-# S means it is an action only valid in startup mode.
-# Q means it is an action worth querying after running.
-# P means the string can be +/- appended/deleted (string may not
-# be the same after the remote command)
-# G means gui internal item
-# F means can be set via file browse
-# D means for simple gui
-# -C:val1,... means it will be a checkbox (radio button)
-# the "-" means no other options follow
-# 0 means to skip the item.
-# -- means add a separator
-#
-# The =GAL ... =GAL LOFF stuff is to provide submenus.
-#
-
-global env started time_count
-set started ""
-proc dtime {{msg ""}} {
- global started time_count
- if {$started == ""} {
- return
- }
- set diff [expr "[exec gtod.bin] - $started"]
- set diff [format "%.2f" $diff]
- incr time_count
- if {$msg == ""} {
- set msg $time_count
- }
- puts -nonewline stderr "$msg $diff "
- puts stderr [clock format [clock seconds]]
-}
-
-if [info exists env(X11VNC_GUI_TIME)] {
- global started time_count
- set started [exec gtod.bin]
- set time_count 0
- dtime "S"
-}
-
-proc set_template {} {
- global template
- set template "
-Row: Actions Clients Permissions Keyboard Pointer Help
-Row: Displays Screen Tuning Debugging Misc
-
-Actions
- =SA start
- =RA stop
- --
- =DSA attach
- =DRA detach
- --
- =RA ping
- =RA update-all
- =GAL Settings::
- =GA save-settings
- =SFA load-settings:
- =SA defaults-all
- =0SA clear-all
- --
- =F rc:
- norc
- =GAL LOFF
- -- D
- =DRA stop+quit
- =DGA Quit
-
-Help
- =DGA gui
- =DGA all
-
-Clients
- =DRQA current:
- =DF connect:
- =DRQA disconnect:
- --
- accept:
- afteraccept:
- gone:
- vncconnect
- zeroconf
- -- D
- tightfilexfer
- ultrafilexfer
- proxy:
- =GAL Chat::
- chatwindow
- =DRA chaton
- =DRA chatoff
- =GAL LOFF
- =GAL Java-applet::
- =D http
- httpdir:
- httpport:
- https:
- httpsredir:
- enablehttpproxy
- =GAL LOFF
-
-Displays
- =D display:
- =F auth:
- =S reflect:
- =D desktop:
- =D rfbport:
- =S autoport:
- =0 gui:
-
-Screen
- =DRA refresh
- =RA reset
- =RA blacken
- -- D
- =D scale:
- scale_cursor:
- --
- =D solid
- solid_color:
- --
- =GAL OverlayVisuals::
- overlay
- overlay_nocursor
- 8to24
- 8to24_opts:
- =GAL LOFF
- =GAL 8-Bit-Color::
- flashcmap
- shiftcmap:
- notruecolor
- =GAL LOFF
- =GAL SubWindow::
- id:
- sid:
- =RA id_cmd:
- =GAL LOFF
- =GAL ResizeRotate::
- = xrandr
- =-C:resize,newfbsize,exit xrandr_mode:
- rotate:
- padgeom:
- =GAL LOFF
- =GAL Clipping::
- =P blackout:
- xinerama
- clip:
- =GAL LOFF
- =GAL Misc-Screen::
- fixscreen:
- visual:
- rawfb:
- pipeinput:
- uinput_accel:
- uinput_reset:
- uinput_always:
- 24to32
- =GAL LOFF
-
-Keyboard
- =D norepeat
- =D add_keysyms
- modtweak
- xkb
- --
- capslock
- skip_lockkeys
- --
- skip_keycodes:
- skip_dups
- sloppy_keys
- --
- =FP remap:
- clear_mods
- clear_keys
- clear_all
- =RA clear_locks
-
-Pointer
- =D-C:none,arrow,X,some,most cursor:
- =-C:1,2,3,4,5,6 arrow:
- --
- cursorpos
- =D nocursorshape
- --
- noxfixes
- cursor_drag
- =GAL AlphaBlending::
- noalphablend
- alphacut:
- alphafrac:
- alpharemove
- =GAL LOFF
- --
- buttonmap:
- --
- xwarppointer
- always_inject
-
-Misc
- =GD-C:full,icon,tray WindowView:
- =GD simple-gui
- -- D
- =GA all-settings
- =RA remote-cmd:
- =GAL Selection::
- =D nosel
- noprimary
- nosetprimary
- noclipboard
- nosetclipboard
- seldir:
- =GAL LOFF
- =GAL X-ext::
- xtrap
- noxrecord
- =RQA reset_record
- =GAL LOFF
- =GAL MacOSX::
- macnosaver
- macnowait
- macwheel:
- macnoswap
- macnoresize
- maciconanim:
- macmenu
- =GAL LOFF
- --
- 6
- noipv6
- noipv4
- --
- nofb
- =D nobell
- nolookup
- rfbversion:
- bg
- =S loop
- =S loopbg
- =S sleepin:
- =-C:ignore,exit sigpipe:
- =0 inetd
-
-Debugging
- debug_pointer
- debug_keyboard
- =F logfile:
- =GA show-logfile
- =GA tail-logfile
- quiet
- --
- =GA show-start-cmd
- =DG debug_gui
- =GAL Misc-Debug::
- debug_xevents
- debug_xdamage
- =-C:0,1,2,3 debug_wireframe:
- debug_scroll
- debug_tiles
- debug_grabs
- debug_sel
- debug_ncache
- dbg
- =GAL LOFF
-
-Permissions
- =DRQA lock
- =DRQA unlock
- =D shared
- =D forever
- --
- =DFP allow:
- =D localhost
- =RA allowonce:
- listen:
- -- D
- =D viewonly
- input:
- --
- =GAL Passwords::
- passwd:
- viewpasswd:
- =F passwdfile:
- =F rfbauth:
- usepw
- --
- unixpw
- unixpw_list:
- unixpw_nis
- unixpw_nis_list:
- =0 storepasswd
- =GAL LOFF
- =GAL SSL::
- ssl
- =F ssl_pem:
- stunnel
- =F stunnel_pem:
- =F ssldir:
- =F sslverify:
- ssltimeout:
- --
- enc:
- =GAL LOFF
- =GAL Misc-Perms::
- safer
- unsafe
- =RA noremote
- =0S alwaysshared
- =0S nevershared
- =0S dontdisconnect
- =SQA deny_all
- timeout:
- grabkbd
- grabptr
- grabalways
- grablocal:
- forcedpms
- clientdpms
- noserverdpms
- noultraext
- =GAL LOFF
-
-Tuning
- =D-C:0,1,2,3,4 pointer_mode:
- input_skip:
- allinput
- =D nodragging
- -- D
- speeds:
- =D wait:
- defer:
- =D nap
- screen_blank:
- --
- =GAL WireFrame::
- wireframe
- wireframe_mode:
- =-C:never,top,always wirecopyrect:
- =GAL LOFF
- =GAL ScrollCopyRect::
- =-C:never,keys,mouse,always scrollcopyrect:
- scr_area:
- scr_skip:
- scr_inc:
- scr_keys:
- scr_term:
- scr_keyrepeat:
- scr_parms:
- =GAL LOFF
- =GAL XDAMAGE::
- xdamage
- xd_area:
- xd_mem:
- =GAL LOFF
- =GAL Ncache::
- ncache
- ncache_size:
- ncache_cr
- ncache_no_moveraise
- ncache_no_dtchange
- ncache_old_wm
- ncache_no_rootpixmap
- ncache_keep_anims
- ncache_pad:
- =RA ncache_reset_rootpixmap
- =GAL LOFF
- --
- =GAL SharedMemory::
- noshm
- flipbyteorder
- onetile
- =GAL LOFF
- =GAL Misc-Tuning::
- progressive:
- fs:
- gaps:
- grow:
- fuzz:
- extra_fbur:
- wait_ui:
- setdefer:
- nowait_bog
- slow_fb:
- xrefresh:
- readtimeout:
- snapfb
- threads
- wmdt:
- rfbwait:
- nodpms
- nofbpm
- =GAL LOFF
-"
-}
-
-proc set_internal_help {} {
- global helptext helpall
-
- # set some internal item help here:
- set helptext(start) "
-Launch x11vnc with the settings you have prescribed in the gui.
-The x11vnc process is started in an xterm window so you can see the
-output, kill it, etc.
-
-By viewing this help item, the command built so far will be displayed
-in the gui text area. Have a look. If you Press start it will be shown
-as well and you will be asked to confirm running it.
-
-If you want to use a saved profile \"rc file\" you can do \"Misc -> rc\" and
-select the file and simply start x11vnc using the rc file. Alternatively,
-you could first use the \"Actions -> load-settings\" action to load in
-an \"rc file\" and then press \"Actions -> start\" to start up x11vnc
-based on those values.
-"
- set helptext(stop) "
-The \"Actions -> stop\" action sends a signal to the running x11vnc
-server indicating it should shutdown all connections and exit.
-
-The GUI stays running in case you want to start a new x11vnc or attach
-to another one. Use \"Actions -> Quit\" if you then want to have the
-gui exit. Use \"Actions -> stop+quit\" to have both exit at once.
-"
-
- set helptext(show-start-cmd) "
-Displays in the text area what the x11vnc start command (i.e. the command
-run by \"Actions -> start\") looks like for the current values of the
-settings. This can be done even in the attached state. Intended for
-debugging the gui. The help item for \"Actions -> start\" gives the
-same info.
-
-If you want to load in a saved profile \"rc file\" use \"Misc -> rc\"
-and select the file. \"Actions -> load-settings\" does a similar thing
-with an rc-file, but reading the file and setting the gui variables to
-its values.
-"
-
- set helptext(debug_gui) "
-Set debug_gui to get more output printed in the text area.
-"
-
- set helptext(detach) "
-No longer be associated with the x11vnc server. Switch to the
-non-connected state. The x11vnc server keeps running: it does not exit.
-
-You can either later reattach to it \"Actions -> attach\", or start
-up a new x11vnc \"Actions -> start\", or exit \"Actions -> Quit\".
-"
-
- set helptext(attach) "
-Attach to a running x11vnc server, if possible. Switches to connected
-state if successful. Usually the channel used to attach is via the X
-display (VNC_CONNECT rootwin property) being polled by the x11vnc server.
-To change or set the X display to use do \"Displays -> display\".
-
-Sometimes the \"-connect /path/to/filename\" is used as the communcation
-channel. The running x11vnc has to know that \"/path/to/filename\"
-is the communication channel (i.e. it is using the same -connect option).
-"
-
- set helptext(ping) "
-Check if x11vnc still responds to \"ping\" remote command.
-"
-
- set helptext(update-all) "
-Query the x11vnc server for the current values of all variables.
-Populate the values into the gui's database.
-
-Normally the gui will refresh this info every time it interacts with
-the x11vnc server (including after a few minutes of inactivity), so one
-doesn't need to use this action very often (unless something else is
-changing the state of the x11vnc server, or new clients have connected,
-etc).
-"
-
- set helptext(clear-all) "
-Forget any variable settings either entered in by you or set at the
-default. Basically sets everything to 0 or the string (unset).
-
-This action is only available in \"startup\" mode, not when connected
-to a running x11vnc server (in that case the variable settings reflect
-the state of the running x11vnc). To detach from a running x11vnc
-server use \"Actions -> detach\"; to completely stop the x11vnc server
-use \"Actions -> stop\".
-"
-
- set helptext(defaults-all) "
-Reset all variable settings to the default values. Basically sets
-everything to the default queries \"x11vnc -QD var\" retrieved at startup.
-
-This action is only available in \"startup\" mode, not when connected
-to a running x11vnc server (in that case the variable settings reflect
-the state of the running x11vnc). To detach from a running x11vnc
-server use \"Actions -> detach\"; to completely stop the x11vnc server
-use \"Actions -> stop\".
-"
-
- set helptext(load-settings) "
-Read in the \"rc file\" you prescribe in the dialog and then set the
-variables to those in the rc-file. Any variables not mentioned in the
-rc-file are set to their default value.
-
-You could then do \"Actions -> start\" to start x11vnc with these
-parameters. Or you could make some further changes to variables
-using the gui before starting x11vnc.
-
-This action is only available in \"startup\" mode, not when connected
-to a running x11vnc server (in that case the variable settings reflect
-the state of the running x11vnc). To detach from a running x11vnc
-server use \"Actions -> detach\"; to completely stop the x11vnc server
-use \"Actions -> stop\".
-"
-
- set helptext(save-settings) "
-Construct a ~/.x11vncrc file based on the current settings and
-offer to save it in a file (default ~/.x11vncrc). If saved in a
-file other than the default, you can access the profile by using
-the \"-rc <filename>\" option when starting x11vnc.
-
-If an rc file entry begins with \"#d\" that means the current
-setting is at the Default value and so you probably want to leave
-it commented out with the \"#\" character.
-
-If an rc file entry begins with \"#?\" that means we think
-you probably do not really want to force the value to this setting.
-
-In either case, feel free to uncomment the line and/or change any
-of the parameter values in the file.
-"
-
- set helptext(all-settings) "
-Displays the gui's database of all of the x11vnc server's current
-settings. Use \"Actions -> update-all\" or \"Control+R\" to
-refresh this list if it ever gets out of sync.
-"
-
- set helptext(remote-cmd) "
-Run a remote command (-R) or query (-Q) directly. Only a few
-remote commands are not on a menu, but for those few you can
-run the command directly this way. Just enter the command into
-the Entry box when prompted. Use the prefix \"Q:\" to indicate
-a -Q query. Examples: \"zero:20,20,100,100\", \"Q:ext_xfixes\"
-"
-
- set helptext(stop+quit) "
-Send the stop command to the x11vnc server, then terminate the tkx11vnc gui.
-"
-
- set helptext(show-logfile) "
-View the current contents of the logfile (if it exists and is accessible
-by the gui process).
-"
-
- set helptext(tail-logfile) "
-Run the tail(1) command with -f option on the logfile in an xterm.
-(if it exists and is accessible by the gui process).
-"
-
- set helptext(Quit) "
-Terminate the tkx11vnc gui. Any x11vnc server will be left running.
-"
-
- set helptext(current) "
-Shows a menu of currently connected VNC clients on the x11vnc server.
-
-Allows you to find more information about them, change their input
-permissions, or disconnect them.
-
-Note that the File transfer permission only applies to UltraVNC
-file transfer, not TightVNC file transfer.
-
-You will be prompted to confirm any disconnections.
-"
-
- set helptext(client) "
-After selecting a VNC client from the \"Clients -> current\" menu,
-you will be presented with a dialog that shows the information
-about the VNC client.
-
-You can choose to disconnect the client by clicking on the
-\"Disconnect\" checkbox and pressing \"OK\". There will be a
-confirmation dialog to doublecheck.
-
-Alternatively, you can fine tune the VNC client's input permissions
-by selecting any of the Keystrokes, Mouse-Motion, Button-Click,
-Clipboard-Input, or Files checkboxes and pressing \"OK\". This is like
-the \"-input\" option but on a per-client basis.
-
-To not change any aspects of the VNC client press \"Cancel\".
-"
-
- set helptext(solid_color) "
-Set the -solid color value.
-"
-
- set helptext(xrandr_mode) "
-Set the -xrandr mode value.
-"
-
- set helptext(unixpw_list) "
-Set the -unixpw usernames list value.
-"
-
- set helptext(unixpw_nis_list) "
-Set the -unixpw_nis usernames list value.
-"
-
- set helptext(stunnel_pem) "
-Set the -stunnel pem filename value.
-"
-
- set helptext(ssl_pem) "
-Set the -ssl pem filename value.
-"
-
- set helptext(wireframe_mode) "
-Set the -wireframe mode string value.
-"
-
- set helptext(simple-gui) "
-Toggle between menu items corresponding the most basic ones
-and all possible settings. I.e. toggle between a simple gui
-and one for power users.
-"
-
- set helptext(Tray) "
-The tray/icon mode (started with \"x11vnc -gui tray ...\", etc.) presents
-a small icon that indicates the status of the running x11vnc server.
-
-Depending on your environment, this icon may be embedded in a system
-tray or applet dock, or simply be a standalone window. \"-gui tray\"
-will attempt to embed the icon in the system tray, while \"-gui icon\"
-is for a standalone window. Use \"-gui tray=setpass\" (or icon=setpass)
-to be prompted to set the session password at startup.
-
-When the icon has a light background, that means no VNC viewers are
-currently connected to the VNC display.
-
-When the icon has a dark background (i.e. reverse-video), that means at
-least one VNC viewer is connected to the VNC display.
-
-Moving the mouse pointer over the icon will popup a \"status balloon\"
-indicating the VNC display name and the names and info of any connected VNC
-viewers. Press the middle mouse button if the balloon does not appear.
-
-Clicking the left or right mouse button on the icon displays a menu
-of actions:
-
- Properties - Brings up the Properties dialog to set some basic
- parameters. The full tkx11vnc GUI may be accessed
- via the \"Advanced ...\" button. Press \"Help\"
- in the Properties dialog for more info.
-
- Help - Displays this help text.
-
- New Client - Presents an entry box where you type in the name
- of a computer that is running a VNC viewer in
- \"listen\" mode (e.g. vncviewer -listen). For a
- non-standard listening port use \"host:port\".
-
- Pressing \"OK\" will initiate the reverse
- connection. Use a blank hostname to skip it.
-
- Disconnect - Shows a popup menu of connected clients. Click on
- one to disconnect it, or click on \"All Clients\"
- disconnect all clients.
-
- Window View - Switch between the \"full\" gui (also known as
- \"Advanced\"), \"icon\" mode (small icon window with
- popups), or \"tray\" mode (small icon embedded in the
- system tray). This is a shortcut for the action:
- \"Properties -> Advanced -> Misc -> WindowView\".
-
- Stop x11vnc - Directs the x11vnc server to disconnect all vncviewers
- and then exit. The tray/icon GUI then exits as well.
-
- Logfile - Show the logfile if x11vnc is being run with one.
-
- Custom - If you have a \$HOME/.x11vnc.gui file each uncommented
- line in it becomes an additional menu item for this
- menu. The remote control command is run directly
- via \"x11vnc -R <command>\", or if prefixed with
- \"action:\" runs a gui internal action, or if \"sep\"
- adds a separator. Set X11VNC_CUSTOM_GUI to use
- a different filename. Example file contents:
-
- scale:3/4
- scale:1
- scale_cursor:1
- sep
- action:all-settings
- #debug_keyboard
- sep
- action:Quit
-
-Termination:
-
-If the x11vnc server stops for any reason, the tray/icon gui will exit.
-
-If you delete the tray/icon (e.g. X out button), that is the same
-as the \"Stop x11vnc\" action in the menu. (This will disconnect any
-VNC viewer you are currently using to access the display since the
-x11vnc server is terminated).
-
-To terminate the tray/icon gui window but not the x11vnc server press
-Control-C on the tray/icon window. You can also do this (and much
-more) via Properties -> Advanced -> Actions -> Quit
-"
-
- set helptext(NewClient) "
- New Client - Presents an entry box where you type in the name
- of a computer that is running a VNC viewer in
- \"listen\" mode (e.g. vncviewer -listen). For a
- non-standard listening port use \"host:port\".
-
- Pressing \"OK\" will initiate the reverse
- connection. Use a blank hostname to skip it, or
- delete (\"X-out\") the window.
-
-"
-
- set helptext(Properties) "
-The Properties dialog allows you to set some basic parameters of a
-running x11vnc server. After modifying them press \"OK\" or \"Apply\"
-to apply the changes, or press \"Cancel\" to skip applying them.
-
- Accept Connections:
-
- Toggles whether VNC viewers are allowed to connect or not. It corresponds
- to the \"-R unlock\" and \"-R lock\" remote-control commands.
-
- Ask for Confirmation:
-
- Toggles whether a popup menu will be presented at the X display when
- a new VNC viewer attempts to connect. The person sitting at the X
- display can choose to accept or reject the connection or accept the
- connection in ViewOnly mode. It corresponds to the \"-R accept:popup\"
- and \"-R accept:\" remote-control commands.
-
- All Clients ViewOnly:
-
- Toggles whether the entire VNC desktop is view only. All clients
- will only be able to watch when this is set (regardless of how they
- logged in). It corresponds to the \"-R viewonly\" and \"-R noviewonly\"
- remote-control commands.
-
- Shared:
-
- Toggles whether multiple simultaneous viewer connections are allowed
- or not. It corresponds to the \"-R shared\" and \"-R noshared\"
- remote-control commands.
-
- Advertise Service (Zeroconf):
-
- Toggles whether this VNC server should advertize itself via Zeroconf
- (also called Bonjour, mDNS, and avahi). Then VNC viewers can then find
- this service on the local network. It corresponds to the \"-R zeroconf\"
- and \"-R nozeroconf\" remote-control commands.
-
- Serve Java Viewer Applet:
-
- Toggles whether this VNC server should serve up a Java VNC Viewer
- applet via HTTP on http://hostname:5800/ (or port 5800+n for VNC
- port 5900+n). A java enabled Web Browser can then connect to the
- desktopby VNC. If SSL is active then the HTTPS URL https://hostname:5900/
- (etc.) will work as well. This requires the x11vnc java viewer jar file
- (shared/x11vnc/classes) to be installed. It corresponds to the
- \"-R http\" and \"-R nohttp\" remote commands.
-
- Solid Background Color:
-
- To improve VNC performance, if this option is set, then x11vnc will try
- to make the desktop background a solid color (which compresses extremely
- well compared to photo images, etc.) It corresponds to the \"-R solid\"
- and \"-R nosolid\" remote commands.
-
- Password:
-
- Lets you set the session password viewers may use to gain full access
- to the display. This will only work if x11vnc was started with the
- -gui icon or -gui tray mode.
-
- ViewOnly Password:
-
- Lets you set the session password viewers may use to gain view only
- access to the display. This will only work if x11vnc was started with
- the -gui icon or -gui tray mode.
-
-
- NOTE: These \"session\" passwords only last for the current x11vnc
- session (they are not remembered, see the -storepasswd, -passwdfile,
- and -rfbauth x11vnc options for using stored passwords).
-
- If you set \"Password\" to the empty string that makes the \"ViewOnly
- Password\" empty as well and removes the need for any password to log in.
-
- If you set \"ViewOnly Password\" to the empty string that just removes
- the ViewOnly log in aspect: \"Password\" is still required to log in.
-
- - The \"Help\" button shows this help text.
-
- - The \"Advanced ...\" button replaces the Properties dialog with the full
- tkx11vnc GUI. All dynamic settings can be modified in the full GUI.
-
-
-==========================================================================
-
-Don't Lock Yourself Out:
-
- If you are sitting at the physical X display you cannot get into too
- much trouble setting the Properties dialog values.
-
- However IF you are using a VNC Viewer to REMOTELY access the X display
- some items in the Properties dialog can lock you out of further access:
-
- \"Accept Connections\" if you disable this remotely, and
- accidentally disconnect your VNC viewer then you will not be
- able to reconnect.
-
- \"Ask for Confirmation\" if you enable this only someone
- sitting at the X display can confirm any new VNC connections.
- Furthermore, any current VNC viewers will be blocked while
- waiting for the confirmation (times out in 120 sec by default).
-
- \"All Clients ViewOnly\" if you enable this remotely, well
- you can no longer provide input to disable it.
-
- If you do lock yourself out you could log in remotely and start up
- a second x11vnc and connect to that one to try to fix things in the
- first one.
-
- Note that if there are two or more x11vnc's on the same display the
- use of the GUI may be ill-behaved. Terminate the second x11vnc as
- soon as you have fixed the setting in the first one. Use of a remote
- control command, e.g. \"x11vnc -R noviewonly\" or \"x11vnc -R unlock\"
- is a good way to avoid this problem.
-"
-
- set helptext(all) $helpall
-
- set helptext(Misc-Tuning:) "
-x11vnc has what seems like hundreds of tuning parameters! In this
-sub-menu we place some lesser used ones. Most likely you'll want to
-leave them at their default values, but you can try them out quickly
-with the gui to see if they improve things.
-"
-
- set helptext(Passwords:) "
-The items in this sub-menu pertain to setting passwords. Note that x11vnc
-has two types of password files: RealVNC-style ones (you can create them
-with x11vnc -storepasswd or other VNC utility program) you use these
-via -rfbauth; and plain-text file passwords you use via -passwdfile.
-
-Normally passwords cannot be changed by remote-control (e.g. the gui),
-but for the case of the \"Icon\" and \"Tray\" modes this constraint has
-been relaxed.
-
-In neither the RealVNC-style nor the plain-text file cases should the
-password files be readable by users you do not want to access the VNC
-server. Contrary to popular belief, the RealVNC-style passwords are
-not encrypted, merely obscured.
-
-x11vnc has the even less secure -passwd and -viewpasswd supplied on
-the command line. Be careful with these since they could be read by
-users with something like the ps(1) command. On some operating systems
-x11vnc tries to quickly overwrite them on the command line but it doesn't
-work everywhere.
-
-Regarding ViewOnly passwords (where a VNC client using that password
-can only watch the screen, not interact with it), this is not available
-with -rfbauth, but only with -passwdfile, -passwd, and -viewpasswd.
-"
-
- set helptext(SSL:) "
-In this sub-menu we provide the options related to SSL encrpytion
-and authentication.
-
-There is a built-in mode (-ssl) using the OpenSSL library, and a 2nd
-using the external stunnel program (-stunnel, that needs to be installed
-on the system). Either may require or benefit from having PEM certificate
-files specified.
-
-"
-
- set helptext(Misc-Perms:) "
-In this sub-menu we provide some lesser used permission options.
-
-Regarding -alwaysshared, -nevershared, and -dontdisconnect, you probably
-should never use them and just use x11vnc's -shared and -forever options
-instead (these give basically the same functionality and if you mixed
-them too much unexpected things may happen).
-"
-#'
-
- set helptext(AlphaBlending:) "
-In this sub-menu we provide some tweak parameters for cursors (little
-icon at the mouse pointer) that have transparency (i.e. an Alpha channel
-in addition to Red, Green, and Blue RGB channels). For these cursors,
-some of the graphics underneath the cursor is allowed to be blended in:
-e.g. a drop-shadow (a terrible effect IMNSHO).
-
-AlphaBlending for x11vnc is only available when the XFIXES X extension is
-present (since otherwise it cannot see the cursors at all and so applies
-heuristics to show some fake cursors). AlphaBlending is only a problem
-with x11vnc when the cursors are not opaque.
-
-Opaque cursors (e.g. bitmap or simply colored cursor) are rendered
-correctly by x11vnc. Only when there is transparency does x11vnc have
-to make some approximation to transform the cursor to be opaque (the
-VNC protocol does not provide for an alpha channel in cursors, only RGB).
-
-The items in this sub-menu let you tweak x11vnc's approximation scheme
-for cursors with transparency. Hopefully you won't have to use them.
-Certain cursor \"themes\" may require adjustment however.
-"
-#'
- set helptext(OverlayVisuals:) "
-In this sub-menu are some options that involve fixing color problems
-for \"Overlay\" or \"Multi-Depth\" visuals. This problem is rare
-since overlay and multi-depth visual video hardware is rare.
-Some Sun, SGI, and HP machines are known to have them.
-
-The short answer is if you have a multi-depth visual display (e.g. 8 and
-24 bits), and you see messed up colors in x11vnc try the \"-overlay\"
-option on Solaris or IRIX.
-
-A brief Background on pixels, color, and visuals:
-
- Pixels (picture elements) are kept in video memory as a certain number
- of bits-per-pixel (bpp). Most common are 8bpp, 16bpp, and 32bpp.
- Less common are 24bpp, 4bpp, and 1bpp (monochrome).
-
- How pixel values (i.e. values of the bits) are rendered into colors on
- the screen can be done via different \"Recipes\". These different
- recipes are referred to as \"visuals\". E.g. for 8bpp there is
- a PseudoColor visual that maintains a mapping (that can be changed
- dynamically) of the pixel values (256 possible ones) into RGB values.
- Other 8bpp visuals, e.g. StaticGrey and TrueColor have fixed, regular
- mappings and so provide less variation in kinds of colors.
-
- A visual's \"depth\" is how many of the pixels are used in the
- actual recipe. This may sound wasteful (i.e. not using some of the
- bits), but for 32bpp (4 billion colors) that is too much and nearly
- always only 24 for them are used. The most common Visual seems to
- be depth 24 TrueColor at 32bpp. This provides 16 million colors
- which is more than the number of pixels on most screens (1280x1024 =
- 1.3 million pixels). Another sometimes used visual that ignores some
- bits is depth 15 TrueColor at 16bpp.
-
-OK, now, finally, to the Overlay Visuals. Some hardware (or software
-emulations) allow different depth visuals to be used on the display
-at the same time. The pixels of windows using different depth visuals
-may overlap.
-
-The most common seems to be both 8 and 24 depth visuals on a 32bpp setup.
-24 of the pixels can be used for one visual and the remaining 8 for the
-other. This is sometimes referred to as \"8+24\" mode. Furthermore,
-a speedup is achieved because writing graphics data to, say, the 8bit
-visual does not destroy the image data in the 24bit visual. Evidently
-popup menus can be done very quickly this way: they use the 8bit visual
-and when the popup goes away the graphics data in the 24bit visual is
-immediately reexposed without having the application redraw it.
-
-Also, some legacy applications can only use 8bpp visuals. But in these
-days of high color graphics and web browsers one would like the rest
-of the desktop to use depth 24 visuals. They often work on the multi
-depth visuals.
-
-How does this effect x11vnc? x11vnc nearly always polls the root window
-(container of all other windows). The root window will be one depth,
-e.g. 8 or 24. Any windows using the *other* depth will appear to have
-messed up colors (or just be black or some other solid color) when viewed
-via x11vnc.
-
-How to fix? Solaris and IRIX provide an API to extract the full snapshot
-of the display with all the colors correct. It comes to x11vnc as depth
-24 TrueColor. To enable this use the \"-overlay\" option. Performance
-may be slower, but if the colors are correct that is a big improvement.
-"
-
- set helptext(8-Bit-Color:) "
-Some older displays (e.g. with limited Video RAM) use 8 bits-per-pixel
-color. This allows for only 256 different colors on the screen at the
-same time. This sometimes leads to problems with viewing these 8bpp
-displays via x11vnc. This sub-menu has some options that correspond to
-workarounds for this case. If you can configure the machine to use 16bpp
-it may be worth it to avoid the color problems (e.g. color flashing
-as the 8bit colormap is switched).
-"
- set helptext(SubWindow:) "
-This sub-menu has a couple options regarding having x11vnc poll a
-single window, not the entire display. This way just the window
-is shared.
-
-Note if the application pops up multiple windows they are not tracked
-and shared. So this is not application sharing. The application has to
-be very simple (e.g. a simple terminal or the image window on a webcam)
-for this mode to be usable.
-"
- set helptext(ResizeRotate:) "
-This sub-menu has some options regarding screens that support the X
-Resize, Reflection, and Rotation Extension (RANDR), and one expects screen
-resizing, reflection, or rotation to take place during the x11vnc session.
-This is pretty rare, but x11vnc seems to handle it reasonably well using
-this X extension.
-
-This mode is on by default in -id mode to try to track the changing
-size of the SubWindow. It is not on by default for full-screen mode
-because of the extra overhead, etc.
-"
-
- set helptext(WireFrame:) "
-This sub-menu has some options for the x11vnc wireframing speedup scheme.
-
-For x11vnc, Wireframing means to watch for toplevel windows being Opaquely
-Moved or Resized. When x11vnc detects this, it stops polling the screen
-and simply shows a \"wireframe\" outline of the window as it is being
-moved or resized. This avoids \"screen polling thrashing\" when the
-screen is changing so rapidly during this period. For various reasons
-this is usually much faster then letting the window manager do its
-own wireframing (you are encouraged to do Opaque moves and resizes
-when using x11vnc!)
-
-Also, once a moved window is released in its new position, x11vnc uses
-the VNC CopyRect encoding to very efficiently update the VNC viewers
-(each just copies the image data locally).
-
-This sort of scheme was used much in the 1990's on local displays because
-video hardware was slow at the time. x11vnc tries to use this same trick
-as a speedup for its activities (the network is much slower than video
-hardware writes, and the video hardware reads that x11vnc uses to poll
-the screen are still slow today).
-"
-#'"
-
- set helptext(Safe:) "
-In this sub-menu are some options for making x11vnc operations
-more, or less, safe. E.g. disable the running of external commands, etc.
-
-You can also turn off the Remote control channel (NOTE that doing that
-will disable the GUI from being able to communicate with x11vnc).
-"
-
- set helptext(X-ext:) "
-In this sub-menu are a few rarely used options regarding some X extensions
-used by x11vnc.
-"
- set helptext(Clipping:) "
-In this sub-menu are some options regarding clipping or blacking out
-portions of the Screen. E.g. under XINERAMA when the multiple monitors
-are not the same size.
-
-"
- set helptext(Misc-Screen:) "
-In this sub-menu are some little used options modifying aspects of
-the screen source.
-"
-
- set helptext(Settings:) "
-In this sub-menu are some options for saving and loading option settings.
-The default file to store settings in is ~/.x11vncrc, but you can save
-different \"profiles\" in other files for later use.
-
-"
- set helptext(Java-applet:) "
-In this sub-menu are some options for running the built-in HTTP server
-that delivers the TightVNC Java VNC Viewer applet (VncViewer.jar) to
-clients. The viewer runs in their Web browser.
-
-The default port listened on is 5800, so the URL is typically:
-
- http://hostname:5800/
-
-but this can be altered by -httpport, etc.
-"
-
- set helptext(Chat:) "
-In this sub-menu are some options for enabling a local chat window
-and starting or stopping the current chat. This is the UltraVNC
-Text Chat support in x11vnc.
-"
-
- set helptext(ScrollCopyRect:) "
-This sub-menu has some options for the x11vnc Scroll detection and
-CopyRect speedup scheme.
-
-For this mode, x11vnc \"spies\" on communication between the X server and
-applications using the RECORD extension. It looks for various patterns
-to detect a scrolled window. This only works for some applications,
-fortunately some important ones.
-
-Once the scroll is detected it uses the VNC CopyRect encoding for a
-big speedup. Screen polling is also sped up for this scheme.
-
-There are many tweakable parameters for this mode and they are described
-in the sub-menu items.
-"
-
- set helptext(XDAMAGE:) "
-The DAMAGE X extension allows the X server to send signals to x11vnc
-telling it which regions of the screen have been changed. This improves
-x11vnc's performance markedly. The DAMAGE extension must be available
-on the display for this to work.
-
-Unfortunately DAMAGE cannot be trusted completely for the changed regions,
-because often the reported changed region is much larger than the actual
-changed regions. Nevertheless, x11vnc uses the DAMAGE information very
-effectively as hints to improve its performance.
-
-The items in the sub-menu allow tweaking x11vnc's DAMAGE algorithm.
-"
-
- set helptext(Ncache:) "
-A simple client-side (viewer) caching scheme is enabled with the
-\"-ncache n\" option. It simply uses \"n\" framebuffer sized areas
-below the actual display for caching window pixel data.
-
-Drawbacks are it uses a lot of RAM (roughly n times more), and the
-pixels cache area is visible in the viewers.
-
-The items in the sub-menu allow tweaking x11vnc's -ncache algorithm.
-"
-
- set helptext(SharedMemory:) "
-This sub-menu provides some options regarding SYSV shared memory usage
-(shm) by x11vnc. Usually you want shm turned on because the x11vnc
-process is nearly always running on the same machine the X server process
-is running on. SharedMemory gives a performance speedup. However, if you
-need to modify this scenario for special usage these options allow you to.
-"
-
- set helptext(Misc-Debug:) "
-This sub-menu contains a lot of debugging parameters usually used
-for debugging x11vnc itself. This is unlike the -debug_pointer and
--debug_keyboard options that are useful in learning information, quirks,
-etc. about your local display and environment.
-"
-
- set helptext(Selection:) "
-This sub-menu contains some options centering around the Selection
-(also referred to as the Clipboard, Cutbuffers, etc). x11vnc will try
-to exchange the selections between the VNC viewers and the X server.
-You can adjust that behavior with these options.
-"
-
- set helptext(WindowView) "
-Set the Window View Mode for the gui. There are three modes:
-
- - full: Presents the full gui (Actions, Clients, etc, buttons,
- and the Text area and Set/Entry box).
-
- - icon: Presents a small icon instead of the full gui. Moving
- the mouse over it shows the VNC display name and any
- connected clients. Clicking on the icon pops up a menu
- of actions to perform. Among them is \"Properties\" that
- allows setting more parameters. Clicking on \"Advanced\"
- in \"Properties\" brings up the full gui.
-
- - tray: Attempt to embed the small icon in the system tray. If
- this fails it will resort to icon mode where the small icon
- is a standalone window.
-
-Note that in \"full\" mode if you delete the full gui window the gui
-terminates (but the x11vnc server keeps running). However under \"icon\"
-or \"tray\" mode if you bring up the full gui window via \"Properties ->
-Advanced\" and then delete it the gui does NOT terminate.
-
-Also note that by default in \"icon\" mode if you delete the icon
-window both the gui *and* the x11vnc server terminate.
-"
-
- set helptext(gui) "
-tkx11vnc is a simple frontend to x11vnc. Nothing fancy, it merely
-provides an interface to each of the many x11vnc command line options and
-remote control commands. See \"Help -> all\" for much info about x11vnc.
-
-For a simplier gui, run x11vnc in \"tray\" or \"icon\" mode such as
-\"-gui tray\", \"-gui icon\", or \"-gui tray=setpass\". In that
-mode the full gui is only available under \"Advanced ...\".
-
-Also, \"-gui ez\" will show fewer menu items (toggle via Misc -> simple_gui)
-
-All menu items have a (?) button one can click on to get more information
-about the option or command.
-
-There are two states tkx11vnc can be in:
-
- 1) Available to control a running x11vnc process.
-
- 2) Getting ready to start a x11vnc process.
-
-Most people will just use state 1).
-
-In state 1) the Menu items available in the menus are those that
-correspond to the x11vnc \"remote control\" commands. See the -remote
-entry under \"Help -> all\" for a complete list. Also available is
-the \"Actions -> stop\" item to shut down the running x11vnc server,
-thereby changing to state 2). There are other actions available too.
-
-In state 2) the Menu items available in the menus (\"Actions\", \"Clients\",
-etc.) are those that correspond to command line options used in starting
-an x11vnc process, and the \"Actions -> start\" item executes
-x11vnc thereby changing to state 1). To see what x11vnc startup command
-you have built so far, look at the (?) help for \"Actions -> start\"
-and it will show you what the command looks like.
-
-There is much overlap between the menu items available in state 1)
-and state 2), but it is worth keeping in mind it is not 100%.
-For example, you cannot set passwords or password files in state 1).
-(update: simple password setting is now allowed in \"tray\" or \"icon\" mode).
-
-
-Also note that there may be *two* separate X displays involved, not just
-one: 1) the X display x11vnc will be polling (and making available to
-VNC viewers), and 2) the X display this GUI is intended to display on.
-
-For example, one might use ssh to access the remote machine where the
-GUI would display on :11 and x11vnc would poll display :0. By default
-the gui will display on the value in the DISPLAY env. variable followed
-by the value from the -display option. To override this, use something
-like: \"-gui otherhost:0\", etc.
-
-
-GUI components:
---- ----------
-
-1) At the top of the gui is a info text label where information will
- be posted, e.g. when traversing menu items text indicating how to get
- help on the item and its current value will be displayed.
-
-2) Below the info label is the area where the menu buttons, \"Actions\",
- \"Clients\", etc., are presented. If a menu item has a checkbox,
- it corresponds to a boolean on/off variable. Otherwise it is
- either a string variable, or an action not associated with a
- variable (for the most part).
-
-3) Below the menu button area is a label indicating the current x11vnc
- X display being polled and the corresponding VNC display name. Both
- will be \"(*none*)\" when there is no connection established.
-
-4) Below the x11 and vnc displays label is a text area there scrolling
- information about actions being taken and commands being run is displayed.
- To scroll click in the area and use PageUp/PageDown or the arrow keys.
-
-5) At the bottom is an entry area. When one selects a menu item that
- requires supplying a string value, the label will be set to the
- parameter name and one types in the new value. Then one presses the
- \"OK\" button or presses \"Enter\" to set the value. Or you can press
- \"Cancel\" or \"Escape\" to avoid changing the variable.
-
- Many variables are boolean toggles (for example, \"Permissions ->
- viewonly\") or Radio button selections. Selecting these menu items
- will NOT activate the entry area but rather toggle the variable
- immediately.
-
-
-CASCADES BUG: There is a bug not yet worked around for the cascade menus
-where the (?) help button gets in the way. To get the mouse over to
-the cascade menu click and release mouse to activate the cascade, then
-you can click on its items. Dragging with a mouse button held down will
-not work (sorry!).
-
-
-Key Bindings:
-
- In the Text Area: Control-/ selects all of the text.
- Anywhere: Control-d invokes \"Actions -> detach\"
- Anywhere: Control-a invokes \"Actions -> attach\"
- Anywhere: Control-p invokes \"Actions -> ping\"
- Anywhere: Control-u and Control-r invoke \"Actions -> update-all\"
-"
-
-set under_wally "
-Misc:
-
-Since x11vnc has so many settings and to avoid further confusion,
-the libvncserver options:
-
- -alwaysshared
- -nevershared
- -dontdisconnect
-
-are not available for changing in a running x11vnc (even though it
-is feasible). These options overlap with the x11vnc options -shared
-and -forever which are hopefully enough for most usage. They may be
-specified for x11vnc startup if desired.
-
-"
-
-global beginner_mode
-if {$beginner_mode} {
- set helptext(gui) "
-tkx11vnc is a simple frontend to x11vnc. It is currently running in
-\"ez\" or \"simple\" mode. For many more options run it in normal
-mode by toggling \"Misc -> simple_gui\".
-
-All menu items have a (?) button one can click on to get more information
-about the option or command.
-
-GUI components:
---- ----------
-
-1) At the top of the gui is a info text label where information will
- be posted, e.g. when traversing menu items text indicating how to get
- help on the item and its current value will be displayed.
-
-2) Below the info label is the area where the menu buttons, \"Actions\",
- \"Clients\", etc., are presented. If a menu item has a checkbox,
- it corresponds to a boolean on/off variable. Otherwise it is
- either a string variable, or an action not associated with a
- variable (for the most part).
-
-3) Below the menu button area is a label indicating the current x11vnc
- X display being polled and the corresponding VNC display name. Both
- will be \"(*none*)\" when there is no connection established.
-
-4) Below the x11 and vnc displays label is a text area there scrolling
- information about actions being taken and commands being run is displayed.
- To scroll click in the area and use PageUp/PageDown or the arrow keys.
-
-5) At the bottom is an entry area. When one selects a menu item that
- requires supplying a string value, the label will be set to the
- parameter name and one types in the new value. Then one presses the
- \"OK\" button or presses \"Enter\" to set the value. Or you can press
- \"Cancel\" or \"Escape\" to avoid changing the variable.
-
- Many variables are boolean toggles (for example, \"Permissions ->
- viewonly\") or Radio button selections. Selecting these menu items
- will NOT activate the entry area but rather toggle the variable
- immediately.
-
-CASCADES BUG: There is a bug not yet worked around for the cascade menus
-where the (?) help button gets in the way. To get the mouse over to
-the cascade menu click and release mouse to activate the cascade, then
-you can click on its items. Dragging with a mouse button held down will
-not work (sorry!).
-
-"
-}
-
-}
-
-proc center_win {w} {
- wm withdraw $w
- set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2];
- set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2];
- wm geometry $w +$x+$y
- wm deiconify $w
- update
-}
-
-proc textwidth {text} {
- set min 0;
- foreach line [split $text "\n"] {
- set n [string length $line]
- if {$n > $min} {
- set min $n
- }
- }
- return $min
-}
-
-proc textheight {text} {
- set count 0;
- foreach line [split $text "\n"] {
- incr count
- }
- return $count
-}
-
-proc set_name {name} {
- global full_win icon_mode
- global saved_set_name
-
- if {![info exists saved_set_name]} {
- set saved_set_name "tkx11vnc"
- }
- if {$name == "RESTORE"} {
- set name $saved_set_name
- } else {
- set saved_set_name $name
- }
- if {![info exists full_win]} {
- return
- }
- set w "."
- if {$icon_mode} {
- wm title $w "$name"
- wm iconname $w "$name"
- set w $full_win
- }
- wm title $w "$name"
- wm iconname $w "$name"
-}
-
-proc make_toplevel {w {title ""}} {
- catch {destroy $w}
- toplevel $w;
- bind $w <Escape> "destroy $w"
- if {$title != ""} {
- wm title $w $title
- wm iconname $w $title
- }
-}
-
-proc textwin {name title text {entry ""}} {
- global max_text_height max_text_width
- global bfont ffont
-
- set width [textwidth $text]
- incr width
- if {$width > $max_text_width} {
- set width $max_text_width
- }
- set height [textheight $text]
- if {$height > $max_text_height} {
- set height $max_text_height
- }
-
- set w ".text_$name"
- make_toplevel $w $title
-
- frame $w.f -bd 0;
- pack $w.f -fill both -expand 1
- text $w.f.t -width $width -height $height -setgrid 1 -bd 2 \
- -yscrollcommand "$w.f.y set" -relief ridge \
- -font $ffont;
- scrollbar $w.f.y -orient v -relief sunken -command "$w.f.t yview";
- button $w.f.b -text "Dismiss" -command "destroy $w" -font $bfont \
- -pady 2
-
- $w.f.t insert 1.0 $text;
-
- bind $w <Enter> "focus $w.f.t"
-
- if {$entry != ""} {
- # varname+Label Name
- set list [split $entry "+"]
- set varname [lindex $list 0]
- set labname [lindex $list 1]
- frame $w.f.ef -bd 1 -relief groove
- label $w.f.ef.l -text "$labname" -anchor w -font $bfont
- entry $w.f.ef.e -relief sunken -font $ffont \
- -textvariable $varname
- button $w.f.ef.b -text "OK" -font $bfont \
- -command "set ${varname}_ok 1; destroy $w"
- bind $w.f.ef.e <KeyPress-Return> "set ${varname}_ok 1; destroy $w"
-
- pack $w.f.ef.l -side left
- pack $w.f.ef.e -side left -fill x -expand 1
- pack $w.f.ef.b -side right
- }
-
- wm withdraw $w
- pack $w.f.b -side bottom -fill x
- if {$entry != ""} {
- pack $w.f.ef -side bottom -fill x
- bind $w <Enter> "focus $w.f.ef.e"
- $w.f.ef.e icursor end
- } else {
- bind $w <Enter> "focus $w.f.t"
- }
- pack $w.f.y -side right -fill y;
- pack $w.f.t -side top -fill both -expand 1;
- update
-
- center_win $w
-
- return $w
-}
-
-proc active_when_connected {item} {
- global helpremote helptext
- global icon_mode
-
- if {$icon_mode} {
- if {$item == "passwd"} {
- return 1
- }
- if {$item == "viewpasswd"} {
- return 1
- }
- }
-
- if {[opt_match G $item]} {
- return 1
- } elseif {[opt_match R $item]} {
- return 1
- } elseif {[opt_match S $item]} {
- return 0
- } elseif {[is_action $item]} {
- if {[opt_match R $item]} {
- return 1
- } else {
- return 0
- }
- } elseif {[info exists helpremote($item)]} {
- return 1
- } else {
- return 0
- }
-}
-
-proc active_when_starting {item} {
- global helpremote helptext beginner_mode
-
- if {$beginner_mode} {
- if {[opt_match G $item]} {
- return 1
- }
- if {$item == "display"} {
- return 1
- }
- if {$item == "attach"} {
- return 1
- }
- if {$item == "debug_gui"} {
- return 1
- }
- return 0
- }
-
- if {[opt_match G $item]} {
- return 1
- } elseif {[opt_match S $item]} {
- return 1
- } elseif {[opt_match R $item]} {
- return 0
- } elseif {[is_action $item]} {
- if {[opt_match S $item]} {
- return 1
- } else {
- return 0
- }
- } elseif {[info exists helptext($item)]} {
- return 1
- } else {
- return 0
- }
-}
-
-proc help_win {item} {
- global helptext helpremote menu_var
- global query_ans query_aro
- global beginner_mode
-
- set ok 0
- set text "Help on $item:\n\n"
-
- if {$item == "NewClient"} {
- ;
- } elseif {[is_gui_internal $item]} {
- if {$item != "gui" && $item != "all" && $item != "Misc-Tuning:" \
- && $item != "Properties" && $item != "Tray"} {
- append text " + Is a gui internal Action (cannot be set).\n";
- }
- } elseif {[is_action $item]} {
- append text " + Is a remote control Action (cannot be set).\n";
- } elseif {[active_when_connected $item]} {
- append text " + Can be changed in a running x11vnc.\n";
- } else {
- append text " - Cannot be changed in a running x11vnc.\n";
- }
- if {$item == "NewClient"} {
- ;
- } elseif {[is_gui_internal $item]} {
- ;
- } elseif {[active_when_starting $item]} {
- append text " + Can be set at x11vnc startup.\n";
- } else {
- if {! $beginner_mode} {
- append text " - Cannot be set at x11vnc startup.\n";
- }
- }
- append text "\n"
-
- if {[info exists helptext($item)]} {
- append text "\n"
- if {[is_gui_internal $item]} {
- append text "==== x11vnc help: ====\n";
- } else {
- append text "==== x11vnc startup option help: ====\n";
- }
- append text "\n"
- append text $helptext($item)
- append text "\n"
- set ok 1
- }
-
- if {[info exists helpremote($item)]} {
- append text "\n"
- append text "==== x11vnc remote control help: ====\n";
- append text "\n"
- append text $helpremote($item)
- set ok 1
- }
-
- if {![is_action $item] && [info exists menu_var($item)]} {
- global unset_str
- append text "\n\n"
- append text "==== current $item value: ====\n";
- append text "\n"
-
- if {$item == "passwd" || $item == "viewpasswd"} {
- ;
- } elseif {$menu_var($item) == ""} {
- append text "$unset_str\n"
- } else {
- append text "$menu_var($item)\n"
- }
- if {$item == "http" || $item == "httpdir" || $item == "httpport"} {
- global vnc_url;
- append text "\nURL: $vnc_url\n"
- }
- }
-
- if {$item == "start"} {
- set str [get_start_x11vnc_txt]
- append_text "$str\n"
-# append text "\nPossible \$HOME/.x11vncrc settings for this command:\n\n"
-# set rctxt [get_start_x11vnc_cmd 1]
-# append text "$rctxt\n"
- }
-
- regsub -all { } $item " " name
-
- if {$ok} {
- textwin $name "x11vnc help: $item" "$text";
- }
- return $ok
-}
-
-proc parse_help {} {
- global env x11vnc_prog;
- global helpall helptext;
-
- set helppipe [open "| $x11vnc_prog -help" "r"];
- if {$helppipe == ""} {
- puts stderr "failed to run $x11vnc_prog -help";
- exit 1;
- }
-
- set sawopts 0;
- set curropt "";
- while {[gets $helppipe line] > -1} {
- append helpall "$line\n"
-
- # XXX
- if {[regexp {^Options:} $line]} {
- set sawopts 1;
- continue;
- }
- # XXX
- if {[regexp {^These options} $line]} {
- continue;
- }
- # tweak aliases:
- regsub {^-zeroconf} $line "-zero_conf" line
- regsub {^-avahi } $line "-zeroconf" line
-
- if {! $sawopts} {
- continue;
- }
- if {[regexp {^-([0-9A-z_][0-9A-z_]*)} $line match name]} {
- set allnames($name) 1;
- if {"$curropt" != "no$name" && "no$curropt" != "$name"} {
- set curropt $name;
- set helptext($curropt) "$line\n";
- } else {
- append helptext($curropt) "$line\n";
- }
- } elseif {$curropt != ""} {
- append helptext($curropt) "$line\n";
- }
- }
- foreach name [array names allnames] {
- if {[regexp {^no} $name]} {
- regsub {^no} $name "" pair
- } else {
- set pair "no$name"
- }
- if {[info exists helptext($name)]} {
- if ![info exists helptext($pair)] {
- set helptext($pair) $helptext($name);
- }
- } elseif {[info exists helptext($pair)]} {
- if ![info exists helptext($name)] {
- set helptext($name) $helptext($pair);
- }
- }
- }
-
- set_internal_help
-}
-
-proc tweak_both {new old} {
- tweak_help $new $old
- tweak_remote_help $new $old
-}
-
-proc tweak_remote_help {new old} {
- global helpremote
- if ![info exists helpremote($new)] {
- if {[info exists helpremote($old)]} {
- set helpremote($new) $helpremote($old)
- }
- }
-}
-
-proc tweak_help {new old} {
- global helptext
- if ![info exists helptext($new)] {
- if {[info exists helptext($old)]} {
- set helptext($new) $helptext($old)
- }
- }
-}
-
-proc parse_remote_help {} {
- global helpremote helptext help_indent remote_name;
-
- set sawopts 0;
- set curropt "";
- set possopts "";
- set offset [expr $help_indent - 1];
- foreach line [split $helptext(remote) "\n"] {
-
- set line [string range $line $offset end];
-
- # XXX
- if {[regexp {^The following -remote/-R commands} $line]} {
- set sawopts 1;
- continue;
- }
- # XXX
- if {[regexp {^The vncconnect.*command} $line]} {
- set sawopts 0;
- }
-
- if {! $sawopts} {
- continue;
- }
- if {[regexp {^([0-9A-z_][0-9A-z_:]*)} $line match name]} {
- regsub {:.*$} $name "" popt
- lappend possopts $popt
- if {"$curropt" != "no$name" && "no$curropt" != "$name"} {
- set curropt $name;
- regsub {:.*$} $curropt "" curropt
- set remote_name($curropt) $name
- set helpremote($curropt) "$line\n";
- } else {
- append helpremote($curropt) "$line\n";
- }
- } elseif {$curropt != ""} {
- append helpremote($curropt) "$line\n";
- }
- }
-
- foreach popt $possopts {
- if {[info exists helpremote($popt)]} {
- continue
- }
- if {[regexp {^no} $popt]} {
- regsub {^no} $popt "" try
- } else {
- set try "no$popt"
- }
- if {[info exists helpremote($try)]} {
- set helpremote($popt) $helpremote($try)
- }
- }
-}
-
-proc parse_query_help {} {
- global query_ans query_aro query_ans_list query_aro_list helptext;
-
- set sawans 0;
- set sawaro 0;
- set ans_str ""
- set aro_str ""
-
- foreach line [split $helptext(query) "\n"] {
-
- if {! $sawans && [regexp {^ *ans=} $line]} {
- set sawans 1
- }
- if {! $sawans} {
- continue
- }
-
- if {[regexp {^ *aro=} $line]} {
- set sawaro 1
- }
- if {$sawaro && [regexp {^[ ]*$} $line]} {
- set sawans 0
- break
- }
-
- regsub {ans=} $line "" line
- regsub {aro=} $line "" line
- set line [string trim $line]
-
- if {$sawaro} {
- set aro_str "$aro_str $line"
- } else {
- set ans_str "$ans_str $line"
- }
- }
-
- regsub -all { *} $ans_str " " ans_str
- regsub -all { *} $aro_str " " aro_str
-
- set ans_str [string trim $ans_str]
- set aro_str [string trim $aro_str]
- set query_ans_list [split $ans_str]
- set query_aro_list [split $aro_str]
-
- foreach item $query_ans_list {
- if {[regexp {^[ ]*$} $item]} {
- continue
- }
- set query_ans($item) 1
- }
- foreach item $query_aro_list {
- if {[regexp {^[ ]*$} $item]} {
- continue
- }
- set query_aro($item) 1
- }
-}
-
-proc in_debug_mode {} {
- global menu_var
- if {![info exists menu_var(debug_gui)]} {
- return 0
- }
- return $menu_var(debug_gui)
-}
-
-# Menubar utilities:
-proc menus_state {state} {
- global menu_b
-
- foreach case [array names menu_b] {
- set menu_button $menu_b($case)
- if {![winfo exists $menu_button]} {
- continue
- }
- $menu_button configure -state $state
- }
-}
-
-proc menus_enable {} {
- global menus_disabled
-
- menus_state "normal"
- set menus_disabled 0
-}
-
-proc menus_disable {} {
- global menus_disabled
-
- set menus_disabled 1
- menus_state "disabled"
-}
-
-# Entry box utilities:
-proc entry_state {x state} {
- global entry_box entry_label entry_ok entry_help entry_skip entry_browse
- global old_labels
- if {$x == "all"} {
- if {!$old_labels} {
- $entry_label configure -state $state
- }
- $entry_box configure -state $state
- $entry_ok configure -state $state
- $entry_skip configure -state $state
- $entry_help configure -state $state
- $entry_browse configure -state $state
- } elseif {$x == "label"} {
- if {!$old_labels} {
- $entry_label configure -state $state
- }
- } elseif {$x == "box"} {
- $entry_box configure -state $state
- } elseif {$x == "ok"} {
- $entry_ok configure -state $state
- } elseif {$x == "skip"} {
- $entry_skip configure -state $state
- } elseif {$x == "help"} {
- $entry_help configure -state $state
- } elseif {$x == "browse"} {
- $entry_browse configure -state $state
- }
-}
-
-proc entry_enable {{x "all"}} {
- entry_state $x normal
-}
-
-proc entry_disable {{x "all"}} {
- entry_state $x disabled
-}
-
-proc entry_browse_button {{show 1}} {
- global entry_browse
- if {$show} {
- pack $entry_browse -side left
- } else {
- pack forget $entry_browse
- }
-}
-proc entry_focus {} {
- global entry_box
- focus $entry_box
-}
-proc entry_select {} {
- global entry_box
- $entry_box selection range 0 end
-}
-proc entry_get {} {
- global entry_box
- return [$entry_box get]
-}
-proc entry_insert {str} {
- global entry_box
- entry_delete
- $entry_box insert end $str
- $entry_box icursor end
-}
-proc entry_delete {} {
- global entry_box
- $entry_box delete 0 end
-}
-
-
-# Utilities for remote control and updating vars.
-
-proc push_new_value {item name new {query 1}} {
- global menu_var always_update remote_output query_output
- global query_result_list
-
- set debug [in_debug_mode]
-
- set getout 0
- set print_getout 0;
-
- set do_query_all 0
-
- set newnew ""
- if {$item == "disconnect"} {
- set newnew "N/A"
- set do_query_all 1
- } elseif {$always_update} {
- set do_query_all 1
- }
-
- if {$item == "remote-cmd"} {
- # kludge for arbitrary remote command:
- if {[regexp {^Q:} $new]} {
- # extra kludge for Q:var to mean -Q var
- regsub {^Q:} $new "" new
- set qonly 1
- } else {
- set qonly 0
- }
- # need to extract item from new:
- set qtmp $new
- regsub {:.*$} $qtmp "" qtmp
- if {$qonly} {
- set rargs [list "-Q" "$qtmp"]
- set print_getout 1
- set qargs ""
- } else {
- set rargs [list "-R" "$new"]
- set qargs ""
- }
- set getout 1
-
- } elseif {[value_is_string $item]} {
- # string var:
- set rargs [list "-R" "$name:$new"]
- set qargs [list "-Q" "$name"]
- } else {
- # boolean var:
- set rargs [list "-R" "$name"]
- set qargs [list "-Q" "$name"]
- }
-
- if {! $query && ! $always_update} {
- set getout 1
- } elseif {$item == "noremote"} {
- set getout 1
- } elseif {[is_action $item] && ![opt_match Q $item] && $rargs != ""} {
- set getout 1
- } elseif {[regexp {^(sid|id)$} $item] && ![regexp {^0x} $new]} {
- set getout 1
- }
-
- set remote_output ""
- set query_output ""
-
- if {!$debug} {
- if [regexp {passwd} $rargs] {
- append_text "x11vnc ..."
- } else {
- append_text "x11vnc $rargs ..."
- }
- }
-
- if {$getout} {
- set remote_output [run_remote_cmd $rargs]
- if {$print_getout} {
- append_text "\t$remote_output"
- }
- append_text "\n"
- return
- }
-
- if {$do_query_all} {
- set all [all_query_vars]
- set qargs [list "-Q" $all]
-
- global last_query_all_time
- set last_query_all_time [clock seconds]
- }
-
- set rqargs [concat $rargs $qargs]
-
- set query [run_remote_cmd $rqargs]
- set query_output $query
-
- set query_result_list ""
-
- if {$newnew != ""} {
- set new $newnew
- }
-
- if {![see_if_ok $query $item "$name:$new"]} {
- # failed
- if {[regexp {^a..=} $query]} {
- # but some result came back
- # synchronize everything with a 2nd call.
- set query_output [query_all 1]
- } else {
- # server may be dead
- if {$item != "ping" && $item != "attach"} {
- try_connect
- }
- }
- } else {
- # succeeded
- # synchronize this variable (or variables)
- # for a speedup used the list parsed by see_if_ok.
- update_menu_vars "USE_LIST"
-
- if {$do_query_all} {
- global all_settings
- set all_settings $query
- }
- }
-}
-
-proc set_kmbc_str {} {
- global vl_bk vl_bm vl_bb vl_bc vl_bf vr_bk vr_bm vr_bb vr_bc vr_bf
-
- set str ""
- if {$vl_bk} {
- append str "K"
- }
- if {$vl_bm} {
- append str "M"
- }
- if {$vl_bb} {
- append str "B"
- }
- if {$vl_bc} {
- append str "C"
- }
- if {$vl_bf} {
- append str "F"
- }
- if {$vr_bk || $vr_bm || $vr_bb || $vr_bc || $vr_bf} {
- append str ","
- }
- if {$vr_bk} {
- append str "K"
- }
- if {$vr_bm} {
- append str "M"
- }
- if {$vr_bb} {
- append str "B"
- }
- if {$vr_bc} {
- append str "C"
- }
- if {$vr_bf} {
- append str "F"
- }
- entry_insert $str
-}
-
-proc insert_input_window {} {
- global text_area cleanup_window
- global ffont menu_var
- global vl_bk vl_bm vl_bb vl_bc vl_bf vr_bk vr_bm vr_bb vr_bc vr_bf
-
- append_text "\nUse these checkboxes to set the input permissions, "
- append_text "or type in the \"KMBCF...\"\n"
- append_text "-input string manually. Then press \"OK\" or \"Cancel\".\n"
- append_text "(note: an empty setting means use the default behavior, "
- append_text "see viewonly)\n\n"
- set w "$text_area.wk_f"
- catch {destroy $w}
- frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
- set fl $w.fl
- frame $fl
- set fr $w.fr
- frame $fr
- label $fl.l -font $ffont -text "Normal clients: "
- checkbutton $fl.bk -pady 1 -font $ffont -anchor w -variable vl_bk \
- -pady 1 -command set_kmbc_str -text "Keystrokes"
- checkbutton $fl.bm -font $ffont -anchor w -variable vl_bm \
- -pady 1 -command set_kmbc_str -text "Mouse-Motion"
- checkbutton $fl.bb -font $ffont -anchor w -variable vl_bb \
- -pady 1 -command set_kmbc_str -text "Button-Click"
- checkbutton $fl.bc -font $ffont -anchor w -variable vl_bc \
- -pady 1 -command set_kmbc_str -text "Clipboard-Input"
- checkbutton $fl.bf -font $ffont -anchor w -variable vl_bf \
- -pady 1 -command set_kmbc_str -text "Files"
- label $fr.l -pady 1 -font $ffont -text "View-Only clients:"
- checkbutton $fr.bk -font $ffont -anchor w -variable vr_bk \
- -pady 1 -command set_kmbc_str -text "Keystrokes"
- checkbutton $fr.bm -font $ffont -anchor w -variable vr_bm \
- -pady 1 -command set_kmbc_str -text "Mouse-Motion"
- checkbutton $fr.bb -font $ffont -anchor w -variable vr_bb \
- -pady 1 -command set_kmbc_str -text "Button-Click"
- checkbutton $fr.bc -font $ffont -anchor w -variable vr_bc \
- -pady 1 -command set_kmbc_str -text "Clipboard-Input"
- checkbutton $fr.bf -font $ffont -anchor w -variable vr_bf \
- -pady 1 -command set_kmbc_str -text "Files"
-
- if {[info exists menu_var(input)]} {
- set input_str $menu_var(input)
- } else {
- set input_str ""
- }
-
- if {[regexp {(.*),(.*)} $input_str match normal viewonly]} {
- ;
- } else {
- set normal $input_str
- set viewonly ""
- }
- set vl_bk 0
- set vl_bm 0
- set vl_bb 0
- set vl_bc 0
- set vl_bf 0
-
- set vr_bk 0
- set vr_bm 0
- set vr_bb 0
- set vr_bc 0
- set vr_bf 0
-
- if {[regexp -nocase {K} $normal]} {
- set vl_bk 1
- }
- if {[regexp -nocase {M} $normal]} {
- set vl_bm 1
- }
- if {[regexp -nocase {B} $normal]} {
- set vl_bb 1
- }
- if {[regexp -nocase {C} $normal]} {
- set vl_bc 1
- }
- if {[regexp -nocase {F} $normal]} {
- set vl_bf 1
- }
- if {[regexp -nocase {K} $viewonly]} {
- set vr_bk 1
- }
- if {[regexp -nocase {M} $viewonly]} {
- set vr_bm 1
- }
- if {[regexp -nocase {B} $viewonly]} {
- set vr_bb 1
- }
- if {[regexp -nocase {C} $viewonly]} {
- set vr_bc 1
- }
- if {[regexp -nocase {F} $viewonly]} {
- set vr_bf 1
- }
-
- pack $fl.l $fl.bk $fl.bm $fl.bb $fl.bc $fl.bf -side top -fill x
- pack $fr.l $fr.bk $fr.bm $fr.bb $fr.bc $fr.bf -side top -fill x
- pack $fl $fr -side left
- update
- update idletasks
- $text_area window create end -window $w
- $text_area see end
- $text_area insert end "\n"
-# $text_area insert end "\n\n\n\n\n\n\n\n\n"
-
- set cleanup_window $w
-}
-
-proc set_ca_str {w} {
- global ca_bk ca_bm ca_bb ca_bc ca_bf ca_di
-
- if {$ca_di} {
- entry_insert "disconnect"
- $w.bk configure -state disabled
- $w.bm configure -state disabled
- $w.bb configure -state disabled
- $w.bc configure -state disabled
- $w.bf configure -state disabled
- return
- }
-
- $w.bk configure -state normal
- $w.bm configure -state normal
- $w.bb configure -state normal
- $w.bc configure -state normal
- $w.bf configure -state normal
-
- set str ""
- if {$ca_bk} {
- append str "K"
- }
- if {$ca_bm} {
- append str "M"
- }
- if {$ca_bb} {
- append str "B"
- }
- if {$ca_bc} {
- append str "C"
- }
- if {$ca_bf} {
- append str "F"
- }
- entry_insert $str
-}
-
-proc insert_client_action_window {input} {
- global text_area cleanup_window
- global ffont menu_var
- global ca_bk ca_bm ca_bb ca_bc ca_bf ca_di
-
- append_text "\nUse these checkboxes to set the input permissions "
- append_text "for this client\n-OR- whether to disconnect it instead. "
- append_text "Then press \"OK\" or \"Cancel\".\n\n"
- set w "$text_area.ca_f"
- catch {destroy $w}
- frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
- checkbutton $w.di -pady 1 -font $ffont -anchor w -variable ca_di \
- -pady 1 -command "set_ca_str $w" -text "Disconnect "
- checkbutton $w.bk -font $ffont -anchor w -variable ca_bk \
- -pady 1 -command "set_ca_str $w" -text "Keystrokes"
- checkbutton $w.bm -font $ffont -anchor w -variable ca_bm \
- -pady 1 -command "set_ca_str $w" -text "Mouse-Motion"
- checkbutton $w.bb -font $ffont -anchor w -variable ca_bb \
- -pady 1 -command "set_ca_str $w" -text "Button-Click"
- checkbutton $w.bc -font $ffont -anchor w -variable ca_bc \
- -pady 1 -command "set_ca_str $w" -text "Clipboard"
- checkbutton $w.bf -font $ffont -anchor w -variable ca_bf \
- -pady 1 -command "set_ca_str $w" -text "Files"
-
- set ca_di 0
- set ca_bk 0
- set ca_bm 0
- set ca_bb 0
- set ca_bf 0
- set ca_bc 0
-
- if {[regexp -nocase {K} $input]} {
- set ca_bk 1
- }
- if {[regexp -nocase {M} $input]} {
- set ca_bm 1
- }
- if {[regexp -nocase {B} $input]} {
- set ca_bb 1
- }
- if {[regexp -nocase {C} $input]} {
- set ca_bc 1
- }
- if {[regexp -nocase {F} $input]} {
- set ca_bf 1
- }
-
- pack $w.di $w.bk $w.bm $w.bb $w.bc $w.bf -side left
- update
- update idletasks
- $text_area window create end -window $w
- $text_area see end
- $text_area insert end "\n"
-
- set cleanup_window $w
-}
-
-proc cleanup_text_window {} {
- global cleanup_window
- if {[info exists cleanup_window]} {
- catch {destroy $cleanup_window}
- }
-}
-
-# For updating a string variable. Also used for simple OK/Cancel dialogs
-# with entry = 0.
-proc entry_dialog {item {entry 1}} {
- global menu_var entry_str entry_set entry_dialog_item
- global unset_str connected_to_x11vnc entry_box
-
- set entry_str "Set $item"
- set entry_set 0
- set entry_dialog_item $item
-
- entry_enable
- menus_disable
-
- if {$item == "passwd" || $item == "viewpasswd"} {
- $entry_box configure -show "*"
- }
-
- if {$entry} {
- entry_insert ""
- if {[info exists menu_var($item)] &&
- $menu_var($item) != $unset_str} {
- entry_insert $menu_var($item)
- entry_select
- }
-
- if {[is_browse $item]} {
- entry_browse_button
- }
- set_info "Set parameter in entry box, "
- entry_focus
- } else {
- entry_disable box
- }
-
- set clean_text_window 0;
-
- if {$item == "input"} {
- insert_input_window
- set clean_text_window 1
- }
-
- update
-
- # wait for user reply:
- vwait entry_set
-
- set rc $entry_set
- set entry_set 0
-
- set value [entry_get]
- update
-
- entry_browse_button 0
- set entry_str "Set... :"
-
- entry_delete
- entry_disable
- menus_enable
-
- if {$clean_text_window} {
- cleanup_text_window;
- }
-
- update
-
- if {! $entry} {
- ;
- } elseif {$rc} {
- set menu_var($item) $value
- } else {
- if {[in_debug_mode]} {
- append_text "skipped setting $item\n"
- }
- }
-
- $entry_box configure -show ""
-
- return $rc
-}
-
-proc warning_dialog {msg {item "gui"} } {
- append_text $msg
- # just reuse the entry widgets for a yes/no dialog
- return [entry_dialog $item 0]
-}
-
-# For updating a boolean toggle:
-proc check_var {item} {
- global menu_var
-
- set inval $menu_var($item);
-
- if {$item == "debug_gui"} {
- return "";
- }
-
- set rname $item
- if {! $inval} {
- if {[regexp {^no} $item]} {
- regsub {^no} $rname "" rname
- } else {
- set rname "no$rname"
- }
- }
- return $rname
-}
-
-proc see_if_ok {query item expected} {
- global query_result_list
-
- set ok 0
- set found ""
-
- set query_result_list [split_query $query]
-
- foreach q $query_result_list {
- # XXX following will crash if $item is not a good regexp
- # need to protect it \Q$item\E style...
-# if {[regexp "^$item:" $q]} {
-# set found $q
-# }
- if {[string first "$item:" $q] == 0} {
- set found $q
- }
- if {$q == $expected} {
- set ok 1
- if {$found != ""} {
- break;
- }
- }
- }
- if {$found == ""} {
- set msg $query
- regsub {^a..=} $msg {} msg
- if {[string length $msg] > 60} {
- set msg [string range $msg 0 60]
- }
- } else {
- set msg $found
- }
- if {!$ok && $found != ""} {
- # check for floating point match:
- set v1 ""
- set v2 ""
- regexp {:([0-9.][0-9.]*)$} $found m0 v1
- regexp {:([0-9.][0-9.]*)$} $expected m0 v2
- if {$v1 != "" && $v2 != ""} {
- set diff ""
- catch {set diff [expr "$v1 - $v2"]}
- if {$diff != ""} {
- if {$diff < 0} {
- set diff [expr "0.0 - $diff"]
- }
- if {$diff < 0.00001} {
- set ok 1
- }
- }
- }
- }
- if {$ok} {
- append_text "\tSet OK ($msg)\n"
- return 1
-
- } elseif {[opt_match P $item] && [regexp {:(-|\+)} $expected]} {
- # e.g. blackout:+30x30+20+20
- append_text "\t($msg)\n"
- return 1
- } elseif {[regexp {:[0-9]\.[0-9]} $expected]} {
- append_text "\t($msg)\n"
- return 1
- } elseif {$item == "connect" || $item == "disconnect"
- || $item == "client" || $item == "client_input"} {
- append_text "\t($msg)\n"
- return 1
- } elseif {$item == "passwd" || $item == "viewpasswd"} {
- append_text "\t($msg)\n"
- return 1
- } else {
- append_text "\t*FAILED* $msg\n"
- return 0
- }
-}
-
-proc get_default_vars {} {
- global default_var env
-
- set qry [all_query_vars]
-
- append qry ",vncconnect"
-
- set q ""
- set i 0
- set all ""
- foreach s [split $qry ","] {
- if {$q != ""} {
- append q ","
- }
- append q $s
- incr i
- if {$i > 50} {
- set qargs [list "-QD" $q]
- set a [run_remote_cmd $qargs]
- if [info exists env(TKX11VNC_PRINT_ALL_QD)] {
- puts $q
- puts $a
- puts "---------------"
- }
- if {$all != ""} {
- append all ","
- }
- append all $a
- set q ""
- set i 0
- }
- }
- if {$q != ""} {
- set qargs [list "-QD" $q]
- set a [run_remote_cmd $qargs]
- if [info exists env(TKX11VNC_PRINT_ALL_QD)] {
- puts $q
- puts $a
- puts "---------------"
- }
- if {$all != ""} {
- append all ","
- }
- append all $a
- }
-
-# old way, qry too long...
-# set qargs [list "-QD" $qry]
-# set all [run_remote_cmd $qargs]
-
- if {[regexp {ans=} $all]} {
- #append_text "Retrieved all default settings.\n"
- } else {
- #append_text "Failed to retrieve default settings.\n"
- }
-
- set query_result_list [split_query $all]
-
- set default_var(gui) ""
-
- foreach piece $query_result_list {
- if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {
- if {$val == "N/A"} {
- if {$item == "vncconnect"} {
- set val 1
- } else {
- set val ""
- }
- }
- if {$item == "display"} {
- set val ""
- } elseif {$item == "desktop"} {
- set val ""
- } elseif {$item == "auth"} {
- set val ""
- } elseif {$item == "gui"} {
- continue
- }
- # some hacks we do here for now..
- if {$item == "cursor" && $val == ""} {
- set val "most"
- } elseif {$item == "scrollcopyrect" && $val == ""} {
- set val "always"
- } elseif {$item == "wirecopyrect" && $val == ""} {
- set val "always"
-# } elseif {$item == "overlay_nocursor" && $val == 0} {
-# set val 1
- }
-
- set default_var($item) $val
-#puts "default: $item -> $val"
- }
- }
-}
-
-proc tilde_expand {file} {
- global env
- if {[file exists $file]} {
- return $file
- }
-
- set user ""
- if {[info exists env(USER)]} {
- set user $env(USER)
- }
- if {$user == "" && [info exists env(LOGNAME)]} {
- set user $env(LOGNAME)
- }
-
- set home ""
- if {[info exists env(HOME)]} {
- set home $env(HOME)
- } elseif {$user != ""} {
- set home "/home/$user"
- }
-
- if {[regexp {^~} $file]} {
- if {[regexp {^~/} $file]} {
- if {$home != ""} {
- regsub {^~} $file $home file
- }
- } else {
- regsub {^~} $file "/home/" file
- }
- }
- return $file
-}
-
-proc insert_cmdline_vars {} {
- global env cmd_var menu_var default_var x11vnc_cmdline
- if {![info exists x11vnc_cmdline]} {
- return
- }
- if {$x11vnc_cmdline == ""} {
- return
- }
- set cmd_var(novar) 1
- set str [string trim $x11vnc_cmdline]
-
- while {[regexp -- {^-} $str]} {
- if {[regexp -- {^--*([^ \t][^ \t]*)(.*)$} $str m var rest]} {
- set rest [string trim $rest]
- set var [string trim $var]
- if {[regexp {^\{\{([^\}]*)\}\}(.*)} $rest m val rest]} {
- set str [string trim $rest]
- set cmd_var($var) $val
- } else {
- set str $rest
- set cmd_var($var) "boolean"
- }
- } else {
- break
- }
- }
-
- if {[info exists cmd_var(rc)]} {
- load_settings $cmd_var(rc)
- } elseif {[info exists cmd_var(norc)]} {
- ;
- } else {
- set filex [tilde_expand "~/.x11vncrc"]
- if {[file exists $filex]} {
- load_settings $filex
- }
- }
-
- foreach var [array names cmd_var] {
- if {$var == "novar"} {
- continue
- }
- if {[regexp {^[ \t]*$} $var]} {
- continue
- }
- if {[info exists menu_var($var)]} {
- if {$cmd_var($var) == "boolean"} {
- set menu_var($var) 1
- } else {
- set menu_var($var) $cmd_var($var)
- }
- }
- }
-}
-
-proc copy_default_vars {} {
- global menu_var default_var
- foreach item [array names default_var] {
- if {[info exists menu_var($item)]} {
- if {[info exists default_var($item)]} {
- set menu_var($item) $default_var($item)
- }
- }
- }
- foreach item [array names menu_var] {
- if {[info exists default_var($item)]} {
- set menu_var($item) $default_var($item)
- }
- }
-}
-
-proc update_menu_vars {{query ""}} {
- global all_settings menu_var query_result_list
- global x11vnc_icon_mode
-
- set debug [in_debug_mode]
-
- if {$query == "USE_LIST"} {
- ;
- } elseif {$query == ""} {
- set query_result_list [split_query $all_settings]
- } else {
- set query_result_list [split_query $query]
- }
-
- foreach piece $query_result_list {
-#puts stderr "UMV: $piece"
- if [regexp {icon_mode:0} $piece] {
- set x11vnc_icon_mode 0
- #puts stderr "x11vnc_icon_mode: $x11vnc_icon_mode"
- }
- if [regexp {icon_mode:1} $piece] {
- set x11vnc_icon_mode 1
- #puts stderr "x11vnc_icon_mode: $x11vnc_icon_mode"
- }
- # XXX ipv6
- if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {
- if {[info exists menu_var($item)]} {
- set old $menu_var($item)
-#puts stderr " $old"
- if {$val == "N/A"} {
- continue
- }
- set menu_var($item) $val
- }
- if {$item == "clients"} {
- update_clients_menu $val
- } elseif {$item == "display"} {
- set_x11_display $val
- } elseif {$item == "vncdisplay"} {
- set_vnc_display $val
- } elseif {$item == "http_url"} {
- set_vnc_url $val
- }
- }
- }
-}
-
-proc load_settings {{file ""}} {
- global menu_var default_var env
-
- if {$file == ""} {
- if {![info exists menu_var(load-settings)]} {
- return
- }
- set file $menu_var(load-settings)
- }
- if {$file == ""} {
- return
- }
-
- set fh ""
- set filex [tilde_expand $file]
- catch {set fh [open $filex "r"]}
-
- if {$fh == ""} {
- append_text "load_settings: *** failed to open $filex ***\n"
- return
- }
- copy_default_vars
-
- set str ""
- while {[gets $fh line] > -1} {
- regsub -all {\\#} $line {__QUOTED_HASH__} line
- if {[regexp {^[ \t]*#} $line]} {
- continue
- }
- for {set i 0} {$i < 5} {incr i} {
- regsub {#.*$} $line "" line
- }
- if {[regexp {^[ \t]*$} $line]} {
- continue
- }
- regsub -all {__QUOTED_HASH__} $line {#} line
- if {[regexp {\\$} $line]} {
- regsub {\\$} $line " " line
- append str "$line"
- } else {
- append str "$line\n"
- }
- }
- close $fh
-
- set count 0
- set parms ""
-
- foreach line [split $str "\n"] {
- set line [string trim $line]
- regsub {^--*} $line "" line
- regsub -all {[ \t][ \t]*} $line " " line
- set list [split $line]
- set item [lindex $list 0]
- set value [lindex $list 1]
- if {[regexp {^[ \t]*$} $item]} {
- continue
- }
- if {$item == "gui"} {
- continue
- }
- if {[info exists menu_var($item)]} {
- if {[value_is_bool $item]} {
- set menu_var($item) 1
- incr count
- append parms " -$item\n"
- } elseif {[value_is_string $item]} {
- if {$value != ""} {
- set menu_var($item) $value
- set nitem [get_nitem $item]
- append parms " -$nitem $value\n"
- incr count
- }
- }
- }
- }
- append_text "loaded $count parameter settings from $filex"
- if {$count > 0} {
- append_text ":\n"
- append_text $parms
- } else {
- append_text ".\n"
- }
-}
-
-proc save_settings {} {
- set rc_text [get_settings_rcfile]
-
- set top "#
-# This file is based on the current x11vnc settings and can be used as
-# as a ~/.x11vncrc defaults file. If saved to another filename, these
-# settings can be passed to x11vnc at startup via \"-rc <filename>\".
-#
-# The rc file comment character is \"#\". Use \"\\#\" for the literal char.
-# You can continue lines using \"\\\" as the last character of a line.
-#
-# Lines beginning with \"#d\" indicate the parameter value is at its default
-# setting and you probably want to leave it commented out.
-#
-# Lines beginning with \"#?\" indicate parameters you probably do not
-# want to hardwire to the current setting (uncomment if you want that).
-#
-# Some parameters are boolean, e.g. -forever, and take no value; while
-# the others, e.g. -wait 50, take a string or numerical value.
-#
-# For booleans, the line will end with comment \"default: on\" or
-# \"default: off\" indicating the default setting. (Note: often
-# \"-nofoobar\" corresponds to option \"-foobar\" and the former is
-# \"the default\", e.g. -norepeat).
-#
-# For string or numerical options, the value \"\" in a line below
-# means the default is unset and you will need to supply some non-empty
-# value to use the parameter. For reference, if the default differs
-# from your value it placed at the end of the line as a comment.
-#
-# Feel free to uncomment or comment any of the lines or to change any
-# of the values of the parameters. Don't be surprised that most if not
-# all of the lines below are commented out (x11vnc has so many parameters,
-# most of them will be at their default values).
-#-------------------------------------------------------------------------
-
-"
-
- set rc_text "$top$rc_text"
-
- global env save_settings_var save_settings_var_ok
- if {[info exists env(HOME)]} {
- set save_settings_var "$env(HOME)/.x11vncrc"
- } else {
- set save_settings_var ".x11vncrc"
- }
- set save_settings_var_ok 0
-
- set w [textwin "save_settings" "Save Settings..." $rc_text \
- "save_settings_var+Save as:"]
-
- tkwait window $w
-
- if {$save_settings_var_ok == 1} {
- set file $save_settings_var
- if {$file == ""} {
- return
- }
- set file [tilde_expand $file]
- append_text "\nSaving current settings to $file ...\n"
- if {[file exists $file]} {
- set backup "${file}~"
- append_text "Backing up $file -> $backup ...\n"
- catch {file delete -force $backup}
- set emsg "*** Backup to $backup failed. ***\n"
- if {![file exists $backup]} {
- catch {file copy -force $file $backup}
- if {![file exists $backup]} {
- append_text $emsg
- bell
- }
- } else {
- append_text $emsg
- bell
- }
- }
- set fh ""
- catch {set fh [open $file "w"]}
- if {$fh != ""} {
- puts $fh $rc_text
- close $fh
- if {![file exists $file]} {
- append_text "*** Saving to $file failed. ***\n"
- bell
- } else {
- append_text "Done.\n"
- }
- } else {
- append_text "*** Open of $file failed. ***\n"
- bell
- }
- }
-}
-
-proc clear_all {} {
- global menu_var unset_str
-
- set debug [in_debug_mode]
-
- foreach item [array names menu_var] {
- if {$item == "debug_gui"} {
- continue
- }
- if {[info exists menu_var($item)]} {
- if {[is_action $item]} {
- set menu_var($item) ""
- } elseif {[value_is_bool $item]} {
- set menu_var($item) 0
- } elseif {[value_is_string $item]} {
- set menu_var($item) $unset_str
- }
- }
- }
- append_text "Cleared all settings.\n"
-}
-
-proc defaults_all {} {
- copy_default_vars
- append_text "Reset all variables to default values.\n"
-}
-
-proc all_query_vars {} {
- global query_ans_list query_aro_list all_settings
- global cache_all_query_vars
-
- if {$cache_all_query_vars != ""} {
- return $cache_all_query_vars
- }
-
- set qry ""
- foreach item $query_ans_list {
- if {$qry == ""} {
- set qry $item
- } else {
- append qry ",$item"
- }
- }
- foreach item $query_aro_list {
- if {$qry == ""} {
- set qry $item
- } else {
- append qry ",$item"
- }
- }
- set cache_all_query_vars $qry
-
- global env
- if [info exists env(TKX11VNC_PRINT_ALL_VARS)] {
- puts "--------------- BEGIN ALL VARS ---------------"
- puts $qry
- puts "--------------- END ALL VARS ---------------"
- }
-
- return $qry
-}
-
-proc query_all {{quiet 0}} {
- global query_ans_list query_aro_list all_settings
- global last_query_all_time
-
- dtime 1
- set qry [all_query_vars]
-
- set qargs [list "-Q" $qry]
- set all [run_remote_cmd $qargs]
-
- if {[regexp {ans=} $all]} {
- if {! $quiet} {
- append_text "Retrieved all current settings.\n"
- }
- set all_settings $all
- update_menu_vars $all
- } else {
- if {! $quiet} {
- append_text "Failed to retrieve current settings.\n"
- }
- }
- set last_query_all_time [clock seconds]
- dtime 2
- return $all
-}
-
-proc set_info {str} {
- global info_str info_label
-#set w1 [$info_label cget -width]
-#set w2 [winfo width $info_label]
-#puts "set_info: w=$w1 winfo=$w2"
-#append_text "$str\n"
- set info_str "$str"
- update
-}
-
-proc append_text {str} {
- global text_area text_area_str
-
- if {![info exists text_area_str]} {
- set text_area_str ""
- }
- append text_area_str $str
-
- if {![info exists text_area]} {
- puts stderr $str
- return
- }
- if {$text_area == ""} {
- puts stderr $str
- return
- }
- if {![winfo exists $text_area]} {
- puts stderr $str
- return
- }
-
- $text_area insert end $str
- $text_area see end
-}
-
-proc show_all_settings {} {
- global all_settings
- global client_sock client_tail
- global x11vnc_client_file
-
- set txt "\nRead-Write settings:\n\n"
- foreach item [split_query $all_settings] {
- regsub {:} $item {: } item
- append txt " $item\n"
- if {[regexp {noremote} $item]} {
- append txt "\nRead-Only settings:\n\n"
- }
- }
- append txt "\nInternal settings:\n\n"
- append txt "x11vnc_client_file: $x11vnc_client_file\n"
- if {[info exists client_tail]} {
- append txt "client_tail: $client_tail\n"
- } else {
- append txt "client_tail: unset\n"
- }
- if {[info exists client_sock]} {
- append txt "client_sock: $client_sock\n"
- } else {
- append txt "client_sock: unset\n"
- }
- set estr ""
- catch {set estr [exec env | grep -i X11VNC]}
- append txt "$estr\n"
- textwin "Settings" "All Current Settings" $txt
-}
-
-proc show_logfile {} {
- global menu_var unset_str
-
- set logfile [tilde_expand $menu_var(logfile)]
-
- if {$logfile == "" || $logfile == $unset_str} {
- set txt "\nNo logfile was specified at x11vnc startup.\n\n"
- } elseif {![file exists $logfile]} {
- set txt "\nLogfile \"$logfile\" does not exist.\n\n"
- } else {
- set fh "-3"
- set err ""
- catch {set fh [open $logfile "r"]} err
- if {$fh == "-3"} {
- set txt "\nError opening \"$logfile\" $err.\n\n"
- } else {
- set txt "\nLogfile \"$logfile\" current contents:\n"
- while {[gets $fh line] > -1} {
- append txt "$line\n"
- }
- close $fh
- }
- }
- textwin "Logfile" "Logfile" $txt
-}
-
-proc tail_logfile {} {
- global menu_var unset_str ffont
- set logfile $menu_var(logfile)
-
- set txt ""
- if {$logfile == "" || $logfile == $unset_str} {
- set txt "\nNo logfile was specified at x11vnc startup.\n\n"
- } elseif {![file exists $logfile]} {
- set txt "\nLogfile \"$logfile\" does not exist.\n\n"
- } else {
- set cmd ""
- set xterm_cmd "xterm -sb -fn $ffont -geometry 80x45 -title x11vnc-logfile -e"
- set cmd [split $xterm_cmd]
- lappend cmd "tail"
- lappend cmd "-3000f"
- lappend cmd $logfile
- lappend cmd "&"
- catch {[eval exec $cmd]}
- }
- if {$txt != ""} {
- textwin "Logfile" "Logfile" $txt
- }
-}
-
-proc set_connected {yesno} {
- global connected_to_x11vnc
- set orig $connected_to_x11vnc
-
- if {$yesno == "yes"} {
- set connected_to_x11vnc 1
- } else {
- set connected_to_x11vnc 0
- no_x11_display
- no_vnc_display
- }
- if {$orig != $connected_to_x11vnc} {
- set_widgets
- }
-}
-
-proc detach_from_display {} {
- global connected_to_x11vnc reply_xdisplay x11vnc_xdisplay
- set str "Detaching from X display."
- if {$reply_xdisplay != ""} {
- set str "Detaching from $reply_xdisplay."
- } elseif {$x11vnc_xdisplay != ""} {
- set str "Detaching from $x11vnc_xdisplay."
- }
- if {$connected_to_x11vnc} {
- append_text "$str\n"
- }
- set_connected no
-}
-
-proc do_stop_quit {} {
- push_new_value "stop" "stop" 1 0
- set_connected no
- update
- after 250
- destroy .
-}
-
-# Menu item is an action:
-proc do_action {item} {
- global menu_var connected_to_x11vnc beginner_mode
-
- if {[in_debug_mode]} {
- append_text "action: \"$item\"\n"
- }
-#puts "action: \"$item\"\n"
-
- if {$item == "ping"} {
- if {$beginner_mode} {
- try_connect_and_query_all
- } else {
- try_connect
- }
- return
- } elseif {$item == "start"} {
- start_x11vnc
- return
- } elseif {$item == "detach"} {
- detach_from_display
- return
- } elseif {$item == "attach"} {
- try_connect_and_query_all
- return
- } elseif {$item == "update-all"} {
- query_all
- return
- } elseif {$item == "clear-all"} {
- clear_all
- return
- } elseif {$item == "defaults-all"} {
- defaults_all
- return
- } elseif {$item == "save-settings"} {
- save_settings
- return
- } elseif {$item == "show-start-cmd"} {
- show_start_cmd
- return
- } elseif {$item == "all-settings"} {
- show_all_settings
- return
- } elseif {$item == "show-logfile"} {
- show_logfile
- return
- } elseif {$item == "tail-logfile"} {
- tail_logfile
- return
- } elseif {$item == "Misc-Tuning:"} {
- menu_help "$item"
- return
- } elseif {$item == "WindowView"} {
- change_view_state
- return
- } elseif {$item == "quit" || $item == "Quit"} {
- destroy .
- exit 0
- } elseif {$item == "stop+quit"} {
- do_stop_quit
- }
-
- if {[value_is_string $item]} {
- if {! [entry_dialog $item]} {
- return
- }
- set new $menu_var($item)
- set name $item
- } else {
- set new 1
- set name $item
- }
-
- if {$item == "load-settings"} {
- load_settings
- return
- }
-
- if {! $connected_to_x11vnc} {
- ;
- } elseif {[regexp {^(stop|quit|exit|shutdown)$} $item]} {
- # just do -R
- append_text "stopping remote x11vnc server...\n"
- push_new_value $item $name $new 0
- set_connected no
-
- } elseif {[opt_match Q $item]} {
- push_new_value $item $name $new 1
- } else {
- push_new_value $item $name $new 0
- }
-}
-
-proc ptime {time} {
- set usec [lindex [split $time] 0]
- set sec [format "%.3f" [expr "$usec / 1000000.0"]]
- puts "time: $sec secs."
-}
-
-proc do_var {item} {
- global connected_to_x11vnc item_cascade menu_var
-
- set debug [in_debug_mode]
-
- set string 0
- if {[is_action $item] || $item == "WindowView"} {
- # Menu item is action:
- if {$debug} {
- ptime [time {do_action $item}]
- } else {
- do_action $item
- }
- return
- }
-
- if {[value_is_string $item]} {
- # Menu item is a string:
- if {$item_cascade($item) != ""} {
- # Cascade sets variable automatically
- } else {
- # Otherwise Entry box
- if {![entry_dialog $item]} {
- return
- }
- }
- set new $menu_var($item)
- set name $item
- } else {
- # Menu item is a boolean:
- set name [check_var $item]
- if {$name == ""} {
- return
- }
- set new 1
- }
- if {$connected_to_x11vnc} {
- if {$debug} {
- ptime [time {push_new_value $item $name $new 1}]
- } else {
- push_new_value $item $name $new 1
- }
-
- if {$item == "http"} {
- global vnc_url
- append_text " URL: $vnc_url\n"
- }
- }
-}
-
-proc menu_help {item} {
- if ![help_win $item] {
- textwin "nohelp" "No help available" \
- "Sorry, no help avaiable for \"$item\""
- }
-}
-
-proc opt_match {c item} {
- global item_opts
- if {[info exists item_opts($item)]} {
- if {[regexp "^\[A-z\]*$c" $item_opts($item)]} {
- return 1
- }
- }
- return 0
-}
-
-proc is_action {item} {
- return [opt_match A $item]
-}
-
-proc is_gui_internal {item} {
- if {$item == "Properties"} {
- return 1
- }
- if {$item == "Tray"} {
- return 1
- }
- return [opt_match G $item]
-}
-
-proc is_browse {item} {
- return [opt_match F $item]
-}
-
-proc value_is_string {item} {
- global item_bool
- if {![info exists item_bool($item)]} {
- return 0
- }
- if {! $item_bool($item)} {
- return 1
- } else {
- return 0
- }
-}
-
-proc value_is_bool {item} {
- global item_bool
- if {![info exists item_bool($item)]} {
- return 0
- }
- if {$item_bool($item)} {
- return 1
- } else {
- return 0
- }
-}
-
-proc split_query0 {query} {
- # original slower way with regexp/regsub
- regsub -all {aro=} $query {ans=} query
- set items {}
- while {1} {
- if {! [regexp {^ans=(.*)$} $query m0 m1]} {
- break
- }
- set item $m1
- set m2 ""
- regexp {,ans=.*$} $item m2
- regsub {,ans=.*$} $item "" item
- if {$item != ""} {
- lappend items $item
- }
- set query $m2
- regsub {^,} $query "" query
- }
- return $items
-}
-
-proc split_query {query} {
- regsub -all {aro=} $query {ans=} query
- set items {}
- while {1} {
- set n [string first "ans=" $query]
- if {$n < 0} {
- break
- }
- set from [expr $n+4]
-
- set m [string first ",ans=" $query]
- if {$m < 0} {
- set more 0
- set item [string range $query $from end]
- } else {
- set more 1
- set to [expr $m-1]
- set item [string range $query $from $to]
- }
- if {$item != ""} {
- lappend items $item
- }
- if {$more} {
- incr m
- set query [string range $query $m end]
- } else {
- set query ""
- }
- }
- return $items
-}
-
-proc set_x11_display {name} {
- global x11_display
- set x11_display "x11vnc X display: $name"
- set_name "tkx11vnc - $name"
-}
-proc set_vnc_display {name} {
- global vnc_display icon_mode
- set vnc_display "VNC display: $name"
-
- if {$icon_mode} {
- set_icon_label
- }
-}
-proc set_vnc_url {name} {
- global vnc_url
- set vnc_url $name
-}
-proc no_x11_display {} {
- set_x11_display "(*none*)"
- set_name "tkx11vnc"
-}
-proc no_vnc_display {} {
- set_vnc_display "(*none*)"
-}
-proc no_vnc_url {} {
- set_vnc_url "(*none*)"
-}
-
-proc get_vnc_display_number {} {
- global vnc_display
- if ![info exists vnc_display] {
- return "none"
- }
- if {$vnc_display == ""} {
- return "none"
- }
- set str $vnc_display
- regsub {VNC display: *} $str "" str
- if [regexp {:([0-9][0-9]*)} $str m0 n] {
- return $n
- }
- return "none"
-}
-
-proc fetch_displays {} {
-
- set qargs [list "-Q" "display,vncdisplay"]
- set result [run_remote_cmd $qargs]
-
- set got_x11 0
- set got_vnc 0
- set got_url 0
-
- foreach item [split_query $result] {
- if {[regexp {^display:(.*)$} $item m0 m1]} {
- set_x11_display $m1
- set got_x11 1
- } elseif {[regexp {^vncdisplay:(.*)$} $item m0 m1]} {
- set_vnc_display $m1
- set got_vnc 1
- } elseif {[regexp {^http_url:(.*)$} $item m0 m1]} {
- set_vnc_url $m1
- set got_url 1
- }
- }
- if {! $got_x11} {
- no_x11_display
- }
- if {! $got_vnc} {
- no_vnc_display
- }
- if {! $got_url} {
- no_vnc_url
- }
-}
-
-proc client_dialog {client} {
- set cid ""
- set host ""
- set ip ""
- global menu_var text_area cleanup_window item_bool
-
- #<id>:<ip>:<port>:<user>:<unix>:<hostname>:<input>:<loginview>:<time>
- append_text "\nClient info string:\n - $client\n\n"
- if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \
- $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {
- set cid $m1
- set ip $m2
- set port $m3
- set user $m4
- set unix $m5
- set host $m6
- regsub {\..*$} $host "" host
- set input $m7
- set logvo $m8
- set ltime $m9
- append_text "Host: $host, Port: $port, User: $user"
- if {$unix != "" && $unix != "none"} {
- append_text ", Unix: $unix"
- }
- append_text ", IP: $ip, Id: $cid\n"
- append_text " - originally logged in as: "
- if {$logvo == "1" } {
- append_text "View-Only Client"
- } else {
- append_text "Normal Client"
- }
- if {$ltime != ""} {
- set tim [clock format $ltime]
- append_text ", $tim"
- }
- append_text "\n"
- append_text " - currently allowed input: "
- set sk 0
- set sm 0
- set sb 0
- set sc 0
- set sf 0
- if {[regexp -nocase {K} $input]} {
- append_text "Keystrokes"
- set sk 1
- }
- if {[regexp -nocase {M} $input]} {
- if {$sk} {
- append_text ", "
- }
- append_text "Mouse-Motion"
- set sm 1
- }
- if {[regexp -nocase {B} $input]} {
- if {$sk || $sm} {
- append_text ", "
- }
- append_text "Button-Click"
- set sb 1
- }
- if {[regexp -nocase {C} $input]} {
- if {$sk || $sm || $sb} {
- append_text ", "
- }
- append_text "Clipboard"
- set sm 1
- }
- if {[regexp -nocase {F} $input]} {
- if {$sk || $sm || $sb || $sf} {
- append_text ", "
- }
- append_text "Files"
- set sf 1
- }
- if {! $sk && ! $sm && ! $sb && ! $sm && ! $sf} {
- append_text "None"
- }
- append_text "\n"
- }
- if {$cid == ""} {
- append_text "Invalid client info string: $client\n"
- return
- }
-
- regsub -all {_} $input "" input
- set menu_var(client) "$input"
- set item_bool(client) 0
-
- insert_client_action_window $input
- set rc [entry_dialog client 1]
-
- cleanup_text_window
-
- set val $menu_var(client)
- #puts "rc: $rc val: $val"
-
- if {! $rc} {
- return;
- } elseif {[regexp -nocase {(disconnect|close)} $val]} {
- disconnect_dialog $client
- } else {
- regsub -all -nocase {[^KMBCF]} $val "" val
- set item_bool(client_input) 0
- push_new_value "client_input" "client_input" "$cid:$val" 0
- }
-}
-
-proc disconnect_dialog {client} {
- set cid ""
- set host ""
- set msg "\n"
- append msg "*** Client info string:\n $client\n"
- if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \
- $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {
- set cid $m1
- set ip $m2
- set port $m3
- set user $m4
- set unix $m5
- set host $m6
- regsub {\..*$} $host "" host
- set input $m7
- set logvo $m8
- set ltime $m9
- append_text "Host: $host, Port: $port, IP: $ip, User: $user"
- if {$unix != "" && $unix != "none"} {
- append_text ", Unix: $unix"
- }
- append_text ", Id: $cid\n"
- }
- if {$cid == ""} {
- append_text "Invalid client info string: $client\n"
- return
- }
- append msg "*** To *DISCONNECT* this client press \"OK\" again, otherwise press \"Cancel\"\n"
- bell
- if {[warning_dialog $msg "current"]} {
- push_new_value "disconnect" "disconnect" $cid 1
- } else {
- append_text "disconnect cancelled.\n"
- }
-}
-
-proc update_clients_and_repost {} {
- global item_cascade menu_m menu_b
-
- append_text "Refreshing connected clients list... "
- query_all 1
- update
-
- set saw 0
- set casc $item_cascade(current)
- set last [$casc index end]
- for {set i 0} {$i <= $last} {incr i} {
- if {[$casc type $i] == "separator"} {
- continue
- }
- set name [$casc entrycget $i -label]
- if {[regexp {^num-clients} $name]} {
- continue
- }
- if {[regexp {^refresh-list} $name]} {
- continue
- }
- if {! $saw} {
- append_text "\n"
- }
- set saw 1
- append_text "client: $name\n"
- }
- if {! $saw} {
- append_text "done.\n"
- }
-}
-
-proc update_clients_menu {list} {
- global item_cascade ffont
- global saved_clients_str
-
- if {![info exists saved_clients_str]} {
- set saved_clients_str ""
- }
- if {$list == "INIT"} {
- set list $saved_clients_str
- } else {
- set saved_clients_str $list
- }
-
- set subm $item_cascade(current);
- catch {destroy $subm}
- menu $subm -tearoff 0 -font $ffont
- $subm add command
- $subm add command -label "refresh-list" \
- -command "update_clients_and_repost"
- $subm add separator
- set count 0
- foreach client [split $list ","] {
- if {![regexp {^[a-z0-9]*[a-z0-9]:} $client]} {
- #append_text "Skipping client line: "
- #append_text $client
- #append_text "\n"
- continue
- }
- regsub -all {[{}()~!$&*|;'"`{}<>\[\]]} $client "" client
- #'
- if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \
- $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {
- set id $m1
- set user $m4
- set unix $m5
- set host $m6
- regsub {\..*$} $host "" host
- set clabel "$host $id"
- if {$unix != "" && $unix != "none"} {
- set clabel "$unix@$clabel"
- } elseif {$user != "unknown-user"} {
- set clabel "$user@$clabel"
- }
- } else {
- regsub {:.*$} $client "" clabel
- }
- $subm add command -label "$clabel" \
- -command "client_dialog \{$client\}"
- incr count
- }
- $subm entryconfigure 0 -label "num-clients: $count"
-}
-
-proc set_widgets {} {
- global connected_to_x11vnc item_case item_menu item_entry menu_m
-
- foreach item [array names item_case] {
- if ![info exists item_case($item)] { continue; }
- set case $item_case($item)
- if ![info exists item_menu($item)] { continue; }
- set menu $item_menu($item)
- if ![info exists item_entry($item)] { continue; }
- set entry $item_entry($item)
- if {$entry < 0} {
- # skip case under beginner_mode
- continue
- }
- set type [$menu type $entry]
- if {$type == "separator" || $type == "tearoff"} {
- continue
- }
- if {![winfo exists $menu]} {
- continue
- }
- if {$connected_to_x11vnc} {
- if {[active_when_connected $item]} {
- $menu entryconfigure $entry -state normal
- } else {
- $menu entryconfigure $entry -state disabled
- }
- } else {
- if {[active_when_starting $item]} {
- $menu entryconfigure $entry -state normal
- } else {
- $menu entryconfigure $entry -state disabled
- }
- }
- }
-}
-
-proc toggle_simple_gui {} {
- global beginner_mode simple_gui_created
- global connected_to_x11vnc make_gui_count
-
- if {$beginner_mode} {
- append_text "\nSwitching to simple-gui mode.\n"
- } else {
- append_text "\nSwitching to power-user gui mode.\n"
- }
-
- if {$make_gui_count == 1} {
- incr make_gui_count
- }
- set simple_gui_created 1
- make_menu_items
- set_widgets
- set_internal_help
- append_text "\n"
-}
-
-proc little_qs {m} {
- global bfont ffont beginner_mode
- global helpremote helptext helplabel
- global tk_version osname
-
- if {$tk_version < 8.0} {
- return
- }
- if {$osname == "Darwin"} {
- return
- }
-
- set n [$m index end]
-
- for {set i 0} {$i <= $n} {incr i} {
- set type [$m type $i]
-#puts "$m - $i - $type"
- if {$type == "separator"} {
- $m add separator
- } elseif {$type == "tearoff"} {
- continue;
- } else {
- set label [$m entrycget $i -label]
- set str ""
- if {[info exists helpremote($label)]} {
- set str "(?)"
- } elseif {[info exists helptext($label)]} {
- set str "(?)"
- }
- $m add command -label $str \
- -font $ffont \
- -command "menu_help $label";
-
- if {$str == ""} {
- $m entryconfigure end -state disabled
- }
- set arg "$m,$i"
-#puts "helplabel: $arg -> $label"
- set helplabel($arg) $label
- set j [$m index end]
- set arg "$m,$j"
- set helplabel($arg) $label
- }
- if {$i == 0} {
- $m entryconfigure end -columnbreak 1
- }
- }
-
- menu_bindings $m
-}
-
-proc make_menu_items {} {
- global template
- global menu_b menu_m menu_count
- global item_opts item_bool item_case item_menu item_entry menu_var unset_str
- global item_cascade
- global bfont ffont beginner_mode simple_gui_created
- global helptext helpremote helplabel
-
- # some tweaks...
- if {![info exists menu_var(deny)]} {
- set menu_var(deny) 0
- }
-
- set case "";
- set L_casc ""
- set L_casc_count 0
- set L_menus [list]
-
- # Extract the menu items:
- foreach line [split $template "\n"] {
- if {[regexp {^Row:} $line]} {
- continue
- }
- if {[regexp {^[A-z]} $line]} {
- set case [string trim $line]
-
- if {$simple_gui_created} {
- set i0 0
- #if {$case == "Misc"} { # kludge for simple_gui
- # set i0 1
- #}
- catch {$menu_m($case) delete $i0 end}
- }
- set menu_count($case) 0
- continue;
- }
-
- set item [string trim $line]
- regsub -all { *} $item " " item
- if {$item == ""} {
- continue;
- }
- set opts ""
- if {[regexp {^=} $item]} {
- set opts [lindex [split $item] 0]
- regsub {^=} $opts "" opts
- set item [lindex [split $item] 1]
- }
- if {[regexp {^0} $opts]} {
- continue;
- }
- if {[regexp {:$} $item]} {
- set bool 0
- } else {
- set bool 1
- }
- regsub {:$} $item {} item
-
- if {$item == "LOFF"} {
- set L_casc ""
- continue
- }
-
- if {$item == "-- D"} {
- set beginner_sep 1
- set item "--"
- } else {
- set beginner_sep 0
- }
-
- set item_opts($item) $opts
- set item_case($item) $case
- set item_bool($item) $bool
- set item_cascade($item) ""
-
- if {$L_casc == ""} {
- set item_entry($item) $menu_count($case)
- set m $menu_m($case)
- } else {
- # hack for cascades for crowded menus. See =GAL opts.
- set item_entry($item) $L_casc_count
- set m $L_casc
- }
-
- set mvar 0
-
- if {$beginner_mode && ! $beginner_sep && ![opt_match D $item]} {
- set item_entry($item) "-1"
- continue;
- }
-
- set item_menu($item) $m
-
- if {0} { puts "ITEM: $item\t- $opts\t- $case\t- \
- $bool\t- $menu_count($case)" }
-
- # Create the menu items, its variables, etc., etc.
-
- if {$item == "--"} {
- $m add separator
-
- } elseif {$item == "Quit"} {
- # Quit item must shut us down:
- $m add command -label "$item" -underline 0 \
- -font $ffont \
- -command {destroy .; exit 0}
-
- } elseif {$case == "Help"} {
- # Help is simple help:
- $m add command -label "$item" \
- -font $ffont \
- -command "menu_help $item"
-
- } elseif {[opt_match L $item]} {
- # Special sub-menu cascade (=GAL ends with LOFF)
- set subm $m.casc_L$menu_count($case)
- catch {destroy $subm}
- menu $subm -tearoff 0 -font $ffont
- set item_cascade($item) $subm
- $m add cascade -label "$item" \
- -font $ffont \
- -menu $subm
- set L_casc $subm
- set L_casc_count -1
- lappend L_menus $L_casc
-
- } elseif {$item == "current"} {
- # Current clients cascade
- set subm $m.current_cascade
- catch {destroy $subm}
- set item_cascade($item) $subm
- update_clients_menu "INIT"
- $m add cascade -label "$item" \
- -font $ffont \
- -menu $subm
-
- } elseif {[is_action $item]} {
- # Action
- $m add command -label "$item" \
- -font $ffont \
- -command "do_var $item"
- if {![info exists menu_var($item)]} {
- set menu_var($item) ""; # for convenience
- }
-
- } elseif {! $item_bool($item)} {
- # String
- if {[regexp -- {-C:(.*)} $item_opts($item) m0 m1]} {
- # Radiobutton select
- set subm $m.radio_cascade$menu_count($case)
- catch {destroy $subm}
- menu $subm -tearoff 0 -font $ffont
- foreach val [split $m1 ","] {
- $subm add radiobutton -label "$val" \
- -command "do_var $item" \
- -value "$val" \
- -font $ffont \
- -variable menu_var($item)
- }
- $m add cascade -label "$item" \
- -font $ffont \
- -menu $subm
- set item_cascade($item) $subm
- } else {
- # Arbitrary_string
- $m add command -label "$item" \
- -font $ffont \
- -command "do_var $item"
- }
- set mvar 1
-
- } elseif {$item == "simple-gui"} {
- $m add checkbutton -label "$item" \
- -command "toggle_simple_gui" \
- -font $ffont \
- -variable beginner_mode
- } else {
- # Boolean
- $m add checkbutton -label "$item" \
- -command "do_var $item" \
- -font $ffont \
- -variable menu_var($item)
- if {![info exists menu_var($item)]} {
- set menu_var($item) 0
- }
- }
-
- if {$L_casc_count == -1} {
- incr menu_count($case)
- incr L_casc_count
- } elseif {$L_casc != ""} {
- incr L_casc_count
- } else {
- incr menu_count($case)
- }
-
- if {$mvar} {
- if {![info exists menu_var($item)]} {
- set menu_var($item) $unset_str
- }
- }
- }
-
- # Now make the little "(?)" help buttons
- global osname
- foreach case [array names menu_m] {
- if {$case == "Help"} {
- continue;
- }
- little_qs $menu_m($case);
- }
- foreach m $L_menus {
- little_qs $m
- }
-}
-
-proc check_update_vars {} {
- global last_query_all_time query_all_freq icon_mode
- global connected_to_x11vnc client_tail client_sock
-
- set now [clock seconds]
-
- set delay $query_all_freq
- if {$client_tail != "" && $client_sock == ""} {
- set delay [expr 2 * $query_all_freq]
- }
-
- if {$connected_to_x11vnc} {
- set quiet 0
- set refresh [expr "$last_query_all_time + $delay"]
-
- # puts "menu_posted $now $last_query_all_time"
- # puts "menu_posted $refresh"
-
- if {$now > $refresh} {
- append_text "Refreshing current settings... "
- query_all $quiet
- if {$quiet} {
- append_text "done\n"
- }
- }
- }
-}
-
-proc menu_posted {} {
- check_update_vars
-}
-
-proc props_widgets {state} {
- global props_buttons
- foreach w $props_buttons {
- $w configure -state $state
- }
- update
-}
-
-proc props_apply {} {
- global props_accept props_confirm props_viewonly props_shared
- global props_zeroconf props_javaview props_solid
- global props_passwd props_viewpasswd
- global prop0_accept prop0_confirm prop0_viewonly prop0_shared
- global prop0_zeroconf prop0_javaview prop0_solid
- global prop0_passwd prop0_viewpasswd
- global menu_var
- global client_sock
-
- props_widgets disabled
-
- set aft 500
- if {[info exists client_sock]} {
- if {$client_sock != ""} {
- set aft 150
- }
- }
- set did 0
-
- set fail 0
-
- if {$props_confirm != $prop0_confirm} {
- if {$did > 0} {after $aft}; incr did
- if {$props_confirm} {
- push_new_value "accept" "accept" "popup" 1
- } else {
- push_new_value "accept" "accept" "" 1
- }
- if {$menu_var(accept) == "popup"} {
- set props_confirm 1
- } elseif {$menu_var(accept) == ""} {
- set props_confirm 0
- }
- if {$props_confirm == $prop0_confirm} {incr fail}
- set prop0_confirm $props_confirm
- }
-
- if {$props_viewonly != $prop0_viewonly} {
- if {$did > 0} {after $aft}; incr did
- if {$props_viewonly} {
- push_new_value "viewonly" "viewonly" 1 1
- } else {
- push_new_value "viewonly" "noviewonly" 1 1
- }
- if {$menu_var(viewonly)} {
- set props_viewonly 1
- } else {
- set props_viewonly 0
- }
- if {$props_viewonly == $prop0_viewonly} {incr fail}
- set prop0_viewonly $props_viewonly
- }
-
- if {$props_shared != $prop0_shared} {
- if {$did > 0} {after $aft}; incr did
- if {$props_shared} {
- push_new_value "shared" "shared" 1 1
- } else {
- push_new_value "shared" "noshared" 1 1
- }
- if {$menu_var(shared)} {
- set props_shared 1
- } else {
- set props_shared 0
- }
- if {$props_shared == $prop0_shared} {incr fail}
- set prop0_shared $props_shared
- }
-
- if {$props_zeroconf != $prop0_zeroconf} {
- if {$did > 0} {after $aft}; incr did
- if {$props_zeroconf} {
- push_new_value "zeroconf" "zeroconf" 1 1
- } else {
- push_new_value "zeroconf" "nozeroconf" 1 1
- }
- if {$menu_var(zeroconf)} {
- set props_zeroconf 1
- } else {
- set props_zeroconf 0
- }
- if {$props_zeroconf == $prop0_zeroconf} {incr fail}
- set prop0_zeroconf $props_zeroconf
- }
-
- if {$props_javaview != $prop0_javaview} {
- if {$did > 0} {after $aft}; incr did
- if {$props_javaview} {
- push_new_value "http" "http" 1 1
- } else {
- push_new_value "http" "nohttp" 1 1
- }
- if {$menu_var(http)} {
- set props_javaview 1
- } else {
- set props_javaview 0
- }
- if {$props_javaview == $prop0_javaview} {incr fail}
- set prop0_javaview $props_javaview
- }
-
- if {$props_solid != $prop0_solid} {
- if {$did > 0} {after $aft}; incr did
- if {$props_solid} {
- push_new_value "solid" "solid" 1 1
- } else {
- push_new_value "solid" "nosolid" 1 1
- }
- if {$menu_var(solid)} {
- set props_solid 1
- } else {
- set props_solid 0
- }
- if {$props_solid == $prop0_solid} {incr fail}
- set prop0_solid $props_solid
- }
-
- set fpw 0
- if {$props_passwd != $prop0_passwd} {
- set fpw 1
- }
- set vpw 0
- if {$props_viewpasswd != $prop0_viewpasswd} {
- set vpw 1
- }
-
- set pw_ord [list]
- if {!$fpw && !$vpw } {
- # neither change
- ;
- } elseif {$fpw && !$vpw} {
- # full password change
- if {$props_passwd == ""} {
- if {$prop0_viewpasswd != ""} {
- # set view to "" as well and first
- set props_viewpasswd ""
- set pw_ord [list vpw fpw]
- } else {
- set pw_ord [list fpw]
- }
- } else {
- # assume view state OK
- set pw_ord [list fpw]
- }
-
- } elseif {!$fpw && $vpw} {
- # view password change
- if {$props_viewpasswd == ""} {
- # assume full state OK
- set pw_ord [list vpw]
- } else {
- if {$prop0_passwd == ""} {
- # could be trouble, x11vnc makes random
- # full passwd...
- set pw_ord [list vpw]
- } else {
- # OK, full non-null.
- set pw_ord [list vpw]
- }
- }
- } elseif {$fpw && $vpw} {
- # both full and view password change
- if {$props_passwd == "" && $props_viewpasswd == ""} {
- # OK, do view first
- set pw_ord [list vpw fpw]
- } elseif {$props_passwd == "" && $props_viewpasswd != ""} {
- # Not good, do view first anyway x11vnc will fix.
- set pw_ord [list vpw fpw]
- } elseif {$props_passwd != "" && $props_viewpasswd == ""} {
- # OK, view first
- set pw_ord [list vpw fpw]
- } elseif {$props_passwd != "" && $props_viewpasswd != ""} {
- # OK, full first
- set pw_ord [list fpw vpw]
- }
- }
-
- foreach case $pw_ord {
- if {$case == "fpw"} {
- if {$did > 0} {after $aft}; incr did
- push_new_value "passwd" "passwd" "$props_passwd" 1
- if {$props_passwd == $prop0_passwd} {incr fail}
- set prop0_passwd $props_passwd
- }
- if {$case == "vpw"} {
- if {$did > 0} {after $aft}; incr did
- push_new_value "viewpasswd" "viewpasswd" "$props_viewpasswd" 1
- if {$props_viewpasswd == $prop0_viewpasswd} {incr fail}
- set prop0_viewpasswd $props_viewpasswd
- }
- }
-
- if {$props_accept != $prop0_accept} {
- if {$did > 0} {after $aft}; incr did
- if {$props_accept} {
- push_new_value "unlock" "unlock" 1 0
- } else {
- push_new_value "lock" "lock" 1 0
- }
- if {$props_accept == $prop0_accept} {incr fail}
- set prop0_accept $props_accept
- }
-
- props_widgets normal
- if {$fail > 0} {
- return 0
- } else {
- return 1
- }
-}
-
-proc props_advanced {} {
- global icon_mode props_win full_win
- global props_advanced_first
-
- if ![info exists props_advanced_first] {
- center_win $full_win
- set props_advanced_first 1
- set first 1
- } else {
- set first 0
- }
- update
- wm deiconify $full_win
- update
-
- if {$first} {
- set w $full_win
- wm minsize $w [winfo width $w] [winfo height $w]
- }
- push_new_value "remote-cmd" "remote-cmd" "Q:clients" 1
-}
-
-proc do_props {} {
- global props_accept props_confirm props_viewonly props_shared
- global props_zeroconf props_javaview props_solid
- global props_passwd props_viewpasswd
- global prop0_accept prop0_confirm prop0_viewonly prop0_shared
- global prop0_zeroconf prop0_javaview prop0_solid
- global prop0_passwd prop0_viewpasswd
- global menu_var unset_str
- global have_labelframes ffont bfont
- global props_buttons icon_noadvanced
- global icon_mode icon_mode_at_startup
- global screen_height screen_width
- global do_props_msg
-
- set msg ""
- if {[info exists do_props_msg]} {
- set msg $do_props_msg
- }
-
- check_update_vars
-
- set pady 0.5m
- set pady 0.3m
- if {$screen_height <= 360} {
- set pady 0m
- }
-
- if [info exists menu_var(deny)] {
- if {$menu_var(deny) == $unset_str || $menu_var(deny) == 0} {
- set props_accept 1
- } else {
- set props_accept 0
- }
- } else {
- set menu_var(deny) 0
- set props_accept 1
- }
- set prop0_accept $props_accept
-
- if [info exists menu_var(accept)] {
- if {$menu_var(accept) == $unset_str || $menu_var(accept) == ""} {
- set props_confirm 0
- } else {
- set props_confirm 1
- }
- } else {
- set menu_var(accept) ""
- set props_confirm 0
- }
- set prop0_confirm $props_confirm
-
- if [info exists menu_var(viewonly)] {
- if {$menu_var(viewonly) == $unset_str || $menu_var(viewonly) == ""} {
- set props_viewonly 0
- } elseif ($menu_var(viewonly)) {
- set props_viewonly 1
- } else {
- set props_viewonly 0
- }
- } else {
- set menu_var(viewonly) 0
- set props_viewonly 0
- }
- set prop0_viewonly $props_viewonly
-
- if [info exists menu_var(shared)] {
- if {$menu_var(shared) == $unset_str || $menu_var(shared) == ""} {
- set props_shared 0
- } elseif ($menu_var(shared)) {
- set props_shared 1
- } else {
- set props_shared 0
- }
- } else {
- set menu_var(shared) 0
- set props_shared 0
- }
- set prop0_shared $props_shared
-
- if [info exists menu_var(zeroconf)] {
- if {$menu_var(zeroconf) == $unset_str || $menu_var(zeroconf) == ""} {
- set props_zeroconf 0
- } elseif ($menu_var(zeroconf)) {
- set props_zeroconf 1
- } else {
- set props_zeroconf 0
- }
- } else {
- set menu_var(zeroconf) 0
- set props_zeroconf 0
- }
- set prop0_zeroconf $props_zeroconf
-
- if [info exists menu_var(http)] {
- if {$menu_var(http) == $unset_str || $menu_var(http) == ""} {
- set props_javaview 0
- } elseif ($menu_var(http)) {
- set props_javaview 1
- } else {
- set props_javaview 0
- }
- } else {
- set menu_var(http) 0
- set props_javaview 0
- }
- set prop0_javaview $props_javaview
-
- if [info exists menu_var(solid)] {
- if {$menu_var(solid) == $unset_str || $menu_var(solid) == ""} {
- set props_solid 0
- } elseif ($menu_var(solid)) {
- set props_solid 1
- } else {
- set props_solid 0
- }
- } else {
- set menu_var(solid) 0
- set props_solid 0
- }
- set prop0_solid $props_solid
-
- if ![info exists props_passwd] {
- set props_passwd ""
- }
- set prop0_passwd $props_passwd
-
- if ![info exists props_viewpasswd] {
- set props_viewpasswd ""
- }
- set prop0_viewpasswd $props_viewpasswd
-
- if [info exists props_buttons] {
- catch {unset props_buttons}
- }
- set props_buttons [list]
-
- set wp .props
- set w $wp
- catch {destroy $wp}
- toplevel $wp
- wm title $wp "x11vnc Properties"
- frame $w.lf
- set w $w.lf
- set b1 "$w.buttons1"
- frame $b1
- button $b1.ok -text OK -command "if {\[props_apply\]} {destroy $wp}" -font $bfont
- button $b1.cancel -text Cancel -command "destroy $wp" -font $bfont
- button $b1.apply -text Apply -command "props_apply" -font $bfont
-
- bind $w <KeyPress-Escape> "destroy $wp"
-
- pack $b1.ok $b1.cancel $b1.apply -side left -expand 0
- lappend props_buttons $b1.apply $b1.cancel $b1.ok
-
- set b2 "$w.buttons2"
- frame $b2
-
- button $b2.advanced -text " Advanced ... " \
- -command "destroy $wp; props_advanced" -font $bfont
- if {! $icon_noadvanced} {
- lappend props_buttons $b2.advanced
- pack $b2.advanced -side left -expand 0
- }
-
- button $b2.help -text " Help " -command "menu_help Properties" -font $bfont
- lappend props_buttons $b2.help
- pack $b2.help -side left -expand 0
-
- set pw "$w.passwd"
- if {$have_labelframes} {
- labelframe $pw -text "Password" -font $bfont
- } else {
- frame $pw
- set l $pw.l
- label $l -text "Password:" -justify left -anchor w -font $bfont
- pack $pw.l -fill x -expand 1 -padx 1m -pady 0m -side top
- }
- entry $pw.e -show "*" -textvariable props_passwd -font $bfont
- pack $pw.e -fill x -expand 1 -padx 1m -pady $pady -side top
-
- global x11vnc_icon_mode
- if {! $x11vnc_icon_mode} {
- catch { $pw.e configure -state disabled}
- if {! $have_labelframes} {
- catch { $pw.l configure -state disabled}
- }
- } else {
- lappend props_buttons $pw.e
- }
-
-
- set vp "$w.viewpw"
- if {$have_labelframes} {
- labelframe $vp -text "ViewOnly Password" -font $bfont
- } else {
- frame $vp
- set l $vp.l
- label $l -text "ViewOnly Password:" -justify left -anchor w -font $bfont
- pack $vp.l -fill x -expand 1 -padx 1m -pady 0m -side top
- }
- entry $vp.e -show "*" -textvariable props_viewpasswd -font $bfont
- pack $vp.e -fill x -expand 1 -padx 1m -pady $pady -side top
-
- if {! $x11vnc_icon_mode} {
- catch { $vp.e configure -state disabled}
- if {! $have_labelframes} {
- catch { $vp.l configure -state disabled}
- }
- } else {
- lappend props_buttons $vp.e
- }
-
- if {! $icon_mode_at_startup} {
- $vp.e configure -state disabled
- catch {$vp.l configure -state disabled}
- catch {$vp configure -state disabled}
- catch {$vp configure -foreground grey60}
- $pw.e configure -state disabled
- catch {$pw.l configure -state disabled}
- catch {$pw configure -state disabled}
- catch {$pw configure -foreground grey60}
- }
-
- set sb "$w.solid"
- frame $sb
- checkbutton $sb.button -text "Solid Background Color" \
- -variable props_solid -anchor w -font $bfont
- pack $sb.button -fill x -expand 1 -padx 1m -pady $pady
-
- set jv "$w.javaview"
- frame $jv
- checkbutton $jv.button -text "Serve Java Viewer Applet" \
- -variable props_javaview -anchor w -font $bfont
- pack $jv.button -fill x -expand 1 -padx 1m -pady $pady
-
- set zc "$w.zeroconf"
- frame $zc
- checkbutton $zc.button -text "Advertise Service (Zeroconf)" \
- -variable props_zeroconf -anchor w -font $bfont
- pack $zc.button -fill x -expand 1 -padx 1m -pady $pady
-
- set sh "$w.shared"
- frame $sh
- checkbutton $sh.button -text "Shared" \
- -variable props_shared -anchor w -font $bfont
- pack $sh.button -fill x -expand 1 -padx 1m -pady $pady
-
- set vo "$w.viewonly"
- frame $vo
- checkbutton $vo.button -text "All Clients ViewOnly" \
- -variable props_viewonly -anchor w -font $bfont
- pack $vo.button -fill x -expand 1 -padx 1m -pady $pady
-
- set cf "$w.confirm"
- frame $cf
- checkbutton $cf.button -text "Ask for Confirmation" \
- -variable props_confirm -anchor w -font $bfont
- pack $cf.button -fill x -expand 1 -padx 1m -pady $pady
-
- set ac "$w.accept"
- frame $ac
- checkbutton $ac.button -text "Accept Connections" \
- -variable props_accept -anchor w -font $bfont
- pack $ac.button -fill x -expand 1 -padx 1m -pady $pady
-
- set px "6m"
- pack $b1 -side bottom -fill x -pady $pady -padx $px
- pack $b2 -side bottom -fill x -pady $pady -padx $px
- pack $vp -side bottom -fill x -pady $pady -padx $px
- pack $pw -side bottom -fill x -pady $pady -padx $px
- pack $sb -side bottom -fill x -pady 0m -padx $px
- pack $jv -side bottom -fill x -pady 0m -padx $px
- pack $zc -side bottom -fill x -pady 0m -padx $px
- pack $sh -side bottom -fill x -pady 0m -padx $px
- pack $vo -side bottom -fill x -pady 0m -padx $px
- pack $cf -side bottom -fill x -pady 0m -padx $px
- pack $ac -side bottom -fill x -pady 0m -padx $px
-
- global show_props_instructions
- if {![info exists show_props_instructions]} {
- set show_props_instructions 1
- }
-
- wm withdraw .props
-
- set wl $w
-
- pack $wl -side left
-
- if {$msg != ""} {
- set tw [textwidth $msg]
- set th [textheight $msg]
- set th [expr $th - 1]
- set ms ".props.msg"
- text $ms -font $ffont -relief ridge -width $tw -height $th
- $ms insert 1.0 $msg
-
- set si "$wl.instructions"
- frame $si
- checkbutton $si.button -text "Show Instructions" \
- -variable show_props_instructions -anchor w -font $bfont \
- -command "toggle_instructions $ms $pady $px"
-
- pack $si.button -fill x -expand 1 -padx 1m -pady $pady
- pack $si -side bottom -fill x -pady 0m -padx $px
-
- if {$show_props_instructions} {
- pack $ms -side left -fill both
- }
-
- update
- }
-
-
- lappend props_buttons $ac.button $cf.button $vo.button $sh.button $zc.button $jv.button $sb.button
-
-
- set w .props
- update
- wm resizable $w 1 0
- center_win $w
- update
-
- #wm minsize $w [winfo width $w] [winfo height $w]
-
- tkwait window $w
- set show_props_instructions 0
-}
-
-proc toggle_instructions {ms pady px} {
- global show_props_instructions
- if {$show_props_instructions} {
- pack $ms -side left -fill both
- } else {
- pack forget $ms
- }
- catch {pack .props}
- update
-}
-
-proc do_new_client {} {
- global newclient ffont bfont
-
- set w .newclient
- catch {destroy $w}
- toplevel $w
- label $w.l -text "Hostname: " -font $bfont
- set newclient ""
- entry $w.e -width 16 -textvariable newclient -font $bfont
- button $w.b -text OK -command "destroy $w" -font $bfont
- button $w.h -text Help -command "menu_help NewClient" -font $bfont
- bind $w.e <Return> "update; after 100; destroy $w"
-
- wm title $w "New Client"
-
- pack $w.l $w.e $w.h $w.b -side left -pady 1m -padx 0.5m
- focus $w.e
- center_win $w
- update
-
- tkwait window $w
-
- regsub -all {[{}()~!$&*|;'"`{}<>\[\]]} $newclient "" newclient
- #'
- if {$newclient != ""} {
- push_new_value "connect" "connect" "$newclient" 1
- }
-}
-
-proc do_disconnect_all {} {
- push_new_value "disconnect" "disconnect" "all" 1
-}
-
-proc do_disconnect_client {id} {
- push_new_value "disconnect" "disconnect" "$id" 1
-}
-
-proc popup_post {m} {
- global popup_cascade_posted client_balloon
- global client_id_list
-
- set popup_cascade_posted 0
-
- set wd "$m.disconnect"
-
- if {![winfo exists $wd]} {
- return
- }
-
- catch {$wd delete 0 end}
-
- $wd add command -label "Disconnect client:"
- $wd add separator
- $wd add command -label "All Clients" -command do_disconnect_all
-
- if {![info exists client_id_list]} {
- return
- }
-
- foreach client $client_id_list {
- if {$client == ""} {
- continue
- }
- if {[regexp {^([^:]*):(.*)$} $client mat id lab]} {
- set nid [expr "$id + 0"]
- $wd add command -label "$nid $lab" \
- -command "do_disconnect_client $id"
- }
- }
-}
-
-proc pmenu {m x y} {
- if {![winfo exists $m]} {
- return
- }
- set x [expr $x-10]
- set y [expr $y-10]
- $m post $x $y
- # XXX more care needed
- grab set -global $m
-}
-
-proc set_client_balloon {str} {
- global client_balloon vnc_display
- global client_id_list
-
- set client_id_list [list]
-
- set client_balloon "$vnc_display"
- set count 0
- regsub -all {^.*aro=clients:} $str "" str
- regsub -all {aro=.*$} $str "" str
- regsub -all {ans=.*$} $str "" str
- foreach client [split $str ","] {
- #puts "client: $client"
- if [regexp {^[ ]*$} $client] {
- continue
- }
- if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \
- $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {
- set id $m1
- set nid [expr "$m1 + 0"]
- set ip $m2
- set port $m3
- set user $m4
- set unix $m5
- if {[string length $user] >= 24} {
- # weird identd hash...
- set user [string range $user 0 8]
- set user "${user}..."
- }
- if {$unix != "" && $unix != "none"} {
- set user $unix
- }
- set host $m6
- set input $m7
- set vo $m8
- set ltime $m9
- if [regexp {^[ ]*$} $host] {
- set host $ip
- }
- set client_balloon "${client_balloon}\n$nid $user\@$host"
- if {$vo == "1"} {
- set client_balloon "${client_balloon} - view"
- lappend client_id_list "$id:$user\@$host - view"
- } else {
- set client_balloon "${client_balloon} - full"
- lappend client_id_list "$id:$user\@$host - full"
- }
- } else {
- set i [expr $count+1]
- if {$i == 1} {
- set client_balloon "${client_balloon}\nunknown-host$i"
- }
- }
- incr count
- }
- if {$count == 0} {
- set client_balloon "${client_balloon}\nNo connections."
- }
- icon_win_cfg $count
-}
-
-proc read_client_info {channel} {
- global x11vnc_client_file client_str client_info_read
- global read_client_info_lock
- global read_clients
- set db 0
-
- set read_clients 0
-
- if {![info exists read_client_info_lock]} {
- set read_client_info_lock 0
- }
-
- if {$channel != ""} {
-
- if {$read_client_info_lock} {
- return
- }
- set read_client_info_lock 1
- after 100
- set str ""
- set count [gets $channel str]
- if {$db} {puts stderr "read_client_info-$channel: $str"}
-
- if {$count == -1 || [eof $channel]} {
- close $channel
- catch {file delete $x11vnc_client_file}
- set read_client_info_lock 0
- clean_icon_exit
- }
- if {$count > 0 && ![regexp {^[ ]*$} $str]} {
- set client_info_read 1
- if {$str == "quit"} {
- catch {file delete $x11vnc_client_file}
- set read_client_info_lock 0
- clean_icon_exit
- } elseif {$str == "skip"} {
- ;
- } elseif [regexp {^clients:} $str] {
- regsub {^clients:} $str "" str
- set read_clients 1
- if {$str == "none"} {
- set str ""
- }
- update_clients_menu $str
- set client_str $str
- set_client_balloon $str
- }
- }
- set read_client_info_lock 0
- }
-}
-
-proc check_set_vnc_display {} {
-
- global read_clients check_set_vnc_display_done
-
- if {[info exists check_set_vnc_display_done]} {
- return
- }
- if {[info exists read_clients]} {
- if {$read_clients} {
- after 250
- query_all
- global client_str
- set_client_balloon $client_str
- set check_set_vnc_display_done 1
- }
- }
-}
-
-proc read_client_tail {} {
- global client_tail
-
- if {$client_tail != ""} {
- read_client_info $client_tail
- check_set_vnc_display
- }
-}
-
-proc read_client_sock {} {
- global client_sock
-
- if {$client_sock != ""} {
- read_client_info $client_sock
- check_set_vnc_display
- }
-}
-
-proc show_client_balloon {} {
- global icon_mode icon_win props_win full_win
- global client_balloon ffont connected_to_x11vnc
-
- set noinfo "tkx11vnc: no client information"
- set noinfo "$noinfo\navailable from x11vnc ..."
- if ![info exists client_balloon] {
- set client_balloon $noinfo
- }
- if {$client_balloon == ""} {
- set client_balloon $noinfo
- }
- if {! [info exists icon_win]} {
- return
- } elseif {$icon_win == ""} {
- return
- } elseif {! [winfo exists $icon_win]} {
- return
- }
-
- set x [expr [winfo rootx $icon_win] + ([winfo width $icon_win]/2)]
- set y [expr [winfo rooty $icon_win] + [winfo height $icon_win] + 4]
-
- set infotext $client_balloon
- if {!$connected_to_x11vnc} {
- set infotext "Not currently attached to x11vnc\nLast available info:\n$infotext"
- }
-
- set w .client_balloon
- catch {destroy $w}
- toplevel $w -bg black -screen [winfo screen $icon_win]
- wm overrideredirect $w 1
- label $w.l -text "$infotext" -relief flat -bg "#ffffaa" -fg black \
- -padx 2 -pady 0 -anchor w -justify left -font $ffont
- pack $w.l -side left -padx 1 -pady 1
-
- set w2 [winfo reqwidth $w.l]
- set h2 [winfo reqheight $w.l]
-
- set W [winfo screenwidth $w]
- set H [winfo screenheight $w]
-
- if {[expr $x+$w2] > $W} {
- set w3 [winfo width $icon_win]
- set x [expr "$W - $w2 - $w3 - 4"]
- }
- if {[expr $y+$h2] > $H} {
- set h3 [winfo height $icon_win]
- set y [expr "$H - $h2 - $h3 - 4"]
- }
-
- wm geometry $w +${x}+${y}
-}
-
-proc kill_client_balloon {} {
- global client_balloon_id client_balloon_win
- if [info exists client_balloon_id] {
- catch {after cancel $client_balloon_id}
- }
- if [winfo exists .client_balloon] {
- destroy .client_balloon
- }
-}
-
-proc icon_win_cfg {clients} {
- global icon_win client_tail client_sock client_info_read
-
- if {! [info exists icon_win]} {
- return
- } elseif {$icon_win == ""} {
- return
- } elseif {! [winfo exists $icon_win]} {
- return
- }
- if {$clients > 0} {
- $icon_win configure -bg black -fg white
- } else {
- $icon_win configure -bg white -fg black
- }
-
- if {$client_tail == "" || !$client_info_read} {
- if {$client_sock == ""} {
- $icon_win configure -fg red
- }
- }
-}
-
-proc server_accept {sock addr port} {
- global socket_cookie server socket_got_callback
- global client_tail client_sock
- set db 0
-
- if {$db} {puts stderr "sock=$sock addr=$addr port=$port"}
-
- update; update idletasks
- after 50
- update; update idletasks
- set count [gets $sock str]
-
- if {$count >= 0} {
- set str [string trim $str]
- if {$db} {puts stderr "server_accept: \"$str\""}
- if {$str == "COOKIE:$socket_cookie"} {
- set client_sock $sock
- if {$db} {puts stderr "cookie matched. $client_sock"}
- } else {
- if {$db} {puts stderr "cookie NO matched."}
- }
- }
- catch {close $server}
- set socket_got_callback 1
- if {$db} {puts stderr "socket_got_callback $socket_got_callback"}
-}
-
-proc try_client_info_sock {} {
- global socket_cookie server socket_got_callback
- global x11vnc_started x11vnc_xdisplay hostname client_sock
- global x11vnc_xdisplay0 menu_var
-
- set db 0
-#dtime t1
- set start 13037
- set tries 100
- set socket_got_callback 0
-
- set xd $x11vnc_xdisplay
- if {$xd == "" && $x11vnc_xdisplay0 != ""} {
- set xd $x11vnc_xdisplay0
- }
- if {$xd == "" && [info exists menu_var(display)]} {
- set xd $menu_var(display)
- }
-
- set myaddr ""
- regsub {\..*$} $hostname "" shost
- if {$x11vnc_started} {
- set myaddr "127.0.0.1"
- } elseif {$xd != ""} {
- if {[regexp {^:} $xd]} {
- set myaddr "127.0.0.1"
- } elseif {[regexp -nocase "^$shost" $xd]} {
- set myaddr "127.0.0.1"
- } elseif {[regexp -nocase "^localhost" $xd]} {
- set myaddr "127.0.0.1"
- } else {
- set myaddr $hostname
- }
- } else {
- set myaddr $hostname
- }
-
- for {set i 0} {$i <= $tries} {incr i} {
- set port [expr $start + $i]
- set server [socket -server server_accept -myaddr $myaddr $port]
- if {$server == ""} {
- continue
- }
- if {[eof $server]} {
- continue
- }
- set err ""
- catch {set err [fconfigure $server -error]}
- #puts "err: $server: $err"
- if {$err == ""} {
- break
- }
- }
- if {$server == ""} {
- append_text "try_client_info_sock: server socket failed.\n"
- return
- }
- if {! $x11vnc_started} {
- run_remote_cmd [list "-nosync" "-R" "noop"]
- if {$db} {dtime A}
- after 250
- if {$db} {dtime A}
- }
-
- # set the cookie to some obscured randomness
- set socket_cookie [clock clicks]
- set r [expr rand()]
- if {$r != ""} {
- append socket_cookie $r
- }
- set r ""
- catch {set r [winfo id .]}
- if {$r != ""} {
- append socket_cookie $r
- }
- if {[regexp {([0-9])([0-9])$} [clock clicks] m m1 m2]} {
- regsub -all {\.} $socket_cookie $m1 socket_cookie
- regsub -all {x} $socket_cookie $m2 socket_cookie
- }
- run_remote_cmd [list "-nosync" "-R" \
- "client_info_sock:$myaddr:$port:$socket_cookie"]
-#dtime t2
- if {$db} {puts "client_info_sock:$myaddr:$port:$socket_cookie"}
- for {set i 0} {$i < 10} {incr i} {
- after 50
- update; update idletasks
-#dtime aa
- if {$socket_got_callback != 0} {
-#puts "break-"
- break
- }
- }
-#dtime t3
-
- set aftid ""
- if {$socket_got_callback == 0} {
- set aftid [after 10000 {set socket_got_callback 2}]
- tkwait variable socket_got_callback
- }
-
- if {$aftid != ""} {
- catch {after cancel $aftid}
- }
-
- if {$socket_got_callback != 1} {
- puts stderr "try_client_info_sock failed: no callback\n"
- catch {close $server}
- } else {
- setup_client_sock 1
- }
-#dtime t4
-}
-
-proc set_icon_label {} {
- global icon_win
-
- set lab [get_icon_label]
-
- if {! [info exists icon_win]} {
- return
- } elseif {$icon_win == ""} {
- return
- } elseif {! [winfo exists $icon_win]} {
- return
- }
-
- if {[info exists icon_win]} {
- $icon_win configure -text $lab
- }
-}
-
-proc get_icon_label {{set 0}} {
- global icon_minimal
-
- set lab0 "x11\nvnc"
-
- if {$icon_minimal} {
- set lab [get_vnc_display_number]
- if {$lab != "none"} {
- #set lab " :$lab"
- set lab ":$lab"
- } else {
- set lab "-"
- }
- } else {
- set lab $lab0
- }
- return $lab
-}
-
-# currently unused
-proc lmenu {menu} {
- global popup_cascade_posted
- global left_iconwin_menu
- set left_iconwin_menu 1
- after 100
- update
- if {!$popup_cascade_posted && $left_iconwin_menu} {
- for {set i 0} {$i < 3} {incr i} {
- after 100
- update
- }
- if {!$popup_cascade_posted && $left_iconwin_menu} {
- $menu unpost
- return
- }
- }
- # kludge for WindowView
- if {$popup_cascade_posted} {
- focus $menu
- }
-}
-
-proc old_balloon {} {
- global client_str saved_clients_str
- set str ""
- if {[info exists client_str]} {
- if {$client_str != ""} {
- set str $client_str
- }
- }
- if {$str == ""} {
- if {[info exists saved_clients_str]} {
- set str $saved_clients_str
- }
- }
- if {$str != ""} {
- set_client_balloon $str
- }
-}
-
-proc get_custom_menu_items {} {
- global env custom_last_read
-
- if {![info exists custom_last_read]} {
- set custom_last_read 0
- }
- if {[info exists env(X11VNC_CUSTOM_GUI)]} {
- set custom "$env(X11VNC_CUSTOM_GUI)"
- } elseif {![info exists env(HOME)]} {
- return [list "none"]
- } else {
- set custom "$env(HOME)/.x11vnc.gui"
- }
- if {![file exists $custom]} {
- return [list "none"]
- }
-
-# if {[file mtime $custom] <= $custom_last_read} {
-# return [list "nochange"]
-# }
-
- set in ""
- catch {set in [open $custom "r"]}
- if {$in == ""} {
- return [list "none"]
- }
-
- set custom_last_read [clock seconds]
-
- set count 0
- while {[gets $in line] > -1} {
- if {[regexp {^[ \t]*#} $line]} {
- continue
- }
- set line [string trim $line]
- if {$line != ""} {
- lappend items $line
- incr count
- }
- }
- close $in
-
- if {$count > 0} {
- return $items
- } else {
- return [list "none"]
- }
-}
-
-proc make_custom_menu {menu font} {
- set items [get_custom_menu_items]
- set i0 [lindex $items 0]
- catch {$menu delete 0 end}
- if {$i0 != "none"} {
- $menu add command -font $font -label "Custom items:"
- $menu add separator
- foreach item $items {
- if {$item == "sep" || $item == "separator"} {
- $menu add separator
- continue
- }
- if {[regexp {^action:(.*)$} $item m action]} {
- $menu add command -font $font -label "$action" \
- -command "do_var $action"
- continue
- }
- $menu add command -font $font -label "$item" \
- -command "run_remote_cmd \[list \"-R\" \"$item\"\]"
- }
- }
-}
-
-proc make_icon {} {
- global icon_mode icon_embed_id icon_win props_win full_win
- global tray_embed tray_running env
- global x11vnc_client_file client_tail client_sock client_str saved_clients_str
- global client_balloon_id
- global bfont sfont snfont ffont
- global icon_minimal gui_start_mode
- global popup_cascade_posted menu_var x11vnc_gui_geom
- set min_x 24
- set min_y 24
-
- set font $bfont
- set mfont $font
-
- if {$tray_embed} {
- set font $sfont
- set mfont $snfont
- }
- if {[info exists env(X11VNC_ICON_FONT)]} {
- set font $env(X11VNC_ICON_FONT)
- }
- if {[regexp {([0-9][0-9]*)x([0-9][0-9]*)} $x11vnc_gui_geom m mx my]} {
- if {$mx < $min_x} {
- set min_x $mx
- }
- if {$my < $min_y} {
- set min_y $my
- }
- }
- wm minsize . $min_x $min_y
-
- if {$tray_embed && $tray_running} {
- wm withdraw .
- }
-
- set l .icon
- set icon_win $l
- catch destroy {$icon_win}
- if {$icon_minimal} {
- set bw 1
- } else {
- set bw 5
- }
- set lab [get_icon_label]
- label $l -text $lab -borderwidth $bw -font $font
- icon_win_cfg 0
-
-
- set popup_cascade_posted 0
- pack $l -fill both -expand 1
- set menu "$l.menu"
- menu $menu -tearoff 0 -postcommand "popup_post $menu"
- $menu add command -font $mfont -label "Properties" -command do_props
- $menu add command -font $mfont -label "Help" -command "menu_help Tray"
- $menu add command -font $mfont -label "Logfile" -command show_logfile
- $menu add separator
- $menu add command -font $mfont -label "New Client" -command do_new_client
-
- set wd "$menu.disconnect"
- catch {destroy $wd}
- menu $wd -tearoff 0 -font $ffont \
- -postcommand {set popup_cascade_posted 1}
- $wd add command -label "Disconnect client:"
- $wd add separator
- $wd add command -label "All Clients" -command do_disconnect_all
- $menu add cascade -font $mfont -label "Disconnect:" -menu $wd
-
- $menu add separator
-
- set wv "$menu.windowview"
- catch {destroy $wv}
- menu $wv -tearoff 0 -font $ffont \
- -postcommand {set popup_cascade_posted 1}
- foreach val {full icon tray} {
- $wv add radiobutton -label "$val" \
- -value "$val" -font $ffont \
- -command "do_var WindowView" \
- -variable menu_var(WindowView)
- }
- $menu add cascade -font $mfont -label "Window View:" -menu $wv
-
- $menu add command -font $mfont -label "Dismiss" -command "$menu unpost"
- $menu add command -font $mfont -label "Stop x11vnc" -command clean_icon_exit
-
- set items [get_custom_menu_items]
- set i0 [lindex $items 0]
- if {$i0 != "none" && $i0 != "nochange"} {
- $menu add separator
- set cm "$menu.custom"
- catch {destroy $cm}
- menu $cm -tearoff 0 -font $ffont \
- -postcommand "set popup_cascade_posted 1; make_custom_menu $cm $ffont"
- $menu add cascade -font $mfont -label "Custom:" -menu $cm
- }
-
- bind $icon_win <ButtonRelease-1> "pmenu $menu %X %Y"
- bind $icon_win <ButtonRelease-3> "pmenu $menu %X %Y"
- bind $icon_win <Enter> {set client_balloon_id [after 500 show_client_balloon]}
- bind $icon_win <Button> {kill_client_balloon}
- bind $icon_win <Leave> {kill_client_balloon}
- bind $icon_win <Shift-ButtonRelease-1> {kill_client_balloon; show_client_balloon}
- bind $icon_win <ButtonRelease-2> {kill_client_balloon; show_client_balloon}
-# bind $menu <Leave> "lmenu $menu"
-# bind $menu <Enter> "set left_iconwin_menu 0"
-# bind $menu <KeyPress-Escape> "$menu unpost"
-
- bind . <Control-KeyPress-c> {destroy .; exit 0}
-
- if {!$tray_embed || !$tray_running} {
- global x11vnc_gui_geom
- if {$x11vnc_gui_geom != ""} {
- set doit 1
- if {[regexp {x} $x11vnc_gui_geom]} {
- if {$gui_start_mode == "full"} {
- set doit 0
- }
- }
- if {$doit} {
- wm geometry . $x11vnc_gui_geom
- }
- }
- }
- wm iconname . "tkx11vnc"
- wm title . "tkx11vnc"
- update
- if {$tray_embed && $tray_running} {
- #wm deiconify .; # why did we have this???
- #after 10000 {wm deiconify .; puts "reqheight [winfo reqheight .]"; puts "reqwidth [winfo reqwidth .]"; puts "height [winfo height .]"; puts "width [winfo width .]"}
- } else {
- wm deiconify .
- }
- update
-
-#puts "reqheight [winfo reqheight .]"
-#puts "reqwidth [winfo reqwidth .]"
-#puts "height [winfo height .]"
-#puts "width [winfo width .]"
-#puts "AAA"
-
- old_balloon
-}
-
-proc setup_client_channel {} {
- global client_sock client_tail
-
-# XXX/setup_client_channel
- if {$client_sock == "" } {
- stop_watch on
- try_client_info_sock
- if {$client_sock == "" } {
- after 500
- try_client_info_sock
- }
- stop_watch off
- }
- if {$client_tail == "" && $client_sock == ""} {
- set m "\n"
- set m "${m}tkx11vnc:\n"
- set m "${m}\n"
- set m "${m} Warning -- running in icon/tray mode but the\n"
- set m "${m} connected client info channel from x11vnc is\n"
- set m "${m} not working. The viewer client list and icon\n"
- set m "${m} color indicator will not be accurate.\n"
- set m "${m}\n"
- set m "${m} You may need to restart \"x11vnc -gui tray ...\"\n"
- set m "${m} for this to work properly.\n"
- set m "${m}\n"
- textwin "Warning" "Warning" $m
- update
- }
- dtime C
-}
-
-proc clean_client_tail {} {
- global client_tail client_info_read
- if [info exists client_tail] {
- if {$client_tail != ""} {
- set p ""
- catch {set p [pid $client_tail]}
- if {$p != ""} {
- catch {exec kill -TERM $p >/dev/null 2>/dev/null}
- }
- catch {close $client_tail}
- set client_tail ""
- }
- }
- set client_info_read 0
-}
-
-proc clean_icon_exit {} {
- clean_client_tail
- push_new_value "stop" "stop" 1 0
- set_connected no
- update
- destroy .
- exit
-}
-
-proc make_gui {mode} {
- global icon_mode tray_embed tray_running full_win icon_win
- global top_widget_names x11vnc_gui_geom
- global gui_current_state make_gui_count
- global x11vnc_connect connected_to_x11vnc
- global x11_display
- global gui_start_mode
-
- incr make_gui_count
-
- if {$gui_start_mode == ""} {
- set gui_start_mode $mode
- }
-
- wm withdraw .
-
- set full_geom ""
- if {[winfo exists .full]} {
- catch {set full_geom [wm geometry .full]}
- }
-
- set fw .full
- set full_win $fw
- catch {pack forget $full_win}
- catch {pack forget $icon_win}
- catch {destroy $full_win}
- catch {destroy $icon_win}
-
- wm minsize . 1 1
-
- set gui_current_state ""
-
- if {$mode == "full"} {
- frame $fw
- set icon_mode 0
-
- wm protocol . WM_DELETE_WINDOW "destroy .; exit"
- make_widgets $fw
-
- set w "."
- wm geometry $w ""
- if {$x11vnc_gui_geom != ""} {
- set doit 1
- if {[regexp {x} $x11vnc_gui_geom]} {
- if {$gui_start_mode != $mode} {
- set doit 0
- }
- }
- if {$doit} {
- wm geometry $w $x11vnc_gui_geom
- }
- }
- pack $fw -fill both -expand 1
-
- } elseif {$mode == "icon" || $mode == "tray"} {
-
- toplevel $fw
- wm withdraw $fw
-
- wm protocol $fw WM_DELETE_WINDOW "wm withdraw .full"
- wm protocol . WM_DELETE_WINDOW "clean_icon_exit"
-
- if {$mode == "icon"} {
- set tray_embed 0
- } elseif {$mode == "tray"} {
- set tray_embed 1
- }
- set icon_mode 1
- make_widgets $fw
- set w $fw
- make_icon
- wm geometry $fw ""
- wm geometry . ""
- } else {
- return
- }
- set_view_variable $mode
- set gui_current_state $mode
-
-
- update
- if {!$tray_embed || !$tray_running} {
- wm deiconify .
- }
- update idletasks
- wm minsize $w [winfo width $w] [winfo height $w]
- if {$mode == "full" && $make_gui_count > 1} {
- center_win .
- }
-
-
- if {$make_gui_count == 1} {
- copy_default_vars
- if {$x11vnc_connect} {
- try_connect_and_query_all
- } else {
- insert_cmdline_vars
- }
- } else {
- set_name "RESTORE"
- }
-
- setup_client_tail
-
- set_widgets
-
- if {$mode == "tray"} {
- setup_tray_embed
- }
-}
-
-proc make_widgets {top} {
- global template make_gui_count
- global menu_b menu_m menu_count
- global item_opts item_bool item_case item_menu item_entry menu_var unset_str
- global item_cascade
- global info_label info_str x11_display vnc_display
- global text_area text_area_str
- global entry_box entry_str entry_set entry_label entry_ok entry_browse
- global entry_help entry_skip
- global bfont ffont beginner_mode
- global helptext helpremote helplabel
- global icon_mode icon_win props_win full_win
- global top_widget_names
- global screen_height screen_width
-
-
- # Make the top label
- set label_width 84
- if {$screen_width <= 400} {
- set label_width 64
- }
- set info_label "$top.info"
- label $info_label -textvariable info_str -bd 2 -relief groove \
- -anchor w -width $label_width -font $ffont
- pack $info_label -side top -fill x -expand 0
-
- set top_widget_names(info) $info_label
-
- # Extract the Rows:
- set row 0;
- set colmax 0;
- foreach line [split $template "\n"] {
- if {[regexp {^Row: (.*)} $line rest]} {
- set col 0
- foreach case [split $rest] {
- if {$case == "" || $case == "Row:"} {
- continue
- }
- set menu_row($case) $row
- set menu_col($case) $col
-
- lappend cases($col) $case;
- set len [string length $case]
- if {[info exists max_len($col)]} {
- if {$len > $max_len($col)} {
- set max_len($col) $len
- }
- } else {
- set max_len($col) $len
- }
- incr col
- if {$col > $colmax} {
- set colmax $col
- }
- }
- incr row;
- }
- }
-
- # Make frames for the rows and make the menu buttons.
- set f "$top.menuframe"
- frame $f
- for {set c 0} {$c < $colmax} {incr c} {
- set colf "$f.menuframe$c"
- frame $colf
- pack $colf -side left -fill y
- set fbg [$colf cget -background]
- foreach case $cases($c) {
- set menub "$colf.menu$case";
- set menu "$colf.menu$case.menu";
- set menu_b($case) $menub
- set menu_m($case) $menu
- set ul 0
- foreach char [split $case ""] {
- set char [string tolower $char]
- if {![info exists underlined($char)]} {
- set underlined($char) 1
- break
- }
- incr ul
- }
- global osname
- set tstr "$case"
- if {$osname == "Darwin"} {
- #set tstr " $case "
- }
- menubutton $menub -text "$tstr" -underline $ul \
- -anchor w -menu $menu -background $fbg \
- -font $bfont
- pack $menub -side top -fill x
- menu $menu -tearoff 0 -postcommand menu_posted
- }
- }
- pack $f -side top -fill x
- set top_widget_names(menuframe) $f
-
- make_menu_items
-
- # Make the x11 and vnc display label bar:
- set df "$top.displayframe"
- frame $df -bd 1 -relief groove
- set top_widget_names(displayframe) $df
-
- set df_x11 "$df.xdisplay"
-
- if {$make_gui_count == 1} {
- no_x11_display
- }
- set lw [expr {$label_width / 2}]
- label $df_x11 -textvariable x11_display -width $lw -anchor w \
- -font $ffont
-
- set df_vnc "$df.vdisplay"
-
- if {$make_gui_count == 1} {
- no_vnc_display
- }
- label $df_vnc -textvariable vnc_display -width $lw -anchor w \
- -font $ffont
-
- pack $df_x11 $df_vnc -side left
- pack $df -side top -fill x
-
- # text area
- global text_height
- set text_area "$top.text"
- if {$screen_width <= 400} {
- text $text_area -height $text_height -width $label_width \
- -relief ridge -font $ffont
- } else {
- text $text_area -height $text_height -relief ridge -font $ffont
- }
- pack $text_area -side top -fill both -expand 1
- set top_widget_names(text) $text_area
-
-
- if {$text_area_str == ""} {
- set str "Click Help -> gui for overview."
- append_text "\n$str\n\n"
- } else {
- append_text $text_area_str
- }
-
- # Make entry box stuff
- set ef "$top.entryframe"
- frame $ef -bd 1 -relief groove
- set top_widget_names(entryframe) $ef
-
- # Entry Label
- set ef_label "$ef.label"
- label $ef_label -textvariable entry_str -anchor w -font $bfont
-
- set entry_str "Set... : "
- set ef_entry "$ef.entry"
- entry $ef_entry -relief sunken -font $ffont
- bind $ef_entry <KeyPress-Return> {set entry_set 1}
- bind $ef_entry <KeyPress-Escape> {set entry_set 0}
-
- set ok_s "OK"
- set cancel_s "Cancel"
- set help_s "Help"
- set browse_s "Browse..."
- global osname
- if {$osname == "Darwin"} {
- set ok_s " OK "
- set cancel_s " Cancel "
- set help_s " Help "
- set browse_s " Browse... "
- }
-
- # Entry OK button
- set bpx "1m"
- set bpy "1"
- set hlt "0"
- set ef_ok "$ef.ok"
- button $ef_ok -text $ok_s -pady $bpy -padx $bpx -command {set entry_set 1} \
- -highlightthickness $hlt \
- -font $bfont
-
- # Entry Skip button
- set ef_skip "$ef.skip"
- button $ef_skip -text $cancel_s -pady $bpy -padx $bpx -command {set entry_set 0} \
- -highlightthickness $hlt \
- -font $bfont
-
- # Entry Help button
- set ef_help "$ef.help"
- button $ef_help -text $help_s -pady $bpy -padx $bpx -command \
- {menu_help $entry_dialog_item} -font $bfont \
- -highlightthickness $hlt
-
- # Entry Browse button
- set ef_browse "$ef.browse"
- button $ef_browse -text $browse_s -pady $bpy -padx $bpx -font $bfont \
- -highlightthickness $hlt \
- -command {entry_insert [tk_getOpenFile]}
-
- pack $ef_label -side left
- pack $ef_entry -side left -fill x -expand 1
- pack $ef_ok -side right
- pack $ef_skip -side right
- pack $ef_help -side right
- pack $ef -side bottom -fill x
-
- set entry_ok $ef_ok
- set entry_skip $ef_skip
- set entry_help $ef_help
- set entry_box $ef_entry
- set entry_browse $ef_browse
- set entry_label $ef_label
- entry_disable
-
-}
-
-proc menu_bindings {m} {
- set db 0
- if {$db} {puts "menu_bindings $m"}
-
- bind $m <<MenuSelect>> {
-#syntax hilite bug \
-MenuSelect>>
- set n [%W index active]
- set db 0
- if {$db} {puts stderr "menu_bindings %W $n"}
- set label " "
- if {$n != "none"} {
- set str %W,$n
- set which ""
-
- if {$db} {puts "menu_bindings $str"}
- if {[info exists helplabel($str)]} {
- set vname [format %%-16s $helplabel($str)]
- set label "Click (?) for help on: $vname"
- set which $helplabel($str)
- }
- if {$which == ""} {
- ;
- } elseif {$which == "passwd" || $which == "viewpasswd"} {
- ;
- } elseif {[is_action $which]} {
- if {[info exists menu_var($which)]
- && $menu_var($which) != ""} {
- set label "$label value: $menu_var($which)"
- } else {
- set label "$label (is action)"
- }
- } elseif {[info exists menu_var($which)]} {
- set label "$label value: $menu_var($which)"
- if {$which == "http"} {
- global vnc_url
- set label "$label URL: $vnc_url"
- }
- }
- }
- set_info $label
- }
-}
-
-proc key_bindings {} {
- global env menus_disabled
- if {[info exists env(USER)] && $env(USER) == "runge"} {
- # quick restart
- bind . <Control-KeyPress-k> {exec $argv0 $argv &; destroy .}
- }
- bind . <Control-KeyPress-p> { \
- global menus_disabled; \
- if {!$menus_disabled} {try_connect_and_query_all} \
- }
- bind . <Control-KeyPress-u> { \
- global menus_disabled; \
- if {!$menus_disabled} {query_all 0} \
- }
- bind . <Control-KeyPress-r> { \
- global menus_disabled; \
- if {!$menus_disabled} {query_all 0} \
- }
- bind . <Control-KeyPress-d> { \
- global menus_disabled; \
- if {!$menus_disabled} {detach_from_display} \
- }
- bind . <Control-KeyPress-a> { \
- global menus_disabled; \
- if {!$menus_disabled} {try_connect_and_query_all} \
- }
-}
-
-proc stop_watch {onoff} {
- global orig_cursor text_area entry_box
-
- set widgets [list .]
- if [info exists text_area] {
- if {$text_area != ""} {
- lappend widgets $text_area
- }
- }
- if [info exists entry_box] {
- if {$entry_box != ""} {
- lappend widgets $entry_box
- }
- }
-
- if {$onoff == "on"} {
- foreach item $widgets {
- if {![winfo exists $item]} {
- continue
- }
- $item config -cursor {watch}
- }
- } else {
- foreach item $widgets {
- if {![winfo exists $item]} {
- continue
- }
- $item config -cursor {}
- }
- }
- update
-}
-
-proc double_check_noremote {} {
- set msg "\n\n"
- append msg "*** WARNING: setting \"noremote\" will disable ALL remote control commands (i.e.\n"
- append msg "*** WARNING: *this* gui will be locked out). Do you really want to do this?\n"
- append msg "*** WARNING: If so, press \"OK\", otherwise press \"Cancel\"\n"
- append msg "\n"
- bell
- return [warning_dialog $msg "noremote"]
-}
-
-proc get_settings_rcfile {} {
- global menu_var default_var unset_str
- global x11vnc_gui_params
-
- set rc_txt ""
-
- set menu_var(gui) $x11vnc_gui_params
-
- foreach item [lsort [array names menu_var]] {
- if {$item == "gui"} {
- ;
- } elseif {![active_when_starting $item]} {
- continue
- } elseif {[is_action $item]} {
- continue
- }
- if {$item == "debug_gui"} {
- continue
- } elseif {$item == "WindowView"} {
- continue
- } elseif {$item == "rc" || $item == "norc"} {
- continue
- } elseif {$item == "loop"} {
- continue
- } elseif {$item == "loopbg"} {
- continue
- }
-
- set def ""
- if {[info exists default_var($item)]} {
- set def $default_var($item)
- }
-
-
- set qst ""
- set hmm "#? "
- if {$item == "display"} {
- set qst $hmm
- } elseif {$item == "desktop"} {
- set qst $hmm
- } elseif {$item == "dontdisconnect"} {
- set qst $hmm
- } elseif {$item == "alwaysshared"} {
- set qst $hmm
- } elseif {$item == "nevershared"} {
- set qst $hmm
- } elseif {$item == "gui"} {
- set qst $hmm
- }
-
- if {![info exists menu_var($item)]} {
- set mv $def
- } else {
- set mv $menu_var($item)
- }
-#puts "item=$item def=$def mv=$mv"
- if {$mv == $unset_str} {
- set mv ""
- }
- set ntab 3
-
- if {$item == "gui" || [value_is_string $item]} {
- set nitem [get_nitem $item]
-
- if {$mv == "" && $def != ""} {
- set qst $hmm
- }
- set n 0
- if {$qst != ""} {
- append rc_txt $qst
- incr n [string length $qst]
- } elseif {$mv == $def} {
- append rc_txt "#d "
- incr n [string length "#d "]
- }
- set mt $mv
- regsub -all {#} $mt {\#} mt
- if {$mt == ""} {
- set mt {""}
- }
- append rc_txt "-$nitem $mt"
-
- if {$mv != $def} {
- set m [string length "-$nitem $mt"]
- incr n $m
- set n [expr $n / 8]
- set c 0
- for {set i $n} {$i <= $ntab} {incr i} {
- append rc_txt "\t"
- incr c
- }
- if {$c == 0} {
- append rc_txt "\t"
- }
- regsub -all {#} $def {\#} def
- if {$def == ""} {
- set def {""}
- }
- append rc_txt "# default: $def"
- }
- append rc_txt "\n"
-
- } elseif {[value_is_bool $item]} {
- set n 0
- if {$qst != ""} {
- append rc_txt $qst
- incr n [string length $qst]
- } elseif {$mv == $def} {
- append rc_txt "#d "
- incr n [string length "#d "]
- }
- if {$def == 1} {
- set dv "on"
- } else {
- set dv "off"
- }
- append rc_txt "-$item"
- set m [string length "-$item"]
- incr n $m
- set n [expr $n / 8]
- for {set i $n} {$i <= $ntab} {incr i} {
- append rc_txt "\t"
- }
- append rc_txt "# default: $dv"
- append rc_txt "\n"
-
- }
- }
- return $rc_txt
-}
-
-proc double_check_start_x11vnc {} {
- global hostname
- set msg [get_start_x11vnc_txt]
- bell
- append msg "\n"
- append msg "*** To run the above command on machine \"$hostname\" (thereby\n"
- append msg "*** starting x11vnc) press \"OK\", otherwise press \"Cancel\".\n"
- return [warning_dialog $msg "start"]
-}
-
-proc get_start_x11vnc_txt {} {
- set cmd [get_start_x11vnc_cmd]
- set str [join $cmd]
- set msg ""
- append msg "\n"
- append msg "==== The command built so far is: ====\n";
- append msg "\n"
- append msg "$str\n"
- return $msg
-}
-
-proc show_start_cmd {} {
- set msg [get_start_x11vnc_txt]
- append_text "$msg\n"
-}
-
-proc get_nitem {item} {
- set nitem $item
- if {$nitem == "screen_blank"} {
- set nitem "sb"
- } elseif {$nitem == "xrandr_mode"} {
- set nitem "xrandr"
- } elseif {$nitem == "unixpw_list"} {
- set nitem "unixpw"
- } elseif {$nitem == "unixpw_nis_list"} {
- set nitem "unixpw_nis"
- } elseif {$nitem == "stunnel_pem"} {
- set nitem "stunnel"
- } elseif {$nitem == "ssl_pem"} {
- set nitem "ssl"
- } elseif {$nitem == "wireframe_mode"} {
- set nitem "wireframe"
- } elseif {$nitem == "solid_color"} {
- set nitem "solid"
- }
- return $nitem
-}
-
-proc get_start_x11vnc_cmd {{show_rc 0}} {
- global cmd_var menu_var default_var unset_str x11vnc_prog
-
- set xterm_cmd "xterm -iconic -geometry 80x35 -title x11vnc-console -e"
-
- set cmd [split $xterm_cmd]
-
- lappend cmd $x11vnc_prog
-
- lappend cmd "-gui"
- lappend cmd "none"
-
- set rc_txt ""
-
- set saw_id 0
-
- foreach item [lsort [array names menu_var]] {
- if {$item == "gui"} {
- continue
- } elseif {![active_when_starting $item]} {
- continue
- } elseif {[is_action $item]} {
- continue
- } elseif {$item == "debug_gui"} {
- continue
- } elseif {$item == "WindowView"} {
- continue
- }
-
- if {$item == "id" || $item == "sid"} {
- set val $menu_var($item);
- if {$val == "0x0" || $val == "root"} {
- continue
- }
- }
- if {$item == "sid" && $saw_id} {
- continue
- }
- if {$item == "id"} {
- set saw_id 1
- } elseif {$item == "httpport" && $menu_var($item) == "0"} {
- continue
- } elseif {$item == "progressive" && $menu_var($item) == "0"} {
- continue
- } elseif {$item == "dontdisconnect" && $menu_var($item) == "-1"} {
- continue
- } elseif {$item == "alwaysshared" && $menu_var($item) == "-1"} {
- continue
- }
-
- if {[value_is_bool $item]} {
- if {[info exists menu_var($item)]} {
- set add 1
- if {[info exists default_var($item)]} {
- if {$menu_var($item) == $default_var($item)} {
- set add 0;
- }
- } elseif {! $menu_var($item)} {
- set add 0
- }
- if {$add} {
- lappend cmd "-$item"
- append rc_txt "-$item\n"
- }
- }
- } elseif {[value_is_string $item]} {
- if {![info exists menu_var($item)]} {
- continue
- }
- if {$menu_var($item) != "" && $menu_var($item) != $unset_str} {
- set add 1
- set nitem [get_nitem $item]
-
- if {[info exists default_var($item)]} {
- if {$menu_var($item) == $default_var($item)} {
- set add 0;
- }
- }
- if {$add} {
- lappend cmd "-$nitem"
- set mv $menu_var($item)
-
- if {[regexp {^~} $mv]} {
- if {$item == "auth" ||
- $item == "rc" ||
- $item == "accept" ||
- $item == "connect" ||
- $item == "allow" ||
- $item == "passwdfile" ||
- $item == "o" ||
- $item == "logfile" ||
- $item == "remap" ||
- $item == "httpdir"} {
- set mv [tilde_expand $mv]
- }
- }
-
- lappend cmd $mv
- set mt $mv
- regsub -all {#} $mt {\#} mt
- append rc_txt "-$nitem $mt\n"
- }
- }
- }
- }
- lappend cmd "2>"
- lappend cmd "/dev/null"
- lappend cmd "&"
-
- if {$show_rc} {
- return $rc_txt
- } else {
- return $cmd
- }
-}
-
-proc start_x11vnc {} {
- global menu_var unset_str
- global x11vnc_prog x11vnc_xdisplay
- global connected_to_x11vnc
-
- if {$connected_to_x11vnc} {
- append_text "\n"
- append_text "WARNING: Still connected to an x11vnc server.\n"
- append_text "WARNING: Use \"stop\" or \"detach\" first.\n"
- return 0
- }
-
- if {![double_check_start_x11vnc]} {
- return
- }
-
- set x11vnc_xdisplay ""
- if {[info exists menu_var(display)]} {
- if {$menu_var(display) != "" && $menu_var(display) != $unset_str} {
- set x11vnc_xdisplay $menu_var(display)
- }
- }
-
- set cmd [get_start_x11vnc_cmd]
-
- set str [join $cmd]
- regsub { -e} $str " -e \\\n " str
-
- if {0} {
- puts "running: $str"
- foreach word $cmd {
- puts " word: $word"
- }
- }
-
- append_text "Starting x11vnc in an iconified xterm with command:\n"
- append_text " $str\n\n"
- catch {[eval exec $cmd]}
- after 500
- try_connect_and_query_all 3
- if {!$connected_to_x11vnc} {
- append_text "\nStarting x11vnc seems to have failed.\n"
- if {[regexp -- {-o } $str] || [regexp -- {-logfile} $str]} {
- append_text "Examine the logfile (Debugging -> show-logfile) for error messages.\n"
- } else {
- append_text "Rerun with a logfile (if needed) and examine the logfile\n"
- append_text "(Debugging -> show-logfile) for error messages.\n"
- }
- }
-}
-
-proc run_remote_cmd_via_sock {opts} {
- global client_sock
-
- set db 0
- if {[file channels $client_sock] == ""} {
- set client_sock ""
- return "fail"
- }
- if {[eof $client_sock]} {
- catch {close $client_sock}
- set client_sock ""
- return "fail"
- }
- set result ""
-
- setup_client_sock 0
-
- set docmd ""
- foreach opt $opts {
- if {$opt == "-R"} {
- set docmd "-R"
- continue
- } elseif {$opt == "-Q"} {
- set docmd "-Q"
- continue
- }
-
- if {$docmd == ""} {
- continue
- } elseif {$docmd == "-R"} {
- set str "cmd=$opt"
- } elseif {$docmd == "-Q"} {
- set str "qry=$opt"
- } else {
- set docmd ""
- continue
- }
-
- if {$db} {puts stderr "run_remote_cmd_via_sock: $docmd \"$str\""}
- catch {puts $client_sock $str}
- if {$db} {puts stderr "run_remote_cmd_via_sock: flush"}
- catch {flush $client_sock}
- if {$db} {puts stderr "run_remote_cmd_via_sock: gets"}
- catch {gets $client_sock res}
- if {$db} {puts stderr "run_remote_cmd_via_sock: \"$res\""}
- set res [string trim $res]
-
- if [regexp {=clients:} $res] {
- regsub {^.*=clients:} $res "" cres
- regsub {,aro=.*$} $cres "" cres
- regsub {,ans=.*$} $cres "" cres
- if {$cres == "none"} {
- set cres ""
- }
- update_clients_menu $cres
- set client_str $cres
- set_client_balloon $cres
- }
-
- if [regexp {^clients:} $res] {
- regsub {^clients:} $res "" tmp
- if {$tmp == "none"} {
- set tmp ""
- }
- update_clients_menu $tmp
- set client_str $tmp
- set_client_balloon $tmp
-
- if ![regexp {^clients} $opt] {
- # we could block here...
- if {$db} {puts stderr "run_remote_cmd_via_sock: gets"}
- gets $client_sock res
- if {$db} {puts stderr "run_remote_cmd_via_sock: \"$res\""}
- set res [string trim $res]
- }
- }
-
- set docmd ""
-
- if {$res != ""} {
- append result "$res\n"
- }
- }
-
- setup_client_sock 1
-
- set result [string trim $result]
-
- return $result
-}
-
-proc run_remote_cmd {opts} {
- global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay
- global x11vnc_auth_file x11vnc_connect_file
- global client_sock
-
- set debug [in_debug_mode]
-
- if {[lindex $opts 0] == "-R" && [lindex $opts 1] == "noremote"} {
- set str [join $opts]
- if ![double_check_noremote] {
- append_text "skipping: x11vnc $str"
- return ""
- } else {
- append_text "running: x11vnc $str (please do \"Actions -> detach\" to clean things up)\n"
- append_text "subsequent -R/-Q commands should fail..."
- }
- }
-
- if {$client_sock != ""} {
- menus_disable
- stop_watch on
- set result [run_remote_cmd_via_sock $opts]
- stop_watch off
- menus_enable
- if {$result != "fail"} {
- return $result
- }
- }
-
- set cmd ""
-
- lappend cmd $x11vnc_prog;
-
- if {$x11vnc_connect_file != ""} {
- lappend cmd "-connect"
- lappend cmd $x11vnc_connect_file
- } else {
- if {$x11vnc_xdisplay != ""} {
- lappend cmd "-display"
- lappend cmd $x11vnc_xdisplay
- }
- if {$x11vnc_auth_file != ""} {
- lappend cmd "-auth"
- lappend cmd $x11vnc_auth_file
- }
- }
- lappend cmd "-sync"
- foreach word $opts {
- lappend cmd $word
- }
- lappend cmd "2>"
- lappend cmd "/dev/null"
-
- if {0 || $debug} {
- set str [join $cmd]
- puts "running: $str"
- foreach word $cmd {
- puts " word: $word"
- }
- }
-
- set output ""
- menus_disable
-
- stop_watch on
- catch {set output [eval exec $cmd]}
- stop_watch off
-
- menus_enable
- if {$debug} {
- if {[string length $output] > 100} {
- set str [string range $output 0 100]
- append_text "output: $str ...\n"
- } else {
- append_text "output: $output\n"
- }
- }
- return $output
-}
-
-proc try_connect_and_query_all {{n 2}} {
- for {set i 0} {$i < $n} {incr i} {
- if {$i > 0} {
- after 500
- append_text "trying again ...\n"
- }
- if {[try_connect]} {
- query_all
- break
- }
- }
-}
-
-proc try_connect {} {
- global x11vnc_xdisplay connected_to_x11vnc reply_xdisplay
- global menu_var unset_str
-
- set db 0
-#dtime c1
-
- if {! $connected_to_x11vnc} {
- if {[info exists menu_var(display)]} {
- set d $menu_var(display)
- if {$d != "" && $d != $unset_str && $d != $x11vnc_xdisplay} {
- set x11vnc_xdisplay $menu_var(display)
- append_text "Setting X display to: $x11vnc_xdisplay\n"
- }
- }
- }
-
- set_info "Pinging $x11vnc_xdisplay ..."
- set rargs [list "-Q" "ping"]
- set result [run_remote_cmd $rargs]
-#dtime c2a
-
- if {$db} {puts "try_connect: \"$result\""}
-
- if {[regexp {^ans=ping:} $result]} {
- regsub {^ans=ping:} $result {} reply_xdisplay
- set msg "Connected to $reply_xdisplay"
- set_info $msg
- append_text "$msg\n"
- set_connected yes
-
- setup_client_channel
-#dtime c2b
- setup_client_sock 1
- setup_client_tail
-
- fetch_displays
-#dtime c3a
- return 1
- } else {
- set str "x11vnc server."
- if {$x11vnc_xdisplay != ""} {
- set str $x11vnc_xdisplay
- }
- set msg "No reply from $str"
- set_info $msg
- append_text "$msg\n"
- set_connected no
- return 0
- }
-}
-
-proc set_view_variable {val} {
- global menu_var
- set menu_var(WindowView) $val
-}
-proc get_view_variable {} {
- global menu_var
- if {![info exists menu_var(WindowView)]} {
- set menu_var(WindowView) "none"
- }
- return $menu_var(WindowView)
-}
-
-proc dono {a b c} {
- exit 1;
-}
-
-proc do_port_prompt {} {
- global bfont ffont
- global port_reply port_set
-
- set guess 5900
- for {set i 0} {$i < 50} {incr i} {
- set fh ""
- set try [expr $guess + $i]
- catch {set fh [socket -server dono $try]}
- if {$fh != ""} {
- catch {close $fh}
- set guess $try
- break;
- }
- }
- set hn ""
- catch {set hn [exec uname -n]}
- if {$hn == ""} {
- set hn "hostname"
- }
-
- set text " Set the x11vnc Listening Port:
-
- VNC Display :0 corresponds to TCP port 5900
- VNC Display :1 corresponds to TCP port 5901
- etc.
-
- In the Entry below, indicate a Port for x11vnc to listen on.
-
- Note that to connect to x11vnc, a VNC Viewer will need to
- know your selection, for example:
-
- vncviewer $hn:0
- vncviewer $hn:1
- etc.
-
- Your firewall may block incoming connections to TCP ports;
- if it does you may need to reconfigure it.
-
- You can also set some additional parameters:
-
- - Enable SSL encryption.
- (requires an SSL enabled vncviewer, such as SSVNC)
- - Listen only on localhost. (e.g. for an SSH tunnel)
- - Enable UltraVNC or TightVNC File transfer.
-"
- set port_set $guess
- set port_reply ""
-
- toplevel .pp
- wm title .pp "Select x11vnc port"
-
- wm protocol . WM_DELETE_WINDOW "destroy .; exit"
- wm protocol .pp WM_DELETE_WINDOW "destroy .pp; exit"
-
- label .pp.m -text "$text" -relief ridge -justify left -font $ffont
-
- global tk_version
- set tkold 0
- if [info exists tk_version] {
- if [regexp {^8\.[0-3]$} $tk_version] {
- set tkold 1
- }
- if [regexp {^[3-7]\.} $tk_version] {
- set tkold 1
- }
- }
-
- if {$tkold} {
- frame .pp.f -bd 1 -relief ridge
- } else {
- frame .pp.f -bd 1 -relief ridge -pady 2
- }
- label .pp.f.l -text "Port: " -font $bfont
- entry .pp.f.e -width 8 -textvariable port_set -font $ffont
- global enable_ssl; set enable_ssl 0
- if [info exists env(X11VNC_SSL_ENABLED)] {
- set enable_ssl 1
- }
- checkbutton .pp.f.ssl -relief raised -pady 3 -padx 3 -text "Enable SSL" -variable enable_ssl -font $bfont
- global localhost; set localhost 0
- if [info exists env(X11VNC_LOCALHOST_ENABLED)] {
- set localhost 1
- }
- checkbutton .pp.f.loc -relief raised -pady 3 -padx 3 -text "Listen on localhost" -variable localhost -font $bfont
- pack .pp.f.l .pp.f.e -side left
- pack .pp.f.loc .pp.f.ssl -side right
-
- if {$tkold} {
- frame .pp.t -bd 1 -relief ridge
- } else {
- frame .pp.t -bd 1 -relief ridge -pady 2
- }
- global file_transfer; set file_transfer "none"
- if [info exists env(X11VNC_FILETRANSFER_ENABLED)] {
- set file_transfer $env(X11VNC_FILETRANSFER_ENABLED)
- }
- label .pp.t.l -text "File Transfer: " -font $bfont
- radiobutton .pp.t.none -text "None" -variable file_transfer -value "none" -font $bfont
- radiobutton .pp.t.ultra -text "UltraVNC" -variable file_transfer -value "ultra" -font $bfont
- radiobutton .pp.t.tight -text "TightVNC" -variable file_transfer -value "tight" -font $bfont
- pack .pp.t.l .pp.t.none .pp.t.ultra .pp.t.tight -side left
-
- frame .pp.o -bd 1 -relief ridge
- button .pp.o.ok -text "OK" -command "set port_reply 1; destroy .pp" -font $bfont
- button .pp.o.cancel -text "Cancel" -command "set port_reply 0; destroy .pp" -font $bfont
- pack .pp.o.ok .pp.o.cancel -side left -fill x -expand 1
- pack .pp.m -side top -fill x -expand 1
- pack .pp.f .pp.t .pp.o -side top -fill x
-
- focus .pp.f.e
- .pp.f.e icursor end
-
- wm withdraw .pp
- update
- center_win .pp
-
- wm minsize .pp [winfo width .pp] [winfo height .pp]
-
- bind .pp.f.e <KeyPress-Return> "set port_reply 1; destroy .pp"
-
- vwait port_reply
-
- if {$port_reply} {
- regsub -all {^:} $port_set "" port_set
- regsub -all {[ \t]} $port_set "" port_set
- if {[regexp {^[0-9][0-9]*$} $port_set]} {
- if {$port_set < 0} {
- set port_set [expr 0 - $port_set]
- } elseif {$port_set < 200} {
- set port_set [expr $port_set + 5900]
- }
- puts "$port_set:ssl${enable_ssl}:localhost$localhost:ft_$file_transfer"
- }
- }
-}
-
-proc change_view_state {} {
- global menu_var gui_current_state
-
- set new [get_view_variable]
-
- if {![info exists gui_current_state]} {
- set gui_current_state ""
- }
- set old $gui_current_state
- #puts "$old -> $new"
-
- if {$old == $new} {
- return
- }
-
- if {$old == "full" || $old == "icon" || $old == "tray"} {
- ;
- } else {
- set old "none"
- }
-
- if {$new == "full" || $new == "icon" || $new == "tray"} {
- if {$old == "tray"} {
- # sigh XReparentWindow would be too easy...
- # undo_tray_embed
- restart_everything $new
- destroy .
- exit
- }
- make_gui $new
- if {$new == "tray"} {
- wm withdraw .
- }
- } else {
- set_view_variable $old
- }
-}
-
-proc setup_client_tail {} {
- global client_tail
- if {$client_tail != ""} {
- fileevent $client_tail readable read_client_tail
- }
-}
-
-proc setup_client_sock {{enable 1}} {
- global client_sock
- if {$client_sock != ""} {
- if {$enable} {
- fileevent $client_sock readable read_client_sock
- } else {
- fileevent $client_sock readable ""
- }
- }
-}
-
-proc setup_tray_embed {} {
- update
- set w [winfo width .]
- set h [winfo height .]
- if {$w < 24} {
- set w 24
- }
- if {$h < 24} {
- set h 24
- }
- wm minsize . $w $h
- set wid [winfo id .]
- push_new_value "remote-cmd" "remote-cmd" "trayembed:$wid" 0
-}
-
-proc restart_everything {gui_mode} {
- global env gui_argv0 x11vnc_prog full_win
- global icon_mode_at_startup
- global tray_embed tray_running
- if {$gui_mode == "full"} {
- set env(X11VNC_ICON_MODE) 0
- } elseif {$gui_mode == "icon"} {
- set env(X11VNC_ICON_MODE) 1
- } elseif {$gui_mode == "tray"} {
- if {$tray_running} {
- set env(X11VNC_ICON_MODE) "RUNNING"
- } else {
- set env(X11VNC_ICON_MODE) "TRAY"
- }
- }
- puts stderr ""
- puts stderr "tkx11vnc: restarting gui to leave tray mode."
- puts stderr " new gui will be running in the background."
- puts stderr " use kill(1) rather than Ctrl-C to kill it."
- puts stderr ""
- if {[info exists env(X11VNC_RESTART_DEPTH)]} {
- set n $env(X11VNC_RESTART_DEPTH)
- incr n
- set env(X11VNC_RESTART_DEPTH) $n
- } else {
- set env(X11VNC_RESTART_DEPTH) 0
- }
- set env(X11VNC_ICON_SETPASS) ""
-
- if {![info exists env(X11VNC_WISHCMD)]} {
- puts stderr "failure in restart_everything."
- exit 1;
- }
-
- set code [exec $x11vnc_prog -printgui]
- if {[string length $code] < 20000} {
- puts stderr "failure in restart_everything."
- exit 1;
- }
- set tmp "/tmp/x11vnc[pid]"
- append tmp [clock clicks]
- set tmp2 ""
- catch {set tmp2 [exec mktemp $tmp.XXXXXX 2>/dev/null]}
- if {$tmp2 != "" && [file exists $tmp2]} {
- set tmp $tmp2
- } else {
- file delete -force $tmp
- if {[file exists $tmp]} {
- puts stderr "failure in restart_everything."
- exit 1;
- }
- }
- set fh [open $tmp "a"]
- if {![file owned $tmp]} {
- puts stderr "failure in restart_everything."
- exit 1;
- }
- file attributes $tmp -permissions "0400"
- puts $fh $code
- close $fh
-
- #puts stderr [exec ls -l $tmp]
-
- wm withdraw .
- catch {wm withdraw $full_win}
- update
-
- exec $env(X11VNC_WISHCMD) $tmp &
- after 2000
- file delete -force $tmp
-
- destroy .
- exit
-}
-
-proc undo_tray_embed {} {
- set wid [winfo id .]
- push_new_value "remote-cmd" "remote-cmd" "trayunembed:$wid" 0
-}
-
-############################################################################
-# main:
-
-if [info exists env(X11VNC_GUI_TIME)] {
- dtime M
-}
-
-wm withdraw .
-
-global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;
-global x11vnc_xdisplay0
-global x11vnc_client_file x11vnc_gui_geom x11vnc_started vnc_url
-global x11vnc_gui_params
-global x11vnc_auth_file x11vnc_connect_file beginner_mode simple_gui_created
-global helpall helptext helpremote helplabel hostname osname
-global all_settings reply_xdisplay always_update
-global max_text_height max_text_width
-global text_height
-global menu_var unset_str menus_disabled
-global bfont ffont sfont snfont old_labels have_labelframes
-global connected_to_x11vnc
-global cache_all_query_vars
-global last_query_all_time query_all_freq client_tail client_sock client_info_read
-global icon_mode icon_mode_at_startup x11vnc_icon_mode
-global tray_embed tray_running icon_setpasswd icon_embed_id
-global icon_noadvanced icon_minimal
-global make_gui_count text_area_str
-global gui_argv0 gui_start_mode
-global screen_height screen_width
-
-set unset_str "(unset)"
-set vnc_url $unset_str
-set connected_to_x11vnc 0
-set menus_disabled 0
-set max_text_height 40
-set max_text_width 90
-set text_height 14
-set bfont "-adobe-helvetica-bold-r-*-*-*-120-*-*-*-*-*-*"
-set sfont "-adobe-helvetica-bold-r-*-*-*-100-*-*-*-*-*-*"
-set snfont "-adobe-helvetica-medium-r-*-*-*-100-*-*-*-*-*-*"
-set ffont "fixed"
-
-set got_helv 0
-catch {
- foreach fam [font families] {
- if {$fam == "helvetica"} {
- set got_helv 1
- }
- if {$fam == "Helvetica"} {
- set got_helv 1
- }
- }
-}
-
-if {$got_helv} {
- set bfont "Helvetica -12 bold"
- set sfont "Helvetica -10 bold"
- set snfont "Helvetica -10"
-}
-
-set ls ""
-catch {set ls [font metrics $bfont -linespace]}
-if {$ls != "" && $ls > 14} {
- # some recent setups have BIG rendering for the above fonts.
- # on recent (8/08) debian these are really ragged:
- set bfont "-adobe-helvetica-bold-r-*-*-*-90-*-*-*-*-*-*"
- set sfont "-adobe-helvetica-bold-r-*-*-*-75-*-*-*-*-*-*"
- set snfont "-adobe-helvetica-medium-r-*-*-*-75-*-*-*-*-*-*"
-
- set ls ""
- catch {set ls [font metrics $bfont -linespace]}
- if {$ls != "" && $ls < 14} {
- # these are bigger but look better... but for how long?
- set bfont "-adobe-helvetica-bold-r-*-*-*-100-*-*-*-*-*-*"
- set sfont "-adobe-helvetica-bold-r-*-*-*-80-*-*-*-*-*-*"
- set snfont "-adobe-helvetica-medium-r-*-*-*-80-*-*-*-*-*-*"
-
- # maybe consider... {-font font Font {Helvetica -12 bold} {Helvetica -12 bold}}
- # or stick with system font like ssvnc.
- }
-}
-
-# need to check if "fixed" font under XFT on tk8.5 is actually fixed width!!
-set ls ""
-catch {set ls [font metrics $ffont -linespace]}
-set fs ""
-catch {set fs [font metrics $ffont -fixed]}
-set redo 0
-if {$fs != "" && $fs != "1"} {
- set redo 1
-}
-if {$ls != "" && $ls > 14} {
- set redo 1
-}
-if {$redo} {
- foreach fn [font names] {
- if {$fn == "TkFixedFont"} {
- set ffont $fn
- break
- }
- }
-}
-
-set help_indent 24;
-set reply_xdisplay ""
-set all_settings "None so far."
-set always_update 1
-set cache_all_query_vars ""
-set query_all_freq 120
-set last_query_all_time [clock seconds]
-set client_tail ""
-set client_sock ""
-set client_info_read 0
-set make_gui_count 0
-set text_area_str ""
-set gui_argv0 $argv0
-set gui_start_mode ""
-
-if {$tk_version < 8.0} {
- puts stderr ""
- puts stderr "*** tkx11vnc: tk version is old $tk_version, please use 8.0 or higher."
- puts stderr "*** will try to continue with reduced functionality..."
- puts stderr ""
-}
-if {[regexp {^[34]} $tk_version] || $tk_version == "8.0"} {
- set old_labels 1
-} else {
- set old_labels 0
-}
-set have_labelframes 1
-if {$tk_version < 8.4} {
- set have_labelframes 0
-}
-
-set screen_height [winfo screenheight .]
-set screen_width [winfo screenwidth .]
-if {$screen_height < 700} {
- # short screen, netbook?
- set max_text_height 30
- if {$screen_height < 500} {
- # short screen, PDA?
- set max_text_height 22
- set text_height 13
- if {$screen_height <= 360} {
- # very short.
- set max_text_height 16
- set max_text_width 60
- set text_height 11
- }
- }
-}
-if {[info exists env(X11VNC_GUI_TEXT_HEIGHT)]} {
- set max_text_height $env(X11VNC_GUI_TEXT_HEIGHT)
-}
-if {[info exists env(X11VNC_GUI_TEXT_WIDTH)]} {
- set max_text_width $env(X11VNC_GUI_TEXT_WIDTH)
-}
-
-if {"$argv" == "-spit"} {
- set fh [open $argv0 r]
- puts "#ifndef _TKX11VNC_H"
- puts "#define _TKX11VNC_H"
- puts "#ifdef NOGUI"
- puts "char gui_code\[\] = \"\";"
- puts "#else"
- puts "/*"
- puts " * tkx11vnc.h: generated by 'tkx11vnc -spit'"
- puts " * Abandon all hope, ye who enter here..."
- puts " * ...edit tkx11vnc instead."
- puts " */"
- puts " char gui_code\[\] ="
- while {[gets $fh line] > -1} {
- regsub -all {\\} $line {\\\\} line
- regsub -all {"} $line {\\"} line
- puts "\"$line\\n\""
- }
- puts "#endif"
- puts "/* ifdef NOGUI */"
- puts "#endif"
- puts "/* ifndef _TKX11VNC_H */"
- close $fh
- puts ";"
- exit 0
-}
-
-set_view_variable "full"
-
-#puts [exec env | grep X11VNC]
-
-# Read environment for clues:
-
-set x11vnc_client_file "";
-if {[info exists env(X11VNC_CLIENT_FILE)]} {
- set x11vnc_client_file $env(X11VNC_CLIENT_FILE);
- set file $x11vnc_client_file
-
- set client_tail ""
- if {[file exists $file] && [file isfile $file]} {
- if {[file readable $file] && [file owned $file]} {
- set client_tail [open "|tail -f $x11vnc_client_file" "r"]
- }
- }
- if {$client_tail != ""} {
- gets $client_tail tmp
- if [eof $client_tail] {
-#puts "eof $client_tail"
- clean_client_tail
- set client_tail ""
- }
- }
- catch {file delete -force $x11vnc_client_file}
-}
-
-if {[info exists env(X11VNC_PROG)]} {
- set x11vnc_prog $env(X11VNC_PROG);
-} else {
- set x11vnc_prog "x11vnc";
-}
-
-if {[info exists env(X11VNC_CMDLINE)]} {
- set x11vnc_cmdline $env(X11VNC_CMDLINE);
-} else {
- set x11vnc_cmdline "";
-}
-
-if {[info exists env(X11VNC_CONNECT)]} {
- set x11vnc_connect 1
-} else {
- set x11vnc_connect 0;
-}
-
-if {[info exists env(X11VNC_GUI_GEOM)]} {
- set x11vnc_gui_geom $env(X11VNC_GUI_GEOM);
-} else {
- set x11vnc_gui_geom ""
-}
-if {[info exists env(X11VNC_GUI_PARAMS)]} {
- set x11vnc_gui_params $env(X11VNC_GUI_PARAMS);
-} else {
- set x11vnc_gui_params ""
-}
-
-if {[info exists env(X11VNC_FONT_BOLD)]} {
- set bfont $env(X11VNC_FONT_BOLD)
-}
-if {[info exists env(X11VNC_FONT_BOLD_SMALL)]} {
- set sfont $env(X11VNC_FONT_BOLD_SMALL)
-}
-if {[info exists env(X11VNC_FONT_REG_SMALL)]} {
- set snfont $env(X11VNC_FONT_REG_SMALL)
-}
-if {[info exists env(X11VNC_FONT_FIXED)]} {
- set ffont $env(X11VNC_FONT_FIXED)
-}
-
-if {[info exists env(X11VNC_CONNECT_FILE)]} {
- set x11vnc_connect_file $env(X11VNC_CONNECT_FILE);
-} else {
- set x11vnc_connect_file "";
-}
-
-set x11vnc_started 0
-if {[info exists env(X11VNC_STARTED)]} {
- set x11vnc_started 1
-}
-
-set x11vnc_xdisplay ""
-if {[info exists env(X11VNC_XDISPLAY)]} {
- set x11vnc_xdisplay $env(X11VNC_XDISPLAY);
- set x11vnc_connect 1
-
-} elseif {$argv != "" && [regexp {:[0-9]} $argv]} {
- set env(X11VNC_XDISPLAY) "$argv"
- set x11vnc_xdisplay "$argv"
- set x11vnc_connect 1
-
-} elseif {[info exists env(DISPLAY)]} {
- set x11vnc_xdisplay $env(DISPLAY);
-} else {
- set x11vnc_xdisplay ":0";
-}
-set x11vnc_xdisplay0 $x11vnc_xdisplay
-
-if {[info exists env(X11VNC_AUTH_FILE)]} {
- set x11vnc_auth_file $env(X11VNC_AUTH_FILE)
-} else {
- set x11vnc_auth_file ""
-}
-
-set simple_gui_created 0
-if {[info exists env(X11VNC_SIMPLE_GUI)]} {
- set beginner_mode 1
-} else {
- set beginner_mode 0
-}
-
-set icon_mode 0
-set x11vnc_icon_mode 0
-set tray_embed 0
-set tray_running 0
-
-if {![info exists env(X11VNC_ICON_MODE_AT_STARTUP)]} {
- if {[info exists env(X11VNC_ICON_MODE)]} {
- if {$env(X11VNC_ICON_MODE) != 0} {
- set env(X11VNC_ICON_MODE_AT_STARTUP) 1
- } else {
- set env(X11VNC_ICON_MODE_AT_STARTUP) 0
- }
- } else {
- set env(X11VNC_ICON_MODE_AT_STARTUP) 0
- }
-}
-set icon_mode_at_startup $env(X11VNC_ICON_MODE_AT_STARTUP)
-
-if {![info exists env(X11VNC_ICON_MODE)]} {
- set icon_mode 0
-} elseif {$env(X11VNC_ICON_MODE) == "" || $env(X11VNC_ICON_MODE) == "0"} {
- set icon_mode 0
-} else {
- set icon_mode 1
- set_view_variable "icon"
- if [regexp -nocase {TRAY} $env(X11VNC_ICON_MODE)] {
- set tray_embed 1
- }
- if [regexp -nocase {RUNNING} $env(X11VNC_ICON_MODE)] {
- set tray_running 1
- }
-}
-
-set icon_setpasswd 0
-if {[info exists env(X11VNC_ICON_SETPASS)]} {
- if {$env(X11VNC_ICON_SETPASS) != ""} {
- set icon_setpasswd 1
- }
-}
-
-set icon_noadvanced 0
-if {[info exists env(X11VNC_ICON_NOADVANCED)]} {
- set icon_noadvanced 1
-}
-
-set icon_minimal 0
-if {[info exists env(X11VNC_ICON_MINIMAL)]} {
- set icon_minimal 1
-}
-
-if {[info exists env(X11VNC_ICON_EMBED_ID)]} {
- set icon_embed_id $env(X11VNC_ICON_EMBED_ID)
-} else {
- set icon_embed_id ""
-}
-
-
-set hostname [exec uname -n]
-set osname [exec uname]
-
-if {[regexp -nocase {IRIX} $osname]} {
- # IRIX "fixed" font is huge and doublespaced...
- set ffont $snfont
-}
-if {[regexp -nocase {Darwin} $osname]} {
- set ffont {Monaco 10}
- set bfont {system}
-}
-
-if {"$argv" == "-portprompt"} {
- do_port_prompt
- exit 0
-}
-
-#puts [exec env]
-#puts "x11vnc_xdisplay: $x11vnc_xdisplay"
-
-set env(X11VNC_STD_HELP) 1
-
-# scrape the help output for the text and remote control vars:
-parse_help;
-parse_remote_help;
-parse_query_help;
-
-# tweaks to duplicate help text:
-tweak_remote_help lock deny
-tweak_remote_help unlock deny
-
-tweak_both quiet q
-tweak_help logfile o
-tweak_both xwarppointer xwarp
-tweak_both screen_blank sb
-
-set_template
-
-set_name "tkx11vnc"
-
-key_bindings;
-
-get_default_vars
-
-dtime D
-
-proc check_setpasswd {} {
- global env icon_setpasswd
- global do_props_msg
- set do_props_msg ""
- if {$icon_setpasswd} {
- set m "\n"
- set m "${m} Note the x11vnc icon in the system tray.\n"
- set m "${m} This panel is its 'Properties' dialog.\n"
- set m "${m}\n"
- set m "${m} To specify a Session Password and to\n"
- set m "${m} allow VNC viewers to connect, follow\n"
- set m "${m} these steps:\n"
- set m "${m}\n"
- set m "${m} Enter a passwd in the Password field\n"
- set m "${m} (it can be left blank.) You can also\n"
- set m "${m} supply a ViewOnly passwd if desired.\n"
- set m "${m}\n"
- set m "${m} Set 'Accept Connections' and then Press \n"
- set m "${m} 'Apply' to allow incoming connections.\n"
- set m "${m}\n"
- set m "${m} No Viewer can connect until you do this.\n"
- set m "${m}\n"
- set m "${m} The passwords are only for this x11vnc\n"
- set m "${m} session and are not saved. Run x11vnc\n"
- set m "${m} manually for more control (e.g. -rfbauth \n"
- set m "${m} for a saved password.)\n"
- set m "${m}\n"
- set m "${m} See 'Help' for details on each option.\n"
-
- global x11vnc_cmdline
-
- set dossl 0
- if {[info exists x11vnc_cmdline]} {
- if [regexp -- {-ssl} $x11vnc_cmdline] {
- set dossl 1
- }
- }
- if {$dossl || [info exists env(X11VNC_GOT_SSL)]} {
- set m "${m}\n"
- set m "${m} SSL encryption mode active. You can\n"
- set m "${m} find your Public Cert in the Logfile\n"
- set m "${m} and also the ~/.vnc/certs directory.\n"
- }
-
- if {[info exists env(X11VNC_SETPASS_FAIL)]} {
- set pp 5900
- if {[info exists env(X11VNC_GOT_RFBPORT_VAL)]} {
- if {$env(X11VNC_GOT_RFBPORT_VAL) > 0} {
- set pp $env(X11VNC_GOT_RFBPORT_VAL)
- }
- }
-
- set m " The x11vnc program failed to start! \n"
- set m "${m}\n"
- set m "${m} Maybe there is another VNC server\n"
- set m "${m} already listening on port $pp?\n"
- set m "${m}\n"
- set m "${m} You will need to start over after\n"
- set m "${m} you make sure x11vnc can start.\n"
- }
-
- set do_props_msg $m
- do_props
- }
-}
-
-if {0} {
- if {[info exists env(X11VNC_ICON_SETPASS)]} {
- if {$env(X11VNC_ICON_SETPASS) == "2"} {
- global icon_mode_at_startup icon_mode
- set icon_mode_at_startup 1
- set icon_mode 2
- }
- }
-}
-
-if {$icon_mode} {
- if {$icon_mode == 2} {
- make_gui "full"
- } elseif {$tray_embed} {
- make_gui "tray"
- } else {
- make_gui "icon"
- }
- dtime G
- old_balloon
- check_setpasswd
- push_new_value "remote-cmd" "remote-cmd" "Q:clients" 1
-} else {
- make_gui "full"
- dtime G
- check_setpasswd
-}
-
-
-# main loop.
diff --git a/x11vnc/tkx11vnc.h b/x11vnc/tkx11vnc.h
deleted file mode 100644
index 46f4bbc..0000000
--- a/x11vnc/tkx11vnc.h
+++ /dev/null
@@ -1,7351 +0,0 @@
-#ifndef _TKX11VNC_H
-#define _TKX11VNC_H
-#ifdef NOGUI
-char gui_code[] = "";
-#else
-/*
- * tkx11vnc.h: generated by 'tkx11vnc -spit'
- * Abandon all hope, ye who enter here...
- * ...edit tkx11vnc instead.
- */
- char gui_code[] =
-"#!/bin/sh\n"
-"# the next line restarts using wish. \\\n"
-"exec wish \"$0\" \"$@\"\n"
-"catch {rename send {}}\n"
-"#\n"
-"# Copyright (C) 2004-2009 Karl J. Runge <runge@karlrunge.com>\n"
-"# All rights reserved.\n"
-"#\n"
-"# This is free software; you can redistribute it and/or modify\n"
-"# it under the terms of the GNU General Public License as published by\n"
-"# the Free Software Foundation; either version 2 of the License, or\n"
-"# (at your option) any later version.\n"
-"#\n"
-"# This software is distributed in the hope that it will be useful,\n"
-"# but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
-"# GNU General Public License for more details.\n"
-"#\n"
-"# You should have received a copy of the GNU General Public License\n"
-"# along with this software; if not, write to the Free Software\n"
-"# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,\n"
-"# USA.\n"
-"\n"
-"#\n"
-"# tkx11vnc v0.2\n"
-"# This is a simple frontend to x11vnc. It uses the remote control\n"
-"# and query features (-remote/-query aka -R/-Q) to interact with it. \n"
-"# It is just a quick-n-dirty hack (it parses -help output, etc), but\n"
-"# it could be of use playing with or learning about the (way too) many\n"
-"# parameters x11vnc has.\n"
-"# \n"
-"# It can be used to interact with a running x11vnc (see the x11vnc\n"
-"# -gui option), or to set the parameters and then start up x11vnc. \n"
-"# \n"
-"\n"
-"#\n"
-"# Below is a simple picture of how the gui should be laid out and how\n"
-"# the menus should be organized. Most menu items correspond to remote\n"
-"# control commands. A trailing \":\" after the item name means it is a string\n"
-"# to be set rather than a boolean that can be toggled (e.g. the entry\n"
-"# box must be used).\n"
-"#\n"
-"# Some tweak options may be set in the prefix \"=\" string.\n"
-"# A means it is an \"Action\" (not a true variable)\n"
-"# R means it is an action only valid in remote mode.\n"
-"# S means it is an action only valid in startup mode.\n"
-"# Q means it is an action worth querying after running.\n"
-"# P means the string can be +/- appended/deleted (string may not\n"
-"# be the same after the remote command)\n"
-"# G means gui internal item\n"
-"# F means can be set via file browse\n"
-"# D means for simple gui\n"
-"# -C:val1,... means it will be a checkbox (radio button)\n"
-"# the \"-\" means no other options follow\n"
-"# 0 means to skip the item.\n"
-"# -- means add a separator\n"
-"#\n"
-"# The =GAL ... =GAL LOFF stuff is to provide submenus.\n"
-"#\n"
-"\n"
-"global env started time_count\n"
-"set started \"\"\n"
-"proc dtime {{msg \"\"}} {\n"
-" global started time_count\n"
-" if {$started == \"\"} {\n"
-" return\n"
-" }\n"
-" set diff [expr \"[exec gtod.bin] - $started\"]\n"
-" set diff [format \"%.2f\" $diff]\n"
-" incr time_count\n"
-" if {$msg == \"\"} {\n"
-" set msg $time_count\n"
-" }\n"
-" puts -nonewline stderr \"$msg $diff \" \n"
-" puts stderr [clock format [clock seconds]]\n"
-"}\n"
-"\n"
-"if [info exists env(X11VNC_GUI_TIME)] {\n"
-" global started time_count\n"
-" set started [exec gtod.bin]\n"
-" set time_count 0\n"
-" dtime \"S\"\n"
-"}\n"
-"\n"
-"proc set_template {} {\n"
-" global template\n"
-" set template \"\n"
-"Row: Actions Clients Permissions Keyboard Pointer Help\n"
-"Row: Displays Screen Tuning Debugging Misc\n"
-"\n"
-"Actions\n"
-" =SA start\n"
-" =RA stop\n"
-" --\n"
-" =DSA attach\n"
-" =DRA detach\n"
-" --\n"
-" =RA ping\n"
-" =RA update-all\n"
-" =GAL Settings::\n"
-" =GA save-settings\n"
-" =SFA load-settings:\n"
-" =SA defaults-all\n"
-" =0SA clear-all\n"
-" --\n"
-" =F rc:\n"
-" norc\n"
-" =GAL LOFF\n"
-" -- D\n"
-" =DRA stop+quit \n"
-" =DGA Quit \n"
-"\n"
-"Help\n"
-" =DGA gui\n"
-" =DGA all\n"
-"\n"
-"Clients\n"
-" =DRQA current:\n"
-" =DF connect:\n"
-" =DRQA disconnect:\n"
-" --\n"
-" accept:\n"
-" afteraccept:\n"
-" gone:\n"
-" vncconnect\n"
-" zeroconf\n"
-" -- D\n"
-" tightfilexfer\n"
-" ultrafilexfer\n"
-" proxy:\n"
-" =GAL Chat::\n"
-" chatwindow\n"
-" =DRA chaton\n"
-" =DRA chatoff\n"
-" =GAL LOFF\n"
-" =GAL Java-applet::\n"
-" =D http\n"
-" httpdir:\n"
-" httpport:\n"
-" https:\n"
-" httpsredir:\n"
-" enablehttpproxy\n"
-" =GAL LOFF\n"
-"\n"
-"Displays\n"
-" =D display:\n"
-" =F auth:\n"
-" =S reflect:\n"
-" =D desktop:\n"
-" =D rfbport:\n"
-" =S autoport:\n"
-" =0 gui:\n"
-"\n"
-"Screen\n"
-" =DRA refresh\n"
-" =RA reset\n"
-" =RA blacken\n"
-" -- D\n"
-" =D scale:\n"
-" scale_cursor:\n"
-" --\n"
-" =D solid\n"
-" solid_color:\n"
-" --\n"
-" =GAL OverlayVisuals::\n"
-" overlay\n"
-" overlay_nocursor\n"
-" 8to24\n"
-" 8to24_opts:\n"
-" =GAL LOFF\n"
-" =GAL 8-Bit-Color::\n"
-" flashcmap\n"
-" shiftcmap:\n"
-" notruecolor\n"
-" =GAL LOFF\n"
-" =GAL SubWindow::\n"
-" id:\n"
-" sid:\n"
-" =RA id_cmd:\n"
-" =GAL LOFF\n"
-" =GAL ResizeRotate::\n"
-" = xrandr\n"
-" =-C:resize,newfbsize,exit xrandr_mode:\n"
-" rotate:\n"
-" padgeom:\n"
-" =GAL LOFF\n"
-" =GAL Clipping::\n"
-" =P blackout:\n"
-" xinerama\n"
-" clip:\n"
-" =GAL LOFF\n"
-" =GAL Misc-Screen::\n"
-" fixscreen:\n"
-" visual:\n"
-" rawfb:\n"
-" pipeinput:\n"
-" uinput_accel:\n"
-" uinput_reset:\n"
-" uinput_always:\n"
-" 24to32\n"
-" =GAL LOFF\n"
-"\n"
-"Keyboard\n"
-" =D norepeat\n"
-" =D add_keysyms\n"
-" modtweak\n"
-" xkb\n"
-" --\n"
-" capslock\n"
-" skip_lockkeys\n"
-" --\n"
-" skip_keycodes:\n"
-" skip_dups\n"
-" sloppy_keys\n"
-" --\n"
-" =FP remap:\n"
-" clear_mods\n"
-" clear_keys\n"
-" clear_all\n"
-" =RA clear_locks\n"
-"\n"
-"Pointer\n"
-" =D-C:none,arrow,X,some,most cursor:\n"
-" =-C:1,2,3,4,5,6 arrow:\n"
-" --\n"
-" cursorpos\n"
-" =D nocursorshape\n"
-" --\n"
-" noxfixes\n"
-" cursor_drag\n"
-" =GAL AlphaBlending::\n"
-" noalphablend\n"
-" alphacut:\n"
-" alphafrac:\n"
-" alpharemove\n"
-" =GAL LOFF\n"
-" --\n"
-" buttonmap:\n"
-" --\n"
-" xwarppointer\n"
-" always_inject\n"
-"\n"
-"Misc\n"
-" =GD-C:full,icon,tray WindowView:\n"
-" =GD simple-gui\n"
-" -- D\n"
-" =GA all-settings\n"
-" =RA remote-cmd:\n"
-" =GAL Selection::\n"
-" =D nosel\n"
-" noprimary\n"
-" nosetprimary\n"
-" noclipboard\n"
-" nosetclipboard\n"
-" seldir:\n"
-" =GAL LOFF\n"
-" =GAL X-ext::\n"
-" xtrap\n"
-" noxrecord\n"
-" =RQA reset_record\n"
-" =GAL LOFF\n"
-" =GAL MacOSX::\n"
-" macnosaver\n"
-" macnowait\n"
-" macwheel:\n"
-" macnoswap\n"
-" macnoresize\n"
-" maciconanim:\n"
-" macmenu\n"
-" =GAL LOFF\n"
-" --\n"
-" 6\n"
-" noipv6\n"
-" noipv4\n"
-" --\n"
-" nofb\n"
-" =D nobell\n"
-" nolookup\n"
-" rfbversion:\n"
-" bg\n"
-" =S loop\n"
-" =S loopbg\n"
-" =S sleepin:\n"
-" =-C:ignore,exit sigpipe:\n"
-" =0 inetd\n"
-"\n"
-"Debugging\n"
-" debug_pointer\n"
-" debug_keyboard\n"
-" =F logfile:\n"
-" =GA show-logfile\n"
-" =GA tail-logfile\n"
-" quiet\n"
-" --\n"
-" =GA show-start-cmd\n"
-" =DG debug_gui\n"
-" =GAL Misc-Debug::\n"
-" debug_xevents\n"
-" debug_xdamage\n"
-" =-C:0,1,2,3 debug_wireframe:\n"
-" debug_scroll\n"
-" debug_tiles\n"
-" debug_grabs\n"
-" debug_sel\n"
-" debug_ncache\n"
-" dbg\n"
-" =GAL LOFF\n"
-"\n"
-"Permissions\n"
-" =DRQA lock\n"
-" =DRQA unlock\n"
-" =D shared\n"
-" =D forever\n"
-" --\n"
-" =DFP allow:\n"
-" =D localhost\n"
-" =RA allowonce:\n"
-" listen:\n"
-" -- D\n"
-" =D viewonly\n"
-" input:\n"
-" --\n"
-" =GAL Passwords::\n"
-" passwd:\n"
-" viewpasswd:\n"
-" =F passwdfile:\n"
-" =F rfbauth:\n"
-" usepw\n"
-" --\n"
-" unixpw\n"
-" unixpw_list:\n"
-" unixpw_nis\n"
-" unixpw_nis_list:\n"
-" =0 storepasswd\n"
-" =GAL LOFF\n"
-" =GAL SSL::\n"
-" ssl\n"
-" =F ssl_pem:\n"
-" stunnel\n"
-" =F stunnel_pem:\n"
-" =F ssldir:\n"
-" =F sslverify:\n"
-" ssltimeout:\n"
-" --\n"
-" enc:\n"
-" =GAL LOFF\n"
-" =GAL Misc-Perms::\n"
-" safer\n"
-" unsafe\n"
-" =RA noremote\n"
-" =0S alwaysshared\n"
-" =0S nevershared\n"
-" =0S dontdisconnect\n"
-" =SQA deny_all\n"
-" timeout:\n"
-" grabkbd\n"
-" grabptr\n"
-" grabalways\n"
-" grablocal:\n"
-" forcedpms\n"
-" clientdpms\n"
-" noserverdpms\n"
-" noultraext\n"
-" =GAL LOFF\n"
-"\n"
-"Tuning\n"
-" =D-C:0,1,2,3,4 pointer_mode:\n"
-" input_skip:\n"
-" allinput\n"
-" =D nodragging\n"
-" -- D\n"
-" speeds:\n"
-" =D wait:\n"
-" defer:\n"
-" =D nap\n"
-" screen_blank:\n"
-" --\n"
-" =GAL WireFrame::\n"
-" wireframe\n"
-" wireframe_mode:\n"
-" =-C:never,top,always wirecopyrect:\n"
-" =GAL LOFF\n"
-" =GAL ScrollCopyRect::\n"
-" =-C:never,keys,mouse,always scrollcopyrect:\n"
-" scr_area:\n"
-" scr_skip:\n"
-" scr_inc:\n"
-" scr_keys:\n"
-" scr_term:\n"
-" scr_keyrepeat:\n"
-" scr_parms:\n"
-" =GAL LOFF\n"
-" =GAL XDAMAGE::\n"
-" xdamage\n"
-" xd_area:\n"
-" xd_mem:\n"
-" =GAL LOFF\n"
-" =GAL Ncache::\n"
-" ncache\n"
-" ncache_size:\n"
-" ncache_cr\n"
-" ncache_no_moveraise\n"
-" ncache_no_dtchange\n"
-" ncache_old_wm\n"
-" ncache_no_rootpixmap\n"
-" ncache_keep_anims\n"
-" ncache_pad:\n"
-" =RA ncache_reset_rootpixmap\n"
-" =GAL LOFF\n"
-" --\n"
-" =GAL SharedMemory::\n"
-" noshm\n"
-" flipbyteorder\n"
-" onetile\n"
-" =GAL LOFF\n"
-" =GAL Misc-Tuning::\n"
-" progressive:\n"
-" fs:\n"
-" gaps:\n"
-" grow:\n"
-" fuzz:\n"
-" extra_fbur:\n"
-" wait_ui:\n"
-" setdefer:\n"
-" nowait_bog\n"
-" slow_fb:\n"
-" xrefresh:\n"
-" readtimeout:\n"
-" snapfb\n"
-" threads\n"
-" wmdt:\n"
-" rfbwait:\n"
-" nodpms\n"
-" nofbpm\n"
-" =GAL LOFF\n"
-"\"\n"
-"}\n"
-"\n"
-"proc set_internal_help {} {\n"
-" global helptext helpall\n"
-"\n"
-" # set some internal item help here:\n"
-" set helptext(start) \"\n"
-"Launch x11vnc with the settings you have prescribed in the gui.\n"
-"The x11vnc process is started in an xterm window so you can see the\n"
-"output, kill it, etc.\n"
-"\n"
-"By viewing this help item, the command built so far will be displayed\n"
-"in the gui text area. Have a look. If you Press start it will be shown\n"
-"as well and you will be asked to confirm running it.\n"
-"\n"
-"If you want to use a saved profile \\\"rc file\\\" you can do \\\"Misc -> rc\\\" and\n"
-"select the file and simply start x11vnc using the rc file. Alternatively,\n"
-"you could first use the \\\"Actions -> load-settings\\\" action to load in\n"
-"an \\\"rc file\\\" and then press \\\"Actions -> start\\\" to start up x11vnc\n"
-"based on those values.\n"
-"\"\n"
-" set helptext(stop) \"\n"
-"The \\\"Actions -> stop\\\" action sends a signal to the running x11vnc\n"
-"server indicating it should shutdown all connections and exit.\n"
-"\n"
-"The GUI stays running in case you want to start a new x11vnc or attach\n"
-"to another one. Use \\\"Actions -> Quit\\\" if you then want to have the\n"
-"gui exit. Use \\\"Actions -> stop+quit\\\" to have both exit at once.\n"
-"\"\n"
-"\n"
-" set helptext(show-start-cmd) \"\n"
-"Displays in the text area what the x11vnc start command (i.e. the command\n"
-"run by \\\"Actions -> start\\\") looks like for the current values of the\n"
-"settings. This can be done even in the attached state. Intended for\n"
-"debugging the gui. The help item for \\\"Actions -> start\\\" gives the\n"
-"same info.\n"
-"\n"
-"If you want to load in a saved profile \\\"rc file\\\" use \\\"Misc -> rc\\\"\n"
-"and select the file. \\\"Actions -> load-settings\\\" does a similar thing\n"
-"with an rc-file, but reading the file and setting the gui variables to\n"
-"its values.\n"
-"\"\n"
-"\n"
-" set helptext(debug_gui) \"\n"
-"Set debug_gui to get more output printed in the text area.\n"
-"\"\n"
-"\n"
-" set helptext(detach) \"\n"
-"No longer be associated with the x11vnc server. Switch to the\n"
-"non-connected state. The x11vnc server keeps running: it does not exit.\n"
-"\n"
-"You can either later reattach to it \\\"Actions -> attach\\\", or start\n"
-"up a new x11vnc \\\"Actions -> start\\\", or exit \\\"Actions -> Quit\\\".\n"
-"\"\n"
-"\n"
-" set helptext(attach) \"\n"
-"Attach to a running x11vnc server, if possible. Switches to connected\n"
-"state if successful. Usually the channel used to attach is via the X\n"
-"display (VNC_CONNECT rootwin property) being polled by the x11vnc server.\n"
-"To change or set the X display to use do \\\"Displays -> display\\\".\n"
-"\n"
-"Sometimes the \\\"-connect /path/to/filename\\\" is used as the communcation\n"
-"channel. The running x11vnc has to know that \\\"/path/to/filename\\\"\n"
-"is the communication channel (i.e. it is using the same -connect option).\n"
-"\"\n"
-"\n"
-" set helptext(ping) \"\n"
-"Check if x11vnc still responds to \\\"ping\\\" remote command.\n"
-"\"\n"
-"\n"
-" set helptext(update-all) \"\n"
-"Query the x11vnc server for the current values of all variables.\n"
-"Populate the values into the gui's database.\n"
-"\n"
-"Normally the gui will refresh this info every time it interacts with\n"
-"the x11vnc server (including after a few minutes of inactivity), so one\n"
-"doesn't need to use this action very often (unless something else is\n"
-"changing the state of the x11vnc server, or new clients have connected,\n"
-"etc).\n"
-"\"\n"
-"\n"
-" set helptext(clear-all) \"\n"
-"Forget any variable settings either entered in by you or set at the\n"
-"default. Basically sets everything to 0 or the string (unset).\n"
-"\n"
-"This action is only available in \\\"startup\\\" mode, not when connected\n"
-"to a running x11vnc server (in that case the variable settings reflect\n"
-"the state of the running x11vnc). To detach from a running x11vnc\n"
-"server use \\\"Actions -> detach\\\"; to completely stop the x11vnc server\n"
-"use \\\"Actions -> stop\\\".\n"
-"\"\n"
-"\n"
-" set helptext(defaults-all) \"\n"
-"Reset all variable settings to the default values. Basically sets\n"
-"everything to the default queries \\\"x11vnc -QD var\\\" retrieved at startup.\n"
-"\n"
-"This action is only available in \\\"startup\\\" mode, not when connected\n"
-"to a running x11vnc server (in that case the variable settings reflect\n"
-"the state of the running x11vnc). To detach from a running x11vnc\n"
-"server use \\\"Actions -> detach\\\"; to completely stop the x11vnc server\n"
-"use \\\"Actions -> stop\\\".\n"
-"\"\n"
-"\n"
-" set helptext(load-settings) \"\n"
-"Read in the \\\"rc file\\\" you prescribe in the dialog and then set the\n"
-"variables to those in the rc-file. Any variables not mentioned in the\n"
-"rc-file are set to their default value.\n"
-"\n"
-"You could then do \\\"Actions -> start\\\" to start x11vnc with these\n"
-"parameters. Or you could make some further changes to variables\n"
-"using the gui before starting x11vnc.\n"
-"\n"
-"This action is only available in \\\"startup\\\" mode, not when connected\n"
-"to a running x11vnc server (in that case the variable settings reflect\n"
-"the state of the running x11vnc). To detach from a running x11vnc\n"
-"server use \\\"Actions -> detach\\\"; to completely stop the x11vnc server\n"
-"use \\\"Actions -> stop\\\".\n"
-"\"\n"
-"\n"
-" set helptext(save-settings) \"\n"
-"Construct a ~/.x11vncrc file based on the current settings and\n"
-"offer to save it in a file (default ~/.x11vncrc). If saved in a\n"
-"file other than the default, you can access the profile by using\n"
-"the \\\"-rc <filename>\\\" option when starting x11vnc.\n"
-"\n"
-"If an rc file entry begins with \\\"#d\\\" that means the current\n"
-"setting is at the Default value and so you probably want to leave\n"
-"it commented out with the \\\"#\\\" character.\n"
-"\n"
-"If an rc file entry begins with \\\"#?\\\" that means we think\n"
-"you probably do not really want to force the value to this setting.\n"
-"\n"
-"In either case, feel free to uncomment the line and/or change any\n"
-"of the parameter values in the file. \n"
-"\"\n"
-"\n"
-" set helptext(all-settings) \"\n"
-"Displays the gui's database of all of the x11vnc server's current\n"
-"settings. Use \\\"Actions -> update-all\\\" or \\\"Control+R\\\" to\n"
-"refresh this list if it ever gets out of sync.\n"
-"\"\n"
-"\n"
-" set helptext(remote-cmd) \"\n"
-"Run a remote command (-R) or query (-Q) directly. Only a few\n"
-"remote commands are not on a menu, but for those few you can\n"
-"run the command directly this way. Just enter the command into\n"
-"the Entry box when prompted. Use the prefix \\\"Q:\\\" to indicate\n"
-"a -Q query. Examples: \\\"zero:20,20,100,100\\\", \\\"Q:ext_xfixes\\\" \n"
-"\"\n"
-"\n"
-" set helptext(stop+quit) \"\n"
-"Send the stop command to the x11vnc server, then terminate the tkx11vnc gui.\n"
-"\"\n"
-"\n"
-" set helptext(show-logfile) \"\n"
-"View the current contents of the logfile (if it exists and is accessible\n"
-"by the gui process).\n"
-"\"\n"
-"\n"
-" set helptext(tail-logfile) \"\n"
-"Run the tail(1) command with -f option on the logfile in an xterm.\n"
-"(if it exists and is accessible by the gui process).\n"
-"\"\n"
-"\n"
-" set helptext(Quit) \"\n"
-"Terminate the tkx11vnc gui. Any x11vnc server will be left running.\n"
-"\"\n"
-"\n"
-" set helptext(current) \"\n"
-"Shows a menu of currently connected VNC clients on the x11vnc server.\n"
-"\n"
-"Allows you to find more information about them, change their input\n"
-"permissions, or disconnect them.\n"
-"\n"
-"Note that the File transfer permission only applies to UltraVNC\n"
-"file transfer, not TightVNC file transfer.\n"
-"\n"
-"You will be prompted to confirm any disconnections.\n"
-"\"\n"
-"\n"
-" set helptext(client) \"\n"
-"After selecting a VNC client from the \\\"Clients -> current\\\" menu,\n"
-"you will be presented with a dialog that shows the information\n"
-"about the VNC client.\n"
-"\n"
-"You can choose to disconnect the client by clicking on the \n"
-"\\\"Disconnect\\\" checkbox and pressing \\\"OK\\\". There will be a\n"
-"confirmation dialog to doublecheck.\n"
-"\n"
-"Alternatively, you can fine tune the VNC client's input permissions\n"
-"by selecting any of the Keystrokes, Mouse-Motion, Button-Click,\n"
-"Clipboard-Input, or Files checkboxes and pressing \\\"OK\\\". This is like\n"
-"the \\\"-input\\\" option but on a per-client basis.\n"
-"\n"
-"To not change any aspects of the VNC client press \\\"Cancel\\\".\n"
-"\"\n"
-"\n"
-" set helptext(solid_color) \"\n"
-"Set the -solid color value.\n"
-"\"\n"
-"\n"
-" set helptext(xrandr_mode) \"\n"
-"Set the -xrandr mode value.\n"
-"\"\n"
-"\n"
-" set helptext(unixpw_list) \"\n"
-"Set the -unixpw usernames list value.\n"
-"\"\n"
-"\n"
-" set helptext(unixpw_nis_list) \"\n"
-"Set the -unixpw_nis usernames list value.\n"
-"\"\n"
-"\n"
-" set helptext(stunnel_pem) \"\n"
-"Set the -stunnel pem filename value.\n"
-"\"\n"
-"\n"
-" set helptext(ssl_pem) \"\n"
-"Set the -ssl pem filename value.\n"
-"\"\n"
-"\n"
-" set helptext(wireframe_mode) \"\n"
-"Set the -wireframe mode string value.\n"
-"\"\n"
-"\n"
-" set helptext(simple-gui) \"\n"
-"Toggle between menu items corresponding the most basic ones\n"
-"and all possible settings. I.e. toggle between a simple gui\n"
-"and one for power users.\n"
-"\"\n"
-"\n"
-" set helptext(Tray) \"\n"
-"The tray/icon mode (started with \\\"x11vnc -gui tray ...\\\", etc.) presents\n"
-"a small icon that indicates the status of the running x11vnc server.\n"
-"\n"
-"Depending on your environment, this icon may be embedded in a system\n"
-"tray or applet dock, or simply be a standalone window. \\\"-gui tray\\\"\n"
-"will attempt to embed the icon in the system tray, while \\\"-gui icon\\\"\n"
-"is for a standalone window. Use \\\"-gui tray=setpass\\\" (or icon=setpass)\n"
-"to be prompted to set the session password at startup.\n"
-"\n"
-"When the icon has a light background, that means no VNC viewers are\n"
-"currently connected to the VNC display.\n"
-"\n"
-"When the icon has a dark background (i.e. reverse-video), that means at\n"
-"least one VNC viewer is connected to the VNC display.\n"
-"\n"
-"Moving the mouse pointer over the icon will popup a \\\"status balloon\\\"\n"
-"indicating the VNC display name and the names and info of any connected VNC\n"
-"viewers. Press the middle mouse button if the balloon does not appear.\n"
-"\n"
-"Clicking the left or right mouse button on the icon displays a menu\n"
-"of actions:\n"
-"\n"
-" Properties - Brings up the Properties dialog to set some basic\n"
-" parameters. The full tkx11vnc GUI may be accessed\n"
-" via the \\\"Advanced ...\\\" button. Press \\\"Help\\\"\n"
-" in the Properties dialog for more info.\n"
-" \n"
-" Help - Displays this help text.\n"
-" \n"
-" New Client - Presents an entry box where you type in the name\n"
-" of a computer that is running a VNC viewer in\n"
-" \\\"listen\\\" mode (e.g. vncviewer -listen). For a\n"
-" non-standard listening port use \\\"host:port\\\".\n"
-"\n"
-" Pressing \\\"OK\\\" will initiate the reverse\n"
-" connection. Use a blank hostname to skip it.\n"
-" \n"
-" Disconnect - Shows a popup menu of connected clients. Click on\n"
-" one to disconnect it, or click on \\\"All Clients\\\"\n"
-" disconnect all clients.\n"
-"\n"
-" Window View - Switch between the \\\"full\\\" gui (also known as\n"
-" \\\"Advanced\\\"), \\\"icon\\\" mode (small icon window with\n"
-" popups), or \\\"tray\\\" mode (small icon embedded in the\n"
-" system tray). This is a shortcut for the action:\n"
-" \\\"Properties -> Advanced -> Misc -> WindowView\\\".\n"
-" \n"
-" Stop x11vnc - Directs the x11vnc server to disconnect all vncviewers\n"
-" and then exit. The tray/icon GUI then exits as well.\n"
-"\n"
-" Logfile - Show the logfile if x11vnc is being run with one.\n"
-"\n"
-" Custom - If you have a \\$HOME/.x11vnc.gui file each uncommented\n"
-" line in it becomes an additional menu item for this\n"
-" menu. The remote control command is run directly\n"
-" via \\\"x11vnc -R <command>\\\", or if prefixed with \n"
-" \\\"action:\\\" runs a gui internal action, or if \\\"sep\\\"\n"
-" adds a separator. Set X11VNC_CUSTOM_GUI to use\n"
-" a different filename. Example file contents:\n"
-"\n"
-" scale:3/4\n"
-" scale:1\n"
-" scale_cursor:1\n"
-" sep\n"
-" action:all-settings\n"
-" #debug_keyboard\n"
-" sep\n"
-" action:Quit\n"
-"\n"
-"Termination:\n"
-"\n"
-"If the x11vnc server stops for any reason, the tray/icon gui will exit.\n"
-"\n"
-"If you delete the tray/icon (e.g. X out button), that is the same\n"
-"as the \\\"Stop x11vnc\\\" action in the menu. (This will disconnect any\n"
-"VNC viewer you are currently using to access the display since the\n"
-"x11vnc server is terminated).\n"
-"\n"
-"To terminate the tray/icon gui window but not the x11vnc server press\n"
-"Control-C on the tray/icon window. You can also do this (and much\n"
-"more) via Properties -> Advanced -> Actions -> Quit\n"
-"\"\n"
-"\n"
-" set helptext(NewClient) \"\n"
-" New Client - Presents an entry box where you type in the name\n"
-" of a computer that is running a VNC viewer in\n"
-" \\\"listen\\\" mode (e.g. vncviewer -listen). For a\n"
-" non-standard listening port use \\\"host:port\\\".\n"
-"\n"
-" Pressing \\\"OK\\\" will initiate the reverse\n"
-" connection. Use a blank hostname to skip it, or\n"
-" delete (\\\"X-out\\\") the window.\n"
-" \n"
-"\"\n"
-"\n"
-" set helptext(Properties) \"\n"
-"The Properties dialog allows you to set some basic parameters of a\n"
-"running x11vnc server. After modifying them press \\\"OK\\\" or \\\"Apply\\\"\n"
-"to apply the changes, or press \\\"Cancel\\\" to skip applying them.\n"
-"\n"
-" Accept Connections:\n"
-"\n"
-" Toggles whether VNC viewers are allowed to connect or not. It corresponds\n"
-" to the \\\"-R unlock\\\" and \\\"-R lock\\\" remote-control commands.\n"
-"\n"
-" Ask for Confirmation:\n"
-"\n"
-" Toggles whether a popup menu will be presented at the X display when\n"
-" a new VNC viewer attempts to connect. The person sitting at the X\n"
-" display can choose to accept or reject the connection or accept the\n"
-" connection in ViewOnly mode. It corresponds to the \\\"-R accept:popup\\\"\n"
-" and \\\"-R accept:\\\" remote-control commands.\n"
-" \n"
-" All Clients ViewOnly:\n"
-"\n"
-" Toggles whether the entire VNC desktop is view only. All clients\n"
-" will only be able to watch when this is set (regardless of how they\n"
-" logged in). It corresponds to the \\\"-R viewonly\\\" and \\\"-R noviewonly\\\"\n"
-" remote-control commands.\n"
-" \n"
-" Shared:\n"
-"\n"
-" Toggles whether multiple simultaneous viewer connections are allowed\n"
-" or not. It corresponds to the \\\"-R shared\\\" and \\\"-R noshared\\\"\n"
-" remote-control commands.\n"
-"\n"
-" Advertise Service (Zeroconf):\n"
-"\n"
-" Toggles whether this VNC server should advertize itself via Zeroconf\n"
-" (also called Bonjour, mDNS, and avahi). Then VNC viewers can then find\n"
-" this service on the local network. It corresponds to the \\\"-R zeroconf\\\"\n"
-" and \\\"-R nozeroconf\\\" remote-control commands.\n"
-"\n"
-" Serve Java Viewer Applet:\n"
-"\n"
-" Toggles whether this VNC server should serve up a Java VNC Viewer\n"
-" applet via HTTP on http://hostname:5800/ (or port 5800+n for VNC\n"
-" port 5900+n). A java enabled Web Browser can then connect to the\n"
-" desktopby VNC. If SSL is active then the HTTPS URL https://hostname:5900/\n"
-" (etc.) will work as well. This requires the x11vnc java viewer jar file\n"
-" (shared/x11vnc/classes) to be installed. It corresponds to the\n"
-" \\\"-R http\\\" and \\\"-R nohttp\\\" remote commands.\n"
-"\n"
-" Solid Background Color:\n"
-"\n"
-" To improve VNC performance, if this option is set, then x11vnc will try\n"
-" to make the desktop background a solid color (which compresses extremely\n"
-" well compared to photo images, etc.) It corresponds to the \\\"-R solid\\\"\n"
-" and \\\"-R nosolid\\\" remote commands.\n"
-"\n"
-" Password:\n"
-"\n"
-" Lets you set the session password viewers may use to gain full access\n"
-" to the display. This will only work if x11vnc was started with the\n"
-" -gui icon or -gui tray mode.\n"
-" \n"
-" ViewOnly Password:\n"
-"\n"
-" Lets you set the session password viewers may use to gain view only\n"
-" access to the display. This will only work if x11vnc was started with\n"
-" the -gui icon or -gui tray mode.\n"
-"\n"
-"\n"
-" NOTE: These \\\"session\\\" passwords only last for the current x11vnc\n"
-" session (they are not remembered, see the -storepasswd, -passwdfile,\n"
-" and -rfbauth x11vnc options for using stored passwords).\n"
-"\n"
-" If you set \\\"Password\\\" to the empty string that makes the \\\"ViewOnly\n"
-" Password\\\" empty as well and removes the need for any password to log in.\n"
-"\n"
-" If you set \\\"ViewOnly Password\\\" to the empty string that just removes\n"
-" the ViewOnly log in aspect: \\\"Password\\\" is still required to log in.\n"
-"\n"
-" - The \\\"Help\\\" button shows this help text.\n"
-" \n"
-" - The \\\"Advanced ...\\\" button replaces the Properties dialog with the full\n"
-" tkx11vnc GUI. All dynamic settings can be modified in the full GUI.\n"
-"\n"
-"\n"
-"==========================================================================\n"
-"\n"
-"Don't Lock Yourself Out:\n"
-"\n"
-" If you are sitting at the physical X display you cannot get into too\n"
-" much trouble setting the Properties dialog values.\n"
-"\n"
-" However IF you are using a VNC Viewer to REMOTELY access the X display\n"
-" some items in the Properties dialog can lock you out of further access:\n"
-"\n"
-" \\\"Accept Connections\\\" if you disable this remotely, and\n"
-" accidentally disconnect your VNC viewer then you will not be\n"
-" able to reconnect.\n"
-" \n"
-" \\\"Ask for Confirmation\\\" if you enable this only someone\n"
-" sitting at the X display can confirm any new VNC connections.\n"
-" Furthermore, any current VNC viewers will be blocked while\n"
-" waiting for the confirmation (times out in 120 sec by default). \n"
-" \n"
-" \\\"All Clients ViewOnly\\\" if you enable this remotely, well\n"
-" you can no longer provide input to disable it.\n"
-" \n"
-" If you do lock yourself out you could log in remotely and start up\n"
-" a second x11vnc and connect to that one to try to fix things in the\n"
-" first one.\n"
-"\n"
-" Note that if there are two or more x11vnc's on the same display the\n"
-" use of the GUI may be ill-behaved. Terminate the second x11vnc as\n"
-" soon as you have fixed the setting in the first one. Use of a remote\n"
-" control command, e.g. \\\"x11vnc -R noviewonly\\\" or \\\"x11vnc -R unlock\\\"\n"
-" is a good way to avoid this problem.\n"
-"\"\n"
-"\n"
-" set helptext(all) $helpall\n"
-"\n"
-" set helptext(Misc-Tuning:) \"\n"
-"x11vnc has what seems like hundreds of tuning parameters! In this\n"
-"sub-menu we place some lesser used ones. Most likely you'll want to\n"
-"leave them at their default values, but you can try them out quickly\n"
-"with the gui to see if they improve things.\n"
-"\"\n"
-"\n"
-" set helptext(Passwords:) \"\n"
-"The items in this sub-menu pertain to setting passwords. Note that x11vnc\n"
-"has two types of password files: RealVNC-style ones (you can create them\n"
-"with x11vnc -storepasswd or other VNC utility program) you use these\n"
-"via -rfbauth; and plain-text file passwords you use via -passwdfile.\n"
-"\n"
-"Normally passwords cannot be changed by remote-control (e.g. the gui),\n"
-"but for the case of the \\\"Icon\\\" and \\\"Tray\\\" modes this constraint has\n"
-"been relaxed.\n"
-"\n"
-"In neither the RealVNC-style nor the plain-text file cases should the\n"
-"password files be readable by users you do not want to access the VNC\n"
-"server. Contrary to popular belief, the RealVNC-style passwords are\n"
-"not encrypted, merely obscured.\n"
-"\n"
-"x11vnc has the even less secure -passwd and -viewpasswd supplied on\n"
-"the command line. Be careful with these since they could be read by\n"
-"users with something like the ps(1) command. On some operating systems\n"
-"x11vnc tries to quickly overwrite them on the command line but it doesn't\n"
-"work everywhere.\n"
-"\n"
-"Regarding ViewOnly passwords (where a VNC client using that password\n"
-"can only watch the screen, not interact with it), this is not available\n"
-"with -rfbauth, but only with -passwdfile, -passwd, and -viewpasswd.\n"
-"\"\n"
-"\n"
-" set helptext(SSL:) \"\n"
-"In this sub-menu we provide the options related to SSL encrpytion\n"
-"and authentication.\n"
-"\n"
-"There is a built-in mode (-ssl) using the OpenSSL library, and a 2nd\n"
-"using the external stunnel program (-stunnel, that needs to be installed\n"
-"on the system). Either may require or benefit from having PEM certificate\n"
-"files specified.\n"
-"\n"
-"\"\n"
-"\n"
-" set helptext(Misc-Perms:) \"\n"
-"In this sub-menu we provide some lesser used permission options.\n"
-"\n"
-"Regarding -alwaysshared, -nevershared, and -dontdisconnect, you probably\n"
-"should never use them and just use x11vnc's -shared and -forever options\n"
-"instead (these give basically the same functionality and if you mixed\n"
-"them too much unexpected things may happen).\n"
-"\"\n"
-"#'\n"
-"\n"
-" set helptext(AlphaBlending:) \"\n"
-"In this sub-menu we provide some tweak parameters for cursors (little\n"
-"icon at the mouse pointer) that have transparency (i.e. an Alpha channel\n"
-"in addition to Red, Green, and Blue RGB channels). For these cursors,\n"
-"some of the graphics underneath the cursor is allowed to be blended in:\n"
-"e.g. a drop-shadow (a terrible effect IMNSHO).\n"
-"\n"
-"AlphaBlending for x11vnc is only available when the XFIXES X extension is\n"
-"present (since otherwise it cannot see the cursors at all and so applies\n"
-"heuristics to show some fake cursors). AlphaBlending is only a problem\n"
-"with x11vnc when the cursors are not opaque.\n"
-"\n"
-"Opaque cursors (e.g. bitmap or simply colored cursor) are rendered\n"
-"correctly by x11vnc. Only when there is transparency does x11vnc have\n"
-"to make some approximation to transform the cursor to be opaque (the\n"
-"VNC protocol does not provide for an alpha channel in cursors, only RGB).\n"
-"\n"
-"The items in this sub-menu let you tweak x11vnc's approximation scheme\n"
-"for cursors with transparency. Hopefully you won't have to use them.\n"
-"Certain cursor \\\"themes\\\" may require adjustment however.\n"
-"\"\n"
-"#'\n"
-" set helptext(OverlayVisuals:) \"\n"
-"In this sub-menu are some options that involve fixing color problems\n"
-"for \\\"Overlay\\\" or \\\"Multi-Depth\\\" visuals. This problem is rare\n"
-"since overlay and multi-depth visual video hardware is rare. \n"
-"Some Sun, SGI, and HP machines are known to have them.\n"
-"\n"
-"The short answer is if you have a multi-depth visual display (e.g. 8 and\n"
-"24 bits), and you see messed up colors in x11vnc try the \\\"-overlay\\\"\n"
-"option on Solaris or IRIX.\n"
-"\n"
-"A brief Background on pixels, color, and visuals:\n"
-"\n"
-" Pixels (picture elements) are kept in video memory as a certain number\n"
-" of bits-per-pixel (bpp). Most common are 8bpp, 16bpp, and 32bpp.\n"
-" Less common are 24bpp, 4bpp, and 1bpp (monochrome).\n"
-"\n"
-" How pixel values (i.e. values of the bits) are rendered into colors on\n"
-" the screen can be done via different \\\"Recipes\\\". These different\n"
-" recipes are referred to as \\\"visuals\\\". E.g. for 8bpp there is\n"
-" a PseudoColor visual that maintains a mapping (that can be changed\n"
-" dynamically) of the pixel values (256 possible ones) into RGB values.\n"
-" Other 8bpp visuals, e.g. StaticGrey and TrueColor have fixed, regular\n"
-" mappings and so provide less variation in kinds of colors.\n"
-"\n"
-" A visual's \\\"depth\\\" is how many of the pixels are used in the\n"
-" actual recipe. This may sound wasteful (i.e. not using some of the\n"
-" bits), but for 32bpp (4 billion colors) that is too much and nearly\n"
-" always only 24 for them are used. The most common Visual seems to\n"
-" be depth 24 TrueColor at 32bpp. This provides 16 million colors\n"
-" which is more than the number of pixels on most screens (1280x1024 =\n"
-" 1.3 million pixels). Another sometimes used visual that ignores some\n"
-" bits is depth 15 TrueColor at 16bpp.\n"
-"\n"
-"OK, now, finally, to the Overlay Visuals. Some hardware (or software\n"
-"emulations) allow different depth visuals to be used on the display\n"
-"at the same time. The pixels of windows using different depth visuals\n"
-"may overlap.\n"
-"\n"
-"The most common seems to be both 8 and 24 depth visuals on a 32bpp setup.\n"
-"24 of the pixels can be used for one visual and the remaining 8 for the\n"
-"other. This is sometimes referred to as \\\"8+24\\\" mode. Furthermore,\n"
-"a speedup is achieved because writing graphics data to, say, the 8bit\n"
-"visual does not destroy the image data in the 24bit visual. Evidently\n"
-"popup menus can be done very quickly this way: they use the 8bit visual\n"
-"and when the popup goes away the graphics data in the 24bit visual is\n"
-"immediately reexposed without having the application redraw it.\n"
-"\n"
-"Also, some legacy applications can only use 8bpp visuals. But in these\n"
-"days of high color graphics and web browsers one would like the rest\n"
-"of the desktop to use depth 24 visuals. They often work on the multi\n"
-"depth visuals.\n"
-"\n"
-"How does this effect x11vnc? x11vnc nearly always polls the root window\n"
-"(container of all other windows). The root window will be one depth,\n"
-"e.g. 8 or 24. Any windows using the *other* depth will appear to have\n"
-"messed up colors (or just be black or some other solid color) when viewed\n"
-"via x11vnc.\n"
-"\n"
-"How to fix? Solaris and IRIX provide an API to extract the full snapshot\n"
-"of the display with all the colors correct. It comes to x11vnc as depth\n"
-"24 TrueColor. To enable this use the \\\"-overlay\\\" option. Performance\n"
-"may be slower, but if the colors are correct that is a big improvement.\n"
-"\"\n"
-"\n"
-" set helptext(8-Bit-Color:) \"\n"
-"Some older displays (e.g. with limited Video RAM) use 8 bits-per-pixel\n"
-"color. This allows for only 256 different colors on the screen at the\n"
-"same time. This sometimes leads to problems with viewing these 8bpp\n"
-"displays via x11vnc. This sub-menu has some options that correspond to\n"
-"workarounds for this case. If you can configure the machine to use 16bpp\n"
-"it may be worth it to avoid the color problems (e.g. color flashing\n"
-"as the 8bit colormap is switched).\n"
-"\"\n"
-" set helptext(SubWindow:) \"\n"
-"This sub-menu has a couple options regarding having x11vnc poll a \n"
-"single window, not the entire display. This way just the window\n"
-"is shared.\n"
-"\n"
-"Note if the application pops up multiple windows they are not tracked\n"
-"and shared. So this is not application sharing. The application has to\n"
-"be very simple (e.g. a simple terminal or the image window on a webcam)\n"
-"for this mode to be usable.\n"
-"\"\n"
-" set helptext(ResizeRotate:) \"\n"
-"This sub-menu has some options regarding screens that support the X\n"
-"Resize, Reflection, and Rotation Extension (RANDR), and one expects screen\n"
-"resizing, reflection, or rotation to take place during the x11vnc session.\n"
-"This is pretty rare, but x11vnc seems to handle it reasonably well using\n"
-"this X extension.\n"
-"\n"
-"This mode is on by default in -id mode to try to track the changing\n"
-"size of the SubWindow. It is not on by default for full-screen mode\n"
-"because of the extra overhead, etc.\n"
-"\"\n"
-"\n"
-" set helptext(WireFrame:) \"\n"
-"This sub-menu has some options for the x11vnc wireframing speedup scheme.\n"
-"\n"
-"For x11vnc, Wireframing means to watch for toplevel windows being Opaquely\n"
-"Moved or Resized. When x11vnc detects this, it stops polling the screen\n"
-"and simply shows a \\\"wireframe\\\" outline of the window as it is being\n"
-"moved or resized. This avoids \\\"screen polling thrashing\\\" when the\n"
-"screen is changing so rapidly during this period. For various reasons\n"
-"this is usually much faster then letting the window manager do its\n"
-"own wireframing (you are encouraged to do Opaque moves and resizes\n"
-"when using x11vnc!)\n"
-"\n"
-"Also, once a moved window is released in its new position, x11vnc uses\n"
-"the VNC CopyRect encoding to very efficiently update the VNC viewers\n"
-"(each just copies the image data locally).\n"
-"\n"
-"This sort of scheme was used much in the 1990's on local displays because\n"
-"video hardware was slow at the time. x11vnc tries to use this same trick\n"
-"as a speedup for its activities (the network is much slower than video\n"
-"hardware writes, and the video hardware reads that x11vnc uses to poll\n"
-"the screen are still slow today).\n"
-"\"\n"
-"#'\"\n"
-"\n"
-" set helptext(Safe:) \"\n"
-"In this sub-menu are some options for making x11vnc operations\n"
-"more, or less, safe. E.g. disable the running of external commands, etc.\n"
-"\n"
-"You can also turn off the Remote control channel (NOTE that doing that\n"
-"will disable the GUI from being able to communicate with x11vnc).\n"
-"\"\n"
-"\n"
-" set helptext(X-ext:) \"\n"
-"In this sub-menu are a few rarely used options regarding some X extensions\n"
-"used by x11vnc.\n"
-"\"\n"
-" set helptext(Clipping:) \"\n"
-"In this sub-menu are some options regarding clipping or blacking out\n"
-"portions of the Screen. E.g. under XINERAMA when the multiple monitors\n"
-"are not the same size.\n"
-"\n"
-"\"\n"
-" set helptext(Misc-Screen:) \"\n"
-"In this sub-menu are some little used options modifying aspects of\n"
-"the screen source.\n"
-"\"\n"
-"\n"
-" set helptext(Settings:) \"\n"
-"In this sub-menu are some options for saving and loading option settings.\n"
-"The default file to store settings in is ~/.x11vncrc, but you can save\n"
-"different \\\"profiles\\\" in other files for later use.\n"
-"\n"
-"\"\n"
-" set helptext(Java-applet:) \"\n"
-"In this sub-menu are some options for running the built-in HTTP server\n"
-"that delivers the TightVNC Java VNC Viewer applet (VncViewer.jar) to\n"
-"clients. The viewer runs in their Web browser.\n"
-"\n"
-"The default port listened on is 5800, so the URL is typically:\n"
-"\n"
-" http://hostname:5800/\n"
-"\n"
-"but this can be altered by -httpport, etc.\n"
-"\"\n"
-"\n"
-" set helptext(Chat:) \"\n"
-"In this sub-menu are some options for enabling a local chat window\n"
-"and starting or stopping the current chat. This is the UltraVNC \n"
-"Text Chat support in x11vnc.\n"
-"\"\n"
-"\n"
-" set helptext(ScrollCopyRect:) \"\n"
-"This sub-menu has some options for the x11vnc Scroll detection and\n"
-"CopyRect speedup scheme.\n"
-"\n"
-"For this mode, x11vnc \\\"spies\\\" on communication between the X server and\n"
-"applications using the RECORD extension. It looks for various patterns\n"
-"to detect a scrolled window. This only works for some applications,\n"
-"fortunately some important ones.\n"
-"\n"
-"Once the scroll is detected it uses the VNC CopyRect encoding for a\n"
-"big speedup. Screen polling is also sped up for this scheme.\n"
-"\n"
-"There are many tweakable parameters for this mode and they are described\n"
-"in the sub-menu items.\n"
-"\"\n"
-"\n"
-" set helptext(XDAMAGE:) \"\n"
-"The DAMAGE X extension allows the X server to send signals to x11vnc\n"
-"telling it which regions of the screen have been changed. This improves\n"
-"x11vnc's performance markedly. The DAMAGE extension must be available\n"
-"on the display for this to work.\n"
-"\n"
-"Unfortunately DAMAGE cannot be trusted completely for the changed regions,\n"
-"because often the reported changed region is much larger than the actual\n"
-"changed regions. Nevertheless, x11vnc uses the DAMAGE information very\n"
-"effectively as hints to improve its performance.\n"
-"\n"
-"The items in the sub-menu allow tweaking x11vnc's DAMAGE algorithm.\n"
-"\"\n"
-"\n"
-" set helptext(Ncache:) \"\n"
-"A simple client-side (viewer) caching scheme is enabled with the\n"
-"\\\"-ncache n\\\" option. It simply uses \\\"n\\\" framebuffer sized areas\n"
-"below the actual display for caching window pixel data. \n"
-"\n"
-"Drawbacks are it uses a lot of RAM (roughly n times more), and the\n"
-"pixels cache area is visible in the viewers.\n"
-"\n"
-"The items in the sub-menu allow tweaking x11vnc's -ncache algorithm.\n"
-"\"\n"
-"\n"
-" set helptext(SharedMemory:) \"\n"
-"This sub-menu provides some options regarding SYSV shared memory usage\n"
-"(shm) by x11vnc. Usually you want shm turned on because the x11vnc\n"
-"process is nearly always running on the same machine the X server process\n"
-"is running on. SharedMemory gives a performance speedup. However, if you\n"
-"need to modify this scenario for special usage these options allow you to.\n"
-"\"\n"
-"\n"
-" set helptext(Misc-Debug:) \"\n"
-"This sub-menu contains a lot of debugging parameters usually used\n"
-"for debugging x11vnc itself. This is unlike the -debug_pointer and\n"
-"-debug_keyboard options that are useful in learning information, quirks,\n"
-"etc. about your local display and environment.\n"
-"\"\n"
-"\n"
-" set helptext(Selection:) \"\n"
-"This sub-menu contains some options centering around the Selection\n"
-"(also referred to as the Clipboard, Cutbuffers, etc). x11vnc will try\n"
-"to exchange the selections between the VNC viewers and the X server.\n"
-"You can adjust that behavior with these options.\n"
-"\"\n"
-"\n"
-" set helptext(WindowView) \"\n"
-"Set the Window View Mode for the gui. There are three modes:\n"
-"\n"
-" - full: Presents the full gui (Actions, Clients, etc, buttons,\n"
-" and the Text area and Set/Entry box).\n"
-"\n"
-" - icon: Presents a small icon instead of the full gui. Moving\n"
-" the mouse over it shows the VNC display name and any\n"
-" connected clients. Clicking on the icon pops up a menu\n"
-" of actions to perform. Among them is \\\"Properties\\\" that\n"
-" allows setting more parameters. Clicking on \\\"Advanced\\\"\n"
-" in \\\"Properties\\\" brings up the full gui.\n"
-"\n"
-" - tray: Attempt to embed the small icon in the system tray. If\n"
-" this fails it will resort to icon mode where the small icon\n"
-" is a standalone window.\n"
-"\n"
-"Note that in \\\"full\\\" mode if you delete the full gui window the gui\n"
-"terminates (but the x11vnc server keeps running). However under \\\"icon\\\"\n"
-"or \\\"tray\\\" mode if you bring up the full gui window via \\\"Properties ->\n"
-"Advanced\\\" and then delete it the gui does NOT terminate.\n"
-"\n"
-"Also note that by default in \\\"icon\\\" mode if you delete the icon\n"
-"window both the gui *and* the x11vnc server terminate.\n"
-"\"\n"
-"\n"
-" set helptext(gui) \"\n"
-"tkx11vnc is a simple frontend to x11vnc. Nothing fancy, it merely\n"
-"provides an interface to each of the many x11vnc command line options and\n"
-"remote control commands. See \\\"Help -> all\\\" for much info about x11vnc.\n"
-"\n"
-"For a simplier gui, run x11vnc in \\\"tray\\\" or \\\"icon\\\" mode such as\n"
-"\\\"-gui tray\\\", \\\"-gui icon\\\", or \\\"-gui tray=setpass\\\". In that\n"
-"mode the full gui is only available under \\\"Advanced ...\\\".\n"
-"\n"
-"Also, \\\"-gui ez\\\" will show fewer menu items (toggle via Misc -> simple_gui)\n"
-"\n"
-"All menu items have a (?) button one can click on to get more information\n"
-"about the option or command.\n"
-"\n"
-"There are two states tkx11vnc can be in:\n"
-"\n"
-" 1) Available to control a running x11vnc process.\n"
-"\n"
-" 2) Getting ready to start a x11vnc process.\n"
-"\n"
-"Most people will just use state 1).\n"
-"\n"
-"In state 1) the Menu items available in the menus are those that\n"
-"correspond to the x11vnc \\\"remote control\\\" commands. See the -remote\n"
-"entry under \\\"Help -> all\\\" for a complete list. Also available is\n"
-"the \\\"Actions -> stop\\\" item to shut down the running x11vnc server,\n"
-"thereby changing to state 2). There are other actions available too.\n"
-"\n"
-"In state 2) the Menu items available in the menus (\\\"Actions\\\", \\\"Clients\\\",\n"
-"etc.) are those that correspond to command line options used in starting\n"
-"an x11vnc process, and the \\\"Actions -> start\\\" item executes\n"
-"x11vnc thereby changing to state 1). To see what x11vnc startup command\n"
-"you have built so far, look at the (?) help for \\\"Actions -> start\\\"\n"
-"and it will show you what the command looks like.\n"
-"\n"
-"There is much overlap between the menu items available in state 1)\n"
-"and state 2), but it is worth keeping in mind it is not 100%.\n"
-"For example, you cannot set passwords or password files in state 1).\n"
-"(update: simple password setting is now allowed in \\\"tray\\\" or \\\"icon\\\" mode).\n"
-"\n"
-"\n"
-"Also note that there may be *two* separate X displays involved, not just\n"
-"one: 1) the X display x11vnc will be polling (and making available to\n"
-"VNC viewers), and 2) the X display this GUI is intended to display on.\n"
-"\n"
-"For example, one might use ssh to access the remote machine where the\n"
-"GUI would display on :11 and x11vnc would poll display :0. By default\n"
-"the gui will display on the value in the DISPLAY env. variable followed\n"
-"by the value from the -display option. To override this, use something\n"
-"like: \\\"-gui otherhost:0\\\", etc.\n"
-"\n"
-"\n"
-"GUI components: \n"
-"--- ----------\n"
-"\n"
-"1) At the top of the gui is a info text label where information will\n"
-" be posted, e.g. when traversing menu items text indicating how to get\n"
-" help on the item and its current value will be displayed.\n"
-"\n"
-"2) Below the info label is the area where the menu buttons, \\\"Actions\\\",\n"
-" \\\"Clients\\\", etc., are presented. If a menu item has a checkbox,\n"
-" it corresponds to a boolean on/off variable. Otherwise it is\n"
-" either a string variable, or an action not associated with a\n"
-" variable (for the most part).\n"
-"\n"
-"3) Below the menu button area is a label indicating the current x11vnc\n"
-" X display being polled and the corresponding VNC display name. Both\n"
-" will be \\\"(*none*)\\\" when there is no connection established.\n"
-"\n"
-"4) Below the x11 and vnc displays label is a text area there scrolling\n"
-" information about actions being taken and commands being run is displayed.\n"
-" To scroll click in the area and use PageUp/PageDown or the arrow keys.\n"
-"\n"
-"5) At the bottom is an entry area. When one selects a menu item that\n"
-" requires supplying a string value, the label will be set to the\n"
-" parameter name and one types in the new value. Then one presses the\n"
-" \\\"OK\\\" button or presses \\\"Enter\\\" to set the value. Or you can press\n"
-" \\\"Cancel\\\" or \\\"Escape\\\" to avoid changing the variable.\n"
-"\n"
-" Many variables are boolean toggles (for example, \\\"Permissions ->\n"
-" viewonly\\\") or Radio button selections. Selecting these menu items\n"
-" will NOT activate the entry area but rather toggle the variable\n"
-" immediately.\n"
-"\n"
-"\n"
-"CASCADES BUG: There is a bug not yet worked around for the cascade menus\n"
-"where the (?) help button gets in the way. To get the mouse over to\n"
-"the cascade menu click and release mouse to activate the cascade, then\n"
-"you can click on its items. Dragging with a mouse button held down will\n"
-"not work (sorry!).\n"
-"\n"
-"\n"
-"Key Bindings:\n"
-"\n"
-" In the Text Area: Control-/ selects all of the text.\n"
-" Anywhere: Control-d invokes \\\"Actions -> detach\\\"\n"
-" Anywhere: Control-a invokes \\\"Actions -> attach\\\"\n"
-" Anywhere: Control-p invokes \\\"Actions -> ping\\\"\n"
-" Anywhere: Control-u and Control-r invoke \\\"Actions -> update-all\\\"\n"
-"\"\n"
-"\n"
-"set under_wally \"\n"
-"Misc:\n"
-"\n"
-"Since x11vnc has so many settings and to avoid further confusion,\n"
-"the libvncserver options:\n"
-"\n"
-" -alwaysshared\n"
-" -nevershared\n"
-" -dontdisconnect\n"
-"\n"
-"are not available for changing in a running x11vnc (even though it\n"
-"is feasible). These options overlap with the x11vnc options -shared\n"
-"and -forever which are hopefully enough for most usage. They may be\n"
-"specified for x11vnc startup if desired.\n"
-"\n"
-"\"\n"
-"\n"
-"global beginner_mode\n"
-"if {$beginner_mode} {\n"
-" set helptext(gui) \"\n"
-"tkx11vnc is a simple frontend to x11vnc. It is currently running in\n"
-"\\\"ez\\\" or \\\"simple\\\" mode. For many more options run it in normal\n"
-"mode by toggling \\\"Misc -> simple_gui\\\".\n"
-"\n"
-"All menu items have a (?) button one can click on to get more information\n"
-"about the option or command.\n"
-"\n"
-"GUI components: \n"
-"--- ----------\n"
-"\n"
-"1) At the top of the gui is a info text label where information will\n"
-" be posted, e.g. when traversing menu items text indicating how to get\n"
-" help on the item and its current value will be displayed.\n"
-"\n"
-"2) Below the info label is the area where the menu buttons, \\\"Actions\\\",\n"
-" \\\"Clients\\\", etc., are presented. If a menu item has a checkbox,\n"
-" it corresponds to a boolean on/off variable. Otherwise it is\n"
-" either a string variable, or an action not associated with a\n"
-" variable (for the most part).\n"
-"\n"
-"3) Below the menu button area is a label indicating the current x11vnc\n"
-" X display being polled and the corresponding VNC display name. Both\n"
-" will be \\\"(*none*)\\\" when there is no connection established.\n"
-"\n"
-"4) Below the x11 and vnc displays label is a text area there scrolling\n"
-" information about actions being taken and commands being run is displayed.\n"
-" To scroll click in the area and use PageUp/PageDown or the arrow keys.\n"
-"\n"
-"5) At the bottom is an entry area. When one selects a menu item that\n"
-" requires supplying a string value, the label will be set to the\n"
-" parameter name and one types in the new value. Then one presses the\n"
-" \\\"OK\\\" button or presses \\\"Enter\\\" to set the value. Or you can press\n"
-" \\\"Cancel\\\" or \\\"Escape\\\" to avoid changing the variable.\n"
-"\n"
-" Many variables are boolean toggles (for example, \\\"Permissions ->\n"
-" viewonly\\\") or Radio button selections. Selecting these menu items\n"
-" will NOT activate the entry area but rather toggle the variable\n"
-" immediately.\n"
-"\n"
-"CASCADES BUG: There is a bug not yet worked around for the cascade menus\n"
-"where the (?) help button gets in the way. To get the mouse over to\n"
-"the cascade menu click and release mouse to activate the cascade, then\n"
-"you can click on its items. Dragging with a mouse button held down will\n"
-"not work (sorry!).\n"
-"\n"
-"\"\n"
-"}\n"
-"\n"
-"}\n"
-"\n"
-"proc center_win {w} {\n"
-" wm withdraw $w\n"
-" set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2];\n"
-" set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2];\n"
-" wm geometry $w +$x+$y\n"
-" wm deiconify $w\n"
-" update\n"
-"}\n"
-"\n"
-"proc textwidth {text} {\n"
-" set min 0;\n"
-" foreach line [split $text \"\\n\"] {\n"
-" set n [string length $line]\n"
-" if {$n > $min} {\n"
-" set min $n\n"
-" }\n"
-" }\n"
-" return $min\n"
-"}\n"
-"\n"
-"proc textheight {text} {\n"
-" set count 0;\n"
-" foreach line [split $text \"\\n\"] {\n"
-" incr count\n"
-" }\n"
-" return $count\n"
-"}\n"
-"\n"
-"proc set_name {name} {\n"
-" global full_win icon_mode\n"
-" global saved_set_name\n"
-"\n"
-" if {![info exists saved_set_name]} {\n"
-" set saved_set_name \"tkx11vnc\"\n"
-" }\n"
-" if {$name == \"RESTORE\"} {\n"
-" set name $saved_set_name\n"
-" } else {\n"
-" set saved_set_name $name\n"
-" }\n"
-" if {![info exists full_win]} {\n"
-" return\n"
-" }\n"
-" set w \".\"\n"
-" if {$icon_mode} {\n"
-" wm title $w \"$name\"\n"
-" wm iconname $w \"$name\"\n"
-" set w $full_win\n"
-" }\n"
-" wm title $w \"$name\"\n"
-" wm iconname $w \"$name\"\n"
-"}\n"
-"\n"
-"proc make_toplevel {w {title \"\"}} {\n"
-" catch {destroy $w}\n"
-" toplevel $w;\n"
-" bind $w <Escape> \"destroy $w\"\n"
-" if {$title != \"\"} {\n"
-" wm title $w $title\n"
-" wm iconname $w $title\n"
-" }\n"
-"}\n"
-"\n"
-"proc textwin {name title text {entry \"\"}} {\n"
-" global max_text_height max_text_width\n"
-" global bfont ffont\n"
-"\n"
-" set width [textwidth $text]\n"
-" incr width\n"
-" if {$width > $max_text_width} {\n"
-" set width $max_text_width\n"
-" }\n"
-" set height [textheight $text]\n"
-" if {$height > $max_text_height} {\n"
-" set height $max_text_height\n"
-" }\n"
-"\n"
-" set w \".text_$name\"\n"
-" make_toplevel $w $title\n"
-"\n"
-" frame $w.f -bd 0;\n"
-" pack $w.f -fill both -expand 1\n"
-" text $w.f.t -width $width -height $height -setgrid 1 -bd 2 \\\n"
-" -yscrollcommand \"$w.f.y set\" -relief ridge \\\n"
-" -font $ffont;\n"
-" scrollbar $w.f.y -orient v -relief sunken -command \"$w.f.t yview\";\n"
-" button $w.f.b -text \"Dismiss\" -command \"destroy $w\" -font $bfont \\\n"
-" -pady 2\n"
-"\n"
-" $w.f.t insert 1.0 $text;\n"
-"\n"
-" bind $w <Enter> \"focus $w.f.t\"\n"
-"\n"
-" if {$entry != \"\"} {\n"
-" # varname+Label Name\n"
-" set list [split $entry \"+\"]\n"
-" set varname [lindex $list 0]\n"
-" set labname [lindex $list 1]\n"
-" frame $w.f.ef -bd 1 -relief groove\n"
-" label $w.f.ef.l -text \"$labname\" -anchor w -font $bfont\n"
-" entry $w.f.ef.e -relief sunken -font $ffont \\\n"
-" -textvariable $varname\n"
-" button $w.f.ef.b -text \"OK\" -font $bfont \\\n"
-" -command \"set ${varname}_ok 1; destroy $w\" \n"
-" bind $w.f.ef.e <KeyPress-Return> \"set ${varname}_ok 1; destroy $w\"\n"
-" \n"
-" pack $w.f.ef.l -side left\n"
-" pack $w.f.ef.e -side left -fill x -expand 1\n"
-" pack $w.f.ef.b -side right\n"
-" }\n"
-"\n"
-" wm withdraw $w\n"
-" pack $w.f.b -side bottom -fill x \n"
-" if {$entry != \"\"} {\n"
-" pack $w.f.ef -side bottom -fill x \n"
-" bind $w <Enter> \"focus $w.f.ef.e\"\n"
-" $w.f.ef.e icursor end\n"
-" } else {\n"
-" bind $w <Enter> \"focus $w.f.t\"\n"
-" }\n"
-" pack $w.f.y -side right -fill y;\n"
-" pack $w.f.t -side top -fill both -expand 1;\n"
-" update\n"
-"\n"
-" center_win $w\n"
-"\n"
-" return $w\n"
-"}\n"
-"\n"
-"proc active_when_connected {item} {\n"
-" global helpremote helptext\n"
-" global icon_mode\n"
-"\n"
-" if {$icon_mode} {\n"
-" if {$item == \"passwd\"} {\n"
-" return 1\n"
-" }\n"
-" if {$item == \"viewpasswd\"} {\n"
-" return 1\n"
-" }\n"
-" }\n"
-"\n"
-" if {[opt_match G $item]} {\n"
-" return 1\n"
-" } elseif {[opt_match R $item]} {\n"
-" return 1\n"
-" } elseif {[opt_match S $item]} {\n"
-" return 0\n"
-" } elseif {[is_action $item]} {\n"
-" if {[opt_match R $item]} {\n"
-" return 1\n"
-" } else {\n"
-" return 0\n"
-" }\n"
-" } elseif {[info exists helpremote($item)]} {\n"
-" return 1\n"
-" } else {\n"
-" return 0\n"
-" }\n"
-"}\n"
-"\n"
-"proc active_when_starting {item} {\n"
-" global helpremote helptext beginner_mode\n"
-"\n"
-" if {$beginner_mode} {\n"
-" if {[opt_match G $item]} {\n"
-" return 1\n"
-" }\n"
-" if {$item == \"display\"} {\n"
-" return 1\n"
-" }\n"
-" if {$item == \"attach\"} {\n"
-" return 1\n"
-" }\n"
-" if {$item == \"debug_gui\"} {\n"
-" return 1\n"
-" }\n"
-" return 0\n"
-" }\n"
-"\n"
-" if {[opt_match G $item]} {\n"
-" return 1\n"
-" } elseif {[opt_match S $item]} {\n"
-" return 1\n"
-" } elseif {[opt_match R $item]} {\n"
-" return 0\n"
-" } elseif {[is_action $item]} {\n"
-" if {[opt_match S $item]} {\n"
-" return 1\n"
-" } else {\n"
-" return 0\n"
-" }\n"
-" } elseif {[info exists helptext($item)]} {\n"
-" return 1\n"
-" } else {\n"
-" return 0\n"
-" }\n"
-"}\n"
-"\n"
-"proc help_win {item} {\n"
-" global helptext helpremote menu_var\n"
-" global query_ans query_aro\n"
-" global beginner_mode\n"
-"\n"
-" set ok 0\n"
-" set text \"Help on $item:\\n\\n\"\n"
-"\n"
-" if {$item == \"NewClient\"} {\n"
-" ;\n"
-" } elseif {[is_gui_internal $item]} {\n"
-" if {$item != \"gui\" && $item != \"all\" && $item != \"Misc-Tuning:\" \\\n"
-" && $item != \"Properties\" && $item != \"Tray\"} {\n"
-" append text \" + Is a gui internal Action (cannot be set).\\n\";\n"
-" }\n"
-" } elseif {[is_action $item]} {\n"
-" append text \" + Is a remote control Action (cannot be set).\\n\";\n"
-" } elseif {[active_when_connected $item]} {\n"
-" append text \" + Can be changed in a running x11vnc.\\n\";\n"
-" } else {\n"
-" append text \" - Cannot be changed in a running x11vnc.\\n\";\n"
-" }\n"
-" if {$item == \"NewClient\"} {\n"
-" ;\n"
-" } elseif {[is_gui_internal $item]} {\n"
-" ;\n"
-" } elseif {[active_when_starting $item]} {\n"
-" append text \" + Can be set at x11vnc startup.\\n\";\n"
-" } else {\n"
-" if {! $beginner_mode} {\n"
-" append text \" - Cannot be set at x11vnc startup.\\n\";\n"
-" }\n"
-" }\n"
-" append text \"\\n\"\n"
-"\n"
-" if {[info exists helptext($item)]} {\n"
-" append text \"\\n\"\n"
-" if {[is_gui_internal $item]} {\n"
-" append text \"==== x11vnc help: ====\\n\";\n"
-" } else {\n"
-" append text \"==== x11vnc startup option help: ====\\n\";\n"
-" }\n"
-" append text \"\\n\"\n"
-" append text $helptext($item)\n"
-" append text \"\\n\"\n"
-" set ok 1\n"
-" }\n"
-"\n"
-" if {[info exists helpremote($item)]} {\n"
-" append text \"\\n\"\n"
-" append text \"==== x11vnc remote control help: ====\\n\";\n"
-" append text \"\\n\"\n"
-" append text $helpremote($item)\n"
-" set ok 1\n"
-" }\n"
-"\n"
-" if {![is_action $item] && [info exists menu_var($item)]} {\n"
-" global unset_str\n"
-" append text \"\\n\\n\"\n"
-" append text \"==== current $item value: ====\\n\";\n"
-" append text \"\\n\"\n"
-"\n"
-" if {$item == \"passwd\" || $item == \"viewpasswd\"} {\n"
-" ;\n"
-" } elseif {$menu_var($item) == \"\"} {\n"
-" append text \"$unset_str\\n\"\n"
-" } else {\n"
-" append text \"$menu_var($item)\\n\"\n"
-" }\n"
-" if {$item == \"http\" || $item == \"httpdir\" || $item == \"httpport\"} {\n"
-" global vnc_url;\n"
-" append text \"\\nURL: $vnc_url\\n\"\n"
-" }\n"
-" }\n"
-"\n"
-" if {$item == \"start\"} {\n"
-" set str [get_start_x11vnc_txt]\n"
-" append_text \"$str\\n\"\n"
-"# append text \"\\nPossible \\$HOME/.x11vncrc settings for this command:\\n\\n\"\n"
-"# set rctxt [get_start_x11vnc_cmd 1]\n"
-"# append text \"$rctxt\\n\"\n"
-" }\n"
-"\n"
-" regsub -all { } $item \" \" name\n"
-"\n"
-" if {$ok} {\n"
-" textwin $name \"x11vnc help: $item\" \"$text\";\n"
-" }\n"
-" return $ok\n"
-"}\n"
-"\n"
-"proc parse_help {} {\n"
-" global env x11vnc_prog;\n"
-" global helpall helptext;\n"
-"\n"
-" set helppipe [open \"| $x11vnc_prog -help\" \"r\"];\n"
-" if {$helppipe == \"\"} {\n"
-" puts stderr \"failed to run $x11vnc_prog -help\";\n"
-" exit 1;\n"
-" }\n"
-"\n"
-" set sawopts 0;\n"
-" set curropt \"\";\n"
-" while {[gets $helppipe line] > -1} {\n"
-" append helpall \"$line\\n\" \n"
-"\n"
-" # XXX\n"
-" if {[regexp {^Options:} $line]} {\n"
-" set sawopts 1;\n"
-" continue;\n"
-" }\n"
-" # XXX\n"
-" if {[regexp {^These options} $line]} {\n"
-" continue;\n"
-" }\n"
-" # tweak aliases:\n"
-" regsub {^-zeroconf} $line \"-zero_conf\" line\n"
-" regsub {^-avahi } $line \"-zeroconf\" line\n"
-"\n"
-" if {! $sawopts} {\n"
-" continue;\n"
-" }\n"
-" if {[regexp {^-([0-9A-z_][0-9A-z_]*)} $line match name]} {\n"
-" set allnames($name) 1;\n"
-" if {\"$curropt\" != \"no$name\" && \"no$curropt\" != \"$name\"} {\n"
-" set curropt $name;\n"
-" set helptext($curropt) \"$line\\n\";\n"
-" } else {\n"
-" append helptext($curropt) \"$line\\n\";\n"
-" }\n"
-" } elseif {$curropt != \"\"} {\n"
-" append helptext($curropt) \"$line\\n\";\n"
-" }\n"
-" }\n"
-" foreach name [array names allnames] {\n"
-" if {[regexp {^no} $name]} {\n"
-" regsub {^no} $name \"\" pair\n"
-" } else {\n"
-" set pair \"no$name\"\n"
-" }\n"
-" if {[info exists helptext($name)]} {\n"
-" if ![info exists helptext($pair)] {\n"
-" set helptext($pair) $helptext($name);\n"
-" }\n"
-" } elseif {[info exists helptext($pair)]} {\n"
-" if ![info exists helptext($name)] {\n"
-" set helptext($name) $helptext($pair);\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" set_internal_help\n"
-"}\n"
-"\n"
-"proc tweak_both {new old} {\n"
-" tweak_help $new $old\n"
-" tweak_remote_help $new $old\n"
-"}\n"
-"\n"
-"proc tweak_remote_help {new old} {\n"
-" global helpremote\n"
-" if ![info exists helpremote($new)] {\n"
-" if {[info exists helpremote($old)]} {\n"
-" set helpremote($new) $helpremote($old)\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc tweak_help {new old} {\n"
-" global helptext\n"
-" if ![info exists helptext($new)] {\n"
-" if {[info exists helptext($old)]} {\n"
-" set helptext($new) $helptext($old)\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc parse_remote_help {} {\n"
-" global helpremote helptext help_indent remote_name;\n"
-"\n"
-" set sawopts 0;\n"
-" set curropt \"\";\n"
-" set possopts \"\";\n"
-" set offset [expr $help_indent - 1];\n"
-" foreach line [split $helptext(remote) \"\\n\"] {\n"
-" \n"
-" set line [string range $line $offset end];\n"
-"\n"
-" # XXX\n"
-" if {[regexp {^The following -remote/-R commands} $line]} {\n"
-" set sawopts 1;\n"
-" continue;\n"
-" }\n"
-" # XXX\n"
-" if {[regexp {^The vncconnect.*command} $line]} {\n"
-" set sawopts 0;\n"
-" }\n"
-"\n"
-" if {! $sawopts} {\n"
-" continue;\n"
-" }\n"
-" if {[regexp {^([0-9A-z_][0-9A-z_:]*)} $line match name]} {\n"
-" regsub {:.*$} $name \"\" popt\n"
-" lappend possopts $popt\n"
-" if {\"$curropt\" != \"no$name\" && \"no$curropt\" != \"$name\"} {\n"
-" set curropt $name;\n"
-" regsub {:.*$} $curropt \"\" curropt\n"
-" set remote_name($curropt) $name\n"
-" set helpremote($curropt) \"$line\\n\";\n"
-" } else {\n"
-" append helpremote($curropt) \"$line\\n\";\n"
-" }\n"
-" } elseif {$curropt != \"\"} {\n"
-" append helpremote($curropt) \"$line\\n\";\n"
-" }\n"
-" }\n"
-"\n"
-" foreach popt $possopts {\n"
-" if {[info exists helpremote($popt)]} {\n"
-" continue\n"
-" }\n"
-" if {[regexp {^no} $popt]} {\n"
-" regsub {^no} $popt \"\" try\n"
-" } else {\n"
-" set try \"no$popt\"\n"
-" }\n"
-" if {[info exists helpremote($try)]} {\n"
-" set helpremote($popt) $helpremote($try)\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc parse_query_help {} {\n"
-" global query_ans query_aro query_ans_list query_aro_list helptext;\n"
-"\n"
-" set sawans 0;\n"
-" set sawaro 0;\n"
-" set ans_str \"\"\n"
-" set aro_str \"\"\n"
-"\n"
-" foreach line [split $helptext(query) \"\\n\"] {\n"
-"\n"
-" if {! $sawans && [regexp {^ *ans=} $line]} {\n"
-" set sawans 1\n"
-" }\n"
-" if {! $sawans} {\n"
-" continue\n"
-" }\n"
-"\n"
-" if {[regexp {^ *aro=} $line]} {\n"
-" set sawaro 1\n"
-" }\n"
-" if {$sawaro && [regexp {^[ ]*$} $line]} {\n"
-" set sawans 0\n"
-" break\n"
-" }\n"
-"\n"
-" regsub {ans=} $line \"\" line\n"
-" regsub {aro=} $line \"\" line\n"
-" set line [string trim $line]\n"
-"\n"
-" if {$sawaro} {\n"
-" set aro_str \"$aro_str $line\"\n"
-" } else {\n"
-" set ans_str \"$ans_str $line\"\n"
-" }\n"
-" }\n"
-"\n"
-" regsub -all { *} $ans_str \" \" ans_str\n"
-" regsub -all { *} $aro_str \" \" aro_str\n"
-"\n"
-" set ans_str [string trim $ans_str]\n"
-" set aro_str [string trim $aro_str]\n"
-" set query_ans_list [split $ans_str]\n"
-" set query_aro_list [split $aro_str]\n"
-"\n"
-" foreach item $query_ans_list {\n"
-" if {[regexp {^[ ]*$} $item]} {\n"
-" continue\n"
-" }\n"
-" set query_ans($item) 1\n"
-" }\n"
-" foreach item $query_aro_list {\n"
-" if {[regexp {^[ ]*$} $item]} {\n"
-" continue\n"
-" }\n"
-" set query_aro($item) 1\n"
-" }\n"
-"}\n"
-"\n"
-"proc in_debug_mode {} {\n"
-" global menu_var\n"
-" if {![info exists menu_var(debug_gui)]} {\n"
-" return 0\n"
-" }\n"
-" return $menu_var(debug_gui)\n"
-"}\n"
-"\n"
-"# Menubar utilities:\n"
-"proc menus_state {state} {\n"
-" global menu_b\n"
-"\n"
-" foreach case [array names menu_b] {\n"
-" set menu_button $menu_b($case)\n"
-" if {![winfo exists $menu_button]} {\n"
-" continue\n"
-" }\n"
-" $menu_button configure -state $state\n"
-" }\n"
-"}\n"
-"\n"
-"proc menus_enable {} {\n"
-" global menus_disabled\n"
-"\n"
-" menus_state \"normal\"\n"
-" set menus_disabled 0\n"
-"}\n"
-"\n"
-"proc menus_disable {} {\n"
-" global menus_disabled\n"
-"\n"
-" set menus_disabled 1\n"
-" menus_state \"disabled\"\n"
-"}\n"
-"\n"
-"# Entry box utilities:\n"
-"proc entry_state {x state} {\n"
-" global entry_box entry_label entry_ok entry_help entry_skip entry_browse\n"
-" global old_labels\n"
-" if {$x == \"all\"} {\n"
-" if {!$old_labels} {\n"
-" $entry_label configure -state $state\n"
-" }\n"
-" $entry_box configure -state $state\n"
-" $entry_ok configure -state $state\n"
-" $entry_skip configure -state $state\n"
-" $entry_help configure -state $state\n"
-" $entry_browse configure -state $state\n"
-" } elseif {$x == \"label\"} {\n"
-" if {!$old_labels} {\n"
-" $entry_label configure -state $state\n"
-" }\n"
-" } elseif {$x == \"box\"} {\n"
-" $entry_box configure -state $state\n"
-" } elseif {$x == \"ok\"} {\n"
-" $entry_ok configure -state $state\n"
-" } elseif {$x == \"skip\"} {\n"
-" $entry_skip configure -state $state\n"
-" } elseif {$x == \"help\"} {\n"
-" $entry_help configure -state $state\n"
-" } elseif {$x == \"browse\"} {\n"
-" $entry_browse configure -state $state\n"
-" }\n"
-"}\n"
-"\n"
-"proc entry_enable {{x \"all\"}} {\n"
-" entry_state $x normal\n"
-"}\n"
-"\n"
-"proc entry_disable {{x \"all\"}} {\n"
-" entry_state $x disabled\n"
-"}\n"
-"\n"
-"proc entry_browse_button {{show 1}} {\n"
-" global entry_browse\n"
-" if {$show} {\n"
-" pack $entry_browse -side left\n"
-" } else {\n"
-" pack forget $entry_browse\n"
-" }\n"
-"}\n"
-"proc entry_focus {} {\n"
-" global entry_box\n"
-" focus $entry_box\n"
-"}\n"
-"proc entry_select {} {\n"
-" global entry_box\n"
-" $entry_box selection range 0 end\n"
-"}\n"
-"proc entry_get {} {\n"
-" global entry_box\n"
-" return [$entry_box get]\n"
-"}\n"
-"proc entry_insert {str} {\n"
-" global entry_box\n"
-" entry_delete\n"
-" $entry_box insert end $str\n"
-" $entry_box icursor end\n"
-"}\n"
-"proc entry_delete {} {\n"
-" global entry_box\n"
-" $entry_box delete 0 end\n"
-"}\n"
-"\n"
-"\n"
-"# Utilities for remote control and updating vars.\n"
-"\n"
-"proc push_new_value {item name new {query 1}} {\n"
-" global menu_var always_update remote_output query_output\n"
-" global query_result_list\n"
-"\n"
-" set debug [in_debug_mode]\n"
-"\n"
-" set getout 0\n"
-" set print_getout 0;\n"
-"\n"
-" set do_query_all 0\n"
-"\n"
-" set newnew \"\"\n"
-" if {$item == \"disconnect\"} {\n"
-" set newnew \"N/A\"\n"
-" set do_query_all 1\n"
-" } elseif {$always_update} {\n"
-" set do_query_all 1\n"
-" }\n"
-"\n"
-" if {$item == \"remote-cmd\"} {\n"
-" # kludge for arbitrary remote command:\n"
-" if {[regexp {^Q:} $new]} {\n"
-" # extra kludge for Q:var to mean -Q var\n"
-" regsub {^Q:} $new \"\" new\n"
-" set qonly 1\n"
-" } else {\n"
-" set qonly 0\n"
-" }\n"
-" # need to extract item from new:\n"
-" set qtmp $new\n"
-" regsub {:.*$} $qtmp \"\" qtmp\n"
-" if {$qonly} {\n"
-" set rargs [list \"-Q\" \"$qtmp\"]\n"
-" set print_getout 1\n"
-" set qargs \"\"\n"
-" } else {\n"
-" set rargs [list \"-R\" \"$new\"]\n"
-" set qargs \"\"\n"
-" }\n"
-" set getout 1\n"
-"\n"
-" } elseif {[value_is_string $item]} {\n"
-" # string var:\n"
-" set rargs [list \"-R\" \"$name:$new\"]\n"
-" set qargs [list \"-Q\" \"$name\"]\n"
-" } else {\n"
-" # boolean var:\n"
-" set rargs [list \"-R\" \"$name\"]\n"
-" set qargs [list \"-Q\" \"$name\"]\n"
-" }\n"
-"\n"
-" if {! $query && ! $always_update} {\n"
-" set getout 1\n"
-" } elseif {$item == \"noremote\"} {\n"
-" set getout 1\n"
-" } elseif {[is_action $item] && ![opt_match Q $item] && $rargs != \"\"} {\n"
-" set getout 1\n"
-" } elseif {[regexp {^(sid|id)$} $item] && ![regexp {^0x} $new]} {\n"
-" set getout 1\n"
-" }\n"
-"\n"
-" set remote_output \"\"\n"
-" set query_output \"\"\n"
-"\n"
-" if {!$debug} {\n"
-" if [regexp {passwd} $rargs] {\n"
-" append_text \"x11vnc ...\"\n"
-" } else {\n"
-" append_text \"x11vnc $rargs ...\"\n"
-" }\n"
-" }\n"
-"\n"
-" if {$getout} {\n"
-" set remote_output [run_remote_cmd $rargs]\n"
-" if {$print_getout} {\n"
-" append_text \"\\t$remote_output\"\n"
-" }\n"
-" append_text \"\\n\"\n"
-" return\n"
-" }\n"
-"\n"
-" if {$do_query_all} {\n"
-" set all [all_query_vars]\n"
-" set qargs [list \"-Q\" $all]\n"
-"\n"
-" global last_query_all_time\n"
-" set last_query_all_time [clock seconds]\n"
-" }\n"
-"\n"
-" set rqargs [concat $rargs $qargs]\n"
-"\n"
-" set query [run_remote_cmd $rqargs]\n"
-" set query_output $query\n"
-"\n"
-" set query_result_list \"\"\n"
-"\n"
-" if {$newnew != \"\"} {\n"
-" set new $newnew\n"
-" }\n"
-"\n"
-" if {![see_if_ok $query $item \"$name:$new\"]} {\n"
-" # failed\n"
-" if {[regexp {^a..=} $query]} {\n"
-" # but some result came back\n"
-" # synchronize everything with a 2nd call.\n"
-" set query_output [query_all 1]\n"
-" } else {\n"
-" # server may be dead\n"
-" if {$item != \"ping\" && $item != \"attach\"} {\n"
-" try_connect\n"
-" }\n"
-" }\n"
-" } else {\n"
-" # succeeded\n"
-" # synchronize this variable (or variables)\n"
-" # for a speedup used the list parsed by see_if_ok.\n"
-" update_menu_vars \"USE_LIST\"\n"
-"\n"
-" if {$do_query_all} {\n"
-" global all_settings\n"
-" set all_settings $query\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc set_kmbc_str {} {\n"
-" global vl_bk vl_bm vl_bb vl_bc vl_bf vr_bk vr_bm vr_bb vr_bc vr_bf\n"
-"\n"
-" set str \"\"\n"
-" if {$vl_bk} {\n"
-" append str \"K\"\n"
-" }\n"
-" if {$vl_bm} {\n"
-" append str \"M\"\n"
-" }\n"
-" if {$vl_bb} {\n"
-" append str \"B\"\n"
-" }\n"
-" if {$vl_bc} {\n"
-" append str \"C\"\n"
-" }\n"
-" if {$vl_bf} {\n"
-" append str \"F\"\n"
-" }\n"
-" if {$vr_bk || $vr_bm || $vr_bb || $vr_bc || $vr_bf} {\n"
-" append str \",\"\n"
-" }\n"
-" if {$vr_bk} {\n"
-" append str \"K\"\n"
-" }\n"
-" if {$vr_bm} {\n"
-" append str \"M\"\n"
-" }\n"
-" if {$vr_bb} {\n"
-" append str \"B\"\n"
-" }\n"
-" if {$vr_bc} {\n"
-" append str \"C\"\n"
-" }\n"
-" if {$vr_bf} {\n"
-" append str \"F\"\n"
-" }\n"
-" entry_insert $str\n"
-"}\n"
-"\n"
-"proc insert_input_window {} {\n"
-" global text_area cleanup_window\n"
-" global ffont menu_var\n"
-" global vl_bk vl_bm vl_bb vl_bc vl_bf vr_bk vr_bm vr_bb vr_bc vr_bf\n"
-"\n"
-" append_text \"\\nUse these checkboxes to set the input permissions, \"\n"
-" append_text \"or type in the \\\"KMBCF...\\\"\\n\"\n"
-" append_text \"-input string manually. Then press \\\"OK\\\" or \\\"Cancel\\\".\\n\"\n"
-" append_text \"(note: an empty setting means use the default behavior, \"\n"
-" append_text \"see viewonly)\\n\\n\"\n"
-" set w \"$text_area.wk_f\"\n"
-" catch {destroy $w}\n"
-" frame $w -bd 1 -relief ridge -cursor {top_left_arrow}\n"
-" set fl $w.fl\n"
-" frame $fl\n"
-" set fr $w.fr\n"
-" frame $fr\n"
-" label $fl.l -font $ffont -text \"Normal clients: \"\n"
-" checkbutton $fl.bk -pady 1 -font $ffont -anchor w -variable vl_bk \\\n"
-" -pady 1 -command set_kmbc_str -text \"Keystrokes\" \n"
-" checkbutton $fl.bm -font $ffont -anchor w -variable vl_bm \\\n"
-" -pady 1 -command set_kmbc_str -text \"Mouse-Motion\" \n"
-" checkbutton $fl.bb -font $ffont -anchor w -variable vl_bb \\\n"
-" -pady 1 -command set_kmbc_str -text \"Button-Click\"\n"
-" checkbutton $fl.bc -font $ffont -anchor w -variable vl_bc \\\n"
-" -pady 1 -command set_kmbc_str -text \"Clipboard-Input\"\n"
-" checkbutton $fl.bf -font $ffont -anchor w -variable vl_bf \\\n"
-" -pady 1 -command set_kmbc_str -text \"Files\"\n"
-" label $fr.l -pady 1 -font $ffont -text \"View-Only clients:\"\n"
-" checkbutton $fr.bk -font $ffont -anchor w -variable vr_bk \\\n"
-" -pady 1 -command set_kmbc_str -text \"Keystrokes\" \n"
-" checkbutton $fr.bm -font $ffont -anchor w -variable vr_bm \\\n"
-" -pady 1 -command set_kmbc_str -text \"Mouse-Motion\" \n"
-" checkbutton $fr.bb -font $ffont -anchor w -variable vr_bb \\\n"
-" -pady 1 -command set_kmbc_str -text \"Button-Click\"\n"
-" checkbutton $fr.bc -font $ffont -anchor w -variable vr_bc \\\n"
-" -pady 1 -command set_kmbc_str -text \"Clipboard-Input\"\n"
-" checkbutton $fr.bf -font $ffont -anchor w -variable vr_bf \\\n"
-" -pady 1 -command set_kmbc_str -text \"Files\"\n"
-"\n"
-" if {[info exists menu_var(input)]} {\n"
-" set input_str $menu_var(input)\n"
-" } else {\n"
-" set input_str \"\"\n"
-" }\n"
-"\n"
-" if {[regexp {(.*),(.*)} $input_str match normal viewonly]} {\n"
-" ;\n"
-" } else {\n"
-" set normal $input_str\n"
-" set viewonly \"\"\n"
-" }\n"
-" set vl_bk 0\n"
-" set vl_bm 0\n"
-" set vl_bb 0\n"
-" set vl_bc 0\n"
-" set vl_bf 0\n"
-"\n"
-" set vr_bk 0\n"
-" set vr_bm 0\n"
-" set vr_bb 0\n"
-" set vr_bc 0\n"
-" set vr_bf 0\n"
-"\n"
-" if {[regexp -nocase {K} $normal]} {\n"
-" set vl_bk 1\n"
-" }\n"
-" if {[regexp -nocase {M} $normal]} {\n"
-" set vl_bm 1\n"
-" }\n"
-" if {[regexp -nocase {B} $normal]} {\n"
-" set vl_bb 1\n"
-" }\n"
-" if {[regexp -nocase {C} $normal]} {\n"
-" set vl_bc 1\n"
-" }\n"
-" if {[regexp -nocase {F} $normal]} {\n"
-" set vl_bf 1\n"
-" }\n"
-" if {[regexp -nocase {K} $viewonly]} {\n"
-" set vr_bk 1\n"
-" }\n"
-" if {[regexp -nocase {M} $viewonly]} {\n"
-" set vr_bm 1\n"
-" }\n"
-" if {[regexp -nocase {B} $viewonly]} {\n"
-" set vr_bb 1\n"
-" }\n"
-" if {[regexp -nocase {C} $viewonly]} {\n"
-" set vr_bc 1\n"
-" }\n"
-" if {[regexp -nocase {F} $viewonly]} {\n"
-" set vr_bf 1\n"
-" }\n"
-"\n"
-" pack $fl.l $fl.bk $fl.bm $fl.bb $fl.bc $fl.bf -side top -fill x\n"
-" pack $fr.l $fr.bk $fr.bm $fr.bb $fr.bc $fr.bf -side top -fill x\n"
-" pack $fl $fr -side left\n"
-" update\n"
-" update idletasks\n"
-" $text_area window create end -window $w\n"
-" $text_area see end\n"
-" $text_area insert end \"\\n\"\n"
-"# $text_area insert end \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\"\n"
-"\n"
-" set cleanup_window $w\n"
-"}\n"
-"\n"
-"proc set_ca_str {w} {\n"
-" global ca_bk ca_bm ca_bb ca_bc ca_bf ca_di\n"
-"\n"
-" if {$ca_di} {\n"
-" entry_insert \"disconnect\"\n"
-" $w.bk configure -state disabled\n"
-" $w.bm configure -state disabled\n"
-" $w.bb configure -state disabled\n"
-" $w.bc configure -state disabled\n"
-" $w.bf configure -state disabled\n"
-" return\n"
-" }\n"
-"\n"
-" $w.bk configure -state normal\n"
-" $w.bm configure -state normal\n"
-" $w.bb configure -state normal\n"
-" $w.bc configure -state normal\n"
-" $w.bf configure -state normal\n"
-"\n"
-" set str \"\"\n"
-" if {$ca_bk} {\n"
-" append str \"K\"\n"
-" }\n"
-" if {$ca_bm} {\n"
-" append str \"M\"\n"
-" }\n"
-" if {$ca_bb} {\n"
-" append str \"B\"\n"
-" }\n"
-" if {$ca_bc} {\n"
-" append str \"C\"\n"
-" }\n"
-" if {$ca_bf} {\n"
-" append str \"F\"\n"
-" }\n"
-" entry_insert $str\n"
-"}\n"
-"\n"
-"proc insert_client_action_window {input} {\n"
-" global text_area cleanup_window\n"
-" global ffont menu_var\n"
-" global ca_bk ca_bm ca_bb ca_bc ca_bf ca_di\n"
-"\n"
-" append_text \"\\nUse these checkboxes to set the input permissions \"\n"
-" append_text \"for this client\\n-OR- whether to disconnect it instead. \"\n"
-" append_text \"Then press \\\"OK\\\" or \\\"Cancel\\\".\\n\\n\"\n"
-" set w \"$text_area.ca_f\"\n"
-" catch {destroy $w}\n"
-" frame $w -bd 1 -relief ridge -cursor {top_left_arrow}\n"
-" checkbutton $w.di -pady 1 -font $ffont -anchor w -variable ca_di \\\n"
-" -pady 1 -command \"set_ca_str $w\" -text \"Disconnect \" \n"
-" checkbutton $w.bk -font $ffont -anchor w -variable ca_bk \\\n"
-" -pady 1 -command \"set_ca_str $w\" -text \"Keystrokes\" \n"
-" checkbutton $w.bm -font $ffont -anchor w -variable ca_bm \\\n"
-" -pady 1 -command \"set_ca_str $w\" -text \"Mouse-Motion\" \n"
-" checkbutton $w.bb -font $ffont -anchor w -variable ca_bb \\\n"
-" -pady 1 -command \"set_ca_str $w\" -text \"Button-Click\"\n"
-" checkbutton $w.bc -font $ffont -anchor w -variable ca_bc \\\n"
-" -pady 1 -command \"set_ca_str $w\" -text \"Clipboard\"\n"
-" checkbutton $w.bf -font $ffont -anchor w -variable ca_bf \\\n"
-" -pady 1 -command \"set_ca_str $w\" -text \"Files\"\n"
-"\n"
-" set ca_di 0\n"
-" set ca_bk 0\n"
-" set ca_bm 0\n"
-" set ca_bb 0\n"
-" set ca_bf 0\n"
-" set ca_bc 0\n"
-"\n"
-" if {[regexp -nocase {K} $input]} {\n"
-" set ca_bk 1\n"
-" }\n"
-" if {[regexp -nocase {M} $input]} {\n"
-" set ca_bm 1\n"
-" }\n"
-" if {[regexp -nocase {B} $input]} {\n"
-" set ca_bb 1\n"
-" }\n"
-" if {[regexp -nocase {C} $input]} {\n"
-" set ca_bc 1\n"
-" }\n"
-" if {[regexp -nocase {F} $input]} {\n"
-" set ca_bf 1\n"
-" }\n"
-"\n"
-" pack $w.di $w.bk $w.bm $w.bb $w.bc $w.bf -side left\n"
-" update\n"
-" update idletasks\n"
-" $text_area window create end -window $w\n"
-" $text_area see end\n"
-" $text_area insert end \"\\n\"\n"
-"\n"
-" set cleanup_window $w\n"
-"}\n"
-"\n"
-"proc cleanup_text_window {} {\n"
-" global cleanup_window\n"
-" if {[info exists cleanup_window]} {\n"
-" catch {destroy $cleanup_window}\n"
-" }\n"
-"}\n"
-"\n"
-"# For updating a string variable. Also used for simple OK/Cancel dialogs\n"
-"# with entry = 0.\n"
-"proc entry_dialog {item {entry 1}} {\n"
-" global menu_var entry_str entry_set entry_dialog_item\n"
-" global unset_str connected_to_x11vnc entry_box\n"
-"\n"
-" set entry_str \"Set $item\"\n"
-" set entry_set 0\n"
-" set entry_dialog_item $item\n"
-"\n"
-" entry_enable\n"
-" menus_disable\n"
-"\n"
-" if {$item == \"passwd\" || $item == \"viewpasswd\"} {\n"
-" $entry_box configure -show \"*\"\n"
-" }\n"
-"\n"
-" if {$entry} {\n"
-" entry_insert \"\"\n"
-" if {[info exists menu_var($item)] &&\n"
-" $menu_var($item) != $unset_str} {\n"
-" entry_insert $menu_var($item)\n"
-" entry_select\n"
-" }\n"
-"\n"
-" if {[is_browse $item]} {\n"
-" entry_browse_button\n"
-" }\n"
-" set_info \"Set parameter in entry box, \"\n"
-" entry_focus\n"
-" } else {\n"
-" entry_disable box\n"
-" }\n"
-"\n"
-" set clean_text_window 0;\n"
-"\n"
-" if {$item == \"input\"} {\n"
-" insert_input_window\n"
-" set clean_text_window 1\n"
-" }\n"
-"\n"
-" update\n"
-"\n"
-" # wait for user reply:\n"
-" vwait entry_set\n"
-"\n"
-" set rc $entry_set\n"
-" set entry_set 0\n"
-"\n"
-" set value [entry_get]\n"
-" update\n"
-"\n"
-" entry_browse_button 0\n"
-" set entry_str \"Set... :\"\n"
-"\n"
-" entry_delete\n"
-" entry_disable\n"
-" menus_enable\n"
-"\n"
-" if {$clean_text_window} {\n"
-" cleanup_text_window;\n"
-" }\n"
-"\n"
-" update\n"
-"\n"
-" if {! $entry} {\n"
-" ;\n"
-" } elseif {$rc} {\n"
-" set menu_var($item) $value\n"
-" } else {\n"
-" if {[in_debug_mode]} {\n"
-" append_text \"skipped setting $item\\n\"\n"
-" }\n"
-" }\n"
-"\n"
-" $entry_box configure -show \"\"\n"
-"\n"
-" return $rc\n"
-"}\n"
-"\n"
-"proc warning_dialog {msg {item \"gui\"} } {\n"
-" append_text $msg\n"
-" # just reuse the entry widgets for a yes/no dialog\n"
-" return [entry_dialog $item 0]\n"
-"}\n"
-"\n"
-"# For updating a boolean toggle:\n"
-"proc check_var {item} {\n"
-" global menu_var\n"
-"\n"
-" set inval $menu_var($item);\n"
-"\n"
-" if {$item == \"debug_gui\"} {\n"
-" return \"\";\n"
-" }\n"
-"\n"
-" set rname $item\n"
-" if {! $inval} {\n"
-" if {[regexp {^no} $item]} {\n"
-" regsub {^no} $rname \"\" rname\n"
-" } else {\n"
-" set rname \"no$rname\"\n"
-" }\n"
-" }\n"
-" return $rname\n"
-"}\n"
-"\n"
-"proc see_if_ok {query item expected} {\n"
-" global query_result_list\n"
-"\n"
-" set ok 0\n"
-" set found \"\"\n"
-"\n"
-" set query_result_list [split_query $query]\n"
-"\n"
-" foreach q $query_result_list {\n"
-" # XXX following will crash if $item is not a good regexp\n"
-" # need to protect it \\Q$item\\E style...\n"
-"# if {[regexp \"^$item:\" $q]} {\n"
-"# set found $q\n"
-"# }\n"
-" if {[string first \"$item:\" $q] == 0} {\n"
-" set found $q\n"
-" }\n"
-" if {$q == $expected} {\n"
-" set ok 1\n"
-" if {$found != \"\"} {\n"
-" break;\n"
-" }\n"
-" }\n"
-" }\n"
-" if {$found == \"\"} {\n"
-" set msg $query\n"
-" regsub {^a..=} $msg {} msg\n"
-" if {[string length $msg] > 60} {\n"
-" set msg [string range $msg 0 60]\n"
-" }\n"
-" } else {\n"
-" set msg $found\n"
-" }\n"
-" if {!$ok && $found != \"\"} {\n"
-" # check for floating point match:\n"
-" set v1 \"\"\n"
-" set v2 \"\"\n"
-" regexp {:([0-9.][0-9.]*)$} $found m0 v1\n"
-" regexp {:([0-9.][0-9.]*)$} $expected m0 v2\n"
-" if {$v1 != \"\" && $v2 != \"\"} {\n"
-" set diff \"\"\n"
-" catch {set diff [expr \"$v1 - $v2\"]}\n"
-" if {$diff != \"\"} {\n"
-" if {$diff < 0} {\n"
-" set diff [expr \"0.0 - $diff\"]\n"
-" }\n"
-" if {$diff < 0.00001} {\n"
-" set ok 1\n"
-" }\n"
-" }\n"
-" }\n"
-" }\n"
-" if {$ok} {\n"
-" append_text \"\\tSet OK ($msg)\\n\"\n"
-" return 1\n"
-"\n"
-" } elseif {[opt_match P $item] && [regexp {:(-|\\+)} $expected]} {\n"
-" # e.g. blackout:+30x30+20+20\n"
-" append_text \"\\t($msg)\\n\"\n"
-" return 1\n"
-" } elseif {[regexp {:[0-9]\\.[0-9]} $expected]} {\n"
-" append_text \"\\t($msg)\\n\"\n"
-" return 1\n"
-" } elseif {$item == \"connect\" || $item == \"disconnect\"\n"
-" || $item == \"client\" || $item == \"client_input\"} {\n"
-" append_text \"\\t($msg)\\n\"\n"
-" return 1\n"
-" } elseif {$item == \"passwd\" || $item == \"viewpasswd\"} {\n"
-" append_text \"\\t($msg)\\n\"\n"
-" return 1\n"
-" } else {\n"
-" append_text \"\\t*FAILED* $msg\\n\"\n"
-" return 0\n"
-" }\n"
-"}\n"
-"\n"
-"proc get_default_vars {} {\n"
-" global default_var env\n"
-"\n"
-" set qry [all_query_vars]\n"
-"\n"
-" append qry \",vncconnect\"\n"
-"\n"
-" set q \"\"\n"
-" set i 0\n"
-" set all \"\"\n"
-" foreach s [split $qry \",\"] {\n"
-" if {$q != \"\"} {\n"
-" append q \",\"\n"
-" }\n"
-" append q $s\n"
-" incr i\n"
-" if {$i > 50} {\n"
-" set qargs [list \"-QD\" $q]\n"
-" set a [run_remote_cmd $qargs]\n"
-" if [info exists env(TKX11VNC_PRINT_ALL_QD)] {\n"
-" puts $q\n"
-" puts $a\n"
-" puts \"---------------\"\n"
-" }\n"
-" if {$all != \"\"} {\n"
-" append all \",\"\n"
-" }\n"
-" append all $a\n"
-" set q \"\"\n"
-" set i 0\n"
-" }\n"
-" }\n"
-" if {$q != \"\"} {\n"
-" set qargs [list \"-QD\" $q]\n"
-" set a [run_remote_cmd $qargs]\n"
-" if [info exists env(TKX11VNC_PRINT_ALL_QD)] {\n"
-" puts $q\n"
-" puts $a\n"
-" puts \"---------------\"\n"
-" }\n"
-" if {$all != \"\"} {\n"
-" append all \",\"\n"
-" }\n"
-" append all $a\n"
-" }\n"
-"\n"
-"# old way, qry too long...\n"
-"# set qargs [list \"-QD\" $qry]\n"
-"# set all [run_remote_cmd $qargs]\n"
-"\n"
-" if {[regexp {ans=} $all]} {\n"
-" #append_text \"Retrieved all default settings.\\n\"\n"
-" } else {\n"
-" #append_text \"Failed to retrieve default settings.\\n\"\n"
-" }\n"
-"\n"
-" set query_result_list [split_query $all]\n"
-"\n"
-" set default_var(gui) \"\"\n"
-"\n"
-" foreach piece $query_result_list {\n"
-" if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {\n"
-" if {$val == \"N/A\"} {\n"
-" if {$item == \"vncconnect\"} {\n"
-" set val 1\n"
-" } else {\n"
-" set val \"\"\n"
-" }\n"
-" }\n"
-" if {$item == \"display\"} {\n"
-" set val \"\"\n"
-" } elseif {$item == \"desktop\"} {\n"
-" set val \"\"\n"
-" } elseif {$item == \"auth\"} {\n"
-" set val \"\"\n"
-" } elseif {$item == \"gui\"} {\n"
-" continue\n"
-" } \n"
-" # some hacks we do here for now..\n"
-" if {$item == \"cursor\" && $val == \"\"} {\n"
-" set val \"most\"\n"
-" } elseif {$item == \"scrollcopyrect\" && $val == \"\"} {\n"
-" set val \"always\"\n"
-" } elseif {$item == \"wirecopyrect\" && $val == \"\"} {\n"
-" set val \"always\"\n"
-"# } elseif {$item == \"overlay_nocursor\" && $val == 0} {\n"
-"# set val 1\n"
-" }\n"
-"\n"
-" set default_var($item) $val\n"
-"#puts \"default: $item -> $val\"\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc tilde_expand {file} {\n"
-" global env\n"
-" if {[file exists $file]} {\n"
-" return $file\n"
-" }\n"
-"\n"
-" set user \"\"\n"
-" if {[info exists env(USER)]} {\n"
-" set user $env(USER)\n"
-" }\n"
-" if {$user == \"\" && [info exists env(LOGNAME)]} {\n"
-" set user $env(LOGNAME)\n"
-" }\n"
-"\n"
-" set home \"\"\n"
-" if {[info exists env(HOME)]} {\n"
-" set home $env(HOME)\n"
-" } elseif {$user != \"\"} {\n"
-" set home \"/home/$user\"\n"
-" }\n"
-"\n"
-" if {[regexp {^~} $file]} {\n"
-" if {[regexp {^~/} $file]} {\n"
-" if {$home != \"\"} {\n"
-" regsub {^~} $file $home file\n"
-" }\n"
-" } else {\n"
-" regsub {^~} $file \"/home/\" file\n"
-" }\n"
-" }\n"
-" return $file\n"
-"}\n"
-"\n"
-"proc insert_cmdline_vars {} {\n"
-" global env cmd_var menu_var default_var x11vnc_cmdline\n"
-" if {![info exists x11vnc_cmdline]} {\n"
-" return\n"
-" }\n"
-" if {$x11vnc_cmdline == \"\"} {\n"
-" return\n"
-" }\n"
-" set cmd_var(novar) 1 \n"
-" set str [string trim $x11vnc_cmdline]\n"
-"\n"
-" while {[regexp -- {^-} $str]} {\n"
-" if {[regexp -- {^--*([^ \\t][^ \\t]*)(.*)$} $str m var rest]} {\n"
-" set rest [string trim $rest]\n"
-" set var [string trim $var]\n"
-" if {[regexp {^\\{\\{([^\\}]*)\\}\\}(.*)} $rest m val rest]} {\n"
-" set str [string trim $rest]\n"
-" set cmd_var($var) $val\n"
-" } else {\n"
-" set str $rest\n"
-" set cmd_var($var) \"boolean\"\n"
-" }\n"
-" } else {\n"
-" break\n"
-" }\n"
-" }\n"
-"\n"
-" if {[info exists cmd_var(rc)]} {\n"
-" load_settings $cmd_var(rc)\n"
-" } elseif {[info exists cmd_var(norc)]} {\n"
-" ;\n"
-" } else {\n"
-" set filex [tilde_expand \"~/.x11vncrc\"]\n"
-" if {[file exists $filex]} {\n"
-" load_settings $filex\n"
-" }\n"
-" }\n"
-"\n"
-" foreach var [array names cmd_var] {\n"
-" if {$var == \"novar\"} {\n"
-" continue\n"
-" }\n"
-" if {[regexp {^[ \\t]*$} $var]} {\n"
-" continue\n"
-" }\n"
-" if {[info exists menu_var($var)]} {\n"
-" if {$cmd_var($var) == \"boolean\"} {\n"
-" set menu_var($var) 1\n"
-" } else {\n"
-" set menu_var($var) $cmd_var($var)\n"
-" }\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc copy_default_vars {} {\n"
-" global menu_var default_var\n"
-" foreach item [array names default_var] {\n"
-" if {[info exists menu_var($item)]} {\n"
-" if {[info exists default_var($item)]} {\n"
-" set menu_var($item) $default_var($item)\n"
-" }\n"
-" }\n"
-" }\n"
-" foreach item [array names menu_var] {\n"
-" if {[info exists default_var($item)]} {\n"
-" set menu_var($item) $default_var($item)\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc update_menu_vars {{query \"\"}} {\n"
-" global all_settings menu_var query_result_list\n"
-" global x11vnc_icon_mode\n"
-"\n"
-" set debug [in_debug_mode]\n"
-"\n"
-" if {$query == \"USE_LIST\"} {\n"
-" ;\n"
-" } elseif {$query == \"\"} {\n"
-" set query_result_list [split_query $all_settings]\n"
-" } else {\n"
-" set query_result_list [split_query $query]\n"
-" }\n"
-"\n"
-" foreach piece $query_result_list {\n"
-"#puts stderr \"UMV: $piece\"\n"
-" if [regexp {icon_mode:0} $piece] {\n"
-" set x11vnc_icon_mode 0\n"
-" #puts stderr \"x11vnc_icon_mode: $x11vnc_icon_mode\"\n"
-" }\n"
-" if [regexp {icon_mode:1} $piece] {\n"
-" set x11vnc_icon_mode 1\n"
-" #puts stderr \"x11vnc_icon_mode: $x11vnc_icon_mode\"\n"
-" }\n"
-" # XXX ipv6\n"
-" if {[regexp {^([^:][^:]*):(.*)$} $piece m0 item val]} {\n"
-" if {[info exists menu_var($item)]} {\n"
-" set old $menu_var($item)\n"
-"#puts stderr \" $old\"\n"
-" if {$val == \"N/A\"} {\n"
-" continue\n"
-" }\n"
-" set menu_var($item) $val\n"
-" }\n"
-" if {$item == \"clients\"} {\n"
-" update_clients_menu $val\n"
-" } elseif {$item == \"display\"} {\n"
-" set_x11_display $val\n"
-" } elseif {$item == \"vncdisplay\"} {\n"
-" set_vnc_display $val\n"
-" } elseif {$item == \"http_url\"} {\n"
-" set_vnc_url $val\n"
-" }\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc load_settings {{file \"\"}} {\n"
-" global menu_var default_var env\n"
-"\n"
-" if {$file == \"\"} {\n"
-" if {![info exists menu_var(load-settings)]} {\n"
-" return\n"
-" }\n"
-" set file $menu_var(load-settings)\n"
-" }\n"
-" if {$file == \"\"} {\n"
-" return\n"
-" }\n"
-"\n"
-" set fh \"\"\n"
-" set filex [tilde_expand $file]\n"
-" catch {set fh [open $filex \"r\"]}\n"
-"\n"
-" if {$fh == \"\"} {\n"
-" append_text \"load_settings: *** failed to open $filex ***\\n\"\n"
-" return\n"
-" }\n"
-" copy_default_vars\n"
-"\n"
-" set str \"\"\n"
-" while {[gets $fh line] > -1} {\n"
-" regsub -all {\\\\#} $line {__QUOTED_HASH__} line\n"
-" if {[regexp {^[ \\t]*#} $line]} {\n"
-" continue\n"
-" }\n"
-" for {set i 0} {$i < 5} {incr i} {\n"
-" regsub {#.*$} $line \"\" line\n"
-" }\n"
-" if {[regexp {^[ \\t]*$} $line]} {\n"
-" continue\n"
-" }\n"
-" regsub -all {__QUOTED_HASH__} $line {#} line\n"
-" if {[regexp {\\\\$} $line]} {\n"
-" regsub {\\\\$} $line \" \" line\n"
-" append str \"$line\"\n"
-" } else {\n"
-" append str \"$line\\n\"\n"
-" }\n"
-" }\n"
-" close $fh\n"
-"\n"
-" set count 0\n"
-" set parms \"\"\n"
-"\n"
-" foreach line [split $str \"\\n\"] {\n"
-" set line [string trim $line]\n"
-" regsub {^--*} $line \"\" line\n"
-" regsub -all {[ \\t][ \\t]*} $line \" \" line\n"
-" set list [split $line]\n"
-" set item [lindex $list 0]\n"
-" set value [lindex $list 1]\n"
-" if {[regexp {^[ \\t]*$} $item]} {\n"
-" continue\n"
-" }\n"
-" if {$item == \"gui\"} {\n"
-" continue\n"
-" }\n"
-" if {[info exists menu_var($item)]} {\n"
-" if {[value_is_bool $item]} {\n"
-" set menu_var($item) 1\n"
-" incr count\n"
-" append parms \" -$item\\n\"\n"
-" } elseif {[value_is_string $item]} {\n"
-" if {$value != \"\"} {\n"
-" set menu_var($item) $value\n"
-" set nitem [get_nitem $item]\n"
-" append parms \" -$nitem $value\\n\"\n"
-" incr count\n"
-" }\n"
-" }\n"
-" }\n"
-" }\n"
-" append_text \"loaded $count parameter settings from $filex\"\n"
-" if {$count > 0} {\n"
-" append_text \":\\n\"\n"
-" append_text $parms\n"
-" } else {\n"
-" append_text \".\\n\"\n"
-" }\n"
-"}\n"
-"\n"
-"proc save_settings {} {\n"
-" set rc_text [get_settings_rcfile]\n"
-"\n"
-" set top \"#\n"
-"# This file is based on the current x11vnc settings and can be used as\n"
-"# as a ~/.x11vncrc defaults file. If saved to another filename, these\n"
-"# settings can be passed to x11vnc at startup via \\\"-rc <filename>\\\".\n"
-"#\n"
-"# The rc file comment character is \\\"#\\\". Use \\\"\\\\#\\\" for the literal char.\n"
-"# You can continue lines using \\\"\\\\\\\" as the last character of a line.\n"
-"#\n"
-"# Lines beginning with \\\"#d\\\" indicate the parameter value is at its default\n"
-"# setting and you probably want to leave it commented out.\n"
-"#\n"
-"# Lines beginning with \\\"#?\\\" indicate parameters you probably do not\n"
-"# want to hardwire to the current setting (uncomment if you want that).\n"
-"# \n"
-"# Some parameters are boolean, e.g. -forever, and take no value; while\n"
-"# the others, e.g. -wait 50, take a string or numerical value.\n"
-"#\n"
-"# For booleans, the line will end with comment \\\"default: on\\\" or\n"
-"# \\\"default: off\\\" indicating the default setting. (Note: often\n"
-"# \\\"-nofoobar\\\" corresponds to option \\\"-foobar\\\" and the former is\n"
-"# \\\"the default\\\", e.g. -norepeat).\n"
-"#\n"
-"# For string or numerical options, the value \\\"\\\" in a line below\n"
-"# means the default is unset and you will need to supply some non-empty\n"
-"# value to use the parameter. For reference, if the default differs\n"
-"# from your value it placed at the end of the line as a comment.\n"
-"# \n"
-"# Feel free to uncomment or comment any of the lines or to change any\n"
-"# of the values of the parameters. Don't be surprised that most if not\n"
-"# all of the lines below are commented out (x11vnc has so many parameters,\n"
-"# most of them will be at their default values).\n"
-"#-------------------------------------------------------------------------\n"
-"\n"
-"\"\n"
-"\n"
-" set rc_text \"$top$rc_text\"\n"
-"\n"
-" global env save_settings_var save_settings_var_ok\n"
-" if {[info exists env(HOME)]} {\n"
-" set save_settings_var \"$env(HOME)/.x11vncrc\"\n"
-" } else {\n"
-" set save_settings_var \".x11vncrc\"\n"
-" }\n"
-" set save_settings_var_ok 0\n"
-"\n"
-" set w [textwin \"save_settings\" \"Save Settings...\" $rc_text \\\n"
-" \"save_settings_var+Save as:\"]\n"
-"\n"
-" tkwait window $w\n"
-"\n"
-" if {$save_settings_var_ok == 1} {\n"
-" set file $save_settings_var\n"
-" if {$file == \"\"} {\n"
-" return\n"
-" }\n"
-" set file [tilde_expand $file]\n"
-" append_text \"\\nSaving current settings to $file ...\\n\" \n"
-" if {[file exists $file]} {\n"
-" set backup \"${file}~\"\n"
-" append_text \"Backing up $file -> $backup ...\\n\"\n"
-" catch {file delete -force $backup}\n"
-" set emsg \"*** Backup to $backup failed. ***\\n\"\n"
-" if {![file exists $backup]} {\n"
-" catch {file copy -force $file $backup}\n"
-" if {![file exists $backup]} {\n"
-" append_text $emsg\n"
-" bell\n"
-" }\n"
-" } else {\n"
-" append_text $emsg\n"
-" bell\n"
-" }\n"
-" }\n"
-" set fh \"\"\n"
-" catch {set fh [open $file \"w\"]}\n"
-" if {$fh != \"\"} {\n"
-" puts $fh $rc_text\n"
-" close $fh\n"
-" if {![file exists $file]} {\n"
-" append_text \"*** Saving to $file failed. ***\\n\"\n"
-" bell\n"
-" } else {\n"
-" append_text \"Done.\\n\"\n"
-" }\n"
-" } else {\n"
-" append_text \"*** Open of $file failed. ***\\n\"\n"
-" bell\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc clear_all {} {\n"
-" global menu_var unset_str\n"
-"\n"
-" set debug [in_debug_mode]\n"
-" \n"
-" foreach item [array names menu_var] {\n"
-" if {$item == \"debug_gui\"} {\n"
-" continue\n"
-" }\n"
-" if {[info exists menu_var($item)]} {\n"
-" if {[is_action $item]} {\n"
-" set menu_var($item) \"\"\n"
-" } elseif {[value_is_bool $item]} {\n"
-" set menu_var($item) 0\n"
-" } elseif {[value_is_string $item]} {\n"
-" set menu_var($item) $unset_str\n"
-" }\n"
-" }\n"
-" }\n"
-" append_text \"Cleared all settings.\\n\"\n"
-"}\n"
-"\n"
-"proc defaults_all {} {\n"
-" copy_default_vars\n"
-" append_text \"Reset all variables to default values.\\n\"\n"
-"}\n"
-"\n"
-"proc all_query_vars {} {\n"
-" global query_ans_list query_aro_list all_settings\n"
-" global cache_all_query_vars\n"
-" \n"
-" if {$cache_all_query_vars != \"\"} {\n"
-" return $cache_all_query_vars\n"
-" }\n"
-"\n"
-" set qry \"\"\n"
-" foreach item $query_ans_list {\n"
-" if {$qry == \"\"} {\n"
-" set qry $item\n"
-" } else {\n"
-" append qry \",$item\"\n"
-" }\n"
-" }\n"
-" foreach item $query_aro_list {\n"
-" if {$qry == \"\"} {\n"
-" set qry $item\n"
-" } else {\n"
-" append qry \",$item\"\n"
-" }\n"
-" }\n"
-" set cache_all_query_vars $qry\n"
-"\n"
-" global env\n"
-" if [info exists env(TKX11VNC_PRINT_ALL_VARS)] {\n"
-" puts \"--------------- BEGIN ALL VARS ---------------\"\n"
-" puts $qry\n"
-" puts \"--------------- END ALL VARS ---------------\"\n"
-" }\n"
-"\n"
-" return $qry\n"
-"}\n"
-"\n"
-"proc query_all {{quiet 0}} {\n"
-" global query_ans_list query_aro_list all_settings\n"
-" global last_query_all_time\n"
-"\n"
-" dtime 1\n"
-" set qry [all_query_vars]\n"
-"\n"
-" set qargs [list \"-Q\" $qry]\n"
-" set all [run_remote_cmd $qargs]\n"
-"\n"
-" if {[regexp {ans=} $all]} {\n"
-" if {! $quiet} {\n"
-" append_text \"Retrieved all current settings.\\n\"\n"
-" }\n"
-" set all_settings $all\n"
-" update_menu_vars $all\n"
-" } else {\n"
-" if {! $quiet} {\n"
-" append_text \"Failed to retrieve current settings.\\n\"\n"
-" }\n"
-" }\n"
-" set last_query_all_time [clock seconds]\n"
-" dtime 2\n"
-" return $all\n"
-"}\n"
-"\n"
-"proc set_info {str} {\n"
-" global info_str info_label\n"
-"#set w1 [$info_label cget -width]\n"
-"#set w2 [winfo width $info_label]\n"
-"#puts \"set_info: w=$w1 winfo=$w2\"\n"
-"#append_text \"$str\\n\"\n"
-" set info_str \"$str\"\n"
-" update\n"
-"}\n"
-"\n"
-"proc append_text {str} {\n"
-" global text_area text_area_str\n"
-"\n"
-" if {![info exists text_area_str]} {\n"
-" set text_area_str \"\"\n"
-" }\n"
-" append text_area_str $str\n"
-"\n"
-" if {![info exists text_area]} {\n"
-" puts stderr $str\n"
-" return\n"
-" }\n"
-" if {$text_area == \"\"} {\n"
-" puts stderr $str\n"
-" return\n"
-" }\n"
-" if {![winfo exists $text_area]} {\n"
-" puts stderr $str\n"
-" return\n"
-" }\n"
-" \n"
-" $text_area insert end $str\n"
-" $text_area see end\n"
-"}\n"
-"\n"
-"proc show_all_settings {} {\n"
-" global all_settings\n"
-" global client_sock client_tail\n"
-" global x11vnc_client_file\n"
-"\n"
-" set txt \"\\nRead-Write settings:\\n\\n\"\n"
-" foreach item [split_query $all_settings] {\n"
-" regsub {:} $item {: } item\n"
-" append txt \" $item\\n\"\n"
-" if {[regexp {noremote} $item]} {\n"
-" append txt \"\\nRead-Only settings:\\n\\n\"\n"
-" }\n"
-" }\n"
-" append txt \"\\nInternal settings:\\n\\n\"\n"
-" append txt \"x11vnc_client_file: $x11vnc_client_file\\n\"\n"
-" if {[info exists client_tail]} {\n"
-" append txt \"client_tail: $client_tail\\n\"\n"
-" } else {\n"
-" append txt \"client_tail: unset\\n\"\n"
-" }\n"
-" if {[info exists client_sock]} {\n"
-" append txt \"client_sock: $client_sock\\n\"\n"
-" } else {\n"
-" append txt \"client_sock: unset\\n\"\n"
-" }\n"
-" set estr \"\"\n"
-" catch {set estr [exec env | grep -i X11VNC]}\n"
-" append txt \"$estr\\n\"\n"
-" textwin \"Settings\" \"All Current Settings\" $txt\n"
-"}\n"
-"\n"
-"proc show_logfile {} {\n"
-" global menu_var unset_str\n"
-"\n"
-" set logfile [tilde_expand $menu_var(logfile)]\n"
-" \n"
-" if {$logfile == \"\" || $logfile == $unset_str} {\n"
-" set txt \"\\nNo logfile was specified at x11vnc startup.\\n\\n\" \n"
-" } elseif {![file exists $logfile]} {\n"
-" set txt \"\\nLogfile \\\"$logfile\\\" does not exist.\\n\\n\"\n"
-" } else {\n"
-" set fh \"-3\"\n"
-" set err \"\"\n"
-" catch {set fh [open $logfile \"r\"]} err\n"
-" if {$fh == \"-3\"} {\n"
-" set txt \"\\nError opening \\\"$logfile\\\" $err.\\n\\n\"\n"
-" } else {\n"
-" set txt \"\\nLogfile \\\"$logfile\\\" current contents:\\n\"\n"
-" while {[gets $fh line] > -1} {\n"
-" append txt \"$line\\n\"\n"
-" }\n"
-" close $fh\n"
-" }\n"
-" }\n"
-" textwin \"Logfile\" \"Logfile\" $txt\n"
-"}\n"
-"\n"
-"proc tail_logfile {} {\n"
-" global menu_var unset_str ffont\n"
-" set logfile $menu_var(logfile)\n"
-" \n"
-" set txt \"\"\n"
-" if {$logfile == \"\" || $logfile == $unset_str} {\n"
-" set txt \"\\nNo logfile was specified at x11vnc startup.\\n\\n\" \n"
-" } elseif {![file exists $logfile]} {\n"
-" set txt \"\\nLogfile \\\"$logfile\\\" does not exist.\\n\\n\"\n"
-" } else {\n"
-" set cmd \"\"\n"
-" set xterm_cmd \"xterm -sb -fn $ffont -geometry 80x45 -title x11vnc-logfile -e\"\n"
-" set cmd [split $xterm_cmd]\n"
-" lappend cmd \"tail\"\n"
-" lappend cmd \"-3000f\"\n"
-" lappend cmd $logfile\n"
-" lappend cmd \"&\"\n"
-" catch {[eval exec $cmd]}\n"
-" }\n"
-" if {$txt != \"\"} {\n"
-" textwin \"Logfile\" \"Logfile\" $txt\n"
-" }\n"
-"}\n"
-"\n"
-"proc set_connected {yesno} {\n"
-" global connected_to_x11vnc\n"
-" set orig $connected_to_x11vnc\n"
-" \n"
-" if {$yesno == \"yes\"} {\n"
-" set connected_to_x11vnc 1\n"
-" } else {\n"
-" set connected_to_x11vnc 0\n"
-" no_x11_display\n"
-" no_vnc_display\n"
-" }\n"
-" if {$orig != $connected_to_x11vnc} {\n"
-" set_widgets\n"
-" }\n"
-"}\n"
-"\n"
-"proc detach_from_display {} {\n"
-" global connected_to_x11vnc reply_xdisplay x11vnc_xdisplay\n"
-" set str \"Detaching from X display.\"\n"
-" if {$reply_xdisplay != \"\"} {\n"
-" set str \"Detaching from $reply_xdisplay.\"\n"
-" } elseif {$x11vnc_xdisplay != \"\"} {\n"
-" set str \"Detaching from $x11vnc_xdisplay.\"\n"
-" }\n"
-" if {$connected_to_x11vnc} {\n"
-" append_text \"$str\\n\"\n"
-" }\n"
-" set_connected no\n"
-"}\n"
-"\n"
-"proc do_stop_quit {} {\n"
-" push_new_value \"stop\" \"stop\" 1 0\n"
-" set_connected no\n"
-" update\n"
-" after 250\n"
-" destroy .\n"
-"}\n"
-"\n"
-"# Menu item is an action:\n"
-"proc do_action {item} {\n"
-" global menu_var connected_to_x11vnc beginner_mode\n"
-"\n"
-" if {[in_debug_mode]} {\n"
-" append_text \"action: \\\"$item\\\"\\n\"\n"
-" }\n"
-"#puts \"action: \\\"$item\\\"\\n\"\n"
-"\n"
-" if {$item == \"ping\"} {\n"
-" if {$beginner_mode} {\n"
-" try_connect_and_query_all\n"
-" } else {\n"
-" try_connect\n"
-" }\n"
-" return\n"
-" } elseif {$item == \"start\"} {\n"
-" start_x11vnc\n"
-" return\n"
-" } elseif {$item == \"detach\"} {\n"
-" detach_from_display\n"
-" return\n"
-" } elseif {$item == \"attach\"} {\n"
-" try_connect_and_query_all\n"
-" return\n"
-" } elseif {$item == \"update-all\"} {\n"
-" query_all\n"
-" return\n"
-" } elseif {$item == \"clear-all\"} {\n"
-" clear_all\n"
-" return\n"
-" } elseif {$item == \"defaults-all\"} {\n"
-" defaults_all\n"
-" return\n"
-" } elseif {$item == \"save-settings\"} {\n"
-" save_settings\n"
-" return\n"
-" } elseif {$item == \"show-start-cmd\"} {\n"
-" show_start_cmd\n"
-" return\n"
-" } elseif {$item == \"all-settings\"} {\n"
-" show_all_settings\n"
-" return\n"
-" } elseif {$item == \"show-logfile\"} {\n"
-" show_logfile\n"
-" return\n"
-" } elseif {$item == \"tail-logfile\"} {\n"
-" tail_logfile\n"
-" return\n"
-" } elseif {$item == \"Misc-Tuning:\"} {\n"
-" menu_help \"$item\"\n"
-" return\n"
-" } elseif {$item == \"WindowView\"} {\n"
-" change_view_state\n"
-" return\n"
-" } elseif {$item == \"quit\" || $item == \"Quit\"} {\n"
-" destroy .\n"
-" exit 0\n"
-" } elseif {$item == \"stop+quit\"} {\n"
-" do_stop_quit\n"
-" }\n"
-"\n"
-" if {[value_is_string $item]} {\n"
-" if {! [entry_dialog $item]} {\n"
-" return\n"
-" }\n"
-" set new $menu_var($item)\n"
-" set name $item\n"
-" } else {\n"
-" set new 1\n"
-" set name $item\n"
-" }\n"
-"\n"
-" if {$item == \"load-settings\"} {\n"
-" load_settings\n"
-" return\n"
-" }\n"
-"\n"
-" if {! $connected_to_x11vnc} {\n"
-" ;\n"
-" } elseif {[regexp {^(stop|quit|exit|shutdown)$} $item]} {\n"
-" # just do -R\n"
-" append_text \"stopping remote x11vnc server...\\n\"\n"
-" push_new_value $item $name $new 0\n"
-" set_connected no\n"
-" \n"
-" } elseif {[opt_match Q $item]} {\n"
-" push_new_value $item $name $new 1\n"
-" } else {\n"
-" push_new_value $item $name $new 0\n"
-" }\n"
-"}\n"
-"\n"
-"proc ptime {time} {\n"
-" set usec [lindex [split $time] 0]\n"
-" set sec [format \"%.3f\" [expr \"$usec / 1000000.0\"]]\n"
-" puts \"time: $sec secs.\"\n"
-"}\n"
-"\n"
-"proc do_var {item} {\n"
-" global connected_to_x11vnc item_cascade menu_var\n"
-"\n"
-" set debug [in_debug_mode]\n"
-"\n"
-" set string 0\n"
-" if {[is_action $item] || $item == \"WindowView\"} {\n"
-" # Menu item is action:\n"
-" if {$debug} {\n"
-" ptime [time {do_action $item}]\n"
-" } else {\n"
-" do_action $item\n"
-" }\n"
-" return\n"
-" }\n"
-"\n"
-" if {[value_is_string $item]} {\n"
-" # Menu item is a string:\n"
-" if {$item_cascade($item) != \"\"} {\n"
-" # Cascade sets variable automatically\n"
-" } else {\n"
-" # Otherwise Entry box\n"
-" if {![entry_dialog $item]} {\n"
-" return\n"
-" }\n"
-" }\n"
-" set new $menu_var($item)\n"
-" set name $item\n"
-" } else {\n"
-" # Menu item is a boolean:\n"
-" set name [check_var $item]\n"
-" if {$name == \"\"} {\n"
-" return\n"
-" }\n"
-" set new 1\n"
-" }\n"
-" if {$connected_to_x11vnc} {\n"
-" if {$debug} {\n"
-" ptime [time {push_new_value $item $name $new 1}]\n"
-" } else {\n"
-" push_new_value $item $name $new 1\n"
-" }\n"
-"\n"
-" if {$item == \"http\"} {\n"
-" global vnc_url\n"
-" append_text \" URL: $vnc_url\\n\"\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc menu_help {item} {\n"
-" if ![help_win $item] {\n"
-" textwin \"nohelp\" \"No help available\" \\\n"
-" \"Sorry, no help avaiable for \\\"$item\\\"\"\n"
-" }\n"
-"}\n"
-"\n"
-"proc opt_match {c item} {\n"
-" global item_opts\n"
-" if {[info exists item_opts($item)]} {\n"
-" if {[regexp \"^\\[A-z\\]*$c\" $item_opts($item)]} {\n"
-" return 1\n"
-" }\n"
-" }\n"
-" return 0\n"
-"}\n"
-"\n"
-"proc is_action {item} {\n"
-" return [opt_match A $item]\n"
-"}\n"
-"\n"
-"proc is_gui_internal {item} {\n"
-" if {$item == \"Properties\"} {\n"
-" return 1\n"
-" }\n"
-" if {$item == \"Tray\"} {\n"
-" return 1\n"
-" }\n"
-" return [opt_match G $item]\n"
-"}\n"
-"\n"
-"proc is_browse {item} {\n"
-" return [opt_match F $item]\n"
-"}\n"
-"\n"
-"proc value_is_string {item} {\n"
-" global item_bool\n"
-" if {![info exists item_bool($item)]} {\n"
-" return 0\n"
-" }\n"
-" if {! $item_bool($item)} {\n"
-" return 1\n"
-" } else {\n"
-" return 0\n"
-" }\n"
-"}\n"
-"\n"
-"proc value_is_bool {item} {\n"
-" global item_bool\n"
-" if {![info exists item_bool($item)]} {\n"
-" return 0\n"
-" }\n"
-" if {$item_bool($item)} {\n"
-" return 1\n"
-" } else {\n"
-" return 0\n"
-" }\n"
-"}\n"
-"\n"
-"proc split_query0 {query} {\n"
-" # original slower way with regexp/regsub\n"
-" regsub -all {aro=} $query {ans=} query\n"
-" set items {}\n"
-" while {1} {\n"
-" if {! [regexp {^ans=(.*)$} $query m0 m1]} {\n"
-" break\n"
-" }\n"
-" set item $m1\n"
-" set m2 \"\"\n"
-" regexp {,ans=.*$} $item m2\n"
-" regsub {,ans=.*$} $item \"\" item\n"
-" if {$item != \"\"} {\n"
-" lappend items $item\n"
-" }\n"
-" set query $m2\n"
-" regsub {^,} $query \"\" query\n"
-" }\n"
-" return $items\n"
-"}\n"
-"\n"
-"proc split_query {query} {\n"
-" regsub -all {aro=} $query {ans=} query\n"
-" set items {}\n"
-" while {1} {\n"
-" set n [string first \"ans=\" $query]\n"
-" if {$n < 0} {\n"
-" break\n"
-" }\n"
-" set from [expr $n+4]\n"
-"\n"
-" set m [string first \",ans=\" $query]\n"
-" if {$m < 0} {\n"
-" set more 0\n"
-" set item [string range $query $from end]\n"
-" } else {\n"
-" set more 1\n"
-" set to [expr $m-1]\n"
-" set item [string range $query $from $to]\n"
-" }\n"
-" if {$item != \"\"} {\n"
-" lappend items $item\n"
-" }\n"
-" if {$more} {\n"
-" incr m\n"
-" set query [string range $query $m end]\n"
-" } else {\n"
-" set query \"\"\n"
-" }\n"
-" }\n"
-" return $items\n"
-"}\n"
-"\n"
-"proc set_x11_display {name} {\n"
-" global x11_display\n"
-" set x11_display \"x11vnc X display: $name\"\n"
-" set_name \"tkx11vnc - $name\"\n"
-"}\n"
-"proc set_vnc_display {name} {\n"
-" global vnc_display icon_mode\n"
-" set vnc_display \"VNC display: $name\"\n"
-"\n"
-" if {$icon_mode} {\n"
-" set_icon_label\n"
-" }\n"
-"}\n"
-"proc set_vnc_url {name} {\n"
-" global vnc_url\n"
-" set vnc_url $name\n"
-"}\n"
-"proc no_x11_display {} {\n"
-" set_x11_display \"(*none*)\"\n"
-" set_name \"tkx11vnc\"\n"
-"}\n"
-"proc no_vnc_display {} {\n"
-" set_vnc_display \"(*none*)\"\n"
-"}\n"
-"proc no_vnc_url {} {\n"
-" set_vnc_url \"(*none*)\"\n"
-"}\n"
-"\n"
-"proc get_vnc_display_number {} {\n"
-" global vnc_display\n"
-" if ![info exists vnc_display] {\n"
-" return \"none\"\n"
-" }\n"
-" if {$vnc_display == \"\"} {\n"
-" return \"none\"\n"
-" }\n"
-" set str $vnc_display\n"
-" regsub {VNC display: *} $str \"\" str\n"
-" if [regexp {:([0-9][0-9]*)} $str m0 n] {\n"
-" return $n\n"
-" }\n"
-" return \"none\"\n"
-"}\n"
-"\n"
-"proc fetch_displays {} {\n"
-"\n"
-" set qargs [list \"-Q\" \"display,vncdisplay\"]\n"
-" set result [run_remote_cmd $qargs]\n"
-"\n"
-" set got_x11 0\n"
-" set got_vnc 0\n"
-" set got_url 0\n"
-"\n"
-" foreach item [split_query $result] {\n"
-" if {[regexp {^display:(.*)$} $item m0 m1]} {\n"
-" set_x11_display $m1\n"
-" set got_x11 1\n"
-" } elseif {[regexp {^vncdisplay:(.*)$} $item m0 m1]} {\n"
-" set_vnc_display $m1\n"
-" set got_vnc 1\n"
-" } elseif {[regexp {^http_url:(.*)$} $item m0 m1]} {\n"
-" set_vnc_url $m1\n"
-" set got_url 1\n"
-" }\n"
-" }\n"
-" if {! $got_x11} {\n"
-" no_x11_display\n"
-" }\n"
-" if {! $got_vnc} {\n"
-" no_vnc_display\n"
-" }\n"
-" if {! $got_url} {\n"
-" no_vnc_url\n"
-" }\n"
-"}\n"
-"\n"
-"proc client_dialog {client} {\n"
-" set cid \"\"\n"
-" set host \"\"\n"
-" set ip \"\"\n"
-" global menu_var text_area cleanup_window item_bool\n"
-"\n"
-" #<id>:<ip>:<port>:<user>:<unix>:<hostname>:<input>:<loginview>:<time>\n"
-" append_text \"\\nClient info string:\\n - $client\\n\\n\"\n"
-" if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \\\n"
-" $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {\n"
-" set cid $m1\n"
-" set ip $m2\n"
-" set port $m3\n"
-" set user $m4\n"
-" set unix $m5\n"
-" set host $m6\n"
-" regsub {\\..*$} $host \"\" host\n"
-" set input $m7\n"
-" set logvo $m8\n"
-" set ltime $m9\n"
-" append_text \"Host: $host, Port: $port, User: $user\"\n"
-" if {$unix != \"\" && $unix != \"none\"} {\n"
-" append_text \", Unix: $unix\"\n"
-" }\n"
-" append_text \", IP: $ip, Id: $cid\\n\"\n"
-" append_text \" - originally logged in as: \"\n"
-" if {$logvo == \"1\" } {\n"
-" append_text \"View-Only Client\"\n"
-" } else {\n"
-" append_text \"Normal Client\"\n"
-" }\n"
-" if {$ltime != \"\"} {\n"
-" set tim [clock format $ltime]\n"
-" append_text \", $tim\"\n"
-" }\n"
-" append_text \"\\n\"\n"
-" append_text \" - currently allowed input: \"\n"
-" set sk 0\n"
-" set sm 0\n"
-" set sb 0\n"
-" set sc 0\n"
-" set sf 0\n"
-" if {[regexp -nocase {K} $input]} {\n"
-" append_text \"Keystrokes\"\n"
-" set sk 1\n"
-" }\n"
-" if {[regexp -nocase {M} $input]} {\n"
-" if {$sk} {\n"
-" append_text \", \"\n"
-" }\n"
-" append_text \"Mouse-Motion\"\n"
-" set sm 1\n"
-" }\n"
-" if {[regexp -nocase {B} $input]} {\n"
-" if {$sk || $sm} {\n"
-" append_text \", \"\n"
-" }\n"
-" append_text \"Button-Click\"\n"
-" set sb 1\n"
-" }\n"
-" if {[regexp -nocase {C} $input]} {\n"
-" if {$sk || $sm || $sb} {\n"
-" append_text \", \"\n"
-" }\n"
-" append_text \"Clipboard\"\n"
-" set sm 1\n"
-" }\n"
-" if {[regexp -nocase {F} $input]} {\n"
-" if {$sk || $sm || $sb || $sf} {\n"
-" append_text \", \"\n"
-" }\n"
-" append_text \"Files\"\n"
-" set sf 1\n"
-" }\n"
-" if {! $sk && ! $sm && ! $sb && ! $sm && ! $sf} {\n"
-" append_text \"None\"\n"
-" }\n"
-" append_text \"\\n\"\n"
-" }\n"
-" if {$cid == \"\"} {\n"
-" append_text \"Invalid client info string: $client\\n\"\n"
-" return\n"
-" }\n"
-"\n"
-" regsub -all {_} $input \"\" input\n"
-" set menu_var(client) \"$input\"\n"
-" set item_bool(client) 0\n"
-"\n"
-" insert_client_action_window $input\n"
-" set rc [entry_dialog client 1]\n"
-"\n"
-" cleanup_text_window\n"
-"\n"
-" set val $menu_var(client)\n"
-" #puts \"rc: $rc val: $val\"\n"
-"\n"
-" if {! $rc} {\n"
-" return;\n"
-" } elseif {[regexp -nocase {(disconnect|close)} $val]} {\n"
-" disconnect_dialog $client\n"
-" } else {\n"
-" regsub -all -nocase {[^KMBCF]} $val \"\" val\n"
-" set item_bool(client_input) 0\n"
-" push_new_value \"client_input\" \"client_input\" \"$cid:$val\" 0\n"
-" }\n"
-"}\n"
-"\n"
-"proc disconnect_dialog {client} {\n"
-" set cid \"\"\n"
-" set host \"\"\n"
-" set msg \"\\n\"\n"
-" append msg \"*** Client info string:\\n $client\\n\"\n"
-" if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \\\n"
-" $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {\n"
-" set cid $m1\n"
-" set ip $m2\n"
-" set port $m3\n"
-" set user $m4\n"
-" set unix $m5\n"
-" set host $m6\n"
-" regsub {\\..*$} $host \"\" host\n"
-" set input $m7\n"
-" set logvo $m8\n"
-" set ltime $m9\n"
-" append_text \"Host: $host, Port: $port, IP: $ip, User: $user\"\n"
-" if {$unix != \"\" && $unix != \"none\"} {\n"
-" append_text \", Unix: $unix\"\n"
-" }\n"
-" append_text \", Id: $cid\\n\"\n"
-" }\n"
-" if {$cid == \"\"} {\n"
-" append_text \"Invalid client info string: $client\\n\"\n"
-" return\n"
-" }\n"
-" append msg \"*** To *DISCONNECT* this client press \\\"OK\\\" again, otherwise press \\\"Cancel\\\"\\n\"\n"
-" bell\n"
-" if {[warning_dialog $msg \"current\"]} {\n"
-" push_new_value \"disconnect\" \"disconnect\" $cid 1\n"
-" } else {\n"
-" append_text \"disconnect cancelled.\\n\"\n"
-" }\n"
-"}\n"
-"\n"
-"proc update_clients_and_repost {} {\n"
-" global item_cascade menu_m menu_b\n"
-"\n"
-" append_text \"Refreshing connected clients list... \"\n"
-" query_all 1\n"
-" update\n"
-"\n"
-" set saw 0\n"
-" set casc $item_cascade(current)\n"
-" set last [$casc index end]\n"
-" for {set i 0} {$i <= $last} {incr i} {\n"
-" if {[$casc type $i] == \"separator\"} {\n"
-" continue\n"
-" }\n"
-" set name [$casc entrycget $i -label]\n"
-" if {[regexp {^num-clients} $name]} {\n"
-" continue\n"
-" }\n"
-" if {[regexp {^refresh-list} $name]} {\n"
-" continue\n"
-" }\n"
-" if {! $saw} {\n"
-" append_text \"\\n\"\n"
-" }\n"
-" set saw 1\n"
-" append_text \"client: $name\\n\"\n"
-" }\n"
-" if {! $saw} {\n"
-" append_text \"done.\\n\"\n"
-" }\n"
-"}\n"
-"\n"
-"proc update_clients_menu {list} {\n"
-" global item_cascade ffont\n"
-" global saved_clients_str\n"
-"\n"
-" if {![info exists saved_clients_str]} {\n"
-" set saved_clients_str \"\"\n"
-" }\n"
-" if {$list == \"INIT\"} {\n"
-" set list $saved_clients_str\n"
-" } else {\n"
-" set saved_clients_str $list\n"
-" }\n"
-"\n"
-" set subm $item_cascade(current);\n"
-" catch {destroy $subm}\n"
-" menu $subm -tearoff 0 -font $ffont\n"
-" $subm add command\n"
-" $subm add command -label \"refresh-list\" \\\n"
-" -command \"update_clients_and_repost\"\n"
-" $subm add separator\n"
-" set count 0\n"
-" foreach client [split $list \",\"] {\n"
-" if {![regexp {^[a-z0-9]*[a-z0-9]:} $client]} {\n"
-" #append_text \"Skipping client line: \"\n"
-" #append_text $client\n"
-" #append_text \"\\n\"\n"
-" continue\n"
-" }\n"
-" regsub -all {[{}()~!$&*|;'\"`{}<>\\[\\]]} $client \"\" client\n"
-" #'\n"
-" if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \\\n"
-" $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {\n"
-" set id $m1\n"
-" set user $m4\n"
-" set unix $m5\n"
-" set host $m6\n"
-" regsub {\\..*$} $host \"\" host\n"
-" set clabel \"$host $id\"\n"
-" if {$unix != \"\" && $unix != \"none\"} {\n"
-" set clabel \"$unix@$clabel\"\n"
-" } elseif {$user != \"unknown-user\"} {\n"
-" set clabel \"$user@$clabel\"\n"
-" }\n"
-" } else {\n"
-" regsub {:.*$} $client \"\" clabel\n"
-" }\n"
-" $subm add command -label \"$clabel\" \\\n"
-" -command \"client_dialog \\{$client\\}\"\n"
-" incr count\n"
-" }\n"
-" $subm entryconfigure 0 -label \"num-clients: $count\"\n"
-"}\n"
-"\n"
-"proc set_widgets {} {\n"
-" global connected_to_x11vnc item_case item_menu item_entry menu_m\n"
-"\n"
-" foreach item [array names item_case] {\n"
-" if ![info exists item_case($item)] { continue; }\n"
-" set case $item_case($item)\n"
-" if ![info exists item_menu($item)] { continue; }\n"
-" set menu $item_menu($item)\n"
-" if ![info exists item_entry($item)] { continue; }\n"
-" set entry $item_entry($item)\n"
-" if {$entry < 0} {\n"
-" # skip case under beginner_mode \n"
-" continue\n"
-" }\n"
-" set type [$menu type $entry]\n"
-" if {$type == \"separator\" || $type == \"tearoff\"} {\n"
-" continue\n"
-" }\n"
-" if {![winfo exists $menu]} {\n"
-" continue\n"
-" }\n"
-" if {$connected_to_x11vnc} {\n"
-" if {[active_when_connected $item]} {\n"
-" $menu entryconfigure $entry -state normal\n"
-" } else {\n"
-" $menu entryconfigure $entry -state disabled\n"
-" }\n"
-" } else {\n"
-" if {[active_when_starting $item]} {\n"
-" $menu entryconfigure $entry -state normal\n"
-" } else {\n"
-" $menu entryconfigure $entry -state disabled\n"
-" }\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc toggle_simple_gui {} {\n"
-" global beginner_mode simple_gui_created\n"
-" global connected_to_x11vnc make_gui_count\n"
-"\n"
-" if {$beginner_mode} {\n"
-" append_text \"\\nSwitching to simple-gui mode.\\n\"\n"
-" } else {\n"
-" append_text \"\\nSwitching to power-user gui mode.\\n\"\n"
-" }\n"
-"\n"
-" if {$make_gui_count == 1} {\n"
-" incr make_gui_count\n"
-" }\n"
-" set simple_gui_created 1\n"
-" make_menu_items\n"
-" set_widgets\n"
-" set_internal_help\n"
-" append_text \"\\n\"\n"
-"}\n"
-"\n"
-"proc little_qs {m} {\n"
-" global bfont ffont beginner_mode\n"
-" global helpremote helptext helplabel\n"
-" global tk_version osname\n"
-"\n"
-" if {$tk_version < 8.0} {\n"
-" return\n"
-" }\n"
-" if {$osname == \"Darwin\"} {\n"
-" return\n"
-" }\n"
-"\n"
-" set n [$m index end]\n"
-"\n"
-" for {set i 0} {$i <= $n} {incr i} {\n"
-" set type [$m type $i]\n"
-"#puts \"$m - $i - $type\"\n"
-" if {$type == \"separator\"} {\n"
-" $m add separator\n"
-" } elseif {$type == \"tearoff\"} {\n"
-" continue;\n"
-" } else {\n"
-" set label [$m entrycget $i -label]\n"
-" set str \"\"\n"
-" if {[info exists helpremote($label)]} {\n"
-" set str \"(?)\"\n"
-" } elseif {[info exists helptext($label)]} {\n"
-" set str \"(?)\"\n"
-" }\n"
-" $m add command -label $str \\\n"
-" -font $ffont \\\n"
-" -command \"menu_help $label\";\n"
-"\n"
-" if {$str == \"\"} {\n"
-" $m entryconfigure end -state disabled\n"
-" }\n"
-" set arg \"$m,$i\"\n"
-"#puts \"helplabel: $arg -> $label\"\n"
-" set helplabel($arg) $label\n"
-" set j [$m index end]\n"
-" set arg \"$m,$j\"\n"
-" set helplabel($arg) $label\n"
-" }\n"
-" if {$i == 0} {\n"
-" $m entryconfigure end -columnbreak 1\n"
-" }\n"
-" }\n"
-"\n"
-" menu_bindings $m\n"
-"}\n"
-"\n"
-"proc make_menu_items {} {\n"
-" global template \n"
-" global menu_b menu_m menu_count\n"
-" global item_opts item_bool item_case item_menu item_entry menu_var unset_str\n"
-" global item_cascade\n"
-" global bfont ffont beginner_mode simple_gui_created\n"
-" global helptext helpremote helplabel\n"
-"\n"
-" # some tweaks...\n"
-" if {![info exists menu_var(deny)]} {\n"
-" set menu_var(deny) 0\n"
-" }\n"
-"\n"
-" set case \"\";\n"
-" set L_casc \"\"\n"
-" set L_casc_count 0\n"
-" set L_menus [list]\n"
-"\n"
-" # Extract the menu items:\n"
-" foreach line [split $template \"\\n\"] {\n"
-" if {[regexp {^Row:} $line]} {\n"
-" continue\n"
-" }\n"
-" if {[regexp {^[A-z]} $line]} {\n"
-" set case [string trim $line]\n"
-"\n"
-" if {$simple_gui_created} {\n"
-" set i0 0\n"
-" #if {$case == \"Misc\"} { # kludge for simple_gui\n"
-" # set i0 1\n"
-" #}\n"
-" catch {$menu_m($case) delete $i0 end}\n"
-" }\n"
-" set menu_count($case) 0\n"
-" continue;\n"
-" }\n"
-"\n"
-" set item [string trim $line]\n"
-" regsub -all { *} $item \" \" item\n"
-" if {$item == \"\"} {\n"
-" continue;\n"
-" }\n"
-" set opts \"\"\n"
-" if {[regexp {^=} $item]} {\n"
-" set opts [lindex [split $item] 0]\n"
-" regsub {^=} $opts \"\" opts\n"
-" set item [lindex [split $item] 1]\n"
-" }\n"
-" if {[regexp {^0} $opts]} {\n"
-" continue;\n"
-" }\n"
-" if {[regexp {:$} $item]} {\n"
-" set bool 0\n"
-" } else {\n"
-" set bool 1\n"
-" }\n"
-" regsub {:$} $item {} item\n"
-"\n"
-" if {$item == \"LOFF\"} {\n"
-" set L_casc \"\"\n"
-" continue\n"
-" }\n"
-"\n"
-" if {$item == \"-- D\"} {\n"
-" set beginner_sep 1\n"
-" set item \"--\"\n"
-" } else {\n"
-" set beginner_sep 0\n"
-" }\n"
-"\n"
-" set item_opts($item) $opts\n"
-" set item_case($item) $case\n"
-" set item_bool($item) $bool\n"
-" set item_cascade($item) \"\"\n"
-"\n"
-" if {$L_casc == \"\"} {\n"
-" set item_entry($item) $menu_count($case)\n"
-" set m $menu_m($case)\n"
-" } else {\n"
-" # hack for cascades for crowded menus. See =GAL opts.\n"
-" set item_entry($item) $L_casc_count\n"
-" set m $L_casc\n"
-" }\n"
-"\n"
-" set mvar 0 \n"
-"\n"
-" if {$beginner_mode && ! $beginner_sep && ![opt_match D $item]} {\n"
-" set item_entry($item) \"-1\"\n"
-" continue;\n"
-" }\n"
-"\n"
-" set item_menu($item) $m\n"
-"\n"
-" if {0} { puts \"ITEM: $item\\t- $opts\\t- $case\\t- \\\n"
-" $bool\\t- $menu_count($case)\" }\n"
-"\n"
-" # Create the menu items, its variables, etc., etc.\n"
-"\n"
-" if {$item == \"--\"} {\n"
-" $m add separator\n"
-"\n"
-" } elseif {$item == \"Quit\"} {\n"
-" # Quit item must shut us down:\n"
-" $m add command -label \"$item\" -underline 0 \\\n"
-" -font $ffont \\\n"
-" -command {destroy .; exit 0}\n"
-"\n"
-" } elseif {$case == \"Help\"} {\n"
-" # Help is simple help:\n"
-" $m add command -label \"$item\" \\\n"
-" -font $ffont \\\n"
-" -command \"menu_help $item\"\n"
-"\n"
-" } elseif {[opt_match L $item]} {\n"
-" # Special sub-menu cascade (=GAL ends with LOFF)\n"
-" set subm $m.casc_L$menu_count($case)\n"
-" catch {destroy $subm}\n"
-" menu $subm -tearoff 0 -font $ffont\n"
-" set item_cascade($item) $subm\n"
-" $m add cascade -label \"$item\" \\\n"
-" -font $ffont \\\n"
-" -menu $subm\n"
-" set L_casc $subm\n"
-" set L_casc_count -1\n"
-" lappend L_menus $L_casc\n"
-"\n"
-" } elseif {$item == \"current\"} {\n"
-" # Current clients cascade\n"
-" set subm $m.current_cascade\n"
-" catch {destroy $subm}\n"
-" set item_cascade($item) $subm\n"
-" update_clients_menu \"INIT\"\n"
-" $m add cascade -label \"$item\" \\\n"
-" -font $ffont \\\n"
-" -menu $subm\n"
-"\n"
-" } elseif {[is_action $item]} {\n"
-" # Action\n"
-" $m add command -label \"$item\" \\\n"
-" -font $ffont \\\n"
-" -command \"do_var $item\"\n"
-" if {![info exists menu_var($item)]} {\n"
-" set menu_var($item) \"\"; # for convenience\n"
-" }\n"
-"\n"
-" } elseif {! $item_bool($item)} {\n"
-" # String\n"
-" if {[regexp -- {-C:(.*)} $item_opts($item) m0 m1]} {\n"
-" # Radiobutton select\n"
-" set subm $m.radio_cascade$menu_count($case)\n"
-" catch {destroy $subm}\n"
-" menu $subm -tearoff 0 -font $ffont\n"
-" foreach val [split $m1 \",\"] {\n"
-" $subm add radiobutton -label \"$val\" \\\n"
-" -command \"do_var $item\" \\\n"
-" -value \"$val\" \\\n"
-" -font $ffont \\\n"
-" -variable menu_var($item)\n"
-" }\n"
-" $m add cascade -label \"$item\" \\\n"
-" -font $ffont \\\n"
-" -menu $subm\n"
-" set item_cascade($item) $subm\n"
-" } else {\n"
-" # Arbitrary_string\n"
-" $m add command -label \"$item\" \\\n"
-" -font $ffont \\\n"
-" -command \"do_var $item\"\n"
-" }\n"
-" set mvar 1\n"
-"\n"
-" } elseif {$item == \"simple-gui\"} {\n"
-" $m add checkbutton -label \"$item\" \\\n"
-" -command \"toggle_simple_gui\" \\\n"
-" -font $ffont \\\n"
-" -variable beginner_mode\n"
-" } else {\n"
-" # Boolean\n"
-" $m add checkbutton -label \"$item\" \\\n"
-" -command \"do_var $item\" \\\n"
-" -font $ffont \\\n"
-" -variable menu_var($item)\n"
-" if {![info exists menu_var($item)]} {\n"
-" set menu_var($item) 0\n"
-" }\n"
-" }\n"
-"\n"
-" if {$L_casc_count == -1} {\n"
-" incr menu_count($case)\n"
-" incr L_casc_count\n"
-" } elseif {$L_casc != \"\"} {\n"
-" incr L_casc_count\n"
-" } else {\n"
-" incr menu_count($case)\n"
-" }\n"
-"\n"
-" if {$mvar} {\n"
-" if {![info exists menu_var($item)]} {\n"
-" set menu_var($item) $unset_str\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" # Now make the little \"(?)\" help buttons\n"
-" global osname\n"
-" foreach case [array names menu_m] {\n"
-" if {$case == \"Help\"} {\n"
-" continue;\n"
-" }\n"
-" little_qs $menu_m($case);\n"
-" }\n"
-" foreach m $L_menus {\n"
-" little_qs $m\n"
-" }\n"
-"}\n"
-"\n"
-"proc check_update_vars {} {\n"
-" global last_query_all_time query_all_freq icon_mode\n"
-" global connected_to_x11vnc client_tail client_sock\n"
-"\n"
-" set now [clock seconds]\n"
-"\n"
-" set delay $query_all_freq\n"
-" if {$client_tail != \"\" && $client_sock == \"\"} {\n"
-" set delay [expr 2 * $query_all_freq]\n"
-" }\n"
-"\n"
-" if {$connected_to_x11vnc} {\n"
-" set quiet 0\n"
-" set refresh [expr \"$last_query_all_time + $delay\"]\n"
-"\n"
-" # puts \"menu_posted $now $last_query_all_time\"\n"
-" # puts \"menu_posted $refresh\"\n"
-"\n"
-" if {$now > $refresh} {\n"
-" append_text \"Refreshing current settings... \"\n"
-" query_all $quiet\n"
-" if {$quiet} {\n"
-" append_text \"done\\n\"\n"
-" }\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc menu_posted {} {\n"
-" check_update_vars\n"
-"}\n"
-"\n"
-"proc props_widgets {state} {\n"
-" global props_buttons\n"
-" foreach w $props_buttons {\n"
-" $w configure -state $state \n"
-" }\n"
-" update\n"
-"}\n"
-"\n"
-"proc props_apply {} {\n"
-" global props_accept props_confirm props_viewonly props_shared \n"
-" global props_zeroconf props_javaview props_solid\n"
-" global props_passwd props_viewpasswd\n"
-" global prop0_accept prop0_confirm prop0_viewonly prop0_shared\n"
-" global prop0_zeroconf prop0_javaview prop0_solid\n"
-" global prop0_passwd prop0_viewpasswd\n"
-" global menu_var\n"
-" global client_sock\n"
-"\n"
-" props_widgets disabled\n"
-"\n"
-" set aft 500\n"
-" if {[info exists client_sock]} {\n"
-" if {$client_sock != \"\"} {\n"
-" set aft 150\n"
-" }\n"
-" }\n"
-" set did 0\n"
-"\n"
-" set fail 0\n"
-"\n"
-" if {$props_confirm != $prop0_confirm} {\n"
-" if {$did > 0} {after $aft}; incr did\n"
-" if {$props_confirm} {\n"
-" push_new_value \"accept\" \"accept\" \"popup\" 1\n"
-" } else {\n"
-" push_new_value \"accept\" \"accept\" \"\" 1\n"
-" }\n"
-" if {$menu_var(accept) == \"popup\"} {\n"
-" set props_confirm 1\n"
-" } elseif {$menu_var(accept) == \"\"} {\n"
-" set props_confirm 0\n"
-" }\n"
-" if {$props_confirm == $prop0_confirm} {incr fail}\n"
-" set prop0_confirm $props_confirm\n"
-" }\n"
-"\n"
-" if {$props_viewonly != $prop0_viewonly} {\n"
-" if {$did > 0} {after $aft}; incr did\n"
-" if {$props_viewonly} {\n"
-" push_new_value \"viewonly\" \"viewonly\" 1 1\n"
-" } else {\n"
-" push_new_value \"viewonly\" \"noviewonly\" 1 1\n"
-" }\n"
-" if {$menu_var(viewonly)} {\n"
-" set props_viewonly 1\n"
-" } else {\n"
-" set props_viewonly 0\n"
-" }\n"
-" if {$props_viewonly == $prop0_viewonly} {incr fail}\n"
-" set prop0_viewonly $props_viewonly\n"
-" }\n"
-"\n"
-" if {$props_shared != $prop0_shared} {\n"
-" if {$did > 0} {after $aft}; incr did\n"
-" if {$props_shared} {\n"
-" push_new_value \"shared\" \"shared\" 1 1\n"
-" } else {\n"
-" push_new_value \"shared\" \"noshared\" 1 1\n"
-" }\n"
-" if {$menu_var(shared)} {\n"
-" set props_shared 1\n"
-" } else {\n"
-" set props_shared 0\n"
-" }\n"
-" if {$props_shared == $prop0_shared} {incr fail}\n"
-" set prop0_shared $props_shared\n"
-" }\n"
-"\n"
-" if {$props_zeroconf != $prop0_zeroconf} {\n"
-" if {$did > 0} {after $aft}; incr did\n"
-" if {$props_zeroconf} {\n"
-" push_new_value \"zeroconf\" \"zeroconf\" 1 1\n"
-" } else {\n"
-" push_new_value \"zeroconf\" \"nozeroconf\" 1 1\n"
-" }\n"
-" if {$menu_var(zeroconf)} {\n"
-" set props_zeroconf 1\n"
-" } else {\n"
-" set props_zeroconf 0\n"
-" }\n"
-" if {$props_zeroconf == $prop0_zeroconf} {incr fail}\n"
-" set prop0_zeroconf $props_zeroconf\n"
-" }\n"
-"\n"
-" if {$props_javaview != $prop0_javaview} {\n"
-" if {$did > 0} {after $aft}; incr did\n"
-" if {$props_javaview} {\n"
-" push_new_value \"http\" \"http\" 1 1\n"
-" } else {\n"
-" push_new_value \"http\" \"nohttp\" 1 1\n"
-" }\n"
-" if {$menu_var(http)} {\n"
-" set props_javaview 1\n"
-" } else {\n"
-" set props_javaview 0\n"
-" }\n"
-" if {$props_javaview == $prop0_javaview} {incr fail}\n"
-" set prop0_javaview $props_javaview\n"
-" }\n"
-"\n"
-" if {$props_solid != $prop0_solid} {\n"
-" if {$did > 0} {after $aft}; incr did\n"
-" if {$props_solid} {\n"
-" push_new_value \"solid\" \"solid\" 1 1\n"
-" } else {\n"
-" push_new_value \"solid\" \"nosolid\" 1 1\n"
-" }\n"
-" if {$menu_var(solid)} {\n"
-" set props_solid 1\n"
-" } else {\n"
-" set props_solid 0\n"
-" }\n"
-" if {$props_solid == $prop0_solid} {incr fail}\n"
-" set prop0_solid $props_solid\n"
-" }\n"
-"\n"
-" set fpw 0\n"
-" if {$props_passwd != $prop0_passwd} {\n"
-" set fpw 1\n"
-" }\n"
-" set vpw 0\n"
-" if {$props_viewpasswd != $prop0_viewpasswd} {\n"
-" set vpw 1\n"
-" }\n"
-"\n"
-" set pw_ord [list]\n"
-" if {!$fpw && !$vpw } {\n"
-" # neither change\n"
-" ;\n"
-" } elseif {$fpw && !$vpw} {\n"
-" # full password change\n"
-" if {$props_passwd == \"\"} {\n"
-" if {$prop0_viewpasswd != \"\"} {\n"
-" # set view to \"\" as well and first\n"
-" set props_viewpasswd \"\"\n"
-" set pw_ord [list vpw fpw]\n"
-" } else {\n"
-" set pw_ord [list fpw]\n"
-" }\n"
-" } else {\n"
-" # assume view state OK\n"
-" set pw_ord [list fpw]\n"
-" }\n"
-" \n"
-" } elseif {!$fpw && $vpw} {\n"
-" # view password change\n"
-" if {$props_viewpasswd == \"\"} {\n"
-" # assume full state OK\n"
-" set pw_ord [list vpw]\n"
-" } else {\n"
-" if {$prop0_passwd == \"\"} {\n"
-" # could be trouble, x11vnc makes random\n"
-" # full passwd...\n"
-" set pw_ord [list vpw]\n"
-" } else {\n"
-" # OK, full non-null.\n"
-" set pw_ord [list vpw]\n"
-" }\n"
-" }\n"
-" } elseif {$fpw && $vpw} {\n"
-" # both full and view password change\n"
-" if {$props_passwd == \"\" && $props_viewpasswd == \"\"} {\n"
-" # OK, do view first\n"
-" set pw_ord [list vpw fpw]\n"
-" } elseif {$props_passwd == \"\" && $props_viewpasswd != \"\"} {\n"
-" # Not good, do view first anyway x11vnc will fix.\n"
-" set pw_ord [list vpw fpw]\n"
-" } elseif {$props_passwd != \"\" && $props_viewpasswd == \"\"} {\n"
-" # OK, view first\n"
-" set pw_ord [list vpw fpw]\n"
-" } elseif {$props_passwd != \"\" && $props_viewpasswd != \"\"} {\n"
-" # OK, full first\n"
-" set pw_ord [list fpw vpw]\n"
-" }\n"
-" }\n"
-"\n"
-" foreach case $pw_ord {\n"
-" if {$case == \"fpw\"} {\n"
-" if {$did > 0} {after $aft}; incr did\n"
-" push_new_value \"passwd\" \"passwd\" \"$props_passwd\" 1\n"
-" if {$props_passwd == $prop0_passwd} {incr fail}\n"
-" set prop0_passwd $props_passwd\n"
-" }\n"
-" if {$case == \"vpw\"} {\n"
-" if {$did > 0} {after $aft}; incr did\n"
-" push_new_value \"viewpasswd\" \"viewpasswd\" \"$props_viewpasswd\" 1\n"
-" if {$props_viewpasswd == $prop0_viewpasswd} {incr fail}\n"
-" set prop0_viewpasswd $props_viewpasswd\n"
-" }\n"
-" }\n"
-"\n"
-" if {$props_accept != $prop0_accept} {\n"
-" if {$did > 0} {after $aft}; incr did\n"
-" if {$props_accept} {\n"
-" push_new_value \"unlock\" \"unlock\" 1 0\n"
-" } else {\n"
-" push_new_value \"lock\" \"lock\" 1 0\n"
-" }\n"
-" if {$props_accept == $prop0_accept} {incr fail}\n"
-" set prop0_accept $props_accept\n"
-" }\n"
-"\n"
-" props_widgets normal\n"
-" if {$fail > 0} {\n"
-" return 0\n"
-" } else {\n"
-" return 1\n"
-" }\n"
-"}\n"
-"\n"
-"proc props_advanced {} {\n"
-" global icon_mode props_win full_win\n"
-" global props_advanced_first\n"
-"\n"
-" if ![info exists props_advanced_first] {\n"
-" center_win $full_win\n"
-" set props_advanced_first 1\n"
-" set first 1\n"
-" } else {\n"
-" set first 0\n"
-" }\n"
-" update\n"
-" wm deiconify $full_win\n"
-" update\n"
-"\n"
-" if {$first} {\n"
-" set w $full_win\n"
-" wm minsize $w [winfo width $w] [winfo height $w]\n"
-" }\n"
-" push_new_value \"remote-cmd\" \"remote-cmd\" \"Q:clients\" 1\n"
-"}\n"
-"\n"
-"proc do_props {} {\n"
-" global props_accept props_confirm props_viewonly props_shared\n"
-" global props_zeroconf props_javaview props_solid\n"
-" global props_passwd props_viewpasswd\n"
-" global prop0_accept prop0_confirm prop0_viewonly prop0_shared\n"
-" global prop0_zeroconf prop0_javaview prop0_solid\n"
-" global prop0_passwd prop0_viewpasswd\n"
-" global menu_var unset_str\n"
-" global have_labelframes ffont bfont\n"
-" global props_buttons icon_noadvanced\n"
-" global icon_mode icon_mode_at_startup\n"
-" global screen_height screen_width\n"
-" global do_props_msg\n"
-"\n"
-" set msg \"\"\n"
-" if {[info exists do_props_msg]} {\n"
-" set msg $do_props_msg\n"
-" }\n"
-"\n"
-" check_update_vars\n"
-"\n"
-" set pady 0.5m\n"
-" set pady 0.3m\n"
-" if {$screen_height <= 360} {\n"
-" set pady 0m\n"
-" }\n"
-"\n"
-" if [info exists menu_var(deny)] {\n"
-" if {$menu_var(deny) == $unset_str || $menu_var(deny) == 0} {\n"
-" set props_accept 1\n"
-" } else {\n"
-" set props_accept 0\n"
-" }\n"
-" } else {\n"
-" set menu_var(deny) 0\n"
-" set props_accept 1\n"
-" }\n"
-" set prop0_accept $props_accept\n"
-"\n"
-" if [info exists menu_var(accept)] {\n"
-" if {$menu_var(accept) == $unset_str || $menu_var(accept) == \"\"} {\n"
-" set props_confirm 0\n"
-" } else {\n"
-" set props_confirm 1\n"
-" }\n"
-" } else {\n"
-" set menu_var(accept) \"\"\n"
-" set props_confirm 0\n"
-" }\n"
-" set prop0_confirm $props_confirm\n"
-"\n"
-" if [info exists menu_var(viewonly)] {\n"
-" if {$menu_var(viewonly) == $unset_str || $menu_var(viewonly) == \"\"} {\n"
-" set props_viewonly 0\n"
-" } elseif ($menu_var(viewonly)) {\n"
-" set props_viewonly 1\n"
-" } else {\n"
-" set props_viewonly 0\n"
-" }\n"
-" } else {\n"
-" set menu_var(viewonly) 0\n"
-" set props_viewonly 0\n"
-" }\n"
-" set prop0_viewonly $props_viewonly\n"
-"\n"
-" if [info exists menu_var(shared)] {\n"
-" if {$menu_var(shared) == $unset_str || $menu_var(shared) == \"\"} {\n"
-" set props_shared 0\n"
-" } elseif ($menu_var(shared)) {\n"
-" set props_shared 1\n"
-" } else {\n"
-" set props_shared 0\n"
-" }\n"
-" } else {\n"
-" set menu_var(shared) 0\n"
-" set props_shared 0\n"
-" }\n"
-" set prop0_shared $props_shared\n"
-"\n"
-" if [info exists menu_var(zeroconf)] {\n"
-" if {$menu_var(zeroconf) == $unset_str || $menu_var(zeroconf) == \"\"} {\n"
-" set props_zeroconf 0\n"
-" } elseif ($menu_var(zeroconf)) {\n"
-" set props_zeroconf 1\n"
-" } else {\n"
-" set props_zeroconf 0\n"
-" }\n"
-" } else {\n"
-" set menu_var(zeroconf) 0\n"
-" set props_zeroconf 0\n"
-" }\n"
-" set prop0_zeroconf $props_zeroconf\n"
-"\n"
-" if [info exists menu_var(http)] {\n"
-" if {$menu_var(http) == $unset_str || $menu_var(http) == \"\"} {\n"
-" set props_javaview 0\n"
-" } elseif ($menu_var(http)) {\n"
-" set props_javaview 1\n"
-" } else {\n"
-" set props_javaview 0\n"
-" }\n"
-" } else {\n"
-" set menu_var(http) 0\n"
-" set props_javaview 0\n"
-" }\n"
-" set prop0_javaview $props_javaview\n"
-"\n"
-" if [info exists menu_var(solid)] {\n"
-" if {$menu_var(solid) == $unset_str || $menu_var(solid) == \"\"} {\n"
-" set props_solid 0\n"
-" } elseif ($menu_var(solid)) {\n"
-" set props_solid 1\n"
-" } else {\n"
-" set props_solid 0\n"
-" }\n"
-" } else {\n"
-" set menu_var(solid) 0\n"
-" set props_solid 0\n"
-" }\n"
-" set prop0_solid $props_solid\n"
-"\n"
-" if ![info exists props_passwd] {\n"
-" set props_passwd \"\"\n"
-" }\n"
-" set prop0_passwd $props_passwd\n"
-"\n"
-" if ![info exists props_viewpasswd] {\n"
-" set props_viewpasswd \"\"\n"
-" }\n"
-" set prop0_viewpasswd $props_viewpasswd\n"
-"\n"
-" if [info exists props_buttons] {\n"
-" catch {unset props_buttons}\n"
-" }\n"
-" set props_buttons [list]\n"
-"\n"
-" set wp .props\n"
-" set w $wp\n"
-" catch {destroy $wp}\n"
-" toplevel $wp\n"
-" wm title $wp \"x11vnc Properties\"\n"
-" frame $w.lf\n"
-" set w $w.lf\n"
-" set b1 \"$w.buttons1\"\n"
-" frame $b1\n"
-" button $b1.ok -text OK -command \"if {\\[props_apply\\]} {destroy $wp}\" -font $bfont\n"
-" button $b1.cancel -text Cancel -command \"destroy $wp\" -font $bfont\n"
-" button $b1.apply -text Apply -command \"props_apply\" -font $bfont\n"
-"\n"
-" bind $w <KeyPress-Escape> \"destroy $wp\"\n"
-"\n"
-" pack $b1.ok $b1.cancel $b1.apply -side left -expand 0\n"
-" lappend props_buttons $b1.apply $b1.cancel $b1.ok\n"
-"\n"
-" set b2 \"$w.buttons2\"\n"
-" frame $b2\n"
-"\n"
-" button $b2.advanced -text \" Advanced ... \" \\\n"
-" -command \"destroy $wp; props_advanced\" -font $bfont\n"
-" if {! $icon_noadvanced} {\n"
-" lappend props_buttons $b2.advanced\n"
-" pack $b2.advanced -side left -expand 0\n"
-" }\n"
-"\n"
-" button $b2.help -text \" Help \" -command \"menu_help Properties\" -font $bfont\n"
-" lappend props_buttons $b2.help\n"
-" pack $b2.help -side left -expand 0\n"
-"\n"
-" set pw \"$w.passwd\"\n"
-" if {$have_labelframes} {\n"
-" labelframe $pw -text \"Password\" -font $bfont\n"
-" } else {\n"
-" frame $pw\n"
-" set l $pw.l\n"
-" label $l -text \"Password:\" -justify left -anchor w -font $bfont\n"
-" pack $pw.l -fill x -expand 1 -padx 1m -pady 0m -side top\n"
-" }\n"
-" entry $pw.e -show \"*\" -textvariable props_passwd -font $bfont\n"
-" pack $pw.e -fill x -expand 1 -padx 1m -pady $pady -side top\n"
-"\n"
-" global x11vnc_icon_mode\n"
-" if {! $x11vnc_icon_mode} {\n"
-" catch { $pw.e configure -state disabled}\n"
-" if {! $have_labelframes} {\n"
-" catch { $pw.l configure -state disabled}\n"
-" }\n"
-" } else {\n"
-" lappend props_buttons $pw.e\n"
-" }\n"
-"\n"
-"\n"
-" set vp \"$w.viewpw\"\n"
-" if {$have_labelframes} {\n"
-" labelframe $vp -text \"ViewOnly Password\" -font $bfont\n"
-" } else {\n"
-" frame $vp\n"
-" set l $vp.l\n"
-" label $l -text \"ViewOnly Password:\" -justify left -anchor w -font $bfont\n"
-" pack $vp.l -fill x -expand 1 -padx 1m -pady 0m -side top\n"
-" }\n"
-" entry $vp.e -show \"*\" -textvariable props_viewpasswd -font $bfont\n"
-" pack $vp.e -fill x -expand 1 -padx 1m -pady $pady -side top\n"
-"\n"
-" if {! $x11vnc_icon_mode} {\n"
-" catch { $vp.e configure -state disabled}\n"
-" if {! $have_labelframes} {\n"
-" catch { $vp.l configure -state disabled}\n"
-" }\n"
-" } else {\n"
-" lappend props_buttons $vp.e\n"
-" }\n"
-"\n"
-" if {! $icon_mode_at_startup} {\n"
-" $vp.e configure -state disabled\n"
-" catch {$vp.l configure -state disabled}\n"
-" catch {$vp configure -state disabled}\n"
-" catch {$vp configure -foreground grey60}\n"
-" $pw.e configure -state disabled\n"
-" catch {$pw.l configure -state disabled}\n"
-" catch {$pw configure -state disabled}\n"
-" catch {$pw configure -foreground grey60}\n"
-" }\n"
-"\n"
-" set sb \"$w.solid\"\n"
-" frame $sb\n"
-" checkbutton $sb.button -text \"Solid Background Color\" \\\n"
-" -variable props_solid -anchor w -font $bfont\n"
-" pack $sb.button -fill x -expand 1 -padx 1m -pady $pady\n"
-"\n"
-" set jv \"$w.javaview\"\n"
-" frame $jv\n"
-" checkbutton $jv.button -text \"Serve Java Viewer Applet\" \\\n"
-" -variable props_javaview -anchor w -font $bfont\n"
-" pack $jv.button -fill x -expand 1 -padx 1m -pady $pady\n"
-"\n"
-" set zc \"$w.zeroconf\"\n"
-" frame $zc\n"
-" checkbutton $zc.button -text \"Advertise Service (Zeroconf)\" \\\n"
-" -variable props_zeroconf -anchor w -font $bfont\n"
-" pack $zc.button -fill x -expand 1 -padx 1m -pady $pady\n"
-"\n"
-" set sh \"$w.shared\"\n"
-" frame $sh\n"
-" checkbutton $sh.button -text \"Shared\" \\\n"
-" -variable props_shared -anchor w -font $bfont\n"
-" pack $sh.button -fill x -expand 1 -padx 1m -pady $pady\n"
-"\n"
-" set vo \"$w.viewonly\"\n"
-" frame $vo\n"
-" checkbutton $vo.button -text \"All Clients ViewOnly\" \\\n"
-" -variable props_viewonly -anchor w -font $bfont\n"
-" pack $vo.button -fill x -expand 1 -padx 1m -pady $pady\n"
-"\n"
-" set cf \"$w.confirm\"\n"
-" frame $cf\n"
-" checkbutton $cf.button -text \"Ask for Confirmation\" \\\n"
-" -variable props_confirm -anchor w -font $bfont\n"
-" pack $cf.button -fill x -expand 1 -padx 1m -pady $pady\n"
-"\n"
-" set ac \"$w.accept\"\n"
-" frame $ac\n"
-" checkbutton $ac.button -text \"Accept Connections\" \\\n"
-" -variable props_accept -anchor w -font $bfont\n"
-" pack $ac.button -fill x -expand 1 -padx 1m -pady $pady\n"
-"\n"
-" set px \"6m\"\n"
-" pack $b1 -side bottom -fill x -pady $pady -padx $px\n"
-" pack $b2 -side bottom -fill x -pady $pady -padx $px\n"
-" pack $vp -side bottom -fill x -pady $pady -padx $px\n"
-" pack $pw -side bottom -fill x -pady $pady -padx $px\n"
-" pack $sb -side bottom -fill x -pady 0m -padx $px\n"
-" pack $jv -side bottom -fill x -pady 0m -padx $px\n"
-" pack $zc -side bottom -fill x -pady 0m -padx $px\n"
-" pack $sh -side bottom -fill x -pady 0m -padx $px\n"
-" pack $vo -side bottom -fill x -pady 0m -padx $px\n"
-" pack $cf -side bottom -fill x -pady 0m -padx $px\n"
-" pack $ac -side bottom -fill x -pady 0m -padx $px\n"
-"\n"
-" global show_props_instructions\n"
-" if {![info exists show_props_instructions]} {\n"
-" set show_props_instructions 1\n"
-" }\n"
-"\n"
-" wm withdraw .props\n"
-"\n"
-" set wl $w\n"
-"\n"
-" pack $wl -side left\n"
-"\n"
-" if {$msg != \"\"} {\n"
-" set tw [textwidth $msg]\n"
-" set th [textheight $msg]\n"
-" set th [expr $th - 1]\n"
-" set ms \".props.msg\"\n"
-" text $ms -font $ffont -relief ridge -width $tw -height $th\n"
-" $ms insert 1.0 $msg\n"
-"\n"
-" set si \"$wl.instructions\"\n"
-" frame $si\n"
-" checkbutton $si.button -text \"Show Instructions\" \\\n"
-" -variable show_props_instructions -anchor w -font $bfont \\\n"
-" -command \"toggle_instructions $ms $pady $px\"\n"
-"\n"
-" pack $si.button -fill x -expand 1 -padx 1m -pady $pady\n"
-" pack $si -side bottom -fill x -pady 0m -padx $px\n"
-"\n"
-" if {$show_props_instructions} {\n"
-" pack $ms -side left -fill both\n"
-" }\n"
-"\n"
-" update\n"
-" }\n"
-"\n"
-"\n"
-" lappend props_buttons $ac.button $cf.button $vo.button $sh.button $zc.button $jv.button $sb.button\n"
-"\n"
-" \n"
-" set w .props\n"
-" update\n"
-" wm resizable $w 1 0\n"
-" center_win $w\n"
-" update\n"
-"\n"
-" #wm minsize $w [winfo width $w] [winfo height $w]\n"
-"\n"
-" tkwait window $w\n"
-" set show_props_instructions 0\n"
-"}\n"
-"\n"
-"proc toggle_instructions {ms pady px} {\n"
-" global show_props_instructions\n"
-" if {$show_props_instructions} {\n"
-" pack $ms -side left -fill both\n"
-" } else {\n"
-" pack forget $ms\n"
-" }\n"
-" catch {pack .props}\n"
-" update\n"
-"}\n"
-"\n"
-"proc do_new_client {} {\n"
-" global newclient ffont bfont\n"
-"\n"
-" set w .newclient\n"
-" catch {destroy $w}\n"
-" toplevel $w\n"
-" label $w.l -text \"Hostname: \" -font $bfont\n"
-" set newclient \"\"\n"
-" entry $w.e -width 16 -textvariable newclient -font $bfont \n"
-" button $w.b -text OK -command \"destroy $w\" -font $bfont\n"
-" button $w.h -text Help -command \"menu_help NewClient\" -font $bfont\n"
-" bind $w.e <Return> \"update; after 100; destroy $w\"\n"
-"\n"
-" wm title $w \"New Client\"\n"
-"\n"
-" pack $w.l $w.e $w.h $w.b -side left -pady 1m -padx 0.5m\n"
-" focus $w.e\n"
-" center_win $w\n"
-" update \n"
-" \n"
-" tkwait window $w\n"
-"\n"
-" regsub -all {[{}()~!$&*|;'\"`{}<>\\[\\]]} $newclient \"\" newclient\n"
-" #'\n"
-" if {$newclient != \"\"} {\n"
-" push_new_value \"connect\" \"connect\" \"$newclient\" 1\n"
-" }\n"
-"}\n"
-"\n"
-"proc do_disconnect_all {} {\n"
-" push_new_value \"disconnect\" \"disconnect\" \"all\" 1\n"
-"}\n"
-"\n"
-"proc do_disconnect_client {id} {\n"
-" push_new_value \"disconnect\" \"disconnect\" \"$id\" 1\n"
-"}\n"
-"\n"
-"proc popup_post {m} {\n"
-" global popup_cascade_posted client_balloon\n"
-" global client_id_list\n"
-"\n"
-" set popup_cascade_posted 0\n"
-" \n"
-" set wd \"$m.disconnect\"\n"
-"\n"
-" if {![winfo exists $wd]} {\n"
-" return\n"
-" }\n"
-"\n"
-" catch {$wd delete 0 end}\n"
-"\n"
-" $wd add command -label \"Disconnect client:\"\n"
-" $wd add separator\n"
-" $wd add command -label \"All Clients\" -command do_disconnect_all\n"
-"\n"
-" if {![info exists client_id_list]} {\n"
-" return\n"
-" }\n"
-"\n"
-" foreach client $client_id_list {\n"
-" if {$client == \"\"} {\n"
-" continue\n"
-" }\n"
-" if {[regexp {^([^:]*):(.*)$} $client mat id lab]} {\n"
-" set nid [expr \"$id + 0\"]\n"
-" $wd add command -label \"$nid $lab\" \\\n"
-" -command \"do_disconnect_client $id\"\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc pmenu {m x y} {\n"
-" if {![winfo exists $m]} {\n"
-" return\n"
-" }\n"
-" set x [expr $x-10]\n"
-" set y [expr $y-10]\n"
-" $m post $x $y\n"
-" # XXX more care needed\n"
-" grab set -global $m\n"
-"}\n"
-"\n"
-"proc set_client_balloon {str} {\n"
-" global client_balloon vnc_display\n"
-" global client_id_list\n"
-"\n"
-" set client_id_list [list]\n"
-" \n"
-" set client_balloon \"$vnc_display\"\n"
-" set count 0\n"
-" regsub -all {^.*aro=clients:} $str \"\" str\n"
-" regsub -all {aro=.*$} $str \"\" str\n"
-" regsub -all {ans=.*$} $str \"\" str\n"
-" foreach client [split $str \",\"] {\n"
-" #puts \"client: $client\"\n"
-" if [regexp {^[ ]*$} $client] {\n"
-" continue\n"
-" }\n"
-" if {[regexp {^(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*):(.*)$} \\\n"
-" $client m0 m1 m2 m3 m4 m5 m6 m7 m8 m9]} {\n"
-" set id $m1\n"
-" set nid [expr \"$m1 + 0\"]\n"
-" set ip $m2\n"
-" set port $m3\n"
-" set user $m4\n"
-" set unix $m5\n"
-" if {[string length $user] >= 24} {\n"
-" # weird identd hash...\n"
-" set user [string range $user 0 8]\n"
-" set user \"${user}...\"\n"
-" }\n"
-" if {$unix != \"\" && $unix != \"none\"} {\n"
-" set user $unix\n"
-" }\n"
-" set host $m6\n"
-" set input $m7\n"
-" set vo $m8\n"
-" set ltime $m9\n"
-" if [regexp {^[ ]*$} $host] {\n"
-" set host $ip\n"
-" }\n"
-" set client_balloon \"${client_balloon}\\n$nid $user\\@$host\"\n"
-" if {$vo == \"1\"} {\n"
-" set client_balloon \"${client_balloon} - view\"\n"
-" lappend client_id_list \"$id:$user\\@$host - view\"\n"
-" } else {\n"
-" set client_balloon \"${client_balloon} - full\"\n"
-" lappend client_id_list \"$id:$user\\@$host - full\"\n"
-" }\n"
-" } else {\n"
-" set i [expr $count+1]\n"
-" if {$i == 1} {\n"
-" set client_balloon \"${client_balloon}\\nunknown-host$i\"\n"
-" }\n"
-" }\n"
-" incr count\n"
-" }\n"
-" if {$count == 0} {\n"
-" set client_balloon \"${client_balloon}\\nNo connections.\"\n"
-" }\n"
-" icon_win_cfg $count\n"
-"}\n"
-"\n"
-"proc read_client_info {channel} {\n"
-" global x11vnc_client_file client_str client_info_read\n"
-" global read_client_info_lock\n"
-" global read_clients\n"
-" set db 0\n"
-"\n"
-" set read_clients 0\n"
-"\n"
-" if {![info exists read_client_info_lock]} {\n"
-" set read_client_info_lock 0\n"
-" }\n"
-"\n"
-" if {$channel != \"\"} {\n"
-"\n"
-" if {$read_client_info_lock} {\n"
-" return\n"
-" }\n"
-" set read_client_info_lock 1\n"
-" after 100\n"
-" set str \"\"\n"
-" set count [gets $channel str]\n"
-" if {$db} {puts stderr \"read_client_info-$channel: $str\"}\n"
-"\n"
-" if {$count == -1 || [eof $channel]} {\n"
-" close $channel\n"
-" catch {file delete $x11vnc_client_file}\n"
-" set read_client_info_lock 0\n"
-" clean_icon_exit\n"
-" }\n"
-" if {$count > 0 && ![regexp {^[ ]*$} $str]} {\n"
-" set client_info_read 1\n"
-" if {$str == \"quit\"} {\n"
-" catch {file delete $x11vnc_client_file}\n"
-" set read_client_info_lock 0\n"
-" clean_icon_exit\n"
-" } elseif {$str == \"skip\"} {\n"
-" ;\n"
-" } elseif [regexp {^clients:} $str] {\n"
-" regsub {^clients:} $str \"\" str\n"
-" set read_clients 1\n"
-" if {$str == \"none\"} {\n"
-" set str \"\"\n"
-" }\n"
-" update_clients_menu $str\n"
-" set client_str $str\n"
-" set_client_balloon $str\n"
-" }\n"
-" }\n"
-" set read_client_info_lock 0\n"
-" }\n"
-"}\n"
-"\n"
-"proc check_set_vnc_display {} {\n"
-" \n"
-" global read_clients check_set_vnc_display_done\n"
-"\n"
-" if {[info exists check_set_vnc_display_done]} {\n"
-" return\n"
-" }\n"
-" if {[info exists read_clients]} {\n"
-" if {$read_clients} {\n"
-" after 250\n"
-" query_all\n"
-" global client_str\n"
-" set_client_balloon $client_str\n"
-" set check_set_vnc_display_done 1\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc read_client_tail {} {\n"
-" global client_tail\n"
-"\n"
-" if {$client_tail != \"\"} {\n"
-" read_client_info $client_tail\n"
-" check_set_vnc_display\n"
-" }\n"
-"}\n"
-"\n"
-"proc read_client_sock {} {\n"
-" global client_sock\n"
-"\n"
-" if {$client_sock != \"\"} {\n"
-" read_client_info $client_sock\n"
-" check_set_vnc_display\n"
-" }\n"
-"}\n"
-"\n"
-"proc show_client_balloon {} {\n"
-" global icon_mode icon_win props_win full_win\n"
-" global client_balloon ffont connected_to_x11vnc\n"
-"\n"
-" set noinfo \"tkx11vnc: no client information\"\n"
-" set noinfo \"$noinfo\\navailable from x11vnc ...\"\n"
-" if ![info exists client_balloon] {\n"
-" set client_balloon $noinfo\n"
-" }\n"
-" if {$client_balloon == \"\"} {\n"
-" set client_balloon $noinfo\n"
-" }\n"
-" if {! [info exists icon_win]} {\n"
-" return\n"
-" } elseif {$icon_win == \"\"} {\n"
-" return\n"
-" } elseif {! [winfo exists $icon_win]} {\n"
-" return\n"
-" }\n"
-"\n"
-" set x [expr [winfo rootx $icon_win] + ([winfo width $icon_win]/2)]\n"
-" set y [expr [winfo rooty $icon_win] + [winfo height $icon_win] + 4]\n"
-"\n"
-" set infotext $client_balloon\n"
-" if {!$connected_to_x11vnc} {\n"
-" set infotext \"Not currently attached to x11vnc\\nLast available info:\\n$infotext\"\n"
-" }\n"
-"\n"
-" set w .client_balloon\n"
-" catch {destroy $w}\n"
-" toplevel $w -bg black -screen [winfo screen $icon_win]\n"
-" wm overrideredirect $w 1\n"
-" label $w.l -text \"$infotext\" -relief flat -bg \"#ffffaa\" -fg black \\\n"
-" -padx 2 -pady 0 -anchor w -justify left -font $ffont\n"
-" pack $w.l -side left -padx 1 -pady 1\n"
-"\n"
-" set w2 [winfo reqwidth $w.l]\n"
-" set h2 [winfo reqheight $w.l]\n"
-"\n"
-" set W [winfo screenwidth $w]\n"
-" set H [winfo screenheight $w]\n"
-"\n"
-" if {[expr $x+$w2] > $W} {\n"
-" set w3 [winfo width $icon_win]\n"
-" set x [expr \"$W - $w2 - $w3 - 4\"] \n"
-" }\n"
-" if {[expr $y+$h2] > $H} {\n"
-" set h3 [winfo height $icon_win]\n"
-" set y [expr \"$H - $h2 - $h3 - 4\"] \n"
-" }\n"
-"\n"
-" wm geometry $w +${x}+${y}\n"
-"}\n"
-"\n"
-"proc kill_client_balloon {} {\n"
-" global client_balloon_id client_balloon_win\n"
-" if [info exists client_balloon_id] {\n"
-" catch {after cancel $client_balloon_id}\n"
-" }\n"
-" if [winfo exists .client_balloon] {\n"
-" destroy .client_balloon\n"
-" }\n"
-"}\n"
-"\n"
-"proc icon_win_cfg {clients} {\n"
-" global icon_win client_tail client_sock client_info_read\n"
-"\n"
-" if {! [info exists icon_win]} {\n"
-" return\n"
-" } elseif {$icon_win == \"\"} {\n"
-" return\n"
-" } elseif {! [winfo exists $icon_win]} {\n"
-" return\n"
-" }\n"
-" if {$clients > 0} {\n"
-" $icon_win configure -bg black -fg white\n"
-" } else {\n"
-" $icon_win configure -bg white -fg black\n"
-" }\n"
-"\n"
-" if {$client_tail == \"\" || !$client_info_read} {\n"
-" if {$client_sock == \"\"} {\n"
-" $icon_win configure -fg red\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc server_accept {sock addr port} {\n"
-" global socket_cookie server socket_got_callback\n"
-" global client_tail client_sock\n"
-" set db 0\n"
-"\n"
-" if {$db} {puts stderr \"sock=$sock addr=$addr port=$port\"}\n"
-"\n"
-" update; update idletasks\n"
-" after 50\n"
-" update; update idletasks\n"
-" set count [gets $sock str]\n"
-"\n"
-" if {$count >= 0} {\n"
-" set str [string trim $str]\n"
-" if {$db} {puts stderr \"server_accept: \\\"$str\\\"\"}\n"
-" if {$str == \"COOKIE:$socket_cookie\"} {\n"
-" set client_sock $sock\n"
-" if {$db} {puts stderr \"cookie matched. $client_sock\"}\n"
-" } else {\n"
-" if {$db} {puts stderr \"cookie NO matched.\"}\n"
-" }\n"
-" }\n"
-" catch {close $server}\n"
-" set socket_got_callback 1\n"
-" if {$db} {puts stderr \"socket_got_callback $socket_got_callback\"}\n"
-"}\n"
-"\n"
-"proc try_client_info_sock {} {\n"
-" global socket_cookie server socket_got_callback\n"
-" global x11vnc_started x11vnc_xdisplay hostname client_sock\n"
-" global x11vnc_xdisplay0 menu_var\n"
-"\n"
-" set db 0\n"
-"#dtime t1\n"
-" set start 13037\n"
-" set tries 100\n"
-" set socket_got_callback 0\n"
-"\n"
-" set xd $x11vnc_xdisplay\n"
-" if {$xd == \"\" && $x11vnc_xdisplay0 != \"\"} {\n"
-" set xd $x11vnc_xdisplay0\n"
-" }\n"
-" if {$xd == \"\" && [info exists menu_var(display)]} {\n"
-" set xd $menu_var(display)\n"
-" }\n"
-"\n"
-" set myaddr \"\"\n"
-" regsub {\\..*$} $hostname \"\" shost\n"
-" if {$x11vnc_started} {\n"
-" set myaddr \"127.0.0.1\"\n"
-" } elseif {$xd != \"\"} {\n"
-" if {[regexp {^:} $xd]} {\n"
-" set myaddr \"127.0.0.1\"\n"
-" } elseif {[regexp -nocase \"^$shost\" $xd]} {\n"
-" set myaddr \"127.0.0.1\"\n"
-" } elseif {[regexp -nocase \"^localhost\" $xd]} {\n"
-" set myaddr \"127.0.0.1\"\n"
-" } else {\n"
-" set myaddr $hostname\n"
-" }\n"
-" } else {\n"
-" set myaddr $hostname\n"
-" }\n"
-" \n"
-" for {set i 0} {$i <= $tries} {incr i} {\n"
-" set port [expr $start + $i]\n"
-" set server [socket -server server_accept -myaddr $myaddr $port]\n"
-" if {$server == \"\"} {\n"
-" continue\n"
-" }\n"
-" if {[eof $server]} {\n"
-" continue\n"
-" }\n"
-" set err \"\"\n"
-" catch {set err [fconfigure $server -error]}\n"
-" #puts \"err: $server: $err\"\n"
-" if {$err == \"\"} {\n"
-" break\n"
-" }\n"
-" }\n"
-" if {$server == \"\"} {\n"
-" append_text \"try_client_info_sock: server socket failed.\\n\"\n"
-" return\n"
-" }\n"
-" if {! $x11vnc_started} {\n"
-" run_remote_cmd [list \"-nosync\" \"-R\" \"noop\"]\n"
-" if {$db} {dtime A}\n"
-" after 250\n"
-" if {$db} {dtime A}\n"
-" }\n"
-"\n"
-" # set the cookie to some obscured randomness\n"
-" set socket_cookie [clock clicks]\n"
-" set r [expr rand()]\n"
-" if {$r != \"\"} {\n"
-" append socket_cookie $r\n"
-" }\n"
-" set r \"\"\n"
-" catch {set r [winfo id .]}\n"
-" if {$r != \"\"} {\n"
-" append socket_cookie $r\n"
-" }\n"
-" if {[regexp {([0-9])([0-9])$} [clock clicks] m m1 m2]} {\n"
-" regsub -all {\\.} $socket_cookie $m1 socket_cookie\n"
-" regsub -all {x} $socket_cookie $m2 socket_cookie\n"
-" }\n"
-" run_remote_cmd [list \"-nosync\" \"-R\" \\\n"
-" \"client_info_sock:$myaddr:$port:$socket_cookie\"]\n"
-"#dtime t2\n"
-" if {$db} {puts \"client_info_sock:$myaddr:$port:$socket_cookie\"}\n"
-" for {set i 0} {$i < 10} {incr i} {\n"
-" after 50\n"
-" update; update idletasks\n"
-"#dtime aa\n"
-" if {$socket_got_callback != 0} {\n"
-"#puts \"break-\"\n"
-" break\n"
-" }\n"
-" }\n"
-"#dtime t3\n"
-"\n"
-" set aftid \"\"\n"
-" if {$socket_got_callback == 0} {\n"
-" set aftid [after 10000 {set socket_got_callback 2}]\n"
-" tkwait variable socket_got_callback\n"
-" }\n"
-"\n"
-" if {$aftid != \"\"} {\n"
-" catch {after cancel $aftid}\n"
-" }\n"
-"\n"
-" if {$socket_got_callback != 1} {\n"
-" puts stderr \"try_client_info_sock failed: no callback\\n\"\n"
-" catch {close $server}\n"
-" } else {\n"
-" setup_client_sock 1\n"
-" }\n"
-"#dtime t4\n"
-"}\n"
-"\n"
-"proc set_icon_label {} {\n"
-" global icon_win\n"
-"\n"
-" set lab [get_icon_label]\n"
-"\n"
-" if {! [info exists icon_win]} {\n"
-" return\n"
-" } elseif {$icon_win == \"\"} {\n"
-" return\n"
-" } elseif {! [winfo exists $icon_win]} {\n"
-" return\n"
-" }\n"
-" \n"
-" if {[info exists icon_win]} {\n"
-" $icon_win configure -text $lab\n"
-" }\n"
-"}\n"
-"\n"
-"proc get_icon_label {{set 0}} {\n"
-" global icon_minimal \n"
-"\n"
-" set lab0 \"x11\\nvnc\"\n"
-" \n"
-" if {$icon_minimal} {\n"
-" set lab [get_vnc_display_number]\n"
-" if {$lab != \"none\"} {\n"
-" #set lab \" :$lab\"\n"
-" set lab \":$lab\"\n"
-" } else {\n"
-" set lab \"-\"\n"
-" }\n"
-" } else {\n"
-" set lab $lab0\n"
-" }\n"
-" return $lab\n"
-"}\n"
-"\n"
-"# currently unused\n"
-"proc lmenu {menu} {\n"
-" global popup_cascade_posted\n"
-" global left_iconwin_menu\n"
-" set left_iconwin_menu 1\n"
-" after 100\n"
-" update\n"
-" if {!$popup_cascade_posted && $left_iconwin_menu} {\n"
-" for {set i 0} {$i < 3} {incr i} {\n"
-" after 100\n"
-" update\n"
-" }\n"
-" if {!$popup_cascade_posted && $left_iconwin_menu} {\n"
-" $menu unpost\n"
-" return\n"
-" }\n"
-" }\n"
-" # kludge for WindowView\n"
-" if {$popup_cascade_posted} {\n"
-" focus $menu\n"
-" }\n"
-"}\n"
-"\n"
-"proc old_balloon {} {\n"
-" global client_str saved_clients_str\n"
-" set str \"\"\n"
-" if {[info exists client_str]} {\n"
-" if {$client_str != \"\"} {\n"
-" set str $client_str\n"
-" }\n"
-" }\n"
-" if {$str == \"\"} {\n"
-" if {[info exists saved_clients_str]} {\n"
-" set str $saved_clients_str\n"
-" }\n"
-" }\n"
-" if {$str != \"\"} {\n"
-" set_client_balloon $str\n"
-" }\n"
-"}\n"
-"\n"
-"proc get_custom_menu_items {} {\n"
-" global env custom_last_read\n"
-"\n"
-" if {![info exists custom_last_read]} {\n"
-" set custom_last_read 0\n"
-" }\n"
-" if {[info exists env(X11VNC_CUSTOM_GUI)]} {\n"
-" set custom \"$env(X11VNC_CUSTOM_GUI)\"\n"
-" } elseif {![info exists env(HOME)]} {\n"
-" return [list \"none\"]\n"
-" } else {\n"
-" set custom \"$env(HOME)/.x11vnc.gui\"\n"
-" }\n"
-" if {![file exists $custom]} {\n"
-" return [list \"none\"]\n"
-" }\n"
-"\n"
-"# if {[file mtime $custom] <= $custom_last_read} {\n"
-"# return [list \"nochange\"]\n"
-"# }\n"
-"\n"
-" set in \"\"\n"
-" catch {set in [open $custom \"r\"]} \n"
-" if {$in == \"\"} {\n"
-" return [list \"none\"]\n"
-" }\n"
-"\n"
-" set custom_last_read [clock seconds]\n"
-"\n"
-" set count 0\n"
-" while {[gets $in line] > -1} {\n"
-" if {[regexp {^[ \\t]*#} $line]} {\n"
-" continue\n"
-" }\n"
-" set line [string trim $line]\n"
-" if {$line != \"\"} {\n"
-" lappend items $line\n"
-" incr count\n"
-" }\n"
-" }\n"
-" close $in\n"
-" \n"
-" if {$count > 0} {\n"
-" return $items\n"
-" } else {\n"
-" return [list \"none\"]\n"
-" }\n"
-"}\n"
-"\n"
-"proc make_custom_menu {menu font} {\n"
-" set items [get_custom_menu_items]\n"
-" set i0 [lindex $items 0]\n"
-" catch {$menu delete 0 end}\n"
-" if {$i0 != \"none\"} {\n"
-" $menu add command -font $font -label \"Custom items:\"\n"
-" $menu add separator\n"
-" foreach item $items {\n"
-" if {$item == \"sep\" || $item == \"separator\"} {\n"
-" $menu add separator\n"
-" continue\n"
-" }\n"
-" if {[regexp {^action:(.*)$} $item m action]} {\n"
-" $menu add command -font $font -label \"$action\" \\\n"
-" -command \"do_var $action\"\n"
-" continue\n"
-" }\n"
-" $menu add command -font $font -label \"$item\" \\\n"
-" -command \"run_remote_cmd \\[list \\\"-R\\\" \\\"$item\\\"\\]\"\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc make_icon {} {\n"
-" global icon_mode icon_embed_id icon_win props_win full_win\n"
-" global tray_embed tray_running env\n"
-" global x11vnc_client_file client_tail client_sock client_str saved_clients_str\n"
-" global client_balloon_id\n"
-" global bfont sfont snfont ffont\n"
-" global icon_minimal gui_start_mode\n"
-" global popup_cascade_posted menu_var x11vnc_gui_geom\n"
-" set min_x 24\n"
-" set min_y 24\n"
-" \n"
-" set font $bfont\n"
-" set mfont $font\n"
-"\n"
-" if {$tray_embed} {\n"
-" set font $sfont\n"
-" set mfont $snfont\n"
-" }\n"
-" if {[info exists env(X11VNC_ICON_FONT)]} {\n"
-" set font $env(X11VNC_ICON_FONT)\n"
-" }\n"
-" if {[regexp {([0-9][0-9]*)x([0-9][0-9]*)} $x11vnc_gui_geom m mx my]} {\n"
-" if {$mx < $min_x} {\n"
-" set min_x $mx\n"
-" }\n"
-" if {$my < $min_y} {\n"
-" set min_y $my\n"
-" }\n"
-" }\n"
-" wm minsize . $min_x $min_y\n"
-"\n"
-" if {$tray_embed && $tray_running} {\n"
-" wm withdraw .\n"
-" }\n"
-"\n"
-" set l .icon\n"
-" set icon_win $l\n"
-" catch destroy {$icon_win}\n"
-" if {$icon_minimal} {\n"
-" set bw 1\n"
-" } else {\n"
-" set bw 5\n"
-" }\n"
-" set lab [get_icon_label]\n"
-" label $l -text $lab -borderwidth $bw -font $font\n"
-" icon_win_cfg 0\n"
-"\n"
-"\n"
-" set popup_cascade_posted 0\n"
-" pack $l -fill both -expand 1\n"
-" set menu \"$l.menu\"\n"
-" menu $menu -tearoff 0 -postcommand \"popup_post $menu\"\n"
-" $menu add command -font $mfont -label \"Properties\" -command do_props\n"
-" $menu add command -font $mfont -label \"Help\" -command \"menu_help Tray\"\n"
-" $menu add command -font $mfont -label \"Logfile\" -command show_logfile\n"
-" $menu add separator\n"
-" $menu add command -font $mfont -label \"New Client\" -command do_new_client\n"
-"\n"
-" set wd \"$menu.disconnect\"\n"
-" catch {destroy $wd}\n"
-" menu $wd -tearoff 0 -font $ffont \\\n"
-" -postcommand {set popup_cascade_posted 1}\n"
-" $wd add command -label \"Disconnect client:\"\n"
-" $wd add separator\n"
-" $wd add command -label \"All Clients\" -command do_disconnect_all\n"
-" $menu add cascade -font $mfont -label \"Disconnect:\" -menu $wd\n"
-"\n"
-" $menu add separator\n"
-"\n"
-" set wv \"$menu.windowview\"\n"
-" catch {destroy $wv}\n"
-" menu $wv -tearoff 0 -font $ffont \\\n"
-" -postcommand {set popup_cascade_posted 1}\n"
-" foreach val {full icon tray} {\n"
-" $wv add radiobutton -label \"$val\" \\\n"
-" -value \"$val\" -font $ffont \\\n"
-" -command \"do_var WindowView\" \\\n"
-" -variable menu_var(WindowView)\n"
-" }\n"
-" $menu add cascade -font $mfont -label \"Window View:\" -menu $wv\n"
-"\n"
-" $menu add command -font $mfont -label \"Dismiss\" -command \"$menu unpost\"\n"
-" $menu add command -font $mfont -label \"Stop x11vnc\" -command clean_icon_exit\n"
-"\n"
-" set items [get_custom_menu_items]\n"
-" set i0 [lindex $items 0]\n"
-" if {$i0 != \"none\" && $i0 != \"nochange\"} {\n"
-" $menu add separator\n"
-" set cm \"$menu.custom\"\n"
-" catch {destroy $cm}\n"
-" menu $cm -tearoff 0 -font $ffont \\\n"
-" -postcommand \"set popup_cascade_posted 1; make_custom_menu $cm $ffont\"\n"
-" $menu add cascade -font $mfont -label \"Custom:\" -menu $cm\n"
-" }\n"
-"\n"
-" bind $icon_win <ButtonRelease-1> \"pmenu $menu %X %Y\"\n"
-" bind $icon_win <ButtonRelease-3> \"pmenu $menu %X %Y\"\n"
-" bind $icon_win <Enter> {set client_balloon_id [after 500 show_client_balloon]}\n"
-" bind $icon_win <Button> {kill_client_balloon}\n"
-" bind $icon_win <Leave> {kill_client_balloon}\n"
-" bind $icon_win <Shift-ButtonRelease-1> {kill_client_balloon; show_client_balloon}\n"
-" bind $icon_win <ButtonRelease-2> {kill_client_balloon; show_client_balloon}\n"
-"# bind $menu <Leave> \"lmenu $menu\"\n"
-"# bind $menu <Enter> \"set left_iconwin_menu 0\"\n"
-"# bind $menu <KeyPress-Escape> \"$menu unpost\"\n"
-"\n"
-" bind . <Control-KeyPress-c> {destroy .; exit 0}\n"
-"\n"
-" if {!$tray_embed || !$tray_running} {\n"
-" global x11vnc_gui_geom\n"
-" if {$x11vnc_gui_geom != \"\"} {\n"
-" set doit 1\n"
-" if {[regexp {x} $x11vnc_gui_geom]} {\n"
-" if {$gui_start_mode == \"full\"} {\n"
-" set doit 0\n"
-" }\n"
-" } \n"
-" if {$doit} {\n"
-" wm geometry . $x11vnc_gui_geom\n"
-" }\n"
-" }\n"
-" }\n"
-" wm iconname . \"tkx11vnc\"\n"
-" wm title . \"tkx11vnc\"\n"
-" update\n"
-" if {$tray_embed && $tray_running} {\n"
-" #wm deiconify .; # why did we have this???\n"
-" #after 10000 {wm deiconify .; puts \"reqheight [winfo reqheight .]\"; puts \"reqwidth [winfo reqwidth .]\"; puts \"height [winfo height .]\"; puts \"width [winfo width .]\"}\n"
-" } else {\n"
-" wm deiconify .\n"
-" }\n"
-" update\n"
-"\n"
-"#puts \"reqheight [winfo reqheight .]\"\n"
-"#puts \"reqwidth [winfo reqwidth .]\"\n"
-"#puts \"height [winfo height .]\"\n"
-"#puts \"width [winfo width .]\"\n"
-"#puts \"AAA\"\n"
-"\n"
-" old_balloon\n"
-"}\n"
-"\n"
-"proc setup_client_channel {} {\n"
-" global client_sock client_tail\n"
-"\n"
-"# XXX/setup_client_channel\n"
-" if {$client_sock == \"\" } {\n"
-" stop_watch on\n"
-" try_client_info_sock\n"
-" if {$client_sock == \"\" } {\n"
-" after 500\n"
-" try_client_info_sock\n"
-" }\n"
-" stop_watch off\n"
-" }\n"
-" if {$client_tail == \"\" && $client_sock == \"\"} {\n"
-" set m \"\\n\"\n"
-" set m \"${m}tkx11vnc:\\n\"\n"
-" set m \"${m}\\n\"\n"
-" set m \"${m} Warning -- running in icon/tray mode but the\\n\"\n"
-" set m \"${m} connected client info channel from x11vnc is\\n\"\n"
-" set m \"${m} not working. The viewer client list and icon\\n\"\n"
-" set m \"${m} color indicator will not be accurate.\\n\"\n"
-" set m \"${m}\\n\"\n"
-" set m \"${m} You may need to restart \\\"x11vnc -gui tray ...\\\"\\n\"\n"
-" set m \"${m} for this to work properly.\\n\"\n"
-" set m \"${m}\\n\"\n"
-" textwin \"Warning\" \"Warning\" $m\n"
-" update\n"
-" }\n"
-" dtime C\n"
-"}\n"
-"\n"
-"proc clean_client_tail {} {\n"
-" global client_tail client_info_read\n"
-" if [info exists client_tail] {\n"
-" if {$client_tail != \"\"} {\n"
-" set p \"\"\n"
-" catch {set p [pid $client_tail]}\n"
-" if {$p != \"\"} {\n"
-" catch {exec kill -TERM $p >/dev/null 2>/dev/null}\n"
-" }\n"
-" catch {close $client_tail}\n"
-" set client_tail \"\"\n"
-" }\n"
-" }\n"
-" set client_info_read 0\n"
-"}\n"
-"\n"
-"proc clean_icon_exit {} {\n"
-" clean_client_tail\n"
-" push_new_value \"stop\" \"stop\" 1 0\n"
-" set_connected no\n"
-" update\n"
-" destroy .\n"
-" exit\n"
-"}\n"
-"\n"
-"proc make_gui {mode} {\n"
-" global icon_mode tray_embed tray_running full_win icon_win\n"
-" global top_widget_names x11vnc_gui_geom\n"
-" global gui_current_state make_gui_count\n"
-" global x11vnc_connect connected_to_x11vnc\n"
-" global x11_display\n"
-" global gui_start_mode\n"
-"\n"
-" incr make_gui_count\n"
-"\n"
-" if {$gui_start_mode == \"\"} {\n"
-" set gui_start_mode $mode\n"
-" }\n"
-"\n"
-" wm withdraw .\n"
-"\n"
-" set full_geom \"\"\n"
-" if {[winfo exists .full]} {\n"
-" catch {set full_geom [wm geometry .full]}\n"
-" }\n"
-"\n"
-" set fw .full\n"
-" set full_win $fw\n"
-" catch {pack forget $full_win}\n"
-" catch {pack forget $icon_win}\n"
-" catch {destroy $full_win}\n"
-" catch {destroy $icon_win}\n"
-"\n"
-" wm minsize . 1 1\n"
-"\n"
-" set gui_current_state \"\"\n"
-"\n"
-" if {$mode == \"full\"} {\n"
-" frame $fw\n"
-" set icon_mode 0\n"
-"\n"
-" wm protocol . WM_DELETE_WINDOW \"destroy .; exit\"\n"
-" make_widgets $fw\n"
-"\n"
-" set w \".\"\n"
-" wm geometry $w \"\"\n"
-" if {$x11vnc_gui_geom != \"\"} {\n"
-" set doit 1\n"
-" if {[regexp {x} $x11vnc_gui_geom]} {\n"
-" if {$gui_start_mode != $mode} {\n"
-" set doit 0\n"
-" }\n"
-" }\n"
-" if {$doit} {\n"
-" wm geometry $w $x11vnc_gui_geom\n"
-" }\n"
-" }\n"
-" pack $fw -fill both -expand 1\n"
-"\n"
-" } elseif {$mode == \"icon\" || $mode == \"tray\"} {\n"
-"\n"
-" toplevel $fw\n"
-" wm withdraw $fw\n"
-"\n"
-" wm protocol $fw WM_DELETE_WINDOW \"wm withdraw .full\"\n"
-" wm protocol . WM_DELETE_WINDOW \"clean_icon_exit\"\n"
-" \n"
-" if {$mode == \"icon\"} {\n"
-" set tray_embed 0\n"
-" } elseif {$mode == \"tray\"} {\n"
-" set tray_embed 1\n"
-" }\n"
-" set icon_mode 1\n"
-" make_widgets $fw\n"
-" set w $fw\n"
-" make_icon\n"
-" wm geometry $fw \"\"\n"
-" wm geometry . \"\"\n"
-" } else {\n"
-" return\n"
-" }\n"
-" set_view_variable $mode\n"
-" set gui_current_state $mode\n"
-"\n"
-"\n"
-" update\n"
-" if {!$tray_embed || !$tray_running} {\n"
-" wm deiconify .\n"
-" }\n"
-" update idletasks\n"
-" wm minsize $w [winfo width $w] [winfo height $w]\n"
-" if {$mode == \"full\" && $make_gui_count > 1} {\n"
-" center_win .\n"
-" }\n"
-"\n"
-"\n"
-" if {$make_gui_count == 1} {\n"
-" copy_default_vars\n"
-" if {$x11vnc_connect} {\n"
-" try_connect_and_query_all\n"
-" } else {\n"
-" insert_cmdline_vars\n"
-" }\n"
-" } else {\n"
-" set_name \"RESTORE\"\n"
-" }\n"
-"\n"
-" setup_client_tail\n"
-"\n"
-" set_widgets\n"
-"\n"
-" if {$mode == \"tray\"} {\n"
-" setup_tray_embed\n"
-" }\n"
-"}\n"
-"\n"
-"proc make_widgets {top} {\n"
-" global template make_gui_count\n"
-" global menu_b menu_m menu_count\n"
-" global item_opts item_bool item_case item_menu item_entry menu_var unset_str\n"
-" global item_cascade\n"
-" global info_label info_str x11_display vnc_display\n"
-" global text_area text_area_str\n"
-" global entry_box entry_str entry_set entry_label entry_ok entry_browse\n"
-" global entry_help entry_skip\n"
-" global bfont ffont beginner_mode\n"
-" global helptext helpremote helplabel\n"
-" global icon_mode icon_win props_win full_win\n"
-" global top_widget_names\n"
-" global screen_height screen_width\n"
-"\n"
-"\n"
-" # Make the top label\n"
-" set label_width 84\n"
-" if {$screen_width <= 400} {\n"
-" set label_width 64\n"
-" }\n"
-" set info_label \"$top.info\"\n"
-" label $info_label -textvariable info_str -bd 2 -relief groove \\\n"
-" -anchor w -width $label_width -font $ffont\n"
-" pack $info_label -side top -fill x -expand 0\n"
-"\n"
-" set top_widget_names(info) $info_label\n"
-"\n"
-" # Extract the Rows:\n"
-" set row 0;\n"
-" set colmax 0;\n"
-" foreach line [split $template \"\\n\"] {\n"
-" if {[regexp {^Row: (.*)} $line rest]} {\n"
-" set col 0\n"
-" foreach case [split $rest] {\n"
-" if {$case == \"\" || $case == \"Row:\"} {\n"
-" continue\n"
-" }\n"
-" set menu_row($case) $row\n"
-" set menu_col($case) $col\n"
-"\n"
-" lappend cases($col) $case;\n"
-" set len [string length $case]\n"
-" if {[info exists max_len($col)]} {\n"
-" if {$len > $max_len($col)} {\n"
-" set max_len($col) $len\n"
-" }\n"
-" } else {\n"
-" set max_len($col) $len\n"
-" }\n"
-" incr col\n"
-" if {$col > $colmax} {\n"
-" set colmax $col\n"
-" }\n"
-" }\n"
-" incr row;\n"
-" }\n"
-" }\n"
-"\n"
-" # Make frames for the rows and make the menu buttons.\n"
-" set f \"$top.menuframe\"\n"
-" frame $f\n"
-" for {set c 0} {$c < $colmax} {incr c} {\n"
-" set colf \"$f.menuframe$c\"\n"
-" frame $colf\n"
-" pack $colf -side left -fill y\n"
-" set fbg [$colf cget -background]\n"
-" foreach case $cases($c) {\n"
-" set menub \"$colf.menu$case\";\n"
-" set menu \"$colf.menu$case.menu\";\n"
-" set menu_b($case) $menub\n"
-" set menu_m($case) $menu\n"
-" set ul 0\n"
-" foreach char [split $case \"\"] {\n"
-" set char [string tolower $char]\n"
-" if {![info exists underlined($char)]} {\n"
-" set underlined($char) 1\n"
-" break\n"
-" }\n"
-" incr ul\n"
-" }\n"
-" global osname\n"
-" set tstr \"$case\"\n"
-" if {$osname == \"Darwin\"} {\n"
-" #set tstr \" $case \"\n"
-" }\n"
-" menubutton $menub -text \"$tstr\" -underline $ul \\\n"
-" -anchor w -menu $menu -background $fbg \\\n"
-" -font $bfont\n"
-" pack $menub -side top -fill x\n"
-" menu $menu -tearoff 0 -postcommand menu_posted\n"
-" }\n"
-" }\n"
-" pack $f -side top -fill x\n"
-" set top_widget_names(menuframe) $f\n"
-"\n"
-" make_menu_items\n"
-"\n"
-" # Make the x11 and vnc display label bar:\n"
-" set df \"$top.displayframe\"\n"
-" frame $df -bd 1 -relief groove\n"
-" set top_widget_names(displayframe) $df\n"
-"\n"
-" set df_x11 \"$df.xdisplay\"\n"
-"\n"
-" if {$make_gui_count == 1} {\n"
-" no_x11_display\n"
-" }\n"
-" set lw [expr {$label_width / 2}]\n"
-" label $df_x11 -textvariable x11_display -width $lw -anchor w \\\n"
-" -font $ffont\n"
-"\n"
-" set df_vnc \"$df.vdisplay\"\n"
-"\n"
-" if {$make_gui_count == 1} {\n"
-" no_vnc_display\n"
-" }\n"
-" label $df_vnc -textvariable vnc_display -width $lw -anchor w \\\n"
-" -font $ffont\n"
-"\n"
-" pack $df_x11 $df_vnc -side left \n"
-" pack $df -side top -fill x\n"
-"\n"
-" # text area\n"
-" global text_height\n"
-" set text_area \"$top.text\"\n"
-" if {$screen_width <= 400} {\n"
-" text $text_area -height $text_height -width $label_width \\\n"
-" -relief ridge -font $ffont\n"
-" } else {\n"
-" text $text_area -height $text_height -relief ridge -font $ffont\n"
-" }\n"
-" pack $text_area -side top -fill both -expand 1\n"
-" set top_widget_names(text) $text_area\n"
-"\n"
-"\n"
-" if {$text_area_str == \"\"} {\n"
-" set str \"Click Help -> gui for overview.\"\n"
-" append_text \"\\n$str\\n\\n\"\n"
-" } else {\n"
-" append_text $text_area_str\n"
-" }\n"
-"\n"
-" # Make entry box stuff\n"
-" set ef \"$top.entryframe\"\n"
-" frame $ef -bd 1 -relief groove\n"
-" set top_widget_names(entryframe) $ef\n"
-"\n"
-" # Entry Label\n"
-" set ef_label \"$ef.label\"\n"
-" label $ef_label -textvariable entry_str -anchor w -font $bfont\n"
-"\n"
-" set entry_str \"Set... : \"\n"
-" set ef_entry \"$ef.entry\"\n"
-" entry $ef_entry -relief sunken -font $ffont\n"
-" bind $ef_entry <KeyPress-Return> {set entry_set 1}\n"
-" bind $ef_entry <KeyPress-Escape> {set entry_set 0}\n"
-"\n"
-" set ok_s \"OK\"\n"
-" set cancel_s \"Cancel\"\n"
-" set help_s \"Help\"\n"
-" set browse_s \"Browse...\"\n"
-" global osname\n"
-" if {$osname == \"Darwin\"} {\n"
-" set ok_s \" OK \"\n"
-" set cancel_s \" Cancel \"\n"
-" set help_s \" Help \"\n"
-" set browse_s \" Browse... \"\n"
-" }\n"
-"\n"
-" # Entry OK button\n"
-" set bpx \"1m\"\n"
-" set bpy \"1\"\n"
-" set hlt \"0\"\n"
-" set ef_ok \"$ef.ok\"\n"
-" button $ef_ok -text $ok_s -pady $bpy -padx $bpx -command {set entry_set 1} \\\n"
-" -highlightthickness $hlt \\\n"
-" -font $bfont\n"
-"\n"
-" # Entry Skip button\n"
-" set ef_skip \"$ef.skip\"\n"
-" button $ef_skip -text $cancel_s -pady $bpy -padx $bpx -command {set entry_set 0} \\\n"
-" -highlightthickness $hlt \\\n"
-" -font $bfont\n"
-"\n"
-" # Entry Help button\n"
-" set ef_help \"$ef.help\"\n"
-" button $ef_help -text $help_s -pady $bpy -padx $bpx -command \\\n"
-" {menu_help $entry_dialog_item} -font $bfont \\\n"
-" -highlightthickness $hlt\n"
-"\n"
-" # Entry Browse button\n"
-" set ef_browse \"$ef.browse\"\n"
-" button $ef_browse -text $browse_s -pady $bpy -padx $bpx -font $bfont \\\n"
-" -highlightthickness $hlt \\\n"
-" -command {entry_insert [tk_getOpenFile]} \n"
-"\n"
-" pack $ef_label -side left\n"
-" pack $ef_entry -side left -fill x -expand 1\n"
-" pack $ef_ok -side right\n"
-" pack $ef_skip -side right\n"
-" pack $ef_help -side right\n"
-" pack $ef -side bottom -fill x\n"
-"\n"
-" set entry_ok $ef_ok\n"
-" set entry_skip $ef_skip\n"
-" set entry_help $ef_help\n"
-" set entry_box $ef_entry\n"
-" set entry_browse $ef_browse\n"
-" set entry_label $ef_label\n"
-" entry_disable\n"
-"\n"
-"}\n"
-"\n"
-"proc menu_bindings {m} {\n"
-" set db 0\n"
-" if {$db} {puts \"menu_bindings $m\"}\n"
-"\n"
-" bind $m <<MenuSelect>> {\n"
-"#syntax hilite bug \\\n"
-"MenuSelect>>\n"
-" set n [%W index active]\n"
-" set db 0\n"
-" if {$db} {puts stderr \"menu_bindings %W $n\"}\n"
-" set label \" \"\n"
-" if {$n != \"none\"} {\n"
-" set str %W,$n\n"
-" set which \"\"\n"
-"\n"
-" if {$db} {puts \"menu_bindings $str\"}\n"
-" if {[info exists helplabel($str)]} {\n"
-" set vname [format %%-16s $helplabel($str)]\n"
-" set label \"Click (?) for help on: $vname\"\n"
-" set which $helplabel($str)\n"
-" }\n"
-" if {$which == \"\"} {\n"
-" ;\n"
-" } elseif {$which == \"passwd\" || $which == \"viewpasswd\"} {\n"
-" ;\n"
-" } elseif {[is_action $which]} {\n"
-" if {[info exists menu_var($which)] \n"
-" && $menu_var($which) != \"\"} {\n"
-" set label \"$label value: $menu_var($which)\"\n"
-" } else {\n"
-" set label \"$label (is action)\"\n"
-" }\n"
-" } elseif {[info exists menu_var($which)]} {\n"
-" set label \"$label value: $menu_var($which)\"\n"
-" if {$which == \"http\"} {\n"
-" global vnc_url\n"
-" set label \"$label URL: $vnc_url\"\n"
-" }\n"
-" }\n"
-" }\n"
-" set_info $label\n"
-" }\n"
-"}\n"
-"\n"
-"proc key_bindings {} {\n"
-" global env menus_disabled\n"
-" if {[info exists env(USER)] && $env(USER) == \"runge\"} {\n"
-" # quick restart\n"
-" bind . <Control-KeyPress-k> {exec $argv0 $argv &; destroy .}\n"
-" }\n"
-" bind . <Control-KeyPress-p> { \\\n"
-" global menus_disabled; \\\n"
-" if {!$menus_disabled} {try_connect_and_query_all} \\\n"
-" }\n"
-" bind . <Control-KeyPress-u> { \\\n"
-" global menus_disabled; \\\n"
-" if {!$menus_disabled} {query_all 0} \\\n"
-" }\n"
-" bind . <Control-KeyPress-r> { \\\n"
-" global menus_disabled; \\\n"
-" if {!$menus_disabled} {query_all 0} \\\n"
-" }\n"
-" bind . <Control-KeyPress-d> { \\\n"
-" global menus_disabled; \\\n"
-" if {!$menus_disabled} {detach_from_display} \\\n"
-" }\n"
-" bind . <Control-KeyPress-a> { \\\n"
-" global menus_disabled; \\\n"
-" if {!$menus_disabled} {try_connect_and_query_all} \\\n"
-" }\n"
-"}\n"
-"\n"
-"proc stop_watch {onoff} {\n"
-" global orig_cursor text_area entry_box\n"
-"\n"
-" set widgets [list .]\n"
-" if [info exists text_area] {\n"
-" if {$text_area != \"\"} {\n"
-" lappend widgets $text_area\n"
-" }\n"
-" }\n"
-" if [info exists entry_box] {\n"
-" if {$entry_box != \"\"} {\n"
-" lappend widgets $entry_box\n"
-" }\n"
-" }\n"
-"\n"
-" if {$onoff == \"on\"} {\n"
-" foreach item $widgets {\n"
-" if {![winfo exists $item]} {\n"
-" continue\n"
-" }\n"
-" $item config -cursor {watch}\n"
-" }\n"
-" } else {\n"
-" foreach item $widgets {\n"
-" if {![winfo exists $item]} {\n"
-" continue\n"
-" }\n"
-" $item config -cursor {}\n"
-" }\n"
-" }\n"
-" update\n"
-"}\n"
-"\n"
-"proc double_check_noremote {} {\n"
-" set msg \"\\n\\n\"\n"
-" append msg \"*** WARNING: setting \\\"noremote\\\" will disable ALL remote control commands (i.e.\\n\"\n"
-" append msg \"*** WARNING: *this* gui will be locked out). Do you really want to do this?\\n\"\n"
-" append msg \"*** WARNING: If so, press \\\"OK\\\", otherwise press \\\"Cancel\\\"\\n\"\n"
-" append msg \"\\n\"\n"
-" bell\n"
-" return [warning_dialog $msg \"noremote\"]\n"
-"}\n"
-"\n"
-"proc get_settings_rcfile {} {\n"
-" global menu_var default_var unset_str\n"
-" global x11vnc_gui_params\n"
-"\n"
-" set rc_txt \"\"\n"
-"\n"
-" set menu_var(gui) $x11vnc_gui_params\n"
-"\n"
-" foreach item [lsort [array names menu_var]] {\n"
-" if {$item == \"gui\"} {\n"
-" ;\n"
-" } elseif {![active_when_starting $item]} {\n"
-" continue\n"
-" } elseif {[is_action $item]} {\n"
-" continue\n"
-" }\n"
-" if {$item == \"debug_gui\"} {\n"
-" continue\n"
-" } elseif {$item == \"WindowView\"} {\n"
-" continue\n"
-" } elseif {$item == \"rc\" || $item == \"norc\"} {\n"
-" continue\n"
-" } elseif {$item == \"loop\"} {\n"
-" continue\n"
-" } elseif {$item == \"loopbg\"} {\n"
-" continue\n"
-" }\n"
-"\n"
-" set def \"\"\n"
-" if {[info exists default_var($item)]} {\n"
-" set def $default_var($item)\n"
-" }\n"
-"\n"
-"\n"
-" set qst \"\"\n"
-" set hmm \"#? \"\n"
-" if {$item == \"display\"} {\n"
-" set qst $hmm\n"
-" } elseif {$item == \"desktop\"} {\n"
-" set qst $hmm\n"
-" } elseif {$item == \"dontdisconnect\"} {\n"
-" set qst $hmm\n"
-" } elseif {$item == \"alwaysshared\"} {\n"
-" set qst $hmm\n"
-" } elseif {$item == \"nevershared\"} {\n"
-" set qst $hmm\n"
-" } elseif {$item == \"gui\"} {\n"
-" set qst $hmm\n"
-" }\n"
-"\n"
-" if {![info exists menu_var($item)]} {\n"
-" set mv $def\n"
-" } else {\n"
-" set mv $menu_var($item)\n"
-" }\n"
-"#puts \"item=$item def=$def mv=$mv\"\n"
-" if {$mv == $unset_str} {\n"
-" set mv \"\"\n"
-" }\n"
-" set ntab 3\n"
-"\n"
-" if {$item == \"gui\" || [value_is_string $item]} {\n"
-" set nitem [get_nitem $item]\n"
-"\n"
-" if {$mv == \"\" && $def != \"\"} {\n"
-" set qst $hmm\n"
-" }\n"
-" set n 0\n"
-" if {$qst != \"\"} {\n"
-" append rc_txt $qst\n"
-" incr n [string length $qst]\n"
-" } elseif {$mv == $def} {\n"
-" append rc_txt \"#d \"\n"
-" incr n [string length \"#d \"]\n"
-" }\n"
-" set mt $mv\n"
-" regsub -all {#} $mt {\\#} mt\n"
-" if {$mt == \"\"} {\n"
-" set mt {\"\"}\n"
-" }\n"
-" append rc_txt \"-$nitem $mt\"\n"
-"\n"
-" if {$mv != $def} {\n"
-" set m [string length \"-$nitem $mt\"]\n"
-" incr n $m\n"
-" set n [expr $n / 8]\n"
-" set c 0\n"
-" for {set i $n} {$i <= $ntab} {incr i} {\n"
-" append rc_txt \"\\t\"\n"
-" incr c\n"
-" }\n"
-" if {$c == 0} {\n"
-" append rc_txt \"\\t\"\n"
-" }\n"
-" regsub -all {#} $def {\\#} def\n"
-" if {$def == \"\"} {\n"
-" set def {\"\"}\n"
-" }\n"
-" append rc_txt \"# default: $def\"\n"
-" }\n"
-" append rc_txt \"\\n\"\n"
-"\n"
-" } elseif {[value_is_bool $item]} {\n"
-" set n 0\n"
-" if {$qst != \"\"} {\n"
-" append rc_txt $qst\n"
-" incr n [string length $qst]\n"
-" } elseif {$mv == $def} {\n"
-" append rc_txt \"#d \"\n"
-" incr n [string length \"#d \"]\n"
-" }\n"
-" if {$def == 1} {\n"
-" set dv \"on\"\n"
-" } else {\n"
-" set dv \"off\"\n"
-" }\n"
-" append rc_txt \"-$item\"\n"
-" set m [string length \"-$item\"]\n"
-" incr n $m\n"
-" set n [expr $n / 8]\n"
-" for {set i $n} {$i <= $ntab} {incr i} {\n"
-" append rc_txt \"\\t\"\n"
-" }\n"
-" append rc_txt \"# default: $dv\"\n"
-" append rc_txt \"\\n\"\n"
-"\n"
-" }\n"
-" }\n"
-" return $rc_txt\n"
-"}\n"
-"\n"
-"proc double_check_start_x11vnc {} {\n"
-" global hostname\n"
-" set msg [get_start_x11vnc_txt]\n"
-" bell\n"
-" append msg \"\\n\"\n"
-" append msg \"*** To run the above command on machine \\\"$hostname\\\" (thereby\\n\"\n"
-" append msg \"*** starting x11vnc) press \\\"OK\\\", otherwise press \\\"Cancel\\\".\\n\"\n"
-" return [warning_dialog $msg \"start\"]\n"
-"}\n"
-"\n"
-"proc get_start_x11vnc_txt {} {\n"
-" set cmd [get_start_x11vnc_cmd]\n"
-" set str [join $cmd]\n"
-" set msg \"\"\n"
-" append msg \"\\n\"\n"
-" append msg \"==== The command built so far is: ====\\n\";\n"
-" append msg \"\\n\"\n"
-" append msg \"$str\\n\"\n"
-" return $msg\n"
-"}\n"
-"\n"
-"proc show_start_cmd {} {\n"
-" set msg [get_start_x11vnc_txt]\n"
-" append_text \"$msg\\n\"\n"
-"}\n"
-"\n"
-"proc get_nitem {item} {\n"
-" set nitem $item\n"
-" if {$nitem == \"screen_blank\"} {\n"
-" set nitem \"sb\"\n"
-" } elseif {$nitem == \"xrandr_mode\"} {\n"
-" set nitem \"xrandr\"\n"
-" } elseif {$nitem == \"unixpw_list\"} {\n"
-" set nitem \"unixpw\"\n"
-" } elseif {$nitem == \"unixpw_nis_list\"} {\n"
-" set nitem \"unixpw_nis\"\n"
-" } elseif {$nitem == \"stunnel_pem\"} {\n"
-" set nitem \"stunnel\"\n"
-" } elseif {$nitem == \"ssl_pem\"} {\n"
-" set nitem \"ssl\"\n"
-" } elseif {$nitem == \"wireframe_mode\"} {\n"
-" set nitem \"wireframe\"\n"
-" } elseif {$nitem == \"solid_color\"} {\n"
-" set nitem \"solid\"\n"
-" }\n"
-" return $nitem\n"
-"}\n"
-"\n"
-"proc get_start_x11vnc_cmd {{show_rc 0}} {\n"
-" global cmd_var menu_var default_var unset_str x11vnc_prog\n"
-"\n"
-" set xterm_cmd \"xterm -iconic -geometry 80x35 -title x11vnc-console -e\"\n"
-"\n"
-" set cmd [split $xterm_cmd]\n"
-"\n"
-" lappend cmd $x11vnc_prog\n"
-"\n"
-" lappend cmd \"-gui\"\n"
-" lappend cmd \"none\"\n"
-"\n"
-" set rc_txt \"\"\n"
-"\n"
-" set saw_id 0\n"
-"\n"
-" foreach item [lsort [array names menu_var]] {\n"
-" if {$item == \"gui\"} {\n"
-" continue\n"
-" } elseif {![active_when_starting $item]} {\n"
-" continue\n"
-" } elseif {[is_action $item]} {\n"
-" continue\n"
-" } elseif {$item == \"debug_gui\"} {\n"
-" continue\n"
-" } elseif {$item == \"WindowView\"} {\n"
-" continue\n"
-" }\n"
-"\n"
-" if {$item == \"id\" || $item == \"sid\"} {\n"
-" set val $menu_var($item);\n"
-" if {$val == \"0x0\" || $val == \"root\"} {\n"
-" continue\n"
-" }\n"
-" }\n"
-" if {$item == \"sid\" && $saw_id} {\n"
-" continue\n"
-" }\n"
-" if {$item == \"id\"} {\n"
-" set saw_id 1\n"
-" } elseif {$item == \"httpport\" && $menu_var($item) == \"0\"} {\n"
-" continue\n"
-" } elseif {$item == \"progressive\" && $menu_var($item) == \"0\"} {\n"
-" continue\n"
-" } elseif {$item == \"dontdisconnect\" && $menu_var($item) == \"-1\"} {\n"
-" continue\n"
-" } elseif {$item == \"alwaysshared\" && $menu_var($item) == \"-1\"} {\n"
-" continue\n"
-" }\n"
-"\n"
-" if {[value_is_bool $item]} {\n"
-" if {[info exists menu_var($item)]} {\n"
-" set add 1\n"
-" if {[info exists default_var($item)]} {\n"
-" if {$menu_var($item) == $default_var($item)} {\n"
-" set add 0;\n"
-" }\n"
-" } elseif {! $menu_var($item)} {\n"
-" set add 0\n"
-" }\n"
-" if {$add} {\n"
-" lappend cmd \"-$item\"\n"
-" append rc_txt \"-$item\\n\"\n"
-" }\n"
-" }\n"
-" } elseif {[value_is_string $item]} {\n"
-" if {![info exists menu_var($item)]} {\n"
-" continue\n"
-" }\n"
-" if {$menu_var($item) != \"\" && $menu_var($item) != $unset_str} {\n"
-" set add 1\n"
-" set nitem [get_nitem $item]\n"
-"\n"
-" if {[info exists default_var($item)]} {\n"
-" if {$menu_var($item) == $default_var($item)} {\n"
-" set add 0;\n"
-" }\n"
-" }\n"
-" if {$add} {\n"
-" lappend cmd \"-$nitem\"\n"
-" set mv $menu_var($item)\n"
-"\n"
-" if {[regexp {^~} $mv]} {\n"
-" if {$item == \"auth\" ||\n"
-" $item == \"rc\" ||\n"
-" $item == \"accept\" || \n"
-" $item == \"connect\" || \n"
-" $item == \"allow\" || \n"
-" $item == \"passwdfile\" || \n"
-" $item == \"o\" || \n"
-" $item == \"logfile\" || \n"
-" $item == \"remap\" || \n"
-" $item == \"httpdir\"} { \n"
-" set mv [tilde_expand $mv]\n"
-" }\n"
-" }\n"
-" \n"
-" lappend cmd $mv\n"
-" set mt $mv\n"
-" regsub -all {#} $mt {\\#} mt\n"
-" append rc_txt \"-$nitem $mt\\n\"\n"
-" }\n"
-" }\n"
-" }\n"
-" }\n"
-" lappend cmd \"2>\"\n"
-" lappend cmd \"/dev/null\"\n"
-" lappend cmd \"&\"\n"
-" \n"
-" if {$show_rc} {\n"
-" return $rc_txt\n"
-" } else {\n"
-" return $cmd\n"
-" }\n"
-"}\n"
-"\n"
-"proc start_x11vnc {} {\n"
-" global menu_var unset_str\n"
-" global x11vnc_prog x11vnc_xdisplay\n"
-" global connected_to_x11vnc\n"
-"\n"
-" if {$connected_to_x11vnc} {\n"
-" append_text \"\\n\"\n"
-" append_text \"WARNING: Still connected to an x11vnc server.\\n\"\n"
-" append_text \"WARNING: Use \\\"stop\\\" or \\\"detach\\\" first.\\n\"\n"
-" return 0\n"
-" }\n"
-"\n"
-" if {![double_check_start_x11vnc]} {\n"
-" return\n"
-" }\n"
-"\n"
-" set x11vnc_xdisplay \"\"\n"
-" if {[info exists menu_var(display)]} {\n"
-" if {$menu_var(display) != \"\" && $menu_var(display) != $unset_str} {\n"
-" set x11vnc_xdisplay $menu_var(display)\n"
-" }\n"
-" }\n"
-"\n"
-" set cmd [get_start_x11vnc_cmd]\n"
-"\n"
-" set str [join $cmd]\n"
-" regsub { -e} $str \" -e \\\\\\n \" str\n"
-"\n"
-" if {0} {\n"
-" puts \"running: $str\"\n"
-" foreach word $cmd {\n"
-" puts \" word: $word\"\n"
-" }\n"
-" }\n"
-"\n"
-" append_text \"Starting x11vnc in an iconified xterm with command:\\n\"\n"
-" append_text \" $str\\n\\n\"\n"
-" catch {[eval exec $cmd]}\n"
-" after 500\n"
-" try_connect_and_query_all 3\n"
-" if {!$connected_to_x11vnc} {\n"
-" append_text \"\\nStarting x11vnc seems to have failed.\\n\"\n"
-" if {[regexp -- {-o } $str] || [regexp -- {-logfile} $str]} {\n"
-" append_text \"Examine the logfile (Debugging -> show-logfile) for error messages.\\n\"\n"
-" } else {\n"
-" append_text \"Rerun with a logfile (if needed) and examine the logfile\\n\"\n"
-" append_text \"(Debugging -> show-logfile) for error messages.\\n\"\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc run_remote_cmd_via_sock {opts} {\n"
-" global client_sock\n"
-"\n"
-" set db 0\n"
-" if {[file channels $client_sock] == \"\"} {\n"
-" set client_sock \"\"\n"
-" return \"fail\"\n"
-" }\n"
-" if {[eof $client_sock]} {\n"
-" catch {close $client_sock}\n"
-" set client_sock \"\"\n"
-" return \"fail\"\n"
-" }\n"
-" set result \"\"\n"
-" \n"
-" setup_client_sock 0\n"
-"\n"
-" set docmd \"\"\n"
-" foreach opt $opts {\n"
-" if {$opt == \"-R\"} {\n"
-" set docmd \"-R\"\n"
-" continue\n"
-" } elseif {$opt == \"-Q\"} {\n"
-" set docmd \"-Q\"\n"
-" continue\n"
-" }\n"
-"\n"
-" if {$docmd == \"\"} {\n"
-" continue\n"
-" } elseif {$docmd == \"-R\"} {\n"
-" set str \"cmd=$opt\"\n"
-" } elseif {$docmd == \"-Q\"} {\n"
-" set str \"qry=$opt\"\n"
-" } else {\n"
-" set docmd \"\"\n"
-" continue\n"
-" }\n"
-"\n"
-" if {$db} {puts stderr \"run_remote_cmd_via_sock: $docmd \\\"$str\\\"\"}\n"
-" catch {puts $client_sock $str}\n"
-" if {$db} {puts stderr \"run_remote_cmd_via_sock: flush\"}\n"
-" catch {flush $client_sock}\n"
-" if {$db} {puts stderr \"run_remote_cmd_via_sock: gets\"}\n"
-" catch {gets $client_sock res}\n"
-" if {$db} {puts stderr \"run_remote_cmd_via_sock: \\\"$res\\\"\"}\n"
-" set res [string trim $res]\n"
-"\n"
-" if [regexp {=clients:} $res] {\n"
-" regsub {^.*=clients:} $res \"\" cres\n"
-" regsub {,aro=.*$} $cres \"\" cres\n"
-" regsub {,ans=.*$} $cres \"\" cres\n"
-" if {$cres == \"none\"} {\n"
-" set cres \"\"\n"
-" }\n"
-" update_clients_menu $cres\n"
-" set client_str $cres\n"
-" set_client_balloon $cres\n"
-" }\n"
-"\n"
-" if [regexp {^clients:} $res] {\n"
-" regsub {^clients:} $res \"\" tmp\n"
-" if {$tmp == \"none\"} {\n"
-" set tmp \"\"\n"
-" }\n"
-" update_clients_menu $tmp\n"
-" set client_str $tmp\n"
-" set_client_balloon $tmp\n"
-"\n"
-" if ![regexp {^clients} $opt] {\n"
-" # we could block here...\n"
-" if {$db} {puts stderr \"run_remote_cmd_via_sock: gets\"}\n"
-" gets $client_sock res\n"
-" if {$db} {puts stderr \"run_remote_cmd_via_sock: \\\"$res\\\"\"}\n"
-" set res [string trim $res]\n"
-" }\n"
-" }\n"
-"\n"
-" set docmd \"\"\n"
-"\n"
-" if {$res != \"\"} {\n"
-" append result \"$res\\n\"\n"
-" }\n"
-" }\n"
-" \n"
-" setup_client_sock 1\n"
-"\n"
-" set result [string trim $result]\n"
-"\n"
-" return $result\n"
-"}\n"
-"\n"
-"proc run_remote_cmd {opts} {\n"
-" global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay\n"
-" global x11vnc_auth_file x11vnc_connect_file\n"
-" global client_sock\n"
-"\n"
-" set debug [in_debug_mode]\n"
-"\n"
-" if {[lindex $opts 0] == \"-R\" && [lindex $opts 1] == \"noremote\"} {\n"
-" set str [join $opts]\n"
-" if ![double_check_noremote] {\n"
-" append_text \"skipping: x11vnc $str\"\n"
-" return \"\"\n"
-" } else {\n"
-" append_text \"running: x11vnc $str (please do \\\"Actions -> detach\\\" to clean things up)\\n\"\n"
-" append_text \"subsequent -R/-Q commands should fail...\"\n"
-" }\n"
-" }\n"
-"\n"
-" if {$client_sock != \"\"} {\n"
-" menus_disable\n"
-" stop_watch on\n"
-" set result [run_remote_cmd_via_sock $opts]\n"
-" stop_watch off\n"
-" menus_enable\n"
-" if {$result != \"fail\"} {\n"
-" return $result\n"
-" }\n"
-" }\n"
-"\n"
-" set cmd \"\"\n"
-"\n"
-" lappend cmd $x11vnc_prog;\n"
-"\n"
-" if {$x11vnc_connect_file != \"\"} {\n"
-" lappend cmd \"-connect\"\n"
-" lappend cmd $x11vnc_connect_file\n"
-" } else {\n"
-" if {$x11vnc_xdisplay != \"\"} {\n"
-" lappend cmd \"-display\"\n"
-" lappend cmd $x11vnc_xdisplay\n"
-" }\n"
-" if {$x11vnc_auth_file != \"\"} {\n"
-" lappend cmd \"-auth\"\n"
-" lappend cmd $x11vnc_auth_file\n"
-" }\n"
-" }\n"
-" lappend cmd \"-sync\"\n"
-" foreach word $opts {\n"
-" lappend cmd $word\n"
-" }\n"
-" lappend cmd \"2>\"\n"
-" lappend cmd \"/dev/null\"\n"
-"\n"
-" if {0 || $debug} {\n"
-" set str [join $cmd]\n"
-" puts \"running: $str\"\n"
-" foreach word $cmd {\n"
-" puts \" word: $word\"\n"
-" }\n"
-" }\n"
-"\n"
-" set output \"\"\n"
-" menus_disable\n"
-"\n"
-" stop_watch on\n"
-" catch {set output [eval exec $cmd]}\n"
-" stop_watch off\n"
-"\n"
-" menus_enable\n"
-" if {$debug} {\n"
-" if {[string length $output] > 100} {\n"
-" set str [string range $output 0 100]\n"
-" append_text \"output: $str ...\\n\"\n"
-" } else {\n"
-" append_text \"output: $output\\n\"\n"
-" }\n"
-" }\n"
-" return $output\n"
-"}\n"
-"\n"
-"proc try_connect_and_query_all {{n 2}} {\n"
-" for {set i 0} {$i < $n} {incr i} {\n"
-" if {$i > 0} {\n"
-" after 500\n"
-" append_text \"trying again ...\\n\"\n"
-" }\n"
-" if {[try_connect]} {\n"
-" query_all\n"
-" break\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc try_connect {} {\n"
-" global x11vnc_xdisplay connected_to_x11vnc reply_xdisplay\n"
-" global menu_var unset_str\n"
-"\n"
-" set db 0\n"
-"#dtime c1\n"
-"\n"
-" if {! $connected_to_x11vnc} {\n"
-" if {[info exists menu_var(display)]} {\n"
-" set d $menu_var(display)\n"
-" if {$d != \"\" && $d != $unset_str && $d != $x11vnc_xdisplay} {\n"
-" set x11vnc_xdisplay $menu_var(display)\n"
-" append_text \"Setting X display to: $x11vnc_xdisplay\\n\"\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" set_info \"Pinging $x11vnc_xdisplay ...\"\n"
-" set rargs [list \"-Q\" \"ping\"]\n"
-" set result [run_remote_cmd $rargs]\n"
-"#dtime c2a\n"
-"\n"
-" if {$db} {puts \"try_connect: \\\"$result\\\"\"}\n"
-"\n"
-" if {[regexp {^ans=ping:} $result]} {\n"
-" regsub {^ans=ping:} $result {} reply_xdisplay\n"
-" set msg \"Connected to $reply_xdisplay\"\n"
-" set_info $msg\n"
-" append_text \"$msg\\n\"\n"
-" set_connected yes\n"
-"\n"
-" setup_client_channel\n"
-"#dtime c2b\n"
-" setup_client_sock 1\n"
-" setup_client_tail\n"
-"\n"
-" fetch_displays\n"
-"#dtime c3a\n"
-" return 1\n"
-" } else {\n"
-" set str \"x11vnc server.\"\n"
-" if {$x11vnc_xdisplay != \"\"} {\n"
-" set str $x11vnc_xdisplay\n"
-" }\n"
-" set msg \"No reply from $str\"\n"
-" set_info $msg\n"
-" append_text \"$msg\\n\"\n"
-" set_connected no\n"
-" return 0\n"
-" }\n"
-"}\n"
-"\n"
-"proc set_view_variable {val} {\n"
-" global menu_var\n"
-" set menu_var(WindowView) $val\n"
-"}\n"
-"proc get_view_variable {} {\n"
-" global menu_var\n"
-" if {![info exists menu_var(WindowView)]} {\n"
-" set menu_var(WindowView) \"none\"\n"
-" }\n"
-" return $menu_var(WindowView)\n"
-"}\n"
-"\n"
-"proc dono {a b c} {\n"
-" exit 1;\n"
-"}\n"
-"\n"
-"proc do_port_prompt {} {\n"
-" global bfont ffont\n"
-" global port_reply port_set\n"
-"\n"
-" set guess 5900\n"
-" for {set i 0} {$i < 50} {incr i} {\n"
-" set fh \"\"\n"
-" set try [expr $guess + $i]\n"
-" catch {set fh [socket -server dono $try]}\n"
-" if {$fh != \"\"} {\n"
-" catch {close $fh}\n"
-" set guess $try\n"
-" break;\n"
-" }\n"
-" }\n"
-" set hn \"\"\n"
-" catch {set hn [exec uname -n]}\n"
-" if {$hn == \"\"} {\n"
-" set hn \"hostname\"\n"
-" }\n"
-"\n"
-" set text \" Set the x11vnc Listening Port:\n"
-"\n"
-" VNC Display :0 corresponds to TCP port 5900\n"
-" VNC Display :1 corresponds to TCP port 5901\n"
-" etc.\n"
-"\n"
-" In the Entry below, indicate a Port for x11vnc to listen on. \n"
-"\n"
-" Note that to connect to x11vnc, a VNC Viewer will need to\n"
-" know your selection, for example:\n"
-"\n"
-" vncviewer $hn:0\n"
-" vncviewer $hn:1\n"
-" etc.\n"
-"\n"
-" Your firewall may block incoming connections to TCP ports;\n"
-" if it does you may need to reconfigure it. \n"
-" \n"
-" You can also set some additional parameters:\n"
-"\n"
-" - Enable SSL encryption.\n"
-" (requires an SSL enabled vncviewer, such as SSVNC) \n"
-" - Listen only on localhost. (e.g. for an SSH tunnel)\n"
-" - Enable UltraVNC or TightVNC File transfer.\n"
-"\"\n"
-" set port_set $guess\n"
-" set port_reply \"\"\n"
-"\n"
-" toplevel .pp\n"
-" wm title .pp \"Select x11vnc port\"\n"
-"\n"
-" wm protocol . WM_DELETE_WINDOW \"destroy .; exit\"\n"
-" wm protocol .pp WM_DELETE_WINDOW \"destroy .pp; exit\"\n"
-"\n"
-" label .pp.m -text \"$text\" -relief ridge -justify left -font $ffont\n"
-"\n"
-" global tk_version\n"
-" set tkold 0\n"
-" if [info exists tk_version] {\n"
-" if [regexp {^8\\.[0-3]$} $tk_version] {\n"
-" set tkold 1\n"
-" }\n"
-" if [regexp {^[3-7]\\.} $tk_version] {\n"
-" set tkold 1\n"
-" }\n"
-" }\n"
-"\n"
-" if {$tkold} {\n"
-" frame .pp.f -bd 1 -relief ridge\n"
-" } else {\n"
-" frame .pp.f -bd 1 -relief ridge -pady 2\n"
-" }\n"
-" label .pp.f.l -text \"Port: \" -font $bfont\n"
-" entry .pp.f.e -width 8 -textvariable port_set -font $ffont\n"
-" global enable_ssl; set enable_ssl 0\n"
-" if [info exists env(X11VNC_SSL_ENABLED)] {\n"
-" set enable_ssl 1\n"
-" }\n"
-" checkbutton .pp.f.ssl -relief raised -pady 3 -padx 3 -text \"Enable SSL\" -variable enable_ssl -font $bfont\n"
-" global localhost; set localhost 0\n"
-" if [info exists env(X11VNC_LOCALHOST_ENABLED)] {\n"
-" set localhost 1\n"
-" }\n"
-" checkbutton .pp.f.loc -relief raised -pady 3 -padx 3 -text \"Listen on localhost\" -variable localhost -font $bfont\n"
-" pack .pp.f.l .pp.f.e -side left\n"
-" pack .pp.f.loc .pp.f.ssl -side right\n"
-"\n"
-" if {$tkold} {\n"
-" frame .pp.t -bd 1 -relief ridge\n"
-" } else {\n"
-" frame .pp.t -bd 1 -relief ridge -pady 2\n"
-" }\n"
-" global file_transfer; set file_transfer \"none\"\n"
-" if [info exists env(X11VNC_FILETRANSFER_ENABLED)] {\n"
-" set file_transfer $env(X11VNC_FILETRANSFER_ENABLED)\n"
-" }\n"
-" label .pp.t.l -text \"File Transfer: \" -font $bfont\n"
-" radiobutton .pp.t.none -text \"None\" -variable file_transfer -value \"none\" -font $bfont\n"
-" radiobutton .pp.t.ultra -text \"UltraVNC\" -variable file_transfer -value \"ultra\" -font $bfont\n"
-" radiobutton .pp.t.tight -text \"TightVNC\" -variable file_transfer -value \"tight\" -font $bfont\n"
-" pack .pp.t.l .pp.t.none .pp.t.ultra .pp.t.tight -side left\n"
-"\n"
-" frame .pp.o -bd 1 -relief ridge\n"
-" button .pp.o.ok -text \"OK\" -command \"set port_reply 1; destroy .pp\" -font $bfont\n"
-" button .pp.o.cancel -text \"Cancel\" -command \"set port_reply 0; destroy .pp\" -font $bfont\n"
-" pack .pp.o.ok .pp.o.cancel -side left -fill x -expand 1\n"
-" pack .pp.m -side top -fill x -expand 1 \n"
-" pack .pp.f .pp.t .pp.o -side top -fill x\n"
-"\n"
-" focus .pp.f.e\n"
-" .pp.f.e icursor end\n"
-"\n"
-" wm withdraw .pp\n"
-" update\n"
-" center_win .pp\n"
-"\n"
-" wm minsize .pp [winfo width .pp] [winfo height .pp]\n"
-"\n"
-" bind .pp.f.e <KeyPress-Return> \"set port_reply 1; destroy .pp\"\n"
-"\n"
-" vwait port_reply\n"
-"\n"
-" if {$port_reply} {\n"
-" regsub -all {^:} $port_set \"\" port_set\n"
-" regsub -all {[ \\t]} $port_set \"\" port_set\n"
-" if {[regexp {^[0-9][0-9]*$} $port_set]} {\n"
-" if {$port_set < 0} {\n"
-" set port_set [expr 0 - $port_set]\n"
-" } elseif {$port_set < 200} {\n"
-" set port_set [expr $port_set + 5900]\n"
-" } \n"
-" puts \"$port_set:ssl${enable_ssl}:localhost$localhost:ft_$file_transfer\"\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc change_view_state {} {\n"
-" global menu_var gui_current_state\n"
-"\n"
-" set new [get_view_variable]\n"
-"\n"
-" if {![info exists gui_current_state]} {\n"
-" set gui_current_state \"\"\n"
-" }\n"
-" set old $gui_current_state\n"
-" #puts \"$old -> $new\"\n"
-"\n"
-" if {$old == $new} {\n"
-" return\n"
-" }\n"
-"\n"
-" if {$old == \"full\" || $old == \"icon\" || $old == \"tray\"} {\n"
-" ;\n"
-" } else {\n"
-" set old \"none\"\n"
-" }\n"
-"\n"
-" if {$new == \"full\" || $new == \"icon\" || $new == \"tray\"} {\n"
-" if {$old == \"tray\"} {\n"
-" # sigh XReparentWindow would be too easy...\n"
-" # undo_tray_embed\n"
-" restart_everything $new\n"
-" destroy .\n"
-" exit\n"
-" }\n"
-" make_gui $new\n"
-" if {$new == \"tray\"} {\n"
-" wm withdraw .\n"
-" }\n"
-" } else {\n"
-" set_view_variable $old\n"
-" }\n"
-"}\n"
-"\n"
-"proc setup_client_tail {} {\n"
-" global client_tail\n"
-" if {$client_tail != \"\"} {\n"
-" fileevent $client_tail readable read_client_tail\n"
-" }\n"
-"}\n"
-"\n"
-"proc setup_client_sock {{enable 1}} {\n"
-" global client_sock\n"
-" if {$client_sock != \"\"} {\n"
-" if {$enable} {\n"
-" fileevent $client_sock readable read_client_sock\n"
-" } else {\n"
-" fileevent $client_sock readable \"\"\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"proc setup_tray_embed {} {\n"
-" update\n"
-" set w [winfo width .]\n"
-" set h [winfo height .]\n"
-" if {$w < 24} {\n"
-" set w 24\n"
-" }\n"
-" if {$h < 24} {\n"
-" set h 24\n"
-" }\n"
-" wm minsize . $w $h\n"
-" set wid [winfo id .] \n"
-" push_new_value \"remote-cmd\" \"remote-cmd\" \"trayembed:$wid\" 0\n"
-"}\n"
-"\n"
-"proc restart_everything {gui_mode} {\n"
-" global env gui_argv0 x11vnc_prog full_win\n"
-" global icon_mode_at_startup\n"
-" global tray_embed tray_running\n"
-" if {$gui_mode == \"full\"} {\n"
-" set env(X11VNC_ICON_MODE) 0\n"
-" } elseif {$gui_mode == \"icon\"} {\n"
-" set env(X11VNC_ICON_MODE) 1\n"
-" } elseif {$gui_mode == \"tray\"} {\n"
-" if {$tray_running} {\n"
-" set env(X11VNC_ICON_MODE) \"RUNNING\"\n"
-" } else {\n"
-" set env(X11VNC_ICON_MODE) \"TRAY\"\n"
-" }\n"
-" }\n"
-" puts stderr \"\"\n"
-" puts stderr \"tkx11vnc: restarting gui to leave tray mode.\"\n"
-" puts stderr \" new gui will be running in the background.\"\n"
-" puts stderr \" use kill(1) rather than Ctrl-C to kill it.\"\n"
-" puts stderr \"\"\n"
-" if {[info exists env(X11VNC_RESTART_DEPTH)]} {\n"
-" set n $env(X11VNC_RESTART_DEPTH)\n"
-" incr n\n"
-" set env(X11VNC_RESTART_DEPTH) $n\n"
-" } else {\n"
-" set env(X11VNC_RESTART_DEPTH) 0\n"
-" }\n"
-" set env(X11VNC_ICON_SETPASS) \"\"\n"
-"\n"
-" if {![info exists env(X11VNC_WISHCMD)]} {\n"
-" puts stderr \"failure in restart_everything.\"\n"
-" exit 1;\n"
-" }\n"
-"\n"
-" set code [exec $x11vnc_prog -printgui]\n"
-" if {[string length $code] < 20000} {\n"
-" puts stderr \"failure in restart_everything.\"\n"
-" exit 1;\n"
-" }\n"
-" set tmp \"/tmp/x11vnc[pid]\"\n"
-" append tmp [clock clicks]\n"
-" set tmp2 \"\"\n"
-" catch {set tmp2 [exec mktemp $tmp.XXXXXX 2>/dev/null]}\n"
-" if {$tmp2 != \"\" && [file exists $tmp2]} {\n"
-" set tmp $tmp2\n"
-" } else {\n"
-" file delete -force $tmp\n"
-" if {[file exists $tmp]} {\n"
-" puts stderr \"failure in restart_everything.\"\n"
-" exit 1;\n"
-" }\n"
-" }\n"
-" set fh [open $tmp \"a\"]\n"
-" if {![file owned $tmp]} {\n"
-" puts stderr \"failure in restart_everything.\"\n"
-" exit 1;\n"
-" }\n"
-" file attributes $tmp -permissions \"0400\"\n"
-" puts $fh $code\n"
-" close $fh\n"
-"\n"
-" #puts stderr [exec ls -l $tmp]\n"
-"\n"
-" wm withdraw .\n"
-" catch {wm withdraw $full_win}\n"
-" update\n"
-"\n"
-" exec $env(X11VNC_WISHCMD) $tmp &\n"
-" after 2000\n"
-" file delete -force $tmp\n"
-" \n"
-" destroy .\n"
-" exit\n"
-"}\n"
-"\n"
-"proc undo_tray_embed {} {\n"
-" set wid [winfo id .] \n"
-" push_new_value \"remote-cmd\" \"remote-cmd\" \"trayunembed:$wid\" 0\n"
-"}\n"
-"\n"
-"############################################################################\n"
-"# main:\n"
-"\n"
-"if [info exists env(X11VNC_GUI_TIME)] {\n"
-" dtime M\n"
-"}\n"
-"\n"
-"wm withdraw .\n"
-"\n"
-"global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;\n"
-"global x11vnc_xdisplay0\n"
-"global x11vnc_client_file x11vnc_gui_geom x11vnc_started vnc_url\n"
-"global x11vnc_gui_params\n"
-"global x11vnc_auth_file x11vnc_connect_file beginner_mode simple_gui_created\n"
-"global helpall helptext helpremote helplabel hostname osname\n"
-"global all_settings reply_xdisplay always_update\n"
-"global max_text_height max_text_width\n"
-"global text_height\n"
-"global menu_var unset_str menus_disabled\n"
-"global bfont ffont sfont snfont old_labels have_labelframes\n"
-"global connected_to_x11vnc\n"
-"global cache_all_query_vars\n"
-"global last_query_all_time query_all_freq client_tail client_sock client_info_read\n"
-"global icon_mode icon_mode_at_startup x11vnc_icon_mode\n"
-"global tray_embed tray_running icon_setpasswd icon_embed_id\n"
-"global icon_noadvanced icon_minimal\n"
-"global make_gui_count text_area_str\n"
-"global gui_argv0 gui_start_mode\n"
-"global screen_height screen_width\n"
-"\n"
-"set unset_str \"(unset)\"\n"
-"set vnc_url $unset_str\n"
-"set connected_to_x11vnc 0\n"
-"set menus_disabled 0\n"
-"set max_text_height 40\n"
-"set max_text_width 90\n"
-"set text_height 14\n"
-"set bfont \"-adobe-helvetica-bold-r-*-*-*-120-*-*-*-*-*-*\"\n"
-"set sfont \"-adobe-helvetica-bold-r-*-*-*-100-*-*-*-*-*-*\"\n"
-"set snfont \"-adobe-helvetica-medium-r-*-*-*-100-*-*-*-*-*-*\"\n"
-"set ffont \"fixed\"\n"
-"\n"
-"set got_helv 0\n"
-"catch {\n"
-" foreach fam [font families] {\n"
-" if {$fam == \"helvetica\"} {\n"
-" set got_helv 1\n"
-" }\n"
-" if {$fam == \"Helvetica\"} {\n"
-" set got_helv 1\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"if {$got_helv} {\n"
-" set bfont \"Helvetica -12 bold\"\n"
-" set sfont \"Helvetica -10 bold\"\n"
-" set snfont \"Helvetica -10\"\n"
-"}\n"
-"\n"
-"set ls \"\"\n"
-"catch {set ls [font metrics $bfont -linespace]}\n"
-"if {$ls != \"\" && $ls > 14} {\n"
-" # some recent setups have BIG rendering for the above fonts.\n"
-" # on recent (8/08) debian these are really ragged:\n"
-" set bfont \"-adobe-helvetica-bold-r-*-*-*-90-*-*-*-*-*-*\"\n"
-" set sfont \"-adobe-helvetica-bold-r-*-*-*-75-*-*-*-*-*-*\"\n"
-" set snfont \"-adobe-helvetica-medium-r-*-*-*-75-*-*-*-*-*-*\"\n"
-"\n"
-" set ls \"\"\n"
-" catch {set ls [font metrics $bfont -linespace]}\n"
-" if {$ls != \"\" && $ls < 14} {\n"
-" # these are bigger but look better... but for how long?\n"
-" set bfont \"-adobe-helvetica-bold-r-*-*-*-100-*-*-*-*-*-*\"\n"
-" set sfont \"-adobe-helvetica-bold-r-*-*-*-80-*-*-*-*-*-*\"\n"
-" set snfont \"-adobe-helvetica-medium-r-*-*-*-80-*-*-*-*-*-*\"\n"
-"\n"
-" # maybe consider... {-font font Font {Helvetica -12 bold} {Helvetica -12 bold}}\n"
-" # or stick with system font like ssvnc.\n"
-" }\n"
-"}\n"
-"\n"
-"# need to check if \"fixed\" font under XFT on tk8.5 is actually fixed width!!\n"
-"set ls \"\"\n"
-"catch {set ls [font metrics $ffont -linespace]}\n"
-"set fs \"\"\n"
-"catch {set fs [font metrics $ffont -fixed]}\n"
-"set redo 0\n"
-"if {$fs != \"\" && $fs != \"1\"} {\n"
-" set redo 1\n"
-"}\n"
-"if {$ls != \"\" && $ls > 14} {\n"
-" set redo 1\n"
-"}\n"
-"if {$redo} {\n"
-" foreach fn [font names] {\n"
-" if {$fn == \"TkFixedFont\"} {\n"
-" set ffont $fn\n"
-" break\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"set help_indent 24;\n"
-"set reply_xdisplay \"\"\n"
-"set all_settings \"None so far.\"\n"
-"set always_update 1\n"
-"set cache_all_query_vars \"\"\n"
-"set query_all_freq 120\n"
-"set last_query_all_time [clock seconds]\n"
-"set client_tail \"\"\n"
-"set client_sock \"\"\n"
-"set client_info_read 0\n"
-"set make_gui_count 0\n"
-"set text_area_str \"\"\n"
-"set gui_argv0 $argv0\n"
-"set gui_start_mode \"\"\n"
-"\n"
-"if {$tk_version < 8.0} {\n"
-" puts stderr \"\"\n"
-" puts stderr \"*** tkx11vnc: tk version is old $tk_version, please use 8.0 or higher.\"\n"
-" puts stderr \"*** will try to continue with reduced functionality...\"\n"
-" puts stderr \"\"\n"
-"}\n"
-"if {[regexp {^[34]} $tk_version] || $tk_version == \"8.0\"} {\n"
-" set old_labels 1\n"
-"} else {\n"
-" set old_labels 0\n"
-"}\n"
-"set have_labelframes 1\n"
-"if {$tk_version < 8.4} {\n"
-" set have_labelframes 0\n"
-"}\n"
-"\n"
-"set screen_height [winfo screenheight .]\n"
-"set screen_width [winfo screenwidth .]\n"
-"if {$screen_height < 700} {\n"
-" # short screen, netbook?\n"
-" set max_text_height 30\n"
-" if {$screen_height < 500} {\n"
-" # short screen, PDA?\n"
-" set max_text_height 22\n"
-" set text_height 13\n"
-" if {$screen_height <= 360} {\n"
-" # very short.\n"
-" set max_text_height 16\n"
-" set max_text_width 60\n"
-" set text_height 11\n"
-" }\n"
-" }\n"
-"}\n"
-"if {[info exists env(X11VNC_GUI_TEXT_HEIGHT)]} {\n"
-" set max_text_height $env(X11VNC_GUI_TEXT_HEIGHT)\n"
-"}\n"
-"if {[info exists env(X11VNC_GUI_TEXT_WIDTH)]} {\n"
-" set max_text_width $env(X11VNC_GUI_TEXT_WIDTH)\n"
-"}\n"
-"\n"
-"if {\"$argv\" == \"-spit\"} {\n"
-" set fh [open $argv0 r]\n"
-" puts \"#ifndef _TKX11VNC_H\"\n"
-" puts \"#define _TKX11VNC_H\"\n"
-" puts \"#ifdef NOGUI\"\n"
-" puts \"char gui_code\\[\\] = \\\"\\\";\"\n"
-" puts \"#else\"\n"
-" puts \"/*\"\n"
-" puts \" * tkx11vnc.h: generated by 'tkx11vnc -spit'\"\n"
-" puts \" * Abandon all hope, ye who enter here...\"\n"
-" puts \" * ...edit tkx11vnc instead.\"\n"
-" puts \" */\"\n"
-" puts \" char gui_code\\[\\] =\"\n"
-" while {[gets $fh line] > -1} {\n"
-" regsub -all {\\\\} $line {\\\\\\\\} line\n"
-" regsub -all {\"} $line {\\\\\"} line\n"
-" puts \"\\\"$line\\\\n\\\"\"\n"
-" }\n"
-" puts \"#endif\"\n"
-" puts \"/* ifdef NOGUI */\"\n"
-" puts \"#endif\"\n"
-" puts \"/* ifndef _TKX11VNC_H */\"\n"
-" close $fh\n"
-" puts \";\"\n"
-" exit 0\n"
-"}\n"
-"\n"
-"set_view_variable \"full\"\n"
-"\n"
-"#puts [exec env | grep X11VNC]\n"
-"\n"
-"# Read environment for clues:\n"
-"\n"
-"set x11vnc_client_file \"\";\n"
-"if {[info exists env(X11VNC_CLIENT_FILE)]} {\n"
-" set x11vnc_client_file $env(X11VNC_CLIENT_FILE);\n"
-" set file $x11vnc_client_file\n"
-"\n"
-" set client_tail \"\"\n"
-" if {[file exists $file] && [file isfile $file]} {\n"
-" if {[file readable $file] && [file owned $file]} {\n"
-" set client_tail [open \"|tail -f $x11vnc_client_file\" \"r\"]\n"
-" }\n"
-" }\n"
-" if {$client_tail != \"\"} {\n"
-" gets $client_tail tmp\n"
-" if [eof $client_tail] {\n"
-"#puts \"eof $client_tail\"\n"
-" clean_client_tail\n"
-" set client_tail \"\"\n"
-" }\n"
-" }\n"
-" catch {file delete -force $x11vnc_client_file}\n"
-"}\n"
-"\n"
-"if {[info exists env(X11VNC_PROG)]} {\n"
-" set x11vnc_prog $env(X11VNC_PROG);\n"
-"} else {\n"
-" set x11vnc_prog \"x11vnc\";\n"
-"}\n"
-"\n"
-"if {[info exists env(X11VNC_CMDLINE)]} {\n"
-" set x11vnc_cmdline $env(X11VNC_CMDLINE);\n"
-"} else {\n"
-" set x11vnc_cmdline \"\";\n"
-"}\n"
-"\n"
-"if {[info exists env(X11VNC_CONNECT)]} {\n"
-" set x11vnc_connect 1\n"
-"} else {\n"
-" set x11vnc_connect 0;\n"
-"}\n"
-"\n"
-"if {[info exists env(X11VNC_GUI_GEOM)]} {\n"
-" set x11vnc_gui_geom $env(X11VNC_GUI_GEOM);\n"
-"} else {\n"
-" set x11vnc_gui_geom \"\"\n"
-"}\n"
-"if {[info exists env(X11VNC_GUI_PARAMS)]} {\n"
-" set x11vnc_gui_params $env(X11VNC_GUI_PARAMS);\n"
-"} else {\n"
-" set x11vnc_gui_params \"\"\n"
-"}\n"
-"\n"
-"if {[info exists env(X11VNC_FONT_BOLD)]} {\n"
-" set bfont $env(X11VNC_FONT_BOLD)\n"
-"}\n"
-"if {[info exists env(X11VNC_FONT_BOLD_SMALL)]} {\n"
-" set sfont $env(X11VNC_FONT_BOLD_SMALL)\n"
-"}\n"
-"if {[info exists env(X11VNC_FONT_REG_SMALL)]} {\n"
-" set snfont $env(X11VNC_FONT_REG_SMALL)\n"
-"}\n"
-"if {[info exists env(X11VNC_FONT_FIXED)]} {\n"
-" set ffont $env(X11VNC_FONT_FIXED)\n"
-"}\n"
-"\n"
-"if {[info exists env(X11VNC_CONNECT_FILE)]} {\n"
-" set x11vnc_connect_file $env(X11VNC_CONNECT_FILE);\n"
-"} else {\n"
-" set x11vnc_connect_file \"\";\n"
-"}\n"
-"\n"
-"set x11vnc_started 0\n"
-"if {[info exists env(X11VNC_STARTED)]} {\n"
-" set x11vnc_started 1\n"
-"}\n"
-"\n"
-"set x11vnc_xdisplay \"\"\n"
-"if {[info exists env(X11VNC_XDISPLAY)]} {\n"
-" set x11vnc_xdisplay $env(X11VNC_XDISPLAY);\n"
-" set x11vnc_connect 1\n"
-"\n"
-"} elseif {$argv != \"\" && [regexp {:[0-9]} $argv]} {\n"
-" set env(X11VNC_XDISPLAY) \"$argv\"\n"
-" set x11vnc_xdisplay \"$argv\"\n"
-" set x11vnc_connect 1\n"
-"\n"
-"} elseif {[info exists env(DISPLAY)]} {\n"
-" set x11vnc_xdisplay $env(DISPLAY);\n"
-"} else {\n"
-" set x11vnc_xdisplay \":0\";\n"
-"}\n"
-"set x11vnc_xdisplay0 $x11vnc_xdisplay\n"
-"\n"
-"if {[info exists env(X11VNC_AUTH_FILE)]} {\n"
-" set x11vnc_auth_file $env(X11VNC_AUTH_FILE)\n"
-"} else {\n"
-" set x11vnc_auth_file \"\"\n"
-"}\n"
-"\n"
-"set simple_gui_created 0\n"
-"if {[info exists env(X11VNC_SIMPLE_GUI)]} {\n"
-" set beginner_mode 1\n"
-"} else {\n"
-" set beginner_mode 0\n"
-"}\n"
-"\n"
-"set icon_mode 0\n"
-"set x11vnc_icon_mode 0\n"
-"set tray_embed 0\n"
-"set tray_running 0\n"
-"\n"
-"if {![info exists env(X11VNC_ICON_MODE_AT_STARTUP)]} {\n"
-" if {[info exists env(X11VNC_ICON_MODE)]} {\n"
-" if {$env(X11VNC_ICON_MODE) != 0} {\n"
-" set env(X11VNC_ICON_MODE_AT_STARTUP) 1\n"
-" } else {\n"
-" set env(X11VNC_ICON_MODE_AT_STARTUP) 0\n"
-" }\n"
-" } else {\n"
-" set env(X11VNC_ICON_MODE_AT_STARTUP) 0\n"
-" }\n"
-"}\n"
-"set icon_mode_at_startup $env(X11VNC_ICON_MODE_AT_STARTUP)\n"
-"\n"
-"if {![info exists env(X11VNC_ICON_MODE)]} {\n"
-" set icon_mode 0\n"
-"} elseif {$env(X11VNC_ICON_MODE) == \"\" || $env(X11VNC_ICON_MODE) == \"0\"} {\n"
-" set icon_mode 0\n"
-"} else {\n"
-" set icon_mode 1\n"
-" set_view_variable \"icon\"\n"
-" if [regexp -nocase {TRAY} $env(X11VNC_ICON_MODE)] {\n"
-" set tray_embed 1\n"
-" }\n"
-" if [regexp -nocase {RUNNING} $env(X11VNC_ICON_MODE)] {\n"
-" set tray_running 1\n"
-" }\n"
-"}\n"
-"\n"
-"set icon_setpasswd 0\n"
-"if {[info exists env(X11VNC_ICON_SETPASS)]} {\n"
-" if {$env(X11VNC_ICON_SETPASS) != \"\"} {\n"
-" set icon_setpasswd 1\n"
-" }\n"
-"}\n"
-"\n"
-"set icon_noadvanced 0\n"
-"if {[info exists env(X11VNC_ICON_NOADVANCED)]} {\n"
-" set icon_noadvanced 1\n"
-"}\n"
-"\n"
-"set icon_minimal 0\n"
-"if {[info exists env(X11VNC_ICON_MINIMAL)]} {\n"
-" set icon_minimal 1\n"
-"}\n"
-"\n"
-"if {[info exists env(X11VNC_ICON_EMBED_ID)]} {\n"
-" set icon_embed_id $env(X11VNC_ICON_EMBED_ID)\n"
-"} else {\n"
-" set icon_embed_id \"\"\n"
-"}\n"
-"\n"
-"\n"
-"set hostname [exec uname -n]\n"
-"set osname [exec uname]\n"
-"\n"
-"if {[regexp -nocase {IRIX} $osname]} {\n"
-" # IRIX \"fixed\" font is huge and doublespaced... \n"
-" set ffont $snfont\n"
-"}\n"
-"if {[regexp -nocase {Darwin} $osname]} {\n"
-" set ffont {Monaco 10}\n"
-" set bfont {system}\n"
-"}\n"
-"\n"
-"if {\"$argv\" == \"-portprompt\"} {\n"
-" do_port_prompt\n"
-" exit 0\n"
-"}\n"
-"\n"
-"#puts [exec env]\n"
-"#puts \"x11vnc_xdisplay: $x11vnc_xdisplay\"\n"
-"\n"
-"set env(X11VNC_STD_HELP) 1\n"
-"\n"
-"# scrape the help output for the text and remote control vars:\n"
-"parse_help;\n"
-"parse_remote_help;\n"
-"parse_query_help;\n"
-"\n"
-"# tweaks to duplicate help text:\n"
-"tweak_remote_help lock deny\n"
-"tweak_remote_help unlock deny\n"
-"\n"
-"tweak_both quiet q\n"
-"tweak_help logfile o\n"
-"tweak_both xwarppointer xwarp\n"
-"tweak_both screen_blank sb\n"
-"\n"
-"set_template\n"
-"\n"
-"set_name \"tkx11vnc\"\n"
-"\n"
-"key_bindings;\n"
-"\n"
-"get_default_vars\n"
-"\n"
-"dtime D\n"
-"\n"
-"proc check_setpasswd {} {\n"
-" global env icon_setpasswd\n"
-" global do_props_msg\n"
-" set do_props_msg \"\"\n"
-" if {$icon_setpasswd} {\n"
-" set m \"\\n\"\n"
-" set m \"${m} Note the x11vnc icon in the system tray.\\n\" \n"
-" set m \"${m} This panel is its 'Properties' dialog.\\n\" \n"
-" set m \"${m}\\n\" \n"
-" set m \"${m} To specify a Session Password and to\\n\" \n"
-" set m \"${m} allow VNC viewers to connect, follow\\n\" \n"
-" set m \"${m} these steps:\\n\" \n"
-" set m \"${m}\\n\" \n"
-" set m \"${m} Enter a passwd in the Password field\\n\" \n"
-" set m \"${m} (it can be left blank.) You can also\\n\" \n"
-" set m \"${m} supply a ViewOnly passwd if desired.\\n\" \n"
-" set m \"${m}\\n\" \n"
-" set m \"${m} Set 'Accept Connections' and then Press \\n\" \n"
-" set m \"${m} 'Apply' to allow incoming connections.\\n\" \n"
-" set m \"${m}\\n\" \n"
-" set m \"${m} No Viewer can connect until you do this.\\n\" \n"
-" set m \"${m}\\n\" \n"
-" set m \"${m} The passwords are only for this x11vnc\\n\" \n"
-" set m \"${m} session and are not saved. Run x11vnc\\n\" \n"
-" set m \"${m} manually for more control (e.g. -rfbauth \\n\" \n"
-" set m \"${m} for a saved password.)\\n\" \n"
-" set m \"${m}\\n\" \n"
-" set m \"${m} See 'Help' for details on each option.\\n\" \n"
-"\n"
-" global x11vnc_cmdline\n"
-"\n"
-" set dossl 0\n"
-" if {[info exists x11vnc_cmdline]} {\n"
-" if [regexp -- {-ssl} $x11vnc_cmdline] {\n"
-" set dossl 1\n"
-" }\n"
-" }\n"
-" if {$dossl || [info exists env(X11VNC_GOT_SSL)]} {\n"
-" set m \"${m}\\n\" \n"
-" set m \"${m} SSL encryption mode active. You can\\n\" \n"
-" set m \"${m} find your Public Cert in the Logfile\\n\" \n"
-" set m \"${m} and also the ~/.vnc/certs directory.\\n\" \n"
-" }\n"
-"\n"
-" if {[info exists env(X11VNC_SETPASS_FAIL)]} {\n"
-" set pp 5900\n"
-" if {[info exists env(X11VNC_GOT_RFBPORT_VAL)]} {\n"
-" if {$env(X11VNC_GOT_RFBPORT_VAL) > 0} {\n"
-" set pp $env(X11VNC_GOT_RFBPORT_VAL)\n"
-" }\n"
-" }\n"
-" \n"
-" set m \" The x11vnc program failed to start! \\n\"\n"
-" set m \"${m}\\n\" \n"
-" set m \"${m} Maybe there is another VNC server\\n\"\n"
-" set m \"${m} already listening on port $pp?\\n\"\n"
-" set m \"${m}\\n\" \n"
-" set m \"${m} You will need to start over after\\n\"\n"
-" set m \"${m} you make sure x11vnc can start.\\n\"\n"
-" }\n"
-" \n"
-" set do_props_msg $m\n"
-" do_props\n"
-" }\n"
-"}\n"
-"\n"
-"if {0} {\n"
-" if {[info exists env(X11VNC_ICON_SETPASS)]} {\n"
-" if {$env(X11VNC_ICON_SETPASS) == \"2\"} {\n"
-" global icon_mode_at_startup icon_mode\n"
-" set icon_mode_at_startup 1\n"
-" set icon_mode 2\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"if {$icon_mode} {\n"
-" if {$icon_mode == 2} {\n"
-" make_gui \"full\"\n"
-" } elseif {$tray_embed} {\n"
-" make_gui \"tray\"\n"
-" } else {\n"
-" make_gui \"icon\"\n"
-" }\n"
-" dtime G\n"
-" old_balloon\n"
-" check_setpasswd\n"
-" push_new_value \"remote-cmd\" \"remote-cmd\" \"Q:clients\" 1\n"
-"} else {\n"
-" make_gui \"full\"\n"
-" dtime G\n"
-" check_setpasswd\n"
-"}\n"
-"\n"
-"\n"
-"# main loop.\n"
-#endif
-/* ifdef NOGUI */
-#endif
-/* ifndef _TKX11VNC_H */
-;
diff --git a/x11vnc/uinput.c b/x11vnc/uinput.c
deleted file mode 100644
index 92bd1d8..0000000
--- a/x11vnc/uinput.c
+++ /dev/null
@@ -1,1876 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- uinput.c -- */
-
-#include "x11vnc.h"
-#include "cleanup.h"
-#include "scan.h"
-#include "xinerama.h"
-#include "screen.h"
-#include "pointer.h"
-#include "keyboard.h"
-#include "allowed_input_t.h"
-
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
-#if LIBVNCSERVER_HAVE_LINUX_INPUT_H
-#if LIBVNCSERVER_HAVE_LINUX_UINPUT_H
-#define UINPUT_OK
-#endif
-#endif
-#endif
-
-#ifdef UINPUT_OK
-#include <sys/ioctl.h>
-#include <linux/input.h>
-#include <linux/uinput.h>
-
-#if !defined(EV_SYN) || !defined(SYN_REPORT)
-#undef UINPUT_OK
-#endif
-
-#endif
-
-
-int check_uinput(void);
-int initialize_uinput(void);
-void shutdown_uinput(void);
-int set_uinput_accel(char *str);
-int set_uinput_thresh(char *str);
-void set_uinput_reset(int ms);
-void set_uinput_always(int);
-void set_uinput_touchscreen(int);
-void set_uinput_abs(int);
-char *get_uinput_accel();
-char *get_uinput_thresh();
-int get_uinput_reset();
-int get_uinput_always();
-int get_uinput_touchscreen();
-int get_uinput_abs();
-void parse_uinput_str(char *str);
-void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client);
-void uinput_key_command(int down, int keysym, rfbClientPtr client);
-
-static void init_key_tracker(void);
-static int mod_is_down(void);
-static int key_is_down(void);
-static void set_uinput_accel_xy(double fx, double fy);
-static void ptr_move(int dx, int dy);
-static void ptr_rel(int dx, int dy);
-static void button_click(int down, int btn);
-static int lookup_code(int keysym);
-
-static int fd = -1;
-static int direct_rel_fd = -1;
-static int direct_abs_fd = -1;
-static int direct_btn_fd = -1;
-static int direct_key_fd = -1;
-static int bmask = 0;
-static int db = 0;
-
-static char *injectable = NULL;
-static char *uinput_dev = NULL;
-static char *tslib_cal = NULL;
-static double a[7];
-static int uinput_touchscreen = 0;
-static int uinput_abs = 0;
-static int btn_touch = 0;
-static int dragskip = 0;
-static int touch_always = 0;
-static int touch_pressure = 1;
-static int abs_x = 0, abs_y = 0;
-
-static char *devs[] = {
- "/dev/misc/uinput",
- "/dev/input/uinput",
- "/dev/uinput",
- NULL
-};
-
-#ifndef O_NDELAY
-#ifdef O_NONBLOCK
-#define O_NDELAY O_NONBLOCK
-#else
-#define O_NDELAY 0
-#endif
-#endif
-
-/*
- * User may need to do:
- modprode uinput
- mknod /dev/input/uinput c 10 223
- */
-
-int check_uinput(void) {
-#ifndef UINPUT_OK
- return 0;
-#else
- int i;
- if (UT.release) {
- int maj, min;
- /* guard against linux 2.4 */
- if (sscanf(UT.release, "%d.%d.", &maj, &min) == 2) {
- if (maj < 2) {
- return 0;
- } else if (maj == 2) {
- /* hmmm IPAQ 2.4.19-rmk6-pxa1-hh37 works... */
-#if 0
- if (min < 6) {
- return 0;
- }
-#endif
- }
- }
- }
- fd = -1;
- i = 0;
- while (devs[i] != NULL) {
- if ( (fd = open(devs[i++], O_WRONLY | O_NDELAY)) >= 0) {
- break;
- }
- }
- if (fd < 0) {
- return 0;
- }
- close(fd);
- fd = -1;
- return 1;
-#endif
-}
-
-static int key_pressed[256];
-static int key_ismod[256];
-
-static void init_key_tracker(void) {
- int i;
- for (i = 0; i < 256; i++) {
- key_pressed[i] = 0;
- key_ismod[i] = 0;
- }
- i = lookup_code(XK_Shift_L); if (0<=i && i<256) key_ismod[i] = 1;
- i = lookup_code(XK_Shift_R); if (0<=i && i<256) key_ismod[i] = 1;
- i = lookup_code(XK_Control_L); if (0<=i && i<256) key_ismod[i] = 1;
- i = lookup_code(XK_Control_R); if (0<=i && i<256) key_ismod[i] = 1;
- i = lookup_code(XK_Alt_L); if (0<=i && i<256) key_ismod[i] = 1;
- i = lookup_code(XK_Alt_R); if (0<=i && i<256) key_ismod[i] = 1;
- i = lookup_code(XK_Meta_L); if (0<=i && i<256) key_ismod[i] = 1;
- i = lookup_code(XK_Meta_R); if (0<=i && i<256) key_ismod[i] = 1;
-}
-
-static int mod_is_down(void) {
- int i;
- if (0) {key_is_down();}
- for (i = 0; i < 256; i++) {
- if (key_pressed[i] && key_ismod[i]) {
- return 1;
- }
- }
- return 0;
-}
-
-static int key_is_down(void) {
- int i;
- for (i = 0; i < 256; i++) {
- if (key_pressed[i]) {
- return 1;
- }
- }
- return 0;
-}
-
-void shutdown_uinput(void) {
-#ifdef UINPUT_OK
- if (fd >= 0) {
- if (db) {
- rfbLog("shutdown_uinput called on fd=%d\n", fd);
- }
- ioctl(fd, UI_DEV_DESTROY);
- close(fd);
- fd = -1;
- }
-
- /* close direct injection files too: */
- if (direct_rel_fd >= 0) close(direct_rel_fd);
- if (direct_abs_fd >= 0) close(direct_abs_fd);
- if (direct_btn_fd >= 0) close(direct_btn_fd);
- if (direct_key_fd >= 0) close(direct_key_fd);
- direct_rel_fd = -1;
- direct_abs_fd = -1;
- direct_btn_fd = -1;
- direct_key_fd = -1;
-#endif
-}
-
-/*
-grep BUS_ /usr/include/linux/input.h | awk '{print $2}' | perl -e 'while (<>) {chomp; print "#ifdef $_\n\t\tif(!strcmp(s, \"$_\"))\tudev.id.bustype = $_\n#endif\n"}'
- */
-static int get_bustype(char *s) {
-#ifdef UINPUT_OK
-
- if (!s) return 0;
-
-#ifdef BUS_PCI
- if(!strcmp(s, "BUS_PCI")) return BUS_PCI;
-#endif
-#ifdef BUS_ISAPNP
- if(!strcmp(s, "BUS_ISAPNP")) return BUS_ISAPNP;
-#endif
-#ifdef BUS_USB
- if(!strcmp(s, "BUS_USB")) return BUS_USB;
-#endif
-#ifdef BUS_HIL
- if(!strcmp(s, "BUS_HIL")) return BUS_HIL;
-#endif
-#ifdef BUS_BLUETOOTH
- if(!strcmp(s, "BUS_BLUETOOTH")) return BUS_BLUETOOTH;
-#endif
-#ifdef BUS_VIRTUAL
- if(!strcmp(s, "BUS_VIRTUAL")) return BUS_VIRTUAL;
-#endif
-#ifdef BUS_ISA
- if(!strcmp(s, "BUS_ISA")) return BUS_ISA;
-#endif
-#ifdef BUS_I8042
- if(!strcmp(s, "BUS_I8042")) return BUS_I8042;
-#endif
-#ifdef BUS_XTKBD
- if(!strcmp(s, "BUS_XTKBD")) return BUS_XTKBD;
-#endif
-#ifdef BUS_RS232
- if(!strcmp(s, "BUS_RS232")) return BUS_RS232;
-#endif
-#ifdef BUS_GAMEPORT
- if(!strcmp(s, "BUS_GAMEPORT")) return BUS_GAMEPORT;
-#endif
-#ifdef BUS_PARPORT
- if(!strcmp(s, "BUS_PARPORT")) return BUS_PARPORT;
-#endif
-#ifdef BUS_AMIGA
- if(!strcmp(s, "BUS_AMIGA")) return BUS_AMIGA;
-#endif
-#ifdef BUS_ADB
- if(!strcmp(s, "BUS_ADB")) return BUS_ADB;
-#endif
-#ifdef BUS_I2C
- if(!strcmp(s, "BUS_I2C")) return BUS_I2C;
-#endif
-#ifdef BUS_HOST
- if(!strcmp(s, "BUS_HOST")) return BUS_HOST;
-#endif
-#ifdef BUS_GSC
- if(!strcmp(s, "BUS_GSC")) return BUS_GSC;
-#endif
-#ifdef BUS_ATARI
- if(!strcmp(s, "BUS_ATARI")) return BUS_ATARI;
-#endif
- if (atoi(s) > 0) {
- return atoi(s);
- }
-
-#endif
- return 0;
-}
-
-static void load_tslib_cal(void) {
- FILE *f;
- char line[1024], *p;
- int i;
-
- /* /etc/pointercal -528 33408 -3417516 -44200 408 40292028 56541 */
-
- /* this is the identity transformation: */
- a[0] = 1.0;
- a[1] = 0.0;
- a[2] = 0.0;
- a[3] = 0.0;
- a[4] = 1.0;
- a[5] = 0.0;
- a[6] = 1.0;
-
- if (tslib_cal == NULL) {
- return;
- }
-
- rfbLog("load_tslib_cal: reading %s\n", tslib_cal);
- f = fopen(tslib_cal, "r");
- if (f == NULL) {
- rfbLogPerror("load_tslib_cal: fopen");
- clean_up_exit(1);
- }
-
- if (fgets(line, sizeof(line), f) == NULL) {
- rfbLogPerror("load_tslib_cal: fgets");
- clean_up_exit(1);
- }
- fclose(f);
-
- p = strtok(line, " \t");
- i = 0;
- while (p) {
- a[i] = (double) atoi(p);
- rfbLog("load_tslib_cal: a[%d] %.3f\n", i, a[i]);
- p = strtok(NULL, " \t");
- i++;
- if (i >= 7) {
- break;
- }
- }
- if (i != 7) {
- rfbLog("load_tslib_cal: invalid tslib file format: i=%d %s\n",
- i, tslib_cal);
- clean_up_exit(1);
- }
-}
-
-
-int initialize_uinput(void) {
-#ifndef UINPUT_OK
- return 0;
-#else
- int i;
- char *s;
- struct uinput_user_dev udev;
-
- if (fd >= 0) {
- shutdown_uinput();
- }
- fd = -1;
-
- if (getenv("X11VNC_UINPUT_DEBUG")) {
- db = atoi(getenv("X11VNC_UINPUT_DEBUG"));
- rfbLog("set uinput debug to: %d\n", db);
- }
-
- if (tslib_cal) {
- load_tslib_cal();
- }
-
- init_key_tracker();
-
- if (uinput_dev) {
- if (!strcmp(uinput_dev, "nouinput")) {
- rfbLog("initialize_uinput: not creating uinput device.\n");
- return 1;
- } else {
- fd = open(uinput_dev, O_WRONLY | O_NDELAY);
- rfbLog("initialize_uinput: using: %s %d\n", uinput_dev, fd);
- }
- } else {
- i = 0;
- while (devs[i] != NULL) {
- if ( (fd = open(devs[i], O_WRONLY | O_NDELAY)) >= 0) {
- rfbLog("initialize_uinput: using: %s %d\n",
- devs[i], fd);
- break;
- }
- i++;
- }
- }
- if (fd < 0) {
- rfbLog("initialize_uinput: could not open an uinput device.\n");
- rfbLogPerror("open");
- if (direct_rel_fd < 0 && direct_abs_fd < 0 && direct_btn_fd < 0 && direct_key_fd < 0) {
- clean_up_exit(1);
- }
- return 1;
- }
-
- memset(&udev, 0, sizeof(udev));
-
- strncpy(udev.name, "x11vnc injector", UINPUT_MAX_NAME_SIZE);
-
- s = getenv("X11VNC_UINPUT_BUS");
- if (s) {
- udev.id.bustype = get_bustype(s);
- } else if (0) {
- udev.id.bustype = BUS_USB;
- }
-
- s = getenv("X11VNC_UINPUT_VERSION");
- if (s) {
- udev.id.version = atoi(s);
- } else if (0) {
- udev.id.version = 4;
- }
-
- ioctl(fd, UI_SET_EVBIT, EV_REL);
- ioctl(fd, UI_SET_RELBIT, REL_X);
- ioctl(fd, UI_SET_RELBIT, REL_Y);
-
- ioctl(fd, UI_SET_EVBIT, EV_KEY);
-
- ioctl(fd, UI_SET_EVBIT, EV_SYN);
-
- for (i=0; i < 256; i++) {
- ioctl(fd, UI_SET_KEYBIT, i);
- }
-
- ioctl(fd, UI_SET_KEYBIT, BTN_MOUSE);
- ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
- ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE);
- ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT);
- ioctl(fd, UI_SET_KEYBIT, BTN_FORWARD);
- ioctl(fd, UI_SET_KEYBIT, BTN_BACK);
-
- if (uinput_touchscreen) {
- ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH);
- rfbLog("uinput: touchscreen enabled.\n");
- }
- if (uinput_touchscreen || uinput_abs) {
- int gw = abs_x, gh = abs_y;
- if (! gw || ! gh) {
- gw = fb_x; gh = fb_y;
- }
- if (! gw || ! gh) {
- gw = dpy_x; gh = dpy_y;
- }
- abs_x = gw;
- abs_y = gh;
- ioctl(fd, UI_SET_EVBIT, EV_ABS);
- ioctl(fd, UI_SET_ABSBIT, ABS_X);
- ioctl(fd, UI_SET_ABSBIT, ABS_Y);
- udev.absmin[ABS_X] = 0;
- udev.absmax[ABS_X] = gw;
- udev.absfuzz[ABS_X] = 0;
- udev.absflat[ABS_X] = 0;
- udev.absmin[ABS_Y] = 0;
- udev.absmax[ABS_Y] = gh;
- udev.absfuzz[ABS_Y] = 0;
- udev.absflat[ABS_Y] = 0;
- rfbLog("uinput: absolute pointer enabled at %dx%d.\n", abs_x, abs_y);
- set_uinput_accel_xy(1.0, 1.0);
- }
-
- if (db) {
- rfbLog(" udev.name: %s\n", udev.name);
- rfbLog(" udev.id.bustype: %d\n", udev.id.bustype);
- rfbLog(" udev.id.vendor: %d\n", udev.id.vendor);
- rfbLog(" udev.id.product: %d\n", udev.id.product);
- rfbLog(" udev.id.version: %d\n", udev.id.version);
- rfbLog(" udev.ff_effects_max: %d\n", udev.ff_effects_max);
- rfbLog(" udev.absmin[ABS_X]: %d\n", udev.absmin[ABS_X]);
- rfbLog(" udev.absmax[ABS_X]: %d\n", udev.absmax[ABS_X]);
- rfbLog(" udev.absfuzz[ABS_X]: %d\n", udev.absfuzz[ABS_X]);
- rfbLog(" udev.absflat[ABS_X]: %d\n", udev.absflat[ABS_X]);
- rfbLog(" udev.absmin[ABS_Y]: %d\n", udev.absmin[ABS_Y]);
- rfbLog(" udev.absmax[ABS_Y]: %d\n", udev.absmax[ABS_Y]);
- rfbLog(" udev.absfuzz[ABS_Y]: %d\n", udev.absfuzz[ABS_Y]);
- rfbLog(" udev.absflat[ABS_Y]: %d\n", udev.absflat[ABS_Y]);
- }
-
- write(fd, &udev, sizeof(udev));
-
- if (ioctl(fd, UI_DEV_CREATE) != 0) {
- rfbLog("ioctl(fd, UI_DEV_CREATE) failed.\n");
- rfbLogPerror("ioctl");
- close(fd);
- clean_up_exit(1);
- }
- return 1;
-#endif
-}
-
-/* these defaults are based on qt-embedded 7/2006 */
-static double fudge_x = 0.5; /* accel=2.0 */
-static double fudge_y = 0.5;
-
-static int thresh = 5;
-static int thresh_or = 1;
-
-static double resid_x = 0.0;
-static double resid_y = 0.0;
-
-static double zero_delay = 0.15;
-static double last_button_click = 0.0;
-
-static int uinput_always = 0;
-
-static void set_uinput_accel_xy(double fx, double fy) {
- fudge_x = 1.0/fx;
- fudge_y = 1.0/fy;
- rfbLog("set_uinput_accel: fx=%.5f fy=%.5f\n", fx, fy);
- rfbLog("set_uinput_accel: ix=%.5f iy=%.5f\n", fudge_x, fudge_y);
-}
-
-static char *uinput_accel_str = NULL;
-static char *uinput_thresh_str = NULL;
-
-int set_uinput_accel(char *str) {
- double fx, fy;
- rfbLog("set_uinput_accel: str=%s\n", str);
- if (sscanf(str, "%lf+%lf", &fx, &fy) == 2) {
- set_uinput_accel_xy(fx, fy);
- } else if (sscanf(str, "%lf", &fx) == 1) {
- set_uinput_accel_xy(fx, fx);
- } else {
- rfbLog("invalid UINPUT accel= option: %s\n", str);
- return 0;
- }
- if (uinput_accel_str) {
- free(uinput_accel_str);
- }
- uinput_accel_str = strdup(str);
- return 1;
-}
-
-int set_uinput_thresh(char *str) {
- rfbLog("set_uinput_thresh: str=%s\n", str);
- if (str[0] == '+') {
- thresh_or = 0;
- }
- thresh = atoi(str);
- if (uinput_thresh_str) {
- free(uinput_thresh_str);
- }
- uinput_thresh_str = strdup(str);
- return 1;
-}
-
-void set_uinput_reset(int ms) {
- zero_delay = (double) ms/1000.;
- rfbLog("set_uinput_reset: %d\n", ms);
-}
-
-void set_uinput_always(int a) {
- uinput_always = a;
-}
-
-void set_uinput_touchscreen(int b) {
- uinput_touchscreen = b;
-}
-
-void set_uinput_abs(int b) {
- uinput_abs = b;
-}
-
-char *get_uinput_accel(void) {
- return uinput_accel_str;
-}
-char *get_uinput_thresh(void) {
- return uinput_thresh_str;
-}
-int get_uinput_reset(void) {
- return (int) (1000 * zero_delay);
-}
-
-int get_uinput_always(void) {
- return uinput_always;
-}
-
-int get_uinput_touchscreen(void) {
- return uinput_touchscreen;
-}
-
-int get_uinput_abs(void) {
- return uinput_abs;
-}
-
-void parse_uinput_str(char *in) {
- char *p, *q, *str = strdup(in);
-
- if (injectable) {
- free(injectable);
- injectable = strdup("KMB");
- }
-
- uinput_touchscreen = 0;
- uinput_abs = 0;
- abs_x = abs_y = 0;
-
- if (tslib_cal) {
- free(tslib_cal);
- tslib_cal = NULL;
- }
-
- p = strtok(str, ",");
- while (p) {
- if (p[0] == '/') {
- if (uinput_dev) {
- free(uinput_dev);
- }
- uinput_dev = strdup(p);
- } else if (strstr(p, "nouinput") == p) {
- if (uinput_dev) {
- free(uinput_dev);
- }
- uinput_dev = strdup(p);
- } else if (strstr(p, "accel=") == p) {
- q = p + strlen("accel=");
- if (! set_uinput_accel(q)) {
- clean_up_exit(1);
- }
- } else if (strstr(p, "thresh=") == p) {
- q = p + strlen("thresh=");
- set_uinput_thresh(q);
-
- } else if (strstr(p, "reset=") == p) {
- int n = atoi(p + strlen("reset="));
- set_uinput_reset(n);
- } else if (strstr(p, "always=") == p) {
- int n = atoi(p + strlen("always="));
- set_uinput_always(n);
- } else if (strpbrk(p, "KMB") == p) {
- if (injectable) {
- free(injectable);
- }
- injectable = strdup(p);
- } else if (strstr(p, "touch_always=") == p) {
- touch_always = atoi(p + strlen("touch_always="));
- } else if (strstr(p, "btn_touch=") == p) {
- btn_touch = atoi(p + strlen("btn_touch="));
- } else if (strstr(p, "dragskip=") == p) {
- dragskip = atoi(p + strlen("dragskip="));
- } else if (strstr(p, "touch") == p) {
- int gw, gh;
- q = strchr(p, '=');
- set_uinput_touchscreen(1);
- set_uinput_abs(1);
- if (q && sscanf(q+1, "%dx%d", &gw, &gh) == 2) {
- abs_x = gw;
- abs_y = gh;
- }
- } else if (strstr(p, "abs") == p) {
- int gw, gh;
- q = strchr(p, '=');
- set_uinput_abs(1);
- if (q && sscanf(q+1, "%dx%d", &gw, &gh) == 2) {
- abs_x = gw;
- abs_y = gh;
- }
- } else if (strstr(p, "pressure=") == p) {
- touch_pressure = atoi(p + strlen("pressure="));
- } else if (strstr(p, "direct_rel=") == p) {
- direct_rel_fd = open(p+strlen("direct_rel="), O_WRONLY);
- if (direct_rel_fd < 0) {
- rfbLogPerror("uinput: direct_rel open");
- } else {
- rfbLog("uinput: opened: %s fd=%d\n", p, direct_rel_fd);
- }
- } else if (strstr(p, "direct_abs=") == p) {
- direct_abs_fd = open(p+strlen("direct_abs="), O_WRONLY);
- if (direct_abs_fd < 0) {
- rfbLogPerror("uinput: direct_abs open");
- } else {
- rfbLog("uinput: opened: %s fd=%d\n", p, direct_abs_fd);
- }
- } else if (strstr(p, "direct_btn=") == p) {
- direct_btn_fd = open(p+strlen("direct_btn="), O_WRONLY);
- if (direct_btn_fd < 0) {
- rfbLogPerror("uinput: direct_btn open");
- } else {
- rfbLog("uinput: opened: %s fd=%d\n", p, direct_btn_fd);
- }
- } else if (strstr(p, "direct_key=") == p) {
- direct_key_fd = open(p+strlen("direct_key="), O_WRONLY);
- if (direct_key_fd < 0) {
- rfbLogPerror("uinput: direct_key open");
- } else {
- rfbLog("uinput: opened: %s fd=%d\n", p, direct_key_fd);
- }
- } else if (strstr(p, "tslib_cal=") == p) {
- tslib_cal = strdup(p+strlen("tslib_cal="));
- } else {
- rfbLog("invalid UINPUT option: %s\n", p);
- clean_up_exit(1);
- }
- p = strtok(NULL, ",");
- }
- free(str);
-}
-
-static void ptr_move(int dx, int dy) {
-#ifdef UINPUT_OK
- struct input_event ev;
- int d = direct_rel_fd < 0 ? fd : direct_rel_fd;
-
- if (injectable && strchr(injectable, 'M') == NULL) {
- return;
- }
-
- memset(&ev, 0, sizeof(ev));
-
- if (db) fprintf(stderr, "ptr_move(%d, %d) fd=%d\n", dx, dy, d);
-
- gettimeofday(&ev.time, NULL);
- ev.type = EV_REL;
- ev.code = REL_Y;
- ev.value = dy;
- write(d, &ev, sizeof(ev));
-
- ev.type = EV_REL;
- ev.code = REL_X;
- ev.value = dx;
- write(d, &ev, sizeof(ev));
-
- ev.type = EV_SYN;
- ev.code = SYN_REPORT;
- ev.value = 0;
- write(d, &ev, sizeof(ev));
-#else
- if (!dx || !dy) {}
-#endif
-}
-
-static void apply_tslib(int *x, int *y) {
- double x1 = *x, y1 = *y, x2, y2;
-
- /* this is the inverse of the tslib linear transform: */
- x2 = (a[4] * (a[6] * x1 - a[2]) - a[1] * (a[6] * y1 - a[5]))/(a[4]*a[0] - a[1]*a[3]);
- y2 = (a[0] * (a[6] * y1 - a[5]) - a[3] * (a[6] * x1 - a[2]))/(a[4]*a[0] - a[1]*a[3]);
-
- *x = (int) x2;
- *y = (int) y2;
-}
-
-
-static void ptr_abs(int x, int y, int p) {
-#ifdef UINPUT_OK
- struct input_event ev;
- int x0, y0;
- int d = direct_abs_fd < 0 ? fd : direct_abs_fd;
-
- if (injectable && strchr(injectable, 'M') == NULL) {
- return;
- }
-
- memset(&ev, 0, sizeof(ev));
-
- x0 = x;
- y0 = y;
-
- if (tslib_cal) {
- apply_tslib(&x, &y);
- }
-
- if (db) fprintf(stderr, "ptr_abs(%d, %d => %d %d, p=%d) fd=%d\n", x0, y0, x, y, p, d);
-
- gettimeofday(&ev.time, NULL);
- ev.type = EV_ABS;
- ev.code = ABS_Y;
- ev.value = y;
- write(d, &ev, sizeof(ev));
-
- ev.type = EV_ABS;
- ev.code = ABS_X;
- ev.value = x;
- write(d, &ev, sizeof(ev));
-
- if (p >= 0) {
- ev.type = EV_ABS;
- ev.code = ABS_PRESSURE;
- ev.value = p;
- write(d, &ev, sizeof(ev));
- }
-
- ev.type = EV_SYN;
- ev.code = SYN_REPORT;
- ev.value = 0;
- write(d, &ev, sizeof(ev));
-#else
- if (!x || !y) {}
-#endif
-}
-
-static int inside_thresh(int dx, int dy, int thr) {
- if (thresh_or) {
- /* this is peeking at qt-embedded qmouse_qws.cpp */
- if (nabs(dx) <= thresh && nabs(dy) <= thr) {
- return 1;
- }
- } else {
- /* this is peeking at xfree/xorg xf86Xinput.c */
- if (nabs(dx) + nabs(dy) < thr) {
- return 1;
- }
- }
- return 0;
-}
-
-static void ptr_rel(int dx, int dy) {
- int dxf, dyf, nx, ny, k;
- int accel, thresh_high, thresh_mid;
- double fx, fy;
- static int try_threshes = -1;
-
- if (try_threshes < 0) {
- if (getenv("X11VNC_UINPUT_THRESHOLDS")) {
- try_threshes = 1;
- } else {
- try_threshes = 0;
- }
- }
-
- if (try_threshes) {
- thresh_high = (int) ( (double) thresh/fudge_x );
- thresh_mid = (int) ( (double) (thresh + thresh_high) / 2.0 );
-
- if (thresh_mid <= thresh) {
- thresh_mid = thresh + 1;
- }
- if (thresh_high <= thresh_mid) {
- thresh_high = thresh_mid + 1;
- }
-
- if (inside_thresh(dx, dy, thresh)) {
- accel = 0;
- } else {
- accel = 1;
- }
- nx = nabs(dx);
- ny = nabs(dy);
-
- } else {
- accel = 1;
- thresh_high = 0;
- nx = ny = 1;
- }
-
- if (accel && nx + ny > 0 ) {
- if (thresh_high > 0 && inside_thresh(dx, dy, thresh_high)) {
- double alpha, t;
- /* XXX */
- if (1 || inside_thresh(dx, dy, thresh_mid)) {
- t = thresh;
- accel = 2;
- } else {
- accel = 3;
- t = thresh_high;
- }
- if (thresh_or) {
- if (nx > ny) {
- fx = t;
- fy = ((double) ny / (double) nx) * t;
- } else {
- fx = ((double) nx / (double) ny) * t;
- fy = t;
- }
- dxf = (int) fx;
- dyf = (int) fy;
- fx = dx;
- fy = dy;
-
- } else {
- if (t > 1) {
- /* XXX */
- t = t - 1.0;
- }
- alpha = t/(nx + ny);
- fx = alpha * dx;
- fy = alpha * dy;
- dxf = (int) fx;
- dyf = (int) fy;
- fx = dx;
- fy = dy;
- }
- } else {
- fx = fudge_x * (double) dx;
- fy = fudge_y * (double) dy;
- dxf = (int) fx;
- dyf = (int) fy;
- }
- } else {
- fx = dx;
- fy = dy;
- dxf = dx;
- dyf = dy;
- }
-
- if (db > 1) fprintf(stderr, "old dx dy: %d %d\n", dx, dy);
- if (db > 1) fprintf(stderr, "new dx dy: %d %d accel: %d\n", dxf, dyf, accel);
-
- ptr_move(dxf, dyf);
-
- resid_x += fx - dxf;
- resid_y += fy - dyf;
-
- for (k = 0; k < 4; k++) {
- if (resid_x <= -1.0 || resid_x >= 1.0 || resid_y <= -1.0 || resid_y >= 1.0) {
- dxf = 0;
- dyf = 0;
- if (resid_x >= 1.0) {
- dxf = (int) resid_x;
- dxf = 1;
- } else if (resid_x <= -1.0) {
- dxf = -((int) (-resid_x));
- dxf = -1;
- }
- resid_x -= dxf;
- if (resid_y >= 1.0) {
- dyf = (int) resid_y;
- dyf = 1;
- } else if (resid_y <= -1.0) {
- dyf = -((int) (-resid_y));
- dyf = -1;
- }
- resid_y -= dyf;
-
- if (db > 1) fprintf(stderr, "*%s resid: dx dy: %d %d %f %f\n", accel > 1 ? "*" : " ", dxf, dyf, resid_x, resid_y);
-if (0) {usleep(100*1000) ;}
- ptr_move(dxf, dyf);
- }
- }
-}
-
-static void button_click(int down, int btn) {
-#ifdef UINPUT_OK
- struct input_event ev;
- int d = direct_btn_fd < 0 ? fd : direct_btn_fd;
-
- if (injectable && strchr(injectable, 'B') == NULL) {
- return;
- }
-
- if (db) fprintf(stderr, "button_click: btn %d %s fd=%d\n", btn, down ? "down" : "up", d);
-
- memset(&ev, 0, sizeof(ev));
- gettimeofday(&ev.time, NULL);
- ev.type = EV_KEY;
- ev.value = down;
-
- if (uinput_touchscreen) {
- ev.code = BTN_TOUCH;
- if (db) fprintf(stderr, "set code to BTN_TOUCH\n");
- } else if (btn == 1) {
- ev.code = BTN_LEFT;
- } else if (btn == 2) {
- ev.code = BTN_MIDDLE;
- } else if (btn == 3) {
- ev.code = BTN_RIGHT;
- } else if (btn == 4) {
- ev.code = BTN_FORWARD;
- } else if (btn == 5) {
- ev.code = BTN_BACK;
- } else {
- return;
- }
-
- write(d, &ev, sizeof(ev));
-
- ev.type = EV_SYN;
- ev.code = SYN_REPORT;
- ev.value = 0;
- write(d, &ev, sizeof(ev));
-
- last_button_click = dnow();
-#else
- if (!down || !btn) {}
-#endif
-}
-
-
-void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client) {
- static int last_x = -1, last_y = -1, last_mask = -1;
- static double last_zero = 0.0;
- allowed_input_t input;
- int do_reset, reset_lower_right = 1;
- double now;
- static int first = 1;
-
- if (first) {
- if (getenv("RESET_ALWAYS")) {
- set_uinput_always(1);
- } else {
- set_uinput_always(0);
- }
- }
- first = 0;
-
- if (db) fprintf(stderr, "uinput_pointer_command: %d %d - %d\n", x, y, mask);
-
- if (view_only) {
- return;
- }
- get_allowed_input(client, &input);
-
- now = dnow();
-
- do_reset = 1;
- if (mask || bmask) {
- do_reset = 0; /* do not do reset if mouse button down */
- } else if (! input.motion) {
- do_reset = 0;
- } else if (now < last_zero + zero_delay) {
- do_reset = 0;
- }
- if (do_reset) {
- if (mod_is_down()) {
- do_reset = 0;
- } else if (now < last_button_click + 0.25) {
- do_reset = 0;
- }
- }
-
- if (uinput_always && !mask && !bmask && input.motion) {
- do_reset = 1;
- }
- if (uinput_abs) {
- do_reset = 0;
- }
-
- if (do_reset) {
- static int first = 1;
-
- if (zero_delay > 0.0 || first) {
- /* try to push it to 0,0 */
- int tx, ty, bigjump = 1;
-
- if (reset_lower_right) {
- tx = fudge_x * (dpy_x - last_x);
- ty = fudge_y * (dpy_y - last_y);
- } else {
- tx = fudge_x * last_x;
- ty = fudge_y * last_y;
- }
-
- tx += 50;
- ty += 50;
-
- if (bigjump) {
- if (reset_lower_right) {
- ptr_move(0, +ty);
- usleep(2*1000);
- ptr_move(+tx, +ty);
- ptr_move(+tx, +ty);
- } else {
- ptr_move(0, -ty);
- usleep(2*1000);
- ptr_move(-tx, -ty);
- ptr_move(-tx, -ty);
- }
- } else {
- int i, step, n = 20;
- step = dpy_x / n;
-
- if (step < 100) step = 100;
-
- for (i=0; i < n; i++) {
- if (reset_lower_right) {
- ptr_move(+step, +step);
- } else {
- ptr_move(-step, -step);
- }
- }
- for (i=0; i < n; i++) {
- if (reset_lower_right) {
- ptr_move(+1, +1);
- } else {
- ptr_move(-1, -1);
- }
- }
- }
- if (db) {
- if (reset_lower_right) {
- fprintf(stderr, "uinput_pointer_command: reset -> (W,H) (%d,%d) [%d,%d]\n", x, y, tx, ty);
- } else {
- fprintf(stderr, "uinput_pointer_command: reset -> (0,0) (%d,%d) [%d,%d]\n", x, y, tx, ty);
- }
- }
-
- /* rest a bit for system to absorb the change */
- if (uinput_always) {
- static double last_sleep = 0.0;
- double nw = dnow(), delay = zero_delay;
- if (delay <= 0.0) delay = 0.1;
- if (nw > last_sleep + delay) {
- usleep(10*1000);
- last_sleep = nw;
- } else {
- usleep(1*1000);
- }
-
- } else {
- usleep(30*1000);
- }
-
- /* now jump back out */
- if (reset_lower_right) {
- ptr_rel(x - dpy_x, y - dpy_y);
- } else {
- ptr_rel(x, y);
- }
- if (1) {usleep(10*1000) ;}
-
- last_x = x;
- last_y = y;
- resid_x = 0.0;
- resid_y = 0.0;
-
- first = 0;
- }
- last_zero = dnow();
- }
-
- if (input.motion) {
- if (x != last_x || y != last_y) {
- if (uinput_touchscreen) {
- ;
- } else if (uinput_abs) {
- ptr_abs(x, y, -1);
- } else {
- ptr_rel(x - last_x, y - last_y);
- }
- last_x = x;
- last_y = y;
- }
- }
-
- if (! input.button) {
- return;
- }
-
- if (last_mask < 0) {
- last_mask = mask;
- }
-
- if (db > 2) {
- fprintf(stderr, "mask: %s\n", bitprint(mask, 16));
- fprintf(stderr, "bmask: %s\n", bitprint(bmask, 16));
- fprintf(stderr, "last_mask: %s\n", bitprint(last_mask, 16));
- fprintf(stderr, "button_mask: %s\n", bitprint(button_mask, 16));
- }
-
- if (uinput_touchscreen) {
- if (!btn_touch) {
- static int down_count = 0;
- int p = touch_pressure >=0 ? touch_pressure : 0;
- if (!last_mask && !mask) {
- if (touch_always) {
- ptr_abs(last_x, last_y, 0);
- }
- } else if (!last_mask && mask) {
- ptr_abs(last_x, last_y, p);
- down_count = 0;
- } else if (last_mask && !mask) {
- ptr_abs(last_x, last_y, 0);
- } else if (last_mask && mask) {
- down_count++;
- if (dragskip > 0) {
- if (down_count % dragskip == 0) {
- ptr_abs(last_x, last_y, p);
- }
- } else {
- ptr_abs(last_x, last_y, p);
- }
- }
- } else {
- if (!last_mask && !mask) {
- if (touch_always) {
- ptr_abs(last_x, last_y, 0);
- }
- } else if (!last_mask && mask) {
- ptr_abs(last_x, last_y, 0);
- button_click(1, 0);
- } else if (last_mask && !mask) {
- ptr_abs(last_x, last_y, 0);
- button_click(0, 0);
- } else if (last_mask && mask) {
- ;
- }
- }
- last_mask = mask;
- } else if (mask != last_mask) {
- int i;
- for (i=1; i <= MAX_BUTTONS; i++) {
- int down, b = 1 << (i-1);
- if ( (last_mask & b) == (mask & b)) {
- continue;
- }
- if (mask & b) {
- down = 1;
- } else {
- down = 0;
- }
- button_click(down, i);
- }
- if (mask && uinput_abs && touch_pressure >= 0) {
- ptr_abs(last_x, last_y, touch_pressure);
- }
- last_mask = mask;
- }
- bmask = mask;
-}
-
-void uinput_key_command(int down, int keysym, rfbClientPtr client) {
-#ifdef UINPUT_OK
- struct input_event ev;
- int scancode;
- allowed_input_t input;
- int d = direct_key_fd < 0 ? fd : direct_key_fd;
-
- if (injectable && strchr(injectable, 'K') == NULL) {
- return;
- }
- if (view_only) {
- return;
- }
- get_allowed_input(client, &input);
- if (! input.keystroke) {
- return;
- }
-
- scancode = lookup_code(keysym);
-
- if (scancode < 0) {
- return;
- }
- if (db) fprintf(stderr, "uinput_key_command: %d -> %d %s fd=%d\n", keysym, scancode, down ? "down" : "up", d);
-
- memset(&ev, 0, sizeof(ev));
- gettimeofday(&ev.time, NULL);
- ev.type = EV_KEY;
- ev.code = (unsigned char) scancode;
- ev.value = down;
-
- write(d, &ev, sizeof(ev));
-
- ev.type = EV_SYN;
- ev.code = SYN_REPORT;
- ev.value = 0;
- write(d, &ev, sizeof(ev));
-
- if (0 <= scancode && scancode < 256) {
- key_pressed[scancode] = down ? 1 : 0;
- }
-#else
- if (!down || !keysym || !client) {}
-#endif
-}
-
-#if 0
- grep 'case XK_' x0vnc.c | sed -e 's/case /$key_lookup{/' -e 's/:/}/' -e 's/return /= $/'
-#endif
-
-static int lookup_code(int keysym) {
-
- if (keysym == NoSymbol) {
- return -1;
- }
-
- switch(keysym) {
-#ifdef UINPUT_OK
- case XK_Escape: return KEY_ESC;
- case XK_1: return KEY_1;
- case XK_2: return KEY_2;
- case XK_3: return KEY_3;
- case XK_4: return KEY_4;
- case XK_5: return KEY_5;
- case XK_6: return KEY_6;
- case XK_7: return KEY_7;
- case XK_8: return KEY_8;
- case XK_9: return KEY_9;
- case XK_0: return KEY_0;
- case XK_exclam: return KEY_1;
- case XK_at: return KEY_2;
- case XK_numbersign: return KEY_3;
- case XK_dollar: return KEY_4;
- case XK_percent: return KEY_5;
- case XK_asciicircum: return KEY_6;
- case XK_ampersand: return KEY_7;
- case XK_asterisk: return KEY_8;
- case XK_parenleft: return KEY_9;
- case XK_parenright: return KEY_0;
- case XK_minus: return KEY_MINUS;
- case XK_underscore: return KEY_MINUS;
- case XK_equal: return KEY_EQUAL;
- case XK_plus: return KEY_EQUAL;
- case XK_BackSpace: return KEY_BACKSPACE;
- case XK_Tab: return KEY_TAB;
- case XK_q: return KEY_Q;
- case XK_Q: return KEY_Q;
- case XK_w: return KEY_W;
- case XK_W: return KEY_W;
- case XK_e: return KEY_E;
- case XK_E: return KEY_E;
- case XK_r: return KEY_R;
- case XK_R: return KEY_R;
- case XK_t: return KEY_T;
- case XK_T: return KEY_T;
- case XK_y: return KEY_Y;
- case XK_Y: return KEY_Y;
- case XK_u: return KEY_U;
- case XK_U: return KEY_U;
- case XK_i: return KEY_I;
- case XK_I: return KEY_I;
- case XK_o: return KEY_O;
- case XK_O: return KEY_O;
- case XK_p: return KEY_P;
- case XK_P: return KEY_P;
- case XK_braceleft: return KEY_LEFTBRACE;
- case XK_braceright: return KEY_RIGHTBRACE;
- case XK_bracketleft: return KEY_LEFTBRACE;
- case XK_bracketright: return KEY_RIGHTBRACE;
- case XK_Return: return KEY_ENTER;
- case XK_Control_L: return KEY_LEFTCTRL;
- case XK_a: return KEY_A;
- case XK_A: return KEY_A;
- case XK_s: return KEY_S;
- case XK_S: return KEY_S;
- case XK_d: return KEY_D;
- case XK_D: return KEY_D;
- case XK_f: return KEY_F;
- case XK_F: return KEY_F;
- case XK_g: return KEY_G;
- case XK_G: return KEY_G;
- case XK_h: return KEY_H;
- case XK_H: return KEY_H;
- case XK_j: return KEY_J;
- case XK_J: return KEY_J;
- case XK_k: return KEY_K;
- case XK_K: return KEY_K;
- case XK_l: return KEY_L;
- case XK_L: return KEY_L;
- case XK_semicolon: return KEY_SEMICOLON;
- case XK_colon: return KEY_SEMICOLON;
- case XK_apostrophe: return KEY_APOSTROPHE;
- case XK_quotedbl: return KEY_APOSTROPHE;
- case XK_grave: return KEY_GRAVE;
- case XK_asciitilde: return KEY_GRAVE;
- case XK_Shift_L: return KEY_LEFTSHIFT;
- case XK_backslash: return KEY_BACKSLASH;
- case XK_bar: return KEY_BACKSLASH;
- case XK_z: return KEY_Z;
- case XK_Z: return KEY_Z;
- case XK_x: return KEY_X;
- case XK_X: return KEY_X;
- case XK_c: return KEY_C;
- case XK_C: return KEY_C;
- case XK_v: return KEY_V;
- case XK_V: return KEY_V;
- case XK_b: return KEY_B;
- case XK_B: return KEY_B;
- case XK_n: return KEY_N;
- case XK_N: return KEY_N;
- case XK_m: return KEY_M;
- case XK_M: return KEY_M;
- case XK_comma: return KEY_COMMA;
- case XK_less: return KEY_COMMA;
- case XK_period: return KEY_DOT;
- case XK_greater: return KEY_DOT;
- case XK_slash: return KEY_SLASH;
- case XK_question: return KEY_SLASH;
- case XK_Shift_R: return KEY_RIGHTSHIFT;
- case XK_KP_Multiply: return KEY_KPASTERISK;
- case XK_Alt_L: return KEY_LEFTALT;
- case XK_space: return KEY_SPACE;
- case XK_Caps_Lock: return KEY_CAPSLOCK;
- case XK_F1: return KEY_F1;
- case XK_F2: return KEY_F2;
- case XK_F3: return KEY_F3;
- case XK_F4: return KEY_F4;
- case XK_F5: return KEY_F5;
- case XK_F6: return KEY_F6;
- case XK_F7: return KEY_F7;
- case XK_F8: return KEY_F8;
- case XK_F9: return KEY_F9;
- case XK_F10: return KEY_F10;
- case XK_Num_Lock: return KEY_NUMLOCK;
- case XK_Scroll_Lock: return KEY_SCROLLLOCK;
- case XK_KP_7: return KEY_KP7;
- case XK_KP_8: return KEY_KP8;
- case XK_KP_9: return KEY_KP9;
- case XK_KP_Subtract: return KEY_KPMINUS;
- case XK_KP_4: return KEY_KP4;
- case XK_KP_5: return KEY_KP5;
- case XK_KP_6: return KEY_KP6;
- case XK_KP_Add: return KEY_KPPLUS;
- case XK_KP_1: return KEY_KP1;
- case XK_KP_2: return KEY_KP2;
- case XK_KP_3: return KEY_KP3;
- case XK_KP_0: return KEY_KP0;
- case XK_KP_Decimal: return KEY_KPDOT;
- case XK_F13: return KEY_F13;
- case XK_F11: return KEY_F11;
- case XK_F12: return KEY_F12;
- case XK_F14: return KEY_F14;
- case XK_F15: return KEY_F15;
- case XK_F16: return KEY_F16;
- case XK_F17: return KEY_F17;
- case XK_F18: return KEY_F18;
- case XK_F19: return KEY_F19;
- case XK_F20: return KEY_F20;
- case XK_KP_Enter: return KEY_KPENTER;
- case XK_Control_R: return KEY_RIGHTCTRL;
- case XK_KP_Divide: return KEY_KPSLASH;
- case XK_Sys_Req: return KEY_SYSRQ;
- case XK_Alt_R: return KEY_RIGHTALT;
- case XK_Linefeed: return KEY_LINEFEED;
- case XK_Home: return KEY_HOME;
- case XK_Up: return KEY_UP;
- case XK_Page_Up: return KEY_PAGEUP;
- case XK_Left: return KEY_LEFT;
- case XK_Right: return KEY_RIGHT;
- case XK_End: return KEY_END;
- case XK_Down: return KEY_DOWN;
- case XK_Page_Down: return KEY_PAGEDOWN;
- case XK_Insert: return KEY_INSERT;
- case XK_Delete: return KEY_DELETE;
- case XK_KP_Equal: return KEY_KPEQUAL;
- case XK_Pause: return KEY_PAUSE;
- case XK_F21: return KEY_F21;
- case XK_F22: return KEY_F22;
- case XK_F23: return KEY_F23;
- case XK_F24: return KEY_F24;
- case XK_KP_Separator: return KEY_KPCOMMA;
- case XK_Meta_L: return KEY_LEFTMETA;
- case XK_Meta_R: return KEY_RIGHTMETA;
- case XK_Multi_key: return KEY_COMPOSE;
-#endif
- default: return -1;
- }
-}
-
-#if 0
-
-From /usr/include/linux/input.h
-
-We maintain it here since it is such a painful mess.
-
-Here is a little script to make it easier:
-
-#!/usr/bin/perl
-while (<>) {
- $_ =~ s/-XK_/XK_/;
- next unless /^XK_/;
- chomp;
- if (/^(\S+)(\s+)(\S+)/) {
- $a = $1;
- $t = $2;
- $b = $3;
- print "\tcase $a:${t}return $b;\n";
- if ($a =~ /XK_[a-z]$/) {
- $a = uc($a);
- print "\tcase $a:${t}return $b;\n";
- }
- }
-}
-
-This only handles US kbd, we would need a kbd database in general...
-Ugh: parse dumpkeys(1) or -fookeys /usr/share/keymaps/i386/qwerty/dk.kmap.gz
-
-XK_Escape KEY_ESC
-XK_1 KEY_1
-XK_2 KEY_2
-XK_3 KEY_3
-XK_4 KEY_4
-XK_5 KEY_5
-XK_6 KEY_6
-XK_7 KEY_7
-XK_8 KEY_8
-XK_9 KEY_9
-XK_0 KEY_0
--XK_exclam KEY_1
--XK_at KEY_2
--XK_numbersign KEY_3
--XK_dollar KEY_4
--XK_percent KEY_5
--XK_asciicircum KEY_6
--XK_ampersand KEY_7
--XK_asterisk KEY_8
--XK_parenleft KEY_9
--XK_parenright KEY_0
-XK_minus KEY_MINUS
--XK_underscore KEY_MINUS
-XK_equal KEY_EQUAL
--XK_plus KEY_EQUAL
-XK_BackSpace KEY_BACKSPACE
-XK_Tab KEY_TAB
-XK_q KEY_Q
-XK_w KEY_W
-XK_e KEY_E
-XK_r KEY_R
-XK_t KEY_T
-XK_y KEY_Y
-XK_u KEY_U
-XK_i KEY_I
-XK_o KEY_O
-XK_p KEY_P
-XK_braceleft KEY_LEFTBRACE
-XK_braceright KEY_RIGHTBRACE
--XK_bracketleft KEY_LEFTBRACE
--XK_bracketright KEY_RIGHTBRACE
-XK_Return KEY_ENTER
-XK_Control_L KEY_LEFTCTRL
-XK_a KEY_A
-XK_s KEY_S
-XK_d KEY_D
-XK_f KEY_F
-XK_g KEY_G
-XK_h KEY_H
-XK_j KEY_J
-XK_k KEY_K
-XK_l KEY_L
-XK_semicolon KEY_SEMICOLON
--XK_colon KEY_SEMICOLON
-XK_apostrophe KEY_APOSTROPHE
--XK_quotedbl KEY_APOSTROPHE
-XK_grave KEY_GRAVE
--XK_asciitilde KEY_GRAVE
-XK_Shift_L KEY_LEFTSHIFT
-XK_backslash KEY_BACKSLASH
--XK_bar KEY_BACKSLASH
-XK_z KEY_Z
-XK_x KEY_X
-XK_c KEY_C
-XK_v KEY_V
-XK_b KEY_B
-XK_n KEY_N
-XK_m KEY_M
-XK_comma KEY_COMMA
--XK_less KEY_COMMA
-XK_period KEY_DOT
--XK_greater KEY_DOT
-XK_slash KEY_SLASH
--XK_question KEY_SLASH
-XK_Shift_R KEY_RIGHTSHIFT
-XK_KP_Multiply KEY_KPASTERISK
-XK_Alt_L KEY_LEFTALT
-XK_space KEY_SPACE
-XK_Caps_Lock KEY_CAPSLOCK
-XK_F1 KEY_F1
-XK_F2 KEY_F2
-XK_F3 KEY_F3
-XK_F4 KEY_F4
-XK_F5 KEY_F5
-XK_F6 KEY_F6
-XK_F7 KEY_F7
-XK_F8 KEY_F8
-XK_F9 KEY_F9
-XK_F10 KEY_F10
-XK_Num_Lock KEY_NUMLOCK
-XK_Scroll_Lock KEY_SCROLLLOCK
-XK_KP_7 KEY_KP7
-XK_KP_8 KEY_KP8
-XK_KP_9 KEY_KP9
-XK_KP_Subtract KEY_KPMINUS
-XK_KP_4 KEY_KP4
-XK_KP_5 KEY_KP5
-XK_KP_6 KEY_KP6
-XK_KP_Add KEY_KPPLUS
-XK_KP_1 KEY_KP1
-XK_KP_2 KEY_KP2
-XK_KP_3 KEY_KP3
-XK_KP_0 KEY_KP0
-XK_KP_Decimal KEY_KPDOT
-NoSymbol KEY_103RD
-XK_F13 KEY_F13
-NoSymbol KEY_102ND
-XK_F11 KEY_F11
-XK_F12 KEY_F12
-XK_F14 KEY_F14
-XK_F15 KEY_F15
-XK_F16 KEY_F16
-XK_F17 KEY_F17
-XK_F18 KEY_F18
-XK_F19 KEY_F19
-XK_F20 KEY_F20
-XK_KP_Enter KEY_KPENTER
-XK_Control_R KEY_RIGHTCTRL
-XK_KP_Divide KEY_KPSLASH
-XK_Sys_Req KEY_SYSRQ
-XK_Alt_R KEY_RIGHTALT
-XK_Linefeed KEY_LINEFEED
-XK_Home KEY_HOME
-XK_Up KEY_UP
-XK_Page_Up KEY_PAGEUP
-XK_Left KEY_LEFT
-XK_Right KEY_RIGHT
-XK_End KEY_END
-XK_Down KEY_DOWN
-XK_Page_Down KEY_PAGEDOWN
-XK_Insert KEY_INSERT
-XK_Delete KEY_DELETE
-NoSymbol KEY_MACRO
-NoSymbol KEY_MUTE
-NoSymbol KEY_VOLUMEDOWN
-NoSymbol KEY_VOLUMEUP
-NoSymbol KEY_POWER
-XK_KP_Equal KEY_KPEQUAL
-NoSymbol KEY_KPPLUSMINUS
-XK_Pause KEY_PAUSE
-XK_F21 KEY_F21
-XK_F22 KEY_F22
-XK_F23 KEY_F23
-XK_F24 KEY_F24
-XK_KP_Separator KEY_KPCOMMA
-XK_Meta_L KEY_LEFTMETA
-XK_Meta_R KEY_RIGHTMETA
-XK_Multi_key KEY_COMPOSE
-
-NoSymbol KEY_STOP
-NoSymbol KEY_AGAIN
-NoSymbol KEY_PROPS
-NoSymbol KEY_UNDO
-NoSymbol KEY_FRONT
-NoSymbol KEY_COPY
-NoSymbol KEY_OPEN
-NoSymbol KEY_PASTE
-NoSymbol KEY_FIND
-NoSymbol KEY_CUT
-NoSymbol KEY_HELP
-NoSymbol KEY_MENU
-NoSymbol KEY_CALC
-NoSymbol KEY_SETUP
-NoSymbol KEY_SLEEP
-NoSymbol KEY_WAKEUP
-NoSymbol KEY_FILE
-NoSymbol KEY_SENDFILE
-NoSymbol KEY_DELETEFILE
-NoSymbol KEY_XFER
-NoSymbol KEY_PROG1
-NoSymbol KEY_PROG2
-NoSymbol KEY_WWW
-NoSymbol KEY_MSDOS
-NoSymbol KEY_COFFEE
-NoSymbol KEY_DIRECTION
-NoSymbol KEY_CYCLEWINDOWS
-NoSymbol KEY_MAIL
-NoSymbol KEY_BOOKMARKS
-NoSymbol KEY_COMPUTER
-NoSymbol KEY_BACK
-NoSymbol KEY_FORWARD
-NoSymbol KEY_CLOSECD
-NoSymbol KEY_EJECTCD
-NoSymbol KEY_EJECTCLOSECD
-NoSymbol KEY_NEXTSONG
-NoSymbol KEY_PLAYPAUSE
-NoSymbol KEY_PREVIOUSSONG
-NoSymbol KEY_STOPCD
-NoSymbol KEY_RECORD
-NoSymbol KEY_REWIND
-NoSymbol KEY_PHONE
-NoSymbol KEY_ISO
-NoSymbol KEY_CONFIG
-NoSymbol KEY_HOMEPAGE
-NoSymbol KEY_REFRESH
-NoSymbol KEY_EXIT
-NoSymbol KEY_MOVE
-NoSymbol KEY_EDIT
-NoSymbol KEY_SCROLLUP
-NoSymbol KEY_SCROLLDOWN
-NoSymbol KEY_KPLEFTPAREN
-NoSymbol KEY_KPRIGHTPAREN
-
-NoSymbol KEY_INTL1
-NoSymbol KEY_INTL2
-NoSymbol KEY_INTL3
-NoSymbol KEY_INTL4
-NoSymbol KEY_INTL5
-NoSymbol KEY_INTL6
-NoSymbol KEY_INTL7
-NoSymbol KEY_INTL8
-NoSymbol KEY_INTL9
-NoSymbol KEY_LANG1
-NoSymbol KEY_LANG2
-NoSymbol KEY_LANG3
-NoSymbol KEY_LANG4
-NoSymbol KEY_LANG5
-NoSymbol KEY_LANG6
-NoSymbol KEY_LANG7
-NoSymbol KEY_LANG8
-NoSymbol KEY_LANG9
-
-NoSymbol KEY_PLAYCD
-NoSymbol KEY_PAUSECD
-NoSymbol KEY_PROG3
-NoSymbol KEY_PROG4
-NoSymbol KEY_SUSPEND
-NoSymbol KEY_CLOSE
-NoSymbol KEY_PLAY
-NoSymbol KEY_FASTFORWARD
-NoSymbol KEY_BASSBOOST
-NoSymbol KEY_PRINT
-NoSymbol KEY_HP
-NoSymbol KEY_CAMERA
-NoSymbol KEY_SOUND
-NoSymbol KEY_QUESTION
-NoSymbol KEY_EMAIL
-NoSymbol KEY_CHAT
-NoSymbol KEY_SEARCH
-NoSymbol KEY_CONNECT
-NoSymbol KEY_FINANCE
-NoSymbol KEY_SPORT
-NoSymbol KEY_SHOP
-NoSymbol KEY_ALTERASE
-NoSymbol KEY_CANCEL
-NoSymbol KEY_BRIGHTNESSDOWN
-NoSymbol KEY_BRIGHTNESSUP
-NoSymbol KEY_MEDIA
-
-NoSymbol KEY_UNKNOWN
-NoSymbol
-NoSymbol BTN_MISC
-NoSymbol BTN_0
-NoSymbol BTN_1
-NoSymbol BTN_2
-NoSymbol BTN_3
-NoSymbol BTN_4
-NoSymbol BTN_5
-NoSymbol BTN_6
-NoSymbol BTN_7
-NoSymbol BTN_8
-NoSymbol BTN_9
-NoSymbol
-NoSymbol BTN_MOUSE
-NoSymbol BTN_LEFT
-NoSymbol BTN_RIGHT
-NoSymbol BTN_MIDDLE
-NoSymbol BTN_SIDE
-NoSymbol BTN_EXTRA
-NoSymbol BTN_FORWARD
-NoSymbol BTN_BACK
-NoSymbol BTN_TASK
-NoSymbol
-NoSymbol BTN_JOYSTICK
-NoSymbol BTN_TRIGGER
-NoSymbol BTN_THUMB
-NoSymbol BTN_THUMB2
-NoSymbol BTN_TOP
-NoSymbol BTN_TOP2
-NoSymbol BTN_PINKIE
-NoSymbol BTN_BASE
-NoSymbol BTN_BASE2
-NoSymbol BTN_BASE3
-NoSymbol BTN_BASE4
-NoSymbol BTN_BASE5
-NoSymbol BTN_BASE6
-NoSymbol BTN_DEAD
-
-NoSymbol BTN_GAMEPAD
-NoSymbol BTN_A
-NoSymbol BTN_B
-NoSymbol BTN_C
-NoSymbol BTN_X
-NoSymbol BTN_Y
-NoSymbol BTN_Z
-NoSymbol BTN_TL
-NoSymbol BTN_TR
-NoSymbol BTN_TL2
-NoSymbol BTN_TR2
-NoSymbol BTN_SELECT
-NoSymbol BTN_START
-NoSymbol BTN_MODE
-NoSymbol BTN_THUMBL
-NoSymbol BTN_THUMBR
-
-NoSymbol BTN_DIGI
-NoSymbol BTN_TOOL_PEN
-NoSymbol BTN_TOOL_RUBBER
-NoSymbol BTN_TOOL_BRUSH
-NoSymbol BTN_TOOL_PENCIL
-NoSymbol BTN_TOOL_AIRBRUSH
-NoSymbol BTN_TOOL_FINGER
-NoSymbol BTN_TOOL_MOUSE
-NoSymbol BTN_TOOL_LENS
-NoSymbol BTN_TOUCH
-NoSymbol BTN_STYLUS
-NoSymbol BTN_STYLUS2
-NoSymbol BTN_TOOL_DOUBLETAP
-NoSymbol BTN_TOOL_TRIPLETAP
-
-NoSymbol BTN_WHEEL
-NoSymbol BTN_GEAR_DOWN
-NoSymbol BTN_GEAR_UP
-
-NoSymbol KEY_OK
-NoSymbol KEY_SELECT
-NoSymbol KEY_GOTO
-NoSymbol KEY_CLEAR
-NoSymbol KEY_POWER2
-NoSymbol KEY_OPTION
-NoSymbol KEY_INFO
-NoSymbol KEY_TIME
-NoSymbol KEY_VENDOR
-NoSymbol KEY_ARCHIVE
-NoSymbol KEY_PROGRAM
-NoSymbol KEY_CHANNEL
-NoSymbol KEY_FAVORITES
-NoSymbol KEY_EPG
-NoSymbol KEY_PVR
-NoSymbol KEY_MHP
-NoSymbol KEY_LANGUAGE
-NoSymbol KEY_TITLE
-NoSymbol KEY_SUBTITLE
-NoSymbol KEY_ANGLE
-NoSymbol KEY_ZOOM
-NoSymbol KEY_MODE
-NoSymbol KEY_KEYBOARD
-NoSymbol KEY_SCREEN
-NoSymbol KEY_PC
-NoSymbol KEY_TV
-NoSymbol KEY_TV2
-NoSymbol KEY_VCR
-NoSymbol KEY_VCR2
-NoSymbol KEY_SAT
-NoSymbol KEY_SAT2
-NoSymbol KEY_CD
-NoSymbol KEY_TAPE
-NoSymbol KEY_RADIO
-NoSymbol KEY_TUNER
-NoSymbol KEY_PLAYER
-NoSymbol KEY_TEXT
-NoSymbol KEY_DVD
-NoSymbol KEY_AUX
-NoSymbol KEY_MP3
-NoSymbol KEY_AUDIO
-NoSymbol KEY_VIDEO
-NoSymbol KEY_DIRECTORY
-NoSymbol KEY_LIST
-NoSymbol KEY_MEMO
-NoSymbol KEY_CALENDAR
-NoSymbol KEY_RED
-NoSymbol KEY_GREEN
-NoSymbol KEY_YELLOW
-NoSymbol KEY_BLUE
-NoSymbol KEY_CHANNELUP
-NoSymbol KEY_CHANNELDOWN
-NoSymbol KEY_FIRST
-NoSymbol KEY_LAST
-NoSymbol KEY_AB
-NoSymbol KEY_NEXT
-NoSymbol KEY_RESTART
-NoSymbol KEY_SLOW
-NoSymbol KEY_SHUFFLE
-NoSymbol KEY_BREAK
-NoSymbol KEY_PREVIOUS
-NoSymbol KEY_DIGITS
-NoSymbol KEY_TEEN
-NoSymbol KEY_TWEN
-
-NoSymbol KEY_DEL_EOL
-NoSymbol KEY_DEL_EOS
-NoSymbol KEY_INS_LINE
-NoSymbol KEY_DEL_LINE
-NoSymbol KEY_MAX
-
-#endif
-
-
diff --git a/x11vnc/uinput.h b/x11vnc/uinput.h
deleted file mode 100644
index 346e97c..0000000
--- a/x11vnc/uinput.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_UINPUT_H
-#define _X11VNC_UINPUT_H
-
-/* -- uinput.h -- */
-
-extern int check_uinput(void);
-extern int initialize_uinput(void);
-extern void shutdown_uinput(void);
-extern int set_uinput_accel(char *str);
-extern int set_uinput_thresh(char *str);
-extern void set_uinput_reset(int ms);
-extern void set_uinput_always(int);
-extern void set_uinput_touchscreen(int);
-extern void set_uinput_abs(int);
-extern char *get_uinput_accel();
-extern char *get_uinput_thresh();
-extern int get_uinput_reset();
-extern int get_uinput_always();
-extern int get_uinput_touchscreen();
-extern int get_uinput_abs();
-extern void parse_uinput_str(char *str);
-extern void uinput_pointer_command(int mask, int x, int y, rfbClientPtr client);
-extern void uinput_key_command(int down, int keysym, rfbClientPtr client);
-
-
-
-#endif /* _X11VNC_UINPUT_H */
diff --git a/x11vnc/unixpw.c b/x11vnc/unixpw.c
deleted file mode 100644
index ccdb195..0000000
--- a/x11vnc/unixpw.c
+++ /dev/null
@@ -1,2281 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- unixpw.c -- */
-
-#ifdef __linux__
-/* some conflict with _XOPEN_SOURCE */
-extern int grantpt(int);
-extern int unlockpt(int);
-extern char *ptsname(int);
-#endif
-
-#ifndef DO_NOT_DECLARE_CRYPT
-extern char *crypt(const char*, const char *);
-#endif
-
-#include "x11vnc.h"
-#include "scan.h"
-#include "cleanup.h"
-#include "xinerama.h"
-#include "connections.h"
-#include "user.h"
-#include "connections.h"
-#include "sslhelper.h"
-#include "cursor.h"
-#include "rates.h"
-#include <rfb/default8x16.h>
-
-#if LIBVNCSERVER_HAVE_FORK
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_WAITPID
-#define UNIXPW_SU
-#endif
-#endif
-
-#ifdef IGNORE_GETSPNAM
-#undef LIBVNCSERVER_HAVE_GETSPNAM
-#define LIBVNCSERVER_HAVE_GETSPNAM 0
-#endif
-
-#if LIBVNCSERVER_HAVE_PWD_H && LIBVNCSERVER_HAVE_GETPWNAM
-#if LIBVNCSERVER_HAVE_CRYPT || LIBVNCSERVER_HAVE_LIBCRYPT
-#define UNIXPW_CRYPT
-#if LIBVNCSERVER_HAVE_GETSPNAM
-#include <shadow.h>
-#endif
-#endif
-#endif
-
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#if LIBVNCSERVER_HAVE_TERMIOS_H
-#include <termios.h>
-#endif
-#if LIBVNCSERVER_HAVE_SYS_STROPTS_H
-#include <sys/stropts.h>
-#endif
-
-#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
-#define IS_BSD
-#endif
-#if (defined(__MACH__) && defined(__APPLE__))
-#define IS_BSD
-#endif
-
-int white_pixel(void);
-void unixpw_screen(int init);
-void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
-void unixpw_accept(char *user);
-void unixpw_deny(void);
-void unixpw_msg(char *msg, int delay);
-int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size, int nodisp);
-int unixpw_cmd_run(char *user, char *pass, char *cmd, char *line, int *n);
-int crypt_verify(char *user, char *pass);
-int cmd_verify(char *user, char *pass);
-void unixpw_verify_screen(char *user, char *pass);
-
-static int text_x(void);
-static int text_y(void);
-static void set_db(void);
-
-int unixpw_in_progress = 0;
-int unixpw_denied = 0;
-int unixpw_in_rfbPE = 0;
-int unixpw_login_viewonly = 0;
-int unixpw_tightvnc_xfer_save = 0;
-rfbBool unixpw_file_xfer_save = FALSE;
-time_t unixpw_last_try_time = 0;
-rfbClientPtr unixpw_client = NULL;
-
-int keep_unixpw = 0;
-char *keep_unixpw_user = NULL;
-char *keep_unixpw_pass = NULL;
-char *keep_unixpw_opts = NULL;
-
-static unsigned char default6x13FontData[2899]={
-0x00,0x00,0xA8,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0xA8,0x00,0x00, /* 0 */
-0x00,0x00,0x00,0x00,0x20,0x70,0xF8,0x70,0x20,0x00,0x00,0x00,0x00, /* 1 */
-0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8,0x54,0xA8, /* 2 */
-0x00,0x00,0xA0,0xA0,0xE0,0xA0,0xA0,0x38,0x10,0x10,0x10,0x00,0x00, /* 3 */
-0x00,0x00,0xE0,0x80,0xC0,0x80,0xB8,0x20,0x30,0x20,0x20,0x00,0x00, /* 4 */
-0x00,0x00,0x60,0x80,0x80,0x60,0x30,0x28,0x30,0x28,0x28,0x00,0x00, /* 5 */
-0x00,0x00,0x80,0x80,0x80,0xE0,0x38,0x20,0x30,0x20,0x20,0x00,0x00, /* 6 */
-0x00,0x00,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 7 */
-0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0xF8,0x00,0x00,0x00, /* 8 */
-0x00,0x00,0x90,0xD0,0xB0,0x90,0x20,0x20,0x20,0x20,0x38,0x00,0x00, /* 9 */
-0x00,0x00,0xA0,0xA0,0xA0,0x40,0x40,0x38,0x10,0x10,0x10,0x00,0x00, /* 10 */
-0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, /* 11 */
-0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20, /* 12 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20, /* 13 */
-0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x00,0x00,0x00,0x00,0x00,0x00, /* 14 */
-0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0x20,0x20,0x20, /* 15 */
-0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16 */
-0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 17 */
-0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, /* 18 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00, /* 19 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, /* 20 */
-0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x20,0x20,0x20,0x20,0x20,0x20, /* 21 */
-0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x20,0x20,0x20,0x20,0x20,0x20, /* 22 */
-0x20,0x20,0x20,0x20,0x20,0x20,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, /* 23 */
-0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0x20, /* 24 */
-0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* 25 */
-0x00,0x00,0x00,0x18,0x60,0x80,0x60,0x18,0x00,0xF8,0x00,0x00,0x00, /* 26 */
-0x00,0x00,0x00,0xC0,0x30,0x08,0x30,0xC0,0x00,0xF8,0x00,0x00,0x00, /* 27 */
-0x00,0x00,0x00,0x00,0x00,0xF8,0x50,0x50,0x50,0x50,0x50,0x00,0x00, /* 28 */
-0x00,0x00,0x00,0x00,0x00,0x08,0xF8,0x20,0xF8,0x80,0x00,0x00,0x00, /* 29 */
-0x00,0x00,0x30,0x48,0x40,0x40,0xE0,0x40,0x40,0x48,0xB0,0x00,0x00, /* 30 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 31 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32 */
-0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, /* 33 */
-0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 34 */
-0x00,0x00,0x00,0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00,0x00,0x00, /* 35 */
-0x00,0x00,0x20,0x78,0xA0,0xA0,0x70,0x28,0x28,0xF0,0x20,0x00,0x00, /* 36 */
-0x00,0x00,0x48,0xA8,0x50,0x10,0x20,0x40,0x50,0xA8,0x90,0x00,0x00, /* 37 */
-0x00,0x00,0x00,0x40,0xA0,0xA0,0x40,0xA0,0x98,0x90,0x68,0x00,0x00, /* 38 */
-0x00,0x00,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 39 */
-0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x00, /* 40 */
-0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x00, /* 41 */
-0x00,0x00,0x00,0x20,0xA8,0xF8,0x70,0xF8,0xA8,0x20,0x00,0x00,0x00, /* 42 */
-0x00,0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,0x00,0x00, /* 43 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x20,0x40,0x00, /* 44 */
-0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, /* 45 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x70,0x20,0x00, /* 46 */
-0x00,0x00,0x08,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0x80,0x00,0x00, /* 47 */
-0x00,0x00,0x20,0x50,0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00,0x00, /* 48 */
-0x00,0x00,0x20,0x60,0xA0,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00, /* 49 */
-0x00,0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x40,0x80,0xF8,0x00,0x00, /* 50 */
-0x00,0x00,0xF8,0x08,0x10,0x20,0x70,0x08,0x08,0x88,0x70,0x00,0x00, /* 51 */
-0x00,0x00,0x10,0x10,0x30,0x50,0x50,0x90,0xF8,0x10,0x10,0x00,0x00, /* 52 */
-0x00,0x00,0xF8,0x80,0x80,0xB0,0xC8,0x08,0x08,0x88,0x70,0x00,0x00, /* 53 */
-0x00,0x00,0x70,0x88,0x80,0x80,0xF0,0x88,0x88,0x88,0x70,0x00,0x00, /* 54 */
-0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00,0x00, /* 55 */
-0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00, /* 56 */
-0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x08,0x88,0x70,0x00,0x00, /* 57 */
-0x00,0x00,0x00,0x00,0x20,0x70,0x20,0x00,0x00,0x20,0x70,0x20,0x00, /* 58 */
-0x00,0x00,0x00,0x00,0x20,0x70,0x20,0x00,0x00,0x30,0x20,0x40,0x00, /* 59 */
-0x00,0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00,0x00, /* 60 */
-0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, /* 61 */
-0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00,0x00, /* 62 */
-0x00,0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00, /* 63 */
-0x00,0x00,0x70,0x88,0x88,0x98,0xA8,0xA8,0xB0,0x80,0x78,0x00,0x00, /* 64 */
-0x00,0x00,0x20,0x50,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00,0x00, /* 65 */
-0x00,0x00,0xF0,0x48,0x48,0x48,0x70,0x48,0x48,0x48,0xF0,0x00,0x00, /* 66 */
-0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x80,0x80,0x88,0x70,0x00,0x00, /* 67 */
-0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xF0,0x00,0x00, /* 68 */
-0x00,0x00,0xF8,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0xF8,0x00,0x00, /* 69 */
-0x00,0x00,0xF8,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0x80,0x00,0x00, /* 70 */
-0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x98,0x88,0x88,0x70,0x00,0x00, /* 71 */
-0x00,0x00,0x88,0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x88,0x00,0x00, /* 72 */
-0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 73 */
-0x00,0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00,0x00, /* 74 */
-0x00,0x00,0x88,0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x88,0x00,0x00, /* 75 */
-0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00,0x00, /* 76 */
-0x00,0x00,0x88,0x88,0xD8,0xA8,0xA8,0x88,0x88,0x88,0x88,0x00,0x00, /* 77 */
-0x00,0x00,0x88,0xC8,0xC8,0xA8,0xA8,0x98,0x98,0x88,0x88,0x00,0x00, /* 78 */
-0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 79 */
-0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x80,0x80,0x00,0x00, /* 80 */
-0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0xA8,0x70,0x08,0x00, /* 81 */
-0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0xA0,0x90,0x88,0x88,0x00,0x00, /* 82 */
-0x00,0x00,0x70,0x88,0x80,0x80,0x70,0x08,0x08,0x88,0x70,0x00,0x00, /* 83 */
-0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 84 */
-0x00,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 85 */
-0x00,0x00,0x88,0x88,0x88,0x88,0x50,0x50,0x50,0x20,0x20,0x00,0x00, /* 86 */
-0x00,0x00,0x88,0x88,0x88,0x88,0xA8,0xA8,0xA8,0xA8,0x50,0x00,0x00, /* 87 */
-0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x50,0x50,0x88,0x88,0x00,0x00, /* 88 */
-0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 89 */
-0x00,0x00,0xF8,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0xF8,0x00,0x00, /* 90 */
-0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, /* 91 */
-0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x10,0x08,0x08,0x00,0x00, /* 92 */
-0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, /* 93 */
-0x00,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 94 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00, /* 95 */
-0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 96 */
-0x00,0x00,0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 97 */
-0x00,0x00,0x80,0x80,0x80,0xF0,0x88,0x88,0x88,0x88,0xF0,0x00,0x00, /* 98 */
-0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x88,0x70,0x00,0x00, /* 99 */
-0x00,0x00,0x08,0x08,0x08,0x78,0x88,0x88,0x88,0x88,0x78,0x00,0x00, /* 100 */
-0x00,0x00,0x00,0x00,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 101 */
-0x00,0x00,0x30,0x48,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x00,0x00, /* 102 */
-0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x88,0x70, /* 103 */
-0x00,0x00,0x80,0x80,0x80,0xB0,0xC8,0x88,0x88,0x88,0x88,0x00,0x00, /* 104 */
-0x00,0x00,0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 105 */
-0x00,0x00,0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x90,0x90,0x60, /* 106 */
-0x00,0x00,0x80,0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00,0x00, /* 107 */
-0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 108 */
-0x00,0x00,0x00,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x88,0x00,0x00, /* 109 */
-0x00,0x00,0x00,0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x88,0x00,0x00, /* 110 */
-0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 111 */
-0x00,0x00,0x00,0x00,0x00,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x80, /* 112 */
-0x00,0x00,0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x78,0x08,0x08,0x08, /* 113 */
-0x00,0x00,0x00,0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x80,0x00,0x00, /* 114 */
-0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x60,0x10,0x88,0x70,0x00,0x00, /* 115 */
-0x00,0x00,0x00,0x40,0x40,0xF0,0x40,0x40,0x40,0x48,0x30,0x00,0x00, /* 116 */
-0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 117 */
-0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x00,0x00, /* 118 */
-0x00,0x00,0x00,0x00,0x00,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00,0x00, /* 119 */
-0x00,0x00,0x00,0x00,0x00,0x88,0x50,0x20,0x20,0x50,0x88,0x00,0x00, /* 120 */
-0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x08,0x88,0x70, /* 121 */
-0x00,0x00,0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0x80,0xF8,0x00,0x00, /* 122 */
-0x00,0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, /* 123 */
-0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 124 */
-0x00,0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0,0x00, /* 125 */
-0x00,0x00,0x48,0xA8,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 126 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160 */
-0x00,0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, /* 161 */
-0x00,0x00,0x20,0x70,0xA8,0xA0,0xA0,0xA8,0x70,0x20,0x00,0x00,0x00, /* 162 */
-0x00,0x00,0x30,0x48,0x40,0x40,0xE0,0x40,0x40,0x48,0xB0,0x00,0x00, /* 163 */
-0x00,0x00,0x00,0x00,0x88,0x70,0x50,0x50,0x70,0x88,0x00,0x00,0x00, /* 164 */
-0x00,0x00,0x88,0x88,0x50,0x50,0xF8,0x20,0xF8,0x20,0x20,0x00,0x00, /* 165 */
-0x00,0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00,0x00, /* 166 */
-0x00,0x30,0x48,0x40,0x30,0x48,0x48,0x30,0x08,0x48,0x30,0x00,0x00, /* 167 */
-0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168 */
-0x00,0x70,0x88,0xA8,0xD8,0xC8,0xD8,0xA8,0x88,0x70,0x00,0x00,0x00, /* 169 */
-0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00,0xF8,0x00,0x00,0x00,0x00, /* 170 */
-0x00,0x00,0x00,0x00,0x28,0x50,0xA0,0xA0,0x50,0x28,0x00,0x00,0x00, /* 171 */
-0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x08,0x08,0x00,0x00,0x00,0x00, /* 172 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00, /* 173 */
-0x00,0x70,0x88,0xE8,0xD8,0xD8,0xE8,0xD8,0x88,0x70,0x00,0x00,0x00, /* 174 */
-0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 175 */
-0x00,0x00,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176 */
-0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0xF8,0x00,0x00,0x00, /* 177 */
-0x00,0x40,0xA0,0x20,0x40,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 178 */
-0x00,0x40,0xA0,0x40,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 179 */
-0x00,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 180 */
-0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x98,0xE8,0x80,0x80, /* 181 */
-0x00,0x00,0x78,0xE8,0xE8,0xE8,0xE8,0x68,0x28,0x28,0x28,0x00,0x00, /* 182 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 183 */
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20, /* 184 */
-0x00,0x40,0xC0,0x40,0x40,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 185 */
-0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0xF8,0x00,0x00,0x00,0x00, /* 186 */
-0x00,0x00,0x00,0x00,0xA0,0x50,0x28,0x28,0x50,0xA0,0x00,0x00,0x00, /* 187 */
-0x00,0x40,0xC0,0x40,0x40,0xE0,0x08,0x18,0x28,0x38,0x08,0x00,0x00, /* 188 */
-0x00,0x40,0xC0,0x40,0x40,0xE0,0x10,0x28,0x08,0x10,0x38,0x00,0x00, /* 189 */
-0x00,0x40,0xA0,0x40,0x20,0xA0,0x48,0x18,0x28,0x38,0x08,0x00,0x00, /* 190 */
-0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x80,0x88,0x88,0x70,0x00,0x00, /* 191 */
-0x00,0x40,0x20,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 192 */
-0x00,0x10,0x20,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 193 */
-0x00,0x30,0x48,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 194 */
-0x00,0x28,0x50,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 195 */
-0x00,0x50,0x50,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 196 */
-0x00,0x20,0x50,0x20,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0x00, /* 197 */
-0x00,0x00,0x58,0xA0,0xA0,0xA0,0xB0,0xE0,0xA0,0xA0,0xB8,0x00,0x00, /* 198 */
-0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x80,0x80,0x88,0x70,0x20,0x40, /* 199 */
-0x00,0x40,0x20,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 200 */
-0x00,0x10,0x20,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 201 */
-0x00,0x30,0x48,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 202 */
-0x00,0x50,0x50,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,0x00, /* 203 */
-0x00,0x40,0x20,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 204 */
-0x00,0x10,0x20,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 205 */
-0x00,0x30,0x48,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 206 */
-0x00,0x50,0x50,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 207 */
-0x00,0x00,0xF0,0x48,0x48,0x48,0xE8,0x48,0x48,0x48,0xF0,0x00,0x00, /* 208 */
-0x00,0x28,0x50,0x00,0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00,0x00, /* 209 */
-0x00,0x40,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 210 */
-0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 211 */
-0x00,0x30,0x48,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 212 */
-0x00,0x28,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 213 */
-0x00,0x50,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 214 */
-0x00,0x00,0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00, /* 215 */
-0x00,0x08,0x70,0x98,0x98,0xA8,0xA8,0xA8,0xC8,0xC8,0x70,0x80,0x00, /* 216 */
-0x00,0x40,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 217 */
-0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 218 */
-0x00,0x30,0x48,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 219 */
-0x00,0x50,0x50,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 220 */
-0x00,0x10,0x20,0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00,0x00, /* 221 */
-0x00,0x00,0x80,0xF0,0x88,0x88,0x88,0xF0,0x80,0x80,0x80,0x00,0x00, /* 222 */
-0x00,0x00,0x60,0x90,0x90,0xA0,0xA0,0x90,0x88,0x88,0xB0,0x00,0x00, /* 223 */
-0x00,0x00,0x40,0x20,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 224 */
-0x00,0x00,0x10,0x20,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 225 */
-0x00,0x00,0x30,0x48,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 226 */
-0x00,0x00,0x28,0x50,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 227 */
-0x00,0x00,0x50,0x50,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 228 */
-0x00,0x30,0x48,0x30,0x00,0x70,0x08,0x78,0x88,0x98,0x68,0x00,0x00, /* 229 */
-0x00,0x00,0x00,0x00,0x00,0x70,0x28,0x70,0xA0,0xA8,0x50,0x00,0x00, /* 230 */
-0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x88,0x70,0x20,0x40, /* 231 */
-0x00,0x00,0x40,0x20,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 232 */
-0x00,0x00,0x10,0x20,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 233 */
-0x00,0x00,0x30,0x48,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 234 */
-0x00,0x00,0x50,0x50,0x00,0x70,0x88,0xF8,0x80,0x88,0x70,0x00,0x00, /* 235 */
-0x00,0x00,0x40,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 236 */
-0x00,0x00,0x10,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 237 */
-0x00,0x00,0x30,0x48,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 238 */
-0x00,0x00,0x50,0x50,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, /* 239 */
-0x00,0x50,0x20,0x60,0x10,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 240 */
-0x00,0x00,0x28,0x50,0x00,0xB0,0xC8,0x88,0x88,0x88,0x88,0x00,0x00, /* 241 */
-0x00,0x00,0x40,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 242 */
-0x00,0x00,0x10,0x20,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 243 */
-0x00,0x00,0x30,0x48,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 244 */
-0x00,0x00,0x28,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 245 */
-0x00,0x00,0x50,0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00, /* 246 */
-0x00,0x00,0x00,0x20,0x20,0x00,0xF8,0x00,0x20,0x20,0x00,0x00,0x00, /* 247 */
-0x00,0x00,0x00,0x00,0x08,0x70,0x98,0xA8,0xA8,0xC8,0x70,0x80,0x00, /* 248 */
-0x00,0x00,0x40,0x20,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 249 */
-0x00,0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 250 */
-0x00,0x00,0x30,0x48,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 251 */
-0x00,0x00,0x50,0x50,0x00,0x88,0x88,0x88,0x88,0x98,0x68,0x00,0x00, /* 252 */
-0x00,0x00,0x10,0x20,0x00,0x88,0x88,0x88,0x98,0x68,0x08,0x88,0x70, /* 253 */
-0x00,0x00,0x00,0x80,0x80,0xB0,0xC8,0x88,0x88,0xC8,0xB0,0x80,0x80, /* 254 */
-0x00,0x00,0x50,0x50,0x00,0x88,0x88,0x88,0x98,0x68,0x08,0x88,0x70, /* 255 */
-};
-static int default6x13FontMetaData[256*5]={
-0,6,13,0,-2,13,6,13,0,-2,26,6,13,0,-2,39,6,13,0,-2,52,6,13,0,-2,65,6,13,0,-2,78,6,13,0,-2,91,6,13,0,-2,104,6,13,0,-2,117,6,13,0,-2,130,6,13,0,-2,143,6,13,0,-2,156,6,13,0,-2,169,6,13,0,-2,182,6,13,0,-2,195,6,13,0,-2,208,6,13,0,-2,221,6,13,0,-2,234,6,13,0,-2,247,6,13,0,-2,260,6,13,0,-2,273,6,13,0,-2,286,6,13,0,-2,299,6,13,0,-2,312,6,13,0,-2,325,6,13,0,-2,338,6,13,0,-2,351,6,13,0,-2,364,6,13,0,-2,377,6,13,0,-2,390,6,13,0,-2,403,6,13,0,-2,416,6,13,0,-2,429,6,13,0,-2,442,6,13,0,-2,455,6,13,0,-2,468,6,13,0,-2,481,6,13,0,-2,494,6,13,0,-2,507,6,13,0,-2,520,6,13,0,-2,533,6,13,0,-2,546,6,13,0,-2,559,6,13,0,-2,572,6,13,0,-2,585,6,13,0,-2,598,6,13,0,-2,611,6,13,0,-2,624,6,13,0,-2,637,6,13,0,-2,650,6,13,0,-2,663,6,13,0,-2,676,6,13,0,-2,689,6,13,0,-2,702,6,13,0,-2,715,6,13,0,-2,728,6,13,0,-2,741,6,13,0,-2,754,6,13,0,-2,767,6,13,0,-2,780,6,13,0,-2,793,6,13,0,-2,806,6,13,0,-2,819,6,13,0,-2,832,6,13,0,-2,845,6,13,0,-2,858,6,13,0,-2,871,6,13,0,-2,884,6,13,0,-2,897,6,13,0,-2,910,6,13,0,-2,923,6,13,0,-2,936,6,13,0,-2,949,6,13,0,-2,962,6,13,0,-2,975,6,13,0,-2,988,6,13,0,-2,1001,6,13,0,-2,1014,6,13,0,-2,1027,6,13,0,-2,1040,6,13,0,-2,1053,6,13,0,-2,1066,6,13,0,-2,1079,6,13,0,-2,1092,6,13,0,-2,1105,6,13,0,-2,1118,6,13,0,-2,1131,6,13,0,-2,1144,6,13,0,-2,1157,6,13,0,-2,1170,6,13,0,-2,1183,6,13,0,-2,1196,6,13,0,-2,1209,6,13,0,-2,1222,6,13,0,-2,1235,6,13,0,-2,1248,6,13,0,-2,1261,6,13,0,-2,1274,6,13,0,-2,1287,6,13,0,-2,1300,6,13,0,-2,1313,6,13,0,-2,1326,6,13,0,-2,1339,6,13,0,-2,1352,6,13,0,-2,1365,6,13,0,-2,1378,6,13,0,-2,1391,6,13,0,-2,1404,6,13,0,-2,1417,6,13,0,-2,1430,6,13,0,-2,1443,6,13,0,-2,1456,6,13,0,-2,1469,6,13,0,-2,1482,6,13,0,-2,1495,6,13,0,-2,1508,6,13,0,-2,1521,6,13,0,-2,1534,6,13,0,-2,1547,6,13,0,-2,1560,6,13,0,-2,1573,6,13,0,-2,1586,6,13,0,-2,1599,6,13,0,-2,1612,6,13,0,-2,1625,6,13,0,-2,1638,6,13,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1651,6,13,0,-2,1664,6,13,0,-2,1677,6,13,0,-2,1690,6,13,0,-2,1703,6,13,0,-2,1716,6,13,0,-2,1729,6,13,0,-2,1742,6,13,0,-2,1755,6,13,0,-2,1768,6,13,0,-2,1781,6,13,0,-2,1794,6,13,0,-2,1807,6,13,0,-2,1820,6,13,0,-2,1833,6,13,0,-2,1846,6,13,0,-2,1859,6,13,0,-2,1872,6,13,0,-2,1885,6,13,0,-2,1898,6,13,0,-2,1911,6,13,0,-2,1924,6,13,0,-2,1937,6,13,0,-2,1950,6,13,0,-2,1963,6,13,0,-2,1976,6,13,0,-2,1989,6,13,0,-2,2002,6,13,0,-2,2015,6,13,0,-2,2028,6,13,0,-2,2041,6,13,0,-2,2054,6,13,0,-2,2067,6,13,0,-2,2080,6,13,0,-2,2093,6,13,0,-2,2106,6,13,0,-2,2119,6,13,0,-2,2132,6,13,0,-2,2145,6,13,0,-2,2158,6,13,0,-2,2171,6,13,0,-2,2184,6,13,0,-2,2197,6,13,0,-2,2210,6,13,0,-2,2223,6,13,0,-2,2236,6,13,0,-2,2249,6,13,0,-2,2262,6,13,0,-2,2275,6,13,0,-2,2288,6,13,0,-2,2301,6,13,0,-2,2314,6,13,0,-2,2327,6,13,0,-2,2340,6,13,0,-2,2353,6,13,0,-2,2366,6,13,0,-2,2379,6,13,0,-2,2392,6,13,0,-2,2405,6,13,0,-2,2418,6,13,0,-2,2431,6,13,0,-2,2444,6,13,0,-2,2457,6,13,0,-2,2470,6,13,0,-2,2483,6,13,0,-2,2496,6,13,0,-2,2509,6,13,0,-2,2522,6,13,0,-2,2535,6,13,0,-2,2548,6,13,0,-2,2561,6,13,0,-2,2574,6,13,0,-2,2587,6,13,0,-2,2600,6,13,0,-2,2613,6,13,0,-2,2626,6,13,0,-2,2639,6,13,0,-2,2652,6,13,0,-2,2665,6,13,0,-2,2678,6,13,0,-2,2691,6,13,0,-2,2704,6,13,0,-2,2717,6,13,0,-2,2730,6,13,0,-2,2743,6,13,0,-2,2756,6,13,0,-2,2769,6,13,0,-2,2782,6,13,0,-2,2795,6,13,0,-2,2808,6,13,0,-2,2821,6,13,0,-2,2834,6,13,0,-2,2847,6,13,0,-2,2860,6,13,0,-2,2873,6,13,0,-2,2886,6,13,0,-2,};
-static rfbFontData default6x13Font={default6x13FontData, default6x13FontMetaData};
-
-static int in_login = 0, in_passwd = 0, tries = 0;
-static int char_row = 0, char_col = 0;
-static int char_x = 0, char_y = 0, char_w = 8, char_h = 16;
-
-static int db = 0;
-
-int white_pixel(void) {
- static unsigned long black_pix = 0, white_pix = 1, set = 0;
-
- RAWFB_RET(0xffffff)
-
- if (depth <= 8 && ! set) {
- X_LOCK;
- black_pix = BlackPixel(dpy, scr);
- white_pix = WhitePixel(dpy, scr);
- X_UNLOCK;
- set = 1;
- }
- if (depth <= 8) {
- return (int) white_pix;
- } else if (depth < 24) {
- return 0xffff;
- } else {
- return 0xffffff;
- }
-}
-
-int black_pixel(void) {
- static unsigned long black_pix = 0, white_pix = 1, set = 0;
-
- RAWFB_RET(0x000000)
-
- if (depth <= 8 && ! set) {
- X_LOCK;
- black_pix = BlackPixel(dpy, scr);
- white_pix = WhitePixel(dpy, scr);
- X_UNLOCK;
- set = 1;
- }
- if (depth <= 8) {
- return (int) black_pix;
- } else if (depth < 24) {
- return 0x0000;
- } else {
- return 0x000000;
- }
-}
-
-static void unixpw_mark(void) {
- if (scaling) {
- mark_rect_as_modified(0, 0, scaled_x, scaled_y, 1);
- } else {
- mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
- }
-}
-
-static int text_x(void) {
- return char_x + char_col * char_w;
-}
-
-static int text_y(void) {
- return char_y + char_row * char_h;
-}
-
-static rfbScreenInfo fscreen;
-static rfbScreenInfoPtr pscreen;
-
-static int f1_help = 0;
-
-void unixpw_screen(int init) {
- if (unixpw_cmd) {
- ; /* OK */
- } else if (unixpw_nis) {
-#ifndef UNIXPW_CRYPT
- rfbLog("-unixpw_nis is not supported on this OS/machine\n");
- clean_up_exit(1);
-#endif
- } else {
-#ifndef UNIXPW_SU
- rfbLog("-unixpw is not supported on this OS/machine\n");
- clean_up_exit(1);
-#endif
- }
- if (init) {
- int x, y;
- char log[] = "login: ";
-
- zero_fb(0, 0, dpy_x, dpy_y);
-
- mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
-
- x = nfix(dpy_x / 2 - strlen(log) * char_w, dpy_x);
- y = (int) (dpy_y / 3.5);
- if (unixpw_system_greeter) {
- y = (int) (dpy_y / 3);
- }
-
- if (scaling) {
- x = (int) (x * scale_fac_x);
- y = (int) (y * scale_fac_y);
- x = nfix(x, scaled_x);
- y = nfix(y, scaled_y);
- }
-
- if (rotating) {
- fscreen.serverFormat.bitsPerPixel = bpp;
- fscreen.paddedWidthInBytes = rfb_bytes_per_line;
- fscreen.frameBuffer = rfb_fb;
- pscreen = &fscreen;
- } else {
- pscreen = screen;
- }
-
- if (pscreen && pscreen->width >= 640 && pscreen->height >= 480) {
- rfbDrawString(pscreen, &default6x13Font, 8, 2+1*13, "F1-Help:", white_pixel());
- }
- f1_help = 0;
-
- if (unixpw_system_greeter) {
- unixpw_system_greeter_active = 0;
- if (use_dpy && strstr(use_dpy, "xdmcp")) {
- if (getenv("X11VNC_SYSTEM_GREETER1")) {
- char moo[] = "Press 'Escape' for System Greeter";
- rfbDrawString(pscreen, &default8x16Font, x-90, y-30, moo, white_pixel());
- } else {
- char moo1[] = "Press 'Escape' for a New Session via System Greeter, or";
- char moo2[] = "otherwise login here to connect to an Existing Session:";
- rfbDrawString(pscreen, &default6x13Font, x-110, y-38, moo1, white_pixel());
- rfbDrawString(pscreen, &default6x13Font, x-110, y-25, moo2, white_pixel());
- }
- set_env("X11VNC_XDM_ONLY", "0");
- unixpw_system_greeter_active = 1;
- }
- }
-
- rfbDrawString(pscreen, &default8x16Font, x, y, log, white_pixel());
-
- char_x = x;
- char_y = y;
- char_col = strlen(log);
- char_row = 0;
-
- set_warrow_cursor();
- }
-
- unixpw_mark();
-}
-
-
-#ifdef MAXPATHLEN
-static char slave_str[MAXPATHLEN];
-#else
-static char slave_str[4096];
-#endif
-
-static int used_get_pty_ptmx = 0;
-
-char *get_pty_ptmx(int *fd_p) {
- char *slave;
- int fd = -1, i, ndevs = 4, tmp;
- char *devs[] = {
- "/dev/ptmx",
- "/dev/ptm/clone",
- "/dev/ptc",
- "/dev/ptmx_bsd"
- };
-
- *fd_p = -1;
-
-#if LIBVNCSERVER_HAVE_GRANTPT
-
- for (i=0; i < ndevs; i++) {
-#ifdef O_NOCTTY
- fd = open(devs[i], O_RDWR|O_NOCTTY);
-#else
- fd = open(devs[i], O_RDWR);
-#endif
- if (fd >= 0) {
- break;
- }
- }
-
- if (fd < 0) {
- rfbLogPerror("open /dev/ptmx");
- return NULL;
- }
-
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCPKT)
- tmp = 0;
- ioctl(fd, TIOCPKT, (char *) &tmp);
-#endif
-
- if (grantpt(fd) != 0) {
- rfbLogPerror("grantpt");
- close(fd);
- return NULL;
- }
- if (unlockpt(fd) != 0) {
- rfbLogPerror("unlockpt");
- close(fd);
- return NULL;
- }
-
- slave = ptsname(fd);
- if (! slave) {
- rfbLogPerror("ptsname");
- close(fd);
- return NULL;
- }
-
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCFLUSH)
- ioctl(fd, TIOCFLUSH, (char *) 0);
-#endif
-
- if (strlen(slave) > sizeof(slave_str)/2) {
- rfbLog("get_pty_ptmx: slave string length too long.\n");
- close(fd);
- return NULL;
- }
-
- strcpy(slave_str, slave);
- *fd_p = fd;
- return slave_str;
-
-#else
- return NULL;
-
-#endif /* GRANTPT */
-}
-
-
-char *get_pty_loop(int *fd_p) {
- char master_str[16];
- int fd = -1, i;
- char c;
-
- *fd_p = -1;
-
- /* for *BSD loop over /dev/ptyXY */
-
- for (c = 'p'; c <= 'z'; c++) {
- for (i=0; i < 16; i++) {
- sprintf(master_str, "/dev/pty%c%x", c, i);
-#ifdef O_NOCTTY
- fd = open(master_str, O_RDWR|O_NOCTTY);
-#else
- fd = open(master_str, O_RDWR);
-#endif
- if (fd >= 0) {
- break;
- }
- }
- if (fd >= 0) {
- break;
- }
- }
- if (fd < 0) {
- return NULL;
- }
-
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCFLUSH)
- ioctl(fd, TIOCFLUSH, (char *) 0);
-#endif
-
- sprintf(slave_str, "/dev/tty%c%x", c, i);
- *fd_p = fd;
- return slave_str;
-}
-
-char *get_pty(int *fd_p) {
- used_get_pty_ptmx = 0;
- if (getenv("BSD_PTY")) {
- return get_pty_loop(fd_p);
- }
-#ifdef IS_BSD
- return get_pty_loop(fd_p);
-#else
-#if LIBVNCSERVER_HAVE_GRANTPT
- used_get_pty_ptmx = 1;
- return get_pty_ptmx(fd_p);
-#else
- return get_pty_loop(fd_p);
-#endif
-#endif
-}
-
-void try_to_be_nobody(void) {
-
-#if LIBVNCSERVER_HAVE_PWD_H
- struct passwd *pw;
- pw = getpwnam("nobody");
-
- if (pw) {
-#if LIBVNCSERVER_HAVE_SETUID
- setuid(pw->pw_uid);
-#endif
-#if LIBVNCSERVER_HAVE_SETEUID
- seteuid(pw->pw_uid);
-#endif
-#if LIBVNCSERVER_HAVE_SETGID
- setgid(pw->pw_gid);
-#endif
-#if LIBVNCSERVER_HAVE_SETEGID
- setegid(pw->pw_gid);
-#endif
- }
-#endif /* PWD_H */
-}
-
-
-static int slave_fd = -1, alarm_fired = 0;
-
-static void close_alarm (int sig) {
- if (slave_fd >= 0) {
- close(slave_fd);
- }
- alarm_fired = 1;
- if (0) sig = 0; /* compiler warning */
-}
-
-static void kill_child (pid_t pid, int fd) {
- int status;
-
- slave_fd = -1;
- alarm_fired = 0;
- if (fd >= 0) {
- close(fd);
- }
- kill(pid, SIGTERM);
- waitpid(pid, &status, WNOHANG);
-}
-
-static int scheck(char *str, int n, char *name) {
- int j, i;
-
- if (! str) {
- return 0;
- }
- j = 0;
- for (i=0; i<n; i++) {
- if (str[i] == '\0') {
- j = 1;
- break;
- }
- if (!strcmp(name, "password")) {
- if (str[i] == '\n') {
- continue;
- }
- }
- if (str[i] < ' ' || str[i] >= 0x7f) {
- rfbLog("scheck: invalid character in %s.\n", name);
- return 0;
- }
- }
- if (j == 0) {
- rfbLog("scheck: unterminated string in %s.\n", name);
- return 0;
- }
- return 1;
-}
-
-int unixpw_list_match(char *user) {
- if (! unixpw_list || unixpw_list[0] == '\0') {
- return 1;
- } else {
- char *p, *q, *str = strdup(unixpw_list);
- int ok = 0;
- int notmode = 0;
-
- if (str[0] == '!') {
- notmode = 1;
- ok = 1;
- p = strtok(str+1, ",");
- } else {
- p = strtok(str, ",");
- }
- while (p) {
- if ( (q = strchr(p, ':')) != NULL ) {
- *q = '\0'; /* get rid of options. */
- }
- if (!strcmp(user, p)) {
- if (notmode) {
- ok = 0;
- } else {
- ok = 1;
- }
- break;
- }
- if (!notmode && !strcmp("*", p)) {
- ok = 1;
- break;
- }
- p = strtok(NULL, ",");
- }
- free(str);
- if (! ok) {
- rfbLog("unixpw_list_match: fail for '%s'\n", user);
- return 0;
- } else {
- rfbLog("unixpw_list_match: OK for '%s'\n", user);
- return 1;
- }
- }
-}
-
-int crypt_verify(char *user, char *pass) {
-#ifndef UNIXPW_CRYPT
- return 0;
-#else
- struct passwd *pwd;
- char *realpw, *cr;
- int n;
-
- if (! scheck(user, 100, "username")) {
- return 0;
- }
- if (! scheck(pass, 100, "password")) {
- return 0;
- }
- if (! unixpw_list_match(user)) {
- return 0;
- }
-
- pwd = getpwnam(user);
- if (! pwd) {
- return 0;
- }
-
- realpw = pwd->pw_passwd;
- if (realpw == NULL || realpw[0] == '\0') {
- return 0;
- }
-
- if (db > 1) fprintf(stderr, "realpw='%s'\n", realpw);
-
- if (strlen(realpw) < 12) {
- /* e.g. "x", try getspnam(), sometimes root for inetd, etc */
-#if LIBVNCSERVER_HAVE_GETSPNAM
- struct spwd *sp = getspnam(user);
- if (sp != NULL && sp->sp_pwdp != NULL) {
- if (db) fprintf(stderr, "using getspnam()\n");
- realpw = sp->sp_pwdp;
- } else {
- if (db) fprintf(stderr, "skipping getspnam()\n");
- }
-#endif
- }
-
- n = strlen(pass);
- if (pass[n-1] == '\n') {
- pass[n-1] = '\0';
- }
-
- /* XXX remove need for cast */
- cr = (char *) crypt(pass, realpw);
- if (db > 1) {
- fprintf(stderr, "user='%s' pass='%s' realpw='%s' cr='%s'\n",
- user, pass, realpw, cr ? cr : "(null)");
- }
- if (cr == NULL || cr[0] == '\0') {
- return 0;
- }
- if (!strcmp(cr, realpw)) {
- return 1;
- } else {
- return 0;
- }
-#endif /* UNIXPW_CRYPT */
-}
-
-int unixpw_cmd_run(char *user, char *pass, char *cmd, char *line, int *n) {
- int i, len, rc;
- char *str;
- FILE *out;
-
- if (! user || ! pass) {
- return 0;
- }
- if (! unixpw_cmd || *unixpw_cmd == '\0') {
- return 0;
- }
-
- if (! scheck(user, 100, "username")) {
- return 0;
- }
- if (! scheck(pass, 100, "password")) {
- return 0;
- }
- if (! unixpw_list_match(user)) {
- return 0;
- }
- if (cmd == NULL) {
- cmd = "";
- }
-
- len = strlen(user) + 1 + strlen(pass) + 1 + 1;
- str = (char *) malloc(len);
- if (! str) {
- return 0;
- }
- str[0] = '\0';
- strcat(str, user);
- strcat(str, "\n");
- strcat(str, pass);
- if (!strchr(pass, '\n')) {
- strcat(str, "\n");
- }
-
- out = tmpfile();
- if (out == NULL) {
- rfbLog("unixpw_cmd_run tmpfile() failed.\n");
- clean_up_exit(1);
- }
-
- set_env("RFB_UNIXPW_CMD_RUN", cmd);
-
- rc = run_user_command(unixpw_cmd, unixpw_client, "cmd_verify",
- str, strlen(str), out);
-
- set_env("RFB_UNIXPW_CMD_RUN", "");
-
- for (i=0; i < len; i++) {
- str[i] = '\0';
- }
- free(str);
-
- fflush(out);
- rewind(out);
- for (i=0; i < (*n) - 1; i++) {
- int c = fgetc(out);
- if (c == EOF) {
- break;
- }
- line[i] = (char) c;
- }
- fclose(out);
- *n = i;
-
- if (rc == 0) {
- return 1;
- } else {
- return 0;
- }
-}
-
-
-int cmd_verify(char *user, char *pass) {
- int i, len, rc;
- char *str;
-
- if (! user || ! pass) {
- return 0;
- }
- if (! unixpw_cmd || *unixpw_cmd == '\0') {
- return 0;
- }
-
- if (! scheck(user, 100, "username")) {
- return 0;
- }
- if (! scheck(pass, 100, "password")) {
- return 0;
- }
- if (! unixpw_list_match(user)) {
- return 0;
- }
-
- if (unixpw_client) {
- ClientData *cd = (ClientData *) unixpw_client->clientData;
- if (cd) {
- cd->username = strdup(user);
- }
- }
-
- len = strlen(user) + 1 + strlen(pass) + 1 + 1;
- str = (char *) malloc(len);
- if (! str) {
- return 0;
- }
- str[0] = '\0';
- strcat(str, user);
- strcat(str, "\n");
- strcat(str, pass);
- if (!strchr(pass, '\n')) {
- strcat(str, "\n");
- }
-
- rc = run_user_command(unixpw_cmd, unixpw_client, "cmd_verify",
- str, strlen(str), NULL);
-
- for (i=0; i < len; i++) {
- str[i] = '\0';
- }
- free(str);
-
- if (rc == 0) {
- return 1;
- } else {
- return 0;
- }
-}
-
-int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size, int nodisp) {
-#ifndef UNIXPW_SU
- return 0;
-#else
- int i, j, status, fd = -1, sfd, tfd, drain_size = 65536, rsize = 0;
- int slow_pw = 1;
- char *slave, *bin_true = NULL, *bin_su = NULL;
- pid_t pid, pidw;
- struct stat sbuf;
- static int first = 1;
- char instr[64], cbuf[10];
-
- if (first) {
- set_db();
- first = 0;
- }
- rfbLog("su_verify: '%s' for %s.\n", user, cmd ? "command" : "login");
- fflush(stderr);
-
- if (! scheck(user, 100, "username")) {
- return 0;
- }
- if (! scheck(pass, 100, "password")) {
- return 0;
- }
- if (! unixpw_list_match(user)) {
- return 0;
- }
-
- /* unixpw */
- if (no_external_cmds || !cmd_ok("unixpw")) {
- rfbLog("su_verify: cannot run external commands.\n");
- clean_up_exit(1);
- }
-
-#define SU_DEBUG 0
-#if SU_DEBUG
- if (stat("/su", &sbuf) == 0) {
- bin_su = "/su"; /* Freesbie read-only-fs /bin/su not suid! */
-#else
- if (0) {
- ;
-#endif
- } else if (stat("/bin/su", &sbuf) == 0) {
- bin_su = "/bin/su";
- } else if (stat("/usr/bin/su", &sbuf) == 0) {
- bin_su = "/usr/bin/su";
- }
- if (bin_su == NULL) {
- rfbLogPerror("existence /bin/su");
- fflush(stderr);
- return 0;
- }
-
- if (stat("/bin/true", &sbuf) == 0) {
- bin_true = "/bin/true";
- } if (stat("/usr/bin/true", &sbuf) == 0) {
- bin_true = "/usr/bin/true";
- }
- if (cmd != NULL && cmd[0] != '\0') {
- /* this is for ext. cmd su -c "my cmd" after login */
- bin_true = cmd;
- }
- if (bin_true == NULL) {
- rfbLogPerror("existence /bin/true");
- fflush(stderr);
- return 0;
- }
-
- slave = get_pty(&fd);
-
- if (slave == NULL) {
- rfbLogPerror("get_pty failed.");
- fflush(stderr);
- return 0;
- }
-
- if (db) fprintf(stderr, "cmd is: %s\n", cmd);
- if (db) fprintf(stderr, "slave is: %s fd=%d\n", slave, fd);
-
- if (fd < 0) {
- rfbLogPerror("get_pty fd < 0");
- fflush(stderr);
- return 0;
- }
-
- fcntl(fd, F_SETFD, 1);
-
- pid = fork();
- if (pid < 0) {
- rfbLogPerror("fork");
- fflush(stderr);
- close(fd);
- return 0;
- }
-
- if (pid == 0) {
- /* child */
-
- int ttyfd;
- ttyfd = -1; /* compiler warning */
-
-#if LIBVNCSERVER_HAVE_SETSID
- if (setsid() == -1) {
- perror("setsid");
- exit(1);
- }
-#else
- if (setpgrp() == -1) {
- perror("setpgrp");
- exit(1);
- }
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCNOTTY)
- ttyfd = open("/dev/tty", O_RDWR);
- if (ttyfd >= 0) {
- (void) ioctl(ttyfd, TIOCNOTTY, (char *) 0);
- close(ttyfd);
- }
-#endif
-
-#endif /* SETSID */
-
- close(0);
- close(1);
- close(2);
-
- sfd = open(slave, O_RDWR);
- if (sfd < 0) {
- exit(1);
- }
-
-/* streams options fixups, handle cases as they are found: */
-#if defined(__hpux)
-#if LIBVNCSERVER_HAVE_SYS_STROPTS_H
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(I_PUSH)
- if (used_get_pty_ptmx) {
- ioctl(sfd, I_PUSH, "ptem");
- ioctl(sfd, I_PUSH, "ldterm");
- ioctl(sfd, I_PUSH, "ttcompat");
- }
-#endif
-#endif
-#endif
-
- /* n.b. sfd will be 0 since we closed 0. so dup it to 1 and 2 */
- if (fcntl(sfd, F_DUPFD, 1) == -1) {
- exit(1);
- }
- if (fcntl(sfd, F_DUPFD, 2) == -1) {
- exit(1);
- }
-
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCSCTTY)
- ioctl(sfd, TIOCSCTTY, (char *) 0);
-#endif
-
- if (db > 2) {
- char nam[256];
- unlink("/tmp/isatty");
- tfd = open("/tmp/isatty", O_CREAT|O_WRONLY, 0600);
- if (isatty(sfd)) {
- close(tfd);
- sprintf(nam, "stty -a < %s > /tmp/isatty 2>&1",
- slave);
- system(nam);
- } else {
- write(tfd, "NOTTTY\n", 7);
- close(tfd);
- }
- }
-
- chdir("/");
-
- try_to_be_nobody();
-#if LIBVNCSERVER_HAVE_GETUID
- if (getuid() == 0 || geteuid() == 0) {
- exit(1);
- }
-#else
- exit(1);
-#endif
-
- set_env("LC_ALL", "C");
- set_env("LANG", "C");
- set_env("SHELL", "/bin/sh");
- if (nodisp) {
- /* this will cause timeout problems with pam_xauth */
- int k;
- for (k=0; k<3; k++) {
- if (getenv("DISPLAY")) {
- char *s = getenv("DISPLAY");
- if (s) *(s-2) = '_'; /* quite... */
- }
- if (getenv("XAUTHORITY")) {
- char *s = getenv("XAUTHORITY");
- if (s) *(s-2) = '_'; /* quite... */
- }
- }
- }
-
- /* synchronize with parent: */
- write(2, "C", 1);
-
- if (cmd) {
- execlp(bin_su, bin_su, "-", user, "-c",
- bin_true, (char *) NULL);
- } else {
- execlp(bin_su, bin_su, user, "-c",
- bin_true, (char *) NULL);
- }
- exit(1);
- }
- /* parent */
-
- if (db) fprintf(stderr, "pid: %d\n", pid);
-
- /*
- * set an alarm for blocking read() to close the master
- * (presumably terminating the child. SIGTERM too...)
- */
- slave_fd = fd;
- alarm_fired = 0;
- signal(SIGALRM, close_alarm);
- alarm(10);
-
- /* synchronize with child: */
- cbuf[0] = '\0';
- cbuf[1] = '\0';
- for (i=0; i<10; i++) {
- int n;
- cbuf[0] = '\0';
- cbuf[1] = '\0';
- n = read(fd, cbuf, 1);
- if (n < 0 && errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
-
- if (db) {
- fprintf(stderr, "read from child: '%s'\n", cbuf);
- }
-
- alarm(0);
- signal(SIGALRM, SIG_DFL);
- if (alarm_fired) {
- kill_child(pid, fd);
- return 0;
- }
-
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCTRAP)
- {
- int control = 1;
- ioctl(fd, TIOCTRAP, &control);
- }
-#endif
-
- /*
- * In addition to checking exit code below, we watch for the
- * appearance of the string "Password:". BSD does not seem to
- * ask for a password trying to su to yourself. This is the
- * setting in /etc/pam.d/su:
- * auth sufficient pam_self.so
- * it may be commented out without problem.
- */
- for (i=0; i< (int) sizeof(instr); i++) {
- instr[i] = '\0';
- }
-
- alarm_fired = 0;
- signal(SIGALRM, close_alarm);
- alarm(10);
-
- j = 0;
- for (i=0; i < (int) strlen("Password:"); i++) {
- char pstr[] = "password:";
- int n, problem;
-
- cbuf[0] = '\0';
- cbuf[1] = '\0';
-
- n = read(fd, cbuf, 1);
- if (n < 0 && errno == EINTR) {
- i--;
- if (i < -1) i = -1;
- continue;
- }
-
- if (db) {
- fprintf(stderr, "%s", cbuf);
- if (db > 3 && n == 1 && cbuf[0] == ':') {
- char cmd0[32];
- usleep( 100 * 1000 );
- fprintf(stderr, "\n\n");
- sprintf(cmd0, "ps wu %d", pid);
- system(cmd0);
- sprintf(cmd0, "stty -a < %s", slave);
- system(cmd0);
- fprintf(stderr, "\n\n");
- }
- }
-
- if (n == 1) {
- if (isspace((unsigned char) cbuf[0])) {
- i--;
- if (i < -1) i = -1;
- continue;
- }
- if (j >= (int) sizeof(instr)-1) {
- rfbLog("su_verify: problem finding Password:\n");
- fflush(stderr);
- return 0;
- }
- instr[j++] = tolower((unsigned char)cbuf[0]);
- }
-
- problem = 0;
- if (n <= 0) {
- problem = 1;
- } else if (strstr(pstr, instr) != pstr) {
-#ifdef _AIX
- if (UT.sysname && strstr(UT.sysname, "AIX")) {
- /* handle: runge's Password: */
- char *luser = (char *) malloc(strlen(user) + 10);
-
- sprintf(luser, "%s's", user);
- lowercase(luser);
- if (db) fprintf(stderr, "\nAIX luser compare: \"%s\" to \"%s\"\n", luser, instr);
- if (strstr(luser, instr) == luser) {
- if (db) fprintf(stderr, "AIX luser compare: strstr OK.\n");
- if (!strcmp(luser, instr)) {
- if (db) fprintf(stderr, "AIX luser compare: strings equal.\n");
- i = -1;
- j = 0;
- memset(instr, 0, sizeof(instr));
- free(luser);
- continue;
- } else {
- i--;
- if (i < -1) i = -1;
- free(luser);
- continue;
- }
- } else {
- if (db) fprintf(stderr, "AIX luser compare: problem=1\n");
- problem = 1;
- }
- free(luser);
- } else
-#endif
- {
- problem = 1;
- }
- }
-
- if (problem) {
- if (db) {
- fprintf(stderr, "\"Password:\" did not "
- "appear: '%s'" " n=%d\n", instr, n);
- if (db > 3 && n == 1 && j < 32) {
- continue;
- }
- }
- alarm(0);
- signal(SIGALRM, SIG_DFL);
- kill_child(pid, fd);
- return 0;
- }
- }
-
- alarm(0);
- signal(SIGALRM, SIG_DFL);
- if (alarm_fired) {
- kill_child(pid, fd);
- return 0;
- }
-
- if (db) fprintf(stderr, "\nsending passwd: %s\n", db > 2 ? pass : "****");
- usleep(100 * 1000);
- if (slow_pw) {
- unsigned int k;
- for (k = 0; k < strlen(pass); k++) {
- write(fd, pass+k, 1);
- usleep(100 * 1000);
- }
- } else {
- write(fd, pass, strlen(pass));
- }
-
- alarm_fired = 0;
- signal(SIGALRM, close_alarm);
- alarm(15);
-
- /*
- * try to drain the output, hopefully never as much as 4096 (motd?)
- * if we don't drain we may block at waitpid. If we close(fd), the
- * make cause child to die by signal.
- */
- if (rbuf && *rbuf_size > 0) {
- /* asked to return output of command */
- drain_size = *rbuf_size;
- rsize = 0;
- }
- if (db) fprintf(stderr, "\ndraining:\n");
- for (i = 0; i< drain_size; i++) {
- int n;
-
- cbuf[0] = '\0';
- cbuf[1] = '\0';
-
- n = read(fd, cbuf, 1);
- if (n < 0 && errno == EINTR) {
- if (db) fprintf(stderr, "\nEINTR n=%d i=%d --", n, i);
- i--;
- if (i < 0) i = 0;
- continue;
- }
-
- if (db) fprintf(stderr, "\nn=%d i=%d errno=%d %.6f '%s'", n, i, errno, dnowx(), cbuf);
-
- if (n <= 0) {
- break;
- }
- if (rbuf && *rbuf_size > 0) {
- rbuf[rsize++] = cbuf[0];
- }
- }
- if (db && rbuf) fprintf(stderr, "\nrbuf: '%s'\n", rbuf);
-
- if (rbuf && *rbuf_size > 0) {
- char *s = rbuf;
- char *p = strdup(pass);
- int n, o = 0;
-
- n = strlen(p);
- if (p[n-1] == '\n') {
- p[n-1] = '\0';
- }
- /*
- * usually is: Password: mypassword\r\n\r\n<output-of-command>
- * and output will have \n -> \r\n
- */
- if (rbuf[0] == ' ') {
- s++;
- o++;
- }
- if (strstr(s, p) == s) {
- s += strlen(p);
- o += strlen(p);
- for (n = 0; n < 4; n++) {
- if (s[0] == '\r' || s[0] == '\n') {
- s++;
- o++;
- }
- }
- }
- if (o > 0) {
- int i = 0;
- rsize -= o;
- while (o < drain_size) {
- rbuf[i++] = rbuf[o++];
- }
- }
- *rbuf_size = rsize;
- strzero(p);
- free(p);
- }
-
- if (db) fprintf(stderr, "\n--\n");
-
- alarm(0);
- signal(SIGALRM, SIG_DFL);
- if (alarm_fired) {
- kill_child(pid, fd);
- return 0;
- }
-
- slave_fd = -1;
-
- pidw = waitpid(pid, &status, 0);
- close(fd);
-
- if (pid != pidw) {
- return 0;
- }
-
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- return 1; /* this is the only return of success. */
- } else {
- return 0;
- }
-#endif /* UNIXPW_SU */
-}
-
-int unixpw_verify(char *user, char *pass) {
- int ok = 0;
- if (unixpw_cmd) {
- if (cmd_verify(user, pass)) {
- rfbLog("unixpw_verify: cmd_verify login for '%s'"
- " succeeded.\n", user);
- fflush(stderr);
- ok = 1;
- } else {
- rfbLog("unixpw_verify: cmd_verify login for '%s'"
- " failed.\n", user);
- fflush(stderr);
- usleep(3000*1000);
- ok = 0;
- }
- } else if (unixpw_nis) {
- if (crypt_verify(user, pass)) {
- rfbLog("unixpw_verify: crypt_verify login for '%s'"
- " succeeded.\n", user);
- fflush(stderr);
- ok = 1;
- } else {
- rfbLog("unixpw_verify: crypt_verify login for '%s'"
- " failed.\n", user);
- fflush(stderr);
- usleep(3000*1000);
- ok = 0;
- }
- } else {
- if (su_verify(user, pass, NULL, NULL, NULL, 1)) {
- rfbLog("unixpw_verify: su_verify login for '%s'"
- " succeeded.\n", user);
- fflush(stderr);
- ok = 1;
- } else {
- rfbLog("unixpw_verify: su_verify login for '%s'"
- " failed.\n", user);
- fflush(stderr);
- /* use su(1)'s sleep */
- ok = 0;
- }
- }
- return ok;
-}
-
-static int skip_it = 0;
-
-static void progress_skippy(void) {
- int i, msec = get_net_latency(); /* probabaly not set yet.. */
-
- if (msec > 300) {
- msec = 300;
- } else if (msec <= 100) {
- msec = 100;
- }
-
- skip_it = 1;
- for (i = 0; i < 5; i++) {
- if (i == 2) {
- rfbPE(msec * 1000);
- } else {
- rfbPE(-1);
- }
- usleep(10*1000);
- }
- skip_it = 0;
-
- usleep(50*1000);
-}
-
-void check_unixpw_userprefs(void) {
- char *prefs = getenv("FD_USERPREFS");
- if (keep_unixpw_user == NULL || keep_unixpw_opts == NULL) {
- return;
- }
-#if LIBVNCSERVER_HAVE_PWD_H
- if (prefs != NULL && !strchr(prefs, '/')) {
- struct passwd *pw = getpwnam(keep_unixpw_user);
- if (pw != NULL) {
- char *file;
- FILE *f;
-
- file = (char *) malloc(strlen(pw->pw_dir) + 1 + strlen(prefs) + 1);
- sprintf(file, "%s/%s", pw->pw_dir, prefs);
-
- f = fopen(file, "r");
- if (f) {
- char *t, *q, buf[1024];
- memset(buf, 0, sizeof(buf));
-
- fgets(buf, 1024, f);
- fclose(f);
-
- q = strchr(buf, '\n');
- if (q) *q = '\0';
- q = strchr(buf, '\r');
- if (q) *q = '\0';
-
- rfbLog("read user prefs %s: %s\n", file, buf);
-
- if (buf[0] == '#') buf[0] = '\0';
-
- t = (char *) malloc(strlen(keep_unixpw_opts) + 1 + strlen(buf) + 1);
- sprintf(t, "%s,%s", keep_unixpw_opts, buf);
- free(keep_unixpw_opts);
- keep_unixpw_opts = t;
- } else {
- rfbLog("could not read user prefs %s\n", file);
- rfbLogPerror("fopen");
- }
- free(file);
- }
- }
-#endif
-}
-
-
-void unixpw_verify_screen(char *user, char *pass) {
- int x, y;
- char li[] = "Login incorrect";
- char ls[] = "Login succeeded";
- char log[] = "login: ";
- char *colon = NULL;
- ClientData *cd = NULL;
- int ok;
-
-if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "********");
- rfbLog("unixpw_verify: '%s'\n", user ? user : "(null)");
-
- if (user) {
- colon = strchr(user, ':');
- }
- if (colon) {
- *colon = '\0';
- rfbLog("unixpw_verify: colon: '%s'\n", user);
- }
- fflush(stderr);
- if (unixpw_client) {
- cd = (ClientData *) unixpw_client->clientData;
- if (cd) {
- char *str = (char *)malloc(strlen("UNIX:") +
- strlen(user) + 1);
- sprintf(str, "UNIX:%s", user);
- if (cd->username) {
- free(cd->username);
- }
- cd->username = str;
- }
- }
-
- ok = unixpw_verify(user, pass);
-
- if (ok) {
- char_row++;
- char_col = 0;
-
- x = text_x();
- y = text_y();
- rfbDrawString(pscreen, &default8x16Font, x, y, ls, white_pixel());
- unixpw_mark();
-
- progress_skippy();
-
- unixpw_accept(user);
-
- if (keep_unixpw) {
- keep_unixpw_user = strdup(user);
- keep_unixpw_pass = strdup(pass);
- if (colon) {
- keep_unixpw_opts = strdup(colon+1);
- } else {
- keep_unixpw_opts = strdup("");
- }
- check_unixpw_userprefs();
- }
-
- if (colon) *colon = ':';
-
- return;
- }
- if (colon) *colon = ':';
-
- if (tries < 2) {
- char_row++;
- char_col = 0;
-
- x = text_x();
- y = text_y();
- rfbDrawString(pscreen, &default8x16Font, x, y, li, white_pixel());
-
- char_row += 2;
-
- x = text_x();
- y = text_y();
- rfbDrawString(pscreen, &default8x16Font, x, y, log, white_pixel());
-
- char_col = strlen(log);
-
- unixpw_mark();
-
- unixpw_last_try_time = time(NULL);
- unixpw_keystroke(0, 0, 2);
- tries++;
- } else {
- unixpw_deny();
- }
-}
-
-static void set_db(void) {
- if (getenv("DEBUG_UNIXPW")) {
- db = atoi(getenv("DEBUG_UNIXPW"));
- rfbLog("DEBUG_UNIXPW: %d\n", db);
- }
-}
-
-void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
- int x, y, i, rc, nmax = 100;
- static char user_r[100], user[100], pass[100];
- static int u_cnt = 0, p_cnt = 0, t_cnt = 0, first = 1;
- static int echo = 1;
- char keystr[100];
- char *str;
-
- if (skip_it) {
- return;
- }
-
- if (first) {
- set_db();
- first = 0;
- for (i=0; i < nmax; i++) {
- user_r[i] = '\0';
- user[i] = '\0';
- pass[i] = '\0';
- }
- }
-
- if (init) {
- in_login = 1;
- in_passwd = 0;
- unixpw_denied = 0;
- echo = 1;
- if (init == 1) {
- tries = 0;
- }
-
- u_cnt = 0;
- p_cnt = 0;
- t_cnt = 0;
- for (i=0; i<nmax; i++) {
- user[i] = '\0';
- pass[i] = '\0';
- }
- if (keep_unixpw_user) {
- free(keep_unixpw_user);
- keep_unixpw_user = NULL;
- }
- if (keep_unixpw_pass) {
- strzero(keep_unixpw_pass);
- free(keep_unixpw_pass);
- keep_unixpw_pass = NULL;
- }
- if (keep_unixpw_opts) {
- strzero(keep_unixpw_opts);
- free(keep_unixpw_opts);
- keep_unixpw_opts = NULL;
- }
-
- return;
- }
-
- if (unixpw_denied) {
- rfbLog("unixpw_keystroke: unixpw_denied state: 0x%x\n", (int) keysym);
- return;
- }
- if (keysym <= 0) {
- rfbLog("unixpw_keystroke: bad keysym1: 0x%x\n", (int) keysym);
- return;
- }
-
- /* rfbKeySym = uint32_t */
- /* KeySym = XID = CARD32 = (unsigned long or unsigned int on LONG64) */
- X_LOCK;
- str = XKeysymToString(keysym);
- X_UNLOCK;
- if (str == NULL) {
- rfbLog("unixpw_keystroke: bad keysym2: 0x%x\n", (int) keysym);
- return;
- }
-
- rc = snprintf(keystr, 100, "%s", str);
- if (rc < 1 || rc > 90) {
- rfbLog("unixpw_keystroke: bad keysym3: 0x%x\n", (int) keysym);
- return;
- }
-
- if (db > 2) {
- fprintf(stderr, "%s / %s 0x%x %s\n", in_login ? "login":"pass ",
- down ? "down":"up ", keysym, keystr);
- }
-
- if (keysym == XK_Return || keysym == XK_Linefeed || keysym == XK_Tab) {
- /* let "up" pass down below for Return case */
- if (down) {
- return;
- }
- } else if (! down) {
- return;
- }
- if (keysym == XK_F1) {
- char h1[] = "F1-Help: For 'login:' type in the username and press Enter, then for 'Password:' enter the password.";
- char hf[] = " Once logged in, username's X session will be searched for and if found then attached to.";
- char hc[] = " Once logged in, username's X session is sought and attached to, otherwise a new session is created.";
- char hx[] = " Once logged in, username's X session is sought and attached to, otherwise a login greeter is presented.";
- char h2[] = " Specify options after a ':' like this: username:opt,opt=val,... Where an opt may be any of:";
- char h3[] = " scale=... (n/m); scale_cursor=... (sc=); solid (so); id=; repeat; clear_mods (cm); clear_keys (ck);";
- char h4[] = " clear_all (ca); speeds=... (sp=); readtimeout=... (rd=) rotate=... (ro=); noncache (nc) (nc=n);";
- char h5[] = " geom=WxHxD (ge=); nodisplay=... (nd=); viewonly (vo); tag=...; gnome kde twm fvwm mwm dtwm wmaker";
- char h6[] = " xfce lxde enlightenment Xsession failsafe. Examples: fred:3/4,so,cm wilma:geom=1024x768x16,kde";
- int ch = 13, p;
- if (!pscreen || pscreen->width < 640 || pscreen->height < 480) {
- return;
- }
- if (f1_help) {
- p = black_pixel();
- f1_help = 0;
- } else {
- p = white_pixel();
- f1_help = 1;
- unixpw_last_try_time = time(NULL) + 45;
- }
- rfbDrawString(pscreen, &default6x13Font, 8, 2+1*ch, h1, p);
- if (use_dpy == NULL) {
- ;
- } else if (strstr(use_dpy, "cmd=FINDDISPLAY")) {
- rfbDrawString(pscreen, &default6x13Font, 8, 2+2*ch, hf, p);
- } else if (strstr(use_dpy, "cmd=FINDCREATEDISPLAY")) {
- if (strstr(use_dpy, "xdmcp")) {
- rfbDrawString(pscreen, &default6x13Font, 8, 2+2*ch, hx, p);
- } else {
- rfbDrawString(pscreen, &default6x13Font, 8, 2+2*ch, hc, p);
- }
- }
- rfbDrawString(pscreen, &default6x13Font, 8, 2+3*ch, h2, p);
- rfbDrawString(pscreen, &default6x13Font, 8, 2+4*ch, h3, p);
- rfbDrawString(pscreen, &default6x13Font, 8, 2+5*ch, h4, p);
- rfbDrawString(pscreen, &default6x13Font, 8, 2+6*ch, h5, p);
- rfbDrawString(pscreen, &default6x13Font, 8, 2+7*ch, h6, p);
- if (!f1_help) {
- rfbDrawString(pscreen, &default6x13Font, 8, 2+1*ch, "F1-Help:", white_pixel());
- }
- unixpw_mark();
- return;
- }
- if (unixpw_system_greeter_active && keysym == XK_Escape) {
- char *u = get_user_name();
- if (keep_unixpw) {
- char *colon = strchr(user, ':');
- keep_unixpw_user = strdup(u);
- keep_unixpw_pass = strdup("");
- if (colon) {
- keep_unixpw_opts = strdup(colon+1);
- } else {
- keep_unixpw_opts = strdup("");
- }
- check_unixpw_userprefs();
- }
- unixpw_system_greeter_active = 2;
- set_env("X11VNC_XDM_ONLY", "1");
- rfbLog("unixpw_system_greeter: VNC client pressed 'Escape'. Allowing\n");
- rfbLog("unixpw_system_greeter: a *FREE* (no password) connection to\n");
- rfbLog("unixpw_system_greeter: the system XDM/GDM/KDM login greeter.\n");
- if (1) {
- char msg[] = " Please wait... ";
- rfbDrawString(pscreen, &default8x16Font,
- text_x(), text_y(), msg, white_pixel());
- unixpw_mark();
-
- progress_skippy();
- }
- unixpw_accept(u);
- free(u);
- return;
- }
-
- if (in_login && keysym == XK_Escape && u_cnt == 0) {
- echo = 0;
- rfbLog("unixpw_keystroke: echo off.\n");
- return;
- }
-
- t_cnt++;
-
- if (in_login) {
- if (keysym == XK_BackSpace || keysym == XK_Delete) {
- if (u_cnt > 0) {
- user[u_cnt-1] = '\0';
- u_cnt--;
-
- x = text_x();
- y = text_y();
- if (scaling) {
- int x2 = x / scale_fac_x;
- int y2 = y / scale_fac_y;
- int w2 = char_w / scale_fac_x;
- int h2 = char_h / scale_fac_y;
-
- x2 = nfix(x2, dpy_x);
- y2 = nfix(y2, dpy_y);
-
- zero_fb(x2 - w2, y2 - h2, x2, y2);
- mark_rect_as_modified(x2 - w2,
- y2 - h2, x2, y2, 0);
- } else {
- zero_fb(x - char_w, y - char_h, x, y);
- mark_rect_as_modified(x - char_w,
- y - char_h, x, y, 0);
- }
- char_col--;
- }
-
- return;
- }
-
- if (keysym == XK_Return || keysym == XK_Linefeed || keysym == XK_Tab) {
- char pw[] = "Password: ";
-
- if (down) {
- /*
- * require Up so the Return Up is not processed
- * by the normal session after login.
- * (actually we already returned above)
- */
- return;
- }
-
- if (t_cnt == 1) {
- /* accidental initial return, e.g. from xterm */
- return;
- }
-
- in_login = 0;
- in_passwd = 1;
-
- char_row++;
- char_col = 0;
-
- x = text_x();
- y = text_y();
- rfbDrawString(pscreen, &default8x16Font, x, y, pw,
- white_pixel());
-
- char_col = strlen(pw);
- unixpw_mark();
- return;
- }
-
- if (u_cnt == 0 && keysym == XK_Up) {
- /*
- * Allow user to hit Up arrow at beginning to
- * regain their username plus any options.
- */
- int i;
- for (i=0; i < nmax; i++) {
- user[i] = '\0';
- }
- for (i=0; i < nmax; i++) {
- char str[10];
- user[u_cnt++] = user_r[i];
- if (user_r[i] == '\0') {
- break;
- }
- str[0] = (char) user_r[i];
- str[1] = '\0';
-
- x = text_x();
- y = text_y();
- if (echo) {
- rfbDrawString(pscreen, &default8x16Font, x, y,
- str, white_pixel());
- }
- mark_rect_as_modified(x, y-char_h, x+char_w,
- y, scaling);
- char_col++;
- usleep(10*1000);
- }
- return;
- }
-
- if (keysym < ' ' || keysym >= 0x7f) {
- /* require normal keyboard characters for username */
- rfbLog("unixpw_keystroke: bad keysym4: 0x%x\n", (int) keysym);
- return;
- }
-
- if (u_cnt >= nmax - 1) {
- /* user[u_cnt=99] will be '\0' */
- rfbLog("unixpw_deny: username too long: %d\n", u_cnt);
- for (i=0; i<nmax; i++) {
- user[i] = '\0';
- pass[i] = '\0';
- }
- unixpw_deny();
- return;
- }
-
-#if 0
- user[u_cnt++] = keystr[0];
-#else
- user[u_cnt++] = (char) keysym;
- for (i=0; i < nmax; i++) {
- /* keep a full copy of username */
- user_r[i] = user[i];
- }
- keystr[0] = (char) keysym;
-#endif
- keystr[1] = '\0';
-
- x = text_x();
- y = text_y();
-
-if (db && db <= 2) fprintf(stderr, "u_cnt: %d %d/%d ks: 0x%x '%s'\n", u_cnt, x, y, keysym, keystr);
-
- if (echo ) {
- rfbDrawString(pscreen, &default8x16Font, x, y, keystr, white_pixel());
- }
-
- mark_rect_as_modified(x, y-char_h, x+char_w, y, scaling);
- char_col++;
-
- return;
-
- } else if (in_passwd) {
- if (keysym == XK_BackSpace || keysym == XK_Delete) {
- if (p_cnt > 0) {
- pass[p_cnt-1] = '\0';
- p_cnt--;
- }
- return;
- }
- if (keysym == XK_Return || keysym == XK_Linefeed) {
- if (down) {
- /*
- * require Up so the Return Up is not processed
- * by the normal session after login.
- * (actually we already returned above)
- */
- return;
- }
-
- if (1) {
- char msg[] = " Please wait... ";
- rfbDrawString(pscreen, &default8x16Font,
- text_x(), text_y(), msg, white_pixel());
- unixpw_mark();
-
- progress_skippy();
- }
-
- in_login = 0;
- in_passwd = 0;
-
- pass[p_cnt++] = '\n';
- unixpw_verify_screen(user, pass);
- for (i=0; i<nmax; i++) {
- user[i] = '\0';
- pass[i] = '\0';
- }
- return;
- }
-
- if (keysym < ' ' || keysym >= 0x7f) {
- /* require normal keyboard characters for password */
- return;
- }
-
- if (p_cnt >= nmax - 2) {
- /* pass[u_cnt=98] will be '\n' */
- /* pass[u_cnt=99] will be '\0' */
- rfbLog("unixpw_deny: password too long: %d\n", p_cnt);
- for (i=0; i<nmax; i++) {
- user[i] = '\0';
- pass[i] = '\0';
- }
- unixpw_deny();
- return;
- }
-
- pass[p_cnt++] = (char) keysym;
-
- return;
-
- } else {
- /* should not happen... anyway clean up a bit. */
- u_cnt = 0;
- p_cnt = 0;
- for (i=0; i<nmax; i++) {
- user_r[i] = '\0';
- user[i] = '\0';
- pass[i] = '\0';
- }
-
- return;
- }
-}
-
-static void apply_opts (char *user) {
- char *p, *q, *str, *opts = NULL, *opts_star = NULL;
- rfbClientPtr cl;
- ClientData *cd;
- int i, notmode = 0;
-
- if (! unixpw_client) {
- rfbLog("apply_opts: unixpw_client is NULL\n");
- clean_up_exit(1);
- }
- cd = (ClientData *) unixpw_client->clientData;
- cl = unixpw_client;
-
- if (! cd) {
- rfbLog("apply_opts: no ClientData\n");
- }
-
- if (user && cd) {
- if (cd->unixname) {
- free(cd->unixname);
- }
- cd->unixname = strdup(user);
- rfbLog("apply_opts: set unixname to: %s\n", cd->unixname);
- }
-
- if (! unixpw_list) {
- return;
- }
- str = strdup(unixpw_list);
-
- /* apply any per-user options. */
- if (str[0] == '!') {
- p = strtok(str+1, ",");
- notmode = 1;
- } else {
- p = strtok(str, ",");
- }
- while (p) {
- if ( (q = strchr(p, ':')) != NULL ) {
- *q = '\0'; /* get rid of options. */
- } else {
- p = strtok(NULL, ",");
- continue;
- }
- if (user && !strcmp(user, p)) {
- /* will not happen in notmode */
- opts = strdup(q+1);
- }
- if (!strcmp("*", p)) {
- opts_star = strdup(q+1);
- }
- p = strtok(NULL, ",");
- }
- free(str);
-
- for (i=0; i < 2; i++) {
- char *s = (i == 0) ? opts_star : opts;
- if (s == NULL) {
- continue;
- }
- p = strtok(s, "+");
- while (p) {
- if (!strcmp(p, "viewonly")) {
- cl->viewOnly = TRUE;
- if (cd) {
- strncpy(cd->input, "-", CILEN);
- }
- } else if (!strcmp(p, "fullaccess")) {
- cl->viewOnly = FALSE;
- if (cd) {
- strncpy(cd->input, "-", CILEN);
- }
- } else if ((q = strstr(p, "input=")) == p) {
- q += strlen("input=");
- if (cd) {
- strncpy(cd->input, q, CILEN);
- }
- } else if (!strcmp(p, "deny")) {
- cl->viewOnly = TRUE;
- unixpw_deny();
- break;
- }
- p = strtok(NULL, "+");
- }
- free(s);
- }
-}
-
-void unixpw_accept(char *user) {
- apply_opts(user);
-
- if (!use_stunnel) {
- ssl_helper_pid(0, -2); /* waitall */
- }
-
- if (accept_cmd && strstr(accept_cmd, "popup") == accept_cmd) {
- if (use_dpy && strstr(use_dpy, "WAIT:") == use_dpy &&
- dpy == NULL) {
- /* handled in main() */
- unixpw_client->onHold = TRUE;
- } else if (! accept_client(unixpw_client)) {
- unixpw_deny();
- return;
- }
- }
-
- if (started_as_root == 1 && users_list
- && strstr(users_list, "unixpw=") == users_list) {
- if (getuid() && geteuid()) {
- rfbLog("unixpw_accept: unixpw= but not root\n");
- started_as_root = 2;
- } else {
- char *u = (char *)malloc(strlen(user)+1);
-
- u[0] = '\0';
- if (!strcmp(users_list, "unixpw=")) {
- sprintf(u, "+%s", user);
- } else {
- char *p, *str = strdup(users_list);
- p = strtok(str + strlen("unixpw="), ",");
- while (p) {
- if (!strcmp(p, user)) {
- sprintf(u, "+%s", user);
- break;
- }
- p = strtok(NULL, ",");
- }
- free(str);
- }
-
- if (u[0] == '\0') {
- rfbLog("unixpw_accept skipping switch to user: %s\n", user);
- } else if (switch_user(u, 0)) {
- rfbLog("unixpw_accept switched to user: %s\n", user);
- } else {
- rfbLog("unixpw_accept failed to switch to user: %s\n", user);
- }
- free(u);
- }
- }
-
- if (unixpw_login_viewonly) {
- unixpw_client->viewOnly = TRUE;
- }
- unixpw_in_progress = 0;
- /* mutex */
- screen->permitFileTransfer = unixpw_file_xfer_save;
- if ((tightfilexfer = unixpw_tightvnc_xfer_save)) {
- /* this doesn't work: the current client is never registered! */
-#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
- rfbLog("rfbRegisterTightVNCFileTransferExtension: 1\n");
- rfbRegisterTightVNCFileTransferExtension();
-#endif
- }
- unixpw_client = NULL;
- mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
- if (macosx_console) {
- refresh_screen(1);
- }
-}
-
-void unixpw_deny(void) {
- int x, y, i;
- char pd[] = "Permission denied.";
-
- rfbLog("unixpw_deny: %d, %d\n", unixpw_denied, unixpw_in_progress);
- if (! unixpw_denied) {
- unixpw_denied = 1;
-
- char_row += 2;
- char_col = 0;
- x = char_x + char_col * char_w;
- y = char_y + char_row * char_h;
-
- rfbDrawString(pscreen, &default8x16Font, x, y, pd, white_pixel());
- unixpw_mark();
-
- for (i=0; i<5; i++) {
- rfbPE(-1);
- rfbPE(-1);
- usleep(500 * 1000);
- }
- }
-
- if (unixpw_client) {
- rfbCloseClient(unixpw_client);
- rfbClientConnectionGone(unixpw_client);
- rfbPE(-1);
- }
-
- unixpw_in_progress = 0;
- /* mutex */
- screen->permitFileTransfer = unixpw_file_xfer_save;
- if ((tightfilexfer = unixpw_tightvnc_xfer_save)) {
-#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
- rfbLog("rfbRegisterTightVNCFileTransferExtension: 2\n");
- rfbRegisterTightVNCFileTransferExtension();
-#endif
- }
- unixpw_client = NULL;
- copy_screen();
-}
-
-void unixpw_msg(char *msg, int delay) {
- int x, y, i;
-
- char_row += 2;
- char_col = 0;
- x = char_x + char_col * char_w;
- y = char_y + char_row * char_h;
-
- rfbDrawString(pscreen, &default8x16Font, x, y, msg, white_pixel());
- unixpw_mark();
-
- for (i=0; i<5; i++) {
- rfbPE(-1);
- rfbPE(-1);
- rfbPE(50 * 1000);
- rfbPE(-1);
- usleep(500 * 1000);
- if (i >= delay) {
- break;
- }
- }
-}
diff --git a/x11vnc/unixpw.h b/x11vnc/unixpw.h
deleted file mode 100644
index 7b93d30..0000000
--- a/x11vnc/unixpw.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_UNIXPW_H
-#define _X11VNC_UNIXPW_H
-
-/* -- unixpw.h -- */
-
-extern int white_pixel(void);
-extern void unixpw_screen(int init);
-extern void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
-extern void unixpw_accept(char *user);
-extern void unixpw_deny(void);
-extern void unixpw_msg(char *msg, int delay);
-extern int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size, int nodisp);
-extern int unixpw_cmd_run(char *user, char *pass, char *cmd, char *line, int *n);
-extern int crypt_verify(char *user, char *pass);
-extern int cmd_verify(char *user, char *pass);
-extern int unixpw_verify(char *user, char *pass);
-extern void unixpw_verify_screen(char *user, char *pass);
-
-extern int unixpw_in_progress;
-extern int unixpw_denied;
-extern int unixpw_in_rfbPE;
-extern int unixpw_login_viewonly;
-extern int unixpw_tightvnc_xfer_save;
-extern rfbBool unixpw_file_xfer_save;
-extern time_t unixpw_last_try_time;
-extern rfbClientPtr unixpw_client;
-extern int keep_unixpw;
-extern char *keep_unixpw_user;
-extern char *keep_unixpw_pass;
-extern char *keep_unixpw_opts;
-
-#endif /* _X11VNC_UNIXPW_H */
diff --git a/x11vnc/user.c b/x11vnc/user.c
deleted file mode 100644
index f09fbb9..0000000
--- a/x11vnc/user.c
+++ /dev/null
@@ -1,3155 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- user.c -- */
-
-#include "x11vnc.h"
-#include "solid.h"
-#include "cleanup.h"
-#include "scan.h"
-#include "screen.h"
-#include "unixpw.h"
-#include "sslhelper.h"
-#include "xwrappers.h"
-#include "connections.h"
-#include "inet.h"
-#include "keyboard.h"
-#include "cursor.h"
-#include "remote.h"
-#include "sslhelper.h"
-#include "avahi.h"
-
-void check_switched_user(void);
-void lurk_loop(char *str);
-int switch_user(char *user, int fb_mode);
-int read_passwds(char *passfile);
-void install_passwds(void);
-void check_new_passwds(int force);
-void progress_client(void);
-int wait_for_client(int *argc, char** argv, int http);
-rfbBool custom_passwd_check(rfbClientPtr cl, const char *response, int len);
-char *xdmcp_insert = NULL;
-
-static void switch_user_task_dummy(void);
-static void switch_user_task_solid_bg(void);
-static char *get_login_list(int with_display);
-static char **user_list(char *user_str);
-static void user2uid(char *user, uid_t *uid, gid_t *gid, char **name, char **home);
-static int lurk(char **users);
-static int guess_user_and_switch(char *str, int fb_mode);
-static int try_user_and_display(uid_t uid, gid_t gid, char *dpystr);
-static int switch_user_env(uid_t uid, gid_t gid, char *name, char *home, int fb_mode);
-static void try_to_switch_users(void);
-
-
-/* tasks for after we switch */
-static void switch_user_task_dummy(void) {
- ; /* dummy does nothing */
-}
-static void switch_user_task_solid_bg(void) {
- /* we have switched users, some things to do. */
- if (use_solid_bg && client_count) {
- solid_bg(0);
- }
-}
-
-void check_switched_user(void) {
- static time_t sched_switched_user = 0;
- static int did_solid = 0;
- static int did_dummy = 0;
- int delay = 15;
- time_t now = time(NULL);
-
- if (unixpw_in_progress) return;
-
- if (started_as_root == 1 && users_list) {
- try_to_switch_users();
- if (started_as_root == 2) {
- /*
- * schedule the switch_user_tasks() call
- * 15 secs is for piggy desktops to start up.
- * might not be enough for slow machines...
- */
- sched_switched_user = now;
- did_dummy = 0;
- did_solid = 0;
- /* add other activities */
- }
- }
- if (! sched_switched_user) {
- return;
- }
-
- if (! did_dummy) {
- switch_user_task_dummy();
- did_dummy = 1;
- }
- if (! did_solid) {
- int doit = 0;
- char *ss = solid_str;
- if (now >= sched_switched_user + delay) {
- doit = 1;
- } else if (ss && strstr(ss, "root:") == ss) {
- if (now >= sched_switched_user + 3) {
- doit = 1;
- }
- } else if (strcmp("root", guess_desktop())) {
- usleep(1000 * 1000);
- doit = 1;
- }
- if (doit) {
- switch_user_task_solid_bg();
- did_solid = 1;
- }
- }
-
- if (did_dummy && did_solid) {
- sched_switched_user = 0;
- }
-}
-
-/* utilities for switching users */
-static char *get_login_list(int with_display) {
- char *out;
-#if LIBVNCSERVER_HAVE_UTMPX_H
- int i, cnt, max = 200, ut_namesize = 32;
- int dpymax = 1000, sawdpy[1000];
- struct utmpx *utx;
-
- /* size based on "username:999," * max */
- out = (char *) malloc(max * (ut_namesize+1+3+1) + 1);
- out[0] = '\0';
-
- for (i=0; i<dpymax; i++) {
- sawdpy[i] = 0;
- }
-
- setutxent();
- cnt = 0;
- while (1) {
- char *user, *line, *host, *id;
- char tmp[10];
- int d = -1;
- utx = getutxent();
- if (! utx) {
- break;
- }
- if (utx->ut_type != USER_PROCESS) {
- continue;
- }
- user = lblanks(utx->ut_user);
- if (*user == '\0') {
- continue;
- }
- if (strchr(user, ',')) {
- continue; /* unlikely, but comma is our sep. */
- }
-
- line = lblanks(utx->ut_line);
- host = lblanks(utx->ut_host);
- id = lblanks(utx->ut_id);
-
- if (with_display) {
- if (0 && line[0] != ':' && strcmp(line, "dtlocal")) {
- /* XXX useful? */
- continue;
- }
-
- if (line[0] == ':') {
- if (sscanf(line, ":%d", &d) != 1) {
- d = -1;
- }
- }
- if (d < 0 && host[0] == ':') {
- if (sscanf(host, ":%d", &d) != 1) {
- d = -1;
- }
- }
- if (d < 0 && id[0] == ':') {
- if (sscanf(id, ":%d", &d) != 1) {
- d = -1;
- }
- }
-
- if (d < 0 || d >= dpymax || sawdpy[d]) {
- continue;
- }
- sawdpy[d] = 1;
- sprintf(tmp, ":%d", d);
- } else {
- /* try to eliminate repeats */
- int repeat = 0;
- char *q;
-
- q = out;
- while ((q = strstr(q, user)) != NULL) {
- char *p = q + strlen(user) + strlen(":DPY");
- if (q == out || *(q-1) == ',') {
- /* bounded on left. */
- if (*p == ',' || *p == '\0') {
- /* bounded on right. */
- repeat = 1;
- break;
- }
- }
- q = p;
- }
- if (repeat) {
- continue;
- }
- sprintf(tmp, ":DPY");
- }
-
- if (*out) {
- strcat(out, ",");
- }
- strcat(out, user);
- strcat(out, tmp);
-
- cnt++;
- if (cnt >= max) {
- break;
- }
- }
- endutxent();
-#else
- out = strdup("");
-#endif
- return out;
-}
-
-static char **user_list(char *user_str) {
- int n, i;
- char *p, **list;
-
- p = user_str;
- n = 1;
- while (*p++) {
- if (*p == ',') {
- n++;
- }
- }
- list = (char **) calloc((n+1)*sizeof(char *), 1);
-
- p = strtok(user_str, ",");
- i = 0;
- while (p) {
- list[i++] = strdup(p);
- p = strtok(NULL, ",");
- }
- list[i] = NULL;
- return list;
-}
-
-static void user2uid(char *user, uid_t *uid, gid_t *gid, char **name, char **home) {
- int numerical = 1, gotgroup = 0;
- char *q;
-
- *uid = (uid_t) -1;
- *name = NULL;
- *home = NULL;
-
- q = user;
- while (*q) {
- if (! isdigit((unsigned char) (*q++))) {
- numerical = 0;
- break;
- }
- }
-
- if (user2group != NULL) {
- static int *did = NULL;
- int i;
-
- if (did == NULL) {
- int n = 0;
- i = 0;
- while (user2group[i] != NULL) {
- n++;
- i++;
- }
- did = (int *) malloc((n+1) * sizeof(int));
- i = 0;
- for (i=0; i<n; i++) {
- did[i] = 0;
- }
- }
- i = 0;
- while (user2group[i] != NULL) {
- if (strstr(user2group[i], user) == user2group[i]) {
- char *w = user2group[i] + strlen(user);
- if (*w == '.') {
-#if (SMALL_FOOTPRINT > 2)
- gotgroup = 0;
-#else
- struct group* gr = getgrnam(++w);
- if (! gr) {
- rfbLog("Invalid group: %s\n", w);
- clean_up_exit(1);
- }
- *gid = gr->gr_gid;
- if (! did[i]) {
- rfbLog("user2uid: using group %s (%d) for %s\n",
- w, (int) *gid, user);
- did[i] = 1;
- }
- gotgroup = 1;
-#endif
- }
- }
- i++;
- }
- }
-
- if (numerical) {
- int u = atoi(user);
-
- if (u < 0) {
- return;
- }
- *uid = (uid_t) u;
- }
-
-#if LIBVNCSERVER_HAVE_PWD_H
- if (1) {
- struct passwd *pw;
- if (numerical) {
- pw = getpwuid(*uid);
- } else {
- pw = getpwnam(user);
- }
- if (pw) {
- *uid = pw->pw_uid;
- if (! gotgroup) {
- *gid = pw->pw_gid;
- }
- *name = pw->pw_name; /* n.b. use immediately */
- *home = pw->pw_dir;
- }
- }
-#endif
-}
-
-
-static int lurk(char **users) {
- uid_t uid;
- gid_t gid;
- int success = 0, dmin = -1, dmax = -1;
- char *p, *logins, **u;
- char **list;
- int lind;
-
- if ((u = users) != NULL && *u != NULL && *(*u) == ':') {
- int len;
- char *tmp;
-
- /* extract min and max display numbers */
- tmp = *u;
- if (strchr(tmp, '-')) {
- if (sscanf(tmp, ":%d-%d", &dmin, &dmax) != 2) {
- dmin = -1;
- dmax = -1;
- }
- }
- if (dmin < 0) {
- if (sscanf(tmp, ":%d", &dmin) != 1) {
- dmin = -1;
- dmax = -1;
- } else {
- dmax = dmin;
- }
- }
- if ((dmin < 0 || dmax < 0) || dmin > dmax || dmax > 10000) {
- dmin = -1;
- dmax = -1;
- }
-
- /* get user logins regardless of having a display: */
- logins = get_login_list(0);
-
- /*
- * now we append the list in users (might as well try
- * them) this will probably allow weird ways of starting
- * xservers to work.
- */
- len = strlen(logins);
- u++;
- while (*u != NULL) {
- len += strlen(*u) + strlen(":DPY,");
- u++;
- }
- tmp = (char *) malloc(len+1);
- strcpy(tmp, logins);
-
- /* now concatenate them: */
- u = users+1;
- while (*u != NULL) {
- char *q, chk[100];
- snprintf(chk, 100, "%s:DPY", *u);
- q = strstr(tmp, chk);
- if (q) {
- char *p = q + strlen(chk);
-
- if (q == tmp || *(q-1) == ',') {
- /* bounded on left. */
- if (*p == ',' || *p == '\0') {
- /* bounded on right. */
- u++;
- continue;
- }
- }
- }
-
- if (*tmp) {
- strcat(tmp, ",");
- }
- strcat(tmp, *u);
- strcat(tmp, ":DPY");
- u++;
- }
- free(logins);
- logins = tmp;
-
- } else {
- logins = get_login_list(1);
- }
-
- list = (char **) calloc((strlen(logins)+2)*sizeof(char *), 1);
- lind = 0;
- p = strtok(logins, ",");
- while (p) {
- list[lind++] = strdup(p);
- p = strtok(NULL, ",");
- }
- free(logins);
-
- lind = 0;
- while (list[lind] != NULL) {
- char *user, *name, *home, dpystr[10];
- char *q, *t;
- int ok = 1, dn;
-
- p = list[lind++];
-
- t = strdup(p); /* bob:0 */
- q = strchr(t, ':');
- if (! q) {
- free(t);
- break;
- }
- *q = '\0';
- user = t;
- snprintf(dpystr, 10, ":%s", q+1);
-
- if (users) {
- u = users;
- ok = 0;
- while (*u != NULL) {
- if (*(*u) == ':') {
- u++;
- continue;
- }
- if (!strcmp(user, *u++)) {
- ok = 1;
- break;
- }
- }
- }
-
- user2uid(user, &uid, &gid, &name, &home);
- free(t);
-
- if (! uid || ! gid) {
- ok = 0;
- }
-
- if (! ok) {
- continue;
- }
-
- for (dn = dmin; dn <= dmax; dn++) {
- if (dn >= 0) {
- sprintf(dpystr, ":%d", dn);
- }
- if (try_user_and_display(uid, gid, dpystr)) {
- if (switch_user_env(uid, gid, name, home, 0)) {
- rfbLog("lurk: now user: %s @ %s\n",
- name, dpystr);
- started_as_root = 2;
- success = 1;
- }
- set_env("DISPLAY", dpystr);
- break;
- }
- }
- if (success) {
- break;
- }
- }
-
- lind = 0;
- while (list[lind] != NULL) {
- free(list[lind]);
- lind++;
- }
-
- return success;
-}
-
-void lurk_loop(char *str) {
- char *tstr = NULL, **users = NULL;
-
- if (strstr(str, "lurk=") != str) {
- exit(1);
- }
- rfbLog("lurking for logins using: '%s'\n", str);
- if (strlen(str) > strlen("lurk=")) {
- char *q = strchr(str, '=');
- tstr = strdup(q+1);
- users = user_list(tstr);
- }
-
- while (1) {
- if (lurk(users)) {
- break;
- }
- sleep(3);
- }
- if (tstr) {
- free(tstr);
- }
- if (users) {
- free(users);
- }
-}
-
-static int guess_user_and_switch(char *str, int fb_mode) {
- char *dstr, *d;
- char *p, *tstr = NULL, *allowed = NULL, *logins, **users = NULL;
- int dpy1, ret = 0;
- char **list;
- int lind;
-
- RAWFB_RET(0)
-
- d = DisplayString(dpy);
- /* pick out ":N" */
- dstr = strchr(d, ':');
- if (! dstr) {
- return 0;
- }
- if (sscanf(dstr, ":%d", &dpy1) != 1) {
- return 0;
- }
- if (dpy1 < 0) {
- return 0;
- }
-
- if (strstr(str, "guess=") == str && strlen(str) > strlen("guess=")) {
- allowed = strchr(str, '=');
- allowed++;
-
- tstr = strdup(allowed);
- users = user_list(tstr);
- }
-
- /* loop over the utmpx entries looking for this display */
- logins = get_login_list(1);
-
- list = (char **) calloc((strlen(logins)+2)*sizeof(char *), 1);
- lind = 0;
- p = strtok(logins, ",");
- while (p) {
- list[lind++] = strdup(p);
- p = strtok(NULL, ",");
- }
-
- lind = 0;
- while (list[lind] != NULL) {
- char *user, *q, *t;
- int dpy2, ok = 1;
-
- p = list[lind++];
-
- t = strdup(p);
- q = strchr(t, ':');
- if (! q) {
- free(t);
- break;
- }
- *q = '\0';
- user = t;
- dpy2 = atoi(q+1);
-
- if (users) {
- char **u = users;
- ok = 0;
- while (*u != NULL) {
- if (!strcmp(user, *u++)) {
- ok = 1;
- break;
- }
- }
- }
- if (dpy1 != dpy2) {
- ok = 0;
- }
-
- if (! ok) {
- free(t);
- continue;
- }
-
- if (switch_user(user, fb_mode)) {
- rfbLog("switched to guessed user: %s\n", user);
- free(t);
- ret = 1;
- break;
- }
- }
- if (tstr) {
- free(tstr);
- }
- if (users) {
- free(users);
- }
- if (logins) {
- free(logins);
- }
- return ret;
-}
-
-static int try_user_and_display(uid_t uid, gid_t gid, char *dpystr) {
- /* NO strtoks */
-#if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_PWD_H
- pid_t pid, pidw;
- char *home, *name;
- int st;
- struct passwd *pw;
-
- pw = getpwuid(uid);
- if (pw) {
- name = pw->pw_name;
- home = pw->pw_dir;
- } else {
- return 0;
- }
-
- /*
- * We fork here and try to open the display again as the
- * new user. Unreadable XAUTHORITY could be a problem...
- * This is not really needed since we have DISPLAY open but:
- * 1) is a good indicator this user owns the session and 2)
- * some activities do spawn new X apps, e.g. xmessage(1), etc.
- */
- if ((pid = fork()) > 0) {
- ;
- } else if (pid == -1) {
- fprintf(stderr, "could not fork\n");
- rfbLogPerror("fork");
- return 0;
- } else {
- /* child */
- Display *dpy2 = NULL;
- int rc;
-
- signal(SIGHUP, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
-
- rc = switch_user_env(uid, gid, name, home, 0);
- if (! rc) {
- exit(1);
- }
-
- fclose(stderr);
- dpy2 = XOpenDisplay_wr(dpystr);
- if (dpy2) {
- XCloseDisplay_wr(dpy2);
- exit(0); /* success */
- } else {
- exit(2); /* fail */
- }
- }
-
- /* see what the child says: */
- pidw = waitpid(pid, &st, 0);
- if (pidw == pid && WIFEXITED(st) && WEXITSTATUS(st) == 0) {
- return 1;
- }
-#endif /* LIBVNCSERVER_HAVE_FORK ... */
- return 0;
-}
-
-int switch_user(char *user, int fb_mode) {
- /* NO strtoks */
- int doit = 0;
- uid_t uid = 0;
- gid_t gid = 0;
- char *name, *home;
-
- if (*user == '+') {
- doit = 1;
- user++;
- }
-
- ssl_helper_pid(0, -2); /* waitall */
-
- if (strstr(user, "guess=") == user) {
- return guess_user_and_switch(user, fb_mode);
- }
-
- user2uid(user, &uid, &gid, &name, &home);
-
- if (uid == (uid_t) -1 || uid == 0) {
- return 0;
- }
- if (gid == 0) {
- return 0;
- }
-
- if (! doit && dpy) {
- /* see if this display works: */
- char *dstr = DisplayString(dpy);
- doit = try_user_and_display(uid, gid, dstr);
- }
-
- if (doit) {
- int rc = switch_user_env(uid, gid, name, home, fb_mode);
- if (rc) {
- started_as_root = 2;
- }
- return rc;
- } else {
- return 0;
- }
-}
-
-static int switch_user_env(uid_t uid, gid_t gid, char *name, char *home, int fb_mode) {
- /* NO strtoks */
- char *xauth;
- int reset_fb = 0;
- int grp_ok = 0;
-
-#if !LIBVNCSERVER_HAVE_SETUID
- return 0;
-#else
- /*
- * OK, tricky here, we need to free the shm... otherwise
- * we won't be able to delete it as the other user...
- */
- if (fb_mode == 1 && (using_shm && ! xform24to32)) {
- reset_fb = 1;
- clean_shm(0);
- free_tiles();
- }
-#if LIBVNCSERVER_HAVE_INITGROUPS
-#if LIBVNCSERVER_HAVE_PWD_H
- if (getpwuid(uid) != NULL && getenv("X11VNC_SINGLE_GROUP") == NULL) {
- struct passwd *p = getpwuid(uid);
- /* another possibility is p->pw_gid instead of gid */
- if (setgid(gid) == 0 && initgroups(p->pw_name, gid) == 0) {
- grp_ok = 1;
- } else {
- rfbLogPerror("initgroups");
- }
- endgrent();
- }
-#endif
-#endif
- if (! grp_ok) {
- if (setgid(gid) == 0) {
- grp_ok = 1;
- }
- }
- if (! grp_ok) {
- if (reset_fb) {
- /* 2 means we did clean_shm and free_tiles */
- do_new_fb(2);
- }
- return 0;
- }
-
- if (setuid(uid) != 0) {
- if (reset_fb) {
- /* 2 means we did clean_shm and free_tiles */
- do_new_fb(2);
- }
- return 0;
- }
-#endif
- if (reset_fb) {
- do_new_fb(2);
- }
-
- xauth = getenv("XAUTHORITY");
- if (xauth && access(xauth, R_OK) != 0) {
- *(xauth-2) = '_'; /* yow */
- }
-
- set_env("USER", name);
- set_env("LOGNAME", name);
- set_env("HOME", home);
- return 1;
-}
-
-static void try_to_switch_users(void) {
- static time_t last_try = 0;
- time_t now = time(NULL);
- char *users, *p;
-
- if (getuid() && geteuid()) {
- rfbLog("try_to_switch_users: not root\n");
- started_as_root = 2;
- return;
- }
- if (!last_try) {
- last_try = now;
- } else if (now <= last_try + 2) {
- /* try every 3 secs or so */
- return;
- }
- last_try = now;
-
- users = strdup(users_list);
-
- if (strstr(users, "guess=") == users) {
- if (switch_user(users, 1)) {
- started_as_root = 2;
- }
- free(users);
- return;
- }
-
- p = strtok(users, ",");
- while (p) {
- if (switch_user(p, 1)) {
- started_as_root = 2;
- rfbLog("try_to_switch_users: now %s\n", p);
- break;
- }
- p = strtok(NULL, ",");
- }
- free(users);
-}
-
-int read_passwds(char *passfile) {
- char line[1024];
- char *filename;
- char **old_passwd_list = passwd_list;
- int linecount = 0, i, remove = 0, read_mode = 0, begin_vo = -1;
- struct stat sbuf;
- static int max = -1;
- FILE *in = NULL;
- static time_t last_read = 0;
- static int read_cnt = 0;
- int db_passwd = 0;
-
- if (max < 0) {
- max = 1000;
- if (getenv("X11VNC_MAX_PASSWDS")) {
- max = atoi(getenv("X11VNC_MAX_PASSWDS"));
- }
- }
-
- filename = passfile;
- if (strstr(filename, "rm:") == filename) {
- filename += strlen("rm:");
- remove = 1;
- } else if (strstr(filename, "read:") == filename) {
- filename += strlen("read:");
- read_mode = 1;
- if (stat(filename, &sbuf) == 0) {
- if (sbuf.st_mtime <= last_read) {
- return 1;
- }
- last_read = sbuf.st_mtime;
- }
- } else if (strstr(filename, "cmd:") == filename) {
- int rc;
-
- filename += strlen("cmd:");
- read_mode = 1;
- in = tmpfile();
- if (in == NULL) {
- rfbLog("run_user_command tmpfile() failed: %s\n",
- filename);
- clean_up_exit(1);
- }
- rc = run_user_command(filename, latest_client, "read_passwds",
- NULL, 0, in);
- if (rc != 0) {
- rfbLog("run_user_command command failed: %s\n",
- filename);
- clean_up_exit(1);
- }
- rewind(in);
- } else if (strstr(filename, "custom:") == filename) {
- return 1;
- }
-
- if (in == NULL && stat(filename, &sbuf) == 0) {
- /* (poor...) upper bound to number of lines */
- max = (int) sbuf.st_size;
- last_read = sbuf.st_mtime;
- }
-
- /* create 1 more than max to have it be the ending NULL */
- passwd_list = (char **) malloc( (max+1) * (sizeof(char *)) );
- for (i=0; i<max+1; i++) {
- passwd_list[i] = NULL;
- }
-
- if (in == NULL) {
- in = fopen(filename, "r");
- }
- if (in == NULL) {
- rfbLog("cannot open passwdfile: %s\n", passfile);
- rfbLogPerror("fopen");
- if (remove) {
- unlink(filename);
- }
- clean_up_exit(1);
- }
-
- if (getenv("DEBUG_PASSWDFILE") != NULL) {
- db_passwd = 1;
- }
-
- while (fgets(line, 1024, in) != NULL) {
- char *p;
- int blank = 1;
- int len = strlen(line);
-
- if (db_passwd) {
- fprintf(stderr, "read_passwds: raw line: %s\n", line);
- }
-
- if (len == 0) {
- continue;
- } else if (line[len-1] == '\n') {
- line[len-1] = '\0';
- }
- if (line[0] == '\0') {
- continue;
- }
- if (strstr(line, "__SKIP__") != NULL) {
- continue;
- }
- if (strstr(line, "__COMM__") == line) {
- continue;
- }
- if (!strcmp(line, "__BEGIN_VIEWONLY__")) {
- if (begin_vo < 0) {
- begin_vo = linecount;
- }
- continue;
- }
- if (line[0] == '#') {
- /* commented out, cannot have password beginning with # */
- continue;
- }
- p = line;
- while (*p != '\0') {
- if (! isspace((unsigned char) (*p))) {
- blank = 0;
- break;
- }
- p++;
- }
- if (blank) {
- continue;
- }
-
- passwd_list[linecount++] = strdup(line);
- if (db_passwd) {
- fprintf(stderr, "read_passwds: keepline: %s\n", line);
- fprintf(stderr, "read_passwds: begin_vo: %d\n", begin_vo);
- }
-
- if (linecount >= max) {
- rfbLog("read_passwds: hit max passwd: %d\n", max);
- break;
- }
- }
- fclose(in);
-
- for (i=0; i<1024; i++) {
- line[i] = '\0';
- }
-
- if (remove) {
- unlink(filename);
- }
-
- if (! linecount) {
- rfbLog("cannot read a valid line from passwdfile: %s\n",
- passfile);
- if (read_cnt == 0) {
- clean_up_exit(1);
- } else {
- return 0;
- }
- }
- read_cnt++;
-
- for (i=0; i<linecount; i++) {
- char *q, *p = passwd_list[i];
- if (!strcmp(p, "__EMPTY__")) {
- *p = '\0';
- } else if ((q = strstr(p, "__COMM__")) != NULL) {
- *q = '\0';
- }
- passwd_list[i] = strdup(p);
- if (db_passwd) {
- fprintf(stderr, "read_passwds: trimline: %s\n", p);
- }
- strzero(p);
- }
-
- begin_viewonly = begin_vo;
- if (read_mode && read_cnt > 1) {
- if (viewonly_passwd) {
- free(viewonly_passwd);
- viewonly_passwd = NULL;
- }
- }
-
- if (begin_viewonly < 0 && linecount == 2) {
- /* for compatibility with previous 2-line usage: */
- viewonly_passwd = strdup(passwd_list[1]);
- if (db_passwd) {
- fprintf(stderr, "read_passwds: linecount is 2.\n");
- }
- if (screen) {
- char **apd = (char **) screen->authPasswdData;
- if (apd) {
- if (apd[0] != NULL) {
- strzero(apd[0]);
- }
- apd[0] = strdup(passwd_list[0]);
- }
- }
- begin_viewonly = 1;
- }
-
- if (old_passwd_list != NULL) {
- char *p;
- i = 0;
- while (old_passwd_list[i] != NULL) {
- p = old_passwd_list[i];
- strzero(p);
- free(old_passwd_list[i]);
- i++;
- }
- free(old_passwd_list);
- }
- return 1;
-}
-
-void install_passwds(void) {
- if (viewonly_passwd) {
- /* append the view only passwd after the normal passwd */
- char **passwds_new = (char **) malloc(3*sizeof(char *));
- char **passwds_old = (char **) screen->authPasswdData;
- passwds_new[0] = passwds_old[0];
- passwds_new[1] = viewonly_passwd;
- passwds_new[2] = NULL;
- /* mutex */
- screen->authPasswdData = (void*) passwds_new;
- } else if (passwd_list) {
- int i = 0;
- while(passwd_list[i] != NULL) {
- i++;
- }
- if (begin_viewonly < 0) {
- begin_viewonly = i+1;
- }
- /* mutex */
- screen->authPasswdData = (void*) passwd_list;
- screen->authPasswdFirstViewOnly = begin_viewonly;
- }
-}
-
-void check_new_passwds(int force) {
- static time_t last_check = 0;
- time_t now;
-
- if (! passwdfile) {
- return;
- }
- if (strstr(passwdfile, "read:") != passwdfile) {
- return;
- }
- if (unixpw_in_progress) return;
-
- if (force) {
- last_check = 0;
- }
-
- now = time(NULL);
- if (now > last_check + 1) {
- if (read_passwds(passwdfile)) {
- install_passwds();
- }
- last_check = now;
- }
-}
-
-rfbBool custom_passwd_check(rfbClientPtr cl, const char *response, int len) {
- char *input, *cmd;
- char num[16];
- int j, i, n, rc;
-
- rfbLog("custom_passwd_check: len=%d\n", len);
-
- if (!passwdfile || strstr(passwdfile, "custom:") != passwdfile) {
- return FALSE;
- }
- cmd = passwdfile + strlen("custom:");
-
- sprintf(num, "%d\n", len);
-
- input = (char *) malloc(2 * len + 16 + 1);
-
- input[0] = '\0';
- strcat(input, num);
- n = strlen(num);
-
- j = n;
- for (i=0; i < len; i++) {
- input[j] = cl->authChallenge[i];
- j++;
- }
- for (i=0; i < len; i++) {
- input[j] = response[i];
- j++;
- }
- rc = run_user_command(cmd, cl, "custom_passwd", input, n+2*len, NULL);
- free(input);
- if (rc == 0) {
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-static void handle_one_http_request(void) {
- rfbLog("handle_one_http_request: begin.\n");
- if (inetd || screen->httpPort == 0) {
- int port = find_free_port(5800, 5860);
- if (port) {
- /* mutex */
- screen->httpPort = port;
- } else {
- rfbLog("handle_one_http_request: no http port.\n");
- clean_up_exit(1);
- }
- }
- screen->autoPort = FALSE;
- screen->port = 0;
-
- http_connections(1);
-
- rfbInitServer(screen);
-
- if (!inetd) {
- /* XXX ipv6 */
- int conn = 0;
- while (1) {
- if (0) fprintf(stderr, "%d %d %d %d\n", conn, screen->listenSock, screen->httpSock, screen->httpListenSock);
- usleep(10 * 1000);
- rfbHttpCheckFds(screen);
- if (conn) {
- if (screen->httpSock < 0) {
- break;
- }
- } else {
- if (screen->httpSock >= 0) {
- conn = 1;
- }
- }
- if (!screen->httpDir) {
- break;
- }
- if (screen->httpListenSock < 0) {
- break;
- }
- }
- rfbLog("handle_one_http_request: finished.\n");
- return;
- } else {
- /* inetd case: */
-#if LIBVNCSERVER_HAVE_FORK
- pid_t pid;
- int s_in = screen->inetdSock;
- if (s_in < 0) {
- rfbLog("handle_one_http_request: inetdSock not set up.\n");
- clean_up_exit(1);
- }
- pid = fork();
- if (pid < 0) {
- rfbLog("handle_one_http_request: could not fork.\n");
- clean_up_exit(1);
- } else if (pid > 0) {
- int status;
- pid_t pidw;
- while (1) {
- rfbHttpCheckFds(screen);
- pidw = waitpid(pid, &status, WNOHANG);
- if (pidw == pid && WIFEXITED(status)) {
- break;
- } else if (pidw < 0) {
- break;
- }
- }
- rfbLog("handle_one_http_request: finished.\n");
- return;
- } else {
- int sock = connect_tcp("127.0.0.1", screen->httpPort);
- if (sock < 0) {
- exit(1);
- }
- raw_xfer(sock, s_in, s_in);
- exit(0);
- }
-#else
- rfbLog("handle_one_http_request: fork not supported.\n");
- clean_up_exit(1);
-#endif
- }
-}
-
-void user_supplied_opts(char *opts) {
- char *p, *str;
- char *allow[] = {
- "skip-display", "skip-auth", "skip-shared",
- "scale", "scale_cursor", "sc", "solid", "so", "id",
- "clear_mods", "cm", "clear_keys", "ck", "repeat",
- "clear_all", "ca",
- "speeds", "sp", "readtimeout", "rd",
- "rotate", "ro",
- "geometry", "geom", "ge",
- "noncache", "nc",
- "nodisplay", "nd",
- "viewonly", "vo",
- "tag",
- NULL
- };
-
- if (getenv("X11VNC_NO_UNIXPW_OPTS")) {
- return;
- }
-
- str = strdup(opts);
-
- p = strtok(str, ",");
- while (p) {
- char *q;
- int i, n, m, ok = 0;
-
- i = 0;
- while (allow[i] != NULL) {
- if (strstr(allow[i], "skip-")) {
- i++;
- continue;
- }
- if (strstr(p, allow[i]) == p) {
- ok = 1;
- break;
- }
- i++;
- }
-
- if (! ok && strpbrk(p, "0123456789") == p &&
- sscanf(p, "%d/%d", &n, &m) == 2) {
- if (scale_str) free(scale_str);
- scale_str = strdup(p);
- } else if (ok) {
- if (0 && strstr(p, "display=") == p) {
- if (use_dpy) free(use_dpy);
- use_dpy = strdup(p + strlen("display="));
- } else if (0 && strstr(p, "auth=") == p) {
- if (auth_file) free(auth_file);
- auth_file = strdup(p + strlen("auth="));
- } else if (0 && !strcmp(p, "shared")) {
- shared = 1;
- } else if (strstr(p, "scale=") == p) {
- if (scale_str) free(scale_str);
- scale_str = strdup(p + strlen("scale="));
- } else if (strstr(p, "scale_cursor=") == p ||
- strstr(p, "sc=") == p) {
- if (scale_cursor_str) free(scale_cursor_str);
- q = strchr(p, '=') + 1;
- scale_cursor_str = strdup(q);
- } else if (strstr(p, "rotate=") == p ||
- strstr(p, "ro=") == p) {
- if (rotating_str) free(rotating_str);
- q = strchr(p, '=') + 1;
- rotating_str = strdup(q);
- } else if (!strcmp(p, "solid") || !strcmp(p, "so")) {
- use_solid_bg = 1;
- if (!solid_str) {
- solid_str = strdup(solid_default);
- }
- } else if (!strcmp(p, "viewonly") || !strcmp(p, "vo")) {
- view_only = 1;
- } else if (strstr(p, "solid=") == p ||
- strstr(p, "so=") == p) {
- use_solid_bg = 1;
- if (solid_str) free(solid_str);
- q = strchr(p, '=') + 1;
- if (!strcmp(q, "R")) {
- solid_str = strdup("root:");
- } else {
- solid_str = strdup(q);
- }
- } else if (strstr(p, "id=") == p) {
- unsigned long win;
- q = p + strlen("id=");
- if (strcmp(q, "pick")) {
- if (scan_hexdec(q, &win)) {
- subwin = win;
- }
- }
- } else if (!strcmp(p, "clear_mods") ||
- !strcmp(p, "cm")) {
- clear_mods = 1;
- } else if (!strcmp(p, "clear_keys") ||
- !strcmp(p, "ck")) {
- clear_mods = 2;
- } else if (!strcmp(p, "clear_all") ||
- !strcmp(p, "ca")) {
- clear_mods = 3;
- } else if (!strcmp(p, "noncache") ||
- !strcmp(p, "nc")) {
- ncache = 0;
- ncache0 = 0;
- } else if (strstr(p, "nc=") == p) {
- int n2 = atoi(p + strlen("nc="));
- if (nabs(n2) < nabs(ncache)) {
- if (ncache < 0) {
- ncache = -nabs(n2);
- } else {
- ncache = nabs(n2);
- }
- }
- } else if (!strcmp(p, "repeat")) {
- no_autorepeat = 0;
- } else if (strstr(p, "speeds=") == p ||
- strstr(p, "sp=") == p) {
- if (speeds_str) free(speeds_str);
- q = strchr(p, '=') + 1;
- speeds_str = strdup(q);
- q = speeds_str;
- while (*q != '\0') {
- if (*q == '-') {
- *q = ',';
- }
- q++;
- }
- } else if (strstr(p, "readtimeout=") == p ||
- strstr(p, "rd=") == p) {
- q = strchr(p, '=') + 1;
- rfbMaxClientWait = atoi(q) * 1000;
- }
- } else {
- rfbLog("skipping option: %s\n", p);
- }
- p = strtok(NULL, ",");
- }
- free(str);
-}
-
-static void vnc_redirect_timeout (int sig) {
- write(2, "timeout: no clients connected.\n", 31);
- if (sig) {};
- exit(0);
-}
-
-static void do_chvt(int vt) {
- char chvt[100];
- sprintf(chvt, "chvt %d >/dev/null 2>/dev/null &", vt);
- rfbLog("running: %s\n", chvt);
- system(chvt);
- sleep(2);
-}
-
-static void setup_fake_fb(XImage* fb_image, int w, int h, int b) {
- if (fake_fb) {
- free(fake_fb);
- }
- fake_fb = (char *) calloc(w*h*b/8, 1);
-
- fb_image->data = fake_fb;
- fb_image->format = ZPixmap;
- fb_image->width = w;
- fb_image->height = h;
- fb_image->bits_per_pixel = b;
- fb_image->bytes_per_line = w*b/8;
- fb_image->bitmap_unit = -1;
- if (b >= 24) {
- fb_image->depth = 24;
- fb_image->red_mask = 0xff0000;
- fb_image->green_mask = 0x00ff00;
- fb_image->blue_mask = 0x0000ff;
- } else if (b >= 16) {
- fb_image->depth = 16;
- fb_image->red_mask = 0x003f;
- fb_image->green_mask = 0x07c0;
- fb_image->blue_mask = 0xf800;
- } else if (b >= 2) {
- fb_image->depth = 8;
- fb_image->red_mask = 0x07;
- fb_image->green_mask = 0x38;
- fb_image->blue_mask = 0xc0;
- } else {
- fb_image->depth = 1;
- fb_image->red_mask = 0x1;
- fb_image->green_mask = 0x1;
- fb_image->blue_mask = 0x1;
- }
-
- depth = fb_image->depth;
-
- dpy_x = wdpy_x = w;
- dpy_y = wdpy_y = h;
- off_x = 0;
- off_y = 0;
-}
-
-void do_announce_http(void);
-void do_mention_java_urls(void);
-
-static void setup_service(void) {
- if (remote_direct) {
- return;
- }
- if (!inetd) {
- do_mention_java_urls();
- do_announce_http();
- if (!use_openssl) {
- announce(screen->port, use_openssl, NULL);
- fprintf(stdout, "PORT=%d\n", screen->port);
- } else {
- fprintf(stdout, "PORT=%d\n", screen->port);
- if (stunnel_port) {
- fprintf(stdout, "SSLPORT=%d\n", stunnel_port);
- } else if (use_openssl) {
- fprintf(stdout, "SSLPORT=%d\n", screen->port);
- }
- }
- fflush(stdout);
- } else if (!use_openssl && avahi) {
- char *name = rfb_desktop_name;
- if (!name) {
- name = use_dpy;
- }
- avahi_initialise();
- avahi_advertise(name, this_host(), screen->port);
- }
-}
-
-static void check_waitbg(void) {
- if (getenv("WAITBG")) {
-#if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SETSID
- int p, n;
- if ((p = fork()) > 0) {
- exit(0);
- } else if (p == -1) {
- rfbLogEnable(1);
- fprintf(stderr, "could not fork\n");
- perror("fork");
- clean_up_exit(1);
- }
- if (setsid() == -1) {
- rfbLogEnable(1);
- fprintf(stderr, "setsid failed\n");
- perror("setsid");
- clean_up_exit(1);
- }
- /* adjust our stdio */
- n = open("/dev/null", O_RDONLY);
- dup2(n, 0);
- dup2(n, 1);
- if (! logfile) {
- dup2(n, 2);
- }
- if (n > 2) {
- close(n);
- }
-#else
- clean_up_exit(1);
-#endif
- }
-}
-
-static void setup_client_connect(int *did_client_connect) {
- if (client_connect != NULL) {
- char *remainder = NULL;
- if (inetd) {
- rfbLog("wait_for_client: -connect disallowed in inetd mode: %s\n",
- client_connect);
- } else if (screen && screen->clientHead) {
- rfbLog("wait_for_client: -connect disallowed: client exists: %s\n",
- client_connect);
- } else if (strchr(client_connect, '=')) {
- rfbLog("wait_for_client: invalid -connect string: %s\n",
- client_connect);
- } else {
- char *q = strchr(client_connect, ',');
- if (q) {
- rfbLog("wait_for_client: only using first"
- " connect host in: %s\n", client_connect);
- remainder = strdup(q+1);
- *q = '\0';
- }
- rfbLog("wait_for_client: reverse_connect(%s)\n",
- client_connect);
- reverse_connect(client_connect);
- *did_client_connect = 1;
- }
- free(client_connect);
- if (remainder != NULL) {
- /* reset to host2,host3,... */
- client_connect = remainder;
- } else {
- client_connect = NULL;
- }
- }
-}
-
-static void loop_for_connect(int did_client_connect) {
- int loop = 0;
- time_t start = time(NULL);
-
- if (first_conn_timeout < 0) {
- first_conn_timeout = -first_conn_timeout;
- }
-
- while (1) {
- loop++;
- if (first_conn_timeout && time(NULL) > start + first_conn_timeout) {
- rfbLog("no client connect after %d seconds.\n", first_conn_timeout);
- shut_down = 1;
- }
- if (shut_down) {
- clean_up_exit(0);
- }
- if (loop < 2) {
- if (did_client_connect) {
- goto screen_check;
- }
- if (inetd) {
- goto screen_check;
- }
- if (screen && screen->clientHead) {
- goto screen_check;
- }
- }
- if ((use_openssl || use_stunnel) && !inetd) {
- int enc_none = (enc_str && !strcmp(enc_str, "none"));
- if (!use_stunnel || enc_none) {
- check_openssl();
- check_https();
- }
- /*
- * This is to handle an initial verify cert from viewer,
- * they disconnect right after fetching the cert.
- */
- if (use_threads) {
- usleep(10 * 1000);
- } else {
- rfbPE(-1);
- }
- if (screen && screen->clientHead) {
- int i;
- if (unixpw) {
- if (! unixpw_in_progress && !vencrypt_enable_plain_login) {
- rfbLog("unixpw but no unixpw_in_progress\n");
- clean_up_exit(1);
- }
- if (unixpw_client && unixpw_client->onHold) {
- rfbLog("taking unixpw_client off hold\n");
- unixpw_client->onHold = FALSE;
- }
- }
- for (i=0; i<10; i++) {
- if (shut_down) {
- clean_up_exit(0);
- }
- usleep(20 * 1000);
- if (0) rfbLog("wait_for_client: %d\n", i);
-
- if (! use_threads) {
- if (unixpw) {
- unixpw_in_rfbPE = 1;
- }
- rfbPE(-1);
- if (unixpw) {
- unixpw_in_rfbPE = 0;
- }
- }
-
- if (unixpw && !unixpw_in_progress) {
- /* XXX too soon. */
- goto screen_check;
- }
- if (!screen->clientHead) {
- break;
- }
- }
- }
- } else if (use_openssl) {
- check_openssl();
- }
-
- if (use_threads) {
- usleep(10 * 1000);
- } else {
- rfbPE(-1);
- }
-
- screen_check:
- if (! screen || ! screen->clientHead) {
- usleep(100 * 1000);
- continue;
- }
-
- rfbLog("wait_for_client: got client\n");
- break;
- }
-}
-
-static void do_unixpw_loop(void) {
- if (unixpw) {
- if (! unixpw_in_progress && !vencrypt_enable_plain_login) {
- rfbLog("unixpw but no unixpw_in_progress\n");
- clean_up_exit(1);
- }
- if (unixpw_client && unixpw_client->onHold) {
- rfbLog("taking unixpw_client off hold.\n");
- unixpw_client->onHold = FALSE;
- }
- while (1) {
- if (shut_down) {
- clean_up_exit(0);
- }
- if (! use_threads) {
- unixpw_in_rfbPE = 1;
- rfbPE(-1);
- unixpw_in_rfbPE = 0;
- }
- if (unixpw_in_progress) {
- static double lping = 0.0;
- if (lping < dnow() + 5) {
- mark_rect_as_modified(0, 0, 1, 1, 1);
- lping = dnow();
- }
- if (time(NULL) > unixpw_last_try_time + 45) {
- rfbLog("unixpw_deny: timed out waiting for reply.\n");
- unixpw_deny();
- }
- usleep(20 * 1000);
- continue;
- }
- rfbLog("wait_for_client: unixpw finished.\n");
- break;
- }
- }
-}
-
-static void vnc_redirect_loop(char *vnc_redirect_test, int *vnc_redirect_cnt) {
- if (unixpw) {
- rfbLog("wait_for_client: -unixpw and Xvnc.redirect not allowed\n");
- clean_up_exit(1);
- }
- if (client_connect) {
- rfbLog("wait_for_client: -connect and Xvnc.redirect not allowed\n");
- clean_up_exit(1);
- }
- if (inetd) {
- if (use_openssl) {
- accept_openssl(OPENSSL_INETD, -1);
- }
- } else {
- pid_t pid = 0;
- /* XXX ipv6 */
- if (screen->httpListenSock >= 0) {
-#if LIBVNCSERVER_HAVE_FORK
- if ((pid = fork()) > 0) {
- close(screen->httpListenSock);
- /* mutex */
- screen->httpListenSock = -2;
- usleep(500 * 1000);
- } else {
- close(screen->listenSock);
- screen->listenSock = -1;
- while (1) {
- usleep(10 * 1000);
- rfbHttpCheckFds(screen);
- }
- exit(1);
- }
-#else
- clean_up_exit(1);
-#endif
- }
- if (first_conn_timeout) {
- if (first_conn_timeout < 0) {
- first_conn_timeout = -first_conn_timeout;
- }
- signal(SIGALRM, vnc_redirect_timeout);
- alarm(first_conn_timeout);
- }
- if (use_openssl) {
- int i;
- if (pid == 0) {
- accept_openssl(OPENSSL_VNC, -1);
- } else {
- for (i=0; i < 16; i++) {
- accept_openssl(OPENSSL_VNC, -1);
- rfbLog("iter %d: vnc_redirect_sock: %d\n", i, vnc_redirect_sock);
- if (vnc_redirect_sock >= 0) {
- break;
- }
- }
- }
- } else {
- struct sockaddr_in addr;
-#ifdef __hpux
- int addrlen = sizeof(addr);
-#else
- socklen_t addrlen = sizeof(addr);
-#endif
- if (screen->listenSock < 0) {
- rfbLog("wait_for_client: Xvnc.redirect not listening... sock=%d port=%d\n", screen->listenSock, screen->port);
- clean_up_exit(1);
- }
- vnc_redirect_sock = accept(screen->listenSock, (struct sockaddr *)&addr, &addrlen);
- }
- if (first_conn_timeout) {
- alarm(0);
- }
- if (pid > 0) {
-#if LIBVNCSERVER_HAVE_FORK
- int rc;
- pid_t pidw;
- rfbLog("wait_for_client: kill TERM: %d\n", (int) pid);
- kill(pid, SIGTERM);
- usleep(1000 * 1000); /* 1.0 sec */
- pidw = waitpid(pid, &rc, WNOHANG);
- if (pidw <= 0) {
- usleep(1000 * 1000); /* 1.0 sec */
- pidw = waitpid(pid, &rc, WNOHANG);
- }
-#else
- clean_up_exit(1);
-#endif
- }
- }
- if (vnc_redirect_sock < 0) {
- rfbLog("wait_for_client: vnc_redirect failed.\n");
- clean_up_exit(1);
- }
- if (!inetd && use_openssl) {
- /* check for Fetch Cert closing */
- fd_set rfds;
- struct timeval tv;
- int nfds;
-
- usleep(300*1000);
-
- FD_ZERO(&rfds);
- FD_SET(vnc_redirect_sock, &rfds);
-
- tv.tv_sec = 0;
- tv.tv_usec = 200000;
- nfds = select(vnc_redirect_sock+1, &rfds, NULL, NULL, &tv);
-
- rfbLog("wait_for_client: vnc_redirect nfds: %d\n", nfds);
- if (nfds > 0) {
- int n;
- n = read(vnc_redirect_sock, vnc_redirect_test, 1);
- if (n <= 0) {
- close(vnc_redirect_sock);
- vnc_redirect_sock = -1;
- rfbLog("wait_for_client: waiting for 2nd connection (Fetch Cert?)\n");
- accept_openssl(OPENSSL_VNC, -1);
- if (vnc_redirect_sock < 0) {
- rfbLog("wait_for_client: vnc_redirect failed.\n");
- clean_up_exit(1);
- }
- } else {
- *vnc_redirect_cnt = n;
- }
- }
- }
-}
-
-static void do_vnc_redirect(int created_disp, char *vnc_redirect_host, int vnc_redirect_port,
- int vnc_redirect_cnt, char *vnc_redirect_test) {
- char *q = strrchr(use_dpy, ':');
- int vdpy = -1, sock = -1;
- int s_in, s_out, i;
- if (vnc_redirect == 2) {
- char num[32];
- sprintf(num, ":%d", vnc_redirect_port);
- q = num;
- }
- if (!q) {
- rfbLog("wait_for_client: can't find number in X display: %s\n", use_dpy);
- clean_up_exit(1);
- }
- if (sscanf(q+1, "%d", &vdpy) != 1) {
- rfbLog("wait_for_client: can't find number in X display: %s\n", q);
- clean_up_exit(1);
- }
- if (vdpy == -1 && vnc_redirect != 2) {
- rfbLog("wait_for_client: can't find number in X display: %s\n", q);
- clean_up_exit(1);
- }
- if (vnc_redirect == 2) {
- if (vdpy < 0) {
- vdpy = -vdpy;
- } else if (vdpy < 200) {
- vdpy += 5900;
- }
- } else {
- vdpy += 5900;
- }
- if (created_disp) {
- usleep(1000*1000);
- }
- for (i=0; i < 20; i++) {
- sock = connect_tcp(vnc_redirect_host, vdpy);
- if (sock >= 0) {
- break;
- }
- rfbLog("wait_for_client: ...\n");
- usleep(500*1000);
- }
- if (sock < 0) {
- rfbLog("wait_for_client: could not connect to a VNC Server at %s:%d\n", vnc_redirect_host, vdpy);
- clean_up_exit(1);
- }
- if (inetd) {
- s_in = fileno(stdin);
- s_out = fileno(stdout);
- } else {
- s_in = s_out = vnc_redirect_sock;
- }
- if (vnc_redirect_cnt > 0) {
- write(vnc_redirect_sock, vnc_redirect_test, vnc_redirect_cnt);
- }
- rfbLog("wait_for_client: switching control to VNC Server at %s:%d\n", vnc_redirect_host, vdpy);
- raw_xfer(sock, s_in, s_out);
-}
-
-extern char find_display[];
-extern char create_display[];
-
-char *setup_cmd(char *str, int *vnc_redirect, char **vnc_redirect_host, int *vnc_redirect_port, int db) {
- char *cmd = NULL;
-
- if (no_external_cmds || !cmd_ok("WAIT")) {
- rfbLog("wait_for_client external cmds not allowed:"
- " %s\n", use_dpy);
- clean_up_exit(1);
- }
-
- cmd = str + strlen("cmd=");
- if (!strcmp(cmd, "FINDDISPLAY-print")) {
- fprintf(stdout, "%s", find_display);
- clean_up_exit(0);
- }
- if (!strcmp(cmd, "FINDDISPLAY-run")) {
- char tmp[] = "/tmp/fd.XXXXXX";
- char com[100];
- int fd = mkstemp(tmp);
- if (fd >= 0) {
- int ret;
- write(fd, find_display, strlen(find_display));
- close(fd);
- set_env("FINDDISPLAY_run", "1");
- sprintf(com, "/bin/sh %s -n", tmp);
- ret = system(com);
- if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) {
- if (got_findauth && !getenv("FD_XDM")) {
- if (getuid() == 0 || geteuid() == 0) {
- set_env("FD_XDM", "1");
- system(com);
- }
- }
- }
- }
- unlink(tmp);
- exit(0);
- }
- if (!strcmp(str, "FINDCREATEDISPLAY-print")) {
- fprintf(stdout, "%s", create_display);
- clean_up_exit(0);
- }
- if (db) fprintf(stderr, "cmd: %s\n", cmd);
- if (strstr(str, "FINDCREATEDISPLAY") || strstr(str, "FINDDISPLAY")) {
- if (strstr(str, "Xvnc.redirect") || strstr(str, "X.redirect")) {
- *vnc_redirect = 1;
- }
- }
- if (strstr(cmd, "FINDDISPLAY-vnc_redirect") == cmd) {
- int p;
- char h[256];
- if (strlen(cmd) >= 256) {
- rfbLog("wait_for_client string too long: %s\n", str);
- clean_up_exit(1);
- }
- h[0] = '\0';
- if (sscanf(cmd, "FINDDISPLAY-vnc_redirect=%d", &p) == 1) {
- ;
- } else if (sscanf(cmd, "FINDDISPLAY-vnc_redirect=%s %d", h, &p) == 2) {
- ;
- } else {
- rfbLog("wait_for_client bad string: %s\n", cmd);
- clean_up_exit(1);
- }
- *vnc_redirect_port = p;
- if (strcmp(h, "")) {
- *vnc_redirect_host = strdup(h);
- }
- *vnc_redirect = 2;
- rfbLog("wait_for_client: vnc_redirect: %s:%d\n", *vnc_redirect_host, *vnc_redirect_port);
- }
- return cmd;
-}
-
-static char *build_create_cmd(char *cmd, int *saw_xdmcp, char *usslpeer, char *tmp) {
- char *create_cmd = NULL;
- char *opts = strchr(cmd, '-');
- char st[] = "";
- char fdgeom[128], fdsess[128], fdopts[128], fdextra[256], fdprog[128];
- char fdxsrv[128], fdxdum[128], fdcups[128], fdesd[128];
- char fdnas[128], fdsmb[128], fdtag[128], fdxdmcpif[128];
- char cdout[128];
-
- if (opts) {
- opts++;
- if (strstr(opts, "xdmcp")) {
- *saw_xdmcp = 1;
- }
- } else {
- opts = st;
- }
- sprintf(fdgeom, "NONE");
- fdsess[0] = '\0';
- fdgeom[0] = '\0';
- fdopts[0] = '\0';
- fdextra[0] = '\0';
- fdprog[0] = '\0';
- fdxsrv[0] = '\0';
- fdxdum[0] = '\0';
- fdcups[0] = '\0';
- fdesd[0] = '\0';
- fdnas[0] = '\0';
- fdsmb[0] = '\0';
- fdtag[0] = '\0';
- fdxdmcpif[0] = '\0';
- cdout[0] = '\0';
-
- if (unixpw && keep_unixpw_opts && !getenv("X11VNC_NO_UNIXPW_OPTS")) {
- char *q, *p, *t = strdup(keep_unixpw_opts);
-
- if (strstr(t, "gnome")) {
- sprintf(fdsess, "gnome");
- } else if (strstr(t, "kde")) {
- sprintf(fdsess, "kde");
- } else if (strstr(t, "lxde")) {
- sprintf(fdsess, "lxde");
- } else if (strstr(t, "twm")) {
- sprintf(fdsess, "twm");
- } else if (strstr(t, "fvwm")) {
- sprintf(fdsess, "fvwm");
- } else if (strstr(t, "mwm")) {
- sprintf(fdsess, "mwm");
- } else if (strstr(t, "cde")) {
- sprintf(fdsess, "cde");
- } else if (strstr(t, "dtwm")) {
- sprintf(fdsess, "dtwm");
- } else if (strstr(t, "xterm")) {
- sprintf(fdsess, "xterm");
- } else if (strstr(t, "wmaker")) {
- sprintf(fdsess, "wmaker");
- } else if (strstr(t, "xfce")) {
- sprintf(fdsess, "xfce");
- } else if (strstr(t, "enlightenment")) {
- sprintf(fdsess, "enlightenment");
- } else if (strstr(t, "Xsession")) {
- sprintf(fdsess, "Xsession");
- } else if (strstr(t, "failsafe")) {
- sprintf(fdsess, "failsafe");
- }
-
- q = strstr(t, "ge=");
- if (! q) q = strstr(t, "geom=");
- if (! q) q = strstr(t, "geometry=");
- if (q) {
- int ok = 1;
- q = strstr(q, "=");
- q++;
- p = strstr(q, ",");
- if (p) *p = '\0';
- p = q;
- while (*p) {
- if (*p == 'x') {
- ;
- } else if (isdigit((int) *p)) {
- ;
- } else {
- ok = 0;
- break;
- }
- p++;
- }
- if (ok && strlen(q) < 32) {
- sprintf(fdgeom, "%s", q);
- if (!quiet) {
- rfbLog("set create display geom: %s\n", fdgeom);
- }
- }
- }
- q = strstr(t, "cups=");
- if (q) {
- int p;
- if (sscanf(q, "cups=%d", &p) == 1) {
- sprintf(fdcups, "%d", p);
- }
- }
- q = strstr(t, "esd=");
- if (q) {
- int p;
- if (sscanf(q, "esd=%d", &p) == 1) {
- sprintf(fdesd, "%d", p);
- }
- }
- if (!getenv("FD_TAG")) {
- char *s = NULL;
-
- q = strstr(t, "tag=");
- if (q) s = strchr(q, ',');
- if (s) *s = '\0';
-
- if (q && strlen(q) < 120) {
- char *p;
- int ok = 1;
- q = strchr(q, '=') + 1;
- p = q;
- while (*p != '\0') {
- char c = *p;
- if (*p == '_' || *p == '-') {
- ;
- } else if (!isalnum((int) c)) {
- ok = 0;
- rfbLog("bad tag char: '%c' in '%s'\n", c, q);
- break;
- }
- p++;
- }
- if (ok) {
- sprintf(fdtag, "%s", q);
- }
- }
- if (s) *s = ',';
- }
- free(t);
- }
- if (fdgeom[0] == '\0' && getenv("FD_GEOM")) {
- snprintf(fdgeom, 120, "%s", getenv("FD_GEOM"));
- }
- if (fdsess[0] == '\0' && getenv("FD_SESS")) {
- snprintf(fdsess, 120, "%s", getenv("FD_SESS"));
- }
- if (fdopts[0] == '\0' && getenv("FD_OPTS")) {
- snprintf(fdopts, 120, "%s", getenv("FD_OPTS"));
- }
- if (fdextra[0] == '\0' && getenv("FD_EXTRA")) {
- if (!strchr(getenv("FD_EXTRA"), '\'')) {
- snprintf(fdextra, 250, "%s", getenv("FD_EXTRA"));
- }
- }
- if (fdprog[0] == '\0' && getenv("FD_PROG")) {
- snprintf(fdprog, 120, "%s", getenv("FD_PROG"));
- }
- if (fdxsrv[0] == '\0' && getenv("FD_XSRV")) {
- snprintf(fdxsrv, 120, "%s", getenv("FD_XSRV"));
- }
- if (fdcups[0] == '\0' && getenv("FD_CUPS")) {
- snprintf(fdcups, 120, "%s", getenv("FD_CUPS"));
- }
- if (fdesd[0] == '\0' && getenv("FD_ESD")) {
- snprintf(fdesd, 120, "%s", getenv("FD_ESD"));
- }
- if (fdnas[0] == '\0' && getenv("FD_NAS")) {
- snprintf(fdnas, 120, "%s", getenv("FD_NAS"));
- }
- if (fdsmb[0] == '\0' && getenv("FD_SMB")) {
- snprintf(fdsmb, 120, "%s", getenv("FD_SMB"));
- }
- if (fdtag[0] == '\0' && getenv("FD_TAG")) {
- snprintf(fdtag, 120, "%s", getenv("FD_TAG"));
- }
- if (fdxdmcpif[0] == '\0' && getenv("FD_XDMCP_IF")) {
- snprintf(fdxdmcpif, 120, "%s", getenv("FD_XDMCP_IF"));
- }
- if (fdxdum[0] == '\0' && getenv("FD_XDUMMY_RUN_AS_ROOT")) {
- snprintf(fdxdum, 120, "%s", getenv("FD_XDUMMY_RUN_AS_ROOT"));
- }
- if (getenv("CREATE_DISPLAY_OUTPUT")) {
- snprintf(cdout, 120, "CREATE_DISPLAY_OUTPUT='%s'", getenv("CREATE_DISPLAY_OUTPUT"));
- }
-
- if (strchr(fdgeom, '\'')) fdgeom[0] = '\0';
- if (strchr(fdopts, '\'')) fdopts[0] = '\0';
- if (strchr(fdextra, '\'')) fdextra[0] = '\0';
- if (strchr(fdprog, '\'')) fdprog[0] = '\0';
- if (strchr(fdxsrv, '\'')) fdxsrv[0] = '\0';
- if (strchr(fdcups, '\'')) fdcups[0] = '\0';
- if (strchr(fdesd, '\'')) fdesd[0] = '\0';
- if (strchr(fdnas, '\'')) fdnas[0] = '\0';
- if (strchr(fdsmb, '\'')) fdsmb[0] = '\0';
- if (strchr(fdtag, '\'')) fdtag[0] = '\0';
- if (strchr(fdxdmcpif, '\'')) fdxdmcpif[0] = '\0';
- if (strchr(fdxdum, '\'')) fdxdum[0] = '\0';
- if (strchr(fdsess, '\'')) fdsess[0] = '\0';
- if (strchr(cdout, '\'')) cdout[0] = '\0';
-
- set_env("FD_GEOM", fdgeom);
- set_env("FD_OPTS", fdopts);
- set_env("FD_EXTRA", fdextra);
- set_env("FD_PROG", fdprog);
- set_env("FD_XSRV", fdxsrv);
- set_env("FD_CUPS", fdcups);
- set_env("FD_ESD", fdesd);
- set_env("FD_NAS", fdnas);
- set_env("FD_SMB", fdsmb);
- set_env("FD_TAG", fdtag);
- set_env("FD_XDMCP_IF", fdxdmcpif);
- set_env("FD_XDUMMY_RUN_AS_ROOT", fdxdum);
- set_env("FD_SESS", fdsess);
-
- if (usslpeer || (unixpw && keep_unixpw_user)) {
- char *uu = usslpeer;
- if (!uu) {
- uu = keep_unixpw_user;
- }
- if (strchr(uu, '\'')) {
- uu = "";
- }
- create_cmd = (char *) malloc(strlen(tmp)+1
- + strlen("env USER='' ")
- + strlen("FD_GEOM='' ")
- + strlen("FD_OPTS='' ")
- + strlen("FD_EXTRA='' ")
- + strlen("FD_PROG='' ")
- + strlen("FD_XSRV='' ")
- + strlen("FD_CUPS='' ")
- + strlen("FD_ESD='' ")
- + strlen("FD_NAS='' ")
- + strlen("FD_SMB='' ")
- + strlen("FD_TAG='' ")
- + strlen("FD_XDMCP_IF='' ")
- + strlen("FD_XDUMMY_RUN_AS_ROOT='' ")
- + strlen("FD_SESS='' /bin/sh ")
- + strlen(uu) + 1
- + strlen(fdgeom) + 1
- + strlen(fdopts) + 1
- + strlen(fdextra) + 1
- + strlen(fdprog) + 1
- + strlen(fdxsrv) + 1
- + strlen(fdcups) + 1
- + strlen(fdesd) + 1
- + strlen(fdnas) + 1
- + strlen(fdsmb) + 1
- + strlen(fdtag) + 1
- + strlen(fdxdmcpif) + 1
- + strlen(fdxdum) + 1
- + strlen(fdsess) + 1
- + strlen(cdout) + 1
- + strlen(opts) + 1);
- sprintf(create_cmd, "env USER='%s' FD_GEOM='%s' FD_SESS='%s' "
- "FD_OPTS='%s' FD_EXTRA='%s' FD_PROG='%s' FD_XSRV='%s' FD_CUPS='%s' "
- "FD_ESD='%s' FD_NAS='%s' FD_SMB='%s' FD_TAG='%s' FD_XDMCP_IF='%s' "
- "FD_XDUMMY_RUN_AS_ROOT='%s' %s /bin/sh %s %s",
- uu, fdgeom, fdsess, fdopts, fdextra, fdprog, fdxsrv,
- fdcups, fdesd, fdnas, fdsmb, fdtag, fdxdmcpif, fdxdum, cdout, tmp, opts);
- } else {
- create_cmd = (char *) malloc(strlen(tmp)
- + strlen("/bin/sh ") + 1 + strlen(opts) + 1);
- sprintf(create_cmd, "/bin/sh %s %s", tmp, opts);
- }
- return create_cmd;
-}
-
-static char *certret_extract() {
- char *q, *p, *str = strdup(certret_str);
- char *upeer = NULL;
- int ok = 0;
-
- q = strstr(str, "Subject: ");
- if (! q) return NULL;
-
- p = strstr(q, "\n");
- if (p) *p = '\0';
-
- q = strstr(q, "CN=");
- if (! q) return NULL;
-
- if (! getenv("X11VNC_SSLPEER_CN")) {
- p = q;
- q = strstr(q, "/emailAddress=");
- if (! q) q = strstr(p, "/Email=");
- if (! q) return NULL;
- }
-
- q = strstr(q, "=");
- if (! q) return NULL;
-
- q++;
- p = strstr(q, " ");
- if (p) *p = '\0';
- p = strstr(q, "@");
- if (p) *p = '\0';
- p = strstr(q, "/");
- if (p) *p = '\0';
-
- upeer = strdup(q);
-
- if (strcmp(upeer, "")) {
- p = upeer;
- while (*p != '\0') {
- char c = *p;
- if (!isalnum((int) c)) {
- *p = '\0';
- break;
- }
- p++;
- }
- if (strcmp(upeer, "")) {
- ok = 1;
- }
- }
- if (! ok) {
- upeer = NULL;
- }
- return upeer;
-}
-
-static void check_nodisplay(char **nd, char **tag) {
- if (unixpw && !getenv("X11VNC_NO_UNIXPW_OPTS") && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
- char *q, *t2, *t = keep_unixpw_opts;
- q = strstr(t, "nd=");
- if (! q) q = strstr(t, "nodisplay=");
- if (q) {
- q = strchr(q, '=') + 1;
- t = strdup(q);
- q = t;
- t2 = strchr(t, ',');
- if (t2) *t2 = '\0';
-
- while (*t != '\0') {
- if (*t == '+') {
- *t = ',';
- }
- t++;
- }
- if (!strchr(q, '\'') && !strpbrk(q, "[](){}`'\"$&*|<>")) {
- if (! quiet) rfbLog("set X11VNC_SKIP_DISPLAY: %s\n", q);
- *nd = q;
- }
- }
-
- q = strstr(keep_unixpw_opts, "tag=");
- if (getenv("FD_TAG")) {
- *tag = strdup(getenv("FD_TAG"));
- } else if (q) {
- q = strchr(q, '=') + 1;
- t = strdup(q);
- q = t;
- t2 = strchr(t, ',');
- if (t2) *t2 = '\0';
-
- if (strlen(q) < 120) {
- int ok = 1;
- while (*t != '\0') {
- char c = *t;
- if (*t == '_' || *t == '-') {
- ;
- } else if (!isalnum((int) c)) {
- ok = 0;
- rfbLog("bad tag char: '%c' in '%s'\n", c, q);
- break;
- }
- t++;
- }
- if (ok) {
- if (! quiet) rfbLog("set FD_TAG: %s\n", q);
- *tag = q;
- }
- }
- }
- }
- if (unixpw_system_greeter_active == 2) {
- if (!keep_unixpw_user) {
- clean_up_exit(1);
- }
- *nd = strdup("all");
- }
-}
-
-static char *get_usslpeer() {
- char *u = NULL, *upeer = NULL;
-
- if (certret_str) {
- upeer = certret_extract();
- }
- if (!upeer) {
- return NULL;
- }
- rfbLog("sslpeer unix username extracted from x509 cert: %s\n", upeer);
-
- u = (char *) malloc(strlen(upeer+2));
- u[0] = '\0';
- if (!strcmp(users_list, "sslpeer=")) {
- sprintf(u, "+%s", upeer);
- } else {
- char *p, *str = strdup(users_list);
- p = strtok(str + strlen("sslpeer="), ",");
- while (p) {
- if (!strcmp(p, upeer)) {
- sprintf(u, "+%s", upeer);
- break;
- }
- p = strtok(NULL, ",");
- }
- free(str);
- }
- if (u[0] == '\0') {
- rfbLog("sslpeer cannot determine user: %s\n", upeer);
- free(u);
- return NULL;
- }
- free(u);
- return upeer;
-}
-
-static void do_try_switch(char *usslpeer, char *users_list_save) {
- if (unixpw_system_greeter_active == 2) {
- rfbLog("unixpw_system_greeter: not trying switch to user '%s'\n", usslpeer ? usslpeer : "");
- return;
- }
- if (usslpeer) {
- char *u = (char *) malloc(strlen(usslpeer+2));
- sprintf(u, "+%s", usslpeer);
- if (switch_user(u, 0)) {
- rfbLog("sslpeer switched to user: %s\n", usslpeer);
- } else {
- rfbLog("sslpeer failed to switch to user: %s\n", usslpeer);
- }
- free(u);
-
- } else if (users_list_save && keep_unixpw_user) {
- char *user = keep_unixpw_user;
- char *u = (char *)malloc(strlen(user)+1);
-
- users_list = users_list_save;
-
- u[0] = '\0';
- if (!strcmp(users_list, "unixpw=")) {
- sprintf(u, "+%s", user);
- } else {
- char *p, *str = strdup(users_list);
- p = strtok(str + strlen("unixpw="), ",");
- while (p) {
- if (!strcmp(p, user)) {
- sprintf(u, "+%s", user);
- break;
- }
- p = strtok(NULL, ",");
- }
- free(str);
- }
-
- if (u[0] == '\0') {
- rfbLog("unixpw_accept skipping switch to user: %s (drc)\n", user);
- } else if (switch_user(u, 0)) {
- rfbLog("unixpw_accept switched to user: %s (drc)\n", user);
- } else {
- rfbLog("unixpw_accept failed to switch to user: %s (drc)\n", user);
- }
- free(u);
- }
-}
-
-static void path_lookup(char *prog) {
- /* see create_display script */
- char *create_display_extra = "/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/dt/bin:/opt/kde4/bin:/opt/kde3/bin:/opt/gnome/bin:/usr/bin:/bin:/usr/sfw/bin:/usr/local/bin";
- char *path, *try, *p;
- int found = 0, len = strlen(create_display_extra);
-
- if (getenv("PATH")) {
- len += strlen(getenv("PATH")) + 1;
- path = (char *) malloc((len+1) * sizeof(char));
- sprintf(path, "%s:%s", getenv("PATH"), create_display_extra);
- } else {
- path = (char *) malloc((len+1) * sizeof(char));
- sprintf(path, "%s", create_display_extra);
- }
- try = (char *) malloc((len+2+strlen(prog)) * sizeof(char));
-
- p = strtok(path, ":");
- while (p) {
- struct stat sbuf;
-
- sprintf(try, "%s/%s", p, prog);
- if (stat(try, &sbuf) == 0) {
- found = 1;
- break;
- }
- p = strtok(NULL, ":");
- }
-
- free(path);
- free(try);
-
- if (!found) {
- fprintf(stderr, "\n");
- fprintf(stderr, "The program \"%s\" could not be found in PATH and standard locations.\n", prog);
- fprintf(stderr, "You probably need to install a package that provides the \"%s\" program.\n", prog);
- fprintf(stderr, "Without it FINDCREATEDISPLAY mode may not be able to create an X display.\n");
- fprintf(stderr, "\n");
- }
-}
-
-static int do_run_cmd(char *cmd, char *create_cmd, char *users_list_save, int created_disp, int db) {
- char tmp[] = "/tmp/x11vnc-find_display.XXXXXX";
- char line1[1024], line2[16384];
- char *q, *usslpeer = NULL;
- int n, nodisp = 0, saw_xdmcp = 0;
- int tmp_fd = -1;
- int internal_cmd = 0;
- int tried_switch = 0;
-
- memset(line1, 0, sizeof(line1));
- memset(line2, 0, sizeof(line2));
-
- if (users_list && strstr(users_list, "sslpeer=") == users_list) {
- usslpeer = get_usslpeer();
- if (! usslpeer) {
- return 0;
- }
- }
- if (getenv("DEBUG_RUN_CMD")) db = 1;
-
- /* only sets environment variables: */
- run_user_command("", latest_client, "env", NULL, 0, NULL);
-
- if (program_name) {
- set_env("X11VNC_PROG", program_name);
- } else {
- set_env("X11VNC_PROG", "x11vnc");
- }
-
- if (!strcmp(cmd, "FINDDISPLAY") ||
- strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
- char *nd = "";
- char *tag = "";
- char fdout[128];
-
- internal_cmd = 1;
-
- tmp_fd = mkstemp(tmp);
-
- if (tmp_fd < 0) {
- rfbLog("wait_for_client: open failed: %s\n", tmp);
- rfbLogPerror("mkstemp");
- clean_up_exit(1);
- }
- chmod(tmp, 0644);
- if (getenv("X11VNC_FINDDISPLAY_ALWAYS_FAILS")) {
- char *s = "#!/bin/sh\necho _FAIL_\nexit 1\n";
- write(tmp_fd, s, strlen(s));
- } else {
- write(tmp_fd, find_display, strlen(find_display));
- }
- close(tmp_fd);
- nodisp = 1;
-
- if (strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
- create_cmd = build_create_cmd(cmd, &saw_xdmcp, usslpeer, tmp);
- if (db) fprintf(stderr, "create_cmd: %s\n", create_cmd);
- }
- if (getenv("X11VNC_SKIP_DISPLAY")) {
- nd = strdup(getenv("X11VNC_SKIP_DISPLAY"));
- }
- check_nodisplay(&nd, &tag);
-
- fdout[0] = '\0';
- if (getenv("FIND_DISPLAY_OUTPUT")) {
- snprintf(fdout, 120, " FIND_DISPLAY_OUTPUT='%s' ", getenv("FIND_DISPLAY_OUTPUT"));
- }
-
- cmd = (char *) malloc(strlen("env X11VNC_SKIP_DISPLAY='' ")
- + strlen(nd) + strlen(" FD_TAG='' ") + strlen(tag) + strlen(tmp) + strlen("/bin/sh ") + strlen(fdout) + 1);
-
- if (strcmp(tag, "")) {
- sprintf(cmd, "env X11VNC_SKIP_DISPLAY='%s' FD_TAG='%s' %s /bin/sh %s", nd, tag, fdout, tmp);
- } else {
- sprintf(cmd, "env X11VNC_SKIP_DISPLAY='%s' %s /bin/sh %s", nd, fdout, tmp);
- }
- }
-
- rfbLog("wait_for_client: running: %s\n", cmd);
-
- if (create_cmd != NULL) {
- if (strstr(create_cmd, "Xvfb")) {
- path_lookup("Xvfb");
- }
- if (strstr(create_cmd, "Xvnc")) {
- path_lookup("Xvnc");
- }
- if (strstr(create_cmd, "Xdummy")) {
- path_lookup("Xdummy");
- }
- }
-
- if (unixpw && !unixpw_nis) {
- int res = 0, k, j, i;
- char line[18000];
-
- memset(line, 0, sizeof(line));
-
- if (unixpw_system_greeter_active == 2) {
- rfbLog("unixpw_system_greeter: forcing find display failure.\n");
- res = 0;
- } else if (keep_unixpw_user && keep_unixpw_pass) {
- n = sizeof(line);
- if (unixpw_cmd != NULL) {
- res = unixpw_cmd_run(keep_unixpw_user,
- keep_unixpw_pass, cmd, line, &n);
- } else {
- res = su_verify(keep_unixpw_user,
- keep_unixpw_pass, cmd, line, &n, nodisp);
- }
- }
-
-if (db) {fprintf(stderr, "line: "); write(2, line, n); write(2, "\n", 1); fprintf(stderr, "res=%d n=%d\n", res, n);}
- if (! res) {
- rfbLog("wait_for_client: find display cmd failed.\n");
- }
-
- if (! res && create_cmd) {
- FILE *mt = fopen(tmp, "w");
- if (! mt) {
- rfbLog("wait_for_client: open failed: %s\n", tmp);
- rfbLogPerror("fopen");
- clean_up_exit(1);
- }
- fprintf(mt, "%s", create_display);
- fclose(mt);
-
- findcreatedisplay = 1;
-
- if (unixpw_cmd != NULL) {
- /* let the external unixpw command do it: */
- n = sizeof(line);
- close_exec_fds();
- res = unixpw_cmd_run(keep_unixpw_user,
- keep_unixpw_pass, create_cmd, line, &n);
- } else if (getuid() != 0 && unixpw_system_greeter_active != 2) {
- /* if not root, run as the other user... */
- n = sizeof(line);
- close_exec_fds();
- res = su_verify(keep_unixpw_user,
- keep_unixpw_pass, create_cmd, line, &n, nodisp);
-if (db) fprintf(stderr, "c-res=%d n=%d line: '%s'\n", res, n, line);
-
- } else {
- FILE *p;
- close_exec_fds();
- if (unixpw_system_greeter_active == 2) {
- rfbLog("unixpw_system_greeter: not trying su_verify() to run\n");
- rfbLog("unixpw_system_greeter: create display command.\n");
- }
- rfbLog("wait_for_client: running: %s\n", create_cmd);
- p = popen(create_cmd, "r");
- if (! p) {
- rfbLog("wait_for_client: popen failed: %s\n", create_cmd);
- res = 0;
- } else if (fgets(line1, 1024, p) == NULL) {
- rfbLog("wait_for_client: read failed: %s\n", create_cmd);
- res = 0;
- } else {
- n = fread(line2, 1, 16384, p);
- if (pclose(p) != 0) {
- res = 0;
- } else {
- strncpy(line, line1, 100);
- memcpy(line + strlen(line1), line2, n);
-if (db) fprintf(stderr, "line1: '%s'\n", line1);
- n += strlen(line1);
- created_disp = 1;
- res = 1;
- }
- }
- }
- if (res && saw_xdmcp && unixpw_system_greeter_active != 2) {
- xdmcp_insert = strdup(keep_unixpw_user);
- }
- }
-
- if (tmp_fd >= 0) {
- unlink(tmp);
- }
-
- if (! res) {
- rfbLog("wait_for_client: cmd failed: %s\n", cmd);
- unixpw_msg("No DISPLAY found.", 3);
- clean_up_exit(1);
- }
-
- /*
- * we need to hunt for DISPLAY= since there may be
- * a login banner or something at the beginning.
- */
- q = strstr(line, "DISPLAY=");
- if (! q) {
- q = line;
- }
- n -= (q - line);
-
- for (k = 0; k < 1024; k++) {
- line1[k] = q[k];
- if (q[k] == '\n') {
- k++;
- break;
- }
- }
- n -= k;
- i = 0;
- for (j = 0; j < 16384; j++) {
- if (j < 16384 - 1) {
- /* xauth data, assume pty added CR */
- if (q[k+j] == '\r' && q[k+j+1] == '\n') {
- continue;
- }
- }
-
- line2[i] = q[k+j];
- i++;
- }
-if (db) write(2, line, 100);
-if (db) fprintf(stderr, "\n");
-
- } else {
- FILE *p;
- int rc;
- close_exec_fds();
-
- if (usslpeer) {
- char *c;
- if (getuid() == 0) {
- c = (char *) malloc(strlen("su - '' -c \"")
- + strlen(usslpeer) + strlen(cmd) + 1 + 1);
- sprintf(c, "su - '%s' -c \"%s\"", usslpeer, cmd);
- } else {
- c = strdup(cmd);
- }
- p = popen(c, "r");
- free(c);
-
- } else if (unixpw_nis && keep_unixpw_user) {
- char *c;
- if (getuid() == 0) {
- c = (char *) malloc(strlen("su - '' -c \"")
- + strlen(keep_unixpw_user) + strlen(cmd) + 1 + 1);
- sprintf(c, "su - '%s' -c \"%s\"", keep_unixpw_user, cmd);
- } else {
- c = strdup(cmd);
- }
- p = popen(c, "r");
- free(c);
-
- } else {
- p = popen(cmd, "r");
- }
-
- if (! p) {
- rfbLog("wait_for_client: cmd failed: %s\n", cmd);
- rfbLogPerror("popen");
- if (tmp_fd >= 0) {
- unlink(tmp);
- }
- clean_up_exit(1);
- }
- if (fgets(line1, 1024, p) == NULL) {
- rfbLog("wait_for_client: read failed: %s\n", cmd);
- rfbLogPerror("fgets");
- if (tmp_fd >= 0) {
- unlink(tmp);
- }
- clean_up_exit(1);
- }
- n = fread(line2, 1, 16384, p);
- rc = pclose(p);
-
- if (rc != 0) {
- rfbLog("wait_for_client: find display cmd failed.\n");
- }
-
- if (create_cmd && rc != 0) {
- FILE *mt = fopen(tmp, "w");
- if (! mt) {
- rfbLog("wait_for_client: open failed: %s\n", tmp);
- rfbLogPerror("fopen");
- if (tmp_fd >= 0) {
- unlink(tmp);
- }
- clean_up_exit(1);
- }
- fprintf(mt, "%s", create_display);
- fclose(mt);
-
- findcreatedisplay = 1;
-
- rfbLog("wait_for_client: FINDCREATEDISPLAY cmd: %s\n", create_cmd);
-
- p = popen(create_cmd, "r");
- if (! p) {
- rfbLog("wait_for_client: cmd failed: %s\n", create_cmd);
- rfbLogPerror("popen");
- if (tmp_fd >= 0) {
- unlink(tmp);
- }
- clean_up_exit(1);
- }
- if (fgets(line1, 1024, p) == NULL) {
- rfbLog("wait_for_client: read failed: %s\n", create_cmd);
- rfbLogPerror("fgets");
- if (tmp_fd >= 0) {
- unlink(tmp);
- }
- clean_up_exit(1);
- }
- n = fread(line2, 1, 16384, p);
- pclose(p);
- }
- if (tmp_fd >= 0) {
- unlink(tmp);
- }
- }
-
-if (db) fprintf(stderr, "line1=%s\n", line1);
-
- if (strstr(line1, "DISPLAY=") != line1) {
- rfbLog("wait_for_client: bad reply '%s'\n", line1);
- if (unixpw) {
- unixpw_msg("No DISPLAY found.", 3);
- }
- clean_up_exit(1);
- }
-
-
- if (strstr(line1, ",VT=")) {
- int vt;
- char *t = strstr(line1, ",VT=");
- vt = atoi(t + strlen(",VT="));
- *t = '\0';
- if (7 <= vt && vt <= 15) {
- do_chvt(vt);
- }
- } else if (strstr(line1, ",XPID=")) {
- int i, pvt, vt = -1;
- char *t = strstr(line1, ",XPID=");
- pvt = atoi(t + strlen(",XPID="));
- *t = '\0';
- if (pvt > 0) {
- for (i=3; i <= 10; i++) {
- int k;
- char proc[100];
- char buf[100];
- sprintf(proc, "/proc/%d/fd/%d", pvt, i);
-if (db) fprintf(stderr, "%d -- %s\n", i, proc);
- for (k=0; k < 100; k++) {
- buf[k] = '\0';
- }
-
- if (readlink(proc, buf, 100) != -1) {
- buf[100-1] = '\0';
-if (db) fprintf(stderr, "%d -- %s -- %s\n", i, proc, buf);
- if (strstr(buf, "/dev/tty") == buf) {
- vt = atoi(buf + strlen("/dev/tty"));
- if (vt > 0) {
- break;
- }
- }
- }
- }
- }
- if (7 <= vt && vt <= 12) {
- do_chvt(vt);
- }
- }
-
- use_dpy = strdup(line1 + strlen("DISPLAY="));
- q = use_dpy;
- while (*q != '\0') {
- if (*q == '\n' || *q == '\r') *q = '\0';
- q++;
- }
- if (line2[0] != '\0') {
- if (strstr(line2, "XAUTHORITY=") == line2) {
- q = line2;
- while (*q != '\0') {
- if (*q == '\n' || *q == '\r') *q = '\0';
- q++;
- }
- if (auth_file) {
- free(auth_file);
- }
- auth_file = strdup(line2 + strlen("XAUTHORITY="));
-
- } else {
- xauth_raw_data = (char *)malloc(n);
- xauth_raw_len = n;
- memcpy(xauth_raw_data, line2, n);
-if (db) {fprintf(stderr, "xauth_raw_len: %d\n", n);
-write(2, xauth_raw_data, n);
-fprintf(stderr, "\n");}
- }
- }
-
- if (!tried_switch) {
- do_try_switch(usslpeer, users_list_save);
- tried_switch = 1;
- }
-
- if (unixpw) {
- /* Some cleanup and messaging for -unixpw case: */
- char str[32];
-
- if (keep_unixpw_user && keep_unixpw_pass) {
- strzero(keep_unixpw_user);
- strzero(keep_unixpw_pass);
- keep_unixpw = 0;
- }
-
- if (created_disp) {
- snprintf(str, 30, "Created DISPLAY %s", use_dpy);
- } else {
- snprintf(str, 30, "Using DISPLAY %s", use_dpy);
- }
- unixpw_msg(str, 2);
- }
- return 1;
-}
-
-void ssh_remote_tunnel(char *, int);
-
-static XImage ximage_struct;
-
-void progress_client(void) {
- int i, j = 0, progressed = 0, db = 0;
- double start = dnow();
- if (getenv("PROGRESS_CLIENT_DBG")) {
- rfbLog("progress_client: begin\n");
- db = 1;
- }
- for (i = 0; i < 15; i++) {
- if (latest_client) {
- for (j = 0; j < 10; j++) {
- if (latest_client->state != RFB_PROTOCOL_VERSION) {
- progressed = 1;
- break;
- }
- if (db) rfbLog("progress_client: calling-1 rfbCFD(1) %.6f\n", dnow()-start);
- rfbCFD(1);
- }
- }
- if (progressed) {
- break;
- }
- if (db) rfbLog("progress_client: calling-2 rfbCFD(1) %.6f\n", dnow()-start);
- rfbCFD(1);
- }
- if (!quiet) {
- rfbLog("client progressed=%d in %d/%d %.6f s\n",
- progressed, i, j, dnow() - start);
- }
-}
-
-int wait_for_client(int *argc, char** argv, int http) {
- /* ugh, here we go... */
- XImage* fb_image;
- int w = 640, h = 480, b = 32;
- int w0 = -1, h0 = -1, i, chg_raw_fb = 0;
- char *str, *q, *cmd = NULL;
- int db = 0, dt = 0;
- char *create_cmd = NULL;
- char *users_list_save = NULL;
- int created_disp = 0, ncache_save;
- int did_client_connect = 0;
- char *vnc_redirect_host = "localhost";
- int vnc_redirect_port = -1, vnc_redirect_cnt = 0;
- char vnc_redirect_test[10];
-
- if (getenv("WAIT_FOR_CLIENT_DB")) {
- db = 1;
- }
-
- vnc_redirect = 0;
-
- if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) {
- return 0;
- }
-
- for (i=0; i < *argc; i++) {
- if (!strcmp(argv[i], "-desktop")) {
- dt = 1;
- }
- if (db) fprintf(stderr, "args %d %s\n", i, argv[i]);
- }
- if (!quiet && !strstr(use_dpy, "FINDDISPLAY-run")) {
- rfbLog("\n");
- rfbLog("wait_for_client: %s\n", use_dpy);
- rfbLog("\n");
- }
-
- str = strdup(use_dpy);
- str += strlen("WAIT");
-
- xdmcp_insert = NULL;
-
- /* get any leading geometry: */
- q = strchr(str+1, ':');
- if (q) {
- *q = '\0';
- if (sscanf(str+1, "%dx%d", &w0, &h0) == 2) {
- w = w0;
- h = h0;
- rfbLog("wait_for_client set: w=%d h=%d\n", w, h);
- } else {
- w0 = -1;
- h0 = -1;
- }
- *q = ':';
- str = q;
- }
- if ((w0 == -1 || h0 == -1) && pad_geometry != NULL) {
- int b0, del = 0;
- char *s = pad_geometry;
- if (strstr(s, "once:") == s) {
- del = 1;
- s += strlen("once:");
- }
- if (sscanf(s, "%dx%dx%d", &w0, &h0, &b0) == 3) {
- w = nabs(w0);
- h = nabs(h0);
- b = nabs(b0);
- } else if (sscanf(s, "%dx%d", &w0, &h0) == 2) {
- w = nabs(w0);
- h = nabs(h0);
- }
- if (del) {
- pad_geometry = NULL;
- }
- }
-
- /* str currently begins with a ':' */
- if (strstr(str, ":cmd=") == str) {
- /* cmd=/path/to/mycommand */
- str++;
- } else if (strpbrk(str, "0123456789") == str+1) {
- /* :0.0 */
- ;
- } else {
- /* hostname:0.0 */
- str++;
- }
-
- if (db) fprintf(stderr, "str: %s\n", str);
-
- if (strstr(str, "cmd=") == str) {
- cmd = setup_cmd(str, &vnc_redirect, &vnc_redirect_host, &vnc_redirect_port, db);
- }
-
- fb_image = &ximage_struct;
- setup_fake_fb(fb_image, w, h, b);
-
- if (! dt) {
- char *s;
- argv[*argc] = strdup("-desktop");
- *argc = (*argc) + 1;
-
- if (cmd) {
- char *q;
- s = choose_title(":0");
- q = strstr(s, ":0");
- if (q) {
- *q = '\0';
- }
- } else {
- s = choose_title(str);
- }
- rfb_desktop_name = strdup(s);
- argv[*argc] = s;
- *argc = (*argc) + 1;
- }
-
- ncache_save = ncache;
- ncache = 0;
-
- initialize_allowed_input();
-
- if (! multiple_cursors_mode) {
- multiple_cursors_mode = strdup("default");
- }
- initialize_cursors_mode();
-
- initialize_screen(argc, argv, fb_image);
-
- if (! inetd && ! use_openssl) {
- if (! screen->port || screen->listenSock < 0) {
- if (got_rfbport && got_rfbport_val == 0) {
- ;
- } else if (ipv6_listen && ipv6_listen_fd >= 0) {
- rfbLog("Info: listening on IPv6 interface only. (wait for client)\n");
- } else {
- rfbLogEnable(1);
- rfbLog("Error: could not obtain listening port. (wait for client)\n");
- if (!got_rfbport && !got_ipv6_listen) {
- rfbLog("If this system is IPv6-only, use the -6 option.\n");
- }
- clean_up_exit(1);
- }
- }
- }
-
- initialize_signals();
-
- if (ssh_str != NULL) {
- ssh_remote_tunnel(ssh_str, screen->port);
- }
-
- if (! raw_fb) {
- chg_raw_fb = 1;
- /* kludge to get RAWFB_RET with dpy == NULL guards */
- raw_fb = (char *) 0x1;
- }
-
- if (cmd && !strcmp(cmd, "HTTPONCE")) {
- handle_one_http_request();
- clean_up_exit(0);
- }
-
- if (http && check_httpdir()) {
- http_connections(1);
- }
-
- if (cmd && unixpw) {
- keep_unixpw = 1;
- }
-
- setup_service();
-
- check_waitbg();
-
- if (vnc_redirect) {
- vnc_redirect_loop(vnc_redirect_test, &vnc_redirect_cnt);
- } else {
-
- if (use_threads && !started_rfbRunEventLoop) {
- started_rfbRunEventLoop = 1;
- rfbRunEventLoop(screen, -1, TRUE);
- }
-
- if (inetd && use_openssl) {
- accept_openssl(OPENSSL_INETD, -1);
- }
-
- setup_client_connect(&did_client_connect);
-
- loop_for_connect(did_client_connect);
-
- if (unixpw) {
- if (cmd && strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
- if (users_list && strstr(users_list, "unixpw=") == users_list) {
- users_list_save = users_list;
- users_list = NULL;
- }
- }
- do_unixpw_loop();
- } else if (cmd && !use_threads) {
- /* try to get RFB proto done now. */
- progress_client();
- }
- }
-
- if (vnc_redirect == 2) {
- ;
- } else if (cmd) {
- if (!do_run_cmd(cmd, create_cmd, users_list_save, created_disp, db)) {
- return 0;
- }
- } else {
- use_dpy = strdup(str);
- }
- if (chg_raw_fb) {
- raw_fb = NULL;
- }
-
- ncache = ncache_save;
-
- if (unixpw && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
- user_supplied_opts(keep_unixpw_opts);
- }
- if (create_cmd) {
- free(create_cmd);
- }
-
- if (vnc_redirect) {
- do_vnc_redirect(created_disp, vnc_redirect_host, vnc_redirect_port,
- vnc_redirect_cnt, vnc_redirect_test);
- clean_up_exit(0);
- }
-
- return 1;
-}
-
diff --git a/x11vnc/user.h b/x11vnc/user.h
deleted file mode 100644
index 68c1bb8..0000000
--- a/x11vnc/user.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_USER_H
-#define _X11VNC_USER_H
-
-/* -- user.h -- */
-
-extern void check_switched_user(void);
-extern void lurk_loop(char *str);
-extern int switch_user(char *, int);
-extern int read_passwds(char *passfile);
-extern void install_passwds(void);
-extern void check_new_passwds(int force);
-extern void progress_client(void);
-extern int wait_for_client(int *argc, char** argv, int http);
-extern rfbBool custom_passwd_check(rfbClientPtr cl, const char *response, int len);
-extern char *xdmcp_insert;
-
-#endif /* _X11VNC_USER_H */
diff --git a/x11vnc/userinput.c b/x11vnc/userinput.c
deleted file mode 100644
index 84bcb7b..0000000
--- a/x11vnc/userinput.c
+++ /dev/null
@@ -1,10199 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- userinput.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "xdamage.h"
-#include "xrecord.h"
-#include "xinerama.h"
-#include "win_utils.h"
-#include "xevents.h"
-#include "user.h"
-#include "scan.h"
-#include "cleanup.h"
-#include "pointer.h"
-#include "rates.h"
-#include "keyboard.h"
-#include "solid.h"
-#include "xrandr.h"
-#include "8to24.h"
-#include "unixpw.h"
-#include "macosx.h"
-#include "macosxCGS.h"
-#include "cursor.h"
-#include "screen.h"
-#include "connections.h"
-
-/*
- * user input handling heuristics
- */
-int defer_update_nofb = 4; /* defer a shorter time under -nofb */
-int last_scroll_type = SCR_NONE;
-
-
-int get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
- Window *frame, Window *win);
-void parse_scroll_copyrect(void);
-void parse_fixscreen(void);
-void parse_wireframe(void);
-
-void set_wirecopyrect_mode(char *str);
-void set_scrollcopyrect_mode(char *str);
-void initialize_scroll_keys(void);
-void initialize_scroll_matches(void);
-void initialize_scroll_term(void);
-void initialize_max_keyrepeat(void);
-
-int direct_fb_copy(int x1, int y1, int x2, int y2, int mark);
-void fb_push(void);
-int fb_push_wait(double max_wait, int flags);
-void eat_viewonly_input(int max_eat, int keep);
-
-void mark_for_xdamage(int x, int y, int w, int h);
-void mark_region_for_xdamage(sraRegionPtr region);
-void set_xdamage_mark(int x, int y, int w, int h);
-int near_wm_edge(int x, int y, int w, int h, int px, int py);
-int near_scrollbar_edge(int x, int y, int w, int h, int px, int py);
-
-void check_fixscreen(void);
-int check_xrecord(void);
-int check_wireframe(void);
-int fb_update_sent(int *count);
-int check_user_input(double dt, double dtr, int tile_diffs, int *cnt);
-void do_copyregion(sraRegionPtr region, int dx, int dy, int mode);
-
-int check_ncache(int reset, int mode);
-int find_rect(int idx, int x, int y, int w, int h);
-int bs_restore(int idx, int *nbatch, sraRegionPtr rmask, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb);
-int try_to_fix_su(Window win, int idx, Window above, int *nbatch, char *mode);
-int try_to_fix_resize_su(Window orig_frame, int orig_x, int orig_y, int orig_w, int orig_h,
- int x, int y, int w, int h, int try_batch);
-int lookup_win_index(Window);
-void set_ncache_xrootpmap(void);
-
-static void get_client_regions(int *req, int *mod, int *cpy, int *num) ;
-static void parse_scroll_copyrect_str(char *scr);
-static void parse_wireframe_str(char *wf);
-static void destroy_str_list(char **list);
-static void draw_box(int x, int y, int w, int h, int restore);
-static int do_bdpush(Window wm_win, int x0, int y0, int w0, int h0, int bdx,
- int bdy, int bdskinny);
-static int set_ypad(void);
-static void scale_mark(int x1, int y1, int x2, int y2, int mark);
-static int push_scr_ev(double *age, int type, int bdpush, int bdx, int bdy,
- int bdskinny, int first_push);
-static int crfix(int x, int dx, int Lx);
-static int scrollability(Window win, int set);
-static int eat_pointer(int max_ptr_eat, int keep);
-static void set_bdpush(int type, double *last_bdpush, int *pushit);
-static int repeat_check(double last_key_scroll);
-static int check_xrecord_keys(void);
-static int check_xrecord_mouse(void);
-static int try_copyrect(Window orig_frame, Window frame, int x, int y, int w, int h,
- int dx, int dy, int *obscured, sraRegionPtr extra_clip, double max_wait, int *nbatch);
-static int wireframe_mod_state();
-static void check_user_input2(double dt);
-static void check_user_input3(double dt, double dtr, int tile_diffs);
-static void check_user_input4(double dt, double dtr, int tile_diffs);
-
-winattr_t *cache_list;
-
-/*
- * For -wireframe: find the direct child of rootwin that has the
- * pointer, assume that is the WM frame that contains the application
- * (i.e. wm reparents the app toplevel) return frame position and size
- * if successful.
- */
-int get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
- Window *frame, Window *win) {
-#if !NO_X11
- Window r, c;
- XWindowAttributes attr;
- Bool ret;
- int rootx, rooty, wx, wy;
- unsigned int mask;
-#endif
-
-#ifdef MACOSX
- if (macosx_console) {
- return macosx_get_wm_frame_pos(px, py, x, y, w, h, frame, win);
- }
-#endif
-
- RAWFB_RET(0)
-
-#if NO_X11
- if (!px || !py || !x || !y || !w || !h || !frame || !win) {}
- return 0;
-#else
-
-
- ret = XQueryPointer_wr(dpy, rootwin, &r, &c, &rootx, &rooty, &wx, &wy,
- &mask);
-
- *frame = c;
-
- /* current pointer position is returned too */
- *px = rootx;
- *py = rooty;
-
- if (!ret || ! c || c == rootwin) {
- /* no immediate child */
- return 0;
- }
-
- /* child window position and size */
- if (! valid_window(c, &attr, 1)) {
- return 0;
- }
-
- *x = attr.x;
- *y = attr.y;
- *w = attr.width;
- *h = attr.height;
-
-#if 0
- /* more accurate, but the animation is bogus anyway */
- if (attr.border_width > 0) {
- *w += 2 * attr.border_width;
- *h += 2 * attr.border_width;
- }
-#endif
-
- if (win != NULL) {
- *win = descend_pointer(5, c, NULL, 0);
- }
-
- return 1;
-#endif /* NO_X11 */
-}
-
-static int scrollcopyrect_top, scrollcopyrect_bot;
-static int scrollcopyrect_left, scrollcopyrect_right;
-static double scr_key_time, scr_key_persist;
-static double scr_mouse_time, scr_mouse_persist, scr_mouse_maxtime;
-static double scr_mouse_pointer_delay;
-static double scr_key_bdpush_time, scr_mouse_bdpush_time;
-
-static void parse_scroll_copyrect_str(char *scr) {
- char *p, *str;
- int i;
- char *part[16];
-
- for (i=0; i<16; i++) {
- part[i] = NULL;
- }
-
- if (scr == NULL || *scr == '\0') {
- return;
- }
-
- str = strdup(scr);
-
- p = strtok(str, ",");
- i = 0;
- while (p) {
- part[i++] = strdup(p);
- p = strtok(NULL, ",");
- if (i >= 16) break;
- }
- free(str);
-
-
- /*
- * Top, Bottom, Left, Right tolerances for scrollbar locations.
- */
- if ((str = part[0]) != NULL) {
- int t, b, l, r;
- if (sscanf(str, "%d+%d+%d+%d", &t, &b, &l, &r) == 4) {
- scrollcopyrect_top = t;
- scrollcopyrect_bot = b;
- scrollcopyrect_left = l;
- scrollcopyrect_right = r;
- }
- free(str);
- }
-
- /* key scrolling timing heuristics. */
- if ((str = part[1]) != NULL) {
- double t1, t2, t3;
- if (sscanf(str, "%lf+%lf+%lf", &t1, &t2, &t3) == 3) {
- scr_key_time = t1;
- scr_key_persist = t2;
- scr_key_bdpush_time = t3;
- }
- free(str);
- }
-
- /* mouse scrolling timing heuristics. */
- if ((str = part[2]) != NULL) {
- double t1, t2, t3, t4, t5;
- if (sscanf(str, "%lf+%lf+%lf+%lf+%lf", &t1, &t2, &t3, &t4,
- &t5) == 5) {
- scr_mouse_time = t1;
- scr_mouse_persist = t2;
- scr_mouse_bdpush_time = t3;
- scr_mouse_pointer_delay = t4;
- scr_mouse_maxtime = t5;
- }
- free(str);
- }
-}
-
-void parse_scroll_copyrect(void) {
- parse_scroll_copyrect_str(SCROLL_COPYRECT_PARMS);
- if (! scroll_copyrect_str) {
- scroll_copyrect_str = strdup(SCROLL_COPYRECT_PARMS);
- }
- parse_scroll_copyrect_str(scroll_copyrect_str);
-}
-
-void parse_fixscreen(void) {
- char *str, *p;
-
- screen_fixup_V = 0.0;
- screen_fixup_C = 0.0;
- screen_fixup_X = 0.0;
- screen_fixup_8 = 0.0;
-
- if (! screen_fixup_str) {
- return;
- }
-
- str = strdup(screen_fixup_str);
-
- p = strtok(str, ",");
- while (p) {
- double t;
- if (*p == 'V' && sscanf(p, "V=%lf", &t) == 1) {
- screen_fixup_V = t;
- } else if (*p == 'C' && sscanf(p, "C=%lf", &t) == 1) {
- screen_fixup_C = t;
- } else if (*p == 'X' && sscanf(p, "X=%lf", &t) == 1) {
- screen_fixup_X = t;
- } else if (*p == 'X' && sscanf(p, "8=%lf", &t) == 1) {
- screen_fixup_8 = t;
- }
- p = strtok(NULL, ",");
- }
- free(str);
-
- if (screen_fixup_V < 0.0) screen_fixup_V = 0.0;
- if (screen_fixup_C < 0.0) screen_fixup_C = 0.0;
- if (screen_fixup_X < 0.0) screen_fixup_X = 0.0;
- if (screen_fixup_8 < 0.0) screen_fixup_8 = 0.0;
-}
-
-/*
-WIREFRAME_PARMS "0xff,2,0,30+6+6+6,Alt,0.05+0.3+2.0,8"
- 0xff,2,0,32+8+8+8,all,0.15+0.30+5.0+0.125
-shade,linewidth,percent,T+B+L+R,mods,t1+t2+t3+t4
- */
-#define LW_MAX 8
-static unsigned long wireframe_shade = 0xff;
-static int wireframe_lw;
-static double wireframe_frac;
-static int wireframe_top, wireframe_bot, wireframe_left, wireframe_right;
-static double wireframe_t1, wireframe_t2, wireframe_t3, wireframe_t4;
-static char *wireframe_mods = NULL;
-
-/*
- * Parse the gory -wireframe string for parameters.
- */
-static void parse_wireframe_str(char *wf) {
- char *p, *str;
- int i;
- char *part[16];
-
- for (i=0; i<16; i++) {
- part[i] = NULL;
- }
-
- if (wf == NULL || *wf == '\0') {
- return;
- }
-
- str = strdup(wf);
-
- /* leading ",", make it start with ignorable string "z" */
- if (*str == ',') {
- char *tmp = (char *) malloc(strlen(str)+2);
- strcpy(tmp, "z");
- strcat(tmp, str);
- free(str);
- str = tmp;
- }
-
- p = strtok(str, ",");
- i = 0;
- while (p) {
- part[i++] = strdup(p);
- p = strtok(NULL, ",");
- if (i >= 16) break;
- }
- free(str);
-
-
- /* Wireframe shade, color, RGB: */
- if ((str = part[0]) != NULL) {
- unsigned long n;
- int r, g, b, ok = 0;
- XColor cdef;
- Colormap cmap;
- if (dpy && (bpp == 32 || bpp == 16)) {
-#if !NO_X11
- X_LOCK;
- cmap = DefaultColormap (dpy, scr);
- if (XParseColor(dpy, cmap, str, &cdef) &&
- XAllocColor(dpy, cmap, &cdef)) {
- r = cdef.red >> 8;
- g = cdef.green >> 8;
- b = cdef.blue >> 8;
- if (r == 0 && g == 0) {
- g = 1; /* need to be > 255 */
- }
- n = 0;
- n |= (r << main_red_shift);
- n |= (g << main_green_shift);
- n |= (b << main_blue_shift);
- wireframe_shade = n;
- ok = 1;
- }
- X_UNLOCK;
-#else
- r = g = b = 0;
- cmap = 0;
- cdef.pixel = 0;
-#endif
- }
- if (ok) {
- ;
- } else if (sscanf(str, "0x%lx", &n) == 1) {
- wireframe_shade = n;
- } else if (sscanf(str, "%lu", &n) == 1) {
- wireframe_shade = n;
- } else if (sscanf(str, "%lx", &n) == 1) {
- wireframe_shade = n;
- }
- free(str);
- }
-
- /* linewidth: # of pixels wide for the wireframe lines */
- if ((str = part[1]) != NULL) {
- int n;
- if (sscanf(str, "%d", &n) == 1) {
- wireframe_lw = n;
- if (wireframe_lw < 1) {
- wireframe_lw = 1;
- }
- if (wireframe_lw > LW_MAX) {
- wireframe_lw = LW_MAX;
- }
- }
- free(str);
- }
-
- /* percentage cutoff for opaque move/resize (like WM's) */
- if ((str = part[2]) != NULL) {
- if (*str == '\0') {
- ;
- } else if (strchr(str, '.')) {
- wireframe_frac = atof(str);
- } else {
- wireframe_frac = ((double) atoi(str))/100.0;
- }
- free(str);
- }
-
- /*
- * Top, Bottom, Left, Right tolerances to guess the wm frame is
- * being grabbed (Top is traditionally bigger, i.e. titlebar):
- */
- if ((str = part[3]) != NULL) {
- int t, b, l, r;
- if (sscanf(str, "%d+%d+%d+%d", &t, &b, &l, &r) == 4) {
- wireframe_top = t;
- wireframe_bot = b;
- wireframe_left = l;
- wireframe_right = r;
- }
- free(str);
- }
-
- /*
- * wireframe in interior with Modifier down.
- * 0 => no mods
- * 1 => all mods
- * Shift,Alt,Control,Meta,Super,Hyper
- */
- if (wireframe_mods) {
- free(wireframe_mods);
- }
- wireframe_mods = NULL;
- if ((str = part[4]) != NULL) {
- if (*str == '0' || !strcmp(str, "none")) {
- ;
- } else if (*str == '1' || !strcmp(str, "all")) {
- wireframe_mods = strdup("all");
- } else if (!strcmp(str, "Alt") || !strcmp(str, "Shift")
- || !strcmp(str, "Control") || !strcmp(str, "Meta")
- || !strcmp(str, "Super") || !strcmp(str, "Hyper")) {
- wireframe_mods = strdup(str);
- }
- }
-
- /* check_wireframe() timing heuristics. */
- if ((str = part[5]) != NULL) {
- double t1, t2, t3, t4;
- if (sscanf(str, "%lf+%lf+%lf+%lf", &t1, &t2, &t3, &t4) == 4) {
- wireframe_t1 = t1;
- wireframe_t2 = t2;
- wireframe_t3 = t3;
- wireframe_t4 = t4;
- }
- free(str);
- }
-}
-
-/*
- * First parse the defaults and apply any user supplied ones (may be a subset)
- */
-void parse_wireframe(void) {
- parse_wireframe_str(WIREFRAME_PARMS);
- if (! wireframe_str) {
- wireframe_str = strdup(WIREFRAME_PARMS);
- }
- parse_wireframe_str(wireframe_str);
-}
-
-/*
- * Set wireframe_copyrect based on desired mode.
- */
-void set_wirecopyrect_mode(char *str) {
- char *orig = wireframe_copyrect;
- if (str == NULL || *str == '\0') {
- wireframe_copyrect = strdup(wireframe_copyrect_default);
- } else if (!strcmp(str, "always") || !strcmp(str, "all")) {
- wireframe_copyrect = strdup("always");
- } else if (!strcmp(str, "top")) {
- wireframe_copyrect = strdup("top");
- } else if (!strcmp(str, "never") || !strcmp(str, "none")) {
- wireframe_copyrect = strdup("never");
- } else {
- if (! wireframe_copyrect) {
- wireframe_copyrect = strdup(wireframe_copyrect_default);
- } else {
- orig = NULL;
- }
- rfbLog("unknown -wirecopyrect mode: %s, using: %s\n", str,
- wireframe_copyrect);
- }
- if (orig) {
- free(orig);
- }
-}
-
-/*
- * Set scroll_copyrect based on desired mode.
- */
-void set_scrollcopyrect_mode(char *str) {
- char *orig = scroll_copyrect;
- if (str == NULL || *str == '\0') {
- scroll_copyrect = strdup(scroll_copyrect_default);
- } else if (!strcmp(str, "always") || !strcmp(str, "all") ||
- !strcmp(str, "both")) {
- scroll_copyrect = strdup("always");
- } else if (!strcmp(str, "keys") || !strcmp(str, "keyboard")) {
- scroll_copyrect = strdup("keys");
- } else if (!strcmp(str, "mouse") || !strcmp(str, "pointer")) {
- scroll_copyrect = strdup("mouse");
- } else if (!strcmp(str, "never") || !strcmp(str, "none")) {
- scroll_copyrect = strdup("never");
- } else {
- if (! scroll_copyrect) {
- scroll_copyrect = strdup(scroll_copyrect_default);
- } else {
- orig = NULL;
- }
- rfbLog("unknown -scrollcopyrect mode: %s, using: %s\n", str,
- scroll_copyrect);
- }
- if (orig) {
- free(orig);
- }
-}
-
-void initialize_scroll_keys(void) {
- char *str, *p;
- int i, nkeys = 0, saw_builtin = 0;
- int ks_max = 2 * 0xFFFF;
-
- if (scroll_key_list) {
- free(scroll_key_list);
- scroll_key_list = NULL;
- }
- if (! scroll_key_list_str || *scroll_key_list_str == '\0') {
- return;
- }
-
- if (strstr(scroll_key_list_str, "builtin")) {
- int k;
- /* add in number of keysyms builtin gives */
- for (k=1; k<ks_max; k++) {
- if (xrecord_scroll_keysym((rfbKeySym) k)) {
- nkeys++;
- }
- }
- }
-
- nkeys++; /* first key, i.e. no commas. */
- p = str = strdup(scroll_key_list_str);
- while(*p) {
- if (*p == ',') {
- nkeys++; /* additional key. */
- }
- p++;
- }
-
- nkeys++; /* exclude/include 0 element */
- nkeys++; /* trailing NoSymbol */
-
- scroll_key_list = (KeySym *) malloc(nkeys*sizeof(KeySym));
- for (i=0; i<nkeys; i++) {
- scroll_key_list[i] = NoSymbol;
- }
- if (*str == '-') {
- scroll_key_list[0] = 1;
- p = strtok(str+1, ",");
- } else {
- p = strtok(str, ",");
- }
- i = 1;
- while (p) {
- if (!strcmp(p, "builtin")) {
- int k;
- if (saw_builtin) {
- p = strtok(NULL, ",");
- continue;
- }
- saw_builtin = 1;
- for (k=1; k<ks_max; k++) {
- if (xrecord_scroll_keysym((rfbKeySym) k)) {
- scroll_key_list[i++] = (rfbKeySym) k;
- }
- }
- } else {
- unsigned int in;
- if (sscanf(p, "%u", &in) == 1) {
- scroll_key_list[i++] = (rfbKeySym) in;
- } else if (sscanf(p, "0x%x", &in) == 1) {
- scroll_key_list[i++] = (rfbKeySym) in;
- } else if (XStringToKeysym(p) != NoSymbol) {
- scroll_key_list[i++] = XStringToKeysym(p);
- } else {
- rfbLog("initialize_scroll_keys: skip unknown "
- "keysym: %s\n", p);
- }
- }
- p = strtok(NULL, ",");
- }
- free(str);
-}
-
-static void destroy_str_list(char **list) {
- int i = 0;
- if (! list) {
- return;
- }
- while (list[i] != NULL) {
- free(list[i++]);
- }
- free(list);
-}
-
-void initialize_scroll_matches(void) {
- char *str, *imp = "__IMPOSSIBLE_STR__";
- int i, n, nkey, nmouse;
-
- destroy_str_list(scroll_good_all);
- scroll_good_all = NULL;
- destroy_str_list(scroll_good_key);
- scroll_good_key = NULL;
- destroy_str_list(scroll_good_mouse);
- scroll_good_mouse = NULL;
-
- destroy_str_list(scroll_skip_all);
- scroll_skip_all = NULL;
- destroy_str_list(scroll_skip_key);
- scroll_skip_key = NULL;
- destroy_str_list(scroll_skip_mouse);
- scroll_skip_mouse = NULL;
-
- /* scroll_good: */
- if (scroll_good_str != NULL && *scroll_good_str != '\0') {
- str = scroll_good_str;
- } else {
- str = scroll_good_str0;
- }
- scroll_good_all = create_str_list(str);
-
- nkey = 0;
- nmouse = 0;
- n = 0;
- while (scroll_good_all[n] != NULL) {
- char *s = scroll_good_all[n++];
- if (strstr(s, "KEY:") == s) nkey++;
- if (strstr(s, "MOUSE:") == s) nmouse++;
- }
- if (nkey++) {
- scroll_good_key = (char **) malloc(nkey*sizeof(char *));
- for (i=0; i<nkey; i++) scroll_good_key[i] = NULL;
- }
- if (nmouse++) {
- scroll_good_mouse = (char **) malloc(nmouse*sizeof(char *));
- for (i=0; i<nmouse; i++) scroll_good_mouse[i] = NULL;
- }
- nkey = 0;
- nmouse = 0;
- for (i=0; i<n; i++) {
- char *s = scroll_good_all[i];
- if (strstr(s, "KEY:") == s) {
- scroll_good_key[nkey++] = strdup(s+strlen("KEY:"));
- free(s);
- scroll_good_all[i] = strdup(imp);
- } else if (strstr(s, "MOUSE:") == s) {
- scroll_good_mouse[nmouse++]=strdup(s+strlen("MOUSE:"));
- free(s);
- scroll_good_all[i] = strdup(imp);
- }
- }
-
- /* scroll_skip: */
- if (scroll_skip_str != NULL && *scroll_skip_str != '\0') {
- str = scroll_skip_str;
- } else {
- str = scroll_skip_str0;
- }
- scroll_skip_all = create_str_list(str);
-
- nkey = 0;
- nmouse = 0;
- n = 0;
- while (scroll_skip_all[n] != NULL) {
- char *s = scroll_skip_all[n++];
- if (strstr(s, "KEY:") == s) nkey++;
- if (strstr(s, "MOUSE:") == s) nmouse++;
- }
- if (nkey++) {
- scroll_skip_key = (char **) malloc(nkey*sizeof(char *));
- for (i=0; i<nkey; i++) scroll_skip_key[i] = NULL;
- }
- if (nmouse++) {
- scroll_skip_mouse = (char **) malloc(nmouse*sizeof(char *));
- for (i=0; i<nmouse; i++) scroll_skip_mouse[i] = NULL;
- }
- nkey = 0;
- nmouse = 0;
- for (i=0; i<n; i++) {
- char *s = scroll_skip_all[i];
- if (strstr(s, "KEY:") == s) {
- scroll_skip_key[nkey++] = strdup(s+strlen("KEY:"));
- free(s);
- scroll_skip_all[i] = strdup(imp);
- } else if (strstr(s, "MOUSE:") == s) {
- scroll_skip_mouse[nmouse++]=strdup(s+strlen("MOUSE:"));
- free(s);
- scroll_skip_all[i] = strdup(imp);
- }
- }
-}
-
-void initialize_scroll_term(void) {
- char *str;
- int n;
-
- destroy_str_list(scroll_term);
- scroll_term = NULL;
-
- if (scroll_term_str != NULL && *scroll_term_str != '\0') {
- str = scroll_term_str;
- } else {
- str = scroll_term_str0;
- }
- if (!strcmp(str, "none")) {
- return;
- }
- scroll_term = create_str_list(str);
-
- n = 0;
- while (scroll_term[n] != NULL) {
- char *s = scroll_good_all[n++];
- /* pull parameters out at some point */
- s = NULL;
- }
-}
-
-void initialize_max_keyrepeat(void) {
- char *str;
- int lo, hi;
-
- if (max_keyrepeat_str != NULL && *max_keyrepeat_str != '\0') {
- str = max_keyrepeat_str;
- } else {
- str = max_keyrepeat_str0;
- }
-
- if (sscanf(str, "%d-%d", &lo, &hi) != 2) {
- rfbLog("skipping invalid -scr_keyrepeat string: %s\n", str);
- sscanf(max_keyrepeat_str0, "%d-%d", &lo, &hi);
- }
- max_keyrepeat_lo = lo;
- max_keyrepeat_hi = hi;
- if (max_keyrepeat_lo < 1) {
- max_keyrepeat_lo = 1;
- }
- if (max_keyrepeat_hi > 40) {
- max_keyrepeat_hi = 40;
- }
-}
-
-typedef struct saveline {
- int x0, y0, x1, y1;
- int shift;
- int vert;
- int saved;
- char *data;
-} saveline_t;
-
-/*
- * Draw the wireframe box onto the framebuffer. Saves the real
- * framebuffer data to some storage lines. Restores previous lines.
- * use restore = 1 to clean up (done with animation).
- * This works with -scale.
- */
-static void draw_box(int x, int y, int w, int h, int restore) {
- int x0, y0, x1, y1, i, pixelsize = bpp/8;
- char *dst, *src, *use_fb;
- static saveline_t *save[4];
- static int first = 1, len = 0;
- int max = dpy_x > dpy_y ? dpy_x : dpy_y;
- int use_Bpl, lw = wireframe_lw;
- unsigned long shade = wireframe_shade;
- int color = 0;
- unsigned short us = 0;
- unsigned long ul = 0;
-
- if (clipshift) {
- x -= coff_x;
- y -= coff_y;
- }
-
- /* handle -8to24 mode: use 2nd fb only */
- use_fb = main_fb;
- use_Bpl = main_bytes_per_line;
-
- if (cmap8to24 && cmap8to24_fb) {
- use_fb = cmap8to24_fb;
- pixelsize = 4;
- if (depth <= 8) {
- use_Bpl *= 4;
- } else if (depth <= 16) {
- use_Bpl *= 2;
- }
- }
-
- if (max > len) {
- /* create/resize storage lines: */
- for (i=0; i<4; i++) {
- len = max;
- if (! first && save[i]) {
- if (save[i]->data) {
- free(save[i]->data);
- save[i]->data = NULL;
- }
- free(save[i]);
- }
- save[i] = (saveline_t *) malloc(sizeof(saveline_t));
- save[i]->saved = 0;
- save[i]->data = (char *) malloc( (LW_MAX+1)*len*4 );
-
- /*
- * Four types of lines:
- * 0) top horizontal
- * 1) bottom horizontal
- * 2) left vertical
- * 3) right vertical
- *
- * shift means shifted by width or height.
- */
- if (i == 0) {
- save[i]->vert = 0;
- save[i]->shift = 0;
- } else if (i == 1) {
- save[i]->vert = 0;
- save[i]->shift = 1;
- } else if (i == 2) {
- save[i]->vert = 1;
- save[i]->shift = 0;
- } else if (i == 3) {
- save[i]->vert = 1;
- save[i]->shift = 1;
- }
- }
- }
- first = 0;
-
- /*
- * restore any saved lines. see below for algorithm and
- * how x0, etc. are used. we just reverse those steps.
- */
- for (i=0; i<4; i++) {
- int s = save[i]->shift;
- int yu, y_min = -1, y_max = -1;
- int y_start, y_stop, y_step;
-
- if (! save[i]->saved) {
- continue;
- }
- x0 = save[i]->x0;
- y0 = save[i]->y0;
- x1 = save[i]->x1;
- y1 = save[i]->y1;
- if (save[i]->vert) {
- y_start = y0+lw;
- y_stop = y1-lw;
- y_step = lw*pixelsize;
- } else {
- y_start = y0 - s*lw;
- y_stop = y_start + lw;
- y_step = max*pixelsize;
- }
- for (yu = y_start; yu < y_stop; yu++) {
- if (x0 == x1) {
- continue;
- }
- if (yu < 0 || yu >= dpy_y) {
- continue;
- }
- if (y_min < 0 || yu < y_min) {
- y_min = yu;
- }
- if (y_max < 0 || yu > y_max) {
- y_max = yu;
- }
- src = save[i]->data + (yu-y_start)*y_step;
- dst = use_fb + yu*use_Bpl + x0*pixelsize;
- memcpy(dst, src, (x1-x0)*pixelsize);
- }
- if (y_min >= 0) {
-if (0) fprintf(stderr, "Mark-1 %d %d %d %d\n", x0, y_min, x1, y_max+1);
- mark_rect_as_modified(x0, y_min, x1, y_max+1, 0);
- }
- save[i]->saved = 0;
- }
-
-if (0) fprintf(stderr, " DrawBox: %04dx%04d+%04d+%04d B=%d rest=%d lw=%d %.4f\n", w, h, x, y, 2*(w+h)*(2-restore)*pixelsize*lw, restore, lw, dnowx());
-
- if (restore) {
- return;
- }
-
-
- /*
- * work out shade/color for the wireframe line, could be a color
- * for 16bpp or 24bpp.
- */
- if (shade > 255) {
- if (pixelsize == 2) {
- us = (unsigned short) (shade & 0xffff);
- color = 1;
- } else if (pixelsize == 4) {
- ul = (unsigned long) shade;
- color = 1;
- } else {
- shade = shade % 256;
- }
- }
-
- for (i=0; i<4; i++) {
- int s = save[i]->shift;
- int yu, y_min = -1, y_max = -1;
- int yblack = -1, xblack1 = -1, xblack2 = -1;
- int y_start, y_stop, y_step;
-
- if (save[i]->vert) {
- /*
- * make the narrow x's be on the screen, let
- * the y's hang off (not drawn).
- */
- save[i]->x0 = x0 = nfix(x + s*w - s*lw, dpy_x);
- save[i]->y0 = y0 = y;
- save[i]->x1 = x1 = nfix(x + s*w - s*lw + lw, dpy_x);
- save[i]->y1 = y1 = y + h;
-
- /*
- * start and stop a linewidth away from true edge,
- * to avoid interfering with horizontal lines.
- */
- y_start = y0+lw;
- y_stop = y1-lw;
- y_step = lw*pixelsize;
-
- /* draw a black pixel for the border if lw > 1 */
- if (s) {
- xblack1 = x1-1;
- } else {
- xblack1 = x0;
- }
- } else {
- /*
- * make the wide x's be on the screen, let the y's
- * hang off (not drawn).
- */
- save[i]->x0 = x0 = nfix(x, dpy_x);
- save[i]->y0 = y0 = y + s*h;
- save[i]->x1 = x1 = nfix(x + w, dpy_x);
- save[i]->y1 = y1 = y0 + lw;
- y_start = y0 - s*lw;
- y_stop = y_start + lw;
- y_step = max*pixelsize;
-
- /* draw a black pixels for the border if lw > 1 */
- if (s) {
- yblack = y_stop - 1;
- } else {
- yblack = y_start;
- }
- xblack1 = x0;
- xblack2 = x1-1;
- }
-
- /* now loop over the allowed y's for either case */
- for (yu = y_start; yu < y_stop; yu++) {
- if (x0 == x1) {
- continue;
- }
- if (yu < 0 || yu >= dpy_y) {
- continue;
- }
-
- /* record min and max y's for marking rectangle: */
- if (y_min < 0 || yu < y_min) {
- y_min = yu;
- }
- if (y_max < 0 || yu > y_max) {
- y_max = yu;
- }
-
- /* save fb data for this line: */
- save[i]->saved = 1;
- src = use_fb + yu*use_Bpl + x0*pixelsize;
- dst = save[i]->data + (yu-y_start)*y_step;
- memcpy(dst, src, (x1-x0)*pixelsize);
-
- /* apply the shade/color to make the wireframe line: */
- if (! color) {
- memset(src, shade, (x1-x0)*pixelsize);
- } else {
- char *csrc = src;
- unsigned short *usp;
- unsigned long *ulp;
- int k;
- for (k=0; k < x1 - x0; k++) {
- if (pixelsize == 4) {
- ulp = (unsigned long *)csrc;
- *ulp = ul;
- } else if (pixelsize == 2) {
- usp = (unsigned short *)csrc;
- *usp = us;
- }
- csrc += pixelsize;
- }
- }
-
- /* apply black border for lw >= 2 */
- if (lw > 1) {
- if (yu == yblack) {
- memset(src, 0, (x1-x0)*pixelsize);
- }
- if (xblack1 >= 0) {
- src = src + (xblack1 - x0)*pixelsize;
- memset(src, 0, pixelsize);
- }
- if (xblack2 >= 0) {
- src = src + (xblack2 - x0)*pixelsize;
- memset(src, 0, pixelsize);
- }
- }
- }
- /* mark it for sending: */
- if (save[i]->saved) {
-if (0) fprintf(stderr, "Mark-2 %d %d %d %d\n", x0, y_min, x1, y_max+1);
- mark_rect_as_modified(x0, y_min, x1, y_max+1, 0);
- }
- }
-}
-
-int direct_fb_copy(int x1, int y1, int x2, int y2, int mark) {
- char *src, *dst;
- int y, pixelsize = bpp/8;
- int xmin = -1, xmax = -1, ymin = -1, ymax = -1;
- int do_cmp = 2;
- double tm;
- int db = 0;
-
-if (db) dtime0(&tm);
-
- x1 = nfix(x1, dpy_x);
- y1 = nfix(y1, dpy_y);
- x2 = nfix(x2, dpy_x+1);
- y2 = nfix(y2, dpy_y+1);
-
- if (x1 == x2) {
- return 1;
- }
- if (y1 == y2) {
- return 1;
- }
-
- X_LOCK;
- for (y = y1; y < y2; y++) {
- XRANDR_SET_TRAP_RET(0, "direct_fb_copy-set");
- copy_image(scanline, x1, y, x2 - x1, 1);
- XRANDR_CHK_TRAP_RET(0, "direct_fb_copy-chk");
-
- src = scanline->data;
- dst = main_fb + y * main_bytes_per_line + x1 * pixelsize;
-
- if (do_cmp == 0 || !mark) {
- memcpy(dst, src, (x2 - x1)*pixelsize);
-
- } else if (do_cmp == 1) {
- if (memcmp(dst, src, (x2 - x1)*pixelsize)) {
- if (ymin == -1 || y < ymin) {
- ymin = y;
- }
- if (ymax == -1 || y > ymax) {
- ymax = y;
- }
- memcpy(dst, src, (x2 - x1)*pixelsize);
- }
-
- } else if (do_cmp == 2) {
- int n, shift, xlo, xhi, k, block = 32;
- char *dst2, *src2;
-
- for (k=0; k*block < (x2 - x1); k++) {
- shift = k*block;
- xlo = x1 + shift;
- xhi = xlo + block;
- if (xhi > x2) {
- xhi = x2;
- }
- n = xhi - xlo;
- if (n < 1) {
- continue;
- }
- src2 = src + shift*pixelsize;
- dst2 = dst + shift*pixelsize;
- if (memcmp(dst2, src2, n*pixelsize)) {
- if (ymin == -1 || y < ymin) {
- ymin = y;
- }
- if (ymax == -1 || y > ymax) {
- ymax = y;
- }
- if (xmin == -1 || xlo < xmin) {
- xmin = xlo;
- }
- if (xmax == -1 || xhi > xmax) {
- xmax = xhi;
- }
- memcpy(dst2, src2, n*pixelsize);
- }
- }
- }
- }
- X_UNLOCK;
-
- if (do_cmp == 0) {
- xmin = x1;
- ymin = y1;
- xmax = x2;
- ymax = y2;
- } else if (do_cmp == 1) {
- xmin = x1;
- xmax = x2;
- }
-
- if (xmin < 0 || ymin < 0 || xmax < 0 || xmin < 0) {
- /* no diffs */
- return 1;
- }
-
- if (xmax < x2) {
- xmax++;
- }
- if (ymax < y2) {
- ymax++;
- }
-
- if (mark) {
- mark_rect_as_modified(xmin, ymin, xmax, ymax, 0);
- }
-
- if (db) {
- fprintf(stderr, "direct_fb_copy: %dx%d+%d+%d - %d %.4f\n",
- x2 - x1, y2 - y1, x1, y1, mark, dtime(&tm));
- }
-
- return 1;
-}
-
-static int do_bdpush(Window wm_win, int x0, int y0, int w0, int h0, int bdx,
- int bdy, int bdskinny) {
-
- XWindowAttributes attr;
- sraRectangleIterator *iter;
- sraRect rect;
- sraRegionPtr frame, whole, tmpregion;
- int tx1, ty1, tx2, ty2;
- static Window last_wm_win = None;
- static int last_x, last_y, last_w, last_h;
- int do_fb_push = 0;
- int db = debug_scroll;
-
- if (wm_win == last_wm_win) {
- attr.x = last_x;
- attr.y = last_y;
- attr.width = last_w;
- attr.height = last_h;
- } else {
- if (!valid_window(wm_win, &attr, 1)) {
- return do_fb_push;
- }
- last_wm_win = wm_win;
- last_x = attr.x;
- last_y = attr.y;
- last_w = attr.width;
- last_h = attr.height;
- }
-if (db > 1) fprintf(stderr, "BDP %d %d %d %d %d %d %d %d %d %d %d\n",
- x0, y0, w0, h0, bdx, bdy, bdskinny, last_x, last_y, last_w, last_h);
-
- /* wm frame: */
- tx1 = attr.x;
- ty1 = attr.y;
- tx2 = attr.x + attr.width;
- ty2 = attr.y + attr.height;
-
- whole = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- if (clipshift) {
- sraRgnOffset(whole, coff_x, coff_y);
- }
- if (subwin) {
- sraRgnOffset(whole, off_x, off_y);
- }
- frame = sraRgnCreateRect(tx1, ty1, tx2, ty2);
- sraRgnAnd(frame, whole);
-
- /* scrolling window: */
- tmpregion = sraRgnCreateRect(x0, y0, x0 + w0, y0 + h0);
- sraRgnAnd(tmpregion, whole);
-
- sraRgnSubtract(frame, tmpregion);
- sraRgnDestroy(tmpregion);
-
- if (!sraRgnEmpty(frame)) {
- double dt = 0.0, dm;
- dtime0(&dm);
- iter = sraRgnGetIterator(frame);
- while (sraRgnIteratorNext(iter, &rect)) {
- tx1 = rect.x1;
- ty1 = rect.y1;
- tx2 = rect.x2;
- ty2 = rect.y2;
-
- if (bdskinny > 0) {
- int ok = 0;
- if (nabs(ty2-ty1) <= bdskinny) {
- ok = 1;
- }
- if (nabs(tx2-tx1) <= bdskinny) {
- ok = 1;
- }
- if (! ok) {
- continue;
- }
- }
-
- if (bdx >= 0) {
- if (bdx < tx1 || tx2 <= bdx) {
- continue;
- }
- }
- if (bdy >= 0) {
- if (bdy < ty1 || ty2 <= bdy) {
- continue;
- }
- }
- if (clipshift) {
- tx1 -= coff_x;
- ty1 -= coff_y;
- tx2 -= coff_x;
- ty2 -= coff_y;
- }
- if (subwin) {
- tx1 -= off_x;
- ty1 -= off_y;
- tx2 -= off_x;
- ty2 -= off_y;
- }
-
- direct_fb_copy(tx1, ty1, tx2, ty2, 1);
-
- do_fb_push++;
- dt += dtime(&dm);
-if (db > 1) fprintf(stderr, " BDP(%d,%d-%d,%d) dt: %.4f\n", tx1, ty1, tx2, ty2, dt);
- }
- sraRgnReleaseIterator(iter);
- }
- sraRgnDestroy(whole);
- sraRgnDestroy(frame);
-
- return do_fb_push;
-}
-
-static int set_ypad(void) {
- int ev, ev_tot = scr_ev_cnt;
- static Window last_win = None;
- static double last_time = 0.0;
- static int y_accum = 0, last_sign = 0;
- double now, cut = 0.1;
- int dy_sum = 0, ys = 0, sign;
- int font_size = 15;
- int win_y, scr_y, loc_cut = 4*font_size, y_cut = 10*font_size;
-
- if (!xrecord_set_by_keys || !xrecord_name_info) {
- return 0;
- }
- if (xrecord_name_info[0] == '\0') {
- return 0;
- }
- if (! ev_tot) {
- return 0;
- }
- if (xrecord_keysym == NoSymbol) {
- return 0;
- }
- if (!xrecord_scroll_keysym(xrecord_keysym)) {
- return 0;
- }
- if (!scroll_term) {
- return 0;
- }
- if (!match_str_list(xrecord_name_info, scroll_term)) {
- return 0;
- }
-
- for (ev=0; ev < ev_tot; ev++) {
- dy_sum += nabs(scr_ev[ev].dy);
- if (scr_ev[ev].dy < 0) {
- ys--;
- } else if (scr_ev[ev].dy > 0) {
- ys++;
- } else {
- ys = 0;
- break;
- }
- if (scr_ev[ev].win != scr_ev[0].win) {
- ys = 0;
- break;
- }
- if (scr_ev[ev].dx != 0) {
- ys = 0;
- break;
- }
- }
- if (ys != ev_tot && ys != -ev_tot) {
- return 0;
- }
- if (ys < 0) {
- sign = -1;
- } else {
- sign = 1;
- }
-
- if (sign > 0) {
- /*
- * this case is not as useful as scrolling near the
- * bottom of a terminal. But there are problems for it too.
- */
- return 0;
- }
-
- win_y = scr_ev[0].win_y + scr_ev[0].win_h;
- scr_y = scr_ev[0].y + scr_ev[0].h;
- if (nabs(scr_y - win_y) > loc_cut) {
- /* require it to be near the bottom. */
- return 0;
- }
-
- now = dnow();
-
- if (now < last_time + cut) {
- int ok = 1;
- if (last_win && scr_ev[0].win != last_win) {
- ok = 0;
- }
- if (last_sign && sign != last_sign) {
- ok = 0;
- }
- if (! ok) {
- last_win = None;
- last_sign = 0;
- y_accum = 0;
- last_time = 0.0;
- return 0;
- }
- } else {
- last_win = None;
- last_sign = 0;
- last_time = 0.0;
- y_accum = 0;
- }
-
- y_accum += sign * dy_sum;
-
- if (4 * nabs(y_accum) > scr_ev[0].h && y_cut) {
- ; /* TBD */
- }
-
- last_sign = sign;
- last_win = scr_ev[0].win;
- last_time = now;
-
- return y_accum;
-}
-
-static void scale_mark(int x1, int y1, int x2, int y2, int mark) {
- int s = 2;
- x1 = nfix(x1 - s, dpy_x);
- y1 = nfix(y1 - s, dpy_y);
- x2 = nfix(x2 + s, dpy_x+1);
- y2 = nfix(y2 + s, dpy_y+1);
- scale_and_mark_rect(x1, y1, x2, y2, mark);
-}
-
-#define PUSH_TEST(n) \
-if (n) { \
- double dt = 0.0, tm; dtime0(&tm); \
- fprintf(stderr, "PUSH---\n"); \
- while (dt < 2.0) { rfbPE(50000); dt += dtime(&tm); } \
- fprintf(stderr, "---PUSH\n"); \
-}
-
-int batch_dxs[], batch_dys[];
-sraRegionPtr batch_reg[];
-void batch_push(int ncr, double delay);
-
-static int push_scr_ev(double *age, int type, int bdpush, int bdx, int bdy,
- int bdskinny, int first_push) {
- Window frame, win, win0;
- int x, y, w, h, wx, wy, ww, wh, dx, dy;
- int x0, y0, w0, h0;
- int nx, ny, nw, nh;
- int dret = 1, do_fb_push = 0, obscured;
- int ev, ev_tot = scr_ev_cnt;
- double tm, dt, st, waittime = 0.125;
- double max_age = *age;
- int db = debug_scroll, rrate = get_read_rate();
- sraRegionPtr backfill, whole, tmpregion, tmpregion2;
- int link, latency, netrate;
- int ypad = 0;
- double last_scroll_event_save = last_scroll_event;
- int fast_push = 0, rc;
-
- /* we return the oldest one. */
- *age = 0.0;
-
- if (ev_tot == 0) {
- return dret;
- }
-
- link = link_rate(&latency, &netrate);
-
- if (link == LR_DIALUP) {
- waittime *= 5;
- } else if (link == LR_BROADBAND) {
- waittime *= 3;
- } else if (latency > 80 || netrate < 40) {
- waittime *= 3;
- }
-
- backfill = sraRgnCreate();
- whole = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- if (clipshift) {
- sraRgnOffset(whole, coff_x, coff_y);
- }
- if (subwin) {
- sraRgnOffset(whole, off_x, off_y);
- }
-
- win0 = scr_ev[0].win;
- x0 = scr_ev[0].win_x;
- y0 = scr_ev[0].win_y;
- w0 = scr_ev[0].win_w;
- h0 = scr_ev[0].win_h;
-
- ypad = set_ypad();
-
-if (db) fprintf(stderr, "ypad: %d dy[0]: %d ev_tot: %d\n", ypad, scr_ev[0].dy, ev_tot);
-
- for (ev=0; ev < ev_tot; ev++) {
- double ag;
-
- x = scr_ev[ev].x;
- y = scr_ev[ev].y;
- w = scr_ev[ev].w;
- h = scr_ev[ev].h;
- dx = scr_ev[ev].dx;
- dy = scr_ev[ev].dy;
- win = scr_ev[ev].win;
- wx = scr_ev[ev].win_x;
- wy = scr_ev[ev].win_y;
- ww = scr_ev[ev].win_w;
- wh = scr_ev[ev].win_h;
- nx = scr_ev[ev].new_x;
- ny = scr_ev[ev].new_y;
- nw = scr_ev[ev].new_w;
- nh = scr_ev[ev].new_h;
- st = scr_ev[ev].t;
-
- ag = (dnow() - servertime_diff) - st;
- if (ag > *age) {
- *age = ag;
- }
-
- if (dabs(ag) > max_age) {
-if (db) fprintf(stderr, "push_scr_ev: TOO OLD: %.4f :: (%.4f - %.4f) "
- "- %.4f \n", ag, dnow(), servertime_diff, st);
- dret = 0;
- break;
- } else {
-if (db) fprintf(stderr, "push_scr_ev: AGE: %.4f\n", ag);
- }
- if (win != win0) {
-if (db) fprintf(stderr, "push_scr_ev: DIFF WIN: 0x%lx != 0x%lx\n", win, win0);
- dret = 0;
- break;
- }
- if (wx != x0 || wy != y0) {
-if (db) fprintf(stderr, "push_scr_ev: WIN SHIFT: %d %d, %d %d", wx, x0, wy, y0);
- dret = 0;
- break;
- }
- if (ww != w0 || wh != h0) {
-if (db) fprintf(stderr, "push_scr_ev: WIN RESIZE: %d %d, %d %d", ww, w0, wh, h0);
- dret = 0;
- break;
- }
- if (w < 1 || h < 1 || ww < 1 || wh < 1) {
-if (db) fprintf(stderr, "push_scr_ev: NEGATIVE h/w: %d %d %d %d\n", w, h, ww, wh);
- dret = 0;
- break;
- }
-
-if (db > 1) fprintf(stderr, "push_scr_ev: got: %d x: %4d y: %3d"
- " w: %4d h: %3d dx: %d dy: %d %dx%d+%d+%d win: 0x%lx\n",
- ev, x, y, w, h, dx, dy, w, h, x, y, win);
-
-if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d"
- " w: %4d h: %3d %dx%d+%d+%d\n",
- ev, wx, wy, ww, wh, ww, wh, wx, wy);
-
-if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d"
- " w: %4d h: %3d %dx%d+%d+%d\n",
- ev, nx, ny, nw, nh, nw, nh, nx, ny);
-
- frame = None;
- if (xrecord_wm_window) {
- frame = xrecord_wm_window;
- }
- if (! frame) {
- X_LOCK;
- frame = query_pointer(rootwin);
- X_UNLOCK;
- }
- if (! frame) {
- frame = win;
- }
-
- dtime0(&tm);
-
- tmpregion = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- if (clipshift) {
- sraRgnOffset(tmpregion, coff_x, coff_y);
- }
- if (subwin) {
- sraRgnOffset(tmpregion, off_x, off_y);
- }
- tmpregion2 = sraRgnCreateRect(wx, wy, wx+ww, wy+wh);
- sraRgnAnd(tmpregion2, whole);
- sraRgnSubtract(tmpregion, tmpregion2);
- sraRgnDestroy(tmpregion2);
-
- /* do the wm frame just incase the above is bogus too. */
- if (frame && frame != win) {
- int k, gotk = -1;
- for (k = stack_list_num - 1; k >= 0; k--) {
- if (stack_list[k].win == frame &&
- stack_list[k].fetched &&
- stack_list[k].valid &&
- stack_list[k].map_state == IsViewable) {
- gotk = k;
- break;
- }
- }
- if (gotk != -1) {
- int tx1, ty1, tx2, ty2;
- tx1 = stack_list[gotk].x;
- ty1 = stack_list[gotk].y;
- tx2 = tx1 + stack_list[gotk].width;
- ty2 = ty1 + stack_list[gotk].height;
- tmpregion2 = sraRgnCreateRect(tx1,ty1,tx2,ty2);
- sraRgnAnd(tmpregion2, whole);
- sraRgnSubtract(tmpregion, tmpregion2);
- sraRgnDestroy(tmpregion2);
- }
- }
-
- /*
- * XXX Need to also clip:
- * children of win
- * siblings of win higher in stacking order.
- * ignore for now... probably will make some apps
- * act very strangely.
- */
- if (ypad) {
- if (ypad < 0) {
- if (h > -ypad) {
- h += ypad;
- } else {
- ypad = 0;
- }
- } else {
- if (h > ypad) {
- y += ypad;
- } else {
- ypad = 0;
- }
- }
- }
-
- if (fast_push) {
- int nbatch = 0;
- double delay, d1 = 0.1, d2 = 0.02;
- rc = try_copyrect(frame, frame, x, y, w, h, dx, dy, &obscured,
- tmpregion, waittime, &nbatch);
-
- if (first_push) {
- delay = d1;
- } else {
- delay = d2;
- }
-
- batch_push(nbatch, delay);
- fb_push();
- } else {
- rc = try_copyrect(frame, frame, x, y, w, h, dx, dy, &obscured,
- tmpregion, waittime, NULL);
- if (rc) {
- last_scroll_type = type;
- dtime0(&last_scroll_event);
-
- do_fb_push++;
- urgent_update = 1;
- sraRgnDestroy(tmpregion);
-PUSH_TEST(0);
- }
- }
-
- if (! rc) {
- dret = 0;
- sraRgnDestroy(tmpregion);
- break;
- }
- dt = dtime(&tm);
-if (0) fprintf(stderr, " try_copyrect dt: %.4f\n", dt);
-
- if (ev > 0) {
- sraRgnOffset(backfill, dx, dy);
- sraRgnAnd(backfill, whole);
- }
-
- if (ypad) {
- if (ypad < 0) {
- ny += ypad;
- nh -= ypad;
- } else {
- ;
- }
- }
-
- tmpregion = sraRgnCreateRect(nx, ny, nx + nw, ny + nh);
- sraRgnAnd(tmpregion, whole);
- sraRgnOr(backfill, tmpregion);
- sraRgnDestroy(tmpregion);
- }
-
- /* try to update the backfill region (new window contents) */
- if (dret != 0) {
- double est, win_area = 0.0, area = 0.0;
- sraRectangleIterator *iter;
- sraRect rect;
- int tx1, ty1, tx2, ty2;
-
- tmpregion = sraRgnCreateRect(x0, y0, x0 + w0, y0 + h0);
- sraRgnAnd(tmpregion, whole);
-
- sraRgnAnd(backfill, tmpregion);
-
- iter = sraRgnGetIterator(tmpregion);
- while (sraRgnIteratorNext(iter, &rect)) {
- tx1 = rect.x1;
- ty1 = rect.y1;
- tx2 = rect.x2;
- ty2 = rect.y2;
-
- win_area += (tx2 - tx1)*(ty2 - ty1);
- }
- sraRgnReleaseIterator(iter);
-
- sraRgnDestroy(tmpregion);
-
-
- iter = sraRgnGetIterator(backfill);
- while (sraRgnIteratorNext(iter, &rect)) {
- tx1 = rect.x1;
- ty1 = rect.y1;
- tx2 = rect.x2;
- ty2 = rect.y2;
-
- area += (tx2 - tx1)*(ty2 - ty1);
- }
- sraRgnReleaseIterator(iter);
-
- est = (area * (bpp/8)) / (1000000.0 * rrate);
-if (db) fprintf(stderr, " area %.1f win_area %.1f est: %.4f", area, win_area, est);
- if (area > 0.90 * win_area) {
-if (db) fprintf(stderr, " AREA_TOO_MUCH");
- dret = 0;
- } else if (est > 0.6) {
-if (db) fprintf(stderr, " EST_TOO_LARGE");
- dret = 0;
- } else if (area <= 0.0) {
- ;
- } else {
- dtime0(&tm);
- iter = sraRgnGetIterator(backfill);
- while (sraRgnIteratorNext(iter, &rect)) {
- tx1 = rect.x1;
- ty1 = rect.y1;
- tx2 = rect.x2;
- ty2 = rect.y2;
-
- if (clipshift) {
- tx1 -= coff_x;
- ty1 -= coff_y;
- tx2 -= coff_x;
- ty2 -= coff_y;
- }
- if (subwin) {
- tx1 -= off_x;
- ty1 -= off_y;
- tx2 -= off_x;
- ty2 -= off_y;
- }
- tx1 = nfix(tx1, dpy_x);
- ty1 = nfix(ty1, dpy_y);
- tx2 = nfix(tx2, dpy_x+1);
- ty2 = nfix(ty2, dpy_y+1);
-
- dtime(&tm);
-if (db) fprintf(stderr, " DFC(%d,%d-%d,%d)", tx1, ty1, tx2, ty2);
- direct_fb_copy(tx1, ty1, tx2, ty2, 1);
- if (fast_push) {
- fb_push();
- }
- do_fb_push++;
-PUSH_TEST(0);
- }
- sraRgnReleaseIterator(iter);
-
- dt = dtime(&tm);
-if (db) fprintf(stderr, " dfc---- dt: %.4f", dt);
-
- }
-if (db && dret) fprintf(stderr, " **** dret=%d", dret);
-if (db && !dret) fprintf(stderr, " ---- dret=%d", dret);
-if (db) fprintf(stderr, "\n");
- }
-
-if (db && bdpush) fprintf(stderr, "BDPUSH-TIME: 0x%lx\n", xrecord_wm_window);
-
- if (bdpush && xrecord_wm_window != None) {
- int x, y, w, h;
- x = scr_ev[0].x;
- y = scr_ev[0].y;
- w = scr_ev[0].w;
- h = scr_ev[0].h;
- do_fb_push += do_bdpush(xrecord_wm_window, x, y, w, h,
- bdx, bdy, bdskinny);
- if (fast_push) {
- fb_push();
- }
- }
-
- if (do_fb_push) {
- dtime0(&tm);
- fb_push();
- dt = dtime(&tm);
-if (0) fprintf(stderr, " fb_push dt: %.4f", dt);
- if (scaling) {
- static double last_time = 0.0;
- double now = dnow(), delay = 0.4, first_wait = 3.0;
- double trate;
- int repeating, lat, rate;
- int link = link_rate(&lat, &rate);
- int skip_first = 0;
-
- if (link == LR_DIALUP || rate < 35) {
- delay *= 4;
- } else if (link != LR_LAN || rate < 100) {
- delay *= 2;
- }
-
- trate = typing_rate(0.0, &repeating);
-
- if (xrecord_set_by_mouse || repeating >= 3) {
- if (now > last_scroll_event_save + first_wait) {
- skip_first = 1;
- }
- }
-
- if (skip_first) {
- /*
- * try not to send the first one, but a
- * single keystroke scroll would be OK.
- */
- } else if (now > last_time + delay) {
-
- scale_mark(x0, y0, x0 + w0, y0 + h0, 1);
- last_copyrect_fix = now;
- }
- last_time = now;
- }
- }
-
- sraRgnDestroy(backfill);
- sraRgnDestroy(whole);
- return dret;
-}
-
-static void get_client_regions(int *req, int *mod, int *cpy, int *num) {
-
- rfbClientIteratorPtr i;
- rfbClientPtr cl;
-
- *req = 0;
- *mod = 0;
- *cpy = 0;
- *num = 0;
-
- i = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(i)) ) {
- if (use_threads) LOCK(cl->updateMutex);
- *req += sraRgnCountRects(cl->requestedRegion);
- *mod += sraRgnCountRects(cl->modifiedRegion);
- *cpy += sraRgnCountRects(cl->copyRegion);
- *num += 1;
- if (use_threads) UNLOCK(cl->updateMutex);
- }
- rfbReleaseClientIterator(i);
-}
-
-/*
- * Wrapper to apply the rfbDoCopyRegion taking into account if scaling
- * is being done. Note that copyrect under the scaling case is often
- * only approximate.
- */
-int DCR_Normal = 0;
-int DCR_FBOnly = 1;
-int DCR_Direct = 2;
-
-void do_copyregion(sraRegionPtr region, int dx, int dy, int mode) {
- sraRectangleIterator *iter;
- sraRect rect;
- int Bpp0 = bpp/8, Bpp;
- int x1, y1, x2, y2, w, stride, stride0;
- int sx1, sy1, sx2, sy2, sdx, sdy;
- int req, mod, cpy, ncli;
- char *dst = NULL, *src = NULL;
-
- last_copyrect = dnow();
-
- if (rfb_fb == main_fb && ! rotating && mode == DCR_Normal) {
- /* normal case, no -scale or -8to24 */
- get_client_regions(&req, &mod, &cpy, &ncli);
-if (0 || debug_scroll > 1) fprintf(stderr, ">>>-rfbDoCopyRect req: %d mod: %d cpy: %d\n", req, mod, cpy);
-
- rfbDoCopyRegion(screen, region, dx, dy);
-
- get_client_regions(&req, &mod, &cpy, &ncli);
-if (0 || debug_scroll > 1) fprintf(stderr, "<<<-rfbDoCopyRect req: %d mod: %d cpy: %d\n", req, mod, cpy);
-
- return;
- }
-
- /* rarer case, we need to call rfbDoCopyRect with scaled xy */
- stride0 = dpy_x * Bpp0;
-
- iter = sraRgnGetReverseIterator(region, dx < 0, dy < 0);
- while(sraRgnIteratorNext(iter, &rect)) {
- int j, c, t;
-
- x1 = rect.x1;
- y1 = rect.y1;
- x2 = rect.x2;
- y2 = rect.y2;
-
- for (c= 0; c < 2; c++) {
-
- Bpp = Bpp0;
- stride = stride0;
-
- if (c == 0) {
- dst = main_fb + y1*stride + x1*Bpp;
- src = main_fb + (y1-dy)*stride + (x1-dx)*Bpp;
-
- } else if (c == 1) {
- if (!cmap8to24 || !cmap8to24_fb) {
- continue;
- }
- if (cmap8to24_fb == rfb_fb) {
- if (mode == DCR_FBOnly) {
- ;
- } else if (mode == DCR_Direct) {
- ;
- } else if (mode == DCR_Normal) {
- continue;
- }
- }
-if (0) fprintf(stderr, "copyrect: cmap8to24_fb: mode=%d\n", mode);
- if (cmap8to24) {
- if (depth <= 8) {
- Bpp = 4 * Bpp0;
- stride = 4 * stride0;
- } else if (depth <= 16) {
- Bpp = 2 * Bpp0;
- stride = 2 * stride0;
- }
- }
- dst = cmap8to24_fb + y1*stride + x1*Bpp;
- src = cmap8to24_fb + (y1-dy)*stride + (x1-dx)*Bpp;
- }
-
- w = (x2 - x1)*Bpp;
-
- if (dy < 0) {
- for (j=y1; j<y2; j++) {
- memmove(dst, src, w);
- dst += stride;
- src += stride;
- }
- } else {
- dst += (y2 - y1 - 1)*stride;
- src += (y2 - y1 - 1)*stride;
- for (j=y2-1; j>=y1; j--) {
- memmove(dst, src, w);
- dst -= stride;
- src -= stride;
- }
- }
- }
-
- if (mode == DCR_FBOnly) {
- continue;
- }
-
-
- if (scaling) {
- sx1 = ((double) x1 / dpy_x) * scaled_x;
- sy1 = ((double) y1 / dpy_y) * scaled_y;
- sx2 = ((double) x2 / dpy_x) * scaled_x;
- sy2 = ((double) y2 / dpy_y) * scaled_y;
- sdx = ((double) dx / dpy_x) * scaled_x;
- sdy = ((double) dy / dpy_y) * scaled_y;
- } else {
- sx1 = x1;
- sy1 = y1;
- sx2 = x2;
- sy2 = y2;
- sdx = dx;
- sdy = dy;
- }
-if (0) fprintf(stderr, "sa.. %d %d %d %d %d %d\n", sx1, sy1, sx2, sy2, sdx, sdy);
-
- if (rotating) {
- rotate_coords(sx1, sy1, &sx1, &sy1, -1, -1);
- rotate_coords(sx2, sy2, &sx2, &sy2, -1, -1);
- if (rotating == ROTATE_X) {
- sdx = -sdx;
- } else if (rotating == ROTATE_Y) {
- sdy = -sdy;
- } else if (rotating == ROTATE_XY) {
- sdx = -sdx;
- sdy = -sdy;
- } else if (rotating == ROTATE_90) {
- t = sdx;
- sdx = -sdy;
- sdy = t;
- } else if (rotating == ROTATE_90X) {
- t = sdx;
- sdx = sdy;
- sdy = t;
- } else if (rotating == ROTATE_90Y) {
- t = sdx;
- sdx = -sdy;
- sdy = -t;
- } else if (rotating == ROTATE_270) {
- t = sdx;
- sdx = sdy;
- sdy = -t;
- }
- }
-
- /* XXX -1? */
- if (sx2 < 0) sx2 = 0;
- if (sy2 < 0) sy2 = 0;
-
- if (sx2 < sx1) {
- t = sx1;
- sx1 = sx2;
- sx2 = t;
- }
- if (sy2 < sy1) {
- t = sy1;
- sy1 = sy2;
- sy2 = t;
- }
-if (0) fprintf(stderr, "sb.. %d %d %d %d %d %d\n", sx1, sy1, sx2, sy2, sdx, sdy);
-
- if (mode == DCR_Direct) {
- rfbClientIteratorPtr i;
- rfbClientPtr cl;
- sraRegionPtr r = sraRgnCreateRect(sx1, sy1, sx2, sy2);
-
- i = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(i)) ) {
- if (use_threads) LOCK(cl->updateMutex);
- rfbSendCopyRegion(cl, r, sdx, sdy);
- if (use_threads) UNLOCK(cl->updateMutex);
- }
- rfbReleaseClientIterator(i);
- sraRgnDestroy(r);
-
- } else {
- rfbDoCopyRect(screen, sx1, sy1, sx2, sy2, sdx, sdy);
- }
- }
- sraRgnReleaseIterator(iter);
-}
-
-void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double delay) {
- rfbClientIteratorPtr i;
- rfbClientPtr cl;
- int k, direct, mode, nrects = 0, bad = 0;
- double t1, t2, start = dnow();
-
- for (k=0; k < ncr; k++) {
- sraRectangleIterator *iter;
- sraRect rect;
-
- iter = sraRgnGetIterator(region[k]);
- while (sraRgnIteratorNext(iter, &rect)) {
- int x1 = rect.x1;
- int y1 = rect.y1;
- int x2 = rect.x2;
- int y2 = rect.y2;
- int ym = dpy_y * (ncache+1);
- int xm = dpy_x;
- if (x1 > xm || y1 > ym || x2 > xm || y2 > ym) {
- if (ncdb) fprintf(stderr, "batch_copyregion: BAD RECTANGLE: %d,%d %d,%d\n", x1, y1, x2, y2);
- bad = 1;
- }
- if (x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0) {
- if (ncdb) fprintf(stderr, "batch_copyregion: BAD RECTANGLE: %d,%d %d,%d\n", x1, y1, x2, y2);
- bad = 1;
- }
- }
- sraRgnReleaseIterator(iter);
- nrects += sraRgnCountRects(region[k]);
- }
- if (bad || nrects == 0) {
- return;
- }
-
- if (delay < 0.0) {
- delay = 0.1;
- }
- if (!fb_push_wait(delay, FB_COPY|FB_MOD)) {
- if (use_threads) usleep(100 * 1000);
- fb_push_wait(0.75, FB_COPY|FB_MOD);
- }
-
- t1 = dnow();
-
- bad = 0;
- i = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(i)) ) {
-
- if (use_threads) LOCK(cl->updateMutex);
-
- if (cl->ublen != 0) {
- fprintf(stderr, "batch_copyregion: *** BAD ublen != 0: %d\n", cl->ublen);
- bad++;
- }
-
- if (use_threads) UNLOCK(cl->updateMutex);
- }
- rfbReleaseClientIterator(i);
-
- if (bad) {
- return;
- }
-
- i = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(i)) ) {
- rfbFramebufferUpdateMsg *fu;
-
- if (use_threads) LOCK(cl->updateMutex);
-
- fu = (rfbFramebufferUpdateMsg *)cl->updateBuf;
- fu->nRects = Swap16IfLE((uint16_t)(nrects));
- fu->type = rfbFramebufferUpdate;
-
- if (cl->ublen != 0) fprintf(stderr, "batch_copyregion: *** BAD-2 ublen != 0: %d\n", cl->ublen);
-
- cl->ublen = sz_rfbFramebufferUpdateMsg;
-
- if (use_threads) UNLOCK(cl->updateMutex);
- }
- rfbReleaseClientIterator(i);
-
- if (rfb_fb == main_fb && !rotating) {
- direct = 0;
- mode = DCR_FBOnly;
- } else {
- direct = 1;
- mode = DCR_Direct;
- }
- for (k=0; k < ncr; k++) {
- do_copyregion(region[k], dx[k], dy[k], mode);
- }
-
- t2 = dnow();
-
- i = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(i)) ) {
-
- if (use_threads) LOCK(cl->updateMutex);
-
- if (!direct) {
- for (k=0; k < ncr; k++) {
- rfbSendCopyRegion(cl, region[k], dx[k], dy[k]);
- }
- }
- rfbSendUpdateBuf(cl);
-
- if (use_threads) UNLOCK(cl->updateMutex);
- }
- rfbReleaseClientIterator(i);
-
- last_copyrect = dnow();
-
-if (0) fprintf(stderr, "batch_copyregion: nrects: %d nregions: %d tot=%.4f t10=%.4f t21=%.4f t32=%.4f %.4f\n",
- nrects, ncr, last_copyrect - start, t1 - start, t2 - t1, last_copyrect - t2, dnowx());
-
-}
-
-void batch_push(int nreg, double delay) {
- int k;
- batch_copyregion(batch_reg, batch_dxs, batch_dys, nreg, delay);
- /* XXX Y */
- fb_push();
- for (k=0; k < nreg; k++) {
- sraRgnDestroy(batch_reg[k]);
- }
-}
-
-void fb_push(void) {
- int req0, mod0, cpy0, req1, mod1, cpy1, ncli;
- int db = (debug_scroll || debug_wireframe);
- rfbClientIteratorPtr i;
- rfbClientPtr cl;
-
- if (use_threads) {
- return;
- }
-
-if (db) get_client_regions(&req0, &mod0, &cpy0, &ncli);
-
- i = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(i)) ) {
- if (use_threads) LOCK(cl->updateMutex);
- if (cl->sock >= 0 && !cl->onHold && FB_UPDATE_PENDING(cl) &&
- !sraRgnEmpty(cl->requestedRegion)) {
- if (!rfbSendFramebufferUpdate(cl, cl->modifiedRegion)) {
- fprintf(stderr, "*** rfbSendFramebufferUpdate *FAILED* #1\n");
- if (cl->ublen) fprintf(stderr, "*** fb_push ublen not zero: %d\n", cl->ublen);
- if (use_threads) UNLOCK(cl->updateMutex);
- break;
- }
- if (cl->ublen) fprintf(stderr, "*** fb_push ublen NOT ZERO: %d\n", cl->ublen);
- }
- if (use_threads) UNLOCK(cl->updateMutex);
- }
- rfbReleaseClientIterator(i);
-
-if (db) {
- get_client_regions(&req1, &mod1, &cpy1, &ncli);
- fprintf(stderr, "\nFB_push: req: %d/%d mod: %d/%d cpy: %d/%d %.4f\n",
- req0, req1, mod0, mod1, cpy0, cpy1, dnowx());
-}
-
-}
-
-int fb_push_wait(double max_wait, int flags) {
- double tm, dt = 0.0;
- int req, mod, cpy, ncli;
- int ok = 0, first = 1;
-
- dtime0(&tm);
- while (dt < max_wait) {
- int done = 1;
- fb_push();
- get_client_regions(&req, &mod, &cpy, &ncli);
- if (flags & FB_COPY && cpy) {
- done = 0;
- }
- if (flags & FB_MOD && mod) {
- done = 0;
- }
- if (flags & FB_REQ && req) {
- done = 0;
- }
- if (done) {
- ok = 1;
- break;
- }
- if (first) {
- first = 0;
- continue;
- }
-
- rfbCFD(0);
- usleep(1000);
- dt += dtime(&tm);
- }
- return ok;
-}
-
-/*
- * utility routine for CopyRect of the window (but not CopyRegion)
- */
-static int crfix(int x, int dx, int Lx) {
- /* adjust x so that copy source is on screen */
- if (dx > 0) {
- if (x-dx < 0) {
- /* off on the left */
- x = dx;
- }
- } else {
- if (x-dx >= Lx) {
- /* off on the right */
- x = Lx + dx - 1;
- }
- }
- return x;
-}
-
-typedef struct scroll_result {
- Window win;
- double time;
- int result;
-} scroll_result_t;
-
-#define SCR_RESULTS_MAX 256
-static scroll_result_t scroll_results[SCR_RESULTS_MAX];
-
-static int scrollability(Window win, int set) {
- double oldest = -1.0;
- int i, index = -1, next_index = -1;
- static int first = 1;
-
- if (first) {
- for (i=0; i<SCR_RESULTS_MAX; i++) {
- scroll_results[i].win = None;
- scroll_results[i].time = 0.0;
- scroll_results[i].result = 0;
- }
- first = 0;
- }
-
- if (win == None) {
- return 0;
- }
- if (set == SCR_NONE) {
- /* lookup case */
- for (i=0; i<SCR_RESULTS_MAX; i++) {
- if (win == scroll_results[i].win) {
- return scroll_results[i].result;
- }
- if (scroll_results[i].win == None) {
- break;
- }
- }
- return 0;
- }
-
- for (i=0; i<SCR_RESULTS_MAX; i++) {
- if (oldest == -1.0 || scroll_results[i].time < oldest) {
- next_index = i;
- oldest = scroll_results[i].time;
- }
- if (win == scroll_results[i].win) {
- index = i;
- break;
- }
- if (next_index >= 0 && scroll_results[i].win == None) {
- break;
- }
- }
-
- if (set == SCR_SUCCESS) {
- set = 1;
- } else if (set == SCR_FAIL) {
- set = -1;
- } else {
- set = 0;
- }
- if (index == -1) {
- scroll_results[next_index].win = win;
- scroll_results[next_index].time = dnow();
- scroll_results[next_index].result = set;
- } else {
- if (scroll_results[index].result == 1) {
- /*
- * once a success, always a success, until they
- * forget about us...
- */
- set = 1;
- } else {
- scroll_results[index].result = set;
- }
- scroll_results[index].time = dnow();
- }
-
- return set;
-}
-
-void eat_viewonly_input(int max_eat, int keep) {
- int i, gp, gk;
-
- for (i=0; i<max_eat; i++) {
- int cont = 0;
- gp = got_pointer_calls;
- gk = got_keyboard_calls;
- rfbCFD(0);
- if (got_pointer_calls > gp) {
- if (debug_pointer) {
- rfbLog("eat_viewonly_input: pointer: %d\n", i);
- }
- cont++;
- }
- if (got_keyboard_calls > gk) {
- if (debug_keyboard) {
- rfbLog("eat_viewonly_input: keyboard: %d\n", i);
- }
- cont++;
- }
- if (i >= keep - 1 && ! cont) {
- break;
- }
- }
-}
-
-static int eat_pointer(int max_ptr_eat, int keep) {
- int i, count = 0, gp = got_pointer_input;
-
- for (i=0; i<max_ptr_eat; i++) {
- rfbCFD(0);
- if (got_pointer_input > gp) {
- count++;
-if (0) fprintf(stderr, "GP*-%d\n", i);
- gp = got_pointer_input;
- } else if (i > keep) {
- break;
- }
- }
- return count;
-}
-
-static void set_bdpush(int type, double *last_bdpush, int *pushit) {
- double now, delay = 0.0;
- int link, latency, netrate;
-
- *pushit = 0;
-
- if (type == SCR_MOUSE) {
- delay = scr_mouse_bdpush_time;
- } else if (type == SCR_KEY) {
- delay = scr_key_bdpush_time;
- }
-
- link = link_rate(&latency, &netrate);
- if (link == LR_DIALUP) {
- delay *= 1.5;
- } else if (link == LR_BROADBAND) {
- delay *= 1.25;
- }
-
- dtime0(&now);
- if (delay > 0.0 && now > *last_bdpush + delay) {
- *pushit = 1;
- *last_bdpush = now;
- }
-}
-
-void mark_for_xdamage(int x, int y, int w, int h) {
- int tx1, ty1, tx2, ty2;
- sraRegionPtr tmpregion;
-
- if (! use_xdamage) {
- return;
- }
-
- tx1 = nfix(x, dpy_x);
- ty1 = nfix(y, dpy_y);
- tx2 = nfix(x + w, dpy_x+1);
- ty2 = nfix(y + h, dpy_y+1);
-
- tmpregion = sraRgnCreateRect(tx1, ty1, tx2, ty2);
- add_region_xdamage(tmpregion);
- sraRgnDestroy(tmpregion);
-}
-
-void mark_region_for_xdamage(sraRegionPtr region) {
- sraRectangleIterator *iter;
- sraRect rect;
- iter = sraRgnGetIterator(region);
- while (sraRgnIteratorNext(iter, &rect)) {
- int x1 = rect.x1;
- int y1 = rect.y1;
- int x2 = rect.x2;
- int y2 = rect.y2;
- mark_for_xdamage(x1, y1, x2 - x1, y2 - y1);
- }
- sraRgnReleaseIterator(iter);
-}
-
-void set_xdamage_mark(int x, int y, int w, int h) {
- sraRegionPtr region;
-
- if (! use_xdamage) {
- return;
- }
- mark_for_xdamage(x, y, w, h);
-
- if (xdamage_scheduled_mark == 0.0) {
- xdamage_scheduled_mark = dnow() + 2.0;
- }
-
- if (xdamage_scheduled_mark_region == NULL) {
- xdamage_scheduled_mark_region = sraRgnCreate();
- }
- region = sraRgnCreateRect(x, y, x + w, y + w);
- sraRgnOr(xdamage_scheduled_mark_region, region);
- sraRgnDestroy(region);
-}
-
-static int repeat_check(double last_key_scroll) {
- int repeating;
- double rate = typing_rate(0.0, &repeating);
- double now = dnow(), delay = 0.5;
- if (rate > 2.0 && repeating && now > last_key_scroll + delay) {
- return 0;
- } else {
- return 1;
- }
-}
-
-static int check_xrecord_keys(void) {
- static int last_wx, last_wy, last_ww, last_wh;
- double spin = 0.0, tm, tnow;
- int scr_cnt = 0, input = 0, scroll_rep;
- int get_out, got_one = 0, flush1 = 0, flush2 = 0;
- int gk, gk0, ret = 0, db = debug_scroll;
- int fail = 0;
- int link, latency, netrate;
-
- static double last_key_scroll = 0.0;
- static double persist_start = 0.0;
- static double last_bdpush = 0.0;
- static int persist_count = 0;
- int scroll_keysym = 0;
- double last_scroll, scroll_persist = scr_key_persist;
- double spin_fac = 1.0, scroll_fac = 2.0, noscroll_fac = 0.75;
- double max_spin, max_long_spin = 0.3;
- double set_repeat_in;
- static double set_repeat = 0.0;
-
-
- RAWFB_RET(0)
-
- if (unixpw_in_progress) return 0;
-
- set_repeat_in = set_repeat;
- set_repeat = 0.0;
-
- get_out = 1;
- if (got_keyboard_input) {
- get_out = 0;
- }
-
- dtime0(&tnow);
- if (tnow < last_key_scroll + scroll_persist) {
- get_out = 0;
- }
-
- if (set_repeat_in > 0.0 && tnow < last_key_scroll + set_repeat_in) {
- get_out = 0;
- }
-
- if (get_out) {
- persist_start = 0.0;
- persist_count = 0;
- last_bdpush = 0.0;
- if (xrecording) {
- xrecord_watch(0, SCR_KEY);
- }
- return 0;
- }
-
-#if 0
- /* not used for keyboard yet */
- scroll_rep = scrollability(xrecord_ptr_window, SCR_NONE) + 1;
- if (scroll_rep == 1) {
- scroll_rep = 2; /* if no info, assume the best. */
- }
-#endif
-
- scroll_keysym = xrecord_scroll_keysym(last_rfb_keysym);
-
- max_spin = scr_key_time;
-
- if (set_repeat_in > 0.0 && tnow < last_key_scroll + 2*set_repeat_in) {
- max_spin = 2 * set_repeat_in;
- } else if (tnow < last_key_scroll + scroll_persist) {
- max_spin = 1.25*(tnow - last_key_scroll);
- } else if (tnow < last_key_to_button_remap_time + 1.5*scroll_persist) {
- /* mostly a hack I use for testing -remap key -> btn4/btn5 */
- max_spin = scroll_persist;
- } else if (scroll_keysym) {
- if (repeat_check(last_key_scroll)) {
- spin_fac = scroll_fac;
- } else {
- spin_fac = noscroll_fac;
- }
- }
- if (max_spin > max_long_spin) {
- max_spin = max_long_spin;
- }
-
- /* XXX use this somehow */
-if (0) link = link_rate(&latency, &netrate);
-
- gk = gk0 = got_keyboard_input;
- dtime0(&tm);
-
-if (db) fprintf(stderr, "check_xrecord_keys: BEGIN LOOP: scr_ev_cnt: "
- "%d max: %.3f %.4f\n", scr_ev_cnt, max_spin, tm - x11vnc_start);
-
- while (1) {
-
- if (scr_ev_cnt) {
- got_one = 1;
-
- scrollability(xrecord_ptr_window, SCR_SUCCESS);
- scroll_rep = 2;
-
- dtime0(&last_scroll);
- last_key_scroll = last_scroll;
- scr_cnt++;
- break;
- }
-
- X_LOCK;
- flush1 = 1;
- XFlush_wr(dpy);
- X_UNLOCK;
-
- if (set_repeat_in > 0.0) {
- max_keyrepeat_time = set_repeat_in;
- }
-
- if (use_threads) {
- usleep(1000);
- } else {
- rfbCFD(1000);
- }
- spin += dtime(&tm);
-
- X_LOCK;
- if (got_keyboard_input > gk) {
- gk = got_keyboard_input;
- input++;
- if (set_repeat_in) {
- ;
- } else if (xrecord_scroll_keysym(last_rfb_keysym)) {
- if (repeat_check(last_key_scroll)) {
- spin_fac = scroll_fac;
- } else {
- spin_fac = noscroll_fac;
- }
- }
-if (0 || db) fprintf(stderr, "check_xrecord: more keys: %.3f 0x%x "
- " %.4f %s %s\n", spin, last_rfb_keysym, last_rfb_keytime - x11vnc_start,
- last_rfb_down ? "down":"up ", last_rfb_key_accepted ? "accept":"skip");
- flush2 = 1;
- XFlush_wr(dpy);
- }
-#if LIBVNCSERVER_HAVE_RECORD
- SCR_LOCK;
- XRecordProcessReplies(rdpy_data);
- SCR_UNLOCK;
-#endif
- X_UNLOCK;
-
- if (spin >= max_spin * spin_fac) {
-if (0 || db) fprintf(stderr, "check_xrecord: SPIN-OUT: %.3f/%.3f\n", spin,
- max_spin * spin_fac);
- fail = 1;
- break;
- }
- }
-
- max_keyrepeat_time = 0.0;
-
- if (scr_ev_cnt) {
- int dret, ev = scr_ev_cnt - 1;
- int bdx, bdy, bdskinny, bdpush = 0;
- double max_age = 0.25, age, tm, dt;
- static double last_scr_ev = 0.0;
-
- last_wx = scr_ev[ev].win_x;
- last_wy = scr_ev[ev].win_y;
- last_ww = scr_ev[ev].win_w;
- last_wh = scr_ev[ev].win_h;
-
- /* assume scrollbar on rhs: */
- bdx = last_wx + last_ww + 3;
- bdy = last_wy + last_wh/2;
- bdskinny = 32;
-
- if (persist_start == 0.0) {
- bdpush = 0;
- } else {
- set_bdpush(SCR_KEY, &last_bdpush, &bdpush);
- }
-
- dtime0(&tm);
- age = max_age;
- dret = push_scr_ev(&age, SCR_KEY, bdpush, bdx, bdy, bdskinny, 1);
- dt = dtime(&tm);
-
- ret = 1 + dret;
- scr_ev_cnt = 0;
-
- if (ret == 2 && xrecord_scroll_keysym(last_rfb_keysym)) {
- int repeating;
- double time_lo = 1.0/max_keyrepeat_lo;
- double time_hi = 1.0/max_keyrepeat_hi;
- double rate = typing_rate(0.0, &repeating);
-if (0 || db) fprintf(stderr, "Typing: dt: %.4f rate: %.1f\n", dt, rate);
- if (repeating) {
- /* n.b. the "quantum" is about 1/30 sec. */
- max_keyrepeat_time = 1.0*dt;
- if (max_keyrepeat_time > time_lo ||
- max_keyrepeat_time < time_hi) {
- max_keyrepeat_time = 0.0;
- } else {
- set_repeat = max_keyrepeat_time;
-if (0 || db) fprintf(stderr, "set max_keyrepeat_time: %.2f\n", max_keyrepeat_time);
- }
- }
- }
-
- last_scr_ev = dnow();
- }
-
- if ((got_one && ret < 2) || persist_count) {
- set_xdamage_mark(last_wx, last_wy, last_ww, last_wh);
- }
-
- if (fail) {
- scrollability(xrecord_ptr_window, SCR_FAIL);
- }
-
- if (xrecording) {
- if (ret < 2) {
- xrecord_watch(0, SCR_KEY);
- }
- }
-
- if (ret == 2) {
- if (persist_start == 0.0) {
- dtime(&persist_start);
- last_bdpush = persist_start;
- }
- } else {
- persist_start = 0.0;
- last_bdpush = 0.0;
- }
-
- /* since we've flushed it, we might as well avoid -input_skip */
- if (flush1 || flush2) {
- got_keyboard_input = 0;
- got_pointer_input = 0;
- }
-
- return ret;
-}
-
-static int check_xrecord_mouse(void) {
- static int last_wx, last_wy, last_ww, last_wh;
- double spin = 0.0, tm, tnow;
- int i, scr_cnt = 0, input = 0, scroll_rep;
- int get_out, got_one = 0, flush1 = 0, flush2 = 0;
- int gp, gp0, ret = 0, db = debug_scroll;
- int gk, gk0;
- int fail = 0;
- int link, latency, netrate;
-
- int start_x, start_y, last_x, last_y;
- static double last_mouse_scroll = 0.0;
- double last_scroll;
- double max_spin[3], max_long[3], persist[3];
- double flush1_time = 0.01;
- static double last_flush = 0.0;
- double last_bdpush = 0.0, button_up_time = 0.0;
- int button_mask_save;
- int already_down = 0, max_ptr_eat = 20;
- static int want_back_in = 0;
- int came_back_in;
- int first_push = 1;
-
- int scroll_wheel = 0;
- int btn4 = (1<<3);
- int btn5 = (1<<4);
-
- RAWFB_RET(0)
-
- get_out = 1;
- if (button_mask) {
- get_out = 0;
- }
- if (want_back_in) {
- get_out = 0;
- }
- dtime0(&tnow);
-if (0) fprintf(stderr, "check_xrecord_mouse: IN xrecording: %d\n", xrecording);
-
- if (get_out) {
- if (xrecording) {
- xrecord_watch(0, SCR_MOUSE);
- }
- return 0;
- }
-
- scroll_rep = scrollability(xrecord_ptr_window, SCR_NONE) + 1;
- if (scroll_rep == 1) {
- scroll_rep = 2; /* if no info, assume the best. */
- }
-
- if (button_mask_prev) {
- already_down = 1;
- }
- if (want_back_in) {
- came_back_in = 1;
- first_push = 0;
- } else {
- came_back_in = 0;
- }
- want_back_in = 0;
-
- if (button_mask & (btn4|btn5)) {
- scroll_wheel = 1;
- }
-
- /*
- * set up times for the various "reputations"
- *
- * 0 => -1, has been tried but never found a scroll.
- * 1 => 0, has not been tried.
- * 2 => +1, has been tried and found a scroll.
- */
-
- /* first spin-out time (no events) */
- max_spin[0] = 1*scr_mouse_time;
- max_spin[1] = 2*scr_mouse_time;
- max_spin[2] = 4*scr_mouse_time;
- if (!already_down) {
- for (i=0; i<3; i++) {
- max_spin[i] *= 1.5;
- }
- }
-
- /* max time between events */
- persist[0] = 1*scr_mouse_persist;
- persist[1] = 2*scr_mouse_persist;
- persist[2] = 4*scr_mouse_persist;
-
- /* absolute max time in the loop */
- max_long[0] = scr_mouse_maxtime;
- max_long[1] = scr_mouse_maxtime;
- max_long[2] = scr_mouse_maxtime;
-
- pointer_flush_delay = scr_mouse_pointer_delay;
-
- /* slow links: */
- link = link_rate(&latency, &netrate);
- if (link == LR_DIALUP) {
- for (i=0; i<3; i++) {
- max_spin[i] *= 2.0;
- }
- pointer_flush_delay *= 2;
- } else if (link == LR_BROADBAND) {
- pointer_flush_delay *= 2;
- }
-
- gp = gp0 = got_pointer_input;
- gk = gk0 = got_keyboard_input;
- dtime0(&tm);
-
- /*
- * this is used for border pushes (bdpush) to guess location
- * of scrollbar (region rects containing this point are pushed).
- */
- last_x = start_x = cursor_x;
- last_y = start_y = cursor_y;
-
-if (db) fprintf(stderr, "check_xrecord_mouse: BEGIN LOOP: scr_ev_cnt: "
- "%d max: %.3f %.4f\n", scr_ev_cnt, max_spin[scroll_rep], tm - x11vnc_start);
-
- while (1) {
- double spin_check;
- if (scr_ev_cnt) {
- int dret, ev = scr_ev_cnt - 1;
- int bdpush = 0, bdx, bdy, bdskinny;
- double tm, dt, age = 0.35;
-
- got_one = 1;
- scrollability(xrecord_ptr_window, SCR_SUCCESS);
- scroll_rep = 2;
-
- scr_cnt++;
-
- dtime0(&last_scroll);
- last_mouse_scroll = last_scroll;
-
- if (last_bdpush == 0.0) {
- last_bdpush = last_scroll;
- }
-
- bdx = start_x;
- bdy = start_y;
- if (clipshift) {
- bdx += coff_x;
- bdy += coff_y;
- }
- if (subwin) {
- bdx += off_x;
- bdy += off_y;
- }
- bdskinny = 32;
-
- set_bdpush(SCR_MOUSE, &last_bdpush, &bdpush);
-
- dtime0(&tm);
-
- dret = push_scr_ev(&age, SCR_MOUSE, bdpush, bdx,
- bdy, bdskinny, first_push);
- if (first_push) first_push = 0;
- ret = 1 + dret;
-
- dt = dtime(&tm);
-
-if (db) fprintf(stderr, " dret: %d scr_ev_cnt: %d dt: %.4f\n",
- dret, scr_ev_cnt, dt);
-
- last_wx = scr_ev[ev].win_x;
- last_wy = scr_ev[ev].win_y;
- last_ww = scr_ev[ev].win_w;
- last_wh = scr_ev[ev].win_h;
- scr_ev_cnt = 0;
-
- if (! dret) {
- break;
- }
- if (0 && button_up_time > 0.0) {
- /* we only take 1 more event with button up */
-if (db) fprintf(stderr, "check_xrecord: BUTTON_UP_SCROLL: %.3f\n", spin);
- break;
- }
- }
-
-
- if (! flush1) {
- if (! already_down || (!scr_cnt && spin>flush1_time)) {
- flush1 = 1;
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- dtime0(&last_flush);
- }
- }
-
- if (use_threads) {
- usleep(1000);
- } else {
- rfbCFD(1000);
- rfbCFD(0);
- }
- spin += dtime(&tm);
-
- if (got_pointer_input > gp) {
- flush2 = 1;
- input += eat_pointer(max_ptr_eat, 1);
- gp = got_pointer_input;
- }
- if (got_keyboard_input > gk) {
- gk = got_keyboard_input;
- input++;
- }
- X_LOCK;
-#if LIBVNCSERVER_HAVE_RECORD
- SCR_LOCK;
- XRecordProcessReplies(rdpy_data);
- SCR_UNLOCK;
-#endif
- X_UNLOCK;
-
- if (! input) {
- spin_check = 1.5 * max_spin[scroll_rep];
- } else {
- spin_check = max_spin[scroll_rep];
- }
-
- if (button_up_time > 0.0) {
- if (tm > button_up_time + max_spin[scroll_rep]) {
-if (db) fprintf(stderr, "check_xrecord: SPIN-OUT-BUTTON_UP: %.3f/%.3f\n", spin, tm - button_up_time);
- break;
- }
- } else if (!scr_cnt) {
- if (spin >= spin_check) {
-
-if (db) fprintf(stderr, "check_xrecord: SPIN-OUT-1: %.3f/%.3f\n", spin, spin_check);
- fail = 1;
- break;
- }
- } else {
- if (tm >= last_scroll + persist[scroll_rep]) {
-
-if (db) fprintf(stderr, "check_xrecord: SPIN-OUT-2: %.3f/%.3f\n", spin, tm - last_scroll);
- break;
- }
- }
- if (spin >= max_long[scroll_rep]) {
-
-if (db) fprintf(stderr, "check_xrecord: SPIN-OUT-3: %.3f/%.3f\n", spin, max_long[scroll_rep]);
- break;
- }
-
- if (! button_mask) {
- int doflush = 0;
- if (button_up_time > 0.0) {
- ;
- } else if (came_back_in) {
- dtime0(&button_up_time);
- doflush = 1;
- } else if (scroll_wheel) {
-if (db) fprintf(stderr, "check_xrecord: SCROLL-WHEEL-BUTTON-UP-KEEP-GOING: %.3f/%.3f %d/%d %d/%d\n", spin, max_long[scroll_rep], last_x, last_y, cursor_x, cursor_y);
- doflush = 1;
- dtime0(&button_up_time);
- } else if (last_x == cursor_x && last_y == cursor_y) {
-if (db) fprintf(stderr, "check_xrecord: BUTTON-UP: %.3f/%.3f %d/%d %d/%d\n", spin, max_long[scroll_rep], last_x, last_y, cursor_x, cursor_y);
- break;
- } else {
-if (db) fprintf(stderr, "check_xrecord: BUTTON-UP-KEEP-GOING: %.3f/%.3f %d/%d %d/%d\n", spin, max_long[scroll_rep], last_x, last_y, cursor_x, cursor_y);
- doflush = 1;
- dtime0(&button_up_time);
- }
- if (doflush) {
- flush1 = 1;
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- dtime0(&last_flush);
- }
- }
-
- last_x = cursor_x;
- last_y = cursor_y;
- }
-
- if (got_one) {
- set_xdamage_mark(last_wx, last_wy, last_ww, last_wh);
- }
-
- if (fail) {
- scrollability(xrecord_ptr_window, SCR_FAIL);
- }
-
- /* flush any remaining pointer events. */
- button_mask_save = button_mask;
- pointer_queued_sent = 0;
- last_x = cursor_x;
- last_y = cursor_y;
- pointer_event(-1, 0, 0, NULL);
- pointer_flush_delay = 0.0;
-
- if (xrecording && pointer_queued_sent && button_mask_save &&
- (last_x != cursor_x || last_y != cursor_y) ) {
-if (db) fprintf(stderr, " pointer() push yields events on: ret=%d\n", ret);
- if (ret == 2) {
-if (db) fprintf(stderr, " we decide to send ret=3\n");
- want_back_in = 1;
- ret = 3;
- flush2 = 1;
- } else {
- if (ret) {
- ret = 1;
- } else {
- ret = 0;
- }
- xrecord_watch(0, SCR_MOUSE);
- }
- } else {
- if (ret) {
- ret = 1;
- } else {
- ret = 0;
- }
- if (xrecording) {
- xrecord_watch(0, SCR_MOUSE);
- }
- }
-
- if (flush2) {
- X_LOCK;
- XFlush_wr(dpy);
- XFlush_wr(rdpy_ctrl);
- X_UNLOCK;
-
- flush2 = 1;
- dtime0(&last_flush);
-
-if (db) fprintf(stderr, "FLUSH-2\n");
- }
-
- /* since we've flushed it, we might as well avoid -input_skip */
- if (flush1 || flush2) {
- got_keyboard_input = 0;
- got_pointer_input = 0;
- }
-
- if (ret) {
- return ret;
- } else if (scr_cnt) {
- return 1;
- } else {
- return 0;
- }
-}
-
-int check_xrecord(void) {
- int watch_keys = 0, watch_mouse = 0, consider_mouse;
- static int mouse_wants_back_in = 0;
-
- RAWFB_RET(0)
-
- if (! use_xrecord) {
- return 0;
- }
- if (unixpw_in_progress) return 0;
-
- if (skip_cr_when_scaling("scroll")) {
- return 0;
- }
-
-if (0) fprintf(stderr, "check_xrecord: IN xrecording: %d\n", xrecording);
-
- if (! xrecording) {
- return 0;
- }
-
- if (!strcmp(scroll_copyrect, "always")) {
- watch_keys = 1;
- watch_mouse = 1;
- } else if (!strcmp(scroll_copyrect, "keys")) {
- watch_keys = 1;
- } else if (!strcmp(scroll_copyrect, "mouse")) {
- watch_mouse = 1;
- }
-
- if (button_mask || mouse_wants_back_in) {
- consider_mouse = 1;
- } else {
- consider_mouse = 0;
- }
-if (0) fprintf(stderr, "check_xrecord: button_mask: %d mouse_wants_back_in: %d\n", button_mask, mouse_wants_back_in);
-
- if (watch_mouse && consider_mouse && xrecord_set_by_mouse) {
- int ret = check_xrecord_mouse();
- if (ret == 3) {
- mouse_wants_back_in = 1;
- } else {
- mouse_wants_back_in = 0;
- }
- return ret;
- } else if (watch_keys && xrecord_set_by_keys) {
- mouse_wants_back_in = 0;
- return check_xrecord_keys();
- } else {
- mouse_wants_back_in = 0;
- return 0;
- }
-}
-
-#define DB_SET \
- int db = 0; \
- int db2 = 0; \
- if (debug_wireframe == 1) { \
- db = 1; \
- } \
- if (debug_wireframe == 2) { \
- db2 = 1; \
- } \
- if (debug_wireframe == 3) { \
- db = 1; \
- db2 = 1; \
- }
-
-#define NBATCHMAX 1024
-int batch_dxs[NBATCHMAX], batch_dys[NBATCHMAX];
-sraRegionPtr batch_reg[NBATCHMAX];
-
-static int try_copyrect(Window orig_frame, Window frame, int x, int y, int w, int h,
- int dx, int dy, int *obscured, sraRegionPtr extra_clip, double max_wait, int *nbatch) {
-
- static int dt_bad = 0;
- static time_t dt_bad_check = 0;
- int x1, y1, x2, y2, sent_copyrect = 0;
- int req, mod, cpy, ncli;
- double tm, dt;
- DB_SET
-
- if (nbatch == NULL) {
- get_client_regions(&req, &mod, &cpy, &ncli);
- if (cpy) {
- /* one is still pending... try to force it out: */
- if (!fb_push_wait(max_wait, FB_COPY)) {
- fb_push_wait(max_wait/2, FB_COPY);
- }
-
- get_client_regions(&req, &mod, &cpy, &ncli);
- }
- if (cpy) {
- return 0;
- }
- }
-
- *obscured = 0;
- /*
- * XXX KDE and xfce do some weird things with the
- * stacking, it does not match XQueryTree. Work around
- * it for now by CopyRect-ing the *whole* on-screen
- * rectangle (whether obscured or not!)
- */
- if (time(NULL) > dt_bad_check + 5) {
- char *dt = guess_desktop();
- if (!strcmp(dt, "kde_maybe_is_ok_now...")) {
- dt_bad = 1;
- } else if (!strcmp(dt, "xfce")) {
- dt_bad = 1;
- } else {
- dt_bad = 0;
- }
- dt_bad_check = time(NULL);
- }
-
- if (clipshift) {
- x -= coff_x;
- y -= coff_y;
- }
- if (subwin) {
- x -= off_x;
- y -= off_y;
- }
-if (db2) fprintf(stderr, "try_copyrect: 0x%lx/0x%lx bad: %d stack_list_num: %d\n", orig_frame, frame, dt_bad, stack_list_num);
-
-/* XXX Y dt_bad = 0 */
- if (dt_bad && wireframe_in_progress) {
- sraRegionPtr rect;
- /* send the whole thing... */
- x1 = crfix(nfix(x, dpy_x), dx, dpy_x);
- y1 = crfix(nfix(y, dpy_y), dy, dpy_y);
- x2 = crfix(nfix(x+w, dpy_x+1), dx, dpy_x+1);
- y2 = crfix(nfix(y+h, dpy_y+1), dy, dpy_y+1);
-
- rect = sraRgnCreateRect(x1, y1, x2, y2);
-
- if (blackouts) {
- int i;
- sraRegionPtr bo_rect;
- for (i=0; i<blackouts; i++) {
- bo_rect = sraRgnCreateRect(blackr[i].x1,
- blackr[i].y1, blackr[i].x2, blackr[i].y2);
- sraRgnSubtract(rect, bo_rect);
- sraRgnDestroy(bo_rect);
- }
- }
- if (!nbatch) {
- do_copyregion(rect, dx, dy, 0);
- } else {
- batch_dxs[*nbatch] = dx;
- batch_dys[*nbatch] = dy;
- batch_reg[*nbatch] = sraRgnCreateRgn(rect);
- (*nbatch)++;
- }
- sraRgnDestroy(rect);
-
- sent_copyrect = 1;
- *obscured = 1; /* set to avoid an aggressive push */
-
- } else if (stack_list_num || dt_bad) {
- int k, tx1, tx2, ty1, ty2;
- sraRegionPtr moved_win, tmp_win, whole;
- sraRectangleIterator *iter;
- sraRect rect;
- int saw_me = 0;
- int orig_x, orig_y;
- int boff, bwin;
- XWindowAttributes attr;
-
- orig_x = x - dx;
- orig_y = y - dy;
-
- tx1 = nfix(orig_x, dpy_x);
- ty1 = nfix(orig_y, dpy_y);
- tx2 = nfix(orig_x+w, dpy_x+1);
- ty2 = nfix(orig_y+h, dpy_y+1);
-
-if (db2) fprintf(stderr, "moved_win: %4d %3d, %4d %3d 0x%lx ---\n",
- tx1, ty1, tx2, ty2, frame);
-
- moved_win = sraRgnCreateRect(tx1, ty1, tx2, ty2);
-
- dtime0(&tm);
-
- boff = get_boff();
- bwin = get_bwin();
-
- X_LOCK;
-
- /*
- * loop over the stack, top to bottom until we
- * find our wm frame:
- */
- for (k = stack_list_num - 1; k >= 0; k--) {
- Window swin;
-
- if (0 && dt_bad) {
- break;
- }
-
- swin = stack_list[k].win;
-if (db2) fprintf(stderr, "sw: %d/%lx\n", k, swin);
- if (swin == frame || swin == orig_frame) {
- if (db2) {
- saw_me = 1; fprintf(stderr, " ----------\n");
- } else {
- break;
- }
- }
-
- /* skip some unwanted cases: */
-#ifndef MACOSX
- if (swin == None) {
- continue;
- }
-#endif
- if (boff <= (int) swin && (int) swin < boff + bwin) {
- ; /* blackouts */
- } else if (! stack_list[k].fetched ||
- stack_list[k].time > tm + 2.0) {
- if (!valid_window(swin, &attr, 1)) {
- stack_list[k].valid = 0;
- } else {
- stack_list[k].valid = 1;
- stack_list[k].x = attr.x;
- stack_list[k].y = attr.y;
- stack_list[k].width = attr.width;
- stack_list[k].height = attr.height;
- stack_list[k].border_width = attr.border_width;
- stack_list[k].depth = attr.depth;
- stack_list[k].class = attr.class;
- stack_list[k].backing_store =
- attr.backing_store;
- stack_list[k].map_state =
- attr.map_state;
- }
- stack_list[k].fetched = 1;
- stack_list[k].time = tm;
- }
- if (!stack_list[k].valid) {
- continue;
- }
-
- attr.x = stack_list[k].x;
- attr.y = stack_list[k].y;
- attr.depth = stack_list[k].depth;
- attr.width = stack_list[k].width;
- attr.height = stack_list[k].height;
- attr.border_width = stack_list[k].border_width;
- attr.map_state = stack_list[k].map_state;
-
- if (attr.map_state != IsViewable) {
- continue;
- }
-if (db2) fprintf(stderr, "sw: %d/%lx %dx%d+%d+%d\n", k, swin, stack_list[k].width, stack_list[k].height, stack_list[k].x, stack_list[k].y);
-
- if (clipshift) {
- attr.x -= coff_x;
- attr.y -= coff_y;
- }
- if (subwin) {
- attr.x -= off_x;
- attr.y -= off_y;
- }
-
- /*
- * first subtract any overlap from the initial
- * window rectangle
- */
-
- /* clip the window to the visible screen: */
- tx1 = nfix(attr.x, dpy_x);
- ty1 = nfix(attr.y, dpy_y);
- tx2 = nfix(attr.x + attr.width, dpy_x+1);
- ty2 = nfix(attr.y + attr.height, dpy_y+1);
-
-if (db2) fprintf(stderr, " tmp_win-1: %4d %3d, %4d %3d 0x%lx\n",
- tx1, ty1, tx2, ty2, swin);
-if (db2 && saw_me) continue;
-
- /* see if window clips us: */
- tmp_win = sraRgnCreateRect(tx1, ty1, tx2, ty2);
- if (sraRgnAnd(tmp_win, moved_win)) {
- *obscured = 1;
-if (db2) fprintf(stderr, " : clips it.\n");
- }
- sraRgnDestroy(tmp_win);
-
- /* subtract it from our region: */
- tmp_win = sraRgnCreateRect(tx1, ty1, tx2, ty2);
- sraRgnSubtract(moved_win, tmp_win);
- sraRgnDestroy(tmp_win);
-
- /*
- * next, subtract from the initial window rectangle
- * anything that would clip it.
- */
-
- /* clip the window to the visible screen: */
- tx1 = nfix(attr.x - dx, dpy_x);
- ty1 = nfix(attr.y - dy, dpy_y);
- tx2 = nfix(attr.x - dx + attr.width, dpy_x+1);
- ty2 = nfix(attr.y - dy + attr.height, dpy_y+1);
-
-if (db2) fprintf(stderr, " tmp_win-2: %4d %3d, %4d %3d 0x%lx\n",
- tx1, ty1, tx2, ty2, swin);
-if (db2 && saw_me) continue;
-
- /* subtract it from our region: */
- tmp_win = sraRgnCreateRect(tx1, ty1, tx2, ty2);
- sraRgnSubtract(moved_win, tmp_win);
- sraRgnDestroy(tmp_win);
- }
-
- X_UNLOCK;
-
- if (extra_clip && ! sraRgnEmpty(extra_clip)) {
- whole = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
-
- if (clipshift) {
- sraRgnOffset(extra_clip, -coff_x, -coff_y);
- }
- if (subwin) {
- sraRgnOffset(extra_clip, -off_x, -off_y);
- }
-
- iter = sraRgnGetIterator(extra_clip);
- while (sraRgnIteratorNext(iter, &rect)) {
- /* clip the window to the visible screen: */
- tx1 = rect.x1;
- ty1 = rect.y1;
- tx2 = rect.x2;
- ty2 = rect.y2;
- tmp_win = sraRgnCreateRect(tx1, ty1, tx2, ty2);
- sraRgnAnd(tmp_win, whole);
-
- /* see if window clips us: */
- if (sraRgnAnd(tmp_win, moved_win)) {
- *obscured = 1;
- }
- sraRgnDestroy(tmp_win);
-
- /* subtract it from our region: */
- tmp_win = sraRgnCreateRect(tx1, ty1, tx2, ty2);
- sraRgnSubtract(moved_win, tmp_win);
- sraRgnDestroy(tmp_win);
-
- /*
- * next, subtract from the initial window rectangle
- * anything that would clip it.
- */
- tmp_win = sraRgnCreateRect(tx1, ty1, tx2, ty2);
- sraRgnOffset(tmp_win, -dx, -dy);
-
- /* clip the window to the visible screen: */
- sraRgnAnd(tmp_win, whole);
-
- /* subtract it from our region: */
- sraRgnSubtract(moved_win, tmp_win);
- sraRgnDestroy(tmp_win);
- }
- sraRgnReleaseIterator(iter);
- sraRgnDestroy(whole);
- }
-
- dt = dtime(&tm);
-if (db2) fprintf(stderr, " stack_work dt: %.4f\n", dt);
-
- if (*obscured && !strcmp(wireframe_copyrect, "top")) {
- ; /* cannot send CopyRegion */
- } else if (! sraRgnEmpty(moved_win)) {
- sraRegionPtr whole, shifted_region;
-
- whole = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- shifted_region = sraRgnCreateRgn(moved_win);
- sraRgnOffset(shifted_region, dx, dy);
- sraRgnAnd(shifted_region, whole);
-
- sraRgnDestroy(whole);
-
- /* now send the CopyRegion: */
- if (! sraRgnEmpty(shifted_region)) {
- dtime0(&tm);
- if (!nbatch) {
- do_copyregion(shifted_region, dx, dy, 0);
- } else {
- batch_dxs[*nbatch] = dx;
- batch_dys[*nbatch] = dy;
- batch_reg[*nbatch] = sraRgnCreateRgn(shifted_region);
- (*nbatch)++;
-
- }
- dt = dtime(&tm);
-if (0 || db2) fprintf(stderr, "do_copyregion: %d %d %d %d dx: %d dy: %d dt: %.4f\n",
- tx1, ty1, tx2, ty2, dx, dy, dt);
- sent_copyrect = 1;
- }
- sraRgnDestroy(shifted_region);
- }
- sraRgnDestroy(moved_win);
- }
- return sent_copyrect;
-}
-
-int near_wm_edge(int x, int y, int w, int h, int px, int py) {
- /* heuristics: */
- int wf_t = wireframe_top;
- int wf_b = wireframe_bot;
- int wf_l = wireframe_left;
- int wf_r = wireframe_right;
-
- int near_edge = 0;
-
- if (wf_t || wf_b || wf_l || wf_r) {
- if (nabs(y - py) < wf_t) {
- near_edge = 1;
- }
- if (nabs(y + h - py) < wf_b) {
- near_edge = 1;
- }
- if (nabs(x - px) < wf_l) {
- near_edge = 1;
- }
- if (nabs(x + w - px) < wf_r) {
- near_edge = 1;
- }
- } else {
- /* all zero; always "near" edge: */
- near_edge = 1;
- }
- return near_edge;
-}
-
-int near_scrollbar_edge(int x, int y, int w, int h, int px, int py) {
- /* heuristics: */
- int sb_t = scrollcopyrect_top;
- int sb_b = scrollcopyrect_bot;
- int sb_l = scrollcopyrect_left;
- int sb_r = scrollcopyrect_right;
-
- int near_edge = 0;
-
- if (sb_t || sb_b || sb_l || sb_r) {
- if (nabs(y - py) < sb_t) {
- near_edge = 1;
- }
- if (nabs(y + h - py) < sb_b) {
- near_edge = 1;
- }
- if (nabs(x - px) < sb_l) {
- near_edge = 1;
- }
- if (nabs(x + w - px) < sb_r) {
- near_edge = 1;
- }
- } else {
- /* all zero; always "near" edge: */
- near_edge = 1;
- }
- return near_edge;
-}
-
-void check_fixscreen(void) {
- double now = dnow();
- int didfull = 0, db = 0;
-
- if (!client_count) {
- return;
- }
- if (unixpw_in_progress) return;
-
- if (screen_fixup_X > 0.0) {
- static double last = 0.0;
- if (now > last + screen_fixup_X) {
- if (db) rfbLog("doing screen_fixup_X\n");
- do_copy_screen = 1;
- last = now;
- didfull = 1;
- }
-
- }
- if (screen_fixup_V > 0.0) {
- static double last = 0.0;
- if (now > last + screen_fixup_V) {
- if (! didfull) {
- refresh_screen(0);
- if (db) rfbLog("doing screen_fixup_V\n");
- }
- last = now;
- didfull = 1;
- }
- }
- if (screen_fixup_C > 0.0) {
- static double last = 0.0;
- if (last_copyrect_fix < last_copyrect &&
- now > last_copyrect + screen_fixup_C) {
- if (! didfull) {
- refresh_screen(0);
- if (db) rfbLog("doing screen_fixup_C\n");
- }
- last_copyrect_fix = now;
- last = now;
- didfull = 1;
- }
- }
- if (scaling && last_copyrect_fix < last_copyrect) {
- static double last = 0.0;
- double delay = 3.0;
- if (now > last + delay) {
- if (! didfull) {
- scale_and_mark_rect(0, 0, dpy_x, dpy_y, 1);
- if (db) rfbLog("doing scale screen_fixup\n");
- }
- last_copyrect_fix = now;
- last = now;
- didfull = 1;
- }
- }
- if (advertise_truecolor && advertise_truecolor_reset && indexed_color) {
- /* this will reset framebuffer to correct colors, if needed */
- static double dlast = 0.0;
- now = dnow();
- if (now > last_client + 1.0 && now < last_client + 3.0 && now > dlast + 5.0) {
- rfbLog("advertise truecolor reset framebuffer\n");
- do_new_fb(1);
- dlast = dnow();
- return;
- }
- }
-}
-
-static int wireframe_mod_state() {
- if (! wireframe_mods) {
- return 0;
- }
- if (!strcmp(wireframe_mods, "all")) {
- if (track_mod_state(NoSymbol, FALSE, FALSE)) {
- return 1;
- } else {
- return 0;
- }
-
- } else if (!strcmp(wireframe_mods, "Alt")) {
- if (track_mod_state(XK_Alt_L, FALSE, FALSE) == 1) {
- return 1;
- } else if (track_mod_state(XK_Alt_R, FALSE, FALSE) == 1) {
- return 1;
- }
- } else if (!strcmp(wireframe_mods, "Shift")) {
- if (track_mod_state(XK_Shift_L, FALSE, FALSE) == 1) {
- return 1;
- } else if (track_mod_state(XK_Shift_R, FALSE, FALSE) == 1) {
- return 1;
- }
- } else if (!strcmp(wireframe_mods, "Control")) {
- if (track_mod_state(XK_Control_L, FALSE, FALSE) == 1) {
- return 1;
- } else if (track_mod_state(XK_Control_R, FALSE, FALSE) == 1) {
- return 1;
- }
- } else if (!strcmp(wireframe_mods, "Meta")) {
- if (track_mod_state(XK_Meta_L, FALSE, FALSE) == 1) {
- return 1;
- } else if (track_mod_state(XK_Meta_R, FALSE, FALSE) == 1) {
- return 1;
- }
- } else if (!strcmp(wireframe_mods, "Super")) {
- if (track_mod_state(XK_Super_L, FALSE, FALSE) == 1) {
- return 1;
- } else if (track_mod_state(XK_Super_R, FALSE, FALSE) == 1) {
- return 1;
- }
- } else if (!strcmp(wireframe_mods, "Hyper")) {
- if (track_mod_state(XK_Hyper_L, FALSE, FALSE) == 1) {
- return 1;
- } else if (track_mod_state(XK_Hyper_R, FALSE, FALSE) == 1) {
- return 1;
- }
- }
- return 0;
-}
-
-static int NPP_nreg = 0;
-static sraRegionPtr NPP_roffscreen = NULL;
-static sraRegionPtr NPP_r_bs_tmp = NULL;
-static Window NPP_nwin = None;
-
-void clear_win_events(Window win, int vis) {
-#if !NO_X11
- if (dpy && win != None && ncache) {
- XEvent ev;
- XErrorHandler old_handler;
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
- while (XCheckTypedWindowEvent(dpy, win, ConfigureNotify, &ev)) {
- if (ncdb) fprintf(stderr, ".");
- if (trapped_xerror) {
- break;
- }
- trapped_xerror = 0;
- }
-/* XXX Y */
- if (vis) {
- while (XCheckTypedWindowEvent(dpy, win, VisibilityNotify, &ev)) {
- if (ncdb) fprintf(stderr, "+");
- if (trapped_xerror) {
- break;
- }
- trapped_xerror = 0;
- }
- }
- XSetErrorHandler(old_handler);
- if (ncdb) fprintf(stderr, " 0x%lx\n", win);
- }
-#endif
-}
-
-void push_borders(sraRect *rects, int nrect) {
- int i, s = 2;
- sraRegionPtr r0, r1, r2;
-
- r0 = sraRgnCreate();
- r1 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
-
- for (i=0; i<nrect; i++) {
- int x = rects[i].x1;
- int y = rects[i].y1;
- int w = rects[i].x2;
- int h = rects[i].y2;
-
- if (w > 0 && h > 0 && w * h > 64 * 64) {
- r2 = sraRgnCreateRect(x - s, y , x , y + h);
- sraRgnOr(r0, r2);
- sraRgnDestroy(r2);
-
- r2 = sraRgnCreateRect(x + w, y , x + w + s, y + h);
- sraRgnOr(r0, r2);
- sraRgnDestroy(r2);
-
- r2 = sraRgnCreateRect(x - s, y - s, x + w + s, y + s);
- sraRgnOr(r0, r2);
- sraRgnDestroy(r2);
-
- r2 = sraRgnCreateRect(x - s, y , x + w + s, y + h + s);
- sraRgnOr(r0, r2);
- sraRgnDestroy(r2);
- }
- }
-
- sraRgnAnd(r0, r1);
-
- if (!sraRgnEmpty(r0)) {
- double d = dnow();
- sraRectangleIterator *iter;
- sraRect rect;
- int db = 0;
-
- if (db) fprintf(stderr, "SCALE_BORDER\n");
- fb_push_wait(0.05, FB_MOD|FB_COPY);
-
- iter = sraRgnGetIterator(r0);
- while (sraRgnIteratorNext(iter, &rect)) {
- /* clip the window to the visible screen: */
- int tx1 = rect.x1;
- int ty1 = rect.y1;
- int tx2 = rect.x2;
- int ty2 = rect.y2;
- scale_and_mark_rect(tx1, ty1, tx2, ty2, 1);
- }
- sraRgnReleaseIterator(iter);
-
- if (db) fprintf(stderr, "SCALE_BORDER %.4f\n", dnow() - d);
- fb_push_wait(0.1, FB_MOD|FB_COPY);
- if (db) fprintf(stderr, "SCALE_BORDER %.4f\n", dnow() - d);
- }
- sraRgnDestroy(r0);
- sraRgnDestroy(r1);
-}
-
-void ncache_pre_portions(Window orig_frame, Window frame, int *nidx_in, int try_batch, int *use_batch,
- int orig_x, int orig_y, int orig_w, int orig_h, int x, int y, int w, int h, double ntim) {
- int nidx, np = ncache_pad;
-
- if (!ntim) {}
- *use_batch = 0;
- *nidx_in = -1;
- NPP_nreg = 0;
- NPP_roffscreen = NULL;
- NPP_r_bs_tmp = NULL;
- NPP_nwin = None;
-
- if (ncache <= 0) {
- return;
- }
-
- if (rotating) {
- try_batch = 0;
- }
-
- if (*nidx_in == -1) {
- nidx = lookup_win_index(orig_frame);
- NPP_nwin = orig_frame;
- if (nidx < 0) {
- nidx = lookup_win_index(frame);
- NPP_nwin = frame;
- }
- } else {
- nidx = *nidx_in;
- }
- if (nidx > 0) {
- sraRegionPtr r0, r1, r2;
- int dx, dy;
- int bs_x = cache_list[nidx].bs_x;
- int bs_y = cache_list[nidx].bs_y;
- int bs_w = cache_list[nidx].bs_w;
- int bs_h = cache_list[nidx].bs_h;
-
- *nidx_in = nidx;
-
- if (bs_x < 0) {
- if (!find_rect(nidx, x, y, w, h)) {
- nidx = -1;
- return;
- }
- bs_x = cache_list[nidx].bs_x;
- bs_y = cache_list[nidx].bs_y;
- bs_w = cache_list[nidx].bs_w;
- bs_h = cache_list[nidx].bs_h;
- }
- if (bs_x < 0) {
- nidx = -1;
- return;
- }
-
- if (try_batch) {
- *use_batch = 1;
- }
-
- if (ncache_pad) {
- orig_x -= np;
- orig_y -= np;
- orig_w += 2 * np;
- orig_h += 2 * np;
- x -= np;
- y -= np;
- w += 2 * np;
- h += 2 * np;
- }
-
- if (clipshift) {
- orig_x -= coff_x;
- orig_y -= coff_y;
- x -= coff_x;
- y -= coff_y;
- }
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
-
- r2 = sraRgnCreateRect(orig_x, orig_y, orig_x + orig_w, orig_y + orig_h);
- sraRgnSubtract(r2, r0);
- if (! sraRgnEmpty(r2) && cache_list[nidx].bs_time > 0.0) {
- /* some is initially offscreen */
- dx = bs_x - orig_x;
- dy = bs_y - orig_y;
- sraRgnOffset(r2, dx, dy);
- dx = 0;
- dy = dpy_y;
- sraRgnOffset(r2, dx, dy);
-if (ncdb) fprintf(stderr, "FB_COPY: %.4f 1) offscreen: dx, dy: %d, %d -> %d, %d orig %dx%d+%d+%d bs_xy: %d %d\n",
- dnow() - ntim, bs_x - orig_x, bs_y - orig_y, dx, dy, orig_w, orig_h, orig_x, orig_y, bs_x, bs_y);
-
- /* 0) save it in the invalid (offscreen) SU portion */
- if (! *use_batch) {
- do_copyregion(r2, dx, dy, 0);
- if (! fb_push_wait(0.2, FB_COPY)) {
- fb_push_wait(0.1, FB_COPY);
- }
- } else {
- batch_dxs[NPP_nreg] = dx;
- batch_dys[NPP_nreg] = dy;
- batch_reg[NPP_nreg++] = sraRgnCreateRgn(r2);
- }
- NPP_roffscreen = sraRgnCreateRgn(r2);
- }
- sraRgnDestroy(r2);
-
- /* 1) use bs for temp storage of the new save under. */
- r1 = sraRgnCreateRect(x, y, x + w, y + h);
- sraRgnAnd(r1, r0);
-
- dx = bs_x - x;
- dy = bs_y - y;
- sraRgnOffset(r1, dx, dy);
-
-if (ncdb) fprintf(stderr, "FB_COPY: %.4f 1) use tmp bs:\n", dnow() - ntim);
- if (! *use_batch) {
- do_copyregion(r1, dx, dy, 0);
- if (! fb_push_wait(0.2, FB_COPY)) {
-if (ncdb) fprintf(stderr, "FB_COPY: %.4f 1) FAILED.\n", dnow() - ntim);
- fb_push_wait(0.1, FB_COPY);
- }
- } else {
- batch_dxs[NPP_nreg] = dx;
- batch_dys[NPP_nreg] = dy;
- batch_reg[NPP_nreg++] = sraRgnCreateRgn(r1);
- }
- NPP_r_bs_tmp = sraRgnCreateRgn(r1);
- sraRgnDestroy(r0);
- sraRgnDestroy(r1);
- }
-}
-
-void ncache_post_portions(int nidx, int use_batch, int orig_x, int orig_y, int orig_w, int orig_h,
- int x, int y, int w, int h, double batch_delay, double ntim) {
- int np = ncache_pad;
- int db = 0;
-
- if (ncache > 0 && nidx >= 0) {
- sraRegionPtr r0, r1, r2, r3;
- int dx, dy;
- int su_x = cache_list[nidx].su_x;
- int su_y = cache_list[nidx].su_y;
- int su_w = cache_list[nidx].su_w;
- int su_h = cache_list[nidx].su_h;
- int bs_x = cache_list[nidx].bs_x;
- int bs_y = cache_list[nidx].bs_y;
- int bs_w = cache_list[nidx].bs_w;
- int bs_h = cache_list[nidx].bs_h;
- int some_su = 0;
-
-if (db) fprintf(stderr, "su: %dx%d+%d+%d bs: %dx%d+%d+%d\n", su_w, su_h, su_x, su_y, bs_w, bs_h, bs_x, bs_y);
-
- if (bs_x < 0) {
- if (!find_rect(nidx, x, y, w, h)) {
- return;
- }
- su_x = cache_list[nidx].su_x;
- su_y = cache_list[nidx].su_y;
- su_w = cache_list[nidx].su_w;
- su_h = cache_list[nidx].su_h;
- bs_x = cache_list[nidx].bs_x;
- bs_y = cache_list[nidx].bs_y;
- bs_w = cache_list[nidx].bs_w;
- bs_h = cache_list[nidx].bs_h;
- }
- if (bs_x < 0) {
- return;
- }
-
- if (ncache_pad) {
- orig_x -= np;
- orig_y -= np;
- orig_w += 2 * np;
- orig_h += 2 * np;
- x -= np;
- y -= np;
- w += 2 * np;
- h += 2 * np;
- }
-
- if (clipshift) {
- orig_x -= coff_x;
- orig_y -= coff_y;
- x -= coff_x;
- y -= coff_y;
- }
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
-
- /* 0b) copy this bs part stored in saveunder */
- if (NPP_roffscreen != NULL) {
- dx = x - su_x;
- dy = y - su_y;
- sraRgnOffset(NPP_roffscreen, dx, dy);
- sraRgnAnd(NPP_roffscreen, r0);
-
- if (! use_batch) {
- do_copyregion(NPP_roffscreen, dx, dy, 0);
- if (!fb_push_wait(0.2, FB_COPY)) {
- fb_push_wait(0.1, FB_COPY);
- }
- } else {
- batch_dxs[NPP_nreg] = dx;
- batch_dys[NPP_nreg] = dy;
- batch_reg[NPP_nreg++] = sraRgnCreateRgn(NPP_roffscreen);
- }
- sraRgnDestroy(NPP_roffscreen);
- }
-
- /* 3) copy from the saveunder to where orig win was */
- r1 = sraRgnCreateRect(orig_x, orig_y, orig_x + orig_w, orig_y + orig_h);
- sraRgnAnd(r1, r0);
- r2 = sraRgnCreateRect(x+np, y+np, x + w-np, y + h-np);
- sraRgnAnd(r2, r0);
- sraRgnSubtract(r1, r2);
-
- dx = orig_x - su_x;
- dy = orig_y - su_y;
-if (db && ncdb) fprintf(stderr, "FB_COPY: %.4f 3) sent_copyrect: su_restore: %d %d\n", dnow() - ntim, dx, dy);
- if (cache_list[nidx].su_time == 0.0) {
- ;
- } else if (! use_batch) {
- do_copyregion(r1, dx, dy, 0);
- if (!fb_push_wait(0.2, FB_COPY)) {
-if (db && ncdb) fprintf(stderr, "FB_COPY: %.4f 3) FAILED.\n", dnow() - ntim);
- fb_push_wait(0.1, FB_COPY);
- }
- } else {
- batch_dxs[NPP_nreg] = dx;
- batch_dys[NPP_nreg] = dy;
- batch_reg[NPP_nreg++] = sraRgnCreateRgn(r1);
- }
-if (db && ncdb) fprintf(stderr, "sent_copyrect: %.4f su_restore: done.\n", dnow() - ntim);
- sraRgnDestroy(r0);
- sraRgnDestroy(r1);
- sraRgnDestroy(r2);
-
- /* 4) if overlap between orig and displaced, move the corner that will still be su: */
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
-
- r1 = sraRgnCreateRect(orig_x, orig_y, orig_x + orig_w, orig_y + orig_h);
- sraRgnAnd(r1, r0);
- r2 = sraRgnCreateRect(x, y, x + w, y + h);
- sraRgnAnd(r2, r0);
- r3 = NULL;
- if (sraRgnAnd(r2, r1) && cache_list[nidx].su_time > 0.0) {
- int dx2 = su_x - orig_x;
- int dy2 = su_y - orig_y;
-
- r3 = sraRgnCreateRgn(r2);
- sraRgnOffset(r2, dx2, dy2);
-
- dx = su_x - x;
- dy = su_y - y;
- sraRgnOffset(r3, dx, dy);
-
- dx = dx - dx2;
- dy = dy - dy2;
-
-if (db && ncdb) fprintf(stderr, "FB_COPY: %.4f 4) move overlap inside su:\n", dnow() - ntim);
- if (! use_batch) {
- do_copyregion(r3, dx, dy, 0);
- if (!fb_push_wait(0.2, FB_COPY)) {
-if (db) fprintf(stderr, "FB_COPY: %.4f 4) FAILED.\n", dnow() - ntim);
- fb_push_wait(0.1, FB_COPY);
- }
- } else {
- batch_dxs[NPP_nreg] = dx;
- batch_dys[NPP_nreg] = dy;
- batch_reg[NPP_nreg++] = sraRgnCreateRgn(r3);
- }
- }
- sraRgnDestroy(r0);
- sraRgnDestroy(r1);
- sraRgnDestroy(r2);
-
- /* 5) copy our temporary stuff from bs to su: */
- dx = su_x - bs_x;
- dy = su_y - bs_y;
- if (NPP_r_bs_tmp == NULL) {
- r1 = sraRgnCreateRect(su_x, su_y, su_x + su_w, su_y + su_h);
- } else {
- r1 = sraRgnCreateRgn(NPP_r_bs_tmp);
- sraRgnOffset(r1, dx, dy);
- sraRgnDestroy(NPP_r_bs_tmp);
- }
- if (r3 != NULL) {
- sraRgnSubtract(r1, r3);
- sraRgnDestroy(r3);
- }
-if (db) fprintf(stderr, "FB_COPY: %.4f 5) move tmp bs to su:\n", dnow() - ntim);
- if (! use_batch) {
- do_copyregion(r1, dx, dy, 0);
- if (!fb_push_wait(0.2, FB_COPY)) {
-if (db) fprintf(stderr, "FB_COPY: %.4f 5) FAILED.\n", dnow() - ntim);
- fb_push_wait(0.1, FB_COPY);
- }
- } else {
- batch_dxs[NPP_nreg] = dx;
- batch_dys[NPP_nreg] = dy;
- batch_reg[NPP_nreg++] = sraRgnCreateRgn(r1);
- }
- if (! sraRgnEmpty(r1)) {
- some_su = 1;
- }
- sraRgnDestroy(r1);
-
- /* 6) not really necessary, update bs with current view: */
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- r1 = sraRgnCreateRect(x, y, x + w, y + h);
- sraRgnAnd(r1, r0);
- dx = bs_x - x;
- dy = bs_y - y;
- sraRgnOffset(r1, dx, dy);
-if (db) fprintf(stderr, "FB_COPY: %.4f 6) snapshot bs:\n", dnow() - ntim);
- if (! use_batch) {
- do_copyregion(r1, dx, dy, 0);
- if (!fb_push_wait(0.2, FB_COPY)) {
-if (db) fprintf(stderr, "FB_COPY: %.4f 6) FAILED.\n", dnow() - ntim);
- fb_push_wait(0.1, FB_COPY);
- }
- } else {
- batch_dxs[NPP_nreg] = dx;
- batch_dys[NPP_nreg] = dy;
- batch_reg[NPP_nreg++] = sraRgnCreateRgn(r1);
- }
- sraRgnDestroy(r0);
- sraRgnDestroy(r1);
-
- if (use_batch) {
- batch_push(NPP_nreg, batch_delay);
-if (ncdb) fprintf(stderr, "FB_COPY: %.4f XX did batch 0x%x %3d su: %dx%d+%d+%d bs: %dx%d+%d+%d\n", dnow() - ntim,
- (unsigned int) cache_list[nidx].win, nidx, su_w, su_h, su_x, su_y, bs_w, bs_h, bs_x, bs_y);
- }
- cache_list[nidx].x = x + np;
- cache_list[nidx].y = y + np;
-
- /* XXX Y */
- cache_list[nidx].bs_time = dnow();
- if (some_su) {
- cache_list[nidx].su_time = dnow();
- }
- } else {
- if (use_batch) {
- batch_push(NPP_nreg, batch_delay);
- }
- }
-
- if (scaling) {
- sraRect rects[2];
-
- rects[0].x1 = orig_x;
- rects[0].y1 = orig_y;
- rects[0].x2 = orig_w;
- rects[0].y2 = orig_h;
-
- rects[1].x1 = x;
- rects[1].y1 = y;
- rects[1].x2 = w;
- rects[1].y2 = h;
- push_borders(rects, 2);
- }
-}
-
-void do_copyrect_drag_move(Window orig_frame, Window frame, int *nidx, int try_batch,
- int now_x, int now_y, int orig_w, int orig_h, int x, int y, int w, int h, double batch_delay) {
-
- int sent_copyrect = 1, obscured = 0;
- int dx, dy;
- int use_batch = 0;
- double ntim = dnow();
- static int nob = -1;
- sraRegionPtr r0, r1;
-
- if (nob < 0) {
- if (getenv("NOCRBATCH")) {
- nob = 1;
- } else {
- nob = 0;
- }
- }
- if (nob) {
- try_batch = 0;
- }
-
- dx = x - now_x;
- dy = y - now_y;
- if (dx == 0 && dy == 0) {
- return;
- }
-if (ncdb) fprintf(stderr, "do_COPY: now_xy: %d %d, orig_wh: %d %d, xy: %d %d, wh: %d %d\n",now_x, now_y, orig_w, orig_h, x, y, w, h);
-
- ncache_pre_portions(orig_frame, frame, nidx, try_batch, &use_batch,
- now_x, now_y, orig_w, orig_h, x, y, w, h, ntim);
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- r1 = sraRgnCreateRect(x, y, x + w, y + h);
- sraRgnAnd(r1, r0);
-
- dx = x - now_x;
- dy = y - now_y;
-
- /* make sure the source is on-screen too */
- sraRgnOffset(r1, -dx, -dy);
- sraRgnAnd(r1, r0);
- sraRgnOffset(r1, +dx, +dy);
- sraRgnAnd(r1, r0); /* just to be sure, problably not needed */
-
- if (! use_batch) {
- do_copyregion(r1, dx, dy, 0);
- if (!fb_push_wait(0.2, FB_COPY)) {
-if (ncdb) fprintf(stderr, "FB_COPY: %.4f 3) *FAILED*\n", dnow() - ntim);
- fb_push_wait(0.1, FB_COPY);
- }
- } else {
- batch_dxs[NPP_nreg] = dx;
- batch_dys[NPP_nreg] = dy;
- batch_reg[NPP_nreg++] = sraRgnCreateRgn(r1);
- }
- sraRgnDestroy(r0);
- sraRgnDestroy(r1);
-
- if (sent_copyrect) {
- if (use_batch) {
- ;
- } else if (! obscured) {
- fb_push_wait(0.1, FB_COPY);
- } else {
- /* no diff for now... */
- fb_push_wait(0.1, FB_COPY);
- }
- ncache_post_portions(*nidx, use_batch,
- now_x, now_y, orig_w, orig_h, x, y, w, h, batch_delay, ntim);
- }
-if (ncdb) fprintf(stderr, "do_COPY: %.4f -- post_portion done.\n", dnow() - ntim);
-}
-
-void check_macosx_iconify(Window orig_frame, Window frame, int flush) {
-#ifdef MACOSX
- static double last = 0.0;
- double now;
- int j, m = 5, idx = -1, ok = 0, unmapped = 0;
-
- if (! macosx_console) {
- return;
- }
-
- now = dnow();
- if (now < last + 0.3) {
- return;
- }
- last = now;
-
- if (ncache > 0 && orig_frame != None) {
- idx = lookup_win_index(orig_frame);
- if (idx >= 0) {
- if (cache_list[idx].map_state == IsUnmapped) {
-if (0) fprintf(stderr, "FAW orig_frame unmapped.\n");
- unmapped = 1;
- m = 3;
- }
- }
- }
-
- if (unmapped) {
- ;
- } else if (orig_frame && macosxCGS_follow_animation_win(orig_frame, -1, 0)) {
- if (0) fprintf(stderr, "FAW orig_frame %d\n", (int) orig_frame);
- } else if (0 && frame && macosxCGS_follow_animation_win(frame, -1, 0)) {
- if (0) fprintf(stderr, "FAW frame %d\n", (int) frame);
- }
- for (j=0; j<m; j++) {
- macosxCGS_get_all_windows();
- if (macosx_checkevent(NULL)) {
- ok = 1;
- if (0) fprintf(stderr, "Check Event 1\n");
- } else {
- if (0) fprintf(stderr, "Check Event 0\n");
- }
- if (ok) {
- break;
- }
- usleep(10 * 1000);
- }
- if (ok) {
- if (flush) {
- fb_push_wait(0.1, FB_COPY|FB_MOD);
- }
- check_ncache(0, 2);
- }
-#else
- if (!orig_frame || !frame || !flush) {}
-#endif
-}
-
-void check_macosx_click_frame(void) {
-#ifdef MACOSX
- if (macosx_console) {
-if (0) fprintf(stderr, "macosx_click_frame: 0x%x\n", macosx_click_frame);
- check_macosx_iconify(macosx_click_frame, None, 0);
- macosx_click_frame = None;
- if (button_mask && !macosx_checkevent(NULL)) {
- check_macosx_iconify(None, None, 0);
- }
- }
-#endif
-}
-
-int clipped(int idx);
-void snap_old(void);
-
-int check_copyrect_raise(int idx, Window orig_frame, int try_batch) {
- char *no = "none";
- int doraise = 1;
- int valid;
- XWindowAttributes attr;
-
- if (! ncache_wf_raises) {
- doraise = 0;
- no = "ncache_wf_raises";
- } else if (cache_list[idx].bs_time == 0.0) {
- doraise = 0;
- no = "bs_time";
- } else if (0 && cache_list[idx].vis_state == VisibilityUnobscured) {
- doraise = 0;
- no = "VisibilityUnobscured";
- } else if (!clipped(idx)) {
- doraise = 0;
- no = "!clipped()";
- }
- if (doraise) {
- int nr = 0, *nb = NULL;
-if (ncdb) fprintf(stderr, "--YES, wf_raise\n");
- if (try_batch) {
- nb = &nr;
- }
- valid = 1;
- bs_restore(idx, nb, NULL, &attr, 0, 1, &valid, 1);
- try_to_fix_su(orig_frame, idx, 0x1, nb, NULL);
- if (nb && nr) {
- batch_push(nr, -1.0);
- }
- fb_push(); /* XXX Y */
- } else {
-if (ncdb && no) fprintf(stderr, "--NO, wf_raise: %s\n", no);
- }
- if (ncache_wf_raises) {
- snapshot_stack_list(0, 0.0);
- snap_old();
- }
- return 1;
-}
-
-int set_copyrect_drag(int idx, Window orig_frame, int try_batch) {
- if (idx < 0) {
- return 0;
- }
- if (cache_list[idx].su_time > 0.0) {
- check_copyrect_raise(idx, orig_frame, try_batch);
- return 1;
- }
- return 0;
-}
-
-/*
- * Applied just before any check_user_input() modes. Look for a
- * ButtonPress; find window it happened in; find the wm frame window
- * for it; watch for that window moving or resizing. If it does, do the
- * wireframe animation. Do this until ButtonRelease or timeouts occur.
- * Remove wireframe.
- *
- * Under -nowirecopyrect, return control to base scheme
- * (check_user_input() ...) that will repaint the screen with the window
- * in the new postion or size. Under -wirecopyrect, apply rfbDoCopyRect
- * or rfbDoCopyRegion: this "pollutes" our framebuffer, but the normal
- * polling will quickly repair it. Under happy circumstances, this
- * reduces actual XShmGetImage work (i.e. if we correctly predicted how
- * the X fb has changed.
- *
- * -scale doesn't always work under -wirecopyrect, but the wireframe does.
- *
- * testing of this mode under -threads is incomplete.
- *
- * returns 1 if it did an animation, 0 if no move/resize triggers
- * went off.
- *
- * TBD: see if we can select StructureNotify ConfigureNotify events for
- * the toplevel windows to get better info on moves and resizes.
- */
-int check_wireframe(void) {
- Window frame = None, orig_frame = None;
- XWindowAttributes attr;
- int dx, dy;
-
- int orig_px, orig_py, orig_x, orig_y, orig_w, orig_h;
- int px, py, x, y, w, h;
- int box_x, box_y, box_w, box_h;
- int orig_cursor_x, orig_cursor_y, g, gd;
- int already_down = 0, win_gone = 0, win_unmapped = 0;
- double spin = 0.0, tm, last_ptr = 0.0, last_draw;
-
- int frame_changed = 0, drew_box = 0, got_2nd_pointer = 0;
- int try_copyrect_drag = 1, do_copyrect_drag = -1;
- int now_x = 0, now_y = 0, nidx = -1;
- double copyrect_drag_delay = -1.0;
- int try_batch = 1; /* XXX Y */
- int mac_skip = 0;
-
- int special_t1 = 0, break_reason = 0, last_draw_cnt = 0, gpi = 0;
- static double first_dt_ave = 0.0;
- static int first_dt_cnt = 0;
- static time_t last_save_stacklist = 0;
- int bdown0, bdown, gotui, cnt = 0;
-
- /* heuristics: */
- double first_event_spin = wireframe_t1;
- double frame_changed_spin = wireframe_t2;
- double max_spin = wireframe_t3;
- double min_draw = wireframe_t4;
- int try_it = 0;
- DB_SET
-
- if (unixpw_in_progress) return 0;
- if (copyrect_drag_delay) {}
-
-#ifdef MACOSX
- if (macosx_console) {
- ;
- } else {
- RAWFB_RET(0)
- }
-#else
- RAWFB_RET(0)
-#endif
-
- if (nofb) {
- return 0;
- }
- if (subwin) {
- return 0; /* don't even bother for -id case */
- }
-
-if (db > 1 && button_mask) fprintf(stderr, "check_wireframe: bm: %d gpi: %d\n", button_mask, got_pointer_input);
-
- bdown0 = 0;
- if (button_mask) {
- bdown0 = 1;
- } else if (wireframe_local && display_button_mask) {
- bdown0 = 2;
- }
- if (! bdown0) {
- return 0; /* no button pressed down */
- }
-
- gotui = 0;
- if (got_pointer_input) {
- gotui = 1;
- } else if (wireframe_local && display_button_mask) {
- gotui = 2;
- }
- if (!use_threads && !gotui) {
- return 0; /* need ptr input, e.g. button down, motion */
- }
-
-if (db > 1) fprintf(stderr, "check_wireframe: %d\n", db);
-
-if (db) fprintf(stderr, "\n*** button down!! x: %d y: %d\n", cursor_x, cursor_y);
-
- /*
- * Query where the pointer is and which child of the root
- * window. We will assume this is the frame the window manager
- * makes when it reparents the toplevel window.
- */
- X_LOCK;
- if (! get_wm_frame_pos(&px, &py, &x, &y, &w, &h, &frame, NULL)) {
-if (db) fprintf(stderr, "NO get_wm_frame_pos-1: 0x%lx\n", frame);
- X_UNLOCK;
-#ifdef MACOSX
- check_macosx_click_frame();
-#endif
- return 0;
- }
- X_UNLOCK;
-
- last_get_wm_frame_time = dnow();
- last_get_wm_frame = frame;
-
-if (db) fprintf(stderr, "a: %d wf: %.3f A: %d origfrm: 0x%lx\n", w*h, wireframe_frac, (dpy_x*dpy_y), frame);
-
- /*
- * apply the percentage size criterion (allow opaque moves for
- * small windows)
- */
- if ((double) w*h < wireframe_frac * (dpy_x * dpy_y)) {
-if (db) fprintf(stderr, "small window %.3f\n", ((double) w*h)/(dpy_x * dpy_y));
- return 0;
- }
-if (db) fprintf(stderr, " frame: x: %d y: %d w: %d h: %d px: %d py: %d fr: 0x%lx\n", x, y, w, h, px, py, frame);
-
- /*
- * see if the pointer is within range of the assumed wm frame
- * decorations on the edge of the window.
- */
-
- try_it = near_wm_edge(x, y, w, h, px, py);
-
- /* Often Alt+ButtonDown starts a window move: */
- if (! try_it && wireframe_mod_state()) {
- try_it = 1;
- }
- if (try_it && clipshift) {
- sraRegionPtr r1, r2;
- int xc = off_x + coff_x;
- int yc = off_y + coff_y;
- r1 = sraRgnCreateRect(x, y, x+w, y+h);
- r2 = sraRgnCreateRect(xc, yc, xc+dpy_x, yc+dpy_y);
- if (!sraRgnAnd(r1, r2)) {
-if (db) fprintf(stderr, "OUTSIDE CLIPSHIFT\n");
- try_it = 0;
- }
- sraRgnDestroy(r1);
- sraRgnDestroy(r2);
- }
- if (! try_it) {
-if (db) fprintf(stderr, "INTERIOR\n");
-#ifdef MACOSX
- check_macosx_click_frame();
-#endif
- return 0;
- }
-
- wireframe_in_progress = 1;
-
- if (button_mask_prev) {
- already_down = 1;
- }
-
- if (! wireframe_str || !strcmp(wireframe_str, WIREFRAME_PARMS)) {
- int link, latency, netrate;
- static int didmsg = 0;
-
- link = link_rate(&latency, &netrate);
- if (link == LR_DIALUP || link == LR_BROADBAND) {
- /* slow link, e.g. dialup, increase timeouts: */
- first_event_spin *= 2.0;
- frame_changed_spin *= 2.0;
- max_spin *= 2.0;
- min_draw *= 1.5;
- if (link == LR_DIALUP) {
- max_spin *= 1.2;
- min_draw *= 1.7;
- }
- if (! didmsg) {
- rfbLog("increased wireframe timeouts for "
- "slow network connection.\n");
- rfbLog("netrate: %d KB/sec, latency: %d ms\n",
- netrate, latency);
- didmsg = 1;
- }
- }
- }
-
- /*
- * pointer() should have snapped the stacking list for us, if
- * not, do it now (if the XFakeButtonEvent has been flushed by
- * now the stacking order may be incorrect).
- */
- if (strcmp(wireframe_copyrect, "never")) {
- if (already_down) {
- double age = 0.0;
- /*
- * see if we can reuse the stack list (pause
- * with button down)
- */
- if (stack_list_num) {
- int k, got_me = 0;
- for (k = stack_list_num -1; k >=0; k--) {
- if (frame == stack_list[k].win) {
- got_me = 1;
- break;
- }
- }
- if (got_me) {
- age = 1.0;
- }
- snapshot_stack_list(0, age);
- }
- }
- if (! stack_list_num) {
- snapshot_stack_list(0, 0.0);
- }
- }
-
-
- /* store initial parameters, we look for changes in them */
- orig_frame = frame;
- orig_px = px; /* pointer position */
- orig_py = py;
- orig_x = x; /* frame position */
- orig_y = y;
- orig_w = w; /* frame size */
- orig_h = h;
-
- orig_cursor_x = cursor_x;
- orig_cursor_y = cursor_y;
-
- /* this is the box frame we would draw */
- box_x = x;
- box_y = y;
- box_w = w;
- box_h = h;
-
- dtime0(&tm);
-
- last_draw = spin;
-
- /* -threads support for check_wireframe() is rough... crash? */
- if (use_threads) {
- /* purge any stored up pointer events: */
- pointer_event(-1, 0, 0, NULL);
- }
-
- if (cursor_noshape_updates_clients(screen)) {
- try_batch = 0;
- }
- if (rotating) {
- try_batch = 0;
- }
- if (use_threads && ncache > 0 && ncache_copyrect) {
- try_batch = 0;
- }
-
- g = got_pointer_input;
- gd = got_local_pointer_input;
-
- while (1) {
-
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
-
- /* try to induce/waitfor some more user input */
- if (use_threads) {
- usleep(1000);
- } else if (drew_box && do_copyrect_drag != 1) {
- rfbPE(1000);
- } else {
- rfbCFD(1000);
- }
- if (bdown0 == 2) {
- /*
- * This is to just update display_button_mask
- * which will also update got_local_pointer_input.
- */
- check_x11_pointer();
-#if 0
- /* what was this for? */
- Window frame;
- int px, py, x, y, w, h;
-#ifdef MACOSX
- if (macosx_console) {
- macosx_get_cursor_pos(&x, &y);
- }
- else
-#endif
- get_wm_frame_pos(&px, &py, &x, &y, &w, &h, &frame, NULL);
-#endif
- }
-
- cnt++;
- spin += dtime(&tm);
-
-if (0) fprintf(stderr, "wf-spin: %.3f\n", spin);
-
- /* check for any timeouts: */
- if (frame_changed) {
- double delay;
- /* max time we play this game: */
- if (spin > max_spin) {
-if (db || db2) fprintf(stderr, " SPIN-OUT-MAX: %.3f\n", spin);
- break_reason = 1;
- break;
- }
- /* watch for pointer events slowing down: */
- if (special_t1) {
- delay = max_spin;
- } else {
- delay = 2.0* frame_changed_spin;
- if (spin > 3.0 * frame_changed_spin) {
- delay = 1.5 * delay;
- }
- }
- if (spin > last_ptr + delay) {
-if (db || db2) fprintf(stderr, " SPIN-OUT-NOT-FAST: %.3f\n", spin);
- break_reason = 2;
- break;
- }
- } else if (got_2nd_pointer) {
- /*
- * pointer is moving, max time we wait for wm
- * move or resize to be detected
- */
- if (spin > frame_changed_spin) {
-if (db || db2) fprintf(stderr, " SPIN-OUT-NOFRAME-SPIN: %.3f\n", spin);
- break_reason = 3;
- break;
- }
- } else {
- /* max time we wait for any pointer input */
- if (spin > first_event_spin) {
-if (db || db2) fprintf(stderr, " SPIN-OUT-NO2ND_PTR: %.3f\n", spin);
- break_reason = 4;
- break;
- }
- }
-
- gpi = 0;
- /* see if some pointer input occurred: */
- if (got_pointer_input > g ||
- (wireframe_local && (got_local_pointer_input > gd))) {
-
-if (db) fprintf(stderr, " ++pointer event!! [%02d] dt: %.3f x: %d y: %d mask: %d\n",
- got_2nd_pointer+1, spin, cursor_x, cursor_y, button_mask);
-
- g = got_pointer_input;
- gd = got_local_pointer_input;
- gpi = 1;
-
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
-
- /* periodically try to let the wm get moving: */
- if (!frame_changed && got_2nd_pointer % 4 == 0) {
- if (got_2nd_pointer == 0) {
- usleep(50 * 1000);
- } else {
- usleep(25 * 1000);
- }
- }
- got_2nd_pointer++;
- last_ptr = spin;
-
- /*
- * see where the pointer currently is. It may
- * not be our starting frame (i.e. mouse now
- * outside of the moving window).
- */
- frame = 0x0;
- X_LOCK;
-
- if (! get_wm_frame_pos(&px, &py, &x, &y, &w, &h,
- &frame, NULL)) {
- frame = 0x0;
-if (db) fprintf(stderr, "NO get_wm_frame_pos-2: 0x%lx\n", frame);
- }
-
- if (frame != orig_frame) {
- /* see if our original frame is still there */
- if (!valid_window(orig_frame, &attr, 1)) {
- X_UNLOCK;
- /* our window frame went away! */
- win_gone = 1;
-if (db) fprintf(stderr, "FRAME-GONE: 0x%lx\n", orig_frame);
- break_reason = 5;
- break;
- }
- if (attr.map_state == IsUnmapped) {
- X_UNLOCK;
- /* our window frame is now unmapped! */
- win_unmapped = 1;
-if (db) fprintf(stderr, "FRAME-UNMAPPED: 0x%lx\n", orig_frame);
- break_reason = 5;
- break;
- }
-
-if (db) fprintf(stderr, "OUT-OF-FRAME: old: x: %d y: %d px: %d py: %d 0x%lx\n", x, y, px, py, frame);
-
- /* new parameters for our frame */
- x = attr.x; /* n.b. rootwin is parent */
- y = attr.y;
- w = attr.width;
- h = attr.height;
- }
- X_UNLOCK;
-
-if (db) fprintf(stderr, " frame: x: %d y: %d w: %d h: %d px: %d py: %d fr: 0x%lx\n", x, y, w, h, px, py, frame);
-if (db) fprintf(stderr, " MO,PT,FR: %d/%d %d/%d %d/%d\n", cursor_x - orig_cursor_x, cursor_y - orig_cursor_y, px - orig_px, py - orig_py, x - orig_x, y - orig_y);
-
- if (frame_changed && frame != orig_frame) {
-if (db) fprintf(stderr, "CHANGED and window switch: 0x%lx\n", frame);
- }
- if (frame_changed && px - orig_px != x - orig_x) {
-if (db) fprintf(stderr, "MOVED and diff DX\n");
- }
- if (frame_changed && py - orig_py != y - orig_y) {
-if (db) fprintf(stderr, "MOVED and diff DY\n");
- }
-
- /* check and see if our frame has been resized: */
- if (!frame_changed && (w != orig_w || h != orig_h)) {
- int n;
- if (!already_down) {
- first_dt_ave += spin;
- first_dt_cnt++;
- }
- n = first_dt_cnt ? first_dt_cnt : 1;
- frame_changed = 2;
-
-if (db) fprintf(stderr, "WIN RESIZE 1st-dt: %.3f\n", first_dt_ave/n);
- }
-
- /* check and see if our frame has been moved: */
- if (!frame_changed && (x != orig_x || y != orig_y)) {
- int n;
- if (!already_down) {
- first_dt_ave += spin;
- first_dt_cnt++;
- }
- n = first_dt_cnt ? first_dt_cnt : 1;
- frame_changed = 1;
-if (db) fprintf(stderr, "FRAME MOVE 1st-dt: %.3f\n", first_dt_ave/n);
- }
- }
-
- /*
- * see if it is time to draw any or a new wireframe box
- */
-
- if (frame_changed) {
- int drawit = 0;
- if (x != box_x || y != box_y) {
- /* moved since last */
-if (0) fprintf(stderr, "DRAW1 %d %d\n", x - box_x, y - box_y);
- drawit = 1;
- } else if (w != box_w || h != box_h) {
- /* resize since last */
- drawit = 1;
- }
- if (drawit) {
- int doit = 0;
- /*
- * check time (to avoid too much
- * animations on slow machines
- * or links).
- */
- if (gpi) {
- if (spin > last_draw + min_draw || ! drew_box) {
- doit = 1;
- }
- if (macosx_console && doit && !mac_skip) {
- if (x != box_x && y != box_y && w != box_w && h != box_h) {
- doit = 0;
- } else if (!button_mask) {
- doit = 0;
- }
- mac_skip++;
- }
- } else {
- if (drew_box && cnt > last_draw_cnt) {
- doit = 1;
-if (0) fprintf(stderr, "*** NO GPI DRAW_BOX\n");
- }
- }
-
- if (doit) {
- if (try_copyrect_drag && ncache > 0) {
- if (!ncache_copyrect) {
- do_copyrect_drag = 0;
- } else if (w != box_w || h != box_h) {
- do_copyrect_drag = 0;
- } else if (do_copyrect_drag < 0) {
- Window fr = orig_frame;
- int idx = lookup_win_index(fr);
- if (idx < 0) {
- fr = frame;
- idx = lookup_win_index(fr);
- }
- if (idx >= 0) {
- do_copyrect_drag = set_copyrect_drag(idx, fr, try_batch);
- if (do_copyrect_drag) {
- min_draw *= 0.66;
- }
- nidx = idx;
- } else {
- do_copyrect_drag = 0;
- }
- now_x = orig_x;
- now_y = orig_y;
- }
- if (do_copyrect_drag) {
- if (orig_w != w || orig_h != h) {
- do_copyrect_drag = 0;
- }
- }
- }
-
- if (do_copyrect_drag <= 0) {
- if (ncache <= 0) {
- ;
- } else if (!drew_box && ncache_wf_raises) {
- Window fr = orig_frame;
- int idx = lookup_win_index(fr);
- if (idx < 0) {
- fr = frame;
- idx = lookup_win_index(fr);
- }
- if (idx >= 0) {
- check_copyrect_raise(idx, fr, try_batch);
- }
- }
- draw_box(x, y, w, h, 0);
- fb_push(); /* XXX Y */
- rfbPE(1000);
- } else {
-#ifndef NO_NCACHE
- int tb = use_threads ? 0 : try_batch;
- do_copyrect_drag_move(orig_frame, frame, &nidx,
- tb, now_x, now_y, orig_w, orig_h, x, y, w, h,
- copyrect_drag_delay);
- now_x = x;
- now_y = y;
- if (copyrect_drag_delay == -1.0) {
- copyrect_drag_delay = 0.04;
- }
-#endif
- }
- drew_box = 1;
- last_wireframe = dnow();
-
- last_draw = spin;
- last_draw_cnt = cnt;
- }
- }
- box_x = x;
- box_y = y;
- box_w = w;
- box_h = h;
- }
-
- /*
- * Now (not earlier) check if the button has come back up.
- * we check here to get a better location and size of
- * the final window.
- */
- bdown = 0;
- if (button_mask) {
- bdown = 1;
- } else if (wireframe_local && display_button_mask) {
- bdown = 2;
- }
- if (! bdown) {
-if (db || db2) fprintf(stderr, "NO button_mask\n");
- break_reason = 6;
- break;
- }
- }
-
- if (! drew_box) {
- /* nice try, but no move or resize detected. cleanup. */
- if (stack_list_num) {
- stack_list_num = 0;
- }
- wireframe_in_progress = 0;
- if (macosx_console && (break_reason == 6 || break_reason == 5)) {
- check_macosx_iconify(orig_frame, frame, drew_box);
- }
- return 0;
- }
-
- /* remove the wireframe */
- if (do_copyrect_drag <= 0) {
- draw_box(0, 0, 0, 0, 1);
- fb_push(); /* XXX Y */
- } else {
- int tb = use_threads ? 0 : try_batch;
- do_copyrect_drag_move(orig_frame, frame, &nidx,
- tb, now_x, now_y, orig_w, orig_h, x, y, w, h, -1.0);
- fb_push_wait(0.15, FB_COPY|FB_MOD);
- }
-
- dx = x - orig_x;
- dy = y - orig_y;
-
- /*
- * see if we can apply CopyRect or CopyRegion to the change:
- */
- if (!strcmp(wireframe_copyrect, "never")) {
- ;
- } else if (win_gone || win_unmapped) {
- ;
- } else if (skip_cr_when_scaling("wireframe")) {
- ;
- } else if (w != orig_w || h != orig_h) {
- if (ncache > 0) {
- try_to_fix_resize_su(orig_frame, orig_x, orig_y, orig_w, orig_h, x, y, w, h, try_batch);
- X_LOCK;
- clear_win_events(orig_frame, 1);
- if (frame != orig_frame) {
- clear_win_events(frame, 1);
- }
- X_UNLOCK;
- }
- } else if (dx == 0 && dy == 0) {
- ;
- } else if (do_copyrect_drag > 0) {
- X_LOCK;
- clear_win_events(NPP_nwin, 0);
- X_UNLOCK;
- } else {
- int spin_ms = (int) (spin * 1000 * 1000);
- int obscured, sent_copyrect = 0;
-
- int nidx = -1;
- int use_batch = 0;
- double ntim;
-
- /*
- * set a timescale comparable to the spin time,
- * but not too short or too long.
- */
- if (spin_ms < 30) {
- spin_ms = 30;
- } else if (spin_ms > 400) {
- spin_ms = 400;
- }
- ntim = dnow();
-
- /* try to flush the wireframe removal: */
-if (ncdb && ncache) fprintf(stderr, "\nSEND_COPYRECT %.4f %.4f\n", dnowx(), dnow() - ntim);
-
- if (! fb_push_wait(0.15, FB_COPY|FB_MOD)) {
-
-if (ncdb && ncache) fprintf(stderr, "FB_COPY *FAILED*, try one more... %.4f", dnow() - ntim);
-
- if (! fb_push_wait(0.15, FB_COPY|FB_MOD)) {
-
-if (ncdb && ncache) fprintf(stderr, "FB_COPY *FAILED* again! %.4f", dnow() - ntim);
-
- }
- }
-
- ncache_pre_portions(orig_frame, frame, &nidx, try_batch, &use_batch,
- orig_x, orig_y, orig_w, orig_h, x, y, w, h, ntim);
-
- /* 2) try to send a clipped copyrect of translation: */
-
- if (! try_batch) {
- sent_copyrect = try_copyrect(orig_frame, frame, x, y, w, h, dx, dy,
- &obscured, NULL, 0.15, NULL);
- } else {
- try_copyrect(orig_frame, frame, x, y, w, h, dx, dy,
- &obscured, NULL, 0.15, &NPP_nreg); /* XXX */
- sent_copyrect = 1;
- use_batch = 1;
- }
-
-if ((ncache || db) && ncdb) fprintf(stderr, "sent_copyrect: %d - obs: %d frame: 0x%lx\n", sent_copyrect, obscured, frame);
- if (sent_copyrect) {
- /* try to push the changes to viewers: */
- if (use_batch) {
- ;
- } else if (! obscured) {
- fb_push_wait(0.1, FB_COPY);
- } else {
- /* no diff for now... */
- fb_push_wait(0.1, FB_COPY);
- }
- ncache_post_portions(nidx, use_batch,
- orig_x, orig_y, orig_w, orig_h, x, y, w, h, -1.0, ntim);
- X_LOCK;
- clear_win_events(NPP_nwin, 0);
- X_UNLOCK;
-
- if (scaling && !use_batch) {
- static double last_time = 0.0;
- double now = dnow(), delay = 0.35;
-
- fb_push_wait(0.1, FB_COPY);
-
- if (now > last_time + delay) {
- int xt = x, yt = y;
-
- if (clipshift) {
- xt -= coff_x;
- yt -= coff_y;
- }
- if (subwin) {
- xt -= off_x;
- yt -= off_y;
- }
-
- scale_mark(xt, yt, xt+w, yt+h, 1);
- last_time = now;
- last_copyrect_fix = now;
- }
- }
- }
- }
-
- if (stack_list_num) {
- /* clean up stack_list for next time: */
- if (break_reason == 1 || break_reason == 2) {
- /*
- * save the stack list, perhaps the user has
- * paused with button down.
- */
- last_save_stacklist = time(NULL);
- } else {
- stack_list_num = 0;
- }
- }
-
- /* final push (for -nowirecopyrect) */
- rfbPE(1000);
- wireframe_in_progress = 0;
-
- if (1) {
- /* In principle no longer needed... see draw_box() */
- if (frame_changed && cmap8to24 /* && multivis_count */) {
- /* handle -8to24 kludge, mark area and check 8bpp... */
- int x1, x2, y1, y2, f = 16;
- x1 = nmin(box_x, orig_x) - f;
- y1 = nmin(box_y, orig_y) - f;
- x2 = nmax(box_x + box_w, orig_x + orig_w) + f;
- y2 = nmax(box_y + box_h, orig_y + orig_h) + f;
- x1 = nfix(x1, dpy_x);
- x2 = nfix(x2, dpy_x+1);
- y1 = nfix(y1, dpy_y);
- y2 = nfix(y2, dpy_y+1);
- if (0) {
- check_for_multivis();
- mark_rect_as_modified(x1, y1, x2, y2, 0);
- } else {
- if (1) {
- bpp8to24(x1, y1, x2, y2);
- } else {
- bpp8to24(0, 0, dpy_x, dpy_y);
- }
- }
- }
- }
-
- urgent_update = 1;
- if (use_xdamage) {
- /* DAMAGE can queue ~1000 rectangles for a move */
- clear_xdamage_mark_region(NULL, 1);
- xdamage_scheduled_mark = dnow() + 2.0;
- }
-
- if (macosx_console && (break_reason == 6 || break_reason == 5)) {
- check_macosx_iconify(orig_frame, frame, drew_box);
- }
-
- return 1;
-}
-
-/*
- * We need to handle user input, particularly pointer input, carefully.
- * This function is only called when non-threaded. Note that
- * rfbProcessEvents() only processes *one* pointer event per call,
- * so if we interlace it with scan_for_updates(), we can get swamped
- * with queued up pointer inputs. And if the pointer inputs are inducing
- * large changes on the screen (e.g. window drags), the whole thing
- * bogs down miserably and only comes back to life at some time after
- * one stops moving the mouse. So, to first approximation, we are trying
- * to eat as much user input here as we can using some hints from the
- * duration of the previous scan_for_updates() call (in dt).
- *
- * note: we do this even under -nofb
- *
- * return of 1 means watch_loop should short-circuit and reloop,
- * return of 0 means watch_loop should proceed to scan_for_updates().
- * (this is for pointer_mode == 1 mode, the others do it all internally,
- * cnt is also only for that mode).
- */
-
-static void check_user_input2(double dt) {
-
- int eaten = 0, miss = 0, max_eat = 50, do_flush = 1;
- int g, g_in;
- double spin = 0.0, tm;
- double quick_spin_fac = 0.40;
- double grind_spin_time = 0.175;
-
- dtime0(&tm);
- g = g_in = got_pointer_input;
- if (!got_pointer_input) {
- return;
- }
- /*
- * Try for some "quick" pointer input processing.
- *
- * About as fast as we can, we try to process user input calling
- * rfbProcessEvents or rfbCheckFds. We do this for a time on
- * order of the last scan_for_updates() time, dt, but if we stop
- * getting user input we break out. We will also break out if
- * we have processed max_eat inputs.
- *
- * Note that rfbCheckFds() does not send any framebuffer updates,
- * so is more what we want here, although it is likely they have
- * all be sent already.
- */
- while (1) {
- if (show_multiple_cursors) {
- rfbPE(1000);
- } else {
- rfbCFD(1000);
- }
- rfbCFD(0);
-
- spin += dtime(&tm);
-
- if (spin > quick_spin_fac * dt) {
- /* get out if spin time comparable to last scan time */
- break;
- }
- if (got_pointer_input > g) {
- int i, max_extra = max_eat / 2;
- g = got_pointer_input;
- eaten++;
- for (i=0; i<max_extra; i++) {
- rfbCFD(0);
- if (got_pointer_input > g) {
- g = got_pointer_input;
- eaten++;
- } else if (i > 1) {
- break;
- }
- }
- X_LOCK;
- do_flush = 0;
-if (0) fprintf(stderr, "check_user_input2-A: XFlush %.4f\n", tm);
- XFlush_wr(dpy);
- X_UNLOCK;
- if (eaten < max_eat) {
- continue;
- }
- } else {
- miss++;
- }
- if (miss > 1) { /* 1 means out on 2nd miss */
- break;
- }
- }
- if (do_flush) {
- X_LOCK;
-if (0) fprintf(stderr, "check_user_input2-B: XFlush %.4f\n", tm);
- XFlush_wr(dpy);
- X_UNLOCK;
- }
-
-
- /*
- * Probably grinding with a lot of fb I/O if dt is this large.
- * (need to do this more elegantly)
- *
- * Current idea is to spin our wheels here *not* processing any
- * fb I/O, but still processing the user input. This user input
- * goes to the X display and changes it, but we don't poll it
- * while we "rest" here for a time on order of dt, the previous
- * scan_for_updates() time. We also break out if we miss enough
- * user input.
- */
- if (dt > grind_spin_time) {
- int i, ms, split = 30;
- double shim;
-
- /*
- * Break up our pause into 'split' steps. We get at
- * most one input per step.
- */
- shim = 0.75 * dt / split;
-
- ms = (int) (1000 * shim);
-
- /* cutoff how long the pause can be */
- if (split * ms > 300) {
- ms = 300 / split;
- }
-
- spin = 0.0;
- dtime0(&tm);
-
- g = got_pointer_input;
- miss = 0;
- for (i=0; i<split; i++) {
- usleep(ms * 1000);
- if (show_multiple_cursors) {
- rfbPE(1000);
- } else {
- rfbCFD(1000);
- }
- spin += dtime(&tm);
- if (got_pointer_input > g) {
- int i, max_extra = max_eat / 2;
- for (i=0; i<max_extra; i++) {
- rfbCFD(0);
- if (got_pointer_input > g) {
- g = got_pointer_input;
- } else if (i > 1) {
- break;
- }
- }
- X_LOCK;
-if (0) fprintf(stderr, "check_user_input2-C: XFlush %.4f\n", tm);
- XFlush_wr(dpy);
- X_UNLOCK;
- miss = 0;
- } else {
- miss++;
- }
- g = got_pointer_input;
- if (miss > 2) {
- break;
- }
- if (1000 * spin > ms * split) {
- break;
- }
- }
- }
-}
-
-static void check_user_input3(double dt, double dtr, int tile_diffs) {
-
- int allowed_misses, miss_tweak, i, g, g_in;
- int last_was_miss, consecutive_misses;
- double spin, spin_max, tm, to, dtm;
- int rfb_wait_ms = 2;
- static double dt_cut = 0.075;
- int gcnt, ginput;
- static int first = 1;
-
- if (dtr || tile_diffs) {} /* unused vars warning: */
-
- if (first) {
- char *p = getenv("SPIN");
- if (p) {
- double junk;
- sscanf(p, "%lf,%lf", &dt_cut, &junk);
- }
- first = 0;
- }
-
- if (!got_pointer_input) {
- return;
- }
-
-
- if (dt < dt_cut) {
- dt = dt_cut; /* this is to try to avoid early exit */
- }
- spin_max = 0.5;
-
- spin = 0.0; /* amount of time spinning */
- allowed_misses = 10; /* number of ptr inputs we can miss */
- miss_tweak = 8;
- last_was_miss = 0;
- consecutive_misses = 1;
- gcnt = 0;
- ginput = 0;
-
- dtime0(&tm);
- to = tm; /* last time we did rfbPE() */
-
- g = g_in = got_pointer_input;
-
- while (1) {
- int got_input = 0;
-
- gcnt++;
-
- if (button_mask) {
- drag_in_progress = 1;
- }
-
- rfbCFD(rfb_wait_ms * 1000);
-
- dtm = dtime(&tm);
- spin += dtm;
-
- if (got_pointer_input == g) {
- if (last_was_miss) {
- consecutive_misses++;
- }
- last_was_miss = 1;
- } else {
- ginput++;
- if (ginput % miss_tweak == 0) {
- allowed_misses++;
- }
- consecutive_misses = 1;
- last_was_miss = 0;
- }
-
- if (spin > spin_max) {
- /* get out if spin time over limit */
- break;
-
- } else if (got_pointer_input > g) {
- /* received some input, flush to display. */
- got_input = 1;
- g = got_pointer_input;
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- } else if (--allowed_misses <= 0) {
- /* too many misses */
- break;
- } else if (consecutive_misses >=3) {
- /* too many misses */
- break;
- } else {
- /* these are misses */
- int wms = 0;
- if (gcnt == 1 && button_mask) {
- /*
- * missed our first input, wait
- * for a defer time. (e.g. on
- * slow link) hopefully client
- * will batch them.
- */
- wms = 50;
- } else if (button_mask) {
- wms = 10;
- } else {
- }
- if (wms) {
- usleep(wms * 1000);
- }
- }
- }
-
- if (ginput >= 2) {
- /* try for a couple more quick ones */
- for (i=0; i<2; i++) {
- rfbCFD(rfb_wait_ms * 1000);
- }
- }
-
- drag_in_progress = 0;
-}
-
-int fb_update_sent(int *count) {
- static int last_count = 0;
- int sent = 0, rc = 0;
- rfbClientIteratorPtr i;
- rfbClientPtr cl;
-
- if (nofb) {
- return 0;
- }
-
- i = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(i)) ) {
-#if 0
- sent += cl->framebufferUpdateMessagesSent;
-#else
-#if LIBVNCSERVER_HAS_STATS
- sent += rfbStatGetMessageCountSent(cl, rfbFramebufferUpdate);
-#endif
-#endif
- }
- rfbReleaseClientIterator(i);
- if (sent != last_count) {
- rc = 1;
- }
- if (count != NULL) {
- *count = sent;
- }
- last_count = sent;
- return rc;
-}
-
-static void check_user_input4(double dt, double dtr, int tile_diffs) {
-
- int g, g_in, i, ginput, gcnt, tmp;
- int last_was_miss, consecutive_misses;
- int min_frame_size = 10; /* 10 tiles */
- double spin, tm, to, tc, dtm, rpe_last;
- int rfb_wait_ms = 2;
- static double dt_cut = 0.050;
- static int first = 1;
-
- int Btile = tile_x * tile_y * bpp/8; /* Bytes per tile */
- double Ttile, dt_use;
- double screen_rate = 6000000.; /* 5 MB/sec */
- double vnccpu_rate = 80 * 100000.; /* 20 KB/sec @ 80X compression */
- double net_rate = 50000.;
- static double Tfac_r = 1.0, Tfac_v = 1.0, Tfac_n = 1.0, Tdelay = 0.001;
- static double dt_min = -1.0, dt_max = -1.0;
- double dt_min_fallback = 0.050;
- static int ssec = 0, total_calls = 0;
- static int push_frame = 0, update_count = 0;
-
- if (first) {
- char *p = getenv("SPIN");
- if (p) {
- sscanf(p, "%lf,%lf,%lf,%lf", &dt_cut, &Tfac_r, &Tfac_v, &Tfac_n);
- }
- first = 0;
- ssec = time(NULL);
-
- if (dtr) {} /* unused vars warning: */
- }
-
- total_calls++;
-
- if (dt_min < 0.0 || dt < dt_min) {
- if (dt > 0.0) {
- dt_min = dt;
- }
- }
- if (dt_min < 0.0) {
- /* sensible value for the very 1st call if dt = 0.0 */
- dt_min = dt_min_fallback;
- }
- if (dt_max < 0.0 || dt > dt_max) {
- dt_max = dt;
- }
-
- if (total_calls > 30 && dt_min > 0.0) {
- static int first = 1;
- /*
- * dt_min will soon be the quickest time to do
- * one scan_for_updates with no tiles copied.
- * use this (instead of copy_tiles) to estimate
- * screen read rate.
- */
- screen_rate = (main_bytes_per_line * ntiles_y) / dt_min;
- if (first) {
- rfbLog("measured screen read rate: %.2f Bytes/sec\n",
- screen_rate);
- }
- first = 0;
- }
-
- dtime0(&tm);
-
- if (dt < dt_cut) {
- dt_use = dt_cut;
- } else {
- dt_use = dt;
- }
-
- if (push_frame) {
- int cnt, iter = 0;
- double tp, push_spin = 0.0;
- dtime0(&tp);
- while (push_spin < dt_use * 0.5) {
- fb_update_sent(&cnt);
- if (cnt != update_count) {
- break;
- }
- /* damn, they didn't push our frame! */
- iter++;
- rfbPE(rfb_wait_ms * 1000);
-
- push_spin += dtime(&tp);
- }
- if (iter) {
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- }
- push_frame = 0;
- update_count = 0;
- }
-
- /*
- * when we first enter we require some pointer input
- */
- if (!got_pointer_input) {
- return;
- }
-
- vnccpu_rate = get_raw_rate();
-
- if ((tmp = get_read_rate()) != 0) {
- screen_rate = (double) tmp;
- }
- if ((tmp = get_net_rate()) != 0) {
- net_rate = (double) tmp;
- }
- net_rate = (vnccpu_rate/get_cmp_rate()) * net_rate;
-
- if ((tmp = get_net_latency()) != 0) {
- Tdelay = 0.5 * ((double) tmp)/1000.;
- }
-
- Ttile = Btile * (Tfac_r/screen_rate + Tfac_v/vnccpu_rate + Tfac_n/net_rate);
-
- spin = 0.0; /* amount of time spinning */
- last_was_miss = 0;
- consecutive_misses = 1;
- gcnt = 0;
- ginput = 0;
-
- rpe_last = to = tc = tm; /* last time we did rfbPE() */
- g = g_in = got_pointer_input;
-
- tile_diffs = 0; /* reset our knowlegde of tile_diffs to zero */
-
- while (1) {
- int got_input = 0;
-
- gcnt++;
-
- if (button_mask) {
- /* this varible is used by our pointer handler */
- drag_in_progress = 1;
- }
-
- /* turn libvncserver crank to process events: */
- rfbCFD(rfb_wait_ms * 1000);
-
- dtm = dtime(&tm);
- spin += dtm;
-
- if ( (gcnt == 1 && got_pointer_input > g) || tm-tc > 2*dt_min) {
- tile_diffs = scan_for_updates(1);
- tc = tm;
- }
-
- if (got_pointer_input == g) {
- if (last_was_miss) {
- consecutive_misses++;
- }
- last_was_miss = 1;
- } else {
- ginput++;
- consecutive_misses = 1;
- last_was_miss = 0;
- }
-
- if (tile_diffs > min_frame_size && spin > Ttile * tile_diffs + Tdelay) {
- /* we think we can push the frame */
- push_frame = 1;
- fb_update_sent(&update_count);
- break;
-
- } else if (got_pointer_input > g) {
- /* received some input, flush it to display. */
- got_input = 1;
- g = got_pointer_input;
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
-
- } else if (consecutive_misses >= 2) {
- /* too many misses in a row */
- break;
-
- } else {
- /* these are pointer input misses */
- int wms;
- if (gcnt == 1 && button_mask) {
- /*
- * missed our first input, wait for
- * a defer time. (e.g. on slow link)
- * hopefully client will batch many
- * of them for the next read.
- */
- wms = 50;
-
- } else if (button_mask) {
- wms = 10;
- } else {
- wms = 0;
- }
- if (wms) {
- usleep(wms * 1000);
- }
- }
- }
- if (ginput >= 2) {
- /* try for a couple more quick ones */
- for (i=0; i<2; i++) {
- rfbCFD(rfb_wait_ms * 1000);
- }
- }
- drag_in_progress = 0;
-}
-
-int check_user_input(double dt, double dtr, int tile_diffs, int *cnt) {
-
- if (rawfb_vnc_reflect) {
- if (got_user_input) {
- if (0) vnc_reflect_process_client();
- }
- if (got_user_input && *cnt % ui_skip != 0) {
- /* every n-th drops thru to scan */
- *cnt = *cnt + 1;
- return 1; /* short circuit watch_loop */
- }
- }
-#ifdef MACOSX
- if (! macosx_console) {
- RAWFB_RET(0)
- }
-#else
- RAWFB_RET(0)
-#endif
-
- if (use_xrecord) {
- int rc = check_xrecord();
- /*
- * 0: nothing found, proceed to other user input schemes.
- * 1: events found, want to do a screen update now.
- * 2: events found, want to loop back for some more.
- * 3: events found, want to loop back for some more,
- * and not have rfbPE() called.
- *
- * For 0, we precede below, otherwise return rc-1.
- */
-if (debug_scroll && rc > 1) fprintf(stderr, " CXR: check_user_input ret %d\n", rc - 1);
- if (rc == 0) {
- ; /* proceed below. */
- } else {
- return rc - 1;
- }
- }
-
- if (wireframe) {
- if (check_wireframe()) {
- return 0;
- }
- }
-
- if (pointer_mode == 1) {
- if ((got_user_input || ui_skip < 0) && *cnt % ui_skip != 0) {
- /* every ui_skip-th drops thru to scan */
- *cnt = *cnt + 1;
- X_LOCK;
- XFlush_wr(dpy);
- X_UNLOCK;
- return 1; /* short circuit watch_loop */
- } else {
- return 0;
- }
- }
- if (pointer_mode >= 2 && pointer_mode <= 4) {
- if (got_keyboard_input) {
- /*
- * for these modes, short circuit watch_loop on
- * *keyboard* input.
- */
- if (*cnt % ui_skip != 0) {
- *cnt = *cnt + 1;
- return 1;
- }
- }
- /* otherwise continue below with pointer input method */
- }
-
- if (pointer_mode == 2) {
- check_user_input2(dt);
- } else if (pointer_mode == 3) {
- check_user_input3(dt, dtr, tile_diffs);
- } else if (pointer_mode == 4) {
- check_user_input4(dt, dtr, tile_diffs);
- }
- return 0;
-}
-
-#if defined(NO_NCACHE) || (NO_X11 && !defined(MACOSX))
-int check_ncache(int a, int b) {
- if (!a || !b) {}
- ncache = 0;
- return 0;
-}
-int lookup_win_index(Window win) {
- if (!win) {}
- return -1;
-}
-int find_rect(int idx, int x, int y, int w, int h) {
- if (!idx || !x || !y || !w || !h) {}
- return 0;
-}
-void snap_old(void) {
- return;
-}
-int clipped(int idx) {
- if (!idx) {}
- return 0;
-}
-int bs_restore(int idx, int *nbatch, sraRegionPtr rmask, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) {
- if (!idx || !nbatch || !rmask || !attr || !clip || !nopad || !valid || !verb) {}
- return 0;
-}
-int try_to_fix_su(Window win, int idx, Window above, int *nbatch, char *mode) {
- if (!win || !idx || !above || !nbatch || !mode) {}
- return 0;
-}
-int try_to_fix_resize_su(Window orig_frame, int orig_x, int orig_y, int orig_w, int orig_h,
- int x, int y, int w, int h, int try_batch) {
- if (!orig_frame || !orig_x || !orig_y || !orig_w || !orig_h || !x || !y || !w || !h || !try_batch) {}
- return 0;
-}
-void set_ncache_xrootpmap(void) {
- return;
-}
-#else
-/* maybe ncache.c it if works */
-
-winattr_t* cache_list = NULL;
-int cache_list_num = 0;
-int cache_list_len = 0;
-
-void snapshot_cache_list(int free_only, double allowed_age) {
- static double last_snap = 0.0, last_free = 0.0;
- double now;
- int num, rc, i;
- unsigned int ui;
- Window r, w;
- Window *list;
- int start = 512;
-
- if (! cache_list) {
- cache_list = (winattr_t *) calloc(start*sizeof(winattr_t), 1);
- cache_list_num = 0;
- cache_list_len = start;
- }
-
- dtime0(&now);
- if (free_only) {
- /* we really don't free it, just reset to zero windows */
- cache_list_num = 0;
- last_free = now;
- return;
- }
-
- if (cache_list_num && now < last_snap + allowed_age) {
- return;
- }
-
- cache_list_num = 0;
- last_free = now;
-
-#ifdef MACOSX
- if (! macosx_console) {
- RAWFB_RET_VOID
- }
-#else
- RAWFB_RET_VOID
-#endif
-
-
-#if NO_X11 && !defined(MACOSX)
- num = rc = i = 0; /* compiler warnings */
- ui = 0;
- r = w = None;
- list = NULL;
- return;
-#else
-
- X_LOCK;
- /* no need to trap error since rootwin */
- rc = XQueryTree_wr(dpy, rootwin, &r, &w, &list, &ui);
- X_UNLOCK;
- num = (int) ui;
-
- if (! rc) {
- cache_list_num = 0;
- last_free = now;
- last_snap = 0.0;
- return;
- }
-
- last_snap = now;
- if (num > cache_list_len) {
- int n = 2*num;
- n = num + 3;
- free(cache_list);
- cache_list = (winattr_t *) calloc(n*sizeof(winattr_t), 1);
- cache_list_len = n;
- }
- for (i=0; i<num; i++) {
- cache_list[i].win = list[i];
- cache_list[i].fetched = 0;
- cache_list[i].valid = 0;
- cache_list[i].time = now;
- cache_list[i].selectinput = 0;
- cache_list[i].vis_cnt = 0;
- cache_list[i].map_cnt = 0;
- cache_list[i].unmap_cnt = 0;
- cache_list[i].create_cnt = 0;
- cache_list[i].vis_state = -1;
- cache_list[i].above = None;
- }
- if (num == 0) {
- cache_list[0].win = None;
- cache_list[0].fetched = 0;
- cache_list[0].valid = 0;
- cache_list[0].time = now;
- cache_list[0].selectinput = 0;
- cache_list[0].vis_cnt = 0;
- cache_list[0].map_cnt = 0;
- cache_list[0].unmap_cnt = 0;
- cache_list[0].create_cnt = 0;
- cache_list[0].vis_state = -1;
- cache_list[0].above = None;
- num++;
- }
-
- cache_list_num = num;
-
- if (num) {
- X_LOCK;
- XFree_wr(list);
- X_UNLOCK;
- }
-#endif /* NO_X11 */
-}
-
-void quick_snap(Window *wins, int *size) {
- int num, rc, i;
- unsigned int ui;
- Window r, w;
- Window *list;
-
-#ifdef MACOSX
- if (1 || ! macosx_console) {
- RAWFB_RET_VOID
- }
-#else
- RAWFB_RET_VOID
-#endif
-
-
-#if NO_X11 && !defined(MACOSX)
- num = rc = i = 0; /* compiler warnings */
- ui = 0;
- r = w = None;
- list = NULL;
- return;
-#else
-
- X_LOCK;
- /* no need to trap error since rootwin */
- rc = XQueryTree_wr(dpy, rootwin, &r, &w, &list, &ui);
- X_UNLOCK;
- num = (int) ui;
-
- if (! rc || num == 0) {
- *size = 0;
- return;
- } else {
- int m = *size;
- if (num < m) {
- m = num;
- }
- for (i=0; i < m; i++) {
- wins[i] = list[i];
- }
- if (num) {
- X_LOCK;
- XFree_wr(list);
- X_UNLOCK;
- }
- *size = m;
- }
-#endif /* NO_X11 */
-}
-
-int get_bs_n(int y) {
- int n;
- for (n = 1; n < ncache; n += 2) {
- if (n*dpy_y <= y && y < (n+1)*dpy_y) {
- return n;
- }
- }
- return -1;
-}
-
-#define NRECENT 32
-Window recent[NRECENT];
-int recidx[NRECENT];
-int rlast, rfree;
-
-int lookup_win_index(Window win) {
- int k, idx = -1;
- int foundfree = 0;
- static int s1 = 0, s2 = 0, s3 = 0;
-
- if (win == rootwin || win == None) {
- return -1;
- }
- for (k = 0; k < NRECENT; k++) {
- if (recent[k] == win) {
- int k2 = recidx[k];
- if (cache_list[k2].win == win) {
- idx = k2;
-if (0) fprintf(stderr, "recentA(shortcut): %d 0x%lx\n", idx, win);
- s1++;
- break;
- }
- }
- }
- if (idx < 0) {
- for(k=0; k<cache_list_num; k++) {
- if (!foundfree && cache_list[k].win == None) {
- rfree = k;
- foundfree = 1;
- }
- if (cache_list[k].win == win) {
- idx = k;
-if (0) fprintf(stderr, "recentB(normal): %d 0x%lx\n", idx, win);
- s2++;
- break;
- }
- }
- if (idx >= 0) {
- recent[rlast] = win;
- recidx[rlast++] = idx;
- rlast = rlast % NRECENT;
- }
- }
- if (idx < 0) {
-if (ncdb) fprintf(stderr, "recentC(fail): %d 0x%lx\n", idx, win);
- s3++;
- }
- if (s1 + s2 + s3 >= 1000) {
-if (ncdb) fprintf(stderr, "lookup_win_index recent hit stats: %d/%d/%d\n", s1, s2, s3);
- s1 = s2 = s3 = 0;
- }
- return idx;
-}
-
-int lookup_free_index(void) {
- int k;
-
- if (rfree >= 0) {
- if (cache_list[rfree].win == None) {
-if (ncdb) fprintf(stderr, "lookup_freeA: %d\n", rfree);
- return rfree;
- }
- }
- rfree = -1;
- for(k=0; k<cache_list_num; k++) {
- if (cache_list[k].win == None) {
- rfree = k;
- break;
- }
- }
- if (rfree < 0) {
- if (ncdb) fprintf(stderr, "*** LOOKUP_FREE_INDEX: incrementing cache_list_num %d/%d\n", cache_list_num, cache_list_len);
-
- rfree = cache_list_num++;
- if (rfree >= cache_list_len) {
- int i, n = 2*cache_list_len;
- winattr_t *cache_new;
-
- if (ncdb) fprintf(stderr, "lookup_free_index: growing cache_list_len: %d -> %d\n", cache_list_len, n);
-
- cache_new = (winattr_t *) calloc(n*sizeof(winattr_t), 1);
- for (i=0; i<cache_list_num-1; i++) {
- cache_new[i] = cache_list[i];
- }
- cache_list_len = n;
- free(cache_list);
- cache_list = cache_new;
- }
- cache_list[rfree].win = None;
- cache_list[rfree].fetched = 0;
- cache_list[rfree].valid = 0;
- cache_list[rfree].time = 0.0;
- cache_list[rfree].selectinput = 0;
- cache_list[rfree].vis_cnt = 0;
- cache_list[rfree].map_cnt = 0;
- cache_list[rfree].unmap_cnt = 0;
- cache_list[rfree].create_cnt = 0;
- cache_list[rfree].vis_state = -1;
- cache_list[rfree].above = None;
- }
-
-if (ncdb) fprintf(stderr, "lookup_freeB: %d\n", rfree);
- return rfree;
-}
-
-#define STACKMAX 4096
-Window old_stack[STACKMAX];
-Window new_stack[STACKMAX];
-Window old_stack_map[STACKMAX];
-Window new_stack_map[STACKMAX];
-int old_stack_index[STACKMAX];
-int old_stack_mapped[STACKMAX];
-int old_stack_n = 0;
-int new_stack_n = 0;
-int old_stack_map_n = 0;
-int new_stack_map_n = 0;
-
-void snap_old(void) {
- int i;
- old_stack_n = STACKMAX;
- quick_snap(old_stack, &old_stack_n);
-if (0) fprintf(stderr, "snap_old: %d %.4f\n", old_stack_n, dnowx());
-#if 0
- for (i= old_stack_n - 1; i >= 0; i--) {
- int idx = lookup_win_index(old_stack[i]);
- if (idx >= 0) {
- if (cache_list[idx].map_state == IsViewable) {
- if (ncdb) fprintf(stderr, " %03d 0x%x\n", i, old_stack[i]);
- }
- }
- }
-#endif
- for (i=0; i < old_stack_n; i++) {
- old_stack_mapped[i] = -1;
- }
-}
-
-void snap_old_index(void) {
- int i, idx;
- for (i=0; i < old_stack_n; i++) {
- idx = lookup_win_index(old_stack[i]);
- old_stack_index[i] = idx;
- if (idx >= 0) {
- if (cache_list[idx].map_state == IsViewable) {
- old_stack_mapped[i] = 1;
- } else {
- old_stack_mapped[i] = 0;
- }
- }
- }
-}
-
-int lookup_old_stack_index(int ic) {
- int idx = old_stack_index[ic];
-
- if (idx < 0) {
- return -1;
- }
- if (cache_list[idx].win != old_stack[ic]) {
- snap_old_index();
- }
- idx = old_stack_index[ic];
- if (idx < 0 || cache_list[idx].win != old_stack[ic]) {
- return -1;
- }
- if (cache_list[idx].map_state == IsViewable) {
- old_stack_mapped[ic] = 1;
- } else {
- old_stack_mapped[ic] = 0;
- }
- return idx;
-}
-
-#define STORE(k, w, attr) \
- if (0) fprintf(stderr, "STORE(%d) = 0x%lx\n", k, w); \
- cache_list[k].win = w; \
- cache_list[k].fetched = 1; \
- cache_list[k].valid = 1; \
- cache_list[k].x = attr.x; \
- cache_list[k].y = attr.y; \
- cache_list[k].width = attr.width; \
- cache_list[k].height = attr.height; \
- cache_list[k].border_width = attr.border_width; \
- cache_list[k].map_state = attr.map_state; \
- cache_list[k].time = dnow();
-
-#if 0
- cache_list[k].width = attr.width + 2*attr.border_width; \
- cache_list[k].height = attr.height + 2*attr.border_width; \
-
-#endif
-
-#define CLEAR(k) \
- if (0) fprintf(stderr, "CLEAR(%d)\n", k); \
- cache_list[k].bs_x = -1; \
- cache_list[k].bs_y = -1; \
- cache_list[k].bs_w = -1; \
- cache_list[k].bs_h = -1; \
- cache_list[k].su_x = -1; \
- cache_list[k].su_y = -1; \
- cache_list[k].su_w = -1; \
- cache_list[k].su_h = -1; \
- cache_list[k].time = 0.0; \
- cache_list[k].bs_time = 0.0; \
- cache_list[k].su_time = 0.0; \
- cache_list[k].vis_obs_time = 0.0; \
- cache_list[k].vis_unobs_time = 0.0;
-
-#define DELETE(k) \
- if (0) fprintf(stderr, "DELETE(%d) = 0x%lx\n", k, cache_list[k].win); \
- cache_list[k].win = None; \
- cache_list[k].fetched = 0; \
- cache_list[k].valid = 0; \
- cache_list[k].selectinput = 0; \
- cache_list[k].vis_cnt = 0; \
- cache_list[k].map_cnt = 0; \
- cache_list[k].unmap_cnt = 0; \
- cache_list[k].create_cnt = 0; \
- cache_list[k].vis_state = -1; \
- cache_list[k].above = None; \
- free_rect(k); /* does CLEAR(k) */
-
-static char unk[32];
-
-char *Etype(int type) {
- if (type == KeyPress) return "KeyPress";
- if (type == KeyRelease) return "KeyRelease";
- if (type == ButtonPress) return "ButtonPress";
- if (type == ButtonRelease) return "ButtonRelease";
- if (type == MotionNotify) return "MotionNotify";
- if (type == EnterNotify) return "EnterNotify";
- if (type == LeaveNotify) return "LeaveNotify";
- if (type == FocusIn) return "FocusIn";
- if (type == FocusOut) return "FocusOut";
- if (type == KeymapNotify) return "KeymapNotify";
- if (type == Expose) return "Expose";
- if (type == GraphicsExpose) return "GraphicsExpose";
- if (type == NoExpose) return "NoExpose";
- if (type == VisibilityNotify) return "VisibilityNotify";
- if (type == CreateNotify) return "CreateNotify";
- if (type == DestroyNotify) return "DestroyNotify";
- if (type == UnmapNotify) return "UnmapNotify";
- if (type == MapNotify) return "MapNotify";
- if (type == MapRequest) return "MapRequest";
- if (type == ReparentNotify) return "ReparentNotify";
- if (type == ConfigureNotify) return "ConfigureNotify";
- if (type == ConfigureRequest) return "ConfigureRequest";
- if (type == GravityNotify) return "GravityNotify";
- if (type == ResizeRequest) return "ResizeRequest";
- if (type == CirculateNotify) return "CirculateNotify";
- if (type == CirculateRequest) return "CirculateRequest";
- if (type == PropertyNotify) return "PropertyNotify";
- if (type == SelectionClear) return "SelectionClear";
- if (type == SelectionRequest) return "SelectionRequest";
- if (type == SelectionNotify) return "SelectionNotify";
- if (type == ColormapNotify) return "ColormapNotify";
- if (type == ClientMessage) return "ClientMessage";
- if (type == MappingNotify) return "MappingNotify";
- if (type == LASTEvent) return "LASTEvent";
- sprintf(unk, "Unknown %d", type);
- return unk;
-}
-char *VState(int state) {
- if (state == VisibilityFullyObscured) return "VisibilityFullyObscured";
- if (state == VisibilityPartiallyObscured) return "VisibilityPartiallyObscured";
- if (state == VisibilityUnobscured) return "VisibilityUnobscured";
- sprintf(unk, "Unknown %d", state);
- return unk;
-}
-char *MState(int state) {
- if (state == IsViewable) return "IsViewable";
- if (state == IsUnmapped) return "IsUnmapped";
- sprintf(unk, "Unknown %d", state);
- return unk;
-}
-sraRegionPtr rect_reg[64];
-sraRegionPtr zero_rects = NULL;
-
-int free_rect(int idx) {
- int n, ok = 0;
- sraRegionPtr r1, r2;
- int x, y, w, h;
-
- if (idx < 0 || idx >= cache_list_num) {
-if (0) fprintf(stderr, "free_rect: bad index: %d\n", idx);
- clean_up_exit(1);
- }
-
- x = cache_list[idx].bs_x;
- y = cache_list[idx].bs_y;
- w = cache_list[idx].bs_w;
- h = cache_list[idx].bs_h;
-
- if (x < 0) {
- CLEAR(idx);
-if (dnow() > last_client + 5 && ncdb) fprintf(stderr, "free_rect: already bs_x invalidated: %d bs_x: %d\n", idx, x);
- return 1;
- }
-
- r2 = sraRgnCreateRect(x, y, x+w, y+h);
-
- n = get_bs_n(y);
- if (n >= 0) {
- r1 = rect_reg[n];
- sraRgnOr(r1, r2);
- ok = 1;
- }
-
- if (zero_rects) {
- sraRgnOr(zero_rects, r2);
- x = cache_list[idx].su_x;
- y = cache_list[idx].su_y;
- w = cache_list[idx].su_w;
- h = cache_list[idx].su_h;
- if (x >= 0) {
- sraRgnDestroy(r2);
- r2 = sraRgnCreateRect(x, y, x+w, y+h);
- sraRgnOr(zero_rects, r2);
- }
- }
- sraRgnDestroy(r2);
-
- CLEAR(idx);
-if (! ok && ncdb) fprintf(stderr, "**** free_rect: not-found %d\n", idx);
- return ok;
-}
-
-int fr_BIG1 = 0;
-int fr_BIG2 = 0;
-int fr_REGION = 0;
-int fr_GRID = 0;
-int fr_EXPIRE = 0;
-int fr_FORCE = 0;
-int fr_FAIL = 0;
-int fr_BIG1t = 0;
-int fr_BIG2t = 0;
-int fr_REGIONt = 0;
-int fr_GRIDt = 0;
-int fr_EXPIREt = 0;
-int fr_FORCEt = 0;
-int fr_FAILt = 0;
-
-void expire_rects1(int idx, int w, int h, int *x_hit, int *y_hit, int big1, int big2, int cram) {
- sraRegionPtr r1, r2, r3;
- int x = -1, y = -1, n;
-
- if (*x_hit < 0) {
- int i, k, old[10], N = 4;
- double dold[10], fa, d, d1, d2, d3;
- int a0 = w * h, a1;
-
- for (k=1; k<=N; k++) {
- old[k] = -1;
- dold[k] = -1.0;
- }
- for (i=0; i<cache_list_num; i++) {
- int wb = cache_list[i].bs_w;
- int hb = cache_list[i].bs_h;
- if (cache_list[i].bs_x < 0) {
- continue;
- }
- if (w > wb || h > hb) {
- continue;
- }
- if (wb == 0 || hb == 0) {
- continue;
- }
- if (a0 == 0) {
- continue;
- }
- if (i == idx) {
- continue;
- }
- a1 = wb * hb;
- fa = ((double) a1) / a0;
- k = (int) fa;
-
- if (k < 1) k = 1;
- if (k > N) continue;
-
- d1 = cache_list[i].time;
- d2 = cache_list[i].bs_time;
- d3 = cache_list[i].su_time;
-
- d = d1;
- if (d2 > d) d = d2;
- if (d3 > d) d = d3;
-
- if (dold[k] == -1.0 || d < dold[k]) {
- old[k] = i;
- dold[k] = d;
- }
- }
-
- for (k=1; k<=N; k++) {
- if (old[k] >= 0) {
- int ik = old[k];
- int k_x = cache_list[ik].bs_x;
- int k_y = cache_list[ik].bs_y;
- int k_w = cache_list[ik].bs_w;
- int k_h = cache_list[ik].bs_h;
-
-if (ncdb) fprintf(stderr, ">>**--**>> found rect via EXPIRE: %d 0x%lx -- %dx%d+%d+%d %d %d -- %dx%d+%d+%d A: %d/%d\n",
- ik, cache_list[ik].win, w, h, x, y, *x_hit, *y_hit, k_w, k_h, k_x, k_y, k_w * k_h, w * h);
-
- free_rect(ik);
- fr_EXPIRE++;
- fr_EXPIREt++;
- *x_hit = k_x;
- *y_hit = k_y;
- n = get_bs_n(*y_hit);
- if (n >= 0) {
- r1 = rect_reg[n];
- r2 = sraRgnCreateRect(*x_hit, *y_hit, *x_hit + w, *y_hit + h);
- sraRgnSubtract(r1, r2);
- sraRgnDestroy(r2);
- } else {
- fprintf(stderr, "failure to find y n in find_rect\n");
- clean_up_exit(1);
- }
- break;
- }
- }
- }
-
- /* next, force ourselves into some corner, expiring many */
- if (*x_hit < 0) {
- int corner_x = (int) (2 * rfac());
- int corner_y = (int) (2 * rfac());
- int x0 = 0, y0 = 0, i, nrand, nr = ncache/2;
- if (nr == 1) {
- nrand = 1;
- } else {
- if (! big1) {
- nrand = 1;
- } else {
- if (big2 && nr > 2) {
- nrand = 1 + (int) ((nr - 2) * rfac());
- nrand += 2;
- } else {
- nrand = 1 + (int) ((nr - 1) * rfac());
- nrand += 1;
- }
- }
- }
- if (nrand < 0 || nrand > nr) {
- nrand = nr;
- }
- if (cram && big1) {
- corner_x = 1;
- }
-
- y0 += dpy_y;
- if (nrand > 1) {
- y0 += 2 * (nrand - 1) * dpy_y;
- }
- if (corner_y) {
- y0 += dpy_y - h;
- }
- if (corner_x) {
- x0 += dpy_x - w;
- }
- r1 = sraRgnCreateRect(x0, y0, x0+w, y0+h);
-
- for (i=0; i<cache_list_num; i++) {
- int xb = cache_list[i].bs_x;
- int yb = cache_list[i].bs_y;
- int wb = cache_list[i].bs_w;
- int hb = cache_list[i].bs_h;
- if (xb < 0) {
- continue;
- }
- if (nabs(yb - y0) > dpy_y) {
- continue;
- }
- r2 = sraRgnCreateRect(xb, yb, xb+wb, yb+hb);
- if (sraRgnAnd(r2, r1)) {
- free_rect(i);
- }
- sraRgnDestroy(r2);
- }
- *x_hit = x0;
- *y_hit = y0;
- r3 = rect_reg[2*nrand-1];
- sraRgnSubtract(r3, r1);
- sraRgnDestroy(r1);
-
-if (ncdb) fprintf(stderr, ">>**--**>> found rect via FORCE: %dx%d+%d+%d -- %d %d\n", w, h, x, y, *x_hit, *y_hit);
-
- fr_FORCE++;
- fr_FORCEt++;
- }
-}
-
-void expire_rects2(int idx, int w, int h, int *x_hit, int *y_hit, int big1, int big2, int cram) {
- sraRegionPtr r1, r2, r3;
- int x = -1, y = -1, n, i, j, k;
- int nwgt_max = 128, nwgt = 0;
- int type[128];
- int val[4][128];
- double wgt[128], norm;
- int Expire = 1, Force = 2;
- int do_expire = 1;
- int do_force = 1;
- double now = dnow(), r;
- double newest = -1.0, oldest = -1.0, basetime;
- double map_factor = 0.25;
-
- for (i=0; i<cache_list_num; i++) {
- double d, d1, d2;
-
- d1 = cache_list[i].bs_time;
- d2 = cache_list[i].su_time;
-
- d = d1;
- if (d2 > d) d = d2;
-
- if (d == 0.0) {
- continue;
- }
-
- if (oldest == -1.0 || d < oldest) {
- oldest = d;
- }
- if (newest == -1.0 || d > newest) {
- newest = d;
- }
- }
- if (newest == -1.0) {
- newest = now;
- }
- if (oldest == -1.0) {
- oldest = newest - 1800;
- }
-
- basetime = newest + 0.1 * (newest - oldest);
-
- if (do_expire) {
- int old[10], N = 4;
- double dold[10], fa, d, d1, d2;
- int a0 = w * h, a1;
-
- for (k=1; k<=N; k++) {
- old[k] = -1;
- dold[k] = -1.0;
- }
- for (i=0; i<cache_list_num; i++) {
- int wb = cache_list[i].bs_w;
- int hb = cache_list[i].bs_h;
- if (cache_list[i].bs_x < 0) {
- continue;
- }
- if (w > wb || h > hb) {
- continue;
- }
- if (wb == 0 || hb == 0) {
- continue;
- }
- if (a0 == 0) {
- continue;
- }
- if (i == idx) {
- continue;
- }
-
- a1 = wb * hb;
- fa = ((double) a1) / a0;
- k = (int) fa;
-
- if (k < 1) k = 1;
- if (k > N) continue;
-
- d1 = cache_list[i].bs_time;
- d2 = cache_list[i].su_time;
-
- d = d1;
- if (d2 > d) d = d2;
- if (d == 0.0) d = oldest;
-
- if (dold[k] == -1.0 || d < dold[k]) {
- old[k] = i;
- dold[k] = d;
- }
- }
-
- for (k=1; k<=N; k++) {
- if (old[k] >= 0) {
- int ik = old[k];
- int k_w = cache_list[ik].bs_w;
- int k_h = cache_list[ik].bs_h;
-
- wgt[nwgt] = (basetime - dold[k]) / (k_w * k_h);
- if (cache_list[ik].map_state == IsViewable) {
- wgt[nwgt] *= map_factor;
- }
- type[nwgt] = Expire;
- val[0][nwgt] = ik;
-if (ncdb) fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 10000 * wgt[nwgt], basetime - dold[k], k_w * k_h, w*h);
- nwgt++;
- if (nwgt >= nwgt_max) {
- break;
- }
- }
- }
- }
-
- /* next, force ourselves into some corner, expiring many rect */
- if (do_force) {
- int corner_x, corner_y;
- int x0, y0;
-
- for (n = 1; n < ncache; n += 2) {
- if (big1 && ncache > 2 && n == 1) {
- continue;
- }
- if (big2 && ncache > 4 && n <= 3) {
- continue;
- }
- for (corner_x = 0; corner_x < 2; corner_x++) {
- if (cram && big1 && corner_x == 0) {
- continue;
- }
- for (corner_y = 0; corner_y < 2; corner_y++) {
- double age = 0.0, area = 0.0, amap = 0.0, a;
- double d, d1, d2, score;
- int nc = 0;
-
- x0 = 0;
- y0 = 0;
- y0 += n * dpy_y;
-
- if (corner_y) {
- y0 += dpy_y - h;
- }
- if (corner_x) {
- x0 += dpy_x - w;
- }
- r1 = sraRgnCreateRect(x0, y0, x0+w, y0+h);
-
- for (i=0; i<cache_list_num; i++) {
- int xb = cache_list[i].bs_x;
- int yb = cache_list[i].bs_y;
- int wb = cache_list[i].bs_w;
- int hb = cache_list[i].bs_h;
-
- if (xb < 0) {
- continue;
- }
- if (nabs(yb - y0) > dpy_y) {
- continue;
- }
-
- r2 = sraRgnCreateRect(xb, yb, xb+wb, yb+hb);
- if (! sraRgnAnd(r2, r1)) {
- sraRgnDestroy(r2);
- continue;
- }
- sraRgnDestroy(r2);
-
- a = wb * hb;
-
- d1 = cache_list[i].bs_time;
- d2 = cache_list[i].su_time;
-
- d = d1;
- if (d2 > d) d = d2;
- if (d == 0.0) d = oldest;
-
- if (cache_list[i].map_state == IsViewable) {
- amap += a;
- }
- area += a;
- age += (basetime - d) * a;
- nc++;
- }
- if (nc == 0) {
- score = 999999.9;
- } else {
- double fac;
- age = age / area;
- score = age / area;
- fac = 1.0 * (1.0 - amap/area) + map_factor * (amap/area);
- score *= fac;
- }
-
- wgt[nwgt] = score;
- type[nwgt] = Force;
- val[0][nwgt] = n;
- val[1][nwgt] = x0;
- val[2][nwgt] = y0;
-if (ncdb) fprintf(stderr, "Force [%02d] %9.5f age=%9.4f area=%8d amap=%8d need=%8d\n", nwgt, 10000 * wgt[nwgt], age, (int) area, (int) amap, w*h);
- nwgt++;
- if (nwgt >= nwgt_max) break;
- sraRgnDestroy(r1);
- }
- if (nwgt >= nwgt_max) break;
- }
- if (nwgt >= nwgt_max) break;
- }
- }
-
- if (nwgt == 0) {
-if (ncdb) fprintf(stderr, "nwgt=0\n");
- *x_hit = -1;
- return;
- }
-
- norm = 0.0;
- for (i=0; i < nwgt; i++) {
- norm += wgt[i];
- }
- for (i=0; i < nwgt; i++) {
- wgt[i] /= norm;
- }
-
- r = rfac();
-
- norm = 0.0;
- for (j=0; j < nwgt; j++) {
- norm += wgt[j];
-if (ncdb) fprintf(stderr, "j=%2d acc=%.6f r=%.6f\n", j, norm, r);
- if (r < norm) {
- break;
- }
- }
- if (j >= nwgt) {
- j = nwgt - 1;
- }
-
- if (type[j] == Expire) {
- int ik = val[0][j];
- int k_x = cache_list[ik].bs_x;
- int k_y = cache_list[ik].bs_y;
- int k_w = cache_list[ik].bs_w;
- int k_h = cache_list[ik].bs_h;
-
-if (ncdb) fprintf(stderr, ">>**--**>> found rect [%d] via RAN EXPIRE: %d 0x%lx -- %dx%d+%d+%d %d %d -- %dx%d+%d+%d A: %d/%d\n",
- get_bs_n(*y_hit), ik, cache_list[ik].win, w, h, x, y, *x_hit, *y_hit, k_w, k_h, k_x, k_y, k_w * k_h, w * h);
-
- free_rect(ik);
- fr_EXPIRE++;
- fr_EXPIREt++;
- *x_hit = k_x;
- *y_hit = k_y;
- n = get_bs_n(*y_hit);
- if (n >= 0) {
- r1 = rect_reg[n];
- r2 = sraRgnCreateRect(*x_hit, *y_hit, *x_hit + w, *y_hit + h);
- sraRgnSubtract(r1, r2);
- sraRgnDestroy(r2);
- } else {
- fprintf(stderr, "failure to find y n in find_rect\n");
- clean_up_exit(1);
- }
-
- } else if (type[j] == Force) {
-
- int x0 = val[1][j];
- int y0 = val[2][j];
- n = val[0][j];
-
- r1 = sraRgnCreateRect(x0, y0, x0+w, y0+h);
-
- for (i=0; i<cache_list_num; i++) {
- int xb = cache_list[i].bs_x;
- int yb = cache_list[i].bs_y;
- int wb = cache_list[i].bs_w;
- int hb = cache_list[i].bs_h;
- if (xb < 0) {
- continue;
- }
- if (nabs(yb - y0) > dpy_y) {
- continue;
- }
- r2 = sraRgnCreateRect(xb, yb, xb+wb, yb+hb);
- if (sraRgnAnd(r2, r1)) {
- free_rect(i);
- }
- sraRgnDestroy(r2);
- }
- *x_hit = x0;
- *y_hit = y0;
- r3 = rect_reg[2*n-1];
- sraRgnSubtract(r3, r1);
- sraRgnDestroy(r1);
-
-if (ncdb) fprintf(stderr, ">>**--**>> found rect [%d] via RAN FORCE: %dx%d+%d+%d -- %d %d\n", n, w, h, x, y, *x_hit, *y_hit);
-
- fr_FORCE++;
- fr_FORCEt++;
- }
-}
-
-void expire_rects(int idx, int w, int h, int *x_hit, int *y_hit, int big1, int big2, int cram) {
- int method = 2;
- if (method == 1) {
- expire_rects1(idx, w, h, x_hit, y_hit, big1, big2, cram);
- } else if (method == 2) {
- expire_rects2(idx, w, h, x_hit, y_hit, big1, big2, cram);
- }
-}
-
-int find_rect(int idx, int x, int y, int w, int h) {
- sraRegionPtr r1, r2;
- sraRectangleIterator *iter;
- sraRect rt;
- int n, x_hit = -1, y_hit = -1;
- int big1 = 0, big2 = 0, cram = 0;
- double fac1 = 0.1, fac2 = 0.25;
- double last_clean = 0.0;
- double now = dnow();
- static int nobigs = -1;
-
- if (rect_reg[1] == NULL) {
- for (n = 1; n <= ncache; n++) {
- rect_reg[n] = sraRgnCreateRect(0, n * dpy_y, dpy_x, (n+1) * dpy_y);
- }
- } else if (now > last_clean + 60) {
- last_clean = now;
- for (n = 1; n < ncache; n += 2) {
- int i, n2 = n+1;
-
- /* n */
- sraRgnDestroy(rect_reg[n]);
- r1 = sraRgnCreateRect(0, n * dpy_y, dpy_x, (n+1) * dpy_y);
- for (i=0; i<cache_list_num; i++) {
- int bs_x = cache_list[i].bs_x;
- int bs_y = cache_list[i].bs_y;
- int bs_w = cache_list[i].bs_w;
- int bs_h = cache_list[i].bs_h;
- if (bs_x < 0) {
- continue;
- }
- if (get_bs_n(bs_y) != n) {
- continue;
- }
- r2 = sraRgnCreateRect(bs_x, bs_y, bs_x+bs_w, bs_y+bs_h);
- sraRgnSubtract(r1, r2);
- }
- rect_reg[n] = r1;
-
- /* n+1 */
- sraRgnDestroy(rect_reg[n2]);
- r1 = sraRgnCreateRect(0, n2 * dpy_y, dpy_x, (n2+1) * dpy_y);
- for (i=0; i<cache_list_num; i++) {
- int bs_x = cache_list[i].bs_x;
- int su_x = cache_list[i].su_x;
- int su_y = cache_list[i].su_y;
- int su_w = cache_list[i].su_w;
- int su_h = cache_list[i].su_h;
- if (bs_x < 0) {
- continue;
- }
- if (get_bs_n(su_y) != n2) {
- continue;
- }
- r2 = sraRgnCreateRect(su_x, su_y, su_x+su_w, su_y+su_h);
- sraRgnSubtract(r1, r2);
- }
- rect_reg[n2] = r1;
- }
- }
-
- if (idx < 0 || idx >= cache_list_num) {
-if (ncdb) fprintf(stderr, "free_rect: bad index: %d\n", idx);
- clean_up_exit(1);
- }
-
- cache_list[idx].bs_x = -1;
- cache_list[idx].su_x = -1;
- cache_list[idx].bs_time = 0.0;
- cache_list[idx].su_time = 0.0;
-
- if (ncache_pad) {
- x -= ncache_pad;
- y -= ncache_pad;
- w += 2 * ncache_pad;
- h += 2 * ncache_pad;
- }
-
- if (ncache <= 2) {
- cram = 1;
- fac2 = 0.45;
- } else if (ncache <= 4) {
- fac1 = 0.18;
- fac2 = 0.35;
- }
- if (macosx_console && !macosx_ncache_macmenu) {
- if (cram) {
- fac1 *= 1.5;
- fac2 *= 1.5;
- } else {
- fac1 *= 2.5;
- fac2 *= 2.5;
- }
- }
- if (w * h > fac1 * (dpy_x * dpy_y)) {
- big1 = 1;
- }
- if (w * h > fac2 * (dpy_x * dpy_y)) {
- big2 = 1;
- }
-
- if (nobigs < 0) {
- if (getenv("NOBIGS")) {
- nobigs = 1;
- } else {
- nobigs = 0;
- }
- }
- if (nobigs) {
- big1 = big2 = 0;
- }
-
- if (w > dpy_x || h > dpy_y) {
-if (ncdb) fprintf(stderr, ">>**--**>> BIG1 rect: %dx%d+%d+%d -- %d %d\n", w, h, x, y, x_hit, y_hit);
- fr_BIG1++;
- fr_BIG1t++;
- return 0;
- }
- if (w == dpy_x && h == dpy_y) {
-if (ncdb) fprintf(stderr, ">>**--**>> BIG1 rect: %dx%d+%d+%d -- %d %d (FULL DISPLAY)\n", w, h, x, y, x_hit, y_hit);
- fr_BIG1++;
- fr_BIG1t++;
- return 0;
- }
- if (cram && big2) {
-if (ncdb) fprintf(stderr, ">>**--**>> BIG2 rect: %dx%d+%d+%d -- %d %d\n", w, h, x, y, x_hit, y_hit);
- fr_BIG2++;
- fr_BIG2t++;
- return 0;
- }
-
- /* first try individual rects of unused region */
- for (n = 1; n < ncache; n += 2) {
- r1 = rect_reg[n];
- r2 = NULL;
- if (big1 && n == 1 && ncache > 2) {
- continue;
- }
- if (big2 && n <= 3 && ncache > 4) {
- continue;
- }
- iter = sraRgnGetIterator(r1);
- while (sraRgnIteratorNext(iter, &rt)) {
- int rw = rt.x2 - rt.x1;
- int rh = rt.y2 - rt.y1;
- if (cram && big1 && rt.x1 < dpy_x/4) {
- continue;
- }
- if (rw >= w && rh >= h) {
- x_hit = rt.x1;
- y_hit = rt.y1;
- if (cram && big1) {
- x_hit = rt.x2 - w;
- }
- r2 = sraRgnCreateRect(x_hit, y_hit, x_hit + w, y_hit + h);
- break;
- }
- }
- sraRgnReleaseIterator(iter);
- if (r2 != NULL) {
-if (ncdb) fprintf(stderr, ">>**--**>> found rect via REGION: %dx%d+%d+%d -- %d %d\n", w, h, x, y, x_hit, y_hit);
- fr_REGION++;
- fr_REGIONt++;
- sraRgnSubtract(r1, r2);
- sraRgnDestroy(r2);
- break;
- }
- }
-
-
- /* next try moving corner to grid points */
- if (x_hit < 0) {
- for (n = 1; n < ncache; n += 2) {
- int rx, ry, Nx = 48, Ny = 24, ny = n * dpy_y;
-
- if (big1 && n == 1 && ncache > 2) {
- continue;
- }
- if (big2 && n == 3 && ncache > 4) {
- continue;
- }
-
- r1 = sraRgnCreateRect(0, n * dpy_y, dpy_x, (n+1) * dpy_y);
- sraRgnSubtract(r1, rect_reg[n]);
- r2 = NULL;
-
- rx = 0;
- while (rx + w <= dpy_x) {
- ry = 0;
- if (cram && big1 && rx < dpy_x/4) {
- rx += dpy_x/Nx;
- continue;
- }
- while (ry + h <= dpy_y) {
- r2 = sraRgnCreateRect(rx, ry+ny, rx + w, ry+ny + h);
- if (sraRgnAnd(r2, r1)) {
- sraRgnDestroy(r2);
- r2 = NULL;
- } else {
- sraRgnDestroy(r2);
- r2 = sraRgnCreateRect(rx, ry+ny, rx + w, ry+ny + h);
- x_hit = rx;
- y_hit = ry+ny;
- }
- ry += dpy_y/Ny;
- if (r2) break;
- }
- rx += dpy_x/Nx;
- if (r2) break;
- }
- sraRgnDestroy(r1);
- if (r2 != NULL) {
- sraRgnSubtract(rect_reg[n], r2);
- sraRgnDestroy(r2);
-if (ncdb) fprintf(stderr, ">>**--**>> found rect via GRID: %dx%d+%d+%d -- %d %d\n", w, h, x, y, x_hit, y_hit);
- fr_GRID++;
- fr_GRIDt++;
- break;
- }
- }
- }
-
- /* next, try expiring the oldest/smallest used bs/su rectangle we fit in */
-
- if (x_hit < 0) {
- expire_rects(idx, w, h, &x_hit, &y_hit, big1, big2, cram);
- }
-
- cache_list[idx].bs_x = x_hit;
- cache_list[idx].bs_y = y_hit;
- cache_list[idx].bs_w = w;
- cache_list[idx].bs_h = h;
-
- cache_list[idx].su_x = x_hit;
- cache_list[idx].su_y = y_hit + dpy_y;
- cache_list[idx].su_w = w;
- cache_list[idx].su_h = h;
-
- if (x_hit < 0) {
- /* bad news, can it still happen? */
- if (ncdb) fprintf(stderr, ">>**--**>> *FAIL rect: %dx%d+%d+%d -- %d %d\n", w, h, x, y, x_hit, y_hit);
- fr_FAIL++;
- fr_FAILt++;
- return 0;
- } else {
- if (0) fprintf(stderr, ">>**--**>> found rect: %dx%d+%d+%d -- %d %d\n", w, h, x, y, x_hit, y_hit);
- }
-
- if (zero_rects) {
- r1 = sraRgnCreateRect(x_hit, y_hit, x_hit+w, y_hit+h);
- sraRgnSubtract(zero_rects, r1);
- sraRgnDestroy(r1);
- r1 = sraRgnCreateRect(x_hit, y_hit+dpy_y, x_hit+w, y_hit+dpy_y+h);
- sraRgnSubtract(zero_rects, r1);
- sraRgnDestroy(r1);
- }
-
- return 1;
-}
-
-static void cache_cr(sraRegionPtr r, int dx, int dy, double d0, double d1, int *nbatch) {
- if (sraRgnEmpty(r)) {
- return;
- }
- if (nbatch == NULL) {
- if (!fb_push_wait(d0, FB_COPY)) {
- fb_push_wait(d0/2, FB_COPY);
- }
- do_copyregion(r, dx, dy, 0);
- if (!fb_push_wait(d1, FB_COPY)) {
- fb_push_wait(d1/2, FB_COPY);
- }
- } else {
- batch_dxs[*nbatch] = dx;
- batch_dys[*nbatch] = dy;
- batch_reg[*nbatch] = sraRgnCreateRgn(r);
- (*nbatch)++;
- }
-}
-
-double save_delay0 = 0.02;
-double restore_delay0 = 0.02;
-double save_delay1 = 0.05;
-double restore_delay1 = 0.05;
-static double dtA, dtB;
-
-int valid_wr(int idx, Window win, XWindowAttributes *attr) {
-#ifdef MACOSX
- if (macosx_console) {
- /* this is all to avoid animation changing WxH+X+Y... */
- if (idx >= 0) {
- int rc = valid_window(win, attr, 1);
- attr->x = cache_list[idx].x;
- attr->y = cache_list[idx].y;
- attr->width = cache_list[idx].width;
- attr->height = cache_list[idx].height;
- return rc;
- } else {
- return valid_window(win, attr, 1);
- }
- }
-#else
- if (!idx) {}
-#endif
- return valid_window(win, attr, 1);
-}
-
-int clipped(int idx) {
- int ic;
- sraRegionPtr r0, r1, r2;
- int x1, y1, w1, h1;
- Window win;
- int clip = 0;
-
- if (idx < 0) {
- return 0;
- }
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
-
- x1 = cache_list[idx].x;
- y1 = cache_list[idx].y;
- w1 = cache_list[idx].width;
- h1 = cache_list[idx].height;
-
- win = cache_list[idx].win;
-
- r1 = sraRgnCreateRect(x1, y1, x1+w1, y1+h1);
- sraRgnAnd(r1, r0);
-
- for (ic = old_stack_n - 1; ic >= 0; ic--) {
- int xc, yc, wc, hc, idx2;
-
- if (old_stack[ic] == win) {
- break;
- }
- if (old_stack_mapped[ic] == 0) {
- continue;
- }
- idx2 = lookup_old_stack_index(ic);
- if (idx2 < 0) {
- continue;
- }
- if (cache_list[idx2].win == win) {
- break;
- }
- if (cache_list[idx2].map_state != IsViewable) {
- continue;
- }
- xc = cache_list[idx2].x;
- yc = cache_list[idx2].y;
- wc = cache_list[idx2].width;
- hc = cache_list[idx2].height;
-
- r2 = sraRgnCreateRect(xc, yc, xc+wc, yc+hc);
- sraRgnAnd(r2, r0);
- if (sraRgnAnd(r2, r1)) {
-if (0) fprintf(stderr, "clip[0x%lx]: 0x%lx, %d/%d\n", win, cache_list[idx2].win, ic, idx2);
- clip = 1;
- }
- sraRgnDestroy(r2);
- if (clip) {
- break;
- }
- }
- sraRgnDestroy(r0);
- sraRgnDestroy(r1);
-if (0) fprintf(stderr, "clip[0x%lx]: %s\n", win, clip ? "clipped" : "no-clipped");
- return clip;
-}
-
-void clip_region(sraRegionPtr r, Window win) {
- int ic, idx2;
- sraRegionPtr r1;
- for (ic = old_stack_n - 1; ic >= 0; ic--) {
- int xc, yc, wc, hc;
-
-if (0) fprintf(stderr, "----[0x%lx]: 0x%lx, %d %d\n", win, old_stack[ic], ic, old_stack_mapped[ic]);
- if (old_stack[ic] == win) {
- break;
- }
- if (old_stack_mapped[ic] == 0) {
- continue;
- }
- idx2 = lookup_old_stack_index(ic);
- if (idx2 < 0) {
- continue;
- }
- if (cache_list[idx2].win == win) {
- break;
- }
- if (cache_list[idx2].map_state != IsViewable) {
- continue;
- }
- xc = cache_list[idx2].x;
- yc = cache_list[idx2].y;
- wc = cache_list[idx2].width;
- hc = cache_list[idx2].height;
- r1 = sraRgnCreateRect(xc, yc, xc+wc, yc+hc);
- if (sraRgnAnd(r1, r)) {
- sraRgnSubtract(r, r1);
-if (0) fprintf(stderr, "clip[0x%lx]: 0x%lx, %d/%d\n", win, cache_list[idx2].win, ic, idx2);
- }
- sraRgnDestroy(r1);
- }
-}
-
-int bs_save(int idx, int *nbatch, XWindowAttributes *attr, int clip, int only_if_tracking, int *valid, int verb) {
- Window win = cache_list[idx].win;
- int x1, y1, w1, h1;
- int x2, y2, w2, h2;
- int x, y, w, h;
- int dx, dy, rc = 1;
- sraRegionPtr r, r0;
-
- x1 = cache_list[idx].x;
- y1 = cache_list[idx].y;
- w1 = cache_list[idx].width;
- h1 = cache_list[idx].height;
-
-if (ncdb && verb) fprintf(stderr, "backingstore save: 0x%lx %3d clip=%d\n", win, idx, clip);
-
- X_LOCK;
- if (*valid) {
- attr->x = x1;
- attr->y = y1;
- attr->width = w1;
- attr->height = h1;
- } else if (! valid_wr(idx, win, attr)) {
-if (ncdb) fprintf(stderr, "bs_save: not a valid X window: 0x%lx\n", win);
- X_UNLOCK;
- *valid = 0;
- cache_list[idx].valid = 0;
- return 0;
- } else {
- *valid = 1;
- }
- X_UNLOCK;
-
- if (only_if_tracking && cache_list[idx].bs_x < 0) {
- return 0;
- }
-
- x2 = attr->x;
- y2 = attr->y;
- w2 = attr->width;
- h2 = attr->height;
-
- if (cache_list[idx].bs_x < 0) {
- rc = find_rect(idx, x2, y2, w2, h2);
- } else if (w2 > cache_list[idx].bs_w || h2 > cache_list[idx].bs_h) {
- free_rect(idx);
- rc = find_rect(idx, x2, y2, w2, h2);
- }
-
- x = cache_list[idx].bs_x;
- y = cache_list[idx].bs_y;
- w = cache_list[idx].bs_w;
- h = cache_list[idx].bs_h;
-
- if (x < 0 || ! rc) {
-if (ncdb) fprintf(stderr, "BS_save: FAIL FOR: %d\n", idx);
- return 0;
- }
-
- if (ncache_pad) {
- x2 -= ncache_pad;
- y2 -= ncache_pad;
- w2 += 2 * ncache_pad;
- h2 += 2 * ncache_pad;
- }
-
- if (clipshift) {
- x2 -= coff_x;
- y2 -= coff_y;
- }
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
- sraRgnAnd(r, r0);
-
- if (clip) {
- clip_region(r, win);
- }
-
- if (sraRgnEmpty(r)) {
-if (ncdb && verb) fprintf(stderr, "BS_save: Region Empty: %d\n", idx);
- sraRgnDestroy(r0);
- sraRgnDestroy(r);
- return 0;
- }
-
- dx = x - x2;
- dy = y - y2;
-
- sraRgnOffset(r, dx, dy);
-
- dtA = dnowx();
-if (ncdb && verb) fprintf(stderr, "BS_save: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy);
- if (w2 > 0 && h2 > 0) {
- cache_cr(r, dx, dy, save_delay0, save_delay1, nbatch);
- }
- dtB = dnowx();
-if (ncdb && verb) fprintf(stderr, "BS_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d %.2f %.2f\n", dtB, dtB-dtA, idx, w1, h1, x1, y1, w2, h2, x2, y2, cache_list[idx].bs_time - x11vnc_start, dnowx());
-
- sraRgnDestroy(r0);
- sraRgnDestroy(r);
-
- last_bs_save = cache_list[idx].bs_time = dnow();
-
- return 1;
-}
-
-int su_save(int idx, int *nbatch, XWindowAttributes *attr, int clip, int *valid, int verb) {
- Window win = cache_list[idx].win;
- int x1, y1, w1, h1;
- int x2, y2, w2, h2;
- int x, y, w, h;
- int dx, dy, rc = 1;
- sraRegionPtr r, r0;
-
-if (ncdb && verb) fprintf(stderr, "save-unders save: 0x%lx %3d \n", win, idx);
-
- x1 = cache_list[idx].x;
- y1 = cache_list[idx].y;
- w1 = cache_list[idx].width;
- h1 = cache_list[idx].height;
-
- X_LOCK;
- if (*valid) {
- attr->x = x1;
- attr->y = y1;
- attr->width = w1;
- attr->height = h1;
- } else if (! valid_wr(idx, win, attr)) {
-if (ncdb) fprintf(stderr, "su_save: not a valid X window: 0x%lx\n", win);
- X_UNLOCK;
- *valid = 0;
- cache_list[idx].valid = 0;
- return 0;
- } else {
- *valid = 1;
- }
- X_UNLOCK;
-
- x2 = attr->x;
- y2 = attr->y;
- w2 = attr->width;
- h2 = attr->height;
-
- if (cache_list[idx].bs_x < 0) {
- rc = find_rect(idx, x2, y2, w2, h2);
- } else if (w2 > cache_list[idx].su_w || h2 > cache_list[idx].su_h) {
- free_rect(idx);
- rc = find_rect(idx, x2, y2, w2, h2);
- }
- x = cache_list[idx].su_x;
- y = cache_list[idx].su_y;
- w = cache_list[idx].su_w;
- h = cache_list[idx].su_h;
-
- if (x < 0 || ! rc) {
-if (ncdb) fprintf(stderr, "SU_save: FAIL FOR: %d\n", idx);
- return 0;
- }
-
- if (ncache_pad) {
- x2 -= ncache_pad;
- y2 -= ncache_pad;
- w2 += 2 * ncache_pad;
- h2 += 2 * ncache_pad;
- }
-
- if (clipshift) {
- x2 -= coff_x;
- y2 -= coff_y;
- }
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
- sraRgnAnd(r, r0);
-
- if (clip) {
- clip_region(r, win);
- }
-
- if (sraRgnEmpty(r)) {
-if (ncdb && verb) fprintf(stderr, "SU_save: Region Empty: %d\n", idx);
- sraRgnDestroy(r0);
- sraRgnDestroy(r);
- return 0;
- }
-
-
- dx = x - x2;
- dy = y - y2;
-
- sraRgnOffset(r, dx, dy);
-
- dtA = dnowx();
-if (ncdb && verb) fprintf(stderr, "SU_save: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy);
- if (w2 > 0 && h2 > 0) {
- cache_cr(r, dx, dy, save_delay0, save_delay1, nbatch);
- }
- dtB = dnowx();
-if (ncdb && verb) fprintf(stderr, "SU_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d %.2f %.2f\n", dtB, dtB-dtA, idx, w1, h1, x1, y1, w2, h2, x2, y2, cache_list[idx].su_time - x11vnc_start, dnowx());
-
- sraRgnDestroy(r0);
- sraRgnDestroy(r);
-
- last_su_save = cache_list[idx].su_time = dnow();
-
- return 1;
-}
-
-int bs_restore(int idx, int *nbatch, sraRegionPtr rmask, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) {
- Window win = cache_list[idx].win;
- int x1, y1, w1, h1;
- int x2, y2, w2, h2;
- int x, y, w, h;
- int dx, dy;
- sraRegionPtr r, r0;
-
-if (ncdb && verb) fprintf(stderr, "backingstore restore: 0x%lx %3d \n", win, idx);
-
- x1 = cache_list[idx].x;
- y1 = cache_list[idx].y;
- w1 = cache_list[idx].width;
- h1 = cache_list[idx].height;
-
- X_LOCK;
- if (*valid) {
- attr->x = x1;
- attr->y = y1;
- attr->width = w1;
- attr->height = h1;
- } else if (! valid_wr(idx, win, attr)) {
-if (ncdb) fprintf(stderr, "BS_restore: not a valid X window: 0x%lx\n", win);
- *valid = 0;
- X_UNLOCK;
- return 0;
- } else {
- *valid = 1;
- }
- X_UNLOCK;
-
- x2 = attr->x;
- y2 = attr->y;
- w2 = attr->width;
- h2 = attr->height;
-
- x = cache_list[idx].bs_x;
- y = cache_list[idx].bs_y;
- w = cache_list[idx].bs_w;
- h = cache_list[idx].bs_h;
-
- if (x < 0 || cache_list[idx].bs_time == 0.0) {
- return 0;
- }
-
- if (ncache_pad) {
- if (nopad) {
- x += ncache_pad;
- y += ncache_pad;
- w -= 2 * ncache_pad;
- h -= 2 * ncache_pad;
- } else {
- x2 -= ncache_pad;
- y2 -= ncache_pad;
- w2 += 2 * ncache_pad;
- h2 += 2 * ncache_pad;
- }
- }
-
- if (clipshift) {
- x2 -= coff_x;
- y2 -= coff_y;
- }
-
- if (w2 > w) {
- w2 = w;
- }
- if (h2 > h) {
- h2 = h;
- }
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- r = sraRgnCreateRect(x, y, x+w2, y+h2);
-
- dx = x2 - x;
- dy = y2 - y;
-
- sraRgnOffset(r, dx, dy);
- sraRgnAnd(r, r0);
-
- if (clip) {
- clip_region(r, win);
- }
- if (rmask != NULL) {
- sraRgnAnd(r, rmask);
- }
-
- dtA = dnowx();
-if (ncdb && verb) fprintf(stderr, "BS_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy);
- if (w2 > 0 && h2 > 0) {
- cache_cr(r, dx, dy, restore_delay0, restore_delay1, nbatch);
- }
- dtB = dnowx();
-if (ncdb && verb) fprintf(stderr, "BS_rest: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d %.2f %.2f\n", dtB, dtB-dtA, idx, w1, h1, x1, y1, w2, h2, x2, y2, cache_list[idx].bs_time - x11vnc_start, dnowx());
-
- sraRgnDestroy(r0);
- sraRgnDestroy(r);
-
- last_bs_restore = dnow();
-
- return 1;
-}
-
-int su_restore(int idx, int *nbatch, sraRegionPtr rmask, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) {
- Window win = cache_list[idx].win;
- int x1, y1, w1, h1;
- int x2 = 0, y2 = 0, w2 = 0, h2 = 0;
- int x, y, w, h;
- int dx, dy;
- sraRegionPtr r, r0;
-
-if (ncdb && verb) fprintf(stderr, "save-unders restore: 0x%lx %3d \n", win, idx);
-
- x1 = cache_list[idx].x;
- y1 = cache_list[idx].y;
- w1 = cache_list[idx].width;
- h1 = cache_list[idx].height;
-
- X_LOCK;
- if (*valid) {
- attr->x = x1;
- attr->y = y1;
- attr->width = w1;
- attr->height = h1;
- x2 = attr->x;
- y2 = attr->y;
- w2 = attr->width;
- h2 = attr->height;
- } else if (! valid_wr(idx, win, attr)) {
-if (ncdb) fprintf(stderr, "SU_restore: not a valid X window: 0x%lx\n", win);
- *valid = 0;
- x2 = x1;
- y2 = y1;
- w2 = w1;
- h2 = h1;
- } else {
- x2 = attr->x;
- y2 = attr->y;
- w2 = attr->width;
- h2 = attr->height;
- *valid = 1;
- }
- X_UNLOCK;
-
- x = cache_list[idx].su_x;
- y = cache_list[idx].su_y;
- w = cache_list[idx].su_w;
- h = cache_list[idx].su_h;
-
- if (x < 0 || cache_list[idx].bs_x < 0 || cache_list[idx].su_time == 0.0) {
-if (ncdb) fprintf(stderr, "SU_rest: su_x/bs_x/su_time: %d %d %.3f\n", x, cache_list[idx].bs_x, cache_list[idx].su_time);
- return 0;
- }
-
- if (ncache_pad) {
- if (nopad) {
- x += ncache_pad;
- y += ncache_pad;
- w -= 2 * ncache_pad;
- h -= 2 * ncache_pad;
- } else {
- x2 -= ncache_pad;
- y2 -= ncache_pad;
- w2 += 2 * ncache_pad;
- h2 += 2 * ncache_pad;
- }
- }
-
- if (clipshift) {
- x2 -= coff_x;
- y2 -= coff_y;
- }
-
- if (w2 > w) {
- w2 = w;
- }
- if (h2 > h) {
- h2 = h;
- }
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- r = sraRgnCreateRect(x, y, x+w2, y+h2);
-
- dx = x2 - x;
- dy = y2 - y;
-
- sraRgnOffset(r, dx, dy);
- sraRgnAnd(r, r0);
-
- if (clip) {
- clip_region(r, win);
- }
- if (rmask != NULL) {
- sraRgnAnd(r, rmask);
- }
-
- dtA = dnowx();
-if (ncdb && verb) fprintf(stderr, "SU_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy);
- if (w2 > 0 && h2 > 0) {
- cache_cr(r, dx, dy, restore_delay0, restore_delay1, nbatch);
- }
- dtB = dnowx();
-if (ncdb && verb) fprintf(stderr, "SU_rest: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d %.2f %.2f\n", dtB, dtB-dtA, idx, w1, h1, x1, y1, w2, h2, x2, y2, cache_list[idx].su_time - x11vnc_start, dnowx());
-
- sraRgnDestroy(r0);
- sraRgnDestroy(r);
-
- last_su_restore = dnow();
-
- return 1;
-}
-
-void check_zero_rects(void) {
- sraRect rt;
- sraRectangleIterator *iter;
- if (! zero_rects) {
- zero_rects = sraRgnCreate();
- }
- if (sraRgnEmpty(zero_rects)) {
- return;
- }
-
- iter = sraRgnGetIterator(zero_rects);
- while (sraRgnIteratorNext(iter, &rt)) {
- zero_fb(rt.x1, rt.y1, rt.x2, rt.y2);
- mark_rect_as_modified(rt.x1, rt.y1, rt.x2, rt.y2, 0);
- }
- sraRgnReleaseIterator(iter);
- sraRgnMakeEmpty(zero_rects);
-}
-
-void block_stats(void) {
- int n, k, s1, s2;
- static int t = -1;
- int vcnt, icnt, tcnt, vtot = 0, itot = 0, ttot = 0;
- t++;
- for (n = 1; n < ncache+1; n += 2) {
- double area = 0.0, frac;
- vcnt = 0;
- icnt = 0;
- tcnt = 0;
- for(k=0; k<cache_list_num; k++) {
- XWindowAttributes attr;
- int x = cache_list[k].bs_x;
- int y = cache_list[k].bs_y;
- int w = cache_list[k].bs_w;
- int h = cache_list[k].bs_h;
- int rc = 0;
- Window win = cache_list[k].win;
-
- if (win == None) {
- continue;
- }
- if (n == 1) {
- X_LOCK;
- rc = valid_window(win, &attr, 1);
- X_UNLOCK;
- if (rc) {
- vtot++;
- } else {
- itot++;
- }
- if (x >= 0) {
- ttot++;
- }
- }
- if (y < n*dpy_y || y > (n+1)*dpy_y) {
- continue;
- }
- if (n != 1) {
- X_LOCK;
- rc = valid_window(win, &attr, 1);
- X_UNLOCK;
- }
- if (rc) {
- vcnt++;
- } else {
- icnt++;
- }
- if (x >= 0) {
- tcnt++;
- }
- if (x < 0) {
- continue;
- }
- area += cache_list[k].width * cache_list[k].height;
- if (! rc && ! macosx_console) {
- char *u = getenv("USER");
- if (u && !strcmp(u, "runge")) fprintf(stderr, "\a");
- if (ncdb) fprintf(stderr, "\n *** UNRECLAIMED WINDOW: 0x%lx %dx%d+%d+%d\n\n", win, w, h, x, y);
- DELETE(k);
- }
- if (t < 3 || (t % 4) == 0 || hack_val || macosx_console) {
- double t1 = cache_list[k].su_time;
- double t2 = cache_list[k].bs_time;
- if (t1 > 0.0) {t1 = dnow() - t1;} else {t1 = -1.0;}
- if (t2 > 0.0) {t2 = dnow() - t2;} else {t2 = -1.0;}
- if (ncdb) fprintf(stderr, " [%02d] %04d 0x%08lx bs: %04dx%04d+%04d+%05d vw: %04dx%04d+%04d+%04d cl: %04dx%04d+%04d+%04d map=%d su=%9.3f bs=%9.3f cnt=%d/%d\n",
- n, k, win, w, h, x, y, attr.width, attr.height, attr.x, attr.y,
- cache_list[k].width, cache_list[k].height, cache_list[k].x, cache_list[k].y,
- attr.map_state == IsViewable, t1, t2, cache_list[k].create_cnt, cache_list[k].map_cnt);
- }
- }
- frac = area /(dpy_x * dpy_y);
- if (ncdb) fprintf(stderr, "block[%02d] %.3f %8d trak/val/inval: %d/%d/%d of %d\n", n, frac, (int) area, tcnt, vcnt, icnt, vcnt+icnt);
- }
-
- if (ncdb) fprintf(stderr, "\n");
- if (ncdb) fprintf(stderr, "block: trak/val/inval %d/%d/%d of %d\n", ttot, vtot, itot, vtot+itot);
-
- s1 = fr_REGION + fr_GRID + fr_EXPIRE + fr_FORCE + fr_BIG1 + fr_BIG2 + fr_FAIL;
- s2 = fr_REGIONt + fr_GRIDt + fr_EXPIREt + fr_FORCEt + fr_BIG1t + fr_BIG2t + fr_FAILt;
- if (ncdb) fprintf(stderr, "\n");
- if (ncdb) fprintf(stderr, "find_rect: REGION/GRID/EXPIRE/FORCE - BIG1/BIG2/FAIL %d/%d/%d/%d - %d/%d/%d of %d\n",
- fr_REGION, fr_GRID, fr_EXPIRE, fr_FORCE, fr_BIG1, fr_BIG2, fr_FAIL, s1);
- if (ncdb) fprintf(stderr, " totals: %d/%d/%d/%d - %d/%d/%d of %d\n",
- fr_REGIONt, fr_GRIDt, fr_EXPIREt, fr_FORCEt, fr_BIG1t, fr_BIG2t, fr_FAILt, s2);
-
- fr_BIG1 = 0;
- fr_BIG2 = 0;
- fr_REGION = 0;
- fr_GRID = 0;
- fr_EXPIRE = 0;
- fr_FORCE = 0;
- fr_FAIL = 0;
- if (ncdb) fprintf(stderr, "\n");
-}
-
-#define NSCHED 128
-Window sched_bs[NSCHED];
-double sched_tm[NSCHED];
-double last_sched_bs = 0.0;
-
-#define SCHED(w, v) \
-{ \
- int k, save = -1, empty = 1; \
- for (k=0; k < NSCHED; k++) { \
- if (sched_bs[k] == None) { \
- save = k; \
- } \
- if (sched_bs[k] == w) { \
- save = k; \
- empty = 0; \
- break; \
- } \
- } \
- if (save >= 0) { \
- sched_bs[save] = w; \
- if (empty) { \
- sched_tm[save] = dnow(); \
- if (v && ncdb) fprintf(stderr, "SCHED: %d %f\n", save, dnowx()); \
- } \
- } \
-}
-
-void xselectinput(Window w, unsigned long evmask, int sync) {
-#if NO_X11
- trapped_xerror = 0;
- trapped_xioerror = 0;
- if (!evmask) {}
-#else
- XErrorHandler old_handler1;
- XIOErrorHandler old_handler2;
-
- if (macosx_console || !dpy) {
- return;
- }
-
- old_handler1 = XSetErrorHandler(trap_xerror);
- old_handler2 = XSetIOErrorHandler(trap_xioerror);
- trapped_xerror = 0;
- trapped_xioerror = 0;
-
- XSelectInput(dpy, w, evmask);
-
- /*
- * We seem to need to synchronize right away since the window
- * might go away quickly.
- */
- if (sync) {
- XSync(dpy, False);
- } else {
- XFlush_wr(dpy);
- }
-
- XSetErrorHandler(old_handler1);
- XSetIOErrorHandler(old_handler2);
-#endif
-
- if (trapped_xerror) {
- if (ncdb) fprintf(stderr, "XSELECTINPUT: trapped X Error.");
- }
- if (trapped_xioerror) {
- if (ncdb) fprintf(stderr, "XSELECTINPUT: trapped XIO Error.");
- }
-if (sync && ncdb) fprintf(stderr, "XSELECTINPUT: 0x%lx sync=%d err=%d/%d\n", w, sync, trapped_xerror, trapped_xioerror);
-}
-
-Bool xcheckmaskevent(Display *d, long mask, XEvent *ev) {
-#ifdef MACOSX
- if (macosx_console) {
- if (macosx_checkevent(ev)) {
- return True;
- } else {
- return False;
- }
- }
-#endif
- RAWFB_RET(False);
-
-#if NO_X11
- if (!d || !mask) {}
- return False;
-#else
- return XCheckMaskEvent(d, mask, ev);
-#endif
-}
-
-#include <rfb/default8x16.h>
-
-#define EVMAX 2048
-XEvent Ev[EVMAX];
-int Ev_done[EVMAX];
-int Ev_order[EVMAX];
-int Ev_area[EVMAX];
-int Ev_tmp[EVMAX];
-int Ev_tmp2[EVMAX];
-Window Ev_tmpwin[EVMAX];
-Window Ev_win[EVMAX];
-Window Ev_map[EVMAX];
-Window Ev_unmap[EVMAX];
-sraRect Ev_rects[EVMAX];
-
-int tmp_stack[STACKMAX];
-sraRegionPtr tmp_reg[STACKMAX];
-
-#define CLEAN_OUT \
- for (i=0; i < n; i++) { \
- sraRgnDestroy(tmp_reg[i]); \
- } \
- if (r1) sraRgnDestroy(r1); \
- if (r0) sraRgnDestroy(r0);
-
-int try_to_fix_resize_su(Window orig_frame, int orig_x, int orig_y, int orig_w, int orig_h,
- int x, int y, int w, int h, int try_batch) {
-
- int idx = lookup_win_index(orig_frame);
- sraRegionPtr r0, r1, r2, r3;
- int sx1, sy1, sw1, sh1, dx, dy;
- int bx1, by1, bw1, bh1;
- int nr = 0, *nbat = NULL;
-
- if (idx < 0) {
- return 0;
- }
- if (cache_list[idx].bs_x < 0 || cache_list[idx].su_time == 0.0) {
- return 0;
- }
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- r1 = sraRgnCreateRect(orig_x, orig_y, orig_x+orig_w, orig_y+orig_h);
- r2 = sraRgnCreateRect(x, y, x+w, y+h);
-
- sraRgnAnd(r1, r0);
- sraRgnAnd(r2, r0);
-
- if (try_batch) {
- nbat = &nr;
- }
-
- if (orig_w >= w && orig_h >= h) {
-
-if (0) fprintf(stderr, "Shrinking resize %d %dx%d+%d+%d -> %dx%d+%d+%d\n", idx, orig_w, orig_h, orig_x, orig_y, w, h, x, y);
- r3 = sraRgnCreateRgn(r1);
- sraRgnSubtract(r3, r2);
-
- sx1 = cache_list[idx].su_x;
- sy1 = cache_list[idx].su_y;
- sw1 = cache_list[idx].su_w;
- sh1 = cache_list[idx].su_h;
-
- dx = orig_x - sx1;
- dy = orig_y - sy1;
-
- cache_cr(r3, dx, dy, 0.075, 0.05, nbat);
- sraRgnDestroy(r3);
-
- r3 = sraRgnCreateRgn(r1);
- sraRgnAnd(r3, r2);
-
- dx = sx1 - orig_x;
- dy = sy1 - orig_y;
- sraRgnOffset(r3, dx, dy);
-
- dx = orig_x - x;
- dy = orig_y - y;
- sraRgnOffset(r3, dx, dy);
-
- cache_cr(r3, dx, dy, 0.075, 0.05, nbat);
- sraRgnDestroy(r3);
-
- if (nr) {
- batch_push(nr, -1.0);
- }
-
- cache_list[idx].x = x;
- cache_list[idx].y = y;
- cache_list[idx].width = w;
- cache_list[idx].height = h;
-
- cache_list[idx].bs_w = w;
- cache_list[idx].bs_h = h;
- cache_list[idx].su_w = w;
- cache_list[idx].su_h = h;
-
- cache_list[idx].bs_time = 0.0;
- /* XXX Y */
- if (0) cache_list[idx].su_time = dnow();
- } else {
-if (0) fprintf(stderr, "Growing resize %d %dx%d+%d+%d -> %dx%d+%d+%d\n", idx, orig_w, orig_h, orig_x, orig_y, w, h, x, y);
-
- sx1 = cache_list[idx].su_x;
- sy1 = cache_list[idx].su_y;
- sw1 = cache_list[idx].su_w;
- sh1 = cache_list[idx].su_h;
-
- bx1 = cache_list[idx].bs_x;
- by1 = cache_list[idx].bs_y;
- bw1 = cache_list[idx].bs_w;
- bh1 = cache_list[idx].bs_h;
-
- if (find_rect(idx, x, y, w, h)) {
- r3 = sraRgnCreateRgn(r2);
- sraRgnAnd(r3, r1);
-
- dx = cache_list[idx].su_x - x;
- dy = cache_list[idx].su_y - y;
-
- sraRgnOffset(r3, dx, dy);
-
- dx = dx - (sx1 - orig_x);
- dy = dy - (sy1 - orig_y);
-
- cache_cr(r3, dx, dy, 0.075, 0.05, nbat);
- sraRgnDestroy(r3);
-
- r3 = sraRgnCreateRgn(r2);
- sraRgnSubtract(r3, r1);
-
- dx = cache_list[idx].su_x - x;
- dy = cache_list[idx].su_y - y;
-
- sraRgnOffset(r3, dx, dy);
-
- cache_cr(r3, dx, dy, 0.075, 0.05, nbat);
- sraRgnDestroy(r3);
-
- if (nr) {
- batch_push(nr, -1.0);
- }
-
- cache_list[idx].bs_time = 0.0;
- /* XXX Y */
- if (0) cache_list[idx].su_time = dnow();
- }
- }
-
- sraRgnDestroy(r0);
- sraRgnDestroy(r1);
- sraRgnDestroy(r2);
-
- return 1;
-}
-
-int try_to_fix_su(Window win, int idx, Window above, int *nbatch, char *mode) {
- int i, idx2, n = 0, found = 0, found_above = 0;
- sraRegionPtr r0, r1, r2;
- Window win2;
- int x, y, w, h, on = 0;
- int x0, y0, w0, h0;
- int x1, y1, w1, h1;
- int x2, y2, w2, h2;
- int unmapped = 0;
- int moved = 0;
-
-
- if (mode && !strcmp(mode, "unmapped")) {
- unmapped = 1;
- } else if (mode && !strcmp(mode, "moved")) {
- moved = 1;
- }
- if (idx < 0) {
- return 0;
- }
-if (ncdb) fprintf(stderr, "TRY_TO_FIX_SU(%d) 0x%lx 0x%lx was_unmapped=%d map_state=%s\n", idx, win, above, unmapped, MState(cache_list[idx].map_state));
-
- if (cache_list[idx].map_state != IsViewable && !unmapped) {
- return 0;
- }
- if (cache_list[idx].su_time == 0.0) {
- return 0;
- }
- if (cache_list[idx].bs_x < 0) {
- return 0;
- }
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
-
- x = cache_list[idx].x;
- y = cache_list[idx].y;
- w = cache_list[idx].width;
- h = cache_list[idx].height;
-
- r1 = sraRgnCreateRect(x, y, x+w, y+h);
-
- sraRgnAnd(r1, r0);
-
- if (sraRgnEmpty(r1)) {
- CLEAN_OUT
- return 0;
- }
-
- if (unmapped) {
- on = 1;
- }
- if (above == 0x1) {
- on = 1;
- }
- for (i = old_stack_n - 1; i >= 0; i--) {
- win2 = old_stack[i];
- if (win2 == above) {
-if (0) fprintf(stderr, "0x%lx turn on: 0x%lx i=%d\n", win, win2, i);
- on = 1;
- found_above = 1;
- }
- if (win2 == win) {
-if (0) fprintf(stderr, "0x%lx turn off: 0x%lx i=%d\n", win, win2, i);
- found = 1;
- on = 0;
- break;
- }
- if (! on) {
- continue;
- }
- idx2 = lookup_win_index(win2);
- if (idx2 < 0) {
- continue;
- }
- if (cache_list[idx2].map_state != IsViewable) {
- continue;
- }
- if (cache_list[idx2].bs_x < 0) {
- continue;
- }
- /* XXX Invalidate? */
-
- x2 = cache_list[idx2].x;
- y2 = cache_list[idx2].y;
- w2 = cache_list[idx2].width;
- h2 = cache_list[idx2].height;
-
- r2 = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
- sraRgnAnd(r2, r0);
- if (! sraRgnAnd(r2, r1)) {
- sraRgnDestroy(r2);
- continue;
- }
-
- tmp_reg[n] = r2;
- tmp_stack[n++] = idx2;
- }
-
- if (! found) {
- CLEAN_OUT
- return 0;
- }
-
- for (i = n - 1; i >= 0; i--) {
- int i2;
- r2 = sraRgnCreateRgn(tmp_reg[i]);
- for (i2 = i + 1; i2 < n; i2++) {
- sraRgnSubtract(r2, tmp_reg[i2]);
- }
- idx2 = tmp_stack[i];
- if (!sraRgnEmpty(r2)) {
- int dx, dy;
- int dx2, dy2;
-
- x0 = cache_list[idx2].x;
- y0 = cache_list[idx2].y;
- w0 = cache_list[idx2].width;
- h0 = cache_list[idx2].height;
-
- x1 = cache_list[idx].su_x; /* SU -> SU */
- y1 = cache_list[idx].su_y;
- w1 = cache_list[idx].su_w;
- h1 = cache_list[idx].su_h;
-
- x2 = cache_list[idx2].su_x;
- y2 = cache_list[idx2].su_y;
- w2 = cache_list[idx2].su_w;
- h2 = cache_list[idx2].su_h;
-
- dx = x2 - x0;
- dy = y2 - y0;
- sraRgnOffset(r2, dx, dy);
-
- dx2 = x1 - x;
- dy2 = y1 - y;
- dx = dx - dx2;
- dy = dy - dy2;
- cache_cr(r2, dx, dy, save_delay0, save_delay1, nbatch);
- }
- sraRgnDestroy(r2);
- }
-
- if (unmapped) {
- CLEAN_OUT
- return found_above;
- }
-
- for (i = n - 1; i >= 0; i--) {
- r2 = sraRgnCreateRgn(tmp_reg[i]);
- idx2 = tmp_stack[i];
- if (!sraRgnEmpty(r2)) {
- int dx, dy;
- int dx2, dy2;
-
- x0 = cache_list[idx2].x;
- y0 = cache_list[idx2].y;
- w0 = cache_list[idx2].width;
- h0 = cache_list[idx2].height;
-
- x1 = cache_list[idx].su_x; /* BS -> SU */
- y1 = cache_list[idx].su_y;
- w1 = cache_list[idx].su_w;
- h1 = cache_list[idx].su_h;
-
- x2 = cache_list[idx2].bs_x;
- y2 = cache_list[idx2].bs_y;
- w2 = cache_list[idx2].bs_w;
- h2 = cache_list[idx2].bs_h;
-
- dx = x1 - x;
- dy = y1 - y;
- sraRgnOffset(r2, dx, dy);
-
- dx2 = x2 - x0;
- dy2 = y2 - y0;
- dx = dx - dx2;
- dy = dy - dy2;
- cache_cr(r2, dx, dy, save_delay0, save_delay1, nbatch);
- }
- sraRgnDestroy(r2);
- }
-
- CLEAN_OUT
- return found_above;
-}
-
-void idx_add_rgn(sraRegionPtr r, sraRegionPtr r0, int idx) {
- int x, y, w, h;
- sraRegionPtr rtmp;
-
- if (idx < 0) {
- return;
- }
- x = cache_list[idx].x;
- y = cache_list[idx].y;
- w = cache_list[idx].width;
- h = cache_list[idx].height;
-
- rtmp = sraRgnCreateRect(x, y, w, h);
- if (r0) {
- sraRgnAnd(rtmp, r0);
- }
- sraRgnOr(r, rtmp);
- sraRgnDestroy(rtmp);
-}
-
-sraRegionPtr idx_create_rgn(sraRegionPtr r0, int idx) {
- int x, y, w, h;
- sraRegionPtr rtmp;
-
- if (idx < 0) {
- return NULL;
- }
- x = cache_list[idx].x;
- y = cache_list[idx].y;
- w = cache_list[idx].width;
- h = cache_list[idx].height;
-
- rtmp = sraRgnCreateRect(x, y, w, h);
- if (r0) {
- sraRgnAnd(rtmp, r0);
- }
- return rtmp;
-}
-
-void scale_mark_xrootpmap(void) {
- char *dst_fb, *src_fb = main_fb;
- int dst_bpl, Bpp = bpp/8, fac = 1;
- int yn = (ncache+1) * dpy_y;
- int yfac = (ncache+2);
- int mark = 1;
-
- if (!scaling || !rfb_fb || rfb_fb == main_fb) {
- mark_rect_as_modified(0, yn, dpy_x, yn + dpy_y, 0);
- return;
- }
-
- if (cmap8to24 && cmap8to24_fb) {
- src_fb = cmap8to24_fb;
- if (scaling) {
- if (depth <= 8) {
- fac = 4;
- } else if (depth <= 16) {
- fac = 2;
- }
- }
- }
- dst_fb = rfb_fb;
- dst_bpl = rfb_bytes_per_line;
-
- scale_rect(scale_fac_x, scale_fac_y, scaling_blend, scaling_interpolate, fac * Bpp,
- src_fb, fac * main_bytes_per_line, dst_fb, dst_bpl, dpy_x, yfac * dpy_y,
- scaled_x, yfac * scaled_y, 0, yn, dpy_x, yn + dpy_y, mark);
-}
-
-void set_ncache_xrootpmap(void) {
- Atom pmap, type;
- int format;
- unsigned long length, after;
- XImage *image = NULL;
- XErrorHandler old_handler;
-
- RAWFB_RET_VOID
-#if !NO_X11
- if (!ncache) {
- return;
- }
- X_LOCK;
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
- pmap = XInternAtom(dpy, "_XROOTPMAP_ID", True);
-
- if (use_solid_bg) {
- image = solid_image(NULL);
- if (!quiet) {
- rfbLog("set_ncache_xrootpmap: solid_image\n");
- }
- } else if (pmap != None) {
- Pixmap pixmap = None;
- unsigned char *d_pmap;
-
- XGetWindowProperty(dpy, rootwin, pmap, 0L, 1L, False,
- AnyPropertyType, &type, &format, &length, &after, &d_pmap);
-
- if (length != 0) {
- pixmap = *((Pixmap *) d_pmap);
- if (pixmap != None) {
- image = XGetImage(dpy, pixmap, 0, 0, dpy_x, dpy_y, AllPlanes, ZPixmap);
- }
- }
- if (!quiet) {
- rfbLog("set_ncache_xrootpmap: loading background pixmap: 0x%lx\n", pixmap);
- }
- } else {
- if (!quiet) {
- rfbLog("set_ncache_xrootpmap: trying root background\n");
- }
- }
- if (image == NULL) {
- image = solid_root((char *) 0x1);
- }
- if (image != NULL) {
- char *src, *dst;
- int line;
- int pixelsize = bpp/8;
- int y1 = dpy_y * (ncache+1);
-
- src = image->data;
- dst = main_fb + y1 * main_bytes_per_line;
- line = 0;
- while (line++ < dpy_y) {
- memcpy(dst, src, dpy_x * pixelsize);
- src += image->bytes_per_line;
- dst += main_bytes_per_line;
- }
- XDestroyImage(image);
- X_UNLOCK;
- scale_mark_xrootpmap();
- X_LOCK;
- } else {
- int yn = (ncache+1) * dpy_y;
- zero_fb(0, yn, dpy_x, yn + dpy_y);
- }
- XSetErrorHandler(old_handler);
- X_UNLOCK;
-#endif
-}
-
-#define EVLISTMAX 256
-#define EV_RESET 0
-#define EV_CREATE 1
-#define EV_DESTROY 2
-#define EV_UNMAP 3
-#define EV_MAP 4
-#define EV_REPARENT 5
-#define EV_CONFIGURE 6
-#define EV_CONFIGURE_SIZE 7
-#define EV_CONFIGURE_POS 8
-#define EV_CONFIGURE_STACK 9
-#define EV_VISIBILITY_UNOBS 10
-#define EV_VISIBILITY_OBS 11
-#define EV_PROPERTY 12
-#define EV_OLD_WM_MAP 13
-#define EV_OLD_WM_UNMAP 14
-#define EV_OLD_WM_OFF 15
-#define EV_OLD_WM_NOTMAPPED 16
-Window _ev_list[EVLISTMAX];
-int _ev_case[EVLISTMAX];
-int _ev_list_cnt;
-
-int n_CN = 0, n_RN = 0, n_DN = 0, n_ON = 0, n_MN = 0, n_UN = 0;
-int n_VN = 0, n_VN_p = 0, n_VN_u = 0, n_ST = 0, n_PN = 0, n_DC = 0;
-int n_ON_sz = 0, n_ON_po = 0, n_ON_st = 0;
-
-int ev_store(Window win, int type) {
- if (type == EV_RESET) {
- n_CN = 0; n_RN = 0; n_DN = 0; n_ON = 0; n_MN = 0; n_UN = 0;
- n_VN = 0; n_VN_p = 0; n_VN_u = 0; n_ST = 0; n_PN = 0; n_DC = 0;
- n_ON_sz = 0; n_ON_po = 0; n_ON_st = 0;
- _ev_list_cnt = 0;
- return 1;
- }
- if (_ev_list_cnt >= EVLISTMAX) {
- return 0;
- }
- _ev_list[_ev_list_cnt] = win;
- _ev_case[_ev_list_cnt++] = type;
- return 1;
-}
-
-int ev_lookup(Window win, int type) {
- int i;
- for(i=0; i < _ev_list_cnt; i++) {
- if (_ev_list[i] == win && _ev_case[i] == type) {
- return 1;
- }
- }
- return 0;
-}
-
-unsigned long all_ev = SubstructureNotifyMask|StructureNotifyMask|VisibilityChangeMask;
-unsigned long win_ev = StructureNotifyMask|VisibilityChangeMask;
-
-void read_events(int *n_in) {
- int n = *n_in;
- Window win, win2;
- XEvent ev;
-
- while (xcheckmaskevent(dpy, all_ev, &Ev[n])) {
- int cfg_size = 0;
- int cfg_pos = 0;
- int cfg_stack = 0;
- int type = Ev[n].type;
- Window w = None;
-
- win = Ev[n].xany.window;
- Ev_done[n] = 0;
- Ev_area[n] = 0;
- Ev_win[n] = win;
- Ev_map[n] = None;
- Ev_unmap[n] = None;
- Ev_order[n] = n;
-
- ev = Ev[n];
-
- if (type == DestroyNotify) w = Ev[n].xcreatewindow.window;
- if (type == CreateNotify) w = Ev[n].xdestroywindow.window;
- if (type == ReparentNotify) w = Ev[n].xreparent.window;
- if (type == UnmapNotify) w = Ev[n].xunmap.window;
- if (type == MapNotify) w = Ev[n].xmap.window;
- if (type == Expose) w = Ev[n].xexpose.window;
- if (type == ConfigureNotify) w = Ev[n].xconfigure.window;
- if (type == VisibilityNotify) w = win;
- if (n == *n_in && ncdb) fprintf(stderr, "\n");
- if (1) {
- char *msg = "";
- int idx = -1, x = 0, y = 0, wd = 0, ht = 0;
- if (w != None) {
- idx = lookup_win_index(w);
- if (idx >= 0) {
- x = cache_list[idx].x;
- y = cache_list[idx].y;
- wd = cache_list[idx].width;
- ht = cache_list[idx].height;
- }
- }
- if (type == VisibilityNotify) {
- msg = VState(Ev[n].xvisibility.state);
- } else if (type == ConfigureNotify) {
- int x_new = Ev[n].xconfigure.x;
- int y_new = Ev[n].xconfigure.y;
- int w_new = Ev[n].xconfigure.width;
- int h_new = Ev[n].xconfigure.height;
- if (idx >= 0) {
- if (w_new != wd || h_new != ht) {
- msg = "change size";
- cfg_size = 1;
- }
- if (x_new != x || y_new != y) {
- if (!strcmp(msg, "")) {
- msg = "change position";
- }
- cfg_pos = 1;
- } else if (! cfg_size) {
- msg = "change stacking";
- cfg_stack = 1;
- }
- }
- }
-
- if (ncdb) fprintf(stderr, "----- %02d inputev 0x%08lx w: 0x%08lx %04dx%04d+%04d+%04d %s %s\n", n, win, w, wd, ht, x, y, Etype(type), msg);
- }
-
- if (win == rootwin) {
- if (type == CreateNotify) {
- win2 = ev.xcreatewindow.window;
- ev_store(win2, EV_CREATE);
- n++;
- n_CN++;
- } else if (type == ReparentNotify) {
- if (ev.xreparent.parent != rootwin) {
- win2 = ev.xreparent.window;
- if (win2 != rootwin) {
- ev_store(win2, EV_REPARENT);
- }
- }
- n++;
- n_RN++;
- } else if (type == PropertyNotify) {
- set_prop_atom(Ev[n].xproperty.atom);
- n++;
- n_PN++;
- } else if (type == MapNotify) {
- win2 = ev.xmap.window;
- ev_store(win2, EV_MAP);
- n++;
- n_CN++;
- } else {
- /* skip rest */
-#if 0
- Window w = None;
-if (type == DestroyNotify) w = Ev[n].xdestroywindow.window;
-if (type == UnmapNotify) w = Ev[n].xunmap.window;
-if (type == MapNotify) w = Ev[n].xmap.window;
-if (type == Expose) w = Ev[n].xexpose.window;
-if (type == ConfigureNotify) w = Ev[n].xconfigure.window;
-if (type != ConfigureNotify) fprintf(stderr, "root: skip %s for 0x%lx\n", Etype(type), w);
-#endif
-
- }
- } else {
- if (type == ReparentNotify) {
- ev_store(win, EV_REPARENT);
- n++;
- n_RN++;
- } else if (type == DestroyNotify) {
- ev_store(win, EV_DESTROY);
- n++;
- n_DN++;
- } else if (type == ConfigureNotify) {
- ev_store(win, EV_CONFIGURE);
- if (cfg_size) {
- ev_store(win, EV_CONFIGURE_SIZE);
- n_ON_sz++;
- }
- if (cfg_pos) {
- ev_store(win, EV_CONFIGURE_POS);
- n_ON_po++;
- }
- if (cfg_stack) {
- ev_store(win, EV_CONFIGURE_STACK);
- n_ON_st++;
- }
- n++;
- n_ON++;
- } else if (type == VisibilityNotify) {
- if (Ev[n].xvisibility.state == VisibilityUnobscured) {
- ev_store(win, EV_VISIBILITY_UNOBS);
- n_VN_u++;
- } else {
- ev_store(win, EV_VISIBILITY_OBS);
- n_VN_p++;
- }
- n++;
- n_VN++;
- } else if (type == MapNotify) {
- ev_store(win, EV_MAP);
- Ev_map[n] = win;
- n++;
- n_MN++;
- } else if (type == UnmapNotify) {
- ev_store(win, EV_UNMAP);
- Ev_unmap[n] = win;
- n++;
- n_UN++;
- } else {
- /* skip rest */
-if (ncdb) fprintf(stderr, "----- skip %s\n", Etype(type));
- }
- }
- if (n >= EVMAX) {
- break;
- }
- }
- *n_in = n;
-}
-
-int try_to_synthesize_su(int force, int urgent, int *nbatch) {
- int i, idx, idx2, n = 0;
- sraRegionPtr r0, r1, r2;
- Window win = None;
- int x0, y0, w0, h0;
- int x1, y1, w1, h1;
- int x2, y2, w2, h2;
- int x3, y3, w3, h3;
- XWindowAttributes attr;
-
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
-
- snap_old();
-
- X_LOCK;
- for (i = old_stack_n - 1; i >= 0; i--) {
- win = old_stack[i];
- if (urgent) { /* XXX Y resp */
- if (!valid_window(win, &attr, 1)) {
- continue;
- }
- idx = lookup_win_index(win);
- if (idx >= 0) {
- STORE(idx, win, attr);
- }
- } else {
- idx = lookup_win_index(win);
- if (idx >= 0) {
- attr.map_state = cache_list[idx].map_state;
- attr.x = cache_list[idx].x;
- attr.y = cache_list[idx].y;
- attr.width = cache_list[idx].width;
- attr.height = cache_list[idx].height;
- } else {
- attr.map_state = IsUnmapped;
- attr.x = 0;
- attr.y = 0;
- attr.width = 0;
- attr.height = 0;
- }
-
- }
- if (attr.map_state != IsViewable) {
- continue;
- }
-if (0) fprintf(stderr, "win: 0x%lx %d idx=%d\n", win, i, idx);
-
- x2 = attr.x;
- y2 = attr.y;
- w2 = attr.width;
- h2 = attr.height;
-
- r2 = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
- sraRgnAnd(r2, r0);
-
- tmp_reg[n] = r2;
- tmp_stack[n++] = idx;
- }
- X_UNLOCK;
-
- if (! n) {
- r1 = NULL;
- CLEAN_OUT
- return 0;
- }
-
- for (i = 0; i < n; i++) {
- int i2, cnt = 0;
- idx = tmp_stack[i];
- if (idx < 0 || cache_list[idx].bs_x < 0) {
- continue;
- }
- r1 = tmp_reg[i];
- if (r1 == NULL || sraRgnEmpty(r1)) {
- continue;
- }
- if (cache_list[idx].su_time > 0.0) {
- if (force) {
-if (ncdb) fprintf(stderr, "forcing synth: 0x%lx %d\n", cache_list[idx].win, idx);
- } else {
- continue;
- }
- }
- if (ncache_xrootpmap) {
- int dx, dy;
-
- x0 = cache_list[idx].x;
- y0 = cache_list[idx].y;
- w0 = cache_list[idx].width;
- h0 = cache_list[idx].height;
-
- x1 = cache_list[idx].su_x;
- y1 = cache_list[idx].su_y;
- w1 = cache_list[idx].su_w;
- h1 = cache_list[idx].su_h;
-
- r2 = sraRgnCreateRgn(tmp_reg[i]);
- dx = x1 - x0;
- dy = y1 - y0;
-
- sraRgnOffset(r2, dx, dy);
-
- x2 = x0;
- y2 = y0 + (ncache+1) * dpy_y;
-
- dx = x1 - x2;
- dy = y1 - y2;
- cache_cr(r2, dx, dy, save_delay0, save_delay1, nbatch);
- cnt++;
-
- sraRgnDestroy(r2);
- }
-
- for (i2 = n - 1; i2 > i; i2--) {
- r2 = sraRgnCreateRgn(tmp_reg[i2]);
- if (sraRgnAnd(r2, r1)) {
- int dx, dy;
- int dx2, dy2;
-
- idx2 = tmp_stack[i2];
- /* XXX Y */
- if (idx2 < 0 || cache_list[idx2].bs_x < 0 || cache_list[idx2].bs_time == 0.0) {
- continue;
- }
-
- x0 = cache_list[idx].x;
- y0 = cache_list[idx].y;
- w0 = cache_list[idx].width;
- h0 = cache_list[idx].height;
-
- x1 = cache_list[idx].su_x;
- y1 = cache_list[idx].su_y;
- w1 = cache_list[idx].su_w;
- h1 = cache_list[idx].su_h;
-
- x2 = cache_list[idx2].x;
- y2 = cache_list[idx2].y;
- w2 = cache_list[idx2].width;
- h2 = cache_list[idx2].height;
-
- x3 = cache_list[idx2].bs_x;
- y3 = cache_list[idx2].bs_y;
- w3 = cache_list[idx2].bs_w;
- h3 = cache_list[idx2].bs_h;
-
- dx = x1 - x0;
- dy = y1 - y0;
- sraRgnOffset(r2, dx, dy);
-
- dx2 = x3 - x2;
- dy2 = y3 - y2;
- dx = dx - dx2;
- dy = dy - dy2;
- cache_cr(r2, dx, dy, save_delay0, save_delay1, nbatch);
- cnt++;
- }
- sraRgnDestroy(r2);
- }
- if (cnt) {
- cache_list[idx].su_time = dnow();
- }
-if (ncdb) fprintf(stderr, " try_to_synth_su: 0x%lx %d idx=%d cnt=%d\n", win, i, idx, cnt);
- }
-
- r1 = NULL;
- CLEAN_OUT
- return 1;
-}
-
-static double last_vis_unobs_time = 0.0;
-static double last_vis_obs_time = 0.0;
-
-static int saw_desktop_change = 0;
-
-void check_sched(int try_batch, int *did_sched) {
- static double last_root = 0.0;
- static double last_pixmap = 0.0;
- double refresh = 60.0;
- int i, k, valid;
- Window win;
- XWindowAttributes attr;
- double now = dnow();
-
- if (now > last_root + refresh) {
-
-if (ncdb) fprintf(stderr, "\n**** checking cache_list[%d]\n\n", cache_list_num);
- block_stats();
-
- for(k=0; k<cache_list_num; k++) {
- valid = 0;
- win = cache_list[k].win;
- X_LOCK;
- if (win == None) {
- ;
- } else if (cache_list[k].selectinput && cache_list[k].time > now - refresh) {
- valid = 1;
- } else if (valid_window(win, &attr, 1)) {
- STORE(k, win, attr);
- if (! cache_list[k].selectinput) {
- xselectinput(win, win_ev, 0);
- CLEAR(k);
- cache_list[k].selectinput = 1;
- }
- valid = 1;
- } else {
-if (ncdb) fprintf(stderr, "DELETE(%d) %dx%d+%d+%d\n", k, cache_list[k].width, cache_list[k].height, cache_list[k].x, cache_list[k].y);
- DELETE(k);
- }
- X_UNLOCK;
-/* XXX Y */
- if (valid) {
- if (cache_list[k].create_cnt && cache_list[k].map_state != IsViewable && cache_list[k].map_cnt == 0) {
- if (cache_list[k].bs_x >= 0) {
-if (ncdb) fprintf(stderr, "Created window never mapped: freeing(%d) 0x%lx\n", k, win);
- free_rect(k);
- }
- }
- }
- }
- last_root = dnow();
- }
-
- if (now > last_sched_bs + 0.30) {
- static double last_sched_vis = 0.0;
- int nr = 0, *bat = NULL;
-
- if (try_batch) {
- bat = &nr;
- }
- if (now < last_wireframe + 2.0) {
- for (i=0; i < NSCHED; i++) {
- sched_bs[i] = None;
- }
- }
- if (now < last_get_wm_frame_time + 1.0) {
- if (last_get_wm_frame != None) {
- int idx = lookup_win_index(last_get_wm_frame);
- if (idx >= 0) {
- if (cache_list[idx].bs_x < 0) {
- int x = cache_list[idx].x;
- int y = cache_list[idx].y;
- int w = cache_list[idx].width;
- int h = cache_list[idx].height;
- if (find_rect(idx, x, y, w, h)) {
- SCHED(last_get_wm_frame, 1);
- }
- }
- }
- }
- }
-
- for (i=0; i < NSCHED; i++) {
- if (sched_bs[i] != None) {
- int idx;
- win = sched_bs[i];
- if (now < sched_tm[i] + 0.55) {
- continue;
- }
- if (n_MN || n_UN || n_ST || n_DC) {
- sched_tm[i] = now;
- continue;
- }
- idx = lookup_win_index(win);
- if (idx >= 0) {
- int aw = cache_list[idx].width;
- int ah = cache_list[idx].height;
- if (cache_list[idx].map_state != IsViewable) {
- ;
- } else if (cache_list[idx].vis_state != VisibilityUnobscured) {
- ;
- } else if (aw * ah < 64 * 64) {
- ;
- } else {
-if (ncdb) fprintf(stderr, "*SNAP BS_save: 0x%lx %d %d %d\n", win, aw, ah, cache_list[idx].map_state);
- valid = 0;
- bs_save(idx, bat, &attr, 1, 0, &valid, 0);
- if (valid) {
- STORE(idx, win, attr);
- } else {
- DELETE(idx);
- }
- }
- } else {
-if (ncdb) fprintf(stderr, "*SCHED LOOKUP FAIL: i=%d 0x%lx\n", i, win);
- }
- }
- sched_bs[i] = None;
- }
- *did_sched = 1;
-
- if (n_MN || n_UN || n_ST || n_DC) {
- if (last_sched_vis < now) {
- last_sched_vis += 1.0;
- }
- } else if (now > last_sched_vis + 3.0 && now > last_wireframe + 2.0) {
- static double last_vis = 0.0;
- int vis_now[32], top_now[32];
- static int vis_prev[32], freq = 0;
- int diff, nv = 32, vis_now_n = 0;
- Window win;
-
- freq++;
-
- for (i=0; i < cache_list_num; i++) {
- int ok = 0;
- int top_only = 1;
- int aw = cache_list[i].width;
- int ah = cache_list[i].height;
- int map_prev = cache_list[i].map_state;
-
- win = cache_list[i].win;
-
- if (saw_desktop_change) {
- top_only = 0;
- }
-
- if (win == None) {
- continue;
- }
- /* XXX Y resp */
- if (saw_desktop_change || freq % 5 == 0) {
- int vret = 0;
- X_LOCK;
- vret = valid_window(win, &attr, 1);
- X_UNLOCK;
- if (!vret) {
- continue;
- }
- STORE(i, win, attr);
- }
- if (!cache_list[i].valid) {
- continue;
- }
- if (cache_list[i].map_state != IsViewable) {
- continue;
- }
- if (cache_list[i].vis_state == VisibilityFullyObscured) {
- continue;
- }
- if (map_prev != IsViewable) {
- /* we hope to catch it below in the normal event processing */
- continue;
- }
- if (aw * ah < 64 * 64) {
- continue;
- }
- if (top_only) {
- if (cache_list[i].vis_state == VisibilityUnobscured) {
- ok = 1;
- } else if (!clipped(i)) {
- ok = 1;
- }
- } else {
- ok = 1;
- }
- if (ok) {
- if (vis_now_n < nv) {
- vis_now[vis_now_n] = i;
- top_now[vis_now_n++] = top_only;
- }
- }
- }
- diff = 0;
- for (k = 0; k < vis_now_n; k++) {
- if (vis_now[k] != vis_prev[k]) {
- diff = 1;
- }
- }
- if (diff == 0) {
- if (now > last_vis + 45.0) {
- diff = 1;
- }
- }
- if (diff) {
-if (ncdb && vis_now_n) fprintf(stderr, "*VIS snapshot all %.4f\n", dnowx());
- for (k = 0; k < vis_now_n; k++) {
- i = vis_now[k];
- win = cache_list[i].win;
- valid = 0;
-if (ncdb) fprintf(stderr, "*VIS BS_save: 0x%lx %d %d %d\n", win, cache_list[i].width, cache_list[i].height, cache_list[i].map_state);
- if (now < cache_list[i].vis_unobs_time + 0.75 && now < cache_list[i].vis_obs_time + 0.75) {
- continue;
- }
- bs_save(i, bat, &attr, !top_now[k], 0, &valid, 1);
- if (valid) {
- STORE(i, win, attr);
- } else {
- DELETE(i);
- }
- vis_prev[k] = vis_now[k];
- }
- last_vis = dnow();
- }
- last_sched_vis = dnow();
- if (! n_DC) {
- saw_desktop_change = 0;
- }
- /* XXX Y */
- try_to_synthesize_su(0, 0, bat);
- }
-
- if (nr) {
- batch_push(nr, -1.0);
- }
- last_sched_bs = dnow();
- }
-#if !NO_X11
- if (dpy && atom_XROOTPMAP_ID == None && now > last_pixmap + 5.0) {
- atom_XROOTPMAP_ID = XInternAtom(dpy, "_XROOTPMAP_ID", True);
- last_pixmap = now;
- }
-#endif
- if (got_XROOTPMAP_ID > 0.0) {
-if (ncdb) fprintf(stderr, "got_XROOTPMAP_ID\n");
- if (ncache_xrootpmap) {
- set_ncache_xrootpmap();
- }
- got_XROOTPMAP_ID = 0.0;
- }
-}
-
-int check_ncache(int reset, int mode) {
- static int first = 1;
- static int last_client_count = -1;
- int i, k, n;
- int did_sched = 0;
-
- Window win, win2;
- XWindowAttributes attr;
- int valid;
- int try_batch = 1; /* XXX Y */
- int use_batch = 0;
- int nreg = 0, *nbatch;
- int create_cnt;
- int su_fix_cnt;
- int pixels = 0, ttot;
- int desktop_change = 0, n1, n2;
- int desktop_change_old_wm = 0;
- int missed_su_restore = 0;
- int missed_bs_restore = 0;
- sraRegionPtr r0, r;
- sraRegionPtr missed_su_restore_rgn;
- sraRegionPtr missed_bs_restore_rgn;
- sraRegionPtr unmapped_rgn;
-
- int nrects = 0;
- int nsave, nxsel;
- double now;
-
- int skipwins_n = 0;
- int skipwins_max = 256;
- Window skipwins[256];
-
- static char *dt_guess = NULL;
- static double dt_last = 0.0;
- int dt_gnome = 0, gnome_animation = 0;
- int dt_kde = 0;
-
- if (unixpw_in_progress) return -1;
-
-#ifdef MACOSX
- if (! macosx_console) {
- RAWFB_RET(-1)
- }
- if (! screen) {
- return -1;
- }
-#else
- RAWFB_RET(-1)
- if (! screen || ! dpy) {
- return -1;
- }
-#endif
-
- now = dnow();
-
-#ifdef NO_NCACHE
- ncache = 0;
-#endif
-
- if (reset && (first || cache_list_len == 0)) {
- return -1;
- }
- if (use_threads) {
- try_batch = 0;
- }
-
- if (ncache0) {
- if (reset) {
- ;
- } else if (!client_count || !ncache || nofb) {
- static double last_purge = 0.0;
- double delay = client_count ? 0.5 : 2.0;
- if (now > last_purge + delay) {
- int c = 0;
- XEvent ev;
- X_LOCK;
- while (xcheckmaskevent(dpy, all_ev, &ev)) {
- c++;
- }
- X_UNLOCK;
- last_purge = dnow();
-if (ncdb && c) fprintf(stderr, "check_ncache purged %d events\n", c);
- }
- if (!client_count && last_client_count >= 0 &&
- client_count != last_client_count) {
- /* this should use less RAM when no clients */
- do_new_fb(1);
- }
- last_client_count = client_count;
- return -1;
- }
- }
- last_client_count = client_count;
-
- if (ncache && ! ncache0) {
- ncache0 = ncache;
- }
-
- if (! ncache || ! ncache0) {
- return -1;
- }
- if (subwin) {
- return -1;
- }
- if (nofb) {
- return -1;
- }
- if (now < last_client + 4) {
- return -1;
- }
- if (! all_clients_initialized()) {
- /* play it safe */
- return -1;
- }
-
-
-
- if (reset) {
- rfbLog("check_ncache: resetting cache: %d/%d %d %d\n", cache_list_num, cache_list_len, ncache, first);
- for (i=0; i < cache_list_num; i++) {
- free_rect(i);
- }
- for (n = 1; n <= ncache; n++) {
- if (rect_reg[n] != NULL) {
- sraRgnDestroy(rect_reg[n]);
- rect_reg[n] = NULL;
- }
- }
- zero_fb(0, dpy_y, dpy_x, (ncache+1)*dpy_y);
- mark_rect_as_modified(0, dpy_y, dpy_x, (ncache+1)*dpy_y, 0);
-
- if (ncache_xrootpmap) {
- set_ncache_xrootpmap();
- }
-
- snap_old();
- return -1;
- }
-
- if (first) {
- int dx = 10, dy = 24, ds = 0;
- int Dx = dpy_x, Dy = dpy_y;
- first = 0;
- for (i=0; i < NRECENT; i++) {
- recent[i] = None;
- }
- for (i=0; i < NSCHED; i++) {
- sched_bs[i] = None;
- }
- rlast = 0;
-
- X_LOCK;
- /* event leak with client_count == 0 */
- xselectinput_rootwin |= SubstructureNotifyMask;
- XSelectInput_wr(dpy, rootwin, xselectinput_rootwin);
- X_UNLOCK;
-
- if (scaling) {
- Dx = scaled_x;
- Dy = scaled_y;
- }
- if (!rotating_same) {
- int t = Dx;
- Dx = Dy;
- Dy = t;
- }
-
- for (i = 0; i < 3; i++) {
- rfbDrawString(screen, &default8x16Font, dx, ds + Dy+1*dy,
- "This is the Pixel buffer cache region. Your VNC Viewer is not hiding it from you.",
- white_pixel());
- rfbDrawString(screen, &default8x16Font, dx, ds + Dy+2*dy,
- "Try resizing your VNC Viewer so you don't see it!!",
- white_pixel());
- rfbDrawString(screen, &default8x16Font, dx, ds + Dy+3*dy,
- "Pay no attention to the man behind the curtain...",
- white_pixel());
- rfbDrawString(screen, &default8x16Font, dx, ds + Dy+4*dy,
- "To disable caching run the server with: x11vnc -noncache ...",
- white_pixel());
- rfbDrawString(screen, &default8x16Font, dx, ds + Dy+5*dy,
- "If there are painting errors press 3 Alt_L's (Left \"Alt\" key) in a row to repaint the screen.",
- white_pixel());
- rfbDrawString(screen, &default8x16Font, dx, ds + Dy+6*dy,
- "More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching",
- white_pixel());
-
- ds += 11 * dy;
- }
-
- snapshot_cache_list(0, 100.0);
- for (i=0; i < cache_list_num; i++) {
- CLEAR(i);
- }
- for (n = 1; n <= ncache; n++) {
- rect_reg[n] = NULL;
- }
-
- if (ncache_xrootpmap) {
- set_ncache_xrootpmap();
- }
-
- snap_old();
- }
-
- check_zero_rects();
-
-if (hack_val == 2) {
- block_stats();
- hack_val = 1;
-}
-#ifdef MACOSX
- if (macosx_console) {
- static double last_all_windows = 0.0;
- if (! macosx_checkevent(NULL)) {
- if (now > last_all_windows + 0.05) {
- macosxCGS_get_all_windows();
- last_all_windows = dnow();
- }
- }
- /* XXX Y */
- rootwin = -1;
- }
-#endif
-
- n = 0;
- ttot = 0;
-
- if (dt_guess == NULL || now > dt_last + 60) {
- static char *dt_prev = NULL;
- dt_prev = dt_guess;
- dt_guess = strdup(guess_desktop());
- if (ncache_xrootpmap && dt_prev && dt_guess) {
- if (strcmp(dt_prev, dt_guess)) {
- set_ncache_xrootpmap();
- }
- }
- dt_last = now;
- if (dt_prev) {
- free(dt_prev);
- }
- }
- if (dt_guess && !strcmp(dt_guess, "gnome")) {
- dt_gnome = 1;
- } else if (dt_guess && !strcmp(dt_guess, "kde")) {
- dt_kde = 1;
- }
- if (dt_kde) {
- kde_no_animate(0);
- }
-
- ev_store(None, EV_RESET);
-
- X_LOCK;
- for (k = 1; k <= 3; k++) {
- int j, retry = 0;
-
- if (retry) {}
-
- nsave = n;
-
- if (k > 1 && ncdb) fprintf(stderr, "read_events-%d\n", k);
- read_events(&n);
-
-#if 0
- if (dt_gnome && (n_MN || n_UN)) {
- retry = 1;
- } else if (ncache_old_wm && n_ON_po >= 2) {
- retry = 1;
- } else if (n > nsave) {
- /* XXX Y */
- retry = 1;
- }
-
- if (retry) {
- int n0 = n;
- usleep(25 * 1000);
- XFlush_wr(dpy);
- read_events(&n);
- if (ncdb) fprintf(stderr, "read_events retry: %d -> %d\n", n0, n);
- }
-#endif
-
- if (n > nsave) {
- int n0 = n;
-
- for (j=0; j<4; j++) {
- if (j < 2) {
- usleep(30 * 1000);
- } else {
- usleep(10 * 1000);
- }
- XFlush_wr(dpy);
- read_events(&n);
- if (ncdb) fprintf(stderr, "read_events retry: %d -> %d\n", n0, n);
- if (n == n0) {
- break;
- }
- n0 = n;
- }
- }
-
- nxsel = 0;
-
- /* handle creates and reparenting: */
- for (n1 = nsave; n1 < n; n1++) {
- Window win2;
- int idx;
- XEvent ev = Ev[n1];
- win = Ev_win[n1];
- if (ev.type == CreateNotify) {
- win2 = ev.xcreatewindow.window;
- if (ev_lookup(win2, EV_REPARENT) || ev_lookup(win2, EV_DESTROY)) {
- if (skipwins_n < skipwins_max) {
-if (ncdb) fprintf(stderr, "SKIPWINS: CreateNotify: 0x%lx %d\n", win2, n1);
- skipwins[skipwins_n++] = win2;
- }
- } else {
- idx = lookup_win_index(win);
- if (idx < 0) {
- idx = lookup_free_index();
- if (idx < 0) {
- continue;
- }
- CLEAR(idx);
- }
-if (ncdb) fprintf(stderr, "PRELOOP: CreateNotify: 0x%lx %d valid_window\n", win2, n1);
- if (valid_window(win2, &attr, 1)) {
- STORE(idx, win2, attr);
- CLEAR(idx);
- cache_list[idx].selectinput = 1;
- cache_list[idx].create_cnt = 1;
-if (ncdb) fprintf(stderr, "PRELOOP: CreateNotify: 0x%lx %d xselectinput\n", win2, n1);
- xselectinput(win2, win_ev, 1);
- nxsel++;
- } else {
- DELETE(idx);
- }
- nxsel++;
- }
- } else if (ev.type == ReparentNotify) {
- if (ev.xreparent.parent != rootwin) {
- win2 = ev.xreparent.window;
- if (win2 != rootwin) {
- idx = lookup_win_index(win2);
-if (ncdb) fprintf(stderr, "PRELOOP: RepartNotify: 0x%lx %d idx=%d\n", win2, n1, idx);
- if (idx >= 0) {
- DELETE(idx);
- }
- if (! ev_lookup(win2, EV_CREATE)) {
- xselectinput(win2, 0, 1);
- nxsel++;
- }
- }
- }
- }
- }
- if (nxsel == 0) {
- break;
- }
- }
-
- X_UNLOCK;
-
- if (got_NET_CURRENT_DESKTOP > 0.0) {
- if (dnow() < got_NET_CURRENT_DESKTOP + 0.25) {
- if (ncdb) fprintf(stderr, "***got_NET_CURRENT_DESKTOP n=%d\n", n);
- desktop_change = 1;
- n_DC++;
- } else {
- if (ncdb) fprintf(stderr, "***got_NET_CURRENT_DESKTOP n=%d STALE\n", n);
- }
- got_NET_CURRENT_DESKTOP = 0.0;
- }
-
- if (n == 0) {
- check_sched(try_batch, &did_sched);
- return 0;
- }
-if (ncdb) fprintf(stderr, "\n"); if (ncdb) rfbLog("IN check_ncache() %d events. %.4f\n", n, now - x11vnc_start);
-
- if (try_batch) {
- use_batch = 1;
- }
-
- if (rotating) {
- use_batch = 0;
- }
- if (cursor_noshape_updates_clients(screen)) {
- use_batch = 0;
- }
-
- if (! use_batch) {
- nbatch = NULL;
- } else {
- nreg = 0;
- nbatch = &nreg;
- }
-
- /* XXX Y */
- for (n1 = 0; n1 < n; n1++) {
- Window twin = Ev_map[n1];
- if (twin == None || twin == rootwin) {
- continue;
- }
- for (n2 = 0; n2 < n; n2++) {
- if (Ev_unmap[n2] == twin) {
- if (skipwins_n < skipwins_max) {
-if (ncdb) fprintf(stderr, "SKIPWINS: Ev_unmap/map: 0x%lx %d\n", twin, n2);
- skipwins[skipwins_n++] = twin;
- break;
- }
- }
- }
- }
-
- if (!desktop_change) {
- if (skipwins_n) {
- if (n_MN + n_UN >= 2 + 2*skipwins_n) {
- desktop_change = 1;
- n_DC++;
- }
- } else {
- if (n_MN + n_UN >= 3) {
- desktop_change = 1;
- n_DC++;
- }
- }
- }
- if (ncache_old_wm) {
- int shifts = 0;
- for (i=0; i < n; i++) {
- XEvent ev;
- int type, idx = -1;
- int ik = Ev_order[i];
- int x_new, y_new, w_new, h_new;
- int x_old, y_old, w_old, h_old;
- int old_wm = 0;
-
- if (Ev_done[ik]) continue;
- win = Ev_win[ik];
-
- ev = Ev[ik];
- type = ev.type;
- if (type != ConfigureNotify) {
- continue;
- }
- if (ev_lookup(win, EV_MAP)) {
- continue;
- } else if (ev_lookup(win, EV_UNMAP)) {
- continue;
- } else if (ev_lookup(win, EV_DESTROY)) {
- continue;
- }
-
- idx = lookup_win_index(win);
- if (idx < 0) {
- continue;
- }
- x_new = ev.xconfigure.x;
- y_new = ev.xconfigure.y;
- w_new = ev.xconfigure.width;
- h_new = ev.xconfigure.height;
-
- x_old = cache_list[idx].x;
- y_old = cache_list[idx].y;
- w_old = cache_list[idx].width;
- h_old = cache_list[idx].height;
-
- if (w_new == w_old && h_new == h_old) {
- if (nabs(x_new - x_old) >= dpy_x || nabs(y_new - y_old) >= dpy_y) {
- sraRegionPtr r_old, r_new, r0;
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- r_old = sraRgnCreateRect(x_old, y_old, x_old+w_old, y_old+h_old);
- sraRgnAnd(r_old, r0);
- r_new = sraRgnCreateRect(x_new, y_new, x_new+w_new, y_new+h_new);
- sraRgnAnd(r_new, r0);
- if (cache_list[idx].map_state != IsViewable) {
- ev_store(win, EV_OLD_WM_NOTMAPPED);
- } else if (sraRgnEmpty(r_old) && !sraRgnEmpty(r_new)) {
- old_wm = 1;
- ev_store(win, EV_OLD_WM_MAP);
- Ev_map[i] = win;
- } else if (!sraRgnEmpty(r_old) && sraRgnEmpty(r_new)) {
- ev_store(win, EV_OLD_WM_UNMAP);
- old_wm = -1;
- Ev_unmap[i] = win;
- } else {
- ev_store(win, EV_OLD_WM_OFF);
- }
- sraRgnDestroy(r_old);
- sraRgnDestroy(r_new);
- sraRgnDestroy(r0);
- shifts++;
-if (ncdb) fprintf(stderr, "old_wm[%d] +%04d+%04d +%04d+%04d old_wm: %d\n", i, x_old, y_old, x_new, y_new, old_wm);
- }
- }
- }
- if (shifts >= 3) {
-if (ncdb) fprintf(stderr, "DESKTOP_CHANGE_OLD_WM: %d\n", shifts);
- desktop_change = 1;
- desktop_change_old_wm = 1;
- }
- }
-
-#define SKIPUMS \
- ok = 1; \
- if (twin == None || twin == rootwin) { \
- continue; \
- } \
- for (ns = 0; ns < skipwins_n; ns++) { \
- if (skipwins[ns] == twin) { \
- ok = 0; \
- break; \
- } \
- }
-
- if (desktop_change) {
- Window twin;
- int ok, s, k, add, cnt, ns;
-
- cnt = 0;
- add = 0;
- for (i=0; i < n; i++) {
- twin = Ev_unmap[i];
- SKIPUMS
- if (ok) {
-if (ncdb) fprintf(stderr, "U Ev_tmp[%d] = %d\n", cnt, i);
- Ev_tmp[cnt++] = i;
- }
- }
- for (i=0; i < n; i++) {
- twin = Ev_map[i];
- SKIPUMS
- if (ok) {
-if (ncdb) fprintf(stderr, "M Ev_tmp[%d] = %d\n", cnt, i);
- Ev_tmp[cnt++] = i;
- }
- }
- for (k = 0; k < cnt; k++) {
- Ev_tmp2[k] = -1;
- }
- /* unmap from top to bottom */
- for (s = old_stack_n - 1; s >= 0; s--) {
- twin = old_stack[s];
- if (twin == None || twin == rootwin) {
- continue;
- }
- for (k = 0; k < cnt; k++) {
- i = Ev_tmp[k];
- if (twin == Ev_unmap[i]) {
-if (ncdb) fprintf(stderr, "U Ev_tmp2[%d] = %d\n", add, i);
- Ev_tmp2[add++] = i;
- break;
- }
- }
- }
- /* map from bottom to top */
- for (s = 0; s < old_stack_n; s++) {
- twin = old_stack[s];
- if (twin == None || twin == rootwin) {
- continue;
- }
- for (k = 0; k < cnt; k++) {
- i = Ev_tmp[k];
- if (twin == Ev_map[i]) {
-if (ncdb) fprintf(stderr, "M Ev_tmp2[%d] = %d\n", add, i);
- Ev_tmp2[add++] = i;
- break;
- }
- }
- }
- k = 0;
- for (i=0; i < n; i++) {
- Window wu, wm;
- int j;
- int oku = 0, okm = 0;
- wu = Ev_unmap[i];
- wm = Ev_map[i];
- ok = 0;
- if (wu != None && wu != rootwin) oku = 1;
- if (wm != None && wm != rootwin) okm = 1;
- if (!oku && !okm) {
- continue;
- }
- if (oku) {
- twin = wu;
- SKIPUMS
- if (!ok) {
- oku = 0;
- }
- }
- if (okm) {
- twin = wm;
- SKIPUMS
- if (!ok) {
- okm = 0;
- }
- }
- if (!oku && !okm) {
- continue;
- }
- j = Ev_tmp2[k++];
- if (j >= 0) {
-if (ncdb) fprintf(stderr, "UM Ev_order[%d] = %d oku=%d okm=%d\n", i, j, oku, okm);
- Ev_order[i] = j;
- }
- }
- }
-
-#if 0
- if (desktop_change) {
- Window twin;
- int ok, s, k, add, cnt, ns;
-
- cnt = 0;
- add = 0;
- for (i=0; i < n; i++) {
- twin = Ev_unmap[i];
- SKIPUMS
- if (ok) {
- Ev_tmp[cnt++] = i;
- }
- }
- for (k = 0; k < cnt; k++) {
- Ev_tmp2[k] = -1;
- }
- /* unmap from top to bottom */
- for (s = old_stack_n - 1; s >= 0; s--) {
- twin = old_stack[s];
- for (k = 0; k < cnt; k++) {
- i = Ev_tmp[k];
- if (twin == Ev_unmap[i]) {
- Ev_tmp2[add++] = i;
- break;
- }
- }
- }
- k = 0;
- for (i=0; i < n; i++) {
- int j;
- twin = Ev_unmap[i];
- SKIPUMS
- if (ok) {
- j = Ev_tmp2[k++];
- if (j >= 0) {
- Ev_order[i] = j;
- }
- }
- }
-
- cnt = 0;
- add = 0;
- for (i=0; i < n; i++) {
- twin = Ev_map[i];
- SKIPUMS
- if (ok) {
- Ev_tmp[cnt++] = i;
- }
- }
- for (k = 0; k < cnt; k++) {
- Ev_tmp2[k] = -1;
- }
- /* map from bottom to top */
- for (s = 0; s < old_stack_n; s++) {
- twin = old_stack[s];
- for (k = 0; k < cnt; k++) {
- i = Ev_tmp[k];
- if (twin == Ev_map[i]) {
- Ev_tmp2[add++] = i;
- break;
- }
- }
- }
- k = 0;
- for (i=0; i < n; i++) {
- int j;
- twin = Ev_map[i];
- SKIPUMS
- if (ok) {
- j = Ev_tmp2[k++];
- if (j >= 0) {
- Ev_order[i] = j;
- }
- }
- }
- }
-#endif
-
- if (!desktop_change && (n_VN_p && !n_UN && (n_MN || n_ON_st))) {
- if (now < last_vis_unobs_time + 0.75 || now < last_vis_obs_time + 0.75) {
- ;
- } else if (n_MN <= 2 && n_ON_st <= 1) {
- for (i=0; i < n; i++) {
- XEvent ev;
- int type, idx = -1, state, valid;
- int ik = Ev_order[i];
-
- if (Ev_done[ik]) continue;
- win = Ev_win[ik];
-
- ev = Ev[ik];
- type = ev.type;
- if (type != VisibilityNotify) {
- continue;
- }
-
- state = ev.xvisibility.state;
- if (state == VisibilityUnobscured) {
- continue;
- }
- if (ev_lookup(win, EV_MAP)) {
- continue;
- } else if (ev_lookup(win, EV_UNMAP)) {
- continue;
- } else if (ev_lookup(win, EV_DESTROY)) {
- continue;
- }
- idx = lookup_win_index(win);
-
- if (idx < 0) {
- continue;
- }
- if (cache_list[idx].vis_state == VisibilityFullyObscured) {
- continue;
- }
- if (now < cache_list[idx].vis_unobs_time + 3.00 || now < cache_list[idx].vis_obs_time + 3.00) {
- continue;
- }
-
-if (ncdb) fprintf(stderr, "----%02d: VisibilityNotify 0x%lx %3d (*PRELOOP*) state: %s U/P %d/%d\n", ik, win, idx, VState(state), n_VN_u, n_VN_p);
- valid = 0;
- bs_save(idx, nbatch, &attr, 1, 0, &valid, 1);
- if (valid) {
- STORE(idx, win, attr);
- } else {
- DELETE(idx);
- }
-
- cache_list[idx].vis_state = state;
- cache_list[idx].vis_obs_time = last_vis_obs_time = dnow();
- Ev_done[ik] = 1;
- }
- }
- }
- if (desktop_change) {
- if (ncache_dt_change) {
- if (ncdb) fprintf(stderr, "GUESSED DESKTOP CHANGE.\n");
- saw_desktop_change = 1;
- } else {
- if (ncdb) fprintf(stderr, "GUESSED DESKTOP CHANGE. Skipping.\n");
- desktop_change = 0;
- }
- }
-
-
- create_cnt = 0;
- missed_su_restore = 0;
- missed_bs_restore = 0;
- missed_su_restore_rgn = sraRgnCreate();
- missed_bs_restore_rgn = sraRgnCreate();
- r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- unmapped_rgn = sraRgnCreate();
- su_fix_cnt = 0;
-
-for (k = 0; k < skipwins_n; k++) {
- if (ncdb) fprintf(stderr, "skipwins[%d] 0x%lx\n", k, skipwins[k]);
-}
-
- X_LOCK;
- for (i=0; i < n; i++) {
- XEvent ev;
- int ns, skip = 0, type, idx = -1;
- int ik = Ev_order[i];
-
- if (Ev_done[ik]) continue;
- win = Ev_win[ik];
-
- ev = Ev[ik];
- type = ev.type;
- Ev_done[ik] = 1;
-
- win2 = win;
- if (win == rootwin) {
- if (type == CreateNotify) {
- win2 = ev.xcreatewindow.window;
- } else if (type == ReparentNotify) {
- win2 = ev.xreparent.window;
- }
- }
- for (ns = 0; ns < skipwins_n; ns++) {
- if (win2 == skipwins[ns]) {
- skip = 1;
- break;
- }
- }
- if (skip) {
-if (ncdb) fprintf(stderr, "skip%02d: ** SpecialSkip 0x%lx/0x%lx type: %s\n", ik, win, win2, Etype(type));
- continue;
- }
-
- if (win == rootwin) {
- if (type == CreateNotify) {
- int x=0, y=0, w=0, h=0;
- valid = 0;
- win2 = ev.xcreatewindow.window;
- idx = lookup_win_index(win2);
- if (idx < 0) {
- continue;
- }
- if (cache_list[idx].valid) {
- valid = 1;
- x=cache_list[idx].x;
- y=cache_list[idx].y;
- w=cache_list[idx].width;
- h=cache_list[idx].height;
- if (w*h > 64 * 64 && ev_lookup(win2, EV_MAP)) {
- X_UNLOCK;
- valid = 1;
- su_save(idx, nbatch, &attr, 0, &valid, 1);
- STORE(idx, win2, attr);
-
- X_LOCK;
-
- if (! desktop_change) {
- SCHED(win2, 1)
- }
- create_cnt++;
- }
- }
-if (ncdb) fprintf(stderr, "root%02d: ** CreateNotify 0x%lx %3d -- %dx%d+%d+%d valid=%d\n", ik, win2, idx, w, h, x, y, valid);
-
- } else if (type == ReparentNotify) {
- if (ev.xreparent.parent != rootwin) {
- win2 = ev.xreparent.window;
- idx = lookup_win_index(win2);
-if (ncdb) fprintf(stderr, "root%02d: ReparentNotifyRM 0x%lx %3d\n", ik, win2, idx);
- }
- } else {
-if (ncdb) fprintf(stderr, "root%02d: ** IgnoringRoot 0x%lx type: %s\n", ik, win, Etype(type));
- }
- } else {
- if (type == ConfigureNotify) {
- int x_new, y_new, w_new, h_new;
- int x_old, y_old, w_old, h_old;
- int stack_change, old_wm = 0;
- Window oabove = None;
-
- idx = lookup_win_index(win);
-
- if (idx >= 0) {
- oabove = cache_list[idx].above;
- }
-
-if (ncdb) fprintf(stderr, "----%02d: ConfigureNotify 0x%lx %3d -- above: 0x%lx -> 0x%lx %dx%d+%d+%d\n", ik, win, idx,
- oabove, ev.xconfigure.above, ev.xconfigure.width, ev.xconfigure.height, ev.xconfigure.x, ev.xconfigure.y);
-
- if (idx < 0) {
- continue;
- }
-
- x_new = ev.xconfigure.x;
- y_new = ev.xconfigure.y;
- w_new = ev.xconfigure.width;
- h_new = ev.xconfigure.height;
-
- x_old = cache_list[idx].x;
- y_old = cache_list[idx].y;
- w_old = cache_list[idx].width;
- h_old = cache_list[idx].height;
-
- if (desktop_change_old_wm) {
- if (ev_lookup(win, EV_OLD_WM_MAP)) {
- if (Ev_map[ik] == win) {
- old_wm = 1;
- } else {
- old_wm = 2;
- }
- } else if (ev_lookup(win, EV_OLD_WM_UNMAP)) {
- if (Ev_unmap[ik] == win) {
- old_wm = -1;
- } else {
- old_wm = 2;
- }
- } else if (ev_lookup(win, EV_OLD_WM_OFF)) {
- old_wm = 2;
- } else if (ev_lookup(win, EV_OLD_WM_NOTMAPPED)) {
- old_wm = 3;
- }
- }
-
- if (!old_wm) {
- if (x_old != x_new || y_old != y_new) {
- /* invalidate su */
- cache_list[idx].su_time = 0.0;
-if (ncdb) fprintf(stderr, " INVALIDATE su: 0x%lx xy: +%d+%d +%d+%d \n", win, x_old, y_old, x_new, y_new);
- }
- if (w_old != w_new || h_old != h_new) {
- /* invalidate bs */
- cache_list[idx].bs_time = 0.0;
-if (ncdb) fprintf(stderr, " INVALIDATE bs: 0x%lx wh: %dx%d %dx%d \n", win, w_old, h_old, w_new, h_new);
- }
- } else {
- int valid;
- X_UNLOCK;
- if (old_wm == 1) {
- /* XXX Y */
-if (ncdb) fprintf(stderr, " OLD_WM_MAP: 0x%lx wh: %dx%d+%d+%d %dx%d+%d+%d \n", win, w_old, h_old, x_old, y_old, w_new, h_new, x_new, y_new);
- valid = 0;
- bs_restore(idx, nbatch, NULL, &attr, 0, 0, &valid, 1);
-
- } else if (old_wm == -1) {
-if (ncdb) fprintf(stderr, " OLD_WM_UNMAP: 0x%lx wh: %dx%d+%d+%d %dx%d+%d+%d \n", win, w_old, h_old, x_old, y_old, w_new, h_new, x_new, y_new);
- valid = 1;
- su_restore(idx, nbatch, NULL, &attr, 1, 0, &valid, 1);
- } else {
-if (ncdb) fprintf(stderr, " OLD_WM_OFF:: 0x%lx wh: %dx%d+%d+%d %dx%d+%d+%d old_wm=%d\n", win, w_old, h_old, x_old, y_old, w_new, h_new, x_new, y_new, old_wm);
- }
- X_LOCK;
- }
-
- stack_change = 0;
- if (old_wm) {
- ;
- } else if (cache_list[idx].above != ev.xconfigure.above) {
- stack_change = 1;
- } else if (x_new == x_old && y_new == y_old && w_new == w_old && h_new == h_old) {
- stack_change = 1;
- }
- if (stack_change) {
- int i2, ok = 1;
- for (i2=0; i2 < n; i2++) {
- if (Ev_map[i2] == win) {
- ok = 0;
- break;
- }
- }
- if (ok) {
- if (n_MN == 0 && n_UN == 0) {
- if (su_fix_cnt > 0) {
- ok = 0;
-if (ncdb) fprintf(stderr, " CONF_IGNORE: Too many stacking changes: 0x%lx\n", win);
- }
- }
-
- }
- if (ok) {
- if (ev_lookup(ev.xconfigure.above, EV_UNMAP)) {
- if (ncdb) fprintf(stderr, " skip try_to_fix_su for GNOME deiconify #1\n");
- if (dt_gnome) {
- gnome_animation = 1;
- }
- ok = 0;
- }
- }
- if (ok && dt_gnome) {
- if (valid_window(ev.xconfigure.above, &attr, 1)) {
- if (attr.map_state != IsViewable) {
- if (ncdb) fprintf(stderr, " skip try_to_fix_su for GNOME deiconify #2\n");
- gnome_animation = 1;
- ok = 0;
- }
- }
- }
- if (ok) {
- int rc = try_to_fix_su(win, idx, ev.xconfigure.above, nbatch, NULL);
- if (rc == 0 && su_fix_cnt == 0 && n_MN == 0 && n_UN == 0) {
- X_UNLOCK;
- try_to_synthesize_su(1, 1, nbatch);
- X_LOCK;
- }
- n_ST++;
- su_fix_cnt++;
- }
- }
-
- cache_list[idx].x = x_new;
- cache_list[idx].y = y_new;
- cache_list[idx].width = w_new;
- cache_list[idx].height = h_new;
-
- cache_list[idx].above = ev.xconfigure.above;
- cache_list[idx].time = dnow();
-
- } else if (type == VisibilityNotify) {
- int state = ev.xvisibility.state;
- idx = lookup_win_index(win);
-if (ncdb) fprintf(stderr, "----%02d: VisibilityNotify 0x%lx %3d state: %s U/P %d/%d\n", ik, win, idx, VState(state), n_VN_u, n_VN_p);
-
- if (idx < 0) {
- continue;
- }
- if (desktop_change) {
- ;
- } else if (macosx_console && n_VN_p == 0) {
- ; /* XXXX not working well yet with UnmapNotify ... */
- } else if (state == VisibilityUnobscured) {
- int ok = 1;
- if (ncache <= 2) {
- ok = 0;
- } else if (ev_lookup(win, EV_MAP)) {
- ok = 0;
- } else if (ev_lookup(win, EV_UNMAP)) {
- ok = 0;
- } else if (ev_lookup(win, EV_DESTROY)) {
- ok = 0;
- } else if (gnome_animation) {
- ok = 0;
- } else {
- /* this is for gnome iconify */
- int i2;
- for (i2=i+1; i2 < n; i2++) {
- int idx2, ik2 = Ev_order[i2];
- sraRegionPtr ro1, ro2;
- Window win2 = Ev_unmap[ik2];
-
- if (win2 == None) {
- continue;
- }
- idx2 = lookup_win_index(win2);
- if (idx2 < 0) {
- continue;
- }
-
- ro1 = idx_create_rgn(r0, idx);
- ro2 = idx_create_rgn(r0, idx2);
-
- if (sraRgnAnd(ro1, ro2)) {
- if (ncdb) fprintf(stderr, " skip VisibilityUnobscured for GNOME iconify.\n");
- ok = 0;
- }
- sraRgnDestroy(ro1);
- sraRgnDestroy(ro2);
- if (! ok) {
- break;
- }
- }
- }
- if (ok) {
- int x2, y2, w2, h2;
- sraRegionPtr rmask = NULL;
- valid = 0;
- if (dnow() < cache_list[idx].vis_unobs_time + 3.00 && !sraRgnEmpty(unmapped_rgn)) {
- x2 = cache_list[idx].x;
- y2 = cache_list[idx].y;
- w2 = cache_list[idx].width;
- h2 = cache_list[idx].height;
- rmask = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
- sraRgnAnd(rmask, unmapped_rgn);
- if (sraRgnEmpty(rmask)) {
- sraRgnDestroy(rmask);
- rmask = NULL;
- }
- }
- if (ev_lookup(win, EV_CONFIGURE_SIZE)) {
- valid = valid_window(win, &attr, 1);
- } else {
- X_UNLOCK;
- bs_restore(idx, nbatch, rmask, &attr, 0, 1, &valid, 1);
- X_LOCK;
- }
- if (rmask != NULL) {
- sraRgnDestroy(rmask);
- }
- if (valid) {
- STORE(idx, win, attr);
-
- cache_list[idx].time = dnow();
- cache_list[idx].vis_cnt++;
- Ev_map[ik] = win;
- Ev_rects[nrects].x1 = cache_list[idx].x;
- Ev_rects[nrects].y1 = cache_list[idx].y;
- Ev_rects[nrects].x2 = cache_list[idx].width;
- Ev_rects[nrects].y2 = cache_list[idx].height;
- nrects++;
- SCHED(win, 1)
- } else {
- DELETE(idx);
- }
- }
- }
- if (state == VisibilityUnobscured) {
- cache_list[idx].vis_unobs_time = last_vis_unobs_time = dnow();
- } else if (cache_list[idx].vis_state == VisibilityUnobscured) {
- cache_list[idx].vis_obs_time = last_vis_obs_time = dnow();
- }
- cache_list[idx].vis_state = state;
-
- } else if (type == MapNotify) {
- idx = lookup_win_index(win);
-if (ncdb) fprintf(stderr, "----%02d: MapNotify 0x%lx %3d\n", ik, win, idx);
-
- if (idx < 0) {
- continue;
- }
-
-#if 0
-/*
- if (cache_list[idx].map_state == IsUnmapped || desktop_change || macosx_console)
- */
-#endif
- if (1) {
- X_UNLOCK;
- if (desktop_change) {
- /* XXX Y */
- int save = 1;
- sraRegionPtr r;
- if (cache_list[idx].su_time != 0.0) {
- save = 0;
- } else if (missed_su_restore) {
- r = idx_create_rgn(r0, idx);
- if (sraRgnAnd(r, missed_su_restore_rgn)) {
- save = 0;
- }
- sraRgnDestroy(r);
- }
- if (missed_bs_restore) {
- r = idx_create_rgn(r0, idx);
- if (sraRgnAnd(r, missed_bs_restore_rgn)) {
- save = 0;
- }
- sraRgnDestroy(r);
- }
- if (save) {
- valid = 0;
- su_save(idx, nbatch, &attr, 1, &valid, 1);
- if (valid) {
- STORE(idx, win, attr);
- }
- }
- } else {
- valid = 0;
- su_save(idx, nbatch, &attr, 0, &valid, 1);
- if (valid) {
- STORE(idx, win, attr);
- }
- }
- valid = 0;
- if (ev_lookup(win, EV_CONFIGURE_SIZE)) {
- X_LOCK;
- valid = valid_window(win, &attr, 1);
- X_UNLOCK;
- idx_add_rgn(missed_bs_restore_rgn, r0, idx);
- missed_bs_restore++;
- } else if (bs_restore(idx, nbatch, NULL, &attr, 0, 0, &valid, 1)) { /* XXX clip? */
- ;
- } else {
- idx_add_rgn(missed_bs_restore_rgn, r0, idx);
- missed_bs_restore++;
- }
- if (valid) {
- STORE(idx, win, attr);
- }
-
- if (macosx_console) {
-#ifdef MACOSX
- macosxCGS_follow_animation_win(win, -1, 1);
- if (valid_window(win, &attr, 1)) {
- STORE(idx, win, attr);
- SCHED(win, 1);
- }
- /* XXX Y */
- if (cache_list[idx].vis_state == -1) {
- cache_list[idx].vis_state = VisibilityUnobscured;
- }
-#endif
- }
- X_LOCK;
- pixels += cache_list[idx].width * cache_list[idx].height;
- cache_list[idx].time = dnow();
- cache_list[idx].map_cnt++;
- Ev_map[ik] = win;
- Ev_rects[nrects].x1 = cache_list[idx].x;
- Ev_rects[nrects].y1 = cache_list[idx].y;
- Ev_rects[nrects].x2 = cache_list[idx].width;
- Ev_rects[nrects].y2 = cache_list[idx].height;
- nrects++;
-
- if (! valid) {
- DELETE(idx);
- }
- }
- cache_list[idx].map_state = IsViewable;
-
- } else if (type == UnmapNotify) {
- int x2, y2, w2, h2;
- idx = lookup_win_index(win);
-if (ncdb) fprintf(stderr, "----%02d: UnmapNotify 0x%lx %3d\n", ik, win, idx);
-
- if (idx < 0) {
- continue;
- }
- if (macosx_console) {
- if (mode == 2) {
- cache_list[idx].map_state = IsViewable;
- }
- }
-
-#if 0
-/*
- if (cache_list[idx].map_state == IsViewable || desktop_change || macosx_console)
- */
-#endif
- if (1) {
- X_UNLOCK;
- if (desktop_change) {
- int save = 1;
- sraRegionPtr r;
- if (cache_list[idx].bs_time > 0.0) {
- save = 0;
- } else if (missed_su_restore) {
- r = idx_create_rgn(r0, idx);
- if (sraRgnAnd(r, missed_su_restore_rgn)) {
- save = 0;
- }
- sraRgnDestroy(r);
- }
- if (missed_bs_restore) {
- r = idx_create_rgn(r0, idx);
- if (sraRgnAnd(r, missed_bs_restore_rgn)) {
- save = 0;
- }
- sraRgnDestroy(r);
- }
- if (save) {
- valid = 0;
- bs_save(idx, nbatch, &attr, 1, 0, &valid, 1);
- }
- } else {
- valid = 0;
- bs_save(idx, nbatch, &attr, 1, 0, &valid, 1);
- }
- valid = 0;
- if (su_restore(idx, nbatch, NULL, &attr, 1, 0, &valid, 1)) {
- try_to_fix_su(win, idx, None, nbatch, "unmapped");
- if (valid) {
- STORE(idx, win, attr);
- } else {
- DELETE(idx);
- }
- } else {
- idx_add_rgn(missed_su_restore_rgn, r0, idx);
- missed_su_restore++;
- }
- X_LOCK;
-
- pixels += cache_list[idx].width * cache_list[idx].height;
- cache_list[idx].time = dnow();
- cache_list[idx].unmap_cnt++;
- Ev_unmap[ik] = win;
- Ev_rects[nrects].x1 = cache_list[idx].x;
- Ev_rects[nrects].y1 = cache_list[idx].y;
- Ev_rects[nrects].x2 = cache_list[idx].width;
- Ev_rects[nrects].y2 = cache_list[idx].height;
- nrects++;
- }
-
- x2 = cache_list[idx].x;
- y2 = cache_list[idx].y;
- w2 = cache_list[idx].width;
- h2 = cache_list[idx].height;
- r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
- sraRgnAnd(r, r0);
- sraRgnOr(unmapped_rgn, r);
- sraRgnDestroy(r);
-
- cache_list[idx].map_state = IsUnmapped;
-
- } else if (type == ReparentNotify) {
- if (ev.xreparent.parent != rootwin) {
- win2 = ev.xreparent.window;
- if (win2 != rootwin) {
- idx = lookup_win_index(win2);
-if (ncdb) fprintf(stderr, "----%02d: ReparentNotifyRM 0x%lx %3d\n", ik, win2, idx);
- }
- }
-
- } else if (type == DestroyNotify) {
- win2 = ev.xdestroywindow.window;
- idx = lookup_win_index(win2);
-if (ncdb) fprintf(stderr, "----%02d: DestroyNotify 0x%lx %3d\n", ik, win2, idx);
-
- if (idx >= 0) {
- DELETE(idx);
- }
- } else {
-if (ncdb) fprintf(stderr, "igno%02d: ** Ignoring 0x%lx type: %s\n", ik, win, Etype(type));
- }
-
- }
- }
- X_UNLOCK;
-
- if (use_batch && nreg) {
- batch_push(nreg, -1.0);
- }
- if (nrects) {
- if (scaling) {
- push_borders(Ev_rects, nrects);
- }
- }
-
- check_sched(try_batch, &did_sched);
-
- if (n_CN || n_RN || n_DN || n_MN || n_UN || n_ST || n_DC || did_sched) {
- snap_old();
- }
-
- sraRgnDestroy(r0);
- sraRgnDestroy(missed_su_restore_rgn);
- sraRgnDestroy(missed_bs_restore_rgn);
-
-if (ncdb) rfbLog("OUT check_ncache(): %.4f %.6f events: %d pixels: %d\n", dnowx(), dnow() - now, n, pixels);
-if (ncdb) fprintf(stderr, "\n");
- return pixels;
-}
-#endif
-
diff --git a/x11vnc/userinput.h b/x11vnc/userinput.h
deleted file mode 100644
index a5fd2b3..0000000
--- a/x11vnc/userinput.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_USERINPUT_H
-#define _X11VNC_USERINPUT_H
-
-/* -- userinput.h -- */
-
-extern int defer_update_nofb;
-extern int last_scroll_type;
-
-extern int get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
- Window *frame, Window *win);
-extern void parse_scroll_copyrect(void);
-extern void parse_fixscreen(void);
-extern void parse_wireframe(void);
-
-extern void set_wirecopyrect_mode(char *str);
-extern void set_scrollcopyrect_mode(char *str);
-extern void initialize_scroll_keys(void);
-extern void initialize_scroll_matches(void);
-extern void initialize_scroll_term(void);
-extern void initialize_max_keyrepeat(void);
-
-extern int direct_fb_copy(int x1, int y1, int x2, int y2, int mark);
-extern void fb_push(void);
-extern int fb_push_wait(double max_wait, int flags);
-extern void eat_viewonly_input(int max_eat, int keep);
-
-extern void mark_for_xdamage(int x, int y, int w, int h);
-extern void mark_region_for_xdamage(sraRegionPtr region);
-extern void set_xdamage_mark(int x, int y, int w, int h);
-extern int near_wm_edge(int x, int y, int w, int h, int px, int py);
-extern int near_scrollbar_edge(int x, int y, int w, int h, int px, int py);
-
-extern void check_fixscreen(void);
-extern int check_xrecord(void);
-extern int check_wireframe(void);
-extern int fb_update_sent(int *count);
-extern int check_user_input(double dt, double dtr, int tile_diffs, int *cnt);
-extern void do_copyregion(sraRegionPtr region, int dx, int dy, int mode);
-
-extern int check_ncache(int reset, int mode);
-extern int find_rect(int idx, int x, int y, int w, int h);
-extern int lookup_win_index(Window);
-extern void set_ncache_xrootpmap(void);
-
-#endif /* _X11VNC_USERINPUT_H */
diff --git a/x11vnc/util.c b/x11vnc/util.c
deleted file mode 100644
index 80b1607..0000000
--- a/x11vnc/util.c
+++ /dev/null
@@ -1,787 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- util.c -- */
-
-#include "x11vnc.h"
-#include "cleanup.h"
-#include "win_utils.h"
-#include "unixpw.h"
-#include "connections.h"
-
-struct timeval _mysleep;
-
-/* this is only for debugging mutexes. see util.h */
-int hxl = 0;
-
-#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
-MUTEX(x11Mutex);
-MUTEX(scrollMutex);
-#endif
-
-int nfix(int i, int n);
-int nmin(int n, int m);
-int nmax(int n, int m);
-int nabs(int n);
-double dabs(double x);
-void lowercase(char *str);
-void uppercase(char *str);
-char *lblanks(char *str);
-void strzero(char *str);
-int scan_hexdec(char *str, unsigned long *num);
-int parse_geom(char *str, int *wp, int *hp, int *xp, int *yp, int W, int H);
-void set_env(char *name, char *value);
-char *bitprint(unsigned int st, int nbits);
-char *get_user_name(void);
-char *get_home_dir(void);
-char *get_shell(void);
-char *this_host(void);
-
-int match_str_list(char *str, char **list);
-char **create_str_list(char *cslist);
-
-double dtime(double *);
-double dtime0(double *);
-double dnow(void);
-double dnowx(void);
-double rnow(void);
-double rfac(void);
-
-int rfbPE(long usec);
-void rfbCFD(long usec);
-
-double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1,
- int X2, int Y2);
-
-char *choose_title(char *display);
-
-
-/*
- * routine to keep 0 <= i < n
- */
-int nfix(int i, int n) {
- if (i < 0) {
- i = 0;
- } else if (i >= n) {
- i = n - 1;
- }
- return i;
-}
-
-int nmin(int n, int m) {
- if (n < m) {
- return n;
- } else {
- return m;
- }
-}
-
-int nmax(int n, int m) {
- if (n > m) {
- return n;
- } else {
- return m;
- }
-}
-
-int nabs(int n) {
- if (n < 0) {
- return -n;
- } else {
- return n;
- }
-}
-
-double dabs(double x) {
- if (x < 0.0) {
- return -x;
- } else {
- return x;
- }
-}
-
-void lowercase(char *str) {
- char *p;
- if (str == NULL) {
- return;
- }
- p = str;
- while (*p != '\0') {
- *p = tolower((unsigned char) (*p));
- p++;
- }
-}
-
-void uppercase(char *str) {
- char *p;
- if (str == NULL) {
- return;
- }
- p = str;
- while (*p != '\0') {
- *p = toupper((unsigned char) (*p));
- p++;
- }
-}
-
-char *lblanks(char *str) {
- char *p = str;
- while (*p != '\0') {
- if (! isspace((unsigned char) (*p))) {
- break;
- }
- p++;
- }
- return p;
-}
-
-void strzero(char *str) {
- char *p = str;
- if (p != NULL) {
- while (*p != '\0') {
- *p = '\0';
- p++;
- }
- }
-}
-
-int is_decimal(char *str) {
- char *p = str;
- if (p != NULL) {
- int first = 1;
- while (*p != '\0') {
- if (first && *p == '-') {
- ;
- } else if (isdigit((int) *p)) {
- ;
- } else {
- return 0;
- }
- first = 0;
- p++;
- }
- return 1;
- }
- return 0;
-}
-
-int scan_hexdec(char *str, unsigned long *num) {
- if (sscanf(str, "0x%lx", num) != 1) {
- if (sscanf(str, "%lu", num) != 1) {
- return 0;
- }
- }
- return 1;
-}
-
-int parse_geom(char *str, int *wp, int *hp, int *xp, int *yp, int W, int H) {
- int w, h, x, y;
- if (! str) {
- return 0;
- }
- /* handle +/-x and +/-y */
- if (sscanf(str, "%dx%d+%d+%d", &w, &h, &x, &y) == 4) {
- ;
- } else if (sscanf(str, "%dx%d-%d+%d", &w, &h, &x, &y) == 4) {
- w = nabs(w);
- x = W - x - w;
- } else if (sscanf(str, "%dx%d+%d-%d", &w, &h, &x, &y) == 4) {
- h = nabs(h);
- y = H - y - h;
- } else if (sscanf(str, "%dx%d-%d-%d", &w, &h, &x, &y) == 4) {
- w = nabs(w);
- h = nabs(h);
- x = W - x - w;
- y = H - y - h;
- } else {
- return 0;
- }
- *wp = w;
- *hp = h;
- *xp = x;
- *yp = y;
- return 1;
-}
-
-void set_env(char *name, char *value) {
- char *str;
- if (! name) {
- return;
- }
- if (! value) {
- value = "";
- }
- str = (char *) malloc(strlen(name) + 1 + strlen(value) + 1);
- sprintf(str, "%s=%s", name, value);
- putenv(str);
-}
-
-char *bitprint(unsigned int st, int nbits) {
- static char str[33];
- int i, mask;
- if (nbits > 32) {
- nbits = 32;
- }
- for (i=0; i<nbits; i++) {
- str[i] = '0';
- }
- str[nbits] = '\0';
- mask = 1;
- for (i=nbits-1; i>=0; i--) {
- if (st & mask) {
- str[i] = '1';
- }
- mask = mask << 1;
- }
- return str; /* take care to use or copy immediately */
-}
-
-char *get_user_name(void) {
- char *user = NULL;
-
- user = getenv("USER");
- if (user == NULL) {
- user = getenv("LOGNAME");
- }
-
-#if LIBVNCSERVER_HAVE_PWD_H
- if (user == NULL) {
- struct passwd *pw = getpwuid(getuid());
- if (pw) {
- user = pw->pw_name;
- }
- }
-#endif
-
- if (user) {
- return(strdup(user));
- } else {
- return(strdup("unknown-user"));
- }
-}
-
-char *get_home_dir(void) {
- char *home = NULL;
-
- home = getenv("HOME");
-
-#if LIBVNCSERVER_HAVE_PWD_H
- if (home == NULL) {
- struct passwd *pw = getpwuid(getuid());
- if (pw) {
- home = pw->pw_dir;
- }
- }
-#endif
-
- if (home) {
- return(strdup(home));
- } else {
- return(strdup("/"));
- }
-}
-
-char *get_shell(void) {
- char *shell = NULL;
-
- shell = getenv("SHELL");
-
-#if LIBVNCSERVER_HAVE_PWD_H
- if (shell == NULL) {
- struct passwd *pw = getpwuid(getuid());
- if (pw) {
- shell = pw->pw_shell;
- }
- }
-#endif
-
- if (shell) {
- return(strdup(shell));
- } else {
- return(strdup("/bin/sh"));
- }
-}
-
-/*
- * utility to get the current host name
- */
-char *this_host(void) {
- char host[MAXN];
-#if LIBVNCSERVER_HAVE_GETHOSTNAME
- if (gethostname(host, MAXN) == 0) {
- host[MAXN-1] = '\0';
- return strdup(host);
- } else if (UT.nodename) {
- return strdup(UT.nodename);
- }
-#endif
- return NULL;
-}
-
-int match_str_list(char *str, char **list) {
- int i = 0, matched = 0;
-
- if (! str || ! list) {
- return 0;
- }
- while (list[i] != NULL) {
- if (!strcmp(list[i], "*")) {
- matched = 1;
- break;
- } else if (strstr(str, list[i])) {
- matched = 1;
- break;
- }
- i++;
- }
- return matched;
-}
-
-char **create_str_list(char *cslist) {
- int i, n;
- char *p, *str;
- char **list = NULL;
-
- if (! cslist) {
- return NULL;
- }
-
- str = strdup(cslist);
- n = 1;
- p = str;
- while (*p != '\0') {
- if (*p == ',') {
- n++;
- }
- p++;
- }
-
- /* the extra last one holds NULL */
- list = (char **) calloc((n+1)*sizeof(char *), 1);
-
- p = strtok(str, ",");
- i = 0;
- while (p && i < n) {
- list[i++] = strdup(p);
- p = strtok(NULL, ",");
- }
- free(str);
-
- return list;
-}
-
-/*
- * simple function for measuring sub-second time differences, using
- * a double to hold the value.
- */
-double dtime(double *t_old) {
- /*
- * usage: call with 0.0 to initialize, subsequent calls give
- * the time difference since last call.
- */
- double t_now, dt;
- struct timeval now;
-
- gettimeofday(&now, NULL);
- t_now = now.tv_sec + ( (double) now.tv_usec/1000000. );
- if (*t_old == 0.0) {
- *t_old = t_now;
- return t_now;
- }
- dt = t_now - *t_old;
- *t_old = t_now;
- return(dt);
-}
-
-/* common dtime() activities: */
-double dtime0(double *t_old) {
- *t_old = 0.0;
- return dtime(t_old);
-}
-
-double dnow(void) {
- double t;
- return dtime0(&t);
-}
-
-double dnowx(void) {
- return dnow() - x11vnc_start;
-}
-
-double rnow(void) {
- double t = dnow();
- t = t - ((int) t);
- if (t > 1.0) {
- t = 1.0;
- } else if (t < 0.0) {
- t = 0.0;
- }
- return t;
-}
-
-double rfac(void) {
- double f;
- static int first = 1;
-
- if (first) {
- unsigned int s;
- if (getenv("RAND_SEED")) {
- s = (unsigned int) atoi(getenv("RAND_SEED"));
- } else {
- s = (unsigned int) ((int) getpid() + 100000 * rnow());
- }
- srand(s);
- first = 0;
- }
-
- f = (double) rand();
- f = f / ((double) RAND_MAX);
-
- return f;
-}
-
-void check_allinput_rate(void) {
- static double last_all_input_check = 0.0;
- static int set = 0, verb = -1;
-
- if (use_threads) {
- return;
- }
- if (verb < 0) {
- verb = 0;
- if (getenv("RATE_VERB")) verb = 1;
- }
- if (! set) {
- set = 1;
- last_all_input_check = dnow();
- } else {
- int dt = 5;
- if (x11vnc_current > last_all_input_check + dt) {
- int n, nq = 0;
- while ((n = rfbCheckFds(screen, 0))) {
- nq += n;
- }
- if (verb) fprintf(stderr, "nqueued: %d\n", nq);
- if (getenv("CHECK_RATE") && nq > 18 * dt) {
- double rate = nq / dt;
- if (verb) rfbLog("check_allinput_rate:\n");
- if (verb) rfbLog("Client is sending %.1f extra requests per second for the\n", rate);
- if (verb) rfbLog("past %d seconds! (queued: %d)\n", dt, nq);
- if (strstr(getenv("CHECK_RATE"), "allinput") && !all_input && !handle_events_eagerly) {
- rfbLog("Switching to -allpinput mode.\n");
- all_input = 1;
- }
- }
- set = 0;
- }
- }
-}
-
-static void do_allinput(long usec) {
- static double last = 0.0;
- static int meas = 0, verb = -1;
- int n, f = 1, cnt = 0, m = 0;
- long usec0;
- double now;
- if (!screen || !screen->clientHead) {
- return;
- }
- if (use_threads) {
- return;
- }
- if (usec < 0) {
- usec = 0;
- }
- usec0 = usec;
- if (last == 0.0) {
- last = dnow();
- }
- if (verb < 0) {
- verb = 0;
- if (getenv("RATE_VERB")) verb = 1;
- }
- while ((n = rfbCheckFds(screen, usec)) > 0) {
- if (f) {
- if (verb) fprintf(stderr, " *");
- f = 0;
- }
- if (cnt++ > 30) {
- break;
- }
- meas += n;
- m += n;
- }
- if (verb) fprintf(stderr, "+%d/%d", cnt, m);
- now = dnow();
- if (now > last + 2.0) {
- double rate = meas / (now - last);
- if (verb) fprintf(stderr, "\n allinput rate: %.2f ", rate);
- meas = 0;
- last = dnow();
- }
-}
-
-/*
- * utility wrapper to call rfbProcessEvents
- * checks that we are not in threaded mode.
- */
-#define USEC_MAX 999999 /* libvncsever assumes < 1 second */
-int rfbPE(long usec) {
- int uip0 = unixpw_in_progress;
- static int check_rate = -1;
- int res = 0;
- if (! screen) {
- return res;
- }
- if (unixpw && unixpw_in_progress && !unixpw_in_rfbPE) {
- rfbLog("unixpw_in_rfbPE: skipping rfbPE\n");
- return res;
- }
-
- if (debug_tiles > 2) {
- double tm = dnow();
- fprintf(stderr, "rfbPE(%d) t: %.4f\n",
- (int) usec, tm - x11vnc_start);
- }
-
- if (usec > USEC_MAX) {
- usec = USEC_MAX;
- }
- if (! use_threads) {
- rfbBool r;
- r = rfbProcessEvents(screen, usec);
- if (r) {
- res = 1;
- }
- }
-
- if (unixpw && unixpw_in_progress && !uip0) {
- if (!unixpw_in_rfbPE) {
- rfbLog("rfbPE: got new client in non-rfbPE\n");
- ; /* this is new unixpw client */
- }
- }
-
- if (ipv6_listen) {
- check_ipv6_listen(usec);
- }
- if (unix_sock) {
- check_unix_sock(usec);
- }
- if (check_rate != 0) {
- if (check_rate < 0) {
- if (getenv("CHECK_RATE")) {
- check_rate = 1;
- } else {
- check_rate = 0;
- }
- }
- if (check_rate && !all_input && x11vnc_current < last_client + 45) {
- check_allinput_rate();
- }
- }
- if (all_input) {
- do_allinput(usec);
- }
- return res;
-}
-
-void rfbCFD(long usec) {
- int uip0 = unixpw_in_progress;
- if (! screen) {
- return;
- }
- if (unixpw && unixpw_in_progress && !unixpw_in_rfbPE) {
- static int msgs = 0;
- static double last_reset = 0.0;
- if (dnow() > last_reset + 5.0) {
- msgs = 0;
- last_reset = dnow();
- }
- if (msgs++ < 10) {
- rfbLog("unixpw_in_rfbPE: skipping rfbCFD\n");
- if (msgs == 10) {
- rfbLog("unixpw_in_rfbPE: skipping rfbCFD ...\n");
- }
- }
- return;
- }
- if (usec > USEC_MAX) {
- usec = USEC_MAX;
- }
-
- if (debug_tiles > 2) {
- double tm = dnow();
- fprintf(stderr, "rfbCFD(%d) t: %.4f\n",
- (int) usec, tm - x11vnc_start);
- }
-
-
- if (! use_threads) {
- if (all_input) {
- do_allinput(usec);
- } else {
- if (handle_events_eagerly) {
- screen->handleEventsEagerly = TRUE;
- } else {
- screen->handleEventsEagerly = FALSE;
- }
- rfbCheckFds(screen, usec);
- }
- }
-
- if (unixpw && unixpw_in_progress && !uip0) {
- if (!unixpw_in_rfbPE) {
- rfbLog("rfbCFD: got new client in non-rfbPE\n");
- ; /* this is new unixpw client */
- }
- }
-}
-
-double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1,
- int X2, int Y2) {
- double a, A, o;
- sraRegionPtr r, R;
- sraRectangleIterator *iter;
- sraRect rt;
-
- a = nabs((x2 - x1) * (y2 - y1));
- A = nabs((X2 - X1) * (Y2 - Y1));
-
- if (a == 0 || A == 0) {
- return 0.0;
- }
-
- r = sraRgnCreateRect(x1, y1, x2, y2);
- R = sraRgnCreateRect(X1, Y1, X2, Y2);
-
- sraRgnAnd(r, R);
-
- o = 0.0;
- iter = sraRgnGetIterator(r);
- while (sraRgnIteratorNext(iter, &rt)) {
- o += nabs( (rt.x2 - rt.x1) * (rt.y2 - rt.y1) );
- }
- sraRgnReleaseIterator(iter);
-
- sraRgnDestroy(r);
- sraRgnDestroy(R);
-
- if (a < A) {
- o = o/a;
- } else {
- o = o/A;
- }
- return o;
-}
-
-/*
- * choose a desktop name
- */
-char *choose_title(char *display) {
- static char title[(MAXN+10)];
-
- memset(title, 0, sizeof(title));
- strcpy(title, "x11vnc");
-
- if (display == NULL) {
- display = getenv("DISPLAY");
- }
-
-#ifdef MACOSX
- if (display == NULL || strstr(display, "/tmp/") == display) {
- char *u = get_user_name();
- char *th = this_host();
- if (strlen(u) > MAXN/4) {
- u = "someone";
- }
- strcpy(title, u);
- if (th == NULL && UT.nodename) {
- th = UT.nodename;
- }
- if (th) {
- strcat(title, "@");
- strncat(title, th, MAXN - strlen(title));
- }
- return title;
- }
-#endif
-
- if (display == NULL) {
- return title;
- }
-
- /* use display: */
- title[0] = '\0';
- if (display[0] == ':') {
- char *th = this_host();
- if (th != NULL) {
- strncpy(title, th, MAXN - strlen(title));
- }
- }
- strncat(title, display, MAXN - strlen(title));
- X_LOCK;
- if (subwin && dpy && valid_window(subwin, NULL, 0)) {
-#if !NO_X11
- char *name = NULL;
- int do_appshare = getenv("X11VNC_APPSHARE_ACTIVE") ? 1 : 0;
- if (0 && do_appshare) {
- title[0] = '\0';
- }
- if (XFetchName(dpy, subwin, &name)) {
- if (name) {
- if (title[0] != '\0') {
- strncat(title, " ", MAXN - strlen(title));
- }
- strncat(title, name, MAXN - strlen(title));
- free(name);
- }
- }
- if (do_appshare) {
- Window c;
- int x, y;
- if (xtranslate(subwin, rootwin, 0, 0, &x, &y, &c, 1)) {
- char tmp[32];
- if (scaling) {
- x *= scale_fac_x;
- y *= scale_fac_y;
- }
- sprintf(tmp, " XY=%d,%d", x, y);
- strncat(title, tmp, MAXN - strlen(title));
- }
- rfbLog("appshare title: %s\n", title);
- }
-#endif /* NO_X11 */
- }
- X_UNLOCK;
- return title;
-}
diff --git a/x11vnc/util.h b/x11vnc/util.h
deleted file mode 100644
index 55585cf..0000000
--- a/x11vnc/util.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_UTIL_H
-#define _X11VNC_UTIL_H
-
-/* -- util.h -- */
-
-extern int nfix(int i, int n);
-extern int nmin(int n, int m);
-extern int nmax(int n, int m);
-extern int nabs(int n);
-extern double dabs(double x);
-extern void lowercase(char *str);
-extern void uppercase(char *str);
-extern char *lblanks(char *str);
-extern void strzero(char *str);
-extern int scan_hexdec(char *str, unsigned long *num);
-extern int parse_geom(char *str, int *wp, int *hp, int *xp, int *yp, int W, int H);
-extern void set_env(char *name, char *value);
-extern char *bitprint(unsigned int st, int nbits);
-extern char *get_user_name(void);
-extern char *get_home_dir(void);
-extern char *get_shell(void);
-extern char *this_host(void);
-
-extern int match_str_list(char *str, char **list);
-extern char **create_str_list(char *cslist);
-
-extern double dtime(double *);
-extern double dtime0(double *);
-extern double dnow(void);
-extern double dnowx(void);
-extern double rnow(void);
-extern double rfac(void);
-
-extern int rfbPE(long usec);
-extern void rfbCFD(long usec);
-extern double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1,
- int X2, int Y2);
-extern char *choose_title(char *display);
-
-
-#define NONUL(x) ((x) ? (x) : "")
-
-/*
- Put this in usleep2() for debug printout.
- fprintf(stderr, "_mysleep: %08d %10.6f %s:%d\n", (x), dnow() - x11vnc_start, __FILE__, __LINE__); \
- */
-
-/* XXX usleep(3) is not thread safe on some older systems... */
-extern struct timeval _mysleep;
-#define usleep2(x) \
- _mysleep.tv_sec = (x) / 1000000; \
- _mysleep.tv_usec = (x) % 1000000; \
- select(0, NULL, NULL, NULL, &_mysleep);
-#if !defined(X11VNC_USLEEP)
-#undef usleep
-#define usleep usleep2
-#endif
-
-/*
- * following is based on IsModifierKey in Xutil.h
-*/
-#define ismodkey(keysym) \
- ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R) && \
- ((KeySym)(keysym) != XK_Caps_Lock) && ((KeySym)(keysym) != XK_Shift_Lock)))
-
-/*
- * When threaded we have to mutex our X11 calls to avoid XIO crashes
- * due to callbacks.
- */
-#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
-extern MUTEX(x11Mutex);
-extern MUTEX(scrollMutex);
-MUTEX(clientMutex);
-MUTEX(inputMutex);
-MUTEX(pointerMutex);
-#endif
-
-#define X_INIT INIT_MUTEX(x11Mutex)
-
-#if 1
-#define X_LOCK LOCK(x11Mutex)
-#define X_UNLOCK UNLOCK(x11Mutex)
-#else
-extern int hxl;
-#define X_LOCK fprintf(stderr, "*** X_LOCK** %d%s %s:%d\n", \
- hxl, hxl ? " BAD-PRE-LOCK":"", __FILE__, __LINE__); LOCK(x11Mutex); hxl = 1;
-#define X_UNLOCK fprintf(stderr, " x_unlock %d%s %s:%d\n", \
- hxl, !hxl ? " BAD-PRE-UNLOCK":"", __FILE__, __LINE__); UNLOCK(x11Mutex); hxl = 0;
-#endif
-
-#define SCR_LOCK if (use_threads) {LOCK(scrollMutex);}
-#define SCR_UNLOCK if (use_threads) {UNLOCK(scrollMutex);}
-#define SCR_INIT INIT_MUTEX(scrollMutex)
-
-#define CLIENT_LOCK if (use_threads) {LOCK(clientMutex);}
-#define CLIENT_UNLOCK if (use_threads) {UNLOCK(clientMutex);}
-#define CLIENT_INIT INIT_MUTEX(clientMutex)
-
-#if 1
-#define INPUT_LOCK if (use_threads) {LOCK(inputMutex);}
-#define INPUT_UNLOCK if (use_threads) {UNLOCK(inputMutex);}
-#else
-#define INPUT_LOCK
-#define INPUT_UNLOCK
-#endif
-#define INPUT_INIT INIT_MUTEX(inputMutex)
-
-#define POINTER_LOCK if (use_threads) {LOCK(pointerMutex);}
-#define POINTER_UNLOCK if (use_threads) {UNLOCK(pointerMutex);}
-#define POINTER_INIT INIT_MUTEX(pointerMutex)
-
-/*
- * The sendMutex member was added to libvncserver 0.9.8
- * rfb/rfb.h sets LIBVNCSERVER_SEND_MUTEX if present.
- */
-#if LIBVNCSERVER_HAVE_LIBPTHREAD && defined(LIBVNCSERVER_SEND_MUTEX)
-#define SEND_LOCK(cl) if (use_threads) LOCK((cl)->sendMutex);
-#define SEND_UNLOCK(cl) if (use_threads) UNLOCK((cl)->sendMutex);
-#else
-#define SEND_LOCK(cl)
-#define SEND_UNLOCK(cl)
-#endif
-
-#endif /* _X11VNC_UTIL_H */
diff --git a/x11vnc/v4l.c b/x11vnc/v4l.c
deleted file mode 100644
index 86c33a6..0000000
--- a/x11vnc/v4l.c
+++ /dev/null
@@ -1,1785 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- v4l.c -- */
-
-#include "x11vnc.h"
-#include "cleanup.h"
-#include "scan.h"
-#include "xinerama.h"
-#include "screen.h"
-#include "connections.h"
-#include "keyboard.h"
-#include "allowed_input_t.h"
-
-#if LIBVNCSERVER_HAVE_LINUX_VIDEODEV_H
-#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#define CONFIG_VIDEO_V4L1_COMPAT
-#include <linux/videodev.h>
-#ifdef __LINUX_VIDEODEV2_H
-# ifndef HAVE_V4L2
-# define HAVE_V4L2 1
-# endif
-#endif
-#define V4L_OK
-#endif
-#endif
-
-char *v4l_guess(char *str, int *fd);
-void v4l_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
-void v4l_pointer_command(int mask, int x, int y, rfbClientPtr client);
-
-static int v4l1_val(int pct);
-static int v4l1_width(int w);
-static int v4l1_height(int h);
-static int v4l1_resize(int fd, int w, int h);
-static void v4l1_setfreq(int fd, unsigned long freq, int verb);
-static void v4l1_set_input(int fd, int which);
-static int v4l1_setfmt(int fd, char *fmt);
-static void apply_settings(char *dev, char *settings, int *fd);
-static int v4l1_dpct(int old, int d);
-static void v4l_requery(void);
-static void v4l_br(int b);
-static void v4l_hu(int b);
-static void v4l_co(int b);
-static void v4l_cn(int b);
-static void v4l_sz(int b);
-static void v4l_sta(int sta);
-static void v4l_inp(int inp);
-static void v4l_fmt(char *fmt);
-static int colon_n(char *line);
-static char *colon_str(char *line);
-static char *colon_tag(char *line);
-static void lookup_rgb(char *g_fmt, int *g_b, int *mask_rev);
-static char *v4l1_lu_palette(unsigned short palette);
-static unsigned short v4l1_lu_palette_str(char *name, int *bits, int *rev);
-static char *v4l2_lu_palette(unsigned int palette);
-static unsigned int v4l2_lu_palette_str(char *name, int *bits, int *rev);
-static int v4l1_query(int fd, int verbose);
-static int v4l2_query(int fd, int verbose);
-static int open_dev(char *dev);
-static char *guess_via_v4l(char *dev, int *fd);
-static char *guess_via_v4l_info(char *dev, int *fd);
-static void parse_str(char *str, char **dev, char **settings, char **atparms);
-static unsigned long lookup_freqtab(int sta);
-static unsigned long lookup_freq(int sta);
-static int lookup_station(unsigned long freq);
-static void init_freqtab(char *file);
-static void init_freqs(void);
-static void init_ntsc_cable(void);
-
-#define C_VIDEO_CAPTURE 1
-#define C_PICTURE 2
-#define C_WINDOW 3
-
-#ifdef V4L_OK
-static struct video_capability v4l1_capability;
-static struct video_channel v4l1_channel;
-static struct video_tuner v4l1_tuner;
-static struct video_picture v4l1_picture;
-static struct video_window v4l1_window;
-
-#if HAVE_V4L2
-static struct v4l2_capability v4l2_capability;
-static struct v4l2_input v4l2_input;
-static struct v4l2_tuner v4l2_tuner;
-static struct v4l2_fmtdesc v4l2_fmtdesc;
-static struct v4l2_format v4l2_format;
-/*static struct v4l2_framebuffer v4l2_fbuf; */
-/*static struct v4l2_queryctrl v4l2_qctrl; */
-#endif
-#endif
-
-static int v4l1_cap = -1;
-static int v4l2_cap = -1;
-#define V4L1_MAX 65535
-
-#define CHANNEL_MAX 500
-static unsigned long ntsc_cable[CHANNEL_MAX];
-static unsigned long custom_freq[CHANNEL_MAX];
-
-static unsigned long last_freq = 0;
-static int last_channel = 0;
-
-static int v4l1_val(int pct) {
- /* pct is % */
- int val, max = V4L1_MAX;
- if (pct < 0) {
- return 0;
- } else if (pct > 100) {
- return max;
- }
- val = (pct * max)/100;
-
- return val;
-}
-static int v4l1_width(int w) {
-#ifdef V4L_OK
- int min = v4l1_capability.minwidth;
- int max = v4l1_capability.maxwidth;
- if (w < min) {
- w = min;
- }
- if (w > max) {
- w = max;
- }
-#endif
- return w;
-}
-static int v4l1_height(int h) {
-#ifdef V4L_OK
- int min = v4l1_capability.minheight;
- int max = v4l1_capability.maxheight;
- if (h < min) {
- h = min;
- }
- if (h > max) {
- h = max;
- }
-#endif
- return h;
-}
-
-static int v4l1_resize(int fd, int w, int h) {
-#ifdef V4L_OK
- int dowin = 0;
-
- memset(&v4l1_window, 0, sizeof(v4l1_window));
- if (ioctl(fd, VIDIOCGWIN, &v4l1_window) == -1) {
- return 0;
- }
-
- if (w > 0) w = v4l1_width(w);
-
- if (w > 0 && w != (int) v4l1_window.width) {
- dowin = 1;
- }
-
- if (h > 0) h = v4l1_height(h);
-
- if (h > 0 && h != (int) v4l1_window.height) {
- dowin = 1;
- }
-
- if (dowin) {
- v4l1_window.x = 0;
- v4l1_window.y = 0;
- ioctl(fd, VIDIOCSWIN, &v4l1_window);
- if (w > 0) v4l1_window.width = w;
- if (h > 0) v4l1_window.height = h;
- fprintf(stderr, "calling V4L_1: VIDIOCSWIN\n");
- fprintf(stderr, "trying new size %dx%d\n",
- v4l1_window.width, v4l1_window.height);
- if (ioctl(fd, VIDIOCSWIN, &v4l1_window) == -1) {
- perror("ioctl VIDIOCSWIN");
- return 0;
- }
- }
-#else
- if (!fd || !w || !h) {}
-#endif
- return 1;
-}
-
-static void v4l1_setfreq(int fd, unsigned long freq, int verb) {
-#ifdef V4L_OK
- unsigned long f0, f1;
- f1 = (freq * 16) / 1000;
- ioctl(fd, VIDIOCGFREQ, &f0);
- if (verb) fprintf(stderr, "read freq: %d\n", (int) f0);
- if (freq > 0) {
- if (ioctl(fd, VIDIOCSFREQ, &f1) == -1) {
- perror("ioctl VIDIOCSFREQ");
- } else {
- ioctl(fd, VIDIOCGFREQ, &f0);
- if (verb) fprintf(stderr, "read freq: %d\n", (int) f0);
- last_freq = freq;
- }
- }
-#else
- if (!fd || !freq || !verb) {}
-#endif
-}
-
-static void v4l1_set_input(int fd, int which) {
-#ifdef V4L_OK
- if (which != -1) {
- memset(&v4l1_channel, 0, sizeof(v4l1_channel));
- v4l1_channel.channel = which;
- if (ioctl(fd, VIDIOCGCHAN, &v4l1_channel) != -1) {
- v4l1_channel.channel = which;
- fprintf(stderr, "setting input channel to %d: %s\n",
- which, v4l1_channel.name);
- last_channel = which;
- ioctl(fd, VIDIOCSCHAN, &v4l1_channel);
- }
- }
-#else
- if (!fd || !which) {}
-#endif
-}
-
-static int v4l1_setfmt(int fd, char *fmt) {
-#ifdef V4L_OK
- unsigned short fnew;
- int bnew, rnew;
-
- fnew = v4l1_lu_palette_str(fmt, &bnew, &rnew);
- if (fnew) {
- v4l1_picture.depth = bnew;
- v4l1_picture.palette = fnew;
- }
- fprintf(stderr, "calling V4L_1: VIDIOCSPICT\n");
- if (ioctl(fd, VIDIOCSPICT, &v4l1_picture) == -1) {
- perror("ioctl VIDIOCSPICT");
- return 0;
- }
- if (raw_fb_pixfmt) {
- free(raw_fb_pixfmt);
- }
- raw_fb_pixfmt = strdup(fmt);
-#else
- if (!fd || !fmt) {}
-#endif
- return 1;
-}
-
-static int ignore_all = 0;
-
-static void apply_settings(char *dev, char *settings, int *fd) {
-#ifdef V4L_OK
- char *str, *p, *fmt = NULL, *tun = NULL, *inp = NULL;
- int br = -1, co = -1, cn = -1, hu = -1;
- int w = -1, h = -1, b = -1;
- int sta = -1;
- int setcnt = 0;
- if (! settings || settings[0] == '\0') {
- return;
- }
- str = strdup(settings);
- p = strtok(str, ",");
- while (p) {
- if (strstr(p, "br=") == p) {
- br = atoi(p+3);
- if (br >= 0) setcnt++;
- } else if (strstr(p, "co=") == p) {
- co = atoi(p+3);
- if (co >= 0) setcnt++;
- } else if (strstr(p, "cn=") == p) {
- cn = atoi(p+3);
- if (cn >= 0) setcnt++;
- } else if (strstr(p, "hu=") == p) {
- hu = atoi(p+3);
- if (hu >= 0) setcnt++;
- } else if (strstr(p, "w=") == p) {
- w = atoi(p+2);
- if (w > 0) setcnt++;
- } else if (strstr(p, "h=") == p) {
- h = atoi(p+2);
- if (h > 0) setcnt++;
- } else if (strstr(p, "bpp=") == p) {
- b = atoi(p+4);
- if (b > 0) setcnt++;
- } else if (strstr(p, "fmt=") == p) {
- fmt = strdup(p+4);
- setcnt++;
- } else if (strstr(p, "tun=") == p) {
- tun = strdup(p+4);
- setcnt++;
- } else if (strstr(p, "inp=") == p) {
- inp = strdup(p+4);
- setcnt++;
- } else if (strstr(p, "sta=") == p) {
- sta = atoi(p+4);
- setcnt++;
- }
- p = strtok(NULL, ",");
- }
- free(str);
- if (! setcnt) {
- return;
- }
- if (*fd < 0) {
- *fd = open_dev(dev);
- }
- if (*fd < 0) {
- return;
- }
- v4l1_cap = v4l1_query(*fd, 1);
- v4l2_cap = v4l2_query(*fd, 1);
-
- if (v4l1_cap && ! ignore_all) {
- if (br >= 0) v4l1_picture.brightness = v4l1_val(br);
- if (hu >= 0) v4l1_picture.hue = v4l1_val(hu);
- if (co >= 0) v4l1_picture.colour = v4l1_val(co);
- if (cn >= 0) v4l1_picture.contrast = v4l1_val(cn);
-
- fprintf(stderr, "calling V4L_1: VIDIOCSPICT\n");
- if (ioctl(*fd, VIDIOCSPICT, &v4l1_picture) == -1) {
- perror("ioctl VIDIOCSPICT");
- }
-
- if (fmt) {
- v4l1_setfmt(*fd, fmt);
- } else if (b > 0 && b != v4l1_picture.depth) {
- if (b == 8) {
- v4l1_setfmt(*fd, "HI240");
- } else if (b == 16) {
- v4l1_setfmt(*fd, "RGB565");
- } else if (b == 24) {
- v4l1_setfmt(*fd, "RGB24");
- } else if (b == 32) {
- v4l1_setfmt(*fd, "RGB32");
- }
- }
-
- v4l1_resize(*fd, w, h);
-
- if (tun) {
- int mode = -1;
- if (!strcasecmp(tun, "PAL")) {
- mode = VIDEO_MODE_PAL;
- } else if (!strcasecmp(tun, "NTSC")) {
- mode = VIDEO_MODE_NTSC;
- } else if (!strcasecmp(tun, "SECAM")) {
- mode = VIDEO_MODE_SECAM;
- } else if (!strcasecmp(tun, "AUTO")) {
- mode = VIDEO_MODE_AUTO;
- }
- if (mode != -1) {
- int i;
- for (i=0; i< v4l1_capability.channels; i++) {
- memset(&v4l1_channel, 0, sizeof(v4l1_channel));
- v4l1_channel.channel = i;
- if (ioctl(*fd, VIDIOCGCHAN, &v4l1_channel) == -1) {
- continue;
- }
- if (! v4l1_channel.tuners) {
- continue;
- }
- if (v4l1_channel.norm == mode) {
- continue;
- }
- v4l1_channel.norm = mode;
- ioctl(*fd, VIDIOCSCHAN, &v4l1_channel);
- }
- }
- }
- if (inp) {
- char s[2];
- int i, chan = -1;
-
- s[0] = inp[0];
- s[1] = '\0';
- if (strstr("0123456789", s)) {
- chan = atoi(inp);
- } else {
- for (i=0; i< v4l1_capability.channels; i++) {
- memset(&v4l1_channel, 0, sizeof(v4l1_channel));
- v4l1_channel.channel = i;
- if (ioctl(*fd, VIDIOCGCHAN, &v4l1_channel) == -1) {
- continue;
- }
- if (!strcmp(v4l1_channel.name, inp)) {
- chan = i;
- break;
- }
- }
- }
- v4l1_set_input(*fd, chan);
- }
- if (sta >= 0) {
- unsigned long freq = lookup_freq(sta);
- v4l1_setfreq(*fd, freq, 1);
- }
- }
- v4l1_cap = v4l1_query(*fd, 1);
- v4l2_cap = v4l2_query(*fd, 1);
-#else
- if (!dev || !settings || !fd) {}
- return;
-#endif
-}
-
-static double dval = 0.05;
-
-static int v4l1_dpct(int old, int d) {
- int newval, max = V4L1_MAX;
-
- /* -1 and 1 are special cases for "small increments" */
- if (d == -1) {
- newval = old - (int) (dval * max);
- } else if (d == 1) {
- newval = old + (int) (dval * max);
- } else {
- newval = (d * max)/100;
- }
- if (newval < 0) {
- newval = 0;
- }
- if (newval > max) {
- newval = max;
- }
- return newval;
-}
-
-static void v4l_requery(void) {
- if (raw_fb_fd < 0) {
- return;
- }
- v4l1_cap = v4l1_query(raw_fb_fd, 1);
- v4l2_cap = v4l2_query(raw_fb_fd, 1);
-}
-
-static void v4l_br(int b) {
-#ifdef V4L_OK
- int old = v4l1_picture.brightness;
-
- v4l1_picture.brightness = v4l1_dpct(old, b);
- ioctl(raw_fb_fd, VIDIOCSPICT, &v4l1_picture);
- v4l_requery();
-#else
- if (!b) {}
-#endif
-}
-
-static void v4l_hu(int b) {
-#ifdef V4L_OK
- int old = v4l1_picture.hue;
-
- v4l1_picture.hue = v4l1_dpct(old, b);
- ioctl(raw_fb_fd, VIDIOCSPICT, &v4l1_picture);
- v4l_requery();
-#else
- if (!b) {}
-#endif
-}
-
-static void v4l_co(int b) {
-#ifdef V4L_OK
- int old = v4l1_picture.colour;
-
- v4l1_picture.colour = v4l1_dpct(old, b);
- ioctl(raw_fb_fd, VIDIOCSPICT, &v4l1_picture);
- v4l_requery();
-#else
- if (!b) {}
-#endif
-}
-
-static void v4l_cn(int b) {
-#ifdef V4L_OK
- int old = v4l1_picture.contrast;
-
- v4l1_picture.contrast = v4l1_dpct(old, b);
- ioctl(raw_fb_fd, VIDIOCSPICT, &v4l1_picture);
- v4l_requery();
-#else
- if (!b) {}
-#endif
-}
-
-static void v4l_sz(int b) {
-#ifdef V4L_OK
- int w_old = v4l1_window.width;
- int h_old = v4l1_window.height;
- int w, h;
-
- if (w_old == 0) {
- w_old = 160;
- }
- if (h_old == 0) {
- h_old = 120;
- }
-
- if (b == 1) {
- w = w_old + (int) (0.15 * w_old);
- h = h_old + (int) (0.15 * h_old);
- } else if (b == -1) {
- w = w_old - (int) (0.15 * w_old);
- h = h_old - (int) (0.15 * h_old);
- } else {
- return;
- }
-
- if (! v4l1_resize(raw_fb_fd, w, h)) {
- return;
- }
-
- v4l_requery();
-
- push_black_screen(4);
-
- ignore_all = 1;
- do_new_fb(1);
- ignore_all = 0;
-#else
- if (!b) {}
-#endif
-}
-
-static void v4l_sta(int sta) {
-#ifdef V4L_OK
- unsigned long freq = 0;
- int cur = lookup_station(last_freq);
-
- if (! last_freq) {
- if (sta == 0 || sta == -1) {
- sta = 11;
- }
- }
-
- if (sta == -1) {
- while (cur > 0) {
- freq = lookup_freq(--cur);
- if (freq) {
- break;
- }
- }
- } else if (sta == 0) {
- while (cur < CHANNEL_MAX - 1) {
- freq = lookup_freq(++cur);
- if (freq) {
- break;
- }
- }
- } else {
- freq = lookup_freq(sta);
- cur = sta;
- }
- fprintf(stderr, "to station %d / %d\n", cur, (int) freq);
- v4l1_setfreq(raw_fb_fd, freq, 0);
-#else
- if (!sta) {}
-#endif
-}
-
-static void v4l_inp(int inp) {
-#ifdef V4L_OK
- int next = -1;
- if (inp == -1) {
- inp = last_channel + 1;
- if (inp >= v4l1_capability.channels) {
- inp = 0;
- }
- next = inp;
- } else if (inp == -2) {
- inp = last_channel - 1;
- if (inp < 0) {
- inp = v4l1_capability.channels - 1;
- }
- next = inp;
- } else {
- next = inp;
- }
- v4l1_set_input(raw_fb_fd, next);
-#else
- if (!inp) {}
-#endif
-}
-
-static void v4l_fmt(char *fmt) {
- if (v4l1_setfmt(raw_fb_fd, fmt)) {
- v4l_requery();
-
- ignore_all = 1;
- do_new_fb(1);
- ignore_all = 0;
- }
-}
-
-void v4l_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
- allowed_input_t input;
-
- if (raw_fb_fd < 0) {
- return;
- }
- if (! down) {
- return;
- }
- if (view_only) {
- return;
- }
- get_allowed_input(client, &input);
- if (! input.keystroke) {
- return;
- }
-
- if (keysym == XK_b) {
- v4l_br(-1);
- } else if (keysym == XK_B) {
- v4l_br(+1);
- } else if (keysym == XK_h) {
- v4l_hu(-1);
- } else if (keysym == XK_H) {
- v4l_hu(+1);
- } else if (keysym == XK_c) {
- v4l_co(-1);
- } else if (keysym == XK_C) {
- v4l_co(+1);
- } else if (keysym == XK_n) {
- v4l_cn(-1);
- } else if (keysym == XK_N) {
- v4l_cn(+1);
- } else if (keysym == XK_s) {
- v4l_sz(-1);
- } else if (keysym == XK_S) {
- v4l_sz(+1);
- } else if (keysym == XK_i) {
- v4l_inp(-1);
- } else if (keysym == XK_I) {
- v4l_inp(-2);
- } else if (keysym == XK_Up) {
- v4l_sta(+0);
- } else if (keysym == XK_Down) {
- v4l_sta(-1);
- } else if (keysym == XK_F1) {
- v4l_fmt("HI240");
- } else if (keysym == XK_F2) {
- v4l_fmt("RGB565");
- } else if (keysym == XK_F3) {
- v4l_fmt("RGB24");
- } else if (keysym == XK_F4) {
- v4l_fmt("RGB32");
- } else if (keysym == XK_F5) {
- v4l_fmt("RGB555");
- } else if (keysym == XK_F6) {
- v4l_fmt("GREY");
- }
- if (client) {}
-}
-
-
-void v4l_pointer_command(int mask, int x, int y, rfbClientPtr client) {
- /* do not forget viewonly perms */
- if (mask || x || y || client) {}
-}
-
-static int colon_n(char *line) {
- char *q;
- int n;
- q = strrchr(line, ':');
- if (! q) {
- return 0;
- }
- q = lblanks(q+1);
- if (sscanf(q, "%d", &n) == 1) {
- return n;
- }
- return 0;
-}
-
-static char *colon_str(char *line) {
- char *q, *p, *t;
- q = strrchr(line, ':');
- if (! q) {
- return strdup("");
- }
- q = lblanks(q+1);
- p = strpbrk(q, " \t\n");
- if (p) {
- *p = '\0';
- }
- t = strdup(q);
- *p = '\n';
- return t;
-}
-
-static char *colon_tag(char *line) {
- char *q, *p, *t;
- q = strrchr(line, '[');
- if (! q) {
- return strdup("");
- }
- q++;
- p = strrchr(q, ']');
- if (! p) {
- return strdup("");
- }
- *p = '\0';
- t = strdup(q);
- *p = ']';
- return t;
-}
-
-static void lookup_rgb(char *fmt, int *bits, int *rev) {
- int tb, tr;
-
- if (v4l2_lu_palette_str(fmt, &tb, &tr)) {
- *bits = tb;
- *rev = tr;
- return;
- }
- if (v4l1_lu_palette_str(fmt, &tb, &tr)) {
- *bits = tb;
- *rev = tr;
- return;
- }
-}
-
-static char *v4l1_lu_palette(unsigned short palette) {
- switch(palette) {
-#ifdef V4L_OK
- case VIDEO_PALETTE_GREY: return "GREY";
- case VIDEO_PALETTE_HI240: return "HI240";
- case VIDEO_PALETTE_RGB565: return "RGB565";
- case VIDEO_PALETTE_RGB24: return "RGB24";
- case VIDEO_PALETTE_RGB32: return "RGB32";
- case VIDEO_PALETTE_RGB555: return "RGB555";
- case VIDEO_PALETTE_YUV422: return "YUV422";
- case VIDEO_PALETTE_YUYV: return "YUYV";
- case VIDEO_PALETTE_UYVY: return "UYVY";
- case VIDEO_PALETTE_YUV420: return "YUV420";
- case VIDEO_PALETTE_YUV411: return "YUV411";
- case VIDEO_PALETTE_RAW: return "RAW";
- case VIDEO_PALETTE_YUV422P: return "YUV422P";
- case VIDEO_PALETTE_YUV411P: return "YUV411P";
- case VIDEO_PALETTE_YUV420P: return "YUV420P";
- case VIDEO_PALETTE_YUV410P: return "YUV410P";
-#endif
- default: return "unknown";
- }
-}
-
-static unsigned short v4l1_lu_palette_str(char *name, int *bits, int *rev) {
-#ifdef V4L_OK
- *rev = 0;
- if (!strcmp(name, "RGB555")) {
- *bits = 16;
- return VIDEO_PALETTE_RGB555;
- } else if (!strcmp(name, "RGB565")) {
- *bits = 16;
- return VIDEO_PALETTE_RGB565;
- } else if (!strcmp(name, "RGB24")) {
- *bits = 24;
- return VIDEO_PALETTE_RGB24;
- } else if (!strcmp(name, "RGB32")) {
- *bits = 32;
- return VIDEO_PALETTE_RGB32;
- } else if (!strcmp(name, "HI240")) {
- *bits = 8;
- return VIDEO_PALETTE_HI240;
- } else if (!strcmp(name, "GREY")) {
- *bits = 8;
- return VIDEO_PALETTE_GREY;
- }
-#else
- if (!name || !bits || !rev) {}
-#endif
- return 0;
-}
-
-static char *v4l2_lu_palette(unsigned int fmt) {
- switch(fmt) {
-#if defined(V4L_OK) && HAVE_V4L2
- case V4L2_PIX_FMT_RGB332: return "RGB332";
- case V4L2_PIX_FMT_RGB555: return "RGB555";
- case V4L2_PIX_FMT_RGB565: return "RGB565";
- case V4L2_PIX_FMT_RGB555X: return "RGB555X";
- case V4L2_PIX_FMT_RGB565X: return "RGB565X";
- case V4L2_PIX_FMT_BGR24: return "BGR24";
- case V4L2_PIX_FMT_RGB24: return "RGB24";
- case V4L2_PIX_FMT_BGR32: return "BGR32";
- case V4L2_PIX_FMT_RGB32: return "RGB32";
- case V4L2_PIX_FMT_GREY: return "GREY";
- case V4L2_PIX_FMT_YVU410: return "YVU410";
- case V4L2_PIX_FMT_YVU420: return "YVU420";
- case V4L2_PIX_FMT_YUYV: return "YUYV";
- case V4L2_PIX_FMT_UYVY: return "UYVY";
- case V4L2_PIX_FMT_YUV422P: return "YUV422P";
- case V4L2_PIX_FMT_YUV411P: return "YUV411P";
- case V4L2_PIX_FMT_Y41P: return "Y41P";
- case V4L2_PIX_FMT_NV12: return "NV12";
- case V4L2_PIX_FMT_NV21: return "NV21";
- case V4L2_PIX_FMT_YUV410: return "YUV410";
- case V4L2_PIX_FMT_YUV420: return "YUV420";
- case V4L2_PIX_FMT_YYUV: return "YYUV";
- case V4L2_PIX_FMT_HI240: return "HI240";
- case V4L2_PIX_FMT_MJPEG: return "MJPEG";
- case V4L2_PIX_FMT_JPEG: return "JPEG";
- case V4L2_PIX_FMT_DV: return "DV";
- case V4L2_PIX_FMT_MPEG: return "MPEG";
-#endif
- default: return "unknown";
- }
-}
-
-static unsigned int v4l2_lu_palette_str(char *name, int *bits, int *rev) {
-#if defined(V4L_OK) && HAVE_V4L2
- if (!strcmp(name, "RGB1") || !strcmp(name, "RGB332")) {
- *bits = 8;
- *rev = 0;
- return V4L2_PIX_FMT_RGB332;
- } else if (!strcmp(name, "RGBO") || !strcmp(name, "RGB555")) {
- *bits = 16;
- *rev = 0;
- return V4L2_PIX_FMT_RGB555;
- } else if (!strcmp(name, "RGBP") || !strcmp(name, "RGB565")) {
- *bits = 16;
- *rev = 0;
- return V4L2_PIX_FMT_RGB565;
- } else if (!strcmp(name, "RGBQ") || !strcmp(name, "RGB555X")) {
- *bits = 16;
- *rev = 1;
- return V4L2_PIX_FMT_RGB555X;
- } else if (!strcmp(name, "RGBR") || !strcmp(name, "RGB565X")) {
- *bits = 16;
- *rev = 1;
- return V4L2_PIX_FMT_RGB565X;
- } else if (!strcmp(name, "BGR3") || !strcmp(name, "BGR24")) {
- *bits = 24;
- *rev = 1;
- return V4L2_PIX_FMT_BGR24;
- } else if (!strcmp(name, "RGB3") || !strcmp(name, "RGB24")) {
- *bits = 24;
- *rev = 0;
- return V4L2_PIX_FMT_RGB24;
- } else if (!strcmp(name, "BGR4") || !strcmp(name, "BGR32")) {
- *bits = 32;
- *rev = 1;
- return V4L2_PIX_FMT_BGR32;
- } else if (!strcmp(name, "RGB4") || !strcmp(name, "RGB32")) {
- *bits = 32;
- *rev = 0;
- return V4L2_PIX_FMT_RGB32;
- } else if (!strcmp(name, "GREY")) {
- *bits = 8;
- *rev = 0;
- return V4L2_PIX_FMT_GREY;
- }
-#else
- if (!name || !bits || !rev) {}
-#endif
- return 0;
-}
-
-static int v4l1_query(int fd, int v) {
-#ifdef V4L_OK
- unsigned int i;
-
- memset(&v4l1_capability, 0, sizeof(v4l1_capability));
- memset(&v4l1_channel, 0, sizeof(v4l1_channel));
- memset(&v4l1_tuner, 0, sizeof(v4l1_tuner));
- memset(&v4l1_picture, 0, sizeof(v4l1_picture));
- memset(&v4l1_window, 0, sizeof(v4l1_window));
-
- if (v) fprintf(stderr, "\nV4L_1 query:\n");
-#ifdef VIDIOCGCAP
- if (ioctl(fd, VIDIOCGCAP, &v4l1_capability) == -1) {
- perror("ioctl VIDIOCGCAP");
- fprintf(stderr, "\n");
- return 0;
- }
-#else
- return 0;
-#endif
- if (v) fprintf(stderr, "v4l-1 capability:\n");
- if (v) fprintf(stderr, " name: %s\n", v4l1_capability.name);
- if (v) fprintf(stderr, " channels: %d\n", v4l1_capability.channels);
- if (v) fprintf(stderr, " audios: %d\n", v4l1_capability.audios);
- if (v) fprintf(stderr, " maxwidth: %d\n", v4l1_capability.maxwidth);
- if (v) fprintf(stderr, " maxheight: %d\n", v4l1_capability.maxheight);
- if (v) fprintf(stderr, " minwidth: %d\n", v4l1_capability.minwidth);
- if (v) fprintf(stderr, " minheight: %d\n", v4l1_capability.minheight);
-
- for (i=0; (int) i < v4l1_capability.channels; i++) {
- char *type = "unknown";
- memset(&v4l1_channel, 0, sizeof(v4l1_channel));
- v4l1_channel.channel = i;
- if (ioctl(fd, VIDIOCGCHAN, &v4l1_channel) == -1) {
- perror("ioctl VIDIOCGCHAN");
- continue;
- }
- if (v4l1_channel.type == VIDEO_TYPE_TV) {
- type = "TV";
- } else if (v4l1_channel.type == VIDEO_TYPE_CAMERA) {
- type = "CAMERA";
- }
- if (v) fprintf(stderr, " channel[%d]: %s\ttuners: %d norm: %d type: %d %s\n",
- i, v4l1_channel.name, v4l1_channel.tuners, v4l1_channel.norm,
- v4l1_channel.type, type);
- }
-
- memset(&v4l1_tuner, 0, sizeof(v4l1_tuner));
- if (ioctl(fd, VIDIOCGTUNER, &v4l1_tuner) != -1) {
- char *mode = "unknown";
- if (v4l1_tuner.mode == VIDEO_MODE_PAL) {
- mode = "PAL";
- } else if (v4l1_tuner.mode == VIDEO_MODE_NTSC) {
- mode = "NTSC";
- } else if (v4l1_tuner.mode == VIDEO_MODE_SECAM) {
- mode = "SECAM";
- } else if (v4l1_tuner.mode == VIDEO_MODE_AUTO) {
- mode = "AUTO";
- }
-
- if (v) fprintf(stderr, " tuner[%d]: %s\tflags: 0x%x mode: %s\n",
- v4l1_tuner.tuner, v4l1_tuner.name, v4l1_tuner.flags, mode);
-
- }
-
- if (ioctl(fd, VIDIOCGPICT, &v4l1_picture) == -1) {
- perror("ioctl VIDIOCGCHAN");
- return 0;
- }
- if (v) fprintf(stderr, "v4l-1 picture:\n");
- if (v) fprintf(stderr, " brightness: %d\n", v4l1_picture.brightness);
- if (v) fprintf(stderr, " hue: %d\n", v4l1_picture.hue);
- if (v) fprintf(stderr, " colour: %d\n", v4l1_picture.colour);
- if (v) fprintf(stderr, " contrast: %d\n", v4l1_picture.contrast);
- if (v) fprintf(stderr, " whiteness: %d\n", v4l1_picture.whiteness);
- if (v) fprintf(stderr, " depth: %d\n", v4l1_picture.depth);
- if (v) fprintf(stderr, " palette: %d %s\n", v4l1_picture.palette,
- v4l1_lu_palette(v4l1_picture.palette));
-
- if (ioctl(fd, VIDIOCGWIN, &v4l1_window) == -1) {
- perror("ioctl VIDIOCGWIN");
- if (v) fprintf(stderr, "\n");
- return 0;
- }
- if (v) fprintf(stderr, "v4l-1 window:\n");
- if (v) fprintf(stderr, " x: %d\n", v4l1_window.x);
- if (v) fprintf(stderr, " y: %d\n", v4l1_window.y);
- if (v) fprintf(stderr, " width: %d\n", v4l1_window.width);
- if (v) fprintf(stderr, " height: %d\n", v4l1_window.height);
- if (v) fprintf(stderr, " chromakey: %d\n", v4l1_window.chromakey);
- if (v) fprintf(stderr, "\n");
-
- return 1;
-#else
- if (!fd || !v) {}
- return 0;
-#endif /* V4L_OK */
-
-}
-static int v4l2_query(int fd, int v) {
-#if defined(V4L_OK) && HAVE_V4L2
- unsigned int i;
-
- memset(&v4l2_capability, 0, sizeof(v4l2_capability));
- memset(&v4l2_input, 0, sizeof(v4l2_input));
- memset(&v4l2_tuner, 0, sizeof(v4l2_tuner));
- memset(&v4l2_fmtdesc, 0, sizeof(v4l2_fmtdesc));
- memset(&v4l2_format, 0, sizeof(v4l2_format));
-
- if (v) fprintf(stderr, "\nV4L_2 query:\n");
-#ifdef VIDIOC_QUERYCAP
- if (ioctl(fd, VIDIOC_QUERYCAP, &v4l2_capability) == -1) {
- perror("ioctl VIDIOC_QUERYCAP");
- if (v) fprintf(stderr, "\n");
- return 0;
- }
-#else
- return 0;
-#endif
-
- if (v) fprintf(stderr, "v4l-2 capability:\n");
- if (v) fprintf(stderr, " driver: %s\n", v4l2_capability.driver);
- if (v) fprintf(stderr, " card: %s\n", v4l2_capability.card);
- if (v) fprintf(stderr, " bus_info: %s\n", v4l2_capability.bus_info);
- if (v) fprintf(stderr, " version: %d\n", v4l2_capability.version);
- if (v) fprintf(stderr, " capabilities: %u\n", v4l2_capability.capabilities);
-
- for (i=0; ; i++) {
- memset(&v4l2_input, 0, sizeof(v4l2_input));
- v4l2_input.index = i;
- if (ioctl(fd, VIDIOC_ENUMINPUT, &v4l2_input) == -1) {
- break;
- }
- if (v) fprintf(stderr, " input[%d]: %s\ttype: %d tuner: %d\n",
- i, v4l2_input.name, v4l2_input.type, v4l2_input.tuner);
- }
- if (v4l2_capability.capabilities & V4L2_CAP_TUNER) {
- for (i=0; ; i++) {
- memset(&v4l2_tuner, 0, sizeof(v4l2_tuner));
- v4l2_tuner.index = i;
- if (ioctl(fd, VIDIOC_G_TUNER, &v4l2_tuner) == -1) {
- break;
- }
- if (v) fprintf(stderr, " tuner[%d]: %s\ttype: %d\n",
- i, v4l2_tuner.name, v4l2_tuner.type);
- }
- }
- if (v4l2_capability.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
- for (i=0; ; i++) {
- memset(&v4l2_fmtdesc, 0, sizeof(v4l2_fmtdesc));
- v4l2_fmtdesc.index = i;
- v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- if (ioctl(fd, VIDIOC_ENUM_FMT, &v4l2_fmtdesc) == -1) {
- break;
- }
- if (v) fprintf(stderr, " fmtdesc[%d]: %s\ttype: %d"
- " pixelformat: %d\n",
- i, v4l2_fmtdesc.description, v4l2_fmtdesc.type,
- v4l2_fmtdesc.pixelformat);
- }
- v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (ioctl(fd, VIDIOC_G_FMT, &v4l2_format) == -1) {
- perror("ioctl VIDIOC_G_FMT");
- } else {
- if (v) fprintf(stderr, " width: %d\n", v4l2_format.fmt.pix.width);
- if (v) fprintf(stderr, " height: %d\n", v4l2_format.fmt.pix.height);
- if (v) fprintf(stderr, " format: %u %s\n",
- v4l2_format.fmt.pix.pixelformat,
- v4l2_lu_palette(v4l2_format.fmt.pix.pixelformat));
- }
- }
-
- return 1;
-#else
- if (!fd || !v) {}
- return 0;
-#endif /* V4L_OK && HAVE_V4L2 */
-
-}
-
-static int open_dev(char *dev) {
- int dfd = -1;
- if (! dev) {
- return dfd;
- }
- dfd = open(dev, O_RDWR);
- if (dfd < 0) {
- rfbLog("failed to rawfb file: %s O_RDWR\n", dev);
- rfbLogPerror("open");
- dfd = open(dev, O_RDONLY);
- }
- if (dfd < 0) {
- rfbLog("failed to rawfb file: %s\n", dev);
- rfbLog("failed to rawfb file: %s O_RDONLY\n", dev);
- rfbLogPerror("open");
- }
- return dfd;
-}
-
-static char *guess_via_v4l(char *dev, int *fd) {
-#ifdef V4L_OK
- int dfd;
-
- if (*fd < 0) {
- dfd = open_dev(dev);
- *fd = dfd;
- }
- dfd = *fd;
- if (dfd < 0) {
- return NULL;
- }
- if (v4l1_cap < 0) {
- v4l1_cap = v4l1_query(dfd, 1);
- }
- if (v4l2_cap < 0) {
- v4l2_cap = v4l2_query(dfd, 1);
- }
-
- if (v4l2_cap) {
-#if HAVE_V4L2
- int g_w = v4l2_format.fmt.pix.width;
- int g_h = v4l2_format.fmt.pix.height;
- int g_d = 0, g_rev;
-
- if (v4l2_format.fmt.pix.pixelformat) {
- char *str = v4l2_lu_palette(v4l2_format.fmt.pix.pixelformat);
- if (strcmp(str, "unknown")) {
- v4l2_lu_palette_str(str, &g_d, &g_rev);
- }
- }
-
- if (g_w > 0 && g_h > 0 && g_d > 0) {
- char *atparms = (char *) malloc(200);
- char *pal = v4l2_lu_palette(v4l2_format.fmt.pix.pixelformat);
- sprintf(atparms, "%dx%dx%d", g_w, g_h, g_d);
- if (strstr(pal, "RGB555")) {
- strcat(atparms, ":7c00/3e0/1f");
- }
- *fd = dfd;
- return atparms;
- }
-#endif
- }
- if (v4l1_cap) {
- int g_w = v4l1_window.width;
- int g_h = v4l1_window.height;
- int g_d = v4l1_picture.depth;
- int g_rev;
- if (g_d == 0) {
- char *str = v4l1_lu_palette(v4l1_picture.palette);
- if (strcmp(str, "unknown")) {
- v4l1_lu_palette_str(str, &g_d, &g_rev);
- }
- }
-if (0) fprintf(stderr, "v4l1: %d %d %d\n", g_w, g_h, g_d);
- if (g_w > 0 && g_h > 0 && g_d > 0) {
- char *atparms = (char *) malloc(200);
- char *pal = v4l1_lu_palette(v4l1_picture.palette);
- fprintf(stderr, "palette: %s\n", pal);
- sprintf(atparms, "%dx%dx%d", g_w, g_h, g_d);
- if (strstr(pal, "RGB555")) {
- strcat(atparms, ":7c00/3e0/1f");
- }
- *fd = dfd;
- return atparms;
- }
- }
-
- /* failure */
- close(dfd);
- return NULL;
-#else
- if (!dev || !fd) {}
- return NULL;
-#endif
-}
-
-static char *guess_via_v4l_info(char *dev, int *fd) {
- char *atparms, *cmd;
- char line[1024], tmp[] = "/tmp/x11vnc-tmp.XXXXXX";
- FILE *out;
- int tmp_fd, len, rc, curr = 0;
- int g_w = 0, g_h = 0, g_b = 0, mask_rev = 0;
- char *g_fmt = NULL;
-
- if (*fd) {}
-
- /* v4l-info */
- if (no_external_cmds || !cmd_ok("v4l-info")) {
- rfbLog("guess_via_v4l_info: cannot run external "
- "command: v4l-info\n");
- return NULL;
- }
-
- if (strchr(dev, '\'')) {
- rfbLog("guess_via_v4l_info: bad dev string: %s\n", dev);
- return NULL;
- }
-
- tmp_fd = mkstemp(tmp);
- if (tmp_fd < 0) {
- return NULL;
- }
-
- len = strlen("v4l-info")+1+1+strlen(dev)+1+1+1+1+strlen(tmp)+1;
- cmd = (char *) malloc(len);
- rfbLog("guess_via_v4l_info running: v4l-info '%s'\n", dev);
- sprintf(cmd, "v4l-info '%s' > %s", dev, tmp);
-
- close(tmp_fd);
- close_exec_fds();
- rc = system(cmd);
- if (rc != 0) {
- unlink(tmp);
- return NULL;
- }
-
- out = fopen(tmp, "r");
- if (out == NULL) {
- unlink(tmp);
- return NULL;
- }
-
- curr = 0;
- while (fgets(line, 1024, out) != NULL) {
- char *lb = lblanks(line);
- if (strstr(line, "video capture") == line) {
- curr = C_VIDEO_CAPTURE;
- } else if (strstr(line, "picture") == line) {
- curr = C_PICTURE;
- } else if (strstr(line, "window") == line) {
- curr = C_WINDOW;
- }
-
-if (0) fprintf(stderr, "lb: %s", lb);
-
- if (curr == C_VIDEO_CAPTURE) {
- if (strstr(lb, "pixelformat ") == lb) {
- fprintf(stderr, "%s", line);
- } else if (strstr(lb, "fmt.pix.width ") == lb) {
- if (! g_w) {
- g_w = colon_n(line);
- }
- } else if (strstr(lb, "fmt.pix.height ") == lb) {
- if (! g_h) {
- g_h = colon_n(line);
- }
- } else if (strstr(lb, "fmt.pix.pixelformat ") == lb) {
- if (! g_fmt) {
- g_fmt = colon_tag(line);
- }
- }
- } else if (curr == C_PICTURE) {
- if (strstr(lb, "depth ") == lb) {
- if (! g_b) {
- g_b = colon_n(line);
- }
- } else if (strstr(lb, "palette ") == lb) {
- if (! g_fmt) {
- g_fmt = colon_str(line);
- }
- }
- } else if (curr == C_WINDOW) {
- if (strstr(lb, "width ") == lb) {
- if (! g_w) {
- g_w = colon_n(line);
- }
- } else if (strstr(lb, "height ") == lb) {
- if (! g_h) {
- g_h = colon_n(line);
- }
- }
- }
- }
- fclose(out);
- unlink(tmp);
-
- if (! g_w) {
- rfbLog("could not guess device width.\n");
- return NULL;
- }
- rfbLog("guessed device width: %d\n", g_w);
-
- if (! g_h) {
- rfbLog("could not guess device height.\n");
- return NULL;
- }
- rfbLog("guessed device height: %d\n", g_h);
-
- if (g_fmt) {
- rfbLog("guessed pixel fmt: %s\n", g_fmt);
- lookup_rgb(g_fmt, &g_b, &mask_rev);
- }
- if (! g_b) {
- rfbLog("could not guess device bpp.\n");
- return NULL;
- }
- rfbLog("guessed device bpp: %d\n", g_b);
-
- atparms = (char *) malloc(100);
- sprintf(atparms, "%dx%dx%d", g_w, g_h, g_b);
- return atparms;
-}
-
-static void parse_str(char *str, char **dev, char **settings, char **atparms) {
- char *p, *q, *s = NULL;
-
- q = strchr(str, '@');
- if (q && strlen(q+1) > 0) {
- /* ends @WxHXB... */
- *atparms = strdup(q+1);
- *q = '\0';
- }
-
- q = strchr(str, ':');
- if (q && strlen(q+1) > 0) {
- /* ends :br=N,w=N... */
- s = strdup(q+1);
- *settings = s;
- *q = '\0';
- }
-
- if (s != NULL) {
- /* see if fn=filename */
- q = strstr(s, "fn=");
- if (q) {
- q += strlen("fn=");
- p = strchr(q, ',');
- if (p) {
- *p = '\0';
- *dev = strdup(q);
- *p = ',';
- } else {
- *dev = strdup(q);
- }
- rfbLog("set video device to: '%s'\n", *dev);
- }
- }
-
- if (*dev == NULL) {
- 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);
- }
-}
-
-char *v4l_guess(char *str, int *fd) {
- char *dev = NULL, *settings = NULL, *atparms = NULL;
-
- parse_str(str, &dev, &settings, &atparms);
-
- init_freqs();
-
- v4l1_cap = -1;
- v4l2_cap = -1;
- *fd = -1;
-
- if (dev == NULL) {
- rfbLog("v4l_guess: could not find device in: %s\n", str);
- return NULL;
- }
-
- if (settings) {
- apply_settings(dev, settings, fd);
- }
-
- if (atparms) {
- /* use user's parameters. */
- char *t = (char *) malloc(5+strlen(dev)+1+strlen(atparms)+1);
- sprintf(t, "snap:%s@%s", dev, atparms);
- return t;
- }
-
- /* try to query the device for parameters. */
- atparms = guess_via_v4l(dev, fd);
- if (atparms == NULL) {
- /* try again with v4l-info(1) */
- atparms = guess_via_v4l_info(dev, fd);
- }
-
- if (atparms == NULL) {
- /* bad news */
- if (*fd >= 0) {
- close(*fd);
- }
- *fd = -1;
- return NULL;
- } else {
- char *t = (char *) malloc(5+strlen(dev)+1+strlen(atparms)+1);
- sprintf(t, "snap:%s@%s", dev, atparms);
- return t;
- }
-}
-
-static unsigned long lookup_freqtab(int sta) {
-
- if (sta >= CHANNEL_MAX) {
- return (unsigned long) sta;
- }
- if (sta < 0 || sta >= CHANNEL_MAX) {
- return 0;
- }
- return custom_freq[sta];
-}
-
-static unsigned long lookup_freq(int sta) {
- if (freqtab) {
- return lookup_freqtab(sta);
- }
- if (sta >= CHANNEL_MAX) {
- return (unsigned long) sta;
- }
- if (sta < 1 || sta > 125) {
- return 0;
- }
- return ntsc_cable[sta];
-}
-
-static int lookup_station(unsigned long freq) {
- int i;
- if (freqtab) {
- for (i = 0; i < CHANNEL_MAX; i++) {
-if (0) fprintf(stderr, "%lu %lu\n", freq, custom_freq[i]);
- if (freq == custom_freq[i]) {
- return i;
- }
- }
- } else {
- for (i = 1; i <= 125; i++) {
- if (freq == ntsc_cable[i]) {
- return i;
- }
- }
- }
- return 0;
-}
-
-static void init_freqtab(char *file) {
- char *p, *q, *dir, *file2;
- char line[1024], inc[1024];
- char *text, *str;
- int size = 0, maxn, extra, currn;
- FILE *in1, *in2;
- static int v = 1;
- if (quiet) {
- v = 0;
- }
-
- /* YUCK */
-
- dir = strdup(file);
- q = strrchr(dir, '/');
- if (q) {
- *(q+1) = '\0';
- } else {
- free(dir);
- dir = strdup("./");
- }
- file2 = (char *) malloc(strlen(dir) + 1024 + 1);
- in1 = fopen(file, "r");
- if (in1 == NULL) {
- rfbLog("error opening freqtab: %s\n", file);
- clean_up_exit(1);
- }
- if (v) fprintf(stderr, "loading frequencies from: %s\n", file);
- while (fgets(line, 1024, in1) != NULL) {
- char *lb;
- char line2[1024];
- size += strlen(line);
- lb = lblanks(line);
- if (strstr(lb, "#include") == lb &&
- sscanf(lb, "#include %s", inc) == 1) {
- char *q, *s = inc;
- if (s[0] == '"') {
- s++;
- }
- q = strrchr(s, '"');
- if (q) {
- *q = '\0';
- }
- sprintf(file2, "%s%s", dir, s);
- in2 = fopen(file2, "r");
- if (in2 == NULL) {
- rfbLog("error opening freqtab include: %s %s\n", line, file2);
- clean_up_exit(1);
- }
- if (v) fprintf(stderr, "loading frequencies from: %s\n", file2);
- while (fgets(line2, 1024, in2) != NULL) {
- size += strlen(line2);
- }
- fclose(in2);
- }
- }
- fclose(in1);
-
- size = 4*(size + 10000);
-
- text = (char *) malloc(size);
-
- text[0] = '\0';
-
- in1 = fopen(file, "r");
- if (in1 == NULL) {
- rfbLog("error opening freqtab: %s\n", file);
- clean_up_exit(1);
- }
- while (fgets(line, 1024, in1) != NULL) {
- char *lb;
- char line2[1024];
- lb = lblanks(line);
- if (lb[0] == '[') {
- strcat(text, lb);
- } else if (strstr(lb, "freq")) {
- strcat(text, lb);
- } else if (strstr(lb, "#include") == lb &&
- sscanf(lb, "#include %s", inc) == 1) {
- char *lb2;
- char *q, *s = inc;
- if (s[0] == '"') {
- s++;
- }
- q = strrchr(s, '"');
- if (q) {
- *q = '\0';
- }
- sprintf(file2, "%s%s", dir, s);
- in2 = fopen(file2, "r");
- if (in2 == NULL) {
- rfbLog("error opening freqtab include: %s %s\n", line, file2);
- clean_up_exit(1);
- }
- while (fgets(line2, 1024, in2) != NULL) {
- lb2 = lblanks(line2);
- if (lb2[0] == '[') {
- strcat(text, lb2);
- } else if (strstr(lb2, "freq")) {
- strcat(text, lb2);
- }
- if ((int) strlen(text) > size/2) {
- break;
- }
- }
- fclose(in2);
- }
- if ((int) strlen(text) > size/2) {
- break;
- }
- }
- fclose(in1);
-
- if (0) fprintf(stderr, "%s", text);
-
- str = strdup(text);
- p = strtok(str, "\n");
- maxn = -1;
- extra = 0;
- while (p) {
- if (p[0] == '[') {
- int ok = 1;
- q = p+1;
- while (*q) {
- if (*q == ']') {
- break;
- }
- if (! isdigit((unsigned char) (*q))) {
- if (0) fprintf(stderr, "extra: %s\n", p);
- extra++;
- ok = 0;
- break;
- }
- q++;
- }
- if (ok) {
- int n;
- if (sscanf(p, "[%d]", &n) == 1) {
- if (n > maxn) {
- maxn = n;
- }
- if (0) fprintf(stderr, "maxn: %d %d\n", maxn, n);
- }
- }
-
- }
- p = strtok(NULL, "\n");
- }
- free(str);
-
- str = strdup(text);
- p = strtok(str, "\n");
- extra = 0;
- currn = 0;
- if (v) fprintf(stderr, "\nname\tstation\tfreq (KHz)\n");
- while (p) {
- if (p[0] == '[') {
- int ok = 1;
- strncpy(line, p, 100);
- q = p+1;
- while (*q) {
- if (*q == ']') {
- break;
- }
- if (! isdigit((unsigned char) (*q))) {
- extra++;
- currn = maxn + extra;
- ok = 0;
- break;
- }
- q++;
- }
- if (ok) {
- int n;
- if (sscanf(p, "[%d]", &n) == 1) {
- currn = n;
- }
- }
- }
- if (strstr(p, "freq") && (q = strchr(p, '=')) != NULL) {
- int n;
- q = lblanks(q+1);
- if (sscanf(q, "%d", &n) == 1) {
- if (currn >= 0 && currn < CHANNEL_MAX) {
- if (v) fprintf(stderr, "%s\t%d\t%d\n", line, currn, n);
- custom_freq[currn] = (unsigned long) n;
- if (last_freq == 0) {
- last_freq = custom_freq[currn];
- }
- }
- }
- }
- p = strtok(NULL, "\n");
- }
- if (v) fprintf(stderr, "\n");
- v = 0;
- free(str);
- free(text);
- free(dir);
- free(file2);
-}
-
-static void init_freqs(void) {
- int i;
- for (i=0; i<CHANNEL_MAX; i++) {
- ntsc_cable[i] = 0;
- custom_freq[i] = 0;
- }
-
- init_ntsc_cable();
- last_freq = ntsc_cable[1];
-
- if (freqtab) {
- init_freqtab(freqtab);
- }
-}
-
-static void init_ntsc_cable(void) {
- ntsc_cable[1] = 73250;
- ntsc_cable[2] = 55250;
- ntsc_cable[3] = 61250;
- ntsc_cable[4] = 67250;
- ntsc_cable[5] = 77250;
- ntsc_cable[6] = 83250;
- ntsc_cable[7] = 175250;
- ntsc_cable[8] = 181250;
- ntsc_cable[9] = 187250;
- ntsc_cable[10] = 193250;
- ntsc_cable[11] = 199250;
- ntsc_cable[12] = 205250;
- ntsc_cable[13] = 211250;
- ntsc_cable[14] = 121250;
- ntsc_cable[15] = 127250;
- ntsc_cable[16] = 133250;
- ntsc_cable[17] = 139250;
- ntsc_cable[18] = 145250;
- ntsc_cable[19] = 151250;
- ntsc_cable[20] = 157250;
- ntsc_cable[21] = 163250;
- ntsc_cable[22] = 169250;
- ntsc_cable[23] = 217250;
- ntsc_cable[24] = 223250;
- ntsc_cable[25] = 229250;
- ntsc_cable[26] = 235250;
- ntsc_cable[27] = 241250;
- ntsc_cable[28] = 247250;
- ntsc_cable[29] = 253250;
- ntsc_cable[30] = 259250;
- ntsc_cable[31] = 265250;
- ntsc_cable[32] = 271250;
- ntsc_cable[33] = 277250;
- ntsc_cable[34] = 283250;
- ntsc_cable[35] = 289250;
- ntsc_cable[36] = 295250;
- ntsc_cable[37] = 301250;
- ntsc_cable[38] = 307250;
- ntsc_cable[39] = 313250;
- ntsc_cable[40] = 319250;
- ntsc_cable[41] = 325250;
- ntsc_cable[42] = 331250;
- ntsc_cable[43] = 337250;
- ntsc_cable[44] = 343250;
- ntsc_cable[45] = 349250;
- ntsc_cable[46] = 355250;
- ntsc_cable[47] = 361250;
- ntsc_cable[48] = 367250;
- ntsc_cable[49] = 373250;
- ntsc_cable[50] = 379250;
- ntsc_cable[51] = 385250;
- ntsc_cable[52] = 391250;
- ntsc_cable[53] = 397250;
- ntsc_cable[54] = 403250;
- ntsc_cable[55] = 409250;
- ntsc_cable[56] = 415250;
- ntsc_cable[57] = 421250;
- ntsc_cable[58] = 427250;
- ntsc_cable[59] = 433250;
- ntsc_cable[60] = 439250;
- ntsc_cable[61] = 445250;
- ntsc_cable[62] = 451250;
- ntsc_cable[63] = 457250;
- ntsc_cable[64] = 463250;
- ntsc_cable[65] = 469250;
- ntsc_cable[66] = 475250;
- ntsc_cable[67] = 481250;
- ntsc_cable[68] = 487250;
- ntsc_cable[69] = 493250;
- ntsc_cable[70] = 499250;
- ntsc_cable[71] = 505250;
- ntsc_cable[72] = 511250;
- ntsc_cable[73] = 517250;
- ntsc_cable[74] = 523250;
- ntsc_cable[75] = 529250;
- ntsc_cable[76] = 535250;
- ntsc_cable[77] = 541250;
- ntsc_cable[78] = 547250;
- ntsc_cable[79] = 553250;
- ntsc_cable[80] = 559250;
- ntsc_cable[81] = 565250;
- ntsc_cable[82] = 571250;
- ntsc_cable[83] = 577250;
- ntsc_cable[84] = 583250;
- ntsc_cable[85] = 589250;
- ntsc_cable[86] = 595250;
- ntsc_cable[87] = 601250;
- ntsc_cable[88] = 607250;
- ntsc_cable[89] = 613250;
- ntsc_cable[90] = 619250;
- ntsc_cable[91] = 625250;
- ntsc_cable[92] = 631250;
- ntsc_cable[93] = 637250;
- ntsc_cable[94] = 643250;
- ntsc_cable[95] = 91250;
- ntsc_cable[96] = 97250;
- ntsc_cable[97] = 103250;
- ntsc_cable[98] = 109250;
- ntsc_cable[99] = 115250;
- ntsc_cable[100] = 649250;
- ntsc_cable[101] = 655250;
- ntsc_cable[102] = 661250;
- ntsc_cable[103] = 667250;
- ntsc_cable[104] = 673250;
- ntsc_cable[105] = 679250;
- ntsc_cable[106] = 685250;
- ntsc_cable[107] = 691250;
- ntsc_cable[108] = 697250;
- ntsc_cable[109] = 703250;
- ntsc_cable[110] = 709250;
- ntsc_cable[111] = 715250;
- ntsc_cable[112] = 721250;
- ntsc_cable[113] = 727250;
- ntsc_cable[114] = 733250;
- ntsc_cable[115] = 739250;
- ntsc_cable[116] = 745250;
- ntsc_cable[117] = 751250;
- ntsc_cable[118] = 757250;
- ntsc_cable[119] = 763250;
- ntsc_cable[120] = 769250;
- ntsc_cable[121] = 775250;
- ntsc_cable[122] = 781250;
- ntsc_cable[123] = 787250;
- ntsc_cable[124] = 793250;
- ntsc_cable[125] = 799250;
-}
-
diff --git a/x11vnc/v4l.h b/x11vnc/v4l.h
deleted file mode 100644
index 1cae722..0000000
--- a/x11vnc/v4l.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_V4L_H
-#define _X11VNC_V4L_H
-
-/* -- v4l.h -- */
-extern char *v4l_guess(char *str, int *fd);
-extern void v4l_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
-extern void v4l_pointer_command(int mask, int x, int y, rfbClientPtr client);
-
-
-#endif /* _X11VNC_V4L_H */
diff --git a/x11vnc/win_utils.c b/x11vnc/win_utils.c
deleted file mode 100644
index 7aa9b4c..0000000
--- a/x11vnc/win_utils.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- win_utils.c -- */
-
-#include "x11vnc.h"
-#include "xinerama.h"
-#include "winattr_t.h"
-#include "cleanup.h"
-#include "xwrappers.h"
-#include "connections.h"
-#include "xrandr.h"
-#include "macosx.h"
-
-winattr_t *stack_list = NULL;
-int stack_list_len = 0;
-int stack_list_num = 0;
-
-
-Window parent_window(Window win, char **name);
-int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet);
-Bool xtranslate(Window src, Window dst, int src_x, int src_y, int *dst_x,
- int *dst_y, Window *child, int bequiet);
-int get_window_size(Window win, int *w, int *h);
-void snapshot_stack_list(int free_only, double allowed_age);
-int get_boff(void);
-int get_bwin(void);
-void update_stack_list(void);
-Window query_pointer(Window start);
-unsigned int mask_state(void);
-int pick_windowid(unsigned long *num);
-Window descend_pointer(int depth, Window start, char *name_info, int len);
-void id_cmd(char *cmd);
-
-
-Window parent_window(Window win, char **name) {
-#if !NO_X11
- Window r, parent;
- Window *list;
- XErrorHandler old_handler;
- unsigned int nchild;
- int rc;
-#endif
-
- if (name != NULL) {
- *name = NULL;
- }
- RAWFB_RET(None)
-#if NO_X11
- nox11_exit(1);
- if (!name || !win) {}
- return None;
-#else
-
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
- rc = XQueryTree_wr(dpy, win, &r, &parent, &list, &nchild);
- XSetErrorHandler(old_handler);
-
- if (! rc || trapped_xerror) {
- trapped_xerror = 0;
- return None;
- }
- trapped_xerror = 0;
-
- if (list) {
- XFree_wr(list);
- }
- if (parent && name) {
- XFetchName(dpy, parent, name);
- }
- return parent;
-#endif /* NO_X11 */
-}
-
-/* trapping utility to check for a valid window: */
-int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet) {
- XWindowAttributes attr, *pattr;
-#if !NO_X11
- XErrorHandler old_handler;
- int ok = 0;
-#endif
-
- if (attr_ret == NULL) {
- pattr = &attr;
- } else {
- pattr = attr_ret;
- }
-
- if (win == None) {
- return 0;
- }
-
-#ifdef MACOSX
- if (macosx_console) {
- return macosx_valid_window(win, attr_ret);
- }
-#endif
-
- RAWFB_RET(0)
-
-#if NO_X11
- nox11_exit(1);
- if (!win || !attr_ret || !bequiet) {}
- return 0;
-#else
-
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
- if (XGetWindowAttributes(dpy, win, pattr)) {
- ok = 1;
- }
- if (trapped_xerror && trapped_xerror_event) {
- if (! quiet && ! bequiet) {
- rfbLog("valid_window: trapped XError: %s (0x%lx)\n",
- xerror_string(trapped_xerror_event), win);
- }
- ok = 0;
- }
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
-
- return ok;
-#endif /* NO_X11 */
-}
-
-Bool xtranslate(Window src, Window dst, int src_x, int src_y, int *dst_x,
- int *dst_y, Window *child, int bequiet) {
- XErrorHandler old_handler = NULL;
- Bool ok = False;
-
- RAWFB_RET(False)
-#if NO_X11
- nox11_exit(1);
- if (!src || !dst || !src_x || !src_y || !dst_x || !dst_y || !child || !bequiet) {}
- if (!old_handler || !ok) {}
- return False;
-#else
-
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
- if (XTranslateCoordinates(dpy, src, dst, src_x, src_y, dst_x,
- dst_y, child)) {
- ok = True;
- }
- if (trapped_xerror && trapped_xerror_event) {
- if (! quiet && ! bequiet) {
- rfbLog("xtranslate: trapped XError: %s (0x%lx)\n",
- xerror_string(trapped_xerror_event), src);
- }
- ok = False;
- }
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
-
- return ok;
-#endif /* NO_X11 */
-}
-
-int get_window_size(Window win, int *w, int *h) {
- XWindowAttributes attr;
- /* valid_window? */
- if (valid_window(win, &attr, 1)) {
- *w = attr.width;
- *h = attr.height;
- return 1;
- } else {
- return 0;
- }
-}
-
-/*
- * For use in the -wireframe stuff, save the stacking order of the direct
- * children of the root window. Ideally done before we send ButtonPress
- * to the X server.
- */
-void snapshot_stack_list(int free_only, double allowed_age) {
- static double last_snap = 0.0, last_free = 0.0;
- double now;
- int num, rc, i, j;
- unsigned int ui;
- Window r, w;
- Window *list;
-
- if (! stack_list) {
- stack_list = (winattr_t *) malloc(256*sizeof(winattr_t));
- stack_list_num = 0;
- stack_list_len = 256;
- }
-
- dtime0(&now);
- if (free_only) {
- /* we really don't free it, just reset to zero windows */
- stack_list_num = 0;
- last_free = now;
- return;
- }
-
- if (stack_list_num && now < last_snap + allowed_age) {
- return;
- }
-
- stack_list_num = 0;
- last_free = now;
-
-#ifdef MACOSX
- if (! macosx_console) {
- RAWFB_RET_VOID
- }
-#else
- RAWFB_RET_VOID
-#endif
-
-#if NO_X11 && !defined(MACOSX)
- num = rc = i = j = 0; /* compiler warnings */
- ui = 0;
- r = w = None;
- list = NULL;
- return;
-#else
-
- X_LOCK;
- /* no need to trap error since rootwin */
- rc = XQueryTree_wr(dpy, rootwin, &r, &w, &list, &ui);
- num = (int) ui;
-
- if (! rc) {
- stack_list_num = 0;
- last_free = now;
- last_snap = 0.0;
- X_UNLOCK;
- return;
- }
-
- last_snap = now;
- if (num > stack_list_len + blackouts) {
- int n = 2*num;
- free(stack_list);
- stack_list = (winattr_t *) malloc(n*sizeof(winattr_t));
- stack_list_len = n;
- }
- j = 0;
- for (i=0; i<num; i++) {
- stack_list[j].win = list[i];
- stack_list[j].fetched = 0;
- stack_list[j].valid = 0;
- stack_list[j].time = now;
- j++;
- }
- for (i=0; i<blackouts; i++) {
- stack_list[j].win = get_boff() + 1;
- stack_list[j].fetched = 1;
- stack_list[j].valid = 1;
- stack_list[j].x = blackr[i].x1;
- stack_list[j].y = blackr[i].y1;
- stack_list[j].width = blackr[i].x2 - blackr[i].x1;
- stack_list[j].height = blackr[i].y2 - blackr[i].y1;
- stack_list[j].time = now;
- stack_list[j].map_state = IsViewable;
- stack_list[j].rx = -1;
- stack_list[j].ry = -1;
- j++;
-
-if (0) fprintf(stderr, "blackr: %d %dx%d+%d+%d\n", i,
- stack_list[j-1].width, stack_list[j-1].height,
- stack_list[j-1].x, stack_list[j-1].y);
-
- }
- stack_list_num = num + blackouts;
- if (debug_wireframe > 1) {
- fprintf(stderr, "snapshot_stack_list: num=%d len=%d\n",
- stack_list_num, stack_list_len);
- }
-
- XFree_wr(list);
- X_UNLOCK;
-#endif /* NO_X11 */
-}
-
-int get_boff(void) {
- if (macosx_console) {
- return 0x1000000;
- } else {
- return 0;
- }
-}
-
-int get_bwin(void) {
- return 10;
-}
-
-void update_stack_list(void) {
- int k;
- double now;
- XWindowAttributes attr;
- int boff, bwin;
-
- if (! stack_list) {
- return;
- }
- if (! stack_list_num) {
- return;
- }
-
- dtime0(&now);
-
- boff = get_boff();
- bwin = get_bwin();
-
- X_LOCK;
- for (k=0; k < stack_list_num; k++) {
- Window win = stack_list[k].win;
- if (win != None && boff <= (int) win && (int) win < boff + bwin) {
- ; /* special, blackout */
- } else if (!valid_window(win, &attr, 1)) {
- stack_list[k].valid = 0;
- } else {
- stack_list[k].valid = 1;
- stack_list[k].x = attr.x;
- stack_list[k].y = attr.y;
- stack_list[k].width = attr.width;
- stack_list[k].height = attr.height;
- stack_list[k].border_width = attr.border_width;
- stack_list[k].depth = attr.depth;
- stack_list[k].class = attr.class;
- stack_list[k].backing_store = attr.backing_store;
- stack_list[k].map_state = attr.map_state;
-
- /* root_x, root_y not used for stack_list usage: */
- stack_list[k].rx = -1;
- stack_list[k].ry = -1;
- }
- stack_list[k].fetched = 1;
- stack_list[k].time = now;
- }
- X_UNLOCK;
-if (0) fprintf(stderr, "update_stack_list[%d]: %.4f %.4f\n", stack_list_num, now - x11vnc_start, dtime(&now));
-}
-
-Window query_pointer(Window start) {
- int rx, ry;
-#if !NO_X11
- Window r, c; /* compiler warnings */
- int wx, wy;
- unsigned int mask;
-#endif
-
-#ifdef MACOSX
- if (macosx_console) {
- macosx_get_cursor_pos(&rx, &ry);
- }
-#endif
-
- RAWFB_RET(None)
-
-#if NO_X11
- if (!start) { rx = ry = 0; }
- return None;
-#else
- if (start == None) {
- start = rootwin;
- }
- if (XQueryPointer_wr(dpy, start, &r, &c, &rx, &ry, &wx, &wy, &mask)) {
- return c;
- } else {
- return None;
- }
-#endif /* NO_X11 */
-}
-
-unsigned int mask_state(void) {
-#if NO_X11
- RAWFB_RET(0)
- return 0;
-#else
- Window r, c;
- int rx, ry, wx, wy;
- unsigned int mask;
-
- RAWFB_RET(0)
-
- if (XQueryPointer_wr(dpy, rootwin, &r, &c, &rx, &ry, &wx, &wy, &mask)) {
- return mask;
- } else {
- return 0;
- }
-#endif /* NO_X11 */
-}
-
-int pick_windowid(unsigned long *num) {
- char line[512];
- int ok = 0, n = 0, msec = 10, secmax = 15;
- FILE *p;
-
- RAWFB_RET(0)
-
- if (use_dpy) {
- set_env("DISPLAY", use_dpy);
- }
- /* id */
- if (no_external_cmds || !cmd_ok("id")) {
- rfbLogEnable(1);
- rfbLog("cannot run external commands in -nocmds mode:\n");
- rfbLog(" \"%s\"\n", "xwininfo");
- rfbLog(" exiting.\n");
- clean_up_exit(1);
- }
- close_exec_fds();
- p = popen("xwininfo", "r");
-
- if (! p) {
- return 0;
- }
-
- fprintf(stderr, "\n");
- fprintf(stderr, " Please select the window for x11vnc to poll\n");
- fprintf(stderr, " by clicking the mouse in that window.\n");
- fprintf(stderr, "\n");
-
- while (msec * n++ < 1000 * secmax) {
- unsigned long tmp;
- char *q;
- fd_set set;
- struct timeval tv;
-
- if (screen && screen->clientHead) {
- /* they may be doing the pointer-pick thru vnc: */
- int nfds;
- tv.tv_sec = 0;
- tv.tv_usec = msec * 1000;
- FD_ZERO(&set);
- FD_SET(fileno(p), &set);
-
- nfds = select(fileno(p)+1, &set, NULL, NULL, &tv);
-
- if (nfds == 0 || nfds < 0) {
- /*
- * select timedout or error.
- * note this rfbPE takes about 30ms too:
- */
- rfbPE(-1);
- XFlush_wr(dpy);
- continue;
- }
- }
-
- if (fgets(line, 512, p) == NULL) {
- break;
- }
- q = strstr(line, " id: 0x");
- if (q) {
- q += 5;
- if (sscanf(q, "0x%lx ", &tmp) == 1) {
- ok = 1;
- *num = tmp;
- fprintf(stderr, " Picked: 0x%lx\n\n", tmp);
- break;
- }
- }
- }
- pclose(p);
- return ok;
-}
-
-Window descend_pointer(int depth, Window start, char *name_info, int len) {
-#if NO_X11
- RAWFB_RET(None)
- if (!depth || !start || !name_info || !len) {}
- return None;
-#else
- Window r, c, clast = None;
- int i, rx, ry, wx, wy;
- int written = 0, filled = 0;
- char *store = NULL;
- unsigned int m;
- static XClassHint *classhint = NULL;
- static char *nm_cache = NULL;
- static int nm_cache_len = 0;
- static Window prev_start = None;
-
- RAWFB_RET(None)
-
- if (! classhint) {
- classhint = XAllocClassHint();
- }
-
- if (! nm_cache) {
- nm_cache = (char *) malloc(1024);
- nm_cache_len = 1024;
- nm_cache[0] = '\0';
- }
- if (name_info && nm_cache_len < len) {
- if (nm_cache) {
- free(nm_cache);
- }
- nm_cache_len = 2*len;
- nm_cache = (char *) malloc(nm_cache_len);
- }
-
- if (name_info) {
- if (start != None && start == prev_start) {
- store = NULL;
- strncpy(name_info, nm_cache, len);
- } else {
- store = name_info;
- name_info[0] = '\0';
- }
- }
-
- if (start != None) {
- c = start;
- if (name_info) {
- prev_start = start;
- }
- } else {
- c = rootwin;
- }
-
- for (i=0; i<depth; i++) {
- clast = c;
- if (store && ! filled) {
- char *name;
- if (XFetchName(dpy, clast, &name) && name != NULL) {
- int l = strlen(name);
- if (written + l+2 < len) {
- strcat(store, "^^");
- written += 2;
- strcat(store, name);
- written += l;
- } else {
- filled = 1;
- }
- XFree_wr(name);
- }
- }
- if (store && classhint && ! filled) {
- classhint->res_name = NULL;
- classhint->res_class = NULL;
- if (XGetClassHint(dpy, clast, classhint)) {
- int l = 0;
- if (classhint->res_class) {
- l += strlen(classhint->res_class);
- }
- if (classhint->res_name) {
- l += strlen(classhint->res_name);
- }
- if (written + l+4 < len) {
- strcat(store, "##");
- if (classhint->res_class) {
- strcat(store,
- classhint->res_class);
- }
- strcat(store, "++");
- if (classhint->res_name) {
- strcat(store,
- classhint->res_name);
- }
- written += l+4;
- } else {
- filled = 1;
- }
- if (classhint->res_class) {
- XFree_wr(classhint->res_class);
- }
- if (classhint->res_name) {
- XFree_wr(classhint->res_name);
- }
- }
- }
- if (! XQueryPointer_wr(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &m)) {
- break;
- }
- if (! c) {
- break;
- }
- }
- if (start != None && name_info) {
- strncpy(nm_cache, name_info, nm_cache_len);
- }
-
- return clast;
-#endif /* NO_X11 */
-}
-
-void id_cmd(char *cmd) {
- int rc, dx = 0, dy = 0, dw = 0, dh = 0;
- int x0, y0, w0, h0;
- int x, y, w, h, do_move = 0, do_resize = 0;
- int disp_x = DisplayWidth(dpy, scr);
- int disp_y = DisplayHeight(dpy, scr);
- Window win = subwin;
- XWindowAttributes attr;
- XErrorHandler old_handler = NULL;
- Window twin;
-
- if (!cmd || !strcmp(cmd, "")) {
- return;
- }
- if (strstr(cmd, "win=") == cmd) {
- if (! scan_hexdec(cmd + strlen("win="), &win)) {
- rfbLog("id_cmd: incorrect win= hex/dec number: %s\n", cmd);
- return;
- } else {
- char *q = strchr(cmd, ':');
- if (!q) {
- rfbLog("id_cmd: incorrect win=...: hex/dec number: %s\n", cmd);
- return;
- }
- rfbLog("id_cmd:%s set window id to 0x%lx\n", cmd, win);
- cmd = q+1;
- }
- }
- if (!win) {
- rfbLog("id_cmd:%s not in sub-window mode or no win=0xNNNN.\n", cmd);
- return;
- }
-#if !NO_X11
- X_LOCK;
- if (!valid_window(win, &attr, 1)) {
- X_UNLOCK;
- return;
- }
- w0 = w = attr.width;
- h0 = h = attr.height;
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
- XTranslateCoordinates(dpy, win, rootwin, 0, 0, &x, &y, &twin);
- x0 = x;
- y0 = y;
- if (strstr(cmd, "move:") == cmd) {
- if (sscanf(cmd, "move:%d%d", &dx, &dy) == 2) {
- x = x + dx;
- y = y + dy;
- do_move = 1;
- }
- } else if (strstr(cmd, "resize:") == cmd) {
- if (sscanf(cmd, "resize:%d%d", &dw, &dh) == 2) {
- w = w + dw;
- h = h + dh;
- do_move = 1;
- do_resize = 1;
- }
- } else if (strstr(cmd, "geom:") == cmd) {
- if (parse_geom(cmd+strlen("geom:"), &w, &h, &x, &y, disp_x, disp_y)) {
- do_move = 1;
- do_resize = 1;
- if (w <= 0) {
- w = w0;
- }
- if (h <= 0) {
- h = h0;
- }
- if (scaling && getenv("X11VNC_APPSHARE_ACTIVE")) {
- x /= scale_fac_x;
- y /= scale_fac_y;
- }
- }
- } else if (!strcmp(cmd, "raise")) {
- rc = XRaiseWindow(dpy, win);
- rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
- } else if (!strcmp(cmd, "lower")) {
- rc = XLowerWindow(dpy, win);
- rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
- } else if (!strcmp(cmd, "map")) {
- rc= XMapRaised(dpy, win);
- rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
- } else if (!strcmp(cmd, "unmap")) {
- rc= XUnmapWindow(dpy, win);
- rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
- } else if (!strcmp(cmd, "iconify")) {
- rc= XIconifyWindow(dpy, win, scr);
- rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
- } else if (strstr(cmd, "wm_name:") == cmd) {
- rc= XStoreName(dpy, win, cmd+strlen("wm_name:"));
- rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
- } else if (strstr(cmd, "icon_name:") == cmd) {
- rc= XSetIconName(dpy, win, cmd+strlen("icon_name:"));
- rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
- } else if (!strcmp(cmd, "wm_delete")) {
- XClientMessageEvent ev;
- memset(&ev, 0, sizeof(ev));
- ev.type = ClientMessage;
- ev.send_event = True;
- ev.display = dpy;
- ev.window = win;
- ev.message_type = XInternAtom(dpy, "WM_PROTOCOLS", False);
- ev.format = 32;
- ev.data.l[0] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- rc = XSendEvent(dpy, win, False, 0, (XEvent *) &ev);
- rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
- } else {
- rfbLog("id_cmd:%s unrecognized command.\n", cmd);
- }
- if (do_move || do_resize) {
- if (w >= disp_x) {
- w = disp_x - 4;
- }
- if (h >= disp_y) {
- h = disp_y - 4;
- }
- if (w < 1) {
- w = 1;
- }
- if (h < 1) {
- h = 1;
- }
- if (x + w > disp_x) {
- x = disp_x - w - 1;
- }
- if (y + h > disp_y) {
- y = disp_y - h - 1;
- }
- if (x < 0) {
- x = 1;
- }
- if (y < 0) {
- y = 1;
- }
- rc = 0;
- rc += XMoveWindow(dpy, win, x, y);
- off_x = x;
- off_y = y;
-
- rc += XResizeWindow(dpy, win, w, h);
-
- rfbLog("id_cmd:%s rc=%d dx=%d dy=%d dw=%d dh=%d %dx%d+%d+%d -> %dx%d+%d+%d\n",
- cmd, rc, dx, dy, dw, dh, w0, h0, x0, y0, w, h, x, h);
- }
- XSync(dpy, False);
- XSetErrorHandler(old_handler);
- if (trapped_xerror) {
- rfbLog("id_cmd:%s trapped_xerror.\n", cmd);
- }
- trapped_xerror = 0;
- if (do_resize) {
- rfbLog("id_cmd:%s calling check_xrandr_event.\n", cmd);
- check_xrandr_event("id_cmd");
- }
- X_UNLOCK;
-#endif
-}
-
diff --git a/x11vnc/win_utils.h b/x11vnc/win_utils.h
deleted file mode 100644
index 0b99165..0000000
--- a/x11vnc/win_utils.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_WIN_UTILS_H
-#define _X11VNC_WIN_UTILS_H
-
-/* -- win_utils.h -- */
-#include "xinerama.h"
-#include "winattr_t.h"
-
-extern winattr_t *stack_list;
-extern int stack_list_len;
-extern int stack_list_num;
-
-extern Window parent_window(Window win, char **name);
-extern int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet);
-extern Bool xtranslate(Window src, Window dst, int src_x, int src_y, int *dst_x,
- int *dst_y, Window *child, int bequiet);
-extern int get_window_size(Window win, int *w, int *h);
-extern void snapshot_stack_list(int free_only, double allowed_age);
-extern int get_boff(void);
-extern int get_bwin(void);
-extern void update_stack_list(void);
-extern Window query_pointer(Window start);
-extern unsigned int mask_state(void);
-extern int pick_windowid(unsigned long *num);
-extern Window descend_pointer(int depth, Window start, char *name_info, int len);
-extern void id_cmd(char *cmd);
-
-#endif /* _X11VNC_WIN_UTILS_H */
diff --git a/x11vnc/winattr_t.h b/x11vnc/winattr_t.h
deleted file mode 100644
index 24ea81b..0000000
--- a/x11vnc/winattr_t.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_WINATTR_T_H
-#define _X11VNC_WINATTR_T_H
-
-/* -- winattr_t.h -- */
-
-typedef struct winattr {
- Window win;
- int fetched;
- int valid;
- int x, y;
- int width, height;
- int border_width;
- int depth;
- int class;
- int backing_store;
- int map_state;
- int rx, ry;
- double time;
- double bs_time;
- double su_time;
- double vis_obs_time;
- double vis_unobs_time;
- int bs_x, bs_y, bs_w, bs_h;
- int su_x, su_y, su_w, su_h;
- Window above;
- short vis_state;
- short selectinput;
- short map_cnt;
- short unmap_cnt;
- short vis_cnt;
- short create_cnt;
-} winattr_t;
-
-#endif /* _X11VNC_WINATTR_T_H */
diff --git a/x11vnc/x11vnc.1 b/x11vnc/x11vnc.1
deleted file mode 100644
index d4dd0a2..0000000
--- a/x11vnc/x11vnc.1
+++ /dev/null
@@ -1,6962 +0,0 @@
-.\" This file was automatically generated from x11vnc -help output.
-.TH X11VNC "1" "December 2010" "x11vnc " "User Commands"
-.SH NAME
-x11vnc - allow VNC connections to real X11 displays
- version: 0.9.13, lastmod: 2010-12-27
-.SH SYNOPSIS
-.B x11vnc
-[OPTION]...
-.SH DESCRIPTION
-.PP
-Typical usage is:
-.IP
-Run this command in a shell on the remote machine "far-host"
-with X session you wish to view:
-.IP
-x11vnc -display :0
-.IP
-Then run this in another window on the machine you are sitting at:
-.IP
-vncviewer far-host:0
-.PP
-Once x11vnc establishes connections with the X11 server and starts listening
-as a VNC server it will print out a string: PORT=XXXX where XXXX is typically
-5900 (the default VNC server port). One would next run something like
-this on the local machine: "vncviewer hostname:N" where "hostname" is
-the name of the machine running x11vnc and N is XXXX - 5900, i.e. usually
-"vncviewer hostname:0".
-.PP
-By default x11vnc will not allow the screen to be shared and it will exit
-as soon as the client disconnects. See \fB-shared\fR and \fB-forever\fR below to override
-these protections. See the FAQ for details how to tunnel the VNC connection
-through an encrypted channel such as
-.IR ssh (1).
-In brief:
-.IP
-ssh \fB-t\fR \fB-L\fR 5900:localhost:5900 far-host 'x11vnc \fB-localhost\fR \fB-display\fR :0'
-.PP
-% vncviewer -encodings 'copyrect tight zrle hextile' localhost:0
-.PP
-Also, use of a VNC password (-rfbauth or \fB-passwdfile)\fR is strongly recommended.
-.PP
-For additional info see: http://www.karlrunge.com/x11vnc/
-and http://www.karlrunge.com/x11vnc/faq.html
-.PP
-Config file support: if the file $HOME/.x11vncrc exists then each line in
-it is treated as a single command line option. Disable with \fB-norc.\fR For
-each option name, the leading character "-" is not required. E.g. a line
-that is either "forever" or "\fB-forever\fR" may be used and are equivalent.
-Likewise "wait 100" or "\fB-wait\fR \fI100\fR" are acceptable and equivalent lines.
-The "#" character comments out to the end of the line in the usual way
-(backslash it for a literal). Leading and trailing whitespace is trimmed off.
-Lines may be continued with a "\\" as the last character of a line (it
-becomes a space character).
-.PP
-.SH OPTIONS
-
-.PP
-\fB-display\fR \fIdisp\fR
-.IP
-X11 server display to connect to, usually :0. The X
-server process must be running on same machine and
-support MIT-SHM. Equivalent to setting the DISPLAY
-environment variable to \fIdisp\fR.
-.IP
-See the description below of the "\fB-display\fR \fIWAIT:...\fR"
-extensions, where alias "\fB-find\fR" will find the user's
-display automatically, and "\fB-create\fR" will create a
-Xvfb session if no session is found.
-.PP
-\fB-auth\fR \fIfile\fR
-.IP
-Set the X authority file to be \fIfile\fR, equivalent to
-setting the XAUTHORITY environment variable to \fIfile\fR
-before startup. Same as \fB-xauth\fR file. See
-.IR Xsecurity (7)
-,
-.IR xauth (1)
-man pages for more info.
-.IP
-Use '-auth guess' to have x11vnc use its \fB-findauth\fR
-mechanism (described below) to try to guess the
-XAUTHORITY filename and use it.
-.IP
-XDM/GDM/KDM: if you are running x11vnc as root and want
-to find the XAUTHORITY before anyone has logged into an
-X session yet, use: x11vnc \fB-env\fR FD_XDM=1 \fB-auth\fR guess ...
-(This will also find the XAUTHORITY if a user is already
-logged into the X session.) When running as root,
-FD_XDM=1 will be tried if the initial \fB-auth\fR guess fails.
-.PP
-\fB-N\fR
-.IP
-If the X display is :N, try to set the VNC display to
-also be :N This just sets the \fB-rfbport\fR option to 5900+N
-The program will exit immediately if that port is not
-available. The \fB-N\fR option only works with normal \fB-display\fR
-usage, e.g. :0 or :8, \fB-N\fR is ignored in the \fB-display\fR
-WAIT:..., \fB-create,\fR \fB-find,\fR \fB-svc,\fR \fB-redirect,\fR etc modes.
-.PP
-\fB-autoport\fR \fIn\fR
-.IP
-Automatically probe for a free VNC port starting at n.
-The default is to start probing at 5900. Use this to
-stay away from other VNC servers near 5900.
-.PP
-\fB-rfbport\fR \fIstr\fR
-.IP
-The VNC port to listen on (a LibVNCServer option), e.g.
-5900, 5901, etc. If specified as "\fB-rfbport\fR \fIPROMPT\fR"
-then the x11vnc \fB-gui\fR is used to prompt the user to
-enter the port number.
-.PP
-\fB-6\fR
-.IP
-IPv6 listening support. In addition to IPv4, the
-IPv6 address is listened on for incoming connections.
-The same port number as IPv4 is used.
-.IP
-NOTE: This x11vnc binary was compiled to have the
-"-6" IPv6 listening mode ENABLED by default (CPPFLAGS
-\fB-DX11VNC_LISTEN6=1).\fR So to disable IPv6 listening mode
-you MUST supply the "\fB-no6\fR" option (see below.)
-.IP
-The "-6" mode works for both normal connections and
-\fB-ssl\fR encrypted ones. Nearly everything is supported
-for the IPv6 case, but there are a few exceptions.
-See \fB-stunnel\fR for its IPv6 support.
-.IP
-Currently, for absolutely everything to work correctly
-the machine may need to have some IPv4 support, at the
-least for the loopback interface. However, for nearly
-all usage modes no IPv4 support is required. See \fB-nopiv4.\fR
-.IP
-If you have trouble compiling or running in IPv6 mode,
-set \fB-DX11VNC_IPV6=0\fR in CPPFLAGS when configuring to
-disable IPv6 support.
-.PP
-\fB-no6\fR
-.IP
-Disable IPv6 listening support (only useful if the
-"-6" mode is compiled in to be the default; see the
-X11VNC_LISTEN6 description above under "-6".)
-.PP
-\fB-noipv6\fR
-.IP
-Do not try to use IPv6 for any listening or connecting
-sockets. This includes both the listening service
-port(s) and outgoing connections from \fB-connect,\fR
-\fB-connect_or_exit,\fR or \fB-proxy.\fR Use this if you are having
-problems due to IPv6.
-.PP
-\fB-noipv4\fR
-.IP
-Do not try to use IPv4 for any listening or connecting
-sockets. This is mainly for exploring the behavior of
-x11vnc on an IPv6-only system, but may have other uses.
-.PP
-\fB-reopen\fR
-.IP
-If the X server connection is disconnected, try to
-reopen the X display (up to one time.) This is of use
-for display managers like GDM (KillInitClients option)
-that kill x11vnc just after the user logs into the
-X session. Note: the reopened state may be unstable.
-Set X11VNC_REOPEN_DISPLAY=n to reopen n times and
-set X11VNC_REOPEN_SLEEP_MAX to the number of seconds,
-default 10, to keep trying to reopen the display (once
-per second.)
-.IP
-Update: as of 0.9.9, x11vnc tries to automatically avoid
-being killed by the display manager by delaying creating
-windows or using XFIXES. So you shouldn't need to use
-KillInitClients=false as long as you log in quickly
-enough (within 45 seconds of connecting.) You can
-disable this by setting X11VNC_AVOID_WINDOWS=never.
-You can also set it to the number of seconds to delay.
-.PP
-\fB-reflect\fR \fIhost:N\fR
-.IP
-Instead of connecting to and polling an X display,
-connect to the remote VNC server host:N and be a
-reflector/repeater for it. This is useful for trying
-to manage the case of many simultaneous VNC viewers
-(e.g. classroom broadcasting) where, e.g. you put
-a repeater on each network switch, etc, to improve
-performance by distributing the load and network
-traffic. Implies \fB-shared\fR (use \fB-noshared\fR as a later
-option to disable). See the discussion below under
-\fB-rawfb\fR vnc:host:N for more details.
-.PP
-\fB-id\fR \fIwindowid\fR
-.IP
-Show the X window corresponding to \fIwindowid\fR not
-the entire display. New windows like popup menus,
-transient toplevels, etc, may not be seen or may be
-clipped. Disabling SaveUnders or BackingStore in the
-X server may help show them. x11vnc may crash if the
-window is initially partially obscured, changes size,
-is iconified, etc. Some steps are taken to avoid this
-and the \fB-xrandr\fR mechanism is used to track resizes. Use
-.IR xwininfo (1)
-to get the window id, or use "\fB-id\fR \fIpick\fR"
-to have x11vnc run
-.IR xwininfo (1)
-for you and extract
-the id. The \fB-id\fR option is useful for exporting very
-simple applications (e.g. the current view on a webcam).
-.PP
-\fB-sid\fR \fIwindowid\fR
-.IP
-As \fB-id,\fR but instead of using the window directly it
-shifts a root view to it: this shows SaveUnders menus,
-etc, although they will be clipped if they extend beyond
-the window.
-.PP
-\fB-appshare\fR
-.IP
-Simple application sharing based on the \fB-id/-sid\fR
-mechanism. Every new toplevel window that the
-application creates induces a new viewer window via
-a reverse connection. The \fB-id/-sid\fR and \fB-connect\fR
-options are required. Run 'x11vnc \fB-appshare\fR \fB-help'\fR
-for more info.
-.PP
-\fB-clip\fR \fIWxH+X+Y\fR
-.IP
-Only show the sub-region of the full display that
-corresponds to the rectangle geometry with size WxH and
-offset +X+Y. The VNC display has size WxH (i.e. smaller
-than the full display). This also works for \fB-id/-sid\fR
-mode where the offset is relative to the upper left
-corner of the selected window. An example use of this
-option would be to split a large (e.g. Xinerama) display
-into two parts to be accessed via separate viewers by
-running a separate x11vnc on each part.
-.IP
-Use '-clip xinerama0' to clip to the first xinerama
-sub-screen (if xinerama is active). xinerama1 for the
-2nd sub-screen, etc. This way you don't need to figure
-out the WxH+X+Y of the desired xinerama sub-screen.
-screens are sorted in increasing distance from the
-(0,0) origin (I.e. not the Xserver's order).
-.PP
-\fB-flashcmap\fR
-.IP
-In 8bpp indexed color, let the installed colormap flash
-as the pointer moves from window to window (slow).
-Also try the \fB-8to24\fR option to avoid flash altogether.
-.PP
-\fB-shiftcmap\fR \fIn\fR
-.IP
-Rare problem, but some 8bpp displays use less than 256
-colorcells (e.g. 16-color grayscale, perhaps the other
-bits are used for double buffering) *and* also need to
-shift the pixels values away from 0, .., ncells. \fIn\fR
-indicates the shift to be applied to the pixel values.
-To see the pixel values set DEBUG_CMAP=1 to print out
-a colormap histogram. Example: \fB-shiftcmap\fR 240
-.PP
-\fB-notruecolor\fR
-.IP
-For 8bpp displays, force indexed color (i.e. a colormap)
-even if it looks like 8bpp TrueColor (rare problem).
-.PP
-\fB-advertise_truecolor\fR
-.IP
-If the X11 display is indexed color, lie to clients
-when they first connect by telling them it is truecolor.
-To workaround RealVNC: inPF has colourMap but not 8bpp
-Use '-advertise_truecolor reset' to reset client fb too.
-.PP
-\fB-visual\fR \fIn\fR
-.IP
-This option probably does not do what you think.
-It simply *forces* the visual used for the framebuffer;
-this may be a bad thing... (e.g. messes up colors or
-cause a crash). It is useful for testing and for some
-workarounds. n may be a decimal number, or 0x hex.
-Run
-.IR xdpyinfo (1)
-for the values. One may also use
-"TrueColor", etc. see <X11/X.h> for a list. If the
-string ends in ":m" then for better or for worse
-the visual depth is forced to be m. You may want to
-use \fB-noshm\fR when using this option (so XGetImage may
-automatically translate the pixel data).
-.PP
-\fB-overlay\fR
-.IP
-Handle multiple depth visuals on one screen, e.g. 8+24
-and 24+8 overlay visuals (the 32 bits per pixel are
-packed with 8 for PseudoColor and 24 for TrueColor).
-.IP
-Currently \fB-overlay\fR only works on Solaris via
-.IR XReadScreen (3X11)
-and IRIX using
-.IR XReadDisplay (3).
-On Solaris there is a problem with image "bleeding"
-around transient popup menus (but not for the menu
-itself): a workaround is to disable SaveUnders
-by passing the "\fB-su\fR" argument to Xsun (in
-/etc/dt/config/Xservers).
-.IP
-Use \fB-overlay\fR as a workaround for situations like these:
-Some legacy applications require the default visual to
-be 8bpp (8+24), or they will use 8bpp PseudoColor even
-when the default visual is depth 24 TrueColor (24+8).
-In these cases colors in some windows will be incorrect
-in x11vnc unless \fB-overlay\fR is used. Another use of
-\fB-overlay\fR is to enable showing the exact mouse cursor
-shape (details below).
-.IP
-Under \fB-overlay,\fR performance will be somewhat slower
-due to the extra image transformations required.
-For optimal performance do not use \fB-overlay,\fR but rather
-configure the X server so that the default visual is
-depth 24 TrueColor and try to have all apps use that
-visual (e.g. some apps have \fB-use24\fR or \fB-visual\fR options).
-.PP
-\fB-overlay_nocursor\fR
-.IP
-Sets \fB-overlay,\fR but does not try to draw the exact mouse
-cursor shape using the overlay mechanism.
-.PP
-\fB-8to24\fR \fI[opts]\fR
-.IP
-Try this option if \fB-overlay\fR is not supported on your
-OS, and you have a legacy 8bpp app that you want to
-view on a multi-depth display with default depth 24
-(and is 32 bpp) OR have a default depth 8 display with
-depth 24 overlay windows for some apps. This option
-may not work on all X servers and hardware (tested
-on XFree86/Xorg mga driver and Xsun). The "opts"
-string is not required and is described below.
-.IP
-This mode enables a hack where x11vnc monitors windows
-within 3 levels from the root window. If it finds
-any that are 8bpp it extracts the indexed color
-pixel values using XGetImage() and then applies a
-transformation using the colormap(s) to create TrueColor
-RGB values that it in turn inserts into bits 1-24 of
-the framebuffer. This creates a depth 24 "view"
-of the display that is then exported via VNC.
-.IP
-Conversely, for default depth 8 displays, the depth
-24 regions are read by XGetImage() and everything is
-transformed and inserted into a depth 24 TrueColor
-framebuffer.
-.IP
-Note that even if there are *no* depth 24 visuals or
-windows (i.e. pure 8bpp), this mode is potentially
-an improvement over \fB-flashcmap\fR because it avoids the
-flashing and shows each window in the correct color.
-.IP
-This method works OK, but may still have bugs and it
-does hog resources. If there are multiple 8bpp windows
-using different colormaps, one may have to iconify all
-but one for the colors to be correct.
-.IP
-There may be painting errors for clipping and switching
-between windows of depths 8 and 24. Heuristics are
-applied to try to minimize the painting errors. One can
-also press 3 Alt_L's in a row to refresh the screen
-if the error does not repair itself. Also the option
-\fB-fixscreen\fR 8=3.0 or \fB-fixscreen\fR V=3.0 may be used to
-periodically refresh the screen at the cost of bandwidth
-(every 3 sec for this example).
-.IP
-The [opts] string can contain the following settings.
-Multiple settings are separated by commas.
-.IP
-For for some X servers with default depth 24 a
-speedup may be achieved via the option "nogetimage".
-This enables a scheme were XGetImage() is not used
-to retrieve the 8bpp data. Instead, it assumes that
-the 8bpp data is in bits 25-32 of the 32bit X pixels.
-There is no requirement that the X server should put
-the data there for our poll requests, but some do and
-so the extra steps to retrieve it can be skipped.
-Tested with mga driver with XFree86/Xorg. For the
-default depth 8 case this option is ignored.
-.IP
-To adjust how often XGetImage() is used to poll the
-non-default visual regions for changes, use the option
-"poll=t" where "t" is a floating point time.
-(default: 0.05)
-.IP
-Setting the option "level2" will limit the search
-for non-default visual windows to two levels from the
-root window. Do this on slow machines where you know
-the window manager only imposes one extra window between
-the app window and the root window.
-.IP
-Also for very slow machines use "cachewin=t"
-where t is a floating point amount of time to cache
-XGetWindowAttributes results. E.g. cachewin=5.0.
-This may lead to the windows being unnoticed for this
-amount of time when deiconifying, painting errors, etc.
-.IP
-While testing on a very old SS20 these options gave
-tolerable response: \fB-8to24\fR poll=0.2,cachewin=5.0. For
-this machine \fB-overlay\fR is supported and gives better
-response.
-.IP
-Debugging for this mode can be enabled by setting
-"dbg=1", "dbg=2", or "dbg=3".
-.PP
-\fB-24to32\fR
-.IP
-Very rare problem: if the framebuffer (X display
-or \fB-rawfb)\fR is 24bpp instead of the usual 32bpp, then
-dynamically transform the pixels to 32bpp. This will be
-slower, but can be used to work around problems where
-VNC viewers cannot handle 24bpp (e.g. "main: setPF:
-not 8, 16 or 32 bpp?"). See the FAQ for more info.
-.IP
-In the case of \fB-rawfb\fR mode, the pixels are directly
-modified by inserting a 0 byte to pad them out to 32bpp.
-For X displays, a kludge is done that is equivalent to
-"\fB-noshm\fR \fI\fB-visual\fR TrueColor:32\fR". (If better performance
-is needed for the latter, feel free to ask).
-.PP
-\fB-scale\fR \fIfraction\fR
-.IP
-Scale the framebuffer by factor \fIfraction\fR. Values
-less than 1 shrink the fb, larger ones expand it. Note:
-the image may not be sharp and response may be slower.
-If \fIfraction\fR contains a decimal point "." it
-is taken as a floating point number, alternatively
-the notation "m/n" may be used to denote fractions
-exactly, e.g. \fB-scale\fR 2/3
-.IP
-To scale asymmetrically in the horizontal and vertical
-directions, specify a WxH geometry to stretch to:
-e.g. '-scale 1024x768', or also '-scale 0.9x0.75'
-.IP
-Scaling Options: can be added after \fIfraction\fR via
-":", to supply multiple ":" options use commas.
-If you just want a quick, rough scaling without
-blending, append ":nb" to \fIfraction\fR (e.g. \fB-scale\fR
-1/3:nb). No blending is the default for 8bpp indexed
-color, to force blending for this case use ":fb".
-.IP
-To disable \fB-scrollcopyrect\fR and \fB-wirecopyrect\fR under
-\fB-scale\fR use ":nocr". If you need to to enable them use
-":cr" or specify them explicitly on the command line.
-If a slow link is detected, ":nocr" may be applied
-automatically. Default: :cr
-.IP
-More esoteric options: for compatibility with vncviewers
-the scaled width is adjusted to be a multiple of 4:
-to disable this use ":n4". ":in" use interpolation
-scheme even when shrinking, ":pad" pad scaled width
-and height to be multiples of scaling denominator
-(e.g. 3 for 2/3).
-.PP
-\fB-geometry\fR \fIWxH\fR
-.IP
-Same as \fB-scale\fR WxH
-.PP
-\fB-scale_cursor\fR \fIfrac\fR
-.IP
-By default if \fB-scale\fR is supplied the cursor shape is
-scaled by the same factor. Depending on your usage,
-you may want to scale the cursor independently of the
-screen or not at all. If you specify \fB-scale_cursor\fR
-the cursor will be scaled by that factor. When using
-\fB-scale\fR mode to keep the cursor at its "natural" size
-use "\fB-scale_cursor\fR \fI1\fR". Most of the ":" scaling
-options apply here as well.
-.PP
-\fB-viewonly\fR
-.IP
-All VNC clients can only watch (default off).
-.PP
-\fB-shared\fR
-.IP
-VNC display is shared, i.e. more than one viewer can
-connect at the same time (default off).
-.PP
-\fB-once\fR
-.IP
-Exit after the first successfully connected viewer
-disconnects, opposite of \fB-forever.\fR This is the Default.
-.PP
-\fB-forever\fR
-.IP
-Keep listening for more connections rather than exiting
-as soon as the first client(s) disconnect. Same as \fB-many\fR
-.IP
-To get the standard non-shared VNC behavior where when
-a new VNC client connects the existing VNC client is
-dropped use: \fB-nevershared\fR \fB-forever\fR This method can
-also be used to guard against hung TCP connections that
-do not go away.
-.PP
-\fB-loop\fR
-.IP
-Create an outer loop restarting the x11vnc process
-whenever it terminates. \fB-bg\fR and \fB-inetd\fR are ignored
-in this mode (however see \fB-loopbg\fR below).
-.IP
-Useful for continuing even if the X server terminates
-and restarts (at that moment the process will need
-permission to reconnect to the new X server of course).
-.IP
-Use, e.g., \fB-loop100\fR to sleep 100 millisecs between
-restarts, etc. Default is 2000ms (i.e. 2 secs) Use,
-e.g. \fB-loop300,5\fR to sleep 300 ms and only loop 5 times.
-.IP
-If \fB-loopbg\fR (plus any numbers) is specified instead,
-the "\fB-bg\fR" option is implied and the mode approximates
-.IR inetd (8)
-usage to some degree. In this case when
-it goes into the background any listening sockets
-(i.e. ports 5900, 5800) are closed, so the next one
-in the loop can use them. This mode will only be of
-use if a VNC client (the only client for that process)
-is already connected before the process goes into the
-background, for example, usage of \fB-display\fR WAIT:..,
-\fB-svc,\fR and \fB-connect\fR can make use of this "poor man's"
-inetd mode. The default wait time is 500ms in this
-mode. This usage could use useful: \fB-svc\fR \fB-bg\fR \fB-loopbg\fR
-.PP
-\fB-timeout\fR \fIn\fR
-.IP
-Exit unless a client connects within the first n seconds
-after startup.
-.IP
-If there have been no connection attempts after n
-seconds x11vnc exits immediately. If a client is
-trying to connect but has not progressed to the normal
-operating state, x11vnc gives it a few more seconds
-to finish and exits if it does not make it to the
-normal state.
-.IP
-For reverse connections via \fB-connect\fR or \fB-connect_or_exit\fR
-a timeout of n seconds will be set for all reverse
-connects. If the connect timeout alarm goes off,
-x11vnc will exit immediately.
-.PP
-\fB-sleepin\fR \fIn\fR
-.IP
-At startup sleep n seconds before proceeding (e.g. to
-allow redirs and listening clients to start up)
-.IP
-If a range is given: '-sleepin min-max', a random value
-between min and max is slept. E.g. '-sleepin 0-20' and
-\'-sleepin 10-30'. Floats are allowed too.
-.PP
-\fB-inetd\fR
-.IP
-Launched by
-.IR inetd (8):
-stdio instead of listening socket.
-Note: if you are not redirecting stderr to a log file
-(via shell 2> or \fB-o\fR option) you MUST also specify the \fB-q\fR
-option, otherwise the stderr goes to the viewer which
-will cause it to abort. Specifying both \fB-inetd\fR and \fB-q\fR
-and no \fB-o\fR will automatically close the stderr.
-.PP
-\fB-tightfilexfer\fR
-.IP
-Enable the TightVNC file transfer extension. Note that
-that when the \fB-viewonly\fR option is supplied all file
-transfers are disabled. Also clients that log in
-viewonly cannot transfer files. However, if the remote
-control mechanism is used to change the global or
-per-client viewonly state the filetransfer permissions
-will NOT change.
-.IP
-IMPORTANT: please understand if \fB-tightfilexfer\fR 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 \fB-users\fR option, then
-VNC Viewers that connect are able to do filetransfer
-reads and writes as *root*.
-.IP
-Also, tightfilexfer is disabled in \fB-unixpw\fR mode.
-.PP
-\fB-ultrafilexfer\fR
-.IP
-Note: to enable UltraVNC filetransfer and to get it to
-work you probably need to supply these LibVNCServer
-options: "\fB-rfbversion\fR \fI3.6 \fB-permitfiletransfer\fR"\fR
-"\fB-ultrafilexfer\fR" is an alias for this combination.
-.IP
-IMPORTANT: please understand if \fB-ultrafilexfer\fR 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 \fB-users\fR option, then
-VNC Viewers that connect are able to do filetransfer
-reads and writes as *root*.
-.IP
-Note that sadly you cannot do both \fB-tightfilexfer\fR and
-\fB-ultrafilexfer\fR at the same time because the latter
-requires setting the version to 3.6 and tightvnc will
-not do filetransfer when it sees that version number.
-.PP
-\fB-http\fR
-.IP
-Instead of using \fB-httpdir\fR (see below) to specify
-where the Java vncviewer applet is, have x11vnc try
-to *guess* where the directory is by looking relative
-to the program location and in standard locations
-(/usr/local/share/x11vnc/classes, etc). Under \fB-ssl\fR or
-\fB-stunnel\fR the ssl classes subdirectory is sought.
-.PP
-\fB-http_ssl\fR
-.IP
-As \fB-http,\fR but force lookup for ssl classes subdir.
-.IP
-Note that for HTTPS, single-port Java applet delivery
-you can set X11VNC_HTTPS_DOWNLOAD_WAIT_TIME to the
-max number of seconds to wait for the applet download
-to finish. The default is 15.
-.PP
-\fB-avahi\fR
-.IP
-Use the Avahi/mDNS ZeroConf protocol to advertise
-this VNC server to the local network. (Related terms:
-Rendezvous, Bonjour). Depending on your setup, you
-may need to start avahi-daemon and open udp port 5353
-in your firewall.
-.IP
-You can set X11VNC_AVAHI_NAME, X11VNC_AVAHI_HOST,
-and/or X11VNC_AVAHI_PORT environment variables
-to override the default values. For example:
-\fB-env\fR X11VNC_AVAHI_NAME=wally
-.IP
-If the avahi API cannot be found at build time, a helper
-program like avahi-
-.IR publish (1)
-or dns-
-.IR sd (1)
-will be tried
-.PP
-\fB-mdns\fR
-.IP
-Same as \fB-avahi.\fR
-.PP
-\fB-zeroconf\fR
-.IP
-Same as \fB-avahi.\fR
-.PP
-\fB-connect\fR \fIstring\fR
-.IP
-For use with "vncviewer -listen" reverse connections.
-If \fIstring\fR has the form "host" or "host:port"
-the connection is made once at startup.
-.IP
-Use commas for a list of host's and host:port's.
-E.g. \fB-connect\fR host1,host2 or host1:0,host2:5678.
-Note that to reverse connect to multiple hosts at the
-same time you will likely need to also supply: \fB-shared\fR
-.IP
-Note that unlike most vnc servers, x11vnc will require a
-password for reverse as well as for forward connections.
-(provided password auth has been enabled, \fB-rfbauth,\fR etc)
-If you do not want to require a password for reverse
-connections set X11VNC_REVERSE_CONNECTION_NO_AUTH=1 in
-your environment before starting x11vnc.
-.IP
-If \fIstring\fR contains "/" it is instead interpreted
-as a file to periodically check for new hosts.
-The first line is read and then the file is truncated.
-Be careful about the location of this file if x11vnc
-is running as root (e.g. via
-.IR gdm (1)
-, etc).
-.IP
-Repeater mode: Some services provide an intermediate
-"vnc repeater": http://www.uvnc.com/addons/repeater.html
-(and also http://koti.mbnet.fi/jtko/ for linux port)
-that acts as a proxy/gateway. Modes like these require
-an initial string to be sent for the reverse connection
-before the VNC protocol is started. Here are the ways
-to do this:
-.IP
-\fB-connect\fR pre=some_string+host:port
-\fB-connect\fR pre128=some_string+host:port
-\fB-connect\fR repeater=ID:1234+host:port
-\fB-connect\fR repeater=23.45.67.89::5501+host:port
-.IP
-SSVNC notation is also supported:
-.IP
-\fB-connect\fR repeater://host:port+ID:1234
-.IP
-As with normal \fB-connect\fR usage, if the repeater port is
-not supplied 5500 is assumed.
-.IP
-The basic idea is between the special tag, e.g. "pre="
-and "+" is the pre-string to be sent. Note that in
-this case host:port is the repeater server, NOT the
-vnc viewer. Somehow the pre-string tells the repeater
-server how to find the vnc viewer and connect you to it.
-.IP
-In the case pre=some_string+host:port, "some_string"
-is simply sent. In the case preNNN=some_string+host:port
-"some_string" is sent in a null padded buffer of
-length NNN. repeater= is the same as pre250=, this is
-the ultravnc repeater buffer size.
-.IP
-Strings like "\\n" and "\\r", etc. are expanded to
-newline and carriage return. "\\c" is expanded to
-"," since the connect string is comma separated.
-.IP
-See also the \fB-proxy\fR option below for additional ways
-to plumb reverse connections.
-.IP
-Reverse SSL: using \fB-connect\fR in \fB-ssl\fR mode makes x11vnc
-act as an SSL client (initiates SSL connection) rather
-than an SSL server. The idea is x11vnc might be
-connecting to stunnel on the viewer side with the
-viewer in listening mode. If you do not want this
-behavior, use \fB-env\fR X11VNC_DISABLE_SSL_CLIENT_MODE=1.
-With this the viewer side can act as the SSL client
-as it normally does for forward connections.
-.IP
-Reverse SSL Repeater mode: This will work, but note
-that if the VNC Client does any sort of a 'Fetch Cert'
-action before connecting, then the Repeater will
-likely drop the connection and both sides will need
-to restart. Consider the use of \fB-connect_or_exit\fR
-and \fB-loop300,2\fR to have x11vnc reconnect once to the
-repeater after the fetch. You will probably also want
-to supply \fB-sslonly\fR to avoid x11vnc thinking the delay
-in response means the connection is VeNCrypt. The env
-var X11VNC_DISABLE_SSL_CLIENT_MODE=1 discussed above
-may also be useful (i.e. the viewer can do a forward
-connection as it normally does.)
-.IP
-IPv6: as of x11vnc 0.9.10 the \fB-connect\fR option should
-connect to IPv6 hosts properly. If there are problems
-you can disable IPv6 by setting \fB-DX11VNC_IPV6=0\fR
-in CPPFLAGS when configuring. If there problems
-connecting to IPv6 hosts consider a relay like the
-included inet6to4 script or the \fB-proxy\fR option.
-.PP
-\fB-connect_or_exit\fR \fIstr\fR
-.IP
-As with \fB-connect,\fR except if none of the reverse
-connections succeed, then x11vnc shuts down immediately
-.IP
-An easier to type alias for this option is '-coe'
-.IP
-By the way, if you do not want x11vnc to listen on
-ANY interface use \fB-rfbport\fR 0 which is handy for the
-\fB-connect_or_exit\fR mode.
-.PP
-\fB-proxy\fR \fIstring\fR
-.IP
-Use proxy in string (e.g. host:port) as a proxy for
-making reverse connections (-connect or \fB-connect_or_exit\fR
-options).
-.IP
-Web proxies are supported, but note by default most of
-them only support destination connections to ports 443
-or 563, so this might not be very useful (the viewer
-would need to listen on that port or the router would
-have to do a port redirection).
-.IP
-A web proxy may be specified by either "host:port"
-or "http://host:port" (the port is required even if
-it is the common choices 80 or 8080)
-.IP
-SOCKS4, SOCKS4a, and SOCKS5 are also supported.
-SOCKS proxies normally do not have restrictions on the
-destination port number.
-.IP
-Use a format like this: socks://host:port or
-socks5://host:port. Note that ssh \fB-D\fR does not support
-SOCKS4a, so use socks5://. For socks:// SOCKS4 is used
-on a numerical IP and "localhost", otherwise SOCKS4a
-is used (and so the proxy tries to do the DNS lookup).
-.IP
-An experimental mode is "\fB-proxy\fR \fIhttp://host:port/...\fR"
-Note the "/" after the port that distinguishes it from
-a normal web proxy. The port must be supplied even if
-it is the default 80. For this mode a GET is done to
-the supplied URL with the string host=H&port=P appended.
-H and P will be the \fB-connect\fR reverse connect host
-and port. Use the string "__END__" to disable the
-appending. The basic idea here is that maybe some cgi
-script provides the actual viewer hookup and tunnelling.
-How to actually achieve this within cgi, php, etc. is
-not clear... A custom web server or apache module
-would be straight-forward.
-.IP
-Another experimental mode is "\fB-proxy\fR \fIssh://user@host\fR"
-in which case a SSH tunnel is used for the proxying.
-"user@" is not needed unless your unix username is
-different on "host". For a non-standard SSH port
-use ssh://user@host:port. If proxies are chained (see
-next paragraph) then the ssh one must be the first one.
-If ssh-agent is not active, then the ssh password needs
-to be entered in the terminal where x11vnc is running.
-Examples:
-.IP
-\fB-connect\fR localhost:0 \fB-proxy\fR ssh://me@friends-pc:2222
-.IP
-\fB-connect\fR snoopy:0 \fB-proxy\fR ssh://ssh.company.com
-.IP
-Multiple proxies may be chained together in case one
-needs to ricochet off of a number of hosts to finally
-reach the VNC viewer. Up to 3 may be chained, separate
-them by commas in the order they are to be connected to.
-E.g.: http://host1:port1,socks5://host2:port2 or three
-like: first,second,third
-.IP
-IPv6: as of x11vnc 0.9.10 the \fB-proxy\fR option should
-connect to IPv6 hosts properly. If there are problems
-you can disable IPv6 by setting \fB-DX11VNC_IPV6=0\fR
-in CPPFLAGS when configuring. If there problems
-connecting to IPv6 hosts consider a relay like the
-included inet6to4 script.
-.PP
-\fB-vncconnect,\fR \fB-novncconnect\fR
-.IP
-Monitor the VNC_CONNECT X property set by the standard
-VNC program
-.IR vncconnect (1).
-When the property is
-set to "host" or "host:port" establish a reverse
-connection. Using
-.IR xprop (1)
-instead of vncconnect may
-work (see the FAQ). The \fB-remote\fR control mechanism uses
-X11VNC_REMOTE channel, and this option disables/enables
-it as well. Default: \fB-vncconnect\fR
-.IP
-To use different names for these X11 properties (e.g. to
-have separate communication channels for multiple
-x11vnc's on the same display) set the VNC_CONNECT or
-X11VNC_REMOTE env. vars. to the string you want, for
-example: \fB-env\fR X11VNC_REMOTE=X11VNC_REMOTE_12345
-Both sides of the channel must use the same unique name.
-The same can be done for the internal X11VNC_TICKER
-property (heartbeat and timestamp) if desired.
-.PP
-\fB-allow\fR \fIhost1[,host2..]\fR
-.IP
-Only allow client connections from hosts matching
-the comma separated list of hostnames or IP addresses.
-Can also be a numerical IP prefix, e.g. "192.168.100."
-to match a simple subnet, for more control build
-LibVNCServer with libwrap support (See the FAQ). If the
-list contains a "/" it instead is a interpreted
-as a file containing addresses or prefixes that is
-re-read each time a new client connects. Lines can be
-commented out with the "#" character in the usual way.
-.IP
-\fB-allow\fR applies in \fB-ssl\fR mode, but not in \fB-stunnel\fR mode.
-.IP
-IPv6: as of x11vnc 0.9.10 a host can be specified
-in IPv6 numerical format, e.g. 2001:4860:b009::93.
-.PP
-\fB-localhost\fR
-.IP
-Basically the same as "\fB-allow\fR \fI127.0.0.1\fR".
-.IP
-Note: if you want to restrict which network interface
-x11vnc listens on, see the \fB-listen\fR option below.
-E.g. "\fB-listen\fR \fIlocalhost\fR" or "\fB-listen\fR \fI192.168.3.21\fR".
-As a special case, the option "\fB-localhost\fR" implies
-"\fB-listen\fR \fIlocalhost\fR".
-.IP
-A rare case, but for non-localhost \fB-listen\fR usage, if
-you use the remote control mechanism (-R) to change
-the \fB-listen\fR interface you may need to manually adjust
-the \fB-allow\fR list (and vice versa) to avoid situations
-where no connections (or too many) are allowed.
-.IP
-If you do not want x11vnc to listen on ANY interface
-(evidently you are using \fB-connect\fR or \fB-connect_or_exit,\fR
-or plan to use remote control: \fB-R\fR connect:host), use
-\fB-rfbport\fR 0
-.IP
-IPv6: if IPv6 is supported, this option automatically
-implies the IPv6 loopback address '::1' as well.
-.PP
-\fB-unixsock\fR \fIstr\fR
-.IP
-Listen on the unix socket (AF_UNIX) 'str'
-for connections. This mode is for either local
-connections or a tunnel endpoint where one wants the
-file permission of the unix socket file to determine
-what can connect to it. (This currently requires an
-edit to libvnserver/rfbserver.c: comment out lines 310
-and 311, 'close(sock)' and 'return NULL' in rfbserver.c
-after the setsockopt() call.) Note that to disable all
-tcp listening ports specify '-rfbport 0' and should be
-useful with this mode. Example:
-mkdir ~/s; chmod 700 ~/s;
-x11vnc \fB-unixsock\fR ~/s/mysock \fB-rfbport\fR 0 ...
-The SSVNC unix vncviewer can connect to unix sockets.
-.PP
-\fB-listen6\fR \fIstr\fR
-.IP
-When in IPv6 listen mode "-6", listen only on the
-network interface with address \fIstr\fR. It also works
-for link scope addresses (fe80::219:dbff:fee5:3f92%eth0)
-and IPv6 hostname strings (e.g. ipv6.google.com.)
-Use LibVNCServer \fB-listen\fR option for the IPv4 interface.
-.PP
-\fB-nolookup\fR
-.IP
-Do not use gethostbyname() or gethostbyaddr() to look up
-host names or IP numbers. Use this if name resolution
-is incorrectly set up and leads to long pauses as name
-lookups time out, etc.
-.PP
-\fB-input\fR \fIstring\fR
-.IP
-Fine tuning of allowed user input. If \fIstring\fR does
-not contain a comma "," the tuning applies only to
-normal clients. Otherwise the part before "," is
-for normal clients and the part after for view-only
-clients. "K" is for Keystroke input, "M" for
-Mouse-motion input, "B" for Button-click input, "C"
-is for Clipboard input, and "F" is for File transfer
-(ultravnc only). Their presence in the string enables
-that type of input. E.g. "\fB-input\fR \fIM\fR" means normal
-users can only move the mouse and "\fB-input\fR \fIKMBCF,M\fR"
-lets normal users do anything and enables view-only
-users to move the mouse. This option is ignored when
-a global \fB-viewonly\fR is in effect (all input is discarded
-in that case).
-.PP
-\fB-grabkbd\fR
-.IP
-When VNC viewers are connected, attempt to the grab
-the keyboard so a (non-malicious) user sitting at the
-physical display is not able to enter keystrokes.
-This method uses
-.IR XGrabKeyboard (3X11)
-and so it is
-not secure and does not rule out the person at the
-physical display injecting keystrokes by flooding the
-server with them, grabbing the keyboard himself, etc.
-Some degree of cooperation from the person at the
-display is assumed. This is intended for remote
-help-desk or educational usage modes.
-.IP
-Note: on some recent (12/2010) X servers and/or
-desktops, \fB-grabkbd\fR no longer works: it prevents the
-window manager from resizing windows and similar things.
-Try \fB-ungrabboth\fR below (might not work.)
-.PP
-\fB-grabptr\fR
-.IP
-As \fB-grabkbd,\fR but for the mouse pointer using
-.IR XGrabPointer (3X11).
-Unfortunately due to the way the X
-server works, the mouse can still be moved around by the
-user at the physical display, but he will not be able to
-change window focus with it. Also some window managers
-that call
-.IR XGrabServer (3X11)
-for resizes, etc, will
-act on the local user's input. Again, some degree of
-cooperation from the person at the display is assumed.
-.PP
-\fB-ungrabboth\fR
-.IP
-Whenever there is any input (either keyboard or
-pointer), ungrab *both* the keyboard and the pointer
-while injecting the synthetic input. This is to allow
-window managers, etc. a chance to grab.
-.PP
-\fB-grabalways\fR
-.IP
-Apply both \fB-grabkbd\fR and \fB-grabptr\fR even when no VNC
-viewers are connected. If you only want one of them,
-use the \fB-R\fR remote control to turn the other back on,
-e.g. \fB-R\fR nograbptr.
-.PP
-\fB-viewpasswd\fR \fIstring\fR
-.IP
-Supply a 2nd password for view-only logins. The \fB-passwd\fR
-(full-access) password must also be supplied.
-.PP
-\fB-passwdfile\fR \fIfilename\fR
-.IP
-Specify the LibVNCServer password via the first line
-of the file \fIfilename\fR (instead of via \fB-passwd\fR on
-the command line where others might see it via
-.IR ps (1)
-).
-.IP
-See the descriptions below for how to supply multiple
-passwords, view-only passwords, to specify external
-programs for the authentication, and other features.
-.IP
-If the filename is prefixed with "rm:" it will be
-removed after being read. Perhaps this is useful in
-limiting the readability of the file. In general, the
-password file should not be readable by untrusted users
-(BTW: neither should the VNC \fB-rfbauth\fR file: it is NOT
-encrypted, only obscured with a fixed key).
-.IP
-If the filename is prefixed with "read:" it will
-periodically be checked for changes and reread. It is
-guaranteed to be reread just when a new client connects
-so that the latest passwords will be used.
-.IP
-If \fIfilename\fR is prefixed with "cmd:" then the
-string after the ":" is run as an external command:
-the output of the command will be interpreted as if it
-were read from a password file (see below). If the
-command does not exit with 0, then x11vnc terminates
-immediately. To specify more than 1000 passwords this
-way set X11VNC_MAX_PASSWDS before starting x11vnc.
-The environment variables are set as in \fB-accept.\fR
-.IP
-Note that due to the VNC protocol only the first 8
-characters of a password are used (DES key).
-.IP
-If \fIfilename\fR is prefixed with "custom:" then a
-custom password checker is supplied as an external
-command following the ":". The command will be run
-when a client authenticates. If the command exits with
-0 the client is accepted, otherwise it is rejected.
-The environment variables are set as in \fB-accept.\fR
-.IP
-The standard input to the custom command will be a
-decimal digit "len" followed by a newline. "len"
-specifies the challenge size and is usually 16 (the
-VNC spec). Then follows len bytes which is the random
-challenge string that was sent to the client. This is
-then followed by len more bytes holding the client's
-response (i.e. the challenge string encrypted via DES
-with the user password in the standard situation).
-.IP
-The "custom:" scheme can be useful to implement
-dynamic passwords or to implement methods where longer
-passwords and/or different encryption algorithms
-are used. The latter will require customizing the VNC
-client as well. One could create an MD5SUM based scheme
-for example.
-.IP
-File format for \fB-passwdfile:\fR
-.IP
-If multiple non-blank lines exist in the file they are
-all taken as valid passwords. Blank lines are ignored.
-Password lines may be "commented out" (ignored) if
-they begin with the character "#" or the line contains
-the string "__SKIP__". Lines may be annotated by use
-of the "__COMM__" string: from it to the end of the
-line is ignored. An empty password may be specified
-via the "__EMPTY__" string on a line by itself (note
-your viewer might not accept empty passwords).
-.IP
-If the string "__BEGIN_VIEWONLY__" appears on a
-line by itself, the remaining passwords are used for
-viewonly access. For compatibility, as a special case
-if the file contains only two password lines the 2nd
-one is automatically taken as the viewonly password.
-Otherwise the "__BEGIN_VIEWONLY__" token must be
-used to have viewonly passwords. (tip: make the 3rd
-and last line be "__BEGIN_VIEWONLY__" to have 2
-full-access passwords)
-.PP
-\fB-showrfbauth\fR \fIfilename\fR
-.IP
-Print to the screen the obscured VNC password kept in
-the rfbauth file \fIfilename\fR and then exit.
-.PP
-\fB-unixpw\fR \fI[list]\fR
-.IP
-Use Unix username and password authentication. x11vnc
-will use the
-.IR su (1)
-program to verify the user's
-password. [list] is an optional comma separated list
-of allowed Unix usernames. If the [list] string begins
-with the character "!" then the entire list is taken
-as an exclude list. See below for per-user options
-that can be applied.
-.IP
-A familiar "login:" and "Password:" dialog is
-presented to the user on a black screen inside the
-vncviewer. The connection is dropped if the user fails
-to supply the correct password in 3 tries or does not
-send one before a 45 second timeout. Existing clients
-are view-only during this period.
-.IP
-If the first character received is "Escape" then the
-unix username will not be displayed after "login:"
-as it is typed. This could be of use for VNC viewers
-that automatically type the username and password.
-.IP
-Since the detailed behavior of
-.IR su (1)
-can vary from
-OS to OS and for local configurations, test the mode
-before deployment to make sure it is working properly.
-x11vnc will attempt to be conservative and reject a
-login if anything abnormal occurs.
-.IP
-One case to note: FreeBSD and the other BSD's by
-default it is impossible for the user running x11vnc to
-validate his *own* password via
-.IR su (1)
-(commenting out
-the pam_self.so entry in /etc/pam.d/su eliminates this
-behavior). So the x11vnc login will always *FAIL* for
-this case (even when the correct password is supplied).
-.IP
-A possible workaround for this on *BSD would be to
-start x11vnc as root with the "\fB-users\fR \fI+nobody\fR" option
-to immediately switch to user nobody where the su'ing
-will proceed normally.
-.IP
-Another source of potential problems are PAM modules
-that prompt for extra info, e.g. password aging modules.
-These logins will fail as well even when the correct
-password is supplied.
-.IP
-**IMPORTANT**: to prevent the Unix password being sent
-in *clear text* over the network, one of two schemes
-will be enforced: 1) the \fB-ssl\fR builtin SSL mode, or 2)
-require both \fB-localhost\fR and \fB-stunnel\fR be enabled.
-.IP
-Method 1) ensures the traffic is encrypted between
-viewer and server. A PEM file will be required, see the
-discussion under \fB-ssl\fR below (under some circumstances
-a temporary one can be automatically generated).
-.IP
-Method 2) requires the viewer connection to appear
-to come from the same machine x11vnc is running on
-(e.g. from a ssh \fB-L\fR port redirection). And that the
-\fB-stunnel\fR SSL mode be used for encryption over the
-network. (see the description of \fB-stunnel\fR below).
-.IP
-Note: as a convenience, if you
-.IR ssh (1)
-in and start
-x11vnc it will check if the environment variable
-SSH_CONNECTION is set and appears reasonable. If it
-does, then the \fB-ssl\fR or \fB-stunnel\fR requirement will be
-dropped since it is assumed you are using ssh for the
-encrypted tunnelling. \fB-localhost\fR is still enforced.
-Use \fB-ssl\fR or \fB-stunnel\fR to force SSL usage even if
-SSH_CONNECTION is set.
-.IP
-To override the above restrictions you can set
-environment variables before starting x11vnc:
-.IP
-Set UNIXPW_DISABLE_SSL=1 to disable requiring either
-\fB-ssl\fR or \fB-stunnel\fR (as under SSH_CONNECTION.) Evidently
-you will be using a different method to encrypt the
-data between the vncviewer and x11vnc: perhaps
-.IR ssh (1)
-or an IPSEC VPN. \fB-localhost\fR is still enforced (however,
-see the next paragraph.)
-.IP
-Set UNIXPW_DISABLE_LOCALHOST=1 to disable the \fB-localhost\fR
-requirement in \fB-unixpw\fR modes. One should never do this
-(i.e. allow the Unix passwords to be sniffed on the
-network.) This also disables the localhost requirement
-for reverse connections (see below.)
-.IP
-Note that use of \fB-localhost\fR with
-.IR ssh (1)
-(and no \fB-unixpw)\fR
-is roughly the same as requiring a Unix user login
-(since a Unix password or the user's public key
-authentication is used by sshd on the machine where
-x11vnc runs and only local connections from that machine
-are accepted).
-.IP
-Regarding reverse connections (e.g. \fB-R\fR connect:host
-and \fB-connect\fR host), when the \fB-localhost\fR constraint is
-in effect then reverse connections can only be used
-to connect to the same machine x11vnc is running on
-(default port 5500). Please use a ssh or stunnel port
-redirection to the viewer machine to tunnel the reverse
-connection over an encrypted channel.
-.IP
-In \fB-inetd\fR mode the Method 1) will be enforced (not
-Method 2). With \fB-ssl\fR in effect reverse connections
-are disabled. If you override this via env. var, be
-sure to also use encryption from the viewer to inetd.
-Tip: you can also have your own stunnel spawn x11vnc
-in \fB-inetd\fR mode (thereby bypassing inetd). See the FAQ
-for details.
-.IP
-The user names in the comma separated [list] may have
-per-user options after a ":", e.g. "fred:opts"
-where "opts" is a "+" separated list of
-"viewonly", "fullaccess", "input=XXXX", or
-"deny", e.g. "karl,wally:viewonly,boss:input=M".
-For "input=" it is the K,M,B,C described under \fB-input.\fR
-.IP
-If an item in the list is "*" that means those
-options apply to all users. It ALSO implies all users
-are allowed to log in after supplying a valid password.
-Use "deny" to explicitly deny some users if you use
-"*" to set a global option. If [list] begins with the
-"!" character then "*" is ignored for checking if
-the user is allowed, but the option values associated
-with it do apply as normal.
-.IP
-There are also some utilities for checking passwords
-if [list] starts with the "%" character. See the
-quick_pw() function for more details. Description:
-"%-" or "%stdin" means read one line from stdin.
-"%env" means it is in $UNIXPW env var. A leading
-"%/" or "%." means read the first line from the
-filename that follows after the % character. % by
-itself means prompt for the username and password.
-Otherwise: %user:pass E.g. \fB-unixpw\fR %fred:swordfish
-For the other cases user:pass is read from the indicated
-source. If the password is correct 'Y user' is printed
-and the program exit code is 0. If the password is
-incorrect it prints 'N user' and the exit code is 1.
-If there is some other error the exit code is 2.
-This feature enables x11vnc to be a general unix user
-password checking tool; it could be used from scripts
-or other programs. These % password checks also apply
-to the \fB-unixpw_nis\fR and \fB-unixpw_cmd\fR options.
-.IP
-For the % password check, if the env. var. UNIXPW_CMD
-is set to a command then it is run as the user (assuming
-the password is correct.) The output of the command is
-not printed, the program or script must manage that by
-some other means. The exit code of x11vnc will depend
-on the exit code of the command that is run.
-.IP
-Use \fB-nounixpw\fR to disable unixpw mode if it was enabled
-earlier in the cmd line (e.g. \fB-svc\fR mode)
-.PP
-\fB-unixpw_nis\fR \fI[list]\fR
-.IP
-As \fB-unixpw\fR above, however do not use
-.IR su (1)
-but rather
-use the traditional
-.IR getpwnam (3)
-+
-.IR crypt (3)
-method to
-verify passwords. All of the above \fB-unixpw\fR options and
-constraints apply.
-.IP
-This mode requires that the encrypted passwords be
-readable. Encrypted passwords stored in /etc/shadow
-will be inaccessible unless x11vnc is run as root.
-.IP
-This is called "NIS" mode simply because in most
-NIS setups user encrypted passwords are accessible
-(e.g. "ypcat passwd") by an ordinary user and so that
-user can authenticate ANY user.
-.IP
-NIS is not required for this mode to work (only that
-.IR getpwnam (3)
-return the encrypted password is required),
-but it is unlikely it will work (as an ordinary user)
-for most modern environments unless NIS is available.
-On the other hand, when x11vnc is run as root it will
-be able to to access /etc/shadow even if NIS is not
-available (note running as root is often done when
-running x11vnc from inetd and xdm/gdm/kdm).
-.IP
-Looked at another way, if you do not want to use the
-.IR su (1)
-method provided by \fB-unixpw\fR (i.e. su_verify()), you
-can run x11vnc as root and use \fB-unixpw_nis.\fR Any users
-with passwords in /etc/shadow can then be authenticated.
-.IP
-In \fB-unixpw_nis\fR mode, under no circumstances is x11vnc's
-user password verifying function based on su called
-(i.e. the function su_verify() that runs /bin/su
-in a pseudoterminal to verify passwords.) However,
-if \fB-unixpw_nis\fR is used in conjunction with the \fB-find\fR
-and \fB-create\fR \fB-display\fR WAIT:... modes then, if x11vnc is
-running as root, /bin/su may be called externally to
-run the find or create commands.
-.PP
-\fB-unixpw_cmd\fR \fIcmd\fR
-.IP
-As \fB-unixpw\fR above, however do not use
-.IR su (1)
-but rather
-run the externally supplied command \fIcmd\fR. The first
-line of its stdin will be the username and the second
-line the received password. If the command exits
-with status 0 (success) the VNC user will be accepted.
-It will be rejected for any other return status.
-.IP
-Dynamic passwords and non-unix passwords, e.g. LDAP,
-can be implemented this way by providing your own custom
-helper program. Note that the remote viewer is given 3
-tries to enter the correct password, and so the program
-may be called in a row that many (or more) times.
-.IP
-If a list of allowed users is needed to limit who can
-log in, use \fB-unixpw\fR [list] in addition to this option.
-.IP
-In FINDDISPLAY and FINDCREATEDISPLAY modes the \fIcmd\fR
-will also be run with the RFB_UNIXPW_CMD_RUN env. var.
-non-empty and set to the corresponding display
-find/create command. The first two lines of input are
-the username and passwd as in the normal case described
-above. To support FINDDISPLAY and FINDCREATEDISPLAY,
-\fIcmd\fR should run the requested command as the user
-(and most likely refusing to run it if the password is
-not correct.) Here is an example script (note it has
-a hardwired bogus password "abc"!)
-.IP
-#!/bin/sh
-# Example x11vnc \fB-unixpw_cmd\fR script.
-# Read the first two lines of stdin (user and passwd)
-read user
-read pass
-.IP
-debug=0
-if [ $debug = 1 ]; then
-echo "user: $user" 1>&2
-echo "pass: $pass" 1>&2
-env | egrep \fB-i\fR 'rfb|vnc' 1>&2
-fi
-.IP
-# Check if the password is valid.
-# (A real example would use ldap lookup, etc!)
-if [ "X$pass" != "Xabc" ]; then
-exit 1 # incorrect password
-fi
-.IP
-if [ "X$RFB_UNIXPW_CMD_RUN" = "X" ]; then
-exit 0 # correct password
-else
-# Run the requested command (finddisplay)
-if [ $debug = 1 ]; then
-echo "run: $RFB_UNIXPW_CMD_RUN" 1>&2
-fi
-exec /bin/su - "$user" \fB-c\fR "$RFB_UNIXPW_CMD_RUN"
-fi
-.IP
-In \fB-unixpw_cmd\fR mode, under no circumstances is x11vnc's
-user password verifying function based on su called
-(i.e. the function su_verify() that runs /bin/su in a
-pseudoterminal to verify passwords.) It is up to the
-supplied unixpw_cmd to do user switching if desired
-and if it has the permissions to do so.
-.PP
-\fB-find\fR
-.IP
-Find the user's display using FINDDISPLAY. This
-is an alias for "\fB-display\fR \fIWAIT:cmd=FINDDISPLAY\fR".
-.IP
-Note: if a \fB-display\fR occurs later on the command line
-it will override the \fB-find\fR setting.
-.IP
-For this and the next few options see \fB-display\fR WAIT:...
-below for all of the details.
-.PP
-\fB-finddpy\fR
-.IP
-Run the FINDDISPLAY program, print out the found
-display (if any) and exit. Output is like: DISPLAY=:0.0
-DISPLAY=:0.0,XPID=12345 or DISPLAY=:0.0,VT=7. XPID is
-the process ID of the found X server. VT is the Linux
-virtual terminal of the X server.
-.PP
-\fB-listdpy\fR
-.IP
-Have the FINDDISPLAY program list all of your displays
-(i.e. all the X displays on the local machine that you
-have access rights to). x11vnc then exits.
-.PP
-\fB-findauth\fR \fI[disp]\fR
-.IP
-Apply the \fB-find/-finddpy\fR heuristics to try to guess
-the XAUTHORITY file for DISPLAY 'disp'. If 'disp'
-is not supplied, then the value in the \fB-display\fR on
-the cmdline is used; failing that $DISPLAY is used;
-and failing that ":0" is used. x11vnc then exits.
-.IP
-If nothing is printed out, that means no XAUTHORITY was
-found for 'disp'; i.e. failure. If "XAUTHORITY="
-is printed out, that means use the default (i.e. do
-not set XAUTHORITY). If "XAUTHORITY=/path/to/file"
-is printed out, then use that file.
-.IP
-XDM/GDM/KDM: if you are running x11vnc as root and want
-to find the XAUTHORITY before anyone has logged into an
-X session yet, use: x11vnc \fB-env\fR FD_XDM=1 \fB-findauth\fR ...
-(This will also find the XAUTHORITY if a user is already
-logged into the X session.) When running as root,
-FD_XDM=1 will be tried if the initial \fB-findauth\fR fails.
-.PP
-\fB-create\fR
-.IP
-First try to find the user's display using FINDDISPLAY,
-if that doesn't succeed create an X session via the
-FINDCREATEDISPLAY method. This is an alias for
-"\fB-display\fR \fIWAIT:cmd=FINDCREATEDISPLAY-Xvfb\fR".
-.IP
-Note: if a \fB-display\fR occurs later on the command line
-it will override the \fB-create\fR setting.
-.IP
-SSH NOTE: for both \fB-find\fR and \fB-create\fR you can (should!)
-add the "\fB-localhost\fR" option to force SSH tunnel access.
-.PP
-\fB-xdummy\fR
-.IP
-As in \fB-create,\fR except Xdummy instead of Xvfb.
-.PP
-\fB-xvnc\fR
-.IP
-As in \fB-create,\fR except Xvnc instead of Xvfb.
-.PP
-\fB-xvnc_redirect\fR
-.IP
-As in \fB-create,\fR except Xvnc.redirect instead of Xvfb.
-.PP
-\fB-xdummy_xvfb\fR
-.IP
-Sets WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb
-.PP
-\fB-create_xsrv\fR \fIstr\fR
-.IP
-Sets WAIT:cmd=FINDCREATEDISPLAY-<str> Can be on cmdline
-after anything that sets WAIT:.. and other things
-(e.g. \fB-svc,\fR \fB-xdmsvc)\fR to adjust the X server list.
-Example: \fB-svc\fR ... \fB-create_xsrv\fR Xdummy,X
-.PP
-\fB-svc\fR
-.IP
-Terminal services mode based on SSL access. Alias for
-\fB-display\fR WAIT:cmd=FINDCREATEDISPLAY-Xvfb \fB-unixpw\fR \fB-users\fR
-unixpw= \fB-ssl\fR SAVE Also "\fB-service\fR".
-.IP
-Note: if a \fB-display,\fR \fB-unixpw,\fR \fB-users,\fR or \fB-ssl\fR occurs
-later on the command line it will override the \fB-svc\fR
-setting.
-.PP
-\fB-svc_xdummy\fR
-.IP
-As \fB-svc\fR except Xdummy instead of Xvfb.
-.PP
-\fB-svc_xvnc\fR
-.IP
-As \fB-svc\fR except Xvnc instead of Xvfb.
-.PP
-\fB-svc_xdummy_xvfb\fR
-.IP
-As \fB-svc\fR with Xdummy,Xvfb.
-.PP
-\fB-xdmsvc\fR
-.IP
-Display manager Terminal services mode based on SSL.
-Alias for \fB-display\fR WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp
-\fB-unixpw\fR \fB-users\fR unixpw= \fB-ssl\fR SAVE Also "\fB-xdm_service\fR".
-.IP
-Note: if a \fB-display,\fR \fB-unixpw,\fR \fB-users,\fR or \fB-ssl\fR occurs
-later on the command line it will override the \fB-xdmsvc\fR
-setting.
-.IP
-To create a session a user will have to first log in
-to the \fB-unixpw\fR dialog and then log in again to the
-XDM/GDM/KDM prompt. Subsequent re-connections will
-only require the \fB-unixpw\fR password. See the discussion
-under \fB-display\fR WAIT:... for more details about XDM,
-etc configuration.
-.IP
-Remember to enable XDMCP in the xdm-config, gdm.conf,
-or kdmrc configuration file. See \fB-display\fR WAIT: for
-more info.
-.PP
-\fB-sshxdmsvc\fR
-.IP
-Display manager Terminal services mode based on SSH.
-Alias for \fB-display\fR WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp
-\fB-localhost.\fR
-.IP
-The \fB-localhost\fR option constrains connections to come
-in via a SSH tunnel (which will require a login).
-To create a session a user will also have to log into
-the XDM GDM KDM prompt. Subsequent re-connections will
-only only require the SSH login. See the discussion
-under \fB-display\fR WAIT:... for more details about XDM,
-etc configuration.
-.IP
-Remember to enable XDMCP in the xdm-config, gdm.conf,
-or kdmrc configuration file. See \fB-display\fR WAIT: for
-more info.
-.PP
-\fB-unixpw_system_greeter\fR
-.IP
-Present a "Press 'Escape' for System Greeter" option
-to the connecting VNC client in combined \fB-unixpw\fR
-and xdmcp FINDCREATEDISPLAY modes (e.g. \fB-xdmsvc).\fR
-.IP
-Normally in a \fB-unixpw\fR mode the VNC client must
-supply a valid username and password to gain access.
-However, if \fB-unixpw_system_greeter\fR is supplied AND
-the FINDCREATEDISPLAY command matches 'xdmcp', then
-the user has the option to press Escape and then get a
-XDM/GDM/KDM login/greeter panel instead. They will then
-supply a username and password directly to the greeter.
-.IP
-Otherwise, in xdmcp FINDCREATEDISPLAY mode the user
-must supply his username and password TWICE. First to
-the initial unixpw login dialog, and second to the
-subsequent XDM/GDM/KDM greeter. Note that if the user
-re-connects and supplies his username and password in
-the unixpw dialog the xdmcp greeter is skipped and
-he is connected directly to his existing X session.
-So the \fB-unixpw_system_greeter\fR option avoids the extra
-password at X session creation time.
-.IP
-Example: x11vnc \fB-xdmsvc\fR \fB-unixpw_system_greeter\fR
-See \fB-unixpw\fR and \fB-display\fR WAIT:... for more info.
-.IP
-The special options after a colon at the end of the
-username (e.g. user:solid) described under \fB-display\fR
-WAIT: are also applied in this mode if they are typed
-in before the user hits Escape. The username is ignored
-but the colon options are not.
-.IP
-The default message is 2 lines in a small font, set
-the env. var. X11VNC_SYSTEM_GREETER1=true for a 1 line
-message in a larger font.
-.IP
-If the user pressed Escape the FINDCREATEDISPLAY command
-will be run with the env. var. X11VNC_XDM_ONLY=1.
-.IP
-Remember to enable XDMCP in the xdm-config, gdm.conf,
-or kdmrc configuration file. See \fB-display\fR WAIT: for
-more info.
-.PP
-\fB-redirect\fR \fIport\fR
-.IP
-As in FINDCREATEDISPLAY-Xvnc.redirect mode except
-redirect immediately (i.e. without X session finding
-or creation) to a VNC server listening on port. You
-can also supply host:port to redirect to a different
-machine.
-.IP
-If 0 <= port < 200 it is taken as a VNC display (5900 is
-added to get the actual port), if port < 0 then \fB-port\fR
-is used.
-.IP
-Probably the only reason to use the \fB-redirect\fR option
-is in conjunction with SSL support, e.g. \fB-ssl\fR SAVE.
-This provides an easy way to add SSL encryption to a VNC
-server that does not support SSL (e.g. Xvnc or vnc.so)
-In fact, the protocol does not even need to be VNC,
-and so "\fB-rfbport\fR \fIport1 \fB-ssl\fR SAVE \fB-redirect\fR host:port2\fR"
-can act as a replacement for
-.IR stunnel (1).
-.IP
-This mode only allows one redirected connection.
-The \fB-forever\fR option does not apply. Use \fB-inetd\fR or
-\fB-loop\fR for persistent service.
-.PP
-\fB-display\fR \fIWAIT:...\fR
-.IP
-A special usage mode for the normal \fB-display\fR option.
-Useful with \fB-unixpw,\fR but can be used independently
-of it. If the display string begins with WAIT: then
-x11vnc waits until a VNC client connects before opening
-the X display (or \fB-rawfb\fR device).
-.IP
-This could be useful for delaying opening the display
-for certain usage modes (say if x11vnc is started at
-boot time and no X server is running or users logged
-in yet).
-.IP
-If the string is, e.g. WAIT:0.0 or WAIT:1, i.e. "WAIT"
-in front of a normal X display, then that indicated
-display is used.
-.IP
-One can also insert a geometry between colons, e.g.
-WAIT:1280x1024:... to set the size of the display the
-VNC client first attaches to since some VNC viewers
-will not automatically adjust to a new framebuffer size.
-.IP
-A more interesting case is like this:
-.IP
-WAIT:cmd=/usr/local/bin/find_display
-.IP
-in which case the command after "cmd=" is run to
-dynamically work out the DISPLAY and optionally the
-XAUTHORITY data. The first line of the command output
-must be of the form DISPLAY=<xdisplay>. On Linux
-if the virtual terminal is known append ",VT=n" to
-this string and the
-.IR chvt (1)
-program will also be run.
-Any remaining output is taken as XAUTHORITY data.
-It can be either of the form XAUTHORITY=<file> or raw
-xauthority data for the display. For example;
-.IP
-xauth extract - $DISPLAY"
-.IP
-NOTE: As specified in the previous paragraph, you can
-supply your own WAIT:cmd=... program or script, BUT
-there are two very useful *BUILT-IN* ones: FINDDISPLAY
-(alias \fB-find\fR above) and FINDCREATEDISPLAY (alias \fB-create\fR
-above.) Most people use these instead of creating
-their own script. Read the following (especially the
-BUILT-IN modes sections) to see how to configure these
-two useful builtin \fB-display\fR WAIT: modes.
-.IP
-In the case of \fB-unixpw\fR (and \fB-unixpw_nis\fR only if x11vnc
-is running as root), then the cmd= command is run
-as the user who just authenticated via the login and
-password prompt.
-.IP
-In the case of \fB-unixpw_cmd,\fR the commands will also be
-run as the logged-in user, as long as the user-supplied
-helper program supports RFB_UNIXPW_CMD_RUN (see the
-\fB-unixpw_cmd\fR option.)
-.IP
-Also in the case of \fB-unixpw,\fR the user logging in can
-place a colon at the end of her username and supply
-a few options: scale=, scale_cursor= (or sc=), solid
-(or so), id=, clear_mods (or cm), clear_keys (or
-ck), clear_all (or ca), repeat, speeds= (or sp=),
-readtimeout= (or rd=), viewonly (or vo), nodisplay=
-(or nd=), rotate= (or ro=), or noncache (or nc),
-all separated by commas if there is more than one.
-After the user logs in successfully, these options will
-be applied to the VNC screen. For example,
-.IP
-login: fred:scale=3/4,sc=1,repeat
-Password: ...
-.IP
-login: runge:sp=modem,rd=120,solid
-.IP
-for convenience m/n implies scale= e.g. fred:3/4 If you
-type and enter your password incorrectly, to retrieve
-your long "login:" line press the Up arrow once
-(before typing anything else).
-.IP
-Most of these colon options only apply to the builtin
-FINDDISPLAY and FINDCREATEDISPLAY modes, but note
-that they are passed to the extrenal command in the
-environment as well and so could be used.
-.IP
-In the login panel, press F1 to get a list of the
-available options that you can add after the username.
-.IP
-Another option is "geom=WxH" or "geom=WxHxD" (or
-ge=). This only has an effect in FINDCREATEDISPLAY
-mode when a virtual X server such as Xvfb is going
-to be created. It sets the width and height of
-the new display, and optionally the color depth as
-well.
-.IP
-You can also supply "gnome", "kde", "twm",
-"fvwm", "mwm", "dtwm", "wmaker", "xfce",
-"lxde", "enlightenment", "Xsession", or
-"failsafe" (same as "xterm") to have the created
-display use that mode for the user session.
-.IP
-Specify "tag=..." to set the unique FD_TAG desktop
-session tag described below. Note: this option will
-be ignored if the FD_TAG env. var. is already set or
-if the viewer-side supplied value is not completely
-composed of alphanumeric or '_' or '-' characters.
-.IP
-User preferences file: Instead of having the user type
-in geom=WxH,... etc. every time he logs in to find
-or create his X session, if you set FD_USERPREFS to
-a string that does not contain the "/" character,
-then the user's home directory is prepended to that
-string and if the file exists its first line is read
-and appended to any options he supplied at the login:
-prompt. For example \fB-env\fR FD_USERPREFS=.x11vnc_create
-and the user put "geom=1600x1200" in his
-~/.x11vnc_create file.
-.IP
-To disable the option setting set the environment
-variable X11VNC_NO_UNIXPW_OPTS=1 before starting x11vnc.
-To set any other options, the user can use the gui
-(x11vnc \fB-gui\fR connect) or the remote control method
-(x11vnc \fB-R\fR opt:val) during his VNC session.
-.IP
-So we see the combination of \fB-display\fR WAIT:cmd=... and
-\fB-unixpw\fR allows automatic pairing of an unix
-authenticated VNC user with his desktop. This could
-be very useful on SunRays and also any system where
-multiple users share a given machine. The user does
-not need to remember special ports or passwords set up
-for his desktop and VNC.
-.IP
-A nice way to use WAIT:cmd=... is out of
-.IR inetd (8)
-(it automatically forks a new x11vnc for each user).
-You can have the x11vnc inetd spawned process run as,
-say, root or nobody. When run as root (for either inetd
-or display manager), you can also supply the option
-"\fB-users\fR \fIunixpw=\fR" to have the x11vnc process switch to
-the user as well. Note: there will be a 2nd SSL helper
-process that will not switch, but it is only encoding
-and decoding the encrypted stream at that point.
-.IP
-BUILT-IN modes:
-.IP
-\fB--\fR Automatic Finding of User X Sessions \fB--\fR
-.IP
-As a special case, WAIT:cmd=FINDDISPLAY will run a
-script that works on most Unixes to determine a user's
-DISPLAY variable and xauthority data (see
-.IR who (1)
-).
-.IP
-NOTE: The option "\fB-find\fR" is an alias for this mode.
-.IP
-To have this default script printed to stdout (e.g. for
-customization) run with WAIT:cmd=FINDDISPLAY-print To
-have the script run to print what display it would find
-use "\fB-finddpy\fR" or WAIT:cmd=FINDDISPLAY-run
-.IP
-The standard script runs
-.IR xdpyinfo (1)
-run on potential
-displays. If your X server(s) have a login greeter
-that exclusively grabs the Xserver, then xdpyinfo
-blocks forever and this mode will not work. See
-www.karlrunge.com/x11vnc/faq.html#faq-display-manager
-for how to disable this for dtgreet on Solaris and
-possibly for other greeters.
-.IP
-In \fB-find/cmd=FINDDISPLAY\fR mode, if you set FD_XDM=1,
-e.g. 'x11vnc \fB-env\fR FD_XDM=1 \fB-find\fR ...' and x11vnc is
-running as root (e.g. inetd) then it will try to find
-the XAUTHORITY file of a running XDM/GDM/KDM login
-greeter (i.e. no user has logged into an X session yet.)
-.IP
-As another special case, WAIT:cmd=HTTPONCE will allow
-x11vnc to service one http request and then exit.
-This is usually done in \fB-inetd\fR mode to run on, say,
-port 5800 and allow the Java vncviewer to be downloaded
-by client web browsers. For example:
-.IP
-5815 stream tcp nowait root /usr/sbin/tcpd /.../x11vnc \\
-\fB-inetd\fR \fB-q\fR \fB-http_ssl\fR \fB-prog\fR /.../x11vnc \\
-\fB-display\fR WAIT:cmd=HTTPONCE
-.IP
-Where /.../x11vnc is the full path to x11vnc.
-It is used in the Apache SSL-portal example (see FAQ).
-.IP
-In this mode you can set X11VNC_SKIP_DISPLAY to a
-comma separated list of displays (e.g. ":0,:1") to
-ignore in the finding process. The ":" is optional.
-Ranges n-m e.g. 0-20 can also be supplied. This string
-can also be set by the connecting user via "nd="
-using "+" instead of "," If "nd=all" or you set
-X11VNC_SKIP_DISPLAY=all then all display finding fails
-as if you set X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 (below.)
-.IP
-On some systems
-.IR lsof (1)
-can be very slow. Set the
-env. var. FIND_DISPLAY_NO_LSOF=1 to skip using lsof to
-try to find the Linux VT the X server is running on.
-set FIND_DISPLAY_NO_VT_FIND=1 to avoid looking at all.
-.IP
-\fB--\fR Automatic Creation of User X Sessions \fB--\fR
-.IP
-An interesting option is WAIT:cmd=FINDCREATEDISPLAY
-that is like FINDDISPLAY in that is uses the same method
-to find an existing display. However, if it does not
-find one it will try to *start* up an X server session
-for the user. This is the only time x11vnc tries to
-actually start up an X server.
-.IP
-NOTE: The option "\fB-create\fR" is an alias for this mode.
-.IP
-It will start looking for an open display number at :20
-Override via X11VNC_CREATE_STARTING_DISPLAY_NUMBER=n
-By default 80 X displays are allowed (i.e. going to :99)
-Override via X11VNC_CREATE_MAX_DISPLAYS=n
-.IP
-For its heuristics, the create display script sets
-LC_ALL=C so that command output is uniform. By default
-it will try to restore LC_ALL right before starting the
-user session. However, if you don't mind it keeping
-LC_ALL=C set the env. var.: X11VNC_CREATE_LC_ALL_C_OK=1
-.IP
-By default FINDCREATEDISPLAY will try Xvfb and then
-Xdummy:
-.IP
-The Xdummy wrapper is part of the x11vnc source code
-(x11vnc/misc/Xdummy) It should be available in PATH
-and have run "Xdummy \fB-install"\fR once to create the
-shared library. Xdummy only works on Linux. As of
-12/2009 it no longer needs to be run as root, and the
-default is to not run as root. In some circumstances
-permissions may require running it as root, in these
-cases specify FD_XDUMMY_RUN_AS_ROOT=1, this is the same
-as supplying \fB-root\fR to the Xdummy cmdline.
-.IP
-Xvfb is available on most platforms and does not
-require root.
-.IP
-An advantage of Xdummy over Xvfb is that Xdummy supports
-RANDR dynamic screen resizing.
-.IP
-When x11vnc exits (i.e. user disconnects) the X
-server session stays running in the background.
-The FINDDISPLAY will find it directly next time.
-The user must exit the X session in the usual way for
-it to terminate (or kill the X server process if all
-else fails).
-.IP
-To troubleshoot the FINDCREATEDISPLAY mechanism,
-set the following env. var. to an output log file,
-e.g \fB-env\fR CREATE_DISPLAY_OUTPUT=/tmp/mydebug.txt
-.IP
-So this is a somewhat odd mode for x11vnc in that it
-will start up and poll virtual X servers! This can
-be used from, say,
-.IR inetd (8)
-to provide a means of
-definitely getting a desktop (either real or virtual)
-on the machine. E.g. a desktop service:
-.IP
-5900 stream tcp nowait root /usr/sbin/tcpd /.../x11vnc
-\fB-inetd\fR \fB-q\fR \fB-http\fR \fB-ssl\fR SAVE \fB-unixpw\fR \fB-users\fR unixpw=\\
-\fB-passwd\fR secret \fB-prog\fR /.../x11vnc \\
-\fB-display\fR WAIT:cmd=FINDCREATEDISPLAY
-.IP
-Where /.../x11vnc is the full path to x11vnc.
-.IP
-See the \fB-svc/-service\fR option alias above.
-.IP
-If for some reason you do not want x11vnc to ever
-try to find an existing display set the env. var
-X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 (also \fB-env\fR ...)
-This is the same as setting X11VNC_SKIP_DISPLAY=all or
-supplying "nd=all" after "username:"
-.IP
-Use WAIT:cmd=FINDCREATEDISPLAY-print to print out the
-script that is used for this.
-.IP
-You can specify the preferred X server order via e.g.,
-WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb,X and/or leave
-out ones you do not want. The the case "X" means try
-to start up a real, hardware X server using
-.IR xinit (1)
-or
-.IR startx (1).
-If there is already an X server running
-the X case may only work on Linux (see
-.IR startx (1)
-).
-.IP
-"Xvnc" will start up a VNC X server (real-
-or tight-vnc, e.g. use if Xvfb is not available).
-"Xsrv" will start up the server program in the
-variable "FD_XSRV" if it is non-empty. You can make
-this be a wrapper script if you like (it must handle :N,
-\fB-geometry,\fR and \fB-depth\fR and other X server options).
-.IP
-You can set the environment variable FD_GEOM (or
-X11VNC_CREATE_GEOM) to WxH or WxHxD to set the width
-and height and optionally the color depth of the
-created display. You can also set FD_SESS to be the
-session (short name of the windowmanager: kde, gnome,
-twm, failsafe, etc.). FD_OPTS contains extra options
-to pass to the X server. You can also set FD_PROG to
-be the full path to the session/windowmanager program.
-.IP
-More FD tricks: FD_CUPS=port or FD_CUPS=host:port
-will set the cups printing environment. Similarly for
-FD_ESD=port or FD_ESD=host:port for esddsp sound
-redirection. Set FD_EXTRA to a command to be run a
-few seconds after the X server starts up. Set FD_TAG
-to be a unique name for the session, it is set as an
-X property, that makes FINDDISPLAY only find sessions
-with that tag value.
-.IP
-Set FD_XDMCP_IF to the network interface that the
-display manager is running on; default is 'localhost'
-but you may need to set it to '::1' on some IPv6 only
-systems or misconfigured display managers.
-.IP
-If you want the FINDCREATEDISPLAY session to contact an
-XDMCP login manager (xdm/gdm/kdm) on the same machine,
-then use "Xvfb.xdmcp" instead of "Xvfb", etc.
-The user will have to supply his username and password
-one more time (but he gets to select his desktop type
-so that can be useful). For this to work, you will
-need to enable localhost XDMCP (udp port 177) for the
-display manager. This seems to be:
-.IP
-for gdm in gdm.conf: Enable=true in section [xdmcp]
-for kdm in kdmrc: Enable=true in section [Xdmcp]
-for xdm in xdm-config: DisplayManager.requestPort: 177
-.IP
-See the shorthand options above "\fB-svc\fR", "\fB-xdmsvc\fR"
-and "\fB-sshxdmsvc\fR" that specify the above options for
-some useful cases.
-.IP
-If you set the env. var WAITBG=1 x11vnc will go into
-the background once listening in wait mode.
-.IP
-Another special mode is FINDCREATEDISPLAY-Xvnc.redirect,
-(or FINDDISPLAY-Xvnc.redirect). In this case it will
-start up Xvnc as above if needed, but instead of
-polling it in its normal way, it simply does a socket
-redirection of the connected VNC viewer to the Xvnc.
-.IP
-So in Xvnc.redirect x11vnc does no VNC but merely
-transfers the data back and forth. This should be
-faster then x11vnc's polling method, but not as fast
-as connecting directly to the Xvnc with the VNC Viewer.
-The idea here is to take advantage of x11vnc's display
-finding/creating scheme, SSL, and perhaps a few others.
-Most of x11vnc's options do not apply in this mode.
-.IP
-Xvnc.redirect should also work for the vnc.so X server
-module for the h/w display however it will work only
-for finding the display and the user must already be
-logged into the X console.
-.PP
-\fB-vencrypt\fR \fImode\fR
-.IP
-The VeNCrypt extension to the VNC protocol allows
-encrypted SSL/TLS connections. If the \fB-ssl\fR mode is
-enabled, then VeNCrypt is enabled as well BY DEFAULT
-(they both use a SSL/TLS tunnel, only the protocol
-handshake is a little different.)
-.IP
-To control when and how VeNCrypt is used, specify the
-mode string. If mode is "never", then VeNCrypt is
-not used. If mode is "support" (the default) then
-VeNCrypt is supported. If mode is "only", then the
-similar and older ANONTLS protocol is not simultaneously
-supported. x11vnc's normal SSL mode (vncs://) will be
-supported under \fB-ssl\fR unless you set mode to "force".
-.IP
-If mode is prefixed with "nodh:", then Diffie Hellman
-anonymous key exchange is disabled. If mode is prefixed
-with "nox509:", then X509 key exchange is disabled.
-.IP
-To disable all Anonymous Diffie-Hellman access
-(susceptible to Man-In-The-Middle attack) you will need
-to supply "\fB-vencrypt\fR \fInodh:support \fB-anontls\fR never\fR"
-or "\fB-vencrypt\fR \fInodh:only\fR"
-.IP
-If mode is prefixed with "newdh:", then new Diffie
-Hellman parameters are generated for each connection
-(this can be time consuming: 1-60 secs; see \fB-dhparams\fR
-below for a faster way) rather than using the
-fixed values in the program. Using fixed, publicly
-known values is not known to be a security problem.
-This setting applies to ANONTLS as well.
-.IP
-Long example: \fB-vencrypt\fR newdh:nox509:support
-.IP
-Also, if mode is prefixed with "plain:", then
-if \fB-unixpw\fR mode is active the VeNCrypt "*Plain"
-username+passwd method is enabled for Unix logins.
-Otherwise in \fB-unixpw\fR mode the normal login panel is
-provided.
-.IP
-You *MUST* supply the \fB-ssl\fR option for VeNCrypt to
-be active. The \fB-vencrypt\fR option only fine-tunes its
-operation.
-.PP
-\fB-anontls\fR \fImode\fR
-.IP
-The ANONTLS extension to the VNC protocol allows
-encrypted SSL/TLS connections. If the \fB-ssl\fR mode is
-enabled, then ANONTLS is enabled as well BY DEFAULT
-(they both use a SSL/TLS tunnel, only the protocol
-handshake is a little different.)
-.IP
-ANONTLS is an older SSL/TLS mode introduced by vino.
-.IP
-It is referred to as 'TLS' for its registered VNC
-security-type name, but we use the more descriptive
-\'ANONTLS' here because it provides only Anonymous
-Diffie-Hellman encrypted connections, and hence no
-possibility for certificate authentication.
-.IP
-To control when and how ANONTLS is used, specify the
-mode string. If mode is "never", then ANONTLS is not
-used. If mode is "support" (the default) then ANONTLS
-is supported. If mode is "only", then the similar
-VeNCrypt protocol is not simultaneously supported.
-x11vnc's normal SSL mode (vncs://) will be supported
-under \fB-ssl\fR unless you set mode to "force".
-.IP
-If mode is prefixed with "newdh:", then new Diffie
-Hellman parameters are generated for each connection
-(this can be time consuming: 1-60 secs; see \fB-dhparams\fR
-below for a faster way) rather than using the
-fixed values in the program. Using fixed, publicly
-known values is not known to be a security problem.
-This setting applies to VeNCrypt as well. See the
-description of "plain:" under \fB-vencrypt.\fR
-.IP
-Long example: \fB-anontls\fR newdh:plain:support
-.IP
-You *MUST* supply the \fB-ssl\fR option for ANONTLS to
-be active. The \fB-anontls\fR option only fine-tunes its
-operation.
-.PP
-\fB-sslonly\fR
-.IP
-Same as: "\fB-vencrypt\fR \fInever \fB-anontls\fR never\fR" i.e. it
-disables the VeNCrypt and ANONTLS encryption methods
-and only allows standard SSL tunneling. You must also
-supply the \fB-ssl\fR ... option (see below.)
-.PP
-\fB-dhparams\fR \fIfile\fR
-.IP
-For some operations a set of Diffie Hellman parameters
-(prime and generator) is needed. If so, use the
-parameters in \fIfile\fR. In particular, the VeNCrypt and
-ANONTLS anonymous DH mode need them. By default a
-fixed set is used. If you do not want to do that you
-can specify "newdh:" to the \fB-vencrypt\fR and \fB-anontls\fR
-options to generate a new set each session. If that
-is too slow for you, use \fB-dhparams\fR file to a set you
-created manually via "openssl dhparam \fB-out\fR file 1024"
-.PP
-\fB-nossl\fR
-.IP
-Disable the \fB-ssl\fR option (see below). Since \fB-ssl\fR is off
-by default \fB-nossl\fR would only be used on the commandline
-to unset any *earlier* \fB-ssl\fR option (or \fB-svc...)\fR
-.PP
-\fB-ssl\fR \fI[pem]\fR
-.IP
-Use the openssl library (www.openssl.org) to provide a
-built-in encrypted SSL/TLS tunnel between VNC viewers
-and x11vnc. This requires libssl support to be
-compiled into x11vnc at build time. If x11vnc is not
-built with libssl support it will exit immediately when
-\fB-ssl\fR is prescribed. See the \fB-stunnel\fR option below for
-an alternative.
-.IP
-The VNC Viewer-side needs to support SSL/TLS as well.
-See this URL and also the discussion below for
-ideas on how to enable SSL support for the viewer:
-http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tun
-nel-viewers . x11vnc provides an SSL enabled Java
-viewer applet in the classes/ssl directory (-http or
-\fB-httpdir\fR options.) The SSVNC viewer package supports
-SSL tunnels too.
-.IP
-If the VNC Viewer supports VeNCrypt or ANONTLS (vino's
-encryption mode) they are also supported by the \fB-ssl\fR
-mode (see the \fB-vencrypt\fR and \fB-anontls\fR options for more
-info; use \fB-sslonly\fR to disable both of them.)
-.IP
-Use "\fB-ssl\fR \fI/path/to/mycert.pem\fR" to specify an SSL
-certificate file in PEM format to use to identify and
-provide a key for this server. See
-.IR openssl (1)
-for more
-info about PEMs and the \fB-sslGenCert\fR and "\fB-ssl\fR \fISAVE\fR"
-options below for how to create them.
-.IP
-The connecting VNC viewer SSL tunnel can (at its option)
-authenticate this server if it has the public key part
-of the certificate (or a common certificate authority,
-CA, is a more sophisticated way to verify this server's
-cert, see \fB-sslGenCA\fR below). This authentication is
-done to prevent Man-In-The-Middle attacks. Otherwise,
-if the VNC viewer simply accepts this server's key
-WITHOUT verification, the traffic is protected from
-passive sniffing on the network, but *NOT* from
-Man-In-The-Middle attacks. There are hacker tools
-like dsniff/webmitm and cain that implement SSL
-Man-In-The-Middle attacks.
-.IP
-If [pem] is empty or the string "SAVE" then the
-.IR openssl (1)
-command must be available to generate the
-certificate the first time. A self-signed certificate
-is generated (see \fB-sslGenCA\fR and \fB-sslGenCert\fR for use
-of a Certificate Authority.) It will be saved to the
-file ~/.vnc/certs/server.pem. On subsequent calls if
-that file already exists it will be used directly.
-.IP
-Use "SAVE_NOPROMPT" to avoid being prompted to
-protect the generated key with a passphrase. However in
-\fB-inetd\fR and \fB-bg\fR modes there will be no prompting for a
-passphrase in either case.
-.IP
-If [pem] is "SAVE_PROMPT" the server.pem certificate
-will be created based on your answers to its prompts for
-all info such as OrganizationalName, CommonName, etc.
-.IP
-Use "SAVE-<string>" and "SAVE_PROMPT-<string>"
-to refer to the file ~/.vnc/certs/server-<string>.pem
-instead (it will be generated if it does not already
-exist). E.g. "SAVE-charlie" will store to the file
-~/.vnc/certs/server-charlie.pem
-.IP
-Examples: x11vnc \fB-ssl\fR SAVE \fB-display\fR :0 ...
-x11vnc \fB-ssl\fR SAVE-someother \fB-display\fR :0 ...
-.IP
-If [pem] is "TMP" and the
-.IR openssl (1)
-utility
-command exists in PATH, then a temporary, self-signed
-certificate will be generated for this session. If
-.IR openssl (1)
-cannot be used to generate a temporary
-certificate x11vnc exits immediately. The temporary
-cert will be discarded when x11vnc exits.
-.IP
-If successful in using
-.IR openssl (1)
-to generate a
-temporary certificate in "SAVE" or "TMP" creation
-modes, the public part of it will be displayed to stderr
-(e.g. one could copy it to the client-side to provide
-authentication of the server to VNC viewers.)
-.IP
-NOTE: In "TMP" mode, unless you safely copy the
-public part of the temporary Cert to the viewer for
-authenticate *every time* (unlikely...), then only
-passive sniffing attacks are prevented and you are
-still open to Man-In-The-Middle attacks. This is
-why the default "SAVE" mode is preferred (and more
-sophisticated CA mode too). Only with saved keys AND
-the VNC viewer authenticating them (via the public
-certificate), are Man-In-The-Middle attacks prevented.
-.IP
-If [pem] is "ANON" then the Diffie-Hellman anonymous
-key exchange method is used. In this mode there
-are *no* SSL certificates and so it is not possible
-to authenticate either the VNC server or VNC client.
-Thus only passive network sniffing attacks are avoided:
-the "ANON" method is susceptible to Man-In-The-Middle
-attacks. "ANON" is not recommended; instead use
-a SSL PEM you created or the default "SAVE" method.
-.IP
-See \fB-ssldir\fR below to use a directory besides the
-default ~/.vnc/certs
-.IP
-If your x11vnc binary was not compiled with OpenSSL
-library support, use of the \fB-ssl\fR option will induce an
-immediate failure and exit. For such binaries, consider
-using the \fB-stunnel\fR option for SSL encrypted connections.
-.IP
-Misc Info: In temporary cert creation mode "TMP", set
-the env. var. X11VNC_SHOW_TMP_PEM=1 to have x11vnc print
-out the entire certificate, including the PRIVATE KEY
-part, to stderr. There are better ways to get/save this
-info. See "SAVE" above and "\fB-sslGenCert\fR" below.
-.PP
-\fB-ssltimeout\fR \fIn\fR
-.IP
-Set SSL read timeout to n seconds. In some situations
-(i.e. an iconified viewer in Windows) the viewer stops
-talking and the connection is dropped after the default
-timeout (25s for about the first minute, 43200s later).
-Set to zero to poll forever. Set to a negative value
-to use the builtin setting.
-.IP
-Note that this value does NOT apply to the *initial* ssl
-init connection. The default timeout for that is 20sec.
-Use \fB-env\fR SSL_INIT_TIMEOUT=n to modify it.
-.PP
-\fB-sslnofail\fR
-.IP
-Exit at the first SSL connection failure. Useful when
-scripting SSL connections (e.g. x11vnc is started via
-ssh) and you do not want x11vnc waiting around for more
-connections, tying up ports, etc.
-.PP
-\fB-ssldir\fR \fIdir\fR
-.IP
-Use \fIdir\fR as an alternate ssl certificate and key
-management toplevel directory. The default is
-~/.vnc/certs
-.IP
-This directory is used to store server and other
-certificates and keys and also other materials. E.g. in
-the simplest case, "\fB-ssl\fR \fISAVE\fR" will store the x11vnc
-server cert in dir/server.pem
-.IP
-Use of alternate directories via \fB-ssldir\fR allows you to
-manage multiple VNC Certificate Authority (CA) keys.
-Another use is if ~/.vnc/cert is on an NFS share you
-might want your certificates and keys to be on a local
-filesystem to prevent network snooping (for example
-\fB-ssldir\fR /var/lib/x11vnc-certs).
-.IP
-\fB-ssldir\fR affects nearly all of the other \fB-ssl*\fR options,
-e.g. \fB-ssl\fR SAVE, \fB-sslGenCert,\fR etc..
-.PP
-\fB-sslverify\fR \fIpath\fR
-.IP
-For either of the \fB-ssl\fR or \fB-stunnel\fR modes, use \fIpath\fR
-to provide certificates to authenticate incoming VNC
-*Client* connections (normally only the server is
-authenticated in SSL.) This can be used as a method
-to replace standard password authentication of clients.
-.IP
-If \fIpath\fR is a directory it contains the client (or CA)
-certificates in separate files. If path is a file,
-it contains one or more certificates. See special tokens
-below. These correspond to the "CApath = dir" and
-"CAfile = file" stunnel options. See the
-.IR stunnel (8)
-manpage for details.
-.IP
-Examples:
-x11vnc \fB-ssl\fR \fB-sslverify\fR ~/my.crt
-x11vnc \fB-ssl\fR \fB-sslverify\fR ~/my_pem_dir/
-.IP
-Note that if path is a directory, it must contain
-the certs in separate files named like <HASH>.0, where
-the value of <HASH> is found by running the command
-"openssl x509 \fB-hash\fR \fB-noout\fR \fB-in\fR file.crt". Evidently
-one uses <HASH>.1 if there is a collision...
-.IP
-The the key-management utility "\fB-sslCertInfo\fR \fIHASHON\fR"
-and "\fB-sslCertInfo\fR \fIHASHOFF\fR" will create/delete these
-hashes for you automatically (via symlink) in the HASH
-subdirs it manages. Then you can point \fB-sslverify\fR to
-the HASH subdir.
-.IP
-Special tokens: in \fB-ssl\fR mode, if \fIpath\fR is not a file or
-a directory, it is taken as a comma separated list of
-tokens that are interpreted as follows:
-.IP
-If a token is "CA" that means load the CA/cacert.pem
-file from the ssl directory. If a token is "clients"
-then all the files clients/*.crt in the ssl directory
-are loaded. Otherwise the file clients/token.crt
-is attempted to be loaded. As a kludge, use a token
-like ../server-foo to load a server cert if you find
-that necessary.
-.IP
-Use \fB-ssldir\fR to use a directory different from the
-~/.vnc/certs default.
-.IP
-Note that if the "CA" cert is loaded you do not need
-to load any of the certs that have been signed by it.
-You will need to load any additional self-signed certs
-however.
-.IP
-Examples:
-x11vnc \fB-ssl\fR \fB-sslverify\fR CA
-x11vnc \fB-ssl\fR \fB-sslverify\fR self:fred,self:jim
-x11vnc \fB-ssl\fR \fB-sslverify\fR CA,clients
-.IP
-Usually "\fB-sslverify\fR \fICA\fR" is the most effective.
-See the \fB-sslGenCA\fR and \fB-sslGenCert\fR options below for
-how to set up and manage the CA framework.
-.IP
-NOTE: the following utilities, \fB-sslGenCA,\fR \fB-sslGenCert,\fR
-\fB-sslEncKey,\fR \fB-sslCertInfo,\fR and \fB-sslCRL\fR are provided for
-completeness, but for casual usage they are overkill.
-.IP
-They provide VNC Certificate Authority (CA) key creation
-and server / client key generation and signing. So they
-provide a basic Public Key management framework for
-VNC-ing with x11vnc. (note that they require
-.IR openssl (1)
-be installed on the system)
-.IP
-However, the simplest usage mode, "\fB-ssl\fR \fITMP\fR" (where
-x11vnc automatically generates its own, self-signed,
-temporary key and the VNC viewers always accept it,
-e.g. accepting via a dialog box) is probably safe enough
-for most scenarios. CA management is not needed.
-.IP
-To protect against Man-In-The-Middle attacks the "TMP"
-mode can be improved by using "\fB-ssl\fR \fISAVE\fR" (same as
-"\fB-ssl\fR", i.e. the default) to have x11vnc create a
-longer term self-signed certificate, and then (safely)
-copy the corresponding public key cert to the desired
-client machines (care must be taken the private key part
-is not stolen; you will be prompted for a passphrase).
-.IP
-So keep in mind no CA key creation or management
-(-sslGenCA and \fB-sslGenCert)\fR is needed for either of
-the above two common usage modes.
-.IP
-One might want to use \fB-sslGenCA\fR and \fB-sslGenCert\fR
-if you had a large number of VNC client and server
-workstations. That way the administrator could generate
-a single CA key with \fB-sslGenCA\fR and distribute its
-certificate part to all of the workstations.
-.IP
-Next, he could create signed VNC server keys
-(-sslGenCert server ...) for each workstation or user
-that then x11vnc would use to authenticate itself to
-any VNC client that has the CA cert.
-.IP
-Optionally, the admin could also make it so the
-VNC clients themselves are authenticated to x11vnc
-(-sslGenCert client ...) For this \fB-sslverify\fR would be
-pointed to the CA cert (and/or self-signed certs).
-.IP
-x11vnc will be able to use all of these cert and
-key files. On the VNC client side, they will need to
-be "imported" somehow. Web browsers have "Manage
-Certificates" actions as does the Java applet plugin
-Control Panel. stunnel can also use these files (see
-the ss_vncviewer example script in the FAQ and SSVNC.)
-.PP
-\fB-sslCRL\fR \fIpath\fR
-.IP
-Set the Certificate Revocation Lists (CRL) to \fIpath\fR.
-This setting applies for both \fB-ssl\fR and \fB-stunnel\fR modes.
-.IP
-If path is a file, the file contains one or more CRLs
-in PEM format. If path is a directory, it contains
-hash named files of CRLs in the usual OpenSSL manner.
-See the OpenSSL and
-.IR stunnel (8)
-documentation for
-more info.
-.IP
-This option only applies if \fB-sslverify\fR has been
-supplied: it checks for revocation along the
-certificate chain used to verify the VNC client.
-The \fB-sslCRL\fR setting will be ignored when \fB-sslverify\fR is
-not specified.
-.IP
-Note that if a CRL's expiration date has passed, all
-SSL connections will fail regardless of if they are
-related to the subject of the CRL or not.
-.IP
-Only rarely will one's x11vnc \fB-ssl\fR infrastructure be so
-large that this option would be useful (since normally
-maintaining the contents of the \fB-sslverify\fR file or
-directory should be enough.) However, when using
-x11vnc with a Certificate Authority (see \fB-sslGenCA)\fR
-to authenticate Clients via SSL/TLS, the \fB-sslCRL\fR option
-can be useful to revoke users' certs whose private SSL
-keys were lost or stolen (e.g. laptop.) This way a new
-CA cert+key does not need to be created and new signed
-client keys generated and distributed to all users.
-.IP
-To create a CRL file with revoked certificates the
-commands 'openssl ca \fB-revoke\fR ...' and 'openssl ca
-\fB-gencrl\fR ...' are useful. (Run them in ~/.vnc/certs)
-.PP
-\fB-sslGenCA\fR \fI[dir]\fR
-.IP
-Generate your own Certificate Authority private key,
-certificate, and other files in directory [dir].
-x11vnc then exits.
-.IP
-If [dir] is not supplied, a \fB-ssldir\fR setting is used,
-or otherwise ~/.vnc/certs is used.
-.IP
-This command also creates directories where server and
-client certs and keys will be stored. The
-.IR openssl (1)
-program must be installed on the system and available
-in PATH.
-.IP
-After the CA files and directories are created the
-x11vnc command exits; the VNC server is not run.
-.IP
-You will be prompted for information to put into the CA
-certificate. The info does not have to be accurate just
-as long as clients accept the cert for VNC connections.
-You will also need to supply a passphrase of at least
-4 characters for the CA private key.
-.IP
-Once you have generated the CA you can distribute
-its certificate part, [dir]/CA/cacert.pem, to other
-workstations where VNC viewers will be run. One will
-need to "import" this certificate in the applications,
-e.g. Web browser, Java applet plugin, stunnel, etc.
-Next, you can create and sign keys using the CA with
-the \fB-sslGenCert\fR option below.
-.IP
-Examples:
-x11vnc \fB-sslGenCA\fR
-x11vnc \fB-sslGenCA\fR ~/myCAdir
-x11vnc \fB-ssldir\fR ~/myCAdir \fB-sslGenCA\fR
-.IP
-(the last two lines are equivalent)
-.PP
-\fB-sslGenCert\fR \fItype\fR \fIname\fR
-.IP
-Generate a VNC server or client certificate and private
-key pair signed by the CA created previously with
-\fB-sslGenCA.\fR The
-.IR openssl (1)
-program must be installed
-on the system and available in PATH.
-.IP
-After the Certificate is generated x11vnc exits; the
-VNC server is not run.
-.IP
-The type of key to be generated is the string \fItype\fR.
-It is either "server" (i.e. for use by x11vnc) or
-"client" (for a VNC viewer). Note that typically
-only "server" is used: the VNC clients authenticate
-themselves by a non-public-key method (e.g. VNC or
-unix password). \fItype\fR is required.
-.IP
-An arbitrary default name you want to associate with
-the key is supplied by the \fIname\fR string. You can
-change it at the various prompts when creating the key.
-\fIname\fR is optional.
-.IP
-If name is left blank for clients keys then "nobody"
-is used. If left blank for server keys, then the
-primary server key: "server.pem" is created (this
-is the saved one referenced by "\fB-ssl\fR \fISAVE\fR" when the
-server is started)
-.IP
-If \fIname\fR begins with the string "self:" then
-a self-signed certificate is created instead of one
-signed by your CA key.
-.IP
-If \fIname\fR begins with the string "req:" then only a
-key (.key) and a certificate signing *request* (.req)
-are generated. You can then send the .req file to
-an external CA (even a professional one, e.g. Thawte)
-and then combine the .key and the received cert into
-the .pem file with the same basename.
-.IP
-The distinction between "server" and "client" is
-simply the choice of output filenames and sub-directory.
-This makes it so the \fB-ssl\fR SAVE-name option can easily
-pick up the x11vnc PEM file this option generates.
-And similarly makes it easy for the \fB-sslverify\fR option
-to pick up your client certs.
-.IP
-There is nothing special about the filename or directory
-location of either the "server" and "client" certs.
-You can rename the files or move them to wherever
-you like.
-.IP
-Precede this option with \fB-ssldir\fR [dir] to use a
-directory other than the default ~/.vnc/certs You will
-need to run \fB-sslGenCA\fR on that directory first before
-doing any \fB-sslGenCert\fR key creation.
-.IP
-Note you cannot recreate a cert with exactly the same
-distiguished name (DN) as an existing one. To do so,
-you will need to edit the [dir]/CA/index.txt file to
-delete the line.
-.IP
-Similar to \fB-sslGenCA,\fR you will be prompted to fill
-in some information that will be recorded in the
-certificate when it is created.
-.IP
-Tip: if you know the fully-qualified hostname other
-people will be connecting to, you can use that as the
-CommonName "CN" to avoid some applications (e.g. web
-browsers and java plugin) complaining that it does not
-match the hostname.
-.IP
-You will also need to supply the CA private key
-passphrase to unlock the private key created from
-\fB-sslGenCA.\fR This private key is used to sign the server
-or client certificate.
-.IP
-The "server" certs can be used by x11vnc directly by
-pointing to them via the \fB-ssl\fR [pem] option. The default
-file will be ~/.vnc/certs/server.pem. This one would
-be used by simply typing \fB-ssl\fR SAVE. The pem file
-contains both the certificate and the private key.
-server.crt file contains the cert only.
-.IP
-The "client" cert + private key file will need
-to be copied and imported into the VNC viewer
-side applications (Web browser, Java plugin,
-stunnel, etc.) Once that is done you can delete the
-"client" private key file on this machine since
-it is only needed on the VNC viewer side. The,
-e.g. ~/.vnc/certs/clients/<name>.pem contains both
-the cert and private key. The <name>.crt contains the
-certificate only.
-.IP
-NOTE: It is very important to know one should
-generate new keys with a passphrase. Otherwise if an
-untrusted user steals the key file he could use it to
-masquerade as the x11vnc server (or VNC viewer client).
-You will be prompted whether to encrypt the key with
-a passphrase or not. It is recommended that you do.
-One inconvenience to a passphrase is that it must
-be typed in EVERY time x11vnc or the client app is
-started up.
-.IP
-Examples:
-.IP
-x11vnc \fB-sslGenCert\fR server
-x11vnc \fB-ssl\fR SAVE \fB-display\fR :0 ...
-.IP
-and then on viewer using ss_vncviewer stunnel wrapper
-(see the FAQ):
-ss_vncviewer \fB-verify\fR ./cacert.crt hostname:0
-.IP
-(this assumes the cacert.crt cert from \fB-sslGenCA\fR
-was safely copied to the VNC viewer machine where
-ss_vncviewer is run)
-.IP
-Example using a name:
-.IP
-x11vnc \fB-sslGenCert\fR server charlie
-x11vnc \fB-ssl\fR SAVE-charlie \fB-display\fR :0 ...
-.IP
-Example for a client certificate (rarely used):
-.IP
-x11vnc \fB-sslGenCert\fR client roger
-scp ~/.vnc/certs/clients/roger.pem somehost:.
-rm ~/.vnc/certs/clients/roger.pem
-.IP
-x11vnc is then started with the option \fB-sslverify\fR
-~/.vnc/certs/clients/roger.crt (or simply \fB-sslverify\fR
-roger), and on the viewer user on somehost could do
-for example:
-.IP
-ss_vncviewer \fB-mycert\fR ./roger.pem hostname:0
-.IP
-If you set the env. var REQ_ARGS='...' it will be
-passed to openssl
-.IR req (1).
-A common use would be
-REQ_ARGS='-days 1095' to bump up the expiration date
-(3 years in this case).
-.PP
-\fB-sslEncKey\fR \fIpem\fR
-.IP
-Utility to encrypt an existing PEM file with a
-passphrase you supply when prompted. For that key to be
-used (e.g. by x11vnc) the passphrase must be supplied
-each time.
-.IP
-The "SAVE" notation described under \fB-ssl\fR applies as
-well. (precede this option with \fB-ssldir\fR [dir] to refer
-a directory besides the default ~/.vnc/certs)
-.IP
-The
-.IR openssl (1)
-program must be installed on the system
-and available in PATH. After the Key file is encrypted
-the x11vnc command exits; the VNC server is not run.
-.IP
-Examples:
-x11vnc \fB-sslEncKey\fR /path/to/foo.pem
-x11vnc \fB-sslEncKey\fR SAVE
-x11vnc \fB-sslEncKey\fR SAVE-charlie
-.PP
-\fB-sslCertInfo\fR \fIpem\fR
-.IP
-Prints out information about an existing PEM file.
-In addition the public certificate is also printed.
-The
-.IR openssl (1)
-program must be in PATH. Basically the
-command "openssl x509 \fB-text"\fR is run on the pem.
-.IP
-After the info is printed the x11vnc command exits;
-the VNC server is not run.
-.IP
-The "SAVE" notation described under \fB-ssl\fR applies
-as well.
-.IP
-Using "LIST" will give a list of all certs being
-managed (in the ~/.vnc/certs dir, use \fB-ssldir\fR to refer
-to another dir). "ALL" will print out the info for
-every managed key (this can be very long). Giving a
-client or server cert shortname will also try a lookup
-(e.g. \fB-sslCertInfo\fR charlie). Use "LISTL" or "LL"
-for a long (ls \fB-l\fR style) listing.
-.IP
-Using "HASHON" will create subdirs [dir]/HASH and
-[dir]/HASH with OpenSSL hash filenames (e.g. 0d5fbbf1.0)
-symlinks pointing up to the corresponding *.crt file.
-([dir] is ~/.vnc/certs or one given by \fB-ssldir.)\fR
-This is a useful way for other OpenSSL applications
-(e.g. stunnel) to access all of the certs without
-having to concatenate them. x11vnc will not use them
-unless you specifically reference them. "HASHOFF"
-removes these HASH subdirs.
-.IP
-The LIST, LISTL, LL, ALL, HASHON, HASHOFF words can
-also be lowercase, e.g. "list".
-.PP
-\fB-sslDelCert\fR \fIpem\fR
-.IP
-Prompts you to delete all .crt .pem .key .req files
-associated with [pem]. x11vnc then exits. "SAVE"
-and lookups as in \fB-sslCertInfo\fR apply as well.
-.PP
-\fB-sslScripts\fR
-.IP
-Prints out both the 'genCA' and 'genCert' x11vnc
-openssl wrapper scripts for you to examine, modify, etc.
-The scripts are printed to stdout and then the x11vnc
-program exits.
-.PP
-\fB-stunnel\fR \fI[pem]\fR
-.IP
-Use the
-.IR stunnel (8)
-(stunnel.mirt.net) to provide an
-encrypted SSL tunnel between viewers and x11vnc.
-.IP
-This external tunnel method was implemented prior to the
-integrated \fB-ssl\fR encryption described above. It still
-works well and avoids the requirement of linking with
-the OpenSSL libraries. This mode requires stunnel
-to be installed on the system and available via PATH
-(n.b. stunnel is often installed in sbin directories).
-Version 4.x of stunnel is assumed (but see \fB-stunnel3\fR
-below.)
-.IP
-[pem] is optional, use "\fB-stunnel\fR \fI/path/to/stunnel.pem\fR"
-to specify a PEM certificate file to pass to stunnel.
-See the \fB-ssl\fR option for more info on certificate files.
-.IP
-Whether or not your stunnel has its own certificate
-depends on your stunnel configuration; stunnel often
-generates one at install time. See your stunnel
-documentation for details. In any event, if you want to
-use this certificate you must supply the full path to it
-as [pem]. Note: the file may only be readable by root.
-.IP
-[pem] may also be the special strings "TMP", "SAVE",
-and "SAVE..." as described in the \fB-ssl\fR option.
-If [pem] is not supplied, "SAVE" is assumed.
-.IP
-Note that the VeNCrypt, ANONTLS, and "ANON" modes
-are not supported in \fB-stunnel\fR mode.
-.IP
-stunnel is started up as a child process of x11vnc and
-any SSL connections stunnel receives are decrypted and
-sent to x11vnc over a local socket. The strings
-"The SSL VNC desktop is ..." and "SSLPORT=..."
-are printed out at startup to indicate this.
-.IP
-The \fB-localhost\fR option is enforced by default to avoid
-people routing around the SSL channel. Use \fB-env\fR
-STUNNEL_DISABLE_LOCALHOST=1 to disable this security
-requirement.
-.IP
-Set \fB-env\fR STUNNEL_DEBUG=1 for more debugging printout.
-.IP
-Set \fB-env\fR STUNNEL_PROG=xxx to the full path of stunnel
-program you want to be used (e.g. /usr/bin/stunnel4).
-.IP
-Set \fB-env\fR STUNNEL_LISTEN=xxx to the address of the
-network interface to listen on (the default is to listen
-on all interfaces), e.g. STUNNEL_LISTEN=192.168.1.100.
-.IP
-A simple way to add IPv6 support is STUNNEL_LISTEN=::
-.IP
-Your VNC viewer will also need to be able to connect
-via SSL. Unfortunately not too many do this. See the
-information about SSL viewers under the \fB-ssl\fR option.
-The x11vnc project's SSVNC is an option.
-.IP
-Also, in the x11vnc distribution, patched TightVNC
-and UltraVNC Java applet jar files are provided in
-the classes/ssl directory that do SSL connections.
-Enable serving them with the \fB-http,\fR \fB-http_ssl,\fR or
-\fB-httpdir\fR (see the option descriptions for more info.)
-.IP
-Note that for the Java viewer applet usage the
-"?PORT=xxxx" in the various URLs printed at startup
-will need to be supplied to the web browser to connect
-properly.
-.IP
-Currently the automatic "single port" HTTPS mode of
-\fB-ssl\fR is not fully supported in \fB-stunnel\fR mode. However,
-it can be emulated via:
-.IP
-% x11vnc \fB-stunnel\fR \fB-http_ssl\fR \fB-http_oneport\fR ...
-.IP
-In general, it is also not too difficult to set up
-an stunnel or other SSL tunnel on the viewer side.
-A simple example on Unix using stunnel 3.x is:
-.IP
-% stunnel \fB-c\fR \fB-d\fR localhost:5901 \fB-r\fR remotehost:5900
-% vncviewer localhost:1
-.IP
-For Windows, stunnel has been ported to it and there
-are probably other such tools available. See the FAQ
-and SSVNC for more examples.
-.PP
-\fB-stunnel3\fR \fI[pem]\fR
-.IP
-Use version 3.x stunnel command line syntax instead of
-version 4.x. The \fB-http/-httpdir\fR Java applet serving
-is currently not available in this mode.
-.PP
-\fB-enc\fR \fIcipher:keyfile\fR
-.IP
-Use symmetric encryption with cipher "cipher"
-and secret key data in "keyfile". If keyfile is
-pw=<string> then "string" is used as the key data.
-.IP
-NOTE: It is recommended that you use SSL via the \fB-ssl\fR
-option instead of this option because SSL is well
-understood and takes great care to establish unique
-session keys and is more compatible with other software.
-Use this option if you do not want to deal with SSL
-certificates for authentication and do not want to
-use SSH but want some encryption for your VNC session.
-Or if you must interface with a symmetric key tunnel
-that you do not have control over.
-.IP
-Note that this mode will NOT work with the UltraVNC DSM
-plugins because they alter the RFB protocol in addition
-to tunnelling with the symmetric cipher (an unfortunate
-choice of implementation...)
-.IP
-cipher can be one of: arc4, aesv2, aes-cfb, blowfish,
-aes256, or 3des. See the OpenSSL documentation for
-more info. The keysize is 128 bits (except for aes256).
-Here is one way to make a keyfile with that many bits:
-.IP
-dd if=/dev/random of=./my.key bs=16 count=1
-.IP
-you will need to securely share this key with the other
-side of the VNC connection (See SSVNC for examples).
-.IP
-Example: \fB-enc\fR blowfish:./my.key
-Example: \fB-enc\fR blowfish:pw=swordfish
-.IP
-By default 16 bytes of random salt followed by 16 bytes
-of random initialization vector are sent at the very
-beginning of the stream. The other side must read these
-and initialize their cipher with them. These values
-make the session key unique (without them the security
-is minimal). Similarly, the other side must send us
-its random salt and IV with those same lengths.
-.IP
-The salt and key data are combined to create a session
-key using an md5 hash as described in
-.IR EVP_BytesToKey (3).
-.IP
-The exact call is: EVP_BytesToKey(Cipher, EVP_md5(),
-salt, keydata, len, 1, keystr, NULL); where salt is
-the random data as described above, and keydata is the
-shared secret key data. keystr is the resulting session
-key. The cipher is then seeded with keystr and uses
-the random initialization vector as its first block.
-.IP
-To modify the amount of random salt and initialization
-vector use cipher@n,m where n is the salt length and
-m the initialization vector length. E.g.
-.IP
-\fB-enc\fR aes-cfb@8,16:./my.key
-.IP
-It is not a good idea to set either one to zero,
-although you may be forced to if the other side of the
-tunnel is not under your control.
-.IP
-To skip the salt and EVP_BytesToKey MD5 entirely (no
-hashing is done: the keydata is directly inserted into
-the cipher) specify "-1" for the salt, e.g.
-.IP
-\fB-enc\fR blowfish@-1,16:./my.key
-.IP
-The message digest can also be changed to something
-besides the default MD5. Use cipher@md+n,m where "md"
-can be one of sha, sha1, md5, or ripe. For example:
-.IP
-\fB-enc\fR arc4@sha+8,16:./my.key
-.IP
-The SSVNC vnc viewer project supplies a symmetric
-encryption tool named "ultravnc_dsm_helper" that can
-be used on the viewer side. For example:
-.IP
-ssvncviewer exec='ultravnc_dsm_helper arc4 my.key 0 h:p'
-.IP
-where h:p is the hostname and port of the x11vnc server.
-ultravnc_dsm_helper may also be used standalone to
-provide a symmetric encryption tunnel for any viewer
-or server (VNC or otherwise.) The cipher (1st arg)
-is basically the same syntax as we use above.
-.IP
-Also see the 'Non-Ultra DSM' SSVNC option for the
-\'UltraVNC DSM Encryption Plugin' advanced option.
-.IP
-For both ways of using the viewer, you can specify the
-salt,ivec sizes (in GUI or, e.g. arc4@8,16).
-.PP
-\fB-https\fR \fI[port]\fR
-.IP
-Use a special, separate HTTPS port (-ssl and
-\fB-stunnel\fR modes only) for HTTPS Java viewer applet
-downloading. I.e. not 5900 and not 5800 (the defaults.)
-.IP
-BACKGROUND: In \fB-ssl\fR mode, it turns out you can use the
-single VNC port (e.g. 5900) for both VNC and HTTPS
-connections. (HTTPS is used to retrieve a SSL-aware
-VncViewer.jar applet that is provided with x11vnc).
-Since both use SSL the implementation was extended to
-detect if HTTP traffic (i.e. GET) is taking place and
-handle it accordingly. The URL would be, e.g.:
-.IP
-https://mymachine.org:5900/
-.IP
-This is convenient for firewalls, etc, because only one
-port needs to be allowed in. However, this heuristic
-adds a few seconds delay to each connection and can be
-unreliable (especially if the user takes much time to
-ponder the Certificate dialogs in his browser, Java VM,
-or VNC Viewer applet. That's right 3 separate "Are
-you sure you want to connect?" dialogs!)
-.IP
-END OF BACKGROUND.
-.IP
-USAGE: So use the \fB-https\fR option to provide a separate,
-more reliable HTTPS port that x11vnc will listen on. If
-[port] is not provided (or is 0), one is autoselected.
-The URL to use is printed out at startup.
-.IP
-The SSL Java applet directory is specified via the
-\fB-httpdir\fR option. If not supplied, \fB-https\fR will try
-to guess the directory as though the \fB-http\fR option
-was supplied.
-.PP
-\fB-httpsredir\fR \fI[port]\fR
-.IP
-In \fB-ssl\fR mode with the Java applet retrieved via HTTPS,
-when the HTML file containing applet parameters
-('index.vnc' or 'proxy.vnc') is sent do NOT set the
-applet PORT parameter to the actual VNC port but set it
-to "port" instead. If "port" is not supplied, then
-the port number is guessed from the Host: HTTP header.
-.IP
-This is useful when an incoming TCP connection
-redirection is performed by a router/gateway/firewall
-from one port to an internal machine where x11vnc is
-listening on a different port. The Java applet needs to
-connect to the firewall/router port, not the VNC port
-on the internal workstation. For example, one could
-redir from mygateway.com:443 to workstation:5900.
-.IP
-This spares the user from having to type in
-https://mygateway.com/?PORT=443 into their web
-browser. Note that port 443 is the default https port;
-other ports must be explicitly indicated, for example:
-https://mygateway.com:8000/?PORT=8000. To avoid having
-to include the PORT= in the browser URL, simply supply
-"\fB-httpsredir\fR" to x11vnc.
-.IP
-This option does not work in \fB-stunnel\fR mode.
-.IP
-More tricks: set the env var X11VNC_EXTRA_HTTPS_PARAMS
-to be extra URL parameters to use. This way you do
-not need to specify extra PARAMS in the index.vnc file.
-E.g. x11vnc \fB-env\fR X11VNC_EXTRA_HTTPS_PARAMS='?GET=1' ...
-.IP
-If you do not want to expose the non-SSL HTTP port to
-the network (i.e. you just want the single VNC/HTTPS
-port, e.g. 5900, open for connections) then specify the
-option \fB-env\fR X11VNC_HTTP_LISTEN_LOCALHOST=1 This way
-the connection to the LibVNCServer httpd server will
-only be available on localhost (note that in \fB-ssl\fR mode,
-HTTPS requests are redirected from SSL to the non-SSL
-LibVNCServer HTTP server.)
-.PP
-\fB-http_oneport\fR
-.IP
-For UN-encrypted connections mode (i.e. no \fB-ssl,\fR
-\fB-stunnel,\fR or \fB-enc\fR options), allow the Java VNC Viewer
-applet to be downloaded thru the VNC port via HTTP.
-.IP
-That is to say, you can use a single port for Java
-applet viewer connections by using a URL in your web
-browser like this, for example:
-.IP
-http://hostname:5900
-.IP
-The regular, two-port mode, URL http://hostname:5800
-will continue to work as well.
-.IP
-As mentioned above, this mode will NOT work with
-the \fB-ssl,\fR \fB-stunnel,\fR or \fB-enc\fR encryption options.
-Note that is it equivalent to '-enc none' (i.e. it
-uses the same detection mechanism as for HTTPS, but
-with no encryption.)
-.IP
-HTTPS single-port is on by default in \fB-ssl\fR encrypted
-mode (and \fB-enc\fR too), so you only need \fB-http_oneport\fR
-when doing non-SSL encrypted connections.
-.IP
-This mode could also be useful for SSH tunnels since
-it means only one port needs to be redirected.
-.IP
-The \fB-httpsredir\fR option may also be useful for this
-mode when using an SSH tunnel as well as for router
-port redirections.
-.IP
-Note that the \fB-env\fR X11VNC_HTTP_LISTEN_LOCALHOST=1
-option described above under \fB-httpsredir\fR applies for
-the LibVNCServer httpd server in all cases (ssl or not.)
-.PP
-\fB-ssh\fR \fIuser@host:disp\fR
-.IP
-Create a remote listening port on machine "host"
-via a SSH tunnel using the \fB-R\fR rport:localhost:lport
-method. lport will be the local x11vnc listening port,
-so a connection to rport (5900+disp) on "host"
-will reach x11vnc. E.g. fred@snoopy.com:0
-.IP
-This could be useful if a firewall/router prevents
-incoming connections to the x11vnc machine, but
-the ssh machine "host" can be reached by the VNC
-viewer. "user@" is not needed unless the remote unix
-username differs from the current one.
-.IP
-By default the remote sshd is usually configured to
-listen only on localhost for rport, so the viewer may
-need to ssh \fB-L\fR redir to "host" as well (See SSVNC to
-automate this). The sshd setting GatewayPorts enables
-listening on all interfaces for rport; viewers can
-reach it more easily.
-.IP
-"disp" is the VNC display for the remote SSH side,
-e.g. 0 corresponds to port 5900, etc. If disp is
-greater than 200 the value is used as the port. Use a
-negative value to force a low port, e.g. host:-80 will
-use port 80.
-.IP
-If ssh-agent is not active, then the ssh password needs
-to be entered in the terminal where x11vnc is running.
-.IP
-By default the remote ssh will issue a 'sleep 300' to
-wait for the incoming connection for 5 mins. To modify
-this use user@host:disp+secs.
-.IP
-If the remote SSH server is on a non-standard port
-(i.e. not 22) use user@host:port:disp+secs.
-.IP
-Note that the ssh process MAY NOT be killed when
-x11vnc exits. It tries by looking at
-.IR ps (1)
-output.
-.PP
-\fB-usepw\fR
-.IP
-If no other password method was supplied on the command
-line, first look for ~/.vnc/passwd and if found use it
-with \fB-rfbauth;\fR next, look for ~/.vnc/passwdfile and
-use it with \fB-passwdfile;\fR otherwise, prompt the user
-for a password to create ~/.vnc/passwd and use it with
-the \fB-rfbauth\fR option. If none of these succeed x11vnc
-exits immediately.
-.PP
-\fB-storepasswd\fR \fIpass\fR \fIfile\fR
-.IP
-Store password \fIpass\fR as the VNC password in the
-file \fIfile\fR. Once the password is stored the
-program exits. Use the password via "\fB-rfbauth\fR \fIfile\fR"
-.IP
-If called with no arguments, "x11vnc \fB-storepasswd",\fR
-the user is prompted for a password and it is stored
-in the file ~/.vnc/passwd. Called with one argument,
-that will be the file to store the prompted password in.
-.PP
-\fB-nopw\fR
-.IP
-Disable the big warning message when you use x11vnc
-without some sort of password.
-.PP
-\fB-accept\fR \fIstring\fR
-.IP
-Run a command (possibly to prompt the user at the
-X11 display) to decide whether an incoming client
-should be allowed to connect or not. \fIstring\fR is
-an external command run via
-.IR system (3)
-or some special
-cases described below. Be sure to quote \fIstring\fR
-if it contains spaces, shell characters, etc. If the
-external command returns 0 the client is accepted,
-otherwise the client is rejected. See below for an
-extension to accept a client view-only.
-.IP
-If x11vnc is running as root (say from
-.IR inetd (8)
-or from
-display managers
-.IR xdm (1)
-,
-.IR gdm (1)
-, etc), think about the
-security implications carefully before supplying this
-option (likewise for the \fB-gone\fR option).
-.IP
-Environment: The RFB_CLIENT_IP environment variable will
-be set to the incoming client IP number and the port
-in RFB_CLIENT_PORT (or -1 if unavailable). Similarly,
-RFB_SERVER_IP and RFB_SERVER_PORT (the x11vnc side
-of the connection), are set to allow identification
-of the tcp virtual circuit. The x11vnc process
-id will be in RFB_X11VNC_PID, a client id number in
-RFB_CLIENT_ID, and the number of other connected clients
-in RFB_CLIENT_COUNT. RFB_MODE will be "accept".
-RFB_STATE will be PROTOCOL_VERSION, SECURITY_TYPE,
-AUTHENTICATION, INITIALISATION, NORMAL, or UNKNOWN
-indicating up to which state the client has achieved.
-RFB_LOGIN_VIEWONLY will be 0, 1, or -1 (unknown).
-RFB_USERNAME, RFB_LOGIN_TIME, and RFB_CURRENT_TIME may
-also be set.
-.IP
-If \fIstring\fR is "popup" then a builtin popup window
-is used. The popup will time out after 120 seconds,
-use "popup:N" to modify the timeout to N seconds
-(use 0 for no timeout).
-.IP
-In the case of "popup" and when the \fB-unixpw\fR option
-is specified, then a *second* window will be popped
-up after the user successfully logs in via his UNIX
-password. This time the user will be identified as
-UNIX:username@hostname, the "UNIX:" prefix indicates
-which user the viewer logged as via \fB-unixpw.\fR The first
-popup is only for whether to allow him to even *try*
-to login via unix password.
-.IP
-If \fIstring\fR is "xmessage" then an
-.IR xmessage (1)
-invocation is used for the command. xmessage must be
-installed on the machine for this to work.
-.IP
-Both "popup" and "xmessage" will present an option
-for accepting the client "View-Only" (the client
-can only watch). This option will not be presented if
-\fB-viewonly\fR has been specified, in which case the entire
-display is view only.
-.IP
-If the user supplied command is prefixed with something
-like "yes:0,no:*,view:3 mycommand ..." then this
-associates the numerical command return code with
-the actions: accept, reject, and accept-view-only,
-respectively. Use "*" instead of a number to indicate
-the default action (in case the command returns an
-unexpected value). E.g. "no:*" is a good choice.
-.IP
-Note that x11vnc blocks while the external command
-or popup is running (other clients may see no updates
-during this period). So a person sitting a the physical
-display is needed to respond to an popup prompt. (use
-a 2nd x11vnc if you lock yourself out).
-.IP
-More \fB-accept\fR tricks: use "popupmouse" to only allow
-mouse clicks in the builtin popup to be recognized.
-Similarly use "popupkey" to only recognize
-keystroke responses. These are to help avoid the
-user accidentally accepting a client by typing or
-clicking. All 3 of the popup keywords can be followed
-by +N+M to supply a position for the popup window.
-The default is to center the popup window.
-.PP
-\fB-afteraccept\fR \fIstring\fR
-.IP
-As \fB-accept,\fR except to run a user supplied command after
-a client has been accepted and authenticated. RFB_MODE
-will be set to "afteraccept" and the other RFB_*
-variables are as in \fB-accept.\fR Unlike \fB-accept,\fR the
-command return code is not interpreted by x11vnc.
-Example: \fB-afteraccept\fR 'killall xlock &'
-.PP
-\fB-gone\fR \fIstring\fR
-.IP
-As \fB-accept,\fR except to run a user supplied command when
-a client goes away (disconnects). RFB_MODE will be
-set to "gone" and the other RFB_* variables are as
-in \fB-accept.\fR The "popup" actions apply as well.
-Unlike \fB-accept,\fR the command return code is not
-interpreted by x11vnc. Example: \fB-gone\fR 'xlock &'
-.PP
-\fB-users\fR \fIlist\fR
-.IP
-If x11vnc is started as root (say from
-.IR inetd (8)
-or from
-display managers
-.IR xdm (1)
-,
-.IR gdm (1)
-, etc), then as soon
-as possible after connections to the X display are
-established try to switch to one of the users in the
-comma separated \fIlist\fR. If x11vnc is not running as
-root this option is ignored.
-.IP
-Why use this option? In general it is not needed since
-x11vnc is already connected to the X display and can
-perform its primary functions. The option was added
-to make some of the *external* utility commands x11vnc
-occasionally runs work properly. In particular under
-GNOME and KDE to implement the "\fB-solid\fR \fIcolor\fR" feature
-external commands (gconftool-2 and dcop) unfortunately
-must be run as the user owning the desktop session.
-Since this option switches userid it also affects the
-userid used to run the processes for the \fB-accept\fR and
-\fB-gone\fR options. It also affects the ability to read
-files for options such as \fB-connect,\fR \fB-allow,\fR and \fB-remap\fR
-and also the ultra and tight filetransfer feature if
-enabled. Note that the \fB-connect\fR file is also sometimes
-written to.
-.IP
-So be careful with this option since in some situations
-its use can decrease security.
-.IP
-In general the switch to a user will only take place
-if the display can still be successfully opened as that
-user (this is primarily to try to guess the actual owner
-of the session). Example: "\fB-users\fR \fIfred,wilma,betty\fR".
-Note that a malicious local user "barney" by
-quickly using "xhost +" when logging in may possibly
-get the x11vnc process to switch to user "fred".
-What happens next?
-.IP
-Under display managers it may be a long time before
-the switch succeeds (i.e. a user logs in). To instead
-make it switch immediately regardless if the display
-can be reopened prefix the username with the "+"
-character. E.g. "\fB-users\fR \fI+bob\fR" or "\fB-users\fR \fI+nobody\fR".
-.IP
-The latter (i.e. switching immediately to user
-"nobody") is the only obvious use of the \fB-users\fR option
-that increases security.
-.IP
-Use the following notation to associate a group with
-a user: user1.group1,user2.group2,... Note that
-.IR initgroups (2)
-will still be called first to try to
-switch to ALL of a user's groups (primary and additional
-groups). Only if that fails or it is not available
-then the single group specified as above (or the user's
-primary group if not specified) is switched to with
-.IR setgid (2).
-Use \fB-env\fR X11VNC_SINGLE_GROUP=1 to prevent
-trying
-.IR initgroups (2)
-and only switch to the single
-group. This sort of setting is only really needed to
-make the ultra or tight filetransfer permissions work
-properly. This format applies to any comma separated list
-of users, even the special "=" modes described below.
-.IP
-In \fB-unixpw\fR mode, if "\fB-users\fR \fIunixpw=\fR" is supplied
-then after a user authenticates himself via the
-\fB-unixpw\fR mechanism, x11vnc will try to switch to that
-user as though "\fB-users\fR \fI+username\fR" had been supplied.
-If you want to limit which users this will be done for,
-provide them as a comma separated list after "unixpw="
-Groups can also be specified as described above.
-.IP
-Similarly, in \fB-ssl\fR mode, if "\fB-users\fR \fIsslpeer=\fR" is
-supplied then after an SSL client authenticates with his
-cert (the \fB-sslverify\fR option is required for this) x11vnc
-will extract a UNIX username from the "emailAddress"
-field (username@hostname.com) of the "Subject" of the
-x509 SSL cert and then try to switch to that user as
-though "\fB-users\fR \fI+username\fR" had been supplied. If you
-want to limit which users this will be done for, provide
-them as a comma separated list after "sslpeer=".
-Set the env. var X11VNC_SSLPEER_CN to use the Common
-Name (normally a hostname) instead of the Email field.
-.IP
-NOTE: for sslpeer= mode the x11vnc administrator must
-take care that any client certs he adds to \fB-sslverify\fR
-have the intended UNIX username in the "emailAddress"
-field of the cert. Otherwise a user may be able to
-log in as another. This command can be of use in
-checking: "openssl x509 \fB-text\fR \fB-in\fR file.crt", see the
-"Subject:" line. Also, along with the normal RFB_*
-env. vars. (see \fB-accept)\fR passed to external cmd=
-commands, RFB_SSL_CLIENT_CERT will be set to the
-client's x509 certificate string.
-.IP
-The sslpeer= mode can aid finding X sessions via the
-FINDDISPLAY and FINDCREATEDISPLAY mechanisms.
-.IP
-To immediately switch to a user *before* connections
-to the X display are made or any files opened use the
-"=" character: "\fB-users\fR \fI=bob\fR". That user needs to
-be able to open the X display and any files of course.
-.IP
-The special user "guess=" means to examine the utmpx
-database (see
-.IR who (1)
-) looking for a user attached to
-the display number (from DISPLAY or \fB-display\fR option)
-and try him/her. To limit the list of guesses, use:
-"\fB-users\fR \fIguess=bob,betty\fR".
-.IP
-Even more sinister is the special user "lurk="
-that means to try to guess the DISPLAY from the utmpx
-login database as well. So it "lurks" waiting for
-anyone to log into an X session and then connects to it.
-Specify a list of users after the = to limit which users
-will be tried. To enable a different searching mode, if
-the first user in the list is something like ":0" or
-":0-2" that indicates a range of DISPLAY numbers that
-will be tried (regardless of whether they are in the
-utmpx database) for all users that are logged in. Also
-see the "\fB-display\fR \fIWAIT:...\fR" functionality. Examples:
-"\fB-users\fR \fIlurk=\fR" and also "\fB-users\fR \fIlurk=:0-1,bob,mary\fR"
-.IP
-Be especially careful using the "guess=" and "lurk="
-modes. They are not recommended for use on machines
-with untrustworthy local users.
-.PP
-\fB-noshm\fR
-.IP
-Do not use the MIT-SHM extension for the polling.
-Remote displays can be polled this way: be careful this
-can use large amounts of network bandwidth. This is
-also of use if the local machine has a limited number
-of shm segments and \fB-onetile\fR is not sufficient.
-.PP
-\fB-flipbyteorder\fR
-.IP
-Sometimes needed if remotely polled host has different
-endianness. Ignored unless \fB-noshm\fR is set.
-.PP
-\fB-onetile\fR
-.IP
-Do not use the new copy_tiles() framebuffer mechanism,
-just use 1 shm tile for polling. Limits shm segments
-used to 3.
-.IP
-To disable any automatic shm reduction set the
-env. var. X11VNC_NO_LIMIT_SHM.
-.PP
-\fB-solid\fR \fI[color]\fR
-.IP
-To improve performance, when VNC clients are connected
-try to change the desktop background to a solid color.
-The [color] is optional: the default color is "cyan4".
-For a different one specify the X color (rgb.txt name,
-e.g. "darkblue" or numerical "#RRGGBB").
-.IP
-Currently this option only works on GNOME, KDE, CDE,
-XFCE, and classic X (i.e. with the background image
-on the root window). The "gconftool-2", "dcop"
-and "xfconf-query" external commands are run for
-GNOME, KDE, and XFCE respectively. This also works
-on native MacOSX. (There is no color selection for
-MacOSX or XFCE.) Other desktops won't work, (send
-us the corresponding commands if you find them).
-If x11vnc is running as root (
-.IR inetd (8)
-or
-.IR gdm (1)
-),
-the \fB-users\fR option may be needed for GNOME, KDE, XFCE.
-If x11vnc guesses your desktop incorrectly, you can
-force it by prefixing color with "gnome:", "kde:",
-"cde:", "xfce:", or "root:".
-.IP
-Update: \fB-solid\fR no longer works on KDE4.
-.IP
-This mode works in a limited way on the Mac OS X Console
-with one color ('kelp') using the screensaver writing
-to the background. Look in "~/Library/Screen Savers"
-for VncSolidColor.png to change the color.
-.PP
-\fB-blackout\fR \fIstring\fR
-.IP
-Black out rectangles on the screen. \fIstring\fR is a
-comma separated list of WxH+X+Y type geometries for
-each rectangle. If one of the items on the list is the
-string "noptr" the mouse pointer will not be allowed
-to go into a blacked out region.
-.PP
-\fB-xinerama,\fR \fB-noxinerama\fR
-.IP
-If your screen is composed of multiple monitors
-glued together via XINERAMA, and that screen is
-not a rectangle this option will try to guess the
-areas to black out (if your system has libXinerama).
-default: \fB-xinerama\fR
-.IP
-In general, we have noticed on XINERAMA displays you may
-need to use the "\fB-xwarppointer\fR" option if the mouse
-pointer misbehaves and it is enabled by default. Use
-"\fB-noxwarppointer\fR" if you do not want this.
-.PP
-\fB-xtrap\fR
-.IP
-Use the DEC-XTRAP extension for keystroke and mouse
-input insertion. For use on legacy systems, e.g. X11R5,
-running an incomplete or missing XTEST extension.
-By default DEC-XTRAP will be used if XTEST server grab
-control is missing, use \fB-xtrap\fR to do the keystroke and
-mouse insertion via DEC-XTRAP as well.
-.PP
-\fB-xrandr\fR \fI[mode]\fR
-.IP
-If the display supports the XRANDR (X Resize, Rotate
-and Reflection) extension, and you expect XRANDR events
-to occur to the display while x11vnc is running, this
-options indicates x11vnc should try to respond to
-them (as opposed to simply crashing by assuming the
-old screen size). See the
-.IR xrandr (1)
-manpage and run
-\'xrandr \fB-q'\fR for more info. [mode] is optional and
-described below.
-.IP
-Since watching for XRANDR events and trapping errors
-increases polling overhead, only use this option if
-XRANDR changes are expected. For example on a rotatable
-screen PDA or laptop, or using a XRANDR-aware Desktop
-where you resize often. It is best to be viewing with a
-vncviewer that supports the NewFBSize encoding, since it
-knows how to react to screen size changes. Otherwise,
-LibVNCServer tries to do so something reasonable for
-viewers that cannot do this (portions of the screen
-may be clipped, unused, etc).
-.IP
-Note: the default now is to check for XRANDR events, but
-do not trap every X call that may fail due to resize.
-If a resize event is received, the full \fB-xrandr\fR mode
-is enabled. To disable even checking for events supply:
-\fB-noxrandr.\fR
-.IP
-"mode" defaults to "resize", which means create a
-new, resized, framebuffer and hope all viewers can cope
-with the change. "newfbsize" means first disconnect
-all viewers that do not support the NewFBSize VNC
-encoding, and then resize the framebuffer. "exit"
-means disconnect all viewer clients, and then terminate
-x11vnc.
-.PP
-\fB-rotate\fR \fIstring\fR
-.IP
-Rotate and/or flip the framebuffer view exported by VNC.
-This transformation is independent of XRANDR and is
-done in software in main memory and so may be slower.
-This mode could be useful on a handheld with portrait or
-landscape modes that do not correspond to the scanline
-order of the actual framebuffer. \fIstring\fR can be:
-.IP
-x flip along x-axis
-y flip along y-axis
-xy flip along x- and y-axes
-+90 rotate 90 degrees clockwise
-\fB-90\fR rotate 90 degrees counter-clockwise
-+90x rotate 90 degrees CW, then flip along x
-+90y rotate 90 degrees CW, then flip along y
-.IP
-these give all possible rotations and reflections.
-.IP
-Aliases: same as xy: yx, +180, \fB-180,\fR 180
-same as \fB-90:\fR +270, 270
-same as +90: 90, (ditto for 90x, 90y)
-.IP
-Like \fB-scale,\fR this transformation is applied at the very
-end of any chain of framebuffer transformations and so
-any options with geometries, e.g. \fB-blackout,\fR \fB-clip,\fR etc.
-are relative to the original X (or \fB-rawfb)\fR framebuffer,
-not the final one sent to VNC viewers.
-.IP
-If you do not want the cursor shape to be rotated
-prefix \fIstring\fR with "nc:", e.g. "nc:+90",
-"nc:xy", etc.
-.PP
-\fB-padgeom\fR \fIWxH\fR
-.IP
-Whenever a new vncviewer connects, the framebuffer is
-replaced with a fake, solid black one of geometry WxH.
-Shortly afterwards the framebuffer is replaced with the
-real one. This is intended for use with vncviewers
-that do not support NewFBSize and one wants to make
-sure the initial viewer geometry will be big enough
-to handle all subsequent resizes (e.g. under \fB-xrandr,\fR
-\fB-remote\fR id:windowid, rescaling, etc.)
-.IP
-In \fB-unixpw\fR mode this sets the size of the login screen.
-Use "once:WxH" it ignore padgeom after the login
-screen is set up.
-.PP
-\fB-o\fR \fIlogfile\fR
-.IP
-Write stderr messages to file \fIlogfile\fR instead of to
-the terminal. Same as "\fB-logfile\fR \fIfile\fR". To append
-to the file use "\fB-oa\fR \fIfile\fR" or "\fB-logappend\fR \fIfile\fR".
-If \fIlogfile\fR contains the string "%VNCDISPLAY"
-it is expanded to the vnc display (the name may need
-to be guessed at.) "%HOME" works too.
-.PP
-\fB-flag\fR \fIfile\fR
-.IP
-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.
-.PP
-\fB-norc\fR
-.IP
-Do not process any .x11vncrc file for options.
-.PP
-\fB-env\fR \fIVAR=VALUE\fR
-.IP
-Set the environment variable 'VAR' to value 'VALUE'
-at x11vnc startup. This is a convenience utility to
-avoid shell script wrappers, etc. to set the env. var.
-You may specify as many of these as needed on the
-command line.
-.PP
-\fB-prog\fR \fI/path/to/x11vnc\fR
-.IP
-Set the full path to the x11vnc program for cases when
-it cannot be determined from argv[0] (e.g. tcpd/inetd)
-.PP
-\fB-h,\fR \fB-help\fR
-.IP
-Print this help text.
--?, \fB-opts\fR Only list the x11vnc options.
-.PP
-\fB-V,\fR \fB-version\fR
-.IP
-Print program version and last modification date.
-.PP
-\fB-license\fR
-.IP
-Print out license information. Same as \fB-copying\fR and
-\fB-warranty.\fR
-.PP
-\fB-dbg\fR
-.IP
-Instead of exiting after cleaning up, run a simple
-"debug crash shell" when fatal errors are trapped.
-.PP
-\fB-q,\fR \fB-quiet\fR
-.IP
-Be quiet by printing less informational output to
-stderr. (use \fB-noquiet\fR to undo an earlier \fB-quiet.)\fR
-.IP
-The \fB-quiet\fR option does not eliminate all informational
-output, it only reduces it. It is ignored in most
-auxiliary usage modes, e.g. \fB-storepasswd.\fR To eliminate
-all output use: 2>/dev/null 1>&2, etc.
-.PP
-\fB-v,\fR \fB-verbose\fR
-.IP
-Print out more information to stderr.
-.PP
-\fB-bg\fR
-.IP
-Go into the background after screen setup. Messages to
-stderr are lost unless \fB-o\fR logfile is used. Something
-like this could be useful in a script:
-.IP
-port=`ssh -t $host "x11vnc -display :0 -bg" | grep PORT`
-.IP
-port=`echo "$port" | sed -e 's/PORT=//'`
-.IP
-port=`expr $port - 5900`
-.IP
-vncviewer $host:$port
-.PP
-\fB-modtweak,\fR \fB-nomodtweak\fR
-.IP
-Option \fB-modtweak\fR automatically tries to adjust the AltGr
-and Shift modifiers for differing language keyboards
-between client and host. Otherwise, only a single key
-press/release of a Keycode is simulated (i.e. ignoring
-the state of the modifiers: this usually works for
-identical keyboards). Also useful in resolving cases
-where a Keysym is bound to multiple keys (e.g. "<" + ">"
-and "," + "<" keys). Default: \fB-modtweak\fR
-.IP
-If you are having trouble with with keys and \fB-xkb\fR or
-\fB-noxkb,\fR and similar things don't help, try \fB-nomodtweak.\fR
-.IP
-On some HP-UX systems it is been noted that they have
-an odd keymapping where a single keycode will have a
-keysym, e.g. "#", up to three times. You can check
-via "xmodmap \fB-pk"\fR or the \fB-dk\fR option. The failure
-is when you try to type "#" it yields "3". If you
-see this problem try setting the environment variable
-MODTWEAK_LOWEST=1 to see if it helps.
-.PP
-\fB-xkb,\fR \fB-noxkb\fR
-.IP
-When in modtweak mode, use the XKEYBOARD extension (if
-the X display supports it) to do the modifier tweaking.
-This is powerful and should be tried if there are still
-keymapping problems when using \fB-modtweak\fR by itself.
-The default is to check whether some common keysyms,
-e.g. !, @, [, are only accessible via \fB-xkb\fR mode and if
-so then automatically enable the mode. To disable this
-automatic detection use \fB-noxkb.\fR
-.IP
-When \fB-xkb\fR mode is active you can set these env. vars.
-They apply only when there is ambiguity as to which
-key to choose (i.e the mapping is not one-to-one).
-NOKEYHINTS=1: for up ascii keystrokes do not use score
-hints saved when the key was pressed down. NOANYDOWN=1:
-for up keystrokes do not resort to searching through
-keys that are currently pressed down. KEYSDOWN=N:
-remember the last N keys press down for tie-breaking
-when an up keystroke comes in.
-.PP
-\fB-capslock\fR
-.IP
-When in \fB-modtweak\fR (the default) or \fB-xkb\fR mode,
-if a keysym in the range A-Z comes in check the X
-server to see if the Caps_Lock is set. If it is do
-not artificially press Shift to generate the keysym.
-This will enable the CapsLock key to behave correctly
-in some circumstances: namely *both* the VNC viewer
-machine and the x11vnc X server are in the CapsLock
-on state. If one side has CapsLock on and the other
-off and the keyboard is not behaving as you think it
-should you should correct the CapsLock states (hint:
-pressing CapsLock inside and outside of the viewer can
-help toggle them both to the correct state). However,
-for best results do not use this option, but rather
-*only* enable CapsLock on the VNC viewer side (i.e. by
-pressing CapsLock outside of the viewer window, also
-\fB-skip_lockkeys\fR below). Also try \fB-nomodtweak\fR for a
-possible workaround.
-.PP
-\fB-skip_lockkeys,\fR \fB-noskip_lockkeys\fR
-.IP
-Have x11vnc ignore all Caps_Lock, Shift_Lock, Num_Lock,
-Scroll_Lock keysyms received from viewers. The idea is
-you press Caps_Lock on the VNC Viewer side but that does
-not change the lock state in the x11vnc-side X server.
-Nevertheless your capitalized letters come in over
-the wire and are applied correctly to the x11vnc-side
-X server. Note this mode probably won't do what you
-want in \fB-nomodtweak\fR mode. Also, a kludge for KP_n
-digits is always done in this mode: they are mapped to
-regular digit keysyms. See also \fB-capslock\fR above.
-The default is \fB-noskip_lockkeys.\fR
-.PP
-\fB-skip_keycodes\fR \fIstring\fR
-.IP
-Ignore the comma separated list of decimal keycodes.
-Perhaps these are keycodes not on your keyboard but
-your X server thinks exist. Currently only applies
-to \fB-xkb\fR mode. Use this option to help x11vnc in the
-reverse problem it tries to solve: Keysym -> Keycode(s)
-when ambiguities exist (more than one Keycode per
-Keysym). Run 'xmodmap \fB-pk'\fR to see your keymapping.
-Example: "\fB-skip_keycodes\fR \fI94,114\fR"
-.PP
-\fB-sloppy_keys\fR
-.IP
-Experimental option that tries to correct some
-"sloppy" key behavior. E.g. if at the viewer you
-press Shift+Key but then release the Shift before
-Key that could give rise to extra unwanted characters
-(usually only between keyboards of different languages).
-Only use this option if you observe problems with
-some keystrokes.
-.PP
-\fB-skip_dups,\fR \fB-noskip_dups\fR
-.IP
-Some VNC viewers send impossible repeated key events,
-e.g. key-down, key-down, key-up, key-up all for the same
-key, or 20 downs in a row for the same modifier key!
-Setting \fB-skip_dups\fR means to skip these duplicates and
-just process the first event. Note: some VNC viewers
-assume they can send down's without the corresponding
-up's and so you should not set this option for
-these viewers (symptom: some keys do not autorepeat)
-Default: \fB-noskip_dups\fR
-.PP
-\fB-add_keysyms,\fR \fB-noadd_keysyms\fR
-.IP
-If a Keysym is received from a VNC viewer and that
-Keysym does not exist in the X server, then add the
-Keysym to the X server's keyboard mapping on an unused
-key. Added Keysyms will be removed periodically and
-also when x11vnc exits. Default: \fB-add_keysyms\fR
-.PP
-\fB-clear_mods\fR
-.IP
-At startup and exit clear the modifier keys by sending
-KeyRelease for each one. The Lock modifiers are skipped.
-Used to clear the state if the display was accidentally
-left with any pressed down.
-.PP
-\fB-clear_keys\fR
-.IP
-As \fB-clear_mods,\fR except try to release ANY pressed key.
-Note that this option and \fB-clear_mods\fR can interfere
-with a person typing at the physical keyboard.
-.PP
-\fB-clear_all\fR
-.IP
-As \fB-clear_keys,\fR except try to release any CapsLock,
-NumLock, etc. locks as well.
-.PP
-\fB-remap\fR \fIstring\fR
-.IP
-Read Keysym remappings from file named \fIstring\fR.
-Format is one pair of Keysyms per line (can be name
-or hex value) separated by a space. If no file named
-\fIstring\fR exists, it is instead interpreted as this
-form: key1-key2,key3-key4,... See <X11/keysymdef.h>
-header file for a list of Keysym names, or use
-.IR xev (1).
-.IP
-To map a key to a button click, use the fake Keysyms
-"Button1", ..., etc. E.g: "\fB-remap\fR \fISuper_R-Button2\fR"
-(useful for pasting on a laptop)
-.IP
-I use these if the machine I am viewing from does not
-have a scrollwheel or I don't like using the one it has:
-.IP
-\fB-remap\fR Super_R-Button4,Menu-Button5
-\fB-remap\fR KP_Add-Button4,KP_Enter-Button5
-.IP
-the former would be used on a PC, the latter on a
-MacBook. This way those little used keys can be used
-to generate bigger hops than the Up and Down arrows
-provide. One can scroll through text or web pages more
-quickly this way (especially if x11vnc scroll detection
-is active.)
-.IP
-Use Button44, Button12, etc. for multiple clicks.
-.IP
-To disable a keysym (i.e. make it so it will not be
-injected), remap it to "NoSymbol" or "None".
-.IP
-Dead keys: "dead" (or silent, mute) keys are keys that
-do not produce a character but must be followed by a 2nd
-keystroke. This is often used for accenting characters,
-e.g. to put "`" on top of "a" by pressing the dead
-key and then "a". Note that this interpretation
-is not part of core X11, it is up to the toolkit or
-application to decide how to react to the sequence.
-The X11 names for these keysyms are "dead_grave",
-"dead_acute", etc. However some VNC viewers send the
-keysyms "grave", "acute" instead thereby disabling
-the accenting. To work around this \fB-remap\fR can be used.
-For example "\fB-remap\fR \fIgrave-dead_grave,acute-dead_acute\fR"
-.IP
-As a convenience, "\fB-remap\fR \fIDEAD\fR" applies these remaps:
-.IP
- g grave-dead_grave
- a acute-dead_acute
- c asciicircum-dead_circumflex
- t asciitilde-dead_tilde
- m macron-dead_macron
- b breve-dead_breve
- D abovedot-dead_abovedot
- d diaeresis-dead_diaeresis
- o degree-dead_abovering
- A doubleacute-dead_doubleacute
- r caron-dead_caron
- e cedilla-dead_cedilla
-.IP
-.IP
-If you just want a subset use the first letter
-label, e.g. "\fB-remap\fR \fIDEAD=ga\fR" to get the first two.
-Additional remaps may also be supplied via commas,
-e.g. "\fB-remap\fR \fIDEAD=ga,Super_R-Button2\fR". Finally,
-"DEAD=missing" means to apply all of the above as
-long as the left hand member is not already in the
-X11 keymap.
-.PP
-\fB-norepeat,\fR \fB-repeat\fR
-.IP
-Option \fB-norepeat\fR disables X server key auto repeat when
-VNC clients are connected and VNC keyboard input is
-not idle for more than 5 minutes. This works around a
-repeating keystrokes bug (triggered by long processing
-delays between key down and key up client events:
-either from large screen changes or high latency).
-Default: \fB-norepeat\fR
-.IP
-You can set the env. var. X11VNC_IDLE_TIMEOUT to the
-number of idle seconds you want (5min = 300secs).
-.IP
-Note: your VNC viewer side will likely do autorepeating,
-so this is no loss unless someone is simultaneously at
-the real X display.
-.IP
-Use "\fB-norepeat\fR \fIN\fR" to set how many times norepeat will
-be reset if something else (e.g. X session manager)
-undoes it. The default is 2. Use a negative value
-for unlimited resets.
-.PP
-\fB-nofb\fR
-.IP
-Ignore video framebuffer: only process keyboard and
-pointer. Intended for use with Win2VNC and x2vnc
-dual-monitor setups.
-.PP
-\fB-nobell\fR
-.IP
-Do not watch for XBell events. (no beeps will be heard)
-Note: XBell monitoring requires the XKEYBOARD extension.
-.PP
-\fB-nosel\fR
-.IP
-Do not manage exchange of X selection/cutbuffer between
-VNC viewers and the X server at all.
-.PP
-\fB-noprimary\fR
-.IP
-Do not poll the PRIMARY selection for changes to send
-back to clients. (PRIMARY is still set on received
-changes, however).
-.PP
-\fB-nosetprimary\fR
-.IP
-Do not set the PRIMARY selection for changes received
-from VNC clients.
-.PP
-\fB-noclipboard\fR
-.IP
-Do not poll the CLIPBOARD selection for changes to send
-back to clients. (CLIPBOARD is still set on received
-changes, however).
-.PP
-\fB-nosetclipboard\fR
-.IP
-Do not set the CLIPBOARD selection for changes
-received from VNC clients.
-.PP
-\fB-seldir\fR \fIstring\fR
-.IP
-If direction string is "send", only send the selection
-to viewers, and if it is "recv" only receive it from
-viewers. To work around apps setting the selection
-too frequently and messing up the other end. You can
-actually supply a comma separated list of directions,
-including "debug" to turn on debugging output.
-.PP
-\fB-cursor\fR \fI[mode],\fR \fB-nocursor\fR
-.IP
-Sets how the pointer cursor shape (little icon at the
-mouse pointer) should be handled. The "mode" string
-is optional and is described below. The default
-is to show some sort of cursor shape(s). How this
-is done depends on the VNC viewer and the X server.
-Use \fB-nocursor\fR to disable cursor shapes completely.
-.IP
-Some VNC viewers support the TightVNC CursorPosUpdates
-and CursorShapeUpdates extensions (cuts down on
-network traffic by not having to send the cursor image
-every time the pointer is moved), in which case these
-extensions are used (see \fB-nocursorshape\fR and \fB-nocursorpos\fR
-below to disable). For other viewers the cursor shape
-is written directly to the framebuffer every time the
-pointer is moved or changed and gets sent along with
-the other framebuffer updates. In this case, there
-will be some lag between the vnc viewer pointer and
-the remote cursor position.
-.IP
-If the X display supports retrieving the cursor shape
-information from the X server, then the default is
-to use that mode. On Solaris this can be done with
-the SUN_OVL extension using \fB-overlay\fR (see also the
-\fB-overlay_nocursor\fR option). A similar overlay scheme
-is used on IRIX. Xorg (e.g. Linux) and recent Solaris
-Xsun servers support the XFIXES extension to retrieve
-the exact cursor shape from the X server. If XFIXES
-is present it is preferred over Overlay and is used by
-default (see \fB-noxfixes\fR below). This can be disabled
-with \fB-nocursor,\fR and also some values of the "mode"
-option below.
-.IP
-Note that under XFIXES cursors with transparency (alpha
-channel) will usually not be exactly represented and one
-may find Overlay preferable. See also the \fB-alphacut\fR
-and \fB-alphafrac\fR options below as fudge factors to try
-to improve the situation for cursors with transparency
-for a given theme.
-.IP
-The "mode" string can be used to fine-tune the
-displaying of cursor shapes. It can be used the
-following ways:
-.IP
-"\fB-cursor\fR \fIarrow\fR" - just show the standard arrow
-nothing more or nothing less.
-.IP
-"\fB-cursor\fR \fInone\fR" - same as "\fB-nocursor\fR"
-.IP
-"\fB-cursor\fR \fIX\fR" - when the cursor appears to be on the
-root window, draw the familiar X shape. Some desktops
-such as GNOME cover up the root window completely,
-and so this will not work, try "X1", etc, to try to
-shift the tree depth. On high latency links or slow
-machines there will be a time lag between expected and
-the actual cursor shape.
-.IP
-"\fB-cursor\fR \fIsome\fR" - like "X" but use additional
-heuristics to try to guess if the window should have
-a windowmanager-like resizer cursor or a text input
-I-beam cursor. This is a complete hack, but may be
-useful in some situations because it provides a little
-more feedback about the cursor shape.
-.IP
-"\fB-cursor\fR \fImost\fR" - try to show as many cursors as
-possible. Often this will only be the same as "some"
-unless the display has overlay visuals or XFIXES
-extensions available. On Solaris and IRIX if XFIXES
-is not available, \fB-overlay\fR mode will be attempted.
-.PP
-\fB-cursor_drag\fR
-.IP
-Show cursor shape changes even when the mouse is being
-dragged with a mouse button down. This is useful if you
-want to be able to see Drag-and-Drop cursor icons, etc.
-.PP
-\fB-arrow\fR \fIn\fR
-.IP
-Choose an alternate "arrow" cursor from a set of
-some common ones. n can be 1 to 6. Default is: 1
-Ignored when in XFIXES cursor-grabbing mode.
-.PP
-\fB-noxfixes\fR
-.IP
-Do not use the XFIXES extension to draw the exact cursor
-shape even if it is available.
-.IP
-Note: To work around a crash in Xorg 1.5 and later
-some people needed to use \fB-noxfixes.\fR The Xorg crash
-occurred right after a Display Manager (e.g. GDM) login.
-Starting with x11vnc 0.9.9 it tries to automatically
-avoid using XFIXES until it is sure a window manager
-is running. See the \fB-reopen\fR option for more info and
-how to use X11VNC_AVOID_WINDOWS=never to disable it.
-.PP
-\fB-alphacut\fR \fIn\fR
-.IP
-When using the XFIXES extension for the cursor shape,
-cursors with transparency will not usually be displayed
-exactly (but opaque ones will). This option sets n as
-a cutoff for cursors that have transparency ("alpha
-channel" with values ranging from 0 to 255) Any cursor
-pixel with alpha value less than n becomes completely
-transparent. Otherwise the pixel is completely opaque.
-Default 240
-.PP
-\fB-alphafrac\fR \fIfraction\fR
-.IP
-With the threshold in \fB-alphacut\fR some cursors will become
-almost completely transparent because their alpha values
-are not high enough. For those cursors adjust the
-alpha threshold until fraction of the non-zero alpha
-channel pixels become opaque. Default 0.33
-.PP
-\fB-alpharemove\fR
-.IP
-By default, XFIXES cursors pixels with transparency have
-the alpha factor multiplied into the RGB color values
-(i.e. that corresponding to blending the cursor with a
-black background). Specify this option to remove the
-alpha factor. (useful for light colored semi-transparent
-cursors).
-.PP
-\fB-noalphablend\fR
-.IP
-In XFIXES mode do not send cursor alpha channel data
-to LibVNCServer. The default is to send it. The
-alphablend effect will only be visible in \fB-nocursorshape\fR
-mode or for clients with cursorshapeupdates turned
-off. (However there is a hack for 32bpp with depth 24,
-it uses the extra 8 bits to store cursor transparency
-for use with a hacked vncviewer that applies the
-transparency locally. See the FAQ for more info).
-.PP
-\fB-nocursorshape\fR
-.IP
-Do not use the TightVNC CursorShapeUpdates extension
-even if clients support it. See \fB-cursor\fR above.
-.PP
-\fB-cursorpos,\fR \fB-nocursorpos\fR
-.IP
-Option \fB-cursorpos\fR enables sending the X cursor position
-back to all vnc clients that support the TightVNC
-CursorPosUpdates extension. Other clients will be able
-to see the pointer motions. Default: \fB-cursorpos\fR
-.PP
-\fB-xwarppointer,\fR \fB-noxwarppointer\fR
-.IP
-Move the pointer with
-.IR XWarpPointer (3X)
-instead of
-the XTEST extension. Use this as a workaround
-if the pointer motion behaves incorrectly, e.g.
-on touchscreens or other non-standard setups.
-.IP
-It is also sometimes needed on XINERAMA displays and is
-enabled by default if XINERAMA is found to be active.
-To prevent this, use \fB-noxwarppointer.\fR
-.PP
-\fB-always_inject\fR
-.IP
-Even if there is no displacement (dx = dy = 0) for a
-VNC mouse event force the pointer to the indicated x,y
-position anyway. Recent (2009) gui toolkits (gnome)
-have problems with x11vnc's original mouse input
-injection method. So x11vnc's mouse input injection
-method has been modified. To regain the OLD behavior
-use this option: \fB-always_inject.\fR Then x11vnc will
-always force positioning the mouse to the x,y position
-even if that position has not changed since the previous
-VNC input event.
-.IP
-The first place this problem was noticed was in gnome
-terminal: if you pressed and released mouse button 3, a
-menu was posted and then its first element 'New Terminal
-Window' was activated. This was because x11vnc injected
-the mouse position twice: once on ButtonPress and again
-on ButtonRelease. The toolkit interpreted the 2nd one
-as mouse motion even though the mouse hadn't moved.
-So now by default x11vnc tries to avoid injecting the
-2nd one.
-.IP
-Note that with the new default x11vnc will be oblivious
-to applications moving the pointer (warping) or the
-user at the physical display moving it. So it might,
-e.g., inject ButtonRelease at the wrong position.
-If this (or similar scenarios) causes problems in your
-environment, specify \fB-always_inject\fR for the old method.
-.PP
-\fB-buttonmap\fR \fIstring\fR
-.IP
-String to remap mouse buttons. Format: IJK-LMN, this
-maps buttons I -> L, etc., e.g. \fB-buttonmap\fR 13-31
-.IP
-Button presses can also be mapped to keystrokes: replace
-a button digit on the right of the dash with :<sym>:
-or :<sym1>+<sym2>: etc. for multiple keys. For example,
-if the viewing machine has a mouse-wheel (buttons 4 5)
-but the x11vnc side does not, these will do scrolls:
-.IP
-\fB-buttonmap\fR 12345-123:Prior::Next:
-.IP
-\fB-buttonmap\fR 12345-123:Up+Up+Up::Down+Down+Down:
-.IP
-See <X11/keysymdef.h> header file for a list of Keysyms,
-or use the
-.IR xev (1)
-program. Note: mapping of button
-clicks to Keysyms may not work if \fB-modtweak\fR or \fB-xkb\fR is
-needed for the Keysym.
-.IP
-If you include a modifier like "Shift_L" the
-modifier's up/down state is toggled, e.g. to send
-"The" use :Shift_L+t+Shift_L+h+e: (the 1st one is
-shift down and the 2nd one is shift up). (note: the
-initial state of the modifier is ignored and not reset)
-To include button events use "Button1", ... etc.
-.IP
-.IP
-\fB-buttonmap\fR currently does not work on MacOSX console
-or in \fB-rawfb\fR mode.
-.IP
-Workaround: use \fB-buttonmap\fR IJ...-LM...=n to limit the
-number of mouse buttons to n, e.g. 123-123=3. This will
-prevent x11vnc from crashing if the X server reports
-there are 5 buttons (4/5 scroll wheel), but there are
-only really 3.
-.PP
-\fB-nodragging\fR
-.IP
-Do not update the display during mouse dragging events
-(mouse button held down). Greatly improves response on
-slow setups, but you lose all visual feedback for drags,
-text selection, and some menu traversals. It overrides
-any \fB-pointer_mode\fR setting.
-.PP
-\fB-ncache\fR \fIn\fR
-.IP
-Client-side caching scheme. Framebuffer memory \fIn\fR
-(an integer) times that of the full display is allocated
-below the actual framebuffer to cache screen contents
-for rapid retrieval. So a W x H frambuffer is expanded
-to a W x (n+1)*H one. Use 0 to disable.
-.IP
-The \fIn\fR is actually optional, the default is 10.
-.IP
-For this and the other \fB-ncache*\fR options below you can
-abbreviate "\fB-ncache\fR" with "\fB-nc\fR". Also, "\fB-nonc\fR"
-is the same as "\fB-ncache\fR \fI0\fR"
-.IP
-This is an experimental option, currently implemented in
-an awkward way in that in the VNC Viewer you can see the
-pixel cache contents if you scroll down, etc. So you
-will have to set things up so you can't see that region.
-If this method is successful, the changes required for
-clients to do this less awkwardly will be investigated.
-.IP
-The SSVNC viewer does a good job at automatically hiding
-the pixel cache region. Or use SSVNC's \fB-ycrop\fR option
-to explicitly hide the region.
-.IP
-Note that this mode consumes a huge amount of memory,
-both on the x11vnc server side and on the VNC Viewer
-side. If n=2 then the amount of RAM used is roughly
-tripled for both x11vnc and the VNC Viewer. As a rule
-of thumb, note that 1280x1024 at depth 24 is about 5MB
-of pixel data.
-.IP
-For reasonable response when cycling through 4 to 6
-large (e.g. web browser) windows a value n of 6 to 12
-is recommended. (that's right: ~10X more memory...)
-.IP
-Because of the way window backingstore and saveunders
-are implemented, n must be even. It will be incremented
-by 1 if it is not.
-.IP
-This mode also works for native MacOS X, but may not
-be as effective as the X version. This is due to a
-number of things, one is the drop-shadow compositing
-that leaves extra areas that need to be repaired (see
-\fB-ncache_pad).\fR Another is the window iconification
-animations need to be avoided (see \fB-macicontime).\fR
-It appears the that the 'Scale' animation mode gives
-better results than the 'Genie' one. Also, window event
-detection not as accurate as the X version.
-.PP
-\fB-ncache_cr\fR
-.IP
-In \fB-ncache\fR mode, try to do copyrect opaque window
-moves/drags instead of wireframes (this can induce
-painting errors). The wireframe will still be used when
-moving a window whose save-unders has not yet been set
-or has been invalidated.
-.IP
-Some VNC Viewers provide better response than others
-with this option. On Unix, realvnc viewer gives
-smoother drags than tightvnc viewer. Response may also
-be choppy if the server side machine is too slow.
-.IP
-Sometimes on very slow modem connections, this actually
-gives an improvement because no pixel data at all
-(not even the box animation) is sent during the drag.
-.PP
-\fB-ncache_no_moveraise\fR
-.IP
-In \fB-ncache\fR mode, do not assume that moving a window
-will cause the window manager to raise it to the top
-of the stack. The default is to assume it does, and
-so at the beginning of any wireframe, etc, window moves
-the window will be pushed to top in the VNC viewer.
-.PP
-\fB-ncache_no_dtchange\fR
-.IP
-In \fB-ncache\fR mode, do not try to guess when the desktop
-(viewport) changes to another one (i.e. another
-workarea). The default is to try to guess and when
-detected try to make the transistion more smoothly.
-.PP
-\fB-ncache_no_rootpixmap\fR
-.IP
-In \fB-ncache\fR mode, do not try to snapshot the desktop
-background to use in guessing or reconstructing window
-save-unders.
-.PP
-\fB-ncache_keep_anims\fR
-.IP
-In \fB-ncache\fR mode, do not try to disable window
-manager animations and other effects (that usually
-degrade ncache performance or cause painting errors).
-The default is to try to disable them on KDE (but not
-GNOME) when VNC clients are connected.
-.IP
-For other window managers or desktops that provide
-animations, effects, compositing, translucency,
-etc. that interfere with the \fB-ncache\fR method you will
-have to disable them manually.
-.PP
-\fB-ncache_old_wm\fR
-.IP
-In \fB-ncache\fR mode, enable some heuristics for old style
-window managers such as fvwm and twm.
-.PP
-\fB-ncache_pad\fR \fIn\fR
-.IP
-In \fB-ncache\fR mode, pad each window with n pixels for the
-caching rectangles. This can be used to try to improve
-the situation with dropshadows or other compositing
-(e.g. MacOS X window manager), although it could make
-things worse. The default is 0 on Unix and 24 on
-MacOS X.
-.PP
-\fB-debug_ncache\fR
-.IP
-Turn on debugging and profiling output under \fB-ncache.\fR
-.PP
-\fB-wireframe\fR \fI[str],\fR \fB-nowireframe\fR
-.IP
-Try to detect window moves or resizes when a mouse
-button is held down and show a wireframe instead of
-the full opaque window. This is based completely on
-heuristics and may not always work: it depends on your
-window manager and even how you move things around.
-See \fB-pointer_mode\fR below for discussion of the "bogging
-down" problem this tries to avoid.
-Default: \fB-wireframe\fR
-.IP
-Shorter aliases: \fB-wf\fR [str] and \fB-nowf\fR
-.IP
-The value "str" is optional and, of course, is
-packed with many tunable parameters for this scheme:
-.IP
-Format: shade,linewidth,percent,T+B+L+R,mod,t1+t2+t3+t4
-Default: 0xff,2,0,32+8+8+8,all,0.15+0.30+5.0+0.125
-.IP
-If you leave nothing between commas: ",," the default
-value is used. If you don't specify enough commas,
-the trailing parameters are set to their defaults.
-.IP
-"shade" indicate the "color" for the wireframe,
-usually a greyscale: 0-255, however for 16 and 32bpp you
-can specify an rgb.txt X color (e.g. "dodgerblue") or
-a value > 255 is treated as RGB (e.g. red is 0xff0000).
-"linewidth" sets the width of the wireframe in pixels.
-"percent" indicates to not apply the wireframe scheme
-to windows with area less than this percent of the
-full screen.
-.IP
-"T+B+L+R" indicates four integers for how close in
-pixels the pointer has to be from the Top, Bottom, Left,
-or Right edges of the window to consider wireframing.
-This is a speedup to quickly exclude a window from being
-wireframed: set them all to zero to not try the speedup
-(scrolling and selecting text will likely be slower).
-.IP
-"mod" specifies if a button down event in the
-interior of the window with a modifier key (Alt, Shift,
-etc.) down should indicate a wireframe opportunity.
-It can be "0" or "none" to skip it, "1" or "all"
-to apply it to any modifier, or "Shift", "Alt",
-"Control", "Meta", "Super", or "Hyper" to only
-apply for that type of modifier key.
-.IP
-"t1+t2+t3+t4" specify four floating point times in
-seconds: t1 is how long to wait for the pointer to move,
-t2 is how long to wait for the window to start moving
-or being resized (for some window managers this can be
-rather long), t3 is how long to keep a wireframe moving
-before repainting the window. t4 is the minimum time
-between sending wireframe "animations". If a slow
-link is detected, these values may be automatically
-changed to something better for a slow link.
-.PP
-\fB-nowireframelocal\fR
-.IP
-By default, mouse motion and button presses of a
-user sitting at the LOCAL display are monitored for
-wireframing opportunities (so that the changes will be
-sent efficiently to the VNC clients). Use this option
-to disable this behavior.
-.PP
-\fB-wirecopyrect\fR \fImode,\fR \fB-nowirecopyrect\fR
-.IP
-Since the \fB-wireframe\fR mechanism evidently tracks moving
-windows accurately, a speedup can be obtained by
-telling the VNC viewers to locally copy the translated
-window region. This is the VNC CopyRect encoding:
-the framebuffer update doesn't need to send the actual
-new image data.
-.IP
-Shorter aliases: \fB-wcr\fR [mode] and \fB-nowcr\fR
-.IP
-"mode" can be "never" (same as \fB-nowirecopyrect)\fR
-to never try the copyrect, "top" means only do it if
-the window was not covered by any other windows, and
-"always" means to translate the orginally unobscured
-region (this may look odd as the remaining pieces come
-in, but helps on a slow link). Default: "always"
-.IP
-Note: there can be painting errors or slow response
-when using \fB-scale\fR so you may want to disable CopyRect
-in this case "\fB-wirecopyrect\fR \fInever\fR" on the command
-line or by remote-control. Or you can also use the
-"\fB-scale\fR \fIxxx:nocr\fR" scale option.
-.PP
-\fB-debug_wireframe\fR
-.IP
-Turn on debugging info printout for the wireframe
-heuristics. "\fB-dwf\fR" is an alias. Specify multiple
-times for more output.
-.PP
-\fB-scrollcopyrect\fR \fImode,\fR \fB-noscrollcopyrect\fR
-.IP
-Like \fB-wirecopyrect,\fR but use heuristics to try to guess
-if a window has scrolled its contents (either vertically
-or horizontally). This requires the RECORD X extension
-to "snoop" on X applications (currently for certain
-XCopyArea and XConfigureWindow X protocol requests).
-Examples: Hitting <Return> in a terminal window when the
-cursor was at the bottom, the text scrolls up one line.
-Hitting <Down> arrow in a web browser window, the web
-page scrolls up a small amount. Or scrolling with a
-scrollbar or mouse wheel.
-.IP
-Shorter aliases: \fB-scr\fR [mode] and \fB-noscr\fR
-.IP
-This scheme will not always detect scrolls, but when
-it does there is a nice speedup from using the VNC
-CopyRect encoding (see \fB-wirecopyrect).\fR The speedup
-is both in reduced network traffic and reduced X
-framebuffer polling/copying. On the other hand, it may
-induce undesired transients (e.g. a terminal cursor
-being scrolled up when it should not be) or other
-painting errors (window tearing, bunching-up, etc).
-These are automatically repaired in a short period
-of time. If this is unacceptable disable the feature
-with \fB-noscrollcopyrect.\fR
-.IP
-Screen clearing kludges: for testing at least, there
-are some "magic key sequences" (must be done in less
-than 1 second) to aid repairing painting errors that
-may be seen when using this mode:
-.IP
-3 Alt_L's in a row: resend whole screen,
-4 Alt_L's in a row: reread and resend whole screen,
-3 Super_L's in a row: mark whole screen for polling,
-4 Super_L's in a row: reset RECORD context,
-5 Super_L's in a row: try to push a black screen
-.IP
-note: Alt_L is the Left "Alt" key (a single key)
-Super_L is the Left "Super" key (Windows flag).
-Both of these are modifier keys, and so should not
-generate characters when pressed by themselves. Also,
-your VNC viewer may have its own refresh hot-key
-or button.
-.IP
-"mode" can be "never" (same as \fB-noscrollcopyrect)\fR
-to never try the copyrect, "keys" means to try it
-in response to keystrokes only, "mouse" means to
-try it in response to mouse events only, "always"
-means to do both. Default: "always"
-.IP
-Note: there can be painting errors or slow response
-when using \fB-scale\fR so you may want to disable CopyRect
-in this case "\fB-scrollcopyrect\fR \fInever\fR" on the command
-line or by remote-control. Or you can also use the
-"\fB-scale\fR \fIxxx:nocr\fR" scale option.
-.PP
-\fB-scr_area\fR \fIn\fR
-.IP
-Set the minimum area in pixels for a rectangle
-to be considered for the \fB-scrollcopyrect\fR detection
-scheme. This is to avoid wasting the effort on small
-rectangles that would be quickly updated the normal way.
-E.g. suppose an app updated the position of its skinny
-scrollbar first and then shifted the large panel
-it controlled. We want to be sure to skip the small
-scrollbar and get the large panel. Default: 60000
-.PP
-\fB-scr_skip\fR \fIlist\fR
-.IP
-Skip scroll detection for applications matching
-the comma separated list of strings in \fIlist\fR.
-Some applications implement their scrolling in
-strange ways where the XCopyArea, etc, also applies
-to invisible portions of the window: if we CopyRect
-those areas it looks awful during the scroll and
-there may be painting errors left after the scroll.
-Soffice.bin is the worst known offender.
-.IP
-Use "##" to denote the start of the application class
-(e.g. "##XTerm") and "++" to denote the start
-of the application instance name (e.g. "++xterm").
-The string your list is matched against is of the form
-"^^WM_NAME##Class++Instance<same-for-any-subwindows>"
-The "xlsclients \fB-la"\fR command will provide this info.
-.IP
-If a pattern is prefixed with "KEY:" it only applies
-to Keystroke generated scrolls (e.g. Up arrow). If it
-is prefixed with "MOUSE:" it only applies to Mouse
-induced scrolls (e.g. dragging on a scrollbar).
-Default: ##Soffice.bin,##StarOffice,##OpenOffice
-.PP
-\fB-scr_inc\fR \fIlist\fR
-.IP
-Opposite of \fB-scr_skip:\fR this list is consulted first
-and if there is a match the window will be monitored
-via RECORD for scrolls irrespective of \fB-scr_skip.\fR
-Use \fB-scr_skip\fR '*' to skip anything that does not match
-your \fB-scr_inc.\fR Use \fB-scr_inc\fR '*' to include everything.
-.PP
-\fB-scr_keys\fR \fIlist\fR
-.IP
-For keystroke scroll detection, only apply the RECORD
-heuristics to the comma separated list of keysyms in
-\fIlist\fR. You may find the RECORD overhead for every
-one of your keystrokes disrupts typing too much, but you
-don't want to turn it off completely with "\fB-scr\fR \fImouse\fR"
-and \fB-scr_parms\fR does not work or is too confusing.
-.IP
-The listed keysyms can be numeric or the keysym
-names in the <X11/keysymdef.h> header file or from the
-.IR xev (1)
-program. Example: "\fB-scr_keys\fR \fIUp,Down,Return\fR".
-One probably wants to have application specific lists
-(e.g. for terminals, etc) but that is too icky to think
-about for now...
-.IP
-If \fIlist\fR begins with the "-" character the list
-is taken as an exclude list: all keysyms except those
-list will be considered. The special string "builtin"
-expands to an internal list of keysyms that are likely
-to cause scrolls. BTW, by default modifier keys,
-Shift_L, Control_R, etc, are skipped since they almost
-never induce scrolling by themselves.
-.PP
-\fB-scr_term\fR \fIlist\fR
-.IP
-Yet another cosmetic kludge. Apply shell/terminal
-heuristics to applications matching comma separated
-list (same as for \fB-scr_skip/-scr_inc).\fR For example an
-annoying transient under scroll detection is if you
-hit Enter in a terminal shell with full text window,
-the solid text cursor block will be scrolled up.
-So for a short time there are two (or more) block
-cursors on the screen. There are similar scenarios,
-(e.g. an output line is duplicated).
-.IP
-These transients are induced by the approximation of
-scroll detection (e.g. it detects the scroll, but not
-the fact that the block cursor was cleared just before
-the scroll). In nearly all cases these transient errors
-are repaired when the true X framebuffer is consulted
-by the normal polling. But they are distracting, so
-what this option provides is extra "padding" near the
-bottom of the terminal window: a few extra lines near
-the bottom will not be scrolled, but rather updated
-from the actual X framebuffer. This usually reduces
-the annoying artifacts. Use "none" to disable.
-Default: "term"
-.PP
-\fB-scr_keyrepeat\fR \fIlo-hi\fR
-.IP
-If a key is held down (or otherwise repeats rapidly) and
-this induces a rapid sequence of scrolls (e.g. holding
-down an Arrow key) the "scrollcopyrect" detection
-and overhead may not be able to keep up. A time per
-single scroll estimate is performed and if that estimate
-predicts a sustainable scrollrate of keys per second
-between "lo" and "hi" then repeated keys will be
-DISCARDED to maintain the scrollrate. For example your
-key autorepeat may be 25 keys/sec, but for a large
-window or slow link only 8 scrolls per second can be
-sustained, then roughly 2 out of every 3 repeated keys
-will be discarded during this period. Default: "4-20"
-.PP
-\fB-scr_parms\fR \fIstring\fR
-.IP
-Set various parameters for the scrollcopyrect mode.
-The format is similar to that for \fB-wireframe\fR and packed
-with lots of parameters:
-.IP
-Format: T+B+L+R,t1+t2+t3,s1+s2+s3+s4+s5
-Default: 0+64+32+32,0.02+0.10+0.9,0.03+0.06+0.5+0.1+5.0
-.IP
-If you leave nothing between commas: ",," the default
-value is used. If you don't specify enough commas,
-the trailing parameters are set to their defaults.
-.IP
-"T+B+L+R" indicates four integers for how close in
-pixels the pointer has to be from the Top, Bottom, Left,
-or Right edges of the window to consider scrollcopyrect.
-If \fB-wireframe\fR overlaps it takes precedence. This is a
-speedup to quickly exclude a window from being watched
-for scrollcopyrect: set them all to zero to not try
-the speedup (things like selecting text will likely
-be slower).
-.IP
-"t1+t2+t3" specify three floating point times in
-seconds that apply to scrollcopyrect detection with
-*Keystroke* input: t1 is how long to wait after a key
-is pressed for the first scroll, t2 is how long to keep
-looking after a Keystroke scroll for more scrolls.
-t3 is how frequently to try to update surrounding
-scrollbars outside of the scrolling area (0.0 to
-disable)
-.IP
-"s1+s2+s3+s4+s5" specify five floating point times
-in seconds that apply to scrollcopyrect detection with
-*Mouse* input: s1 is how long to wait after a mouse
-button is pressed for the first scroll, s2 is how long
-to keep waiting for additional scrolls after the first
-Mouse scroll was detected. s3 is how frequently to
-try to update surrounding scrollbars outside of the
-scrolling area (0.0 to disable). s4 is how long to
-buffer pointer motion (to try to get fewer, bigger
-mouse scrolls). s5 is the maximum time to spend just
-updating the scroll window without updating the rest
-of the screen.
-.PP
-\fB-fixscreen\fR \fIstring\fR
-.IP
-Periodically "repair" the screen based on settings
-in \fIstring\fR. Hopefully you won't need this option,
-it is intended for cases when the \fB-scrollcopyrect\fR or
-\fB-wirecopyrect\fR features leave too many painting errors,
-but it can be used for any scenario. This option
-periodically performs costly operations and so
-interactive response may be reduced when it is on.
-You can use 3 Alt_L's (the Left "Alt" key) taps in
-a row (as described under \fB-scrollcopyrect)\fR instead to
-manually request a screen repaint when it is needed.
-.IP
-\fIstring\fR is a comma separated list of one or more of
-the following: "V=t", "C=t", "X=t", and "8=t".
-In these "t" stands for a time in seconds (it is
-a floating point even though one should usually use
-values > 2 to avoid wasting resources). V sets how
-frequently the entire screen should be sent to viewers
-(it is like the 3 Alt_L's). C sets how long to wait
-after a CopyRect to repaint the full screen. X sets
-how frequently to reread the full X11 framebuffer from
-the X server and push it out to connected viewers.
-Use of X should be rare, please report a bug if you
-find you need it. 8= applies only for \fB-8to24\fR mode: it
-sets how often the non-default visual regions of the
-screen (e.g. 8bpp windows) are refreshed. Examples:
-\fB-fixscreen\fR V=10 \fB-fixscreen\fR C=10
-.PP
-\fB-debug_scroll\fR
-.IP
-Turn on debugging info printout for the scroll
-heuristics. "\fB-ds\fR" is an alias. Specify it multiple
-times for more output.
-.PP
-\fB-noxrecord\fR
-.IP
-Disable any use of the RECORD extension. This is
-currently used by the \fB-scrollcopyrect\fR scheme and to
-monitor X server grabs.
-.PP
-\fB-grab_buster,\fR \fB-nograb_buster\fR
-.IP
-Some of the use of the RECORD extension can leave a
-tiny window for XGrabServer deadlock. This is only if
-the whole-server grabbing application expects mouse or
-keyboard input before releasing the grab. It is usually
-a window manager that does this. x11vnc takes care to
-avoid the problem, but if caught x11vnc will freeze.
-Without \fB-grab_buster,\fR the only solution is to go the
-physical display and give it some input to satisfy the
-grabbing app. Or manually kill and restart the window
-manager if that is feasible. With \fB-grab_buster,\fR x11vnc
-will fork a helper thread and if x11vnc appears to be
-stuck in a grab after a period of time (20-30 sec) then
-it will inject some user input: button clicks, Escape,
-mouse motion, etc to try to break the grab. If you
-experience a lot of grab deadlock, please report a bug.
-.PP
-\fB-debug_grabs\fR
-.IP
-Turn on debugging info printout with respect to
-XGrabServer() deadlock for \fB-scrollcopyrect__mode_.\fR
-.PP
-\fB-debug_sel\fR
-.IP
-Turn on debugging info printout with respect to
-PRIMARY, CLIPBOARD, and CUTBUFFER0 selections.
-.PP
-\fB-pointer_mode\fR \fIn\fR
-.IP
-Various pointer motion update schemes. "\fB-pm\fR" is
-an alias. The problem is pointer motion can cause
-rapid changes on the screen: consider the rapid
-changes when you drag a large window around opaquely.
-Neither x11vnc's screen polling and vnc compression
-routines nor the bandwidth to the vncviewers can keep
-up these rapid screen changes: everything will bog down
-when dragging or scrolling. So a scheme has to be used
-to "eat" much of that pointer input before re-polling
-the screen and sending out framebuffer updates. The
-mode number \fIn\fR can be 0 to 4 and selects one of
-the schemes desribed below.
-.IP
-Note that the \fB-wireframe\fR and \fB-scrollcopyrect__mode_s\fR
-complement \fB-pointer_mode\fR by detecting (and improving)
-certain periods of "rapid screen change".
-.IP
-n=0: does the same as \fB-nodragging.\fR (all screen polling
-is suspended if a mouse button is pressed.)
-.IP
-n=1: was the original scheme used to about Jan 2004:
-it basically just skips \fB-input_skip\fR keyboard or pointer
-events before repolling the screen.
-.IP
-n=2 is an improved scheme: by watching the current rate
-of input events it tries to detect if it should try to
-"eat" additional pointer events before continuing.
-.IP
-n=3 is basically a dynamic \fB-nodragging\fR mode: it detects
-when the mouse motion has paused and then refreshes
-the display.
-.IP
-n=4 attempts to measures network rates and latency,
-the video card read rate, and how many tiles have been
-changed on the screen. From this, it aggressively tries
-to push screen "frames" when it decides it has enough
-resources to do so. NOT FINISHED.
-.IP
-The default n is 2. Note that modes 2, 3, 4 will skip
-\fB-input_skip\fR keyboard events (but it will not count
-pointer events). Also note that these modes are not
-available in \fB-threads\fR mode which has its own pointer
-event handling mechanism.
-.IP
-To try out the different pointer modes to see which
-one gives the best response for your usage, it is
-convenient to use the remote control function, for
-example "x11vnc \fB-R\fR pm:4" or the tcl/tk gui (Tuning ->
-pointer_mode -> n).
-.PP
-\fB-input_skip\fR \fIn\fR
-.IP
-For the pointer handling when non-threaded: try to
-read n user input events before scanning display. n < 0
-means to act as though there is always user input.
-Default: 10
-.PP
-\fB-allinput\fR
-.IP
-Have x11vnc read and process all available client input
-before proceeding.
-.PP
-\fB-input_eagerly\fR
-.IP
-Similar to \fB-allinput\fR but use the handleEventsEagerly
-mechanism built into LibVNCServer.
-.PP
-\fB-speeds\fR \fIrd,bw,lat\fR
-.IP
-x11vnc tries to estimate some speed parameters that
-are used to optimize scheduling (e.g. \fB-pointer_mode\fR
-4, \fB-wireframe,\fR \fB-scrollcopyrect)\fR and other things.
-Use the \fB-speeds\fR option to set these manually.
-The triple \fIrd,bw,lat\fR corresponds to video h/w
-read rate in MB/sec, network bandwidth to clients in
-KB/sec, and network latency to clients in milliseconds,
-respectively. If a value is left blank, e.g. "-speeds
-,100,15", then the internal scheme is used to estimate
-the empty value(s).
-.IP
-Typical PC video cards have read rates of 5-10 MB/sec.
-If the framebuffer is in main memory instead of video
-h/w (e.g. SunRay, shadowfb, dummy driver, Xvfb), the
-read rate may be much faster. "x11perf \fB-getimage500"\fR
-can be used to get a lower bound (remember to factor
-in the bytes per pixel). It is up to you to estimate
-the network bandwith and latency to clients. For the
-latency the
-.IR ping (1)
-command can be used.
-.IP
-For convenience there are some aliases provided,
-e.g. "\fB-speeds\fR \fImodem\fR". The aliases are: "modem" for
-6,4,200; "dsl" for 6,100,50; and "lan" for 6,5000,1
-.PP
-\fB-wmdt\fR \fIstring\fR
-.IP
-For some features, e.g. \fB-wireframe\fR and \fB-scrollcopyrect,\fR
-x11vnc has to work around issues for certain window
-managers or desktops (currently kde and xfce).
-By default it tries to guess which one, but it can
-guess incorrectly. Use this option to indicate which
-wm/dt. \fIstring\fR can be "gnome", "kde", "cde",
-"xfce", or "root" (classic X wm). Anything else
-is interpreted as "root".
-.PP
-\fB-debug_pointer\fR
-.IP
-Print debugging output for every pointer event.
-.PP
-\fB-debug_keyboard\fR
-.IP
-Print debugging output for every keyboard event.
-.PP
-Same as \fB-dp\fR and \fB-dk,\fR respectively. Use multiple
-times for more output.
-.PP
-\fB-defer\fR \fItime\fR
-.IP
-Time in ms to delay sending updates to connected clients
-(deferUpdateTime) Default: 20
-.PP
-\fB-wait\fR \fItime\fR
-.IP
-Time in ms to pause between screen polls. Used to cut
-down on load. Default: 20
-.PP
-\fB-extra_fbur\fR \fIn\fR
-.IP
-Perform extra FrameBufferUpdateRequests checks to
-try to be in better sync with the client's requests.
-What this does is perform extra polls of the client
-socket at critical times (before '-defer' and '-wait'
-calls.) The default is n=1. Set to a larger number to
-insert more checks or set to n=0 to disable. A downside
-of these extra calls is that more mouse input may be
-processed than desired.
-.PP
-\fB-wait_ui\fR \fIfactor\fR
-.IP
-Factor by which to cut the \fB-wait\fR time if there
-has been recent user input (pointer or keyboard).
-Improves response, but increases the load whenever you
-are moving the mouse or typing. Default: 2.00
-.PP
-\fB-setdefer\fR \fIn\fR
-.IP
-When the \fB-wait_ui\fR mechanism cuts down the wait time ms,
-set the defer time to the same ms value. n=1 to enable,
-0 to disable, and -1 to set defer to 0 (no delay).
-Similarly, 2 and -2 indicate 'urgent_update' mode should
-be used to push the updates even sooner. Default: 1
-.PP
-\fB-nowait_bog\fR
-.IP
-Do not detect if the screen polling is "bogging down"
-and sleep more. Some activities with no user input can
-slow things down a lot: consider a large terminal window
-with a long build running in it continuously streaming
-text output. By default x11vnc will try to detect this
-(3 screen polls in a row each longer than 0.25 sec with
-no user input), and sleep up to 1.5 secs to let things
-"catch up". Use this option to disable that detection.
-.PP
-\fB-slow_fb\fR \fItime\fR
-.IP
-Floating point time in seconds to delay all screen
-polling. For special purpose usage where a low frame
-rate is acceptable and desirable, but you want the
-user input processed at the normal rate so you cannot
-use \fB-wait.\fR
-.PP
-\fB-xrefresh\fR \fItime\fR
-.IP
-Floating point time in seconds to indicate how often to
-do the equivalent of
-.IR xrefresh (1)
-to force all windows
-(in the viewable area if \fB-id,\fR \fB-sid,\fR or \fB-clip\fR is used)
-to repaint themselves. Use this only if applications
-misbehave by not repainting themselves properly.
-See also \fB-noxdamage.\fR
-.PP
-\fB-nap,\fR \fB-nonap\fR
-.IP
-Monitor activity and if it is low take longer naps
-between screen polls to really cut down load when idle.
-Default: take naps
-.PP
-\fB-sb\fR \fItime\fR
-.IP
-Time in seconds after NO activity (e.g. screen blank)
-to really throttle down the screen polls (i.e. sleep
-for about 1.5 secs). Use 0 to disable. Default: 60
-Set the env. var. X11VNC_SB_FACTOR to scale it.
-.PP
-\fB-readtimeout\fR \fIn\fR
-.IP
-Set LibVNCServer rfbMaxClientWait to n seconds. On
-slow links that take a long time to paint the first
-screen LibVNCServer may hit the timeout and drop the
-connection. Default: 20 seconds.
-.PP
-\fB-ping\fR \fIn\fR
-.IP
-Send a 1x1 framebuffer update to all clients every n
-seconds (e.g. to try to keep a network connection alive)
-.PP
-\fB-nofbpm,\fR \fB-fbpm\fR
-.IP
-If the system supports the FBPM (Frame Buffer Power
-Management) extension (i.e. some Sun systems), then
-prevent the video h/w from going into a reduced power
-state when VNC clients are connected.
-.IP
-FBPM capable video h/w save energy when the workstation
-is idle by going into low power states (similar to DPMS
-for monitors). This interferes with x11vnc's polling
-of the framebuffer data.
-.IP
-"\fB-nofbpm\fR" means prevent FBPM low power states whenever
-VNC clients are connected, while "\fB-fbpm\fR" means to not
-monitor the FBPM state at all. See the
-.IR xset (1)
-manpage
-for details. \fB-nofbpm\fR is basically the same as running
-"xset fbpm force on" periodically. Default: \fB-fbpm\fR
-.PP
-\fB-nodpms,\fR \fB-dpms\fR
-.IP
-If the system supports the DPMS (Display Power Management
-Signaling) extension, then prevent the monitor from
-going into a reduced power state when VNC clients
-are connected.
-.IP
-DPMS reduced power monitor states are a good thing
-and you normally want the power down to take place
-(usually x11vnc has no problem exporting the display in
-this state). You probably only want to use "\fB-nodpms\fR"
-to work around problems with Screen Savers kicking
-on in DPMS low power states. There is known problem
-with kdesktop_lock on KDE where the screen saver keeps
-kicking in every time user input stops for a second
-or two. Specifying "\fB-nodpms\fR" works around it.
-.IP
-"\fB-nodpms\fR" means prevent DPMS low power states whenever
-VNC clients are connected, while "\fB-dpms\fR" means to not
-monitor the DPMS state at all. See the
-.IR xset (1)
-manpage
-for details. \fB-nodpms\fR is basically the same as running
-"xset dpms force on" periodically. Default: \fB-dpms\fR
-.PP
-\fB-forcedpms\fR
-.IP
-If the system supports the DPMS (Display Power
-Management Signaling) extension, then try to keep the
-monitor in a powered off state. This is to prevent
-nosey people at the physical display from viewing what
-is on the screen. Be sure to lock the screen before
-disconnecting.
-.IP
-This method is far from bullet proof, e.g. suppose
-someone attaches a non-DPMS monitor, or loads the
-machine so that there is a gap of time before x11vnc
-restores the powered off state? On many machines if
-he floods it with keyboard and mouse input he can see
-flashes of what is on the screen before the DPMS off
-state is reestablished. For this to work securely
-there would need to be support in the X server to do
-this exactly rather than approximately with DPMS.
-.PP
-\fB-clientdpms\fR
-.IP
-As \fB-forcedpms\fR but only when VNC clients are connected.
-.PP
-\fB-noserverdpms\fR
-.IP
-The UltraVNC ServerInput extension is supported.
-This allows the VNC viewer to click a button that will
-cause the server (x11vnc) to try to disable keyboard
-and mouse input at the physical display and put the
-monitor in dpms powered off state. Use this option to
-skip powering off the monitor.
-.PP
-\fB-noultraext\fR
-.IP
-Disable the following UltraVNC extensions: SingleWindow
-and ServerInput. The others managed by LibVNCServer
-(textchat, 1/n scaling, rfbEncodingUltra) are not.
-.PP
-\fB-chatwindow\fR
-.IP
-Place a local UltraVNC chat window on the X11 display
-that x11vnc is polling. That way the person on the VNC
-viewer-side can chat with the person at the physical
-X11 console. (e.g. helpdesk w/o telephone)
-.IP
-For this to work the SSVNC package (version 1.0.21 or
-later) MUST BE installed on the system where x11vnc runs
-and the 'ssvnc' command must be available in $PATH.
-The ssvncviewer is used as a chat window helper.
-See http://www.karlrunge.com/x11vnc/ssvnc.html
-.IP
-This option implies '-rfbversion 3.6' so as to trick
-UltraVNC viewers, otherwise they assume chat is not
-available. To specify a different rfbversion, place
-it after the \fB-chatwindow\fR option on the cmdline.
-.IP
-See also the remote control 'chaton' and 'chatoff'
-actions. These can also be set from the tkx11vnc GUI.
-.PP
-\fB-noxdamage\fR
-.IP
-Do not use the X DAMAGE extension to detect framebuffer
-changes even if it is available. Use \fB-xdamage\fR if your
-default is to have it off.
-.IP
-x11vnc's use of the DAMAGE extension: 1) significantly
-reduces the load when the screen is not changing much,
-and 2) detects changed areas (small ones by default)
-more quickly.
-.IP
-Currently the DAMAGE extension is overly conservative
-and often reports large areas (e.g. a whole terminal
-or browser window) as damaged even though the actual
-changed region is much smaller (sometimes just a few
-pixels). So heuristics were introduced to skip large
-areas and use the damage rectangles only as "hints"
-for the traditional scanline polling. The following
-tuning parameters are introduced to adjust this
-behavior:
-.PP
-\fB-xd_area\fR \fIA\fR
-.IP
-Set the largest DAMAGE rectangle area \fIA\fR (in
-pixels: width * height) to trust as truly damaged:
-the rectangle will be copied from the framebuffer
-(slow) no matter what. Set to zero to trust *all*
-rectangles. Default: 20000
-.PP
-\fB-xd_mem\fR \fIf\fR
-.IP
-Set how long DAMAGE rectangles should be "remembered",
-\fIf\fR is a floating point number and is in units of the
-scanline repeat cycle time (32 iterations). The default
-(1.0) should give no painting problems. Increase it if
-there are problems or decrease it to live on the edge
-(perhaps useful on a slow machine).
-.PP
-\fB-sigpipe\fR \fIstring\fR
-.IP
-Broken pipe (SIGPIPE) handling. \fIstring\fR can be
-"ignore" or "exit". For "ignore" LibVNCServer
-will handle the abrupt loss of a client and continue,
-for "exit" x11vnc will cleanup and exit at the 1st
-broken connection.
-.IP
-This option is not really needed since LibVNCServer
-is doing the correct thing now for quite some time.
-However, for convenience you can use it to ignore other
-signals, e.g. "\fB-sigpipe\fR \fIignore:HUP,INT,TERM\fR" in case
-that would be useful for some sort of application.
-You can also put "exit:.." in the list to have x11vnc
-cleanup on the listed signals. "\fB-sig\fR" is an alias
-for this option if you don't like the 'pipe'. Example:
-\fB-sig\fR ignore:INT,TERM,exit:USR1
-.PP
-\fB-threads,\fR \fB-nothreads\fR
-.IP
-Whether or not to use the threaded LibVNCServer
-algorithm [rfbRunEventLoop] if libpthread is available.
-In this mode new threads (one for input and one
-for output) are created to handle each new client.
-Default: \fB-nothreads.\fR
-.IP
-Thread stability is much improved in version 0.9.8.
-.IP
-Multiple clients in threaded mode should be stable
-for the ZRLE encoding on all platforms. The Tight and
-Zlib encodings are currently only stable on Linux for
-multiple clients. Compile with \fB-DTLS=__thread\fR if your
-OS and compiler and linker support it.
-.IP
-For resizes (randr, etc.) set this env. var. to the number
-of milliseconds to sleep: X11VNC_THREADS_NEW_FB_SLEEP
-at various places in the do_new_fb() action. This is to
-let various activities settle. Default is about 500ms.
-.IP
-Multiple clients in threaded mode could yield better
-performance for 'class-room' broadcasting usage; also in
-\fB-appshare\fR broadcast mode. See also the \fB-reflect\fR option.
-.PP
-\fB-fs\fR \fIf\fR
-.IP
-If the fraction of changed tiles in a poll is greater
-than f, the whole screen is updated. Default: 0.75
-.PP
-\fB-gaps\fR \fIn\fR
-.IP
-Heuristic to fill in gaps in rows or cols of n or
-less tiles. Used to improve text paging. Default: 4
-.PP
-\fB-grow\fR \fIn\fR
-.IP
-Heuristic to grow islands of changed tiles n or wider
-by checking the tile near the boundary. Default: 3
-.PP
-\fB-fuzz\fR \fIn\fR
-.IP
-Tolerance in pixels to mark a tiles edges as changed.
-Default: 2
-.PP
-\fB-debug_tiles\fR
-.IP
-Print debugging output for tiles, fb updates, etc.
-.PP
-\fB-snapfb\fR
-.IP
-Instead of polling the X display framebuffer (fb)
-for changes, periodically copy all of X display fb
-into main memory and examine that copy for changes.
-(This setting also applies for non-X \fB-rawfb\fR modes).
-Under some circumstances this will improve interactive
-response, or at least make things look smoother, but in
-others (most!) it will make the response worse. If the
-video h/w fb is such that reading small tiles is very
-slow this mode could help. To keep the "framerate"
-up the screen size x bpp cannot be too large. Note that
-this mode is very wasteful of memory I/O resources
-(it makes full screen copies even if nothing changes).
-It may be of use in video capture-like applications,
-webcams, or where window tearing is a problem.
-.PP
-\fB-rawfb\fR \fIstring\fR
-.IP
-Instead of polling X, poll the memory object specified
-in \fIstring\fR.
-.IP
-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:/..."
-for slower
-.IR lseek (2)
-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
-WxHxB as above. See
-.IR shmat (1)
-and
-.IR ipcs (1)
-.IP
-If you do not supply a type "map" is assumed if
-the file exists (see the next paragraphs for some
-exceptions to this.)
-.IP
-If string is "setup:cmd", then the command "cmd"
-is run and the first line from it is read and used
-as \fIstring\fR. This allows initializing the device,
-determining WxHxB, etc. These are often done as root
-so take care.
-.IP
-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",
-"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 (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/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
-.IP
-\fB-rawfb\fR map:/dev/fb0@1024x768x32
-.IP
-\fB-rawfb\fR map:/tmp/Xvfb_screen0@640x480x8+3232
-.IP
-\fB-rawfb\fR file:/tmp/my.pnm@250x200x24+37
-.IP
-\fB-rawfb\fR file:/dev/urandom@128x128x8
-\fB-rawfb\fR snap:/dev/video0@320x240x24 \fB-24to32\fR
-\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
-.IR ipcs (1)
-and
-.IR fbset (1)
-for the first two examples)
-.IP
-In general all user input is discarded by default (see
-the \fB-pipeinput\fR option for how to use a helper program
-to insert). Most of the X11 (screen, keyboard, mouse)
-options do not make sense and many will cause this
-mode to crash, so please think twice before setting or
-changing them in a running x11vnc.
-.IP
-If you DO NOT want x11vnc to close the X DISPLAY in
-rawfb mode, prepend a "+" e.g. +file:/dev/fb0...
-Keeping the display open enables the default
-remote-control channel, which could be useful.
-Alternatively, if you specify \fB-noviewonly,\fR then the
-mouse and keyboard input are STILL sent to the X
-display, this usage should be very rare, i.e. doing
-something strange with /dev/fb0.
-.IP
-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
-*every* snapfb snapshot, set the environment variable:
-SNAPFB_RAWFB_RESET=1 as well.
-.IP
-If you want x11vnc to dynamically transform a 24bpp
-rawfb to 32bpp (note that this will be slower) also
-supply the \fB-24to32\fR option. This would be useful for,
-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
-device itself. So if you do not supply "@WxHxB...
-parameters x11vnc will try to determine them. It first
-tries the v4l API if that support has been compiled in.
-Otherwise it will run the v4l-
-.IR info (1)
-external program
-if it is available.
-.IP
-The simplest examples are "\fB-rawfb\fR \fIvideo\fR" and "-rawfb
-video1" which imply the device file /dev/video and
-/dev/video1, respectively. You can also supply the
-/dev if you like, e.g. "\fB-rawfb\fR \fI/dev/video0\fR"
-.IP
-Since the video capture device framebuffer usually
-changes continuously (e.g. brightness fluctuations),
-you may want to use the \fB-wait,\fR \fB-slow_fb,\fR or \fB-defer\fR
-options to lower the "framerate" to cut down on
-network VNC traffic.
-.IP
-A more sophisticated video device scheme allows
-initializing the device's settings using:
-.IP
-\fB-rawfb\fR video:<settings>
-.IP
-The prefix could also be, as above, e.g. "video1:" to
-specify the device file. The v4l API must be available
-for this to work. Otherwise, you will need to try
-to initialize the device with an external program,
-e.g. xawtv, spcaview, and hope they persist when x11vnc
-re-opens the device.
-.IP
-<settings> is a comma separated list of key=value pairs.
-The device's brightness, color, contrast, and hue can
-be set to percentages, e.g. br=80,co=50,cn=44,hu=60.
-.IP
-The device filename can be set too if needed (if it
-does not start with "video"), e.g. fn=/dev/qcam.
-.IP
-The width, height and bpp of the framebuffer can be
-set via, e.g., w=160,h=120,bpp=16.
-.IP
-Related to the bpp above, the pixel format can be set
-via the fmt=XXX, where XXX can be one of: GREY, HI240,
-RGB555, RGB565, RGB24, and RGB32 (with bpp 8, 8, 16, 16,
-24, and 32 respectively). See http://www.linuxtv.org
-for more info (V4L api).
-.IP
-For TV/rf tuner cards one can set the tuning mode
-via tun=XXX where XXX can be one of PAL, NTSC, SECAM,
-or AUTO.
-.IP
-One can switch the input channel by the inp=XXX setting,
-where XXX is the name of the input channel (Television,
-Composite1, S-Video, etc). Use the name that is in the
-information about the device that is printed at startup.
-.IP
-For input channels with tuners (e.g. Television) one
-can change which station is selected by the sta=XXX
-setting. XXX is the station number. Currently only
-the ntsc-cable-us (US cable) channels are built into
-x11vnc. See the \fB-freqtab\fR option below to supply one
-from xawtv. If XXX is greater than 500, then it is
-interpreted as a raw frequency in KHz.
-.IP
-Example:
-.IP
-\fB-rawfb\fR video:br=80,w=320,h=240,fmt=RGB32,tun=NTSC,sta=47
-.IP
-one might need to add inp=Television too for the input
-channel to be TV if the card doesn't come up by default
-in that one.
-.IP
-Note that not all video capture devices will support
-all of the above settings.
-.IP
-See the \fB-pipeinput\fR VID option below for a way to control
-the settings through the VNC Viewer via keystrokes.
-As a shortcut, if the string begins "Video.." instead
-of "video.." then \fB-pipeinput\fR VID is implied.
-.IP
-As above, if you specify a "@WxHxB..." after the
-<settings> string they are used verbatim: the device
-is not queried for the current values. Otherwise the
-device will be queried.
-.IP
-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 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, 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. It also provides more accurate
-keystroke insertion. 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 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"
-or "vtx".
-.IP
-The string "/dev/fb0" (1, etc.) can be used instead
-of "console". This can be used to specify a different
-framebuffer device, e.g. /dev/fb1. As a shortcut the
-"/dev/" can be dropped. If the name is something
-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 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
-\fB-rawfb\fR /dev/fb0 (same)
-\fB-rawfb\fR console3 (force /dev/tty3)
-\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
-VNC server "host" is connected to (i.e. x11vnc acts as
-a VNC client itself) and that framebuffer is exported.
-.IP
-This mode is really only of use if you are trying
-to improve performance in the case of many (e.g. >
-10) simultaneous VNC viewers, and you try a divide
-and conquer scheme to reduce bandwidth and improve
-responsiveness. (However, another user found this mode
-useful to export a demo display through a slow link:
-then multiple demo viewers connected to the reflecting
-x11vnc on the fast side of the link, and so avoided
-all of the demo viewers going through the slow link.)
-.IP
-For example, if there will be 64 simultaneous VNC
-viewers this can lead to a lot of redundant VNC traffic
-to and from the server host:N, extra CPU usage,
-and all viewers response can be reduced by having
-to wait for writes to the slowest client to finish.
-However, if you set up 8 reflectors/repeaters started
-with option \fB-rawfb\fR vnc:host:N, then there are only
-8 connections to host:N. Each repeater then handles
-8 vnc viewer connections thereby spreading the load
-around. In classroom broadcast usage, try to put the
-repeaters on different switches. This mode is the same
-as \fB-reflect\fR host:N. Replace "host:N" by "listen"
-or "listen:port" for a reverse connection.
-.IP
-Overall performance will not be as good as a single
-direct connection because, among other things,
-there is an additional level of framebuffer polling
-and pointer motion can still induce many changes per
-second that must be propagated. Tip: if the remote VNC
-is x11vnc doing wireframing, or an X display that does
-wireframing that gives much better response than opaque
-window dragging. Consider the \fB-nodragging\fR option if
-the problem is severe.
-.IP
-The env. var. X11VNC_REFLECT_PASSWORD can be set to
-the password needed to log into the vnc host server, or
-to "file:path_to_file" to indicate a file containing
-the password as its first line.
-.IP
-To set the pixel format that x11vnc requests as a VNC
-CLIENT set the env. vars: X11VNC_REFLECT_bitsPerSample
-X11VNC_REFLECT_samplesPerPixel, and
-X11VNC_REFLECT_bytesPerPixel; the defaults are 8, 3, 4.
-2, 3, 1 would give a low color mode. See the function
-rfbGetClient() in libvncclient for more info.
-.IP
-The VNC HOST mode implies \fB-shared.\fR Use \fB-noshared\fR as
-a subsequent cmdline option to disable sharing.
-.PP
-\fB-freqtab\fR \fIfile\fR
-.IP
-For use with "\fB-rawfb\fR \fIvideo\fR" for TV tuner devices to
-specify station frequencies. Instead of using the built
-in ntsc-cable-us mapping of station number to frequency,
-use the data in file. For stations that are not
-numeric, e.g. SE20, they are placed above the highest
-numbered station in the order they are found. Example:
-"\fB-freqtab\fR \fI/usr/X11R6/share/xawtv/europe-west.list\fR"
-You can make your own freqtab by copying the xawtv
-format.
-.PP
-\fB-pipeinput\fR \fIcmd\fR
-.IP
-This option lets you supply an external command in
-\fIcmd\fR that x11vnc will pipe all of the user input
-events to in a simple format. In \fB-pipeinput\fR mode by
-default x11vnc will not process any of the user input
-events. If you prefix \fIcmd\fR with "tee:" it will
-both send them to the pipe command and process them.
-For a description of the format run "-pipeinput
-tee:/bin/cat". Another prefix is "reopen" which
-means to reopen pipe if it exits. Separate multiple
-prefixes with commas.
-.IP
-In combination with \fB-rawfb\fR one might be able to
-do amusing things (e.g. control non-X devices).
-To facilitate this, if \fB-rawfb\fR is in effect then the
-value is stored in X11VNC_RAWFB_STR for the pipe command
-to use if it wants. Do 'env | grep X11VNC' for more.
-.IP
-Built-in pipeinput modes (no external program required):
-.IP
-If cmd is "VID" and you are using the \fB-rawfb\fR for a
-video capture device, then an internal list of keyboard
-mappings is used to set parameters of the video.
-The mappings are:
-.IP
-"B" and "b" adjust the brightness up and down.
-"H" and "h" adjust the hue.
-"C" and "c" adjust the colour.
-"N" and "n" adjust the contrast.
-"S" and "s" adjust the size of the capture screen.
-"I" and "i" cycle through input channels.
-Up and Down arrows adjust the station (if a tuner)
-F1, F2, ..., F6 will switch the video capture pixel
-format to HI240, RGB565, RGB24, RGB32, RGB555, and
-GREY respectively. See \fB-rawfb\fR video for details.
-.IP
-If cmd is "CONSOLE" or "CONSOLEn" where n
-is a Linux console number, then the linux console
-keystroke insertion to /dev/ttyN (see \fB-rawfb\fR console)
-is performed.
-.IP
-If cmd begins with "UINPUT" then the Linux uinput
-module is used to insert both keystroke and mouse events
-to the Linux console (see \fB-rawfb\fR above). This usually
-is the /dev/input/uinput device file (you may need to
-create it with "mknod /dev/input/uinput c 10 223"
-and insert the module with "modprobe uinput".
-.IP
-The UINPUT mode currently only does US keyboards (a
-scan code option may be added), and not all keysyms
-are supported. But it is probably more accurate than
-the "CONSOLE" method.
-.IP
-You may want to use the options \fB-cursor\fR none and
-\fB-nodragging\fR in this mode.
-.IP
-Additional tuning options may be supplied via:
-UINPUT:opt1,opt2,... (a comma separated list). If an
-option begins with "/" it is taken as the uinput
-device file.
-.IP
-Which uinput is injected can be controlled by an option
-string made of the characters "K", "M", and "B"
-(see the \fB-input\fR option), e.g. "KM" allows keystroke
-and motion but not button clicks.
-.IP
-A UINPUT option of the form: accel=f, or accel=fx+fy
-sets the mouse motion "acceleration". This is used
-to correct raw mouse relative motion into how much the
-application cursor moves (x11vnc has no control over,
-or knowledge of how the windowing application interprets
-the raw mouse motions). Typically the acceleration
-for an X display is 2 (see xset "m" option). "f"
-is a floating point number, e.g. 3.0. Use "fx+fy"
-if you need to supply different corrections for x and y.
-.IP
-Note: the default acceleration is 2.0 since it seems
-both X and qt-embedded often (but not always) use
-this value.
-.IP
-Even with a correct accel setting the mouse position
-will get out of sync (probably due to a mouse
-"threshold" setting where the acceleration doe not
-apply, set
-.IR xset (1)
-). The option reset=N sets the
-number of ms (default 150) after which the cursor is
-attempted to be reset (by forcing the mouse to (0,
-0) via small increments and then back out to (x, y)
-in 1 jump), This correction seems to be needed but can
-cause jerkiness or unexpected behavior with menus, etc.
-Use reset=0 to disable.
-.IP
-If you set the env. var X11VNC_UINPUT_THRESHOLDS then
-the thresh=n mode will be enabled. It is currently
-not working well. If |dx| <= thresh and |dy| < thresh
-no acceleration is applied. Use "thresh=+n" |dx| +
-|dy| < thresh to be used instead (X11?)
-.IP
-Example:
-\fB-pipeinput\fR UINPUT:accel=4.0 \fB-cursor\fR none
-.IP
-If the uinput device has an absolute pointer (as opposed
-to a normal mouse that is a relative pointer) you can
-specify the option "abs". Note that a touchpad
-on a laptop is an absolute device to some degree.
-This (usually) avoids all the problems with mouse
-acceleration. If x11vnc has trouble deducing the
-size of the device, use "abs=WxH". Furthermore,
-if the device is a touchscreen (assumed to have an
-absolute pointer) use "touch" or "touch=WxH".
-For touchscreens, when a mouse button is pressed,
-a pressure increase is injected, and when the button
-is released a pressure of zero is injected.
-.IP
-If touch has been set, use "touch_always=1" to
-indicate whenever the mouse moves with no button
-pressed, a touch event of zero pressure should be
-sent anyway. Also use "btn_touch=1" to indicate a
-BTN_TOUCH keystroke press or release should be sent
-instead of a pressure change. Set "dragskip=n" to
-skip n dragged mouse touches (with pressure applied)
-before injecting one. To indicate the pressure that
-should be sent when there is a button click for a
-touchscreen device, specify pressure=n, e.g. n=5. The
-default is n=1.
-.IP
-If a touch screen is being used ("touch" above)
-and it is having its input processed by tslib, you can
-specify the tslib calibration file via tslib_cal=<file>.
-For example, tslib_cal=/etc/pointercal. To get accurate
-or even usable positioning this is required when tslib
-is in use.
-.IP
-The Linux uinput mechanism can be bypassed and one can
-write input events DIRECTLY to the devices instead.
-To do this, specify one or more of the following
-for the input classes: direct_rel=<device>
-direct_abs=<device> direct_btn=<device> or
-direct_key=<device>. The <device> file is usually
-something like /dev/input/event1 but you can specify
-any device file or pipe. You must specify each one
-of the above classes even if they correspond to the
-same device file (rel/abs and btn are often the same.)
-Look at the file /proc/bus/input/devices to get an idea
-what is available and the device filenames. Note:
-The /dev/input/mouse* devices do not seem to work,
-use the corresponding /dev/input/event* file instead.
-Any input class not directly specified as above will be
-handled via the uinput mechanism. To disable creating a
-uinput device (and thereby discarding unhandled input),
-specify "nouinput".
-.IP
-Examples:
-.IP
-\fB-pipeinput\fR UINPUT:direct_abs=/dev/input/event1
-.IP
-this was used on a qtmoko Neo freerunner (armel):
-.IP
-\fB-pipeinput\fR UINPUT:touch,tslib_cal=/etc/pointercal,
-direct_abs=/dev/input/event1,nouinput,dragskip=4
-.IP
-(where the long line has been split into two.)
-.IP
-You can set the env. var X11VNC_UINPUT_DEBUG=1 or higher
-to get debugging output for UINPUT mode.
-.PP
-\fB-macnodim\fR
-.IP
-For the native MacOSX server, disable dimming.
-.PP
-\fB-macnosleep\fR
-.IP
-For the native MacOSX server, disable display sleep.
-.PP
-\fB-macnosaver\fR
-.IP
-For the native MacOSX server, disable screensaver.
-.PP
-\fB-macnowait\fR
-.IP
-For the native MacOSX server, do not wait for the
-user to switch back to his display.
-.PP
-\fB-macwheel\fR \fIn\fR
-.IP
-For the native MacOSX server, set the mouse wheel
-speed to n (default 5).
-.PP
-\fB-macnoswap\fR
-.IP
-For the native MacOSX server, do not swap mouse
-buttons 2 and 3.
-.PP
-\fB-macnoresize\fR
-.IP
-For the native MacOSX server, do not resize or reset
-the framebuffer even if it is detected that the screen
-resolution or depth has changed.
-.PP
-\fB-maciconanim\fR \fIn\fR
-.IP
-For the native MacOSX server, set n to the number
-of milliseconds that the window iconify/deiconify
-animation takes. In \fB-ncache\fR mode this value will be
-used to skip the animation if possible. (default 400)
-.PP
-\fB-macmenu\fR
-.IP
-For the native MacOSX server, in \fB-ncache\fR client-side
-caching mode, try to cache pull down menus (not perfect
-because they have animated fades, etc.)
-.PP
-\fB-macuskbd\fR
-.IP
-For the native MacOSX server, use the original
-keystroke insertion code based on a US keyboard.
-.PP
-\fB-macnoopengl\fR
-.IP
-For the native MacOSX server, do not use OpenGL for
-screen capture, but rather use the original, deprecated
-raw memory access method: addr = CGDisplayBaseAddress().
-.PP
-\fB-macnorawfb\fR
-.IP
-For the native MacOSX server, disable the raw memory
-address screen capture method.
-.IP
-MACOSX NOTE: There are some deprecated MacOSX interfaces
-to inject keyboard and mouse events and the raw memory
-access method is deprecated as well (however, OpenGL
-will be preferred if available because it is faster.)
-One can force not using any deprecated interfaces at
-compile time by setting \fB-DX11VNC_MACOSX_NO_DEPRECATED=1\fR
-in CPPFLAGS. Or to turn them off one by one:
-\fB-DX11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS=1,\fR
-\fB-DX11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS=1\fR or
-\fB-DX11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER=1\fR
-At run time, for testing and workarounds, one can
-disable them by using:
-\fB-env\fR X11VNC_MACOSX_NO_DEPRECATED=1
-\fB-env\fR X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS=1
-\fB-env\fR X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS=1 or
-\fB-env\fR X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER=1
-Note: When doing either of these for the mouse input
-not everything works currently, e.g. double clicks and
-wireframing. Also, screen resolution and pixel depth
-changes will not be automatically detected unless the
-deprecated framebuffer interfaces are allowed.
-.IP
-Conversely, if you are compiling on an
-older machine that does not have some of
-the newer interfaces, you may need to specify
-\fB-DX11VNC_MACOSX_NO_CGEVENTCREATESCROLLWHEELEVENT\fR
-\fB-DX11VNC_MACOSX_NO_CGEVENTCREATEMOUSEEVENT\fR or
-\fB-DX11VNC_MACOSX_NO_CGEVENTCREATEKEYBOARDEVENT.\fR Use
-\fB-DX11VNC_MACOSX_USE_GETMAINDEVICE\fR to regain the very
-old QuickDraw GetMainDevice() interface (rare...)
-.PP
-\fB-gui\fR \fI[gui-opts]\fR
-.IP
-Start up a simple tcl/tk gui based on the remote
-control options \fB-remote/-query\fR described below.
-Requires the "wish" program to be installed on the
-machine. "gui-opts" is not required: the default
-is to start up both the full gui and x11vnc with the
-gui showing up on the X display in the environment
-variable DISPLAY.
-.IP
-"gui-opts" can be a comma separated list of items.
-Currently there are these types of items: 1) a gui
-mode, a 2) gui "simplicity", 3) the X display the
-gui should display on, 4) a "tray" or "icon" mode,
-and 5) a gui geometry.
-.IP
-1) The gui mode can be "start", "conn", or "wait"
-"start" is the default mode above and is not required.
-"conn" means do not automatically start up x11vnc,
-but instead just try to connect to an existing x11vnc
-process. "wait" means just start the gui and nothing
-else (you will later instruct the gui to start x11vnc
-or connect to an existing one.)
-.IP
-2) The gui simplicity is off by default (a power-user
-gui with all options is presented) To start with
-something less daunting supply the string "simple"
-("ez" is an alias for this). Once the gui is
-started you can toggle between the two with "Misc ->
-simple_gui".
-.IP
-3) Note the possible confusion regarding the potentially
-two different X displays: x11vnc polls one, but you
-may want the gui to appear on another. For example, if
-you ssh in and x11vnc is not running yet you may want
-the gui to come back to you via your ssh redirected X
-display (e.g. localhost:10).
-.IP
-If you do not specify a gui X display in "gui-opts"
-then the DISPLAY environment variable and \fB-display\fR
-option are tried (in that order). Regarding the x11vnc
-X display the gui will try to communication with, it
-first tries \fB-display\fR and then DISPLAY. For example,
-"x11vnc \fB-display\fR :0 \fB-gui\fR otherhost:0", will remote
-control an x11vnc polling :0 and display the gui on
-otherhost:0 The "tray/icon" mode below reverses this
-preference, preferring to display on the x11vnc display.
-.IP
-4) When "tray" or "icon" is specified, the gui
-presents itself as a small icon with behavior typical
-of a "system tray" or "dock applet". The color
-of the icon indicates status (connected clients) and
-there is also a balloon status. Clicking on the icon
-gives a menu from which properties, etc, can be set and
-the full gui is available under "Advanced". To be
-fully functional, the gui mode should be "start"
-(the default).
-.IP
-Note that tray or icon mode will imply the \fB-forever\fR
-x11vnc option (if the x11vnc server is started along
-with the gui) unless \fB-connect\fR or \fB-connect_or_exit\fR has
-been specified. So x11vnc (and the tray/icon gui)
-will wait for more connections after the first client
-disconnects. If you want only one viewer connection
-include the \fB-once\fR option.
-.IP
-For "icon" the gui just a small standalone window.
-For "tray" it will attempt to embed itself in the
-"system tray" if possible. If "=setpass" is appended then
-at startup the X11 user will be prompted to set the
-VNC session password. If =<hexnumber> is appended
-that icon will attempt to embed itself in the window
-given by hexnumber. Use =noadvanced to disable the
-full gui. (To supply more than one, use "+" sign).
-E.g. \fB-gui\fR tray=setpass and \fB-gui\fR icon=0x3600028
-.IP
-Other modes: "full", the default and need not be
-specified. "\fB-gui\fR \fInone\fR", do not show a gui, useful
-to override a ~/.x11vncrc setting, etc.
-.IP
-5) When "geom=+X+Y" is specified, that geometry
-is passed to the gui toplevel. This is the icon in
-icon/tray mode, or the full gui otherwise. You can
-also specify width and height, i.e. WxH+X+Y, but it
-is not recommended. In "tray" mode the geometry is
-ignored unless the system tray manager does not seem
-to be running. One could imagine using something like
-"\fB-gui\fR \fItray,geom=+4000+4000\fR" with a display manager
-to keep the gui invisible until someone logs in...
-.IP
-More icon tricks, "icon=minimal" gives an icon just
-with the VNC display number. You can also set the font
-with "iconfont=...". The following could be useful:
-"\fB-gui\fR \fIicon=minimal,iconfont=5x8,geom=24x10+0-0\fR"
-.IP
-General examples of the \fB-gui\fR option: "x11vnc \fB-gui",\fR
-"x11vnc \fB-gui\fR ez" "x11vnc \fB-gui\fR localhost:10",
-"x11vnc \fB-gui\fR conn,host:0", "x11vnc \fB-gui\fR tray,ez"
-"x11vnc \fB-gui\fR tray=setpass"
-.IP
-If you do not intend to start x11vnc from the gui
-(i.e. just remote control an existing one), then the
-gui process can run on a different machine from the
-x11vnc server as long as X permissions, etc. permit
-communication between the two.
-.IP
-FONTS: On some systems the tk fonts can be too small,
-jagged, or otherwise unreadable. There are 4 env vars
-you can set to be the tk font you prefer:
-.IP
-X11VNC_FONT_BOLD main font for menus and buttons.
-X11VNC_FONT_FIXED font for fixed width text.
-.IP
-X11VNC_FONT_BOLD_SMALL tray icon font.
-X11VNC_FONT_REG_SMALL tray icon menu font.
-.IP
-The last two only apply for the tray icon mode.
-.IP
-Here are some examples:
-.IP
-\fB-env\fR X11VNC_FONT_BOLD='Helvetica \fB-16\fR bold'
-\fB-env\fR X11VNC_FONT_FIXED='Courier \fB-14'\fR
-\fB-env\fR X11VNC_FONT_REG_SMALL='Helvetica \fB-12'\fR
-.IP
-You can put the lines like the above (without the
-quotes) in your ~/.x11vncrc file to avoid having to
-specify them on the x11vnc command line.
-.PP
-\fB-remote\fR \fIcommand\fR
-.IP
-Remotely control some aspects of an already running
-x11vnc server. "\fB-R\fR" and "\fB-r\fR" are aliases for
-"\fB-remote\fR". After the remote control command is
-sent to the running server the 'x11vnc \fB-remote\fR ...'
-x11vnc command exits. You can often use the \fB-query\fR
-command (see below) to see if the x11vnc server
-processed your \fB-remote\fR command.
-.IP
-The default communication channel is that of X
-properties (specifically X11VNC_REMOTE), and so this
-command must be run with correct settings for DISPLAY
-and possibly XAUTHORITY to connect to the X server
-and set the property. Alternatively, use the \fB-display\fR
-and \fB-auth\fR options to set them to the correct values.
-The running server cannot use the \fB-novncconnect\fR option
-because that disables the communication channel.
-See below for alternate channels.
-.IP
-For example: 'x11vnc \fB-remote\fR stop' (which is the same as
-\'x11vnc \fB-R\fR stop') will close down the x11vnc server.
-\'x11vnc \fB-R\fR shared' will enable shared connections, and
-\'x11vnc \fB-R\fR scale:3/4' will rescale the desktop.
-.IP
-To use a different name for the X11 property (e.g. to
-have separate communication channels for multiple
-x11vnc's on the same display) set the X11VNC_REMOTE
-environment variable to the string you want, for
-example: \fB-env\fR X11VNC_REMOTE=X11VNC_REMOTE_12345
-Both sides of the channel must use the same unique name.
-.IP
-To run a bunch of commands in a sequence use something
-like: x11vnc \fB-R\fR 'script:firstcmd;secondcmd;...'
-.IP
-Use x11vnc \fB-R\fR script:file=/path/to/file to read commands
-from a file (can be multi-line and use the comment '#'
-character in the normal way. The ';' separator must
-still be used to separate each command.)
-.IP
-To not try to contact another x11vnc process and instead
-just run the command (or query) directly, prefix the
-command with the string "DIRECT:"
-.IP
-.IP
-The following \fB-remote/-R\fR commands are supported:
-.IP
-stop terminate the server, same as "quit"
-"exit" or "shutdown".
-.IP
-ping see if the x11vnc server responds.
-return is: ans=ping:<display>
-.IP
-ping:mystring as above, but use your own unique string.
-return is: ans=ping:mystring:<xdisplay>
-.IP
-blacken try to push a black fb update to all
-clients (due to timings a client
-could miss it). Same as "zero", also
-"zero:x1,y1,x2,y2" for a rectangle.
-.IP
-refresh send the entire fb to all clients.
-.IP
-reset recreate the fb, polling memory, etc.
-.IP
-id:windowid set \fB-id\fR window to "windowid". empty
-or "root" to go back to root window
-.IP
-sid:windowid set \fB-sid\fR window to "windowid"
-.IP
-id_cmd:cmd cmds: raise, lower, map, unmap, iconify,
-move:dXdY, resize:dWdH, geom:WxH+X+Y. dX
-dY, dW, and dH must have a leading "+"
-or "-" e.g.: move:-30+10 resize:+20+35
-also: wm_delete, wm_name:string and
-icon_name:string. Also id_cmd:win=N:cmd
-.IP
-waitmapped wait until subwin is mapped.
-.IP
-nowaitmapped do not wait until subwin is mapped.
-.IP
-clip:WxH+X+Y set \fB-clip\fR mode to "WxH+X+Y"
-.IP
-flashcmap enable \fB-flashcmap\fR mode.
-.IP
-noflashcmap disable \fB-flashcmap\fR mode.
-.IP
-shiftcmap:n set \fB-shiftcmap\fR to n.
-.IP
-notruecolor enable \fB-notruecolor\fR mode.
-.IP
-truecolor disable \fB-notruecolor\fR mode.
-.IP
-overlay enable \fB-overlay\fR mode (if applicable).
-.IP
-nooverlay disable \fB-overlay\fR mode.
-.IP
-overlay_cursor in \fB-overlay\fR mode, enable cursor drawing.
-.IP
-overlay_nocursor disable cursor drawing. same as
-nooverlay_cursor.
-.IP
-8to24 enable \fB-8to24\fR mode (if applicable).
-.IP
-no8to24 disable \fB-8to24\fR mode.
-.IP
-8to24_opts:str set the \fB-8to24\fR opts to "str".
-.IP
-24to32 enable \fB-24to32\fR mode (if applicable).
-.IP
-no24to32 disable \fB-24to32\fR mode.
-.IP
-visual:vis set \fB-visual\fR to "vis"
-.IP
-scale:frac set \fB-scale\fR to "frac"
-.IP
-scale_cursor:f set \fB-scale_cursor\fR to "f"
-.IP
-viewonly enable \fB-viewonly\fR mode.
-.IP
-noviewonly disable \fB-viewonly\fR mode.
-.IP
-shared enable \fB-shared\fR mode.
-.IP
-noshared disable \fB-shared\fR mode.
-.IP
-forever enable \fB-forever\fR mode.
-.IP
-noforever disable \fB-forever\fR mode.
-.IP
-timeout:n reset \fB-timeout\fR to n, if there are
-currently no clients, exit unless one
-connects in the next n secs.
-.IP
-tightfilexfer enable filetransfer for NEW clients.
-.IP
-notightfilexfer disable filetransfer for NEW clients.
-.IP
-ultrafilexfer enable filetransfer for clients.
-.IP
-noultrafilexfer disable filetransfer for clients.
-.IP
-rfbversion:n.m set \fB-rfbversion\fR for new clients.
-.IP
-http enable http client connections.
-.IP
-nohttp disable http client connections.
-.IP
-deny deny any new connections, same as "lock"
-.IP
-nodeny allow new connections, same as "unlock"
-.IP
-avahi enable avahi service advertising.
-.IP
-noavahi disable avahi service advertising.
-.IP
-mdns enable avahi service advertising.
-.IP
-nomdns disable avahi service advertising.
-.IP
-zeroconf enable avahi service advertising.
-.IP
-nozeroconf disable avahi service advertising.
-.IP
-connect:host do reverse connection to host, "host"
-may be a comma separated list of hosts
-or host:ports. See \fB-connect.\fR Passwords
-required as with fwd connections.
-See X11VNC_REVERSE_CONNECTION_NO_AUTH=1
-.IP
-disconnect:host disconnect any clients from "host"
-same as "close:host". Use host
-"all" to close all current clients.
-If you know the client internal hex ID,
-e.g. 0x3 (returned by "\fB-query\fR \fIclients\fR"
-and RFB_CLIENT_ID) you can use that too.
-.IP
-proxy:host:port set reverse connection proxy (empty to
-disable).
-.IP
-allowonce:host For the next connection only, allow
-connection from "host". In \fB-ssl\fR mode
-two connections are allowed (i.e. Fetch
-Cert) unless X11VNC_NO_SSL_ALLOW_TWICE=1
-.IP
-allow:hostlist set \fB-allow\fR list to (comma separated)
-"hostlist". See \fB-allow\fR and \fB-localhost.\fR
-Do not use with \fB-allow\fR /path/to/file
-Use "+host" to add a single host, and
-use "\fB-host\fR" to delete a single host
-.IP
-localhost enable \fB-localhost\fR mode
-.IP
-nolocalhost disable \fB-localhost\fR mode
-.IP
-listen:str set \fB-listen\fR to str, empty to disable.
-.IP
-noipv6 enable \fB-noipv6\fR mode.
-.IP
-ipv6 disable \fB-noipv6\fR mode.
-.IP
-noipv4 enable \fB-noipv4\fR mode.
-.IP
-ipv4 disable \fB-noipv4\fR mode.
-.IP
-6 enable -6 IPv6 listening mode.
-.IP
-no6 disable -6 IPv6 listening mode.
-.IP
-lookup disable \fB-nolookup\fR mode.
-.IP
-nolookup enable \fB-nolookup\fR mode.
-.IP
-lookup disable \fB-nolookup\fR mode.
-.IP
-input:str set \fB-input\fR to "str", empty to disable.
-.IP
-grabkbd enable \fB-grabkbd\fR mode.
-.IP
-nograbkbd disable \fB-grabkbd\fR mode.
-.IP
-grabptr enable \fB-grabptr\fR mode.
-.IP
-nograbptr disable \fB-grabptr\fR mode.
-.IP
-grabalways enable \fB-grabalways\fR mode.
-.IP
-nograbalways disable \fB-grabalways\fR mode.
-.IP
-grablocal:n set \fB-grablocal\fR to n.
-.IP
-client_input:str set the K, M, B \fB-input\fR on a per-client
-basis. select which client as for
-disconnect, e.g. client_input:host:MB
-or client_input:0x2:K
-.IP
-accept:cmd set \fB-accept\fR "cmd" (empty to disable).
-.IP
-afteraccept:cmd set \fB-afteraccept\fR (empty to disable).
-.IP
-gone:cmd set \fB-gone\fR "cmd" (empty to disable).
-.IP
-noshm enable \fB-noshm\fR mode.
-.IP
-shm disable \fB-noshm\fR mode (i.e. use shm).
-.IP
-flipbyteorder enable \fB-flipbyteorder\fR mode, you may need
-to set noshm for this to do something.
-.IP
-noflipbyteorder disable \fB-flipbyteorder\fR mode.
-.IP
-onetile enable \fB-onetile\fR mode. (you may need to
-set shm for this to do something)
-.IP
-noonetile disable \fB-onetile\fR mode.
-.IP
-solid enable \fB-solid\fR mode
-.IP
-nosolid disable \fB-solid\fR mode.
-.IP
-solid_color:color set \fB-solid\fR color (and apply it).
-.IP
-blackout:str set \fB-blackout\fR "str" (empty to disable).
-See \fB-blackout\fR for the form of "str"
-(basically: WxH+X+Y,...)
-Use "+WxH+X+Y" to append a single
-rectangle use "-WxH+X+Y" to delete one
-.IP
-xinerama enable \fB-xinerama\fR mode. (if applicable)
-.IP
-noxinerama disable \fB-xinerama\fR mode.
-.IP
-xtrap enable \fB-xtrap\fR input mode(if applicable)
-.IP
-noxtrap disable \fB-xtrap\fR input mode.
-.IP
-xrandr enable \fB-xrandr\fR mode. (if applicable)
-.IP
-noxrandr disable \fB-xrandr\fR mode.
-.IP
-xrandr_mode:mode set the \fB-xrandr\fR mode to "mode".
-.IP
-rotate:mode set the \fB-rotate\fR mode to "mode".
-.IP
-padgeom:WxH set \fB-padgeom\fR to WxH (empty to disable)
-If WxH is "force" or "do" the padded
-geometry fb is immediately applied.
-.IP
-quiet enable \fB-quiet\fR mode.
-.IP
-noquiet disable \fB-quiet\fR mode.
-.IP
-modtweak enable \fB-modtweak\fR mode.
-.IP
-nomodtweak enable \fB-nomodtweak\fR mode.
-.IP
-xkb enable \fB-xkb\fR modtweak mode.
-.IP
-noxkb disable \fB-xkb\fR modtweak mode.
-.IP
-capslock enable \fB-capslock\fR mode.
-.IP
-nocapslock disable \fB-capslock\fR mode.
-.IP
-skip_lockkeys enable \fB-skip_lockkeys\fR mode.
-.IP
-noskip_lockkeys disable \fB-skip_lockkeys\fR mode.
-.IP
-skip_keycodes:str enable \fB-xkb\fR \fB-skip_keycodes\fR "str".
-.IP
-sloppy_keys enable \fB-sloppy_keys\fR mode.
-.IP
-nosloppy_keys disable \fB-sloppy_keys\fR mode.
-.IP
-skip_dups enable \fB-skip_dups\fR mode.
-.IP
-noskip_dups disable \fB-skip_dups\fR mode.
-.IP
-add_keysyms enable \fB-add_keysyms\fR mode.
-.IP
-noadd_keysyms stop adding keysyms. those added will
-still be removed at exit.
-.IP
-clear_mods enable \fB-clear_mods\fR mode and clear them.
-.IP
-noclear_mods disable \fB-clear_mods\fR mode.
-.IP
-clear_keys enable \fB-clear_keys\fR mode and clear them.
-.IP
-noclear_keys disable \fB-clear_keys\fR mode.
-.IP
-clear_locks do the clear_locks action.
-.IP
-clear_all do the clear_all action.
-.IP
-keystate have x11vnc print current keystate.
-.IP
-remap:str set \fB-remap\fR "str" (empty to disable).
-See \fB-remap\fR for the form of "str"
-(basically: key1-key2,key3-key4,...)
-Use "+key1-key2" to append a single
-keymapping, use "-key1-key2" to delete.
-.IP
-norepeat enable \fB-norepeat\fR mode.
-.IP
-repeat disable \fB-norepeat\fR mode.
-.IP
-nofb enable \fB-nofb\fR mode.
-.IP
-fb disable \fB-nofb\fR mode.
-.IP
-bell enable bell (if supported).
-.IP
-nobell disable bell.
-.IP
-sendbell ring the bell now.
-.IP
-nosel enable \fB-nosel\fR mode.
-.IP
-sel disable \fB-nosel\fR mode.
-.IP
-noprimary enable \fB-noprimary\fR mode.
-.IP
-primary disable \fB-noprimary\fR mode.
-.IP
-nosetprimary enable \fB-nosetprimary\fR mode.
-.IP
-setprimary disable \fB-nosetprimary\fR mode.
-.IP
-noclipboard enable \fB-noclipboard\fR mode.
-.IP
-clipboard disable \fB-noclipboard\fR mode.
-.IP
-nosetclipboard enable \fB-nosetclipboard\fR mode.
-.IP
-setclipboard disable \fB-nosetclipboard\fR mode.
-.IP
-seldir:str set \fB-seldir\fR to "str"
-.IP
-resend_cutbuffer resend the most recent CUTBUFFER0 copy
-.IP
-resend_clipboard resend the most recent CLIPBOARD copy
-.IP
-resend_primary resend the most recent PRIMARY copy
-.IP
-cursor:mode enable \fB-cursor\fR "mode".
-.IP
-show_cursor enable showing a cursor.
-.IP
-noshow_cursor disable showing a cursor. (same as
-"nocursor")
-.IP
-cursor_drag enable cursor changes during drag.
-.IP
-nocursor_drag disable cursor changes during drag.
-.IP
-arrow:n set \fB-arrow\fR to alternate n.
-.IP
-xfixes enable xfixes cursor shape mode.
-.IP
-noxfixes disable xfixes cursor shape mode.
-.IP
-alphacut:n set \fB-alphacut\fR to n.
-.IP
-alphafrac:f set \fB-alphafrac\fR to f.
-.IP
-alpharemove enable \fB-alpharemove\fR mode.
-.IP
-noalpharemove disable \fB-alpharemove\fR mode.
-.IP
-alphablend disable \fB-noalphablend\fR mode.
-.IP
-noalphablend enable \fB-noalphablend\fR mode.
-.IP
-cursorshape disable \fB-nocursorshape\fR mode.
-.IP
-nocursorshape enable \fB-nocursorshape\fR mode.
-.IP
-cursorpos disable \fB-nocursorpos\fR mode.
-.IP
-nocursorpos enable \fB-nocursorpos\fR mode.
-.IP
-xwarp enable \fB-xwarppointer\fR mode.
-.IP
-noxwarp disable \fB-xwarppointer\fR mode.
-.IP
-always_inject enable \fB-always_inject\fR mode.
-.IP
-noalways_inject disable \fB-always_inject\fR mode.
-.IP
-buttonmap:str set \fB-buttonmap\fR "str", empty to disable
-.IP
-dragging disable \fB-nodragging\fR mode.
-.IP
-nodragging enable \fB-nodragging\fR mode.
-.IP
-ncache reenable \fB-ncache\fR mode.
-.IP
-noncache disable \fB-ncache\fR mode.
-.IP
-ncache_size:n set \fB-ncache\fR size to n.
-.IP
-ncache_cr enable \fB-ncache_cr\fR mode.
-.IP
-noncache_cr disable \fB-ncache_cr\fR mode.
-.IP
-ncache_no_moveraise enable no_moveraise mode.
-.IP
-noncache_no_moveraise disable no_moveraise mode.
-.IP
-ncache_no_dtchange enable ncache_no_dtchange mode.
-.IP
-noncache_no_dtchange disable ncache_no_dtchange mode.
-.IP
-ncache_old_wm enable ncache_old_wm mode.
-.IP
-noncache_old_wm disable ncache_old_wm mode.
-.IP
-ncache_no_rootpixmap enable ncache_no_rootpixmap.
-.IP
-noncache_no_rootpixmap disable ncache_no_rootpixmap.
-.IP
-ncache_reset_rootpixmap recheck the root pixmap, ncrp
-.IP
-ncache_keep_anims enable ncache_keep_anims.
-.IP
-noncache_keep_anims disable ncache_keep_anims.
-.IP
-ncache_pad:n set \fB-ncache_pad\fR to n.
-.IP
-wireframe enable \fB-wireframe\fR mode. same as "wf"
-.IP
-nowireframe disable \fB-wireframe\fR mode. same as "nowf"
-.IP
-wireframe:str enable \fB-wireframe\fR mode string.
-.IP
-wireframe_mode:str enable \fB-wireframe\fR mode string.
-.IP
-wireframelocal enable wireframelocal. same as "wfl"
-.IP
-nowireframe disable wireframelocal. same as "nowfl"
-.IP
-wirecopyrect:str set \fB-wirecopyrect\fR string. same as "wcr:"
-.IP
-scrollcopyrect:str set \fB-scrollcopyrect\fR string. same "scr"
-.IP
-noscrollcopyrect disable \fB-scrollcopyrect__mode_.\fR "noscr"
-.IP
-scr_area:n set \fB-scr_area\fR to n
-.IP
-scr_skip:list set \fB-scr_skip\fR to "list"
-.IP
-scr_inc:list set \fB-scr_inc\fR to "list"
-.IP
-scr_keys:list set \fB-scr_keys\fR to "list"
-.IP
-scr_term:list set \fB-scr_term\fR to "list"
-.IP
-scr_keyrepeat:str set \fB-scr_keyrepeat\fR to "str"
-.IP
-scr_parms:str set \fB-scr_parms\fR parameters.
-.IP
-fixscreen:str set \fB-fixscreen\fR to "str".
-.IP
-noxrecord disable all use of RECORD extension.
-.IP
-xrecord enable use of RECORD extension.
-.IP
-reset_record reset RECORD extension (if avail.)
-.IP
-pointer_mode:n set \fB-pointer_mode\fR to n. same as "pm"
-.IP
-input_skip:n set \fB-input_skip\fR to n.
-.IP
-allinput enable use of \fB-allinput\fR mode.
-.IP
-noallinput disable use of \fB-allinput\fR mode.
-.IP
-input_eagerly enable use of \fB-input_eagerly\fR mode.
-.IP
-noinput_eagerly disable use of \fB-input_eagerly\fR mode.
-.IP
-ssltimeout:n set \fB-ssltimeout\fR to n.
-.IP
-speeds:str set \fB-speeds\fR to str.
-.IP
-wmdt:str set \fB-wmdt\fR to str.
-.IP
-debug_pointer enable \fB-debug_pointer,\fR same as "dp"
-.IP
-nodebug_pointer disable \fB-debug_pointer,\fR same as "nodp"
-.IP
-debug_keyboard enable \fB-debug_keyboard,\fR same as "dk"
-.IP
-nodebug_keyboard disable \fB-debug_keyboard,\fR same as "nodk"
-.IP
-keycode:n inject keystroke 'keycode' (xmodmap \fB-pk)\fR
-.IP
-keycode:n,down inject 'keycode' (down=0,1)
-.IP
-keysym:str inject keystroke 'keysym' (number/name)
-.IP
-keysym:str,down inject 'keysym' (down=0,1)
-.IP
-ptr:x,y,mask inject pointer event x, y, button-mask
-.IP
-fakebuttonevent:button,down direct XTestFakeButtonEvent.
-.IP
-sleep:t sleep floating point time t.
-.IP
-get_xprop:p get X property named 'p'.
-.IP
-set_xprop:p:val set X property named 'p' to 'val'.
-p -> id=NNN:p for hex/dec window id.
-.IP
-wininfo:id get info about X window id. use 'root'
-for root window, use +id for children.
-.IP
-grab_state get state of pointer and keyboard grab.
-.IP
-pointer_pos print XQueryPointer x,y cursor position.
-.IP
-pointer_x print XQueryPointer x cursor position.
-.IP
-pointer_y print XQueryPointer y cursor position.
-.IP
-pointer_same print XQueryPointer ptr on same screen.
-.IP
-pointer_root print XQueryPointer curr ptr rootwin.
-.IP
-pointer_mask print XQueryPointer button and mods mask
-.IP
-mouse_x print x11vnc's idea of cursor position.
-.IP
-mouse_y print x11vnc's idea of cursor position.
-.IP
-noop do nothing.
-.IP
-defer:n set \fB-defer\fR to n ms,same as deferupdate:n
-.IP
-wait:n set \fB-wait\fR to n ms.
-.IP
-extra_fbur:n set \fB-extra_fbur\fR to n.
-.IP
-wait_ui:f set \fB-wait_ui\fR factor to f.
-.IP
-setdefer:n set \fB-setdefer\fR to \fB-2,-1,0,1,\fR or 2.
-.IP
-wait_bog disable \fB-nowait_bog\fR mode.
-.IP
-nowait_bog enable \fB-nowait_bog\fR mode.
-.IP
-slow_fb:f set \fB-slow_fb\fR to f seconds.
-.IP
-xrefresh:f set \fB-xrefresh\fR to f seconds.
-.IP
-readtimeout:n set read timeout to n seconds.
-.IP
-nap enable \fB-nap\fR mode.
-.IP
-nonap disable \fB-nap\fR mode.
-.IP
-sb:n set \fB-sb\fR to n s, same as screen_blank:n
-.IP
-fbpm disable \fB-nofbpm\fR mode.
-.IP
-nofbpm enable \fB-nofbpm\fR mode.
-.IP
-dpms disable \fB-nodpms\fR mode.
-.IP
-nodpms enable \fB-nodpms\fR mode.
-.IP
-forcedpms enable \fB-forcedpms\fR mode.
-.IP
-noforcedpms disable \fB-forcedpms\fR mode.
-.IP
-clientdpms enable \fB-clientdpms\fR mode.
-.IP
-noclientdpms disable \fB-clientdpms\fR mode.
-.IP
-noserverdpms enable \fB-noserverdpms\fR mode.
-.IP
-serverdpms disable \fB-noserverdpms\fR mode.
-.IP
-noultraext enable \fB-noultraext\fR mode.
-.IP
-ultraext disable \fB-noultraext\fR mode.
-.IP
-chatwindow enable local chatwindow mode.
-.IP
-nochatwindow disable local chatwindow mode.
-.IP
-chaton begin chat using local window.
-.IP
-chatoff end chat using local window.
-.IP
-xdamage enable xdamage polling hints.
-.IP
-noxdamage disable xdamage polling hints.
-.IP
-xd_area:A set \fB-xd_area\fR max pixel area to "A"
-.IP
-xd_mem:f set \fB-xd_mem\fR remembrance to "f"
-.IP
-fs:frac set \fB-fs\fR fraction to "frac", e.g. 0.5
-.IP
-gaps:n set \fB-gaps\fR to n.
-.IP
-grow:n set \fB-grow\fR to n.
-.IP
-fuzz:n set \fB-fuzz\fR to n.
-.IP
-snapfb enable \fB-snapfb\fR mode.
-.IP
-nosnapfb disable \fB-snapfb\fR mode.
-.IP
-rawfb:str set \fB-rawfb\fR mode to "str".
-.IP
-uinput_accel:f set uinput_accel to f.
-.IP
-uinput_thresh:n set uinput_thresh to n.
-.IP
-uinput_reset:n set uinput_reset to n ms.
-.IP
-uinput_always:n set uinput_always to 1/0.
-.IP
-progressive:n set LibVNCServer \fB-progressive\fR slice
-height parameter to n.
-.IP
-desktop:str set \fB-desktop\fR name to str for new clients.
-.IP
-rfbport:n set \fB-rfbport\fR to n.
-.IP
-macnosaver enable \fB-macnosaver\fR mode.
-.IP
-macsaver disable \fB-macnosaver\fR mode.
-.IP
-macnowait enable \fB-macnowait\fR mode.
-.IP
-macwait disable \fB-macnowait\fR mode.
-.IP
-macwheel:n set \fB-macwheel\fR to n.
-.IP
-macnoswap enable \fB-macnoswap\fR mouse button mode.
-.IP
-macswap disable \fB-macnoswap\fR mouse button mode.
-.IP
-macnoresize enable \fB-macnoresize\fR mode.
-.IP
-macresize disable \fB-macnoresize\fR mode.
-.IP
-maciconanim:n set \fB-maciconanim\fR to n.
-.IP
-macmenu enable \fB-macmenu\fR mode.
-.IP
-macnomenu disable \fB-macmenu\fR mode.
-.IP
-macuskbd enable \fB-macuskbd\fR mode.
-.IP
-macnouskbd disable \fB-macuskbd\fR mode.
-.IP
-httpport:n set \fB-httpport\fR to n.
-.IP
-httpdir:dir set \fB-httpdir\fR to dir (and enable http).
-.IP
-enablehttpproxy enable \fB-enablehttpproxy\fR mode.
-.IP
-noenablehttpproxy disable \fB-enablehttpproxy\fR mode.
-.IP
-alwaysshared enable \fB-alwaysshared\fR mode.
-.IP
-noalwaysshared disable \fB-alwaysshared\fR mode.
-(may interfere with other options)
-.IP
-nevershared enable \fB-nevershared\fR mode.
-.IP
-nonevershared disable \fB-nevershared\fR mode.
-(may interfere with other options)
-.IP
-dontdisconnect enable \fB-dontdisconnect\fR mode.
-.IP
-nodontdisconnect disable \fB-dontdisconnect\fR mode.
-(may interfere with other options)
-.IP
-debug_xevents enable debugging X events.
-.IP
-nodebug_xevents disable debugging X events.
-.IP
-debug_xdamage enable debugging X DAMAGE mechanism.
-.IP
-nodebug_xdamage disable debugging X DAMAGE mechanism.
-.IP
-debug_wireframe enable debugging wireframe mechanism.
-.IP
-nodebug_wireframe disable debugging wireframe mechanism.
-.IP
-debug_scroll enable debugging scrollcopy mechanism.
-.IP
-nodebug_scroll disable debugging scrollcopy mechanism.
-.IP
-debug_tiles enable \fB-debug_tiles\fR
-.IP
-nodebug_tiles disable \fB-debug_tiles\fR
-.IP
-debug_grabs enable \fB-debug_grabs\fR
-.IP
-nodebug_grabs disable \fB-debug_grabs\fR
-.IP
-debug_sel enable \fB-debug_sel\fR
-.IP
-nodebug_sel disable \fB-debug_sel\fR
-.IP
-debug_ncache enable \fB-debug_ncache\fR
-.IP
-nodebug_ncache disable \fB-debug_ncache\fR
-.IP
-dbg enable \fB-dbg\fR crash shell
-.IP
-nodbg disable \fB-dbg\fR crash shell
-.IP
-.IP
-noremote disable the \fB-remote\fR command processing,
-it cannot be turned back on.
-.IP
-.IP
-bcx_xattach:str This remote control command is for
-use with the BARCO xattach program or the x2x program.
-Both of these programs are for 'pointer and keyboard'
-sharing between separate X displays. In general the
-two displays are usually nearby, e.g. on the same desk,
-and this allows the user to share a single pointer and
-keyboard between them. The user moves the mouse to
-an edge and then the mouse pointer appears to 'jump'
-to the other display screen. Thus it emulates what a
-single X server would do for two screens (e.g. :0.0 and
-:0.1) The illusion of a single Xserver with multiple
-screens is achieved by forwarding events to the 2nd
-one via the XTEST extension.
-.IP
-What the x11vnc bcx_xattach command does is to perform
-some pointer movements to try to INDUCE xattach/x2x
-to 'jump' to the other display. In what follows the
-\'master' display refers to the one that when it has
-\'focus' it is basically doing nothing besides watching
-for the mouse to go over an edge. The 'slave'
-display refers to the one to which the mouse and
-keyboard is redirected to once an edge in the master
-has been crossed. Note that the x11vnc executing the
-bcx_xattach command MUST be the one connected to the
-*master* display.
-.IP
-Also note that when input is being redirected (via
-XTEST) from the master display to the slave display,
-the master display's pointer and keyboard are *grabbed*
-by xattach/x2x. x11vnc can use this info to verify that
-the master/slave mode change has taken place correctly.
-If you specify the "ifneeded" option (see below)
-and the initial grab state is that of the desired
-final state, then no pointer movements are injected
-and "DONE,GRAB_OK" is returned.
-.IP
-"str" must contain one of "up", "down", "left",
-or "right" to indicate the direction of the 'jump'.
-"str" must also contain one of "master_to_slave"
-or "slave_to_master" to indicate the type of mode
-change induced by the jump. Use "M2S" and "S2M"
-as shorter aliases.
-.IP
-"str" may be a "+" separated list of additional
-tuning options. The "shift=n" option indicates an
-offset shift position away from (0,0) (default 20).
-"final=x+y" specifies the final position of the cursor
-at the end of the normal move sequence; default 30+30.
-"extra_move=x+y" means to do one more pointer move
-after "final" to x+y. "dt=n" sets the sleep time
-in milliseconds between pointer moves (default: 40ms)
-"retry=n" specifies the maximum number of retries if
-the grab state change fails. "ifneeded" means to not
-apply the pointer movements if the initial grab state is
-that of the desired final state. "nograbcheck" means
-to not check if the grab state changed as expected and
-only apply the pointer movements (default is to check
-the grab states.)
-.IP
-If you do not specify "up", etc., to bcx_xattach
-nothing will be attempted and the command returns
-the string FAIL,NO_DIRECTION_SPECIFIED. If you do
-not specify "master_to_slave" or "M2S", etc., to
-bcx_xattach nothing will be attempted and the command
-returns the string FAIL,NO_MODE_CHANGE_SPECIFIED.
-.IP
-Otherwise, the returned string will contain "DONE".
-It will be "DONE,GRAB_OK" if the grab state changed
-as expected (or if "ifneeded" was supplied and
-the initial grab state was already the desired
-one.) If the initial grab state was incorrect,
-but the final grab state was correct then it is
-"DONE,GRAB_FAIL_INIT". If the initial grab state
-was correct, but the final grab state was incorrect
-then it is "DONE,GRAB_FAIL_FINAL". If both are
-incorrect it will be "DONE,GRAB_FAIL". Under grab
-failure the string will be followed by ":p1,k1-p2,k2"
-where p1,k1 indicates the initial pointer and keyboard
-grab states and p2,k2 the final ones. If GRAB_FAIL or
-GRAB_FAIL_FINAL occurs, the action will be retried up
-to 3 times; trying to reset the state and sleeping a
-bit between each try. Set retry=n to adjust the number
-of retries, zero to disable retries.
-.IP
-Examples:
-\fB-R\fR bcx_xattach:down+M2S
-\fB-R\fR bcx_xattach:up+S2M
-\fB-R\fR bcx_xattach:up+S2M+nograbcheck+dt=30
-\fB-R\fR bcx_xattach:down+M2S+extra_move=100+100
-.IP
-or use \fB-Q\fR instead of \fB-R\fR to retrieve the result text.
-.IP
-End of the bcx_xattach:str description.
-.IP
-The
-.IR vncconnect (1)
-command from standard VNC
-distributions may also be used if string is prefixed
-with "cmd=" E.g. 'vncconnect cmd=stop'. Under some
-circumstances
-.IR xprop (1)
-can used if it supports \fB-set\fR
-(see the FAQ).
-.IP
-If "\fB-connect\fR \fI/path/to/file\fR" has been supplied to the
-running x11vnc server then that file can be used as a
-communication channel (this is the only way to remote
-control one of many x11vnc's polling the same X display)
-Simply run: 'x11vnc \fB-connect\fR /path/to/file \fB-remote\fR ...'
-or you can directly write to the file via something
-like: "echo cmd=stop > /path/to/file", etc.
-.PP
-\fB-query\fR \fIvariable\fR
-.IP
-Like \fB-remote,\fR except just query the value of
-\fIvariable\fR. "\fB-Q\fR" is an alias for "\fB-query\fR".
-Multiple queries can be done by separating variables
-by commas, e.g. \fB-query\fR var1,var2. The results come
-back in the form ans=var1:value1,ans=var2:value2,...
-to the standard output. If a variable is read-only,
-it comes back with prefix "aro=" instead of "ans=".
-.IP
-Some \fB-remote\fR commands are pure actions that do not make
-sense as variables, e.g. "stop" or "disconnect", in
-these cases the value returned is "N/A". To direct a
-query straight to the X11VNC_REMOTE property or connect
-file use "qry=..." instead of "cmd=..."
-.IP
-ans= stop quit exit shutdown ping resend_cutbuffer
-resend_clipboard resend_primary blacken zero refresh
-reset close disconnect id_cmd id sid waitmapped
-nowaitmapped clip flashcmap noflashcmap shiftcmap
-truecolor notruecolor overlay nooverlay overlay_cursor
-overlay_yescursor nooverlay_nocursor nooverlay_cursor
-nooverlay_yescursor overlay_nocursor 8to24 no8to24
-8to24_opts 24to32 no24to32 visual scale scale_cursor
-viewonly noviewonly shared noshared forever noforever
-once timeout tightfilexfer notightfilexfer ultrafilexfer
-noultrafilexfer rfbversion deny lock nodeny unlock avahi
-mdns zeroconf noavahi nomdns nozeroconf connect proxy
-allowonce allow noipv6 ipv6 noipv4 ipv4 no6 6 localhost
-nolocalhost listen lookup nolookup accept afteraccept
-gone shm noshm flipbyteorder noflipbyteorder onetile
-noonetile solid_color solid nosolid blackout xinerama
-noxinerama xtrap noxtrap xrandr noxrandr xrandr_mode
-rotate padgeom quiet q noquiet modtweak nomodtweak xkb
-noxkb capslock nocapslock skip_lockkeys noskip_lockkeys
-skip_keycodes sloppy_keys nosloppy_keys skip_dups
-noskip_dups add_keysyms noadd_keysyms clear_mods
-noclear_mods clear_keys noclear_keys clear_all
-clear_locks keystate remap repeat norepeat fb nofb bell
-nobell sendbell sel nosel primary noprimary setprimary
-nosetprimary clipboard noclipboard setclipboard
-nosetclipboard seldir cursorshape nocursorshape
-cursorpos nocursorpos cursor_drag nocursor_drag cursor
-show_cursor noshow_cursor nocursor arrow xfixes noxfixes
-xdamage noxdamage xd_area xd_mem alphacut alphafrac
-alpharemove noalpharemove alphablend noalphablend
-xwarppointer xwarp noxwarppointer noxwarp always_inject
-noalways_inject buttonmap dragging nodragging ncache_cr
-noncache_cr ncache_no_moveraise noncache_no_moveraise
-ncache_no_dtchange noncache_no_dtchange
-ncache_no_rootpixmap noncache_no_rootpixmap
-ncache_reset_rootpixmap ncrp ncache_keep_anims
-noncache_keep_anims ncache_old_wm noncache_old_wm
-ncache_pad ncache noncache ncache_size debug_ncache
-nodebug_ncache wireframe_mode wireframe wf nowireframe
-nowf wireframelocal wfl nowireframelocal nowfl
-wirecopyrect wcr nowirecopyrect nowcr scr_area
-scr_skip scr_inc scr_keys scr_term scr_keyrepeat
-scr_parms scrollcopyrect scr noscrollcopyrect
-noscr fixscreen noxrecord xrecord reset_record
-pointer_mode pm input_skip allinput noallinput
-input_eagerly noinput_eagerly input grabkbd nograbkbd
-grabptr nograbptr grabalways nograbalways grablocal
-client_input ssltimeout speeds wmdt debug_pointer dp
-nodebug_pointer nodp debug_keyboard dk nodebug_keyboard
-nodk keycode keysym ptr fakebuttonevent sleep get_xprop
-set_xprop wininfo bcx_xattach deferupdate defer
-setdefer extra_fbur wait_ui wait_bog nowait_bog
-slow_fb xrefresh wait readtimeout nap nonap sb
-screen_blank fbpm nofbpm dpms nodpms clientdpms
-noclientdpms forcedpms noforcedpms noserverdpms
-serverdpms noultraext ultraext chatwindow nochatwindow
-chaton chatoff fs gaps grow fuzz snapfb nosnapfb
-rawfb uinput_accel uinput_thresh uinput_reset
-uinput_always progressive rfbport http nohttp httpport
-httpdir enablehttpproxy noenablehttpproxy alwaysshared
-noalwaysshared nevershared noalwaysshared dontdisconnect
-nodontdisconnect desktop debug_xevents nodebug_xevents
-debug_xevents debug_xdamage nodebug_xdamage
-debug_xdamage debug_wireframe nodebug_wireframe
-debug_wireframe debug_scroll nodebug_scroll debug_scroll
-debug_tiles dbt nodebug_tiles nodbt debug_tiles
-debug_grabs nodebug_grabs debug_sel nodebug_sel dbg
-nodbg macnosaver macsaver nomacnosaver macnowait macwait
-nomacnowait macwheel macnoswap macswap nomacnoswap
-macnoresize macresize nomacnoresize maciconanim macmenu
-macnomenu nomacmenu macuskbd nomacuskbd noremote
-.IP
-aro= noop display vncdisplay icon_mode autoport
-loop loopbg desktopname guess_desktop guess_dbus
-http_url auth xauth users rootshift clipshift scale_str
-scaled_x scaled_y scale_numer scale_denom scale_fac_x
-scale_fac_y scaling_blend scaling_nomult4 scaling_pad
-scaling_interpolate inetd privremote unsafe safer nocmds
-passwdfile unixpw unixpw_nis unixpw_list ssl ssl_pem
-sslverify stunnel stunnel_pem https httpsredir usepw
-using_shm logfile o flag rmflag rc norc h help V version
-lastmod bg sigpipe threads readrate netrate netlatency
-pipeinput clients client_count pid ext_xtest ext_xtrap
-ext_xrecord ext_xkb ext_xshm ext_xinerama ext_overlay
-ext_xfixes ext_xdamage ext_xrandr rootwin num_buttons
-button_mask mouse_x mouse_y grab_state pointer_pos
-pointer_x pointer_y pointer_same pointer_root
-pointer_mask bpp depth indexed_color dpy_x dpy_y wdpy_x
-wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y rfbauth
-passwd viewpasswd
-.PP
-\fB-QD\fR \fIvariable\fR
-.IP
-Just like \fB-query\fR variable, but returns the default
-value for that parameter (no running x11vnc server
-is consulted)
-.PP
-\fB-sync\fR
-.IP
-By default \fB-remote\fR commands are run asynchronously, that
-is, the request is posted and the program immediately
-exits. Use \fB-sync\fR to have the program wait for an
-acknowledgement from the x11vnc server that command was
-processed (somehow). On the other hand \fB-query\fR requests
-are always processed synchronously because they have
-to wait for the answer.
-.IP
-Also note that if both \fB-remote\fR and \fB-query\fR requests are
-supplied on the command line, the \fB-remote\fR is processed
-first (synchronously: no need for \fB-sync),\fR and then
-the \fB-query\fR request is processed in the normal way.
-This allows for a reliable way to see if the \fB-remote\fR
-command was processed by querying for any new settings.
-Note however that there is timeout of a few seconds
-(see the next paragraph) so if the x11vnc takes longer
-than that to process the requests the requester will
-think that a failure has taken place.
-.IP
-The default is to wait 3.5 seconds. Or if cmd=stop
-only 1.0 seconds. If cmd matches 'script:' then it
-will wait up to 10.0 seconds. Set X11VNC_SYNC_TIMEOUT
-to the number of seconds you want it to wait.
-.PP
-\fB-query_retries\fR \fIstr\fR
-.IP
-If a query fails to get a response from an x11vnc
-server, retry up to n times. \fIstr\fR is specified as
-n[:t][/match] Optionally the delay between tries may
-be specified by "t" a floating point time (default
-0.5 seconds.) Note: the response is not checked for
-validity or whether it corresponds to the query sent.
-The query "ping:mystring" may be used to help uniquely
-identify the query. Optionally, a matching string after
-a "/" will be used to check the result text. Up to
-n retries will take place until the matching string is
-found in the output text. If the match string is never
-found the program's exit code is 1; if the match is
-found it exits with 0. Note that there may be stdout
-printed for each retry (i.e. multiple lines printed
-out to stdout.)
-Example: \fB-query_retries\fR 4:1.5/grab_state
-.PP
-\fB-remote_prefix\fR \fIstr\fR
-.IP
-Enable a remote-control communication channel for
-connected VNC clients. str is a non-empty string. If a
-VNC client sends rfbCutText having the prefix \fIstr\fR
-then the part after it is processed as though it were
-sent via 'x11vnc \fB-remote\fR ...'. If it begins with
-neither 'cmd=' nor 'qry=' then 'qry=' is assumed.
-Any corresponding output text for that remote control
-command is sent back to all client as rfbCutText.
-The returned output is also prefixed with \fIstr\fR.
-Example: \fB-remote_prefix\fR DO_THIS:
-.IP
-Note that enabling \fB-remote_prefix\fR allows the remote
-VNC viewers to run x11vnc \fB-remote\fR commands. Do not
-use this option if they are not to be trusted.
-.PP
-\fB-noremote,\fR \fB-yesremote\fR
-.IP
-Do not process any remote control commands or queries.
-Do process remote control commands or queries.
-Default: \fB-yesremote\fR
-.IP
-A note about security wrt remote control commands.
-If someone can connect to the X display and change
-the property X11VNC_REMOTE, then they can remotely
-control x11vnc. Normally access to the X display is
-protected. Note that if they can modify X11VNC_REMOTE
-on the X server, they have enough permissions to also
-run their own x11vnc and thus have complete control
-of the desktop. If the "\fB-connect\fR \fI/path/to/file\fR"
-channel is being used, obviously anyone who can write
-to /path/to/file can remotely control x11vnc. So be
-sure to protect the X display and that file's write
-permissions. See \fB-privremote\fR below.
-.IP
-If you are paranoid and do not think \fB-noremote\fR is
-enough, to disable the X11VNC_REMOTE property channel
-completely use \fB-novncconnect,\fR or use the \fB-safer\fR option
-that shuts many things off.
-.PP
-\fB-unsafe\fR
-.IP
-A few remote commands are disabled by default
-(currently: id:pick, accept:<cmd>, gone:<cmd>, and
-rawfb:setup:<cmd>) because they are associated with
-running external programs. If you specify \fB-unsafe,\fR then
-these remote-control commands are allowed. Note that
-you can still specify these parameters on the command
-line, they just cannot be invoked via remote-control.
-.PP
-\fB-safer\fR
-.IP
-Equivalent to: \fB-novncconnect\fR \fB-noremote\fR and prohibiting
-\fB-gui\fR and the \fB-connect\fR file. Shuts off communcation
-channels.
-.PP
-\fB-privremote\fR
-.IP
-Perform some sanity checks and disable remote-control
-commands if it appears that the X DISPLAY and/or
-connectfile can be accessed by other users. Once
-remote-control is disabled it cannot be turned back on.
-.PP
-\fB-nocmds\fR
-.IP
-No external commands (e.g.
-.IR system (3)
-,
-.IR popen (3)
-,
-.IR exec (3)
-)
-will be run at all.
-.PP
-\fB-allowedcmds\fR \fIlist\fR
-.IP
-\fIlist\fR contains a comma separated list of the only
-external commands that can be run. The full list of
-associated options is:
-.IP
-stunnel, ssl, unixpw, WAIT, zeroconf, id, accept,
-afteraccept, gone, pipeinput, v4l-info, rawfb-setup,
-dt, gui, ssh, storepasswd, passwdfile, custom_passwd,
-findauth, crash.
-.IP
-See each option's help to learn the associated external
-command. Note that the \fB-nocmds\fR option takes precedence
-and disables all external commands.
-.PP
-\fB-deny_all\fR
-.IP
-For use with \fB-remote\fR nodeny: start out denying all
-incoming clients until "\fB-remote\fR \fInodeny\fR" is used to
-let them in.
-.PP
-These options are passed to LibVNCServer:
-.PP
-\fB-rfbport\fR \fIport\fR
-.IP
-TCP port for RFB protocol
-.PP
-\fB-rfbwait\fR \fItime\fR
-.IP
-max time in ms to wait for RFB client
-.PP
-\fB-rfbauth\fR \fIpasswd-file\fR
-.IP
-use authentication on RFB protocol
-(use 'x11vnc \fB-storepasswd\fR pass file' to create a password file)
-.PP
-\fB-rfbversion\fR \fI3.x\fR
-.IP
-Set the version of the RFB we choose to advertise
-.PP
-\fB-permitfiletransfer\fR
-.IP
-permit file transfer support
-.PP
-\fB-passwd\fR \fIplain-password\fR
-.IP
-use authentication
-(use plain-password as password, USE AT YOUR RISK)
-.PP
-\fB-deferupdate\fR \fItime\fR
-.IP
-time in ms to defer updates (default 40)
-.PP
-\fB-deferptrupdate\fR \fItime\fR
-.IP
-time in ms to defer pointer updates (default none)
-.PP
-\fB-desktop\fR \fIname\fR
-.IP
-VNC desktop name (default "LibVNCServer")
-.PP
-\fB-alwaysshared\fR
-.IP
-always treat new clients as shared
-.PP
-\fB-nevershared\fR
-.IP
-never treat new clients as shared
-.PP
-\fB-dontdisconnect\fR
-.IP
-don't disconnect existing clients when a new non-shared
-connection comes in (refuse new connection instead)
-.PP
-\fB-httpdir\fR \fIdir-path\fR
-.IP
-enable http server using dir-path home
-.PP
-\fB-httpport\fR \fIportnum\fR
-.IP
-use portnum for http connection
-.PP
-\fB-enablehttpproxy\fR
-.IP
-enable http proxy support
-.PP
-\fB-progressive\fR \fIheight\fR
-.IP
-enable progressive updating for slow links
-.PP
-\fB-listen\fR \fIipaddr\fR
-.IP
-listen for connections only on network interface with
-addr ipaddr. '-listen localhost' and hostname work too.
-.PP
-libvncserver-tight-extension options:
-.PP
-\fB-disablefiletransfer\fR
-.IP
-disable file transfer
-.PP
-\fB-ftproot\fR \fIstring\fR
-.IP
-set ftp root
-.SH "FILES"
-.IR $HOME/.x11vncrc ,
-.IR $HOME/.Xauthority
-.SH "ENVIRONMENT"
-.IR DISPLAY ,
-.IR XAUTHORITY ,
-.IR HOME
-.PP
-The following are set for the auxiliary commands
-run by \fB-accept\fR, \fB-gone\fR and other cases:
-.PP
-.IR RFB_CLIENT_IP ,
-.IR RFB_CLIENT_PORT ,
-.IR RFB_SERVER_IP ,
-.IR RFB_SERVER_PORT ,
-.IR RFB_X11VNC_PID ,
-.IR RFB_CLIENT_ID ,
-.IR RFB_CLIENT_COUNT ,
-.IR RFB_MODE
-.IR RFB_STATE
-.IR RFB_LOGIN_VIEWONLY
-.IR RFB_LOGIN_TIME
-.IR RFB_CURRENT_TIME
-.IR RFB_USERNAME
-.IR RFB_SSL_CLIENT_CERT
-.SH "SEE ALSO"
-.IR vncviewer (1),
-.IR vncpasswd (1),
-.IR vncconnect (1),
-.IR vncserver (1),
-.IR Xvnc (1),
-.IR xev (1),
-.IR xdpyinfo (1),
-.IR xwininfo (1),
-.IR xprop (1),
-.IR xmodmap (1),
-.IR xrandr (1),
-.IR Xserver (1),
-.IR xauth (1),
-.IR xhost (1),
-.IR Xsecurity (7),
-.IR xmessage (1),
-.IR XGetImage (3X11),
-.IR ipcrm (1),
-.IR inetd (1),
-.IR xdm (1),
-.IR gdm (1),
-.IR kdm (1),
-.IR ssh (1),
-.IR stunnel (8),
-.IR su (1),
-.IR http://www.tightvnc.com ,
-.IR http://www.realvnc.com ,
-.IR http://www.karlrunge.com/x11vnc/ ,
-.IR http://www.karlrunge.com/x11vnc/#faq
-.SH AUTHORS
-x11vnc was written by Karl J. Runge <runge@karlrunge.com>,
-it is part of the LibVNCServer project <http://sf.net/projects/libvncserver>.
-This manual page is based one the one written by Ludovic Drolez
-<ldrolez@debian.org>, for the Debian project (both may be used by others).
diff --git a/x11vnc/x11vnc.c b/x11vnc/x11vnc.c
deleted file mode 100644
index 64a73de..0000000
--- a/x11vnc/x11vnc.c
+++ /dev/null
@@ -1,5945 +0,0 @@
-/*
- * x11vnc: a VNC server for X displays.
- *
- * Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- * All rights reserved.
- *
- * This file is part of x11vnc.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License, or (at
- * your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA or see <http://www.gnu.org/licenses/>.
- *
- * In addition, as a special exception, Karl J. Runge
- * gives permission to link the code of its release of x11vnc with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify this file, you may extend this exception to your version of the
- * file, but you are not obligated to do so. If you do not wish to do
- * so, delete this exception statement from your version.
- */
-
-/*
- * This program is based on some ideas from the following programs:
- *
- * the initial x11vnc.c in libvncserver (Johannes E. Schindelin)
- * x0rfbserver, the original native X vnc server (Jens Wagner)
- * krfb, the KDE desktopsharing project (Tim Jansen)
- *
- * Please see http://www.karlrunge.com/x11vnc for the most up-to-date
- * information about x11vnc. Some of the following text may be out
- * of date.
- *
- * The primary goal of this program is to create a portable and simple
- * command-line server utility that allows a VNC viewer to connect
- * to an actual X display (as the above do). The only non-standard
- * dependency of this program is the static library libvncserver.a.
- * Although in some environments libjpeg.so or libz.so may not be
- * readily available and needs to be installed, they may be found
- * at ftp://ftp.uu.net/graphics/jpeg/ and http://www.gzip.org/zlib/,
- * respectively. To increase portability it is written in plain C.
- *
- * Another goal is to improve performance and interactive response.
- * The algorithm of x0rfbserver was used as a base. Many additional
- * heuristics are also applied.
- *
- * Another goal is to add many features that enable and incourage creative
- * usage and application of the tool. Apologies for the large number
- * of options!
- *
- * To build:
- *
- * Obtain the libvncserver package (http://libvncserver.sourceforge.net).
- * As of 12/2002 this version of x11vnc.c is contained in the libvncserver
- * CVS tree and released in version 0.5.
- *
- * gcc should be used on all platforms. To build a threaded version put
- * "-D_REENTRANT -DX11VNC_THREADED" in the environment variable CFLAGS
- * or CPPFLAGS (e.g. before running the libvncserver configure). The
- * threaded mode is a bit more responsive, but can be unstable (e.g.
- * if more than one client the same tight or zrle encoding).
- *
- * Known shortcomings:
- *
- * The screen updates are good, but of course not perfect since the X
- * display must be continuously polled and read for changes and this is
- * slow for most hardware. This can be contrasted with receiving a change
- * callback from the X server, if that were generally possible... (UPDATE:
- * this is handled now with the X DAMAGE extension, but unfortunately
- * that doesn't seem to address the slow read from the video h/w). So,
- * e.g., opaque moves and similar window activity can be very painful;
- * one has to modify one's behavior a bit.
- *
- * General audio at the remote display is lost unless one separately
- * sets up some audio side-channel such as esd.
- *
- * It does not appear possible to query the X server for the current
- * cursor shape. We can use XTest to compare cursor to current window's
- * cursor, but we cannot extract what the cursor is... (UPDATE: we now
- * use XFIXES extension for this. Also on Solaris and IRIX Overlay
- * extensions exists that allow drawing the mouse into the framebuffer)
- *
- * The current *position* of the remote X mouse pointer is shown with
- * the -cursor option. Further, if -cursor X is used, a trick
- * is done to at least show the root window cursor vs non-root cursor.
- * (perhaps some heuristic can be done to further distinguish cases...,
- * currently "-cursor some" is a first hack at this)
- *
- * Under XFIXES mode for showing the cursor shape, the cursor may be
- * poorly approximated if it has transparency (alpha channel).
- *
- * Windows using visuals other than the default X visual may have
- * their colors messed up. When using 8bpp indexed color, the colormap
- * is attempted to be followed, but may become out of date. Use the
- * -flashcmap option to have colormap flashing as the pointer moves
- * windows with private colormaps (slow). Displays with mixed depth 8 and
- * 24 visuals will incorrectly display windows using the non-default one.
- * On Sun and Sgi hardware we can to work around this with -overlay.
- *
- * Feature -id <windowid> can be picky: it can crash for things like
- * the window not sufficiently mapped into server memory, etc (UPDATE:
- * we now use the -xrandr mechanisms to trap errors more robustly for
- * this mode). SaveUnders menus, popups, etc will not be seen.
- *
- * Under some situations the keysym unmapping is not correct, especially
- * if the two keyboards correspond to different languages. The -modtweak
- * option is the default and corrects most problems. One can use the
- * -xkb option to try to use the XKEYBOARD extension to clear up any
- * remaining problems.
- *
- * Occasionally, a few tile updates can be missed leaving a patch of
- * color that needs to be refreshed. This may only be when threaded,
- * which is no longer the default.
- *
- * There seems to be a serious bug with simultaneous clients when
- * threaded, currently the only workaround in this case is -nothreads
- * (which is now the default).
- */
-
-
-/* -- x11vnc.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "xdamage.h"
-#include "xrecord.h"
-#include "xevents.h"
-#include "xinerama.h"
-#include "xrandr.h"
-#include "xkb_bell.h"
-#include "win_utils.h"
-#include "remote.h"
-#include "scan.h"
-#include "gui.h"
-#include "help.h"
-#include "user.h"
-#include "cleanup.h"
-#include "keyboard.h"
-#include "pointer.h"
-#include "cursor.h"
-#include "userinput.h"
-#include "screen.h"
-#include "connections.h"
-#include "rates.h"
-#include "unixpw.h"
-#include "inet.h"
-#include "sslcmds.h"
-#include "sslhelper.h"
-#include "selection.h"
-#include "pm.h"
-#include "solid.h"
-
-/*
- * main routine for the x11vnc program
- */
-void watch_loop(void);
-
-static int limit_shm(void);
-static void check_rcfile(int argc, char **argv);
-static void immediate_switch_user(int argc, char* argv[]);
-static void print_settings(int try_http, int bg, char *gui_str);
-static void check_loop_mode(int argc, char* argv[], int force);
-static void check_appshare_mode(int argc, char* argv[]);
-
-static int tsdo_timeout_flag;
-
-static void tsdo_timeout (int sig) {
- tsdo_timeout_flag = 1;
- if (sig) {};
-}
-
-#define TASKMAX 32
-static pid_t ts_tasks[TASKMAX];
-static int ts_taskn = -1;
-
-int tsdo(int port, int lsock, int *conn) {
- int csock, rsock, i, db = 1;
- pid_t pid;
- struct sockaddr_in addr;
-#ifdef __hpux
- int addrlen = sizeof(addr);
-#else
- socklen_t addrlen = sizeof(addr);
-#endif
-
- if (*conn < 0) {
- signal(SIGALRM, tsdo_timeout);
- tsdo_timeout_flag = 0;
-
- alarm(10);
- csock = accept(lsock, (struct sockaddr *)&addr, &addrlen);
- alarm(0);
-
- if (db) rfbLog("tsdo: accept: lsock: %d, csock: %d, port: %d\n", lsock, csock, port);
-
- if (tsdo_timeout_flag > 0 || csock < 0) {
- close(csock);
- *conn = -1;
- return 1;
- }
- *conn = csock;
- } else {
- csock = *conn;
- if (db) rfbLog("tsdo: using existing csock: %d, port: %d\n", csock, port);
- }
-
- rsock = connect_tcp("127.0.0.1", port);
- if (rsock < 0) {
- if (db) rfbLog("tsdo: connect_tcp(port=%d) failed.\n", port);
- close(csock);
- return 2;
- }
-
- pid = fork();
- if (pid < 0) {
- close(csock);
- close(rsock);
- return 3;
- }
- if (pid > 0) {
- ts_taskn = (ts_taskn+1) % TASKMAX;
- ts_tasks[ts_taskn] = pid;
- close(csock);
- close(rsock);
- *conn = -1;
- return 0;
- }
- if (pid == 0) {
- for (i=0; i<255; i++) {
- if (i != csock && i != rsock && i != 2) {
- close(i);
- }
- }
-#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;
-}
-
-void set_redir_properties(void);
-
-#define TSMAX 32
-#define TSSTK 16
-
-void terminal_services(char *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;
- XErrorHandler old_handler1;
- XIOErrorHandler old_handler2;
- char num[32];
- time_t last_clean = time(NULL);
-
- if (getenv("TS_REDIR_DEBUG")) {
- db = 2;
- }
-
- if (! dpy) {
- return;
- }
-
- rwin = RootWindow(dpy, DefaultScreen(dpy));
-
- at = XInternAtom(dpy, "TS_REDIR_LIST", False);
- if (at != None) {
- XChangeProperty(dpy, rwin, at, XA_STRING, 8,
- PropModeReplace, (unsigned char *)list, strlen(list));
- XSync(dpy, False);
- }
- if (db) fprintf(stderr, "TS_REDIR_LIST Atom: %d.\n", (int) at);
-
- oh_restart_it_all:
-
- for (i=0; i<TASKMAX; i++) {
- ts_tasks[i] = 0;
- }
- for (i=0; i<TSMAX; i++) {
- socks[i] = -1;
- listen[i] = -1;
- for (j=0; j<TSSTK; j++) {
- redir[i][j] = 0;
- }
- }
-
- rate_start = 0.0;
- rate_count = 0;
-
- n = 0;
- str = strdup(list);
- p = strtok(str, ",");
- while (p) {
- int m1, m2;
- if (db) fprintf(stderr, "item: %s\n", p);
- q = strrchr(p, ':');
- if (!q) {
- p = strtok(NULL, ",");
- continue;
- }
- r = strchr(p, ':');
- if (!r || r == q) {
- p = strtok(NULL, ",");
- continue;
- }
-
- m1 = atoi(q+1);
- *q = '\0';
- m2 = atoi(r+1);
- *r = '\0';
-
- if (m1 <= 0 || m2 <= 0 || m1 >= 0xffff || m2 >= 0xffff) {
- p = strtok(NULL, ",");
- continue;
- }
-
- redir[n][0] = m1;
- listen[n] = m2;
- tag[n] = strdup(p);
-
- if (db) fprintf(stderr, " %d %d %s\n", redir[n][0], listen[n], tag[n]);
-
- *r = ':';
- *q = ':';
-
- n++;
- if (n >= TSMAX) {
- break;
- }
- p = strtok(NULL, ",");
- }
- free(str);
-
- if (n==0) {
- return;
- }
-
- at = XInternAtom(dpy, "TS_REDIR_PID", False);
- if (at != None) {
- sprintf(num, "%d", getpid());
- XChangeProperty(dpy, rwin, at, XA_STRING, 8,
- PropModeReplace, (unsigned char *)num, strlen(num));
- XSync(dpy, False);
- }
-
- for (i=0; i<n; i++) {
- int k;
- atom[i] = XInternAtom(dpy, tag[i], False);
- if (db) fprintf(stderr, "tag: %s atom: %d\n", tag[i], (int) atom[i]);
- if (atom[i] == None) {
- continue;
- }
- sprintf(num, "%d", redir[i][0]);
- if (db) fprintf(stderr, " listen: %d redir: %s\n", listen[i], num);
- XChangeProperty(dpy, rwin, atom[i], XA_STRING, 8,
- PropModeReplace, (unsigned char *)num, strlen(num));
- XSync(dpy, False);
-
- for (k=1; k <= 5; k++) {
- /* XXX ::1 fallback? */
- socks[i] = listen_tcp(listen[i], htonl(INADDR_LOOPBACK), 1);
- if (socks[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")) {
- if (!strcmp(getenv("TSD_RESTART"), "1")) {
- set_redir_properties();
- }
- }
-
- while (1) {
- struct timeval tv;
- int nfd;
- int fmax = -1;
-
- tv.tv_sec = 3;
- tv.tv_usec = 0;
-
- FD_ZERO(&rd);
- for (i=0; i<n; i++) {
- if (socks[i] >= 0) {
- FD_SET(socks[i], &rd);
- if (socks[i] > fmax) {
- fmax = socks[i];
- }
- }
- }
-
- nfd = select(fmax+1, &rd, NULL, NULL, &tv);
-
- if (db && 0) fprintf(stderr, "nfd=%d\n", nfd);
- if (nfd < 0 && errno == EINTR) {
- XSync(dpy, True);
- continue;
- }
- if (nfd > 0) {
- int did_ts = 0;
- for(i=0; i<n; i++) {
- int k = 0;
- for (j = 0; j < TSSTK; j++) {
- tstk[j] = 0;
- }
- for (j = 0; j < TSSTK; j++) {
- if (redir[i][j] != 0) {
- tstk[k++] = redir[i][j];
- }
- }
- for (j = 0; j < TSSTK; j++) {
- redir[i][j] = tstk[j];
-if (tstk[j] != 0) fprintf(stderr, "B redir[%d][%d] = %d %s\n", i, j, tstk[j], tag[i]);
- }
- }
- for(i=0; i<n; i++) {
- int s = socks[i];
- if (s < 0) {
- continue;
- }
- if (FD_ISSET(s, &rd)) {
- int p0, p, found = -1, jzero = -1;
- int conn = -1;
-
- get_prop(num, 32, atom[i], None);
- p0 = atoi(num);
-
- for (j = TSSTK-1; j >= 0; j--) {
- if (redir[i][j] == 0) {
- jzero = j;
- continue;
- }
- if (p0 > 0 && p0 < 0xffff) {
- if (redir[i][j] == p0) {
- found = j;
- break;
- }
- }
- }
- if (jzero < 0) {
- jzero = TSSTK-1;
- }
- if (found < 0) {
- if (p0 > 0 && p0 < 0xffff) {
- redir[i][jzero] = p0;
- }
- }
- for (j = TSSTK-1; j >= 0; j--) {
- int rc;
- p = redir[i][j];
- if (p <= 0 || p >= 0xffff) {
- redir[i][j] = 0;
- continue;
- }
-
- if (dnow() > 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);
- if (p != p0) {
- sprintf(num, "%d", p);
- XChangeProperty(dpy, rwin, atom[i], XA_STRING, 8,
- PropModeReplace, (unsigned char *)num, strlen(num));
- XSync(dpy, False);
- }
- break;
- } else if (rc == 1) {
- /* accept failed */
- 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, 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(500*1000);
- break;
- }
- }
- for (j = 0; j < TSSTK; j++) {
- if (redir[i][j] != 0) fprintf(stderr, "A redir[%d][%d] = %d %s\n", i, j, redir[i][j], tag[i]);
- }
- }
- }
- if (did_ts && rate_count > 100) {
- int 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<n; i++) {
- int s = socks[i];
- if (s < 0) {
- continue;
- }
- rfbLog("terminal_services: closing listen=%d sock=%d.\n", listen[i], socks[i]);
- if (listen[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<TASKMAX; i++) {
- pid_t p = ts_tasks[i];
- if (p > 0) {
- int status;
- pid_t p2 = waitpid(p, &status, WNOHANG);
- if (p2 == p) {
- ts_tasks[i] = 0;
- }
- }
- }
- /* this is to drop events and exit when X server is gone. */
- old_handler1 = XSetErrorHandler(trap_xerror);
- old_handler2 = XSetIOErrorHandler(trap_xioerror);
- trapped_xerror = 0;
- trapped_xioerror = 0;
-
- XSync(dpy, True);
-
- sprintf(num, "%d", (int) time(NULL));
- at = XInternAtom(dpy, "TS_REDIR", False);
- if (at != None) {
- XChangeProperty(dpy, rwin, at, XA_STRING, 8,
- PropModeReplace, (unsigned char *)num, strlen(num));
- XSync(dpy, False);
- }
- if (time(NULL) > last_clean + 20 * 60) {
- int i, j;
- for(i=0; i<n; i++) {
- int first = 1;
- for (j = TSSTK-1; j >= 0; j--) {
- int s, p = redir[i][j];
- if (p <= 0 || p >= 0xffff) {
- redir[i][j] = 0;
- continue;
- }
- s = connect_tcp("127.0.0.1", p);
- if (s < 0) {
- redir[i][j] = 0;
- if (db) fprintf(stderr, "tsdo[%d][%d] clean: connect failed: %d\n", i, j, p);
- } else {
- close(s);
- if (first) {
- sprintf(num, "%d", p);
- XChangeProperty(dpy, rwin, atom[i], XA_STRING, 8,
- PropModeReplace, (unsigned char *)num, strlen(num));
- XSync(dpy, False);
- }
- first = 0;
- }
- usleep(500*1000);
- }
- }
- last_clean = time(NULL);
- }
- if (trapped_xerror || trapped_xioerror) {
- if (db) fprintf(stderr, "Xerror: %d/%d\n", trapped_xerror, trapped_xioerror);
- exit(0);
- }
- XSetErrorHandler(old_handler1);
- XSetIOErrorHandler(old_handler2);
- }
-#endif
-}
-
-char *ts_services[][2] = {
- {"FD_CUPS", "TS_CUPS_REDIR"},
- {"FD_SMB", "TS_SMB_REDIR"},
- {"FD_ESD", "TS_ESD_REDIR"},
- {"FD_NAS", "TS_NAS_REDIR"},
- {NULL, NULL}
-};
-
-void do_tsd(void) {
-#if !NO_X11
- Atom a;
- char prop[513];
- pid_t pid;
- char *cmd;
- int n, sz = 0;
- char *disp = DisplayString(dpy);
- char *logfile = getenv("TS_REDIR_LOGFILE");
- int db = 0;
-
- if (getenv("TS_REDIR_DEBUG")) {
- db = 1;
- }
- if (db) fprintf(stderr, "do_tsd() in.\n");
-
- prop[0] = '\0';
- a = XInternAtom(dpy, "TS_REDIR_LIST", False);
- if (a != None) {
- get_prop(prop, 512, a, None);
- }
- if (db) fprintf(stderr, "TS_REDIR_LIST Atom: %d = '%s'\n", (int) a, prop);
-
- if (prop[0] == '\0') {
- return;
- }
-
- if (! program_name) {
- program_name = "x11vnc";
- }
- sz += strlen(program_name) + 1;
- sz += strlen("-display") + 1;
- sz += strlen(disp) + 1;
- sz += strlen("-tsd") + 1;
- sz += 1 + strlen(prop) + 1 + 1;
- sz += strlen("-env TSD_RESTART=1") + 1;
- sz += strlen("</dev/null 1>/dev/null 2>&1") + 1;
- sz += strlen(" &") + 1;
- if (logfile) {
- sz += strlen(logfile);
- }
- if (ipv6_listen) {
- sz += strlen("-6") + 1;
- }
-
- cmd = (char *) malloc(sz);
-
- if (getenv("XAUTHORITY")) {
- char *xauth = getenv("XAUTHORITY");
- if (!strcmp(xauth, "") || access(xauth, R_OK) != 0) {
- *(xauth-2) = '_'; /* yow */
- }
- }
- sprintf(cmd, "%s -display %s -tsd '%s' -env TSD_RESTART=1 %s </dev/null 1>%s 2>&1 &",
- program_name, disp, prop, ipv6_listen ? "-6" : "",
- logfile ? logfile : "/dev/null" );
- rfbLog("running: %s\n", cmd);
-
-#if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SETSID
- /* fork into the background now */
- if ((pid = fork()) > 0) {
- pid_t pidw;
- int status;
- double s = dnow();
-
- while (dnow() < s + 1.5) {
- pidw = waitpid(pid, &status, WNOHANG);
- if (pidw == pid) {
- break;
- }
- usleep(100*1000);
- }
- return;
-
- } else if (pid == -1) {
- system(cmd);
- } else {
- setsid();
- /* adjust our stdio */
- n = open("/dev/null", O_RDONLY);
- dup2(n, 0);
- dup2(n, 1);
- dup2(n, 2);
- if (n > 2) {
- close(n);
- }
- system(cmd);
- exit(0);
- }
-#else
- system(cmd);
-#endif
-
-#endif
-}
-
-void set_redir_properties(void) {
-#if !NO_X11
- char *e, *f, *t;
- Atom a;
- char num[32];
- int i, p;
-
- if (! dpy) {
- return;
- }
-
- i = 0;
- while (ts_services[i][0] != NULL) {
- f = ts_services[i][0];
- t = ts_services[i][1];
- e = getenv(f);
- if (!e || strstr(e, "DAEMON-") != e) {
- i++;
- continue;
- }
- p = atoi(e + strlen("DAEMON-"));
- if (p <= 0) {
- i++;
- continue;
- }
- sprintf(num, "%d", p);
- a = XInternAtom(dpy, t, False);
- if (a != None) {
- Window rwin = RootWindow(dpy, DefaultScreen(dpy));
-fprintf(stderr, "Set: %s %s %s -> %s\n", f, t, e, num);
- XChangeProperty(dpy, rwin, a, XA_STRING, 8,
- PropModeReplace, (unsigned char *) num, strlen(num));
- XSync(dpy, False);
- }
- i++;
- }
-#endif
-}
-
-static void check_redir_services(void) {
-#if !NO_X11
- Atom a;
- char prop[513];
- time_t tsd_last;
- int restart = 0;
- pid_t pid = 0;
- int db = 0;
- db = 0;
-
- if (getenv("TS_REDIR_DEBUG")) {
- db = 1;
- }
- if (db) fprintf(stderr, "check_redir_services in.\n");
-
- if (! dpy) {
- return;
- }
-
- a = XInternAtom(dpy, "TS_REDIR_PID", False);
- if (a != None) {
- prop[0] = '\0';
- get_prop(prop, 512, a, None);
- if (prop[0] != '\0') {
- pid = (pid_t) atoi(prop);
- }
- }
- if (db) fprintf(stderr, "TS_REDIR_PID Atom: %d = '%s'\n", (int) a, prop);
-
- if (getenv("FD_TAG") && strcmp(getenv("FD_TAG"), "")) {
- a = XInternAtom(dpy, "FD_TAG", False);
- if (a != None) {
- Window rwin = RootWindow(dpy, DefaultScreen(dpy));
- char *tag = getenv("FD_TAG");
- XChangeProperty(dpy, rwin, a, XA_STRING, 8,
- PropModeReplace, (unsigned char *)tag, strlen(tag));
- XSync(dpy, False);
- }
- if (db) fprintf(stderr, "FD_TAG Atom: %d = '%s'\n", (int) a, prop);
- }
-
- prop[0] = '\0';
- a = XInternAtom(dpy, "TS_REDIR", False);
- if (a != None) {
- get_prop(prop, 512, a, None);
- }
- if (db) fprintf(stderr, "TS_REDIR Atom: %d = '%s'\n", (int) a, prop);
- if (prop[0] == '\0') {
- rfbLog("TS_REDIR is empty, restarting...\n");
- restart = 1;
- } else {
- tsd_last = (time_t) atoi(prop);
- if (time(NULL) > tsd_last + 30) {
- rfbLog("TS_REDIR seems dead for: %d sec, restarting...\n",
- time(NULL) - tsd_last);
- restart = 1;
- } else if (pid > 0 && time(NULL) > tsd_last + 6) {
- if (kill(pid, 0) != 0) {
- rfbLog("TS_REDIR seems dead via kill(%d, 0), restarting...\n",
- pid);
- restart = 1;
- }
- }
- }
- if (restart) {
-
- if (pid > 1) {
- rfbLog("killing TS_REDIR_PID: %d\n", pid);
- kill(pid, SIGTERM);
- usleep(500*1000);
- kill(pid, SIGKILL);
- }
- do_tsd();
- if (db) fprintf(stderr, "check_redir_services restarted.\n");
- return;
- }
-
- if (db) fprintf(stderr, "check_redir_services, no restart, calling set_redir_properties.\n");
- set_redir_properties();
-#endif
-}
-
-void ssh_remote_tunnel(char *instr, int lport) {
- char *q, *cmd, *ssh;
- char *s = strdup(instr);
- int sleep = 300, disp = 0, sport = 0;
- int rc, len, rport;
-
- /* user@host:port:disp+secs */
-
- /* +sleep */
- q = strrchr(s, '+');
- if (q) {
- sleep = atoi(q+1);
- if (sleep <= 0) {
- sleep = 1;
- }
- *q = '\0';
- }
- /* :disp */
- q = strrchr(s, ':');
- if (q) {
- disp = atoi(q+1);
- *q = '\0';
- }
-
- /* :sshport */
- q = strrchr(s, ':');
- if (q) {
- sport = atoi(q+1);
- *q = '\0';
- }
-
- if (getenv("SSH")) {
- ssh = getenv("SSH");
- } else {
- ssh = "ssh";
- }
-
- len = 0;
- len += strlen(ssh) + strlen(s) + 500;
- cmd = (char *) malloc(len);
-
- if (disp >= 0 && disp <= 200) {
- rport = disp + 5900;
- } else if (disp < 0) {
- rport = -disp;
- } else {
- rport = disp;
- }
-
- if (sport > 0) {
- sprintf(cmd, "%s -f -p %d -R '%d:localhost:%d' '%s' 'sleep %d'", ssh, sport, rport, lport, s, sleep);
- } else {
- sprintf(cmd, "%s -f -R '%d:localhost:%d' '%s' 'sleep %d'", ssh, rport, lport, s, sleep);
- }
-
- if (no_external_cmds || !cmd_ok("ssh")) {
- rfbLogEnable(1);
- rfbLog("cannot run external commands in -nocmds mode:\n");
- rfbLog(" \"%s\"\n", cmd);
- rfbLog(" exiting.\n");
- clean_up_exit(1);
- }
-
- close_exec_fds();
- fprintf(stderr, "\n");
- rfbLog("running: %s\n", cmd);
- rc = system(cmd);
-
- if (rc != 0) {
- free(cmd);
- free(s);
- rfbLog("ssh remote listen failed.\n");
- clean_up_exit(1);
- }
-
- if (1) {
- FILE *pipe;
- int mypid = (int) getpid();
- int bestpid = -1;
- int best = -1;
- char line[1024];
- char *psef = "ps -ef";
- char *psww = "ps wwwwwwaux";
- char *ps = psef;
- /* not portable... but it is really good to terminate the ssh when done. */
- /* ps -ef | egrep 'ssh2.*-R.*5907:localhost:5900.*runge@celias.lbl.gov.*sleep 300' | grep -v grep | awk '{print $2}' */
- if (strstr(UT.sysname, "Linux")) {
- ps = psww;
- } else if (strstr(UT.sysname, "BSD")) {
- ps = psww;
- } else if (strstr(UT.sysname, "Darwin")) {
- ps = psww;
- }
- sprintf(cmd, "env COLUMNS=256 %s | egrep '%s.*-R *%d:localhost:%d.*%s.*sleep *%d' | grep -v grep | awk '{print $2}'", ps, ssh, rport, lport, s, sleep);
- pipe = popen(cmd, "r");
- if (pipe) {
- while (fgets(line, 1024, pipe) != NULL) {
- int p = atoi(line);
- if (p > 0) {
- int score;
- if (p > mypid) {
- score = p - mypid;
- } else {
- score = p - mypid + 32768;
- if (score < 0) {
- score = 32768;
- }
- }
- if (best < 0 || score < best) {
- best = score;
- bestpid = p;
- }
- }
- }
- pclose(pipe);
- }
-
- if (bestpid != -1) {
- ssh_pid = (pid_t) bestpid;
- rfbLog("guessed ssh pid=%d, will terminate it on exit.\n", bestpid);
- }
- }
-
- free(cmd);
- free(s);
-}
-
-/*
- * check blacklist for OSs with tight shm limits.
- */
-static int limit_shm(void) {
- int limit = 0;
-
- if (UT.sysname == NULL) {
- return 0;
- }
- if (getenv("X11VNC_NO_LIMIT_SHM")) {
- return 0;
- }
- if (!strcmp(UT.sysname, "SunOS")) {
- char *r = UT.release;
- if (*r == '5' && *(r+1) == '.') {
- if (strchr("2345678", *(r+2)) != NULL) {
- limit = 1;
- }
- }
- } else if (!strcmp(UT.sysname, "Darwin")) {
- limit = 1;
- }
- if (limit && ! quiet) {
- fprintf(stderr, "reducing shm usage on %s %s (adding "
- "-onetile)\n", UT.sysname, UT.release);
- }
- return limit;
-}
-
-
-/*
- * quick-n-dirty ~/.x11vncrc: each line (except # comments) is a cmdline option.
- */
-static int argc2 = 0;
-static char **argv2;
-
-static void check_rcfile(int argc, char **argv) {
- int i, j, pwlast, enclast, norc = 0, argmax = 1024;
- char *infile = NULL;
- char rcfile[1024];
- FILE *rc = NULL;
-
- for (i=1; i < argc; i++) {
- if (!strcmp(argv[i], "-printgui")) {
- fprintf(stdout, "%s", get_gui_code());
- fflush(stdout);
- exit(0);
- }
- if (!strcmp(argv[i], "-norc")) {
- norc = 1;
- got_norc = 1;
- }
- if (!strcmp(argv[i], "-QD")) {
- norc = 1;
- }
- if (!strcmp(argv[i], "-rc")) {
- if (i+1 >= argc) {
- fprintf(stderr, "-rc option requires a "
- "filename\n");
- exit(1);
- } else {
- infile = argv[i+1];
- }
- }
- }
- rc_norc = norc;
- rc_rcfile = strdup("");
- if (norc) {
- ;
- } else if (infile != NULL) {
- rc = fopen(infile, "r");
- rc_rcfile = strdup(infile);
- if (rc == NULL) {
- fprintf(stderr, "could not open rcfile: %s\n", infile);
- perror("fopen");
- exit(1);
- }
- } else {
- char *home = get_home_dir();
- if (! home) {
- norc = 1;
- } else {
- memset(rcfile, 0, sizeof(rcfile));
- strncpy(rcfile, home, 500);
- free(home);
-
- strcat(rcfile, "/.x11vncrc");
- infile = rcfile;
- rc = fopen(rcfile, "r");
- if (rc == NULL) {
- norc = 1;
- } else {
- rc_rcfile = strdup(rcfile);
- rc_rcfile_default = 1;
- }
- }
- }
-
- argv2 = (char **) malloc(argmax * sizeof(char *));
- argv2[argc2++] = strdup(argv[0]);
-
- if (! norc) {
- char line[4096], parm[400], tmp[401];
- char *buf, *tbuf;
- struct stat sbuf;
- int sz;
-
- if (fstat(fileno(rc), &sbuf) != 0) {
- fprintf(stderr, "problem with %s\n", infile);
- perror("fstat");
- exit(1);
- }
- sz = sbuf.st_size+1; /* allocate whole file size */
- if (sz < 1024) {
- sz = 1024;
- }
-
- buf = (char *) malloc(sz);
- buf[0] = '\0';
-
- while (fgets(line, 4096, rc) != NULL) {
- char *q, *p = line;
- char c;
- int cont = 0;
-
- q = p;
- c = '\0';
- while (*q) {
- if (*q == '#') {
- if (c != '\\') {
- *q = '\0';
- break;
- }
- }
- c = *q;
- q++;
- }
-
- q = p;
- c = '\0';
- while (*q) {
- if (*q == '\n') {
- if (c == '\\') {
- cont = 1;
- *q = '\0';
- *(q-1) = ' ';
- break;
- }
- while (isspace((unsigned char) (*q))) {
- *q = '\0';
- if (q == p) {
- break;
- }
- q--;
- }
- break;
- }
- c = *q;
- q++;
- }
- if (q != p && !cont) {
- if (*q == '\0') {
- q--;
- }
- while (isspace((unsigned char) (*q))) {
- *q = '\0';
- if (q == p) {
- break;
- }
- q--;
- }
- }
-
- p = lblanks(p);
-
- strncat(buf, p, sz - strlen(buf) - 1);
- if (cont) {
- continue;
- }
- if (buf[0] == '\0') {
- continue;
- }
-
- i = 0;
- q = buf;
- while (*q) {
- i++;
- if (*q == '\n' || isspace((unsigned char) (*q))) {
- break;
- }
- q++;
- }
-
- if (i >= 400) {
- fprintf(stderr, "invalid rcfile line: %s/%s\n",
- p, buf);
- exit(1);
- }
-
- if (sscanf(buf, "%s", parm) != 1) {
- fprintf(stderr, "invalid rcfile line: %s\n", p);
- exit(1);
- }
- if (parm[0] == '-') {
- strncpy(tmp, parm, 400);
- } else {
- tmp[0] = '-';
- strncpy(tmp+1, parm, 400);
- }
-
- if (strstr(tmp, "-loop") == tmp) {
- if (! getenv("X11VNC_LOOP_MODE")) {
- check_loop_mode(argc, argv, 1);
- exit(0);
- }
- }
-
- argv2[argc2++] = strdup(tmp);
- if (argc2 >= argmax) {
- fprintf(stderr, "too many rcfile options\n");
- exit(1);
- }
-
- p = buf;
- p += strlen(parm);
- p = lblanks(p);
-
- if (*p == '\0') {
- buf[0] = '\0';
- continue;
- }
-
- tbuf = (char *) calloc(strlen(p) + 1, 1);
-
- j = 0;
- while (*p) {
- if (*p == '\\' && *(p+1) == '#') {
- ;
- } else {
- tbuf[j++] = *p;
- }
- p++;
- }
-
- argv2[argc2++] = strdup(tbuf);
- free(tbuf);
- if (argc2 >= argmax) {
- fprintf(stderr, "too many rcfile options\n");
- exit(1);
- }
- buf[0] = '\0';
- }
- fclose(rc);
- free(buf);
- }
- pwlast = 0;
- enclast = 0;
- for (i=1; i < argc; i++) {
- argv2[argc2++] = strdup(argv[i]);
-
- if (pwlast || !strcmp("-passwd", argv[i])
- || !strcmp("-viewpasswd", argv[i])) {
- char *p = argv[i];
- if (pwlast) {
- pwlast = 0;
- } else {
- pwlast = 1;
- }
- strzero(p);
- }
- if (enclast || !strcmp("-enc", argv[i])) {
- char *q, *p = argv[i];
- if (enclast) {
- enclast = 0;
- } else {
- enclast = 1;
- }
- q = strstr(p, "pw=");
- if (q) {
- strzero(q);
- }
- }
- if (argc2 >= argmax) {
- fprintf(stderr, "too many rcfile options\n");
- exit(1);
- }
- }
-}
-
-static void immediate_switch_user(int argc, char* argv[]) {
- int i, bequiet = 0;
- for (i=1; i < argc; i++) {
- if (strcmp(argv[i], "-inetd")) {
- bequiet = 1;
- }
- if (strcmp(argv[i], "-quiet")) {
- bequiet = 1;
- }
- if (strcmp(argv[i], "-q")) {
- bequiet = 1;
- }
- }
- for (i=1; i < argc; i++) {
- char *u, *q;
-
- if (strcmp(argv[i], "-users")) {
- continue;
- }
- if (i == argc - 1) {
- fprintf(stderr, "not enough arguments for: -users\n");
- exit(1);
- }
- if (*(argv[i+1]) != '=') {
- break;
- }
-
- /* wants an immediate switch: =bob */
- u = strdup(argv[i+1]);
- *u = '+';
- q = strchr(u, '.');
- if (q) {
- user2group = (char **) malloc(2*sizeof(char *));
- user2group[0] = strdup(u+1);
- user2group[1] = NULL;
- *q = '\0';
- }
- if (strstr(u, "+guess") == u) {
- fprintf(stderr, "invalid user: %s\n", u+1);
- exit(1);
- }
- if (!switch_user(u, 0)) {
- fprintf(stderr, "Could not switch to user: %s\n", u+1);
- exit(1);
- } else {
- if (!bequiet) {
- fprintf(stderr, "Switched to user: %s\n", u+1);
- }
- started_as_root = 2;
- }
- free(u);
- break;
- }
-}
-
-static void quick_pw(char *str) {
- char *p, *q;
- char tmp[1024];
- int db = 0;
-
- if (db) fprintf(stderr, "quick_pw: %s\n", str);
-
- if (! str || str[0] == '\0') {
- exit(2);
- }
- if (str[0] != '%') {
- exit(2);
- }
- /*
- * "%-" or "%stdin" means read one line from stdin.
- *
- * "%env" means it is in $UNIXPW env var.
- *
- * starting "%/" or "%." means read the first line from that file.
- *
- * "%%" or "%" means prompt user.
- *
- * otherwise: %user:pass
- */
- if (!strcmp(str, "%-") || !strcmp(str, "%stdin")) {
- if(fgets(tmp, 1024, stdin) == NULL) {
- exit(2);
- }
- q = strdup(tmp);
- } else if (!strcmp(str, "%env")) {
- if (getenv("UNIXPW") == NULL) {
- exit(2);
- }
- q = strdup(getenv("UNIXPW"));
- } else if (!strcmp(str, "%%") || !strcmp(str, "%")) {
- char *t, inp[1024];
- fprintf(stdout, "username: ");
- if(fgets(tmp, 128, stdin) == NULL) {
- exit(2);
- }
- strcpy(inp, tmp);
- t = strchr(inp, '\n');
- if (t) {
- *t = ':';
- } else {
- strcat(inp, ":");
-
- }
- fprintf(stdout, "password: ");
- /* test mode: no_external_cmds does not apply */
- system("stty -echo");
- if(fgets(tmp, 128, stdin) == NULL) {
- fprintf(stdout, "\n");
- system("stty echo");
- exit(2);
- }
- system("stty echo");
- fprintf(stdout, "\n");
- strcat(inp, tmp);
- q = strdup(inp);
- } else if (str[1] == '/' || str[1] == '.') {
- FILE *in = fopen(str+1, "r");
- if (in == NULL) {
- exit(2);
- }
- if(fgets(tmp, 1024, in) == NULL) {
- exit(2);
- }
- fclose(in);
- q = strdup(tmp);
- } else {
- q = strdup(str+1);
- }
- p = (char *) malloc(strlen(q) + 10);
- strcpy(p, q);
- if (strchr(p, '\n') == NULL) {
- strcat(p, "\n");
- }
-
- if ((q = strchr(p, ':')) == NULL) {
- exit(2);
- }
- *q = '\0';
- if (db) fprintf(stderr, "'%s' '%s'\n", p, q+1);
- if (unixpw_cmd) {
- if (cmd_verify(p, q+1)) {
- fprintf(stdout, "Y %s\n", p);
- exit(0);
- } else {
- fprintf(stdout, "N %s\n", p);
- exit(1);
- }
- } else if (unixpw_nis) {
- if (crypt_verify(p, q+1)) {
- fprintf(stdout, "Y %s\n", p);
- exit(0);
- } else {
- fprintf(stdout, "N %s\n", p);
- exit(1);
- }
- } else {
- char *ucmd = getenv("UNIXPW_CMD");
- if (su_verify(p, q+1, ucmd, NULL, NULL, 1)) {
- fprintf(stdout, "Y %s\n", p);
- exit(0);
- } else {
- fprintf(stdout, "N %s\n", p);
- exit(1);
- }
- }
- /* NOTREACHED */
- exit(2);
-}
-
-static void print_settings(int try_http, int bg, char *gui_str) {
-
- fprintf(stderr, "\n");
- fprintf(stderr, "Settings:\n");
- fprintf(stderr, " display: %s\n", use_dpy ? use_dpy
- : "null");
-#if SMALL_FOOTPRINT < 2
- fprintf(stderr, " authfile: %s\n", auth_file ? auth_file
- : "null");
- fprintf(stderr, " subwin: 0x%lx\n", subwin);
- fprintf(stderr, " -sid mode: %d\n", rootshift);
- fprintf(stderr, " clip: %s\n", clip_str ? clip_str
- : "null");
- fprintf(stderr, " flashcmap: %d\n", flash_cmap);
- fprintf(stderr, " shiftcmap: %d\n", shift_cmap);
- fprintf(stderr, " force_idx: %d\n", force_indexed_color);
- fprintf(stderr, " cmap8to24: %d\n", cmap8to24);
- fprintf(stderr, " 8to24_opts: %s\n", cmap8to24_str ? cmap8to24_str
- : "null");
- fprintf(stderr, " 24to32: %d\n", xform24to32);
- fprintf(stderr, " visual: %s\n", visual_str ? visual_str
- : "null");
- fprintf(stderr, " overlay: %d\n", overlay);
- fprintf(stderr, " ovl_cursor: %d\n", overlay_cursor);
- fprintf(stderr, " scaling: %d %.4f %.4f\n", scaling, scale_fac_x, scale_fac_y);
- fprintf(stderr, " viewonly: %d\n", view_only);
- fprintf(stderr, " shared: %d\n", shared);
- fprintf(stderr, " conn_once: %d\n", connect_once);
- fprintf(stderr, " timeout: %d\n", first_conn_timeout);
- fprintf(stderr, " ping: %d\n", ping_interval);
- fprintf(stderr, " inetd: %d\n", inetd);
- fprintf(stderr, " tightfilexfer: %d\n", tightfilexfer);
- fprintf(stderr, " http: %d\n", try_http);
- fprintf(stderr, " connect: %s\n", client_connect
- ? client_connect : "null");
- fprintf(stderr, " connectfile %s\n", client_connect_file
- ? client_connect_file : "null");
- fprintf(stderr, " vnc_conn: %d\n", vnc_connect);
- fprintf(stderr, " allow: %s\n", allow_list ? allow_list
- : "null");
- fprintf(stderr, " input: %s\n", allowed_input_str
- ? allowed_input_str : "null");
- fprintf(stderr, " passfile: %s\n", passwdfile ? passwdfile
- : "null");
- fprintf(stderr, " unixpw: %d\n", unixpw);
- fprintf(stderr, " unixpw_lst: %s\n", unixpw_list ? unixpw_list:"null");
- fprintf(stderr, " ssl: %s\n", openssl_pem ? openssl_pem:"null");
- fprintf(stderr, " ssldir: %s\n", ssl_certs_dir ? ssl_certs_dir:"null");
- fprintf(stderr, " ssltimeout %d\n", ssl_timeout_secs);
- fprintf(stderr, " sslverify: %s\n", ssl_verify ? ssl_verify:"null");
- fprintf(stderr, " stunnel: %d\n", use_stunnel);
- fprintf(stderr, " accept: %s\n", accept_cmd ? accept_cmd
- : "null");
- fprintf(stderr, " accept: %s\n", afteraccept_cmd ? afteraccept_cmd
- : "null");
- fprintf(stderr, " gone: %s\n", gone_cmd ? gone_cmd
- : "null");
- fprintf(stderr, " users: %s\n", users_list ? users_list
- : "null");
- fprintf(stderr, " using_shm: %d\n", using_shm);
- fprintf(stderr, " flipbytes: %d\n", flip_byte_order);
- fprintf(stderr, " onetile: %d\n", single_copytile);
- fprintf(stderr, " solid: %s\n", solid_str
- ? solid_str : "null");
- fprintf(stderr, " blackout: %s\n", blackout_str
- ? blackout_str : "null");
- fprintf(stderr, " xinerama: %d\n", xinerama);
- fprintf(stderr, " xtrap: %d\n", xtrap_input);
- fprintf(stderr, " xrandr: %d\n", xrandr);
- fprintf(stderr, " xrandrmode: %s\n", xrandr_mode ? xrandr_mode
- : "null");
- fprintf(stderr, " padgeom: %s\n", pad_geometry
- ? pad_geometry : "null");
- fprintf(stderr, " logfile: %s\n", logfile ? logfile
- : "null");
- fprintf(stderr, " logappend: %d\n", logfile_append);
- fprintf(stderr, " flag: %s\n", flagfile ? flagfile
- : "null");
- fprintf(stderr, " rm_flag: %s\n", rm_flagfile ? rm_flagfile
- : "null");
- fprintf(stderr, " rc_file: \"%s\"\n", rc_rcfile ? rc_rcfile
- : "null");
- fprintf(stderr, " norc: %d\n", rc_norc);
- fprintf(stderr, " dbg: %d\n", crash_debug);
- fprintf(stderr, " bg: %d\n", bg);
- fprintf(stderr, " mod_tweak: %d\n", use_modifier_tweak);
- fprintf(stderr, " isolevel3: %d\n", use_iso_level3);
- fprintf(stderr, " xkb: %d\n", use_xkb_modtweak);
- fprintf(stderr, " skipkeys: %s\n",
- skip_keycodes ? skip_keycodes : "null");
- fprintf(stderr, " sloppykeys: %d\n", sloppy_keys);
- fprintf(stderr, " skip_dups: %d\n", skip_duplicate_key_events);
- fprintf(stderr, " addkeysyms: %d\n", add_keysyms);
- fprintf(stderr, " xkbcompat: %d\n", xkbcompat);
- fprintf(stderr, " clearmods: %d\n", clear_mods);
- fprintf(stderr, " remap: %s\n", remap_file ? remap_file
- : "null");
- fprintf(stderr, " norepeat: %d\n", no_autorepeat);
- fprintf(stderr, " norepeatcnt:%d\n", no_repeat_countdown);
- fprintf(stderr, " nofb: %d\n", nofb);
- fprintf(stderr, " watchbell: %d\n", watch_bell);
- fprintf(stderr, " watchsel: %d\n", watch_selection);
- fprintf(stderr, " watchprim: %d\n", watch_primary);
- fprintf(stderr, " seldir: %s\n", sel_direction ?
- sel_direction : "null");
- fprintf(stderr, " cursor: %d\n", show_cursor);
- fprintf(stderr, " multicurs: %d\n", show_multiple_cursors);
- fprintf(stderr, " curs_mode: %s\n", multiple_cursors_mode
- ? multiple_cursors_mode : "null");
- fprintf(stderr, " arrow: %d\n", alt_arrow);
- fprintf(stderr, " xfixes: %d\n", use_xfixes);
- fprintf(stderr, " alphacut: %d\n", alpha_threshold);
- fprintf(stderr, " alphafrac: %.2f\n", alpha_frac);
- fprintf(stderr, " alpharemove:%d\n", alpha_remove);
- fprintf(stderr, " alphablend: %d\n", alpha_blend);
- fprintf(stderr, " cursorshape:%d\n", cursor_shape_updates);
- fprintf(stderr, " cursorpos: %d\n", cursor_pos_updates);
- fprintf(stderr, " xwarpptr: %d\n", use_xwarppointer);
- fprintf(stderr, " alwaysinj: %d\n", always_inject);
- fprintf(stderr, " buttonmap: %s\n", pointer_remap
- ? pointer_remap : "null");
- fprintf(stderr, " dragging: %d\n", show_dragging);
- fprintf(stderr, " ncache: %d\n", ncache);
- fprintf(stderr, " wireframe: %s\n", wireframe_str ?
- wireframe_str : WIREFRAME_PARMS);
- fprintf(stderr, " wirecopy: %s\n", wireframe_copyrect ?
- wireframe_copyrect : wireframe_copyrect_default);
- fprintf(stderr, " scrollcopy: %s\n", scroll_copyrect ?
- scroll_copyrect : scroll_copyrect_default);
- fprintf(stderr, " scr_area: %d\n", scrollcopyrect_min_area);
- fprintf(stderr, " scr_skip: %s\n", scroll_skip_str ?
- scroll_skip_str : scroll_skip_str0);
- fprintf(stderr, " scr_inc: %s\n", scroll_good_str ?
- scroll_good_str : scroll_good_str0);
- fprintf(stderr, " scr_keys: %s\n", scroll_key_list_str ?
- scroll_key_list_str : "null");
- fprintf(stderr, " scr_term: %s\n", scroll_term_str ?
- scroll_term_str : "null");
- fprintf(stderr, " scr_keyrep: %s\n", max_keyrepeat_str ?
- max_keyrepeat_str : "null");
- fprintf(stderr, " scr_parms: %s\n", scroll_copyrect_str ?
- scroll_copyrect_str : SCROLL_COPYRECT_PARMS);
- fprintf(stderr, " fixscreen: %s\n", screen_fixup_str ?
- screen_fixup_str : "null");
- fprintf(stderr, " noxrecord: %d\n", noxrecord);
- fprintf(stderr, " grabbuster: %d\n", grab_buster);
- fprintf(stderr, " ptr_mode: %d\n", pointer_mode);
- fprintf(stderr, " inputskip: %d\n", ui_skip);
- fprintf(stderr, " speeds: %s\n", speeds_str
- ? speeds_str : "null");
- fprintf(stderr, " wmdt: %s\n", wmdt_str
- ? wmdt_str : "null");
- fprintf(stderr, " debug_ptr: %d\n", debug_pointer);
- fprintf(stderr, " debug_key: %d\n", debug_keyboard);
- fprintf(stderr, " defer: %d\n", defer_update);
- fprintf(stderr, " waitms: %d\n", waitms);
- fprintf(stderr, " wait_ui: %.2f\n", wait_ui);
- fprintf(stderr, " nowait_bog: %d\n", !wait_bog);
- fprintf(stderr, " slow_fb: %.2f\n", slow_fb);
- fprintf(stderr, " xrefresh: %.2f\n", xrefresh);
- fprintf(stderr, " readtimeout: %d\n", rfbMaxClientWait/1000);
- fprintf(stderr, " take_naps: %d\n", take_naps);
- fprintf(stderr, " sb: %d\n", screen_blank);
- fprintf(stderr, " fbpm: %d\n", !watch_fbpm);
- fprintf(stderr, " dpms: %d\n", !watch_dpms);
- fprintf(stderr, " xdamage: %d\n", use_xdamage);
- fprintf(stderr, " xd_area: %d\n", xdamage_max_area);
- fprintf(stderr, " xd_mem: %.3f\n", xdamage_memory);
- fprintf(stderr, " sigpipe: %s\n", sigpipe
- ? sigpipe : "null");
- fprintf(stderr, " threads: %d\n", use_threads);
- fprintf(stderr, " fs_frac: %.2f\n", fs_frac);
- fprintf(stderr, " gaps_fill: %d\n", gaps_fill);
- fprintf(stderr, " grow_fill: %d\n", grow_fill);
- fprintf(stderr, " tile_fuzz: %d\n", tile_fuzz);
- fprintf(stderr, " snapfb: %d\n", use_snapfb);
- fprintf(stderr, " rawfb: %s\n", raw_fb_str
- ? raw_fb_str : "null");
- fprintf(stderr, " pipeinput: %s\n", pipeinput_str
- ? pipeinput_str : "null");
- fprintf(stderr, " gui: %d\n", launch_gui);
- fprintf(stderr, " gui_mode: %s\n", gui_str
- ? gui_str : "null");
- fprintf(stderr, " noremote: %d\n", !accept_remote_cmds);
- fprintf(stderr, " unsafe: %d\n", !safe_remote_only);
- fprintf(stderr, " privremote: %d\n", priv_remote);
- fprintf(stderr, " safer: %d\n", more_safe);
- fprintf(stderr, " nocmds: %d\n", no_external_cmds);
- fprintf(stderr, " deny_all: %d\n", deny_all);
- fprintf(stderr, " pid: %d\n", getpid());
- fprintf(stderr, "\n");
-#endif
-}
-
-
-static void check_loop_mode(int argc, char* argv[], int force) {
- int i;
- int loop_mode = 0, loop_sleep = 2000, loop_max = 0;
-
- if (force) {
- loop_mode = 1;
- }
- for (i=1; i < argc; i++) {
- char *p = argv[i];
- if (strstr(p, "--") == p) {
- p++;
- }
- if (strstr(p, "-loop") == p) {
- char *q;
- loop_mode = 1;
- if ((q = strchr(p, ',')) != NULL) {
- loop_max = atoi(q+1);
- *q = '\0';
- }
- if (strstr(p, "-loopbg") == p) {
- set_env("X11VNC_LOOP_MODE_BG", "1");
- loop_sleep = 500;
- }
-
- q = strpbrk(p, "0123456789");
- if (q) {
- loop_sleep = atoi(q);
- if (loop_sleep <= 0) {
- loop_sleep = 20;
- }
- }
- }
- }
- if (loop_mode && getenv("X11VNC_LOOP_MODE") == NULL) {
-#if LIBVNCSERVER_HAVE_FORK
- char **argv2;
- int k, i = 1;
-
- set_env("X11VNC_LOOP_MODE", "1");
- argv2 = (char **) malloc((argc+1)*sizeof(char *));
-
- for (k=0; k < argc+1; k++) {
- argv2[k] = NULL;
- if (k < argc) {
- argv2[k] = argv[k];
- }
- }
- while (1) {
- int status;
- pid_t p;
- fprintf(stderr, "\n --- x11vnc loop: %d ---\n\n", i++);
- fflush(stderr);
- usleep(500 * 1000);
- if ((p = fork()) > 0) {
- fprintf(stderr, " --- x11vnc loop: waiting "
- "for: %d\n\n", p);
- wait(&status);
- } else if (p == -1) {
- fprintf(stderr, "could not fork\n");
- perror("fork");
- exit(1);
- } else {
- /* loop mode: no_external_cmds does not apply */
- execvp(argv[0], argv2);
- exit(1);
- }
-
- if (loop_max > 0 && i > loop_max) {
- fprintf(stderr, "\n --- x11vnc loop: did %d"
- " done. ---\n\n", loop_max);
- break;
- }
-
- fprintf(stderr, "\n --- x11vnc loop: sleeping %d ms "
- "---\n\n", loop_sleep);
- usleep(loop_sleep * 1000);
- }
- exit(0);
-#else
- fprintf(stderr, "fork unavailable, cannot do -loop mode\n");
- exit(1);
-#endif
- }
-}
-
-extern int appshare_main(int argc, char* argv[]);
-
-static void check_appshare_mode(int argc, char* argv[]) {
- int i;
-
- for (i=1; i < argc; i++) {
- char *p = argv[i];
- if (strstr(p, "--") == p) {
- p++;
- }
- if (strstr(p, "-appshare") == p) {
- appshare_main(argc, argv);
- exit(0);
- }
- }
-}
-
-static void store_homedir_passwd(char *file) {
- char str1[32], str2[32], *p, *h, *f;
- struct stat sbuf;
-
- str1[0] = '\0';
- str2[0] = '\0';
-
- /* storepasswd */
- if (no_external_cmds || !cmd_ok("storepasswd")) {
- fprintf(stderr, "-nocmds cannot be used with -storepasswd\n");
- exit(1);
- }
-
- fprintf(stderr, "Enter VNC password: ");
- system("stty -echo");
- if (fgets(str1, 32, stdin) == NULL) {
- perror("fgets");
- system("stty echo");
- exit(1);
- }
- fprintf(stderr, "\n");
-
- fprintf(stderr, "Verify password: ");
- if (fgets(str2, 32, stdin) == NULL) {
- perror("fgets");
- system("stty echo");
- exit(1);
- }
- fprintf(stderr, "\n");
- system("stty echo");
-
- if ((p = strchr(str1, '\n')) != NULL) {
- *p = '\0';
- }
- if ((p = strchr(str2, '\n')) != NULL) {
- *p = '\0';
- }
- if (strcmp(str1, str2)) {
- fprintf(stderr, "** passwords differ.\n");
- exit(1);
- }
- if (str1[0] == '\0') {
- fprintf(stderr, "** no password supplied.\n");
- exit(1);
- }
-
- if (file != NULL) {
- f = file;
- } else {
-
- h = getenv("HOME");
- if (! h) {
- fprintf(stderr, "** $HOME not set.\n");
- exit(1);
- }
-
- f = (char *) malloc(strlen(h) + strlen("/.vnc/passwd") + 1);
- sprintf(f, "%s/.vnc", h);
-
- if (stat(f, &sbuf) != 0) {
- if (mkdir(f, 0755) != 0) {
- fprintf(stderr, "** could not create directory %s\n", f);
- perror("mkdir");
- exit(1);
- }
- } else if (! S_ISDIR(sbuf.st_mode)) {
- fprintf(stderr, "** not a directory %s\n", f);
- exit(1);
- }
-
- sprintf(f, "%s/.vnc/passwd", h);
- }
- fprintf(stderr, "Write password to %s? [y]/n ", f);
-
- if (fgets(str2, 32, stdin) == NULL) {
- perror("fgets");
- exit(1);
- }
- if (str2[0] == 'n' || str2[0] == 'N') {
- fprintf(stderr, "not creating password.\n");
- exit(1);
- }
-
- if (rfbEncryptAndStorePasswd(str1, f) != 0) {
- fprintf(stderr, "** error creating password: %s\n", f);
- perror("storepasswd");
- exit(1);
- }
- if (stat(f, &sbuf) != 0) {
- fprintf(stderr, "** error creating password: %s\n", f);
- perror("stat");
- exit(1);
- }
- fprintf(stdout, "Password written to: %s\n", f);
- exit(0);
-}
-
-void ncache_beta_tester_message(void) {
-
-char msg[] =
-"\n"
-"******************************************************************************\n"
-"\n"
-"Hello! Exciting News!!\n"
-"\n"
-"You have been selected at random to beta-test the x11vnc '-ncache' VNC\n"
-"client-side pixel caching feature!\n"
-"\n"
-"This scheme stores pixel data offscreen on the VNC viewer side for faster\n"
-"retrieval. It should work with any VNC viewer.\n"
-"\n"
-"This method requires much testing and so we hope you will try it out and\n"
-"perhaps even report back your observations. However, if you do not want\n"
-"to test or use the feature, run x11vnc like this:\n"
-"\n"
-" x11vnc -noncache ...\n"
-"\n"
-"Your current setting is: -ncache %d\n"
-"\n"
-"The feature needs additional testing because we want to have x11vnc\n"
-"performance enhancements on by default. Otherwise, only a relative few\n"
-"would notice and use the -ncache option (e.g. the wireframe and scroll\n"
-"detection features are on by default). A couple things to note:\n"
-"\n"
-" 1) It uses a large amount of RAM (on both viewer and server sides)\n"
-"\n"
-" 2) You can actually see the cached pixel data if you scroll down\n"
-" to it in your viewer; adjust your viewer's size to hide it.\n"
-"\n"
-"More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching\n"
-"\n"
-"waiting for connections:\n"
-;
-
-char msg2[] =
-"\n"
-"******************************************************************************\n"
-"Have you tried the x11vnc '-ncache' VNC client-side pixel caching feature yet?\n"
-"\n"
-"The scheme stores pixel data offscreen on the VNC viewer side for faster\n"
-"retrieval. It should work with any VNC viewer. Try it by running:\n"
-"\n"
-" x11vnc -ncache 10 ...\n"
-"\n"
-"One can also add -ncache_cr for smooth 'copyrect' window motion.\n"
-"More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching\n"
-"\n"
-;
-
- if (raw_fb_str && !macosx_console) {
- return;
- }
- if (quiet) {
- return;
- }
- if (remote_direct) {
- return;
- }
- if (nofb) {
- return;
- }
-#ifdef NO_NCACHE
- return;
-#endif
-
- if (ncache == 0) {
- fprintf(stderr, "%s", msg2);
- ncache0 = ncache = 0;
- } else {
- fprintf(stderr, msg, ncache);
- }
-}
-
-#define SHOW_NO_PASSWORD_WARNING \
- (!got_passwd && !got_rfbauth && (!got_passwdfile || !passwd_list) \
- && !query_cmd && !remote_cmd && !unixpw && !got_gui_pw \
- && ! ssl_verify && !inetd && !terminal_services_daemon)
-
-static void do_sleepin(char *sleep) {
- int n1, n2, nt;
- double f1, f2, ft;
-
- if (strchr(sleep, '-')) {
- double s = atof(strchr(sleep, '-')+1);
- if (sscanf(sleep, "%d-%d", &n1, &n2) == 2) {
- if (n1 > n2) {
- nt = n1;
- n1 = n2;
- n2 = nt;
- }
- s = n1 + rfac() * (n2 - n1);
- } else if (sscanf(sleep, "%lf-%lf", &f1, &f2) == 2) {
- if (f1 > f2) {
- ft = f1;
- f1 = f2;
- f2 = ft;
- }
- s = f1 + rfac() * (f2 - f1);
- }
- if (getenv("DEBUG_SLEEPIN")) fprintf(stderr, "sleepin: %f secs\n", s);
- usleep( (int) (1000*1000*s) );
- } else {
- n1 = atoi(sleep);
- if (getenv("DEBUG_SLEEPIN")) fprintf(stderr, "sleepin: %d secs\n", n1);
- if (n1 > 0) {
- usleep(1000*1000*n1);
- }
- }
-}
-
-static void check_guess_auth_file(void) {
- if (!strcasecmp(auth_file, "guess")) {
- char line[4096], *cmd, *q, *disp = use_dpy ? use_dpy: "";
- FILE *p;
- int n;
- if (!program_name) {
- rfbLog("-auth guess: no program_name found.\n");
- clean_up_exit(1);
- }
- if (strpbrk(program_name, " \t\r\n")) {
- rfbLog("-auth guess: whitespace in program_name '%s'\n", program_name);
- clean_up_exit(1);
- }
- if (no_external_cmds || !cmd_ok("findauth")) {
- rfbLog("-auth guess: cannot run external commands in -nocmds mode:\n");
- clean_up_exit(1);
- }
-
- cmd = (char *)malloc(100 + strlen(program_name) + strlen(disp));
- sprintf(cmd, "%s -findauth %s -env _D_XDM=1", program_name, disp);
- p = popen(cmd, "r");
- if (!p) {
- rfbLog("-auth guess: could not run cmd '%s'\n", cmd);
- clean_up_exit(1);
- }
- memset(line, 0, sizeof(line));
- n = fread(line, 1, sizeof(line), p);
- pclose(p);
- q = strrchr(line, '\n');
- if (q) *q = '\0';
- if (!strcmp(disp, "")) {
- disp = getenv("DISPLAY");
- if (!disp) {
- disp = "unset";
- }
- }
- if (strstr(line, "XAUTHORITY=") != line && !getenv("FD_XDM")) {
- if (use_dpy == NULL || strstr(use_dpy, "cmd=FIND") == NULL) {
- if (getuid() == 0 || geteuid() == 0) {
- char *q = strstr(cmd, "_D_XDM=1");
- if (q) {
- *q = 'F';
- rfbLog("-auth guess: failed for display='%s'\n", disp);
- rfbLog("-auth guess: since we are root, retrying with FD_XDM=1\n");
- p = popen(cmd, "r");
- if (!p) {
- rfbLog("-auth guess: could not run cmd '%s'\n", cmd);
- clean_up_exit(1);
- }
- memset(line, 0, sizeof(line));
- n = fread(line, 1, sizeof(line), p);
- pclose(p);
- q = strrchr(line, '\n');
- if (q) *q = '\0';
- }
- }
- }
- }
- if (!strcmp(line, "")) {
- rfbLog("-auth guess: failed for display='%s'\n", disp);
- clean_up_exit(1);
- } else if (strstr(line, "XAUTHORITY=") != line) {
- rfbLog("-auth guess: failed. '%s' for display='%s'\n", line, disp);
- clean_up_exit(1);
- } else if (!strcmp(line, "XAUTHORITY=")) {
- rfbLog("-auth guess: using default XAUTHORITY for display='%s'\n", disp);
- q = getenv("XAUTHORITY");
- if (q) {
- *(q-2) = '_'; /* yow */
- }
- auth_file = NULL;
- } else {
- rfbLog("-auth guess: using '%s' for disp='%s'\n", line, disp);
- auth_file = strdup(line + strlen("XAUTHORITY="));
- }
- }
-}
-
-extern int is_decimal(char *);
-
-int main(int argc, char* argv[]) {
-
- int i, len, tmpi;
- int ev, er, maj, min;
- char *arg;
- int remote_sync = 0;
- char *remote_cmd = NULL;
- char *query_cmd = NULL;
- int query_retries = 0;
- double query_delay = 0.5;
- char *query_match = NULL;
- char *gui_str = NULL;
- int got_gui_pw = 0;
- int pw_loc = -1, got_passwd = 0, got_rfbauth = 0, nopw = NOPW;
- int got_viewpasswd = 0, got_localhost = 0, got_passwdfile = 0;
- int vpw_loc = -1;
- int dt = 0, bg = 0;
- int got_rfbwait = 0;
- int got_httpdir = 0, try_http = 0;
- int orig_use_xdamage = use_xdamage;
- int http_oneport_msg = 0;
- XImage *fb0 = NULL;
- int ncache_msg = 0;
- char *got_rfbport_str = NULL;
- int got_rfbport_pos = -1;
- int got_tls = 0;
- int got_inetd = 0;
- int got_noxrandr = 0;
-
- /* used to pass args we do not know about to rfbGetScreen(): */
- int argc_vnc_max = 1024;
- int argc_vnc = 1; char *argv_vnc[2048];
-
- /* check for -loop mode: */
- check_loop_mode(argc, argv, 0);
-
- /* check for -appshare mode: */
- check_appshare_mode(argc, argv);
-
- dtime0(&x11vnc_start);
-
- for (i=1; i < argc; i++) {
- if (!strcmp(argv[i], "-inetd")) {
- got_inetd = 1;
- }
- }
-
- if (!getuid() || !geteuid()) {
- started_as_root = 1;
- if (0 && !got_inetd) {
- rfbLog("getuid: %d geteuid: %d\n", getuid(), geteuid());
- }
-
- /* check for '-users =bob' */
- immediate_switch_user(argc, argv);
- }
-
- for (i=0; i < 2048; i++) {
- argv_vnc[i] = NULL;
- }
-
- argv_vnc[0] = strdup(argv[0]);
- program_name = strdup(argv[0]);
- program_pid = (int) getpid();
-
- solid_default = strdup(solid_default); /* for freeing with -R */
-
- len = 0;
- for (i=1; i < argc; i++) {
- len += strlen(argv[i]) + 4 + 1;
- }
- program_cmdline = (char *) malloc(len+1);
- program_cmdline[0] = '\0';
- for (i=1; i < argc; i++) {
- char *s = argv[i];
- if (program_cmdline[0]) {
- strcat(program_cmdline, " ");
- }
- if (*s == '-') {
- strcat(program_cmdline, s);
- } else {
- strcat(program_cmdline, "{{");
- strcat(program_cmdline, s);
- strcat(program_cmdline, "}}");
- }
- }
-
- for (i=0; i<ICON_MODE_SOCKS; i++) {
- icon_mode_socks[i] = -1;
- }
-
- check_rcfile(argc, argv);
- /* kludge for the new array argv2 set in check_rcfile() */
-# define argc argc2
-# define argv argv2
-
-# define CHECK_ARGC if (i >= argc-1) { \
- fprintf(stderr, "not enough arguments for: %s\n", arg); \
- exit(1); \
- }
-
- /*
- * do a quick check for parameters that apply to "utility"
- * commands, i.e. ones that do not run the server.
- */
- for (i=1; i < argc; i++) {
- arg = argv[i];
- if (strstr(arg, "--") == arg) {
- arg++;
- }
- if (!strcmp(arg, "-ssldir")) {
- CHECK_ARGC
- ssl_certs_dir = strdup(argv[++i]);
- }
- }
-
- /*
- * do a quick check for -env parameters
- */
- for (i=1; i < argc; i++) {
- char *p, *q;
- arg = argv[i];
- if (strstr(arg, "--") == arg) {
- arg++;
- }
- if (!strcmp(arg, "-env")) {
- CHECK_ARGC
- p = strdup(argv[++i]);
- q = strchr(p, '=');
- if (! q) {
- fprintf(stderr, "no -env '=' found: %s\n", p);
- exit(1);
- } else {
- *q = '\0';
- }
- set_env(p, q+1);
- free(p);
- }
- }
-
- for (i=1; i < argc; i++) {
- /* quick-n-dirty --option handling. */
- arg = argv[i];
- if (strstr(arg, "--") == arg) {
- arg++;
- }
-
- if (!strcmp(arg, "-display")) {
- CHECK_ARGC
- use_dpy = strdup(argv[++i]);
- if (strstr(use_dpy, "WAIT")) {
- extern char find_display[];
- extern char create_display[];
- if (strstr(use_dpy, "cmd=FINDDISPLAY-print")) {
- fprintf(stdout, "%s", find_display);
- exit(0);
- }
- if (strstr(use_dpy, "cmd=FINDCREATEDISPLAY-print")) {
- fprintf(stdout, "%s", create_display);
- exit(0);
- }
- }
- continue;
- }
- if (!strcmp(arg, "-reopen")) {
- char *str = getenv("X11VNC_REOPEN_DISPLAY");
- if (str) {
- int rmax = atoi(str);
- if (rmax > 0) {
- set_env("X11VNC_REOPEN_DISPLAY", str);
- }
- } else {
- set_env("X11VNC_REOPEN_DISPLAY", "1");
- }
- continue;
- }
- if (!strcmp(arg, "-find")) {
- use_dpy = strdup("WAIT:cmd=FINDDISPLAY");
- continue;
- }
- if (!strcmp(arg, "-finddpy") || strstr(arg, "-listdpy") == arg) {
- int ic = 0;
- use_dpy = strdup("WAIT:cmd=FINDDISPLAY-run");
- if (argc > i+1) {
- set_env("X11VNC_USER", argv[i+1]);
- fprintf(stdout, "X11VNC_USER=%s\n", getenv("X11VNC_USER"));
- }
- if (strstr(arg, "-listdpy") == arg) {
- set_env("FIND_DISPLAY_ALL", "1");
- }
- wait_for_client(&ic, NULL, 0);
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-findauth")) {
- got_findauth = 1;
- if (argc > i+1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- set_env("FINDAUTH_DISPLAY", argv[i+1]);
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-create")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb");
- continue;
- }
- if (!strcmp(arg, "-create_xsrv")) {
- CHECK_ARGC
- use_dpy = (char *) malloc(strlen(argv[i+1])+100);
- sprintf(use_dpy, "WAIT:cmd=FINDCREATEDISPLAY-%s", argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-xdummy")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy");
- continue;
- }
- if (!strcmp(arg, "-xdummy_xvfb")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb");
- continue;
- }
- if (!strcmp(arg, "-xvnc")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvnc");
- continue;
- }
- if (!strcmp(arg, "-xvnc_redirect")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvnc.redirect");
- continue;
- }
- if (!strcmp(arg, "-redirect")) {
- char *q, *t, *t0 = "WAIT:cmd=FINDDISPLAY-vnc_redirect";
- CHECK_ARGC
- t = (char *) malloc(strlen(t0) + strlen(argv[++i]) + 2);
- q = strrchr(argv[i], ':');
- if (q) *q = ' ';
- sprintf(t, "%s=%s", t0, argv[i]);
- use_dpy = t;
- continue;
- }
- if (!strcmp(arg, "-auth") || !strcmp(arg, "-xauth")) {
- CHECK_ARGC
- auth_file = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-N")) {
- display_N = 1;
- continue;
- }
- if (!strcmp(arg, "-autoport")) {
- CHECK_ARGC
- auto_port = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-reflect")) {
- CHECK_ARGC
- raw_fb_str = (char *) malloc(4 + strlen(argv[i+1]) + 1);
- sprintf(raw_fb_str, "vnc:%s", argv[++i]);
- shared = 1;
- continue;
- }
- if (!strcmp(arg, "-tsd")) {
- CHECK_ARGC
- terminal_services_daemon = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-id") || !strcmp(arg, "-sid")) {
- CHECK_ARGC
- if (!strcmp(arg, "-sid")) {
- rootshift = 1;
- } else {
- rootshift = 0;
- }
- i++;
- if (!strcmp("pick", argv[i])) {
- if (started_as_root) {
- fprintf(stderr, "unsafe: %s pick\n",
- arg);
- exit(1);
- } else if (! pick_windowid(&subwin)) {
- fprintf(stderr, "invalid %s pick\n",
- arg);
- exit(1);
- }
- } else if (! scan_hexdec(argv[i], &subwin)) {
- fprintf(stderr, "invalid %s arg: %s\n", arg,
- argv[i]);
- exit(1);
- }
- continue;
- }
- if (!strcmp(arg, "-waitmapped")) {
- subwin_wait_mapped = 1;
- continue;
- }
- if (!strcmp(arg, "-clip")) {
- CHECK_ARGC
- clip_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-flashcmap")) {
- flash_cmap = 1;
- continue;
- }
- if (!strcmp(arg, "-shiftcmap")) {
- CHECK_ARGC
- shift_cmap = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-notruecolor")) {
- force_indexed_color = 1;
- continue;
- }
- if (!strcmp(arg, "-advertise_truecolor")) {
- advertise_truecolor = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- if (strstr(s, "reset")) {
- advertise_truecolor_reset = 1;
- }
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-overlay")) {
- overlay = 1;
- continue;
- }
- if (!strcmp(arg, "-overlay_nocursor")) {
- overlay = 1;
- overlay_cursor = 0;
- continue;
- }
- if (!strcmp(arg, "-overlay_yescursor")) {
- overlay = 1;
- overlay_cursor = 2;
- continue;
- }
- if (!strcmp(arg, "-8to24")) {
-#if !SKIP_8TO24
- cmap8to24 = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- cmap8to24_str = strdup(s);
- i++;
- }
- }
-#endif
- continue;
- }
- if (!strcmp(arg, "-24to32")) {
- xform24to32 = 1;
- continue;
- }
- if (!strcmp(arg, "-visual")) {
- CHECK_ARGC
- visual_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scale")) {
- CHECK_ARGC
- scale_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-geometry")) {
- CHECK_ARGC
- scale_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scale_cursor")) {
- CHECK_ARGC
- scale_cursor_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-viewonly")) {
- view_only = 1;
- continue;
- }
- if (!strcmp(arg, "-noviewonly")) {
- view_only = 0;
- got_noviewonly = 1;
- continue;
- }
- if (!strcmp(arg, "-shared")) {
- shared = 1;
- continue;
- }
- if (!strcmp(arg, "-noshared")) {
- shared = 0;
- continue;
- }
- if (!strcmp(arg, "-once")) {
- connect_once = 1;
- got_connect_once = 1;
- continue;
- }
- if (!strcmp(arg, "-many") || !strcmp(arg, "-forever")) {
- connect_once = 0;
- continue;
- }
- if (strstr(arg, "-loop") == arg) {
- ; /* handled above */
- continue;
- }
- if (strstr(arg, "-appshare") == arg) {
- ; /* handled above */
- continue;
- }
- if (strstr(arg, "-freeze_when_obscured") == arg) {
- freeze_when_obscured = 1;
- continue;
- }
- if (!strcmp(arg, "-timeout")) {
- CHECK_ARGC
- first_conn_timeout = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-sleepin")) {
- CHECK_ARGC
- do_sleepin(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-users")) {
- CHECK_ARGC
- users_list = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-inetd")) {
- inetd = 1;
- continue;
- }
- if (!strcmp(arg, "-notightfilexfer")) {
- tightfilexfer = 0;
- continue;
- }
- if (!strcmp(arg, "-tightfilexfer")) {
- tightfilexfer = 1;
- continue;
- }
- if (!strcmp(arg, "-http")) {
- try_http = 1;
- continue;
- }
- if (!strcmp(arg, "-http_ssl")) {
- try_http = 1;
- http_ssl = 1;
- got_tls++;
- continue;
- }
- if (!strcmp(arg, "-avahi") || !strcmp(arg, "-mdns") || !strcmp(arg, "-zeroconf")) {
- avahi = 1;
- continue;
- }
- if (!strcmp(arg, "-connect") ||
- !strcmp(arg, "-connect_or_exit") ||
- !strcmp(arg, "-coe")) {
- CHECK_ARGC
- if (!strcmp(arg, "-connect_or_exit")) {
- connect_or_exit = 1;
- } else if (!strcmp(arg, "-coe")) {
- connect_or_exit = 1;
- }
- if (strchr(argv[++i], '/') && !strstr(argv[i], "repeater://")) {
- struct stat sb;
- client_connect_file = strdup(argv[i]);
- if (stat(client_connect_file, &sb) != 0) {
- FILE* f = fopen(client_connect_file, "w");
- if (f != NULL) fclose(f);
- }
- } else {
- client_connect = strdup(argv[i]);
- }
- continue;
- }
- if (!strcmp(arg, "-proxy")) {
- CHECK_ARGC
- connect_proxy = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-vncconnect")) {
- vnc_connect = 1;
- continue;
- }
- if (!strcmp(arg, "-novncconnect")) {
- vnc_connect = 0;
- continue;
- }
- if (!strcmp(arg, "-allow")) {
- CHECK_ARGC
- allow_list = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-localhost")) {
- allow_list = strdup("127.0.0.1");
- got_localhost = 1;
- continue;
- }
- if (!strcmp(arg, "-unixsock")) {
- CHECK_ARGC
- unix_sock = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-listen6")) {
- CHECK_ARGC
-#if X11VNC_IPV6
- listen_str6 = strdup(argv[++i]);
-#else
- ++i;
-#endif
- continue;
- }
- if (!strcmp(arg, "-nolookup")) {
- host_lookup = 0;
- continue;
- }
- if (!strcmp(arg, "-6")) {
-#if X11VNC_IPV6
- ipv6_listen = 1;
- got_ipv6_listen = 1;
-#endif
- continue;
- }
- if (!strcmp(arg, "-no6")) {
-#if X11VNC_IPV6
- ipv6_listen = 0;
- got_ipv6_listen = 0;
-#endif
- continue;
- }
- if (!strcmp(arg, "-noipv6")) {
- noipv6 = 1;
- continue;
- }
- if (!strcmp(arg, "-noipv4")) {
- noipv4 = 1;
- continue;
- }
-
- if (!strcmp(arg, "-input")) {
- CHECK_ARGC
- allowed_input_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-grabkbd")) {
- grab_kbd = 1;
- continue;
- }
- if (!strcmp(arg, "-grabptr")) {
- grab_ptr = 1;
- continue;
- }
- if (!strcmp(arg, "-ungrabboth")) {
- ungrab_both = 1;
- continue;
- }
- if (!strcmp(arg, "-grabalways")) {
- grab_kbd = 1;
- grab_ptr = 1;
- grab_always = 1;
- continue;
- }
-#ifdef ENABLE_GRABLOCAL
- if (!strcmp(arg, "-grablocal")) {
- CHECK_ARGC
- grab_local = atoi(argv[++i]);
- continue;
- }
-#endif
- if (!strcmp(arg, "-viewpasswd")) {
- vpw_loc = i;
- CHECK_ARGC
- viewonly_passwd = strdup(argv[++i]);
- got_viewpasswd = 1;
- continue;
- }
- if (!strcmp(arg, "-passwdfile")) {
- CHECK_ARGC
- passwdfile = strdup(argv[++i]);
- got_passwdfile = 1;
- continue;
- }
- if (!strcmp(arg, "-svc") || !strcmp(arg, "-service")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb");
- unixpw = 1;
- users_list = strdup("unixpw=");
- use_openssl = 1;
- openssl_pem = strdup("SAVE");
- continue;
- }
- if (!strcmp(arg, "-svc_xdummy")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy");
- unixpw = 1;
- users_list = strdup("unixpw=");
- use_openssl = 1;
- openssl_pem = strdup("SAVE");
- continue;
- }
- if (!strcmp(arg, "-svc_xdummy_xvfb")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb");
- unixpw = 1;
- users_list = strdup("unixpw=");
- use_openssl = 1;
- openssl_pem = strdup("SAVE");
- continue;
- }
- if (!strcmp(arg, "-svc_xvnc")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvnc");
- unixpw = 1;
- users_list = strdup("unixpw=");
- use_openssl = 1;
- openssl_pem = strdup("SAVE");
- continue;
- }
- if (!strcmp(arg, "-xdmsvc") || !strcmp(arg, "-xdm_service")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp");
- unixpw = 1;
- users_list = strdup("unixpw=");
- use_openssl = 1;
- openssl_pem = strdup("SAVE");
- continue;
- }
- if (!strcmp(arg, "-sshxdmsvc")) {
- use_dpy = strdup("WAIT:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp");
- allow_list = strdup("127.0.0.1");
- got_localhost = 1;
- continue;
- }
- if (!strcmp(arg, "-unixpw_system_greeter")) {
- unixpw_system_greeter = 1;
- continue;
- }
- if (!strcmp(arg, "-unixpw_cmd")
- || !strcmp(arg, "-unixpw_cmd_unsafe")) {
- CHECK_ARGC
- unixpw_cmd = strdup(argv[++i]);
- unixpw = 1;
- if (strstr(arg, "_unsafe")) {
- /* hidden option for testing. */
- set_env("UNIXPW_DISABLE_SSL", "1");
- set_env("UNIXPW_DISABLE_LOCALHOST", "1");
- }
- continue;
- }
- if (strstr(arg, "-unixpw") == arg) {
- unixpw = 1;
- if (strstr(arg, "-unixpw_nis")) {
- unixpw_nis = 1;
- }
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- unixpw_list = strdup(s);
- i++;
- }
- if (s[0] == '%') {
- unixpw_list = NULL;
- quick_pw(s);
- exit(2);
- }
- }
- if (strstr(arg, "_unsafe")) {
- /* hidden option for testing. */
- set_env("UNIXPW_DISABLE_SSL", "1");
- set_env("UNIXPW_DISABLE_LOCALHOST", "1");
- }
- continue;
- }
- if (strstr(arg, "-nounixpw") == arg) {
- unixpw = 0;
- unixpw_nis = 0;
- if (unixpw_list) {
- unixpw_list = NULL;
- }
- if (unixpw_cmd) {
- unixpw_cmd = NULL;
- }
- continue;
- }
- if (!strcmp(arg, "-vencrypt")) {
- char *s;
- CHECK_ARGC
- s = strdup(argv[++i]);
- got_tls++;
- if (strstr(s, "never")) {
- vencrypt_mode = VENCRYPT_NONE;
- } else if (strstr(s, "support")) {
- vencrypt_mode = VENCRYPT_SUPPORT;
- } else if (strstr(s, "only")) {
- vencrypt_mode = VENCRYPT_SOLE;
- } else if (strstr(s, "force")) {
- vencrypt_mode = VENCRYPT_FORCE;
- } else {
- fprintf(stderr, "invalid %s arg: %s\n", arg, s);
- exit(1);
- }
- if (strstr(s, "nodh")) {
- vencrypt_kx = VENCRYPT_NODH;
- } else if (strstr(s, "nox509")) {
- vencrypt_kx = VENCRYPT_NOX509;
- }
- if (strstr(s, "newdh")) {
- create_fresh_dhparams = 1;
- }
- if (strstr(s, "noplain")) {
- vencrypt_enable_plain_login = 0;
- } else if (strstr(s, "plain")) {
- vencrypt_enable_plain_login = 1;
- }
- free(s);
- continue;
- }
- if (!strcmp(arg, "-anontls")) {
- char *s;
- CHECK_ARGC
- s = strdup(argv[++i]);
- got_tls++;
- if (strstr(s, "never")) {
- anontls_mode = ANONTLS_NONE;
- } else if (strstr(s, "support")) {
- anontls_mode = ANONTLS_SUPPORT;
- } else if (strstr(s, "only")) {
- anontls_mode = ANONTLS_SOLE;
- } else if (strstr(s, "force")) {
- anontls_mode = ANONTLS_FORCE;
- } else {
- fprintf(stderr, "invalid %s arg: %s\n", arg, s);
- exit(1);
- }
- if (strstr(s, "newdh")) {
- create_fresh_dhparams = 1;
- }
- free(s);
- continue;
- }
- if (!strcmp(arg, "-sslonly")) {
- vencrypt_mode = VENCRYPT_NONE;
- anontls_mode = ANONTLS_NONE;
- got_tls++;
- continue;
- }
- if (!strcmp(arg, "-dhparams")) {
- CHECK_ARGC
- dhparams_file = strdup(argv[++i]);
- got_tls++;
- continue;
- }
- if (!strcmp(arg, "-nossl")) {
- use_openssl = 0;
- openssl_pem = NULL;
- got_tls = -1000;
- continue;
- }
- if (!strcmp(arg, "-ssl")) {
- use_openssl = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- if (!strcmp(s, "ADH")) {
- openssl_pem = strdup("ANON");
- } else if (!strcmp(s, "ANONDH")) {
- openssl_pem = strdup("ANON");
- } else if (!strcmp(s, "TMP")) {
- openssl_pem = NULL;
- } else {
- openssl_pem = strdup(s);
- }
- i++;
- } else {
- openssl_pem = strdup("SAVE");
- }
- } else {
- openssl_pem = strdup("SAVE");
- }
- continue;
- }
- if (!strcmp(arg, "-enc")) {
- use_openssl = 1;
- CHECK_ARGC
- enc_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-http_oneport")) {
- http_oneport_msg = 1;
- use_openssl = 1;
- enc_str = strdup("none");
- continue;
- }
- if (!strcmp(arg, "-ssltimeout")) {
- CHECK_ARGC
- ssl_timeout_secs = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-sslnofail")) {
- ssl_no_fail = 1;
- continue;
- }
- if (!strcmp(arg, "-ssldir")) {
- CHECK_ARGC
- ssl_certs_dir = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-sslverify")) {
- CHECK_ARGC
- ssl_verify = strdup(argv[++i]);
- got_tls++;
- continue;
- }
- if (!strcmp(arg, "-sslCRL")) {
- CHECK_ARGC
- ssl_crl = strdup(argv[++i]);
- got_tls++;
- continue;
- }
- if (!strcmp(arg, "-sslGenCA")) {
- char *cdir = NULL;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- cdir = strdup(s);
- i++;
- }
- }
- sslGenCA(cdir);
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-sslGenCert")) {
- char *ty, *nm = NULL;
- if (i >= argc-1) {
- fprintf(stderr, "Must be:\n");
- fprintf(stderr, " x11vnc -sslGenCert server ...\n");
- fprintf(stderr, "or x11vnc -sslGenCert client ...\n");
- exit(1);
- }
- ty = argv[i+1];
- if (strcmp(ty, "server") && strcmp(ty, "client")) {
- fprintf(stderr, "Must be:\n");
- fprintf(stderr, " x11vnc -sslGenCert server ...\n");
- fprintf(stderr, "or x11vnc -sslGenCert client ...\n");
- exit(1);
- }
- if (i < argc-2) {
- nm = argv[i+2];
- }
- sslGenCert(ty, nm);
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-sslEncKey")) {
- if (i < argc-1) {
- char *s = argv[i+1];
- sslEncKey(s, 0);
- }
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-sslCertInfo")) {
- if (i < argc-1) {
- char *s = argv[i+1];
- sslEncKey(s, 1);
- }
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-sslDelCert")) {
- if (i < argc-1) {
- char *s = argv[i+1];
- sslEncKey(s, 2);
- }
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-sslScripts")) {
- sslScripts();
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-stunnel")) {
- use_stunnel = 1;
- got_tls = -1000;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- if (!strcmp(s, "TMP")) {
- stunnel_pem = NULL;
- } else {
- stunnel_pem = strdup(s);
- }
- i++;
- } else {
- stunnel_pem = strdup("SAVE");
- }
- } else {
- stunnel_pem = strdup("SAVE");
- }
- continue;
- }
- if (!strcmp(arg, "-stunnel3")) {
- use_stunnel = 3;
- got_tls = -1000;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- if (!strcmp(s, "TMP")) {
- stunnel_pem = NULL;
- } else {
- stunnel_pem = strdup(s);
- }
- i++;
- } else {
- stunnel_pem = strdup("SAVE");
- }
- } else {
- stunnel_pem = strdup("SAVE");
- }
- continue;
- }
- if (!strcmp(arg, "-https")) {
- https_port_num = 0;
- try_http = 1;
- got_tls++;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- https_port_num = atoi(s);
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-httpsredir")) {
- https_port_redir = -1;
- got_tls++;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- https_port_redir = atoi(s);
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-nopw")) {
- nopw = 1;
- continue;
- }
- if (!strcmp(arg, "-ssh")) {
- CHECK_ARGC
- ssh_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-usepw")) {
- usepw = 1;
- continue;
- }
- if (!strcmp(arg, "-storepasswd")) {
- if (argc == i+1) {
- store_homedir_passwd(NULL);
- exit(0);
- }
- if (argc == i+2) {
- store_homedir_passwd(argv[i+1]);
- exit(0);
- }
- if (argc >= i+4 || rfbEncryptAndStorePasswd(argv[i+1],
- argv[i+2]) != 0) {
- perror("storepasswd");
- fprintf(stderr, "-storepasswd failed for file: %s\n",
- argv[i+2]);
- exit(1);
- } else {
- fprintf(stderr, "stored passwd in file: %s\n",
- argv[i+2]);
- exit(0);
- }
- continue;
- }
- if (!strcmp(arg, "-showrfbauth")) {
- if (argc >= i+2) {
- char *f = argv[i+1];
- char *s = rfbDecryptPasswdFromFile(f);
- if (!s) {
- perror("showrfbauth");
- fprintf(stderr, "rfbDecryptPasswdFromFile failed: %s\n", f);
- exit(1);
- }
- fprintf(stdout, "rfbDecryptPasswdFromFile file: %s\n", f);
- fprintf(stdout, "rfbDecryptPasswdFromFile pass: %s\n", s);
- }
- exit(0);
- }
- if (!strcmp(arg, "-accept")) {
- CHECK_ARGC
- accept_cmd = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-afteraccept")) {
- CHECK_ARGC
- afteraccept_cmd = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-gone")) {
- CHECK_ARGC
- gone_cmd = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-noshm")) {
- using_shm = 0;
- continue;
- }
- if (!strcmp(arg, "-flipbyteorder")) {
- flip_byte_order = 1;
- continue;
- }
- if (!strcmp(arg, "-onetile")) {
- single_copytile = 1;
- continue;
- }
- if (!strcmp(arg, "-solid")) {
- use_solid_bg = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- solid_str = strdup(s);
- i++;
- }
- }
- if (! solid_str) {
- solid_str = strdup(solid_default);
- }
- continue;
- }
- if (!strcmp(arg, "-blackout")) {
- CHECK_ARGC
- blackout_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-xinerama")) {
- xinerama = 1;
- continue;
- }
- if (!strcmp(arg, "-noxinerama")) {
- xinerama = 0;
- continue;
- }
- if (!strcmp(arg, "-xtrap")) {
- xtrap_input = 1;
- continue;
- }
- if (!strcmp(arg, "-xrandr")) {
- xrandr = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (known_xrandr_mode(s)) {
- xrandr_mode = strdup(s);
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-noxrandr")) {
- xrandr = 0;
- xrandr_maybe = 0;
- got_noxrandr = 1;
- continue;
- }
- if (!strcmp(arg, "-rotate")) {
- CHECK_ARGC
- rotating_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-padgeom")
- || !strcmp(arg, "-padgeometry")) {
- CHECK_ARGC
- pad_geometry = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-o") || !strcmp(arg, "-logfile")) {
- CHECK_ARGC
- logfile_append = 0;
- logfile = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-oa") || !strcmp(arg, "-logappend")) {
- CHECK_ARGC
- logfile_append = 1;
- logfile = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-flag")) {
- CHECK_ARGC
- flagfile = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-rmflag")) {
- CHECK_ARGC
- rm_flagfile = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-rc")) {
- i++; /* done above */
- continue;
- }
- if (!strcmp(arg, "-norc")) {
- ; /* done above */
- continue;
- }
- if (!strcmp(arg, "-env")) {
- i++; /* done above */
- continue;
- }
- if (!strcmp(arg, "-prog")) {
- CHECK_ARGC
- if (program_name) {
- free(program_name);
- }
- program_name = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-h") || !strcmp(arg, "-help")) {
- print_help(0);
- continue;
- }
- if (!strcmp(arg, "-?") || !strcmp(arg, "-opts")) {
- print_help(1);
- continue;
- }
- if (!strcmp(arg, "-V") || !strcmp(arg, "-version")) {
- fprintf(stdout, "x11vnc: %s\n", lastmod);
- exit(0);
- continue;
- }
- if (!strcmp(arg, "-license") ||
- !strcmp(arg, "-copying") || !strcmp(arg, "-warranty")) {
- print_license();
- continue;
- }
- if (!strcmp(arg, "-dbg")) {
- crash_debug = 1;
- continue;
- }
- if (!strcmp(arg, "-nodbg")) {
- crash_debug = 0;
- continue;
- }
- if (!strcmp(arg, "-q") || !strcmp(arg, "-quiet")) {
- quiet = 1;
- continue;
- }
- if (!strcmp(arg, "-noquiet")) {
- quiet = 0;
- continue;
- }
- if (!strcmp(arg, "-v") || !strcmp(arg, "-verbose")) {
- verbose = 1;
- continue;
- }
- if (!strcmp(arg, "-bg") || !strcmp(arg, "-background")) {
-#if LIBVNCSERVER_HAVE_SETSID
- bg = 1;
- opts_bg = bg;
-#else
- if (!got_inetd) {
- fprintf(stderr, "warning: -bg mode not supported.\n");
- }
-#endif
- continue;
- }
- if (!strcmp(arg, "-modtweak")) {
- use_modifier_tweak = 1;
- continue;
- }
- if (!strcmp(arg, "-nomodtweak")) {
- use_modifier_tweak = 0;
- got_nomodtweak = 1;
- continue;
- }
- if (!strcmp(arg, "-isolevel3")) {
- use_iso_level3 = 1;
- continue;
- }
- if (!strcmp(arg, "-xkb")) {
- use_modifier_tweak = 1;
- use_xkb_modtweak = 1;
- continue;
- }
- if (!strcmp(arg, "-noxkb")) {
- use_xkb_modtweak = 0;
- got_noxkb = 1;
- continue;
- }
- if (!strcmp(arg, "-capslock")) {
- watch_capslock = 1;
- continue;
- }
- if (!strcmp(arg, "-skip_lockkeys")) {
- skip_lockkeys = 1;
- continue;
- }
- if (!strcmp(arg, "-noskip_lockkeys")) {
- skip_lockkeys = 0;
- continue;
- }
- if (!strcmp(arg, "-xkbcompat")) {
- xkbcompat = 1;
- continue;
- }
- if (!strcmp(arg, "-skip_keycodes")) {
- CHECK_ARGC
- skip_keycodes = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-sloppy_keys")) {
- sloppy_keys++;
- continue;
- }
- if (!strcmp(arg, "-skip_dups")) {
- skip_duplicate_key_events = 1;
- continue;
- }
- if (!strcmp(arg, "-noskip_dups")) {
- skip_duplicate_key_events = 0;
- continue;
- }
- if (!strcmp(arg, "-add_keysyms")) {
- add_keysyms++;
- continue;
- }
- if (!strcmp(arg, "-noadd_keysyms")) {
- add_keysyms = 0;
- continue;
- }
- if (!strcmp(arg, "-clear_mods")) {
- clear_mods = 1;
- continue;
- }
- if (!strcmp(arg, "-clear_keys")) {
- clear_mods = 2;
- continue;
- }
- if (!strcmp(arg, "-clear_all")) {
- clear_mods = 3;
- continue;
- }
- if (!strcmp(arg, "-remap")) {
- CHECK_ARGC
- remap_file = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-norepeat")) {
- no_autorepeat = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (*s == '-') {
- s++;
- }
- if (isdigit((unsigned char) (*s))) {
- no_repeat_countdown = atoi(argv[++i]);
- }
- }
- continue;
- }
- if (!strcmp(arg, "-repeat")) {
- no_autorepeat = 0;
- continue;
- }
- if (!strcmp(arg, "-nofb")) {
- nofb = 1;
- continue;
- }
- if (!strcmp(arg, "-nobell")) {
- watch_bell = 0;
- sound_bell = 0;
- continue;
- }
- if (!strcmp(arg, "-nosel")) {
- watch_selection = 0;
- watch_primary = 0;
- watch_clipboard = 0;
- continue;
- }
- if (!strcmp(arg, "-noprimary")) {
- watch_primary = 0;
- continue;
- }
- if (!strcmp(arg, "-nosetprimary")) {
- set_primary = 0;
- continue;
- }
- if (!strcmp(arg, "-noclipboard")) {
- watch_clipboard = 0;
- continue;
- }
- if (!strcmp(arg, "-nosetclipboard")) {
- set_clipboard = 0;
- continue;
- }
- if (!strcmp(arg, "-seldir")) {
- CHECK_ARGC
- sel_direction = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-cursor")) {
- show_cursor = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (known_cursors_mode(s)) {
- multiple_cursors_mode = strdup(s);
- i++;
- if (!strcmp(s, "none")) {
- show_cursor = 0;
- }
- }
- }
- continue;
- }
- if (!strcmp(arg, "-nocursor")) {
- multiple_cursors_mode = strdup("none");
- show_cursor = 0;
- continue;
- }
- if (!strcmp(arg, "-cursor_drag")) {
- cursor_drag_changes = 1;
- continue;
- }
- if (!strcmp(arg, "-nocursor_drag")) {
- cursor_drag_changes = 0;
- continue;
- }
- if (!strcmp(arg, "-arrow")) {
- CHECK_ARGC
- alt_arrow = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-xfixes")) {
- use_xfixes = 1;
- continue;
- }
- if (!strcmp(arg, "-noxfixes")) {
- use_xfixes = 0;
- continue;
- }
- if (!strcmp(arg, "-alphacut")) {
- CHECK_ARGC
- alpha_threshold = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-alphafrac")) {
- CHECK_ARGC
- alpha_frac = atof(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-alpharemove")) {
- alpha_remove = 1;
- continue;
- }
- if (!strcmp(arg, "-noalphablend")) {
- alpha_blend = 0;
- continue;
- }
- if (!strcmp(arg, "-nocursorshape")) {
- cursor_shape_updates = 0;
- continue;
- }
- if (!strcmp(arg, "-cursorpos")) {
- cursor_pos_updates = 1;
- got_cursorpos = 1;
- continue;
- }
- if (!strcmp(arg, "-nocursorpos")) {
- cursor_pos_updates = 0;
- continue;
- }
- if (!strcmp(arg, "-xwarppointer")) {
- use_xwarppointer = 1;
- continue;
- }
- if (!strcmp(arg, "-noxwarppointer")) {
- use_xwarppointer = 0;
- got_noxwarppointer = 1;
- continue;
- }
- if (!strcmp(arg, "-always_inject")) {
- always_inject = 1;
- continue;
- }
- if (!strcmp(arg, "-buttonmap")) {
- CHECK_ARGC
- pointer_remap = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-nodragging")) {
- show_dragging = 0;
- continue;
- }
-#ifndef NO_NCACHE
- if (!strcmp(arg, "-ncache") || !strcmp(arg, "-nc")) {
- if (i < argc-1) {
- char *s = argv[i+1];
- if (s[0] != '-') {
- ncache = atoi(s);
- i++;
- } else {
- ncache = ncache_default;
- }
- } else {
- ncache = ncache_default;
- }
- if (ncache % 2 != 0) {
- ncache++;
- }
- continue;
- }
- if (!strcmp(arg, "-noncache") || !strcmp(arg, "-nonc")) {
- ncache = 0;
- continue;
- }
- if (!strcmp(arg, "-ncache_cr") || !strcmp(arg, "-nc_cr")) {
- ncache_copyrect = 1;
- continue;
- }
- if (!strcmp(arg, "-ncache_no_moveraise") || !strcmp(arg, "-nc_no_moveraise")) {
- ncache_wf_raises = 1;
- continue;
- }
- if (!strcmp(arg, "-ncache_no_dtchange") || !strcmp(arg, "-nc_no_dtchange")) {
- ncache_dt_change = 0;
- continue;
- }
- if (!strcmp(arg, "-ncache_no_rootpixmap") || !strcmp(arg, "-nc_no_rootpixmap")) {
- ncache_xrootpmap = 0;
- continue;
- }
- if (!strcmp(arg, "-ncache_keep_anims") || !strcmp(arg, "-nc_keep_anims")) {
- ncache_keep_anims = 1;
- continue;
- }
- if (!strcmp(arg, "-ncache_old_wm") || !strcmp(arg, "-nc_old_wm")) {
- ncache_old_wm = 1;
- continue;
- }
- if (!strcmp(arg, "-ncache_pad") || !strcmp(arg, "-nc_pad")) {
- CHECK_ARGC
- ncache_pad = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-debug_ncache")) {
- ncdb++;
- continue;
- }
-#endif
- if (!strcmp(arg, "-wireframe")
- || !strcmp(arg, "-wf")) {
- wireframe = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (*s != '-') {
- wireframe_str = strdup(argv[++i]);
- }
- }
- continue;
- }
- if (!strcmp(arg, "-nowireframe")
- || !strcmp(arg, "-nowf")) {
- wireframe = 0;
- continue;
- }
- if (!strcmp(arg, "-nowireframelocal")
- || !strcmp(arg, "-nowfl")) {
- wireframe_local = 0;
- continue;
- }
- if (!strcmp(arg, "-wirecopyrect")
- || !strcmp(arg, "-wcr")) {
- CHECK_ARGC
- set_wirecopyrect_mode(argv[++i]);
- got_wirecopyrect = 1;
- continue;
- }
- if (!strcmp(arg, "-nowirecopyrect")
- || !strcmp(arg, "-nowcr")) {
- set_wirecopyrect_mode("never");
- continue;
- }
- if (!strcmp(arg, "-debug_wireframe")
- || !strcmp(arg, "-dwf")) {
- debug_wireframe++;
- continue;
- }
- if (!strcmp(arg, "-scrollcopyrect")
- || !strcmp(arg, "-scr")) {
- CHECK_ARGC
- set_scrollcopyrect_mode(argv[++i]);
- got_scrollcopyrect = 1;
- continue;
- }
- if (!strcmp(arg, "-noscrollcopyrect")
- || !strcmp(arg, "-noscr")) {
- set_scrollcopyrect_mode("never");
- continue;
- }
- if (!strcmp(arg, "-scr_area")) {
- int tn;
- CHECK_ARGC
- tn = atoi(argv[++i]);
- if (tn >= 0) {
- scrollcopyrect_min_area = tn;
- }
- continue;
- }
- if (!strcmp(arg, "-scr_skip")) {
- CHECK_ARGC
- scroll_skip_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scr_inc")) {
- CHECK_ARGC
- scroll_good_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scr_keys")) {
- CHECK_ARGC
- scroll_key_list_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scr_term")) {
- CHECK_ARGC
- scroll_term_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scr_keyrepeat")) {
- CHECK_ARGC
- max_keyrepeat_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-scr_parms")) {
- CHECK_ARGC
- scroll_copyrect_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-fixscreen")) {
- CHECK_ARGC
- screen_fixup_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-debug_scroll")
- || !strcmp(arg, "-ds")) {
- debug_scroll++;
- continue;
- }
- if (!strcmp(arg, "-noxrecord")) {
- noxrecord = 1;
- continue;
- }
- if (!strcmp(arg, "-pointer_mode")
- || !strcmp(arg, "-pm")) {
- char *p, *s;
- CHECK_ARGC
- s = argv[++i];
- if ((p = strchr(s, ':')) != NULL) {
- ui_skip = atoi(p+1);
- if (! ui_skip) ui_skip = 1;
- *p = '\0';
- }
- if (atoi(s) < 1 || atoi(s) > pointer_mode_max) {
- if (!got_inetd) {
- rfbLog("pointer_mode out of range 1-%d: %d\n",
- pointer_mode_max, atoi(s));
- }
- } else {
- pointer_mode = atoi(s);
- got_pointer_mode = pointer_mode;
- }
- continue;
- }
- if (!strcmp(arg, "-input_skip")) {
- CHECK_ARGC
- ui_skip = atoi(argv[++i]);
- if (! ui_skip) ui_skip = 1;
- continue;
- }
- if (!strcmp(arg, "-allinput")) {
- all_input = 1;
- continue;
- }
- if (!strcmp(arg, "-noallinput")) {
- all_input = 0;
- continue;
- }
- if (!strcmp(arg, "-input_eagerly")) {
- handle_events_eagerly = 1;
- continue;
- }
- if (!strcmp(arg, "-noinput_eagerly")) {
- handle_events_eagerly = 0;
- continue;
- }
- if (!strcmp(arg, "-speeds")) {
- CHECK_ARGC
- speeds_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-wmdt")) {
- CHECK_ARGC
- wmdt_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-debug_pointer")
- || !strcmp(arg, "-dp")) {
- debug_pointer++;
- continue;
- }
- if (!strcmp(arg, "-debug_keyboard")
- || !strcmp(arg, "-dk")) {
- debug_keyboard++;
- continue;
- }
- if (!strcmp(arg, "-debug_xdamage")) {
- debug_xdamage++;
- continue;
- }
- if (!strcmp(arg, "-defer")) {
- CHECK_ARGC
- defer_update = atoi(argv[++i]);
- got_defer = 1;
- continue;
- }
- if (!strcmp(arg, "-setdefer")) {
- CHECK_ARGC
- set_defer = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-wait")) {
- CHECK_ARGC
- waitms = atoi(argv[++i]);
- got_waitms = 1;
- continue;
- }
- if (!strcmp(arg, "-extra_fbur")) {
- CHECK_ARGC
- extra_fbur = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-wait_ui")) {
- CHECK_ARGC
- wait_ui = atof(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-nowait_bog")) {
- wait_bog = 0;
- continue;
- }
- if (!strcmp(arg, "-slow_fb")) {
- CHECK_ARGC
- slow_fb = atof(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-xrefresh")) {
- CHECK_ARGC
- xrefresh = atof(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-readtimeout")) {
- CHECK_ARGC
- rfbMaxClientWait = atoi(argv[++i]) * 1000;
- continue;
- }
- if (!strcmp(arg, "-ping")) {
- CHECK_ARGC
- ping_interval = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-nap")) {
- take_naps = 1;
- continue;
- }
- if (!strcmp(arg, "-nonap")) {
- take_naps = 0;
- continue;
- }
- if (!strcmp(arg, "-sb")) {
- CHECK_ARGC
- screen_blank = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-nofbpm")) {
- watch_fbpm = 1;
- continue;
- }
- if (!strcmp(arg, "-fbpm")) {
- watch_fbpm = 0;
- continue;
- }
- if (!strcmp(arg, "-nodpms")) {
- watch_dpms = 1;
- continue;
- }
- if (!strcmp(arg, "-dpms")) {
- watch_dpms = 0;
- continue;
- }
- if (!strcmp(arg, "-forcedpms")) {
- force_dpms = 1;
- continue;
- }
- if (!strcmp(arg, "-clientdpms")) {
- client_dpms = 1;
- continue;
- }
- if (!strcmp(arg, "-noserverdpms")) {
- no_ultra_dpms = 1;
- continue;
- }
- if (!strcmp(arg, "-noultraext")) {
- no_ultra_ext = 1;
- continue;
- }
- if (!strcmp(arg, "-chatwindow")) {
- chat_window = 1;
- if (argc_vnc + 1 < argc_vnc_max) {
- if (!got_inetd) {
- rfbLog("setting '-rfbversion 3.6' for -chatwindow.\n");
- }
- argv_vnc[argc_vnc++] = strdup("-rfbversion");
- argv_vnc[argc_vnc++] = strdup("3.6");
- }
- continue;
- }
- if (!strcmp(arg, "-xdamage")) {
- use_xdamage++;
- continue;
- }
- if (!strcmp(arg, "-noxdamage")) {
- use_xdamage = 0;
- continue;
- }
- if (!strcmp(arg, "-xd_area")) {
- int tn;
- CHECK_ARGC
- tn = atoi(argv[++i]);
- if (tn >= 0) {
- xdamage_max_area = tn;
- }
- continue;
- }
- if (!strcmp(arg, "-xd_mem")) {
- double f;
- CHECK_ARGC
- f = atof(argv[++i]);
- if (f >= 0.0) {
- xdamage_memory = f;
- }
- continue;
- }
- if (!strcmp(arg, "-sigpipe") || !strcmp(arg, "-sig")) {
- CHECK_ARGC
- if (known_sigpipe_mode(argv[++i])) {
- sigpipe = strdup(argv[i]);
- } else {
- fprintf(stderr, "invalid -sigpipe arg: %s, must"
- " be \"ignore\" or \"exit\"\n", argv[i]);
- exit(1);
- }
- continue;
- }
-#if LIBVNCSERVER_HAVE_LIBPTHREAD
- if (!strcmp(arg, "-threads")) {
-#if defined(X11VNC_THREADED)
- use_threads = 1;
-#else
- if (getenv("X11VNC_THREADED")) {
- use_threads = 1;
- } else if (1) {
- /* we re-enable it due to threaded mode bugfixes. */
- use_threads = 1;
- } else {
- if (!got_inetd) {
- rfbLog("\n");
- rfbLog("The -threads mode is unstable and not tested or maintained.\n");
- rfbLog("It is disabled in the source code. If you really need\n");
- rfbLog("the feature you can reenable it at build time by setting\n");
- rfbLog("-DX11VNC_THREADED in CPPFLAGS. Or set X11VNC_THREADED=1\n");
- rfbLog("in your runtime environment.\n");
- rfbLog("\n");
- usleep(500*1000);
- }
- }
-#endif
- continue;
- }
- if (!strcmp(arg, "-nothreads")) {
- use_threads = 0;
- continue;
- }
-#endif
- if (!strcmp(arg, "-fs")) {
- CHECK_ARGC
- fs_frac = atof(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-gaps")) {
- CHECK_ARGC
- gaps_fill = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-grow")) {
- CHECK_ARGC
- grow_fill = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-fuzz")) {
- CHECK_ARGC
- tile_fuzz = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-debug_tiles")
- || !strcmp(arg, "-dbt")) {
- debug_tiles++;
- continue;
- }
- if (!strcmp(arg, "-debug_grabs")) {
- debug_grabs++;
- continue;
- }
- if (!strcmp(arg, "-debug_sel")) {
- debug_sel++;
- continue;
- }
- if (!strcmp(arg, "-grab_buster")) {
- grab_buster++;
- continue;
- }
- if (!strcmp(arg, "-nograb_buster")) {
- grab_buster = 0;
- continue;
- }
- if (!strcmp(arg, "-snapfb")) {
- use_snapfb = 1;
- continue;
- }
- if (!strcmp(arg, "-rand")) {
- /* equiv. to -nopw -rawfb rand for quick tests */
- raw_fb_str = strdup("rand");
- nopw = 1;
- continue;
- }
- if (!strcmp(arg, "-rawfb")) {
- CHECK_ARGC
- raw_fb_str = strdup(argv[++i]);
- if (strstr(raw_fb_str, "vnc:") == raw_fb_str) {
- shared = 1;
- }
- continue;
- }
- if (!strcmp(arg, "-freqtab")) {
- CHECK_ARGC
- freqtab = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-pipeinput")) {
- CHECK_ARGC
- pipeinput_str = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-macnodim")) {
- macosx_nodimming = 1;
- continue;
- }
- if (!strcmp(arg, "-macnosleep")) {
- macosx_nosleep = 1;
- continue;
- }
- if (!strcmp(arg, "-macnosaver")) {
- macosx_noscreensaver = 1;
- continue;
- }
- if (!strcmp(arg, "-macnowait")) {
- macosx_wait_for_switch = 0;
- continue;
- }
- if (!strcmp(arg, "-macwheel")) {
- CHECK_ARGC
- macosx_mouse_wheel_speed = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-macnoswap")) {
- macosx_swap23 = 0;
- continue;
- }
- if (!strcmp(arg, "-macnoresize")) {
- macosx_resize = 0;
- continue;
- }
- if (!strcmp(arg, "-maciconanim")) {
- CHECK_ARGC
- macosx_icon_anim_time = atoi(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-macmenu")) {
- macosx_ncache_macmenu = 1;
- continue;
- }
- if (!strcmp(arg, "-macuskbd")) {
- macosx_us_kbd = 1;
- continue;
- }
- if (!strcmp(arg, "-macnoopengl")) {
- macosx_no_opengl = 1;
- continue;
- }
- if (!strcmp(arg, "-macnorawfb")) {
- macosx_no_rawfb = 1;
- continue;
- }
- if (!strcmp(arg, "-gui")) {
- launch_gui = 1;
- if (i < argc-1) {
- char *s = argv[i+1];
- if (*s != '-') {
- gui_str = strdup(s);
- if (strstr(gui_str, "setp")) {
- got_gui_pw = 1;
- }
- i++;
- }
- }
- continue;
- }
- if (!strcmp(arg, "-remote") || !strcmp(arg, "-R")
- || !strcmp(arg, "-r") || !strcmp(arg, "-remote-control")) {
- char *str;
- CHECK_ARGC
- i++;
- str = argv[i];
- if (*str == '-') {
- /* accidental leading '-' */
- str++;
- }
- if (!strcmp(str, "ping")) {
- query_cmd = strdup(str);
- } else {
- remote_cmd = strdup(str);
- }
- if (remote_cmd && strchr(remote_cmd, ':') == NULL) {
- /* interpret -R -scale 3/4 at least */
- if (i < argc-1 && *(argv[i+1]) != '-') {
- int n;
-
- /* it must be the parameter value */
- i++;
- n = strlen(remote_cmd) + strlen(argv[i]) + 2;
-
- str = (char *) malloc(n);
- sprintf(str, "%s:%s", remote_cmd, argv[i]);
- free(remote_cmd);
- remote_cmd = str;
- }
- }
- if (!getenv("QUERY_VERBOSE")) {
- quiet = 1;
- }
- xkbcompat = 0;
- continue;
- }
- if (!strcmp(arg, "-query") || !strcmp(arg, "-Q")) {
- CHECK_ARGC
- query_cmd = strdup(argv[++i]);
- if (!getenv("QUERY_VERBOSE")) {
- quiet = 1;
- }
- xkbcompat = 0;
- continue;
- }
- if (!strcmp(arg, "-query_retries")) {
- char *s;
- CHECK_ARGC
- s = strdup(argv[++i]);
- /* n[:t][/match] */
- if (strchr(s, '/')) {
- char *q = strchr(s, '/');
- query_match = strdup(q+1);
- *q = '\0';
- }
- if (strchr(s, ':')) {
- char *q = strchr(s, ':');
- query_delay = atof(q+1);
- }
- query_retries = atoi(s);
- free(s);
- continue;
- }
- if (!strcmp(arg, "-QD")) {
- CHECK_ARGC
- query_cmd = strdup(argv[++i]);
- query_default = 1;
- continue;
- }
- if (!strcmp(arg, "-sync")) {
- remote_sync = 1;
- continue;
- }
- if (!strcmp(arg, "-nosync")) {
- remote_sync = 0;
- continue;
- }
- if (!strcmp(arg, "-remote_prefix")) {
- CHECK_ARGC
- remote_prefix = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-noremote")) {
- accept_remote_cmds = 0;
- continue;
- }
- if (!strcmp(arg, "-yesremote")) {
- accept_remote_cmds = 1;
- continue;
- }
- if (!strcmp(arg, "-unsafe")) {
- safe_remote_only = 0;
- continue;
- }
- if (!strcmp(arg, "-privremote")) {
- priv_remote = 1;
- continue;
- }
- if (!strcmp(arg, "-safer")) {
- more_safe = 1;
- continue;
- }
- if (!strcmp(arg, "-nocmds")) {
- no_external_cmds = 1;
- continue;
- }
- if (!strcmp(arg, "-allowedcmds")) {
- CHECK_ARGC
- allowed_external_cmds = strdup(argv[++i]);
- continue;
- }
- if (!strcmp(arg, "-deny_all")) {
- deny_all = 1;
- continue;
- }
- if (!strcmp(arg, "-httpdir")) {
- CHECK_ARGC
- http_dir = strdup(argv[++i]);
- got_httpdir = 1;
- continue;
- }
- if (1) {
- if (!strcmp(arg, "-desktop") && i < argc-1) {
- dt = 1;
- rfb_desktop_name = strdup(argv[i+1]);
- }
- if (!strcmp(arg, "-passwd")) {
- pw_loc = i;
- got_passwd = 1;
- }
- if (!strcmp(arg, "-rfbauth")) {
- got_rfbauth = 1;
- }
- if (!strcmp(arg, "-rfbwait")) {
- got_rfbwait = 1;
- }
- if (!strcmp(arg, "-deferupdate")) {
- got_deferupdate = 1;
- }
- if (!strcmp(arg, "-rfbport") && i < argc-1) {
- got_rfbport = 1;
- if (!strcasecmp(argv[i+1], "prompt")) {
- ;
- } else if (!is_decimal(argv[i+1])) {
- if (!got_inetd) {
- rfbLog("Invalid -rfbport value: '%s'\n", argv[i+1]);
- rfbLog("setting it to '-1' to induce failure.\n");
- argv[i+1] = strdup("-1");
- }
- }
- got_rfbport_str = strdup(argv[i+1]);
- got_rfbport_pos = argc_vnc+1;
- got_rfbport_val = atoi(argv[i+1]);
- }
- if (!strcmp(arg, "-httpport") && i < argc-1) {
- if (!is_decimal(argv[i+1])) {
- rfbLog("Invalid -httpport value: '%s'\n", argv[i+1]);
- clean_up_exit(1);
- }
- }
- if (!strcmp(arg, "-alwaysshared ")) {
- got_alwaysshared = 1;
- }
- if (!strcmp(arg, "-nevershared")) {
- got_nevershared = 1;
- }
- if (!strcmp(arg, "-listen") && i < argc-1) {
- listen_str = strdup(argv[i+1]);
- }
- /* otherwise copy it for libvncserver use below. */
- if (!strcmp(arg, "-ultrafilexfer")) {
- got_ultrafilexfer = 1;
- } else if (argc_vnc < argc_vnc_max) {
- argv_vnc[argc_vnc++] = strdup(arg);
- } else {
- rfbLog("too many arguments.\n");
- exit(1);
- }
- continue;
- }
- }
-
- if (! getenv("NO_LIBXCB_ALLOW_SLOPPY_LOCK")) {
- /* libxcb is a bit too strict for us sometimes... */
- set_env("LIBXCB_ALLOW_SLOPPY_LOCK", "1");
- }
-
- if (getenv("PATH") == NULL || !strcmp(getenv("PATH"), "")) {
- /* set a minimal PATH, usually only null in inetd. */
- set_env("PATH", "/bin:/usr/bin");
- }
-
- /* handle -findauth case now that cmdline has been read */
- if (got_findauth) {
- char *s;
- int ic = 0;
- if (use_dpy != NULL) {
- set_env("DISPLAY", use_dpy);
- }
- use_dpy = strdup("WAIT:cmd=FINDDISPLAY-run");
-
- s = getenv("FINDAUTH_DISPLAY");
- if (s && strcmp("", s)) {
- set_env("DISPLAY", s);
- }
- s = getenv("DISPLAY");
- if (s && strcmp("", s)) {
- set_env("X11VNC_SKIP_DISPLAY", s);
- } else {
- set_env("X11VNC_SKIP_DISPLAY", ":0");
- }
- set_env("X11VNC_SKIP_DISPLAY_NEGATE", "1");
- set_env("FIND_DISPLAY_XAUTHORITY_PATH", "1");
- set_env("FIND_DISPLAY_NO_SHOW_XAUTH", "1");
- set_env("FIND_DISPLAY_NO_SHOW_DISPLAY", "1");
- wait_for_client(&ic, NULL, 0);
- exit(0);
- }
-
- /* set OS struct UT */
- uname(&UT);
-
- orig_use_xdamage = use_xdamage;
-
- if (!auto_port && getenv("AUTO_PORT")) {
- auto_port = atoi(getenv("AUTO_PORT"));
- }
-
- if (getenv("X11VNC_LOOP_MODE")) {
- if (bg && !getenv("X11VNC_LOOP_MODE_BG")) {
- if (! quiet) {
- fprintf(stderr, "disabling -bg in -loop "
- "mode\n");
- }
- bg = 0;
- } else if (!bg && getenv("X11VNC_LOOP_MODE_BG")) {
- if (! quiet) {
- fprintf(stderr, "enabling -bg in -loopbg "
- "mode\n");
- }
- bg = 1;
- }
- if (inetd) {
- if (! quiet) {
- fprintf(stderr, "disabling -inetd in -loop "
- "mode\n");
- }
- inetd = 0;
- }
- }
-
- if (launch_gui && (query_cmd || remote_cmd)) {
- launch_gui = 0;
- gui_str = NULL;
- }
- if (more_safe) {
- launch_gui = 0;
- }
-
-#ifdef MACOSX
- if (! use_dpy) {
- /* we need this for gui since no X properties */
- if (!client_connect_file && !client_connect) {
- char *user = get_user_name();
- char *str = (char *) malloc(strlen(user) + strlen("/tmp/x11vnc-macosx-remote.") + 1);
- struct stat sb;
- sprintf(str, "/tmp/x11vnc-macosx-remote.%s", user);
- if (!remote_cmd && !query_cmd) {
- unlink(str);
- if (stat(str, &sb) != 0) {
- int fd = open(str, O_WRONLY|O_EXCL|O_CREAT, 0600);
- if (fd >= 0) {
- close(fd);
- client_connect_file = str;
- }
- }
- } else {
- client_connect_file = str;
- }
- if (client_connect_file) {
- if (!got_inetd) {
- rfbLog("MacOS X: set -connect file to %s\n", client_connect_file);
- }
- }
- }
- }
-#endif
- if (got_rfbport_str != NULL && !strcasecmp(got_rfbport_str, "prompt")) {
- char *opts, tport[32];
-
- if (gui_str) {
- opts = (char *) malloc(strlen(gui_str) + 32);
- sprintf(opts, "%s,portprompt", gui_str);
- } else {
- opts = strdup("portprompt");
- }
- got_rfbport_val = -1;
-
- do_gui(opts, 0);
- if (got_rfbport_val == -1) {
- rfbLog("Port prompt indicated cancel.\n");
- clean_up_exit(1);
- }
- if (!got_inetd) {
- rfbLog("Port prompt selected: %d\n", got_rfbport_val);
- }
- sprintf(tport, "%d", got_rfbport_val);
- argv_vnc[got_rfbport_pos] = strdup(tport);
- free(opts);
- }
-
- {
- char num[32];
- sprintf(num, "%d", got_rfbport_val);
- set_env("X11VNC_GOT_RFBPORT_VAL", num);
- }
-
- if (got_ultrafilexfer && argc_vnc + 2 < argc_vnc_max) {
- argv_vnc[argc_vnc++] = strdup("-rfbversion");
- argv_vnc[argc_vnc++] = strdup("3.6");
- argv_vnc[argc_vnc++] = strdup("-permitfiletransfer");
- }
-
- if (launch_gui) {
- int sleep = 0;
- if (SHOW_NO_PASSWORD_WARNING && !nopw) {
- sleep = 1;
- }
- do_gui(gui_str, sleep);
- }
- if (logfile) {
- int n;
- char *pstr = "%VNCDISPLAY";
- if (strstr(logfile, pstr)) {
- char *h = this_host();
- char *s, *q, *newlog;
- int n, p = got_rfbport_val;
- /* we don't really know the port yet... so guess */
- if (p < 0) {
- p = auto_port;
- }
- if (p <= 0) {
- p = 5900;
- }
- s = (char *) malloc(strlen(h) + 32);
- sprintf(s, "%s:%d", h, p);
- n = 1;
- q = logfile;
- while (1) {
- char *t = strstr(q, pstr);
- if (!t) break;
- n++;
- q = t+1;
- }
- newlog = (char *) malloc(strlen(logfile) + n * strlen(pstr));
- newlog[0] = '\0';
-
- q = logfile;
- while (1) {
- char *t = strstr(q, pstr);
- if (!t) {
- strcat(newlog, q);
- break;
- }
- strncat(newlog, q, t - q);
- strcat(newlog, s);
- q = t + strlen(pstr);
- }
- logfile = newlog;
- if (!quiet && !got_inetd) {
- rfbLog("Expanded logfile to '%s'\n", newlog);
-
- }
- free(s);
- }
- pstr = "%HOME";
- if (strstr(logfile, pstr)) {
- char *h = get_home_dir();
- char *s, *q, *newlog;
-
- s = (char *) malloc(strlen(h) + 32);
- sprintf(s, "%s", h);
- n = 1;
- q = logfile;
- while (1) {
- char *t = strstr(q, pstr);
- if (!t) break;
- n++;
- q = t+1;
- }
- newlog = (char *) malloc(strlen(logfile) + n * strlen(pstr));
- newlog[0] = '\0';
-
- q = logfile;
- while (1) {
- char *t = strstr(q, pstr);
- if (!t) {
- strcat(newlog, q);
- break;
- }
- strncat(newlog, q, t - q);
- strcat(newlog, s);
- q = t + strlen(pstr);
- }
- logfile = newlog;
- if (!quiet && !got_inetd) {
- rfbLog("Expanded logfile to '%s'\n", newlog);
- }
- free(s);
- }
-
- if (logfile_append) {
- n = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0666);
- } else {
- n = open(logfile, O_WRONLY|O_CREAT|O_TRUNC, 0666);
- }
- if (n < 0) {
- fprintf(stderr, "error opening logfile: %s\n", logfile);
- perror("open");
- exit(1);
- }
- if (dup2(n, 2) < 0) {
- fprintf(stderr, "dup2 failed\n");
- perror("dup2");
- exit(1);
- }
- if (n > 2) {
- close(n);
- }
- }
- if (ipv6_listen) {
- if (inetd) {
- ipv6_listen = 0;
- }
- }
- if (inetd && quiet && !logfile) {
- int n;
- /*
- * Redir stderr to /dev/null under -inetd and -quiet
- * but no -o logfile. Typical problem:
- * Xlib: extension "RECORD" missing on display ":1.0".
- * If they want this info, they should use -o logfile,
- * or no -q and 2>logfile.
- */
- n = open("/dev/null", O_WRONLY);
- if (n >= 0) {
- if (dup2(n, 2) >= 0) {
- if (n > 2) {
- close(n);
- }
- }
- }
- }
- if (! quiet && ! inetd) {
- int i;
- if (http_oneport_msg) {
- rfbLog("setting '-enc none' for -http_oneport mode.\n");
- }
- for (i=1; i < argc_vnc; i++) {
- rfbLog("passing arg to libvncserver: %s\n", argv_vnc[i]);
- if (!strcmp(argv_vnc[i], "-passwd")) {
- i++;
- }
- }
- }
-
- if (remote_cmd || query_cmd) {
- /*
- * no need to open DISPLAY, just write it to the file now
- * similar for query_default.
- */
- if (client_connect_file || query_default) {
- int i, rc = 1;
- for (i=0; i <= query_retries; i++) {
- rc = do_remote_query(remote_cmd, query_cmd,
- remote_sync, query_default);
- if (rc == 0) {
- if (query_match) {
- if (query_result && strstr(query_result, query_match)) {
- break;
- }
- rc = 1;
- } else {
- break;
- }
- }
- if (i < query_retries) {
- fprintf(stderr, "sleep: %.3f\n", query_delay);
- usleep( (int) (query_delay * 1000 * 1000) );
- }
- }
- fflush(stderr);
- fflush(stdout);
- exit(rc);
- }
- }
-
- if (usepw && ! got_rfbauth && ! got_passwd && ! got_passwdfile && !unixpw) {
- char *f, *h = getenv("HOME");
- struct stat sbuf;
- int found = 0, set_rfbauth = 0;
-
- if (!h) {
- rfbLog("HOME unset in -usepw mode.\n");
- exit(1);
- }
- f = (char *) malloc(strlen(h)+strlen("/.vnc/passwdfile") + 1);
-
- sprintf(f, "%s/.vnc/passwd", h);
- if (stat(f, &sbuf) == 0) {
- found = 1;
- if (! quiet) {
- rfbLog("-usepw: found %s\n", f);
- }
- got_rfbauth = 1;
- set_rfbauth = 1;
- }
-
- sprintf(f, "%s/.vnc/passwdfile", h);
- if (! found && stat(f, &sbuf) == 0) {
- found = 1;
- if (! quiet) {
- rfbLog("-usepw: found %s\n", f);
- }
- got_passwdfile = 1;
- passwdfile = strdup(f);
- }
-
-#if LIBVNCSERVER_HAVE_FORK
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H
-#if LIBVNCSERVER_HAVE_WAITPID
- if (! found) {
- pid_t pid = fork();
- if (pid < 0) {
- ;
- } else if (pid == 0) {
- execlp(argv[0], argv[0], "-storepasswd",
- (char *) NULL);
- exit(1);
- } else {
- int s;
- waitpid(pid, &s, 0);
- if (WIFEXITED(s) && WEXITSTATUS(s) == 0) {
- got_rfbauth = 1;
- set_rfbauth = 1;
- found = 1;
- }
- }
- }
-#endif
-#endif
-#endif
-
- if (set_rfbauth) {
- sprintf(f, "%s/.vnc/passwd", h);
- if (argc_vnc < 100) {
- argv_vnc[argc_vnc++] = strdup("-rfbauth");
- } else {
- exit(1);
- }
- if (argc_vnc < 100) {
- argv_vnc[argc_vnc++] = strdup(f);
- } else {
- exit(1);
- }
- }
- if (! found) {
- fprintf(stderr, "x11vnc -usepw: could not find"
- " a password to use.\n");
- exit(1);
- }
- free(f);
- }
-
- if (got_rfbauth && (got_passwd || got_viewpasswd || got_passwdfile)) {
- fprintf(stderr, "option -rfbauth is incompatible with:\n");
- fprintf(stderr, " -passwd, -viewpasswd, and -passwdfile\n");
- exit(1);
- }
- if (got_passwdfile && (got_passwd || got_viewpasswd)) {
- fprintf(stderr, "option -passwdfile is incompatible with:\n");
- fprintf(stderr, " -passwd and -viewpasswd\n");
- exit(1);
- }
-
- /*
- * If -passwd was used, clear it out of argv. This does not
- * work on all UNIX, have to use execvp() in general...
- */
- if (pw_loc > 0) {
- int i;
- for (i=pw_loc; i <= pw_loc+1; i++) {
- if (i < argc) {
- char *p = argv[i];
- strzero(p);
- }
- }
- } else if (passwdfile) {
- /* read passwd(s) from file */
- if (strstr(passwdfile, "cmd:") == passwdfile ||
- strstr(passwdfile, "custom:") == passwdfile) {
- char tstr[100], *q;
- sprintf(tstr, "%f", dnow());
- if ((q = strrchr(tstr, '.')) == NULL) {
- q = tstr;
- } else {
- q++;
- }
- /* never used under cmd:, used to force auth */
- argv_vnc[argc_vnc++] = strdup("-passwd");
- argv_vnc[argc_vnc++] = strdup(q);
- } else if (read_passwds(passwdfile)) {
- argv_vnc[argc_vnc++] = strdup("-passwd");
- argv_vnc[argc_vnc++] = strdup(passwd_list[0]);
- }
- got_passwd = 1;
- pw_loc = 100; /* just for pw_loc check below */
- }
- if (vpw_loc > 0) {
- int i;
- for (i=vpw_loc; i <= vpw_loc+1; i++) {
- if (i < argc) {
- char *p = argv[i];
- strzero(p);
- }
- }
- }
-#ifdef HARDWIRE_PASSWD
- if (!got_rfbauth && !got_passwd) {
- argv_vnc[argc_vnc++] = strdup("-passwd");
- argv_vnc[argc_vnc++] = strdup(HARDWIRE_PASSWD);
- got_passwd = 1;
- pw_loc = 100;
- }
-#endif
-#ifdef HARDWIRE_VIEWPASSWD
- if (!got_rfbauth && got_passwd && !viewonly_passwd && !passwd_list) {
- viewonly_passwd = strdup(HARDWIRE_VIEWPASSWD);
- }
-#endif
- if (viewonly_passwd && pw_loc < 0) {
- rfbLog("-passwd must be supplied when using -viewpasswd\n");
- exit(1);
- }
- if (1) {
- /* mix things up a little bit */
- unsigned char buf[CHALLENGESIZE];
- int k, kmax = (int) (50 * rfac()) + 10;
- for (k=0; k < kmax; k++) {
- rfbRandomBytes(buf);
- }
- }
-
- if (SHOW_NO_PASSWORD_WARNING) {
- char message[] = "-rfbauth, -passwdfile, -passwd password, "
- "or -unixpw required.";
- if (! nopw) {
- nopassword_warning_msg(got_localhost);
- }
-#if PASSWD_REQUIRED
- rfbLog("%s\n", message);
- exit(1);
-#endif
-#if PASSWD_UNLESS_NOPW
- if (! nopw) {
- rfbLog("%s\n", message);
- exit(1);
- }
-#endif
- message[0] = '\0'; /* avoid compiler warning */
- }
-
- if (more_safe) {
- if (! quiet) {
- rfbLog("-safer mode:\n");
- rfbLog(" vnc_connect=0\n");
- rfbLog(" accept_remote_cmds=0\n");
- rfbLog(" safe_remote_only=1\n");
- rfbLog(" launch_gui=0\n");
- }
- vnc_connect = 0;
- accept_remote_cmds = 0;
- safe_remote_only = 1;
- launch_gui = 0;
- }
-
- if (users_list && strchr(users_list, '.')) {
- char *p, *q, *tmp = (char *) malloc(strlen(users_list)+1);
- char *str = strdup(users_list);
- int i, n, db = 1;
-
- tmp[0] = '\0';
-
- n = strlen(users_list) + 1;
- user2group = (char **) malloc(n * sizeof(char *));
- for (i=0; i<n; i++) {
- user2group[i] = NULL;
- }
-
- i = 0;
- p = strtok(str, ",");
- if (db) fprintf(stderr, "users_list: %s\n", users_list);
- while (p) {
- if (tmp[0] != '\0') {
- strcat(tmp, ",");
- }
- q = strchr(p, '.');
- if (q) {
- char *s = strchr(p, '=');
- if (! s) {
- s = p;
- } else {
- s++;
- }
- if (s[0] == '+') s++;
- user2group[i++] = strdup(s);
- if (db) fprintf(stderr, "u2g: %s\n", s);
- *q = '\0';
- }
- strcat(tmp, p);
- p = strtok(NULL, ",");
- }
- free(str);
- users_list = tmp;
- if (db) fprintf(stderr, "users_list: %s\n", users_list);
- }
-
- if (got_tls > 0 && !use_openssl) {
- rfbLog("SSL: Error: you did not supply the '-ssl ...' option even\n");
- rfbLog("SSL: though you supplied one of these related options:\n");
- rfbLog("SSL: -sslonly, -sslverify, -sslCRL, -vencrypt, -anontls,\n");
- rfbLog("SSL: -dhparams, -https, -http_ssl, or -httpsredir.\n");
- rfbLog("SSL: Restart with, for example, '-ssl SAVE' on the cmd line.\n");
- rfbLog("SSL: See the '-ssl' x11vnc -help description for more info.\n");
- if (!getenv("X11VNC_FORCE_NO_OPENSSL")) {
- exit(1);
- }
- }
-
- if (unixpw) {
- if (inetd) {
- use_stunnel = 0;
- }
- if (! use_stunnel && ! use_openssl) {
- if (getenv("UNIXPW_DISABLE_SSL")) {
- rfbLog("Skipping -ssl/-stunnel requirement"
- " due to\n");
- rfbLog("UNIXPW_DISABLE_SSL setting.\n");
-
- if (!getenv("UNIXPW_DISABLE_LOCALHOST")) {
- if (!got_localhost) {
- rfbLog("Forcing -localhost mode.\n");
- }
- allow_list = strdup("127.0.0.1");
- got_localhost = 1;
- }
- } else if (have_ssh_env()) {
- char *s = getenv("SSH_CONNECTION");
- if (! s) s = getenv("SSH_CLIENT");
- if (! s) s = "SSH_CONNECTION";
- fprintf(stderr, "\n");
- rfbLog("Skipping -ssl/-stunnel constraint in"
- " -unixpw mode,\n");
- rfbLog("assuming your SSH encryption"
- " is:\n");
- rfbLog(" %s\n", s);
-
- if (!getenv("UNIXPW_DISABLE_LOCALHOST")) {
- if (!got_localhost) {
- rfbLog("Setting -localhost in SSH + -unixpw mode.\n");
- }
- allow_list = strdup("127.0.0.1");
- got_localhost = 1;
- }
-
- rfbLog("If you *actually* want SSL, restart"
- " with -ssl on the cmdline\n");
- if (! nopw) {
- usleep(2000*1000);
- }
- } else {
- if (openssl_present()) {
- rfbLog("set -ssl in -unixpw mode.\n");
- use_openssl = 1;
- } else if (inetd) {
- rfbLog("could not set -ssl in -inetd"
- " + -unixpw mode.\n");
- exit(1);
- } else {
- rfbLog("set -stunnel in -unixpw mode.\n");
- use_stunnel = 1;
- }
- }
- rfbLog("\n");
- }
- if (use_threads && !getenv("UNIXPW_THREADS")) {
- if (! quiet) {
- rfbLog("disabling -threads under -unixpw\n");
- rfbLog("\n");
- }
- use_threads = 0;
- }
- }
- if (use_stunnel && ! got_localhost) {
- if (! getenv("STUNNEL_DISABLE_LOCALHOST") &&
- ! getenv("UNIXPW_DISABLE_LOCALHOST")) {
- if (! quiet) {
- rfbLog("Setting -localhost in -stunnel mode.\n");
- }
- allow_list = strdup("127.0.0.1");
- got_localhost = 1;
- }
- }
- if (ssl_verify && ! use_stunnel && ! use_openssl) {
- rfbLog("-sslverify must be used with -ssl or -stunnel\n");
- exit(1);
- }
- if (https_port_num >= 0 && ! use_openssl) {
- rfbLog("-https must be used with -ssl\n");
- exit(1);
- }
-
- if (use_threads && !got_noxrandr) {
- xrandr = 1;
- if (! quiet) {
- rfbLog("enabling -xrandr in -threads mode.\n");
- }
- }
-
- /* fixup settings that do not make sense */
-
- if (use_threads && nofb && cursor_pos_updates) {
- if (! quiet) {
- rfbLog("disabling -threads under -nofb -cursorpos\n");
- }
- use_threads = 0;
- }
- if (tile_fuzz < 1) {
- tile_fuzz = 1;
- }
- if (waitms < 0) {
- waitms = 0;
- }
-
- if (alpha_threshold < 0) {
- alpha_threshold = 0;
- }
- if (alpha_threshold > 256) {
- alpha_threshold = 256;
- }
- if (alpha_frac < 0.0) {
- alpha_frac = 0.0;
- }
- if (alpha_frac > 1.0) {
- alpha_frac = 1.0;
- }
- if (alpha_blend) {
- alpha_remove = 0;
- }
-
- if (cmap8to24 && overlay) {
- if (! quiet) {
- rfbLog("disabling -overlay in -8to24 mode.\n");
- }
- overlay = 0;
- }
-
- if (tightfilexfer && view_only) {
- if (! quiet) {
- rfbLog("setting -notightfilexfer in -viewonly mode.\n");
- }
- /* how to undo via -R? */
- tightfilexfer = 0;
- }
-
- if (inetd) {
- shared = 0;
- connect_once = 1;
- bg = 0;
- if (use_stunnel) {
- exit(1);
- }
- }
-
- http_try_it = try_http;
-
- if (flip_byte_order && using_shm && ! quiet) {
- rfbLog("warning: -flipbyte order only works with -noshm\n");
- }
-
- if (! wireframe_copyrect) {
- set_wirecopyrect_mode(NULL);
- }
- if (! scroll_copyrect) {
- set_scrollcopyrect_mode(NULL);
- }
- if (screen_fixup_str) {
- parse_fixscreen();
- }
- initialize_scroll_matches();
- initialize_scroll_term();
- initialize_max_keyrepeat();
-
- /* increase rfbwait if threaded */
- if (use_threads && ! got_rfbwait) {
- /* ??? lower this ??? */
- rfbMaxClientWait = 604800000;
- }
-
- /* no framebuffer (Win2VNC) mode */
-
- if (nofb) {
- /* disable things that do not make sense with no fb */
- set_nofb_params(0);
-
- if (! got_deferupdate && ! got_defer) {
- /* reduce defer time under -nofb */
- defer_update = defer_update_nofb;
- }
- if (got_pointer_mode < 0) {
- pointer_mode = POINTER_MODE_NOFB;
- }
- }
-
- if (ncache < 0) {
- ncache_beta_tester = 1;
- ncache_msg = 1;
- if (ncache == -1) {
- ncache = 0;
- }
- ncache = -ncache;
- if (try_http || got_httpdir) {
- /* JVM usually not set to handle all the memory */
- ncache = 0;
- ncache_msg = 0;
- }
- if (subwin) {
- ncache = 0;
- ncache_msg = 0;
- }
- }
-
- if (raw_fb_str) {
- set_raw_fb_params(0);
- }
- if (! got_deferupdate) {
- char tmp[40];
- sprintf(tmp, "%d", defer_update);
- argv_vnc[argc_vnc++] = strdup("-deferupdate");
- argv_vnc[argc_vnc++] = strdup(tmp);
- }
-
- if (debug_pointer || debug_keyboard) {
- if (!logfile) {
- if (bg || quiet) {
- rfbLog("disabling -bg/-q under -debug_pointer"
- "/-debug_keyboard\n");
- bg = 0;
- quiet = 0;
- }
- }
- }
-
- /* initialize added_keysyms[] array to zeros */
- add_keysym(NoSymbol);
-
- /* tie together cases of -localhost vs. -listen localhost */
- if (! listen_str) {
- if (allow_list && !strcmp(allow_list, "127.0.0.1")) {
- listen_str = strdup("localhost");
- argv_vnc[argc_vnc++] = strdup("-listen");
- argv_vnc[argc_vnc++] = strdup(listen_str);
- }
- } else if (!strcmp(listen_str, "localhost") ||
- !strcmp(listen_str, "127.0.0.1")) {
- allow_list = strdup("127.0.0.1");
- }
-
- initialize_crash_handler();
-
- if (! quiet) {
- if (verbose) {
- print_settings(try_http, bg, gui_str);
- }
- rfbLog("x11vnc version: %s pid: %d\n", lastmod, getpid());
- } else {
- rfbLogEnable(0);
- }
-
- X_INIT;
- SCR_INIT;
- CLIENT_INIT;
- INPUT_INIT;
- POINTER_INIT;
-
- /* open the X display: */
-
-#if LIBVNCSERVER_HAVE_XKEYBOARD
- /*
- * Disable XKEYBOARD before calling XOpenDisplay()
- * this should be used if there is ambiguity in the keymapping.
- */
- if (xkbcompat) {
- Bool rc = XkbIgnoreExtension(True);
- if (! quiet) {
- rfbLog("Disabling xkb XKEYBOARD extension. rc=%d\n",
- rc);
- }
- if (watch_bell) {
- watch_bell = 0;
- if (! quiet) rfbLog("Disabling bell.\n");
- }
- }
-#else
- watch_bell = 0;
- use_xkb_modtweak = 0;
-#endif
-
-#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
- if (tightfilexfer) {
- rfbLog("rfbRegisterTightVNCFileTransferExtension: 6\n");
- rfbRegisterTightVNCFileTransferExtension();
- } else {
- if (0) rfbLog("rfbUnregisterTightVNCFileTransferExtension: 3\n");
- rfbUnregisterTightVNCFileTransferExtension();
- }
-#endif
-
- initialize_allowed_input();
-
- if (display_N && !got_rfbport) {
- char *ud = use_dpy;
- if (ud == NULL) {
- ud = getenv("DISPLAY");
- }
- if (ud && strstr(ud, "cmd=") == NULL) {
- char *p;
- ud = strdup(ud);
- p = strrchr(ud, ':');
- if (p) {
- int N;
- char *q = strchr(p, '.');
- if (q) {
- *q = '\0';
- }
- N = atoi(p+1);
- if (argc_vnc+1 < argc_vnc_max) {
- char Nstr[16];
- sprintf(Nstr, "%d", (5900 + N) % 65536);
- argv_vnc[argc_vnc++] = strdup("-rfbport");
- argv_vnc[argc_vnc++] = strdup(Nstr);
- got_rfbport = 1;
- }
- }
- free(ud);
- }
- }
-
- if (users_list && strstr(users_list, "lurk=")) {
- if (use_dpy) {
- rfbLog("warning: -display does not make sense in "
- "\"lurk=\" mode...\n");
- }
- if (auth_file != NULL && strcmp(auth_file, "guess")) {
- set_env("XAUTHORITY", auth_file);
- }
- lurk_loop(users_list);
-
- } else if (use_dpy && strstr(use_dpy, "WAIT:") == use_dpy) {
- char *mcm = multiple_cursors_mode;
-
- if (strstr(use_dpy, "Xdummy")) {
- if (!xrandr && !got_noxrandr) {
- if (! quiet) {
- rfbLog("Enabling -xrandr for possible use of Xdummy server.\n");
- }
- xrandr = 1;
- }
- }
-
- waited_for_client = wait_for_client(&argc_vnc, argv_vnc,
- try_http && ! got_httpdir);
-
- if (!mcm && multiple_cursors_mode) {
- free(multiple_cursors_mode);
- multiple_cursors_mode = NULL;
- }
- }
-
-
- if (auth_file) {
- check_guess_auth_file();
- if (auth_file != NULL) {
- set_env("XAUTHORITY", auth_file);
- }
- }
-
-#ifdef MACOSX
- if (use_dpy && !strcmp(use_dpy, "console")) {
- ;
- } else
-#endif
- if (use_dpy && strcmp(use_dpy, "")) {
- dpy = XOpenDisplay_wr(use_dpy);
-#ifdef MACOSX
- } else if (!subwin && getenv("DISPLAY")
- && strstr(getenv("DISPLAY"), "/tmp/") ) {
- /* e.g. /tmp/launch-XlspvM/:0 on leopard */
- rfbLog("MacOSX: Ignoring $DISPLAY '%s'\n", getenv("DISPLAY"));
- rfbLog("MacOSX: Use -display $DISPLAY to force it.\n");
-#endif
- } else if (raw_fb_str != NULL && raw_fb_str[0] != '+' && !got_noviewonly) {
- rfbLog("Not opening DISPLAY in -rawfb mode (force via -rawfb +str)\n");
- dpy = NULL; /* don't open it. */
- } else if ( (use_dpy = getenv("DISPLAY")) ) {
- if (strstr(use_dpy, "localhost") == use_dpy) {
- rfbLog("\n");
- rfbLog("WARNING: DISPLAY starts with localhost: '%s'\n", use_dpy);
- rfbLog("WARNING: Is this an SSH X11 port forwarding? You most\n");
- rfbLog("WARNING: likely don't want x11vnc to use that DISPLAY.\n");
- rfbLog("WARNING: You probably should supply something\n");
- rfbLog("WARNING: like: -display :0 to access the physical\n");
- rfbLog("WARNING: X display on the machine where x11vnc is running.\n");
- rfbLog("\n");
- usleep(500 * 1000);
- } else if (using_shm && use_dpy[0] != ':') {
- rfbLog("\n");
- rfbLog("WARNING: DISPLAY might not be local: '%s'\n", use_dpy);
- rfbLog("WARNING: Is this the DISPLAY of another machine? Usually,\n");
- rfbLog("WARNING: x11vnc is run on the same machine with the\n");
- rfbLog("WARNING: physical X display to be exported by VNC. If\n");
- rfbLog("WARNING: that is what you really meant, supply something\n");
- rfbLog("WARNING: like: -display :0 on the x11vnc command line.\n");
- rfbLog("\n");
- usleep(250 * 1000);
- }
- dpy = XOpenDisplay_wr(use_dpy);
- } else {
- dpy = XOpenDisplay_wr("");
- }
- last_open_xdisplay = time(NULL);
-
- if (terminal_services_daemon != NULL) {
- terminal_services(terminal_services_daemon);
- exit(0);
- }
-
- if (dpy && !xrandr && !got_noxrandr) {
-#if !NO_X11
- Atom trap_xrandr = XInternAtom(dpy, "X11VNC_TRAP_XRANDR", True);
- if (trap_xrandr != None) {
- if (! quiet) {
- rfbLog("Enabling -xrandr due to X11VNC_TRAP_XRANDR atom.\n");
- }
- xrandr = 1;
- }
-#endif
- }
-
-#ifdef MACOSX
- if (! dpy && ! raw_fb_str) {
- raw_fb_str = strdup("console");
- }
-#endif
-
- if (! dpy && raw_fb_str) {
- rfbLog("Continuing without X display in -rawfb mode.\n");
- goto raw_fb_pass_go_and_collect_200_dollars;
- }
-
- if (! dpy && ! use_dpy && ! getenv("DISPLAY")) {
- int i, s = 4;
- rfbLogEnable(1);
- rfbLog("\a\n");
- rfbLog("*** XOpenDisplay failed. No -display or DISPLAY.\n");
- rfbLog("*** Trying \":0\" in %d seconds. Press Ctrl-C to"
- " abort.\n", s);
- rfbLog("*** ");
- for (i=1; i<=s; i++) {
- fprintf(stderr, "%d ", i);
- sleep(1);
- }
- fprintf(stderr, "\n");
- use_dpy = ":0";
- dpy = XOpenDisplay_wr(use_dpy);
- last_open_xdisplay = time(NULL);
- if (dpy) {
- rfbLog("*** XOpenDisplay of \":0\" successful.\n");
- }
- rfbLog("\n");
- if (quiet) rfbLogEnable(0);
- }
-
- if (! dpy) {
- char *d = use_dpy;
- if (!d) d = getenv("DISPLAY");
- if (!d) d = "null";
- rfbLogEnable(1);
- fprintf(stderr, "\n");
- rfbLog("***************************************\n", d);
- rfbLog("*** XOpenDisplay failed (%s)\n", d);
- xopen_display_fail_message(d);
- exit(1);
- } else if (use_dpy) {
- if (! quiet) rfbLog("Using X display %s\n", use_dpy);
- } else {
- if (! quiet) rfbLog("Using default X display.\n");
- }
-
- if (clip_str != NULL && dpy != NULL) {
- check_xinerama_clip();
- }
-
- scr = DefaultScreen(dpy);
- rootwin = RootWindow(dpy, scr);
-
-#if !NO_X11
- if (dpy) {
- Window w = XCreateSimpleWindow(dpy, rootwin, 0, 0, 1, 1, 0, 0, 0);
- if (! quiet) rfbLog("rootwin: 0x%lx reswin: 0x%lx dpy: 0x%x\n", rootwin, w, dpy);
- if (w != None) {
- XDestroyWindow(dpy, w);
- }
- XSync(dpy, False);
- }
-#endif
-
- if (ncache_beta_tester) {
- int h = DisplayHeight(dpy, scr);
- int w = DisplayWidth(dpy, scr);
- int mem = (w * h * 4) / (1000 * 1000), MEM = 96;
- if (mem < 1) mem = 1;
-
- /* limit poor, unsuspecting beta tester's viewer to 96 MB */
- if ( (ncache+2) * mem > MEM ) {
- int n = (MEM/mem) - 2;
- if (n < 0) n = 0;
- n = 2 * (n / 2);
- if (n < ncache) {
- ncache = n;
- }
- }
- }
-
- if (grab_always) {
- Window save = window;
- window = rootwin;
- adjust_grabs(1, 0);
- window = save;
- }
-
- if ( (remote_cmd && strstr(remote_cmd, "DIRECT:") == remote_cmd)
- || (query_cmd && strstr(query_cmd, "DIRECT:") == query_cmd )) {
- /* handled below after most everything is setup. */
- if (getenv("QUERY_VERBOSE")) {
- quiet = 0;
- } else {
- quiet = 1;
- remote_direct = 1;
- }
- if (!auto_port) {
- auto_port = 5970;
- }
- } else if (remote_cmd || query_cmd) {
- int i, rc = 1;
- for (i=0; i <= query_retries; i++) {
- rc = do_remote_query(remote_cmd, query_cmd, remote_sync,
- query_default);
- if (rc == 0) {
- if (query_match) {
- if (query_result && strstr(query_result, query_match)) {
- break;
- }
- rc = 1;
- } else {
- break;
- }
- }
- if (i < query_retries) {
- fprintf(stderr, "sleep: %.3f\n", query_delay);
- usleep( (int) (query_delay * 1000 * 1000) );
- }
- }
- XFlush_wr(dpy);
- fflush(stderr);
- fflush(stdout);
- usleep(30 * 1000); /* still needed? */
- XCloseDisplay_wr(dpy);
- exit(rc);
- }
-
- if (! quiet && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("------------------ USEFUL INFORMATION ------------------\n");
- }
-
- if (priv_remote) {
- if (! remote_control_access_ok()) {
- rfbLog("** Disabling remote commands in -privremote mode.\n");
- accept_remote_cmds = 0;
- }
- }
-
- sync_tod_with_servertime();
- if (grab_buster) {
- spawn_grab_buster();
- }
-
-#if LIBVNCSERVER_HAVE_LIBXFIXES
- if (! XFixesQueryExtension(dpy, &xfixes_base_event_type, &er)) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("Disabling XFIXES mode: display does not support it.\n");
- }
- xfixes_base_event_type = 0;
- xfixes_present = 0;
- } else {
- xfixes_present = 1;
- }
-#endif
- if (! xfixes_present) {
- use_xfixes = 0;
- }
-
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- if (! XDamageQueryExtension(dpy, &xdamage_base_event_type, &er)) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("Disabling X DAMAGE mode: display does not support it.\n");
- }
- xdamage_base_event_type = 0;
- xdamage_present = 0;
- } else {
- xdamage_present = 1;
- }
-#endif
- if (! xdamage_present) {
- use_xdamage = 0;
- }
- if (! quiet && xdamage_present && use_xdamage && ! raw_fb_str) {
- rfbLog("X DAMAGE available on display, using it for polling hints.\n");
- rfbLog(" To disable this behavior use: '-noxdamage'\n");
- rfbLog("\n");
- rfbLog(" Most compositing window managers like 'compiz' or 'beryl'\n");
- rfbLog(" cause X DAMAGE to fail, and so you may not see any screen\n");
- rfbLog(" updates via VNC. Either disable 'compiz' (recommended) or\n");
- rfbLog(" supply the x11vnc '-noxdamage' command line option.\n");
- }
-
- if (! quiet && wireframe && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("Wireframing: -wireframe mode is in effect for window moves.\n");
- rfbLog(" If this yields undesired behavior (poor response, painting\n");
- rfbLog(" errors, etc) it may be disabled:\n");
- rfbLog(" - use '-nowf' to disable wireframing completely.\n");
- rfbLog(" - use '-nowcr' to disable the Copy Rectangle after the\n");
- rfbLog(" moved window is released in the new position.\n");
- rfbLog(" Also see the -help entry for tuning parameters.\n");
- rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row to \n");
- rfbLog(" repaint the screen, also see the -fixscreen option for\n");
- rfbLog(" periodic repaints.\n");
- if (scale_str && !strstr(scale_str, "nocr")) {
- rfbLog(" Note: '-scale' is on and this can cause more problems.\n");
- }
- }
-
- overlay_present = 0;
-#if defined(SOLARIS_OVERLAY) && !NO_X11
- if (! XQueryExtension(dpy, "SUN_OVL", &maj, &ev, &er)) {
- if (! quiet && overlay && ! raw_fb_str) {
- rfbLog("Disabling -overlay: SUN_OVL extension not available.\n");
- }
- } else {
- overlay_present = 1;
- }
-#endif
-#if defined(IRIX_OVERLAY) && !NO_X11
- if (! XReadDisplayQueryExtension(dpy, &ev, &er)) {
- if (! quiet && overlay && ! raw_fb_str) {
- rfbLog("Disabling -overlay: IRIX ReadDisplay extension not available.\n");
- }
- } else {
- overlay_present = 1;
- }
-#endif
- if (overlay && !overlay_present) {
- overlay = 0;
- overlay_cursor = 0;
- }
-
- /* cursor shapes setup */
- if (! multiple_cursors_mode) {
- multiple_cursors_mode = strdup("default");
- }
- if (show_cursor) {
- if(!strcmp(multiple_cursors_mode, "default")
- && xfixes_present && use_xfixes) {
- free(multiple_cursors_mode);
- multiple_cursors_mode = strdup("most");
-
- if (! quiet && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("XFIXES available on display, resetting cursor mode\n");
- rfbLog(" to: '-cursor most'.\n");
- rfbLog(" to disable this behavior use: '-cursor arrow'\n");
- rfbLog(" or '-noxfixes'.\n");
- }
- }
- if(!strcmp(multiple_cursors_mode, "most")) {
- if (xfixes_present && use_xfixes &&
- overlay_cursor == 1) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("using XFIXES for cursor drawing.\n");
- }
- overlay_cursor = 0;
- }
- }
- }
-
- if (overlay) {
- using_shm = 0;
- if (flash_cmap && ! quiet && ! raw_fb_str) {
- rfbLog("warning: -flashcmap may be incompatible with -overlay\n");
- }
- if (show_cursor && overlay_cursor) {
- char *s = multiple_cursors_mode;
- if (*s == 'X' || !strcmp(s, "some") ||
- !strcmp(s, "arrow")) {
- /*
- * user wants these modes, so disable fb cursor
- */
- overlay_cursor = 0;
- } else {
- /*
- * "default" and "most", we turn off
- * show_cursor since it will automatically
- * be in the framebuffer.
- */
- show_cursor = 0;
- }
- }
- }
-
- initialize_cursors_mode();
-
- /* check for XTEST */
- if (! XTestQueryExtension_wr(dpy, &ev, &er, &maj, &min)) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("WARNING: XTEST extension not available (either missing from\n");
- rfbLog(" display or client library libXtst missing at build time).\n");
- rfbLog(" MOST user input (pointer and keyboard) will be DISCARDED.\n");
- rfbLog(" If display does have XTEST, be sure to build x11vnc with\n");
- rfbLog(" a working libXtst build environment (e.g. libxtst-dev,\n");
- rfbLog(" or other packages).\n");
- rfbLog("No XTEST extension, switching to -xwarppointer mode for\n");
- rfbLog(" pointer motion input.\n");
- }
- xtest_present = 0;
- use_xwarppointer = 1;
- } else {
- xtest_present = 1;
- xtest_base_event_type = ev;
- if (maj <= 1 || (maj == 2 && min <= 2)) {
- /* no events defined as of 2.2 */
- xtest_base_event_type = 0;
- }
- }
-
- if (! XETrapQueryExtension_wr(dpy, &ev, &er, &maj)) {
- xtrap_present = 0;
- } else {
- xtrap_present = 1;
- xtrap_base_event_type = ev;
- }
-
- /*
- * Window managers will often grab the display during resize,
- * etc, using XGrabServer(). To avoid deadlock (our user resize
- * input is not processed) we tell the server to process our
- * requests during all grabs:
- */
- disable_grabserver(dpy, 0);
-
- /* check for RECORD */
- if (! XRecordQueryVersion_wr(dpy, &maj, &min)) {
- xrecord_present = 0;
- if (! quiet) {
- rfbLog("\n");
- rfbLog("The RECORD X extension was not found on the display.\n");
- rfbLog("If your system has disabled it by default, you can\n");
- rfbLog("enable it to get a nice x11vnc performance speedup\n");
- rfbLog("for scrolling by putting this into the \"Module\" section\n");
- rfbLog("of /etc/X11/xorg.conf or /etc/X11/XF86Config:\n");
- rfbLog("\n");
- rfbLog(" Section \"Module\"\n");
- rfbLog(" ...\n");
- rfbLog(" Load \"record\"\n");
- rfbLog(" ...\n");
- rfbLog(" EndSection\n");
- rfbLog("\n");
- }
- } else {
- xrecord_present = 1;
- }
-
- initialize_xrecord();
-
- tmpi = 1;
- if (scroll_copyrect) {
- if (strstr(scroll_copyrect, "never")) {
- tmpi = 0;
- }
- } else if (scroll_copyrect_default) {
- if (strstr(scroll_copyrect_default, "never")) {
- tmpi = 0;
- }
- }
- if (! xrecord_present) {
- tmpi = 0;
- }
-#if !LIBVNCSERVER_HAVE_RECORD
- tmpi = 0;
-#endif
- if (! quiet && tmpi && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("Scroll Detection: -scrollcopyrect mode is in effect to\n");
- rfbLog(" use RECORD extension to try to detect scrolling windows\n");
- rfbLog(" (induced by either user keystroke or mouse input).\n");
- rfbLog(" If this yields undesired behavior (poor response, painting\n");
- rfbLog(" errors, etc) it may be disabled via: '-noscr'\n");
- rfbLog(" Also see the -help entry for tuning parameters.\n");
- rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row to \n");
- rfbLog(" repaint the screen, also see the -fixscreen option for\n");
- rfbLog(" periodic repaints.\n");
- if (scale_str && !strstr(scale_str, "nocr")) {
- rfbLog(" Note: '-scale' is on and this can cause more problems.\n");
- }
- }
-
- if (! quiet && ncache && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("Client Side Caching: -ncache mode is in effect to provide\n");
- rfbLog(" client-side pixel data caching. This speeds up\n");
- rfbLog(" iconifying/deiconifying windows, moving and raising\n");
- rfbLog(" windows, and reposting menus. In the simple CopyRect\n");
- rfbLog(" encoding scheme used (no compression) a huge amount\n");
- rfbLog(" of extra memory (20-100MB) is used on both the server and\n");
- rfbLog(" client sides. This mode works with any VNC viewer.\n");
- rfbLog(" However, in most you can actually see the cached pixel\n");
- rfbLog(" data by scrolling down, so you need to re-adjust its size.\n");
- rfbLog(" See http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching.\n");
- rfbLog(" If this mode yields undesired behavior (poor response,\n");
- rfbLog(" painting errors, etc) it may be disabled via: '-ncache 0'\n");
- rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row to \n");
- rfbLog(" repaint the screen, also see the -fixscreen option for\n");
- rfbLog(" periodic repaints.\n");
- if (scale_str) {
- rfbLog(" Note: '-scale' is on and this can cause more problems.\n");
- }
- }
- if (ncache && getenv("NCACHE_DEBUG")) {
- ncdb = 1;
- }
-
- /* check for OS with small shm limits */
- if (using_shm && ! single_copytile) {
- if (limit_shm()) {
- single_copytile = 1;
- }
- }
-
- single_copytile_orig = single_copytile;
-
- /* check for MIT-SHM */
- if (! XShmQueryExtension_wr(dpy)) {
- xshm_present = 0;
- if (! using_shm) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("info: display does not support XShm.\n");
- }
- } else {
- if (! quiet && ! raw_fb_str) {
- rfbLog("\n");
- rfbLog("warning: XShm extension is not available.\n");
- rfbLog("For best performance the X Display should be local. (i.e.\n");
- rfbLog("the x11vnc and X server processes should be running on\n");
- rfbLog("the same machine.)\n");
-#if LIBVNCSERVER_HAVE_XSHM
- rfbLog("Restart with -noshm to override this.\n");
- }
- exit(1);
-#else
- rfbLog("Switching to -noshm mode.\n");
- }
- using_shm = 0;
-#endif
- }
- } else {
-#if !NO_X11
- int op, ev, er;
- if (XQueryExtension(dpy, "MIT-SHM", &op, &ev, &er)) {
- xshm_opcode = op;
- if (0) fprintf(stderr, "xshm_opcode: %d %d %d\n", op, ev, er);
- }
-#endif
- }
-
-#if LIBVNCSERVER_HAVE_XKEYBOARD
- /* check for XKEYBOARD */
- initialize_xkb();
- initialize_watch_bell();
- if (!xkb_present && use_xkb_modtweak) {
- if (! quiet && ! raw_fb_str) {
- rfbLog("warning: disabling xkb modtweak. XKEYBOARD ext. not present.\n");
- }
- use_xkb_modtweak = 0;
- }
-#endif
-
- if (xkb_present && !use_xkb_modtweak && !got_noxkb) {
- if (use_modifier_tweak) {
- switch_to_xkb_if_better();
- }
- }
-
-#if LIBVNCSERVER_HAVE_LIBXRANDR
- if (! XRRQueryExtension(dpy, &xrandr_base_event_type, &er)) {
- if (xrandr && ! quiet && ! raw_fb_str) {
- rfbLog("Disabling -xrandr mode: display does not support X RANDR.\n");
- }
- xrandr_base_event_type = 0;
- xrandr = 0;
- xrandr_maybe = 0;
- xrandr_present = 0;
- } else {
- xrandr_present = 1;
- }
-#endif
-
- check_pm();
-
- if (! quiet && ! raw_fb_str) {
- rfbLog("--------------------------------------------------------\n");
- rfbLog("\n");
- }
-
- raw_fb_pass_go_and_collect_200_dollars:
-
- if (! dpy || raw_fb_str) {
- int doit = 0;
- /* XXX this needs improvement (esp. for remote control) */
- if (! raw_fb_str || strstr(raw_fb_str, "console") == raw_fb_str) {
-#ifdef MACOSX
- doit = 1;
-#endif
- }
- if (raw_fb_str && strstr(raw_fb_str, "vnc") == raw_fb_str) {
- doit = 1;
- }
- if (doit) {
- if (! multiple_cursors_mode) {
- multiple_cursors_mode = strdup("most");
- }
- initialize_cursors_mode();
- use_xdamage = orig_use_xdamage;
- if (use_xdamage) {
- xdamage_present = 1;
- initialize_xdamage();
- }
- }
- }
-
- if (! dt) {
- static char str[] = "-desktop";
- argv_vnc[argc_vnc++] = str;
- argv_vnc[argc_vnc++] = choose_title(use_dpy);
- rfb_desktop_name = strdup(argv_vnc[argc_vnc-1]);
- }
-
- /*
- * Create the XImage corresponding to the display framebuffer.
- */
-
- fb0 = initialize_xdisplay_fb();
-
- /*
- * In some cases (UINPUT touchscreens) we need the dpy_x dpy_y
- * to initialize pipeinput. So we do it after fb is created.
- */
- initialize_pipeinput();
-
- /*
- * n.b. we do not have to X_LOCK any X11 calls until watch_loop()
- * is called since we are single-threaded until then.
- */
-
- initialize_screen(&argc_vnc, argv_vnc, fb0);
-
- if (waited_for_client) {
- if (fake_fb) {
- free(fake_fb);
- fake_fb = NULL;
- }
- if (use_solid_bg && client_count) {
- solid_bg(0);
- }
- if (accept_cmd && strstr(accept_cmd, "popup") == accept_cmd) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl, cl0 = NULL;
- int i = 0;
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- i++;
- if (i != 1) {
- rfbLog("WAIT popup: too many clients\n");
- clean_up_exit(1);
- }
- cl0 = cl;
- }
- rfbReleaseClientIterator(iter);
- if (i != 1 || cl0 == NULL) {
- rfbLog("WAIT popup: no clients.\n");
- clean_up_exit(1);
- }
- if (! accept_client(cl0)) {
- rfbLog("WAIT popup: denied.\n");
- clean_up_exit(1);
- }
- rfbLog("waited_for_client: popup accepted.\n");
- cl0->onHold = FALSE;
- }
- if (macosx_console) {
- refresh_screen(1);
- }
- if (dpy && xdmcp_insert != NULL) {
-#if !NO_X11
- char c;
- int n = strlen(xdmcp_insert);
- KeyCode k, k2;
- KeySym sym;
- int i, ok = 1;
- for (i = 0; i < n; i++) {
- c = xdmcp_insert[i];
- sym = (KeySym) c;
- if (sym < ' ' || sym > 0x7f) {
- ok = 0;
- break;
- }
- k = XKeysymToKeycode(dpy, sym);
- if (k == NoSymbol) {
- ok = 0;
- break;
- }
- }
- if (ok) {
- XFlush_wr(dpy);
- usleep(2*1000*1000);
- if (!quiet) {
- rfbLog("sending XDM '%s'\n", xdmcp_insert);
- }
- for (i = 0; i < n; i++) {
- c = xdmcp_insert[i];
- sym = (KeySym) c;
- k = XKeysymToKeycode(dpy, sym);
- if (isupper(c)) {
- k2 = XKeysymToKeycode(dpy, XK_Shift_L);
- XTestFakeKeyEvent_wr(dpy, k2, True, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- }
- if (0) fprintf(stderr, "C/k %c/%x\n", c, k);
- XTestFakeKeyEvent_wr(dpy, k, True, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- XTestFakeKeyEvent_wr(dpy, k, False, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- if (isupper(c)) {
- k2 = XKeysymToKeycode(dpy, XK_Shift_L);
- XTestFakeKeyEvent_wr(dpy, k2, False, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- }
- }
- k2 = XKeysymToKeycode(dpy, XK_Tab);
- XTestFakeKeyEvent_wr(dpy, k2, True, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- XTestFakeKeyEvent_wr(dpy, k2, False, CurrentTime);
- XFlush_wr(dpy);
- usleep(100*1000);
- }
- free(xdmcp_insert);
-#endif
- }
- check_redir_services();
- }
-
- if (! waited_for_client) {
- if (try_http && ! got_httpdir && check_httpdir()) {
- http_connections(1);
- }
- if (ssh_str != NULL) {
- ssh_remote_tunnel(ssh_str, screen->port);
- }
- }
-
- initialize_tiles();
-
- /* rectangular blackout regions */
- initialize_blackouts_and_xinerama();
-
- /* created shm or XImages when using_shm = 0 */
- initialize_polling_images();
-
- initialize_signals();
-
- initialize_speeds();
-
- if (speeds_read_rate_measured > 80) {
- /* framebuffer read is fast at > 80 MB/sec */
- int same = 0;
- if (waitms == defer_update) {
- same = 1;
- }
- if (! got_waitms) {
- waitms /= 2;
- if (waitms < 5) {
- waitms = 5;
- }
- if (!quiet) {
- rfbLog("fast read: reset -wait ms to: %d\n", waitms);
- }
- }
- if (! got_deferupdate && ! got_defer) {
- if (defer_update > 10) {
- if (same) {
- defer_update = waitms;
- } else {
- defer_update = 10;
- }
- if (screen) {
- screen->deferUpdateTime = defer_update;
- }
- rfbLog("fast read: reset -defer ms to: %d\n", defer_update);
- }
- }
- }
-
- initialize_keyboard_and_pointer();
-
- if (inetd && use_openssl) {
- if (! waited_for_client) {
- accept_openssl(OPENSSL_INETD, -1);
- }
- }
- if (! inetd && ! use_openssl) {
- if (! screen->port || screen->listenSock < 0) {
- if (got_rfbport && got_rfbport_val == 0) {
- ;
- } else if (ipv6_listen && ipv6_listen_fd >= 0) {
- rfbLog("Info: listening only on IPv6 interface.\n");
- } else {
- rfbLogEnable(1);
- rfbLog("Error: could not obtain listening port.\n");
- if (!got_rfbport && !got_ipv6_listen) {
- rfbLog("If this system is IPv6-only, use the -6 option.\n");
- }
- clean_up_exit(1);
- }
- }
- }
-
-#ifdef MACOSX
- if (remote_cmd || query_cmd) {
- ;
- } else if (macosx_console) {
- double dt = dnow();
- copy_screen();
- dt = dnow() - dt;
- rfbLog("macosx_console: copied screen in %.3f sec %.1f MB/sec\n",
- dt, dpy_x * dpy_y * bpp / (1e+6 * 8 * dt));
-
- }
-#endif
-
- if (! quiet) {
- rfbLog("screen setup finished.\n");
- if (SHOW_NO_PASSWORD_WARNING && !nopw) {
- rfbLog("\n");
- rfbLog("WARNING: You are running x11vnc WITHOUT"
- " a password. See\n");
- rfbLog("WARNING: the warning message printed above"
- " for more info.\n");
- }
- }
- set_vnc_desktop_name();
-
- if (ncache_beta_tester && (ncache != 0 || ncache_msg)) {
- ncache_beta_tester_message();
- }
-
- if (remote_cmd || query_cmd) {
- /* This is DIRECT: case */
- do_remote_query(remote_cmd, query_cmd, remote_sync, query_default);
- if (getenv("SLEEP")) sleep(atoi(getenv("SLEEP")));
- clean_up_exit(0);
- }
-
-#if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SETSID
- if (bg) {
- int p, n;
- if (getenv("X11VNC_LOOP_MODE_BG")) {
- if (screen && screen->listenSock >= 0) {
- close(screen->listenSock);
- FD_CLR(screen->listenSock,&screen->allFds);
- screen->listenSock = -1;
- }
- if (screen && screen->httpListenSock >= 0) {
- close(screen->httpListenSock);
- screen->httpListenSock = -1;
- }
- if (openssl_sock >= 0) {
- close(openssl_sock);
- openssl_sock = -1;
- }
- if (https_sock >= 0) {
- close(https_sock);
- https_sock = -1;
- }
- if (openssl_sock6 >= 0) {
- close(openssl_sock6);
- openssl_sock6 = -1;
- }
- if (https_sock6 >= 0) {
- close(https_sock6);
- https_sock6 = -1;
- }
- if (ipv6_listen_fd >= 0) {
- close(ipv6_listen_fd);
- ipv6_listen_fd = -1;
- }
- if (ipv6_http_fd >= 0) {
- close(ipv6_http_fd);
- ipv6_http_fd = -1;
- }
- }
- /* fork into the background now */
- if ((p = fork()) > 0) {
- exit(0);
- } else if (p == -1) {
- rfbLogEnable(1);
- fprintf(stderr, "could not fork\n");
- perror("fork");
- clean_up_exit(1);
- }
- if (setsid() == -1) {
- rfbLogEnable(1);
- fprintf(stderr, "setsid failed\n");
- perror("setsid");
- clean_up_exit(1);
- }
- /* adjust our stdio */
- n = open("/dev/null", O_RDONLY);
- dup2(n, 0);
- dup2(n, 1);
- if (! logfile) {
- dup2(n, 2);
- }
- if (n > 2) {
- close(n);
- }
- }
-#endif
-
- watch_loop();
-
- return(0);
-
-#undef argc
-#undef argv
-
-}
-
diff --git a/x11vnc/x11vnc.desktop b/x11vnc/x11vnc.desktop
deleted file mode 100644
index b7a8ad2..0000000
--- a/x11vnc/x11vnc.desktop
+++ /dev/null
@@ -1,10 +0,0 @@
-[Desktop Entry]
-Name=X11VNC Server
-Comment=Share this desktop by VNC
-Exec=x11vnc -gui tray=setpass -rfbport PROMPT -bg -o %%HOME/.x11vnc.log.%%VNCDISPLAY
-Icon=computer
-Terminal=false
-Type=Application
-StartupNotify=false
-#StartupWMClass=x11vnc_port_prompt
-Categories=Network;RemoteAccess;
diff --git a/x11vnc/x11vnc.h b/x11vnc/x11vnc.h
deleted file mode 100644
index 015531d..0000000
--- a/x11vnc/x11vnc.h
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_X11VNC_H
-#define _X11VNC_X11VNC_H
-
-/* -- x11vnc.h -- */
-/*
- * These ' -- filename.[ch] -- ' comments represent a partial cleanup:
- * they are an odd way to indicate how this huge file would be split up
- * someday into multiple files.
- *
- * The primary reason we have not broken up this file is for user
- * convenience: those wanting to use the latest version download a single
- * file, x11vnc.c, and off they go...
- */
-
-/****************************************************************************/
-
-/* Standard includes and libvncserver */
-
-#include <unistd.h>
-#include <signal.h>
-#include <sys/utsname.h>
-#ifdef __hpux
-/* to avoid select() compiler warning */
-#include <sys/time.h>
-#endif
-#include <time.h>
-#include <errno.h>
-
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <ctype.h>
-
-#include <rfb/rfb.h>
-#include <rfb/rfbregion.h>
-
-
-/* we can now build under --without-x: */
-#if LIBVNCSERVER_HAVE_X11
-
-#define NO_X11 0
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-
-#else
-
-#define NO_X11 1
-#ifndef SKIP_NO_X11
-#include "nox11.h"
-#endif
-#include <rfb/keysym.h>
-
-#endif
-
-/****************************************************************************/
-
-
-/*
- * Build-time customization via CPPFLAGS.
- *
- * Summary of options to include in CPPFLAGS for custom builds:
- *
- * -DVNCSHARED to have the vnc display shared by default.
- * -DFOREVER to have -forever on by default.
- * -DNOREPEAT=0 to have -repeat on by default.
- * -DXINERAMA=0 to have -noxinerama on by default.
- * -DADDKEYSYMS=0 to have -noadd_keysyms the default.
- *
- * -DREMOTE_DEFAULT=0 to disable remote-control on by default (-yesremote).
- * -DREMOTE_CONTROL=0 to disable remote-control mechanism completely.
- * -DEXTERNAL_COMMANDS=0 to disable the running of all external commands.
- * -DTIGHTFILEXFER=0 disable tightfilexfer.
- *
- * -DHARDWIRE_PASSWD=... hardwired passwords, quoting necessary.
- * -DHARDWIRE_VIEWPASSWD=...
- * -DNOPW=1 make -nopw the default (skip warning)
- * -DUSEPW=1 make -usepw the default
- * -DPASSWD_REQUIRED=1 exit unless a password is supplied.
- * -DPASSWD_UNLESS_NOPW=1 exit unless a password is supplied and no -nopw.
- *
- * -DCURSOR_DRAG=1 to have -cursor_drag as the default.
- * -DWIREFRAME=0 to have -nowireframe as the default.
- * -DWIREFRAME_COPYRECT=0 to have -nowirecopyrect as the default.
- * -DWIREFRAME_PARMS=... set default -wirecopyrect parameters.
- * -DSCROLL_COPYRECT=0 to have -noscrollcopyrect as the default.
- * -DSCROLL_COPYRECT_PARMS=... set default -scrollcopyrect parameters.
- * -DSCALING_COPYRECT=0
- * -DXDAMAGE=0 to have -noxdamage as the default.
- * -DSKIPDUPS=0 to have -noskip_dups as the default or vice versa.
- *
- * -DPOINTER_MODE_DEFAULT={0,1,2,3,4} set default -pointer_mode.
- * -DBOLDLY_CLOSE_DISPLAY=0 to not close X DISPLAY under -rawfb.
- * -DSMALL_FOOTPRINT=1 for smaller binary size (no help, no gui, etc)
- * use 2 or 3 for even smaller footprint.
- * -DNOGUI do not include the gui tkx11vnc.
- * -DSKIP_HELP=1 smaller.
- * -DSKIP_XKB=1 a little smaller.
- * -DSKIP_8to24=1 a little smaller.
- * -DPOLL_8TO24_DELAY=N
- * -DDEBUG_XEVENTS=1 enable printout for X events.
- *
- * -DX11VNC_MACOSX_USE_GETMAINDEVICE use deprecated GetMainDevice on macosx
- *
- * -DX11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS={0,1}
- * -DX11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS={0,1}
- * -DX11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER={0,1}
- *
- * or for all:
- *
- * -DX11VNC_MACOSX_NO_DEPRECATED=1
- *
- * env. var. of the same names as above can be set to imply true.
- *
- * Set these in CPPFLAGS before running configure. E.g.:
- *
- * % env CPPFLAGS="-DFOREVER -DREMOTE_CONTROL=0" ./configure
- * % make
- */
-
-/*
- * This can be used to disable the remote control mechanism.
- */
-#ifndef REMOTE_CONTROL
-#define REMOTE_CONTROL 1
-#endif
-
-#ifndef XINERAMA
-#define XINERAMA 1
-#endif
-
-#ifndef NOPW
-#define NOPW 0
-#endif
-
-#ifndef USEPW
-#define USEPW 0
-#endif
-
-#ifndef PASSWD_REQUIRED
-#define PASSWD_REQUIRED 0
-#endif
-
-#ifndef PASSWD_UNLESS_NOPW
-#define PASSWD_UNLESS_NOPW 0
-#endif
-
-/* some -D macros for building with old LibVNCServer */
-#ifndef LIBVNCSERVER_HAS_STATS
-#define LIBVNCSERVER_HAS_STATS 1
-#endif
-
-#ifndef LIBVNCSERVER_HAS_SHUTDOWNSOCKETS
-#define LIBVNCSERVER_HAS_SHUTDOWNSOCKETS 1
-#endif
-
-#ifndef LIBVNCSERVER_HAS_TEXTCHAT
-#define LIBVNCSERVER_HAS_TEXTCHAT 1
-#endif
-
-#ifdef PRE_0_8_LIBVNCSERVER
-#undef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
-#undef LIBVNCSERVER_HAS_STATS
-#undef LIBVNCSERVER_HAS_SHUTDOWNSOCKETS
-#undef LIBVNCSERVER_HAS_TEXTCHAT
-#define LIBVNCSERVER_HAS_STATS 0
-#define LIBVNCSERVER_HAS_SHUTDOWNSOCKETS 0
-#define LIBVNCSERVER_HAS_TEXTCHAT 0
-#endif
-
-/* these are for delaying features: */
-#define xxNO_NCACHE
-
-/*
- * Beginning of support for small binary footprint build for embedded
- * systems, PDA's etc. It currently just cuts out the low-hanging
- * fruit (large text passages). Set to 2, 3 to cut out some of the
- * more esoteric extensions. More tedious is to modify LDFLAGS in the
- * Makefile to not link against the extension libraries... but that
- * should be done too (manually for now).
- *
- * If there is interest more of the bloat can be removed... Currently
- * these shrink the binary from 1100K to about 600K.
- */
-#ifndef SMALL_FOOTPRINT
-#define SMALL_FOOTPRINT 0
-#endif
-
-#ifndef SKIP_XKB
-#define SKIP_XKB 0
-#endif
-#ifndef SKIP_8TO24
-#define SKIP_8TO24 0
-#endif
-#ifndef SKIP_HELP
-#define SKIP_HELP 0
-#endif
-
-#if SMALL_FOOTPRINT
-#undef NOGUI
-#define NOGUI
-#undef SKIP_HELP
-#define SKIP_HELP 1
-#endif
-
-#if (SMALL_FOOTPRINT > 1)
-#undef SKIP_XKB
-#undef SKIP_8TO24
-#undef LIBVNCSERVER_HAVE_LIBXINERAMA
-#undef LIBVNCSERVER_HAVE_LIBXFIXES
-#undef LIBVNCSERVER_HAVE_LIBXDAMAGE
-#define SKIP_XKB 1
-#define SKIP_8TO24 1
-#define LIBVNCSERVER_HAVE_LIBXINERAMA 0
-#define LIBVNCSERVER_HAVE_LIBXFIXES 0
-#define LIBVNCSERVER_HAVE_LIBXDAMAGE 0
-#endif
-
-#if (SMALL_FOOTPRINT > 2)
-#undef LIBVNCSERVER_HAVE_UTMPX_H
-#undef LIBVNCSERVER_HAVE_PWD_H
-#undef REMOTE_CONTROL
-#define LIBVNCSERVER_HAVE_UTMPX_H 0
-#define LIBVNCSERVER_HAVE_PWD_H 0
-#define REMOTE_CONTROL 0
-#endif
-
-#ifndef X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS
-#if X11VNC_MACOSX_NO_DEPRECATED
-#define X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS 1
-#else
-#define X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS 0
-#endif
-#endif
-
-#ifndef X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS
-#if X11VNC_MACOSX_NO_DEPRECATED
-#define X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS 1
-#else
-#define X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS 0
-#endif
-#endif
-
-#ifndef X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER
-#if X11VNC_MACOSX_NO_DEPRECATED
-#define X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER 1
-#else
-#define X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER 0
-#endif
-#endif
-
-/*
- * Not recommended unless you know what you are getting into, but if you
- * define the HARDWIRE_PASSWD or HARDWIRE_VIEWPASSWD variables here or in
- * CPPFLAGS you can set a default -passwd and -viewpasswd string values,
- * perhaps this would be better than nothing on an embedded system, etc.
- * These default values will be overridden by the command line.
- * We don't even give an example ;-)
- */
-
-/****************************************************************************/
-
-/* Extensions and related includes: */
-
-#if LIBVNCSERVER_HAVE_XSHM
-# if defined(__hpux) && defined(__ia64) /* something weird on hp/itanic */
-# undef _INCLUDE_HPUX_SOURCE
-# endif
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <X11/extensions/XShm.h>
-#endif
-#if LIBVNCSERVER_HAVE_SHMAT
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
-
-#include <dirent.h>
-
-#if LIBVNCSERVER_HAVE_XTEST
-#include <X11/extensions/XTest.h>
-#endif
-extern int xtest_base_event_type;
-
-#if LIBVNCSERVER_HAVE_LIBXTRAP
-#define NEED_EVENTS
-#define NEED_REPLIES
-#include <X11/extensions/xtraplib.h>
-#include <X11/extensions/xtraplibp.h>
-extern XETC *trap_ctx;
-#endif
-extern int xtrap_base_event_type;
-
-#if LIBVNCSERVER_HAVE_RECORD
-#include <X11/Xproto.h>
-#include <X11/extensions/record.h>
-#endif
-
-#if LIBVNCSERVER_HAVE_XKEYBOARD
-#include <X11/XKBlib.h>
-#endif
-
-#if LIBVNCSERVER_HAVE_LIBXINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-
-#if LIBVNCSERVER_HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#include <netdb.h>
-#ifndef _AIX
-extern int h_errno;
-#endif
-
-#if LIBVNCSERVER_HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#endif
-
-#ifndef SOL_IPV6
-#ifdef IPPROTO_IPV6
-#define SOL_IPV6 IPPROTO_IPV6
-#endif
-#endif
-
-#ifndef IPV6_V6ONLY
-#ifdef IPV6_BINDV6ONLY
-#define IPV6_V6ONLY IPV6_BINDV6ONLY
-#endif
-#endif
-
-#ifndef X11VNC_IPV6
-#if defined(AF_INET6)
-#define X11VNC_IPV6 1
-#else
-#define X11VNC_IPV6 0
-#endif
-#endif
-
-#ifndef X11VNC_LISTEN6
-#define X11VNC_LISTEN6 1
-#endif
-
-#if !X11VNC_IPV6
-#undef X11VNC_LISTEN6
-#define X11VNC_LISTEN6 0
-#endif
-
-#if LIBVNCSERVER_HAVE_PWD_H
-#include <pwd.h>
-#include <grp.h>
-#endif
-#if LIBVNCSERVER_HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-#if LIBVNCSERVER_HAVE_UTMPX_H
-#include <utmpx.h>
-#endif
-
-#if LIBVNCSERVER_HAVE_MMAP
-#include <sys/mman.h>
-#endif
-
-/*
- * overlay/multi-depth screen reading support
- * undef SOLARIS_OVERLAY or IRIX_OVERLAY if there are problems building.
- */
-
-/* solaris/sun */
-#if defined (__SVR4) && defined (__sun)
-# define SOLARIS
-# ifdef LIBVNCSERVER_HAVE_SOLARIS_XREADSCREEN
-# define SOLARIS_OVERLAY
-# define OVERLAY_OS
-# endif
-#endif
-
-#ifdef SOLARIS_OVERLAY
-#include <X11/extensions/transovl.h>
-#endif
-
-/* irix/sgi */
-#if defined(__sgi)
-# define IRIX
-# ifdef LIBVNCSERVER_HAVE_IRIX_XREADDISPLAY
-# define IRIX_OVERLAY
-# define OVERLAY_OS
-# endif
-#endif
-
-/*
- * For reference, the OS header defines:
- __SVR4 && __sun is solaris
- __sgi
- __hpux
- __osf__
- __OpenBSD__
- __FreeBSD__
- __NetBSD__
- __linux__
- (defined(__MACH__) && defined(__APPLE__))
- _AIX
- */
-#if (defined(__MACH__) && defined(__APPLE__))
-#define MACOSX
-#endif
-
-
-#ifdef IRIX_OVERLAY
-#include <X11/extensions/readdisplay.h>
-#endif
-
-extern int overlay_present;
-
-#if LIBVNCSERVER_HAVE_LIBXRANDR
-#include <X11/extensions/Xrandr.h>
-#endif
-extern int xrandr_base_event_type;
-
-#if LIBVNCSERVER_HAVE_LIBXFIXES
-#include <X11/extensions/Xfixes.h>
-#endif
-extern int xfixes_base_event_type;
-
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
-#include <X11/extensions/Xdamage.h>
-#endif
-extern int xdamage_base_event_type;
-
-#define RAWFB_RET(y) if (raw_fb && ! dpy) return y;
-#define RAWFB_RET_VOID if (raw_fb && ! dpy) return;
-
-extern char lastmod[];
-
-/* X display info */
-
-extern Display *dpy; /* the single display screen we connect to */
-extern int scr;
-extern char *xauth_raw_data;
-extern int xauth_raw_len;
-extern Window window, rootwin; /* polled window, root window (usu. same) */
-extern Visual *default_visual; /* the default visual (unless -visual) */
-extern int bpp, depth;
-extern int indexed_color;
-extern int dpy_x, dpy_y; /* size of display */
-extern int fb_x, fb_y, fb_b; /* fb size and bpp guesses at display */
-extern int off_x, off_y; /* offsets for -sid */
-extern int wdpy_x, wdpy_y; /* for actual sizes in case of -clip */
-extern int cdpy_x, cdpy_y, coff_x, coff_y; /* the -clip params */
-extern int button_mask; /* button state and info */
-extern int button_mask_prev;
-extern int num_buttons;
-
-extern long xselectinput_rootwin;
-
-extern unsigned int display_button_mask;
-extern unsigned int display_mod_mask;
-
-/* image structures */
-extern XImage *scanline;
-extern XImage *fullscreen;
-extern XImage **tile_row; /* for all possible row runs */
-extern XImage *snaprect; /* for XShmGetImage (fs_factor) */
-extern XImage *snap; /* the full snap fb */
-extern XImage *raw_fb_image; /* the raw fb */
-
-#if !LIBVNCSERVER_HAVE_XSHM
-/*
- * for simplicity, define this struct since we'll never use them
- * under using_shm = 0.
- */
-typedef struct {
- int shmid; char *shmaddr; Bool readOnly;
-} XShmSegmentInfo;
-#endif
-
-/* corresponding shm structures */
-extern XShmSegmentInfo scanline_shm;
-extern XShmSegmentInfo fullscreen_shm;
-extern XShmSegmentInfo *tile_row_shm; /* for all possible row runs */
-extern XShmSegmentInfo snaprect_shm;
-
-/* rfb screen info */
-extern rfbScreenInfoPtr screen;
-extern char *rfb_desktop_name;
-extern char *http_dir;
-extern char vnc_desktop_name[];
-extern char *main_fb; /* our copy of the X11 fb */
-extern char *rfb_fb; /* same as main_fb unless transformation */
-extern char *fake_fb; /* used under -padgeom */
-extern char *snap_fb; /* used under -snapfb */
-extern char *cmap8to24_fb; /* used under -8to24 */
-extern char *rot_fb; /* used under -rotate */
-extern char *raw_fb;
-extern char *raw_fb_addr;
-extern int raw_fb_offset;
-extern int raw_fb_shm;
-extern int raw_fb_mmap;
-extern int raw_fb_seek;
-extern int raw_fb_fd;
-extern int raw_fb_back_to_X;
-
-extern int raw_fb_native_bpp;
-extern int raw_fb_expand_bytes;
-extern unsigned long raw_fb_native_red_mask, raw_fb_native_green_mask, raw_fb_native_blue_mask;
-extern unsigned short raw_fb_native_red_max, raw_fb_native_green_max, raw_fb_native_blue_max;
-extern unsigned short raw_fb_native_red_shift, raw_fb_native_green_shift, raw_fb_native_blue_shift;
-
-extern int rfb_bytes_per_line;
-extern int main_bytes_per_line;
-extern int rot_bytes_per_line;
-extern unsigned long main_red_mask, main_green_mask, main_blue_mask;
-extern unsigned short main_red_max, main_green_max, main_blue_max;
-extern unsigned short main_red_shift, main_green_shift, main_blue_shift;
-
-extern int raw_fb_bytes_per_line; /* of actual raw region we poll, not our raw_fb */
-
-/* scaling parameters */
-extern char *scale_str;
-extern double scale_fac_x;
-extern double scale_fac_y;
-extern int scaling;
-extern int scaling_blend; /* for no blending option (very course) */
-extern int scaling_nomult4; /* do not require width = n * 4 */
-extern int scaling_pad; /* pad out scaled sizes to fit denominator */
-extern int scaling_interpolate; /* use interpolation scheme when shrinking */
-extern int scaled_x, scaled_y; /* dimensions of scaled display */
-extern int scale_numer, scale_denom; /* n/m */
-extern char *rotating_str;
-extern int rotating;
-extern int rotating_same;
-extern int rotating_cursors;
-
-/* scale cursor */
-extern char *scale_cursor_str;
-extern double scale_cursor_fac_x;
-extern double scale_cursor_fac_y;
-extern int scaling_cursor;
-extern int scaling_cursor_blend;
-extern int scaling_cursor_interpolate;
-extern int scale_cursor_numer, scale_cursor_denom;
-
-/* size of the basic tile unit that is polled for changes: */
-extern int tile_x;
-extern int tile_y;
-extern int ntiles, ntiles_x, ntiles_y;
-
-/* arrays that indicate changed or checked tiles. */
-extern unsigned char *tile_has_diff, *tile_tried, *tile_copied;
-extern unsigned char *tile_has_xdamage_diff, *tile_row_has_xdamage_diff;
-
-/* times of recent events */
-extern time_t last_event, last_input, last_client, last_open_xdisplay;
-extern time_t last_keyboard_input, last_pointer_input;
-extern time_t last_local_input; /* macosx */
-extern time_t last_fb_bytes_sent;
-extern double last_keyboard_time;
-extern double last_pointer_time;
-extern double last_pointer_click_time;
-extern double last_pointer_motion_time;
-extern double last_key_to_button_remap_time;
-extern double last_copyrect;
-extern double last_copyrect_fix;
-extern double last_wireframe;
-extern double servertime_diff;
-extern double x11vnc_start;
-extern double x11vnc_current;
-extern double g_now;
-
-extern double last_get_wm_frame_time;
-extern Window last_get_wm_frame;
-extern double last_bs_restore;
-extern double last_su_restore;
-extern double last_bs_save;
-extern double last_su_save;
-
-extern int hack_val;
-
-/* last client to move pointer */
-extern rfbClientPtr last_pointer_client;
-extern rfbClientPtr latest_client;
-extern double last_client_gone;
-extern double last_new_client;
-
-extern int waited_for_client;
-extern int findcreatedisplay;
-extern char *terminal_services_daemon;
-
-extern int client_count;
-extern int clients_served;
-extern int client_normal_count;
-
-/* more transient kludge variables: */
-extern int cursor_x, cursor_y; /* x and y from the viewer(s) */
-extern int button_change_x, button_change_y;
-extern int got_user_input;
-extern int got_pointer_input;
-extern int got_local_pointer_input;
-extern int got_pointer_calls;
-extern int got_keyboard_input;
-extern int got_keyboard_calls;
-extern int urgent_update;
-extern int last_keyboard_keycode;
-extern rfbBool last_rfb_down;
-extern rfbBool last_rfb_key_accepted;
-extern rfbKeySym last_rfb_keysym;
-extern double last_rfb_keytime;
-extern double last_rfb_key_injected;
-extern double last_rfb_ptr_injected;
-extern int fb_copy_in_progress;
-extern int drag_in_progress;
-extern int shut_down;
-extern int do_copy_screen;
-extern time_t damage_time;
-extern int damage_delay;
-
-extern int program_pid;
-extern char *program_name;
-extern char *program_cmdline;
-
-extern struct utsname UT;
-
-typedef struct hint {
- /* location x, y, height, and width of a change-rectangle */
- /* (grows as adjacent horizontal tiles are glued together) */
- int x, y, w, h;
-} hint_t;
-
-/* struct with client specific data: */
-#define CILEN 10
-typedef struct _ClientData {
- int uid;
- char *hostname;
- char *username;
- char *unixname;
- int client_port;
- int server_port;
- char *server_ip;
- char input[CILEN];
- int login_viewonly;
- time_t login_time;
-
- pid_t ssl_helper_pid;
-
- int had_cursor_shape_updates;
- int had_cursor_pos_updates;
-
- double timer;
- double send_cmp_rate;
- double send_raw_rate;
- double latency;
- int cmp_bytes_sent;
- int raw_bytes_sent;
-
-} ClientData;
-
-extern void nox11_exit(int rc);
-
-#include "params.h"
-#include "enums.h"
-#include "options.h"
-#include "util.h"
-
-#endif /* _X11VNC_X11VNC_H */
diff --git a/x11vnc/x11vnc_defs.c b/x11vnc/x11vnc_defs.c
deleted file mode 100644
index 8234aff..0000000
--- a/x11vnc/x11vnc_defs.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- x11vnc_defs.c -- */
-
-#include "x11vnc.h"
-
-int overlay_present = 0;
-
-int xrandr_base_event_type = 0;
-
-int xfixes_base_event_type = 0;
-int xtest_base_event_type = 0;
-#if LIBVNCSERVER_HAVE_LIBXTRAP
-XETC *trap_ctx = NULL;
-#endif
-int xtrap_base_event_type = 0;
-int xdamage_base_event_type = 0;
-
-/* date +'lastmod: %Y-%m-%d' */
-char lastmod[] = "0.9.13 lastmod: 2010-12-27";
-
-/* X display info */
-
-Display *dpy = NULL; /* the single display screen we connect to */
-int scr = 0;
-char *xauth_raw_data = NULL;
-int xauth_raw_len = 0;
-Window window = None, rootwin = None; /* polled window, root window (usu. same) */
-Visual *default_visual = NULL; /* the default visual (unless -visual) */
-int bpp = 0, depth = 0;
-int indexed_color = 0;
-int dpy_x = 0, dpy_y = 0; /* size of display */
-int fb_x = 0, fb_y = 0, fb_b = 0; /* fb size and bpp guesses at display */
-int off_x, off_y; /* offsets for -sid */
-int wdpy_x, wdpy_y; /* for actual sizes in case of -clip */
-int cdpy_x, cdpy_y, coff_x, coff_y; /* the -clip params */
-int button_mask = 0; /* button state and info */
-int button_mask_prev = 0;
-int num_buttons = -1;
-
-long xselectinput_rootwin = 0;
-
-unsigned int display_button_mask = 0;
-unsigned int display_mod_mask = 0;
-
-/* image structures */
-XImage *scanline = NULL;
-XImage *fullscreen = NULL;
-XImage **tile_row = NULL; /* for all possible row runs */
-XImage *snaprect = NULL; /* for XShmGetImage (fs_factor) */
-XImage *snap = NULL; /* the full snap fb */
-XImage *raw_fb_image = NULL; /* the raw fb */
-
-/* corresponding shm structures */
-XShmSegmentInfo scanline_shm;
-XShmSegmentInfo fullscreen_shm;
-XShmSegmentInfo *tile_row_shm; /* for all possible row runs */
-XShmSegmentInfo snaprect_shm;
-
-/* rfb screen info */
-rfbScreenInfoPtr screen = NULL;
-char *rfb_desktop_name = NULL;
-char *http_dir = NULL;
-char vnc_desktop_name[256];
-char *main_fb = NULL; /* our copy of the X11 fb */
-char *rfb_fb = NULL; /* same as main_fb unless transformation */
-char *fake_fb = NULL; /* used under -padgeom */
-char *snap_fb = NULL; /* used under -snapfb */
-char *cmap8to24_fb = NULL; /* used under -8to24 */
-char *rot_fb = NULL;
-char *raw_fb = NULL; /* when used should be main_fb */
-char *raw_fb_addr = NULL;
-int raw_fb_offset = 0;
-int raw_fb_shm = 0;
-int raw_fb_mmap = 0;
-int raw_fb_seek = 0;
-int raw_fb_fd = -1;
-int raw_fb_back_to_X = 0; /* kludge for testing rawfb -> 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;
-unsigned long main_red_mask = 0, main_green_mask = 0, main_blue_mask = 0;
-unsigned short main_red_max = 0, main_green_max = 0, main_blue_max = 0;
-unsigned short main_red_shift = 0, main_green_shift = 0, main_blue_shift = 0;
-
-int raw_fb_bytes_per_line = 0;
-
-/* scaling parameters */
-char *scale_str = NULL;
-double scale_fac_x = 1.0;
-double scale_fac_y = 1.0;
-int scaling = 0;
-int scaling_blend = 1; /* for no blending option (very course) */
-int scaling_nomult4 = 0; /* do not require width = n * 4 */
-int scaling_pad = 0; /* pad out scaled sizes to fit denominator */
-int scaling_interpolate = 0; /* use interpolation scheme when shrinking */
-int scaled_x = 0, scaled_y = 0; /* dimensions of scaled display */
-int scale_numer = 0, scale_denom = 0; /* n/m */
-char *rotating_str = NULL;
-int rotating = 0;
-int rotating_same = 0;
-int rotating_cursors = 0;
-
-/* scale cursor */
-char *scale_cursor_str = NULL;
-double scale_cursor_fac_x = 1.0;
-double scale_cursor_fac_y = 1.0;
-int scaling_cursor = 0;
-int scaling_cursor_blend = 1;
-int scaling_cursor_interpolate = 0;
-int scale_cursor_numer = 0, scale_cursor_denom = 0;
-
-/* size of the basic tile unit that is polled for changes: */
-int tile_x = 32;
-int tile_y = 32;
-int ntiles, ntiles_x = 0, ntiles_y = 0;
-
-/* arrays that indicate changed or checked tiles. */
-unsigned char *tile_has_diff = NULL, *tile_tried = NULL, *tile_copied = NULL;
-unsigned char *tile_has_xdamage_diff = NULL, *tile_row_has_xdamage_diff = NULL;
-
-/* times of recent events */
-time_t last_event = 0, last_input = 0, last_client = 0, last_open_xdisplay = 0;
-time_t last_local_input = 0;
-time_t last_keyboard_input = 0, last_pointer_input = 0;
-time_t last_fb_bytes_sent = 0;
-double last_keyboard_time = 0.0;
-double last_pointer_time = 0.0;
-double last_pointer_click_time = 0.0;
-double last_pointer_motion_time = 0.0;
-double last_key_to_button_remap_time = 0.0;
-double last_copyrect = 0.0;
-double last_copyrect_fix = 0.0;
-double last_wireframe = 0.0;
-double servertime_diff = 0.0;
-double x11vnc_start = 0.0;
-double x11vnc_current = 0.0;
-double g_now = 0.0;
-
-double last_get_wm_frame_time = 0.0;
-Window last_get_wm_frame = None;
-double last_bs_restore = 0.0;
-double last_su_restore = 0.0;
-double last_bs_save = 0.0;
-double last_su_save = 0.0;
-
-int hack_val = 0;
-
-/* last client to move pointer */
-rfbClientPtr last_pointer_client = NULL;
-rfbClientPtr latest_client = NULL;
-double last_client_gone = 0.0;
-double last_new_client = 0.0;
-
-int waited_for_client = 0;
-int findcreatedisplay = 0;
-char *terminal_services_daemon = NULL;
-
-int client_count = 0;
-int clients_served = 0;
-int client_normal_count = 0;
-
-/* more transient kludge variables: */
-int cursor_x = 0, cursor_y = 0; /* x and y from the viewer(s) */
-int button_change_x = 0, button_change_y = 0;
-int got_user_input = 0;
-int got_pointer_input = 0;
-int got_local_pointer_input = 0;
-int got_pointer_calls = 0;
-int got_keyboard_input = 0;
-int got_keyboard_calls = 0;
-int urgent_update = 0;
-int last_keyboard_keycode = 0;
-rfbBool last_rfb_down = FALSE;
-rfbBool last_rfb_key_accepted = FALSE;
-rfbKeySym last_rfb_keysym = 0;
-double last_rfb_keytime = 0.0;
-double last_rfb_key_injected = 0.0;
-double last_rfb_ptr_injected = 0.0;
-int fb_copy_in_progress = 0;
-int drag_in_progress = 0;
-int shut_down = 0;
-int do_copy_screen = 0;
-time_t damage_time = 0;
-int damage_delay = 0;
-
-int program_pid = 0;
-char *program_name = NULL;
-char *program_cmdline = NULL;
-
-struct utsname UT;
-
-
diff --git a/x11vnc/xdamage.c b/x11vnc/xdamage.c
deleted file mode 100644
index 3eb12f5..0000000
--- a/x11vnc/xdamage.c
+++ /dev/null
@@ -1,840 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- xdamage.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "userinput.h"
-#include "unixpw.h"
-
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
-Damage xdamage = 0;
-#endif
-
-#ifndef XDAMAGE
-#define XDAMAGE 1
-#endif
-int use_xdamage = XDAMAGE; /* use the xdamage rects for scanline hints */
-int xdamage_present = 0;
-
-#ifdef MACOSX
-int xdamage_max_area = 50000;
-#else
-int xdamage_max_area = 20000; /* pixels */
-#endif
-
-double xdamage_memory = 1.0; /* in units of NSCAN */
-int xdamage_tile_count = 0, xdamage_direct_count = 0;
-double xdamage_scheduled_mark = 0.0;
-double xdamage_crazy_time = 0.0;
-double xdamage_crazy_delay = 300.0;
-sraRegionPtr xdamage_scheduled_mark_region = NULL;
-sraRegionPtr *xdamage_regions = NULL;
-int xdamage_ticker = 0;
-int XD_skip = 0, XD_tot = 0, XD_des = 0; /* for stats */
-
-void add_region_xdamage(sraRegionPtr new_region);
-void clear_xdamage_mark_region(sraRegionPtr markregion, int flush);
-int collect_non_X_xdamage(int x_in, int y_in, int w_in, int h_in, int call);
-int collect_xdamage(int scancnt, int call);
-int xdamage_hint_skip(int y);
-void initialize_xdamage(void);
-void create_xdamage_if_needed(int force);
-void destroy_xdamage_if_needed(void);
-void check_xdamage_state(void);
-
-static void record_desired_xdamage_rect(int x, int y, int w, int h);
-
-
-static void record_desired_xdamage_rect(int x, int y, int w, int h) {
- /*
- * Unfortunately we currently can't trust an xdamage event
- * to correspond to real screen damage. E.g. focus-in for
- * mozilla (depending on wm) will mark the whole toplevel
- * area as damaged, when only the border has changed.
- * Similar things for terminal windows.
- *
- * This routine uses some heuristics to detect small enough
- * damage regions that we will not have a performance problem
- * if we believe them even though they are wrong. We record
- * the corresponding tiles the damage regions touch.
- */
- int dt_x, dt_y, nt_x1, nt_y1, nt_x2, nt_y2, nt;
- int ix, iy, cnt = 0;
- int area = w*h, always_accept = 0;
- /*
- * XXX: not working yet, slow and overlaps with scan_display()
- * probably slow because tall skinny rectangles very inefficient
- * in general and in direct_fb_copy() (100X slower then horizontal).
- */
- int use_direct_fb_copy = 0;
- int wh_min, wh_max;
- static int first = 1, udfb = 0;
-
- /* compiler warning: */
- nt_x1 = 0; nt_y1 = 0; nt_x2 = 0; nt_y2 = 0;
-
- if (first) {
- if (getenv("XD_DFC")) {
- udfb = 1;
- }
- first = 0;
- }
- if (udfb) {
- use_direct_fb_copy = 1;
- }
-
- if (xdamage_max_area <= 0) {
- always_accept = 1;
- }
-
- if (!always_accept && area > xdamage_max_area) {
- return;
- }
-
- dt_x = w / tile_x;
- dt_y = h / tile_y;
-
- if (w < h) {
- wh_min = w;
- wh_max = h;
- } else {
- wh_min = h;
- wh_max = w;
- }
-
- if (!always_accept && dt_y >= 3 && area > 4000) {
- /*
- * if it is real it should be caught by a normal scanline
- * poll, but we might as well keep if small (tall line?).
- */
- return;
- }
-
- if (use_direct_fb_copy) {
- X_UNLOCK;
- direct_fb_copy(x, y, x + w, y + h, 1);
- xdamage_direct_count++;
- X_LOCK;
- } else if (0 && wh_min < tile_x/4 && wh_max > 30 * wh_min) {
- /* try it for long, skinny rects, XXX still no good */
- X_UNLOCK;
- direct_fb_copy(x, y, x + w, y + h, 1);
- xdamage_direct_count++;
- X_LOCK;
- } else {
-
- if (ntiles_x == 0 || ntiles_y == 0) {
- /* too early. */
- return;
- }
- nt_x1 = nfix( (x)/tile_x, ntiles_x);
- nt_x2 = nfix((x+w)/tile_x, ntiles_x);
- nt_y1 = nfix( (y)/tile_y, ntiles_y);
- nt_y2 = nfix((y+h)/tile_y, ntiles_y);
-
- /*
- * loop over the rectangle of tiles (1 tile for a small
- * input rect).
- */
- for (ix = nt_x1; ix <= nt_x2; ix++) {
- for (iy = nt_y1; iy <= nt_y2; iy++) {
- nt = ix + iy * ntiles_x;
- cnt++;
- if (! tile_has_xdamage_diff[nt]) {
- XD_des++;
- tile_has_xdamage_diff[nt] = 1;
- }
- /* not used: */
- tile_row_has_xdamage_diff[iy] = 1;
- xdamage_tile_count++;
- }
- }
- }
- if (debug_xdamage > 1) {
- fprintf(stderr, "xdamage: desired: %dx%d+%d+%d\tA: %6d tiles="
- "%02d-%02d/%02d-%02d tilecnt: %d\n", w, h, x, y,
- w * h, nt_x1, nt_x2, nt_y1, nt_y2, cnt);
- }
-}
-
-void add_region_xdamage(sraRegionPtr new_region) {
- sraRegionPtr reg;
- int prev_tick, nreg;
-
- if (! xdamage_regions) {
- return;
- }
-
- nreg = (xdamage_memory * NSCAN) + 1;
- prev_tick = xdamage_ticker - 1;
- if (prev_tick < 0) {
- prev_tick = nreg - 1;
- }
-
- reg = xdamage_regions[prev_tick];
- if (reg != NULL && new_region != NULL) {
-if (debug_xdamage > 1) fprintf(stderr, "add_region_xdamage: prev_tick: %d reg %p new_region %p\n", prev_tick, (void *)reg, (void *)new_region);
- sraRgnOr(reg, new_region);
- }
-}
-
-void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) {
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- XEvent ev;
- sraRegionPtr tmpregion;
- int count = 0;
-
- RAWFB_RET_VOID
-
- if (! xdamage_present || ! use_xdamage) {
- return;
- }
- if (! xdamage) {
- return;
- }
- if (! xdamage_base_event_type) {
- return;
- }
- if (unixpw_in_progress) return;
-
- X_LOCK;
- if (flush) {
- XFlush_wr(dpy);
- }
- while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
- count++;
- }
- /* clear the whole damage region */
- XDamageSubtract(dpy, xdamage, None, None);
- X_UNLOCK;
-
- if (debug_tiles || debug_xdamage) {
- fprintf(stderr, "clear_xdamage_mark_region: %d\n", count);
- }
-
- if (! markregion) {
- /* NULL means mark the whole display */
- tmpregion = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- add_region_xdamage(tmpregion);
- sraRgnDestroy(tmpregion);
- } else {
- add_region_xdamage(markregion);
- }
-#else
- if (0) flush++; /* compiler warnings */
- if (0) markregion = NULL;
-#endif
-}
-
-int collect_non_X_xdamage(int x_in, int y_in, int w_in, int h_in, int call) {
- sraRegionPtr tmpregion;
- sraRegionPtr reg;
- static int rect_count = 0;
- int nreg, ccount = 0, dcount = 0, ecount = 0;
- static time_t last_rpt = 0;
- time_t now;
- double tm, dt;
- int x, y, w, h, x2, y2;
-
-if (call && debug_xdamage > 1) fprintf(stderr, "collect_non_X_xdamage: %d %d %d %d - %d / %d\n", x_in, y_in, w_in, h_in, call, use_xdamage);
-
- if (! use_xdamage) {
- return 0;
- }
- if (! xdamage_regions) {
- return 0;
- }
-
- dtime0(&tm);
-
- nreg = (xdamage_memory * NSCAN) + 1;
-
- if (call == 0) {
- xdamage_ticker = (xdamage_ticker+1) % nreg;
- xdamage_direct_count = 0;
- reg = xdamage_regions[xdamage_ticker];
- if (reg != NULL) {
- sraRgnMakeEmpty(reg);
- }
- } else {
- if (xdamage_ticker < 0) {
- xdamage_ticker = 0;
- }
- reg = xdamage_regions[xdamage_ticker];
- }
- if (reg == NULL) {
- return 0;
- }
-
- if (x_in < 0) {
- return 0;
- }
-
-
- x = x_in;
- y = y_in;
- w = w_in;
- h = h_in;
-
- /* translate if needed */
- if (clipshift) {
- /* set coords relative to fb origin */
- if (0 && rootshift) {
- /*
- * Note: not needed because damage is
- * relative to subwin, not rootwin.
- */
- x = x - off_x;
- y = y - off_y;
- }
- if (clipshift) {
- x = x - coff_x;
- y = y - coff_y;
- }
-
- x2 = x + w; /* upper point */
- x = nfix(x, dpy_x); /* place both in fb area */
- x2 = nfix(x2, dpy_x+1);
- w = x2 - x; /* recompute w */
-
- y2 = y + h;
- y = nfix(y, dpy_y);
- y2 = nfix(y2, dpy_y+1);
- h = y2 - y;
-
- if (w <= 0 || h <= 0) {
- return 0;
- }
- }
- if (debug_xdamage > 2) {
- fprintf(stderr, "xdamage: -> event %dx%d+%d+%d area:"
- " %d dups: %d %s reg: %p\n", w, h, x, y, w*h, dcount,
- (w*h > xdamage_max_area) ? "TOO_BIG" : "", (void *)reg);
- }
-
- record_desired_xdamage_rect(x, y, w, h);
-
- tmpregion = sraRgnCreateRect(x, y, x + w, y + h);
- sraRgnOr(reg, tmpregion);
- sraRgnDestroy(tmpregion);
- rect_count++;
- ccount++;
-
- if (0 && xdamage_direct_count) {
- fb_push();
- }
-
- dt = dtime(&tm);
- if ((debug_tiles > 1 && ecount) || (debug_tiles && ecount > 200)
- || debug_xdamage > 1) {
- fprintf(stderr, "collect_non_X_xdamage(%d): %.4f t: %.4f ev/dup/accept"
- "/direct %d/%d/%d/%d\n", call, dt, tm - x11vnc_start, ecount,
- dcount, ccount, xdamage_direct_count);
- }
- now = time(NULL);
- if (! last_rpt) {
- last_rpt = now;
- }
- if (now > last_rpt + 15) {
- double rat = -1.0;
-
- if (XD_tot) {
- rat = ((double) XD_skip)/XD_tot;
- }
- if (debug_tiles || debug_xdamage) {
- fprintf(stderr, "xdamage: == scanline skip/tot: "
- "%04d/%04d =%.3f rects: %d desired: %d\n",
- XD_skip, XD_tot, rat, rect_count, XD_des);
- }
-
- XD_skip = 0;
- XD_tot = 0;
- XD_des = 0;
- rect_count = 0;
- last_rpt = now;
- }
- return 0;
-}
-
-int collect_xdamage(int scancnt, int call) {
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- XDamageNotifyEvent *dev;
- XEvent ev;
- sraRegionPtr tmpregion;
- sraRegionPtr reg;
- static int rect_count = 0;
- int nreg, ccount = 0, dcount = 0, ecount = 0;
- static time_t last_rpt = 0;
- time_t now;
- int x, y, w, h, x2, y2;
- int i, dup, next = 0, dup_max = 0;
-#define DUPSZ 32
- int dup_x[DUPSZ], dup_y[DUPSZ], dup_w[DUPSZ], dup_h[DUPSZ];
- double tm, dt;
- int mark_all = 0, retries = 0, too_many = 1000, tot_ev = 0;
-
- RAWFB_RET(0)
-
- if (scancnt) {} /* unused vars warning: */
-
- if (! xdamage_present || ! use_xdamage) {
- return 0;
- }
- if (! xdamage) {
- return 0;
- }
- if (! xdamage_base_event_type) {
- return 0;
- }
- if (! xdamage_regions) {
- return 0;
- }
-
- dtime0(&tm);
-
- nreg = (xdamage_memory * NSCAN) + 1;
-
- if (call == 0) {
- xdamage_ticker = (xdamage_ticker+1) % nreg;
- xdamage_direct_count = 0;
- reg = xdamage_regions[xdamage_ticker];
- if (reg != NULL) {
- sraRgnMakeEmpty(reg);
- }
- } else {
- if (xdamage_ticker < 0) {
- xdamage_ticker = 0;
- }
- reg = xdamage_regions[xdamage_ticker];
- }
- if (reg == NULL) {
- return 0;
- }
-
-
- X_LOCK;
-if (0) XFlush_wr(dpy);
-if (0) XEventsQueued(dpy, QueuedAfterFlush);
-
- come_back_for_more:
-
- while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
- /*
- * TODO max cut off time in this loop?
- * Could check QLength and if huge just mark the whole
- * screen.
- */
- ecount++;
- tot_ev++;
-
- if (mark_all) {
- continue;
- }
- if (ecount == too_many) {
- int nqa = XEventsQueued(dpy, QueuedAlready);
- if (nqa >= too_many) {
- static double last_msg = 0.0;
- tmpregion = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- sraRgnOr(reg, tmpregion);
- sraRgnDestroy(tmpregion);
- if (dnow() > last_msg + xdamage_crazy_delay) {
- rfbLog("collect_xdamage: too many xdamage events %d+%d\n", ecount, nqa);
- last_msg = dnow();
- }
- mark_all = 1;
- }
- }
-
- if (ev.type != xdamage_base_event_type + XDamageNotify) {
- break;
- }
- dev = (XDamageNotifyEvent *) &ev;
- if (dev->damage != xdamage) {
- continue; /* not ours! */
- }
-
- x = dev->area.x;
- y = dev->area.y;
- w = dev->area.width;
- h = dev->area.height;
-
- /*
- * we try to manually remove some duplicates because
- * certain activities can lead to many 10's of dups
- * in a row. The region work can be costly and reg is
- * later used in xdamage_hint_skip loops, so it is good
- * to skip them if possible.
- */
- dup = 0;
- for (i=0; i < dup_max; i++) {
- if (dup_x[i] == x && dup_y[i] == y && dup_w[i] == w &&
- dup_h[i] == h) {
- dup = 1;
- break;
- }
- }
- if (dup) {
- dcount++;
- continue;
- }
- if (dup_max < DUPSZ) {
- next = dup_max;
- dup_max++;
- } else {
- next = (next+1) % DUPSZ;
- }
- dup_x[next] = x;
- dup_y[next] = y;
- dup_w[next] = w;
- dup_h[next] = h;
-
- /* translate if needed */
- if (clipshift) {
- /* set coords relative to fb origin */
- if (0 && rootshift) {
- /*
- * Note: not needed because damage is
- * relative to subwin, not rootwin.
- */
- x = x - off_x;
- y = y - off_y;
- }
- if (clipshift) {
- x = x - coff_x;
- y = y - coff_y;
- }
-
- x2 = x + w; /* upper point */
- x = nfix(x, dpy_x); /* place both in fb area */
- x2 = nfix(x2, dpy_x+1);
- w = x2 - x; /* recompute w */
-
- y2 = y + h;
- y = nfix(y, dpy_y);
- y2 = nfix(y2, dpy_y+1);
- h = y2 - y;
-
- if (w <= 0 || h <= 0) {
- continue;
- }
- }
- if (debug_xdamage > 2) {
- fprintf(stderr, "xdamage: -> event %dx%d+%d+%d area:"
- " %d dups: %d %s\n", w, h, x, y, w*h, dcount,
- (w*h > xdamage_max_area) ? "TOO_BIG" : "");
- }
-
- record_desired_xdamage_rect(x, y, w, h);
-
- tmpregion = sraRgnCreateRect(x, y, x + w, y + h);
- sraRgnOr(reg, tmpregion);
- sraRgnDestroy(tmpregion);
- rect_count++;
- ccount++;
- }
-
- if (mark_all) {
- if (ecount + XEventsQueued(dpy, QueuedAlready) >= 3 * too_many && retries < 3) {
- retries++;
- XFlush_wr(dpy);
- usleep(20 * 1000);
- XFlush_wr(dpy);
- ecount = 0;
- goto come_back_for_more;
- }
- }
-
- /* clear the whole damage region for next time. XXX check */
- if (call == 1) {
- XDamageSubtract(dpy, xdamage, None, None);
- }
- X_UNLOCK;
-
- if (tot_ev > 20 * too_many) {
- rfbLog("collect_xdamage: xdamage has gone crazy (screensaver or game?) ev: %d ret: %d\n", tot_ev, retries);
- rfbLog("collect_xdamage: disabling xdamage for %d seconds.\n", (int) xdamage_crazy_delay);
- destroy_xdamage_if_needed();
- X_LOCK;
- XSync(dpy, False);
- while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
- ;
- }
- X_UNLOCK;
- xdamage_crazy_time = dnow();
- }
-
- if (0 && xdamage_direct_count) {
- fb_push();
- }
-
- dt = dtime(&tm);
- if ((debug_tiles > 1 && ecount) || (debug_tiles && ecount > 200)
- || debug_xdamage > 1) {
- fprintf(stderr, "collect_xdamage(%d): %.4f t: %.4f ev/dup/accept"
- "/direct %d/%d/%d/%d\n", call, dt, tm - x11vnc_start, ecount,
- dcount, ccount, xdamage_direct_count);
- }
- now = time(NULL);
- if (! last_rpt) {
- last_rpt = now;
- }
- if (now > last_rpt + 15) {
- double rat = -1.0;
-
- if (XD_tot) {
- rat = ((double) XD_skip)/XD_tot;
- }
- if (debug_tiles || debug_xdamage) {
- fprintf(stderr, "xdamage: == scanline skip/tot: "
- "%04d/%04d =%.3f rects: %d desired: %d\n",
- XD_skip, XD_tot, rat, rect_count, XD_des);
- }
-
- XD_skip = 0;
- XD_tot = 0;
- XD_des = 0;
- rect_count = 0;
- last_rpt = now;
- }
-#else
- if (0) scancnt++; /* compiler warnings */
- if (0) call++;
- if (0) record_desired_xdamage_rect(0, 0, 0, 0);
-#endif
- return 0;
-}
-
-int xdamage_hint_skip(int y) {
- static sraRegionPtr scanline = NULL;
- static sraRegionPtr tmpl_y = NULL;
- int fast_tmpl = 1;
- sraRegionPtr reg, tmpl;
- int ret, i, n, nreg;
-#ifndef NO_NCACHE
- static int ncache_no_skip = 0;
- static double last_ncache_no_skip = 0.0;
- static double last_ncache_no_skip_long = 0.0, ncache_fac = 0.25;
-#endif
-
- if (! xdamage_present || ! use_xdamage) {
- return 0; /* cannot skip */
- }
- if (! xdamage_regions) {
- return 0; /* cannot skip */
- }
-
- if (! scanline) {
- /* keep it around to avoid malloc etc, recreate */
- scanline = sraRgnCreate();
- }
- if (! tmpl_y) {
- tmpl_y = sraRgnCreateRect(0, 0, dpy_x, 1);
- }
-
- nreg = (xdamage_memory * NSCAN) + 1;
-
-#ifndef NO_NCACHE
- if (ncache > 0) {
- if (ncache_no_skip == 0) {
- double now = g_now;
- if (now > last_ncache_no_skip + 8.0) {
- ncache_no_skip = 1;
- } else if (now < last_bs_restore + 0.5) {
- ncache_no_skip = 1;
- } else if (now < last_su_restore + 0.5) {
- ncache_no_skip = 1;
- } else if (now < last_copyrect + 0.5) {
- ncache_no_skip = 1;
- }
- if (ncache_no_skip) {
- last_ncache_no_skip = dnow();
- if (now > last_ncache_no_skip_long + 60.0) {
- ncache_fac = 2.0;
- last_ncache_no_skip_long = now;
- } else {
- ncache_fac = 0.25;
- }
- return 0;
- }
- } else {
- if (ncache_no_skip++ >= ncache_fac*nreg + 4) {
- ncache_no_skip = 0;
- } else {
- return 0;
- }
- }
- }
-#endif
-
- if (fast_tmpl) {
- sraRgnOffset(tmpl_y, 0, y);
- tmpl = tmpl_y;
- } else {
- tmpl = sraRgnCreateRect(0, y, dpy_x, y+1);
- }
-
- ret = 1;
- for (i=0; i<nreg; i++) {
- /* go back thru the history starting at most recent */
- n = (xdamage_ticker + nreg - i) % nreg;
- reg = xdamage_regions[n];
- if (reg == NULL) {
- continue;
- }
- if (sraRgnEmpty(reg)) {
- /* checking for emptiness is very fast */
- continue;
- }
- sraRgnMakeEmpty(scanline);
- sraRgnOr(scanline, tmpl);
- if (sraRgnAnd(scanline, reg)) {
- ret = 0;
- break;
- }
- }
- if (fast_tmpl) {
- sraRgnOffset(tmpl_y, 0, -y);
- } else {
- sraRgnDestroy(tmpl);
- }
-if (0) fprintf(stderr, "xdamage_hint_skip: %d -> %d\n", y, ret);
-
- return ret;
-}
-
-void initialize_xdamage(void) {
- sraRegionPtr *ptr;
- int i, nreg;
-
- if (! xdamage_present) {
- use_xdamage = 0;
- }
- if (xdamage_regions) {
- ptr = xdamage_regions;
- while (*ptr != NULL) {
- sraRgnDestroy(*ptr);
- ptr++;
- }
- free(xdamage_regions);
- xdamage_regions = NULL;
- }
- if (use_xdamage) {
- nreg = (xdamage_memory * NSCAN) + 2;
- xdamage_regions = (sraRegionPtr *)
- malloc(nreg * sizeof(sraRegionPtr));
- for (i = 0; i < nreg; i++) {
- ptr = xdamage_regions+i;
- if (i == nreg - 1) {
- *ptr = NULL;
- } else {
- *ptr = sraRgnCreate();
- sraRgnMakeEmpty(*ptr);
- }
- }
- /* set so will be 0 in first collect_xdamage call */
- xdamage_ticker = -1;
- }
-}
-
-void create_xdamage_if_needed(int force) {
-
- RAWFB_RET_VOID
-
- if (force) {}
-
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- if (! xdamage || force) {
- X_LOCK;
- xdamage = XDamageCreate(dpy, window, XDamageReportRawRectangles);
- XDamageSubtract(dpy, xdamage, None, None);
- X_UNLOCK;
- rfbLog("created xdamage object: 0x%lx\n", xdamage);
- }
-#endif
-}
-
-void destroy_xdamage_if_needed(void) {
-
- RAWFB_RET_VOID
-
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- if (xdamage) {
- XEvent ev;
- X_LOCK;
- XDamageDestroy(dpy, xdamage);
- XFlush_wr(dpy);
- if (xdamage_base_event_type) {
- while (XCheckTypedEvent(dpy,
- xdamage_base_event_type+XDamageNotify, &ev)) {
- ;
- }
- }
- X_UNLOCK;
- rfbLog("destroyed xdamage object: 0x%lx\n", xdamage);
- xdamage = 0;
- }
-#endif
-}
-
-void check_xdamage_state(void) {
- if (! xdamage_present) {
- return;
- }
- /*
- * Create or destroy the Damage object as needed, we don't want
- * one if no clients are connected.
- */
- if (xdamage_crazy_time > 0.0 && dnow() < xdamage_crazy_time + xdamage_crazy_delay) {
- return;
- }
- if (client_count && use_xdamage) {
- create_xdamage_if_needed(0);
- if (xdamage_scheduled_mark > 0.0 && dnow() >
- xdamage_scheduled_mark) {
- if (xdamage_scheduled_mark_region) {
- mark_region_for_xdamage(
- xdamage_scheduled_mark_region);
- sraRgnDestroy(xdamage_scheduled_mark_region);
- xdamage_scheduled_mark_region = NULL;
- } else {
- mark_for_xdamage(0, 0, dpy_x, dpy_y);
- }
- xdamage_scheduled_mark = 0.0;
- }
- } else {
- destroy_xdamage_if_needed();
- }
-}
-
-
diff --git a/x11vnc/xdamage.h b/x11vnc/xdamage.h
deleted file mode 100644
index 9919b7d..0000000
--- a/x11vnc/xdamage.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_XDAMAGE_H
-#define _X11VNC_XDAMAGE_H
-
-/* -- xdamage.h -- */
-
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
-extern Damage xdamage;
-#endif
-extern int use_xdamage;
-extern int xdamage_present;
-extern int xdamage_max_area;
-extern double xdamage_memory;
-extern int xdamage_tile_count, xdamage_direct_count;
-extern double xdamage_scheduled_mark;
-extern double xdamage_crazy_time;
-extern double xdamage_crazy_delay;
-extern sraRegionPtr xdamage_scheduled_mark_region;
-extern sraRegionPtr *xdamage_regions;
-extern int xdamage_ticker;
-extern int XD_skip, XD_tot, XD_des;
-
-extern void add_region_xdamage(sraRegionPtr new_region);
-extern void clear_xdamage_mark_region(sraRegionPtr markregion, int flush);
-extern int collect_non_X_xdamage(int x_in, int y_in, int w_in, int h_in, int call);
-extern int collect_xdamage(int scancnt, int call);
-extern int xdamage_hint_skip(int y);
-extern void initialize_xdamage(void);
-extern void create_xdamage_if_needed(int force);
-extern void destroy_xdamage_if_needed(void);
-extern void check_xdamage_state(void);
-
-#endif /* _X11VNC_XDAMAGE_H */
diff --git a/x11vnc/xevents.c b/x11vnc/xevents.c
deleted file mode 100644
index 72b6515..0000000
--- a/x11vnc/xevents.c
+++ /dev/null
@@ -1,2175 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- xevents.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "xkb_bell.h"
-#include "xrandr.h"
-#include "xdamage.h"
-#include "xrecord.h"
-#include "selection.h"
-#include "keyboard.h"
-#include "cursor.h"
-#include "gui.h"
-#include "connections.h"
-#include "unixpw.h"
-#include "cleanup.h"
-#include "macosx.h"
-#include "screen.h"
-#include "pm.h"
-#include "pointer.h"
-#include "remote.h"
-#include "inet.h"
-
-/* XXX CHECK BEFORE RELEASE */
-int grab_buster = 0;
-int grab_kbd = 0;
-int grab_ptr = 0;
-int grab_always = 0;
-int ungrab_both = 0;
-int grab_local = 0;
-int sync_tod_delay = 20;
-
-void initialize_vnc_connect_prop(void);
-void initialize_x11vnc_remote_prop(void);
-void initialize_clipboard_atom(void);
-void spawn_grab_buster(void);
-void sync_tod_with_servertime(void);
-void check_keycode_state(void);
-void check_autorepeat(void);
-void set_prop_atom(Atom atom);
-void check_xevents(int reset);
-void xcut_receive(char *text, int len, rfbClientPtr cl);
-
-void kbd_release_all_keys(rfbClientPtr cl);
-void set_single_window(rfbClientPtr cl, int x, int y);
-void set_server_input(rfbClientPtr cl, int s);
-void set_text_chat(rfbClientPtr cl, int l, char *t);
-int get_keyboard_led_state_hook(rfbScreenInfoPtr s);
-int get_file_transfer_permitted(rfbClientPtr cl);
-void get_prop(char *str, int len, Atom prop, Window w);
-int guess_dm_gone(int t1, int t2);
-
-static void initialize_xevents(int reset);
-static void print_xevent_bases(void);
-static void bust_grab(int reset);
-static int process_watch(char *str, int parent, int db);
-static void grab_buster_watch(int parent, char *dstr);
-
-
-void initialize_vnc_connect_prop(void) {
- char *prop_str;
- vnc_connect_str[0] = '\0';
- RAWFB_RET_VOID
-#if !NO_X11
- prop_str = getenv("VNC_CONNECT");
- if (prop_str == NULL) {
- prop_str = "VNC_CONNECT";
- }
- vnc_connect_prop = XInternAtom(dpy, "VNC_CONNECT", False);
-#endif
-}
-
-void initialize_x11vnc_remote_prop(void) {
- char *prop_str;
- x11vnc_remote_str[0] = '\0';
- RAWFB_RET_VOID
-#if !NO_X11
- prop_str = getenv("X11VNC_REMOTE");
- if (prop_str == NULL) {
- prop_str = "X11VNC_REMOTE";
- }
- x11vnc_remote_prop = XInternAtom(dpy, prop_str, False);
-#endif
-}
-
-void initialize_clipboard_atom(void) {
- RAWFB_RET_VOID
-#if NO_X11
- return;
-#else
- clipboard_atom = XInternAtom(dpy, "CLIPBOARD", False);
- if (clipboard_atom == None) {
- if (! quiet) rfbLog("could not find atom CLIPBOARD\n");
- if (watch_clipboard) {
- watch_clipboard = 0;
- }
- if (set_clipboard) {
- set_clipboard = 0;
- }
- }
-#endif /* NO_X11 */
-}
-
-/*
- we observed these strings:
-
- 6 gdm_string: Gnome-power-manager
- 6 gdm_string: Gnome-session
- 6 gdm_string: Gnome-settings-daemon
- 6 gdm_string: Login Window
- 6 gdm_string: Notify-osd
- 6 gdm_string: Panel
- 12 gdm_string: Metacity
- 12 gdm_string: gnome-power-manager
- 12 gdm_string: gnome-session
- 12 gdm_string: gnome-settings-daemon
- 12 gdm_string: notify-osd
- 18 gdm_string: Gdm-simple-greeter
- 24 gdm_string: metacity
- 36 gdm_string: gdm-simple-greeter
-
- kdmgreet
- Kdmgreet
- */
-
-static int dm_string(char *str) {
- char *s = getenv("DEBUG_WM_RUNNING");
- if (str == NULL) {
- return 0;
- }
- if (str[0] == '\0') {
- return 0;
- }
- if (0) fprintf(stderr, "dm_string: %s\n", str);
- if (strstr(str, "gdm-") == str || strstr(str, "Gdm-") == str) {
- if (strstr(str, "-greeter") != NULL) {
- if (s) rfbLog("dm_string: %s\n", str);
- return 1;
- }
- }
- if (!strcmp(str, "kdmgreet") || !strcmp(str, "Kdmgreet")) {
- if (s) rfbLog("dm_string: %s\n", str);
- return 1;
- }
- return 0;
-}
-
-static int dm_still_running(void) {
-#if NO_X11
- return 0;
-#else
- Window r, parent;
- Window *winlist;
- unsigned int nc;
- int rc, i;
- static XClassHint *classhint = NULL;
- XErrorHandler old_handler;
- int saw_gdm_name = 0;
-
- /* some times a window can go away before we get to it */
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
-
- if (! classhint) {
- classhint = XAllocClassHint();
- }
-
- /* we are xlocked. */
- rc = XQueryTree_wr(dpy, DefaultRootWindow(dpy), &r, &parent, &winlist, &nc);
- if (!rc || winlist == NULL || nc == 0) {
- nc = 0;
- }
- for (i=0; i < (int) nc; i++) {
- char *name = NULL;
- Window w = winlist[i];
- if (XFetchName(dpy, w, &name) && name != NULL) {
- saw_gdm_name += dm_string(name);
- XFree_wr(name);
- }
- classhint->res_name = NULL;
- classhint->res_class = NULL;
- if (XGetClassHint(dpy, w, classhint)) {
- name = classhint->res_name;
- if (name != NULL) {
- saw_gdm_name += dm_string(name);
- XFree_wr(name);
- }
- name = classhint->res_class;
- if (name != NULL) {
- saw_gdm_name += dm_string(name);
- XFree_wr(name);
- }
- }
- if (saw_gdm_name > 0) {
- break;
- }
- }
- if (winlist != NULL) {
- XFree_wr(winlist);
- }
-
- XSync(dpy, False);
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
-
- return saw_gdm_name;
-#endif
-}
-
-static int wm_running(void) {
- char *s = getenv("DEBUG_WM_RUNNING");
- int ret = 0;
- RAWFB_RET(0)
-#if NO_X11
- return 0;
-#else
- /*
- * Unfortunately with recent GDM (v2.28), they run gnome-session,
- * dbus-launch, and metacity for the Login greeter! So the simple
- * XInternAtom checks below no longer work.
- * We also see a similar thing with KDE.
- */
- if (dm_still_running()) {
- return 0;
- }
-
- /* we are xlocked. */
- if (XInternAtom(dpy, "_NET_SUPPORTED", True) != None) {
- if (s) rfbLog("wm is running (_NET_SUPPORTED).\n");
- ret++;
- }
- if (XInternAtom(dpy, "_WIN_PROTOCOLS", True) != None) {
- if (s) rfbLog("wm is running (_WIN_PROTOCOLS).\n");
- ret++;
- }
- if (XInternAtom(dpy, "_XROOTPMAP_ID", True) != None) {
- if (s) rfbLog("wm is running (_XROOTPMAP_ID).\n");
- ret++;
- }
- if (XInternAtom(dpy, "_MIT_PRIORITY_COLORS", True) != None) {
- if (s) rfbLog("wm is running (_MIT_PRIORITY_COLORS).\n");
- ret++;
- }
- if (!ret) {
- if (s) rfbLog("wm is not running.\n");
- return 0;
- } else {
- if (s) rfbLog("wm is running ret=%d.\n", ret);
- return 1;
- }
-#endif /* NO_X11 */
-
-}
-
-int guess_dm_gone(int t1, int t2) {
- int wait = t2;
- char *avoid = getenv("X11VNC_AVOID_WINDOWS");
- time_t tcheck = last_client;
-
- if (last_open_xdisplay > last_client) {
- /* better time for -display WAIT:... */
- tcheck = last_open_xdisplay;
- }
-
- if (avoid && !strcmp(avoid, "never")) {
- return 1;
- }
- if (!screen || !screen->clientHead) {
- return 0;
- }
- if (avoid) {
- int n = atoi(avoid);
- if (n > 1) {
- wait = n;
- } else {
- wait = 90;
- }
- } else {
- static time_t saw_wm = 0;
-
- wait = t2;
-
- X_LOCK;
- if (wm_running()) {
- if (saw_wm == 0) {
- saw_wm = time(NULL);
- } else if (time(NULL) <= saw_wm + 2) {
- /* try to wait a few seconds after transition */
- ;
- } else {
- wait = t1;
- }
- }
- X_UNLOCK;
- }
- if (getenv("DEBUG_WM_RUNNING")) {
- rfbLog("guess_dm_gone: wait=%d\n", wait);
- }
- /* we assume they've logged in OK after wait seconds... */
- if (time(NULL) <= tcheck + wait) {
- return 0;
- }
- return 1;
-}
-
-static void initialize_xevents(int reset) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!reset) {}
- return;
-#else
- static int did_xselect_input = 0;
- static int did_xcreate_simple_window = 0;
- static int did_vnc_connect_prop = 0;
- static int did_x11vnc_remote_prop = 0;
- static int did_clipboard_atom = 0;
- static int did_xfixes = 0;
- static int did_xdamage = 0;
- static int did_xrandr = 0;
-
- RAWFB_RET_VOID
-
- if (reset) {
- did_xselect_input = 0;
- did_xcreate_simple_window = 0;
- did_vnc_connect_prop = 0;
- did_x11vnc_remote_prop = 0;
- did_clipboard_atom = 0;
- did_xfixes = 0;
- did_xdamage = 0;
- did_xrandr = 0;
- }
-
- if ((watch_selection || vnc_connect) && !did_xselect_input) {
- /*
- * register desired event(s) for notification.
- * PropertyChangeMask is for CUT_BUFFER0 changes.
- * XXX: does this cause a flood of other stuff?
- */
- X_LOCK;
- xselectinput_rootwin |= PropertyChangeMask;
- XSelectInput_wr(dpy, rootwin, xselectinput_rootwin);
-
- if (subwin && freeze_when_obscured) {
- XSelectInput_wr(dpy, subwin, VisibilityChangeMask);
- }
- X_UNLOCK;
- did_xselect_input = 1;
- }
- if (watch_selection && !did_xcreate_simple_window) {
- /* create fake window for our selection ownership, etc */
-
- /*
- * We try to delay creating selwin until we are past
- * any GDM, (or other KillInitClients=true) manager.
- */
- if (guess_dm_gone(8, 45)) {
- X_LOCK;
- selwin = XCreateSimpleWindow(dpy, rootwin, 3, 2, 1, 1, 0, 0, 0);
- X_UNLOCK;
- did_xcreate_simple_window = 1;
- if (! quiet) rfbLog("created selwin: 0x%lx\n", selwin);
- }
- }
-
- if ((xrandr || xrandr_maybe) && !did_xrandr) {
- initialize_xrandr();
- did_xrandr = 1;
- }
- if (vnc_connect && !did_vnc_connect_prop) {
- initialize_vnc_connect_prop();
- did_vnc_connect_prop = 1;
- }
- if (vnc_connect && !did_x11vnc_remote_prop) {
- initialize_x11vnc_remote_prop();
- did_x11vnc_remote_prop = 1;
- }
- if (run_gui_pid > 0) {
- kill(run_gui_pid, SIGUSR1);
- run_gui_pid = 0;
- }
- if (!did_clipboard_atom) {
- initialize_clipboard_atom();
- did_clipboard_atom = 1;
- }
- if (xfixes_present && use_xfixes && !did_xfixes) {
- /*
- * We try to delay creating initializing xfixes until
- * we are past the display manager, due to Xorg bug:
- * http://bugs.freedesktop.org/show_bug.cgi?id=18451
- */
- if (guess_dm_gone(8, 45)) {
- initialize_xfixes();
- did_xfixes = 1;
- if (! quiet) rfbLog("called initialize_xfixes()\n");
- }
- }
- if (xdamage_present && !did_xdamage) {
- initialize_xdamage();
- did_xdamage = 1;
- }
-#endif /* NO_X11 */
-}
-
-static void print_xevent_bases(void) {
- fprintf(stderr, "X event bases: xkb=%d, xtest=%d, xrandr=%d, "
- "xfixes=%d, xdamage=%d, xtrap=%d\n", xkb_base_event_type,
- xtest_base_event_type, xrandr_base_event_type,
- xfixes_base_event_type, xdamage_base_event_type,
- xtrap_base_event_type);
- fprintf(stderr, " MapNotify=%d, ClientMsg=%d PropNotify=%d "
- "SelNotify=%d, SelRequest=%d\n", MappingNotify, ClientMessage,
- PropertyNotify, SelectionNotify, SelectionRequest);
- fprintf(stderr, " SelClear=%d, Expose=%d\n", SelectionClear, Expose);
-}
-
-void get_prop(char *str, int len, Atom prop, Window w) {
- int i;
-#if !NO_X11
- Atom type;
- int format, slen, dlen;
- unsigned long nitems = 0, bytes_after = 0;
- unsigned char* data = NULL;
-#endif
-
- for (i=0; i<len; i++) {
- str[i] = '\0';
- }
- if (prop == None) {
- return;
- }
-
- RAWFB_RET_VOID
-
-#if NO_X11
- return;
-#else
-
- slen = 0;
- if (w == None) {
- w = DefaultRootWindow(dpy);
- }
-
- do {
- if (XGetWindowProperty(dpy, w,
- prop, nitems/4, len/16, False,
- AnyPropertyType, &type, &format, &nitems, &bytes_after,
- &data) == Success) {
-
- dlen = nitems * (format/8);
- if (slen + dlen > len) {
- /* too big */
- XFree_wr(data);
- break;
- }
- memcpy(str+slen, data, dlen);
- slen += dlen;
- str[slen] = '\0';
- XFree_wr(data);
- }
- } while (bytes_after > 0);
-#endif /* NO_X11 */
-}
-
-static void bust_grab(int reset) {
-#if NO_X11
- if (!reset) {}
- return;
-#else
- static int bust_count = 0;
- static time_t last_bust = 0;
- time_t now = time(NULL);
- KeyCode key;
- int button, x, y, nb;
-
- if (now > last_bust + 180) {
- bust_count = 0;
- }
- if (reset) {
- bust_count = 0;
- return;
- }
-
- x = 0;
- y = 0;
- button = 0;
- key = NoSymbol;
-
- nb = 8;
- if (bust_count >= 3 * nb) {
- fprintf(stderr, "too many bust_grab's %d for me\n", bust_count);
- exit(0);
- }
- if (bust_count % nb == 0) {
- button = 1;
- } else if (bust_count % nb == 1) {
- button = 1;
- } else if (bust_count % nb == 2) {
- key = XKeysymToKeycode(dpy, XK_Escape);
- } else if (bust_count % nb == 3) {
- button = 3;
- } else if (bust_count % nb == 4) {
- key = XKeysymToKeycode(dpy, XK_space);
- } else if (bust_count % nb == 5) {
- x = bust_count * 23;
- y = bust_count * 17;
- } else if (bust_count % nb == 5) {
- button = 2;
- } else if (bust_count % nb == 6) {
- key = XKeysymToKeycode(dpy, XK_a);
- }
-
- if (key == NoSymbol) {
- key = XKeysymToKeycode(dpy, XK_a);
- if (key == NoSymbol) {
- button = 1;
- }
- }
-
- bust_count++;
-
- if (button) {
- /* try button press+release */
- fprintf(stderr, "**bust_grab: button%d %.4f\n",
- button, dnowx());
- XTestFakeButtonEvent_wr(dpy, button, True, CurrentTime);
- XFlush_wr(dpy);
- usleep(50 * 1000);
- XTestFakeButtonEvent_wr(dpy, button, False, CurrentTime);
- } else if (x > 0) {
- /* try button motion*/
- int scr = DefaultScreen(dpy);
-
- fprintf(stderr, "**bust_grab: x=%d y=%d %.4f\n", x, y,
- dnowx());
- XTestFakeMotionEvent_wr(dpy, scr, x, y, CurrentTime);
- XFlush_wr(dpy);
- usleep(50 * 1000);
-
- /* followed by button press */
- button = 1;
- fprintf(stderr, "**bust_grab: button%d\n", button);
- XTestFakeButtonEvent_wr(dpy, button, True, CurrentTime);
- XFlush_wr(dpy);
- usleep(50 * 1000);
- XTestFakeButtonEvent_wr(dpy, button, False, CurrentTime);
- } else {
- /* try Escape or Space press+release */
- fprintf(stderr, "**bust_grab: keycode: %d %.4f\n",
- (int) key, dnowx());
- XTestFakeKeyEvent_wr(dpy, key, True, CurrentTime);
- XFlush_wr(dpy);
- usleep(50 * 1000);
- XTestFakeKeyEvent_wr(dpy, key, False, CurrentTime);
- }
- XFlush_wr(dpy);
- last_bust = time(NULL);
-#endif /* NO_X11 */
-}
-
-typedef struct _grabwatch {
- int pid;
- int tick;
- unsigned long time;
- time_t change;
-} grabwatch_t;
-#define GRABWATCH 16
-
-static int grab_buster_delay = 20;
-static pid_t grab_buster_pid = 0;
-
-static int grab_npids = 1;
-
-static int process_watch(char *str, int parent, int db) {
- int i, pid, ticker, npids;
- char diff[128];
- unsigned long xtime;
- static grabwatch_t watches[GRABWATCH];
- static int first = 1;
- time_t now = time(NULL);
- static time_t last_bust = 0;
- int too_long, problems = 0;
-
- if (first) {
- for (i=0; i < GRABWATCH; i++) {
- watches[i].pid = 0;
- watches[i].tick = 0;
- watches[i].time = 0;
- watches[i].change = 0;
- }
- first = 0;
- }
-
- /* record latest value of prop */
- if (str && *str != '\0') {
- if (sscanf(str, "%d/%d/%lu/%s", &pid, &ticker, &xtime, diff)
- == 4) {
- int got = -1, free = -1;
-
- if (db) fprintf(stderr, "grab_buster %d - %d - %lu - %s"
- "\n", pid, ticker, xtime, diff);
-
- if (pid == parent && !strcmp(diff, "QUIT")) {
- /* that's it. */
- return 0;
- }
- if (pid == 0 || ticker == 0 || xtime == 0) {
- /* bad prop read. */
- goto badtickerstr;
- }
- for (i=0; i < GRABWATCH; i++) {
- if (watches[i].pid == pid) {
- got = i;
- break;
- }
- if (free == -1 && watches[i].pid == 0) {
- free = i;
- }
- }
- if (got == -1) {
- if (free == -1) {
- /* bad news */;
- free = GRABWATCH - 1;
- }
- watches[free].pid = pid;
- watches[free].tick = ticker;
- watches[free].time = xtime;
- watches[free].change = now;
- if (db) fprintf(stderr, "grab_buster free slot: %d\n", free);
- } else {
- if (db) fprintf(stderr, "grab_buster got slot: %d\n", got);
- if (watches[got].tick != ticker) {
- watches[got].change = now;
- }
- if (watches[got].time != xtime) {
- watches[got].change = now;
- }
- watches[got].tick = ticker;
- watches[got].time = xtime;
- }
- } else {
- if (db) fprintf(stderr, "grab_buster bad prop str: %s\n", str);
- }
- }
-
- badtickerstr:
-
- too_long = grab_buster_delay;
- if (too_long < 3 * sync_tod_delay) {
- too_long = 3 * sync_tod_delay;
- }
-
- npids = 0;
- for (i=0; i < GRABWATCH; i++) {
- if (watches[i].pid) {
- npids++;
- }
- }
- grab_npids = npids;
- if (npids > 4) {
- npids = 4;
- }
-
- /* now check everyone we are tracking */
- for (i=0; i < GRABWATCH; i++) {
- int fac = 1;
- if (!watches[i].pid) {
- continue;
- }
- if (watches[i].change == 0) {
- watches[i].change = now; /* just to be sure */
- continue;
- }
-
- pid = watches[i].pid;
-
- if (pid != parent) {
- fac = 2;
- }
- if (npids > 0) {
- fac *= npids;
- }
-
- if (now > watches[i].change + fac*too_long) {
- int process_alive = 1;
-
- fprintf(stderr, "grab_buster: problem with pid: "
- "%d - %d/%d/%d\n", pid, (int) now,
- (int) watches[i].change, too_long);
-
- if (kill((pid_t) pid, 0) != 0) {
- if (1 || errno == ESRCH) {
- process_alive = 0;
- }
- }
-
- if (!process_alive) {
- watches[i].pid = 0;
- watches[i].tick = 0;
- watches[i].time = 0;
- watches[i].change = 0;
- fprintf(stderr, "grab_buster: pid gone: %d\n",
- pid);
- if (pid == parent) {
- /* that's it */
- return 0;
- }
- } else {
- int sleep = sync_tod_delay * 1000 * 1000;
-
- bust_grab(0);
- problems++;
- last_bust = now;
- usleep(1 * sleep);
- break;
- }
- }
- }
-
- if (!problems) {
- bust_grab(1);
- }
- return 1;
-}
-
-static void grab_buster_watch(int parent, char *dstr) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!parent || !dstr) {}
- return;
-#else
- Atom ticker_atom = None;
- int sleep = sync_tod_delay * 921 * 1000;
- char propval[200];
- int ev, er, maj, min;
- int db = 0;
- char *ticker_str = "X11VNC_TICKER";
-
- RAWFB_RET_VOID
-
- if (grab_buster > 1) {
- db = 1;
- }
-
- /* overwrite original dpy, we let orig connection sit unused. */
- dpy = XOpenDisplay_wr(dstr);
- if (!dpy) {
- fprintf(stderr, "grab_buster_watch: could not reopen: %s\n",
- dstr);
- return;
- }
- rfbLogEnable(0);
-
- /* check for XTEST, etc, and then disable grabs for us */
- if (! XTestQueryExtension_wr(dpy, &ev, &er, &maj, &min)) {
- xtest_present = 0;
- } else {
- xtest_present = 1;
- }
- if (! XETrapQueryExtension_wr(dpy, &ev, &er, &maj)) {
- xtrap_present = 0;
- } else {
- xtrap_present = 1;
- }
-
- if (! xtest_present && ! xtrap_present) {
- fprintf(stderr, "grab_buster_watch: no grabserver "
- "protection on display: %s\n", dstr);
- return;
- }
- disable_grabserver(dpy, 0);
-
- usleep(3 * sleep);
-
- if (getenv("X11VNC_TICKER")) {
- ticker_str = getenv("X11VNC_TICKER");
- }
- ticker_atom = XInternAtom(dpy, ticker_str, False);
- if (! ticker_atom) {
- fprintf(stderr, "grab_buster_watch: no ticker atom\n");
- return;
- }
-
- while(1) {
- int slp = sleep;
- if (grab_npids > 1) {
- slp = slp / 8;
- }
- usleep(slp);
- usleep((int) (0.60 * rfac() * slp));
-
- if (kill((pid_t) parent, 0) != 0) {
- break;
- }
-
- get_prop(propval, 128, ticker_atom, None);
- if (db) fprintf(stderr, "got_prop: %s\n", propval);
-
- if (!process_watch(propval, parent, db)) {
- break;
- }
- }
-#endif /* NO_X11 */
-}
-
-void spawn_grab_buster(void) {
-#if LIBVNCSERVER_HAVE_FORK
- pid_t pid;
- int parent = (int) getpid();
- char *dstr = strdup(DisplayString(dpy));
-
- RAWFB_RET_VOID
-
- XCloseDisplay_wr(dpy);
- dpy = NULL;
-
- if ((pid = fork()) > 0) {
- grab_buster_pid = pid;
- if (! quiet) {
- rfbLog("grab_buster pid is: %d\n", (int) pid);
- }
- } else if (pid == -1) {
- fprintf(stderr, "spawn_grab_buster: could not fork\n");
- rfbLogPerror("fork");
- } else {
- signal(SIGHUP, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
-
- grab_buster_watch(parent, dstr);
- exit(0);
- }
-
- dpy = XOpenDisplay_wr(dstr);
- if (!dpy) {
- rfbLog("failed to reopen display %s in spawn_grab_buster\n",
- dstr);
- exit(1);
- }
-#endif
-}
-
-void sync_tod_with_servertime(void) {
-#if NO_X11
- RAWFB_RET_VOID
- return;
-#else
- static Atom ticker_atom = None;
- XEvent xev;
- char diff[128];
- static int seq = 0;
- static unsigned long xserver_ticks = 1;
- int i, db = 0;
-
- RAWFB_RET_VOID
-
- if (atom_NET_ACTIVE_WINDOW == None) {
- atom_NET_ACTIVE_WINDOW = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", True);
- }
- if (atom_NET_CURRENT_DESKTOP == None) {
- atom_NET_CURRENT_DESKTOP = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", True);
- }
- if (atom_NET_CLIENT_LIST_STACKING == None) {
- atom_NET_CLIENT_LIST_STACKING = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", True);
- }
- if (atom_XROOTPMAP_ID == None) {
- atom_XROOTPMAP_ID = XInternAtom(dpy, "_XROOTPMAP_ID", True);
- }
-
- if (! ticker_atom) {
- char *ticker_str = "X11VNC_TICKER";
- if (getenv("X11VNC_TICKER")) {
- ticker_str = getenv("X11VNC_TICKER");
- }
- ticker_atom = XInternAtom(dpy, ticker_str, False);
- }
- if (! ticker_atom) {
- return;
- }
-
- XSync(dpy, False);
- while (XCheckTypedEvent(dpy, PropertyNotify, &xev)) {
- set_prop_atom(xev.xproperty.atom);
- }
-
- snprintf(diff, 128, "%d/%08d/%lu/%.6f", (int) getpid(), seq++,
- xserver_ticks, servertime_diff);
- XChangeProperty(dpy, rootwin, ticker_atom, XA_STRING, 8,
- PropModeReplace, (unsigned char *) diff, strlen(diff));
- XSync(dpy, False);
-
- for (i=0; i < 10; i++) {
- int k, got = 0;
-
- for (k=0; k < 5; k++) {
- while (XCheckTypedEvent(dpy, PropertyNotify, &xev)) {
- if (xev.xproperty.atom == ticker_atom) {
- double stime;
-
- xserver_ticks = xev.xproperty.time;
- stime = (double) xev.xproperty.time;
- stime = stime/1000.0;
- servertime_diff = dnow() - stime;
- if (db) rfbLog("set servertime_diff: "
- "%.6f\n", servertime_diff);
- got = 1;
- }
- }
- }
- if (got) {
- break;
- }
- usleep(1000);
- }
-#endif /* NO_X11 */
-}
-
-void check_keycode_state(void) {
- static time_t last_check = 0;
- int delay = 10, noinput = 3;
- time_t now = time(NULL);
-
- if (! client_count) {
- return;
- }
- if (unixpw_in_progress) return;
-
- RAWFB_RET_VOID
-
- /*
- * periodically update our model of the keycode_state[]
- * by correlating with the Xserver. wait for a pause in
- * keyboard input to be on the safe side. the idea here
- * is to remove stale keycode state, not to be perfectly
- * in sync with the Xserver at every instant of time.
- */
- if (now > last_check + delay && now > last_keyboard_input + noinput) {
- X_LOCK;
- init_track_keycode_state();
- X_UNLOCK;
- last_check = now;
- }
-}
-
-/*
- * To use the experimental -grablocal option configure like this:
- * env CPPFLAGS=-DENABLE_GRABLOCAL LDFLAGS=-lXss ./configure
- */
-#ifdef ENABLE_GRABLOCAL
-#include <X11/extensions/scrnsaver.h>
-
-void check_local_grab(void) {
- static double last_check = 0.0;
- double now;
-
- if (grab_local <= 0) {
- return;
- }
- if (! client_count) {
- return;
- }
- if (unixpw_in_progress) return;
-
- if (last_rfb_key_injected <= 0.0 && last_rfb_ptr_injected <= 0.0) {
- return;
- }
-
- RAWFB_RET_VOID
-
- now = dnow();
-
- if (now > last_check + 0.1) {
-#if !NO_X11
- int ret;
- double idle;
- XScreenSaverInfo info;
- static int save_viewonly = -1, local_is_idle = -1, db = -1;
-
- if (debug_keyboard) db = debug_keyboard;
- if (debug_pointer ) db = debug_pointer;
-
- if (db < 0) {
- if (getenv("LOCAL_GRAB_DEBUG")) {
- db = atoi(getenv("LOCAL_GRAB_DEBUG"));
- } else {
- db = 0;
- }
- }
-
- ret = XScreenSaverQueryInfo(dpy, RootWindowOfScreen(
- ScreenOfDisplay(dpy, 0)), &info);
-
- if (ret) {
- double tlatest_rfb = 0.0;
-
- idle = ((double) info.idle)/1000.0;
- now = dnow();
-
- if (last_rfb_key_injected > 0.0) {
- tlatest_rfb = last_rfb_key_injected;
- }
- if (last_rfb_ptr_injected > tlatest_rfb) {
- tlatest_rfb = last_rfb_ptr_injected;
- }
- if (db > 1) fprintf(stderr, "idle: %.4f latest: %.4f dt: %.4f\n", idle, now - tlatest_rfb, idle - (now - tlatest_rfb));
-
- if (now - tlatest_rfb <= idle + 0.005) {
- /* 0.005 is 5ms tolerance */
- } else if (idle < grab_local) {
- if (local_is_idle < 0 || local_is_idle) {
- save_viewonly = view_only;
- view_only = 1;
- if (db) {
- rfbLog("check_local_grab: set viewonly\n");
- }
- }
-
- local_is_idle = 0;
- } else {
- if (!local_is_idle && save_viewonly >= 0) {
- view_only = save_viewonly;
- if (db) {
- rfbLog("check_local_grab: restored viewonly; %d\n", view_only);
- }
- }
- local_is_idle = 1;
- }
- }
-#endif
- last_check = dnow();
- }
-}
-#endif
-
-void check_autorepeat(void) {
- static time_t last_check = 0;
- static int idle_timeout = -300, idle_reset = 0;
- time_t now = time(NULL);
- int autorepeat_is_on, autorepeat_initially_on;
-
- if (! no_autorepeat || ! client_count) {
- return;
- }
- if (now <= last_check + 1) {
- return;
- }
-
- if (unixpw_in_progress) return;
-
- if (idle_timeout < 0) {
- if (getenv("X11VNC_IDLE_TIMEOUT")) {
- idle_timeout = atoi(getenv("X11VNC_IDLE_TIMEOUT"));
- }
- if (idle_timeout < 0) {
- idle_timeout = -idle_timeout;
- }
- }
-
- last_check = now;
-
- autorepeat_is_on = get_autorepeat_state();
- autorepeat_initially_on = get_initial_autorepeat_state();
-
- if (view_only) {
- if (! autorepeat_is_on) {
- autorepeat(1, 1);
- }
- return;
- }
-
- if (now > last_keyboard_input + idle_timeout) {
- /* autorepeat should be on when idle */
- if (! autorepeat_is_on && autorepeat_initially_on) {
- static time_t last_msg = 0;
- static int cnt = 0;
- if (now > last_msg + idle_timeout && cnt++ < 10) {
- rfbLog("idle keyboard: turning X autorepeat"
- " back on.\n");
- last_msg = now;
- }
- autorepeat(1, 1);
- idle_reset = 1;
- }
- } else {
- if (idle_reset) {
- int i, state[256], didmsg = 0, pressed = 0;
- int mwt = 600, mmax = 20;
- static int msgcnt = 0;
- static double lastmsg = 0.0;
-
- for (i=0; i<256; i++) {
- state[i] = 0;
- }
- if (use_threads) {X_LOCK;}
- get_keystate(state);
- if (use_threads) {X_UNLOCK;}
-
- for (i=0; i<256; i++) {
- if (state[i] != 0) {
- /* better wait until all keys are up */
- pressed++;
- if (msgcnt < mmax || dnow() > lastmsg + mwt) {
- char *str = "unset";
-#if !NO_X11
- if (use_threads) {X_LOCK;}
- str = XKeysymToString(XKeycodeToKeysym(dpy, i, 0));
- if (use_threads) {X_UNLOCK;}
-#endif
- str = str ? str : "nosymbol";
- didmsg++;
- rfbLog("active keyboard: waiting until "
- "all keys are up. key_down=%d %s. "
- "If the key is inaccessible via keyboard, "
- "consider 'x11vnc -R clear_all'\n", i, str);
- }
- }
- }
- if (didmsg > 0) {
- msgcnt++;
- if (msgcnt == mmax) {
- rfbLog("active keyboard: last such "
- "message for %d secs.\n", mwt);
- }
- lastmsg = dnow();
- }
- if (pressed > 0) {
- return;
- }
- }
- if (idle_reset) {
- static time_t last_msg = 0;
- static int cnt = 0;
- if (now > last_msg + idle_timeout && cnt++ < 10) {
- rfbLog("active keyboard: turning X autorepeat"
- " off.\n");
- last_msg = now;
- }
- autorepeat(0, 1);
- idle_reset = 0;
-
- } else if (no_repeat_countdown && autorepeat_is_on) {
- int n = no_repeat_countdown - 1;
- if (n >= 0) {
- rfbLog("Battling with something for "
- "-norepeat!! (%d resets left)\n", n);
- } else {
- rfbLog("Battling with something for "
- "-norepeat!!\n");
- }
- if (no_repeat_countdown > 0) {
- no_repeat_countdown--;
- }
- autorepeat(1, 0);
- autorepeat(0, 0);
- }
- }
-}
-
-void set_prop_atom(Atom atom) {
- if (atom == None) return;
- if (atom == atom_NET_ACTIVE_WINDOW) got_NET_ACTIVE_WINDOW = dnow();
- if (atom == atom_NET_CURRENT_DESKTOP) got_NET_CURRENT_DESKTOP = dnow();
- if (atom == atom_NET_CLIENT_LIST_STACKING) got_NET_CLIENT_LIST_STACKING = dnow();
- if (atom == atom_XROOTPMAP_ID) got_XROOTPMAP_ID = dnow();
-}
-
-/*
- * This routine is periodically called to check for selection related
- * and other X11 events and respond to them as needed.
- */
-void check_xevents(int reset) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!reset) {}
- return;
-#else
- XEvent xev;
- int tmp, have_clients = 0;
- static int sent_some_sel = 0;
- static time_t last_call = 0;
- static time_t last_bell = 0;
- static time_t last_init_check = 0;
- static time_t last_sync = 0;
- static time_t last_time_sync = 0;
- time_t now = time(NULL);
- static double last_request = 0.0;
- static double last_xrefresh = 0.0;
- XErrorHandler old_handler;
-
- if (unixpw_in_progress) return;
-
- RAWFB_RET_VOID
-
- if (now > last_init_check+1 || reset) {
- last_init_check = now;
- initialize_xevents(reset);
- if (reset) {
- return;
- }
- }
-
- if (screen && screen->clientHead) {
- have_clients = 1;
- }
-
- X_LOCK;
- /*
- * There is a bug where we have to wait before sending text to
- * the client... so instead of sending right away we wait a
- * the few seconds.
- */
-
- if (have_clients && watch_selection && !sent_some_sel
- && now > last_client + sel_waittime) {
- if (XGetSelectionOwner(dpy, XA_PRIMARY) == None) {
- cutbuffer_send();
- }
- sent_some_sel = 1;
- }
- if (! have_clients) {
- /*
- * If we don't have clients we can miss the X server
- * going away until a client connects.
- */
- static time_t last_X_ping = 0;
- if (now > last_X_ping + 5) {
- last_X_ping = now;
- XGetSelectionOwner(dpy, XA_PRIMARY);
- }
- }
-
- if (have_clients && xrefresh > 0.0 && dnow() > last_xrefresh + xrefresh) {
- XSetWindowAttributes swa;
- Visual visual;
- Window xrf;
- unsigned long mask;
-
- swa.override_redirect = True;
- swa.backing_store = NotUseful;
- swa.save_under = False;
- swa.background_pixmap = None;
- visual.visualid = CopyFromParent;
- mask = (CWOverrideRedirect|CWBackingStore|CWSaveUnder|CWBackPixmap);
-
- xrf = XCreateWindow(dpy, window, coff_x, coff_y, dpy_x, dpy_y, 0, CopyFromParent,
- InputOutput, &visual, mask, &swa);
- if (xrf != None) {
- if (0) fprintf(stderr, "XCreateWindow(%d, %d, %d, %d) 0x%lx\n", coff_x, coff_y, dpy_x, dpy_y, xrf);
- XMapWindow(dpy, xrf);
- XFlush_wr(dpy);
- XDestroyWindow(dpy, xrf);
- XFlush_wr(dpy);
- }
- last_xrefresh = dnow();
- }
-
- if (now > last_call+1) {
- /* we only check these once a second or so. */
- int n = 0;
-
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
-
- while (XCheckTypedEvent(dpy, MappingNotify, &xev)) {
- XRefreshKeyboardMapping((XMappingEvent *) &xev);
- n++;
- }
- if (n && use_modifier_tweak) {
- X_UNLOCK;
- initialize_modtweak();
- X_LOCK;
- }
- if (xtrap_base_event_type) {
- int base = xtrap_base_event_type;
- while (XCheckTypedEvent(dpy, base, &xev)) {
- ;
- }
- }
- if (xtest_base_event_type) {
- int base = xtest_base_event_type;
- while (XCheckTypedEvent(dpy, base, &xev)) {
- ;
- }
- }
- /*
- * we can get ClientMessage from our XSendEvent() call in
- * selection_request().
- */
- while (XCheckTypedEvent(dpy, ClientMessage, &xev)) {
- ;
- }
-
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
- last_call = now;
- }
-
- if (freeze_when_obscured) {
- if (XCheckTypedEvent(dpy, VisibilityNotify, &xev)) {
- if (xev.type == VisibilityNotify && xev.xany.window == subwin) {
- int prev = subwin_obscured;
- if (xev.xvisibility.state == VisibilityUnobscured) {
- subwin_obscured = 0;
- } else if (xev.xvisibility.state == VisibilityPartiallyObscured) {
- subwin_obscured = 1;
- } else {
- subwin_obscured = 2;
- }
- rfbLog("subwin_obscured: %d -> %d\n", prev, subwin_obscured);
- }
- }
- }
-
- /* check for CUT_BUFFER0, VNC_CONNECT, X11VNC_REMOTE changes: */
- if (XCheckTypedEvent(dpy, PropertyNotify, &xev)) {
- int got_cutbuffer = 0;
- int got_vnc_connect = 0;
- int got_x11vnc_remote = 0;
- static int prop_dbg = -1;
-
- /* to avoid piling up between calls, read all PropertyNotify now */
- do {
- if (xev.type == PropertyNotify) {
- if (xev.xproperty.atom == XA_CUT_BUFFER0) {
- got_cutbuffer++;
- } else if (vnc_connect && vnc_connect_prop != None
- && xev.xproperty.atom == vnc_connect_prop) {
- got_vnc_connect++;
- } else if (vnc_connect && x11vnc_remote_prop != None
- && xev.xproperty.atom == x11vnc_remote_prop) {
- got_x11vnc_remote++;
- }
- set_prop_atom(xev.xproperty.atom);
- }
- } while (XCheckTypedEvent(dpy, PropertyNotify, &xev));
-
- if (prop_dbg < 0) {
- prop_dbg = 0;
- if (getenv("PROP_DBG")) {
- prop_dbg = 1;
- }
- }
-
- if (prop_dbg && (got_cutbuffer > 1 || got_vnc_connect > 1 || got_x11vnc_remote > 1)) {
- static double lastmsg = 0.0;
- static int count = 0;
- double now = dnow();
-
- if (1 && now > lastmsg + 300.0) {
- if (got_cutbuffer > 1) {
- rfbLog("check_xevents: warning: %d cutbuffer events since last check.\n", got_cutbuffer);
- }
- if (got_vnc_connect > 1) {
- rfbLog("check_xevents: warning: %d vnc_connect events since last check.\n", got_vnc_connect);
- }
- if (got_x11vnc_remote > 1) {
- rfbLog("check_xevents: warning: %d x11vnc_remote events since last check.\n", got_x11vnc_remote);
- }
- count++;
- if (count >= 3) {
- lastmsg = now;
- count = 0;
- }
- }
- }
-
- if (got_cutbuffer) {
- /*
- * Go retrieve CUT_BUFFER0 and send it.
- *
- * set_cutbuffer is a flag to try to avoid
- * processing our own cutbuffer changes.
- */
- if (have_clients && watch_selection && !set_cutbuffer) {
- cutbuffer_send();
- sent_some_sel = 1;
- }
- set_cutbuffer = 0;
- }
- if (got_vnc_connect) {
- /*
- * Go retrieve VNC_CONNECT string.
- */
- read_vnc_connect_prop(0);
- }
- if (got_x11vnc_remote) {
- /*
- * Go retrieve X11VNC_REMOTE string.
- */
- read_x11vnc_remote_prop(0);
- }
- }
-
- /* do this now that we have just cleared PropertyNotify */
- tmp = 0;
- if (rfac() < 0.6) {
- tmp = 1;
- }
- if (now > last_time_sync + sync_tod_delay + tmp) {
- sync_tod_with_servertime();
- last_time_sync = now;
- }
-
-#if LIBVNCSERVER_HAVE_LIBXRANDR
- if (xrandr || xrandr_maybe) {
- check_xrandr_event("check_xevents");
- }
-#endif
-#if LIBVNCSERVER_HAVE_LIBXFIXES
- if (xfixes_present && use_xfixes && xfixes_first_initialized && xfixes_base_event_type) {
- if (XCheckTypedEvent(dpy, xfixes_base_event_type +
- XFixesCursorNotify, &xev)) {
- got_xfixes_cursor_notify++;
- }
- }
-#endif
-
- /* check for our PRIMARY request notification: */
- if (watch_primary || watch_clipboard) {
- int doprimary = 1, doclipboard = 2, which, own = 0;
- double delay = 1.0;
- Atom atom;
- char *req;
-
- if (XCheckTypedEvent(dpy, SelectionNotify, &xev)) {
- if (xev.type == SelectionNotify &&
- xev.xselection.requestor == selwin &&
- xev.xselection.property != None &&
- xev.xselection.target == XA_STRING) {
- Atom s = xev.xselection.selection;
- if (s == XA_PRIMARY || s == clipboard_atom) {
- /* go retrieve it and check it */
- if (now > last_client + sel_waittime
- || sent_some_sel) {
- selection_send(&xev);
- }
- }
- }
- }
- /*
- * Every second or so, request PRIMARY or CLIPBOARD,
- * unless we already own it or there is no owner or we
- * have no clients.
- * TODO: even at this low rate we should look into
- * and performance problems in odds cases (large text,
- * modem, etc.)
- */
- which = 0;
- if (watch_primary && watch_clipboard && ! own_clipboard &&
- ! own_primary) {
- delay = 0.6;
- }
- if (dnow() > last_request + delay) {
- /*
- * It is not a good idea to do both at the same
- * time so we must choose one:
- */
- if (watch_primary && watch_clipboard) {
- static int count = 0;
- if (own_clipboard) {
- which = doprimary;
- } else if (own_primary) {
- which = doclipboard;
- } else if (count++ % 3 == 0) {
- which = doclipboard;
- } else {
- which = doprimary;
- }
- } else if (watch_primary) {
- which = doprimary;
- } else if (watch_clipboard) {
- which = doclipboard;
- }
- last_request = dnow();
- }
- atom = None;
- req = "none";
- if (which == doprimary) {
- own = own_primary;
- atom = XA_PRIMARY;
- req = "PRIMARY";
- } else if (which == doclipboard) {
- own = own_clipboard;
- atom = clipboard_atom;
- req = "CLIPBOARD";
- }
- if (which != 0 && ! own && have_clients &&
- XGetSelectionOwner(dpy, atom) != None && selwin != None) {
- XConvertSelection(dpy, atom, XA_STRING, XA_STRING,
- selwin, CurrentTime);
- if (debug_sel) {
- rfbLog("request %s\n", req);
- }
- }
- }
-
- if (own_primary || own_clipboard) {
- /* we own PRIMARY or CLIPBOARD, see if someone requested it: */
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
-
- if (XCheckTypedEvent(dpy, SelectionRequest, &xev)) {
- if (own_primary && xev.type == SelectionRequest &&
- xev.xselectionrequest.selection == XA_PRIMARY) {
- selection_request(&xev, "PRIMARY");
- }
- if (own_clipboard && xev.type == SelectionRequest &&
- xev.xselectionrequest.selection == clipboard_atom) {
- selection_request(&xev, "CLIPBOARD");
- }
- }
-
- /* we own PRIMARY or CLIPBOARD, see if we no longer own it: */
- if (XCheckTypedEvent(dpy, SelectionClear, &xev)) {
- if (own_primary && xev.type == SelectionClear &&
- xev.xselectionclear.selection == XA_PRIMARY) {
- own_primary = 0;
- if (xcut_str_primary) {
- free(xcut_str_primary);
- xcut_str_primary = NULL;
- }
- if (debug_sel) {
- rfbLog("Released PRIMARY.\n");
- }
- }
- if (own_clipboard && xev.type == SelectionClear &&
- xev.xselectionclear.selection == clipboard_atom) {
- own_clipboard = 0;
- if (xcut_str_clipboard) {
- free(xcut_str_clipboard);
- xcut_str_clipboard = NULL;
- }
- if (debug_sel) {
- rfbLog("Released CLIPBOARD.\n");
- }
- }
- }
-
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
- }
-
- if (watch_bell || now > last_bell+1) {
- last_bell = now;
- check_bell_event();
- }
- if (tray_request != None) {
- static time_t last_tray_request = 0;
- if (now > last_tray_request + 2) {
- last_tray_request = now;
- if (tray_embed(tray_request, tray_unembed)) {
- tray_window = tray_request;
- tray_request = None;
- }
- }
- }
-
-#ifndef DEBUG_XEVENTS
-#define DEBUG_XEVENTS 1
-#endif
-#if DEBUG_XEVENTS
- if (debug_xevents) {
- static time_t last_check = 0;
- static time_t reminder = 0;
- static int freq = 0;
-
- if (! freq) {
- if (getenv("X11VNC_REMINDER_RATE")) {
- freq = atoi(getenv("X11VNC_REMINDER_RATE"));
- } else {
- freq = 300;
- }
- }
-
- if (now > last_check + 1) {
- int ev_type_max = 300, ev_size = 400;
- XEvent xevs[400];
- int i, tot = XEventsQueued(dpy, QueuedAlready);
-
- if (reminder == 0 || (tot && now > reminder + freq)) {
- print_xevent_bases();
- reminder = now;
- }
- last_check = now;
-
- if (tot) {
- fprintf(stderr, "Total events queued: %d\n",
- tot);
- }
- for (i=1; i<ev_type_max; i++) {
- int k, n = 0;
- while (XCheckTypedEvent(dpy, i, xevs+n)) {
- if (++n >= ev_size) {
- break;
- }
- }
- if (n) {
- fprintf(stderr, " %d%s events of type"
- " %d queued\n", n,
- (n >= ev_size) ? "+" : "", i);
- }
- for (k=n-1; k >= 0; k--) {
- XPutBackEvent(dpy, xevs+k);
- }
- }
- }
- }
-#endif
-
- if (now > last_sync + 1200) {
- /* kludge for any remaining event leaks */
- int bugout = use_xdamage ? 500 : 50;
- int qlen, i;
- if (last_sync != 0) {
- qlen = XEventsQueued(dpy, QueuedAlready);
- if (qlen >= bugout) {
- rfbLog("event leak: %d queued, "
- " calling XSync(dpy, True)\n", qlen);
- rfbLog(" for diagnostics run: 'x11vnc -R"
- " debug_xevents:1'\n");
- XSync(dpy, True);
- }
- }
- last_sync = now;
-
- /* clear these, we don't want any events on them */
- if (rdpy_ctrl) {
- qlen = XEventsQueued(rdpy_ctrl, QueuedAlready);
- for (i=0; i<qlen; i++) {
- XNextEvent(rdpy_ctrl, &xev);
- }
- }
- if (gdpy_ctrl) {
- qlen = XEventsQueued(gdpy_ctrl, QueuedAlready);
- for (i=0; i<qlen; i++) {
- XNextEvent(gdpy_ctrl, &xev);
- }
- }
- }
- X_UNLOCK;
-
-#endif /* NO_X11 */
-}
-
-extern int rawfb_vnc_reflect;
-/*
- * hook called when a VNC client sends us some "XCut" text (rfbClientCutText).
- */
-void xcut_receive(char *text, int len, rfbClientPtr cl) {
- allowed_input_t input;
-
- if (threads_drop_input) {
- return;
- }
-
- if (unixpw_in_progress) {
- rfbLog("xcut_receive: unixpw_in_progress, skipping.\n");
- return;
- }
-
- if (!watch_selection) {
- return;
- }
- if (view_only) {
- return;
- }
- if (text == NULL || len == 0) {
- return;
- }
- get_allowed_input(cl, &input);
- if (!input.clipboard) {
- return;
- }
- INPUT_LOCK;
-
- if (remote_prefix != NULL && strstr(text, remote_prefix) == text) {
- char *result, *rcmd = text + strlen(remote_prefix);
- char *tmp = (char *) calloc(len + 8, 1);
-
- if (strstr(rcmd, "cmd=") != rcmd && strstr(rcmd, "qry=") != rcmd) {
- strcat(tmp, "qry=");
- }
- strncat(tmp, rcmd, len - strlen(remote_prefix));
- rfbLog("remote_prefix command: '%s'\n", tmp);
-
- if (use_threads) {
- if (client_connect_file) {
- FILE *f = fopen(client_connect_file, "w");
- if (f) {
- fprintf(f, "%s\n", tmp);
- fclose(f);
- free(tmp);
- INPUT_UNLOCK;
- return;
- }
- }
- if (vnc_connect) {
- sprintf(x11vnc_remote_str, "%s", tmp);
- free(tmp);
- INPUT_UNLOCK;
- return;
- }
- }
- INPUT_UNLOCK;
-
-
- result = process_remote_cmd(tmp, 1);
- if (result == NULL ) {
- result = strdup("null");
- } else if (!strcmp(result, "")) {
- free(result);
- result = strdup("none");
- }
- rfbLog("remote_prefix result: '%s'\n", result);
-
- free(tmp);
- tmp = (char *) calloc(strlen(remote_prefix) + strlen(result) + 1, 1);
-
- strcat(tmp, remote_prefix);
- strcat(tmp, result);
- free(result);
-
- rfbSendServerCutText(screen, tmp, strlen(tmp));
- free(tmp);
-
- return;
- }
-
- if (! check_sel_direction("recv", "xcut_receive", text, len)) {
- INPUT_UNLOCK;
- return;
- }
-
-#ifdef MACOSX
- if (macosx_console) {
- macosx_set_sel(text, len);
- INPUT_UNLOCK;
- return;
- }
-#endif
-
- if (rawfb_vnc_reflect) {
- vnc_reflect_send_cuttext(text, len);
- INPUT_UNLOCK;
- return;
- }
-
- RAWFB_RET_VOID
-
-#if NO_X11
- INPUT_UNLOCK;
- return;
-#else
-
- X_LOCK;
-
- /* associate this text with PRIMARY (and SECONDARY...) */
- if (set_primary && ! own_primary && selwin != None) {
- own_primary = 1;
- /* we need to grab the PRIMARY selection */
- XSetSelectionOwner(dpy, XA_PRIMARY, selwin, CurrentTime);
- XFlush_wr(dpy);
- if (debug_sel) {
- rfbLog("Own PRIMARY.\n");
- }
- }
-
- if (set_clipboard && ! own_clipboard && clipboard_atom != None && selwin != None) {
- own_clipboard = 1;
- /* we need to grab the CLIPBOARD selection */
- XSetSelectionOwner(dpy, clipboard_atom, selwin, CurrentTime);
- XFlush_wr(dpy);
- if (debug_sel) {
- rfbLog("Own CLIPBOARD.\n");
- }
- }
-
- /* duplicate the text string for our own use. */
- if (set_primary) {
- if (xcut_str_primary != NULL) {
- free(xcut_str_primary);
- xcut_str_primary = NULL;
- }
- xcut_str_primary = (char *) malloc((size_t) (len+1));
- strncpy(xcut_str_primary, text, len);
- xcut_str_primary[len] = '\0'; /* make sure null terminated */
- if (debug_sel) {
- rfbLog("Set PRIMARY '%s'\n", xcut_str_primary);
- }
- }
- if (set_clipboard) {
- if (xcut_str_clipboard != NULL) {
- free(xcut_str_clipboard);
- xcut_str_clipboard = NULL;
- }
- xcut_str_clipboard = (char *) malloc((size_t) (len+1));
- strncpy(xcut_str_clipboard, text, len);
- xcut_str_clipboard[len] = '\0'; /* make sure null terminated */
- if (debug_sel) {
- rfbLog("Set CLIPBOARD '%s'\n", xcut_str_clipboard);
- }
- }
-
- /* copy this text to CUT_BUFFER0 as well: */
- XChangeProperty(dpy, rootwin, XA_CUT_BUFFER0, XA_STRING, 8,
- PropModeReplace, (unsigned char *) text, len);
- XFlush_wr(dpy);
-
- X_UNLOCK;
- INPUT_UNLOCK;
-
- set_cutbuffer = 1;
-#endif /* NO_X11 */
-}
-
-void kbd_release_all_keys(rfbClientPtr cl) {
- if (unixpw_in_progress) {
- rfbLog("kbd_release_all_keys: unixpw_in_progress, skipping.\n");
- return;
- }
- if (cl->viewOnly) {
- return;
- }
-
- RAWFB_RET_VOID
-
-#if NO_X11
- return;
-#else
- if (use_threads) {
- X_LOCK;
- }
-
- clear_keys();
- clear_modifiers(0);
-
- if (use_threads) {
- X_UNLOCK;
- }
-#endif
-}
-
-void set_single_window(rfbClientPtr cl, int x, int y) {
- int ok = 0;
- if (no_ultra_ext) {
- return;
- }
- if (unixpw_in_progress) {
- rfbLog("set_single_window: unixpw_in_progress, dropping client.\n");
- rfbCloseClient(cl);
- return;
- }
- if (cl->viewOnly) {
- return;
- }
-
- RAWFB_RET_VOID
-
-#if NO_X11
- return;
-#else
- if (x==1 && y==1) {
- if (subwin) {
- subwin = 0x0;
- ok = 1;
- }
- } else {
- Window r, c;
- int rootx, rooty, wx, wy;
- unsigned int mask;
-
- update_x11_pointer_position(x, y);
- XSync(dpy, False);
-
- if (XQueryPointer_wr(dpy, rootwin, &r, &c, &rootx, &rooty,
- &wx, &wy, &mask)) {
- if (c != None) {
- subwin = c;
- ok = 1;
- }
- }
- }
-
- if (ok) {
- check_black_fb();
- do_new_fb(1);
- }
-#endif
-
-}
-void set_server_input(rfbClientPtr cl, int grab) {
- if (no_ultra_ext) {
- return;
- }
- if (unixpw_in_progress) {
- rfbLog("set_server_input: unixpw_in_progress, dropping client.\n");
- rfbCloseClient(cl);
- return;
- }
- if (cl->viewOnly) {
- return;
- }
-
- RAWFB_RET_VOID
-
-#if NO_X11
- return;
-#else
- if (grab) {
- if (!no_ultra_dpms) {
- set_dpms_mode("enable");
- set_dpms_mode("off");
- force_dpms = 1;
- }
-
- process_remote_cmd("cmd=grabkbd", 0);
- process_remote_cmd("cmd=grabptr", 0);
-
- } else {
- process_remote_cmd("cmd=nograbkbd", 0);
- process_remote_cmd("cmd=nograbptr", 0);
-
- if (!no_ultra_dpms) {
- force_dpms = 0;
- }
- }
-#endif
-}
-
-static int wsock_timeout_sock = -1;
-
-static void wsock_timeout (int sig) {
- rfbLog("sig: %d, wsock_timeout.\n", sig);
- if (wsock_timeout_sock >= 0) {
- close(wsock_timeout_sock);
- wsock_timeout_sock = -1;
- }
-}
-
-static void try_local_chat_window(void) {
- int i, port, lsock;
- char cmd[100];
- struct sockaddr_in addr;
- pid_t pid = -1;
-#ifdef __hpux
- int addrlen = sizeof(addr);
-#else
- socklen_t addrlen = sizeof(addr);
-#endif
-
- for (i = 0; i < 90; i++) {
- /* find an open port */
- port = 7300 + i;
- /* XXX ::1 fallback */
- lsock = listen_tcp(port, htonl(INADDR_LOOPBACK), 0);
- if (lsock >= 0) {
- break;
- }
- port = 0;
- }
-
- if (port == 0) {
- return;
- }
-
- /* have ssvncvncviewer connect back to us (n.b. sockpair fails) */
-
- sprintf(cmd, "ssvnc -cmd VNC://localhost:%d -chatonly", port);
-
-#if LIBVNCSERVER_HAVE_FORK
- pid = fork();
-#endif
-
- if (pid == -1) {
- perror("fork");
- return;
- } else if (pid == 0) {
- char *args[4];
- int d;
- args[0] = "/bin/sh";
- args[1] = "-c";
- /* "ssvnc -cmd VNC://fd=0 -chatonly"; not working */
- args[2] = cmd;
- args[3] = NULL;
-
- set_env("VNCVIEWER_PASSWORD", "moo");
-#if !NO_X11
- if (dpy != NULL) {
- set_env("DISPLAY", DisplayString(dpy));
- }
-#endif
- for (d = 3; d < 256; d++) {
- close(d);
- }
-
- execvp(args[0], args);
- perror("exec");
- exit(1);
- } else {
- int i, sock = -1;
- rfbNewClientHookPtr new_save;
-
- signal(SIGALRM, wsock_timeout);
- wsock_timeout_sock = lsock;
-
- alarm(10);
- sock = accept(lsock, (struct sockaddr *)&addr, &addrlen);
- alarm(0);
-
- signal(SIGALRM, SIG_DFL);
- close(lsock);
-
- if (sock < 0) {
- return;
- }
-
- /* mutex */
- new_save = screen->newClientHook;
- screen->newClientHook = new_client_chat_helper;
-
- chat_window_client = create_new_client(sock, 1);
-
- screen->newClientHook = new_save;
-
- if (chat_window_client != NULL) {
- rfbPasswordCheckProcPtr pwchk_save = screen->passwordCheck;
- rfbBool save_shared1 = screen->alwaysShared;
- rfbBool save_shared2 = screen->neverShared;
-
- screen->alwaysShared = TRUE;
- screen->neverShared = FALSE;
-
- screen->passwordCheck = password_check_chat_helper;
- for (i=0; i<30; i++) {
- rfbPE(-1);
- if (!chat_window_client) {
- break;
- }
- if (chat_window_client->state == RFB_NORMAL) {
- break;
- }
- }
-
- screen->passwordCheck = pwchk_save;
- screen->alwaysShared = save_shared1;
- screen->neverShared = save_shared2;
- }
- }
-}
-
-void set_text_chat(rfbClientPtr cl, int len, char *txt) {
- int dochat = 1;
- rfbClientIteratorPtr iter;
- rfbClientPtr cl2;
- unsigned int ulen = (unsigned int) len;
-
- if (no_ultra_ext || ! dochat) {
- return;
- }
-
- if (unixpw_in_progress) {
- rfbLog("set_text_chat: unixpw_in_progress, dropping client.\n");
- rfbCloseClient(cl);
- return;
- }
-#if LIBVNCSERVER_HAS_TEXTCHAT
-
- if (chat_window && chat_window_client == NULL && ulen == rfbTextChatOpen) {
- try_local_chat_window();
- }
-
- saw_ultra_chat = 1;
-
- iter = rfbGetClientIterator(screen);
- while( (cl2 = rfbClientIteratorNext(iter)) ) {
- unsigned int ulen = (unsigned int) len;
- if (cl2 == cl) {
- continue;
- }
- if (cl2->state != RFB_NORMAL) {
- continue;
- }
-
- SEND_LOCK(cl2);
-
- if (ulen == rfbTextChatOpen) {
- rfbSendTextChatMessage(cl2, rfbTextChatOpen, "");
- } else if (ulen == rfbTextChatClose) {
- rfbSendTextChatMessage(cl2, rfbTextChatClose, "");
- /* not clear what is going on WRT close and finished... */
- rfbSendTextChatMessage(cl2, rfbTextChatFinished, "");
- } else if (ulen == rfbTextChatFinished) {
- rfbSendTextChatMessage(cl2, rfbTextChatFinished, "");
- } else if (len <= rfbTextMaxSize) {
- rfbSendTextChatMessage(cl2, len, txt);
- }
-
- SEND_UNLOCK(cl2);
- }
- rfbReleaseClientIterator(iter);
-
- if (ulen == rfbTextChatClose && cl != NULL) {
- /* not clear what is going on WRT close and finished... */
- SEND_LOCK(cl);
- rfbSendTextChatMessage(cl, rfbTextChatFinished, "");
- SEND_UNLOCK(cl);
- }
-#endif
-}
-
-int get_keyboard_led_state_hook(rfbScreenInfoPtr s) {
- if (s) {}
- if (unixpw_in_progress) {
- rfbLog("get_keyboard_led_state_hook: unixpw_in_progress, skipping.\n");
- return 0;
- }
- return 0;
-}
-int get_file_transfer_permitted(rfbClientPtr cl) {
- allowed_input_t input;
- if (unixpw_in_progress) {
- rfbLog("get_file_transfer_permitted: unixpw_in_progress, dropping client.\n");
- rfbCloseClient(cl);
- return FALSE;
- }
-if (0) fprintf(stderr, "get_file_transfer_permitted called\n");
- if (view_only) {
- return FALSE;
- }
- if (cl->viewOnly) {
- return FALSE;
- }
- get_allowed_input(cl, &input);
- if (!input.files) {
- return FALSE;
- }
- if (screen->permitFileTransfer) {
- saw_ultra_file = 1;
- }
- return screen->permitFileTransfer;
-}
-
-
diff --git a/x11vnc/xevents.h b/x11vnc/xevents.h
deleted file mode 100644
index 5b8bdce..0000000
--- a/x11vnc/xevents.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_XEVENTS_H
-#define _X11VNC_XEVENTS_H
-
-/* -- xevents.h -- */
-
-extern int grab_buster;
-extern int grab_kbd;
-extern int grab_ptr;
-extern int grab_always;
-extern int ungrab_both;
-extern int grab_local;
-extern int sync_tod_delay;
-
-extern void initialize_vnc_connect_prop(void);
-extern void initialize_x11vnc_remote_prop(void);
-extern void initialize_clipboard_atom(void);
-extern void spawn_grab_buster(void);
-extern void sync_tod_with_servertime(void);
-extern void check_keycode_state(void);
-extern void check_autorepeat(void);
-extern void set_prop_atom(Atom atom);
-extern void check_xevents(int reset);
-extern void xcut_receive(char *text, int len, rfbClientPtr cl);
-
-extern void kbd_release_all_keys(rfbClientPtr cl);
-extern void set_single_window(rfbClientPtr cl, int x, int y);
-extern void set_server_input(rfbClientPtr cl, int s);
-extern void set_text_chat(rfbClientPtr cl, int l, char *t);
-extern int get_keyboard_led_state_hook(rfbScreenInfoPtr s);
-extern int get_file_transfer_permitted(rfbClientPtr cl);
-extern void get_prop(char *str, int len, Atom prop, Window w);
-extern int guess_dm_gone(int t1, int t2);
-
-
-#endif /* _X11VNC_XEVENTS_H */
diff --git a/x11vnc/xinerama.c b/x11vnc/xinerama.c
deleted file mode 100644
index 0d2ca71..0000000
--- a/x11vnc/xinerama.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- xinerama.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "blackout_t.h"
-#include "scan.h"
-
-/*
- * routines related to xinerama and blacking out rectangles
- */
-
-/* blacked-out region (-blackout, -xinerama) */
-
-#define BLACKR_MAX 100
-blackout_t blackr[BLACKR_MAX]; /* hardwired max blackouts */
-tile_blackout_t *tile_blackout;
-int blackouts = 0;
-
-void initialize_blackouts_and_xinerama(void);
-void push_sleep(int n);
-void push_black_screen(int n);
-void refresh_screen(int push);
-void zero_fb(int x1, int y1, int x2, int y2);
-
-
-static void initialize_blackouts(char *list);
-static void blackout_tiles(void);
-static void initialize_xinerama (void);
-
-
-/*
- * Take a comma separated list of geometries: WxH+X+Y and register them as
- * rectangles to black out from the screen.
- */
-static void initialize_blackouts(char *list) {
- char *p, *blist = strdup(list);
- int x, y, X, Y, h, w, t;
-
- p = strtok(blist, ", \t");
- while (p) {
- if (!strcmp("noptr", p)) {
- blackout_ptr = 1;
- rfbLog("pointer will be blocked from blackout "
- "regions\n");
- p = strtok(NULL, ", \t");
- continue;
- }
- if (! parse_geom(p, &w, &h, &x, &y, dpy_x, dpy_y)) {
- if (*p != '\0') {
- rfbLog("skipping invalid geometry: %s\n", p);
- }
- p = strtok(NULL, ", \t");
- continue;
- }
- w = nabs(w);
- h = nabs(h);
- x = nfix(x, dpy_x);
- y = nfix(y, dpy_y);
- X = x + w;
- Y = y + h;
- X = nfix(X, dpy_x+1);
- Y = nfix(Y, dpy_y+1);
- if (x > X) {
- t = X; X = x; x = t;
- }
- if (y > Y) {
- t = Y; Y = y; y = t;
- }
-
- /* take clipping region into account */
- x = nfix(x - coff_x, wdpy_x);
- X = nfix(X - coff_x, wdpy_x);
- y = nfix(y - coff_y, wdpy_y);
- Y = nfix(Y - coff_y, wdpy_y);
-
- if (x < 0 || x > dpy_x || y < 0 || y > dpy_y ||
- X < 0 || X > dpy_x || Y < 0 || Y > dpy_y ||
- x == X || y == Y) {
- rfbLog("skipping invalid blackout geometry: %s x="
- "%d-%d,y=%d-%d,w=%d,h=%d\n", p, x, X, y, Y, w, h);
- } else {
- rfbLog("blackout rect: %s: x=%d-%d y=%d-%d\n", p,
- x, X, y, Y);
-
- /*
- * note that the black out is x1 <= x but x < x2
- * for the region. i.e. the x2, y2 are outside
- * by 1 pixel.
- */
- blackr[blackouts].x1 = x;
- blackr[blackouts].y1 = y;
- blackr[blackouts].x2 = X;
- blackr[blackouts].y2 = Y;
- blackouts++;
- if (blackouts >= BLACKR_MAX) {
- rfbLog("too many blackouts: %d\n", blackouts);
- break;
- }
- }
- p = strtok(NULL, ", \t");
- }
- free(blist);
-}
-
-/*
- * Now that all blackout rectangles have been constructed, see what overlap
- * they have with the tiles in the system. If a tile is touched by a
- * blackout, record information.
- */
-static void blackout_tiles(void) {
- int tx, ty;
- int debug_bo = 0;
- if (! blackouts) {
- return;
- }
- if (getenv("DEBUG_BLACKOUT") != NULL) {
- debug_bo = 1;
- }
-
- /*
- * to simplify things drop down to single copy mode, etc...
- */
- single_copytile = 1;
- /* loop over all tiles. */
- for (ty=0; ty < ntiles_y; ty++) {
- for (tx=0; tx < ntiles_x; tx++) {
- sraRegionPtr tile_reg, black_reg;
- sraRect rect;
- sraRectangleIterator *iter;
- int n, b, x1, y1, x2, y2, cnt;
-
- /* tile number and coordinates: */
- n = tx + ty * ntiles_x;
- x1 = tx * tile_x;
- y1 = ty * tile_y;
- x2 = x1 + tile_x;
- y2 = y1 + tile_y;
- if (x2 > dpy_x) {
- x2 = dpy_x;
- }
- if (y2 > dpy_y) {
- y2 = dpy_y;
- }
-
- /* make regions for the tile and the blackouts: */
- black_reg = (sraRegionPtr) sraRgnCreate();
- tile_reg = (sraRegionPtr) sraRgnCreateRect(x1, y1,
- x2, y2);
-
- tile_blackout[n].cover = 0;
- tile_blackout[n].count = 0;
-
- /* union of blackouts */
- for (b=0; b < blackouts; b++) {
- sraRegionPtr tmp_reg = (sraRegionPtr)
- sraRgnCreateRect(blackr[b].x1,
- blackr[b].y1, blackr[b].x2, blackr[b].y2);
-
- sraRgnOr(black_reg, tmp_reg);
- sraRgnDestroy(tmp_reg);
- }
-
- if (! sraRgnAnd(black_reg, tile_reg)) {
- /*
- * no intersection for this tile, so we
- * are done.
- */
- sraRgnDestroy(black_reg);
- sraRgnDestroy(tile_reg);
- continue;
- }
-
- /*
- * loop over rectangles that make up the blackout
- * region:
- */
- cnt = 0;
- iter = sraRgnGetIterator(black_reg);
- while (sraRgnIteratorNext(iter, &rect)) {
-
- /* make sure x1 < x2 and y1 < y2 */
- if (rect.x1 > rect.x2) {
- int tmp = rect.x2;
- rect.x2 = rect.x1;
- rect.x1 = tmp;
- }
- if (rect.y1 > rect.y2) {
- int tmp = rect.y2;
- rect.y2 = rect.y1;
- rect.y1 = tmp;
- }
-
- /* store coordinates */
- tile_blackout[n].bo[cnt].x1 = rect.x1;
- tile_blackout[n].bo[cnt].y1 = rect.y1;
- tile_blackout[n].bo[cnt].x2 = rect.x2;
- tile_blackout[n].bo[cnt].y2 = rect.y2;
-
- /* note if the tile is completely obscured */
- if (rect.x1 == x1 && rect.y1 == y1 &&
- rect.x2 == x2 && rect.y2 == y2) {
- tile_blackout[n].cover = 2;
- if (debug_bo) {
- fprintf(stderr, "full: %d=%d,%d"
- " (%d-%d) (%d-%d)\n",
- n, tx, ty, x1, x2, y1, y2);
- }
- } else {
- tile_blackout[n].cover = 1;
- if (debug_bo) {
- fprintf(stderr, "part: %d=%d,%d"
- " (%d-%d) (%d-%d)\n",
- n, tx, ty, x1, x2, y1, y2);
- }
- }
-
- if (++cnt >= BO_MAX) {
- rfbLog("too many blackout rectangles "
- "for tile %d=%d,%d.\n", n, tx, ty);
- break;
- }
- }
- sraRgnReleaseIterator(iter);
-
- sraRgnDestroy(black_reg);
- sraRgnDestroy(tile_reg);
-
- tile_blackout[n].count = cnt;
- if (debug_bo && cnt > 1) {
- rfbLog("warning: multiple region overlaps[%d] "
- "for tile %d=%d,%d.\n", cnt, n, tx, ty);
- }
- }
- }
-}
-
-static int did_xinerama_clip = 0;
-
-void check_xinerama_clip(void) {
-#if LIBVNCSERVER_HAVE_LIBXINERAMA
- int n, k, i, ev, er, juse = -1;
- int score[32], is = 0;
- XineramaScreenInfo *x;
-
- if (!clip_str || !dpy) {
- return;
- }
- if (sscanf(clip_str, "xinerama%d", &k) == 1) {
- ;
- } else if (sscanf(clip_str, "screen%d", &k) == 1) {
- ;
- } else {
- return;
- }
-
- free(clip_str);
- clip_str = NULL;
-
- if (! XineramaQueryExtension(dpy, &ev, &er)) {
- return;
- }
- if (! XineramaIsActive(dpy)) {
- return;
- }
- x = XineramaQueryScreens(dpy, &n);
- if (k < 0 || k >= n) {
- XFree_wr(x);
- return;
- }
- for (i=0; i < n; i++) {
- score[is++] = nabs(x[i].x_org) + nabs(x[i].y_org);
- if (is >= 32) {
- break;
- }
- }
- for (i=0; i <= k; i++) {
- int j, jmon = 0, mon = -1, mox = -1;
- for (j=0; j < is; j++) {
- if (mon < 0 || score[j] < mon) {
- mon = score[j];
- jmon = j;
- }
- if (mox < 0 || score[j] > mox) {
- mox = score[j];
- }
- }
- juse = jmon;
- score[juse] = mox+1+i;
- }
-
- if (juse >= 0 && juse < n) {
- char str[64];
- sprintf(str, "%dx%d+%d+%d", x[juse].width, x[juse].height,
- x[juse].x_org, x[juse].y_org);
- clip_str = strdup(str);
- did_xinerama_clip = 1;
- } else {
- clip_str = strdup("");
- }
- XFree_wr(x);
- if (!quiet) {
- rfbLog("set -clip to '%s' for xinerama%d\n", clip_str, k);
- }
-#endif
-}
-
-static void initialize_xinerama (void) {
-#if !LIBVNCSERVER_HAVE_LIBXINERAMA
- if (!raw_fb_str) {
- rfbLog("Xinerama: Library libXinerama is not available to determine\n");
- rfbLog("Xinerama: the head geometries, consider using -blackout\n");
- rfbLog("Xinerama: if the screen is non-rectangular.\n");
- }
-#else
- XineramaScreenInfo *sc, *xineramas;
- sraRegionPtr black_region, tmp_region;
- sraRectangleIterator *iter;
- sraRect rect;
- char *bstr, *tstr;
- int ev, er, i, n, rcnt;
-
- RAWFB_RET_VOID
-
- X_LOCK;
- if (! XineramaQueryExtension(dpy, &ev, &er)) {
- if (verbose) {
- rfbLog("Xinerama: disabling: display does not support it.\n");
- }
- xinerama = 0;
- xinerama_present = 0;
- X_UNLOCK;
- return;
- }
- if (! XineramaIsActive(dpy)) {
- /* n.b. change to XineramaActive(dpy, window) someday */
- if (verbose) {
- rfbLog("Xinerama: disabling: not active on display.\n");
- }
- xinerama = 0;
- xinerama_present = 0;
- X_UNLOCK;
- return;
- }
- xinerama_present = 1;
- rfbLog("\n");
- rfbLog("Xinerama is present and active (e.g. multi-head).\n");
-
- /* n.b. change to XineramaGetData() someday */
- xineramas = XineramaQueryScreens(dpy, &n);
- rfbLog("Xinerama: number of sub-screens: %d\n", n);
-
- if (! use_xwarppointer && ! got_noxwarppointer && n > 1) {
- rfbLog("Xinerama: enabling -xwarppointer mode to try to correct\n");
- rfbLog("Xinerama: mouse pointer motion. XTEST+XINERAMA bug.\n");
- rfbLog("Xinerama: Use -noxwarppointer to force XTEST.\n");
- use_xwarppointer = 1;
- }
-
- if (n == 1) {
- rfbLog("Xinerama: no blackouts needed (only one sub-screen)\n");
- rfbLog("\n");
- XFree_wr(xineramas);
- X_UNLOCK;
- return; /* must be OK w/o change */
- }
-
- black_region = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
-
- sc = xineramas;
- for (i=0; i<n; i++) {
- int x, y, w, h;
-
- x = sc->x_org;
- y = sc->y_org;
- w = sc->width;
- h = sc->height;
-
- rfbLog("Xinerama: sub-screen[%d] %dx%d+%d+%d\n", i, w, h, x, y);
-
- tmp_region = sraRgnCreateRect(x, y, x + w, y + h);
-
- sraRgnSubtract(black_region, tmp_region);
- sraRgnDestroy(tmp_region);
- sc++;
- }
- XFree_wr(xineramas);
- X_UNLOCK;
-
-
- if (sraRgnEmpty(black_region)) {
- rfbLog("Xinerama: no blackouts needed (screen fills"
- " rectangle)\n");
- rfbLog("\n");
- sraRgnDestroy(black_region);
- return;
- }
- if (did_xinerama_clip) {
- rfbLog("Xinerama: no blackouts due to -clip xinerama.\n");
- return;
- }
-
- /* max len is 10000x10000+10000+10000 (23 chars) per geometry */
- rcnt = (int) sraRgnCountRects(black_region);
- bstr = (char *) malloc(30 * (rcnt+1));
- tstr = (char *) malloc(30);
- bstr[0] = '\0';
-
- iter = sraRgnGetIterator(black_region);
- while (sraRgnIteratorNext(iter, &rect)) {
- int x, y, w, h;
-
- /* make sure x1 < x2 and y1 < y2 */
- if (rect.x1 > rect.x2) {
- int tmp = rect.x2;
- rect.x2 = rect.x1;
- rect.x1 = tmp;
- }
- if (rect.y1 > rect.y2) {
- int tmp = rect.y2;
- rect.y2 = rect.y1;
- rect.y1 = tmp;
- }
- x = rect.x1;
- y = rect.y1;
- w = rect.x2 - x;
- h = rect.y2 - y;
- sprintf(tstr, "%dx%d+%d+%d,", w, h, x, y);
- strcat(bstr, tstr);
- }
- sraRgnReleaseIterator(iter);
- initialize_blackouts(bstr);
- rfbLog("\n");
-
- free(bstr);
- free(tstr);
-#endif
-}
-
-void initialize_blackouts_and_xinerama(void) {
-
- blackouts = 0;
- blackout_ptr = 0;
-
- if (blackout_str != NULL) {
- initialize_blackouts(blackout_str);
- }
- if (xinerama) {
- initialize_xinerama();
- }
- if (blackouts) {
- blackout_tiles();
- /* schedule a copy_screen(), now is too early. */
- do_copy_screen = 1;
- }
-}
-
-void push_sleep(int n) {
- int i;
- for (i=0; i<n; i++) {
- rfbPE(-1);
- if (i != n-1 && defer_update) {
- usleep(defer_update * 1000);
- }
- }
-}
-
-/*
- * try to forcefully push a black screen to all connected clients
- */
-void push_black_screen(int n) {
- int Lx = dpy_x, Ly = dpy_y;
- if (!screen) {
- return;
- }
-#ifndef NO_NCACHE
- if (ncache > 0) {
- Ly = dpy_y * (1+ncache);
- }
-#endif
- zero_fb(0, 0, Lx, Ly);
- mark_rect_as_modified(0, 0, Lx, Ly, 0);
- push_sleep(n);
-}
-
-void refresh_screen(int push) {
- int i;
- if (!screen) {
- return;
- }
- mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
- for (i=0; i<push; i++) {
- rfbPE(-1);
- }
-}
-
-/*
- * Fill the framebuffer with zero for the prescribed rectangle
- */
-void zero_fb(int x1, int y1, int x2, int y2) {
- int pixelsize = bpp/8;
- int line, fill = 0, yfac = 1;
- char *dst;
-
-#ifndef NO_NCACHE
- if (ncache > 0) {
- yfac = 1+ncache;
- if (ncache_xrootpmap) {
- yfac++;
- }
- }
-#endif
-
- if (x1 < 0 || x2 <= x1 || x2 > dpy_x) {
- return;
- }
- if (y1 < 0 || y2 <= y1 || y2 > yfac * dpy_y) {
- return;
- }
- if (! main_fb) {
- return;
- }
-
- dst = main_fb + y1 * main_bytes_per_line + x1 * pixelsize;
- line = y1;
- while (line++ < y2) {
- memset(dst, fill, (size_t) (x2 - x1) * pixelsize);
- dst += main_bytes_per_line;
- }
-}
-
-
diff --git a/x11vnc/xinerama.h b/x11vnc/xinerama.h
deleted file mode 100644
index 6fd00cf..0000000
--- a/x11vnc/xinerama.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_XINERAMA_H
-#define _X11VNC_XINERAMA_H
-
-/* -- xinerama.h -- */
-#include "blackout_t.h"
-
-extern blackout_t blackr[];
-extern tile_blackout_t *tile_blackout;
-extern int blackouts;
-
-extern void initialize_blackouts_and_xinerama(void);
-extern void push_sleep(int n);
-extern void push_black_screen(int n);
-extern void refresh_screen(int push);
-extern void zero_fb(int x1, int y1, int x2, int y2);
-extern void check_xinerama_clip(void);
-
-#endif /* _X11VNC_XINERAMA_H */
diff --git a/x11vnc/xkb_bell.c b/x11vnc/xkb_bell.c
deleted file mode 100644
index 71563d6..0000000
--- a/x11vnc/xkb_bell.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- xkb_bell.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "connections.h"
-
-/*
- * Bell event handling. Requires XKEYBOARD extension.
- */
-int xkb_base_event_type = 0;
-
-void initialize_xkb(void);
-void initialize_watch_bell(void);
-void check_bell_event(void);
-
-
-#if LIBVNCSERVER_HAVE_XKEYBOARD
-
-/*
- * check for XKEYBOARD, set up xkb_base_event_type
- */
-void initialize_xkb(void) {
- int ir, reason;
- int op, ev, er, maj, min;
-
- RAWFB_RET_VOID
-
- if (xkbcompat) {
- xkb_present = 0;
- } else if (! XkbQueryExtension(dpy, &op, &ev, &er, &maj, &min)) {
- if (! quiet) {
- rfbLog("warning: XKEYBOARD extension not present.\n");
- }
- xkb_present = 0;
- } else {
- xkb_present = 1;
- }
-
- if (! xkb_present) {
- return;
- }
-
- if (! xauth_raw(1)) {
- return;
- }
-
- if (! XkbOpenDisplay(DisplayString(dpy), &xkb_base_event_type, &ir,
- NULL, NULL, &reason) ) {
- if (! quiet) {
- rfbLog("warning: disabling XKEYBOARD. XkbOpenDisplay"
- " failed.\n");
- }
- xkb_base_event_type = 0;
- xkb_present = 0;
- }
- xauth_raw(0);
-}
-
-void initialize_watch_bell(void) {
- if (! xkb_present) {
- if (! quiet) {
- rfbLog("warning: disabling bell. XKEYBOARD ext. "
- "not present.\n");
- }
- watch_bell = 0;
- sound_bell = 0;
- return;
- }
-
- RAWFB_RET_VOID
-
- XkbSelectEvents(dpy, XkbUseCoreKbd, XkbBellNotifyMask, 0);
-
- if (! watch_bell) {
- return;
- }
- if (! XkbSelectEvents(dpy, XkbUseCoreKbd, XkbBellNotifyMask,
- XkbBellNotifyMask) ) {
- if (! quiet) {
- rfbLog("warning: disabling bell. XkbSelectEvents"
- " failed.\n");
- }
- watch_bell = 0;
- sound_bell = 0;
- }
-}
-
-/*
- * We call this periodically to process any bell events that have
- * taken place.
- */
-void check_bell_event(void) {
- XEvent xev;
- XkbAnyEvent *xkb_ev;
- int got_bell = 0;
-
- if (! xkb_base_event_type) {
- return;
- }
- RAWFB_RET_VOID
-
- /* caller does X_LOCK */
- if (! XCheckTypedEvent(dpy, xkb_base_event_type, &xev)) {
- return;
- }
- if (! watch_bell) {
- /* we return here to avoid xkb events piling up */
- return;
- }
-
- xkb_ev = (XkbAnyEvent *) &xev;
- if (xkb_ev->xkb_type == XkbBellNotify) {
- got_bell = 1;
- }
-
- if (got_bell && sound_bell) {
- if (! all_clients_initialized()) {
- rfbLog("check_bell_event: not sending bell: "
- "uninitialized clients\n");
- } else {
- if (screen && client_count) {
- rfbSendBell(screen);
- }
- }
- }
-}
-#else
-void initialize_watch_bell(void) {
- watch_bell = 0;
- sound_bell = 0;
-}
-void check_bell_event(void) {}
-#endif
-
-
diff --git a/x11vnc/xkb_bell.h b/x11vnc/xkb_bell.h
deleted file mode 100644
index 16762e7..0000000
--- a/x11vnc/xkb_bell.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_XKB_BELL_H
-#define _X11VNC_XKB_BELL_H
-
-/* -- xkb_bell.h -- */
-
-extern int xkb_base_event_type;
-
-extern void initialize_xkb(void);
-extern void initialize_watch_bell(void);
-extern void check_bell_event(void);
-
-#endif /* _X11VNC_XKB_BELL_H */
diff --git a/x11vnc/xrandr.c b/x11vnc/xrandr.c
deleted file mode 100644
index f2fb5ea..0000000
--- a/x11vnc/xrandr.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- xrandr.c -- */
-
-#include "x11vnc.h"
-#include "cleanup.h"
-#include "connections.h"
-#include "remote.h"
-#include "screen.h"
-#include "win_utils.h"
-
-time_t last_subwin_trap = 0;
-int subwin_trap_count = 0;
-XErrorHandler old_getimage_handler;
-
-int xrandr_present = 0;
-int xrandr_width = -1;
-int xrandr_height = -1;
-int xrandr_rotation = -1;
-Time xrandr_timestamp = 0;
-Time xrandr_cfg_time = 0;
-
-void initialize_xrandr(void);
-int check_xrandr_event(char *msg);
-int known_xrandr_mode(char *s);
-
-static int handle_subwin_resize(char *msg);
-static void handle_xrandr_change(int new_x, int new_y);
-
-
-void initialize_xrandr(void) {
- if (xrandr_present && dpy) {
-#if LIBVNCSERVER_HAVE_LIBXRANDR
- Rotation rot;
-
- X_LOCK;
- xrandr_width = XDisplayWidth(dpy, scr);
- xrandr_height = XDisplayHeight(dpy, scr);
- XRRRotations(dpy, scr, &rot);
- xrandr_rotation = (int) rot;
- if (xrandr || xrandr_maybe) {
- XRRSelectInput(dpy, rootwin, RRScreenChangeNotifyMask);
- } else {
- XRRSelectInput(dpy, rootwin, 0);
- }
- X_UNLOCK;
-#endif
- } else if (xrandr) {
- rfbLog("-xrandr mode specified, but no RANDR support on\n");
- rfbLog(" display or in client library. Disabling -xrandr "
- "mode.\n");
- xrandr = 0;
- }
-}
-
-static int handle_subwin_resize(char *msg) {
- int new_x, new_y;
- int i, check = 10, ms = 250; /* 2.5 secs total... */
-
- if (msg) {} /* unused vars warning: */
- if (! subwin) {
- return 0; /* hmmm... */
- }
- if (! valid_window(subwin, NULL, 0)) {
- rfbLogEnable(1);
- rfbLog("subwin 0x%lx went away!\n", subwin);
- X_UNLOCK;
- clean_up_exit(1);
- }
- if (! get_window_size(subwin, &new_x, &new_y)) {
- rfbLogEnable(1);
- rfbLog("could not get size of subwin 0x%lx\n", subwin);
- X_UNLOCK;
- clean_up_exit(1);
- }
- if (wdpy_x == new_x && wdpy_y == new_y) {
- /* no change */
- return 0;
- }
-
- /* window may still be changing (e.g. drag resize) */
- for (i=0; i < check; i++) {
- int newer_x, newer_y;
- usleep(ms * 1000);
-
- if (! get_window_size(subwin, &newer_x, &newer_y)) {
- rfbLogEnable(1);
- rfbLog("could not get size of subwin 0x%lx\n", subwin);
- clean_up_exit(1);
- }
- if (new_x == newer_x && new_y == newer_y) {
- /* go for it... */
- break;
- } else {
- rfbLog("subwin 0x%lx still changing size...\n", subwin);
- new_x = newer_x;
- new_y = newer_y;
- }
- }
-
- rfbLog("subwin 0x%lx new size: x: %d -> %d, y: %d -> %d\n",
- subwin, wdpy_x, new_x, wdpy_y, new_y);
- rfbLog("calling handle_xrandr_change() for resizing\n");
-
- X_UNLOCK;
- handle_xrandr_change(new_x, new_y);
- return 1;
-}
-
-static void handle_xrandr_change(int new_x, int new_y) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- RAWFB_RET_VOID
-
- /* assumes no X_LOCK */
-
- /* sanity check xrandr_mode */
- if (! xrandr_mode) {
- xrandr_mode = strdup("default");
- } else if (! known_xrandr_mode(xrandr_mode)) {
- free(xrandr_mode);
- xrandr_mode = strdup("default");
- }
- rfbLog("xrandr_mode: %s\n", xrandr_mode);
- if (!strcmp(xrandr_mode, "exit")) {
- close_all_clients();
- rfbLog(" shutting down due to XRANDR event.\n");
- clean_up_exit(0);
- }
- if (!strcmp(xrandr_mode, "newfbsize") && screen) {
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (cl->useNewFBSize) {
- continue;
- }
- rfbLog(" closing client %s (no useNewFBSize"
- " support).\n", cl->host);
- rfbCloseClient(cl);
- rfbClientConnectionGone(cl);
- }
- rfbReleaseClientIterator(iter);
- }
-
- /* default, resize, and newfbsize create a new fb: */
- rfbLog("check_xrandr_event: trying to create new framebuffer...\n");
- if (new_x < wdpy_x || new_y < wdpy_y) {
- check_black_fb();
- }
- do_new_fb(1);
- rfbLog("check_xrandr_event: fb WxH: %dx%d\n", wdpy_x, wdpy_y);
-}
-
-int check_xrandr_event(char *msg) {
- XEvent xev;
-
- RAWFB_RET(0)
-
- /* it is assumed that X_LOCK is on at this point. */
-
- if (subwin) {
- return handle_subwin_resize(msg);
- }
-#if LIBVNCSERVER_HAVE_LIBXRANDR
- if (! xrandr_present) {
- return 0;
- }
- if (! xrandr && ! xrandr_maybe) {
- return 0;
- }
-
-
- if (xrandr_base_event_type && XCheckTypedEvent(dpy,
- xrandr_base_event_type + RRScreenChangeNotify, &xev)) {
- int do_change, qout = 0;
- static int first = 1;
- XRRScreenChangeNotifyEvent *rev;
-
- rev = (XRRScreenChangeNotifyEvent *) &xev;
-
- if (first && ! xrandr) {
- fprintf(stderr, "\n");
- if (getenv("X11VNC_DEBUG_XRANDR") == NULL) {
- qout = 1;
- }
- }
- first = 0;
-
- rfbLog("check_xrandr_event():\n");
- rfbLog("Detected XRANDR event at location '%s':\n", msg);
-
- if (qout) {
- ;
- } else {
- rfbLog(" serial: %d\n", (int) rev->serial);
- rfbLog(" timestamp: %d\n", (int) rev->timestamp);
- rfbLog(" cfg_timestamp: %d\n", (int) rev->config_timestamp);
- rfbLog(" size_id: %d\n", (int) rev->size_index);
- rfbLog(" sub_pixel: %d\n", (int) rev->subpixel_order);
- rfbLog(" rotation: %d\n", (int) rev->rotation);
- rfbLog(" width: %d\n", (int) rev->width);
- rfbLog(" height: %d\n", (int) rev->height);
- rfbLog(" mwidth: %d mm\n", (int) rev->mwidth);
- rfbLog(" mheight: %d mm\n", (int) rev->mheight);
- rfbLog("\n");
- rfbLog("check_xrandr_event: previous WxH: %dx%d\n",
- wdpy_x, wdpy_y);
- }
-
- if (wdpy_x == rev->width && wdpy_y == rev->height &&
- xrandr_rotation == (int) rev->rotation) {
- rfbLog("check_xrandr_event: no change detected.\n");
- do_change = 0;
- if (! xrandr) {
- rfbLog("check_xrandr_event: "
- "enabling full XRANDR trapping anyway.\n");
- xrandr = 1;
- }
- } else {
- do_change = 1;
- if (! xrandr) {
- rfbLog("check_xrandr_event: Resize; "
- "enabling full XRANDR trapping.\n");
- xrandr = 1;
- }
- }
-
- xrandr_width = rev->width;
- xrandr_height = rev->height;
- xrandr_timestamp = rev->timestamp;
- xrandr_cfg_time = rev->config_timestamp;
- xrandr_rotation = (int) rev->rotation;
-
- if (! qout) rfbLog("check_xrandr_event: updating config...\n");
- XRRUpdateConfiguration(&xev);
-
- if (do_change) {
- /* under do_change caller normally returns before its X_UNLOCK */
- X_UNLOCK;
- handle_xrandr_change(rev->width, rev->height);
- X_LOCK;
- }
- if (qout) {
- return do_change;
- }
- rfbLog("check_xrandr_event: current WxH: %dx%d\n",
- XDisplayWidth(dpy, scr), XDisplayHeight(dpy, scr));
- rfbLog("check_xrandr_event(): returning control to"
- " caller...\n");
-
-
- return do_change;
- }
-#else
- xev.type = 0;
-#endif
-
-
- return 0;
-}
-
-int known_xrandr_mode(char *s) {
-/*
- * default:
- * resize: the default
- * exit: shutdown clients and exit.
- * newfbsize: shutdown clients that do not support NewFBSize encoding.
- */
- if (strcmp(s, "default") && strcmp(s, "resize") &&
- strcmp(s, "exit") && strcmp(s, "newfbsize")) {
- return 0;
- } else {
- return 1;
- }
-}
-
-
diff --git a/x11vnc/xrandr.h b/x11vnc/xrandr.h
deleted file mode 100644
index 3f898f6..0000000
--- a/x11vnc/xrandr.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_XRANDR_H
-#define _X11VNC_XRANDR_H
-
-/* -- xrandr.h -- */
-
-extern time_t last_subwin_trap;
-extern int subwin_trap_count;
-extern XErrorHandler old_getimage_handler;
-
-extern int xrandr_present;
-extern int xrandr_width;
-extern int xrandr_height;
-extern int xrandr_rotation;
-extern Time xrandr_timestamp;
-extern Time xrandr_cfg_time;
-
-extern void initialize_xrandr(void);
-extern int check_xrandr_event(char *msg);
-extern int known_xrandr_mode(char *s);
-
-#define XRANDR_SET_TRAP_RET(x,y) \
- if (subwin || xrandr) { \
- trapped_getimage_xerror = 0; \
- old_getimage_handler = XSetErrorHandler(trap_getimage_xerror); \
- if (check_xrandr_event(y)) { \
- trapped_getimage_xerror = 0; \
- XSetErrorHandler(old_getimage_handler); \
- X_UNLOCK; \
- return(x); \
- } \
- }
-#define XRANDR_CHK_TRAP_RET(x,y) \
- if (subwin || xrandr) { \
- if (trapped_getimage_xerror) { \
- if (subwin) { \
- static int last = 0; \
- subwin_trap_count++; \
- if (time(NULL) > last_subwin_trap + 60) { \
- rfbLog("trapped GetImage xerror" \
- " in SUBWIN mode. [%d]\n", \
- subwin_trap_count); \
- last_subwin_trap = time(NULL); \
- last = subwin_trap_count; \
- } \
- if (subwin_trap_count - last > 30) { \
- /* window probably iconified */ \
- usleep(1000*1000); \
- } \
- } else { \
- rfbLog("trapped GetImage xerror" \
- " in XRANDR mode.\n"); \
- } \
- trapped_getimage_xerror = 0; \
- XSetErrorHandler(old_getimage_handler); \
- XFlush_wr(dpy); \
- check_xrandr_event(y); \
- X_UNLOCK; \
- return(x); \
- } \
- }
-
-#endif /* _X11VNC_XRANDR_H */
diff --git a/x11vnc/xrecord.c b/x11vnc/xrecord.c
deleted file mode 100644
index 87e15b9..0000000
--- a/x11vnc/xrecord.c
+++ /dev/null
@@ -1,2084 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- xrecord.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "win_utils.h"
-#include "cleanup.h"
-#include "userinput.h"
-#include "winattr_t.h"
-#include "scrollevent_t.h"
-#include "unixpw.h"
-
-#define SCR_EV_MAX 128
-scroll_event_t scr_ev[SCR_EV_MAX];
-int scr_ev_cnt;
-
-int xrecording = 0;
-int xrecord_set_by_keys = 0;
-int xrecord_set_by_mouse = 0;
-Window xrecord_focus_window = None;
-Window xrecord_wm_window = None;
-Window xrecord_ptr_window = None;
-KeySym xrecord_keysym = NoSymbol;
-
-#define NAMEINFO 2048
-char xrecord_name_info[NAMEINFO];
-
-#define SCR_ATTR_CACHE 8
-winattr_t scr_attr_cache[SCR_ATTR_CACHE];
-static double attr_cache_max_age = 1.5;
-
-Display *rdpy_data = NULL; /* Data connection for RECORD */
-Display *rdpy_ctrl = NULL; /* Control connection for RECORD */
-
-Display *gdpy_ctrl = NULL;
-Display *gdpy_data = NULL;
-int xserver_grabbed = 0;
-
-int trap_record_xerror(Display *, XErrorEvent *);
-
-void initialize_xrecord(void);
-void zerodisp_xrecord(void);
-void shutdown_xrecord(void);
-int xrecord_skip_keysym(rfbKeySym keysym);
-int xrecord_skip_button(int newb, int old);
-int xrecord_scroll_keysym(rfbKeySym keysym);
-void check_xrecord_reset(int force);
-void xrecord_watch(int start, int setby);
-
-
-#if LIBVNCSERVER_HAVE_RECORD
-static XRecordRange *rr_CA = NULL;
-static XRecordRange *rr_CW = NULL;
-static XRecordRange *rr_GS = NULL;
-static XRecordRange *rr_scroll[10];
-static XRecordContext rc_scroll;
-static XRecordClientSpec rcs_scroll;
-static XRecordRange *rr_grab[10];
-static XRecordContext rc_grab;
-static XRecordClientSpec rcs_grab;
-#endif
-static XErrorEvent *trapped_record_xerror_event;
-
-static void xrecord_grabserver(int start);
-static int xrecord_vi_scroll_keysym(rfbKeySym keysym);
-static int xrecord_emacs_scroll_keysym(rfbKeySym keysym);
-static int lookup_attr_cache(Window win, int *cache_index, int *next_index);
-#if LIBVNCSERVER_HAVE_RECORD
-static void record_CA(XPointer ptr, XRecordInterceptData *rec_data);
-static void record_CW(XPointer ptr, XRecordInterceptData *rec_data);
-static void record_switch(XPointer ptr, XRecordInterceptData *rec_data);
-static void record_grab(XPointer ptr, XRecordInterceptData *rec_data);
-static void shutdown_record_context(XRecordContext rc, int bequiet, int reopen);
-#endif
-static void check_xrecord_grabserver(void);
-
-
-int trap_record_xerror(Display *d, XErrorEvent *error) {
- trapped_record_xerror = 1;
- trapped_record_xerror_event = error;
-
- if (d) {} /* unused vars warning: */
-
- return 0;
-}
-
-static void xrecord_grabserver(int start) {
- XErrorHandler old_handler = NULL;
- int rc = 0;
-
- if (debug_grabs) {
- fprintf(stderr, "xrecord_grabserver%d/%d %.5f\n",
- xserver_grabbed, start, dnowx());
- }
-
- if (! gdpy_ctrl || ! gdpy_data) {
- return;
- }
-#if LIBVNCSERVER_HAVE_RECORD
- if (!start) {
- if (! rc_grab) {
- return;
- }
- XRecordDisableContext(gdpy_ctrl, rc_grab);
- XRecordFreeContext(gdpy_ctrl, rc_grab);
- XFlush_wr(gdpy_ctrl);
- rc_grab = 0;
- return;
- }
-
- xserver_grabbed = 0;
-
- rr_grab[0] = rr_GS;
- rcs_grab = XRecordAllClients;
-
- rc_grab = XRecordCreateContext(gdpy_ctrl, 0, &rcs_grab, 1, rr_grab, 1);
- trapped_record_xerror = 0;
- old_handler = XSetErrorHandler(trap_record_xerror);
-
- XSync(gdpy_ctrl, True);
-
- if (! rc_grab || trapped_record_xerror) {
- XCloseDisplay_wr(gdpy_ctrl);
- XCloseDisplay_wr(gdpy_data);
- gdpy_ctrl = NULL;
- gdpy_data = NULL;
- XSetErrorHandler(old_handler);
- return;
- }
- rc = XRecordEnableContextAsync(gdpy_data, rc_grab, record_grab, NULL);
- if (!rc || trapped_record_xerror) {
- XCloseDisplay_wr(gdpy_ctrl);
- XCloseDisplay_wr(gdpy_data);
- gdpy_ctrl = NULL;
- gdpy_data = NULL;
- XSetErrorHandler(old_handler);
- return;
- }
- XFlush_wr(gdpy_data);
- XSetErrorHandler(old_handler);
-#else
- if (!rc || !old_handler) {}
-#endif
- if (debug_grabs) {
- fprintf(stderr, "xrecord_grabserver-done: %.5f\n", dnowx());
- }
-}
-
-void zerodisp_xrecord(void) {
- rdpy_data = NULL;
- rdpy_ctrl = NULL;
- gdpy_data = NULL;
- gdpy_ctrl = NULL;
-}
-
-void initialize_xrecord(void) {
- use_xrecord = 0;
- if (! xrecord_present) {
- return;
- }
- if (nofb) {
- return;
- }
- if (noxrecord) {
- return;
- }
- RAWFB_RET_VOID
-#if LIBVNCSERVER_HAVE_RECORD
-
- if (rr_CA) XFree_wr(rr_CA);
- if (rr_CW) XFree_wr(rr_CW);
- if (rr_GS) XFree_wr(rr_GS);
-
- rr_CA = XRecordAllocRange();
- rr_CW = XRecordAllocRange();
- rr_GS = XRecordAllocRange();
- if (!rr_CA || !rr_CW || !rr_GS) {
- return;
- }
- /* protocol request ranges: */
- rr_CA->core_requests.first = X_CopyArea;
- rr_CA->core_requests.last = X_CopyArea;
-
- rr_CW->core_requests.first = X_ConfigureWindow;
- rr_CW->core_requests.last = X_ConfigureWindow;
-
- rr_GS->core_requests.first = X_GrabServer;
- rr_GS->core_requests.last = X_UngrabServer;
-
- X_LOCK;
- /* open a 2nd control connection to DISPLAY: */
- if (rdpy_data) {
- XCloseDisplay_wr(rdpy_data);
- rdpy_data = NULL;
- }
- if (rdpy_ctrl) {
- XCloseDisplay_wr(rdpy_ctrl);
- rdpy_ctrl = NULL;
- }
- rdpy_ctrl = XOpenDisplay_wr(DisplayString(dpy));
- if (!rdpy_ctrl) {
- fprintf(stderr, "rdpy_ctrl open failed: %s / %s / %s / %s\n", getenv("DISPLAY"), DisplayString(dpy), getenv("XAUTHORITY"), getenv("XAUTHORIT_"));
- }
- XSync(dpy, True);
- XSync(rdpy_ctrl, True);
- /* open datalink connection to DISPLAY: */
- rdpy_data = XOpenDisplay_wr(DisplayString(dpy));
- if (!rdpy_data) {
- fprintf(stderr, "rdpy_data open failed\n");
- }
- if (!rdpy_ctrl || ! rdpy_data) {
- X_UNLOCK;
- return;
- }
- disable_grabserver(rdpy_ctrl, 0);
- disable_grabserver(rdpy_data, 0);
-
- use_xrecord = 1;
-
- /*
- * now set up the GrabServer watcher. We get GrabServer
- * deadlock in XRecordCreateContext() even with XTestGrabServer
- * in place, why? Not sure, so we manually watch for grabs...
- */
- if (gdpy_data) {
- XCloseDisplay_wr(gdpy_data);
- gdpy_data = NULL;
- }
- if (gdpy_ctrl) {
- XCloseDisplay_wr(gdpy_ctrl);
- gdpy_ctrl = NULL;
- }
- xserver_grabbed = 0;
-
- gdpy_ctrl = XOpenDisplay_wr(DisplayString(dpy));
- if (!gdpy_ctrl) {
- fprintf(stderr, "gdpy_ctrl open failed\n");
- }
- XSync(dpy, True);
- XSync(gdpy_ctrl, True);
- gdpy_data = XOpenDisplay_wr(DisplayString(dpy));
- if (!gdpy_data) {
- fprintf(stderr, "gdpy_data open failed\n");
- }
- if (gdpy_ctrl && gdpy_data) {
- disable_grabserver(gdpy_ctrl, 0);
- disable_grabserver(gdpy_data, 0);
- xrecord_grabserver(1);
- }
- X_UNLOCK;
-#endif
-}
-
-void shutdown_xrecord(void) {
-#if LIBVNCSERVER_HAVE_RECORD
-
- if (debug_grabs) {
- fprintf(stderr, "shutdown_xrecord%d %.5f\n",
- xserver_grabbed, dnowx());
- }
-
- if (rr_CA) XFree_wr(rr_CA);
- if (rr_CW) XFree_wr(rr_CW);
- if (rr_GS) XFree_wr(rr_GS);
-
- rr_CA = NULL;
- rr_CW = NULL;
- rr_GS = NULL;
-
- X_LOCK;
- if (rdpy_ctrl && rc_scroll) {
- XRecordDisableContext(rdpy_ctrl, rc_scroll);
- XRecordFreeContext(rdpy_ctrl, rc_scroll);
- XSync(rdpy_ctrl, False);
- rc_scroll = 0;
- }
-
- if (gdpy_ctrl && rc_grab) {
- XRecordDisableContext(gdpy_ctrl, rc_grab);
- XRecordFreeContext(gdpy_ctrl, rc_grab);
- XSync(gdpy_ctrl, False);
- rc_grab = 0;
- }
-
- if (rdpy_data) {
- XCloseDisplay_wr(rdpy_data);
- rdpy_data = NULL;
- }
- if (rdpy_ctrl) {
- XCloseDisplay_wr(rdpy_ctrl);
- rdpy_ctrl = NULL;
- }
- if (gdpy_data) {
- XCloseDisplay_wr(gdpy_data);
- gdpy_data = NULL;
- }
- if (gdpy_ctrl) {
- XCloseDisplay_wr(gdpy_ctrl);
- gdpy_ctrl = NULL;
- }
- xserver_grabbed = 0;
- X_UNLOCK;
-#endif
- use_xrecord = 0;
-
- if (debug_grabs) {
- fprintf(stderr, "shutdown_xrecord-done: %.5f\n", dnowx());
- }
-}
-
-int xrecord_skip_keysym(rfbKeySym keysym) {
- KeySym sym = (KeySym) keysym;
- int ok = -1, matched = 0;
-
- if (scroll_key_list) {
- int k, exclude = 0;
- if (scroll_key_list[0]) {
- exclude = 1;
- }
- k = 1;
- while (scroll_key_list[k] != NoSymbol) {
- if (scroll_key_list[k++] == sym) {
- matched = 1;
- break;
- }
- }
- if (exclude) {
- if (matched) {
- return 1;
- } else {
- ok = 1;
- }
- } else {
- if (matched) {
- ok = 1;
- } else {
- ok = 0;
- }
- }
- }
- if (ok == 1) {
- return 0;
- } else if (ok == 0) {
- return 1;
- }
-
- /* apply various heuristics: */
-
- if (IsModifierKey(sym)) {
- /* Shift, Control, etc, usu. generate no scrolls */
- return 1;
- }
- if (sym == XK_space && scroll_term) {
- /* space in a terminal is usu. full page... */
- Window win;
- static Window prev_top = None;
- int size = 256;
- static char name[256];
-
- X_LOCK;
- win = query_pointer(rootwin);
- X_UNLOCK;
- if (win != None && win != rootwin) {
- if (prev_top != None && win == prev_top) {
- ; /* use cached result */
- } else {
- prev_top = win;
- X_LOCK;
- win = descend_pointer(6, win, name, size);
- X_UNLOCK;
- }
- if (match_str_list(name, scroll_term)) {
- return 1;
- }
- }
- }
-
- /* TBD use typing_rate() so */
- return 0;
-}
-
-int xrecord_skip_button(int new_button, int old) {
- /* unused vars warning: */
- if (new_button || old) {}
-
- return 0;
-}
-
-static int xrecord_vi_scroll_keysym(rfbKeySym keysym) {
- KeySym sym = (KeySym) keysym;
- if (sym == XK_J || sym == XK_j || sym == XK_K || sym == XK_k) {
- return 1; /* vi */
- }
- if (sym == XK_D || sym == XK_d || sym == XK_U || sym == XK_u) {
- return 1; /* Ctrl-d/u */
- }
- if (sym == XK_Z || sym == XK_z) {
- return 1; /* zz, zt, zb .. */
- }
- return 0;
-}
-
-static int xrecord_emacs_scroll_keysym(rfbKeySym keysym) {
- KeySym sym = (KeySym) keysym;
- if (sym == XK_N || sym == XK_n || sym == XK_P || sym == XK_p) {
- return 1; /* emacs */
- }
- /* Must be some more ... */
- return 0;
-}
-
-int xrecord_scroll_keysym(rfbKeySym keysym) {
- KeySym sym = (KeySym) keysym;
- /* X11/keysymdef.h */
-
- if (sym == XK_Return || sym == XK_KP_Enter || sym == XK_Linefeed) {
- return 1; /* Enter */
- }
- if (sym==XK_Up || sym==XK_KP_Up || sym==XK_Down || sym==XK_KP_Down) {
- return 1; /* U/D arrows */
- }
- if (sym == XK_Left || sym == XK_KP_Left || sym == XK_Right ||
- sym == XK_KP_Right) {
- return 1; /* L/R arrows */
- }
- if (xrecord_vi_scroll_keysym(keysym)) {
- return 1;
- }
- if (xrecord_emacs_scroll_keysym(keysym)) {
- return 1;
- }
- return 0;
-}
-
-static int lookup_attr_cache(Window win, int *cache_index, int *next_index) {
- double now, t, oldest = 0.0;
- int i, old_index = -1, count = 0;
- Window cwin;
-
- *cache_index = -1;
- *next_index = -1;
-
- if (win == None) {
- return 0;
- }
- if (attr_cache_max_age == 0.0) {
- return 0;
- }
-
- dtime0(&now);
- for (i=0; i < SCR_ATTR_CACHE; i++) {
-
- cwin = scr_attr_cache[i].win;
- t = scr_attr_cache[i].time;
-
- if (now > t + attr_cache_max_age) {
- /* expire it even if it is the one we want */
- scr_attr_cache[i].win = cwin = None;
- scr_attr_cache[i].fetched = 0;
- scr_attr_cache[i].valid = 0;
- }
-
- if (*next_index == -1 && cwin == None) {
- *next_index = i;
- }
- if (*next_index == -1) {
- /* record oldest */
- if (old_index == -1 || t < oldest) {
- oldest = t;
- old_index = i;
- }
- }
- if (cwin != None) {
- count++;
- }
- if (cwin == win) {
- if (*cache_index == -1) {
- *cache_index = i;
- } else {
- /* remove dups */
- scr_attr_cache[i].win = None;
- scr_attr_cache[i].fetched = 0;
- scr_attr_cache[i].valid = 0;
- }
- }
- }
- if (*next_index == -1) {
- *next_index = old_index;
- }
-
-if (0) fprintf(stderr, "lookup_attr_cache count: %d\n", count);
- if (*cache_index != -1) {
- return 1;
- } else {
- return 0;
- }
-}
-
-
-static XID xrecord_seq = 0;
-static double xrecord_start = 0.0;
-
-#if LIBVNCSERVER_HAVE_RECORD
-static void record_CA(XPointer ptr, XRecordInterceptData *rec_data) {
- xCopyAreaReq *req;
- Window src = None, dst = None, c;
- XWindowAttributes attr, attr2;
- int src_x, src_y, dst_x, dst_y, rx, ry, rx2, ry2;
- int good = 1, dx = 0, dy = 0, k=0, i;
- unsigned int w, h;
- int dba = 0, db = debug_scroll;
- int cache_index, next_index, valid;
- static int must_equal = -1;
-
- if (dba || db) {
- if (rec_data->category == XRecordFromClient) {
- req = (xCopyAreaReq *) rec_data->data;
- if (req->reqType == X_CopyArea) {
- src = req->srcDrawable;
- dst = req->dstDrawable;
- }
- }
- }
-
-if (dba || db > 1) fprintf(stderr, "record_CA-%d id_base: 0x%lx ptr: 0x%lx "
- "seq: 0x%lx rc: 0x%lx cat: %d swapped: %d 0x%lx/0x%lx\n", k++,
- rec_data->id_base, (unsigned long) ptr, xrecord_seq, rc_scroll,
- rec_data->category, rec_data->client_swapped, src, dst);
-
- if (! xrecording) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CA-%d\n", k++);
-
- if (rec_data->id_base == 0) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CA-%d\n", k++);
-
- if ((XID) ptr != xrecord_seq) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CA-%d\n", k++);
-
- if (rec_data->category != XRecordFromClient) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CA-%d\n", k++);
-
- req = (xCopyAreaReq *) rec_data->data;
-
- if (req->reqType != X_CopyArea) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CA-%d\n", k++);
-
- if (must_equal < 0) {
- must_equal = 0;
- if (getenv("X11VNC_SCROLL_MUST_EQUAL")) {
- must_equal = 1;
- }
- }
-
-/*
-
-xterm, gnome-terminal, others.
-
-Note we miss the X_ImageText8 that clears the block cursor. So there is a
-short period of time with a painting error: two cursors, one above the other.
-
- X_ImageText8
- draw: 0x8c00017 nChars: 1, gc: 0x8c00013, x: 101, y: 585, chars=' '
- X_ClearArea
- window: 0x8c00018, x: 2, y: 217, w: 10, h: 5
- X_FillPoly
- draw: 0x8c00018 gc: 0x8c0000a, shape: 0, coordMode: 0,
- X_FillPoly
- draw: 0x8c00018 gc: 0x8c0000b, shape: 0, coordMode: 0,
- X_CopyArea
- src: 0x8c00017, dst: 0x8c00017, gc: 0x8c00013, srcX: 17, srcY: 15, dstX: 17, dstY: 2, w: 480, h: 572
- X_ChangeWindowAttributes
- X_ClearArea
- window: 0x8c00017, x: 17, y: 574, w: 480, h: 13
- X_ChangeWindowAttributes
-
- */
-
- src = req->srcDrawable;
- dst = req->dstDrawable;
- src_x = req->srcX;
- src_y = req->srcY;
- dst_x = req->dstX;
- dst_y = req->dstY;
- w = req->width;
- h = req->height;
-
- if (w*h < (unsigned int) scrollcopyrect_min_area) {
- if (db > 1) fprintf(stderr, "record_CA scroll area too small.\n");
- good = 0;
- } else if (!src || !dst) {
- if (db > 1) fprintf(stderr, "record_CA null src or dst.\n");
- good = 0;
- } else if (scr_ev_cnt >= SCR_EV_MAX) {
- if (db > 1) fprintf(stderr, "record_CA null too many scr events.\n");
- good = 0;
- } else if (must_equal && src != dst) {
- if (db > 1) fprintf(stderr, "record_CA src not equal dst.\n");
- good = 0;
- }
-
- if (src == dst) {
- dx = dst_x - src_x;
- dy = dst_y - src_y;
-
- if (dx != 0 && dy != 0) {
- good = 0;
- }
- }
-
-if (!good && (dba || db > 1)) fprintf(stderr, "record_CA-x src_x: %d src_y: %d "
- "dst_x: %d dst_y: %d w: %d h: %d scr_ev_cnt: %d 0x%lx/0x%lx\n",
- src_x, src_y, dst_x, dst_y, w, h, scr_ev_cnt, src, dst);
-
- if (! good) {
- return;
- }
-
-if (db > 1) fprintf(stderr, "record_CA-%d\n", k++);
-
- /*
- * after all of the above succeeds, now contact X server.
- * we try to get away with some caching here.
- */
- if (lookup_attr_cache(src, &cache_index, &next_index)) {
- i = cache_index;
- attr.x = scr_attr_cache[i].x;
- attr.y = scr_attr_cache[i].y;
- attr.width = scr_attr_cache[i].width;
- attr.height = scr_attr_cache[i].height;
- attr.map_state = scr_attr_cache[i].map_state;
- rx = scr_attr_cache[i].rx;
- ry = scr_attr_cache[i].ry;
- valid = scr_attr_cache[i].valid;
-
- } else {
- valid = valid_window(src, &attr, 1);
-
- if (valid) {
- if (!xtranslate(src, rootwin, 0, 0, &rx, &ry, &c, 1)) {
- valid = 0;
- }
- }
- if (next_index >= 0) {
- i = next_index;
- scr_attr_cache[i].win = src;
- scr_attr_cache[i].fetched = 1;
- scr_attr_cache[i].valid = valid;
- scr_attr_cache[i].time = dnow();
- if (valid) {
- scr_attr_cache[i].x = attr.x;
- scr_attr_cache[i].y = attr.y;
- scr_attr_cache[i].width = attr.width;
- scr_attr_cache[i].height = attr.height;
- scr_attr_cache[i].border_width = attr.border_width;
- scr_attr_cache[i].depth = attr.depth;
- scr_attr_cache[i].class = attr.class;
- scr_attr_cache[i].backing_store =
- attr.backing_store;
- scr_attr_cache[i].map_state = attr.map_state;
-
- scr_attr_cache[i].rx = rx;
- scr_attr_cache[i].ry = ry;
- }
- }
- }
-
- if (! valid) {
- if (db > 1) fprintf(stderr, "record_CA not valid-1.\n");
- return;
- }
-if (db > 1) fprintf(stderr, "record_CA-%d\n", k++);
-
- if (attr.map_state != IsViewable) {
- if (db > 1) fprintf(stderr, "record_CA not viewable-1.\n");
- return;
- }
-
- /* recent gdk/gtk windows use different src and dst. for compositing? */
- if (src != dst) {
- if (lookup_attr_cache(dst, &cache_index, &next_index)) {
- i = cache_index;
- attr2.x = scr_attr_cache[i].x;
- attr2.y = scr_attr_cache[i].y;
- attr2.width = scr_attr_cache[i].width;
- attr2.height = scr_attr_cache[i].height;
- attr2.map_state = scr_attr_cache[i].map_state;
- rx2 = scr_attr_cache[i].rx;
- ry2 = scr_attr_cache[i].ry;
- valid = scr_attr_cache[i].valid;
-
- } else {
- valid = valid_window(dst, &attr2, 1);
-
- if (valid) {
- if (!xtranslate(dst, rootwin, 0, 0, &rx2, &ry2, &c, 1)) {
- valid = 0;
- }
- }
- if (next_index >= 0) {
- i = next_index;
- scr_attr_cache[i].win = dst;
- scr_attr_cache[i].fetched = 1;
- scr_attr_cache[i].valid = valid;
- scr_attr_cache[i].time = dnow();
- if (valid) {
- scr_attr_cache[i].x = attr2.x;
- scr_attr_cache[i].y = attr2.y;
- scr_attr_cache[i].width = attr2.width;
- scr_attr_cache[i].height = attr2.height;
- scr_attr_cache[i].border_width = attr2.border_width;
- scr_attr_cache[i].depth = attr2.depth;
- scr_attr_cache[i].class = attr2.class;
- scr_attr_cache[i].backing_store =
- attr2.backing_store;
- scr_attr_cache[i].map_state = attr2.map_state;
-
- scr_attr_cache[i].rx = rx2;
- scr_attr_cache[i].ry = ry2;
- }
- }
- }
-
-if (dba || db > 1) fprintf(stderr, "record_CA-? src_x: %d src_y: %d "
- "dst_x: %d dst_y: %d w: %d h: %d scr_ev_cnt: %d 0x%lx/0x%lx\n",
- src_x, src_y, dst_x, dst_y, w, h, scr_ev_cnt, src, dst);
-
- if (! valid) {
- if (db > 1) fprintf(stderr, "record_CA not valid-2.\n");
- return;
- }
- if (attr2.map_state != IsViewable) {
- if (db > 1) fprintf(stderr, "record_CA not viewable-2.\n");
- return;
- }
- dst_x = dst_x - (rx - rx2);
- dst_y = dst_y - (ry - ry2);
-
- dx = dst_x - src_x;
- dy = dst_y - src_y;
-
- if (dx != 0 && dy != 0) {
- return;
- }
- }
-
-
- if (0 || dba || db) {
- double st, dt;
- st = (double) rec_data->server_time/1000.0;
- dt = (dnow() - servertime_diff) - st;
- fprintf(stderr, "record_CA-%d *FOUND_SCROLL: src: 0x%lx dx: %d dy: %d "
- "x: %d y: %d w: %d h: %d st: %.4f %.4f %.4f\n", k++, src, dx, dy,
- src_x, src_y, w, h, st, dt, dnowx());
- }
-
- i = scr_ev_cnt;
-
- scr_ev[i].win = src;
- scr_ev[i].frame = None;
- scr_ev[i].dx = dx;
- scr_ev[i].dy = dy;
- scr_ev[i].x = rx + dst_x;
- scr_ev[i].y = ry + dst_y;
- scr_ev[i].w = w;
- scr_ev[i].h = h;
- scr_ev[i].t = ((double) rec_data->server_time)/1000.0;
- scr_ev[i].win_x = rx;
- scr_ev[i].win_y = ry;
- scr_ev[i].win_w = attr.width;
- scr_ev[i].win_h = attr.height;
- scr_ev[i].new_x = 0;
- scr_ev[i].new_y = 0;
- scr_ev[i].new_w = 0;
- scr_ev[i].new_h = 0;
-
- if (dx == 0) {
- if (dy > 0) {
- scr_ev[i].new_x = rx + src_x;
- scr_ev[i].new_y = ry + src_y;
- scr_ev[i].new_w = w;
- scr_ev[i].new_h = dy;
- } else {
- scr_ev[i].new_x = rx + src_x;
- scr_ev[i].new_y = ry + dst_y + h;
- scr_ev[i].new_w = w;
- scr_ev[i].new_h = -dy;
- }
- } else if (dy == 0) {
- if (dx > 0) {
- scr_ev[i].new_x = rx + src_x;
- scr_ev[i].new_y = rx + src_y;
- scr_ev[i].new_w = dx;
- scr_ev[i].new_h = h;
- } else {
- scr_ev[i].new_x = rx + dst_x + w;
- scr_ev[i].new_y = ry + src_y;
- scr_ev[i].new_w = -dx;
- scr_ev[i].new_h = h;
- }
- }
-
- scr_ev_cnt++;
-}
-
-typedef struct cw_event {
- Window win;
- int x, y, w, h;
-} cw_event_t;
-
-#define MAX_CW 128
-static cw_event_t cw_events[MAX_CW];
-
-static void record_CW(XPointer ptr, XRecordInterceptData *rec_data) {
- xConfigureWindowReq *req;
- Window win = None, c;
- Window src = None, dst = None;
- XWindowAttributes attr;
- int absent = 0x100000;
- int src_x, src_y, dst_x, dst_y, rx, ry;
- int good = 1, dx, dy, k=0, i, j, match, list[3];
- int f_x, f_y, f_w, f_h;
- int x, y, w, h;
- int x0, y0, w0, h0, x1, y1, w1, h1, x2, y2, w2, h2;
- static int index = 0;
- unsigned int vals[4];
- unsigned tmask;
- char *data;
- int dba = 0, db = debug_scroll;
- int cache_index, next_index, valid;
-
- if (db) {
- if (rec_data->category == XRecordFromClient) {
- req = (xConfigureWindowReq *) rec_data->data;
- if (req->reqType == X_ConfigureWindow) {
- src = req->window;
- }
- }
- }
-
-if (dba || db > 1) fprintf(stderr, "record_CW-%d id_base: 0x%lx ptr: 0x%lx "
- "seq: 0x%lx rc: 0x%lx cat: %d swapped: %d 0x%lx/0x%lx\n", k++,
- rec_data->id_base, (unsigned long) ptr, xrecord_seq, rc_scroll,
- rec_data->category, rec_data->client_swapped, src, dst);
-
-
- if (! xrecording) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- if ((XID) ptr != xrecord_seq) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- if (rec_data->id_base == 0) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- if (rec_data->category == XRecordStartOfData) {
- index = 0;
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- if (rec_data->category != XRecordFromClient) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- if (rec_data->client_swapped) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- req = (xConfigureWindowReq *) rec_data->data;
-
- if (req->reqType != X_ConfigureWindow) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- tmask = req->mask;
-
- tmask &= ~CWX;
- tmask &= ~CWY;
- tmask &= ~CWWidth;
- tmask &= ~CWHeight;
-
- if (tmask) {
- /* require no more than these 4 flags */
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- f_x = req->mask & CWX;
- f_y = req->mask & CWY;
- f_w = req->mask & CWWidth;
- f_h = req->mask & CWHeight;
-
- if (! f_x || ! f_y) {
- if (f_w && f_h) {
- ; /* netscape 4.x style */
- } else {
- return;
- }
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- if ( (f_w && !f_h) || (!f_w && f_h) ) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- for (i=0; i<4; i++) {
- vals[i] = 0;
- }
-
- data = (char *)req;
- data += sz_xConfigureWindowReq;
-
- for (i=0; i<req->length; i++) {
- unsigned int v;
- /*
- * We use unsigned int for the values. There were
- * some crashes on 64bit machines with unsigned longs.
- * Need to check that X protocol sends 32bit values.
- */
- v = *( (unsigned int *) data);
-if (db > 1) fprintf(stderr, " vals[%d] 0x%x/%d\n", i, v, v);
- vals[i] = v;
- data += sizeof(unsigned int);
- }
-
- if (index >= MAX_CW) {
- int i, j;
-
- /* FIXME, circular, etc. */
- for (i=0; i<2; i++) {
- j = MAX_CW - 2 + i;
- cw_events[i].win = cw_events[j].win;
- cw_events[i].x = cw_events[j].x;
- cw_events[i].y = cw_events[j].y;
- cw_events[i].w = cw_events[j].w;
- cw_events[i].h = cw_events[j].h;
- }
- index = 2;
- }
-
- if (! f_x && ! f_y) {
- /* netscape 4.x style CWWidth,CWHeight */
- vals[2] = vals[0];
- vals[3] = vals[1];
- vals[0] = 0;
- vals[1] = 0;
- }
-
- cw_events[index].win = req->window;
-
- if (! f_x) {
- cw_events[index].x = absent;
- } else {
- cw_events[index].x = (int) vals[0];
- }
- if (! f_y) {
- cw_events[index].y = absent;
- } else {
- cw_events[index].y = (int) vals[1];
- }
-
- if (! f_w) {
- cw_events[index].w = absent;
- } else {
- cw_events[index].w = (int) vals[2];
- }
- if (! f_h) {
- cw_events[index].h = absent;
- } else {
- cw_events[index].h = (int) vals[3];
- }
-
- x = cw_events[index].x;
- y = cw_events[index].y;
- w = cw_events[index].w;
- h = cw_events[index].h;
- win = cw_events[index].win;
-
-if (dba || db) fprintf(stderr, " record_CW ind: %d win: 0x%lx x: %d y: %d w: %d h: %d\n",
- index, win, x, y, w, h);
-
- index++;
-
- if (index < 3) {
- good = 0;
- } else if (w != absent && h != absent &&
- w*h < scrollcopyrect_min_area) {
- good = 0;
- }
-
- if (! good) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- match = 0;
- for (j=index - 1; j >= 0; j--) {
- if (cw_events[j].win == win) {
- list[match++] = j;
- }
- if (match >= 3) {
- break;
- }
- }
-
- if (match != 3) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
-/*
-
-Mozilla:
-
-Up arrow: window moves down a bit (dy > 0):
-
- X_ConfigureWindow
- length: 7, window: 0x2e000cd, mask: 0xf, v0 0, v1 -18, v2 760, v3 906, v4 327692, v5 48234701, v6 3,
- CW-mask: CWX,CWY,CWWidth,CWHeight,
- X_ConfigureWindow
- length: 5, window: 0x2e000cd, mask: 0x3, v0 0, v1 0, v2 506636, v3 48234701, v4 48234511,
- CW-mask: CWX,CWY,
- X_ConfigureWindow
- length: 7, window: 0x2e000cd, mask: 0xf, v0 0, v1 0, v2 760, v3 888, v4 65579, v5 0, v6 108009,
- CW-mask: CWX,CWY,CWWidth,CWHeight,
-
-Down arrow: window moves up a bit (dy < 0):
-
- X_ConfigureWindow
- length: 7, window: 0x2e000cd, mask: 0xf, v0 0, v1 0, v2 760, v3 906, v4 327692, v5 48234701, v6 262147,
- CW-mask: CWX,CWY,CWWidth,CWHeight,
- X_ConfigureWindow
- length: 5, window: 0x2e000cd, mask: 0x3, v0 0, v1 -18, v2 506636, v3 48234701, v4 48234511,
- CW-mask: CWX,CWY,
- X_ConfigureWindow
- length: 7, window: 0x2e000cd, mask: 0xf, v0 0, v1 0, v2 760, v3 888, v4 96555, v5 48265642, v6 48265262,
- CW-mask: CWX,CWY,CWWidth,CWHeight,
-
-
-Netscape 4.x
-
-Up arrow:
-71.76142 0.01984 X_ConfigureWindow
- length: 7, window: 0x9800488, mask: 0xf, v0 0, v1 -15, v2 785, v3 882, v4 327692, v5 159384712, v6 1769484,
- CW-mask: CWX,CWY,CWWidth,CWHeight,
-71.76153 0.00011 X_ConfigureWindow
- length: 5, window: 0x9800488, mask: 0xc, v0 785, v1 867, v2 329228, v3 159384712, v4 159383555,
- CW-mask: CWWidth,CWHeight,
- XXX,XXX
-71.76157 0.00003 X_ConfigureWindow
- length: 5, window: 0x9800488, mask: 0x3, v0 0, v1 0, v2 131132, v3 159385313, v4 328759,
- CW-mask: CWX,CWY,
- XXX,XXX
-
-Down arrow:
-72.93147 0.01990 X_ConfigureWindow
- length: 5, window: 0x9800488, mask: 0xc, v0 785, v1 882, v2 328972, v3 159384712, v4 159383555,
- CW-mask: CWWidth,CWHeight,
- XXX,XXX
-72.93156 0.00009 X_ConfigureWindow
- length: 5, window: 0x9800488, mask: 0x3, v0 0, v1 -15, v2 458764, v3 159384712, v4 159383567,
- CW-mask: CWX,CWY,
-72.93160 0.00004 X_ConfigureWindow
- length: 7, window: 0x9800488, mask: 0xf, v0 0, v1 0, v2 785, v3 867, v4 131132, v5 159385335, v6 328759,
- CW-mask: CWX,CWY,CWWidth,CWHeight,
-
-
-sadly, probably need to handle some more...
-
- */
- x0 = cw_events[list[2]].x;
- y0 = cw_events[list[2]].y;
- w0 = cw_events[list[2]].w;
- h0 = cw_events[list[2]].h;
-
- x1 = cw_events[list[1]].x;
- y1 = cw_events[list[1]].y;
- w1 = cw_events[list[1]].w;
- h1 = cw_events[list[1]].h;
-
- x2 = cw_events[list[0]].x;
- y2 = cw_events[list[0]].y;
- w2 = cw_events[list[0]].w;
- h2 = cw_events[list[0]].h;
-
- /* see NS4 XXX's above: */
- if (w2 == absent || h2 == absent) {
- /* up arrow */
- if (w2 == absent) {
- w2 = w1;
- }
- if (h2 == absent) {
- h2 = h1;
- }
- }
- if (x1 == absent || y1 == absent) {
- /* up arrow */
- if (x1 == absent) {
- x1 = x2;
- }
- if (y1 == absent) {
- y1 = y2;
- }
- }
- if (x0 == absent || y0 == absent) {
- /* down arrow */
- if (x0 == absent) {
- /* hmmm... what to do */
- x0 = x2;
- }
- if (y0 == absent) {
- y0 = y2;
- }
- }
-
-if (dba) fprintf(stderr, "%d/%d/%d/%d %d/%d/%d/%d %d/%d/%d/%d\n", x0, y0, w0, h0, x1, y1, w1, h1, x2, y2, w2, h2);
-
- dy = y1 - y0;
- dx = x1 - x0;
-
- src_x = x2;
- src_y = y2;
- w = w2;
- h = h2;
-
- /* check w and h before we modify them */
- if (w <= 0 || h <= 0) {
- good = 0;
- } else if (w == absent || h == absent) {
- good = 0;
- }
- if (! good) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- if (dy > 0) {
- h -= dy;
- } else {
- h += dy;
- src_y -= dy;
- }
- if (dx > 0) {
- w -= dx;
- } else {
- w += dx;
- src_x -= dx;
- }
-
- dst_x = src_x + dx;
- dst_y = src_y + dy;
-
- if (x0 == absent || x1 == absent || x2 == absent) {
- good = 0;
- } else if (y0 == absent || y1 == absent || y2 == absent) {
- good = 0;
- } else if (dx != 0 && dy != 0) {
- good = 0;
- } else if (w0 - w2 != nabs(dx)) {
- good = 0;
- } else if (h0 - h2 != nabs(dy)) {
- good = 0;
- } else if (scr_ev_cnt >= SCR_EV_MAX) {
- good = 0;
- }
-
- if (! good) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- /*
- * geometry OK.
- * after all of the above succeeds, now contact X server.
- */
- if (lookup_attr_cache(win, &cache_index, &next_index)) {
- i = cache_index;
- attr.x = scr_attr_cache[i].x;
- attr.y = scr_attr_cache[i].y;
- attr.width = scr_attr_cache[i].width;
- attr.height = scr_attr_cache[i].height;
- attr.map_state = scr_attr_cache[i].map_state;
- rx = scr_attr_cache[i].rx;
- ry = scr_attr_cache[i].ry;
- valid = scr_attr_cache[i].valid;
-
-if (0) fprintf(stderr, "lookup_attr_cache hit: %2d %2d 0x%lx %d\n",
- cache_index, next_index, win, valid);
-
- } else {
- valid = valid_window(win, &attr, 1);
-
-if (0) fprintf(stderr, "lookup_attr_cache MISS: %2d %2d 0x%lx %d\n",
- cache_index, next_index, win, valid);
-
- if (valid) {
- if (!xtranslate(win, rootwin, 0, 0, &rx, &ry, &c, 1)) {
- valid = 0;
- }
- }
- if (next_index >= 0) {
- i = next_index;
- scr_attr_cache[i].win = win;
- scr_attr_cache[i].fetched = 1;
- scr_attr_cache[i].valid = valid;
- scr_attr_cache[i].time = dnow();
- if (valid) {
- scr_attr_cache[i].x = attr.x;
- scr_attr_cache[i].y = attr.y;
- scr_attr_cache[i].width = attr.width;
- scr_attr_cache[i].height = attr.height;
- scr_attr_cache[i].depth = attr.depth;
- scr_attr_cache[i].class = attr.class;
- scr_attr_cache[i].backing_store =
- attr.backing_store;
- scr_attr_cache[i].map_state = attr.map_state;
-
- scr_attr_cache[i].rx = rx;
- scr_attr_cache[i].ry = ry;
- }
- }
- }
-
- if (! valid) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- if (attr.map_state != IsViewable) {
- return;
- }
-if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
-
- if (0 || dba || db) {
- double st, dt;
- st = (double) rec_data->server_time/1000.0;
- dt = (dnow() - servertime_diff) - st;
- fprintf(stderr, "record_CW-%d *FOUND_SCROLL: win: 0x%lx dx: %d dy: %d "
- "x: %d y: %d w: %d h: %d st: %.4f dt: %.4f %.4f\n", k++, win,
- dx, dy, src_x, src_y, w, h, st, dt, dnowx());
- }
-
- i = scr_ev_cnt;
-
- scr_ev[i].win = win;
- scr_ev[i].frame = None;
- scr_ev[i].dx = dx;
- scr_ev[i].dy = dy;
- scr_ev[i].x = rx + dst_x;
- scr_ev[i].y = ry + dst_y;
- scr_ev[i].w = w;
- scr_ev[i].h = h;
- scr_ev[i].t = ((double) rec_data->server_time)/1000.0;
- scr_ev[i].win_x = rx;
- scr_ev[i].win_y = ry;
- scr_ev[i].win_w = attr.width;
- scr_ev[i].win_h = attr.height;
- scr_ev[i].new_x = 0;
- scr_ev[i].new_y = 0;
- scr_ev[i].new_w = 0;
- scr_ev[i].new_h = 0;
-
- if (dx == 0) {
- if (dy > 0) {
- scr_ev[i].new_x = rx + src_x;
- scr_ev[i].new_y = ry + src_y;
- scr_ev[i].new_w = w;
- scr_ev[i].new_h = dy;
- } else {
- scr_ev[i].new_x = rx + src_x;
- scr_ev[i].new_y = ry + dst_y + h;
- scr_ev[i].new_w = w;
- scr_ev[i].new_h = -dy;
- }
- } else if (dy == 0) {
- if (dx > 0) {
- scr_ev[i].new_x = rx + src_x;
- scr_ev[i].new_y = rx + src_y;
- scr_ev[i].new_w = dx;
- scr_ev[i].new_h = h;
- } else {
- scr_ev[i].new_x = rx + dst_x + w;
- scr_ev[i].new_y = ry + src_y;
- scr_ev[i].new_w = -dx;
- scr_ev[i].new_h = h;
- }
- }
-
- /* indicate we have a new one */
- scr_ev_cnt++;
-
- index = 0;
-}
-
-static void record_switch(XPointer ptr, XRecordInterceptData *rec_data) {
- static int first = 1;
- xReq *req;
-
- if (first) {
- int i;
- for (i=0; i<SCR_ATTR_CACHE; i++) {
- scr_attr_cache[i].win = None;
- scr_attr_cache[i].fetched = 0;
- scr_attr_cache[i].valid = 0;
- scr_attr_cache[i].time = 0.0;
- }
- first = 0;
- }
-
- /* should handle control msgs, start/stop/etc */
- if (rec_data->category == XRecordStartOfData) {
- record_CW(ptr, rec_data);
- } else if (rec_data->category == XRecordEndOfData) {
- ;
- } else if (rec_data->category == XRecordClientStarted) {
- ;
- } else if (rec_data->category == XRecordClientDied) {
- ;
- } else if (rec_data->category == XRecordFromServer) {
- ;
- }
-
- if (rec_data->category != XRecordFromClient) {
- XRecordFreeData(rec_data);
- return;
- }
-
- req = (xReq *) rec_data->data;
-
- if (req->reqType == X_CopyArea) {
- record_CA(ptr, rec_data);
- } else if (req->reqType == X_ConfigureWindow) {
- record_CW(ptr, rec_data);
- } else {
- ;
- }
- XRecordFreeData(rec_data);
-}
-
-static void record_grab(XPointer ptr, XRecordInterceptData *rec_data) {
- xReq *req;
- int db = 0;
-
- if (debug_grabs) db = 1;
-
- /* should handle control msgs, start/stop/etc */
- if (rec_data->category == XRecordStartOfData) {
- ;
- } else if (rec_data->category == XRecordEndOfData) {
- ;
- } else if (rec_data->category == XRecordClientStarted) {
- ;
- } else if (rec_data->category == XRecordClientDied) {
- ;
- } else if (rec_data->category == XRecordFromServer) {
- ;
- }
-
- if (rec_data->category != XRecordFromClient) {
- XRecordFreeData(rec_data);
- return;
- }
-
- req = (xReq *) rec_data->data;
-
- if (req->reqType == X_GrabServer) {
- double now = dnowx();
- xserver_grabbed++;
- if (db) rfbLog("X server Grabbed: %d %.5f\n", xserver_grabbed, now);
- if (xserver_grabbed > 1) {
- /*
- * some apps do multiple grabs... very unlikely
- * two apps will be doing it at same time.
- */
- xserver_grabbed = 1;
- }
- } else if (req->reqType == X_UngrabServer) {
- double now = dnowx();
- xserver_grabbed--;
- if (xserver_grabbed < 0) {
- xserver_grabbed = 0;
- }
- if (db) rfbLog("X server Un-Grabbed: %d %.5f\n", xserver_grabbed, now);
- } else {
- ;
- }
- XRecordFreeData(rec_data);
-
- /* unused vars warning: */
- if (ptr) {}
-}
-#endif
-
-static void check_xrecord_grabserver(void) {
-#if LIBVNCSERVER_HAVE_RECORD
- int last_val, cnt = 0, i, max = 10;
- double d;
- if (!gdpy_ctrl || !gdpy_data) {
- return;
- }
- if (unixpw_in_progress) return;
-
- dtime0(&d);
- XFlush_wr(gdpy_ctrl);
- for (i=0; i<max; i++) {
- last_val = xserver_grabbed;
- XRecordProcessReplies(gdpy_data);
- if (xserver_grabbed != last_val) {
- cnt++;
- } else if (i > 2) {
- break;
- }
- }
- if (cnt) {
- XFlush_wr(gdpy_ctrl);
- }
- if (debug_grabs && cnt > 0) {
- d = dtime(&d);
-fprintf(stderr, "check_xrecord_grabserver: cnt=%d i=%d %.4f\n", cnt, i, d);
- }
-#endif
-}
-
-#if LIBVNCSERVER_HAVE_RECORD
-static void shutdown_record_context(XRecordContext rc, int bequiet, int reopen) {
- int ret1, ret2;
- int verb = (!bequiet && !quiet);
-
- RAWFB_RET_VOID
- if (0 || debug_scroll) {
- rfbLog("shutdown_record_context(0x%lx, %d, %d)\n", rc,
- bequiet, reopen);
- verb = 1;
- }
-
- ret1 = XRecordDisableContext(rdpy_ctrl, rc);
- if (!ret1 && verb) {
- rfbLog("XRecordDisableContext(0x%lx) failed.\n", rc);
- }
- ret2 = XRecordFreeContext(rdpy_ctrl, rc);
- if (!ret2 && verb) {
- rfbLog("XRecordFreeContext(0x%lx) failed.\n", rc);
- }
- XFlush_wr(rdpy_ctrl);
-
- if (reopen == 2 && ret1 && ret2) {
- reopen = 0; /* 2 means reopen only on failure */
- }
- if (reopen && gdpy_ctrl) {
- check_xrecord_grabserver();
- if (xserver_grabbed) {
- rfbLog("shutdown_record_context: skip reopen,"
- " server grabbed\n");
- reopen = 0;
- }
- }
- if (reopen) {
- char *dpystr = DisplayString(dpy);
-
- if (debug_scroll) {
- rfbLog("closing RECORD data connection.\n");
- }
- XCloseDisplay_wr(rdpy_data);
- rdpy_data = NULL;
-
- if (debug_scroll) {
- rfbLog("closing RECORD control connection.\n");
- }
- XCloseDisplay_wr(rdpy_ctrl);
- rdpy_ctrl = NULL;
-
- rdpy_ctrl = XOpenDisplay_wr(dpystr);
-
- if (! rdpy_ctrl) {
- rfbLog("Failed to reopen RECORD control connection:"
- "%s\n", dpystr);
- rfbLog(" disabling RECORD scroll detection.\n");
- use_xrecord = 0;
- return;
- }
- XSync(dpy, False);
-
- disable_grabserver(rdpy_ctrl, 0);
- XSync(rdpy_ctrl, True);
-
- rdpy_data = XOpenDisplay_wr(dpystr);
-
- if (! rdpy_data) {
- rfbLog("Failed to reopen RECORD data connection:"
- "%s\n", dpystr);
- rfbLog(" disabling RECORD scroll detection.\n");
- XCloseDisplay_wr(rdpy_ctrl);
- rdpy_ctrl = NULL;
- use_xrecord = 0;
- return;
- }
- disable_grabserver(rdpy_data, 0);
-
- if (debug_scroll || (! bequiet && reopen == 2)) {
- rfbLog("reopened RECORD data and control display"
- " connections: %s\n", dpystr);
- }
- }
-}
-#endif
-
-void check_xrecord_reset(int force) {
- static double last_reset = 0.0;
- int reset_time = 60, require_idle = 10;
- int reset_time2 = 600, require_idle2 = 40;
- double now = 0.0;
- XErrorHandler old_handler = NULL;
-
- if (gdpy_ctrl) {
- X_LOCK;
- check_xrecord_grabserver();
- X_UNLOCK;
- } else {
- /* more dicey if not watching grabserver */
- reset_time = reset_time2;
- require_idle = require_idle2;
- }
-
- if (!use_xrecord) {
- return;
- }
- if (xrecording) {
- return;
- }
- if (button_mask) {
- return;
- }
- if (xserver_grabbed) {
- return;
- }
-
- if (unixpw_in_progress) return;
-
-#if LIBVNCSERVER_HAVE_RECORD
- if (! rc_scroll) {
- return;
- }
- now = dnow();
- if (last_reset == 0.0) {
- last_reset = now;
- return;
- }
- /*
- * try to wait for a break in input to reopen the displays
- * this is only to avoid XGrabServer deadlock on the repopens.
- */
- if (force) {
- ;
- } else if (now < last_reset + reset_time) {
- return;
- } else if (now < last_pointer_click_time + require_idle) {
- return;
- } else if (now < last_keyboard_time + require_idle) {
- return;
- }
- X_LOCK;
- trapped_record_xerror = 0;
- old_handler = XSetErrorHandler(trap_record_xerror);
-
- /* unlikely, but check again since we will definitely be doing it. */
- if (gdpy_ctrl) {
- check_xrecord_grabserver();
- if (xserver_grabbed) {
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- return;
- }
- }
-
- shutdown_record_context(rc_scroll, 0, 1);
- rc_scroll = 0;
-
- XSetErrorHandler(old_handler);
- X_UNLOCK;
-
- last_reset = now;
-#else
- if (!old_handler || now == 0.0 || !last_reset || !force) {}
-#endif
-}
-
-#define RECORD_ERROR_MSG(tag) \
- if (! quiet) { \
- static int cnt = 0; \
- static time_t last = 0; \
- int show = 0; \
- cnt++; \
- if (debug_scroll || cnt < 20) { \
- show = 1; \
- } else if (cnt == 20) { \
- last = time(NULL); \
- rfbLog("disabling RECORD XError messages for 600s\n"); \
- show = 1; \
- } else if (time(NULL) > last + 600) { \
- cnt = 0; \
- show = 1; \
- } \
- if (show) { \
- rfbLog("trapped RECORD XError: %s %s %d/%d/%d (0x%lx)\n", \
- tag, xerror_string(trapped_record_xerror_event), \
- (int) trapped_record_xerror_event->error_code, \
- (int) trapped_record_xerror_event->request_code, \
- (int) trapped_record_xerror_event->minor_code, \
- (int) trapped_record_xerror_event->resourceid); \
- } \
- }
-
-void xrecord_watch(int start, int setby) {
-#if LIBVNCSERVER_HAVE_RECORD
- Window focus, wm, c, clast;
- static double create_time = 0.0;
- int rc;
- int do_shutdown = 0;
- int reopen_dpys = 1;
- XErrorHandler old_handler = NULL;
- static Window last_win = None, last_result = None;
-#endif
- int db = debug_scroll;
- double now;
- static double last_error = 0.0;
-
-if (0) db = 1;
-
- if (nofb) {
- xrecording = 0;
- return;
- }
- if (use_threads) {
- /* XXX not working. Still? Painting errors. */
- static int first = 1;
- if (first) {
- if (use_xrecord && !getenv("XRECORD_THREADS")) {
- rfbLog("xrecord_watch: disabling scroll detection in -threads mode.\n");
- rfbLog("xrecord_watch: Set -env XRECORD_THREADS=1 to enable it.\n");
- use_xrecord = 0;
- xrecording = 0;
- }
- first = 0;
- }
- if (!use_xrecord && !xrecording) {
- return;
- }
- }
-
- dtime0(&now);
- if (now < last_error + 0.5) {
- return;
- }
-
- if (gdpy_ctrl) {
- X_LOCK;
- check_xrecord_grabserver();
- X_UNLOCK;
- if (xserver_grabbed) {
-if (db || debug_grabs) fprintf(stderr, "xrecord_watch: %d/%d out xserver_grabbed\n", start, setby);
- return;
- }
- }
-
-#if LIBVNCSERVER_HAVE_RECORD
- if (! start) {
- int shut_reopen = 2, shut_time = 25;
-if (db || debug_grabs) fprintf(stderr, "XRECORD OFF: %d/%d %.4f\n", xrecording, setby, now - x11vnc_start);
- xrecording = 0;
- if (! rc_scroll) {
- xrecord_focus_window = None;
- xrecord_wm_window = None;
- xrecord_ptr_window = None;
- xrecord_keysym = NoSymbol;
- rcs_scroll = 0;
- return;
- }
-
- if (! do_shutdown && now > create_time + shut_time) {
- /* XXX unstable if we keep a RECORD going forever */
- do_shutdown = 1;
- }
-
- SCR_LOCK;
-
- if (do_shutdown) {
-if (db > 1) fprintf(stderr, "=== shutdown-scroll 0x%lx\n", rc_scroll);
- X_LOCK;
- trapped_record_xerror = 0;
- old_handler = XSetErrorHandler(trap_record_xerror);
-
- shutdown_record_context(rc_scroll, 0, shut_reopen);
- rc_scroll = 0;
-
- /*
- * n.b. there is a grabserver issue wrt
- * XRecordCreateContext() even though rdpy_ctrl
- * is set imprevious to grabs. Perhaps a bug
- * in the X server or library...
- *
- * If there are further problems, a thought
- * to recreate rc_scroll right after the
- * reopen.
- */
-
- if (! use_xrecord) {
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- SCR_UNLOCK;
- return;
- }
-
- XRecordProcessReplies(rdpy_data);
-
- if (trapped_record_xerror) {
- RECORD_ERROR_MSG("shutdown");
- last_error = now;
- }
-
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- SCR_UNLOCK;
-
- } else {
- if (rcs_scroll) {
-if (db > 1) fprintf(stderr, "=== disab-scroll 0x%lx 0x%lx\n", rc_scroll, rcs_scroll);
- X_LOCK;
- trapped_record_xerror = 0;
- old_handler =
- XSetErrorHandler(trap_record_xerror);
-
- rcs_scroll = XRecordCurrentClients;
- XRecordUnregisterClients(rdpy_ctrl, rc_scroll,
- &rcs_scroll, 1);
- XRecordDisableContext(rdpy_ctrl, rc_scroll);
- XFlush_wr(rdpy_ctrl);
- XRecordProcessReplies(rdpy_data);
-
- if (trapped_record_xerror) {
- RECORD_ERROR_MSG("disable");
-
- shutdown_record_context(rc_scroll,
- 0, reopen_dpys);
- rc_scroll = 0;
-
- last_error = now;
-
- if (! use_xrecord) {
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- SCR_UNLOCK;
- return;
- }
- }
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- }
- }
-
- SCR_UNLOCK;
- /*
- * XXX if we do a XFlush_wr(rdpy_ctrl) here we get:
- *
-
- X Error of failed request: XRecordBadContext
- Major opcode of failed request: 145 (RECORD)
- Minor opcode of failed request: 5 (XRecordEnableContext)
- Context in failed request: 0x2200013
- Serial number of failed request: 29
- Current serial number in output stream: 29
-
- *
- * need to figure out what is going on... since it may lead
- * infrequent failures.
- */
- xrecord_focus_window = None;
- xrecord_wm_window = None;
- xrecord_ptr_window = None;
- xrecord_keysym = NoSymbol;
- rcs_scroll = 0;
- return;
- }
-if (db || debug_grabs) fprintf(stderr, "XRECORD ON: %d/%d %.4f\n", xrecording, setby, now - x11vnc_start);
-
- if (xrecording) {
- return;
- }
-
- if (do_shutdown && rc_scroll) {
- static int didmsg = 0;
- /* should not happen... */
- if (0 || !didmsg) {
- rfbLog("warning: do_shutdown && rc_scroll\n");
- didmsg = 1;
- }
- xrecord_watch(0, SCR_NONE);
- }
-
- xrecording = 0;
- xrecord_focus_window = None;
- xrecord_wm_window = None;
- xrecord_ptr_window = None;
- xrecord_keysym = NoSymbol;
- xrecord_set_by_keys = 0;
- xrecord_set_by_mouse = 0;
-
- /* get the window with focus and mouse pointer: */
- clast = None;
- focus = None;
- wm = None;
-
- X_LOCK;
- SCR_LOCK;
-#if 0
- /*
- * xrecord_focus_window / focus not currently used... save a
- * round trip to the X server for now.
- * N.B. our heuristic is inaccurate: if he is scrolling and
- * drifts off of the scrollbar onto another application we
- * will catch that application, not the starting ones.
- * check_xrecord_{keys,mouse} mitigates this somewhat by
- * delaying calls to xrecord_watch as much as possible.
- */
- XGetInputFocus(dpy, &focus, &i);
-#endif
-
- wm = query_pointer(rootwin);
- if (wm) {
- c = wm;
- } else {
- c = rootwin;
- }
-
- /* descend a bit to avoid wm frames: */
- if (c != rootwin && c == last_win) {
- /* use cached results to avoid roundtrips: */
- clast = last_result;
- } else if (scroll_good_all == NULL && scroll_skip_all == NULL) {
- /* more efficient if name info not needed. */
- xrecord_name_info[0] = '\0';
- clast = descend_pointer(6, c, NULL, 0);
- } else {
- char *nm;
- int matched_good = 0, matched_skip = 0;
-
- clast = descend_pointer(6, c, xrecord_name_info, NAMEINFO);
-if (db) fprintf(stderr, "name_info: %s\n", xrecord_name_info);
-
- nm = xrecord_name_info;
-
- if (scroll_good_all) {
- matched_good += match_str_list(nm, scroll_good_all);
- }
- if (setby == SCR_KEY && scroll_good_key) {
- matched_good += match_str_list(nm, scroll_good_key);
- }
- if (setby == SCR_MOUSE && scroll_good_mouse) {
- matched_good += match_str_list(nm, scroll_good_mouse);
- }
- if (scroll_skip_all) {
- matched_skip += match_str_list(nm, scroll_skip_all);
- }
- if (setby == SCR_KEY && scroll_skip_key) {
- matched_skip += match_str_list(nm, scroll_skip_key);
- }
- if (setby == SCR_MOUSE && scroll_skip_mouse) {
- matched_skip += match_str_list(nm, scroll_skip_mouse);
- }
-
- if (!matched_good && matched_skip) {
- clast = None;
- }
- }
- if (c != rootwin) {
- /* cache results for possible use next call */
- last_win = c;
- last_result = clast;
- }
-
- if (!clast || clast == rootwin) {
-if (db) fprintf(stderr, "--- xrecord_watch: SKIP.\n");
- X_UNLOCK;
- SCR_UNLOCK;
- return;
- }
-
- /* set protocol request ranges: */
- rr_scroll[0] = rr_CA;
- rr_scroll[1] = rr_CW;
-
- /*
- * start trapping... there still are some occasional failures
- * not yet understood, likely some race condition WRT the
- * context being setup.
- */
- trapped_record_xerror = 0;
- old_handler = XSetErrorHandler(trap_record_xerror);
-
- if (! rc_scroll) {
- /* do_shutdown case or first time in */
-
- if (gdpy_ctrl) {
- /*
- * Even though rdpy_ctrl is impervious to grabs
- * at this point, we still get deadlock, why?
- * It blocks in the library find_display() call.
- */
- check_xrecord_grabserver();
- if (xserver_grabbed) {
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- SCR_UNLOCK;
- return;
- }
- }
- rcs_scroll = (XRecordClientSpec) clast;
- rc_scroll = XRecordCreateContext(rdpy_ctrl, 0, &rcs_scroll, 1,
- rr_scroll, 2);
-
- if (! do_shutdown) {
- XSync(rdpy_ctrl, False);
- }
-if (db) fprintf(stderr, "NEW rc: 0x%lx\n", rc_scroll);
- if (rc_scroll) {
- dtime0(&create_time);
- } else {
- rcs_scroll = 0;
- }
-
- } else if (! do_shutdown) {
- if (rcs_scroll) {
- /*
- * should have been unregistered in xrecord_watch(0)...
- */
- rcs_scroll = XRecordCurrentClients;
- XRecordUnregisterClients(rdpy_ctrl, rc_scroll,
- &rcs_scroll, 1);
-
-if (db > 1) fprintf(stderr, "=2= unreg-scroll 0x%lx 0x%lx\n", rc_scroll, rcs_scroll);
-
- }
-
- rcs_scroll = (XRecordClientSpec) clast;
-
-if (db > 1) fprintf(stderr, "=-= reg-scroll 0x%lx 0x%lx\n", rc_scroll, rcs_scroll);
-
- if (!XRecordRegisterClients(rdpy_ctrl, rc_scroll, 0,
- &rcs_scroll, 1, rr_scroll, 2)) {
- if (1 || now > last_error + 60) {
- rfbLog("failed to register client 0x%lx with"
- " X RECORD context rc_scroll.\n", clast);
- }
- last_error = now;
- rcs_scroll = 0;
- /* continue on for now... */
- }
- }
-
- XFlush_wr(rdpy_ctrl);
-
-if (db) fprintf(stderr, "rc_scroll: 0x%lx\n", rc_scroll);
- if (trapped_record_xerror) {
- RECORD_ERROR_MSG("register");
- }
-
- if (! rc_scroll) {
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- SCR_UNLOCK;
- use_xrecord = 0;
- rfbLog("failed to create X RECORD context rc_scroll.\n");
- rfbLog(" switching to -noscrollcopyrect mode.\n");
- return;
- } else if (! rcs_scroll || trapped_record_xerror) {
- /* try again later */
- shutdown_record_context(rc_scroll, 0, reopen_dpys);
- rc_scroll = 0;
- last_error = now;
-
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- SCR_UNLOCK;
- return;
- }
-
- xrecord_focus_window = focus;
-#if 0
- /* xrecord_focus_window currently unused. */
- if (! xrecord_focus_window) {
- xrecord_focus_window = clast;
- }
-#endif
- xrecord_wm_window = wm;
- if (! xrecord_wm_window) {
- xrecord_wm_window = clast;
- }
-
- xrecord_ptr_window = clast;
-
- xrecording = 1;
- xrecord_seq++;
- dtime0(&xrecord_start);
-
- rc = XRecordEnableContextAsync(rdpy_data, rc_scroll, record_switch,
- (XPointer) xrecord_seq);
-
- if (!rc || trapped_record_xerror) {
- if (1 || now > last_error + 60) {
- rfbLog("failed to enable RECORD context "
- "rc_scroll: 0x%lx rc: %d\n", rc_scroll, rc);
- if (trapped_record_xerror) {
- RECORD_ERROR_MSG("enable-failed");
- }
- }
- shutdown_record_context(rc_scroll, 0, reopen_dpys);
- rc_scroll = 0;
- last_error = now;
- xrecording = 0;
- /* continue on for now... */
- }
- XSetErrorHandler(old_handler);
-
- /* XXX this may cause more problems than it solves... */
- if (use_xrecord) {
- XFlush_wr(rdpy_data);
- }
-
- X_UNLOCK;
- SCR_UNLOCK;
-#endif
-}
-
-
diff --git a/x11vnc/xrecord.h b/x11vnc/xrecord.h
deleted file mode 100644
index 2c1e2d7..0000000
--- a/x11vnc/xrecord.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_XRECORD_H
-#define _X11VNC_XRECORD_H
-
-/* -- xrecord.h -- */
-#include "scrollevent_t.h"
-#include "winattr_t.h"
-
-extern scroll_event_t scr_ev[];
-extern int scr_ev_cnt;
-extern int xrecording;
-extern int xrecord_set_by_keys;
-extern int xrecord_set_by_mouse;
-extern Window xrecord_focus_window;
-extern Window xrecord_wm_window;
-extern Window xrecord_ptr_window;
-extern KeySym xrecord_keysym;
-extern char xrecord_name_info[];
-
-extern winattr_t scr_attr_cache[];
-
-extern Display *rdpy_data;
-extern Display *rdpy_ctrl;
-
-extern Display *gdpy_ctrl;
-extern int xserver_grabbed;
-
-extern void initialize_xrecord(void);
-extern void zerodisp_xrecord(void);
-extern void shutdown_xrecord(void);
-extern int xrecord_skip_keysym(rfbKeySym keysym);
-extern int xrecord_skip_button(int newb, int old);
-extern int xrecord_scroll_keysym(rfbKeySym keysym);
-extern void check_xrecord_reset(int force);
-extern void xrecord_watch(int start, int setby);
-
-#endif /* _X11VNC_XRECORD_H */
diff --git a/x11vnc/xwrappers.c b/x11vnc/xwrappers.c
deleted file mode 100644
index e7158cf..0000000
--- a/x11vnc/xwrappers.c
+++ /dev/null
@@ -1,1522 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- xwrappers.c -- */
-
-#include "x11vnc.h"
-#include "xrecord.h"
-#include "keyboard.h"
-#include "xevents.h"
-#include "connections.h"
-#include "cleanup.h"
-#include "macosx.h"
-
-int xshm_present = 0;
-int xshm_opcode = 0;
-int xtest_present = 0;
-int xtrap_present = 0;
-int xrecord_present = 0;
-int xkb_present = 0;
-int xinerama_present = 0;
-
-int keycode_state[256];
-int rootshift = 0;
-int clipshift = 0;
-
-
-int guess_bits_per_color(int bits_per_pixel);
-
-int XFlush_wr(Display *disp);
-
-Status XShmGetImage_wr(Display *disp, Drawable d, XImage *image, int x, int y,
- unsigned long mask);
-XImage *XShmCreateImage_wr(Display* disp, Visual* vis, unsigned int depth,
- int format, char* data, XShmSegmentInfo* shminfo, unsigned int width,
- unsigned int height);
-Status XShmAttach_wr(Display *disp, XShmSegmentInfo *shminfo);
-Status XShmDetach_wr(Display *disp, XShmSegmentInfo *shminfo);
-Bool XShmQueryExtension_wr(Display *disp);
-int XShmGetEventBase_wr(Display *disp);
-
-XImage *xreadscreen(Display *disp, Drawable d, int x, int y,
- unsigned int width, unsigned int height, Bool show_cursor);
-XImage *XGetSubImage_wr(Display *disp, Drawable d, int x, int y,
- unsigned int width, unsigned int height, unsigned long plane_mask,
- int format, XImage *dest_image, int dest_x, int dest_y);
-XImage *XGetImage_wr(Display *disp, Drawable d, int x, int y,
- unsigned int width, unsigned int height, unsigned long plane_mask,
- int format);
-XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth,
- int format, int offset, char *data, unsigned int width,
- unsigned int height, int bitmap_pad, int bytes_per_line);
-void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h);
-void init_track_keycode_state(void);
-
-void XTRAP_FakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
- unsigned long delay);
-void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
- unsigned long delay);
-void XTRAP_FakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
- unsigned long delay);
-void XTestFakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
- unsigned long delay);
-void XTRAP_FakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
- unsigned long delay);
-void XTestFakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
- unsigned long delay);
-
-Bool XTestCompareCurrentCursorWithWindow_wr(Display* dpy, Window w);
-Bool XTestCompareCursorWithWindow_wr(Display* dpy, Window w, Cursor cursor);
-Bool XTestQueryExtension_wr(Display *dpy, int *ev, int *er, int *maj,
- int *min);
-void XTestDiscard_wr(Display *dpy);
-Bool XETrapQueryExtension_wr(Display *dpy, int *ev, int *er, int *op);
-int XTestGrabControl_wr(Display *dpy, Bool impervious);
-int XTRAP_GrabControl_wr(Display *dpy, Bool impervious);
-void disable_grabserver(Display *in_dpy, int change);
-
-Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min);
-
-int xauth_raw(int on);
-Display *XOpenDisplay_wr(char *display_name);
-int XCloseDisplay_wr(Display *display);
-
-Bool XQueryPointer_wr(Display *display, Window w, Window *root_return,
- Window *child_return, int *root_x_return, int *root_y_return,
- int *win_x_return, int *win_y_return, unsigned int *mask_return);
-
-Status XQueryTree_wr(Display *display, Window w, Window *root_return,
- Window *parent_return, Window **children_return,
- unsigned int *nchildren_return);
-
-int XFree_wr(void *data);
-int XSelectInput_wr(Display *display, Window w, long event_mask);
-
-void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
-static void upup_downdown_warning(KeyCode key, Bool down);
-
-/*
- * used in rfbGetScreen and rfbNewFramebuffer: and estimate to the number
- * of bits per color, of course for some visuals, e.g. 565, the number
- * is not the same for each color. This is just a sane default.
- */
-int guess_bits_per_color(int bits_per_pixel) {
- int bits_per_color;
-
- /* first guess, spread them "evenly" over R, G, and B */
- bits_per_color = bits_per_pixel/3;
- if (bits_per_color < 1) {
- bits_per_color = 1; /* 1bpp, 2bpp... */
- }
-
- /* choose safe values for usual cases: */
- if (bits_per_pixel == 8) {
- bits_per_color = 2;
- } else if (bits_per_pixel == 15 || bits_per_pixel == 16) {
- bits_per_color = 5;
- } else if (bits_per_pixel == 24 || bits_per_pixel == 32) {
- bits_per_color = 8;
- }
- return bits_per_color;
-}
-
-int XFlush_wr(Display *disp) {
-#if NO_X11
- if (!disp) {}
- return 1;
-#else
- if (disp) {
- return XFlush(disp);
- } else {
- return 1;
- }
-#endif /* NO_X11 */
-}
-
-/*
- * Kludge to interpose image gets and limit to a subset rectangle of
- * the rootwin. This is the -sid option trying to work around invisible
- * saveUnders menu, etc, windows. Also -clip option.
- */
-
-#define ADJUST_ROOTSHIFT \
- if (rootshift && subwin) { \
- d = rootwin; \
- x += off_x; \
- y += off_y; \
- } \
- if (clipshift) { \
- x += coff_x; \
- y += coff_y; \
- }
-
-/*
- * Wrappers for Image related X calls
- */
-Status XShmGetImage_wr(Display *disp, Drawable d, XImage *image, int x, int y,
- unsigned long mask) {
-
- ADJUST_ROOTSHIFT
-
- /* Note: the Solaris overlay stuff is all non-shm (using_shm = 0) */
-
-#if LIBVNCSERVER_HAVE_XSHM
- return XShmGetImage(disp, d, image, x, y, mask);
-#else
- if (!disp || !d || !image || !x || !y || !mask) {}
- return (Status) 0;
-#endif
-}
-
-XImage *XShmCreateImage_wr(Display* disp, Visual* vis, unsigned int depth,
- int format, char* data, XShmSegmentInfo* shminfo, unsigned int width,
- unsigned int height) {
-
-#if LIBVNCSERVER_HAVE_XSHM
- return XShmCreateImage(disp, vis, depth, format, data, shminfo,
- width, height);
-#else
- if (!disp || !vis || !depth || !format || !data || !shminfo || !width || !height) {}
- return (XImage *) 0;
-#endif
-}
-
-Status XShmAttach_wr(Display *disp, XShmSegmentInfo *shminfo) {
-#if LIBVNCSERVER_HAVE_XSHM
- return XShmAttach(disp, shminfo);
-#else
- if (!disp || !shminfo) {}
- return (Status) 0;
-#endif
-}
-
-Status XShmDetach_wr(Display *disp, XShmSegmentInfo *shminfo) {
-#if LIBVNCSERVER_HAVE_XSHM
- if (getenv("X11VNC_SHM_DEBUG")) fprintf(stderr, "XShmDetach_wr: %p disp: %p\n", (void *)shminfo, (void *)disp);
- return XShmDetach(disp, shminfo);
-#else
- if (!disp || !shminfo) {}
- return (Status) 0;
-#endif
-}
-
-Bool XShmQueryExtension_wr(Display *disp) {
-#if LIBVNCSERVER_HAVE_XSHM
- return XShmQueryExtension(disp);
-#else
- if (!disp) {}
- return False;
-#endif
-}
-
-int XShmGetEventBase_wr(Display *disp) {
-#if LIBVNCSERVER_HAVE_XSHM
- return XShmGetEventBase(disp);
-#else
- if (!disp) {}
- return 0;
-#endif
-}
-
-/* wrapper for overlay screen reading: */
-
-XImage *xreadscreen(Display *disp, Drawable d, int x, int y,
- unsigned int width, unsigned int height, Bool show_cursor) {
-#if NO_X11
- if (!disp || !d || !x || !y || !width || !height || !show_cursor) {}
- return NULL;
-#else
-
-#ifdef SOLARIS_OVERLAY
- return XReadScreen(disp, d, x, y, width, height,
- show_cursor);
-#else
-# ifdef IRIX_OVERLAY
- { unsigned long hints = 0, hints_ret;
- if (show_cursor) hints |= XRD_READ_POINTER;
- return XReadDisplay(disp, d, x, y, width, height,
- hints, &hints_ret);
- }
-# else
- /* unused vars warning: */
- if (disp || d || x || y || width || height || show_cursor) {}
-
- return NULL;
-# endif
-#endif
-
-#endif /* NO_X11 */
-}
-
-XImage *XGetSubImage_wr(Display *disp, Drawable d, int x, int y,
- unsigned int width, unsigned int height, unsigned long plane_mask,
- int format, XImage *dest_image, int dest_x, int dest_y) {
-#if NO_X11
- nox11_exit(1);
- if (!disp || !d || !x || !y || !width || !height || !plane_mask || !format || !dest_image || !dest_x || !dest_y) {}
- return NULL;
-#else
- ADJUST_ROOTSHIFT
-
- if (overlay && dest_x == 0 && dest_y == 0) {
- size_t size = dest_image->height * dest_image->bytes_per_line;
- XImage *xi;
-
- xi = xreadscreen(disp, d, x, y, width, height,
- (Bool) overlay_cursor);
-
- if (! xi) return NULL;
-
- /*
- * There is extra overhead from memcpy and free...
- * this is not like the real XGetSubImage(). We hope
- * this significant overhead is still small compared to
- * the time to retrieve the fb data.
- */
- memcpy(dest_image->data, xi->data, size);
-
- XDestroyImage(xi);
- return (dest_image);
- }
- return XGetSubImage(disp, d, x, y, width, height, plane_mask,
- format, dest_image, dest_x, dest_y);
-#endif /* NO_X11 */
-}
-
-XImage *XGetImage_wr(Display *disp, Drawable d, int x, int y,
- unsigned int width, unsigned int height, unsigned long plane_mask,
- int format) {
-#if NO_X11
- if (!disp || !d || !x || !y || !width || !height || !plane_mask || !format) {}
- nox11_exit(1);
- return NULL;
-#else
-
- ADJUST_ROOTSHIFT
-
- if (overlay) {
- return xreadscreen(disp, d, x, y, width, height,
- (Bool) overlay_cursor);
- }
- return XGetImage(disp, d, x, y, width, height, plane_mask, format);
-#endif /* NO_X11 */
-}
-
-XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth,
- int format, int offset, char *data, unsigned int width,
- unsigned int height, int bitmap_pad, int bytes_per_line) {
- /*
- * This is a kludge to get a created XImage to exactly match what
- * XReadScreen returns: we noticed the rgb masks are different
- * from XCreateImage with the high color visual (red mask <->
- * blue mask). Note we read from the root window(!) then free
- * the data.
- */
-
- if (raw_fb) { /* raw_fb hack */
- XImage *xi;
- xi = (XImage *) malloc(sizeof(XImage));
- memset(xi, 0, sizeof(XImage));
- xi->depth = depth;
- if (depth >= 24) {
- xi->bits_per_pixel = 32;
- } else if (depth > 16) {
- xi->bits_per_pixel = 24;
- } else if (depth > 8) {
- xi->bits_per_pixel = 16;
- } else {
- xi->bits_per_pixel = 8;
- }
- xi->format = format;
- xi->xoffset = offset;
- xi->data = data;
- xi->width = width;
- xi->height = height;
- xi->bitmap_pad = bitmap_pad;
- xi->bytes_per_line = bytes_per_line ? bytes_per_line :
- xi->width * xi->bits_per_pixel / 8;
- xi->bitmap_unit = -1; /* hint to not call XDestroyImage */
- return xi;
- }
-
-#if NO_X11
- nox11_exit(1);
- if (!disp || !visual || !depth || !format || !offset || !data || !width
- || !height || !width || !bitmap_pad || !bytes_per_line) {}
- return NULL;
-#else
- if (overlay) {
- XImage *xi;
- xi = xreadscreen(disp, window, 0, 0, width, height, False);
- if (xi == NULL) {
- return xi;
- }
- if (xi->data != NULL) {
- free(xi->data);
- }
- xi->data = data;
- return xi;
- }
-
- return XCreateImage(disp, visual, depth, format, offset, data,
- width, height, bitmap_pad, bytes_per_line);
-#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 (rm_f | gm_f | bm_f) {}
-
- 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 < (unsigned int) 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++) {
-
- 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 < (int) w; ix++) {
- int bx = (x + ix) * raw_fb_native_bpp;
- int ib = bx / 8;
- int br = bx - ib * 8;
- unsigned char val;
-
- 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;
- }
-
- 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) {
- /*
- * kludge to read 1 byte at a time and dynamically transform
- * 24bpp -> 32bpp by inserting a extra 0 byte into dst.
- */
- char *src, *dst;
- unsigned int line;
- static char *buf = NULL;
- static int buflen = -1;
- int bpl = wdpy_x * 3; /* pixelsize == 3 */
- int LE, n, stp, len, del, sz = w * 3;
- int insert_zeroes = 1;
-
-#define INSERT_ZEROES \
- len = sz; \
- del = 0; \
- stp = 0; \
- while (len > 0) { \
- if (insert_zeroes && (del - LE) % 4 == 0) { \
- *(dst + del) = 0; \
- del++; \
- } \
- *(dst + del) = *(buf + stp); \
- del++; \
- len--; \
- stp++; \
- }
-
- if (rfbEndianTest) {
- LE = 3; /* little endian */
- } else {
- LE = 0; /* big endian */
- }
-
- if (sz > buflen || buf == NULL) {
- if (buf) {
- free(buf);
- }
- buf = (char *) malloc(4*(sz + 1000));
- }
-
- if (clipshift && ! use_snapfb) {
- x += coff_x;
- y += coff_y;
- }
-
- if (use_snapfb && dest != snap) {
- /* snapfb src */
- src = snap->data + snap->bytes_per_line*y + 3*x;
- dst = dest->data;
- for (line = 0; line < h; line++) {
- memcpy(buf, src, sz);
-
- INSERT_ZEROES
-
- src += snap->bytes_per_line;
- dst += dest->bytes_per_line;
- }
-
- } else if (! raw_fb_seek) {
- /* mmap */
- bpl = raw_fb_bytes_per_line;
- if (clipshift && wdpy_x != cdpy_x) {
- bpl = wdpy_x * 3;
- }
- src = raw_fb_addr + raw_fb_offset + bpl*y + 3*x;
- dst = dest->data;
-
- if (use_snapfb && dest == snap) {
- /*
- * writing *to* snap_fb: need the x,y offset,
- * and also do not do inserts.
- */
- dst += bpl*y + 3*x;
- insert_zeroes = 0;
- }
-
- for (line = 0; line < h; line++) {
- memcpy(buf, src, sz);
-
- INSERT_ZEROES
-
- src += bpl;
- dst += dest->bytes_per_line;
- }
-
- } else {
- /* lseek */
- off_t off;
- bpl = raw_fb_bytes_per_line;
- if (clipshift && wdpy_x != cdpy_x) {
- bpl = wdpy_x * 3;
- }
- off = (off_t) (raw_fb_offset + bpl*y + 3*x);
-
- lseek(raw_fb_fd, off, SEEK_SET);
- dst = dest->data;
-
- if (use_snapfb && dest == snap) {
- /*
- * writing *to* snap_fb: need the x,y offset,
- * and also do not do inserts.
- */
- dst += bpl*y + 3*x;
- insert_zeroes = 0;
- }
-
- for (line = 0; line < h; line++) {
- len = sz;
- 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;
- }
- }
-
- INSERT_ZEROES
-
- if (bpl > sz) {
- off = (off_t) (bpl - sz);
- lseek(raw_fb_fd, off, SEEK_CUR);
- }
- dst += dest->bytes_per_line;
- }
- }
-}
-
-#ifdef MACOSX
-void macosx_copy_opengl(char *, int, int, unsigned int, unsigned int);
-#endif
-
-void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
- char *src, *dst;
- unsigned int line;
- int pixelsize = bpp/8;
- static int db = -1;
-
-#ifdef MACOSX
- if (macosx_console && macosx_read_opengl) {
- macosx_copy_opengl(dest->data, x, y, w, h);
- return;
- }
-#endif
-
- if (xform24to32) {
- 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 (db < 0) {
- if (getenv("DEBUG_COPY_RAW_FB")) {
- db = atoi(getenv("DEBUG_COPY_RAW_FB"));
- } else {
- db = 0;
- }
- }
-
- if (clipshift && ! use_snapfb) {
- x += coff_x;
- y += coff_y;
- }
-
-
- if (use_snapfb && dest != snap) {
- /* snapfb src */
- src = snap->data + snap->bytes_per_line*y + pixelsize*x;
- dst = dest->data;
-
-if (db) fprintf(stderr, "snap->bytes_per_line: %d, dest->bytes_per_line: %d, w: %d h: %d dpy_x: %d wdpy_x: %d cdpy_x: %d bpp: %d pixelsize: %d\n", snap->bytes_per_line, dest->bytes_per_line, w, h, dpy_x, wdpy_x, cdpy_x, bpp, pixelsize);
-
- for (line = 0; line < h; line++) {
- memcpy(dst, src, w * pixelsize);
- src += snap->bytes_per_line;
- dst += dest->bytes_per_line;
- }
-
- } else if (! raw_fb_seek) {
- /* mmap */
- int bpl = raw_fb_bytes_per_line;
-
- if (clipshift && wdpy_x != cdpy_x) {
- bpl = wdpy_x * pixelsize;
- }
-
- src = raw_fb_addr + raw_fb_offset + bpl*y + pixelsize*x;
- dst = dest->data;
-
-if (db) fprintf(stderr, "bpl: %d, dest->bytes_per_line: %d, w: %d h: %d dpy_x: %d wdpy_x: %d cdpy_x: %d bpp: %d pixelsize: %d\n", bpl, dest->bytes_per_line, w, h, dpy_x, wdpy_x, cdpy_x, bpp, pixelsize);
-
- for (line = 0; line < h; line++) {
- memcpy(dst, src, w * pixelsize);
- src += bpl;
- dst += dest->bytes_per_line;
- }
-
- } else {
- /* lseek */
- int n, len, del, sz = w * pixelsize;
- off_t off;
- int bpl = raw_fb_bytes_per_line;
-
- if (clipshift && wdpy_x != cdpy_x) {
- bpl = wdpy_x * pixelsize;
- }
-
- off = (off_t) (raw_fb_offset + bpl*y + pixelsize*x);
-
- lseek(raw_fb_fd, off, SEEK_SET);
- dst = dest->data;
-
-if (db) fprintf(stderr, "lseek 0 ps: %d sz: %d off: %d bpl: %d\n", pixelsize, sz, (int) off, bpl);
-
- for (line = 0; line < h; line++) {
- len = sz;
- del = 0;
- while (len > 0) {
- n = read(raw_fb_fd, dst + del, len);
-
- if (n > 0) {
- del += n;
- len -= n;
- } else if (n == 0) {
- break;
- } else if (errno != EINTR && errno != EAGAIN) {
- break;
- }
- }
- if (bpl > sz) {
- off = (off_t) (bpl - sz);
- lseek(raw_fb_fd, off, SEEK_CUR);
- }
- dst += dest->bytes_per_line;
- }
- }
-}
-
-void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
- /* default (w=0, h=0) is the fill the entire XImage */
- if (dest == NULL) {
- return;
- }
- if (w < 1) {
- w = dest->width;
- }
- if (h < 1) {
- h = dest->height;
- }
-
- if (raw_fb) {
- copy_raw_fb(dest, x, y, w, h);
-
- } else if (use_snapfb && snap_fb && dest != snaprect) {
- char *src, *dst;
- unsigned int line;
- int pixelsize = bpp/8;
-
- src = snap->data + snap->bytes_per_line*y + pixelsize*x;
- dst = dest->data;
- for (line = 0; line < h; line++) {
- memcpy(dst, src, w * pixelsize);
- src += snap->bytes_per_line;
- dst += dest->bytes_per_line;
- }
-
- } else if ((using_shm && ! xform24to32) && (int) w == dest->width &&
- (int) h == dest->height) {
- XShmGetImage_wr(dpy, window, dest, x, y, AllPlanes);
-
- } else {
- XGetSubImage_wr(dpy, window, x, y, w, h, AllPlanes,
- ZPixmap, dest, 0, 0);
- }
-}
-
-#define DEBUG_SKIPPED_INPUT(dbg, str) \
- if (dbg) { \
- rfbLog("skipped input: %s\n", str); \
- }
-
-void init_track_keycode_state(void) {
- int i;
- for (i=0; i<256; i++) {
- keycode_state[i] = 0;
- }
- get_keystate(keycode_state);
-}
-
-static void upup_downdown_warning(KeyCode key, Bool down) {
- RAWFB_RET_VOID
-#if NO_X11
- if (!key || !down) {}
- return;
-#else
- if ((down ? 1:0) == keycode_state[(int) key]) {
- char *str = XKeysymToString(XKeycodeToKeysym(dpy, key, 0));
- rfbLog("XTestFakeKeyEvent: keycode=0x%x \"%s\" is *already* "
- "%s\n", key, str ? str : "null", down ? "down":"up");
- }
-#endif /* NO_X11 */
-}
-
-/*
- * wrappers for XTestFakeKeyEvent, etc..
- * also for XTrap equivalents XESimulateXEventRequest
- */
-
-void XTRAP_FakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
- unsigned long delay) {
-
- RAWFB_RET_VOID
-#if NO_X11
- nox11_exit(1);
- if (!dpy || !key || !down || !delay) {}
- return;
-#else
-
- if (! xtrap_present) {
- DEBUG_SKIPPED_INPUT(debug_keyboard, "keyboard: no-XTRAP");
- return;
- }
- /* unused vars warning: */
- if (key || down || delay) {}
-
-# if LIBVNCSERVER_HAVE_LIBXTRAP
- XESimulateXEventRequest(trap_ctx, down ? KeyPress : KeyRelease,
- key, 0, 0, 0);
- if (debug_keyboard) {
- upup_downdown_warning(key, down);
- }
- keycode_state[(int) key] = down ? 1 : 0;
-# else
- DEBUG_SKIPPED_INPUT(debug_keyboard, "keyboard: no-XTRAP-build");
-# endif
-
-#endif /* NO_X11 */
-}
-
-void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
- unsigned long delay) {
- static int first = 1;
- int regrab = 0;
-
- RAWFB_RET_VOID
-
-#if NO_X11
- nox11_exit(1);
- if (!dpy || !key || !down || !delay || !first) {}
- return;
-#else
- if (debug_keyboard) {
- char *str = XKeysymToString(XKeycodeToKeysym(dpy, key, 0));
- rfbLog("XTestFakeKeyEvent(dpy, keycode=0x%x \"%s\", %s)\n",
- key, str ? str : "null", down ? "down":"up");
- }
- if (first) {
- init_track_keycode_state();
- first = 0;
- }
- if (down) {
- last_keyboard_keycode = -key;
- } else {
- last_keyboard_keycode = key;
- }
-
- if (grab_kbd) {
- XUngrabKeyboard(dpy, CurrentTime);
- regrab = 1;
- }
- if (grab_ptr && ungrab_both) {
- XUngrabPointer(dpy, CurrentTime);
- regrab = 1;
- }
-
- if (xtrap_input) {
- XTRAP_FakeKeyEvent_wr(dpy, key, down, delay);
- if (regrab) {
- adjust_grabs(1, 1);
- }
- return;
- }
-
- if (! xtest_present) {
- DEBUG_SKIPPED_INPUT(debug_keyboard, "keyboard: no-XTEST");
- return;
- }
- if (debug_keyboard) {
- rfbLog("calling XTestFakeKeyEvent(%d, %d) %.4f\n",
- key, down, dnowx());
- }
-#if LIBVNCSERVER_HAVE_XTEST
- XTestFakeKeyEvent(dpy, key, down, delay);
- if (regrab) {
- adjust_grabs(1, 1);
- }
- if (debug_keyboard) {
- upup_downdown_warning(key, down);
- }
- keycode_state[(int) key] = down ? 1 : 0;
-#endif
-
-#endif /* NO_X11 */
-}
-
-void XTRAP_FakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
- unsigned long delay) {
-
- RAWFB_RET_VOID
-#if NO_X11
- nox11_exit(1);
- if (!dpy || !button || !is_press || !delay) {}
- return;
-#else
-
- if (! xtrap_present) {
- DEBUG_SKIPPED_INPUT(debug_keyboard, "button: no-XTRAP");
- return;
- }
- /* unused vars warning: */
- if (button || is_press || delay) {}
-
-#if LIBVNCSERVER_HAVE_LIBXTRAP
- XESimulateXEventRequest(trap_ctx,
- is_press ? ButtonPress : ButtonRelease, button, 0, 0, 0);
-#else
- DEBUG_SKIPPED_INPUT(debug_keyboard, "button: no-XTRAP-build");
-#endif
-
-#endif /* NO_X11 */
-}
-
-void XTestFakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
- unsigned long delay) {
- int regrab = 0;
-
- RAWFB_RET_VOID
-#if NO_X11
- nox11_exit(1);
- if (!dpy || !button || !is_press || !delay) {}
- return;
-#else
-
- if (grab_ptr) {
- XUngrabPointer(dpy, CurrentTime);
- regrab = 1;
- }
- if (grab_kbd && ungrab_both) {
- XUngrabKeyboard(dpy, CurrentTime);
- regrab = 1;
- }
-
- if (xtrap_input) {
- XTRAP_FakeButtonEvent_wr(dpy, button, is_press, delay);
- if (regrab) {
- adjust_grabs(1, 1);
- }
- return;
- }
-
- if (! xtest_present) {
- DEBUG_SKIPPED_INPUT(debug_keyboard, "button: no-XTEST");
- return;
- }
- if (debug_pointer) {
- rfbLog("calling XTestFakeButtonEvent(%d, %d) %.4f\n",
- button, is_press, dnowx());
- }
-#if LIBVNCSERVER_HAVE_XTEST
- XTestFakeButtonEvent(dpy, button, is_press, delay);
-#endif
- if (regrab) {
- adjust_grabs(1, 1);
- }
-#endif /* NO_X11 */
-}
-
-void XTRAP_FakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
- unsigned long delay) {
-
- RAWFB_RET_VOID
-
-#if NO_X11
- nox11_exit(1);
- if (!dpy || !screen || !x || !y || !delay) {}
- return;
-#else
- if (! xtrap_present) {
- DEBUG_SKIPPED_INPUT(debug_keyboard, "motion: no-XTRAP");
- return;
- }
- /* unused vars warning: */
- if (dpy || screen || x || y || delay) {}
-
-#if LIBVNCSERVER_HAVE_LIBXTRAP
- XESimulateXEventRequest(trap_ctx, MotionNotify, 0, x, y, 0);
-#else
- DEBUG_SKIPPED_INPUT(debug_keyboard, "motion: no-XTRAP-build");
-#endif
-
-#endif /* NO_X11 */
-}
-
-void XTestFakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
- unsigned long delay) {
- int regrab = 0;
-
- RAWFB_RET_VOID
-#if NO_X11
- nox11_exit(1);
- if (!dpy || !screen || !x || !y || !delay) {}
- return;
-#else
-
- if (grab_ptr) {
- XUngrabPointer(dpy, CurrentTime);
- regrab = 1;
- }
- if (grab_kbd && ungrab_both) {
- XUngrabKeyboard(dpy, CurrentTime);
- regrab = 1;
- }
-
- if (xtrap_input) {
- XTRAP_FakeMotionEvent_wr(dpy, screen, x, y, delay);
- if (regrab) {
- adjust_grabs(1, 1);
- }
- return;
- }
-
- if (debug_pointer) {
- rfbLog("calling XTestFakeMotionEvent(%d, %d) %.4f\n",
- x, y, dnowx());
- }
-#if LIBVNCSERVER_HAVE_XTEST
- XTestFakeMotionEvent(dpy, screen, x, y, delay);
-#endif
- if (regrab) {
- adjust_grabs(1, 1);
- }
-#endif /* NO_X11 */
-}
-
-Bool XTestCompareCurrentCursorWithWindow_wr(Display* dpy, Window w) {
- if (! xtest_present) {
- return False;
- }
- RAWFB_RET(False)
-
-#if LIBVNCSERVER_HAVE_XTEST
- return XTestCompareCurrentCursorWithWindow(dpy, w);
-#else
- if (!w) {}
- return False;
-#endif
-}
-
-Bool XTestCompareCursorWithWindow_wr(Display* dpy, Window w, Cursor cursor) {
- if (! xtest_present) {
- return False;
- }
- RAWFB_RET(False)
-#if LIBVNCSERVER_HAVE_XTEST
- return XTestCompareCursorWithWindow(dpy, w, cursor);
-#else
- if (!dpy || !w || !cursor) {}
- return False;
-#endif
-}
-
-Bool XTestQueryExtension_wr(Display *dpy, int *ev, int *er, int *maj,
- int *min) {
- RAWFB_RET(False)
-#if LIBVNCSERVER_HAVE_XTEST
- return XTestQueryExtension(dpy, ev, er, maj, min);
-#else
- if (!dpy || !ev || !er || !maj || !min) {}
- return False;
-#endif
-}
-
-void XTestDiscard_wr(Display *dpy) {
- if (! xtest_present) {
- return;
- }
- RAWFB_RET_VOID
-#if LIBVNCSERVER_HAVE_XTEST
- XTestDiscard(dpy);
-#else
- if (!dpy) {}
-#endif
-}
-
-Bool XETrapQueryExtension_wr(Display *dpy, int *ev, int *er, int *op) {
- RAWFB_RET(False)
-#if LIBVNCSERVER_HAVE_LIBXTRAP
- return XETrapQueryExtension(dpy, (INT32 *)ev, (INT32 *)er,
- (INT32 *)op);
-#else
- /* unused vars warning: */
- if (ev || er || op) {}
- return False;
-#endif
-}
-
-int XTestGrabControl_wr(Display *dpy, Bool impervious) {
- if (! xtest_present) {
- return 0;
- }
- RAWFB_RET(0)
-#if LIBVNCSERVER_HAVE_XTEST && LIBVNCSERVER_HAVE_XTESTGRABCONTROL
- XTestGrabControl(dpy, impervious);
- return 1;
-#else
- if (!dpy || !impervious) {}
- return 0;
-#endif
-}
-
-int XTRAP_GrabControl_wr(Display *dpy, Bool impervious) {
- if (! xtrap_present) {
- /* unused vars warning: */
- if (dpy || impervious) {}
- return 0;
- }
- RAWFB_RET(0)
-#if LIBVNCSERVER_HAVE_LIBXTRAP
- else {
- ReqFlags requests;
-
- if (! impervious) {
- if (trap_ctx) {
- XEFreeTC(trap_ctx);
- }
- trap_ctx = NULL;
- return 1;
- }
-
- if (! trap_ctx) {
- trap_ctx = XECreateTC(dpy, 0, NULL);
- if (! trap_ctx) {
- rfbLog("DEC-XTRAP XECreateTC failed. Watch "
- "out for XGrabServer from wm's\n");
- return 0;
- }
- XEStartTrapRequest(trap_ctx);
- memset(requests, 0, sizeof(requests));
- BitTrue(requests, X_GrabServer);
- BitTrue(requests, X_UngrabServer);
- XETrapSetRequests(trap_ctx, True, requests);
- XETrapSetGrabServer(trap_ctx, True);
- }
- return 1;
- }
-#endif
- return 0;
-}
-
-void disable_grabserver(Display *in_dpy, int change) {
- int ok = 0;
- static int didmsg = 0;
-
- if (debug_grabs) {
- fprintf(stderr, "disable_grabserver/%d %.5f\n",
- xserver_grabbed, dnowx());
- didmsg = 0;
- }
-
- if (! xtrap_input) {
- if (XTestGrabControl_wr(in_dpy, True)) {
- if (change) {
- XTRAP_GrabControl_wr(in_dpy, False);
- }
- if (! didmsg && ! raw_fb_str) {
- rfbLog("GrabServer control via XTEST.\n");
- didmsg = 1;
- }
- ok = 1;
- } else {
- if (XTRAP_GrabControl_wr(in_dpy, True)) {
- ok = 1;
- if (! didmsg && ! raw_fb_str) {
- rfbLog("Using DEC-XTRAP for protection"
- " from XGrabServer.\n");
- didmsg = 1;
- }
- }
- }
- } else {
- if (XTRAP_GrabControl_wr(in_dpy, True)) {
- if (change) {
- XTestGrabControl_wr(in_dpy, False);
- }
- if (! didmsg && ! raw_fb_str) {
- rfbLog("GrabServer control via DEC-XTRAP.\n");
- didmsg = 1;
- }
- ok = 1;
- } else {
- if (XTestGrabControl_wr(in_dpy, True)) {
- ok = 1;
- if (! didmsg && ! raw_fb_str) {
- rfbLog("DEC-XTRAP XGrabServer "
- "protection not available, "
- "using XTEST.\n");
- didmsg = 1;
- }
- }
- }
- }
- if (! ok && ! didmsg) {
- rfbLog("*********************************************************\n");
- rfbLog("* No XTEST or DEC-XTRAP protection from XGrabServer !!! *\n");
- rfbLog("* DEADLOCK if your window manager calls XGrabServer !!! *\n");
- rfbLog("*********************************************************\n");
- }
- XFlush_wr(in_dpy);
-}
-
-Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min) {
- RAWFB_RET(False)
-#if LIBVNCSERVER_HAVE_RECORD
- return XRecordQueryVersion(dpy, maj, min);
-#else
- if (!dpy || !maj || !min) {}
- return False;
-#endif
-}
-
-int xauth_raw(int on) {
- char tmp[] = "/tmp/x11vnc-xauth.XXXXXX";
- int tmp_fd = -1;
- static char *old_xauthority = NULL;
- static char *old_tmp = NULL;
- int db = 0;
-
- if (on) {
- if (old_xauthority) {
- free(old_xauthority);
- old_xauthority = NULL;
- }
- if (old_tmp) {
- free(old_tmp);
- old_tmp = NULL;
- }
- if (xauth_raw_data) {
- tmp_fd = mkstemp(tmp);
- if (tmp_fd < 0) {
- rfbLog("could not create tmp xauth file: %s\n", tmp);
- return 0;
- }
- if (db) fprintf(stderr, "XAUTHORITY tmp: %s\n", tmp);
- write(tmp_fd, xauth_raw_data, xauth_raw_len);
- close(tmp_fd);
- if (getenv("XAUTHORITY")) {
- old_xauthority = strdup(getenv("XAUTHORITY"));
- } else {
- old_xauthority = strdup("");
- }
- set_env("XAUTHORITY", tmp);
- old_tmp = strdup(tmp);
- }
- return 1;
- } else {
- if (old_xauthority) {
- if (!strcmp(old_xauthority, "")) {
- char *xauth = getenv("XAUTHORITY");
- if (xauth) {
- *(xauth-2) = '_'; /* yow */
- }
- } else {
- set_env("XAUTHORITY", old_xauthority);
- }
- free(old_xauthority);
- old_xauthority = NULL;
- }
- if (old_tmp) {
- unlink(old_tmp);
- free(old_tmp);
- old_tmp = NULL;
- }
- return 1;
- }
-}
-
-Display *XOpenDisplay_wr(char *display_name) {
- Display *d = NULL;
- int db = 0;
-
- if (! xauth_raw(1)) {
- return NULL;
- }
-#if NO_X11
- rfbLog("This x11vnc was built without X11 support (-rawfb only).\n");
- if (!display_name || !d || !db) {}
- return NULL;
-#else
-
- d = XOpenDisplay(display_name);
- if (db) fprintf(stderr, "XOpenDisplay_wr: %s %p\n", display_name, (void *)d);
-
- if (d == NULL && !getenv("NO_XAUTHLOCALHOSTNAME")) {
- char *xalhn = getenv("XAUTHLOCALHOSTNAME");
- if (1 || !xalhn) {
- rfbLog("XOpenDisplay(\"%s\") failed.\n",
- display_name ? display_name : "");
- rfbLog("Trying again with XAUTHLOCALHOSTNAME=localhost ...\n");
- set_env("XAUTHLOCALHOSTNAME", "localhost");
- d = XOpenDisplay(display_name);
- if (d == NULL && xalhn) {
- char *ptr = getenv("XAUTHLOCALHOSTNAME");
- if (ptr) {
- *(ptr-2) = '_'; /* yow */
- rfbLog("XOpenDisplay(\"%s\") failed.\n",
- display_name ? display_name : "");
- rfbLog("Trying again with unset XAUTHLOCALHOSTNAME ...\n");
- d = XOpenDisplay(display_name);
- }
- }
- }
- }
-
- xauth_raw(0);
-
- return d;
-#endif /* NO_X11 */
-}
-
-int XCloseDisplay_wr(Display *display) {
- int db = 0;
- if (db) fprintf(stderr, "XCloseDisplay_wr: %p\n", (void *)display);
-#if NO_X11
- return 0;
-#else
- return XCloseDisplay(display);
-#endif /* NO_X11 */
-}
-
-static unsigned int Bmask = (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask);
-static unsigned int Mmask = (ShiftMask|LockMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask);
-
-static unsigned int last_local_button_mask = 0;
-static unsigned int last_local_mod_mask = 0;
-static int last_local_x = 0;
-static int last_local_y = 0;
-
-Bool XQueryPointer_wr(Display *display, Window w, Window *root_return,
- Window *child_return, int *root_x_return, int *root_y_return,
- int *win_x_return, int *win_y_return, unsigned int *mask_return) {
-#if NO_X11
- if (!display || !w || !root_return || !child_return || !root_x_return
- || !root_y_return || !win_x_return || !win_y_return || !mask_return) {}
- return False;
-#else
- Bool rc;
- XErrorHandler old_handler;
-
-
- if (! display) {
- return False;
- }
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
-
- rc = XQueryPointer(display, w, root_return, child_return,
- root_x_return, root_y_return, win_x_return, win_y_return,
- mask_return);
-
- XSetErrorHandler(old_handler);
- if (trapped_xerror) {
- rc = 0;
- }
- if (rc) {
- display_button_mask = (*mask_return) & Bmask;
- display_mod_mask = (*mask_return) & Mmask;
- if (last_local_button_mask != display_button_mask) {
- got_local_pointer_input++;
- } else if (*root_x_return != last_local_x ||
- *root_y_return != last_local_y) {
- got_local_pointer_input++;
- }
- last_local_button_mask = display_button_mask;
- last_local_mod_mask = display_mod_mask;
- last_local_x = *root_x_return;
- last_local_y = *root_y_return;
- }
- return rc;
-#endif /* NO_X11 */
-}
-
-
-Status XQueryTree_wr(Display *display, Window w, Window *root_return,
- Window *parent_return, Window **children_return,
- unsigned int *nchildren_return) {
-
-#ifdef MACOSX
- if (macosx_console) {
- return macosx_xquerytree(w, root_return, parent_return,
- children_return, nchildren_return);
- }
-#endif
-#if NO_X11
- if (!display || !w || !root_return || !parent_return
- || !children_return || !nchildren_return) {}
- return (Status) 0;
-#else
- if (! display) {
- return (Status) 0;
- }
- return XQueryTree(display, w, root_return, parent_return,
- children_return, nchildren_return);
-#endif /* NO_X11 */
-
-}
-
-int XFree_wr(void *data) {
- if (data == NULL) {
- return 1;
- }
- if (! dpy) {
- return 1;
- }
-#if NO_X11
- return 1;
-#else
- return XFree(data);
-#endif
-}
-
-int XSelectInput_wr(Display *display, Window w, long event_mask) {
-#if NO_X11
- if (!display || !w || !event_mask) {}
- return 0;
-#else
- int rc;
- XErrorHandler old_handler;
- if (display == NULL || w == None) {
- return 0;
- }
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
- rc = XSelectInput(display, w, event_mask);
- XSetErrorHandler(old_handler);
- if (trapped_xerror) {
- rc = 0;
- }
- return rc;
-#endif
-}
-
-void nox11_exit(int rc) {
-#if NO_X11
- rfbLog("This x11vnc was not built with X11 support.\n");
- clean_up_exit(rc);
-#else
- if (0) {rc = 0;}
-#endif
-}
-
-
-#if NO_X11
-#include "nox11_funcs.h"
-#endif
-
diff --git a/x11vnc/xwrappers.h b/x11vnc/xwrappers.h
deleted file mode 100644
index f1e0fbf..0000000
--- a/x11vnc/xwrappers.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-#ifndef _X11VNC_XWRAPPERS_H
-#define _X11VNC_XWRAPPERS_H
-
-/* -- xwrappers.h -- */
-
-extern int xshm_present;
-extern int xshm_opcode;
-extern int xtest_present;
-extern int xtrap_present;
-extern int xrecord_present;
-extern int xkb_present;
-extern int xinerama_present;
-
-extern int keycode_state[];
-extern int rootshift;
-extern int clipshift;
-
-
-extern int guess_bits_per_color(int bits_per_pixel);
-
-extern int XFlush_wr(Display *disp);
-
-extern Status XShmGetImage_wr(Display *disp, Drawable d, XImage *image, int x, int y,
- unsigned long mask);
-extern XImage *XShmCreateImage_wr(Display* disp, Visual* vis, unsigned int depth,
- int format, char* data, XShmSegmentInfo* shminfo, unsigned int width,
- unsigned int height);
-extern Status XShmAttach_wr(Display *disp, XShmSegmentInfo *shminfo);
-extern Status XShmDetach_wr(Display *disp, XShmSegmentInfo *shminfo);
-extern Bool XShmQueryExtension_wr(Display *disp);
-extern int XShmGetEventBase_wr(Display *disp);
-
-extern XImage *xreadscreen(Display *disp, Drawable d, int x, int y,
- unsigned int width, unsigned int height, Bool show_cursor);
-extern XImage *XGetSubImage_wr(Display *disp, Drawable d, int x, int y,
- unsigned int width, unsigned int height, unsigned long plane_mask,
- int format, XImage *dest_image, int dest_x, int dest_y);
-extern XImage *XGetImage_wr(Display *disp, Drawable d, int x, int y,
- unsigned int width, unsigned int height, unsigned long plane_mask,
- int format);
-extern XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth,
- int format, int offset, char *data, unsigned int width,
- unsigned int height, int bitmap_pad, int bytes_per_line);
-extern void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h);
-extern void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
-extern void init_track_keycode_state(void);
-
-extern void XTRAP_FakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
- unsigned long delay);
-extern void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
- unsigned long delay);
-extern void XTRAP_FakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
- unsigned long delay);
-extern void XTestFakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
- unsigned long delay);
-extern void XTRAP_FakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
- unsigned long delay);
-extern void XTestFakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
- unsigned long delay);
-
-extern Bool XTestCompareCurrentCursorWithWindow_wr(Display* dpy, Window w);
-extern Bool XTestCompareCursorWithWindow_wr(Display* dpy, Window w, Cursor cursor);
-extern Bool XTestQueryExtension_wr(Display *dpy, int *ev, int *er, int *maj,
- int *min);
-extern void XTestDiscard_wr(Display *dpy);
-extern Bool XETrapQueryExtension_wr(Display *dpy, int *ev, int *er, int *op);
-extern int XTestGrabControl_wr(Display *dpy, Bool impervious);
-extern int XTRAP_GrabControl_wr(Display *dpy, Bool impervious);
-extern void disable_grabserver(Display *in_dpy, int change);
-
-extern Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min);
-
-extern int xauth_raw(int on);
-extern Display *XOpenDisplay_wr(char *display_name);
-extern int XCloseDisplay_wr(Display *display);
-
-extern Bool XQueryPointer_wr(Display *display, Window w, Window *root_return,
- Window *child_return, int *root_x_return, int *root_y_return,
- int *win_x_return, int *win_y_return, unsigned int *mask_return);
-
-extern Status XQueryTree_wr(Display *display, Window w, Window *root_return,
- Window *parent_return, Window **children_return,
- unsigned int *nchildren_return);
-
-extern int XFree_wr(void *data);
-extern int XSelectInput_wr(Display *display, Window w, long event_mask);
-
-
-#endif /* _X11VNC_XWRAPPERS_H */
OpenPOWER on IntegriCloud