XFree86 X server ``New Design'' (DRAFT) : Helper Functions
Previous: The Loader
Next: The vgahw module

18. Helper Functions

This section describe ``helper'' functions that video driver might find useful. While video drivers are not required to use any of these to be considered ``compliant'', the use of appropriate helpers is strongly encouraged to improve the consistency of driver behaviour.

18.1. Functions for printing messages

ErrorF(const char *format, ...)

This is the basic function for writing to the error log (typically stderr and/or a log file). Video drivers should usually avoid using this directly in favour of the more specialised functions described below. This function is useful for printing messages while debugging a driver.

FatalError(const char *format, ...)

This prints a message and causes the Xserver to abort. It should rarely be used within a video driver, as most error conditions should be flagged by the return values of the driver functions. This allows the higher layers to decide how to proceed. In rare cases, this can be used within a driver if a fatal unexpected condition is found.

xf86ErrorF(const char *format, ...)

This is like ErrorF(), except that the message is only printed when the Xserver's verbosity level is set to the default (1) or higher. It means that the messages are not printed when the server is started with the -quiet flag. Typically this function would only be used for continuing messages started with one of the more specialised functions described below.

xf86ErrorFVerb(int verb, const char *format, ...)

Like xf86ErrorF(), except the minimum verbosity level for which the message is to be printed is given explicitly. Passing a verb value of zero means the message is always printed. A value higher than 1 can be used for information would normally not be needed, but which might be useful when diagnosing problems.

xf86Msg(MessageType type, const char *format, ...)

This is like xf86ErrorF(), except that the message is prefixed with a marker determined by the value of type. The marker is used to indicate the type of message (warning, error, probed value, config value, etc). Note the xf86Verbose value is ignored for messages of type X_ERROR.

The marker values are:

X_PROBED
Value was probed.
X_CONFIG
Value was given in the config file.
X_DEFAULT
Value is a default.
X_CMDLINE
Value was given on the command line.
X_NOTICE
Notice.
X_ERROR
Error message.
X_WARNING
Warning message.
X_INFO
Informational message.
X_NONE
No prefix.

xf86MsgVerb(MessageType type, int verb, const char *format, ...)

Like xf86Msg(), but with the verbosity level given explicitly.

xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)

This is like xf86Msg() except that the driver's name (the name field of the ScrnInfoRec) followed by the scrnIndex in parentheses is printed following the prefix. This should be used by video drivers in most cases as it clearly indicates which driver/screen the message is for. If scrnIndex is negative, this function behaves exactly like xf86Msg().

NOTE: This function can only be used after the ScrnInfoRec and its name field have been allocated. That means that it can not be used before the END of the ChipProbe() function. Prior to that, use xf86Msg(), providing the driver's name explicitly. No screen number can be supplied at that point.

xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
          const char *format, ...)

Like xf86DrvMsg(), but with the verbosity level given explicitly.

18.2. Functions for setting values based on command line and config file

Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp,
          int fbbpp, int depth24flags)

This function sets the depth, pixmapBPP and bitsPerPixel fields of the ScrnInfoRec. It also determines the defaults for display-wide attributes and pixmap formats the screen will support, and finds the Display subsection that matches the depth/bpp. This function should normally be called very early from the ChipPreInit() function.

It requires that the confScreen field of the ScrnInfoRec be initialised prior to calling it. This is done by the XFree86 common layer prior to calling ChipPreInit().

The parameters passed are:

depth

driver's preferred default depth if no other is given. If zero, use the overall server default.

bpp

Same, but for the pixmap bpp.

fbbpp

Same, but for the framebuffer bpp.

depth24flags

Flags that indicate the level of 24/32bpp support and whether conversion between different framebuffer and pixmap formats is supported. The flags for this argument are defined as follows, and multiple flags may be ORed together:

NoDepth24Support

No depth 24 formats supported
Support24bppFb
24bpp framebuffer supported
Support32bppFb
32bpp framebuffer supported
SupportConvert24to32
Can convert 24bpp pixmap to 32bpp fb
SupportConvert32to24
Can convert 32bpp pixmap to 24bpp fb
ForceConvert24to32
Force 24bpp pixmap to 32bpp fb conversion
ForceConvert32to24
Force 32bpp pixmap to 24bpp fb conversion

