X Server Device Developer's Guide
  Procure somente este livro
Fazer download desta apostila em PDF

Virtual User Input Device Interface

C

This appendix discusses the manipulation of workstation data, which is mostly global data related to input and input devices. This chapter also explains the mechanism that sets up input devices to generate event codes and how a device driver conforms to the Virtual User Input Device (vuid) interface.

Virtual User Input Device (vuid)

The vuid is a possible interface between input devices and the device handler. Device drivers in OpenWindows 3.3 must read themselves and are not required to generate vuid events. Devices can generate vuid events, a variation of the vuid format, or a totally new format. The vuid format provided in this appendix is an example format.

What Kind of Devices?

Vuid is targeted to input devices that gather command data from users. Examples of these devices are: mice, keyboards, joysticks, light pens, knobs, sliders, buttons, and ascii terminals. The vuid interface is not designed to support input devices that produce extremely large amounts of data, such as input scanners, disk drives, and voice packets.

Vuid Station Codes

This section defines the layout of the address space of vuid station codes. It explains how to extend the vuid address space.

Address Space Layout

The address space for vuid events is 16-bits long, from 0 to 65535 inclusive. It is broken into 256 segments that are 256 entries long (VUID_SEG_SIZE). The top 8 bits contain a vuid segment identifier value. The bottom 8 bits contains a segment-specific value from 0 to 255. Some segments are predefined and some are available for expansion. Here is how the address space is currently broken down:
  • ASCII_DEVID (0x00) -- ASCII codes, which include META codes.
  • TOP_DEVID (0x01) -- Top codes, which are ASCII with the 9th bit on.
  • Reserved (0x02 to 0x7F) -- For Sun vuid implementations.
  • Reserved for Sun customers (0x80 to 0xFF) -- If you are writing a new vuid, you can use a segment in here.

Adding a New Segment

The central registry of virtual user input devices is usr/include/sys/vuid_event.h. To allocate a new vuid you must modify this file:
  • Choose an unused portion of the address space. Vuids from 0x00 to 0x7F are reserved for use by Sun. Vuids from 0x80 to 0xFF are reserved for Sun customers.
  • Add the new device with a *_DEVID #define in this file. Briefly describe the purpose or usage or both of the device. Mention the place where more information can be found.
  • Add the new device to the Vuid_device enumeration with a VUID_devname entry.
  • List the specific event codes in another header file that is specific to the new device. ASCII_DEVID, TOP_DEVID and WORKSTATION_DEVID events are listed in vuid_event.h.

Firm Events

A stream of firm events is what your driver is expected to emit when called through the read system call. This stream is a byte stream that encodes Firm_event structures. A firm event is a structure comprising an ID that indicates what kind of event it is, the value of the event, and a time when this event occurred; it also carries some information that allows the event's eventual consumer to maintain the complete state of its input system.

The Firm_event Structure

The firm_event structure is defined in usr/include/sys/vuid_event.h:

  typedef struct firm_event {  
       u_short          id;  
       u_char           pair_type;  
       u_char           pair;  
       int              value;  
       struct timeval time;  
  } Firm_event;  
  
  #define FE_PAIR_NONE           0  
  #define FE_PAIR_SET            1  
  #define FE_PAIR_DELTA          2  
  #define FE_PAIR_ABSOLUTE       3  

id -- is the event's unique identifier. It is either the id of an existing vuid event (if you are trying to emulate part of the vuid) or one you created.
value -- is the event's value. It is often 0 (up) or 1 (down). For valuators it is a 32-bit integer.
time -- is the event's timestamp of when the event occurred. The timestamp is not defined to be meaningful except to compare with other Firm_event time stamps. In the kernel, a call to uniqtime, which takes a pointer to a struct timeval, gets you a close-to-current unique time. In user processes, a call to gettimeofday(2) gets time from the same source (but it is not guaranteed to be unique).

Pairs

The pair_type and pair fields enable a consumer of events to maintain input state in an event-independent way. The pair field is critical for an input state maintenance package--one that is designed to know about the semantics of particular events, to maintain correct data for corresponding absolute, delta, and paired-state variables. Some examples help make this clear:
  • You have a tablet emitting absolute locations. Depending on the client, the absolute location is important (for digitizing) or the difference between the current location and the previous location is important (for computing acceleration while tracking a cursor).
  • You have a keyboard in which the user has typed ^C. Your driver first emits a SHIFT_CTRL event as the control key goes down. Next your driver emits a ^C event (one of the events from the ASCII vuid segment) as the "c" key goes down. Now the application that your are driving happens to be using the "c" key as a shift key in some specialized application.
The vuid supports a notion of updating a companion event at the same time that a single event is generated. In the first situation, your want your tablet to update companion absolute and relative event values with a single event. In the second situation, you want your keyboard to update companion ^C and "c" event values with a single event. The vuid supports this notion of updating a companion event in such a way as to be independent from these two particular cases. pair_type defines the type of companion event:
FE_PAIR_NONE -- is the common case in which pair is not defined, that is, there is no companion.
FE_PAIR_SET -- is used for ASCII controlled events in which pair is the uncontrolled base event, that is, ^C and "c" or "C", depending on the state of the shift key. The use of this pair type is not restricted to ASCII situations. This pair type simply says to set the pairth event in id's vuid segment to value.
FE_PAIR_DELTA -- identifies pair as the delta companion to id. This means that the pairth event in id's vuid segment is set to the delta of id's current value and value. Always create vuid valuator events as delta/absolute pairs. For example, the events LOC_X_DELTA and LOC_X_ABSOLUTE are pairs and the events LOC_Y_DELTA and LOC_Y_ABSOLUTE are pairs.
FE_PAIR_ABSOLUTE -- identifies pair as the absolute companion to id. This means that the pairth event in id's vuid segment is set to the sum of id's current value and value. Always create vuid valuator events as delta/absolute pairs.
As indicated, pair must be in the same vuid segment as id.

Device Controls

A vuid driver responds to a variety of device controls.

Output Mode

It is more common to start from an existing device driver that already speaks its own native protocol and flush this old protocol in favor of the vuid protocol. In this case, you might want to operate in both modes. VUID*FORMAT ioctls are used to control which byte stream format an input device emits.
VUIDSFORMAT sets the input device byte stream format to one of:
  • VUID_NATIVE -- the device's native byte stream format (it could be vuid).
  • VUID_FIRM_EVENT -- the byte stream format is Firm_events.

    An errno of ENOTTY or EINVAL indicates that a device cannot speak Firm_events.

VUIDGFORMAT gets the input device byte stream format.