The following is this item for the example we follow, after xf86AddInputDriver() is called as seen in the next paragraphs:

driverVersion

1

driverName

"mouse"

Identify()(int flags)

NULL

PreInit()

MousePreInit

UnInit()

NULL

module

module (*)

refCount

0

(*) module is of type ModuleDescPtr returned by LoadModule(), which is called by xf86LoadModules().

The pDrv->PreInit function, in our case MousePreInit(), is called next from InitInput(). This fills and returns pInfo, which is of type InputInfoPtr. The InputInfoRec it points to, for the example we follow, is presented in the next example. The pInfo are linked in the xf86InputDevs list. This is the result of xf86AllocateInput() that is called from InitInput() to allocate a new pInfo.

InitInput() calls next xf86ActivateDevice() for each pInfo of the xf86InputDevs list. xf86ActivateDevice() calls AddInputDevice(), which allocates dev, a DeviceIntPtr (points to a _DeviceIntRec) and then it calls RegisterPointerDevice() and RegisterKeyboardDevice() to register the core mouse and keyboard devices.

where coreKeyboard and corePointer are the pInfo (of type InputInfoPtr) that are returned from the PreInit() functions of the mouse and keyboard drivers, which have the XI86_CORE_POINTER and XI86_CORE_KEYBOARD flags respectively set.

II.

The following lines of xf86ActivateDevice(), called by InitInput() fill dev (of type DeviceIntPtr) which was allocated previously in xf86ActivateDevice() by calling AddInputDevice() with argument the pInfo->device_control:

assign some of the fields of dev (field deviceProc was set by _AddInputDevice). Among the fields in section 3.2.5.1 we are interested in processInputProc. As we see for instance in _RegisterPointerDevice() this becomes ProcessPointerEvent. Similarly for the keyboard in _RegisterKeyboardDevice it becomes ProcessKeyboardEvent.

Recall from section 3.2.2.2 that xf86ConfigLayout is of type serverLayoutRec. xf86ConfigLayout 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()).

xf86InputDriverlistFromConfig() creates the modulearray[], a array of strings whose elements are the module names. The module names are the ones we find at the driver field of xf86ConfigLayout.inputs. For instance for the xorg.conf of the green boxed example the module name becomes "mouse".

xf86LoadModules() is used then to load all modules of the modulearray[]. This function was covered in a section 3.2.2.5. In a short xf86LoadModules() calls LoadModule() for each module found in the list. One of the main things LoadModule() does is call the module's setup routine as:

ret->TearDownData = ret->SetupProc(ret, options, errmaj, errmin);

The first argument ret is obtained from NewModuleDesc() (called by LoadModule) and is of type ModuleDescPtr. ret is filled by LoadModule() and in the current example 'module' is the actual argument that substitutes ret (the formal parameter).

LoadModule() checks if the special data object <modulename>ModuleData is present. For the current example this found in mouse.c as:

the last NULL value (the red one) after the xf86AddInputDriver() call is substituted by a pointer to the 'module'.

A common place to find the "mouse" module is:
/usr/lib/xorg/modules/input//mouse_drv.so

The previous steps are described in section 5.6 of the DESIGN document (Register Video and Input Drivers):

5.6 Register Video and Input Drivers
This is done at the start of the first server generation only.
When a driver module is loaded, the loader calls its Setup function. For
video drivers, this function calls xf86AddDriver() to register the driver's
DriverRec, which contains a small set of essential details and driver entry
points required during the early phase of InitOutput(). xf86AddDriver() adds
it to the global xf86DriverList[] array.
The DriverRec contains the driver canonical name, the Identify(), Probe() and
AvailableOptions() function entry points as well as a pointer to the driver's
module (as returned from the loader when the driver was loaded) and a refer-
ence count which keeps track of how many screens are using the driver. The
entry driver entry points are those required prior to the driver allocating
and filling in its ScrnInfoRec.
For a static server, the xf86DriverList[] array is initialised at build time,
and the loading of modules is not done.
A similar procedure is used for input drivers. The input driver's Setup
function calls xf86AddInputDriver() to register the driver's InputDriverRec,
which contains a small set of essential details and driver entry points
required during the early phase of InitInput(). xf86AddInputDriver() adds it
to the global xf86InputDriverList[] array. For a static server, the
xf86InputDriverList[] array is initialised at build time.
Both the xf86DriverList[] and xf86InputDriverList[] arrays have been ini-
tialised by the end of this stage.
Once all the drivers are registered, their ChipIdentify() functions are
called.

What is a canonical file name? As the Loader Overview explains:
"The module name module is normally the module's canonical name, which doesn't contain any directory path information, or any object/library file prefixes of suffixes."

The ModuleDescPtr to the 'module', filled by LoadModule() as previously referred

options

Notes:

xf86AllocateInput() is used to set the drv field of the InputInfoRec to the first argument of MousePreInit(). This is the return value of MatchInput() which is the
xf86InputDriverList[] element with driverName "mouse". As mentioned previously in the current section this list is created by xf86InputDriverlistFromConfig() from xf86ConfigLayout.inputs->driver.

For AddInputDevice() we read at xfree86.org:
"This DIX function allocates the device structure, registers a callback function (which handles device init, close, on and off), and returns the input handle, which can be treated as opaque. It is called once for each input device. Once input handles for core keyboard and core pointer devices have been obtained from AddInputDevice(), they are registered as core devices by calling RegisterPointerDevice() and RegisterKeyboardDevice()."

For the example we follow in the green box the local->device_control (or pInfo->device_control) is function MouseProc(). The second argument are flags added by the xf86ActivateDevice() to the pInfo->flags. Because flag XI86_CORE_POINTER is added now (along with XI86_OPEN_ON_INIT, XI86_ALWAYS_CORE and XI86_CORE_KEYBOARD) RegisterPointerDevice() is also called from xf86ActivateDevice():