It uses the command line, config file, and default values in the correct order of precedence to determine the depth and bpp values. It is up to the driver to check the results to see that it supports them. If not the ChipPreInit() function should return FALSE.

If only one of depth/bpp is given, the other is set to a reasonable (and consistent) default.

If a driver finds that the initial depth24flags it uses later results in a fb format that requires more video memory than is available it may call this function a second time with a different depth24flags setting.

On success, the return value is TRUE. On failure it prints an error message and returns FALSE.

The following fields of the ScrnInfoRec are initialised by this function:

depth, bitsPerPixel, display, imageByteOrder, bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats, formats, fbFormat.

void xf86PrintDepthBpp(scrnInfoPtr scrp)

This function can be used to print out the depth and bpp settings. It should be called after the final call to xf86SetDepthBpp().

Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)

This function sets the weight, mask, offset and rgbBits fields of the ScrnInfoRec. It would normally be called fairly early in the ChipPreInit() function for depths > 8bpp.

It requires that the depth and display fields of the ScrnInfoRec be initialised prior to calling it.

The parameters passed are:

weight

driver's preferred default weight if no other is given. If zero, use the overall server default.

mask

Same, but for mask.

It uses the command line, config file, and default values in the correct order of precedence to determine the weight value. It derives the mask and offset values from the weight and the defaults. It is up to the driver to check the results to see that it supports them. If not the ChipPreInit() function should return FALSE.

On success, this function prints a message showing the weight values selected, and returns TRUE.

On failure it prints an error message and returns FALSE.

The following fields of the ScrnInfoRec are initialised by this function:

weight, mask, offset.

Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)

This function sets the defaultVisual field of the ScrnInfoRec. It would normally be called fairly early from the ChipPreInit() function.

It requires that the depth and display fields of the ScrnInfoRec be initialised prior to calling it.

The parameters passed are:

visual

driver's preferred default visual if no other is given. If -1, use the overall server default.

It uses the command line, config file, and default values in the correct order of precedence to determine the default visual value. It is up to the driver to check the result to see that it supports it. If not the ChipPreInit() function should return FALSE.

On success, this function prints a message showing the default visual selected, and returns TRUE.

On failure it prints an error message and returns FALSE.

Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)

This function sets the gamma field of the ScrnInfoRec. It would normally be called fairly early from the ChipPreInit() function in cases where the driver supports gamma correction.

It requires that the monitor field of the ScrnInfoRec be initialised prior to calling it.

The parameters passed are:

gamma

driver's preferred default gamma if no other is given. If zero (< 0.01), use the overall server default.

It uses the command line, config file, and default values in the correct order of precedence to determine the gamma value. It is up to the driver to check the results to see that it supports them. If not the ChipPreInit() function should return FALSE.

On success, this function prints a message showing the gamma value selected, and returns TRUE.

On failure it prints an error message and returns FALSE.

void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)

This function sets the xDpi and yDpi fields of the ScrnInfoRec. The driver can specify preferred defaults by setting x and y to non-zero values. The -dpi command line option overrides all other settings. Otherwise, if the DisplaySize entry is present in the screen's Monitor config file section, it is used together with the virtual size to calculate the dpi values. This function should be called after all the mode resolution has been done.

void xf86SetBlackWhitePixels(ScrnInfoPtr pScrn)

This functions sets the blackPixel and whitePixel fields of the ScrnInfoRec according to whether or not the -flipPixels command line options is present.

const char *xf86GetVisualName(int visual)

Returns a printable string with the visual name matching the numerical visual class provided. If the value is outside the range of valid visual classes, NULL is returned.

18.3. Primary Mode functions

The primary mode helper functions are those which would normally be used by a driver, unless it has unusual requirements which cannot be catered for the by the helpers.

int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
          char **modeNames, ClockRangePtr clockRanges,
          int *linePitches, int minPitch, int maxPitch,
          int pitchInc, int minHeight, int maxHeight,
          int virtualX, int virtualY,
          unsigned long apertureSize,
          LookupModeFlags strategy)

