8662 lines
		
	
	
		
			297 KiB
		
	
	
	
		
			XML
		
	
	
	
			
		
		
	
	
			8662 lines
		
	
	
		
			297 KiB
		
	
	
	
		
			XML
		
	
	
	
<?xml version="1.0" encoding="ISO-8859-1"?>
 | 
						|
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
 | 
						|
 "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
 | 
						|
 <!ENTITY % xorg-defs SYSTEM "defs.ent"> %xorg-defs;
 | 
						|
 <!ENTITY % defs SYSTEM "/xserver/doc/xml/xserver.ent"> %defs;
 | 
						|
 <!-- config file keyword markup -->
 | 
						|
 <!-- specific config file keywords -->
 | 
						|
 <!ENTITY k.device "<emphasis>Device</emphasis>">
 | 
						|
 <!ENTITY k.monitor "<emphasis>Monitor</emphasis>">
 | 
						|
 <!ENTITY k.display "<emphasis>Display</emphasis>">
 | 
						|
 <!ENTITY k.inputdevice "<emphasis>InputDevice</emphasis>">
 | 
						|
 <!ENTITY k.screen "<emphasis>Screen</emphasis>">
 | 
						|
 <!ENTITY k.serverlayout "<emphasis>ServerLayout</emphasis>">
 | 
						|
 <!ENTITY k.driver "<emphasis>Driver</emphasis>">
 | 
						|
 <!ENTITY k.module "<emphasis>Module</emphasis>">
 | 
						|
 <!ENTITY k.identifier "<emphasis>Identifier</emphasis>">
 | 
						|
 <!ENTITY k.serverflags "<emphasis>ServerFlags</emphasis>">
 | 
						|
] >
 | 
						|
 | 
						|
<article id="ddxDesign">
 | 
						|
  <articleinfo>
 | 
						|
 | 
						|
    <title>XFree86 DDX Design</title>
 | 
						|
 | 
						|
    <authorgroup>
 | 
						|
      <corpauthor>The XFree86 Project</corpauthor>
 | 
						|
      <corpauthor>The X.Org Foundation</corpauthor>
 | 
						|
 | 
						|
      <othercredit>
 | 
						|
	<firstname>Jim</firstname><surname>Gettys</surname>
 | 
						|
	<contrib>Updates for X11R6.7</contrib>
 | 
						|
      </othercredit>
 | 
						|
    </authorgroup>
 | 
						|
 | 
						|
    <pubdate>&xserver.reldate;</pubdate>
 | 
						|
    <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo>
 | 
						|
    <releaseinfo>X Server Version &xserver.version;</releaseinfo>
 | 
						|
 | 
						|
  </articleinfo>
 | 
						|
 | 
						|
  <note><para>
 | 
						|
This document describes software undergoing continual evolution, and
 | 
						|
the interfaces described here are subject to change without notice.
 | 
						|
This document is intended to cover the interfaces as found in the
 | 
						|
xorg-server-&xserver.version; release, but is probably not completely
 | 
						|
in sync with the code base.
 | 
						|
    </para></note>
 | 
						|
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>Preface</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
This document was originally the design spec for the DDX layer of the
 | 
						|
XFree86 4.0 X server.  The X.Org Foundation adopted the XFree86 4.4rc2
 | 
						|
version of that server as the basis of the Xorg server project, and has
 | 
						|
evolved the XFree86 DDX layer greatly since forking.   This document thus
 | 
						|
covers only the current implementation of the XFree86 DDX as found in the
 | 
						|
Xorg server &xserver.version; release, and no longer matches the XFree86
 | 
						|
server itself.
 | 
						|
      </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The XFree86 Project's broad design principles for XFree86 4.0 were:
 | 
						|
      <itemizedlist>
 | 
						|
	<listitem><para>keep it reasonable
 | 
						|
	    <itemizedlist>
 | 
						|
	      <listitem><para>We cannot rewrite the complete server
 | 
						|
		</para></listitem>
 | 
						|
	      <listitem><para>We don't want to re-invent the wheel
 | 
						|
		</para></listitem>
 | 
						|
	    </itemizedlist></para></listitem>
 | 
						|
	<listitem><para>keep it modular
 | 
						|
	    <itemizedlist>
 | 
						|
	      <listitem><para>As many things as possible should go into modules
 | 
						|
		</para></listitem>
 | 
						|
	      <listitem><para>The basic loader binary should be minimal
 | 
						|
		</para></listitem>
 | 
						|
	      <listitem><para>A clean design with well defined layering is
 | 
						|
		  important</para></listitem>
 | 
						|
	      <listitem><para>DDX specific global variables are a nono
 | 
						|
		</para></listitem>
 | 
						|
	      <listitem><para>The structure should be flexible enough to allow
 | 
						|
		  future extensions</para></listitem>
 | 
						|
	      <listitem><para>The structure should minimize duplication of
 | 
						|
		  common code</para></listitem>
 | 
						|
	    </itemizedlist></para></listitem>
 | 
						|
	<listitem><para>keep important features in mind
 | 
						|
	    <itemizedlist>
 | 
						|
	      <listitem><para>multiple screens, including multiple instances
 | 
						|
		  of drivers</para></listitem>
 | 
						|
	      <listitem><para>mixing different color depths and visuals on
 | 
						|
		  different and ideally even on the same screen
 | 
						|
		</para></listitem>
 | 
						|
	      <listitem><para>better control of the PCI device used
 | 
						|
		</para></listitem>
 | 
						|
	      <listitem><para>better config file parser</para></listitem>
 | 
						|
	      <listitem><para>get rid of all VGA compatibility assumptions
 | 
						|
		</para></listitem>
 | 
						|
	    </itemizedlist></para></listitem>
 | 
						|
      </itemizedlist>
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
While the XFree86 project had a goal of avoiding changes to the DIX
 | 
						|
layer unless they found major deficiencies there, to avoid divergence from
 | 
						|
the X.Org sample implementation they were integrating changes from, the
 | 
						|
X.Org developers now maintain both sides, and make changes where they are
 | 
						|
most appropriate.   This document concentrates on the XFree86 DDX layer used
 | 
						|
in the Xorg server itself (the code found in <filename>hw/xfree86</filename>
 | 
						|
in the source tree), and developers will also want to refer to the
 | 
						|
<filename>Xserver-spec</filename> documentation that covers the DIX layer
 | 
						|
routines common to all the X servers in the sample implementation.
 | 
						|
    </para>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>The xorg.conf File</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
The xorg.conf file format is based on the XF86Config format from XFree86 4.4,
 | 
						|
which is in turn similar to the old XFree86 3.x XF86Config format, with the
 | 
						|
following changes:
 | 
						|
    </para>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>&k.device; section</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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:
 | 
						|
 | 
						|
 | 
						|
	<variablelist>
 | 
						|
	  <varlistentry><term>Driver "drivername"</term>
 | 
						|
	    <listitem><para>
 | 
						|
        Specifies the name of the driver to be used for the card.  This
 | 
						|
        is mandatory.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
	  <varlistentry><term>BusID "busslot"</term>
 | 
						|
	    <listitem><para>
 | 
						|
        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@domain:slot:func". The "@domain" part
 | 
						|
        can be left out for domain 0.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
	</variablelist>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    A &k.device; section is considered <quote>active</quote> if there is a reference
 | 
						|
    to it in an active &k.screen; section.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>&k.screen; section</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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 <quote>active</quote>
 | 
						|
    if there is a reference to it either from the command line, or from
 | 
						|
    an active &k.serverlayout; section.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>&k.inputdevice; section</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The &k.inputdevice; section is a new section that describes
 | 
						|
    configuration information for input devices.  It replaces the old
 | 
						|
    <emphasis>Keyboard</emphasis>, <emphasis>Pointer</emphasis> and <emphasis>XInput</emphasis>
 | 
						|
    sections.  Like the &k.device; section, it has two mandatory keywords:
 | 
						|
    &k.identifier; and &k.driver;.  For compatibility purposes the old
 | 
						|
    <emphasis>Keyboard</emphasis> and <emphasis>Pointer</emphasis> sections are
 | 
						|
    converted by the parser into &k.inputdevice; sections as follows:
 | 
						|
 | 
						|
	<variablelist>
 | 
						|
	  <varlistentry><term><emphasis>Keyboard</emphasis></term>
 | 
						|
	    <listitem><literallayout>
 | 
						|
             &k.identifier; "Implicit Core Keyboard"
 | 
						|
             &k.driver; "kbd"
 | 
						|
	      </literallayout></listitem></varlistentry>
 | 
						|
	  <varlistentry><term><emphasis>Pointer</emphasis></term>
 | 
						|
	    <listitem><literallayout>
 | 
						|
             &k.identifier; "Implicit Core Pointer"
 | 
						|
             &k.driver; "mouse"
 | 
						|
	      </literallayout></listitem></varlistentry>
 | 
						|
	</variablelist>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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 <option>-screen</option> 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 "kbd" and "mouse" are used as the core
 | 
						|
    keyboard and pointer respectively.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>&k.serverlayout; section</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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:
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
      Section "ServerLayout"
 | 
						|
        Identifier "Main Layout"
 | 
						|
        Screen     0 "Screen 1" ""  ""  ""  "Screen 2"
 | 
						|
        Screen     1 "Screen 2"
 | 
						|
        Screen     "Screen 3"
 | 
						|
      EndSection
 | 
						|
	</programlisting>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The preferred way of specifying the layout is to explicitly specify
 | 
						|
    the screen's location in absolute terms or relative to another
 | 
						|
    screen.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    In the absolute case, the upper left corner's coordinates are given
 | 
						|
    after the <emphasis>Absolute</emphasis> keyword.  If the coordinates are
 | 
						|
    omitted, a value of <code>(0,0)</code> is assumed.  An example
 | 
						|
    of absolute positioning follows:
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
      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
 | 
						|
	</programlisting>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    In the relative case, the position is specified by either using one of
 | 
						|
    the following keywords followed by the name of the reference screen:
 | 
						|
 | 
						|
	<simplelist type='vert' columns='1'>
 | 
						|
	  <member><emphasis>RightOf</emphasis></member>
 | 
						|
	  <member><emphasis>LeftOf</emphasis></member>
 | 
						|
	  <member><emphasis>Above</emphasis></member>
 | 
						|
	  <member><emphasis>Below</emphasis></member>
 | 
						|
	  <member><emphasis>Relative</emphasis></member>
 | 
						|
	</simplelist>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    When the <emphasis>Relative</emphasis> 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.
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
      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
 | 
						|
	</programlisting>
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Options</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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 <link linkend="options">Options</link> section
 | 
						|
    for details.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>Driver Interface</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
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.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The entry points for drawing operations are already taken care of by
 | 
						|
the framebuffer code.  Extensions and enhancements to framebuffer code
 | 
						|
are outside the scope of this document.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
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 <quote>helper</quote> 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.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
Events that a driver needs to react to are:
 | 
						|
 | 
						|
      <variablelist>
 | 
						|
	<varlistentry><term>ScreenInit</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     An initialisation function is called from the DIX layer for each
 | 
						|
     screen at the start of each server generation.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	<varlistentry><term>Enter VT</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     The server takes control of the console.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	<varlistentry><term>Leave VT</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     The server releases control of the console.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	<varlistentry><term>Mode Switch</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     Change video mode.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	<varlistentry><term>ViewPort change</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     Change the origin of the physical view port.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	<varlistentry><term>ScreenSaver state change</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     Screen saver activation/deactivation.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	<varlistentry><term>CloseScreen</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     A close screen function is called from the DIX layer for each screen
 | 
						|
     at the end of each server generation.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
      </variablelist>
 | 
						|
    </para>
 | 
						|
 | 
						|
 | 
						|
    <para>
 | 
						|
In addition to these events, the following functions are required by
 | 
						|
the XFree86 common layer:
 | 
						|
 | 
						|
      <variablelist>
 | 
						|
	<varlistentry><term>Identify</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     Print a driver identifying message.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	<varlistentry><term>Probe</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     This is how a driver identifies if there is any hardware present that
 | 
						|
     it knows how to drive.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	<varlistentry><term>PreInit</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     Process information from the xorg.conf file, determine the
 | 
						|
     full characteristics of the hardware, and determine if a valid
 | 
						|
     configuration is present.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
      </variablelist>
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The VidMode extension also requires:
 | 
						|
 | 
						|
      <variablelist>
 | 
						|
	<varlistentry><term>ValidMode</term>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
     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.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
      </variablelist>
 | 
						|
    </para>
 | 
						|
 | 
						|
 | 
						|
    <para>
 | 
						|
Other extensions may require other entry points.  The drivers will
 | 
						|
inform the common layer of these in such cases.
 | 
						|
    </para>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>Resource Access Control Introduction</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
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.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Terms and Definitions</title>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>Bus</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    <quote>Bus</quote> 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).  <quote>Bus</quote> 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.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    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.
 | 
						|
	</para>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>Entity</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    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.
 | 
						|
	</para>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>Resource</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    <quote>Resource</quote> refers to a range of memory or I/O addresses an entity
 | 
						|
    can decode.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    If a device is capable of disabling this decoding the resource is
 | 
						|
    called shareable.  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.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    If the entity is capable of decoding this range at a different
 | 
						|
    location this resource is considered relocatable.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Resources which start at a specific address and occupy a single
 | 
						|
    continuous range are called block resources.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Alternatively resource addresses can be decoded in a way that they
 | 
						|
    satisfy the conditions:
 | 
						|
	  <programlisting>
 | 
						|
                    address & mask == base
 | 
						|
	  </programlisting>
 | 
						|
    and
 | 
						|
	  <programlisting>
 | 
						|
                       base & mask == base
 | 
						|
	  </programlisting>
 | 
						|
    Resources addressed in such a way are called sparse resources.
 | 
						|
	</para>
 | 
						|
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>Server States</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    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.
 | 
						|
	</para>
 | 
						|
      </sect3>
 | 
						|
    </sect2>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>Control Flow in the Server and Mandatory Driver Functions</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
At the start of each server generation, <function>main()</function>
 | 
						|
(<filename>dix/main.c</filename>) calls the DDX function
 | 
						|
<function>InitOutput()</function>.  This is the first place that the DDX gets
 | 
						|
control.  <function>InitOutput()</function> is expected to fill in the global
 | 
						|
<structname>screenInfo</structname> struct, and one
 | 
						|
<structfield>screenInfo.screen[]</structfield> entry for each screen present.
 | 
						|
