Commit 94b092cd authored by runge's avatar runge

x11vnc: -8to24 more speedups; tunables for very slow machines.

parent d0ef1285
...@@ -17,7 +17,7 @@ static int check_pointer_in_depth24(void); ...@@ -17,7 +17,7 @@ static int check_pointer_in_depth24(void);
static void parse_cmap8to24(void); static void parse_cmap8to24(void);
static void set_poll_fb(void); static void set_poll_fb(void);
static int check_depth(Window win, Window top, int doall); static int check_depth(Window win, Window top, int doall);
static int check_depth_win(Window win, Window top, XWindowAttributes attr); static int check_depth_win(Window win, Window top, XWindowAttributes *attr);
static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w); static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w);
static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod); static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod);
static void poll_line_complement(int x1, int x2, int y1, sraRegionPtr mod); static void poll_line_complement(int x1, int x2, int y1, sraRegionPtr mod);
...@@ -27,7 +27,7 @@ static void mark_rgn_rects(sraRegionPtr mod); ...@@ -27,7 +27,7 @@ static void mark_rgn_rects(sraRegionPtr mod);
static int get_8bpp_regions(int validate); static int get_8bpp_regions(int validate);
static int get_cmap(int j, Colormap cmap); static int get_cmap(int j, Colormap cmap);
static void do_8bpp_region(int n, sraRegionPtr mark); static void do_8bpp_region(int n, sraRegionPtr mark);
static XImage *cmap_xi(XImage *xi, Visual *visual, int win_depth); static XImage *cmap_xi(XImage *xi, Window win, int win_depth);
static void transform_rect(sraRect rect, Window win, int win_depth, int cm); static void transform_rect(sraRect rect, Window win, int win_depth, int cm);
/* struct for keeping info about the 8bpp windows: */ /* struct for keeping info about the 8bpp windows: */
...@@ -41,6 +41,7 @@ typedef struct window8 { ...@@ -41,6 +41,7 @@ typedef struct window8 {
Colormap cmap; Colormap cmap;
Bool map_installed; Bool map_installed;
int fetched; int fetched;
double last_fetched;
sraRegionPtr clip_region; sraRegionPtr clip_region;
} window8bpp_t; } window8bpp_t;
...@@ -50,21 +51,59 @@ enum mark_8bpp_modes { ...@@ -50,21 +51,59 @@ enum mark_8bpp_modes {
MARK_8BPP_TOP MARK_8BPP_TOP
}; };
#define NCOLOR 256
static Colormap root_cmap = 0; static Colormap root_cmap = 0;
static unsigned int root_rgb[NCOLOR];
static void set_root_cmap(void) { static void set_root_cmap(void) {
static time_t last_set = 0; static time_t last_set = 0;
time_t now = time(0); time_t now = time(0);
XWindowAttributes attr; XWindowAttributes attr;
static XColor color[NCOLOR];
int redo = 0;
if (now > last_set + 5) { if (now > last_set + 10) {
root_cmap = 0; redo = 1;
} }
if (! root_cmap) { if (! root_cmap || redo) {
X_LOCK; X_LOCK;
if (valid_window(window, &attr, 1)) { if (! valid_window(window, &attr, 1)) {
X_UNLOCK;
return;
}
if (attr.colormap) {
int i, ncells = NCOLOR;
for (i=0; i < ncells; i++) {
color[i].pixel = i;
color[i].pad = 0;
}
last_set = now; last_set = now;
root_cmap = attr.colormap; root_cmap = attr.colormap;
XQueryColors(dpy, root_cmap, color, ncells);
for (i=0; i < ncells; i++) {
unsigned int red, green, blue;
/* strip out highest 8 bits of values: */
red = (color[i].red & 0xff00) >> 8;
green = (color[i].green & 0xff00) >> 8;
blue = (color[i].blue & 0xff00) >> 8;
/*
* the maxes should be at 255 already,
* but just in case...
*/
red = (main_red_max * red )/255;
green = (main_green_max * green)/255;
blue = (main_blue_max * blue )/255;
/* shift them over and or together for value */
red = red << main_red_shift;
green = green << main_green_shift;
blue = blue << main_blue_shift;
/* store it in the array to be used later */
root_rgb[i] = red | green | blue;
}
} }
X_UNLOCK; X_UNLOCK;
} }
...@@ -77,6 +116,8 @@ static window8bpp_t windows_8bpp[MAX_8BPP_WINDOWS]; ...@@ -77,6 +116,8 @@ static window8bpp_t windows_8bpp[MAX_8BPP_WINDOWS];
static int db24 = 0; static int db24 = 0;
static int xgetimage_8to24 = 1; static int xgetimage_8to24 = 1;
static double poll_8to24_delay = POLL_8TO24_DELAY; static double poll_8to24_delay = POLL_8TO24_DELAY;
static double cache_win = 0.0;
static int level2_8to24 = 0;
static int check_pointer_in_depth24(void) { static int check_pointer_in_depth24(void) {
int tries = 0, in_24 = 0; int tries = 0, in_24 = 0;
...@@ -129,13 +170,19 @@ static void parse_cmap8to24(void) { ...@@ -129,13 +170,19 @@ static void parse_cmap8to24(void) {
db24 = 0; db24 = 0;
xgetimage_8to24 = 1; xgetimage_8to24 = 1;
poll_8to24_delay = POLL_8TO24_DELAY; poll_8to24_delay = POLL_8TO24_DELAY;
level2_8to24 = 0;
cache_win = 0.0;
while (p) { while (p) {
if (strstr(p, "dbg=") == p) { if (strstr(p, "dbg=") == p) {
db24 = atoi(p + strlen("dbg=")); db24 = atoi(p + strlen("dbg="));
} else if (strstr(p, "poll=") == p) { } else if (strstr(p, "poll=") == p) {
poll_8to24_delay = atof(p + strlen("poll=")); poll_8to24_delay = atof(p + strlen("poll="));
} else if (strstr(p, "cachewin=") == p) {
cache_win = atof(p + strlen("cachewin="));
} else if (!strcmp(p, "nogetimage")) { } else if (!strcmp(p, "nogetimage")) {
xgetimage_8to24 = 0; xgetimage_8to24 = 0;
} else if (!strcmp(p, "level2")) {
level2_8to24 = 1;
} }
p = strtok(NULL, ","); p = strtok(NULL, ",");
} }
...@@ -175,6 +222,11 @@ static void set_poll_fb(void) { ...@@ -175,6 +222,11 @@ static void set_poll_fb(void) {
pfb(1, &poll8_fb, &poll8_fb_w, &poll8_fb_h); pfb(1, &poll8_fb, &poll8_fb_w, &poll8_fb_h);
} }
int MV_glob = 0;
int MV_count;
int MV_hit;
double MV_start;
void check_for_multivis(void) { void check_for_multivis(void) {
XWindowAttributes attr; XWindowAttributes attr;
int doall = 0; int doall = 0;
...@@ -190,8 +242,9 @@ void check_for_multivis(void) { ...@@ -190,8 +242,9 @@ void check_for_multivis(void) {
static double last_call = 0.0; static double last_call = 0.0;
static double last_query = 0.0; static double last_query = 0.0;
double now = dnow(); double now = dnow();
double delay;
if (now > last_parse + 0.75) { if (now > last_parse + 1.0) {
last_parse = now; last_parse = now;
parse_cmap8to24(); parse_cmap8to24();
} }
...@@ -207,6 +260,7 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call); ...@@ -207,6 +260,7 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
windows_8bpp[i].map_state = IsUnmapped; windows_8bpp[i].map_state = IsUnmapped;
windows_8bpp[i].cmap = (Colormap) 0; windows_8bpp[i].cmap = (Colormap) 0;
windows_8bpp[i].fetched = 0; windows_8bpp[i].fetched = 0;
windows_8bpp[i].last_fetched = -1.0;
windows_8bpp[i].clip_region = NULL; windows_8bpp[i].clip_region = NULL;
} }
set_poll_fb(); set_poll_fb();
...@@ -215,6 +269,10 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call); ...@@ -215,6 +269,10 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
doall = 1; /* fetch everything first time */ doall = 1; /* fetch everything first time */
} }
if (wireframe_in_progress) {
return;
}
set_root_cmap(); set_root_cmap();
/* /*
...@@ -243,7 +301,13 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call); ...@@ -243,7 +301,13 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
} }
/* snapshot + update the current stacking order: */ /* snapshot + update the current stacking order: */
if (doall || now > last_update + 0.15) { /* TUNABLE */
if (poll_8to24_delay >= POLL_8TO24_DELAY) {
delay = 3.0 * poll_8to24_delay;
} else {
delay = 3.0 * POLL_8TO24_DELAY; /* 0.15 */
}
if (doall || now > last_update + delay) {
snapshot_stack_list(0, 0.0); snapshot_stack_list(0, 0.0);
update_stack_list(); update_stack_list();
last_update = now; last_update = now;
...@@ -282,22 +346,41 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call); ...@@ -282,22 +346,41 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
windows_8bpp[i].map_state = IsUnmapped; windows_8bpp[i].map_state = IsUnmapped;
windows_8bpp[i].cmap = (Colormap) 0; windows_8bpp[i].cmap = (Colormap) 0;
windows_8bpp[i].fetched = 0; windows_8bpp[i].fetched = 0;
windows_8bpp[i].last_fetched = -1.0;
} }
} }
X_UNLOCK; X_UNLOCK;
} }
MV_count = 0;
MV_hit = 0;
MV_start = dnow();
set_root_cmap();
/* loop over all toplevels, both 8 and 24 depths: */ /* loop over all toplevels, both 8 and 24 depths: */
X_LOCK; /* a giant lock around the whole activity */
for (k=0; k < stack_list_num; k++) { for (k=0; k < stack_list_num; k++) {
Window r, parent; Window r, parent;
Window *list0; Window *list0;
Status rc; Status rc;
unsigned int nc0; unsigned int nc0;
int i1; int i1;
XErrorHandler old_handler;
double delay;
Window win = stack_list[k].win; Window win = stack_list[k].win;
if (now < last_query + 0.05) { /* TUNABLE */
if (poll_8to24_delay >= POLL_8TO24_DELAY) {
delay = 1.5 * poll_8to24_delay;
} else {
delay = 1.5 * POLL_8TO24_DELAY; /* 0.075 */
}
if (now < last_query + delay) {
break; break;
} }
...@@ -328,12 +411,17 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call); ...@@ -328,12 +411,17 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
} }
/* we recurse up to two levels down from stack_list windows */ /* we recurse up to two levels down from stack_list windows */
X_LOCK;
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XQueryTree(dpy, win, &r, &parent, &list0, &nc0); rc = XQueryTree(dpy, win, &r, &parent, &list0, &nc0);
X_UNLOCK; XSetErrorHandler(old_handler);
if (! rc) {
if (! rc || trapped_xerror) {
trapped_xerror = 0;
continue; continue;
} }
trapped_xerror = 0;
/* loop over grandchildren of rootwin: */ /* loop over grandchildren of rootwin: */
for (i1=0; i1 < (int) nc0; i1++) { for (i1=0; i1 < (int) nc0; i1++) {
...@@ -345,12 +433,22 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call); ...@@ -345,12 +433,22 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
if (check_depth(win1, win, doall)) { if (check_depth(win1, win, doall)) {
continue; continue;
} }
X_LOCK;
if (level2_8to24) {
continue;
}
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XQueryTree(dpy, win1, &r, &parent, &list1, &nc1); rc = XQueryTree(dpy, win1, &r, &parent, &list1, &nc1);
X_UNLOCK; XSetErrorHandler(old_handler);
if (! rc) {
if (! rc || trapped_xerror) {
trapped_xerror = 0;
continue; continue;
} }
trapped_xerror = 0;
/* loop over great-grandchildren of rootwin: */ /* loop over great-grandchildren of rootwin: */
for (i2=0; i2< (int) nc1; i2++) { for (i2=0; i2< (int) nc1; i2++) {
Window win2 = list1[i2]; Window win2 = list1[i2];
...@@ -361,19 +459,20 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call); ...@@ -361,19 +459,20 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
/* more? Which wm does this? */ /* more? Which wm does this? */
} }
if (nc1) { if (nc1) {
X_LOCK;
XFree(list1); XFree(list1);
X_UNLOCK;
} }
} }
if (nc0) { if (nc0) {
X_LOCK;
XFree(list0); XFree(list0);
X_UNLOCK;
} }
} }
X_UNLOCK;
last_query = dnow(); last_query = dnow();
MV_glob += MV_count;
if (0) fprintf(stderr, "MV_count: %d hit: %d %.4f %10.2f\n", MV_count, MV_hit, last_query - MV_start, MV_glob / (last_query - x11vnc_start));
if (screen_fixup_8 > 0.0 && now > last_fixup + screen_fixup_8) { if (screen_fixup_8 > 0.0 && now > last_fixup + screen_fixup_8) {
last_fixup = now; last_fixup = now;
mark_8bpp(MARK_8BPP_ALL); mark_8bpp(MARK_8BPP_ALL);
...@@ -416,44 +515,124 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call); ...@@ -416,44 +515,124 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
} }
} }
} }
if (0) fprintf(stderr, "done: %.4f\n", dnow() - last_query);
}
#define VW_CACHE_MAX 1024
static XWindowAttributes vw_cache_attr[VW_CACHE_MAX];
static Window vw_cache_win[VW_CACHE_MAX];
static void set_attr(XWindowAttributes *attr, int j) {
memcpy((void *) (vw_cache_attr+j), (void *) attr,
sizeof(XWindowAttributes));
}
#if 0
static int get_attr(XWindowAttributes *attr, int j) {
memcpy((void *) attr, (void *) (vw_cache_attr+j),
sizeof(XWindowAttributes));
return 1;
}
#endif
static XWindowAttributes wattr;
static XWindowAttributes *vw_lookup(Window win) {
static double last_purge = 0.0;
double now;
int i, j, k;
if (win == None) {
return NULL;
}
now = dnow();
if (now > last_purge + cache_win) {
last_purge = now;
for (i=0; i<VW_CACHE_MAX; i++) {
vw_cache_win[i] = None;
}
}
j = -1;
k = -1;
for (i=0; i<VW_CACHE_MAX; i++) {
if (vw_cache_win[i] == win) {
j = i;
break;
} else if (vw_cache_win[i] == None) {
k = i;
break;
}
}
if (j >= 0) {
MV_hit++;
return vw_cache_attr+j;
} else if (k >= 0) {
XWindowAttributes attr2;
int rc = valid_window(win, &attr2, 1);
if (rc) {
vw_cache_win[k] = win;
set_attr(&attr2, k);
return vw_cache_attr+k;
} else {
return NULL;
}
} else {
/* Full */
int rc = valid_window(win, &wattr, 1);
if (rc) {
return &wattr;
} else {
return NULL;
}
}
} }
static int check_depth(Window win, Window top, int doall) { static int check_depth(Window win, Window top, int doall) {
XWindowAttributes attr; XWindowAttributes attr, *pattr;
X_LOCK;
/* first see if it is (still) a valid window: */ /* first see if it is (still) a valid window: */
if (! valid_window(win, &attr, 1)) { MV_count++;
X_UNLOCK;
return 1; /* indicate done */ if (cache_win > 0.0) {
pattr = vw_lookup(win);
if (pattr == NULL) {
return 1; /* indicate done */
}
} else {
if (! valid_window(win, &attr, 1)) {
return 1; /* indicate done */
}
pattr = &attr;
} }
X_UNLOCK;
if (! doall && attr.map_state != IsViewable) { if (! doall && pattr->map_state != IsViewable) {
/* /*
* store results anyway... this may lead to table * store results anyway... this may lead to table
* filling up, but currently this allows us to update * filling up, but currently this allows us to update
* state of onetime mapped windows. * state of onetime mapped windows.
*/ */
check_depth_win(win, top, attr); check_depth_win(win, top, pattr);
return 1; /* indicate done */ return 1; /* indicate done */
} else if (check_depth_win(win, top, attr)) { } else if (check_depth_win(win, top, pattr)) {
return 1; /* indicate done */ return 1; /* indicate done */
} else { } else {
return 0; /* indicate not done */ return 0; /* indicate not done */
} }
} }
static int check_depth_win(Window win, Window top, XWindowAttributes attr) { static int check_depth_win(Window win, Window top, XWindowAttributes *attr) {
int store_it = 0; int store_it = 0;
/* /*
* only store windows with depth not equal to the default visual's * only store windows with depth not equal to the default visual's
* depth note some windows can have depth == 0 ... (skip them). * depth note some windows can have depth == 0 ... (skip them).
*/ */
if (attr.depth > 0) { if (attr->depth > 0) {
set_root_cmap(); if (depth == 24 && attr->depth != 24) {
if (depth == 24 && attr.depth != 24) {
store_it = 1; store_it = 1;
} else if (depth == 8 && root_cmap && attr.colormap != } else if (depth == 8 && root_cmap && attr->colormap !=
root_cmap) { root_cmap) {
store_it = 1; store_it = 1;
} }
...@@ -462,13 +641,13 @@ static int check_depth_win(Window win, Window top, XWindowAttributes attr) { ...@@ -462,13 +641,13 @@ static int check_depth_win(Window win, Window top, XWindowAttributes attr) {
if (store_it) { if (store_it) {
int i, j = -1, none = -1, nomap = -1; int i, j = -1, none = -1, nomap = -1;
int new = 0; int new = 0;
if (attr.map_state == IsViewable) { if (attr->map_state == IsViewable) {
/* count the visible ones: */ /* count the visible ones: */
multivis_count++; multivis_count++;
if (attr.depth == 24) { if (attr->depth == 24) {
multivis_24count++; multivis_24count++;
} }
if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth); if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr->depth);
} }
/* try to find a table slot for this window: */ /* try to find a table slot for this window: */
...@@ -489,7 +668,7 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth); ...@@ -489,7 +668,7 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth);
} }
} }
if (j < 0) { if (j < 0) {
if (attr.map_state != IsViewable) { if (attr->map_state != IsViewable) {
/* no slot and not visible: not worth keeping */ /* no slot and not visible: not worth keeping */
return 1; return 1;
} else if (none >= 0) { } else if (none >= 0) {
...@@ -503,7 +682,7 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth); ...@@ -503,7 +682,7 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth);
/* otherwise we cannot store it... */ /* otherwise we cannot store it... */
} }
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); 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: */ /* store if if we found a slot j: */
if (j >= 0) { if (j >= 0) {
...@@ -511,33 +690,34 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx ms: %d j: %d no: %d nm: %d dep=%d ...@@ -511,33 +690,34 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx ms: %d j: %d no: %d nm: %d dep=%d
int x, y; int x, y;
int now_vis = 0; int now_vis = 0;
if (attr.map_state == IsViewable && if (attr->map_state == IsViewable &&
windows_8bpp[j].map_state != IsViewable) { windows_8bpp[j].map_state != IsViewable) {
now_vis = 1; 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); 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].win = win;
windows_8bpp[j].top = top; windows_8bpp[j].top = top;
windows_8bpp[j].depth = attr.depth; windows_8bpp[j].depth = attr->depth;
windows_8bpp[j].map_state = attr.map_state; windows_8bpp[j].map_state = attr->map_state;
windows_8bpp[j].cmap = attr.colormap; windows_8bpp[j].cmap = attr->colormap;
windows_8bpp[j].map_installed = attr.map_installed; windows_8bpp[j].map_installed = attr->map_installed;
windows_8bpp[j].w = attr.width; windows_8bpp[j].w = attr->width;
windows_8bpp[j].h = attr.height; windows_8bpp[j].h = attr->height;
windows_8bpp[j].fetched = 1; windows_8bpp[j].fetched = 1;
windows_8bpp[j].last_fetched = dnow();
/* translate x y to be WRT the root window (not parent) */ /* translate x y to be WRT the root window (not parent) */
X_LOCK;
xtranslate(win, window, 0, 0, &x, &y, &w, 1); xtranslate(win, window, 0, 0, &x, &y, &w, 1);
X_UNLOCK;
windows_8bpp[j].x = x; windows_8bpp[j].x = x;
windows_8bpp[j].y = y; windows_8bpp[j].y = y;
if (new || now_vis) { if (new || now_vis) {
if (db24) fprintf(stderr, "new/now_vis: 0x%lx %d/%d\n", win, 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 it immediately if a new one: */
mark_rect_as_modified(x, y, x + attr.width, X_UNLOCK; /* dont forget the giant lock */
y + attr.height, 0); mark_rect_as_modified(x, y, x + attr->width,
y + attr->height, 0);
X_LOCK;
} }
} else { } else {
/* /*
...@@ -583,10 +763,14 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) { ...@@ -583,10 +763,14 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
static int xi8_w = 0, xi24_w = 0; static int xi8_w = 0, xi24_w = 0;
XErrorHandler old_handler = NULL; XErrorHandler old_handler = NULL;
XWindowAttributes attr;
XImage *xi; XImage *xi;
Window c, win = windows_8bpp[n].win; Window c, win = windows_8bpp[n].win;
static XWindowAttributes attr;
static Window last_win = None;
static double last_time = 0.0;
double now;
sraRegionPtr rect; sraRegionPtr rect;
int mx1, mx2, my1, my2; int mx1, mx2, my1, my2;
int ns = NSCAN/2; int ns = NSCAN/2;
...@@ -602,9 +786,17 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) { ...@@ -602,9 +786,17 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
} }
X_LOCK; X_LOCK;
if (! valid_window(windows_8bpp[n].win, &attr, 1)) { now = dnow();
X_UNLOCK; if (last_win != None && win == last_win && now < last_time + 0.5) {
return 0; ; /* use previous attr */
} else {
if (! valid_window(win, &attr, 1)) {
X_UNLOCK;
last_win = None;
return 0;
}
last_time = now;
last_win = win;
} }
if (attr.depth != 8 && attr.depth != 24) { if (attr.depth != 8 && attr.depth != 24) {
...@@ -624,19 +816,25 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) { ...@@ -624,19 +816,25 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
n_off = poll24_fb_w * y1 + x1; n_off = poll24_fb_w * y1 + x1;
} }
xtranslate(win, window, 0, 0, &xo, &yo, &c, 1); old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
/* xtranslate() not used to save two XSetErrorHandler calls */
XTranslateCoordinates(dpy, win, window, 0, 0, &xo, &yo, &c);
xo = x1 - xo; xo = x1 - xo;
yo = y1 - yo; yo = y1 - yo;
w = x2 - x1; w = x2 - x1;
if (xo < 0 || yo < 0 || xo + w > attr.width) { if (trapped_xerror || xo < 0 || yo < 0 || xo + w > attr.width) {
if (db24 > 2) fprintf(stderr, "avoid bad match...\n"); if (db24 > 2) fprintf(stderr, "avoid bad match...\n");
XSetErrorHandler(old_handler);
trapped_xerror = 0;
X_UNLOCK; X_UNLOCK;
return 0; return 0;
} }
trapped_xerror = 0; trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
xi_r = XGetSubImage(dpy, win, xo, yo, w, 1, AllPlanes, ZPixmap, xi, xi_r = XGetSubImage(dpy, win, xo, yo, w, 1, AllPlanes, ZPixmap, xi,
0, 0); 0, 0);
XSetErrorHandler(old_handler); XSetErrorHandler(old_handler);
...@@ -943,6 +1141,7 @@ if (db24 > 1) fprintf(stderr, "get_8bpp_regions: 0x%lx ms=%d dep=%d i=%d\n", w, ...@@ -943,6 +1141,7 @@ if (db24 > 1) fprintf(stderr, "get_8bpp_regions: 0x%lx ms=%d dep=%d i=%d\n", w,
windows_8bpp[i].map_state = IsUnmapped; windows_8bpp[i].map_state = IsUnmapped;
windows_8bpp[i].cmap = (Colormap) 0; windows_8bpp[i].cmap = (Colormap) 0;
windows_8bpp[i].fetched = 0; windows_8bpp[i].fetched = 0;
windows_8bpp[i].last_fetched = -1.0;
continue; continue;
} }
X_UNLOCK; X_UNLOCK;
...@@ -954,6 +1153,7 @@ if (db24 > 1) fprintf(stderr, "get_8bpp_regions: 0x%lx ms=%d dep=%d i=%d\n", w, ...@@ -954,6 +1153,7 @@ if (db24 > 1) fprintf(stderr, "get_8bpp_regions: 0x%lx ms=%d dep=%d i=%d\n", w,
windows_8bpp[i].w = attr.width; windows_8bpp[i].w = attr.width;
windows_8bpp[i].h = attr.height; windows_8bpp[i].h = attr.height;
windows_8bpp[i].fetched = 1; windows_8bpp[i].fetched = 1;
windows_8bpp[i].last_fetched = dnow();
if (attr.map_state != IsViewable) { if (attr.map_state != IsViewable) {
continue; continue;
...@@ -1053,7 +1253,6 @@ if (db24 > 1) fprintf(stderr, "subtract: 0x%lx %d -- %d %d %d %d\n", swin, k, s ...@@ -1053,7 +1253,6 @@ if (db24 > 1) fprintf(stderr, "subtract: 0x%lx %d -- %d %d %d %d\n", swin, k, s
return mapcount; return mapcount;
} }
#define NCOLOR 256
static XColor color[CMAPMAX][NCOLOR]; static XColor color[CMAPMAX][NCOLOR];
static unsigned int rgb[CMAPMAX][NCOLOR]; static unsigned int rgb[CMAPMAX][NCOLOR];
static int cmap_failed[CMAPMAX]; static int cmap_failed[CMAPMAX];
...@@ -1188,19 +1387,26 @@ if (db24 > 1) fprintf(stderr, "ncmaps: %d\n", ncmaps); ...@@ -1188,19 +1387,26 @@ if (db24 > 1) fprintf(stderr, "ncmaps: %d\n", ncmaps);
sraRgnDestroy(clip); sraRgnDestroy(clip);
} }
static XImage *cmap_xi(XImage *xi, Visual *visual, int win_depth) { static XImage *cmap_xi(XImage *xi, Window win, int win_depth) {
XWindowAttributes attr;
char *d; char *d;
if (xi) { if (xi) {
XDestroyImage(xi); XDestroyImage(xi);
} }
if (win_depth == 8) { if (! valid_window(win, &attr, 1)) {
return (XImage *) NULL;
}
if (attr.depth != win_depth) {
return (XImage *) NULL;
} else if (win_depth == 8) {
d = (char *) malloc(dpy_x * dpy_y * 1); d = (char *) malloc(dpy_x * dpy_y * 1);
} else if (win_depth == 24) { } else if (win_depth == 24) {
d = (char *) malloc(dpy_x * dpy_y * 4); d = (char *) malloc(dpy_x * dpy_y * 4);
} else { } else {
return (XImage *) NULL; return (XImage *) NULL;
} }
return XCreateImage(dpy, visual, win_depth, ZPixmap, 0, d, dpy_x, return XCreateImage(dpy, attr.visual, win_depth, ZPixmap, 0, d, dpy_x,
dpy_y, 8, 0); dpy_y, 8, 0);
} }
...@@ -1214,7 +1420,7 @@ static void transform_rect(sraRect rect, Window win, int win_depth, int cm) { ...@@ -1214,7 +1420,7 @@ static void transform_rect(sraRect rect, Window win, int win_depth, int cm) {
int poll_Bpl; int poll_Bpl;
int do_getimage = xgetimage_8to24; int do_getimage = xgetimage_8to24;
int line, n_off, j, h, w, vw; int line, n_off, j, h, w;
unsigned int hi, idx; unsigned int hi, idx;
XWindowAttributes attr; XWindowAttributes attr;
XErrorHandler old_handler = NULL; XErrorHandler old_handler = NULL;
...@@ -1232,6 +1438,7 @@ if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rec ...@@ -1232,6 +1438,7 @@ if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rec
do_getimage = 1; do_getimage = 1;
} }
#if 0
if (do_getimage) { if (do_getimage) {
X_LOCK; X_LOCK;
vw = valid_window(win, &attr, 1); vw = valid_window(win, &attr, 1);
...@@ -1239,6 +1446,9 @@ if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rec ...@@ -1239,6 +1446,9 @@ if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rec
} }
if (do_getimage && vw) { if (do_getimage && vw) {
#else
if (do_getimage) {
#endif
static XImage *xi_8 = NULL; static XImage *xi_8 = NULL;
static XImage *xi_24 = NULL; static XImage *xi_24 = NULL;
XImage *xi = NULL, *xi_r; XImage *xi = NULL, *xi_r;
...@@ -1250,37 +1460,43 @@ if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rec ...@@ -1250,37 +1460,43 @@ if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rec
hu = (unsigned int) h; hu = (unsigned int) h;
X_LOCK; X_LOCK;
xtranslate(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) {
X_UNLOCK;
if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
return;
}
#define GETSUBIMAGE #define GETSUBIMAGE
#ifdef GETSUBIMAGE #ifdef GETSUBIMAGE
if (win_depth == 8) { if (win_depth == 8) {
if (xi_8 == NULL || xi_8->width != dpy_x || if (xi_8 == NULL || xi_8->width != dpy_x ||
xi_8->height != dpy_y) { xi_8->height != dpy_y) {
xi_8 = cmap_xi(xi_8, attr.visual, attr.depth); xi_8 = cmap_xi(xi_8, win, 8);
} }
xi = xi_8; xi = xi_8;
} else if (win_depth == 24) { } else if (win_depth == 24) {
if (xi_24 == NULL || xi_24->width != dpy_x || if (xi_24 == NULL || xi_24->width != dpy_x ||
xi_24->height != dpy_y) { xi_24->height != dpy_y) {
xi_24 = cmap_xi(xi_24, attr.visual, attr.depth); xi_24 = cmap_xi(xi_24, win, 24);
} }
xi = xi_24; xi = xi_24;
} }
#endif #endif
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror); old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
XTranslateCoordinates(dpy, win, window, 0, 0, &xo, &yo, &c);
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 (trapped_xerror || xo < 0 || yo < 0) {
/* w > attr.width || h > attr.height */
XSetErrorHandler(old_handler);
X_UNLOCK;
trapped_xerror = 0;
if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
return;
}
trapped_xerror = 0;
#ifndef GETSUBIMAGE #ifndef GETSUBIMAGE
xi = XGetImage(dpy, win, xo, yo, wu, hu, AllPlanes, ZPixmap); xi = XGetImage(dpy, win, xo, yo, wu, hu, AllPlanes, ZPixmap);
xi_r = xi; xi_r = xi;
...@@ -1427,15 +1643,15 @@ void bpp8to24(int x1, int y1, int x2, int y2) { ...@@ -1427,15 +1643,15 @@ void bpp8to24(int x1, int y1, int x2, int y2) {
static int last_map_count = 0, call_count = 0; static int last_map_count = 0, call_count = 0;
static double last_get_8bpp_validate = 0.0; static double last_get_8bpp_validate = 0.0;
static double last_snapshot = 0.0; static double last_snapshot = 0.0;
double now, dt, d0; double now;
double dt, d0 = 0.0, t2;
if (! cmap8to24 || ! cmap8to24_fb) { if (! cmap8to24 || ! cmap8to24_fb) {
/* hmmm, why were we called? */ /* hmmm, why were we called? */
return; return;
} }
now = dnow(); if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, dnow() - last_get_8bpp_validate);
if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now - last_get_8bpp_validate);
call_count++; call_count++;
...@@ -1453,10 +1669,6 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now ...@@ -1453,10 +1669,6 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
return; return;
} }
X_LOCK;
XFlush(dpy); /* make sure X server is up to date WRT input, etc */
X_UNLOCK;
/* copy from main_fb to cmap8to24_fb regardless of 8bpp windows: */ /* copy from main_fb to cmap8to24_fb regardless of 8bpp windows: */
h = y2 - y1; h = y2 - y1;
...@@ -1465,7 +1677,6 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now ...@@ -1465,7 +1677,6 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
if (depth == 8) { if (depth == 8) {
/* need to cook up to depth 24 TrueColor */ /* need to cook up to depth 24 TrueColor */
/* pixelsize = 1 */ /* pixelsize = 1 */
int tcm = CMAPMAX - 1;
n_off = main_bytes_per_line * y1 + pixelsize * x1; n_off = main_bytes_per_line * y1 + pixelsize * x1;
...@@ -1473,7 +1684,7 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now ...@@ -1473,7 +1684,7 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
dst = cmap8to24_fb + 4 * n_off; dst = cmap8to24_fb + 4 * n_off;
set_root_cmap(); set_root_cmap();
if (get_cmap(tcm, root_cmap)) { if (root_cmap) {
int ps1 = 1, ps2 = 4; int ps1 = 1, ps2 = 4;
#if 0 #if 0
unsigned int hi; unsigned int hi;
...@@ -1496,7 +1707,7 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now ...@@ -1496,7 +1707,7 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
} else { } else {
} }
#endif #endif
*ui = rgb[tcm][idx]; *ui = root_rgb[idx];
if (db24 > 2) histo[idx]++; if (db24 > 2) histo[idx]++;
} }
src += main_bytes_per_line; src += main_bytes_per_line;
...@@ -1534,21 +1745,36 @@ if (db24 > 2) histo[idx]++; ...@@ -1534,21 +1745,36 @@ if (db24 > 2) histo[idx]++;
if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}} if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
now = dnow();
dt = now - last_get_8bpp_validate; dt = now - last_get_8bpp_validate;
d0 = dnow(); /* TUNABLES */
if (dt < 0.0025) { if (dt < 0.003) {
; /* XXX does this still give painting errors? */ ; /* XXX does this still give painting errors? */
} else { } else {
int snapit = 0; int snapit = 0;
if (dt < 0.04) { double delay1, delay2, delay3;
if (poll_8to24_delay >= POLL_8TO24_DELAY) {
delay1 = 1.0 * poll_8to24_delay;
delay2 = 2.0 * poll_8to24_delay;
delay3 = 10. * poll_8to24_delay;
} else {
delay1 = 1.0 * POLL_8TO24_DELAY; /* 0.05 */
delay2 = 2.0 * POLL_8TO24_DELAY; /* 0.1 */
delay3 = 10. * POLL_8TO24_DELAY; /* 0.5 */
}
if (cache_win > 1.0) {
delay2 *= 2;
delay3 *= 2;
}
if (dt < delay1) {
validate = 0; validate = 0;
} }
if (last_map_count) { if (last_map_count) {
if (now > last_snapshot + 0.05) { if (now > last_snapshot + delay2) {
snapit = 1; snapit = 1;
} }
} else { } else {
if (now > last_snapshot + 0.4) { if (now > last_snapshot + delay3) {
snapit = 1; snapit = 1;
} }
} }
...@@ -1556,15 +1782,20 @@ if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}} ...@@ -1556,15 +1782,20 @@ if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
if (snapit) { if (snapit) {
/* less problems if we update the stack frequently */ /* less problems if we update the stack frequently */
snapshot_stack_list(0, 0.0); snapshot_stack_list(0, 0.0);
if (0) fprintf(stderr, "SNAP time: %.4f\n", dnow() - now);
update_stack_list(); update_stack_list();
last_snapshot = now; last_snapshot = dnow();
if (0) fprintf(stderr, "UPDA time: %.4f\n", last_snapshot - now);
} }
if (0) t2 = dnow();
last_map_count = get_8bpp_regions(validate); last_map_count = get_8bpp_regions(validate);
if (validate) { if (validate) {
last_get_8bpp_validate = now; last_get_8bpp_validate = dnow();
} }
if (0) fprintf(stderr, "get8bpp-%d: %.4f\n", validate, dnow() - t2);
} }
if (db24) d0 = dnow();
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); 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);
...@@ -1630,6 +1861,7 @@ if (db24 > 2) fprintf(stderr, "cmap %d %.4f\n", (int) cmaps[j], dnow() - d0); ...@@ -1630,6 +1861,7 @@ if (db24 > 2) fprintf(stderr, "cmap %d %.4f\n", (int) cmaps[j], dnow() - d0);
sraRgnDestroy(rect); sraRgnDestroy(rect);
} }
} }
if (0) fprintf(stderr, "done time: %.4f\n", dnow() - d0);
if (db24 > 2) {for(i=0; i<256;i++) {fprintf(stderr, " cmap histo[%03d] %d\n", i, histo[i]);}} if (db24 > 2) {for(i=0; i<256;i++) {fprintf(stderr, " cmap histo[%03d] %d\n", i, histo[i]);}}
} }
......
2006-02-06 Karl Runge <runge@karlrunge.com>
* x11vnc: -8to24 more speedups; tunables for very slow machines.
2006-02-04 Karl Runge <runge@karlrunge.com> 2006-02-04 Karl Runge <runge@karlrunge.com>
* x11vnc: -8to24 speedups and improvements. * x11vnc: -8to24 speedups and improvements.
......
x11vnc README file Date: Sat Feb 4 22:21:00 EST 2006 x11vnc README file Date: Mon Feb 6 00:16:18 EST 2006
The following information is taken from these URLs: The following information is taken from these URLs:
...@@ -4898,7 +4898,7 @@ x11vnc: a VNC server for real X displays ...@@ -4898,7 +4898,7 @@ x11vnc: a VNC server for real X displays
Here are all of x11vnc command line options: Here are all of x11vnc command line options:
% x11vnc -opts (see below for -help long descriptions) % x11vnc -opts (see below for -help long descriptions)
x11vnc: allow VNC connections to real X11 displays. 0.8 lastmod: 2006-02-04 x11vnc: allow VNC connections to real X11 displays. 0.8 lastmod: 2006-02-06
x11vnc options: x11vnc options:
-display disp -auth file -display disp -auth file
...@@ -5009,7 +5009,7 @@ libvncserver-tight-extension options: ...@@ -5009,7 +5009,7 @@ libvncserver-tight-extension options:
% x11vnc -help % x11vnc -help
x11vnc: allow VNC connections to real X11 displays. 0.8 lastmod: 2006-02-04 x11vnc: allow VNC connections to real X11 displays. 0.8 lastmod: 2006-02-06
Typical usage is: Typical usage is:
...@@ -5201,6 +5201,18 @@ Options: ...@@ -5201,6 +5201,18 @@ Options:
"poll=t" where "t" is a floating point time. "poll=t" where "t" is a floating point time.
(default: 0.05) (default: 0.05)
Setting the option "level2" will limit the search
for non-default visual windows to two levels from the
root window. Do this on slow machines where you know
the window manager only imposes one extra window between
the app window and the root window.
Also for very slow machines use "cachewin=t"
where t is a floating point amount of time to cache
XGetWindowAttributes results. E.g. cachewin=5.0.
This may lead to the windows being unnoticed for this
amount of time when deiconifying, painting errors, etc.
Debugging for this mode can be enabled by setting Debugging for this mode can be enabled by setting
"dbg=1", "dbg=2", or "dbg=3". "dbg=1", "dbg=2", or "dbg=3".
......
...@@ -209,6 +209,18 @@ void print_help(int mode) { ...@@ -209,6 +209,18 @@ void print_help(int mode) {
" \"poll=t\" where \"t\" is a floating point time.\n" " \"poll=t\" where \"t\" is a floating point time.\n"
" (default: %.2f)\n" " (default: %.2f)\n"
"\n" "\n"
" Setting the option \"level2\" will limit the search\n"
" for non-default visual windows to two levels from the\n"
" root window. Do this on slow machines where you know\n"
" the window manager only imposes one extra window between\n"
" the app window and the root window.\n"
"\n"
" Also for very slow machines use \"cachewin=t\"\n"
" where t is a floating point amount of time to cache\n"
" XGetWindowAttributes results. E.g. cachewin=5.0.\n"
" This may lead to the windows being unnoticed for this\n"
" amount of time when deiconifying, painting errors, etc.\n"
"\n"
" Debugging for this mode can be enabled by setting \n" " Debugging for this mode can be enabled by setting \n"
" \"dbg=1\", \"dbg=2\", or \"dbg=3\".\n" " \"dbg=1\", \"dbg=2\", or \"dbg=3\".\n"
"\n" "\n"
......
...@@ -25,15 +25,25 @@ Window descend_pointer(int depth, Window start, char *name_info, int len); ...@@ -25,15 +25,25 @@ Window descend_pointer(int depth, Window start, char *name_info, int len);
Window parent_window(Window win, char **name) { Window parent_window(Window win, char **name) {
Window r, parent; Window r, parent;
Window *list; Window *list;
XErrorHandler old_handler;
unsigned int nchild; unsigned int nchild;
int rc;
if (name != NULL) { if (name != NULL) {
*name = NULL; *name = NULL;
} }
if (! XQueryTree(dpy, win, &r, &parent, &list, &nchild)) { old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XQueryTree(dpy, win, &r, &parent, &list, &nchild);
XSetErrorHandler(old_handler);
if (! rc || trapped_xerror) {
trapped_xerror = 0;
return None; return None;
} }
trapped_xerror = 0;
if (list) { if (list) {
XFree(list); XFree(list);
} }
...@@ -59,8 +69,8 @@ int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet) { ...@@ -59,8 +69,8 @@ int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet) {
return 0; return 0;
} }
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror); old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
if (XGetWindowAttributes(dpy, win, pattr)) { if (XGetWindowAttributes(dpy, win, pattr)) {
ok = 1; ok = 1;
} }
...@@ -148,6 +158,7 @@ void snapshot_stack_list(int free_only, double allowed_age) { ...@@ -148,6 +158,7 @@ void snapshot_stack_list(int free_only, double allowed_age) {
last_free = now; last_free = now;
X_LOCK; X_LOCK;
/* no need to trap error since rootwin */
rc = XQueryTree(dpy, rootwin, &r, &w, &list, &ui); rc = XQueryTree(dpy, rootwin, &r, &w, &list, &ui);
num = (int) ui; num = (int) ui;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.TH X11VNC "1" "February 2006" "x11vnc " "User Commands" .TH X11VNC "1" "February 2006" "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.8, lastmod: 2006-02-04 version: 0.8, lastmod: 2006-02-06
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
...@@ -241,6 +241,18 @@ non-default visual regions for changes, use the option ...@@ -241,6 +241,18 @@ non-default visual regions for changes, use the option
"poll=t" where "t" is a floating point time. "poll=t" where "t" is a floating point time.
(default: 0.05) (default: 0.05)
.IP .IP
Setting the option "level2" will limit the search
for non-default visual windows to two levels from the
root window. Do this on slow machines where you know
the window manager only imposes one extra window between
the app window and the root window.
.IP
Also for very slow machines use "cachewin=t"
where t is a floating point amount of time to cache
XGetWindowAttributes results. E.g. cachewin=5.0.
This may lead to the windows being unnoticed for this
amount of time when deiconifying, painting errors, etc.
.IP
Debugging for this mode can be enabled by setting Debugging for this mode can be enabled by setting
"dbg=1", "dbg=2", or "dbg=3". "dbg=1", "dbg=2", or "dbg=3".
.PP .PP
......
...@@ -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.8 lastmod: 2006-02-04"; char lastmod[] = "0.8 lastmod: 2006-02-06";
/* X display info */ /* 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