diff options
Diffstat (limited to 'x11vnc/userinput.c')
| -rw-r--r-- | x11vnc/userinput.c | 574 |
1 files changed, 355 insertions, 219 deletions
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(); } |
