NAME

       Tcl_CreateEventSource,   Tcl_DeleteEventSource,   Tcl_Set­
       MaxBlockTime,    Tcl_QueueEvent,     Tcl_ThreadQueueEvent,
       Tcl_ThreadAlert,  Tcl_GetCurrentThread,  Tcl_DeleteEvents,
       Tcl_InitNotifier, Tcl_FinalizeNotifier,  Tcl_WaitForEvent,
       Tcl_AlertNotifier,  Tcl_SetTimer, Tcl_ServiceAll, Tcl_Ser­
       viceEvent, Tcl_GetServiceMode,  Tcl_SetServiceMode  -  the
       event queue and notifier interfaces


SYNOPSIS

       #include <tcl.h>

       void
       Tcl_CreateEventSource(setupProc, checkProc, clientData)

       void
       Tcl_DeleteEventSource(setupProc, checkProc, clientData)

       void
       Tcl_SetMaxBlockTime(timePtr)

       void
       Tcl_QueueEvent(evPtr, position)

       void                                                       |
       Tcl_ThreadQueueEvent(threadId, evPtr, position)            |

       void                                                       |
       Tcl_ThreadAlert(threadId, clientData)                      |

       Tcl_ThreadId                                               |
       Tcl_GetCurrentThread()                                     |

       void                                                       |
       Tcl_DeleteEvents(deleteProc, clientData)                   |

       ClientData                                                 |
       Tcl_InitNotifier()                                         |

       void                                                       |
       Tcl_FinalizeNotifier(clientData)                           |

       int                                                        |
       Tcl_WaitForEvent(timePtr)                                  |

       void                                                       |
       Tcl_AlertNotifier(clientData)                              |

       void                                                       |
       Tcl_SetTimer(timePtr)                                      |

       int                                                        |


       int                                                        |
       Tcl_ServiceEvent(flags)                                    |

       int                                                        |
       Tcl_GetServiceMode()                                       |

       int                                                        |
       Tcl_SetServiceMode(mode)                                   |


ARGUMENTS

       Tcl_EventSetupProc    *setupProc     (in)      Procedure
                                                      to   invoke
                                                      to  prepare
                                                      for   event
                                                      wait     in
                                                      Tcl_DoOneEvent.

       Tcl_EventCheckProc    *checkProc     (in)      Procedure
                                                      for
                                                      Tcl_DoOneEvent
                                                      to   invoke
                                                      after wait­
                                                      ing     for
                                                      events.
                                                      Checks   to
                                                      see  if any
                                                      events have
                                                      occurred
                                                      and, if so,
                                                      queues
                                                      them.

       ClientData            clientData     (in)      Arbitrary
                                                      one-word
                                                      value    to
                                                      pass     to
                                                      setupProc,
                                                      checkProc,
                                                      or
                                                      deleteProc.

       Tcl_Time              *timePtr       (in)      Indicates
                                                      the maximum
                                                      amount   of
                                                      time     to
                                                      wait for an
                                                      event.
                                                      This     is
                                                      specified
                                                      as       an
                                                      interval

                                                      to   wait),
                                                      not      an
                                                      absolute
                                                      time  (when
                                                      to wakeup).
                                                      If      the
                                                      pointer
                                                      passed   to
                                                      Tcl_Wait­
                                                      ForEvent is
                                                      NULL,    it
                                                      means there
                                                      is no maxi­
                                                      mum    wait
                                                      time:  wait
                                                      forever  if
                                                      necessary.

       Tcl_Event             *evPtr         (in)      An event to
                                                      add  to the
                                                      event
                                                      queue.  The
                                                      storage for
                                                      the   event
                                                      must   have
                                                      been  allo­
                                                      cated    by
                                                      the  caller
                                                      using
                                                      Tcl_Alloc
                                                      or ckalloc.

       Tcl_QueuePosition     position       (in)      Where    to
                                                      add the new
                                                      event    in
                                                      the  queue:
                                                      TCL_QUEUE_TAIL,
                                                      TCL_QUEUE_HEAD,
                                                      or
                                                      TCL_QUEUE_MARK.

       Tcl_ThreadId          threadId       (in)      A    unique
                                                      identifier
                                                      for       a
                                                      thread.

       Tcl_EventDeleteProc   *deleteProc    (in)      Procedure
                                                      to   invoke
                                                      for    each
                                                      queued
                                                      event    in
                                                      Tcl_Dele­
                                                      teEvents.

                                                      of   events
                                                      to service.
                                                      These flags
                                                      are     the
                                                      same     as
                                                      those
                                                      passed   to
                                                      Tcl_DoOneEvent.

       int                   mode           (in)                         ||
                                                      Inidicates  |
                                                      whether     |
                                                      events      |
                                                      should   be |
                                                      serviced by |
                                                      Tcl_Ser­    |
                                                      viceAll.    |
                                                      Must be one |
                                                      of TCL_SER­ |
                                                      VICE_NONE   |
                                                      or TCL_SER­ |
                                                      VICE_ALL.
