Hands-on Projects for the Linux Graphics Subsystem

The second part of the parsing process cover at the point the first part ended, which is the part of xf86HandleConfigFile() after the comment:

* now we convert part of the information contained in the parser
* structures into our own structures.
* The important part here is to figure out which Screen Sections
* in the XF86Config file are active so that we can piece together
* the modes that we need later down the road.
* And while we are at it, we'll decode the rest of the stuff as well

Before this we have to discuss more thoroughly the Serverlayout Section of the xorg.conf.

ServerLayout section

2.4. ServerLayout section
The ServerLayout section is a new section that is used to identify which Screen
sections are to be used in a multi-headed configuration, and the relative layout
of those screens. It also identifies which InputDevice sections are to be used.
Each ServerLayout section has an identifier, a list of Screen section
identifiers, and a list of InputDevice section identifiers. ServerFlags options
may also be included in a ServerLayout section, making it possible to override
the global values in the ServerFlags section.
A ServerLayout section can be made active by being referenced on the command
line. In the absence of this, a default will be chosen (the first one found).
The screen names may optionally be followed by a number specifying the preferred
screen number, and optionally by information specifying the physical
positioning of the screen, either in absolute terms or relative to another
screen (or screens).

The ServerLayout sections are at the highest level. They bind together the input
and output devices that will be used in a session. The input devices are
described in the InputDevice sections. Output devices usually consist of
multiple independent components (e.g., a graphics board and a monitor). These
multiple components are bound together in the Screen sections, and it is these
that are referenced by the ServerLayout section. Each Screen section binds
together a graphics board and a monitor. The graphics boards are described in
the Device sections, and the monitors are described in the Monitor sections.

The parsing process of the previous section fills the global XF86ConfigRec with the info xorg.conf provides and the Table 1 of the previous section illustrates how some fields of XF86ConfigRec are filled. Before we proceed we focus in the XF86ConfLayoutPtr field that will be used in the current section. As we find in Table 1 function xf86parseLayoutSection() collects info from xorg.conf to a XF86ConfLayoutPtr pointer.

XF86ConfLayoutRec, which points to XF86ConfLayoutRec is defined in xf86Parser.h as:

xf86parseLayoutSection()

In the images below we follow this example. This implies the presence of two screens (XF86ConfScreenRec) and the two corresponding devices (XF86ConfDeviceRec):

We continue then at the next step in xf86HandleConfigFile():

/* First check if a layout section is present, and if it is valid. */
if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
if (xf86ScreenName == NULL) {
xf86Msg(X_WARNING,
"No Layout section. Using the first Screen section.\n");
}
if (!configImpliedLayout(&xf86ConfigLayout,
xf86configptr->conf_screen_lst)) {
xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
return CONFIG_PARSE_ERROR;
}

xf86ConfigLayout
defined in xf86Globals.c is the data structure that is used at this point to represent the Layout section information. It collects the information parsed by xorg.conf and stored previously in the XF86ConfLayoutPtr field of the global XF86ConfigRec. This process is done in configLayout() (or in configImpliedLayout()).

xf86ScreenName is initially NULL. The command line option "-screen", if there is one, provides to this variable a value by calling ddxProcessArgument(), which processes command line options. Along with the following variable - command line options it is defined in xf86Globals.c:

Those variables represent values for the Layout, Screen, Pointer and Keyboard respectively that were passed to the X Server as command line arguments.

configImpliedLayout()

configImpliedLayout() is used in the case that there is no layout section. It looks first for a "-screen" command line option and in this case xf86findScreen() is used to lookup the screen given from the command line from the conf_screen_lst list of the global XF86ConfigRec. If no command line argument is passed to the X Server configImpliedLayout() tries to find the first Screen section and sets it as the only active screen. This requires that xorg.conf provided a screen section (i.e. conf_screen <> NULL). In this case configImpliedLayout() allocates a struct confScreenRec for the first field of the screenLayoutRec (slp[0].screen) and fills it by calling configScreen() as:

configScreen(slp[0].screen, conf_screen, 0, from)

Next we continue with xf86HandleConfigFile() at the point of the source code where the previous example applies, that is no configImpliedLayout(), since there is a "ServerLayout" section. Therefore configLayout() is called:

configLayout() searches for the active layout section in xorg.conf. From the DESIGN document we read:

"A ServerLayout section can be made active by being referenced on the command
line. In the absence of this, a default will be chosen (the first one found)."

If a layout is passed as command line argument (and therefore variable xf86LayoutName is non-NULL) xf86findLayout() is called to lookup the argument at the conf_layout conf_layout_lst list of the global XF86ConfigRec and conf_layout points to this otherwise it points to the first node of the list.

