if (use_threads && old_pointer != 1) {
if (use_threads && pointer_mode != 1) {
void pointer(int mask, int x, int y, rfbClientPtr client) {	if (debug_pointer && mask >= 0) {		static int show_motion = -1;		if (show_motion == -1) {			if (getenv("X11VNC_DB_NOMOTION")) {				show_motion = 0;			} else {				show_motion = 1;			}		}		if (show_motion) {			rfbLog("pointer(mask: 0x%x, x:%4d, y:%4d)\n",			    mask, x, y);		}	}	if (view_only) {		return;	}	if (client && client->viewOnly) {		return;	}	if (scaling) {		/* map from rfb size to X11 size: */		x = ((double) x / scaled_x) * dpy_x;		x = nfix(x, dpy_x);		y = ((double) y / scaled_y) * dpy_y;		y = nfix(y, dpy_y);	}	if (mask >= 0) {		/*		 * mask = -1 is a special case call from scan_for_updates()		 * to flush the event queue; there is no real pointer event.		 */		got_user_input++;		got_pointer_input++;		last_pointer_client = client;	}	/*	 * The following is hopefully an improvement wrt response during	 * pointer user input (window drags) for the threaded case.	 * See check_user_input() for the more complicated things we do	 * in the non-threaded case.	 */	if (use_threads && old_pointer != 1) {#		define NEV 32		/* storage for the event queue */		static int mutex_init = 0;		static int nevents = 0;		static int ev[NEV][3];		int i;		/* timer things */		static double dt = 0.0, tmr = 0.0, maxwait = 0.4;		if (! mutex_init) {			INIT_MUTEX(pointerMutex);			mutex_init = 1;		}		LOCK(pointerMutex);		/* 		 * If the framebuffer is being copied in another thread		 * (scan_for_updates()), we will queue up to 32 pointer		 * events for later.  The idea is by delaying these input		 * events, the screen is less likely to change during the		 * copying period, and so will give rise to less window		 * "tearing".		 *		 * Tearing is not completely eliminated because we do		 * not suspend work in the other libvncserver threads.		 * Maybe that is a possibility with a mutex...		 */		if (fb_copy_in_progress && mask >= 0) {			/* 			 * mask = -1 is an all-clear signal from			 * scan_for_updates().			 *			 * dt is a timer in seconds; we only queue for so long.			 */			dt += dtime(&tmr);			if (nevents < NEV && dt < maxwait) {				i = nevents++;				ev[i][0] = mask;				ev[i][1] = x;				ev[i][2] = y;				UNLOCK(pointerMutex);				if (debug_pointer) {					rfbLog("pointer(): deferring event "					    "%d\n", i);				}				return;			}		}		/* time to send the queue */		for (i=0; i<nevents; i++) {			if (debug_pointer) {				rfbLog("pointer(): sending event %d\n", i+1);			}			update_x11_pointer(ev[i][0], ev[i][1], ev[i][2]);		}		if (nevents && dt > maxwait) {			X_LOCK;			XFlush(dpy);				X_UNLOCK;		}		nevents = 0;	/* reset everything */		tmr = 0.0;		dt = 0.0;		dtime(&tmr);		UNLOCK(pointerMutex);	}	if (mask < 0) {		/* -1 just means flush the event queue */		if (debug_pointer > 1) {			rfbLog("pointer(): flush only.\n");		}		return;	}	/* update the X display with the event: */	update_x11_pointer(mask, x, y);}