Here is what <function>InitOutput()</function> does:
 | 
						|
    </para>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Parse the xorg.conf file</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The entire file is parsed first to remove any section ordering
 | 
						|
    requirements.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Initial processing of parsed information and command line options
 | 
						|
      </title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The initial processing is to determine paths like the
 | 
						|
    <emphasis>ModulePath</emphasis>, etc, and to determine which &k.serverlayout;,
 | 
						|
    &k.screen; and &k.device; sections are active.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Enable port I/O access</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    Port I/O access is controlled from the XFree86 common layer, and is
 | 
						|
    <quote>all or nothing</quote>.  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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The implementation details of this may vary on different platforms.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>General bus probe</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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 <function>xf86GetPciVideoInfo()</function>.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    pciVideoPtr *xf86GetPciVideoInfo(void);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
	returns a pointer to a list of pointers to
 | 
						|
	<structname>pciVideoRec</structname> entries, of which there is one for
 | 
						|
	each detected PCI video card.  The list is terminated with a
 | 
						|
	<constant>NULL</constant> pointer.  If no PCI video cards were
 | 
						|
	detected, the return value is <constant>NULL</constant>.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <para>
 | 
						|
    After the bus probe, the resource broker is initialised.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Load initial set of modules</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The next set of modules loaded are those specified explicitly in the
 | 
						|
    &k.module; section of the config file.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Register Video and Input Drivers</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    When a driver module is loaded, the loader calls its
 | 
						|
    <function>Setup</function> function.  For video drivers, this function
 | 
						|
    calls <function>xf86AddDriver()</function> to register the driver's
 | 
						|
    <structname>DriverRec</structname>, which contains a small set of essential
 | 
						|
    details and driver entry points required during the early phase of
 | 
						|
    <function>InitOutput()</function>.  <function>xf86AddDriver()</function>
 | 
						|
    adds it to the global <varname>xf86DriverList[]</varname> array.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The <structname>DriverRec</structname> contains the driver canonical name,
 | 
						|
    the <function>Identify()</function>,
 | 
						|
    <function>Probe()</function> and <function>AvailableOptions()</function>
 | 
						|
    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
 | 
						|
    <structname>ScrnInfoRec</structname>.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    For a static server, the <varname>xf86DriverList[]</varname> array is
 | 
						|
    initialised at build time, and the loading of modules is not done.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    A similar procedure is used for input drivers.  The input driver's
 | 
						|
    <function>Setup</function> function calls
 | 
						|
    <function>xf86AddInputDriver()</function> to register the driver's
 | 
						|
    <structname>InputDriverRec</structname>, which contains a small set of
 | 
						|
    essential details and driver entry points required during the early
 | 
						|
    phase of <function>InitInput()</function>.
 | 
						|
    <function>xf86AddInputDriver()</function> adds it to the global
 | 
						|
    <varname>xf86InputDriverList[]</varname> array.  For a static server,
 | 
						|
    the <varname>xf86InputDriverList[]</varname> array is initialised at
 | 
						|
    build time.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    Both the <varname>xf86DriverList[]</varname> and
 | 
						|
    <varname>xf86InputDriverList[]</varname> arrays have been initialised
 | 
						|
    by the end of this stage.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    Once all the drivers are registered, their
 | 
						|
    <function>ChipIdentify()</function> functions are called.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void ChipIdentify(int flags);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      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.
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86PrintChipsets(const char *drvname, const char *drvmsg,
 | 
						|
                           SymTabPtr chips);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function provides an easy way for a driver's ChipIdentify
 | 
						|
      function to format the identification message.
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Initialise Access Control</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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 <quote>primary</quote> video device.  These
 | 
						|
    devices remain disabled for the next step.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
 | 
						|
    <sect2 id="probe">
 | 
						|
      <title>Video Driver Probe</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.  The
 | 
						|
    <function>ChipProbe()</function> function of each registered video driver
 | 
						|
    is called.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool ChipProbe(DriverPtr drv, int flags);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      The purpose of this is to identify all instances of hardware
 | 
						|
      supported by the driver.  The flags value is currently either 0,
 | 
						|
      <constant>PROBE_DEFAULT</constant> or <constant>PROBE_DETECT</constant>.
 | 
						|
      <constant>PROBE_DETECT</constant> is used if "-configure" or "-probe"
 | 
						|
      command line arguments are given and indicates to the
 | 
						|
      <function>Probe()</function> function that it should not configure the
 | 
						|
      bus entities and that no xorg.conf information is available.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
      The probe must find the active device sections that match the
 | 
						|
      driver by calling <function>xf86MatchDevice()</function>.  The number
 | 
						|
      of matches found limits the maximum number of instances for this
 | 
						|
      driver.  If no matches are found, the function should return
 | 
						|
      <constant>FALSE</constant> immediately.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	<para>
 | 
						|
      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
 | 
						|
      <function>xf86MatchPciInstances()</function> helper function be used
 | 
						|
      for identifying matching PCI devices
 | 
						|
      (see the <link linkend="rac">RAC</link> section).  These helpers also
 | 
						|
      checks and claims the appropriate entity.  When not using the
 | 
						|
      helper, that should be done with <function>xf86CheckPciSlot()</function>
 | 
						|
      and <function>xf86ClaimPciSlot()</function> for PCI devices (see the
 | 
						|
      <link linkend="rac">RAC</link> section).
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
      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 <function>xf86ConfigPciEntity()</function> helper function
 | 
						|
      for PCI.
 | 
						|
        </para>
 | 
						|
 | 
						|
	<para>
 | 
						|
      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 <constant>FALSE</constant> if the chipset doesn't match
 | 
						|
      one supported by the driver.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
      If there are no active device sections that the driver considers
 | 
						|
      relevant, it must return <constant>FALSE</constant>.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
      Allocate a <structname>ScrnInfoRec</structname> 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
 | 
						|
      <function>xf86ConfigPciEntity()</function> for PCI instances.
 | 
						|
      These functions allocate a <structname>ScrnInfoRec</structname> for active
 | 
						|
      entities. Optionally <function>xf86AllocateScreen()</function>
 | 
						|
      function may also be used to allocate the <structname>ScrnInfoRec</structname>.
 | 
						|
      Any of these functions take care of initialising fields to defined
 | 
						|
      <quote>unused</quote> values.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
      Claim the entities for each instance of the hardware found.  This
 | 
						|
      prevents other drivers from claiming the same hardware.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
      Must leave hardware in the same state it found it in, and must not
 | 
						|
      do any hardware initialisation.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
      All detection can be overridden via the config file, and that
 | 
						|
      parsed information is available to the driver at this stage.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
      Returns <constant>TRUE</constant> if one or more instances are found,
 | 
						|
      and <constant>FALSE</constant> otherwise.
 | 
						|
	</para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    int xf86MatchDevice(const char *drivername,
 | 
						|
                        GDevPtr **driversectlist)
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function takes the name of the driver and returns via
 | 
						|
      <parameter>driversectlist</parameter> 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 <literal>-1</literal>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The caller should use <function>xfree()</function> to free
 | 
						|
      <parameter>*driversectlist</parameter> when it is no longer needed.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags)
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function allocates a new <structname>ScrnInfoRec</structname> in the
 | 
						|
      <varname>xf86Screens[]</varname> array.  This function is normally
 | 
						|
      called by the video driver <function>ChipProbe()</function> functions.
 | 
						|
      The return value is a pointer to the newly allocated
 | 
						|
      <structname>ScrnInfoRec</structname>.  The <structfield>scrnIndex</structfield>,
 | 
						|
      <structfield>origIndex</structfield>, <structfield>module</structfield> and
 | 
						|
      <structfield>drv</structfield> fields are initialised.  The reference count
 | 
						|
      in <parameter>drv</parameter> is incremented.  The storage for any
 | 
						|
      currently allocated <quote>privates</quote> pointers is also allocated and
 | 
						|
      the <structfield>privates</structfield> 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.
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <para>
 | 
						|
    At the completion of this, a list of <structname>ScrnInfoRecs</structname>
 | 
						|
    have been allocated in the <varname>xf86Screens[]</varname> array, and
 | 
						|
    the associated entities and fixed resources have been claimed.  The
 | 
						|
    following <structname>ScrnInfoRec</structname> fields must be initialised at
 | 
						|
    this point:
 | 
						|
 | 
						|
	<literallayout>
 | 
						|
          driverVersion
 | 
						|
          driverName
 | 
						|
          scrnIndex(*)
 | 
						|
          origIndex(*)
 | 
						|
          drv(*)
 | 
						|
          module(*)
 | 
						|
          name
 | 
						|
          Probe
 | 
						|
          PreInit
 | 
						|
          ScreenInit
 | 
						|
          EnterVT
 | 
						|
          LeaveVT
 | 
						|
          numEntities
 | 
						|
          entityList
 | 
						|
          access
 | 
						|
	</literallayout>
 | 
						|
 | 
						|
    <literal>(*)</literal> These are initialised when the <structname>ScrnInfoRec</structname>
 | 
						|
    is allocated, and not explicitly by the driver.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The following <structname>ScrnInfoRec</structname> fields must be initialised
 | 
						|
    if the driver is going to use them:
 | 
						|
 | 
						|
	<literallayout>
 | 
						|
          SwitchMode
 | 
						|
          AdjustFrame
 | 
						|
          FreeScreen
 | 
						|
          ValidMode
 | 
						|
	</literallayout>
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Matching Screens</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    After the Probe phase is finished, there will be some number of
 | 
						|
    <structname>ScrnInfoRec</structname>s.  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, <function>InitOutput()</function> sets
 | 
						|
    <structfield>screenInfo.numScreens</structfield> to <constant>0</constant> and
 | 
						|
    returns.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    At this point the following fields of the <structname>ScrnInfoRec</structname>s
 | 
						|
    must be initialised:
 | 
						|
 | 
						|
	<literallayout>
 | 
						|
          confScreen
 | 
						|
	</literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Allocate non-conflicting resources</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    If any drivers registered an <function>EntityInit()</function> function
 | 
						|
    during the Probe phase, then they are called here.
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Sort the Screens and pre-check Monitor Information</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The list of screens is sorted to match the ordering requested in the
 | 
						|
    config file.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The list of modes for each active monitor is checked against the
 | 
						|
    monitor's parameters.  Invalid modes are pruned.
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>PreInit</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    This is done at the start of the first server generation only.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    For each <structname>ScrnInfoRec</structname>, enable access to the screens entities and call
 | 
						|
    the <function>ChipPreInit()</function> function.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool ChipPreInit(ScrnInfoRec screen, int flags);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      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 <structname>ScrnInfoRec</structname> that
 | 
						|
      can be set once at the beginning of the first server generation.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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
 | 
						|
      <function>xf86GetEntityInfo()</function>) and checked for the correct
 | 
						|
      bus type and that none of the shareable resources registered during
 | 
						|
      the Probe phase was rejected.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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 <function>EntityInit()</function> function that it registered,
 | 
						|
      then it may enable them here providing that it disables them before
 | 
						|
      this function returns.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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 <structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield>
 | 
						|
      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 <quote>privates</quote> index to
 | 
						|
      hook their data into by calling
 | 
						|
      <function>xf86AllocateScrnInfoPrivateIndex()</function>.  The <quote>privates</quote>
 | 
						|
      data is persistent.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      Helper functions for some of these things are provided at the
 | 
						|
      XFree86 common level, and the driver can choose to make use of
 | 
						|
      them.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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  <function>xf86LoadSubModule()</function>
 | 
						|
      or the <function>xf86LoadDrvSubModule()</function> function should be
 | 
						|
      used to load modules depending on whether a
 | 
						|
      <structname>ScrnInfoRec</structname> has been set up. A driver may unload
 | 
						|
      a module within this function if it was only needed temporarily,
 | 
						|
      and the <function>xf86UnloadSubModule()</function> 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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The bulk of the <structname>ScrnInfoRec</structname> fields should be filled
 | 
						|
      out in this function.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      <function>ChipPreInit()</function> returns <constant>FALSE</constant> when
 | 
						|
      the configuration is unusable in some way (unsupported depth, no
 | 
						|
      valid modes, not enough video memory, etc), and <constant>TRUE</constant>
 | 
						|
      if it is usable.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      It is expected that if the <function>ChipPreInit()</function> function
 | 
						|
      returns <constant>TRUE</constant>, 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 <function>ChipPreInit()</function> function.
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The <structname>ScrnInfoRec</structname>s for screens where the <function>ChipPreInit()</function> fails are removed.
 | 
						|
    If none remain, <function>InitOutput()</function> sets <structfield>screenInfo.numScreens</structfield> to <constant>0</constant> and returns.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    At this point, further fields of the <structname>ScrnInfoRec</structname>s 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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The following fields of the <structname>ScrnInfoRec</structname>s should be filled in if the
 | 
						|
    driver is going to use them:
 | 
						|
 | 
						|
	<literallayout>
 | 
						|
          monitor
 | 
						|
          display
 | 
						|
          depth
 | 
						|
          pixmapBPP
 | 
						|
          bitsPerPixel
 | 
						|
          weight                (>8bpp only)
 | 
						|
          mask                  (>8bpp only)
 | 
						|
          offset                (>8bpp only)
 | 
						|
          rgbBits               (8bpp only)
 | 
						|
          gamma
 | 
						|
          defaultVisual
 | 
						|
          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
 | 
						|
          memBase
 | 
						|
          driverPrivate
 | 
						|
          chipID
 | 
						|
          chipRev
 | 
						|
	</literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name);
 | 
						|
      and
 | 
						|
    pointer xf86LoadDrvSubModule(DriverPtr drv, const char *name);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Load a module that a driver depends on.  This function loads the
 | 
						|
      module <parameter>name</parameter> 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 <constant>NULL</constant>.  If a driver
 | 
						|
      needs to explicitly unload a module it has loaded in this way,
 | 
						|
      the return value must be saved and passed to
 | 
						|
      <function>xf86UnloadSubModule()</function> when unloading.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86UnloadSubModule(pointer module);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Unloads the module referenced by <parameter>module</parameter>.
 | 
						|
      <parameter>module</parameter> should be a pointer returned previously
 | 
						|
      by <function>xf86LoadSubModule()</function> or
 | 
						|
      <function>xf86LoadDrvSubModule()</function> .
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Cleaning up Unused Drivers</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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.
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Consistency Checks</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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.
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Check if Resource Control is Needed</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>AddScreen (ScreenInit)</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    At this point, the valid screens are known.
 | 
						|
    <function>AddScreen()</function> is called for each of them, passing
 | 
						|
    <function>ChipScreenInit()</function> as the argument.
 | 
						|
    <function>AddScreen()</function> is a DIX function that allocates a new
 | 
						|
    <structfield>screenInfo.screen[]</structfield> entry (aka
 | 
						|
    <varname>pScreen</varname>), and does some basic initialisation of it.
 | 
						|
    It then calls the <function>ChipScreenInit()</function> function, with
 | 
						|
    <parameter>pScreen</parameter> as one of its arguments.  If
 | 
						|
    <function>ChipScreenInit()</function> returns <constant>FALSE</constant>,
 | 
						|
    <function>AddScreen()</function> returns <constant>-1</constant>.  Otherwise
 | 
						|
    it returns the index of the screen.  <function>AddScreen()</function>
 | 
						|
    should only fail because of programming errors or failure to allocate
 | 
						|
    resources (like memory).  All configuration problems should be
 | 
						|
    detected BEFORE this point.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool ChipScreenInit(ScreenPtr pScreen,
 | 
						|
                        int argc, char **argv);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This is called at the start of each server generation.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      Fill in all of <parameter>pScreen</parameter>, possibly doing some of
 | 
						|
      this by calling ScreenInit functions from other layers like mi,
 | 
						|
      framebuffers (cfb, etc), and extensions.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      Decide which operations need to be placed under resource access
 | 
						|
      control.  The classes of operations are the frame buffer operations
 | 
						|
      (<constant>RAC_FB</constant>), the pointer operations
 | 
						|
      (<constant>RAC_CURSOR</constant>), the viewport change operations
 | 
						|
      (<constant>RAC_VIEWPORT</constant>) and the colormap operations
 | 
						|
      (<constant>RAC_COLORMAP</constant>).  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 <structfield>racMemFlags</structfield> and
 | 
						|
      <structfield>racIoFlags</structfield> fields of the <structname>ScrnInfoRec</structname>
 | 
						|
      respectively).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      Map any video memory or other memory regions.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      Save the video card state.  Enough state must be saved so that
 | 
						|
      the original state can later be restored.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      Initialise the initial video mode.  The <structname>ScrnInfoRec</structname>'s
 | 
						|
      <structfield>vtSema</structfield> field should be set to <constant>TRUE</constant>
 | 
						|
      just prior to changing the video hardware's state.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
 | 
						|
      <para>
 | 
						|
    The <function>ChipScreenInit()</function> function (or functions from other
 | 
						|
    layers that it calls) should allocate entries in the
 | 
						|
    <structname>ScreenRec</structname>'s <structfield>devPrivates</structfield> area by
 | 
						|
    calling <function>AllocateScreenPrivateIndex()</function> if it needs
 | 
						|
    per-generation storage.  Since the <structname>ScreenRec</structname>'s
 | 
						|
    <structfield>devPrivates</structfield> information is cleared for each server
 | 
						|
    generation, this is the correct place to initialise it.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    After <function>AddScreen()</function> has successfully returned, the
 | 
						|
    following <structname>ScrnInfoRec</structname> fields are initialised:
 | 
						|
 | 
						|
	<literallayout>
 | 
						|
          pScreen
 | 
						|
          racMemFlags
 | 
						|
          racIoFlags
 | 
						|
	</literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The <function>ChipScreenInit()</function> function should initialise the
 | 
						|
    <structfield>CloseScreen</structfield> and <structfield>SaveScreen</structfield> fields
 | 
						|
    of <parameter>pScreen</parameter>.  The old value of
 | 
						|
    <structfield>pScreen->CloseScreen</structfield> should be saved as part of
 | 
						|
    the driver's per-screen private data, allowing it to be called from
 | 
						|
    <function>ChipCloseScreen()</function>.  This means that the existing
 | 
						|
    <function>CloseScreen()</function> function is wrapped.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Finalising RAC Initialisation</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    After all the <function>ChipScreenInit()</function> 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:
 | 
						|
 | 
						|
	<orderedlist>
 | 
						|
	  <listitem><para>
 | 
						|
	The shareable 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).
 | 
						|
	    </para></listitem>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
        A resource marked <quote>disabled</quote> during OPERATING state will be
 | 
						|
        ignored entirely.
 | 
						|
	    </para></listitem>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
	A resource marked <quote>unused</quote> will only conflict with an overlapping
 | 
						|
	resource of an other entity if the second is actually in use
 | 
						|
	during OPERATING state.
 | 
						|
	    </para></listitem>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
	If an <quote>unused</quote> 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.
 | 
						|
	    </para></listitem>
 | 
						|
	</orderedlist>
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Finishing InitOutput()</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    At this point <function>InitOutput()</function> is finished, and all the
 | 
						|
    screens have been setup in their initial video mode.
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Mode Switching</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    When a SwitchMode event is received, <function>ChipSwitchMode()</function>
 | 
						|
    is called (when it exists):
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool ChipSwitchMode(int index, DisplayModePtr mode);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Initialises the new mode for the screen identified by
 | 
						|
      <parameter>index;</parameter>.  The viewport may need to be adjusted
 | 
						|
      also.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Changing Viewport</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    When a Change Viewport event is received,
 | 
						|
    <function>ChipAdjustFrame()</function> is called (when it exists):
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void ChipAdjustFrame(int index, int x, int y);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Changes the viewport for the screen identified by
 | 
						|
      <parameter>index;</parameter>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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
 | 
						|
      <structfield>frameX0</structfield>, <structfield>frameY0</structfield>, <structfield>frameX1</structfield>
 | 
						|
      and <structfield>frameY1</structfield> 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.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>VT Switching</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    When a VT switch event is received, <function>xf86VTSwitch()</function>
 | 
						|
    is called.  <function>xf86VTSwitch()</function> does the following:
 | 
						|
 | 
						|
	<variablelist>
 | 
						|
	  <varlistentry><term>On ENTER:</term>
 | 
						|
	    <listitem>
 | 
						|
	      <itemizedlist>
 | 
						|
		<listitem><para>
 | 
						|
		    enable port I/O access
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    save and initialise the bus/resource state
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    enter the SETUP server state
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    calls <function>ChipEnterVT()</function> for each screen
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    enter the OPERATING server state
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    validate GCs
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    Restore fb from saved pixmap for each screen
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    Enable all input devices
 | 
						|
		  </para></listitem>
 | 
						|
	      </itemizedlist>
 | 
						|
	    </listitem>
 | 
						|
	  </varlistentry>
 | 
						|
	  <varlistentry>
 | 
						|
	    <term>On LEAVE:</term>
 | 
						|
	    <listitem>
 | 
						|
	      <itemizedlist>
 | 
						|
		<listitem><para>
 | 
						|
		    Save fb to pixmap for each screen
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    validate GCs
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    enter the SETUP server state
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    calls <function>ChipLeaveVT()</function> for each screen
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    disable all input devices
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    restore bus/resource state
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
		    disables port I/O access
 | 
						|
		  </para></listitem>
 | 
						|
	      </itemizedlist>
 | 
						|
	    </listitem>
 | 
						|
	  </varlistentry>
 | 
						|
	</variablelist>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool ChipEnterVT(ScrnInfoPtr pScrn);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function should initialise the current video mode and
 | 
						|
      initialise the viewport, turn on the HW cursor if appropriate,
 | 
						|
      etc.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      Should it re-save the video state before initialising the video
 | 
						|
      mode?
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void ChipLeaveVT(ScrnInfoPtr pScrn);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function should restore the saved video state.  If
 | 
						|
      appropriate it should also turn off the HW cursor, and invalidate
 | 
						|
      any pixmap/font caches.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <para>
 | 
						|
    Optionally, <function>ChipLeaveVT()</function> may also unmap memory
 | 
						|
    regions.  If so, <function>ChipEnterVT()</function> will need to remap
 | 
						|
    them.  Additionally, if an aperture used to access video memory is
 | 
						|
    unmapped and remapped in this fashion, <function>ChipEnterVT()</function>
 | 
						|
    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
 | 
						|
    <function>ModifyPixmapHeader()</function> function, as follows
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    (*pScreen->ModifyPixmapHeader)(pScrn->ppix,
 | 
						|
                                   -1, -1, -1, -1, -1, NewApertureAddress);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
        where the <structfield>ppix</structfield> field in a ScrnInfoRec
 | 
						|
        points to the pixmap used by the screen's
 | 
						|
        <function>SaveRestoreImage()</function> function to hold the screen's
 | 
						|
        contents while switched out.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <para>
 | 
						|
    Other layers may wrap the <function>ChipEnterVT()</function> and
 | 
						|
    <function>ChipLeaveVT()</function> functions if they need to take some
 | 
						|
    action when these events are received.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>End of server generation</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    At the end of each server generation, the DIX layer calls
 | 
						|
    <function>ChipCloseScreen()</function> for each screen:
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool ChipCloseScreen(int index, ScreenPtr pScreen);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function should restore the saved video state and unmap the
 | 
						|
      memory regions.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      It should also free per-screen data structures allocated by the
 | 
						|
      driver.  Note that the persistent data held in the
 | 
						|
      <structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield> field
 | 
						|
      should not be freed here because it is needed by subsequent server
 | 
						|
      generations.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The <structname>ScrnInfoRec</structname>'s <structfield>vtSema</structfield> field
 | 
						|
      should be set to <constant>FALSE</constant> once the video HW state
 | 
						|
      has been restored.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      Before freeing the per-screen driver data the saved
 | 
						|
      <structfield>CloseScreen</structfield> value should be restored to
 | 
						|
      <structfield>pScreen->CloseScreen</structfield>, and that function should
 | 
						|
      be called after freeing the data.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
    </sect2>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>Optional Driver Functions</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
The functions outlined here can be called from the XFree86 common layer,
 | 
						|
but their presence is optional.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Mode Validation</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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:
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    ModeStatus ChipValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode,
 | 
						|
                             Bool verbose, int flags);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Check the passed mode for hw-specific constraints, and return the
 | 
						|
      appropriate status value.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <para>
 | 
						|
This function may also modify the effective timings and clock of the passed
 | 
						|
mode.  These have been stored in the mode's <structfield>Crtc*</structfield> and
 | 
						|
<structfield>SynthClock</structfield> 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 <function>xf86PrintModes()</function>.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
The function is called once for every mode in the xorg.conf Monitor section
 | 
						|
assigned to the screen, with <parameter>flags</parameter> set to
 | 
						|
<constant>MODECHECK_INITIAL</constant>.  It is subsequently called for every mode
 | 
						|
in the xorg.conf Display subsection assigned to the screen, with
 | 
						|
<parameter>flags</parameter> set to <constant>MODECHECK_FINAL</constant>.  In the second
 | 
						|
case, the mode will have successfully passed all other tests.  In addition,
 | 
						|
the <structname>ScrnInfoRec</structname>'s <structfield>virtualX</structfield>,
 | 
						|
<structfield>virtualY</structfield> and <structfield>displayWidth</structfield> fields will have been
 | 
						|
set as if the mode to be validated were to be the last mode accepted.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
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.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Free screen data</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    When a screen is deleted prior to the completion of the ScreenInit
 | 
						|
    phase the <function>ChipFreeScreen()</function> function is called when defined.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void ChipFreeScreen(ScrnInfoPtr pScrn);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Free any driver-allocated data that may have been allocated up to
 | 
						|
      and including an unsuccessful <function>ChipScreenInit()</function>
 | 
						|
      call.  This would predominantly be data allocated by
 | 
						|
      <function>ChipPreInit()</function> that persists across server
 | 
						|
      generations.  It would include the <structfield>driverPrivate</structfield>,
 | 
						|
      and any <quote>privates</quote> entries that modules may have allocated.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
</sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>Recommended driver functions</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
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.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Save</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    Save the video state.  This could be called from <function>ChipScreenInit()</function> and
 | 
						|
    (possibly) <function>ChipEnterVT()</function>.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void ChipSave(ScrnInfoPtr pScrn);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      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.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Restore</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    Restore the original video state.  This could be called from the
 | 
						|
    <function>ChipLeaveVT()</function> and <function>ChipCloseScreen()</function>
 | 
						|
    functions.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void ChipRestore(ScrnInfoPtr pScrn);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Restores the saved state from the private storage.  Usually only
 | 
						|
      used for restoring text modes.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Initialise Mode</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    Initialise a video mode.  This could be called from the
 | 
						|
    <function>ChipScreenInit()</function>, <function>ChipSwitchMode()</function>
 | 
						|
    and <function>ChipEnterVT()</function> functions.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool ChipModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Programs the hardware for the given video mode.
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>Data and Data Structures</title>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Command line data</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
Some of them are:
 | 
						|
 | 
						|
	<literallayout>
 | 
						|
    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
 | 
						|
	</literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
If we ever do allow for screen-specific command line options, we may
 | 
						|
need to rethink this.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
These can be accessed in a read-only manner by drivers with the following
 | 
						|
functions:
 | 
						|
      </para>
 | 
						|
 | 
						|
     <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    int xf86GetVerbosity();
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Returns the value of <varname>xf86Verbose</varname>.
 | 
						|
	    </para></blockquote>
 | 
						|
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
     <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    int xf86GetDepth();
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Returns the <option>-depth</option> command line setting.  If not
 | 
						|
      set on the command line, <constant>-1</constant> is returned.
 | 
						|
	    </para></blockquote>
 | 
						|
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
     <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    rgb xf86GetWeight();
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Returns the <option>-weight</option> command line setting.  If not
 | 
						|
      set on the command line, <literal remap="tt">{0, 0, 0}</literal> is returned.
 | 
						|
	    </para></blockquote>
 | 
						|
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Gamma xf86GetGamma();
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Returns the <option>-gamma</option> or <option>-rgamma</option>,
 | 
						|
      <option>-ggamma</option>, <option>-bgamma</option> command line settings.
 | 
						|
      If not set on the command line, <literal remap="tt">{0.0, 0.0, 0.0}</literal>
 | 
						|
      is returned.
 | 
						|
	    </para></blockquote>
 | 
						|
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool xf86GetFlipPixels();
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Returns <constant>TRUE</constant> if <option>-flippixels</option> is
 | 
						|
      present on the command line, and <constant>FALSE</constant> otherwise.
 | 
						|
	    </para></blockquote>
 | 
						|
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Data handling</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
The global data is typically not required by drivers, and as such, most
 | 
						|
of it is stored in the private <structname>xf86InfoRec</structname>.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
The screen-specific data collected from the config file is stored in
 | 
						|
screen, device, display, monitor-specific data structures that are separate
 | 
						|
from the <varname>ScrnInfoRecs</varname>, with the appropriate elements/fields
 | 
						|
hooked into the <varname>ScrnInfoRecs</varname> as required.  The screen
 | 
						|
config data is held in <structname>confScreenRec</structname>, device data in
 | 
						|
the <structname>GDevRec</structname>, monitor data in the <structname>MonRec</structname>,
 | 
						|
and display data in the <structname>DispRec</structname>.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
The XFree86 common layer's screen specific data (the actual data in use
 | 
						|
for each screen) is held in the <varname>ScrnInfoRecs</varname>.  As has
 | 
						|
been outlined above, the <varname>ScrnInfoRecs</varname> are allocated at probe
 | 
						|
time, and it is the responsibility of the Drivers' <function>Probe()</function>
 | 
						|
and <function>PreInit()</function> 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:
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
    command line  ->  config file  ->  probed/default data
 | 
						|
	</para></blockquote>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
For most things in this category there are helper functions that the
 | 
						|
drivers can use to ensure that the above precedence is consistently
 | 
						|
used.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
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
 | 
						|
<structname>ScrnInfoRec</structname>, consider the balance between the convenience
 | 
						|
of things that lots of drivers need and the size/obscurity of the
 | 
						|
<structname>ScrnInfoRec</structname>.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
Per-screen driver specific data that cannot be accommodated with the
 | 
						|
static <structname>ScrnInfoRec</structname> fields is held in a driver-defined
 | 
						|
data structure, a pointer to which is assigned to the
 | 
						|
<structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield> field.  This
 | 
						|
is per-screen data that persists across server generations (as does the
 | 
						|
bulk of the static <structname>ScrnInfoRec</structname> data).  It would typically
 | 
						|
also include the video card's saved state.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
Per-screen data for other modules that the driver uses that is reset for each
 | 
						|
server generation is hooked into the <structname>ScrnInfoRec</structname>
 | 
						|
through its <structfield>privates</structfield> field.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
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 <filename>xf86.h</filename> and <filename>xf86str.h</filename>
 | 
						|
files are visible to video drivers.  Things defined in
 | 
						|
<filename>xf86Priv.h</filename> and <filename>xf86Privstr.h</filename> are NOT
 | 
						|
intended to be visible to video drivers, and it is an error for a driver
 | 
						|
to include those files.
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Accessing global data</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
Some other global state information that the drivers may access via
 | 
						|
functions is as follows:
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool xf86ServerIsExiting();
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Returns <constant>TRUE</constant> if the server is at the end of a
 | 
						|
      generation and is in the process of exiting, and
 | 
						|
      <constant>FALSE</constant> otherwise.
 | 
						|
	    </para></blockquote>
 | 
						|
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool xf86ServerIsResetting();
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Returns <constant>TRUE</constant> if the server is at the end of a
 | 
						|
      generation and is in the process of resetting, and
 | 
						|
      <constant>FALSE</constant> otherwise.
 | 
						|
	    </para></blockquote>
 | 
						|
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool xf86ServerIsOnlyProbing();
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Returns <constant>TRUE</constant> if the -probeonly command line flag
 | 
						|
      was specified, and <constant>FALSE</constant> otherwise.
 | 
						|
	    </para></blockquote>
 | 
						|
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Allocating private data</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
A driver and any module it uses may allocate per-screen private storage
 | 
						|
in either the <structname>ScreenRec</structname> (DIX level) or
 | 
						|
<structname>ScrnInfoRec</structname> (XFree86 common layer level).
 | 
						|
<structname>ScreenRec</structname> storage persists only for a single server
 | 
						|
generation, and <structname>ScrnInfoRec</structname> storage persists across
 | 
						|
generations for the lifetime of the server.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
The <structname>ScreenRec</structname> <structfield>devPrivates</structfield> data must be
 | 
						|
reallocated/initialised at the start of each new generation.  This is
 | 
						|
normally done from the <function>ChipScreenInit()</function> function, and
 | 
						|
Init functions for other modules that it calls.  Data allocated in this
 | 
						|
way should be freed by the driver's <function>ChipCloseScreen()</function>
 | 
						|
functions, and Close functions for other modules that it calls.  A new
 | 
						|
<structfield>devPrivates</structfield> entry is allocated by calling the
 | 
						|
<function>AllocateScreenPrivateIndex()</function> function.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    int AllocateScreenPrivateIndex();
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function allocates a new element in the
 | 
						|
      <structfield>devPrivates</structfield> field of all currently existing
 | 
						|
      <literal remap="tt">ScreenRecs</literal>.  The return value is the index of this
 | 
						|
      new element in the <structfield>devPrivates</structfield> array.  The
 | 
						|
      <structfield>devPrivates</structfield> field is of type
 | 
						|
      <structname>DevUnion</structname>:
 | 
						|
 | 
						|
	      <programlisting>
 | 
						|
        typedef union _DevUnion {
 | 
						|
            pointer             ptr;
 | 
						|
            long                val;
 | 
						|
            unsigned long       uval;
 | 
						|
            pointer             (*fptr)(void);
 | 
						|
        } DevUnion;
 | 
						|
	      </programlisting>
 | 
						|
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      This function will return <constant>-1</constant> when there is an
 | 
						|
      error allocating the new index.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <para>
 | 
						|
The <structname>ScrnInfoRec</structname> <structfield>privates</structfield> data persists
 | 
						|
for the life of the server, so only needs to be allocated once.  This
 | 
						|
should be done from the <function>ChipPreInit()</function> function, and Init
 | 
						|
functions for other modules that it calls.  Data allocated in this way
 | 
						|
should be freed by the driver's <function>ChipFreeScreen()</function> functions,
 | 
						|
and Free functions for other modules that it calls.  A new
 | 
						|
<structfield>privates</structfield> entry is allocated by calling the
 | 
						|
<function>xf86AllocateScrnInfoPrivateIndex()</function> function.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    int xf86AllocateScrnInfoPrivateIndex();
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function allocates a new element in the <structfield>privates</structfield>
 | 
						|
      field of all currently existing <varname>ScrnInfoRecs</varname>.
 | 
						|
      The return value is the index of this new element in the
 | 
						|
      <structfield>privates</structfield> array.  The <structfield>privates</structfield>
 | 
						|
      field is of type <structfield>DevUnion</structfield>:
 | 
						|
 | 
						|
	      <programlisting>
 | 
						|
        typedef union _DevUnion {
 | 
						|
            pointer             ptr;
 | 
						|
            long                val;
 | 
						|
            unsigned long       uval;
 | 
						|
            pointer             (*fptr)(void);
 | 
						|
        } DevUnion;
 | 
						|
	      </programlisting>
 | 
						|
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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 <structname>ScreenRec</structname>
 | 
						|
      (<function>AllocateScreenPrivateIndex()</function>) differs in this
 | 
						|
      respect by returning <constant>-1</constant> when the allocation fails.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
    </sect2>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1 id="rac">
 | 
						|
    <title>Keeping Track of Bus Resources</title>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Theory of Operation</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