_________________________________________________________________


INTRODUCTION

       The  interfaces  described  here are used to customize the
       Tcl event loop.  The two most common customizations are to
       add  new  sources  of events and to merge Tcl's event loop
       with some other event loop, such as  one  provided  by  an
       application in which Tcl is embedded.  Each of these tasks
       is described in a separate section below.

       The procedures in  this  manual  entry  are  the  building
       blocks out of which the Tcl event notifier is constructed.
       The event notifier is the lowest layer in  the  Tcl  event
       mechanism.  It consists of three things:

       [1]    Event  sources:  these  represent the ways in which
              events can be generated.  For example, there  is  a
              timer  event source that implements the Tcl_Create­
              TimerHandler procedure and the after  command,  and
              there  is  a  file event source that implements the
              Tcl_CreateFileHandler procedure  on  Unix  systems.
              An  event  source  must  work  with the notifier to
              detect events at the right times,  record  them  on
              the event queue, and eventually notify higher-level
              software that they have occurred.   The  procedures
              Tcl_CreateEventSource,  Tcl_DeleteEventSource,  and
              Tcl_SetMaxBlockTime, Tcl_QueueEvent, and  Tcl_Dele­
              teEvents are used primarily by event sources.

       [2]    The  event  queue:  for  non-threaded applications,

              containing  events  that have been detected but not
              yet serviced.  Event sources place events onto  the
              queue  so  that  they  may be processed in order at
              appropriate times during the event loop. The  event
              queue  guarantees  a  fair discipline of event han­
              dling, so that no event source can starve the  oth­
              ers.  It also allows events to be saved for servic­
              ing at a future time.  Threaded  applications  work |
              in  a  similar manner, except that there is a sepa­ |
              rate event queue for each thread containing  a  Tcl |
              interpreter.   Tcl_QueueEvent is used (primarily by |
              event sources) to add events to the event queue and |
              Tcl_DeleteEvents  is used to remove events from the |
              queue  without  processing  them.   In  a  threaded |
              application,  Tcl_QueueEvent  adds  an event to the |
              current thread's  queue,  and  Tcl_ThreadQueueEvent |
              adds an event to a queue in a specific thread.      |

       [3]                                                               ||
              The event loop: in  order  to  detect  and  process |
              events,  the  application  enters a loop that waits |
              for events to  occur,  places  them  on  the  event |
              queue,  and then processes them.  Most applications |
              will   do   this   by   calling    the    procedure |
              Tcl_DoOneEvent,  which  is  described in a separate |
              manual entry.                                       |

       Most Tcl applications need not  worry  about  any  of  the |
       internals  of the Tcl notifier.  However, the notifier now |
       has enough flexibility to be retargeted either for  a  new |
       platform  or  to  use  an external event loop (such as the |
       Motif event loop, when Tcl is embedded in a Motif applica­ |
       tion).   The  procedures Tcl_WaitForEvent and Tcl_SetTimer |
       are normally implemented by Tcl, but may be replaced  with |
       new  versions  to retarget the notifier (the Tcl_InitNoti­ |
       fier, Tcl_AlertNotifier, Tcl_FinalizeNotifier,  Tcl_Sleep, |
       Tcl_CreateFileHandler, and Tcl_DeleteFileHandler must also |
       be  replaced;  see  CREATING  A  NEW  NOTIFIER  below  for |
       details).    The   procedures   Tcl_ServiceAll,   Tcl_Ser­ |
       viceEvent, Tcl_GetServiceMode, and Tcl_SetServiceMode  are |
       provided  to  help connect Tcl's event loop to an external |
       event loop such as Motif's.                                |


