From f6e8710729287837c6a7de87e52286f0bffdac27 Mon Sep 17 00:00:00 2001 From: dscho Date: Tue, 11 Nov 2003 13:25:37 +0000 Subject: [PATCH] -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 * 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();