This section discusses the following areas:
GL supports three classes of input devices:
valuators | Return an integer value. For example, a dial on a dial and button box is a valuator. A mouse is a pair of valuators: one reports horizontal position and the other reports vertical position. |
buttons | Return a Boolean value: FALSE when they are not pressed (open) and TRUE when they are pressed (closed). Examples of buttons are keys on an unencoded keyboard, buttons on a mouse, and the switches on a dial and button box. |
other devices | Return information about other system events. For example, the keyboard returns ASCII characters. Most of these special devices register events. The keyboard device reports character values when keys (or combinations of keys) are pressed. If you press the A key, an ASCII a is reported; if you press the Shift key, nothing is reported. If you hold down the Shift key and then press the A key, an ASCII A is reported. |
blkqread | |
Reads multiple entries from the event queue. | |
getbutton | |
Returns the current state of a button. | |
getdev | |
Reads a list of valuators. | |
getvaluator | |
Returns the current state of a valuator. | |
isqueued | |
Indicates whether a specified device is enabled for event queuing. | |
noise | |
Filters valuator motion. | |
qdevice | |
Enables an input device for event queuing. | |
qenter | |
Creates an event queue entry. | |
qread | |
Reads the first entry in the event queue. | |
qreset | |
Empties the event queue. | |
qtest | |
Checks the contents of the event queue. | |
setvaluator | |
Assigns an initial value to a valuator. | |
tie | |
Ties two valuators to a button. | |
unqdevice | |
Disables an input device for event queuing. |
Understanding Windows and Input Control in GL introduces window and input control categories.
Most input devices have an associated current value. If the input device is a button, the value is either 1 (pressed) or 0 (not pressed). If the device is a valuator, such as a dial or the x position of the mouse, its value is an integer that indicates the position of the device. Some special devices do not have an associated current value.
A program can get the value from input devices by either polling or queuing:
In most cases, using the input queue is better than polling. For example, if you press and release a mouse button in an instant, a program that uses polling can miss the event (that the button was down) if it happened between two calls to getbutton(LEFTMOUSE).
For example, in a drawing program where you may want to indicate a series of vertices quickly and the system's calculations cannot keep up, queuing saves all the state changes so nothing is missed. This is so even if the program is doing something else when the event happens.
Devices that are queued act as asynchronous devices, independent of the user process. Whenever a device that is queued changes state, an entry is made in the event queue. If a program reads the queue in a timely fashion, no events are lost.
You can decide which devices, if any, to queue and establish some rules about what constitutes a state change, or event, for those devices. By default, no devices are queued.
Another difference between polling and queuing is that as long as a polled I/O device is active, it continues to send its value to the program that polls it. For instance, a call to getbutton(LEFTMOUSE) continues returning a value as long as you hold down the mouse button. In contrast, if the left mouse button had been queued, you could hold it down for any length of time and only one event is added to the queue. A second event is added to the queue only when the button is released and pressed a second time.
In addition to input subroutines, other subroutines control the characteristics of the peripheral input/output devices (see "Using the Keyboard"). These subroutines turn the keyboard click and the keyboard lights on and off; ring the keyboard bell; and control the lights on the dial and button box.
See the Input Buttons, Input Valuators, and Special Devices tables for listings of specific devices and their descriptions. Special devices, such as window manager, cursor, and ghost devices, are discussed in "Special Devices".
Input Buttons | |
Devices | Description |
MOUSE1 | Right mouse button |
MOUSE2 | Middle mouse button |
MOUSE3 | Left mouse button |
RIGHTMOUSE | Right mouse button |
MIDDLEMOUSE | Middle mouse button |
LEFTMOUSE | Left mouse button |
SW0...SW31 | 32 buttons on dial and button box |
AKEY...PADENTER, BKEY...PADENTER | All the keys on the keyboard |
BPAD0 | Pen stylus or button for digitizer tablet |
BPAD1 | Button for digitizer tablet |
BPAD2 | Button for digitizer tablet |
BPAD3 | Button for digitizer tablet |
MENUBUTTON | Menu button |
Input Valuators | |
Devices | Description |
MOUSEX | x valuator on mouse |
MOUSEY | y valuator on mouse |
DIAL0...DIAL7 | Dials on dial and button box |
BPADX | x valuator on digitizer tablet |
BPADY | y valuator on digitizer tablet |
CURSORX | x valuator attached to cursor (usually MOUSEX) |
CURSORY | y valuator attached to cursor (usually MOUSEY) |
GHOST X | x ghost valuator |
GHOST Y | y ghost valuator |
TIMER0...TIMER3 | Timer devices |
Special Devices | |
Device | Description |
QFULL | Creates event when device queue overflows |
You can poll a device to determine its current state.
The getbutton subroutine polls a button and returns its current state. The number parameter specifies the number of the device you want to poll. The getbutton subroutine returns either TRUE or FALSE. TRUE indicates the button is pressed. The syntax is as follows:
Int32 getbutton(Device number)
The getdev subroutine polls up to 128 valuators and buttons at one time. You specify the number of devices you want to poll and an array of devices. (See the Input Buttons and Input Valuators tables for listings of devices.) The values parameter returns the state of each device in the corresponding array location. The syntax is as follows:
void getdev(Int32 number, Device *devices, Int16 *values)
To determine the values of valuators, use the getvaluator subroutine. You can poll any valuator, whether it is queued or not. The device parameter specifies a valuator device number, whose value reflects the current state of the device. The syntax is as follows:
Int32 getvaluator(Device device)
Input devices can make entries in the event queue. Each entry includes the device number and a device value. The qdevice subroutine enables queuing of events from an input device. The unqdevice subroutine indicates that a device is no longer queued. The isqueued subroutine tells you if a specific device is queued. The three subroutines most commonly used for queuing are qdevice, qread, and qtest.
The input queue can contain up to 101 events at a time. To check for overflow, you can queue the QFULL device. This inserts a QFULL event in the graphics input queue of a GL program at the point where queue overflow occurred. This event is returned by the qread subroutine at the point in the input queue at which data was lost.
The qdevice subroutine queues the specified device (a keyboard, button, or valuator). The device parameter specifies a device name. Each time the device changes state, an entry is made in the event queue. The syntax is as follows:
void qdevice(Device device)
The qtest subroutine returns the device number of the first entry in the event queue; if the queue is empty, the subroutine returns zero. The qtest subroutine always returns immediately to the caller and makes no changes to the queue. The syntax is as follows:
Int32 qtest()
The qread subroutine, like the qtest subroutine, returns the device number of the first entry in the event queue. However, if the queue is empty, the subroutine waits until an event is added to the queue. The qread subroutine returns the device number, writes the data part of the entry into data, and removes the entry from the queue. The syntax is as follows:
Int32 qread(Int16 data)
The qreset subroutine removes all entries from the event queue and discards them. The syntax is as follows:
void qreset()
The following C language code uses both polling and queuing to control a simple paint program. To determine the color, the program reads characters typed from the keyboard. To determine the drawing location, the program polls the LEFTMOUSE device and draws a 5-pixel-wide circle if the value for the device is TRUE.
while (TRUE) { while (qtest() || !attached) { dev=qread(&value); if (dev == ESCKEY) { exit(0); } else if (dev == REDRAW) { /* if first in queue */ reshapeviewport(); color (BLUE); clear(); } else if (dev == RKEY) { color(RED); } else if (dev == GKEY) { color(GREEN); } else if (dev == BKEY) { color (BLUE); } else if (dev == INPUTCHANGE) attached = value; } /*end of while qtest or not attached */ mdraw(); } /* end of while (TRUE) */ } /* end of main() */ mdraw() {
int ix; int iy; if (getbutton(LEFTMOUSE)) {
ix=getvaluator(MOUSEX); iy=getvaluator(MOUSEY); circfi (ix, iy, 5); } }
This example assumes that you have initialized the program appropriately, especially regarding the use of the qdevice subroutine to enable the R, G, and B keys for queuing.
You can tie a queued button to one or two valuators so that whenever the button changes state, the system records the button change and the current valuator position in the event queue. The tie subroutine takes three parameters: button and two valuators, val1 and val2. The syntax is as follows:
void tie(Device button, Device val1, Device val2)
Whenever the button changes state, three entries are made in the queue that record the current state of the button and the current position of each valuator. You can tie one valuator to a button by making the val2 parameter equal to zero. You can untie a button from valuators by making both the val1 and val2 parameters equal to zero.
Some valuators are noisy; that is, they report small fluctuations in value, indicating movement when no event has occurred. The noise subroutine allows you to set a lower limit on what constitutes a move. The value of a noisy valuator must change by at least the value set in the delta parameter before the motion is significant. The noise subroutine determines how often a queued valuator makes entries in the event queue. For example, noise(v,5) means that the valuator specified in the valuator parameter must move at least five units before a new queue entry is made. The syntax is as follows:
void noise(Device valuator, Int16 delta)
The qenter subroutine creates event queue entries. It places entries directly into the event queue. The qenter subroutine takes two 16-bit integers, given in the qtype and value parameters, and enters them into the event queue. The syntax is as follows:
void qenter(Int16 qtype, Int16 value)
Use the unqdevice subroutine to disable the queuing of events from a device. If the device has recorded events in the queue that have not been read, those events remain in the queue. (You can use the qreset subroutine to flush the event queue.) The syntax is as follows:
void unqdevice(Device dev)
The isqueued subroutine indicates whether a specific device is queued. It returns a Boolean value. A value of TRUE indicates that the device is enabled for queuing; FALSE indicates that the device is not queued. The syntax is as follows:
Int32 isqueued(Int16 device)
The blkqread subroutine returns multiple queue entries. Its first parameter, data, specifies an array of short integers, and its second parameter, number, specifies the size of the array data. The blkqread subroutine returns the number of 16-bit integers stored in the array specified in the data parameter. The array is filled alternately with device numbers and device values. Because each queue entry consists of two 16-bit words, the number of entries read is twice the number of queue entries and cannot be more than the value of the number parameter. The syntax is as follows:
Int32 blkqread(Int16 *data, Int16 number)
You can also use this subroutine when only the last entry in the event queue is of interest; for example, when a user-defined cursor is being dragged across the screen and only its final position is significant.
Keyboard, mouse, and valuator events are added to the event queue only when the application window has input focus. Input focus is controlled by the window manager. Windows with focus are usually highlighted in some fashion (typically by changing the border color of the window).
Note: In a multiwindow application, only one of the application windows can have input focus at a time.
The default window manager for your system is the AIXwindows window manager. The behavior of this window manager can be controlled by appropriately editing the ./.Xdefaults file in the user's home directory. The focus policy is controlled by the keyboardFocusPolicy resource. If the following line is added to the .Xdefaults file:
Mwm*keyboardFocusPolicy: pointer
the window with the cursor in it has input focus. Alternatively, if the following line is added to the .Xdefaults file:
Mwm*keyboardFocusPolicy: explicit
the user must click with the left mouse button inside a window to give that window input focus.
Notes:
- The window focus affects how the MOUSEX and MOUSEY events are reported. In particular, if pointer focus is selected, mouse events are reported only when the cursor is inside one of the application's windows. If explicit focus is selected, mouse events may be reported, depending on which window has the focus, even if the cursor is outside any of the application's windows.
- The focus policy determines how INPUTCHANGE events are queued. An INPUTCHANGE event is queued when an application's window receives or loses input focus. If pointer focus is selected, an INPUTCHANGE event is queued when the cursor enters or leaves an application window. If explicit focus is selected, the INPUTCHANGE token is generated only when the user makes a focus change by clicking the mouse elsewhere.
This section discusses the five types of special devices:
(See "Using the Keyboard".)
The timer devices record an event every 60th of a second. You can use a timer device to synchronize a graphics program with a real clock. To record events less frequently, use the noise subroutine. For example, if you call:
noise (TIMER0, 30)
only every 30th event is recorded, so an event queue entry is made each half second.
The cursor devices are pseudo-devices that are equivalent to the valuators currently attached to the cursor. (See "Creating a Cursor" for more information.)
Ghost devices, GHOSTX and GHOSTY, do not correspond to any physical devices, although they can be used to change a device under program control. For example, to drive the cursor from software, use attachcursor(GHOSTX,GHOSTY) to make the cursor position depend on the ghost devices. Then use the setvaluator subroutine on GHOSTX and GHOSTY to move the cursor.
The following devices can be queued by the user application to obtain window manager events. Some of these devices are queued automatically when a window is opened. Some have to be queued explicitly. All of these devices return the window ID of the window associated with the event. See "Creating and Managing Windows" for more information.
REDRAW | The window manager inserts a redraw token each time a window becomes exposed and needs to be redrawn. The REDRAW device is queued automatically when a window is opened. | |
REDRAW events are generated for a window whenever the following events occur: | ||
In the current implementation, the contents of the z-buffer are not copied to the new location on a window move; therefore, a REDRAW event is generated out of necessity. In the current implementation, REDRAW events are not generated if the overlay portion of a window has been drawn into or otherwise affected by other windows, other GL applications, or the use of the fullscrn, endfullscrn subroutines. Currently, the REDRAWOVERLAY pseudodevice is not supported. | ||
REDRAWICONIC | The window manager sends this token when a window needs to be redrawn as an icon. The REDRAWICONIC device is queued automatically when the iconsize subroutine is called. | |
DEPTHCHANGE | When queued, this device indicates an open window has been pushed or
popped. The value of the token is the gid of the window that has
changed. Use the windepth
subroutine to determine the stacking order.
| |
WINSHUT | When queued, the window manager sends this token when the Close
item is selected from the window manager's title bar option menu. If the
WINSHUT device is not queued, the Close item on the program's
window menu appears grayed-out and has no effect if selected. Do not confuse
the WINSHUT with the WINQUIT device. The WINSHUT device is used by the
applications program to shut a window; the WINQUIT device is used to quit
and exit the program.
|
|
WINQUIT | When queued, the window manager sends this token rather than killing a process when the Quit item is selected from the window manager's title bar option menu. If this device is not quit, the window manager issues a kill -15 command to the process ID of the process owning the window. | |
WINFREEZE | If queued, the window manager sends this token when a window is stowed to icons, rather than blocking the processes of the stowed windows. This device should be queued if the program is designed to draw an icon (see the iconsize subroutine) or is a multiwindow application. In other words, if one window of a multiwindow application is stowed, this device allows the owner process to continue. | |
WINTHAW | If queued, the window manager sends this token when a window is unstowed. | |
INPUTCHANGE | The window manager inserts an INPUTCHANGE token when a window is given input focus. The value inserted with the token is the window ID of the window receiving focus. A value of 0 (zero) is returned if the window given focus belongs to another application. The INPUTCHANGE device is queued automatically when a window is opened. | |
PIECECHANGE | If queued, this device indicates that a window has been exposed because another window has been moved away. This token is not sent if the window has been unstowed from an icon, or has been exposed due to a depth change. |
The application programmer can set the initial value of a valuator device with the setvaluator subroutine.
Valuators are single-value input devices: for example, the horizontal and vertical motion of mouse, or the turning of a dial. The value is a 16-bit integer. The setvaluator subroutine assigns an initial value (the init parameter) to a valuator. The min and max parameters specify the minimum and maximum values the device can assume. The syntax is as follows:
void setvaluator(Device val, Int16 init, Int16 min, Int16 max)
In addition to subroutines that poll and queue input devices, there are those that control the characteristics and behavior of the GL peripheral input/output devices. See "Using the Keyboard" for this information.