Commit 17e6b6a2 authored by runge's avatar runge

x11vnc: -8to24 now works on default depth 8 displays.

parent e38c3c22
This diff is collapsed.
......@@ -4,6 +4,7 @@
/* -- 8to24.h -- */
extern int multivis_count;
extern int multivis_24count;
extern void check_for_multivis(void);
extern void bpp8to24(int, int, int, int);
......
2006-01-18 Karl Runge <runge@karlrunge.com>
* x11vnc: -8to24 now works on default depth 8 screens.
2006-01-16 Karl Runge <runge@karlrunge.com>
* x11vnc: more tweaks to -8to24, add XGETIMAGE_8TO24 mode to call
XGetImage() on the 8bpp regions.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -943,6 +943,12 @@ static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
first = 0;
}
if (cmap8to24 && cmap8to24_fb && depth == 8) {
if (Bpp == 1) {
Bpp = 4;
}
}
if (scaling_cursor && scale_cursor_fac != 1.0) {
int W, H;
char *pixels_use = (char *) pixels;
......
......@@ -98,6 +98,7 @@ void print_help(int mode) {
"\n"
"-flashcmap In 8bpp indexed color, let the installed colormap flash\n"
" as the pointer moves from window to window (slow).\n"
" Also try the -8to24 option to avoid flash altogether.\n"
"-shiftcmap n Rare problem, but some 8bpp displays use less than 256\n"
" colorcells (e.g. 16-color grayscale, perhaps the other\n"
" bits are used for double buffering) *and* also need to\n"
......@@ -150,8 +151,10 @@ void print_help(int mode) {
"-8to24 If -overlay is not supported on your OS, and you have a\n"
" legacy 8bpp app that you want to view on a multi-depth\n"
" display with default depth 24 (and is 32 bpp), try\n"
" this option. This option may not work on all X servers\n"
" and hardware (tested on XFree86/Xorg mga driver).\n"
" this option. It will also work for a default depth 8\n"
" display with depth 24 overlay windows. This option\n"
" may not work on all X servers and hardware (tested on\n"
" XFree86/Xorg mga driver).\n"
"\n"
" It enables a hack where x11vnc monitors windows within 3\n"
" levels from the root window. If it finds any that are\n"
......@@ -159,14 +162,22 @@ void print_help(int mode) {
" these regions where it extracts the 8bpp index color\n"
" value from bits 25-32 and maps them on to TrueColor\n"
" values and inserts them into bits 1-24 (i.e. overwrites\n"
" bits 1-24). This method appears to work, but may still\n"
" have bugs and note that it does hog resources. If there\n"
" bits 1-24).\n"
"\n"
" For default depth 8 displays, everything is tranformed\n"
" to 32bpp (and is potentially a improvement over\n"
" -flashcmap). Also for default depth 8 displays, setting\n"
" the env. var. HIGHBITS_8TO24 may give a speedup for\n"
" transforming 8bpp pixel data.\n"
"\n"
" These schemes appear to work, but may still have\n"
" bugs and note that they do hog resources. If there\n"
" are multiple 8bpp windows using different colormaps,\n"
" one may have to iconify all but one for the colors to\n"
" be correct.\n"
"\n"
" There may also be painting errors for clipping\n"
" and switching between windows of depths 8 and 24.\n"
" There may also be painting errors for clipping and\n"
" switching between windows of depths 8 and 24.\n"
" Heuristics are applied to try to minimize the painting\n"
" errors. One can also press 3 Alt_L's in a row to\n"
" refresh the screen if the error does not repair itself.\n"
......@@ -183,12 +194,8 @@ void print_help(int mode) {
" a scheme were XGetImage() is used to retrieve the 8bpp\n"
" data instead of assuming that data is in bits 25-32.\n"
" This mode is significantly slower than the above mode.\n"
"\n"
" Note that -8to24 does not work on displays with 8bpp\n"
" default visual with depth 24 applications. The Xserver\n"
" -cc option can be used to switch the default depth\n"
" on multidepth setups. It may be possible to handle\n"
" this case.\n"
" For the default depth 8 case, XGetImage() is always\n"
" used to access depth 24 pixel data.\n"
"\n"
"-scale fraction Scale the framebuffer by factor \"fraction\". Values\n"
" less than 1 shrink the fb, larger ones expand it. Note:\n"
......
......@@ -984,8 +984,16 @@ char *process_remote_cmd(char *cmd, int stringonly) {
snprintf(buf, bufn, "ans=%s:%d", p, cmap8to24);
goto qry;
}
if (overlay) {
rfbLog("disabling -overlay in -8to24 mode.\n");
overlay = 0;
}
rfbLog("remote_cmd: turning on -8to24 mode.\n");
cmap8to24 = 1;
if (overlay) {
rfbLog("disabling -overlay in -8to24 mode.\n");
overlay = 0;
}
do_new_fb(0);
} else if (!strcmp(p, "no8to24")) {
......
......@@ -1160,6 +1160,7 @@ void scale_rect(double factor, int blend, int interpolate, int Bpp,
void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
char *src_fb = main_fb;
int Bpp = bpp/8, fac = 1;
if (!screen || !rfb_fb || !main_fb) {
return;
......@@ -1185,10 +1186,13 @@ void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
if (cmap8to24 && cmap8to24_fb) {
src_fb = cmap8to24_fb;
if (scaling && depth == 8) {
fac = 4;
}
}
scale_rect(scale_fac, scaling_blend, scaling_interpolate, bpp/8,
src_fb, main_bytes_per_line, rfb_fb, rfb_bytes_per_line,
scale_rect(scale_fac, scaling_blend, scaling_interpolate, fac * Bpp,
src_fb, fac * main_bytes_per_line, rfb_fb, rfb_bytes_per_line,
dpy_x, dpy_y, scaled_x, scaled_y, X1, Y1, X2, Y2, 1);
}
......
......@@ -1502,11 +1502,39 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
int height = fb->height;
int create_screen = screen ? 0 : 1;
int bits_per_color;
int fb_bpp, fb_Bpl, fb_depth;
bpp = fb->bits_per_pixel;
fb_bpp = (int) fb->bits_per_pixel;
fb_Bpl = (int) fb->bytes_per_line;
fb_depth = (int) fb->depth;
main_bytes_per_line = fb->bytes_per_line;
if (cmap8to24) {
if (raw_fb) {
if (!quiet) rfbLog("disabling -8to24 mode"
" in raw_fb mode.\n");
cmap8to24 = 0;
} else if (depth == 24) {
if (fb_bpp != 32) {
if (!quiet) rfbLog("disabling -8to24 mode:"
" bpp != 32 with depth == 24\n");
cmap8to24 = 0;
}
} else if (depth == 8) {
/* need to cook up the screen fb to be depth 24 */
fb_bpp = 32;
fb_depth = 24;
} else {
if (!quiet) rfbLog("disabling -8to24 mode:"
" default depth not 24 or 8\n");
cmap8to24 = 0;
}
}
setup_scaling(&width, &height);
if (scaling) {
rfbLog("scaling screen: %dx%d -> %dx%d scale_fac=%.5f\n",
......@@ -1517,32 +1545,35 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
rfb_bytes_per_line = main_bytes_per_line;
}
if (cmap8to24 && depth == 8) {
rfb_bytes_per_line *= 4;
}
/*
* These are just hints wrt pixel format just to let
* rfbGetScreen/rfbNewFramebuffer proceed with reasonable
* defaults. We manually set them in painful detail below.
*/
bits_per_color = guess_bits_per_color(fb->bits_per_pixel);
bits_per_color = guess_bits_per_color(fb_bpp);
/* n.b. samplesPerPixel (set = 1 here) seems to be unused. */
if (create_screen) {
screen = rfbGetScreen(argc, argv, width, height,
bits_per_color, 1, (int) fb->bits_per_pixel/8);
bits_per_color, 1, fb_bpp/8);
if (screen && http_dir) {
http_connections(1);
}
} else {
/* set set frameBuffer member below. */
rfbLog("rfbNewFramebuffer(0x%x, 0x%x, %d, %d, %d, %d, %d)\n",
screen, NULL, width, height,
bits_per_color, 1, fb->bits_per_pixel/8);
screen, NULL, width, height, bits_per_color, 1, fb_bpp/8);
/* these are probably overwritten, but just to be safe: */
screen->bitsPerPixel = fb->bits_per_pixel;
screen->depth = fb->depth;
screen->bitsPerPixel = fb_bpp;
screen->depth = fb_depth;
rfbNewFramebuffer(screen, NULL, width, height,
bits_per_color, 1, (int) fb->bits_per_pixel/8);
bits_per_color, 1, (int) fb_bpp/8);
}
if (! screen) {
int i;
......@@ -1583,8 +1614,8 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
/* set up format from scratch: */
screen->paddedWidthInBytes = rfb_bytes_per_line;
screen->serverFormat.bitsPerPixel = fb->bits_per_pixel;
screen->serverFormat.depth = fb->depth;
screen->serverFormat.bitsPerPixel = fb_bpp;
screen->serverFormat.depth = fb_depth;
screen->serverFormat.trueColour = TRUE;
screen->serverFormat.redShift = 0;
......@@ -1605,12 +1636,33 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
main_green_mask = fb->green_mask;
main_blue_mask = fb->blue_mask;
have_masks = ((fb->red_mask|fb->green_mask|fb->blue_mask) != 0);
if (force_indexed_color) {
have_masks = 0;
}
if (cmap8to24 && depth == 8) {
XVisualInfo vinfo;
/* more cooking up... */
have_masks = 2;
/* need to fetch TrueColor visual */
X_LOCK;
if (XMatchVisualInfo(dpy, scr, 24, TrueColor, &vinfo)) {
main_red_mask = vinfo.red_mask;
main_green_mask = vinfo.green_mask;
main_blue_mask = vinfo.blue_mask;
} else if (fb->byte_order == LSBFirst) {
main_red_mask = 0x00ff0000;
main_green_mask = 0x0000ff00;
main_blue_mask = 0x000000ff;
} else {
main_red_mask = 0x000000ff;
main_green_mask = 0x0000ff00;
main_blue_mask = 0x00ff0000;
}
X_UNLOCK;
}
if (! have_masks && screen->serverFormat.bitsPerPixel == 8
&& dpy && CellsOfScreen(ScreenOfDisplay(dpy, scr))) {
/* indexed color */
......@@ -1641,41 +1693,45 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
if (raw_fb) {
rfbLog("Raw fb at addr %p is %dbpp depth=%d "
"true color\n", raw_fb_addr,
fb_bpp, fb_depth);
} else if (have_masks == 2) {
rfbLog("X display %s is %dbpp depth=%d indexed "
"color (-8to24 mode)\n", DisplayString(dpy),
fb->bits_per_pixel, fb->depth);
} else {
rfbLog("X display %s is %dbpp depth=%d true "
"color\n", DisplayString(dpy),
fb->bits_per_pixel, fb->depth);
fb_bpp, fb_depth);
}
}
indexed_color = 0;
/* convert masks to bit shifts and max # colors */
if (fb->red_mask) {
while (! (fb->red_mask
if (main_red_mask) {
while (! (main_red_mask
& (1 << screen->serverFormat.redShift))) {
screen->serverFormat.redShift++;
}
}
if (fb->green_mask) {
while (! (fb->green_mask
if (main_green_mask) {
while (! (main_green_mask
& (1 << screen->serverFormat.greenShift))) {
screen->serverFormat.greenShift++;
}
}
if (fb->blue_mask) {
while (! (fb->blue_mask
if (main_blue_mask) {
while (! (main_blue_mask
& (1 << screen->serverFormat.blueShift))) {
screen->serverFormat.blueShift++;
}
}
screen->serverFormat.redMax
= fb->red_mask >> screen->serverFormat.redShift;
= main_red_mask >> screen->serverFormat.redShift;
screen->serverFormat.greenMax
= fb->green_mask >> screen->serverFormat.greenShift;
= main_green_mask >> screen->serverFormat.greenShift;
screen->serverFormat.blueMax
= fb->blue_mask >> screen->serverFormat.blueShift;
= main_blue_mask >> screen->serverFormat.blueShift;
main_red_max = screen->serverFormat.redMax;
main_green_max = screen->serverFormat.greenMax;
......@@ -1703,6 +1759,17 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
bitprint(fb->green_mask, 32));
fprintf(stderr, " blue_mask: 0x%08lx %s\n", fb->blue_mask,
bitprint(fb->blue_mask, 32));
if (cmap8to24) {
fprintf(stderr, " 8to24 info:\n");
fprintf(stderr, " fb_bpp: %d\n", fb_bpp);
fprintf(stderr, " fb_depth: %d\n", fb_depth);
fprintf(stderr, " red_mask: 0x%08lx %s\n", main_red_mask,
bitprint(main_red_mask, 32));
fprintf(stderr, " green_mask: 0x%08lx %s\n", main_green_mask,
bitprint(main_green_mask, 32));
fprintf(stderr, " blue_mask: 0x%08lx %s\n", main_blue_mask,
bitprint(main_blue_mask, 32));
}
fprintf(stderr, " red: max: %3d shift: %2d\n",
main_red_max, main_red_shift);
fprintf(stderr, " green: max: %3d shift: %2d\n",
......@@ -1765,16 +1832,11 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
rfb_fb = NULL;
cmap8to24_fb = NULL;
if (cmap8to24) {
if (screen->serverFormat.bitsPerPixel != 32 ||
screen->serverFormat.depth != 24) {
if (!quiet) rfbLog("disabling -8to24 mode:"
" bpp != 32 or depth != 24\n");
cmap8to24 = 0;
}
}
if (cmap8to24) {
int n = main_bytes_per_line * fb->height;
if (depth == 8) {
n *= 4;
}
cmap8to24_fb = (char *) malloc(n);
memset(cmap8to24_fb, 0, n);
}
......@@ -1795,9 +1857,6 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
fprintf(stderr, "\n");
}
bpp = screen->serverFormat.bitsPerPixel;
depth = screen->serverFormat.depth;
/* may need, bpp, main_red_max, etc. */
parse_wireframe();
parse_scroll_copyrect();
......
......@@ -1729,16 +1729,16 @@ static void get_client_regions(int *req, int *mod, int *cpy, int *num) {
static void do_copyregion(sraRegionPtr region, int dx, int dy) {
sraRectangleIterator *iter;
sraRect rect;
int Bpp = bpp/8;
int x1, y1, x2, y2, w, stride;
int Bpp0 = bpp/8, Bpp;
int x1, y1, x2, y2, w, stride, stride0;
int sx1, sy1, sx2, sy2, sdx, sdy;
int req, mod, cpy, ncli;
char *dst, *src;
char *dst = NULL, *src = NULL;
last_copyrect = dnow();
if (!scaling || rfb_fb == main_fb) {
/* normal case */
if (rfb_fb == main_fb) {
/* normal case, no -scale or -8to24 */
get_client_regions(&req, &mod, &cpy, &ncli);
if (debug_scroll > 1) fprintf(stderr, "<<<-rfbDoCopyRect req: %d mod: %d cpy: %d\n", req, mod, cpy);
rfbDoCopyRegion(screen, region, dx, dy);
......@@ -1750,43 +1750,73 @@ if (debug_scroll > 1) fprintf(stderr, ">>>-rfbDoCopyRect req: %d mod: %d cpy: %d
}
/* rarer case, we need to call rfbDoCopyRect with scaled xy */
stride = dpy_x * Bpp;
stride0 = dpy_x * Bpp0;
iter = sraRgnGetReverseIterator(region, dx < 0, dy < 0);
while(sraRgnIteratorNext(iter, &rect)) {
int j;
int j, c;
x1 = rect.x1;
y1 = rect.y1;
x2 = rect.x2;
y2 = rect.y2;
w = (x2 - x1)*Bpp;
dst = main_fb + y1*stride + x1*Bpp;
src = main_fb + (y1-dy)*stride + (x1-dx)*Bpp;
if (dy < 0) {
for (j=y1; j<y2; j++) {
memmove(dst, src, w);
dst += stride;
src += stride;
for (c= 0; c < 2; c++) {
Bpp = Bpp0;
stride = stride0;
if (c == 0) {
dst = main_fb + y1*stride + x1*Bpp;
src = main_fb + (y1-dy)*stride + (x1-dx)*Bpp;
} else if (c == 1) {
if (! cmap8to24_fb || cmap8to24_fb == rfb_fb) {
continue;
}
if (cmap8to24 && depth == 8) {
Bpp = 4 * Bpp0;
stride = 4 * stride0;
}
dst = cmap8to24_fb + y1*stride + x1*Bpp;
src = cmap8to24_fb + (y1-dy)*stride + (x1-dx)*Bpp;
}
} else {
dst += (y2 - y1 - 1)*stride;
src += (y2 - y1 - 1)*stride;
for (j=y2-1; j>=y1; j--) {
memmove(dst, src, w);
dst -= stride;
src -= stride;
w = (x2 - x1)*Bpp;
if (dy < 0) {
for (j=y1; j<y2; j++) {
memmove(dst, src, w);
dst += stride;
src += stride;
}
} else {
dst += (y2 - y1 - 1)*stride;
src += (y2 - y1 - 1)*stride;
for (j=y2-1; j>=y1; j--) {
memmove(dst, src, w);
dst -= stride;
src -= stride;
}
}
}
sx1 = ((double) x1 / dpy_x) * scaled_x;
sy1 = ((double) y1 / dpy_y) * scaled_y;
sx2 = ((double) x2 / dpy_x) * scaled_x;
sy2 = ((double) y2 / dpy_y) * scaled_y;
sdx = ((double) dx / dpy_x) * scaled_x;
sdy = ((double) dy / dpy_y) * scaled_y;
if (scaling) {
sx1 = ((double) x1 / dpy_x) * scaled_x;
sy1 = ((double) y1 / dpy_y) * scaled_y;
sx2 = ((double) x2 / dpy_x) * scaled_x;
sy2 = ((double) y2 / dpy_y) * scaled_y;
sdx = ((double) dx / dpy_x) * scaled_x;
sdy = ((double) dy / dpy_y) * scaled_y;
} else {
sx1 = x1;
sy1 = y1;
sx2 = x2;
sy2 = y2;
sdx = dx;
sdy = dy;
}
rfbDoCopyRect(screen, sx1, sy1, sx2, sy2, sdx, sdy);
}
......@@ -3710,8 +3740,6 @@ if (db) fprintf(stderr, "send_copyrect: %d\n", sent_copyrect);
if (0) fprintf(stderr, "wireframe_in_progress over: %d %d %d %d\n", x1, y1, x2, y2);
check_for_multivis();
if (1) mark_rect_as_modified(x1, y1, x2, y2, 0);
if (0) mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
if (0) rfbPE(-1);
}
urgent_update = 1;
......
......@@ -2,7 +2,7 @@
.TH X11VNC "1" "January 2006" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.8, lastmod: 2006-01-16
version: 0.8, lastmod: 2006-01-18
.SH SYNOPSIS
.B x11vnc
[OPTION]...
......@@ -110,6 +110,7 @@ of the selected window.
.IP
In 8bpp indexed color, let the installed colormap flash
as the pointer moves from window to window (slow).
Also try the \fB-8to24\fR option to avoid flash altogether.
.PP
\fB-shiftcmap\fR \fIn\fR
.IP
......@@ -182,8 +183,10 @@ cursor shape using the overlay mechanism.
If \fB-overlay\fR is not supported on your OS, and you have a
legacy 8bpp app that you want to view on a multi-depth
display with default depth 24 (and is 32 bpp), try
this option. This option may not work on all X servers
and hardware (tested on XFree86/Xorg mga driver).
this option. It will also work for a default depth 8
display with depth 24 overlay windows. This option
may not work on all X servers and hardware (tested on
XFree86/Xorg mga driver).
.IP
It enables a hack where x11vnc monitors windows within 3
levels from the root window. If it finds any that are
......@@ -191,14 +194,22 @@ levels from the root window. If it finds any that are
these regions where it extracts the 8bpp index color
value from bits 25-32 and maps them on to TrueColor
values and inserts them into bits 1-24 (i.e. overwrites
bits 1-24). This method appears to work, but may still
have bugs and note that it does hog resources. If there
bits 1-24).
.IP
For default depth 8 displays, everything is tranformed
to 32bpp (and is potentially a improvement over
\fB-flashcmap).\fR Also for default depth 8 displays, setting
the env. var. HIGHBITS_8TO24 may give a speedup for
transforming 8bpp pixel data.
.IP
These schemes appear to work, but may still have
bugs and note that they do hog resources. If there
are multiple 8bpp windows using different colormaps,
one may have to iconify all but one for the colors to
be correct.
.IP
There may also be painting errors for clipping
and switching between windows of depths 8 and 24.
There may also be painting errors for clipping and
switching between windows of depths 8 and 24.
Heuristics are applied to try to minimize the painting
errors. One can also press 3 Alt_L's in a row to
refresh the screen if the error does not repair itself.
......@@ -215,12 +226,8 @@ XGETIMAGE_8TO24=1 before starting x11vnc. This enables
a scheme were XGetImage() is used to retrieve the 8bpp
data instead of assuming that data is in bits 25-32.
This mode is significantly slower than the above mode.
.IP
Note that \fB-8to24\fR does not work on displays with 8bpp
default visual with depth 24 applications. The Xserver
\fB-cc\fR option can be used to switch the default depth
on multidepth setups. It may be possible to handle
this case.
For the default depth 8 case, XGetImage() is always
used to access depth 24 pixel data.
.PP
\fB-scale\fR \fIfraction\fR
.IP
......
......@@ -1560,7 +1560,7 @@ int main(int argc, char* argv[]) {
set_wirecopyrect_mode(argv[++i]);
got_wirecopyrect = 1;
} else if (!strcmp(arg, "-nowirecopyrect")
|| !strcmp(arg, "-nowf")) {
|| !strcmp(arg, "-nowcr")) {
set_wirecopyrect_mode("never");
} else if (!strcmp(arg, "-debug_wireframe")
|| !strcmp(arg, "-dwf")) {
......@@ -2054,10 +2054,18 @@ int main(int argc, char* argv[]) {
alpha_remove = 0;
}
if (cmap8to24 && overlay) {
if (! quiet) {
rfbLog("disabling -overlay in -8to24 mode.\n");
}
overlay = 0;
}
if (filexfer && view_only) {
if (! quiet) {
rfbLog("setting -nofilexfer in -viewonly mode.\n");
}
/* how to undo via -R? */
filexfer = 0;
}
......
......@@ -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 lastmod: 2006-01-16";
char lastmod[] = "0.8 lastmod: 2006-01-18";
/* 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