Previous | Contents | Index |
To return the first event on the event queue and copy it into the
specified event data structure, use the NEXT EVENT and PEEK EVENT
routines. NEXT EVENT returns the first event, copies it into an EVENT
structure, and removes it from the queue. PEEK EVENT returns the first
event, copies it into an event data structure, but does not remove it
from the queue.
In both cases, if the event queue is empty, the routine flushes the
output buffer and blocks until an event is received.
9.12.3 Selecting Events That Match User-Defined Routines
Xlib enables the client to check all the events on the queue for a specific type of event by specifying a client-defined routine known as a predicate procedure. The predicate procedure determines if the event on the queue is one that the client is interested in.
The client calls the predicate procedure from inside the event routine. The predicate procedure should determine only if the event is useful and must not call Xlib routines. The predicate procedure is called once for each event in the queue until it finds a match.
Table 9-11 lists routines that use a predicate procedure and indicates whether or not the routine blocks.
Routine | Description | Blocking/ No Blocking |
---|---|---|
IF EVENT | Checks the event queue for the specified event. If the event matches, removes the event from the queue. This routine is also called each time an event is added to the queue. | Blocking |
CHECK IF EVENT | Checks the event queue for the specified event. If the event matches, removes the event from the queue. If the predicate procedure does not find a match, it flushes the output buffer. | No blocking |
PEEK IF EVENT | Checks the event queue for the specified event but does not remove it from the queue. This routine is also called each time an event is added to the queue. | Blocking |
Xlib enables a client to process events out of order by specifying a window identifier and one of the event masks listed in Table 9-3 when calling routines listed in Table 9-12.
For example, the following specifies keyboard events on window window by using the event mask name constant KeymapStateMask.
. . . XWindowEvent(dpy, window, KeymapStateMask, &event) |
Table 9-12 lists routines that use event or window masks and indicates whether the routine blocks.
Routine | Description | Blocking/ No Blocking |
---|---|---|
WINDOW EVENT | Searches the event queue and removes the next event that matches both the specified window and event mask | Blocking |
CHECK WINDOW EVENT | Searches the event queue, then the events available on the server connection, and removes the first event that matches the specified event and window mask | No blocking |
MASK EVENT | Searches the event queue and removes the next event that matches the event mask | Blocking |
CHECK MASK EVENT | Searches the event queue, then the events available on the server connection, and removes the next event that matches an event mask | No blocking |
CHECK TYPED EVENT | Returns the next event in the queue that matches an event type | No blocking |
CHECK TYPED WINDOW EVENT | Searches the event queue, then the events available on the server connection, and removes the next event that matches the specified type and window | No blocking |
To push an event back onto the top of the event queue, use the PUT BACK
EVENT routine.
PUT BACK EVENT is useful when a client returns an event from the queue
and decides to use it later. There is no limit to how many times in
succession PUT BACK EVENT can be called.
9.12.6 Sending Events to Other Clients
To send an event to a client, use the SEND EVENT routine. For example,
owners of a selection should use this routine to send a SELECTION
NOTIFY event to a requestor when a selection has been converted and
stored as a property.
9.13 Error Handling
Xlib has two default error handlers. One manages fatal errors, such as when the connection to a display is severed due to a system failure. The other handles error events from the server. The default error handlers print an explanatory message and text and then exit.
Each of these error handlers can be replaced by client error handling routines. If a client-supplied routine is passed a null pointer, Xlib reinvokes the default error handler.
This section describes the Xlib event error handling resources
including enabling synchronous operation, handling server errors, and
handling input/output (I/O) errors.
9.13.1 Enabling Synchronous Operation
When debugging programs, it is convenient to require Xlib to behave synchronously so that errors are reported at the time they occur.
To enable synchronous operation, use the SYNCHRONIZE routine. The
client passes the display argument and the
onoff argument. The onoff argument
passes either a value of zero (disabling synchronization) or a nonzero
value (enabling synchronization).
9.13.2 Using the Default Error Handlers
To handle error events when an error event is received, use the SET ERROR HANDLER routine.
Xlib provides an error event data structure that passes information to the SET ERROR HANDLER routine.
The following illustrates the error event data structure:
typedef struct { int type Display *display unsigned long serial; char error_code; char request_code; char minor_code; XID resourceid; } XErrorEvent; |
Table 9-13 describes the members of the data structure.
Member Name | Description |
---|---|
type | Type of error event being reported |
display | Display on which the error event occurred |
serial | Number of requests starting at one sent over the network connection since it was opened |
error_code | Identifying error code of the failing routine |
request_code | Protocol representation of the name of the procedure that failed and defined in X11/X.h |
minor_code | Minor opcode of failed request |
resourceid | Resource ID |
The routines described in this section return Xlib error codes. For a description of the error codes, see the X Window System. The following lists the codes:
BadAccess | BadImplementation |
BadAlloc | BadLength |
BadAtom | BadMatch |
BadColor | BadName |
BadCursor | BadPixmap |
BadDrawable | BadRequest |
BadFont | BadValue |
BadGC | BadWindow |
BadIDChoice |
When creating any X resource, such as a window, pixmap, or gc, it is important to note that these routines are asynchronous and do not return errors if the create operation fails. Although Xlib returns a resource ID for these routines, it does not indicate that a valid resource was created by the server.
Use the following method to check if the client has successfully created a resource:
The X resource manager, also referred to as the resource manager in the rest of this chapter, is a database manager that provides a set of tools for specifying client preferences such as color, fonts, and line width.
This chapter describes using the resource manager and includes the following topics:
The resource manager is a database manager; however, it operates differently than most database managers. In most systems, the database contains precise specifications; the client then queries the database using imprecise or broad specifications. With the resource manager, a large set of resources can be specified in the database with one imprecise specification. The client queries the resource manager with a precise specification and one value is returned. Thus, the resource manager can be used by clients to return values for color, font names, or other resources.
For example, a client can specify in the resource manager database that all windows should have a blue background but that all windows used for editing text should have a white background. This specification can be done using just two entries in the database: one entry that sets the text-editing window to white and one entry that sets all other windows to blue.
To illustrate how the resource manager works, consider the following example of a simple graphics client called xgr. This client allows the user to draw simple graphic line figures and text using the command buttons at the top of the window. In addition, it provides drawing in three different line widths. Figure 10-1 illustrates the user interface of the client.
Figure 10-1 Interface of Client xgr
Assume that the interface of the client xgr uses a set of windows from the parent window (which includes all client windows) all the way down to the individual command buttons that actually draw the graphics. It is this window hierarchy that provides one method for creating and naming the resources in the database.
It is important to note here that the resource manager imposes no restrictions on the entries in the database. However, if entries in the database are formed logically, then it is easy to specify resources for any portion of the client. Incorrect entries can have unpredictable results.
10.1.1 Names and Classes
Each object that uses the resource manager must have a
name and a class. A name is a more
specific way of referring to a particular object or window; whereas,
the class is more general and can be used for returning values for an
entire set, or class, of windows or objects.
The name and the class are built from components at each level of the window hierarchy. Components within a name and a class are separated by periods. Although names and classes can have an arbitrary number of components, each name and class must be fully-qualified. A fully-qualified name has the same number of components as its reciprocal fully-qualified class. Refer to Figure 10-2 for an example of fully-qualified names and classes.
Because names and classes can often contain the same components, the following conventions are used to differentiate between a name and a class:
Although the preceding conventions are not rules, they provide one method to differentiate between names and classes.
Note that in the resource manager names and classes are created by the
client and are entirely arbitrary. Section 10.1.2 shows how names and
classes can be formed and used.
10.1.2 Forming Names and Classes
To illustrate how names and classes are formed, consider the client xgr from the preceding example. At the top level is the client xgr which forms the first component of the name and the class, xgr and Xgr respectively.
The parent window forms the second component for the name and the class. This window is named main; its class is MainWindow. Therefore, its fully-qualified name is the name of its parent followed by its name, or xgr.main. Its fully-qualified class is the class of its parent followed by its class, or Xgr.MainWindow.
At the next level is the window that contains the buttons that perform the graphic operations. The fully-qualified name of this window is its name, buttons, appended to the name of its parent or xgr.main.buttons. Its fully-qualified class is its class appended to its parent's class, or Xgr.MainWindow.Box.
Figure 10-2 Hierarchy of Names and Classes of the Client xgr
At the lowest level is the set of windows that actually perform the graphics operations. Each has a name such as drawText, or drawEllipse, yet each belongs to the class of windows called Commands. Therefore, the fully-qualified name of the button that draws the text is xgr.main.buttons.drawText and its fully-qualified class is Xgr.MainWindow.Box.Command.
Figure 10-2 shows the hierarchy of the windows and the names and classes of each window.
The resources that any object or window needs are called attributes, and as such have a name and a class. For example, some of the attributes that the client can set for the window named main include height, width, background color, and foreground color. The fully-qualified name of the height attribute for the window main is xgr.main.height. Its class is Xgr.MainWindow.Height.
To illustrate how names and classes differ in their uses, suppose that the client xgr needs to have a white background assigned for the window named draw, yet needs to have a red background for all command buttons. The following entries in Table 10-1 meet these requirements.
Entry | Explanation |
---|---|
xgr.draw.background: white | Within the client named xgr, the window named draw is assigned a white background. |
xgr.draw.buttons.Command.background: red | Within the client named xgr, all windows that belong to the class Command are assigned a red background. With this one entry, each window that draws the graphics is assigned the color red. |
When a client looks up a resource, it passes the complete name and
complete class of the resource to a lookup routine. The resource
manager then returns the resource value that best matches the name and
the class.
10.1.3 Resource Manager Matching Rules
Resources are stored with only partially specified names and classes, using pattern matching constructs. The following rules pertain to individual entries in the database:
To signal a continuation of a line, use the backslash (\) character. Use the \n characters to indicate a new line, for example when using a multiline table such as a translation table. Refer to the VMS DECwindows Guide to Application Programming for more information about translation tables.
The following are examples of resource database entries:
xgr.main.color: blue *MainWindow.Color: red xgr*Font: -Adobe-New Century Schoolbook-Bold-R-Normal-- \ *-140-*-*-P-*-ISO8859-1 xgr*lineWidth.thin: 1 xgr*lineWidth.medium: 2 xgr*lineWidth.heavy: 3 |
After the lookup routine passes the fully specified name and class, the lookup algorithm then searches the database for the name that most closely matches the full name and class passed by the lookup routine. The algorithm that determines the resource name that matches a given query is the heart of the database.
Table 10-2 lists the rules for the match in order of precedence and an example of each rule.
Rule | Example |
---|---|
The attribute of the name and the class must match. | The queries xgr.main.width (name) and Xgr.MainWindow.Width (class) do not match the database entry: xgr.main: 600. (The entry is missing the attribute, width.) |
Database entries with name or class prefixed by a period (.) are more specific than those prefixed by an asterisk (*). | The entry xgr.font is more specific than xgr*font. The entry xgr.font will be fetched before xgr*font. |
Names are more specific than classes. | The entry *main.color is more specific than *MainWindow.Color. |
Specifying a name or a class is more specific than omitting either. | The entry *MainWindow*Color is more specific than *Color. |
Left components are more specific than right components. | The entry *xgr*color is more specific than *main*color for the query xgr.main.color. |
If neither a period nor an asterisk is specified at the beginning, a period is implicit. | The entry xgr.main is identical to .xgr.main. |
Previous | Next | Contents | Index |