Site hosted by Angelfire.com: Build your free website today!

Hands-on Projects for the Linux Graphics Subsystem

New book from Christos Karayiannis

Available in Amazon Kindle format at:

amazon.com   amazon.co.uk   amazon.de   amazon.es   amazon.fr   amazon.it

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

From DESIGN document we read:

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

From xorg.conf man page we read:

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:

typedef struct
{
	GenericListRec list;
	char *lay_identifier;
	XF86ConfAdjacencyPtr lay_adjacency_lst;
	XF86ConfInactivePtr lay_inactive_lst;
	XF86ConfInputrefPtr lay_input_lst;
	XF86OptionPtr lay_option_lst;
	char *lay_comment;
}
XF86ConfLayoutRec, *XF86ConfLayoutPtr;

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()).

serverLayoutRec xf86ConfigLayout = {NULL, };

where serverLayoutRec is defined in xf86str.h as:

typedef struct _serverlayoutrec {
    char *		id;
    screenLayoutPtr	screens;
    GDevPtr		inactives;
    IDevPtr		inputs;
    pointer		options;
} serverLayoutRec, *serverLayoutPtr;

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:

char *xf86LayoutName = NULL;
char *xf86ScreenName = NULL;
char *xf86PointerName = NULL;
char *xf86KeyboardName = NULL;

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:

    } else {
	if (xf86configptr->conf_flags != NULL) {
	  char *dfltlayout = NULL;
 	  pointer optlist = xf86configptr->conf_flags->flg_option_lst;
	
	  if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
	    dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
	  if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
			  dfltlayout)) {
	    xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
	    return CONFIG_PARSE_ERROR;
	  }
	} else {
	  if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
			  NULL)) {
	    xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
	    return CONFIG_PARSE_ERROR;
	  }
	}
    }

configLayout() is implemented as:

configLayout()

/*
 * figure out which layout is active, which screens are used in that layout,
 * which drivers and monitors are used in these screens
 */
static Bool
configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
	     char *default_layout)
{
    XF86ConfAdjacencyPtr adjp;
    XF86ConfInactivePtr idp;
    XF86ConfInputrefPtr irp;
    int count = 0;
    int scrnum;
    XF86ConfLayoutPtr l;
    MessageType from;
    screenLayoutPtr slp;
    GDevPtr gdp;
    IDevPtr indp;
    int i = 0, j;

    if (!servlayoutp)
	return FALSE;

    /*
     * which layout section is the active one?
     *
     * If there is a -layout command line option, use that one, otherwise
     * pick the first one.
     */
    from = X_DEFAULT;
    if (xf86LayoutName != NULL)
	from = X_CMDLINE;
    else if (default_layout) {
	xf86LayoutName = default_layout;
	from = X_CONFIG;
    }
    if (xf86LayoutName != NULL) {
	if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
	    xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
		    xf86LayoutName);
	    return FALSE;
	}
	conf_layout = l;
    }
    xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
    adjp = conf_layout->lay_adjacency_lst;

    /*
     * we know that each screen is referenced exactly once on the left side
     * of a layout statement in the Layout section. So to allocate the right
     * size for the array we do a quick walk of the list to figure out how
     * many sections we have
     */
    while (adjp) {
        count++;
        adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
    }
#ifdef DEBUG
    ErrorF("Found %d screens in the layout section %s",
           count, conf_layout->lay_identifier);
#endif
    slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
    slp[count].screen = NULL;
    /*
     * now that we have storage, loop over the list again and fill in our
     * data structure; at this point we do not fill in the adjacency
     * information as it is not clear if we need it at all
     */
    adjp = conf_layout->lay_adjacency_lst;
    count = 0;
    while (adjp) {
        slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
	if (adjp->adj_scrnum < 0)
	    scrnum = count;
	else
	    scrnum = adjp->adj_scrnum;
	if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
			  X_CONFIG))
	    return FALSE;
	slp[count].x = adjp->adj_x;
	slp[count].y = adjp->adj_y;
	slp[count].refname = adjp->adj_refscreen;
	switch (adjp->adj_where) {
	case CONF_ADJ_OBSOLETE:
	    slp[count].where = PosObsolete;
	    slp[count].topname = adjp->adj_top_str;
	    slp[count].bottomname = adjp->adj_bottom_str;
	    slp[count].leftname = adjp->adj_left_str;
	    slp[count].rightname = adjp->adj_right_str;
	    break;
	case CONF_ADJ_ABSOLUTE:
	    slp[count].where = PosAbsolute;
	    break;
	case CONF_ADJ_RIGHTOF:
	    slp[count].where = PosRightOf;
	    break;
	case CONF_ADJ_LEFTOF:
	    slp[count].where = PosLeftOf;
	    break;
	case CONF_ADJ_ABOVE:
	    slp[count].where = PosAbove;
	    break;
	case CONF_ADJ_BELOW:
	    slp[count].where = PosBelow;
	    break;
	case CONF_ADJ_RELATIVE:
	    slp[count].where = PosRelative;
	    break;
	}
        count++;
        adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
    }

    /* XXX Need to tie down the upper left screen. */

    /* Fill in the refscreen and top/bottom/left/right values */
    for (i = 0; i < count; i++) {
	for (j = 0; j < count; j++) {
	    if (slp[i].refname &&
		strcmp(slp[i].refname, slp[j].screen->id) == 0) {
		slp[i].refscreen = slp[j].screen;
	    }
	    if (slp[i].topname &&
		strcmp(slp[i].topname, slp[j].screen->id) == 0) {
		slp[i].top = slp[j].screen;
	    }
	    if (slp[i].bottomname &&
		strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
		slp[i].bottom = slp[j].screen;
	    }
	    if (slp[i].leftname &&
		strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
		slp[i].left = slp[j].screen;
	    }
	    if (slp[i].rightname &&
		strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
		slp[i].right = slp[j].screen;
	    }
	}
	if (slp[i].where != PosObsolete
	    && slp[i].where != PosAbsolute
	    && !slp[i].refscreen) {
	    xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
		     slp[i].refname);
	    slp[i].where = PosAbsolute;
	    slp[i].x = 0;
	    slp[i].y = 0;
	}
    }

    /*
     * Count the number of inactive devices.
     */
    count = 0;
    idp = conf_layout->lay_inactive_lst;
    while (idp) {
        count++;
        idp = (XF86ConfInactivePtr)idp->list.next;
    }
#ifdef DEBUG
    ErrorF("Found %d inactive devices in the layout section %s",
           count, conf_layout->lay_identifier);
#endif
    gdp = xnfalloc((count + 1) * sizeof(GDevRec));
    gdp[count].identifier = NULL;
    idp = conf_layout->lay_inactive_lst;
    count = 0;
    while (idp) {
	if (!configDevice(&gdp[count], idp->inactive_device, FALSE))
	    return FALSE;
        count++;
        idp = (XF86ConfInactivePtr)idp->list.next;
    }
    /*
     * Count the number of input devices.
     */
    count = 0;
    irp = conf_layout->lay_input_lst;
    while (irp) {
        count++;
        irp = (XF86ConfInputrefPtr)irp->list.next;
    }
#ifdef DEBUG
    ErrorF("Found %d input devices in the layout section %s",
           count, conf_layout->lay_identifier);
#endif
    indp = xnfalloc((count + 1) * sizeof(IDevRec));
    indp[count].identifier = NULL;
    irp = conf_layout->lay_input_lst;
    count = 0;
    while (irp) {
	if (!configInput(&indp[count], irp->iref_inputdev, X_CONFIG))
	    return FALSE;
	indp[count].extraOptions = irp->iref_option_lst;
        count++;
        irp = (XF86ConfInputrefPtr)irp->list.next;
    }
    servlayoutp->id = conf_layout->lay_identifier;
    servlayoutp->screens = slp;
    servlayoutp->inactives = gdp;
    servlayoutp->inputs = indp;
    servlayoutp->options = conf_layout->lay_option_lst;
    from = X_DEFAULT;

    if (!checkCoreInputDevices(servlayoutp, FALSE))
	return FALSE;
    return TRUE;
}

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:

configScreen(slp[count].screen, adjp->adj_screen, scrnum,
			  X_CONFIG))

where slp is allocated by configLayout() and is of type screenLayoutRec:

typedef struct _screenlayoutrec {
    confScreenPtr	screen;
    char *		topname;
    confScreenPtr	top;
    char *		bottomname;
    confScreenPtr	bottom;
    char *		leftname;
    confScreenPtr	left;
    char *		rightname;
    confScreenPtr	right;
    PositionType	where;
    int			x;
    int			y;
    char *		refname;
    confScreenPtr	refscreen;
} screenLayoutRec, *screenLayoutPtr;

Therefore slp[count].screen is of type confScreenPtr, which is defined as:


======================================================================

THIS STRUCT IA PASSED AS ARGUMENT AND IS FILLED IN configScreen() 

======================================================================

typedef struct _confscreenrec {
    char *		id;
    int			screennum;
    int			defaultdepth;
    int			defaultbpp;
    int			defaultfbbpp;
    MonPtr		monitor;
    GDevPtr		device;
    int			numdisplays;
    DispPtr		displays;
    int			numxvadaptors;
    confXvAdaptorPtr	xvadaptors;
    pointer		options;
} confScreenRec, *confScreenPtr;

