X_LOCK; if (first && (watch_selection || vnc_connect)) {  XSelectInput(dpy, rootwin, PropertyChangeMask); } if (first && watch_selection) {  selwin = XCreateSimpleWindow(dpy, rootwin, 0, 0, 1, 1, 0, 0, 0); } if (first && vnc_connect) { vnc_connect_str[0] = '\0'; vnc_connect_prop = XInternAtom(dpy, "VNC_CONNECT", False);
if (first) { initialize_xevents();
void check_xevents(void) {	XEvent xev;	static int first = 1, sent_some_sel = 0;	static time_t last_request = 0;	time_t now = time(0);	int have_clients = screen->clientHead ? 1 : 0;	X_LOCK;	if (first && (watch_selection || vnc_connect)) {		/*		 * register desired event(s) for notification.		 * PropertyChangeMask is for CUT_BUFFER0 changes.		 * TODO: does this cause a flood of other stuff?		 */		XSelectInput(dpy, rootwin, PropertyChangeMask);	}	if (first && watch_selection) {		/* create fake window for our selection ownership, etc */		selwin = XCreateSimpleWindow(dpy, rootwin, 0, 0, 1, 1, 0, 0, 0);	}	if (first && vnc_connect) {		vnc_connect_str[0] = '\0';		vnc_connect_prop = XInternAtom(dpy, "VNC_CONNECT", False);	}	first = 0;	/*	 * There is a bug where we have to wait before sending text to	 * the client... so instead of sending right away we wait a	 * the few seconds.	 */	if (have_clients && watch_selection && ! sent_some_sel	    && now > last_client + sel_waittime) {		if (XGetSelectionOwner(dpy, XA_PRIMARY) == None) {			cutbuffer_send();		}		sent_some_sel = 1;	}	if (XCheckTypedEvent(dpy, MappingNotify, &xev)) {		XRefreshKeyboardMapping((XMappingEvent *) &xev);		if (use_modifier_tweak) {			X_UNLOCK;			initialize_modtweak();			X_LOCK;		}	}	/* check for CUT_BUFFER0 and VNC_CONNECT changes: */	if (XCheckTypedEvent(dpy, PropertyNotify, &xev)) {		if (xev.type == PropertyNotify) {			if (xev.xproperty.atom == XA_CUT_BUFFER0) {				/*				 * Go retrieve CUT_BUFFER0 and send it.				 *				 * set_cutbuffer is a flag to try to avoid				 * processing our own cutbuffer changes.				 */				if (have_clients && watch_selection				    && ! set_cutbuffer) {					cutbuffer_send();					sent_some_sel = 1;				}				set_cutbuffer = 0;			} else if (vnc_connect && vnc_connect_prop != None		    	    && xev.xproperty.atom == vnc_connect_prop) {					/*				 * Go retrieve VNC_CONNECT string.				 */				read_vnc_connect_prop();			}		}	}	/* check for our PRIMARY request notification: */	if (watch_primary) {		if (XCheckTypedEvent(dpy, SelectionNotify, &xev)) {			if (xev.type == SelectionNotify &&			    xev.xselection.requestor == selwin &&			    xev.xselection.selection == XA_PRIMARY &&			    xev.xselection.property != None &&			    xev.xselection.target == XA_STRING) {				/* go retrieve PRIMARY and check it */				if (now > last_client + sel_waittime				    || sent_some_sel) {					selection_send(&xev);				}			}		}		if (now > last_request) {			/*			 * Every second or two, request PRIMARY, unless we			 * already own it or there is no owner or we have			 * no clients.			 * TODO: even at this low rate we should look into			 * and performance problems in odds cases, etc.			 */			last_request = now;			if (! own_selection && have_clients &&			    XGetSelectionOwner(dpy, XA_PRIMARY) != None) {				XConvertSelection(dpy, XA_PRIMARY, XA_STRING,				    XA_STRING, selwin, CurrentTime);			}		}	}	if (own_selection) {		/* we own PRIMARY, see if someone requested it: */		if (XCheckTypedEvent(dpy, SelectionRequest, &xev)) {			if (xev.type == SelectionRequest &&			    xev.xselectionrequest.selection == XA_PRIMARY) {				selection_request(&xev);			}		}		/* we own PRIMARY, see if we no longer own it: */		if (XCheckTypedEvent(dpy, SelectionClear, &xev)) {			if (xev.type == SelectionClear &&			    xev.xselectionclear.selection == XA_PRIMARY) {				own_selection = 0;				if (xcut_string) {					free(xcut_string);					xcut_string = NULL;				}			}		}	}	X_UNLOCK;}