Commit 65b42bb8 authored by runge's avatar runge

x11vnc: support colormaps for depths other than 8. xinerama warppointer only...

x11vnc: support colormaps for depths other than 8.  xinerama warppointer only if more than one subscreen.
parent 1983292e
This diff is collapsed.
2008-05-31 Karl Runge <runge@karlrunge.com>
* x11vnc: Improvements to nonstandard indexed color support, e.g.
depths 1, 4, 12, etc. instead of only 8. Only enable xinerama
xwarppointer if there is more than 1 subscreen.
2008-05-07 Karl Runge <runge@karlrunge.com> 2008-05-07 Karl Runge <runge@karlrunge.com>
* x11vnc: add UltraVNC repeater proxy support. fix to setp gui * x11vnc: add UltraVNC repeater proxy support. fix to setp gui
mode. -threads is now strongly discouraged. Read PORT= in url. mode. -threads is now strongly discouraged. Read PORT= in url.
......
This diff is collapsed.
...@@ -2734,6 +2734,23 @@ void check_gui_inputs(void) { ...@@ -2734,6 +2734,23 @@ void check_gui_inputs(void) {
} }
} }
static int turn_off_truecolor = 0;
static void turn_off_truecolor_ad(rfbClientPtr client) {
if (turn_off_truecolor) {
rfbLog("turning off truecolor advertising.\n");
screen->serverFormat.trueColour = FALSE;
screen->displayHook = NULL;
screen->serverFormat.redShift = 0;
screen->serverFormat.greenShift = 0;
screen->serverFormat.blueShift = 0;
screen->serverFormat.redMax = 0;
screen->serverFormat.greenMax = 0;
screen->serverFormat.blueMax = 0;
turn_off_truecolor = 0;
}
}
/* /*
* libvncserver callback for when a new client connects * libvncserver callback for when a new client connects
*/ */
...@@ -2877,6 +2894,43 @@ enum rfbNewClientAction new_client(rfbClientPtr client) { ...@@ -2877,6 +2894,43 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
check_ncache(1, 0); check_ncache(1, 0);
} }
if (advertise_truecolor && indexed_color) {
int rs = 0, gs = 2, bs = 4;
int rm = 3, gm = 3, bm = 3;
if (bpp >= 24) {
rs = 0, gs = 8, bs = 16;
rm = 255, gm = 255, bm = 255;
} else if (bpp >= 16) {
rs = 0, gs = 5, bs = 10;
rm = 31, gm = 31, bm = 31;
}
rfbLog("advertising truecolor.\n");
if (getenv("ADVERT_BMSHIFT")) {
bm--;
}
client->format.trueColour = TRUE;
client->format.redShift = rs;
client->format.greenShift = gs;
client->format.blueShift = bs;
client->format.redMax = rm;
client->format.greenMax = gm;
client->format.blueMax = bm;
rfbSetTranslateFunction(client);
screen->serverFormat.trueColour = TRUE;
screen->serverFormat.redShift = rs;
screen->serverFormat.greenShift = gs;
screen->serverFormat.blueShift = bs;
screen->serverFormat.redMax = rm;
screen->serverFormat.greenMax = gm;
screen->serverFormat.blueMax = bm;
screen->displayHook = turn_off_truecolor_ad;
turn_off_truecolor = 1;
}
if (unixpw) { if (unixpw) {
unixpw_in_progress = 1; unixpw_in_progress = 1;
unixpw_client = client; unixpw_client = client;
......
...@@ -976,8 +976,8 @@ static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h, ...@@ -976,8 +976,8 @@ static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
first = 0; first = 0;
} }
if (cmap8to24 && cmap8to24_fb && depth == 8) { if (cmap8to24 && cmap8to24_fb && depth <= 16) {
if (Bpp == 1) { if (Bpp <= 2) {
Bpp = 4; Bpp = 4;
} }
} }
......
...@@ -140,6 +140,11 @@ void print_help(int mode) { ...@@ -140,6 +140,11 @@ void print_help(int mode) {
" a colormap histogram. Example: -shiftcmap 240\n" " a colormap histogram. Example: -shiftcmap 240\n"
"-notruecolor For 8bpp displays, force indexed color (i.e. a colormap)\n" "-notruecolor For 8bpp displays, force indexed color (i.e. a colormap)\n"
" even if it looks like 8bpp TrueColor (rare problem).\n" " even if it looks like 8bpp TrueColor (rare problem).\n"
"-advertise_truecolor If the X11 display is indexed color, lie to clients\n"
" when they first connect by telling them it is truecolor.\n"
" To workaround RealVNC: inPF has colourMap but not 8bpp\n"
" Use '-advertise_truecolor reset' to reset client fb too.\n"
"\n"
"-visual n This option probably does not do what you think.\n" "-visual n This option probably does not do what you think.\n"
" It simply *forces* the visual used for the framebuffer;\n" " It simply *forces* the visual used for the framebuffer;\n"
" this may be a bad thing... (e.g. messes up colors or\n" " this may be a bad thing... (e.g. messes up colors or\n"
...@@ -147,8 +152,10 @@ void print_help(int mode) { ...@@ -147,8 +152,10 @@ void print_help(int mode) {
" workarounds. n may be a decimal number, or 0x hex.\n" " workarounds. n may be a decimal number, or 0x hex.\n"
" Run xdpyinfo(1) for the values. One may also use\n" " Run xdpyinfo(1) for the values. One may also use\n"
" \"TrueColor\", etc. see <X11/X.h> for a list. If the\n" " \"TrueColor\", etc. see <X11/X.h> for a list. If the\n"
" string ends in \":m\" then for better or for worse the\n" " string ends in \":m\" then for better or for worse\n"
" visual depth is forced to be m.\n" " the visual depth is forced to be m. You may want to\n"
" use -noshm when using this option (so XGetImage may\n"
" automatically translate the pixel data).\n"
"\n" "\n"
"-overlay Handle multiple depth visuals on one screen, e.g. 8+24\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" " and 24+8 overlay visuals (the 32 bits per pixel are\n"
......
...@@ -396,7 +396,8 @@ make_so() { ...@@ -396,7 +396,8 @@ make_so() {
warn "$tmp still exists." warn "$tmp still exists."
exit 1 exit 1
fi fi
tail +$n1 $0 | head -$dn > $tmp #tail +$n1 $0 | head -$dn > $tmp
tail -n +$n1 $0 | head -n $dn > $tmp
# compile it to Xdummy.so: # compile it to Xdummy.so:
rm -f $SO rm -f $SO
......
...@@ -114,6 +114,8 @@ int ping_interval = 0; /* -ping */ ...@@ -114,6 +114,8 @@ int ping_interval = 0; /* -ping */
int flash_cmap = 0; /* follow installed colormaps */ int flash_cmap = 0; /* follow installed colormaps */
int shift_cmap = 0; /* ncells < 256 and needs shift of pixel values */ int shift_cmap = 0; /* ncells < 256 and needs shift of pixel values */
int force_indexed_color = 0; /* whether to force indexed color for 8bpp */ int force_indexed_color = 0; /* whether to force indexed color for 8bpp */
int advertise_truecolor = 0;
int advertise_truecolor_reset = 0;
int cmap8to24 = 0; /* -8to24 */ int cmap8to24 = 0; /* -8to24 */
int xform24to32 = 0; /* -24to32 */ int xform24to32 = 0; /* -24to32 */
char *cmap8to24_str = NULL; char *cmap8to24_str = NULL;
......
...@@ -89,6 +89,8 @@ extern int ping_interval; ...@@ -89,6 +89,8 @@ extern int ping_interval;
extern int flash_cmap; extern int flash_cmap;
extern int shift_cmap; extern int shift_cmap;
extern int force_indexed_color; extern int force_indexed_color;
extern int advertise_truecolor;
extern int advertise_truecolor_reset;
extern int cmap8to24; extern int cmap8to24;
extern char *cmap8to24_str; extern char *cmap8to24_str;
extern int xform24to32; extern int xform24to32;
......
...@@ -1285,8 +1285,12 @@ void scale_and_mark_rect(int X1, int Y1, int X2, int Y2, int mark) { ...@@ -1285,8 +1285,12 @@ void scale_and_mark_rect(int X1, int Y1, int X2, int Y2, int mark) {
if (cmap8to24 && cmap8to24_fb) { if (cmap8to24 && cmap8to24_fb) {
src_fb = cmap8to24_fb; src_fb = cmap8to24_fb;
if (scaling && depth == 8) { if (scaling) {
if (depth <= 8) {
fac = 4; fac = 4;
} else if (depth <= 16) {
fac = 2;
}
} }
} }
dst_fb = rfb_fb; dst_fb = rfb_fb;
......
...@@ -79,6 +79,7 @@ int rawfb_vnc_reflect = 0; ...@@ -79,6 +79,7 @@ int rawfb_vnc_reflect = 0;
*/ */
#define NCOLOR 256 #define NCOLOR 256
/* this is only for rawfb */
void set_greyscale_colormap(void) { void set_greyscale_colormap(void) {
int i; int i;
if (! screen) { if (! screen) {
...@@ -139,6 +140,8 @@ if (0) fprintf(stderr, "set_hi240_colormap: %s\n", raw_fb_pixfmt); ...@@ -139,6 +140,8 @@ if (0) fprintf(stderr, "set_hi240_colormap: %s\n", raw_fb_pixfmt);
rfbSetClientColourMaps(screen, 0, 256); rfbSetClientColourMaps(screen, 0, 256);
} }
/* this is only for rawfb */
void unset_colormap(void) { void unset_colormap(void) {
if (! screen) { if (! screen) {
return; return;
...@@ -151,35 +154,55 @@ void unset_colormap(void) { ...@@ -151,35 +154,55 @@ void unset_colormap(void) {
if (0) fprintf(stderr, "unset_colormap: %s\n", raw_fb_pixfmt); if (0) fprintf(stderr, "unset_colormap: %s\n", raw_fb_pixfmt);
} }
/* this is X11 case */
void set_colormap(int reset) { void set_colormap(int reset) {
#if NO_X11 #if NO_X11
if (!reset) {} if (!reset) {}
return; return;
#else #else
static int init = 1; static int init = 1;
static XColor color[NCOLOR], prev[NCOLOR]; static XColor *color = NULL, *prev = NULL;
static int ncolor = 0;
Colormap cmap; Colormap cmap;
Visual *vis; Visual *vis;
int i, ncells, diffs = 0; int i, ncells, diffs = 0;
if (reset) { if (reset) {
init = 1; init = 1;
ncolor = 0;
if (screen->colourMap.data.shorts) { if (screen->colourMap.data.shorts) {
free(screen->colourMap.data.shorts); free(screen->colourMap.data.shorts);
screen->colourMap.data.shorts = NULL; screen->colourMap.data.shorts = NULL;
} }
if (color) {
free(color);
color = NULL;
}
if (prev) {
free(prev);
prev = NULL;
}
} }
if (0) fprintf(stderr, "unset_colormap: %d\n", reset);
if (init) { if (init) {
screen->colourMap.count = NCOLOR; if (depth > 8) {
ncolor = 1 << depth;
} else {
ncolor = NCOLOR;
}
screen->colourMap.count = ncolor;
screen->serverFormat.trueColour = FALSE; screen->serverFormat.trueColour = FALSE;
screen->colourMap.is16 = TRUE; screen->colourMap.is16 = TRUE;
screen->colourMap.data.shorts = (unsigned short *) screen->colourMap.data.shorts = (unsigned short *)
malloc(3*sizeof(unsigned short) * NCOLOR); malloc(3*sizeof(unsigned short) * ncolor);
}
if (color == NULL) {
color = (XColor *) calloc(ncolor * sizeof(XColor), 1);
prev = (XColor *) calloc(ncolor * sizeof(XColor), 1);
} }
for (i=0; i < NCOLOR; i++) { for (i=0; i < ncolor; i++) {
prev[i].red = color[i].red; prev[i].red = color[i].red;
prev[i].green = color[i].green; prev[i].green = color[i].green;
prev[i].blue = color[i].blue; prev[i].blue = color[i].blue;
...@@ -203,15 +226,15 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset); ...@@ -203,15 +226,15 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset);
} }
} }
if (ncells != NCOLOR) { if (ncells != ncolor) {
if (init && ! quiet) {
rfbLog("set_colormap: number of cells is %d "
"instead of %d.\n", ncells, NCOLOR);
}
if (! shift_cmap) { if (! shift_cmap) {
screen->colourMap.count = ncells; screen->colourMap.count = ncells;
} }
} }
if (init && ! quiet) {
rfbLog("set_colormap: number of cells: %d, "
"ncolor(%d) is %d.\n", ncells, depth, ncolor);
}
if (flash_cmap && ! init) { if (flash_cmap && ! init) {
XWindowAttributes attr; XWindowAttributes attr;
...@@ -233,9 +256,9 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset); ...@@ -233,9 +256,9 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset);
} }
} }
} }
if (ncells > NCOLOR && ! quiet) { if (ncells > ncolor && ! quiet) {
rfbLog("set_colormap: big problem: ncells=%d > %d\n", rfbLog("set_colormap: big problem: ncells=%d > %d\n",
ncells, NCOLOR); ncells, ncolor);
} }
if (vis->class == TrueColor || vis->class == DirectColor) { if (vis->class == TrueColor || vis->class == DirectColor) {
...@@ -245,7 +268,7 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset); ...@@ -245,7 +268,7 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset);
* mentioned in xdpyinfo. Looks OK... perhaps fortuitously. * mentioned in xdpyinfo. Looks OK... perhaps fortuitously.
*/ */
if (ncells == 8 && ! shift_cmap) { if (ncells == 8 && ! shift_cmap) {
ncells = NCOLOR; ncells = ncolor;
} }
} }
...@@ -271,7 +294,7 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset); ...@@ -271,7 +294,7 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset);
diffs++; diffs++;
} }
if (shift_cmap && k >= 0 && k < NCOLOR) { if (shift_cmap && k >= 0 && k < ncolor) {
/* kludge to copy the colors to higher pixel values */ /* kludge to copy the colors to higher pixel values */
screen->colourMap.data.shorts[k*3+0] = color[i].red; screen->colourMap.data.shorts[k*3+0] = color[i].red;
screen->colourMap.data.shorts[k*3+1] = color[i].green; screen->colourMap.data.shorts[k*3+1] = color[i].green;
...@@ -285,7 +308,7 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset); ...@@ -285,7 +308,7 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset);
"with uninitialized clients.\n"); "with uninitialized clients.\n");
} }
if (shift_cmap) { if (shift_cmap) {
rfbSetClientColourMaps(screen, 0, NCOLOR); rfbSetClientColourMaps(screen, 0, ncolor);
} else { } else {
rfbSetClientColourMaps(screen, 0, ncells); rfbSetClientColourMaps(screen, 0, ncells);
} }
...@@ -297,7 +320,8 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset); ...@@ -297,7 +320,8 @@ if (0) fprintf(stderr, "unset_colormap: %d\n", reset);
static void debug_colormap(XImage *fb) { static void debug_colormap(XImage *fb) {
static int debug_cmap = -1; static int debug_cmap = -1;
int i, k, histo[NCOLOR]; int i, k, *histo;
int ncolor;
if (debug_cmap < 0) { if (debug_cmap < 0) {
if (getenv("DEBUG_CMAP") != NULL) { if (getenv("DEBUG_CMAP") != NULL) {
...@@ -312,11 +336,13 @@ static void debug_colormap(XImage *fb) { ...@@ -312,11 +336,13 @@ static void debug_colormap(XImage *fb) {
if (! fb) { if (! fb) {
return; return;
} }
if (fb->bits_per_pixel > 8) { if (fb->bits_per_pixel > 16) {
return; return;
} }
ncolor = screen->colourMap.count;
histo = (int *) calloc(ncolor * sizeof(int), 1);
for (i=0; i < NCOLOR; i++) { for (i=0; i < ncolor; i++) {
histo[i] = 0; histo[i] = 0;
} }
for (k = 0; k < fb->width * fb->height; k++) { for (k = 0; k < fb->width * fb->height; k++) {
...@@ -327,7 +353,7 @@ static void debug_colormap(XImage *fb) { ...@@ -327,7 +353,7 @@ static void debug_colormap(XImage *fb) {
histo[n]++; histo[n]++;
} }
fprintf(stderr, "\nColormap histogram for current screen contents:\n"); fprintf(stderr, "\nColormap histogram for current screen contents:\n");
for (i=0; i < NCOLOR; i++) { for (i=0; i < ncolor; i++) {
unsigned short r = screen->colourMap.data.shorts[i*3+0]; unsigned short r = screen->colourMap.data.shorts[i*3+0];
unsigned short g = screen->colourMap.data.shorts[i*3+1]; unsigned short g = screen->colourMap.data.shorts[i*3+1];
unsigned short b = screen->colourMap.data.shorts[i*3+2]; unsigned short b = screen->colourMap.data.shorts[i*3+2];
...@@ -338,6 +364,7 @@ static void debug_colormap(XImage *fb) { ...@@ -338,6 +364,7 @@ static void debug_colormap(XImage *fb) {
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
} }
free(histo);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
...@@ -1931,12 +1958,38 @@ XImage *initialize_xdisplay_fb(void) { ...@@ -1931,12 +1958,38 @@ XImage *initialize_xdisplay_fb(void) {
if (xform24to32) { if (xform24to32) {
if (DefaultDepth(dpy, scr) == 24) { if (DefaultDepth(dpy, scr) == 24) {
vis_str = strdup("TrueColor:32"); vis_str = strdup("TrueColor:32");
rfbLog("initialize_xdisplay_fb: vis_str set to: %s ", rfbLog("initialize_xdisplay_fb: vis_str set to: %s\n",
vis_str); vis_str);
visual_id = (VisualID) 0; visual_id = (VisualID) 0;
visual_depth = 0; visual_depth = 0;
set_visual_str_to_something = 1; set_visual_str_to_something = 1;
} }
} else if (DefaultDepth(dpy, scr) < 8) {
/* check very low bpp case, e.g. mono or vga16 */
Screen *s = DefaultScreenOfDisplay(dpy);
XImage *xi = XGetImage_wr(dpy, DefaultRootWindow(dpy), 0, 0, 2, 2, AllPlanes,
ZPixmap);
if (xi && xi->bits_per_pixel < 8) {
int lowbpp = xi->bits_per_pixel;
if (!vis_str) {
char tmp[32];
sprintf(tmp, "0x%x:8", (int) s->root_visual->visualid);
vis_str = strdup(tmp);
rfbLog("initialize_xdisplay_fb: low bpp[%d], vis_str "
"set to: %s\n", lowbpp, vis_str);
}
if (using_shm) {
using_shm = 0;
rfbLog("initialize_xdisplay_fb: low bpp[%d], "
"disabling shm\n", lowbpp);
}
visual_id = (VisualID) 0;
visual_depth = 0;
set_visual_str_to_something = 1;
}
if (xi) {
XDestroyImage(xi);
}
} }
if (vis_str != NULL) { if (vis_str != NULL) {
...@@ -2420,13 +2473,13 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { ...@@ -2420,13 +2473,13 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
" bpp != 32 with depth == 24\n"); " bpp != 32 with depth == 24\n");
cmap8to24 = 0; cmap8to24 = 0;
} }
} else if (depth == 8) { } else if (depth <= 16) {
/* need to cook up the screen fb to be depth 24 */ /* need to cook up the screen fb to be depth 24 */
fb_bpp = 32; fb_bpp = 32;
fb_depth = 24; fb_depth = 24;
} else { } else {
if (!quiet) rfbLog("disabling -8to24 mode:" if (!quiet) rfbLog("disabling -8to24 mode:"
" default depth not 24 or 8\n"); " default depth not 16 or less\n");
cmap8to24 = 0; cmap8to24 = 0;
} }
} }
...@@ -2489,9 +2542,14 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { ...@@ -2489,9 +2542,14 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
} }
#endif #endif
if (cmap8to24 && depth == 8) { if (cmap8to24) {
if (depth <= 8) {
rfb_bytes_per_line *= 4; rfb_bytes_per_line *= 4;
rot_bytes_per_line *= 4; rot_bytes_per_line *= 4;
} else if (depth <= 16) {
rfb_bytes_per_line *= 2;
rot_bytes_per_line *= 2;
}
} }
/* /*
...@@ -2596,7 +2654,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { ...@@ -2596,7 +2654,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
have_masks = 0; have_masks = 0;
} }
if (cmap8to24 && depth == 8 && dpy) { if (cmap8to24 && depth <= 16 && dpy) {
XVisualInfo vinfo; XVisualInfo vinfo;
vinfo.red_mask = 0; vinfo.red_mask = 0;
vinfo.green_mask = 0; vinfo.green_mask = 0;
...@@ -2638,13 +2696,14 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { ...@@ -2638,13 +2696,14 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
free(fmt); free(fmt);
} }
if (! have_masks && screen->serverFormat.bitsPerPixel == 8 if (! have_masks && screen->serverFormat.bitsPerPixel <= 16
&& dpy && CellsOfScreen(ScreenOfDisplay(dpy, scr))) { && dpy && CellsOfScreen(ScreenOfDisplay(dpy, scr))) {
/* indexed color */ /* indexed color. we let 1 <= bpp <= 16, but it is normally 8 */
if (!quiet) { if (!quiet) {
rfbLog("\n"); rfbLog("\n");
rfbLog("X display %s is 8bpp indexed color\n", rfbLog("X display %s is %dbpp indexed color, depth=%d\n",
DisplayString(dpy)); DisplayString(dpy), screen->serverFormat.bitsPerPixel,
screen->serverFormat.depth);
if (! flash_cmap && ! overlay) { if (! flash_cmap && ! overlay) {
rfbLog("\n"); rfbLog("\n");
rfbLog("In 8bpp PseudoColor mode if you " rfbLog("In 8bpp PseudoColor mode if you "
...@@ -2656,6 +2715,18 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { ...@@ -2656,6 +2715,18 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
rfbLog("\n"); rfbLog("\n");
} }
} }
if (screen->serverFormat.depth < 8) {
rfbLog("resetting serverFormat.depth %d -> 8.\n",
screen->serverFormat.depth);
rfbLog("resetting serverFormat.bpp %d -> 8.\n",
screen->serverFormat.bitsPerPixel);
screen->serverFormat.depth = 8;
screen->serverFormat.bitsPerPixel = 8;
}
if (screen->serverFormat.depth > 8) {
rfbLog("WARNING: indexed color depth > 8, Tight encoding will crash.\n");
}
screen->serverFormat.trueColour = FALSE; screen->serverFormat.trueColour = FALSE;
indexed_color = 1; indexed_color = 1;
set_colormap(1); set_colormap(1);
...@@ -2688,6 +2759,29 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { ...@@ -2688,6 +2759,29 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
indexed_color = 0; indexed_color = 0;
if (!have_masks) {
int M, B = bits_per_color;
if (3*B > fb_bpp) B--;
if (B < 1) B = 1;
M = (1 << B) - 1;
rfbLog("WARNING: all TrueColor RGB masks are zero!\n");
rfbLog("WARNING: cooking something up for VNC fb... B=%d M=%d\n", B, M);
main_red_mask = M;
main_green_mask = M;
main_blue_mask = M;
main_red_mask = main_red_mask << (2*B);
main_green_mask = main_green_mask << (1*B);
main_blue_mask = main_blue_mask << (0*B);
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));
}
/* convert masks to bit shifts and max # colors */ /* convert masks to bit shifts and max # colors */
if (main_red_mask) { if (main_red_mask) {
while (! (main_red_mask while (! (main_red_mask
...@@ -2821,8 +2915,10 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { ...@@ -2821,8 +2915,10 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
if (cmap8to24) { if (cmap8to24) {
int n = main_bytes_per_line * fb->height; int n = main_bytes_per_line * fb->height;
if (depth == 8) { if (depth <= 8) {
n *= 4; n *= 4;
} else if (depth <= 16) {
n *= 2;
} }
cmap8to24_fb = (char *) malloc(n); cmap8to24_fb = (char *) malloc(n);
memset(cmap8to24_fb, 0, n); memset(cmap8to24_fb, 0, n);
......
...@@ -790,8 +790,10 @@ static void draw_box(int x, int y, int w, int h, int restore) { ...@@ -790,8 +790,10 @@ static void draw_box(int x, int y, int w, int h, int restore) {
if (cmap8to24 && cmap8to24_fb) { if (cmap8to24 && cmap8to24_fb) {
use_fb = cmap8to24_fb; use_fb = cmap8to24_fb;
pixelsize = 4; pixelsize = 4;
if (depth == 8) { if (depth <= 8) {
use_Bpl *= 4; use_Bpl *= 4;
} else if (depth <= 16) {
use_Bpl *= 2;
} }
} }
...@@ -1882,9 +1884,14 @@ if (0 || debug_scroll > 1) fprintf(stderr, "<<<-rfbDoCopyRect req: %d mod: %d cp ...@@ -1882,9 +1884,14 @@ if (0 || debug_scroll > 1) fprintf(stderr, "<<<-rfbDoCopyRect req: %d mod: %d cp
} }
} }
if (0) fprintf(stderr, "copyrect: cmap8to24_fb: mode=%d\n", mode); if (0) fprintf(stderr, "copyrect: cmap8to24_fb: mode=%d\n", mode);
if (cmap8to24 && depth == 8) { if (cmap8to24) {
if (depth <= 8) {
Bpp = 4 * Bpp0; Bpp = 4 * Bpp0;
stride = 4 * stride0; stride = 4 * stride0;
} else if (depth <= 16) {
Bpp = 2 * Bpp0;
stride = 2 * stride0;
}
} }
dst = cmap8to24_fb + y1*stride + x1*Bpp; dst = cmap8to24_fb + y1*stride + x1*Bpp;
src = cmap8to24_fb + (y1-dy)*stride + (x1-dx)*Bpp; src = cmap8to24_fb + (y1-dy)*stride + (x1-dx)*Bpp;
...@@ -3566,6 +3573,17 @@ void check_fixscreen(void) { ...@@ -3566,6 +3573,17 @@ void check_fixscreen(void) {
didfull = 1; didfull = 1;
} }
} }
if (advertise_truecolor && advertise_truecolor_reset && indexed_color) {
/* this will reset framebuffer to correct colors, if needed */
static dlast = 0.0;
now = dnow();
if (now > last_client + 1.0 && now < last_client + 3.0 && now > dlast + 5.0) {
rfbLog("advertise truecolor reset framebuffer\n");
do_new_fb(1);
dlast = dnow();
return;
}
}
} }
static int wireframe_mod_state() { static int wireframe_mod_state() {
...@@ -8083,8 +8101,12 @@ void scale_mark_xrootpmap(void) { ...@@ -8083,8 +8101,12 @@ void scale_mark_xrootpmap(void) {
if (cmap8to24 && cmap8to24_fb) { if (cmap8to24 && cmap8to24_fb) {
src_fb = cmap8to24_fb; src_fb = cmap8to24_fb;
if (scaling && depth == 8) { if (scaling) {
if (depth <= 8) {
fac = 4; fac = 4;
} else if (depth <= 16) {
fac = 2;
}
} }
} }
dst_fb = rfb_fb; dst_fb = rfb_fb;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.TH X11VNC "1" "May 2008" "x11vnc " "User Commands" .TH X11VNC "1" "May 2008" "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.9.4, lastmod: 2008-05-10 version: 0.9.4, lastmod: 2008-05-31
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
...@@ -161,6 +161,13 @@ a colormap histogram. Example: \fB-shiftcmap\fR 240 ...@@ -161,6 +161,13 @@ a colormap histogram. Example: \fB-shiftcmap\fR 240
For 8bpp displays, force indexed color (i.e. a colormap) For 8bpp displays, force indexed color (i.e. a colormap)
even if it looks like 8bpp TrueColor (rare problem). even if it looks like 8bpp TrueColor (rare problem).
.PP .PP
\fB-advertise_truecolor\fR
.IP
If the X11 display is indexed color, lie to clients
when they first connect by telling them it is truecolor.
To workaround RealVNC: inPF has colourMap but not 8bpp
Use '-advertise_truecolor reset' to reset client fb too.
.PP
\fB-visual\fR \fIn\fR \fB-visual\fR \fIn\fR
.IP .IP
This option probably does not do what you think. This option probably does not do what you think.
...@@ -172,8 +179,10 @@ Run ...@@ -172,8 +179,10 @@ Run
.IR xdpyinfo (1) .IR xdpyinfo (1)
for the values. One may also use for the values. One may also use
"TrueColor", etc. see <X11/X.h> for a list. If the "TrueColor", etc. see <X11/X.h> for a list. If the
string ends in ":m" then for better or for worse the string ends in ":m" then for better or for worse
visual depth is forced to be m. the visual depth is forced to be m. You may want to
use \fB-noshm\fR when using this option (so XGetImage may
automatically translate the pixel data).
.PP .PP
\fB-overlay\fR \fB-overlay\fR
.IP .IP
......
...@@ -2514,6 +2514,17 @@ int main(int argc, char* argv[]) { ...@@ -2514,6 +2514,17 @@ int main(int argc, char* argv[]) {
shift_cmap = atoi(argv[++i]); shift_cmap = atoi(argv[++i]);
} else if (!strcmp(arg, "-notruecolor")) { } else if (!strcmp(arg, "-notruecolor")) {
force_indexed_color = 1; force_indexed_color = 1;
} else if (!strcmp(arg, "-advertise_truecolor")) {
advertise_truecolor = 1;
if (i < argc-1) {
char *s = argv[i+1];
if (s[0] != '-') {
if (strstr(s, "reset")) {
advertise_truecolor_reset = 1;
}
i++;
}
}
} else if (!strcmp(arg, "-overlay")) { } else if (!strcmp(arg, "-overlay")) {
overlay = 1; overlay = 1;
} else if (!strcmp(arg, "-overlay_nocursor")) { } else if (!strcmp(arg, "-overlay_nocursor")) {
......
...@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0; ...@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0; int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.9.4 lastmod: 2008-05-10"; char lastmod[] = "0.9.4 lastmod: 2008-05-31";
/* X display info */ /* X display info */
......
...@@ -263,19 +263,19 @@ static void initialize_xinerama (void) { ...@@ -263,19 +263,19 @@ static void initialize_xinerama (void) {
rfbLog("\n"); rfbLog("\n");
rfbLog("Xinerama is present and active (e.g. multi-head).\n"); rfbLog("Xinerama is present and active (e.g. multi-head).\n");
if (! use_xwarppointer && ! got_noxwarppointer) {
rfbLog("Xinerama: enabling -xwarppointer mode to try to correct\n");
rfbLog("Xinerama: mouse pointer motion. XTEST+XINERAMA bug.\n");
rfbLog("Xinerama: Use -noxwarppointer to force XTEST.\n");
use_xwarppointer = 1;
}
/* n.b. change to XineramaGetData() someday */ /* n.b. change to XineramaGetData() someday */
xineramas = XineramaQueryScreens(dpy, &n); xineramas = XineramaQueryScreens(dpy, &n);
if (verbose) { if (verbose) {
rfbLog("Xinerama: number of sub-screens: %d\n", n); rfbLog("Xinerama: number of sub-screens: %d\n", n);
} }
if (! use_xwarppointer && ! got_noxwarppointer && n > 1) {
rfbLog("Xinerama: enabling -xwarppointer mode to try to correct\n");
rfbLog("Xinerama: mouse pointer motion. XTEST+XINERAMA bug.\n");
rfbLog("Xinerama: Use -noxwarppointer to force XTEST.\n");
use_xwarppointer = 1;
}
if (n == 1) { if (n == 1) {
if (verbose) { if (verbose) {
rfbLog("Xinerama: no blackouts needed (only one" rfbLog("Xinerama: no blackouts needed (only one"
......
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