The graphic input devices subsystem includes the keyboard/sound, mouse, tablet, dials, and lighted programmable-function keys (LPFK) devices. These devices provide operator input primarily to graphic applications. However, the keyboard can provide system input by means of the console.
The program interface to the input device drivers is described in the inputdd.h header file. This header file is available as part of the bos.adt.graphics fileset.
An open subroutine call is used to create a channel between the caller and a graphic input device driver. The keyboard supports two such channels. The most recently created channel is considered the active channel. All other graphic input device drivers support only one channel. The open subroutine call is processed normally, except that the OFLAG and MODE parameters are ignored. The keyboard provides support for the fp_open subroutine call; however, only one kernel mode channel can be open at any given time. The fp_open subroutine call returns EACCES for all other graphic input devices.
The close subroutine is used to remove a channel created by the open subroutine call.
The graphic input device drivers do not support read or write operations. A read or write to a graphic input device special file behaves as if a read or write was made to /dev/null.
The ioctl operations provide run-time services. The special files support the following ioctl operations:
IOCINFO | Returns the devinfo structure. |
GIOQUERYID | Returns the ID of the attached devices. |
IOCINFO | Returns the devinfo structure. |
DIALREGRING | Registers the input ring. |
DIALRFLUSH | Flushes the input ring. |
DIALSETGRAND | Sets the dial granularity. |
IOCINFO | Returns the devinfo structure. |
LPFKREGRING | Registers the input ring. |
LPFKRFLUSH | Flushes the input ring. |
LPFKLIGHT | Sets and resets the key lights. |
Data is obtained from graphic input devices by way of a circular First-In First-Out (FIFO) queue or input ring, rather than with a read subroutine call. The memory address of the input ring is registered with an ioctl (or fp_ioctl) subroutine call. The program that registers the input ring is the owner of the ring and is responsible for allocating, initializing, and freeing the storage associated with the ring. The same input ring can be shared by multiple devices.
The input ring consists of the input ring header followed by the reporting area. The input ring header contains the reporting area size, the head pointer, the tail pointer, the overflow flag, and the notification type flag. Before registering an input ring, the ring owner must ensure that the head and tail pointers contain the starting address of the reporting area. The overflow flag must also be cleared and the size field set equal to the number of bytes in the reporting area. After the input ring has been registered, the owner can modify only the head pointer and the notification type flag.
Data stored on the input ring is structured as one or more event reports. Event reports are placed at the tail of the ring by the graphic input device drivers. Previously queued event reports are taken from the head of the input ring by the owner of the ring. The input ring is empty when the head and tail locations are the same. An overflow condition exists if placement of an event on the input ring would overwrite data that has not been processed. Following an overflow, new event reports are not placed on the input ring until the input ring is flushed via an ioctl subroutine or service vector call.
The owner of the input ring is notified when an event is available for processing via a SIGMSG signal or via callback if the channel was created by an fp_open subroutine call. The notification type flag in the input ring header specifies whether the owner should be notified each tine an event is placed on the ring or only when an event is placed on an empty ring.
When multiple keyboard channels are opened, keyboard events are placed on the input ring associated with the most recently opened channel. When this channel is closed, the alternate channel is activated and keyboard events are placed on the input ring associated with that channel.
Each event report consists of an identifier followed by the report size in bytes, a time stamp (system time in milliseconds), and one or more bytes of device-dependent data. The value of the identifier is specified when the input ring is registered. The program requesting the input-ring registration is responsible for identifier uniqueness within the input-ring scope.
The event reports are as follows:
ID | Specifies the report identifier. |
Length | Specifies the report length. |
Time stamp | Specifies the system time (in milliseconds). |
Number of key pressed | Specifies the number of the key pressed. |
ID | Specifies the report identifier. |
Length | Specifies the report length. |
Time stamp | Specifies the system time (in milliseconds). |
Format | Specifies the format of additional
fields.
Format 1:
|
The keyboard service vector provides a limited set of keyboard-related and sound-related services for kernel extensions. The following services are available:
The address of the service vector is obtained with the fp_ioctl subroutine call during a non-critical period. The kernel extension can later invoke the service using an indirect call as follows:
(*ServiceVector[ServiceNumber]) (dev_t DeviceNumber, caddr_t Arg);
where:
If successful, the function returns a value of 0 is returned. Otherwise, the function returns an error number defined in the errno.h file. Flush-queue and enable/disable-SAK requests are always processed, but alarm requests are ignored if the kernel extension's channel is inactive.
The following example uses the service vector to sound the alarm:
/* pinned data structures */ /* This example assumes that pinning is done elsewhere. */ int (**ksvtbl) (); struct ksalarm alarm; dev_t devno; /* get address of service vector */ /* This should be done in a noncritical section */ if (fp_ioctl(fp, KSQUERYSV, &ksvtbl, 0)) { /* error recovery */ } . . . /* critical section */ /* sound alarm for 1 second using service vector */ alarm.duration = 128; alarm.frequency = 100; if ((*ksvtbl[KSVALARM]) (devno, &alarm)) { /* error recovery */ }
Special keyboard sequences are provided for the Secure Attention Key (SAK) and the Keep Alive Poll (KAP).
The user requests a secure shell by keying a secure attention. The keyboard driver interprets the key sequence CTRL x r as the SAK. An indirect call using the keyboard service vector enables and disables the detection of this key sequence. If detection of the SAK is enabled, a SAK causes the SAK callback to be invoked. The SAK callback is invoked even if the input ring is inactive due to a user process issuing an open to the keyboard special file. The SAK callback runs within the interrupt environment.
The keyboard device driver supports a special key sequence that kills the process that owns the keyboard. This sequence must first be defined with a KSKAP ioctl operation. After this sequence is defined, the keyboard device driver sends a SIGKAP signal to the process that owns the keyboard when the special sequence is entered on the keyboard. The process that owns the keyboard must acknowledge the KSKAP signal with a KSKAPACK ioctl within 30 seconds or the keyboard driver will terminate the process with a SIGKILL signal. The KAP is enabled on a per-channel basis and is unavailable if the channel is owned by a kernel extension.