NOTIFIER BASICS |

       The easiest way to understand how the notifier works is to
       consider  what  happens  when  Tcl_DoOneEvent  is  called.
       Tcl_DoOneEvent is passed a flags argument  that  indicates
       what  sort  of events it is OK to process and also whether
       or not to block if no events  are  ready.   Tcl_DoOneEvent
       does the following things:

       [1]    Check  the  event  queue  to see if it contains any
              events that can be serviced.  If  so,  service  the

              return.  It does this by  calling  Tcl_ServiceEvent |
              and passing in the flags argument.

       [2]    Prepare  to  block  for  an  event.   To  do  this,
              Tcl_DoOneEvent invokes a setup  procedure  in  each
              event source.  The event source will perform event-
              source specific initialization  and  possibly  call |
              Tcl_SetMaxBlockTime  to  limit  how  long Tcl_Wait­
              ForEvent will block if no new events occur.

       [3]    Call Tcl_WaitForEvent.  This  procedure  is  imple­
              mented  differently  on  different  platforms;   it
              waits for an event to occur, based on the  informa­
              tion  provided  by the event sources.  It may cause
              the application to block if  timePtr  specifies  an
              interval  other  than  0.  Tcl_WaitForEvent returns
              when something has happened, such as a file  becom­
              ing  readable  or  the  interval  given  by timePtr
              expiring.  If there are  no  events  for  Tcl_Wait­
              ForEvent  to  wait for, so that it would block for­
              ever,   then    it    returns    immediately    and
              Tcl_DoOneEvent returns 0.

       [4]    Call  a  check procedure in each event source.  The
              check procedure determines whether  any  events  of
              interest  to  this  source  occurred.   If  so, the
              events are added to the event queue.

       [5]    Check the event queue to see  if  it  contains  any
              events  that  can  be serviced.  If so, service the
              first possible event, remove it from the queue, and
              return.

       [6]    See  if  there  are  idle callbacks pending. If so,
              invoke all of them and return.

       [7]    Either return 0 to indicate  that  no  events  were
              ready,  or  go  back  to  step  [2] if blocking was
              requested by the caller.


