* not needed because damage is relative * to subwin, not rootwin.
* Note: not needed because damage is * relative to subwin, not rootwin.
void collect_xdamage(int scancnt) {#if LIBVNCSERVER_HAVE_LIBXDAMAGE	XDamageNotifyEvent *dev;#if 0	XserverRegion xregion;#endif	XEvent ev;	sraRegionPtr tmpregion;	sraRegionPtr reg;	static int rect_count = 0;	int nreg, ccount = 0, dcount = 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 16	int dup_x[DUPSZ], dup_y[DUPSZ], dup_w[DUPSZ], dup_h[DUPSZ];	if (! xdamage_present || ! using_xdamage) {		return;	}	if (! xdamage) {		return;	}	nreg = (xdamage_memory * NSCAN) + 1;	xdamage_ticker = (xdamage_ticker+1) % nreg;	reg = xdamage_regions[xdamage_ticker];  	sraRgnMakeEmpty(reg);	X_LOCK;	while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {		/* TODO max cut off time in this loop? */		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) {				/*				 * 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);			w = x2 - x;		/* recompute w */						y2 = y + h;			y  = nfix(y,  dpy_y);			y2 = nfix(y2, dpy_y);			h = y2 - y;			if (w <= 0 || h <= 0) {				continue;			}		}		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 */	XDamageSubtract(dpy, xdamage, None, None);	X_UNLOCK;	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 (0) fprintf(stderr, "skip/tot: %04d/%04d  rat=%.3f  rect_count: %d  desired_rects: %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}