diff options
author | marha <marha@users.sourceforge.net> | 2010-05-20 07:07:37 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2010-05-20 07:07:37 +0000 |
commit | 3319741e6f9fc3232eb40462a261271b9af2dcb2 (patch) | |
tree | ffe7fbae59390aafa850dcdbd3ea48d2cb59bda0 /xorg-server/hw/xfree86/doc | |
parent | 153f5cafa19da4e4c0cf21e9c909958359ed8ebd (diff) | |
download | vcxsrv-3319741e6f9fc3232eb40462a261271b9af2dcb2.tar.gz vcxsrv-3319741e6f9fc3232eb40462a261271b9af2dcb2.tar.bz2 vcxsrv-3319741e6f9fc3232eb40462a261271b9af2dcb2.zip |
xserver git update 20/5/2010
Diffstat (limited to 'xorg-server/hw/xfree86/doc')
-rw-r--r-- | xorg-server/hw/xfree86/doc/sgml/DESIGN.sgml | 14834 |
1 files changed, 7420 insertions, 7414 deletions
diff --git a/xorg-server/hw/xfree86/doc/sgml/DESIGN.sgml b/xorg-server/hw/xfree86/doc/sgml/DESIGN.sgml index e95df7999..c6fc63edb 100644 --- a/xorg-server/hw/xfree86/doc/sgml/DESIGN.sgml +++ b/xorg-server/hw/xfree86/doc/sgml/DESIGN.sgml @@ -1,7414 +1,7420 @@ -<!DOCTYPE linuxdoc PUBLIC "-//Xorg//DTD linuxdoc//EN" [ - <!ENTITY % defs SYSTEM "X11/defs.ent"> %defs; - <!-- config file keyword markup --> - <!ENTITY s.key STARTTAG "bf"> - <!ENTITY e.key ENDTAG "bf"> - <!-- specific config file keywords --> - <!ENTITY k.device "&s.key;Device&e.key;"> - <!ENTITY k.monitor "&s.key;Monitor&e.key;"> - <!ENTITY k.display "&s.key;Display&e.key;"> - <!ENTITY k.inputdevice "&s.key;InputDevice&e.key;"> - <!ENTITY k.screen "&s.key;Screen&e.key;"> - <!ENTITY k.serverlayout "&s.key;ServerLayout&e.key;"> - <!ENTITY k.driver "&s.key;Driver&e.key;"> - <!ENTITY k.module "&s.key;Module&e.key;"> - <!ENTITY k.identifier "&s.key;Identifier&e.key;"> - <!ENTITY k.serverflags "&s.key;ServerFlags&e.key;"> - <!-- command line markup --> - <!ENTITY s.cmd STARTTAG "tt"> - <!ENTITY e.cmd ENDTAG "tt"> - <!-- inline code markup --> - <!ENTITY s.code STARTTAG "tt"> - <!ENTITY e.code ENDTAG "tt"> - <!-- function indent --> - <!ENTITY f.indent "&nl          "> -] > - -<article> - -<title>XFree86 server 4.x Design (DRAFT) -<author>The XFree86 Project, Inc -<and>Updates for X11R&relvers; by Jim Gettys -<date>19 December 2003 - - - - - - - -<ident> -$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DESIGN.sgml,v 1.53 2003/08/23 14:10:14 dawes Exp $ -</ident> - - -<p> -<bf>NOTE</bf>: This is a DRAFT document, and the interfaces described here -are subject to change without notice. - - -<sect>Preface -<p> - -The broad design principles are: -<itemize> - <item>keep it reasonable - <itemize> - <item>We cannot rewrite the complete server - <item>We don't want to re-invent the wheel - </itemize> - <item>keep it modular - <itemize> - <item>As many things as possible should go into modules - <item>The basic loader binary should be minimal - <item>A clean design with well defined layering is important - <item>DDX specific global variables are a nono - <item>The structure should be flexible enough to allow - future extensions - <item> The structure should minimize duplication of common code - </itemize> - <item>keep important features in mind - <itemize> - <item>multiple screens, including multiple instances of drivers - <item>mixing different color depths and visuals on different - and ideally even on the same screen - <item>better control of the PCI device used - <item>better config file parser - <item>get rid of all VGA compatibility assumptions - </itemize> -</itemize> - -Unless we find major deficiencies in the DIX layer, we should avoid -making changes there. - -<sect>The xorg.conf File -<p> - -The xorg.conf file format is similar to the old format, with the following -changes: - -<sect1>&k.device; section -<p> - - The &k.device; sections are similar to what they used to be, and - describe hardware-specific information for a single video card. - &k.device; - Some new keywords are added: - - - <descrip> - <tag>Driver "drivername"</tag> - Specifies the name of the driver to be used for the card. This - is mandatory. - <tag>BusID "busslot"</tag> - Specifies uniquely the location of the card on the bus. The - purpose is to identify particular cards in a multi-headed - configuration. The format of the argument is intentionally - vague, and may be architecture dependent. For a PCI bus, it - is something like "bus:slot:func". - </descrip> - - A &k.device; section is considered ``active'' if there is a reference - to it in an active &k.screen; section. - -<sect1>&k.screen; section -<p> - - The &k.screen; sections are similar to what they used to be. They - no longer have a &k.driver; keyword, but an &k.identifier; keyword - is added. (The &k.driver; keyword may be accepted in place of the - &k.identifier; keyword for compatibility purposes.) The identifier - can be used to identify which screen is to be active when multiple - &k.screen sections are present. It is possible to specify the active - screen from the command line. A default is chosen in the absence - of one being specified. A &k.screen; section is considered ``active'' - if there is a reference to it either from the command line, or from - an active &k.serverlayout; section. - -<sect1>&k.inputdevice; section -<p> - - The &k.inputdevice; section is a new section that describes - configuration information for input devices. It replaces the old - &s.key;Keyboard&e.key;, &s.key;Pointer&e.key; and &s.key;XInput&e.key; - sections. Like the &k.device; section, it has two mandatory keywords: - &k.identifier; and &k.driver;. For compatibility purposes the old - &s.key;Keyboard&e.key; and &s.key;Pointer&e.key; sections are - converted by the parser into &k.inputdevice; sections as follows: - - <descrip> - <tag>&s.key;Keyboard&e.key;</tag> - &k.identifier; "Implicit Core Keyboard"<newline> - &k.driver; "keyboard" - <tag>&s.key;Pointer&e.key;</tag> - &k.identifier; "Implicit Core Pointer"<newline> - &k.driver; "mouse" - </descrip> - - An &k.inputdevice; section is considered active if there is a - reference to it in an active &k.serverlayout; section. An - &k.inputdevice; section may also be referenced implicitly if there - is no &k.serverlayout; section, if the &s.cmd;-screen&e.cmd; command - line options is used, or if the &k.serverlayout; section doesn't - reference any &k.inputdevice; sections. In this case, the first - sections with drivers "keyboard" and "mouse" are used as the core - keyboard and pointer respectively. - -<sect1>&k.serverlayout; section -<p> - - The &k.serverlayout; section is a new section that is used to identify - which &k.screen; sections are to be used in a multi-headed configuration, - and the relative layout of those screens. It also identifies which - &k.inputdevice; sections are to be used. Each &k.serverlayout section - has an identifier, a list of &k.screen; section identifiers, and a list of - &k.inputdevice; section identifiers. &k.serverflags; options may also be - included in a &k.serverlayout; section, making it possible to override - the global values in the &k.serverflags; section. - - A &k.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). - When no screen number is specified, they are numbered according to - the order in which they are listed. The old (now obsolete) method - of providing the positioning information is to give the names of - the four adjacent screens. The order of these is top, bottom, left, - right. Here is an example of a &k.serverlayout; section for two - screens using the old method, with the second located to the right - of the first: - - <code> - Section "ServerLayout" - Identifier "Main Layout" - Screen 0 "Screen 1" "" "" "" "Screen 2" - Screen 1 "Screen 2" - Screen "Screen 3" - EndSection - </code> - - The preferred way of specifying the layout is to explicitly specify - the screen's location in absolute terms or relative to another - screen. - - In the absolute case, the upper left corner's coordinates are given - after the &s.key;Absolute&e.key; keyword. If the coordinates are - omitted, a value of &s.code;(0,0)&e.code; is assumed. An example - of absolute positioning follows: - - <code> - Section "ServerLayout" - Identifier "Main Layout" - Screen 0 "Screen 1" Absolute 0 0 - Screen 1 "Screen 2" Absolute 1024 0 - Screen "Screen 3" Absolute 2048 0 - EndSection - </code> - - In the relative case, the position is specified by either using one of - the following keywords followed by the name of the reference screen: - - <quote> - &s.key;RightOf&nl; - LeftOf&nl; - Above&nl; - Below&nl; - Relative&e.key; - </quote> - - When the &s.key;Relative&e.key; keyword is used, the reference screen - name is followed by the coordinates of the new screen's origin - relative to reference screen. The following example shows how to use - some of the relative positioning options. - - <code> - Section "ServerLayout" - Identifier "Main Layout" - Screen 0 "Screen 1" - Screen 1 "Screen 2" RightOf "Screen 1" - Screen "Screen 3" Relative "Screen 1" 2048 0 - EndSection - </code> - -<sect1>Options -<p> - - Options are used more extensively. They may appear in most sections - now. Options related to drivers can be present in the &k.screen;, - &k.device; and &k.monitor; sections and the &k.display; subsections. - The order of precedence is &k.display;, &k.screen;, &k.monitor;, - &k.device;. Options have been extended to allow an optional value - to be specified in addition to the option name. For more details - about options, see the <ref id="options" name="Options"> section - for details. - -<sect>Driver Interface -<p> - -The driver interface consists of a minimal set of entry points that are -required based on the external events that the driver must react to. -No non-essential structure is imposed on the way they are used beyond -that. This is a significant difference compared with the old design. - -The entry points for drawing operations are already taken care of by -the framebuffer code (including, XAA). Extensions and enhancements to -framebuffer code are outside the scope of this document. - -This approach to the driver interface provides good flexibility, but does -increase the complexity of drivers. To help address this, the XFree86 -common layer provides a set of ``helper'' functions to take care of things -that most drivers need. These helpers help minimise the amount of code -duplication between drivers. The use of helper functions by drivers is -however optional, though encouraged. The basic philosophy behind the -helper functions is that they should be useful to many drivers, that -they should balance this against the complexity of their interface. It -is inevitable that some drivers may find some helpers unsuitable and -need to provide their own code. - -Events that a driver needs to react to are: - - <descrip> - <tag>ScreenInit</tag> - - An initialisation function is called from the DIX layer for each - screen at the start of each server generation. - - <tag>Enter VT</tag> - - The server takes control of the console. - - <tag>Leave VT</tag> - - The server releases control of the console. - - <tag>Mode Switch</tag> - - Change video mode. - - <tag>ViewPort change</tag> - - Change the origin of the physical view port. - - <tag>ScreenSaver state change</tag> - - Screen saver activation/deactivation. - - <tag>CloseScreen</tag> - - A close screen function is called from the DIX layer for each screen - at the end of each server generation. - </descrip> - - -In addition to these events, the following functions are required by -the XFree86 common layer: - - <descrip> - <tag>Identify</tag> - - Print a driver identifying message. - - <tag>Probe</tag> - - This is how a driver identifies if there is any hardware present that - it knows how to drive. - - <tag>PreInit</tag> - - Process information from the xorg.conf file, determine the - full characteristics of the hardware, and determine if a valid - configuration is present. - </descrip> - -The VidMode extension also requires: - - <descrip> - <tag>ValidMode</tag> - - Identify if a new mode is usable with the current configuration. - The PreInit function (and/or helpers it calls) may also make use - of the ValidMode function or something similar. - </descrip> - - -Other extensions may require other entry points. The drivers will -inform the common layer of these in such cases. - -<sect>Resource Access Control Introduction -<p> - -Graphics devices are accessed through ranges in I/O or memory space. -While most modern graphics devices allow relocation of such ranges many -of them still require the use of well established interfaces such as -VGA memory and IO ranges or 8514/A IO ranges. With modern buses (like -PCI) it is possible for multiple video devices to share access to these -resources. The RAC (Resource Access Control) subsystem provides a -mechanism for this. - -<sect1>Terms and Definitions -<p> - -<sect2>Bus -<p> - - ``Bus'' is ambiguous as it is used for different things: it may refer - to physical incompatible extension connectors in a computer system. - The RAC system knows two such systems: The ISA bus and the PCI bus. - (On the software level EISA, MCA and VL buses are currently treated - like ISA buses). ``Bus'' may also refer to logically different - entities on a single bus system which are connected via bridges. A - PCI system may have several distinct PCI buses connecting each other - by PCI-PCI bridges or to the host CPU by HOST-PCI bridges. - - Systems that host more than one bus system link these together using - bridges. Bridges are a concern to RAC as they might block or pass - specific resources. PCI-PCI bridges may be set up to pass VGA - resources to the secondary bus. PCI-ISA buses pass any resources not - decoded on the primary PCI bus to the ISA bus. This way VGA resources - (although exclusive on the ISA bus) can be shared by ISA and PCI - cards. Currently HOST-PCI bridges are not yet handled by RAC as they - require specific drivers. - -<sect2>Entity -<p> - - The smallest independently addressable unit on a system bus is - referred to as an entity. So far we know ISA and PCI entities. PCI - entities can be located on the PCI bus by an unique ID consisting of - the bus, card and function number. - -<sect2>Resource -<p> - - ``Resource'' refers to a range of memory or I/O addresses an entity - can decode. - - If a device is capable of disabling this decoding the resource is - called sharable. For PCI devices a generic method is provided to - control resource decoding. Other devices will have to provide a - device specific function to control decoding. - - If the entity is capable of decoding this range at a different - location this resource is considered relocatable. - - Resources which start at a specific address and occupy a single - continuous range are called block resources. - - Alternatively resource addresses can be decoded in a way that they - satisfy the conditions: - <quote><verb> - address & mask == base - </verb></quote> - and - <quote><verb> - base & mask == base - </verb></quote> - Resources addressed in such a way are called sparse resources. - -<sect2>Server States -<p> - - The resource access control system knows two server states: the - SETUP and the OPERATING state. The SETUP state is entered whenever - a mode change takes place or the server exits or does VT switching. - During this state all entity resources are under resource access - control. During OPERATING state only those entities are controlled - which actually have shared resources that conflict with others. - -<sect>Control Flow in the Server and Mandatory Driver Functions -<p> - -At the start of each server generation, &s.code;main()&e.code; -(&s.code;dix/main.c&e.code;) calls the DDX function -&s.code;InitOutput()&e.code;. This is the first place that the DDX gets -control. &s.code;InitOutput()&e.code; is expected to fill in the global -&s.code;screenInfo&e.code; struct, and one -&s.code;screenInfo.screen[]&e.code; entry for each screen present. Here -is what &s.code;InitOutput()&e.code; does: - -<sect1>Parse the xorg.conf file -<p> - - This is done at the start of the first server generation only. - - The xorg.conf file is read in full, and the resulting information - stored in data structures. None of the parsed information is - processed at this point. The parser data structures are opaque to - the video drivers and to most of the common layer code. - - The entire file is parsed first to remove any section ordering - requirements. - - -<sect1>Initial processing of parsed information and command line options -<p> - - This is done at the start of the first server generation only. - - The initial processing is to determine paths like the - &s.key;ModulePath&e.key;, etc, and to determine which &k.serverlayout;, - &k.screen; and &k.device; sections are active. - - -<sect1>Enable port I/O access -<p> - - Port I/O access is controlled from the XFree86 common layer, and is - ``all or nothing''. It is enabled prior to calling driver probes, at - the start of subsequent server generations, and when VT switching - back to the Xserver. It is disabled at the end of server generations, - and when VT switching away from the Xserver. - - The implementation details of this may vary on different platforms. - - -<sect1>General bus probe -<p> - - This is done at the start of the first server generation only. - - In the case of ix86 machines, this will be a general PCI probe. - The full information obtained here will be available to the drivers. - This information persists for the life of the Xserver. In the PCI - case, the PCI information for all video cards found is available by - calling &s.code;xf86GetPciVideoInfo()&e.code;. - - <quote> - &s.code;pciVideoPtr *xf86GetPciVideoInfo(void)&e.code; - <quote><p> - returns a pointer to a list of pointers to - &s.code;pciVideoRec&e.code; entries, of which there is one for - each detected PCI video card. The list is terminated with a - &s.code;NULL&e.code; pointer. If no PCI video cards were - detected, the return value is &s.code;NULL&e.code;. - - </quote> - </quote> - - After the bus probe, the resource broker is initialised. - - -<sect1>Load initial set of modules -<p> - - This is done at the start of the first server generation only. - - The core server contains a list of mandatory modules. These are loaded - first. Currently the only module on this list is the bitmap font module. - - The next set of modules loaded are those specified explicitly in the - &k.module; section of the config file. - - The final set of initial modules are the driver modules referenced - by the active &k.device; and &k.inputdevice; sections in the config - file. Each of these modules is loaded exactly once. - - -<sect1>Register Video and Input Drivers -<p> - - This is done at the start of the first server generation only. - - When a driver module is loaded, the loader calls its - &s.code;Setup&e.code; function. For video drivers, this function - calls &s.code;xf86AddDriver()&e.code; to register the driver's - &s.code;DriverRec&e.code;, which contains a small set of essential - details and driver entry points required during the early phase of - &s.code;InitOutput()&e.code;. &s.code;xf86AddDriver()&e.code; adds - it to the global &s.code;xf86DriverList[]&e.code; array. - - The &s.code;DriverRec&e.code; contains the driver canonical name, - the &s.code;Identify()&e.code;, - &s.code;Probe()&e.code; and &s.code;AvailableOptions()&e.code; - 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 reference 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 - &s.code;ScrnInfoRec&e.code;. - - For a static server, the &s.code;xf86DriverList[]&e.code; 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 - &s.code;Setup&e.code; function calls - &s.code;xf86AddInputDriver()&e.code; to register the driver's - &s.code;InputDriverRec&e.code;, which contains a small set of - essential details and driver entry points required during the early - phase of &s.code;InitInput()&e.code;. - &s.code;xf86AddInputDriver()&e.code; adds it to the global - &s.code;xf86InputDriverList[]&e.code; array. For a static server, - the &s.code;xf86InputDriverList[]&e.code; array is initialised at - build time. - - Both the &s.code;xf86DriverList[]&e.code; and - &s.code;xf86InputDriverList[]&e.code; arrays have been initialised - by the end of this stage. - - Once all the drivers are registered, their - &s.code;ChipIdentify()&e.code; functions are called. - - <quote> - &s.code;void ChipIdentify(int flags)&e.code; - <quote> - This is expected to print a message indicating the driver name, - a short summary of what it supports, and a list of the chipset - names that it supports. It may use the xf86PrintChipsets() helper - to do this. - </quote> - </quote> - - <quote> - &s.code;void xf86PrintChipsets(const char *drvname, const char *drvmsg, - &f.indent;SymTabPtr chips)&e.code; - <quote> - This function provides an easy way for a driver's ChipIdentify - function to format the identification message. - </quote> - </quote> - -<sect1>Initialise Access Control -<p> - - This is done at the start of the first server generation only. - - The Resource Access Control (RAC) subsystem is initialised before - calling any driver functions that may access hardware. All generic - bus information is probed and saved (for restoration later). All - (shared resource) video devices are disabled at the generic bus - level, and a probe is done to find the ``primary'' video device. These - devices remain disabled for the next step. - - -<sect1>Video Driver Probe<label id="probe"> -<p> - This is done at the start of the first server generation only. The - &s.code;ChipProbe()&e.code; function of each registered video driver - is called. - - <quote><p> - &s.code;Bool ChipProbe(DriverPtr drv, int flags)&e.code; - <quote><p> - The purpose of this is to identify all instances of hardware - supported by the driver. The flags value is currently either 0, - &s.code;PROBE_DEFAULT&e.code; or &s.code;PROBE_DETECT&e.code;. - &s.code;PROBE_DETECT&e.code; is used if "-configure" or "-probe" - command line arguments are given and indicates to the - &s.code;Probe()&e.code; function that it should not configure the - bus entities and that no xorg.conf information is available. - - The probe must find the active device sections that match the - driver by calling &s.code;xf86MatchDevice()&e.code;. The number - of matches found limits the maximum number of instances for this - driver. If no matches are found, the function should return - &s.code;FALSE&e.code; immediately. - - Devices that cannot be identified by using device-independent - methods should be probed at this stage (keeping in mind that access - to all resources that can be disabled in a device-independent way - are disabled during this phase). The probe must be a minimal - probe. It should just determine if there is a card present that - the driver can drive. It should use the least intrusive probe - methods possible. It must not do anything that is not essential, - like probing for other details such as the amount of memory - installed, etc. It is recommended that the - &s.code;xf86MatchPciInstances()&e.code; helper function be used - for identifying matching PCI devices, and similarly the - &s.code;xf86MatchIsaInstances()&e.code; for ISA (non-PCI) devices - (see the <ref id="rac" name="RAC"> section). These helpers also - checks and claims the appropriate entity. When not using the - helper, that should be done with &s.code;xf86CheckPciSlot()&e.code; - and &s.code;xf86ClaimPciSlot()&e.code; for PCI devices and - &s.code;xf86ClaimIsaSlot()&e.code; for ISA devices (see the - <ref id="rac" name="RAC"> section). - - The probe must register all non-relocatable resources at this - stage. If a resource conflict is found between exclusive resources - the driver will fail immediately. This is usually best done with - the &s.code;xf86ConfigPciEntity()&e.code; helper function - for PCI and &s.code;xf86ConfigIsaEntity()&e.code; for ISA - (see the <ref id="rac" name="RAC"> section). It is possible to - register some entity specific functions with those helpers. When - not using the helpers, the &s.code;xf86AddEntityToScreen()&e.code; - &s.code;xf86ClaimFixedResources()&e.code; and - &s.code;xf86SetEntityFuncs()&e.code; should be used instead (see - the <ref id="rac" name="RAC"> section). - - If a chipset is specified in an active device section which the - driver considers relevant (ie it has no driver specified, or the - driver specified matches the driver doing the probe), the Probe - must return &s.code;FALSE&e.code; if the chipset doesn't match - one supported by the driver. - - If there are no active device sections that the driver considers - relevant, it must return &s.code;FALSE&e.code;. - - Allocate a &s.code;ScrnInfoRec&e.code; for each active instance of the - hardware found, and fill in the basic information, including the - other driver entry points. This is best done with the - &s.code;xf86ConfigIsaEntity()&e.code; helper function for ISA - instances or &s.code;xf86ConfigPciEntity()&e.code; for PCI instances. - These functions allocate a &s.code;ScrnInfoRec&e.code; for active - entities. Optionally &s.code;xf86AllocateScreen()&e.code; - function may also be used to allocate the &s.code;ScrnInfoRec&e.code;. - Any of these functions take care of initialising fields to defined - ``unused'' values. - - Claim the entities for each instance of the hardware found. This - prevents other drivers from claiming the same hardware. - - Must leave hardware in the same state it found it in, and must not - do any hardware initialisation. - - All detection can be overridden via the config file, and that - parsed information is available to the driver at this stage. - - Returns &s.code;TRUE&e.code; if one or more instances are found, - and &s.code;FALSE&e.code; otherwise. - - </quote> - - &s.code;int xf86MatchDevice(const char *drivername, - &f.indent;GDevPtr **driversectlist)&e.code; - <quote><p> - - This function takes the name of the driver and returns via - &s.code;driversectlist&e.code; a list of device sections that - match the driver name. The function return value is the number - of matches found. If a fatal error is encountered the return - value is &s.code;-1&e.code;. - - The caller should use &s.code;xfree()&e.code; to free - &s.code;*driversectlist&e.code; when it is no longer needed. - - </quote> - - &s.code;ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags)&e.code; - <quote><p> - This function allocates a new &s.code;ScrnInfoRec&e.code; in the - &s.code;xf86Screens[]&e.code; array. This function is normally - called by the video driver &s.code;ChipProbe()&e.code; functions. - The return value is a pointer to the newly allocated - &s.code;ScrnInfoRec&e.code;. The &s.code;scrnIndex&e.code;, - &s.code;origIndex&e.code;, &s.code;module&e.code; and - &s.code;drv&e.code; fields are initialised. The reference count - in &s.code;drv&e.code; is incremented. The storage for any - currently allocated ``privates'' pointers is also allocated and - the &s.code;privates&e.code; field initialised (the privates data - is of course not allocated or initialised). This function never - returns on failure. If the allocation fails, the server exits - with a fatal error. The flags value is not currently used, and - should be set to zero. - </quote> - </quote> - - At the completion of this, a list of &s.code;ScrnInfoRecs&e.code; - have been allocated in the &s.code;xf86Screens[]&e.code; array, and - the associated entities and fixed resources have been claimed. The - following &s.code;ScrnInfoRec&e.code; fields must be initialised at - this point: - - <quote><verb> - driverVersion - driverName - scrnIndex(*) - origIndex(*) - drv(*) - module(*) - name - Probe - PreInit - ScreenInit - EnterVT - LeaveVT - numEntities - entityList - access - </verb></quote> - - <tt>(*)</tt> These are initialised when the &s.code;ScrnInfoRec&e.code; - is allocated, and not explicitly by the driver. - - The following &s.code;ScrnInfoRec&e.code; fields must be initialised - if the driver is going to use them: - - <quote><verb> - SwitchMode - AdjustFrame - FreeScreen - ValidMode - </verb></quote> - -<sect1>Matching Screens -<p> - - This is done at the start of the first server generation only. - - After the Probe phase is finished, there will be some number of - &s.code;ScrnInfoRecs&e.code;. These are then matched with the active - &k.screen; sections in the xorg.conf, and those not having an active - &k.screen; section are deleted. If the number of remaining screens - is 0, &s.code;InitOutput()&e.code; sets - &s.code;screenInfo.numScreens&e.code; to &s.code;0&e.code; and - returns. - - At this point the following fields of the &s.code;ScrnInfoRecs&e.code; - must be initialised: - - <quote><verb> - confScreen - </verb></quote> - - -<sect1>Allocate non-conflicting resources -<p> - - This is done at the start of the first server generation only. - - Before calling the drivers again, the resource information collected - from the Probe phase is processed. This includes checking the extent - of PCI resources for the probed devices, and resolving any conflicts - in the relocatable PCI resources. It also reports conflicts, checks - bus routing issues, and anything else that is needed to enable the - entities for the next phase. - - If any drivers registered an &s.code;EntityInit()&e.code; function - during the Probe phase, then they are called here. - - -<sect1>Sort the Screens and pre-check Monitor Information -<p> - - This is done at the start of the first server generation only. - - The list of screens is sorted to match the ordering requested in the - config file. - - The list of modes for each active monitor is checked against the - monitor's parameters. Invalid modes are pruned. - - -<sect1>PreInit -<p> - - This is done at the start of the first server generation only. - - For each &s.code;ScrnInfoRec&e.code;, enable access to the screens entities and call - the &s.code;ChipPreInit()&e.code; function. - - <quote><p> - &s.code;Bool ChipPreInit(ScrnInfoRec screen, int flags)&e.code; - <quote><p> - The purpose of this function is to find out all the information - required to determine if the configuration is usable, and to - initialise those parts of the &s.code;ScrnInfoRec&e.code; that - can be set once at the beginning of the first server generation. - - The number of entities registered for the screen should be checked - against the expected number (most drivers expect only one). The - entity information for each of them should be retrieved (with - &s.code;xf86GetEntityInfo()&e.code;) and checked for the correct - bus type and that none of the sharable resources registered during - the Probe phase was rejected. - - Access to resources for the entities that can be controlled in a - device-independent way are enabled before this function is called. - If the driver needs to access any resources that it has disabled - in an &s.code;EntityInit()&e.code; function that it registered, - then it may enable them here providing that it disables them before - this function returns. - - This includes probing for video memory, clocks, ramdac, and all - other HW info that is needed. It includes determining the - depth/bpp/visual and related info. It includes validating and - determining the set of video modes that will be used (and anything - that is required to determine that). - - This information should be determined in the least intrusive way - possible. The state of the HW must remain unchanged by this - function. Although video memory (including MMIO) may be mapped - within this function, it must be unmapped before returning. Driver - specific information should be stored in a structure hooked into - the &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; - field. Any other modules which require persistent data (ie data - that persists across server generations) should be initialised in - this function, and they should allocate a ``privates'' index to - hook their data into by calling - &s.code;xf86AllocateScrnInfoPrivateIndex().&e.code; The ``privates'' - data is persistent. - - Helper functions for some of these things are provided at the - XFree86 common level, and the driver can choose to make use of - them. - - All additional resources that the screen needs must be registered - here. This should be done with - &s.code;xf86RegisterResources()&e.code;. If some of the fixed - resources registered in the Probe phase are not needed or not - decoded by the hardware when in the OPERATING server state, their - status should be updated with - &s.code;xf86SetOperatingState()&e.code;. - - Modules may be loaded at any point in this function, and all - modules that the driver will need must be loaded before the end - of this function. Either the &s.code;xf86LoadSubModule()&e.code; - or the &s.code;xf86LoadDrvSubModule()&e.code; function should be - used to load modules depending on whether a - &s.code;ScrnInfoRec&e.code; has been set up. A driver may unload - a module within this function if it was only needed temporarily, - and the &s.code;xf86UnloadSubModule()&e.code; function should be used - to do that. Otherwise there is no need to explicitly unload modules - because the loader takes care of module dependencies and will - unload submodules automatically if/when the driver module is - unloaded. - - The bulk of the &s.code;ScrnInfoRec&e.code; fields should be filled - out in this function. - - &s.code;ChipPreInit()&e.code; returns &s.code;FALSE&e.code; when - the configuration is unusable in some way (unsupported depth, no - valid modes, not enough video memory, etc), and &s.code;TRUE&e.code; - if it is usable. - - It is expected that if the &s.code;ChipPreInit()&e.code; function - returns &s.code;TRUE&e.code;, then the only reasons that subsequent - stages in the driver might fail are lack or resources (like xalloc - failures). All other possible reasons for failure should be - determined by the &s.code;ChipPreInit()&e.code; function. - - </quote> - </quote> - - The &s.code;ScrnInfoRecs&e.code; for screens where the &s.code;ChipPreInit()&e.code; fails are removed. - If none remain, &s.code;InitOutput()&e.code; sets &s.code;screenInfo.numScreens&e.code; to &s.code;0&e.code; and returns. - - At this point, further fields of the &s.code;ScrnInfoRecs&e.code; would normally be - filled in. Most are not strictly mandatory, but many are required - by other layers and/or helper functions that the driver may choose - to use. The documentation for those layers and helper functions - indicates which they require. - - The following fields of the &s.code;ScrnInfoRecs&e.code; should be filled in if the - driver is going to use them: - - <quote><verb> - monitor - display - depth - pixmapBPP - bitsPerPixel - weight (>8bpp only) - mask (>8bpp only) - offset (>8bpp only) - rgbBits (8bpp only) - gamma - defaultVisual - maxHValue - maxVValue - virtualX - virtualY - displayWidth - frameX0 - frameY0 - frameX1 - frameY1 - zoomLocked - modePool - modes - currentMode - progClock (TRUE if clock is programmable) - chipset - ramdac - clockchip - numClocks (if not programmable) - clock[] (if not programmable) - videoRam - biosBase - memBase - memClk - driverPrivate - chipID - chipRev - </verb></quote> - - <quote><p> - &s.code;pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)&e.code: - and - &s.code;pointer xf86LoadDrvSubModule(DriverPtr drv, const char *name)&e.code: - <quote><p> - Load a module that a driver depends on. This function loads the - module &s.code;name&e.code; as a sub module of the driver. The - return value is a handle identifying the new module. If the load - fails, the return value will be &s.code;NULL&e.code;. If a driver - needs to explicitly unload a module it has loaded in this way, - the return value must be saved and passed to - &s.code;xf86UnloadSubModule()&e.code; when unloading. - - </quote> - - &s.code;void xf86UnloadSubModule(pointer module)&e.code; - <quote><p> - Unloads the module referenced by &s.code;module&e.code;. - &s.code;module&e.code; should be a pointer returned previously - by &s.code;xf86LoadSubModule()&e.code; or - &s.code;xf86LoadDrvSubModule()&e.code; . - - </quote> - </quote> - -<sect1>Cleaning up Unused Drivers -<p> - - At this point it is known which screens will be in use, and which - drivers are being used. Unreferenced drivers (and modules they - may have loaded) are unloaded here. - - -<sect1>Consistency Checks -<p> - - The parameters that must be global to the server, like pixmap formats, - bitmap bit order, bitmap scanline unit and image byte order are - compared for each of the screens. If a mismatch is found, the server - exits with an appropriate message. - - -<sect1>Check if Resource Control is Needed -<p> - - Determine if resource access control is needed. This is the case - if more than one screen is used. If necessary the RAC wrapper module - is loaded. - -<sect1>AddScreen (ScreenInit) -<p> - - At this point, the valid screens are known. - &s.code;AddScreen()&e.code; is called for each of them, passing - &s.code;ChipScreenInit()&e.code; as the argument. - &s.code;AddScreen()&e.code; is a DIX function that allocates a new - &s.code;screenInfo.screen[]&e.code; entry (aka - &s.code;pScreen&e.code;), and does some basic initialisation of it. - It then calls the &s.code;ChipScreenInit()&e.code; function, with - &s.code;pScreen&e.code; as one of its arguments. If - &s.code;ChipScreenInit()&e.code; returns &s.code;FALSE&e.code;, - &s.code;AddScreen()&e.code; returns &s.code;-1&e.code;. Otherwise - it returns the index of the screen. &s.code;AddScreen()&e.code; - should only fail because of programming errors or failure to allocate - resources (like memory). All configuration problems should be - detected BEFORE this point. - - <quote><p> - &s.code;Bool ChipScreenInit(int index, ScreenPtr pScreen, - &f.indent;int argc, char **argv)&e.code; - <quote><p> - This is called at the start of each server generation. - - Fill in all of &s.code;pScreen&e.code;, possibly doing some of - this by calling ScreenInit functions from other layers like mi, - framebuffers (cfb, etc), and extensions. - - Decide which operations need to be placed under resource access - control. The classes of operations are the frame buffer operations - (&s.code;RAC_FB&e.code;), the pointer operations - (&s.code;RAC_CURSOR&e.code;), the viewport change operations - (&s.code;RAC_VIEWPORT&e.code;) and the colormap operations - (&s.code;RAC_COLORMAP&e.code;). Any operation that requires - resources which might be disabled during OPERATING state should - be set to use RAC. This can be specified separately for memory - and IO resources (the &s.code;racMemFlags&e.code; and - &s.code;racIoFlags&e.code; fields of the &s.code;ScrnInfoRec&e.code; - respectively). - - Map any video memory or other memory regions. - - Save the video card state. Enough state must be saved so that - the original state can later be restored. - - Initialise the initial video mode. The &s.code;ScrnInfoRec&e.code;'s - &s.code;vtSema&e.code; field should be set to &s.code;TRUE&e.code; - just prior to changing the video hardware's state. - - </quote> - </quote> - - - The &s.code;ChipScreenInit()&e.code; function (or functions from other - layers that it calls) should allocate entries in the - &s.code;ScreenRec&e.code;'s &s.code;devPrivates&e.code; area by - calling &s.code;AllocateScreenPrivateIndex()&e.code; if it needs - per-generation storage. Since the &s.code;ScreenRec&e.code;'s - &s.code;devPrivates&e.code; information is cleared for each server - generation, this is the correct place to initialise it. - - After &s.code;AddScreen()&e.code; has successfully returned, the - following &s.code;ScrnInfoRec&e.code; fields are initialised: - - <quote><verb> - pScreen - racMemFlags - racIoFlags - </verb></quote> - - The &s.code;ChipScreenInit()&e.code; function should initialise the - &s.code;CloseScreen&e.code; and &s.code;SaveScreen&e.code; fields - of &s.code;pScreen&e.code;. The old value of - &s.code;pScreen->CloseScreen&e.code; should be saved as part of - the driver's per-screen private data, allowing it to be called from - &s.code;ChipCloseScreen()&e.code;. This means that the existing - &s.code;CloseScreen()&e.code; function is wrapped. - -<sect1>Finalising RAC Initialisation -<p> - - After all the &s.code;ChipScreenInit()&e.code; functions have been - called, each screen has registered its RAC requirements. This - information is used to determine which shared resources are requested - by more than one driver and set the access functions accordingly. - This is done following these rules: - - <enum> - <item>The sharable resources registered by each entity are compared. - If a resource is registered by more than one entity the entity - will be marked to indicate that it needs to share this resources - type (IO or MEM). - - <item>A resource marked ``disabled'' during OPERATING state will be - ignored entirely. - - <item>A resource marked ``unused'' will only conflict with an overlapping - resource of an other entity if the second is actually in use - during OPERATING state. - - <item>If an ``unused'' resource was found to conflict but the entity - does not use any other resource of this type the entire resource - type will be disabled for that entity. - </enum> - - -<sect1>Finishing InitOutput() -<p> - - At this point &s.code;InitOutput()&e.code; is finished, and all the - screens have been setup in their initial video mode. - - -<sect1>Mode Switching -<p> - - When a SwitchMode event is received, &s.code;ChipSwitchMode()&e.code; - is called (when it exists): - - <quote><p> - &s.code;Bool ChipSwitchMode(int index, DisplayModePtr mode, int flags)&e.code; - <quote><p> - Initialises the new mode for the screen identified by - &s.code;index;&e.code;. The viewport may need to be adjusted - also. - - </quote> - </quote> - - -<sect1>Changing Viewport -<p> - - When a Change Viewport event is received, - &s.code;ChipAdjustFrame()&e.code; is called (when it exists): - - <quote><p> - &s.code;void ChipAdjustFrame(int index, int x, int y, int flags)&e.code; - <quote><p> - Changes the viewport for the screen identified by - &s.code;index;&e.code;. - - It should be noted that many chipsets impose restrictions on where the - viewport may be placed in the virtual resolution, either for alignment - reasons, or to prevent the start of the viewport from being positioned - within a pixel (as can happen in a 24bpp mode). After calculating the - value the chipset's panning registers need to be set to for non-DGA - modes, this function should recalculate the ScrnInfoRec's - &s.code;frameX0&e.code;, &s.code;frameY0&e.code, &s.code;frameX1&e.code; - and &s.code;frameY1&e.code; fields to correspond to that value. If - this is not done, switching to another mode might cause the position - of a hardware cursor to change. - - </quote> - </quote> - - -<sect1>VT Switching -<p> - - When a VT switch event is received, &s.code;xf86VTSwitch()&e.code; - is called. &s.code;xf86VTSwitch()&e.code; does the following: - - <descrip> - <tag>On ENTER:</tag> - <itemize> - <item>enable port I/O access - - <item>save and initialise the bus/resource state - - <item>enter the SETUP server state - - <item>calls &s.code;ChipEnterVT()&e.code; for each screen - - <item>enter the OPERATING server state - - <item>validate GCs - - <item>Restore fb from saved pixmap for each screen - - <item>Enable all input devices - </itemize> - <tag>On LEAVE:</tag> - <itemize> - <item>Save fb to pixmap for each screen - - <item>validate GCs - - <item>enter the SETUP server state - - <item>calls &s.code;ChipLeaveVT()&e.code; for each screen - - <item>disable all input devices - - <item>restore bus/resource state - - <item>disables port I/O access - </itemize> - </descrip> - - <quote><p> - &s.code;Bool ChipEnterVT(int index, int flags)&e.code; - <quote><p> - This function should initialise the current video mode and - initialise the viewport, turn on the HW cursor if appropriate, - etc. - - Should it re-save the video state before initialising the video - mode? - - </quote> - - &s.code;void ChipLeaveVT(int index, int flags)&e.code; - <quote><p> - This function should restore the saved video state. If - appropriate it should also turn off the HW cursor, and invalidate - any pixmap/font caches. - - </quote> - - Optionally, &s.code;ChipLeaveVT()&e.code; may also unmap memory - regions. If so, &s.code;ChipEnterVT()&e.code; will need to remap - them. Additionally, if an aperture used to access video memory is - unmapped and remapped in this fashion, &s.code;ChipEnterVT()&e.code; - will also need to notify the framebuffer layers of the aperture's new - location in virtual memory. This is done with a call to the screen's - &s.code;ModifyPixmapHeader()&e.code; function, as follows - - <quote><p> - &s.code;(*pScreen->ModifyPixmapHeader)(pScrn->ppix, - &f.indent;-1, -1, -1, -1, -1, <it>NewApertureAddress</it>);&e.code; - <quote><p> - where the &s.code``ppix''&e.code; field in a ScrnInfoRec - points to the pixmap used by the screen's - &s.code;SaveRestoreImage()&e.code; function to hold the screen's - contents while switched out. - - </quote> - </quote> - - Currently, aperture remapping, as described here, should not be - attempted if the driver uses the &s.code;xf8_16bpp&e.code; or - &s.code;xf8_32bpp&e.code; framebuffer layers. A pending - restructuring of VT switching will address this restriction in - the near future. - - </quote> - - Other layers may wrap the &s.code;ChipEnterVT()&e.code; and - &s.code;ChipLeaveVT()&e.code; functions if they need to take some - action when these events are received. - -<sect1>End of server generation -<p> - - At the end of each server generation, the DIX layer calls - &s.code;ChipCloseScreen()&e.code; for each screen: - - <quote><p> - &s.code;Bool ChipCloseScreen(int index, ScreenPtr pScreen)&e.code; - <quote><p> - This function should restore the saved video state and unmap the - memory regions. - - It should also free per-screen data structures allocated by the - driver. Note that the persistent data held in the - &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field - should not be freed here because it is needed by subsequent server - generations. - - The &s.code;ScrnInfoRec&e.code;'s &s.code;vtSema&e.code; field - should be set to &s.code;FALSE&e.code; once the video HW state - has been restored. - - Before freeing the per-screen driver data the saved - &s.code;CloseScreen&e.code; value should be restored to - &s.code;pScreen->CloseScreen&e.code;, and that function should - be called after freeing the data. - - </quote> - </quote> - -<sect>Optional Driver Functions -<p> - -The functions outlined here can be called from the XFree86 common layer, -but their presence is optional. - -<sect1>Mode Validation -<p> - - When a mode validation helper supplied by the XFree86-common layer is - being used, it can be useful to provide a function to check for hw - specific mode constraints: - - <quote><p> - &s.code;ModeStatus ChipValidMode(int index, DisplayModePtr mode, - &f.indent;Bool verbose, int flags)&e.code; - <quote><p> - Check the passed mode for hw-specific constraints, and return the - appropriate status value. - - </quote> - </quote> - -<p> -This function may also modify the effective timings and clock of the passed -mode. These have been stored in the mode's &s.code;Crtc*&e.code; and -&s.code;SynthClock&e.code; elements, and have already been adjusted for -interlacing, doublescanning, multiscanning and clock multipliers and dividers. -The function should not modify any other mode field, unless it wants to modify -the mode timings reported to the user by &s.code;xf86PrintModes()&e.code;. - -<p> -The function is called once for every mode in the xorg.conf Monitor section -assigned to the screen, with &s.code;flags&e.code; set to -&s.code;MODECHECK_INITIAL&e.code;. It is subsequently called for every mode -in the xorg.conf Display subsection assigned to the screen, with -&s.code;flags&e.code; set to &s.code;MODECHECK_FINAL&e.code;. In the second -case, the mode will have successfully passed all other tests. In addition, -the &s.code;ScrnInfoRec&e.code;'s &s.code;virtualX&e.code;, -&s.code;virtualY&e.code; and &s.code;displayWidth&e.code; fields will have been -set as if the mode to be validated were to be the last mode accepted. - -<p> -In effect, calls with MODECHECK_INITIAL are intended for checks that do not -depend on any mode other than the one being validated, while calls with -MODECHECK_FINAL are intended for checks that may involve more than one mode. - -<sect1>Free screen data -<p> - - When a screen is deleted prior to the completion of the ScreenInit - phase the &s.code;ChipFreeScreen()&e.code; function is called when defined. - - <quote><p> - &s.code;void ChipFreeScreen(int scrnindex, int flags)&e.code; - <quote><p> - Free any driver-allocated data that may have been allocated up to - and including an unsuccessful &s.code;ChipScreenInit()&e.code; - call. This would predominantly be data allocated by - &s.code;ChipPreInit()&e.code; that persists across server - generations. It would include the &s.code;driverPrivate&e.code;, - and any ``privates'' entries that modules may have allocated. - - </quote> - </quote> - - -<sect>Recommended driver functions -<p> - -The functions outlined here are for internal use by the driver only. -They are entirely optional, and are never accessed directly from higher -layers. The sample function declarations shown here are just examples. -The interface (if any) used is up to the driver. - -<sect1>Save -<p> - - Save the video state. This could be called from &s.code;ChipScreenInit()&e.code; and - (possibly) &s.code;ChipEnterVT()&e.code;. - - <quote><p> - &s.code;void ChipSave(ScrnInfoPtr pScrn)&e.code; - <quote><p> - Saves the current state. This will only be saving pre-server - states or states before returning to the server. There is only - one current saved state per screen and it is stored in private - storage in the screen. - - </quote> - </quote> - -<sect1>Restore -<p> - - Restore the original video state. This could be called from the - &s.code;ChipLeaveVT()&e.code; and &s.code;ChipCloseScreen()&e.code; - functions. - - <quote><p> - &s.code;void ChipRestore(ScrnInfoPtr pScrn)&e.code; - <quote><p> - Restores the saved state from the private storage. Usually only - used for restoring text modes. - - </quote> - </quote> - - -<sect1>Initialise Mode -<p> - - Initialise a video mode. This could be called from the - &s.code;ChipScreenInit()&e.code;, &s.code;ChipSwitchMode()&e.code; - and &s.code;ChipEnterVT()&e.code; functions. - - <quote><p> - &s.code;Bool ChipModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)&e.code; - <quote><p> - Programs the hardware for the given video mode. - - </quote> - </quote> - - -<sect>Data and Data Structures -<p> - -<sect1>Command line data -<p> - -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: - -<quote><verb> - 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 -</verb></quote> - -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: - - <quote><p> - &s.code;int xf86GetVerbosity()&e.code; - <quote><p> - Returns the value of &s.code;xf86Verbose&e.code;. - - </quote> - - &s.code;int xf86GetDepth()&e.code; - <quote><p> - Returns the &s.cmd;-depth&e.cmd; command line setting. If not - set on the command line, &s.code;-1&e.code; is returned. - - </quote> - - &s.code;rgb xf86GetWeight()&e.code; - <quote><p> - Returns the &s.cmd;-weight&e.cmd; command line setting. If not - set on the command line, &s.code;{0, 0, 0}&e.code; is returned. - - </quote> - - &s.code;Gamma xf86GetGamma()&e.code; - <quote><p> - Returns the &s.cmd;-gamma&e.cmd; or &s.cmd;-rgamma&e.cmd;, - &s.cmd;-ggamma&e.cmd;, &s.cmd;-bgamma&e.cmd; command line settings. - If not set on the command line, &s.code;{0.0, 0.0, 0.0}&e.code; - is returned. - - </quote> - - &s.code;Bool xf86GetFlipPixels()&e.code; - <quote><p> - Returns &s.code;TRUE&e.code; if &s.cmd;-flippixels&e.cmd; is - present on the command line, and &s.code;FALSE&e.code; otherwise. - - </quote> - - &s.code;const char *xf86GetServerName()&e.code; - <quote><p> - Returns the name of the X server from the command line. - - </quote> - </quote> - -<sect1>Data handling -<p> - -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 &s.code;xf86InfoRec&e.code;. - -The screen-specific data collected from the config file is stored in -screen, device, display, monitor-specific data structures that are separate -from the &s.code;ScrnInfoRecs&e.code;, with the appropriate elements/fields -hooked into the &s.code;ScrnInfoRecs&e.code; as required. The screen -config data is held in &s.code;confScreenRec&e.code;, device data in -the &s.code;GDevRec&e.code;, monitor data in the &s.code;MonRec&e.code;, -and display data in the &s.code;DispRec&e.code;. - -The XFree86 common layer's screen specific data (the actual data in use -for each screen) is held in the &s.code;ScrnInfoRecs&e.code;. As has -been outlined above, the &s.code;ScrnInfoRecs&e.code; are allocated at probe -time, and it is the responsibility of the Drivers' &s.code;Probe()&e.code; -and &s.code;PreInit()&e.code; 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: - - <quote> - command line -> config file -> probed/default data - </quote> - -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 -&s.code;ScrnInfoRec&e.code;, consider the balance between the convenience -of things that lots of drivers need and the size/obscurity of the -&s.code;ScrnInfoRec&e.code;. - -Per-screen driver specific data that cannot be accommodated with the -static &s.code;ScrnInfoRec&e.code; fields is held in a driver-defined -data structure, a pointer to which is assigned to the -&s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field. This -is per-screen data that persists across server generations (as does the -bulk of the static &s.code;ScrnInfoRec&e.code; 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 &s.code;ScrnInfoRec&e.code; through it's &s.code;privates&e.code; -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 &s.code;xf86.h&e.code; and &s.code;xf86str.h&e.code; -files are visible to video drivers. Things defined in -&s.code;xf86Priv.h&e.code; and &s.code;xf86Privstr.h&e.code; are NOT -intended to be visible to video drivers, and it is an error for a driver -to include those files. - - -<sect1>Accessing global data -<p> - -Some other global state information that the drivers may access via -functions is as follows: - - <quote><p> - &s.code;Bool xf86ServerIsExiting()&e.code; - <quote><p> - Returns &s.code;TRUE&e.code; if the server is at the end of a - generation and is in the process of exiting, and - &s.code;FALSE&e.code; otherwise. - - </quote> - - &s.code;Bool xf86ServerIsResetting()&e.code; - <quote><p> - Returns &s.code;TRUE&e.code; if the server is at the end of a - generation and is in the process of resetting, and - &s.code;FALSE&e.code; otherwise. - - </quote> - - &s.code;Bool xf86ServerIsInitialising()&e.code; - <quote><p> - Returns &s.code;TRUE&e.code; if the server is at the beginning of - a generation and is in the process of initialising, and - &s.code;FALSE&e.code; otherwise. - - </quote> - - &s.code;Bool xf86ServerIsOnlyProbing()&e.code; - <quote><p> - Returns &s.code;TRUE&e.code; if the -probeonly command line flag - was specified, and &s.code;FALSE&e.code; otherwise. - - </quote> - - &s.code;Bool xf86CaughtSignal()&e.code; - <quote><p> - Returns &s.code;TRUE&e.code; if the server has caught a signal, - and &s.code;FALSE&e.code; otherwise. - - </quote> - </quote> - -<sect1>Allocating private data -<p> - -A driver and any module it uses may allocate per-screen private storage -in either the &s.code;ScreenRec&e.code; (DIX level) or -&s.code;ScrnInfoRec&e.code; (XFree86 common layer level). -&s.code;ScreenRec&e.code; storage persists only for a single server -generation, and &s.code;ScrnInfoRec&e.code; storage persists across -generations for the lifetime of the server. - -The &s.code;ScreenRec&e.code; &s.code;devPrivates&e.code; data must be -reallocated/initialised at the start of each new generation. This is -normally done from the &s.code;ChipScreenInit()&e.code; function, and -Init functions for other modules that it calls. Data allocated in this -way should be freed by the driver's &s.code;ChipCloseScreen()&e.code; -functions, and Close functions for other modules that it calls. A new -&s.code;devPrivates&e.code; entry is allocated by calling the -&s.code;AllocateScreenPrivateIndex()&e.code; function. - - <quote><p> - &s.code;int AllocateScreenPrivateIndex()&e.code; - <quote><p> - This function allocates a new element in the - &s.code;devPrivates&e.code; field of all currently existing - &s.code;ScreenRecs&e.code;. The return value is the index of this - new element in the &s.code;devPrivates&e.code; array. The - &s.code;devPrivates&e.code; field is of type - &s.code;DevUnion&e.code;: - - <verb> - typedef union _DevUnion { - pointer ptr; - long val; - unsigned long uval; - pointer (*fptr)(void); - } DevUnion; - </verb> - - 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 &s.code;-1&e.code; when there is an - error allocating the new index. - - </quote> - </quote> - -The &s.code;ScrnInfoRec&e.code; &s.code;privates&e.code; data persists -for the life of the server, so only needs to be allocated once. This -should be done from the &s.code;ChipPreInit()&e.code; function, and Init -functions for other modules that it calls. Data allocated in this way -should be freed by the driver's &s.code;ChipFreeScreen()&e.code; functions, -and Free functions for other modules that it calls. A new -&s.code;privates&e.code; entry is allocated by calling the -&s.code;xf86AllocateScrnInfoPrivateIndex()&e.code; function. - - - <quote><p> - &s.code;int xf86AllocateScrnInfoPrivateIndex()&e.code; - <quote><p> - This function allocates a new element in the &s.code;privates&e.code; - field of all currently existing &s.code;ScrnInfoRecs&e.code;. - The return value is the index of this new element in the - &s.code;privates&e.code; array. The &s.code;privates&e.code; - field is of type &s.code;DevUnion&e.code;: - - <verb> - typedef union _DevUnion { - pointer ptr; - long val; - unsigned long uval; - pointer (*fptr)(void); - } DevUnion; - </verb> - - 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 &s.code;ScreenRec&e.code; - (&s.code;AllocateScreenPrivateIndex()&e.code;) differs in this - respect by returning &s.code;-1&e.code; when the allocation fails. - - </quote> - </quote> - -<sect>Keeping Track of Bus Resources<label id="rac"> -<p> - -<sect1>Theory of Operation -<p> - -The XFree86 common layer has knowledge of generic access control mechanisms -for devices on certain bus systems (currently the PCI bus) as well as -of methods to enable or disable access to the buses itself. Furthermore -it can access information on resources decoded by these devices and if -necessary modify it. - -When first starting the Xserver collects all this information, saves it -for restoration, checks it for consistency, and if necessary, corrects -it. Finally it disables all resources on a generic level prior to -calling any driver function. - -When the &s.code;Probe()&e.code; function of each driver is called the -device sections are matched against the devices found in the system. -The driver may probe devices at this stage that cannot be identified by -using device independent methods. Access to all resources that can be -controlled in a device independent way is disabled. The -&s.code;Probe()&e.code; function should register all non-relocatable -resources at this stage. If a resource conflict is found between -exclusive resources the driver will fail immediately. Optionally the -driver might specify an &s.code;EntityInit()&e.code;, -&s.code;EntityLeave()&e.code; and &s.code;EntityEnter()&e.code; function. - -&s.code;EntityInit()&e.code; can be used to disable any shared resources -that are not controlled by the generic access control functions. It is -called prior to the PreInit phase regardless if an entity is active or -not. When calling the &s.code;EntityInit()&e.code;, -&s.code;EntityEnter()&e.code; and &s.code;EntityLeave()&e.code; functions -the common level will disable access to all other entities on a generic -level. Since the common level has no knowledge of device specific -methods to disable access to resources it cannot be guaranteed that -certain resources are not decoded by any other entity until the -&s.code;EntityInit()&e.code; or &s.code;EntityEnter()&e.code; phase is -finished. Device drivers should therefore register all those resources -which they are going to disable. If these resources are never to be -used by any driver function they may be flagged &s.code;ResInit&e.code; -so that they can be removed from the resource list after processing all -&s.code;EntityInit()&e.code; functions. &s.code;EntityEnter()&e.code; -should disable decoding of all resources which are not registered as -exclusive and which are not handled by the generic access control in -the common level. The difference to &s.code;EntityInit()&e.code; is -that the latter one is only called once during lifetime of the server. -It can therefore be used to set up variables prior to disabling resources. -&s.code;EntityLeave()&e.code; should restore the original state when -exiting the server or switching to a different VT. It also needs to -disable device specific access functions if they need to be disabled on -server exit or VT switch. The default state is to enable them before -giving up the VT. - -In &s.code;PreInit()&e.code; phase each driver should check if any -sharable resources it has registered during &s.code;Probe()&e.code; has -been denied and take appropriate action which could simply be to fail. -If it needs to access resources it has disabled during -&s.code;EntitySetup()&e.code; it can do so provided it has registered -these and will disable them before returning from -&s.code;PreInit()&e.code;. This also applies to all other driver -functions. Several functions are provided to request resource ranges, -register these, correct PCI config space and add replacements for the -generic access functions. Resources may be marked ``disabled'' or -``unused'' during OPERATING stage. Although these steps could also be -performed in &s.code;ScreenInit()&e.code;, this is not desirable. - -Following &s.code;PreInit()&e.code; phase the common level determines -if resource access control is needed. This is the case if more than -one screen is used. If necessary the RAC wrapper module is loaded. In -&s.code;ScreenInit()&e.code; the drivers can decide which operations -need to be placed under RAC. Available are the frame buffer operations, -the pointer operations and the colormap operations. Any operation that -requires resources which might be disabled during OPERATING state should -be set to use RAC. This can be specified separately for memory and IO -resources. - -When &s.code;ScreenInit()&e.code; phase is done the common level will -determine which shared resources are requested by more than one driver -and set the access functions accordingly. This is done following these -rules: - -<enum> -<item>The sharable resources registered by each entity are compared. If - a resource is registered by more than one entity the entity will be - marked to need to share this resources type (&s.code;IO&e.code; or - &s.code;MEM&e.code;). - -<item>A resource marked ``disabled'' during OPERATING state will be ignored - entirely. - -<item>A resource marked ``unused'' will only conflicts with an overlapping - resource of an other entity if the second is actually in use during - OPERATING state. - -<item>If an ``unused'' resource was found to conflict however the entity - does not use any other resource of this type the entire resource type - will be disabled for that entity. -</enum> - -The driver has the choice among different ways to control access to -certain resources: - -<enum> -<item>It can rely on the generic access functions. This is probably the - most common case. Here the driver only needs to register any resource - it is going to use. - -<item>It can replace the generic access functions by driver specific - ones. This will mostly be used in cases where no generic access - functions are available. In this case the driver has to make sure - these resources are disabled when entering the &s.code;PreInit()&e.code; - stage. Since the replacement functions are registered in - &s.code;PreInit()&e.code; the driver will have to enable these - resources itself if it needs to access them during this state. The - driver can specify if the replacement functions can control memory - and/or I/O resources separately. - -<item>The driver can enable resources itself when it needs them. Each - driver function enabling them needs to disable them before it will - return. This should be used if a resource which can be controlled - in a device dependent way is only required during SETUP state. This - way it can be marked ``unused'' during OPERATING state. -</enum> - -A resource which is decoded during OPERATING state however never accessed -by the driver should be marked unused. - -Since access switching latencies are an issue during Xserver operation, -the common level attempts to minimize the number of entities that need -to be placed under RAC control. When a wrapped operation is called, -the &s.code;EnableAccess()&e.code; function is called before control is -passed on. &s.code;EnableAccess()&e.code; checks if a screen is under -access control. If not it just establishes bus routing and returns. -If the screen needs to be under access control, -&s.code;EnableAccess()&e.code; determines which resource types -(&s.code;MEM&e.code;, &s.code;IO&e.code;) are required. Then it tests -if this access is already established. If so it simply returns. If -not it disables the currently established access, fixes bus routing and -enables access to all entities registered for this screen. - -Whenever a mode switch or a VT-switch is performed the common level will -return to SETUP state. - -<sect1>Resource Types -<p> - -Resource have certain properties. When registering resources each range -is accompanied by a flag consisting of the ORed flags of the different -properties the resource has. Each resource range may be classified -according to - -<itemize> - <item>its physical properties i.e., if it addresses - memory (&s.code;ResMem&e.code;) or - I/O space (&s.code;ResIo&e.code;), - <item>if it addresses a - block (&s.code;ResBlock&e.code;) or - sparse (&s.code;ResSparse&e.code;) - range, - <item>its access properties. -</itemize> - -There are two known access properties: - -<itemize> - <item>&s.code;ResExclusive&e.code; - for resources which may not be shared with any other device and - <item>&s.code;ResShared&e.code; - for resources which can be disabled and therefore can be shared. -</itemize> - -If it is necessary to test a resource against any type a generic access -type &s.code;ResAny&e.code; is provided. If this is set the resource -will conflict with any resource of a different entity intersecting its -range. Further it can be specified that a resource is decoded however -never used during any stage (&s.code;ResUnused&e.code;) or during -OPERATING state (&s.code;ResUnusedOpr&e.code;). A resource only visible -during the init functions (ie. &s.code;EntityInit()&e.code;, -&s.code;EntityEnter()&e.code; and &s.code;EntityLeave()&e.code; should -be registered with the flag &s.code;ResInit&e.code;. A resource that -might conflict with background resource ranges may be flagged with -&s.code;ResBios&e.code;. This might be useful when registering resources -ranges that were assigned by the system Bios. - -Several predefined resource lists are available for VGA and 8514/A -resources in &s.code;common/xf86Resources.h&e.code;. - -<sect1>Available Functions<label id="avail"> -<p> - -The functions provided for resource management are listed in their order -of use in the driver. - - -<sect2>Probe Phase -<p> - -In this phase each driver detects those resources it is able to drive, -creates an entity record for each of them, registers non-relocatable -resources and allocates screens and adds the resources to screens. - -Two helper functions are provided for matching device sections in the -xorg.conf file to the devices: - - <quote><p> - &s.code;int xf86MatchPciInstances(const char *driverName, int vendorID, - &f.indent;SymTabPtr chipsets, PciChipsets *PCIchipsets, - &f.indent;GDevPtr *devList, int numDevs, DriverPtr drvp, - &f.indent;int **foundEntities)&e.code; - <quote><p> - This function finds matches between PCI cards that a driver supports - and config file device sections. It is intended for use in the - &s.code;ChipProbe()&e.code; function of drivers for PCI cards. - Only probed PCI devices with a vendor ID matching - &s.code;vendorID&e.code; are considered. &s.code;devList&e.code; - and &s.code;numDevs&e.code; are typically those found from - calling &s.code;xf86MatchDevice()&e.code;, and represent the active - config file device sections relevant to the driver. - &s.code;PCIchipsets&e.code; is a table that provides a mapping - between the PCI device IDs, the driver's internal chipset tokens - and a list of fixed resources. - - When a device section doesn't have a &s.key;BusID&e.key; entry it - can only match the primary video device. Secondary devices are - only matched with device sections that have a matching - &s.key;BusID&e.key; entry. - - Once the preliminary matches have been found, a final match is - confirmed by checking if the chipset override, ChipID override or - probed PCI chipset type match one of those given in the - &s.code;chipsets&e.code; and &s.code;PCIchipsets&e.code; lists. - The &s.code;PCIchipsets&e.code; list includes a list of the PCI - device IDs supported by the driver. The list should be terminated - with an entry with PCI ID &s.code;-1&e.code;". The - &s.code;chipsets&e.code; list is a table mapping the driver's - internal chipset tokens to names, and should be terminated with - a &s.code;NULL&e.code; entry. Only those entries with a - corresponding entry in the &s.code;PCIchipsets&e.code; list are - considered. The order of precedence is: config file chipset, - config file ChipID, probed PCI device ID. - - In cases where a driver handles PCI chipsets with more than one - vendor ID, it may set &s.code;vendorID&e.code; to - &s.code;0&e.code;, and OR each devID in the list with (the - vendor ID << 16). - - Entity index numbers for confirmed matches are returned as an - array via &s.code;foundEntities&e.code;. The PCI information, - chipset token and device section for each match are found in the - &s.code;EntityInfoRec&e.code; referenced by the indices. - - The function return value is the number of confirmed matches. A - return value of &s.code;-1&e.code; indicates an internal error. - The returned &s.code;foundEntities&e.code; array should be freed - by the driver with &s.code;xfree()&e.code; when it is no longer - needed in cases where the return value is greater than zero. - - </quote> - - &s.code;int xf86MatchIsaInstances(const char *driverName, - &f.indent;SymTabPtr chipsets, IsaChipsets *ISAchipsets, - &f.indent;DriverPtr drvp, FindIsaDevProc FindIsaDevice, - &f.indent;GDevPtr *devList, int numDevs, - int **foundEntities)&e.code; - <quote><p> - This function finds matches between ISA cards that a driver supports - and config file device sections. It is intended for use in the - &s.code;ChipProbe()&e.code; function of drivers for ISA cards. - &s.code;devList&e.code; and &s.code;numDevs&e.code; are - typically those found from calling &s.code;xf86MatchDevice()&e.code;, - and represent the active config file device sections relevant to - the driver. &s.code;ISAchipsets&e.code; is a table that provides - a mapping between the driver's internal chipset tokens and the - resource classes. &s.code;FindIsaDevice&e.code; is a - driver-provided function that probes the hardware and returns the - chipset token corresponding to what was detected, and - &s.code;-1&e.code; if nothing was detected. - - If the config file device section contains a chipset entry, then - it is checked against the &s.code;chipsets&e.code; list. When - no chipset entry is present, the &s.code;FindIsaDevice&e.code; - function is called instead. - - Entity index numbers for confirmed matches are returned as an - array via &s.code;foundEntities&e.code;. The chipset token and - device section for each match are found in the - &s.code;EntityInfoRec&e.code; referenced by the indices. - - The function return value is the number of confirmed matches. A - return value of &s.code;-1&e.code; indicates an internal error. - The returned &s.code;foundEntities&e.code; array should be freed - by the driver with &s.code;xfree()&e.code; when it is no longer - needed in cases where the return value is greater than zero. - - </quote> - </quote> - -These two helper functions make use of several core functions that are -available at the driver level: - - <quote><p> - &s.code;Bool xf86ParsePciBusString(const char *busID, int *bus, - &f.indent;int *device, int *func)&e.code; - <quote><p> - Takes a &s.code;BusID&e.code; string, and if it is in the correct - format, returns the PCI &s.code;bus&e.code;, &s.code;device&e.code;, - &s.code;func&e.code; values that it indicates. The format of the - string is expected to be "PCI:bus:device:func" where each of `bus', - `device' and `func' are decimal integers. The ":func" part may - be omitted, and the func value assumed to be zero, but this isn't - encouraged. The "PCI" prefix may also be omitted. The prefix - "AGP" is currently equivalent to the "PCI" prefix. If the string - isn't a valid PCI BusID, the return value is &s.code;FALSE&e.code;. - - </quote> - - - &s.code;Bool xf86ComparePciBusString(const char *busID, int bus, - &f.indent;int device, int func)&e.code; - <quote><p> - Compares a &s.code;BusID&e.code; string with PCI &s.code;bus&e.code;, - &s.code;device&e.code;, &s.code;func&e.code; values. If they - match &s.code;TRUE&e.code; is returned, and &s.code;FALSE&e.code; - if they don't. - - </quote> - - &s.code;Bool xf86ParseIsaBusString(const char *busID)&e.code; - <quote><p> - Compares a &s.code;BusID&e.code; string with the ISA bus ID string - ("ISA" or "ISA:"). If they match &s.code;TRUE&e.code; is returned, - and &s.code;FALSE&e.code; if they don't. - - </quote> - - &s.code;Bool xf86CheckPciSlot(int bus, int device, int func)&e.code; - <quote><p> - Checks if the PCI slot &s.code;bus:device:func&e.code; has been - claimed. If so, it returns &s.code;FALSE&e.code;, and otherwise - &s.code;TRUE&e.code;. - - </quote> - - &s.code;int xf86ClaimPciSlot(int bus, int device, int func, DriverPtr drvp, - &f.indent;int chipset, GDevPtr dev, Bool active)&e.code; - <quote><p> - This function is used to claim a PCI slot, allocate the associated - entity record and initialise their data structures. The return - value is the index of the newly allocated entity record, or - &s.code;-1&e.code; if the claim fails. This function should always - succeed if &s.code;xf86CheckPciSlot()&e.code; returned - &s.code;TRUE&e.code; for the same PCI slot. - - </quote> - - &s.code;Bool xf86IsPrimaryPci(void)&e.code; - <quote><p> - This function returns &s.code;TRUE&e.code; if the primary card is - a PCI device, and &s.code;FALSE&e.code; otherwise. - - </quote> - - &s.code;int xf86ClaimIsaSlot(DriverPtr drvp, int chipset, - &f.indent;GDevPtr dev, Bool active)&e.code; - <quote><p> - This allocates an entity record entity and initialise the data - structures. The return value is the index of the newly allocated - entity record. - - </quote> - - &s.code;Bool xf86IsPrimaryIsa(void)&e.code; - <quote><p> - This function returns &s.code;TRUE&e.code; if the primary card is - an ISA (non-PCI) device, and &s.code;FALSE&e.code; otherwise. - - </quote> - </quote> - -Two helper functions are provided to aid configuring entities: - <quote><p> - &s.code;ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn, - &f.indent;int scrnFlag, int entityIndex, - &f.indent;PciChipsets *p_chip, - &f.indent;resList res, EntityProc init, - &f.indent;EntityProc enter, EntityProc leave, - &f.indent;pointer private)&e.code; - <p> - &s.code;ScrnInfoPtr xf86ConfigIsaEntity(ScrnInfoPtr pScrn, - &f.indent;int scrnFlag, int entityIndex, - &f.indent;IsaChipsets *i_chip, - &f.indent;resList res, EntityProc init, - &f.indent;EntityProc enter, EntityProc leave, - &f.indent;pointer private)&e.code; - <quote><p> - These functions are used to register the non-relocatable resources - for an entity, and the optional entity-specific &s.code;Init&e.code;, &s.code;Enter&e.code; and - &s.code;Leave&e.code; functions. Usually the list of fixed resources is obtained - from the Isa/PciChipsets lists. However an additional list of - resources may be passed. Generally this is not required. - For active entities a &s.code;ScrnInfoRec&e.code; is allocated - if the &s.code;pScrn&e.code; argument is &s.code;NULL&e.code;. -The - return value is &s.code;TRUE&e.code; when successful. The init, enter, leave - functions are defined as follows: - - <quote> - &s.code;typedef void (*EntityProc)(int entityIndex, - &f.indent;pointer private)&e.code; - </quote> - - They are passed the entity index and a pointer to a private scratch - area. This can be set up during &s.code;Probe()&e.code; and - its address can be passed to - &s.code;xf86ConfigIsaEntity()&e.code; and - &s.code;xf86ConfigPciEntity()&e.code; as the last argument. - - </quote> - </quote> - -These two helper functions make use of several core functions that are -available at the driver level: - <quote><p> - &s.code;void xf86ClaimFixedResources(resList list, int entityIndex)&e.code; - <quote><p> - This function registers the non-relocatable resources which cannot - be disabled and which therefore would cause the server to fail - immediately if they were found to conflict. It also records - non-relocatable but sharable resources for processing after the - &s.code;Probe()&e.code; phase. - - </quote> - - &s.code;Bool xf86SetEntityFuncs(int entityIndex, EntityProc init, - &f.indent;EntityProc enter, EntityProc leave, pointer)&e.code; - <quote><p> - This function registers with an entity the &s.code;init&e.code;, - &s.code;enter&e.code;, &s.code;leave&e.code; functions along - with the pointer to their private area. - - </quote> - - &s.code;void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)&e.code; - <quote><p> - This function associates the entity referenced by - &s.code;entityIndex&e.code; with the screen. - - </quote> - </quote> - -<sect2>PreInit Phase -<p> - -During this phase the remaining resources should be registered. -&s.code;PreInit()&e.code; should call &s.code;xf86GetEntityInfo()&e.code; -to obtain a pointer to an &s.code;EntityInfoRec&e.code; for each entity -it is able to drive and check if any resource are listed in its -&s.code;resources&e.code; field. If resources registered in the Probe -phase have been rejected in the post-Probe phase -(&s.code;resources&e.code; is non-&s.code;NULL&e.code;), then the driver should -decide if it can continue without using these or if it should fail. - - <quote><p> - &s.code;EntityInfoPtr xf86GetEntityInfo(int entityIndex)&e.code; - <quote><p> - This function returns a pointer to the &s.code;EntityInfoRec&e.code; - referenced by &s.code;entityIndex&e.code;. The returned - &s.code;EntityInfoRec&e.code; should be freed with - &s.code;xfree()&e.code; when no longer needed. - - </quote> - </quote> -Several functions are provided to simplify resource registration: - <quote><p> - &s.code;Bool xf86IsEntityPrimary(int entityIndex)&e.code; - <quote><p> - This function returns &s.code;TRUE&e.code; if the entity referenced - by &s.code;entityIndex&e.code; is the primary display device (i.e., - the one initialised at boot time and used in text mode). - - </quote> - - &s.code;Bool xf86IsScreenPrimary(int scrnIndex)&e.code; - <quote><p> - This function returns &s.code;TRUE&e.code; if the primary entity - is registered with the screen referenced by - &s.code;scrnIndex&e.code;. - - </quote> - - &s.code;pciVideoPtr xf86GetPciInfoForEntity(int entityIndex)&e.code; - <quote><p> - This function returns a pointer to the &s.code;pciVideoRec&e.code; - for the specified entity. If the entity is not a PCI device, - &s.code;NULL&e.code; is returned. - - </quote> - </quote> - -The primary function for registration of resources is: - <quote><p> - &s.code;resPtr xf86RegisterResources(int entityIndex, resList list, - &f.indent;int access)&e.code; - <quote><p> - This function tries to register the resources in - &s.code;list&e.code;. If list is &s.code;NULL&e.code; it tries - to determine the resources automatically. This only works for - entities that provide a generic way to read out the resource ranges - they decode. So far this is only the case for PCI devices. By - default the PCI resources are registered as shared - (&s.code;ResShared&e.code;) if the driver wants to set a different - access type it can do so by specifying the access flags in the - third argument. A value of &s.code;0&e.code; means to use the - default settings. If for any reason the resource broker is not - able to register some of the requested resources the function will - return a pointer to a list of the failed ones. In this case the - driver may be able to move the resource to different locations. - In case of PCI bus entities this is done by passing the list of - failed resources to &s.code;xf86ReallocatePciResources()&e.code;. - When the registration succeeds, the return value is - &s.code;NULL&e.code;. - - </quote> - - &s.code;resPtr xf86ReallocatePciResources(int entityIndex, resPtr pRes)&e.code; - <quote><p> - This function takes a list of PCI resources that need to be - reallocated and returns &s.code;NULL&e.code when all relocations are - successful. - &s.code;xf86RegisterResources()&e.code; should be called again to - register the relocated resources with the broker. - If the reallocation fails, a list of the resources that could not be - relocated is returned. - - </quote> - </quote> - -Two functions are provided to obtain a resource range of a given type: - <quote><p> - &s.code;resRange xf86GetBlock(long type, memType size, - &f.indent;memType window_start, memType window_end, - &f.indent;memType align_mask, resPtr avoid)&e.code; - <quote><p> - This function tries to find a block range of size - &s.code;size&e.code; and type &s.code;type&e.code; in a window - bound by &s.code;window_start&e.code; and &s.code;window_end&e.code; - with the alignment specified in &s.code;align_mask&e.code;. - Optionally a list of resource ranges which should be avoided within - the window can be supplied. On failure a zero-length range of - type &s.code;ResEnd&e.code; will be returned. - - </quote> - &s.code;resRange xf86GetSparse(long type, memType fixed_bits, - &f.indent;memType decode_mask, memType address_mask, - &f.indent;resPtr avoid)&e.code; - <quote><p> - This function is like the previous one, but attempts to find a - sparse range instead of a block range. Here three values have to - be specified: the &s.code;address_mask&e.code; which marks all - bits of the mask part of the address, the &s.code;decode_mask&e.code; - which masks out the bits which are hardcoded and are therefore - not available for relocation and the values of the fixed bits. - The function tries to find a base that satisfies the given condition. - If the function fails it will return a zero range of type - &s.code;ResEnd&e.code;. Optionally it might be passed a list of - resource ranges to avoid. - - </quote> - </quote> - -Some PCI devices are broken in the sense that they return invalid size -information for a certain resource. In this case the driver can supply -the correct size and make sure that the resource range allocated for -the card is large enough to hold the address range decoded by the card. -The function &s.code;xf86FixPciResource()&e.code; can be used to do this: - <quote><p> - &s.code;Bool xf86FixPciResource(int entityIndex, unsigned int prt, - &f.indent;CARD32 alignment, long type)&e.code; - <quote><p> - This function fixes a PCI resource allocation. The - &s.code;prt&e.code; parameter contains the number of the PCI base - register that needs to be fixed (&s.code;0-5&e.code;, and - &s.code;6&e.code; for the BIOS base register). The size is - specified by the alignment. Since PCI resources need to span an - integral range of size &s.code;2^n&e.code;, the alignment also - specifies the number of addresses that will be decoded. If the - driver specifies a type mask it can override the default type for - PCI resources which is &s.code;ResShared&e.code;. The resource - broker needs to know that to find a matching resource range. This - function should be called before calling - &s.code;xf86RegisterResources()&e.code;. The return value is - &s.code;TRUE&e.code; when the function succeeds. - - </quote> - - &s.code;Bool xf86CheckPciMemBase(pciVideoPtr pPci, memType base)&e.code; - <quote><p> - This function checks that the memory base address specified matches - one of the PCI base address register values for the given PCI - device. This is mostly used to check that an externally provided - base address (e.g., from a config file) matches an actual value - allocated to a device. - - </quote> - </quote> - -The driver may replace the generic access control functions for an entity. -This is done with the &s.code;xf86SetAccessFuncs()&e.code;: - <quote><p> - &s.code;void xf86SetAccessFuncs(EntityInfoPtr pEnt, - &f.indent;xf86SetAccessFuncPtr funcs, - &f.indent;xf86SetAccessFuncPtr oldFuncs)&e.code; - <quote><p> - with: - </quote> - - <verb> - typedef struct { - xf86AccessPtr mem; - xf86AccessPtr io; - xf86AccessPtr io_mem; - } xf86SetAccessFuncRec, *xf86SetAccessFuncPtr; - </verb> - - <quote><p> - The driver can pass three functions: one for I/O access, one for - memory access and one for combined memory and I/O access. If the - memory access and combined access functions are identical the - common level assumes that the memory access cannot be controlled - independently of I/O access, if the I/O access function and the - combined access functions are the same it is assumed that I/O can - not be controlled independently. If memory and I/O have to be - controlled together all three values should be the same. If a - non &s.code;NULL&e.code; value is passed as third argument it is - interpreted as an address where to store the old access record. - If the third argument is &s.code;NULL&e.code; it will be assumed - that the generic access should be enabled before replacing the - access functions. Otherwise it will be disabled. The driver may - enable them itself using the returned values. It should do this - from its replacement access functions as the generic access may - be disabled by the common level on certain occasions. If replacement - functions are specified they must control all resources of the - specific type registered for the entity. - - </quote> - </quote> - -To find out if a specific resource range conflicts with another -resource the &s.code;xf86ChkConflict()&e.code; function may be used: - <quote><p> - &s.code;memType xf86ChkConflict(resRange *rgp, int entityIndex)&e.code; - <quote><p> - This function checks if the resource range &s.code;rgp&e.code; of - for the specified entity conflicts with with another resource. - If a conflict is found, the address of the start of the conflict - is returned. The return value is zero when there is no conflict. - - </quote> - </quote> - -The OPERATING state properties of previously registered fixed resources -can be set with the &s.code;xf86SetOperatingState()&e.code; function: - <quote><p> - &s.code;resPtr xf86SetOperatingState(resList list, int entityIndex, - &f.indent;int mask)&e.code; - <quote><p> - This function is used to set the status of a resource during - OPERATING state. &s.code;list&e.code; holds a list to which - &s.code;mask&e.code; is to be applied. The parameter - &s.code;mask&e.code; may have the value &s.code;ResUnusedOpr&e.code; - and &s.code;ResDisableOpr&e.code;. The first one should be used - if a resource isn't used by the driver during OPERATING state - although it is decoded by the device, while the latter one indicates - that the resource is not decoded during OPERATING state. Note - that the resource ranges have to match those specified during - registration. If a range has been specified starting at - &s.code;A&e.code; and ending at &s.code;B&e.code; and suppose - &s.code;C&e.code; us a value satisfying - &s.code;A < C < B&e.code; one may not - specify the resource range &s.code;(A,B)&e.code; by splitting it - into two ranges &s.code;(A,C)&e.code; and &s.code;(C,B)&e.code;. - - </quote> - </quote> - -The following two functions are provided for special cases: - <quote><p> - &s.code;void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)&e.code; - <quote><p> - This function may be used to remove an entity from a screen. This - only makes sense if a screen has more than one entity assigned or - the screen is to be deleted. No test is made if the screen has - any entities left. - - </quote> - - &s.code;void xf86DeallocateResourcesForEntity(int entityIndex, long type)&e.code; - <quote><p> - This function deallocates all resources of a given type registered - for a certain entity from the resource broker list. - - </quote> - </quote> - -<sect2>ScreenInit Phase -<p> - -All that is required in this phase is to setup the RAC flags. Note that -it is also permissible to set these flags up in the PreInit phase. The -RAC flags are held in the &s.code;racIoFlags&e.code; and &s.code;racMemFlags&e.code; fields of the -&s.code;ScrnInfoRec&e.code; for each screen. They specify which graphics operations -might require the use of shared resources. This can be specified -separately for memory and I/O resources. The available flags are defined -in &s.code;rac/xf86RAC.h&e.code;. They are: - - &s.code;RAC_FB&e.code; - <quote> - for framebuffer operations (including hw acceleration) - </quote> - &s.code;RAC_CURSOR&e.code; - <quote> - for Cursor operations - (??? I'm not sure if we need this for SW cursor it depends - on which level the sw cursor is drawn) - </quote> - &s.code;RAC_COLORMAP&e.code; - <quote> - for colormap operations - </quote> - &s.code;RAC_VIEWPORT&e.code; - <quote> - for the call to &s.code;ChipAdjustFrame()&e.code; </quote> - - -The flags are ORed together. - -<sect>Config file ``Option'' entries<label id="options"> -<p> - -Option entries are permitted in most sections and subsections of the -config file. There are two forms of option entries: - -<descrip> -<tag>Option "option-name"</tag> - A boolean option. -<tag>Option "option-name" "option-value"</tag> - An option with an arbitrary value. -</descrip> - -The option entries are handled by the parser, and a list of the parsed -options is included with each of the appropriate data structures that -the drivers have access to. The data structures used to hold the option -information are opaque to the driver, and a driver must not access the -option data directly. Instead, the common layer provides a set of -functions that may be used to access, check and manipulate the option -data. - -First, the low level option handling functions. In most cases drivers -would not need to use these directly. - - <quote><p> - &s.code;pointer xf86FindOption(pointer options, const char *name)&e.code; - <quote><p> - Takes a list of options and an option name, and returns a handle - for the first option entry in the list matching the name. Returns - &s.code;NULL&e.code; if no match is found. - - </quote> - - &s.code;char *xf86FindOptionValue(pointer options, const char *name)&e.code; - <quote><p> - Takes a list of options and an option name, and returns the value - associated with the first option entry in the list matching the - name. If the matching option has no value, an empty string - (&s.code;""&e.code;) is returned. Returns &s.code;NULL&e.code; - if no match is found. - - </quote> - - &s.code;void xf86MarkOptionUsed(pointer option)&e.code; - <quote><p> - Takes a handle for an option, and marks that option as used. - - </quote> - - &s.code;void xf86MarkOptionUsedByName(pointer options, const char *name)&e.code; - <quote><p> - Takes a list of options and an option name and marks the first - option entry in the list matching the name as used. - - </quote> - </quote> - - -Next, the higher level functions that most drivers would use. - <quote><p> - &s.code;void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)&e.code; - <quote><p> - Collect the options from each of the config file sections used by - the screen (&s.code;pScrn&e.code;) and return the merged list as - &s.code;pScrn->options&e.code;. This function requires that - &s.code;pScrn->confScreen&e.code;, &s.code;pScrn->display&e.code;, - &s.code;pScrn->monitor&e.code;, - &s.code;pScrn->numEntities&e.code;, and - &s.code;pScrn->entityList&e.code; are initialised. - &s.code;extraOpts&e.code; may optionally be set to an additional - list of options to be combined with the others. The order of - precedence for options is &s.code;extraOpts&e.code;, display, - confScreen, monitor, device. - - </quote> - - &s.code;void xf86ProcessOptions(int scrnIndex, pointer options, - &f.indent;OptionInfoPtr optinfo)&e.code; - <quote><p> - Processes a list of options according to the information in the - array of &s.code;OptionInfoRecs&e.code; (&s.code;optinfo&e.code;). - The resulting information is stored in the &s.code;value&e.code; - fields of the appropriate &s.code;optinfo&e.code; entries. The - &s.code;found&e.code; fields are set to &s.code;TRUE&e.code; - when an option with a value of the correct type if found, and - &s.code;FALSE&e.code; otherwise. The &s.code;type&e.code; field - is used to determine the expected value type for each option. - Each option in the list of options for which there is a name match - (but not necessarily a value type match) is marked as used. - Warning messages are printed when option values don't match the - types specified in the optinfo data. - - NOTE: If this function is called before a driver's screen number - is known (e.g., from the &s.code;ChipProbe()&e.code; function) a - &s.code;scrnIndex&e.code; value of &s.code;-1&e.code; should be - used. - - NOTE 2: Given that this function stores into the - &s.code;OptionInfoRecs&e.code; pointed to by &s.code;optinfo&e.code, - the caller should ensure the &s.code;OptionInfoRecs&e.code; are - (re-)initialised before the call, especially if the caller expects - to use the predefined option values as defaults. - - The &s.code;OptionInfoRec&e.code; is defined as follows: - - <verb> - typedef struct { - double freq; - int units; - } OptFrequency; - - typedef union { - unsigned long num; - char * str; - double realnum; - Bool bool; - OptFrequency freq; - } ValueUnion; - - typedef enum { - OPTV_NONE = 0, - OPTV_INTEGER, - OPTV_STRING, /* a non-empty string */ - OPTV_ANYSTR, /* Any string, including an empty one */ - OPTV_REAL, - OPTV_BOOLEAN, - OPTV_FREQ - } OptionValueType; - - typedef enum { - OPTUNITS_HZ = 1, - OPTUNITS_KHZ, - OPTUNITS_MHZ - } OptFreqUnits; - - typedef struct { - int token; - const char* name; - OptionValueType type; - ValueUnion value; - Bool found; - } OptionInfoRec, *OptionInfoPtr; - </verb> - - &s.code;OPTV_FREQ&e.code; can be used for options values that are - frequencies. These values are a floating point number with an - optional unit name appended. The unit name can be one of "Hz", - "kHz", "k", "MHz", "M". The multiplier associated with the unit - is stored in &s.code;freq.units&e.code;, and the scaled frequency - is stored in &s.code;freq.freq&e.code;. When no unit is specified, - &s.code;freq.units&e.code; is set to &s.code;0&e.code;, and - &s.code;freq.freq&e.code; is unscaled. - - Typical usage is to setup an array of - &s.code;OptionInfoRecs&e.code; with all fields initialised. - The &s.code;value&e.code; and &s.code;found&e.code; fields get - set by &s.code;xf86ProcessOptions()&e.code;. For cases where the - value parsing is more complex, the driver should specify - &s.code;OPTV_STRING&e.code;, and parse the string itself. An - example of using this option handling is included in the - <ref id="sample" name="Sample Driver"> section. - - </quote> - - &s.code;void xf86ShowUnusedOptions(int scrnIndex, pointer options)&e.code; - <quote><p> - Prints out warning messages for each option in the list of options - that isn't marked as used. This is intended to show options that - the driver hasn't recognised. It would normally be called near - the end of the &s.code;ChipScreenInit()&e.code; function, but only - when &s.code;serverGeneration == 1&e.code;. - - </quote> - - &s.code;OptionInfoPtr xf86TokenToOptinfo(const OptionInfoRec *table, - &f.indent;int token)&e.code; - - <quote><p> - Returns a pointer to the &s.code;OptionInfoRec&e.code; in - &s.code;table&e.code; with a token field matching - &s.code;token&e.code;. Returns &s.code;NULL&e.code; if no match - is found. - - </quote> - - &s.code;Bool xf86IsOptionSet(const OptionInfoRec *table, int token)&e.code; - <quote><p> - Returns the &s.code;found&e.code; field of the - &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; with a - &s.code;token&e.code; field matching &s.code;token&e.code;. This - can be used for options of all types. Note that for options of - type &s.code;OPTV_BOOLEAN&e.code;, it isn't sufficient to check - this to determine the value of the option. Returns - &s.code;FALSE&e.code; if no match is found. - - </quote> - - &s.code;char *xf86GetOptValString(const OptionInfoRec *table, int token)&e.code; - <quote><p> - Returns the &s.code;value.str&e.code; field of the - &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; with a - token field matching &s.code;token&e.code;. Returns - &s.code;NULL&e.code; if no match is found. - - </quote> - - &s.code;Bool xf86GetOptValInteger(const OptionInfoRec *table, int token, - &f.indent;int *value)&e.code; - <quote><p> - Returns via &s.code;*value&e.code; the &s.code;value.num&e.code; - field of the &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; - with a &s.code;token&e.code; field matching &s.code;token&e.code;. - &s.code;*value&e.code; is only changed when a match is found so - it can be safely initialised with a default prior to calling this - function. The function return value is as for - &s.code;xf86IsOptionSet()&e.code;. - - </quote> - - &s.code;Bool xf86GetOptValULong(const OptionInfoRec *table, int token, - &f.indent;unsigned long *value)&e.code; - <quote><p> - Like &s.code;xf86GetOptValInteger()&e.code;, except the value is - treated as an &s.code;unsigned long&e.code;. - - </quote> - - &s.code;Bool xf86GetOptValReal(const OptionInfoRec *table, int token, - &f.indent;double *value)&e.code; - <quote><p> - Like &s.code;xf86GetOptValInteger()&e.code;, except that - &s.code;value.realnum&e.code; is used. - - </quote> - - &s.code;Bool xf86GetOptValFreq(const OptionInfoRec *table, int token, - &f.indent;OptFreqUnits expectedUnits, double *value)&e.code; - <quote><p> - Like &s.code;xf86GetOptValInteger()&e.code;, except that the - &s.code;value.freq&e.code; data is returned. The frequency value - is scaled to the units indicated by &s.code;expectedUnits&e.code;. - The scaling is exact when the units were specified explicitly in - the option's value. Otherwise, the &s.code;expectedUnits&e.code; - field is used as a hint when doing the scaling. In this case, - values larger than &s.code;1000&e.code; are assumed to have be - specified in the next smallest units. For example, if the Option - value is "10000" and expectedUnits is &s.code;OPTUNITS_MHZ&e.code;, - the value returned is &s.code;10&e.code;. - - </quote> - - &s.code;Bool xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value)&e.code; - <quote><p> - This function is used to check boolean options - (&s.code;OPTV_BOOLEAN&e.code;). If the function return value is - &s.code;FALSE&e.code;, it means the option wasn't set. Otherwise - &s.code;*value&e.code; is set to the boolean value indicated by - the option's value. No option &s.code;value&e.code; is interpreted - as &s.code;TRUE&e.code;. Option values meaning &s.code;TRUE&e.code; - are "1", "yes", "on", "true", and option values meaning - &s.code;FALSE&e.code; are "0", "no", "off", "false". Option names - both with the "no" prefix in their names, and with that prefix - removed are also checked and handled in the obvious way. - &s.code;*value&e.code; is not changed when the option isn't present. - It should normally be set to a default value before calling this - function. - - </quote> - - &s.code;Bool xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def)&e.code; - <quote><p> - This function is used to check boolean options - (&s.code;OPTV_BOOLEAN&e.code;). If the option is set, its value - is returned. If the options is not set, the default value specified - by &s.code;def&e.code; is returned. The option interpretation is - the same as for &s.code;xf86GetOptValBool()&e.code;. - - </quote> - - &s.code;int xf86NameCmp(const char *s1, const char *s2)&e.code; - <quote><p> - This function should be used when comparing strings from the config - file with expected values. It works like &s.code;strcmp()&e.code;, - but is not case sensitive and space, tab, and `<tt>_</tt>' characters - are ignored in the comparison. The use of this function isn't - restricted to parsing option values. It may be used anywhere - where this functionality required. - - </quote> - </quote> - -<sect>Modules, Drivers, Include Files and Interface Issues -<p> - -NOTE: this section is incomplete. - - -<sect1>Include files -<p> - -The following include files are typically required by video drivers: - - <quote><p> - All drivers should include these: - <quote> - &s.code;"xf86.h"&nl; - "xf86_OSproc.h"&nl; - "xf86_ansic.h"&nl; - "xf86Resources.h"&e.code; - </quote> - Wherever inb/outb (and related things) are used the following should be - included: - <quote> - &s.code;"compiler.h"&e.code; - </quote> - Note: in drivers, this must be included after &s.code;"xf86_ansic.h"&e.code;. - - Drivers that need to access PCI vendor/device definitions need this: - <quote> - &s.code;"xf86PciInfo.h"&e.code; - </quote> - - Drivers that need to access the PCI config space need this: - <quote> - &s.code;"xf86Pci.h"&e.code; - </quote> - - Drivers that initialise a SW cursor need this: - <quote> - &s.code;"mipointer.h"&e.code; - </quote> - - All drivers implementing backing store need this: - <quote> - &s.code;"mibstore.h"&e.code; - </quote> - - All drivers using the mi colourmap code need this: - <quote> - &s.code;"micmap.h"&e.code; - </quote> - - If a driver uses the vgahw module, it needs this: - <quote> - &s.code;"vgaHW.h"&e.code; - </quote> - - Drivers supporting VGA or Hercules monochrome screens need: - <quote> - &s.code;"xf1bpp.h"&e.code; - </quote> - - Drivers supporting VGA or EGC 16-colour screens need: - <quote> - &s.code;"xf4bpp.h"&e.code; - </quote> - - Drivers using cfb need: - <quote> - &s.code;#define PSZ 8&nl; - #include "cfb.h"&nl; - #undef PSZ&e.code; - </quote> - - Drivers supporting bpp 16, 24 or 32 with cfb need one or more of: - <quote> - &s.code;"cfb16.h"&nl; - "cfb24.h"&nl; - "cfb32.h"&e.code; - </quote> - - If a driver uses XAA, it needs these: - <quote> - &s.code;"xaa.h"&nl; - "xaalocal.h"&e.code; - </quote> - - If a driver uses the fb manager, it needs this: - <quote> - &s.code;"xf86fbman.h"&e.code; - </quote> - </quote> - -Non-driver modules should include &s.code;"xf86_ansic.h"&e.code; to get the correct -wrapping of ANSI C/libc functions. - -All modules must NOT include any system include files, or the following: - - <quote> - &s.code;"xf86Priv.h"&nl; - "xf86Privstr.h"&nl; - "xf86_OSlib.h"&nl; - "Xos.h"&e.code; - </quote> - -In addition, "xf86_libc.h" must not be included explicitly. It is -included implicitly by "xf86_ansic.h". - - -<sect>Offscreen Memory Manager -<p> - -Management of offscreen video memory may be handled by the XFree86 -framebuffer manager. Once the offscreen memory manager is running, -drivers or extensions may allocate, free or resize areas of offscreen -video memory using the following functions (definitions taken from -&s.code;xf86fbman.h&e.code;): - -<code> - typedef struct _FBArea { - ScreenPtr pScreen; - BoxRec box; - int granularity; - void (*MoveAreaCallback)(struct _FBArea*, struct _FBArea*) - void (*RemoveAreaCallback)(struct _FBArea*) - DevUnion devPrivate; - } FBArea, *FBAreaPtr; - - typedef void (*MoveAreaCallbackProcPtr)(FBAreaPtr from, FBAreaPtr to) - typedef void (*RemoveAreaCallbackProcPtr)(FBAreaPtr) - - FBAreaPtr xf86AllocateOffscreenArea ( - ScreenPtr pScreen, - int width, int height, - int granularity, - MoveAreaCallbackProcPtr MoveAreaCallback, - RemoveAreaCallbackProcPtr RemoveAreaCallback, - pointer privData - ) - - void xf86FreeOffscreenArea (FBAreaPtr area) - - Bool xf86ResizeOffscreenArea ( - FBAreaPtr area - int w, int h - ) -</code> - -The function: -<quote> - &s.code;Bool xf86FBManagerRunning(ScreenPtr pScreen)&e.code; -</quote> - -can be used by an extension to check if the driver has initialized -the memory manager. The manager is not available if this returns -&s.code;FALSE&e.code; and the functions above will all fail. - - -&s.code;xf86AllocateOffscreenArea()&e.code; can be used to request a -rectangle of dimensions &s.code;width&e.code; x &s.code;height&e.code; -(in pixels) from unused offscreen memory. &s.code;granularity&e.code; -specifies that the leftmost edge of the rectangle must lie on some -multiple of &s.code;granularity&e.code; pixels. A granularity of zero -means the same thing as a granularity of one - no alignment preference. -A &s.code;MoveAreaCallback&e.code; can be provided to notify the requester -when the offscreen area is moved. If no &s.code;MoveAreaCallback&e.code; -is supplied then the area is considered to be immovable. The -&s.code;privData&e.code; field will be stored in the manager's internal -structure for that allocated area and will be returned to the requester -in the &s.code;FBArea&e.code; passed via the -&s.code;MoveAreaCallback&e.code;. An optional -&s.code;RemoveAreaCallback&e.code; is provided. If the driver provides -this it indicates that the area should be allocated with a lower priority. -Such an area may be removed when a higher priority request (one that -doesn't have a &s.code;RemoveAreaCallback&e.code;) is made. When this -function is called, the driver will have an opportunity to do whatever -cleanup it needs to do to deal with the loss of the area, but it must -finish its cleanup before the function exits since the offscreen memory -manager will free the area immediately after. - -&s.code;xf86AllocateOffscreenArea()&e.code; returns &s.code;NULL&e.code; -if it was unable to allocate the requested area. When no longer needed, -areas should be freed with &s.code;xf86FreeOffscreenArea()&e.code;. - -&s.code;xf86ResizeOffscreenArea()&e.code; resizes an existing -&s.code;FBArea&e.code;. &s.code;xf86ResizeOffscreenArea()&e.code; -returns &s.code;TRUE&e.code; if the resize was successful. If -&s.code;xf86ResizeOffscreenArea()&e.code; returns &s.code;FALSE&e.code;, -the original &s.code;FBArea&e.code; is left unmodified. Resizing an -area maintains the area's original &s.code;granularity&e.code;, -&s.code;devPrivate&e.code;, and &s.code;MoveAreaCallback&e.code;. -&s.code;xf86ResizeOffscreenArea()&e.code; has considerably less overhead -than freeing the old area then reallocating the new size, so it should -be used whenever possible. - -The function: - <quote> - &s.code;Bool xf86QueryLargestOffscreenArea( - &f.indent;ScreenPtr pScreen, - &f.indent;int *width, int *height, - &f.indent;int granularity, - &f.indent;int preferences, - &f.indent;int priority - &nl)&e.code; - </quote> - -is provided to query the width and height of the largest single -&s.code;FBArea&e.code; allocatable given a particular priority. -&s.code;preferences&e.code; can be one of the following to indicate -whether width, height or area should be considered when determining -which is the largest single &s.code;FBArea&e.code; available. - - <quote> - &s.code;FAVOR_AREA_THEN_WIDTH&nl; - FAVOR_AREA_THEN_HEIGHT&nl; - FAVOR_WIDTH_THEN_AREA&nl; - FAVOR_HEIGHT_THEN_AREA&e.code; - </quote> - -&s.code;priority&e.code; is one of the following: - - <quote><p> - &s.code;PRIORITY_LOW&e.code; - <quote><p> - Return the largest block available without stealing anyone else's - space. This corresponds to the priority of allocating a - &s.code;FBArea&e.code; when a &s.code;RemoveAreaCallback&e.code; - is provided. - - </quote> - &s.code;PRIORITY_NORMAL&e.code; - <quote><p> - Return the largest block available if it is acceptable to steal a - lower priority area from someone. This corresponds to the priority - of allocating a &s.code;FBArea&e.code; without providing a - &s.code;RemoveAreaCallback&e.code;. - - </quote> - &s.code;PRIORITY_EXTREME&e.code; - <quote><p> - Return the largest block available if all &s.code;FBAreas&e.code; - that aren't locked down were expunged from memory first. This - corresponds to any allocation made directly after a call to - &s.code;xf86PurgeUnlockedOffscreenAreas()&e.code;. - - </quote> - </quote> - - -The function: - - <quote> - &s.code;Bool xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen)&e.code; - </quote> - -is provided as an extreme method to free up offscreen memory. This -will remove all removable &s.code;FBArea&e.code; allocations. - - -Initialization of the XFree86 framebuffer manager is done via - - <quote> - &s.code;Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox)&e.code; - </quote> - -&s.code;FullBox&e.code; represents the area of the framebuffer that the -manager is allowed to manage. This is typically a box with a width of -&s.code;pScrn->displayWidth&e.code; and a height of as many lines as -can be fit within the total video memory, however, the driver can reserve -areas at the extremities by passing a smaller area to the manager. - -&s.code;xf86InitFBManager()&e.code; must be called before XAA is -initialized since XAA uses the manager for it's pixmap cache. - -An alternative function is provided to allow the driver to initialize -the framebuffer manager with a Region rather than a box. - - <quote> - &s.code;Bool xf86InitFBManagerRegion(ScreenPtr pScreen, - &f.indent;RegionPtr FullRegion)&e.code; - </quote> - -&s.code;xf86InitFBManagerRegion()&e.code;, unlike -&s.code;xf86InitFBManager()&e.code;, does not remove the area used for -the visible screen so that area should not be included in the region -passed to the function. &s.code;xf86InitFBManagerRegion()&e.code; is -useful when non-contiguous areas are available to be managed, and is -required when multiple framebuffers are stored in video memory (as in -the case where an overlay of a different depth is stored as a second -framebuffer in offscreen memory). - - -<sect>Colormap Handling<label id="cmap"> -<p> - -A generic colormap handling layer is provided within the XFree86 common -layer. This layer takes care of most of the details, and only requires -a function from the driver that loads the hardware palette when required. -To use the colormap layer, a driver calls the -&s.code;xf86HandleColormaps()&e.code; function. - - <quote><p> - &s.code;Bool xf86HandleColormaps(ScreenPtr pScreen, int maxColors, - &f.indent;int sigRGBbits, LoadPaletteFuncPtr loadPalette, - &f.indent;SetOverscanFuncPtr setOverscan, - unsigned int flags)&e.code; - <quote><p> - This function must be called after the default colormap has been - initialised. The &s.code;pScrn->gamma&e.code; field must also - be initialised, preferably by calling &s.code;xf86SetGamma()&e.code;. - &s.code;maxColors&e.code; is the number of entries in the palette. - &s.code;sigRGBbits&e.code; is the size in bits of each color - component in the DAC's palette. &s.code;loadPalette&e.code; - is a driver-provided function for loading a colormap into the - hardware, and is described below. &s.code;setOverscan&e.code; is - an optional function that may be provided when the overscan color - is an index from the standard LUT and when it needs to be adjusted - to keep it as close to black as possible. The - &s.code;setOverscan&e.code; function programs the overscan index. - It shouldn't normally be used for depths other than 8. - &s.code;setOverscan&e.code; should be set to &s.code;NULL&e.code; - when it isn't needed. &s.code;flags&e.code; may be set to the - following (which may be ORed together): - - &s.code;CMAP_PALETTED_TRUECOLOR&e.code; - <quote><p> - the TrueColor visual is paletted and is - just a special case of DirectColor. - This flag is only valid for - &s.code;bpp > 8&e.code;. - - </quote> - - &s.code;CMAP_RELOAD_ON_MODE_SWITCH&e.code; - <quote><p> - reload the colormap automatically - after mode switches. This is useful - for when the driver is resetting the - hardware during mode switches and - corrupting or erasing the hardware - palette. - - </quote> - - &s.code;CMAP_LOAD_EVEN_IF_OFFSCREEN&e.code; - <quote><p> - reload the colormap even if the screen - is switched out of the server's VC. - The palette is <it>not</it> reloaded when - the screen is switched back in, nor after - mode switches. This is useful when the - driver needs to keep track of palette - changes. - - </quote> - - The colormap layer normally reloads the palette after VT enters so it - is not necessary for the driver to save and restore the palette - when switching VTs. The driver must, however, still save the - initial palette during server start up and restore it during - server exit. - - </quote> - - &s.code;void LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, - &f.indent;LOCO *colors, VisualPtr pVisual)&e.code; - <quote><p> - &s.code;LoadPalette()&e.code; is a driver-provided function for - loading a colormap into hardware. &s.code;colors&e.code; is the - array of RGB values that represent the full colormap. - &s.code;indices&e.code; is a list of index values into the colors - array. These indices indicate the entries that need to be updated. - &s.code;numColors&e.code; is the number of the indices to be - updated. - - </quote> - - &s.code;void SetOverscan(ScrnInfoPtr pScrn, int overscan)&e.code; - <quote><p> - &s.code;SetOverscan()&e.code; is a driver-provided function for - programming the &s.code;overscan&e.code; index. As described - above, it is normally only appropriate for LUT modes where all - colormap entries are available for the display, but where one of - them is also used for the overscan (typically 8bpp for VGA compatible - LUTs). It isn't required in cases where the overscan area is - never visible. - - </quote> - </quote> - - -<sect>DPMS Extension -<p> - -Support code for the DPMS extension is included in the XFree86 common layer. -This code provides an interface between the main extension code, and a means -for drivers to initialise DPMS when they support it. One function is -available to drivers to do this initialisation, and it is always available, -even when the DPMS extension is not supported by the core server (in -which case it returns a failure result). - - - <quote><p> - &s.code;Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)&e.code; - <quote><p> - This function registers a driver's DPMS level programming function - &s.code;set&e.code;. It also checks - &s.code;pScrn->options&e.code; for the "dpms" option, and when - present marks DPMS as being enabled for that screen. The - &s.code;set&e.code; function is called whenever the DPMS level - changes, and is used to program the requested level. - &s.code;flags&e.code; is currently not used, and should be - &s.code;0&e.code;. If the initialisation fails for any reason, - including when there is no DPMS support in the core server, the - function returns &s.code;FALSE&e.code;. - - </quote> - </quote> - - -Drivers that implement DPMS support must provide the following function, -that gets called when the DPMS level is changed: - - - <quote><p> - &s.code;void ChipDPMSSet(ScrnInfoPtr pScrn, int level, int flags)&e.code; - <quote><p> - Program the DPMS level specified by &s.code;level&e.code;. Valid - values of &s.code;level&e.code; are &s.code;DPMSModeOn&e.code;, - &s.code;DPMSModeStandby&e.code;, &s.code;DPMSModeSuspend&e.code;, - &s.code;DPMSModeOff&e.code;. These values are defined in - &s.code;"extensions/dpms.h"&e.code;. - - </quote> - </quote> - - -<sect>DGA Extension -<p> - -Drivers can support the XFree86 Direct Graphics Architecture (DGA) by -filling out a structure of function pointers and a list of modes and -passing them to DGAInit. - - <quote><p> - &s.code;Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs, - &f.indent;DGAModePtr modes, int num)&e.code; - <quote><p> - <verb> -/** The DGAModeRec **/ - -typedef struct { - int num; - DisplayModePtr mode; - int flags; - int imageWidth; - int imageHeight; - int pixmapWidth; - int pixmapHeight; - int bytesPerScanline; - int byteOrder; - int depth; - int bitsPerPixel; - unsigned long red_mask; - unsigned long green_mask; - unsigned long blue_mask; - int viewportWidth; - int viewportHeight; - int xViewportStep; - int yViewportStep; - int maxViewportX; - int maxViewportY; - int viewportFlags; - int offset; - unsigned char *address; - int reserved1; - int reserved2; -} DGAModeRec, *DGAModePtr; -</verb> - - &s.code;num&e.code; - <quote> - Can be ignored. The DGA DDX will assign these numbers. - </quote> - - &s.code;mode&e.code; - <quote> - A pointer to the &s.code;DisplayModeRec&e.code; for this mode. - </quote> - - &s.code;flags&e.code; - <quote><p> - The following flags are defined and may be OR'd together: - - &s.code;DGA_CONCURRENT_ACCESS&e.code; - <quote><p> - Indicates that the driver supports concurrent graphics - accelerator and linear framebuffer access. - - </quote> - - &s.code;DGA_FILL_RECT&nl; - DGA_BLIT_RECT&nl; - DGA_BLIT_RECT_TRANS&e.code; - <quote><p> - Indicates that the driver supports the FillRect, BlitRect - or BlitTransRect functions in this mode. - - </quote> - - &s.code;DGA_PIXMAP_AVAILABLE&e.code; - <quote><p> - Indicates that Xlib may be used on the framebuffer. - This flag will usually be set unless the driver wishes - to prohibit this for some reason. - - </quote> - - &s.code;DGA_INTERLACED&nl; - DGA_DOUBLESCAN&e.code; - <quote><p> - Indicates that these are interlaced or double scan modes. - - </quote> - </quote> - - &s.code;imageWidth&nl; - imageHeight&e.code; - <quote><p> - These are the dimensions of the linear framebuffer - accessible by the client. - - </quote> - - &s.code;pixmapWidth&nl; - pixmapHeight&e.code; - <quote><p> - These are the dimensions of the area of the - framebuffer accessible by the graphics accelerator. - - </quote> - - &s.code;bytesPerScanline&e.code; - <quote><p> - Pitch of the framebuffer in bytes. - - </quote> - - &s.code;byteOrder&e.code; - <quote><p> - Usually the same as - &s.code;pScrn->imageByteOrder&e.code;. - - </quote> - - &s.code;depth&e.code; - <quote><p> - The depth of the framebuffer in this mode. - - </quote> - - &s.code;bitsPerPixel&e.code; - <quote><p> - The number of bits per pixel in this mode. - - </quote> - - &s.code;red_mask&nl; - green_mask&nl; - blue_mask&e.code; - <quote><p> - The RGB masks for this mode, if applicable. - - </quote> - - &s.code;viewportWidth&nl; - viewportHeight&e.code; - <quote><p> - Dimensions of the visible part of the framebuffer. - Usually &s.code;mode->HDisplay&e.code; and - &s.code;mode->VDisplay&e.code;. - - </quote> - - &s.code;xViewportStep&nl; - yViewportStep&e.code; - <quote><p> - The granularity of x and y viewport positions that - the driver supports in this mode. - - </quote> - - &s.code;maxViewportX&nl; - maxViewportY&e.code; - <quote><p> - The maximum viewport position supported by the - driver in this mode. - - </quote> - - &s.code;viewportFlags&e.code; - <quote><p> - The following may be OR'd together: - - &s.code;DGA_FLIP_IMMEDIATE&e.code; - <quote><p> - The driver supports immediate viewport changes. - - </quote> - &s.code;DGA_FLIP_RETRACE&e.code; - <quote<p> - The driver supports viewport changes at retrace. - - </quote> - </quote> - - &s.code;offset&e.code; - <quote><p> - The offset into the linear framebuffer that corresponds to - pixel (0,0) for this mode. - - </quote> - - &s.code;address&e.code; - <quote><p> - The virtual address of the framebuffer as mapped by the driver. - This is needed when DGA_PIXMAP_AVAILABLE is set. - - </quote> - - <verb> -/** The DGAFunctionRec **/ - -typedef struct { - Bool (*OpenFramebuffer)( - ScrnInfoPtr pScrn, - char **name, - unsigned char **mem, - int *size, - int *offset, - int *extra - ); - void (*CloseFramebuffer)(ScrnInfoPtr pScrn); - Bool (*SetMode)(ScrnInfoPtr pScrn, DGAModePtr pMode); - void (*SetViewport)(ScrnInfoPtr pScrn, int x, int y, int flags); - int (*GetViewport)(ScrnInfoPtr pScrn); - void (*Sync)(ScrnInfoPtr); - void (*FillRect)( - ScrnInfoPtr pScrn, - int x, int y, int w, int h, - unsigned long color - ); - void (*BlitRect)( - ScrnInfoPtr pScrn, - int srcx, int srcy, - int w, int h, - int dstx, int dsty - ); - void (*BlitTransRect)( - ScrnInfoPtr pScrn, - int srcx, int srcy, - int w, int h, - int dstx, int dsty, - unsigned long color - ); -} DGAFunctionRec, *DGAFunctionPtr; -</verb> - - </quote> - - &s.code;Bool OpenFramebuffer (pScrn, name, mem, size, offset, extra)&e.code; - <quote><p> - &s.code;OpenFramebuffer()&e.code; should pass the client everything - it needs to know to be able to open the framebuffer. These - parameters are OS specific and their meanings are to be interpreted - by an OS specific client library. - - &s.code;name&e.code; - <quote><p> - The name of the device to open or &s.code;NULL&e.code; if - there is no special device to open. A &s.code;NULL&e.code; - name tells the client that it should open whatever device - one would usually open to access physical memory. - - </quote> - &s.code;mem&e.code; - <quote><p> - The physical address of the start of the framebuffer. - - </quote> - &s.code;size&e.code; - <quote><p> - The size of the framebuffer in bytes. - - </quote> - &s.code;offset&e.code; - <quote><p> - Any offset into the device, if applicable. - - </quote> - &s.code;flags&e.code; - <quote><p> - Any additional information that the client may need. - Currently, only the &s.code;DGA_NEED_ROOT&e.code; flag is - defined. - - </quote> - </quote> - - &s.code;void CloseFramebuffer (pScrn)&e.code; - <quote><p> - &s.code;CloseFramebuffer()&e.code; merely informs the driver (if it - even cares) that client no longer needs to access the framebuffer - directly. This function is optional. - - </quote> - - &s.code;Bool SetMode (pScrn, pMode)&e.code; - <quote><p> - &s.code;SetMode()&e.code; tells the driver to initialize the mode - passed to it. If &s.code;pMode&e.code; is &s.code;NULL&e.code;, - then the driver should restore the original pre-DGA mode. - - </quote> - - &s.code;void SetViewport (pScrn, x, y, flags)&e.code; - <quote><p> - &s.code;SetViewport()&e.code; tells the driver to make the upper - left-hand corner of the visible screen correspond to coordinate - &s.code;(x,y)&e.code; on the framebuffer. &s.code;Flags&e.code; - currently defined are: - - &s.code;DGA_FLIP_IMMEDIATE&e.code; - <quote><p> - The viewport change should occur immediately. - - </quote> - &s.code;DGA_FLIP_RETRACE&e.code; - <quote><p> - The viewport change should occur at the - vertical retrace, but this function should - return sooner if possible. - - </quote> - The &s.code;(x,y)&e.code; locations will be passed as the client - specified them, however, the driver is expected to round these - locations down to the next supported location as specified by the - &s.code;xViewportStep&e.code; and &s.code;yViewportStep&e.code; - for the current mode. - - </quote> - - &s.code;int GetViewport (pScrn)&e.code; - <quote><p> - &s.code;GetViewport()&e.code; gets the current page flip status. - Set bits in the returned int correspond to viewport change requests - still pending. For instance, set bit zero if the last SetViewport - request is still pending, bit one if the one before that is still - pending, etc. - - </quote> - - &s.code;void Sync (pScrn)&e.code; - <quote><p> - This function should ensure that any graphics accelerator operations - have finished. This function should not return until the graphics - accelerator is idle. - - </quote> - - &s.code;void FillRect (pScrn, x, y, w, h, color)&e.code; - <quote><p> - This optional function should fill a rectangle - &s.code;w × h&e.code; located at - &s.code;(x,y)&e.code; in the given color. - - </quote> - - &s.code;void BlitRect (pScrn, srcx, srcy, w, h, dstx, dsty)&e.code; - <quote><p> - This optional function should copy an area - &s.code;w × h&e.code; located at - &s.code;(srcx,srcy)&e.code; to location &s.code;(dstx,dsty)&e.code;. - This function will need to handle copy directions as appropriate. - - </quote> - - &s.code;void BlitTransRect (pScrn, srcx, srcy, w, h, dstx, dsty, color)&e.code; - <quote><p> - This optional function is the same as BlitRect except that pixels - in the source corresponding to the color key &s.code;color&e.code; - should be skipped. - - </quote> - </quote> - -<sect>The XFree86 X Video Extension (Xv) Device Dependent Layer -<p> - -XFree86 offers the X Video Extension which allows clients to treat video -as any another primitive and ``Put'' video into drawables. By default, -the extension reports no video adaptors as being available since the -DDX layer has not been initialized. The driver can initialize the DDX -layer by filling out one or more &s.code;XF86VideoAdaptorRecs&e.code; -as described later in this document and passing a list of -&s.code;XF86VideoAdaptorPtr&e.code; pointers to the following function: - - <quote> - &s.code;Bool xf86XVScreenInit( - &f.indent;ScreenPtr pScreen, - &f.indent;XF86VideoAdaptorPtr *adaptPtrs, - &f.indent;int num)&e.code; - </quote> - -After doing this, the extension will report video adaptors as being -available, providing the data in their respective -&s.code;XF86VideoAdaptorRecs&e.code; was valid. -&s.code;xf86XVScreenInit()&e.code; <em>copies</em> data from the structure -passed to it so the driver may free it after the initialization. At -the moment, the DDX only supports rendering into Window drawables. -Pixmap rendering will be supported after a sufficient survey of suitable -hardware is completed. - -The &s.code;XF86VideoAdaptorRec&e.code;: - -<quote><p> -<verb> -typedef struct { - unsigned int type; - int flags; - char *name; - int nEncodings; - XF86VideoEncodingPtr pEncodings; - int nFormats; - XF86VideoFormatPtr pFormats; - int nPorts; - DevUnion *pPortPrivates; - int nAttributes; - XF86AttributePtr pAttributes; - int nImages; - XF86ImagePtr pImages; - PutVideoFuncPtr PutVideo; - PutStillFuncPtr PutStill; - GetVideoFuncPtr GetVideo; - GetStillFuncPtr GetStill; - StopVideoFuncPtr StopVideo; - SetPortAttributeFuncPtr SetPortAttribute; - GetPortAttributeFuncPtr GetPortAttribute; - QueryBestSizeFuncPtr QueryBestSize; - PutImageFuncPtr PutImage; - QueryImageAttributesFuncPtr QueryImageAttributes; -} XF86VideoAdaptorRec, *XF86VideoAdaptorPtr; -</verb> - - Each adaptor will have its own XF86VideoAdaptorRec. The fields are - as follows: - - &s.code;type&e.code; - <quote><p> - This can be any of the following flags OR'd together. - - &s.code;XvInputMask&e.code; - &s.code;XvOutputMask&e.code; - <quote><p> - These refer to the target drawable and are similar to a Window's - class. &s.code;XvInputMask&e.code; indicates that the adaptor - can put video into a drawable. &s.code;XvOutputMask&e.code; - indicates that the adaptor can get video from a drawable. - </quote> - - &s.code;XvVideoMask&e.code; - &s.code;XvStillMask&e.code; - &s.code;XvImageMask&e.code; - <quote><p> - These indicate that the adaptor supports video, still or - image primitives respectively. - </quote> - - &s.code;XvWindowMask&e.code; - &s.code;XvPixmapMask&e.code; - <quote><p> - These indicate the types of drawables the adaptor is capable - of rendering into. At the moment, Pixmap rendering is not - supported and the &s.code;XvPixmapMask&e.code; flag is ignored. - </quote> - - </quote> - - &s.code;flags&e.code; - <quote><p> - Currently, the following flags are defined: - - &s.code;VIDEO_NO_CLIPPING&e.code; - <quote><p> - This indicates that the video adaptor does not support - clipping. The driver will never receive ``Put'' requests - where less than the entire area determined by - &s.code;drw_x&e.code;, &s.code;drw_y&e.code;, - &s.code;drw_w&e.code; and &s.code;drw_h&e.code; is visible. - This flag does not apply to ``Get'' requests. Hardware - that is incapable of clipping ``Gets'' may punt or get - the extents of the clipping region passed to it. - - </quote> - - &s.code;VIDEO_INVERT_CLIPLIST&e.code; - <quote><p> - This indicates that the video driver requires the clip - list to contain the regions which are obscured rather - than the regions which are are visible. - - </quote> - - &s.code;VIDEO_OVERLAID_STILLS&e.code; - <quote><p> - Implementing PutStill for hardware that does video as an - overlay can be awkward since it's unclear how long to leave - the video up for. When this flag is set, StopVideo will be - called whenever the destination gets clipped or moved so that - the still can be left up until then. - - </quote> - - &s.code;VIDEO_OVERLAID_IMAGES&e.code; - <quote><p> - Same as &s.code;VIDEO_OVERLAID_STILLS&e.code; but for images. - </quote> - - &s.code;VIDEO_CLIP_TO_VIEWPORT&e.code; - <quote><p> - Indicates that the clip region passed to the driver functions - should be clipped to the visible portion of the screen in the - case where the viewport is smaller than the virtual desktop. - </quote> - - </quote> - - &s.code;name&e.code; - <quote><p> - The name of the adaptor. - - </quote> - - &s.code;nEncodings&nl; - pEncodings&e.code; - <quote><p> - The number of encodings the adaptor is capable of and pointer - to the &s.code;XF86VideoEncodingRec&e.code; array. The - &s.code;XF86VideoEncodingRec&e.code; is described later on. - For drivers that only support XvImages there should be an encoding - named "XV_IMAGE" and the width and height should specify - the maximum size source image supported. - - </quote> - - &s.code;nFormats&nl; - pFormats&e.code; - <quote><p> - The number of formats the adaptor is capable of and pointer to - the &s.code;XF86VideoFormatRec&e.code; array. The - &s.code;XF86VideoFormatRec&e.code; is described later on. - - </quote> - - &s.code;nPorts&nl; - pPortPrivates&e.code; - <quote><p> - The number of ports is the number of separate data streams which - the adaptor can handle simultaneously. If you have more than - one port, the adaptor is expected to be able to render into more - than one window at a time. &s.code;pPortPrivates&e.code; is - an array of pointers or ints - one for each port. A port's - private data will be passed to the driver any time the port is - requested to do something like put the video or stop the video. - In the case where there may be many ports, this enables the - driver to know which port the request is intended for. Most - commonly, this will contain a pointer to the data structure - containing information about the port. In Xv, all ports on - a particular adaptor are expected to be identical in their - functionality. - - </quote> - - &s.code;nAttributes&nl; - pAttributes&e.code; - <quote><p> - The number of attributes recognized by the adaptor and a pointer to - the array of &s.code;XF86AttributeRecs&e.code;. The - &s.code;XF86AttributeRec&e.code; is described later on. - - </quote> - - &s.code;nImages&nl; - pImages&e.code; - <quote><p> - The number of &s.code;XF86ImageRecs&e.code; supported by the adaptor - and a pointer to the array of &s.code;XF86ImageRecs&e.code;. The - &s.code;XF86ImageRec&e.code; is described later on. - - </quote> - - - &s.code;PutVideo PutStill GetVideo GetStill StopVideo - SetPortAttribute GetPortAttribute QueryBestSize PutImage - QueryImageAttributes&e.code; - <quote><p> - These functions define the DDX->driver interface. In each - case, the pointer &s.code;data&e.code; is passed to the driver. - This is the port private for that port as described above. All - fields are required except under the following conditions: - - <enum> - <item>&s.code;PutVideo&e.code;, &s.code;PutStill&e.code; and - the image routines &s.code;PutImage&e.code; and - &s.code;QueryImageAttributes&e.code; are not required when the - adaptor type does not contain &s.code;XvInputMask&e.code;. - - <item>&s.code;GetVideo&e.code; and &s.code;GetStill&e.code; - are not required when the adaptor type does not contain - &s.code;XvOutputMask&e.code;. - - <item>&s.code;GetVideo&e.code; and &s.code;PutVideo&e.code; - are not required when the adaptor type does not contain - &s.code;XvVideoMask&e.code;. - - <item>&s.code;GetStill&e.code; and &s.code;PutStill&e.code; - are not required when the adaptor type does not contain - &s.code;XvStillMask&e.code;. - - <item>&s.code;PutImage&e.code; and &s.code;QueryImageAttributes&e.code; - are not required when the adaptor type does not contain - &s.code;XvImageMask&e.code;. - - </enum> - - With the exception of &s.code;QueryImageAttributes&e.code;, these - functions should return &s.code;Success&e.code; if the operation was - completed successfully. They can return &s.code;XvBadAlloc&e.code; - otherwise. &s.code;QueryImageAttributes&e.code; returns the size - of the XvImage queried. - - If the &s.code;VIDEO_NO_CLIPPING&e.code; - flag is set, the &s.code;clipBoxes&e.code; may be ignored by - the driver. &s.code;ClipBoxes&e.code; is an &s.code;X-Y&e.code; - banded region identical to those used throughout the server. - The clipBoxes represent the visible portions of the area determined - by &s.code;drw_x&e.code;, &s.code;drw_y&e.code;, - &s.code;drw_w&e.code; and &s.code;drw_h&e.code; in the Get/Put - function. The boxes are in screen coordinates, are guaranteed - not to overlap and an empty region will never be passed. - If the driver has specified &s.code;VIDEO_INVERT_CLIPLIST&e.code;, - &s.code;clipBoxes&e.code; will indicate the areas of the primitive - which are obscured rather than the areas visible. - - </quote> - - &s.code;typedef int (* PutVideoFuncPtr)( ScrnInfoPtr pScrn, - &f.indent;short vid_x, short vid_y, short drw_x, short drw_y, - &f.indent;short vid_w, short vid_h, short drw_w, short drw_h, - &f.indent;RegionPtr clipBoxes, pointer data )&e.code; - <quote><p> - This indicates that the driver should take a subsection - &s.code;vid_w&e.code; by &s.code;vid_h&e.code; at location - &s.code;(vid_x,vid_y)&e.code; from the video stream and direct - it into the rectangle &s.code;drw_w&e.code; by &s.code;drw_h&e.code; - at location &s.code;(drw_x,drw_y)&e.code; on the screen, scaling as - necessary. Due to the large variations in capabilities of - the various hardware expected to be used with this extension, - it is not expected that all hardware will be able to do this - exactly as described. In that case the driver should just do - ``the best it can,'' scaling as closely to the target rectangle - as it can without rendering outside of it. In the worst case, - the driver can opt to just not turn on the video. - - </quote> - - &s.code;typedef int (* PutStillFuncPtr)( ScrnInfoPtr pScrn, - &f.indent;short vid_x, short vid_y, short drw_x, short drw_y, - &f.indent;short vid_w, short vid_h, short drw_w, short drw_h, - &f.indent;RegionPtr clipBoxes, pointer data )&e.code; - <quote><p> - This is same as &s.code;PutVideo&e.code; except that the driver - should place only one frame from the stream on the screen. - - </quote> - - &s.code;typedef int (* GetVideoFuncPtr)( ScrnInfoPtr pScrn, - &f.indent;short vid_x, short vid_y, short drw_x, short drw_y, - &f.indent;short vid_w, short vid_h, short drw_w, short drw_h, - &f.indent;RegionPtr clipBoxes, pointer data )&e.code; - <quote><p> - This is same as &s.code;PutVideo&e.code; except that the driver - gets video from the screen and outputs it. The driver should - do the best it can to get the requested dimensions correct - without reading from an area larger than requested. - - </quote> - - &s.code;typedef int (* GetStillFuncPtr)( ScrnInfoPtr pScrn, - &f.indent;short vid_x, short vid_y, short drw_x, short drw_y, - &f.indent;short vid_w, short vid_h, short drw_w, short drw_h, - &f.indent;RegionPtr clipBoxes, pointer data )&e.code; - <quote><p> - This is the same as &s.code;GetVideo&e.code; except that the - driver should place only one frame from the screen into the - output stream. - - </quote> - - &s.code;typedef void (* StopVideoFuncPtr)(ScrnInfoPtr pScrn, - &f.indent;pointer data, Bool cleanup)&e.code; - <quote><p> - This indicates the driver should stop displaying the video. - This is used to stop both input and output video. The - &s.code;cleanup&e.code; field indicates that the video is - being stopped because the client requested it to stop or - because the server is exiting the current VT. In that case - the driver should deallocate any offscreen memory areas (if - there are any) being used to put the video to the screen. If - &s.code;cleanup&e.code; is not set, the video is being stopped - temporarily due to clipping or moving of the window, etc... - and video will likely be restarted soon so the driver should - not deallocate any offscreen areas associated with that port. - - </quote> - &s.code;typedef int (* SetPortAttributeFuncPtr)(ScrnInfoPtr pScrn, - &f.indent;Atom attribute,INT32 value, pointer data)&e.code; - - &s.code;typedef int (* GetPortAttributeFuncPtr)(ScrnInfoPtr pScrn, - &f.indent;Atom attribute,INT32 *value, pointer data)&e.code; - - <quote><p> - A port may have particular attributes such as hue, - saturation, brightness or contrast. Xv clients set and - get these attribute values by sending attribute strings - (Atoms) to the server. Such requests end up at these - driver functions. It is recommended that the driver provide - at least the following attributes mentioned in the Xv client - library docs: - <quote> - &s.code;XV_ENCODING&nl; - XV_HUE&nl; - XV_SATURATION&nl; - XV_BRIGHTNESS&nl; - XV_CONTRAST&e.code; - </quote> - but the driver may recognize as many atoms as it wishes. If - a requested attribute is unknown by the driver it should return - &s.code;BadMatch&e.code;. &s.code;XV_ENCODING&e.code; is the - attribute intended to let the client specify which video - encoding the particular port should be using (see the description - of &s.code;XF86VideoEncodingRec&e.code; below). If the - requested encoding is unsupported, the driver should return - &s.code;XvBadEncoding&e.code;. If the value lies outside the - advertised range &s.code;BadValue&e.code; may be returned. - &s.code;Success&e.code; should be returned otherwise. - - </quote> - - &s.code;typedef void (* QueryBestSizeFuncPtr)(ScrnInfoPtr pScrn, - &f.indent;Bool motion, short vid_w, short vid_h, - &f.indent;short drw_w, short drw_h, - &f.indent;unsigned int *p_w, unsigned int *p_h, pointer data)&e.code; - <quote><p> - &s.code;QueryBestSize&e.code; provides the client with a way - to query what the destination dimensions would end up being - if they were to request that an area - &s.code;vid_w&e.code by &s.code;vid_h&e.code; from the video - stream be scaled to rectangle of - &s.code;drw_w&e.code; by &s.code;drw_h&e.code; on the screen. - Since it is not expected that all hardware will be able to - get the target dimensions exactly, it is important that the - driver provide this function. - - </quote> - - &s.code;typedef int (* PutImageFuncPtr)( ScrnInfoPtr pScrn, - &f.indent;short src_x, short src_y, short drw_x, short drw_y, - &f.indent;short src_w, short src_h, short drw_w, short drw_h, - &f.indent;int image, char *buf, short width, short height, - &f.indent;Bool sync, RegionPtr clipBoxes, pointer data )&e.code; - <quote><p> - This is similar to &s.code;PutStill&e.code; except that the - source of the video is not a port but the data stored in a system - memory buffer at &s.code;buf&e.code;. The data is in the format - indicated by the &s.code;image&e.code; descriptor and represents a - source of size &s.code;width&e.code; by &s.code;height&e.code;. - If &s.code;sync&e.code; is TRUE the driver should not return - from this function until it is through reading the data - from &s.code;buf&e.code;. Returning when &s.code;sync&e.code; - is TRUE indicates that it is safe for the data at &s.code;buf&e.code; - to be replaced, freed, or modified. - - </quote> - - &s.code;typedef int (* QueryImageAttributesFuncPtr)( ScrnInfoPtr pScrn, - &f.indent;int image, short *width, short *height, - &f.indent;int *pitches, int *offsets)&e.code; - <quote><p> - This function is called to let the driver specify how data for - a particular &s.code;image&e.code; of size &s.code;width&e.code; - by &s.code;height&e.code; should be stored. Sometimes only - the size and corrected width and height are needed. In that - case &s.code;pitches&e.code; and &s.code;offsets&e.code; are - NULL. The size of the memory required for the image is returned - by this function. The &s.code;width&e.code; and - &s.code;height&e.code; of the requested image can be altered by - the driver to reflect format limitations (such as component - sampling periods that are larger than one). If - &s.code;pitches&e.code; and &s.code;offsets&e.code; are not NULL, - these will be arrays with as many elements in them as there - are planes in the &s.code;image&e.code; format. The driver - should specify the pitch (in bytes) of each scanline in the - particular plane as well as the offset to that plane (in bytes) - from the beginning of the image. - - </quote> - - </quote> - -The XF86VideoEncodingRec: -<quote><p> -<verb> -typedef struct { - int id; - char *name; - unsigned short width, height; - XvRationalRec rate; -} XF86VideoEncodingRec, *XF86VideoEncodingPtr; - -</verb> - The &s.code;XF86VideoEncodingRec&e.code; specifies what encodings - the adaptor can support. Most of this data is just informational - and for the client's benefit, and is what will be reported by - &s.code;XvQueryEncodings&e.code;. The &s.code;id&e.code; field is - expected to be a unique identifier to allow the client to request a - certain encoding via the &s.code;XV_ENCODING&e.code; attribute string. - -</quote> - -The XF86VideoFormatRec: - -<quote><p> -<verb> -typedef struct { - char depth; - short class; -} XF86VideoFormatRec, *XF86VideoFormatPtr; -</verb> - - This specifies what visuals the video is viewable in. - &s.code;depth&e.code; is the depth of the visual (not bpp). - &s.code;class&e.code; is the visual class such as - &s.code;TrueColor&e.code;, &s.code;DirectColor&e.code; or - &s.code;PseudoColor&e.code;. Initialization of an adaptor will fail - if none of the visuals on that screen are supported. - -</quote> - -The XF86AttributeRec: - -<quote><p> -<verb> -typedef struct { - int flags; - int min_value; - int max_value; - char *name; -} XF86AttributeListRec, *XF86AttributeListPtr; - -</verb> - - Each adaptor may have an array of these advertising the attributes - for its ports. Currently defined flags are &s.code;XvGettable&e.code; - and &s.code;XvSettable&e.code; which may be OR'd together indicating that - attribute is ``gettable'' or ``settable'' by the client. The - &s.code;min&e.code; and &s.code;max&e.code; field specify the valid range - for the value. &s.code;Name&e.code; is a text string describing the - attribute by name. - -</quote> - -The XF86ImageRec: - -<quote><p> -<verb> -typedef struct { - int id; - int type; - int byte_order; - char guid[16]; - int bits_per_pixel; - int format; - int num_planes; - - /* for RGB formats */ - int depth; - unsigned int red_mask; - unsigned int green_mask; - unsigned int blue_mask; - - /* for YUV formats */ - unsigned int y_sample_bits; - unsigned int u_sample_bits; - unsigned int v_sample_bits; - unsigned int horz_y_period; - unsigned int horz_u_period; - unsigned int horz_v_period; - unsigned int vert_y_period; - unsigned int vert_u_period; - unsigned int vert_v_period; - char component_order[32]; - int scanline_order; -} XF86ImageRec, *XF86ImagePtr; -</verb> - - XF86ImageRec describes how video source data is laid out in memory. - The fields are as follows: - - &s.code;id&e.code; - <quote><p> - This is a unique descriptor for the format. It is often good to - set this value to the FOURCC for the format when applicable. - </quote> - - &s.code;type&e.code; - <quote><p> - This is &s.code;XvRGB&e.code; or &s.code;XvYUV&e.code;. - </quote> - - &s.code;byte_order&e.code; - <quote><p> - This is &s.code;LSBFirst&e.code; or &s.code;MSBFirst&e.code;. - </quote> - - &s.code;guid&e.code; - <quote><p> - This is the Globally Unique IDentifier for the format. When - not applicable, all characters should be NULL. - </quote> - - &s.code;bits_per_pixel&e.code; - <quote><p> - The number of bits taken up (but not necessarily used) by each - pixel. Note that for some planar formats which have fractional - bits per pixel (such as IF09) this number may be rounded _down_. - </quote> - - &s.code;format&e.code; - <quote><p> - This is &s.code;XvPlanar&e.code; or &s.code;XvPacked&e.code;. - </quote> - - &s.code;num_planes&e.code; - <quote><p> - The number of planes in planar formats. This should be set to - one for packed formats. - </quote> - - &s.code;depth&e.code; - <quote><p> - The significant bits per pixel in RGB formats (analgous to the - depth of a pixmap format). - </quote> - - &s.code;red_mask&e.code; - &s.code;green_mask&e.code; - &s.code;blue_mask&e.code; - <quote><p> - The red, green and blue bitmasks for packed RGB formats. - </quote> - - &s.code;y_sample_bits&e.code; - &s.code;u_sample_bits&e.code; - &s.code;v_sample_bits&e.code; - <quote><p> - The y, u and v sample sizes (in bits). - </quote> - - &s.code;horz_y_period&e.code; - &s.code;horz_u_period&e.code; - &s.code;horz_v_period&e.code; - <quote><p> - The y, u and v sampling periods in the horizontal direction. - </quote> - - &s.code;vert_y_period&e.code; - &s.code;vert_u_period&e.code; - &s.code;vert_v_period&e.code; - <quote><p> - The y, u and v sampling periods in the vertical direction. - </quote> - - &s.code;component_order&e.code; - <quote><p> - Uppercase ascii characters representing the order that - samples are stored within packed formats. For planar formats - this represents the ordering of the planes. Unused characters - in the 32 byte string should be set to NULL. - </quote> - - &s.code;scanline_order&e.code; - <quote><p> - This is &s.code;XvTopToBottom&e.code; or &s.code;XvBottomToTop&e.code;. - </quote> - - Since some formats (particular some planar YUV formats) may not -be completely defined by the parameters above, the guid, when -available, should provide the most accurate description of the -format. - -</quote> - -<sect>The Loader -<p> - -This section describes the interfaces to the module loader. The loader -interfaces can be divided into two groups: those that are only available to -the XFree86 common layer, and those that are also available to modules. - -<sect1>Loader Overview -<p> - -The loader is capable of loading modules in a range of object formats, -and knowledge of these formats is built in to the loader. Knowledge of -new object formats can be added to the loader in a straightforward -manner. This makes it possible to provide OS-independent modules (for -a given CPU architecture type). In addition to this, the loader can -load modules via the OS-provided &s.code;dlopen(3)&e.code; service where -available. Such modules are not platform independent, and the semantics -of &s.code;dlopen()&e.code; on most systems results in significant -limitations in the use of modules of this type. Support for -&s.code;dlopen()&e.code; modules in the loader is primarily for -experimental and development purposes. - -Symbols exported by the loader (on behalf of the core X server) to -modules are determined at compile time. Only those symbols explicitly -exported are available to modules. All external symbols of loaded -modules are exported to other modules, and to the core X server. The -loader can be requested to check for unresolved symbols at any time, -and the action to be taken for unresolved symbols can be controlled by -the caller of the loader. Typically the caller identifies which symbols -can safely remain unresolved and which cannot. - -NOTE: Now that ISO-C allows pointers to functions and pointers to data to -have different internal representations, some of the following interfaces -will need to be revisited. - -<sect1>Semi-private Loader Interface -<p> - -The following is the semi-private loader interface that is available to the -XFree86 common layer. - - <quote><p> - &s.code;void LoaderInit(void)&e.code; - <quote><p> - The &s.code;LoaderInit()&e.code; function initialises the loader, - and it must be called once before calling any other loader functions. - This function initialises the tables of exported symbols, and anything - else that might need to be initialised. - - </quote> - - &s.code;void LoaderSetPath(const char *path)&e.code; - <quote><p> - The &s.code;LoaderSetPath()&e.code; function initialises a default - module search path. This must be called if calls to other functions - are to be made without explicitly specifying a module search path. - The search path &s.code;path&e.code; must be a string of one or more - comma separated absolute paths. Modules are expected to be located - below these paths, possibly in subdirectories of these paths. - - </quote> - - &s.code;pointer LoadModule(const char *module, const char *path, - &f.indent;const char **subdirlist, const char **patternlist, - &f.indent;pointer options, const XF86ModReqInfo * modreq, - &f.indent;int *errmaj, int *errmin)&e.code; - <quote><p> - The &s.code;LoadModule()&e.code; function loads the module called - &s.code;module&e.code;. The return value is a module handle, and - may be used in future calls to the loader that require a reference - to a loaded module. The module name &s.code;module&e.code; is - normally the module's canonical name, which doesn't contain any - directory path information, or any object/library file prefixes of - suffixes. Currently a full pathname and/or filename is also accepted. - This might change. The other parameters are: - - &s.code;path&e.code; - <quote><p> - An optional comma-separated list of module search paths. - When &s.code;NULL&e.code;, the default search path is used. - - </quote> - - &s.code;subdirlist&e.code; - <quote><p> - An optional &s.code;NULL&e.code; terminated list of - subdirectories to search. When &s.code;NULL&e.code;, - the default built-in list is used (refer to - &s.code;stdSubdirs&e.code; in &s.code;loadmod.c&e.code;). - The default list is also substituted for entries in - &s.code;subdirlist&e.code; with the value - &s.code;DEFAULT_LIST&e.code;. This makes is possible - to augment the default list instead of replacing it. - Subdir elements must be relative, and must not contain - &s.code;".."&e.code;. If any violate this requirement, - the load fails. - - </quote> - - &s.code;patternlist&e.code; - <quote><p> - An optional &s.code;NULL&e.code; terminated list of - POSIX regular expressions used to connect module - filenames with canonical module names. Each regex - should contain exactly one subexpression that corresponds - to the canonical module name. When &s.code;NULL&e.code;, - the default built-in list is used (refer to - &s.code;stdPatterns&e.code; in - &s.code;loadmod.c&e.code;). The default list is also - substituted for entries in &s.code;patternlist&e.code; - with the value &s.code;DEFAULT_LIST&e.code;. This - makes it possible to augment the default list instead - of replacing it. - - </quote> - - &s.code;options&e.code; - <quote><p> - An optional parameter that is passed to the newly - loaded module's &s.code;SetupProc&e.code; function - (if it has one). This argument is normally a - &s.code;NULL&e.code; terminated list of - &s.code;Options&e.code;, and must be interpreted that - way by modules loaded directly by the XFree86 common - layer. However, it may be used for application-specific - parameter passing in other situations. - - When loading ``external'' modules (modules that don't - have the standard entry point, for example a - special shared library) the options parameter can be - set to &s.code;EXTERN_MODULE&e.code; to tell the - loader not to reject the module when it doesn't find - the standard entry point. - - </quote> - - &s.code;modreq&e.code; - <quote><p> - An optional &s.code;XF86ModReqInfo*&e.code; containing - version/ABI/vendor information to requirements to - check the newly loaded module against. The main - purpose of this is to allow the loader to verify that - a module of the correct type/version before running - its &s.code;SetupProc&e.code; function. - - The &s.code;XF86ModReqInfo&e.code; struct is defined - as follows: -<verb> -typedef struct { - CARD8 majorversion; /* MAJOR_UNSPEC */ - CARD8 minorversion; /* MINOR_UNSPEC */ - CARD16 patchlevel; /* PATCH_UNSPEC */ - const char * abiclass; /* ABI_CLASS_NONE */ - CARD32 abiversion; /* ABI_VERS_UNSPEC */ - const char * moduleclass; /* MOD_CLASS_NONE */ -} XF86ModReqInfo; -</verb> - - The information here is compared against the equivalent - information in the module's - &s.code;XF86ModuleVersionInfo&e.code; record (which - is described below). The values in comments above - indicate ``don't care'' settings for each of the fields. - The comparisons made are as follows: - - &s.code;majorversion&e.code; - <quote><p> - Must match the module's majorversion - exactly. - - </quote> - &s.code;minorversion&e.code; - <quote><p> - The module's minor version must be - no less than this value. This - comparison is only made if - &s.code;majorversion&e.code; is - specified and matches. - - </quote> - &s.code;patchlevel&e.code; - <quote><p> - The module's patchlevel must be no - less than this value. This comparison - is only made if - &s.code;minorversion&e.code; is - specified and matches. - - </quote> - &s.code;abiclass&e.code; - <quote><p> - String must match the module's abiclass - string. - - </quote> - &s.code;abiversion&e.code; - <quote><p> - Must be consistent with the module's - abiversion (major equal, minor no - older). - - </quote> - &s.code;moduleclass&e.code; - <quote><p> - String must match the module's - moduleclass string. - - </quote> - - </quote> - - &s.code;errmaj&e.code; - <quote><p> - An optional pointer to a variable holding the major - part or the error code. When provided, - &s.code;*errmaj&e.code; is filled in when - &s.code;LoadModule()&e.code; fails. - - </quote> - - &s.code;errmin&e.code; - <quote><p> - Like &s.code;errmaj&e.code;, but for the minor part - of the error code. - - </quote> - - </quote> - - &s.code;void UnloadModule(pointer mod)&e.code; - <quote><p> - This function unloads the module referred to by the handle mod. - All child modules are also unloaded recursively. This function must - not be used to directly unload modules that are child modules (i.e., - those that have been loaded with the &s.code;LoadSubModule()&e.code; - described below). - - </quote> - </quote> - -<sect1>Module Requirements -<p> - -Modules must provide information about themselves to the loader, and -may optionally provide entry points for "setup" and "teardown" functions -(those two functions are referred to here as &s.code;SetupProc&e.code; -and &s.code;TearDownProc&e.code;). - -The module information is contained in the -&s.code;XF86ModuleVersionInfo&e.code; struct, which is defined as follows: - -<quote><p><verb> -typedef struct { - const char * modname; /* name of module, e.g. "foo" */ - const char * vendor; /* vendor specific string */ - CARD32 _modinfo1_; /* constant MODINFOSTRING1/2 to find */ - CARD32 _modinfo2_; /* infoarea with a binary editor/sign tool */ - CARD32 xf86version; /* contains XF86_VERSION_CURRENT */ - CARD8 majorversion; /* module-specific major version */ - CARD8 minorversion; /* module-specific minor version */ - CARD16 patchlevel; /* module-specific patch level */ - const char * abiclass; /* ABI class that the module uses */ - CARD32 abiversion; /* ABI version */ - const char * moduleclass; /* module class */ - CARD32 checksum[4]; /* contains a digital signature of the */ - /* version info structure */ -} XF86ModuleVersionInfo; -</verb> - -The fields are used as follows: - - &s.code;modname&e.code; - <quote><p> - The module's name. This field is currently only for - informational purposes, but the loader may be modified - in future to require it to match the module's canonical - name. - - </quote> - - &s.code;vendor&e.code; - <quote><p> - The module vendor. This field is for informational purposes - only. - - </quote> - - &s.code;_modinfo1_&e.code; - <quote><p> - This field holds the first part of a signature that can - be used to locate this structure in the binary. It should - always be initialised to &s.code;MODINFOSTRING1&e.code;. - - </quote> - - &s.code;_modinfo2_&e.code; - <quote><p> - This field holds the second part of a signature that can - be used to locate this structure in the binary. It should - always be initialised to &s.code;MODINFOSTRING2&e.code;. - - </quote> - - &s.code;xf86version&e.code; - <quote><p> - The XFree86 version against which the module was compiled. - This is mostly for informational/diagnostic purposes. It - should be initialised to &s.code;XF86_VERSION_CURRENT&e.code;, which is - defined in &s.code;xf86Version.h&e.code;. - - </quote> - - &s.code;majorversion&e.code; - <quote><p> - The module-specific major version. For modules where this - version is used for more than simply informational - purposes, the major version should only change (be - incremented) when ABI incompatibilities are introduced, - or ABI components are removed. - - </quote> - - &s.code;minorversion&e.code; - <quote><p> - The module-specific minor version. For modules where this - version is used for more than simply informational - purposes, the minor version should only change (be - incremented) when ABI additions are made in a backward - compatible way. It should be reset to zero when the major - version is increased. - - </quote> - - &s.code;patchlevel&e.code; - <quote><p> - The module-specific patch level. The patch level should - increase with new revisions of the module where there - are no ABI changes, and it should be reset to zero when - the minor version is increased. - - </quote> - - &s.code;abiclass&e.code; - <quote><p> - The ABI class that the module requires. The class is - specified as a string for easy extensibility. It should - indicate which (if any) of the X server's built-in ABI - classes that the module relies on, or a third-party ABI - if appropriate. Built-in ABI classes currently defined are: - - <quote> - &s.code;ABI_CLASS_NONE&e.code; - <quote>no class</quote> - &s.code;ABI_CLASS_ANSIC&e.code; - <quote>only requires the ANSI C interfaces</quote> - &s.code;ABI_CLASS_VIDEODRV&e.code; - <quote>requires the video driver ABI</quote> - &s.code;ABI_CLASS_XINPUT&e.code; - <quote>requires the XInput driver ABI</quote> - &s.code;ABI_CLASS_EXTENSION&e.code; - <quote>requires the extension module ABI</quote> - &s.code;ABI_CLASS_FONT&e.code; - <quote>requires the font module ABI</quote> - </quote> - - </quote> - - &s.code;abiversion&e.code; - <quote><p> - The version of abiclass that the module requires. The - version consists of major and minor components. The - major version must match and the minor version must be - no newer than that provided by the server or parent - module. Version identifiers for the built-in classes - currently defined are: - - <quote> - &s.code;ABI_ANSIC_VERSION&nl; - ABI_VIDEODRV_VERSION&nl; - ABI_XINPUT_VERSION&nl; - ABI_EXTENSION_VERSION&nl; - ABI_FONT_VERSION&e.code; - </quote> - - </quote> - - &s.code;moduleclass&e.code; - <quote><p> - This is similar to the abiclass field, except that it - defines the type of module rather than the ABI it - requires. For example, although all video drivers require - the video driver ABI, not all modules that require the - video driver ABI are video drivers. This distinction - can be made with the moduleclass. Currently pre-defined - module classes are: - - <quote> - &s.code;MOD_CLASS_NONE&nl; - MOD_CLASS_VIDEODRV&nl; - MOD_CLASS_XINPUT&nl; - MOD_CLASS_FONT&nl; - MOD_CLASS_EXTENSION&e.code; - </quote> - - </quote> - - &s.code;checksum&e.code; - <quote><p> - Not currently used. - - </quote> - -</quote> - -The module version information, and the optional &s.code;SetupProc&e.code; -and &s.code;TearDownProc&e.code; entry points are found by the loader -by locating a data object in the module called "modnameModuleData", -where "modname" is the canonical name of the module. Modules must -contain such a data object, and it must be declared with global scope, -be compile-time initialised, and is of the following type: - -<quote> -<verb> -typedef struct { - XF86ModuleVersionInfo * vers; - ModuleSetupProc setup; - ModuleTearDownProc teardown; -} XF86ModuleData; -</verb> -</quote> - -The vers parameter must be initialised to a pointer to a correctly -initialised &s.code;XF86ModuleVersionInfo&e.code; struct. The other -two parameter are optional, and should be initialised to -&s.code;NULL&e.code; when not required. The other parameters are defined -as - - <quote><p> - &s.code;typedef pointer (*ModuleSetupProc)(pointer, pointer, int *, int *)&e.code; - - &s.code;typedef void (*ModuleTearDownProc)(pointer)&e.code; - - - &s.code;pointer SetupProc(pointer module, pointer options, - &f.indent;int *errmaj, int *errmin)&e.code; - <quote><p> - When defined, this function is called by the loader after successfully - loading a module. module is a handle for the newly loaded module, - and maybe used by the &s.code;SetupProc&e.code; if it calls other - loader functions that require a reference to it. The remaining - arguments are those that were passed to the - &s.code;LoadModule()&e.code; (or &s.code;LoadSubModule()&e.code;), - and are described above. When the &s.code;SetupProc&e.code; is - successful it must return a non-&s.code;NULL&e.code; value. The - loader checks this, and if it is &s.code;NULL&e.code; it unloads - the module and reports the failure to the caller of - &s.code;LoadModule()&e.code;. If the &s.code;SetupProc&e.code; - does things that need to be undone when the module is unloaded, - it should define a &s.code;TearDownProc&e.code;, and return a - pointer that the &s.code;TearDownProc&e.code; can use to undo what - has been done. - - When a module is loaded multiple times, the &s.code;SetupProc&e.code; - is called once for each time it is loaded. - - </quote> - - &s.code;void TearDownProc(pointer tearDownData)&e.code; - <quote><p> - When defined, this function is called when the loader unloads a - module. The &s.code;tearDownData&e.code; parameter is the return - value of the &s.code;SetupProc()&e.code; that was called when the - module was loaded. The purpose of this function is to clean up - before the module is unloaded (for example, by freeing allocated - resources). - - </quote> - </quote> - -<sect1>Public Loader Interface -<p> - -The following is the Loader interface that is available to any part of -the server, and may also be used from within modules. - - <quote><p> - &s.code;pointer LoadSubModule(pointer parent, const char *module, - &f.indent;const char **subdirlist, const char **patternlist, - &f.indent;pointer options, const XF86ModReqInfo * modreq, - &f.indent;int *errmaj, int *errmin)&e.code; - <quote><p> - This function is like the &s.code;LoadModule()&e.code; function - described above, except that the module loaded is registered as a - child of the calling module. The &s.code;parent&e.code; parameter - is the calling module's handle. Modules loaded with this function - are automatically unloaded when the parent module is unloaded. The - other difference is that the path parameter may not be specified. - The module search path used for modules loaded with this function - is the default search path as initialised with - &s.code;LoaderSetPath()&e.code;. - - </quote> - - &s.code;void UnloadSubModule(pointer module)&e.code; - <quote><p> - This function unloads the module with handle &s.code;module&e.code;. - If that module itself has children, they are also unloaded. It is - like &s.code;UnloadModule()&e.code;, except that it is safe to use - for unloading child modules. - - </quote> - - &s.code;pointer LoaderSymbol(const char *symbol)&e.code; - <quote><p> - This function returns the address of the symbol with name - &s.code;symbol&e.code;. This may be used to locate a module entry - point with a known name. - - </quote> - - &s.code;char **LoaderlistDirs(const char **subdirlist, - &f.indent;const char **patternlist)&e.code; - <quote><p> - This function returns a &s.code;NULL&e.code; terminated list of - canonical modules names for modules found in the default module - search path. The &s.code;subdirlist&e.code; and - &s.code;patternlist&e.code; parameters are as described above, and - can be used to control the locations and names that are searched. - If no modules are found, the return value is &s.code;NULL&e.code;. - The returned list should be freed by calling - &s.code;LoaderFreeDirList()&e.code; when it is no longer needed. - - </quote> - - &s.code;void LoaderFreeDirList(char **list)&e.code; - <quote><p> - This function frees a module list created by - &s.code;LoaderlistDirs()&e.code;. - - </quote> - - &s.code;void LoaderReqSymLists(const char **list0, ...)&e.code; - <quote><p> - This function allows the registration of required symbols with the - loader. It is normally used by a caller of - &s.code;LoadSubModule()&e.code;. If any symbols registered in this - way are found to be unresolved when - &s.code;LoaderCheckUnresolved()&e.code; is called then - &s.code;LoaderCheckUnresolved()&e.code; will report a failure. - The function takes one or more &s.code;NULL&e.code; terminated - lists of symbols. The end of the argument list is indicated by a - &s.code;NULL&e.code; argument. - - </quote> - - &s.code;void LoaderReqSymbols(const char *sym0, ...)&e.code; - <quote><p> - This function is like &s.code;LoaderReqSymLists()&e.code; except - that its arguments are symbols rather than lists of symbols. This - function is more convenient when single functions are to be registered, - especially when the single function might depend on runtime factors. - The end of the argument list is indicated by a &s.code;NULL&e.code; - argument. - - </quote> - - &s.code;void LoaderRefSymLists(const char **list0, ...)&e.code; - <quote><p> - This function allows the registration of possibly unresolved symbols - with the loader. When &s.code;LoaderCheckUnresolved()&e.code; is - run it won't generate warnings for symbols registered in this way - unless they were also registered as required symbols. - The function takes one or more &s.code;NULL&e.code; terminated - lists of symbols. The end of the argument list is indicated by a - &s.code;NULL&e.code; argument. - - </quote> - - &s.code;void LoaderRefSymbols(const char *sym0, ...)&e.code; - <quote><p> - This function is like &s.code;LoaderRefSymLists()&e.code; except - that its arguments are symbols rather than lists of symbols. This - function is more convenient when single functions are to be registered, - especially when the single function might depend on runtime factors. - The end of the argument list is indicated by a &s.code;NULL&e.code; - argument. - - </quote> - - &s.code;int LoaderCheckUnresolved(int delayflag)&e.code; - <quote><p> - This function checks for unresolved symbols. It generates warnings - for unresolved symbols that have not been registered with - &s.code;LoaderRefSymLists()&e.code;, and maps them to a dummy - function. This behaviour may change in future. If unresolved - symbols are found that have been registered with - &s.code;LoaderReqSymLists()&e.code; or - &s.code;LoaderReqSymbols()&e.code; then this function returns a - non-zero value. If none of these symbols are unresolved the return - value is zero, indicating success. - - The &s.code;delayflag&e.code; parameter should normally be set to - &s.code;LD_RESOLV_IFDONE&e.code;. - - </quote> - - &s.code;LoaderErrorMsg(const char *name, const char *modname, - &f.indent;int errmaj, int errmin)&e.code; - <quote><p> - This function prints an error message that includes the text ``Failed - to load module'', the module name &s.code;modname&e.code;, a message - specific to the &s.code;errmaj&e.code; value, and the value if - &s.code;errmin&e.code;. If &s.code;name&e.code; is - non-&s.code;NULL&e.code;, it is printed as an identifying prefix - to the message (followed by a `:'). - - </quote> - </quote> - -<sect1>Special Registration Functions -<p> - -The loader contains some functions for registering some classes of modules. -These may be moved out of the loader at some point. - - <quote><p> - &s.code;void LoadExtension(ExtensionModule *ext)&e.code; - <quote><p> - This registers the entry points for the extension identified by - &s.code;ext&e.code;. The &s.code;ExtensionModule&e.code; struct is - defined as: - -<quote> -<verb> -typedef struct { - InitExtension initFunc; - char * name; - Bool *disablePtr; - InitExtension setupFunc; -} ExtensionModule; -</verb> -</quote> - - </quote> - - &s.code;void LoadFont(FontModule *font)&e.code; - <quote><p> - This registers the entry points for the font rasteriser module - identified by &s.code;font&e.code;. The &s.code;FontModule&e.code; - struct is defined as: - -<quote> -<verb> -typedef struct { - InitFont initFunc; - char * name; - pointer module; -} FontModule; -</verb> -</quote> - - </quote> - </quote> - -</sect> - - -<sect>Helper Functions -<p> - -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. - -<sect1>Functions for printing messages -<p> - - <quote><p> - &s.code;ErrorF(const char *format, ...)&e.code; - <quote><p> - 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. - - </quote> - - &s.code;FatalError(const char *format, ...)&e.code; - <quote><p> - 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. - - </quote> - - &s.code;xf86ErrorF(const char *format, ...)&e.code; - <quote><p> - This is like &s.code;ErrorF()&e.code;, except that the message is - only printed when the Xserver's verbosity level is set to the - default (&s.code;1&e.code;) or higher. It means that the messages - are not printed when the server is started with the - &s.cmd;-quiet&e.cmd; flag. Typically this function would only be - used for continuing messages started with one of the more specialised - functions described below. - - </quote> - - &s.code;xf86ErrorFVerb(int verb, const char *format, ...)&e.code; - <quote><p> - Like &s.code;xf86ErrorF()&e.code;, except the minimum verbosity - level for which the message is to be printed is given explicitly. - Passing a &s.code;verb&e.code; value of zero means the message - is always printed. A value higher than &s.code;1&e.code; can be - used for information would normally not be needed, but which might - be useful when diagnosing problems. - - </quote> - - &s.code;xf86Msg(MessageType type, const char *format, ...)&e.code; - <quote><p> - This is like &s.code;xf86ErrorF()&e.code;, except that the message - is prefixed with a marker determined by the value of - &s.code;type&e.code;. The marker is used to indicate the type of - message (warning, error, probed value, config value, etc). Note - the &s.code;xf86Verbose&e.code; value is ignored for messages of - type &s.code;X_ERROR&e.code;. - - The marker values are: - - <quote> - &s.code;X_PROBED&e.code; - <quote>Value was probed.</quote> - &s.code;X_CONFIG&e.code; - <quote>Value was given in the config file.</quote> - &s.code;X_DEFAULT&e.code; - <quote>Value is a default.</quote> - &s.code;X_CMDLINE&e.code; - <quote>Value was given on the command line.</quote> - &s.code;X_NOTICE&e.code; - <quote>Notice.</quote> - &s.code;X_ERROR&e.code; - <quote>Error message.</quote> - &s.code;X_WARNING&e.code; - <quote>Warning message.</quote> - &s.code;X_INFO&e.code; - <quote>Informational message.</quote> - &s.code;X_NONE&e.code; - <quote>No prefix.</quote> - &s.code;X_NOT_IMPLEMENTED&e.code; - <quote>The message relates to functionality that is not yet - implemented.</quote> - </quote> - - - </quote> - - &s.code;xf86MsgVerb(MessageType type, int verb, const char *format, ...)&e.code; - <quote><p> - Like &s.code;xf86Msg()&e.code;, but with the verbosity level given - explicitly. - - </quote> - - &s.code;xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)&e.code; - <quote><p> - This is like &s.code;xf86Msg()&e.code; except that the driver's - name (the &s.code;name&e.code; field of the - &s.code;ScrnInfoRec&e.code;) followed by the - &s.code;scrnIndex&e.code; 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 - &s.code;scrnIndex&e.code; is negative, this function behaves - exactly like &s.code;xf86Msg()&e.code;. - - NOTE: This function can only be used after the - &s.code;ScrnInfoRec&e.code; and its &s.code;name&e.code; field - have been allocated. Normally, this means that it can not be - used before the END of the &s.code;ChipProbe()&e.code; function. - Prior to that, use &s.code;xf86Msg()&e.code;, providing the - driver's name explicitly. No screen number can be supplied at - that point. - - </quote> - - &s.code;xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, - &f.indent;const char *format, ...)&e.code; - <quote><p> - Like &s.code;xf86DrvMsg()&e.code;, but with the verbosity level - given explicitly. - - </quote> - </quote> - - -<sect1>Functions for setting values based on command line and config file -<p> - - <quote><p> - &s.code;Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp, - &f.indent;int fbbpp, int depth24flags)&e.code; - <quote><p> - This function sets the &s.code;depth&e.code;, &s.code;pixmapBPP&e.code; and &s.code;bitsPerPixel&e.code; fields - of the &s.code;ScrnInfoRec&e.code;. 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 - &s.code;ChipPreInit()&e.code; function. - - It requires that the &s.code;confScreen&e.code; field of the &s.code;ScrnInfoRec&e.code; be - initialised prior to calling it. This is done by the XFree86 - common layer prior to calling &s.code;ChipPreInit()&e.code;. - - The parameters passed are: - - &s.code;depth&e.code; - <quote><p> - driver's preferred default depth if no other is given. - If zero, use the overall server default. - - </quote> - &s.code;bpp&e.code; - <quote><p> - Same, but for the pixmap bpp. - - </quote> - &s.code;fbbpp&e.code; - <quote><p> - Same, but for the framebuffer bpp. - - </quote> - &s.code;depth24flags&e.code; - <quote><p> - 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: - - &s.code;NoDepth24Support&e.code; - <quote>No depth 24 formats supported</quote> - &s.code;Support24bppFb&e.code; - <quote>24bpp framebuffer supported</quote> - &s.code;Support32bppFb&e.code; - <quote>32bpp framebuffer supported</quote> - &s.code;SupportConvert24to32&e.code; - <quote>Can convert 24bpp pixmap to 32bpp fb</quote> - &s.code;SupportConvert32to24&e.code; - <quote>Can convert 32bpp pixmap to 24bpp fb</quote> - &s.code;ForceConvert24to32&e.code; - <quote>Force 24bpp pixmap to 32bpp fb conversion</quote> - &s.code;ForceConvert32to24&e.code; - <quote>Force 32bpp pixmap to 24bpp fb conversion</quote> - - </quote> - - 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 &s.code;ChipPreInit()&e.code; function should - return &s.code;FALSE&e.code;. - - 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 &s.code;depth24flags&e.code; - 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 &s.code;depth24flags&e.code; setting. - - On success, the return value is &s.code;TRUE&e.code;. On failure - it prints an error message and returns &s.code;FALSE&e.code;. - - The following fields of the &s.code;ScrnInfoRec&e.code; are - initialised by this function: - - <quote> - &s.code;depth&e.code;, &s.code;bitsPerPixel&e.code;, - &s.code;display&e.code;, &s.code;imageByteOrder&e.code;, - &s.code;bitmapScanlinePad&e.code;, - &s.code;bitmapScanlineUnit&e.code;, &s.code;bitmapBitOrder&e.code;, - &s.code;numFormats&e.code;, &s.code;formats&e.code;, - &s.code;fbFormat&e.code;. - </quote> - - </quote> - - &s.code;void xf86PrintDepthBpp(scrnInfoPtr scrp)&e.code; - <quote><p> - This function can be used to print out the depth and bpp settings. - It should be called after the final call to - &s.code;xf86SetDepthBpp()&e.code;. - - </quote> - - &s.code;Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)&e.code; - <quote><p> - This function sets the &s.code;weight&e.code;, &s.code;mask&e.code;, - &s.code;offset&e.code; and &s.code;rgbBits&e.code; fields of the - &s.code;ScrnInfoRec&e.code;. It would normally be called fairly - early in the &s.code;ChipPreInit()&e.code; function for - depths > 8bpp. - - It requires that the &s.code;depth&e.code; and - &s.code;display&e.code; fields of the &s.code;ScrnInfoRec&e.code; - be initialised prior to calling it. - - The parameters passed are: - - &s.code;weight&e.code; - <quote><p> - driver's preferred default weight if no other is given. - If zero, use the overall server default. - - </quote> - - &s.code;mask&e.code; - <quote><p> - Same, but for mask. - - </quote> - - 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 &s.code;ChipPreInit()&e.code; function should - return &s.code;FALSE&e.code;. - - On success, this function prints a message showing the weight - values selected, and returns &s.code;TRUE&e.code;. - - On failure it prints an error message and returns &s.code;FALSE&e.code;. - - The following fields of the &s.code;ScrnInfoRec&e.code; are - initialised by this function: - - <quote> - &s.code;weight&e.code;, &s.code;mask&e.code;, &s.code;offset&e.code;. - </quote> - - </quote> - - &s.code;Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)&e.code; - <quote><p> - This function sets the &s.code;defaultVisual&e.code; field of the - &s.code;ScrnInfoRec&e.code;. It would normally be called fairly - early from the &s.code;ChipPreInit()&e.code; function. - - It requires that the &s.code;depth&e.code; and - &s.code;display&e.code; fields of the &s.code;ScrnInfoRec&e.code; - be initialised prior to calling it. - - The parameters passed are: - - &s.code;visual&e.code; - <quote><p> - driver's preferred default visual if no other is given. - If &s.code;-1&e.code;, use the overall server default. - - </quote> - - 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 &s.code;ChipPreInit()&e.code; function should - return &s.code;FALSE&e.code;. - - On success, this function prints a message showing the default visual - selected, and returns &s.code;TRUE&e.code;. - - On failure it prints an error message and returns &s.code;FALSE&e.code;. - - </quote> - - &s.code;Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)&e.code; - <quote><p> - This function sets the &s.code;gamma&e.code; field of the - &s.code;ScrnInfoRec&e.code;. It would normally be called fairly - early from the &s.code;ChipPreInit()&e.code; function in cases - where the driver supports gamma correction. - - It requires that the &s.code;monitor&e.code; field of the - &s.code;ScrnInfoRec&e.code; be initialised prior to calling it. - - The parameters passed are: - - &s.code;gamma&e.code; - <quote><p> - driver's preferred default gamma if no other is given. - If zero (&s.code;< 0.01&e.code;), use the overall server - default. - - </quote> - - 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 &s.code;ChipPreInit()&e.code; function should - return &s.code;FALSE&e.code;. - - On success, this function prints a message showing the gamma - value selected, and returns &s.code;TRUE&e.code;. - - On failure it prints an error message and returns &s.code;FALSE&e.code;. - - </quote> - - &s.code;void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)&e.code; - <quote><p> - This function sets the &s.code;xDpi&e.code; and &s.code;yDpi&e.code; - fields of the &s.code;ScrnInfoRec&e.code;. The driver can specify - preferred defaults by setting &s.code;x&e.code; and &s.code;y&e.code; - to non-zero values. The &s.cmd;-dpi&e.cmd; command line option - overrides all other settings. Otherwise, if the - &s.key;DisplaySize&e.key; entry is present in the screen's &k.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. - - </quote> - - &s.code;void xf86SetBlackWhitePixels(ScrnInfoPtr pScrn)&e.code; - <quote><p> - This functions sets the &s.code;blackPixel&e.code; and - &s.code;whitePixel&e.code; fields of the &s.code;ScrnInfoRec&e.code; - according to whether or not the &s.cmd;-flipPixels&e.cmd; command - line options is present. - - </quote> - - &s.code;const char *xf86GetVisualName(int visual)&e.code; - <quote><p> - 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, &s.code;NULL&e.code; is returned. - - </quote> - </quote> - - -<sect1>Primary Mode functions -<p> - -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. - - <quote><p> - &s.code;int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, - &f.indent;char **modeNames, ClockRangePtr clockRanges, - &f.indent;int *linePitches, int minPitch, int maxPitch, - &f.indent;int pitchInc, int minHeight, int maxHeight, - &f.indent;int virtualX, int virtualY, - &f.indent;unsigned long apertureSize, - &f.indent;LookupModeFlags strategy)&e.code; - <quote><p> - 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 &s.code;ChipPreInit()&e.code; function. - - The parameters passed to the function are: - - &s.code;availModes&e.code; - <quote><p> - List of modes available for the monitor. - - </quote> - &s.code;modeNames&e.code; - <quote><p> - List of mode names that the screen is requesting. - - </quote> - &s.code;clockRanges&e.code; - <quote><p> - 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 - &s.code;clockRanges&e.code;. - - </quote> - &s.code;linePitches&e.code; - <quote><p> - List of line pitches supported by the driver. - This is optional and should be &s.code;NULL&e.code; when - not used. - - </quote> - &s.code;minPitch&e.code; - <quote><p> - Minimum line pitch supported by the driver. This must - be supplied when &s.code;linePitches&e.code; is - &s.code;NULL&e.code;, and is ignored otherwise. - - </quote> - &s.code;maxPitch&e.code; - <quote><p> - Maximum line pitch supported by the driver. This is - required when &s.code;minPitch&e.code; is required. - - </quote> - &s.code;pitchInc&e.code; - <quote><p> - Granularity of horizontal pitch values as supported by - the chipset. This is expressed in bits. This must be - supplied. - - </quote> - &s.code;minHeight&e.code; - <quote><p> - minimum virtual height allowed. If zero, no limit is - imposed. - - </quote> - &s.code;maxHeight&e.code; - <quote><p> - maximum virtual height allowed. If zero, no limit is - imposed. - - </quote> - &s.code;virtualX&e.code; - <quote><p> - 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. - - </quote> - &s.code;virtualY&e.code; - <quote><p> - 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. - - </quote> - &s.code;apertureSize&e.code; - <quote><p> - The size (in bytes) of the aperture used to access video - memory. - - </quote> - &s.code;strategy&e.code; - <quote><p> - The strategy to use when choosing from multiple modes - with the same name. The options are: - - &s.code;LOOKUP_DEFAULT&e.code; - <quote>???</quote> - &s.code;LOOKUP_BEST_REFRESH&e.code; - <quote>mode with best refresh rate</quote> - &s.code;LOOKUP_CLOSEST_CLOCK&e.code; - <quote>mode with closest matching clock</quote> - &s.code;LOOKUP_LIST_ORDER&e.code; - <quote>first usable mode in list</quote> - - The following options can also be combined (OR'ed) with - one of the above: - - &s.code;LOOKUP_CLKDIV2&e.code; - <quote>Allow halved clocks</quote> - &s.code;LOOKUP_OPTIONAL_TOLERANCES&e.code; - <quote>Allow missing horizontal sync and/or vertical refresh - ranges in the xorg.conf Monitor section</quote> - - &s.code;LOOKUP_OPTIONAL_TOLERANCES&e.code; 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). - - </quote> - - This function requires that the following fields of the - &s.code;ScrnInfoRec&e.code; are initialised prior to calling it: - - &s.code;clock[]&e.code; - <quote>List of discrete clocks (when non-programmable)</quote> - &s.code;numClocks&e.code; - <quote>Number of discrete clocks (when non-programmable)</quote> - &s.code;progClock&e.code; - <quote>Whether the clock is programmable or not</quote> - &s.code;monitor&e.code; - <quote>Pointer to the applicable xorg.conf monitor section</quote> - &s.code;fdFormat&e.code; - <quote>Format of the screen buffer</quote> - &s.code;videoRam&e.code; - <quote>total video memory size (in bytes)</quote> - &s.code;maxHValue&e.code; - <quote>Maximum horizontal timing value allowed</quote> - &s.code;maxVValue&e.code; - <quote>Maximum vertical timing value allowed</quote> - &s.code;xInc&e.code; - <quote>Horizontal timing increment in pixels (defaults to 8)</quote> - - This function fills in the following &s.code;ScrnInfoRec&e.code; - fields: - - &s.code;modePool&e.code; - <quote><p> - A subset of the modes available to the monitor which - are compatible with the driver. - - </quote> - &s.code;modes&e.code; - <quote><p> - 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. - - </quote> - &s.code;virtualX&e.code; - <quote><p> - The resulting virtual width. - - </quote> - &s.code;virtualY&e.code; - <quote><p> - The resulting virtual height. - - </quote> - &s.code;displayWidth&e.code; - <quote><p> - The resulting line pitch. - - </quote> - &s.code;virtualFrom&e.code; - <quote><p> - Where the virtual size was determined from. - - </quote> - - The first stage of this function checks that the - &s.code;virtualX&e.code; and &s.code;virtualY&e.code; values - supplied (if greater than zero) are consistent with the line pitch - and &s.code;maxHeight&e.code; limitations. If not, an error - message is printed, and the return value is &s.code;-1&e.code;. - - 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 &s.code;2&e.code;. If the mode pool ends up being empty, - a warning message is printed, and the return value is - &s.code;0&e.code;. - - 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 &s.code;-1&e.code;. Otherwise, - the return value is the number of valid modes found - (&s.code;0&e.code; 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 &s.code;-1&e.code;, the - &s.code;ChipPreInit()&e.code; function should return - &s.code;FALSE&e.code;. - - &s.code;clockRanges&e.code; is a linked list of clock ranges - allowed by the driver. If a mode doesn't fit in any of the defined - &s.code;clockRanges&e.code;, it is rejected. The first - &s.code;clockRange&e.code; that matches all requirements is used. - This structure needs to be initialized to NULL when allocated. - - &s.code;clockRanges&e.code; contains the following fields: - - &s.code;minClock&nl; - maxClock&e.code; - <quote><p> - The lower and upper mode clock bounds for which the rest - of the &s.code;clockRange&e.code; parameters apply. - Since these are the mode clocks, they are not scaled - with the &s.code;ClockMulFactor&e.code; and - &s.code;ClockDivFactor&e.code;. It is up to the driver - to adjust these values if they depend on the clock - scaling factors. - - </quote> - &s.code;clockIndex&e.code; - <quote><p> - (not used yet) &s.code;-1&e.code; for programmable clocks - - </quote> - &s.code;interlaceAllowed&e.code; - <quote><p> - &s.code;TRUE&e.code; if interlacing is allowed for this - range - - </quote> - &s.code;doubleScanAllowed&e.code; - <quote><p> - &s.code;TRUE&e.code; if doublescan or multiscan is allowed - for this range - - </quote> - &s.code;ClockMulFactor&nl; - ClockDivFactor&e.code; - <quote><p> - Scaling factors that are applied to the mode clocks ONLY - before selecting a clock index (when there is no - programmable clock) or a &s.code;SynthClock&e.code; - 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 &s.code;2:1&e.code; 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, &s.code;ClockMulFactor=1&e.code; and - &s.code;ClockDivFactor=2&e.code;. This means that the - clock used for clock selection (ie, determining the - correct clock index from the list of discrete clocks) - or for the &s.code;SynthClock&e.code; field in case of - a programmable clock is: (&s.code;mode->Clock * - ClockMulFactor) / ClockDivFactor&e.code;. - - </quote> - &s.code;PrivFlags&e.code; - <quote><p> - This field is copied into the - &s.code;mode->PrivFlags&e.code; field when this - &s.code;clockRange&e.code; is selected by - &s.code;xf86ValidateModes()&e.code;. 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 &s.code;INT&e.code;). - </quote> - - Note that the &s.code;mode->SynthClock&e.code; field is always - filled in by &s.code;xf86ValidateModes()&e.code;: 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: - - &s.code;mode->SynthClock = - &f.indent;(mode->Clock * ClockMulFactor) / ClockDivFactor&e.code; - - </quote> - - &s.code;void xf86PruneDriverModes(ScrnInfoPtr scrp)&e.code; - <quote><p> - This function deletes modes in the modes field of the - &s.code;ScrnInfoRec&e.code; that have been marked as invalid. - This is normally run after having run - &s.code;xf86ValidateModes()&e.code; for the last time. For each - mode that is deleted, a warning message is printed out indicating - the reason for it being deleted. - - </quote> - - &s.code;void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)&e.code; - <quote><p> - This function fills in the &s.code;Crtc*&e.code; fields for all - the modes in the &s.code;modes&e.code; field of the - &s.code;ScrnInfoRec&e.code;. The &s.code;adjustFlags&e.code; - parameter determines how the vertical CRTC values are scaled for - interlaced modes. They are halved if it is - &s.code;INTERLACE_HALVE_V&e.code;. The vertical CRTC values are - doubled for doublescan modes, and are further multiplied by the - &s.code;VScan&e.code; value. - - This function is normally called after calling - &s.code;xf86PruneDriverModes()&e.code;. - - </quote> - - &s.code;void xf86PrintModes(ScrnInfoPtr scrp)&e.code; - <quote><p> - This function prints out the virtual size setting, and the line - pitch being used. It also prints out two lines for each mode being - used. The first line includes the mode's pixel clock, horizontal sync - rate, refresh rate, and whether it is interlaced, doublescanned and/or - multi-scanned. The second line is the mode's Modeline. - - This function is normally called after calling - &s.code;xf86SetCrtcForModes()&e.code;. - - </quote> - </quote> - - -<sect1>Secondary Mode functions -<p> - -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. - - <quote><p> - &s.code;int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2, - &f.indent;int *divider)&e.code; - <quote><p> - This function returns the index of the closest clock to the - frequency &s.code;freq&e.code; given (in kHz). It assumes that - the number of clocks is greater than zero. It requires that the - &s.code;numClocks&e.code; and &s.code;clock&e.code; fields of the - &s.code;ScrnInfoRec&e.code; are initialised. The - &s.code;allowDiv2&e.code; field determines if the clocks can be - halved. The &s.code;*divider&e.code; return value indicates - whether clock division is used when determining the clock returned. - - This function is only for non-programmable clocks. - - </quote> - - &s.code;const char *xf86ModeStatusToString(ModeStatus status)&e.code; - <quote><p> - This function converts the &s.code;status&e.code; value to a - descriptive printable string. - - </quote> - - &s.code;ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep, - &f.indent;ClockRangePtr clockRanges, LookupModeFlags strategy)&e.code; - <quote><p> - This function takes a pointer to a mode with the name filled in, - and looks for a mode in the &s.code;modePool&e.code; list which - matches. The parameters of the matching mode are filled in to - &s.code;*modep&e.code;. The &s.code;clockRanges&e.code; and - &s.code;strategy&e.code; parameters are as for the - &s.code;xf86ValidateModes()&e.code; function above. - - This function requires the &s.code;modePool&e.code;, - &s.code;clock[]&e.code;, &s.code;numClocks&e.code; and - &s.code;progClock&e.code; fields of the &s.code;ScrnInfoRec&e.code; - to be initialised before being called. - - The return value is &s.code;MODE_OK&e.code; if a mode was found. - Otherwise it indicates why a matching mode could not be found. - - </quote> - - &s.code;ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, - &f.indent;DisplayModePtr mode, ClockRangePtr clockRanges, - &f.indent;LookupModeFlags strategy, int maxPitch, - &f.indent;int virtualX, int virtualY)&e.code; - <quote><p> - This function checks the passed mode against some basic driver - constraints. Apart from the ones passed explicitly, the - &s.code;maxHValue&e.code; and &s.code;maxVValue&e.code; fields of - the &s.code;ScrnInfoRec&e.code; are also used. If the - &s.code;ValidMode&e.code; field of the &s.code;ScrnInfoRec&e.code; - 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 &s.code;MODE_OK&e.code;. Otherwise the return value indicates - which constraint wasn't met. - - </quote> - - &s.code;void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)&e.code; - <quote><p> - This function deletes the &s.code;mode&e.code; given from the - &s.code;modeList&e.code;. It never prints any messages, so it is - up to the caller to print a message if required. - - </quote> - </quote> - -<sect1>Functions for handling strings and tokens -<p> - - 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: - -<quote><verb> -typedef struct { - int token; - const char * name; -} SymTabRec, *SymTabPtr; -</verb></quote> - - A table is an initialised array of &s.code;SymTabRec&e.code;. 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 - &s.code;token&e.code; value of &s.code;-1&e.code; and - &s.code;NULL&e.code; for the &s.code;name&e.code;. - - - <quote><p> - &s.code;const char *xf86TokenToString(SymTabPtr table, int token)&e.code; - <quote><p> - This function returns the first string in &s.code;table&e.code; - that matches &s.code;token&e.code;. If no match is found, - &s.code;NULL&e.code; is returned (NOTE, older versions of this - function would return the string "unknown" when no match is found). - - </quote> - - &s.code;int xf86StringToToken(SymTabPtr table, const char *string)&e.code; - <quote><p> - This function returns the first token in &s.code;table&e.code; - that matches &s.code;string&e.code;. The - &s.code;xf86NameCmp()&e.code; function is used to determine the - match. If no match is found, &s.code;-1&e.code; is returned. - - </quote> - </quote> - - -<sect1>Functions for finding which config file entries to use -<p> - - These functions can be used to select the appropriate config file - entries that match the detected hardware. They are described above - in the <ref id="probe" name="Probe"> and - <ref id="avail" name="Available Functions"> sections. - - -<sect1>Probing discrete clocks on old hardware -<p> - - The &s.code;xf86GetClocks()&e.code; function may be used to assist - in finding the discrete pixel clock values on older hardware. - - - <quote><p> - &s.code;void xf86GetClocks(ScrnInfoPtr pScrn, int num, - &f.indent;Bool (*ClockFunc)(ScrnInfoPtr, int), - &f.indent;void (*ProtectRegs)(ScrnInfoPtr, Bool), - &f.indent;void (*BlankScreen)(ScrnInfoPtr, Bool), - &f.indent;int vertsyncreg, int maskval, int knownclkindex, - &f.indent;int knownclkvalue)&e.code; - <quote><p> - This function uses a comparative sampling method to measure the - discrete pixel clock values. The number of discrete clocks to - measure is given by &s.code;num&e.code;. &s.code;clockFunc&e.code; - is a function that selects the &s.code;n&e.code;'th clock. It - should also save or restore any state affected by programming the - clocks when the index passed is &s.code;CLK_REG_SAVE&e.code; or - &s.code;CLK_REG_RESTORE&e.code;. &s.code;ProtectRegs&e.code; is - a function that does whatever is required to protect the hardware - state while selecting a new clock. &s.code;BlankScreen&e.code; - is a function that blanks the screen. &s.code;vertsyncreg&e.code; - and &s.code;maskval&e.code; are the register and bitmask to - check for the presence of vertical sync pulses. - &s.code;knownclkindex&e.code; and &s.code;knownclkvalue&e.code; - 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 &s.code;pScrn->numClocks&e.code;, - and the probed clocks are set in the &s.code;pScrn->clock[]&e.code; - array. All of the clock values are in units of kHz. - - </quote> - - &s.code;void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)&e.code; - <quote><p> - Print out the pixel clocks &s.code;scrp->clock[]&e.code;. - &s.code;from&e.code; indicates whether the clocks were probed - or from the config file. - - </quote> - </quote> - -<sect1>Other helper functions -<p> - <quote><p> - &s.code;Bool xf86IsUnblank(int mode)&e.code; - <quote><p> - Returns &s.code;TRUE&e.code; when the screen saver mode specified - by &s.code;mode&e.code; requires the screen be unblanked, - and &s.code;FALSE&e.code; otherwise. The screen saver modes that - require blanking are &s.code;SCREEN_SAVER_ON&e.code; and - &s.code;SCREEN_SAVER_CYCLE&e.code;, and the screen saver modes that - require unblanking are &s.code;SCREEN_SAVER_OFF&e.code; and - &s.code;SCREEN_SAVER_FORCER&e.code;. Drivers may call this helper - from their &s.code;SaveScreen()&e.code; function to interpret the - screen saver modes. - - </quote> - </quote> - -<sect>The vgahw module -<p> - -The vgahw modules provides an interface for saving, restoring and -programming the standard VGA registers, and for handling VGA colourmaps. - -<sect1>Data Structures -<p> - - The public data structures used by the vgahw module are - &s.code;vgaRegRec&e.code; and &s.code;vgaHWRec&e.code;. They are - defined in &s.code;vgaHW.h.&e.code; - - -<sect1>General vgahw Functions -<p> - - <quote><p> - &s.code;Bool vgaHWGetHWRec(ScrnInfoPtr pScrn)&e.code; - <quote><p> - This function allocates a &s.code;vgaHWRec&e.code; structure, and - hooks it into the &s.code;ScrnInfoRec&e.code;'s - &s.code;privates&e.code;. Like all information hooked into the - &s.code;privates&e.code;, it is persistent, and only needs to be - allocated once per screen. This function should normally be called - from the driver's &s.code;ChipPreInit()&e.code; function. The - &s.code;vgaHWRec&e.code; is zero-allocated, and the following - fields are explicitly initialised: - - &s.code;ModeReg.DAC[]&e.code; - <quote>initialised with a default colourmap</quote> - &s.code;ModeReg.Attribute[0x11]&e.code; - <quote>initialised with the default overscan index</quote> - &s.code;ShowOverscan&e.code; - <quote>initialised according to the "ShowOverscan" option</quote> - &s.code;paletteEnabled&e.code; - <quote>initialised to FALSE</quote> - &s.code;cmapSaved&e.code; - <quote>initialised to FALSE</quote> - &s.code;pScrn&e.code; - <quote>initialised to pScrn</quote> - - In addition to the above, &s.code;vgaHWSetStdFuncs()&e.code; is - called to initialise the register access function fields with the - standard VGA set of functions. - - Once allocated, a pointer to the &s.code;vgaHWRec&e.code; can be - obtained from the &s.code;ScrnInfoPtr&e.code; with the - &s.code;VGAHWPTR(pScrn)&e.code; macro. - - </quote> - - &s.code;void vgaHWFreeHWRec(ScrnInfoPtr pScrn)&e.code; - <quote><p> - This function frees a &s.code;vgaHWRec&e.code; structure. It - should be called from a driver's &s.code;ChipFreeScreen()&e.code; - function. - - </quote> - - &s.code;Bool vgaHWSetRegCounts(ScrnInfoPtr pScrn, int numCRTC, - &f.indent;int numSequencer, int numGraphics, int numAttribute)&e.code; - <quote><p> - This function allows the number of CRTC, Sequencer, Graphics and - Attribute registers to be changed. This makes it possible for - extended registers to be saved and restored with - &s.code;vgaHWSave()&e.code; and &s.code;vgaHWRestore()&e.code;. - This function should be called after a &s.code;vgaHWRec&e.code; - has been allocated with &s.code;vgaHWGetHWRec()&e.code;. The - default values are defined in &s.code;vgaHW.h&e.code; as follows: - - <quote><verb> -#define VGA_NUM_CRTC 25 -#define VGA_NUM_SEQ 5 -#define VGA_NUM_GFX 9 -#define VGA_NUM_ATTR 21 - </verb></quote> - - </quote> - - &s.code;Bool vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)&e.code; - <quote><p> - This function copies the contents of the VGA saved registers in - &s.code;src&e.code; to &s.code;dst&e.code;. Note that it isn't - possible to simply do this with &s.code;memcpy()&e.code; (or - similar). This function returns &s.code;TRUE&e.code; unless there - is a problem allocating space for the &s.code;CRTC&e.code and - related fields in &s.code;dst&e.code;. - - </quote> - - &s.code;void vgaHWSetStdFuncs(vgaHWPtr hwp)&e.code; - <quote><p> - This function initialises the register access function fields of - &s.code;hwp&e.code; with the standard VGA set of functions. This - is called by &s.code;vgaHWGetHWRec()&e.code;, so there is usually - no need to call this explicitly. The register access functions - are described below. If the registers are shadowed in some other - port I/O space (for example a PCI I/O region), these functions - can be used to access the shadowed registers if - &s.code;hwp->PIOOffset&e.code; is initialised with - &s.code;offset&e.code;, calculated in such a way that when the - standard VGA I/O port value is added to it the correct offset into - the PIO area results. This value is initialised to zero in - &s.code;vgaHWGetHWRec()&e.code;. (Note: the PIOOffset functionality - is present in XFree86 4.1.0 and later.) - - </quote> - - &s.code;void vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)&e.code; - <quote><p> - This function initialised the register access function fields of - hwp with a generic MMIO set of functions. - &s.code;hwp->MMIOBase&e.code; is initialised with - &s.code;base&e.code;, which must be the virtual address that the - start of MMIO area is mapped to. &s.code;hwp->MMIOOffset&e.code; - is initialised with &s.code;offset&e.code;, which must be calculated - in such a way that when the standard VGA I/O port value is added - to it the correct offset into the MMIO area results. That means - that these functions are only suitable when the VGA I/O ports are - made available in a direct mapping to the MMIO space. If that is - not the case, the driver will need to provide its own register - access functions. The register access functions are described - below. - - </quote> - - &s.code;Bool vgaHWMapMem(ScrnInfoPtr pScrn)&e.code; - <quote><p> - This function maps the VGA memory window. It requires that the - &s.code;vgaHWRec&e.code; be allocated. If a driver requires - non-default &s.code;MapPhys&e.code; or &s.code;MapSize&e.code; - settings (the physical location and size of the VGA memory window) - then those fields of the &s.code;vgaHWRec&e.code; must be initialised - before calling this function. Otherwise, this function initialiases - the default values of &s.code;0xA0000&e.code; for - &s.code;MapPhys&e.code; and &s.code;(64 * 1024)&e.code; for - &s.code;MapSize&e.code;. This function must be called before - attempting to save or restore the VGA state. If the driver doesn't - call it explicitly, the &s.code;vgaHWSave()&e.code; and - &s.code;vgaHWRestore()&e.code; functions may call it if they need - to access the VGA memory (in which case they will also call - &s.code;vgaHWUnmapMem()&e.code; to unmap the VGA memory before - exiting). - - </quote> - - &s.code;void vgaHWUnmapMem(ScrnInfoPtr pScrn)&e.code; - <quote><p> - This function unmaps the VGA memory window. It must only be called - after the memory has been mapped. The &s.code;Base&e.code; field - of the &s.code;vgaHWRec&e.code; field is set to &s.code;NULL&e.code; - to indicate that the memory is no longer mapped. - - </quote> - - &s.code;void vgaHWGetIOBase(vgaHWPtr hwp)&e.code; - <quote><p> - This function initialises the &s.code;IOBase&e.code; field of the - &s.code;vgaHWRec&e.code;. This function must be called before - using any other functions that access the video hardware. - - A macro &s.code;VGAHW_GET_IOBASE()&e.code; is also available in - &s.code;vgaHW.h&e.code; that returns the I/O base, and this may - be used when the vgahw module is not loaded (for example, in the - &s.code;ChipProbe()&e.code; function). - - </quote> - - &s.code;void vgaHWUnlock(vgaHWPtr hwp)&e.code; - <quote><p> - This function unlocks the VGA &s.code;CRTC[0-7]&e.code; registers, - and must be called before attempting to write to those registers. - - </quote> - - &s.code;void vgaHWLock(vgaHWPtr hwp)&e.code; - <quote><p> - This function locks the VGA &s.code;CRTC[0-7]&e.code; registers. - - </quote> - - &s.code;void vgaHWEnable(vgaHWPtr hwp)&e.code; - <quote><p> - This function enables the VGA subsystem. (Note, this function is - present in XFree86 4.1.0 and later.). - - </quote> - - &s.code;void vgaHWDisable(vgaHWPtr hwp)&e.code; - <quote><p> - This function disables the VGA subsystem. (Note, this function is - present in XFree86 4.1.0 and later.). - - </quote> - - &s.code;void vgaHWSave(ScrnInfoPtr pScrn, vgaRegPtr save, int flags)&e.code; - <quote><p> - This function saves the VGA state. The state is written to the - &s.code;vgaRegRec&e.code; pointed to by &s.code;save&e.code;. - &s.code;flags&e.code; is set to one or more of the following flags - ORed together: - - &s.code;VGA_SR_MODE&e.code; - <quote>the mode setting registers are saved</quote> - &s.code;VGA_SR_FONTS&e.code; - <quote>the text mode font/text data is saved</quote> - &s.code;VGA_SR_CMAP&e.code; - <quote>the colourmap (LUT) is saved</quote> - &s.code;VGA_SR_ALL&e.code; - <quote>all of the above are saved</quote> - - The &s.code;vgaHWRec&e.code; and its &s.code;IOBase&e.code; fields - must be initialised before this function is called. If - &s.code;VGA_SR_FONTS&e.code; is set in &s.code;flags&e.code;, the - VGA memory window must be mapped. If it isn't then - &s.code;vgaHWMapMem()&e.code; will be called to map it, and - &s.code;vgaHWUnmapMem()&e.code; will be called to unmap it - afterwards. &s.code;vgaHWSave()&e.code; uses the three functions - below in the order &s.code;vgaHWSaveColormap()&e.code;, - &s.code;vgaHWSaveMode()&e.code;, &s.code;vgaHWSaveFonts()&e.code; to - carry out the different save phases. It is undecided at this - stage whether they will remain part of the vgahw module's public - interface or not. - - </quote> - - &s.code;void vgaHWSaveMode(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code; - <quote><p> - This function saves the VGA mode registers. They are saved to - the &s.code;vgaRegRec&e.code; pointed to by &s.code;save&e.code;. - The registers saved are: - - <quote> - &s.code;MiscOut&nl; - CRTC[0-0x18]&nl; - Attribute[0-0x14]&nl; - Graphics[0-8]&nl; - Sequencer[0-4]&e.code; - </quote> - - The number of registers actually saved may be modified by a prior call - to &s.code;vgaHWSetRegCounts()&e.code;. - - </quote> - - &s.code;void vgaHWSaveFonts(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code; - <quote><p> - This function saves the text mode font and text data held in the - video memory. If called while in a graphics mode, no save is - done. The VGA memory window must be mapped with - &s.code;vgaHWMapMem()&e.code; before to calling this function. - - On some platforms, one or more of the font/text plane saves may be - no-ops. This is the case when the platform's VC driver already - takes care of this. - - </quote> - - &s.code;void vgaHWSaveColormap(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code; - <quote><p> - This function saves the VGA colourmap (LUT). Before saving it, it - attempts to verify that the colourmap is readable. In rare cases - where it isn't readable, a default colourmap is saved instead. - - </quote> - - &s.code;void vgaHWRestore(ScrnInfoPtr pScrn, vgaRegPtr restore, int flags)&e.code; - <quote><p> - This function programs the VGA state. The state programmed is - that contained in the &s.code;vgaRegRec&e.code; pointed to by - &s.code;restore&e.code;. &s.code;flags&e.code; is the same - as described above for the &s.code;vgaHWSave()&e.code; function. - - The &s.code;vgaHWRec&e.code; and its &s.code;IOBase&e.code; fields - must be initialised before this function is called. If - &s.code;VGA_SR_FONTS&e.code; is set in &s.code;flags&e.code;, the - VGA memory window must be mapped. If it isn't then - &s.code;vgaHWMapMem()&e.code; will be called to map it, and - &s.code;vgaHWUnmapMem()&e.code; will be called to unmap it - afterwards. &s.code;vgaHWRestore()&e.code; uses the three functions - below in the order &s.code;vgaHWRestoreFonts()&e.code;, - &s.code;vgaHWRestoreMode()&e.code;, - &s.code;vgaHWRestoreColormap()&e.code; to carry out the different - restore phases. It is undecided at this stage whether they will - remain part of the vgahw module's public interface or not. - - </quote> - - &s.code;void vgaHWRestoreMode(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code; - <quote><p> - This function restores the VGA mode registers. They are restored - from the data in the &s.code;vgaRegRec&e.code; pointed to by - &s.code;restore&e.code;. The registers restored are: - - <quote> - &s.code;MiscOut&nl; - CRTC[0-0x18]&nl; - Attribute[0-0x14]&nl; - Graphics[0-8]&nl; - Sequencer[0-4]&e.code; - </quote> - - The number of registers actually restored may be modified by a prior call - to &s.code;vgaHWSetRegCounts()&e.code;. - - </quote> - - &s.code;void vgaHWRestoreFonts(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code; - <quote><p> - This function restores the text mode font and text data to the - video memory. The VGA memory window must be mapped with - &s.code;vgaHWMapMem()&e.code; before to calling this function. - - On some platforms, one or more of the font/text plane restores - may be no-ops. This is the case when the platform's VC driver - already takes care of this. - - </quote> - - &s.code;void vgaHWRestoreColormap(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code; - <quote><p> - This function restores the VGA colourmap (LUT). - - </quote> - - &s.code;void vgaHWInit(ScrnInfoPtr pScrn, DisplayModePtr mode)&e.code; - <quote><p> - This function fills in the &s.code;vgaHWRec&e.code;'s - &s.code;ModeReg&e.code; field with the values appropriate for - programming the given video mode. It requires that the - &s.code;ScrnInfoRec&e.code;'s &s.code;depth&e.code; field is - initialised, which determines how the registers are programmed. - - </quote> - - &s.code;void vgaHWSeqReset(vgaHWPtr hwp, Bool start)&e.code; - <quote><p> - Do a VGA sequencer reset. If start is &s.code;TRUE&e.code;, the - reset is started. If start is &s.code;FALSE&e.code;, the reset - is ended. - - </quote> - - &s.code;void vgaHWProtect(ScrnInfoPtr pScrn, Bool on)&e.code; - <quote><p> - This function protects VGA registers and memory from corruption - during loads. It is typically called with on set to - &s.code;TRUE&e.code; before programming, and with on set to - &s.code;FALSE&e.code; after programming. - - </quote> - - &s.code;Bool vgaHWSaveScreen(ScreenPtr pScreen, int mode)&e.code; - <quote><p> - This function blanks and unblanks the screen. It is blanked when - &s.code;mode&e.code; is &s.code;SCREEN_SAVER_ON&e.code; or - &s.code;SCREEN_SAVER_CYCLE&e.code;, and unblanked when - &s.code;mode&e.code; is &s.code;SCREEN_SAVER_OFF&e.code; or - &s.code;SCREEN_SAVER_FORCER&e.code;. - - </quote> - - &s.code;void vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)&e.code; - <quote><p> - This function blanks and unblanks the screen. It is blanked when - &s.code;on&e.code; is &s.code;FALSE&e.code;, and unblanked when - &s.code;on&e.code; is &s.code;TRUE&e.code;. This function is - provided for use in cases where the &s.code;ScrnInfoRec&e.code; - can't be derived from the &s.code;ScreenRec&e.code; (while probing - for clocks, for example). - - </quote> - </quote> - -<sect1>VGA Colormap Functions -<p> - - The vgahw module uses the standard colormap support (see the - <ref id="cmap" name="Colormap Handling"> section. This is initialised - with the following function: - - <quote> - &s.code;Bool vgaHWHandleColormaps(ScreenPtr pScreen)&e.code; - </quote> - - -<sect1>VGA Register Access Functions -<p> - - The vgahw module abstracts access to the standard VGA registers by - using a set of functions held in the &s.code;vgaHWRec&e.code;. When - the &s.code;vgaHWRec&e.code; is created these function pointers are - initialised with the set of standard VGA I/O register access functions. - In addition to these, the vgahw module includes a basic set of MMIO - register access functions, and the &s.code;vgaHWRec&e.code; function - pointers can be initialised to these by calling the - &s.code;vgaHWSetMmioFuncs()&e.code; function described above. Some - drivers/platforms may require a different set of functions for VGA - access. The access functions are described here. - - - <quote><p> - &s.code;void writeCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)&e.code; - <quote><p> - Write &s.code;value&e.code; to CRTC register &s.code;index&e.code;. - - </quote> - - &s.code;CARD8 readCrtc(vgaHWPtr hwp, CARD8 index)&e.code; - <quote><p> - Return the value read from CRTC register &s.code;index&e.code;. - - </quote> - - &s.code;void writeGr(vgaHWPtr hwp, CARD8 index, CARD8 value)&e.code; - <quote><p> - Write &s.code;value&e.code; to Graphics Controller register - &s.code;index&e.code;. - - </quote> - - &s.code;CARD8 readGR(vgaHWPtr hwp, CARD8 index)&e.code; - <quote><p> - Return the value read from Graphics Controller register - &s.code;index&e.code;. - - </quote> - - &s.code;void writeSeq(vgaHWPtr hwp, CARD8 index, CARD8, value)&e.code; - <quote><p> - Write &s.code;value&e.code; to Sequencer register - &s.code;index&e.code;. - - </quote> - - &s.code;CARD8 readSeq(vgaHWPtr hwp, CARD8 index)&e.code; - <quote><p> - Return the value read from Sequencer register &s.code;index&e.code;. - - </quote> - - &s.code;void writeAttr(vgaHWPtr hwp, CARD8 index, CARD8, value)&e.code; - <quote><p> - Write &s.code;value&e.code; to Attribute Controller register - &s.code;index&e.code;. When writing out the index value this - function should set bit 5 (&s.code;0x20&e.code;) according to the - setting of &s.code;hwp->paletteEnabled&e.code; in order to - preserve the palette access state. It should be cleared when - &s.code;hwp->paletteEnabled&e.code; is &s.code;TRUE&e.code; - and set when it is &s.code;FALSE&e.code;. - - </quote> - - &s.code;CARD8 readAttr(vgaHWPtr hwp, CARD8 index)&e.code; - <quote><p> - Return the value read from Attribute Controller register - &s.code;index&e.code;. When writing out the index value this - function should set bit 5 (&s.code;0x20&e.code;) according to the - setting of &s.code;hwp->paletteEnabled&e.code; in order to - preserve the palette access state. It should be cleared when - &s.code;hwp->paletteEnabled&e.code; is &s.code;TRUE&e.code; - and set when it is &s.code;FALSE&e.code;. - - </quote> - - &s.code;void writeMiscOut(vgaHWPtr hwp, CARD8 value)&e.code; - <quote><p> - Write `&s.code;value&e.code;' to the Miscellaneous Output register. - - </quote> - - &s.code;CARD8 readMiscOut(vgwHWPtr hwp)&e.code; - <quote><p> - Return the value read from the Miscellaneous Output register. - - </quote> - - &s.code;void enablePalette(vgaHWPtr hwp)&e.code; - <quote><p> - Clear the palette address source bit in the Attribute Controller - index register and set &s.code;hwp->paletteEnabled&e.code; to - &s.code;TRUE&e.code;. - - </quote> - - &s.code;void disablePalette(vgaHWPtr hwp)&e.code; - <quote><p> - Set the palette address source bit in the Attribute Controller - index register and set &s.code;hwp->paletteEnabled&e.code; to - &s.code;FALSE&e.code;. - - </quote> - - &s.code;void writeDacMask(vgaHWPtr hwp, CARD8 value)&e.code; - <quote><p> - Write &s.code;value&e.code; to the DAC Mask register. - - </quote> - - &s.code;CARD8 readDacMask(vgaHWptr hwp)&e.code; - <quote><p> - Return the value read from the DAC Mask register. - - </quote> - - &s.code;void writeDacReadAddress(vgaHWPtr hwp, CARD8 value)&e.code; - <quote><p> - Write &s.code;value&e.code; to the DAC Read Address register. - - </quote> - - &s.code;void writeDacWriteAddress(vgaHWPtr hwp, CARD8 value)&e.code; - <quote><p> - Write &s.code;value&e.code; to the DAC Write Address register. - - </quote> - - &s.code;void writeDacData(vgaHWPtr hwp, CARD8 value)&e.code; - <quote><p> - Write &s.code;value&e.code; to the DAC Data register. - - </quote> - - &s.code;CARD8 readDacData(vgaHWptr hwp)&e.code; - <quote><p> - Return the value read from the DAC Data register. - - </quote> - - &s.code;CARD8 readEnable(vgaHWptr hwp)&e.code; - <quote><p> - Return the value read from the VGA Enable register. (Note: This - function is present in XFree86 4.1.0 and later.) - - </quote> - - &s.code;void writeEnable(vgaHWPtr hwp, CARD8 value)&e.code; - <quote><p> - Write &s.code;value&e.code; to the VGA Enable register. (Note: This - function is present in XFree86 4.1.0 and later.) - - </quote> - </quote> - -<sect>Some notes about writing a driver<label id="sample"> -<p> - -<em>NOTE: some parts of this are not up to date</em> - -The following is an outline for writing a basic unaccelerated driver -for a PCI video card with a linear mapped framebuffer, and which has a -VGA core. It is includes some general information that is relevant to -most drivers (even those which don't fit that basic description). - -The information here is based on the initial conversion of the Matrox -Millennium driver to the ``new design''. For a fleshing out and sample -implementation of some of the bits outlined here, refer to that driver. -Note that this is an example only. The approach used here will not be -appropriate for all drivers. - -Each driver must reserve a unique driver name, and a string that is used -to prefix all of its externally visible symbols. This is to avoid name -space clashes when loading multiple drivers. The examples here are for -the ``ZZZ'' driver, which uses the ``ZZZ'' or ``zzz'' prefix for its externally -visible symbols. - - -<sect1>Include files -<p> - - All drivers normally include the following headers: - <quote> - &s.code;"xf86.h"&nl; - "xf86_OSproc.h"&nl; - "xf86_ansic.h"&nl; - "xf86Resources.h"&e.code; - </quote> - Wherever inb/outb (and related things) are used the following should be - included: - <quote> - &s.code;"compiler.h"&e.code; - </quote> - Note: in drivers, this must be included after &s.code;"xf86_ansic.h"&e.code;. - - Drivers that need to access PCI vendor/device definitions need this: - <quote> - &s.code;"xf86PciInfo.h"&e.code; - </quote> - - Drivers that need to access the PCI config space need this: - <quote> - &s.code;"xf86Pci.h"&e.code; - </quote> - - Drivers using the mi banking wrapper need: - - <quote> - &s.code;"mibank.h"&e.code; - </quote> - - Drivers that initialise a SW cursor need this: - <quote> - &s.code;"mipointer.h"&e.code; - </quote> - - All drivers implementing backing store need this: - <quote> - &s.code;"mibstore.h"&e.code; - </quote> - - All drivers using the mi colourmap code need this: - <quote> - &s.code;"micmap.h"&e.code; - </quote> - - If a driver uses the vgahw module, it needs this: - <quote> - &s.code;"vgaHW.h"&e.code; - </quote> - - Drivers supporting VGA or Hercules monochrome screens need: - <quote> - &s.code;"xf1bpp.h"&e.code; - </quote> - - Drivers supporting VGA or EGC 16-colour screens need: - <quote> - &s.code;"xf4bpp.h"&e.code; - </quote> - - Drivers using cfb need: - <quote> - &s.code;#define PSZ 8&nl; - #include "cfb.h"&nl; - #undef PSZ&e.code; - </quote> - - Drivers supporting bpp 16, 24 or 32 with cfb need one or more of: - <quote> - &s.code;"cfb16.h"&nl; - "cfb24.h"&nl; - "cfb32.h"&e.code; - </quote> - - The driver's own header file: - <quote> - &s.code;"zzz.h"&e.code; - </quote> - - Drivers must NOT include the following: - - <quote> - &s.code;"xf86Priv.h"&nl; - "xf86Privstr.h"&nl; - "xf86_libc.h"&nl; - "xf86_OSlib.h"&nl; - "Xos.h"&e.code;&nl; - any OS header - </quote> - - -<sect1>Data structures and initialisation -<p> - -<itemize> - <item>The following macros should be defined: - <code> -#define VERSION <version-as-an-int> -#define ZZZ_NAME "ZZZ" /* the name used to prefix messages */ -#define ZZZ_DRIVER_NAME "zzz" /* the driver name as used in config file */ -#define ZZZ_MAJOR_VERSION <int> -#define ZZZ_MINOR_VERSION <int> -#define ZZZ_PATCHLEVEL <int> - </code> -<p> - NOTE: &s.code;ZZZ_DRIVER_NAME&e.code; should match the name of the - driver module without things like the "lib" prefix, the "_drv" suffix - or filename extensions. -<p> - - <item>A DriverRec must be defined, which includes the functions required - at the pre-probe phase. The name of this DriverRec must be an - upper-case version of ZZZ_DRIVER_NAME (for the purposes of static - linking). -<p> - <code> -DriverRec ZZZ = { - VERSION, - ZZZ_DRIVER_NAME, - ZZZIdentify, - ZZZProbe, - ZZZAvailableOptions, - NULL, - 0 -}; - </code> - - <item>Define list of supported chips and their matching ID: -<p> - <code> -static SymTabRec ZZZChipsets[] = { - { PCI_CHIP_ZZZ1234, "zzz1234a" }, - { PCI_CHIP_ZZZ5678, "zzz5678a" }, - { -1, NULL } -}; - </code> -<p> - The token field may be any integer value that the driver may use to - uniquely identify the supported chipsets. For drivers that support - only PCI devices using the PCI device IDs might be a natural choice, - but this isn't mandatory. For drivers that support both PCI and other - devices (like ISA), some other ID should probably used. When other - IDs are used as the tokens it is recommended that the names be - defined as an &s.code;enum&e.code; type. -<p> - <item>If the driver uses the &s.code;xf86MatchPciInstances(&e.code;) - helper (recommended for drivers that support PCI cards) a list that - maps PCI IDs to chip IDs and fixed resources must be defined: -<p> - <code> -static PciChipsets ZZZPciChipsets[] = { - { PCI_CHIP_ZZZ1234, PCI_CHIP_ZZZ1234, RES_SHARED_VGA }, - { PCI_CHIP_ZZZ5678, PCI_CHIP_ZZZ5678, RES_SHARED_VGA }, - { -1, -1, RES_UNDEFINED } -} - </code> -<p> - <item>Define the &s.code;XF86ModuleVersionInfo&e.code; struct for the - driver. This is required for the dynamically loaded version: -<p> - <code> -static XF86ModuleVersionInfo zzzVersRec = -{ - "zzz", - MODULEVENDORSTRING, - MODINFOSTRING1, - MODINFOSTRING2, - XF86_VERSION_CURRENT, - ZZZ_MAJOR_VERSION, ZZZ_MINOR_VERSION, ZZZ_PATCHLEVEL, - ABI_CLASS_VIDEODRV, - ABI_VIDEODRV_VERSION, - MOD_CLASS_VIDEODRV, - {0,0,0,0} -}; - </code> -<p> - <item>Define a data structure to hold the driver's screen-specific data. - This must be used instead of global variables. This would be defined - in the &s.code;"zzz.h"&e.code; file, something like: -<p> - <code> -typedef struct { - type1 field1; - type2 field2; - int fooHack; - Bool pciRetry; - Bool noAccel; - Bool hwCursor; - CloseScreenProcPtr CloseScreen; - OptionInfoPtr Options; - ... -} ZZZRec, *ZZZPtr; - </code> -<p> - <item>Define the list of config file Options that the driver accepts. For - consistency between drivers those in the list of ``standard'' options - should be used where appropriate before inventing new options. -<p> - <code> -typedef enum { - OPTION_FOO_HACK, - OPTION_PCI_RETRY, - OPTION_HW_CURSOR, - OPTION_NOACCEL -} ZZZOpts; - -static const OptionInfoRec ZZZOptions[] = { - { OPTION_FOO_HACK, "FooHack", OPTV_INTEGER, {0}, FALSE }, - { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, - { -1, NULL, OPTV_NONE, {0}, FALSE } -}; - </code> -<p> -</itemize> - -<sect1>Functions -<p> - - -<sect2>SetupProc -<p> - - For dynamically loaded modules, a &s.code;ModuleData&e.code; - variable is required. It is should be the name of the driver - prepended to "ModuleData". A &s.code;Setup()&e.code; function is - also required, which calls &s.code;xf86AddDriver()&e.code; to add - the driver to the main list of drivers. - - <code> -static MODULESETUPPROTO(zzzSetup); - -XF86ModuleData zzzModuleData = { &zzzVersRec, zzzSetup, NULL }; - -static pointer -zzzSetup(pointer module, pointer opts, int *errmaj, int *errmin) -{ - static Bool setupDone = FALSE; - - /* This module should be loaded only once, but check to be sure. */ - - if (!setupDone) { - /* - * Modules that this driver always requires may be loaded - * here by calling LoadSubModule(). - */ - - setupDone = TRUE; - xf86AddDriver(&MGA, module, 0); - - /* - * The return value must be non-NULL on success even though - * there is no TearDownProc. - */ - return (pointer)1; - } else { - if (errmaj) *errmaj = LDR_ONCEONLY; - return NULL; - } -} - </code> - -<sect2>GetRec, FreeRec -<p> - - A function is usually required to allocate the driver's - screen-specific data structure and hook it into the - &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field. - The &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; is - initialised to &s.code;NULL&e.code;, so it is easy to check if the - initialisation has already been done. After allocating it, initialise - the fields. By using &s.code;xnfcalloc()&e.code; to do the allocation - it is zeroed, and if the allocation fails the server exits. -<p> - NOTE: - When allocating structures from inside the driver which are defined - on the common level it is important to initialize the structure to - zero. - Only this guarantees that the server remains source compatible to - future changes in common level structures. - - <code> -static Bool -ZZZGetRec(ScrnInfoPtr pScrn) -{ - if (pScrn->driverPrivate != NULL) - return TRUE; - pScrn->driverPrivate = xnfcalloc(sizeof(ZZZRec), 1); - /* Initialise as required */ - ... - return TRUE; -} - </code> - - Define a macro in &s.code;"zzz.h"&e.code; which gets a pointer to - the &s.code;ZZZRec&e.code; when given &s.code;pScrn&e.code;: - - <code> -#define ZZZPTR(p) ((ZZZPtr)((p)->driverPrivate)) - </code> - - Define a function to free the above, setting it to &s.code;NULL&e.code; - once it has been freed: - - <code> -static void -ZZZFreeRec(ScrnInfoPtr pScrn) -{ - if (pScrn->driverPrivate == NULL) - return; - xfree(pScrn->driverPrivate); - pScrn->driverPrivate = NULL; -} - </code> - -<sect2>Identify -<p> - - Define the &s.code;Identify()&e.code; function. It is run before - the Probe, and typically prints out an identifying message, which - might include the chipsets it supports. This function is mandatory: - - <code> -static void -ZZZIdentify(int flags) -{ - xf86PrintChipsets(ZZZ_NAME, "driver for ZZZ Tech chipsets", - ZZZChipsets); -} - </code> - -<sect2>Probe -<p> - - Define the &s.code;Probe()&e.code; function. The purpose of this - is to find all instances of the hardware that the driver supports, - and for the ones not already claimed by another driver, claim the - slot, and allocate a &s.code;ScrnInfoRec&e.code;. This should be - a minimal probe, and it should under no circumstances leave the - state of the hardware changed. Because a device is found, don't - assume that it will be used. Don't do any initialisations other - than the required &s.code;ScrnInfoRec&e.code; initialisations. - Don't allocate any new data structures. - - This function is mandatory. - - NOTE: The &s.code;xf86DrvMsg()&e.code; functions cannot be used from - the Probe. - - <code> -static Bool -ZZZProbe(DriverPtr drv, int flags) -{ - Bool foundScreen = FALSE; - int numDevSections, numUsed; - GDevPtr *devSections; - int *usedChips; - int i; - - /* - * Find the config file Device sections that match this - * driver, and return if there are none. - */ - if ((numDevSections = xf86MatchDevice(ZZZ_DRIVER_NAME, - &devSections)) <= 0) { - return FALSE; - } - - /* - * Since this is a PCI card, "probing" just amounts to checking - * the PCI data that the server has already collected. If there - * is none, return. - * - * Although the config file is allowed to override things, it - * is reasonable to not allow it to override the detection - * of no PCI video cards. - * - * The provided xf86MatchPciInstances() helper takes care of - * the details. - */ - /* test if PCI bus present */ - if (xf86GetPciVideoInfo()) { - - numUsed = xf86MatchPciInstances(ZZZ_NAME, PCI_VENDOR_ZZZ, - ZZZChipsets, ZZZPciChipsets, devSections, - numDevSections, drv, &usedChips); - - for (i = 0; i < numUsed; i++) { - ScrnInfoPtr pScrn = NULL; - if ((pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i], - ZZZPciChipsets, NULL, NULL, - NULL, NULL, NULL))) { - /* Allocate a ScrnInfoRec */ - pScrn->driverVersion = VERSION; - pScrn->driverName = ZZZ_DRIVER_NAME; - pScrn->name = ZZZ_NAME; - pScrn->Probe = ZZZProbe; - pScrn->PreInit = ZZZPreInit; - pScrn->ScreenInit = ZZZScreenInit; - pScrn->SwitchMode = ZZZSwitchMode; - pScrn->AdjustFrame = ZZZAdjustFrame; - pScrn->EnterVT = ZZZEnterVT; - pScrn->LeaveVT = ZZZLeaveVT; - pScrn->FreeScreen = ZZZFreeScreen; - pScrn->ValidMode = ZZZValidMode; - foundScreen = TRUE; - /* add screen to entity */ - } - } - xfree(usedChips); - } - -#ifdef HAS_ISA_DEVS - /* - * If the driver supports ISA hardware, the following block - * can be included too. - */ - numUsed = xf86MatchIsaInstances(ZZZ_NAME, ZZZChipsets, - ZZZIsaChipsets, drv, ZZZFindIsaDevice, - devSections, numDevSections, &usedChips); - for (i = 0; i < numUsed; i++) { - ScrnInfoPtr pScrn = NULL; - if ((pScrn = xf86ConfigIsaEntity(pScrn, flags, usedChips[i], - ZZZIsaChipsets, NULL, NULL, NULL, - NULL, NULL))) { - pScrn->driverVersion = VERSION; - pScrn->driverName = ZZZ_DRIVER_NAME; - pScrn->name = ZZZ_NAME; - pScrn->Probe = ZZZProbe; - pScrn->PreInit = ZZZPreInit; - pScrn->ScreenInit = ZZZScreenInit; - pScrn->SwitchMode = ZZZSwitchMode; - pScrn->AdjustFrame = ZZZAdjustFrame; - pScrn->EnterVT = ZZZEnterVT; - pScrn->LeaveVT = ZZZLeaveVT; - pScrn->FreeScreen = ZZZFreeScreen; - pScrn->ValidMode = ZZZValidMode; - foundScreen = TRUE; - } - } - xfree(usedChips); -#endif /* HAS_ISA_DEVS */ - - xfree(devSections); - return foundScreen; - </code> - -<sect2>AvailableOptions -<p> - - Define the &s.code;AvailableOptions()&e.code; function. The purpose - of this is to return the available driver options back to the - -configure option, so that an xorg.conf file can be built and the - user can see which options are available for them to use. - -<sect2>PreInit -<p> - - Define the &s.code;PreInit()&e.code; function. The purpose of - this is to find all the information required to determine if the - configuration is usable, and to initialise those parts of the - &s.code;ScrnInfoRec&e.code; that can be set once at the beginning - of the first server generation. The information should be found in - the least intrusive way possible. - - This function is mandatory. - - NOTES: - <enum> - <item>The &s.code;PreInit()&e.code; function is only called once - during the life of the X server (at the start of the first - generation). - - <item>Data allocated here must be of the type that persists for - the life of the X server. This means that data that hooks into - the &s.code;ScrnInfoRec&e.code;'s &s.code;privates&e.code; - field should be allocated here, but data that hooks into the - &s.code;ScreenRec&e.code;'s &s.code;devPrivates&e.code; field - should not be allocated here. The &s.code;driverPrivate&e.code; - field should also be allocated here. - - <item>Although the &s.code;ScrnInfoRec&e.code; has been allocated - before this function is called, the &s.code;ScreenRec&e.code; - has not been allocated. That means that things requiring it - cannot be used in this function. - - <item>Very little of the &s.code;ScrnInfoRec&e.code; has been - initialised when this function is called. It is important to - get the order of doing things right in this function. - - </enum> - - <code> -static Bool -ZZZPreInit(ScrnInfoPtr pScrn, int flags) -{ - /* Fill in the monitor field */ - pScrn->monitor = pScrn->confScreen->monitor; - - /* - * If using the vgahw module, it will typically be loaded - * here by calling xf86LoadSubModule(pScrn, "vgahw"); - */ - - /* - * Set the depth/bpp. Use the globally preferred depth/bpp. If the - * driver has special default depth/bpp requirements, the defaults should - * be specified here explicitly. - * We support both 24bpp and 32bpp framebuffer layouts. - * This sets pScrn->display also. - */ - if (!xf86SetDepthBpp(pScrn, 0, 0, 0, - Support24bppFb | Support32bppFb)) { - return FALSE; - } else { - if (depth/bpp isn't one we support) { - print error message; - return FALSE; - } - } - /* Print out the depth/bpp that was set */ - xf86PrintDepthBpp(pScrn); - - /* Set bits per RGB for 8bpp */ - if (pScrn->depth <= 8) { - /* Take into account a dac_6_bit option here */ - pScrn->rgbBits = 6 or 8; - } - - /* - * xf86SetWeight() and xf86SetDefaultVisual() must be called - * after pScrn->display is initialised. - */ - - /* Set weight/mask/offset for depth > 8 */ - if (pScrn->depth > 8) { - if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) { - return FALSE; - } else { - if (weight isn't one we support) { - print error message; - return FALSE; - } - } - } - - /* Set the default visual. */ - if (!xf86SetDefaultVisual(pScrn, -1)) { - return FALSE; - } else { - if (visual isn't one we support) { - print error message; - return FALSE; - } - } - - /* If the driver supports gamma correction, set the gamma. */ - if (!xf86SetGamma(pScrn, default_gamma)) { - return FALSE; - } - - /* This driver uses a programmable clock */ - pScrn->progClock = TRUE; - - /* Allocate the ZZZRec driverPrivate */ - if (!ZZZGetRec(pScrn)) { - return FALSE; - } - - pZzz = ZZZPTR(pScrn); - - /* Collect all of the option flags (fill in pScrn->options) */ - xf86CollectOptions(pScrn, NULL); - - /* - * Process the options based on the information in ZZZOptions. - * The results are written to pZzz->Options. If all of the options - * processing is done within this function a local variable "options" - * can be used instead of pZzz->Options. - */ - if (!(pZzz->Options = xalloc(sizeof(ZZZOptions)))) - return FALSE; - (void)memcpy(pZzz->Options, ZZZOptions, sizeof(ZZZOptions)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pZzz->Options); - - /* - * Set various fields of ScrnInfoRec and/or ZZZRec based on - * the options found. - */ - from = X_DEFAULT; - pZzz->hwCursor = FALSE; - if (xf86IsOptionSet(pZzz->Options, OPTION_HW_CURSOR)) { - from = X_CONFIG; - pZzz->hwCursor = TRUE; - } - xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", - pZzz->hwCursor ? "HW" : "SW"); - if (xf86IsOptionSet(pZzz->Options, OPTION_NOACCEL)) { - pZzz->noAccel = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Acceleration disabled\n"); - } else { - pZzz->noAccel = FALSE; - } - if (xf86IsOptionSet(pZzz->Options, OPTION_PCI_RETRY)) { - pZzz->UsePCIRetry = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n"); - } - pZzz->fooHack = 0; - if (xf86GetOptValInteger(pZzz->Options, OPTION_FOO_HACK, - &pZzz->fooHack)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Foo Hack set to %d\n", - pZzz->fooHack); - } - - /* - * Find the PCI slot(s) that this screen claimed in the probe. - * In this case, exactly one is expected, so complain otherwise. - * Note in this case we're not interested in the card types so - * that parameter is set to NULL. - */ - if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL)) - != 1) { - print error message; - ZZZFreeRec(pScrn); - if (i > 0) - xfree(pciList); - return FALSE; - } - /* Note that pciList should be freed below when no longer needed */ - - /* - * Determine the chipset, allowing config file chipset and - * chipid values to override the probed information. The config - * chipset value has precedence over its chipid value if both - * are present. - * - * It isn't necessary to fill in pScrn->chipset if the driver - * keeps track of the chipset in its ZZZRec. - */ - - ... - - /* - * Determine video memory, fb base address, I/O addresses, etc, - * allowing the config file to override probed values. - * - * Set the appropriate pScrn fields (videoRam is probably the - * most important one that other code might require), and - * print out the settings. - */ - - ... - - /* Initialise a clockRanges list. */ - - ... - - /* Set any other chipset specific things in the ZZZRec */ - - ... - - /* Select valid modes from those available */ - - i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, - pScrn->display->modes, clockRanges, - NULL, minPitch, maxPitch, rounding, - minHeight, maxHeight, - pScrn->display->virtualX, - pScrn->display->virtualY, - pScrn->videoRam * 1024, - LOOKUP_BEST_REFRESH); - if (i == -1) { - ZZZFreeRec(pScrn); - return FALSE; - } - - /* Prune the modes marked as invalid */ - - xf86PruneDriverModes(pScrn); - - /* If no valid modes, return */ - - if (i == 0 || pScrn->modes == NULL) { - print error message; - ZZZFreeRec(pScrn); - return FALSE; - } - - /* - * Initialise the CRTC fields for the modes. This driver expects - * vertical values to be halved for interlaced modes. - */ - xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); - - /* Set the current mode to the first in the list. */ - pScrn->currentMode = pScrn->modes; - - /* Print the list of modes being used. */ - xf86PrintModes(pScrn); - - /* Set the DPI */ - xf86SetDpi(pScrn, 0, 0); - - /* Load bpp-specific modules */ - switch (pScrn->bitsPerPixel) { - case 1: - mod = "xf1bpp"; - break; - case 4: - mod = "xf4bpp"; - break; - case 8: - mod = "cfb"; - break; - case 16: - mod = "cfb16"; - break; - case 24: - mod = "cfb24"; - break; - case 32: - mod = "cfb32"; - break; - } - if (mod && !xf86LoadSubModule(pScrn, mod)) - ZZZFreeRec(pScrn); - return FALSE; - - /* Load XAA if needed */ - if (!pZzz->noAccel || pZzz->hwCursor) - if (!xf86LoadSubModule(pScrn, "xaa")) { - ZZZFreeRec(pScrn); - return FALSE; - } - - /* Done */ - return TRUE; -} - </code> - -<sect2>MapMem, UnmapMem -<p> - - Define functions to map and unmap the video memory and any other - memory apertures required. These functions are not mandatory, but - it is often useful to have such functions. - - <code> -static Bool -ZZZMapMem(ScrnInfoPtr pScrn) -{ - /* Call xf86MapPciMem() to map each PCI memory area */ - ... - return TRUE or FALSE; -} - -static Bool -ZZZUnmapMem(ScrnInfoPtr pScrn) -{ - /* Call xf86UnMapVidMem() to unmap each memory area */ - ... - return TRUE or FALSE; -} - </code> - -<sect2>Save, Restore -<p> - - Define functions to save and restore the original video state. These - functions are not mandatory, but are often useful. - - <code> -static void -ZZZSave(ScrnInfoPtr pScrn) -{ - /* - * Save state into per-screen data structures. - * If using the vgahw module, vgaHWSave will typically be - * called here. - */ - ... -} - -static void -ZZZRestore(ScrnInfoPtr pScrn) -{ - /* - * Restore state from per-screen data structures. - * If using the vgahw module, vgaHWRestore will typically be - * called here. - */ - ... -} - </code> - -<sect2>ModeInit -<p> - - Define a function to initialise a new video mode. This function isn't - mandatory, but is often useful. - - <code> -static Bool -ZZZModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) -{ - /* - * Program a video mode. If using the vgahw module, - * vgaHWInit and vgaRestore will typically be called here. - * Once up to the point where there can't be a failure - * set pScrn->vtSema to TRUE. - */ - ... -} - </code> - -<sect2>ScreenInit -<p> - - Define the &s.code;ScreenInit()&e.code; function. This is called - at the start of each server generation, and should fill in as much - of the &s.code;ScreenRec&e.code; as possible as well as any other - data that is initialised once per generation. It should initialise - the framebuffer layers it is using, and initialise the initial video - mode. - - This function is mandatory. - - NOTE: The &s.code;ScreenRec&e.code; (&s.code;pScreen&e.code;) is - passed to this driver, but it and the - &s.code;ScrnInfoRecs&e.code; are not yet hooked into each - other. This means that in this function, and functions it - calls, one cannot be found from the other. - - <code> -static Bool -ZZZScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) -{ - /* Get the ScrnInfoRec */ - pScrn = xf86Screens[pScreen->myNum]; - - /* - * If using the vgahw module, its data structures and related - * things are typically initialised/mapped here. - */ - - /* Save the current video state */ - ZZZSave(pScrn); - - /* Initialise the first mode */ - ZZZModeInit(pScrn, pScrn->currentMode); - - /* Set the viewport if supported */ - - ZZZAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - - /* - * Setup the screen's visuals, and initialise the framebuffer - * code. - */ - - /* Reset the visual list */ - miClearVisualTypes(); - - /* - * Setup the visuals supported. This driver only supports - * TrueColor for bpp > 8, so the default set of visuals isn't - * acceptable. To deal with this, call miSetVisualTypes with - * the appropriate visual mask. - */ - - if (pScrn->bitsPerPixel > 8) { - if (!miSetVisualTypes(pScrn->depth, TrueColorMask, - pScrn->rgbBits, pScrn->defaultVisual)) - return FALSE; - } else { - if (!miSetVisualTypes(pScrn->depth, - miGetDefaultVisualMask(pScrn->depth), - pScrn->rgbBits, pScrn->defaultVisual)) - return FALSE; - } - - /* - * Initialise the framebuffer. - */ - - switch (pScrn->bitsPerPixel) { - case 1: - ret = xf1bppScreenInit(pScreen, FbBase, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - case 4: - ret = xf4bppScreenInit(pScreen, FbBase, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - case 8: - ret = cfbScreenInit(pScreen, FbBase, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - case 16: - ret = cfb16ScreenInit(pScreen, FbBase, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - case 24: - ret = cfb24ScreenInit(pScreen, FbBase, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - case 32: - ret = cfb32ScreenInit(pScreen, FbBase, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - default: - print a message about an internal error; - ret = FALSE; - break; - } - - if (!ret) - return FALSE; - - /* Override the default mask/offset settings */ - if (pScrn->bitsPerPixel > 8) { - for (i = 0, visual = pScreen->visuals; - i < pScreen->numVisuals; i++, visual++) { - if ((visual->class | DynamicClass) == DirectColor) { - visual->offsetRed = pScrn->offset.red; - visual->offsetGreen = pScrn->offset.green; - visual->offsetBlue = pScrn->offset.blue; - visual->redMask = pScrn->mask.red; - visual->greenMask = pScrn->mask.green; - visual->blueMask = pScrn->mask.blue; - } - } - } - - /* - * If banking is needed, initialise an miBankInfoRec (defined in - * "mibank.h"), and call miInitializeBanking(). - */ - if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY, - pScrn->displayWidth, pBankInfo)) - return FALSE; - - /* - * If backing store is to be supported (as is usually the case), - * initialise it. - */ - miInitializeBackingStore(pScreen); - - /* - * Set initial black & white colourmap indices. - */ - xf86SetBlackWhitePixels(pScreen); - - /* - * Install colourmap functions. If using the vgahw module, - * vgaHandleColormaps would usually be called here. - */ - - ... - - /* - * Initialise cursor functions. This example is for the mi - * software cursor. - */ - miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); - - /* Initialise the default colourmap */ - switch (pScrn->depth) { - case 1: - if (!xf1bppCreateDefColormap(pScreen)) - return FALSE; - break; - case 4: - if (!xf4bppCreateDefColormap(pScreen)) - return FALSE; - break; - default: - if (!cfbCreateDefColormap(pScreen)) - return FALSE; - break; - } - - /* - * Wrap the CloseScreen vector and set SaveScreen. - */ - ZZZPTR(pScrn)->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = ZZZCloseScreen; - pScreen->SaveScreen = ZZZSaveScreen; - - /* Report any unused options (only for the first generation) */ - if (serverGeneration == 1) { - xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); - } - - /* Done */ - return TRUE; -} - </code> - - -<sect2>SwitchMode -<p> - - Define the &s.code;SwitchMode()&e.code; function if mode switching - is supported by the driver. - - <code> -static Bool -ZZZSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) -{ - return ZZZModeInit(xf86Screens[scrnIndex], mode); -} - </code> - - -<sect2>AdjustFrame -<p> - - Define the &s.code;AdjustFrame()&e.code; function if the driver - supports this. - - <code> -static void -ZZZAdjustFrame(int scrnIndex, int x, int y, int flags) -{ - /* Adjust the viewport */ -} - </code> - - -<sect2>EnterVT, LeaveVT -<p> - - Define the &s.code;EnterVT()&e.code; and &s.code;LeaveVT()&e.code; - functions. - - These functions are mandatory. - - <code> -static Bool -ZZZEnterVT(int scrnIndex, int flags) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - return ZZZModeInit(pScrn, pScrn->currentMode); -} - -static void -ZZZLeaveVT(int scrnIndex, int flags) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - ZZZRestore(pScrn); -} - </code> - -<sect2>CloseScreen -<p> - - Define the &s.code;CloseScreen()&e.code; function: - - This function is mandatory. Note that it unwraps the previously - wrapped &s.code;pScreen->CloseScreen&e.code;, and finishes by - calling it. - - <code> -static Bool -ZZZCloseScreen(int scrnIndex, ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - if (pScrn->vtSema) { - ZZZRestore(pScrn); - ZZZUnmapMem(pScrn); - } - pScrn->vtSema = FALSE; - pScreen->CloseScreen = ZZZPTR(pScrn)->CloseScreen; - return (*pScreen->CloseScreen)(scrnIndex, pScreen); -} - </code> - -<sect2>SaveScreen -<p> - - Define the &s.code;SaveScreen()&e.code; function (the screen - blanking function). When using the vgahw module, this will typically - be: - - <code> -static Bool -ZZZSaveScreen(ScreenPtr pScreen, int mode) -{ - return vgaHWSaveScreen(pScreen, mode); -} - </code> - - This function is mandatory. Before modifying any hardware register - directly this function needs to make sure that the Xserver is active - by checking if &s.code;pScrn&e.code; is non-NULL and for - &s.code;pScrn->vtSema == TRUE&e.code;. - -<sect2>FreeScreen -<p> - - Define the &s.code;FreeScreen()&e.code; function. This function - is optional. It should be defined if the &s.code;ScrnInfoRec&e.code; - &s.code;driverPrivate&e.code; field is used so that it can be freed - when a screen is deleted by the common layer for reasons possibly - beyond the driver's control. This function is not used in during - normal (error free) operation. The per-generation data is freed by - the &s.code;CloseScreen()&e.code; function. - - <code> -static void -ZZZFreeScreen(int scrnIndex, int flags) -{ - /* - * If the vgahw module is used vgaHWFreeHWRec() would be called - * here. - */ - ZZZFreeRec(xf86Screens[scrnIndex]); -} - </code> - - -</article> +<!DOCTYPE linuxdoc PUBLIC "-//Xorg//DTD linuxdoc//EN" [
+ <!ENTITY % defs SYSTEM "X11/defs.ent"> %defs;
+ <!-- config file keyword markup -->
+ <!ENTITY s.key STARTTAG "bf">
+ <!ENTITY e.key ENDTAG "bf">
+ <!-- specific config file keywords -->
+ <!ENTITY k.device "&s.key;Device&e.key;">
+ <!ENTITY k.monitor "&s.key;Monitor&e.key;">
+ <!ENTITY k.display "&s.key;Display&e.key;">
+ <!ENTITY k.inputdevice "&s.key;InputDevice&e.key;">
+ <!ENTITY k.screen "&s.key;Screen&e.key;">
+ <!ENTITY k.serverlayout "&s.key;ServerLayout&e.key;">
+ <!ENTITY k.driver "&s.key;Driver&e.key;">
+ <!ENTITY k.module "&s.key;Module&e.key;">
+ <!ENTITY k.identifier "&s.key;Identifier&e.key;">
+ <!ENTITY k.serverflags "&s.key;ServerFlags&e.key;">
+ <!-- command line markup -->
+ <!ENTITY s.cmd STARTTAG "tt">
+ <!ENTITY e.cmd ENDTAG "tt">
+ <!-- inline code markup -->
+ <!ENTITY s.code STARTTAG "tt">
+ <!ENTITY e.code ENDTAG "tt">
+ <!-- function indent -->
+ <!ENTITY f.indent "&nl          ">
+] >
+
+<article>
+
+<title>XFree86 server 4.x Design (DRAFT)
+<author>The XFree86 Project, Inc
+<and>Updates for X11R&relvers; by Jim Gettys
+<date>19 December 2003
+
+
+
+
+
+
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DESIGN.sgml,v 1.53 2003/08/23 14:10:14 dawes Exp $
+</ident>
+
+
+<p>
+<bf>NOTE</bf>: This is a DRAFT document, and the interfaces described here
+are subject to change without notice.
+
+
+<sect>Preface
+<p>
+
+The broad design principles are:
+<itemize>
+ <item>keep it reasonable
+ <itemize>
+ <item>We cannot rewrite the complete server
+ <item>We don't want to re-invent the wheel
+ </itemize>
+ <item>keep it modular
+ <itemize>
+ <item>As many things as possible should go into modules
+ <item>The basic loader binary should be minimal
+ <item>A clean design with well defined layering is important
+ <item>DDX specific global variables are a nono
+ <item>The structure should be flexible enough to allow
+ future extensions
+ <item> The structure should minimize duplication of common code
+ </itemize>
+ <item>keep important features in mind
+ <itemize>
+ <item>multiple screens, including multiple instances of drivers
+ <item>mixing different color depths and visuals on different
+ and ideally even on the same screen
+ <item>better control of the PCI device used
+ <item>better config file parser
+ <item>get rid of all VGA compatibility assumptions
+ </itemize>
+</itemize>
+
+Unless we find major deficiencies in the DIX layer, we should avoid
+making changes there.
+
+<sect>The xorg.conf File
+<p>
+
+The xorg.conf file format is similar to the old format, with the following
+changes:
+
+<sect1>&k.device; section
+<p>
+
+ The &k.device; sections are similar to what they used to be, and
+ describe hardware-specific information for a single video card.
+ &k.device;
+ Some new keywords are added:
+
+
+ <descrip>
+ <tag>Driver "drivername"</tag>
+ Specifies the name of the driver to be used for the card. This
+ is mandatory.
+ <tag>BusID "busslot"</tag>
+ Specifies uniquely the location of the card on the bus. The
+ purpose is to identify particular cards in a multi-headed
+ configuration. The format of the argument is intentionally
+ vague, and may be architecture dependent. For a PCI bus, it
+ is something like "bus:slot:func".
+ </descrip>
+
+ A &k.device; section is considered ``active'' if there is a reference
+ to it in an active &k.screen; section.
+
+<sect1>&k.screen; section
+<p>
+
+ The &k.screen; sections are similar to what they used to be. They
+ no longer have a &k.driver; keyword, but an &k.identifier; keyword
+ is added. (The &k.driver; keyword may be accepted in place of the
+ &k.identifier; keyword for compatibility purposes.) The identifier
+ can be used to identify which screen is to be active when multiple
+ &k.screen sections are present. It is possible to specify the active
+ screen from the command line. A default is chosen in the absence
+ of one being specified. A &k.screen; section is considered ``active''
+ if there is a reference to it either from the command line, or from
+ an active &k.serverlayout; section.
+
+<sect1>&k.inputdevice; section
+<p>
+
+ The &k.inputdevice; section is a new section that describes
+ configuration information for input devices. It replaces the old
+ &s.key;Keyboard&e.key;, &s.key;Pointer&e.key; and &s.key;XInput&e.key;
+ sections. Like the &k.device; section, it has two mandatory keywords:
+ &k.identifier; and &k.driver;. For compatibility purposes the old
+ &s.key;Keyboard&e.key; and &s.key;Pointer&e.key; sections are
+ converted by the parser into &k.inputdevice; sections as follows:
+
+ <descrip>
+ <tag>&s.key;Keyboard&e.key;</tag>
+ &k.identifier; "Implicit Core Keyboard"<newline>
+ &k.driver; "keyboard"
+ <tag>&s.key;Pointer&e.key;</tag>
+ &k.identifier; "Implicit Core Pointer"<newline>
+ &k.driver; "mouse"
+ </descrip>
+
+ An &k.inputdevice; section is considered active if there is a
+ reference to it in an active &k.serverlayout; section. An
+ &k.inputdevice; section may also be referenced implicitly if there
+ is no &k.serverlayout; section, if the &s.cmd;-screen&e.cmd; command
+ line options is used, or if the &k.serverlayout; section doesn't
+ reference any &k.inputdevice; sections. In this case, the first
+ sections with drivers "keyboard" and "mouse" are used as the core
+ keyboard and pointer respectively.
+
+<sect1>&k.serverlayout; section
+<p>
+
+ The &k.serverlayout; section is a new section that is used to identify
+ which &k.screen; sections are to be used in a multi-headed configuration,
+ and the relative layout of those screens. It also identifies which
+ &k.inputdevice; sections are to be used. Each &k.serverlayout section
+ has an identifier, a list of &k.screen; section identifiers, and a list of
+ &k.inputdevice; section identifiers. &k.serverflags; options may also be
+ included in a &k.serverlayout; section, making it possible to override
+ the global values in the &k.serverflags; section.
+
+ A &k.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).
+ When no screen number is specified, they are numbered according to
+ the order in which they are listed. The old (now obsolete) method
+ of providing the positioning information is to give the names of
+ the four adjacent screens. The order of these is top, bottom, left,
+ right. Here is an example of a &k.serverlayout; section for two
+ screens using the old method, with the second located to the right
+ of the first:
+
+ <code>
+ Section "ServerLayout"
+ Identifier "Main Layout"
+ Screen 0 "Screen 1" "" "" "" "Screen 2"
+ Screen 1 "Screen 2"
+ Screen "Screen 3"
+ EndSection
+ </code>
+
+ The preferred way of specifying the layout is to explicitly specify
+ the screen's location in absolute terms or relative to another
+ screen.
+
+ In the absolute case, the upper left corner's coordinates are given
+ after the &s.key;Absolute&e.key; keyword. If the coordinates are
+ omitted, a value of &s.code;(0,0)&e.code; is assumed. An example
+ of absolute positioning follows:
+
+ <code>
+ Section "ServerLayout"
+ Identifier "Main Layout"
+ Screen 0 "Screen 1" Absolute 0 0
+ Screen 1 "Screen 2" Absolute 1024 0
+ Screen "Screen 3" Absolute 2048 0
+ EndSection
+ </code>
+
+ In the relative case, the position is specified by either using one of
+ the following keywords followed by the name of the reference screen:
+
+ <quote>
+ &s.key;RightOf&nl;
+ LeftOf&nl;
+ Above&nl;
+ Below&nl;
+ Relative&e.key;
+ </quote>
+
+ When the &s.key;Relative&e.key; keyword is used, the reference screen
+ name is followed by the coordinates of the new screen's origin
+ relative to reference screen. The following example shows how to use
+ some of the relative positioning options.
+
+ <code>
+ Section "ServerLayout"
+ Identifier "Main Layout"
+ Screen 0 "Screen 1"
+ Screen 1 "Screen 2" RightOf "Screen 1"
+ Screen "Screen 3" Relative "Screen 1" 2048 0
+ EndSection
+ </code>
+
+<sect1>Options
+<p>
+
+ Options are used more extensively. They may appear in most sections
+ now. Options related to drivers can be present in the &k.screen;,
+ &k.device; and &k.monitor; sections and the &k.display; subsections.
+ The order of precedence is &k.display;, &k.screen;, &k.monitor;,
+ &k.device;. Options have been extended to allow an optional value
+ to be specified in addition to the option name. For more details
+ about options, see the <ref id="options" name="Options"> section
+ for details.
+
+<sect>Driver Interface
+<p>
+
+The driver interface consists of a minimal set of entry points that are
+required based on the external events that the driver must react to.
+No non-essential structure is imposed on the way they are used beyond
+that. This is a significant difference compared with the old design.
+
+The entry points for drawing operations are already taken care of by
+the framebuffer code (including, XAA). Extensions and enhancements to
+framebuffer code are outside the scope of this document.
+
+This approach to the driver interface provides good flexibility, but does
+increase the complexity of drivers. To help address this, the XFree86
+common layer provides a set of ``helper'' functions to take care of things
+that most drivers need. These helpers help minimise the amount of code
+duplication between drivers. The use of helper functions by drivers is
+however optional, though encouraged. The basic philosophy behind the
+helper functions is that they should be useful to many drivers, that
+they should balance this against the complexity of their interface. It
+is inevitable that some drivers may find some helpers unsuitable and
+need to provide their own code.
+
+Events that a driver needs to react to are:
+
+ <descrip>
+ <tag>ScreenInit</tag>
+
+ An initialisation function is called from the DIX layer for each
+ screen at the start of each server generation.
+
+ <tag>Enter VT</tag>
+
+ The server takes control of the console.
+
+ <tag>Leave VT</tag>
+
+ The server releases control of the console.
+
+ <tag>Mode Switch</tag>
+
+ Change video mode.
+
+ <tag>ViewPort change</tag>
+
+ Change the origin of the physical view port.
+
+ <tag>ScreenSaver state change</tag>
+
+ Screen saver activation/deactivation.
+
+ <tag>CloseScreen</tag>
+
+ A close screen function is called from the DIX layer for each screen
+ at the end of each server generation.
+ </descrip>
+
+
+In addition to these events, the following functions are required by
+the XFree86 common layer:
+
+ <descrip>
+ <tag>Identify</tag>
+
+ Print a driver identifying message.
+
+ <tag>Probe</tag>
+
+ This is how a driver identifies if there is any hardware present that
+ it knows how to drive.
+
+ <tag>PreInit</tag>
+
+ Process information from the xorg.conf file, determine the
+ full characteristics of the hardware, and determine if a valid
+ configuration is present.
+ </descrip>
+
+The VidMode extension also requires:
+
+ <descrip>
+ <tag>ValidMode</tag>
+
+ Identify if a new mode is usable with the current configuration.
+ The PreInit function (and/or helpers it calls) may also make use
+ of the ValidMode function or something similar.
+ </descrip>
+
+
+Other extensions may require other entry points. The drivers will
+inform the common layer of these in such cases.
+
+<sect>Resource Access Control Introduction
+<p>
+
+Graphics devices are accessed through ranges in I/O or memory space.
+While most modern graphics devices allow relocation of such ranges many
+of them still require the use of well established interfaces such as
+VGA memory and IO ranges or 8514/A IO ranges. With modern buses (like
+PCI) it is possible for multiple video devices to share access to these
+resources. The RAC (Resource Access Control) subsystem provides a
+mechanism for this.
+
+<sect1>Terms and Definitions
+<p>
+
+<sect2>Bus
+<p>
+
+ ``Bus'' is ambiguous as it is used for different things: it may refer
+ to physical incompatible extension connectors in a computer system.
+ The RAC system knows two such systems: The ISA bus and the PCI bus.
+ (On the software level EISA, MCA and VL buses are currently treated
+ like ISA buses). ``Bus'' may also refer to logically different
+ entities on a single bus system which are connected via bridges. A
+ PCI system may have several distinct PCI buses connecting each other
+ by PCI-PCI bridges or to the host CPU by HOST-PCI bridges.
+
+ Systems that host more than one bus system link these together using
+ bridges. Bridges are a concern to RAC as they might block or pass
+ specific resources. PCI-PCI bridges may be set up to pass VGA
+ resources to the secondary bus. PCI-ISA buses pass any resources not
+ decoded on the primary PCI bus to the ISA bus. This way VGA resources
+ (although exclusive on the ISA bus) can be shared by ISA and PCI
+ cards. Currently HOST-PCI bridges are not yet handled by RAC as they
+ require specific drivers.
+
+<sect2>Entity
+<p>
+
+ The smallest independently addressable unit on a system bus is
+ referred to as an entity. So far we know ISA and PCI entities. PCI
+ entities can be located on the PCI bus by an unique ID consisting of
+ the bus, card and function number.
+
+<sect2>Resource
+<p>
+
+ ``Resource'' refers to a range of memory or I/O addresses an entity
+ can decode.
+
+ If a device is capable of disabling this decoding the resource is
+ called sharable. For PCI devices a generic method is provided to
+ control resource decoding. Other devices will have to provide a
+ device specific function to control decoding.
+
+ If the entity is capable of decoding this range at a different
+ location this resource is considered relocatable.
+
+ Resources which start at a specific address and occupy a single
+ continuous range are called block resources.
+
+ Alternatively resource addresses can be decoded in a way that they
+ satisfy the conditions:
+ <quote><verb>
+ address & mask == base
+ </verb></quote>
+ and
+ <quote><verb>
+ base & mask == base
+ </verb></quote>
+ Resources addressed in such a way are called sparse resources.
+
+<sect2>Server States
+<p>
+
+ The resource access control system knows two server states: the
+ SETUP and the OPERATING state. The SETUP state is entered whenever
+ a mode change takes place or the server exits or does VT switching.
+ During this state all entity resources are under resource access
+ control. During OPERATING state only those entities are controlled
+ which actually have shared resources that conflict with others.
+
+<sect>Control Flow in the Server and Mandatory Driver Functions
+<p>
+
+At the start of each server generation, &s.code;main()&e.code;
+(&s.code;dix/main.c&e.code;) calls the DDX function
+&s.code;InitOutput()&e.code;. This is the first place that the DDX gets
+control. &s.code;InitOutput()&e.code; is expected to fill in the global
+&s.code;screenInfo&e.code; struct, and one
+&s.code;screenInfo.screen[]&e.code; entry for each screen present. Here
+is what &s.code;InitOutput()&e.code; does:
+
+<sect1>Parse the xorg.conf file
+<p>
+
+ This is done at the start of the first server generation only.
+
+ The xorg.conf file is read in full, and the resulting information
+ stored in data structures. None of the parsed information is
+ processed at this point. The parser data structures are opaque to
+ the video drivers and to most of the common layer code.
+
+ The entire file is parsed first to remove any section ordering
+ requirements.
+
+
+<sect1>Initial processing of parsed information and command line options
+<p>
+
+ This is done at the start of the first server generation only.
+
+ The initial processing is to determine paths like the
+ &s.key;ModulePath&e.key;, etc, and to determine which &k.serverlayout;,
+ &k.screen; and &k.device; sections are active.
+
+
+<sect1>Enable port I/O access
+<p>
+
+ Port I/O access is controlled from the XFree86 common layer, and is
+ ``all or nothing''. It is enabled prior to calling driver probes, at
+ the start of subsequent server generations, and when VT switching
+ back to the Xserver. It is disabled at the end of server generations,
+ and when VT switching away from the Xserver.
+
+ The implementation details of this may vary on different platforms.
+
+
+<sect1>General bus probe
+<p>
+
+ This is done at the start of the first server generation only.
+
+ In the case of ix86 machines, this will be a general PCI probe.
+ The full information obtained here will be available to the drivers.
+ This information persists for the life of the Xserver. In the PCI
+ case, the PCI information for all video cards found is available by
+ calling &s.code;xf86GetPciVideoInfo()&e.code;.
+
+ <quote>
+ &s.code;pciVideoPtr *xf86GetPciVideoInfo(void)&e.code;
+ <quote><p>
+ returns a pointer to a list of pointers to
+ &s.code;pciVideoRec&e.code; entries, of which there is one for
+ each detected PCI video card. The list is terminated with a
+ &s.code;NULL&e.code; pointer. If no PCI video cards were
+ detected, the return value is &s.code;NULL&e.code;.
+
+ </quote>
+ </quote>
+
+ After the bus probe, the resource broker is initialised.
+
+
+<sect1>Load initial set of modules
+<p>
+
+ This is done at the start of the first server generation only.
+
+ The core server contains a list of mandatory modules. These are loaded
+ first. Currently the only module on this list is the bitmap font module.
+
+ The next set of modules loaded are those specified explicitly in the
+ &k.module; section of the config file.
+
+ The final set of initial modules are the driver modules referenced
+ by the active &k.device; and &k.inputdevice; sections in the config
+ file. Each of these modules is loaded exactly once.
+
+
+<sect1>Register Video and Input Drivers
+<p>
+
+ This is done at the start of the first server generation only.
+
+ When a driver module is loaded, the loader calls its
+ &s.code;Setup&e.code; function. For video drivers, this function
+ calls &s.code;xf86AddDriver()&e.code; to register the driver's
+ &s.code;DriverRec&e.code;, which contains a small set of essential
+ details and driver entry points required during the early phase of
+ &s.code;InitOutput()&e.code;. &s.code;xf86AddDriver()&e.code; adds
+ it to the global &s.code;xf86DriverList[]&e.code; array.
+
+ The &s.code;DriverRec&e.code; contains the driver canonical name,
+ the &s.code;Identify()&e.code;,
+ &s.code;Probe()&e.code; and &s.code;AvailableOptions()&e.code;
+ 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 reference 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
+ &s.code;ScrnInfoRec&e.code;.
+
+ For a static server, the &s.code;xf86DriverList[]&e.code; 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
+ &s.code;Setup&e.code; function calls
+ &s.code;xf86AddInputDriver()&e.code; to register the driver's
+ &s.code;InputDriverRec&e.code;, which contains a small set of
+ essential details and driver entry points required during the early
+ phase of &s.code;InitInput()&e.code;.
+ &s.code;xf86AddInputDriver()&e.code; adds it to the global
+ &s.code;xf86InputDriverList[]&e.code; array. For a static server,
+ the &s.code;xf86InputDriverList[]&e.code; array is initialised at
+ build time.
+
+ Both the &s.code;xf86DriverList[]&e.code; and
+ &s.code;xf86InputDriverList[]&e.code; arrays have been initialised
+ by the end of this stage.
+
+ Once all the drivers are registered, their
+ &s.code;ChipIdentify()&e.code; functions are called.
+
+ <quote>
+ &s.code;void ChipIdentify(int flags)&e.code;
+ <quote>
+ This is expected to print a message indicating the driver name,
+ a short summary of what it supports, and a list of the chipset
+ names that it supports. It may use the xf86PrintChipsets() helper
+ to do this.
+ </quote>
+ </quote>
+
+ <quote>
+ &s.code;void xf86PrintChipsets(const char *drvname, const char *drvmsg,
+ &f.indent;SymTabPtr chips)&e.code;
+ <quote>
+ This function provides an easy way for a driver's ChipIdentify
+ function to format the identification message.
+ </quote>
+ </quote>
+
+<sect1>Initialise Access Control
+<p>
+
+ This is done at the start of the first server generation only.
+
+ The Resource Access Control (RAC) subsystem is initialised before
+ calling any driver functions that may access hardware. All generic
+ bus information is probed and saved (for restoration later). All
+ (shared resource) video devices are disabled at the generic bus
+ level, and a probe is done to find the ``primary'' video device. These
+ devices remain disabled for the next step.
+
+
+<sect1>Video Driver Probe<label id="probe">
+<p>
+ This is done at the start of the first server generation only. The
+ &s.code;ChipProbe()&e.code; function of each registered video driver
+ is called.
+
+ <quote><p>
+ &s.code;Bool ChipProbe(DriverPtr drv, int flags)&e.code;
+ <quote><p>
+ The purpose of this is to identify all instances of hardware
+ supported by the driver. The flags value is currently either 0,
+ &s.code;PROBE_DEFAULT&e.code; or &s.code;PROBE_DETECT&e.code;.
+ &s.code;PROBE_DETECT&e.code; is used if "-configure" or "-probe"
+ command line arguments are given and indicates to the
+ &s.code;Probe()&e.code; function that it should not configure the
+ bus entities and that no xorg.conf information is available.
+
+ The probe must find the active device sections that match the
+ driver by calling &s.code;xf86MatchDevice()&e.code;. The number
+ of matches found limits the maximum number of instances for this
+ driver. If no matches are found, the function should return
+ &s.code;FALSE&e.code; immediately.
+
+ Devices that cannot be identified by using device-independent
+ methods should be probed at this stage (keeping in mind that access
+ to all resources that can be disabled in a device-independent way
+ are disabled during this phase). The probe must be a minimal
+ probe. It should just determine if there is a card present that
+ the driver can drive. It should use the least intrusive probe
+ methods possible. It must not do anything that is not essential,
+ like probing for other details such as the amount of memory
+ installed, etc. It is recommended that the
+ &s.code;xf86MatchPciInstances()&e.code; helper function be used
+ for identifying matching PCI devices, and similarly the
+ &s.code;xf86MatchIsaInstances()&e.code; for ISA (non-PCI) devices
+ (see the <ref id="rac" name="RAC"> section). These helpers also
+ checks and claims the appropriate entity. When not using the
+ helper, that should be done with &s.code;xf86CheckPciSlot()&e.code;
+ and &s.code;xf86ClaimPciSlot()&e.code; for PCI devices and
+ &s.code;xf86ClaimIsaSlot()&e.code; for ISA devices (see the
+ <ref id="rac" name="RAC"> section).
+
+ The probe must register all non-relocatable resources at this
+ stage. If a resource conflict is found between exclusive resources
+ the driver will fail immediately. This is usually best done with
+ the &s.code;xf86ConfigPciEntity()&e.code; helper function
+ for PCI and &s.code;xf86ConfigIsaEntity()&e.code; for ISA
+ (see the <ref id="rac" name="RAC"> section). It is possible to
+ register some entity specific functions with those helpers. When
+ not using the helpers, the &s.code;xf86AddEntityToScreen()&e.code;
+ &s.code;xf86ClaimFixedResources()&e.code; and
+ &s.code;xf86SetEntityFuncs()&e.code; should be used instead (see
+ the <ref id="rac" name="RAC"> section).
+
+ If a chipset is specified in an active device section which the
+ driver considers relevant (ie it has no driver specified, or the
+ driver specified matches the driver doing the probe), the Probe
+ must return &s.code;FALSE&e.code; if the chipset doesn't match
+ one supported by the driver.
+
+ If there are no active device sections that the driver considers
+ relevant, it must return &s.code;FALSE&e.code;.
+
+ Allocate a &s.code;ScrnInfoRec&e.code; for each active instance of the
+ hardware found, and fill in the basic information, including the
+ other driver entry points. This is best done with the
+ &s.code;xf86ConfigIsaEntity()&e.code; helper function for ISA
+ instances or &s.code;xf86ConfigPciEntity()&e.code; for PCI instances.
+ These functions allocate a &s.code;ScrnInfoRec&e.code; for active
+ entities. Optionally &s.code;xf86AllocateScreen()&e.code;
+ function may also be used to allocate the &s.code;ScrnInfoRec&e.code;.
+ Any of these functions take care of initialising fields to defined
+ ``unused'' values.
+
+ Claim the entities for each instance of the hardware found. This
+ prevents other drivers from claiming the same hardware.
+
+ Must leave hardware in the same state it found it in, and must not
+ do any hardware initialisation.
+
+ All detection can be overridden via the config file, and that
+ parsed information is available to the driver at this stage.
+
+ Returns &s.code;TRUE&e.code; if one or more instances are found,
+ and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;int xf86MatchDevice(const char *drivername,
+ &f.indent;GDevPtr **driversectlist)&e.code;
+ <quote><p>
+
+ This function takes the name of the driver and returns via
+ &s.code;driversectlist&e.code; a list of device sections that
+ match the driver name. The function return value is the number
+ of matches found. If a fatal error is encountered the return
+ value is &s.code;-1&e.code;.
+
+ The caller should use &s.code;xfree()&e.code; to free
+ &s.code;*driversectlist&e.code; when it is no longer needed.
+
+ </quote>
+
+ &s.code;ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags)&e.code;
+ <quote><p>
+ This function allocates a new &s.code;ScrnInfoRec&e.code; in the
+ &s.code;xf86Screens[]&e.code; array. This function is normally
+ called by the video driver &s.code;ChipProbe()&e.code; functions.
+ The return value is a pointer to the newly allocated
+ &s.code;ScrnInfoRec&e.code;. The &s.code;scrnIndex&e.code;,
+ &s.code;origIndex&e.code;, &s.code;module&e.code; and
+ &s.code;drv&e.code; fields are initialised. The reference count
+ in &s.code;drv&e.code; is incremented. The storage for any
+ currently allocated ``privates'' pointers is also allocated and
+ the &s.code;privates&e.code; field initialised (the privates data
+ is of course not allocated or initialised). This function never
+ returns on failure. If the allocation fails, the server exits
+ with a fatal error. The flags value is not currently used, and
+ should be set to zero.
+ </quote>
+ </quote>
+
+ At the completion of this, a list of &s.code;ScrnInfoRecs&e.code;
+ have been allocated in the &s.code;xf86Screens[]&e.code; array, and
+ the associated entities and fixed resources have been claimed. The
+ following &s.code;ScrnInfoRec&e.code; fields must be initialised at
+ this point:
+
+ <quote><verb>
+ driverVersion
+ driverName
+ scrnIndex(*)
+ origIndex(*)
+ drv(*)
+ module(*)
+ name
+ Probe
+ PreInit
+ ScreenInit
+ EnterVT
+ LeaveVT
+ numEntities
+ entityList
+ access
+ </verb></quote>
+
+ <tt>(*)</tt> These are initialised when the &s.code;ScrnInfoRec&e.code;
+ is allocated, and not explicitly by the driver.
+
+ The following &s.code;ScrnInfoRec&e.code; fields must be initialised
+ if the driver is going to use them:
+
+ <quote><verb>
+ SwitchMode
+ AdjustFrame
+ FreeScreen
+ ValidMode
+ </verb></quote>
+
+<sect1>Matching Screens
+<p>
+
+ This is done at the start of the first server generation only.
+
+ After the Probe phase is finished, there will be some number of
+ &s.code;ScrnInfoRecs&e.code;. These are then matched with the active
+ &k.screen; sections in the xorg.conf, and those not having an active
+ &k.screen; section are deleted. If the number of remaining screens
+ is 0, &s.code;InitOutput()&e.code; sets
+ &s.code;screenInfo.numScreens&e.code; to &s.code;0&e.code; and
+ returns.
+
+ At this point the following fields of the &s.code;ScrnInfoRecs&e.code;
+ must be initialised:
+
+ <quote><verb>
+ confScreen
+ </verb></quote>
+
+
+<sect1>Allocate non-conflicting resources
+<p>
+
+ This is done at the start of the first server generation only.
+
+ Before calling the drivers again, the resource information collected
+ from the Probe phase is processed. This includes checking the extent
+ of PCI resources for the probed devices, and resolving any conflicts
+ in the relocatable PCI resources. It also reports conflicts, checks
+ bus routing issues, and anything else that is needed to enable the
+ entities for the next phase.
+
+ If any drivers registered an &s.code;EntityInit()&e.code; function
+ during the Probe phase, then they are called here.
+
+
+<sect1>Sort the Screens and pre-check Monitor Information
+<p>
+
+ This is done at the start of the first server generation only.
+
+ The list of screens is sorted to match the ordering requested in the
+ config file.
+
+ The list of modes for each active monitor is checked against the
+ monitor's parameters. Invalid modes are pruned.
+
+
+<sect1>PreInit
+<p>
+
+ This is done at the start of the first server generation only.
+
+ For each &s.code;ScrnInfoRec&e.code;, enable access to the screens entities and call
+ the &s.code;ChipPreInit()&e.code; function.
+
+ <quote><p>
+ &s.code;Bool ChipPreInit(ScrnInfoRec screen, int flags)&e.code;
+ <quote><p>
+ The purpose of this function is to find out all the information
+ required to determine if the configuration is usable, and to
+ initialise those parts of the &s.code;ScrnInfoRec&e.code; that
+ can be set once at the beginning of the first server generation.
+
+ The number of entities registered for the screen should be checked
+ against the expected number (most drivers expect only one). The
+ entity information for each of them should be retrieved (with
+ &s.code;xf86GetEntityInfo()&e.code;) and checked for the correct
+ bus type and that none of the sharable resources registered during
+ the Probe phase was rejected.
+
+ Access to resources for the entities that can be controlled in a
+ device-independent way are enabled before this function is called.
+ If the driver needs to access any resources that it has disabled
+ in an &s.code;EntityInit()&e.code; function that it registered,
+ then it may enable them here providing that it disables them before
+ this function returns.
+
+ This includes probing for video memory, clocks, ramdac, and all
+ other HW info that is needed. It includes determining the
+ depth/bpp/visual and related info. It includes validating and
+ determining the set of video modes that will be used (and anything
+ that is required to determine that).
+
+ This information should be determined in the least intrusive way
+ possible. The state of the HW must remain unchanged by this
+ function. Although video memory (including MMIO) may be mapped
+ within this function, it must be unmapped before returning. Driver
+ specific information should be stored in a structure hooked into
+ the &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code;
+ field. Any other modules which require persistent data (ie data
+ that persists across server generations) should be initialised in
+ this function, and they should allocate a ``privates'' index to
+ hook their data into by calling
+ &s.code;xf86AllocateScrnInfoPrivateIndex().&e.code; The ``privates''
+ data is persistent.
+
+ Helper functions for some of these things are provided at the
+ XFree86 common level, and the driver can choose to make use of
+ them.
+
+ All additional resources that the screen needs must be registered
+ here. This should be done with
+ &s.code;xf86RegisterResources()&e.code;. If some of the fixed
+ resources registered in the Probe phase are not needed or not
+ decoded by the hardware when in the OPERATING server state, their
+ status should be updated with
+ &s.code;xf86SetOperatingState()&e.code;.
+
+ Modules may be loaded at any point in this function, and all
+ modules that the driver will need must be loaded before the end
+ of this function. Either the &s.code;xf86LoadSubModule()&e.code;
+ or the &s.code;xf86LoadDrvSubModule()&e.code; function should be
+ used to load modules depending on whether a
+ &s.code;ScrnInfoRec&e.code; has been set up. A driver may unload
+ a module within this function if it was only needed temporarily,
+ and the &s.code;xf86UnloadSubModule()&e.code; function should be used
+ to do that. Otherwise there is no need to explicitly unload modules
+ because the loader takes care of module dependencies and will
+ unload submodules automatically if/when the driver module is
+ unloaded.
+
+ The bulk of the &s.code;ScrnInfoRec&e.code; fields should be filled
+ out in this function.
+
+ &s.code;ChipPreInit()&e.code; returns &s.code;FALSE&e.code; when
+ the configuration is unusable in some way (unsupported depth, no
+ valid modes, not enough video memory, etc), and &s.code;TRUE&e.code;
+ if it is usable.
+
+ It is expected that if the &s.code;ChipPreInit()&e.code; function
+ returns &s.code;TRUE&e.code;, then the only reasons that subsequent
+ stages in the driver might fail are lack or resources (like xalloc
+ failures). All other possible reasons for failure should be
+ determined by the &s.code;ChipPreInit()&e.code; function.
+
+ </quote>
+ </quote>
+
+ The &s.code;ScrnInfoRecs&e.code; for screens where the &s.code;ChipPreInit()&e.code; fails are removed.
+ If none remain, &s.code;InitOutput()&e.code; sets &s.code;screenInfo.numScreens&e.code; to &s.code;0&e.code; and returns.
+
+ At this point, further fields of the &s.code;ScrnInfoRecs&e.code; would normally be
+ filled in. Most are not strictly mandatory, but many are required
+ by other layers and/or helper functions that the driver may choose
+ to use. The documentation for those layers and helper functions
+ indicates which they require.
+
+ The following fields of the &s.code;ScrnInfoRecs&e.code; should be filled in if the
+ driver is going to use them:
+
+ <quote><verb>
+ monitor
+ display
+ depth
+ pixmapBPP
+ bitsPerPixel
+ weight (>8bpp only)
+ mask (>8bpp only)
+ offset (>8bpp only)
+ rgbBits (8bpp only)
+ gamma
+ defaultVisual
+ maxHValue
+ maxVValue
+ virtualX
+ virtualY
+ displayWidth
+ frameX0
+ frameY0
+ frameX1
+ frameY1
+ zoomLocked
+ modePool
+ modes
+ currentMode
+ progClock (TRUE if clock is programmable)
+ chipset
+ ramdac
+ clockchip
+ numClocks (if not programmable)
+ clock[] (if not programmable)
+ videoRam
+ biosBase
+ memBase
+ memClk
+ driverPrivate
+ chipID
+ chipRev
+ </verb></quote>
+
+ <quote><p>
+ &s.code;pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)&e.code:
+ and
+ &s.code;pointer xf86LoadDrvSubModule(DriverPtr drv, const char *name)&e.code:
+ <quote><p>
+ Load a module that a driver depends on. This function loads the
+ module &s.code;name&e.code; as a sub module of the driver. The
+ return value is a handle identifying the new module. If the load
+ fails, the return value will be &s.code;NULL&e.code;. If a driver
+ needs to explicitly unload a module it has loaded in this way,
+ the return value must be saved and passed to
+ &s.code;xf86UnloadSubModule()&e.code; when unloading.
+
+ </quote>
+
+ &s.code;void xf86UnloadSubModule(pointer module)&e.code;
+ <quote><p>
+ Unloads the module referenced by &s.code;module&e.code;.
+ &s.code;module&e.code; should be a pointer returned previously
+ by &s.code;xf86LoadSubModule()&e.code; or
+ &s.code;xf86LoadDrvSubModule()&e.code; .
+
+ </quote>
+ </quote>
+
+<sect1>Cleaning up Unused Drivers
+<p>
+
+ At this point it is known which screens will be in use, and which
+ drivers are being used. Unreferenced drivers (and modules they
+ may have loaded) are unloaded here.
+
+
+<sect1>Consistency Checks
+<p>
+
+ The parameters that must be global to the server, like pixmap formats,
+ bitmap bit order, bitmap scanline unit and image byte order are
+ compared for each of the screens. If a mismatch is found, the server
+ exits with an appropriate message.
+
+
+<sect1>Check if Resource Control is Needed
+<p>
+
+ Determine if resource access control is needed. This is the case
+ if more than one screen is used. If necessary the RAC wrapper module
+ is loaded.
+
+<sect1>AddScreen (ScreenInit)
+<p>
+
+ At this point, the valid screens are known.
+ &s.code;AddScreen()&e.code; is called for each of them, passing
+ &s.code;ChipScreenInit()&e.code; as the argument.
+ &s.code;AddScreen()&e.code; is a DIX function that allocates a new
+ &s.code;screenInfo.screen[]&e.code; entry (aka
+ &s.code;pScreen&e.code;), and does some basic initialisation of it.
+ It then calls the &s.code;ChipScreenInit()&e.code; function, with
+ &s.code;pScreen&e.code; as one of its arguments. If
+ &s.code;ChipScreenInit()&e.code; returns &s.code;FALSE&e.code;,
+ &s.code;AddScreen()&e.code; returns &s.code;-1&e.code;. Otherwise
+ it returns the index of the screen. &s.code;AddScreen()&e.code;
+ should only fail because of programming errors or failure to allocate
+ resources (like memory). All configuration problems should be
+ detected BEFORE this point.
+
+ <quote><p>
+ &s.code;Bool ChipScreenInit(int index, ScreenPtr pScreen,
+ &f.indent;int argc, char **argv)&e.code;
+ <quote><p>
+ This is called at the start of each server generation.
+
+ Fill in all of &s.code;pScreen&e.code;, possibly doing some of
+ this by calling ScreenInit functions from other layers like mi,
+ framebuffers (cfb, etc), and extensions.
+
+ Decide which operations need to be placed under resource access
+ control. The classes of operations are the frame buffer operations
+ (&s.code;RAC_FB&e.code;), the pointer operations
+ (&s.code;RAC_CURSOR&e.code;), the viewport change operations
+ (&s.code;RAC_VIEWPORT&e.code;) and the colormap operations
+ (&s.code;RAC_COLORMAP&e.code;). Any operation that requires
+ resources which might be disabled during OPERATING state should
+ be set to use RAC. This can be specified separately for memory
+ and IO resources (the &s.code;racMemFlags&e.code; and
+ &s.code;racIoFlags&e.code; fields of the &s.code;ScrnInfoRec&e.code;
+ respectively).
+
+ Map any video memory or other memory regions.
+
+ Save the video card state. Enough state must be saved so that
+ the original state can later be restored.
+
+ Initialise the initial video mode. The &s.code;ScrnInfoRec&e.code;'s
+ &s.code;vtSema&e.code; field should be set to &s.code;TRUE&e.code;
+ just prior to changing the video hardware's state.
+
+ </quote>
+ </quote>
+
+
+ The &s.code;ChipScreenInit()&e.code; function (or functions from other
+ layers that it calls) should allocate entries in the
+ &s.code;ScreenRec&e.code;'s &s.code;devPrivates&e.code; area by
+ calling &s.code;AllocateScreenPrivateIndex()&e.code; if it needs
+ per-generation storage. Since the &s.code;ScreenRec&e.code;'s
+ &s.code;devPrivates&e.code; information is cleared for each server
+ generation, this is the correct place to initialise it.
+
+ After &s.code;AddScreen()&e.code; has successfully returned, the
+ following &s.code;ScrnInfoRec&e.code; fields are initialised:
+
+ <quote><verb>
+ pScreen
+ racMemFlags
+ racIoFlags
+ </verb></quote>
+
+ The &s.code;ChipScreenInit()&e.code; function should initialise the
+ &s.code;CloseScreen&e.code; and &s.code;SaveScreen&e.code; fields
+ of &s.code;pScreen&e.code;. The old value of
+ &s.code;pScreen->CloseScreen&e.code; should be saved as part of
+ the driver's per-screen private data, allowing it to be called from
+ &s.code;ChipCloseScreen()&e.code;. This means that the existing
+ &s.code;CloseScreen()&e.code; function is wrapped.
+
+<sect1>Finalising RAC Initialisation
+<p>
+
+ After all the &s.code;ChipScreenInit()&e.code; functions have been
+ called, each screen has registered its RAC requirements. This
+ information is used to determine which shared resources are requested
+ by more than one driver and set the access functions accordingly.
+ This is done following these rules:
+
+ <enum>
+ <item>The sharable resources registered by each entity are compared.
+ If a resource is registered by more than one entity the entity
+ will be marked to indicate that it needs to share this resources
+ type (IO or MEM).
+
+ <item>A resource marked ``disabled'' during OPERATING state will be
+ ignored entirely.
+
+ <item>A resource marked ``unused'' will only conflict with an overlapping
+ resource of an other entity if the second is actually in use
+ during OPERATING state.
+
+ <item>If an ``unused'' resource was found to conflict but the entity
+ does not use any other resource of this type the entire resource
+ type will be disabled for that entity.
+ </enum>
+
+
+<sect1>Finishing InitOutput()
+<p>
+
+ At this point &s.code;InitOutput()&e.code; is finished, and all the
+ screens have been setup in their initial video mode.
+
+
+<sect1>Mode Switching
+<p>
+
+ When a SwitchMode event is received, &s.code;ChipSwitchMode()&e.code;
+ is called (when it exists):
+
+ <quote><p>
+ &s.code;Bool ChipSwitchMode(int index, DisplayModePtr mode, int flags)&e.code;
+ <quote><p>
+ Initialises the new mode for the screen identified by
+ &s.code;index;&e.code;. The viewport may need to be adjusted
+ also.
+
+ </quote>
+ </quote>
+
+
+<sect1>Changing Viewport
+<p>
+
+ When a Change Viewport event is received,
+ &s.code;ChipAdjustFrame()&e.code; is called (when it exists):
+
+ <quote><p>
+ &s.code;void ChipAdjustFrame(int index, int x, int y, int flags)&e.code;
+ <quote><p>
+ Changes the viewport for the screen identified by
+ &s.code;index;&e.code;.
+
+ It should be noted that many chipsets impose restrictions on where the
+ viewport may be placed in the virtual resolution, either for alignment
+ reasons, or to prevent the start of the viewport from being positioned
+ within a pixel (as can happen in a 24bpp mode). After calculating the
+ value the chipset's panning registers need to be set to for non-DGA
+ modes, this function should recalculate the ScrnInfoRec's
+ &s.code;frameX0&e.code;, &s.code;frameY0&e.code, &s.code;frameX1&e.code;
+ and &s.code;frameY1&e.code; fields to correspond to that value. If
+ this is not done, switching to another mode might cause the position
+ of a hardware cursor to change.
+
+ </quote>
+ </quote>
+
+
+<sect1>VT Switching
+<p>
+
+ When a VT switch event is received, &s.code;xf86VTSwitch()&e.code;
+ is called. &s.code;xf86VTSwitch()&e.code; does the following:
+
+ <descrip>
+ <tag>On ENTER:</tag>
+ <itemize>
+ <item>enable port I/O access
+
+ <item>save and initialise the bus/resource state
+
+ <item>enter the SETUP server state
+
+ <item>calls &s.code;ChipEnterVT()&e.code; for each screen
+
+ <item>enter the OPERATING server state
+
+ <item>validate GCs
+
+ <item>Restore fb from saved pixmap for each screen
+
+ <item>Enable all input devices
+ </itemize>
+ <tag>On LEAVE:</tag>
+ <itemize>
+ <item>Save fb to pixmap for each screen
+
+ <item>validate GCs
+
+ <item>enter the SETUP server state
+
+ <item>calls &s.code;ChipLeaveVT()&e.code; for each screen
+
+ <item>disable all input devices
+
+ <item>restore bus/resource state
+
+ <item>disables port I/O access
+ </itemize>
+ </descrip>
+
+ <quote><p>
+ &s.code;Bool ChipEnterVT(int index, int flags)&e.code;
+ <quote><p>
+ This function should initialise the current video mode and
+ initialise the viewport, turn on the HW cursor if appropriate,
+ etc.
+
+ Should it re-save the video state before initialising the video
+ mode?
+
+ </quote>
+
+ &s.code;void ChipLeaveVT(int index, int flags)&e.code;
+ <quote><p>
+ This function should restore the saved video state. If
+ appropriate it should also turn off the HW cursor, and invalidate
+ any pixmap/font caches.
+
+ </quote>
+
+ Optionally, &s.code;ChipLeaveVT()&e.code; may also unmap memory
+ regions. If so, &s.code;ChipEnterVT()&e.code; will need to remap
+ them. Additionally, if an aperture used to access video memory is
+ unmapped and remapped in this fashion, &s.code;ChipEnterVT()&e.code;
+ will also need to notify the framebuffer layers of the aperture's new
+ location in virtual memory. This is done with a call to the screen's
+ &s.code;ModifyPixmapHeader()&e.code; function, as follows
+
+ <quote><p>
+ &s.code;(*pScreen->ModifyPixmapHeader)(pScrn->ppix,
+ &f.indent;-1, -1, -1, -1, -1, <it>NewApertureAddress</it>);&e.code;
+ <quote><p>
+ where the &s.code``ppix''&e.code; field in a ScrnInfoRec
+ points to the pixmap used by the screen's
+ &s.code;SaveRestoreImage()&e.code; function to hold the screen's
+ contents while switched out.
+
+ </quote>
+ </quote>
+
+ Currently, aperture remapping, as described here, should not be
+ attempted if the driver uses the &s.code;xf8_16bpp&e.code; or
+ &s.code;xf8_32bpp&e.code; framebuffer layers. A pending
+ restructuring of VT switching will address this restriction in
+ the near future.
+
+ </quote>
+
+ Other layers may wrap the &s.code;ChipEnterVT()&e.code; and
+ &s.code;ChipLeaveVT()&e.code; functions if they need to take some
+ action when these events are received.
+
+<sect1>End of server generation
+<p>
+
+ At the end of each server generation, the DIX layer calls
+ &s.code;ChipCloseScreen()&e.code; for each screen:
+
+ <quote><p>
+ &s.code;Bool ChipCloseScreen(int index, ScreenPtr pScreen)&e.code;
+ <quote><p>
+ This function should restore the saved video state and unmap the
+ memory regions.
+
+ It should also free per-screen data structures allocated by the
+ driver. Note that the persistent data held in the
+ &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field
+ should not be freed here because it is needed by subsequent server
+ generations.
+
+ The &s.code;ScrnInfoRec&e.code;'s &s.code;vtSema&e.code; field
+ should be set to &s.code;FALSE&e.code; once the video HW state
+ has been restored.
+
+ Before freeing the per-screen driver data the saved
+ &s.code;CloseScreen&e.code; value should be restored to
+ &s.code;pScreen->CloseScreen&e.code;, and that function should
+ be called after freeing the data.
+
+ </quote>
+ </quote>
+
+<sect>Optional Driver Functions
+<p>
+
+The functions outlined here can be called from the XFree86 common layer,
+but their presence is optional.
+
+<sect1>Mode Validation
+<p>
+
+ When a mode validation helper supplied by the XFree86-common layer is
+ being used, it can be useful to provide a function to check for hw
+ specific mode constraints:
+
+ <quote><p>
+ &s.code;ModeStatus ChipValidMode(int index, DisplayModePtr mode,
+ &f.indent;Bool verbose, int flags)&e.code;
+ <quote><p>
+ Check the passed mode for hw-specific constraints, and return the
+ appropriate status value.
+
+ </quote>
+ </quote>
+
+<p>
+This function may also modify the effective timings and clock of the passed
+mode. These have been stored in the mode's &s.code;Crtc*&e.code; and
+&s.code;SynthClock&e.code; elements, and have already been adjusted for
+interlacing, doublescanning, multiscanning and clock multipliers and dividers.
+The function should not modify any other mode field, unless it wants to modify
+the mode timings reported to the user by &s.code;xf86PrintModes()&e.code;.
+
+<p>
+The function is called once for every mode in the xorg.conf Monitor section
+assigned to the screen, with &s.code;flags&e.code; set to
+&s.code;MODECHECK_INITIAL&e.code;. It is subsequently called for every mode
+in the xorg.conf Display subsection assigned to the screen, with
+&s.code;flags&e.code; set to &s.code;MODECHECK_FINAL&e.code;. In the second
+case, the mode will have successfully passed all other tests. In addition,
+the &s.code;ScrnInfoRec&e.code;'s &s.code;virtualX&e.code;,
+&s.code;virtualY&e.code; and &s.code;displayWidth&e.code; fields will have been
+set as if the mode to be validated were to be the last mode accepted.
+
+<p>
+In effect, calls with MODECHECK_INITIAL are intended for checks that do not
+depend on any mode other than the one being validated, while calls with
+MODECHECK_FINAL are intended for checks that may involve more than one mode.
+
+<sect1>Free screen data
+<p>
+
+ When a screen is deleted prior to the completion of the ScreenInit
+ phase the &s.code;ChipFreeScreen()&e.code; function is called when defined.
+
+ <quote><p>
+ &s.code;void ChipFreeScreen(int scrnindex, int flags)&e.code;
+ <quote><p>
+ Free any driver-allocated data that may have been allocated up to
+ and including an unsuccessful &s.code;ChipScreenInit()&e.code;
+ call. This would predominantly be data allocated by
+ &s.code;ChipPreInit()&e.code; that persists across server
+ generations. It would include the &s.code;driverPrivate&e.code;,
+ and any ``privates'' entries that modules may have allocated.
+
+ </quote>
+ </quote>
+
+
+<sect>Recommended driver functions
+<p>
+
+The functions outlined here are for internal use by the driver only.
+They are entirely optional, and are never accessed directly from higher
+layers. The sample function declarations shown here are just examples.
+The interface (if any) used is up to the driver.
+
+<sect1>Save
+<p>
+
+ Save the video state. This could be called from &s.code;ChipScreenInit()&e.code; and
+ (possibly) &s.code;ChipEnterVT()&e.code;.
+
+ <quote><p>
+ &s.code;void ChipSave(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ Saves the current state. This will only be saving pre-server
+ states or states before returning to the server. There is only
+ one current saved state per screen and it is stored in private
+ storage in the screen.
+
+ </quote>
+ </quote>
+
+<sect1>Restore
+<p>
+
+ Restore the original video state. This could be called from the
+ &s.code;ChipLeaveVT()&e.code; and &s.code;ChipCloseScreen()&e.code;
+ functions.
+
+ <quote><p>
+ &s.code;void ChipRestore(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ Restores the saved state from the private storage. Usually only
+ used for restoring text modes.
+
+ </quote>
+ </quote>
+
+
+<sect1>Initialise Mode
+<p>
+
+ Initialise a video mode. This could be called from the
+ &s.code;ChipScreenInit()&e.code;, &s.code;ChipSwitchMode()&e.code;
+ and &s.code;ChipEnterVT()&e.code; functions.
+
+ <quote><p>
+ &s.code;Bool ChipModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)&e.code;
+ <quote><p>
+ Programs the hardware for the given video mode.
+
+ </quote>
+ </quote>
+
+
+<sect>Data and Data Structures
+<p>
+
+<sect1>Command line data
+<p>
+
+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:
+
+<quote><verb>
+ 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
+</verb></quote>
+
+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:
+
+ <quote><p>
+ &s.code;int xf86GetVerbosity()&e.code;
+ <quote><p>
+ Returns the value of &s.code;xf86Verbose&e.code;.
+
+ </quote>
+
+ &s.code;int xf86GetDepth()&e.code;
+ <quote><p>
+ Returns the &s.cmd;-depth&e.cmd; command line setting. If not
+ set on the command line, &s.code;-1&e.code; is returned.
+
+ </quote>
+
+ &s.code;rgb xf86GetWeight()&e.code;
+ <quote><p>
+ Returns the &s.cmd;-weight&e.cmd; command line setting. If not
+ set on the command line, &s.code;{0, 0, 0}&e.code; is returned.
+
+ </quote>
+
+ &s.code;Gamma xf86GetGamma()&e.code;
+ <quote><p>
+ Returns the &s.cmd;-gamma&e.cmd; or &s.cmd;-rgamma&e.cmd;,
+ &s.cmd;-ggamma&e.cmd;, &s.cmd;-bgamma&e.cmd; command line settings.
+ If not set on the command line, &s.code;{0.0, 0.0, 0.0}&e.code;
+ is returned.
+
+ </quote>
+
+ &s.code;Bool xf86GetFlipPixels()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if &s.cmd;-flippixels&e.cmd; is
+ present on the command line, and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;const char *xf86GetServerName()&e.code;
+ <quote><p>
+ Returns the name of the X server from the command line.
+
+ </quote>
+ </quote>
+
+<sect1>Data handling
+<p>
+
+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 &s.code;xf86InfoRec&e.code;.
+
+The screen-specific data collected from the config file is stored in
+screen, device, display, monitor-specific data structures that are separate
+from the &s.code;ScrnInfoRecs&e.code;, with the appropriate elements/fields
+hooked into the &s.code;ScrnInfoRecs&e.code; as required. The screen
+config data is held in &s.code;confScreenRec&e.code;, device data in
+the &s.code;GDevRec&e.code;, monitor data in the &s.code;MonRec&e.code;,
+and display data in the &s.code;DispRec&e.code;.
+
+The XFree86 common layer's screen specific data (the actual data in use
+for each screen) is held in the &s.code;ScrnInfoRecs&e.code;. As has
+been outlined above, the &s.code;ScrnInfoRecs&e.code; are allocated at probe
+time, and it is the responsibility of the Drivers' &s.code;Probe()&e.code;
+and &s.code;PreInit()&e.code; 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:
+
+ <quote>
+ command line -> config file -> probed/default data
+ </quote>
+
+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
+&s.code;ScrnInfoRec&e.code;, consider the balance between the convenience
+of things that lots of drivers need and the size/obscurity of the
+&s.code;ScrnInfoRec&e.code;.
+
+Per-screen driver specific data that cannot be accommodated with the
+static &s.code;ScrnInfoRec&e.code; fields is held in a driver-defined
+data structure, a pointer to which is assigned to the
+&s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field. This
+is per-screen data that persists across server generations (as does the
+bulk of the static &s.code;ScrnInfoRec&e.code; 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 &s.code;ScrnInfoRec&e.code; through it's &s.code;privates&e.code;
+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 &s.code;xf86.h&e.code; and &s.code;xf86str.h&e.code;
+files are visible to video drivers. Things defined in
+&s.code;xf86Priv.h&e.code; and &s.code;xf86Privstr.h&e.code; are NOT
+intended to be visible to video drivers, and it is an error for a driver
+to include those files.
+
+
+<sect1>Accessing global data
+<p>
+
+Some other global state information that the drivers may access via
+functions is as follows:
+
+ <quote><p>
+ &s.code;Bool xf86ServerIsExiting()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if the server is at the end of a
+ generation and is in the process of exiting, and
+ &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;Bool xf86ServerIsResetting()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if the server is at the end of a
+ generation and is in the process of resetting, and
+ &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;Bool xf86ServerIsInitialising()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if the server is at the beginning of
+ a generation and is in the process of initialising, and
+ &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;Bool xf86ServerIsOnlyProbing()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if the -probeonly command line flag
+ was specified, and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;Bool xf86CaughtSignal()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if the server has caught a signal,
+ and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+ </quote>
+
+<sect1>Allocating private data
+<p>
+
+A driver and any module it uses may allocate per-screen private storage
+in either the &s.code;ScreenRec&e.code; (DIX level) or
+&s.code;ScrnInfoRec&e.code; (XFree86 common layer level).
+&s.code;ScreenRec&e.code; storage persists only for a single server
+generation, and &s.code;ScrnInfoRec&e.code; storage persists across
+generations for the lifetime of the server.
+
+The &s.code;ScreenRec&e.code; &s.code;devPrivates&e.code; data must be
+reallocated/initialised at the start of each new generation. This is
+normally done from the &s.code;ChipScreenInit()&e.code; function, and
+Init functions for other modules that it calls. Data allocated in this
+way should be freed by the driver's &s.code;ChipCloseScreen()&e.code;
+functions, and Close functions for other modules that it calls. A new
+&s.code;devPrivates&e.code; entry is allocated by calling the
+&s.code;AllocateScreenPrivateIndex()&e.code; function.
+
+ <quote><p>
+ &s.code;int AllocateScreenPrivateIndex()&e.code;
+ <quote><p>
+ This function allocates a new element in the
+ &s.code;devPrivates&e.code; field of all currently existing
+ &s.code;ScreenRecs&e.code;. The return value is the index of this
+ new element in the &s.code;devPrivates&e.code; array. The
+ &s.code;devPrivates&e.code; field is of type
+ &s.code;DevUnion&e.code;:
+
+ <verb>
+ typedef union _DevUnion {
+ pointer ptr;
+ long val;
+ unsigned long uval;
+ pointer (*fptr)(void);
+ } DevUnion;
+ </verb>
+
+ 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 &s.code;-1&e.code; when there is an
+ error allocating the new index.
+
+ </quote>
+ </quote>
+
+The &s.code;ScrnInfoRec&e.code; &s.code;privates&e.code; data persists
+for the life of the server, so only needs to be allocated once. This
+should be done from the &s.code;ChipPreInit()&e.code; function, and Init
+functions for other modules that it calls. Data allocated in this way
+should be freed by the driver's &s.code;ChipFreeScreen()&e.code; functions,
+and Free functions for other modules that it calls. A new
+&s.code;privates&e.code; entry is allocated by calling the
+&s.code;xf86AllocateScrnInfoPrivateIndex()&e.code; function.
+
+
+ <quote><p>
+ &s.code;int xf86AllocateScrnInfoPrivateIndex()&e.code;
+ <quote><p>
+ This function allocates a new element in the &s.code;privates&e.code;
+ field of all currently existing &s.code;ScrnInfoRecs&e.code;.
+ The return value is the index of this new element in the
+ &s.code;privates&e.code; array. The &s.code;privates&e.code;
+ field is of type &s.code;DevUnion&e.code;:
+
+ <verb>
+ typedef union _DevUnion {
+ pointer ptr;
+ long val;
+ unsigned long uval;
+ pointer (*fptr)(void);
+ } DevUnion;
+ </verb>
+
+ 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 &s.code;ScreenRec&e.code;
+ (&s.code;AllocateScreenPrivateIndex()&e.code;) differs in this
+ respect by returning &s.code;-1&e.code; when the allocation fails.
+
+ </quote>
+ </quote>
+
+<sect>Keeping Track of Bus Resources<label id="rac">
+<p>
+
+<sect1>Theory of Operation
+<p>
+
+The XFree86 common layer has knowledge of generic access control mechanisms
+for devices on certain bus systems (currently the PCI bus) as well as
+of methods to enable or disable access to the buses itself. Furthermore
+it can access information on resources decoded by these devices and if
+necessary modify it.
+
+When first starting the Xserver collects all this information, saves it
+for restoration, checks it for consistency, and if necessary, corrects
+it. Finally it disables all resources on a generic level prior to
+calling any driver function.
+
+When the &s.code;Probe()&e.code; function of each driver is called the
+device sections are matched against the devices found in the system.
+The driver may probe devices at this stage that cannot be identified by
+using device independent methods. Access to all resources that can be
+controlled in a device independent way is disabled. The
+&s.code;Probe()&e.code; function should register all non-relocatable
+resources at this stage. If a resource conflict is found between
+exclusive resources the driver will fail immediately. Optionally the
+driver might specify an &s.code;EntityInit()&e.code;,
+&s.code;EntityLeave()&e.code; and &s.code;EntityEnter()&e.code; function.
+
+&s.code;EntityInit()&e.code; can be used to disable any shared resources
+that are not controlled by the generic access control functions. It is
+called prior to the PreInit phase regardless if an entity is active or
+not. When calling the &s.code;EntityInit()&e.code;,
+&s.code;EntityEnter()&e.code; and &s.code;EntityLeave()&e.code; functions
+the common level will disable access to all other entities on a generic
+level. Since the common level has no knowledge of device specific
+methods to disable access to resources it cannot be guaranteed that
+certain resources are not decoded by any other entity until the
+&s.code;EntityInit()&e.code; or &s.code;EntityEnter()&e.code; phase is
+finished. Device drivers should therefore register all those resources
+which they are going to disable. If these resources are never to be
+used by any driver function they may be flagged &s.code;ResInit&e.code;
+so that they can be removed from the resource list after processing all
+&s.code;EntityInit()&e.code; functions. &s.code;EntityEnter()&e.code;
+should disable decoding of all resources which are not registered as
+exclusive and which are not handled by the generic access control in
+the common level. The difference to &s.code;EntityInit()&e.code; is
+that the latter one is only called once during lifetime of the server.
+It can therefore be used to set up variables prior to disabling resources.
+&s.code;EntityLeave()&e.code; should restore the original state when
+exiting the server or switching to a different VT. It also needs to
+disable device specific access functions if they need to be disabled on
+server exit or VT switch. The default state is to enable them before
+giving up the VT.
+
+In &s.code;PreInit()&e.code; phase each driver should check if any
+sharable resources it has registered during &s.code;Probe()&e.code; has
+been denied and take appropriate action which could simply be to fail.
+If it needs to access resources it has disabled during
+&s.code;EntitySetup()&e.code; it can do so provided it has registered
+these and will disable them before returning from
+&s.code;PreInit()&e.code;. This also applies to all other driver
+functions. Several functions are provided to request resource ranges,
+register these, correct PCI config space and add replacements for the
+generic access functions. Resources may be marked ``disabled'' or
+``unused'' during OPERATING stage. Although these steps could also be
+performed in &s.code;ScreenInit()&e.code;, this is not desirable.
+
+Following &s.code;PreInit()&e.code; phase the common level determines
+if resource access control is needed. This is the case if more than
+one screen is used. If necessary the RAC wrapper module is loaded. In
+&s.code;ScreenInit()&e.code; the drivers can decide which operations
+need to be placed under RAC. Available are the frame buffer operations,
+the pointer operations and the colormap operations. Any operation that
+requires resources which might be disabled during OPERATING state should
+be set to use RAC. This can be specified separately for memory and IO
+resources.
+
+When &s.code;ScreenInit()&e.code; phase is done the common level will
+determine which shared resources are requested by more than one driver
+and set the access functions accordingly. This is done following these
+rules:
+
+<enum>
+<item>The sharable resources registered by each entity are compared. If
+ a resource is registered by more than one entity the entity will be
+ marked to need to share this resources type (&s.code;IO&e.code; or
+ &s.code;MEM&e.code;).
+
+<item>A resource marked ``disabled'' during OPERATING state will be ignored
+ entirely.
+
+<item>A resource marked ``unused'' will only conflicts with an overlapping
+ resource of an other entity if the second is actually in use during
+ OPERATING state.
+
+<item>If an ``unused'' resource was found to conflict however the entity
+ does not use any other resource of this type the entire resource type
+ will be disabled for that entity.
+</enum>
+
+The driver has the choice among different ways to control access to
+certain resources:
+
+<enum>
+<item>It can rely on the generic access functions. This is probably the
+ most common case. Here the driver only needs to register any resource
+ it is going to use.
+
+<item>It can replace the generic access functions by driver specific
+ ones. This will mostly be used in cases where no generic access
+ functions are available. In this case the driver has to make sure
+ these resources are disabled when entering the &s.code;PreInit()&e.code;
+ stage. Since the replacement functions are registered in
+ &s.code;PreInit()&e.code; the driver will have to enable these
+ resources itself if it needs to access them during this state. The
+ driver can specify if the replacement functions can control memory
+ and/or I/O resources separately.
+
+<item>The driver can enable resources itself when it needs them. Each
+ driver function enabling them needs to disable them before it will
+ return. This should be used if a resource which can be controlled
+ in a device dependent way is only required during SETUP state. This
+ way it can be marked ``unused'' during OPERATING state.
+</enum>
+
+A resource which is decoded during OPERATING state however never accessed
+by the driver should be marked unused.
+
+Since access switching latencies are an issue during Xserver operation,
+the common level attempts to minimize the number of entities that need
+to be placed under RAC control. When a wrapped operation is called,
+the &s.code;EnableAccess()&e.code; function is called before control is
+passed on. &s.code;EnableAccess()&e.code; checks if a screen is under
+access control. If not it just establishes bus routing and returns.
+If the screen needs to be under access control,
+&s.code;EnableAccess()&e.code; determines which resource types
+(&s.code;MEM&e.code;, &s.code;IO&e.code;) are required. Then it tests
+if this access is already established. If so it simply returns. If
+not it disables the currently established access, fixes bus routing and
+enables access to all entities registered for this screen.
+
+Whenever a mode switch or a VT-switch is performed the common level will
+return to SETUP state.
+
+<sect1>Resource Types
+<p>
+
+Resource have certain properties. When registering resources each range
+is accompanied by a flag consisting of the ORed flags of the different
+properties the resource has. Each resource range may be classified
+according to
+
+<itemize>
+ <item>its physical properties i.e., if it addresses
+ memory (&s.code;ResMem&e.code;) or
+ I/O space (&s.code;ResIo&e.code;),
+ <item>if it addresses a
+ block (&s.code;ResBlock&e.code;) or
+ sparse (&s.code;ResSparse&e.code;)
+ range,
+ <item>its access properties.
+</itemize>
+
+There are two known access properties:
+
+<itemize>
+ <item>&s.code;ResExclusive&e.code;
+ for resources which may not be shared with any other device and
+ <item>&s.code;ResShared&e.code;
+ for resources which can be disabled and therefore can be shared.
+</itemize>
+
+If it is necessary to test a resource against any type a generic access
+type &s.code;ResAny&e.code; is provided. If this is set the resource
+will conflict with any resource of a different entity intersecting its
+range. Further it can be specified that a resource is decoded however
+never used during any stage (&s.code;ResUnused&e.code;) or during
+OPERATING state (&s.code;ResUnusedOpr&e.code;). A resource only visible
+during the init functions (ie. &s.code;EntityInit()&e.code;,
+&s.code;EntityEnter()&e.code; and &s.code;EntityLeave()&e.code; should
+be registered with the flag &s.code;ResInit&e.code;. A resource that
+might conflict with background resource ranges may be flagged with
+&s.code;ResBios&e.code;. This might be useful when registering resources
+ranges that were assigned by the system Bios.
+
+Several predefined resource lists are available for VGA and 8514/A
+resources in &s.code;common/xf86Resources.h&e.code;.
+
+<sect1>Available Functions<label id="avail">
+<p>
+
+The functions provided for resource management are listed in their order
+of use in the driver.
+
+
+<sect2>Probe Phase
+<p>
+
+In this phase each driver detects those resources it is able to drive,
+creates an entity record for each of them, registers non-relocatable
+resources and allocates screens and adds the resources to screens.
+
+Two helper functions are provided for matching device sections in the
+xorg.conf file to the devices:
+
+ <quote><p>
+ &s.code;int xf86MatchPciInstances(const char *driverName, int vendorID,
+ &f.indent;SymTabPtr chipsets, PciChipsets *PCIchipsets,
+ &f.indent;GDevPtr *devList, int numDevs, DriverPtr drvp,
+ &f.indent;int **foundEntities)&e.code;
+ <quote><p>
+ This function finds matches between PCI cards that a driver supports
+ and config file device sections. It is intended for use in the
+ &s.code;ChipProbe()&e.code; function of drivers for PCI cards.
+ Only probed PCI devices with a vendor ID matching
+ &s.code;vendorID&e.code; are considered. &s.code;devList&e.code;
+ and &s.code;numDevs&e.code; are typically those found from
+ calling &s.code;xf86MatchDevice()&e.code;, and represent the active
+ config file device sections relevant to the driver.
+ &s.code;PCIchipsets&e.code; is a table that provides a mapping
+ between the PCI device IDs, the driver's internal chipset tokens
+ and a list of fixed resources.
+
+ When a device section doesn't have a &s.key;BusID&e.key; entry it
+ can only match the primary video device. Secondary devices are
+ only matched with device sections that have a matching
+ &s.key;BusID&e.key; entry.
+
+ Once the preliminary matches have been found, a final match is
+ confirmed by checking if the chipset override, ChipID override or
+ probed PCI chipset type match one of those given in the
+ &s.code;chipsets&e.code; and &s.code;PCIchipsets&e.code; lists.
+ The &s.code;PCIchipsets&e.code; list includes a list of the PCI
+ device IDs supported by the driver. The list should be terminated
+ with an entry with PCI ID &s.code;-1&e.code;". The
+ &s.code;chipsets&e.code; list is a table mapping the driver's
+ internal chipset tokens to names, and should be terminated with
+ a &s.code;NULL&e.code; entry. Only those entries with a
+ corresponding entry in the &s.code;PCIchipsets&e.code; list are
+ considered. The order of precedence is: config file chipset,
+ config file ChipID, probed PCI device ID.
+
+ In cases where a driver handles PCI chipsets with more than one
+ vendor ID, it may set &s.code;vendorID&e.code; to
+ &s.code;0&e.code;, and OR each devID in the list with (the
+ vendor ID << 16).
+
+ Entity index numbers for confirmed matches are returned as an
+ array via &s.code;foundEntities&e.code;. The PCI information,
+ chipset token and device section for each match are found in the
+ &s.code;EntityInfoRec&e.code; referenced by the indices.
+
+ The function return value is the number of confirmed matches. A
+ return value of &s.code;-1&e.code; indicates an internal error.
+ The returned &s.code;foundEntities&e.code; array should be freed
+ by the driver with &s.code;xfree()&e.code; when it is no longer
+ needed in cases where the return value is greater than zero.
+
+ </quote>
+
+ &s.code;int xf86MatchIsaInstances(const char *driverName,
+ &f.indent;SymTabPtr chipsets, IsaChipsets *ISAchipsets,
+ &f.indent;DriverPtr drvp, FindIsaDevProc FindIsaDevice,
+ &f.indent;GDevPtr *devList, int numDevs,
+ int **foundEntities)&e.code;
+ <quote><p>
+ This function finds matches between ISA cards that a driver supports
+ and config file device sections. It is intended for use in the
+ &s.code;ChipProbe()&e.code; function of drivers for ISA cards.
+ &s.code;devList&e.code; and &s.code;numDevs&e.code; are
+ typically those found from calling &s.code;xf86MatchDevice()&e.code;,
+ and represent the active config file device sections relevant to
+ the driver. &s.code;ISAchipsets&e.code; is a table that provides
+ a mapping between the driver's internal chipset tokens and the
+ resource classes. &s.code;FindIsaDevice&e.code; is a
+ driver-provided function that probes the hardware and returns the
+ chipset token corresponding to what was detected, and
+ &s.code;-1&e.code; if nothing was detected.
+
+ If the config file device section contains a chipset entry, then
+ it is checked against the &s.code;chipsets&e.code; list. When
+ no chipset entry is present, the &s.code;FindIsaDevice&e.code;
+ function is called instead.
+
+ Entity index numbers for confirmed matches are returned as an
+ array via &s.code;foundEntities&e.code;. The chipset token and
+ device section for each match are found in the
+ &s.code;EntityInfoRec&e.code; referenced by the indices.
+
+ The function return value is the number of confirmed matches. A
+ return value of &s.code;-1&e.code; indicates an internal error.
+ The returned &s.code;foundEntities&e.code; array should be freed
+ by the driver with &s.code;xfree()&e.code; when it is no longer
+ needed in cases where the return value is greater than zero.
+
+ </quote>
+ </quote>
+
+These two helper functions make use of several core functions that are
+available at the driver level:
+
+ <quote><p>
+ &s.code;Bool xf86ParsePciBusString(const char *busID, int *bus,
+ &f.indent;int *device, int *func)&e.code;
+ <quote><p>
+ Takes a &s.code;BusID&e.code; string, and if it is in the correct
+ format, returns the PCI &s.code;bus&e.code;, &s.code;device&e.code;,
+ &s.code;func&e.code; values that it indicates. The format of the
+ string is expected to be "PCI:bus:device:func" where each of `bus',
+ `device' and `func' are decimal integers. The ":func" part may
+ be omitted, and the func value assumed to be zero, but this isn't
+ encouraged. The "PCI" prefix may also be omitted. The prefix
+ "AGP" is currently equivalent to the "PCI" prefix. If the string
+ isn't a valid PCI BusID, the return value is &s.code;FALSE&e.code;.
+
+ </quote>
+
+
+ &s.code;Bool xf86ComparePciBusString(const char *busID, int bus,
+ &f.indent;int device, int func)&e.code;
+ <quote><p>
+ Compares a &s.code;BusID&e.code; string with PCI &s.code;bus&e.code;,
+ &s.code;device&e.code;, &s.code;func&e.code; values. If they
+ match &s.code;TRUE&e.code; is returned, and &s.code;FALSE&e.code;
+ if they don't.
+
+ </quote>
+
+ &s.code;Bool xf86ParseIsaBusString(const char *busID)&e.code;
+ <quote><p>
+ Compares a &s.code;BusID&e.code; string with the ISA bus ID string
+ ("ISA" or "ISA:"). If they match &s.code;TRUE&e.code; is returned,
+ and &s.code;FALSE&e.code; if they don't.
+
+ </quote>
+
+ &s.code;Bool xf86CheckPciSlot(int bus, int device, int func)&e.code;
+ <quote><p>
+ Checks if the PCI slot &s.code;bus:device:func&e.code; has been
+ claimed. If so, it returns &s.code;FALSE&e.code;, and otherwise
+ &s.code;TRUE&e.code;.
+
+ </quote>
+
+ &s.code;int xf86ClaimPciSlot(int bus, int device, int func, DriverPtr drvp,
+ &f.indent;int chipset, GDevPtr dev, Bool active)&e.code;
+ <quote><p>
+ This function is used to claim a PCI slot, allocate the associated
+ entity record and initialise their data structures. The return
+ value is the index of the newly allocated entity record, or
+ &s.code;-1&e.code; if the claim fails. This function should always
+ succeed if &s.code;xf86CheckPciSlot()&e.code; returned
+ &s.code;TRUE&e.code; for the same PCI slot.
+
+ </quote>
+
+ &s.code;Bool xf86IsPrimaryPci(void)&e.code;
+ <quote><p>
+ This function returns &s.code;TRUE&e.code; if the primary card is
+ a PCI device, and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;int xf86ClaimIsaSlot(DriverPtr drvp, int chipset,
+ &f.indent;GDevPtr dev, Bool active)&e.code;
+ <quote><p>
+ This allocates an entity record entity and initialise the data
+ structures. The return value is the index of the newly allocated
+ entity record.
+
+ </quote>
+
+ &s.code;Bool xf86IsPrimaryIsa(void)&e.code;
+ <quote><p>
+ This function returns &s.code;TRUE&e.code; if the primary card is
+ an ISA (non-PCI) device, and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+ </quote>
+
+Two helper functions are provided to aid configuring entities:
+ <quote><p>
+ &s.code;ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn,
+ &f.indent;int scrnFlag, int entityIndex,
+ &f.indent;PciChipsets *p_chip,
+ &f.indent;resList res, EntityProc init,
+ &f.indent;EntityProc enter, EntityProc leave,
+ &f.indent;pointer private)&e.code;
+ <p>
+ &s.code;ScrnInfoPtr xf86ConfigIsaEntity(ScrnInfoPtr pScrn,
+ &f.indent;int scrnFlag, int entityIndex,
+ &f.indent;IsaChipsets *i_chip,
+ &f.indent;resList res, EntityProc init,
+ &f.indent;EntityProc enter, EntityProc leave,
+ &f.indent;pointer private)&e.code;
+ <quote><p>
+ These functions are used to register the non-relocatable resources
+ for an entity, and the optional entity-specific &s.code;Init&e.code;, &s.code;Enter&e.code; and
+ &s.code;Leave&e.code; functions. Usually the list of fixed resources is obtained
+ from the Isa/PciChipsets lists. However an additional list of
+ resources may be passed. Generally this is not required.
+ For active entities a &s.code;ScrnInfoRec&e.code; is allocated
+ if the &s.code;pScrn&e.code; argument is &s.code;NULL&e.code;.
+The
+ return value is &s.code;TRUE&e.code; when successful. The init, enter, leave
+ functions are defined as follows:
+
+ <quote>
+ &s.code;typedef void (*EntityProc)(int entityIndex,
+ &f.indent;pointer private)&e.code;
+ </quote>
+
+ They are passed the entity index and a pointer to a private scratch
+ area. This can be set up during &s.code;Probe()&e.code; and
+ its address can be passed to
+ &s.code;xf86ConfigIsaEntity()&e.code; and
+ &s.code;xf86ConfigPciEntity()&e.code; as the last argument.
+
+ </quote>
+ </quote>
+
+These two helper functions make use of several core functions that are
+available at the driver level:
+ <quote><p>
+ &s.code;void xf86ClaimFixedResources(resList list, int entityIndex)&e.code;
+ <quote><p>
+ This function registers the non-relocatable resources which cannot
+ be disabled and which therefore would cause the server to fail
+ immediately if they were found to conflict. It also records
+ non-relocatable but sharable resources for processing after the
+ &s.code;Probe()&e.code; phase.
+
+ </quote>
+
+ &s.code;Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
+ &f.indent;EntityProc enter, EntityProc leave, pointer)&e.code;
+ <quote><p>
+ This function registers with an entity the &s.code;init&e.code;,
+ &s.code;enter&e.code;, &s.code;leave&e.code; functions along
+ with the pointer to their private area.
+
+ </quote>
+
+ &s.code;void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)&e.code;
+ <quote><p>
+ This function associates the entity referenced by
+ &s.code;entityIndex&e.code; with the screen.
+
+ </quote>
+ </quote>
+
+<sect2>PreInit Phase
+<p>
+
+During this phase the remaining resources should be registered.
+&s.code;PreInit()&e.code; should call &s.code;xf86GetEntityInfo()&e.code;
+to obtain a pointer to an &s.code;EntityInfoRec&e.code; for each entity
+it is able to drive and check if any resource are listed in its
+&s.code;resources&e.code; field. If resources registered in the Probe
+phase have been rejected in the post-Probe phase
+(&s.code;resources&e.code; is non-&s.code;NULL&e.code;), then the driver should
+decide if it can continue without using these or if it should fail.
+
+ <quote><p>
+ &s.code;EntityInfoPtr xf86GetEntityInfo(int entityIndex)&e.code;
+ <quote><p>
+ This function returns a pointer to the &s.code;EntityInfoRec&e.code;
+ referenced by &s.code;entityIndex&e.code;. The returned
+ &s.code;EntityInfoRec&e.code; should be freed with
+ &s.code;xfree()&e.code; when no longer needed.
+
+ </quote>
+ </quote>
+Several functions are provided to simplify resource registration:
+ <quote><p>
+ &s.code;Bool xf86IsEntityPrimary(int entityIndex)&e.code;
+ <quote><p>
+ This function returns &s.code;TRUE&e.code; if the entity referenced
+ by &s.code;entityIndex&e.code; is the primary display device (i.e.,
+ the one initialised at boot time and used in text mode).
+
+ </quote>
+
+ &s.code;Bool xf86IsScreenPrimary(int scrnIndex)&e.code;
+ <quote><p>
+ This function returns &s.code;TRUE&e.code; if the primary entity
+ is registered with the screen referenced by
+ &s.code;scrnIndex&e.code;.
+
+ </quote>
+
+ &s.code;pciVideoPtr xf86GetPciInfoForEntity(int entityIndex)&e.code;
+ <quote><p>
+ This function returns a pointer to the &s.code;pciVideoRec&e.code;
+ for the specified entity. If the entity is not a PCI device,
+ &s.code;NULL&e.code; is returned.
+
+ </quote>
+ </quote>
+
+The primary function for registration of resources is:
+ <quote><p>
+ &s.code;resPtr xf86RegisterResources(int entityIndex, resList list,
+ &f.indent;int access)&e.code;
+ <quote><p>
+ This function tries to register the resources in
+ &s.code;list&e.code;. If list is &s.code;NULL&e.code; it tries
+ to determine the resources automatically. This only works for
+ entities that provide a generic way to read out the resource ranges
+ they decode. So far this is only the case for PCI devices. By
+ default the PCI resources are registered as shared
+ (&s.code;ResShared&e.code;) if the driver wants to set a different
+ access type it can do so by specifying the access flags in the
+ third argument. A value of &s.code;0&e.code; means to use the
+ default settings. If for any reason the resource broker is not
+ able to register some of the requested resources the function will
+ return a pointer to a list of the failed ones. In this case the
+ driver may be able to move the resource to different locations.
+ In case of PCI bus entities this is done by passing the list of
+ failed resources to &s.code;xf86ReallocatePciResources()&e.code;.
+ When the registration succeeds, the return value is
+ &s.code;NULL&e.code;.
+
+ </quote>
+
+ &s.code;resPtr xf86ReallocatePciResources(int entityIndex, resPtr pRes)&e.code;
+ <quote><p>
+ This function takes a list of PCI resources that need to be
+ reallocated and returns &s.code;NULL&e.code when all relocations are
+ successful.
+ &s.code;xf86RegisterResources()&e.code; should be called again to
+ register the relocated resources with the broker.
+ If the reallocation fails, a list of the resources that could not be
+ relocated is returned.
+
+ </quote>
+ </quote>
+
+Two functions are provided to obtain a resource range of a given type:
+ <quote><p>
+ &s.code;resRange xf86GetBlock(long type, memType size,
+ &f.indent;memType window_start, memType window_end,
+ &f.indent;memType align_mask, resPtr avoid)&e.code;
+ <quote><p>
+ This function tries to find a block range of size
+ &s.code;size&e.code; and type &s.code;type&e.code; in a window
+ bound by &s.code;window_start&e.code; and &s.code;window_end&e.code;
+ with the alignment specified in &s.code;align_mask&e.code;.
+ Optionally a list of resource ranges which should be avoided within
+ the window can be supplied. On failure a zero-length range of
+ type &s.code;ResEnd&e.code; will be returned.
+
+ </quote>
+ &s.code;resRange xf86GetSparse(long type, memType fixed_bits,
+ &f.indent;memType decode_mask, memType address_mask,
+ &f.indent;resPtr avoid)&e.code;
+ <quote><p>
+ This function is like the previous one, but attempts to find a
+ sparse range instead of a block range. Here three values have to
+ be specified: the &s.code;address_mask&e.code; which marks all
+ bits of the mask part of the address, the &s.code;decode_mask&e.code;
+ which masks out the bits which are hardcoded and are therefore
+ not available for relocation and the values of the fixed bits.
+ The function tries to find a base that satisfies the given condition.
+ If the function fails it will return a zero range of type
+ &s.code;ResEnd&e.code;. Optionally it might be passed a list of
+ resource ranges to avoid.
+
+ </quote>
+ </quote>
+
+Some PCI devices are broken in the sense that they return invalid size
+information for a certain resource. In this case the driver can supply
+the correct size and make sure that the resource range allocated for
+the card is large enough to hold the address range decoded by the card.
+The function &s.code;xf86FixPciResource()&e.code; can be used to do this:
+ <quote><p>
+ &s.code;Bool xf86FixPciResource(int entityIndex, unsigned int prt,
+ &f.indent;CARD32 alignment, long type)&e.code;
+ <quote><p>
+ This function fixes a PCI resource allocation. The
+ &s.code;prt&e.code; parameter contains the number of the PCI base
+ register that needs to be fixed (&s.code;0-5&e.code;, and
+ &s.code;6&e.code; for the BIOS base register). The size is
+ specified by the alignment. Since PCI resources need to span an
+ integral range of size &s.code;2^n&e.code;, the alignment also
+ specifies the number of addresses that will be decoded. If the
+ driver specifies a type mask it can override the default type for
+ PCI resources which is &s.code;ResShared&e.code;. The resource
+ broker needs to know that to find a matching resource range. This
+ function should be called before calling
+ &s.code;xf86RegisterResources()&e.code;. The return value is
+ &s.code;TRUE&e.code; when the function succeeds.
+
+ </quote>
+
+ &s.code;Bool xf86CheckPciMemBase(pciVideoPtr pPci, memType base)&e.code;
+ <quote><p>
+ This function checks that the memory base address specified matches
+ one of the PCI base address register values for the given PCI
+ device. This is mostly used to check that an externally provided
+ base address (e.g., from a config file) matches an actual value
+ allocated to a device.
+
+ </quote>
+ </quote>
+
+The driver may replace the generic access control functions for an entity.
+This is done with the &s.code;xf86SetAccessFuncs()&e.code;:
+ <quote><p>
+ &s.code;void xf86SetAccessFuncs(EntityInfoPtr pEnt,
+ &f.indent;xf86SetAccessFuncPtr funcs,
+ &f.indent;xf86SetAccessFuncPtr oldFuncs)&e.code;
+ <quote><p>
+ with:
+ </quote>
+
+ <verb>
+ typedef struct {
+ xf86AccessPtr mem;
+ xf86AccessPtr io;
+ xf86AccessPtr io_mem;
+ } xf86SetAccessFuncRec, *xf86SetAccessFuncPtr;
+ </verb>
+
+ <quote><p>
+ The driver can pass three functions: one for I/O access, one for
+ memory access and one for combined memory and I/O access. If the
+ memory access and combined access functions are identical the
+ common level assumes that the memory access cannot be controlled
+ independently of I/O access, if the I/O access function and the
+ combined access functions are the same it is assumed that I/O can
+ not be controlled independently. If memory and I/O have to be
+ controlled together all three values should be the same. If a
+ non &s.code;NULL&e.code; value is passed as third argument it is
+ interpreted as an address where to store the old access record.
+ If the third argument is &s.code;NULL&e.code; it will be assumed
+ that the generic access should be enabled before replacing the
+ access functions. Otherwise it will be disabled. The driver may
+ enable them itself using the returned values. It should do this
+ from its replacement access functions as the generic access may
+ be disabled by the common level on certain occasions. If replacement
+ functions are specified they must control all resources of the
+ specific type registered for the entity.
+
+ </quote>
+ </quote>
+
+To find out if a specific resource range conflicts with another
+resource the &s.code;xf86ChkConflict()&e.code; function may be used:
+ <quote><p>
+ &s.code;memType xf86ChkConflict(resRange *rgp, int entityIndex)&e.code;
+ <quote><p>
+ This function checks if the resource range &s.code;rgp&e.code; of
+ for the specified entity conflicts with with another resource.
+ If a conflict is found, the address of the start of the conflict
+ is returned. The return value is zero when there is no conflict.
+
+ </quote>
+ </quote>
+
+The OPERATING state properties of previously registered fixed resources
+can be set with the &s.code;xf86SetOperatingState()&e.code; function:
+ <quote><p>
+ &s.code;resPtr xf86SetOperatingState(resList list, int entityIndex,
+ &f.indent;int mask)&e.code;
+ <quote><p>
+ This function is used to set the status of a resource during
+ OPERATING state. &s.code;list&e.code; holds a list to which
+ &s.code;mask&e.code; is to be applied. The parameter
+ &s.code;mask&e.code; may have the value &s.code;ResUnusedOpr&e.code;
+ and &s.code;ResDisableOpr&e.code;. The first one should be used
+ if a resource isn't used by the driver during OPERATING state
+ although it is decoded by the device, while the latter one indicates
+ that the resource is not decoded during OPERATING state. Note
+ that the resource ranges have to match those specified during
+ registration. If a range has been specified starting at
+ &s.code;A&e.code; and ending at &s.code;B&e.code; and suppose
+ &s.code;C&e.code; us a value satisfying
+ &s.code;A < C < B&e.code; one may not
+ specify the resource range &s.code;(A,B)&e.code; by splitting it
+ into two ranges &s.code;(A,C)&e.code; and &s.code;(C,B)&e.code;.
+
+ </quote>
+ </quote>
+
+The following two functions are provided for special cases:
+ <quote><p>
+ &s.code;void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)&e.code;
+ <quote><p>
+ This function may be used to remove an entity from a screen. This
+ only makes sense if a screen has more than one entity assigned or
+ the screen is to be deleted. No test is made if the screen has
+ any entities left.
+
+ </quote>
+
+ &s.code;void xf86DeallocateResourcesForEntity(int entityIndex, long type)&e.code;
+ <quote><p>
+ This function deallocates all resources of a given type registered
+ for a certain entity from the resource broker list.
+
+ </quote>
+ </quote>
+
+<sect2>ScreenInit Phase
+<p>
+
+All that is required in this phase is to setup the RAC flags. Note that
+it is also permissible to set these flags up in the PreInit phase. The
+RAC flags are held in the &s.code;racIoFlags&e.code; and &s.code;racMemFlags&e.code; fields of the
+&s.code;ScrnInfoRec&e.code; for each screen. They specify which graphics operations
+might require the use of shared resources. This can be specified
+separately for memory and I/O resources. The available flags are defined
+in &s.code;rac/xf86RAC.h&e.code;. They are:
+
+ &s.code;RAC_FB&e.code;
+ <quote>
+ for framebuffer operations (including hw acceleration)
+ </quote>
+ &s.code;RAC_CURSOR&e.code;
+ <quote>
+ for Cursor operations
+ (??? I'm not sure if we need this for SW cursor it depends
+ on which level the sw cursor is drawn)
+ </quote>
+ &s.code;RAC_COLORMAP&e.code;
+ <quote>
+ for colormap operations
+ </quote>
+ &s.code;RAC_VIEWPORT&e.code;
+ <quote>
+ for the call to &s.code;ChipAdjustFrame()&e.code; </quote>
+
+
+The flags are ORed together.
+
+<sect>Config file ``Option'' entries<label id="options">
+<p>
+
+Option entries are permitted in most sections and subsections of the
+config file. There are two forms of option entries:
+
+<descrip>
+<tag>Option "option-name"</tag>
+ A boolean option.
+<tag>Option "option-name" "option-value"</tag>
+ An option with an arbitrary value.
+</descrip>
+
+The option entries are handled by the parser, and a list of the parsed
+options is included with each of the appropriate data structures that
+the drivers have access to. The data structures used to hold the option
+information are opaque to the driver, and a driver must not access the
+option data directly. Instead, the common layer provides a set of
+functions that may be used to access, check and manipulate the option
+data.
+
+First, the low level option handling functions. In most cases drivers
+would not need to use these directly.
+
+ <quote><p>
+ &s.code;pointer xf86FindOption(pointer options, const char *name)&e.code;
+ <quote><p>
+ Takes a list of options and an option name, and returns a handle
+ for the first option entry in the list matching the name. Returns
+ &s.code;NULL&e.code; if no match is found.
+
+ </quote>
+
+ &s.code;char *xf86FindOptionValue(pointer options, const char *name)&e.code;
+ <quote><p>
+ Takes a list of options and an option name, and returns the value
+ associated with the first option entry in the list matching the
+ name. If the matching option has no value, an empty string
+ (&s.code;""&e.code;) is returned. Returns &s.code;NULL&e.code;
+ if no match is found.
+
+ </quote>
+
+ &s.code;void xf86MarkOptionUsed(pointer option)&e.code;
+ <quote><p>
+ Takes a handle for an option, and marks that option as used.
+
+ </quote>
+
+ &s.code;void xf86MarkOptionUsedByName(pointer options, const char *name)&e.code;
+ <quote><p>
+ Takes a list of options and an option name and marks the first
+ option entry in the list matching the name as used.
+
+ </quote>
+ </quote>
+
+
+Next, the higher level functions that most drivers would use.
+ <quote><p>
+ &s.code;void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)&e.code;
+ <quote><p>
+ Collect the options from each of the config file sections used by
+ the screen (&s.code;pScrn&e.code;) and return the merged list as
+ &s.code;pScrn->options&e.code;. This function requires that
+ &s.code;pScrn->confScreen&e.code;, &s.code;pScrn->display&e.code;,
+ &s.code;pScrn->monitor&e.code;,
+ &s.code;pScrn->numEntities&e.code;, and
+ &s.code;pScrn->entityList&e.code; are initialised.
+ &s.code;extraOpts&e.code; may optionally be set to an additional
+ list of options to be combined with the others. The order of
+ precedence for options is &s.code;extraOpts&e.code;, display,
+ confScreen, monitor, device.
+
+ </quote>
+
+ &s.code;void xf86ProcessOptions(int scrnIndex, pointer options,
+ &f.indent;OptionInfoPtr optinfo)&e.code;
+ <quote><p>
+ Processes a list of options according to the information in the
+ array of &s.code;OptionInfoRecs&e.code; (&s.code;optinfo&e.code;).
+ The resulting information is stored in the &s.code;value&e.code;
+ fields of the appropriate &s.code;optinfo&e.code; entries. The
+ &s.code;found&e.code; fields are set to &s.code;TRUE&e.code;
+ when an option with a value of the correct type if found, and
+ &s.code;FALSE&e.code; otherwise. The &s.code;type&e.code; field
+ is used to determine the expected value type for each option.
+ Each option in the list of options for which there is a name match
+ (but not necessarily a value type match) is marked as used.
+ Warning messages are printed when option values don't match the
+ types specified in the optinfo data.
+
+ NOTE: If this function is called before a driver's screen number
+ is known (e.g., from the &s.code;ChipProbe()&e.code; function) a
+ &s.code;scrnIndex&e.code; value of &s.code;-1&e.code; should be
+ used.
+
+ NOTE 2: Given that this function stores into the
+ &s.code;OptionInfoRecs&e.code; pointed to by &s.code;optinfo&e.code,
+ the caller should ensure the &s.code;OptionInfoRecs&e.code; are
+ (re-)initialised before the call, especially if the caller expects
+ to use the predefined option values as defaults.
+
+ The &s.code;OptionInfoRec&e.code; is defined as follows:
+
+ <verb>
+ typedef struct {
+ double freq;
+ int units;
+ } OptFrequency;
+
+ typedef union {
+ unsigned long num;
+ char * str;
+ double realnum;
+ Bool bool;
+ OptFrequency freq;
+ } ValueUnion;
+
+ typedef enum {
+ OPTV_NONE = 0,
+ OPTV_INTEGER,
+ OPTV_STRING, /* a non-empty string */
+ OPTV_ANYSTR, /* Any string, including an empty one */
+ OPTV_REAL,
+ OPTV_BOOLEAN,
+ OPTV_PERCENT,
+ OPTV_FREQ
+ } OptionValueType;
+
+ typedef enum {
+ OPTUNITS_HZ = 1,
+ OPTUNITS_KHZ,
+ OPTUNITS_MHZ
+ } OptFreqUnits;
+
+ typedef struct {
+ int token;
+ const char* name;
+ OptionValueType type;
+ ValueUnion value;
+ Bool found;
+ } OptionInfoRec, *OptionInfoPtr;
+ </verb>
+
+ &s.code;OPTV_FREQ&e.code; can be used for options values that are
+ frequencies. These values are a floating point number with an
+ optional unit name appended. The unit name can be one of "Hz",
+ "kHz", "k", "MHz", "M". The multiplier associated with the unit
+ is stored in &s.code;freq.units&e.code;, and the scaled frequency
+ is stored in &s.code;freq.freq&e.code;. When no unit is specified,
+ &s.code;freq.units&e.code; is set to &s.code;0&e.code;, and
+ &s.code;freq.freq&e.code; is unscaled.
+
+ &s.code;OPTV_PERCENT&e.code; can be used for option values that are
+ specified in percent (e.g. "20%"). These values are a floating point
+ number with a percent sign appended. If the percent sign is missing,
+ the parser will fail to match the value.
+
+ Typical usage is to setup an array of
+ &s.code;OptionInfoRecs&e.code; with all fields initialised.
+ The &s.code;value&e.code; and &s.code;found&e.code; fields get
+ set by &s.code;xf86ProcessOptions()&e.code;. For cases where the
+ value parsing is more complex, the driver should specify
+ &s.code;OPTV_STRING&e.code;, and parse the string itself. An
+ example of using this option handling is included in the
+ <ref id="sample" name="Sample Driver"> section.
+
+ </quote>
+
+ &s.code;void xf86ShowUnusedOptions(int scrnIndex, pointer options)&e.code;
+ <quote><p>
+ Prints out warning messages for each option in the list of options
+ that isn't marked as used. This is intended to show options that
+ the driver hasn't recognised. It would normally be called near
+ the end of the &s.code;ChipScreenInit()&e.code; function, but only
+ when &s.code;serverGeneration == 1&e.code;.
+
+ </quote>
+
+ &s.code;OptionInfoPtr xf86TokenToOptinfo(const OptionInfoRec *table,
+ &f.indent;int token)&e.code;
+
+ <quote><p>
+ Returns a pointer to the &s.code;OptionInfoRec&e.code; in
+ &s.code;table&e.code; with a token field matching
+ &s.code;token&e.code;. Returns &s.code;NULL&e.code; if no match
+ is found.
+
+ </quote>
+
+ &s.code;Bool xf86IsOptionSet(const OptionInfoRec *table, int token)&e.code;
+ <quote><p>
+ Returns the &s.code;found&e.code; field of the
+ &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; with a
+ &s.code;token&e.code; field matching &s.code;token&e.code;. This
+ can be used for options of all types. Note that for options of
+ type &s.code;OPTV_BOOLEAN&e.code;, it isn't sufficient to check
+ this to determine the value of the option. Returns
+ &s.code;FALSE&e.code; if no match is found.
+
+ </quote>
+
+ &s.code;char *xf86GetOptValString(const OptionInfoRec *table, int token)&e.code;
+ <quote><p>
+ Returns the &s.code;value.str&e.code; field of the
+ &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; with a
+ token field matching &s.code;token&e.code;. Returns
+ &s.code;NULL&e.code; if no match is found.
+
+ </quote>
+
+ &s.code;Bool xf86GetOptValInteger(const OptionInfoRec *table, int token,
+ &f.indent;int *value)&e.code;
+ <quote><p>
+ Returns via &s.code;*value&e.code; the &s.code;value.num&e.code;
+ field of the &s.code;OptionInfoRec&e.code; in &s.code;table&e.code;
+ with a &s.code;token&e.code; field matching &s.code;token&e.code;.
+ &s.code;*value&e.code; is only changed when a match is found so
+ it can be safely initialised with a default prior to calling this
+ function. The function return value is as for
+ &s.code;xf86IsOptionSet()&e.code;.
+
+ </quote>
+
+ &s.code;Bool xf86GetOptValULong(const OptionInfoRec *table, int token,
+ &f.indent;unsigned long *value)&e.code;
+ <quote><p>
+ Like &s.code;xf86GetOptValInteger()&e.code;, except the value is
+ treated as an &s.code;unsigned long&e.code;.
+
+ </quote>
+
+ &s.code;Bool xf86GetOptValReal(const OptionInfoRec *table, int token,
+ &f.indent;double *value)&e.code;
+ <quote><p>
+ Like &s.code;xf86GetOptValInteger()&e.code;, except that
+ &s.code;value.realnum&e.code; is used.
+
+ </quote>
+
+ &s.code;Bool xf86GetOptValFreq(const OptionInfoRec *table, int token,
+ &f.indent;OptFreqUnits expectedUnits, double *value)&e.code;
+ <quote><p>
+ Like &s.code;xf86GetOptValInteger()&e.code;, except that the
+ &s.code;value.freq&e.code; data is returned. The frequency value
+ is scaled to the units indicated by &s.code;expectedUnits&e.code;.
+ The scaling is exact when the units were specified explicitly in
+ the option's value. Otherwise, the &s.code;expectedUnits&e.code;
+ field is used as a hint when doing the scaling. In this case,
+ values larger than &s.code;1000&e.code; are assumed to have be
+ specified in the next smallest units. For example, if the Option
+ value is "10000" and expectedUnits is &s.code;OPTUNITS_MHZ&e.code;,
+ the value returned is &s.code;10&e.code;.
+
+ </quote>
+
+ &s.code;Bool xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value)&e.code;
+ <quote><p>
+ This function is used to check boolean options
+ (&s.code;OPTV_BOOLEAN&e.code;). If the function return value is
+ &s.code;FALSE&e.code;, it means the option wasn't set. Otherwise
+ &s.code;*value&e.code; is set to the boolean value indicated by
+ the option's value. No option &s.code;value&e.code; is interpreted
+ as &s.code;TRUE&e.code;. Option values meaning &s.code;TRUE&e.code;
+ are "1", "yes", "on", "true", and option values meaning
+ &s.code;FALSE&e.code; are "0", "no", "off", "false". Option names
+ both with the "no" prefix in their names, and with that prefix
+ removed are also checked and handled in the obvious way.
+ &s.code;*value&e.code; is not changed when the option isn't present.
+ It should normally be set to a default value before calling this
+ function.
+
+ </quote>
+
+ &s.code;Bool xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def)&e.code;
+ <quote><p>
+ This function is used to check boolean options
+ (&s.code;OPTV_BOOLEAN&e.code;). If the option is set, its value
+ is returned. If the options is not set, the default value specified
+ by &s.code;def&e.code; is returned. The option interpretation is
+ the same as for &s.code;xf86GetOptValBool()&e.code;.
+
+ </quote>
+
+ &s.code;int xf86NameCmp(const char *s1, const char *s2)&e.code;
+ <quote><p>
+ This function should be used when comparing strings from the config
+ file with expected values. It works like &s.code;strcmp()&e.code;,
+ but is not case sensitive and space, tab, and `<tt>_</tt>' characters
+ are ignored in the comparison. The use of this function isn't
+ restricted to parsing option values. It may be used anywhere
+ where this functionality required.
+
+ </quote>
+ </quote>
+
+<sect>Modules, Drivers, Include Files and Interface Issues
+<p>
+
+NOTE: this section is incomplete.
+
+
+<sect1>Include files
+<p>
+
+The following include files are typically required by video drivers:
+
+ <quote><p>
+ All drivers should include these:
+ <quote>
+ &s.code;"xf86.h"&nl;
+ "xf86_OSproc.h"&nl;
+ "xf86_ansic.h"&nl;
+ "xf86Resources.h"&e.code;
+ </quote>
+ Wherever inb/outb (and related things) are used the following should be
+ included:
+ <quote>
+ &s.code;"compiler.h"&e.code;
+ </quote>
+ Note: in drivers, this must be included after &s.code;"xf86_ansic.h"&e.code;.
+
+ Drivers that need to access PCI vendor/device definitions need this:
+ <quote>
+ &s.code;"xf86PciInfo.h"&e.code;
+ </quote>
+
+ Drivers that need to access the PCI config space need this:
+ <quote>
+ &s.code;"xf86Pci.h"&e.code;
+ </quote>
+
+ Drivers that initialise a SW cursor need this:
+ <quote>
+ &s.code;"mipointer.h"&e.code;
+ </quote>
+
+ All drivers implementing backing store need this:
+ <quote>
+ &s.code;"mibstore.h"&e.code;
+ </quote>
+
+ All drivers using the mi colourmap code need this:
+ <quote>
+ &s.code;"micmap.h"&e.code;
+ </quote>
+
+ If a driver uses the vgahw module, it needs this:
+ <quote>
+ &s.code;"vgaHW.h"&e.code;
+ </quote>
+
+ Drivers supporting VGA or Hercules monochrome screens need:
+ <quote>
+ &s.code;"xf1bpp.h"&e.code;
+ </quote>
+
+ Drivers supporting VGA or EGC 16-colour screens need:
+ <quote>
+ &s.code;"xf4bpp.h"&e.code;
+ </quote>
+
+ Drivers using cfb need:
+ <quote>
+ &s.code;#define PSZ 8&nl;
+ #include "cfb.h"&nl;
+ #undef PSZ&e.code;
+ </quote>
+
+ Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
+ <quote>
+ &s.code;"cfb16.h"&nl;
+ "cfb24.h"&nl;
+ "cfb32.h"&e.code;
+ </quote>
+
+ If a driver uses XAA, it needs these:
+ <quote>
+ &s.code;"xaa.h"&nl;
+ "xaalocal.h"&e.code;
+ </quote>
+
+ If a driver uses the fb manager, it needs this:
+ <quote>
+ &s.code;"xf86fbman.h"&e.code;
+ </quote>
+ </quote>
+
+Non-driver modules should include &s.code;"xf86_ansic.h"&e.code; to get the correct
+wrapping of ANSI C/libc functions.
+
+All modules must NOT include any system include files, or the following:
+
+ <quote>
+ &s.code;"xf86Priv.h"&nl;
+ "xf86Privstr.h"&nl;
+ "xf86_OSlib.h"&nl;
+ "Xos.h"&e.code;
+ </quote>
+
+In addition, "xf86_libc.h" must not be included explicitly. It is
+included implicitly by "xf86_ansic.h".
+
+
+<sect>Offscreen Memory Manager
+<p>
+
+Management of offscreen video memory may be handled by the XFree86
+framebuffer manager. Once the offscreen memory manager is running,
+drivers or extensions may allocate, free or resize areas of offscreen
+video memory using the following functions (definitions taken from
+&s.code;xf86fbman.h&e.code;):
+
+<code>
+ typedef struct _FBArea {
+ ScreenPtr pScreen;
+ BoxRec box;
+ int granularity;
+ void (*MoveAreaCallback)(struct _FBArea*, struct _FBArea*)
+ void (*RemoveAreaCallback)(struct _FBArea*)
+ DevUnion devPrivate;
+ } FBArea, *FBAreaPtr;
+
+ typedef void (*MoveAreaCallbackProcPtr)(FBAreaPtr from, FBAreaPtr to)
+ typedef void (*RemoveAreaCallbackProcPtr)(FBAreaPtr)
+
+ FBAreaPtr xf86AllocateOffscreenArea (
+ ScreenPtr pScreen,
+ int width, int height,
+ int granularity,
+ MoveAreaCallbackProcPtr MoveAreaCallback,
+ RemoveAreaCallbackProcPtr RemoveAreaCallback,
+ pointer privData
+ )
+
+ void xf86FreeOffscreenArea (FBAreaPtr area)
+
+ Bool xf86ResizeOffscreenArea (
+ FBAreaPtr area
+ int w, int h
+ )
+</code>
+
+The function:
+<quote>
+ &s.code;Bool xf86FBManagerRunning(ScreenPtr pScreen)&e.code;
+</quote>
+
+can be used by an extension to check if the driver has initialized
+the memory manager. The manager is not available if this returns
+&s.code;FALSE&e.code; and the functions above will all fail.
+
+
+&s.code;xf86AllocateOffscreenArea()&e.code; can be used to request a
+rectangle of dimensions &s.code;width&e.code; x &s.code;height&e.code;
+(in pixels) from unused offscreen memory. &s.code;granularity&e.code;
+specifies that the leftmost edge of the rectangle must lie on some
+multiple of &s.code;granularity&e.code; pixels. A granularity of zero
+means the same thing as a granularity of one - no alignment preference.
+A &s.code;MoveAreaCallback&e.code; can be provided to notify the requester
+when the offscreen area is moved. If no &s.code;MoveAreaCallback&e.code;
+is supplied then the area is considered to be immovable. The
+&s.code;privData&e.code; field will be stored in the manager's internal
+structure for that allocated area and will be returned to the requester
+in the &s.code;FBArea&e.code; passed via the
+&s.code;MoveAreaCallback&e.code;. An optional
+&s.code;RemoveAreaCallback&e.code; is provided. If the driver provides
+this it indicates that the area should be allocated with a lower priority.
+Such an area may be removed when a higher priority request (one that
+doesn't have a &s.code;RemoveAreaCallback&e.code;) is made. When this
+function is called, the driver will have an opportunity to do whatever
+cleanup it needs to do to deal with the loss of the area, but it must
+finish its cleanup before the function exits since the offscreen memory
+manager will free the area immediately after.
+
+&s.code;xf86AllocateOffscreenArea()&e.code; returns &s.code;NULL&e.code;
+if it was unable to allocate the requested area. When no longer needed,
+areas should be freed with &s.code;xf86FreeOffscreenArea()&e.code;.
+
+&s.code;xf86ResizeOffscreenArea()&e.code; resizes an existing
+&s.code;FBArea&e.code;. &s.code;xf86ResizeOffscreenArea()&e.code;
+returns &s.code;TRUE&e.code; if the resize was successful. If
+&s.code;xf86ResizeOffscreenArea()&e.code; returns &s.code;FALSE&e.code;,
+the original &s.code;FBArea&e.code; is left unmodified. Resizing an
+area maintains the area's original &s.code;granularity&e.code;,
+&s.code;devPrivate&e.code;, and &s.code;MoveAreaCallback&e.code;.
+&s.code;xf86ResizeOffscreenArea()&e.code; has considerably less overhead
+than freeing the old area then reallocating the new size, so it should
+be used whenever possible.
+
+The function:
+ <quote>
+ &s.code;Bool xf86QueryLargestOffscreenArea(
+ &f.indent;ScreenPtr pScreen,
+ &f.indent;int *width, int *height,
+ &f.indent;int granularity,
+ &f.indent;int preferences,
+ &f.indent;int priority
+ &nl)&e.code;
+ </quote>
+
+is provided to query the width and height of the largest single
+&s.code;FBArea&e.code; allocatable given a particular priority.
+&s.code;preferences&e.code; can be one of the following to indicate
+whether width, height or area should be considered when determining
+which is the largest single &s.code;FBArea&e.code; available.
+
+ <quote>
+ &s.code;FAVOR_AREA_THEN_WIDTH&nl;
+ FAVOR_AREA_THEN_HEIGHT&nl;
+ FAVOR_WIDTH_THEN_AREA&nl;
+ FAVOR_HEIGHT_THEN_AREA&e.code;
+ </quote>
+
+&s.code;priority&e.code; is one of the following:
+
+ <quote><p>
+ &s.code;PRIORITY_LOW&e.code;
+ <quote><p>
+ Return the largest block available without stealing anyone else's
+ space. This corresponds to the priority of allocating a
+ &s.code;FBArea&e.code; when a &s.code;RemoveAreaCallback&e.code;
+ is provided.
+
+ </quote>
+ &s.code;PRIORITY_NORMAL&e.code;
+ <quote><p>
+ Return the largest block available if it is acceptable to steal a
+ lower priority area from someone. This corresponds to the priority
+ of allocating a &s.code;FBArea&e.code; without providing a
+ &s.code;RemoveAreaCallback&e.code;.
+
+ </quote>
+ &s.code;PRIORITY_EXTREME&e.code;
+ <quote><p>
+ Return the largest block available if all &s.code;FBAreas&e.code;
+ that aren't locked down were expunged from memory first. This
+ corresponds to any allocation made directly after a call to
+ &s.code;xf86PurgeUnlockedOffscreenAreas()&e.code;.
+
+ </quote>
+ </quote>
+
+
+The function:
+
+ <quote>
+ &s.code;Bool xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen)&e.code;
+ </quote>
+
+is provided as an extreme method to free up offscreen memory. This
+will remove all removable &s.code;FBArea&e.code; allocations.
+
+
+Initialization of the XFree86 framebuffer manager is done via
+
+ <quote>
+ &s.code;Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox)&e.code;
+ </quote>
+
+&s.code;FullBox&e.code; represents the area of the framebuffer that the
+manager is allowed to manage. This is typically a box with a width of
+&s.code;pScrn->displayWidth&e.code; and a height of as many lines as
+can be fit within the total video memory, however, the driver can reserve
+areas at the extremities by passing a smaller area to the manager.
+
+&s.code;xf86InitFBManager()&e.code; must be called before XAA is
+initialized since XAA uses the manager for it's pixmap cache.
+
+An alternative function is provided to allow the driver to initialize
+the framebuffer manager with a Region rather than a box.
+
+ <quote>
+ &s.code;Bool xf86InitFBManagerRegion(ScreenPtr pScreen,
+ &f.indent;RegionPtr FullRegion)&e.code;
+ </quote>
+
+&s.code;xf86InitFBManagerRegion()&e.code;, unlike
+&s.code;xf86InitFBManager()&e.code;, does not remove the area used for
+the visible screen so that area should not be included in the region
+passed to the function. &s.code;xf86InitFBManagerRegion()&e.code; is
+useful when non-contiguous areas are available to be managed, and is
+required when multiple framebuffers are stored in video memory (as in
+the case where an overlay of a different depth is stored as a second
+framebuffer in offscreen memory).
+
+
+<sect>Colormap Handling<label id="cmap">
+<p>
+
+A generic colormap handling layer is provided within the XFree86 common
+layer. This layer takes care of most of the details, and only requires
+a function from the driver that loads the hardware palette when required.
+To use the colormap layer, a driver calls the
+&s.code;xf86HandleColormaps()&e.code; function.
+
+ <quote><p>
+ &s.code;Bool xf86HandleColormaps(ScreenPtr pScreen, int maxColors,
+ &f.indent;int sigRGBbits, LoadPaletteFuncPtr loadPalette,
+ &f.indent;SetOverscanFuncPtr setOverscan,
+ unsigned int flags)&e.code;
+ <quote><p>
+ This function must be called after the default colormap has been
+ initialised. The &s.code;pScrn->gamma&e.code; field must also
+ be initialised, preferably by calling &s.code;xf86SetGamma()&e.code;.
+ &s.code;maxColors&e.code; is the number of entries in the palette.
+ &s.code;sigRGBbits&e.code; is the size in bits of each color
+ component in the DAC's palette. &s.code;loadPalette&e.code;
+ is a driver-provided function for loading a colormap into the
+ hardware, and is described below. &s.code;setOverscan&e.code; is
+ an optional function that may be provided when the overscan color
+ is an index from the standard LUT and when it needs to be adjusted
+ to keep it as close to black as possible. The
+ &s.code;setOverscan&e.code; function programs the overscan index.
+ It shouldn't normally be used for depths other than 8.
+ &s.code;setOverscan&e.code; should be set to &s.code;NULL&e.code;
+ when it isn't needed. &s.code;flags&e.code; may be set to the
+ following (which may be ORed together):
+
+ &s.code;CMAP_PALETTED_TRUECOLOR&e.code;
+ <quote><p>
+ the TrueColor visual is paletted and is
+ just a special case of DirectColor.
+ This flag is only valid for
+ &s.code;bpp > 8&e.code;.
+
+ </quote>
+
+ &s.code;CMAP_RELOAD_ON_MODE_SWITCH&e.code;
+ <quote><p>
+ reload the colormap automatically
+ after mode switches. This is useful
+ for when the driver is resetting the
+ hardware during mode switches and
+ corrupting or erasing the hardware
+ palette.
+
+ </quote>
+
+ &s.code;CMAP_LOAD_EVEN_IF_OFFSCREEN&e.code;
+ <quote><p>
+ reload the colormap even if the screen
+ is switched out of the server's VC.
+ The palette is <it>not</it> reloaded when
+ the screen is switched back in, nor after
+ mode switches. This is useful when the
+ driver needs to keep track of palette
+ changes.
+
+ </quote>
+
+ The colormap layer normally reloads the palette after VT enters so it
+ is not necessary for the driver to save and restore the palette
+ when switching VTs. The driver must, however, still save the
+ initial palette during server start up and restore it during
+ server exit.
+
+ </quote>
+
+ &s.code;void LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ &f.indent;LOCO *colors, VisualPtr pVisual)&e.code;
+ <quote><p>
+ &s.code;LoadPalette()&e.code; is a driver-provided function for
+ loading a colormap into hardware. &s.code;colors&e.code; is the
+ array of RGB values that represent the full colormap.
+ &s.code;indices&e.code; is a list of index values into the colors
+ array. These indices indicate the entries that need to be updated.
+ &s.code;numColors&e.code; is the number of the indices to be
+ updated.
+
+ </quote>
+
+ &s.code;void SetOverscan(ScrnInfoPtr pScrn, int overscan)&e.code;
+ <quote><p>
+ &s.code;SetOverscan()&e.code; is a driver-provided function for
+ programming the &s.code;overscan&e.code; index. As described
+ above, it is normally only appropriate for LUT modes where all
+ colormap entries are available for the display, but where one of
+ them is also used for the overscan (typically 8bpp for VGA compatible
+ LUTs). It isn't required in cases where the overscan area is
+ never visible.
+
+ </quote>
+ </quote>
+
+
+<sect>DPMS Extension
+<p>
+
+Support code for the DPMS extension is included in the XFree86 common layer.
+This code provides an interface between the main extension code, and a means
+for drivers to initialise DPMS when they support it. One function is
+available to drivers to do this initialisation, and it is always available,
+even when the DPMS extension is not supported by the core server (in
+which case it returns a failure result).
+
+
+ <quote><p>
+ &s.code;Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)&e.code;
+ <quote><p>
+ This function registers a driver's DPMS level programming function
+ &s.code;set&e.code;. It also checks
+ &s.code;pScrn->options&e.code; for the "dpms" option, and when
+ present marks DPMS as being enabled for that screen. The
+ &s.code;set&e.code; function is called whenever the DPMS level
+ changes, and is used to program the requested level.
+ &s.code;flags&e.code; is currently not used, and should be
+ &s.code;0&e.code;. If the initialisation fails for any reason,
+ including when there is no DPMS support in the core server, the
+ function returns &s.code;FALSE&e.code;.
+
+ </quote>
+ </quote>
+
+
+Drivers that implement DPMS support must provide the following function,
+that gets called when the DPMS level is changed:
+
+
+ <quote><p>
+ &s.code;void ChipDPMSSet(ScrnInfoPtr pScrn, int level, int flags)&e.code;
+ <quote><p>
+ Program the DPMS level specified by &s.code;level&e.code;. Valid
+ values of &s.code;level&e.code; are &s.code;DPMSModeOn&e.code;,
+ &s.code;DPMSModeStandby&e.code;, &s.code;DPMSModeSuspend&e.code;,
+ &s.code;DPMSModeOff&e.code;. These values are defined in
+ &s.code;"extensions/dpms.h"&e.code;.
+
+ </quote>
+ </quote>
+
+
+<sect>DGA Extension
+<p>
+
+Drivers can support the XFree86 Direct Graphics Architecture (DGA) by
+filling out a structure of function pointers and a list of modes and
+passing them to DGAInit.
+
+ <quote><p>
+ &s.code;Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs,
+ &f.indent;DGAModePtr modes, int num)&e.code;
+ <quote><p>
+ <verb>
+/** The DGAModeRec **/
+
+typedef struct {
+ int num;
+ DisplayModePtr mode;
+ int flags;
+ int imageWidth;
+ int imageHeight;
+ int pixmapWidth;
+ int pixmapHeight;
+ int bytesPerScanline;
+ int byteOrder;
+ int depth;
+ int bitsPerPixel;
+ unsigned long red_mask;
+ unsigned long green_mask;
+ unsigned long blue_mask;
+ int viewportWidth;
+ int viewportHeight;
+ int xViewportStep;
+ int yViewportStep;
+ int maxViewportX;
+ int maxViewportY;
+ int viewportFlags;
+ int offset;
+ unsigned char *address;
+ int reserved1;
+ int reserved2;
+} DGAModeRec, *DGAModePtr;
+</verb>
+
+ &s.code;num&e.code;
+ <quote>
+ Can be ignored. The DGA DDX will assign these numbers.
+ </quote>
+
+ &s.code;mode&e.code;
+ <quote>
+ A pointer to the &s.code;DisplayModeRec&e.code; for this mode.
+ </quote>
+
+ &s.code;flags&e.code;
+ <quote><p>
+ The following flags are defined and may be OR'd together:
+
+ &s.code;DGA_CONCURRENT_ACCESS&e.code;
+ <quote><p>
+ Indicates that the driver supports concurrent graphics
+ accelerator and linear framebuffer access.
+
+ </quote>
+
+ &s.code;DGA_FILL_RECT&nl;
+ DGA_BLIT_RECT&nl;
+ DGA_BLIT_RECT_TRANS&e.code;
+ <quote><p>
+ Indicates that the driver supports the FillRect, BlitRect
+ or BlitTransRect functions in this mode.
+
+ </quote>
+
+ &s.code;DGA_PIXMAP_AVAILABLE&e.code;
+ <quote><p>
+ Indicates that Xlib may be used on the framebuffer.
+ This flag will usually be set unless the driver wishes
+ to prohibit this for some reason.
+
+ </quote>
+
+ &s.code;DGA_INTERLACED&nl;
+ DGA_DOUBLESCAN&e.code;
+ <quote><p>
+ Indicates that these are interlaced or double scan modes.
+
+ </quote>
+ </quote>
+
+ &s.code;imageWidth&nl;
+ imageHeight&e.code;
+ <quote><p>
+ These are the dimensions of the linear framebuffer
+ accessible by the client.
+
+ </quote>
+
+ &s.code;pixmapWidth&nl;
+ pixmapHeight&e.code;
+ <quote><p>
+ These are the dimensions of the area of the
+ framebuffer accessible by the graphics accelerator.
+
+ </quote>
+
+ &s.code;bytesPerScanline&e.code;
+ <quote><p>
+ Pitch of the framebuffer in bytes.
+
+ </quote>
+
+ &s.code;byteOrder&e.code;
+ <quote><p>
+ Usually the same as
+ &s.code;pScrn->imageByteOrder&e.code;.
+
+ </quote>
+
+ &s.code;depth&e.code;
+ <quote><p>
+ The depth of the framebuffer in this mode.
+
+ </quote>
+
+ &s.code;bitsPerPixel&e.code;
+ <quote><p>
+ The number of bits per pixel in this mode.
+
+ </quote>
+
+ &s.code;red_mask&nl;
+ green_mask&nl;
+ blue_mask&e.code;
+ <quote><p>
+ The RGB masks for this mode, if applicable.
+
+ </quote>
+
+ &s.code;viewportWidth&nl;
+ viewportHeight&e.code;
+ <quote><p>
+ Dimensions of the visible part of the framebuffer.
+ Usually &s.code;mode->HDisplay&e.code; and
+ &s.code;mode->VDisplay&e.code;.
+
+ </quote>
+
+ &s.code;xViewportStep&nl;
+ yViewportStep&e.code;
+ <quote><p>
+ The granularity of x and y viewport positions that
+ the driver supports in this mode.
+
+ </quote>
+
+ &s.code;maxViewportX&nl;
+ maxViewportY&e.code;
+ <quote><p>
+ The maximum viewport position supported by the
+ driver in this mode.
+
+ </quote>
+
+ &s.code;viewportFlags&e.code;
+ <quote><p>
+ The following may be OR'd together:
+
+ &s.code;DGA_FLIP_IMMEDIATE&e.code;
+ <quote><p>
+ The driver supports immediate viewport changes.
+
+ </quote>
+ &s.code;DGA_FLIP_RETRACE&e.code;
+ <quote<p>
+ The driver supports viewport changes at retrace.
+
+ </quote>
+ </quote>
+
+ &s.code;offset&e.code;
+ <quote><p>
+ The offset into the linear framebuffer that corresponds to
+ pixel (0,0) for this mode.
+
+ </quote>
+
+ &s.code;address&e.code;
+ <quote><p>
+ The virtual address of the framebuffer as mapped by the driver.
+ This is needed when DGA_PIXMAP_AVAILABLE is set.
+
+ </quote>
+
+ <verb>
+/** The DGAFunctionRec **/
+
+typedef struct {
+ Bool (*OpenFramebuffer)(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *extra
+ );
+ void (*CloseFramebuffer)(ScrnInfoPtr pScrn);
+ Bool (*SetMode)(ScrnInfoPtr pScrn, DGAModePtr pMode);
+ void (*SetViewport)(ScrnInfoPtr pScrn, int x, int y, int flags);
+ int (*GetViewport)(ScrnInfoPtr pScrn);
+ void (*Sync)(ScrnInfoPtr);
+ void (*FillRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+ );
+ void (*BlitRect)(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+ );
+ void (*BlitTransRect)(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+ );
+} DGAFunctionRec, *DGAFunctionPtr;
+</verb>
+
+ </quote>
+
+ &s.code;Bool OpenFramebuffer (pScrn, name, mem, size, offset, extra)&e.code;
+ <quote><p>
+ &s.code;OpenFramebuffer()&e.code; should pass the client everything
+ it needs to know to be able to open the framebuffer. These
+ parameters are OS specific and their meanings are to be interpreted
+ by an OS specific client library.
+
+ &s.code;name&e.code;
+ <quote><p>
+ The name of the device to open or &s.code;NULL&e.code; if
+ there is no special device to open. A &s.code;NULL&e.code;
+ name tells the client that it should open whatever device
+ one would usually open to access physical memory.
+
+ </quote>
+ &s.code;mem&e.code;
+ <quote><p>
+ The physical address of the start of the framebuffer.
+
+ </quote>
+ &s.code;size&e.code;
+ <quote><p>
+ The size of the framebuffer in bytes.
+
+ </quote>
+ &s.code;offset&e.code;
+ <quote><p>
+ Any offset into the device, if applicable.
+
+ </quote>
+ &s.code;flags&e.code;
+ <quote><p>
+ Any additional information that the client may need.
+ Currently, only the &s.code;DGA_NEED_ROOT&e.code; flag is
+ defined.
+
+ </quote>
+ </quote>
+
+ &s.code;void CloseFramebuffer (pScrn)&e.code;
+ <quote><p>
+ &s.code;CloseFramebuffer()&e.code; merely informs the driver (if it
+ even cares) that client no longer needs to access the framebuffer
+ directly. This function is optional.
+
+ </quote>
+
+ &s.code;Bool SetMode (pScrn, pMode)&e.code;
+ <quote><p>
+ &s.code;SetMode()&e.code; tells the driver to initialize the mode
+ passed to it. If &s.code;pMode&e.code; is &s.code;NULL&e.code;,
+ then the driver should restore the original pre-DGA mode.
+
+ </quote>
+
+ &s.code;void SetViewport (pScrn, x, y, flags)&e.code;
+ <quote><p>
+ &s.code;SetViewport()&e.code; tells the driver to make the upper
+ left-hand corner of the visible screen correspond to coordinate
+ &s.code;(x,y)&e.code; on the framebuffer. &s.code;Flags&e.code;
+ currently defined are:
+
+ &s.code;DGA_FLIP_IMMEDIATE&e.code;
+ <quote><p>
+ The viewport change should occur immediately.
+
+ </quote>
+ &s.code;DGA_FLIP_RETRACE&e.code;
+ <quote><p>
+ The viewport change should occur at the
+ vertical retrace, but this function should
+ return sooner if possible.
+
+ </quote>
+ The &s.code;(x,y)&e.code; locations will be passed as the client
+ specified them, however, the driver is expected to round these
+ locations down to the next supported location as specified by the
+ &s.code;xViewportStep&e.code; and &s.code;yViewportStep&e.code;
+ for the current mode.
+
+ </quote>
+
+ &s.code;int GetViewport (pScrn)&e.code;
+ <quote><p>
+ &s.code;GetViewport()&e.code; gets the current page flip status.
+ Set bits in the returned int correspond to viewport change requests
+ still pending. For instance, set bit zero if the last SetViewport
+ request is still pending, bit one if the one before that is still
+ pending, etc.
+
+ </quote>
+
+ &s.code;void Sync (pScrn)&e.code;
+ <quote><p>
+ This function should ensure that any graphics accelerator operations
+ have finished. This function should not return until the graphics
+ accelerator is idle.
+
+ </quote>
+
+ &s.code;void FillRect (pScrn, x, y, w, h, color)&e.code;
+ <quote><p>
+ This optional function should fill a rectangle
+ &s.code;w × h&e.code; located at
+ &s.code;(x,y)&e.code; in the given color.
+
+ </quote>
+
+ &s.code;void BlitRect (pScrn, srcx, srcy, w, h, dstx, dsty)&e.code;
+ <quote><p>
+ This optional function should copy an area
+ &s.code;w × h&e.code; located at
+ &s.code;(srcx,srcy)&e.code; to location &s.code;(dstx,dsty)&e.code;.
+ This function will need to handle copy directions as appropriate.
+
+ </quote>
+
+ &s.code;void BlitTransRect (pScrn, srcx, srcy, w, h, dstx, dsty, color)&e.code;
+ <quote><p>
+ This optional function is the same as BlitRect except that pixels
+ in the source corresponding to the color key &s.code;color&e.code;
+ should be skipped.
+
+ </quote>
+ </quote>
+
+<sect>The XFree86 X Video Extension (Xv) Device Dependent Layer
+<p>
+
+XFree86 offers the X Video Extension which allows clients to treat video
+as any another primitive and ``Put'' video into drawables. By default,
+the extension reports no video adaptors as being available since the
+DDX layer has not been initialized. The driver can initialize the DDX
+layer by filling out one or more &s.code;XF86VideoAdaptorRecs&e.code;
+as described later in this document and passing a list of
+&s.code;XF86VideoAdaptorPtr&e.code; pointers to the following function:
+
+ <quote>
+ &s.code;Bool xf86XVScreenInit(
+ &f.indent;ScreenPtr pScreen,
+ &f.indent;XF86VideoAdaptorPtr *adaptPtrs,
+ &f.indent;int num)&e.code;
+ </quote>
+
+After doing this, the extension will report video adaptors as being
+available, providing the data in their respective
+&s.code;XF86VideoAdaptorRecs&e.code; was valid.
+&s.code;xf86XVScreenInit()&e.code; <em>copies</em> data from the structure
+passed to it so the driver may free it after the initialization. At
+the moment, the DDX only supports rendering into Window drawables.
+Pixmap rendering will be supported after a sufficient survey of suitable
+hardware is completed.
+
+The &s.code;XF86VideoAdaptorRec&e.code;:
+
+<quote><p>
+<verb>
+typedef struct {
+ unsigned int type;
+ int flags;
+ char *name;
+ int nEncodings;
+ XF86VideoEncodingPtr pEncodings;
+ int nFormats;
+ XF86VideoFormatPtr pFormats;
+ int nPorts;
+ DevUnion *pPortPrivates;
+ int nAttributes;
+ XF86AttributePtr pAttributes;
+ int nImages;
+ XF86ImagePtr pImages;
+ PutVideoFuncPtr PutVideo;
+ PutStillFuncPtr PutStill;
+ GetVideoFuncPtr GetVideo;
+ GetStillFuncPtr GetStill;
+ StopVideoFuncPtr StopVideo;
+ SetPortAttributeFuncPtr SetPortAttribute;
+ GetPortAttributeFuncPtr GetPortAttribute;
+ QueryBestSizeFuncPtr QueryBestSize;
+ PutImageFuncPtr PutImage;
+ QueryImageAttributesFuncPtr QueryImageAttributes;
+} XF86VideoAdaptorRec, *XF86VideoAdaptorPtr;
+</verb>
+
+ Each adaptor will have its own XF86VideoAdaptorRec. The fields are
+ as follows:
+
+ &s.code;type&e.code;
+ <quote><p>
+ This can be any of the following flags OR'd together.
+
+ &s.code;XvInputMask&e.code;
+ &s.code;XvOutputMask&e.code;
+ <quote><p>
+ These refer to the target drawable and are similar to a Window's
+ class. &s.code;XvInputMask&e.code; indicates that the adaptor
+ can put video into a drawable. &s.code;XvOutputMask&e.code;
+ indicates that the adaptor can get video from a drawable.
+ </quote>
+
+ &s.code;XvVideoMask&e.code;
+ &s.code;XvStillMask&e.code;
+ &s.code;XvImageMask&e.code;
+ <quote><p>
+ These indicate that the adaptor supports video, still or
+ image primitives respectively.
+ </quote>
+
+ &s.code;XvWindowMask&e.code;
+ &s.code;XvPixmapMask&e.code;
+ <quote><p>
+ These indicate the types of drawables the adaptor is capable
+ of rendering into. At the moment, Pixmap rendering is not
+ supported and the &s.code;XvPixmapMask&e.code; flag is ignored.
+ </quote>
+
+ </quote>
+
+ &s.code;flags&e.code;
+ <quote><p>
+ Currently, the following flags are defined:
+
+ &s.code;VIDEO_NO_CLIPPING&e.code;
+ <quote><p>
+ This indicates that the video adaptor does not support
+ clipping. The driver will never receive ``Put'' requests
+ where less than the entire area determined by
+ &s.code;drw_x&e.code;, &s.code;drw_y&e.code;,
+ &s.code;drw_w&e.code; and &s.code;drw_h&e.code; is visible.
+ This flag does not apply to ``Get'' requests. Hardware
+ that is incapable of clipping ``Gets'' may punt or get
+ the extents of the clipping region passed to it.
+
+ </quote>
+
+ &s.code;VIDEO_INVERT_CLIPLIST&e.code;
+ <quote><p>
+ This indicates that the video driver requires the clip
+ list to contain the regions which are obscured rather
+ than the regions which are are visible.
+
+ </quote>
+
+ &s.code;VIDEO_OVERLAID_STILLS&e.code;
+ <quote><p>
+ Implementing PutStill for hardware that does video as an
+ overlay can be awkward since it's unclear how long to leave
+ the video up for. When this flag is set, StopVideo will be
+ called whenever the destination gets clipped or moved so that
+ the still can be left up until then.
+
+ </quote>
+
+ &s.code;VIDEO_OVERLAID_IMAGES&e.code;
+ <quote><p>
+ Same as &s.code;VIDEO_OVERLAID_STILLS&e.code; but for images.
+ </quote>
+
+ &s.code;VIDEO_CLIP_TO_VIEWPORT&e.code;
+ <quote><p>
+ Indicates that the clip region passed to the driver functions
+ should be clipped to the visible portion of the screen in the
+ case where the viewport is smaller than the virtual desktop.
+ </quote>
+
+ </quote>
+
+ &s.code;name&e.code;
+ <quote><p>
+ The name of the adaptor.
+
+ </quote>
+
+ &s.code;nEncodings&nl;
+ pEncodings&e.code;
+ <quote><p>
+ The number of encodings the adaptor is capable of and pointer
+ to the &s.code;XF86VideoEncodingRec&e.code; array. The
+ &s.code;XF86VideoEncodingRec&e.code; is described later on.
+ For drivers that only support XvImages there should be an encoding
+ named "XV_IMAGE" and the width and height should specify
+ the maximum size source image supported.
+
+ </quote>
+
+ &s.code;nFormats&nl;
+ pFormats&e.code;
+ <quote><p>
+ The number of formats the adaptor is capable of and pointer to
+ the &s.code;XF86VideoFormatRec&e.code; array. The
+ &s.code;XF86VideoFormatRec&e.code; is described later on.
+
+ </quote>
+
+ &s.code;nPorts&nl;
+ pPortPrivates&e.code;
+ <quote><p>
+ The number of ports is the number of separate data streams which
+ the adaptor can handle simultaneously. If you have more than
+ one port, the adaptor is expected to be able to render into more
+ than one window at a time. &s.code;pPortPrivates&e.code; is
+ an array of pointers or ints - one for each port. A port's
+ private data will be passed to the driver any time the port is
+ requested to do something like put the video or stop the video.
+ In the case where there may be many ports, this enables the
+ driver to know which port the request is intended for. Most
+ commonly, this will contain a pointer to the data structure
+ containing information about the port. In Xv, all ports on
+ a particular adaptor are expected to be identical in their
+ functionality.
+
+ </quote>
+
+ &s.code;nAttributes&nl;
+ pAttributes&e.code;
+ <quote><p>
+ The number of attributes recognized by the adaptor and a pointer to
+ the array of &s.code;XF86AttributeRecs&e.code;. The
+ &s.code;XF86AttributeRec&e.code; is described later on.
+
+ </quote>
+
+ &s.code;nImages&nl;
+ pImages&e.code;
+ <quote><p>
+ The number of &s.code;XF86ImageRecs&e.code; supported by the adaptor
+ and a pointer to the array of &s.code;XF86ImageRecs&e.code;. The
+ &s.code;XF86ImageRec&e.code; is described later on.
+
+ </quote>
+
+
+ &s.code;PutVideo PutStill GetVideo GetStill StopVideo
+ SetPortAttribute GetPortAttribute QueryBestSize PutImage
+ QueryImageAttributes&e.code;
+ <quote><p>
+ These functions define the DDX->driver interface. In each
+ case, the pointer &s.code;data&e.code; is passed to the driver.
+ This is the port private for that port as described above. All
+ fields are required except under the following conditions:
+
+ <enum>
+ <item>&s.code;PutVideo&e.code;, &s.code;PutStill&e.code; and
+ the image routines &s.code;PutImage&e.code; and
+ &s.code;QueryImageAttributes&e.code; are not required when the
+ adaptor type does not contain &s.code;XvInputMask&e.code;.
+
+ <item>&s.code;GetVideo&e.code; and &s.code;GetStill&e.code;
+ are not required when the adaptor type does not contain
+ &s.code;XvOutputMask&e.code;.
+
+ <item>&s.code;GetVideo&e.code; and &s.code;PutVideo&e.code;
+ are not required when the adaptor type does not contain
+ &s.code;XvVideoMask&e.code;.
+
+ <item>&s.code;GetStill&e.code; and &s.code;PutStill&e.code;
+ are not required when the adaptor type does not contain
+ &s.code;XvStillMask&e.code;.
+
+ <item>&s.code;PutImage&e.code; and &s.code;QueryImageAttributes&e.code;
+ are not required when the adaptor type does not contain
+ &s.code;XvImageMask&e.code;.
+
+ </enum>
+
+ With the exception of &s.code;QueryImageAttributes&e.code;, these
+ functions should return &s.code;Success&e.code; if the operation was
+ completed successfully. They can return &s.code;XvBadAlloc&e.code;
+ otherwise. &s.code;QueryImageAttributes&e.code; returns the size
+ of the XvImage queried.
+
+ If the &s.code;VIDEO_NO_CLIPPING&e.code;
+ flag is set, the &s.code;clipBoxes&e.code; may be ignored by
+ the driver. &s.code;ClipBoxes&e.code; is an &s.code;X-Y&e.code;
+ banded region identical to those used throughout the server.
+ The clipBoxes represent the visible portions of the area determined
+ by &s.code;drw_x&e.code;, &s.code;drw_y&e.code;,
+ &s.code;drw_w&e.code; and &s.code;drw_h&e.code; in the Get/Put
+ function. The boxes are in screen coordinates, are guaranteed
+ not to overlap and an empty region will never be passed.
+ If the driver has specified &s.code;VIDEO_INVERT_CLIPLIST&e.code;,
+ &s.code;clipBoxes&e.code; will indicate the areas of the primitive
+ which are obscured rather than the areas visible.
+
+ </quote>
+
+ &s.code;typedef int (* PutVideoFuncPtr)( ScrnInfoPtr pScrn,
+ &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
+ &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
+ &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
+ <quote><p>
+ This indicates that the driver should take a subsection
+ &s.code;vid_w&e.code; by &s.code;vid_h&e.code; at location
+ &s.code;(vid_x,vid_y)&e.code; from the video stream and direct
+ it into the rectangle &s.code;drw_w&e.code; by &s.code;drw_h&e.code;
+ at location &s.code;(drw_x,drw_y)&e.code; on the screen, scaling as
+ necessary. Due to the large variations in capabilities of
+ the various hardware expected to be used with this extension,
+ it is not expected that all hardware will be able to do this
+ exactly as described. In that case the driver should just do
+ ``the best it can,'' scaling as closely to the target rectangle
+ as it can without rendering outside of it. In the worst case,
+ the driver can opt to just not turn on the video.
+
+ </quote>
+
+ &s.code;typedef int (* PutStillFuncPtr)( ScrnInfoPtr pScrn,
+ &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
+ &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
+ &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
+ <quote><p>
+ This is same as &s.code;PutVideo&e.code; except that the driver
+ should place only one frame from the stream on the screen.
+
+ </quote>
+
+ &s.code;typedef int (* GetVideoFuncPtr)( ScrnInfoPtr pScrn,
+ &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
+ &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
+ &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
+ <quote><p>
+ This is same as &s.code;PutVideo&e.code; except that the driver
+ gets video from the screen and outputs it. The driver should
+ do the best it can to get the requested dimensions correct
+ without reading from an area larger than requested.
+
+ </quote>
+
+ &s.code;typedef int (* GetStillFuncPtr)( ScrnInfoPtr pScrn,
+ &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
+ &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
+ &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
+ <quote><p>
+ This is the same as &s.code;GetVideo&e.code; except that the
+ driver should place only one frame from the screen into the
+ output stream.
+
+ </quote>
+
+ &s.code;typedef void (* StopVideoFuncPtr)(ScrnInfoPtr pScrn,
+ &f.indent;pointer data, Bool cleanup)&e.code;
+ <quote><p>
+ This indicates the driver should stop displaying the video.
+ This is used to stop both input and output video. The
+ &s.code;cleanup&e.code; field indicates that the video is
+ being stopped because the client requested it to stop or
+ because the server is exiting the current VT. In that case
+ the driver should deallocate any offscreen memory areas (if
+ there are any) being used to put the video to the screen. If
+ &s.code;cleanup&e.code; is not set, the video is being stopped
+ temporarily due to clipping or moving of the window, etc...
+ and video will likely be restarted soon so the driver should
+ not deallocate any offscreen areas associated with that port.
+
+ </quote>
+ &s.code;typedef int (* SetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
+ &f.indent;Atom attribute,INT32 value, pointer data)&e.code;
+
+ &s.code;typedef int (* GetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
+ &f.indent;Atom attribute,INT32 *value, pointer data)&e.code;
+
+ <quote><p>
+ A port may have particular attributes such as hue,
+ saturation, brightness or contrast. Xv clients set and
+ get these attribute values by sending attribute strings
+ (Atoms) to the server. Such requests end up at these
+ driver functions. It is recommended that the driver provide
+ at least the following attributes mentioned in the Xv client
+ library docs:
+ <quote>
+ &s.code;XV_ENCODING&nl;
+ XV_HUE&nl;
+ XV_SATURATION&nl;
+ XV_BRIGHTNESS&nl;
+ XV_CONTRAST&e.code;
+ </quote>
+ but the driver may recognize as many atoms as it wishes. If
+ a requested attribute is unknown by the driver it should return
+ &s.code;BadMatch&e.code;. &s.code;XV_ENCODING&e.code; is the
+ attribute intended to let the client specify which video
+ encoding the particular port should be using (see the description
+ of &s.code;XF86VideoEncodingRec&e.code; below). If the
+ requested encoding is unsupported, the driver should return
+ &s.code;XvBadEncoding&e.code;. If the value lies outside the
+ advertised range &s.code;BadValue&e.code; may be returned.
+ &s.code;Success&e.code; should be returned otherwise.
+
+ </quote>
+
+ &s.code;typedef void (* QueryBestSizeFuncPtr)(ScrnInfoPtr pScrn,
+ &f.indent;Bool motion, short vid_w, short vid_h,
+ &f.indent;short drw_w, short drw_h,
+ &f.indent;unsigned int *p_w, unsigned int *p_h, pointer data)&e.code;
+ <quote><p>
+ &s.code;QueryBestSize&e.code; provides the client with a way
+ to query what the destination dimensions would end up being
+ if they were to request that an area
+ &s.code;vid_w&e.code by &s.code;vid_h&e.code; from the video
+ stream be scaled to rectangle of
+ &s.code;drw_w&e.code; by &s.code;drw_h&e.code; on the screen.
+ Since it is not expected that all hardware will be able to
+ get the target dimensions exactly, it is important that the
+ driver provide this function.
+
+ </quote>
+
+ &s.code;typedef int (* PutImageFuncPtr)( ScrnInfoPtr pScrn,
+ &f.indent;short src_x, short src_y, short drw_x, short drw_y,
+ &f.indent;short src_w, short src_h, short drw_w, short drw_h,
+ &f.indent;int image, char *buf, short width, short height,
+ &f.indent;Bool sync, RegionPtr clipBoxes, pointer data )&e.code;
+ <quote><p>
+ This is similar to &s.code;PutStill&e.code; except that the
+ source of the video is not a port but the data stored in a system
+ memory buffer at &s.code;buf&e.code;. The data is in the format
+ indicated by the &s.code;image&e.code; descriptor and represents a
+ source of size &s.code;width&e.code; by &s.code;height&e.code;.
+ If &s.code;sync&e.code; is TRUE the driver should not return
+ from this function until it is through reading the data
+ from &s.code;buf&e.code;. Returning when &s.code;sync&e.code;
+ is TRUE indicates that it is safe for the data at &s.code;buf&e.code;
+ to be replaced, freed, or modified.
+
+ </quote>
+
+ &s.code;typedef int (* QueryImageAttributesFuncPtr)( ScrnInfoPtr pScrn,
+ &f.indent;int image, short *width, short *height,
+ &f.indent;int *pitches, int *offsets)&e.code;
+ <quote><p>
+ This function is called to let the driver specify how data for
+ a particular &s.code;image&e.code; of size &s.code;width&e.code;
+ by &s.code;height&e.code; should be stored. Sometimes only
+ the size and corrected width and height are needed. In that
+ case &s.code;pitches&e.code; and &s.code;offsets&e.code; are
+ NULL. The size of the memory required for the image is returned
+ by this function. The &s.code;width&e.code; and
+ &s.code;height&e.code; of the requested image can be altered by
+ the driver to reflect format limitations (such as component
+ sampling periods that are larger than one). If
+ &s.code;pitches&e.code; and &s.code;offsets&e.code; are not NULL,
+ these will be arrays with as many elements in them as there
+ are planes in the &s.code;image&e.code; format. The driver
+ should specify the pitch (in bytes) of each scanline in the
+ particular plane as well as the offset to that plane (in bytes)
+ from the beginning of the image.
+
+ </quote>
+
+ </quote>
+
+The XF86VideoEncodingRec:
+<quote><p>
+<verb>
+typedef struct {
+ int id;
+ char *name;
+ unsigned short width, height;
+ XvRationalRec rate;
+} XF86VideoEncodingRec, *XF86VideoEncodingPtr;
+
+</verb>
+ The &s.code;XF86VideoEncodingRec&e.code; specifies what encodings
+ the adaptor can support. Most of this data is just informational
+ and for the client's benefit, and is what will be reported by
+ &s.code;XvQueryEncodings&e.code;. The &s.code;id&e.code; field is
+ expected to be a unique identifier to allow the client to request a
+ certain encoding via the &s.code;XV_ENCODING&e.code; attribute string.
+
+</quote>
+
+The XF86VideoFormatRec:
+
+<quote><p>
+<verb>
+typedef struct {
+ char depth;
+ short class;
+} XF86VideoFormatRec, *XF86VideoFormatPtr;
+</verb>
+
+ This specifies what visuals the video is viewable in.
+ &s.code;depth&e.code; is the depth of the visual (not bpp).
+ &s.code;class&e.code; is the visual class such as
+ &s.code;TrueColor&e.code;, &s.code;DirectColor&e.code; or
+ &s.code;PseudoColor&e.code;. Initialization of an adaptor will fail
+ if none of the visuals on that screen are supported.
+
+</quote>
+
+The XF86AttributeRec:
+
+<quote><p>
+<verb>
+typedef struct {
+ int flags;
+ int min_value;
+ int max_value;
+ char *name;
+} XF86AttributeListRec, *XF86AttributeListPtr;
+
+</verb>
+
+ Each adaptor may have an array of these advertising the attributes
+ for its ports. Currently defined flags are &s.code;XvGettable&e.code;
+ and &s.code;XvSettable&e.code; which may be OR'd together indicating that
+ attribute is ``gettable'' or ``settable'' by the client. The
+ &s.code;min&e.code; and &s.code;max&e.code; field specify the valid range
+ for the value. &s.code;Name&e.code; is a text string describing the
+ attribute by name.
+
+</quote>
+
+The XF86ImageRec:
+
+<quote><p>
+<verb>
+typedef struct {
+ int id;
+ int type;
+ int byte_order;
+ char guid[16];
+ int bits_per_pixel;
+ int format;
+ int num_planes;
+
+ /* for RGB formats */
+ int depth;
+ unsigned int red_mask;
+ unsigned int green_mask;
+ unsigned int blue_mask;
+
+ /* for YUV formats */
+ unsigned int y_sample_bits;
+ unsigned int u_sample_bits;
+ unsigned int v_sample_bits;
+ unsigned int horz_y_period;
+ unsigned int horz_u_period;
+ unsigned int horz_v_period;
+ unsigned int vert_y_period;
+ unsigned int vert_u_period;
+ unsigned int vert_v_period;
+ char component_order[32];
+ int scanline_order;
+} XF86ImageRec, *XF86ImagePtr;
+</verb>
+
+ XF86ImageRec describes how video source data is laid out in memory.
+ The fields are as follows:
+
+ &s.code;id&e.code;
+ <quote><p>
+ This is a unique descriptor for the format. It is often good to
+ set this value to the FOURCC for the format when applicable.
+ </quote>
+
+ &s.code;type&e.code;
+ <quote><p>
+ This is &s.code;XvRGB&e.code; or &s.code;XvYUV&e.code;.
+ </quote>
+
+ &s.code;byte_order&e.code;
+ <quote><p>
+ This is &s.code;LSBFirst&e.code; or &s.code;MSBFirst&e.code;.
+ </quote>
+
+ &s.code;guid&e.code;
+ <quote><p>
+ This is the Globally Unique IDentifier for the format. When
+ not applicable, all characters should be NULL.
+ </quote>
+
+ &s.code;bits_per_pixel&e.code;
+ <quote><p>
+ The number of bits taken up (but not necessarily used) by each
+ pixel. Note that for some planar formats which have fractional
+ bits per pixel (such as IF09) this number may be rounded _down_.
+ </quote>
+
+ &s.code;format&e.code;
+ <quote><p>
+ This is &s.code;XvPlanar&e.code; or &s.code;XvPacked&e.code;.
+ </quote>
+
+ &s.code;num_planes&e.code;
+ <quote><p>
+ The number of planes in planar formats. This should be set to
+ one for packed formats.
+ </quote>
+
+ &s.code;depth&e.code;
+ <quote><p>
+ The significant bits per pixel in RGB formats (analgous to the
+ depth of a pixmap format).
+ </quote>
+
+ &s.code;red_mask&e.code;
+ &s.code;green_mask&e.code;
+ &s.code;blue_mask&e.code;
+ <quote><p>
+ The red, green and blue bitmasks for packed RGB formats.
+ </quote>
+
+ &s.code;y_sample_bits&e.code;
+ &s.code;u_sample_bits&e.code;
+ &s.code;v_sample_bits&e.code;
+ <quote><p>
+ The y, u and v sample sizes (in bits).
+ </quote>
+
+ &s.code;horz_y_period&e.code;
+ &s.code;horz_u_period&e.code;
+ &s.code;horz_v_period&e.code;
+ <quote><p>
+ The y, u and v sampling periods in the horizontal direction.
+ </quote>
+
+ &s.code;vert_y_period&e.code;
+ &s.code;vert_u_period&e.code;
+ &s.code;vert_v_period&e.code;
+ <quote><p>
+ The y, u and v sampling periods in the vertical direction.
+ </quote>
+
+ &s.code;component_order&e.code;
+ <quote><p>
+ Uppercase ascii characters representing the order that
+ samples are stored within packed formats. For planar formats
+ this represents the ordering of the planes. Unused characters
+ in the 32 byte string should be set to NULL.
+ </quote>
+
+ &s.code;scanline_order&e.code;
+ <quote><p>
+ This is &s.code;XvTopToBottom&e.code; or &s.code;XvBottomToTop&e.code;.
+ </quote>
+
+ Since some formats (particular some planar YUV formats) may not
+be completely defined by the parameters above, the guid, when
+available, should provide the most accurate description of the
+format.
+
+</quote>
+
+<sect>The Loader
+<p>
+
+This section describes the interfaces to the module loader. The loader
+interfaces can be divided into two groups: those that are only available to
+the XFree86 common layer, and those that are also available to modules.
+
+<sect1>Loader Overview
+<p>
+
+The loader is capable of loading modules in a range of object formats,
+and knowledge of these formats is built in to the loader. Knowledge of
+new object formats can be added to the loader in a straightforward
+manner. This makes it possible to provide OS-independent modules (for
+a given CPU architecture type). In addition to this, the loader can
+load modules via the OS-provided &s.code;dlopen(3)&e.code; service where
+available. Such modules are not platform independent, and the semantics
+of &s.code;dlopen()&e.code; on most systems results in significant
+limitations in the use of modules of this type. Support for
+&s.code;dlopen()&e.code; modules in the loader is primarily for
+experimental and development purposes.
+
+Symbols exported by the loader (on behalf of the core X server) to
+modules are determined at compile time. Only those symbols explicitly
+exported are available to modules. All external symbols of loaded
+modules are exported to other modules, and to the core X server. The
+loader can be requested to check for unresolved symbols at any time,
+and the action to be taken for unresolved symbols can be controlled by
+the caller of the loader. Typically the caller identifies which symbols
+can safely remain unresolved and which cannot.
+
+NOTE: Now that ISO-C allows pointers to functions and pointers to data to
+have different internal representations, some of the following interfaces
+will need to be revisited.
+
+<sect1>Semi-private Loader Interface
+<p>
+
+The following is the semi-private loader interface that is available to the
+XFree86 common layer.
+
+ <quote><p>
+ &s.code;void LoaderInit(void)&e.code;
+ <quote><p>
+ The &s.code;LoaderInit()&e.code; function initialises the loader,
+ and it must be called once before calling any other loader functions.
+ This function initialises the tables of exported symbols, and anything
+ else that might need to be initialised.
+
+ </quote>
+
+ &s.code;void LoaderSetPath(const char *path)&e.code;
+ <quote><p>
+ The &s.code;LoaderSetPath()&e.code; function initialises a default
+ module search path. This must be called if calls to other functions
+ are to be made without explicitly specifying a module search path.
+ The search path &s.code;path&e.code; must be a string of one or more
+ comma separated absolute paths. Modules are expected to be located
+ below these paths, possibly in subdirectories of these paths.
+
+ </quote>
+
+ &s.code;pointer LoadModule(const char *module, const char *path,
+ &f.indent;const char **subdirlist, const char **patternlist,
+ &f.indent;pointer options, const XF86ModReqInfo * modreq,
+ &f.indent;int *errmaj, int *errmin)&e.code;
+ <quote><p>
+ The &s.code;LoadModule()&e.code; function loads the module called
+ &s.code;module&e.code;. The return value is a module handle, and
+ may be used in future calls to the loader that require a reference
+ to a loaded module. The module name &s.code;module&e.code; is
+ normally the module's canonical name, which doesn't contain any
+ directory path information, or any object/library file prefixes of
+ suffixes. Currently a full pathname and/or filename is also accepted.
+ This might change. The other parameters are:
+
+ &s.code;path&e.code;
+ <quote><p>
+ An optional comma-separated list of module search paths.
+ When &s.code;NULL&e.code;, the default search path is used.
+
+ </quote>
+
+ &s.code;subdirlist&e.code;
+ <quote><p>
+ An optional &s.code;NULL&e.code; terminated list of
+ subdirectories to search. When &s.code;NULL&e.code;,
+ the default built-in list is used (refer to
+ &s.code;stdSubdirs&e.code; in &s.code;loadmod.c&e.code;).
+ The default list is also substituted for entries in
+ &s.code;subdirlist&e.code; with the value
+ &s.code;DEFAULT_LIST&e.code;. This makes is possible
+ to augment the default list instead of replacing it.
+ Subdir elements must be relative, and must not contain
+ &s.code;".."&e.code;. If any violate this requirement,
+ the load fails.
+
+ </quote>
+
+ &s.code;patternlist&e.code;
+ <quote><p>
+ An optional &s.code;NULL&e.code; terminated list of
+ POSIX regular expressions used to connect module
+ filenames with canonical module names. Each regex
+ should contain exactly one subexpression that corresponds
+ to the canonical module name. When &s.code;NULL&e.code;,
+ the default built-in list is used (refer to
+ &s.code;stdPatterns&e.code; in
+ &s.code;loadmod.c&e.code;). The default list is also
+ substituted for entries in &s.code;patternlist&e.code;
+ with the value &s.code;DEFAULT_LIST&e.code;. This
+ makes it possible to augment the default list instead
+ of replacing it.
+
+ </quote>
+
+ &s.code;options&e.code;
+ <quote><p>
+ An optional parameter that is passed to the newly
+ loaded module's &s.code;SetupProc&e.code; function
+ (if it has one). This argument is normally a
+ &s.code;NULL&e.code; terminated list of
+ &s.code;Options&e.code;, and must be interpreted that
+ way by modules loaded directly by the XFree86 common
+ layer. However, it may be used for application-specific
+ parameter passing in other situations.
+
+ When loading ``external'' modules (modules that don't
+ have the standard entry point, for example a
+ special shared library) the options parameter can be
+ set to &s.code;EXTERN_MODULE&e.code; to tell the
+ loader not to reject the module when it doesn't find
+ the standard entry point.
+
+ </quote>
+
+ &s.code;modreq&e.code;
+ <quote><p>
+ An optional &s.code;XF86ModReqInfo*&e.code; containing
+ version/ABI/vendor information to requirements to
+ check the newly loaded module against. The main
+ purpose of this is to allow the loader to verify that
+ a module of the correct type/version before running
+ its &s.code;SetupProc&e.code; function.
+
+ The &s.code;XF86ModReqInfo&e.code; struct is defined
+ as follows:
+<verb>
+typedef struct {
+ CARD8 majorversion; /* MAJOR_UNSPEC */
+ CARD8 minorversion; /* MINOR_UNSPEC */
+ CARD16 patchlevel; /* PATCH_UNSPEC */
+ const char * abiclass; /* ABI_CLASS_NONE */
+ CARD32 abiversion; /* ABI_VERS_UNSPEC */
+ const char * moduleclass; /* MOD_CLASS_NONE */
+} XF86ModReqInfo;
+</verb>
+
+ The information here is compared against the equivalent
+ information in the module's
+ &s.code;XF86ModuleVersionInfo&e.code; record (which
+ is described below). The values in comments above
+ indicate ``don't care'' settings for each of the fields.
+ The comparisons made are as follows:
+
+ &s.code;majorversion&e.code;
+ <quote><p>
+ Must match the module's majorversion
+ exactly.
+
+ </quote>
+ &s.code;minorversion&e.code;
+ <quote><p>
+ The module's minor version must be
+ no less than this value. This
+ comparison is only made if
+ &s.code;majorversion&e.code; is
+ specified and matches.
+
+ </quote>
+ &s.code;patchlevel&e.code;
+ <quote><p>
+ The module's patchlevel must be no
+ less than this value. This comparison
+ is only made if
+ &s.code;minorversion&e.code; is
+ specified and matches.
+
+ </quote>
+ &s.code;abiclass&e.code;
+ <quote><p>
+ String must match the module's abiclass
+ string.
+
+ </quote>
+ &s.code;abiversion&e.code;
+ <quote><p>
+ Must be consistent with the module's
+ abiversion (major equal, minor no
+ older).
+
+ </quote>
+ &s.code;moduleclass&e.code;
+ <quote><p>
+ String must match the module's
+ moduleclass string.
+
+ </quote>
+
+ </quote>
+
+ &s.code;errmaj&e.code;
+ <quote><p>
+ An optional pointer to a variable holding the major
+ part or the error code. When provided,
+ &s.code;*errmaj&e.code; is filled in when
+ &s.code;LoadModule()&e.code; fails.
+
+ </quote>
+
+ &s.code;errmin&e.code;
+ <quote><p>
+ Like &s.code;errmaj&e.code;, but for the minor part
+ of the error code.
+
+ </quote>
+
+ </quote>
+
+ &s.code;void UnloadModule(pointer mod)&e.code;
+ <quote><p>
+ This function unloads the module referred to by the handle mod.
+ All child modules are also unloaded recursively. This function must
+ not be used to directly unload modules that are child modules (i.e.,
+ those that have been loaded with the &s.code;LoadSubModule()&e.code;
+ described below).
+
+ </quote>
+ </quote>
+
+<sect1>Module Requirements
+<p>
+
+Modules must provide information about themselves to the loader, and
+may optionally provide entry points for "setup" and "teardown" functions
+(those two functions are referred to here as &s.code;SetupProc&e.code;
+and &s.code;TearDownProc&e.code;).
+
+The module information is contained in the
+&s.code;XF86ModuleVersionInfo&e.code; struct, which is defined as follows:
+
+<quote><p><verb>
+typedef struct {
+ const char * modname; /* name of module, e.g. "foo" */
+ const char * vendor; /* vendor specific string */
+ CARD32 _modinfo1_; /* constant MODINFOSTRING1/2 to find */
+ CARD32 _modinfo2_; /* infoarea with a binary editor/sign tool */
+ CARD32 xf86version; /* contains XF86_VERSION_CURRENT */
+ CARD8 majorversion; /* module-specific major version */
+ CARD8 minorversion; /* module-specific minor version */
+ CARD16 patchlevel; /* module-specific patch level */
+ const char * abiclass; /* ABI class that the module uses */
+ CARD32 abiversion; /* ABI version */
+ const char * moduleclass; /* module class */
+ CARD32 checksum[4]; /* contains a digital signature of the */
+ /* version info structure */
+} XF86ModuleVersionInfo;
+</verb>
+
+The fields are used as follows:
+
+ &s.code;modname&e.code;
+ <quote><p>
+ The module's name. This field is currently only for
+ informational purposes, but the loader may be modified
+ in future to require it to match the module's canonical
+ name.
+
+ </quote>
+
+ &s.code;vendor&e.code;
+ <quote><p>
+ The module vendor. This field is for informational purposes
+ only.
+
+ </quote>
+
+ &s.code;_modinfo1_&e.code;
+ <quote><p>
+ This field holds the first part of a signature that can
+ be used to locate this structure in the binary. It should
+ always be initialised to &s.code;MODINFOSTRING1&e.code;.
+
+ </quote>
+
+ &s.code;_modinfo2_&e.code;
+ <quote><p>
+ This field holds the second part of a signature that can
+ be used to locate this structure in the binary. It should
+ always be initialised to &s.code;MODINFOSTRING2&e.code;.
+
+ </quote>
+
+ &s.code;xf86version&e.code;
+ <quote><p>
+ The XFree86 version against which the module was compiled.
+ This is mostly for informational/diagnostic purposes. It
+ should be initialised to &s.code;XF86_VERSION_CURRENT&e.code;, which is
+ defined in &s.code;xf86Version.h&e.code;.
+
+ </quote>
+
+ &s.code;majorversion&e.code;
+ <quote><p>
+ The module-specific major version. For modules where this
+ version is used for more than simply informational
+ purposes, the major version should only change (be
+ incremented) when ABI incompatibilities are introduced,
+ or ABI components are removed.
+
+ </quote>
+
+ &s.code;minorversion&e.code;
+ <quote><p>
+ The module-specific minor version. For modules where this
+ version is used for more than simply informational
+ purposes, the minor version should only change (be
+ incremented) when ABI additions are made in a backward
+ compatible way. It should be reset to zero when the major
+ version is increased.
+
+ </quote>
+
+ &s.code;patchlevel&e.code;
+ <quote><p>
+ The module-specific patch level. The patch level should
+ increase with new revisions of the module where there
+ are no ABI changes, and it should be reset to zero when
+ the minor version is increased.
+
+ </quote>
+
+ &s.code;abiclass&e.code;
+ <quote><p>
+ The ABI class that the module requires. The class is
+ specified as a string for easy extensibility. It should
+ indicate which (if any) of the X server's built-in ABI
+ classes that the module relies on, or a third-party ABI
+ if appropriate. Built-in ABI classes currently defined are:
+
+ <quote>
+ &s.code;ABI_CLASS_NONE&e.code;
+ <quote>no class</quote>
+ &s.code;ABI_CLASS_ANSIC&e.code;
+ <quote>only requires the ANSI C interfaces</quote>
+ &s.code;ABI_CLASS_VIDEODRV&e.code;
+ <quote>requires the video driver ABI</quote>
+ &s.code;ABI_CLASS_XINPUT&e.code;
+ <quote>requires the XInput driver ABI</quote>
+ &s.code;ABI_CLASS_EXTENSION&e.code;
+ <quote>requires the extension module ABI</quote>
+ &s.code;ABI_CLASS_FONT&e.code;
+ <quote>requires the font module ABI</quote>
+ </quote>
+
+ </quote>
+
+ &s.code;abiversion&e.code;
+ <quote><p>
+ The version of abiclass that the module requires. The
+ version consists of major and minor components. The
+ major version must match and the minor version must be
+ no newer than that provided by the server or parent
+ module. Version identifiers for the built-in classes
+ currently defined are:
+
+ <quote>
+ &s.code;ABI_ANSIC_VERSION&nl;
+ ABI_VIDEODRV_VERSION&nl;
+ ABI_XINPUT_VERSION&nl;
+ ABI_EXTENSION_VERSION&nl;
+ ABI_FONT_VERSION&e.code;
+ </quote>
+
+ </quote>
+
+ &s.code;moduleclass&e.code;
+ <quote><p>
+ This is similar to the abiclass field, except that it
+ defines the type of module rather than the ABI it
+ requires. For example, although all video drivers require
+ the video driver ABI, not all modules that require the
+ video driver ABI are video drivers. This distinction
+ can be made with the moduleclass. Currently pre-defined
+ module classes are:
+
+ <quote>
+ &s.code;MOD_CLASS_NONE&nl;
+ MOD_CLASS_VIDEODRV&nl;
+ MOD_CLASS_XINPUT&nl;
+ MOD_CLASS_FONT&nl;
+ MOD_CLASS_EXTENSION&e.code;
+ </quote>
+
+ </quote>
+
+ &s.code;checksum&e.code;
+ <quote><p>
+ Not currently used.
+
+ </quote>
+
+</quote>
+
+The module version information, and the optional &s.code;SetupProc&e.code;
+and &s.code;TearDownProc&e.code; entry points are found by the loader
+by locating a data object in the module called "modnameModuleData",
+where "modname" is the canonical name of the module. Modules must
+contain such a data object, and it must be declared with global scope,
+be compile-time initialised, and is of the following type:
+
+<quote>
+<verb>
+typedef struct {
+ XF86ModuleVersionInfo * vers;
+ ModuleSetupProc setup;
+ ModuleTearDownProc teardown;
+} XF86ModuleData;
+</verb>
+</quote>
+
+The vers parameter must be initialised to a pointer to a correctly
+initialised &s.code;XF86ModuleVersionInfo&e.code; struct. The other
+two parameter are optional, and should be initialised to
+&s.code;NULL&e.code; when not required. The other parameters are defined
+as
+
+ <quote><p>
+ &s.code;typedef pointer (*ModuleSetupProc)(pointer, pointer, int *, int *)&e.code;
+
+ &s.code;typedef void (*ModuleTearDownProc)(pointer)&e.code;
+
+
+ &s.code;pointer SetupProc(pointer module, pointer options,
+ &f.indent;int *errmaj, int *errmin)&e.code;
+ <quote><p>
+ When defined, this function is called by the loader after successfully
+ loading a module. module is a handle for the newly loaded module,
+ and maybe used by the &s.code;SetupProc&e.code; if it calls other
+ loader functions that require a reference to it. The remaining
+ arguments are those that were passed to the
+ &s.code;LoadModule()&e.code; (or &s.code;LoadSubModule()&e.code;),
+ and are described above. When the &s.code;SetupProc&e.code; is
+ successful it must return a non-&s.code;NULL&e.code; value. The
+ loader checks this, and if it is &s.code;NULL&e.code; it unloads
+ the module and reports the failure to the caller of
+ &s.code;LoadModule()&e.code;. If the &s.code;SetupProc&e.code;
+ does things that need to be undone when the module is unloaded,
+ it should define a &s.code;TearDownProc&e.code;, and return a
+ pointer that the &s.code;TearDownProc&e.code; can use to undo what
+ has been done.
+
+ When a module is loaded multiple times, the &s.code;SetupProc&e.code;
+ is called once for each time it is loaded.
+
+ </quote>
+
+ &s.code;void TearDownProc(pointer tearDownData)&e.code;
+ <quote><p>
+ When defined, this function is called when the loader unloads a
+ module. The &s.code;tearDownData&e.code; parameter is the return
+ value of the &s.code;SetupProc()&e.code; that was called when the
+ module was loaded. The purpose of this function is to clean up
+ before the module is unloaded (for example, by freeing allocated
+ resources).
+
+ </quote>
+ </quote>
+
+<sect1>Public Loader Interface
+<p>
+
+The following is the Loader interface that is available to any part of
+the server, and may also be used from within modules.
+
+ <quote><p>
+ &s.code;pointer LoadSubModule(pointer parent, const char *module,
+ &f.indent;const char **subdirlist, const char **patternlist,
+ &f.indent;pointer options, const XF86ModReqInfo * modreq,
+ &f.indent;int *errmaj, int *errmin)&e.code;
+ <quote><p>
+ This function is like the &s.code;LoadModule()&e.code; function
+ described above, except that the module loaded is registered as a
+ child of the calling module. The &s.code;parent&e.code; parameter
+ is the calling module's handle. Modules loaded with this function
+ are automatically unloaded when the parent module is unloaded. The
+ other difference is that the path parameter may not be specified.
+ The module search path used for modules loaded with this function
+ is the default search path as initialised with
+ &s.code;LoaderSetPath()&e.code;.
+
+ </quote>
+
+ &s.code;void UnloadSubModule(pointer module)&e.code;
+ <quote><p>
+ This function unloads the module with handle &s.code;module&e.code;.
+ If that module itself has children, they are also unloaded. It is
+ like &s.code;UnloadModule()&e.code;, except that it is safe to use
+ for unloading child modules.
+
+ </quote>
+
+ &s.code;pointer LoaderSymbol(const char *symbol)&e.code;
+ <quote><p>
+ This function returns the address of the symbol with name
+ &s.code;symbol&e.code;. This may be used to locate a module entry
+ point with a known name.
+
+ </quote>
+
+ &s.code;char **LoaderlistDirs(const char **subdirlist,
+ &f.indent;const char **patternlist)&e.code;
+ <quote><p>
+ This function returns a &s.code;NULL&e.code; terminated list of
+ canonical modules names for modules found in the default module
+ search path. The &s.code;subdirlist&e.code; and
+ &s.code;patternlist&e.code; parameters are as described above, and
+ can be used to control the locations and names that are searched.
+ If no modules are found, the return value is &s.code;NULL&e.code;.
+ The returned list should be freed by calling
+ &s.code;LoaderFreeDirList()&e.code; when it is no longer needed.
+
+ </quote>
+
+ &s.code;void LoaderFreeDirList(char **list)&e.code;
+ <quote><p>
+ This function frees a module list created by
+ &s.code;LoaderlistDirs()&e.code;.
+
+ </quote>
+
+ &s.code;void LoaderReqSymLists(const char **list0, ...)&e.code;
+ <quote><p>
+ This function allows the registration of required symbols with the
+ loader. It is normally used by a caller of
+ &s.code;LoadSubModule()&e.code;. If any symbols registered in this
+ way are found to be unresolved when
+ &s.code;LoaderCheckUnresolved()&e.code; is called then
+ &s.code;LoaderCheckUnresolved()&e.code; will report a failure.
+ The function takes one or more &s.code;NULL&e.code; terminated
+ lists of symbols. The end of the argument list is indicated by a
+ &s.code;NULL&e.code; argument.
+
+ </quote>
+
+ &s.code;void LoaderReqSymbols(const char *sym0, ...)&e.code;
+ <quote><p>
+ This function is like &s.code;LoaderReqSymLists()&e.code; except
+ that its arguments are symbols rather than lists of symbols. This
+ function is more convenient when single functions are to be registered,
+ especially when the single function might depend on runtime factors.
+ The end of the argument list is indicated by a &s.code;NULL&e.code;
+ argument.
+
+ </quote>
+
+ &s.code;void LoaderRefSymLists(const char **list0, ...)&e.code;
+ <quote><p>
+ This function allows the registration of possibly unresolved symbols
+ with the loader. When &s.code;LoaderCheckUnresolved()&e.code; is
+ run it won't generate warnings for symbols registered in this way
+ unless they were also registered as required symbols.
+ The function takes one or more &s.code;NULL&e.code; terminated
+ lists of symbols. The end of the argument list is indicated by a
+ &s.code;NULL&e.code; argument.
+
+ </quote>
+
+ &s.code;void LoaderRefSymbols(const char *sym0, ...)&e.code;
+ <quote><p>
+ This function is like &s.code;LoaderRefSymLists()&e.code; except
+ that its arguments are symbols rather than lists of symbols. This
+ function is more convenient when single functions are to be registered,
+ especially when the single function might depend on runtime factors.
+ The end of the argument list is indicated by a &s.code;NULL&e.code;
+ argument.
+
+ </quote>
+
+ &s.code;int LoaderCheckUnresolved(int delayflag)&e.code;
+ <quote><p>
+ This function checks for unresolved symbols. It generates warnings
+ for unresolved symbols that have not been registered with
+ &s.code;LoaderRefSymLists()&e.code;, and maps them to a dummy
+ function. This behaviour may change in future. If unresolved
+ symbols are found that have been registered with
+ &s.code;LoaderReqSymLists()&e.code; or
+ &s.code;LoaderReqSymbols()&e.code; then this function returns a
+ non-zero value. If none of these symbols are unresolved the return
+ value is zero, indicating success.
+
+ The &s.code;delayflag&e.code; parameter should normally be set to
+ &s.code;LD_RESOLV_IFDONE&e.code;.
+
+ </quote>
+
+ &s.code;LoaderErrorMsg(const char *name, const char *modname,
+ &f.indent;int errmaj, int errmin)&e.code;
+ <quote><p>
+ This function prints an error message that includes the text ``Failed
+ to load module'', the module name &s.code;modname&e.code;, a message
+ specific to the &s.code;errmaj&e.code; value, and the value if
+ &s.code;errmin&e.code;. If &s.code;name&e.code; is
+ non-&s.code;NULL&e.code;, it is printed as an identifying prefix
+ to the message (followed by a `:').
+
+ </quote>
+ </quote>
+
+<sect1>Special Registration Functions
+<p>
+
+The loader contains some functions for registering some classes of modules.
+These may be moved out of the loader at some point.
+
+ <quote><p>
+ &s.code;void LoadExtension(ExtensionModule *ext)&e.code;
+ <quote><p>
+ This registers the entry points for the extension identified by
+ &s.code;ext&e.code;. The &s.code;ExtensionModule&e.code; struct is
+ defined as:
+
+<quote>
+<verb>
+typedef struct {
+ InitExtension initFunc;
+ char * name;
+ Bool *disablePtr;
+ InitExtension setupFunc;
+} ExtensionModule;
+</verb>
+</quote>
+
+ </quote>
+
+ &s.code;void LoadFont(FontModule *font)&e.code;
+ <quote><p>
+ This registers the entry points for the font rasteriser module
+ identified by &s.code;font&e.code;. The &s.code;FontModule&e.code;
+ struct is defined as:
+
+<quote>
+<verb>
+typedef struct {
+ InitFont initFunc;
+ char * name;
+ pointer module;
+} FontModule;
+</verb>
+</quote>
+
+ </quote>
+ </quote>
+
+</sect>
+
+
+<sect>Helper Functions
+<p>
+
+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.
+
+<sect1>Functions for printing messages
+<p>
+
+ <quote><p>
+ &s.code;ErrorF(const char *format, ...)&e.code;
+ <quote><p>
+ 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.
+
+ </quote>
+
+ &s.code;FatalError(const char *format, ...)&e.code;
+ <quote><p>
+ 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.
+
+ </quote>
+
+ &s.code;xf86ErrorF(const char *format, ...)&e.code;
+ <quote><p>
+ This is like &s.code;ErrorF()&e.code;, except that the message is
+ only printed when the Xserver's verbosity level is set to the
+ default (&s.code;1&e.code;) or higher. It means that the messages
+ are not printed when the server is started with the
+ &s.cmd;-quiet&e.cmd; flag. Typically this function would only be
+ used for continuing messages started with one of the more specialised
+ functions described below.
+
+ </quote>
+
+ &s.code;xf86ErrorFVerb(int verb, const char *format, ...)&e.code;
+ <quote><p>
+ Like &s.code;xf86ErrorF()&e.code;, except the minimum verbosity
+ level for which the message is to be printed is given explicitly.
+ Passing a &s.code;verb&e.code; value of zero means the message
+ is always printed. A value higher than &s.code;1&e.code; can be
+ used for information would normally not be needed, but which might
+ be useful when diagnosing problems.
+
+ </quote>
+
+ &s.code;xf86Msg(MessageType type, const char *format, ...)&e.code;
+ <quote><p>
+ This is like &s.code;xf86ErrorF()&e.code;, except that the message
+ is prefixed with a marker determined by the value of
+ &s.code;type&e.code;. The marker is used to indicate the type of
+ message (warning, error, probed value, config value, etc). Note
+ the &s.code;xf86Verbose&e.code; value is ignored for messages of
+ type &s.code;X_ERROR&e.code;.
+
+ The marker values are:
+
+ <quote>
+ &s.code;X_PROBED&e.code;
+ <quote>Value was probed.</quote>
+ &s.code;X_CONFIG&e.code;
+ <quote>Value was given in the config file.</quote>
+ &s.code;X_DEFAULT&e.code;
+ <quote>Value is a default.</quote>
+ &s.code;X_CMDLINE&e.code;
+ <quote>Value was given on the command line.</quote>
+ &s.code;X_NOTICE&e.code;
+ <quote>Notice.</quote>
+ &s.code;X_ERROR&e.code;
+ <quote>Error message.</quote>
+ &s.code;X_WARNING&e.code;
+ <quote>Warning message.</quote>
+ &s.code;X_INFO&e.code;
+ <quote>Informational message.</quote>
+ &s.code;X_NONE&e.code;
+ <quote>No prefix.</quote>
+ &s.code;X_NOT_IMPLEMENTED&e.code;
+ <quote>The message relates to functionality that is not yet
+ implemented.</quote>
+ </quote>
+
+
+ </quote>
+
+ &s.code;xf86MsgVerb(MessageType type, int verb, const char *format, ...)&e.code;
+ <quote><p>
+ Like &s.code;xf86Msg()&e.code;, but with the verbosity level given
+ explicitly.
+
+ </quote>
+
+ &s.code;xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)&e.code;
+ <quote><p>
+ This is like &s.code;xf86Msg()&e.code; except that the driver's
+ name (the &s.code;name&e.code; field of the
+ &s.code;ScrnInfoRec&e.code;) followed by the
+ &s.code;scrnIndex&e.code; 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
+ &s.code;scrnIndex&e.code; is negative, this function behaves
+ exactly like &s.code;xf86Msg()&e.code;.
+
+ NOTE: This function can only be used after the
+ &s.code;ScrnInfoRec&e.code; and its &s.code;name&e.code; field
+ have been allocated. Normally, this means that it can not be
+ used before the END of the &s.code;ChipProbe()&e.code; function.
+ Prior to that, use &s.code;xf86Msg()&e.code;, providing the
+ driver's name explicitly. No screen number can be supplied at
+ that point.
+
+ </quote>
+
+ &s.code;xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
+ &f.indent;const char *format, ...)&e.code;
+ <quote><p>
+ Like &s.code;xf86DrvMsg()&e.code;, but with the verbosity level
+ given explicitly.
+
+ </quote>
+ </quote>
+
+
+<sect1>Functions for setting values based on command line and config file
+<p>
+
+ <quote><p>
+ &s.code;Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp,
+ &f.indent;int fbbpp, int depth24flags)&e.code;
+ <quote><p>
+ This function sets the &s.code;depth&e.code;, &s.code;pixmapBPP&e.code; and &s.code;bitsPerPixel&e.code; fields
+ of the &s.code;ScrnInfoRec&e.code;. 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
+ &s.code;ChipPreInit()&e.code; function.
+
+ It requires that the &s.code;confScreen&e.code; field of the &s.code;ScrnInfoRec&e.code; be
+ initialised prior to calling it. This is done by the XFree86
+ common layer prior to calling &s.code;ChipPreInit()&e.code;.
+
+ The parameters passed are:
+
+ &s.code;depth&e.code;
+ <quote><p>
+ driver's preferred default depth if no other is given.
+ If zero, use the overall server default.
+
+ </quote>
+ &s.code;bpp&e.code;
+ <quote><p>
+ Same, but for the pixmap bpp.
+
+ </quote>
+ &s.code;fbbpp&e.code;
+ <quote><p>
+ Same, but for the framebuffer bpp.
+
+ </quote>
+ &s.code;depth24flags&e.code;
+ <quote><p>
+ 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:
+
+ &s.code;NoDepth24Support&e.code;
+ <quote>No depth 24 formats supported</quote>
+ &s.code;Support24bppFb&e.code;
+ <quote>24bpp framebuffer supported</quote>
+ &s.code;Support32bppFb&e.code;
+ <quote>32bpp framebuffer supported</quote>
+ &s.code;SupportConvert24to32&e.code;
+ <quote>Can convert 24bpp pixmap to 32bpp fb</quote>
+ &s.code;SupportConvert32to24&e.code;
+ <quote>Can convert 32bpp pixmap to 24bpp fb</quote>
+ &s.code;ForceConvert24to32&e.code;
+ <quote>Force 24bpp pixmap to 32bpp fb conversion</quote>
+ &s.code;ForceConvert32to24&e.code;
+ <quote>Force 32bpp pixmap to 24bpp fb conversion</quote>
+
+ </quote>
+
+ 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 &s.code;ChipPreInit()&e.code; function should
+ return &s.code;FALSE&e.code;.
+
+ 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 &s.code;depth24flags&e.code;
+ 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 &s.code;depth24flags&e.code; setting.
+
+ On success, the return value is &s.code;TRUE&e.code;. On failure
+ it prints an error message and returns &s.code;FALSE&e.code;.
+
+ The following fields of the &s.code;ScrnInfoRec&e.code; are
+ initialised by this function:
+
+ <quote>
+ &s.code;depth&e.code;, &s.code;bitsPerPixel&e.code;,
+ &s.code;display&e.code;, &s.code;imageByteOrder&e.code;,
+ &s.code;bitmapScanlinePad&e.code;,
+ &s.code;bitmapScanlineUnit&e.code;, &s.code;bitmapBitOrder&e.code;,
+ &s.code;numFormats&e.code;, &s.code;formats&e.code;,
+ &s.code;fbFormat&e.code;.
+ </quote>
+
+ </quote>
+
+ &s.code;void xf86PrintDepthBpp(scrnInfoPtr scrp)&e.code;
+ <quote><p>
+ This function can be used to print out the depth and bpp settings.
+ It should be called after the final call to
+ &s.code;xf86SetDepthBpp()&e.code;.
+
+ </quote>
+
+ &s.code;Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)&e.code;
+ <quote><p>
+ This function sets the &s.code;weight&e.code;, &s.code;mask&e.code;,
+ &s.code;offset&e.code; and &s.code;rgbBits&e.code; fields of the
+ &s.code;ScrnInfoRec&e.code;. It would normally be called fairly
+ early in the &s.code;ChipPreInit()&e.code; function for
+ depths > 8bpp.
+
+ It requires that the &s.code;depth&e.code; and
+ &s.code;display&e.code; fields of the &s.code;ScrnInfoRec&e.code;
+ be initialised prior to calling it.
+
+ The parameters passed are:
+
+ &s.code;weight&e.code;
+ <quote><p>
+ driver's preferred default weight if no other is given.
+ If zero, use the overall server default.
+
+ </quote>
+
+ &s.code;mask&e.code;
+ <quote><p>
+ Same, but for mask.
+
+ </quote>
+
+ 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 &s.code;ChipPreInit()&e.code; function should
+ return &s.code;FALSE&e.code;.
+
+ On success, this function prints a message showing the weight
+ values selected, and returns &s.code;TRUE&e.code;.
+
+ On failure it prints an error message and returns &s.code;FALSE&e.code;.
+
+ The following fields of the &s.code;ScrnInfoRec&e.code; are
+ initialised by this function:
+
+ <quote>
+ &s.code;weight&e.code;, &s.code;mask&e.code;, &s.code;offset&e.code;.
+ </quote>
+
+ </quote>
+
+ &s.code;Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)&e.code;
+ <quote><p>
+ This function sets the &s.code;defaultVisual&e.code; field of the
+ &s.code;ScrnInfoRec&e.code;. It would normally be called fairly
+ early from the &s.code;ChipPreInit()&e.code; function.
+
+ It requires that the &s.code;depth&e.code; and
+ &s.code;display&e.code; fields of the &s.code;ScrnInfoRec&e.code;
+ be initialised prior to calling it.
+
+ The parameters passed are:
+
+ &s.code;visual&e.code;
+ <quote><p>
+ driver's preferred default visual if no other is given.
+ If &s.code;-1&e.code;, use the overall server default.
+
+ </quote>
+
+ 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 &s.code;ChipPreInit()&e.code; function should
+ return &s.code;FALSE&e.code;.
+
+ On success, this function prints a message showing the default visual
+ selected, and returns &s.code;TRUE&e.code;.
+
+ On failure it prints an error message and returns &s.code;FALSE&e.code;.
+
+ </quote>
+
+ &s.code;Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)&e.code;
+ <quote><p>
+ This function sets the &s.code;gamma&e.code; field of the
+ &s.code;ScrnInfoRec&e.code;. It would normally be called fairly
+ early from the &s.code;ChipPreInit()&e.code; function in cases
+ where the driver supports gamma correction.
+
+ It requires that the &s.code;monitor&e.code; field of the
+ &s.code;ScrnInfoRec&e.code; be initialised prior to calling it.
+
+ The parameters passed are:
+
+ &s.code;gamma&e.code;
+ <quote><p>
+ driver's preferred default gamma if no other is given.
+ If zero (&s.code;< 0.01&e.code;), use the overall server
+ default.
+
+ </quote>
+
+ 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 &s.code;ChipPreInit()&e.code; function should
+ return &s.code;FALSE&e.code;.
+
+ On success, this function prints a message showing the gamma
+ value selected, and returns &s.code;TRUE&e.code;.
+
+ On failure it prints an error message and returns &s.code;FALSE&e.code;.
+
+ </quote>
+
+ &s.code;void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)&e.code;
+ <quote><p>
+ This function sets the &s.code;xDpi&e.code; and &s.code;yDpi&e.code;
+ fields of the &s.code;ScrnInfoRec&e.code;. The driver can specify
+ preferred defaults by setting &s.code;x&e.code; and &s.code;y&e.code;
+ to non-zero values. The &s.cmd;-dpi&e.cmd; command line option
+ overrides all other settings. Otherwise, if the
+ &s.key;DisplaySize&e.key; entry is present in the screen's &k.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.
+
+ </quote>
+
+ &s.code;void xf86SetBlackWhitePixels(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ This functions sets the &s.code;blackPixel&e.code; and
+ &s.code;whitePixel&e.code; fields of the &s.code;ScrnInfoRec&e.code;
+ according to whether or not the &s.cmd;-flipPixels&e.cmd; command
+ line options is present.
+
+ </quote>
+
+ &s.code;const char *xf86GetVisualName(int visual)&e.code;
+ <quote><p>
+ 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, &s.code;NULL&e.code; is returned.
+
+ </quote>
+ </quote>
+
+
+<sect1>Primary Mode functions
+<p>
+
+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.
+
+ <quote><p>
+ &s.code;int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
+ &f.indent;char **modeNames, ClockRangePtr clockRanges,
+ &f.indent;int *linePitches, int minPitch, int maxPitch,
+ &f.indent;int pitchInc, int minHeight, int maxHeight,
+ &f.indent;int virtualX, int virtualY,
+ &f.indent;unsigned long apertureSize,
+ &f.indent;LookupModeFlags strategy)&e.code;
+ <quote><p>
+ 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 &s.code;ChipPreInit()&e.code; function.
+
+ The parameters passed to the function are:
+
+ &s.code;availModes&e.code;
+ <quote><p>
+ List of modes available for the monitor.
+
+ </quote>
+ &s.code;modeNames&e.code;
+ <quote><p>
+ List of mode names that the screen is requesting.
+
+ </quote>
+ &s.code;clockRanges&e.code;
+ <quote><p>
+ 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
+ &s.code;clockRanges&e.code;.
+
+ </quote>
+ &s.code;linePitches&e.code;
+ <quote><p>
+ List of line pitches supported by the driver.
+ This is optional and should be &s.code;NULL&e.code; when
+ not used.
+
+ </quote>
+ &s.code;minPitch&e.code;
+ <quote><p>
+ Minimum line pitch supported by the driver. This must
+ be supplied when &s.code;linePitches&e.code; is
+ &s.code;NULL&e.code;, and is ignored otherwise.
+
+ </quote>
+ &s.code;maxPitch&e.code;
+ <quote><p>
+ Maximum line pitch supported by the driver. This is
+ required when &s.code;minPitch&e.code; is required.
+
+ </quote>
+ &s.code;pitchInc&e.code;
+ <quote><p>
+ Granularity of horizontal pitch values as supported by
+ the chipset. This is expressed in bits. This must be
+ supplied.
+
+ </quote>
+ &s.code;minHeight&e.code;
+ <quote><p>
+ minimum virtual height allowed. If zero, no limit is
+ imposed.
+
+ </quote>
+ &s.code;maxHeight&e.code;
+ <quote><p>
+ maximum virtual height allowed. If zero, no limit is
+ imposed.
+
+ </quote>
+ &s.code;virtualX&e.code;
+ <quote><p>
+ 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.
+
+ </quote>
+ &s.code;virtualY&e.code;
+ <quote><p>
+ 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.
+
+ </quote>
+ &s.code;apertureSize&e.code;
+ <quote><p>
+ The size (in bytes) of the aperture used to access video
+ memory.
+
+ </quote>
+ &s.code;strategy&e.code;
+ <quote><p>
+ The strategy to use when choosing from multiple modes
+ with the same name. The options are:
+
+ &s.code;LOOKUP_DEFAULT&e.code;
+ <quote>???</quote>
+ &s.code;LOOKUP_BEST_REFRESH&e.code;
+ <quote>mode with best refresh rate</quote>
+ &s.code;LOOKUP_CLOSEST_CLOCK&e.code;
+ <quote>mode with closest matching clock</quote>
+ &s.code;LOOKUP_LIST_ORDER&e.code;
+ <quote>first usable mode in list</quote>
+
+ The following options can also be combined (OR'ed) with
+ one of the above:
+
+ &s.code;LOOKUP_CLKDIV2&e.code;
+ <quote>Allow halved clocks</quote>
+ &s.code;LOOKUP_OPTIONAL_TOLERANCES&e.code;
+ <quote>Allow missing horizontal sync and/or vertical refresh
+ ranges in the xorg.conf Monitor section</quote>
+
+ &s.code;LOOKUP_OPTIONAL_TOLERANCES&e.code; 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).
+
+ </quote>
+
+ This function requires that the following fields of the
+ &s.code;ScrnInfoRec&e.code; are initialised prior to calling it:
+
+ &s.code;clock[]&e.code;
+ <quote>List of discrete clocks (when non-programmable)</quote>
+ &s.code;numClocks&e.code;
+ <quote>Number of discrete clocks (when non-programmable)</quote>
+ &s.code;progClock&e.code;
+ <quote>Whether the clock is programmable or not</quote>
+ &s.code;monitor&e.code;
+ <quote>Pointer to the applicable xorg.conf monitor section</quote>
+ &s.code;fdFormat&e.code;
+ <quote>Format of the screen buffer</quote>
+ &s.code;videoRam&e.code;
+ <quote>total video memory size (in bytes)</quote>
+ &s.code;maxHValue&e.code;
+ <quote>Maximum horizontal timing value allowed</quote>
+ &s.code;maxVValue&e.code;
+ <quote>Maximum vertical timing value allowed</quote>
+ &s.code;xInc&e.code;
+ <quote>Horizontal timing increment in pixels (defaults to 8)</quote>
+
+ This function fills in the following &s.code;ScrnInfoRec&e.code;
+ fields:
+
+ &s.code;modePool&e.code;
+ <quote><p>
+ A subset of the modes available to the monitor which
+ are compatible with the driver.
+
+ </quote>
+ &s.code;modes&e.code;
+ <quote><p>
+ 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.
+
+ </quote>
+ &s.code;virtualX&e.code;
+ <quote><p>
+ The resulting virtual width.
+
+ </quote>
+ &s.code;virtualY&e.code;
+ <quote><p>
+ The resulting virtual height.
+
+ </quote>
+ &s.code;displayWidth&e.code;
+ <quote><p>
+ The resulting line pitch.
+
+ </quote>
+ &s.code;virtualFrom&e.code;
+ <quote><p>
+ Where the virtual size was determined from.
+
+ </quote>
+
+ The first stage of this function checks that the
+ &s.code;virtualX&e.code; and &s.code;virtualY&e.code; values
+ supplied (if greater than zero) are consistent with the line pitch
+ and &s.code;maxHeight&e.code; limitations. If not, an error
+ message is printed, and the return value is &s.code;-1&e.code;.
+
+ 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 &s.code;2&e.code;. If the mode pool ends up being empty,
+ a warning message is printed, and the return value is
+ &s.code;0&e.code;.
+
+ 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 &s.code;-1&e.code;. Otherwise,
+ the return value is the number of valid modes found
+ (&s.code;0&e.code; 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 &s.code;-1&e.code;, the
+ &s.code;ChipPreInit()&e.code; function should return
+ &s.code;FALSE&e.code;.
+
+ &s.code;clockRanges&e.code; is a linked list of clock ranges
+ allowed by the driver. If a mode doesn't fit in any of the defined
+ &s.code;clockRanges&e.code;, it is rejected. The first
+ &s.code;clockRange&e.code; that matches all requirements is used.
+ This structure needs to be initialized to NULL when allocated.
+
+ &s.code;clockRanges&e.code; contains the following fields:
+
+ &s.code;minClock&nl;
+ maxClock&e.code;
+ <quote><p>
+ The lower and upper mode clock bounds for which the rest
+ of the &s.code;clockRange&e.code; parameters apply.
+ Since these are the mode clocks, they are not scaled
+ with the &s.code;ClockMulFactor&e.code; and
+ &s.code;ClockDivFactor&e.code;. It is up to the driver
+ to adjust these values if they depend on the clock
+ scaling factors.
+
+ </quote>
+ &s.code;clockIndex&e.code;
+ <quote><p>
+ (not used yet) &s.code;-1&e.code; for programmable clocks
+
+ </quote>
+ &s.code;interlaceAllowed&e.code;
+ <quote><p>
+ &s.code;TRUE&e.code; if interlacing is allowed for this
+ range
+
+ </quote>
+ &s.code;doubleScanAllowed&e.code;
+ <quote><p>
+ &s.code;TRUE&e.code; if doublescan or multiscan is allowed
+ for this range
+
+ </quote>
+ &s.code;ClockMulFactor&nl;
+ ClockDivFactor&e.code;
+ <quote><p>
+ Scaling factors that are applied to the mode clocks ONLY
+ before selecting a clock index (when there is no
+ programmable clock) or a &s.code;SynthClock&e.code;
+ 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 &s.code;2:1&e.code; 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, &s.code;ClockMulFactor=1&e.code; and
+ &s.code;ClockDivFactor=2&e.code;. This means that the
+ clock used for clock selection (ie, determining the
+ correct clock index from the list of discrete clocks)
+ or for the &s.code;SynthClock&e.code; field in case of
+ a programmable clock is: (&s.code;mode->Clock *
+ ClockMulFactor) / ClockDivFactor&e.code;.
+
+ </quote>
+ &s.code;PrivFlags&e.code;
+ <quote><p>
+ This field is copied into the
+ &s.code;mode->PrivFlags&e.code; field when this
+ &s.code;clockRange&e.code; is selected by
+ &s.code;xf86ValidateModes()&e.code;. 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 &s.code;INT&e.code;).
+ </quote>
+
+ Note that the &s.code;mode->SynthClock&e.code; field is always
+ filled in by &s.code;xf86ValidateModes()&e.code;: 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:
+
+ &s.code;mode->SynthClock =
+ &f.indent;(mode->Clock * ClockMulFactor) / ClockDivFactor&e.code;
+
+ </quote>
+
+ &s.code;void xf86PruneDriverModes(ScrnInfoPtr scrp)&e.code;
+ <quote><p>
+ This function deletes modes in the modes field of the
+ &s.code;ScrnInfoRec&e.code; that have been marked as invalid.
+ This is normally run after having run
+ &s.code;xf86ValidateModes()&e.code; for the last time. For each
+ mode that is deleted, a warning message is printed out indicating
+ the reason for it being deleted.
+
+ </quote>
+
+ &s.code;void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)&e.code;
+ <quote><p>
+ This function fills in the &s.code;Crtc*&e.code; fields for all
+ the modes in the &s.code;modes&e.code; field of the
+ &s.code;ScrnInfoRec&e.code;. The &s.code;adjustFlags&e.code;
+ parameter determines how the vertical CRTC values are scaled for
+ interlaced modes. They are halved if it is
+ &s.code;INTERLACE_HALVE_V&e.code;. The vertical CRTC values are
+ doubled for doublescan modes, and are further multiplied by the
+ &s.code;VScan&e.code; value.
+
+ This function is normally called after calling
+ &s.code;xf86PruneDriverModes()&e.code;.
+
+ </quote>
+
+ &s.code;void xf86PrintModes(ScrnInfoPtr scrp)&e.code;
+ <quote><p>
+ This function prints out the virtual size setting, and the line
+ pitch being used. It also prints out two lines for each mode being
+ used. The first line includes the mode's pixel clock, horizontal sync
+ rate, refresh rate, and whether it is interlaced, doublescanned and/or
+ multi-scanned. The second line is the mode's Modeline.
+
+ This function is normally called after calling
+ &s.code;xf86SetCrtcForModes()&e.code;.
+
+ </quote>
+ </quote>
+
+
+<sect1>Secondary Mode functions
+<p>
+
+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.
+
+ <quote><p>
+ &s.code;int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
+ &f.indent;int *divider)&e.code;
+ <quote><p>
+ This function returns the index of the closest clock to the
+ frequency &s.code;freq&e.code; given (in kHz). It assumes that
+ the number of clocks is greater than zero. It requires that the
+ &s.code;numClocks&e.code; and &s.code;clock&e.code; fields of the
+ &s.code;ScrnInfoRec&e.code; are initialised. The
+ &s.code;allowDiv2&e.code; field determines if the clocks can be
+ halved. The &s.code;*divider&e.code; return value indicates
+ whether clock division is used when determining the clock returned.
+
+ This function is only for non-programmable clocks.
+
+ </quote>
+
+ &s.code;const char *xf86ModeStatusToString(ModeStatus status)&e.code;
+ <quote><p>
+ This function converts the &s.code;status&e.code; value to a
+ descriptive printable string.
+
+ </quote>
+
+ &s.code;ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
+ &f.indent;ClockRangePtr clockRanges, LookupModeFlags strategy)&e.code;
+ <quote><p>
+ This function takes a pointer to a mode with the name filled in,
+ and looks for a mode in the &s.code;modePool&e.code; list which
+ matches. The parameters of the matching mode are filled in to
+ &s.code;*modep&e.code;. The &s.code;clockRanges&e.code; and
+ &s.code;strategy&e.code; parameters are as for the
+ &s.code;xf86ValidateModes()&e.code; function above.
+
+ This function requires the &s.code;modePool&e.code;,
+ &s.code;clock[]&e.code;, &s.code;numClocks&e.code; and
+ &s.code;progClock&e.code; fields of the &s.code;ScrnInfoRec&e.code;
+ to be initialised before being called.
+
+ The return value is &s.code;MODE_OK&e.code; if a mode was found.
+ Otherwise it indicates why a matching mode could not be found.
+
+ </quote>
+
+ &s.code;ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp,
+ &f.indent;DisplayModePtr mode, ClockRangePtr clockRanges,
+ &f.indent;LookupModeFlags strategy, int maxPitch,
+ &f.indent;int virtualX, int virtualY)&e.code;
+ <quote><p>
+ This function checks the passed mode against some basic driver
+ constraints. Apart from the ones passed explicitly, the
+ &s.code;maxHValue&e.code; and &s.code;maxVValue&e.code; fields of
+ the &s.code;ScrnInfoRec&e.code; are also used. If the
+ &s.code;ValidMode&e.code; field of the &s.code;ScrnInfoRec&e.code;
+ 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 &s.code;MODE_OK&e.code;. Otherwise the return value indicates
+ which constraint wasn't met.
+
+ </quote>
+
+ &s.code;void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)&e.code;
+ <quote><p>
+ This function deletes the &s.code;mode&e.code; given from the
+ &s.code;modeList&e.code;. It never prints any messages, so it is
+ up to the caller to print a message if required.
+
+ </quote>
+ </quote>
+
+<sect1>Functions for handling strings and tokens
+<p>
+
+ 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:
+
+<quote><verb>
+typedef struct {
+ int token;
+ const char * name;
+} SymTabRec, *SymTabPtr;
+</verb></quote>
+
+ A table is an initialised array of &s.code;SymTabRec&e.code;. 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
+ &s.code;token&e.code; value of &s.code;-1&e.code; and
+ &s.code;NULL&e.code; for the &s.code;name&e.code;.
+
+
+ <quote><p>
+ &s.code;const char *xf86TokenToString(SymTabPtr table, int token)&e.code;
+ <quote><p>
+ This function returns the first string in &s.code;table&e.code;
+ that matches &s.code;token&e.code;. If no match is found,
+ &s.code;NULL&e.code; is returned (NOTE, older versions of this
+ function would return the string "unknown" when no match is found).
+
+ </quote>
+
+ &s.code;int xf86StringToToken(SymTabPtr table, const char *string)&e.code;
+ <quote><p>
+ This function returns the first token in &s.code;table&e.code;
+ that matches &s.code;string&e.code;. The
+ &s.code;xf86NameCmp()&e.code; function is used to determine the
+ match. If no match is found, &s.code;-1&e.code; is returned.
+
+ </quote>
+ </quote>
+
+
+<sect1>Functions for finding which config file entries to use
+<p>
+
+ These functions can be used to select the appropriate config file
+ entries that match the detected hardware. They are described above
+ in the <ref id="probe" name="Probe"> and
+ <ref id="avail" name="Available Functions"> sections.
+
+
+<sect1>Probing discrete clocks on old hardware
+<p>
+
+ The &s.code;xf86GetClocks()&e.code; function may be used to assist
+ in finding the discrete pixel clock values on older hardware.
+
+
+ <quote><p>
+ &s.code;void xf86GetClocks(ScrnInfoPtr pScrn, int num,
+ &f.indent;Bool (*ClockFunc)(ScrnInfoPtr, int),
+ &f.indent;void (*ProtectRegs)(ScrnInfoPtr, Bool),
+ &f.indent;void (*BlankScreen)(ScrnInfoPtr, Bool),
+ &f.indent;int vertsyncreg, int maskval, int knownclkindex,
+ &f.indent;int knownclkvalue)&e.code;
+ <quote><p>
+ This function uses a comparative sampling method to measure the
+ discrete pixel clock values. The number of discrete clocks to
+ measure is given by &s.code;num&e.code;. &s.code;clockFunc&e.code;
+ is a function that selects the &s.code;n&e.code;'th clock. It
+ should also save or restore any state affected by programming the
+ clocks when the index passed is &s.code;CLK_REG_SAVE&e.code; or
+ &s.code;CLK_REG_RESTORE&e.code;. &s.code;ProtectRegs&e.code; is
+ a function that does whatever is required to protect the hardware
+ state while selecting a new clock. &s.code;BlankScreen&e.code;
+ is a function that blanks the screen. &s.code;vertsyncreg&e.code;
+ and &s.code;maskval&e.code; are the register and bitmask to
+ check for the presence of vertical sync pulses.
+ &s.code;knownclkindex&e.code; and &s.code;knownclkvalue&e.code;
+ 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 &s.code;pScrn->numClocks&e.code;,
+ and the probed clocks are set in the &s.code;pScrn->clock[]&e.code;
+ array. All of the clock values are in units of kHz.
+
+ </quote>
+
+ &s.code;void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)&e.code;
+ <quote><p>
+ Print out the pixel clocks &s.code;scrp->clock[]&e.code;.
+ &s.code;from&e.code; indicates whether the clocks were probed
+ or from the config file.
+
+ </quote>
+ </quote>
+
+<sect1>Other helper functions
+<p>
+ <quote><p>
+ &s.code;Bool xf86IsUnblank(int mode)&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; when the screen saver mode specified
+ by &s.code;mode&e.code; requires the screen be unblanked,
+ and &s.code;FALSE&e.code; otherwise. The screen saver modes that
+ require blanking are &s.code;SCREEN_SAVER_ON&e.code; and
+ &s.code;SCREEN_SAVER_CYCLE&e.code;, and the screen saver modes that
+ require unblanking are &s.code;SCREEN_SAVER_OFF&e.code; and
+ &s.code;SCREEN_SAVER_FORCER&e.code;. Drivers may call this helper
+ from their &s.code;SaveScreen()&e.code; function to interpret the
+ screen saver modes.
+
+ </quote>
+ </quote>
+
+<sect>The vgahw module
+<p>
+
+The vgahw modules provides an interface for saving, restoring and
+programming the standard VGA registers, and for handling VGA colourmaps.
+
+<sect1>Data Structures
+<p>
+
+ The public data structures used by the vgahw module are
+ &s.code;vgaRegRec&e.code; and &s.code;vgaHWRec&e.code;. They are
+ defined in &s.code;vgaHW.h.&e.code;
+
+
+<sect1>General vgahw Functions
+<p>
+
+ <quote><p>
+ &s.code;Bool vgaHWGetHWRec(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ This function allocates a &s.code;vgaHWRec&e.code; structure, and
+ hooks it into the &s.code;ScrnInfoRec&e.code;'s
+ &s.code;privates&e.code;. Like all information hooked into the
+ &s.code;privates&e.code;, it is persistent, and only needs to be
+ allocated once per screen. This function should normally be called
+ from the driver's &s.code;ChipPreInit()&e.code; function. The
+ &s.code;vgaHWRec&e.code; is zero-allocated, and the following
+ fields are explicitly initialised:
+
+ &s.code;ModeReg.DAC[]&e.code;
+ <quote>initialised with a default colourmap</quote>
+ &s.code;ModeReg.Attribute[0x11]&e.code;
+ <quote>initialised with the default overscan index</quote>
+ &s.code;ShowOverscan&e.code;
+ <quote>initialised according to the "ShowOverscan" option</quote>
+ &s.code;paletteEnabled&e.code;
+ <quote>initialised to FALSE</quote>
+ &s.code;cmapSaved&e.code;
+ <quote>initialised to FALSE</quote>
+ &s.code;pScrn&e.code;
+ <quote>initialised to pScrn</quote>
+
+ In addition to the above, &s.code;vgaHWSetStdFuncs()&e.code; is
+ called to initialise the register access function fields with the
+ standard VGA set of functions.
+
+ Once allocated, a pointer to the &s.code;vgaHWRec&e.code; can be
+ obtained from the &s.code;ScrnInfoPtr&e.code; with the
+ &s.code;VGAHWPTR(pScrn)&e.code; macro.
+
+ </quote>
+
+ &s.code;void vgaHWFreeHWRec(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ This function frees a &s.code;vgaHWRec&e.code; structure. It
+ should be called from a driver's &s.code;ChipFreeScreen()&e.code;
+ function.
+
+ </quote>
+
+ &s.code;Bool vgaHWSetRegCounts(ScrnInfoPtr pScrn, int numCRTC,
+ &f.indent;int numSequencer, int numGraphics, int numAttribute)&e.code;
+ <quote><p>
+ This function allows the number of CRTC, Sequencer, Graphics and
+ Attribute registers to be changed. This makes it possible for
+ extended registers to be saved and restored with
+ &s.code;vgaHWSave()&e.code; and &s.code;vgaHWRestore()&e.code;.
+ This function should be called after a &s.code;vgaHWRec&e.code;
+ has been allocated with &s.code;vgaHWGetHWRec()&e.code;. The
+ default values are defined in &s.code;vgaHW.h&e.code; as follows:
+
+ <quote><verb>
+#define VGA_NUM_CRTC 25
+#define VGA_NUM_SEQ 5
+#define VGA_NUM_GFX 9
+#define VGA_NUM_ATTR 21
+ </verb></quote>
+
+ </quote>
+
+ &s.code;Bool vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)&e.code;
+ <quote><p>
+ This function copies the contents of the VGA saved registers in
+ &s.code;src&e.code; to &s.code;dst&e.code;. Note that it isn't
+ possible to simply do this with &s.code;memcpy()&e.code; (or
+ similar). This function returns &s.code;TRUE&e.code; unless there
+ is a problem allocating space for the &s.code;CRTC&e.code and
+ related fields in &s.code;dst&e.code;.
+
+ </quote>
+
+ &s.code;void vgaHWSetStdFuncs(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ This function initialises the register access function fields of
+ &s.code;hwp&e.code; with the standard VGA set of functions. This
+ is called by &s.code;vgaHWGetHWRec()&e.code;, so there is usually
+ no need to call this explicitly. The register access functions
+ are described below. If the registers are shadowed in some other
+ port I/O space (for example a PCI I/O region), these functions
+ can be used to access the shadowed registers if
+ &s.code;hwp->PIOOffset&e.code; is initialised with
+ &s.code;offset&e.code;, calculated in such a way that when the
+ standard VGA I/O port value is added to it the correct offset into
+ the PIO area results. This value is initialised to zero in
+ &s.code;vgaHWGetHWRec()&e.code;. (Note: the PIOOffset functionality
+ is present in XFree86 4.1.0 and later.)
+
+ </quote>
+
+ &s.code;void vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)&e.code;
+ <quote><p>
+ This function initialised the register access function fields of
+ hwp with a generic MMIO set of functions.
+ &s.code;hwp->MMIOBase&e.code; is initialised with
+ &s.code;base&e.code;, which must be the virtual address that the
+ start of MMIO area is mapped to. &s.code;hwp->MMIOOffset&e.code;
+ is initialised with &s.code;offset&e.code;, which must be calculated
+ in such a way that when the standard VGA I/O port value is added
+ to it the correct offset into the MMIO area results. That means
+ that these functions are only suitable when the VGA I/O ports are
+ made available in a direct mapping to the MMIO space. If that is
+ not the case, the driver will need to provide its own register
+ access functions. The register access functions are described
+ below.
+
+ </quote>
+
+ &s.code;Bool vgaHWMapMem(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ This function maps the VGA memory window. It requires that the
+ &s.code;vgaHWRec&e.code; be allocated. If a driver requires
+ non-default &s.code;MapPhys&e.code; or &s.code;MapSize&e.code;
+ settings (the physical location and size of the VGA memory window)
+ then those fields of the &s.code;vgaHWRec&e.code; must be initialised
+ before calling this function. Otherwise, this function initialiases
+ the default values of &s.code;0xA0000&e.code; for
+ &s.code;MapPhys&e.code; and &s.code;(64 * 1024)&e.code; for
+ &s.code;MapSize&e.code;. This function must be called before
+ attempting to save or restore the VGA state. If the driver doesn't
+ call it explicitly, the &s.code;vgaHWSave()&e.code; and
+ &s.code;vgaHWRestore()&e.code; functions may call it if they need
+ to access the VGA memory (in which case they will also call
+ &s.code;vgaHWUnmapMem()&e.code; to unmap the VGA memory before
+ exiting).
+
+ </quote>
+
+ &s.code;void vgaHWUnmapMem(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ This function unmaps the VGA memory window. It must only be called
+ after the memory has been mapped. The &s.code;Base&e.code; field
+ of the &s.code;vgaHWRec&e.code; field is set to &s.code;NULL&e.code;
+ to indicate that the memory is no longer mapped.
+
+ </quote>
+
+ &s.code;void vgaHWGetIOBase(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ This function initialises the &s.code;IOBase&e.code; field of the
+ &s.code;vgaHWRec&e.code;. This function must be called before
+ using any other functions that access the video hardware.
+
+ A macro &s.code;VGAHW_GET_IOBASE()&e.code; is also available in
+ &s.code;vgaHW.h&e.code; that returns the I/O base, and this may
+ be used when the vgahw module is not loaded (for example, in the
+ &s.code;ChipProbe()&e.code; function).
+
+ </quote>
+
+ &s.code;void vgaHWUnlock(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ This function unlocks the VGA &s.code;CRTC[0-7]&e.code; registers,
+ and must be called before attempting to write to those registers.
+
+ </quote>
+
+ &s.code;void vgaHWLock(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ This function locks the VGA &s.code;CRTC[0-7]&e.code; registers.
+
+ </quote>
+
+ &s.code;void vgaHWEnable(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ This function enables the VGA subsystem. (Note, this function is
+ present in XFree86 4.1.0 and later.).
+
+ </quote>
+
+ &s.code;void vgaHWDisable(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ This function disables the VGA subsystem. (Note, this function is
+ present in XFree86 4.1.0 and later.).
+
+ </quote>
+
+ &s.code;void vgaHWSave(ScrnInfoPtr pScrn, vgaRegPtr save, int flags)&e.code;
+ <quote><p>
+ This function saves the VGA state. The state is written to the
+ &s.code;vgaRegRec&e.code; pointed to by &s.code;save&e.code;.
+ &s.code;flags&e.code; is set to one or more of the following flags
+ ORed together:
+
+ &s.code;VGA_SR_MODE&e.code;
+ <quote>the mode setting registers are saved</quote>
+ &s.code;VGA_SR_FONTS&e.code;
+ <quote>the text mode font/text data is saved</quote>
+ &s.code;VGA_SR_CMAP&e.code;
+ <quote>the colourmap (LUT) is saved</quote>
+ &s.code;VGA_SR_ALL&e.code;
+ <quote>all of the above are saved</quote>
+
+ The &s.code;vgaHWRec&e.code; and its &s.code;IOBase&e.code; fields
+ must be initialised before this function is called. If
+ &s.code;VGA_SR_FONTS&e.code; is set in &s.code;flags&e.code;, the
+ VGA memory window must be mapped. If it isn't then
+ &s.code;vgaHWMapMem()&e.code; will be called to map it, and
+ &s.code;vgaHWUnmapMem()&e.code; will be called to unmap it
+ afterwards. &s.code;vgaHWSave()&e.code; uses the three functions
+ below in the order &s.code;vgaHWSaveColormap()&e.code;,
+ &s.code;vgaHWSaveMode()&e.code;, &s.code;vgaHWSaveFonts()&e.code; to
+ carry out the different save phases. It is undecided at this
+ stage whether they will remain part of the vgahw module's public
+ interface or not.
+
+ </quote>
+
+ &s.code;void vgaHWSaveMode(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
+ <quote><p>
+ This function saves the VGA mode registers. They are saved to
+ the &s.code;vgaRegRec&e.code; pointed to by &s.code;save&e.code;.
+ The registers saved are:
+
+ <quote>
+ &s.code;MiscOut&nl;
+ CRTC[0-0x18]&nl;
+ Attribute[0-0x14]&nl;
+ Graphics[0-8]&nl;
+ Sequencer[0-4]&e.code;
+ </quote>
+
+ The number of registers actually saved may be modified by a prior call
+ to &s.code;vgaHWSetRegCounts()&e.code;.
+
+ </quote>
+
+ &s.code;void vgaHWSaveFonts(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
+ <quote><p>
+ This function saves the text mode font and text data held in the
+ video memory. If called while in a graphics mode, no save is
+ done. The VGA memory window must be mapped with
+ &s.code;vgaHWMapMem()&e.code; before to calling this function.
+
+ On some platforms, one or more of the font/text plane saves may be
+ no-ops. This is the case when the platform's VC driver already
+ takes care of this.
+
+ </quote>
+
+ &s.code;void vgaHWSaveColormap(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
+ <quote><p>
+ This function saves the VGA colourmap (LUT). Before saving it, it
+ attempts to verify that the colourmap is readable. In rare cases
+ where it isn't readable, a default colourmap is saved instead.
+
+ </quote>
+
+ &s.code;void vgaHWRestore(ScrnInfoPtr pScrn, vgaRegPtr restore, int flags)&e.code;
+ <quote><p>
+ This function programs the VGA state. The state programmed is
+ that contained in the &s.code;vgaRegRec&e.code; pointed to by
+ &s.code;restore&e.code;. &s.code;flags&e.code; is the same
+ as described above for the &s.code;vgaHWSave()&e.code; function.
+
+ The &s.code;vgaHWRec&e.code; and its &s.code;IOBase&e.code; fields
+ must be initialised before this function is called. If
+ &s.code;VGA_SR_FONTS&e.code; is set in &s.code;flags&e.code;, the
+ VGA memory window must be mapped. If it isn't then
+ &s.code;vgaHWMapMem()&e.code; will be called to map it, and
+ &s.code;vgaHWUnmapMem()&e.code; will be called to unmap it
+ afterwards. &s.code;vgaHWRestore()&e.code; uses the three functions
+ below in the order &s.code;vgaHWRestoreFonts()&e.code;,
+ &s.code;vgaHWRestoreMode()&e.code;,
+ &s.code;vgaHWRestoreColormap()&e.code; to carry out the different
+ restore phases. It is undecided at this stage whether they will
+ remain part of the vgahw module's public interface or not.
+
+ </quote>
+
+ &s.code;void vgaHWRestoreMode(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
+ <quote><p>
+ This function restores the VGA mode registers. They are restored
+ from the data in the &s.code;vgaRegRec&e.code; pointed to by
+ &s.code;restore&e.code;. The registers restored are:
+
+ <quote>
+ &s.code;MiscOut&nl;
+ CRTC[0-0x18]&nl;
+ Attribute[0-0x14]&nl;
+ Graphics[0-8]&nl;
+ Sequencer[0-4]&e.code;
+ </quote>
+
+ The number of registers actually restored may be modified by a prior call
+ to &s.code;vgaHWSetRegCounts()&e.code;.
+
+ </quote>
+
+ &s.code;void vgaHWRestoreFonts(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
+ <quote><p>
+ This function restores the text mode font and text data to the
+ video memory. The VGA memory window must be mapped with
+ &s.code;vgaHWMapMem()&e.code; before to calling this function.
+
+ On some platforms, one or more of the font/text plane restores
+ may be no-ops. This is the case when the platform's VC driver
+ already takes care of this.
+
+ </quote>
+
+ &s.code;void vgaHWRestoreColormap(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
+ <quote><p>
+ This function restores the VGA colourmap (LUT).
+
+ </quote>
+
+ &s.code;void vgaHWInit(ScrnInfoPtr pScrn, DisplayModePtr mode)&e.code;
+ <quote><p>
+ This function fills in the &s.code;vgaHWRec&e.code;'s
+ &s.code;ModeReg&e.code; field with the values appropriate for
+ programming the given video mode. It requires that the
+ &s.code;ScrnInfoRec&e.code;'s &s.code;depth&e.code; field is
+ initialised, which determines how the registers are programmed.
+
+ </quote>
+
+ &s.code;void vgaHWSeqReset(vgaHWPtr hwp, Bool start)&e.code;
+ <quote><p>
+ Do a VGA sequencer reset. If start is &s.code;TRUE&e.code;, the
+ reset is started. If start is &s.code;FALSE&e.code;, the reset
+ is ended.
+
+ </quote>
+
+ &s.code;void vgaHWProtect(ScrnInfoPtr pScrn, Bool on)&e.code;
+ <quote><p>
+ This function protects VGA registers and memory from corruption
+ during loads. It is typically called with on set to
+ &s.code;TRUE&e.code; before programming, and with on set to
+ &s.code;FALSE&e.code; after programming.
+
+ </quote>
+
+ &s.code;Bool vgaHWSaveScreen(ScreenPtr pScreen, int mode)&e.code;
+ <quote><p>
+ This function blanks and unblanks the screen. It is blanked when
+ &s.code;mode&e.code; is &s.code;SCREEN_SAVER_ON&e.code; or
+ &s.code;SCREEN_SAVER_CYCLE&e.code;, and unblanked when
+ &s.code;mode&e.code; is &s.code;SCREEN_SAVER_OFF&e.code; or
+ &s.code;SCREEN_SAVER_FORCER&e.code;.
+
+ </quote>
+
+ &s.code;void vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)&e.code;
+ <quote><p>
+ This function blanks and unblanks the screen. It is blanked when
+ &s.code;on&e.code; is &s.code;FALSE&e.code;, and unblanked when
+ &s.code;on&e.code; is &s.code;TRUE&e.code;. This function is
+ provided for use in cases where the &s.code;ScrnInfoRec&e.code;
+ can't be derived from the &s.code;ScreenRec&e.code; (while probing
+ for clocks, for example).
+
+ </quote>
+ </quote>
+
+<sect1>VGA Colormap Functions
+<p>
+
+ The vgahw module uses the standard colormap support (see the
+ <ref id="cmap" name="Colormap Handling"> section. This is initialised
+ with the following function:
+
+ <quote>
+ &s.code;Bool vgaHWHandleColormaps(ScreenPtr pScreen)&e.code;
+ </quote>
+
+
+<sect1>VGA Register Access Functions
+<p>
+
+ The vgahw module abstracts access to the standard VGA registers by
+ using a set of functions held in the &s.code;vgaHWRec&e.code;. When
+ the &s.code;vgaHWRec&e.code; is created these function pointers are
+ initialised with the set of standard VGA I/O register access functions.
+ In addition to these, the vgahw module includes a basic set of MMIO
+ register access functions, and the &s.code;vgaHWRec&e.code; function
+ pointers can be initialised to these by calling the
+ &s.code;vgaHWSetMmioFuncs()&e.code; function described above. Some
+ drivers/platforms may require a different set of functions for VGA
+ access. The access functions are described here.
+
+
+ <quote><p>
+ &s.code;void writeCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to CRTC register &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;CARD8 readCrtc(vgaHWPtr hwp, CARD8 index)&e.code;
+ <quote><p>
+ Return the value read from CRTC register &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;void writeGr(vgaHWPtr hwp, CARD8 index, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to Graphics Controller register
+ &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;CARD8 readGR(vgaHWPtr hwp, CARD8 index)&e.code;
+ <quote><p>
+ Return the value read from Graphics Controller register
+ &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;void writeSeq(vgaHWPtr hwp, CARD8 index, CARD8, value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to Sequencer register
+ &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;CARD8 readSeq(vgaHWPtr hwp, CARD8 index)&e.code;
+ <quote><p>
+ Return the value read from Sequencer register &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;void writeAttr(vgaHWPtr hwp, CARD8 index, CARD8, value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to Attribute Controller register
+ &s.code;index&e.code;. When writing out the index value this
+ function should set bit 5 (&s.code;0x20&e.code;) according to the
+ setting of &s.code;hwp->paletteEnabled&e.code; in order to
+ preserve the palette access state. It should be cleared when
+ &s.code;hwp->paletteEnabled&e.code; is &s.code;TRUE&e.code;
+ and set when it is &s.code;FALSE&e.code;.
+
+ </quote>
+
+ &s.code;CARD8 readAttr(vgaHWPtr hwp, CARD8 index)&e.code;
+ <quote><p>
+ Return the value read from Attribute Controller register
+ &s.code;index&e.code;. When writing out the index value this
+ function should set bit 5 (&s.code;0x20&e.code;) according to the
+ setting of &s.code;hwp->paletteEnabled&e.code; in order to
+ preserve the palette access state. It should be cleared when
+ &s.code;hwp->paletteEnabled&e.code; is &s.code;TRUE&e.code;
+ and set when it is &s.code;FALSE&e.code;.
+
+ </quote>
+
+ &s.code;void writeMiscOut(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write `&s.code;value&e.code;' to the Miscellaneous Output register.
+
+ </quote>
+
+ &s.code;CARD8 readMiscOut(vgwHWPtr hwp)&e.code;
+ <quote><p>
+ Return the value read from the Miscellaneous Output register.
+
+ </quote>
+
+ &s.code;void enablePalette(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ Clear the palette address source bit in the Attribute Controller
+ index register and set &s.code;hwp->paletteEnabled&e.code; to
+ &s.code;TRUE&e.code;.
+
+ </quote>
+
+ &s.code;void disablePalette(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ Set the palette address source bit in the Attribute Controller
+ index register and set &s.code;hwp->paletteEnabled&e.code; to
+ &s.code;FALSE&e.code;.
+
+ </quote>
+
+ &s.code;void writeDacMask(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to the DAC Mask register.
+
+ </quote>
+
+ &s.code;CARD8 readDacMask(vgaHWptr hwp)&e.code;
+ <quote><p>
+ Return the value read from the DAC Mask register.
+
+ </quote>
+
+ &s.code;void writeDacReadAddress(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to the DAC Read Address register.
+
+ </quote>
+
+ &s.code;void writeDacWriteAddress(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to the DAC Write Address register.
+
+ </quote>
+
+ &s.code;void writeDacData(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to the DAC Data register.
+
+ </quote>
+
+ &s.code;CARD8 readDacData(vgaHWptr hwp)&e.code;
+ <quote><p>
+ Return the value read from the DAC Data register.
+
+ </quote>
+
+ &s.code;CARD8 readEnable(vgaHWptr hwp)&e.code;
+ <quote><p>
+ Return the value read from the VGA Enable register. (Note: This
+ function is present in XFree86 4.1.0 and later.)
+
+ </quote>
+
+ &s.code;void writeEnable(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to the VGA Enable register. (Note: This
+ function is present in XFree86 4.1.0 and later.)
+
+ </quote>
+ </quote>
+
+<sect>Some notes about writing a driver<label id="sample">
+<p>
+
+<em>NOTE: some parts of this are not up to date</em>
+
+The following is an outline for writing a basic unaccelerated driver
+for a PCI video card with a linear mapped framebuffer, and which has a
+VGA core. It is includes some general information that is relevant to
+most drivers (even those which don't fit that basic description).
+
+The information here is based on the initial conversion of the Matrox
+Millennium driver to the ``new design''. For a fleshing out and sample
+implementation of some of the bits outlined here, refer to that driver.
+Note that this is an example only. The approach used here will not be
+appropriate for all drivers.
+
+Each driver must reserve a unique driver name, and a string that is used
+to prefix all of its externally visible symbols. This is to avoid name
+space clashes when loading multiple drivers. The examples here are for
+the ``ZZZ'' driver, which uses the ``ZZZ'' or ``zzz'' prefix for its externally
+visible symbols.
+
+
+<sect1>Include files
+<p>
+
+ All drivers normally include the following headers:
+ <quote>
+ &s.code;"xf86.h"&nl;
+ "xf86_OSproc.h"&nl;
+ "xf86_ansic.h"&nl;
+ "xf86Resources.h"&e.code;
+ </quote>
+ Wherever inb/outb (and related things) are used the following should be
+ included:
+ <quote>
+ &s.code;"compiler.h"&e.code;
+ </quote>
+ Note: in drivers, this must be included after &s.code;"xf86_ansic.h"&e.code;.
+
+ Drivers that need to access PCI vendor/device definitions need this:
+ <quote>
+ &s.code;"xf86PciInfo.h"&e.code;
+ </quote>
+
+ Drivers that need to access the PCI config space need this:
+ <quote>
+ &s.code;"xf86Pci.h"&e.code;
+ </quote>
+
+ Drivers using the mi banking wrapper need:
+
+ <quote>
+ &s.code;"mibank.h"&e.code;
+ </quote>
+
+ Drivers that initialise a SW cursor need this:
+ <quote>
+ &s.code;"mipointer.h"&e.code;
+ </quote>
+
+ All drivers implementing backing store need this:
+ <quote>
+ &s.code;"mibstore.h"&e.code;
+ </quote>
+
+ All drivers using the mi colourmap code need this:
+ <quote>
+ &s.code;"micmap.h"&e.code;
+ </quote>
+
+ If a driver uses the vgahw module, it needs this:
+ <quote>
+ &s.code;"vgaHW.h"&e.code;
+ </quote>
+
+ Drivers supporting VGA or Hercules monochrome screens need:
+ <quote>
+ &s.code;"xf1bpp.h"&e.code;
+ </quote>
+
+ Drivers supporting VGA or EGC 16-colour screens need:
+ <quote>
+ &s.code;"xf4bpp.h"&e.code;
+ </quote>
+
+ Drivers using cfb need:
+ <quote>
+ &s.code;#define PSZ 8&nl;
+ #include "cfb.h"&nl;
+ #undef PSZ&e.code;
+ </quote>
+
+ Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
+ <quote>
+ &s.code;"cfb16.h"&nl;
+ "cfb24.h"&nl;
+ "cfb32.h"&e.code;
+ </quote>
+
+ The driver's own header file:
+ <quote>
+ &s.code;"zzz.h"&e.code;
+ </quote>
+
+ Drivers must NOT include the following:
+
+ <quote>
+ &s.code;"xf86Priv.h"&nl;
+ "xf86Privstr.h"&nl;
+ "xf86_libc.h"&nl;
+ "xf86_OSlib.h"&nl;
+ "Xos.h"&e.code;&nl;
+ any OS header
+ </quote>
+
+
+<sect1>Data structures and initialisation
+<p>
+
+<itemize>
+ <item>The following macros should be defined:
+ <code>
+#define VERSION <version-as-an-int>
+#define ZZZ_NAME "ZZZ" /* the name used to prefix messages */
+#define ZZZ_DRIVER_NAME "zzz" /* the driver name as used in config file */
+#define ZZZ_MAJOR_VERSION <int>
+#define ZZZ_MINOR_VERSION <int>
+#define ZZZ_PATCHLEVEL <int>
+ </code>
+<p>
+ NOTE: &s.code;ZZZ_DRIVER_NAME&e.code; should match the name of the
+ driver module without things like the "lib" prefix, the "_drv" suffix
+ or filename extensions.
+<p>
+
+ <item>A DriverRec must be defined, which includes the functions required
+ at the pre-probe phase. The name of this DriverRec must be an
+ upper-case version of ZZZ_DRIVER_NAME (for the purposes of static
+ linking).
+<p>
+ <code>
+DriverRec ZZZ = {
+ VERSION,
+ ZZZ_DRIVER_NAME,
+ ZZZIdentify,
+ ZZZProbe,
+ ZZZAvailableOptions,
+ NULL,
+ 0
+};
+ </code>
+
+ <item>Define list of supported chips and their matching ID:
+<p>
+ <code>
+static SymTabRec ZZZChipsets[] = {
+ { PCI_CHIP_ZZZ1234, "zzz1234a" },
+ { PCI_CHIP_ZZZ5678, "zzz5678a" },
+ { -1, NULL }
+};
+ </code>
+<p>
+ The token field may be any integer value that the driver may use to
+ uniquely identify the supported chipsets. For drivers that support
+ only PCI devices using the PCI device IDs might be a natural choice,
+ but this isn't mandatory. For drivers that support both PCI and other
+ devices (like ISA), some other ID should probably used. When other
+ IDs are used as the tokens it is recommended that the names be
+ defined as an &s.code;enum&e.code; type.
+<p>
+ <item>If the driver uses the &s.code;xf86MatchPciInstances(&e.code;)
+ helper (recommended for drivers that support PCI cards) a list that
+ maps PCI IDs to chip IDs and fixed resources must be defined:
+<p>
+ <code>
+static PciChipsets ZZZPciChipsets[] = {
+ { PCI_CHIP_ZZZ1234, PCI_CHIP_ZZZ1234, RES_SHARED_VGA },
+ { PCI_CHIP_ZZZ5678, PCI_CHIP_ZZZ5678, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+}
+ </code>
+<p>
+ <item>Define the &s.code;XF86ModuleVersionInfo&e.code; struct for the
+ driver. This is required for the dynamically loaded version:
+<p>
+ <code>
+static XF86ModuleVersionInfo zzzVersRec =
+{
+ "zzz",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ ZZZ_MAJOR_VERSION, ZZZ_MINOR_VERSION, ZZZ_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+ </code>
+<p>
+ <item>Define a data structure to hold the driver's screen-specific data.
+ This must be used instead of global variables. This would be defined
+ in the &s.code;"zzz.h"&e.code; file, something like:
+<p>
+ <code>
+typedef struct {
+ type1 field1;
+ type2 field2;
+ int fooHack;
+ Bool pciRetry;
+ Bool noAccel;
+ Bool hwCursor;
+ CloseScreenProcPtr CloseScreen;
+ OptionInfoPtr Options;
+ ...
+} ZZZRec, *ZZZPtr;
+ </code>
+<p>
+ <item>Define the list of config file Options that the driver accepts. For
+ consistency between drivers those in the list of ``standard'' options
+ should be used where appropriate before inventing new options.
+<p>
+ <code>
+typedef enum {
+ OPTION_FOO_HACK,
+ OPTION_PCI_RETRY,
+ OPTION_HW_CURSOR,
+ OPTION_NOACCEL
+} ZZZOpts;
+
+static const OptionInfoRec ZZZOptions[] = {
+ { OPTION_FOO_HACK, "FooHack", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+ </code>
+<p>
+</itemize>
+
+<sect1>Functions
+<p>
+
+
+<sect2>SetupProc
+<p>
+
+ For dynamically loaded modules, a &s.code;ModuleData&e.code;
+ variable is required. It is should be the name of the driver
+ prepended to "ModuleData". A &s.code;Setup()&e.code; function is
+ also required, which calls &s.code;xf86AddDriver()&e.code; to add
+ the driver to the main list of drivers.
+
+ <code>
+static MODULESETUPPROTO(zzzSetup);
+
+XF86ModuleData zzzModuleData = { &zzzVersRec, zzzSetup, NULL };
+
+static pointer
+zzzSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ /* This module should be loaded only once, but check to be sure. */
+
+ if (!setupDone) {
+ /*
+ * Modules that this driver always requires may be loaded
+ * here by calling LoadSubModule().
+ */
+
+ setupDone = TRUE;
+ xf86AddDriver(&MGA, module, 0);
+
+ /*
+ * The return value must be non-NULL on success even though
+ * there is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+ </code>
+
+<sect2>GetRec, FreeRec
+<p>
+
+ A function is usually required to allocate the driver's
+ screen-specific data structure and hook it into the
+ &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field.
+ The &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; is
+ initialised to &s.code;NULL&e.code;, so it is easy to check if the
+ initialisation has already been done. After allocating it, initialise
+ the fields. By using &s.code;xnfcalloc()&e.code; to do the allocation
+ it is zeroed, and if the allocation fails the server exits.
+<p>
+ NOTE:
+ When allocating structures from inside the driver which are defined
+ on the common level it is important to initialize the structure to
+ zero.
+ Only this guarantees that the server remains source compatible to
+ future changes in common level structures.
+
+ <code>
+static Bool
+ZZZGetRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+ pScrn->driverPrivate = xnfcalloc(sizeof(ZZZRec), 1);
+ /* Initialise as required */
+ ...
+ return TRUE;
+}
+ </code>
+
+ Define a macro in &s.code;"zzz.h"&e.code; which gets a pointer to
+ the &s.code;ZZZRec&e.code; when given &s.code;pScrn&e.code;:
+
+ <code>
+#define ZZZPTR(p) ((ZZZPtr)((p)->driverPrivate))
+ </code>
+
+ Define a function to free the above, setting it to &s.code;NULL&e.code;
+ once it has been freed:
+
+ <code>
+static void
+ZZZFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+ </code>
+
+<sect2>Identify
+<p>
+
+ Define the &s.code;Identify()&e.code; function. It is run before
+ the Probe, and typically prints out an identifying message, which
+ might include the chipsets it supports. This function is mandatory:
+
+ <code>
+static void
+ZZZIdentify(int flags)
+{
+ xf86PrintChipsets(ZZZ_NAME, "driver for ZZZ Tech chipsets",
+ ZZZChipsets);
+}
+ </code>
+
+<sect2>Probe
+<p>
+
+ Define the &s.code;Probe()&e.code; function. The purpose of this
+ is to find all instances of the hardware that the driver supports,
+ and for the ones not already claimed by another driver, claim the
+ slot, and allocate a &s.code;ScrnInfoRec&e.code;. This should be
+ a minimal probe, and it should under no circumstances leave the
+ state of the hardware changed. Because a device is found, don't
+ assume that it will be used. Don't do any initialisations other
+ than the required &s.code;ScrnInfoRec&e.code; initialisations.
+ Don't allocate any new data structures.
+
+ This function is mandatory.
+
+ NOTE: The &s.code;xf86DrvMsg()&e.code; functions cannot be used from
+ the Probe.
+
+ <code>
+static Bool
+ZZZProbe(DriverPtr drv, int flags)
+{
+ Bool foundScreen = FALSE;
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+
+ /*
+ * Find the config file Device sections that match this
+ * driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(ZZZ_DRIVER_NAME,
+ &devSections)) <= 0) {
+ return FALSE;
+ }
+
+ /*
+ * Since this is a PCI card, "probing" just amounts to checking
+ * the PCI data that the server has already collected. If there
+ * is none, return.
+ *
+ * Although the config file is allowed to override things, it
+ * is reasonable to not allow it to override the detection
+ * of no PCI video cards.
+ *
+ * The provided xf86MatchPciInstances() helper takes care of
+ * the details.
+ */
+ /* test if PCI bus present */
+ if (xf86GetPciVideoInfo()) {
+
+ numUsed = xf86MatchPciInstances(ZZZ_NAME, PCI_VENDOR_ZZZ,
+ ZZZChipsets, ZZZPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+ if ((pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
+ ZZZPciChipsets, NULL, NULL,
+ NULL, NULL, NULL))) {
+ /* Allocate a ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = ZZZ_DRIVER_NAME;
+ pScrn->name = ZZZ_NAME;
+ pScrn->Probe = ZZZProbe;
+ pScrn->PreInit = ZZZPreInit;
+ pScrn->ScreenInit = ZZZScreenInit;
+ pScrn->SwitchMode = ZZZSwitchMode;
+ pScrn->AdjustFrame = ZZZAdjustFrame;
+ pScrn->EnterVT = ZZZEnterVT;
+ pScrn->LeaveVT = ZZZLeaveVT;
+ pScrn->FreeScreen = ZZZFreeScreen;
+ pScrn->ValidMode = ZZZValidMode;
+ foundScreen = TRUE;
+ /* add screen to entity */
+ }
+ }
+ xfree(usedChips);
+ }
+
+#ifdef HAS_ISA_DEVS
+ /*
+ * If the driver supports ISA hardware, the following block
+ * can be included too.
+ */
+ numUsed = xf86MatchIsaInstances(ZZZ_NAME, ZZZChipsets,
+ ZZZIsaChipsets, drv, ZZZFindIsaDevice,
+ devSections, numDevSections, &usedChips);
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+ if ((pScrn = xf86ConfigIsaEntity(pScrn, flags, usedChips[i],
+ ZZZIsaChipsets, NULL, NULL, NULL,
+ NULL, NULL))) {
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = ZZZ_DRIVER_NAME;
+ pScrn->name = ZZZ_NAME;
+ pScrn->Probe = ZZZProbe;
+ pScrn->PreInit = ZZZPreInit;
+ pScrn->ScreenInit = ZZZScreenInit;
+ pScrn->SwitchMode = ZZZSwitchMode;
+ pScrn->AdjustFrame = ZZZAdjustFrame;
+ pScrn->EnterVT = ZZZEnterVT;
+ pScrn->LeaveVT = ZZZLeaveVT;
+ pScrn->FreeScreen = ZZZFreeScreen;
+ pScrn->ValidMode = ZZZValidMode;
+ foundScreen = TRUE;
+ }
+ }
+ xfree(usedChips);
+#endif /* HAS_ISA_DEVS */
+
+ xfree(devSections);
+ return foundScreen;
+ </code>
+
+<sect2>AvailableOptions
+<p>
+
+ Define the &s.code;AvailableOptions()&e.code; function. The purpose
+ of this is to return the available driver options back to the
+ -configure option, so that an xorg.conf file can be built and the
+ user can see which options are available for them to use.
+
+<sect2>PreInit
+<p>
+
+ Define the &s.code;PreInit()&e.code; function. The purpose of
+ this is to find all the information required to determine if the
+ configuration is usable, and to initialise those parts of the
+ &s.code;ScrnInfoRec&e.code; that can be set once at the beginning
+ of the first server generation. The information should be found in
+ the least intrusive way possible.
+
+ This function is mandatory.
+
+ NOTES:
+ <enum>
+ <item>The &s.code;PreInit()&e.code; function is only called once
+ during the life of the X server (at the start of the first
+ generation).
+
+ <item>Data allocated here must be of the type that persists for
+ the life of the X server. This means that data that hooks into
+ the &s.code;ScrnInfoRec&e.code;'s &s.code;privates&e.code;
+ field should be allocated here, but data that hooks into the
+ &s.code;ScreenRec&e.code;'s &s.code;devPrivates&e.code; field
+ should not be allocated here. The &s.code;driverPrivate&e.code;
+ field should also be allocated here.
+
+ <item>Although the &s.code;ScrnInfoRec&e.code; has been allocated
+ before this function is called, the &s.code;ScreenRec&e.code;
+ has not been allocated. That means that things requiring it
+ cannot be used in this function.
+
+ <item>Very little of the &s.code;ScrnInfoRec&e.code; has been
+ initialised when this function is called. It is important to
+ get the order of doing things right in this function.
+
+ </enum>
+
+ <code>
+static Bool
+ZZZPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ /* Fill in the monitor field */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * If using the vgahw module, it will typically be loaded
+ * here by calling xf86LoadSubModule(pScrn, "vgahw");
+ */
+
+ /*
+ * Set the depth/bpp. Use the globally preferred depth/bpp. If the
+ * driver has special default depth/bpp requirements, the defaults should
+ * be specified here explicitly.
+ * We support both 24bpp and 32bpp framebuffer layouts.
+ * This sets pScrn->display also.
+ */
+ if (!xf86SetDepthBpp(pScrn, 0, 0, 0,
+ Support24bppFb | Support32bppFb)) {
+ return FALSE;
+ } else {
+ if (depth/bpp isn't one we support) {
+ print error message;
+ return FALSE;
+ }
+ }
+ /* Print out the depth/bpp that was set */
+ xf86PrintDepthBpp(pScrn);
+
+ /* Set bits per RGB for 8bpp */
+ if (pScrn->depth <= 8) {
+ /* Take into account a dac_6_bit option here */
+ pScrn->rgbBits = 6 or 8;
+ }
+
+ /*
+ * xf86SetWeight() and xf86SetDefaultVisual() must be called
+ * after pScrn->display is initialised.
+ */
+
+ /* Set weight/mask/offset for depth > 8 */
+ if (pScrn->depth > 8) {
+ if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
+ return FALSE;
+ } else {
+ if (weight isn't one we support) {
+ print error message;
+ return FALSE;
+ }
+ }
+ }
+
+ /* Set the default visual. */
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ if (visual isn't one we support) {
+ print error message;
+ return FALSE;
+ }
+ }
+
+ /* If the driver supports gamma correction, set the gamma. */
+ if (!xf86SetGamma(pScrn, default_gamma)) {
+ return FALSE;
+ }
+
+ /* This driver uses a programmable clock */
+ pScrn->progClock = TRUE;
+
+ /* Allocate the ZZZRec driverPrivate */
+ if (!ZZZGetRec(pScrn)) {
+ return FALSE;
+ }
+
+ pZzz = ZZZPTR(pScrn);
+
+ /* Collect all of the option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /*
+ * Process the options based on the information in ZZZOptions.
+ * The results are written to pZzz->Options. If all of the options
+ * processing is done within this function a local variable "options"
+ * can be used instead of pZzz->Options.
+ */
+ if (!(pZzz->Options = xalloc(sizeof(ZZZOptions))))
+ return FALSE;
+ (void)memcpy(pZzz->Options, ZZZOptions, sizeof(ZZZOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pZzz->Options);
+
+ /*
+ * Set various fields of ScrnInfoRec and/or ZZZRec based on
+ * the options found.
+ */
+ from = X_DEFAULT;
+ pZzz->hwCursor = FALSE;
+ if (xf86IsOptionSet(pZzz->Options, OPTION_HW_CURSOR)) {
+ from = X_CONFIG;
+ pZzz->hwCursor = TRUE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pZzz->hwCursor ? "HW" : "SW");
+ if (xf86IsOptionSet(pZzz->Options, OPTION_NOACCEL)) {
+ pZzz->noAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Acceleration disabled\n");
+ } else {
+ pZzz->noAccel = FALSE;
+ }
+ if (xf86IsOptionSet(pZzz->Options, OPTION_PCI_RETRY)) {
+ pZzz->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ pZzz->fooHack = 0;
+ if (xf86GetOptValInteger(pZzz->Options, OPTION_FOO_HACK,
+ &pZzz->fooHack)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Foo Hack set to %d\n",
+ pZzz->fooHack);
+ }
+
+ /*
+ * Find the PCI slot(s) that this screen claimed in the probe.
+ * In this case, exactly one is expected, so complain otherwise.
+ * Note in this case we're not interested in the card types so
+ * that parameter is set to NULL.
+ */
+ if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL))
+ != 1) {
+ print error message;
+ ZZZFreeRec(pScrn);
+ if (i > 0)
+ xfree(pciList);
+ return FALSE;
+ }
+ /* Note that pciList should be freed below when no longer needed */
+
+ /*
+ * Determine the chipset, allowing config file chipset and
+ * chipid values to override the probed information. The config
+ * chipset value has precedence over its chipid value if both
+ * are present.
+ *
+ * It isn't necessary to fill in pScrn->chipset if the driver
+ * keeps track of the chipset in its ZZZRec.
+ */
+
+ ...
+
+ /*
+ * Determine video memory, fb base address, I/O addresses, etc,
+ * allowing the config file to override probed values.
+ *
+ * Set the appropriate pScrn fields (videoRam is probably the
+ * most important one that other code might require), and
+ * print out the settings.
+ */
+
+ ...
+
+ /* Initialise a clockRanges list. */
+
+ ...
+
+ /* Set any other chipset specific things in the ZZZRec */
+
+ ...
+
+ /* Select valid modes from those available */
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, minPitch, maxPitch, rounding,
+ minHeight, maxHeight,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pScrn->videoRam * 1024,
+ LOOKUP_BEST_REFRESH);
+ if (i == -1) {
+ ZZZFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+
+ xf86PruneDriverModes(pScrn);
+
+ /* If no valid modes, return */
+
+ if (i == 0 || pScrn->modes == NULL) {
+ print error message;
+ ZZZFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Initialise the CRTC fields for the modes. This driver expects
+ * vertical values to be halved for interlaced modes.
+ */
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list. */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used. */
+ xf86PrintModes(pScrn);
+
+ /* Set the DPI */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ mod = "xf1bpp";
+ break;
+ case 4:
+ mod = "xf4bpp";
+ break;
+ case 8:
+ mod = "cfb";
+ break;
+ case 16:
+ mod = "cfb16";
+ break;
+ case 24:
+ mod = "cfb24";
+ break;
+ case 32:
+ mod = "cfb32";
+ break;
+ }
+ if (mod && !xf86LoadSubModule(pScrn, mod))
+ ZZZFreeRec(pScrn);
+ return FALSE;
+
+ /* Load XAA if needed */
+ if (!pZzz->noAccel || pZzz->hwCursor)
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ ZZZFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Done */
+ return TRUE;
+}
+ </code>
+
+<sect2>MapMem, UnmapMem
+<p>
+
+ Define functions to map and unmap the video memory and any other
+ memory apertures required. These functions are not mandatory, but
+ it is often useful to have such functions.
+
+ <code>
+static Bool
+ZZZMapMem(ScrnInfoPtr pScrn)
+{
+ /* Call xf86MapPciMem() to map each PCI memory area */
+ ...
+ return TRUE or FALSE;
+}
+
+static Bool
+ZZZUnmapMem(ScrnInfoPtr pScrn)
+{
+ /* Call xf86UnMapVidMem() to unmap each memory area */
+ ...
+ return TRUE or FALSE;
+}
+ </code>
+
+<sect2>Save, Restore
+<p>
+
+ Define functions to save and restore the original video state. These
+ functions are not mandatory, but are often useful.
+
+ <code>
+static void
+ZZZSave(ScrnInfoPtr pScrn)
+{
+ /*
+ * Save state into per-screen data structures.
+ * If using the vgahw module, vgaHWSave will typically be
+ * called here.
+ */
+ ...
+}
+
+static void
+ZZZRestore(ScrnInfoPtr pScrn)
+{
+ /*
+ * Restore state from per-screen data structures.
+ * If using the vgahw module, vgaHWRestore will typically be
+ * called here.
+ */
+ ...
+}
+ </code>
+
+<sect2>ModeInit
+<p>
+
+ Define a function to initialise a new video mode. This function isn't
+ mandatory, but is often useful.
+
+ <code>
+static Bool
+ZZZModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ /*
+ * Program a video mode. If using the vgahw module,
+ * vgaHWInit and vgaRestore will typically be called here.
+ * Once up to the point where there can't be a failure
+ * set pScrn->vtSema to TRUE.
+ */
+ ...
+}
+ </code>
+
+<sect2>ScreenInit
+<p>
+
+ Define the &s.code;ScreenInit()&e.code; function. This is called
+ at the start of each server generation, and should fill in as much
+ of the &s.code;ScreenRec&e.code; as possible as well as any other
+ data that is initialised once per generation. It should initialise
+ the framebuffer layers it is using, and initialise the initial video
+ mode.
+
+ This function is mandatory.
+
+ NOTE: The &s.code;ScreenRec&e.code; (&s.code;pScreen&e.code;) is
+ passed to this driver, but it and the
+ &s.code;ScrnInfoRecs&e.code; are not yet hooked into each
+ other. This means that in this function, and functions it
+ calls, one cannot be found from the other.
+
+ <code>
+static Bool
+ZZZScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ /* Get the ScrnInfoRec */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ /*
+ * If using the vgahw module, its data structures and related
+ * things are typically initialised/mapped here.
+ */
+
+ /* Save the current video state */
+ ZZZSave(pScrn);
+
+ /* Initialise the first mode */
+ ZZZModeInit(pScrn, pScrn->currentMode);
+
+ /* Set the viewport if supported */
+
+ ZZZAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * Setup the screen's visuals, and initialise the framebuffer
+ * code.
+ */
+
+ /* Reset the visual list */
+ miClearVisualTypes();
+
+ /*
+ * Setup the visuals supported. This driver only supports
+ * TrueColor for bpp > 8, so the default set of visuals isn't
+ * acceptable. To deal with this, call miSetVisualTypes with
+ * the appropriate visual mask.
+ */
+
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Initialise the framebuffer.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ ret = cfb24ScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ print a message about an internal error;
+ ret = FALSE;
+ break;
+ }
+
+ if (!ret)
+ return FALSE;
+
+ /* Override the default mask/offset settings */
+ if (pScrn->bitsPerPixel > 8) {
+ for (i = 0, visual = pScreen->visuals;
+ i < pScreen->numVisuals; i++, visual++) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ /*
+ * If banking is needed, initialise an miBankInfoRec (defined in
+ * "mibank.h"), and call miInitializeBanking().
+ */
+ if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
+ pScrn->displayWidth, pBankInfo))
+ return FALSE;
+
+ /*
+ * If backing store is to be supported (as is usually the case),
+ * initialise it.
+ */
+ miInitializeBackingStore(pScreen);
+
+ /*
+ * Set initial black & white colourmap indices.
+ */
+ xf86SetBlackWhitePixels(pScreen);
+
+ /*
+ * Install colourmap functions. If using the vgahw module,
+ * vgaHandleColormaps would usually be called here.
+ */
+
+ ...
+
+ /*
+ * Initialise cursor functions. This example is for the mi
+ * software cursor.
+ */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Initialise the default colourmap */
+ switch (pScrn->depth) {
+ case 1:
+ if (!xf1bppCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+ case 4:
+ if (!xf4bppCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+ default:
+ if (!cfbCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+ }
+
+ /*
+ * Wrap the CloseScreen vector and set SaveScreen.
+ */
+ ZZZPTR(pScrn)->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = ZZZCloseScreen;
+ pScreen->SaveScreen = ZZZSaveScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Done */
+ return TRUE;
+}
+ </code>
+
+
+<sect2>SwitchMode
+<p>
+
+ Define the &s.code;SwitchMode()&e.code; function if mode switching
+ is supported by the driver.
+
+ <code>
+static Bool
+ZZZSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return ZZZModeInit(xf86Screens[scrnIndex], mode);
+}
+ </code>
+
+
+<sect2>AdjustFrame
+<p>
+
+ Define the &s.code;AdjustFrame()&e.code; function if the driver
+ supports this.
+
+ <code>
+static void
+ZZZAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ /* Adjust the viewport */
+}
+ </code>
+
+
+<sect2>EnterVT, LeaveVT
+<p>
+
+ Define the &s.code;EnterVT()&e.code; and &s.code;LeaveVT()&e.code;
+ functions.
+
+ These functions are mandatory.
+
+ <code>
+static Bool
+ZZZEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ return ZZZModeInit(pScrn, pScrn->currentMode);
+}
+
+static void
+ZZZLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ ZZZRestore(pScrn);
+}
+ </code>
+
+<sect2>CloseScreen
+<p>
+
+ Define the &s.code;CloseScreen()&e.code; function:
+
+ This function is mandatory. Note that it unwraps the previously
+ wrapped &s.code;pScreen->CloseScreen&e.code;, and finishes by
+ calling it.
+
+ <code>
+static Bool
+ZZZCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ if (pScrn->vtSema) {
+ ZZZRestore(pScrn);
+ ZZZUnmapMem(pScrn);
+ }
+ pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = ZZZPTR(pScrn)->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+ </code>
+
+<sect2>SaveScreen
+<p>
+
+ Define the &s.code;SaveScreen()&e.code; function (the screen
+ blanking function). When using the vgahw module, this will typically
+ be:
+
+ <code>
+static Bool
+ZZZSaveScreen(ScreenPtr pScreen, int mode)
+{
+ return vgaHWSaveScreen(pScreen, mode);
+}
+ </code>
+
+ This function is mandatory. Before modifying any hardware register
+ directly this function needs to make sure that the Xserver is active
+ by checking if &s.code;pScrn&e.code; is non-NULL and for
+ &s.code;pScrn->vtSema == TRUE&e.code;.
+
+<sect2>FreeScreen
+<p>
+
+ Define the &s.code;FreeScreen()&e.code; function. This function
+ is optional. It should be defined if the &s.code;ScrnInfoRec&e.code;
+ &s.code;driverPrivate&e.code; field is used so that it can be freed
+ when a screen is deleted by the common layer for reasons possibly
+ beyond the driver's control. This function is not used in during
+ normal (error free) operation. The per-generation data is freed by
+ the &s.code;CloseScreen()&e.code; function.
+
+ <code>
+static void
+ZZZFreeScreen(int scrnIndex, int flags)
+{
+ /*
+ * If the vgahw module is used vgaHWFreeHWRec() would be called
+ * here.
+ */
+ ZZZFreeRec(xf86Screens[scrnIndex]);
+}
+ </code>
+
+
+</article>
|