When the <function>Probe()</function> 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
 | 
						|
<function>Probe()</function> 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 <function>EntityInit()</function>,
 | 
						|
<function>EntityLeave()</function> and <function>EntityEnter()</function> function.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
<function>EntityInit()</function> 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 <function>EntityInit()</function>,
 | 
						|
<function>EntityEnter()</function> and <function>EntityLeave()</function> 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
 | 
						|
<function>EntityInit()</function> or <function>EntityEnter()</function> 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 <constant>ResInit</constant>
 | 
						|
so that they can be removed from the resource list after processing all
 | 
						|
<function>EntityInit()</function> functions.  <function>EntityEnter()</function>
 | 
						|
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 <function>EntityInit()</function> 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.
 | 
						|
<function>EntityLeave()</function> 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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
In <function>PreInit()</function> phase each driver should check if any
 | 
						|
shareable resources it has registered during <function>Probe()</function> has
 | 
						|
been denied and take appropriate action which could simply be to fail.
 | 
						|
If it needs to access resources it has disabled during
 | 
						|
<function>EntitySetup()</function> it can do so provided it has registered
 | 
						|
these and will disable them before returning from
 | 
						|
<function>PreInit()</function>.  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 <quote>disabled</quote> or
 | 
						|
<quote>unused</quote> during OPERATING stage.  Although these steps could also be
 | 
						|
performed in <function>ScreenInit()</function>, this is not desirable.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
Following <function>PreInit()</function> 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
 | 
						|
<function>ScreenInit()</function> 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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
When <function>ScreenInit()</function> 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:
 | 
						|
 | 
						|
	<orderedlist>
 | 
						|
	  <listitem><para>
 | 
						|
   The shareable 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 (<constant>IO</constant> or
 | 
						|
   <constant>MEM</constant>).
 | 
						|
	    </para></listitem>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
   A resource marked <quote>disabled</quote> during OPERATING state will be ignored
 | 
						|
   entirely.
 | 
						|
	    </para></listitem>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
   A resource marked <quote>unused</quote> will only conflicts with an overlapping
 | 
						|
   resource of an other entity if the second is actually in use during
 | 
						|
   OPERATING state.
 | 
						|
	    </para></listitem>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
   If an <quote>unused</quote> 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.
 | 
						|
	    </para></listitem>
 | 
						|
	</orderedlist>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
The driver has the choice among different ways to control access to
 | 
						|
certain resources:
 | 
						|
 | 
						|
	<orderedlist>
 | 
						|
	  <listitem><para>
 | 
						|
   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.
 | 
						|
	    </para></listitem>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
   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 <function>PreInit()</function>
 | 
						|
   stage.  Since the replacement functions are registered in
 | 
						|
   <function>PreInit()</function> 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.
 | 
						|
	    </para></listitem>
 | 
						|
 | 
						|
	  <listitem><para>
 | 
						|
   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 <quote>unused</quote> during OPERATING state.
 | 
						|
	    </para></listitem>
 | 
						|
	</orderedlist>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
A resource which is decoded during OPERATING state however never accessed
 | 
						|
by the driver should be marked unused.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
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 <function>EnableAccess()</function> function is called before control is
 | 
						|
passed on.  <function>EnableAccess()</function> 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,
 | 
						|
<function>EnableAccess()</function> determines which resource types
 | 
						|
(<literal remap="tt">MEM</literal>, <literal remap="tt">IO</literal>) 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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
Whenever a mode switch or a VT-switch is performed the common level will
 | 
						|
return to SETUP state.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Resource Types</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
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
 | 
						|
 | 
						|
	<itemizedlist>
 | 
						|
	  <listitem><para>
 | 
						|
       its physical properties i.e., if it addresses
 | 
						|
       memory (<constant>ResMem</constant>)  or
 | 
						|
       I/O space (<constant>ResIo</constant>),
 | 
						|
	    </para></listitem>
 | 
						|
	  <listitem><para>
 | 
						|
       if it addresses a
 | 
						|
       block (<constant>ResBlock</constant>) or
 | 
						|
       sparse (<constant>ResSparse</constant>)
 | 
						|
       range,
 | 
						|
	    </para></listitem>
 | 
						|
	  <listitem><para>
 | 
						|
       its access properties.
 | 
						|
	    </para></listitem>
 | 
						|
	</itemizedlist>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
There are two known access properties:
 | 
						|
 | 
						|
	<itemizedlist>
 | 
						|
	  <listitem><para>
 | 
						|
  <constant>ResExclusive</constant>
 | 
						|
    for resources which may not be shared with any other device and
 | 
						|
	    </para></listitem>
 | 
						|
	  <listitem><para>
 | 
						|
  <constant>ResShared</constant>
 | 
						|
    for resources which can be disabled and therefore can be shared.
 | 
						|
	    </para></listitem>
 | 
						|
	</itemizedlist>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
If it is necessary to test a resource against any type a generic access
 | 
						|
type <constant>ResAny</constant> 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 (<constant>ResUnused</constant>) or during
 | 
						|
OPERATING state (<constant>ResUnusedOpr</constant>).  A resource only visible
 | 
						|
during the init functions (ie.  <function>EntityInit()</function>,
 | 
						|
<function>EntityEnter()</function> and <function>EntityLeave()</function> should
 | 
						|
be registered with the flag <constant>ResInit</constant>.  A resource that
 | 
						|
might conflict with background resource ranges may be flagged with
 | 
						|
<constant>ResBios</constant>.  This might be useful when registering resources
 | 
						|
ranges that were assigned by the system Bios.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
Several predefined resource lists are available for VGA and 8514/A
 | 
						|
resources in <filename>common/xf86Resources.h</filename>.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2 id="avail">
 | 
						|
      <title>Available Functions</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
The functions provided for resource management are listed in their order
 | 
						|
of use in the driver.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>Probe Phase</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
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.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
Two helper functions are provided for matching device sections in the
 | 
						|
xorg.conf file to the devices:
 | 
						|
	</para>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    int xf86MatchPciInstances(const char *driverName, int vendorID,
 | 
						|
                              SymTabPtr chipsets, PciChipsets *PCIchipsets,
 | 
						|
                              GDevPtr *devList, int numDevs, DriverPtr drvp,
 | 
						|
                              int **foundEntities);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      This function finds matches between PCI cards that a driver supports
 | 
						|
      and config file device sections.  It is intended for use in the
 | 
						|
      <function>ChipProbe()</function> function of drivers for PCI cards.
 | 
						|
      Only probed PCI devices with a vendor ID matching
 | 
						|
      <parameter>vendorID</parameter> are considered.  <parameter>devList</parameter>
 | 
						|
      and <parameter>numDevs</parameter> are typically those found from
 | 
						|
      calling <function>xf86MatchDevice()</function>, and represent the active
 | 
						|
      config file device sections relevant to the driver.
 | 
						|
      <parameter>PCIchipsets</parameter> is a table that provides a mapping
 | 
						|
      between the PCI device IDs, the driver's internal chipset tokens
 | 
						|
      and a list of fixed resources.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	      <para>
 | 
						|
      When a device section doesn't have a <emphasis>BusID</emphasis> entry it
 | 
						|
      can only match the primary video device.  Secondary devices are
 | 
						|
      only matched with device sections that have a matching
 | 
						|
      <emphasis>BusID</emphasis> entry.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	      <para>
 | 
						|
      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
 | 
						|
      <parameter>chipsets</parameter> and <parameter>PCIchipsets</parameter> lists.
 | 
						|
      The <parameter>PCIchipsets</parameter> list includes a list of the PCI
 | 
						|
      device IDs supported by the driver.  The list should be terminated
 | 
						|
      with an entry with PCI ID <constant>-1</constant>".  The
 | 
						|
      <parameter>chipsets</parameter> list is a table mapping the driver's
 | 
						|
      internal chipset tokens to names, and should be terminated with
 | 
						|
      a <constant>NULL</constant> entry.  Only those entries with a
 | 
						|
      corresponding entry in the <parameter>PCIchipsets</parameter> list are
 | 
						|
      considered.  The order of precedence is: config file chipset,
 | 
						|
      config file ChipID, probed PCI device ID.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	      <para>
 | 
						|
      In cases where a driver handles PCI chipsets with more than one
 | 
						|
      vendor ID, it may set <parameter>vendorID</parameter> to
 | 
						|
      <constant>0</constant>, and OR each devID in the list with (the
 | 
						|
      vendor ID << 16).
 | 
						|
	      </para>
 | 
						|
 | 
						|
	      <para>
 | 
						|
      Entity index numbers for confirmed matches are returned as an
 | 
						|
      array via <parameter>foundEntities</parameter>.  The PCI information,
 | 
						|
      chipset token and device section for each match are found in the
 | 
						|
      <structname>EntityInfoRec</structname> referenced by the indices.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	      <para>
 | 
						|
      The function return value is the number of confirmed matches.  A
 | 
						|
      return value of <constant>-1</constant> indicates an internal error.
 | 
						|
      The returned <parameter>foundEntities</parameter> array should be freed
 | 
						|
      by the driver with <function>xfree()</function> when it is no longer
 | 
						|
      needed in cases where the return value is greater than zero.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<para>
 | 
						|
These two helper functions make use of several core functions that are
 | 
						|
available at the driver level:
 | 
						|
	</para>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    Bool xf86ParsePciBusString(const char *busID, int *bus,
 | 
						|
                               int *device, int *func);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      Takes a <parameter>BusID</parameter> string, and if it is in the correct
 | 
						|
      format, returns the PCI <parameter>bus</parameter>, <parameter>device</parameter>,
 | 
						|
      <parameter>func</parameter> values that it indicates.  The format of the
 | 
						|
      string is expected to be "PCI:bus:device:func" where each of <quote>bus</quote>,
 | 
						|
      <quote>device</quote> and <quote>func</quote> 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 <constant>FALSE</constant>.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    Bool xf86ComparePciBusString(const char *busID, int bus,
 | 
						|
                                 int device, int func);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      Compares a <parameter>BusID</parameter> string with PCI <parameter>bus</parameter>,
 | 
						|
      <parameter>device</parameter>, <parameter>func</parameter> values.  If they
 | 
						|
      match <constant>TRUE</constant> is returned, and <constant>FALSE</constant>
 | 
						|
      if they don't.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    Bool xf86CheckPciSlot(int bus, int device, int func);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      Checks if the PCI slot <literal remap="tt">bus:device:func</literal> has been
 | 
						|
      claimed.  If so, it returns <constant>FALSE</constant>, and otherwise
 | 
						|
      <constant>TRUE</constant>.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    int xf86ClaimPciSlot(int bus, int device, int func, DriverPtr drvp,
 | 
						|
                         int chipset, GDevPtr dev, Bool active);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      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
 | 
						|
      <constant>-1</constant> if the claim fails.  This function should always
 | 
						|
      succeed if <function>xf86CheckPciSlot()</function> returned
 | 
						|
      <constant>TRUE</constant> for the same PCI slot.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    Bool xf86IsPrimaryPci(void);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      This function returns <constant>TRUE</constant> if the primary card is
 | 
						|
      a PCI device, and <constant>FALSE</constant> otherwise.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<para>
 | 
						|
Two helper functions are provided to aid configuring entities:
 | 
						|
	</para>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn,
 | 
						|
                                    int scrnFlag, int entityIndex,
 | 
						|
                                    PciChipsets *p_chip,
 | 
						|
                                    void *res, EntityProc init,
 | 
						|
                                    EntityProc enter, EntityProc leave,
 | 
						|
                                    pointer private);
 | 
						|
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      This functions is used to register the entity. The <parameter>res</parameter>, <parameter>init</parameter>, <parameter>enter</parameter>, and <parameter>leave</parameter> arguments are unused, and should be <constant>NULL</constant>.
 | 
						|
      For active entities a <structname>ScrnInfoRec</structname> is allocated
 | 
						|
      if the <parameter>pScrn</parameter> argument is <constant>NULL</constant>.
 | 
						|
The
 | 
						|
      return value is <constant>TRUE</constant> when successful.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<para>
 | 
						|
These two helper functions make use of several core functions that are
 | 
						|
available at the driver level:
 | 
						|
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
      This function associates the entity referenced by
 | 
						|
      <parameter>entityIndex</parameter> with the screen.
 | 
						|
		</para>
 | 
						|
 | 
						|
	      </blockquote></para></blockquote>
 | 
						|
	</para>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>PreInit Phase</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
During this phase the remaining resources should be registered.
 | 
						|
<function>PreInit()</function> should call <function>xf86GetEntityInfo()</function>
 | 
						|
to obtain a pointer to an <structname>EntityInfoRec</structname> for each entity
 | 
						|
it is able to drive and check if any resource are listed in its
 | 
						|
<structfield>resources</structfield> field.  If resources registered in the Probe
 | 
						|
phase have been rejected in the post-Probe phase
 | 
						|
(<structfield>resources</structfield> is non-<constant>NULL</constant>), then the driver should
 | 
						|
decide if it can continue without using these or if it should fail.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    EntityInfoPtr xf86GetEntityInfo(int entityIndex);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      This function returns a pointer to the <structname>EntityInfoRec</structname>
 | 
						|
      referenced by <parameter>entityIndex</parameter>.  The returned
 | 
						|
      <structname>EntityInfoRec</structname> should be freed with
 | 
						|
      <function>xfree()</function> when no longer needed.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<para>
 | 
						|
Several functions are provided to simplify resource registration:
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    Bool xf86IsEntityPrimary(int entityIndex);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
      This function returns <constant>TRUE</constant> if the entity referenced
 | 
						|
      by <parameter>entityIndex</parameter> is the primary display device (i.e.,
 | 
						|
      the one initialised at boot time and used in text mode).
 | 
						|
		</para>
 | 
						|
 | 
						|
	      </blockquote></para></blockquote>
 | 
						|
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    Bool xf86IsScreenPrimary(ScrnInfoPtr pScrn);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
      This function returns <constant>TRUE</constant> if the primary entity
 | 
						|
      is registered with the screen referenced by
 | 
						|
      <parameter>pScrn</parameter>.
 | 
						|
		</para>
 | 
						|
 | 
						|
	      </blockquote></para></blockquote>
 | 
						|
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    pciVideoPtr xf86GetPciInfoForEntity(int entityIndex);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
      This function returns a pointer to the <structname>pciVideoRec</structname>
 | 
						|
      for the specified entity.  If the entity is not a PCI device,
 | 
						|
      <constant>NULL</constant> is returned.
 | 
						|
		</para>
 | 
						|
 | 
						|
	      </blockquote></para></blockquote>
 | 
						|
	</para>
 | 
						|
 | 
						|
<para>
 | 
						|
Two functions are provided to obtain a resource range of a given type:
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    resRange xf86GetBlock(long type, memType size,
 | 
						|
                          memType window_start, memType window_end,
 | 
						|
                          memType align_mask, resPtr avoid);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
      This function tries to find a block range of size
 | 
						|
      <parameter>size</parameter> and type <parameter>type</parameter> in a window
 | 
						|
      bound by <parameter>window_start</parameter> and <parameter>window_end</parameter>
 | 
						|
      with the alignment specified in <parameter>align_mask</parameter>.
 | 
						|
      Optionally a list of resource ranges which should be avoided within
 | 
						|
      the window can be supplied.  On failure a zero-length range of
 | 
						|
      type <constant>ResEnd</constant> will be returned.
 | 
						|
		</para>
 | 
						|
	      </blockquote></para></blockquote>
 | 
						|
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    resRange xf86GetSparse(long type, memType fixed_bits,
 | 
						|
                           memType decode_mask, memType address_mask,
 | 
						|
                           resPtr avoid);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
      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 <parameter>address_mask</parameter> which marks all
 | 
						|
      bits of the mask part of the address, the <parameter>decode_mask</parameter>
 | 
						|
      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
 | 
						|
      <constant>ResEnd</constant>.  Optionally it might be passed a list of
 | 
						|
      resource ranges to avoid.
 | 
						|
		</para>
 | 
						|
 | 
						|
	      </blockquote></para></blockquote>
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    Bool xf86CheckPciMemBase(pciVideoPtr pPci, memType base);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
      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.
 | 
						|
		</para>
 | 
						|
 | 
						|
	      </blockquote></para></blockquote>
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
The following two functions are provided for special cases:
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
      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.
 | 
						|
		</para>
 | 
						|
 | 
						|
	      </blockquote></para></blockquote>
 | 
						|
	</para>
 | 
						|
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>ScreenInit Phase</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
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 <structfield>racIoFlags</structfield> and <structfield>racMemFlags</structfield> fields of the
 | 
						|
<structname>ScrnInfoRec</structname> 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 <filename>rac/xf86RAC.h</filename>.  They are:
 | 
						|
 | 
						|
	  <variablelist>
 | 
						|
	    <varlistentry><term><constant>RAC_FB</constant></term>
 | 
						|
	      <listitem><para>
 | 
						|
	for framebuffer operations (including hw acceleration)
 | 
						|
		</para></listitem></varlistentry>
 | 
						|
	    <varlistentry><term><constant>RAC_CURSOR</constant></term>
 | 
						|
	      <listitem><para>
 | 
						|
	for Cursor operations
 | 
						|
        (??? I'm not sure if we need this for SW cursor it depends
 | 
						|
         on which level the sw cursor is drawn)
 | 
						|
		</para></listitem></varlistentry>
 | 
						|
	    <varlistentry><term><constant>RAC_COLORMAP</constant></term>
 | 
						|
	      <listitem><para>
 | 
						|
	for colormap operations
 | 
						|
		</para></listitem></varlistentry>
 | 
						|
	    <varlistentry><term><constant>RAC_VIEWPORT</constant></term>
 | 
						|
	      <listitem><para>
 | 
						|
	for the call to <function>ChipAdjustFrame()</function>
 | 
						|
		</para></listitem></varlistentry>
 | 
						|
	    </variablelist>
 | 
						|
 | 
						|
 | 
						|
The flags are ORed together.
 | 
						|
	</para>
 | 
						|
      </sect3>
 | 
						|
    </sect2>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1 id="options">
 | 
						|
    <title>Config file <quote>Option</quote> entries</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
Option entries are permitted in most sections and subsections of the
 | 
						|
config file.  There are two forms of option entries:
 | 
						|
 | 
						|
      <variablelist>
 | 
						|
	<varlistentry><term>Option "option-name"</term>
 | 
						|
	  <listitem><para>
 | 
						|
	A boolean option.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
	<varlistentry><term>Option "option-name" "option-value"</term>
 | 
						|
	  <listitem><para>
 | 
						|
	An option with an arbitrary value.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
      </variablelist>
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
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.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
First, the low level option handling functions.  In most cases drivers
 | 
						|
would not need to use these directly.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    XF86OptionPtr xf86FindOption(XF86OptionPtr options, const char *name);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      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
 | 
						|
      <constant>NULL</constant> if no match is found.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    const char *xf86FindOptionValue(XF86OptionPtr options, const char *name);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      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
 | 
						|
      (<constant>""</constant>) is returned.  Returns <constant>NULL</constant>
 | 
						|
      if no match is found.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    void xf86MarkOptionUsed(XF86OptionPtr option);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      Takes a handle for an option, and marks that option as used.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    void xf86MarkOptionUsedByName(XF86OptionPtr options, const char *name);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      Takes a list of options and an option name and marks the first
 | 
						|
      option entry in the list matching the name as used.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <para>
 | 
						|
Next, the higher level functions that most drivers would use.
 | 
						|
    </para>
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    void xf86CollectOptions(ScrnInfoPtr pScrn, XF86OptionPtr extraOpts);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      Collect the options from each of the config file sections used by
 | 
						|
      the screen (<parameter>pScrn</parameter>) and return the merged list as
 | 
						|
      <structfield>pScrn->options</structfield>.  This function requires that
 | 
						|
      <structfield>pScrn->confScreen</structfield>, <structfield>pScrn->display</structfield>,
 | 
						|
      <structfield>pScrn->monitor</structfield>,
 | 
						|
      <structfield>pScrn->numEntities</structfield>, and
 | 
						|
      <structfield>pScrn->entityList</structfield> are initialised.
 | 
						|
      <parameter>extraOpts</parameter> may optionally be set to an additional
 | 
						|
      list of options to be combined with the others.  The order of
 | 
						|
      precedence for options is <parameter>extraOpts</parameter>, display,
 | 
						|
      confScreen, monitor, device.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    void xf86ProcessOptions(int scrnIndex, XF86OptionPtr options,
 | 
						|
                            OptionInfoPtr optinfo);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      Processes a list of options according to the information in the
 | 
						|
      array of <structname>OptionInfoRecs</structname> (<parameter>optinfo</parameter>).
 | 
						|
      The resulting information is stored in the <structfield>value</structfield>
 | 
						|
      fields of the appropriate <parameter>optinfo</parameter> entries.  The
 | 
						|
      <structfield>found</structfield> fields are set to <constant>TRUE</constant>
 | 
						|
      when an option with a value of the correct type if found, and
 | 
						|
      <constant>FALSE</constant> otherwise.  The <structfield>type</structfield> 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.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
      NOTE: If this function is called before a driver's screen number
 | 
						|
      is known (e.g., from the <function>ChipProbe()</function> function) a
 | 
						|
      <parameter>scrnIndex</parameter> value of <constant>-1</constant> should be
 | 
						|
      used.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
      NOTE 2: Given that this function stores into the
 | 
						|
      <literal remap="tt">OptionInfoRecs</literal> pointed to by <parameter>optinfo</parameter>,
 | 
						|
      the caller should ensure the <literal remap="tt">OptionInfoRecs</literal> are
 | 
						|
      (re-)initialised before the call, especially if the caller expects
 | 
						|
      to use the predefined option values as defaults.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
      The <structname>OptionInfoRec</structname> is defined as follows:
 | 
						|
 | 
						|
	    <programlisting>
 | 
						|
      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;
 | 
						|
	    </programlisting>
 | 
						|
	  </para>
 | 
						|
	  <para>
 | 
						|
      <constant>OPTV_FREQ</constant> 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 <structfield>freq.units</structfield>, and the scaled frequency
 | 
						|
      is stored in <structfield>freq.freq</structfield>.  When no unit is specified,
 | 
						|
      <structfield>freq.units</structfield> is set to <constant>0</constant>, and
 | 
						|
      <structfield>freq.freq</structfield> is unscaled.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
      <constant>OPTV_PERCENT</constant> 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.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
      Typical usage is to setup an array of
 | 
						|
      <structname>OptionInfoRec</structname>s with all fields initialised.
 | 
						|
      The <structfield>value</structfield> and <structfield>found</structfield> fields get
 | 
						|
      set by <function>xf86ProcessOptions()</function>.  For cases where the
 | 
						|
      value parsing is more complex, the driver should specify
 | 
						|
      <constant>OPTV_STRING</constant>, and parse the string itself.  An
 | 
						|
      example of using this option handling is included in the
 | 
						|
      <link linkend="sample">Sample Driver</link> section.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    void xf86ShowUnusedOptions(int scrnIndex, XF86OptionPtr options);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      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 <function>ChipScreenInit()</function> function, but only
 | 
						|
      when <code>serverGeneration == 1</code>
 | 
						|
	  </para>
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    OptionInfoPtr xf86TokenToOptinfo(const OptionInfoRec *table,
 | 
						|
                                     int token);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      Returns a pointer to the <structname>OptionInfoRec</structname> in
 | 
						|
      <parameter>table</parameter> with a token field matching
 | 
						|
      <parameter>token</parameter>.  Returns <constant>NULL</constant> if no match
 | 
						|
      is found.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    Bool xf86IsOptionSet(const OptionInfoRec *table, int token);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      Returns the <literal remap="tt">found</literal> field of the
 | 
						|
      <structname>OptionInfoRec</structname> in <parameter>table</parameter> with a
 | 
						|
      <structfield>token</structfield> field matching <parameter>token</parameter>.  This
 | 
						|
      can be used for options of all types.  Note that for options of
 | 
						|
      type <constant>OPTV_BOOLEAN</constant>, it isn't sufficient to check
 | 
						|
      this to determine the value of the option.  Returns
 | 
						|
      <constant>FALSE</constant> if no match is found.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    char *xf86GetOptValString(const OptionInfoRec *table, int token);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      Returns the <structfield>value.str</structfield> field of the
 | 
						|
      <structname>OptionInfoRec</structname> in <parameter>table</parameter> with a
 | 
						|
      token field matching <parameter>token</parameter>.  Returns
 | 
						|
      <constant>NULL</constant> if no match is found.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    Bool xf86GetOptValInteger(const OptionInfoRec *table, int token,
 | 
						|
 | 
						|
                                int *value);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
      Returns via <parameter>*value</parameter> the <structfield>value.num</structfield>
 | 
						|
      field of the <structname>OptionInfoRec</structname> in <parameter>table</parameter>
 | 
						|
      with a <structfield>token</structfield> field matching <parameter>token</parameter>.
 | 
						|
      <parameter>*value</parameter> 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
 | 
						|
      <function>xf86IsOptionSet()</function>.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    Bool xf86GetOptValULong(const OptionInfoRec *table, int token,
 | 
						|
                            unsigned long *value);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      Like <function>xf86GetOptValInteger()</function>, except the value is
 | 
						|
      treated as an <type>unsigned long</type>.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    Bool xf86GetOptValReal(const OptionInfoRec *table, int token,
 | 
						|
                           double *value);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      Like <function>xf86GetOptValInteger()</function>, except that
 | 
						|
      <structfield>value.realnum</structfield> is used.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    Bool xf86GetOptValFreq(const OptionInfoRec *table, int token,
 | 
						|
                           OptFreqUnits expectedUnits, double *value);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      Like <function>xf86GetOptValInteger()</function>, except that the
 | 
						|
      <structfield>value.freq</structfield> data is returned.  The frequency value
 | 
						|
      is scaled to the units indicated by <parameter>expectedUnits</parameter>.
 | 
						|
      The scaling is exact when the units were specified explicitly in
 | 
						|
      the option's value.  Otherwise, the <parameter>expectedUnits</parameter>
 | 
						|
      field is used as a hint when doing the scaling.  In this case,
 | 
						|
      values larger than <constant>1000</constant> are assumed to have be
 | 
						|
      specified in the next smallest units.  For example, if the Option
 | 
						|
      value is "10000" and expectedUnits is <constant>OPTUNITS_MHZ</constant>,
 | 
						|
      the value returned is <constant>10</constant>.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
      <programlisting>
 | 
						|
    Bool xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value);
 | 
						|
      </programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      This function is used to check boolean options
 | 
						|
      (<constant>OPTV_BOOLEAN</constant>).  If the function return value is
 | 
						|
      <constant>FALSE</constant>, it means the option wasn't set.  Otherwise
 | 
						|
      <parameter>*value</parameter> is set to the boolean value indicated by
 | 
						|
      the option's value.  No option <parameter>value</parameter> is interpreted
 | 
						|
      as <constant>TRUE</constant>.  Option values meaning <constant>TRUE</constant>
 | 
						|
      are "1", "yes", "on", "true", and option values meaning
 | 
						|
      <constant>FALSE</constant> 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.
 | 
						|
      <parameter>*value</parameter> is not changed when the option isn't present.
 | 
						|
      It should normally be set to a default value before calling this
 | 
						|
      function.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    Bool xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      This function is used to check boolean options
 | 
						|
      (<constant>OPTV_BOOLEAN</constant>).  If the option is set, its value
 | 
						|
      is returned.  If the options is not set, the default value specified
 | 
						|
      by <parameter>def</parameter> is returned.  The option interpretation is
 | 
						|
      the same as for <function>xf86GetOptValBool()</function>.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    int xf86NameCmp(const char *s1, const char *s2);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      This function should be used when comparing strings from the config
 | 
						|
      file with expected values.  It works like <function>strcmp()</function>,
 | 
						|
      but is not case sensitive and space, tab, and <quote><literal>_</literal></quote> 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.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>Modules, Drivers, Include Files and Interface Issues</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
