VMS DECwindows Guide to Xlib (Release 4) Programming: MIT C Binding


Previous Contents Index


Chapter 9
Handling Events

An event is a report of either a change in the state of a device (such as a mouse) or the execution of a routine called by a client. An event can be either unsolicited or solicited. Typically, unsolicited events are reports of keyboard or pointer activity. Solicited events are Xlib responses to calls by clients.

Xlib reports events asynchronously. When any event occurs, Xlib processes the event and sends it to clients that have specified an interest in that type of event.

This chapter describes the following concepts needed to manage events:

This chapter provides information for a subset of event types. For a complete reference of event handling routines and data structures, see the DECwindows Motif for OpenVMS Guide to Non-C Bindings and the X Window System.

9.1 Event Processing

Apart from errors, which Section 9.13 describes, Xlib events issue from operations on either windows or pixmaps. Most events result from operations associated with windows. The smallest window that contains the pointer when a window event occurs is the source window.

Xlib searches the window hierarchy upward from the source window until one of the following applies:

While there are many types of window events, events associated with pixmaps occur only when a client cannot compute a destination region because the source region is out-of-bounds (see Chapter 6 for a description of source and destination regions). When a client attempts an operation on an out-of-bounds pixmap region, Xlib puts the event on the event queue and checks a list to determine if a client is interested in the event. If a client is interested, Xlib sends information to the client using an event data structure.

Xlib can report 30 types of events related to keyboards, mice, windowing, and graphics operations. A flag identifies each type to facilitate referring to the event. Table 9-1 lists event types, grouped by category, and the flags that represent them.

Table 9-1 Event Types
Event Type Flag Name
Keyboard Events
Key press KeyPress
Key release KeyRelease
Pointer Motion Events
Button press ButtonPress
Button release ButtonRelease
Motion notify MotionNotify
Window Crossing Events
Enter notify EnterNotify
Leave notify LeaveNotify
Input Focus Events
Focus in FocusIn
Focus out FocusOut
Keymap State Event
Keymap notify KeymapNotify
Exposure Events
Expose Expose
Graphics expose GraphicsExpose
No expose NoExpose
Window State Events
Circulate notify CirculateNotify
Configure notify ConfigureNotify
Create notify CreateNotify
Destroy notify DestroyNotify
Gravity notify GravityNotify
Map notify MapNotify
Mapping notify MappingNotify
Reparent notify ReparentNotify
Unmap notify UnmapNotify
Visibility notify VisibilityNotify
Color Map State Events
Color map notify ColormapNotify
Client Communication Events
Client message ClientMessage
Property notify PropertyNotify
Selection clear SelectionClear
Selection notify SelectionNotify
Selection request SelectionRequest

Every event type has a corresponding data structure that Xlib uses to pass information to clients. See the sections that describe handling specific event types for a description of the relevant event-specific data structures.

Xlib includes the any event data structure, which clients can use to receive reports of any type of event. The following illustrates the any event data structure:


typedef struct { 
        int type; 
        unsigned long serial; 
        Bool send_event; 
        Display *display; 
        Window window; 
} XAnyEvent; 

Table 9-2 describes members of the data structure.

Table 9-2 Any Event Data Structure Members
Member Name Contents
type Type of event being reported
serial Number of the last request processed by the server
send_event Value defined by the constant true if the event came from a SEND EVENT request
display Display on which the event occurred
window Window on which the event report was requested

To enable clients to manage multiple types of events easily, Xlib also includes an event data structure, which is composed of the union of individual event data structures.

The following illustrates the event data structure:


typedef union _XEvent { 
        int type;             
        XAnyEvent xany; 
        XKeyEvent xkey; 
        XButtonEvent xbutton; 
        XMotionEvent xmotion; 
        XCrossingEvent xcrossing; 
        XFocusChangeEvent xfocus; 
        XExposeEvent xexpose; 
        XGraphicsExposeEvent xgraphicsexpose; 
        XNoExposeEvent xnoexpose; 
        XVisibilityEvent xvisibility; 
        XCreateWindowEvent xcreatewindow; 
        XDestroyWindowEvent xdestroywindow; 
        XUnmapEvent xunmap; 
        XMapEvent xmap; 
        XMapRequestEvent xmaprequest; 
        XReparentEvent xreparent; 
        XConfigureEvent xconfigure; 
        XGravityEvent xgravity; 
        XResizeRequestEvent xresizerequest; 
        XConfigureRequestEvent xconfigurerequest; 
        XCirculateEvent xcirculate; 
        XCirculateRequestEvent xcirculaterequest; 
        XPropertyEvent xproperty; 
        XSelectionClearEvent xselectionclear; 
        XSelectionRequestEvent xselectionrequest; 
        XSelectionEvent xselection; 
        XColormapEvent xcolormap; 
        XClientMessageEvent xclient; 
        XMappingEvent xmapping; 
        XErrorEvent xerror; 
        XKeymapEvent xkeymap; 
} XEvent; 

