OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [generic/] [tclNotify.c] - Diff between revs 578 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 578 Rev 1765
/*
/*
 * tclNotify.c --
 * tclNotify.c --
 *
 *
 *      This file implements the generic portion of the Tcl notifier.
 *      This file implements the generic portion of the Tcl notifier.
 *      The notifier is lowest-level part of the event system.  It
 *      The notifier is lowest-level part of the event system.  It
 *      manages an event queue that holds Tcl_Event structures.  The
 *      manages an event queue that holds Tcl_Event structures.  The
 *      platform specific portion of the notifier is defined in the
 *      platform specific portion of the notifier is defined in the
 *      tcl*Notify.c files in each platform directory.
 *      tcl*Notify.c files in each platform directory.
 *
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998 by Scriptics Corporation.
 * Copyright (c) 1998 by Scriptics Corporation.
 *
 *
 * See the file "license.terms" for information on usage and redistribution
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 *
 * RCS: @(#) $Id: tclNotify.c,v 1.1.1.1 2002-01-16 10:25:28 markom Exp $
 * RCS: @(#) $Id: tclNotify.c,v 1.1.1.1 2002-01-16 10:25:28 markom Exp $
 */
 */
 
 
#include "tclInt.h"
#include "tclInt.h"
#include "tclPort.h"
#include "tclPort.h"
 
 
/*
/*
 * The following static indicates whether this module has been initialized.
 * The following static indicates whether this module has been initialized.
 */
 */
 
 
static int initialized = 0;
static int initialized = 0;
 
 
/*
/*
 * For each event source (created with Tcl_CreateEventSource) there
 * For each event source (created with Tcl_CreateEventSource) there
 * is a structure of the following type:
 * is a structure of the following type:
 */
 */
 
 
typedef struct EventSource {
typedef struct EventSource {
    Tcl_EventSetupProc *setupProc;
    Tcl_EventSetupProc *setupProc;
    Tcl_EventCheckProc *checkProc;
    Tcl_EventCheckProc *checkProc;
    ClientData clientData;
    ClientData clientData;
    struct EventSource *nextPtr;
    struct EventSource *nextPtr;
} EventSource;
} EventSource;
 
 
/*
/*
 * The following structure keeps track of the state of the notifier.
 * The following structure keeps track of the state of the notifier.
 * The first three elements keep track of the event queue.  In addition to
 * The first three elements keep track of the event queue.  In addition to
 * the first (next to be serviced) and last events in the queue, we keep
 * the first (next to be serviced) and last events in the queue, we keep
 * track of a "marker" event.  This provides a simple priority mechanism
 * track of a "marker" event.  This provides a simple priority mechanism
 * whereby events can be inserted at the front of the queue but behind all
 * whereby events can be inserted at the front of the queue but behind all
 * other high-priority events already in the queue (this is used for things
 * other high-priority events already in the queue (this is used for things
 * like a sequence of Enter and Leave events generated during a grab in
 * like a sequence of Enter and Leave events generated during a grab in
 * Tk).
 * Tk).
 */
 */
 
 
static struct {
static struct {
    Tcl_Event *firstEventPtr;   /* First pending event, or NULL if none. */
    Tcl_Event *firstEventPtr;   /* First pending event, or NULL if none. */
    Tcl_Event *lastEventPtr;    /* Last pending event, or NULL if none. */
    Tcl_Event *lastEventPtr;    /* Last pending event, or NULL if none. */
    Tcl_Event *markerEventPtr;  /* Last high-priority event in queue, or
    Tcl_Event *markerEventPtr;  /* Last high-priority event in queue, or
                                 * NULL if none. */
                                 * NULL if none. */
    int serviceMode;            /* One of TCL_SERVICE_NONE or
    int serviceMode;            /* One of TCL_SERVICE_NONE or
                                 * TCL_SERVICE_ALL. */
                                 * TCL_SERVICE_ALL. */
    int blockTimeSet;           /* 0 means there is no maximum block
    int blockTimeSet;           /* 0 means there is no maximum block
                                 * time:  block forever. */
                                 * time:  block forever. */
    Tcl_Time blockTime;         /* If blockTimeSet is 1, gives the
    Tcl_Time blockTime;         /* If blockTimeSet is 1, gives the
                                 * maximum elapsed time for the next block. */
                                 * maximum elapsed time for the next block. */
    int inTraversal;            /* 1 if Tcl_SetMaxBlockTime is being
    int inTraversal;            /* 1 if Tcl_SetMaxBlockTime is being
                                 * called during an event source traversal. */
                                 * called during an event source traversal. */
    EventSource *firstEventSourcePtr;
    EventSource *firstEventSourcePtr;
                                /* Pointer to first event source in
                                /* Pointer to first event source in
                                 * global list of event sources. */
                                 * global list of event sources. */
} notifier;
} notifier;
 
 
/*
/*
 * Declarations for functions used in this file.
 * Declarations for functions used in this file.
 */
 */
 
 
static void     InitNotifier _ANSI_ARGS_((void));
static void     InitNotifier _ANSI_ARGS_((void));
static void     NotifierExitHandler _ANSI_ARGS_((ClientData clientData));
static void     NotifierExitHandler _ANSI_ARGS_((ClientData clientData));
 
 


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * InitNotifier --
 * InitNotifier --
 *
 *
 *      This routine is called to initialize the notifier module.
 *      This routine is called to initialize the notifier module.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      Creates an exit handler and initializes static data.
 *      Creates an exit handler and initializes static data.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