NOTE: this section is incomplete.
 | 
						|
    </para>
 | 
						|
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Include files</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
The following include files are typically required by video drivers:
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
  All drivers should include these:
 | 
						|
	    <literallayout><filename>
 | 
						|
    "xf86.h"
 | 
						|
    "xf86_OSproc.h"
 | 
						|
    "xf86_ansic.h"
 | 
						|
    "xf86Resources.h"
 | 
						|
	    </filename></literallayout>
 | 
						|
  Wherever inb/outb (and related things) are used the following should be
 | 
						|
  included:
 | 
						|
	    <literallayout><filename>
 | 
						|
    "compiler.h"
 | 
						|
	      </filename></literallayout>
 | 
						|
  Note: in drivers, this must be included after <filename>"xf86_ansic.h"</filename>.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
  Drivers that need to access the PCI config space need this:
 | 
						|
	    <literallayout><filename>
 | 
						|
    "xf86Pci.h"
 | 
						|
	      </filename></literallayout>
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
  Drivers that initialise a SW cursor need this:
 | 
						|
	    <literallayout><filename>
 | 
						|
    "mipointer.h"
 | 
						|
	      </filename></literallayout>
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
  All drivers using the mi colourmap code need this:
 | 
						|
	    <literallayout><filename>
 | 
						|
    "micmap.h"
 | 
						|
	      </filename></literallayout>
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
  If a driver uses the vgahw module, it needs this:
 | 
						|
	    <literallayout><filename>
 | 
						|
    "vgaHW.h"
 | 
						|
	      </filename></literallayout>
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
  Drivers supporting VGA or Hercules monochrome screens need:
 | 
						|
	    <literallayout><filename>
 | 
						|
    "xf1bpp.h"
 | 
						|
	      </filename></literallayout>
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
  Drivers supporting VGA or EGC 16-colour screens need:
 | 
						|
	    <literallayout><filename>
 | 
						|
    "xf4bpp.h"
 | 
						|
	      </filename></literallayout>
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
  Drivers using cfb need:
 | 
						|
	    <programlisting>
 | 
						|
    #define PSZ 8
 | 
						|
    #include "cfb.h"
 | 
						|
    #undef PSZ
 | 
						|
	    </programlisting>
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
  Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
 | 
						|
	    <literallayout><filename>
 | 
						|
    "cfb16.h"
 | 
						|
    "cfb24.h"
 | 
						|
    "cfb32.h"
 | 
						|
	      </filename></literallayout>
 | 
						|
	  </para>
 | 
						|
 | 
						|
	  <para>
 | 
						|
  If a driver uses the fb manager, it needs this:
 | 
						|
	    <literallayout><filename>
 | 
						|
    "xf86fbman.h"
 | 
						|
	      </filename></literallayout>
 | 
						|
	  </para>
 | 
						|
	</blockquote>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
Non-driver modules should include <filename>"xf86_ansic.h"</filename> to get the correct
 | 
						|
wrapping of ANSI C/libc functions.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
All modules must NOT include any system include files, or the following:
 | 
						|
 | 
						|
	<literallayout><filename>
 | 
						|
    "xf86Priv.h"
 | 
						|
    "xf86Privstr.h"
 | 
						|
    "xf86_OSlib.h"
 | 
						|
    "Xos.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
In addition, "xf86_libc.h" must not be included explicitly.  It is
 | 
						|
included implicitly by "xf86_ansic.h".
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>Offscreen Memory Manager</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
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
 | 
						|
<filename>xf86fbman.h</filename>):
 | 
						|
 | 
						|
      <programlisting>
 | 
						|
    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
 | 
						|
    )
 | 
						|
      </programlisting>
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The function:
 | 
						|
      <programlisting>
 | 
						|
    Bool xf86FBManagerRunning(ScreenPtr pScreen);
 | 
						|
      </programlisting>
 | 
						|
 | 
						|
can be used by an extension to check if the driver has initialized
 | 
						|
the memory manager.  The manager is not available if this returns
 | 
						|
<constant>FALSE</constant> and the functions above will all fail.
 | 
						|
    </para>
 | 
						|
 | 
						|
 | 
						|
    <para>
 | 
						|
<function>xf86AllocateOffscreenArea()</function> can be used to request a
 | 
						|
rectangle of dimensions <parameter>width</parameter> × <parameter>height</parameter>
 | 
						|
(in pixels) from unused offscreen memory.  <parameter>granularity</parameter>
 | 
						|
specifies that the leftmost edge of the rectangle must lie on some
 | 
						|
multiple of <parameter>granularity</parameter> pixels.  A granularity of zero
 | 
						|
means the same thing as a granularity of one - no alignment preference.
 | 
						|
A <parameter>MoveAreaCallback</parameter> can be provided to notify the requester
 | 
						|
when the offscreen area is moved.  If no <parameter>MoveAreaCallback</parameter>
 | 
						|
is supplied then the area is considered to be immovable.  The
 | 
						|
<parameter>privData</parameter> field will be stored in the manager's internal
 | 
						|
structure for that allocated area and will be returned to the requester
 | 
						|
in the <parameter>FBArea</parameter> passed via the
 | 
						|
<parameter>MoveAreaCallback</parameter>.  An optional
 | 
						|
<parameter>RemoveAreaCallback</parameter> 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 <parameter>RemoveAreaCallback</parameter>) 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.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
<function>xf86AllocateOffscreenArea()</function> returns <constant>NULL</constant>
 | 
						|
if it was unable to allocate the requested area.  When no longer needed,
 | 
						|
areas should be freed with <function>xf86FreeOffscreenArea()</function>.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
<function>xf86ResizeOffscreenArea()</function> resizes an existing
 | 
						|
<literal remap="tt">FBArea</literal>.  <function>xf86ResizeOffscreenArea()</function>
 | 
						|
returns <constant>TRUE</constant> if the resize was successful.  If
 | 
						|
<function>xf86ResizeOffscreenArea()</function> returns <constant>FALSE</constant>,
 | 
						|
the original <literal remap="tt">FBArea</literal> is left unmodified.  Resizing an
 | 
						|
area maintains the area's original <literal remap="tt">granularity</literal>,
 | 
						|
<literal remap="tt">devPrivate</literal>, and <literal remap="tt">MoveAreaCallback</literal>.
 | 
						|
<function>xf86ResizeOffscreenArea()</function> has considerably less overhead
 | 
						|
than freeing the old area then reallocating the new size, so it should
 | 
						|
be used whenever possible.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The function:
 | 
						|
      <programlisting>
 | 
						|
    Bool xf86QueryLargestOffscreenArea(
 | 
						|
      ScreenPtr pScreen,
 | 
						|
      int *width, int *height,
 | 
						|
      int granularity,
 | 
						|
      int preferences,
 | 
						|
      int priority
 | 
						|
    );
 | 
						|
	</programlisting>
 | 
						|
 | 
						|
is provided to query the width and height of the largest single
 | 
						|
<structname>FBArea</structname> allocatable given a particular priority.
 | 
						|
<parameter>preferences</parameter> can be one of the following to indicate
 | 
						|
whether width, height or area should be considered when determining
 | 
						|
which is the largest single <structname>FBArea</structname> available.
 | 
						|
 | 
						|
      <programlisting>
 | 
						|
  FAVOR_AREA_THEN_WIDTH
 | 
						|
  FAVOR_AREA_THEN_HEIGHT
 | 
						|
  FAVOR_WIDTH_THEN_AREA
 | 
						|
  FAVOR_HEIGHT_THEN_AREA
 | 
						|
      </programlisting>
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
<parameter>priority</parameter> is one of the following:
 | 
						|
 | 
						|
      <blockquote>
 | 
						|
	<para>
 | 
						|
  <constant>PRIORITY_LOW</constant>
 | 
						|
	  <blockquote><para>
 | 
						|
     Return the largest block available without stealing anyone else's
 | 
						|
     space.  This corresponds to the priority of allocating a
 | 
						|
     <structname>FBArea</structname> when a <function>RemoveAreaCallback</function>
 | 
						|
     is provided.
 | 
						|
	    </para></blockquote>
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
   <constant>PRIORITY_NORMAL</constant>
 | 
						|
	  <blockquote><para>
 | 
						|
     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 <structname>FBArea</structname> without providing a
 | 
						|
     <function>RemoveAreaCallback</function>.
 | 
						|
	    </para></blockquote>
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    <constant>PRIORITY_EXTREME</constant>
 | 
						|
	  <blockquote><para>
 | 
						|
     Return the largest block available if all <structname>FBArea</structname>s
 | 
						|
     that aren't locked down were expunged from memory first.  This
 | 
						|
     corresponds to any allocation made directly after a call to
 | 
						|
     <function>xf86PurgeUnlockedOffscreenAreas()</function>.
 | 
						|
	    </para></blockquote>
 | 
						|
	</para>
 | 
						|
 | 
						|
      </blockquote>
 | 
						|
    </para>
 | 
						|
 | 
						|
 | 
						|
    <para>
 | 
						|
The function:
 | 
						|
 | 
						|
      <programlisting>
 | 
						|
    Bool xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen);
 | 
						|
      </programlisting>
 | 
						|
 | 
						|
is provided as an extreme method to free up offscreen memory.  This
 | 
						|
will remove all removable <structname>FBArea</structname> allocations.
 | 
						|
    </para>
 | 
						|
 | 
						|
 | 
						|
    <para>
 | 
						|
Initialization of the XFree86 framebuffer manager is done via
 | 
						|
 | 
						|
      <programlisting>
 | 
						|
    Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox);
 | 
						|
      </programlisting>
 | 
						|
 | 
						|
<parameter>FullBox</parameter> represents the area of the framebuffer that the
 | 
						|
manager is allowed to manage.  This is typically a box with a width of
 | 
						|
<structfield>pScrn->displayWidth</structfield> 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.
 | 
						|
    </para>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1 id="cmap">
 | 
						|
    <title>Colormap Handling</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
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
 | 
						|
<function>xf86HandleColormaps()</function> function.
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool xf86HandleColormaps(ScreenPtr pScreen, int maxColors,
 | 
						|
                             int sigRGBbits, LoadPaletteFuncPtr loadPalette,
 | 
						|
                             SetOverscanFuncPtr setOverscan,
 | 
						|
                             unsigned int flags);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function must be called after the default colormap has been
 | 
						|
      initialised.  The <structfield>pScrn->gamma</structfield> field must also
 | 
						|
      be initialised, preferably by calling <function>xf86SetGamma()</function>.
 | 
						|
      <parameter>maxColors</parameter> is the number of entries in the palette.
 | 
						|
      <parameter>sigRGBbits</parameter> is the size in bits of each color
 | 
						|
      component in the DAC's palette.  <parameter>loadPalette</parameter>
 | 
						|
      is a driver-provided function for loading a colormap into the
 | 
						|
      hardware, and is described below.  <parameter>setOverscan</parameter> 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
 | 
						|
      <parameter>setOverscan</parameter> function programs the overscan index.
 | 
						|
      It shouldn't normally be used for depths other than 8.
 | 
						|
      <parameter>setOverscan</parameter> should be set to <constant>NULL</constant>
 | 
						|
      when it isn't needed.  <parameter>flags</parameter> may be set to the
 | 
						|
      following (which may be ORed together):
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>CMAP_PALETTED_TRUECOLOR</constant></term>
 | 
						|
		  <listitem><para>
 | 
						|
				    the TrueColor visual is paletted and is
 | 
						|
				    just a special case of DirectColor.
 | 
						|
				    This flag is only valid for
 | 
						|
				    <code>bpp > 8</code>.
 | 
						|
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>CMAP_RELOAD_ON_MODE_SWITCH</constant></term>
 | 
						|
		  <listitem><para>
 | 
						|
				    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.
 | 
						|
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>CMAP_LOAD_EVEN_IF_OFFSCREEN</constant></term>
 | 
						|
		  <listitem><para>
 | 
						|
				    reload the colormap even if the screen
 | 
						|
				    is switched out of the server's VC.
 | 
						|
				    The palette is <emphasis>not</emphasis> 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.
 | 
						|
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
 | 
						|
                     LOCO *colors, VisualPtr pVisual);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      <function>LoadPalette()</function> is a driver-provided function for
 | 
						|
      loading a colormap into hardware.  <parameter>colors</parameter> is the
 | 
						|
      array of RGB values that represent the full colormap.
 | 
						|
      <parameter>indices</parameter> is a list of index values into the colors
 | 
						|
      array.  These indices indicate the entries that need to be updated.
 | 
						|
      <parameter>numColors</parameter> is the number of the indices to be
 | 
						|
      updated.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void SetOverscan(ScrnInfoPtr pScrn, int overscan);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      <function>SetOverscan()</function> is a driver-provided function for
 | 
						|
      programming the <parameter>overscan</parameter> 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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para>
 | 
						|
      </blockquote></para>
 | 
						|
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>DPMS Extension</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
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).
 | 
						|
    </para>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags);
 | 
						|
	</programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
      This function registers a driver's DPMS level programming function
 | 
						|
      <parameter>set</parameter>.  It also checks
 | 
						|
      <structfield>pScrn->options</structfield> for the "dpms" option, and when
 | 
						|
      present marks DPMS as being enabled for that screen.  The
 | 
						|
      <parameter>set</parameter> function is called whenever the DPMS level
 | 
						|
      changes, and is used to program the requested level.
 | 
						|
      <parameter>flags</parameter> is currently not used, and should be
 | 
						|
      <constant>0</constant>.  If the initialisation fails for any reason,
 | 
						|
      including when there is no DPMS support in the core server, the
 | 
						|
      function returns <constant>FALSE</constant>.
 | 
						|
	  </para>
 | 
						|
 | 
						|
	</blockquote></para></blockquote>
 | 
						|
 | 
						|
 | 
						|
    <para>
 | 
						|
Drivers that implement DPMS support must provide the following function,
 | 
						|
that gets called when the DPMS level is changed:
 | 
						|
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void ChipDPMSSet(ScrnInfoPtr pScrn, int level, int flags);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Program the DPMS level specified by <parameter>level</parameter>.  Valid
 | 
						|
      values of <parameter>level</parameter> are <constant>DPMSModeOn</constant>,
 | 
						|
      <constant>DPMSModeStandby</constant>, <constant>DPMSModeSuspend</constant>,
 | 
						|
      <constant>DPMSModeOff</constant>.  These values are defined in
 | 
						|
      <filename>"extensions/dpms.h"</filename>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </para>
 | 
						|
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>DGA Extension</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
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.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <blockquote><para>
 | 
						|
	<programlisting>
 | 
						|
    Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs,
 | 
						|
                 DGAModePtr modes, int num);
 | 
						|
 | 
						|