CREATING A NEW EVENT SOURCE

       An event source consists of three  procedures  invoked  by
       the  notifier,  plus  additional  C  procedures  that  are
       invoked by higher-level code to arrange  for  event-driven
       callbacks.   The  three  procedures called by the notifier
       consist of the setup and check procedures described above,
       plus an additional procedure that is invoked when an event
       is removed from the event queue for servicing.

       The procedure Tcl_CreateEventSource creates  a  new  event
       source.   Its  arguments  specify  the setup procedure and
       check procedure for the event  source.   SetupProc  should

              typedef void Tcl_EventSetupProc(
                ClientData clientData,
                int flags);
       The clientData argument will be the same as the clientData
       argument to Tcl_CreateEventSource;  it is  typically  used
       to  point  to  private  information  managed  by the event
       source.  The flags argument will be the same as the  flags
       argument  passed  to  Tcl_DoOneEvent  except  that it will
       never   be   0    (Tcl_DoOneEvent    replaces    0    with
       TCL_ALL_EVENTS).   Flags  indicates  what  kinds of events
       should be considered; if the  bit  corresponding  to  this
       event  source  isn't  set,  the event source should return
       immediately without doing anything.  For example, the file
       event source checks for the TCL_FILE_EVENTS bit.

       SetupProc's job is to make sure that the application wakes
       up when events of the desired type occur.  This  is  typi­
       cally  done in a platform-dependent fashion.  For example,
       under Unix an event source might  call  Tcl_CreateFileHan­
       dler;  under  Windows it might request notification with a
       Windows event.  For timer-driven  event  sources  such  as
       timer  events  or  any  polled event, the event source can
       call Tcl_SetMaxBlockTime to force the application to  wake
       up after a specified time even if no events have occurred. |
       If  no  event  source   calls   Tcl_SetMaxBlockTime   then |
       Tcl_WaitForEvent  will  wait  as  long as necessary for an |
       event to occur; otherwise, it will only wait  as  long  as |
       the shortest interval passed to Tcl_SetMaxBlockTime by one |
       of the event sources.  If an event source  knows  that  it |
       already  has events ready to report, it can request a zero |
       maximum block time.  For example, the setup procedure  for |
       the  X  event  source  looks  to  see  if there are events |
       already queued.  If there are, it  calls  Tcl_SetMaxBlock­ |
       Time with a 0 block time so that Tcl_WaitForEvent does not |
       block if there is no new data on the  X  connection.   The
       timePtr argument to Tcl_WaitForEvent points to a structure
       that describes a time interval in  seconds  and  microsec­
       onds:
              typedef struct Tcl_Time {
                long sec;
                long usec;
              } Tcl_Time;
       The usec field should be less than 1000000.

       Information  provided  to Tcl_SetMaxBlockTime is only used |
       for the next call to  Tcl_WaitForEvent;  it  is  discarded |
       after  Tcl_WaitForEvent  returns.   The next time an event
       wait is done each of the event sources'  setup  procedures
       will be called again, and they can specify new information
       for that event wait.

       If the application uses an external event loop rather than |
       Tcl_DoOneEvent,   the  event  sources  may  need  to  call |

       event handler is registered that needs to poll for events, |
       the event source may call Tcl_SetMaxBlockTime to  set  the |
       block  time  to  zero  to force the external event loop to |
       call  Tcl.   In  this  case,  Tcl_SetMaxBlockTime  invokes |
       Tcl_SetTimer  with  the  shortest  interval seen since the |
       last call to Tcl_DoOneEvent or Tcl_ServiceAll.             |

       In addition to the generic procedure  Tcl_SetMaxBlockTime, |
       other  platform-specific  procedures may also be available |
       for setupProc, if there is additional  information  needed |
       by  Tcl_WaitForEvent  on  that  platform.  For example, on |
       Unix systems the Tcl_CreateFileHandler  interface  can  be |
       used to wait for file events.

       The  second procedure provided by each event source is its
       check procedure, indicated by the  checkProc  argument  to
       Tcl_CreateEventSource.  CheckProc must match the following
       prototype:
              typedef void Tcl_EventCheckProc(
                ClientData clientData,
                int flags);
       The arguments to this procedure are the same as those  for
       setupProc.   CheckProc  is invoked by Tcl_DoOneEvent after
       it has waited for events.  Presumably at least  one  event
       source  is now prepared to queue an event.  Tcl_DoOneEvent
       calls each of the event sources in turn, so they all  have
       a  chance  to  queue any events that are ready.  The check
       procedure does two things.  First,  it  must  see  if  any
       events have triggered.  Different event sources do this in
       different ways.

       If an event source's check procedure detects an  interest­
       ing event, it must add the event to Tcl's event queue.  To
       do this, the event source calls Tcl_QueueEvent.  The evPtr
       argument is a pointer to a dynamically allocated structure
       containing the event (see below for  more  information  on
       memory  management  issues).  Each event source can define
       its own event structure with whatever information is rele­
       vant  to that event source.  However, the first element of
       the structure must be a structure of type  Tcl_Event,  and
       the  address  of this structure is used when communicating
       between the event source and the rest of the notifier.   A
       Tcl_Event has the following definition:
              typedef struct {
                  Tcl_EventProc *proc;
                  struct Tcl_Event *nextPtr;
              } Tcl_Event;
       The  event source must fill in the proc field of the event
       before calling Tcl_QueueEvent.  The  nextPtr  is  used  to
       link  together  the  events in the queue and should not be
       modified by the event source.

       An event may be  added  to  the  queue  at  any  of  three

       Tcl_QueueEvent:

       TCL_QUEUE_TAIL          Add the event at the back  of  the
                               queue,  so  that all other pending
                               events  will  be  serviced  first.
                               This  is  almost  always the right
                               place for new events.

       TCL_QUEUE_HEAD          Add the event at the front of  the
                               queue, so that it will be serviced
                               before all other queued events.

       TCL_QUEUE_MARK          Add the event at the front of  the
                               queue,   unless  there  are  other
                               events at the front whose position
                               is TCL_QUEUE_MARK;  if so, add the
                               new event  just  after  all  other
                               TCL_QUEUE_MARK events.  This value
                               of position is used to  insert  an
                               ordered  sequence of events at the
                               front of  the  queue,  such  as  a
                               series  of  Enter and Leave events
                               synthesized  during  a   grab   or
                               ungrab operation in Tk.

       When it is time to handle an event from the queue (steps 1 |
       and 4 above) Tcl_ServiceEvent will invoke the proc  speci­ |
       fied  in  the first queued Tcl_Event structure.  Proc must
       match the following prototype:
              typedef int Tcl_EventProc(
                Tcl_Event *evPtr,
                int flags);
       The first argument to proc is  a  pointer  to  the  event,
       which  will  be  the  same  as  the  first argument to the
       Tcl_QueueEvent call that added the  event  to  the  queue.
       The  second argument to proc is the flags argument for the |
       current call to Tcl_ServiceEvent;  this  is  used  by  the |
       event  source  to return immediately if its events are not
       relevant.

       It is up to proc to handle the event, typically by  invok­
       ing  one  or more Tcl commands or C-level callbacks.  Once
       the event  source  has  finished  handling  the  event  it
       returns  1  to indicate that the event can be removed from
       the queue.  If for some reason the  event  source  decides
       that  the  event  cannot  be  handled at this time, it may
       return 0 to indicate that the event should be deferred for |
       processing  later;   in this case Tcl_ServiceEvent will go
       on to the next event in the queue and attempt  to  service
       it.   There  are several reasons why an event source might
       defer an event.  One possibility is that  events  of  this
       type are excluded by the flags argument.  For example, the
       file  event  source  will   always   return   0   if   the

       of deferring events happens in Tk if Tk_RestrictEvents has
       been invoked to defer certain kinds of window events.

       When  proc  returns  1,  Tcl_ServiceEvent  will remove the |
       event from the event queue and  free  its  storage.   Note |
       that  the  storage  for  an event must be allocated by the |
       event source (using Tcl_Alloc or the  Tcl  macro  ckalloc) |
       before  calling  Tcl_QueueEvent,  but  it will be freed by |
       Tcl_ServiceEvent, not by the event source.                 |

       Threaded applications work in  a  similar  manner,  except |
       that  there is a separate event queue for each thread con­ |
       taining a Tcl interpreter.  Calling  Tcl_QueueEvent  in  a |
       multithreaded  application  adds  an  event to the current |
       thread's queue.  To  add  an  event  to  another  thread's |
       queue,   use  Tcl_ThreadQueueEvent.   Tcl_ThreadQueueEvent |
       accepts as an  argument  a  Tcl_ThreadId  argument,  which |
       uniquely  identifies  a  thread  in a Tcl application.  To |
       obtain the Tcl_ThreadID for the current  thread,  use  the |
       Tcl_GetCurrentThread procedure.  (A thread would then need |
       to pass this identifier to other threads for those threads |
       to  be  able to add events to its queue.)  After adding an |
       event to another thread's queue, you then  typically  need |
       to  call  Tcl_ThreadAlert to "wake up" that thread's noti­ |
       fier to alert it to the new event.                         |

       Tcl_DeleteEvents can be used to explicitly remove  one  or |
       more  events from the event queue.  Tcl_DeleteEvents calls |
       proc for each event in the queue, deleting those for  with |
       the  procedure  returns 1.  Events for which the procedure |
       returns 0 are left in the queue.  Proc  should  match  the |
       following prototype:                                       |
              typedef int Tcl_EventDeleteProc(                    |
                Tcl_Event *evPtr,                                 |
                ClientData clientData);                           |
       The clientData argument will be the same as the clientData |
       argument to Tcl_DeleteEvents;  it  is  typically  used  to |
       point  to private information managed by the event source. |
       The evPtr will point to the next event in the queue.       |

       Tcl_DeleteEventSource deletes an event source.  The setup­ |
       Proc,  checkProc,  and  clientData  arguments must exactly |
       match those provided to the Tcl_CreateEventSource for  the |
       event  source  to  be  deleted.  If no such source exists, |
       Tcl_DeleteEventSource has no effect.


