| 1 | '\" | 
|---|
| 2 | '\" Copyright (c) 1998-1999 Scriptics Corporation | 
|---|
| 3 | '\" Copyright (c) 1995-1997 Sun Microsystems, Inc. | 
|---|
| 4 | '\" | 
|---|
| 5 | '\" See the file "license.terms" for information on usage and redistribution | 
|---|
| 6 | '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. | 
|---|
| 7 | '\"  | 
|---|
| 8 | '\" RCS: @(#) $Id: Notifier.3,v 1.21 2007/12/13 15:22:31 dgp Exp $ | 
|---|
| 9 | '\"  | 
|---|
| 10 | .so man.macros | 
|---|
| 11 | .TH Notifier 3 8.1 Tcl "Tcl Library Procedures" | 
|---|
| 12 | .BS | 
|---|
| 13 | .SH NAME | 
|---|
| 14 | Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrentThread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode \- the event queue and notifier interfaces | 
|---|
| 15 | .SH SYNOPSIS | 
|---|
| 16 | .nf | 
|---|
| 17 | \fB#include <tcl.h>\fR | 
|---|
| 18 | .sp | 
|---|
| 19 | void | 
|---|
| 20 | \fBTcl_CreateEventSource\fR(\fIsetupProc, checkProc, clientData\fR) | 
|---|
| 21 | .sp | 
|---|
| 22 | void | 
|---|
| 23 | \fBTcl_DeleteEventSource\fR(\fIsetupProc, checkProc, clientData\fR) | 
|---|
| 24 | .sp | 
|---|
| 25 | void | 
|---|
| 26 | \fBTcl_SetMaxBlockTime\fR(\fItimePtr\fR) | 
|---|
| 27 | .sp | 
|---|
| 28 | void | 
|---|
| 29 | \fBTcl_QueueEvent\fR(\fIevPtr, position\fR) | 
|---|
| 30 | .sp | 
|---|
| 31 | void | 
|---|
| 32 | \fBTcl_ThreadQueueEvent\fR(\fIthreadId, evPtr, position\fR) | 
|---|
| 33 | .sp | 
|---|
| 34 | void | 
|---|
| 35 | \fBTcl_ThreadAlert\fR(\fIthreadId\fR) | 
|---|
| 36 | .sp | 
|---|
| 37 | Tcl_ThreadId | 
|---|
| 38 | \fBTcl_GetCurrentThread\fR() | 
|---|
| 39 | .sp | 
|---|
| 40 | void | 
|---|
| 41 | \fBTcl_DeleteEvents\fR(\fIdeleteProc, clientData\fR) | 
|---|
| 42 | .sp | 
|---|
| 43 | ClientData | 
|---|
| 44 | \fBTcl_InitNotifier\fR() | 
|---|
| 45 | .sp | 
|---|
| 46 | void | 
|---|
| 47 | \fBTcl_FinalizeNotifier\fR(\fIclientData\fR) | 
|---|
| 48 | .sp | 
|---|
| 49 | int | 
|---|
| 50 | \fBTcl_WaitForEvent\fR(\fItimePtr\fR) | 
|---|
| 51 | .sp | 
|---|
| 52 | void | 
|---|
| 53 | \fBTcl_AlertNotifier\fR(\fIclientData\fR) | 
|---|
| 54 | .sp | 
|---|
| 55 | void | 
|---|
| 56 | \fBTcl_SetTimer\fR(\fItimePtr\fR) | 
|---|
| 57 | .sp | 
|---|
| 58 | int | 
|---|
| 59 | \fBTcl_ServiceAll\fR() | 
|---|
| 60 | .sp | 
|---|
| 61 | int | 
|---|
| 62 | \fBTcl_ServiceEvent\fR(\fIflags\fR) | 
|---|
| 63 | .sp | 
|---|
| 64 | int | 
|---|
| 65 | \fBTcl_GetServiceMode\fR() | 
|---|
| 66 | .sp | 
|---|
| 67 | int | 
|---|
| 68 | \fBTcl_SetServiceMode\fR(\fImode\fR) | 
|---|
| 69 | .sp | 
|---|
| 70 | void | 
|---|
| 71 | \fBTcl_ServiceModeHook\fR(\fImode\fR) | 
|---|
| 72 | .sp | 
|---|
| 73 | void | 
|---|
| 74 | \fBTcl_SetNotifier\fR(\fInotifierProcPtr\fR) | 
|---|
| 75 | .SH ARGUMENTS | 
|---|
| 76 | .AS Tcl_EventDeleteProc *notifierProcPtr | 
|---|
| 77 | .AP Tcl_EventSetupProc *setupProc in | 
|---|
| 78 | Procedure to invoke to prepare for event wait in \fBTcl_DoOneEvent\fR. | 
|---|
| 79 | .AP Tcl_EventCheckProc *checkProc in | 
|---|
| 80 | Procedure for \fBTcl_DoOneEvent\fR to invoke after waiting for | 
|---|
| 81 | events.  Checks to see if any events have occurred and, if so, | 
|---|
| 82 | queues them. | 
|---|
| 83 | .AP ClientData clientData in | 
|---|
| 84 | Arbitrary one-word value to pass to \fIsetupProc\fR, \fIcheckProc\fR, or | 
|---|
| 85 | \fIdeleteProc\fR. | 
|---|
| 86 | .AP Tcl_Time *timePtr in | 
|---|
| 87 | Indicates the maximum amount of time to wait for an event.  This | 
|---|
| 88 | is specified as an interval (how long to wait), not an absolute | 
|---|
| 89 | time (when to wakeup).  If the pointer passed to \fBTcl_WaitForEvent\fR | 
|---|
| 90 | is NULL, it means there is no maximum wait time:  wait forever if | 
|---|
| 91 | necessary. | 
|---|
| 92 | .AP Tcl_Event *evPtr in | 
|---|
| 93 | An event to add to the event queue.  The storage for the event must | 
|---|
| 94 | have been allocated by the caller using \fBTcl_Alloc\fR or \fBckalloc\fR. | 
|---|
| 95 | .AP Tcl_QueuePosition position in | 
|---|
| 96 | Where to add the new event in the queue:  \fBTCL_QUEUE_TAIL\fR, | 
|---|
| 97 | \fBTCL_QUEUE_HEAD\fR, or \fBTCL_QUEUE_MARK\fR. | 
|---|
| 98 | .AP Tcl_ThreadId threadId in | 
|---|
| 99 | A unique identifier for a thread. | 
|---|
| 100 | .AP Tcl_EventDeleteProc *deleteProc in | 
|---|
| 101 | Procedure to invoke for each queued event in \fBTcl_DeleteEvents\fR. | 
|---|
| 102 | .AP int flags in | 
|---|
| 103 | What types of events to service.  These flags are the same as those | 
|---|
| 104 | passed to \fBTcl_DoOneEvent\fR. | 
|---|
| 105 | .AP int mode in | 
|---|
| 106 | Indicates whether events should be serviced by \fBTcl_ServiceAll\fR. | 
|---|
| 107 | Must be one of \fBTCL_SERVICE_NONE\fR or \fBTCL_SERVICE_ALL\fR. | 
|---|
| 108 | .AP Tcl_NotifierProcs* notifierProcPtr in | 
|---|
| 109 | Structure of function pointers describing notifier procedures that are | 
|---|
| 110 | to replace the ones installed in the executable.  See | 
|---|
| 111 | \fBREPLACING THE NOTIFIER\fR for details. | 
|---|
| 112 | .BE | 
|---|
| 113 |  | 
|---|
| 114 | .SH INTRODUCTION | 
|---|
| 115 | .PP | 
|---|
| 116 | The interfaces described here are used to customize the Tcl event | 
|---|
| 117 | loop.  The two most common customizations are to add new sources of | 
|---|
| 118 | events and to merge Tcl's event loop with some other event loop, such | 
|---|
| 119 | as one provided by an application in which Tcl is embedded.  Each of | 
|---|
| 120 | these tasks is described in a separate section below. | 
|---|
| 121 | .PP | 
|---|
| 122 | The procedures in this manual entry are the building blocks out of which | 
|---|
| 123 | the Tcl event notifier is constructed.  The event notifier is the lowest | 
|---|
| 124 | layer in the Tcl event mechanism.  It consists of three things: | 
|---|
| 125 | .IP [1] | 
|---|
| 126 | Event sources: these represent the ways in which events can be | 
|---|
| 127 | generated.  For example, there is a timer event source that implements | 
|---|
| 128 | the \fBTcl_CreateTimerHandler\fR procedure and the \fBafter\fR | 
|---|
| 129 | command, and there is a file event source that implements the | 
|---|
| 130 | \fBTcl_CreateFileHandler\fR procedure on Unix systems.  An event | 
|---|
| 131 | source must work with the notifier to detect events at the right | 
|---|
| 132 | times, record them on the event queue, and eventually notify | 
|---|
| 133 | higher-level software that they have occurred.  The procedures | 
|---|
| 134 | \fBTcl_CreateEventSource\fR, \fBTcl_DeleteEventSource\fR, | 
|---|
| 135 | and \fBTcl_SetMaxBlockTime\fR, \fBTcl_QueueEvent\fR, and | 
|---|
| 136 | \fBTcl_DeleteEvents\fR are used primarily by event sources. | 
|---|
| 137 | .IP [2] | 
|---|
| 138 | The event queue: for non-threaded applications, | 
|---|
| 139 | there is a single queue for the whole application, | 
|---|
| 140 | containing events that have been detected but not yet serviced.  Event | 
|---|
| 141 | sources place events onto the queue so that they may be processed in | 
|---|
| 142 | order at appropriate times during the event loop. The event queue | 
|---|
| 143 | guarantees a fair discipline of event handling, so that no event | 
|---|
| 144 | source can starve the others.  It also allows events to be saved for | 
|---|
| 145 | servicing at a future time.  Threaded applications work in a | 
|---|
| 146 | similar manner, except that there is a separate event queue for | 
|---|
| 147 | each thread containing a Tcl interpreter. | 
|---|
| 148 | \fBTcl_QueueEvent\fR is used (primarily | 
|---|
| 149 | by event sources) to add events to the event queue and  | 
|---|
| 150 | \fBTcl_DeleteEvents\fR is used to remove events from the queue without | 
|---|
| 151 | processing them.  In a threaded application, \fBTcl_QueueEvent\fR adds | 
|---|
| 152 | an event to the current thread's queue, and \fBTcl_ThreadQueueEvent\fR | 
|---|
| 153 | adds an event to a queue in a specific thread. | 
|---|
| 154 | .IP [3] | 
|---|
| 155 | The event loop: in order to detect and process events, the application | 
|---|
| 156 | enters a loop that waits for events to occur, places them on the event | 
|---|
| 157 | queue, and then processes them.  Most applications will do this by | 
|---|
| 158 | calling the procedure \fBTcl_DoOneEvent\fR, which is described in a | 
|---|
| 159 | separate manual entry. | 
|---|
| 160 | .PP | 
|---|
| 161 | Most Tcl applications need not worry about any of the internals of | 
|---|
| 162 | the Tcl notifier.  However, the notifier now has enough flexibility | 
|---|
| 163 | to be retargeted either for a new platform or to use an external event | 
|---|
| 164 | loop (such as the Motif event loop, when Tcl is embedded in a Motif | 
|---|
| 165 | application).  The procedures \fBTcl_WaitForEvent\fR and | 
|---|
| 166 | \fBTcl_SetTimer\fR are normally implemented by Tcl, but may be | 
|---|
| 167 | replaced with new versions to retarget the notifier (the | 
|---|
| 168 | \fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR, | 
|---|
| 169 | \fBTcl_FinalizeNotifier\fR, \fBTcl_Sleep\fR, | 
|---|
| 170 | \fBTcl_CreateFileHandler\fR, and \fBTcl_DeleteFileHandler\fR must | 
|---|
| 171 | also be replaced; see CREATING A NEW NOTIFIER below for details). | 
|---|
| 172 | The procedures \fBTcl_ServiceAll\fR, \fBTcl_ServiceEvent\fR, | 
|---|
| 173 | \fBTcl_GetServiceMode\fR, and \fBTcl_SetServiceMode\fR are provided | 
|---|
| 174 | to help connect Tcl's event loop to an external event loop such as | 
|---|
| 175 | Motif's. | 
|---|
| 176 | .SH "NOTIFIER BASICS" | 
|---|
| 177 | .PP | 
|---|
| 178 | The easiest way to understand how the notifier works is to consider | 
|---|
| 179 | what happens when \fBTcl_DoOneEvent\fR is called. | 
|---|
| 180 | \fBTcl_DoOneEvent\fR is passed a \fIflags\fR argument that indicates | 
|---|
| 181 | what sort of events it is OK to process and also whether or not to | 
|---|
| 182 | block if no events are ready.  \fBTcl_DoOneEvent\fR does the following | 
|---|
| 183 | things: | 
|---|
| 184 | .IP [1] | 
|---|
| 185 | Check the event queue to see if it contains any events that can | 
|---|
| 186 | be serviced.  If so, service the first possible event, remove it | 
|---|
| 187 | from the queue, and return.  It does this by calling | 
|---|
| 188 | \fBTcl_ServiceEvent\fR and passing in the \fIflags\fR argument. | 
|---|
| 189 | .IP [2] | 
|---|
| 190 | Prepare to block for an event.  To do this, \fBTcl_DoOneEvent\fR | 
|---|
| 191 | invokes a \fIsetup procedure\fR in each event source. | 
|---|
| 192 | The event source will perform event-source specific initialization and | 
|---|
| 193 | possibly call \fBTcl_SetMaxBlockTime\fR to limit how long | 
|---|
| 194 | \fBTcl_WaitForEvent\fR will block if no new events occur. | 
|---|
| 195 | .IP [3] | 
|---|
| 196 | Call \fBTcl_WaitForEvent\fR.  This procedure is implemented differently | 
|---|
| 197 | on different platforms;  it waits for an event to occur, based on the | 
|---|
| 198 | information provided by the event sources. | 
|---|
| 199 | It may cause the application to block if \fItimePtr\fR specifies | 
|---|
| 200 | an interval other than 0. | 
|---|
| 201 | \fBTcl_WaitForEvent\fR returns when something has happened, | 
|---|
| 202 | such as a file becoming readable or the interval given by \fItimePtr\fR | 
|---|
| 203 | expiring.  If there are no events for \fBTcl_WaitForEvent\fR to | 
|---|
| 204 | wait for, so that it would block forever, then it returns immediately | 
|---|
| 205 | and \fBTcl_DoOneEvent\fR returns 0. | 
|---|
| 206 | .IP [4] | 
|---|
| 207 | Call a \fIcheck procedure\fR in each event source.  The check | 
|---|
| 208 | procedure determines whether any events of interest to this source | 
|---|
| 209 | occurred.  If so, the events are added to the event queue. | 
|---|
| 210 | .IP [5] | 
|---|
| 211 | Check the event queue to see if it contains any events that can | 
|---|
| 212 | be serviced.  If so, service the first possible event, remove it | 
|---|
| 213 | from the queue, and return. | 
|---|
| 214 | .IP [6] | 
|---|
| 215 | See if there are idle callbacks pending. If so, invoke all of them and | 
|---|
| 216 | return. | 
|---|
| 217 | .IP [7] | 
|---|
| 218 | Either return 0 to indicate that no events were ready, or go back to | 
|---|
| 219 | step [2] if blocking was requested by the caller. | 
|---|
| 220 |  | 
|---|
| 221 | .SH "CREATING A NEW EVENT SOURCE" | 
|---|
| 222 | .PP | 
|---|
| 223 | An event source consists of three procedures invoked by the notifier, | 
|---|
| 224 | plus additional C procedures that are invoked by higher-level code | 
|---|
| 225 | to arrange for event-driven callbacks.  The three procedures called | 
|---|
| 226 | by the notifier consist of the setup and check procedures described | 
|---|
| 227 | above, plus an additional procedure that is invoked when an event | 
|---|
| 228 | is removed from the event queue for servicing. | 
|---|
| 229 | .PP | 
|---|
| 230 | The procedure \fBTcl_CreateEventSource\fR creates a new event source. | 
|---|
| 231 | Its arguments specify the setup procedure and check procedure for | 
|---|
| 232 | the event source. | 
|---|
| 233 | \fISetupProc\fR should match the following prototype: | 
|---|
| 234 | .CS | 
|---|
| 235 | typedef void Tcl_EventSetupProc( | 
|---|
| 236 |         ClientData \fIclientData\fR, | 
|---|
| 237 |         int \fIflags\fR); | 
|---|
| 238 | .CE | 
|---|
| 239 | The \fIclientData\fR argument will be the same as the \fIclientData\fR | 
|---|
| 240 | argument to \fBTcl_CreateEventSource\fR;  it is typically used to | 
|---|
| 241 | point to private information managed by the event source. | 
|---|
| 242 | The \fIflags\fR argument will be the same as the \fIflags\fR | 
|---|
| 243 | argument passed to \fBTcl_DoOneEvent\fR except that it will never | 
|---|
| 244 | be 0 (\fBTcl_DoOneEvent\fR replaces 0 with \fBTCL_ALL_EVENTS\fR). | 
|---|
| 245 | \fIFlags\fR indicates what kinds of events should be considered; | 
|---|
| 246 | if the bit corresponding to this event source is not set, the event | 
|---|
| 247 | source should return immediately without doing anything.  For | 
|---|
| 248 | example, the file event source checks for the \fBTCL_FILE_EVENTS\fR | 
|---|
| 249 | bit. | 
|---|
| 250 | .PP | 
|---|
| 251 | \fISetupProc\fR's job is to make sure that the application wakes up | 
|---|
| 252 | when events of the desired type occur.  This is typically done in a | 
|---|
| 253 | platform-dependent fashion.  For example, under Unix an event source | 
|---|
| 254 | might call \fBTcl_CreateFileHandler\fR; under Windows it might | 
|---|
| 255 | request notification with a Windows event.  For timer-driven event | 
|---|
| 256 | sources such as timer events or any polled event, the event source | 
|---|
| 257 | can call \fBTcl_SetMaxBlockTime\fR to force the application to wake | 
|---|
| 258 | up after a specified time even if no events have occurred. | 
|---|
| 259 | If no event source calls \fBTcl_SetMaxBlockTime\fR | 
|---|
| 260 | then \fBTcl_WaitForEvent\fR will wait as long as necessary for an | 
|---|
| 261 | event to occur; otherwise, it will only wait as long as the shortest | 
|---|
| 262 | interval passed to \fBTcl_SetMaxBlockTime\fR by one of the event | 
|---|
| 263 | sources.  If an event source knows that it already has events ready to | 
|---|
| 264 | report, it can request a zero maximum block time.  For example, the | 
|---|
| 265 | setup procedure for the X event source looks to see if there are | 
|---|
| 266 | events already queued.  If there are, it calls | 
|---|
| 267 | \fBTcl_SetMaxBlockTime\fR with a 0 block time so that | 
|---|
| 268 | \fBTcl_WaitForEvent\fR does not block if there is no new data on the X | 
|---|
| 269 | connection. | 
|---|
| 270 | The \fItimePtr\fR argument to \fBTcl_WaitForEvent\fR points to | 
|---|
| 271 | a structure that describes a time interval in seconds and | 
|---|
| 272 | microseconds: | 
|---|
| 273 | .CS | 
|---|
| 274 | typedef struct Tcl_Time { | 
|---|
| 275 |         long \fIsec\fR; | 
|---|
| 276 |         long \fIusec\fR; | 
|---|
| 277 | } Tcl_Time; | 
|---|
| 278 | .CE | 
|---|
| 279 | The \fIusec\fR field should be less than 1000000. | 
|---|
| 280 | .PP | 
|---|
| 281 | Information provided to \fBTcl_SetMaxBlockTime\fR | 
|---|
| 282 | is only used for the next call to \fBTcl_WaitForEvent\fR; it is | 
|---|
| 283 | discarded after \fBTcl_WaitForEvent\fR returns. | 
|---|
| 284 | The next time an event wait is done each of the event sources' | 
|---|
| 285 | setup procedures will be called again, and they can specify new | 
|---|
| 286 | information for that event wait. | 
|---|
| 287 | .PP | 
|---|
| 288 | If the application uses an external event loop rather than | 
|---|
| 289 | \fBTcl_DoOneEvent\fR, the event sources may need to call | 
|---|
| 290 | \fBTcl_SetMaxBlockTime\fR at other times.  For example, if a new event | 
|---|
| 291 | handler is registered that needs to poll for events, the event source | 
|---|
| 292 | may call \fBTcl_SetMaxBlockTime\fR to set the block time to zero to | 
|---|
| 293 | force the external event loop to call Tcl.  In this case, | 
|---|
| 294 | \fBTcl_SetMaxBlockTime\fR invokes \fBTcl_SetTimer\fR with the shortest | 
|---|
| 295 | interval seen since the last call to \fBTcl_DoOneEvent\fR or | 
|---|
| 296 | \fBTcl_ServiceAll\fR. | 
|---|
| 297 | .PP | 
|---|
| 298 | In addition to the generic procedure \fBTcl_SetMaxBlockTime\fR, other | 
|---|
| 299 | platform-specific procedures may also be available for | 
|---|
| 300 | \fIsetupProc\fR, if there is additional information needed by | 
|---|
| 301 | \fBTcl_WaitForEvent\fR on that platform.  For example, on Unix systems | 
|---|
| 302 | the \fBTcl_CreateFileHandler\fR interface can be used to wait for file events. | 
|---|
| 303 | .PP | 
|---|
| 304 | The second procedure provided by each event source is its check | 
|---|
| 305 | procedure, indicated by the \fIcheckProc\fR argument to | 
|---|
| 306 | \fBTcl_CreateEventSource\fR.  \fICheckProc\fR must match the | 
|---|
| 307 | following prototype: | 
|---|
| 308 | .CS | 
|---|
| 309 | typedef void Tcl_EventCheckProc( | 
|---|
| 310 |         ClientData \fIclientData\fR, | 
|---|
| 311 |         int \fIflags\fR); | 
|---|
| 312 | .CE | 
|---|
| 313 | The arguments to this procedure are the same as those for \fIsetupProc\fR. | 
|---|
| 314 | \fBCheckProc\fR is invoked by \fBTcl_DoOneEvent\fR after it has waited | 
|---|
| 315 | for events.  Presumably at least one event source is now prepared to | 
|---|
| 316 | queue an event.  \fBTcl_DoOneEvent\fR calls each of the event sources | 
|---|
| 317 | in turn, so they all have a chance to queue any events that are ready. | 
|---|
| 318 | The check procedure does two things.  First, it must see if any events | 
|---|
| 319 | have triggered.  Different event sources do this in different ways. | 
|---|
| 320 | .PP | 
|---|
| 321 | If an event source's check procedure detects an interesting event, it | 
|---|
| 322 | must add the event to Tcl's event queue.  To do this, the event source | 
|---|
| 323 | calls \fBTcl_QueueEvent\fR.  The \fIevPtr\fR argument is a pointer to | 
|---|
| 324 | a dynamically allocated structure containing the event (see below for | 
|---|
| 325 | more information on memory management issues).  Each event source can | 
|---|
| 326 | define its own event structure with whatever information is relevant | 
|---|
| 327 | to that event source.  However, the first element of the structure | 
|---|
| 328 | must be a structure of type \fBTcl_Event\fR, and the address of this | 
|---|
| 329 | structure is used when communicating between the event source and the | 
|---|
| 330 | rest of the notifier.  A \fBTcl_Event\fR has the following definition: | 
|---|
| 331 | .CS | 
|---|
| 332 | typedef struct { | 
|---|
| 333 |     Tcl_EventProc *\fIproc\fR; | 
|---|
| 334 |     struct Tcl_Event *\fInextPtr\fR; | 
|---|
| 335 | } Tcl_Event; | 
|---|
| 336 | .CE | 
|---|
| 337 | The event source must fill in the \fIproc\fR field of | 
|---|
| 338 | the event before calling \fBTcl_QueueEvent\fR. | 
|---|
| 339 | The \fInextPtr\fR is used to link together the events in the queue | 
|---|
| 340 | and should not be modified by the event source. | 
|---|
| 341 | .PP | 
|---|
| 342 | An event may be added to the queue at any of three positions, depending | 
|---|
| 343 | on the \fIposition\fR argument to \fBTcl_QueueEvent\fR: | 
|---|
| 344 | .IP \fBTCL_QUEUE_TAIL\fR 24 | 
|---|
| 345 | Add the event at the back of the queue, so that all other pending | 
|---|
| 346 | events will be serviced first.  This is almost always the right | 
|---|
| 347 | place for new events. | 
|---|
| 348 | .IP \fBTCL_QUEUE_HEAD\fR 24 | 
|---|
| 349 | Add the event at the front of the queue, so that it will be serviced | 
|---|
| 350 | before all other queued events. | 
|---|
| 351 | .IP \fBTCL_QUEUE_MARK\fR 24 | 
|---|
| 352 | Add the event at the front of the queue, unless there are other | 
|---|
| 353 | events at the front whose position is \fBTCL_QUEUE_MARK\fR;  if so, | 
|---|
| 354 | add the new event just after all other \fBTCL_QUEUE_MARK\fR events. | 
|---|
| 355 | This value of \fIposition\fR is used to insert an ordered sequence of | 
|---|
| 356 | events at the front of the queue, such as a series of | 
|---|
| 357 | Enter and Leave events synthesized during a grab or ungrab operation | 
|---|
| 358 | in Tk. | 
|---|
| 359 | .PP | 
|---|
| 360 | When it is time to handle an event from the queue (steps 1 and 4 | 
|---|
| 361 | above) \fBTcl_ServiceEvent\fR will invoke the \fIproc\fR specified | 
|---|
| 362 | in the first queued \fBTcl_Event\fR structure. | 
|---|
| 363 | \fIProc\fR must match the following prototype: | 
|---|
| 364 | .CS | 
|---|
| 365 | typedef int Tcl_EventProc( | 
|---|
| 366 |         Tcl_Event *\fIevPtr\fR, | 
|---|
| 367 |         int \fIflags\fR); | 
|---|
| 368 | .CE | 
|---|
| 369 | The first argument to \fIproc\fR is a pointer to the event, which will | 
|---|
| 370 | be the same as the first argument to the \fBTcl_QueueEvent\fR call that | 
|---|
| 371 | added the event to the queue. | 
|---|
| 372 | The second argument to \fIproc\fR is the \fIflags\fR argument for the | 
|---|
| 373 | current call to \fBTcl_ServiceEvent\fR;  this is used by the event source | 
|---|
| 374 | to return immediately if its events are not relevant. | 
|---|
| 375 | .PP | 
|---|
| 376 | It is up to \fIproc\fR to handle the event, typically by invoking | 
|---|
| 377 | one or more Tcl commands or C-level callbacks. | 
|---|
| 378 | Once the event source has finished handling the event it returns 1 | 
|---|
| 379 | to indicate that the event can be removed from the queue. | 
|---|
| 380 | If for some reason the event source decides that the event cannot | 
|---|
| 381 | be handled at this time, it may return 0 to indicate that the event | 
|---|
| 382 | should be deferred for processing later;  in this case \fBTcl_ServiceEvent\fR | 
|---|
| 383 | will go on to the next event in the queue and attempt to service it. | 
|---|
| 384 | There are several reasons why an event source might defer an event. | 
|---|
| 385 | One possibility is that events of this type are excluded by the | 
|---|
| 386 | \fIflags\fR argument. | 
|---|
| 387 | For example, the file event source will always return 0 if the | 
|---|
| 388 | \fBTCL_FILE_EVENTS\fR bit is not set in \fIflags\fR. | 
|---|
| 389 | Another example of deferring events happens in Tk if | 
|---|
| 390 | \fBTk_RestrictEvents\fR has been invoked to defer certain kinds | 
|---|
| 391 | of window events. | 
|---|
| 392 | .PP | 
|---|
| 393 | When \fIproc\fR returns 1, \fBTcl_ServiceEvent\fR will remove the | 
|---|
| 394 | event from the event queue and free its storage. | 
|---|
| 395 | Note that the storage for an event must be allocated by | 
|---|
| 396 | the event source (using \fBTcl_Alloc\fR or the Tcl macro \fBckalloc\fR) | 
|---|
| 397 | before calling \fBTcl_QueueEvent\fR, but it | 
|---|
| 398 | will be freed by \fBTcl_ServiceEvent\fR, not by the event source. | 
|---|
| 399 | .PP | 
|---|
| 400 | Threaded applications work in a | 
|---|
| 401 | similar manner, except that there is a separate event queue for | 
|---|
| 402 | each thread containing a Tcl interpreter. | 
|---|
| 403 | Calling \fBTcl_QueueEvent\fR in a multithreaded application adds | 
|---|
| 404 | an event to the current thread's queue. | 
|---|
| 405 | To add an event to another thread's queue, use \fBTcl_ThreadQueueEvent\fR. | 
|---|
| 406 | \fBTcl_ThreadQueueEvent\fR accepts as an argument a Tcl_ThreadId argument, | 
|---|
| 407 | which uniquely identifies a thread in a Tcl application.  To obtain the | 
|---|
| 408 | Tcl_ThreadID for the current thread, use the \fBTcl_GetCurrentThread\fR | 
|---|
| 409 | procedure.  (A thread would then need to pass this identifier to other | 
|---|
| 410 | threads for those threads to be able to add events to its queue.) | 
|---|
| 411 | After adding an event to another thread's queue, you then typically | 
|---|
| 412 | need to call \fBTcl_ThreadAlert\fR to | 
|---|
| 413 | .QW "wake up" | 
|---|
| 414 | that thread's notifier to alert it to the new event. | 
|---|
| 415 | .PP | 
|---|
| 416 | \fBTcl_DeleteEvents\fR can be used to explicitly remove one or more | 
|---|
| 417 | events from the event queue.  \fBTcl_DeleteEvents\fR calls \fIproc\fR | 
|---|
| 418 | for each event in the queue, deleting those for with the procedure | 
|---|
| 419 | returns 1.  Events for which the procedure returns 0 are left in the | 
|---|
| 420 | queue.  \fIProc\fR should match the following prototype: | 
|---|
| 421 | .CS | 
|---|
| 422 | typedef int Tcl_EventDeleteProc( | 
|---|
| 423 |         Tcl_Event *\fIevPtr\fR, | 
|---|
| 424 |         ClientData \fIclientData\fR); | 
|---|
| 425 | .CE | 
|---|
| 426 | The \fIclientData\fR argument will be the same as the \fIclientData\fR | 
|---|
| 427 | argument to \fBTcl_DeleteEvents\fR; it is typically used to point to | 
|---|
| 428 | private information managed by the event source.  The \fIevPtr\fR will | 
|---|
| 429 | point to the next event in the queue. | 
|---|
| 430 | .PP | 
|---|
| 431 | \fBTcl_DeleteEventSource\fR deletes an event source.  The \fIsetupProc\fR, | 
|---|
| 432 | \fIcheckProc\fR, and \fIclientData\fR arguments must exactly match those | 
|---|
| 433 | provided to the \fBTcl_CreateEventSource\fR for the event source to be deleted. | 
|---|
| 434 | If no such source exists, \fBTcl_DeleteEventSource\fR has no effect. | 
|---|
| 435 |  | 
|---|
| 436 | .SH "CREATING A NEW NOTIFIER" | 
|---|
| 437 | .PP | 
|---|
| 438 | The notifier consists of all the procedures described in this manual | 
|---|
| 439 | entry, plus \fBTcl_DoOneEvent\fR and \fBTcl_Sleep\fR, which are | 
|---|
| 440 | available on all platforms, and \fBTcl_CreateFileHandler\fR and | 
|---|
| 441 | \fBTcl_DeleteFileHandler\fR, which are Unix-specific.  Most of these | 
|---|
| 442 | procedures are generic, in that they are the same for all notifiers. | 
|---|
| 443 | However, none of the procedures are notifier-dependent: | 
|---|
| 444 | \fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR, | 
|---|
| 445 | \fBTcl_FinalizeNotifier\fR, \fBTcl_SetTimer\fR, \fBTcl_Sleep\fR, | 
|---|
| 446 | \fBTcl_WaitForEvent\fR, \fBTcl_CreateFileHandler\fR, | 
|---|
| 447 | \fBTcl_DeleteFileHandler\fR and \fBTcl_ServiceModeHook\fR.  To support a | 
|---|
| 448 | new platform or to integrate Tcl with an application-specific event loop, | 
|---|
| 449 | you must write new versions of these procedures. | 
|---|
| 450 | .PP | 
|---|
| 451 | \fBTcl_InitNotifier\fR initializes the notifier state and returns | 
|---|
| 452 | a handle to the notifier state.  Tcl calls this | 
|---|
| 453 | procedure when initializing a Tcl interpreter.  Similarly, | 
|---|
| 454 | \fBTcl_FinalizeNotifier\fR shuts down the notifier, and is | 
|---|
| 455 | called by \fBTcl_Finalize\fR when shutting down a Tcl interpreter. | 
|---|
| 456 | .PP | 
|---|
| 457 | \fBTcl_WaitForEvent\fR is the lowest-level procedure in the notifier; | 
|---|
| 458 | it is responsible for waiting for an | 
|---|
| 459 | .QW interesting | 
|---|
| 460 | event to occur or | 
|---|
| 461 | for a given time to elapse.  Before \fBTcl_WaitForEvent\fR is invoked, | 
|---|
| 462 | each of the event sources' setup procedure will have been invoked. | 
|---|
| 463 | The \fItimePtr\fR argument to | 
|---|
| 464 | \fBTcl_WaitForEvent\fR gives the maximum time to block for an event, | 
|---|
| 465 | based on calls to \fBTcl_SetMaxBlockTime\fR made by setup procedures | 
|---|
| 466 | and on other information (such as the \fBTCL_DONT_WAIT\fR bit in | 
|---|
| 467 | \fIflags\fR). | 
|---|
| 468 | .PP | 
|---|
| 469 | Ideally, \fBTcl_WaitForEvent\fR should only wait for an event | 
|---|
| 470 | to occur; it should not actually process the event in any way. | 
|---|
| 471 | Later on, the | 
|---|
| 472 | event sources will process the raw events and create Tcl_Events on | 
|---|
| 473 | the event queue in their \fIcheckProc\fR procedures. | 
|---|
| 474 | However, on some platforms (such as Windows) this is not possible; | 
|---|
| 475 | events may be processed in \fBTcl_WaitForEvent\fR, including queuing | 
|---|
| 476 | Tcl_Events and more (for example, callbacks for native widgets may be | 
|---|
| 477 | invoked).  The return value from \fBTcl_WaitForEvent\fR must be either | 
|---|
| 478 | 0, 1, or \-1.  On platforms such as Windows where events get processed in | 
|---|
| 479 | \fBTcl_WaitForEvent\fR, a return value of 1 means that there may be more | 
|---|
| 480 | events still pending that have not been processed.  This is a sign to the | 
|---|
| 481 | caller that it must call \fBTcl_WaitForEvent\fR again if it wants all | 
|---|
| 482 | pending events to be processed. A 0 return value means that calling | 
|---|
| 483 | \fBTcl_WaitForEvent\fR again will not have any effect: either this is a | 
|---|
| 484 | platform where \fBTcl_WaitForEvent\fR only waits without doing any event | 
|---|
| 485 | processing, or \fBTcl_WaitForEvent\fR knows for sure that there are no | 
|---|
| 486 | additional events to process (e.g. it returned because the time | 
|---|
| 487 | elapsed).  Finally, a return value of \-1 means that the event loop is | 
|---|
| 488 | no longer operational and the application should probably unwind and | 
|---|
| 489 | terminate.  Under Windows this happens when a WM_QUIT message is received; | 
|---|
| 490 | under Unix it happens when \fBTcl_WaitForEvent\fR would have waited | 
|---|
| 491 | forever because there were no active event sources and the timeout was | 
|---|
| 492 | infinite. | 
|---|
| 493 | .PP | 
|---|
| 494 | \fBTcl_AlertNotifier\fR is used in multithreaded applications to allow | 
|---|
| 495 | any thread to | 
|---|
| 496 | .QW "wake up" | 
|---|
| 497 | the notifier to alert it to new events on its | 
|---|
| 498 | queue.  \fBTcl_AlertNotifier\fR requires as an argument the notifier | 
|---|
| 499 | handle returned by \fBTcl_InitNotifier\fR. | 
|---|
| 500 | .PP | 
|---|
| 501 | If the notifier will be used with an external event loop, then it must | 
|---|
| 502 | also support the \fBTcl_SetTimer\fR interface.  \fBTcl_SetTimer\fR is | 
|---|
| 503 | invoked by \fBTcl_SetMaxBlockTime\fR whenever the maximum blocking | 
|---|
| 504 | time has been reduced.  \fBTcl_SetTimer\fR should arrange for the | 
|---|
| 505 | external event loop to invoke \fBTcl_ServiceAll\fR after the specified | 
|---|
| 506 | interval even if no events have occurred.  This interface is needed | 
|---|
| 507 | because \fBTcl_WaitForEvent\fR is not invoked when there is an external | 
|---|
| 508 | event loop.  If the | 
|---|
| 509 | notifier will only be used from \fBTcl_DoOneEvent\fR, then | 
|---|
| 510 | \fBTcl_SetTimer\fR need not do anything. | 
|---|
| 511 | .PP | 
|---|
| 512 | \fBTcl_ServiceModeHook\fR is called by the platform-independent portion | 
|---|
| 513 | of the notifier when client code makes a call to | 
|---|
| 514 | \fBTcl_SetServiceMode\fR. This hook is provided to support operating | 
|---|
| 515 | systems that require special event handling when the application is in | 
|---|
| 516 | a modal loop (the Windows notifier, for instance, uses this hook to | 
|---|
| 517 | create a communication window). | 
|---|
| 518 | .PP | 
|---|
| 519 | On Unix systems, the file event source also needs support from the | 
|---|
| 520 | notifier.  The file event source consists of the | 
|---|
| 521 | \fBTcl_CreateFileHandler\fR and \fBTcl_DeleteFileHandler\fR | 
|---|
| 522 | procedures, which are described in the \fBTcl_CreateFileHandler\fR | 
|---|
| 523 | manual page. | 
|---|
| 524 | .PP | 
|---|
| 525 | The \fBTcl_Sleep\fR and \fBTcl_DoOneEvent\fR interfaces are described | 
|---|
| 526 | in their respective manual pages. | 
|---|
| 527 | .PP | 
|---|
| 528 | The easiest way to create a new notifier is to look at the code | 
|---|
| 529 | for an existing notifier, such as the files \fBunix/tclUnixNotfy.c\fR | 
|---|
| 530 | or \fBwin/tclWinNotify.c\fR in the Tcl source distribution. | 
|---|
| 531 |  | 
|---|
| 532 | .SH "REPLACING THE NOTIFIER" | 
|---|
| 533 | .PP | 
|---|
| 534 | A notifier that has been written according to the conventions above | 
|---|
| 535 | can also be installed in a running process in place of the standard | 
|---|
| 536 | notifier.  This mechanism is used so that a single executable can be | 
|---|
| 537 | used (with the standard notifier) as a stand-alone program and reused | 
|---|
| 538 | (with a replacement notifier in a loadable extension) as an extension | 
|---|
| 539 | to another program, such as a Web browser plugin. | 
|---|
| 540 | .PP | 
|---|
| 541 | To do this, the extension makes a call to \fBTcl_SetNotifier\fR | 
|---|
| 542 | passing a pointer to a \fBTcl_NotifierProcs\fR data structure.  The | 
|---|
| 543 | structure has the following layout: | 
|---|
| 544 | .CS | 
|---|
| 545 | typedef struct Tcl_NotifierProcs { | 
|---|
| 546 |     Tcl_SetTimerProc *setTimerProc; | 
|---|
| 547 |     Tcl_WaitForEventProc *waitForEventProc; | 
|---|
| 548 |     Tcl_CreateFileHandlerProc *createFileHandlerProc; | 
|---|
| 549 |     Tcl_DeleteFileHandlerProc *deleteFileHandlerProc; | 
|---|
| 550 |     Tcl_InitNotifierProc *initNotifierProc; | 
|---|
| 551 |     Tcl_FinalizeNotifierProc *finalizeNotifierProc; | 
|---|
| 552 |     Tcl_AlertNotifierProc *alertNotifierProc; | 
|---|
| 553 |     Tcl_ServiceModeHookProc *serviceModeHookProc; | 
|---|
| 554 | } Tcl_NotifierProcs; | 
|---|
| 555 | .CE | 
|---|
| 556 | Following the call to \fBTcl_SetNotifier\fR, the pointers given in | 
|---|
| 557 | the \fBTcl_NotifierProcs\fR structure replace whatever notifier had | 
|---|
| 558 | been installed in the process. | 
|---|
| 559 | .PP | 
|---|
| 560 | It is extraordinarily unwise to replace a running notifier. Normally, | 
|---|
| 561 | \fBTcl_SetNotifier\fR should be called at process initialization time | 
|---|
| 562 | before the first call to \fBTcl_InitNotifier\fR. | 
|---|
| 563 |  | 
|---|
| 564 | .SH "EXTERNAL EVENT LOOPS" | 
|---|
| 565 | .PP | 
|---|
| 566 | The notifier interfaces are designed so that Tcl can be embedded into | 
|---|
| 567 | applications that have their own private event loops.  In this case, | 
|---|
| 568 | the application does not call \fBTcl_DoOneEvent\fR except in the case | 
|---|
| 569 | of recursive event loops such as calls to the Tcl commands \fBupdate\fR | 
|---|
| 570 | or \fBvwait\fR.  Most of the time is spent in the external event loop | 
|---|
| 571 | of the application.  In this case the notifier must arrange for the | 
|---|
| 572 | external event loop to call back into Tcl when something | 
|---|
| 573 | happens on the various Tcl event sources.  These callbacks should | 
|---|
| 574 | arrange for appropriate Tcl events to be placed on the Tcl event queue. | 
|---|
| 575 | .PP | 
|---|
| 576 | Because the external event loop is not calling \fBTcl_DoOneEvent\fR on | 
|---|
| 577 | a regular basis, it is up to the notifier to arrange for | 
|---|
| 578 | \fBTcl_ServiceEvent\fR to be called whenever events are pending on the | 
|---|
| 579 | Tcl event queue.  The easiest way to do this is to invoke | 
|---|
| 580 | \fBTcl_ServiceAll\fR at the end of each callback from the external | 
|---|
| 581 | event loop.  This will ensure that all of the event sources are | 
|---|
| 582 | polled, any queued events are serviced, and any pending idle handlers | 
|---|
| 583 | are processed before returning control to the application.  In | 
|---|
| 584 | addition, event sources that need to poll for events can call | 
|---|
| 585 | \fBTcl_SetMaxBlockTime\fR to force the external event loop to call | 
|---|
| 586 | Tcl even if no events are available on the system event queue. | 
|---|
| 587 | .PP | 
|---|
| 588 | As a side effect of processing events detected in the main external | 
|---|
| 589 | event loop, Tcl may invoke \fBTcl_DoOneEvent\fR to start a recursive event | 
|---|
| 590 | loop in commands like \fBvwait\fR.  \fBTcl_DoOneEvent\fR will invoke | 
|---|
| 591 | the external event loop, which will result in callbacks as described | 
|---|
| 592 | in the preceding paragraph, which will result in calls to | 
|---|
| 593 | \fBTcl_ServiceAll\fR.  However, in these cases it is undesirable to | 
|---|
| 594 | service events in \fBTcl_ServiceAll\fR.  Servicing events there is | 
|---|
| 595 | unnecessary because control will immediately return to the | 
|---|
| 596 | external event loop and hence to \fBTcl_DoOneEvent\fR, which can | 
|---|
| 597 | service the events itself.  Furthermore, \fBTcl_DoOneEvent\fR is | 
|---|
| 598 | supposed to service only a single event, whereas \fBTcl_ServiceAll\fR | 
|---|
| 599 | normally services all pending events.  To handle this situation, | 
|---|
| 600 | \fBTcl_DoOneEvent\fR sets a flag for \fBTcl_ServiceAll\fR | 
|---|
| 601 | that causes it to return without servicing any events. | 
|---|
| 602 | This flag is called the \fIservice mode\fR; | 
|---|
| 603 | \fBTcl_DoOneEvent\fR restores it to its previous value before it returns. | 
|---|
| 604 | .PP | 
|---|
| 605 | In some cases, however, it may be necessary for \fBTcl_ServiceAll\fR | 
|---|
| 606 | to service events | 
|---|
| 607 | even when it has been invoked from \fBTcl_DoOneEvent\fR.  This happens | 
|---|
| 608 | when there is yet another recursive event loop invoked via an | 
|---|
| 609 | event handler called by \fBTcl_DoOneEvent\fR (such as one that is | 
|---|
| 610 | part of a native widget).  In this case, \fBTcl_DoOneEvent\fR may not | 
|---|
| 611 | have a chance to service events so \fBTcl_ServiceAll\fR must service | 
|---|
| 612 | them all.  Any recursive event loop that calls an external event | 
|---|
| 613 | loop rather than \fBTcl_DoOneEvent\fR must reset the service mode so | 
|---|
| 614 | that all events get processed in \fBTcl_ServiceAll\fR.  This is done | 
|---|
| 615 | by invoking the \fBTcl_SetServiceMode\fR procedure.  If | 
|---|
| 616 | \fBTcl_SetServiceMode\fR is passed \fBTCL_SERVICE_NONE\fR, then calls | 
|---|
| 617 | to \fBTcl_ServiceAll\fR will return immediately without processing any | 
|---|
| 618 | events.  If \fBTcl_SetServiceMode\fR is passed \fBTCL_SERVICE_ALL\fR, | 
|---|
| 619 | then calls to \fBTcl_ServiceAll\fR will behave normally. | 
|---|
| 620 | \fBTcl_SetServiceMode\fR returns the previous value of the service | 
|---|
| 621 | mode, which should be restored when the recursive loop exits. | 
|---|
| 622 | \fBTcl_GetServiceMode\fR returns the current value of the service | 
|---|
| 623 | mode. | 
|---|
| 624 |  | 
|---|
| 625 | .SH "SEE ALSO" | 
|---|
| 626 | \fBTcl_CreateFileHandler\fR, \fBTcl_DeleteFileHandler\fR, \fBTcl_Sleep\fR, | 
|---|
| 627 | \fBTcl_DoOneEvent\fR, \fBThread(3)\fR | 
|---|
| 628 | .SH KEYWORDS | 
|---|
| 629 | event, notifier, event queue, event sources, file events, timer, idle, service mode, threads | 
|---|