summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--x11vnc/8to24.c420
-rw-r--r--x11vnc/ChangeLog3
-rw-r--r--x11vnc/README18
-rw-r--r--x11vnc/help.c12
-rw-r--r--x11vnc/win_utils.c15
-rw-r--r--x11vnc/x11vnc.114
-rw-r--r--x11vnc/x11vnc_defs.c2
7 files changed, 383 insertions, 101 deletions
diff --git a/x11vnc/8to24.c b/x11vnc/8to24.c
index bfe9292..88b923c 100644
--- a/x11vnc/8to24.c
+++ b/x11vnc/8to24.c
@@ -17,7 +17,7 @@ static int check_pointer_in_depth24(void);
static void parse_cmap8to24(void);
static void set_poll_fb(void);
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 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);
@@ -27,7 +27,7 @@ static void mark_rgn_rects(sraRegionPtr mod);
static int get_8bpp_regions(int validate);
static int get_cmap(int j, Colormap cmap);
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);
/* struct for keeping info about the 8bpp windows: */
@@ -41,6 +41,7 @@ typedef struct window8 {
Colormap cmap;
Bool map_installed;
int fetched;
+ double last_fetched;
sraRegionPtr clip_region;
} window8bpp_t;
@@ -50,21 +51,59 @@ enum mark_8bpp_modes {
MARK_8BPP_TOP
};
+#define NCOLOR 256
+
static Colormap root_cmap = 0;
+static unsigned int root_rgb[NCOLOR];
static void set_root_cmap(void) {
static time_t last_set = 0;
time_t now = time(0);
XWindowAttributes attr;
+ static XColor color[NCOLOR];
+ int redo = 0;
- if (now > last_set + 5) {
- root_cmap = 0;
+ if (now > last_set + 10) {
+ redo = 1;
}
- if (! root_cmap) {
+ if (! root_cmap || redo) {
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;
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;
}
@@ -77,6 +116,8 @@ static window8bpp_t windows_8bpp[MAX_8BPP_WINDOWS];
static int db24 = 0;
static int xgetimage_8to24 = 1;
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) {
int tries = 0, in_24 = 0;
@@ -129,13 +170,19 @@ static void parse_cmap8to24(void) {
db24 = 0;
xgetimage_8to24 = 1;
poll_8to24_delay = POLL_8TO24_DELAY;
+ level2_8to24 = 0;
+ cache_win = 0.0;
while (p) {
if (strstr(p, "dbg=") == p) {
db24 = atoi(p + strlen("dbg="));
} else if (strstr(p, "poll=") == p) {
poll_8to24_delay = atof(p + strlen("poll="));
+ } else if (strstr(p, "cachewin=") == p) {
+ cache_win = atof(p + strlen("cachewin="));
} else if (!strcmp(p, "nogetimage")) {
xgetimage_8to24 = 0;
+ } else if (!strcmp(p, "level2")) {
+ level2_8to24 = 1;
}
p = strtok(NULL, ",");
}
@@ -175,6 +222,11 @@ static void set_poll_fb(void) {
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) {
XWindowAttributes attr;
int doall = 0;
@@ -190,8 +242,9 @@ void check_for_multivis(void) {
static double last_call = 0.0;
static double last_query = 0.0;
double now = dnow();
+ double delay;
- if (now > last_parse + 0.75) {
+ if (now > last_parse + 1.0) {
last_parse = now;
parse_cmap8to24();
}
@@ -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].cmap = (Colormap) 0;
windows_8bpp[i].fetched = 0;
+ windows_8bpp[i].last_fetched = -1.0;
windows_8bpp[i].clip_region = NULL;
}
set_poll_fb();
@@ -215,6 +269,10 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
doall = 1; /* fetch everything first time */
}
+ if (wireframe_in_progress) {
+ return;
+ }
+
set_root_cmap();
/*
@@ -243,7 +301,13 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
}
/* 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);
update_stack_list();
last_update = now;
@@ -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].cmap = (Colormap) 0;
windows_8bpp[i].fetched = 0;
+ windows_8bpp[i].last_fetched = -1.0;
}
}
X_UNLOCK;
}
+ MV_count = 0;
+ MV_hit = 0;
+ MV_start = dnow();
+
+ set_root_cmap();
+
/* 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++) {
Window r, parent;
Window *list0;
Status rc;
unsigned int nc0;
int i1;
+ XErrorHandler old_handler;
+ double delay;
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;
}
@@ -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 */
- X_LOCK;
+
+ old_handler = XSetErrorHandler(trap_xerror);
+ trapped_xerror = 0;
rc = XQueryTree(dpy, win, &r, &parent, &list0, &nc0);
- X_UNLOCK;
- if (! rc) {
+ XSetErrorHandler(old_handler);
+
+ if (! rc || trapped_xerror) {
+ trapped_xerror = 0;
continue;
}
+ trapped_xerror = 0;
/* loop over grandchildren of rootwin: */
for (i1=0; i1 < (int) nc0; i1++) {
@@ -345,12 +433,22 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
if (check_depth(win1, win, doall)) {
continue;
}
- X_LOCK;
+
+ if (level2_8to24) {
+ continue;
+ }
+
+ old_handler = XSetErrorHandler(trap_xerror);
+ trapped_xerror = 0;
rc = XQueryTree(dpy, win1, &r, &parent, &list1, &nc1);
- X_UNLOCK;
- if (! rc) {
+ XSetErrorHandler(old_handler);
+
+ if (! rc || trapped_xerror) {
+ trapped_xerror = 0;
continue;
}
+ trapped_xerror = 0;
+
/* loop over great-grandchildren of rootwin: */
for (i2=0; i2< (int) nc1; i2++) {
Window win2 = list1[i2];
@@ -361,19 +459,20 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
/* more? Which wm does this? */
}
if (nc1) {
- X_LOCK;
XFree(list1);
- X_UNLOCK;
}
}
if (nc0) {
- X_LOCK;
XFree(list0);
- X_UNLOCK;
}
}
+ X_UNLOCK;
+
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) {
last_fixup = now;
mark_8bpp(MARK_8BPP_ALL);
@@ -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) {
- XWindowAttributes attr;
+ XWindowAttributes attr, *pattr;
- X_LOCK;
/* first see if it is (still) a valid window: */
- if (! valid_window(win, &attr, 1)) {
- X_UNLOCK;
- return 1; /* indicate done */
+MV_count++;
+
+ 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
* filling up, but currently this allows us to update
* state of onetime mapped windows.
*/
- check_depth_win(win, top, attr);
+ check_depth_win(win, top, pattr);
return 1; /* indicate done */
- } else if (check_depth_win(win, top, attr)) {
+ } else if (check_depth_win(win, top, pattr)) {
return 1; /* indicate done */
} else {
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;
/*
* 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 > 0) {
- set_root_cmap();
- if (depth == 24 && attr.depth != 24) {
+ if (attr->depth > 0) {
+ if (depth == 24 && attr->depth != 24) {
store_it = 1;
- } else if (depth == 8 && root_cmap && attr.colormap !=
+ } else if (depth == 8 && root_cmap && attr->colormap !=
root_cmap) {
store_it = 1;
}
@@ -462,13 +641,13 @@ static int check_depth_win(Window win, Window top, XWindowAttributes attr) {
if (store_it) {
int i, j = -1, none = -1, nomap = -1;
int new = 0;
- if (attr.map_state == IsViewable) {
+ if (attr->map_state == IsViewable) {
/* count the visible ones: */
multivis_count++;
- if (attr.depth == 24) {
+ if (attr->depth == 24) {
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: */
@@ -489,7 +668,7 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth);
}
}
if (j < 0) {
- if (attr.map_state != IsViewable) {
+ if (attr->map_state != IsViewable) {
/* no slot and not visible: not worth keeping */
return 1;
} else if (none >= 0) {
@@ -503,7 +682,7 @@ 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 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: */
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
int x, y;
int now_vis = 0;
- if (attr.map_state == IsViewable &&
+ 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);
+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;
- windows_8bpp[j].map_state = attr.map_state;
- windows_8bpp[j].cmap = attr.colormap;
- windows_8bpp[j].map_installed = attr.map_installed;
- windows_8bpp[j].w = attr.width;
- windows_8bpp[j].h = attr.height;
+ windows_8bpp[j].depth = attr->depth;
+ windows_8bpp[j].map_state = attr->map_state;
+ windows_8bpp[j].cmap = attr->colormap;
+ windows_8bpp[j].map_installed = attr->map_installed;
+ windows_8bpp[j].w = attr->width;
+ windows_8bpp[j].h = attr->height;
windows_8bpp[j].fetched = 1;
+ windows_8bpp[j].last_fetched = dnow();
/* translate x y to be WRT the root window (not parent) */
- X_LOCK;
xtranslate(win, window, 0, 0, &x, &y, &w, 1);
- X_UNLOCK;
windows_8bpp[j].x = x;
windows_8bpp[j].y = y;
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);
+ X_UNLOCK; /* dont forget the giant lock */
+ mark_rect_as_modified(x, y, x + attr->width,
+ y + attr->height, 0);
+ X_LOCK;
}
} else {
/*
@@ -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;
XErrorHandler old_handler = NULL;
- XWindowAttributes attr;
XImage *xi;
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;
int mx1, mx2, my1, my2;
int ns = NSCAN/2;
@@ -602,9 +786,17 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
}
X_LOCK;
- if (! valid_window(windows_8bpp[n].win, &attr, 1)) {
- X_UNLOCK;
- return 0;
+ now = dnow();
+ if (last_win != None && win == last_win && now < last_time + 0.5) {
+ ; /* 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) {
@@ -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;
}
- 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;
yo = y1 - yo;
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");
+ XSetErrorHandler(old_handler);
+ trapped_xerror = 0;
X_UNLOCK;
return 0;
}
trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
xi_r = XGetSubImage(dpy, win, xo, yo, w, 1, AllPlanes, ZPixmap, xi,
0, 0);
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,
windows_8bpp[i].map_state = IsUnmapped;
windows_8bpp[i].cmap = (Colormap) 0;
windows_8bpp[i].fetched = 0;
+ windows_8bpp[i].last_fetched = -1.0;
continue;
}
X_UNLOCK;
@@ -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].h = attr.height;
windows_8bpp[i].fetched = 1;
+ windows_8bpp[i].last_fetched = dnow();
if (attr.map_state != IsViewable) {
continue;
@@ -1053,7 +1253,6 @@ if (db24 > 1) fprintf(stderr, "subtract: 0x%lx %d -- %d %d %d %d\n", swin, k, s
return mapcount;
}
-#define NCOLOR 256
static XColor color[CMAPMAX][NCOLOR];
static unsigned int rgb[CMAPMAX][NCOLOR];
static int cmap_failed[CMAPMAX];
@@ -1188,19 +1387,26 @@ if (db24 > 1) fprintf(stderr, "ncmaps: %d\n", ncmaps);
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;
+
if (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);
} else if (win_depth == 24) {
d = (char *) malloc(dpy_x * dpy_y * 4);
} else {
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);
}
@@ -1214,7 +1420,7 @@ static void transform_rect(sraRect rect, Window win, int win_depth, int cm) {
int poll_Bpl;
int do_getimage = xgetimage_8to24;
- int line, n_off, j, h, w, vw;
+ int line, n_off, j, h, w;
unsigned int hi, idx;
XWindowAttributes attr;
XErrorHandler old_handler = NULL;
@@ -1232,6 +1438,7 @@ if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rec
do_getimage = 1;
}
+#if 0
if (do_getimage) {
X_LOCK;
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
}
if (do_getimage && vw) {
+#else
+ if (do_getimage) {
+#endif
static XImage *xi_8 = NULL;
static XImage *xi_24 = NULL;
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
hu = (unsigned int) h;
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
#ifdef GETSUBIMAGE
if (win_depth == 8) {
if (xi_8 == NULL || xi_8->width != dpy_x ||
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;
} else if (win_depth == 24) {
if (xi_24 == NULL || xi_24->width != dpy_x ||
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;
}
#endif
- trapped_xerror = 0;
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
xi = XGetImage(dpy, win, xo, yo, wu, hu, AllPlanes, ZPixmap);
xi_r = xi;
@@ -1427,15 +1643,15 @@ void bpp8to24(int x1, int y1, int x2, int y2) {
static int last_map_count = 0, call_count = 0;
static double last_get_8bpp_validate = 0.0;
static double last_snapshot = 0.0;
- double now, dt, d0;
+ double now;
+ double dt, d0 = 0.0, t2;
if (! cmap8to24 || ! cmap8to24_fb) {
/* hmmm, why were we called? */
return;
}
- now = dnow();
-if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now - last_get_8bpp_validate);
+if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, dnow() - last_get_8bpp_validate);
call_count++;
@@ -1453,10 +1669,6 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
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: */
h = y2 - y1;
@@ -1465,7 +1677,6 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
if (depth == 8) {
/* need to cook up to depth 24 TrueColor */
/* pixelsize = 1 */
- int tcm = CMAPMAX - 1;
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
dst = cmap8to24_fb + 4 * n_off;
set_root_cmap();
- if (get_cmap(tcm, root_cmap)) {
+ if (root_cmap) {
int ps1 = 1, ps2 = 4;
#if 0
unsigned int hi;
@@ -1496,7 +1707,7 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
} else {
}
#endif
- *ui = rgb[tcm][idx];
+ *ui = root_rgb[idx];
if (db24 > 2) histo[idx]++;
}
src += main_bytes_per_line;
@@ -1534,21 +1745,36 @@ if (db24 > 2) histo[idx]++;
if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
+ now = dnow();
dt = now - last_get_8bpp_validate;
- d0 = dnow();
- if (dt < 0.0025) {
+ /* TUNABLES */
+ if (dt < 0.003) {
; /* XXX does this still give painting errors? */
} else {
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;
}
if (last_map_count) {
- if (now > last_snapshot + 0.05) {
+ if (now > last_snapshot + delay2) {
snapit = 1;
}
} else {
- if (now > last_snapshot + 0.4) {
+ if (now > last_snapshot + delay3) {
snapit = 1;
}
}
@@ -1556,15 +1782,20 @@ if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
if (snapit) {
/* less problems if we update the stack frequently */
snapshot_stack_list(0, 0.0);
+if (0) fprintf(stderr, "SNAP time: %.4f\n", dnow() - now);
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);
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);
@@ -1630,6 +1861,7 @@ if (db24 > 2) fprintf(stderr, "cmap %d %.4f\n", (int) cmaps[j], dnow() - d0);
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]);}}
}
diff --git a/x11vnc/ChangeLog b/x11vnc/ChangeLog
index 8a5f81b..9b9f3c1 100644
--- a/x11vnc/ChangeLog
+++ b/x11vnc/ChangeLog
@@ -1,3 +1,6 @@
+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>
* x11vnc: -8to24 speedups and improvements.
diff --git a/x11vnc/README b/x11vnc/README
index a34b6bd..299e0fc 100644
--- a/x11vnc/README
+++ b/x11vnc/README
@@ -1,5 +1,5 @@
-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:
@@ -4898,7 +4898,7 @@ x11vnc: a VNC server for real X displays
Here are all of x11vnc command line options:
% 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:
-display disp -auth file
@@ -5009,7 +5009,7 @@ libvncserver-tight-extension options:
% 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:
@@ -5201,6 +5201,18 @@ Options:
"poll=t" where "t" is a floating point time.
(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
"dbg=1", "dbg=2", or "dbg=3".
diff --git a/x11vnc/help.c b/x11vnc/help.c
index 3a558cd..692276a 100644
--- a/x11vnc/help.c
+++ b/x11vnc/help.c
@@ -209,6 +209,18 @@ void print_help(int mode) {
" \"poll=t\" where \"t\" is a floating point time.\n"
" (default: %.2f)\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"
" \"dbg=1\", \"dbg=2\", or \"dbg=3\".\n"
"\n"
diff --git a/x11vnc/win_utils.c b/x11vnc/win_utils.c
index 327daae..aad1362 100644
--- a/x11vnc/win_utils.c
+++ b/x11vnc/win_utils.c
@@ -25,15 +25,25 @@ Window descend_pointer(int depth, Window start, char *name_info, int len);
Window parent_window(Window win, char **name) {
Window r, parent;
Window *list;
+ XErrorHandler old_handler;
unsigned int nchild;
+ int rc;
if (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;
}
+ trapped_xerror = 0;
+
if (list) {
XFree(list);
}
@@ -59,8 +69,8 @@ int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet) {
return 0;
}
- trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
+ trapped_xerror = 0;
if (XGetWindowAttributes(dpy, win, pattr)) {
ok = 1;
}
@@ -148,6 +158,7 @@ void snapshot_stack_list(int free_only, double allowed_age) {
last_free = now;
X_LOCK;
+ /* no need to trap error since rootwin */
rc = XQueryTree(dpy, rootwin, &r, &w, &list, &ui);
num = (int) ui;
diff --git a/x11vnc/x11vnc.1 b/x11vnc/x11vnc.1
index fb99e80..ca48b79 100644
--- a/x11vnc/x11vnc.1
+++ b/x11vnc/x11vnc.1
@@ -2,7 +2,7 @@
.TH X11VNC "1" "February 2006" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
- version: 0.8, lastmod: 2006-02-04
+ version: 0.8, lastmod: 2006-02-06
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@@ -241,6 +241,18 @@ non-default visual regions for changes, use the option
"poll=t" where "t" is a floating point time.
(default: 0.05)
.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
"dbg=1", "dbg=2", or "dbg=3".
.PP
diff --git a/x11vnc/x11vnc_defs.c b/x11vnc/x11vnc_defs.c
index d4bc860..a73b8e0 100644
--- a/x11vnc/x11vnc_defs.c
+++ b/x11vnc/x11vnc_defs.c
@@ -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-02-04";
+char lastmod[] = "0.8 lastmod: 2006-02-06";
/* X display info */