[ Next Article | Previous Article | Book Contents | Library Home | Legal | Search ]
Kernel Extensions and Device Support Programming Concepts

Chapter 8. Graphic Input Devices Subsystem

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.

open and close Subroutines

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 may 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.

read and write Subroutines

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.

ioctl Subroutines

The ioctl operations provide run-time services. The special files support the following ioctl operations:

Keyboard

IOCINFO Returns the devinfo structure.
KSQUERYID Queries the keyboard device identifier.
KSQUERYSV Queries the keyboard service vector.
KSREGRING Registers the input ring.
KSRFLUSH Flushes the input ring.
KSLED Sets and resets the keyboard LEDs.
KSCFGCLICK Configures the clicker.
KSVOLUME Sets the alarm volume.
KSALARM Sounds the alarm.
KSTRATE Sets the typematic rate.
KSTDELAY Sets the typematic delay.
KSKAP Enables and disables the keep-alive poll.
KSKAPACK Acknowledges the keep-alive poll.
KSDIAGMODE Enables and disables the diagnostics mode.
Notes:
  1. A nonactive channel processes only IOCINFO, KSQUERYID, KSQUERYSV, KSREGRING, KSRFLUSH, KSKAP, and KSKAPACK. All other ioctl subroutine calls are ignored without error.
  2. The KSLED, KSCFGCLICK, KSVOLUME, KSALARM, KSTRATE, and KSTDELAY ioctl subroutine calls return an EBUSY error in the errno global variable when the keyboard is in diagnostics mode.
  3. The KSQUERYSV ioctl subroutine call is only available when the channel is open from kernel mode (with the fp_open kernel service).
  4. The KSKAP, KSKAPACK, KSDIAGMODE ioctl subroutine calls are only available when the channel is open from user mode.

Mouse

IOCINFO Returns the devinfo structure.
MQUERYID Queries the mouse device identifier.
MREGRING Registers the input ring.
MRFLUSH Flushes the input ring.
MTHRESHOLD Sets the mouse reporting threshold.
MRESOLUTION Sets the mouse resolution.
MSCALE Sets the mouse scale.
MSAMPLERATE Sets the mouse sample rate.

Tablet

IOCINFO Returns the devinfo structure.
TABQUERYID Queries the tablet device identifier.
TABREGRING Registers the input ring.
TABFLUSH Flushes the input ring.
TABCONVERSION Sets the tablet conversion mode.
TABRESOLUTION Sets the tablet resolution.
TABORIGIN Sets the tablet origin.
TABSAMPLERATE Sets the tablet sample rate.
TABDEADZONE Sets the tablet dead zones.

GIO (Graphics I/O) Adapter

IOCINFO Returns the devinfo structure.
GIOQUERYID Returns the ID of the attached devices.

Dials

IOCINFO Returns the devinfo structure.
DIALREGRING Registers the input ring.
DIALRFLUSH Flushes the input ring.
DIALSETGRAND Sets the dial granularity.

LPFK

IOCINFO Returns the devinfo structure.
LPFKREGRING Registers the input ring.
LPFKRFLUSH Flushes the input ring.
LPFKLIGHT Sets and resets the key lights.

Input Ring

Data is obtained from graphic input devices via 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.

Management of Multiple Keyboard Input Rings

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.

Event Report Formats

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.

Note: Event report structures are placed on the input-ring without spacing. Data wraps from the end to the beginning of the reporting area. A report can be split on any byte boundary into two non-contiguous sections.

The event reports are as follows:

Keyboard
ID Specifies the report identifier.
Length Specifies the report length.
Time stamp Specifies the system time (in milliseconds).
Key position code Specifies the key position code.
Key scan code Specifies the key scan code.
Status flags Specifies the status flags.
Tablet
ID Specifies the report identifier.
Length Specifies the report length.
Time stamp Specifies the system time (in milliseconds).
Absolute X Specifies the absolute X coordinate.
Absolute Y Specifies the absolute Y coordinate.
LPFK
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.
Dials
ID Specifies the report identifier.
Length Specifies the report length.
Time stamp Specifies the system time (in milliseconds).
Number of dial changed Specifies the number of the dial changed.
Delta change Specifies delta dial rotation.
Mouse
ID Specifies the report identifier.
Length Specifies the report length.
Time stamp Specifies the system time (in milliseconds).
Delta X Specifies the delta mouse motion along the X axis.
Delta Y Specifies the delta mouse motion along the Y axis.
Button status Specifies the button status.

Keyboard Service Vector

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

Special keyboard sequences are provided for the Secure Attention Key (SAK) and the Keep Alive Poll (KAP).

Secure Attention Key

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.

Keep Alive Poll

The keyboard device driver supports a special key sequence that kills the process which 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 which owns the keyboard when the special sequence is entered on the keyboard. The process which 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.


[ Next Article | Previous Article | Book Contents | Library Home | Legal | Search ]