/** 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;
 | 
						|
	</programlisting>
 | 
						|
 | 
						|
	<variablelist>
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>num</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
	 Can be ignored.  The DGA DDX will assign these numbers.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>mode</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
	A pointer to the <structname>DisplayModeRec</structname> for this mode.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>flags</structfield></term>
 | 
						|
	      <listitem><para>
 | 
						|
	The following flags are defined and may be OR'd together:
 | 
						|
 | 
						|
		  <variablelist>
 | 
						|
		    <varlistentry>
 | 
						|
		      <term><constant>DGA_CONCURRENT_ACCESS</constant></term>
 | 
						|
		      <listitem><para>
 | 
						|
            Indicates that the driver supports concurrent graphics
 | 
						|
            accelerator and linear framebuffer access.
 | 
						|
 | 
						|
			</para></listitem></varlistentry>
 | 
						|
 | 
						|
		    <varlistentry>
 | 
						|
		      <term><constant>DGA_FILL_RECT
 | 
						|
			  DGA_BLIT_RECT
 | 
						|
			  DGA_BLIT_RECT_TRANS</constant></term>
 | 
						|
		      <listitem><para>
 | 
						|
	    Indicates that the driver supports the FillRect, BlitRect
 | 
						|
            or BlitTransRect functions in this mode.
 | 
						|
 | 
						|
			</para></listitem></varlistentry>
 | 
						|
 | 
						|
		    <varlistentry>
 | 
						|
		      <term><constant>DGA_PIXMAP_AVAILABLE</constant></term>
 | 
						|
		      <listitem><para>
 | 
						|
	    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.
 | 
						|
 | 
						|
			</para></listitem></varlistentry>
 | 
						|
 | 
						|
		    <varlistentry>
 | 
						|
		      <term><constant>DGA_INTERLACED
 | 
						|
			  DGA_DOUBLESCAN</constant></term>
 | 
						|
		      <listitem><para>
 | 
						|
            Indicates that these are interlaced or double scan modes.
 | 
						|
 | 
						|
			</para></listitem></varlistentry>
 | 
						|
		  </variablelist>
 | 
						|
		</para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>imageWidth
 | 
						|
		imageHeight</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		    These are the dimensions of the linear framebuffer
 | 
						|
                     accessible by the client.
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>pixmapWidth
 | 
						|
		pixmapHeight</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		     These are the dimensions of the area of the
 | 
						|
                     framebuffer accessible by the graphics accelerator.
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>bytesPerScanline</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		      Pitch of the framebuffer in bytes.
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>byteOrder</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		     Usually the same as
 | 
						|
		     <structfield>pScrn->imageByteOrder</structfield>.
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>depth</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		     The depth of the framebuffer in this mode.
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>bitsPerPixel</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		      The number of bits per pixel in this mode.
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>red_mask</structfield></term>
 | 
						|
	    <term><structfield>green_mask</structfield></term>
 | 
						|
	    <term><structfield>blue_mask</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		      The RGB masks for this mode, if applicable.
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>viewportWidth</structfield></term>
 | 
						|
	    <term><structfield>viewportHeight</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		      Dimensions of the visible part of the framebuffer.
 | 
						|
		      Usually <structfield>mode->HDisplay</structfield> and
 | 
						|
		      <structfield>mode->VDisplay</structfield>.
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>xViewportStep
 | 
						|
		yViewportStep</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		     The granularity of x and y viewport positions that
 | 
						|
                     the driver supports in this mode.
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>maxViewportX
 | 
						|
		maxViewportY</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		      The maximum viewport position supported by the
 | 
						|
                       driver in this mode.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>viewportFlags</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		     The following may be OR'd together:
 | 
						|
 | 
						|
		<variablelist>
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><constant>DGA_FLIP_IMMEDIATE</constant></term>
 | 
						|
		    <listitem><para>
 | 
						|
		The driver supports immediate viewport changes.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><constant>DGA_FLIP_RETRACE</constant></term>
 | 
						|
 | 
						|
		    <listitem><para>
 | 
						|
		The driver supports viewport changes at retrace.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
		  </variablelist>
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>offset</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
	        The offset into the linear framebuffer that corresponds to
 | 
						|
                pixel (0,0) for this mode.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>address</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
                The virtual address of the framebuffer as mapped by the driver.
 | 
						|
                This is needed when DGA_PIXMAP_AVAILABLE is set.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	</variablelist>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
/** 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;
 | 
						|
	</programlisting>
 | 
						|
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    Bool OpenFramebuffer (pScrn, name, mem, size, offset, extra);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      <function>OpenFramebuffer()</function> 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.
 | 
						|
 | 
						|
		<variablelist>
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><parameter>name</parameter></term>
 | 
						|
		    <listitem><para>
 | 
						|
	      The name of the device to open or <constant>NULL</constant> if
 | 
						|
	      there is no special device to open.  A <constant>NULL</constant>
 | 
						|
	      name tells the client that it should open whatever device
 | 
						|
	      one would usually open to access physical memory.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><parameter>mem</parameter></term>
 | 
						|
		    <listitem><para>
 | 
						|
	      The physical address of the start of the framebuffer.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><parameter>size</parameter></term>
 | 
						|
		    <listitem><para>
 | 
						|
	      The size of the framebuffer in bytes.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><parameter>offset</parameter></term>
 | 
						|
		    <listitem><para>
 | 
						|
	      Any offset into the device, if applicable.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><parameter>flags</parameter></term>
 | 
						|
		    <listitem><para>
 | 
						|
	      Any additional information that the client may need.
 | 
						|
	      Currently, only the <constant>DGA_NEED_ROOT</constant> flag is
 | 
						|
	      defined.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		</variablelist>
 | 
						|
	      </para></blockquote>
 | 
						|
	  </para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    void CloseFramebuffer (pScrn);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      <function>CloseFramebuffer()</function> merely informs the driver (if it
 | 
						|
      even cares) that client no longer needs to access the framebuffer
 | 
						|
      directly.  This function is optional.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    Bool SetMode (pScrn, pMode);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      <function>SetMode()</function> tells the driver to initialize the mode
 | 
						|
      passed to it.  If <parameter>pMode</parameter> is <constant>NULL</constant>,
 | 
						|
      then the driver should restore the original pre-DGA mode.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    void SetViewport (pScrn, x, y, flags);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      <function>SetViewport()</function> tells the driver to make the upper
 | 
						|
      left-hand corner of the visible screen correspond to coordinate
 | 
						|
      <literal remap="tt">(x,y)</literal> on the framebuffer.  <parameter>flags</parameter>
 | 
						|
      currently defined are:
 | 
						|
 | 
						|
		<variablelist>
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><constant>DGA_FLIP_IMMEDIATE</constant></term>
 | 
						|
		    <listitem><para>
 | 
						|
	    The viewport change should occur immediately.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><constant>DGA_FLIP_RETRACE</constant></term>
 | 
						|
		    <listitem><para>
 | 
						|
	    The viewport change should occur at the
 | 
						|
            vertical retrace, but this function should
 | 
						|
            return sooner if possible.
 | 
						|
			</para></listitem></varlistentry>
 | 
						|
		</variablelist>
 | 
						|
	      </para>
 | 
						|
 | 
						|
	      <para>
 | 
						|
      The <literal remap="tt">(x,y)</literal> 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
 | 
						|
      <structfield>xViewportStep</structfield> and <structfield>yViewportStep</structfield>
 | 
						|
      for the current mode.
 | 
						|
	      </para>
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    int GetViewport (pScrn);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      <function>GetViewport()</function> 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.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    void Sync (pScrn);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      This function should ensure that any graphics accelerator operations
 | 
						|
      have finished.  This function should not return until the graphics
 | 
						|
      accelerator is idle.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    void FillRect (pScrn, x, y, w, h, color);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      This optional function should fill a rectangle
 | 
						|
      <parameter>w × h</parameter> located at
 | 
						|
      <parameter>(x,y)</parameter> in the given color.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    void BlitRect (pScrn, srcx, srcy, w, h, dstx, dsty);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      This optional function should copy an area
 | 
						|
      <parameter>w × h</parameter> located at
 | 
						|
      <parameter>(srcx,srcy)</parameter> to location <parameter>(dstx,dsty)</parameter>.
 | 
						|
      This function will need to handle copy directions as appropriate.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    void BlitTransRect (pScrn, srcx, srcy, w, h, dstx, dsty, color);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
      This optional function is the same as BlitRect except that pixels
 | 
						|
      in the source corresponding to the color key <parameter>color</parameter>
 | 
						|
      should be skipped.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
    </para></blockquote>
 | 
						|
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>The XFree86 X Video Extension (Xv) Device Dependent Layer</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
XFree86 offers the X Video Extension which allows clients to treat video
 | 
						|
as any another primitive and <quote>Put</quote> 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 <literal remap="tt">XF86VideoAdaptorRecs</literal>
 | 
						|
as described later in this document and passing a list of
 | 
						|
<literal remap="tt">XF86VideoAdaptorPtr</literal> pointers to the following function:
 | 
						|
 | 
						|
      <programlisting>
 | 
						|
    Bool xf86XVScreenInit(ScreenPtr pScreen,
 | 
						|
                          XF86VideoAdaptorPtr *adaptPtrs,
 | 
						|
                          int num);
 | 
						|
      </programlisting>
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
After doing this, the extension will report video adaptors as being
 | 
						|
available, providing the data in their respective
 | 
						|
<literal remap="tt">XF86VideoAdaptorRecs</literal> was valid.
 | 
						|
<function>xf86XVScreenInit()</function> <emphasis>copies</emphasis> 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.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The <structname>XF86VideoAdaptorRec</structname>:
 | 
						|
 | 
						|
      <programlisting>
 | 
						|
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;
 | 
						|
      </programlisting></para>
 | 
						|
 | 
						|
    <para>
 | 
						|
Each adaptor will have its own XF86VideoAdaptorRec.  The fields are
 | 
						|
as follows:
 | 
						|
 | 
						|
      <variablelist>
 | 
						|
	<varlistentry>
 | 
						|
	  <term><structfield>type</structfield></term>
 | 
						|
	  <listitem><para>
 | 
						|
	This can be any of the following flags OR'd together.
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>XvInputMask</constant>
 | 
						|
		    <constant>XvOutputMask</constant></term>
 | 
						|
		  <listitem><para>
 | 
						|
	    These refer to the target drawable and are similar to a Window's
 | 
						|
	    class. <literal remap="tt">XvInputMask</literal> indicates that the adaptor
 | 
						|
	    can put video into a drawable.  <literal remap="tt">XvOutputMask</literal>
 | 
						|
	    indicates that the adaptor can get video from a drawable.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>XvVideoMask</constant>
 | 
						|
		    <constant>XvStillMask</constant>
 | 
						|
		    <constant>XvImageMask</constant></term>
 | 
						|
		  <listitem><para>
 | 
						|
	    These indicate that the adaptor supports video, still or
 | 
						|
	    image primitives respectively.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>XvWindowMask</constant>
 | 
						|
		    <constant>XvPixmapMask</constant></term>
 | 
						|
		  <listitem><para>
 | 
						|
	    These indicate the types of drawables the adaptor is capable
 | 
						|
	    of rendering into.  At the moment, Pixmap rendering is not
 | 
						|
	    supported and the <constant>XvPixmapMask</constant> flag is ignored.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
	      </variablelist>
 | 
						|
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	<varlistentry>
 | 
						|
	  <term><structfield>flags</structfield></term>
 | 
						|
	  <listitem><para>
 | 
						|
	Currently, the following flags are defined:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>VIDEO_OVERLAID_STILLS</constant></term>
 | 
						|
		  <listitem><para>
 | 
						|
	   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.
 | 
						|
		    </para></listitem>
 | 
						|
 | 
						|
		</varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>VIDEO_OVERLAID_IMAGES</constant></term>
 | 
						|
		  <listitem><para>
 | 
						|
	   Same as <constant>VIDEO_OVERLAID_STILLS</constant> but for images.
 | 
						|
		    </para></listitem>
 | 
						|
		</varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>VIDEO_CLIP_TO_VIEWPORT</constant></term>
 | 
						|
		  <listitem><para>
 | 
						|
	    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.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	      </variablelist>
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	<varlistentry>
 | 
						|
	  <term><structfield>name</structfield></term>
 | 
						|
	  <listitem><para>
 | 
						|
	The name of the adaptor.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	<varlistentry>
 | 
						|
	  <term><structfield>nEncodings</structfield>
 | 
						|
	    <structfield>pEncodings</structfield></term>
 | 
						|
	  <listitem><para>
 | 
						|
	The number of encodings the adaptor is capable of and pointer
 | 
						|
	to the <structname>XF86VideoEncodingRec</structname> array.  The
 | 
						|
	<structname>XF86VideoEncodingRec</structname> 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.
 | 
						|
	  </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	<varlistentry>
 | 
						|
	  <term><structfield>nFormats</structfield>
 | 
						|
	      <structfield>pFormats</structfield></term>
 | 
						|
	  <listitem><para>
 | 
						|
	The number of formats the adaptor is capable of and pointer to
 | 
						|
	the <structname>XF86VideoFormatRec</structname> array.  The
 | 
						|
	<structname>XF86VideoFormatRec</structname> is described later on.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	<varlistentry>
 | 
						|
	  <term><structfield>nPorts</structfield>
 | 
						|
	    <structfield>pPortPrivates</structfield></term>
 | 
						|
	  <listitem><para>
 | 
						|
	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.  <structfield>pPortPrivates</structfield> 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.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	<varlistentry>
 | 
						|
	  <term><structfield>nAttributes</structfield>
 | 
						|
	    <structfield>pAttributes</structfield></term>
 | 
						|
	  <listitem><para>
 | 
						|
	The number of attributes recognized by the adaptor and a pointer to
 | 
						|
	the array of <structname>XF86AttributeRecs</structname>.  The
 | 
						|
	<structname>XF86AttributeRec</structname> is described later on.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	<varlistentry>
 | 
						|
	  <term><structfield>nImages</structfield>
 | 
						|
	    <structfield>pImages</structfield></term>
 | 
						|
	  <listitem><para>
 | 
						|
	The number of <structname>XF86ImageRecs</structname> supported by the adaptor
 | 
						|
	and a pointer to the array of <structname>XF86ImageRecs</structname>. The
 | 
						|
	<structname>XF86ImageRec</structname> is described later on.
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	<varlistentry>
 | 
						|
	  <term><structfield>
 | 
						|
     PutVideo PutStill GetVideo GetStill StopVideo
 | 
						|
     SetPortAttribute GetPortAttribute QueryBestSize PutImage
 | 
						|
     QueryImageAttributes
 | 
						|
	    </structfield></term>
 | 
						|
	  <listitem><para>
 | 
						|
	These functions define the DDX->driver interface.  In each
 | 
						|
	case, the pointer <parameter>data</parameter> 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:
 | 
						|
 | 
						|
	      <orderedlist>
 | 
						|
		<listitem><para>
 | 
						|
	     <structfield>PutVideo</structfield>, <structfield>PutStill</structfield> and
 | 
						|
	     the image routines <structfield>PutImage</structfield> and
 | 
						|
	     <structfield>QueryImageAttributes</structfield> are not required when the
 | 
						|
	     adaptor type does not contain <constant>XvInputMask</constant>.
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
	     <structfield>GetVideo</structfield> and <structfield>GetStill</structfield>
 | 
						|
	     are not required when the adaptor type does not contain
 | 
						|
	     <constant>XvOutputMask</constant>.
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
	     <structfield>GetVideo</structfield> and <structfield>PutVideo</structfield>
 | 
						|
	     are not required when the adaptor type does not contain
 | 
						|
	     <constant>XvVideoMask</constant>.
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
	     <structfield>GetStill</structfield> and <structfield>PutStill</structfield>
 | 
						|
	     are not required when the adaptor type does not contain
 | 
						|
	     <constant>XvStillMask</constant>.
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
		<listitem><para>
 | 
						|
	     <structfield>PutImage</structfield> and <structfield>QueryImageAttributes</structfield>
 | 
						|
	     are not required when the adaptor type does not contain
 | 
						|
	     <constant>XvImageMask</constant>.
 | 
						|
		  </para></listitem>
 | 
						|
 | 
						|
	      </orderedlist>
 | 
						|
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
	With the exception of <structfield>QueryImageAttributes</structfield>, these
 | 
						|
	functions should return <constant>Success</constant> if the operation was
 | 
						|
	completed successfully.  They can return <constant>XvBadAlloc</constant>
 | 
						|
	otherwise. <structfield>QueryImageAttributes</structfield> returns the size
 | 
						|
	of the XvImage queried.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
	<literal remap="tt">ClipBoxes</literal> is an <literal remap="tt">X-Y</literal>
 | 
						|
	banded region identical to those used throughout the server.
 | 
						|
	The clipBoxes represent the visible portions of the area determined
 | 
						|
	by <literal remap="tt">drw_x</literal>, <literal remap="tt">drw_y</literal>,
 | 
						|
	<literal remap="tt">drw_w</literal> and <literal remap="tt">drw_h</literal> in the Get/Put
 | 
						|
	function.  The boxes are in screen coordinates, are guaranteed
 | 
						|
	not to overlap and an empty region will never be passed.
 | 
						|
 | 
						|
	    </para></listitem></varlistentry>
 | 
						|
      </variablelist>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    typedef  int (* PutVideoFuncPtr)( ScrnInfoPtr pScrn,
 | 
						|
                   short vid_x, short vid_y, short drw_x, short drw_y,
 | 
						|
                   short vid_w, short vid_h, short drw_w, short drw_h,
 | 
						|
                   RegionPtr clipBoxes, pointer data );
 | 
						|
	  </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
	  This indicates that the driver should take a subsection
 | 
						|
	  <parameter>vid_w</parameter> by <parameter>vid_h</parameter> at location
 | 
						|
	  <parameter>(vid_x,vid_y)</parameter> from the video stream and direct
 | 
						|
	  it into the rectangle <parameter>drw_w</parameter> by <parameter>drw_h</parameter>
 | 
						|
	  at location <parameter>(drw_x,drw_y)</parameter> 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
 | 
						|
	  <quote>the best it can,</quote> 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.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    typedef  int (* PutStillFuncPtr)( ScrnInfoPtr pScrn,
 | 
						|
                   short vid_x, short vid_y, short drw_x, short drw_y,
 | 
						|
                   short vid_w, short vid_h, short drw_w, short drw_h,
 | 
						|
                   RegionPtr clipBoxes, pointer data );
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
	  This is same as <structfield>PutVideo</structfield> except that the driver
 | 
						|
	  should place only one frame from the stream on the screen.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    typedef int (* GetVideoFuncPtr)( ScrnInfoPtr pScrn,
 | 
						|
                  short vid_x, short vid_y, short drw_x, short drw_y,
 | 
						|
                  short vid_w, short vid_h, short drw_w, short drw_h,
 | 
						|
                  RegionPtr clipBoxes, pointer data );
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
	  This is same as <structfield>PutVideo</structfield> 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.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    typedef int (* GetStillFuncPtr)( ScrnInfoPtr pScrn,
 | 
						|
                  short vid_x, short vid_y, short drw_x, short drw_y,
 | 
						|
                  short vid_w, short vid_h, short drw_w, short drw_h,
 | 
						|
                  RegionPtr clipBoxes, pointer data );
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
	  This is the same as <literal remap="tt">GetVideo</literal> except that the
 | 
						|
	  driver should place only one frame from the screen into the
 | 
						|
	  output stream.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    typedef void (* StopVideoFuncPtr)(ScrnInfoPtr pScrn,
 | 
						|
                                      pointer data, Bool cleanup);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
	  This indicates the driver should stop displaying the video.
 | 
						|
	  This is used to stop both input and output video.  The
 | 
						|
	  <parameter>cleanup</parameter> 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
 | 
						|
	  <parameter>cleanup</parameter> 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.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
	  <blockquote><para>
 | 
						|
	      <programlisting>
 | 
						|
    typedef int (* SetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
 | 
						|
                                Atom attribute,INT32 value, pointer data);
 | 
						|
	      </programlisting>
 | 
						|
 | 
						|
	      <programlisting>
 | 
						|
    typedef int (* GetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
 | 
						|
                                Atom attribute,INT32 *value, pointer data);
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
	  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:
 | 
						|
		<literallayout><constant>
 | 
						|
		XV_ENCODING
 | 
						|
		XV_HUE
 | 
						|
		XV_SATURATION
 | 
						|
		XV_BRIGHTNESS
 | 
						|
		XV_CONTRAST
 | 
						|
		  </constant></literallayout>
 | 
						|
	  but the driver may recognize as many atoms as it wishes.  If
 | 
						|
	  a requested attribute is unknown by the driver it should return
 | 
						|
	  <constant>BadMatch</constant>.  <constant>XV_ENCODING</constant> is the
 | 
						|
	  attribute intended to let the client specify which video
 | 
						|
	  encoding the particular port should be using (see the description
 | 
						|
	  of <structname>XF86VideoEncodingRec</structname> below).  If the
 | 
						|
	  requested encoding is unsupported, the driver should return
 | 
						|
	  <constant>XvBadEncoding</constant>.  If the value lies outside the
 | 
						|
	  advertised range <constant>BadValue</constant> may be returned.
 | 
						|
	  <constant>Success</constant> should be returned otherwise.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	  <blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    typedef void (* QueryBestSizeFuncPtr)(ScrnInfoPtr pScrn,
 | 
						|
                   Bool motion, short vid_w, short vid_h,
 | 
						|
                   short drw_w, short drw_h,
 | 
						|
                   unsigned int *p_w, unsigned int *p_h, pointer data);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
	   <function>QueryBestSize</function> provides the client with a way
 | 
						|
	   to query what the destination dimensions would end up being
 | 
						|
	   if they were to request that an area
 | 
						|
	   <parameter>vid_w</parameter> by <parameter>vid_h</parameter> from the video
 | 
						|
	   stream be scaled to rectangle of
 | 
						|
	   <parameter>drw_w</parameter> by <parameter>drw_h</parameter> 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.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    typedef  int (* PutImageFuncPtr)( ScrnInfoPtr pScrn,
 | 
						|
                   short src_x, short src_y, short drw_x, short drw_y,
 | 
						|
                   short src_w, short src_h, short drw_w, short drw_h,
 | 
						|
                   int image, char *buf, short width, short height,
 | 
						|
                   Bool sync, RegionPtr clipBoxes, pointer data );
 | 
						|
	      </programlisting>
 | 
						|
	      <blockquote><para>
 | 
						|
	  This is similar to <structfield>PutStill</structfield> except that the
 | 
						|
	  source of the video is not a port but the data stored in a system
 | 
						|
	  memory buffer at <parameter>buf</parameter>.  The data is in the format
 | 
						|
	  indicated by the <parameter>image</parameter> descriptor and represents a
 | 
						|
	  source of size <parameter>width</parameter> by <parameter>height</parameter>.
 | 
						|
	  If <parameter>sync</parameter> is TRUE the driver should not return
 | 
						|
	  from this function until it is through reading the data
 | 
						|
	  from <parameter>buf</parameter>.  Returning when <parameter>sync</parameter>
 | 
						|
	  is TRUE indicates that it is safe for the data at <parameter>buf</parameter>
 | 
						|
	  to be replaced, freed, or modified.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    typedef  int (* QueryImageAttributesFuncPtr)( ScrnInfoPtr pScrn,
 | 
						|
                                int image, short *width, short *height,
 | 
						|
                                int *pitches, int *offsets);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
	  This function is called to let the driver specify how data for
 | 
						|
	  a particular <parameter>image</parameter> of size <parameter>width</parameter>
 | 
						|
	  by <parameter>height</parameter> should be stored.  Sometimes only
 | 
						|
	  the size and corrected width and height are needed.  In that
 | 
						|
	  case <parameter>pitches</parameter> and <parameter>offsets</parameter> are
 | 
						|
	  NULL.  The size of the memory required for the image is returned
 | 
						|
	  by this function.  The <parameter>width</parameter> and
 | 
						|
	  <parameter>height</parameter> 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
 | 
						|
	  <parameter>pitches</parameter> and <parameter>offsets</parameter> are not NULL,
 | 
						|
	  these will be arrays with as many elements in them as there
 | 
						|
	  are planes in the <parameter>image</parameter> 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.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The XF86VideoEncodingRec:
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
typedef struct {
 | 
						|
	int id;
 | 
						|
	char *name;
 | 
						|
	unsigned short width, height;
 | 
						|
	XvRationalRec rate;
 | 
						|
} XF86VideoEncodingRec, *XF86VideoEncodingPtr;
 | 
						|
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
   The <structname>XF86VideoEncodingRec</structname> 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
 | 
						|
   <function>XvQueryEncodings</function>.  The <parameter>id</parameter> field is
 | 
						|
   expected to be a unique identifier to allow the client to request a
 | 
						|
   certain encoding via the <constant>XV_ENCODING</constant> attribute string.
 | 
						|
 | 
						|
	    </para>
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The XF86VideoFormatRec:
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
typedef struct {
 | 
						|
	char  depth;
 | 
						|
	short class;
 | 
						|
} XF86VideoFormatRec, *XF86VideoFormatPtr;
 | 
						|
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This specifies what visuals the video is viewable in.
 | 
						|
    <parameter>depth</parameter> is the depth of the visual (not bpp).
 | 
						|
    <parameter>class</parameter> is the visual class such as
 | 
						|
    <constant>TrueColor</constant>, <constant>DirectColor</constant> or
 | 
						|
    <constant>PseudoColor</constant>.  Initialization of an adaptor will fail
 | 
						|
    if none of the visuals on that screen are supported.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The XF86AttributeRec:
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
typedef struct {
 | 
						|
	int   flags;
 | 
						|
	int   min_value;
 | 
						|
	int   max_value;
 | 
						|
	char  *name;
 | 
						|
} XF86AttributeListRec, *XF86AttributeListPtr;
 | 
						|
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
   Each adaptor may have an array of these advertising the attributes
 | 
						|
   for its ports.  Currently defined flags are <literal remap="tt">XvGettable</literal>
 | 
						|
   and <literal remap="tt">XvSettable</literal> which may be OR'd together indicating that
 | 
						|
   attribute is <quote>gettable</quote> or <quote>settable</quote> by the client.  The
 | 
						|
   <literal remap="tt">min</literal> and <literal remap="tt">max</literal> field specify the valid range
 | 
						|
   for the value.  <literal remap="tt">Name</literal> is a text string describing the
 | 
						|
   attribute by name.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The XF86ImageRec:
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
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;
 | 
						|
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
   XF86ImageRec describes how video source data is laid out in memory.
 | 
						|
   The fields are as follows:
 | 
						|
 | 
						|
		<variablelist>
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>id</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	This is a unique descriptor for the format.  It is often good to
 | 
						|
        set this value to the FOURCC for the format when applicable.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>type</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	This is <constant>XvRGB</constant> or <constant>XvYUV</constant>.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>byte_order</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	This is <constant>LSBFirst</constant> or <constant>MSBFirst</constant>.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>guid</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	This is the Globally Unique IDentifier for the format.  When
 | 
						|
	not applicable, all characters should be NULL.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>bits_per_pixel</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	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_.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>format</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	This is <constant>XvPlanar</constant> or <constant>XvPacked</constant>.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>num_planes</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	The number of planes in planar formats.  This should be set to
 | 
						|
	one for packed formats.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>depth</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	The significant bits per pixel in RGB formats (analogous to the
 | 
						|
	depth of a pixmap format).
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>red_mask</structfield></term>
 | 
						|
		    <term><structfield>green_mask</structfield></term>
 | 
						|
		    <term><structfield>blue_mask</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	The red, green and blue bitmasks for packed RGB formats.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>y_sample_bits</structfield></term>
 | 
						|
		    <term><structfield>u_sample_bits</structfield></term>
 | 
						|
		    <term><structfield>v_sample_bits</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	The y, u and v sample sizes (in bits).
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>horz_y_period</structfield></term>
 | 
						|
		    <term><structfield>horz_u_period</structfield></term>
 | 
						|
		    <term><structfield>horz_v_period</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	The y, u and v sampling periods in the horizontal direction.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>vert_y_period</structfield></term>
 | 
						|
		    <term><structfield>vert_u_period</structfield></term>
 | 
						|
		    <term><structfield>vert_v_period</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	The y, u and v sampling periods in the vertical direction.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>component_order</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	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.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><structfield>scanline_order</structfield></term>
 | 
						|
		    <listitem><para>
 | 
						|
	This is <constant>XvTopToBottom</constant> or <constant>XvBottomToTop</constant>.
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
 | 
						|
		  </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
  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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </para>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>The Loader</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
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.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Loader Overview</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
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 <function>dlopen(3)</function> service where
 | 
						|
available.  Such modules are not platform independent, and the semantics
 | 
						|
of <function>dlopen()</function> on most systems results in significant
 | 
						|
limitations in the use of modules of this type.  Support for
 | 
						|
<function>dlopen()</function> modules in the loader is primarily for
 | 
						|
experimental and development purposes.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
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.
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Semi-private Loader Interface</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
The following is the semi-private loader interface that is available to the
 | 
						|
XFree86 common layer.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void LoaderInit(void);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    The <function>LoaderInit()</function> 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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void LoaderSetPath(const char *path);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    The <function>LoaderSetPath()</function> 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 <parameter>path</parameter> 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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    pointer LoadModule(const char *module, pointer options,
 | 
						|
                       const XF86ModReqInfo * modreq, int *errmaj);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    The <function>LoadModule()</function> function loads the module called
 | 
						|
    <parameter>module</parameter>.  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 <parameter>module</parameter> 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:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>options</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		  An optional parameter that is passed to the newly
 | 
						|
		  loaded module's <literal remap="tt">SetupProc</literal> function
 | 
						|
		  (if it has one).  This argument is normally a
 | 
						|
		  <constant>NULL</constant> terminated list of
 | 
						|
		  <structname>Options</structname>, 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.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>modreq</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		  An optional <structname>XF86ModReqInfo*</structname> 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 <function>SetupProc</function> function.
 | 
						|
		      </para>
 | 
						|
 | 
						|
		    <para>
 | 
						|
		  The <literal remap="tt">XF86ModReqInfo</literal> struct is defined
 | 
						|
		  as follows:
 | 
						|
		      <programlisting>
 | 
						|
typedef struct {
 | 
						|
	CARD8        majorversion;
 | 
						|
	CARD8        minorversion;
 | 
						|
	CARD16       patchlevel;
 | 
						|
	const char * abiclass;
 | 
						|
	CARD32       abiversion;
 | 
						|
	const char * moduleclass;
 | 
						|
} XF86ModReqInfo;
 | 
						|
			</programlisting>
 | 
						|
 | 
						|
		  The information here is compared against the equivalent
 | 
						|
		  information in the module's
 | 
						|
		  <structname>XF86ModuleVersionInfo</structname> record (which
 | 
						|
		  is described below).  The values in comments above
 | 
						|
		  indicate <quote>don't care</quote> settings for each of the fields.
 | 
						|
		  The comparisons made are as follows:
 | 
						|
 | 
						|
		      <variablelist>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><structfield>majorversion</structfield></term>
 | 
						|
			  <listitem><para>
 | 
						|
				   Must match the module's majorversion
 | 
						|
				   exactly.
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
 | 
						|
			<varlistentry>
 | 
						|
			  <term><structfield>minorversion</structfield></term>
 | 
						|
			  <listitem><para>
 | 
						|
				   The module's minor version must be
 | 
						|
				   no less than this value.  This
 | 
						|
				   comparison is only made if
 | 
						|
				   <structfield>majorversion</structfield>
 | 
						|
                                   matches.
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
 | 
						|
			<varlistentry>
 | 
						|
			  <term><structfield>patchlevel</structfield></term>
 | 
						|
			  <listitem><para>
 | 
						|
				   The module's patchlevel must be no
 | 
						|
				   less than this value.  This comparison
 | 
						|
				   is only made if
 | 
						|
				   <structfield>minorversion</structfield>
 | 
						|
				   matches.
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
 | 
						|
			<varlistentry>
 | 
						|
			  <term><structfield>abiclass</structfield></term>
 | 
						|
			  <listitem><para>
 | 
						|
				   String must match the module's abiclass
 | 
						|
				   string.
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
 | 
						|
			<varlistentry>
 | 
						|
			  <term><structfield>abiversion</structfield></term>
 | 
						|
			  <listitem><para>
 | 
						|
				   Must be consistent with the module's
 | 
						|
				   abiversion (major equal, minor no
 | 
						|
				   older).
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
 | 
						|
			<varlistentry>
 | 
						|
			  <term><structfield>moduleclass</structfield></term>
 | 
						|
			  <listitem><para>
 | 
						|
				   String must match the module's
 | 
						|
				   moduleclass string.
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		      </variablelist>
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>errmaj</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		  An optional pointer to a variable holding the major
 | 
						|
		  part or the error code.  When provided,
 | 
						|
		  <parameter>*errmaj</parameter> is filled in when
 | 
						|
		  <function>LoadModule()</function> fails.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	      </variablelist>
 | 
						|
 | 
						|
	    </para></blockquote>
 | 
						|
	</para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void UnloadModule(pointer mod);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    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 <function>LoadSubModule()</function>
 | 
						|
    described below).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Module Requirements</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
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 <function>SetupProc</function>
 | 
						|
and <function>TearDownProc</function>).
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
The module information is contained in the
 | 
						|
<structname>XF86ModuleVersionInfo</structname> struct, which is defined as follows:
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
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;
 | 
						|
	</programlisting>
 | 
						|
 | 
						|
The fields are used as follows:
 | 
						|
 | 
						|
	<variablelist>
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>modname</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		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.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>vendor</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		The module vendor.  This field is for informational purposes
 | 
						|
                only.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>_modinfo1_</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		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 <constant>MODINFOSTRING1</constant>.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>_modinfo2_</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		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 <constant>MODINFOSTRING2</constant>.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>xf86version</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		The XFree86 version against which the module was compiled.
 | 
						|
                This is mostly for informational/diagnostic purposes.  It
 | 
						|
		should be initialised to <constant>XF86_VERSION_CURRENT</constant>, which is
 | 
						|
		defined in <filename>xf86Version.h</filename>.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>majorversion</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		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.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>minorversion</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		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.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>patchlevel</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		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.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>abiclass</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		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:
 | 
						|
 | 
						|
		<variablelist>
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><constant>ABI_CLASS_NONE</constant></term>
 | 
						|
		    <listitem><para>no class
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><constant>ABI_CLASS_ANSIC</constant></term>
 | 
						|
		    <listitem><para>only requires the ANSI C interfaces
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><constant>ABI_CLASS_VIDEODRV</constant></term>
 | 
						|
		    <listitem><para>requires the video driver ABI
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><constant>ABI_CLASS_XINPUT</constant></term>
 | 
						|
		    <listitem><para>requires the XInput driver ABI
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
		  <varlistentry>
 | 
						|
		    <term><constant>ABI_CLASS_EXTENSION</constant></term>
 | 
						|
		    <listitem><para>requires the extension module ABI
 | 
						|
		      </para></listitem></varlistentry>
 | 
						|
		</variablelist>
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>abiversion</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		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:
 | 
						|
 | 
						|
		<literallayout><constant>
 | 
						|
                   ABI_ANSIC_VERSION
 | 
						|
                   ABI_VIDEODRV_VERSION
 | 
						|
                   ABI_XINPUT_VERSION
 | 
						|
                   ABI_EXTENSION_VERSION
 | 
						|
		  </constant></literallayout>
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>moduleclass</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		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:
 | 
						|
 | 
						|
		<literallayout><constant>
 | 
						|
                   MOD_CLASS_NONE
 | 
						|
                   MOD_CLASS_VIDEODRV
 | 
						|
                   MOD_CLASS_XINPUT
 | 
						|
                   MOD_CLASS_EXTENSION
 | 
						|
		  </constant></literallayout>
 | 
						|
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	  <varlistentry>
 | 
						|
	    <term><structfield>checksum</structfield></term>
 | 
						|
	    <listitem><para>
 | 
						|
		Not currently used.
 | 
						|
	      </para></listitem></varlistentry>
 | 
						|
 | 
						|
	</variablelist>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
The module version information, and the optional <function>SetupProc</function>
 | 
						|
and <function>TearDownProc</function> 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:
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
typedef struct {
 | 
						|
    XF86ModuleVersionInfo *     vers;
 | 
						|
    ModuleSetupProc             setup;
 | 
						|
    ModuleTearDownProc          teardown;
 | 
						|
} XF86ModuleData;
 | 
						|
	</programlisting>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
The vers parameter must be initialised to a pointer to a correctly
 | 
						|
initialised <structname>XF86ModuleVersionInfo</structname> struct.  The other
 | 
						|
two parameter are optional, and should be initialised to
 | 
						|
<constant>NULL</constant> when not required.  The other parameters are defined
 | 
						|
as
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    typedef pointer (*ModuleSetupProc)(pointer, pointer, int *, int *);
 | 
						|
 | 
						|
    typedef void (*ModuleTearDownProc)(pointer);
 | 
						|
 | 
						|
    pointer SetupProc(pointer module, pointer options,
 | 
						|
                      int *errmaj, int *errmin);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
    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 <function>SetupProc</function> if it calls other
 | 
						|
    loader functions that require a reference to it.   The remaining
 | 
						|
    arguments are those that were passed to the
 | 
						|
    <function>LoadModule()</function> (or <function>LoadSubModule()</function>),
 | 
						|
    and are described above. When the <function>SetupProc</function> is
 | 
						|
    successful it must return a non-<constant>NULL</constant> value.  The
 | 
						|
    loader checks this, and if it is <constant>NULL</constant> it unloads
 | 
						|
    the module and reports the failure to the caller of
 | 
						|
    <function>LoadModule()</function>.  If the <function>SetupProc</function>
 | 
						|
    does things that need to be undone when the module is unloaded,
 | 
						|
    it should define a <function>TearDownProc</function>, and return a
 | 
						|
    pointer that the <function>TearDownProc</function> can use to undo what
 | 
						|
    has been done.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	      <para>
 | 
						|
    When a module is loaded multiple times, the <function>SetupProc</function>
 | 
						|
    is called once for each time it is loaded.
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	    <programlisting>
 | 
						|
    void TearDownProc(pointer tearDownData);
 | 
						|
	    </programlisting>
 | 
						|
	    <blockquote><para>
 | 
						|
    When defined, this function is called when the loader unloads a
 | 
						|
    module.  The <parameter>tearDownData</parameter> parameter is the return
 | 
						|
    value of the <function>SetupProc()</function> 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).
 | 
						|
	      </para>
 | 
						|
 | 
						|
	    </blockquote></para></blockquote>
 | 
						|
      </para>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Public Loader Interface</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
The following is the Loader interface that is available to any part of
 | 
						|
the server, and may also be used from within modules.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    pointer LoadSubModule(pointer parent, const char *module,
 | 
						|
                          const char **subdirlist, const char **patternlist,
 | 
						|
                          pointer options, const XF86ModReqInfo * modreq,
 | 
						|
                          int *errmaj, int *errmin);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This function is like the <function>LoadModule()</function> function
 | 
						|
    described above, except that the module loaded is registered as a
 | 
						|
    child of the calling module.  The <parameter>parent</parameter> parameter
 | 
						|
    is the calling module's handle.  Modules loaded with this function
 | 
						|
    are automatically unloaded when the parent module is unloaded.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void UnloadSubModule(pointer module);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This function unloads the module with handle <parameter>module</parameter>.
 | 
						|
    If that module itself has children, they are also unloaded.  It is
 | 
						|
    like <function>UnloadModule()</function>, except that it is safe to use
 | 
						|
    for unloading child modules.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    pointer LoaderSymbol(const char *symbol);
 | 
						|
	  </programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
    This function returns the address of the symbol with name
 | 
						|
    <parameter>symbol</parameter>.  This may be used to locate a module entry
 | 
						|
    point with a known name.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    char **LoaderlistDirs(const char **subdirlist,
 | 
						|
                          const char **patternlist);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This function returns a <constant>NULL</constant> terminated list of
 | 
						|
    canonical modules names for modules found in the default module
 | 
						|
    search path.  The <parameter>subdirlist</parameter> and
 | 
						|
    <parameter>patternlist</parameter> 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 <constant>NULL</constant>.
 | 
						|
    The returned list should be freed by calling
 | 
						|
    <function>LoaderFreeDirList()</function> when it is no longer needed.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void LoaderFreeDirList(char **list);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This function frees a module list created by
 | 
						|
    <function>LoaderlistDirs()</function>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void LoaderReqSymLists(const char **list0, ...);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This function allows the registration of required symbols with the
 | 
						|
    loader.  It is normally used by a caller of
 | 
						|
    <function>LoadSubModule()</function>.  If any symbols registered in this
 | 
						|
    way are found to be unresolved when
 | 
						|
    <function>LoaderCheckUnresolved()</function> is called then
 | 
						|
    <function>LoaderCheckUnresolved()</function> will report a failure.
 | 
						|
    The function takes one or more <constant>NULL</constant> terminated
 | 
						|
    lists of symbols.  The end of the argument list is indicated by a
 | 
						|
    <constant>NULL</constant> argument.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void LoaderReqSymbols(const char *sym0, ...);
 | 
						|
	  </programlisting>
 | 
						|
	<blockquote><para>
 | 
						|
    This function is like <function>LoaderReqSymLists()</function> 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 <constant>NULL</constant>
 | 
						|
    argument.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void LoaderRefSymLists(const char **list0, ...);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This function allows the registration of possibly unresolved symbols
 | 
						|
    with the loader.  When <function>LoaderCheckUnresolved()</function> 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 <constant>NULL</constant> terminated
 | 
						|
    lists of symbols.  The end of the argument list is indicated by a
 | 
						|
    <constant>NULL</constant> argument.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void LoaderRefSymbols(const char *sym0, ...);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This function is like <function>LoaderRefSymLists()</function> 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 <constant>NULL</constant>
 | 
						|
    argument.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    int LoaderCheckUnresolved(int delayflag);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This function checks for unresolved symbols.  It generates warnings
 | 
						|
    for unresolved symbols that have not been registered with
 | 
						|
    <function>LoaderRefSymLists()</function>, and maps them to a dummy
 | 
						|
    function.  This behaviour may change in future.  If unresolved
 | 
						|
    symbols are found that have been registered with
 | 
						|
    <function>LoaderReqSymLists()</function> or
 | 
						|
    <function>LoaderReqSymbols()</function> then this function returns a
 | 
						|
    non-zero value.  If none of these symbols are unresolved the return
 | 
						|
    value is zero, indicating success.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
    The <parameter>delayflag</parameter> parameter should normally be set to
 | 
						|
    <constant>LD_RESOLV_IFDONE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    LoaderErrorMsg(const char *name, const char *modname,
 | 
						|
                   int errmaj, int errmin);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This function prints an error message that includes the text <quote>Failed
 | 
						|
    to load module</quote>, the module name <parameter>modname</parameter>, a message
 | 
						|
    specific to the <parameter>errmaj</parameter> value, and the value if
 | 
						|
    <parameter>errmin</parameter>.  If <parameter>name</parameter> is
 | 
						|
    non-<constant>NULL</constant>, it is printed as an identifying prefix
 | 
						|
    to the message (followed by a <quote>:</quote>).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Special Registration Functions</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
The loader contains some functions for registering some classes of modules.
 | 
						|
These may be moved out of the loader at some point.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void LoadExtensionList(const ExtensionModule ext[], int size, Bool builtin);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
    This registers the entry points for the extension array identified by
 | 
						|
    <parameter>ext</parameter>.  The <structname>ExtensionModule</structname> struct is
 | 
						|
    defined as:
 | 
						|
 | 
						|
	      <programlisting>
 | 
						|
typedef struct {
 | 
						|
    InitExtension       initFunc;
 | 
						|
    char *              name;
 | 
						|
    Bool                *disablePtr;
 | 
						|
} ExtensionModule;
 | 
						|
	      </programlisting>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>Helper Functions</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
This section describe <quote>helper</quote> functions that video driver
 | 
						|
might find useful.  While video drivers are not required to use any of
 | 
						|
these to be considered <quote>compliant</quote>, the use of appropriate helpers is
 | 
						|
strongly encouraged to improve the consistency of driver behaviour.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Functions for printing messages</title>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    ErrorF(const char *format, ...);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    FatalError(const char *format, ...);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    xf86ErrorF(const char *format, ...);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This is like <function>ErrorF()</function>, except that the message is
 | 
						|
      only printed when the Xserver's verbosity level is set to the
 | 
						|
      default (<constant>1</constant>) or higher.  It means that the messages
 | 
						|
      are not printed when the server is started with the
 | 
						|
      <option>-quiet</option> flag.  Typically this function would only be
 | 
						|
      used for continuing messages started with one of the more specialised
 | 
						|
      functions described below.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    xf86ErrorFVerb(int verb, const char *format, ...);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Like <function>xf86ErrorF()</function>, except the minimum verbosity
 | 
						|
      level for which the message is to be printed is given explicitly.
 | 
						|
      Passing a <parameter>verb</parameter> value of zero means the message
 | 
						|
      is always printed.  A value higher than <constant>1</constant> can be
 | 
						|
      used for information would normally not be needed, but which might
 | 
						|
      be useful when diagnosing problems.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    xf86Msg(MessageType type, const char *format, ...);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This is like <function>xf86ErrorF()</function>, except that the message
 | 
						|
      is prefixed with a marker determined by the value of
 | 
						|
      <parameter>type</parameter>.  The marker is used to indicate the type of
 | 
						|
      message (warning, error, probed value, config value, etc).  Note
 | 
						|
      the <varname>xf86Verbose</varname> value is ignored for messages of
 | 
						|
      type <constant>X_ERROR</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The marker values are:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>X_PROBED</constant></term>
 | 
						|
		  <listitem><para>Value was probed.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>X_CONFIG</constant></term>
 | 
						|
		  <listitem><para>Value was given in the config file.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>X_DEFAULT</constant></term>
 | 
						|
		  <listitem><para>Value is a default.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>X_CMDLINE</constant></term>
 | 
						|
		  <listitem><para>Value was given on the command line.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>X_NOTICE</constant></term>
 | 
						|
		  <listitem><para>Notice.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>X_ERROR</constant></term>
 | 
						|
		  <listitem><para>Error message.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>X_WARNING</constant></term>
 | 
						|
		  <listitem><para>Warning message.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>X_INFO</constant></term>
 | 
						|
		  <listitem><para>Informational message.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>X_NONE</constant></term>
 | 
						|
		  <listitem><para>No prefix.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>X_NOT_IMPLEMENTED</constant></term>
 | 
						|
		  <listitem><para>The message relates to functionality
 | 
						|
		      that is not yetimplemented.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		</variablelist>
 | 
						|
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This is like <function>xf86Msg()</function> except that the driver's
 | 
						|
      name (the <structfield>name</structfield> field of the
 | 
						|
      <structname>ScrnInfoRec</structname>) followed by the
 | 
						|
      <parameter>scrnIndex</parameter> 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
 | 
						|
      <parameter>scrnIndex</parameter> is negative, this function behaves
 | 
						|
      exactly like <function>xf86Msg()</function>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      NOTE: This function can only be used after the
 | 
						|
      <structname>ScrnInfoRec</structname> and its <structfield>name</structfield> field
 | 
						|
      have been allocated.  Normally, this means that it can not be
 | 
						|
      used before the END of the <function>ChipProbe()</function> function.
 | 
						|
      Prior to that, use <function>xf86Msg()</function>, providing the
 | 
						|
      driver's name explicitly.  No screen number can be supplied at
 | 
						|
      that point.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
 | 
						|
                                const char *format, ...);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Like <function>xf86DrvMsg()</function>, but with the verbosity level
 | 
						|
      given explicitly.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Functions for setting values based on command line and config file</title>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp,
 | 
						|
 | 
						|
                                int fbbpp, int depth24flags);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function sets the <structfield>depth</structfield>, <structfield>pixmapBPP</structfield> and <structfield>bitsPerPixel</structfield> fields
 | 
						|
      of the <structname>ScrnInfoRec</structname>.  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
 | 
						|
      <function>ChipPreInit()</function> function.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      It requires that the <structfield>confScreen</structfield> field of the <structname>ScrnInfoRec</structname> be
 | 
						|
      initialised prior to calling it.  This is done by the XFree86
 | 
						|
      common layer prior to calling <function>ChipPreInit()</function>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The parameters passed are:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>depth</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		driver's preferred default depth if no other is given.
 | 
						|
                If zero, use the overall server default.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>bpp</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		Same, but for the pixmap bpp.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>fbbpp</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		Same, but for the framebuffer bpp.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>depth24flags</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		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:
 | 
						|
 | 
						|
		      <variablelist>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>NoDepth24Support</constant></term>
 | 
						|
			  <listitem><para>No depth 24 formats supported
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>Support24bppFb</constant></term>
 | 
						|
			  <listitem><para>24bpp framebuffer supported
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>Support32bppFb</constant></term>
 | 
						|
			  <listitem><para>32bpp framebuffer supported
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>SupportConvert24to32</constant></term>
 | 
						|
			  <listitem><para>Can convert 24bpp pixmap to 32bpp fb
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>SupportConvert32to24</constant></term>
 | 
						|
			  <listitem><para>Can convert 32bpp pixmap to 24bpp fb
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>ForceConvert24to32</constant></term>
 | 
						|
			  <listitem><para>Force 24bpp pixmap to 32bpp fb conversion
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>ForceConvert32to24</constant></term>
 | 
						|
			  <listitem><para>Force 32bpp pixmap to 24bpp fb conversion
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
		      </variablelist>
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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 <function>ChipPreInit()</function> function should
 | 
						|
      return <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      If only one of depth/bpp is given, the other is set to a reasonable
 | 
						|
      (and consistent) default.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      If a driver finds that the initial <parameter>depth24flags</parameter>
 | 
						|
      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 <parameter>depth24flags</parameter> setting.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      On success, the return value is <constant>TRUE</constant>.  On failure
 | 
						|
      it prints an error message and returns <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The following fields of the <structname>ScrnInfoRec</structname> are
 | 
						|
      initialised by this function:
 | 
						|
 | 
						|
	      <blockquote><para>
 | 
						|
<structfield>depth</structfield>, <structfield>bitsPerPixel</structfield>,
 | 
						|
<structfield>display</structfield>, <structfield>imageByteOrder</structfield>,
 | 
						|
<structfield>bitmapScanlinePad</structfield>,
 | 
						|
<structfield>bitmapScanlineUnit</structfield>, <structfield>bitmapBitOrder</structfield>,
 | 
						|
<structfield>numFormats</structfield>, <structfield>formats</structfield>,
 | 
						|
<structfield>fbFormat</structfield>.
 | 
						|
		</para></blockquote>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86PrintDepthBpp(scrnInfoPtr scrp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function can be used to print out the depth and bpp settings.
 | 
						|
      It should be called after the final call to
 | 
						|
      <function>xf86SetDepthBpp()</function>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function sets the <structfield>weight</structfield>, <structfield>mask</structfield>,
 | 
						|
      <structfield>offset</structfield> and <structfield>rgbBits</structfield> fields of the
 | 
						|
      <structname>ScrnInfoRec</structname>.  It would normally be called fairly
 | 
						|
      early in the <function>ChipPreInit()</function> function for
 | 
						|
      depths > 8bpp.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      It requires that the <structfield>depth</structfield> and
 | 
						|
      <structfield>display</structfield> fields of the <structname>ScrnInfoRec</structname>
 | 
						|
      be initialised prior to calling it.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The parameters passed are:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>weight</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		driver's preferred default weight if no other is given.
 | 
						|
                If zero, use the overall server default.
 | 
						|
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>mask</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		Same, but for mask.
 | 
						|
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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 <function>ChipPreInit()</function> function should
 | 
						|
      return <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      On success, this function prints a message showing the weight
 | 
						|
      values selected, and returns <constant>TRUE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      On failure it prints an error message and returns <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The following fields of the <structname>ScrnInfoRec</structname> are
 | 
						|
      initialised by this function:
 | 
						|
 | 
						|
	      <blockquote><para>
 | 
						|
		  <structfield>weight</structfield>,
 | 
						|
		  <structfield>mask</structfield>,
 | 
						|
		  <structfield>offset</structfield>.
 | 
						|
		</para></blockquote>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function sets the <structfield>defaultVisual</structfield> field of the
 | 
						|
      <structname>ScrnInfoRec</structname>.  It would normally be called fairly
 | 
						|
      early from the <function>ChipPreInit()</function> function.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      It requires that the <structfield>depth</structfield> and
 | 
						|
      <structfield>display</structfield> fields of the <structname>ScrnInfoRec</structname>
 | 
						|
      be initialised prior to calling it.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The parameters passed are:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>visual</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		driver's preferred default visual if no other is given.
 | 
						|
		If <constant>-1</constant>, use the overall server default.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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 <function>ChipPreInit()</function> function should
 | 
						|
      return <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      On success, this function prints a message showing the default visual
 | 
						|
      selected, and returns <constant>TRUE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      On failure it prints an error message and returns <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function sets the <structfield>gamma</structfield> field of the
 | 
						|
      <structname>ScrnInfoRec</structname>.  It would normally be called fairly
 | 
						|
      early from the <function>ChipPreInit()</function> function in cases
 | 
						|
      where the driver supports gamma correction.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      It requires that the <structfield>monitor</structfield> field of the
 | 
						|
      <structname>ScrnInfoRec</structname> be initialised prior to calling it.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The parameters passed are:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>gamma</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		driver's preferred default gamma if no other is given.
 | 
						|
		If zero (<code>< 0.01</code>), use the overall server
 | 
						|
		default.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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 <function>ChipPreInit()</function> function should
 | 
						|
      return <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      On success, this function prints a message showing the gamma
 | 
						|
      value selected, and returns <constant>TRUE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      On failure it prints an error message and returns <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function sets the <structfield>xDpi</structfield> and <structfield>yDpi</structfield>
 | 
						|
      fields of the <structname>ScrnInfoRec</structname>.  The driver can specify
 | 
						|
      preferred defaults by setting <parameter>x</parameter> and <parameter>y</parameter>
 | 
						|
      to non-zero values.  The <option>-dpi</option> command line option
 | 
						|
      overrides all other settings.  Otherwise, if the
 | 
						|
      <emphasis>DisplaySize</emphasis> 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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86SetBlackWhitePixels(ScrnInfoPtr pScrn);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This functions sets the <structfield>blackPixel</structfield> and
 | 
						|
      <structfield>whitePixel</structfield> fields of the <structname>ScrnInfoRec</structname>
 | 
						|
      according to whether or not the <option>-flipPixels</option> command
 | 
						|
      line options is present.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    const char *xf86GetVisualName(int visual);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      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, <constant>NULL</constant> is returned.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Primary Mode functions</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
 | 
						|
                          char **modeNames, ClockRangePtr clockRanges,
 | 
						|
                          int *linePitches, int minPitch, int maxPitch,
 | 
						|
                          int pitchInc, int minHeight, int maxHeight,
 | 
						|
                          int virtualX, int virtualY,
 | 
						|
                          unsigned long apertureSize,
 | 
						|
                          LookupModeFlags strategy);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      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 <function>ChipPreInit()</function> function.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The parameters passed to the function are:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>availModes</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		List of modes available for the monitor.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>modeNames</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		List of mode names that the screen is requesting.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>clockRanges</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		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
 | 
						|
		<parameter>clockRanges</parameter>.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>linePitches</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		List of line pitches supported by the driver.
 | 
						|
		This is optional and should be <constant>NULL</constant> when
 | 
						|
		not used.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>minPitch</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		Minimum line pitch supported by the driver.  This must
 | 
						|
		be supplied when <parameter>linePitches</parameter> is
 | 
						|
		<constant>NULL</constant>, and is ignored otherwise.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>maxPitch</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		Maximum line pitch supported by the driver.  This is
 | 
						|
		required when <parameter>minPitch</parameter> is required.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>pitchInc</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		Granularity of horizontal pitch values as supported by
 | 
						|
		the chipset.  This is expressed in bits.  This must be
 | 
						|
		supplied.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>minHeight</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		minimum virtual height allowed.  If zero, no limit is
 | 
						|
		imposed.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>maxHeight</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		maximum virtual height allowed.  If zero, no limit is
 | 
						|
		imposed.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>virtualX</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		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.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>virtualY</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		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.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>apertureSize</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		The size (in bytes) of the aperture used to access video
 | 
						|
		memory.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><parameter>strategy</parameter></term>
 | 
						|
		  <listitem><para>
 | 
						|
		The strategy to use when choosing from multiple modes
 | 
						|
		with the same name.  The options are:
 | 
						|
 | 
						|
		      <variablelist>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>LOOKUP_DEFAULT</constant></term>
 | 
						|
			  <listitem><para>???
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>LOOKUP_BEST_REFRESH</constant></term>
 | 
						|
			  <listitem><para>mode with best refresh rate
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>LOOKUP_CLOSEST_CLOCK</constant></term>
 | 
						|
			  <listitem><para>mode with closest matching clock
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>LOOKUP_LIST_ORDER</constant></term>
 | 
						|
			  <listitem><para>first usable mode in list
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
		      </variablelist>
 | 
						|
 | 
						|
		The following options can also be combined (OR'ed) with
 | 
						|
		one of the above:
 | 
						|
 | 
						|
		      <variablelist>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>LOOKUP_CLKDIV2</constant></term>
 | 
						|
			  <listitem><para>Allow halved clocks
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
			<varlistentry>
 | 
						|
			  <term><constant>LOOKUP_OPTIONAL_TOLERANCES</constant></term>
 | 
						|
			  <listitem><para>
 | 
						|
		      Allow missing horizontal sync and/or vertical refresh
 | 
						|
		      ranges in the xorg.conf Monitor section
 | 
						|
			    </para></listitem></varlistentry>
 | 
						|
		      </variablelist>
 | 
						|
 | 
						|
		<constant>LOOKUP_OPTIONAL_TOLERANCES</constant> 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).
 | 
						|
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      This function requires that the following fields of the
 | 
						|
      <structname>ScrnInfoRec</structname> are initialised prior to calling it:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>clock[]</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		      List of discrete clocks (when non-programmable)
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>numClocks</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		      Number of discrete clocks (when non-programmable)
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>progClock</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		      Whether the clock is programmable or not
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>monitor</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		      Pointer to the applicable xorg.conf monitor section
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>fdFormat</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		      Format of the screen buffer
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>videoRam</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		      total video memory size (in bytes)
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>xInc</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		      Horizontal timing increment in pixels (defaults to 8)
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      This function fills in the following <structname>ScrnInfoRec</structname>
 | 
						|
      fields:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>modePool</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		A subset of the modes available to the monitor which
 | 
						|
                are compatible with the driver.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>modes</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		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.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>virtualX</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		The resulting virtual width.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>virtualY</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		The resulting virtual height.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>displayWidth</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		The resulting line pitch.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The first stage of this function checks that the
 | 
						|
      <parameter>virtualX</parameter> and <parameter>virtualY</parameter> values
 | 
						|
      supplied (if greater than zero) are consistent with the line pitch
 | 
						|
      and <parameter>maxHeight</parameter> limitations.  If not, an error
 | 
						|
      message is printed, and the return value is <constant>-1</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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 <constant>2</constant>.  If the mode pool ends up being empty,
 | 
						|
      a warning message is printed, and the return value is
 | 
						|
      <constant>0</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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 <constant>-1</constant>.  Otherwise,
 | 
						|
      the return value is the number of valid modes found
 | 
						|
      (<constant>0</constant> if none are found).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      If this function returns <constant>-1</constant>, the
 | 
						|
      <function>ChipPreInit()</function> function should return
 | 
						|
      <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      <parameter>clockRanges</parameter> is a linked list of clock ranges
 | 
						|
      allowed by the driver.  If a mode doesn't fit in any of the defined
 | 
						|
      <parameter>clockRanges</parameter>, it is rejected.  The first
 | 
						|
      <literal remap="tt">clockRange</literal> that matches all requirements is used.
 | 
						|
      This structure needs to be initialized to NULL when allocated.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      <parameter>clockRanges</parameter> contains the following fields:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>minClock</structfield></term>
 | 
						|
		  <term><structfield>maxClock</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		The lower and upper mode clock bounds for which the rest
 | 
						|
		of the <structname>clockRange</structname> parameters apply.
 | 
						|
		Since these are the mode clocks, they are not scaled
 | 
						|
		with the <structfield>ClockMulFactor</structfield> and
 | 
						|
		<structfield>ClockDivFactor</structfield>.  It is up to the driver
 | 
						|
		to adjust these values if they depend on the clock
 | 
						|
		scaling factors.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>clockIndex</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		(not used yet) <constant>-1</constant> for programmable clocks
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>interlaceAllowed</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		<constant>TRUE</constant> if interlacing is allowed for this
 | 
						|
		range
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>doubleScanAllowed</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		<constant>TRUE</constant> if doublescan or multiscan is allowed
 | 
						|
		for this range
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>ClockMulFactor</structfield></term>
 | 
						|
		  <term><structfield>ClockDivFactor</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		Scaling factors that are applied to the mode clocks ONLY
 | 
						|
		before selecting a clock index (when there is no
 | 
						|
		programmable clock) or a <structfield>SynthClock</structfield>
 | 
						|
		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).
 | 
						|
		    </para>
 | 
						|
 | 
						|
		    <para>
 | 
						|
		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 <literal remap="tt">2:1</literal> 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, <code>ClockMulFactor=1</code> and
 | 
						|
		<code>ClockDivFactor=2</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 <structfield>SynthClock</structfield> field in case of
 | 
						|
		a programmable clock is:  (<code>mode->Clock *
 | 
						|
		ClockMulFactor) / ClockDivFactor</code>.
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>PrivFlags</structfield></term>
 | 
						|
		  <listitem><para>
 | 
						|
		This field is copied into the
 | 
						|
		<literal remap="tt">mode->PrivFlags</literal> field when this
 | 
						|
		<literal remap="tt">clockRange</literal> is selected by
 | 
						|
		<function>xf86ValidateModes()</function>.  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 <literal remap="tt">INT</literal>).
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      Note that the <structfield>mode->SynthClock</structfield> field is always
 | 
						|
      filled in by <function>xf86ValidateModes()</function>: it will contain
 | 
						|
      the <quote>data transport clock</quote>, 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:
 | 
						|
 | 
						|
	      <programlisting>
 | 
						|
    mode->SynthClock = (mode->Clock * ClockMulFactor) / ClockDivFactor
 | 
						|
	      </programlisting>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86PruneDriverModes(ScrnInfoPtr scrp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function deletes modes in the modes field of the
 | 
						|
      <structname>ScrnInfoRec</structname> that have been marked as invalid.
 | 
						|
      This is normally run after having run
 | 
						|
      <function>xf86ValidateModes()</function> for the last time.  For each
 | 
						|
      mode that is deleted, a warning message is printed out indicating
 | 
						|
      the reason for it being deleted.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function fills in the <structname>Crtc*</structname> fields for all
 | 
						|
      the modes in the <structfield>modes</structfield> field of the
 | 
						|
      <structname>ScrnInfoRec</structname>.  The <parameter>adjustFlags</parameter>
 | 
						|
      parameter determines how the vertical CRTC values are scaled for
 | 
						|
      interlaced modes.  They are halved if it is
 | 
						|
      <constant>INTERLACE_HALVE_V</constant>.  The vertical CRTC values are
 | 
						|
      doubled for doublescan modes, and are further multiplied by the
 | 
						|
      <literal remap="tt">VScan</literal> value.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      This function is normally called after calling
 | 
						|
      <function>xf86PruneDriverModes()</function>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86PrintModes(ScrnInfoPtr scrp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      This function is normally called after calling
 | 
						|
      <function>xf86SetCrtcForModes()</function>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Secondary Mode functions</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
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.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    const char *xf86ModeStatusToString(ModeStatus status);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function converts the <parameter>status</parameter> value to a
 | 
						|
      descriptive printable string.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function deletes the <parameter>mode</parameter> given from the
 | 
						|
      <parameter>modeList</parameter>.  It never prints any messages, so it is
 | 
						|
      up to the caller to print a message if required.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Functions for handling strings and tokens</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    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:
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
typedef struct {
 | 
						|
    int                 token;
 | 
						|
    const char *        name;
 | 
						|
} SymTabRec, *SymTabPtr;
 | 
						|
	</programlisting>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
    A table is an initialised array of <structname>SymTabRec</structname>.  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
 | 
						|
    <structfield>token</structfield> value of <constant>-1</constant> and
 | 
						|
    <constant>NULL</constant> for the <structfield>name</structfield>.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    const char *xf86TokenToString(SymTabPtr table, int token);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function returns the first string in <parameter>table</parameter>
 | 
						|
      that matches <parameter>token</parameter>.  If no match is found,
 | 
						|
      <constant>NULL</constant> is returned (NOTE, older versions of this
 | 
						|
      function would return the string "unknown" when no match is found).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    int xf86StringToToken(SymTabPtr table, const char *string);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function returns the first token in <parameter>table</parameter>
 | 
						|
      that matches <parameter>string</parameter>.  The
 | 
						|
      <function>xf86NameCmp()</function> function is used to determine the
 | 
						|
      match.  If no match is found, <constant>-1</constant> is returned.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Functions for finding which config file entries to use</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    These functions can be used to select the appropriate config file
 | 
						|
    entries that match the detected hardware.  They are described above
 | 
						|
    in the <link linkend="probe">Probe</link> and
 | 
						|
    <link linkend="avail">Available Functions</link> sections.
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Probing discrete clocks on old hardware</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The <function>xf86GetClocks()</function> function may be used to assist
 | 
						|
    in finding the discrete pixel clock values on older hardware.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86GetClocks(ScrnInfoPtr pScrn, int num,
 | 
						|
                       Bool (*ClockFunc)(ScrnInfoPtr, int),
 | 
						|
                       void (*ProtectRegs)(ScrnInfoPtr, Bool),
 | 
						|
                       void (*BlankScreen)(ScrnInfoPtr, Bool),
 | 
						|
                       int vertsyncreg, int maskval, int knownclkindex,
 | 
						|
                       int knownclkvalue);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function uses a comparative sampling method to measure the
 | 
						|
      discrete pixel clock values.  The number of discrete clocks to
 | 
						|
      measure is given by <parameter>num</parameter>.  <parameter>clockFunc</parameter>
 | 
						|
      is a function that selects the <parameter>n</parameter>'th clock.  It
 | 
						|
      should also save or restore any state affected by programming the
 | 
						|
      clocks when the index passed is <constant>CLK_REG_SAVE</constant> or
 | 
						|
      <constant>CLK_REG_RESTORE</constant>.  <parameter>ProtectRegs</parameter> is
 | 
						|
      a function that does whatever is required to protect the hardware
 | 
						|
      state while selecting a new clock.  <parameter>BlankScreen</parameter>
 | 
						|
      is a function that blanks the screen.  <parameter>vertsyncreg</parameter>
 | 
						|
      and <parameter>maskval</parameter> are the register and bitmask to
 | 
						|
      check for the presence of vertical sync pulses.
 | 
						|
      <parameter>knownclkindex</parameter> and <parameter>knownclkvalue</parameter>
 | 
						|
      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 <structfield>pScrn->numClocks</structfield>,
 | 
						|
      and the probed clocks are set in the <structfield>pScrn->clock[]</structfield>
 | 
						|
      array.  All of the clock values are in units of kHz.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Print out the pixel clocks <parameter>scrp->clock[]</parameter>.
 | 
						|
      <parameter>from</parameter> indicates whether the clocks were probed
 | 
						|
      or from the config file.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Other helper functions</title>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool xf86IsUnblank(int mode);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Returns <constant>TRUE</constant> when the screen saver mode specified
 | 
						|
      by <parameter>mode</parameter> requires the screen be unblanked,
 | 
						|
      and <constant>FALSE</constant> otherwise.  The screen saver modes that
 | 
						|
      require blanking are <constant>SCREEN_SAVER_ON</constant> and
 | 
						|
      <constant>SCREEN_SAVER_CYCLE</constant>, and the screen saver modes that
 | 
						|
      require unblanking are <constant>SCREEN_SAVER_OFF</constant> and
 | 
						|
      <constant>SCREEN_SAVER_FORCER</constant>.  Drivers may call this helper
 | 
						|
      from their <function>SaveScreen()</function> function to interpret the
 | 
						|
      screen saver modes.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </sect2>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1>
 | 
						|
    <title>The vgahw module</title>
 | 
						|
 | 
						|
    <para>
 | 
						|
The vgahw modules provides an interface for saving, restoring and
 | 
						|
programming the standard VGA registers, and for handling VGA colourmaps.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Data Structures</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The public data structures used by the vgahw module are
 | 
						|
    <structname>vgaRegRec</structname> and <structname>vgaHWRec</structname>.  They are
 | 
						|
    defined in <filename>vgaHW.h.</filename>
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>General vgahw Functions</title>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool vgaHWGetHWRec(ScrnInfoPtr pScrn);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function allocates a <structname>vgaHWRec</structname> structure, and
 | 
						|
      hooks it into the <structname>ScrnInfoRec</structname>'s
 | 
						|
      <structfield>privates</structfield>.  Like all information hooked into the
 | 
						|
      <structfield>privates</structfield>, it is persistent, and only needs to be
 | 
						|
      allocated once per screen.  This function should normally be called
 | 
						|
      from the driver's <function>ChipPreInit()</function> function.  The
 | 
						|
      <structname>vgaHWRec</structname> is zero-allocated, and the following
 | 
						|
      fields are explicitly initialised:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>ModeReg.DAC[]</structfield></term>
 | 
						|
		  <listitem><para>initialised with a default colourmap
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>ModeReg.Attribute[0x11]</structfield></term>
 | 
						|
		  <listitem><para>initialised with the default overscan index
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>ShowOverscan</structfield></term>
 | 
						|
		  <listitem><para>initialised according to the "ShowOverscan" option
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>paletteEnabled</structfield></term>
 | 
						|
		  <listitem><para>initialised to FALSE
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>cmapSaved</structfield></term>
 | 
						|
		  <listitem><para>initialised to FALSE
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><structfield>pScrn</structfield></term>
 | 
						|
		  <listitem><para>initialised to pScrn
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      In addition to the above, <function>vgaHWSetStdFuncs()</function> is
 | 
						|
      called to initialise the register access function fields with the
 | 
						|
      standard VGA set of functions.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      Once allocated, a pointer to the <structname>vgaHWRec</structname> can be
 | 
						|
      obtained from the <literal remap="tt">ScrnInfoPtr</literal> with the
 | 
						|
      <literal remap="tt">VGAHWPTR(pScrn)</literal> macro.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWFreeHWRec(ScrnInfoPtr pScrn);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function frees a <structname>vgaHWRec</structname> structure.  It
 | 
						|
      should be called from a driver's <function>ChipFreeScreen()</function>
 | 
						|
      function.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function copies the contents of the VGA saved registers in
 | 
						|
      <parameter>src</parameter> to <parameter>dst</parameter>.  Note that it isn't
 | 
						|
      possible to simply do this with <function>memcpy()</function> (or
 | 
						|
      similar).  This function returns <constant>TRUE</constant> unless there
 | 
						|
      is a problem allocating space for the <structfield>CRTC</structfield> and
 | 
						|
      related fields in <parameter>dst</parameter>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWSetStdFuncs(vgaHWPtr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function initialises the register access function fields of
 | 
						|
      <parameter>hwp</parameter> with the standard VGA set of functions.  This
 | 
						|
      is called by <function>vgaHWGetHWRec()</function>, 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
 | 
						|
      <structfield>hwp->PIOOffset</structfield> is initialised with
 | 
						|
      <literal remap="tt">offset</literal>, 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
 | 
						|
      <function>vgaHWGetHWRec()</function>.  (Note: the PIOOffset functionality
 | 
						|
      is present in XFree86 4.1.0 and later.)
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function initialised the register access function fields of
 | 
						|
      hwp with a generic MMIO set of functions.
 | 
						|
      <structfield>hwp->MMIOBase</structfield> is initialised with
 | 
						|
      <parameter>base</parameter>, which must be the virtual address that the
 | 
						|
      start of MMIO area is mapped to.  <structfield>hwp->MMIOOffset</structfield>
 | 
						|
      is initialised with <parameter>offset</parameter>, 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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool vgaHWMapMem(ScrnInfoPtr pScrn);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function maps the VGA memory window.  It requires that the
 | 
						|
      <structname>vgaHWRec</structname> be allocated.  If a driver requires
 | 
						|
      non-default <structfield>MapPhys</structfield> or <structfield>MapSize</structfield>
 | 
						|
      settings (the physical location and size of the VGA memory window)
 | 
						|
      then those fields of the <structname>vgaHWRec</structname> must be initialised
 | 
						|
      before calling this function.  Otherwise, this function initialiases
 | 
						|
      the default values of <constant>0xA0000</constant> for
 | 
						|
      <structfield>MapPhys</structfield> and <code>(64 * 1024)</code> for
 | 
						|
      <structfield>MapSize</structfield>.  This function must be called before
 | 
						|
      attempting to save or restore the VGA state.  If the driver doesn't
 | 
						|
      call it explicitly, the <function>vgaHWSave()</function> and
 | 
						|
      <function>vgaHWRestore()</function> functions may call it if they need
 | 
						|
      to access the VGA memory (in which case they will also call
 | 
						|
      <function>vgaHWUnmapMem()</function> to unmap the VGA memory before
 | 
						|
      exiting).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWUnmapMem(ScrnInfoPtr pScrn);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function unmaps the VGA memory window.  It must only be called
 | 
						|
      after the memory has been mapped.  The <structfield>Base</structfield> field
 | 
						|
      of the <structname>vgaHWRec</structname> field is set to <constant>NULL</constant>
 | 
						|
      to indicate that the memory is no longer mapped.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWGetIOBase(vgaHWPtr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function initialises the <structfield>IOBase</structfield> field of the
 | 
						|
      <structname>vgaHWRec</structname>.  This function must be called before
 | 
						|
      using any other functions that access the video hardware.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      A macro <function>VGAHW_GET_IOBASE()</function> is also available in
 | 
						|
      <filename>vgaHW.h</filename> that returns the I/O base, and this may
 | 
						|
      be used when the vgahw module is not loaded (for example, in the
 | 
						|
      <function>ChipProbe()</function> function).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWUnlock(vgaHWPtr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function unlocks the VGA <literal remap="tt">CRTC[0-7]</literal> registers,
 | 
						|
      and must be called before attempting to write to those registers.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWLock(vgaHWPtr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function locks the VGA <literal remap="tt">CRTC[0-7]</literal> registers.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWEnable(vgaHWPtr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function enables the VGA subsystem.  (Note, this function is
 | 
						|
      present in XFree86 4.1.0 and later.).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWSave(ScrnInfoPtr pScrn, vgaRegPtr save, int flags);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function saves the VGA state.  The state is written to the
 | 
						|
      <structname>vgaRegRec</structname> pointed to by <parameter>save</parameter>.
 | 
						|
      <parameter>flags</parameter> is set to one or more of the following flags
 | 
						|
      ORed together:
 | 
						|
 | 
						|
	      <variablelist>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>VGA_SR_MODE</constant></term>
 | 
						|
		  <listitem><para>the mode setting registers are saved
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>VGA_SR_FONTS</constant></term>
 | 
						|
		  <listitem><para>the text mode font/text data is saved
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>VGA_SR_CMAP</constant></term>
 | 
						|
		  <listitem><para>the colourmap (LUT) is saved
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
		<varlistentry>
 | 
						|
		  <term><constant>VGA_SR_ALL</constant></term>
 | 
						|
		  <listitem><para>all of the above are saved
 | 
						|
		    </para></listitem></varlistentry>
 | 
						|
	      </variablelist>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The <structname>vgaHWRec</structname> and its <structfield>IOBase</structfield> fields
 | 
						|
      must be initialised before this function is called.  If
 | 
						|
      <constant>VGA_SR_FONTS</constant> is set in <parameter>flags</parameter>, the
 | 
						|
      VGA memory window must be mapped.  If it isn't then
 | 
						|
      <function>vgaHWMapMem()</function> will be called to map it, and
 | 
						|
      <function>vgaHWUnmapMem()</function> will be called to unmap it
 | 
						|
      afterwards.  <function>vgaHWSave()</function> uses the three functions
 | 
						|
      below in the order <function>vgaHWSaveColormap()</function>,
 | 
						|
      <function>vgaHWSaveMode()</function>, <function>vgaHWSaveFonts()</function> 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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWSaveMode(ScrnInfoPtr pScrn, vgaRegPtr save);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function saves the VGA mode registers.  They are saved to
 | 
						|
      the <structname>vgaRegRec</structname> pointed to by <parameter>save</parameter>.
 | 
						|
      The registers saved are:
 | 
						|
 | 
						|
	      <literallayout>
 | 
						|
        MiscOut
 | 
						|
        CRTC[0-0x18]
 | 
						|
        Attribute[0-0x14]
 | 
						|
        Graphics[0-8]
 | 
						|
        Sequencer[0-4]
 | 
						|
	      </literallayout>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWSaveFonts(ScrnInfoPtr pScrn, vgaRegPtr save);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      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
 | 
						|
      <function>vgaHWMapMem()</function> before to calling this function.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWSaveColormap(ScrnInfoPtr pScrn, vgaRegPtr save);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWRestore(ScrnInfoPtr pScrn, vgaRegPtr restore, int flags);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function programs the VGA state.  The state programmed is
 | 
						|
      that contained in the <structname>vgaRegRec</structname> pointed to by
 | 
						|
      <parameter>restore</parameter>.  <parameter>flags</parameter> is the same
 | 
						|
      as described above for the <function>vgaHWSave()</function> function.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      The <structname>vgaHWRec</structname> and its <structfield>IOBase</structfield> fields
 | 
						|
      must be initialised before this function is called.  If
 | 
						|
      <constant>VGA_SR_FONTS</constant> is set in <parameter>flags</parameter>, the
 | 
						|
      VGA memory window must be mapped.  If it isn't then
 | 
						|
      <function>vgaHWMapMem()</function> will be called to map it, and
 | 
						|
      <function>vgaHWUnmapMem()</function> will be called to unmap it
 | 
						|
      afterwards.  <function>vgaHWRestore()</function> uses the three functions
 | 
						|
      below in the order <function>vgaHWRestoreFonts()</function>,
 | 
						|
      <function>vgaHWRestoreMode()</function>,
 | 
						|
      <function>vgaHWRestoreColormap()</function> 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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWRestoreMode(ScrnInfoPtr pScrn, vgaRegPtr restore);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function restores the VGA mode registers.  They are restored
 | 
						|
      from the data in the <structname>vgaRegRec</structname> pointed to by
 | 
						|
      <parameter>restore</parameter>.  The registers restored are:
 | 
						|
 | 
						|
	      <literallayout>
 | 
						|
        MiscOut
 | 
						|
        CRTC[0-0x18]
 | 
						|
        Attribute[0-0x14]
 | 
						|
        Graphics[0-8]
 | 
						|
        Sequencer[0-4]
 | 
						|
	      </literallayout>
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWRestoreFonts(ScrnInfoPtr pScrn, vgaRegPtr restore);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function restores the text mode font and text data to the
 | 
						|
      video memory.  The VGA memory window must be mapped with
 | 
						|
      <function>vgaHWMapMem()</function> before to calling this function.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	    <para>
 | 
						|
      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.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWRestoreColormap(ScrnInfoPtr pScrn, vgaRegPtr restore);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function restores the VGA colourmap (LUT).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function fills in the <structname>vgaHWRec</structname>'s
 | 
						|
      <structfield>ModeReg</structfield> field with the values appropriate for
 | 
						|
      programming the given video mode.  It requires that the
 | 
						|
      <structname>ScrnInfoRec</structname>'s <structfield>depth</structfield> field is
 | 
						|
      initialised, which determines how the registers are programmed.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWSeqReset(vgaHWPtr hwp, Bool start);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Do a VGA sequencer reset.  If start is <constant>TRUE</constant>, the
 | 
						|
      reset is started.  If start is <constant>FALSE</constant>, the reset
 | 
						|
      is ended.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWProtect(ScrnInfoPtr pScrn, Bool on);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function protects VGA registers and memory from corruption
 | 
						|
      during loads.  It is typically called with on set to
 | 
						|
      <constant>TRUE</constant> before programming, and with on set to
 | 
						|
      <constant>FALSE</constant> after programming.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool vgaHWSaveScreen(ScreenPtr pScreen, int mode);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function blanks and unblanks the screen.  It is blanked when
 | 
						|
      <parameter>mode</parameter> is <constant>SCREEN_SAVER_ON</constant> or
 | 
						|
      <constant>SCREEN_SAVER_CYCLE</constant>, and unblanked when
 | 
						|
      <parameter>mode</parameter> is <constant>SCREEN_SAVER_OFF</constant> or
 | 
						|
      <constant>SCREEN_SAVER_FORCER</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      This function blanks and unblanks the screen.  It is blanked when
 | 
						|
      <parameter>on</parameter> is <constant>FALSE</constant>, and unblanked when
 | 
						|
      <parameter>on</parameter> is <constant>TRUE</constant>.  This function is
 | 
						|
      provided for use in cases where the <structname>ScrnInfoRec</structname>
 | 
						|
      can't be derived from the <structname>ScreenRec</structname> (while probing
 | 
						|
      for clocks, for example).
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>VGA Colormap Functions</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The vgahw module uses the standard colormap support (see the
 | 
						|
    <link linkend="cmap">Colormap Handling</link> section.  This is initialised
 | 
						|
    with the following function:
 | 
						|
 | 
						|
	<blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    Bool vgaHWHandleColormaps(ScreenPtr pScreen);
 | 
						|
	    </programlisting>
 | 
						|
	  </para></blockquote>
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>VGA Register Access Functions</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
    The vgahw module abstracts access to the standard VGA registers by
 | 
						|
    using a set of functions held in the <structname>vgaHWRec</structname>.  When
 | 
						|
    the <structname>vgaHWRec</structname> 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 <structname>vgaHWRec</structname> function
 | 
						|
    pointers can be initialised to these by calling the
 | 
						|
    <function>vgaHWSetMmioFuncs()</function> function described above.  Some
 | 
						|
    drivers/platforms may require a different set of functions for VGA
 | 
						|
    access.  The access functions are described here.
 | 
						|
      </para>
 | 
						|
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void writeCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Write <parameter>value</parameter> to CRTC register <parameter>index</parameter>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    CARD8 readCrtc(vgaHWPtr hwp, CARD8 index);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Return the value read from CRTC register <parameter>index</parameter>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void writeGr(vgaHWPtr hwp, CARD8 index, CARD8 value);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Write <parameter>value</parameter> to Graphics Controller register
 | 
						|
      <parameter>index</parameter>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    CARD8 readGR(vgaHWPtr hwp, CARD8 index);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Return the value read from Graphics Controller register
 | 
						|
      <parameter>index</parameter>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void writeSeq(vgaHWPtr hwp, CARD8 index, CARD8, value);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Write <parameter>value</parameter> to Sequencer register
 | 
						|
      <parameter>index</parameter>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    CARD8 readSeq(vgaHWPtr hwp, CARD8 index);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Return the value read from Sequencer register <parameter>index</parameter>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void writeAttr(vgaHWPtr hwp, CARD8 index, CARD8, value);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Write <parameter>value</parameter> to Attribute Controller register
 | 
						|
      <parameter>index</parameter>.  When writing out the index value this
 | 
						|
      function should set bit 5 (<constant>0x20</constant>) according to the
 | 
						|
      setting of <structfield>hwp->paletteEnabled</structfield> in order to
 | 
						|
      preserve the palette access state.  It should be cleared when
 | 
						|
      <structfield>hwp->paletteEnabled</structfield> is <constant>TRUE</constant>
 | 
						|
      and set when it is <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    CARD8 readAttr(vgaHWPtr hwp, CARD8 index);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Return the value read from Attribute Controller register
 | 
						|
      <parameter>index</parameter>.  When writing out the index value this
 | 
						|
      function should set bit 5 (<constant>0x20</constant>) according to the
 | 
						|
      setting of <structfield>hwp->paletteEnabled</structfield> in order to
 | 
						|
      preserve the palette access state.  It should be cleared when
 | 
						|
      <structfield>hwp->paletteEnabled</structfield> is <constant>TRUE</constant>
 | 
						|
      and set when it is <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void writeMiscOut(vgaHWPtr hwp, CARD8 value);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Write <quote><parameter>value</parameter></quote> to the Miscellaneous Output register.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    CARD8 readMiscOut(vgwHWPtr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Return the value read from the Miscellaneous Output register.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void enablePalette(vgaHWPtr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Clear the palette address source bit in the Attribute Controller
 | 
						|
      index register and set <literal remap="tt">hwp->paletteEnabled</literal> to
 | 
						|
      <constant>TRUE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void disablePalette(vgaHWPtr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Set the palette address source bit in the Attribute Controller
 | 
						|
      index register and set <literal remap="tt">hwp->paletteEnabled</literal> to
 | 
						|
      <constant>FALSE</constant>.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void writeDacMask(vgaHWPtr hwp, CARD8 value);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Write <parameter>value</parameter> to the DAC Mask register.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    CARD8 readDacMask(vgaHWptr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Return the value read from the DAC Mask register.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void writeDacReadAddress(vgaHWPtr hwp, CARD8 value);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Write <parameter>value</parameter> to the DAC Read Address register.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void writeDacWriteAddress(vgaHWPtr hwp, CARD8 value);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Write <parameter>value</parameter> to the DAC Write Address register.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void writeDacData(vgaHWPtr hwp, CARD8 value);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Write <parameter>value</parameter> to the DAC Data register.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    CARD8 readDacData(vgaHWptr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Return the value read from the DAC Data register.
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    CARD8 readEnable(vgaHWptr hwp);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Return the value read from the VGA Enable register.  (Note: This
 | 
						|
      function is present in XFree86 4.1.0 and later.)
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
 | 
						|
      <blockquote><para>
 | 
						|
	  <programlisting>
 | 
						|
    void writeEnable(vgaHWPtr hwp, CARD8 value);
 | 
						|
	  </programlisting>
 | 
						|
	  <blockquote><para>
 | 
						|
      Write <parameter>value</parameter> to the VGA Enable register.  (Note: This
 | 
						|
      function is present in XFree86 4.1.0 and later.)
 | 
						|
	    </para>
 | 
						|
 | 
						|
	  </blockquote></para></blockquote>
 | 
						|
    </sect2>
 | 
						|
  </sect1>
 | 
						|
 | 
						|
  <sect1 id="sample">
 | 
						|
    <title>Some notes about writing a driver</title>
 | 
						|
 | 
						|
    <note><para>NOTE: some parts of this are not up to date</para></note>
 | 
						|
 | 
						|
    <para>
 | 
						|
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).
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
The information here is based on the initial conversion of the Matrox
 | 
						|
Millennium driver to the <quote>new design</quote>.  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.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <para>
 | 
						|
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 <quote>ZZZ</quote> driver, which uses the <quote>ZZZ</quote> or <quote>zzz</quote> prefix for its externally
 | 
						|
visible symbols.
 | 
						|
    </para>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Include files</title>
 | 
						|
 | 
						|
      <para>
 | 
						|
  All drivers normally include the following headers:
 | 
						|
	<literallayout><filename>
 | 
						|
    "xf86.h"
 | 
						|
    "xf86_OSproc.h"
 | 
						|
    "xf86_ansic.h"
 | 
						|
    "xf86Resources.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
  Wherever inb/outb (and related things) are used the following should be
 | 
						|
  included:
 | 
						|
	<literallayout><filename>
 | 
						|
    "compiler.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
  Note: in drivers, this must be included after <filename>"xf86_ansic.h"</filename>.
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  Drivers that need to access PCI vendor/device definitions need this:
 | 
						|
	<literallayout><filename>
 | 
						|
    "xf86PciInfo.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  Drivers that need to access the PCI config space need this:
 | 
						|
	<literallayout><filename>
 | 
						|
    "xf86Pci.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  Drivers using the mi banking wrapper need:
 | 
						|
 | 
						|
	<literallayout><filename>
 | 
						|
    "mibank.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  Drivers that initialise a SW cursor need this:
 | 
						|
	<literallayout><filename>
 | 
						|
    "mipointer.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  All drivers using the mi colourmap code need this:
 | 
						|
	<literallayout><filename>
 | 
						|
    "micmap.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  If a driver uses the vgahw module, it needs this:
 | 
						|
	<literallayout><filename>
 | 
						|
    "vgaHW.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  Drivers supporting VGA or Hercules monochrome screens need:
 | 
						|
	<literallayout><filename>
 | 
						|
    "xf1bpp.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  Drivers supporting VGA or EGC 16-colour screens need:
 | 
						|
	<literallayout><filename>
 | 
						|
    "xf4bpp.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  Drivers using cfb need:
 | 
						|
	<programlisting>
 | 
						|
    #define PSZ 8
 | 
						|
    #include "cfb.h"
 | 
						|
    #undef PSZ
 | 
						|
	</programlisting>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
 | 
						|
	<literallayout><filename>
 | 
						|
    "cfb16.h"
 | 
						|
    "cfb24.h"
 | 
						|
    "cfb32.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  The driver's own header file:
 | 
						|
	<literallayout><filename>
 | 
						|
    "zzz.h"
 | 
						|
	  </filename></literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
      <para>
 | 
						|
  Drivers must NOT include the following:
 | 
						|
 | 
						|
	<literallayout><filename>
 | 
						|
    "xf86Priv.h"
 | 
						|
    "xf86Privstr.h"
 | 
						|
    "xf86_libc.h"
 | 
						|
    "xf86_OSlib.h"
 | 
						|
    "Xos.h"</filename>
 | 
						|
    any OS header
 | 
						|
	</literallayout>
 | 
						|
      </para>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Data structures and initialisation</title>
 | 
						|
 | 
						|
      <itemizedlist>
 | 
						|
	<listitem>
 | 
						|
	  <para>The following macros should be defined:
 | 
						|
	    <programlisting>
 | 
						|
#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>
 | 
						|
	    </programlisting>
 | 
						|
	  </para>
 | 
						|
	  <para>
 | 
						|
    NOTE: <constant>ZZZ_DRIVER_NAME</constant> should match the name of the
 | 
						|
    driver module without things like the "lib" prefix, the "_drv" suffix
 | 
						|
    or filename extensions.
 | 
						|
	  </para>
 | 
						|
	</listitem>
 | 
						|
 | 
						|
	<listitem>
 | 
						|
	  <para>
 | 
						|
    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).
 | 
						|
	    <programlisting>
 | 
						|
DriverRec ZZZ = {
 | 
						|
    VERSION,
 | 
						|
    ZZZ_DRIVER_NAME,
 | 
						|
    ZZZIdentify,
 | 
						|
    ZZZProbe,
 | 
						|
    ZZZAvailableOptions,
 | 
						|
    NULL,
 | 
						|
    0
 | 
						|
};
 | 
						|
	    </programlisting>
 | 
						|
	  </para>
 | 
						|
	</listitem>
 | 
						|
 | 
						|
	<listitem>
 | 
						|
	  <para>Define list of supported chips and their matching ID:
 | 
						|
	    <programlisting>
 | 
						|
static SymTabRec ZZZChipsets[] = {
 | 
						|
    { PCI_CHIP_ZZZ1234, "zzz1234a" },
 | 
						|
    { PCI_CHIP_ZZZ5678, "zzz5678a" },
 | 
						|
    { -1,               NULL }
 | 
						|
};
 | 
						|
	    </programlisting>
 | 
						|
	  </para>
 | 
						|
	  <para>
 | 
						|
    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 <type>enum</type> type.
 | 
						|
	  </para>
 | 
						|
	</listitem>
 | 
						|
 | 
						|
	<listitem>
 | 
						|
	  <para>
 | 
						|
    If the driver uses the <function>xf86MatchPciInstances()</function>
 | 
						|
    helper (recommended for drivers that support PCI cards) a list that
 | 
						|
    maps PCI IDs to chip IDs and fixed resources must be defined:
 | 
						|
	    <programlisting>
 | 
						|
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 }
 | 
						|
}
 | 
						|
	    </programlisting>
 | 
						|
	  </para>
 | 
						|
	</listitem>
 | 
						|
 | 
						|
	<listitem>
 | 
						|
	  <para>
 | 
						|
    Define the <structname>XF86ModuleVersionInfo</structname> struct for the
 | 
						|
    driver.  This is required for the dynamically loaded version:
 | 
						|
	    <programlisting>
 | 
						|
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}
 | 
						|
};
 | 
						|
	    </programlisting>
 | 
						|
	  </para>
 | 
						|
	</listitem>
 | 
						|
 | 
						|
	<listitem>
 | 
						|
	  <para>
 | 
						|
    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 <filename>"zzz.h"</filename> file, something like:
 | 
						|
	    <programlisting>
 | 
						|
typedef struct {
 | 
						|
    type1  field1;
 | 
						|
    type2  field2;
 | 
						|
    int    fooHack;
 | 
						|
    Bool   pciRetry;
 | 
						|
    Bool   noAccel;
 | 
						|
    Bool   hwCursor;
 | 
						|
    CloseScreenProcPtr CloseScreen;
 | 
						|
    OptionInfoPtr Options;
 | 
						|
    ...
 | 
						|
} ZZZRec, *ZZZPtr;
 | 
						|
	    </programlisting>
 | 
						|
	  </para>
 | 
						|
	</listitem>
 | 
						|
 | 
						|
	<listitem>
 | 
						|
	  <para>
 | 
						|
    Define the list of config file Options that the driver accepts.  For
 | 
						|
    consistency between drivers those in the list of <quote>standard</quote> options
 | 
						|
    should be used where appropriate before inventing new options.
 | 
						|
 | 
						|
	    <programlisting>
 | 
						|
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 }
 | 
						|
};
 | 
						|
	    </programlisting>
 | 
						|
	  </para>
 | 
						|
	</listitem>
 | 
						|
      </itemizedlist>
 | 
						|
    </sect2>
 | 
						|
 | 
						|
    <sect2>
 | 
						|
      <title>Functions</title>
 | 
						|
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>SetupProc</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    For dynamically loaded modules, a <varname>ModuleData</varname>
 | 
						|
    variable is required.  It is should be the name of the driver
 | 
						|
    prepended to "ModuleData".  A <function>Setup()</function> function is
 | 
						|
    also required, which calls <function>xf86AddDriver()</function> to add
 | 
						|
    the driver to the main list of drivers.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
static MODULESETUPPROTO(zzzSetup);
 | 
						|
 | 
						|
XF86ModuleData zzzModuleData = { .vers = &zzzVersRec, .setup = zzzSetup, .teardown = 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;
 | 
						|
    }
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>GetRec, FreeRec</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    A function is usually required to allocate the driver's
 | 
						|
    screen-specific data structure and hook it into the
 | 
						|
    <structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield> field.
 | 
						|
    The <structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield> is
 | 
						|
    initialised to <constant>NULL</constant>, so it is easy to check if the
 | 
						|
    initialisation has already been done.  After allocating it, initialise
 | 
						|
    the fields.  By using <function>XNFcallocarray()</function> to do the allocation
 | 
						|
    it is zeroed, and if the allocation fails the server exits.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    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.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
static Bool
 | 
						|
ZZZGetRec(ScrnInfoPtr pScrn)
 | 
						|
{
 | 
						|
    if (pScrn->driverPrivate != NULL)
 | 
						|
        return TRUE;
 | 
						|
    pScrn->driverPrivate = XNFcallocarray(1, sizeof(ZZZRec));
 | 
						|
    /* Initialise as required */
 | 
						|
    ...
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define a macro in <filename>"zzz.h"</filename> which gets a pointer to
 | 
						|
    the <structname>ZZZRec</structname> when given <parameter>pScrn</parameter>:
 | 
						|
 | 
						|
	  <programlisting>
 | 
						|
