diff options
author | marha <marha@users.sourceforge.net> | 2011-03-25 15:37:13 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-03-25 15:37:13 +0000 |
commit | 41a502478a2972358dec934d82ee401c61a5cd36 (patch) | |
tree | 3fda8100e6da9b4a2863789e393016a750502067 /libXt/specs/CH07 | |
parent | 81aeaf653a832c4054d9a40b1cc796911521a739 (diff) | |
parent | 272e57235cd60a2e65ac8258d96a02eb3939b687 (diff) | |
download | vcxsrv-41a502478a2972358dec934d82ee401c61a5cd36.tar.gz vcxsrv-41a502478a2972358dec934d82ee401c61a5cd36.tar.bz2 vcxsrv-41a502478a2972358dec934d82ee401c61a5cd36.zip |
svn merge ^/branches/released .
Diffstat (limited to 'libXt/specs/CH07')
-rw-r--r-- | libXt/specs/CH07 | 3555 |
1 files changed, 3555 insertions, 0 deletions
diff --git a/libXt/specs/CH07 b/libXt/specs/CH07 new file mode 100644 index 000000000..07b36746b --- /dev/null +++ b/libXt/specs/CH07 @@ -0,0 +1,3555 @@ +.\" $Xorg: CH07,v 1.4 2000/08/17 19:42:45 cpqbld Exp $ +.\" Copyright \(co 1985, 1986, 1987, 1988, 1991, 1994 +.\" X Consortium +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining +.\" a copy of this software and associated documentation files (the +.\" "Software"), to deal in the Software without restriction, including +.\" without limitation the rights to use, copy, modify, merge, publish, +.\" distribute, sublicense, and/or sell copies of the Software, and to +.\" permit persons to whom the Software is furnished to do so, subject to +.\" the following conditions: +.\" +.\" The above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of the X Consortium shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from the X Consortium. +.\" +.\" Copyright \(co 1985, 1986, 1987, 1988, 1991, 1994 +.\" Digital Equipment Corporation, Maynard, Massachusetts. +.\" +.\" Permission to use, copy, modify and distribute this documentation for any +.\" purpose and without fee is hereby granted, provided that the above copyright +.\" notice appears in all copies and that both that copyright notice and this +.\" permission notice appear in supporting documentation, and that the name of +.\" Digital not be used in in advertising or publicity pertaining +.\" to distribution of the software without specific, written prior permission. +.\" Digital makes no representations about the suitability of the +.\" software described herein for any purpose. +.\" It is provided ``as is'' without express or implied warranty. +.\" +\& +.sp 1 +.ce 3 +\s+1\fBChapter 7\fP\s-1 + +\s+1\fBEvent Management\fP\s-1 +.sp 2 +.nr H1 7 +.nr H2 0 +.nr H3 0 +.nr H4 0 +.nr H5 0 +.LP +.XS +Chapter 7 \(em Event Management +.XE +While Xlib allows the reading and processing of events anywhere in an application, +widgets in the \*(tk neither directly read events +nor grab the server or pointer. +Widgets register procedures that are to be called +when an event or class of events occurs in that widget. +.LP +A typical application consists of startup code followed by an event loop +that reads events and dispatches them by calling +the procedures that widgets have registered. +The default event loop provided by the \*(xI is +.PN XtAppMainLoop . +.LP +The event manager is a collection of functions to perform the following tasks: +.IP \(bu 5 +Add or remove event sources other than X server events (in particular, +timer interrupts, file input, or POSIX signals). +.IP \(bu 5 +Query the status of event sources. +.IP \(bu 5 +Add or remove procedures to be called when an event occurs for a particular +widget. +.IP \(bu 5 +Enable and +disable the dispatching of user-initiated events (keyboard and pointer events) +for a particular widget. +.IP \(bu 5 +Constrain the dispatching of events to a cascade of pop-up widgets. +.IP \(bu 5 +Register procedures to be called when specific events arrive. +.IP \(bu 5 +Register procedures to be called when the \*(xI will block. +.IP \(bu 5 +Enable safe operation in a multi-threaded environment. +.LP +Most widgets do not need to call any of the event handler functions explicitly. +The normal interface to X events is through the higher-level +translation manager, +which maps sequences of X events, with modifiers, into procedure calls. +Applications rarely use any of the event manager routines besides +.PN XtAppMainLoop . + +.NH 2 +Adding and Deleting Additional Event Sources +.XS +\fB\*(SN Adding and Deleting Additional Event Sources\fP +.XE +.LP +While most applications are driven only by X events, +some applications need to incorporate other sources of input +into the \*(xI event-handling mechanism. +The event manager provides routines to integrate notification of timer events +and file data pending into this mechanism. +.LP +The next section describes functions that provide input gathering from files. +The application registers the files with the \*(xI read routine. +When input is pending on one of the files, +the registered callback procedures are invoked. + +.NH 3 +Adding and Removing Input Sources +.XS +\fB\*(SN Adding and Removing Input Sources\fP +.XE +.LP +To register a new file as an input source for a given application context, use +.PN XtAppAddInput . +.LP +.IN "XtAppAddInput" "" "@DEF@" +.sM +.FD 0 +XtInputId XtAppAddInput(\fIapp_context\fP, \fIsource\fP, \fIcondition\fP, \ +\fIproc\fP, \fIclient_data\fP) +.br + XtAppContext \fIapp_context\fP; +.br + int \fIsource\fP; +.br + XtPointer \fIcondition\fP; +.br + XtInputCallbackProc \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context that identifies the application. +.IP \fIsource\fP 1i +Specifies the source file descriptor on a POSIX-based system +or other operating-system-dependent device specification. +.IP \fIcondition\fP 1i +Specifies the mask that indicates a read, write, or exception condition +or some other operating-system-dependent condition. +.IP \fIproc\fP 1i +Specifies the procedure to be called when the condition is found. +.IP \fIclient_data\fP 1i +Specifies an argument passed to the specified procedure +when it is called. +.LP +.eM +The +.PN XtAppAddInput +function registers with the \*(xI read routine a new source of events, +which is usually file input but can also be file output. +Note that \fIfile\fP should be loosely interpreted to mean any sink +or source of data. +.PN XtAppAddInput +also specifies the conditions under which the source can generate events. +When an event is pending on this source, +the callback procedure is called. +.LP +The legal values for the \fIcondition\fP argument are operating-system-dependent. +On a POSIX-based system, +\fIsource\fP is a file number and the condition is some union of the following: +.IN "XtInputReadMask" "" "@DEF@" +.IP \fBXtInputReadMask\fR 1.5i +Specifies that \fIproc\fP is to be called when \fIsource\fP has data to be read. +.IN "XtInputWriteMask" "" "@DEF@" +.IP \fBXtInputWriteMask\fR 1.5i +Specifies that \fIproc\fP is to be called when \fIsource\fP is ready +for writing. +.IN "XtInputExceptMask" "" "@DEF@" +.IP \fBXtInputExceptMask\fR 1.5i +Specifies that \fIproc\fP is to be called when \fIsource\fP has +exception data. +.LP +Callback procedure pointers used to handle file events are of +type +.PN XtInputCallbackProc . +.LP +.IN "XtInputCallbackProc" "" "@DEF@" +.sM +.FD 0 +typedef void (*XtInputCallbackProc)(XtPointer, int*, XtInputId*); +.br + XtPointer \fIclient_data\fP; +.br + int *\fIsource\fP; +.br + XtInputId *\fIid\fP; +.FN +.IP \fIclient_data\fP 1i +Passes the client data argument that was registered for this procedure in +.PN XtApp\%AddInput . +.IP \fIsource\fP 1i +Passes the source file descriptor generating the event. +.IP \fIid\fP 1i +Passes the id returned from the corresponding +.PN XtAppAddInput +call. +.LP +.eM +See Section 7.12 for information regarding the use of +.PN XtAppAddInput +in multiple threads. +.sp +.LP +To discontinue a source of input, use +.PN XtRemoveInput . +.LP +.IN "XtRemoveInput" "" "@DEF@" +.sM +.FD 0 +void XtRemoveInput(\fIid\fP) +.br + XtInputId \fIid\fP; +.FN +.IP \fIid\fP 1i +Specifies the id returned from the corresponding +.PN XtAppAddInput +call. +.LP +.eM +The +.PN XtRemoveInput +function causes the \*(xI read routine to stop watching for events +from the file source specified by \fIid\fP. +.LP +See Section 7.12 for information regarding the use of +.PN XtRemoveInput +in multiple threads. + +.NH 3 +Adding and Removing Blocking Notifications +.XS +\fB\*(SN Adding and Removing Blocking Notifications\fP +.XE +.LP +Occasionally it is desirable for an application to receive notification +when the \*(xI event manager detects no pending input from file sources +and no pending input from X server event sources and is about to block +in an operating system call. +.sp +.LP +To register a hook that is called immediately prior to event blocking, use +.PN XtAppAddBlockHook . +.LP +.IN "XtAppAddBlockHook" "" "@DEF@" +.sM +.FD 0 +XtBlockHookId XtAppAddBlockHook(\fIapp_context\fP, \fIproc\fP, \ +\fIclient_data\fP) +.br + XtAppContext \fIapp_context\fP; +.br + XtBlockHookProc \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context that identifies the application. +.IP \fIproc\fP 1i +Specifies the procedure to be called before blocking. +.IP \fIclient_data\fP 1i +Specifies an argument passed to the specified procedure when it is called. +.LP +.eM +The +.PN XtAppAddBlockHook +function registers the specified procedure and returns an identifier for it. +The hook procedure \fIproc\fP is called at any time in the future when +the \*(xI are about to block pending some input. +.LP +The procedure pointers used to provide notification of event blocking +are of type +.PN XtBlockHookProc . +.LP +.IN "XtBlockHookProc" "" "@DEF@" +.sM +.FD 0 +typedef void (*XtBlockHookProc)(XtPointer); +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIclient_data\fP 1i +Passes the client data argument that was registered for this procedure in +.PN XtApp\%AddBlockHook . +.LP +.eM +To discontinue the use of a procedure for blocking notification, use +.PN XtRemoveBlockHook . +.LP +.IN "XtRemoveBlockHook" "" "@DEF@" +.sM +.FD 0 +void XtRemoveBlockHook(\fIid\fP) +.br + XtBlockHookId \fIid\fP; +.FN +.IP \fIid\fP 1i +Specifies the identifier returned from the corresponding call to +.PN XtAppAddBlockHook . +.LP +.eM +The +.PN XtRemoveBlockHook +function removes the specified procedure from the list of procedures +that are called by the \*(xI read routine before blocking on event sources. + +.NH 3 +Adding and Removing Timeouts +.XS +\fB\*(SN Adding and Removing Timeouts\fP +.XE +.LP +The timeout facility notifies the application or the widget +through a callback procedure that a specified time interval has elapsed. +Timeout values are uniquely identified by an interval id. +.sp +.LP +To register a timeout callback, use +.PN XtAppAddTimeOut . +.LP +.IN "XtAppAddTimeOut" "" "@DEF@" +.sM +.FD 0 +XtIntervalId XtAppAddTimeOut(\fIapp_context\fP, \fIinterval\fP, \fIproc\fP, \ +\fIclient_data\fP) +.br + XtAppContext \fIapp_context\fP; +.br + unsigned long \fIinterval\fP; +.br + XtTimerCallbackProc \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context for which the timer is to be set. +.IP \fIinterval\fP 1i +Specifies the time interval in milliseconds. +.IP \fIproc\fP 1i +Specifies the procedure to be called when the time expires. +.IP \fIclient_data\fP 1i +Specifies an argument passed to the specified procedure +when it is called. +.LP +.eM +The +.PN XtAppAddTimeOut +function creates a timeout and returns an identifier for it. +The timeout value is set to \fIinterval\fP. +The callback procedure \fIproc\fP is called when +.PN XtAppNextEvent +or +.PN XtAppProcessEvent +is next called after the time interval elapses, +and then the timeout is removed. +.LP +Callback procedure pointers used with timeouts are of +type +.PN XtTimerCallbackProc . +.LP +.IN "XtTimerCallbackProc" "" "@DEF@" +.sM +.FD 0 +typedef void (*XtTimerCallbackProc)(XtPointer, XtIntervalId*); +.br + XtPointer \fIclient_data\fP; +.br + XtIntervalId *\fItimer\fP; +.FN +.IP \fIclient_data\fP 1i +Passes the client data argument that was registered for this procedure in +.PN XtApp\%AddTimeOut . +.IP \fItimer\fP 1i +Passes the id returned from the corresponding +.PN XtAppAddTimeOut +call. +.LP +.eM +See Section 7.12 for information regarding the use of +.PN XtAppAddTimeOut +in multiple threads. +.sp +.LP +To clear a timeout value, use +.PN XtRemoveTimeOut . +.LP +.IN "XtRemoveTimeOut" "" "@DEF@" +.sM +.FD 0 +void XtRemoveTimeOut(\fItimer\fP) +.br + XtIntervalId \fItimer\fP; +.FN +.IP \fItimer\fP 1i +Specifies the id for the timeout request to be cleared. +.LP +.eM +The +.PN XtRemoveTimeOut +function removes the pending timeout. +Note that timeouts are automatically removed once they trigger. +.LP +Please refer to Section 7.12 for information regarding the use of +.PN XtRemoveTimeOut +in multiple threads. + +.NH 3 +Adding and Removing Signal Callbacks +.XS +\fB\*(SN Adding and Removing Signal Callbacks\fP +.XE +.LP +The signal facility notifies the application or the widget through a +callback procedure that a signal or other external asynchronous event +has occurred. The registered callback procedures are uniquely identified +by a signal id. +.sp +.LP +Prior to establishing a signal handler, the application or widget should +call +.PN XtAppAddSignal +and store the resulting identifier in a place accessible to the signal +handler. When a signal arrives, the signal handler should call +.PN XtNoticeSignal +to notify the \*(xI that a signal has occured. To register a signal +callback use +.PN XtAppAddSignal . +.LP +.IN "XtAppAddSignal" "" "@DEF@" +.sM +.FD 0 +XtSignalId XtAppAddSignal(\fIapp_context\fP, \fIproc\fP, \fIclient_data\fP) +.br + XtAppContext \fIapp_context\fP; +.br + XtSignalCallbackProc \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context that identifies the application. +.IP \fIproc\fP 1i +Specifies the procedure to be called when the signal is noticed. +.IP \fIclient_data\fP 1i +Specifies an argument passed to the specified procedure when it is called. +.LP +.eM +The callback procedure pointers used to handle signal events are of type +.PN XtSignalCallbackProc . +.LP +.IN "XtSignalCallbackProc" "" "@DEF@" +.sM +.FD 0 +typedef void (*XtSignalCallbackProc)(XtPointer, XtSignalId*); +.br + XtPointer \fIclient_data\fP; +.br + XtSignalId *\fIid\fP; +.FN +.IP \fIclient_data\fP 1i +Passes the client data argument that was registered for this procedure in +.PN XtAppAddSignal . +.IP \fIid\fP 1i +Passes the id returned from the corresponding +.PN XtAppAddSignal +call. +.LP +.eM +To notify the \*(xI that a signal has occured, use +.PN XtNoticeSignal . +.LP +.IN "XtNoticeSignal" "" "@DEF@" +.sp +.sM +.FD 0 +void XtNoticeSignal(\fIid\fP) +.br + XtSignalId \fIid\fP; +.FN +.IP \fIid\fP 1i +Specifies the id returned from the corresponding +.PN XtAppAddSignal +call. +.LP +.eM +On a POSIX-based system, +.PN XtNoticeSignal +is the only \*(xI function that can safely be called from a signal handler. +If +.PN XtNoticeSignal +is invoked multiple times before the \*(xI are able to invoke the +registered callback, the callback is only called once. +Logically, the \*(xI maintain ``pending'' flag for each registered callback. +This flag is initially +.PN False +and is set to +.PN True +by +.PN XtNoticeSignal . +When +.PN XtAppNextEvent +or +.PN XtAppProcessEvent +(with a mask including +.PN XtIMSignal ) +is called, all registered callbacks with ``pending'' +.PN True +are invoked and the flags are reset to +.PN False . +.LP +If the signal handler wants to track how many times the signal has been +raised, it can keep its own private counter. Typically the handler would +not do any other work; the callback does the actual processing for the +signal. The \*(xI never block signals from being raised, so if a given +signal can be raised multiple times before the \*(xI can invoke the +callback for that signal, the callback must be designed to deal with +this. In another case, a signal might be raised just after the \*(xI +sets the pending flag to +.PN False +but before the callback can get control, in which case the pending flag +will still be +.PN True +after the callback returns, and the \*(xI will invoke the callback +again, even though all of the signal raises have been handled. The +callback must also be prepared to handle this case. +.LP +To remove a registered signal callback, call +.PN XtRemoveSignal . +.LP +.IN "XtRemoveSignal" "" "@DEF@" +.sM +.FD 0 +void XtRemoveSignal(\fIid\fP) +.br + XtSignalId \fIid\fP; +.FN +.IP \fIid\fP 1i +Specifies the id returned by the corresponding call to +.PN XtAppAddSignal . +.LP +.eM +The client should typically disable the source of the signal before calling +.PN XtRemoveSignal . +If the signal could have been raised again before the source was disabled +and the client wants to process it, then after disabling the source but +before calling +.PN XtRemoveSignal +the client can test for signals with +.PN XtAppPending +and process them by calling +.PN XtAppProcessEvent +with the mask +.PN XtIMSignal . + +.NH 2 +Constraining Events to a Cascade of Widgets +.XS +\fB\*(SN Constraining Events to a Cascade of Widgets\fP +.XE +.LP +.IN "Grabbing Input" +.IN "Input Grabbing" +Modal widgets are widgets that, except for the input directed to them, +lock out user input to the application. +.LP +When a modal menu or modal dialog box is popped up using +.PN XtPopup , +user events (keyboard and pointer events) that occur outside the modal +widget should be delivered to the modal widget or ignored. +In no case will user events be delivered to a widget outside +the modal widget. +.LP +Menus can pop up submenus, and dialog boxes can pop up further dialog +boxes to create a pop-up cascade. +In this case, +user events may be delivered to one of several modal widgets in the cascade. +.LP +Display-related events should be delivered outside the modal cascade so that +exposure events and the like keep the application's display up-to-date. +Any event that occurs within the cascade is delivered as usual. +The user events delivered to the most recent spring-loaded shell +in the cascade when they occur outside the cascade are called remap events +and are +.PN KeyPress , +.PN KeyRelease , +.PN ButtonPress , +and +.PN ButtonRelease . +The user events ignored when they occur outside the cascade are +.PN MotionNotify +and +.PN EnterNotify . +All other events are delivered normally. +In particular, note that this is one +way in which widgets can receive +.PN LeaveNotify +events without first receiving +.PN EnterNotify +events; they should be prepared to deal with +this, typically by ignoring any unmatched +.PN LeaveNotify +events. +.LP +.PN XtPopup +uses the +.PN XtAddGrab +and +.PN XtRemoveGrab +functions to constrain user events to a modal cascade +and subsequently to remove a grab when the modal widget is popped down. + +.sp +.LP +To constrain or redirect user input to a modal widget, use +.PN XtAddGrab . +.LP +.IN "XtAddGrab" "" "@DEF@" +.sM +.FD 0 +void XtAddGrab(\fIw\fP, \fIexclusive\fP, \fIspring_loaded\fP) +.br + Widget \fIw\fP; +.br + Boolean \fIexclusive\fP; +.br + Boolean \fIspring_loaded\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget to add to the modal cascade. \*(cI +.IP \fIexclusive\fP 1i +Specifies whether user events should be dispatched exclusively to this widget +or also to previous widgets in the cascade. +.IP \fIspring_loaded\fP 1i +Specifies whether this widget was popped up because the user pressed +a pointer button. +.LP +.eM +The +.PN XtAddGrab +function appends the widget to the modal cascade +and checks that \fIexclusive\fP is +.PN True +if \fIspring_loaded\fP is +.PN True . +If this condition is not met, +.PN XtAddGrab +generates a warning message. +.LP +The modal cascade is used by +.PN XtDispatchEvent +when it tries to dispatch a user event. +When at least one modal widget is in the widget cascade, +.PN XtDispatchEvent +first determines if the event should be delivered. +It starts at the most recent cascade entry and follows the cascade up to and +including the most recent cascade entry added with the \fIexclusive\fP parameter +.PN True . +.LP +This subset of the modal cascade along with all descendants of these widgets +comprise the active subset. +User events that occur outside the widgets in this subset are ignored +or remapped. +Modal menus with submenus generally add a submenu widget to the cascade +with \fIexclusive\fP +.PN False . +Modal dialog boxes that need to restrict user input to the most deeply nested +dialog box add a subdialog widget to the cascade with \fIexclusive\fP +.PN True . +User events that occur within the active subset are delivered to the +appropriate widget, which is usually a child or further descendant of the modal +widget. +.LP +Regardless of where in the application they occur, +remap events are always delivered to the most recent widget in the active +subset of the cascade registered with \fIspring_loaded\fP +.PN True , +if any such widget exists. +If the event +occurred in the active subset of the cascade but outside the +spring-loaded widget, it is delivered normally before being +delivered also to the spring-loaded widget. +Regardless of where it is dispatched, the \*(xI do not modify +the contents of the event. +.sp +.LP +To remove the redirection of user input to a modal widget, use +.PN XtRemoveGrab . +.LP +.IN "XtRemoveGrab" "" "@DEF@" +.sM +.FD 0 +void XtRemoveGrab(\fIw\fP) +.br + Widget \fIw\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget to remove from the modal cascade. +.LP +.eM +The +.PN XtRemoveGrab +function removes widgets from the modal cascade starting +at the most recent widget up to and including the specified widget. +It issues a warning if the specified widget is not on the modal cascade. + +.NH 3 +Requesting Key and Button Grabs +.XS +\fB\*(SN Requesting Key and Button Grabs\fP +.XE +.LP +The \*(xI provide a set of key and button grab interfaces that +are parallel to those provided by Xlib and that allow the \*(xI +to modify event dispatching when necessary. \*(tk applications and +widgets that need to passively grab keys or buttons or actively grab +the keyboard or pointer should use the +following \*(xI routines rather than the corresponding Xlib +routines. +.sp +.LP +To passively grab a single key of the keyboard, use +.PN XtGrabKey . +.LP +.IN "XtGrabKey" "" "@DEF@" +.sM +.FD 0 +void XtGrabKey(\fIwidget\fP, \fIkeycode\fP, \fImodifiers\fP, \ +\fIowner_events\fP, \fIpointer_mode\fP, \fIkeyboard_mode\fP) +.br + Widget \fIwidget\fP; +.br + KeyCode \fIkeycode\fP; +.br + Modifiers \fImodifiers\fP; +.br + Boolean \fIowner_events\fP; +.br + int \fIpointer_mode\fP, \fIkeyboard_mode\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget in whose window the key is to be grabbed. \*(cI +.sp 6p +.IP \fIkeycode\fP +.br +.ns +.IP \fImodifiers\fP +.br +.ns +.IP \fIowner_events\fP +.br +.ns +.IP \fIpointer_mode\fP +.br +.ns +.IP \fIkeyboard_mode\fP 1i +Specify arguments to +.PN XGrabKey ; +see Section 12.2 in \fI\*(xL\fP. +.LP +.eM +.PN XtGrabKey +calls +.PN XGrabKey +specifying the widget's window as the grab +window if the widget is realized. The remaining arguments are exactly +as for +.PN XGrabKey . +If the widget is not realized, or is later unrealized, the call to +.PN XGrabKey +is performed (again) when +the widget is realized and its window becomes mapped. In the future, +if +.PN XtDispatchEvent +is called with a +.PN KeyPress +event matching the specified keycode and modifiers (which may be +.PN AnyKey +or +.PN AnyModifier , +respectively) for the +widget's window, the \*(xI will call +.PN XtUngrabKeyboard +with the timestamp from the +.PN KeyPress +event if either of the following conditions is true: +.IP \(bu 3 +There is a modal cascade and the widget is not in +the active subset of the cascade and the keyboard was not previously +grabbed, or +.IP \(bu 3 +.PN XFilterEvent +returns +.PN True . + +.sp +.LP +To cancel a passive key grab, use +.PN XtUngrabKey . +.LP +.IN "XtUngrabKey" "" "@DEF@" +.sM +.FD 0 +void XtUngrabKey(\fIwidget\fP, \fIkeycode\fP\fI, modifiers\fP) +.br + Widget \fIwidget\fP; +.br + KeyCode \fIkeycode\fP; +.br + Modifiers \fImodifiers\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget in whose window the key was grabbed. +.sp 6p +.IP \fIkeycode\fP +.br +.ns +.IP \fImodifiers\fP 1i +Specify arguments to +.PN XUngrabKey ; +see Section 12.2 in \fI\*(xL\fP. +.LP +.eM +The +.PN XtUngrabKey +procedure calls +.PN XUngrabKey +specifying the widget's +window as the ungrab window if the widget is realized. The remaining +arguments are exactly as for +.PN XUngrabKey . +If the widget is not realized, +.PN XtUngrabKey +removes a deferred +.PN XtGrabKey +request, if any, for the specified widget, keycode, and modifiers. +.sp +.LP +To actively grab the keyboard, use +.PN XtGrabKeyboard . +.LP +.IN "XtGrabKeyboard" "" "@DEF@" +.sM +.FD 0 +int XtGrabKeyboard(\fIwidget\fP, \fIowner_events\fP, \fIpointer_mode\fP, \ +\fIkeyboard_mode\fP, \fItime\fP) +.br + Widget \fIwidget\fP; +.br + Boolean \fIowner_events\fP; +.br + int \fIpointer_mode\fP, \fIkeyboard_mode\fP; +.br + Time \fItime\fP; +.br +.FN +.IP \fIwidget\fP 1i +Specifies the widget for whose window the keyboard is to be grabbed. +\*(cI +.sp 6p +.IP \fIowner_events\fP +.br +.ns +.IP \fIpointer_mode\fP +.br +.ns +.IP \fIkeyboard_mode\fP +.br +.ns +.IP \fItime\fP 1i +Specify arguments to +.PN XGrabKeyboard ; +see Section 12.2 in \fI\*(xL\fP. +.LP +.eM +If the specified widget is realized, +.PN XtGrabKeyboard +calls +.PN XGrabKeyboard +specifying the widget's window as the grab window. The remaining +arguments and return value are exactly as for +.PN XGrabKeyboard . +If the widget is not realized, +.PN XtGrabKeyboard +immediately returns +.PN GrabNotViewable . +No future automatic ungrab is implied by +.PN XtGrabKeyboard . +.sp +.LP +To cancel an active keyboard grab, use +.PN XtUngrabKeyboard . +.LP +.IN "XtUngrabKeyboard" "" "@DEF@" +.sM +.FD 0 +void XtUngrabKeyboard(\fIwidget\fP, \fItime\fP) +.br + Widget \fIwidget\fP; +.br + Time \fItime\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget that has the active keyboard grab. +.IP \fItime\fP 1i +Specifies the additional argument to +.PN XUngrabKeyboard ; +see Section 12.2 in \fI\*(xL\fP. +.LP +.eM +.PN XtUngrabKeyboard +calls +.PN XUngrabKeyboard +with the specified time. +.sp +.LP +To passively grab a single pointer button, use +.PN XtGrabButton . +.LP +.IN "XtGrabButton" "" "@DEF@" +.sM +.FD 0 +void XtGrabButton(\fIwidget\fP, \fIbutton\fP, \fImodifiers\fP, \ +\fIowner_events\fP, \fIevent_mask\fP, \fIpointer_mode\fP, + \fIkeyboard_mode\fP, \fIconfine_to\fP, \fIcursor\fP) +.br + Widget \fIwidget\fP; +.br + int \fIbutton\fP; +.br + Modifiers \fImodifiers\fP; +.br + Boolean \fIowner_events\fP; +.br + unsigned int \fIevent_mask\fP; +.br + int \fIpointer_mode\fP, \fIkeyboard_mode\fP; +.br + Window \fIconfine_to\fP; +.br + Cursor \fIcursor\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget in whose window the button is to be grabbed. \*(cI +.sp 6p +.IP \fIbutton\fP +.br +.ns +.IP \fImodifiers\fP +.br +.ns +.IP \fIowner_events\fP +.br +.ns +.IP \fIevent_mask\fP +.br +.ns +.IP \fIpointer_mode\fP +.br +.ns +.IP \fIkeyboard_mode\fP +.br +.ns +.IP \fIconfine_to\fP +.br +.ns +.IP \fIcursor\fP 1i +Specify arguments to +.PN XGrabButton ; +see Section 12.1 in \fI\*(xL\fP. +.LP +.eM +.PN XtGrabButton +calls +.PN XGrabButton +specifying the widget's window as the +grab window if the widget is realized. The remaining arguments are +exactly as for +.PN XGrabButton . +If the widget is not realized, or is later unrealized, the call to +.PN XGrabButton +is performed (again) +when the widget is realized and its window becomes mapped. In the +future, if +.PN XtDispatchEvent +is called with a +.PN ButtonPress +event matching the specified button and modifiers (which may be +.PN AnyButton +or +.PN AnyModifier , +respectively) +for the widget's window, the \*(xI will call +.PN XtUngrabPointer +with the timestamp from the +.PN ButtonPress +event if either of the following conditions is true: +.IP \(bu 3 +There is a modal cascade and the +widget is not in the active subset of the cascade and the pointer was +not previously grabbed, or +.IP \(bu 3 +.PN XFilterEvent +returns +.PN True . + +.sp +.LP +To cancel a passive button grab, use +.PN XtUngrabButton . +.LP +.IN "XtUngrabButton" "" "@DEF@" +.sM +.FD 0 +void XtUngrabButton(\fIwidget\fP, \fIbutton\fP, \fImodifiers\fP) +.br + Widget \fIwidget\fP; +.br + unsigned int \fIbutton\fP; +.br + Modifiers \fImodifiers\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget in whose window the button was grabbed. +.IP \fIbutton\fP +.br +.ns +.IP \fImodifiers\fP 1i +Specify arguments to +.PN XUngrabButton ; +see Section 12.1 in \fI\*(xL\fP. +.LP +.eM +The +.PN XtUngrabButton +procedure calls +.PN XUngrabButton +specifying the +widget's window as the ungrab window if the widget is realized. The +remaining arguments are exactly as for +.PN XUngrabButton . +If the widget is not realized, +.PN XtUngrabButton +removes a deferred +.PN XtGrabButton +request, if any, for the specified widget, button, and modifiers. +.sp +.LP +To actively grab the pointer, use +.PN XtGrabPointer . +.LP +.IN "XtGrabPointer" "" "@DEF@" +.sM +.FD 0 +int XtGrabPointer(\fIwidget\fP, \fIowner_events\fP, \fIevent_mask\fP, \ +\fIpointer_mode\fP, \fIkeyboard_mode\fP, + \fIconfine_to\fP, \fIcursor\fP, \fItime\fP) +.br + Widget \fIwidget\fP; +.br + Boolean \fIowner_events\fP; +.br + unsigned int \fIevent_mask\fP; +.br + int \fIpointer_mode\fP, \fIkeyboard_mode\fP; +.br + Window \fIconfine_to\fP; +.br + Cursor \fIcursor\fP; +.br + Time \fItime\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget for whose window the pointer is to be grabbed. \*(cI +.sp 6p +.IP \fIowner_events\fP +.br +.ns +.IP \fIevent_mask\fP +.br +.ns +.IP \fIpointer_mode\fP +.br +.ns +.IP \fIkeyboard_mode\fP +.br +.ns +.IP \fIconfine_to\fP +.br +.ns +.IP \fIcursor\fP +.br +.ns +.IP \fItime\fP 1i +Specify arguments to +.PN XGrabPointer ; +see Section 12.1 in \fI\*(xL\fP. +.LP +.eM +If the specified widget is realized, +.PN XtGrabPointer +calls +.PN XGrabPointer , +specifying the widget's window as the grab window. The remaining +arguments and return value are exactly as for +.PN XGrabPointer . +If the widget is not realized, +.PN XtGrabPointer +immediately returns +.PN GrabNotViewable . +No future automatic ungrab is implied by +.PN XtGrabPointer . +.sp +.LP +To cancel an active pointer grab, use +.PN XtUngrabPointer . +.LP +.IN "XtUngrabPointer" "" "@DEF@" +.sM +.FD 0 +void XtUngrabPointer(\fIwidget\fP, \fItime\fP) +.br + Widget \fIwidget\fP; +.br + Time \fItime\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget that has the active pointer grab. +.IP \fItime\fP 1i +Specifies the time argument to +.PN XUngrabPointer ; +see Section 12.1 in \fI\*(xL\fP. +.LP +.eM +.PN XtUngrabPointer +calls +.PN XUngrabPointer +with the specified time. + +.NH 2 +Focusing Events on a Child +.XS +\fB\*(SN Focusing Events on a Child\fP +.XE +.LP +To redirect keyboard input to a normal descendant of a +widget without calling +.PN XSetInputFocus , +use +.PN XtSetKeyboardFocus . +.LP +.IN "XtSetKeyboardFocus" "" "@DEF@" +.sM +.FD 0 +void XtSetKeyboardFocus(\fIsubtree\fP\, \fIdescendant\fP) +.br + Widget \fIsubtree\fP, \fIdescendant\fP; +.FN +.IP \fIsubtree\fP 1i +Specifies the subtree of the hierarchy for which the keyboard focus is +to be set. \*(cI +.IP \fIdescendant\fP 1i +Specifies either the normal (non-pop-up) descendant of \fIsubtree\fP to which +keyboard events are logically directed, or +.PN None . +It is not an error to specify +.PN None +when no input focus was previously set. \*(oI +.LP +.eM +.PN XtSetKeyboardFocus +causes +.PN XtDispatchEvent +to remap keyboard events occurring within the specified subtree +and dispatch them to the specified descendant widget or to an ancestor. +If the descendant's class is not a subclass of Core, the descendant is +replaced by its closest windowed ancestor. +.LP +When there is no modal cascade, keyboard events can be dispatched +to a widget in one of five ways. Assume the server delivered the +event to the window for widget E (because of X input focus, key or +keyboard grabs, or pointer position). +.IP \(bu 3 +If neither E nor any of E's ancestors have redirected the keyboard +focus, or if the event activated a grab for E as specified by a call +to +.PN XtGrabKey +with any value of \fIowner_events\fP, or +if the keyboard is actively grabbed by E with \fIowner_events\fP +.PN False +via +.PN XtGrabKeyboard +or +.PN XtGrabKey +on a previous key press, the event is dispatched to E. +.IP \(bu 3 +Beginning with the ancestor of E closest to the root that has +redirected the keyboard focus or E if no such ancestor exists, if +the target of that focus redirection has in turn redirected the +keyboard focus, recursively follow this focus chain to find a widget +F that has not redirected focus. +.RS +.IP \- 3 +If E is the final focus target widget F or a descendant of F, the +event is dispatched to E. +.IP \- 3 +If E is not F, an ancestor of F, or a descendant of F, and the event +activated a grab for E as specified by a call to +.PN XtGrabKey +for E, +.PN XtUngrabKeyboard +is called. +.IP \- 3 +If E is an ancestor of F, and the event is a key press, and either +.RS +.IP + 3 +E has grabbed the key with +.PN XtGrabKey +and \fIowner_events\fP +.PN False , +or +.IP + 3 +E has grabbed the key with +.PN XtGrabKey +and \fIowner_events\fP +.PN True , +and the coordinates of the event are outside the rectangle specified +by E's geometry, +.RE +then the event is dispatched to E. +.IP \- 3 +Otherwise, define A as the closest common ancestor of E and F: +.RS +.IP + 3 +If there is an active keyboard grab for any widget via either +.PN XtGrabKeyboard +or +.PN XtGrabKey +on a previous key press, or +if no widget between F and A (noninclusive) has grabbed +the key and modifier combination with +.PN XtGrabKey +and any value of \fIowner_events\fP, the event is dispatched to F. +.IP + 3 +Else, the event is dispatched to the ancestor of F closest to A +that has grabbed the key and modifier combination with +.PN XtGrabKey . +.RE +.RE +.LP +When there is a modal cascade, if the final destination widget as +identified above is in the active subset of the cascade, the event is +dispatched; otherwise the event is remapped to a spring-loaded shell +or discarded. +Regardless of where it is dispatched, the \*(xI do not modify +the contents of the event. +.LP +When \fIsubtree\fP or one of its descendants acquires the X input focus +or the pointer moves into the subtree such that keyboard events would +now be delivered to the subtree, a +.PN FocusIn +event is generated for the descendant if +.PN FocusChange +events have been selected by the descendant. +Similarly, when \fIsubtree\fP loses the X input focus +or the keyboard focus for one of its ancestors, a +.PN FocusOut +event is generated for descendant if +.PN FocusChange +events have been selected by the descendant. +.sp +.LP +A widget tree may also actively manage the X server input focus. To +do so, a widget class specifies an accept_focus procedure. +.LP +.IN "accept_focus procedure" +The accept_focus procedure pointer is of type +.PN XtAcceptFocusProc . +.LP +.IN "XtAcceptFocusProc" "" "@DEF@" +.sM +.FD 0 +typedef Boolean (*XtAcceptFocusProc)(Widget, Time*); +.br + Widget \fIw\fP; +.br + Time *\fItime\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget. +.IP \fItime\fP 1i +Specifies the X time of the event causing the accept focus. +.LP +.eM +Widgets that need the input focus can call +.PN XSetInputFocus +explicitly, pursuant to the restrictions of the \fI\*(xC\fP. +To allow outside agents, such as the parent, +to cause a widget to take the input focus, +every widget exports an accept_focus procedure. +The widget returns a value indicating +whether it actually took the focus or not, +so that the parent can give the focus to another widget. +Widgets that need to know when they lose the input focus must use +the Xlib focus notification mechanism explicitly +(typically by specifying translations for +.PN FocusIn +and +.PN FocusOut +events). +Widgets classes that never want the input focus should set the +\fIaccept_focus\fP field to NULL. +.sp +.LP +To call a widget's accept_focus procedure, use +.PN XtCallAcceptFocus . +.LP +.IN "XtCallAcceptFocus" "" "@DEF@" +.sM +.FD 0 +Boolean XtCallAcceptFocus(\fIw\fP, \fItime\fP) +.br + Widget \fIw\fP; +.br + Time *\fItime\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget. \*(cI +.IP \fItime\fP 1i +Specifies the X time of the event that is causing the focus change. +.LP +.eM +The +.PN XtCallAcceptFocus +function calls the specified widget's accept_focus procedure, +passing it the specified widget and time, and returns what the accept_focus +procedure returns. +If \fIaccept_focus\fP is NULL, +.PN XtCallAcceptFocus +returns +.PN False . + +.NH 3 +Events for Drawables That Are Not a Widget's Window +.XS +\fB\*(SN Events for Drawables That Are Not a Widget's Window\fP +.XE +.LP +Sometimes an application must handle events for drawables that are not +associated with widgets in its widget tree. Examples include handling +.PN GraphicsExpose +and +.PN NoExpose +events on Pixmaps, and handling +.PN PropertyNotify +events on the root window. +.LP +To register a drawable with the \*(xI event dispatching, use +.PN XtRegisterDrawable . +.LP +.IN "XtRegisterDrawable" "" "@DEF@" +.sM +.FD 0 +void XtRegisterDrawable(\fIdisplay\fP, \fIdrawable\fP, \fIwidget\fP) +.br + Display *\fIdisplay\fP; +.br + Drawable \fIdrawable\fP; +.br + Widget \fIwidget\fP; +.FN +.IP \fIdisplay\fP 1i +Specifies the drawable's display. +.IP \fIdrawable\fP 1i +Specifies the drawable to register. +.IP \fIwidget\fP 1i +Specifies the widget to register the drawable for. +.LP +.eM +.PN XtRegisterDrawable +associates the specified drawable with the specified widget +so that future calls to +.PN XtWindowToWidget +with the drawable will return the widget. +The default event dispatcher will dispatch future events that +arrive for the drawable to the widget in the same manner as +events that contain the widget's window. +.LP +If the drawable is already registered with another widget, or if the +drawable is the window of a widget in the client's widget tree, the +results of calling +.PN XtRegisterDrawable +are undefined. + +.LP +To unregister a drawable with the Intrinsics event dispatching, use +.PN XtUnregisterDrawable . +.LP +.IN "XtUnregisterDrawable" "" "@DEF@" +.sM +.FD 0 +void XtUnregisterDrawable(\fIdisplay\fP, \fIdrawable\fP) +.br + Display *\fIdisplay\fP; +.br + Drawable \fIdrawable\fP; +.FN +.IP \fIdisplay\fP 1i +Specifies the drawable's display. +.IP \fIdrawable\fP 1i +Specifies the drawable to unregister. +.LP +.eM +.PN XtUnregisterDrawable +removes an association created with +.PN XtRegisterDrawable . +If the drawable is the window of a widget in the client's widget tree +the results of calling +.PN XtUnregisterDrawable +are undefined. + +.NH 2 +Querying Event Sources +.XS +\fB\*(SN Querying Event Sources\fP +.XE +.LP +The event manager provides several functions to examine and read events +(including file and timer events) that are in the queue. +The next three functions are \*(xI equivalents of the +.PN XPending , +.PN XPeekEvent , +and +.PN XNextEvent +Xlib calls. +.sp +.LP +.IN "Events" +To determine if there are any events on the input queue for a given application, +use +.PN XtAppPending . +.LP +.IN "XtAppPending" "" "@DEF@" +.sM +.FD 0 +XtInputMask XtAppPending(\fIapp_context\fP) +.br + XtAppContext \fIapp_context\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context that identifies the application to check. +.LP +.eM +The +.PN XtAppPending +function returns a nonzero value if there are +events pending from the X server, timer pending, other input sources +pending, or signal sources pending. The +value returned is a bit mask that is the OR of +.PN XtIMXEvent , +.PN XtIMTimer , +.PN XtIMAlternateInput , +and +.PN XtIMSignal +(see +.PN XtAppProcessEvent ). +If there are no events pending, +.PN XtAppPending +flushes the output buffers of each Display in the application context +and returns zero. +.sp +.LP +To return the event from the head of a given application's input queue +without removing input from the queue, use +.PN XtAppPeekEvent . +.LP +.IN "XtAppPeekEvent" "" "@DEF@" +.sM +.FD 0 +Boolean XtAppPeekEvent(\fIapp_context\fP, \fIevent_return\fP) +.br + XtAppContext \fIapp_context\fP; +.br + XEvent *\fIevent_return\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context that identifies the application. +.IP \fIevent_return\fP 1i +Returns the event information to the specified event structure. +.LP +.eM +If there is an X event in the queue, +.PN XtAppPeekEvent +copies it into \fIevent_return\fP and returns +.PN True . +If no X input is on the queue, +.PN XtAppPeekEvent +flushes the output buffers of each Display in the application context +and blocks until some input is available +(possibly calling some timeout callbacks in the interim). +If the next available input is an X event, +.PN XtAppPeekEvent +fills in \fIevent_return\fP and returns +.PN True . +Otherwise, the input is for an input source +registered with +.PN XtAppAddInput , +and +.PN XtAppPeekEvent +returns +.PN False . +.FS +The sample implementations provides XtAppPeekEvent as described. Timeout callbacks +are called while blocking for input. If some input for an input source is +available, +.PN XtAppPeekEvent +will return +.PN True +without returning an event. +.FE +.sp +.LP +To remove and return the event +from the head of a given application's X event queue, +use +.PN XtAppNextEvent . +.LP +.IN "XtAppNextEvent" "" "@DEF@" +.sM +.FD 0 +void XtAppNextEvent(\fIapp_context\fP, \fIevent_return\fP) +.br + XtAppContext \fIapp_context\fP; +.br + XEvent *\fIevent_return\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context that identifies the application. +.IP \fIevent_return\fP 1i +Returns the event information to the specified event structure. +.LP +.eM +If the X event queue is empty, +.PN XtAppNextEvent +flushes the X output buffers of each Display in the application context +and waits for an X event while looking at the other input sources +and timeout values and calling any callback procedures triggered by them. +This wait time can be used for background processing; +see Section 7.8. + +.NH 2 +Dispatching Events +.XS +\fB\*(SN Dispatching Events\fP +.XE +.LP +The \*(xI provide functions that dispatch events +to widgets or other application code. +Every client interested in X events on a widget uses +.PN XtAddEventHandler +to register which events it is +interested in and a procedure (event handler) to be called +when the event happens in that window. +The translation manager automatically registers event handlers for widgets +that use translation tables; see Chapter 10. +.sp +.LP +Applications that need direct control of the processing of different types +of input should use +.PN XtAppProcessEvent . +.LP +.IN "XtAppProcessEvent" "" "@DEF@" +.sM +.FD 0 +void XtAppProcessEvent(\fIapp_context\fP, \fImask\fP) +.br + XtAppContext \fIapp_context\fP; +.br + XtInputMask \fImask\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context that identifies the +application for which to process input. +.IP \fImask\fP 1i +Specifies what types of events to process. +The mask is the bitwise inclusive OR of any combination of +.PN XtIMXEvent , +.PN XtIMTimer , +.PN XtIMAlternateInput , +and +.PN XtIMSignal . +As a convenience, +.PN Intrinsic.h +defines the symbolic name +.PN XtIMAll +to be the bitwise inclusive OR of these four event types. +.LP +.eM +The +.PN XtAppProcessEvent +function processes one timer, input source, signal source, or X event. +If there is no event or input of the appropriate type to process, then +.PN XtAppProcessEvent +blocks until there is. +If there is more than one type of input available to process, +it is undefined which will get processed. +Usually, this procedure is not called by client applications; see +.PN XtAppMainLoop . +.PN XtAppProcessEvent +processes timer events by calling any appropriate timer callbacks, +input sources by calling any appropriate input callbacks, +signal source by calling any appropriate signal callbacks, +and X events by +calling +.PN XtDispatchEvent . +.LP +When an X event is received, +it is passed to +.PN XtDispatchEvent , +which calls the appropriate event handlers +and passes them the widget, the event, and client-specific data +registered with each procedure. +If no handlers for that event are registered, +the event is ignored and the dispatcher simply returns. + +.sp +.LP +To dispatch an event returned by +.PN XtAppNextEvent , +retrieved directly from the Xlib queue, or synthetically constructed, +to any registered event filters or event handlers, call +.PN XtDispatchEvent . +.LP +.IN "XtDispatchEvent" "" "@DEF@" +.sM +.FD 0 +Boolean XtDispatchEvent(\fIevent\fP) +.br + XEvent *\fIevent\fP; +.FN +.IP \fIevent\fP 1i +Specifies a pointer to the event structure to be dispatched +to the appropriate event handlers. +.LP +.eM +The +.PN XtDispatchEvent +function first calls +.PN XFilterEvent +with the \fIevent\fP and the window of the widget to which the +\*(xI intend to dispatch the event, or the event window if +the \*(xI would not dispatch the event to any handlers. +If +.PN XFilterEvent +returns +.PN True +and the event activated a server grab as identified +by a previous call to +.PN XtGrabKey +or +.PN XtGrabButton , +.PN XtDispatchEvent +calls +.PN XtUngrabKeyboard +or +.PN XtUngrabPointer +with the timestamp from the event and immediately returns +.PN True . +If +.PN XFilterEvent +returns +.PN True +and a grab was not activated, +.PN XtDispatchEvent +just immediately returns +.PN True . +Otherwise, +.PN XtDispatchEvent +sends the event to the event handler functions that +have been previously registered with the dispatch routine. +.PN XtDispatchEvent +returns +.PN True +if +.PN XFilterEvent +returned +.PN True , +or if the event was dispatched to some handler, and +.PN False +if it found no handler to which to dispatch the event. +.PN XtDispatchEvent +records the last timestamp in any event that +contains a timestamp (see +.PN XtLastTimestampProcessed ), +regardless of whether it was filtered or dispatched. +If a modal cascade is active with \fIspring_loaded\fP +.PN True , +and if the event is a remap event as defined by +.PN XtAddGrab , +.PN XtDispatchEvent +may dispatch the event a second time. If it does so, +.PN XtDispatchEvent +will call +.PN XFilterEvent +again with the window of the spring-loaded widget prior to the second +dispatch, and if +.PN XFilterEvent +returns +.PN True , +the second dispatch will not be performed. + +.NH 2 +The Application Input Loop +.XS +\fB\*(SN The Application Input Loop\fP +.XE +.LP +To process all input from a given application in a continuous loop, +use the convenience procedure +.PN XtAppMainLoop . +.LP +.IN "XtAppMainLoop" "" "@DEF@" +.sM +.FD 0 +void XtAppMainLoop(\fIapp_context\fP) +.br + XtAppContext \fIapp_context\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context that identifies the application. +.LP +.eM +The +.PN XtAppMainLoop +function first reads the next incoming X event by calling +.PN XtAppNextEvent +and then dispatches the event to the appropriate registered procedure +by calling +.PN XtDispatchEvent . +This constitutes the main loop of \*(tk applications. +There is nothing special about +.PN XtAppMainLoop ; +it simply calls +.PN XtAppNextEvent +and then +.PN XtDispatchEvent +in a conditional loop. +At the bottom of the loop, it checks to see if the specified +application context's destroy flag is set. +If the flag is set, the loop breaks. +The whole loop is enclosed between a matching +.PN XtAppLock +and +.PN XtAppUnlock . +.LP +Applications can provide their own version of this loop, +which tests some global termination flag or tests that the number +of top-level widgets is larger than zero before circling back to the call to +.PN XtAppNextEvent . + +.NH 2 +Setting and Checking the Sensitivity State of a Widget +.XS +\fB\*(SN Setting and Checking the Sensitivity State of a Widget\fP +.XE +.LP +Many widgets have a mode in which they assume a different appearance +(for example, are grayed out or stippled), do not respond to user events, +and become dormant. +.LP +When dormant, +a widget is considered to be insensitive. +If a widget is insensitive, +the event manager does not dispatch any events to the widget +with an event type of +.PN KeyPress , +.PN KeyRelease , +.PN ButtonPress , +.PN ButtonRelease , +.PN MotionNotify , +.PN EnterNotify , +.PN LeaveNotify , +.PN FocusIn , +or +.PN FocusOut . +.LP +A widget can be insensitive because its \fIsensitive\fP field is +.PN False +or because one of its ancestors is insensitive and thus the widget's +\fIancestor_sensitive\fP field also is +.PN False . +A widget can but does not need to distinguish these two cases visually. +.NT +Pop-up shells will have +\fIancestor_sensitive\fP +.PN False +if the parent was insensitive when the shell +was created. Since +.PN XtSetSensitive +on the parent will not +modify the resource of the pop-up child, clients are advised to include +a resource specification of the form +``*TransientShell.ancestorSensitive: True'' +in the application defaults resource file or to +otherwise ensure that the parent is +sensitive when creating pop-up shells. +.NE +.sp +.LP +To set the sensitivity state of a widget, use +.PN XtSetSensitive . +.LP +.IN "XtSetSensitive" "" "@DEF@" +.sM +.FD 0 +void XtSetSensitive(\fIw\fP, \fIsensitive\fP) +.br + Widget \fIw\fP; +.br + Boolean \fIsensitive\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget. \*(rI +.IP \fIsensitive\fP 1i +Specifies whether the widget should receive +keyboard, pointer, and focus events. +.LP +.eM +The +.PN XtSetSensitive +function first calls +.PN XtSetValues +on the current widget with an argument list specifying the +XtNsensitive resource and the new value. +If \fIsensitive\fP is +.PN False +and the widget's class is a subclass of +Composite, +.PN XtSetSensitive +recursively propagates the new value +down the child tree by calling +.PN XtSetValues +on each child to set \fIancestor_sensitive\fP to +.PN False . +If \fIsensitive\fP is +.PN True +and the widget's class is a subclass of +Composite +and the widget's \fIancestor_sensitive\fP field is +.PN True , +.PN XtSetSensitive +sets the \fIancestor_sensitive\fP of each child to +.PN True +and then recursively calls +.PN XtSetValues +on each normal descendant that is now sensitive to set +\fIancestor_sensitive\fP to +.PN True . +.LP +.PN XtSetSensitive +calls +.PN XtSetValues +to change the \fIsensitive\fP and \fIancestor_sensitive\fP fields +of each affected widget. +Therefore, when one of these changes, +the widget's set_values procedure should +take whatever display actions are needed +(for example, graying out or stippling the widget). +.LP +.PN XtSetSensitive +maintains the invariant that, if the parent has either \fIsensitive\fP +or \fIancestor_sensitive\fP +.PN False , +then all children have \fIancestor_sensitive\fP +.PN False . +.sp +.LP +To check the current sensitivity state of a widget, +use +.PN XtIsSensitive . +.LP +.IN "XtIsSensitive" "" "@DEF@" +.sM +.FD 0 +Boolean XtIsSensitive(\fIw\fP) +.br + Widget \fIw\fP; +.FN +.IP \fIw\fP 1i +Specifies the object. \*(oI +.LP +.eM +The +.PN XtIsSensitive +function returns +.PN True +or +.PN False +to indicate whether user input events are being dispatched. +If object's class is a subclass of RectObj and +both \fIsensitive\fP and \fIancestor_sensitive\fP are +.PN True , +.PN XtIsSensitive +returns +.PN True ; +otherwise, it returns +.PN False . + +.NH 2 +Adding Background Work Procedures +.XS +\fB\*(SN Adding Background Work Procedures\fP +.XE +.LP +The \*(xI have some limited support for background processing. +Because most applications spend most of their time waiting for input, +you can register an idle-time work procedure +that is called when the toolkit would otherwise block in +.PN XtAppNextEvent +or +.PN XtAppProcessEvent . +Work procedure pointers are of type +.PN XtWorkProc . +.LP +.IN "XtWorkProc" "" "@DEF@" +.sM +.FD 0 +typedef Boolean (*XtWorkProc)(XtPointer); +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIclient_data\fP 1i +Passes the client data specified when the work procedure was registered. +.LP +.eM +This procedure should return +.PN True +when it is done to indicate that it +should be removed. +If the procedure returns +.PN False , +it will remain registered and called again when the +application is next idle. +Work procedures should be very judicious about how much they do. +If they run for more than a small part of a second, +interactive feel is likely to suffer. +.sp +.LP +To register a work procedure for a given application, use +.PN XtAppAddWorkProc . +.LP +.IN "XtAppAddWorkProc" "" "@DEF@" +.sM +.FD 0 +XtWorkProcId XtAppAddWorkProc(\fIapp_context\fP, \fIproc\fP, \fIclient_data\fP) +.br + XtAppContext \fIapp_context\fP; +.br + XtWorkProc \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context that identifies the application. +.IP \fIproc\fP 1i +Specifies the procedure to be called when the application is idle. +.IP \fIclient_data\fP 1i +Specifies the argument passed to the specified procedure +when it is called. +.LP +.eM +The +.PN XtAppAddWorkProc +function adds the specified work procedure for the application identified +by \fIapp_context\fP +and returns an opaque unique identifier for this work procedure. +Multiple work procedures can be registered, +and the most recently added one is always the one that is called. +However, if a work procedure adds another work procedure, +the newly added one has lower priority than the current one. +.sp +.LP +To remove a work procedure, either return +.PN True +from the procedure when it is called or use +.PN XtRemoveWorkProc +outside of the procedure. +.LP +.IN "XtRemoveWorkProc" "" "@DEF@" +.sM +.FD 0 +void XtRemoveWorkProc(\fIid\fP) +.br + XtWorkProcId \fIid\fP; +.FN +.IP \fIid\fP 1i +Specifies which work procedure to remove. +.LP +.eM +The +.PN XtRemoveWorkProc +function explicitly removes the specified background work procedure. + +.NH 2 +X Event Filters +.XS +\*(SN X Event Filters +.XE +.LP +The event manager provides filters that can be applied to +specific X events. +The filters, which screen out events that are redundant or are temporarily +unwanted, handle +pointer motion compression, +enter/leave compression, and +exposure compression. + +.NH 3 +Pointer Motion Compression +.XS +\*(SN Pointer Motion Compression +.XE +.LP +Widgets can have a hard time keeping up with a rapid stream of +pointer motion events. Furthermore, +they usually do not care about every motion event. To throw out +redundant motion events, the widget class field \fIcompress_motion\fP should be +.PN True . +.IN "compress_motion field" +When a request for an event would return a motion event, +the \*(xI check if there are any other motion events +for the same widget immediately +following the current one and, if so, skip all but the last of them. + +.NH 3 +Enter/Leave Compression +.XS +\*(SN Enter/Leave Compression +.XE +.LP +To throw out pairs of enter and leave events that have no intervening events, +as can happen when the user moves the pointer across a widget +without stopping in it, +the widget class field \fIcompress_enterleave\fP should be +.PN True . +.IN "compress_enterleave field" +These enter and leave events are not delivered to the client +if they are found together in the input queue. + +.NH 3 +Exposure Compression +.XS +\*(SN Exposure Compression +.XE +.LP +.IN "compress_expose field" +Many widgets prefer to process a series of exposure events as a +single expose region rather than as individual rectangles. Widgets +with complex displays might use the expose region as a clip list +in a graphics context, and widgets with simple displays might +ignore the region entirely and redisplay their whole window or +might get the bounding box from the region and redisplay only that +rectangle. +.LP +In either case, these widgets do not care about getting partial exposure events. +The \fIcompress_exposure\fP field in the widget class +structure specifies the type and number of exposure events that are +dispatched to the widget's expose procedure. This field must be +initialized to one of the following values: +.sp +.sM +.Ds 0 +.TA 3i +.ta 3i +#define XtExposeNoCompress ((XtEnum)False) +#define XtExposeCompressSeries ((XtEnum)True) +#define XtExposeCompressMultiple <implementation-defined> +#define XtExposeCompressMaximal <implementation-defined> +.De +.LP +.eM +optionally ORed with any combination of the following flags (all with +implementation-defined values): +.PN XtExposeGraphicsExpose , +.PN XtExposeGraphicsExposeMerged , +.PN XtExposeNoExpose , +and +.PN XtExposeNoRegion . + +.LP +If the \fIcompress_exposure\fP field in the widget class structure does not +specify +.PN XtExposeNoCompress , +the event manager calls the widget's expose procedure only +once for a series of exposure events. +In this case, all +.PN Expose +or +.PN GraphicsExpose +events are accumulated into a region. +When the final event is received, +the event manager replaces the rectangle in the event with the +bounding box for the region +and calls the widget's expose procedure, +passing the modified exposure event and (unless +.PN XtExposeNoRegion +is specified) the region. +For more information on regions, see Section 16.5 in \fI\*(xL\fP.) +.LP +The values have the following interpretation: +.sp +.LP +.PN XtExposeNoCompress +.IN "XtExposeNoCompress" "" "@DEF@" +.IP +No exposure compression is performed; every selected event is +individually dispatched to the expose procedure with a \fIregion\fP +argument of NULL. +.sp +.LP +.PN XtExposeCompressSeries +.IN "XtExposeCompressSeries" "" "@DEF@" +.IP +Each series of exposure events is coalesced into a single event, +which is dispatched +when an exposure event with count equal to zero is reached. +.sp +.LP +.PN XtExposeCompressMultiple +.IN "XtExposeCompressMultiple" "" "@DEF@" +.IP +Consecutive series of exposure events are coalesced into a single +event, which is dispatched +when an exposure event with count equal to zero is reached and either +the event queue is empty or the next event is not an exposure event +for the same widget. +.sp +.LP +.PN XtExposeCompressMaximal +.IN "XtExposeCompressMaximal" "" "@DEF" +.IP +All expose series currently in the queue for the widget +are coalesced into a single +event without regard to intervening nonexposure events. If a +partial series is in the end of the queue, the \*(xI will +block until the end of the series is received. +.sp +.LP +The additional flags have the following meaning: +.sp +.LP +.PN XtExposeGraphicsExpose +.IN "XtExposeGraphicsExpose" "" "@DEF@" +.IP +Specifies that +.PN GraphicsExpose +events are also to be dispatched to +the expose procedure. +.PN GraphicsExpose +events are compressed, if specified, in the same manner as +.PN Expose +events. +.sp +.LP +.PN XtExposeGraphicsExposeMerged +.IN "XtExposeGraphicsExposeMerged" "" "@DEF@" +.IP +Specifies in the case of +.PN XtExposeCompressMultiple +and +.PN XtExposeCompressMaximal +that series of +.PN GraphicsExpose +and +.PN Expose +events are to be compressed together, with the final event type +determining the type of the event passed to the expose procedure. +If this flag is not set, then only series of the same event type +as the event at the head of the queue are coalesced. This flag +also implies +.PN XtExposeGraphicsExpose . +.sp +.LP +.PN XtExposeNoExpose +.IN "XtExposeNoExpose" "" "@DEF@" +.IP +Specifies that +.PN NoExpose +events are also to be dispatched to the expose procedure. +.PN NoExpose +events are never coalesced with +other exposure events or with each other. +.sp +.LP +.PN XtExposeNoRegion +.IN "XtExposeNoRegion" "" "@DEF" +.IP +Specifies that the final region argument passed to the expose +procedure is NULL. The rectangle in the event will still +contain bounding box information for the entire series of +compressed exposure events. This option saves processing time when the +region is not needed by the widget. + +.NH 2 +Widget Exposure and Visibility +.XS +\*(SN Widget Exposure and Visibility +.XE +.LP +Every primitive widget and some composite widgets display data on the screen +by means of direct Xlib calls. +Widgets cannot simply write to the screen and forget what they have done. +They must keep enough state to redisplay the window or parts +of it if a portion is obscured and then reexposed. + +.NH 3 +Redisplay of a Widget: The expose Procedure +.XS +\*(SN Redisplay of a Widget: The expose Procedure +.XE +.IN "expose procedure" +.LP +The expose procedure pointer in a widget class is of type +.PN XtExposeProc . +.LP +.IN "XtExposeProc" "" "@DEF@" +.sM +.FD 0 +typedef void (*XtExposeProc)(Widget, XEvent*, Region); +.br + Widget \fIw\fP; +.br + XEvent *\fIevent\fP; +.br + Region \fIregion\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget instance requiring redisplay. +.IP \fIevent\fP 1i +Specifies the exposure event giving the rectangle requiring redisplay. +.IP \fIregion\fP 1i +Specifies the union of all rectangles in this exposure sequence. +.LP +.eM +The redisplay of a widget upon exposure is the responsibility of the +expose procedure in the widget's class record. +If a widget has no display semantics, +it can specify NULL for the \fIexpose\fP field. +Many composite widgets serve only as containers for their children +and have no expose procedure. +.NT +If the \fIexpose\fP procedure is NULL, +.PN XtRealizeWidget +fills in a default bit gravity of +.PN NorthWestGravity +before it calls the widget's realize procedure. +.NE +.LP +If the widget's \fIcompress_exposure\fP class field specifies +.PN XtExposeNoCompress +or +.PN XtExposeNoRegion , +or if the event type is +.PN NoExpose +(see Section 7.9.3), +\fIregion\fP is NULL. If +.PN XtExposeNoCompress +is not specified and the event type is not +.PN NoExpose , +the event is the final event in the compressed series +but \fIx\fP, \fIy\fP, \fIwidth\fP, and \fIheight\fP contain +the bounding box for all the compressed events. +The region is created and destroyed by the \*(xI, but +the widget is permitted to modify the region contents. +.LP +A small simple widget (for example, Label) can ignore the bounding box +information in the event and redisplay the entire window. +A more complicated widget (for example, Text) can use the bounding box +information to minimize the amount of calculation and redisplay it does. +A very complex widget uses the region as a clip list in a GC and +ignores the event information. +The expose procedure is not chained and is therefore +responsible for exposure of all superclass data +as well as its own. +.LP +However, +it often is possible to anticipate the display needs of several levels +of subclassing. +For example, rather than implement separate display procedures for +the widgets Label, Pushbutton, and Toggle, +you could write a single display routine in Label that uses display state +fields like +.LP +.DS +Boolean invert; +Boolean highlight; +Dimension highlight_width; +.DE +Label would have \fIinvert\fP and \fIhighlight\fP always +.PN False +and \fIhighlight_width\fP zero. +Pushbutton would dynamically set \fIhighlight\fP and \fIhighlight_width\fP, +but it would leave \fIinvert\fP always +.PN False . +Finally, Toggle would dynamically set all three. +In this case, +the expose procedures for Pushbutton and Toggle inherit +their superclass's expose procedure; +see Section 1.6.10. + +.NH 3 +Widget Visibility +.XS +\*(SN Widget Visibility +.XE +.LP +Some widgets may use substantial computing resources to produce the +data they will display. +However, this effort is wasted if the widget is not actually visible +on the screen, that is, if the widget is obscured by another application +or is iconified. +.LP +.IN "Visibility" +The \fIvisible\fP field in the +core +widget structure provides a hint to the widget that it need not compute +display data. +This field is guaranteed to be +.PN True +by the time an +exposure +event is processed if any part of the widget is visible, +but is +.PN False +if the widget is fully obscured. +.LP +Widgets can use or ignore the \fIvisible\fP hint. +If they ignore it, +they should have \fIvisible_interest\fP in their widget class record set +.PN False . +In such cases, +the \fIvisible\fP field is initialized +.PN True +and never changes. +If \fIvisible_interest\fP is +.PN True , +the event manager asks for +.PN VisibilityNotify +events for the widget and sets \fIvisible\fP to +.PN True +on +.PN VisibilityUnobscured +or +.PN VisibilityPartiallyObscured +.IN VisibilityNotify +events and +.PN False +on +.PN VisibilityFullyObscured +events. + +.NH 2 +X Event Handlers +.XS +\*(SN X Event Handlers +.XE +.LP +Event handlers are procedures called when specified events +occur in a widget. +Most widgets need not use event handlers explicitly. +Instead, they use the \*(xI translation manager. +Event handler procedure pointers are of the type +.PN XtEventHandler . +.LP +.IN "XtEventHandler" "" "@DEF@" +.sM +.FD 0 +typedef void (*XtEventHandler)(Widget, XtPointer, XEvent*, Boolean*); +.br + Widget \fIw\fP; +.br + XtPointer \fIclient_data\fP; +.br + XEvent *\fIevent\fP; +.br + Boolean *\fIcontinue_to_dispatch\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget for which the event arrived. +.IP \fIclient_data\fP 1i +Specifies any client-specific information registered with the event handler. +.IP \fIevent\fP 1i +Specifies the triggering event. +.IP \fIcontinue_to_dispatch\fP 1i +Specifies whether the remaining event +handlers registered for the current event +should be called. +.LP +.eM +After receiving an event and before calling any event handlers, the +Boolean pointed to by \fIcontinue_to_dispatch\fP is initialized to +.PN True . +When an event handler is called, it may decide that further processing +of the event is not desirable and may store +.PN False +in this Boolean, in +which case any handlers remaining to be called for the event are +ignored. +.LP +The circumstances under which the \*(xI may add event handlers +to a widget are currently implementation-dependent. Clients must +therefore be aware that storing +.PN False +into the \fIcontinue_to_dispatch\fP argument can lead to portability problems. + +.NH 3 +Event Handlers That Select Events +.XS +\*(SN Event Handlers That Select Events +.XE +.LP +To register an event handler procedure with the dispatch mechanism, use +.PN XtAddEventHandler . +.LP +.IN "XtAddEventHandler" "" "@DEF@" +.sM +.FD 0 +void XtAddEventHandler(\fIw\fP, \fIevent_mask\fP, \fInonmaskable\fP, \ +\fIproc\fP, \fIclient_data\fP) +.br + Widget \fIw\fP; +.br + EventMask \fIevent_mask\fP; +.br + Boolean \fInonmaskable\fP; +.br + XtEventHandler \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget for which this event handler is being registered. \*(cI +.IP \fIevent_mask\fP 1i +Specifies the event mask for which to call this procedure. +.IP \fInonmaskable\fP 1i +Specifies whether this procedure should be +called on the nonmaskable events +.Pn ( GraphicsExpose , +.PN NoExpose , +.PN SelectionClear , +.PN SelectionRequest , +.PN SelectionNotify , +.PN ClientMessage , +and +.PN MappingNotify ). +.IP \fIproc\fP 1i +Specifies the procedure to be called. +.IP \fIclient_data\fP 1i +Specifies additional data to be passed to the event handler. +.LP +.eM +The +.PN XtAddEventHandler +function registers a procedure with the dispatch mechanism that is +to be called when an event that matches the mask occurs on the specified +widget. +Each widget has a single registered event handler list, which will +contain any procedure/client_data pair exactly once regardless of +the manner in which it is registered. +If the procedure is already registered with the same \fIclient_data\fP +value, +the specified mask augments the existing mask. +If the widget is realized, +.PN XtAddEventHandler +calls +.PN XSelectInput , +if necessary. +The order in which this procedure is called relative to other handlers +registered for the same event is not defined. +.sp +.LP +To remove a previously registered event handler, use +.PN XtRemoveEventHandler . +.LP +.IN "XtRemoveEventHandler" "" "@DEF@" +.sM +.FD 0 +void XtRemoveEventHandler(\fIw\fP, \fIevent_mask\fP, \fInonmaskable\fP, \ +\fIproc\fP, \fIclient_data\fP) +.br + Widget \fIw\fP; +.br + EventMask \fIevent_mask\fP; +.br + Boolean \fInonmaskable\fP; +.br + XtEventHandler \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget for which this procedure is registered. \*(cI +.IP \fIevent_mask\fP 1i +Specifies the event mask for which to unregister this procedure. +.IP \fInonmaskable\fP 1i +Specifies whether this procedure should be +removed on the nonmaskable events +.Pn ( GraphicsExpose , +.PN NoExpose , +.PN SelectionClear , +.PN SelectionRequest , +.PN SelectionNotify , +.PN ClientMessage , +and +.PN MappingNotify ). +.IP \fIproc\fP 1i +Specifies the procedure to be removed. +.IP \fIclient_data\fP 1i +Specifies the registered client data. +.LP +.eM +The +.PN XtRemoveEventHandler +function unregisters an event handler registered with +.PN XtAddEventHandler +or +.PN XtInsertEventHandler +for the specified events. +The request is ignored if \fIclient_data\fP does not match the value given +when the handler was registered. +If the widget is realized and no other event handler requires the event, +.PN XtRemoveEventHandler +calls +.PN XSelectInput . +If the specified procedure has not been registered +or if it has been registered with a different value of \fIclient_data\fP, +.PN XtRemoveEventHandler +returns without reporting an error. +.LP +To stop a procedure registered with +.PN XtAddEventHandler +or +.PN XtInsertEventHandler +from receiving all selected events, call +.PN XtRemoveEventHandler +with an \fIevent_mask\fP of +.PN XtAllEvents +and \fInonmaskable\fP +.PN True . +The procedure will continue to receive any events +that have been specified in calls to +.PN XtAddRawEventHandler +or +.PN XtInsertRawEventHandler . +.sp +.LP +To register an event handler procedure that receives events before or +after all previously registered event handlers, use +.PN XtInsertEventHandler . +.LP +.IN "XtListPosition" "" "@DEF@" +.IN "XtInsertEventHandler" "" "@DEF@" +.sM +.Ds 0 +typedef enum {XtListHead, XtListTail} XtListPosition; +.De +.LP +.FD 0 +void XtInsertEventHandler(\fIw\fP, \fIevent_mask\fP, \fInonmaskable\fP, \ +\fIproc\fP, \fIclient_data\fP, \fIposition\fP) +.br + Widget \fIw\fP; +.br + EventMask \fIevent_mask\fP; +.br + Boolean \fInonmaskable\fP; +.br + XtEventHandler \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.br + XtListPosition \fIposition\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget for which this event handler is being registered. \*(cI +.IP \fIevent_mask\fP 1i +Specifies the event mask for which to call this procedure. +.IP \fInonmaskable\fP 1i +Specifies whether this procedure should be +called on the nonmaskable events +.Pn ( GraphicsExpose , +.PN NoExpose , +.PN SelectionClear , +.PN SelectionRequest , +.PN SelectionNotify , +.PN ClientMessage , +and +.PN MappingNotify ). +.IP \fIproc\fP 1i +Specifies the procedure to be called. +.IP \fIclient_data\fP 1i +Specifies additional data to be passed to the client's event handler. +.IP \fIposition\fP 1i +Specifies when the event handler is to be called +relative to other previously registered handlers. +.LP +.eM +.PN XtInsertEventHandler +is identical to +.PN XtAddEventHandler +with the additional \fIposition\fP argument. If \fIposition\fP is +.PN XtListHead , +the event +handler is registered so that it is called before any event +handlers that were previously registered for the same widget. If +\fIposition\fP is +.PN XtListTail , +the event handler is registered to be called +after any previously registered event handlers. If the procedure is +already registered with the same \fIclient_data\fP value, the specified mask +augments the existing mask and the procedure is repositioned in +the list. + +.NH 3 +Event Handlers That Do Not Select Events +.XS +\*(SN Event Handlers That Do Not Select Events +.XE +.LP +On occasion, +clients need to register an event handler procedure with the +dispatch mechanism without explicitly +causing the X server to select for that event. +To do this, use +.PN XtAddRawEventHandler . +.LP +.IN "XtAddRawEventHandler" "" "@DEF@" +.sM +.FD 0 +void XtAddRawEventHandler(\fIw\fP, \fIevent_mask\fP, \fInonmaskable\fP, \ +\fIproc\fP, \fIclient_data\fP) +.br + Widget \fIw\fP; +.br + EventMask \fIevent_mask\fP; +.br + Boolean \fInonmaskable\fP; +.br + XtEventHandler \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget for which this event handler is being registered. \*(cI +.IP \fIevent_mask\fP 1i +Specifies the event mask for which to call this procedure. +.IP \fInonmaskable\fP 1i +Specifies whether this procedure should be +called on the nonmaskable events +.Pn ( GraphicsExpose , +.PN NoExpose , +.PN SelectionClear , +.PN SelectionRequest , +.PN SelectionNotify , +.PN ClientMessage , +and +.PN MappingNotify ). +.IP \fIproc\fP 1i +Specifies the procedure to be called. +.IP \fIclient_data\fP 1i +Specifies additional data to be passed to the client's event handler. +.LP +.eM +The +.PN XtAddRawEventHandler +function is similar to +.PN XtAddEventHandler +except that it does not affect the widget's event mask and never causes an +.PN XSelectInput +for its events. +Note that the widget might already have those mask bits set +because of other nonraw event handlers registered on it. +If the procedure is already registered with the same \fIclient_data\fP, +the specified mask augments the existing mask. +The order in which this procedure is called relative to other handlers +registered for the same event is not defined. +.sp +.LP +To remove a previously registered raw event handler, use +.PN XtRemoveRawEventHandler . +.LP +.IN "XtRemoveRawEventHandler" "" "@DEF@" +.sM +.FD 0 +void XtRemoveRawEventHandler(\fIw\fP, \fIevent_mask\fP, \fInonmaskable\fP, \ +\fIproc\fP, \fIclient_data\fP) +.br + Widget \fIw\fP; +.br + EventMask \fIevent_mask\fP; +.br + Boolean \fInonmaskable\fP; +.br + XtEventHandler \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget for which this procedure is registered. \*(cI +.IP \fIevent_mask\fP 1i +Specifies the event mask for which to unregister this procedure. +.IP \fInonmaskable\fP 1i +Specifies whether this procedure should be +removed on the nonmaskable events +.Pn ( GraphicsExpose , +.PN NoExpose , +.PN SelectionClear , +.PN SelectionRequest , +.PN SelectionNotify , +.PN ClientMessage , +and +.PN MappingNotify ). +.IP \fIproc\fP 1i +Specifies the procedure to be registered. +.IP \fIclient_data\fP 1i +Specifies the registered client data. +.LP +.eM +The +.PN XtRemoveRawEventHandler +function unregisters an event handler registered with +.PN XtAddRawEventHandler +or +.PN XtInsertRawEventHandler +for the specified events without changing +the window event mask. +The request is ignored if \fIclient_data\fP does not match the value given +when the handler was registered. +If the specified procedure has not been registered +or if it has been registered with a different value of \fIclient_data\fP, +.PN XtRemoveRawEventHandler +returns without reporting an error. +.LP +To stop a procedure +registered with +.PN XtAddRawEventHandler +or +.PN XtInsertRawEventHandler +from receiving all nonselected events, call +.PN XtRemoveRawEventHandler +with an \fIevent_mask\fP of +.PN XtAllEvents +and \fInonmaskable\fP +.PN True . +The procedure +will continue to receive any events that have been specified in calls to +.PN XtAddEventHandler +or +.PN XtInsertEventHandler . +.sp +.LP +To register an event handler procedure that receives events before or +after all previously registered event handlers without selecting for +the events, use +.PN XtInsertRawEventHandler . +.LP +.IN "XtInsertRawEventHandler" "" "@DEF@" +.sM +.FD 0 +void XtInsertRawEventHandler(\fIw\fP, \fIevent_mask\fP, \fInonmaskable\fP, \ +\fIproc\fP, \fIclient_data\fP, \fIposition\fP) +.br + Widget \fIw\fP; +.br + EventMask \fIevent_mask\fP; +.br + Boolean \fInonmaskable\fP; +.br + XtEventHandler \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.br + XtListPosition \fIposition\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget for which this event handler is being registered. \*(cI +.IP \fIevent_mask\fP 1i +Specifies the event mask for which to call this procedure. +.IP \fInonmaskable\fP 1i +Specifies whether this procedure should be +called on the nonmaskable events +.Pn ( GraphicsExpose , +.PN NoExpose , +.PN SelectionClear , +.PN SelectionRequest , +.PN SelectionNotify , +.PN ClientMessage , +and +.PN MappingNotify ). +.IP \fIproc\fP 1i +Specifies the procedure to be registered. +.IP \fIclient_data\fP 1i +Specifies additional data to be passed to the client's event handler. +.IP \fIposition\fP 1i +Specifies when the event handler is to be called +relative to other previously registered handlers. +.LP +.eM +The +.PN XtInsertRawEventHandler +function is similar to +.PN XtInsertEventHandler +except that it does not modify the widget's event +mask and never causes an +.PN XSelectInput +for the specified events. If +the procedure is already registered with the same \fIclient_data\fP +value, the +specified mask augments the existing mask and the procedure is +repositioned in the list. + +.NH 3 +Current Event Mask +.XS +\*(SN Current Event Mask +.XE +.LP +To retrieve the event mask for a given widget, use +.PN XtBuildEventMask . +.LP +.IN "XtBuildEventMask" "" "@DEF@" +.sM +.FD 0 +EventMask XtBuildEventMask(\fIw\fP) +.br + Widget \fIw\fP; +.FN +.IP \fIw\fP 1i +Specifies the widget. \*(cI +.LP +.eM +The +.PN XtBuildEventMask +function returns the event mask representing the logical OR +of all event masks for event handlers registered on the widget with +.PN XtAddEventHandler +and +.PN XtInsertEventHandler +and all event translations, including accelerators, +installed on the widget. +This is the same event mask stored into the +.PN XSetWindowAttributes +structure by +.PN XtRealizeWidget +and sent to the server when event handlers and translations are installed or +removed on the realized widget. + +.NH 3 +Event Handlers for X11 Protocol Extensions +.XS +\fB\*(SN Event Handlers for X11 Protocol Extensions\fP +.XE +.LP +To register an event handler procedure with the \*(xI dispatch +mechanism according to an event type, use +.PN XtInsertEventTypeHandler . +.LP +.IN "XtInsertEventTypeHandler" "" "@DEF" +.sM +.FD 0 +void XtInsertEventTypeHandler(\fIwidget\fP, \fIevent_type\fP, \ +\fIselect_data\fP, \fIproc\fP, \fIclient_data\fP, \fIposition\fP) +.br + Widget \fIwidget\fP; +.br + int \fIevent_type\fP; +.br + XtPointer \fIselect_data\fP; +.br + XtEventHandler \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.br + XtListPosition \fIposition\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget for which this event handler is being registered. \*(cI +.IP \fIevent_type\fP 1i +Specifies the event type for which to call this event handler. +.IP \fIselect_data\fP 1i +Specifies data used to request events of the specified type from the server, +or NULL. +.IP \fIproc\fP 1i +Specifies the event handler to be called. +.IP \fIclient_data\fP 1i +Specifies additional data to be passed to the event handler. +.IP \fIposition\fP 1i +Specifies when the event handler is to be called relative to other +previously registered handlers. +.LP +.eM +.PN XtInsertEventTypeHandler +registers a procedure with the +dispatch mechanism that is to be called when an event that matches the +specified \fIevent_type\fP is dispatched to the specified \fIwidget\fP. +.LP +If \fIevent_type\fP specifies one of the core X protocol events, then +\fIselect_data\fP must be a pointer to a value of type +.PN EventMask , +indicating +the event mask to be used to select for the desired event. This event +mask is included in the value returned by +.PN XtBuildEventMask . +If the widget is realized, +.PN XtInsertEventTypeHandler +calls +.PN XSelectInput +if necessary. Specifying NULL for \fIselect_data\fP is equivalent to +specifying a pointer to an event mask containing 0. This is similar +to the +.PN XtInsertRawEventHandler +function. +.LP +If \fIevent_type\fP specifies an extension event type, then the semantics of +the data pointed to by \fIselect_data\fP are defined by the extension +selector registered for the specified event type. +.LP +In either case the \*(xI are not required to copy the data +pointed to by \fIselect_data\fP, so the caller must ensure that it remains +valid as long as the event handler remains registered with this value +of \fIselect_data\fP. +.LP +The \fIposition\fP argument allows the client to control the order of +invocation of event handlers registered for the same event type. If +the client does not care about the order, it should normally specify +.PN XtListTail , +which registers this event handler after any previously +registered handlers for this event type. +.LP +Each widget has a single registered event handler list, which will +contain any procedure/client_data pair exactly once if it is +registered with +.PN XtInsertEventTypeHandler , +regardless of the manner +in which it is registered and regardless of the value(s) +of \fIselect_data\fP. If the procedure is already registered with the +same \fIclient_data\fP value, the specified mask augments the existing +mask and the procedure is repositioned in the list. +.sp +.LP +To remove an event handler registered with +.PN XtInsertEventTypeHandler , +use +.PN XtRemoveEventTypeHandler . +.LP +.IN "XtRemoveEventTypeHandler" "" "@DEF" +.sM +.FD 0 +void XtRemoveEventTypeHandler(\fIwidget\fP, \fIevent_type\fP, \ +\fIselect_data\fP, \fIproc\fP, \fIclient_data\fP) +.br + Widget \fIwidget\fP; +.br + int \fIevent_type\fP; +.br + XtPointer \fIselect_data\fP; +.br + XtEventHandler \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget for which the event handler was registered. \*(cI +.IP \fIevent_type\fP 1i +Specifies the event type for which the handler was registered. +.IP \fIselect_data\fP 1i +Specifies data used to deselect events of the specified type +from the server, or NULL. +.IP \fIproc\fP 1i +Specifies the event handler to be removed. +.IP \fIclient_data\fP 1i +Specifies the additional client data with which the procedure was registered. +.LP +.eM +The +.PN XtRemoveEventTypeHandler +function unregisters an event handler +registered with +.PN XtInsertEventTypeHandler +for the specified event type. +The request is ignored if \fIclient_data\fP does not match the value given +when the handler was registered. +.LP +If \fIevent_type\fP specifies one of the core X protocol events, +\fIselect_data\fP must be a pointer to a value of type +.PN EventMask, indicating the event +mask to be used to deselect for the appropriate event. If the widget +is realized, +.PN XtRemoveEventTypeHandler +calls +.PN XSelectInput +if necessary. +Specifying NULL for \fIselect_data\fP is equivalent to specifying a pointer +to an event mask containing 0. This is similar to the +.PN XtRemoveRawEventHandler +function. +.LP +If \fIevent_type\fP specifies an extension event type, then the semantics of +the data pointed to by \fIselect_data\fP are defined by the extension +selector registered for the specified event type. +.sp +.LP +To register a procedure to select extension events for a widget, use +.PN XtRegisterExtensionSelector . +.LP +.IN "XtRegisterExtensionSelector" "" "@DEF@" +.sM +.FD 0 +void XtRegisterExtensionSelector(\fIdisplay\fP, \fImin_event_type\fP, \ +\fImax_event_type\fP, \fIproc\fP, + \fIclient_data\fP) +.br + Display \fI*display\fP; +.br + int \fImin_event_type\fP; +.br + int \fImax_event_type\fP; +.br + XtExtensionSelectProc \fIproc\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIdisplay\fP 1.5i +Specifies the display for which the extension selector is to be registered. +.IP \fImin_event_type\fP +.IP \fImax_event_type\fP 1.5i +Specifies the range of event types for the extension. +.IP \fIproc\fP 1.5i +Specifies the extension selector procedure. +.IP \fIclient_data\fP 1.5i +Specifies additional data to be passed to the extension selector. +.LP +.eM +The +.PN XtRegisterExtensionSelector +function registers a procedure to arrange +for the delivery of extension events to widgets. +.LP +If \fImin_event_type\fP and \fImax_event_type\fP match the parameters +to a previous call to +.PN XtRegisterExtensionSelector +for the same \fIdisplay\fP, then \fIproc\fP and \fIclient_data\fP +replace the previously +registered values. If the range specified by \fImin_event_type\fP +and \fImax_event_type\fP overlaps the range of the parameters to a +previous call for the same display in any other way, an error results. +.LP +When a widget is realized, +after the \fIcore.realize\fP method is called, +the \*(xI check to see if any event +handler specifies an event type within the range of a registered +extension selector. If so, the \*(xI call each such selector. +If an event type handler is added or removed, the \*(xI check to +see if the event type falls within the range of a registered extension +selector, and if it does, calls the selector. In either case the \*(xI +pass a list of all the widget's event types that are within the +selector's range. The corresponding select data are also passed. The +selector is responsible for enabling the delivery of extension events +required by the widget. +.sp +.LP +An extension selector is of type +.PN XtExtensionSelectProc . +.LP +.IN "XtExtensionSelectProc" "" "@DEF" +.sM +.FD 0 +typedef void (*XtExtensionSelectProc)(Widget, int *, XtPointer *, int, \ +XtPointer); +.br + Widget \fIwidget\fP; +.br + int *\fIevent_types\fP; +.br + XtPointer *\fIselect_data\fP; +.br + int \fIcount\fP; +.br + XtPointer \fIclient_data\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget that is being realized or is having +an event handler added or removed. +.IP \fIevent_types\fP 1i +Specifies a list of event types that the widget has +registered event handlers for. +.IP \fIselect_data\fP 1i +Specifies a list of the select_data parameters specified in +.PN XtInsertEventTypeHandler . +.IP \fIcount\fP 1i +Specifies the number of entries in the \fIevent_types\fP and \fIselect_data\fP +lists. +.IP \fIclient_data\fP 1i +Specifies the additional client data with which the procedure was registered. +.LP +.eM +The \fIevent_types\fP and \fIselect_data\fP lists will always have the +same number of elements, specified by \fIcount\fP. +Each event type/select data pair represents one call to +.PN XtInsertEventTypeHandler . +.sp +.LP +To register a procedure to dispatch events of a specific type within +.PN XtDispatchEvent , +use +.PN XtSetEventDispatcher . +.LP +.IN "XtSetEventDispatcher" "" "@DEF@" +.sM +.FD 0 +XtEventDispatchProc XtSetEventDispatcher(\fIdisplay\fP, \fIevent_type\fP, \ +\fIproc\fP) +.br + Display *\fIdisplay\fP; +.br + int \fIevent_type\fP; +.br + XtEventDispatchProc \fIproc\fP; +.FN +.IP \fIdisplay\fP 1i +Specifies the display for which the event dispatcher is to be registered. +.IP \fIevent_type\fP 1i +Specifies the event type for which the dispatcher should be invoked. +.IP \fIproc\fP 1i +Specifies the event dispatcher procedure. +.LP +.eM +The +.PN XtSetEventDispatcher +function registers the event dispatcher procedure specified by \fIproc\fP +for events with the type \fIevent_type\fP. The previously registered +dispatcher (or the default dispatcher if there was no previously registered +dispatcher) is returned. If \fIproc\fP is NULL, the default procedure is +restored for the specified type. +.LP +In the future, when +.PN XtDispatchEvent +is called with an event type of \fIevent_type\fP, the specified \fIproc\fP +(or the default dispatcher) is invoked to determine a widget +to which to dispatch the event. +.LP +The default dispatcher handles the \*(xI modal cascade and keyboard +focus mechanisms, handles the semantics of \fIcompress_enterleave\fP +and \fIcompress_motion\fP, and discards all extension events. +.sp +.LP +An event dispatcher procedure pointer is of type +.PN XtEventDispatchProc . +.LP +.IN "XtEventDispatchProc" "" "@DEF@" +.sM +.FD 0 +typedef Boolean (*XtEventDispatchProc)(XEvent*) +.br + XEvent *\fIevent\fP; +.FN +.IP \fIevent\fP 1i +Passes the event to be dispatched. +.LP +.eM +The event dispatcher procedure should determine whether this event is of +a type that should be dispatched to a widget. +.LP +If the event should be dispatched to a widget, the event dispatcher +procedure should determine the appropriate widget to receive the +event, call +.PN XFilterEvent +with the window of this widget, or +.PN None +if the event is to be discarded, and if +.PN XFilterEvent +returns +.PN False , +dispatch the event to the widget using +.PN XtDispatchEventToWidget . +The procedure should return +.PN True +if either +.PN XFilterEvent +or +.PN XtDispatchEventToWidget +returned +.PN True +and +.PN False +otherwise. +.LP +If the event should not be dispatched to a widget, the event +dispatcher procedure should attempt to dispatch the event elsewhere as +appropriate and return +.PN True +if it successfully dispatched the event and +.PN False +otherwise. +.sp +.LP +Some dispatchers for extension events may wish to forward events +according to the Intrinsics' keyboard focus mechanism. To determine +which widget is the end result of keyboard event forwarding, use +.PN XtGetKeyboardFocusWidget . +.LP +.IN "XtGetKeyboardFocusWidget" "" "@DEF@" +.sM +.FD 0 +Widget XtGetKeyboardFocusWidget(\fIwidget\fP) +.br + Widget \fIwidget\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget to get forwarding information for. +.LP +.eM +The +.PN XtGetKeyboardFocusWidget +function returns the widget that would be the end result of keyboard +event forwarding for a keyboard event for the specified widget. +.sp +.LP +To dispatch an event to a specified widget, use +.PN XtDispatchEventToWidget . +.LP +.IN "XtDispatchEventToWidget" "" "@DEF@" +.sM +.FD 0 +Boolean XtDispatchEventToWidget(\fIwidget\fP, \fIevent\fP) +.br + Widget \fIwidget\fP; +.br + XEvent *\fIevent\fP; +.FN +.IP \fIwidget\fP 1i +Specifies the widget to which to dispatch the event. +.IP \fIevent\fP 1i +Specifies a pointer to the event to be dispatched. +.LP +.eM +The +.PN XtDispatchEventToWidget +function scans the list of registered event handlers for the +specified widget and calls each handler that has been registered +for the specified event type, subject to the \fIcontinue_to_dispatch\fP +value returned by each handler. +The \*(xI behave as if event handlers were registered at the head +of the list for +.PN Expose , +.PN NoExpose , +.PN GraphicsExpose , +and +.PN VisibilityNotify +events to invoke the widget's expose procedure according to the exposure +compression rules and to update the widget's \fIvisible\fP field +if \fIvisible_interest\fP is +.PN True . +These internal event handlers never set \fIcontinue_to_dispatch\fP to +.PN False . +.LP +.PN XtDispatchEventToWidget +returns +.PN True +if any event handler was called and +.PN False +otherwise. + +.NH 2 +Using the \*(xI in a Multi-Threaded Environment +.XS +\*(SN Using the \*(xI in a Multi-Threaded Environment +.XE +.LP +The \*(xI may be used in environments that offer multiple threads +of execution within the context of a single process. A multi-threaded +application using the \*(xI must explicitly initialize the toolkit +for mutually exclusive access by calling +.PN XtToolkitThreadInitialize . + +.NH 3 +Initializing a Multi-Threaded \*(xI Application +.XS +\fB\*(SN Initializing a Multi-Threaded \*(xI Application\fP +.XE +.LP +To test and initialize \*(xI support for mutually exclusive thread +access, call +.PN XtToolkitThreadInitialize . +.LP +.IN "XtToolkitThreadInitialize" "" "@DEF@" +.sM +.FD 0 +Boolean XtToolkitThreadInitialize() +.FN +.LP +.eM +.PN XtToolkitThreadInitialize +returns \fBTrue\fP if the \*(xI support mutually exclusive thread +access, otherwise it returns \fBFalse\fP. \fBXtToolkitThreadInitialize\fP +must be called before +.PN XtCreateApplicationContext , +.PN XtAppInitialize , +.PN XtOpenApplication , +or +.PN XtSetLanguageProc +is called. \fBXtToolkitThreadInitialize\fP may be called more than once; +however, the application writer must ensure that it is not called +simultaneously by two or more threads. + +.NH 3 +Locking \*(tk Data Structures +.XS +\fB\*(SN Locking \*(tk Data Structures\fP +.XE +.LP +The \*(xI employs two levels of locking: application context and +process. Locking an application context ensures mutually exclusive +access by a thread to the state associated with the application context, +including all displays and widgets associated with it. Locking a +process ensures mutually exclusive access by a thread to \*(xI process +global data. +.LP +A client may acquire a lock multiple times and the effect is cumulative. +The client must ensure that the lock is released an equal number of times in +order for the lock to be acquired by another thread. +.LP +Most application writers will have little need to use locking as the +\*(xI performs the necessary locking internally. +Resource converters are an exception. +They require the application context or process to be locked +before the application can safely call them directly, for example: +.LP +.KS +.Ds +.TA .5i 2i +.ta .5i 2i + ... + XtAppLock(app_context); + XtCvtStringToPixel(dpy, args, num_args, fromVal, toVal, closure_ret); + XtAppUnlock(app_context); + ... +.De +.KE +.LP +When the application relies upon +.PN XtConvertAndStore +or a converter to provide the storage for the results of a +conversion, the application should acquire the process lock before +calling out and hold the lock until the results have been copied. +.LP +Application writers who write their own +utility functions, such as one which retrieves the being_destroyed field from +a widget instance, must lock the application context before accessing +widget internal data. For example: +.LP +.KS +.Ds +.TA .5i 2i +.ta .5i 2i +#include <X11/CoreP.h> +Boolean BeingDestroyed (widget) + Widget widget; +{ + Boolean ret; + XtAppLock(XtWidgetToApplicationContext(widget)); + ret = widget->core.being_destroyed; + XtAppUnlock(XtWidgetToApplicationContext(widget)); + return ret; +} +.De +.KE +A client that wishes to atomically call two or more \*(xI functions +must lock the application context. For example: +.LP +.KS +.Ds +.TA .5i 2i +.ta .5i 2i + ... + XtAppLock(XtWidgetToApplicationContext(widget)); + XtUnmanageChild (widget1); + XtManageChild (widget2); + XtAppUnlock(XtWidgetToApplicationContext(widget)); + ... +.De +.KE + +.NH 4 +Locking the Application Context +.XS +\fB\*(SN Locking the Application Context\fP +.XE +.LP +To ensure mutual exclusion of application context, display, or +widget internal state, use +.PN XtAppLock. +.LP +.IN "XtAppLock" "" "@DEF@" +.sM +.FD 0 +void XtAppLock(\fIapp_context\fP) +.br + XtAppContext \fIapp_context\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context to lock. +.LP +.eM +\fBXtAppLock\fP blocks until it is able to acquire the lock. Locking the +application context also ensures that only the thread holding the lock +makes Xlib calls from within Xt. An application that makes its own +direct Xlib calls must either lock the application context around every +call or enable thread locking in Xlib. +.LP +To unlock a locked application context, use +.PN XtAppUnlock. +.LP +.IN "XtAppUnlock" "" "@DEF@" +.sM +.FD 0 +void XtAppUnlock(\fIapp_context\fP) +.br + XtAppContext \fIapp_context\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context that was previously locked. +.LP +.eM + +.NH 4 +Locking the Process +.XS +\*(SN Locking the Process +.XE +.LP +To ensure mutual exclusion of \*(tk process global data, a +widget writer must use +.PN XtProcessLock. +.LP +.IN "XtProcessLock" "" "@DEF@" +.sM +.FD 0 +void XtProcessLock() +.FN +.LP +.eM +\fBXtProcessLock\fP blocks until it is able to acquire the lock. +Widget writers may use XtProcessLock to guarantee mutually exclusive +access to widget static data. +.LP +To unlock a locked process, use +.PN XtProcessUnlock . +.LP +.IN "XtProcessUnlock" "" "@DEF@" +.sM +.FD 0 +void XtProcessUnlock() +.FN +.LP +.eM +To lock both an application context and the process at the same +time, call +.PN XtAppLock +first and then +.PN XtProcessLock . +To release both locks, call +.PN XtProcessUnlock +first and then +.PN XtAppUnlock . +The order is important to avoid deadlock. + +.NH 3 +Event Management in a Multi-Threaded Environment +.XS +\fB\*(SN Event Management in a Multi-Threaded Environment\fP +.XE +.LP +In a nonthreaded environment an application writer could reasonably +assume that it is safe to exit the application from a quit callback. +This assumption may no longer hold true in a multi-threaded environment; +therefore it is desirable to provide a mechanism to terminate an +event-processing loop without necessarily terminating its thread. +.LP +To indicate that the event loop should terminate after the current +event dispatch has completed, use +.PN XtAppSetExitFlag . +.LP +.IN "XtAppSetExitFlag" "" "@DEF@" +.sM +.FD 0 +void XtAppSetExitFlag(\fIapp_context\fP) +.br + XtAppContext \fIapp_context\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context. +.LP +.eM +.PN XtAppMainLoop +tests the value of the flag and will return if the flag is \fBTrue\fP. +.LP +Application writers who implement their own main loop may test the +value of the exit flag with +.PN XtAppGetExitFlag . +.LP +.IN "XtAppGetExitFlag" "" "@DEF@" +.sM +.FD 0 +Boolean XtAppGetExitFlag(\fIapp_context\fP) +.br + XtAppContext \fIapp_context\fP; +.FN +.IP \fIapp_context\fP 1i +Specifies the application context. +.LP +.eM +.PN XtAppGetExitFlag +will normally return \fBFalse\fP, indicating that event processing +may continue. When +.PN XtAppGetExitFlag +returns \fBTrue\fP, the loop must terminate and return to the caller, +which might then destroy the application context. +.LP +Application writers should be aware that, if a thread is blocked in +.PN XtAppNextEvent , +.PN XtAppPeekEvent , +or +.PN XtAppProcessEvent +and another thread in the same application context opens a new display, +adds an alternate input, or a timeout, any new source(s) will not +normally be "noticed" by the blocked thread. Any new sources are +"noticed" the next time one of these functions is called. +.LP +The \*(xI manage access to events on a last-in, first-out basis. If +multiple threads in the same application context block in +.PN XtAppNextEvent , +.PN XtAppPeekEvent , +or +.PN XtAppProcessEvent , +the last thread to call one of these functions is the first +thread to return. +.bp |