A screenLayoutRec is allocated and is filled with the approptriate number of confScreenRec according to the screen number of the ServerLayout section.

Next the conf_layout->lay_adjacency_lst is examined to find the number of screen references in the ServerLayout section. For each reference a confScreenRec is allocated.

configLayout() fills the serverLayoutRec that the serverLayoutPtr of its first argument points to. It uses the layout info from the parsed xorg.conf file stored in conf_layout (the second argument of configLayout) which is actually the XF86ConfLayoutPtr field of the global struct XF86ConfigRec.

For each screen found in conf_layout->lay_adjacency_lst function configScreen() is called as:

================================================================================
THIS STRUCT IS PASSED AS ARGUMENT AND IS FILLED IN configLayout()
================================================================================
Notice: the previous three yellow boxed structures along with the serverLayoutRec,
are the basic structures that are formed in this section from the parsed
xorg.conf file, which is represented here by the XF86ConfLayoutRec (see images
at the top of page).
typedef struct _serverlayoutrec {
char * id;
screenLayoutPtr screens;
GDevPtr inactives;
IDevPtr inputs;
pointer options;
} serverLayoutRec, *serverLayoutPtr;
===============================================================================
serverLayoutPtr is filled in the following lines of configLayout():
servlayoutp->id = conf_layout->lay_identifier;
servlayoutp->screens = slp;
servlayoutp->inactives = gdp;
servlayoutp->inputs = indp;
servlayoutp->options = conf_layout->lay_option_lst;
===============================================================================

configScreen()

configScreen() fills the confScreenRec fields with the values taken from all nodes of conf_layout->lay_adjacency_lst->adj_screen:

configDevice() creates a device (pointer GDevPtr) from conf_device, the config info of xorg.conf. As mentioned in the boxed comment previously conf_device is created by xf86parseDeviceSection(). configDevice() is implemented as:

We make a case study here for the device field of screenp, since this will provide the dev struct for the sections that follow.

Consider the screenp->device field. This is filled by configDevice() using the value of the second argument conf_screen->scrn_device. Struct conf_screen was acquired in section 3.2.2.1. Table 1 of this section shows that xf86parseScreenSection() returns information from xorg.conf about the Screen section in a XF86ConfScreenPtr.

From Table 1 is indicated also that xf86parseDeviceSection returns info for the device section at a XF86ConfDevicePtr.

Example

We will use the example of this xorg.conf, which will be also used in the sections that follow. The specific xorg.conf provides the device pointers (GDevPtr) that follow (which resulted from the parsed conf_device as the following routine, configDevice() shows). Notice that parsePrologue(), called by xf86parseDeviceSection() sets all fields of conf_device initially to NULL and therefore if they obtain no value they remain NULL.

GDevRec resulted from screen0

GDevRec resulted from screen1

identifier

Matrox Graphics, Inc. MGA G400 AGP

Matrox Graphics, Inc. MGA G400 AGP second head

vendor

NULL

NULL

board

NULL

NULL

chipset

NULL

NULL

ramdac

NULL

NULL

driver

mga

mga

myScreenSection

NULL

NULL

claimed

FALSE

FALSE

dacSpeeds

NULL

NULL

numclocks

NULL

NULL

clock

NULL

NULL

clockchip

NULL

NULL

busID

PCI:1:0:0

PCI:1:0:0

active

TRUE

TRUE

inUse

NULL

NULL

videoRam

NULL

NULL

textClockFreq

NULL

NULL

BiosBase

NULL

NULL

MemBase

NULL

NULL

IOBase

NULL

NULL

chipID

NULL

NULL

chipRev

NULL

NULL

options

["AGPMode" "4"],["hw cursor" "on"]

["AGPMode" "4"],["hw cursor" "on"]

irq

NULL

NULL

screen

0

1

Notice the options field is of type XF86OptionRec and in the previous table we show only the opt_name and opt_val fields of the two nodes that are connected via the 'list' fields.

Also the claimed field become TRUE when xf86AddDevToEntity() is called. See Driver Processing

configInput()

configInput() adds a new IDevRec struct in indp[] (the first argument). The second argument is conf_layout->lay_input_lst->iref_inputdev. Therefore the values are copied from conf_layout to the current IDevRec. conf_layout was filled by xf86parseLayoutSection (see section 3.2.2.1). Since we take as example the mouse input device we examine here the code of this routine for the case INPUTDEVICE:

From the source of xf86parseLayoutSection() we see that the XF86ConfInputrefPtr for the mouse has the fields provided by Inputedevice Mouse0. Therefore the copied values to the IDevPtr at configInput() become: