aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-05-16 08:06:12 +0000
committermarha <marha@users.sourceforge.net>2011-05-16 08:06:12 +0000
commit08cbf3b50bfe713044f36b363c73768cd042f13c (patch)
tree6be4c5dd7f5bc2f058228b2a2fa747a4d7666dc5 /xorg-server/hw/xfree86
parentd8c3e3d2ba88d6b87a718aef7f4fb4627113eb52 (diff)
downloadvcxsrv-08cbf3b50bfe713044f36b363c73768cd042f13c.tar.gz
vcxsrv-08cbf3b50bfe713044f36b363c73768cd042f13c.tar.bz2
vcxsrv-08cbf3b50bfe713044f36b363c73768cd042f13c.zip
xserver xkeyboar-config mesa git update 16 May 2011
Diffstat (limited to 'xorg-server/hw/xfree86')
-rw-r--r--xorg-server/hw/xfree86/Makefile.am236
-rw-r--r--xorg-server/hw/xfree86/common/xf86Events.c6
-rw-r--r--xorg-server/hw/xfree86/common/xf86Init.c2
-rw-r--r--xorg-server/hw/xfree86/common/xf86Priv.h3
-rw-r--r--xorg-server/hw/xfree86/common/xf86Xinput.c43
-rw-r--r--xorg-server/hw/xfree86/doc/Makefile.am22
-rw-r--r--xorg-server/hw/xfree86/doc/README.DRIcomp (renamed from xorg-server/hw/xfree86/doc/devel/README.DRIcomp)0
-rw-r--r--xorg-server/hw/xfree86/doc/Registry (renamed from xorg-server/hw/xfree86/doc/devel/Registry)0
-rw-r--r--xorg-server/hw/xfree86/doc/ddxDesign.xml (renamed from xorg-server/hw/xfree86/doc/sgml/DESIGN.xml)18788
-rw-r--r--xorg-server/hw/xfree86/doc/devel/Makefile.am7
-rw-r--r--xorg-server/hw/xfree86/doc/exa-driver.txt (renamed from xorg-server/hw/xfree86/doc/devel/exa-driver.txt)0
-rw-r--r--xorg-server/hw/xfree86/doc/sgml/Makefile.am27
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.c7
13 files changed, 9548 insertions, 9593 deletions
diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am
index 94ef966e2..f1a759a27 100644
--- a/xorg-server/hw/xfree86/Makefile.am
+++ b/xorg-server/hw/xfree86/Makefile.am
@@ -1,118 +1,118 @@
-
-if DRI
-DRI_SUBDIR = dri
-endif
-
-if DRI2
-DRI2_SUBDIR = dri2
-endif
-
-if XF86UTILS
-XF86UTILS_SUBDIR = utils
-endif
-
-if XAA
-XAA_SUBDIR = xaa
-endif
-
-if VGAHW
-VGAHW_SUBDIR = vgahw
-endif
-
-if VBE
-VBE_SUBDIR = vbe
-endif
-
-if INT10MODULE
-INT10_SUBDIR = int10
-endif
-
-SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \
- ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \
- loader dixmods exa modes \
- $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man
-
-DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
- parser ramdac shadowfb vbe vgahw xaa \
- loader dixmods dri dri2 exa modes \
- utils doc man
-
-bin_PROGRAMS = Xorg
-Xorg_SOURCES = xorg.c
-
-AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
-INCLUDES = @XORG_INCS@
-
-noinst_LTLIBRARIES = libxorg.la
-libxorg_la_SOURCES = libxorg.c
-libxorg_la_LIBADD = \
- $(XSERVER_LIBS) \
- loader/libloader.la \
- os-support/libxorgos.la \
- common/libcommon.la \
- parser/libxf86config_internal.la \
- dixmods/libdixmods.la \
- modes/libxf86modes.la \
- ramdac/libramdac.la \
- ddc/libddc.la \
- i2c/libi2c.la \
- dixmods/libxorgxkb.la \
- $(top_builddir)/mi/libmi.la \
- $(top_builddir)/os/libos.la \
- @XORG_LIBS@
-
-libxorg_la_DEPENDENCIES = $(libxorg_la_LIBADD)
-
-libxorg.c xorg.c:
- touch $@
-
-DISTCLEANFILES = libxorg.c xorg.c
-
-Xorg_DEPENDENCIES = libxorg.la
-Xorg_LDADD = $(MAIN_LIB) libxorg.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS)
-
-Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
-
-BUILT_SOURCES = xorg.conf.example
-DISTCLEANFILES += xorg.conf.example
-EXTRA_DIST = xorgconf.cpp
-
-if SPECIAL_DTRACE_OBJECTS
-# Re-add dtrace object code that gets lost when building static libraries
-Xorg_LDADD += $(XSERVER_LIBS)
-endif
-
-if SOLARIS_ASM_INLINE
-# Needs to be built before any files are compiled when using Sun compilers
-# so in*/out* inline definitions are properly processed.
-
-BUILT_SOURCES += os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il
-
-os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il:
- cd os-support/solaris ; \
- $(MAKE) $(AM_MAKEFLAGS) solaris-@SOLARIS_INOUT_ARCH@.il
-endif
-
-# do not use $(mkdir_p) if you want automake 1.7 to work
-install-data-local:
- mkdir -p $(DESTDIR)$(logdir)
-
-
-install-exec-local: install-binPROGRAMS
- (cd $(DESTDIR)$(bindir) && rm -f X && ln -s Xorg X)
-if INSTALL_SETUID
- chown root $(DESTDIR)$(bindir)/Xorg
- chmod u+s $(DESTDIR)$(bindir)/Xorg
-endif
-
-# Use variables from XORG_MANPAGE_SECTIONS and X Server configuration
-# Do not include manpages.am as values are not appropriate for rc files
-CONF_SUBSTS = -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' \
- -e 's|MODULEPATH|$(DEFAULT_MODULE_PATH)|g' \
- -e 's|DEFAULTFONTPATH|$(COMPILEDDEFAULTFONTPATH)|g'
-
-xorg.conf.example: xorgconf.cpp
- $(AM_V_GEN)$(SED) $(CONF_SUBSTS) < $< > $@
-
-relink:
- $(AM_V_at)rm -f Xorg && $(MAKE) Xorg
+
+if DRI
+DRI_SUBDIR = dri
+endif
+
+if DRI2
+DRI2_SUBDIR = dri2
+endif
+
+if XF86UTILS
+XF86UTILS_SUBDIR = utils
+endif
+
+if XAA
+XAA_SUBDIR = xaa
+endif
+
+if VGAHW
+VGAHW_SUBDIR = vgahw
+endif
+
+if VBE
+VBE_SUBDIR = vbe
+endif
+
+if INT10MODULE
+INT10_SUBDIR = int10
+endif
+
+SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \
+ ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \
+ loader dixmods exa modes \
+ $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man
+
+DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
+ parser ramdac shadowfb vbe vgahw xaa \
+ loader dixmods dri dri2 exa modes \
+ utils doc man
+
+bin_PROGRAMS = Xorg
+Xorg_SOURCES = xorg.c
+
+AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
+INCLUDES = @XORG_INCS@
+
+noinst_LTLIBRARIES = libxorg.la
+libxorg_la_SOURCES = libxorg.c
+libxorg_la_LIBADD = \
+ $(XSERVER_LIBS) \
+ loader/libloader.la \
+ os-support/libxorgos.la \
+ common/libcommon.la \
+ parser/libxf86config_internal.la \
+ dixmods/libdixmods.la \
+ modes/libxf86modes.la \
+ ramdac/libramdac.la \
+ ddc/libddc.la \
+ i2c/libi2c.la \
+ dixmods/libxorgxkb.la \
+ $(top_builddir)/mi/libmi.la \
+ $(top_builddir)/os/libos.la \
+ @XORG_LIBS@
+
+libxorg_la_DEPENDENCIES = $(libxorg_la_LIBADD)
+
+libxorg.c xorg.c:
+ touch $@
+
+DISTCLEANFILES = libxorg.c xorg.c
+
+Xorg_DEPENDENCIES = libxorg.la
+Xorg_LDADD = $(MAIN_LIB) libxorg.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS)
+
+Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
+
+BUILT_SOURCES = xorg.conf.example
+DISTCLEANFILES += xorg.conf.example
+EXTRA_DIST = xorgconf.cpp
+
+if SPECIAL_DTRACE_OBJECTS
+# Re-add dtrace object code that gets lost when building static libraries
+Xorg_LDADD += $(XSERVER_LIBS)
+endif
+
+if SOLARIS_ASM_INLINE
+# Needs to be built before any files are compiled when using Sun compilers
+# so in*/out* inline definitions are properly processed.
+
+BUILT_SOURCES += os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il
+
+os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il:
+ cd os-support/solaris ; \
+ $(MAKE) $(AM_MAKEFLAGS) solaris-@SOLARIS_INOUT_ARCH@.il
+endif
+
+# do not use $(mkdir_p) if you want automake 1.7 to work
+install-data-local:
+ mkdir -p $(DESTDIR)$(logdir)
+
+
+install-exec-local: install-binPROGRAMS
+ (cd $(DESTDIR)$(bindir) && rm -f X && ln -s Xorg X)
+if INSTALL_SETUID
+ chown root $(DESTDIR)$(bindir)/Xorg
+ chmod u+s $(DESTDIR)$(bindir)/Xorg
+endif
+
+# Use variables from XORG_MANPAGE_SECTIONS and X Server configuration
+# Do not include manpages.am as values are not appropriate for rc files
+CONF_SUBSTS = -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' \
+ -e 's|MODULEPATH|$(DEFAULT_MODULE_PATH)|g' \
+ -e 's|DEFAULTFONTPATH|$(COMPILEDDEFAULTFONTPATH)|g'
+
+xorg.conf.example: xorgconf.cpp
+ $(AM_V_GEN)$(SED) $(CONF_SUBSTS) < $(srcdir)/xorgconf.cpp > $@
+
+relink:
+ $(AM_V_at)rm -f Xorg && $(MAKE) Xorg
diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c
index 3006ad183..c4a4db9be 100644
--- a/xorg-server/hw/xfree86/common/xf86Events.c
+++ b/xorg-server/hw/xfree86/common/xf86Events.c
@@ -376,7 +376,7 @@ static void
xf86ReleaseKeys(DeviceIntPtr pDev)
{
KeyClassPtr keyc;
- int i, j, nevents, sigstate;
+ int i, sigstate;
if (!pDev || !pDev->key)
return;
@@ -399,9 +399,7 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
i++) {
if (key_is_down(pDev, i, KEY_POSTED)) {
sigstate = xf86BlockSIGIO ();
- nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL);
- for (j = 0; j < nevents; j++)
- mieqEnqueue(pDev, (InternalEvent*)(xf86Events + j)->event);
+ QueueKeyboardEvents(pDev, KeyRelease, i, NULL);
xf86UnblockSIGIO(sigstate);
}
}
diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c
index 0b36163c0..53f763aaf 100644
--- a/xorg-server/hw/xfree86/common/xf86Init.c
+++ b/xorg-server/hw/xfree86/common/xf86Init.c
@@ -806,8 +806,6 @@ InitInput(int argc, char **argv)
mieqInit();
- GetEventList(&xf86Events);
-
/* Initialize all configured input devices */
for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
/* Replace obsolete keyboard driver with kbd */
diff --git a/xorg-server/hw/xfree86/common/xf86Priv.h b/xorg-server/hw/xfree86/common/xf86Priv.h
index 7137a5363..5d91ab367 100644
--- a/xorg-server/hw/xfree86/common/xf86Priv.h
+++ b/xorg-server/hw/xfree86/common/xf86Priv.h
@@ -148,9 +148,6 @@ extern _X_EXPORT int xf86SetVerbosity(int verb);
extern _X_EXPORT int xf86SetLogVerbosity(int verb);
extern _X_EXPORT Bool xf86CallDriverProbe( struct _DriverRec * drv, Bool detect_only );
-/* xf86Xinput.c */
-extern _X_EXPORT EventList *xf86Events;
-
#endif /* _NO_XF86_PROTOTYPES */
diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c
index ef4542c5f..e7e1ce1f0 100644
--- a/xorg-server/hw/xfree86/common/xf86Xinput.c
+++ b/xorg-server/hw/xfree86/common/xf86Xinput.c
@@ -99,8 +99,6 @@
return; \
}
-EventListPtr xf86Events = NULL;
-
static int
xf86InputDevicePostInit(DeviceIntPtr dev);
@@ -329,8 +327,8 @@ xf86ActivateDevice(InputInfoPtr pInfo)
dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL);
if (serverGeneration == 1)
- xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
- pInfo->name, pInfo->type_name);
+ xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s, id %d)\n",
+ pInfo->name, pInfo->type_name, dev->id);
return dev;
}
@@ -1012,7 +1010,6 @@ xf86PostMotionEventM(DeviceIntPtr device,
int is_absolute,
const ValuatorMask *mask)
{
- int i = 0, nevents = 0;
int flags = 0;
if (valuator_mask_num_valuators(mask) > 0)
@@ -1050,11 +1047,7 @@ xf86PostMotionEventM(DeviceIntPtr device,
}
#endif
- nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask);
-
- for (i = 0; i < nevents; i++) {
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
- }
+ QueuePointerEvents(device, MotionNotify, 0, flags, mask);
}
void
@@ -1099,13 +1092,7 @@ xf86PostProximityEventM(DeviceIntPtr device,
int is_in,
const ValuatorMask *mask)
{
- int i, nevents;
-
- nevents = GetProximityEvents(xf86Events, device,
- is_in ? ProximityIn : ProximityOut, mask);
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
+ QueueProximityEvents(device, is_in ? ProximityIn : ProximityOut, mask);
}
void
@@ -1157,7 +1144,6 @@ xf86PostButtonEventM(DeviceIntPtr device,
int is_down,
const ValuatorMask *mask)
{
- int i = 0, nevents = 0;
int flags = 0;
if (valuator_mask_num_valuators(mask) > 0)
@@ -1177,13 +1163,9 @@ xf86PostButtonEventM(DeviceIntPtr device,
}
#endif
- nevents = GetPointerEvents(xf86Events, device,
- is_down ? ButtonPress : ButtonRelease, button,
- flags, mask);
-
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
+ QueuePointerEvents(device,
+ is_down ? ButtonPress : ButtonRelease, button,
+ flags, mask);
}
void
@@ -1235,8 +1217,6 @@ xf86PostKeyEventM(DeviceIntPtr device,
int is_absolute,
const ValuatorMask *mask)
{
- int i = 0, nevents = 0;
-
#if XFreeXDGA
DeviceIntPtr pointer;
@@ -1250,12 +1230,9 @@ xf86PostKeyEventM(DeviceIntPtr device,
}
#endif
- nevents = GetKeyboardEvents(xf86Events, device,
- is_down ? KeyPress : KeyRelease,
- key_code, mask);
-
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+ QueueKeyboardEvents(device,
+ is_down ? KeyPress : KeyRelease,
+ key_code, mask);
}
void
diff --git a/xorg-server/hw/xfree86/doc/Makefile.am b/xorg-server/hw/xfree86/doc/Makefile.am
index acb8937f0..1c3620abb 100644
--- a/xorg-server/hw/xfree86/doc/Makefile.am
+++ b/xorg-server/hw/xfree86/doc/Makefile.am
@@ -1,4 +1,18 @@
-SUBDIRS = devel sgml
-
-EXTRA_DIST = \
- README.modes
+
+if ENABLE_DEVEL_DOCS
+if HAVE_XMLTO
+
+# Main DocBook/XML files (DOCTYPE book)
+docbook = ddxDesign.xml
+
+# Generate DocBook/XML output formats with or without stylesheets
+include $(top_srcdir)/devbook.am
+
+endif HAVE_XMLTO
+endif ENABLE_DEVEL_DOCS
+
+EXTRA_DIST = \
+ Registry \
+ exa-driver.txt \
+ README.DRIcomp \
+ README.modes
diff --git a/xorg-server/hw/xfree86/doc/devel/README.DRIcomp b/xorg-server/hw/xfree86/doc/README.DRIcomp
index 89f40a759..89f40a759 100644
--- a/xorg-server/hw/xfree86/doc/devel/README.DRIcomp
+++ b/xorg-server/hw/xfree86/doc/README.DRIcomp
diff --git a/xorg-server/hw/xfree86/doc/devel/Registry b/xorg-server/hw/xfree86/doc/Registry
index 89a5f10fa..89a5f10fa 100644
--- a/xorg-server/hw/xfree86/doc/devel/Registry
+++ b/xorg-server/hw/xfree86/doc/Registry
diff --git a/xorg-server/hw/xfree86/doc/sgml/DESIGN.xml b/xorg-server/hw/xfree86/doc/ddxDesign.xml
index 13e582877..02909602c 100644
--- a/xorg-server/hw/xfree86/doc/sgml/DESIGN.xml
+++ b/xorg-server/hw/xfree86/doc/ddxDesign.xml
@@ -1,9394 +1,9394 @@
-<?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 &amp; mask == base
- </programlisting>
- and
- <programlisting>
- base &amp; 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 (&gt;8bpp only)
- mask (&gt;8bpp only)
- offset (&gt;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-&gt;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-&gt;ModifyPixmapHeader)(pScrn-&gt;ppix,
- -1, -1, -1, -1, -1, NewApertureAddress);
- </programlisting>
- <blockquote><para>
- where the <structfield>ppix</structfield> field in a ScrnInfoRec
- points to the pixmap used by the screen's
- <function>SaveRestoreImage()</function> function to hold the screen's
- contents while switched out.
- </para>
-
- </blockquote></para></blockquote>
-
- <para>
- Other layers may wrap the <function>ChipEnterVT()</function> and
- <function>ChipLeaveVT()</function> functions if they need to take some
- action when these events are received.
- </para>
- </sect2>
-
- <sect2>
- <title>End of server generation</title>
-
- <para>
- At the end of each server generation, the DIX layer calls
- <function>ChipCloseScreen()</function> for each screen:
- </para>
-
- <blockquote><para>
- <programlisting>
- Bool ChipCloseScreen(int index, ScreenPtr pScreen);
- </programlisting>
- <blockquote><para>
- This function should restore the saved video state and unmap the
- memory regions.
- </para>
-
- <para>
- It should also free per-screen data structures allocated by the
- driver. Note that the persistent data held in the
- <structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield> field
- should not be freed here because it is needed by subsequent server
- generations.
- </para>
-
- <para>
- The <structname>ScrnInfoRec</structname>'s <structfield>vtSema</structfield> field
- should be set to <constant>FALSE</constant> once the video HW state
- has been restored.
- </para>
-
- <para>
- Before freeing the per-screen driver data the saved
- <structfield>CloseScreen</structfield> value should be restored to
- <structfield>pScreen-&gt;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 -&gt; config file -&gt; 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&nbsp;ID&nbsp;&lt;&lt;&nbsp;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&circ;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&nbsp;&lt;&nbsp;C&nbsp;&lt;&nbsp;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-&gt;options</structfield>. This function requires that
- <structfield>pScrn-&gt;confScreen</structfield>, <structfield>pScrn-&gt;display</structfield>,
- <structfield>pScrn-&gt;monitor</structfield>,
- <structfield>pScrn-&gt;numEntities</structfield>, and
- <structfield>pScrn-&gt;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&nbsp;==&nbsp;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>&nbsp;&times;&nbsp;<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-&gt;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-&gt;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&nbsp;&gt;&nbsp;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-&gt;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-&gt;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-&gt;HDisplay</structfield> and
- <structfield>mode-&gt;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&nbsp;&times;&nbsp;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&nbsp;&times;&nbsp;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-&gt;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&nbsp;&gt;&nbsp;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>&lt; 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-&gt;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-&gt;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-&gt;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-&gt;SynthClock = (mode-&gt;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-&gt;numClocks</structfield>,
- and the probed clocks are set in the <structfield>pScrn-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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&nbsp;*&nbsp;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-&gt;paletteEnabled</structfield> in order to
- preserve the palette access state. It should be cleared when
- <structfield>hwp-&gt;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-&gt;paletteEnabled</structfield> in order to
- preserve the palette access state. It should be cleared when
- <structfield>hwp-&gt;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-&gt;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-&gt;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 &lt;version-as-an-int&gt;
-#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 &lt;int&gt;
-#define ZZZ_MINOR_VERSION &lt;int&gt;
-#define ZZZ_PATCHLEVEL &lt;int&gt;
- </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 = { &amp;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(&amp;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-&gt;driverPrivate != NULL)
- return TRUE;
- pScrn-&gt;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)-&gt;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-&gt;driverPrivate == NULL)
- return;
- xfree(pScrn-&gt;driverPrivate);
- pScrn-&gt;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,
- &amp;devSections)) &lt;= 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, &amp;usedChips);
-
- for (i = 0; i &lt; numUsed; i++) {
- ScrnInfoPtr pScrn = NULL;
- if ((pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
- ZZZPciChipsets, NULL, NULL,
- NULL, NULL, NULL))) {
- /* Allocate a ScrnInfoRec */
- pScrn-&gt;driverVersion = VERSION;
- pScrn-&gt;driverName = ZZZ_DRIVER_NAME;
- pScrn-&gt;name = ZZZ_NAME;
- pScrn-&gt;Probe = ZZZProbe;
- pScrn-&gt;PreInit = ZZZPreInit;
- pScrn-&gt;ScreenInit = ZZZScreenInit;
- pScrn-&gt;SwitchMode = ZZZSwitchMode;
- pScrn-&gt;AdjustFrame = ZZZAdjustFrame;
- pScrn-&gt;EnterVT = ZZZEnterVT;
- pScrn-&gt;LeaveVT = ZZZLeaveVT;
- pScrn-&gt;FreeScreen = ZZZFreeScreen;
- pScrn-&gt;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, &amp;usedChips);
- for (i = 0; i &lt; numUsed; i++) {
- ScrnInfoPtr pScrn = NULL;
- if ((pScrn = xf86ConfigIsaEntity(pScrn, flags, usedChips[i],
- ZZZIsaChipsets, NULL, NULL, NULL,
- NULL, NULL))) {
- pScrn-&gt;driverVersion = VERSION;
- pScrn-&gt;driverName = ZZZ_DRIVER_NAME;
- pScrn-&gt;name = ZZZ_NAME;
- pScrn-&gt;Probe = ZZZProbe;
- pScrn-&gt;PreInit = ZZZPreInit;
- pScrn-&gt;ScreenInit = ZZZScreenInit;
- pScrn-&gt;SwitchMode = ZZZSwitchMode;
- pScrn-&gt;AdjustFrame = ZZZAdjustFrame;
- pScrn-&gt;EnterVT = ZZZEnterVT;
- pScrn-&gt;LeaveVT = ZZZLeaveVT;
- pScrn-&gt;FreeScreen = ZZZFreeScreen;
- pScrn-&gt;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-&gt;monitor = pScrn-&gt;confScreen-&gt;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-&gt;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-&gt;depth &lt;= 8) {
- /* Take into account a dac_6_bit option here */
- pScrn-&gt;rgbBits = 6 or 8;
- }
-
- /*
- * xf86SetWeight() and xf86SetDefaultVisual() must be called
- * after pScrn-&gt;display is initialised.
- */
-
- /* Set weight/mask/offset for depth &gt; 8 */
- if (pScrn-&gt;depth &gt; 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-&gt;progClock = TRUE;
-
- /* Allocate the ZZZRec driverPrivate */
- if (!ZZZGetRec(pScrn)) {
- return FALSE;
- }
-
- pZzz = ZZZPTR(pScrn);
-
- /* Collect all of the option flags (fill in pScrn-&gt;options) */
- xf86CollectOptions(pScrn, NULL);
-
- /*
- * Process the options based on the information in ZZZOptions.
- * The results are written to pZzz-&gt;Options. If all of the options
- * processing is done within this function a local variable "options"
- * can be used instead of pZzz-&gt;Options.
- */
- if (!(pZzz-&gt;Options = xalloc(sizeof(ZZZOptions))))
- return FALSE;
- (void)memcpy(pZzz-&gt;Options, ZZZOptions, sizeof(ZZZOptions));
- xf86ProcessOptions(pScrn-&gt;scrnIndex, pScrn-&gt;options, pZzz-&gt;Options);
-
- /*
- * Set various fields of ScrnInfoRec and/or ZZZRec based on
- * the options found.
- */
- from = X_DEFAULT;
- pZzz-&gt;hwCursor = FALSE;
- if (xf86IsOptionSet(pZzz-&gt;Options, OPTION_HW_CURSOR)) {
- from = X_CONFIG;
- pZzz-&gt;hwCursor = TRUE;
- }
- xf86DrvMsg(pScrn-&gt;scrnIndex, from, "Using %s cursor\n",
- pZzz-&gt;hwCursor ? "HW" : "SW");
- if (xf86IsOptionSet(pZzz-&gt;Options, OPTION_NOACCEL)) {
- pZzz-&gt;noAccel = TRUE;
- xf86DrvMsg(pScrn-&gt;scrnIndex, X_CONFIG,
- "Acceleration disabled\n");
- } else {
- pZzz-&gt;noAccel = FALSE;
- }
- if (xf86IsOptionSet(pZzz-&gt;Options, OPTION_PCI_RETRY)) {
- pZzz-&gt;UsePCIRetry = TRUE;
- xf86DrvMsg(pScrn-&gt;scrnIndex, X_CONFIG, "PCI retry enabled\n");
- }
- pZzz-&gt;fooHack = 0;
- if (xf86GetOptValInteger(pZzz-&gt;Options, OPTION_FOO_HACK,
- &amp;pZzz-&gt;fooHack)) {
- xf86DrvMsg(pScrn-&gt;scrnIndex, X_CONFIG, "Foo Hack set to %d\n",
- pZzz-&gt;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-&gt;scrnIndex, &amp;pciList, NULL))
- != 1) {
- print error message;
- ZZZFreeRec(pScrn);
- if (i &gt; 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-&gt;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-&gt;monitor-&gt;Modes,
- pScrn-&gt;display-&gt;modes, clockRanges,
- NULL, minPitch, maxPitch, rounding,
- minHeight, maxHeight,
- pScrn-&gt;display-&gt;virtualX,
- pScrn-&gt;display-&gt;virtualY,
- pScrn-&gt;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-&gt;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-&gt;currentMode = pScrn-&gt;modes;
-
- /* Print the list of modes being used. */
- xf86PrintModes(pScrn);
-
- /* Set the DPI */
- xf86SetDpi(pScrn, 0, 0);
-
- /* Load bpp-specific modules */
- switch (pScrn-&gt;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 &amp;&amp; !xf86LoadSubModule(pScrn, mod))
- ZZZFreeRec(pScrn);
- return FALSE;
-
- /* Load XAA if needed */
- if (!pZzz-&gt;noAccel || pZzz-&gt;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-&gt;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-&gt;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-&gt;currentMode);
-
- /* Set the viewport if supported */
-
- ZZZAdjustFrame(scrnIndex, pScrn-&gt;frameX0, pScrn-&gt;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 &gt; 8, so the default set of visuals isn't
- * acceptable. To deal with this, call miSetVisualTypes with
- * the appropriate visual mask.
- */
-
- if (pScrn-&gt;bitsPerPixel &gt; 8) {
- if (!miSetVisualTypes(pScrn-&gt;depth, TrueColorMask,
- pScrn-&gt;rgbBits, pScrn-&gt;defaultVisual))
- return FALSE;
- } else {
- if (!miSetVisualTypes(pScrn-&gt;depth,
- miGetDefaultVisualMask(pScrn-&gt;depth),
- pScrn-&gt;rgbBits, pScrn-&gt;defaultVisual))
- return FALSE;
- }
-
- /*
- * Initialise the framebuffer.
- */
-
- switch (pScrn-&gt;bitsPerPixel) {
- case 1:
- ret = xf1bppScreenInit(pScreen, FbBase,
- pScrn-&gt;virtualX, pScrn-&gt;virtualY,
- pScrn-&gt;xDpi, pScrn-&gt;yDpi,
- pScrn-&gt;displayWidth);
- break;
- case 4:
- ret = xf4bppScreenInit(pScreen, FbBase,
- pScrn-&gt;virtualX, pScrn-&gt;virtualY,
- pScrn-&gt;xDpi, pScrn-&gt;yDpi,
- pScrn-&gt;displayWidth);
- break;
- case 8:
- ret = cfbScreenInit(pScreen, FbBase,
- pScrn-&gt;virtualX, pScrn-&gt;virtualY,
- pScrn-&gt;xDpi, pScrn-&gt;yDpi,
- pScrn-&gt;displayWidth);
- break;
- case 16:
- ret = cfb16ScreenInit(pScreen, FbBase,
- pScrn-&gt;virtualX, pScrn-&gt;virtualY,
- pScrn-&gt;xDpi, pScrn-&gt;yDpi,
- pScrn-&gt;displayWidth);
- break;
- case 24:
- ret = cfb24ScreenInit(pScreen, FbBase,
- pScrn-&gt;virtualX, pScrn-&gt;virtualY,
- pScrn-&gt;xDpi, pScrn-&gt;yDpi,
- pScrn-&gt;displayWidth);
- break;
- case 32:
- ret = cfb32ScreenInit(pScreen, FbBase,
- pScrn-&gt;virtualX, pScrn-&gt;virtualY,
- pScrn-&gt;xDpi, pScrn-&gt;yDpi,
- pScrn-&gt;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-&gt;bitsPerPixel &gt; 8) {
- for (i = 0, visual = pScreen-&gt;visuals;
- i &lt; pScreen-&gt;numVisuals; i++, visual++) {
- if ((visual-&gt;class | DynamicClass) == DirectColor) {
- visual-&gt;offsetRed = pScrn-&gt;offset.red;
- visual-&gt;offsetGreen = pScrn-&gt;offset.green;
- visual-&gt;offsetBlue = pScrn-&gt;offset.blue;
- visual-&gt;redMask = pScrn-&gt;mask.red;
- visual-&gt;greenMask = pScrn-&gt;mask.green;
- visual-&gt;blueMask = pScrn-&gt;mask.blue;
- }
- }
- }
-
- /*
- * If banking is needed, initialise an miBankInfoRec (defined in
- * "mibank.h"), and call miInitializeBanking().
- */
- if (!miInitializeBanking(pScreen, pScrn-&gt;virtualX, pScrn-&gt;virtualY,
- pScrn-&gt;displayWidth, pBankInfo))
- return FALSE;
-
- /*
- * If backing store is to be supported (as is usually the case),
- * initialise it.
- */
- miInitializeBackingStore(pScreen);
-
- /*
- * Set initial black &amp; 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-&gt;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)-&gt;CloseScreen = pScreen-&gt;CloseScreen;
- pScreen-&gt;CloseScreen = ZZZCloseScreen;
- pScreen-&gt;SaveScreen = ZZZSaveScreen;
-
- /* Report any unused options (only for the first generation) */
- if (serverGeneration == 1) {
- xf86ShowUnusedOptions(pScrn-&gt;scrnIndex, pScrn-&gt;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-&gt;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-&gt;CloseScreen</structfield>, and finishes by
- calling it.
- </para>
-
- <programlisting>
-static Bool
-ZZZCloseScreen(int scrnIndex, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- if (pScrn-&gt;vtSema) {
- ZZZRestore(pScrn);
- ZZZUnmapMem(pScrn);
- }
- pScrn-&gt;vtSema = FALSE;
- pScreen-&gt;CloseScreen = ZZZPTR(pScrn)-&gt;CloseScreen;
- return (*pScreen-&gt;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-&gt;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>
+<?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 id="ddxDesign">
+ <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 &amp; mask == base
+ </programlisting>
+ and
+ <programlisting>
+ base &amp; 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 (&gt;8bpp only)
+ mask (&gt;8bpp only)
+ offset (&gt;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-&gt;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-&gt;ModifyPixmapHeader)(pScrn-&gt;ppix,
+ -1, -1, -1, -1, -1, NewApertureAddress);
+ </programlisting>
+ <blockquote><para>
+ where the <structfield>ppix</structfield> field in a ScrnInfoRec
+ points to the pixmap used by the screen's
+ <function>SaveRestoreImage()</function> function to hold the screen's
+ contents while switched out.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <para>
+ Other layers may wrap the <function>ChipEnterVT()</function> and
+ <function>ChipLeaveVT()</function> functions if they need to take some
+ action when these events are received.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>End of server generation</title>
+
+ <para>
+ At the end of each server generation, the DIX layer calls
+ <function>ChipCloseScreen()</function> for each screen:
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool ChipCloseScreen(int index, ScreenPtr pScreen);
+ </programlisting>
+ <blockquote><para>
+ This function should restore the saved video state and unmap the
+ memory regions.
+ </para>
+
+ <para>
+ It should also free per-screen data structures allocated by the
+ driver. Note that the persistent data held in the
+ <structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield> field
+ should not be freed here because it is needed by subsequent server
+ generations.
+ </para>
+
+ <para>
+ The <structname>ScrnInfoRec</structname>'s <structfield>vtSema</structfield> field
+ should be set to <constant>FALSE</constant> once the video HW state
+ has been restored.
+ </para>
+
+ <para>
+ Before freeing the per-screen driver data the saved
+ <structfield>CloseScreen</structfield> value should be restored to
+ <structfield>pScreen-&gt;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 -&gt; config file -&gt; 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&nbsp;ID&nbsp;&lt;&lt;&nbsp;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&circ;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&nbsp;&lt;&nbsp;C&nbsp;&lt;&nbsp;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-&gt;options</structfield>. This function requires that
+ <structfield>pScrn-&gt;confScreen</structfield>, <structfield>pScrn-&gt;display</structfield>,
+ <structfield>pScrn-&gt;monitor</structfield>,
+ <structfield>pScrn-&gt;numEntities</structfield>, and
+ <structfield>pScrn-&gt;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&nbsp;==&nbsp;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>&nbsp;&times;&nbsp;<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-&gt;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-&gt;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&nbsp;&gt;&nbsp;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-&gt;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-&gt;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-&gt;HDisplay</structfield> and
+ <structfield>mode-&gt;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&nbsp;&times;&nbsp;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&nbsp;&times;&nbsp;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-&gt;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&nbsp;&gt;&nbsp;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>&lt; 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-&gt;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-&gt;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-&gt;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-&gt;SynthClock = (mode-&gt;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-&gt;numClocks</structfield>,
+ and the probed clocks are set in the <structfield>pScrn-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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&nbsp;*&nbsp;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-&gt;paletteEnabled</structfield> in order to
+ preserve the palette access state. It should be cleared when
+ <structfield>hwp-&gt;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-&gt;paletteEnabled</structfield> in order to
+ preserve the palette access state. It should be cleared when
+ <structfield>hwp-&gt;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-&gt;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-&gt;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 &lt;version-as-an-int&gt;
+#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 &lt;int&gt;
+#define ZZZ_MINOR_VERSION &lt;int&gt;
+#define ZZZ_PATCHLEVEL &lt;int&gt;
+ </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 = { &amp;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(&amp;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-&gt;driverPrivate != NULL)
+ return TRUE;
+ pScrn-&gt;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)-&gt;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-&gt;driverPrivate == NULL)
+ return;
+ xfree(pScrn-&gt;driverPrivate);
+ pScrn-&gt;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,
+ &amp;devSections)) &lt;= 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, &amp;usedChips);
+
+ for (i = 0; i &lt; numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+ if ((pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
+ ZZZPciChipsets, NULL, NULL,
+ NULL, NULL, NULL))) {
+ /* Allocate a ScrnInfoRec */
+ pScrn-&gt;driverVersion = VERSION;
+ pScrn-&gt;driverName = ZZZ_DRIVER_NAME;
+ pScrn-&gt;name = ZZZ_NAME;
+ pScrn-&gt;Probe = ZZZProbe;
+ pScrn-&gt;PreInit = ZZZPreInit;
+ pScrn-&gt;ScreenInit = ZZZScreenInit;
+ pScrn-&gt;SwitchMode = ZZZSwitchMode;
+ pScrn-&gt;AdjustFrame = ZZZAdjustFrame;
+ pScrn-&gt;EnterVT = ZZZEnterVT;
+ pScrn-&gt;LeaveVT = ZZZLeaveVT;
+ pScrn-&gt;FreeScreen = ZZZFreeScreen;
+ pScrn-&gt;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, &amp;usedChips);
+ for (i = 0; i &lt; numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+ if ((pScrn = xf86ConfigIsaEntity(pScrn, flags, usedChips[i],
+ ZZZIsaChipsets, NULL, NULL, NULL,
+ NULL, NULL))) {
+ pScrn-&gt;driverVersion = VERSION;
+ pScrn-&gt;driverName = ZZZ_DRIVER_NAME;
+ pScrn-&gt;name = ZZZ_NAME;
+ pScrn-&gt;Probe = ZZZProbe;
+ pScrn-&gt;PreInit = ZZZPreInit;
+ pScrn-&gt;ScreenInit = ZZZScreenInit;
+ pScrn-&gt;SwitchMode = ZZZSwitchMode;
+ pScrn-&gt;AdjustFrame = ZZZAdjustFrame;
+ pScrn-&gt;EnterVT = ZZZEnterVT;
+ pScrn-&gt;LeaveVT = ZZZLeaveVT;
+ pScrn-&gt;FreeScreen = ZZZFreeScreen;
+ pScrn-&gt;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-&gt;monitor = pScrn-&gt;confScreen-&gt;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-&gt;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-&gt;depth &lt;= 8) {
+ /* Take into account a dac_6_bit option here */
+ pScrn-&gt;rgbBits = 6 or 8;
+ }
+
+ /*
+ * xf86SetWeight() and xf86SetDefaultVisual() must be called
+ * after pScrn-&gt;display is initialised.
+ */
+
+ /* Set weight/mask/offset for depth &gt; 8 */
+ if (pScrn-&gt;depth &gt; 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-&gt;progClock = TRUE;
+
+ /* Allocate the ZZZRec driverPrivate */
+ if (!ZZZGetRec(pScrn)) {
+ return FALSE;
+ }
+
+ pZzz = ZZZPTR(pScrn);
+
+ /* Collect all of the option flags (fill in pScrn-&gt;options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /*
+ * Process the options based on the information in ZZZOptions.
+ * The results are written to pZzz-&gt;Options. If all of the options
+ * processing is done within this function a local variable "options"
+ * can be used instead of pZzz-&gt;Options.
+ */
+ if (!(pZzz-&gt;Options = xalloc(sizeof(ZZZOptions))))
+ return FALSE;
+ (void)memcpy(pZzz-&gt;Options, ZZZOptions, sizeof(ZZZOptions));
+ xf86ProcessOptions(pScrn-&gt;scrnIndex, pScrn-&gt;options, pZzz-&gt;Options);
+
+ /*
+ * Set various fields of ScrnInfoRec and/or ZZZRec based on
+ * the options found.
+ */
+ from = X_DEFAULT;
+ pZzz-&gt;hwCursor = FALSE;
+ if (xf86IsOptionSet(pZzz-&gt;Options, OPTION_HW_CURSOR)) {
+ from = X_CONFIG;
+ pZzz-&gt;hwCursor = TRUE;
+ }
+ xf86DrvMsg(pScrn-&gt;scrnIndex, from, "Using %s cursor\n",
+ pZzz-&gt;hwCursor ? "HW" : "SW");
+ if (xf86IsOptionSet(pZzz-&gt;Options, OPTION_NOACCEL)) {
+ pZzz-&gt;noAccel = TRUE;
+ xf86DrvMsg(pScrn-&gt;scrnIndex, X_CONFIG,
+ "Acceleration disabled\n");
+ } else {
+ pZzz-&gt;noAccel = FALSE;
+ }
+ if (xf86IsOptionSet(pZzz-&gt;Options, OPTION_PCI_RETRY)) {
+ pZzz-&gt;UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn-&gt;scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ pZzz-&gt;fooHack = 0;
+ if (xf86GetOptValInteger(pZzz-&gt;Options, OPTION_FOO_HACK,
+ &amp;pZzz-&gt;fooHack)) {
+ xf86DrvMsg(pScrn-&gt;scrnIndex, X_CONFIG, "Foo Hack set to %d\n",
+ pZzz-&gt;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-&gt;scrnIndex, &amp;pciList, NULL))
+ != 1) {
+ print error message;
+ ZZZFreeRec(pScrn);
+ if (i &gt; 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-&gt;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-&gt;monitor-&gt;Modes,
+ pScrn-&gt;display-&gt;modes, clockRanges,
+ NULL, minPitch, maxPitch, rounding,
+ minHeight, maxHeight,
+ pScrn-&gt;display-&gt;virtualX,
+ pScrn-&gt;display-&gt;virtualY,
+ pScrn-&gt;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-&gt;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-&gt;currentMode = pScrn-&gt;modes;
+
+ /* Print the list of modes being used. */
+ xf86PrintModes(pScrn);
+
+ /* Set the DPI */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn-&gt;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 &amp;&amp; !xf86LoadSubModule(pScrn, mod))
+ ZZZFreeRec(pScrn);
+ return FALSE;
+
+ /* Load XAA if needed */
+ if (!pZzz-&gt;noAccel || pZzz-&gt;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-&gt;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-&gt;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-&gt;currentMode);
+
+ /* Set the viewport if supported */
+
+ ZZZAdjustFrame(scrnIndex, pScrn-&gt;frameX0, pScrn-&gt;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 &gt; 8, so the default set of visuals isn't
+ * acceptable. To deal with this, call miSetVisualTypes with
+ * the appropriate visual mask.
+ */
+
+ if (pScrn-&gt;bitsPerPixel &gt; 8) {
+ if (!miSetVisualTypes(pScrn-&gt;depth, TrueColorMask,
+ pScrn-&gt;rgbBits, pScrn-&gt;defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn-&gt;depth,
+ miGetDefaultVisualMask(pScrn-&gt;depth),
+ pScrn-&gt;rgbBits, pScrn-&gt;defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Initialise the framebuffer.
+ */
+
+ switch (pScrn-&gt;bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, FbBase,
+ pScrn-&gt;virtualX, pScrn-&gt;virtualY,
+ pScrn-&gt;xDpi, pScrn-&gt;yDpi,
+ pScrn-&gt;displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, FbBase,
+ pScrn-&gt;virtualX, pScrn-&gt;virtualY,
+ pScrn-&gt;xDpi, pScrn-&gt;yDpi,
+ pScrn-&gt;displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, FbBase,
+ pScrn-&gt;virtualX, pScrn-&gt;virtualY,
+ pScrn-&gt;xDpi, pScrn-&gt;yDpi,
+ pScrn-&gt;displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, FbBase,
+ pScrn-&gt;virtualX, pScrn-&gt;virtualY,
+ pScrn-&gt;xDpi, pScrn-&gt;yDpi,
+ pScrn-&gt;displayWidth);
+ break;
+ case 24:
+ ret = cfb24ScreenInit(pScreen, FbBase,
+ pScrn-&gt;virtualX, pScrn-&gt;virtualY,
+ pScrn-&gt;xDpi, pScrn-&gt;yDpi,
+ pScrn-&gt;displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, FbBase,
+ pScrn-&gt;virtualX, pScrn-&gt;virtualY,
+ pScrn-&gt;xDpi, pScrn-&gt;yDpi,
+ pScrn-&gt;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-&gt;bitsPerPixel &gt; 8) {
+ for (i = 0, visual = pScreen-&gt;visuals;
+ i &lt; pScreen-&gt;numVisuals; i++, visual++) {
+ if ((visual-&gt;class | DynamicClass) == DirectColor) {
+ visual-&gt;offsetRed = pScrn-&gt;offset.red;
+ visual-&gt;offsetGreen = pScrn-&gt;offset.green;
+ visual-&gt;offsetBlue = pScrn-&gt;offset.blue;
+ visual-&gt;redMask = pScrn-&gt;mask.red;
+ visual-&gt;greenMask = pScrn-&gt;mask.green;
+ visual-&gt;blueMask = pScrn-&gt;mask.blue;
+ }
+ }
+ }
+
+ /*
+ * If banking is needed, initialise an miBankInfoRec (defined in
+ * "mibank.h"), and call miInitializeBanking().
+ */
+ if (!miInitializeBanking(pScreen, pScrn-&gt;virtualX, pScrn-&gt;virtualY,
+ pScrn-&gt;displayWidth, pBankInfo))
+ return FALSE;
+
+ /*
+ * If backing store is to be supported (as is usually the case),
+ * initialise it.
+ */
+ miInitializeBackingStore(pScreen);
+
+ /*
+ * Set initial black &amp; 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-&gt;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)-&gt;CloseScreen = pScreen-&gt;CloseScreen;
+ pScreen-&gt;CloseScreen = ZZZCloseScreen;
+ pScreen-&gt;SaveScreen = ZZZSaveScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn-&gt;scrnIndex, pScrn-&gt;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-&gt;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-&gt;CloseScreen</structfield>, and finishes by
+ calling it.
+ </para>
+
+ <programlisting>
+static Bool
+ZZZCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ if (pScrn-&gt;vtSema) {
+ ZZZRestore(pScrn);
+ ZZZUnmapMem(pScrn);
+ }
+ pScrn-&gt;vtSema = FALSE;
+ pScreen-&gt;CloseScreen = ZZZPTR(pScrn)-&gt;CloseScreen;
+ return (*pScreen-&gt;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-&gt;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>
diff --git a/xorg-server/hw/xfree86/doc/devel/Makefile.am b/xorg-server/hw/xfree86/doc/devel/Makefile.am
deleted file mode 100644
index c9eca5eb3..000000000
--- a/xorg-server/hw/xfree86/doc/devel/Makefile.am
+++ /dev/null
@@ -1,7 +0,0 @@
-# Documentation for developers that is distributed with the source but
-# not installed on the system for end-users
-
-EXTRA_DIST = \
- Registry \
- exa-driver.txt \
- README.DRIcomp
diff --git a/xorg-server/hw/xfree86/doc/devel/exa-driver.txt b/xorg-server/hw/xfree86/doc/exa-driver.txt
index 048307ee7..048307ee7 100644
--- a/xorg-server/hw/xfree86/doc/devel/exa-driver.txt
+++ b/xorg-server/hw/xfree86/doc/exa-driver.txt
diff --git a/xorg-server/hw/xfree86/doc/sgml/Makefile.am b/xorg-server/hw/xfree86/doc/sgml/Makefile.am
deleted file mode 100644
index e6661c544..000000000
--- a/xorg-server/hw/xfree86/doc/sgml/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2005 Red Hat, Inc.
-#
-# Permission to use, copy, modify, distribute, and sell this software
-# and its documentation for any purpose is hereby granted without
-# fee, provided that the above copyright notice appear in all copies
-# and that both that copyright notice and this permission notice
-# appear in supporting documentation, and that the name of Red Hat
-# not be used in advertising or publicity pertaining to distribution
-# of the software without specific, written prior permission. Red
-# Hat makes no representations about the suitability of this software
-# for any purpose. It is provided "as is" without express or implied
-# warranty.
-#
-# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
-# NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-doc_sources = DESIGN.xml
-
-# Developer's documentation is not installed
-if ENABLE_DEVEL_DOCS
-include $(top_srcdir)/doc/xml/xmlrules-noinst.in
-endif
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index 5c42a51df..bf7ebb9f8 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/hw/xfree86/dri2/dri2.c
@@ -83,6 +83,7 @@ typedef struct _DRI2Drawable {
CARD64 last_swap_ust; /* ust at completion of most recent swap */
int swap_limit; /* for N-buffering */
unsigned long serialNumber;
+ Bool needInvalidate;
} DRI2DrawableRec, *DRI2DrawablePtr;
typedef struct _DRI2Screen {
@@ -497,6 +498,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
DRI2BufferFrontLeft);
}
+ pPriv->needInvalidate = TRUE;
+
return pPriv->buffers;
err_out:
@@ -540,9 +543,11 @@ DRI2InvalidateDrawable(DrawablePtr pDraw)
DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
DRI2DrawableRefPtr ref;
- if (!pPriv)
+ if (!pPriv || !pPriv->needInvalidate)
return;
+ pPriv->needInvalidate = FALSE;
+
list_for_each_entry(ref, &pPriv->reference_list, link)
ref->invalidate(pDraw, ref->priv);
}