This function basically selects the set of modes to use based on those available and the various constraints. It also sets some other related parameters. It is normally called near the end of the ChipPreInit() function.

The parameters passed to the function are:

availModes

List of modes available for the monitor.

modeNames

List of mode names that the screen is requesting.

clockRanges

A list of clock ranges allowed by the driver. Each range includes whether interlaced or multiscan modes are supported for that range. See below for more on clockRanges.

linePitches

List of supported line pitches supported by the driver. This is optional and should be NULL when not used.

minPitch

Minimum line pitch supported by the driver. This must be supplied when linePitches is NULL, and is ignored otherwise.

maxPitch

Maximum line pitch supported by the driver. This is required when minPitch is required.

pitchInc

Granularity of horizontal pitch values as supported by the chipset. This is expressed in bits. This must be supplied.

minHeight

minimum virtual height allowed. If zero, no limit is imposed.

maxHeight

maximum virtual height allowed. If zero, no limit is imposed.

virtualX

If greater than zero, this is the virtual width value that will be used. Otherwise, the virtual width is chosen to be the smallest that can accommodate the modes selected.

virtualY

If greater than zero, this is the virtual height value that will be used. Otherwise, the virtual height is chosen to be the smallest that can accommodate the modes selected.

apertureSize

The size (in bytes) of the aperture used to access video memory.

strategy

The strategy to use when choosing from multiple modes with the same name. The options are:

LOOKUP_DEFAULT

???
LOOKUP_BEST_REFRESH
mode with best refresh rate
LOOKUP_CLOSEST_CLOCK
mode with closest matching clock
LOOKUP_LIST_ORDER
first usable mode in list

