XFree86 server 4.x Design (DRAFT) : Data and Data Structures
Previous: Recommended driver functions
Next: Keeping Track of Bus Resources

## 8. Data and Data Structures

### 8.1. Command line data

Command line options are typically global, and are stored in global variables. These variables are read-only and are available to drivers via a function call interface. Most of these command line values are processed via helper functions to ensure that they are treated consistently by all drivers. The other means of access is provided for cases where the supplied helper functions might not be appropriate.

Some of them are:

>         xf86Verbose               verbosity level
>         xf86Bpp                   -bpp from the command line
>         xf86Depth                 -depth from the command line
>         xf86Weight                -weight from the command line
>         xf86Gamma                 -{r,g,b,}gamma from the command line
>         xf86FlipPixels            -flippixels from the command line
>         xf86ProbeOnly             -probeonly from the command line
>         defaultColorVisualClass   -cc from the command line

If we ever do allow for screen-specific command line options, we may need to rethink this.

These can be accessed in a read-only manner by drivers with the following functions:

> `int xf86GetVerbosity()`

> > Returns the value of `xf86Verbose`.

> `int xf86GetDepth()`

> > Returns the `-depth` command line setting. If not set on the command line, `-1` is returned.

> `rgb xf86GetWeight()`

> > Returns the `-weight` command line setting. If not set on the command line, `{0, 0, 0}` is returned.

> `Gamma xf86GetGamma()`

> > Returns the `-gamma` or `-rgamma`, `-ggamma`, `-bgamma` command line settings. If not set on the command line, `{0.0, 0.0, 0.0}` is returned.

> `Bool xf86GetFlipPixels()`

> > Returns `TRUE` if `-flippixels` is present on the command line, and `FALSE` otherwise.

> `const char *xf86GetServerName()`

> > Returns the name of the X server from the command line.

### 8.2. Data handling

Config file data contains parts that are global, and parts that are Screen specific. All of it is parsed into data structures that neither the drivers or most other parts of the server need to know about.

The global data is typically not required by drivers, and as such, most of it is stored in the private `xf86InfoRec`.

The screen-specific data collected from the config file is stored in screen, device, display, monitor-specific data structures that are separate from the `ScrnInfoRecs`, with the appropriate elements/fields hooked into the `ScrnInfoRecs` as required. The screen config data is held in `confScreenRec`, device data in the `GDevRec`, monitor data in the `MonRec`, and display data in the `DispRec`.

The XFree86 common layer's screen specific data (the actual data in use for each screen) is held in the `ScrnInfoRecs`. As has been outlined above, the `ScrnInfoRecs` are allocated at probe time, and it is the responsibility of the Drivers' `Probe()` and `PreInit()` functions to finish filling them in based on both data provided on the command line and data provided from the Config file. The precedence for this is:

> command line -> config file -> probed/default data

For most things in this category there are helper functions that the drivers can use to ensure that the above precedence is consistently used.

As well as containing screen-specific data that the XFree86 common layer (including essential parts of the server infrastructure as well as helper functions) needs to access, it also contains some data that drivers use internally. When considering whether to add a new field to the `ScrnInfoRec`, consider the balance between the convenience of things that lots of drivers need and the size/obscurity of the `ScrnInfoRec`.

Per-screen driver specific data that cannot be accommodated with the static `ScrnInfoRec` fields is held in a driver-defined data structure, a pointer to which is assigned to the `ScrnInfoRec`'s `driverPrivate` field. This is per-screen data that persists across server generations (as does the bulk of the static `ScrnInfoRec` data). It would typically also include the video card's saved state.

Per-screen data for other modules that the driver uses (for example, the XAA module) that is reset for each server generation is hooked into the `ScrnInfoRec` through it's `privates` field.

Once it has stabilised, the data structures and variables accessible to video drivers will be documented here. In the meantime, those things defined in the `xf86.h` and `xf86str.h` files are visible to video drivers. Things defined in `xf86Priv.h` and `xf86Privstr.h` are NOT intended to be visible to video drivers, and it is an error for a driver to include those files.

### 8.3. Accessing global data

Some other global state information that the drivers may access via functions is as follows:

> `Bool xf86ServerIsExiting()`

> > Returns `TRUE` if the server is at the end of a generation and is in the process of exiting, and `FALSE` otherwise.

> `Bool xf86ServerIsResetting()`

> > Returns `TRUE` if the server is at the end of a generation and is in the process of resetting, and `FALSE` otherwise.

> `Bool xf86ServerIsInitialising()`

> > Returns `TRUE` if the server is at the beginning of a generation and is in the process of initialising, and `FALSE` otherwise.

> `Bool xf86ServerIsOnlyProbing()`

> > Returns `TRUE` if the -probeonly command line flag was specified, and `FALSE` otherwise.

> `Bool xf86CaughtSignal()`

> > Returns `TRUE` if the server has caught a signal, and `FALSE` otherwise.

### 8.4. Allocating private data

A driver and any module it uses may allocate per-screen private storage in either the `ScreenRec` (DIX level) or `ScrnInfoRec` (XFree86 common layer level). `ScreenRec` storage persists only for a single server generation, and `ScrnInfoRec` storage persists across generations for the lifetime of the server.

The `ScreenRec` `devPrivates` data must be reallocated/initialised at the start of each new generation. This is normally done from the `ChipScreenInit()` function, and Init functions for other modules that it calls. Data allocated in this way should be freed by the driver's `ChipCloseScreen()` functions, and Close functions for other modules that it calls. A new `devPrivates` entry is allocated by calling the `AllocateScreenPrivateIndex()` function.

> `int AllocateScreenPrivateIndex()`

> > This function allocates a new element in the `devPrivates` field of all currently existing `ScreenRecs`. The return value is the index of this new element in the `devPrivates` array. The `devPrivates` field is of type `DevUnion`:

> >             typedef union _DevUnion {
> >                 pointer             ptr;
> >                 long                val;
> >                 unsigned long       uval;
> >                 pointer             (*fptr)(void);
> >             } DevUnion;

> > which allows the element to be used for any of the above types. It is commonly used as a pointer to data that the caller allocates after the new index has been allocated.

> > This function will return `-1` when there is an error allocating the new index.

The `ScrnInfoRec` `privates` data persists for the life of the server, so only needs to be allocated once. This should be done from the `ChipPreInit()` function, and Init functions for other modules that it calls. Data allocated in this way should be freed by the driver's `ChipFreeScreen()` functions, and Free functions for other modules that it calls. A new `privates` entry is allocated by calling the `xf86AllocateScrnInfoPrivateIndex()` function.

> `int xf86AllocateScrnInfoPrivateIndex()`

> > This function allocates a new element in the `privates` field of all currently existing `ScrnInfoRecs`. The return value is the index of this new element in the `privates` array. The `privates` field is of type `DevUnion`:

> >             typedef union _DevUnion {
> >                 pointer             ptr;
> >                 long                val;
> >                 unsigned long       uval;
> >                 pointer             (*fptr)(void);
> >             } DevUnion;

> > which allows the element to be used for any of the above types. It is commonly used as a pointer to data that the caller allocates after the new index has been allocated.

> > This function will not return when there is an error allocating the new index. When there is an error it will cause the server to exit with a fatal error. The similar function for allocation privates in the `ScreenRec` (`AllocateScreenPrivateIndex()`) differs in this respect by returning `-1` when the allocation fails.

XFree86 server 4.x Design (DRAFT) : Data and Data Structures
Previous: Recommended driver functions
Next: Keeping Track of Bus Resources