#define ZZZPTR(p) ((ZZZPtr)((p)->driverPrivate))
 | 
						|
	  </programlisting>
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define a function to free the above, setting it to <constant>NULL</constant>
 | 
						|
    once it has been freed:
 | 
						|
 | 
						|
	  <programlisting>
 | 
						|
static void
 | 
						|
ZZZFreeRec(ScrnInfoPtr pScrn)
 | 
						|
{
 | 
						|
    if (pScrn->driverPrivate == NULL)
 | 
						|
        return;
 | 
						|
    xfree(pScrn->driverPrivate);
 | 
						|
    pScrn->driverPrivate = NULL;
 | 
						|
}
 | 
						|
	  </programlisting>
 | 
						|
	</para>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>Identify</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>Identify()</function> 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:
 | 
						|
 | 
						|
	  <programlisting>
 | 
						|
static void
 | 
						|
ZZZIdentify(int flags)
 | 
						|
{
 | 
						|
    xf86PrintChipsets(ZZZ_NAME, "driver for ZZZ Tech chipsets",
 | 
						|
                      ZZZChipsets);
 | 
						|
}
 | 
						|
	  </programlisting>
 | 
						|
	</para>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>Probe</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>Probe()</function> 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 <structname>ScrnInfoRec</structname>.  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 <structname>ScrnInfoRec</structname> initialisations.
 | 
						|
    Don't allocate any new data structures.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    This function is mandatory.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    NOTE: The <function>xf86DrvMsg()</function> functions cannot be used from
 | 
						|
    the Probe.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
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);
 | 
						|
    }
 | 
						|
 | 
						|
    xfree(devSections);
 | 
						|
    return foundScreen;
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>AvailableOptions</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>AvailableOptions()</function> 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.
 | 
						|
	</para>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>PreInit</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>PreInit()</function> 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
 | 
						|
    <structname>ScrnInfoRec</structname> that can be set once at the beginning
 | 
						|
    of the first server generation.  The information should be found in
 | 
						|
    the least intrusive way possible.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    This function is mandatory.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    NOTES:
 | 
						|
	  <orderedlist>
 | 
						|
	    <listitem><para>
 | 
						|
	 The <function>PreInit()</function> function is only called once
 | 
						|
	 during the life of the X server (at the start of the first
 | 
						|
	 generation).
 | 
						|
	      </para></listitem>
 | 
						|
 | 
						|
	    <listitem><para>
 | 
						|
	 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 <structname>ScrnInfoRec</structname>'s <structfield>privates</structfield>
 | 
						|
	 field should be allocated here, but data that hooks into the
 | 
						|
	 <structname>ScreenRec</structname>'s <structfield>devPrivates</structfield> field
 | 
						|
	 should not be allocated here.  The <structfield>driverPrivate</structfield>
 | 
						|
	 field should also be allocated here.
 | 
						|
	      </para></listitem>
 | 
						|
 | 
						|
	    <listitem><para>
 | 
						|
	 Although the <structname>ScrnInfoRec</structname> has been allocated
 | 
						|
	 before this function is called, the <structname>ScreenRec</structname>
 | 
						|
	 has not been allocated.  That means that things requiring it
 | 
						|
	 cannot be used in this function.
 | 
						|
	      </para></listitem>
 | 
						|
 | 
						|
	    <listitem><para>
 | 
						|
	 Very little of the <structname>ScrnInfoRec</structname> has been
 | 
						|
	 initialised when this function is called.  It is important to
 | 
						|
	 get the order of doing things right in this function.
 | 
						|
	      </para></listitem>
 | 
						|
 | 
						|
	  </orderedlist>
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
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;
 | 
						|
 | 
						|
 | 
						|
    /* Done */
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>MapMem, UnmapMem</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    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.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
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;
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>Save, Restore</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define functions to save and restore the original video state.  These
 | 
						|
    functions are not mandatory, but are often useful.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
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.
 | 
						|
     */
 | 
						|
    ...
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>ModeInit</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define a function to initialise a new video mode.  This function isn't
 | 
						|
    mandatory, but is often useful.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
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.
 | 
						|
     */
 | 
						|
    ...
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>ScreenInit</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>ScreenInit()</function> function.  This is called
 | 
						|
    at the start of each server generation, and should fill in as much
 | 
						|
    of the <structname>ScreenRec</structname> 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.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    This function is mandatory.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    NOTE: The <structname>ScreenRec</structname> (<parameter>pScreen</parameter>) is
 | 
						|
	  passed to this driver, but it and the
 | 
						|
	  <varname>ScrnInfoRecs</varname> are not yet hooked into each
 | 
						|
	  other.  This means that in this function, and functions it
 | 
						|
	  calls, one cannot be found from the other.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
