if (scancnt) {}
int collect_xdamage(int scancnt, int call) {#if LIBVNCSERVER_HAVE_LIBXDAMAGE	XDamageNotifyEvent *dev;	XEvent ev;	sraRegionPtr tmpregion;	sraRegionPtr reg;	static int rect_count = 0;	int nreg, ccount = 0, dcount = 0, ecount = 0;	static time_t last_rpt = 0;	time_t now;	int x, y, w, h, x2, y2;	int i, dup, next, dup_max = 0;#define DUPSZ 32	int dup_x[DUPSZ], dup_y[DUPSZ], dup_w[DUPSZ], dup_h[DUPSZ];	double tm, dt;	if (! xdamage_present || ! use_xdamage) {		return 0;	}	if (! xdamage) {		return 0;	}	if (! xdamage_base_event_type) {		return 0;	}	dtime0(&tm);	nreg = (xdamage_memory * NSCAN) + 1;	if (call == 0) {		xdamage_ticker = (xdamage_ticker+1) % nreg;		xdamage_direct_count = 0;		reg = xdamage_regions[xdamage_ticker];  		sraRgnMakeEmpty(reg);	} else {		reg = xdamage_regions[xdamage_ticker];  	}	X_LOCK;if (0)	XFlush(dpy);if (0)	XEventsQueued(dpy, QueuedAfterFlush);	while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {		/*		 * TODO max cut off time in this loop?		 * Could check QLength and if huge just mark the whole		 * screen.		 */		ecount++;		if (ev.type != xdamage_base_event_type + XDamageNotify) {			break;		}		dev = (XDamageNotifyEvent *) &ev;		if (dev->damage != xdamage) {			continue;	/* not ours! */		}		x = dev->area.x;		y = dev->area.y;		w = dev->area.width;		h = dev->area.height;		/*		 * we try to manually remove some duplicates because		 * certain activities can lead to many 10's of dups		 * in a row.  The region work can be costly and reg is		 * later used in xdamage_hint_skip loops, so it is good		 * to skip them if possible.		 */		dup = 0;		for (i=0; i < dup_max; i++) {			if (dup_x[i] == x && dup_y[i] == y && dup_w[i] == w &&			    dup_h[i] == h) {				dup = 1;				break;			}		}		if (dup) {			dcount++;			continue;		}		if (dup_max < DUPSZ) {			next = dup_max;			dup_max++;		} else {			next = (next+1) % DUPSZ;		}		dup_x[next] = x;		dup_y[next] = y;		dup_w[next] = w;		dup_h[next] = h;		/* translate if needed */		if (clipshift) {			/* set coords relative to fb origin */			if (0 && rootshift) {				/*				 * Note: not needed because damage is				 * relative to subwin, not rootwin.				 */				x = x - off_x;				y = y - off_y;			}			if (clipshift) {				x = x - coff_x;				y = y - coff_y;			}			x2 = x + w;		/* upper point */			x  = nfix(x,  dpy_x);	/* place both in fb area */			x2 = nfix(x2, dpy_x+1);			w = x2 - x;		/* recompute w */						y2 = y + h;			y  = nfix(y,  dpy_y);			y2 = nfix(y2, dpy_y+1);			h = y2 - y;			if (w <= 0 || h <= 0) {				continue;			}		}		if (debug_xdamage > 2) {			fprintf(stderr, "xdamage: -> event %dx%d+%d+%d area:"			    " %d  dups: %d  %s\n", w, h, x, y, w*h, dcount,			    (w*h > xdamage_max_area) ? "TOO_BIG" : "");		}		record_desired_xdamage_rect(x, y, w, h);		tmpregion = sraRgnCreateRect(x, y, x + w, y + h); 		sraRgnOr(reg, tmpregion);		sraRgnDestroy(tmpregion);		rect_count++;		ccount++;	}	/* clear the whole damage region for next time. XXX check */	if (call == 1) {		XDamageSubtract(dpy, xdamage, None, None);	}	X_UNLOCK;	if (0 && xdamage_direct_count) {		fb_push();	}	dt = dtime(&tm);	if ((debug_tiles > 1 && ecount) || (debug_tiles && ecount > 200)	    || debug_xdamage > 1) {		fprintf(stderr, "collect_xdamage(%d): %.4f t: %.4f ev/dup/accept"		    "/direct %d/%d/%d/%d\n", call, dt, tm - x11vnc_start, ecount,		    dcount, ccount, xdamage_direct_count); 	}	now = time(0);	if (! last_rpt) {		last_rpt = now;	}	if (now > last_rpt + 15) {		double rat = -1.0;		if (XD_tot) {			rat = ((double) XD_skip)/XD_tot;		}		if (debug_tiles || debug_xdamage) {			fprintf(stderr, "xdamage: == scanline skip/tot: "			    "%04d/%04d =%.3f  rects: %d  desired: %d\n",			    XD_skip, XD_tot, rat, rect_count, XD_des);		}					XD_skip = 0;		XD_tot  = 0;		XD_des  = 0;		rect_count = 0;		last_rpt = now;	}#endif	return 0;}