static void EatGrabEvents( TkDisplay *dispPtr, /* Display from which to consume events. */ unsigned int serial) /* Only discard events that have a serial * number at least this great. */ { Tk_RestrictProc *oldProc; GrabInfo info; ClientData oldArg, dummy; info.display = dispPtr->display; info.serial = serial; TkpSync(info.display); oldProc = Tk_RestrictEvents(GrabRestrictProc, &info, &oldArg); while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) { /* EMPTY */ } Tk_RestrictEvents(oldProc, oldArg, &dummy); }
int TkScrollWindow( Tk_Window tkwin, /* The window to be scrolled. */ GC gc, /* GC for window to be scrolled. */ int x, int y, int width, int height, /* Position rectangle to be scrolled. */ int dx, int dy, /* Distance rectangle should be moved. */ TkRegion damageRgn) /* Region to accumulate damage in. */ { Tk_RestrictProc *oldProc; ClientData oldArg, dummy; ScrollInfo info; XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc, x, y, (unsigned) width, (unsigned) height, x+dx, y+dy); info.done = 0; info.window = Tk_WindowId(tkwin); info.display = Tk_Display(tkwin); info.region = damageRgn; info.dx = dx; info.dy = dy; /* * Sync the event stream so all of the expose events will be on the Tk * event queue before we start filtering. This avoids busy waiting while * we filter events. */ TkpSync(info.display); oldProc = Tk_RestrictEvents(ScrollRestrictProc, (ClientData) &info, &oldArg); while (!info.done) { Tcl_ServiceEvent(TCL_WINDOW_EVENTS); } Tk_RestrictEvents(oldProc, oldArg, &dummy); if (XEmptyRegion((Region) damageRgn)) { return 0; } else { return 1; } }
int TkUnixDoOneXEvent( Tcl_Time *timePtr) /* Specifies the absolute time when the call * should time out. */ { TkDisplay *dispPtr; static fd_mask readMask[MASK_SIZE]; struct timeval blockTime, *timeoutPtr; Tcl_Time now; int fd, index, numFound, numFdBits = 0; fd_mask bit, *readMaskPtr = readMask; /* * Look for queued events first. */ if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) { return 1; } /* * Compute the next block time and check to see if we have timed out. Note * that HP-UX defines tv_sec to be unsigned so we have to be careful in * our arithmetic. */ if (timePtr) { Tcl_GetTime(&now); blockTime.tv_sec = timePtr->sec; blockTime.tv_usec = timePtr->usec - now.usec; if (blockTime.tv_usec < 0) { now.sec += 1; blockTime.tv_usec += 1000000; } if (blockTime.tv_sec < now.sec) { blockTime.tv_sec = 0; blockTime.tv_usec = 0; } else { blockTime.tv_sec -= now.sec; } timeoutPtr = &blockTime; } else { timeoutPtr = NULL; } /* * Set up the select mask for all of the displays. If a display has data * pending, then we want to poll instead of blocking. */ memset(readMask, 0, MASK_SIZE*sizeof(fd_mask)); for (dispPtr = TkGetDisplayList(); dispPtr != NULL; dispPtr = dispPtr->nextPtr) { XFlush(dispPtr->display); if (QLength(dispPtr->display) > 0) { blockTime.tv_sec = 0; blockTime.tv_usec = 0; } fd = ConnectionNumber(dispPtr->display); index = fd/(NBBY*sizeof(fd_mask)); bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask))); readMask[index] |= bit; if (numFdBits <= fd) { numFdBits = fd+1; } } numFound = select(numFdBits, (SELECT_MASK *) readMaskPtr, NULL, NULL, timeoutPtr); if (numFound <= 0) { /* * Some systems don't clear the masks after an error, so we have to do * it here. */ memset(readMask, 0, MASK_SIZE*sizeof(fd_mask)); } /* * Process any new events on the display connections. */ for (dispPtr = TkGetDisplayList(); dispPtr != NULL; dispPtr = dispPtr->nextPtr) { fd = ConnectionNumber(dispPtr->display); index = fd/(NBBY*sizeof(fd_mask)); bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask))); if ((readMask[index] & bit) || (QLength(dispPtr->display) > 0)) { DisplayFileProc((ClientData)dispPtr, TCL_READABLE); } } if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) { return 1; } /* * Check to see if we timed out. */ if (timePtr) { Tcl_GetTime(&now); if ((now.sec > timePtr->sec) || ((now.sec == timePtr->sec) && (now.usec > timePtr->usec))) { return 0; } } /* * We had an event but we did not generate a Tcl event from it. Behave as * though we dealt with it. (JYL&SS) */ return 1; }