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

pull/1/head
runge 19 years ago
parent e38c3c224b
commit 17e6b6a2bf

@ -6,13 +6,20 @@
#include "win_utils.h"
int multivis_count = 0;
int multivis_24count = 0;
void check_for_multivis(void);
void bpp8to24(int, int, int, int);
void mark_8bpp(void);
static void set_root_cmap(void);
static void check_pointer_in_depth24(void);
static int check_depth(Window win, Window top, int doall);
static int check_depth_win(Window win, Window top, XWindowAttributes attr);
static int get_8pp_region(sraRegionPtr region8bpp, sraRegionPtr rect,
int validate);
static int get_cmap(int j, Colormap cmap);
static void do_8bpp_region(sraRect rect);
/* struct for keeping info about the 8bpp windows: */
typedef struct window8 {
@ -27,12 +34,69 @@ typedef struct window8 {
int fetched;
} window8bpp_t;
static Colormap root_cmap = 0;
static void set_root_cmap(void) {
static time_t last_set = 0;
time_t now = time(0);
XWindowAttributes attr;
if (now > last_set + 5) {
root_cmap = 0;
}
if (! root_cmap) {
if (valid_window(window, &attr, 1)) {
last_set = now;
root_cmap = attr.colormap;
}
}
}
/* fixed size array. Will primarily hold visible 8bpp windows */
#define MAX_8BPP_WINDOWS 64
static window8bpp_t windows_8bpp[MAX_8BPP_WINDOWS];
static int db24 = 0;
static int xgetimage_8to24 = 0;
static int do_hibits = 0;
static void check_pointer_in_depth24(void) {
int tries = 0, in_24 = 0;
XWindowAttributes attr;
Window c, w;
double now = dnow();
c = window;
if (now > last_keyboard_time + 1.0 && now > last_pointer_time + 1.0) {
return;
}
X_LOCK;
while (c && tries++ < 3) {
c = query_pointer(c);
if (valid_window(c, &attr, 1)) {
if (attr.depth == 24) {
in_24 = 1;
break;
}
}
}
X_UNLOCK;
if (in_24) {
int x1, y1, x2, y2;
X_LOCK;
xtranslate(c, window, 0, 0, &x1, &y1, &w, 1);
X_UNLOCK;
x2 = x1 + attr.width;
y2 = y1 + attr.height;
x1 = nfix(x1, dpy_x);
y1 = nfix(y1, dpy_y);
x2 = nfix(x2, dpy_x);
y2 = nfix(y2, dpy_y);
if (db24 > 1) fprintf(stderr, "check_pointer_in_depth24 %d %d %d %d\n", x1, y1, x2, y2);
mark_rect_as_modified(x1, y1, x2, y2, 0);
}
}
void check_for_multivis(void) {
XWindowAttributes attr;
@ -61,9 +125,13 @@ void check_for_multivis(void) {
if (getenv("XGETIMAGE_8TO24") != NULL) {
xgetimage_8to24 = 1;
}
if (getenv("HIGHBITS_8TO24") != NULL) {
do_hibits = 1;
}
first = 0;
doall = 1; /* fetch everything first time */
}
set_root_cmap();
/*
* allocate an "old stack" list of all toplevels. we compare
@ -117,9 +185,17 @@ void check_for_multivis(void) {
if (diff && multivis_count) {
if (db24) fprintf(stderr, "check_for_multivis stack diff: mark_all %f\n", now - x11vnc_start);
mark_8bpp();
} else if (depth == 8 && multivis_24count) {
static double last_check = 0.0;
if (now > last_check + 0.25) {
last_check = now;
check_pointer_in_depth24();
}
}
multivis_count = 0;
multivis_24count = 0;
/*
* every 10 seconds we try to clean out and also refresh the window
@ -130,8 +206,8 @@ if (db24) fprintf(stderr, "check_for_multivis stack diff: mark_all %f\n", now -
X_LOCK;
for (i=0; i < MAX_8BPP_WINDOWS; i++) {
Window w = windows_8bpp[i].win;
if ((db24) && w != None) fprintf(stderr, " windows_8bpp: 0x%lx i=%02d ms: %d\n", windows_8bpp[i].win, i, windows_8bpp[i].map_state);
if (w == None || ! valid_window(w, &attr, 1)) {
if ((db24) && w != None) fprintf(stderr, " windows_8bpp: 0x%lx i=%02d ms: %d dep=%d\n", windows_8bpp[i].win, i, windows_8bpp[i].map_state, windows_8bpp[i].depth);
if (! valid_window(w, &attr, 1)) {
/* catch windows that went away: */
windows_8bpp[i].win = None;
windows_8bpp[i].top = None;
@ -252,18 +328,30 @@ static int check_depth(Window win, Window top, int doall) {
}
static int check_depth_win(Window win, Window top, XWindowAttributes attr) {
int store_it = 0;
/*
* only store windows with depth not equal to the default visual's depth
* note some windows can have depth == 0 ... (skip them).
*/
if (attr.depth != depth && attr.depth > 0) {
if (attr.depth > 0) {
set_root_cmap();
if (depth == 24 && attr.depth != 24) {
store_it = 1;
} else if (depth == 8 && root_cmap && attr.colormap !=
root_cmap) {
store_it = 1;
}
}
if (store_it) {
int i, j = -1, none = -1, nomap = -1;
int new = 0;
if (attr.map_state == IsViewable) {
/* count the visible ones: */
multivis_count++;
if (attr.depth == 24) {
multivis_24count++;
}
if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth);
}
@ -299,14 +387,19 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth);
/* otherwise we cannot store it... */
}
if (db24 > 1) fprintf(stderr, "multivis: 0x%lx ms: %d j: %d no: %d nm: %d\n", win, attr.map_state, j, none, nomap);
if (db24 > 1) fprintf(stderr, "multivis: 0x%lx ms: %d j: %d no: %d nm: %d dep=%d\n", win, attr.map_state, j, none, nomap, attr.depth);
/* store if if we found a slot j: */
if (j >= 0) {
Window w;
int x, y;
int now_vis = 0;
if (db24 > 1) fprintf(stderr, "multivis: STORE 0x%lx j: %3d ms: %d\n", win, j, attr.map_state);
if (attr.map_state == IsViewable &&
windows_8bpp[j].map_state != IsViewable) {
now_vis = 1;
}
if (db24 > 1) fprintf(stderr, "multivis: STORE 0x%lx j: %3d ms: %d dep=%d\n", win, j, attr.map_state, attr.depth);
windows_8bpp[j].win = win;
windows_8bpp[j].top = top;
windows_8bpp[j].depth = attr.depth;
@ -323,8 +416,8 @@ if (db24 > 1) fprintf(stderr, "multivis: STORE 0x%lx j: %3d ms: %d\n", win, j, a
windows_8bpp[j].fetched = 1;
if (new) {
if (db24) fprintf(stderr, "new: 0x%lx\n", win);
if (new || now_vis) {
if (db24) fprintf(stderr, "new/now_vis: 0x%lx %d/%d\n", win, new, now_vis);
/* mark it immediately if a new one: */
mark_rect_as_modified(x, y, x + attr.width,
y + attr.height, 0);
@ -345,76 +438,26 @@ if (db24 > 1) fprintf(stderr, " ------------ 0x%lx i=%d\n", windows_8bp
return 0;
}
void bpp8to24(int x1, int y1, int x2, int y2) {
char *src;
char *dst;
unsigned int *ui;
unsigned int hi, idx;
int ps, pixelsize = bpp/8;
int line, i, h, k, w;
# define CMAPMAX 64
Colormap cmaps[CMAPMAX];
int ncmaps, cmap_max = CMAPMAX;
sraRegionPtr rect, disp, region8bpp;
XWindowAttributes attr;
static int last_map_count = 0, call_count = 0;
static double last_validate = 0.0;
int validate = 1;
int histo[256];
#define CMAPMAX 64
Colormap cmaps[CMAPMAX];
int ncmaps;
if (! cmap8to24 || !cmap8to24_fb) {
/* hmmm, why were we called? */
return;
}
static int get_8pp_region(sraRegionPtr region8bpp, sraRegionPtr rect,
int validate) {
call_count++;
XWindowAttributes attr;
int i, k, mapcount = 0;
/* initialize color map list */
ncmaps = 0;
for (i=0; i < cmap_max; i++) {
for (i=0; i < CMAPMAX; i++) {
cmaps[i] = (Colormap) 0;
}
/* clip to display just in case: */
x1 = nfix(x1, dpy_x);
y1 = nfix(y1, dpy_y);
x2 = nfix(x2, dpy_x);
y2 = nfix(y2, dpy_y);
/* create regions for finding overlap, etc. */
disp = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
rect = sraRgnCreateRect(x1, y1, x2, y2);
region8bpp = sraRgnCreate();
X_LOCK;
XFlush(dpy); /* make sure X server is up to date WRT input, etc */
X_UNLOCK;
if (last_map_count > MAX_8BPP_WINDOWS/4) {
/* table is filling up... skip validating sometimes: */
int skip = 3;
if (last_map_count > MAX_8BPP_WINDOWS/2) {
skip = 6;
}
if (last_map_count > 3*MAX_8BPP_WINDOWS/4) {
skip = 12;
}
if (call_count % skip != 0) {
validate = 0;
if (db24) fprintf(stderr, " bpp8to24: No validate: %d -- %d\n", skip, last_map_count);
} else {
if (db24) fprintf(stderr, " bpp8to24: yesvalidate: %d -- %d\n", skip, last_map_count);
}
}
last_map_count = 0;
if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
/* loop over the table of 8bpp windows: */
for (i=0; i < MAX_8BPP_WINDOWS; i++) {
sraRegionPtr tmp_reg, tmp_reg2;
Window w = windows_8bpp[i].win;
Window c;
Window c, w = windows_8bpp[i].win;
int x, y;
if (wireframe_in_progress) {
@ -425,13 +468,12 @@ if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
continue;
}
if (db24 > 1) fprintf(stderr, "bpp8to24: 0x%lx ms=%d i=%d\n", w, windows_8bpp[i].map_state, i);
if (db24 > 1) fprintf(stderr, "get_8pp_region: 0x%lx ms=%d dep=%d i=%d\n", w, windows_8bpp[i].map_state, windows_8bpp[i].depth, i);
if (validate) {
/*
* this could be slow: validating 8bpp windows each
* time...
*/
last_validate = dnow();
X_LOCK;
if (! valid_window(w, &attr, 1)) {
@ -451,8 +493,9 @@ if (db24 > 1) fprintf(stderr, "bpp8to24: 0x%lx ms=%d i=%d\n", w, windows_8bpp[i]
X_LOCK;
xtranslate(w, window, 0, 0, &x, &y, &c, 1);
X_UNLOCK;
} else {
/* this would be faster: no call to X server: */
/* this will be faster: no call to X server: */
if (windows_8bpp[i].map_state != IsViewable) {
continue;
}
@ -463,17 +506,16 @@ if (db24 > 1) fprintf(stderr, "bpp8to24: 0x%lx ms=%d i=%d\n", w, windows_8bpp[i]
attr.map_state = windows_8bpp[i].map_state;
attr.colormap = windows_8bpp[i].cmap;
}
last_map_count++;
mapcount++;
/* tmp region for this 8bpp rectangle: */
tmp_reg = sraRgnCreateRect(nfix(x, dpy_x), nfix(y, dpy_y),
nfix(x + attr.width, dpy_x), nfix(y + attr.height, dpy_y));
/* clip to display screen: */
if (0) sraRgnAnd(tmp_reg, disp);
/* find overlap with mark region in rect: */
sraRgnAnd(tmp_reg, rect);
if (sraRgnEmpty(tmp_reg)) {
/* skip if no overlap: */
sraRgnDestroy(tmp_reg);
@ -485,7 +527,7 @@ if (db24 > 1) fprintf(stderr, "bpp8to24: 0x%lx ms=%d i=%d\n", w, windows_8bpp[i]
Window swin = stack_list[k].win;
int sx, sy, sw, sh;
if (db24 > 1) fprintf(stderr, "Stack win: 0x%lx %d iv=%d\n", swin, k, stack_list[k].map_state);
if (db24 > 1 && stack_list[k].map_state == IsViewable) fprintf(stderr, "Stack win: 0x%lx %d iv=%d\n", swin, k, stack_list[k].map_state);
if (swin == windows_8bpp[i].top) {
/* found our top level: we clip the rest. */
@ -503,10 +545,11 @@ if (db24 > 1) fprintf(stderr, "found top: 0x%lx %d iv=%d\n", swin, k, stack_list
sw = stack_list[k].width;
sh = stack_list[k].height;
if (db24 > 1) fprintf(stderr, "subtract: 0x%lx %d -- %d %d %d %d\n", swin, k, sx, sy, sw, sh);
tmp_reg2 = sraRgnCreateRect(nfix(sx, dpy_x),
nfix(sy, dpy_y), nfix(sx + sw, dpy_x),
nfix(sy + sh, dpy_y));
if (0) sraRgnAnd(tmp_reg2, disp);
/* subtract it from the 8bpp window region */
sraRgnSubtract(tmp_reg, tmp_reg2);
@ -521,7 +564,7 @@ if (db24 > 1) fprintf(stderr, "Empty tmp_reg\n");
}
/* otherwise, store any new colormaps: */
if (ncmaps < cmap_max && attr.colormap != (Colormap) 0) {
if (ncmaps < CMAPMAX && attr.colormap != (Colormap) 0) {
int m, sawit = 0;
for (m=0; m < ncmaps; m++) {
if (cmaps[m] == attr.colormap) {
@ -529,7 +572,7 @@ if (db24 > 1) fprintf(stderr, "Empty tmp_reg\n");
break;
}
}
if (! sawit) {
if (! sawit && attr.depth == 8) {
/* store only new ones: */
cmaps[ncmaps++] = attr.colormap;
}
@ -540,43 +583,29 @@ if (db24 > 1) fprintf(stderr, "Empty tmp_reg\n");
sraRgnDestroy(tmp_reg);
}
/* copy from main_fb to cmap8to24_fb regardless of 8bpp windows: */
src = main_fb + main_bytes_per_line * y1 + pixelsize * x1;
dst = cmap8to24_fb + main_bytes_per_line * y1 + pixelsize * x1;
h = y2 - y1;
w = x2 - x1;
for (line = 0; line < h; line++) {
memcpy(dst, src, w * pixelsize);
src += main_bytes_per_line;
dst += main_bytes_per_line;
}
if (db24 > 1) fprintf(stderr, "bpp8to24 w=%d h=%d m=%p c=%p r=%p \n", w, h, main_fb, cmap8to24_fb, rfb_fb);
return mapcount;
}
/*
* now go back and tranform and 8bpp regions to TrueColor in
* cmap8to24_fb. we have to guess the best colormap to use if
* there is more than one...
*/
#define NCOLOR 256
if (! sraRgnEmpty(region8bpp) && ncmaps) {
sraRectangleIterator *iter;
sraRect rect;
int i, j, ncells;
int cmap_failed[CMAPMAX];
static XColor color[CMAPMAX][NCOLOR];
static unsigned int rgb[CMAPMAX][NCOLOR];
static XColor color[CMAPMAX][NCOLOR];
static unsigned int rgb[CMAPMAX][NCOLOR];
static int cmap_failed[CMAPMAX];
int histo[256];
static int get_cmap(int j, Colormap cmap) {
int i, ncells;
XErrorHandler old_handler = NULL;
#if 0
if (0) {
/* not working properly for depth 24... */
X_LOCK;
ncells = CellsOfScreen(ScreenOfDisplay(dpy, scr));
X_UNLOCK;
#else
} else {
ncells = NCOLOR;
#endif
}
if (db24 > 1) fprintf(stderr, "get_cmap: %d 0x%x\n", j, (unsigned int) cmap);
/* ncells should "always" be 256. */
if (ncells > NCOLOR) {
ncells = NCOLOR;
@ -585,14 +614,6 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 w=%d h=%d m=%p c=%p r=%p \n", w, h, main
ncells = NCOLOR;
}
/*
* first, grab all of the associated colormaps from the
* X server. Hopefully just 1 or 2...
*/
for (j=0; j<ncmaps; j++) {
if (db24 > 1) fprintf(stderr, "cmap %d\n", (int) cmaps[j]);
/* initialize XColor array: */
for (i=0; i < ncells; i++) {
color[j][i].pixel = i;
@ -603,20 +624,15 @@ if (db24 > 1) fprintf(stderr, "cmap %d\n", (int) cmaps[j]);
X_LOCK;
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
XQueryColors(dpy, cmaps[j], color[j], ncells);
XQueryColors(dpy, cmap, color[j], ncells);
XSetErrorHandler(old_handler);
X_UNLOCK;
if (trapped_xerror) {
/*
* results below will be indefinite...
* need to exclude this one.
*/
trapped_xerror = 0;
cmap_failed[j] = 1;
continue;
return 0;
}
trapped_xerror = 0;
cmap_failed[j] = 0;
/* now map each index to depth 24 RGB */
for (i=0; i < ncells; i++) {
@ -634,7 +650,7 @@ if (db24 > 1) fprintf(stderr, "cmap %d\n", (int) cmaps[j]);
green = (main_green_max * green)/255;
blue = (main_blue_max * blue )/255;
if (db24 > 2) fprintf(stderr, " cmap[%02d][%03d]: %03d %03d %03d 0x%08lx \n", j, i, red, green, blue, ( red << main_red_shift | green << main_green_shift | blue << main_blue_shift));
if (db24 > 2) fprintf(stderr, " cmap[%02d][%03d]: %03d %03d %03d 0x%08x \n", j, i, red, green, blue, ( red << main_red_shift | green << main_green_shift | blue << main_blue_shift));
/* shift them over and or together for value */
red = red << main_red_shift;
@ -643,26 +659,26 @@ if (db24 > 2) fprintf(stderr, " cmap[%02d][%03d]: %03d %03d %03d 0x%08lx \n", j
rgb[j][i] = red | green | blue;
}
}
return 1;
}
static void do_8bpp_region(sraRect rect) {
char *src, *dst;
unsigned int *ui;
unsigned char *uc;
int ps, pixelsize = bpp/8;
int do_getimage = xgetimage_8to24;
int line, n_off, j, h, w;
unsigned int hi, idx;
XWindowAttributes attr;
XErrorHandler old_handler = NULL;
/* loop over the rectangles making up region8bpp */
iter = sraRgnGetIterator(region8bpp);
while (sraRgnIteratorNext(iter, &rect)) {
double score, max_score = -1.0;
int n, m, best;
int m, best, best_depth = 0;
Window best_win = None;
if (rect.x1 > rect.x2) {
int tmp = rect.x2;
rect.x2 = rect.x1;
rect.x1 = tmp;
}
if (rect.y1 > rect.y2) {
int tmp = rect.y2;
rect.y2 = rect.y1;
rect.y1 = tmp;
}
if (db24 > 1) fprintf(stderr, "ncmaps: %d\n", ncmaps);
/*
@ -684,12 +700,11 @@ if (db24 > 1) fprintf(stderr, "ncmaps: %d\n", ncmaps);
/* see if XQueryColors failed: */
for (k=0; k<ncmaps; k++) {
if (windows_8bpp[m].cmap == cmaps[k]
&& cmap_failed[k]) {
if (windows_8bpp[m].cmap == cmaps[k] && cmap_failed[k]) {
failed = 1;
}
}
if (failed) {
if (windows_8bpp[m].depth == 8 && failed) {
continue;
}
@ -700,15 +715,15 @@ if (db24 > 1) fprintf(stderr, "ncmaps: %d\n", ncmaps);
my2 = windows_8bpp[m].y + windows_8bpp[m].h;
/* use overlap as score: */
score = rect_overlap(mx1, my1, mx2, my2,
rect.x1, rect.y1, rect.x2, rect.y2);
score = rect_overlap(mx1, my1, mx2, my2, rect.x1, rect.y1,
rect.x2, rect.y2);
if (score > max_score) {
max_score = score;
best = m;
best_win = windows_8bpp[m].win;
best_depth = windows_8bpp[m].depth;
}
if (db24 > 1) fprintf(stderr, "cmap_score: 0x%x %.3f %.3f\n", (int) windows_8bpp[m].cmap, score, max_score);
}
@ -738,41 +753,48 @@ if (db24 > 1) fprintf(stderr, "cmap_score: 0x%x %.3f %.3f\n", (int) windows_8bpp
if (db24 > 1) fprintf(stderr, "transform %d %d %d %d\n", rect.x1, rect.y1, rect.x2, rect.y2);
/* now tranform the pixels in this rectangle: */
n = main_bytes_per_line * rect.y1 + pixelsize * rect.x1;
n_off = main_bytes_per_line * rect.y1 + pixelsize * rect.x1;
src = cmap8to24_fb + n;
h = rect.y2 - rect.y1;
w = rect.x2 - rect.x1;
if (xgetimage_8to24 && best_win != None &&
valid_window(best_win, &attr, 1)) {
/* experimental mode. */
if (depth == 8) {
/*
* need to fetch depth 24 data. might need for
* best_depth == 8 too... (hi | ... failure).
*/
if (best_depth == 24) {
do_getimage = 1;
} else if (! do_hibits) {
do_getimage = 1;
}
}
if (do_getimage && valid_window(best_win, &attr, 1)) {
XImage *xi;
Window c;
XErrorHandler old_handler = NULL;
unsigned int wu, hu;
int xo, yo;
ps = 1; /* assume 8bpp */
wu = (unsigned int) w;
hu = (unsigned int) h;
X_LOCK;
xtranslate(best_win, window, 0, 0, &xo, &yo,
&c, 1);
xtranslate(best_win, window, 0, 0, &xo, &yo, &c, 1);
xo = rect.x1 - xo;
yo = rect.y1 - yo;
if (db24 > 1) fprintf(stderr, "xywh: %d %d %d %d vs. %d %d\n", xo, yo, w, h, attr.width, attr.height);
if (xo < 0 || yo < 0 || w > attr.width ||
h > attr.height) {
if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
if (xo < 0 || yo < 0 || w > attr.width || h > attr.height) {
X_UNLOCK;
continue;
if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
return;
}
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
/* FIXME: XGetSubImage? */
xi = XGetImage(dpy, best_win, xo, yo, wu, hu,
AllPlanes, ZPixmap);
XSetErrorHandler(old_handler);
@ -780,51 +802,90 @@ if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
if (! xi || trapped_xerror) {
trapped_xerror = 0;
if (db24 > 1) fprintf(stderr, "xi-fail: 0x%p trap=%d %d %d %d %d\n", xi, trapped_xerror, xo, yo, w, h);
continue;
if (db24 > 1) fprintf(stderr, "xi-fail: 0x%p trap=%d %d %d %d %d\n", (void *)xi, trapped_xerror, xo, yo, w, h);
return;
} else {
if (db24 > 1) fprintf(stderr, "xi: 0x%p %d %d %d %d -- %d %d\n", xi, xo, yo, w, h, xi->width, xi->height);
if (db24 > 1) fprintf(stderr, "xi: 0x%p %d %d %d %d -- %d %d\n", (void *)xi, xo, yo, w, h, xi->width, xi->height);
}
trapped_xerror = 0;
if (xi->depth != 8) {
if (xi->depth != 8 && xi->depth != 24) {
X_LOCK;
XDestroyImage(xi);
X_UNLOCK;
if (db24) fprintf(stderr, "xi: wrong depth: %d\n", xi->depth);
continue;
return;
}
if (xi->depth == 8) {
int ps1, ps2, fac;
if (depth == 8) {
ps1 = 1;
ps2 = 4;
fac = 4;
} else {
ps1 = 1;
ps2 = pixelsize;
fac = 1;
}
dst = src;
src = xi->data;
dst = cmap8to24_fb + fac * n_off;
/* line by line ... */
for (line = 0; line < xi->height; line++) {
/* pixel by pixel... */
for (j = 0; j < xi->width; j++) {
unsigned char *uc;
uc = (unsigned char *) (src + ps * j);
ui = (unsigned int *) (dst+pixelsize*j);
uc = (unsigned char *) (src + ps1 * j);
ui = (unsigned int *) (dst + ps2 * j);
idx = (int) (*uc);
hi = (*ui) & 0xff000000;
*ui = hi | rgb[best][idx];
if (db24 > 2) histo[idx]++;
*ui = rgb[best][idx];
}
src += xi->bytes_per_line;
dst += main_bytes_per_line;
dst += main_bytes_per_line * fac;
}
} else if (xi->depth == 24) {
/* line by line ... */
int ps1 = 4, fac;
if (depth == 8) {
fac = 4;
} else {
fac = 1; /* should not happen */
}
src = xi->data;
dst = cmap8to24_fb + fac * n_off;
for (line = 0; line < xi->height; line++) {
memcpy(dst, src, w * ps1);
src += xi->bytes_per_line;
dst += main_bytes_per_line * fac;
}
}
X_LOCK;
XDestroyImage(xi);
X_UNLOCK;
} else if (! xgetimage_8to24) {
} else if (! do_getimage) {
/* normal mode. */
int fac;
if (depth == 8) {
/* cooked up depth 24 TrueColor */
ps = 4;
fac = 4;
src = cmap8to24_fb + 4 * n_off;
} else {
ps = pixelsize;
fac = 1;
src = cmap8to24_fb + n_off;
}
/* line by line ... */
for (line = 0; line < h; line++) {
@ -840,12 +901,162 @@ if (db24 > 2) histo[idx]++;
/* map to lookup index; rewrite pixel */
idx = hi >> 24;
*ui = hi | rgb[best][idx];
}
src += main_bytes_per_line * fac;
}
}
}
void bpp8to24(int x1, int y1, int x2, int y2) {
char *src, *dst;
unsigned char *uc;
unsigned int *ui;
unsigned int hi;
int idx, pixelsize = bpp/8;
int line, i, j, h, w;
int n_off;
sraRegionPtr rect, disp, region8bpp;
int validate = 1;
static int last_map_count = 0, call_count = 0;
if (! cmap8to24 || !cmap8to24_fb) {
/* hmmm, why were we called? */
return;
}
call_count++;
/* clip to display just in case: */
x1 = nfix(x1, dpy_x);
y1 = nfix(y1, dpy_y);
x2 = nfix(x2, dpy_x);
y2 = nfix(y2, dpy_y);
/* create regions for finding overlap, etc. */
disp = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
rect = sraRgnCreateRect(x1, y1, x2, y2);
region8bpp = sraRgnCreate();
X_LOCK;
XFlush(dpy); /* make sure X server is up to date WRT input, etc */
X_UNLOCK;
if (last_map_count > MAX_8BPP_WINDOWS/4) {
/* table is filling up... skip validating sometimes: */
int skip = 3;
if (last_map_count > MAX_8BPP_WINDOWS/2) {
skip = 6;
} else if (last_map_count > 3*MAX_8BPP_WINDOWS/4) {
skip = 12;
}
if (call_count % skip != 0) {
validate = 0;
}
}
if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
last_map_count = get_8pp_region(region8bpp, rect, validate);
/* copy from main_fb to cmap8to24_fb regardless of 8bpp windows: */
h = y2 - y1;
w = x2 - x1;
if (depth == 8) {
/* need to cook up to depth 24 TrueColor */
/* pixelsize = 1 */
n_off = main_bytes_per_line * y1 + pixelsize * x1;
src = main_fb + n_off;
dst = cmap8to24_fb + 4 * n_off;
set_root_cmap();
if (get_cmap(0, root_cmap)) {
int ps1 = 1, ps2 = 4;
/* line by line ... */
for (line = 0; line < h; line++) {
/* pixel by pixel... */
for (j = 0; j < w; j++) {
uc = (unsigned char *) (src + ps1 * j);
ui = (unsigned int *) (dst + ps2 * j);
idx = (int) (*uc);
if (do_hibits) {
hi = idx << 24;
*ui = hi | rgb[0][idx];
} else {
*ui = rgb[0][idx];
}
if (db24 > 2) histo[idx]++;
}
src += main_bytes_per_line;
dst += main_bytes_per_line * 4;
}
}
} else if (depth == 24) {
/* pixelsize = 4 */
n_off = main_bytes_per_line * y1 + pixelsize * x1;
src = main_fb + n_off;
dst = cmap8to24_fb + n_off;
/* otherwise, the pixel data as is */
for (line = 0; line < h; line++) {
memcpy(dst, src, w * pixelsize);
src += main_bytes_per_line;
dst += main_bytes_per_line;
}
}
if (db24 > 1) fprintf(stderr, "bpp8to24 w=%d h=%d m=%p c=%p r=%p ncmaps=%d\n", w, h, main_fb, cmap8to24_fb, rfb_fb, ncmaps);
/*
* now go back and tranform and 8bpp regions to TrueColor in
* cmap8to24_fb. we have to guess the best colormap to use if
* there is more than one...
*/
if (! sraRgnEmpty(region8bpp) && (ncmaps || depth == 8)) {
sraRectangleIterator *iter;
sraRect rect;
int j;
/*
* first, grab all of the associated colormaps from the
* X server. Hopefully just 1 or 2...
*/
for (j=0; j<ncmaps; j++) {
if (! get_cmap(j, cmaps[j])) {
cmap_failed[j] = 1;
} else {
cmap_failed[j] = 0;
}
if (db24 > 1) fprintf(stderr, "cmap %d\n", (int) cmaps[j]);
}
/* loop over the rectangles making up region8bpp */
iter = sraRgnGetIterator(region8bpp);
while (sraRgnIteratorNext(iter, &rect)) {
if (rect.x1 > rect.x2) {
int tmp = rect.x2;
rect.x2 = rect.x1;
rect.x1 = tmp;
}
if (rect.y1 > rect.y2) {
int tmp = rect.y2;
rect.y2 = rect.y1;
rect.y1 = tmp;
}
do_8bpp_region(rect);
}
sraRgnReleaseIterator(iter);
}
@ -868,14 +1079,27 @@ void mark_8bpp(void) {
for (i=0; i < MAX_8BPP_WINDOWS; i++) {
int x1, y1, x2, y2, w, h, f = 32;
f = 0; /* skip fuzz, may bring in other windows... */
if (windows_8bpp[i].win == None) {
continue;
}
if (windows_8bpp[i].map_state != IsViewable) {
XWindowAttributes attr;
int vw;
X_LOCK;
vw = valid_window(windows_8bpp[i].win, &attr, 1);
X_UNLOCK;
if (vw) {
if (attr.map_state != IsViewable) {
continue;
}
} else {
continue;
}
}
x1 = windows_8bpp[i].x;
y1 = windows_8bpp[i].y;

@ -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);

@ -1,3 +1,6 @@
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.

File diff suppressed because it is too large Load Diff

@ -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;
setup_scaling(&width, &height);
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,21 +1750,41 @@ 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;
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;
}
w = (x2 - x1)*Bpp;
if (dy < 0) {
for (j=y1; j<y2; j++) {
memmove(dst, src, w);
@ -1780,13 +1800,23 @@ if (debug_scroll > 1) fprintf(stderr, ">>>-rfbDoCopyRect req: %d mod: %d cpy: %d
src -= stride;
}
}
}
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 */

Loading…
Cancel
Save