x11vnc: -overlay to fix colors with Sun 8+24 overlay visuals. -sid option.

pull/1/head
runge 21 years ago
parent 6460243eaf
commit d77d118d99

@ -1,3 +1,7 @@
2004-08-15 Karl Runge <runge@karlrunge.com>
* x11vnc: -overlay to fix colors with Sun 8+24 overlay visuals.
* -sid option.
2004-08-03 Karl Runge <runge@karlrunge.com> 2004-08-03 Karl Runge <runge@karlrunge.com>
* x11vnc: manpage and README * x11vnc: manpage and README
* fix XKBlib.h detection on *BSD * fix XKBlib.h detection on *BSD

@ -1,3 +1,12 @@
2004-08-15 Karl Runge <runge@karlrunge.com>
* -overlay option to fix color problems on Sun machines with 8+24
and 24+8 overlay visuals, uses Solaris XReadScreen().
* expose -sid option (shifted -id windowid) to allow explicit
wrapping of XGetImage, etc for -overlay
* fix misc bugs: missing var types, hardwired blackouts sizes,
subwin desktop name crash.
2004-08-03 Karl Runge <runge@karlrunge.com> 2004-08-03 Karl Runge <runge@karlrunge.com>
* add man page x11vnc.1 autogenerated from x11vnc -help; tweak * add man page x11vnc.1 autogenerated from x11vnc -help; tweak
help output a little bit. Adjust autoconf to pick up manpage. help output a little bit. Adjust autoconf to pick up manpage.

File diff suppressed because it is too large Load Diff

@ -2,7 +2,7 @@
.TH X11VNC "1" "August 2004" "x11vnc " "User Commands" .TH X11VNC "1" "August 2004" "x11vnc " "User Commands"
.SH NAME .SH NAME
x11vnc - allow VNC connections to real X11 displays x11vnc - allow VNC connections to real X11 displays
version: 0.6.2, lastmod: 2004-07-31 version: 0.6.3pre, lastmod: 2004-08-15
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
@ -69,7 +69,9 @@ entire display. Warning: bugs! new toplevels missed!...
\fB-sid\fR \fIwindowid\fR \fB-sid\fR \fIwindowid\fR
.IP .IP
As \fB-id,\fR but instead of using the window directly it As \fB-id,\fR but instead of using the window directly it
shifts a root view to it: shows saveUnders menus, etc. shifts a root view to it: shows saveUnders menus, etc,
although they will be clipped if they extend beyond
the window.
.PP .PP
\fB-flashcmap\fR \fB-flashcmap\fR
.IP .IP
@ -78,7 +80,34 @@ as the pointer moves from window to window (slow).
.PP .PP
\fB-notruecolor\fR \fB-notruecolor\fR
.IP .IP
Force 8bpp indexed color even if it looks like TrueColor. For 8bpp displays, force indexed color (i.e. a colormap)
even if it looks like 8bpp TrueColor. (rare problem)
.PP
\fB-overlay\fR
.IP
Handle multiple depth visuals on one screen, e.g. 8+24
and 24+8 overlay visuals (the 32 bits per pixel are
packed with 8 for PseudoColor and 24 for TrueColor).
.IP
Currently \fB-overlay\fR only works on Solaris (it uses
XReadScreen(3X11)). There are still some problems with
surrounding-region painting for popup menus (but not
for the popup menu itself); a workaround is to disable
SaveUnders (pass \fB-su\fR to Xsun). Amusingly, if \fB-overlay\fR
is used with \fB-mouse,\fR the mouse cursor shape is correct.
.IP
Use \fB-overlay\fR as a workaround for situations like these:
Some legacy applications require the default visual
be 8bpp (8+24), or they will use 8bpp PseudoColor even
when the default visual is depth 24 TrueColor (24+8).
In these cases colors in some windows will be messed
up in x11vnc unless \fB-overlay\fR is used.
.IP
Under \fB-overlay,\fR performance will be somewhat degraded
due to the extra image transformations required.
For optimal performance do not use \fB-overlay,\fR but rather
configure the X server so that the default visual is
depth 24 TrueColor and have all apps use that visual.
.PP .PP
\fB-visual\fR \fIn\fR \fB-visual\fR \fIn\fR
.IP .IP
@ -100,7 +129,7 @@ less than 1 shrink the fb. Note: image may not be sharp
and response may be slower. If \fIfraction\fR contains and response may be slower. If \fIfraction\fR contains
a decimal point "." it is taken as a floating point a decimal point "." it is taken as a floating point
number, alternatively the notation "m/n" may be used number, alternatively the notation "m/n" may be used
to denote fractions, e.g. \fB-scale\fR 2/3. to denote fractions exactly, e.g. \fB-scale\fR 2/3.
.IP .IP
Scaling Options: can be added after \fIfraction\fR via Scaling Options: can be added after \fIfraction\fR via
":", to supply multiple ":" options use commas. ":", to supply multiple ":" options use commas.