The type member specifies the type of event being reported. For descriptions of the other members of the event data structure, see the section that describes the specific event type.

9.2 Selecting Event Types

Xlib sends information about an event only to clients that have specified an interest in that event type. Clients use one of the following methods to indicate interest in event types:

Note that Xlib always reports client messages, mapping notifications, selection clearings, selection notifications, and selection requests.

See the description of the SELECT INPUT routine in the X Window System for restrictions on event reporting to multiple clients.

9.2.1 Using the SELECT INPUT Routine

Use the SELECT INPUT routine to specify the types of events Xlib reports to a client. Select event types by passing to Xlib one or more of the masks listed in Table 9-3.

Table 9-3 Event Masks
Event Mask Event Reported (Event Type)
ButtonMotionMask At least one button on the pointing device is pressed while the pointer moves (MotionNotify).
Button1MotionMask Button 1 of the pointing device is pressed while the pointer moves (MotionNotify).
Button2MotionMask Button 2 of the pointing device is pressed while the pointer moves (MotionNotify).
Button3MotionMask Button 3 of the pointing device is pressed while the pointer moves (MotionNotify).
Button4MotionMask Button 4 of the pointing device is pressed while the pointer moves (MotionNotify).
Button5MotionMask Button 5 of the pointing device is pressed while the pointer moves (MotionNotify).
ButtonPressMask A button on the pointing device is pressed (ButtonPress).
ButtonReleaseMask A button on the pointing device is released (ButtonRelease).
ColormapChangeMask A client installs, changes, or removes a color map (ColormapNotify).
EnterWindowMask The pointer enters a window (EnterNotify).
ExposureMask A window becomes visible, a graphics region cannot be computed, a graphics request exposes a region or all sources available, and a no expose event is generated (Expose, GraphicsExpose, NoExpose).
LeaveWindowMask The pointer leaves a window (LeaveNotify).
FocusChangeMask The keyboard focus changes (FocusIn, FocusOut).
KeymapStateMask The key map changes (KeymapNotify).
KeyPressMask A key is pressed or released (KeyPress, KeyRelease).
OwnerGrabButtonMask Not applicable.
PointerMotionMask The pointer moves (MotionNotify).
PointerMotionHintMask Xlib is free to report only one pointer-motion event (MotionNotify) until one of the following occurs:
  • Either the key or button state changes.
  • The pointer leaves the window.
  • The client calls QUERY POINTER or GET MOTION EVENTS.
PropertyChangeMask A client changes a property (PropertyNotify).
StructureNotifyMask One of the following operations occurs on a window:
  • Circulate (CirculateNotify)
  • Configure (ConfigureNotify)
  • Destroy (DestroyNotify)
  • Move (GravityNotify)
  • Map (MapNotify)
  • Reparent (ReparentNotify)
  • Unmap (UnmapNotify)
SubstructureNotifyMask One of the following operations occurs on the child of a window:
  • Circulate (CirculateNotify)
  • Configure (ConfigureNotify)
  • Create (CreateNotify)
  • Destroy (DestroyNotify)
  • Move (GravityNotify)
  • Map (MapNotify)
  • Reparent (ReparentNotify)
  • Unmap (UnmapNotify)
VisibilityChangeMask The visibility of a window changes (VisibilityNotify).

The following illustrates using the SELECT INPUT routine:


               .
               .
               .
XSelectInput(dpy,win,StructureNotifyMask); 
}                     

Clients specify the StructureNotifyMask mask to indicate an interest in one or more of the following window operations (see Table 9-3):
Circulating Configuring
Destroying Reparenting
Changing gravity Mapping and unmapping
Moving  

9.2.2 Specifying Event Types When Creating a Window

To specify event types when calling the CREATE WINDOW routine, use the method described in Section 3.2.2 for setting window attributes. Indicate the type of event Xlib reports to a client by doing the following:

  1. Set the event_mask window attribute to one or more masks listed in Table 9-3.
  2. Specify the event mask flag using the value_mask argument of the CREATE WINDOW routine.

Example 9-1 illustrates this method of selecting events. The program specifies that Xlib notify the client of exposure events.

Example 9-1 Selecting Event Types Using the CREATE WINDOW Routine

Window window; 
                  .
                  .
                  .
static void doCreateWindows( ) 
{   
    int windowW = 400; 
    int windowH = 300; 
    int windowX = (WidthOfScreen(screen)-window1W)>>1; 
    int windowY = (HeightOfScreen(screen)-window1H)>>1; 
    XSetWindowAttributes xswa; 
    
    /* Create the window1 window */ 
 
(1)   xswa.event_mask = ExposureMask; 
 
(2)   window = XCreateWindow(dpy, RootWindowOfScreen(screen), 
        windowX, windowY, windowW, windowH, 0, 
        DefaultDepthOfScreen(screen), InputOutput, 
        DefaultVisualOfScreen(screen), CWEventMask, &xswa); 
} 

  1. Set the event mask of the set window attributes data structure to indicate interest in exposure events.
  2. The window attribute is referred to by the constant CWEventMask, which specifies the attribute.

