9403 lines
327 KiB
XML
9403 lines
327 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 % 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>
|
||
|
<articleinfo>
|
||
|
|
||
|
<title>XFree86 DDX Design (Xorg server version &xserver.version;)</title>
|
||
|
|
||
|
<authorgroup>
|
||
|
<corpauthor><ulink url="http://www.xfree86.org/">
|
||
|
The XFree86 Project, Inc.</ulink></corpauthor>
|
||
|
<corpauthor><ulink url="http://www.x.org/">
|
||
|
The X.Org Foundation, Inc.</ulink></corpauthor>
|
||
|
|
||
|
<othercredit>
|
||
|
<firstname>Jim</firstname><surname>Gettys</surname>
|
||
|
<contrib>Updates for X11R6.7</contrib>
|
||
|
</othercredit>
|
||
|
</authorgroup>
|
||
|
|
||
|
<pubdate>&xserver.reldate;</pubdate>
|
||
|
<releaseinfo>Xorg 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:slot:func".
|
||
|
</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; "keyboard"
|
||
|
</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 "keyboard" 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 (including, XAA). 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 sharable. For PCI devices a generic method is provided to
|
||
|
control resource decoding. Other devices will have to provide a
|
||
|
device specific function to control decoding.
|
||
|
</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 core server contains a list of mandatory modules. These are loaded
|
||
|
first. Currently the only module on this list is the bitmap font module.
|
||
|
</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, and similarly the
|
||
|
<function>xf86MatchIsaInstances()</function> for ISA (non-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 and
|
||
|
<function>xf86ClaimIsaSlot()</function> for ISA 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 and <function>xf86ConfigIsaEntity()</function> for ISA
|
||
|
(see the <link linkend="rac">RAC</link> section). It is possible to
|
||
|
register some entity specific functions with those helpers. When
|
||
|
not using the helpers, the <function>xf86AddEntityToScreen()</function>
|
||
|
<function>xf86ClaimFixedResources()</function> and
|
||
|
<function>xf86SetEntityFuncs()</function> should be used instead (see
|
||
|
the <link linkend="rac">RAC</link> section).
|
||
|
</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>xf86ConfigIsaEntity()</function> helper function for ISA
|
||
|
instances or <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 sharable 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>
|
||
|
All additional resources that the screen needs must be registered
|
||
|
here. This should be done with
|
||
|
<function>xf86RegisterResources()</function>. If some of the fixed
|
||
|
resources registered in the Probe phase are not needed or not
|
||
|
decoded by the hardware when in the OPERATING server state, their
|
||
|
status should be updated with
|
||
|
<function>xf86SetOperatingState()</function>.
|
||
|
</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
|
||
|
maxHValue
|
||
|
maxVValue
|
||
|
virtualX
|
||
|
virtualY
|
||
|
displayWidth
|
||
|
frameX0
|
||
|
frameY0
|
||
|
frameX1
|
||
|
frameY1
|
||
|
zoomLocked
|
||
|
modePool
|
||
|
modes
|
||
|
currentMode
|
||
|
progClock (TRUE if clock is programmable)
|
||
|
chipset
|
||
|
ramdac
|
||
|
clockchip
|
||
|
numClocks (if not programmable)
|
||
|
clock[] (if not programmable)
|
||
|
videoRam
|
||
|
biosBase
|
||
|
memBase
|
||
|
memClk
|
||
|
driverPrivate
|
||
|
chipID
|
||
|
chipRev
|
||
|
</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(int index, 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 sharable resources registered by each entity are compared.
|
||
|
If a resource is registered by more than one entity the entity
|
||
|
will be marked to indicate that it needs to share this resources
|
||
|
type (IO or MEM).
|
||
|
</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, int flags);
|
||
|
</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, int flags);
|
||
|
</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(int index, int flags);
|
||
|
</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(int index, int flags);
|
||
|
</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>
|
||
|
Currently, aperture remapping, as described here, should not be
|
||
|
attempted if the driver uses the <literal remap="tt">xf8_16bpp</literal> or
|
||
|
<literal remap="tt">xf8_32bpp</literal> framebuffer layers. A pending
|
||
|
restructuring of VT switching will address this restriction in
|
||
|
the near future.
|
||
|
</para>
|
||
|
|
||
|
<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(int index, 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(int scrnindex, int flags);
|
||
|
</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>
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
const char *xf86GetServerName();
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
Returns the name of the X server from the command line.
|
||
|
</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 (for example,
|
||
|
the XAA module) that is reset for each server generation is hooked into
|
||
|
the <structname>ScrnInfoRec</structname> through it's <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 xf86ServerIsInitialising();
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
Returns <constant>TRUE</constant> if the server is at the beginning of
|
||
|
a generation and is in the process of initialising, 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>
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
Bool xf86CaughtSignal();
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
Returns <constant>TRUE</constant> if the server has caught a signal,
|
||
|
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
|
||
|
sharable 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 sharable resources registered by each entity are compared. If
|
||
|
a resource is registered by more than one entity the entity will be
|
||
|
marked to need to share this resources type (<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>
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
int xf86MatchIsaInstances(const char *driverName,
|
||
|
SymTabPtr chipsets, IsaChipsets *ISAchipsets,
|
||
|
DriverPtr drvp, FindIsaDevProc FindIsaDevice,
|
||
|
GDevPtr *devList, int numDevs,
|
||
|
int **foundEntities);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function finds matches between ISA cards that a driver supports
|
||
|
and config file device sections. It is intended for use in the
|
||
|
<function>ChipProbe()</function> function of drivers for ISA cards.
|
||
|
<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>ISAchipsets</parameter> is a table that provides
|
||
|
a mapping between the driver's internal chipset tokens and the
|
||
|
resource classes. <parameter>FindIsaDevice</parameter> is a
|
||
|
driver-provided function that probes the hardware and returns the
|
||
|
chipset token corresponding to what was detected, and
|
||
|
<constant>-1</constant> if nothing was detected.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
If the config file device section contains a chipset entry, then
|
||
|
it is checked against the <parameter>chipsets</parameter> list. When
|
||
|
no chipset entry is present, the <parameter>FindIsaDevice</parameter>
|
||
|
function is called instead.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
Entity index numbers for confirmed matches are returned as an
|
||
|
array via <parameter>foundEntities</parameter>. The 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 xf86ParseIsaBusString(const char *busID);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
Compares a <parameter>BusID</parameter> string with the ISA bus ID string
|
||
|
("ISA" or "ISA:"). 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>
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
int xf86ClaimIsaSlot(DriverPtr drvp, int chipset,
|
||
|
GDevPtr dev, Bool active);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This allocates an entity record entity and initialise the data
|
||
|
structures. The return value is the index of the newly allocated
|
||
|
entity record.
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
Bool xf86IsPrimaryIsa(void);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function returns <constant>TRUE</constant> if the primary card is
|
||
|
an ISA (non-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,
|
||
|
resList res, EntityProc init,
|
||
|
EntityProc enter, EntityProc leave,
|
||
|
pointer private);
|
||
|
|
||
|
ScrnInfoPtr xf86ConfigIsaEntity(ScrnInfoPtr pScrn,
|
||
|
int scrnFlag, int entityIndex,
|
||
|
IsaChipsets *i_chip,
|
||
|
resList res, EntityProc init,
|
||
|
EntityProc enter, EntityProc leave,
|
||
|
pointer private);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
These functions are used to register the non-relocatable resources
|
||
|
for an entity, and the optional entity-specific <parameter>Init</parameter>, <parameter>Enter</parameter> and
|
||
|
<parameter>Leave</parameter> functions. Usually the list of fixed resources is obtained
|
||
|
from the Isa/PciChipsets lists. However an additional list of
|
||
|
resources may be passed. Generally this is not required.
|
||
|
For active entities a <structname>ScrnInfoRec</structname> is allocated
|
||
|
if the <parameter>pScrn</parameter> argument is <constant>NULL</constant>.
|
||
|
The
|
||
|
return value is <constant>TRUE</constant> when successful. The init, enter, leave
|
||
|
functions are defined as follows:
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
typedef void (*EntityProc)(int entityIndex,
|
||
|
pointer private);
|
||
|
</programlisting>
|
||
|
</para></blockquote>
|
||
|
|
||
|
They are passed the entity index and a pointer to a private scratch
|
||
|
area. This can be set up during <function>Probe()</function> and
|
||
|
its address can be passed to
|
||
|
<function>xf86ConfigIsaEntity()</function> and
|
||
|
<function>xf86ConfigPciEntity()</function> as the last argument.
|
||
|
</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 xf86ClaimFixedResources(resList list, int entityIndex);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function registers the non-relocatable resources which cannot
|
||
|
be disabled and which therefore would cause the server to fail
|
||
|
immediately if they were found to conflict. It also records
|
||
|
non-relocatable but sharable resources for processing after the
|
||
|
<function>Probe()</function> phase.
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
|
||
|
EntityProc enter, EntityProc leave, pointer);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function registers with an entity the <parameter>init</parameter>,
|
||
|
<parameter>enter</parameter>, <parameter>leave</parameter> functions along
|
||
|
with the pointer to their private area.
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
|
||
|
<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(int scrnIndex);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function returns <constant>TRUE</constant> if the primary entity
|
||
|
is registered with the screen referenced by
|
||
|
<parameter>scrnIndex</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>
|
||
|
The primary function for registration of resources is:
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
resPtr xf86RegisterResources(int entityIndex, resList list,
|
||
|
int access);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function tries to register the resources in
|
||
|
<parameter>list</parameter>. If list is <constant>NULL</constant> it tries
|
||
|
to determine the resources automatically. This only works for
|
||
|
entities that provide a generic way to read out the resource ranges
|
||
|
they decode. So far this is only the case for PCI devices. By
|
||
|
default the PCI resources are registered as shared
|
||
|
(<constant>ResShared</constant>) if the driver wants to set a different
|
||
|
access type it can do so by specifying the access flags in the
|
||
|
third argument. A value of <constant>0</constant> means to use the
|
||
|
default settings. If for any reason the resource broker is not
|
||
|
able to register some of the requested resources the function will
|
||
|
return a pointer to a list of the failed ones. In this case the
|
||
|
driver may be able to move the resource to different locations.
|
||
|
In case of PCI bus entities this is done by passing the list of
|
||
|
failed resources to <function>xf86ReallocatePciResources()</function>.
|
||
|
When the registration succeeds, the return value is
|
||
|
<constant>NULL</constant>.
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
</para>
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
resPtr xf86ReallocatePciResources(int entityIndex, resPtr pRes);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function takes a list of PCI resources that need to be
|
||
|
reallocated and returns <constant>NULL</constant> when all relocations are
|
||
|
successful.
|
||
|
<function>xf86RegisterResources()</function> should be called again to
|
||
|
register the relocated resources with the broker.
|
||
|
If the reallocation fails, a list of the resources that could not be
|
||
|
relocated is returned.
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
|
||
|
<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>
|
||
|
Some PCI devices are broken in the sense that they return invalid size
|
||
|
information for a certain resource. In this case the driver can supply
|
||
|
the correct size and make sure that the resource range allocated for
|
||
|
the card is large enough to hold the address range decoded by the card.
|
||
|
The function <function>xf86FixPciResource()</function> can be used to do this:
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
Bool xf86FixPciResource(int entityIndex, unsigned int prt,
|
||
|
CARD32 alignment, long type);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function fixes a PCI resource allocation. The
|
||
|
<parameter>prt</parameter> parameter contains the number of the PCI base
|
||
|
register that needs to be fixed (<constant>0-5</constant>, and
|
||
|
<constant>6</constant> for the BIOS base register). The size is
|
||
|
specified by the alignment. Since PCI resources need to span an
|
||
|
integral range of size <literal remap="tt">2ˆn</literal>, the alignm ent also
|
||
|
specifies the number of addresses that will be decoded. If the
|
||
|
driver specifies a type mask it can override the default type for
|
||
|
PCI resources which is <constant>ResShared</constant>. The resource
|
||
|
broker needs to know that to find a matching resource range. This
|
||
|
function should be called before calling
|
||
|
<function>xf86RegisterResources()</function>. The return value is
|
||
|
<constant>TRUE</constant> when the function succeeds.
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
|
||
|
<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 driver may replace the generic access control functions for an entity.
|
||
|
This is done with the <function>xf86SetAccessFuncs()</function>:
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
void xf86SetAccessFuncs(EntityInfoPtr pEnt,
|
||
|
xf86SetAccessFuncPtr funcs,
|
||
|
xf86SetAccessFuncPtr oldFuncs);
|
||
|
</programlisting>
|
||
|
with:
|
||
|
<programlisting>
|
||
|
typedef struct {
|
||
|
xf86AccessPtr mem;
|
||
|
xf86AccessPtr io;
|
||
|
xf86AccessPtr io_mem;
|
||
|
} xf86SetAccessFuncRec, *xf86SetAccessFuncPtr;
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
The driver can pass three functions: one for I/O access, one for
|
||
|
memory access and one for combined memory and I/O access. If the
|
||
|
memory access and combined access functions are identical the
|
||
|
common level assumes that the memory access cannot be controlled
|
||
|
independently of I/O access, if the I/O access function and the
|
||
|
combined access functions are the same it is assumed that I/O can
|
||
|
not be controlled independently. If memory and I/O have to be
|
||
|
controlled together all three values should be the same. If a
|
||
|
non <constant>NULL</constant> value is passed as third argument it is
|
||
|
interpreted as an address where to store the old access record.
|
||
|
If the third argument is <constant>NULL</constant> it will be assumed
|
||
|
that the generic access should be enabled before replacing the
|
||
|
access functions. Otherwise it will be disabled. The driver may
|
||
|
enable them itself using the returned values. It should do this
|
||
|
from its replacement access functions as the generic access may
|
||
|
be disabled by the common level on certain occasions. If replacement
|
||
|
functions are specified they must control all resources of the
|
||
|
specific type registered for the entity.
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
To find out if a specific resource range conflicts with another
|
||
|
resource the <function>xf86ChkConflict()</function> function may be used:
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
memType xf86ChkConflict(resRange *rgp, int entityIndex);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function checks if the resource range <parameter>rgp</parameter> of
|
||
|
for the specified entity conflicts with with another resource.
|
||
|
If a conflict is found, the address of the start of the conflict
|
||
|
is returned. The return value is zero when there is no conflict.
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The OPERATING state properties of previously registered fixed resources
|
||
|
can be set with the <function>xf86SetOperatingState()</function> function:
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
resPtr xf86SetOperatingState(resList list, int entityIndex,
|
||
|
int mask);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function is used to set the status of a resource during
|
||
|
OPERATING state. <parameter>list</parameter> holds a list to which
|
||
|
<parameter>mask</parameter> is to be applied. The parameter
|
||
|
<parameter>mask</parameter> may have the value <constant>ResUnusedOpr</constant>
|
||
|
and <constant>ResDisableOpr</constant>. The first one should be used
|
||
|
if a resource isn't used by the driver during OPERATING state
|
||
|
although it is decoded by the device, while the latter one indicates
|
||
|
that the resource is not decoded during OPERATING state. Note
|
||
|
that the resource ranges have to match those specified during
|
||
|
registration. If a range has been specified starting at
|
||
|
<literal remap="tt">A</literal> and ending at <literal remap="tt">B</literal> and suppose
|
||
|
<literal remap="tt">C</literal> us a value satisfying
|
||
|
<literal remap="tt">A < C < B</literal> one may not
|
||
|
specify the resource range <literal remap="tt">(A,B)</literal> by splitting it
|
||
|
into two ranges <literal remap="tt">(A,C)</literal> and <literal remap="tt">(C,B)</literal>.
|
||
|
</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>
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
void xf86DeallocateResourcesForEntity(int entityIndex, long type);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function deallocates all resources of a given type registered
|
||
|
for a certain entity from the resource broker list.
|
||
|
</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>
|
||
|
pointer xf86FindOption(pointer 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>
|
||
|
char *xf86FindOptionValue(pointer 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(pointer 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(pointer 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, pointer 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, pointer 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, pointer 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 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 that initialise a SW cursor need this:
|
||
|
<literallayout><filename>
|
||
|
"mipointer.h"
|
||
|
</filename></literallayout>
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
All drivers implementing backing store need this:
|
||
|
<literallayout><filename>
|
||
|
"mibstore.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 XAA, it needs these:
|
||
|
<literallayout><filename>
|
||
|
"xaa.h"
|
||
|
"xaalocal.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>
|
||
|
|
||
|
<para>
|
||
|
<function>xf86InitFBManager()</function> must be called before XAA is
|
||
|
initialized since XAA uses the manager for it's pixmap cache.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
An alternative function is provided to allow the driver to initialize
|
||
|
the framebuffer manager with a Region rather than a box.
|
||
|
|
||
|
<programlisting>
|
||
|
Bool xf86InitFBManagerRegion(ScreenPtr pScreen,
|
||
|
RegionPtr FullRegion);
|
||
|
</programlisting>
|
||
|
|
||
|
<function>xf86InitFBManagerRegion()</function>, unlike
|
||
|
<function>xf86InitFBManager()</function>, does not remove the area used for
|
||
|
the visible screen so that area should not be included in the region
|
||
|
passed to the function. <function>xf86InitFBManagerRegion()</function> is
|
||
|
useful when non-contiguous areas are available to be managed, and is
|
||
|
required when multiple framebuffers are stored in video memory (as in
|
||
|
the case where an overlay of a different depth is stored as a second
|
||
|
framebuffer in offscreen memory).
|
||
|
</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_NO_CLIPPING</constant></term>
|
||
|
<listitem><para>
|
||
|
This indicates that the video adaptor does not support
|
||
|
clipping. The driver will never receive <quote>Put</quote> requests
|
||
|
where less than the entire area determined by
|
||
|
<parameter>drw_x</parameter>, <parameter>drw_y</parameter>,
|
||
|
<parameter>drw_w</parameter> and <parameter>drw_h</parameter> is visible.
|
||
|
This flag does not apply to <quote>Get</quote> requests. Hardware
|
||
|
that is incapable of clipping <quote>Gets</quote> may punt or get
|
||
|
the extents of the clipping region passed to it.
|
||
|
</para></listitem>
|
||
|
|
||
|
</varlistentry>
|
||
|
|
||
|
<varlistentry>
|
||
|
<term><constant>VIDEO_INVERT_CLIPLIST</constant></term>
|
||
|
<listitem><para>
|
||
|
This indicates that the video driver requires the clip
|
||
|
list to contain the regions which are obscured rather
|
||
|
than the regions which are are visible.
|
||
|
</para></listitem>
|
||
|
|
||
|
</varlistentry>
|
||
|
|
||
|
<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>
|
||
|
If the <constant>VIDEO_NO_CLIPPING</constant>
|
||
|
flag is set, the <literal remap="tt">clipBoxes</literal> may be ignored by
|
||
|
the driver. <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.
|
||
|
If the driver has specified <constant>VIDEO_INVERT_CLIPLIST</constant>,
|
||
|
<literal remap="tt">clipBoxes</literal> will indicate the areas of the primitive
|
||
|
which are obscured rather than the areas visible.
|
||
|
|
||
|
</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 (analgous 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, const char *path,
|
||
|
const char **subdirlist, const char **patternlist,
|
||
|
pointer options, const XF86ModReqInfo * modreq,
|
||
|
int *errmaj, int *errmin);
|
||
|
</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>path</parameter></term>
|
||
|
<listitem><para>
|
||
|
An optional comma-separated list of module search paths.
|
||
|
When <constant>NULL</constant>, the default search path is used.
|
||
|
</para></listitem></varlistentry>
|
||
|
|
||
|
|
||
|
<varlistentry>
|
||
|
<term><parameter>subdirlist</parameter></term>
|
||
|
<listitem><para>
|
||
|
An optional <constant>NULL</constant> terminated list of
|
||
|
subdirectories to search. When <constant>NULL</constant>,
|
||
|
the default built-in list is used (refer to
|
||
|
<varname>stdSubdirs</varname> in <filename>loadmod.c</filename>).
|
||
|
The default list is also substituted for entries in
|
||
|
<parameter>subdirlist</parameter> with the value
|
||
|
<constant>DEFAULT_LIST</constant>. This makes is possible
|
||
|
to augment the default list instead of replacing it.
|
||
|
Subdir elements must be relative, and must not contain
|
||
|
<literal remap="tt">".."</literal>. If any violate this requirement,
|
||
|
the load fails.
|
||
|
</para></listitem></varlistentry>
|
||
|
|
||
|
|
||
|
<varlistentry>
|
||
|
<term><parameter>patternlist</parameter></term>
|
||
|
<listitem><para>
|
||
|
An optional <constant>NULL</constant> terminated list of
|
||
|
POSIX regular expressions used to connect module
|
||
|
filenames with canonical module names. Each regex
|
||
|
should contain exactly one subexpression that corresponds
|
||
|
to the canonical module name. When <constant>NULL</constant>,
|
||
|
the default built-in list is used (refer to
|
||
|
<varname>stdPatterns</varname> in
|
||
|
<filename>loadmod.c</filename>). The default list is also
|
||
|
substituted for entries in <parameter>patternlist</parameter>
|
||
|
with the value <constant>DEFAULT_LIST</constant>. This
|
||
|
makes it possible to augment the default list instead
|
||
|
of replacing it.
|
||
|
</para></listitem></varlistentry>
|
||
|
|
||
|
|
||
|
<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>
|
||
|
|
||
|
<para>
|
||
|
When loading <quote>external</quote> modules (modules that don't
|
||
|
have the standard entry point, for example a
|
||
|
special shared library) the options parameter can be
|
||
|
set to <constant>EXTERN_MODULE</constant> to tell the
|
||
|
loader not to reject the module when it doesn't find
|
||
|
the standard entry point.
|
||
|
</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; /* MAJOR_UNSPEC */
|
||
|
CARD8 minorversion; /* MINOR_UNSPEC */
|
||
|
CARD16 patchlevel; /* PATCH_UNSPEC */
|
||
|
const char * abiclass; /* ABI_CLASS_NONE */
|
||
|
CARD32 abiversion; /* ABI_VERS_UNSPEC */
|
||
|
const char * moduleclass; /* MOD_CLASS_NONE */
|
||
|
} XF86ModReqInfo;
|
||
|
</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> is
|
||
|
specified and 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> is
|
||
|
specified and 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>
|
||
|
|
||
|
<varlistentry>
|
||
|
<term><parameter>errmin</parameter></term>
|
||
|
<listitem><para>
|
||
|
Like <parameter>errmaj</parameter>, but for the minor part
|
||
|
of the error code.
|
||
|
</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>
|
||
|
<varlistentry>
|
||
|
<term><constant>ABI_CLASS_FONT</constant></term>
|
||
|
<listitem><para>requires the font 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
|
||
|
ABI_FONT_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_FONT
|
||
|
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. The
|
||
|
other difference is that the path parameter may not be specified.
|
||
|
The module search path used for modules loaded with this function
|
||
|
is the default search path as initialised with
|
||
|
<function>LoaderSetPath()</function>.
|
||
|
</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 LoadExtension(ExtensionModule *ext);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This registers the entry points for the extension identified by
|
||
|
<parameter>ext</parameter>. The <structname>ExtensionModule</structname> struct is
|
||
|
defined as:
|
||
|
|
||
|
<programlisting>
|
||
|
typedef struct {
|
||
|
InitExtension initFunc;
|
||
|
char * name;
|
||
|
Bool *disablePtr;
|
||
|
InitExtension setupFunc;
|
||
|
} ExtensionModule;
|
||
|
</programlisting>
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
void LoadFont(FontModule *font);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This registers the entry points for the font rasteriser module
|
||
|
identified by <parameter>font</parameter>. The <structname>FontModule</structname>
|
||
|
struct is defined as:
|
||
|
|
||
|
<programlisting>
|
||
|
typedef struct {
|
||
|
InitFont initFunc;
|
||
|
char * name;
|
||
|
pointer module;
|
||
|
} FontModule;
|
||
|
</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>
|
||
|
xf86MsgVerb(MessageType type, int verb, const char *format, ...);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
Like <function>xf86Msg()</function>, but with the verbosity level given
|
||
|
explicitly.
|
||
|
</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>maxHValue</structfield></term>
|
||
|
<listitem><para>
|
||
|
Maximum horizontal timing value allowed
|
||
|
</para></listitem></varlistentry>
|
||
|
<varlistentry>
|
||
|
<term><structfield>maxVValue</structfield></term>
|
||
|
<listitem><para>
|
||
|
Maximum vertical timing value allowed
|
||
|
</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>
|
||
|
|
||
|
<varlistentry>
|
||
|
<term><structfield>virtualFrom</structfield></term>
|
||
|
<listitem><para>
|
||
|
Where the virtual size was determined from.
|
||
|
</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>
|
||
|
int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
|
||
|
int *divider);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function returns the index of the closest clock to the
|
||
|
frequency <parameter>freq</parameter> given (in kHz). It assumes that
|
||
|
the number of clocks is greater than zero. It requires that the
|
||
|
<structfield>numClocks</structfield> and <structfield>clock</structfield> fields of the
|
||
|
<structname>ScrnInfoRec</structname> are initialised. The
|
||
|
<structfield>allowDiv2</structfield> field determines if the clocks can be
|
||
|
halved. The <parameter>*divider</parameter> return value indicates
|
||
|
whether clock division is used when determining the clock returned.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
This function is only for non-programmable clocks.
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
|
||
|
<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>
|
||
|
ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
|
||
|
ClockRangePtr clockRanges, LookupModeFlags strategy);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function takes a pointer to a mode with the name filled in,
|
||
|
and looks for a mode in the <structfield>modePool</structfield> list which
|
||
|
matches. The parameters of the matching mode are filled in to
|
||
|
<parameter>*modep</parameter>. The <parameter>clockRanges</parameter> and
|
||
|
<parameter>strategy</parameter> parameters are as for the
|
||
|
<function>xf86ValidateModes()</function> function above.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
This function requires the <structfield>modePool</structfield>,
|
||
|
<structfield>clock[]</structfield>, <structfield>numClocks</structfield> and
|
||
|
<structfield>progClock</structfield> fields of the <structname>ScrnInfoRec</structname>
|
||
|
to be initialised before being called.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The return value is <constant>MODE_OK</constant> if a mode was found.
|
||
|
Otherwise it indicates why a matching mode could not be found.
|
||
|
</para>
|
||
|
|
||
|
</blockquote></para></blockquote>
|
||
|
|
||
|
<blockquote><para>
|
||
|
<programlisting>
|
||
|
ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp,
|
||
|
DisplayModePtr mode, ClockRangePtr clockRanges,
|
||
|
LookupModeFlags strategy, int maxPitch,
|
||
|
int virtualX, int virtualY);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function checks the passed mode against some basic driver
|
||
|
constraints. Apart from the ones passed explicitly, the
|
||
|
<structfield>maxHValue</structfield> and <structfield>maxVValue</structfield> fields of
|
||
|
the <structname>ScrnInfoRec</structname> are also used. If the
|
||
|
<structfield>ValidMode</structfield> field of the <structname>ScrnInfoRec</structname>
|
||
|
is set, that function is also called to check the mode. Next, the
|
||
|
mode is checked against the monitor's constraints.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
If the mode is consistent with all constraints, the return value
|
||
|
is <constant>MODE_OK</constant>. Otherwise the return value indicates
|
||
|
which constraint wasn't met.
|
||
|
</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 vgaHWSetRegCounts(ScrnInfoPtr pScrn, int numCRTC,
|
||
|
int numSequencer, int numGraphics, int numAttribute);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function allows the number of CRTC, Sequencer, Graphics and
|
||
|
Attribute registers to be changed. This makes it possible for
|
||
|
extended registers to be saved and restored with
|
||
|
<function>vgaHWSave()</function> and <function>vgaHWRestore()</function>.
|
||
|
This function should be called after a <structname>vgaHWRec</structname>
|
||
|
has been allocated with <function>vgaHWGetHWRec()</function>. The
|
||
|
default values are defined in <filename>vgaHW.h</filename> as follows:
|
||
|
|
||
|
<programlisting>
|
||
|
#define VGA_NUM_CRTC 25
|
||
|
#define VGA_NUM_SEQ 5
|
||
|
#define VGA_NUM_GFX 9
|
||
|
#define VGA_NUM_ATTR 21
|
||
|
</programlisting>
|
||
|
</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 vgaHWDisable(vgaHWPtr hwp);
|
||
|
</programlisting>
|
||
|
<blockquote><para>
|
||
|
This function disables 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>
|
||
|
|
||
|
<para>
|
||
|
The number of registers actually saved may be modified by a prior call
|
||
|
to <function>vgaHWSetRegCounts()</function>.
|
||
|
</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>
|
||
|
|
||
|
<para>
|
||
|
The number of registers actually restored may be modified by a prior call
|
||
|
to <function>vgaHWSetRegCounts()</function>.
|
||
|
</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 implementing backing store need this:
|
||
|
<literallayout><filename>
|
||
|
"mibstore.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 = { &zzzVersRec, zzzSetup, NULL };
|
||
|
|
||
|
static pointer
|
||
|
zzzSetup(pointer module, pointer opts, int *errmaj, int *errmin)
|
||
|
{
|
||
|
static Bool setupDone = FALSE;
|
||
|
|
||
|
/* This module should be loaded only once, but check to be sure. */
|
||
|
|
||
|
if (!setupDone) {
|
||
|
/*
|
||
|
* Modules that this driver always requires may be loaded
|
||
|
* here by calling LoadSubModule().
|
||
|
*/
|
||
|
|
||
|
setupDone = TRUE;
|
||
|
xf86AddDriver(&MGA, module, 0);
|
||
|
|
||
|
/*
|
||
|
* The return value must be non-NULL on success even though
|
||
|
* there is no TearDownProc.
|
||
|
*/
|
||
|
return (pointer)1;
|
||
|
} else {
|
||
|
if (errmaj) *errmaj = LDR_ONCEONLY;
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
</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>xnfcalloc()</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 = xnfcalloc(sizeof(ZZZRec), 1);
|
||
|
/* 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);
|
||
|
}
|
||
|
|
||
|
#ifdef HAS_ISA_DEVS
|
||
|
/*
|
||
|
* If the driver supports ISA hardware, the following block
|
||
|
* can be included too.
|
||
|
*/
|
||
|
numUsed = xf86MatchIsaInstances(ZZZ_NAME, ZZZChipsets,
|
||
|
ZZZIsaChipsets, drv, ZZZFindIsaDevice,
|
||
|
devSections, numDevSections, &usedChips);
|
||
|
for (i = 0; i < numUsed; i++) {
|
||
|
ScrnInfoPtr pScrn = NULL;
|
||
|
if ((pScrn = xf86ConfigIsaEntity(pScrn, flags, usedChips[i],
|
||
|
ZZZIsaChipsets, NULL, NULL, NULL,
|
||
|
NULL, NULL))) {
|
||
|
pScrn->driverVersion = VERSION;
|
||
|
pScrn->driverName = ZZZ_DRIVER_NAME;
|
||
|
pScrn->name = ZZZ_NAME;
|
||
|
pScrn->Probe = ZZZProbe;
|
||
|
pScrn->PreInit = ZZZPreInit;
|
||
|
pScrn->ScreenInit = ZZZScreenInit;
|
||
|
pScrn->SwitchMode = ZZZSwitchMode;
|
||
|
pScrn->AdjustFrame = ZZZAdjustFrame;
|
||
|
pScrn->EnterVT = ZZZEnterVT;
|
||
|
pScrn->LeaveVT = ZZZLeaveVT;
|
||
|
pScrn->FreeScreen = ZZZFreeScreen;
|
||
|
pScrn->ValidMode = ZZZValidMode;
|
||
|
foundScreen = TRUE;
|
||
|
}
|
||
|
}
|
||
|
xfree(usedChips);
|
||
|
#endif /* HAS_ISA_DEVS */
|
||
|
|
||
|
xfree(devSections);
|
||
|
return foundScreen;
|
||
|
</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;
|
||
|
|
||
|
/* Load XAA if needed */
|
||
|
if (!pZzz->noAccel || pZzz->hwCursor)
|
||
|
if (!xf86LoadSubModule(pScrn, "xaa")) {
|
||
|
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(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
||
|
{
|
||
|
/* Get the ScrnInfoRec */
|
||
|
pScrn = xf86Screens[pScreen->myNum];
|
||
|
|
||
|
/*
|
||
|
* If using the vgahw module, its data structures and related
|
||
|
* things are typically initialised/mapped here.
|
||
|
*/
|
||
|
|
||
|
/* Save the current video state */
|
||
|
ZZZSave(pScrn);
|
||
|
|
||
|
/* Initialise the first mode */
|
||
|
ZZZModeInit(pScrn, pScrn->currentMode);
|
||
|
|
||
|
/* Set the viewport if supported */
|
||
|
|
||
|
ZZZAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
|
||
|
|
||
|
/*
|
||
|
* Setup the screen's visuals, and initialise the framebuffer
|
||
|
* code.
|
||
|
*/
|
||
|
|
||
|
/* Reset the visual list */
|
||
|
miClearVisualTypes();
|
||
|
|
||
|
/*
|
||
|
* Setup the visuals supported. This driver only supports
|
||
|
* TrueColor for bpp > 8, so the default set of visuals isn't
|
||
|
* acceptable. To deal with this, call miSetVisualTypes with
|
||
|
* the appropriate visual mask.
|
||
|
*/
|
||
|
|
||
|
if (pScrn->bitsPerPixel > 8) {
|
||
|
if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
|
||
|
pScrn->rgbBits, pScrn->defaultVisual))
|
||
|
return FALSE;
|
||
|
} else {
|
||
|
if (!miSetVisualTypes(pScrn->depth,
|
||
|
miGetDefaultVisualMask(pScrn->depth),
|
||
|
pScrn->rgbBits, pScrn->defaultVisual))
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Initialise the framebuffer.
|
||
|
*/
|
||
|
|
||
|
switch (pScrn->bitsPerPixel) {
|
||
|
case 1:
|
||
|
ret = xf1bppScreenInit(pScreen, FbBase,
|
||
|
pScrn->virtualX, pScrn->virtualY,
|
||
|
pScrn->xDpi, pScrn->yDpi,
|
||
|
pScrn->displayWidth);
|
||
|
break;
|
||
|
case 4:
|
||
|
ret = xf4bppScreenInit(pScreen, FbBase,
|
||
|
pScrn->virtualX, pScrn->virtualY,
|
||
|
pScrn->xDpi, pScrn->yDpi,
|
||
|
pScrn->displayWidth);
|
||
|
break;
|
||
|
case 8:
|
||
|
ret = cfbScreenInit(pScreen, FbBase,
|
||
|
pScrn->virtualX, pScrn->virtualY,
|
||
|
pScrn->xDpi, pScrn->yDpi,
|
||
|
pScrn->displayWidth);
|
||
|
break;
|
||
|
case 16:
|
||
|
ret = cfb16ScreenInit(pScreen, FbBase,
|
||
|
pScrn->virtualX, pScrn->virtualY,
|
||
|
pScrn->xDpi, pScrn->yDpi,
|
||
|
pScrn->displayWidth);
|
||
|
break;
|
||
|
case 24:
|
||
|
ret = cfb24ScreenInit(pScreen, FbBase,
|
||
|
pScrn->virtualX, pScrn->virtualY,
|
||
|
pScrn->xDpi, pScrn->yDpi,
|
||
|
pScrn->displayWidth);
|
||
|
break;
|
||
|
case 32:
|
||
|
ret = cfb32ScreenInit(pScreen, FbBase,
|
||
|
pScrn->virtualX, pScrn->virtualY,
|
||
|
pScrn->xDpi, pScrn->yDpi,
|
||
|
pScrn->displayWidth);
|
||
|
break;
|
||
|
default:
|
||
|
print a message about an internal error;
|
||
|
ret = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (!ret)
|
||
|
return FALSE;
|
||
|
|
||
|
/* Override the default mask/offset settings */
|
||
|
if (pScrn->bitsPerPixel > 8) {
|
||
|
for (i = 0, visual = pScreen->visuals;
|
||
|
i < pScreen->numVisuals; i++, visual++) {
|
||
|
if ((visual->class | DynamicClass) == DirectColor) {
|
||
|
visual->offsetRed = pScrn->offset.red;
|
||
|
visual->offsetGreen = pScrn->offset.green;
|
||
|
visual->offsetBlue = pScrn->offset.blue;
|
||
|
visual->redMask = pScrn->mask.red;
|
||
|
visual->greenMask = pScrn->mask.green;
|
||
|
visual->blueMask = pScrn->mask.blue;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* If banking is needed, initialise an miBankInfoRec (defined in
|
||
|
* "mibank.h"), and call miInitializeBanking().
|
||
|
*/
|
||
|
if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
|
||
|
pScrn->displayWidth, pBankInfo))
|
||
|
return FALSE;
|
||
|
|
||
|
/*
|
||
|
* If backing store is to be supported (as is usually the case),
|
||
|
* initialise it.
|
||
|
*/
|
||
|
miInitializeBackingStore(pScreen);
|
||
|
|
||
|
/*
|
||
|
* Set initial black & white colourmap indices.
|
||
|
*/
|
||
|
xf86SetBlackWhitePixels(pScreen);
|
||
|
|
||
|
/*
|
||
|
* Install colourmap functions. If using the vgahw module,
|
||
|
* vgaHandleColormaps would usually be called here.
|
||
|
*/
|
||
|
|
||
|
...
|
||
|
|
||
|
/*
|
||
|
* Initialise cursor functions. This example is for the mi
|
||
|
* software cursor.
|
||
|
*/
|
||
|
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
|
||
|
|
||
|
/* Initialise the default colourmap */
|
||
|
switch (pScrn->depth) {
|
||
|
case 1:
|
||
|
if (!xf1bppCreateDefColormap(pScreen))
|
||
|
return FALSE;
|
||
|
break;
|
||
|
case 4:
|
||
|
if (!xf4bppCreateDefColormap(pScreen))
|
||
|
return FALSE;
|
||
|
break;
|
||
|
default:
|
||
|
if (!cfbCreateDefColormap(pScreen))
|
||
|
return FALSE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Wrap the CloseScreen vector and set SaveScreen.
|
||
|
*/
|
||
|
ZZZPTR(pScrn)->CloseScreen = pScreen->CloseScreen;
|
||
|
pScreen->CloseScreen = ZZZCloseScreen;
|
||
|
pScreen->SaveScreen = ZZZSaveScreen;
|
||
|
|
||
|
/* Report any unused options (only for the first generation) */
|
||
|
if (serverGeneration == 1) {
|
||
|
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
|
||
|
}
|
||
|
|
||
|
/* Done */
|
||
|
return TRUE;
|
||
|
}
|
||
|
</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(int scrnIndex, DisplayModePtr mode, int flags)
|
||
|
{
|
||
|
return ZZZModeInit(xf86Screens[scrnIndex], mode);
|
||
|
}
|
||
|
</programlisting>
|
||
|
</sect3>
|
||
|
|
||
|
<sect3>
|
||
|
<title>AdjustFrame</title>
|
||
|
|
||
|
<para>
|
||
|
Define the <function>AdjustFrame()</function> function if the driver
|
||
|
supports this.
|
||
|
</para>
|
||
|
|
||
|
<programlisting>
|
||
|
static void
|
||
|
ZZZAdjustFrame(int scrnIndex, int x, int y, int flags)
|
||
|
{
|
||
|
/* 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(int scrnIndex, int flags)
|
||
|
{
|
||
|
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
|
||
|
return ZZZModeInit(pScrn, pScrn->currentMode);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ZZZLeaveVT(int scrnIndex, int flags)
|
||
|
{
|
||
|
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
|
||
|
ZZZRestore(pScrn);
|
||
|
}
|
||
|
</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(int scrnIndex, ScreenPtr pScreen)
|
||
|
{
|
||
|
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
|
||
|
if (pScrn->vtSema) {
|
||
|
ZZZRestore(pScrn);
|
||
|
ZZZUnmapMem(pScrn);
|
||
|
}
|
||
|
pScrn->vtSema = FALSE;
|
||
|
pScreen->CloseScreen = ZZZPTR(pScrn)->CloseScreen;
|
||
|
return (*pScreen->CloseScreen)(scrnIndex, pScreen);
|
||
|
}
|
||
|
</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(int scrnIndex, int flags)
|
||
|
{
|
||
|
/*
|
||
|
* If the vgahw module is used vgaHWFreeHWRec() would be called
|
||
|
* here.
|
||
|
*/
|
||
|
ZZZFreeRec(xf86Screens[scrnIndex]);
|
||
|
}
|
||
|
|
||
|
</programlisting>
|
||
|
|
||
|
</sect3>
|
||
|
|
||
|
</sect2>
|
||
|
|
||
|
</sect1>
|
||
|
|
||
|
</article>
|