@ -79,6 +79,7 @@
* -flashcmap option to have colormap flashing as the pointer moves * -flashcmap option to have colormap flashing as the pointer moves
* windows with private colormaps (slow). Displays with mixed depth 8 and * windows with private colormaps (slow). Displays with mixed depth 8 and
* 24 visuals will incorrectly display windows using the non-default one. * 24 visuals will incorrectly display windows using the non-default one.
* On Sun hardware we try to work around this with -overlay.
* *
* Feature -id <windowid> can be picky: it can crash for things like the * Feature -id <windowid> can be picky: it can crash for things like the
* window not sufficiently mapped into server memory, use of -mouse, etc. * window not sufficiently mapped into server memory, use of -mouse, etc.
@ -141,6 +142,11 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif
#if defined (__SVR4) && defined (__sun)
#define SOLARIS
#include <X11/extensions/transovl.h>
#endif
/* /*
* Temporary kludge: to run with -xinerama define the following * Temporary kludge: to run with -xinerama define the following
* macro (uncomment) and be sure to link with -lXinerama * macro (uncomment) and be sure to link with -lXinerama
@ -156,18 +162,19 @@
#endif #endif
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.6.3pre lastmod: 2004-08-03"; char lastmod[] = "0.6.3pre lastmod: 2004-08-15";
/* X display info */ /* X display info */
Display *dpy = 0;
Visual *visual; Display *dpy = 0; /* the single display screen we connect to */
Window window, rootwin;
int scr; int scr;
Window window, rootwin; /* polled window, root window (usu. same) */
Visual *default_visual; /* the default visual (unless -visual) */
int bpp, depth; int bpp, depth;
int button_mask = 0;
int dpy_x, dpy_y;
int off_x, off_y;
int indexed_colour = 0; int indexed_colour = 0;
int dpy_x, dpy_y; /* size of display */
int off_x, off_y; /* offsets for -sid */
int button_mask = 0; /* button state and info */
int num_buttons = -1; int num_buttons = -1;
/* image structures */ /* image structures */
@ -209,17 +216,19 @@ int ntiles, ntiles_x, ntiles_y;
/* arrays that indicate changed or checked tiles. */ /* arrays that indicate changed or checked tiles. */
unsigned char *tile_has_diff, *tile_tried; unsigned char *tile_has_diff, *tile_tried;
/* blacked-out region things */ /* blacked-out region (-blackout, -xinerama) */
typedef struct bout { typedef struct bout {
int x1, y1, x2, y2; int x1, y1, x2, y2;
} blackout_t; } blackout_t;
#define BO_MAX 16
typedef struct tbout { typedef struct tbout {
blackout_t bo[16]; /* hardwired max rectangles. */ blackout_t bo[BO_MAX]; /* hardwired max rectangles. */
int cover; int cover;
int count; int count;
} tile_blackout_t; } tile_blackout_t;
blackout_t blackr[100]; /* hardwired max blackouts */ #define BLACKR_MAX 100
blackout_t blackr[BLACKR_MAX]; /* hardwired max blackouts */
int blackouts = 0; int blackouts = 0;
tile_blackout_t *tile_blackout; tile_blackout_t *tile_blackout;
@ -245,6 +254,7 @@ int shut_down = 0;
char vnc_connect_str[VNC_CONNECT_MAX+1]; char vnc_connect_str[VNC_CONNECT_MAX+1];
Atom vnc_connect_prop = None; Atom vnc_connect_prop = None;
/* function prototypes (see filename comment above) */ /* function prototypes (see filename comment above) */
int all_clients_initialized(void); int all_clients_initialized(void);
@ -378,9 +388,11 @@ int watch_primary = 1; /* more dicey, poll for changes in PRIMARY */
int sigpipe = 1; /* 0=skip, 1=ignore, 2=exit */ int sigpipe = 1; /* 0=skip, 1=ignore, 2=exit */
/* for -visual override */ /* visual stuff for -visual override or -overlay */
VisualID visual_id = (VisualID) 0; VisualID visual_id = (VisualID) 0;
int visual_depth = 0; int visual_depth = 0;
int overlay = 0;
int overlay_mouse = 0;
/* tile heuristics: */ /* tile heuristics: */
double fs_frac = 0.75; /* threshold tile fraction to do fullscreen updates. */ double fs_frac = 0.75; /* threshold tile fraction to do fullscreen updates. */
@ -394,6 +406,7 @@ int debug_keyboard = 0;
int quiet = 0; int quiet = 0;
/* info about command line opts */
int got_rfbport = 0; int got_rfbport = 0;
int got_alwaysshared = 0; int got_alwaysshared = 0;
int got_nevershared = 0; int got_nevershared = 0;
@ -454,6 +467,102 @@ int nfix(int i, int n) {
return i; return i;
} }
/*
* Kludge to interpose image gets and limit to a subset rectangle of
* the rootwin. This is the -sid option trying to work around invisible
* saveUnders menu, etc, windows.
*/
int rootshift = 0;
#define ADJUST_ROOTSHIFT \
if (rootshift && subwin) { \
d = rootwin; \
x += off_x; \
y += off_y; \
}
/* Wrappers for Image related X calls */
Status XShmGetImage_wr(Display *disp, Drawable d, XImage *image, int x, int y,
unsigned long mask) {
ADJUST_ROOTSHIFT
/* The Solaris overlay stuff is all non-shm (using_shm = 0) */
return XShmGetImage(disp, d, image, x, y, mask);
}
XImage *XGetSubImage_wr(Display *disp, Drawable d, int x, int y,
unsigned int width, unsigned int height, unsigned long plane_mask,
int format, XImage *dest_image, int dest_x, int dest_y) {
ADJUST_ROOTSHIFT
#ifdef SOLARIS
if (overlay && dest_x == 0 && dest_y == 0) {
size_t size = dest_image->height * dest_image->bytes_per_line;
XImage *xi = XReadScreen(disp, d, x, y, width, height,
(Bool) overlay_mouse);
/*
* There is extra overhead from memcpy and free...
* this is not like the real XGetSubImage(). We hope
* this significant overhead is still small compared to
* the time to retrieve the fb data.
*/
memcpy(dest_image->data, xi->data, size);
XDestroyImage(xi);
return (dest_image);
}
#endif
return XGetSubImage(disp, d, x, y, width, height, plane_mask,
format, dest_image, dest_x, dest_y);
}
XImage *XGetImage_wr(Display *disp, Drawable d, int x, int y,
unsigned int width, unsigned int height, unsigned long plane_mask,
int format) {
ADJUST_ROOTSHIFT
#ifdef SOLARIS
if (overlay) {
return XReadScreen(disp, d, x, y, width, height,
(Bool) overlay_mouse);
}
#endif
return XGetImage(disp, d, x, y, width, height, plane_mask, format);
}
XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth,
int format, int offset, char *data, unsigned int width,
unsigned int height, int bitmap_pad, int bytes_per_line) {
/*
* This is a kludge to get a created XImage to exactly match what
* XReadScreen returns: we noticed the rgb masks are different from
* XCreateImage with the high color visual (red mask <-> blue mask).
* Note we read from the root window(!) then free the data.
*/
#ifdef SOLARIS
if (overlay) {
XImage *xi;
xi = XReadScreen(disp, window, 0, 0, width, height, False);
if (xi == NULL) {
return xi;
}
if (xi->data != NULL) {
free(xi->data);
}
xi->data = data;
return xi;
}
#endif
return XCreateImage(disp, visual, depth, format, offset, data,
width, height, bitmap_pad, bytes_per_line);
}
/* -- cleanup.c -- */ /* -- cleanup.c -- */
/* /*
@ -4329,7 +4438,7 @@ static int tree_descend_cursor(void) {
/* /*
* This is for mouse patch drawing under -xinerama or -blackout * This is for mouse patch drawing under -xinerama or -blackout
*/ */
static void blackout_nearby_tiles(x, y, dt) { static void blackout_nearby_tiles(int x, int y, int dt) {
int sx, sy, n, b; int sx, sy, n, b;
int tx = x/tile_x; int tx = x/tile_x;
int ty = y/tile_y; int ty = y/tile_y;
@ -4676,7 +4785,7 @@ void set_colormap(void) {
cmap = DefaultColormap(dpy, scr); cmap = DefaultColormap(dpy, scr);
ncells = CellsOfScreen(ScreenOfDisplay(dpy, scr)); ncells = CellsOfScreen(ScreenOfDisplay(dpy, scr));
vis = visual; vis = default_visual;
if (subwin) { if (subwin) {
XWindowAttributes attr; XWindowAttributes attr;
@ -4727,7 +4836,7 @@ void set_colormap(void) {
/* /*
* Kludge to make 8bpp TrueColor & DirectColor be like * Kludge to make 8bpp TrueColor & DirectColor be like
* the StaticColor map. The ncells = 8 is "8 per subfield" * the StaticColor map. The ncells = 8 is "8 per subfield"
* mentioned in xdpyinfo. Looks OK... likely fortuitously. * mentioned in xdpyinfo. Looks OK... perhaps fortuitously.
*/ */
if (ncells == 8) { if (ncells == 8) {
ncells = NCOLOR; ncells = NCOLOR;
@ -4768,25 +4877,31 @@ void set_colormap(void) {
/* /*
* Experimental mode to force the visual of the window instead of querying * Experimental mode to force the visual of the window instead of querying
* it. Currently just used for testing or overriding some rare cases. * it. Used for testing, overriding some rare cases (win2vnc), and for
* Input string can be a decimal or 0x hex or something like TrueColor * -overlay . Input string can be a decimal or 0x hex or something like
* or TrueColor:24 to force a depth as well. * TrueColor or TrueColor:24 to force a depth as well.
*
* visual_id and possibly visual_depth are set.
*/ */
void set_visual(char *vstring) { void set_visual(char *str) {
int vis, defdepth = DefaultDepth(dpy, scr); int vis, vdepth, defdepth = DefaultDepth(dpy, scr);
XVisualInfo vinfo; XVisualInfo vinfo;
char *p; char *p, *vstring = strdup(str);
if (! quiet) { if (! quiet) {
fprintf(stderr, "set_visual: %s\n", vstring); fprintf(stderr, "set_visual: %s\n", vstring);
} }
/* set visual depth */
if ((p = strchr(vstring, ':')) != NULL) { if ((p = strchr(vstring, ':')) != NULL) {
visual_depth = atoi(p+1); visual_depth = atoi(p+1);
*p = '\0'; *p = '\0';
vdepth = visual_depth;
} else { } else {
visual_depth = defdepth; vdepth = defdepth;
} }
/* set visual id number */
if (strcmp(vstring, "StaticGray") == 0) { if (strcmp(vstring, "StaticGray") == 0) {
vis = StaticGray; vis = StaticGray;
} else if (strcmp(vstring, "GrayScale") == 0) { } else if (strcmp(vstring, "GrayScale") == 0) {
@ -4810,8 +4925,10 @@ void set_visual(char *vstring) {
exit(1); exit(1);
} }
visual_id = (VisualID) v_in; visual_id = (VisualID) v_in;
free(vstring);
return; return;
} }
if (XMatchVisualInfo(dpy, scr, visual_depth, vis, &vinfo)) { if (XMatchVisualInfo(dpy, scr, visual_depth, vis, &vinfo)) {
; ;
} else if (XMatchVisualInfo(dpy, scr, defdepth, vis, &vinfo)) { } else if (XMatchVisualInfo(dpy, scr, defdepth, vis, &vinfo)) {
@ -4820,6 +4937,9 @@ void set_visual(char *vstring) {
fprintf(stderr, "could not find visual: %s\n", vstring); fprintf(stderr, "could not find visual: %s\n", vstring);
exit(1); exit(1);
} }
free(vstring);
/* set numerical visual id. */
visual_id = vinfo.visualid; visual_id = vinfo.visualid;
} }
@ -4837,7 +4957,7 @@ void nofb_hook(rfbClientPtr cl) {
return; return;
} }
rfbLog("framebuffer requested in -nofb mode by client %s\n", cl->host); rfbLog("framebuffer requested in -nofb mode by client %s\n", cl->host);
fb = XGetImage(dpy, window, 0, 0, dpy_x, dpy_y, AllPlanes, ZPixmap); fb = XGetImage_wr(dpy, window, 0, 0, dpy_x, dpy_y, AllPlanes, ZPixmap);
main_fb = fb->data; main_fb = fb->data;
rfb_fb = main_fb; rfb_fb = main_fb;
screen->frameBuffer = rfb_fb; screen->frameBuffer = rfb_fb;
@ -5147,7 +5267,7 @@ void initialize_blackout (char *list) {
blackr[blackouts].x2 = X; blackr[blackouts].x2 = X;
blackr[blackouts].y2 = Y; blackr[blackouts].y2 = Y;
blackouts++; blackouts++;
if (blackouts >= 100) { if (blackouts >= BLACKR_MAX) {
rfbLog("too many blackouts: %d\n", blackouts); rfbLog("too many blackouts: %d\n", blackouts);
break; break;
} }
@ -5209,8 +5329,8 @@ void blackout_tiles(void) {
/* union of blackouts */ /* union of blackouts */
for (b=0; b < blackouts; b++) { for (b=0; b < blackouts; b++) {
sraRegionPtr tmp_reg = (sraRegionPtr) sraRegionPtr tmp_reg = (sraRegionPtr)
sraRgnCreateRect(blackr[b].x1, blackr[b].y1, sraRgnCreateRect(blackr[b].x1,
blackr[b].x2, blackr[b].y2); blackr[b].y1, blackr[b].x2, blackr[b].y2);
sraRgnOr(black_reg, tmp_reg); sraRgnOr(black_reg, tmp_reg);
sraRgnDestroy(tmp_reg); sraRgnDestroy(tmp_reg);
@ -5260,7 +5380,7 @@ void blackout_tiles(void) {
tile_blackout[n].cover = 1; tile_blackout[n].cover = 1;
} }
if (++cnt >= 10) { if (++cnt >= BO_MAX) {
rfbLog("too many blackout rectangles " rfbLog("too many blackout rectangles "
"for tile %d=%d,%d.\n", n, tx, ty); "for tile %d=%d,%d.\n", n, tx, ty);
break; break;
@ -5376,7 +5496,7 @@ void initialize_xinerama (void) {
/* /*
* Fill the framebuffer with zero for the prescribed rectangle * Fill the framebuffer with zero for the prescribed rectangle
*/ */
void zero_fb(x1, y1, x2, y2) { void zero_fb(int x1, int y1, int x2, int y2) {
int pixelsize = bpp >> 3; int pixelsize = bpp >> 3;
int line, fill = 0; int line, fill = 0;
char *dst; char *dst;
@ -5485,7 +5605,7 @@ static void set_fs_factor(int max) {
} }
/* /*
* set up an XShm image * set up an XShm image, or if not using shm just create the XImage.
*/ */
static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h, static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
char *name) { char *name) {
@ -5504,8 +5624,8 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
if (! using_shm) { if (! using_shm) {
/* we only need the XImage created */ /* we only need the XImage created */
xim = XCreateImage(dpy, visual, depth, ZPixmap, 0, NULL, w, h, xim = XCreateImage_wr(dpy, default_visual, depth, ZPixmap,
BitmapPad(dpy), 0); 0, NULL, w, h, BitmapPad(dpy), 0);
X_UNLOCK; X_UNLOCK;
@ -5541,7 +5661,8 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
return 1; return 1;
} }
xim = XShmCreateImage(dpy, visual, depth, ZPixmap, NULL, shm, w, h); xim = XShmCreateImage(dpy, default_visual, depth, ZPixmap, NULL,
shm, w, h);
if (xim == NULL) { if (xim == NULL) {
rfbErr("XShmCreateImage(%s) failed.\n", name); rfbErr("XShmCreateImage(%s) failed.\n", name);
@ -6393,13 +6514,13 @@ static void copy_tiles(int tx, int ty, int nt) {
/* read in the whole tile run at once: */ /* read in the whole tile run at once: */
if ( using_shm && size_x == tile_x * nt && size_y == tile_y ) { if ( using_shm && size_x == tile_x * nt && size_y == tile_y ) {
/* general case: */ /* general case: */
XShmGetImage(dpy, window, tile_row[nt], x, y, AllPlanes); XShmGetImage_wr(dpy, window, tile_row[nt], x, y, AllPlanes);
} else { } else {
/* /*
* No shm or near bottom/rhs edge case: * No shm or near bottom/rhs edge case:
* (but only if tile size does not divide screen size) * (but only if tile size does not divide screen size)
*/ */
XGetSubImage(dpy, window, x, y, size_x, size_y, AllPlanes, XGetSubImage_wr(dpy, window, x, y, size_x, size_y, AllPlanes,
ZPixmap, tile_row[nt], 0, 0); ZPixmap, tile_row[nt], 0, 0);
} }
X_UNLOCK; X_UNLOCK;
@ -6991,9 +7112,10 @@ void copy_screen(void) {
/* screen may be too big for 1 shm area, so broken into fs_factor */ /* screen may be too big for 1 shm area, so broken into fs_factor */
for (i=0; i < fs_factor; i++) { for (i=0; i < fs_factor; i++) {
if (using_shm) { if (using_shm) {
XShmGetImage(dpy, window, fullscreen, 0, y, AllPlanes); XShmGetImage_wr(dpy, window, fullscreen, 0, y,
AllPlanes);
} else { } else {
XGetSubImage(dpy, window, 0, y, fullscreen->width, XGetSubImage_wr(dpy, window, 0, y, fullscreen->width,
fullscreen->height, AllPlanes, ZPixmap, fullscreen, fullscreen->height, AllPlanes, ZPixmap, fullscreen,
0, 0); 0, 0);
} }
@ -7254,9 +7376,9 @@ static int scan_display(int ystart, int rescan) {
/* grab the horizontal scanline from the display: */ /* grab the horizontal scanline from the display: */
X_LOCK; X_LOCK;
if (using_shm) { if (using_shm) {
XShmGetImage(dpy, window, scanline, 0, y, AllPlanes); XShmGetImage_wr(dpy, window, scanline, 0, y, AllPlanes);
} else { } else {
XGetSubImage(dpy, window, 0, y, scanline->width, XGetSubImage_wr(dpy, window, 0, y, scanline->width,
scanline->height, AllPlanes, ZPixmap, scanline, scanline->height, AllPlanes, ZPixmap, scanline,
0, 0); 0, 0);
} }
@ -7816,9 +7938,37 @@ static void print_help(void) {
"\n" "\n"
"-id windowid Show the window corresponding to \"windowid\" not the\n" "-id windowid Show the window corresponding to \"windowid\" not the\n"
" entire display. Warning: bugs! new toplevels missed!...\n" " entire display. Warning: bugs! new toplevels missed!...\n"
"-sid windowid As -id, but instead of using the window directly it\n"
" shifts a root view to it: shows saveUnders menus, etc,\n"
" although they will be clipped if they extend beyond\n"
" the window.\n"
"-flashcmap In 8bpp indexed color, let the installed colormap flash\n" "-flashcmap In 8bpp indexed color, let the installed colormap flash\n"
" as the pointer moves from window to window (slow).\n" " as the pointer moves from window to window (slow).\n"
"-notruecolor Force 8bpp indexed color even if it looks like TrueColor.\n" "-notruecolor For 8bpp displays, force indexed color (i.e. a colormap)\n"
" even if it looks like 8bpp TrueColor. (rare problem)\n"
"-overlay Handle multiple depth visuals on one screen, e.g. 8+24\n"
" and 24+8 overlay visuals (the 32 bits per pixel are\n"
" packed with 8 for PseudoColor and 24 for TrueColor).\n"
"\n"
" Currently -overlay only works on Solaris (it uses\n"
" XReadScreen(3X11)). There are still some problems with\n"
" surrounding-region painting for popup menus (but not\n"
" for the popup menu itself); a workaround is to disable\n"
" SaveUnders (pass -su to Xsun). Amusingly, if -overlay\n"
" is used with -mouse, the mouse cursor shape is correct.\n"
"\n"
" Use -overlay as a workaround for situations like these:\n"
" Some legacy applications require the default visual\n"
" be 8bpp (8+24), or they will use 8bpp PseudoColor even\n"
" when the default visual is depth 24 TrueColor (24+8).\n"
" In these cases colors in some windows will be messed\n"
" up in x11vnc unless -overlay is used.\n"
"\n"
" Under -overlay, performance will be somewhat degraded\n"
" due to the extra image transformations required.\n"
" For optimal performance do not use -overlay, but rather\n"
" configure the X server so that the default visual is\n"
" depth 24 TrueColor and have all apps use that visual.\n"
"-visual n Experimental option: probably does not do what you\n" "-visual n Experimental option: probably does not do what you\n"
" think. It simply *forces* the visual used for the\n" " think. It simply *forces* the visual used for the\n"
" framebuffer; this may be a bad thing... It is useful for\n" " framebuffer; this may be a bad thing... It is useful for\n"
@ -7833,7 +7983,7 @@ static void print_help(void) {
" and response may be slower. If \"fraction\" contains\n" " and response may be slower. If \"fraction\" contains\n"
" a decimal point \".\" it is taken as a floating point\n" " a decimal point \".\" it is taken as a floating point\n"
" number, alternatively the notation \"m/n\" may be used\n" " number, alternatively the notation \"m/n\" may be used\n"
" to denote fractions, e.g. -scale 2/3.\n" " to denote fractions exactly, e.g. -scale 2/3.\n"
"\n" "\n"
" Scaling Options: can be added after \"fraction\" via\n" " Scaling Options: can be added after \"fraction\" via\n"
" \":\", to supply multiple \":\" options use commas.\n" " \":\", to supply multiple \":\" options use commas.\n"
@ -8189,7 +8339,7 @@ static char *choose_title(char *display) {
strncat(title, display, MAXN - strlen(title)); strncat(title, display, MAXN - strlen(title));
if (subwin) { if (subwin) {
char *name; char *name;
if (XFetchName(dpy, window, &name)) { if (XFetchName(dpy, subwin, &name)) {
strncat(title, " ", MAXN - strlen(title)); strncat(title, " ", MAXN - strlen(title));
strncat(title, name, MAXN - strlen(title)); strncat(title, name, MAXN - strlen(title));
} }
@ -8436,6 +8586,16 @@ int main(int argc, char* argv[]) {
exit(1); exit(1);
} }
} }
} else if (!strcmp(arg, "-sid")) {
rootshift = 1;
CHECK_ARGC
if (sscanf(argv[++i], "0x%x", &subwin) != 1) {
if (sscanf(argv[i], "%d", &subwin) != 1) {
fprintf(stderr, "bad -id arg: %s\n",
argv[i]);
exit(1);
}
}
} else if (!strcmp(arg, "-scale")) { } else if (!strcmp(arg, "-scale")) {
int m, n; int m, n;
char *p; char *p;
@ -8500,6 +8660,8 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-visual")) { } else if (!strcmp(arg, "-visual")) {
CHECK_ARGC CHECK_ARGC
visual_str = argv[++i]; visual_str = argv[++i];
} else if (!strcmp(arg, "-overlay")) {
overlay = 1;
} else if (!strcmp(arg, "-flashcmap")) { } else if (!strcmp(arg, "-flashcmap")) {
flash_cmap = 1; flash_cmap = 1;
} else if (!strcmp(arg, "-notruecolor")) { } else if (!strcmp(arg, "-notruecolor")) {
@ -8866,6 +9028,28 @@ int main(int argc, char* argv[]) {
argv_vnc[argc_vnc++] = "604800000"; /* one week... */ argv_vnc[argc_vnc++] = "604800000"; /* one week... */
} }
if (overlay) {
#ifdef SOLARIS
using_shm = 0;
if (flash_cmap && ! quiet) {
fprintf(stderr, "warning: -flashcmap may be "
"incompatible with -overlay\n");
}
if (show_mouse) {
show_mouse = 0;
overlay_mouse = 1;
}
#else
if (! quiet) {
fprintf(stderr, "disabling -overlay: currently only "
"available on Solaris Xsun.\n");
}
overlay = 0;
#endif
}
/* check for OS with small shm limits */ /* check for OS with small shm limits */
if (using_shm && ! single_copytile) { if (using_shm && ! single_copytile) {
if (limit_shm()) { if (limit_shm()) {
@ -8903,6 +9087,8 @@ int main(int argc, char* argv[]) {
fprintf(stderr, "scaling: %d %.5f\n", scaling, scale_fac); fprintf(stderr, "scaling: %d %.5f\n", scaling, scale_fac);
fprintf(stderr, "visual: %s\n", visual_str ? visual_str fprintf(stderr, "visual: %s\n", visual_str ? visual_str
: "null"); : "null");
fprintf(stderr, "overlay: %d\n", overlay);
fprintf(stderr, "ovl_mouse: %d\n", overlay_mouse);
fprintf(stderr, "viewonly: %d\n", view_only); fprintf(stderr, "viewonly: %d\n", view_only);
fprintf(stderr, "shared: %d\n", shared); fprintf(stderr, "shared: %d\n", shared);
fprintf(stderr, "conn_once: %d\n", connect_once); fprintf(stderr, "conn_once: %d\n", connect_once);
@ -9025,14 +9211,15 @@ int main(int argc, char* argv[]) {
} else { } else {
if (! quiet) fprintf(stderr, "Using default X display.\n"); if (! quiet) fprintf(stderr, "Using default X display.\n");
} }
scr = DefaultScreen(dpy);
rootwin = RootWindow(dpy, scr);
if (! dt) { if (! dt) {
static char str[] = "-desktop"; static char str[] = "-desktop";
argv_vnc[argc_vnc++] = str; argv_vnc[argc_vnc++] = str;
argv_vnc[argc_vnc++] = choose_title(use_dpy); argv_vnc[argc_vnc++] = choose_title(use_dpy);
} }
scr = DefaultScreen(dpy);
rootwin = RootWindow(dpy, scr);
/* check for XTEST */ /* check for XTEST */
if (! XTestQueryExtension(dpy, &ev, &er, &maj, &min)) { if (! XTestQueryExtension(dpy, &ev, &er, &maj, &min)) {
@ -9060,9 +9247,38 @@ int main(int argc, char* argv[]) {
} }
} }
if (overlay) {
/*
* ideally we'd like to not have to cook up the visual variables
* but rather let it all come out of XReadScreen(), however
* there is no way to get a default visual out of it, so we
* pretend -visual TrueColor:NN was supplied with NN usually 24.
*/
#ifdef SOLARIS
char str[16];
XImage *xi;
Window twin = subwin ? subwin : rootwin;
xi = XReadScreen(dpy, twin, 0, 0, 8, 8, False);
sprintf(str, "TrueColor:%d", xi->depth);
if (xi->depth != 24 && ! quiet) {
fprintf(stderr, "warning XReadScreen() image has "
"depth %d instead of 24.\n", xi->depth);
}
XDestroyImage(xi);
if (visual_str != NULL && ! quiet) {
fprintf(stderr, "warning: replacing '-visual %s' by "
"'%s' for use with -overlay\n", visual_str, str);
}
visual_str = strdup(str);
#endif
}
if (visual_str != NULL) { if (visual_str != NULL) {
set_visual(visual_str); set_visual(visual_str);
} }
#ifdef LIBVNCSERVER_HAVE_XKEYBOARD #ifdef LIBVNCSERVER_HAVE_XKEYBOARD
/* check for XKEYBOARD */ /* check for XKEYBOARD */
if (use_xkb) { if (use_xkb) {
@ -9083,7 +9299,8 @@ int main(int argc, char* argv[]) {
dpy_y = DisplayHeight(dpy, scr); dpy_y = DisplayHeight(dpy, scr);
off_x = 0; off_x = 0;
off_y = 0; off_y = 0;
visual = DefaultVisual(dpy, scr); /* this may be overridden via visual_id below */
default_visual = DefaultVisual(dpy, scr);
} else { } else {
/* experiment to share just one window */ /* experiment to share just one window */
XWindowAttributes attr; XWindowAttributes attr;
@ -9095,7 +9312,9 @@ int main(int argc, char* argv[]) {
} }
dpy_x = attr.width; dpy_x = attr.width;
dpy_y = attr.height; dpy_y = attr.height;
visual = attr.visual;
/* this may be overridden via visual_id below */
default_visual = attr.visual;
/* show_mouse has some segv crashes as well */ /* show_mouse has some segv crashes as well */
if (show_root_cursor) { if (show_root_cursor) {
@ -9108,16 +9327,17 @@ int main(int argc, char* argv[]) {
set_offset(); set_offset();
} }
/* initialize depth to reasonable value */ /* initialize depth to reasonable value, visual_id may override */
depth = DefaultDepth(dpy, scr); depth = DefaultDepth(dpy, scr);
/*
* User asked for non-default visual, this is not working well but it
* does some useful things... What should it do in general?
*/
if (visual_id) { if (visual_id) {
XVisualInfo vinfo_tmpl, *vinfo;
int n; int n;
XVisualInfo vinfo_tmpl, *vinfo;
/*
* we are in here from -visual or -overlay options
* visual_id and visual_depth were set in set_visual().
*/
vinfo_tmpl.visualid = visual_id; vinfo_tmpl.visualid = visual_id;
vinfo = XGetVisualInfo(dpy, VisualIDMask, &vinfo_tmpl, &n); vinfo = XGetVisualInfo(dpy, VisualIDMask, &vinfo_tmpl, &n);
@ -9126,10 +9346,11 @@ int main(int argc, char* argv[]) {
(int) visual_id); (int) visual_id);
exit(1); exit(1);
} }
visual = vinfo->visual; default_visual = vinfo->visual;
depth = vinfo->depth; depth = vinfo->depth;
if (visual_depth) { if (visual_depth) {
depth = visual_depth; /* force it */ /* force it from -visual FooColor:NN */
depth = visual_depth;
} }
if (! quiet) { if (! quiet) {
fprintf(stderr, "vis id: 0x%x\n", fprintf(stderr, "vis id: 0x%x\n",
@ -9148,19 +9369,23 @@ int main(int argc, char* argv[]) {
} }
if (nofb || visual_id) { if (nofb) {
fb = XCreateImage(dpy, visual, depth, ZPixmap, 0, NULL,
dpy_x, dpy_y, BitmapPad(dpy), 0);
/* /*
* For -nofb we do not allocate the framebuffer, so we * For -nofb we do not allocate the framebuffer, so we
* can save a few MB of memory. * can save a few MB of memory.
*/ */
if (! nofb) { fb = XCreateImage_wr(dpy, default_visual, depth, ZPixmap,
fb->data = (char *) malloc(fb->bytes_per_line * 0, NULL, dpy_x, dpy_y, BitmapPad(dpy), 0);
fb->height);
} } else if (visual_id) {
/*
* we need to call XCreateImage to supply the visual
*/
fb = XCreateImage_wr(dpy, default_visual, depth, ZPixmap,
0, NULL, dpy_x, dpy_y, BitmapPad(dpy), 0);
fb->data = (char *) malloc(fb->bytes_per_line * fb->height);
} else { } else {
fb = XGetImage(dpy, window, 0, 0, dpy_x, dpy_y, AllPlanes, fb = XGetImage_wr(dpy, window, 0, 0, dpy_x, dpy_y, AllPlanes,
ZPixmap); ZPixmap);
if (! quiet) { if (! quiet) {
fprintf(stderr, "Read initial data from X display into" fprintf(stderr, "Read initial data from X display into"

Loading…
Cancel
Save