The following options can also be combined (OR'ed) with one of the above:

LOOKUP_CLKDIV2

Allow halved clocks
LOOKUP_OPTIONAL_TOLERANCES
Allow missing horizontal sync and/or vertical refresh ranges in the XF86Config Monitor section

LOOKUP_OPTIONAL_TOLERANCES should only be specified when the driver can ensure all modes it generates can sync on, or at least not damage, the monitor or digital flat panel. Horizontal sync and/or vertical refresh ranges specified by the user will still be honoured (and acted upon).

This function requires that the following fields of the ScrnInfoRec are initialised prior to calling it:

clock[]

List of discrete clocks (when non-programmable)
numClocks
Number of discrete clocks (when non-programmable)
progClock
Whether the clock is programmable or not
monitor
Pointer to the applicable XF86Config monitor section
fdFormat
Format of the screen buffer
videoRam
total video memory size (in bytes)
maxHValue
Maximum horizontal timing value allowed
maxVValue
Maximum vertical timing value allowed
xInc
Horizontal timing increment in pixels (defaults to 8)

This function fills in the following ScrnInfoRec fields:

modePool

A subset of the modes available to the monitor which are compatible with the driver.

modes

One mode entry for each of the requested modes, with the status field of each filled in to indicate if the mode has been accepted or not. This list of modes is a circular list.

virtualX

The resulting virtual width.

virtualY

The resulting virtual height.

displayWidth

The resulting line pitch.

virtualFrom

Where the virtual size was determined from.

The first stage of this function checks that the virtualX and virtualY values supplied (if greater than zero) are consistent with the line pitch and maxHeight limitations. If not, an error message is printed, and the return value is -1.

The second stage sets up the mode pool, eliminating immediately any modes that exceed the driver's line pitch limits, and also the virtual width and height limits (if greater than zero). For each mode removed an informational message is printed at verbosity level 2. If the mode pool ends up being empty, a warning message is printed, and the return value is 0.

The final stage is to lookup each mode name, and fill in the remaining parameters. If an error condition is encountered, a message is printed, and the return value is -1. Otherwise, the return value is the number of valid modes found (0 if none are found).

Even if the supplied mode names include duplicates, no two names will ever match the same mode. Furthermore, if the supplied mode names do not yield a valid mode (including the case where no names are passed at all), the function will continue looking through the mode pool until it finds a mode that survives all checks, or until the mode pool is exhausted.

A message is only printed by this function when a fundamental problem is found. It is intended that this function may be called more than once if there is more than one set of constraints that the driver can work within.

If this function returns -1, the ChipPreInit() function should return FALSE.

clockRanges is a linked list of clock ranges allowed by the driver. If a mode doesn't fit in any of the defined clockRanges, it is rejected. The first clockRange that matches all requirements is used.

clockRanges contains the following fields:

minClock
maxClock

The lower and upper mode clock bounds for which the rest of the clockRange parameters apply. Since these are the mode clocks, they are not scaled with the ClockMulFactor and ClockDivFactor. It is up to the driver to adjust these values if they depend on the clock scaling factors.

clockIndex

(not used yet) -1 for programmable clocks

interlaceAllowed

TRUE if interlacing is allowed for this range

doubleScanAllowed

TRUE if doublescan or multiscan is allowed for this range

ClockMulFactor
ClockDivFactor

Scaling factors that are applied to the mode clocks ONLY before selecting a clock index (when there is no programmable clock) or a SynthClock value. This is useful for drivers that support pixel multiplexing or that need to scale the clocks because of hardware restrictions (like sending 24bpp data to an 8 bit RAMDAC using a tripled clock).

Note that these parameters describe what must be done to the mode clock to achieve the data transport clock between graphics controller and RAMDAC. For example for 2:1 pixel multiplexing, two pixels are sent to the RAMDAC on each clock. This allows the RAMDAC clock to be half of the actual pixel clock. Hence, ClockMulFactor=1 and ClockDivFactor=2. This means that the clock used for clock selection (ie, determining the correct clock index from the list of discrete clocks) or for the SynthClock field in case of a programmable clock is: (mode->Clock * ClockMulFactor) / ClockDivFactor.

PrivFlags

This field is copied into the mode->PrivFlags field when this clockRange is selected by xf86ValidateModes(). It allows the driver to find out what clock range was selected, so it knows it needs to set up pixel multiplexing or any other range-dependent feature. This field is purely driver-defined: it may contain flag bits, an index or anything else (as long as it is an INT).

Note that the mode->SynthClock field is always filled in by xf86ValidateModes(): it will contain the ``data transport clock'', which is the clock that will have to be programmed in the chip when it has a programmable clock, or the clock that will be picked from the clocks list when it is not a programmable one. Thus:

mode->SynthClock =
          (mode->Clock * ClockMulFactor) / ClockDivFactor

void xf86PruneDriverModes(ScrnInfoPtr scrp)

This function deletes modes in the modes field of the ScrnInfoRec that have been marked as invalid. This is normally run after having run xf86ValidateModes() for the last time. For each mode that is deleted, a warning message is printed out indicating the reason for it being deleted.

void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)

This function fills in the Crtc* fields for all the modes in the modes field of the ScrnInfoRec. The adjustFlags parameter determines how the vertical CRTC values are scaled for interlaced modes. They are halved if it is INTERLACE_HALVE_V. The vertical CRTC values are doubled for doublescan modes, and are further multiplied by the VScan value.

This function is normally called after calling xf86PruneDriverModes().

void xf86PrintModes(ScrnInfoPtr scrp)

This function prints out the virtual size setting, and the line pitch being used. It also prints out one line for each mode being used, including its pixel clock, horizontal sync rate, refresh rate, and whether it is interlaced or multiscan.

This function is normally called after calling xf86SetCrtcForModes().

18.4. Secondary Mode functions

The secondary mode helper functions are functions which are normally used by the primary mode helper functions, and which are not normally called directly by a driver. If a driver has unusual requirements and needs to do its own mode validation, it might be able to make use of some of these secondary mode helper functions.

int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
          int *divider)

This function returns the index of the closest clock to the frequency freq given (in kHz). It assumes that the number of clocks is greater than zero. It requires that the numClocks and clock fields of the ScrnInfoRec are initialised. The allowDiv2 field determines if the clocks can be halved. The *divider return value indicates whether clock division is used when determining the clock returned.

This function is only for non-programmable clocks.

const char *xf86ModeStatusToString(ModeStatus status)

This function converts the status value to a descriptive printable string.

ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
          ClockRangePtr clockRanges, LookupModeFlags strategy)

