Пример #1
0
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;
    }
}
Пример #3
0
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;
}