VMS DECwindows Device Driver Manual
1.4 Driver Architecture
DECwindows workstation device driver software divides into multiple
driver modules, as follows:
- Class input driver
- Port input driver
- Output driver
- Common driver
The driver modularity provides flexibility and ease of coding during
driver development and ease of driver upgrades for the varied
workstation types and devices. The various driver modules communicate
by means of vector tables and shared data in the unit control block
The architecture of the software modules or basic subsystems for
workstation families with busless CPUs is shown in Figure 1-2. Input
drivers process data from the keyboard or mouse and pass it to the
server. The input drivers also process output data, such as keyboard
LED information, from the server to the keyboard. An output driver
processes graphics and windowing requests in the form of output data
that passes from the server to the monitor.
Workstation families with Q22 bus-based CPUs and VCB01/VCB02 video
controllers use the GxADRIVER modules. For these, the driver
architecture differs slightly in that the port input driver software is
part of the output driver module, as shown in Figure 1-3. However,
the class/port input characteristic of a DECwindows device interface
remains the same.
Figure 1-2 DECwindows Driver Architecture for Busless
Figure 1-3 DECwindows Driver Architecture for Q22-Bus
1.4.1 Driver/Server Interface
As shown in Figure 1-2 and Figure 1-3, the DECwindows driver
presents two interfaces to the server: a queue interface and a $QIO
The queue interface is an input event queue in memory
that is shared between the server and drivers. This queue is
interlocked for correct operation on multiprocessor workstations. The
input queue receives all input events as they are generated by the
drivers. A driver time-stamps each input event as it inserts the event
in the queue. Asynchronous input events supported by the drivers
include the following:
- Key presses and releases
- Mouse movement
- Mouse button presses and releases
The use of a single queue ensures that all input is correctly
time-ordered when the server reads it.
The $QIO interface is the second driver/server
interface, which is also common to VMS device drivers. Generally only
the DECwindows server should make $QIO calls or access the queue.
Applications should use the DECwindows library (Xlib) routines to
perform these functions.
1.4.2 Common Driver Function
The common driver (INDRIVER) is the interface between an input or an
output driver and the DECwindows server. It monitors the input queue
and supports the server protocol of the interface. The common driver
handles device-independent processing and functions that are common to
all workstations. Common driver $QIO service routines support $QIO
calls from the server. Getting device information or parsing $QIO
parameters for all the device drivers are examples of the common driver
1.4.3 Class/Port Input Driver Function
The input drivers handle input data transfers from the
keyboard, mouse, tablet, and other input devices to the common driver
and on to the server. They are based on a modular class/port
driver interface designed for VMS that allows for new input
devices or serial line hardware to be easily added. Class/port input
drivers are bound together by means of the input device's UCB data
structure and form a class/port interface. Note that parts of the VMS
terminal class/port interface model are not used by DECwindows. The VMS
terminal class/port interface is described in the OpenVMS VAX Device Support Manual.
The port drivers provided by VMS receive interrupts
from and transmit data to the hardware ports. Port drivers service
input serial lines only. These serial lines may be part of the graphics
hardware (VCB02 controller) or a standard serial line controller
(VAXstation 2000 DZ controller). Data received by the port driver is
passed to the appropriate class driver for interpretation.
The class drivers provided by VMS include the keyboard
driver (IKDRIVER) and the mouse driver (IMDRIVER). A class driver
interprets a byte stream from an input device and then formats the data
into an event packet for the input queue. Because each input device,
such as a keyboard or tablet, must interpret a different byte stream
protocol, there is one class driver per input device type on a system.
1.4.4 Output Driver Function
The output driver processes graphics and windowing requests from the
server to the screen. Output drivers manage the output functions of the
video controller. For example, the output driver performs all
device-dependent processing, such as receiving device interrupts,
manipulating the color map, drawing, and managing the current state of
the graphics hardware. Note that the output modules for Q22-bus CPUs
(GxADRIVERs) also contain port input driver software, as shown in
Some DECwindows video devices use an output queue. For instance,
drivers for color devices support an output queue, while monochrome
drivers do not. This queue is the interface for drawing operations from
the server (or applications). Like the input queue, the output queue is
in nonpaged pool shared by the driver and the server. Drawing packets
are inserted into the queue by the server. The driver removes the
packets from the queue and executes them in the queued order.
Common Driver/Server Interface
The common driver/server link defines two interface types; the common
input queue interface and the common $QIO interface. The main
DECwindows device driver interface to the server is a buffer containing
a queue of event packets formatted for the X11 standard protocol. This
chapter describes the buffer/input queue and the protocol of the
driver/server interface. Also described is the $QIO interface. The
service mechanism that supports the $QIO calls is described in
Chapter 5. Data structures referenced in this chapter are described
in detail in Appendix A.
2.1 Driver/Server Common Buffer
The common driver manages an input buffer that the driver shares with
the server. Figure 2-1 illustrates the input buffer structure with
its queues. The shared input buffer is a block allocated in nonpaged
pool. It contains a control block or header and two queues: an input
event queue and a free queue. The queues are self-relative interlocked
queues that provide an efficient communication path for frequent
driver/server operations. Using the input buffer control block (INB),
the common driver monitors each queue containing input event packets
(INPs). Each packet stored in the queue contains a forward and a
backward pointer (FLINK and BLINK) to the next and previous packet in
the self-relative queue.
Figure 2-1 Input Buffer General Structure
2.1.1 Input Queue and Motion History Buffer
The server may create a pointer motion history buffer (MHB) to improve
system response to pointer movement. The input queue always maintains
the most recent motion events along with other input device events for
the server. However, if the motion compression feature is enabled, the
server may not receive all of the motion events generated in the input
queue. If the server requires motion events that were not delivered
because of motion compression, the server can access the motion history
buffer for the older motion events.
Like the input buffer, the MHB is allocated in nonpaged pool. The
server issues an Initialize Motion History $QIO call (described in this
chapter) specifying the desired size in pages. The motion history
buffer (shown in Figure 2-2) contains a control block or header in
the first 16 bytes, followed by a ring of 8-byte motion history packets
(MHPs) throughout the remaining allocated space. Like the input buffer,
the motion history buffer contains active event packets and free
packets. When a server/driver searches the queue, the oldest motion
history event packet and free packet are located in the ring with
put and get pointers in the MHB header. Each motion
history packet contains the x and y movement with an
event timestamp. Refer to Appendix A for detailed field information.
Once an MHB is created, a pointer motion event is first stored in a
motion history packet in the MHB and then copied into an input packet
in the input buffer shared with the server. However, the server can
disable the MHB by setting the INB$V_MHB_BUSY bit, which forces the
buffering of all events by way of the input buffer only.
When motion event compression is enabled (by the Set Motion Compression
$QIO), the motion event decoder removes the oldest motion event packet
from the input queue as it inserts the newest event. Thus, the removed
events (the oldest of a large burst of pointer motion, those not yet
retrieved by the server, or both) are lost, yielding motion
compression. The number of lost motion events or motion compression
hits is stored in counter DWI$L_PTR_MOTION_COMP_HIT. If necessary, the
server program can recover lost events by accessing the motion history
buffer instead of the input queue.
Figure 2-2 Motion History Buffer General Structure
2.1.2 Input Queue Event Packet
The input packet structure (INP) defines the packet format used in the
input queue interface between the device driver and the DECwindows
server. The basic DECwindows format of the input packet, shown in
Figure 2-3, is compatible with the X event in the X Window System
Depending on the driver, some fields in the input packet of certain
events may vary. The packet illustrated in Figure 2-3 is a typical
keyboard- or mouse-generated input event for key/button transitions and
mouse motion. The first 12 bytes (3 longwords) are common to all event
types. The event information is always 32 bytes long, excluding the
forward/backward pointers (FLINK/BLINK). The FLINK and BLINK pointers
link (in proper order) all the event packets of the input queue. Refer
to Appendix A for detailed field information.
Figure 2-3 Queue Event Packet Format
2.1.3 Queue Processing of Input
There is one input queue and one free queue for each keyboard/mouse
pair for input. As each event occurs in the device, the class driver
gets a free packet from the free queue and inserts it into the input
queue. The class driver links all active keyboard and pointer event
packets in the input queue using the forward link (FLINK) and backward
link (BLINK) INP fields (see Figure 2-4).
Because there is a single input queue shared by the input devices,
packet-link pointers ensure that all events are correctly time-ordered
when they are read by the server. The size of the input queue varies
inversely with the size of the free queue; as more packets move to the
input queue, the number of free packets diminishes.
The common driver checks the queue at timed intervals to see if there
is input. During the hardware vertical retrace interval (VSYNC), the
driver checks the INPUT_QUEUE_FLINK pointer in the input buffer control
block (INB). If the queue is not empty or the queue is not being
accessed by the server, the driver wakes the server to signal the
presence of input.
When the server responds, the server processes the event data, removes
the event packet from the input queue, and inserts the packet on the
free queue. The server processes each event packet in the queue until
the queue is empty.
Figure 2-4 Input Queue and Free Queue
2.2 $QIO Common Interface
The INDRIVER module contains function decision table (FDT) routines
that make up a $QIO common interface. The $QIO common interface
provides for initialization and information requests from the server or
server extension to a device. The $QIO interface is used for infrequent
operations that do not require synchronization with input or output
requests or when notification upon completion of a request is needed.
2.3 $QIO Calls to DECwindows Drivers
This section presents the output $QIO calls used in a server that are
supported by services within the DECwindows common driver. The $QIO
system service format is presented first.
$QIO calls must be issued to a physical device, as they cannot be
directed to a pseudodevice (such as IKA0 for the keyboard decoder).
Initially, using the $ASSIGN system service, the appropriate device
name is assigned to an I/O channel. The channel number entry is
required for the chan parameter in the $QIO system
service call. Physical device names on a GPX workstation are GAA0 for
output to the screen, GAA1 for the keyboard, and GAA2 for the mouse
(see Table 1-1). Note that the DECwindows environment provides
logical names (DECW$SERVER_SCREENS, DECW$KEYBOARD, and DECW$POINTER)
located in DECW$SERVERn_TABLES to point to the physical device.
$QIO System Service
The Queue I/O Request system service queues an I/O request to a channel
associated with a device. The SYS$QIO format described next applies to
all the $QIO calls presented in this chapter. For more information on
SYS$QIO refer to OpenVMS System Services Reference Manual.
arguments efn is the event flag number of the I/O
operation. The efn argument is a longword containing
the number of the event flag.
chan is the I/O channel assigned ($ASSIGN) to the
device name to which the request is directed. The chan
argument is a longword containing the number of the I/O channel;
however, $QIO uses only the low-order word.
func is the device-specific function code specifying
the operation to be performed. The func argument is a
longword containing the function code.
iosb is the I/O status block to receive the final
completion status of the I/O operation. The iosb
argument is the address of the quadword I/O status block.
astadr is the asynchronous system trap (AST) service
routine to be executed when the I/O completes. The
astadr argument is the address of a longword that is
the entry mask to the AST routine.
astprm is the AST parameter to be passed to the AST
service routine. The astprm argument is a longword
containing the AST parameter.
p1 is the function modifier specifying the service
being called within the basic function code (IO$K_DECW_xxx).
p2 to p6 are the function-specific
parameters being passed.
2.4 Sense-Mode Calls
The FDT sense-mode routines within the common driver service the $QIO
sense mode function calls from a server. The following sense-mode calls
are supported by the DECwindows common driver:
- Get Device Information
- Sense Cursor Bounds
- Sense Keyboard Information
- Sense Keyboard LED
- Sense Motion Compression
- Sense Operator Window Key
- Sense Pointer Acceleration
- Sense Pseudomouse Key
- Sense Screen Saver Timeout
This section defines the specific argument data required for each $QIO
call within the sense-mode functions serviced by the common driver.
Each of these calls requires the IO$_SENSEMODE function code.
Get Device Information
The Get Device Information $QIO sense-mode function returns the address
and size of the device information block (DVI). The target device is
the output display. The function returns a pointer to the (read-only)
DVI block. The DVI contains static device information such as the size
of the memory frame buffer, the resolution of the screen, the number of
bits per pixel in the frame buffer, the number of cursor planes, and
the width and height of the cursor bitmap. See the DVI block in
Figure A-1 and Table A-1 for more detailed field information.
Table 2-1 provides the required argument information for the Get
Device Information $QIO call.
Sense Cursor Bounds
The Sense Cursor Bounds $QIO sense-mode function returns the cursor
(pointer) x and y screen boundaries. In a multiscreen
environment, the call is made from the server/screen that the cursor is
If the confine-cursor flag (FLAG$V_CURSOR_BOUNDED) is set to 1, the
cursor boundaries are confined to the values pointed to by longword
parameters p3 to p6. If the
confine-cursor flag is set to 0, the cursor is free to travel anywhere,
including other screens in multiscreen environments.
Much of the cursor information is stored in the UCB common output
Table 2-2 provides the required argument information for the Sense
Cursor Bounds $QIO call.
Table 2-2 Argument Data for Sense Cursor Bounds$QIO Call
IO$_SENSEMODE function code
IO$K_DECW_CURSOR_BOUNDS function modifier
Address of the confine cursor flag bit (FLAG$V_CURSOR_BOUNDED of
Address of the
x-axis left boundary (UCB$W_DECW_X1_BOUNDRY)
Address of the
y-axis top boundary (UCB$W_DECW_Y1_BOUNDRY)
Address of the
x-axis right boundary (UCB$W_DECW_X2_BOUNDRY)
Address of the
y-axis bottom boundary (UCB$W_DECW_Y2_BOUNDRY)
Sense Keyboard Information
The Sense Keyboard Information $QIO function returns the current
functional characteristics or information concerning the keyboard
device. Table 2-3 provides the argument information required for the
Sense Keyboard Information $QIO call.
Figure A-4 and Table A-4 show and define the data structure that
passes the keyboard information requested for the $QIO call.
Table 2-3 Argument Data for Sense Keyboard Information$QIO Call
IO$_SENSEMODE function code
IO$K_DECW_KB_INFO function modifier
Address of the keyboard information (characteristics) block (KIB)
Address of the longword that stores the length of the keyboard
p4, p5, p6
Set to 0