Commit 5b198763 authored by runge's avatar runge

x11vnc: FINDCREATEDISPLAY support to create X session if one cannot be found. ...

x11vnc: FINDCREATEDISPLAY support to create X session if one cannot be found.  Fix bug in java viewer.
parent 726cedb8
......@@ -1378,7 +1378,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+}
diff -x VncCanvas.java -Naur vnc_javasrc.orig/VncViewer.java vnc_javasrc/VncViewer.java
--- vnc_javasrc.orig/VncViewer.java 2004-03-04 08:34:25.000000000 -0500
+++ vnc_javasrc/VncViewer.java 2006-09-23 18:36:42.000000000 -0400
+++ vnc_javasrc/VncViewer.java 2006-12-01 02:31:26.000000000 -0500
@@ -88,6 +88,14 @@
int deferCursorUpdates;
int deferUpdateRequests;
......@@ -1394,7 +1394,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/VncViewer.java vnc_javasrc/VncView
// Reference to this applet for inter-applet communication.
public static java.applet.Applet refApplet;
@@ -626,6 +634,51 @@
@@ -626,6 +634,53 @@
// SocketFactory.
socketFactory = readParameter("SocketFactory", false);
......@@ -1430,8 +1430,10 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/VncViewer.java vnc_javasrc/VncView
+ if (urlPrefix.indexOf("/") != 0) {
+ urlPrefix = "/" + urlPrefix;
+ }
+ } else {
+ urlPrefix = "";
+ }
+ System.out.println("urlPrefix: " + urlPrefix);
+ System.out.println("urlPrefix: '" + urlPrefix + "'");
+
+ forceProxy = false;
+ str = readParameter("forceProxy", false);
......
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.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -35,6 +35,7 @@ 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);
......@@ -542,6 +543,18 @@ void unset_signals(void) {
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) {
/*
......
......@@ -21,6 +21,7 @@ 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 */
......@@ -517,6 +517,8 @@ int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
rfbLog("running command:\n");
rfbLog(" %s\n", cmd);
close_exec_fds();
if (output != NULL) {
FILE *ph = popen(cmd, "r");
char line[1024];
......@@ -587,7 +589,6 @@ int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
}
}
#else
/* this will still have port 5900 open */
rc = system(cmd);
#endif
got_rc:
......
......@@ -456,6 +456,7 @@ if (0) fprintf(stderr, "run_gui: %s -- %d %d\n", gui_xdisplay, connect_to_x11vnc
strcat(cmd, icon_mode_embed_id);
}
}
close_exec_fds();
pipe = popen(cmd, "w");
if (! pipe) {
fprintf(stderr, "could not run: %s\n", cmd);
......
......@@ -685,17 +685,27 @@ void print_help(int mode) {
"\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. A more interesting case is like this:\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>. Any remaining\n"
" output is taken as XAUTHORITY data. It can be either\n"
" of the form XAUTHORITY=<file> or raw xauthority data for\n"
" the display (e.g. \"xauth extract - $DISPLAY\" 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 (e.g. \"xauth extract -\n"
" $DISPLAY\" output).\n"
"\n"
#ifndef NO_SSL_OR_UNIXPW
" In the case of -unixpw (but not -unixpw_nis), then the\n"
......@@ -749,6 +759,7 @@ void print_help(int mode) {
" 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"
" To have this default script printed to stdout (e.g. for\n"
" customization) run with WAIT:cmd=FINDDISPLAY-print\n"
"\n"
......@@ -765,10 +776,46 @@ void print_help(int mode) {
" Where /.../x11vnc is the full path to x11vnc.\n"
" It is used in the Apache SSL-portal example (see FAQ).\n"
"\n"
" Finally, one can insert a geometry between colons,\n"
" e.g. WAIT:1280x1024:... to set the size of the display\n"
" the VNC client first attaches to since some VNC viewers\n"
" will not automatically adjust to a new framebuffer size.\n"
" An experimental 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"
" 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"
" source code (x11vnc/misc/Xdummy) It should be available\n"
" in PATH and have run \"Xdummy -install\" once to create\n"
" the shared library. Xdummy requires root permission\n"
" and only works on Linux. Xvfb is available on most\n"
" platforms.\n"
"\n"
" When x11vnc exits (i.e. user disconnects) the X server\n"
" session stays running in the background. Presumably the\n"
" FINDDISPLAY will find it next time. The user must exit\n"
" the X session in the usual way for it to terminate.\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"
" 5915 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"
" 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 \"X\"\n"
" means try to start up a real, hardware X server using\n"
" xinit(1). If there is already an X server running the\n"
" X case may only work on Linux (see startx(1)).\n"
"\n"
#ifndef NO_SSL_OR_UNIXPW
"-ssl [pem] Use the openssl library (www.openssl.org) to provide a\n"
......@@ -2524,35 +2571,37 @@ void print_help(int mode) {
" Default: %d\n"
"-debug_tiles Print debugging output for tiles, fb updates, etc.\n"
"\n"
"-snapfb Instead of polling the X display framebuffer (fb) for\n"
" changes, periodically copy all of X display fb into main\n"
" memory and examine that copy for changes. Under some\n"
" circumstances this will improve interactive response,\n"
" or at least make things look smoother, but in others\n"
" (most!) it will make the response worse. If the video\n"
" h/w fb is such that reading small tiles is very slow\n"
" this mode could help. To keep the \"framerate\" up\n"
" the screen size x bpp cannot be too large. Note that\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"
" or where window tearing is a problem.\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 shared memory segments string is of the\n"
" form: \"shm:N@WxHxB\" which specifies a shmid\n"
" N and framebuffer Width, Height, and Bits\n"
" per pixel.\n"
"\n"
" For file polling to memory map mmap(2) a file use:\n"
" \"map:/path/to/a/file@WxHxB\", with WxHxB as above.\n"
" \"mmap:...\" is the same. If there is trouble with mmap,\n"
" use \"file:/...\" for slower lseek(2) based reading.\n"
" Use \"snap:...\" to imply -snapfb mode and the \"file:\"\n"
" access (this is for devices that only provide the fb\n"
" all at once).\n"
" \"map:/path/to/a/file@WxHxB\", with framebuffer Width,\n"
" Height, and Bits per pixel. \"mmap:...\" is the\n"
" same.\n"
"\n"
" If there is trouble with mmap, use \"file:/...\"\n"
" for slower lseek(2) based reading. Use \"snap:...\"\n"
" to imply -snapfb mode and the \"file:\" access (this\n"
" is for devices that only provide the fb all at once).\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"
......@@ -2579,7 +2628,7 @@ void print_help(int mode) {
" guesses them based on the bpp.\n"
"\n"
" Another optional suffix is the Bytes Per Line which in\n"
" some cases is not WxHxB/4. Specify it as WxHxB-BPL\n"
" some cases is not WxB/4. 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"
......@@ -2612,11 +2661,11 @@ void print_help(int mode) {
" display, this usage should be very rare, i.e. doing\n"
" something strange with /dev/fb0.\n"
"\n"
" If the device is not \"seekable\" try reading it all\n"
" at once in full snaps via the \"snap:\" mode (note:\n"
" this is a resource hog). If you are using file: or\n"
" map: and the device needs to be reopened for *every*\n"
" snapfb snapshot, set the environment variable:\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"
......
EXTRA_DIST=README blockdpy.c dtVncPopup rx11vnc rx11vnc.pl shm_clear ranfb.pl slide.pl vcinject.pl x11vnc_loop
EXTRA_DIST=README blockdpy.c dtVncPopup rx11vnc rx11vnc.pl shm_clear ranfb.pl slide.pl vcinject.pl x11vnc_loop Xdummy
......@@ -997,6 +997,7 @@ if (0) fprintf(stderr, "initialize_pipeinput: %s -- %s\n", pipeinput_str, p);
clean_up_exit(1);
}
rfbLog("pipeinput: starting: \"%s\"...\n", p);
close_exec_fds();
pipeinput_fh = popen(p, "w");
if (! pipeinput_fh) {
......
......@@ -40,6 +40,7 @@ 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);
static void debug_colormap(XImage *fb);
......@@ -51,7 +52,6 @@ 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 announce(int lport, int ssl, char *iface);
static void setup_scaling(int *width_in, int *height_in);
int rawfb_reset = -1;
......@@ -920,6 +920,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\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);
......@@ -2497,7 +2498,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
install_passwds();
}
static void announce(int lport, int ssl, char *iface) {
void announce(int lport, int ssl, char *iface) {
char *host = this_host();
char *tvdt;
......
......@@ -21,6 +21,7 @@ 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 int rawfb_reset;
extern int rawfb_dev_video;
......
......@@ -68,6 +68,7 @@ static int dt_cmd(char *cmd) {
rfbLog("running command:\n %s\n", cmd);
usr_bin_path(0);
close_exec_fds();
rc = system(cmd);
usr_bin_path(1);
......@@ -96,6 +97,7 @@ static char *cmd_output(char *cmd) {
rfbLog("running pipe:\n %s\n", cmd);
usr_bin_path(0);
close_exec_fds();
p = popen(cmd, "r");
usr_bin_path(1);
......
......@@ -901,6 +901,7 @@ void openssl_port(void) {
clean_up_exit(1);
}
rfbLog("openssl_port: listen on port/sock %d/%d\n", port, sock);
announce(port, 1, NULL);
openssl_sock = sock;
openssl_port_num = port;
......
......@@ -688,6 +688,24 @@ char find_display[] =
"# x11vnc then uses the info to open the display.\n"
"#\n"
"\n"
"FIND_DISPLAY_OUTPUT=/tmp/fdo.txt\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"
" 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"
" set -xv\n"
"fi\n"
"\n"
"#env; set -xv\n"
"PATH=$PATH:/bin:/usr/bin:/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/ucb\n"
"export PATH\n"
......@@ -743,9 +761,23 @@ char find_display[] =
" fi\n"
" # loop over xauth list items machine ^hostname/unix:N\n"
" host=`hostname | sed -e 's/\\..*$//'`\n"
" tries1=\"\"\n"
" tries2=\"\"\n"
" for d in `xauth list | awk '{print $1}' | grep /unix \\\n"
" | grep \"^${host}\" | sed -e 's/^.*://' | sort -n | uniq`\n"
" do\n"
" if [ -e \"/tmp/.X$d-lock\" -o -e \"/tmp/.X11-unix/X$d\" ]; then\n"
" tries1=\"$tries1 $d\"\n"
" else\n"
" # these are often ssh X redirs so try them last or skip:\n"
" #tries2=\"$tries2 $d\"\n"
" :\n"
" fi\n"
" done\n"
" \n"
"\n"
" for d in $tries1 $tries2\n"
" do\n"
" xdpyinfo -display \":$d\" >/dev/null 2>&1\n"
" if [ $? = 0 ]; then\n"
" # try again with no authority:\n"
......@@ -766,12 +798,339 @@ char find_display[] =
" fi\n"
"fi\n"
"\n"
"echo \"DISPLAY=$display\"\n"
"chvt=\"\"\n"
"if [ \"X`uname`\" = \"XLinux\" ]; then\n"
" vt=`ps wwwwwaux | grep X | egrep -v 'startx|xinit' | grep \" $display \" | egrep ' vt([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -1`\n"
" if [ \"X$vt\" != \"X\" ]; then\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"
" chvt=\",VT=$vt\"\n"
" fi\n"
" else\n"
" vt=`ps wwwwwaux | grep X | grep \" $display \" | egrep ' tty([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -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"
" chvt=\",VT=$vt\"\n"
" fi\n"
" fi\n"
" fi\n"
"fi\n"
"\n"
"echo \"DISPLAY=$display$chvt\"\n"
"if [ \"X$showxauth\" != \"X\" ]; then\n"
" xauth extract - \"$display\" 2>/dev/null\n"
"fi\n"
"\n"
"\n"
"exit 0\n"
;
char create_display[] =
"#!/bin/sh\n"
"\n"
"CREATE_DISPLAY_OUTPUT=/tmp/cdo.txt\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"
"\n"
"if [ \"X$CREATE_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
" set -xv\n"
"fi\n"
"\n"
"findfree() {\n"
" try=20\n"
" n=\"\"\n"
" while [ $try -lt 99 ]\n"
" do\n"
" if [ ! -e \"/tmp/.X${try}-lock\" ]; then\n"
" n=$try\n"
" break\n"
" fi\n"
" try=`expr $try + 1`\n"
" done\n"
" echo \"$n\"\n"
"}\n"
"\n"
"findsession() {\n"
" if [ \"X$session\" != \"X\" ]; then\n"
" echo \"$session\"\n"
" return\n"
" fi\n"
" home=`csh -f -c \"echo ~$USER\"`\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/.xsession\" ]; then\n"
" echo \"$home/.xsession\"\n"
" return\n"
" elif [ -f \"$home/.xinitrc\" ]; then\n"
" echo \"$home/.xinitrc\"\n"
" return\n"
" fi\n"
" if [ -f \"$home/.dmrc\" ]; then\n"
" if [ \"X$have_startkde\" != \"X\" ]; then\n"
" if egrep -i 'Session=(default|kde)' \"$home/.dmrc\" > /dev/null; then\n"
" echo \"$have_startkde\"\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 windowmaker metacity\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"
" fi\n"
" if [ \"X$have_xterm\" != \"X\" ]; then\n"
" echo $have_xterm\n"
" return\n"
" else\n"
" echo \".xinitrc\"\n"
" fi\n"
"}\n"
"\n"
"server() {\n"
" authfile=`auth`\n"
" sess=`findsession`\n"
" DISPLAY=:$N\n"
" export DISPLAY\n"
" stmp=\"\"\n"
" if [ \"X$have_root\" != \"X\" -a \"X$USER\" != \"Xroot\" ]; then\n"
" sess=\"env DISPLAY=:$N $sess\"\n"
" fi\n"
" if echo \"$sess\" | grep '[ ]' > /dev/null; then\n"
" stmp=/tmp/.cd$$\n"
" rm -f $stmp\n"
" touch $stmp\n"
" chmod 755 $stmp\n"
" echo \"#!/bin/sh\" > $stmp\n"
" echo \"$sess\" >> $stmp\n"
" echo \"sleep 1\" >> $stmp\n"
" echo \"rm -f $stmp\" >> $stmp\n"
" sess=$stmp\n"
" fi\n"
" if [ \"X$have_root\" != \"X\" -a \"X$USER\" != \"Xroot\" ]; then\n"
" ctmp=\"/tmp/.xa.$$\"\n"
" touch $ctmp\n"
" chmod 644 $ctmp\n"
" $have_xauth -f $authfile nextract - :$N > $ctmp\n"
" su - $USER -c \"$have_xauth nmerge - < $ctmp\" 1>&2\n"
" $have_xauth -f $authfile nextract - `hostname`:$N > $ctmp\n"
" su - $USER -c \"$have_xauth nmerge - < $ctmp\" 1>&2\n"
" rm -f $ctmp\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"
" if [ \"X$have_startx\" != \"X\" ]; then\n"
" echo \"$have_startx $sess -- $* -auth $authfile\" 1>&2\n"
" $have_startx $sess -- $* -auth $authfile 1>&2 &\n"
" pid=$!\n"
" elif [ \"X$have_xinit\" != \"X\" ]; then\n"
" echo \"$have_xinit $sess -- $* -auth $authfile\" 1>&2\n"
" $have_xinit $sess -- $* -auth $authfile 1>&2 &\n"
" pid=$!\n"
" else\n"
" echo \"$*\"\n"
" nohup $* 1>&2 &\n"
" pid=$!\n"
" nohup $sess 1>&2 &\n"
" fi\n"
" sleep 4\n"
" if kill -0 $pid; then\n"
" result=1\n"
" else\n"
" result=0\n"
" fi\n"
" #(sleep 120; rm -f $authfile) &\n"
"}\n"
"\n"
"try_X() {\n"
" if [ \"X$have_xinit\" != \"X\" ]; then\n"
" save_have_startx=$have_startx\n"
" have_startx=\"\"\n"
" server :$N\n"
" have_startx=$save_have_startx\n"
" fi\n"
"}\n"
"\n"
"try_Xdummy() {\n"
" if [ \"X$have_Xdummy\" = \"X\" ]; then\n"
" return\n"
" fi\n"
" if [ \"X$have_root\" = \"X\" ]; then\n"
" return\n"
" fi\n"
"\n"
" #save_have_startx=$have_startx\n"
" #have_startx=\"\"\n"
" server $have_Xdummy :$N -geom $geom -depth $depth\n"
" #have_startx=$save_have_startx\n"
"}\n"
"\n"
"try_Xvfb() {\n"
" if [ \"X$have_Xvfb\" = \"X\" ]; then\n"
" return\n"
" fi\n"
"\n"
" #save_have_startx=$have_startx\n"
" #have_startx=\"\"\n"
" server $have_Xvfb :$N -screen 0 ${geom}x${depth}\n"
" #have_startx=$save_have_startx\n"
"\n"
" if [ \"X$result\" = \"X1\" -a \"X$have_xmodmap\" != \"X\" ]; then\n"
" (\n"
" sleep 1; $have_xmodmap -display :$N -e \"keycode any = Shift_R\" \n"
" sleep 1; $have_xmodmap -display :$N -e \"add Shift = Shift_L Shift_R\" \n"
" sleep 1; $have_xmodmap -display :$N -e \"keycode any = Control_R\" \n"
" sleep 1; $have_xmodmap -display :$N -e \"add Control = Control_L Control_R\" \n"
" sleep 1; $have_xmodmap -display :$N -e \"keycode any = Alt_L\" \n"
" sleep 1; $have_xmodmap -display :$N -e \"keycode any = Alt_R\" \n"
" sleep 1; $have_xmodmap -display :$N -e \"keycode any = Meta_L\" \n"
" sleep 1; $have_xmodmap -display :$N -e \"clear Mod1\" \n"
" sleep 1; $have_xmodmap -display :$N -e \"add Mod1 = Alt_L Alt_R Meta_L\" \n"
" ) 1>&2 &\n"
" fi\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 [ -e /dev/urandom ]; then\n"
" cookie=`dd if=/dev/urandom count=32 2>/dev/null | md5sum | awk '{print $1}'`\n"
" elif [ -e /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"
" cookie=`(echo $RANDOM; date; uptime; ps -ealf 2>&1) | md5sum | awk '{print $1}'`\n"
" fi\n"
" elif [ \"X$have_xauth\" != \"X\" ]; then\n"
" cookie=`$have_xauth list | awk '{print $NF}' | tail -1`\n"
" fi\n"
" if [ \"X$cookie\" = \"X\" ]; then\n"
" # oh well..\n"
" cookie=$cookie`printf \"%08x\" \"$RANDOM$$\"`\n"
" cookie=$cookie`printf \"%08x\" \"$RANDOM$$\"`\n"
" cookie=$cookie`printf \"%08x\" \"$RANDOM$$\"`\n"
" cookie=$cookie`printf \"%08x\" \"$RANDOM$$\"`\n"
" fi\n"
" echo \"$cookie\"\n"
"}\n"
"\n"
"auth() {\n"
" if [ \"X$have_xauth\" = \"X\" ]; then\n"
" exit 1\n"
" fi\n"
" tmp=\"/tmp/.xauth$$$RANDOM\"\n"
" rm -f $tmp\n"
" touch $tmp\n"
" chmod 600 $tmp\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"
" echo \"$tmp\"\n"
"}\n"
"\n"
"\n"
"depth=${depth:-16}\n"
"geom=${geom:-1280x1024}\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$USER\" = \"X\" ]; then\n"
" USER=$LOGNAME\n"
"fi\n"
"if [ \"X$USER\" = \"X\" ]; then\n"
" USER=`whoami`\n"
"fi\n"
"\n"
"PATH=$PATH:/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/dt/bin:/opt/kde3/bin:/opt/gnome/bin:/usr/bin:/bin\n"
"\n"
"have_root=\"\"\n"
"id0=`id`\n"
"if id | grep -w root > /dev/null; then\n"
" have_root=\"1\"\n"
"fi\n"
"\n"
"for prog in startx xinit xdm gdm kdm xterm Xdummy Xvfb xauth mcookie md5sum xmodmap startkde gnome-session blackbox fvwm mwm openbox twm windowmaker metacity\n"
"do\n"
" p2=`echo \"$prog\" | sed -e 's/-/_/g'`\n"
" eval \"have_$p2=''\"\n"
" if type $prog > /dev/null 2>&1; then\n"
" eval \"have_$p2=`which $prog`\"\n"
" fi\n"
"done\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=Xdummy,Xvfb\n"
"fi\n"
"\n"
"for curr_try in `echo \"$TRY\" | tr ',' ' '`\n"
"do\n"
" result=0\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"
" try_Xvfb\n"
" elif echo \"$curr_try\" | grep -iw \"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"
" exit 0\n"
" fi\n"
"done\n"
"\n"
"exit 1\n"
;
#endif /* _SSLTOOLS_H */
......@@ -1221,6 +1221,7 @@ void user_supplied_opts(char *opts) {
}
extern char find_display[];
extern char create_display[];
static XImage ximage_struct;
int wait_for_client(int *argc, char** argv, int http) {
......@@ -1231,6 +1232,9 @@ int wait_for_client(int *argc, char** argv, int http) {
int db = 0;
char tmp[] = "/tmp/x11vnc-find_display.XXXXXX";
int tmp_fd = -1, dt = 0;
char *create_cmd = NULL;
char *users_list_save = NULL;
int created_disp = 0;
if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) {
return 0;
......@@ -1285,6 +1289,10 @@ int wait_for_client(int *argc, char** argv, int http) {
fprintf(stdout, "%s", find_display);
clean_up_exit(0);
}
if (!strcmp(str, "FINDCREATEDISPLAY-print")) {
fprintf(stdout, "%s", create_display);
clean_up_exit(0);
}
if (db) fprintf(stderr, "cmd: %s\n", cmd);
}
......@@ -1394,6 +1402,12 @@ int wait_for_client(int *argc, char** argv, int http) {
rfbLog("taking unixpw_client off hold.\n");
unixpw_client->onHold = FALSE;
}
if (cmd && strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
if (users_list && strstr(users_list, "unixpw=") == users_list) {
users_list_save = users_list;
users_list = NULL;
}
}
while (1) {
if (shut_down) {
clean_up_exit(0);
......@@ -1421,7 +1435,8 @@ int wait_for_client(int *argc, char** argv, int http) {
memset(line1, 0, 1024);
memset(line2, 0, 16384);
if (!strcmp(cmd, "FINDDISPLAY")) {
if (!strcmp(cmd, "FINDDISPLAY") ||
strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
tmp_fd = mkstemp(tmp);
if (tmp_fd < 0) {
rfbLog("wait_for_client: open failed: %s\n", tmp);
......@@ -1431,6 +1446,28 @@ int wait_for_client(int *argc, char** argv, int http) {
write(tmp_fd, find_display, strlen(find_display));
close(tmp_fd);
chmod(tmp, 0644);
if (strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
char *opts = strchr(cmd, '-');
char st[] = "";
if (opts) {
opts++;
} else {
opts = st;
}
if (unixpw && keep_unixpw_user) {
create_cmd = (char *) malloc(strlen(tmp)
+ strlen("env USER='' /bin/sh ")
+ strlen(keep_unixpw_user) + 1 + strlen(opts) + 1);
sprintf(create_cmd, "env USER='%s' /bin/sh %s %s",
keep_unixpw_user, 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);
}
if (db) fprintf(stderr, "create_cmd: %s\n", create_cmd);
}
cmd = (char *) malloc(strlen(tmp) + strlen("/bin/sh ") + 1);
sprintf(cmd, "/bin/sh %s", tmp);
}
......@@ -1447,17 +1484,58 @@ int wait_for_client(int *argc, char** argv, int http) {
n = 18000;
res = su_verify(keep_unixpw_user,
keep_unixpw_pass, cmd, line, &n);
strzero(keep_unixpw_user);
strzero(keep_unixpw_pass);
}
keep_unixpw = 0;
if (db) write(2, line, n); write(2, "\n", 1);
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);
if (getuid() != 0) {
/* if not root, run as the other user... */
n = 18000;
res = su_verify(keep_unixpw_user,
keep_unixpw_pass, create_cmd, line, &n);
/*if (1) fprintf(stderr, "line: '%s'\n", line); */
} else {
FILE *p;
close_exec_fds();
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 (tmp_fd >= 0) {
unlink(tmp);
}
if (db) write(2, line, n); write(2, "\n", 1);
if (! res) {
rfbLog("wait_for_client: cmd failed: %s\n", cmd);
unixpw_msg("No DISPLAY found.", 3);
......@@ -1490,18 +1568,23 @@ if (db) write(2, line, n); write(2, "\n", 1);
continue;
}
}
line2[i] = q[k+j];
i++;
}
write(2, line, 100);
fprintf(stderr, "\n");
} else {
FILE *p = popen(cmd, "r");
FILE *p;
int rc;
close_exec_fds();
p = popen(cmd, "r");
if (! p) {
rfbLog("wait_for_client: cmd failed: %s\n", cmd);
rfbLogPerror("popen");
if (tmp_fd >= 0) {
unlink(tmp);
}
unixpw_msg("No DISPLAY found.", 3);
clean_up_exit(1);
}
if (fgets(line1, 1024, p) == NULL) {
......@@ -1510,22 +1593,71 @@ if (db) write(2, line, n); write(2, "\n", 1);
if (tmp_fd >= 0) {
unlink(tmp);
}
unixpw_msg("No DISPLAY found.", 3);
clean_up_exit(1);
}
n = fread(line2, 1, 16384, p);
pclose(p);
rc = pclose(p);
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);
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);
}
if (tmp_fd >= 0) {
unlink(tmp);
}
}
if (strstr(line1, "DISPLAY=") != line1) {
rfbLog("wait_for_client: bad reply %s\n", line1);
rfbLog("wait_for_client: bad reply '%s'\n", line1);
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 <= 128) {
char chvt[100];
sprintf(chvt, "chvt %d >/dev/null 2>/dev/null &", vt);
rfbLog("running: %s\n", chvt);
system(chvt);
sleep(2);
}
}
use_dpy = strdup(line1 + strlen("DISPLAY="));
q = use_dpy;
while (*q != '\0') {
......@@ -1551,9 +1683,53 @@ if (db) write(2, line, n); write(2, "\n", 1);
if (db) fprintf(stderr, "xauth_raw_len: %d\n", n);
}
}
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\n", user);
} else if (switch_user(u, 0)) {
rfbLog("unixpw_accept switched to user: %s\n", user);
} else {
rfbLog("unixpw_accept failed to switched to user: %s\n", user);
}
free(u);
}
if (unixpw) {
char str[32];
snprintf(str, 30, "Using DISPLAY %s", use_dpy);
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);
}
} else {
......@@ -1565,6 +1741,9 @@ if (db) fprintf(stderr, "xauth_raw_len: %d\n", n);
if (unixpw && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
user_supplied_opts(keep_unixpw_opts);
}
if (create_cmd) {
free(create_cmd);
}
return 1;
}
......
......@@ -1126,6 +1126,7 @@ static char *guess_via_v4l_info(char *dev, int *fd) {
sprintf(cmd, "v4l-info '%s' > %s", dev, tmp);
close(tmp_fd);
close_exec_fds();
rc = system(cmd);
if (rc != 0) {
unlink(tmp);
......
......@@ -378,6 +378,7 @@ int pick_windowid(unsigned long *num) {
rfbLog(" exiting.\n");
clean_up_exit(1);
}
close_exec_fds();
p = popen("xwininfo", "r");
if (! p) {
......
.\" This file was automatically generated from x11vnc -help output.
.TH X11VNC "1" "November 2006" "x11vnc " "User Commands"
.TH X11VNC "1" "December 2006" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.8.4, lastmod: 2006-11-23
version: 0.8.4, lastmod: 2006-12-09
.SH SYNOPSIS
.B x11vnc
[OPTION]...
......@@ -814,17 +814,29 @@ 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. A more interesting case is like this:
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>. Any remaining
output is taken as XAUTHORITY data. It can be either
of the form XAUTHORITY=<file> or raw xauthority data for
the display (e.g. "xauth extract - $DISPLAY" 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 (e.g. "xauth extract -
$DISPLAY" output).
.IP
In the case of \fB-unixpw\fR (but not \fB-unixpw_nis),\fR then the
above command is run as the user who just authenticated
......@@ -879,6 +891,7 @@ script that works on most Unixes to determine a user's
DISPLAY variable and xauthority data (see
.IR who (1)
).
.IP
To have this default script printed to stdout (e.g. for
customization) run with WAIT:cmd=FINDDISPLAY-print
.IP
......@@ -895,10 +908,51 @@ by client web browsers. For example:
Where /.../x11vnc is the full path to x11vnc.
It is used in the Apache SSL-portal example (see FAQ).
.IP
Finally, one can 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.
An experimental 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
start up an X server.
.IP
By default FINDCREATEDISPLAY will try Xdummy and
then Xvfb. 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 requires root permission
and only works on Linux. Xvfb is available on most
platforms.
.IP
When x11vnc exits (i.e. user disconnects) the X server
session stays running in the background. Presumably the
FINDDISPLAY will find it next time. The user must exit
the X session in the usual way for it to terminate.
.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
5915 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
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
.IR xinit (1).
If there is already an X server running the
X case may only work on Linux (see
.IR startx (1)
).
.PP
\fB-ssl\fR \fI[pem]\fR
.IP
......@@ -2992,41 +3046,46 @@ 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. 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
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,
or where window tearing is a problem.
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 shared memory segments string is of the
form: "shm:N@WxHxB" which specifies a shmid
N and framebuffer Width, Height, and Bits
per pixel.
.IP
For file polling to memory map
.IR mmap (2)
a file use:
"map:/path/to/a/file@WxHxB", with WxHxB as above.
"mmap:..." is the same. If there is trouble with mmap,
use "file:/..." for slower
"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.
Use "snap:..." to imply \fB-snapfb\fR mode and the "file:"
access (this is for devices that only provide the fb
all at once).
based reading. Use "snap:..."
to imply \fB-snapfb\fR mode and the "file:" access (this
is for devices that only provide the fb all at once).
.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
......@@ -3053,7 +3112,7 @@ memory object. If the masks are not provided x11vnc
guesses them based on the bpp.
.IP
Another optional suffix is the Bytes Per Line which in
some cases is not WxHxB/4. Specify it as WxHxB-BPL
some cases is not WxB/4. 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
......@@ -3095,11 +3154,11 @@ 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" 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:
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
......
......@@ -1580,10 +1580,15 @@ int main(int argc, char* argv[]) {
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);
}
}
} else if (!strcmp(arg, "-auth") || !strcmp(arg, "-xauth")) {
CHECK_ARGC
......
......@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.4 lastmod: 2006-11-23";
char lastmod[] = "0.8.4 lastmod: 2006-12-09";
/* X display info */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment