From f6e8710729287837c6a7de87e52286f0bffdac27 Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Tue, 11 Nov 2003 13:25:37 +0000
Subject: -inetd, -noshm and friends added

---
 ChangeLog        |   3 ++
 contrib/x11vnc.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 119 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7b1ec59..d77720c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2003-11-07  Karl Runge
+	* support "-inetd", "-noshm", "-flipbyteorder" in x11vnc
+
 2003-10-26  Johannes E. Schindelin  <Johannes.Schindelin@gmx.de>
 	* released Version 0.6
 
diff --git a/contrib/x11vnc.c b/contrib/x11vnc.c
index 051bafd..abb85ef 100644
--- a/contrib/x11vnc.c
+++ b/contrib/x11vnc.c
@@ -166,6 +166,7 @@ hint_t *hint_list;
 
 int shared = 0;			/* share vnc display. */
 int view_only = 0;		/* clients can only watch. */
+int inetd = 0;			/* spawned from inetd(1) */
 int connect_once = 1;		/* disconnect after first connection session. */
 int flash_cmap = 0;		/* follow installed colormaps */
 
@@ -175,6 +176,8 @@ int local_cursor = 1;		/* whether the viewer draws a local cursor */
 int show_mouse = 0;		/* display a cursor for the real mouse */
 int show_root_cursor = 0;	/* show X when on root background */
 
+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.
@@ -337,8 +340,8 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
 				return(RFB_CLIENT_REFUSE);
 			}
 		}
-		client->clientGoneHook = client_gone;
 	}
+	client->clientGoneHook = client_gone;
 	if (view_only)  {
 		client->clientData = (void *) -1;
 	} else {
@@ -1107,6 +1110,20 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
 
 	screen->frameBuffer = fb->data; 
 
+	if (inetd) {
+		int fd = dup(0);
+		if (fd < 3) {
+			rfbErr("dup(0) = %d failed.\n", fd);
+			perror("dup");
+			exit(1);
+		}
+		fclose(stdin);
+		fclose(stdout);
+		/* we keep stderr for logging */
+		screen->inetdSock = fd;
+		screen->rfbPort = 0;
+	}
+
 	/* XXX the following 3 settings are based on libvncserver defaults. */
 	if (screen->rfbPort == 5900) {
 		screen->autoPort = TRUE;
@@ -1194,6 +1211,45 @@ void shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
 
 	X_LOCK;
 
+	if (! using_shm) {
+		/* we only need the XImage created */
+		xim = XCreateImage(dpy, visual, bpp, ZPixmap, 0, NULL, w, h,
+		    BitmapPad(dpy), 0);
+
+		X_UNLOCK;
+
+		if (xim == NULL) {
+			rfbErr("XCreateImage(%s) failed.\n", name);
+			exit(1);
+		}
+		xim->data = (char *) malloc(xim->bytes_per_line * xim->height);
+		if (xim->data == NULL) {
+			rfbErr("XCreateImage(%s) data malloc failed.\n", name);
+			exit(1);
+		}
+		if (flip_byte_order) {
+			static int reported = 0;
+			char *bo;
+			if (xim->byte_order == LSBFirst) {
+				bo = "MSBFirst";
+				xim->byte_order = MSBFirst;
+				xim->bitmap_bit_order = MSBFirst;
+			} else {
+				bo = "LSBFirst";
+				xim->byte_order = LSBFirst;
+				xim->bitmap_bit_order = LSBFirst;
+			}
+			if (! reported && ! quiet) {
+				fprintf(stderr, "changing XImage byte order"
+				    " to %s\n", bo);
+				reported = 1;
+			}
+		}
+
+		*ximg_ptr = xim;
+		return;
+	}
+
 	xim = XShmCreateImage(dpy, visual, bpp, ZPixmap, NULL, shm, w, h);
 
 	if (xim == NULL) {
@@ -1203,6 +1259,7 @@ void shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
 
 	*ximg_ptr = xim;
 
+
 	shm->shmid = shmget(IPC_PRIVATE,
 	    xim->bytes_per_line * xim->height, IPC_CREAT | 0777);
 
@@ -1231,11 +1288,17 @@ void shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
 }
 
 void shm_delete(XShmSegmentInfo *shm) {
+	if (! using_shm) {
+		return;
+	}
 	shmdt(shm->shmaddr);
 	shmctl(shm->shmid, IPC_RMID, 0);
 }
 
 void shm_clean(XShmSegmentInfo *shm, XImage *xim) {
+	if (! using_shm) {
+		return;
+	}
 	X_LOCK;
 	XShmDetach(dpy, shm);
 	XDestroyImage(xim);
@@ -1460,12 +1523,12 @@ void copy_tile(int tx, int ty) {
 	n = tx + ty * ntiles_x;		/* number of the tile */
 
 	X_LOCK;
-	if ( size_x == tile_x && size_y == tile_y ) {
+	if ( using_shm && size_x == tile_x && size_y == tile_y ) {
 		/* general case: */
 		XShmGetImage(dpy, window, tile, x, y, AllPlanes);
 	} else {
 		/*
-		 * near bottom or rhs edge case:
+		 * No shm or near bottom/rhs edge case:
 		 * (but only if tile size does not divide screen size)
 		 */
 		XGetSubImage(dpy, window, x, y, size_x, size_y, AllPlanes,
@@ -1832,7 +1895,7 @@ int grow_islands() {
 void copy_screen() {
 	int pixelsize = bpp >> 3;
 	char *rfb_fb;
-	int i, y, block_size, xi;
+	int i, y, block_size;
 
 	block_size = (dpy_x * (dpy_y/fs_factor) * pixelsize);
 
@@ -1842,7 +1905,13 @@ void copy_screen() {
 	X_LOCK;
 
 	for (i=0; i < fs_factor; i++) {
-		xi = XShmGetImage(dpy, window, fullscreen, 0, y, AllPlanes);
+		if (using_shm) {
+			XShmGetImage(dpy, window, fullscreen, 0, y, AllPlanes);
+		} else {
+			XGetSubImage(dpy, window, 0, y, fullscreen->width,
+			    fullscreen->height, AllPlanes, ZPixmap, fullscreen,
+			    0, 0);
+		}
 		memcpy(rfb_fb, fullscreen->data, (size_t) block_size);
 
 		y += dpy_y / fs_factor;
@@ -1963,7 +2032,13 @@ int scan_display(int ystart, int rescan) {
 
 		/* grab the horizontal scanline from the display: */
 		X_LOCK;
-		XShmGetImage(dpy, window, scanline, 0, y, AllPlanes);
+		if (using_shm) {
+			XShmGetImage(dpy, window, scanline, 0, y, AllPlanes);
+		} else {
+			XGetSubImage(dpy, window, 0, y, scanline->width,
+			    scanline->height, AllPlanes, ZPixmap, scanline,
+			    0, 0);
+		}
 		X_UNLOCK;
 
 		/* for better memory i/o try the whole line at once */
@@ -2215,6 +2290,12 @@ void print_help() {
 "-shared                VNC display is shared (default %s).\n"
 "-many                  keep listening for more connections rather than exiting\n"
 "                       as soon as the first clients disconnect.\n"
+"-inetd                 launched by inetd(1): stdio instead of listening socket.\n"
+"-noshm                 do not use the MIT-SHM extension for the polling.\n"
+"                       remote displays can be polled this way: be careful\n"
+"                       this can use large amounts of network bandwidth.\n"
+"-flipbyteorder         sometimes needed if remotely polled host has different\n"
+"                       endianness.  ignored unless -noshm is set.\n"
 "\n"
 "-q                     be quiet by printing less informational output.\n" 
 "-bg                    go into the background after screen setup.\n" 
@@ -2321,6 +2402,7 @@ int main(int argc, char** argv) {
 	char *use_dpy = NULL;
 	int dt = 0;
 	int bg = 0;
+	int got_waitms = 0;
 
 	/* used to pass args we do not know about to rfbGetScreen(): */
 	int argc2 = 1; char *argv2[100];
@@ -2346,6 +2428,12 @@ int main(int argc, char** argv) {
 			shared = 1;
 		} else if (!strcmp(argv[i], "-many")) {
 			connect_once = 0;
+		} else if (!strcmp(argv[i], "-inetd")) {
+			inetd = 1;
+		} else if (!strcmp(argv[i], "-noshm")) {
+			using_shm = 0;
+		} else if (!strcmp(argv[i], "-flipbyteorder")) {
+			flip_byte_order = 1;
 		} else if (!strcmp(argv[i], "-modtweak")) {
 			use_modifier_tweak = 1;
 		} else if (!strcmp(argv[i], "-nomodtweak")) {
@@ -2365,6 +2453,7 @@ int main(int argc, char** argv) {
 			defer_update = atoi(argv[++i]);
 		} else if (!strcmp(argv[i], "-wait")) {
 			waitms = atoi(argv[++i]);
+			got_waitms = 1;
 		} else if (!strcmp(argv[i], "-nap")) {
 			take_naps = 1;
 #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
@@ -2415,10 +2504,22 @@ int main(int argc, char** argv) {
 	if (waitms < 0) {
 		waitms = 0;
 	}
+	if (! using_shm && ! got_waitms) {
+		/* try to cut down on polling over network... */
+		waitms *= 2;
+	}
+	if (inetd) {
+		shared = 0;
+		connect_once = 1;
+		bg = 0;
+	}
 	if (! quiet) {
 		fprintf(stderr, "viewonly:   %d\n", view_only);
 		fprintf(stderr, "shared:     %d\n", shared);
+		fprintf(stderr, "inetd:      %d\n", inetd);
 		fprintf(stderr, "conn_once:  %d\n", connect_once);
+		fprintf(stderr, "using_shm:  %d\n", using_shm);
+		fprintf(stderr, "flipbyteo:  %d\n", flip_byte_order);
 		fprintf(stderr, "mod_tweak:  %d\n", use_modifier_tweak);
 		fprintf(stderr, "loc_curs:   %d\n", local_cursor);
 		fprintf(stderr, "mouse:      %d\n", show_mouse);
@@ -2460,9 +2561,14 @@ int main(int argc, char** argv) {
 		exit(1);
 	}
 	if (! XShmQueryExtension(dpy)) {
-		fprintf(stderr, "Display does not support XShm extension"
-		    " (must be local).\n");
-		exit(1);
+		if (! using_shm) {
+			fprintf(stderr, "warning: display does not support "
+			    "XShm.\n");
+		} else {
+			fprintf(stderr, "Display does not support XShm "
+			    "extension (must be local).\n");
+			exit(1);
+		}
 	}
 
 	/*
@@ -2527,7 +2633,7 @@ int main(int argc, char** argv) {
 
 	initialize_tiles();
 
-	initialize_shm();
+	initialize_shm();	/* also creates XImages when using_shm = 0 */
 
 	set_signals();
 
-- 
cgit v1.2.3

