Except for the video mode change callback, all activity between the driver and
the kernel terminal emulator is initiated by the tem (terminal emulator module). This
means that the tem issues all of the ioctl commands described in this
document. The following sections provide implementation details for each ioctl command. For more information,
see the visual_io(7I) man page and the /usr/include/sys/visual_io.h include file. See Video Mode Change Callback Interface for detailed information
about the video mode change callback function.

Note - Each ioctl command should determine whether the FKIOCTL is set in the ioctl
flag argument and return EPERM if that bit is not set.

VIS_DEVINIT

The VIS_DEVINITioctl command initializes the frame buffer driver as the system console
device. This ioctl passes the address of a vis_devinit structure.

The tem first loads the address of its video mode change callback function
into the modechg_cb field of the vis_devinit structure and loads its soft state into
the modechg_arg field. The tem then issues the VIS_DEVINITioctl command. The frame buffer
driver then initializes itself and returns a summary of its configuration back to
the tem by setting the version, width, height, linebytes, depth, mode, and polledio
fields in the vis_devinit structure. The vis_devinit structure is shown in the following code.

To implement the VIS_DEVINITioctl command in the console frame buffer driver,
follow these general steps:

Define a struct to contain the console-specific state. This structure is private to the console frame buffer driver. This structure is referred to as consinfo in this appendix. The consinfo structure contains information such as:

Current size of the blit buffer

Pointer to the blit buffer

Color map information

Driver rendering mode information such as line pitch

Background color

Video memory address

Terminal emulator callback address

Allocate memory:

Allocate a blit buffer large enough to store a reasonable default sized rectangle of pixels at the highest video depth. Additional memory can be allocated if an incoming request exceeds the size of the buffer. The frame buffer driver's largest font is 12×22. Assuming DEFAULT_HEIGHT is 12, DEFAULT_WIDTH is 22, and the maximum video depth is 32, the buffer size should be 8448 bytes (DEFAULT_HEIGHT × DEFAULT_WIDTH × 32).

Allocate a vis_polledio structure.

Allocate a buffer to hold a cursor. This buffer should be the size of the largest character. This buffer will not change size.

Obtain the video change callback address and callback context of the tem from modechg_cb and modechg_ctx and store this information in the consinfo structure.

Populate the vis_polledio structure with entry point addresses for the polled display, copy, and cursor functions.

Provide the appropriate information in the fields of the vis_devinit structure that was passed to the driver by the tem:

Set the version field to VIS_CONS_REV, which is a constant defined in the /usr/include/sys/visual_io.h header file.

Set the mode field to VIS_PIXEL.

Set the polledio field to the address of the vis_polledio structure.

Set the height field to the video mode height in pixels.

Set the width field to the video mode width in pixels.

Set the depth field to the frame buffer pixel depth in bytes (for example, a 32-bit pixel depth would be 4 bytes).

Set the linebytes field to the value of height × width × depth.

This information is sent from the driver to the tem by using the vis_devinit structure. This information tells the terminal emulator how to render information and pass it to the graphics driver.

Whenever the console frame buffer driver changes its video mode (specifically height, width, or depth), the driver must call the video mode change callback function of the tem to update the vis_devinit structure and to pass this structure back to the terminal emulator. The terminal emulator passes its mode change callback function address in the modechg_cb field of the vis_devinit structure. The mode change callback function has the following function signature:

As shown in the preceding typedef, the mode change callback function takes two arguments. The first argument is the modechg_arg and the second argument is the vis_devinit structure. The modechg_arg is sent from the tem to the driver during the VIS_DEVINITioctl command initialization. The driver must send the modechg_arg back to the tem with each video mode change callback.

Initialize the context of the kernel console. Specific requirements vary depending upon the capability of the graphics device. This initialization might include such steps as setting the draw engine state, initializing the palette, or locating and mapping video memory or the rendering engine so that data can be blitted onto the screen.

Return the vis_devinit structure to the caller.

VIS_DEFINI

The VIS_DEFINIioctl command releases the driver's console resources and finishes the session.

To implement the VIS_DEVFINIioctl command in the console frame buffer driver,
follow these general steps:

VIS_CONSDISPLAY

The VIS_CONSDISPLAYioctl command displays a rectangle of pixels at a specified location.
This display is also referred to as blitting a rectangle. The vis_consdisplay structure
contains the information necessary to render a rectangle at the video depth that
both the driver and the tem are using. The vis_consdisplay structure is shown
in the following code.