GDevPtr is defined in xf86str.h as:


===============================================================================

THIS STRUCT IS PASSED AS ARGUMENT AND IS FILLED IN configDevice()

===============================================================================

typedef struct {
   char *			identifier;
   char *			vendor;
   char *			board;
   char *			chipset;
   char *			ramdac;
   char *			driver;
   struct _confscreenrec *	myScreenSection;
   Bool				claimed;
   int				dacSpeeds[MAXDACSPEEDS];
   int				numclocks;
   int				clock[MAXCLOCKS];
   char *			clockchip;
   char *			busID;
   Bool				active;
   Bool				inUse;
   int				videoRam;
   int				textClockFreq;
   unsigned long		BiosBase;	/* Base address of video BIOS */
   unsigned long		MemBase;	/* Frame buffer base address */
   unsigned long		IOBase;
   int				chipID;
   int				chipRev;
   pointer			options;
   int                          irq;
   int                          screen;         /* For multi-CRTC cards */
} GDevRec, *GDevPtr;


================================================================================

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:

static Bool
configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
	     MessageType from)
{
    int count = 0;
    XF86ConfDisplayPtr dispptr;
    XF86ConfAdaptorLinkPtr conf_adaptor;
    Bool defaultMonitor = FALSE;

    xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
	    scrnum);
    /*
     * now we fill in the elements of the screen
     */
    screenp->id         = conf_screen->scrn_identifier;
    screenp->screennum  = scrnum;
    screenp->defaultdepth = conf_screen->scrn_defaultdepth;
    screenp->defaultbpp = conf_screen->scrn_defaultbpp;
    screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
    screenp->monitor    = xnfcalloc(1, sizeof(MonRec));
    /* If no monitor is specified, create a default one. */
    if (!conf_screen->scrn_monitor) {
	XF86ConfMonitorRec defMon;

	bzero(&defMon, sizeof(defMon));
	defMon.mon_identifier = "";
	/*
	 * TARGET_REFRESH_RATE may be defined to effectively limit the
	 * default resolution to the largest that has a "good" refresh
	 * rate.
	 */
#ifdef TARGET_REFRESH_RATE
	defMon.mon_option_lst = xf86ReplaceRealOption(defMon.mon_option_lst,
						      "TargetRefresh",
						      TARGET_REFRESH_RATE);
#endif
	if (!configMonitor(screenp->monitor, &defMon))
	    return FALSE;
	defaultMonitor = TRUE;
    } else {
	if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
	    return FALSE;
    }
    screenp->device     = xnfcalloc(1, sizeof(GDevRec));
    configDevice(screenp->device,conf_screen->scrn_device, TRUE);
    screenp->device->myScreenSection = screenp;
    screenp->options = conf_screen->scrn_option_lst;
    
    /*
     * figure out how many display subsections there are and fill them in
     */
    dispptr = conf_screen->scrn_display_lst;
    while(dispptr) {
        count++;
        dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
    }
    screenp->displays   = xnfalloc((count) * sizeof(DispRec));
    screenp->numdisplays = count;
    count = 0;
    dispptr = conf_screen->scrn_display_lst;
    while(dispptr) {
        configDisplay(&(screenp->displays[count]),dispptr);
        count++;
        dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
    }

    /*
     * figure out how many videoadaptor references there are and fill them in
     */
    conf_adaptor = conf_screen->scrn_adaptor_lst;
    while(conf_adaptor) {
        count++;
        conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
    }
    screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
    screenp->numxvadaptors = 0;
    conf_adaptor = conf_screen->scrn_adaptor_lst;
    while(conf_adaptor) {
        if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
			    conf_adaptor->al_adaptor))
    	    screenp->numxvadaptors++;
        conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
    }

    if (defaultMonitor) {
	xf86Msg(X_WARNING, "No monitor specified for screen \"%s\".\n"
		"\tUsing a default monitor configuration.\n", screenp->id);
    }
    return TRUE;
}

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:

