From 222ecab5cae7add1186bbfe3bf50608b0d90b0c1 Mon Sep 17 00:00:00 2001 From: runge Date: Sun, 19 Aug 2007 19:13:12 +0000 Subject: x11vnc: better -xkb tie-breaking for up keystrokes. Add Xsrv/FD_XSRV custom server to FINDCREATEDISPLAY list. --- x11vnc/ChangeLog | 4 ++ x11vnc/README | 54 ++++++++++++------ x11vnc/help.c | 48 +++++++++++----- x11vnc/keyboard.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++---- x11vnc/ssltools.h | 19 +++++-- x11vnc/user.c | 13 ++++- x11vnc/x11vnc.1 | 51 +++++++++++------ x11vnc/x11vnc_defs.c | 2 +- 8 files changed, 273 insertions(+), 70 deletions(-) (limited to 'x11vnc') 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 + * x11vnc: better -xkb tie-breaking for up keystrokes. Add + Xsrv/FD_XSRV custom server to FINDCREATEDISPLAY list. + 2007-08-18 Karl Runge * 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) 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 */ -- cgit v1.2.3