6
Handling Input
In discussing canvases in the previous chapter, we showed how to do some basic event hand-
ling in the canvas’s paint window. This chapter goes into detail about the content of such
events, the breakdown of the Event data structure that describes the event, the different
types of input events that can be handled, and the specifics about what gets passed to the pro-
gram’s event handling callback routine. Chapter 20, The Notifier, should be reviewed for an
in-depth discussion of how to handle events on a somewhat more advanced level. It
addresses the event types themselves, how to register which events you want to be notified
of, and how to interpret the events you receive.
This chapter also describes the interface to the special keyboard and mouse features includ-
ing soft function keys, virtual keyboards, mouseless model keyboard mappings, and accelera-
tor keys. These features support OPEN LOOK Level 2 functions that permit you to use multi-
ple “virtual keyboards,” and software-supported function keys. You also have the option of
using the keyboard as a locator device along with or in place of a mouse.
This chapter discusses the following:
• The design of event handling.
• The breakdown of the Event data structure.
• Registering an event handler and the events you are interested in.
• Interpreting the events your event handler received.
• Sending messages to other windows or clients.
• Explicit reading of events from the server.
• Using the soft function keys.
• Virtual keyboards.
• The mouseless model.
• Using accelerators.
Handling Input
Handling Input 115
6.1 Introduction to Events in XView
Events are generated from several sources, including standard devices such as the keyboard
and mouse, special input devices such as graphics tablets, and the window system itself.
XView does not directly receive events from the hardware devices; the X server is responsi-
ble for managing these events and communicating them to the XView application. The
Notifier receives all X events on behalf of the client application and dispatches them to the
appropriate callback procedures registered by XView objects.
Because the Notifier multiplexes the input stream between windows, each individual window
operates under the illusion that it has the user’s full attention. That is, it sees precisely those
input events that the user has directed to it. Each window indicates which events it is pre-
pared to handle using input masks. An event callback procedure processes the events when
they occur. Many windows have default event handlers that are installed internally by cer-
tain XView packages. Panels, for example, have a default event notification procedure that is
used to identify which panel item received the input. Text subwindows capture events to
allow typing and monitor text selection generated by using the mouse. However, some
events may result in separate callback procedures being notified as well—repaint and resize
events, for example, may have separate callback routines installed.
Applications can send messages to separate windows within the same application or to other
applications running under separate processes. The X function XSendEvent() sends cli-
ent-specified X events to other windows. XClientMessageEvent is one such event that
can be sent. XView provides the function xv_send_message() as an interface for send-
ing client messages in this manner.
The X Window System has a full set of events that can be sent to client applications by the
server. It is highly recommended that you review Chapter 8, Events, in Volume One, Xlib
Programming Manual, for specifics on the nature of these events.
6.2 Classes of Events
Events are grouped into the following classes:
• Semantic Events
•
ASCII Events
• Locator Button Events
• Locator Motion Events
• Function Key Events
• Repaint and Resize Events
• Client Messages
• Selection Events
116 XView Programming Manual
Each of these event types are discussed in Section 6.3, “Registering Events,” and Section 6.7,
“Interpreting Client Messages.” There are separate issues to consider in both cases. How-
ever, semantic event codes are common to both. We will first address event IDs and semantic
events and then move directly on to event registration. After we discuss how to register the
events you are interested in, we will discuss how your event handling routine can interpret
the events it receives.
6.2.0.1 Event IDs
Event IDs are integer values that have been assigned somewhat, but not completely, arbitrar-
ily to events that may be generated in X.* Some event IDs represent keyboard events, func-
tion key events, window resize and repaint events, and so on. Although both X and XView
understand the same events, there is no correlation between the event ID and Xlib’s event
codes. Thus, keyboard event IDs are not key symbols as defined by X’s KeySym or
XKeyEvent.keycode fields.
Event IDs are helpful when debugging applications; you can stop in event-handling routines
and print the value of a particular event ID to identify the specific event type. One helpful
hint is that the
ASCII event IDs correspond to the ASCII codes generated. That is, if the user
presses the x key, then the event ID is x.
6.2.0.2 Semantic events
Also called action events, semantic events are used to describe the meaning of an event using
semantic phrases, so to speak, rather than using the literal event code represented by an event
ID. That is, the definition of the macro describes the value of the event as well as its mean-
ing. When someone presses a key marked HELP on the keyboard, the event ID may represent
a large, cryptic numeral such as 65034. However, the semantic code associated with the key
event would be ACTION_HELP.
There are also cases where the keyboard has been remapped by some applications for other
purposes. For example, in OPEN LOOK, the SELECT button defaults to the leftmost physical
mouse button, also known as button one. Normally this button is activated using the index
finger for a right-handed person. A left-handed person who places the mouse on the left may
remap the semantics of the leftmost and rightmost buttons (assuming a multibutton mouse).
This allows the left-handed user to also use his index finger to activate the SELECT button.
We recommend that you use semantic actions when referring to events for consistency with
other applications as well as consistency with different computers. Section 5, in the XView
Reference Manual, provides a list of the semantic events. These events are defined in
<xview/win_input.h>.
*This concept is carried over from SunView and is foreign to X.
Handling Input
Handling Input 117
6.3 Registering Events
Typically, when you specify which events a particular window is interested in, you also spec-
ify an event handler for that window. You register an event handler with an XView window,
not the object with which the window is associated. Sometimes the object and the window
are one and the same (i.e., panels), but in other cases, they are not. Specifically, to register an
event handler for canvases you use the paint window as in:
Xv_Window window;
Canvas canvas;
int win;
window = (Xv_Window)xv_get(canvas, CANVAS_NTH_PAINT_WINDOW, win);
For text subwindows, you use the view window:
Xv_Window window;
Textsw textsw;
int win_no;
window = (Xv_Window)xv_get(textsw, OPENWIN_NTH_VIEW, win_no);
Once you have obtained the window, you can install the event handler using the
WIN_EVENT_PROC attribute:
xv_set(window,
WIN_EVENT_PROC, sample_event_proc,
WIN_CONSUME_EVENTS, WIN_ASCII_EVENTS, WIN_MOUSE_BUTTONS, NULL,
NULL);
The window is of type Xv_Window. The event handler is a function that is called whenever
any of the registered events occur in the specified windows. Details about this routine and
how to interpret the events delivered to it are discussed later in this chapter, starting with
Section 6.4, “The Event Handler.”
This section discusses specifically how to register and unregister the events in which you are
interested for a particular window. There are several ways to describe events you wish to
register. You can specify action (semantic) events, literal events or event classes defined by
XView (as shown in the example), or you can use X event masks (familiar to Xlib program-
mers). Which method you choose for registering events does not affect the function of the
event handler; it maintains its function of receiving and understanding events.
6.3.1 Specifying X Event Masks
The simplest and most direct method for people familiar with Xlib programming is to use X
event masks.* To register or unregister events using X masks, you can use:
WIN_CONSUME_X_EVENT_MASK
WIN_IGNORE_X_EVENT_MASK
*See Volume One, Xlib Programming Manual, for a complete discussion of event masks and their implications.
118 XView Programming Manual
The value for these attributes is a mask made up of any of the event masks defined in
<X11/X.h>. Do not confuse event masks with actual event types.
WIN_CONSUME_X_EVENT_MASK appends the specified event mask to the existing event mask
for the object. However, to set the event mask explicitly to the specified mask, use
WIN_EVENT_MASK. To clear the event mask completely, use:
xv_set(window, WIN_X_EVENT_MASK, NoEventMask, NULL);
The following code segment demonstrates how a canvas would register interest in the key-
board and mouse buttons:
xv_set(window,
WIN_CONSUME_X_EVENT_MASK, ButtonPressMask | KeyPressMask,
NULL);
Notice that we did not specify ButtonReleaseMask or KeyReleaseMask. Thus, the
event handler is going to receive the down-events only.
When you specify event masks with the attribute WIN_IGNORE_X_EVENT_MASK, then those
events are not delivered to your event handler. You cannot use this attribute to unregister all
events and expect that to unregister your event handler. You must set the WIN_EVENT_PROC
to NULL to do that. It is perfectly legal to have no events registered with a window.
6.3.2 Specifying XView Events
XView events (or event types) are simply alternate ways to specify events when you register
them or interpret them. When using these event types to register events, you are not adding
any more functionality than using the Xlib event registration scheme in the previous section.
However, XView event types may make it easier to identify more precisely which events you
are interested in being notified of.
The header files <xview/win_input.h> and <xview/win_event.h> have several data types, and
most XView event definitions allow you to register events with windows or the Notifier.
There are two methods available to do this: using the Inputmask data structure or specify-
ing XView event codes directly.
Although the Inputmask method tends to be less elegant than using XView event types, it
is necessary in order to use xv_input_readevent() and other advanced-usage func-
tions. See Section 6.8, “Reading Input Directly,” for details about how the Inputmask
structure is used.
The attribute
WIN_CONSUME_EVENTS is used to register events via XView event types. The
value for this attribute is a NULL-terminated list of the XView events defined in the header
files mentioned above. Let’s re-examine the example used in the previous section:
xv_set(window,
WIN_EVENT_PROC, sample_event_proc,
WIN_CONSUME_EVENTS, WIN_ASCII_EVENTS, WIN_MOUSE_BUTTONS, NULL,
NULL);
The values WIN_ASCII_EVENTS and WIN_MOUSE_BUTTONS encompass all the ASCII codes
from 0 to 127, inclusive, and the mouse button events. The events specified are added to the
Handling Input
Handling Input 119
Get Volume 7A: XView Programming Manual now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.