9.2.3 Specifying Event Types When Changing Window Attributes

To specify one or more event types when changing window attributes, use the method described in Section 3.7 for changing window attributes. Indicate an interest in event types by doing the following:

  1. Set the event_mask window attribute to one or more masks listed in Table 9-3.
  2. Specify the event mask flag using the value_mask argument of the CHANGE WINDOW ATTRIBUTES routine.

The following illustrates this method:


                  .
                  .
                  .
    xswa.event_mask = StructureNotify; 
 
 
    XChangeWindowAttributes(dpy, win, CWEventMask, &xswa); 

9.3 Pointer Events

Xlib reports pointer events to interested clients when the button on the pointing device is pressed or released or when the pointer moves.

This section describes how to handle the following pointer events:

The section also describes the button event and motion event data structures.

9.3.1 Handling Button Presses and Releases

To receive event notification of button presses and releases, pass the window identifier and either the ButtonPressMask mask or the ButtonReleaseMask mask when using the selection method described in Section 9.2.

When a button is pressed, Xlib searches for ancestors of the event window from the root window down to determine whether or not a client has specified a passive grab, an exclusive interest in the button. If Xlib finds no passive grab, it starts an active grab, reserving the button for the sole use of the client receiving notification of the event. Xlib also sets the time of the last pointer grab to the current server time. The effect is the same as calling the GRAB BUTTON routine with argument values listed in Table 9-4.

Table 9-4 Values Used for Grabbing Buttons
Argument Value
window_id Event window.
event_mask Client pointer motion mask.
pointer_mode Value specified by the constant GrabModeAsync.
keyboard_mode Value specified by the constant GrabModeAsync.
owner_events True, if the owner has selected OwnerGrabButtonMask. Otherwise, false.
confine_to None.
cursor None.

Refer to Chapter 11 for more information about using grabs.

Xlib uses the button event data structure to report button presses and releases. The following illustrates the data structure:


typedef struct {                                                 
        int type;          
        unsigned long serial; 
        Bool send_event; 
        Display *display;  
        Window window; 
        Window root; 
        Window subwindow; 
        Time time;  
        int x, y;  
        int x_root, y_root; 
        unsigned int state; 
        unsigned int button;                  
        Bool same_screen; 
} XButtonEvent; 
typedef XButtonEvent XButtonPressedEvent; 
typedef XButtonEvent XButtonReleasedEvent; 

Table 9-5 describes members of the button event data structure. Note that Xlib defines the button pressed event and button released event data structures as a type button event.

Table 9-5 Button Event Data Structure Members
Member Name Contents
type Type of event reported. The event type can be either ButtonPress or ButtonRelease.
serial Number of the last request processed by the server.
send_event Value defined by the constant true if the event came from a SEND EVENT request.
display Address of the display on which the event occurred.
window Event window.
root Root window in which the event occurred.
subwindow Source window in which the event occurred.
time Time in milliseconds at which the event occurred.
x The x value of the pointer coordinates in the source window.
y The y value of the pointer coordinates in the source window.
x_root The x value of the pointer coordinates relative to the root window.
y_root The y value of the pointer coordinates relative to the root window.
state State of the button just prior to the event. Xlib can set this member to the bitwise OR of one or more of the following masks:
Button1Mask Button2Mask
Button3Mask Button4Mask
Button5Mask Mod1Mask
Mod2Mask Mod3Mask
Mod4Mask Mod5Mask
button Buttons that changed state. Xlib can set this member to one of the following values:
Button1 Button2
Button3 Button4
Button5  
screen Indicates whether or not the event window is on the same screen as the root window.

Example 9-2 illustrates the button press event handling routine of the sample program described in Chapter 1. The program calls shutdown routines when the user clicks the mouse button in window2.

Example 9-2 Handling Button Presses

/***** Handle events *****/ 
static void doHandleEvents( ) 
{ 
    XEvent event;         
 
    for ( ; ; ) { 
        XNextEvent(dpy, &event); 
        switch (event.type) { 
            case Expose:                doExpose(&event); break; 
            case ButtonPress:           doButtonPress(&event); break; 
        } 
    }                                           
} 
                    .
                    .
                    .
static void doButtonPress(eventP) 
XEvent *eventP;                                                      
{                               
        if (eventP->xexpose.window != window2) { 
        state =1; 
        XDrawImageString(dpy, child, gc, 75, 75, message[state], 
            strlen(message[state])); 
        return; 
    }    
 
    /***** Unmap and destroy windows *****/ 
 
    XUnmapWindow(dpy, window1); 
    XDestroyWindow(dpy, window1); 
                  
    XCloseDisplay(dpy);    
            
    sys$exit (1); 
}                          


Previous Next Contents Index