summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrunge <runge>2007-08-19 19:13:12 +0000
committerrunge <runge>2007-08-19 19:13:12 +0000
commit222ecab5cae7add1186bbfe3bf50608b0d90b0c1 (patch)
tree6c0580cc8c4dd6fffd6492e67017cc10738e89c4
parenta69ed666eb66fc9a4d93a2fd9496c99d82e0d4d3 (diff)
downloadlibtdevnc-222ecab5.tar.gz
libtdevnc-222ecab5.zip
x11vnc: better -xkb tie-breaking for up keystrokes. Add Xsrv/FD_XSRV custom server to FINDCREATEDISPLAY list.
-rw-r--r--x11vnc/ChangeLog4
-rw-r--r--x11vnc/README54
-rw-r--r--x11vnc/help.c48
-rw-r--r--x11vnc/keyboard.c152
-rw-r--r--x11vnc/ssltools.h19
-rw-r--r--x11vnc/user.c13
-rw-r--r--x11vnc/x11vnc.151
-rw-r--r--x11vnc/x11vnc_defs.c2
8 files changed, 273 insertions, 70 deletions
diff --git a/x11vnc/ChangeLog b/x11vnc/ChangeLog
index 8962e33..d604e8f 100644
--- a/x11vnc/ChangeLog
+++ b/x11vnc/ChangeLog
@@ -1,3 +1,7 @@
+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.
diff --git a/x11vnc/README b/x11vnc/README
index b90e46d..6928025 100644
--- a/x11vnc/README
+++ b/x11vnc/README
@@ -1,5 +1,5 @@
-x11vnc README file Date: Fri Aug 17 23:09:12 EDT 2007
+x11vnc README file Date: Sun Aug 19 14:30:12 EDT 2007
The following information is taken from these URLs:
@@ -11075,7 +11075,7 @@ x11vnc: a VNC server for real X displays
Here are all of x11vnc command line options:
% x11vnc -opts (see below for -help long descriptions)
-x11vnc: allow VNC connections to real X11 displays. 0.9.3 lastmod: 2007-08-17
+x11vnc: allow VNC connections to real X11 displays. 0.9.3 lastmod: 2007-08-19
x11vnc options:
-display disp -auth file -N
@@ -11189,7 +11189,7 @@ libvncserver-tight-extension options:
% x11vnc -help
-x11vnc: allow VNC connections to real X11 displays. 0.9.3 lastmod: 2007-08-17
+x11vnc: allow VNC connections to real X11 displays. 0.9.3 lastmod: 2007-08-19
(type "x11vnc -opts" to just list the options.)
@@ -12065,7 +12065,7 @@ Options:
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
- start up an X server.
+ actually start up an X server.
By default FINDCREATEDISPLAY will try Xdummy and
then Xvfb. The Xdummy wrapper is part of the x11vnc
@@ -12100,22 +12100,30 @@ Options:
X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 (also -env ...)
Use WAIT:cmd=FINDCREATEDISPLAY-print to print out the
- script used. You can specify the preferred order via
- e.g., WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb,X and/or
- leave out ones you do not want. The the extra case
- "X" means try to start up a real, hardware X server
- using xinit(1) or startx(1). "Xvnc" also works. If
- there is already an X server running the X case may
- only work on Linux (see startx(1)).
+ script used.
+
+ 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), and FD_OPTS as extra options to pass
- to the created X server. You can also set FD_PROG to
- be the full path to the session/windowmanager program.
+ 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 as extra options to pass to
+ the X server. You can also set FD_PROG to be the full
+ path to the session/windowmanager program.
If you want the FINDCREATEDISPLAY session to contact an
XDMCP login manager (xdm/gdm/kdm) on the same machine,
@@ -13089,6 +13097,16 @@ t
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 keep was press 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
diff --git a/x11vnc/help.c b/x11vnc/help.c
index e6f8b37..03a3e1a 100644
--- a/x11vnc/help.c
+++ b/x11vnc/help.c
@@ -899,7 +899,7 @@ void print_help(int mode) {
" 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"
-" start up an X server.\n"
+" actually start up an X server.\n"
"\n"
" By default FINDCREATEDISPLAY will try Xdummy and\n"
" then Xvfb. The Xdummy wrapper is part of the x11vnc\n"
@@ -934,22 +934,30 @@ void print_help(int mode) {
" X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 (also -env ...)\n"
"\n"
" Use WAIT:cmd=FINDCREATEDISPLAY-print to print out the\n"
-" script used. You can specify the preferred order via\n"
-" e.g., WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb,X and/or\n"
-" leave out ones you do not want. The the extra case\n"
-" \"X\" means try to start up a real, hardware X server\n"
-" using xinit(1) or startx(1). \"Xvnc\" also works. If\n"
-" there is already an X server running the X case may\n"
-" only work on Linux (see startx(1)).\n"
+" script used.\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), and FD_OPTS as extra options to pass\n"
-" to the created X server. You can also set FD_PROG to\n"
-" be the full path to the session/windowmanager program.\n"
+" X11VNC_CREATE_GEOM) to WxH or WxHxD to set the width and\n"
+" height and optionally the color depth of the created\n"
+" display. You can also set FD_SESS to be the session\n"
+" (short name of the windowmanager: kde, gnome, twm,\n"
+" failsafe, etc.). FD_OPTS as extra options to pass to\n"
+" the X server. You can also set FD_PROG to be the full\n"
+" path to the session/windowmanager program.\n"
"\n"
" If you want the FINDCREATEDISPLAY session to contact an\n"
" XDMCP login manager (xdm/gdm/kdm) on the same machine,\n"
@@ -1931,6 +1939,16 @@ void print_help(int mode) {
" 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 keep was press 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"
diff --git a/x11vnc/keyboard.c b/x11vnc/keyboard.c
index c7eaa97..15e7c70 100644
--- a/x11vnc/keyboard.c
+++ b/x11vnc/keyboard.c
@@ -1466,6 +1466,7 @@ xkbmodifiers[] For the KeySym bound to this (keycode,group,level) store
}
}
+static int score_hint[0x100][0x100];
/*
* Called on user keyboard input. Try to solve the reverse mapping
* problem: KeySym (from VNC client) => KeyCode(s) to press to generate
@@ -1485,8 +1486,10 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
XkbStateRec kbstate;
int got_kbstate = 0;
int Kc_f, Grp_f = 0, Lvl_f = 0;
- static int Kc_last_down = -1;
- static KeySym Ks_last_down = NoSymbol;
+# define KLAST 10
+ static int Kc_last_down[KLAST];
+ static KeySym Ks_last_down[KLAST];
+ static int klast = 0, khints = 1, anydown = 1;
if (!client || !down || !keysym) {} /* unused vars warning: */
@@ -1494,6 +1497,32 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
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;
+ }
+ for (i=0; i<0x100; i++) {
+ for (j=0; j<0x100; j++) {
+ score_hint[i][j] = -1;
+ }
+ }
+ }
+
if (debug_keyboard) {
char *str = XKeysymToString(keysym);
@@ -1636,6 +1665,12 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
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;
@@ -1678,6 +1713,9 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
"keycode %03d: %4d\n",
kc_f[l], myscore);
}
+ if (khints && keysym < 0x100 && kc_f[l] < 0x100) {
+ score_hint[(int) keysym][kc_f[l]] = score[l];
+ }
}
for (l=0; l < found; l++) {
int myscore = score[l];
@@ -1693,39 +1731,125 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
} else {
/* up */
+ int i, Kc_loc = -1;
Kc_f = -1;
- if (keysym == Ks_last_down) {
- int l;
+
+ /* 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, sbest = -1, lbest, l;
for (l=0; l < found; l++) {
- if (Kc_last_down == kc_f[l]) {
- Kc_f = Kc_last_down;
+ 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 any one that is down */
+ if (Kc_f == -1 && anydown) {
int l;
+ int best = -1, lbest;
/*
* If it is already down, that is
* a great hint. Use it.
*
- * note: keycode_state in internal and
+ * note: keycode_state is internal and
* ignores someone pressing keys on the
* physical display (but is updated
* periodically to clean out stale info).
*/
+ /* we could probably break ties based on lowest XKeycodeToKeysym index */
for (l=0; l < found; l++) {
int key = (int) kc_f[l];
+ int j, jmatch = -1;
+
if (keycode_state[key]) {
- Kc_f = kc_f[l];
- break;
+ continue;
+ }
+ 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);
}
}
+ /* 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, kc_f[0]!!\n");
+ }
}
}
} else {
@@ -1747,7 +1871,7 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
fprintf(stderr, " \"%s\"", str ? str : "null");
}
fprintf(stderr, ", picked this one: %03d (last down: %03d)\n",
- Kc_f, Kc_last_down);
+ Kc_f, Kc_last_down[0]);
}
if (sloppy_keys) {
@@ -1769,8 +1893,12 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
Bool dn;
/* remember these to aid the subsequent up case: */
- Ks_last_down = keysym;
- Kc_last_down = Kc_f;
+ 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 */
diff --git a/x11vnc/ssltools.h b/x11vnc/ssltools.h
index 2bf5157..33576ff 100644
--- a/x11vnc/ssltools.h
+++ b/x11vnc/ssltools.h
@@ -1208,6 +1208,15 @@ char create_display[] =
" 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"
+"\n"
"try_Xvfb() {\n"
" if [ \"X$have_Xvfb\" = \"X\" ]; then\n"
" return\n"
@@ -1427,13 +1436,15 @@ char create_display[] =
" fi\n"
" curr_try=`echo \"$curr_try\" | sed -e 's/[+.-]xdmcp//'`\n"
" \n"
-" if echo \"$curr_try\" | grep -iw \"Xdummy\" > /dev/null; then\n"
+" if echo \"$curr_try\" | grep -iw \"^Xdummy\" > /dev/null; then\n"
" try_Xdummy\n"
-" elif echo \"$curr_try\" | grep -iw \"Xvfb\" > /dev/null; then\n"
+" elif echo \"$curr_try\" | grep -iw \"^Xvfb\" > /dev/null; then\n"
" try_Xvfb\n"
-" elif echo \"$curr_try\" | grep -iw \"Xvnc\" > /dev/null; then\n"
+" elif echo \"$curr_try\" | grep -iw \"^Xvnc\" > /dev/null; then\n"
" try_Xvnc\n"
-" elif echo \"$curr_try\" | grep -iw \"X\" > /dev/null; then\n"
+" elif echo \"$curr_try\" | grep -iw \"^Xsrv\" > /dev/null; then\n"
+" try_Xsrv\n"
+" elif echo \"$curr_try\" | grep -iw \"^X\" > /dev/null; then\n"
" try_X\n"
" fi\n"
" if [ \"X$result\" = \"X1\" ]; then\n"
diff --git a/x11vnc/user.c b/x11vnc/user.c
index 9a8a663..94b0629 100644
--- a/x11vnc/user.c
+++ b/x11vnc/user.c
@@ -1789,7 +1789,7 @@ if (0) db = 1;
if (strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
char *opts = strchr(cmd, '-');
char st[] = "";
- char geom[128], xsess[128], fdopts[128], fdprog[128];
+ char geom[128], xsess[128], fdopts[128], fdprog[128], fdxsrv[128];
if (opts) {
opts++;
if (strstr(opts, "xdmcp")) {
@@ -1803,6 +1803,7 @@ if (0) db = 1;
geom[0] = '\0';
fdopts[0] = '\0';
fdprog[0] = '\0';
+ fdxsrv[0] = '\0';
#if 0
if (!keep_unixpw_opts) {
fprintf(stderr, "no keep_unixpw_opts\n");
@@ -1878,11 +1879,15 @@ if (!keep_unixpw_opts) {
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"));
+ }
set_env("FD_GEOM", geom);
set_env("FD_SESS", xsess);
set_env("FD_OPTS", fdopts);
set_env("FD_PROG", fdprog);
+ set_env("FD_XSRV", fdxsrv);
if (usslpeer || (unixpw && keep_unixpw_user)) {
char *uu = usslpeer;
@@ -1894,15 +1899,17 @@ if (!keep_unixpw_opts) {
+ strlen("FD_GEOM='' ")
+ strlen("FD_OPTS='' ")
+ strlen("FD_PROG='' ")
+ + strlen("FD_XSRV='' ")
+ strlen("FD_SESS='' /bin/sh ")
+ strlen(uu) + 1
+ strlen(geom) + 1
+ strlen(xsess) + 1
+ strlen(fdopts) + 1
+ strlen(fdprog) + 1
+ + strlen(fdxsrv) + 1
+ strlen(opts) + 1);
- sprintf(create_cmd, "env USER='%s' FD_GEOM='%s' FD_SESS='%s' FD_OPTS='%s' FD_PROG='%s' /bin/sh %s %s",
- uu, geom, xsess, fdopts, fdprog, tmp, opts);
+ sprintf(create_cmd, "env USER='%s' FD_GEOM='%s' FD_SESS='%s' FD_OPTS='%s' FD_PROG='%s' FD_XSRV='%s' /bin/sh %s %s",
+ uu, geom, xsess, fdopts, fdprog, fdxsrv, tmp, opts);
} else {
create_cmd = (char *) malloc(strlen(tmp)
+ strlen("/bin/sh ") + 1 + strlen(opts) + 1);
diff --git a/x11vnc/x11vnc.1 b/x11vnc/x11vnc.1
index 71bcdcd..f3af7f2 100644
--- a/x11vnc/x11vnc.1
+++ b/x11vnc/x11vnc.1
@@ -2,7 +2,7 @@
.TH X11VNC "1" "August 2007" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
- version: 0.9.3, lastmod: 2007-08-17
+ version: 0.9.3, lastmod: 2007-08-19
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@@ -1050,7 +1050,7 @@ 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
-start up an X server.
+actually start up an X server.
.IP
By default FINDCREATEDISPLAY will try Xdummy and
then Xvfb. The Xdummy wrapper is part of the x11vnc
@@ -1087,28 +1087,35 @@ try to find an existing display set the env. var
X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 (also \fB-env\fR ...)
.IP
Use WAIT:cmd=FINDCREATEDISPLAY-print to print out the
-script used. You can specify the preferred order via
-e.g., WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb,X and/or
-leave out ones you do not want. The the extra case
-"X" means try to start up a real, hardware X server
-using
+script used.
+.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).
-"Xvnc" also works. If
-there is already an X server running the X case may
-only work on Linux (see
+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), and FD_OPTS as extra options to pass
-to the created X server. You can also set FD_PROG to
-be the full path to the session/windowmanager program.
+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 as 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
If you want the FINDCREATEDISPLAY session to contact an
XDMCP login manager (xdm/gdm/kdm) on the same machine,
@@ -2233,6 +2240,16 @@ 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 keep was press 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
diff --git a/x11vnc/x11vnc_defs.c b/x11vnc/x11vnc_defs.c
index dff6f19..1ca84a6 100644
--- a/x11vnc/x11vnc_defs.c
+++ b/x11vnc/x11vnc_defs.c
@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
-char lastmod[] = "0.9.3 lastmod: 2007-08-17";
+char lastmod[] = "0.9.3 lastmod: 2007-08-19";
/* X display info */