diff options
-rw-r--r-- | x11vnc/README | 55 | ||||
-rw-r--r-- | x11vnc/options.c | 2 | ||||
-rw-r--r-- | x11vnc/userinput.c | 574 | ||||
-rw-r--r-- | x11vnc/winattr_t.h | 2 | ||||
-rw-r--r-- | x11vnc/x11vnc.1 | 2 | ||||
-rw-r--r-- | x11vnc/x11vnc.h | 4 | ||||
-rw-r--r-- | x11vnc/x11vnc_defs.c | 6 | ||||
-rw-r--r-- | x11vnc/xdamage.c | 13 |
8 files changed, 430 insertions, 228 deletions
diff --git a/x11vnc/README b/x11vnc/README index 4fb66ed..c907518 100644 --- a/x11vnc/README +++ b/x11vnc/README @@ -1,5 +1,5 @@ -x11vnc README file Date: Wed Jan 3 19:10:56 EST 2007 +x11vnc README file Date: Sun Jan 7 12:08:49 EST 2007 The following information is taken from these URLs: @@ -4171,6 +4171,52 @@ ied) (rare problem). + Example for the KDE desktop: + + Launch the "KDE Control Center" utility. Sometimes this is called + "Personal Settings". + + Select "Desktop". + + Then Select "Window Behavior". In the "Moving" Tab set these: + * YES - Display content in moving windows + * YES - Display content in resizing windows + * NO - Display window geometry when moving or resizing + * NO - Animate minimize and restore + + In the "Translucency" Tab set: + * NO - Use translucency/shadows + + Next hit "Back" and then select "Panels". + + In the "Appearance" Tab set: + * NO - Enable icon mouseover effects + * NO - Enable transparency + + Now go all the way back up to the top and Select "Appearance & + Themes". + + Select "Background" and set: + * YES - No picture + * Colors: Single Color + + Select "Fonts" and disable anti-aliased fonts if you are bold enough. + + Select "Launch Feedback" and set: + * Busy Cursor: No Busy Cursor + * NO - Enable taskbar notification + + Select "Screen Saver" and set: + * Screen Saver: Blank Screen + + Select "Style" and in the "Effects" Tab set: + * NO - Enable GUI effects + + + Example for the GNOME desktop: + * TBD. + + Q-64: Does x11vnc support the X DAMAGE Xserver extension to find modified regions of the screen quickly and efficiently? @@ -5436,7 +5482,8 @@ EndSection "-nodpms" option to keep the Monitor out of low power state while VNC clients are connected. This is basically the same as typing "xset dpms force on" periodically. (if you don't want to do these things just - disable the screensaver). + disable the screensaver). Feel free to file a bug against + kdesktop_lock with KDE. Q-97: Can I use x11vnc to view my VMWare session remotely? @@ -9272,7 +9319,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.4 lastmod: 2007-01-03 +x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2007-01-07 x11vnc options: -display disp -auth file -id windowid @@ -9379,7 +9426,7 @@ libvncserver-tight-extension options: % x11vnc -help -x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2007-01-03 +x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2007-01-07 (type "x11vnc -opts" to just list the options.) diff --git a/x11vnc/options.c b/x11vnc/options.c index fcb1961..72d7de1 100644 --- a/x11vnc/options.c +++ b/x11vnc/options.c @@ -195,7 +195,7 @@ int wireframe_in_progress = 0; int wireframe_local = 1; #ifndef NCACHE -#define NCACHE -10 +#define NCACHE -12 #endif #ifdef MACOSX int ncache = 0; diff --git a/x11vnc/userinput.c b/x11vnc/userinput.c index 7ee7db3..3626ac3 100644 --- a/x11vnc/userinput.c +++ b/x11vnc/userinput.c @@ -2040,7 +2040,9 @@ void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double de } rfbReleaseClientIterator(i); -fprintf(stderr, "batch_copyregion: nrects: %d nregions: %d dt=%.4f\n", nrects, ncr, dnow() - start); + last_copyrect = dnow(); + +fprintf(stderr, "batch_copyregion: nrects: %d nregions: %d dt=%.4f %.4f\n", nrects, ncr, dnow() - start, dnowx()); } @@ -4183,7 +4185,7 @@ fprintf(stderr, "--YES, wf_raise\n"); nb = &nr; } valid = 1; - bs_restore(idx, nb, &attr, 0, 1, &valid, 1); + bs_restore(idx, nb, NULL, &attr, 0, 1, &valid, 1); try_to_fix_su(orig_frame, idx, 0x1, nb, NULL); if (nb && nr) { batch_push(nr, -1.0); @@ -4690,7 +4692,7 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n"); } if (doit) { - if (try_copyrect_drag) { + if (try_copyrect_drag && ncache > 0) { if (!ncache_copyrect) { do_copyrect_drag = 0; } else if (w != box_w || h != box_h) { @@ -4722,7 +4724,9 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n"); } if (do_copyrect_drag <= 0) { - if (!drew_box && ncache_wf_raises) { + if (ncache <= 0) { + ; + } else if (!drew_box && ncache_wf_raises) { Window fr = orig_frame; int idx = lookup_win_index(fr); if (idx < 0) { @@ -5935,7 +5939,9 @@ int lookup_old_stack_index(int ic) { cache_list[k].su_h = -1; \ cache_list[k].time = 0.0; \ cache_list[k].bs_time = 0.0; \ - cache_list[k].su_time = 0.0; + cache_list[k].su_time = 0.0; \ + cache_list[k].vis_obs_time = 0.0; \ + cache_list[k].vis_unobs_time = 0.0; #define DELETE(k) \ if (0) fprintf(stderr, "DELETE(%d) = 0x%x\n", k, cache_list[k].win); \ @@ -6234,10 +6240,41 @@ void expire_rects2(int idx, int w, int h, int *x_hit, int *y_hit, int big1, int int do_expire = 1; int do_force = 1; double now = dnow(), r; + double newest = -1.0, oldest = -1.0, basetime; + double map_factor = 0.25; + + for (i=0; i<cache_list_num; i++) { + double d, d1, d2; + + d1 = cache_list[i].bs_time; + d2 = cache_list[i].su_time; + + d = d1; + if (d2 > d) d = d2; + + if (d == 0.0) { + continue; + } + + if (oldest == -1.0 || d < oldest) { + oldest = d; + } + if (newest == -1.0 || d > newest) { + newest = d; + } + } + if (newest == -1.0) { + newest = now; + } + if (oldest == -1.0) { + oldest = newest - 1800; + } + + basetime = newest + 0.1 * (newest - oldest); if (do_expire) { int old[10], N = 4; - double dold[10], fa, d, d1, d2, d3; + double dold[10], fa, d, d1, d2; int a0 = w * h, a1; for (k=1; k<=N; k++) { @@ -6270,13 +6307,12 @@ void expire_rects2(int idx, int w, int h, int *x_hit, int *y_hit, int big1, int if (k < 1) k = 1; if (k > N) continue; - d1 = cache_list[i].time; - d2 = cache_list[i].bs_time; - d3 = cache_list[i].su_time; + d1 = cache_list[i].bs_time; + d2 = cache_list[i].su_time; d = d1; if (d2 > d) d = d2; - if (d3 > d) d = d3; + if (d == 0.0) d = oldest; if (dold[k] == -1.0 || d < dold[k]) { old[k] = i; @@ -6290,10 +6326,13 @@ void expire_rects2(int idx, int w, int h, int *x_hit, int *y_hit, int big1, int int k_w = cache_list[ik].bs_w; int k_h = cache_list[ik].bs_h; - wgt[nwgt] = (now - dold[k]) / (k_w * k_h); + wgt[nwgt] = (basetime - dold[k]) / (k_w * k_h); + if (cache_list[ik].map_state == IsViewable) { + wgt[nwgt] *= map_factor; + } type[nwgt] = Expire; val[0][nwgt] = ik; -fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 10000 * wgt[nwgt], now - dold[k], k_w * k_h, w*h); +fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 10000 * wgt[nwgt], basetime - dold[k], k_w * k_h, w*h); nwgt++; if (nwgt >= nwgt_max) { break; @@ -6319,8 +6358,8 @@ fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 1 continue; } for (corner_y = 0; corner_y < 2; corner_y++) { - double age = 0.0, area = 0.0, a; - double d, d1, d2, d3, score; + double age = 0.0, area = 0.0, amap = 0.0, a; + double d, d1, d2, score; int nc = 0; x0 = 0; @@ -6336,6 +6375,7 @@ fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 1 r1 = sraRgnCreateRect(x0, y0, x0+w, y0+h); for (i=0; i<cache_list_num; i++) { + double top; int xb = cache_list[i].bs_x; int yb = cache_list[i].bs_y; int wb = cache_list[i].bs_w; @@ -6357,23 +6397,28 @@ fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 1 a = wb * hb; - d1 = cache_list[i].time; - d2 = cache_list[i].bs_time; - d3 = cache_list[i].su_time; + d1 = cache_list[i].bs_time; + d2 = cache_list[i].su_time; d = d1; if (d2 > d) d = d2; - if (d3 > d) d = d3; + if (d == 0.0) d = oldest; + if (cache_list[i].map_state == IsViewable) { + amap += a; + } area += a; - age += (now - d) * a; + age += (basetime - d) * a; nc++; } if (nc == 0) { score = 999999.9; } else { + double fac; age = age / area; score = age / area; + fac = 1.0 * (1.0 - amap/area) + map_factor * (amap/area); + score *= fac; } wgt[nwgt] = score; @@ -6381,7 +6426,7 @@ fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 1 val[0][nwgt] = n; val[1][nwgt] = x0; val[2][nwgt] = y0; -fprintf(stderr, "Force [%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 10000 * wgt[nwgt], age, (int) area, w*h); +fprintf(stderr, "Force [%02d] %9.5f age=%9.4f area=%8d amap=%8d need=%8d\n", nwgt, 10000 * wgt[nwgt], age, (int) area, (int) amap, w*h); nwgt++; if (nwgt >= nwgt_max) break; sraRgnDestroy(r1); @@ -6987,8 +7032,8 @@ if (verb) fprintf(stderr, "BS_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d // if (!novalidate) { // STORE(idx, win, attr); // } - cache_list[idx].bs_time = dnow(); - + last_bs_save = cache_list[idx].bs_time = dnow(); + return 1; } @@ -7087,12 +7132,12 @@ if (verb) fprintf(stderr, "SU_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d // if (!novalidate) { // STORE(idx, win, attr); // } - cache_list[idx].su_time = dnow(); + last_su_save = cache_list[idx].su_time = dnow(); return 1; } -int bs_restore(int idx, int *nbatch, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) { +int bs_restore(int idx, int *nbatch, sraRegionPtr rmask, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) { Window win = cache_list[idx].win; int x1, y1, w1, h1; int x2, y2, w2, h2; @@ -7178,6 +7223,9 @@ fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win); if (clip) { clip_region(r, win); } + if (rmask != NULL) { + sraRgnAnd(r, rmask); + } dtA = dnowx(); if (verb) fprintf(stderr, "BS_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy); @@ -7193,11 +7241,13 @@ if (verb) fprintf(stderr, "BS_rest: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d // if (!novalidate) { // STORE(idx, win, attr); // } + + last_bs_restore = dnow(); return 1; } -int su_restore(int idx, int *nbatch, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) { +int su_restore(int idx, int *nbatch, sraRegionPtr rmask, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) { Window win = cache_list[idx].win; int x1, y1, w1, h1; int x2, y2, w2, h2; @@ -7285,6 +7335,9 @@ fprintf(stderr, "SU_rest: su_x/bs_x/su_time: %d %d %.3f\n", x, cache_list[idx].b if (clip) { clip_region(r, win); } + if (rmask != NULL) { + sraRgnAnd(r, rmask); + } dtA = dnowx(); if (verb) fprintf(stderr, "SU_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy); @@ -7302,6 +7355,9 @@ if (verb) fprintf(stderr, "SU_rest: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d // } else if (!novalidate) { // STORE(idx, win, attr); // } + + last_su_restore = dnow(); + return 1; } @@ -7953,8 +8009,40 @@ if (type == UnmapNotify) w = Ev[n].xunmap.window; if (type == MapNotify) w = Ev[n].xmap.window; if (type == Expose) w = Ev[n].xexpose.window; if (type == ConfigureNotify) w = Ev[n].xconfigure.window; +if (type == VisibilityNotify) w = win; if (n == *n_in) fprintf(stderr, "\n"); -fprintf(stderr, "----- %d inputev 0x%08x w: 0x%08x %s\n", n, win, w, Etype(type)); +if (1) { + char *msg = ""; + int idx = -1, x = 0, y = 0, wd = 0, ht = 0; + if (w != None) { + idx = lookup_win_index(w); + if (idx >= 0) { + x = cache_list[idx].x; + y = cache_list[idx].y; + wd = cache_list[idx].width; + ht = cache_list[idx].height; + } + } + if (type == VisibilityNotify) { + msg = VState(Ev[n].xvisibility.state); + } else if (type == ConfigureNotify) { + int x_new = Ev[n].xconfigure.x; + int y_new = Ev[n].xconfigure.y; + int w_new = Ev[n].xconfigure.width; + int h_new = Ev[n].xconfigure.height; + if (idx >= 0) { + if (w_new != wd || h_new != ht) { + msg = "change size"; + } else if (x_new != x || y_new != y) { + msg = "change position"; + } else { + msg = "change stacking"; + } + } + } + + fprintf(stderr, "----- %d inputev 0x%08x w: 0x%08x %04dx%04d+%04d+%04d %s %s\n", n, win, w, wd, ht, x, y, Etype(type), msg); +} if (win == rootwin) { if (type == CreateNotify) { @@ -8038,191 +8126,15 @@ fprintf(stderr, "----- skip %s\n", Etype(type)); *n_in = n; } -int check_ncache(int reset, int mode) { - static double last_root = 0.0; - static int first = 1; - static int last_client_count = -1; - int i, k, n; - int did_sched = 0; +static int saw_desktop_change = 0; - double now, refresh = 60.0; - Window win, win2; +void check_sched(int try_batch, int *did_sched) { + static double last_root = 0.0; + double refresh = 60.0; + int i, k, valid; + Window win; XWindowAttributes attr; - int valid; - int try_batch = 1; /* XXX Y */ - int use_batch = 0; - int nreg = 0, *nbatch; - int create_cnt; - int pixels = 0, ttot; - int desktop_change = 0, n1, n2; - static int saw_desktop_change = 0; - int missed_su_restore = 0; - int missed_bs_restore = 0; - sraRegionPtr r0, r; - sraRegionPtr missed_su_restore_rgn; - sraRegionPtr missed_bs_restore_rgn; - - int nrects = 0; - int nsave, nxsel; - int did_vis_snap = 0; - - int skipwins_n = 0; - int skipwins_max = 256; - Window skipwins[256]; - - if (unixpw_in_progress) return -1; - -#ifdef MACOSX - if (! macosx_console) { - RAWFB_RET(-1) - } -#else - RAWFB_RET(-1) -#endif - - if (! screen) { - return -1; - } - - now = dnow(); - - if (ncache0) { - if (reset) { - ; - } else if (!client_count || !ncache || nofb) { - static double last_purge = 0.0; - double delay = client_count ? 0.5 : 2.0; - if (now > last_purge + delay) { - int c = 0; - XEvent ev; - X_LOCK; - while (xcheckmaskevent(dpy, all_ev, &ev)) { - c++; - } - X_UNLOCK; - last_purge = dnow(); -if (c) fprintf(stderr, "check_ncache purged %d events\n", c); - } - if (!client_count && last_client_count >= 0 && - client_count != last_client_count) { - /* this should use less RAM when no clients */ - do_new_fb(1); - } - last_client_count = client_count; - return -1; - } - } - last_client_count = client_count; - - if (ncache && ! ncache0) { - ncache0 = ncache; - } - - if (! ncache || ! ncache0) { - return -1; - } - if (subwin) { - return -1; - } - if (nofb) { - return -1; - } - - if (reset) { - rfbLog("check_ncache: resetting cache\n"); - for (i=0; i < cache_list_num; i++) { - free_rect(i); - CLEAR(i); - } - for (n = 1; n <= ncache; n++) { - if (rect_reg[n] != NULL) { - sraRgnDestroy(rect_reg[n]); - rect_reg[n] = NULL; - } - } - zero_fb(0, dpy_y, dpy_x, (ncache+1)*dpy_y); - mark_rect_as_modified(0, dpy_y, dpy_x, (ncache+1)*dpy_y, 0); - - snap_old(); - return -1; - } - - if (first) { - int dx = 10, dy = 24, ds = 0; - int Dx = dpy_x, Dy = dpy_y; - first = 0; - for (i=0; i < NRECENT; i++) { - recent[i] = None; - } - for (i=0; i < NSCHED; i++) { - sched_bs[i] = None; - } - rlast = 0; - - X_LOCK; - /* event leak with client_count == 0 */ - xselectinput_rootwin |= SubstructureNotifyMask; - XSelectInput_wr(dpy, rootwin, xselectinput_rootwin); - X_UNLOCK; - - if (scaling) { - Dx = scaled_x; - Dy = scaled_y; - } - if (!rotating_same) { - int t = Dx; - Dx = Dy; - Dy = t; - } - - for (i = 0; i < 3; i++) { - rfbDrawString(screen, &default8x16Font, dx, ds + Dy+1*dy, - "This is the Pixel buffer cache region. Your VNC Viewer is not hiding it from you.", - white_pixel()); - rfbDrawString(screen, &default8x16Font, dx, ds + Dy+2*dy, - "Try resizing your VNC Viewer so you don't see it!! Pay no attention to the man behind the curtain...", - white_pixel()); - rfbDrawString(screen, &default8x16Font, dx, ds + Dy+3*dy, - "To disable run the server with: x11vnc -ncache 0 ...", - white_pixel()); - rfbDrawString(screen, &default8x16Font, dx, ds + Dy+4*dy, - "More info: http://www.karlrunge.com/x11vnc/#faq-client-caching", - white_pixel()); - - ds += 8 * dy; - } - - snapshot_cache_list(0, 100.0); - for (i=0; i < cache_list_num; i++) { - CLEAR(i); - } - for (n = 1; n <= ncache; n++) { - rect_reg[n] = NULL; - } - snap_old(); - } - - if (now < last_client + 4) { - return -1; - } - -if (hack_val == 2) { - block_stats(); - hack_val = 1; -} -#ifdef MACOSX - if (macosx_console) { - static double last_all_windows = 0.0; - if (! macosx_checkevent(NULL)) { - if (now > last_all_windows + 0.05) { - macosxCGS_get_all_windows(); - last_all_windows = dnow(); - } - } - /* XXX Y */ - rootwin = -1; - } -#endif + double now = dnow(); if (now > last_root + refresh) { @@ -8265,8 +8177,6 @@ fprintf(stderr, "Created window never mapped: freeing(%d) 0x%x\n", k, (unsigned last_root = dnow(); } - check_zero_rects(); - if (now > last_sched_bs + 0.30) { static double last_sched_vis = 0.0; int nr = 0, *bat = NULL; @@ -8329,7 +8239,7 @@ fprintf(stderr, "*SCHED LOOKUP FAIL: i=%d 0x%x\n", i, win); } sched_bs[i] = None; } - did_sched = 1; + *did_sched = 1; if (now > last_sched_vis + 3.0 && now > last_wireframe + 2.0) { static double last_vis = 0.0; @@ -8338,7 +8248,7 @@ fprintf(stderr, "*SCHED LOOKUP FAIL: i=%d 0x%x\n", i, win); int diff, nv = 32, vis_now_n = 0; Window win; - did_vis_snap = 1; +if (1) fprintf(stderr, "VIS snapshot all %.4f\n", dnowx()); for (i=0; i < cache_list_num; i++) { int ok = 0; int top_only = 1; @@ -8400,6 +8310,9 @@ fprintf(stderr, "*SCHED LOOKUP FAIL: i=%d 0x%x\n", i, win); win = cache_list[i].win; valid = 0; fprintf(stderr, "*VIS BS_save: 0x%x %d %d %d\n", win, cache_list[i].width, cache_list[i].height, cache_list[i].map_state); + if (now < cache_list[i].vis_unobs_time + 0.75 && now < cache_list[i].vis_obs_time + 0.75) { + continue; + } bs_save(i, bat, &attr, !top_now[k], 0, &valid, 0); if (valid) { STORE(i, win, attr); @@ -8419,6 +8332,193 @@ fprintf(stderr, "*VIS BS_save: 0x%x %d %d %d\n", win, cache_list[i].width, cach } last_sched_bs = dnow(); } +} + +int check_ncache(int reset, int mode) { + static int first = 1; + static int last_client_count = -1; + int i, k, n; + int did_sched = 0; + + Window win, win2; + XWindowAttributes attr; + int valid; + int try_batch = 1; /* XXX Y */ + int use_batch = 0; + int nreg = 0, *nbatch; + int create_cnt; + int pixels = 0, ttot; + int desktop_change = 0, n1, n2; + int missed_su_restore = 0; + int missed_bs_restore = 0; + sraRegionPtr r0, r; + sraRegionPtr missed_su_restore_rgn; + sraRegionPtr missed_bs_restore_rgn; + sraRegionPtr unmapped_rgn; + + int nrects = 0; + int nsave, nxsel; + double now; + + int skipwins_n = 0; + int skipwins_max = 256; + Window skipwins[256]; + + if (unixpw_in_progress) return -1; + +#ifdef MACOSX + if (! macosx_console) { + RAWFB_RET(-1) + } +#else + RAWFB_RET(-1) +#endif + + if (! screen) { + return -1; + } + + now = dnow(); + + if (ncache0) { + if (reset) { + ; + } else if (!client_count || !ncache || nofb) { + static double last_purge = 0.0; + double delay = client_count ? 0.5 : 2.0; + if (now > last_purge + delay) { + int c = 0; + XEvent ev; + X_LOCK; + while (xcheckmaskevent(dpy, all_ev, &ev)) { + c++; + } + X_UNLOCK; + last_purge = dnow(); +if (c) fprintf(stderr, "check_ncache purged %d events\n", c); + } + if (!client_count && last_client_count >= 0 && + client_count != last_client_count) { + /* this should use less RAM when no clients */ + do_new_fb(1); + } + last_client_count = client_count; + return -1; + } + } + last_client_count = client_count; + + if (ncache && ! ncache0) { + ncache0 = ncache; + } + + if (! ncache || ! ncache0) { + return -1; + } + if (subwin) { + return -1; + } + if (nofb) { + return -1; + } + + if (reset) { + rfbLog("check_ncache: resetting cache\n"); + for (i=0; i < cache_list_num; i++) { + free_rect(i); + CLEAR(i); + } + for (n = 1; n <= ncache; n++) { + if (rect_reg[n] != NULL) { + sraRgnDestroy(rect_reg[n]); + rect_reg[n] = NULL; + } + } + zero_fb(0, dpy_y, dpy_x, (ncache+1)*dpy_y); + mark_rect_as_modified(0, dpy_y, dpy_x, (ncache+1)*dpy_y, 0); + + snap_old(); + return -1; + } + + if (first) { + int dx = 10, dy = 24, ds = 0; + int Dx = dpy_x, Dy = dpy_y; + first = 0; + for (i=0; i < NRECENT; i++) { + recent[i] = None; + } + for (i=0; i < NSCHED; i++) { + sched_bs[i] = None; + } + rlast = 0; + + X_LOCK; + /* event leak with client_count == 0 */ + xselectinput_rootwin |= SubstructureNotifyMask; + XSelectInput_wr(dpy, rootwin, xselectinput_rootwin); + X_UNLOCK; + + if (scaling) { + Dx = scaled_x; + Dy = scaled_y; + } + if (!rotating_same) { + int t = Dx; + Dx = Dy; + Dy = t; + } + + for (i = 0; i < 3; i++) { + rfbDrawString(screen, &default8x16Font, dx, ds + Dy+1*dy, + "This is the Pixel buffer cache region. Your VNC Viewer is not hiding it from you.", + white_pixel()); + rfbDrawString(screen, &default8x16Font, dx, ds + Dy+2*dy, + "Try resizing your VNC Viewer so you don't see it!! Pay no attention to the man behind the curtain...", + white_pixel()); + rfbDrawString(screen, &default8x16Font, dx, ds + Dy+3*dy, + "To disable run the server with: x11vnc -ncache 0 ...", + white_pixel()); + rfbDrawString(screen, &default8x16Font, dx, ds + Dy+4*dy, + "More info: http://www.karlrunge.com/x11vnc/#faq-client-caching", + white_pixel()); + + ds += 8 * dy; + } + + snapshot_cache_list(0, 100.0); + for (i=0; i < cache_list_num; i++) { + CLEAR(i); + } + for (n = 1; n <= ncache; n++) { + rect_reg[n] = NULL; + } + snap_old(); + } + + check_zero_rects(); + + if (now < last_client + 4) { + return -1; + } + +if (hack_val == 2) { + block_stats(); + hack_val = 1; +} +#ifdef MACOSX + if (macosx_console) { + static double last_all_windows = 0.0; + if (! macosx_checkevent(NULL)) { + if (now > last_all_windows + 0.05) { + macosxCGS_get_all_windows(); + last_all_windows = dnow(); + } + } + /* XXX Y */ + rootwin = -1; + } +#endif n = 0; ttot = 0; @@ -8506,10 +8606,10 @@ fprintf(stderr, "PRELOOP: RepartNotify: 0x%x %d idx=%d\n", win2, n1, idx); } if (n == 0) { + check_sched(try_batch, &did_sched); return 0; } fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events. %.4f\n", n, now - x11vnc_start); -if (did_vis_snap) fprintf(stderr, "VIS snapshot all %.4f\n", dnowx()); if (try_batch) { use_batch = 1; @@ -8663,6 +8763,7 @@ fprintf(stderr, "SKIPWINS: Ev_unmap/map: 0x%x %d\n", twin, n2); missed_su_restore_rgn = sraRgnCreate(); missed_bs_restore_rgn = sraRgnCreate(); r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y); + unmapped_rgn = sraRgnCreate(); for (k = 0; k < skipwins_n; k++) { fprintf(stderr, "skipwins[%d] 0x%x\n", k, skipwins[k]); @@ -8771,12 +8872,12 @@ fprintf(stderr, "----%02d: ConfigureNotify 0x%x %3d -- above: 0x%x -> 0x%x % if (x_old != x_new || y_old != y_new) { /* invalidate su */ cache_list[idx].su_time = 0.0; -fprintf(stderr, " INVALIDATE su: 0x%x xy: %d/%d %d/%d \n", (unsigned int) win, x_old, y_old, x_new, y_new); +fprintf(stderr, " INVALIDATE su: 0x%x xy: +%d+%d +%d+%d \n", (unsigned int) win, x_old, y_old, x_new, y_new); } if (w_old != w_new || h_old != h_new) { /* invalidate bs */ cache_list[idx].bs_time = 0.0; -fprintf(stderr, " INVALIDATE bs: 0x%x wh: %d/%d %d/%d \n", (unsigned int) win, w_old, h_old, w_new, h_new); +fprintf(stderr, " INVALIDATE bs: 0x%x wh: %dx%d %dx%d \n", (unsigned int) win, w_old, h_old, w_new, h_new); } stack_change = 0; @@ -8831,9 +8932,26 @@ fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", i ok = 0; } if (ok) { + int x2, y2, w2, h2; + sraRegionPtr rmask = NULL; X_UNLOCK; valid = 0; - bs_restore(idx, nbatch, &attr, 0, 1, &valid, 1); + if (dnow() < cache_list[idx].vis_unobs_time + 3.00 && !sraRgnEmpty(unmapped_rgn)) { + x2 = cache_list[idx].x; + y2 = cache_list[idx].y; + w2 = cache_list[idx].width; + h2 = cache_list[idx].height; + rmask = sraRgnCreateRect(x2, y2, x2+w2, y2+h2); + sraRgnAnd(rmask, unmapped_rgn); + if (sraRgnEmpty(rmask)) { + sraRgnDestroy(rmask); + rmask = NULL; + } + } + bs_restore(idx, nbatch, rmask, &attr, 0, 1, &valid, 1); + if (rmask != NULL) { + sraRgnDestroy(rmask); + } X_LOCK; if (valid) { STORE(idx, win, attr); @@ -8852,6 +8970,11 @@ fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", i } } } + if (state == VisibilityUnobscured) { + cache_list[idx].vis_unobs_time = dnow(); + } else if (cache_list[idx].vis_state == VisibilityUnobscured) { + cache_list[idx].vis_obs_time = dnow(); + } cache_list[idx].vis_state = state; } else if (type == MapNotify) { @@ -8900,7 +9023,7 @@ fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", ik, (unsigned int) win } } valid = 0; - if (bs_restore(idx, nbatch, &attr, 0, 0, &valid, 1)) { /* XXX clip? */ + if (bs_restore(idx, nbatch, NULL, &attr, 0, 0, &valid, 1)) { /* XXX clip? */ ; } else { idx_add_rgn(missed_bs_restore_rgn, r0, idx); @@ -8941,6 +9064,7 @@ fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", ik, (unsigned int) win cache_list[idx].map_state = IsViewable; } else if (type == UnmapNotify) { + int x2, y2, w2, h2; idx = lookup_win_index(win); fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", ik, (unsigned int) win, idx); @@ -8984,7 +9108,7 @@ fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", ik, (unsigned int) win bs_save(idx, nbatch, &attr, 1, 0, &valid, 1); } valid = 0; - if (su_restore(idx, nbatch, &attr, 1, 0, &valid, 1)) { + if (su_restore(idx, nbatch, NULL, &attr, 1, 0, &valid, 1)) { try_to_fix_su(win, idx, None, nbatch, "unmapped"); if (valid) { STORE(idx, win, attr); @@ -9007,6 +9131,16 @@ fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", ik, (unsigned int) win Ev_rects[nrects].y2 = cache_list[idx].height; nrects++; } + + x2 = cache_list[idx].x; + y2 = cache_list[idx].y; + w2 = cache_list[idx].width; + h2 = cache_list[idx].height; + r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2); + sraRgnAnd(r, r0); + sraRgnOr(unmapped_rgn, r); + sraRgnDestroy(r); + cache_list[idx].map_state = IsUnmapped; } else if (type == ReparentNotify) { @@ -9043,6 +9177,8 @@ fprintf(stderr, "igno%02d: ** Ignoring 0x%x type: %s\n", ik, (unsigned int) } } + check_sched(try_batch, &did_sched); + if (n_CN || n_RN || n_DN || n_MN || n_UN || n_ST || did_sched) { snap_old(); } diff --git a/x11vnc/winattr_t.h b/x11vnc/winattr_t.h index 1696b3f..cfde047 100644 --- a/x11vnc/winattr_t.h +++ b/x11vnc/winattr_t.h @@ -17,6 +17,8 @@ typedef struct winattr { double time; double bs_time; double su_time; + double vis_obs_time; + double vis_unobs_time; int bs_x, bs_y, bs_w, bs_h; int su_x, su_y, su_w, su_h; Window above; diff --git a/x11vnc/x11vnc.1 b/x11vnc/x11vnc.1 index 21df2e8..98c471c 100644 --- a/x11vnc/x11vnc.1 +++ b/x11vnc/x11vnc.1 @@ -2,7 +2,7 @@ .TH X11VNC "1" "January 2007" "x11vnc " "User Commands" .SH NAME x11vnc - allow VNC connections to real X11 displays - version: 0.8.4, lastmod: 2007-01-03 + version: 0.8.4, lastmod: 2007-01-07 .SH SYNOPSIS .B x11vnc [OPTION]... diff --git a/x11vnc/x11vnc.h b/x11vnc/x11vnc.h index 5dad134..3aaa9f4 100644 --- a/x11vnc/x11vnc.h +++ b/x11vnc/x11vnc.h @@ -470,6 +470,10 @@ extern double x11vnc_start; extern double last_get_wm_frame_time; extern Window last_get_wm_frame; +extern double last_bs_restore; +extern double last_su_restore; +extern double last_bs_save; +extern double last_su_save; extern int hack_val; diff --git a/x11vnc/x11vnc_defs.c b/x11vnc/x11vnc_defs.c index 6600061..adca47a 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.4 lastmod: 2007-01-03"; +char lastmod[] = "0.8.4 lastmod: 2007-01-07"; /* X display info */ @@ -134,6 +134,10 @@ double x11vnc_start = 0.0; double last_get_wm_frame_time = 0.0; Window last_get_wm_frame = None; +double last_bs_restore = 0.0; +double last_su_restore = 0.0; +double last_bs_save = 0.0; +double last_su_save = 0.0; int hack_val = 0; diff --git a/x11vnc/xdamage.c b/x11vnc/xdamage.c index 2343a98..08e2278 100644 --- a/x11vnc/xdamage.c +++ b/x11vnc/xdamage.c @@ -563,13 +563,22 @@ int xdamage_hint_skip(int y) { if (ncache > 0) { if (ncache_no_skip == 0) { - if (dnow() > last_ncache_no_skip + 4.0) { + double now = dnow(); + if (now > last_ncache_no_skip + 8.0) { ncache_no_skip = 1; + } else if (now < last_bs_restore + 0.5) { + ncache_no_skip = 1; + } else if (now < last_su_restore + 0.5) { + ncache_no_skip = 1; + } else if (now < last_copyrect + 0.5) { + ncache_no_skip = 1; + } + if (ncache_no_skip) { last_ncache_no_skip = dnow(); return 0; } } else { - if (++ncache_no_skip >= 2*nreg) { + if (ncache_no_skip++ >= 1*nreg + 4) { ncache_no_skip = 0; } else { return 0; |