This function takes a pointer to a mode with the name filled in, and looks for a mode in the modePool list which matches. The parameters of the matching mode are filled in to *modep. The clockRanges and strategy parameters are as for the xf86ValidateModes() function above.

This function requires the modePool, clock[], numClocks and progClock fields of the ScrnInfoRec to be initialised before being called.

The return value is MODE_OK if a mode was found. Otherwise it indicates why a matching mode could not be found.

ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp,
          DisplayModePtr mode, ClockRangePtr clockRanges,
          LookupModeFlags strategy, int maxPitch,
          int virtualX, int virtualY)

This function checks the passed mode against some basic driver constraints. Apart from the ones passed explicitly, the maxHValue and maxVValue fields of the ScrnInfoRec are also used. If the ValidMode field of the ScrnInfoRec is set, that function is also called to check the mode. Next, the mode is checked against the monitor's constraints.

If the mode is consistent with all constraints, the return value is MODE_OK. Otherwise the return value indicates which constraint wasn't met.

void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)

This function deletes the mode given from the modeList. It never prints any messages, so it is up to the caller to print a message if required.

18.5. Functions for handling strings and tokens

Tables associating strings and numerical tokens combined with the following functions provide a compact way of handling strings from the config file, and for converting tokens into printable strings. The table data structure is:

typedef struct {
    int                 token;
    const char *        name;
} SymTabRec, *SymTabPtr;

A table is an initialised array of SymTabRec. The tokens must be non-negative integers. Multiple names may be mapped to a single token. The table is terminated with an element with a token value of -1 and NULL for the name.

const char *xf86TokenToString(SymTabPtr table, int token)

This function returns the first string in table that matches token. If no match is found, NULL is returned (NOTE, older versions of this function would return the string "unknown" when no match is found).

int xf86StringToToken(SymTabPtr table, const char *string)

This function returns the first token in table that matches string. The xf86NameCmp() function is used to determine the match. If no match is found, -1 is returned.

18.6. Functions for finding which config file entries to use

These functions can be used to select the appropriate config file entries that match the detected hardware. They are described above in the Probe and Available Functions sections.

18.7. Probing discrete clocks on old hardware

The xf86GetClocks() function may be used to assist in finding the discrete pixel clock values on older hardware.

void xf86GetClocks(ScrnInfoPtr pScrn, int num,
          Bool (*ClockFunc)(ScrnInfoPtr, int),
          void (*ProtectRegs)(ScrnInfoPtr, Bool),
          void (*BlankScreen)(ScrnInfoPtr, Bool),
          int vertsyncreg, int maskval, int knownclkindex,
          int knownclkvalue)

This function uses a comparative sampling method to measure the discrete pixel clock values. The number of discrete clocks to measure is given by num. clockFunc is a function that selects the n'th clock. It should also save or restore any state affected by programming the clocks when the index passed is CLK_REG_SAVE or CLK_REG_RESTORE. ProtectRegs is a function that does whatever is required to protect the hardware state while selecting a new clock. BlankScreen is a function that blanks the screen. vertsyncreg and maskval are the register and bitmask to check for the presence of vertical sync pulses. knownclkindex and knownclkvalue are the index and value of a known clock. These are the known references on which the comparative measurements are based. The number of clocks probed is set in pScrn->numClocks, and the probed clocks are set in the pScrn->clock[] array. All of the clock values are in units of kHz.

void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)

Print out the pixel clocks scrp->clock[]. from indicates whether the clocks were probed or from the config file.

18.8. Other helper functions

Bool xf86IsUnblank(int mode)

Returns FALSE when the screen saver mode specified by mode requires the screen be unblanked, and TRUE otherwise. The screen saver modes that require blanking are SCREEN_SAVER_ON and SCREEN_SAVER_CYCLE, and the screen saver modes that require unblanking are SCREEN_SAVER_OFF and SCREEN_SAVER_FORCER. Drivers may call this helper from their SaveScreen() function to interpret the screen saver modes.


XFree86 X server ``New Design'' (DRAFT) : Helper Functions
Previous: The Loader
Next: The vgahw module