CREATING A NEW NOTIFIER

       The notifier consists of all the procedures  described  in
       this  manual  entry,  plus  Tcl_DoOneEvent  and Tcl_Sleep,
       which are available on all platforms, and  Tcl_CreateFile­ |
       Handler  and  Tcl_DeleteFileHandler,  which  are Unix-spe­ |
       cific.  Most of these procedures are generic, in that they |

       procedures   are   notifier-dependent:   Tcl_InitNotifier, |
       Tcl_AlertNotifier,   Tcl_FinalizeNotifier,   Tcl_SetTimer, |
       Tcl_Sleep,  Tcl_WaitForEvent,  Tcl_CreateFileHandler   and |
       Tcl_DeleteFileHandler.   To  support  a new platform or to |
       integrate Tcl with an application-specific event loop, you |
       must write new versions of these procedures.               |

       Tcl_InitNotifier   initializes   the  notifier  state  and |
       returns a handle to the notifier state.   Tcl  calls  this |
       procedure  when intializing a Tcl interpreter.  Similarly, |
       Tcl_FinalizeNotifier  shuts  down  the  notifier,  and  is |
       called  by  Tcl_Finalize  when  shutting down a Tcl inter­ |
       preter.                                                    |

       Tcl_WaitForEvent is  the  lowest-level  procedure  in  the |
       notifier; it is responsible for waiting for an ``interest­ |
       ing'' event to occur  or  for  a  given  time  to  elapse. |
       Before  Tcl_WaitForEvent  is  invoked,  each  of the event |
       sources' setup procedure  will  have  been  invoked.   The |
       timePtr  argument  to  Tcl_WaitForEvent  gives the maximum |
       time to block for an event, based  on  calls  to  Tcl_Set­ |
       MaxBlockTime  made by setup procedures and on other infor­ |
       mation (such as the TCL_DONT_WAIT bit in flags).           |

       Ideally, Tcl_WaitForEvent should only wait for an event to |
       occur;  it  should  not  actually process the event in any |
       way.  Later on, the event sources  will  process  the  raw |
       events  and  create Tcl_Events on the event queue in their |
       checkProc procedures.  However, on some platforms (such as |
       Windows)  this  isn't possible; events may be processed in |
       Tcl_WaitForEvent, including queuing  Tcl_Events  and  more |
       (for   example,   callbacks  for  native  widgets  may  be |
       invoked).  The return value from Tcl_WaitForEvent must  be |
       either  0,  1,  or -1.  On platforms such as Windows where |
       events get processed in Tcl_WaitForEvent, a  return  value |
       of  1  means  that  there may be more events still pending |
       that haven't been processed.  This is a sign to the caller |
       that  it  must call Tcl_WaitForEvent again if it wants all |
       pending events to be processed. A  0  return  value  means |
       that  calling  Tcl_WaitForEvent  again  will  not have any |
       effect: either this is a platform  where  Tcl_WaitForEvent |
       only   waits   without  doing  any  event  processing,  or |
       Tcl_WaitForEvent knows for sure that there  are  no  addi­ |
       tional  events  to  process  (e.g. it returned because the |
       time elapsed).  Finally, a return value of -1  means  that |
       the  event  loop is no longer operational and the applica­ |
       tion should probably unwind and terminate.  Under  Windows |
       this  happens  when  a  WM_QUIT message is received; under |
       Unix it happens when Tcl_WaitForEvent  would  have  waited |
       forever because there were no active event sources and the |
       timeout was infinite.                                      |

       Tcl_AlertNotifier is used in multithreaded applications to |

       new events on its queue.  Tcl_AlertNotifier requires as an |
       argument the notifier handle returned by Tcl_InitNotifier. |

       If the notifier will be used with an external event  loop, |
       then  it  must  also  support  the Tcl_SetTimer interface. |
       Tcl_SetTimer is invoked  by  Tcl_SetMaxBlockTime  whenever |
       the  maximum blocking time has been reduced.  Tcl_SetTimer |
       should arrange for  the  external  event  loop  to  invoke |
       Tcl_ServiceAll  after  the  specified  interval even if no |
       events have occurred.  This interface  is  needed  because |
       Tcl_WaitForEvent  isn't  invoked when there is an external |
       event loop.  If  the  notifier  will  only  be  used  from |
       Tcl_DoOneEvent, then Tcl_SetTimer need not do anything.    |

       On  Unix systems, the file event source also needs support |
       from the notifier.  The file event source consists of  the |
       Tcl_CreateFileHandler   and  Tcl_DeleteFileHandler  proce­ |
       dures, which are described  in  the  Tcl_CreateFileHandler |
       manual page.                                               |

       The  Tcl_Sleep and Tcl_DoOneEvent interfaces are described |
       in their respective manual pages.                          |

       The easiest way to create a new notifier is to look at the |
       code   for   an  existing  notifier,  such  as  the  files |
       unix/tclUnixNotfy.c  or  win/tclWinNotify.c  in  the   Tcl |
       source distribution.                                       |


