summaryrefslogtreecommitdiffstats
path: root/x11vnc/xdamage.c
diff options
context:
space:
mode:
authorrunge <runge@karlrunge.com>2009-10-08 17:30:36 -0400
committerrunge <runge@karlrunge.com>2009-10-08 17:30:36 -0400
commit3129ef668abf2b3f9b624bdb4c5ac0365ae2583b (patch)
treea2f7edda96dd11da79f7fbbab886625caaa41ae8 /x11vnc/xdamage.c
parent169ef3a0429b3e21720856024076e1941221e987 (diff)
downloadlibtdevnc-3129ef668abf2b3f9b624bdb4c5ac0365ae2583b.tar.gz
libtdevnc-3129ef668abf2b3f9b624bdb4c5ac0365ae2583b.zip
Huge number of changes, see x11vnc/ChangeLog
Diffstat (limited to 'x11vnc/xdamage.c')
-rw-r--r--x11vnc/xdamage.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/x11vnc/xdamage.c b/x11vnc/xdamage.c
index 9db86ae..946aff2 100644
--- a/x11vnc/xdamage.c
+++ b/x11vnc/xdamage.c
@@ -56,6 +56,8 @@ int xdamage_max_area = 20000; /* pixels */
double xdamage_memory = 1.0; /* in units of NSCAN */
int xdamage_tile_count = 0, xdamage_direct_count = 0;
double xdamage_scheduled_mark = 0.0;
+double xdamage_crazy_time = 0.0;
+double xdamage_crazy_delay = 300.0;
sraRegionPtr xdamage_scheduled_mark_region = NULL;
sraRegionPtr *xdamage_regions = NULL;
int xdamage_ticker = 0;
@@ -400,6 +402,7 @@ int collect_xdamage(int scancnt, int call) {
#define DUPSZ 32
int dup_x[DUPSZ], dup_y[DUPSZ], dup_w[DUPSZ], dup_h[DUPSZ];
double tm, dt;
+ int mark_all = 0, retries = 0, too_many = 1000, tot_ev = 0;
RAWFB_RET(0)
@@ -443,6 +446,9 @@ int collect_xdamage(int scancnt, int call) {
X_LOCK;
if (0) XFlush_wr(dpy);
if (0) XEventsQueued(dpy, QueuedAfterFlush);
+
+ come_back_for_more:
+
while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
/*
* TODO max cut off time in this loop?
@@ -450,6 +456,26 @@ if (0) XEventsQueued(dpy, QueuedAfterFlush);
* screen.
*/
ecount++;
+ tot_ev++;
+
+ if (mark_all) {
+ continue;
+ }
+ if (ecount == too_many) {
+ int nqa = XEventsQueued(dpy, QueuedAlready);
+ if (nqa >= too_many) {
+ static double last_msg = 0.0;
+ tmpregion = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
+ sraRgnOr(reg, tmpregion);
+ sraRgnDestroy(tmpregion);
+ if (dnow() > last_msg + xdamage_crazy_delay) {
+ rfbLog("collect_xdamage: too many xdamage events %d+%d\n", ecount, nqa);
+ last_msg = dnow();
+ }
+ mark_all = 1;
+ }
+ }
+
if (ev.type != xdamage_base_event_type + XDamageNotify) {
break;
}
@@ -537,12 +563,37 @@ if (0) XEventsQueued(dpy, QueuedAfterFlush);
rect_count++;
ccount++;
}
+
+ if (mark_all) {
+ if (ecount + XEventsQueued(dpy, QueuedAlready) >= 3 * too_many && retries < 3) {
+ retries++;
+ XFlush_wr(dpy);
+ usleep(20 * 1000);
+ XFlush_wr(dpy);
+ ecount = 0;
+ goto come_back_for_more;
+ }
+ }
+
/* clear the whole damage region for next time. XXX check */
if (call == 1) {
XDamageSubtract(dpy, xdamage, None, None);
}
X_UNLOCK;
+ if (tot_ev > 20 * too_many) {
+ rfbLog("collect_xdamage: xdamage has gone crazy (screensaver or game?) ev: %d ret: %d\n", tot_ev, retries);
+ rfbLog("collect_xdamage: disabling xdamage for %d seconds.\n", (int) xdamage_crazy_delay);
+ destroy_xdamage_if_needed();
+ X_LOCK;
+ XSync(dpy, False);
+ while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
+ ;
+ }
+ X_UNLOCK;
+ xdamage_crazy_time = dnow();
+ }
+
if (0 && xdamage_direct_count) {
fb_push();
}
@@ -726,7 +777,7 @@ void create_xdamage_if_needed(int force) {
xdamage = XDamageCreate(dpy, window, XDamageReportRawRectangles);
XDamageSubtract(dpy, xdamage, None, None);
X_UNLOCK;
- rfbLog("created xdamage object: 0x%lx\n", xdamage);
+ rfbLog("created xdamage object: 0x%lx\n", xdamage);
}
#endif
}
@@ -762,6 +813,9 @@ void check_xdamage_state(void) {
* Create or destroy the Damage object as needed, we don't want
* one if no clients are connected.
*/
+ if (xdamage_crazy_time > 0.0 && dnow() < xdamage_crazy_time + xdamage_crazy_delay) {
+ return;
+ }
if (client_count && use_xdamage) {
create_xdamage_if_needed(0);
if (xdamage_scheduled_mark > 0.0 && dnow() >