static Bool
configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
{
    int i;

    if (active)
	xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
		conf_device->dev_identifier);
    else
	xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
		conf_device->dev_identifier);
	
    devicep->identifier = conf_device->dev_identifier;
    devicep->vendor = conf_device->dev_vendor;
    devicep->board = conf_device->dev_board;
    devicep->chipset = conf_device->dev_chipset;
    devicep->ramdac = conf_device->dev_ramdac;
    devicep->driver = conf_device->dev_driver;
    devicep->active = active;
    devicep->videoRam = conf_device->dev_videoram;
    devicep->BiosBase = conf_device->dev_bios_base;
    devicep->MemBase = conf_device->dev_mem_base;
    devicep->IOBase = conf_device->dev_io_base;
    devicep->clockchip = conf_device->dev_clockchip;
    devicep->busID = conf_device->dev_busid;
    devicep->textClockFreq = conf_device->dev_textclockfreq;
    devicep->chipID = conf_device->dev_chipid;
    devicep->chipRev = conf_device->dev_chiprev;
    devicep->options = conf_device->dev_option_lst;
    devicep->irq = conf_device->dev_irq;
    devicep->screen = conf_device->dev_screen;

    for (i = 0; i < MAXDACSPEEDS; i++) {
	if (i < CONF_MAXDACSPEEDS)
            devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
	else
	    devicep->dacSpeeds[i] = 0;
    }
    devicep->numclocks = conf_device->dev_clocks;
    if (devicep->numclocks > MAXCLOCKS)
	devicep->numclocks = MAXCLOCKS;
    for (i = 0; i < devicep->numclocks; i++) {
	devicep->clock[i] = conf_device->dev_clock[i];
    }
    devicep->claimed = FALSE;

    return TRUE;
}

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
identifierMatrox Graphics, Inc. MGA G400 AGP Matrox Graphics, Inc. MGA G400 AGP second head
vendor NULLNULL
boardNULL NULL
chipsetNULL NULL
ramdacNULL NULL
driver mgamga
myScreenSectionNULL NULL
claimed FALSEFALSE
dacSpeedsNULL NULL
numclocks NULL NULL
clock NULL NULL
clockchip NULL NULL
busIDPCI:1:0:0PCI:1:0:0
active TRUETRUE
inUseNULL NULL
videoRamNULL NULL
textClockFreqNULL NULL
BiosBaseNULL NULL
MemBase NULL NULL
IOBase NULL NULL
chipIDNULL NULL
chipRevNULL NULL
options ["AGPMode" "4"],["hw cursor" "on"]["AGPMode" "4"],["hw cursor" "on"]
irqNULL NULL
screen0 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

typedef struct
{
	GenericListRec list;
	char *opt_name;
	char *opt_val;
	int opt_used;
	char *opt_comment;
}
XF86OptionRec, *XF86OptionPtr;

configInput()

configLayout() calls configInput() as:

configInput(&indp[count], irp->iref_inputdev, X_CONFIG))

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:

			
case INPUTDEVICE:
		{
			XF86ConfInputrefPtr iptr;

			iptr = xf86confcalloc (1, sizeof (XF86ConfInputrefRec));
			iptr->list.next = NULL;
			iptr->iref_option_lst = NULL;
			if (xf86getSubToken (&(ptr->lay_comment)) != STRING)
				Error (INPUTDEV_MSG, NULL);
			iptr->iref_inputdev_str = val.str;
			while ((token = xf86getSubToken (&(ptr->lay_comment))) == STRING)
			{
				iptr->iref_option_lst =
				xf86addNewOption (iptr->iref_option_lst, val.str, NULL);
			}
			xf86unGetToken (token);
			ptr->lay_input_lst = (XF86ConfInputrefPtr)
				xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
		}
		break;

configInput() is implemented in xf86Config.c as:

static Bool
configInput(IDevPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
{
    xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
    inputp->identifier = conf_input->inp_identifier;
    inputp->driver = conf_input->inp_driver;
    inputp->commonOptions = conf_input->inp_option_lst;
    inputp->extraOptions = NULL;

    /* XXX This is required until the keyboard driver is converted */
    if (!xf86NameCmp(inputp->driver, "keyboard"))
	return configInputKbd(inputp);

    return TRUE;
}

The result of this will be examined latter in section 3.2.3. At this section the following xorg.conf is used:

Section "ServerLayout"
        Identifier     "single head configuration"
        Screen      0  "Screen0" 0 0
        InputDevice    "Keyboard0" "CoreKeyboard"
        InputDevice    "Synaptics" "CorePointer"
        InputDevice    "Mouse0"    "AlwaysCore"
EndSection

. . .

Section "InputDevice"
        Identifier  "Mouse0"
        Driver      "mouse"
        Option      "Device" "/dev/input/mice"
        Option      "Protocol" "IMPS/2"
        Option      "ZAxisMapping" "4 5"        # Scrollwheel support
        Option      "Emulate3Buttons" "yes"     # L+R buttons count as middle
EndSection

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:

inputp->identifier: "Mouse0"
inputp->driver: "mouse"
inputp->commonOptions: "Device" "/dev/input/mice" , "Protocol" "IMPS/2" , "ZAxisMapping" "4 5", "Emulate3Buttons" "yes"