static Bool
 | 
						|
ZZZScreenInit(ScreenPtr pScreen, int argc, char **argv)
 | 
						|
{
 | 
						|
    /* Get the ScrnInfoRec */
 | 
						|
    pScrn = xf86ScreenToScrn(pScreen);
 | 
						|
 | 
						|
    /*
 | 
						|
     * 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(pScrn, pScrn->frameX0, pScrn->frameY0);
 | 
						|
 | 
						|
    /*
 | 
						|
     * 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;
 | 
						|
 | 
						|
    /*
 | 
						|
     * Set initial black & white colourmap indices.
 | 
						|
     */
 | 
						|
    xf86SetBlackWhitePixels(pScreen);
 | 
						|
 | 
						|
    /*
 | 
						|
     * Install colourmap functions.
 | 
						|
     */
 | 
						|
 | 
						|
    ...
 | 
						|
 | 
						|
    /*
 | 
						|
     * 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;
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>SwitchMode</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>SwitchMode()</function> function if mode switching
 | 
						|
    is supported by the driver.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
static Bool
 | 
						|
ZZZSwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
 | 
						|
{
 | 
						|
    return ZZZModeInit(pScrn, mode);
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>AdjustFrame</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>AdjustFrame()</function> function if the driver
 | 
						|
    supports this.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
static void
 | 
						|
ZZZAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
 | 
						|
{
 | 
						|
    /* Adjust the viewport */
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>EnterVT, LeaveVT</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>EnterVT()</function> and <function>LeaveVT()</function>
 | 
						|
    functions.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    These functions are mandatory.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
static Bool
 | 
						|
ZZZEnterVT(ScrnInfoPtr pScrn)
 | 
						|
{
 | 
						|
    return ZZZModeInit(pScrn, pScrn->currentMode);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
ZZZLeaveVT(ScrnInfoPtr pScrn)
 | 
						|
{
 | 
						|
    ZZZRestore(pScrn);
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>CloseScreen</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>CloseScreen()</function> function:
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    This function is mandatory.  Note that it unwraps the previously
 | 
						|
    wrapped <structfield>pScreen->CloseScreen</structfield>, and finishes by
 | 
						|
    calling it.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
static Bool
 | 
						|
ZZZCloseScreen(ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
 | 
						|
    if (pScrn->vtSema) {
 | 
						|
        ZZZRestore(pScrn);
 | 
						|
        ZZZUnmapMem(pScrn);
 | 
						|
    }
 | 
						|
    pScrn->vtSema = FALSE;
 | 
						|
    pScreen->CloseScreen = ZZZPTR(pScrn)->CloseScreen;
 | 
						|
    return (*pScreen->CloseScreen)(pScreen);
 | 
						|
}
 | 
						|
	</programlisting>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>SaveScreen</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>SaveScreen()</function> function (the screen
 | 
						|
    blanking function).  When using the vgahw module, this will typically
 | 
						|
    be:
 | 
						|
 | 
						|
	  <programlisting>
 | 
						|
static Bool
 | 
						|
ZZZSaveScreen(ScreenPtr pScreen, int mode)
 | 
						|
{
 | 
						|
    return vgaHWSaveScreen(pScreen, mode);
 | 
						|
}
 | 
						|
	  </programlisting>
 | 
						|
	</para>
 | 
						|
 | 
						|
	<para>
 | 
						|
    This function is mandatory.  Before modifying any hardware register
 | 
						|
    directly this function needs to make sure that the Xserver is active
 | 
						|
    by checking if <parameter>pScrn</parameter> is non-NULL and for
 | 
						|
    <literal remap="tt">pScrn->vtSema == TRUE</literal>.
 | 
						|
	</para>
 | 
						|
      </sect3>
 | 
						|
 | 
						|
      <sect3>
 | 
						|
	<title>FreeScreen</title>
 | 
						|
 | 
						|
	<para>
 | 
						|
    Define the <function>FreeScreen()</function> function.  This function
 | 
						|
    is optional.  It should be defined if the <structname>ScrnInfoRec</structname>
 | 
						|
    <structfield>driverPrivate</structfield> 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 <function>CloseScreen()</function> function.
 | 
						|
	</para>
 | 
						|
 | 
						|
	<programlisting>
 | 
						|
static void
 | 
						|
ZZZFreeScreen(ScrnInfoPtr pScrn)
 | 
						|
{
 | 
						|
    /*
 | 
						|
     * If the vgahw module is used vgaHWFreeHWRec() would be called
 | 
						|
     * here.
 | 
						|
     */
 | 
						|
    ZZZFreeRec(pScrn);
 | 
						|
}
 | 
						|
 | 
						|
	</programlisting>
 | 
						|
 | 
						|
      </sect3>
 | 
						|
 | 
						|
    </sect2>
 | 
						|
 | 
						|
  </sect1>
 | 
						|
 | 
						|
</article>
 |