void considerLocStillEvent() { if ( !loc_still_posted ) { unsigned long now = mclock(); if ( now - host_last_time < (unsigned long)loc_still_time ) { DEBUG(NAME_locStill, Cprintf("TimeDiff = %d (ignored)\n", now - host_last_time)); return; } if ( !pceMTTryLock(LOCK_PCE) ) return; if ( instanceOfObject(last_window, ClassWindow) && !onFlag(last_window, F_FREED|F_FREEING) && valInt(last_x) > 0 && valInt(last_y) > 0 ) { ServiceMode(is_service_window(last_window), { AnswerMark mark; EventObj e; markAnswerStack(mark); e = newObject(ClassEvent, NAME_locStill, last_window, last_x, last_y, last_buttons, toInt(last_time + now - host_last_time), EAV); addCodeReference(e); postNamedEvent(e, (Graphical) last_window, DEFAULT, NAME_postEvent); delCodeReference(e); freeableObj(e); rewindAnswerStack(mark, NIL); }) }
status ws_dispatch(Int FD, Any timeout) { XtIntervalId tid = 0; XtInputId iid = 0; status rval = SUCCEED; int ofd = dispatch_fd; int fd = (isDefault(FD) ? dispatch_fd : isNil(FD) ? -1 : valInt(FD)); /* No context: wait for input */ /* timeout */ if ( ThePceXtAppContext == NULL ) { int ready; #ifdef HAVE_POLL int to; struct pollfd fds[1]; if ( isNil(timeout) ) { to = -1; } else if ( isDefault(timeout) ) { to = 250; } else if ( isInteger(timeout) ) { to = valInt(timeout); } else if ( instanceOfObject(timeout, ClassReal) ) { to = (int)(valReal(timeout)*1000.0); } else to = 256; fds[0].fd = fd; fds[0].events = POLLIN; ready = poll(fds, 1, to); #else struct timeval to; struct timeval *tp = &to; fd_set readfds; int setmax = 0; if ( isNil(timeout) ) { tp = NULL; } else if ( isDefault(timeout) ) { to.tv_sec = 0; to.tv_usec = 250000; } else { double v; if ( isInteger(timeout) ) v = (double)valInt(timeout)/1000.0; else if ( instanceOfObject(timeout, ClassReal) ) v = valReal(timeout); else v = 0.25; to.tv_sec = (long)v; to.tv_usec = (long)(v * 1000000.0) % 1000000; } FD_ZERO(&readfds); if ( fd >= 0 ) { FD_SET(fd, &readfds); setmax = max(setmax, fd); dispatch_fd = fd; } ready = select(setmax+1, &readfds, NULL, NULL, tp); #endif dispatch_fd = ofd; return (ready > 0 ? SUCCEED : FAIL); } /* A display: dispatch until there */ /* is input or a timeout */ if ( fd >= 0 ) { iid = XtAppAddInput(ThePceXtAppContext, fd, (XtPointer) XtInputReadMask, is_pending, NULL); dispatch_fd = fd; } if ( notNil(timeout) ) { long to = -1; if ( isInteger(timeout) ) to = valInt(timeout); else if ( instanceOfObject(timeout, ClassReal) ) to = (long)(valReal(timeout)*1000.0); if ( to > 0 ) tid = XtAppAddTimeOut(ThePceXtAppContext, to, is_timeout, (XtPointer) &rval); } DEBUG(NAME_dispatch, Cprintf("Dispatch: timeout = %s, tid = %p\n", pp(timeout), (void*)tid)); if ( pceMTTryLock(LOCK_PCE) ) { RedrawDisplayManager(TheDisplayManager()); pceMTUnlock(LOCK_PCE); } /* All callbacks must be locked! */ XtAppProcessEvent(ThePceXtAppContext, XtIMXEvent|XtIMTimer|XtIMAlternateInput); if ( tid && rval ) /* if rval = FAIL, we had a timeout */ XtRemoveTimeOut(tid); if ( iid ) XtRemoveInput(iid); dispatch_fd = ofd; considerLocStillEvent(); return rval; }