EXTERNAL EVENT LOOPS |

       The  notifier  interfaces  are designed so that Tcl can be |
       embedded into applications that  have  their  own  private |
       event  loops.  In this case, the application does not call |
       Tcl_DoOneEvent except in the case of recursive event loops |
       such  as  calls to the Tcl commands update or vwait.  Most |
       of the time is spent in the external  event  loop  of  the |
       application.   In  this case the notifier must arrange for |
       the external event loop to call back into Tcl  when  some­ |
       thing  happens  on  the  various Tcl event sources.  These |
       callbacks should arrange for appropriate Tcl events to  be |
       placed on the Tcl event queue.                             |

       Because   the   external   event   loop   is  not  calling |
       Tcl_DoOneEvent on a regular basis, it is up to  the  noti­ |
       fier to arrange for Tcl_ServiceEvent to be called whenever |
       events are pending on the Tcl event  queue.   The  easiest |
       way  to  do this is to invoke Tcl_ServiceAll at the end of |
       each callback from the external  event  loop.   This  will |
       ensure  that  all  of  the  event  sources are polled, any |
       queued events are serviced, and any pending idle  handlers |
       are processed before returning control to the application. |
       In addition, event sources that need to  poll  for  events |
       can  call  Tcl_SetMaxBlockTime to force the external event |

       system event queue.                                        |

       As a side effect of processing events detected in the main |
       external event loop,  Tcl  may  invoke  Tcl_DoOneEvent  to |
       start  a  recursive  event  loop  in  commands like vwait. |
       Tcl_DoOneEvent will invoke the external event loop,  which |
       will  result  in  callbacks  as described in the preceding |
       paragraph, which will result in calls  to  Tcl_ServiceAll. |
       However,  in  these  cases  it  is  undesirable to service |
       events  in  Tcl_ServiceAll.   Servicing  events  there  is |
       unnecessary because control will immediately return to the |
       external event loop and hence to Tcl_DoOneEvent, which can |
       service the events itself.  Furthermore, Tcl_DoOneEvent is |
       supposed to service only a single event, whereas  Tcl_Ser­ |
       viceAll  normally  services all pending events.  To handle |
       this situation, Tcl_DoOneEvent sets a  flag  for  Tcl_Ser­ |
       viceAll  that  causes  it  to return without servicing any |
       events.   This  flag   is   called   the   service   mode; |
       Tcl_DoOneEvent restores it to its previous value before it |
       returns.                                                   |

       In some cases, however, it may be necessary  for  Tcl_Ser­ |
       viceAll  to  service  events even when it has been invoked |
       from Tcl_DoOneEvent.   This  happens  when  there  is  yet |
       another  recursive event loop invoked via an event handler |
       called by Tcl_DoOneEvent (such as one that is  part  of  a |
       native widget).  In this case, Tcl_DoOneEvent may not have |
       a chance to service events so Tcl_ServiceAll must  service |
       them all.  Any recursive event loop that calls an external |
       event loop rather than Tcl_DoOneEvent must reset the  ser­ |
       vice  mode  so  that  all events get processed in Tcl_Ser­ |
       viceAll.  This is done by invoking the  Tcl_SetServiceMode |
       procedure.    If  Tcl_SetServiceMode  is  passed  TCL_SER­ |
       VICE_NONE, then calls to Tcl_ServiceAll will return  imme­ |
       diately without processing any events.  If Tcl_SetService­ |
       Mode is passed TCL_SERVICE_ALL,  then  calls  to  Tcl_Ser­ |
       viceAll  will behave normally.  Tcl_SetServiceMode returns |
       the previous value of the service mode,  which  should  be |
       restored  when  the recursive loop exits.  Tcl_GetService­ |
       Mode returns the current value of the service mode.


SEE ALSO

       Tcl_CreateFileHandler,  Tcl_DeleteFileHandler,  Tcl_Sleep,
       Tcl_DoOneEvent, Thread(3)


KEYWORDS

       event,  notifier, event queue, event sources, file events,
       timer, idle, service mode, threads


Man(1) output converted with man2html