static void
static void
InitNotifier()
InitNotifier()
{
{
    initialized = 1;
    initialized = 1;
    memset(&notifier, 0, sizeof(notifier));
    memset(&notifier, 0, sizeof(notifier));
    notifier.serviceMode = TCL_SERVICE_NONE;
    notifier.serviceMode = TCL_SERVICE_NONE;
    Tcl_CreateExitHandler(NotifierExitHandler, NULL);
    Tcl_CreateExitHandler(NotifierExitHandler, NULL);
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * NotifierExitHandler --
 * NotifierExitHandler --
 *
 *
 *      This routine is called during Tcl finalization.
 *      This routine is called during Tcl finalization.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      Clears the notifier intialization flag.
 *      Clears the notifier intialization flag.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
static void
static void
NotifierExitHandler(clientData)
NotifierExitHandler(clientData)
    ClientData clientData;  /* Not used. */
    ClientData clientData;  /* Not used. */
{
{
    initialized = 0;
    initialized = 0;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tcl_CreateEventSource --
 * Tcl_CreateEventSource --
 *
 *
 *      This procedure is invoked to create a new source of events.
 *      This procedure is invoked to create a new source of events.
 *      The source is identified by a procedure that gets invoked
 *      The source is identified by a procedure that gets invoked
 *      during Tcl_DoOneEvent to check for events on that source
 *      during Tcl_DoOneEvent to check for events on that source
 *      and queue them.
 *      and queue them.
 *
 *
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      SetupProc and checkProc will be invoked each time that Tcl_DoOneEvent
 *      SetupProc and checkProc will be invoked each time that Tcl_DoOneEvent
 *      runs out of things to do.  SetupProc will be invoked before
 *      runs out of things to do.  SetupProc will be invoked before
 *      Tcl_DoOneEvent calls select or whatever else it uses to wait
 *      Tcl_DoOneEvent calls select or whatever else it uses to wait
 *      for events.  SetupProc typically calls functions like Tcl_WatchFile
 *      for events.  SetupProc typically calls functions like Tcl_WatchFile
 *      or Tcl_SetMaxBlockTime to indicate what to wait for.
 *      or Tcl_SetMaxBlockTime to indicate what to wait for.
 *
 *
 *      CheckProc is called after select or whatever operation was actually
 *      CheckProc is called after select or whatever operation was actually
 *      used to wait.  It figures out whether anything interesting actually
 *      used to wait.  It figures out whether anything interesting actually
 *      happened (e.g. by calling Tcl_FileReady), and then calls
 *      happened (e.g. by calling Tcl_FileReady), and then calls
 *      Tcl_QueueEvent to queue any events that are ready.
 *      Tcl_QueueEvent to queue any events that are ready.
 *
 *
 *      Each of these procedures is passed two arguments, e.g.
 *      Each of these procedures is passed two arguments, e.g.
 *              (*checkProc)(ClientData clientData, int flags));
 *              (*checkProc)(ClientData clientData, int flags));
 *      ClientData is the same as the clientData argument here, and flags
 *      ClientData is the same as the clientData argument here, and flags
 *      is a combination of things like TCL_FILE_EVENTS that indicates
 *      is a combination of things like TCL_FILE_EVENTS that indicates
 *      what events are of interest:  setupProc and checkProc use flags
 *      what events are of interest:  setupProc and checkProc use flags
 *      to figure out whether their events are relevant or not.
 *      to figure out whether their events are relevant or not.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
Tcl_CreateEventSource(setupProc, checkProc, clientData)
Tcl_CreateEventSource(setupProc, checkProc, clientData)
    Tcl_EventSetupProc *setupProc;      /* Procedure to invoke to figure out
    Tcl_EventSetupProc *setupProc;      /* Procedure to invoke to figure out
                                         * what to wait for. */
                                         * what to wait for. */
    Tcl_EventCheckProc *checkProc;      /* Procedure to call after waiting
    Tcl_EventCheckProc *checkProc;      /* Procedure to call after waiting
                                         * to see what happened. */
                                         * to see what happened. */
    ClientData clientData;              /* One-word argument to pass to
    ClientData clientData;              /* One-word argument to pass to
                                         * setupProc and checkProc. */
                                         * setupProc and checkProc. */
{
{
    EventSource *sourcePtr;
    EventSource *sourcePtr;
 
 
    if (!initialized) {
    if (!initialized) {
        InitNotifier();
        InitNotifier();
    }
    }
 
 
    sourcePtr = (EventSource *) ckalloc(sizeof(EventSource));
    sourcePtr = (EventSource *) ckalloc(sizeof(EventSource));
    sourcePtr->setupProc = setupProc;
    sourcePtr->setupProc = setupProc;
    sourcePtr->checkProc = checkProc;
    sourcePtr->checkProc = checkProc;
    sourcePtr->clientData = clientData;
    sourcePtr->clientData = clientData;
    sourcePtr->nextPtr = notifier.firstEventSourcePtr;
    sourcePtr->nextPtr = notifier.firstEventSourcePtr;
    notifier.firstEventSourcePtr = sourcePtr;
    notifier.firstEventSourcePtr = sourcePtr;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tcl_DeleteEventSource --
 * Tcl_DeleteEventSource --
 *
 *
 *      This procedure is invoked to delete the source of events
 *      This procedure is invoked to delete the source of events
 *      given by proc and clientData.
 *      given by proc and clientData.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      The given event source is cancelled, so its procedure will
 *      The given event source is cancelled, so its procedure will
 *      never again be called.  If no such source exists, nothing
 *      never again be called.  If no such source exists, nothing
 *      happens.
 *      happens.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
Tcl_DeleteEventSource(setupProc, checkProc, clientData)
Tcl_DeleteEventSource(setupProc, checkProc, clientData)
    Tcl_EventSetupProc *setupProc;      /* Procedure to invoke to figure out
    Tcl_EventSetupProc *setupProc;      /* Procedure to invoke to figure out
                                         * what to wait for. */
                                         * what to wait for. */
    Tcl_EventCheckProc *checkProc;      /* Procedure to call after waiting
    Tcl_EventCheckProc *checkProc;      /* Procedure to call after waiting
                                         * to see what happened. */
                                         * to see what happened. */
    ClientData clientData;              /* One-word argument to pass to
    ClientData clientData;              /* One-word argument to pass to
                                         * setupProc and checkProc. */
                                         * setupProc and checkProc. */
{
{
    EventSource *sourcePtr, *prevPtr;
    EventSource *sourcePtr, *prevPtr;
 
 
    for (sourcePtr = notifier.firstEventSourcePtr, prevPtr = NULL;
    for (sourcePtr = notifier.firstEventSourcePtr, prevPtr = NULL;
            sourcePtr != NULL;
            sourcePtr != NULL;
            prevPtr = sourcePtr, sourcePtr = sourcePtr->nextPtr) {
            prevPtr = sourcePtr, sourcePtr = sourcePtr->nextPtr) {
        if ((sourcePtr->setupProc != setupProc)
        if ((sourcePtr->setupProc != setupProc)
                || (sourcePtr->checkProc != checkProc)
                || (sourcePtr->checkProc != checkProc)
                || (sourcePtr->clientData != clientData)) {
                || (sourcePtr->clientData != clientData)) {
            continue;
            continue;
        }
        }
        if (prevPtr == NULL) {
        if (prevPtr == NULL) {
            notifier.firstEventSourcePtr = sourcePtr->nextPtr;
            notifier.firstEventSourcePtr = sourcePtr->nextPtr;
        } else {
        } else {
            prevPtr->nextPtr = sourcePtr->nextPtr;
            prevPtr->nextPtr = sourcePtr->nextPtr;
        }
        }
        ckfree((char *) sourcePtr);
        ckfree((char *) sourcePtr);
        return;
        return;
    }
    }
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tcl_QueueEvent --
 * Tcl_QueueEvent --
 *
 *
 *      Insert an event into the Tk event queue at one of three
 *      Insert an event into the Tk event queue at one of three
 *      positions: the head, the tail, or before a floating marker.
 *      positions: the head, the tail, or before a floating marker.
 *      Events inserted before the marker will be processed in
 *      Events inserted before the marker will be processed in
 *      first-in-first-out order, but before any events inserted at
 *      first-in-first-out order, but before any events inserted at
 *      the tail of the queue.  Events inserted at the head of the
 *      the tail of the queue.  Events inserted at the head of the
 *      queue will be processed in last-in-first-out order.
 *      queue will be processed in last-in-first-out order.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      None.
 *      None.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
Tcl_QueueEvent(evPtr, position)
Tcl_QueueEvent(evPtr, position)
    Tcl_Event* evPtr;           /* Event to add to queue.  The storage
    Tcl_Event* evPtr;           /* Event to add to queue.  The storage
                                 * space must have been allocated the caller
                                 * space must have been allocated the caller
                                 * with malloc (ckalloc), and it becomes
                                 * with malloc (ckalloc), and it becomes
                                 * the property of the event queue.  It
                                 * the property of the event queue.  It
                                 * will be freed after the event has been
                                 * will be freed after the event has been
                                 * handled. */
                                 * handled. */
    Tcl_QueuePosition position; /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,
    Tcl_QueuePosition position; /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,
                                 * TCL_QUEUE_MARK. */
                                 * TCL_QUEUE_MARK. */
{
{
    if (!initialized) {
    if (!initialized) {
        InitNotifier();
        InitNotifier();
    }
    }
 
 
    if (position == TCL_QUEUE_TAIL) {
    if (position == TCL_QUEUE_TAIL) {
        /*
        /*
         * Append the event on the end of the queue.
         * Append the event on the end of the queue.
         */
         */
 
 
        evPtr->nextPtr = NULL;
        evPtr->nextPtr = NULL;
        if (notifier.firstEventPtr == NULL) {
        if (notifier.firstEventPtr == NULL) {
            notifier.firstEventPtr = evPtr;
            notifier.firstEventPtr = evPtr;
        } else {
        } else {
            notifier.lastEventPtr->nextPtr = evPtr;
            notifier.lastEventPtr->nextPtr = evPtr;
        }
        }
        notifier.lastEventPtr = evPtr;
        notifier.lastEventPtr = evPtr;
    } else if (position == TCL_QUEUE_HEAD) {
    } else if (position == TCL_QUEUE_HEAD) {
        /*
        /*
         * Push the event on the head of the queue.
         * Push the event on the head of the queue.
         */
         */
 
 
        evPtr->nextPtr = notifier.firstEventPtr;
        evPtr->nextPtr = notifier.firstEventPtr;
        if (notifier.firstEventPtr == NULL) {
        if (notifier.firstEventPtr == NULL) {
            notifier.lastEventPtr = evPtr;
            notifier.lastEventPtr = evPtr;
        }
        }
        notifier.firstEventPtr = evPtr;
        notifier.firstEventPtr = evPtr;
    } else if (position == TCL_QUEUE_MARK) {
    } else if (position == TCL_QUEUE_MARK) {
        /*
        /*
         * Insert the event after the current marker event and advance
         * Insert the event after the current marker event and advance
         * the marker to the new event.
         * the marker to the new event.
         */
         */
 
 
        if (notifier.markerEventPtr == NULL) {
        if (notifier.markerEventPtr == NULL) {
            evPtr->nextPtr = notifier.firstEventPtr;
            evPtr->nextPtr = notifier.firstEventPtr;
            notifier.firstEventPtr = evPtr;
            notifier.firstEventPtr = evPtr;
        } else {
        } else {
            evPtr->nextPtr = notifier.markerEventPtr->nextPtr;
            evPtr->nextPtr = notifier.markerEventPtr->nextPtr;
            notifier.markerEventPtr->nextPtr = evPtr;
            notifier.markerEventPtr->nextPtr = evPtr;
        }
        }
        notifier.markerEventPtr = evPtr;
        notifier.markerEventPtr = evPtr;
        if (evPtr->nextPtr == NULL) {
        if (evPtr->nextPtr == NULL) {
            notifier.lastEventPtr = evPtr;
            notifier.lastEventPtr = evPtr;
        }
        }
    }
    }
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tcl_DeleteEvents --
 * Tcl_DeleteEvents --
 *
 *
 *      Calls a procedure for each event in the queue and deletes those
 *      Calls a procedure for each event in the queue and deletes those
 *      for which the procedure returns 1. Events for which the
 *      for which the procedure returns 1. Events for which the
 *      procedure returns 0 are left in the queue.
 *      procedure returns 0 are left in the queue.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      Potentially removes one or more events from the event queue.
 *      Potentially removes one or more events from the event queue.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
Tcl_DeleteEvents(proc, clientData)
Tcl_DeleteEvents(proc, clientData)
    Tcl_EventDeleteProc *proc;          /* The procedure to call. */
    Tcl_EventDeleteProc *proc;          /* The procedure to call. */
    ClientData clientData;              /* type-specific data. */
    ClientData clientData;              /* type-specific data. */
{
{
    Tcl_Event *evPtr, *prevPtr, *hold;
    Tcl_Event *evPtr, *prevPtr, *hold;
 
 
    if (!initialized) {
    if (!initialized) {
        InitNotifier();
        InitNotifier();
    }
    }
 
 
    for (prevPtr = (Tcl_Event *) NULL, evPtr = notifier.firstEventPtr;
    for (prevPtr = (Tcl_Event *) NULL, evPtr = notifier.firstEventPtr;
             evPtr != (Tcl_Event *) NULL;
             evPtr != (Tcl_Event *) NULL;
             ) {
             ) {
        if ((*proc) (evPtr, clientData) == 1) {
        if ((*proc) (evPtr, clientData) == 1) {
            if (notifier.firstEventPtr == evPtr) {
            if (notifier.firstEventPtr == evPtr) {
                notifier.firstEventPtr = evPtr->nextPtr;
                notifier.firstEventPtr = evPtr->nextPtr;
                if (evPtr->nextPtr == NULL) {
                if (evPtr->nextPtr == NULL) {
                    notifier.lastEventPtr = prevPtr;
                    notifier.lastEventPtr = prevPtr;
                }
                }
                if (notifier.markerEventPtr == evPtr) {
                if (notifier.markerEventPtr == evPtr) {
                    notifier.markerEventPtr = prevPtr;
                    notifier.markerEventPtr = prevPtr;
                }
                }
            } else {
            } else {
                prevPtr->nextPtr = evPtr->nextPtr;
                prevPtr->nextPtr = evPtr->nextPtr;
            }
            }
            hold = evPtr;
            hold = evPtr;
            evPtr = evPtr->nextPtr;
            evPtr = evPtr->nextPtr;
            ckfree((char *) hold);
            ckfree((char *) hold);
        } else {
        } else {
            prevPtr = evPtr;
            prevPtr = evPtr;
            evPtr = evPtr->nextPtr;
            evPtr = evPtr->nextPtr;
        }
        }
    }
    }
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tcl_ServiceEvent --
 * Tcl_ServiceEvent --
 *
 *
 *      Process one event from the event queue, or invoke an
 *      Process one event from the event queue, or invoke an
 *      asynchronous event handler.
 *      asynchronous event handler.
 *
 *
 * Results:
 * Results:
 *      The return value is 1 if the procedure actually found an event
 *      The return value is 1 if the procedure actually found an event
 *      to process.  If no processing occurred, then 0 is returned.
 *      to process.  If no processing occurred, then 0 is returned.
 *
 *
 * Side effects:
 * Side effects:
 *      Invokes all of the event handlers for the highest priority
 *      Invokes all of the event handlers for the highest priority
 *      event in the event queue.  May collapse some events into a
 *      event in the event queue.  May collapse some events into a
 *      single event or discard stale events.
 *      single event or discard stale events.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
int
int
Tcl_ServiceEvent(flags)
Tcl_ServiceEvent(flags)
    int flags;                  /* Indicates what events should be processed.
    int flags;                  /* Indicates what events should be processed.
                                 * May be any combination of TCL_WINDOW_EVENTS
                                 * May be any combination of TCL_WINDOW_EVENTS
                                 * TCL_FILE_EVENTS, TCL_TIMER_EVENTS, or other
                                 * TCL_FILE_EVENTS, TCL_TIMER_EVENTS, or other
                                 * flags defined elsewhere.  Events not
                                 * flags defined elsewhere.  Events not
                                 * matching this will be skipped for processing
                                 * matching this will be skipped for processing
                                 * later. */
                                 * later. */
{
{
    Tcl_Event *evPtr, *prevPtr;
    Tcl_Event *evPtr, *prevPtr;
    Tcl_EventProc *proc;
    Tcl_EventProc *proc;
 
 
    if (!initialized) {
    if (!initialized) {
        InitNotifier();
        InitNotifier();
    }
    }
 
 
    /*
    /*
     * Asynchronous event handlers are considered to be the highest
     * Asynchronous event handlers are considered to be the highest
     * priority events, and so must be invoked before we process events
     * priority events, and so must be invoked before we process events
     * on the event queue.
     * on the event queue.
     */
     */
 
 
    if (Tcl_AsyncReady()) {
    if (Tcl_AsyncReady()) {
        (void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0);
        (void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0);
        return 1;
        return 1;
    }
    }
 
 
    /*
    /*
     * No event flags is equivalent to TCL_ALL_EVENTS.
     * No event flags is equivalent to TCL_ALL_EVENTS.
     */
     */
 
 
    if ((flags & TCL_ALL_EVENTS) == 0) {
    if ((flags & TCL_ALL_EVENTS) == 0) {
        flags |= TCL_ALL_EVENTS;
        flags |= TCL_ALL_EVENTS;
    }
    }
 
 
    /*
    /*
     * Loop through all the events in the queue until we find one
     * Loop through all the events in the queue until we find one
     * that can actually be handled.
     * that can actually be handled.
     */
     */
 
 
    for (evPtr = notifier.firstEventPtr; evPtr != NULL;
    for (evPtr = notifier.firstEventPtr; evPtr != NULL;
         evPtr = evPtr->nextPtr) {
         evPtr = evPtr->nextPtr) {
        /*
        /*
         * Call the handler for the event.  If it actually handles the
         * Call the handler for the event.  If it actually handles the
         * event then free the storage for the event.  There are two
         * event then free the storage for the event.  There are two
         * tricky things here, but stemming from the fact that the event
         * tricky things here, but stemming from the fact that the event
         * code may be re-entered while servicing the event:
         * code may be re-entered while servicing the event:
         *
         *
         * 1. Set the "proc" field to NULL.  This is a signal to ourselves
         * 1. Set the "proc" field to NULL.  This is a signal to ourselves
         *    that we shouldn't reexecute the handler if the event loop
         *    that we shouldn't reexecute the handler if the event loop
         *    is re-entered.
         *    is re-entered.
         * 2. When freeing the event, must search the queue again from the
         * 2. When freeing the event, must search the queue again from the
         *    front to find it.  This is because the event queue could
         *    front to find it.  This is because the event queue could
         *    change almost arbitrarily while handling the event, so we
         *    change almost arbitrarily while handling the event, so we
         *    can't depend on pointers found now still being valid when
         *    can't depend on pointers found now still being valid when
         *    the handler returns.
         *    the handler returns.
         */
         */
 
 
        proc = evPtr->proc;
        proc = evPtr->proc;
        evPtr->proc = NULL;
        evPtr->proc = NULL;
        if ((proc != NULL) && (*proc)(evPtr, flags)) {
        if ((proc != NULL) && (*proc)(evPtr, flags)) {
            if (notifier.firstEventPtr == evPtr) {
            if (notifier.firstEventPtr == evPtr) {
                notifier.firstEventPtr = evPtr->nextPtr;
                notifier.firstEventPtr = evPtr->nextPtr;
                if (evPtr->nextPtr == NULL) {
                if (evPtr->nextPtr == NULL) {
                    notifier.lastEventPtr = NULL;
                    notifier.lastEventPtr = NULL;
                }
                }
                if (notifier.markerEventPtr == evPtr) {
                if (notifier.markerEventPtr == evPtr) {
                    notifier.markerEventPtr = NULL;
                    notifier.markerEventPtr = NULL;
                }
                }
            } else {
            } else {
                for (prevPtr = notifier.firstEventPtr;
                for (prevPtr = notifier.firstEventPtr;
                     prevPtr->nextPtr != evPtr; prevPtr = prevPtr->nextPtr) {
                     prevPtr->nextPtr != evPtr; prevPtr = prevPtr->nextPtr) {
                    /* Empty loop body. */
                    /* Empty loop body. */
                }
                }
                prevPtr->nextPtr = evPtr->nextPtr;
                prevPtr->nextPtr = evPtr->nextPtr;
                if (evPtr->nextPtr == NULL) {
                if (evPtr->nextPtr == NULL) {
                    notifier.lastEventPtr = prevPtr;
                    notifier.lastEventPtr = prevPtr;
                }
                }
                if (notifier.markerEventPtr == evPtr) {
                if (notifier.markerEventPtr == evPtr) {
                    notifier.markerEventPtr = prevPtr;
                    notifier.markerEventPtr = prevPtr;
                }
                }
            }
            }
            ckfree((char *) evPtr);
            ckfree((char *) evPtr);
            return 1;
            return 1;
        } else {
        } else {
            /*
            /*
             * The event wasn't actually handled, so we have to restore
             * The event wasn't actually handled, so we have to restore
             * the proc field to allow the event to be attempted again.
             * the proc field to allow the event to be attempted again.
             */
             */
 
 
            evPtr->proc = proc;
            evPtr->proc = proc;
        }
        }
 
 
        /*
        /*
         * The handler for this event asked to defer it.  Just go on to
         * The handler for this event asked to defer it.  Just go on to
         * the next event.
         * the next event.
         */
         */
 
 
        continue;
        continue;
    }
    }
    return 0;
    return 0;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tcl_GetServiceMode --
 * Tcl_GetServiceMode --
 *
 *
 *      This routine returns the current service mode of the notifier.
 *      This routine returns the current service mode of the notifier.
 *
 *
 * Results:
 * Results:
 *      Returns either TCL_SERVICE_ALL or TCL_SERVICE_NONE.
 *      Returns either TCL_SERVICE_ALL or TCL_SERVICE_NONE.
 *
 *
 * Side effects:
 * Side effects:
 *      None.
 *      None.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
int
int
Tcl_GetServiceMode()
Tcl_GetServiceMode()
{
{
    if (!initialized) {
    if (!initialized) {
        InitNotifier();
        InitNotifier();
    }
    }
 
 
    return notifier.serviceMode;
    return notifier.serviceMode;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tcl_SetServiceMode --
 * Tcl_SetServiceMode --
 *
 *
 *      This routine sets the current service mode of the notifier.
 *      This routine sets the current service mode of the notifier.
 *
 *
 * Results:
 * Results:
 *      Returns the previous service mode.
 *      Returns the previous service mode.
 *
 *
 * Side effects:
 * Side effects:
 *      None.
 *      None.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
int
int
Tcl_SetServiceMode(mode)
Tcl_SetServiceMode(mode)
    int mode;                   /* New service mode: TCL_SERVICE_ALL or
    int mode;                   /* New service mode: TCL_SERVICE_ALL or
                                 * TCL_SERVICE_NONE */
                                 * TCL_SERVICE_NONE */
{
{
    int oldMode;
    int oldMode;
 
 
    if (!initialized) {
    if (!initialized) {
        InitNotifier();
        InitNotifier();
    }
    }
 
 
    oldMode = notifier.serviceMode;
    oldMode = notifier.serviceMode;
    notifier.serviceMode = mode;
    notifier.serviceMode = mode;
    return oldMode;
    return oldMode;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tcl_SetMaxBlockTime --
 * Tcl_SetMaxBlockTime --
 *
 *
 *      This procedure is invoked by event sources to tell the notifier
 *      This procedure is invoked by event sources to tell the notifier
 *      how long it may block the next time it blocks.  The timePtr
 *      how long it may block the next time it blocks.  The timePtr
 *      argument gives a maximum time;  the actual time may be less if
 *      argument gives a maximum time;  the actual time may be less if
 *      some other event source requested a smaller time.
 *      some other event source requested a smaller time.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      May reduce the length of the next sleep in the notifier.
 *      May reduce the length of the next sleep in the notifier.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
Tcl_SetMaxBlockTime(timePtr)
Tcl_SetMaxBlockTime(timePtr)
    Tcl_Time *timePtr;          /* Specifies a maximum elapsed time for
    Tcl_Time *timePtr;          /* Specifies a maximum elapsed time for
                                 * the next blocking operation in the
                                 * the next blocking operation in the
                                 * event notifier. */
                                 * event notifier. */
{
{
    if (!initialized) {
    if (!initialized) {
        InitNotifier();
        InitNotifier();
    }
    }
 
 
    if (!notifier.blockTimeSet || (timePtr->sec < notifier.blockTime.sec)
    if (!notifier.blockTimeSet || (timePtr->sec < notifier.blockTime.sec)
            || ((timePtr->sec == notifier.blockTime.sec)
            || ((timePtr->sec == notifier.blockTime.sec)
            && (timePtr->usec < notifier.blockTime.usec))) {
            && (timePtr->usec < notifier.blockTime.usec))) {
        notifier.blockTime = *timePtr;
        notifier.blockTime = *timePtr;
        notifier.blockTimeSet = 1;
        notifier.blockTimeSet = 1;
    }
    }
 
 
    /*
    /*
     * If we are called outside an event source traversal, set the
     * If we are called outside an event source traversal, set the
     * timeout immediately.
     * timeout immediately.
     */
     */
 
 
    if (!notifier.inTraversal) {
    if (!notifier.inTraversal) {
        if (notifier.blockTimeSet) {
        if (notifier.blockTimeSet) {
            Tcl_SetTimer(&notifier.blockTime);
            Tcl_SetTimer(&notifier.blockTime);
        } else {
        } else {
            Tcl_SetTimer(NULL);
            Tcl_SetTimer(NULL);
        }
        }
    }
    }
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tcl_DoOneEvent --
 * Tcl_DoOneEvent --
 *
 *
 *      Process a single event of some sort.  If there's no work to
 *      Process a single event of some sort.  If there's no work to
 *      do, wait for an event to occur, then process it.
 *      do, wait for an event to occur, then process it.
 *
 *
 * Results:
 * Results:
 *      The return value is 1 if the procedure actually found an event
 *      The return value is 1 if the procedure actually found an event
 *      to process.  If no processing occurred, then 0 is returned (this
 *      to process.  If no processing occurred, then 0 is returned (this
 *      can happen if the TCL_DONT_WAIT flag is set or if there are no
 *      can happen if the TCL_DONT_WAIT flag is set or if there are no
 *      event handlers to wait for in the set specified by flags).
 *      event handlers to wait for in the set specified by flags).
 *
 *
 * Side effects:
 * Side effects:
 *      May delay execution of process while waiting for an event,
 *      May delay execution of process while waiting for an event,
 *      unless TCL_DONT_WAIT is set in the flags argument.  Event
 *      unless TCL_DONT_WAIT is set in the flags argument.  Event
 *      sources are invoked to check for and queue events.  Event
 *      sources are invoked to check for and queue events.  Event
 *      handlers may produce arbitrary side effects.
 *      handlers may produce arbitrary side effects.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
int
int
Tcl_DoOneEvent(flags)
Tcl_DoOneEvent(flags)
    int flags;                  /* Miscellaneous flag values:  may be any
    int flags;                  /* Miscellaneous flag values:  may be any
                                 * combination of TCL_DONT_WAIT,
                                 * combination of TCL_DONT_WAIT,
                                 * TCL_WINDOW_EVENTS, TCL_FILE_EVENTS,
                                 * TCL_WINDOW_EVENTS, TCL_FILE_EVENTS,
                                 * TCL_TIMER_EVENTS, TCL_IDLE_EVENTS, or
                                 * TCL_TIMER_EVENTS, TCL_IDLE_EVENTS, or
                                 * others defined by event sources. */
                                 * others defined by event sources. */
{
{
    int result = 0, oldMode;
    int result = 0, oldMode;
    EventSource *sourcePtr;
    EventSource *sourcePtr;
    Tcl_Time *timePtr;
    Tcl_Time *timePtr;
 
 
    if (!initialized) {
    if (!initialized) {
        InitNotifier();
        InitNotifier();
    }
    }
 
 
    /*
    /*
     * The first thing we do is to service any asynchronous event
     * The first thing we do is to service any asynchronous event
     * handlers.
     * handlers.
     */
     */
 
 
    if (Tcl_AsyncReady()) {
    if (Tcl_AsyncReady()) {
        (void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0);
        (void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0);
        return 1;
        return 1;
    }
    }
 
 
    /*
    /*
     * No event flags is equivalent to TCL_ALL_EVENTS.
     * No event flags is equivalent to TCL_ALL_EVENTS.
     */
     */
 
 
    if ((flags & TCL_ALL_EVENTS) == 0) {
    if ((flags & TCL_ALL_EVENTS) == 0) {
        flags |= TCL_ALL_EVENTS;
        flags |= TCL_ALL_EVENTS;
    }
    }
 
 
    /*
    /*
     * Set the service mode to none so notifier event routines won't
     * Set the service mode to none so notifier event routines won't
     * try to service events recursively.
     * try to service events recursively.
     */
     */
 
 
    oldMode = notifier.serviceMode;
    oldMode = notifier.serviceMode;
    notifier.serviceMode = TCL_SERVICE_NONE;
    notifier.serviceMode = TCL_SERVICE_NONE;
 
 
    /*
    /*
     * The core of this procedure is an infinite loop, even though
     * The core of this procedure is an infinite loop, even though
     * we only service one event.  The reason for this is that we
     * we only service one event.  The reason for this is that we
     * may be processing events that don't do anything inside of Tcl.
     * may be processing events that don't do anything inside of Tcl.
     */
     */
 
 
    while (1) {
    while (1) {
 
 
        /*
        /*
         * If idle events are the only things to service, skip the
         * If idle events are the only things to service, skip the
         * main part of the loop and go directly to handle idle
         * main part of the loop and go directly to handle idle
         * events (i.e. don't wait even if TCL_DONT_WAIT isn't set).
         * events (i.e. don't wait even if TCL_DONT_WAIT isn't set).
         */
         */
 
 
        if ((flags & TCL_ALL_EVENTS) == TCL_IDLE_EVENTS) {
        if ((flags & TCL_ALL_EVENTS) == TCL_IDLE_EVENTS) {
            flags = TCL_IDLE_EVENTS|TCL_DONT_WAIT;
            flags = TCL_IDLE_EVENTS|TCL_DONT_WAIT;
            goto idleEvents;
            goto idleEvents;
        }
        }
 
 
        /*
        /*
         * Ask Tcl to service a queued event, if there are any.
         * Ask Tcl to service a queued event, if there are any.
         */
         */
 
 
        if (Tcl_ServiceEvent(flags)) {
        if (Tcl_ServiceEvent(flags)) {
            result = 1;
            result = 1;
            break;
            break;
        }
        }
 
 
        /*
        /*
         * If TCL_DONT_WAIT is set, be sure to poll rather than
         * If TCL_DONT_WAIT is set, be sure to poll rather than
         * blocking, otherwise reset the block time to infinity.
         * blocking, otherwise reset the block time to infinity.
         */
         */
 
 
        if (flags & TCL_DONT_WAIT) {
        if (flags & TCL_DONT_WAIT) {
            notifier.blockTime.sec = 0;
            notifier.blockTime.sec = 0;
            notifier.blockTime.usec = 0;
            notifier.blockTime.usec = 0;
            notifier.blockTimeSet = 1;
            notifier.blockTimeSet = 1;
        } else {
        } else {
            notifier.blockTimeSet = 0;
            notifier.blockTimeSet = 0;
        }
        }
 
 
        /*
        /*
         * Set up all the event sources for new events.  This will
         * Set up all the event sources for new events.  This will
         * cause the block time to be updated if necessary.
         * cause the block time to be updated if necessary.
         */
         */
 
 
        notifier.inTraversal = 1;
        notifier.inTraversal = 1;
        for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
        for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
             sourcePtr = sourcePtr->nextPtr) {
             sourcePtr = sourcePtr->nextPtr) {
            if (sourcePtr->setupProc) {
            if (sourcePtr->setupProc) {
                (sourcePtr->setupProc)(sourcePtr->clientData, flags);
                (sourcePtr->setupProc)(sourcePtr->clientData, flags);
            }
            }
        }
        }
        notifier.inTraversal = 0;
        notifier.inTraversal = 0;
 
 
        if ((flags & TCL_DONT_WAIT) || notifier.blockTimeSet) {
        if ((flags & TCL_DONT_WAIT) || notifier.blockTimeSet) {
            timePtr = &notifier.blockTime;
            timePtr = &notifier.blockTime;
        } else {
        } else {
            timePtr = NULL;
            timePtr = NULL;
        }
        }
 
 
        /*
        /*
         * Wait for a new event or a timeout.  If Tcl_WaitForEvent
         * Wait for a new event or a timeout.  If Tcl_WaitForEvent
         * returns -1, we should abort Tcl_DoOneEvent.
         * returns -1, we should abort Tcl_DoOneEvent.
         */
         */
 
 
        result = Tcl_WaitForEvent(timePtr);
        result = Tcl_WaitForEvent(timePtr);
        if (result < 0) {
        if (result < 0) {
            result = 0;
            result = 0;
            break;
            break;
        }
        }
 
 
        /*
        /*
         * Check all the event sources for new events.
         * Check all the event sources for new events.
         */
         */
 
 
        for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
        for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
             sourcePtr = sourcePtr->nextPtr) {
             sourcePtr = sourcePtr->nextPtr) {
            if (sourcePtr->checkProc) {
            if (sourcePtr->checkProc) {
                (sourcePtr->checkProc)(sourcePtr->clientData, flags);
                (sourcePtr->checkProc)(sourcePtr->clientData, flags);
            }
            }
        }
        }
 
 
        /*
        /*
         * Check for events queued by the notifier or event sources.
         * Check for events queued by the notifier or event sources.
         */
         */
 
 
        if (Tcl_ServiceEvent(flags)) {
        if (Tcl_ServiceEvent(flags)) {
            result = 1;
            result = 1;
            break;
            break;
        }
        }
 
 
        /*
        /*
         * We've tried everything at this point, but nobody we know
         * We've tried everything at this point, but nobody we know
         * about had anything to do.  Check for idle events.  If none,
         * about had anything to do.  Check for idle events.  If none,
         * either quit or go back to the top and try again.
         * either quit or go back to the top and try again.
         */
         */
 
 
        idleEvents:
        idleEvents:
        if (flags & TCL_IDLE_EVENTS) {
        if (flags & TCL_IDLE_EVENTS) {
            if (TclServiceIdle()) {
            if (TclServiceIdle()) {
                result = 1;
                result = 1;
                break;
                break;
            }
            }
        }
        }
        if (flags & TCL_DONT_WAIT) {
        if (flags & TCL_DONT_WAIT) {
            break;
            break;
        }
        }
 
 
        /*
        /*
         * If Tcl_WaitForEvent has returned 1,
         * If Tcl_WaitForEvent has returned 1,
         * indicating that one system event has been dispatched
         * indicating that one system event has been dispatched
         * (and thus that some Tcl code might have been indirectly executed),
         * (and thus that some Tcl code might have been indirectly executed),
         * we break out of the loop.
         * we break out of the loop.
         * We do this to give VwaitCmd for instance a chance to check
         * We do this to give VwaitCmd for instance a chance to check
         * if that system event had the side effect of changing the
         * if that system event had the side effect of changing the
         * variable (so the vwait can return and unwind properly).
         * variable (so the vwait can return and unwind properly).
         *
         *
         * NB: We will process idle events if any first, because
         * NB: We will process idle events if any first, because
         *     otherwise we might never do the idle events if the notifier
         *     otherwise we might never do the idle events if the notifier
         *     always gets system events.
         *     always gets system events.
         */
         */
 
 
        if (result) {
        if (result) {
            break;
            break;
        }
        }
 
 
    }
    }
 
 
    notifier.serviceMode = oldMode;
    notifier.serviceMode = oldMode;
    return result;
    return result;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tcl_ServiceAll --
 * Tcl_ServiceAll --
 *
 *
 *      This routine checks all of the event sources, processes
 *      This routine checks all of the event sources, processes
 *      events that are on the Tcl event queue, and then calls the
 *      events that are on the Tcl event queue, and then calls the
 *      any idle handlers.  Platform specific notifier callbacks that
 *      any idle handlers.  Platform specific notifier callbacks that
 *      generate events should call this routine before returning to
 *      generate events should call this routine before returning to
 *      the system in order to ensure that Tcl gets a chance to
 *      the system in order to ensure that Tcl gets a chance to
 *      process the new events.
 *      process the new events.
 *
 *
 * Results:
 * Results:
 *      Returns 1 if an event or idle handler was invoked, else 0.
 *      Returns 1 if an event or idle handler was invoked, else 0.
 *
 *
 * Side effects:
 * Side effects:
 *      Anything that an event or idle handler may do.
 *      Anything that an event or idle handler may do.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
int
int
Tcl_ServiceAll()
Tcl_ServiceAll()
{
{
    int result = 0;
    int result = 0;
    EventSource *sourcePtr;
    EventSource *sourcePtr;
 
 
    if (!initialized) {
    if (!initialized) {
        InitNotifier();
        InitNotifier();
    }
    }
 
 
    if (notifier.serviceMode == TCL_SERVICE_NONE) {
    if (notifier.serviceMode == TCL_SERVICE_NONE) {
        return result;
        return result;
    }
    }
 
 
    /*
    /*
     * We need to turn off event servicing like we to in Tcl_DoOneEvent,
     * We need to turn off event servicing like we to in Tcl_DoOneEvent,
     * to avoid recursive calls.
     * to avoid recursive calls.
     */
     */
 
 
    notifier.serviceMode = TCL_SERVICE_NONE;
    notifier.serviceMode = TCL_SERVICE_NONE;
 
 
    /*
    /*
     * Check async handlers first.
     * Check async handlers first.
     */
     */
 
 
    if (Tcl_AsyncReady()) {
    if (Tcl_AsyncReady()) {
        (void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0);
        (void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0);
    }
    }
 
 
    /*
    /*
     * Make a single pass through all event sources, queued events,
     * Make a single pass through all event sources, queued events,
     * and idle handlers.  Note that we wait to update the notifier
     * and idle handlers.  Note that we wait to update the notifier
     * timer until the end so we can avoid multiple changes.
     * timer until the end so we can avoid multiple changes.
     */
     */
 
 
    notifier.inTraversal = 1;
    notifier.inTraversal = 1;
    notifier.blockTimeSet = 0;
    notifier.blockTimeSet = 0;
 
 
    for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
    for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
         sourcePtr = sourcePtr->nextPtr) {
         sourcePtr = sourcePtr->nextPtr) {
        if (sourcePtr->setupProc) {
        if (sourcePtr->setupProc) {
            (sourcePtr->setupProc)(sourcePtr->clientData, TCL_ALL_EVENTS);
            (sourcePtr->setupProc)(sourcePtr->clientData, TCL_ALL_EVENTS);
        }
        }
    }
    }
    for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
    for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
         sourcePtr = sourcePtr->nextPtr) {
         sourcePtr = sourcePtr->nextPtr) {
        if (sourcePtr->checkProc) {
        if (sourcePtr->checkProc) {
            (sourcePtr->checkProc)(sourcePtr->clientData, TCL_ALL_EVENTS);
            (sourcePtr->checkProc)(sourcePtr->clientData, TCL_ALL_EVENTS);
        }
        }
    }
    }
 
 
    while (Tcl_ServiceEvent(0)) {
    while (Tcl_ServiceEvent(0)) {
        result = 1;
        result = 1;
    }
    }
    if (TclServiceIdle()) {
    if (TclServiceIdle()) {
        result = 1;
        result = 1;
    }
    }
 
 
    if (!notifier.blockTimeSet) {
    if (!notifier.blockTimeSet) {
        Tcl_SetTimer(NULL);
        Tcl_SetTimer(NULL);
    } else {
    } else {
        Tcl_SetTimer(&notifier.blockTime);
        Tcl_SetTimer(&notifier.blockTime);
    }
    }
    notifier.inTraversal = 0;
    notifier.inTraversal = 0;
    notifier.serviceMode = TCL_SERVICE_ALL;
    notifier.serviceMode = TCL_SERVICE_ALL;
    return result;
    return result;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.