To implement the VIS_CONSDISPLAYioctl command in the console frame buffer driver,
follow these general steps:

Copy the vis_consdisplay structure.

Validate the display parameters. Return an error if any of the display parameters is out of range.

Calculate the size of the rectangle to be blitted into video memory. Validate this size against the size of the blit buffer created during VIS_DEVINIT. Allocate additional memory for the blit buffer if necessary.

Retrieve the blit data. This data has been prepared by the kernel terminal emulator at the agreed upon pixel depth. That depth is the same pixel depth that was conveyed by the tem during VIS_DEVINIT. The pixel depth is updated whenever the device driver changes video modes through callback to the tem. Typical pixel depths are 8-bit color map indexed, and 32-bit TrueColor.

Invalidate any user context so that user applications cannot simultaneously access the frame buffer hardware through user memory mappings. This step is neither allowed nor necessary in polled I/O mode because user applications are not running. Be sure to hold a lock so that users cannot restore the mapping through a page fault until the VIS_CONSDISPLAYioctl completes.

Establish the driver-specific console rendering context.

If the frame buffer is running in 8-bit color indexed mode, restore the kernel console color map that the tem set up through a previous VIS_PUTCMAPioctl. A lazy color map loading scheme is recommended to optimize performance. In a lazy scheme, the console frame buffer only restores colors it has actually used since the VIS_DEVINITioctl was issued.

Display the data passed from the tem at the pixel coordinates sent by the tem. You might need to transform the RGB pixel data byte order.

VIS_CONSCOPY

The VIS_CONSCOPYioctl command copies a rectangular region of pixels from one location
to another location. One use for this ioctl is to scroll.

To implement the VIS_CONSCOPYioctl command in the console frame buffer
driver, follow these general steps:

Copy the vis_conscopy structure. The vis_conscopy structure describes the source and target rectangle sizes and locations.

Validate the display parameters. Return an error if any of the display parameters is out of range.

Invalidate any user context so that user applications cannot simultaneously access the frame buffer hardware through user memory mappings. This step is neither allowed nor necessary in polled I/O mode because user applications are not running. Be sure to hold a lock so that users cannot restore the mapping through a page fault until the VIS_CONSDISPLAYioctl completes.

Call the function to copy the rectangle.

Note - For optimal performance, use the rendering engine of the graphic device to implement the copy function. You need to decide how to do the context management within the driver to set up the rendering engine for best performance.

VIS_CONSCURSOR

The VIS_CONSCURSORioctl command displays or hides a cursor. The vis_conscursor structure is shown
in the following code.

To implement the VIS_CONSCOPYioctl command in the console frame buffer driver,
follow these general steps:

Copy the vis_conscursor structure from the kernel terminal emulator.

Validate the display parameters. Return an error if any of the display parameters are out of range.

Invalidate any user context so that user applications cannot simultaneously access the frame buffer hardware through user memory mappings. This step is neither allowed nor necessary in polled I/O mode because user applications are not running. Be sure to hold a lock so that users cannot restore the mapping through a page fault until the VIS_CONSDISPLAYioctl completes.

The terminal emulator can call the VIS_CONSCOPYioctl with one of the following two actions: SHOW_CURSOR and HIDE_CURSOR. The following steps describe how to implement this functionality by reading and writing video memory. You might also be able to use the rendering engine to do this work. Whether you can use the rendering engine depends on the frame buffer hardware.

Take these steps to implement the SHOW_CURSOR functionality:

Save the pixels within the rectangle where the cursor will be drawn. These saved pixels will be needed to hide the cursor.

Scan all the pixels on the screen bounded by the rectangle where the cursor will be drawn. Within this rectangle, replace the pixels that match the specified cursor foreground color (fg_color) with white pixels. Replace the pixels that match the specified cursor background color (bg_color) with black pixels. The visual effect is of a black cursor over white text. This method works with any foreground and background color of text. Attempting to invert colors based upon color map position is not feasible. More sophisticated strategies, such as attempting color inversion using HSB coloring (Hue, Saturation, Brightness), are not necessary.

To implement the HIDE_CURSOR functionality, replace the pixels beneath the cursor rectangle with the pixels saved from the previous SHOW_CURSOR action.

VIS_PUTCMAP

The VIS_PUTCMAPioctl command establishes the console color map. The terminal emulator calls
this function to set up the color map of the kernel. The vis_cmap
structure is shown in the following code. This structure only applies to 8-bit
color indexed mode.