7415 lines
		
	
	
		
			264 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			7415 lines
		
	
	
		
			264 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| <!DOCTYPE linuxdoc PUBLIC "-//Xorg//DTD linuxdoc//EN" [
 | |
|  <!ENTITY % defs SYSTEM "defs.ent"> %defs;
 | |
|  <!-- config file keyword markup -->
 | |
|  <!ENTITY s.key STARTTAG "bf">
 | |
|  <!ENTITY e.key ENDTAG "bf">
 | |
|  <!-- specific config file keywords -->
 | |
|  <!ENTITY k.device "&s.key;Device&e.key;">
 | |
|  <!ENTITY k.monitor "&s.key;Monitor&e.key;">
 | |
|  <!ENTITY k.display "&s.key;Display&e.key;">
 | |
|  <!ENTITY k.inputdevice "&s.key;InputDevice&e.key;">
 | |
|  <!ENTITY k.screen "&s.key;Screen&e.key;">
 | |
|  <!ENTITY k.serverlayout "&s.key;ServerLayout&e.key;">
 | |
|  <!ENTITY k.driver "&s.key;Driver&e.key;">
 | |
|  <!ENTITY k.module "&s.key;Module&e.key;">
 | |
|  <!ENTITY k.identifier "&s.key;Identifier&e.key;">
 | |
|  <!ENTITY k.serverflags "&s.key;ServerFlags&e.key;">
 | |
|  <!-- command line markup -->
 | |
|  <!ENTITY s.cmd STARTTAG "tt">
 | |
|  <!ENTITY e.cmd ENDTAG "tt">
 | |
|  <!-- inline code markup -->
 | |
|  <!ENTITY s.code STARTTAG "tt">
 | |
|  <!ENTITY e.code ENDTAG "tt">
 | |
|  <!-- function indent -->
 | |
|  <!ENTITY f.indent "&nl          ">
 | |
| ] >
 | |
| 
 | |
| <article>
 | |
| 
 | |
| <title>XFree86 server 4.x Design (DRAFT)
 | |
| <author>The XFree86 Project, Inc
 | |
| <and>Updates for X11R&relvers; by Jim Gettys
 | |
| <date>19 December 2003
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| <ident>
 | |
| $XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DESIGN.sgml,v 1.53 2003/08/23 14:10:14 dawes Exp $
 | |
| </ident>
 | |
| 
 | |
| 
 | |
| <p>
 | |
| <bf>NOTE</bf>: This is a DRAFT document, and the interfaces described here
 | |
| are subject to change without notice.
 | |
| 
 | |
| 
 | |
| <sect>Preface
 | |
| <p>
 | |
| 
 | |
| The broad design principles are:
 | |
| <itemize>
 | |
|   <item>keep it reasonable
 | |
| 	<itemize>
 | |
| 	  <item>We cannot rewrite the complete server
 | |
| 	  <item>We don't want to re-invent the wheel
 | |
| 	</itemize>
 | |
|   <item>keep it modular
 | |
| 	<itemize>
 | |
| 	  <item>As many things as possible should go into modules
 | |
| 	  <item>The basic loader binary should be minimal
 | |
| 	  <item>A clean design with well defined layering is important
 | |
| 	  <item>DDX specific global variables are a nono
 | |
| 	  <item>The structure should be flexible enough to allow
 | |
| 		future extensions
 | |
| 	  <item> The structure should minimize duplication of common code
 | |
| 	</itemize>
 | |
|   <item>keep important features in mind
 | |
| 	<itemize>
 | |
| 	  <item>multiple screens, including multiple instances of drivers
 | |
| 	  <item>mixing different color depths and visuals on different
 | |
| 		and ideally even on the same screen
 | |
| 	  <item>better control of the PCI device used
 | |
| 	  <item>better config file parser
 | |
| 	  <item>get rid of all VGA compatibility assumptions
 | |
| 	</itemize>
 | |
| </itemize>
 | |
| 
 | |
| Unless we find major deficiencies in the DIX layer, we should avoid
 | |
| making changes there.
 | |
| 
 | |
| <sect>The xorg.conf File
 | |
| <p>
 | |
| 
 | |
| The xorg.conf file format is similar to the old format, with the following
 | |
| changes:
 | |
| 
 | |
| <sect1>&k.device; section
 | |
| <p>
 | |
| 
 | |
|     The &k.device; sections are similar to what they used to be, and
 | |
|     describe hardware-specific information for a single video card.
 | |
|     &k.device;
 | |
|     Some new keywords are added:
 | |
| 
 | |
| 
 | |
|     <descrip>
 | |
|       <tag>Driver "drivername"</tag>
 | |
|         Specifies the name of the driver to be used for the card.  This
 | |
|         is mandatory.
 | |
|       <tag>BusID "busslot"</tag>
 | |
|         Specifies uniquely the location of the card on the bus.  The
 | |
|         purpose is to identify particular cards in a multi-headed
 | |
|         configuration.  The format of the argument is intentionally
 | |
|         vague, and may be architecture dependent.  For a PCI bus, it
 | |
|         is something like "bus:slot:func".
 | |
|     </descrip>
 | |
| 
 | |
|     A &k.device; section is considered ``active'' if there is a reference
 | |
|     to it in an active &k.screen; section.
 | |
| 
 | |
| <sect1>&k.screen; section
 | |
| <p>
 | |
| 
 | |
|     The &k.screen; sections are similar to what they used to be.  They
 | |
|     no longer have a &k.driver; keyword, but an &k.identifier; keyword
 | |
|     is added.  (The &k.driver; keyword may be accepted in place of the
 | |
|     &k.identifier; keyword for compatibility purposes.)  The identifier
 | |
|     can be used to identify which screen is to be active when multiple
 | |
|     &k.screen sections are present.  It is possible to specify the active
 | |
|     screen from the command line.  A default is chosen in the absence
 | |
|     of one being specified.  A &k.screen; section is considered ``active''
 | |
|     if there is a reference to it either from the command line, or from
 | |
|     an active &k.serverlayout; section.
 | |
| 
 | |
| <sect1>&k.inputdevice; section
 | |
| <p>
 | |
| 
 | |
|     The &k.inputdevice; section is a new section that describes
 | |
|     configuration information for input devices.  It replaces the old
 | |
|     &s.key;Keyboard&e.key;, &s.key;Pointer&e.key; and &s.key;XInput&e.key;
 | |
|     sections.  Like the &k.device; section, it has two mandatory keywords:
 | |
|     &k.identifier; and &k.driver;.  For compatibility purposes the old
 | |
|     &s.key;Keyboard&e.key; and &s.key;Pointer&e.key; sections are
 | |
|     converted by the parser into &k.inputdevice; sections as follows:
 | |
| 
 | |
|     <descrip>
 | |
|       <tag>&s.key;Keyboard&e.key;</tag>
 | |
|              &k.identifier; "Implicit Core Keyboard"<newline>
 | |
|              &k.driver; "keyboard"
 | |
|       <tag>&s.key;Pointer&e.key;</tag>
 | |
|              &k.identifier; "Implicit Core Pointer"<newline>
 | |
|              &k.driver; "mouse"
 | |
|     </descrip>
 | |
| 
 | |
|     An &k.inputdevice; section is considered active if there is a
 | |
|     reference to it in an active &k.serverlayout; section.  An
 | |
|     &k.inputdevice; section may also be referenced implicitly if there
 | |
|     is no &k.serverlayout; section, if the &s.cmd;-screen&e.cmd; command
 | |
|     line options is used, or if the &k.serverlayout; section doesn't
 | |
|     reference any &k.inputdevice; sections.  In this case, the first
 | |
|     sections with drivers "keyboard" and "mouse" are used as the core
 | |
|     keyboard and pointer respectively.
 | |
| 
 | |
| <sect1>&k.serverlayout; section
 | |
| <p>
 | |
| 
 | |
|     The &k.serverlayout; section is a new section that is used to identify
 | |
|     which &k.screen; sections are to be used in a multi-headed configuration,
 | |
|     and the relative layout of those screens.  It also identifies which
 | |
|     &k.inputdevice; sections are to be used.  Each &k.serverlayout section
 | |
|     has an identifier, a list of &k.screen; section identifiers, and a list of
 | |
|     &k.inputdevice; section identifiers.  &k.serverflags; options may also be
 | |
|     included in a &k.serverlayout; section, making it possible to override
 | |
|     the global values in the &k.serverflags; section.
 | |
| 
 | |
|     A &k.serverlayout; section can be made active by being referenced on
 | |
|     the command line.  In the absence of this, a default will be chosen
 | |
|     (the first one found).  The screen names may optionally be followed
 | |
|     by a number specifying the preferred screen number, and optionally
 | |
|     by information specifying the physical positioning of the screen,
 | |
|     either in absolute terms or relative to another screen (or screens).
 | |
|     When no screen number is specified, they are numbered according to
 | |
|     the order in which they are listed.  The old (now obsolete) method
 | |
|     of providing the positioning information is to give the names of
 | |
|     the four adjacent screens.  The order of these is top, bottom, left,
 | |
|     right.  Here is an example of a &k.serverlayout; section for two
 | |
|     screens using the old method, with the second located to the right
 | |
|     of the first:
 | |
| 
 | |
|     <code>
 | |
|       Section "ServerLayout"
 | |
|         Identifier "Main Layout"
 | |
|         Screen     0 "Screen 1" ""  ""  ""  "Screen 2"
 | |
|         Screen     1 "Screen 2"
 | |
|         Screen     "Screen 3"
 | |
|       EndSection
 | |
|     </code>
 | |
| 
 | |
|     The preferred way of specifying the layout is to explicitly specify
 | |
|     the screen's location in absolute terms or relative to another
 | |
|     screen.
 | |
| 
 | |
|     In the absolute case, the upper left corner's coordinates are given
 | |
|     after the &s.key;Absolute&e.key; keyword.  If the coordinates are
 | |
|     omitted, a value of &s.code;(0,0)&e.code; is assumed.  An example
 | |
|     of absolute positioning follows:
 | |
| 
 | |
|     <code>
 | |
|       Section "ServerLayout"
 | |
|         Identifier "Main Layout"
 | |
|         Screen     0 "Screen 1" Absolute 0 0
 | |
|         Screen     1 "Screen 2" Absolute 1024 0
 | |
|         Screen     "Screen 3" Absolute 2048 0
 | |
|       EndSection
 | |
|     </code>
 | |
| 
 | |
|     In the relative case, the position is specified by either using one of
 | |
|     the following keywords followed by the name of the reference screen:
 | |
| 
 | |
|     <quote>
 | |
|       &s.key;RightOf&nl;
 | |
|       LeftOf&nl;
 | |
|       Above&nl;
 | |
|       Below&nl;
 | |
|       Relative&e.key;
 | |
|     </quote>
 | |
| 
 | |
|     When the &s.key;Relative&e.key; keyword is used, the reference screen
 | |
|     name is followed by the coordinates of the new screen's origin
 | |
|     relative to reference screen.  The following example shows how to use
 | |
|     some of the relative positioning options.
 | |
| 
 | |
|     <code>
 | |
|       Section "ServerLayout"
 | |
|         Identifier "Main Layout"
 | |
|         Screen     0 "Screen 1"
 | |
|         Screen     1 "Screen 2" RightOf "Screen 1"
 | |
|         Screen     "Screen 3" Relative "Screen 1" 2048 0
 | |
|       EndSection
 | |
|     </code>
 | |
| 
 | |
| <sect1>Options
 | |
| <p>
 | |
| 
 | |
|     Options are used more extensively.  They may appear in most sections
 | |
|     now.  Options related to drivers can be present in the &k.screen;,
 | |
|     &k.device; and &k.monitor; sections and the &k.display; subsections.
 | |
|     The order of precedence is &k.display;, &k.screen;, &k.monitor;,
 | |
|     &k.device;.  Options have been extended to allow an optional value
 | |
|     to be specified in addition to the option name.  For more details
 | |
|     about options, see the <ref id="options" name="Options"> section
 | |
|     for details.
 | |
| 
 | |
| <sect>Driver Interface
 | |
| <p>
 | |
| 
 | |
| The driver interface consists of a minimal set of entry points that are
 | |
| required based on the external events that the driver must react to.
 | |
| No non-essential structure is imposed on the way they are used beyond
 | |
| that.  This is a significant difference compared with the old design.
 | |
| 
 | |
| The entry points for drawing operations are already taken care of by
 | |
| the framebuffer code (including, XAA).  Extensions and enhancements to
 | |
| framebuffer code are outside the scope of this document.
 | |
| 
 | |
| This approach to the driver interface provides good flexibility, but does
 | |
| increase the complexity of drivers.  To help address this, the XFree86
 | |
| common layer provides a set of ``helper'' functions to take care of things
 | |
| that most drivers need.  These helpers help minimise the amount of code
 | |
| duplication between drivers.  The use of helper functions by drivers is
 | |
| however optional, though encouraged.  The basic philosophy behind the
 | |
| helper functions is that they should be useful to many drivers, that
 | |
| they should balance this against the complexity of their interface.  It
 | |
| is inevitable that some drivers may find some helpers unsuitable and
 | |
| need to provide their own code.
 | |
| 
 | |
| Events that a driver needs to react to are:
 | |
| 
 | |
|    <descrip>
 | |
|    <tag>ScreenInit</tag>
 | |
| 
 | |
|      An initialisation function is called from the DIX layer for each
 | |
|      screen at the start of each server generation.
 | |
| 
 | |
|    <tag>Enter VT</tag>
 | |
| 
 | |
|      The server takes control of the console.
 | |
| 
 | |
|    <tag>Leave VT</tag>
 | |
| 
 | |
|      The server releases control of the console.
 | |
| 
 | |
|    <tag>Mode Switch</tag>
 | |
| 
 | |
|      Change video mode.
 | |
| 
 | |
|    <tag>ViewPort change</tag>
 | |
| 
 | |
|      Change the origin of the physical view port.
 | |
| 
 | |
|    <tag>ScreenSaver state change</tag>
 | |
| 
 | |
|      Screen saver activation/deactivation.
 | |
| 
 | |
|    <tag>CloseScreen</tag>
 | |
| 
 | |
|      A close screen function is called from the DIX layer for each screen
 | |
|      at the end of each server generation.
 | |
|    </descrip>
 | |
| 
 | |
| 
 | |
| In addition to these events, the following functions are required by
 | |
| the XFree86 common layer:
 | |
| 
 | |
|    <descrip>
 | |
|    <tag>Identify</tag>
 | |
| 
 | |
|      Print a driver identifying message.
 | |
| 
 | |
|    <tag>Probe</tag>
 | |
| 
 | |
|      This is how a driver identifies if there is any hardware present that
 | |
|      it knows how to drive.
 | |
| 
 | |
|    <tag>PreInit</tag>
 | |
| 
 | |
|      Process information from the xorg.conf file, determine the
 | |
|      full characteristics of the hardware, and determine if a valid
 | |
|      configuration is present.
 | |
|    </descrip>
 | |
| 
 | |
| The VidMode extension also requires:
 | |
| 
 | |
|    <descrip>
 | |
|    <tag>ValidMode</tag>
 | |
| 
 | |
|      Identify if a new mode is usable with the current configuration.
 | |
|      The PreInit function (and/or helpers it calls) may also make use
 | |
|      of the ValidMode function or something similar.
 | |
|    </descrip>
 | |
| 
 | |
| 
 | |
| Other extensions may require other entry points.  The drivers will
 | |
| inform the common layer of these in such cases.
 | |
| 
 | |
| <sect>Resource Access Control Introduction
 | |
| <p>
 | |
| 
 | |
| Graphics devices are accessed through ranges in I/O or memory space.
 | |
| While most modern graphics devices allow relocation of such ranges many
 | |
| of them still require the use of well established interfaces such as
 | |
| VGA memory and IO ranges or 8514/A IO ranges.  With modern buses (like
 | |
| PCI) it is possible for multiple video devices to share access to these
 | |
| resources.  The RAC (Resource Access Control) subsystem provides a
 | |
| mechanism for this.
 | |
| 
 | |
| <sect1>Terms and Definitions
 | |
| <p>
 | |
| 
 | |
| <sect2>Bus
 | |
| <p>
 | |
| 
 | |
|     ``Bus'' is ambiguous as it is used for different things: it may refer
 | |
|     to physical incompatible extension connectors in a computer system.
 | |
|     The RAC system knows two such systems: The ISA bus and the PCI bus.
 | |
|     (On the software level EISA, MCA and VL buses are currently treated
 | |
|     like ISA buses).  ``Bus'' may also refer to logically different
 | |
|     entities on a single bus system which are connected via bridges.  A
 | |
|     PCI system may have several distinct PCI buses connecting each other
 | |
|     by PCI-PCI bridges or to the host CPU by HOST-PCI bridges.
 | |
| 
 | |
|     Systems that host more than one bus system link these together using
 | |
|     bridges.  Bridges are a concern to RAC as they might block or pass
 | |
|     specific resources.  PCI-PCI bridges may be set up to pass VGA
 | |
|     resources to the secondary bus.  PCI-ISA buses pass any resources not
 | |
|     decoded on the primary PCI bus to the ISA bus.  This way VGA resources
 | |
|     (although exclusive on the ISA bus) can be shared by ISA and PCI
 | |
|     cards.  Currently HOST-PCI bridges are not yet handled by RAC as they
 | |
|     require specific drivers.
 | |
| 
 | |
| <sect2>Entity
 | |
| <p>
 | |
| 
 | |
|     The smallest independently addressable unit on a system bus is
 | |
|     referred to as an entity.  So far we know ISA and PCI entities.  PCI
 | |
|     entities can be located on the PCI bus by an unique ID consisting of
 | |
|     the bus, card and function number.
 | |
| 
 | |
| <sect2>Resource
 | |
| <p>
 | |
| 
 | |
|     ``Resource'' refers to a range of memory or I/O addresses an entity
 | |
|     can decode.
 | |
| 
 | |
|     If a device is capable of disabling this decoding the resource is
 | |
|     called sharable.  For PCI devices a generic method is provided to
 | |
|     control resource decoding.  Other devices will have to provide a
 | |
|     device specific function to control decoding.
 | |
| 
 | |
|     If the entity is capable of decoding this range at a different
 | |
|     location this resource is considered relocatable.
 | |
| 
 | |
|     Resources which start at a specific address and occupy a single
 | |
|     continuous range are called block resources.
 | |
| 
 | |
|     Alternatively resource addresses can be decoded in a way that they
 | |
|     satisfy the conditions:
 | |
|     <quote><verb>
 | |
|                     address & mask == base
 | |
|     </verb></quote>
 | |
|     and
 | |
|     <quote><verb>
 | |
|                        base & mask == base
 | |
|     </verb></quote>
 | |
|     Resources addressed in such a way are called sparse resources.
 | |
| 
 | |
| <sect2>Server States
 | |
| <p>
 | |
| 
 | |
|     The resource access control system knows two server states: the
 | |
|     SETUP and the OPERATING state.  The SETUP state is entered whenever
 | |
|     a mode change takes place or the server exits or does VT switching.
 | |
|     During this state all entity resources are under resource access
 | |
|     control.  During OPERATING state only those entities are controlled
 | |
|     which actually have shared resources that conflict with others.
 | |
| 
 | |
| <sect>Control Flow in the Server and Mandatory Driver Functions
 | |
| <p>
 | |
| 
 | |
| At the start of each server generation, &s.code;main()&e.code;
 | |
| (&s.code;dix/main.c&e.code;) calls the DDX function
 | |
| &s.code;InitOutput()&e.code;.  This is the first place that the DDX gets
 | |
| control.  &s.code;InitOutput()&e.code; is expected to fill in the global
 | |
| &s.code;screenInfo&e.code; struct, and one
 | |
| &s.code;screenInfo.screen[]&e.code; entry for each screen present.  Here
 | |
| is what &s.code;InitOutput()&e.code; does:
 | |
| 
 | |
| <sect1>Parse the xorg.conf file
 | |
| <p>
 | |
| 
 | |
|     This is done at the start of the first server generation only.
 | |
| 
 | |
|     The xorg.conf file is read in full, and the resulting information
 | |
|     stored in data structures.  None of the parsed information is
 | |
|     processed at this point.  The parser data structures are opaque to
 | |
|     the video drivers and to most of the common layer code.
 | |
| 
 | |
|     The entire file is parsed first to remove any section ordering
 | |
|     requirements.
 | |
| 
 | |
| 
 | |
| <sect1>Initial processing of parsed information and command line options
 | |
| <p>
 | |
| 
 | |
|     This is done at the start of the first server generation only.
 | |
| 
 | |
|     The initial processing is to determine paths like the
 | |
|     &s.key;ModulePath&e.key;, etc, and to determine which &k.serverlayout;,
 | |
|     &k.screen; and &k.device; sections are active.
 | |
| 
 | |
| 
 | |
| <sect1>Enable port I/O access
 | |
| <p>
 | |
| 
 | |
|     Port I/O access is controlled from the XFree86 common layer, and is
 | |
|     ``all or nothing''.  It is enabled prior to calling driver probes, at
 | |
|     the start of subsequent server generations, and when VT switching
 | |
|     back to the Xserver.  It is disabled at the end of server generations,
 | |
|     and when VT switching away from the Xserver.
 | |
| 
 | |
|     The implementation details of this may vary on different platforms.
 | |
| 
 | |
| 
 | |
| <sect1>General bus probe
 | |
| <p>
 | |
| 
 | |
|     This is done at the start of the first server generation only.
 | |
| 
 | |
|     In the case of ix86 machines, this will be a general PCI probe.
 | |
|     The full information obtained here will be available to the drivers.
 | |
|     This information persists for the life of the Xserver.  In the PCI
 | |
|     case, the PCI information for all video cards found is available by
 | |
|     calling &s.code;xf86GetPciVideoInfo()&e.code;.
 | |
| 
 | |
|     <quote>
 | |
|     &s.code;pciVideoPtr *xf86GetPciVideoInfo(void)&e.code;
 | |
|     <quote><p>
 | |
| 	returns a pointer to a list of pointers to
 | |
| 	&s.code;pciVideoRec&e.code; entries, of which there is one for
 | |
| 	each detected PCI video card.  The list is terminated with a
 | |
| 	&s.code;NULL&e.code; pointer.  If no PCI video cards were
 | |
| 	detected, the return value is &s.code;NULL&e.code;.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
|     After the bus probe, the resource broker is initialised.
 | |
| 
 | |
| 
 | |
| <sect1>Load initial set of modules
 | |
| <p>
 | |
| 
 | |
|     This is done at the start of the first server generation only.
 | |
| 
 | |
|     The core server contains a list of mandatory modules.  These are loaded
 | |
|     first.  Currently the only module on this list is the bitmap font module.
 | |
| 
 | |
|     The next set of modules loaded are those specified explicitly in the
 | |
|     &k.module; section of the config file.
 | |
| 
 | |
|     The final set of initial modules are the driver modules referenced
 | |
|     by the active &k.device; and &k.inputdevice; sections in the config
 | |
|     file.  Each of these modules is loaded exactly once.
 | |
| 
 | |
| 
 | |
| <sect1>Register Video and Input Drivers
 | |
| <p>
 | |
| 
 | |
|     This is done at the start of the first server generation only.
 | |
| 
 | |
|     When a driver module is loaded, the loader calls its
 | |
|     &s.code;Setup&e.code; function.  For video drivers, this function
 | |
|     calls &s.code;xf86AddDriver()&e.code; to register the driver's
 | |
|     &s.code;DriverRec&e.code;, which contains a small set of essential
 | |
|     details and driver entry points required during the early phase of
 | |
|     &s.code;InitOutput()&e.code;.  &s.code;xf86AddDriver()&e.code; adds
 | |
|     it to the global &s.code;xf86DriverList[]&e.code; array.
 | |
| 
 | |
|     The &s.code;DriverRec&e.code; contains the driver canonical name,
 | |
|     the &s.code;Identify()&e.code;,
 | |
|     &s.code;Probe()&e.code; and &s.code;AvailableOptions()&e.code;
 | |
|     function entry points as well as a pointer
 | |
|     to the driver's module (as returned from the loader when the driver
 | |
|     was loaded) and a reference count which keeps track of how many
 | |
|     screens are using the driver.  The entry driver entry points are
 | |
|     those required prior to the driver allocating and filling in its
 | |
|     &s.code;ScrnInfoRec&e.code;.
 | |
| 
 | |
|     For a static server, the &s.code;xf86DriverList[]&e.code; array is
 | |
|     initialised at build time, and the loading of modules is not done.
 | |
| 
 | |
|     A similar procedure is used for input drivers.  The input driver's
 | |
|     &s.code;Setup&e.code; function calls
 | |
|     &s.code;xf86AddInputDriver()&e.code; to register the driver's
 | |
|     &s.code;InputDriverRec&e.code;, which contains a small set of
 | |
|     essential details and driver entry points required during the early
 | |
|     phase of &s.code;InitInput()&e.code;.
 | |
|     &s.code;xf86AddInputDriver()&e.code; adds it to the global
 | |
|     &s.code;xf86InputDriverList[]&e.code; array.  For a static server,
 | |
|     the &s.code;xf86InputDriverList[]&e.code; array is initialised at
 | |
|     build time.
 | |
| 
 | |
|     Both the &s.code;xf86DriverList[]&e.code; and
 | |
|     &s.code;xf86InputDriverList[]&e.code; arrays have been initialised
 | |
|     by the end of this stage.
 | |
| 
 | |
|     Once all the drivers are registered, their
 | |
|     &s.code;ChipIdentify()&e.code; functions are called.
 | |
| 
 | |
|     <quote>
 | |
|     &s.code;void ChipIdentify(int flags)&e.code;
 | |
|     <quote>
 | |
|       This is expected to print a message indicating the driver name,
 | |
|       a short summary of what it supports, and a list of the chipset
 | |
|       names that it supports.  It may use the xf86PrintChipsets() helper
 | |
|       to do this.
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
|     <quote>
 | |
|     &s.code;void xf86PrintChipsets(const char *drvname, const char *drvmsg,
 | |
|                      &f.indent;SymTabPtr chips)&e.code;
 | |
|     <quote>
 | |
|       This function provides an easy way for a driver's ChipIdentify
 | |
|       function to format the identification message.
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect1>Initialise Access Control
 | |
| <p>
 | |
| 
 | |
|     This is done at the start of the first server generation only.
 | |
| 
 | |
|     The Resource Access Control (RAC) subsystem is initialised before
 | |
|     calling any driver functions that may access hardware.  All generic
 | |
|     bus information is probed and saved (for restoration later).  All
 | |
|     (shared resource) video devices are disabled at the generic bus
 | |
|     level, and a probe is done to find the ``primary'' video device.  These
 | |
|     devices remain disabled for the next step.
 | |
| 
 | |
| 
 | |
| <sect1>Video Driver Probe<label id="probe">
 | |
| <p>
 | |
|     This is done at the start of the first server generation only.  The
 | |
|     &s.code;ChipProbe()&e.code; function of each registered video driver
 | |
|     is called.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool ChipProbe(DriverPtr drv, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       The purpose of this is to identify all instances of hardware
 | |
|       supported by the driver.  The flags value is currently either 0,
 | |
|       &s.code;PROBE_DEFAULT&e.code; or &s.code;PROBE_DETECT&e.code;.
 | |
|       &s.code;PROBE_DETECT&e.code; is used if "-configure" or "-probe"
 | |
|       command line arguments are given and indicates to the
 | |
|       &s.code;Probe()&e.code; function that it should not configure the
 | |
|       bus entities and that no xorg.conf information is available.
 | |
| 
 | |
|       The probe must find the active device sections that match the
 | |
|       driver by calling &s.code;xf86MatchDevice()&e.code;.  The number
 | |
|       of matches found limits the maximum number of instances for this
 | |
|       driver.  If no matches are found, the function should return
 | |
|       &s.code;FALSE&e.code; immediately.
 | |
| 
 | |
|       Devices that cannot be identified by using device-independent
 | |
|       methods should be probed at this stage (keeping in mind that access
 | |
|       to all resources that can be disabled in a device-independent way
 | |
|       are disabled during this phase).  The probe must be a minimal
 | |
|       probe.  It should just determine if there is a card present that
 | |
|       the driver can drive.  It should use the least intrusive probe
 | |
|       methods possible.  It must not do anything that is not essential,
 | |
|       like probing for other details such as the amount of memory
 | |
|       installed, etc.  It is recommended that the
 | |
|       &s.code;xf86MatchPciInstances()&e.code; helper function be used
 | |
|       for identifying matching PCI devices, and similarly the
 | |
|       &s.code;xf86MatchIsaInstances()&e.code; for ISA (non-PCI) devices
 | |
|       (see the <ref id="rac" name="RAC"> section).  These helpers also
 | |
|       checks and claims the appropriate entity.  When not using the
 | |
|       helper, that should be done with &s.code;xf86CheckPciSlot()&e.code;
 | |
|       and &s.code;xf86ClaimPciSlot()&e.code; for PCI devices and
 | |
|       &s.code;xf86ClaimIsaSlot()&e.code; for ISA devices (see the
 | |
|       <ref id="rac" name="RAC"> section).
 | |
| 
 | |
|       The probe must register all non-relocatable resources at this
 | |
|       stage.  If a resource conflict is found between exclusive resources
 | |
|       the driver will fail immediately.  This is usually best done with
 | |
|       the &s.code;xf86ConfigPciEntity()&e.code; helper function
 | |
|       for PCI and &s.code;xf86ConfigIsaEntity()&e.code; for ISA
 | |
|       (see the <ref id="rac" name="RAC"> section).  It is possible to
 | |
|       register some entity specific functions with those helpers.  When
 | |
|       not using the helpers, the &s.code;xf86AddEntityToScreen()&e.code;
 | |
|       &s.code;xf86ClaimFixedResources()&e.code; and
 | |
|       &s.code;xf86SetEntityFuncs()&e.code; should be used instead (see
 | |
|       the <ref id="rac" name="RAC"> section).
 | |
| 
 | |
|       If a chipset is specified in an active device section which the
 | |
|       driver considers relevant (ie it has no driver specified, or the
 | |
|       driver specified matches the driver doing the probe), the Probe
 | |
|       must return &s.code;FALSE&e.code; if the chipset doesn't match
 | |
|       one supported by the driver.
 | |
| 
 | |
|       If there are no active device sections that the driver considers
 | |
|       relevant, it must return &s.code;FALSE&e.code;.
 | |
| 
 | |
|       Allocate a &s.code;ScrnInfoRec&e.code; for each active instance of the
 | |
|       hardware found, and fill in the basic information, including the
 | |
|       other driver entry points.   This is best done with the
 | |
|       &s.code;xf86ConfigIsaEntity()&e.code; helper function for ISA
 | |
|       instances or &s.code;xf86ConfigPciEntity()&e.code; for PCI instances.
 | |
|       These functions allocate a &s.code;ScrnInfoRec&e.code; for active
 | |
|       entities. Optionally &s.code;xf86AllocateScreen()&e.code;
 | |
|       function may also be used to allocate the &s.code;ScrnInfoRec&e.code;.
 | |
|       Any of these functions take care of initialising fields to defined
 | |
|       ``unused'' values.
 | |
| 
 | |
|       Claim the entities for each instance of the hardware found.  This
 | |
|       prevents other drivers from claiming the same hardware.
 | |
| 
 | |
|       Must leave hardware in the same state it found it in, and must not
 | |
|       do any hardware initialisation.
 | |
| 
 | |
|       All detection can be overridden via the config file, and that
 | |
|       parsed information is available to the driver at this stage.
 | |
| 
 | |
|       Returns &s.code;TRUE&e.code; if one or more instances are found,
 | |
|       and &s.code;FALSE&e.code; otherwise.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;int xf86MatchDevice(const char *drivername,
 | |
| 		&f.indent;GDevPtr **driversectlist)&e.code;
 | |
|     <quote><p>
 | |
| 
 | |
|       This function takes the name of the driver and returns via
 | |
|       &s.code;driversectlist&e.code; a list of device sections that
 | |
|       match the driver name.  The function return value is the number
 | |
|       of matches found.  If a fatal error is encountered the return
 | |
|       value is &s.code;-1&e.code;.
 | |
| 
 | |
|       The caller should use &s.code;xfree()&e.code; to free
 | |
|       &s.code;*driversectlist&e.code; when it is no longer needed.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       This function allocates a new &s.code;ScrnInfoRec&e.code; in the
 | |
|       &s.code;xf86Screens[]&e.code; array.  This function is normally
 | |
|       called by the video driver &s.code;ChipProbe()&e.code; functions.
 | |
|       The return value is a pointer to the newly allocated
 | |
|       &s.code;ScrnInfoRec&e.code;.  The &s.code;scrnIndex&e.code;,
 | |
|       &s.code;origIndex&e.code;, &s.code;module&e.code; and
 | |
|       &s.code;drv&e.code; fields are initialised.  The reference count
 | |
|       in &s.code;drv&e.code; is incremented.  The storage for any
 | |
|       currently allocated ``privates'' pointers is also allocated and
 | |
|       the &s.code;privates&e.code; field initialised (the privates data
 | |
|       is of course not allocated or initialised).  This function never
 | |
|       returns on failure.  If the allocation fails, the server exits
 | |
|       with a fatal error.  The flags value is not currently used, and
 | |
|       should be set to zero.
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
|     At the completion of this, a list of &s.code;ScrnInfoRecs&e.code;
 | |
|     have been allocated in the &s.code;xf86Screens[]&e.code; array, and
 | |
|     the associated entities and fixed resources have been claimed.  The
 | |
|     following &s.code;ScrnInfoRec&e.code; fields must be initialised at
 | |
|     this point:
 | |
| 
 | |
|     <quote><verb>
 | |
|           driverVersion
 | |
|           driverName
 | |
|           scrnIndex(*)
 | |
|           origIndex(*)
 | |
|           drv(*)
 | |
|           module(*)
 | |
|           name
 | |
|           Probe
 | |
|           PreInit
 | |
|           ScreenInit
 | |
|           EnterVT
 | |
|           LeaveVT
 | |
|           numEntities
 | |
|           entityList
 | |
|           access
 | |
|     </verb></quote>
 | |
| 
 | |
|     <tt>(*)</tt> These are initialised when the &s.code;ScrnInfoRec&e.code;
 | |
|     is allocated, and not explicitly by the driver.
 | |
| 
 | |
|     The following &s.code;ScrnInfoRec&e.code; fields must be initialised
 | |
|     if the driver is going to use them:
 | |
| 
 | |
|     <quote><verb>
 | |
|           SwitchMode
 | |
|           AdjustFrame
 | |
|           FreeScreen
 | |
|           ValidMode
 | |
|     </verb></quote>
 | |
| 
 | |
| <sect1>Matching Screens
 | |
| <p>
 | |
| 
 | |
|     This is done at the start of the first server generation only.
 | |
| 
 | |
|     After the Probe phase is finished, there will be some number of
 | |
|     &s.code;ScrnInfoRecs&e.code;.  These are then matched with the active
 | |
|     &k.screen; sections in the xorg.conf, and those not having an active
 | |
|     &k.screen; section are deleted.  If the number of remaining screens
 | |
|     is 0, &s.code;InitOutput()&e.code; sets
 | |
|     &s.code;screenInfo.numScreens&e.code; to &s.code;0&e.code; and
 | |
|     returns.
 | |
| 
 | |
|     At this point the following fields of the &s.code;ScrnInfoRecs&e.code;
 | |
|     must be initialised:
 | |
| 
 | |
|     <quote><verb>
 | |
|           confScreen
 | |
|     </verb></quote>
 | |
| 
 | |
| 
 | |
| <sect1>Allocate non-conflicting resources
 | |
| <p>
 | |
| 
 | |
|     This is done at the start of the first server generation only.
 | |
| 
 | |
|     Before calling the drivers again, the resource information collected
 | |
|     from the Probe phase is processed.  This includes checking the extent
 | |
|     of PCI resources for the probed devices, and resolving any conflicts
 | |
|     in the relocatable PCI resources.  It also reports conflicts, checks
 | |
|     bus routing issues, and anything else that is needed to enable the
 | |
|     entities for the next phase.
 | |
| 
 | |
|     If any drivers registered an &s.code;EntityInit()&e.code; function
 | |
|     during the Probe phase, then they are called here.
 | |
| 
 | |
| 
 | |
| <sect1>Sort the Screens and pre-check Monitor Information
 | |
| <p>
 | |
| 
 | |
|     This is done at the start of the first server generation only.
 | |
| 
 | |
|     The list of screens is sorted to match the ordering requested in the
 | |
|     config file.
 | |
| 
 | |
|     The list of modes for each active monitor is checked against the
 | |
|     monitor's parameters.  Invalid modes are pruned.
 | |
| 
 | |
| 
 | |
| <sect1>PreInit
 | |
| <p>
 | |
| 
 | |
|     This is done at the start of the first server generation only.
 | |
| 
 | |
|     For each &s.code;ScrnInfoRec&e.code;, enable access to the screens entities and call
 | |
|     the &s.code;ChipPreInit()&e.code; function.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool ChipPreInit(ScrnInfoRec screen, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       The purpose of this function is to find out all the information
 | |
|       required to determine if the configuration is usable, and to
 | |
|       initialise those parts of the &s.code;ScrnInfoRec&e.code; that
 | |
|       can be set once at the beginning of the first server generation.
 | |
| 
 | |
|       The number of entities registered for the screen should be checked
 | |
|       against the expected number (most drivers expect only one).  The
 | |
|       entity information for each of them should be retrieved (with
 | |
|       &s.code;xf86GetEntityInfo()&e.code;) and checked for the correct
 | |
|       bus type and that none of the sharable resources registered during
 | |
|       the Probe phase was rejected.
 | |
| 
 | |
|       Access to resources for the entities that can be controlled in a
 | |
|       device-independent way are enabled before this function is called.
 | |
|       If the driver needs to access any resources that it has disabled
 | |
|       in an &s.code;EntityInit()&e.code; function that it registered,
 | |
|       then it may enable them here providing that it disables them before
 | |
|       this function returns.
 | |
| 
 | |
|       This includes probing for video memory, clocks, ramdac, and all
 | |
|       other HW info that is needed.  It includes determining the
 | |
|       depth/bpp/visual and related info.  It includes validating and
 | |
|       determining the set of video modes that will be used (and anything
 | |
|       that is required to determine that).
 | |
| 
 | |
|       This information should be determined in the least intrusive way
 | |
|       possible.  The state of the HW must remain unchanged by this
 | |
|       function.  Although video memory (including MMIO) may be mapped
 | |
|       within this function, it must be unmapped before returning.  Driver
 | |
|       specific information should be stored in a structure hooked into
 | |
|       the &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code;
 | |
|       field.  Any other modules which require persistent data (ie data
 | |
|       that persists across server generations) should be initialised in
 | |
|       this function, and they should allocate a ``privates'' index to
 | |
|       hook their data into by calling
 | |
|       &s.code;xf86AllocateScrnInfoPrivateIndex().&e.code;  The ``privates''
 | |
|       data is persistent.
 | |
| 
 | |
|       Helper functions for some of these things are provided at the
 | |
|       XFree86 common level, and the driver can choose to make use of
 | |
|       them.
 | |
| 
 | |
|       All additional resources that the screen needs must be registered
 | |
|       here.  This should be done with
 | |
|       &s.code;xf86RegisterResources()&e.code;.  If some of the fixed
 | |
|       resources registered in the Probe phase are not needed or not
 | |
|       decoded by the hardware when in the OPERATING server state, their
 | |
|       status should be updated with
 | |
|       &s.code;xf86SetOperatingState()&e.code;.
 | |
| 
 | |
|       Modules may be loaded at any point in this function, and all
 | |
|       modules that the driver will need must be loaded before the end
 | |
|       of this function.  Either the  &s.code;xf86LoadSubModule()&e.code;
 | |
|       or the &s.code;xf86LoadDrvSubModule()&e.code; function should be
 | |
|       used to load modules depending on whether a
 | |
|       &s.code;ScrnInfoRec&e.code; has been set up. A driver may unload
 | |
|       a module within this function if it was only needed temporarily,
 | |
|       and the &s.code;xf86UnloadSubModule()&e.code; function should be used
 | |
|       to do that.  Otherwise there is no need to explicitly unload modules
 | |
|       because the loader takes care of module dependencies and will
 | |
|       unload submodules automatically if/when the driver module is
 | |
|       unloaded.
 | |
| 
 | |
|       The bulk of the &s.code;ScrnInfoRec&e.code; fields should be filled
 | |
|       out in this function.
 | |
| 
 | |
|       &s.code;ChipPreInit()&e.code; returns &s.code;FALSE&e.code; when
 | |
|       the configuration is unusable in some way (unsupported depth, no
 | |
|       valid modes, not enough video memory, etc), and &s.code;TRUE&e.code;
 | |
|       if it is usable.
 | |
| 
 | |
|       It is expected that if the &s.code;ChipPreInit()&e.code; function
 | |
|       returns &s.code;TRUE&e.code;, then the only reasons that subsequent
 | |
|       stages in the driver might fail are lack or resources (like xalloc
 | |
|       failures).  All other possible reasons for failure should be
 | |
|       determined by the &s.code;ChipPreInit()&e.code; function.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
|     The &s.code;ScrnInfoRecs&e.code; for screens where the &s.code;ChipPreInit()&e.code; fails are removed.
 | |
|     If none remain, &s.code;InitOutput()&e.code; sets &s.code;screenInfo.numScreens&e.code; to &s.code;0&e.code; and returns.
 | |
| 
 | |
|     At this point, further fields of the &s.code;ScrnInfoRecs&e.code; would normally be
 | |
|     filled in.  Most are not strictly mandatory, but many are required
 | |
|     by other layers and/or helper functions that the driver may choose
 | |
|     to use.  The documentation for those layers and helper functions
 | |
|     indicates which they require.
 | |
| 
 | |
|     The following fields of the &s.code;ScrnInfoRecs&e.code; should be filled in if the
 | |
|     driver is going to use them:
 | |
| 
 | |
|     <quote><verb>
 | |
|           monitor
 | |
|           display
 | |
|           depth
 | |
|           pixmapBPP
 | |
|           bitsPerPixel
 | |
|           weight                (>8bpp only)
 | |
|           mask                  (>8bpp only)
 | |
|           offset                (>8bpp only)
 | |
|           rgbBits               (8bpp only)
 | |
|           gamma
 | |
|           defaultVisual
 | |
|           maxHValue
 | |
|           maxVValue
 | |
|           virtualX
 | |
|           virtualY
 | |
|           displayWidth
 | |
|           frameX0
 | |
|           frameY0
 | |
|           frameX1
 | |
|           frameY1
 | |
|           zoomLocked
 | |
|           modePool
 | |
|           modes
 | |
|           currentMode
 | |
|           progClock             (TRUE if clock is programmable)
 | |
|           chipset
 | |
|           ramdac
 | |
|           clockchip
 | |
|           numClocks             (if not programmable)
 | |
|           clock[]               (if not programmable)
 | |
|           videoRam
 | |
|           biosBase
 | |
|           memBase
 | |
|           memClk
 | |
|           driverPrivate
 | |
|           chipID
 | |
|           chipRev
 | |
|     </verb></quote>
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)&e.code:
 | |
|       and
 | |
|     &s.code;pointer xf86LoadDrvSubModule(DriverPtr drv, const char *name)&e.code:
 | |
|     <quote><p>
 | |
|       Load a module that a driver depends on.  This function loads the
 | |
|       module &s.code;name&e.code; as a sub module of the driver.  The
 | |
|       return value is a handle identifying the new module.  If the load
 | |
|       fails, the return value will be &s.code;NULL&e.code;.  If a driver
 | |
|       needs to explicitly unload a module it has loaded in this way,
 | |
|       the return value must be saved and passed to
 | |
|       &s.code;xf86UnloadSubModule()&e.code; when unloading.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86UnloadSubModule(pointer module)&e.code;
 | |
|     <quote><p>
 | |
|       Unloads the module referenced by &s.code;module&e.code;.
 | |
|       &s.code;module&e.code; should be a pointer returned previously
 | |
|       by &s.code;xf86LoadSubModule()&e.code; or
 | |
|       &s.code;xf86LoadDrvSubModule()&e.code; .
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect1>Cleaning up Unused Drivers
 | |
| <p>
 | |
| 
 | |
|     At this point it is known which screens will be in use, and which
 | |
|     drivers are being used.  Unreferenced drivers (and modules they
 | |
|     may have loaded) are unloaded here.
 | |
| 
 | |
| 
 | |
| <sect1>Consistency Checks
 | |
| <p>
 | |
| 
 | |
|     The parameters that must be global to the server, like pixmap formats,
 | |
|     bitmap bit order, bitmap scanline unit and image byte order are
 | |
|     compared for each of the screens.  If a mismatch is found, the server
 | |
|     exits with an appropriate message.
 | |
| 
 | |
| 
 | |
| <sect1>Check if Resource Control is Needed
 | |
| <p>
 | |
| 
 | |
|     Determine if resource access control is needed.  This is the case
 | |
|     if more than one screen is used.  If necessary the RAC wrapper module
 | |
|     is loaded.
 | |
| 
 | |
| <sect1>AddScreen (ScreenInit)
 | |
| <p>
 | |
| 
 | |
|     At this point, the valid screens are known.
 | |
|     &s.code;AddScreen()&e.code; is called for each of them, passing
 | |
|     &s.code;ChipScreenInit()&e.code; as the argument.
 | |
|     &s.code;AddScreen()&e.code; is a DIX function that allocates a new
 | |
|     &s.code;screenInfo.screen[]&e.code; entry (aka
 | |
|     &s.code;pScreen&e.code;), and does some basic initialisation of it.
 | |
|     It then calls the &s.code;ChipScreenInit()&e.code; function, with
 | |
|     &s.code;pScreen&e.code; as one of its arguments.  If
 | |
|     &s.code;ChipScreenInit()&e.code; returns &s.code;FALSE&e.code;,
 | |
|     &s.code;AddScreen()&e.code; returns &s.code;-1&e.code;.  Otherwise
 | |
|     it returns the index of the screen.  &s.code;AddScreen()&e.code;
 | |
|     should only fail because of programming errors or failure to allocate
 | |
|     resources (like memory).  All configuration problems should be
 | |
|     detected BEFORE this point.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool ChipScreenInit(int index, ScreenPtr pScreen,
 | |
| 	&f.indent;int argc, char **argv)&e.code;
 | |
|     <quote><p>
 | |
|       This is called at the start of each server generation.
 | |
| 
 | |
|       Fill in all of &s.code;pScreen&e.code;, possibly doing some of
 | |
|       this by calling ScreenInit functions from other layers like mi,
 | |
|       framebuffers (cfb, etc), and extensions.
 | |
| 
 | |
|       Decide which operations need to be placed under resource access
 | |
|       control.  The classes of operations are the frame buffer operations
 | |
|       (&s.code;RAC_FB&e.code;), the pointer operations
 | |
|       (&s.code;RAC_CURSOR&e.code;), the viewport change operations
 | |
|       (&s.code;RAC_VIEWPORT&e.code;) and the colormap operations
 | |
|       (&s.code;RAC_COLORMAP&e.code;).  Any operation that requires
 | |
|       resources which might be disabled during OPERATING state should
 | |
|       be set to use RAC.  This can be specified separately for memory
 | |
|       and IO resources (the &s.code;racMemFlags&e.code; and
 | |
|       &s.code;racIoFlags&e.code; fields of the &s.code;ScrnInfoRec&e.code;
 | |
|       respectively).
 | |
| 
 | |
|       Map any video memory or other memory regions.
 | |
| 
 | |
|       Save the video card state.  Enough state must be saved so that
 | |
|       the original state can later be restored.
 | |
| 
 | |
|       Initialise the initial video mode.  The &s.code;ScrnInfoRec&e.code;'s
 | |
|       &s.code;vtSema&e.code; field should be set to &s.code;TRUE&e.code;
 | |
|       just prior to changing the video hardware's state.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
|     The &s.code;ChipScreenInit()&e.code; function (or functions from other
 | |
|     layers that it calls) should allocate entries in the
 | |
|     &s.code;ScreenRec&e.code;'s &s.code;devPrivates&e.code; area by
 | |
|     calling &s.code;AllocateScreenPrivateIndex()&e.code; if it needs
 | |
|     per-generation storage.  Since the &s.code;ScreenRec&e.code;'s
 | |
|     &s.code;devPrivates&e.code; information is cleared for each server
 | |
|     generation, this is the correct place to initialise it.
 | |
| 
 | |
|     After &s.code;AddScreen()&e.code; has successfully returned, the
 | |
|     following &s.code;ScrnInfoRec&e.code; fields are initialised:
 | |
| 
 | |
|     <quote><verb>
 | |
|           pScreen
 | |
|           racMemFlags
 | |
|           racIoFlags
 | |
|     </verb></quote>
 | |
| 
 | |
|     The &s.code;ChipScreenInit()&e.code; function should initialise the
 | |
|     &s.code;CloseScreen&e.code; and &s.code;SaveScreen&e.code; fields
 | |
|     of &s.code;pScreen&e.code;.  The old value of
 | |
|     &s.code;pScreen->CloseScreen&e.code; should be saved as part of
 | |
|     the driver's per-screen private data, allowing it to be called from
 | |
|     &s.code;ChipCloseScreen()&e.code;.  This means that the existing
 | |
|     &s.code;CloseScreen()&e.code; function is wrapped.
 | |
| 
 | |
| <sect1>Finalising RAC Initialisation
 | |
| <p>
 | |
| 
 | |
|     After all the &s.code;ChipScreenInit()&e.code; functions have been
 | |
|     called, each screen has registered its RAC requirements.  This
 | |
|     information is used to determine which shared resources are requested
 | |
|     by more than one driver and set the access functions accordingly.
 | |
|     This is done following these rules:
 | |
| 
 | |
|     <enum>
 | |
|      <item>The sharable resources registered by each entity are compared.
 | |
| 	If a resource is registered by more than one entity the entity
 | |
| 	will be marked to indicate that it needs to share this resources
 | |
| 	type (IO or MEM).
 | |
| 
 | |
|      <item>A resource marked ``disabled'' during OPERATING state will be
 | |
|         ignored entirely.
 | |
| 
 | |
|      <item>A resource marked ``unused'' will only conflict with an overlapping
 | |
| 	resource of an other entity if the second is actually in use
 | |
| 	during OPERATING state.
 | |
| 
 | |
|      <item>If an ``unused'' resource was found to conflict but the entity
 | |
| 	does not use any other resource of this type the entire resource
 | |
| 	type will be disabled for that entity.
 | |
|     </enum>
 | |
| 
 | |
| 
 | |
| <sect1>Finishing InitOutput()
 | |
| <p>
 | |
| 
 | |
|     At this point &s.code;InitOutput()&e.code; is finished, and all the
 | |
|     screens have been setup in their initial video mode.
 | |
| 
 | |
| 
 | |
| <sect1>Mode Switching
 | |
| <p>
 | |
| 
 | |
|     When a SwitchMode event is received, &s.code;ChipSwitchMode()&e.code;
 | |
|     is called (when it exists):
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool ChipSwitchMode(int index, DisplayModePtr mode, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       Initialises the new mode for the screen identified by
 | |
|       &s.code;index;&e.code;.  The viewport may need to be adjusted
 | |
|       also.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
| <sect1>Changing Viewport
 | |
| <p>
 | |
| 
 | |
|     When a Change Viewport event is received,
 | |
|     &s.code;ChipAdjustFrame()&e.code; is called (when it exists):
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;void ChipAdjustFrame(int index, int x, int y, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       Changes the viewport for the screen identified by
 | |
|       &s.code;index;&e.code;.
 | |
| 
 | |
|       It should be noted that many chipsets impose restrictions on where the
 | |
|       viewport may be placed in the virtual resolution, either for alignment
 | |
|       reasons, or to prevent the start of the viewport from being positioned
 | |
|       within a pixel (as can happen in a 24bpp mode).  After calculating the
 | |
|       value the chipset's panning registers need to be set to for non-DGA
 | |
|       modes, this function should recalculate the ScrnInfoRec's
 | |
|       &s.code;frameX0&e.code;, &s.code;frameY0&e.code, &s.code;frameX1&e.code;
 | |
|       and &s.code;frameY1&e.code; fields to correspond to that value.  If
 | |
|       this is not done, switching to another mode might cause the position
 | |
|       of a hardware cursor to change.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
| <sect1>VT Switching
 | |
| <p>
 | |
| 
 | |
|     When a VT switch event is received, &s.code;xf86VTSwitch()&e.code;
 | |
|     is called.  &s.code;xf86VTSwitch()&e.code; does the following:
 | |
| 
 | |
|     <descrip>
 | |
|     <tag>On ENTER:</tag>
 | |
|     <itemize>
 | |
|       <item>enable port I/O access
 | |
| 
 | |
|       <item>save and initialise the bus/resource state
 | |
| 
 | |
|       <item>enter the SETUP server state
 | |
| 
 | |
|       <item>calls &s.code;ChipEnterVT()&e.code; for each screen
 | |
| 
 | |
|       <item>enter the OPERATING server state
 | |
| 
 | |
|       <item>validate GCs
 | |
| 
 | |
|       <item>Restore fb from saved pixmap for each screen
 | |
| 
 | |
|       <item>Enable all input devices
 | |
|     </itemize>
 | |
|     <tag>On LEAVE:</tag>
 | |
|     <itemize>
 | |
|       <item>Save fb to pixmap for each screen
 | |
| 
 | |
|       <item>validate GCs
 | |
| 
 | |
|       <item>enter the SETUP server state
 | |
| 
 | |
|       <item>calls &s.code;ChipLeaveVT()&e.code; for each screen
 | |
| 
 | |
|       <item>disable all input devices
 | |
| 
 | |
|       <item>restore bus/resource state
 | |
| 
 | |
|       <item>disables port I/O access
 | |
|     </itemize>
 | |
|     </descrip>
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool ChipEnterVT(int index, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       This function should initialise the current video mode and
 | |
|       initialise the viewport, turn on the HW cursor if appropriate,
 | |
|       etc.
 | |
| 
 | |
|       Should it re-save the video state before initialising the video
 | |
|       mode?
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void ChipLeaveVT(int index, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       This function should restore the saved video state.  If
 | |
|       appropriate it should also turn off the HW cursor, and invalidate
 | |
|       any pixmap/font caches.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     Optionally, &s.code;ChipLeaveVT()&e.code; may also unmap memory
 | |
|     regions.  If so, &s.code;ChipEnterVT()&e.code; will need to remap
 | |
|     them.  Additionally, if an aperture used to access video memory is
 | |
|     unmapped and remapped in this fashion, &s.code;ChipEnterVT()&e.code;
 | |
|     will also need to notify the framebuffer layers of the aperture's new
 | |
|     location in virtual memory.  This is done with a call to the screen's
 | |
|     &s.code;ModifyPixmapHeader()&e.code; function, as follows
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;(*pScreen->ModifyPixmapHeader)(pScrn->ppix,
 | |
|         &f.indent;-1, -1, -1, -1, -1, <it>NewApertureAddress</it>);&e.code;
 | |
|     <quote><p>
 | |
|         where the &s.code``ppix''&e.code; field in a ScrnInfoRec
 | |
|         points to the pixmap used by the screen's
 | |
|         &s.code;SaveRestoreImage()&e.code; function to hold the screen's
 | |
|         contents while switched out.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
|     Currently, aperture remapping, as described here, should not be
 | |
|     attempted if the driver uses the &s.code;xf8_16bpp&e.code; or
 | |
|     &s.code;xf8_32bpp&e.code; framebuffer layers.  A pending
 | |
|     restructuring of VT switching will address this restriction in
 | |
|     the near future.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     Other layers may wrap the &s.code;ChipEnterVT()&e.code; and
 | |
|     &s.code;ChipLeaveVT()&e.code; functions if they need to take some
 | |
|     action when these events are received.
 | |
| 
 | |
| <sect1>End of server generation
 | |
| <p>
 | |
| 
 | |
|     At the end of each server generation, the DIX layer calls
 | |
|     &s.code;ChipCloseScreen()&e.code; for each screen:
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool ChipCloseScreen(int index, ScreenPtr pScreen)&e.code;
 | |
|     <quote><p>
 | |
|       This function should restore the saved video state and unmap the
 | |
|       memory regions.
 | |
| 
 | |
|       It should also free per-screen data structures allocated by the
 | |
|       driver.  Note that the persistent data held in the
 | |
|       &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field
 | |
|       should not be freed here because it is needed by subsequent server
 | |
|       generations.
 | |
| 
 | |
|       The &s.code;ScrnInfoRec&e.code;'s &s.code;vtSema&e.code; field
 | |
|       should be set to &s.code;FALSE&e.code; once the video HW state
 | |
|       has been restored.
 | |
| 
 | |
|       Before freeing the per-screen driver data the saved
 | |
|       &s.code;CloseScreen&e.code; value should be restored to
 | |
|       &s.code;pScreen->CloseScreen&e.code;, and that function should
 | |
|       be called after freeing the data.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect>Optional Driver Functions
 | |
| <p>
 | |
| 
 | |
| The functions outlined here can be called from the XFree86 common layer,
 | |
| but their presence is optional.
 | |
| 
 | |
| <sect1>Mode Validation
 | |
| <p>
 | |
| 
 | |
|     When a mode validation helper supplied by the XFree86-common layer is
 | |
|     being used, it can be useful to provide a function to check for hw
 | |
|     specific mode constraints:
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;ModeStatus ChipValidMode(int index, DisplayModePtr mode,
 | |
|                    &f.indent;Bool verbose, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       Check the passed mode for hw-specific constraints, and return the
 | |
|       appropriate status value.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <p>
 | |
| This function may also modify the effective timings and clock of the passed
 | |
| mode.  These have been stored in the mode's &s.code;Crtc*&e.code; and
 | |
| &s.code;SynthClock&e.code; elements, and have already been adjusted for
 | |
| interlacing, doublescanning, multiscanning and clock multipliers and dividers.
 | |
| The function should not modify any other mode field, unless it wants to modify
 | |
| the mode timings reported to the user by &s.code;xf86PrintModes()&e.code;.
 | |
| 
 | |
| <p>
 | |
| The function is called once for every mode in the xorg.conf Monitor section
 | |
| assigned to the screen, with &s.code;flags&e.code; set to
 | |
| &s.code;MODECHECK_INITIAL&e.code;.  It is subsequently called for every mode
 | |
| in the xorg.conf Display subsection assigned to the screen, with
 | |
| &s.code;flags&e.code; set to &s.code;MODECHECK_FINAL&e.code;.  In the second
 | |
| case, the mode will have successfully passed all other tests.  In addition,
 | |
| the &s.code;ScrnInfoRec&e.code;'s &s.code;virtualX&e.code;,
 | |
| &s.code;virtualY&e.code; and &s.code;displayWidth&e.code; fields will have been
 | |
| set as if the mode to be validated were to be the last mode accepted.
 | |
| 
 | |
| <p>
 | |
| In effect, calls with MODECHECK_INITIAL are intended for checks that do not
 | |
| depend on any mode other than the one being validated, while calls with
 | |
| MODECHECK_FINAL are intended for checks that may involve more than one mode.
 | |
| 
 | |
| <sect1>Free screen data
 | |
| <p>
 | |
| 
 | |
|     When a screen is deleted prior to the completion of the ScreenInit
 | |
|     phase the &s.code;ChipFreeScreen()&e.code; function is called when defined.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;void ChipFreeScreen(int scrnindex, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       Free any driver-allocated data that may have been allocated up to
 | |
|       and including an unsuccessful &s.code;ChipScreenInit()&e.code;
 | |
|       call.  This would predominantly be data allocated by
 | |
|       &s.code;ChipPreInit()&e.code; that persists across server
 | |
|       generations.  It would include the &s.code;driverPrivate&e.code;,
 | |
|       and any ``privates'' entries that modules may have allocated.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
| <sect>Recommended driver functions
 | |
| <p>
 | |
| 
 | |
| The functions outlined here are for internal use by the driver only.
 | |
| They are entirely optional, and are never accessed directly from higher
 | |
| layers.  The sample function declarations shown here are just examples.
 | |
| The interface (if any) used is up to the driver.
 | |
| 
 | |
| <sect1>Save
 | |
| <p>
 | |
| 
 | |
|     Save the video state.  This could be called from &s.code;ChipScreenInit()&e.code; and
 | |
|     (possibly) &s.code;ChipEnterVT()&e.code;.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;void ChipSave(ScrnInfoPtr pScrn)&e.code;
 | |
|     <quote><p>
 | |
|       Saves the current state.  This will only be saving pre-server
 | |
|       states or states before returning to the server.  There is only
 | |
|       one current saved state per screen and it is stored in private
 | |
|       storage in the screen.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect1>Restore
 | |
| <p>
 | |
| 
 | |
|     Restore the original video state.  This could be called from the
 | |
|     &s.code;ChipLeaveVT()&e.code; and &s.code;ChipCloseScreen()&e.code;
 | |
|     functions.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;void ChipRestore(ScrnInfoPtr pScrn)&e.code;
 | |
|     <quote><p>
 | |
|       Restores the saved state from the private storage.  Usually only
 | |
|       used for restoring text modes.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
| <sect1>Initialise Mode
 | |
| <p>
 | |
| 
 | |
|     Initialise a video mode.  This could be called from the
 | |
|     &s.code;ChipScreenInit()&e.code;, &s.code;ChipSwitchMode()&e.code;
 | |
|     and &s.code;ChipEnterVT()&e.code; functions.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool ChipModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)&e.code;
 | |
|     <quote><p>
 | |
|       Programs the hardware for the given video mode.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
| <sect>Data and Data Structures
 | |
| <p>
 | |
| 
 | |
| <sect1>Command line data
 | |
| <p>
 | |
| 
 | |
| Command line options are typically global, and are stored in global
 | |
| variables.  These variables are read-only and are available to drivers
 | |
| via a function call interface.  Most of these command line values are
 | |
| processed via helper functions to ensure that they are treated consistently
 | |
| by all drivers.  The other means of access is provided for cases where
 | |
| the supplied helper functions might not be appropriate.
 | |
| 
 | |
| Some of them are:
 | |
| 
 | |
| <quote><verb>
 | |
|     xf86Verbose               verbosity level
 | |
|     xf86Bpp                   -bpp from the command line
 | |
|     xf86Depth                 -depth from the command line
 | |
|     xf86Weight                -weight from the command line
 | |
|     xf86Gamma                 -{r,g,b,}gamma from the command line
 | |
|     xf86FlipPixels            -flippixels from the command line
 | |
|     xf86ProbeOnly             -probeonly from the command line
 | |
|     defaultColorVisualClass   -cc from the command line
 | |
| </verb></quote>
 | |
| 
 | |
| If we ever do allow for screen-specific command line options, we may
 | |
| need to rethink this.
 | |
| 
 | |
| These can be accessed in a read-only manner by drivers with the following
 | |
| functions:
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;int xf86GetVerbosity()&e.code;
 | |
|     <quote><p>
 | |
|       Returns the value of &s.code;xf86Verbose&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;int xf86GetDepth()&e.code;
 | |
|     <quote><p>
 | |
|       Returns the &s.cmd;-depth&e.cmd; command line setting.  If not
 | |
|       set on the command line, &s.code;-1&e.code; is returned.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;rgb xf86GetWeight()&e.code;
 | |
|     <quote><p>
 | |
|       Returns the &s.cmd;-weight&e.cmd; command line setting.  If not
 | |
|       set on the command line, &s.code;{0, 0, 0}&e.code; is returned.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Gamma xf86GetGamma()&e.code;
 | |
|     <quote><p>
 | |
|       Returns the &s.cmd;-gamma&e.cmd; or &s.cmd;-rgamma&e.cmd;,
 | |
|       &s.cmd;-ggamma&e.cmd;, &s.cmd;-bgamma&e.cmd; command line settings.
 | |
|       If not set on the command line, &s.code;{0.0, 0.0, 0.0}&e.code;
 | |
|       is returned.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86GetFlipPixels()&e.code;
 | |
|     <quote><p>
 | |
|       Returns &s.code;TRUE&e.code; if &s.cmd;-flippixels&e.cmd; is
 | |
|       present on the command line, and &s.code;FALSE&e.code; otherwise.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;const char *xf86GetServerName()&e.code;
 | |
|     <quote><p>
 | |
|       Returns the name of the X server from the command line.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect1>Data handling
 | |
| <p>
 | |
| 
 | |
| Config file data contains parts that are global, and parts that are
 | |
| Screen specific.  All of it is parsed into data structures that neither
 | |
| the drivers or most other parts of the server need to know about.
 | |
| 
 | |
| The global data is typically not required by drivers, and as such, most
 | |
| of it is stored in the private &s.code;xf86InfoRec&e.code;.
 | |
| 
 | |
| The screen-specific data collected from the config file is stored in
 | |
| screen, device, display, monitor-specific data structures that are separate
 | |
| from the &s.code;ScrnInfoRecs&e.code;, with the appropriate elements/fields
 | |
| hooked into the &s.code;ScrnInfoRecs&e.code; as required.  The screen
 | |
| config data is held in &s.code;confScreenRec&e.code;, device data in
 | |
| the &s.code;GDevRec&e.code;, monitor data in the &s.code;MonRec&e.code;,
 | |
| and display data in the &s.code;DispRec&e.code;.
 | |
| 
 | |
| The XFree86 common layer's screen specific data (the actual data in use
 | |
| for each screen) is held in the &s.code;ScrnInfoRecs&e.code;.  As has
 | |
| been outlined above, the &s.code;ScrnInfoRecs&e.code; are allocated at probe
 | |
| time, and it is the responsibility of the Drivers' &s.code;Probe()&e.code;
 | |
| and &s.code;PreInit()&e.code; functions to finish filling them in based
 | |
| on both data provided on the command line and data provided from the
 | |
| Config file.  The precedence for this is:
 | |
| 
 | |
|     <quote>
 | |
|     command line  ->  config file  ->  probed/default data
 | |
|     </quote>
 | |
| 
 | |
| For most things in this category there are helper functions that the
 | |
| drivers can use to ensure that the above precedence is consistently
 | |
| used.
 | |
| 
 | |
| As well as containing screen-specific data that the XFree86 common layer
 | |
| (including essential parts of the server infrastructure as well as helper
 | |
| functions) needs to access, it also contains some data that drivers use
 | |
| internally.  When considering whether to add a new field to the
 | |
| &s.code;ScrnInfoRec&e.code;, consider the balance between the convenience
 | |
| of things that lots of drivers need and the size/obscurity of the
 | |
| &s.code;ScrnInfoRec&e.code;.
 | |
| 
 | |
| Per-screen driver specific data that cannot be accommodated with the
 | |
| static &s.code;ScrnInfoRec&e.code; fields is held in a driver-defined
 | |
| data structure, a pointer to which is assigned to the
 | |
| &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field.  This
 | |
| is per-screen data that persists across server generations (as does the
 | |
| bulk of the static &s.code;ScrnInfoRec&e.code; data).  It would typically
 | |
| also include the video card's saved state.
 | |
| 
 | |
| Per-screen data for other modules that the driver uses (for example,
 | |
| the XAA module) that is reset for each server generation is hooked into
 | |
| the &s.code;ScrnInfoRec&e.code; through it's &s.code;privates&e.code;
 | |
| field.
 | |
| 
 | |
| Once it has stabilised, the data structures and variables accessible to
 | |
| video drivers will be documented here.  In the meantime, those things
 | |
| defined in the &s.code;xf86.h&e.code; and &s.code;xf86str.h&e.code;
 | |
| files are visible to video drivers.  Things defined in
 | |
| &s.code;xf86Priv.h&e.code; and &s.code;xf86Privstr.h&e.code; are NOT
 | |
| intended to be visible to video drivers, and it is an error for a driver
 | |
| to include those files.
 | |
| 
 | |
| 
 | |
| <sect1>Accessing global data
 | |
| <p>
 | |
| 
 | |
| Some other global state information that the drivers may access via
 | |
| functions is as follows:
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool xf86ServerIsExiting()&e.code;
 | |
|     <quote><p>
 | |
|       Returns &s.code;TRUE&e.code; if the server is at the end of a
 | |
|       generation and is in the process of exiting, and
 | |
|       &s.code;FALSE&e.code; otherwise.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86ServerIsResetting()&e.code;
 | |
|     <quote><p>
 | |
|       Returns &s.code;TRUE&e.code; if the server is at the end of a
 | |
|       generation and is in the process of resetting, and
 | |
|       &s.code;FALSE&e.code; otherwise.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86ServerIsInitialising()&e.code;
 | |
|     <quote><p>
 | |
|       Returns &s.code;TRUE&e.code; if the server is at the beginning of
 | |
|       a generation and is in the process of initialising, and
 | |
|       &s.code;FALSE&e.code; otherwise.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86ServerIsOnlyProbing()&e.code;
 | |
|     <quote><p>
 | |
|       Returns &s.code;TRUE&e.code; if the -probeonly command line flag
 | |
|       was specified, and &s.code;FALSE&e.code; otherwise.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86CaughtSignal()&e.code;
 | |
|     <quote><p>
 | |
|       Returns &s.code;TRUE&e.code; if the server has caught a signal,
 | |
|       and &s.code;FALSE&e.code; otherwise.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect1>Allocating private data
 | |
| <p>
 | |
| 
 | |
| A driver and any module it uses may allocate per-screen private storage
 | |
| in either the &s.code;ScreenRec&e.code; (DIX level) or
 | |
| &s.code;ScrnInfoRec&e.code; (XFree86 common layer level).
 | |
| &s.code;ScreenRec&e.code; storage persists only for a single server
 | |
| generation, and &s.code;ScrnInfoRec&e.code; storage persists across
 | |
| generations for the lifetime of the server.
 | |
| 
 | |
| The &s.code;ScreenRec&e.code; &s.code;devPrivates&e.code; data must be
 | |
| reallocated/initialised at the start of each new generation.  This is
 | |
| normally done from the &s.code;ChipScreenInit()&e.code; function, and
 | |
| Init functions for other modules that it calls.  Data allocated in this
 | |
| way should be freed by the driver's &s.code;ChipCloseScreen()&e.code;
 | |
| functions, and Close functions for other modules that it calls.  A new
 | |
| &s.code;devPrivates&e.code; entry is allocated by calling the
 | |
| &s.code;AllocateScreenPrivateIndex()&e.code; function.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;int AllocateScreenPrivateIndex()&e.code;
 | |
|     <quote><p>
 | |
|       This function allocates a new element in the
 | |
|       &s.code;devPrivates&e.code; field of all currently existing
 | |
|       &s.code;ScreenRecs&e.code;.  The return value is the index of this
 | |
|       new element in the &s.code;devPrivates&e.code; array.  The
 | |
|       &s.code;devPrivates&e.code; field is of type
 | |
|       &s.code;DevUnion&e.code;:
 | |
| 
 | |
| 	<verb>
 | |
|         typedef union _DevUnion {
 | |
|             pointer             ptr;
 | |
|             long                val;
 | |
|             unsigned long       uval;
 | |
|             pointer             (*fptr)(void);
 | |
|         } DevUnion;
 | |
| 	</verb>
 | |
| 
 | |
|       which allows the element to be used for any of the above types.
 | |
|       It is commonly used as a pointer to data that the caller allocates
 | |
|       after the new index has been allocated.
 | |
| 
 | |
|       This function will return &s.code;-1&e.code; when there is an
 | |
|       error allocating the new index.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| The &s.code;ScrnInfoRec&e.code; &s.code;privates&e.code; data persists
 | |
| for the life of the server, so only needs to be allocated once.  This
 | |
| should be done from the &s.code;ChipPreInit()&e.code; function, and Init
 | |
| functions for other modules that it calls.  Data allocated in this way
 | |
| should be freed by the driver's &s.code;ChipFreeScreen()&e.code; functions,
 | |
| and Free functions for other modules that it calls.  A new
 | |
| &s.code;privates&e.code; entry is allocated by calling the
 | |
| &s.code;xf86AllocateScrnInfoPrivateIndex()&e.code; function.
 | |
| 
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;int xf86AllocateScrnInfoPrivateIndex()&e.code;
 | |
|     <quote><p>
 | |
|       This function allocates a new element in the &s.code;privates&e.code;
 | |
|       field of all currently existing &s.code;ScrnInfoRecs&e.code;.
 | |
|       The return value is the index of this new element in the
 | |
|       &s.code;privates&e.code; array.  The &s.code;privates&e.code;
 | |
|       field is of type &s.code;DevUnion&e.code;:
 | |
| 
 | |
|         <verb>
 | |
|         typedef union _DevUnion {
 | |
|             pointer             ptr;
 | |
|             long                val;
 | |
|             unsigned long       uval;
 | |
|             pointer             (*fptr)(void);
 | |
|         } DevUnion;
 | |
|         </verb>
 | |
| 
 | |
|       which allows the element to be used for any of the above types.
 | |
|       It is commonly used as a pointer to data that the caller allocates
 | |
|       after the new index has been allocated.
 | |
| 
 | |
|       This function will not return when there is an error allocating
 | |
|       the new index.  When there is an error it will cause the server
 | |
|       to exit with a fatal error.  The similar function for allocation
 | |
|       privates in the &s.code;ScreenRec&e.code;
 | |
|       (&s.code;AllocateScreenPrivateIndex()&e.code;) differs in this
 | |
|       respect by returning &s.code;-1&e.code; when the allocation fails.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect>Keeping Track of Bus Resources<label id="rac">
 | |
| <p>
 | |
| 
 | |
| <sect1>Theory of Operation
 | |
| <p>
 | |
| 
 | |
| The XFree86 common layer has knowledge of generic access control mechanisms
 | |
| for devices on certain bus systems (currently the PCI bus) as well as
 | |
| of methods to enable or disable access to the buses itself.  Furthermore
 | |
| it can access information on resources decoded by these devices and if
 | |
| necessary modify it.
 | |
| 
 | |
| When first starting the Xserver collects all this information, saves it
 | |
| for restoration, checks it for consistency, and if necessary, corrects
 | |
| it.  Finally it disables all resources on a generic level prior to
 | |
| calling any driver function.
 | |
| 
 | |
| When the &s.code;Probe()&e.code; function of each driver is called the
 | |
| device sections are matched against the devices found in the system.
 | |
| The driver may probe devices at this stage that cannot be identified by
 | |
| using device independent methods.  Access to all resources that can be
 | |
| controlled in a device independent way is disabled.  The
 | |
| &s.code;Probe()&e.code; function should register all non-relocatable
 | |
| resources at this stage.  If a resource conflict is found between
 | |
| exclusive resources the driver will fail immediately.  Optionally the
 | |
| driver might specify an &s.code;EntityInit()&e.code;,
 | |
| &s.code;EntityLeave()&e.code; and &s.code;EntityEnter()&e.code; function.
 | |
| 
 | |
| &s.code;EntityInit()&e.code; can be used to disable any shared resources
 | |
| that are not controlled by the generic access control functions.  It is
 | |
| called prior to the PreInit phase regardless if an entity is active or
 | |
| not.  When calling the &s.code;EntityInit()&e.code;,
 | |
| &s.code;EntityEnter()&e.code; and &s.code;EntityLeave()&e.code; functions
 | |
| the common level will disable access to all other entities on a generic
 | |
| level.  Since the common level has no knowledge of device specific
 | |
| methods to disable access to resources it cannot be guaranteed that
 | |
| certain resources are not decoded by any other entity until the
 | |
| &s.code;EntityInit()&e.code; or &s.code;EntityEnter()&e.code; phase is
 | |
| finished.  Device drivers should therefore register all those resources
 | |
| which they are going to disable.  If these resources are never to be
 | |
| used by any driver function they may be flagged &s.code;ResInit&e.code;
 | |
| so that they can be removed from the resource list after processing all
 | |
| &s.code;EntityInit()&e.code; functions.  &s.code;EntityEnter()&e.code;
 | |
| should disable decoding of all resources which are not registered as
 | |
| exclusive and which are not handled by the generic access control in
 | |
| the common level.  The difference to &s.code;EntityInit()&e.code; is
 | |
| that the latter one is only called once during lifetime of the server.
 | |
| It can therefore be used to set up variables prior to disabling resources.
 | |
| &s.code;EntityLeave()&e.code; should restore the original state when
 | |
| exiting the server or switching to a different VT.  It also needs to
 | |
| disable device specific access functions if they need to be disabled on
 | |
| server exit or VT switch.  The default state is to enable them before
 | |
| giving up the VT.
 | |
| 
 | |
| In &s.code;PreInit()&e.code; phase each driver should check if any
 | |
| sharable resources it has registered during &s.code;Probe()&e.code; has
 | |
| been denied and take appropriate action which could simply be to fail.
 | |
| If it needs to access resources it has disabled during
 | |
| &s.code;EntitySetup()&e.code; it can do so provided it has registered
 | |
| these and will disable them before returning from
 | |
| &s.code;PreInit()&e.code;.  This also applies to all other driver
 | |
| functions.  Several functions are provided to request resource ranges,
 | |
| register these, correct PCI config space and add replacements for the
 | |
| generic access functions.  Resources may be marked ``disabled'' or
 | |
| ``unused'' during OPERATING stage.  Although these steps could also be
 | |
| performed in &s.code;ScreenInit()&e.code;, this is not desirable.
 | |
| 
 | |
| Following &s.code;PreInit()&e.code; phase the common level determines
 | |
| if resource access control is needed.  This is the case if more than
 | |
| one screen is used.  If necessary the RAC wrapper module is loaded.  In
 | |
| &s.code;ScreenInit()&e.code; the drivers can decide which operations
 | |
| need to be placed under RAC.  Available are the frame buffer operations,
 | |
| the pointer operations and the colormap operations.  Any operation that
 | |
| requires resources which might be disabled during OPERATING state should
 | |
| be set to use RAC.  This can be specified separately for memory and IO
 | |
| resources.
 | |
| 
 | |
| When &s.code;ScreenInit()&e.code; phase is done the common level will
 | |
| determine which shared resources are requested by more than one driver
 | |
| and set the access functions accordingly.  This is done following these
 | |
| rules:
 | |
| 
 | |
| <enum>
 | |
| <item>The sharable resources registered by each entity are compared.  If
 | |
|    a resource is registered by more than one entity the entity will be
 | |
|    marked to need to share this resources type (&s.code;IO&e.code; or
 | |
|    &s.code;MEM&e.code;).
 | |
| 
 | |
| <item>A resource marked ``disabled'' during OPERATING state will be ignored
 | |
|    entirely.
 | |
| 
 | |
| <item>A resource marked ``unused'' will only conflicts with an overlapping
 | |
|    resource of an other entity if the second is actually in use during
 | |
|    OPERATING state.
 | |
| 
 | |
| <item>If an ``unused'' resource was found to conflict however the entity
 | |
|    does not use any other resource of this type the entire resource type
 | |
|    will be disabled for that entity.
 | |
| </enum>
 | |
| 
 | |
| The driver has the choice among different ways to control access to
 | |
| certain resources:
 | |
| 
 | |
| <enum>
 | |
| <item>It can rely on the generic access functions.  This is probably the
 | |
|    most common case.  Here the driver only needs to register any resource
 | |
|    it is going to use.
 | |
| 
 | |
| <item>It can replace the generic access functions by driver specific
 | |
|    ones.  This will mostly be used in cases where no generic access
 | |
|    functions are available.  In this case the driver has to make sure
 | |
|    these resources are disabled when entering the &s.code;PreInit()&e.code;
 | |
|    stage.  Since the replacement functions are registered in
 | |
|    &s.code;PreInit()&e.code; the driver will have to enable these
 | |
|    resources itself if it needs to access them during this state.  The
 | |
|    driver can specify if the replacement functions can control memory
 | |
|    and/or I/O resources separately.
 | |
| 
 | |
| <item>The driver can enable resources itself when it needs them.  Each
 | |
|    driver function enabling them needs to disable them before it will
 | |
|    return.  This should be used if a resource which can be controlled
 | |
|    in a device dependent way is only required during SETUP state.  This
 | |
|    way it can be marked ``unused'' during OPERATING state.
 | |
| </enum>
 | |
| 
 | |
| A resource which is decoded during OPERATING state however never accessed
 | |
| by the driver should be marked unused.
 | |
| 
 | |
| Since access switching latencies are an issue during Xserver operation,
 | |
| the common level attempts to minimize the number of entities that need
 | |
| to be placed under RAC control.  When a wrapped operation is called,
 | |
| the &s.code;EnableAccess()&e.code; function is called before control is
 | |
| passed on.  &s.code;EnableAccess()&e.code; checks if a screen is under
 | |
| access control.  If not it just establishes bus routing and returns.
 | |
| If the screen needs to be under access control,
 | |
| &s.code;EnableAccess()&e.code; determines which resource types
 | |
| (&s.code;MEM&e.code;, &s.code;IO&e.code;) are required.  Then it tests
 | |
| if this access is already established.  If so it simply returns.  If
 | |
| not it disables the currently established access, fixes bus routing and
 | |
| enables access to all entities registered for this screen.
 | |
| 
 | |
| Whenever a mode switch or a VT-switch is performed the common level will
 | |
| return to SETUP state.
 | |
| 
 | |
| <sect1>Resource Types
 | |
| <p>
 | |
| 
 | |
| Resource have certain properties.  When registering resources each range
 | |
| is accompanied by a flag consisting of the ORed flags of the different
 | |
| properties the resource has.  Each resource range may be classified
 | |
| according to
 | |
| 
 | |
| <itemize>
 | |
|   <item>its physical properties i.e., if it addresses
 | |
|        memory (&s.code;ResMem&e.code;)  or
 | |
|        I/O space (&s.code;ResIo&e.code;),
 | |
|   <item>if it addresses a
 | |
|        block (&s.code;ResBlock&e.code;) or
 | |
|        sparse (&s.code;ResSparse&e.code;)
 | |
|     range,
 | |
|   <item>its access properties.
 | |
| </itemize>
 | |
| 
 | |
| There are two known access properties:
 | |
| 
 | |
| <itemize>
 | |
|   <item>&s.code;ResExclusive&e.code;
 | |
|     for resources which may not be shared with any other device and
 | |
|   <item>&s.code;ResShared&e.code;
 | |
|     for resources which can be disabled and therefore can be shared.
 | |
| </itemize>
 | |
| 
 | |
| If it is necessary to test a resource against any type a generic access
 | |
| type &s.code;ResAny&e.code; is provided.  If this is set the resource
 | |
| will conflict with any resource of a different entity intersecting its
 | |
| range.  Further it can be specified that a resource is decoded however
 | |
| never used during any stage (&s.code;ResUnused&e.code;) or during
 | |
| OPERATING state (&s.code;ResUnusedOpr&e.code;).  A resource only visible
 | |
| during the init functions (ie.  &s.code;EntityInit()&e.code;,
 | |
| &s.code;EntityEnter()&e.code; and &s.code;EntityLeave()&e.code; should
 | |
| be registered with the flag &s.code;ResInit&e.code;.  A resource that
 | |
| might conflict with background resource ranges may be flagged with
 | |
| &s.code;ResBios&e.code;.  This might be useful when registering resources
 | |
| ranges that were assigned by the system Bios.
 | |
| 
 | |
| Several predefined resource lists are available for VGA and 8514/A
 | |
| resources in &s.code;common/xf86Resources.h&e.code;.
 | |
| 
 | |
| <sect1>Available Functions<label id="avail">
 | |
| <p>
 | |
| 
 | |
| The functions provided for resource management are listed in their order
 | |
| of use in the driver.
 | |
| 
 | |
| 
 | |
| <sect2>Probe Phase
 | |
| <p>
 | |
| 
 | |
| In this phase each driver detects those resources it is able to drive,
 | |
| creates an entity record for each of them, registers non-relocatable
 | |
| resources and allocates screens and adds the resources to screens.
 | |
| 
 | |
| Two helper functions are provided for matching device sections in the
 | |
| xorg.conf file to the devices:
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;int xf86MatchPciInstances(const char *driverName, int vendorID,
 | |
| 		&f.indent;SymTabPtr chipsets, PciChipsets *PCIchipsets,
 | |
|                 &f.indent;GDevPtr *devList, int numDevs, DriverPtr drvp,
 | |
|                 &f.indent;int **foundEntities)&e.code;
 | |
|     <quote><p>
 | |
|       This function finds matches between PCI cards that a driver supports
 | |
|       and config file device sections.  It is intended for use in the
 | |
|       &s.code;ChipProbe()&e.code; function of drivers for PCI cards.
 | |
|       Only probed PCI devices with a vendor ID matching
 | |
|       &s.code;vendorID&e.code; are considered.  &s.code;devList&e.code;
 | |
|       and &s.code;numDevs&e.code; are typically those found from
 | |
|       calling &s.code;xf86MatchDevice()&e.code;, and represent the active
 | |
|       config file device sections relevant to the driver.
 | |
|       &s.code;PCIchipsets&e.code; is a table that provides a mapping
 | |
|       between the PCI device IDs, the driver's internal chipset tokens
 | |
|       and a list of fixed resources.
 | |
| 
 | |
|       When a device section doesn't have a &s.key;BusID&e.key; entry it
 | |
|       can only match the primary video device.  Secondary devices are
 | |
|       only matched with device sections that have a matching
 | |
|       &s.key;BusID&e.key; entry.
 | |
| 
 | |
|       Once the preliminary matches have been found, a final match is
 | |
|       confirmed by checking if the chipset override, ChipID override or
 | |
|       probed PCI chipset type match one of those given in the
 | |
|       &s.code;chipsets&e.code; and &s.code;PCIchipsets&e.code; lists.
 | |
|       The &s.code;PCIchipsets&e.code; list includes a list of the PCI
 | |
|       device IDs supported by the driver.  The list should be terminated
 | |
|       with an entry with PCI ID &s.code;-1&e.code;".  The
 | |
|       &s.code;chipsets&e.code; list is a table mapping the driver's
 | |
|       internal chipset tokens to names, and should be terminated with
 | |
|       a &s.code;NULL&e.code; entry.  Only those entries with a
 | |
|       corresponding entry in the &s.code;PCIchipsets&e.code; list are
 | |
|       considered.  The order of precedence is: config file chipset,
 | |
|       config file ChipID, probed PCI device ID.
 | |
| 
 | |
|       In cases where a driver handles PCI chipsets with more than one
 | |
|       vendor ID, it may set &s.code;vendorID&e.code; to
 | |
|       &s.code;0&e.code;, and OR each devID in the list with (the
 | |
|       vendor ID << 16).
 | |
| 
 | |
|       Entity index numbers for confirmed matches are returned as an
 | |
|       array via &s.code;foundEntities&e.code;.  The PCI information,
 | |
|       chipset token and device section for each match are found in the
 | |
|       &s.code;EntityInfoRec&e.code; referenced by the indices.
 | |
| 
 | |
|       The function return value is the number of confirmed matches.  A
 | |
|       return value of &s.code;-1&e.code; indicates an internal error.
 | |
|       The returned &s.code;foundEntities&e.code; array should be freed
 | |
|       by the driver with &s.code;xfree()&e.code; when it is no longer
 | |
|       needed in cases where the return value is greater than zero.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;int xf86MatchIsaInstances(const char *driverName,
 | |
| 		     &f.indent;SymTabPtr chipsets, IsaChipsets *ISAchipsets,
 | |
| 		     &f.indent;DriverPtr drvp, FindIsaDevProc FindIsaDevice,
 | |
| 		     &f.indent;GDevPtr *devList, int numDevs,
 | |
| 					int **foundEntities)&e.code;
 | |
|     <quote><p>
 | |
|       This function finds matches between ISA cards that a driver supports
 | |
|       and config file device sections.  It is intended for use in the
 | |
|       &s.code;ChipProbe()&e.code; function of drivers for ISA cards.
 | |
|       &s.code;devList&e.code; and &s.code;numDevs&e.code; are
 | |
|       typically those found from calling &s.code;xf86MatchDevice()&e.code;,
 | |
|       and represent the active config file device sections relevant to
 | |
|       the driver.  &s.code;ISAchipsets&e.code; is a table that provides
 | |
|       a mapping between the driver's internal chipset tokens and the
 | |
|       resource classes.  &s.code;FindIsaDevice&e.code; is a
 | |
|       driver-provided function that probes the hardware and returns the
 | |
|       chipset token corresponding to what was detected, and
 | |
|       &s.code;-1&e.code; if nothing was detected.
 | |
| 
 | |
|       If the config file device section contains a chipset entry, then
 | |
|       it is checked against the &s.code;chipsets&e.code; list.  When
 | |
|       no chipset entry is present, the &s.code;FindIsaDevice&e.code;
 | |
|       function is called instead.
 | |
| 
 | |
|       Entity index numbers for confirmed matches are returned as an
 | |
|       array via &s.code;foundEntities&e.code;.  The chipset token and
 | |
|       device section for each match are found in the
 | |
|       &s.code;EntityInfoRec&e.code; referenced by the indices.
 | |
| 
 | |
|       The function return value is the number of confirmed matches.  A
 | |
|       return value of &s.code;-1&e.code; indicates an internal error.
 | |
|       The returned &s.code;foundEntities&e.code; array should be freed
 | |
|       by the driver with &s.code;xfree()&e.code; when it is no longer
 | |
|       needed in cases where the return value is greater than zero.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| These two helper functions make use of several core functions that are
 | |
| available at the driver level:
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool xf86ParsePciBusString(const char *busID, int *bus,
 | |
| 			&f.indent;int *device, int *func)&e.code;
 | |
|     <quote><p>
 | |
|       Takes a &s.code;BusID&e.code; string, and if it is in the correct
 | |
|       format, returns the PCI &s.code;bus&e.code;, &s.code;device&e.code;,
 | |
|       &s.code;func&e.code; values that it indicates.  The format of the
 | |
|       string is expected to be "PCI:bus:device:func" where each of `bus',
 | |
|       `device' and `func' are decimal integers.  The ":func" part may
 | |
|       be omitted, and the func value assumed to be zero, but this isn't
 | |
|       encouraged.  The "PCI" prefix may also be omitted.  The prefix
 | |
|       "AGP" is currently equivalent to the "PCI" prefix.  If the string
 | |
|       isn't a valid PCI BusID, the return value is &s.code;FALSE&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
|     &s.code;Bool xf86ComparePciBusString(const char *busID, int bus,
 | |
| 			&f.indent;int device, int func)&e.code;
 | |
|     <quote><p>
 | |
|       Compares a &s.code;BusID&e.code; string with PCI &s.code;bus&e.code;,
 | |
|       &s.code;device&e.code;, &s.code;func&e.code; values.  If they
 | |
|       match &s.code;TRUE&e.code; is returned, and &s.code;FALSE&e.code;
 | |
|       if they don't.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86ParseIsaBusString(const char *busID)&e.code;
 | |
|     <quote><p>
 | |
|       Compares a &s.code;BusID&e.code; string with the ISA bus ID string
 | |
|       ("ISA" or "ISA:").  If they match &s.code;TRUE&e.code; is returned,
 | |
|       and &s.code;FALSE&e.code; if they don't.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86CheckPciSlot(int bus, int device, int func)&e.code;
 | |
|     <quote><p>
 | |
|       Checks if the PCI slot &s.code;bus:device:func&e.code; has been
 | |
|       claimed.  If so, it returns &s.code;FALSE&e.code;, and otherwise
 | |
|       &s.code;TRUE&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;int xf86ClaimPciSlot(int bus, int device, int func, DriverPtr drvp,
 | |
| 			&f.indent;int chipset, GDevPtr dev, Bool active)&e.code;
 | |
|     <quote><p>
 | |
|       This function is used to claim a PCI slot, allocate the associated
 | |
|       entity record and initialise their data structures.  The return
 | |
|       value is the index of the newly allocated entity record, or
 | |
|       &s.code;-1&e.code; if the claim fails.  This function should always
 | |
|       succeed if &s.code;xf86CheckPciSlot()&e.code; returned
 | |
|       &s.code;TRUE&e.code; for the same PCI slot.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86IsPrimaryPci(void)&e.code;
 | |
|     <quote><p>
 | |
|       This function returns &s.code;TRUE&e.code; if the primary card is
 | |
|       a PCI device, and &s.code;FALSE&e.code; otherwise.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;int xf86ClaimIsaSlot(DriverPtr drvp, int chipset,
 | |
| 			&f.indent;GDevPtr dev, Bool active)&e.code;
 | |
|     <quote><p>
 | |
|       This allocates an entity record entity and initialise the data
 | |
|       structures.  The return value is the index of the newly allocated
 | |
|       entity record.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86IsPrimaryIsa(void)&e.code;
 | |
|     <quote><p>
 | |
|       This function returns &s.code;TRUE&e.code; if the primary card is
 | |
|       an ISA (non-PCI) device, and &s.code;FALSE&e.code; otherwise.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| Two helper functions are provided to aid configuring entities:
 | |
|     <quote><p>
 | |
|     &s.code;ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn,
 | |
|                                  &f.indent;int scrnFlag, int entityIndex,
 | |
|                                  &f.indent;PciChipsets *p_chip,
 | |
|                                  &f.indent;resList res, EntityProc init,
 | |
|                                  &f.indent;EntityProc enter, EntityProc leave,
 | |
|                                  &f.indent;pointer private)&e.code;
 | |
|     <p>
 | |
|     &s.code;ScrnInfoPtr xf86ConfigIsaEntity(ScrnInfoPtr pScrn,
 | |
|                                  &f.indent;int scrnFlag, int entityIndex,
 | |
|                                  &f.indent;IsaChipsets *i_chip,
 | |
|                                  &f.indent;resList res, EntityProc init,
 | |
|                                  &f.indent;EntityProc enter, EntityProc leave,
 | |
|                                  &f.indent;pointer private)&e.code;
 | |
|     <quote><p>
 | |
|       These functions are used to register the non-relocatable resources
 | |
|       for an entity, and the optional entity-specific &s.code;Init&e.code;, &s.code;Enter&e.code; and
 | |
|       &s.code;Leave&e.code; functions.  Usually the list of fixed resources is obtained
 | |
|       from the Isa/PciChipsets lists.  However an additional list of
 | |
|       resources may be passed.  Generally this is not required.
 | |
|       For active entities a &s.code;ScrnInfoRec&e.code; is allocated
 | |
|       if the &s.code;pScrn&e.code; argument is &s.code;NULL&e.code;.
 | |
| The
 | |
|       return value is &s.code;TRUE&e.code; when successful.  The init, enter, leave
 | |
|       functions are defined as follows:
 | |
| 
 | |
|         <quote>
 | |
|         &s.code;typedef void (*EntityProc)(int entityIndex,
 | |
| 			&f.indent;pointer private)&e.code;
 | |
|         </quote>
 | |
| 
 | |
|       They are passed the entity index and a pointer to a private scratch
 | |
|       area.  This can be set up during &s.code;Probe()&e.code; and
 | |
|       its address can be passed to
 | |
|       &s.code;xf86ConfigIsaEntity()&e.code; and
 | |
|       &s.code;xf86ConfigPciEntity()&e.code; as the last argument.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| These two helper functions make use of several core functions that are
 | |
| available at the driver level:
 | |
|     <quote><p>
 | |
|     &s.code;void xf86ClaimFixedResources(resList list, int entityIndex)&e.code;
 | |
|     <quote><p>
 | |
|       This function registers the non-relocatable resources which cannot
 | |
|       be disabled and which therefore would cause the server to fail
 | |
|       immediately if they were found to conflict.  It also records
 | |
|       non-relocatable but sharable resources for processing after the
 | |
|       &s.code;Probe()&e.code; phase.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
 | |
| 			&f.indent;EntityProc enter, EntityProc leave, pointer)&e.code;
 | |
|     <quote><p>
 | |
|       This function registers with an entity the &s.code;init&e.code;,
 | |
|       &s.code;enter&e.code;, &s.code;leave&e.code; functions along
 | |
|       with the pointer to their private area.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)&e.code;
 | |
|     <quote><p>
 | |
|       This function associates the entity referenced by
 | |
|       &s.code;entityIndex&e.code; with the screen.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect2>PreInit Phase
 | |
| <p>
 | |
| 
 | |
| During this phase the remaining resources should be registered.
 | |
| &s.code;PreInit()&e.code; should call &s.code;xf86GetEntityInfo()&e.code;
 | |
| to obtain a pointer to an &s.code;EntityInfoRec&e.code; for each entity
 | |
| it is able to drive and check if any resource are listed in its
 | |
| &s.code;resources&e.code; field.  If resources registered in the Probe
 | |
| phase have been rejected in the post-Probe phase
 | |
| (&s.code;resources&e.code; is non-&s.code;NULL&e.code;), then the driver should
 | |
| decide if it can continue without using these or if it should fail.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;EntityInfoPtr xf86GetEntityInfo(int entityIndex)&e.code;
 | |
|     <quote><p>
 | |
|       This function returns a pointer to the &s.code;EntityInfoRec&e.code;
 | |
|       referenced by &s.code;entityIndex&e.code;.  The returned
 | |
|       &s.code;EntityInfoRec&e.code; should be freed with
 | |
|       &s.code;xfree()&e.code; when no longer needed.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| Several functions are provided to simplify resource registration:
 | |
|     <quote><p>
 | |
|     &s.code;Bool xf86IsEntityPrimary(int entityIndex)&e.code;
 | |
|     <quote><p>
 | |
|       This function returns &s.code;TRUE&e.code; if the entity referenced
 | |
|       by &s.code;entityIndex&e.code; is the primary display device (i.e.,
 | |
|       the one initialised at boot time and used in text mode).
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86IsScreenPrimary(int scrnIndex)&e.code;
 | |
|     <quote><p>
 | |
|       This function returns &s.code;TRUE&e.code; if the primary entity
 | |
|       is registered with the screen referenced by
 | |
|       &s.code;scrnIndex&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;pciVideoPtr xf86GetPciInfoForEntity(int entityIndex)&e.code;
 | |
|     <quote><p>
 | |
|       This function returns a pointer to the &s.code;pciVideoRec&e.code;
 | |
|       for the specified entity.  If the entity is not a PCI device,
 | |
|       &s.code;NULL&e.code; is returned.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| The primary function for registration of resources is:
 | |
|     <quote><p>
 | |
|     &s.code;resPtr xf86RegisterResources(int entityIndex, resList list,
 | |
| 			&f.indent;int access)&e.code;
 | |
|     <quote><p>
 | |
|       This function tries to register the resources in
 | |
|       &s.code;list&e.code;.  If list is &s.code;NULL&e.code; it tries
 | |
|       to determine the resources automatically.  This only works for
 | |
|       entities that provide a generic way to read out the resource ranges
 | |
|       they decode.  So far this is only the case for PCI devices.  By
 | |
|       default the PCI resources are registered as shared
 | |
|       (&s.code;ResShared&e.code;) if the driver wants to set a different
 | |
|       access type it can do so by specifying the access flags in the
 | |
|       third argument.  A value of &s.code;0&e.code; means to use the
 | |
|       default settings.  If for any reason the resource broker is not
 | |
|       able to register some of the requested resources the function will
 | |
|       return a pointer to a list of the failed ones.  In this case the
 | |
|       driver may be able to move the resource to different locations.
 | |
|       In case of PCI bus entities this is done by passing the list of
 | |
|       failed resources to &s.code;xf86ReallocatePciResources()&e.code;.
 | |
|       When the registration succeeds, the return value is
 | |
|       &s.code;NULL&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;resPtr xf86ReallocatePciResources(int entityIndex, resPtr pRes)&e.code;
 | |
|     <quote><p>
 | |
|       This function takes a list of PCI resources that need to be
 | |
|       reallocated and returns &s.code;NULL&e.code when all relocations are
 | |
|       successful.
 | |
|       &s.code;xf86RegisterResources()&e.code; should be called again to
 | |
|       register the relocated resources with the broker.
 | |
|       If the reallocation fails, a list of the resources that could not be
 | |
|       relocated is returned.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| Two functions are provided to obtain a resource range of a given type:
 | |
|     <quote><p>
 | |
|     &s.code;resRange xf86GetBlock(long type, memType size,
 | |
| 			&f.indent;memType window_start, memType window_end,
 | |
| 			&f.indent;memType align_mask, resPtr avoid)&e.code;
 | |
|     <quote><p>
 | |
|       This function tries to find a block range of size
 | |
|       &s.code;size&e.code; and type &s.code;type&e.code; in a window
 | |
|       bound by &s.code;window_start&e.code; and &s.code;window_end&e.code;
 | |
|       with the alignment specified in &s.code;align_mask&e.code;.
 | |
|       Optionally a list of resource ranges which should be avoided within
 | |
|       the window can be supplied.  On failure a zero-length range of
 | |
|       type &s.code;ResEnd&e.code; will be returned.
 | |
| 
 | |
|     </quote>
 | |
|     &s.code;resRange xf86GetSparse(long type, memType fixed_bits,
 | |
| 			&f.indent;memType decode_mask, memType address_mask,
 | |
| 			&f.indent;resPtr avoid)&e.code;
 | |
|     <quote><p>
 | |
|       This function is like the previous one, but attempts to find a
 | |
|       sparse range instead of a block range.  Here three values have to
 | |
|       be specified: the &s.code;address_mask&e.code; which marks all
 | |
|       bits of the mask part of the address, the &s.code;decode_mask&e.code;
 | |
|       which masks out the bits which are hardcoded and are therefore
 | |
|       not available for relocation and the values of the fixed bits.
 | |
|       The function tries to find a base that satisfies the given condition.
 | |
|       If the function fails it will return a zero range of type
 | |
|       &s.code;ResEnd&e.code;.  Optionally it might be passed a list of
 | |
|       resource ranges to avoid.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| Some PCI devices are broken in the sense that they return invalid size
 | |
| information for a certain resource.  In this case the driver can supply
 | |
| the correct size and make sure that the resource range allocated for
 | |
| the card is large enough to hold the address range decoded by the card.
 | |
| The function &s.code;xf86FixPciResource()&e.code; can be used to do this:
 | |
|     <quote><p>
 | |
|     &s.code;Bool xf86FixPciResource(int entityIndex, unsigned int prt,
 | |
| 				&f.indent;CARD32 alignment, long type)&e.code;
 | |
|     <quote><p>
 | |
|       This function fixes a PCI resource allocation.  The
 | |
|       &s.code;prt&e.code; parameter contains the number of the PCI base
 | |
|       register that needs to be fixed (&s.code;0-5&e.code;, and
 | |
|       &s.code;6&e.code; for the BIOS base register).  The size is
 | |
|       specified by the alignment.  Since PCI resources need to span an
 | |
|       integral range of size &s.code;2^n&e.code;, the alignment also
 | |
|       specifies the number of addresses that will be decoded.  If the
 | |
|       driver specifies a type mask it can override the default type for
 | |
|       PCI resources which is &s.code;ResShared&e.code;.  The resource
 | |
|       broker needs to know that to find a matching resource range.  This
 | |
|       function should be called before calling
 | |
|       &s.code;xf86RegisterResources()&e.code;.  The return value is
 | |
|       &s.code;TRUE&e.code; when the function succeeds.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86CheckPciMemBase(pciVideoPtr pPci, memType base)&e.code;
 | |
|     <quote><p>
 | |
|       This function checks that the memory base address specified matches
 | |
|       one of the PCI base address register values for the given PCI
 | |
|       device.  This is mostly used to check that an externally provided
 | |
|       base address (e.g., from a config file) matches an actual value
 | |
|       allocated to a device.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| The driver may replace the generic access control functions for an entity.
 | |
| This is done with the &s.code;xf86SetAccessFuncs()&e.code;:
 | |
|     <quote><p>
 | |
|     &s.code;void xf86SetAccessFuncs(EntityInfoPtr pEnt,
 | |
|                         &f.indent;xf86SetAccessFuncPtr funcs,
 | |
| 			&f.indent;xf86SetAccessFuncPtr oldFuncs)&e.code;
 | |
|     <quote><p>
 | |
|      with:
 | |
|     </quote>
 | |
| 
 | |
|     <verb>
 | |
|       typedef struct {
 | |
|           xf86AccessPtr mem;
 | |
|           xf86AccessPtr io;
 | |
|           xf86AccessPtr io_mem;
 | |
|       } xf86SetAccessFuncRec, *xf86SetAccessFuncPtr;
 | |
|     </verb>
 | |
| 
 | |
|     <quote><p>
 | |
|       The driver can pass three functions: one for I/O access, one for
 | |
|       memory access and one for combined memory and I/O access.  If the
 | |
|       memory access and combined access functions are identical the
 | |
|       common level assumes that the memory access cannot be controlled
 | |
|       independently of I/O access, if the I/O access function and the
 | |
|       combined access functions are the same it is assumed that I/O can
 | |
|       not be controlled independently.  If memory and I/O have to be
 | |
|       controlled together all three values should be the same.  If a
 | |
|       non &s.code;NULL&e.code; value is passed as third argument it is
 | |
|       interpreted as an address where to store the old access record.
 | |
|       If the third argument is &s.code;NULL&e.code; it will be assumed
 | |
|       that the generic access should be enabled before replacing the
 | |
|       access functions.  Otherwise it will be disabled.  The driver may
 | |
|       enable them itself using the returned values.  It should do this
 | |
|       from its replacement access functions as the generic access may
 | |
|       be disabled by the common level on certain occasions.  If replacement
 | |
|       functions are specified they must control all resources of the
 | |
|       specific type registered for the entity.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| To find out if a specific resource range conflicts with another
 | |
| resource the &s.code;xf86ChkConflict()&e.code; function may be used:
 | |
|     <quote><p>
 | |
|     &s.code;memType xf86ChkConflict(resRange *rgp, int entityIndex)&e.code;
 | |
|     <quote><p>
 | |
|       This function checks if the resource range &s.code;rgp&e.code; of
 | |
|       for the specified entity conflicts with with another resource.
 | |
|       If a conflict is found, the address of the start of the conflict
 | |
|       is returned.  The return value is zero when there is no conflict.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| The OPERATING state properties of previously registered fixed resources
 | |
| can be set with the &s.code;xf86SetOperatingState()&e.code; function:
 | |
|     <quote><p>
 | |
|     &s.code;resPtr xf86SetOperatingState(resList list, int entityIndex,
 | |
| 			&f.indent;int mask)&e.code;
 | |
|     <quote><p>
 | |
|       This function is used to set the status of a resource during
 | |
|       OPERATING state.  &s.code;list&e.code; holds a list to which
 | |
|       &s.code;mask&e.code; is to be applied.  The parameter
 | |
|       &s.code;mask&e.code; may have the value &s.code;ResUnusedOpr&e.code;
 | |
|       and &s.code;ResDisableOpr&e.code;.  The first one should be used
 | |
|       if a resource isn't used by the driver during OPERATING state
 | |
|       although it is decoded by the device, while the latter one indicates
 | |
|       that the resource is not decoded during OPERATING state.  Note
 | |
|       that the resource ranges have to match those specified during
 | |
|       registration.  If a range has been specified starting at
 | |
|       &s.code;A&e.code; and ending at &s.code;B&e.code; and suppose
 | |
|       &s.code;C&e.code; us a value satisfying
 | |
|       &s.code;A < C < B&e.code; one may not
 | |
|       specify the resource range &s.code;(A,B)&e.code; by splitting it
 | |
|       into two ranges &s.code;(A,C)&e.code; and &s.code;(C,B)&e.code;.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| The following two functions are provided for special cases:
 | |
|     <quote><p>
 | |
|     &s.code;void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)&e.code;
 | |
|     <quote><p>
 | |
|       This function may be used to remove an entity from a screen.  This
 | |
|       only makes sense if a screen has more than one entity assigned or
 | |
|       the screen is to be deleted.  No test is made if the screen has
 | |
|       any entities left.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86DeallocateResourcesForEntity(int entityIndex, long type)&e.code;
 | |
|     <quote><p>
 | |
|       This function deallocates all resources of a given type registered
 | |
|       for a certain entity from the resource broker list.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect2>ScreenInit Phase
 | |
| <p>
 | |
| 
 | |
| All that is required in this phase is to setup the RAC flags.  Note that
 | |
| it is also permissible to set these flags up in the PreInit phase.  The
 | |
| RAC flags are held in the &s.code;racIoFlags&e.code; and &s.code;racMemFlags&e.code; fields of the
 | |
| &s.code;ScrnInfoRec&e.code; for each screen.  They specify which graphics operations
 | |
| might require the use of shared resources.  This can be specified
 | |
| separately for memory and I/O resources.  The available flags are defined
 | |
| in &s.code;rac/xf86RAC.h&e.code;.  They are:
 | |
| 
 | |
|     &s.code;RAC_FB&e.code;
 | |
| 	<quote>
 | |
| 	for framebuffer operations (including hw acceleration)
 | |
| 	</quote>
 | |
|     &s.code;RAC_CURSOR&e.code;
 | |
| 	<quote>
 | |
| 	for Cursor operations
 | |
|         (??? I'm not sure if we need this for SW cursor it depends
 | |
|          on which level the sw cursor is drawn)
 | |
| 	</quote>
 | |
|     &s.code;RAC_COLORMAP&e.code;
 | |
| 	<quote>
 | |
| 	for colormap operations
 | |
| 	</quote>
 | |
|     &s.code;RAC_VIEWPORT&e.code;
 | |
| 	<quote>
 | |
| 	for the call to &s.code;ChipAdjustFrame()&e.code; </quote>
 | |
| 
 | |
| 
 | |
| The flags are ORed together.
 | |
| 
 | |
| <sect>Config file ``Option'' entries<label id="options">
 | |
| <p>
 | |
| 
 | |
| Option entries are permitted in most sections and subsections of the
 | |
| config file.  There are two forms of option entries:
 | |
| 
 | |
| <descrip>
 | |
| <tag>Option "option-name"</tag>
 | |
| 	A boolean option.
 | |
| <tag>Option "option-name" "option-value"</tag>
 | |
| 	An option with an arbitrary value.
 | |
| </descrip>
 | |
| 
 | |
| The option entries are handled by the parser, and a list of the parsed
 | |
| options is included with each of the appropriate data structures that
 | |
| the drivers have access to.  The data structures used to hold the option
 | |
| information are opaque to the driver, and a driver must not access the
 | |
| option data directly.  Instead, the common layer provides a set of
 | |
| functions that may be used to access, check and manipulate the option
 | |
| data.
 | |
| 
 | |
| First, the low level option handling functions.  In most cases drivers
 | |
| would not need to use these directly.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;pointer xf86FindOption(pointer options, const char *name)&e.code;
 | |
|     <quote><p>
 | |
|       Takes a list of options and an option name, and returns a handle
 | |
|       for the first option entry in the list matching the name.  Returns
 | |
|       &s.code;NULL&e.code; if no match is found.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;char *xf86FindOptionValue(pointer options, const char *name)&e.code;
 | |
|     <quote><p>
 | |
|       Takes a list of options and an option name, and returns the value
 | |
|       associated with the first option entry in the list matching the
 | |
|       name.  If the matching option has no value, an empty string
 | |
|       (&s.code;""&e.code;) is returned.  Returns &s.code;NULL&e.code;
 | |
|       if no match is found.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86MarkOptionUsed(pointer option)&e.code;
 | |
|     <quote><p>
 | |
|       Takes a handle for an option, and marks that option as used.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86MarkOptionUsedByName(pointer options, const char *name)&e.code;
 | |
|     <quote><p>
 | |
|       Takes a list of options and an option name and marks the first
 | |
|       option entry in the list matching the name as used.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
| Next, the higher level functions that most drivers would use.
 | |
|     <quote><p>
 | |
|     &s.code;void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)&e.code;
 | |
|     <quote><p>
 | |
|       Collect the options from each of the config file sections used by
 | |
|       the screen (&s.code;pScrn&e.code;) and return the merged list as
 | |
|       &s.code;pScrn->options&e.code;.  This function requires that
 | |
|       &s.code;pScrn->confScreen&e.code;, &s.code;pScrn->display&e.code;,
 | |
|       &s.code;pScrn->monitor&e.code;,
 | |
|       &s.code;pScrn->numEntities&e.code;, and
 | |
|       &s.code;pScrn->entityList&e.code; are initialised.
 | |
|       &s.code;extraOpts&e.code; may optionally be set to an additional
 | |
|       list of options to be combined with the others.  The order of
 | |
|       precedence for options is &s.code;extraOpts&e.code;, display,
 | |
|       confScreen, monitor, device.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86ProcessOptions(int scrnIndex, pointer options,
 | |
| 			&f.indent;OptionInfoPtr optinfo)&e.code;
 | |
|     <quote><p>
 | |
|       Processes a list of options according to the information in the
 | |
|       array of &s.code;OptionInfoRecs&e.code; (&s.code;optinfo&e.code;).
 | |
|       The resulting information is stored in the &s.code;value&e.code;
 | |
|       fields of the appropriate &s.code;optinfo&e.code; entries.  The
 | |
|       &s.code;found&e.code; fields are set to &s.code;TRUE&e.code;
 | |
|       when an option with a value of the correct type if found, and
 | |
|       &s.code;FALSE&e.code; otherwise.  The &s.code;type&e.code; field
 | |
|       is used to determine the expected value type for each option.
 | |
|       Each option in the list of options for which there is a name match
 | |
|       (but not necessarily a value type match) is marked as used.
 | |
|       Warning messages are printed when option values don't match the
 | |
|       types specified in the optinfo data.
 | |
| 
 | |
|       NOTE: If this function is called before a driver's screen number
 | |
|       is known (e.g., from the &s.code;ChipProbe()&e.code; function) a
 | |
|       &s.code;scrnIndex&e.code; value of &s.code;-1&e.code; should be
 | |
|       used.
 | |
| 
 | |
|       NOTE 2: Given that this function stores into the
 | |
|       &s.code;OptionInfoRecs&e.code; pointed to by &s.code;optinfo&e.code,
 | |
|       the caller should ensure the &s.code;OptionInfoRecs&e.code; are
 | |
|       (re-)initialised before the call, especially if the caller expects
 | |
|       to use the predefined option values as defaults.
 | |
| 
 | |
|       The &s.code;OptionInfoRec&e.code; is defined as follows:
 | |
| 
 | |
|       <verb>
 | |
|       typedef struct {
 | |
|           double freq;
 | |
|           int units;
 | |
|       } OptFrequency;
 | |
| 
 | |
|       typedef union {
 | |
|           unsigned long       num;
 | |
|           char *              str;
 | |
|           double              realnum;
 | |
|           Bool                bool;
 | |
|           OptFrequency        freq;
 | |
|       } ValueUnion;
 | |
| 
 | |
|       typedef enum {
 | |
|           OPTV_NONE = 0,
 | |
|           OPTV_INTEGER,
 | |
|           OPTV_STRING,  /* a non-empty string */
 | |
|           OPTV_ANYSTR,  /* Any string, including an empty one */
 | |
|           OPTV_REAL,
 | |
|           OPTV_BOOLEAN,
 | |
|           OPTV_FREQ
 | |
|       } OptionValueType;
 | |
| 
 | |
|       typedef enum {
 | |
|           OPTUNITS_HZ = 1,
 | |
|           OPTUNITS_KHZ,
 | |
|           OPTUNITS_MHZ
 | |
|       } OptFreqUnits;
 | |
| 
 | |
|       typedef struct {
 | |
|           int                 token;
 | |
|           const char*         name;
 | |
|           OptionValueType     type;
 | |
|           ValueUnion          value;
 | |
|           Bool                found;
 | |
|       } OptionInfoRec, *OptionInfoPtr;
 | |
|       </verb>
 | |
| 
 | |
|       &s.code;OPTV_FREQ&e.code; can be used for options values that are
 | |
|       frequencies.  These values are a floating point number with an
 | |
|       optional unit name appended.  The unit name can be one of "Hz",
 | |
|       "kHz", "k", "MHz", "M".  The multiplier associated with the unit
 | |
|       is stored in &s.code;freq.units&e.code;, and the scaled frequency
 | |
|       is stored in &s.code;freq.freq&e.code;.  When no unit is specified,
 | |
|       &s.code;freq.units&e.code; is set to &s.code;0&e.code;, and
 | |
|       &s.code;freq.freq&e.code; is unscaled.
 | |
| 
 | |
|       Typical usage is to setup an array of
 | |
|       &s.code;OptionInfoRecs&e.code; with all fields initialised.
 | |
|       The &s.code;value&e.code; and &s.code;found&e.code; fields get
 | |
|       set by &s.code;xf86ProcessOptions()&e.code;.  For cases where the
 | |
|       value parsing is more complex, the driver should specify
 | |
|       &s.code;OPTV_STRING&e.code;, and parse the string itself.  An
 | |
|       example of using this option handling is included in the
 | |
|       <ref id="sample" name="Sample Driver"> section.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86ShowUnusedOptions(int scrnIndex, pointer options)&e.code;
 | |
|     <quote><p>
 | |
|       Prints out warning messages for each option in the list of options
 | |
|       that isn't marked as used.  This is intended to show options that
 | |
|       the driver hasn't recognised.  It would normally be called near
 | |
|       the end of the &s.code;ChipScreenInit()&e.code; function, but only
 | |
|       when &s.code;serverGeneration == 1&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;OptionInfoPtr xf86TokenToOptinfo(const OptionInfoRec *table,
 | |
| 			&f.indent;int token)&e.code;
 | |
| 
 | |
|     <quote><p>
 | |
|       Returns a pointer to the &s.code;OptionInfoRec&e.code; in
 | |
|       &s.code;table&e.code; with a token field matching
 | |
|       &s.code;token&e.code;.  Returns &s.code;NULL&e.code; if no match
 | |
|       is found.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86IsOptionSet(const OptionInfoRec *table, int token)&e.code;
 | |
|     <quote><p>
 | |
|       Returns the &s.code;found&e.code; field of the
 | |
|       &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; with a
 | |
|       &s.code;token&e.code; field matching &s.code;token&e.code;.  This
 | |
|       can be used for options of all types.  Note that for options of
 | |
|       type &s.code;OPTV_BOOLEAN&e.code;, it isn't sufficient to check
 | |
|       this to determine the value of the option.  Returns
 | |
|       &s.code;FALSE&e.code; if no match is found.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;char *xf86GetOptValString(const OptionInfoRec *table, int token)&e.code;
 | |
|     <quote><p>
 | |
|       Returns the &s.code;value.str&e.code; field of the
 | |
|       &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; with a
 | |
|       token field matching &s.code;token&e.code;.  Returns
 | |
|       &s.code;NULL&e.code; if no match is found.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86GetOptValInteger(const OptionInfoRec *table, int token,
 | |
| 			&f.indent;int *value)&e.code;
 | |
|     <quote><p>
 | |
|       Returns via &s.code;*value&e.code; the &s.code;value.num&e.code;
 | |
|       field of the &s.code;OptionInfoRec&e.code; in &s.code;table&e.code;
 | |
|       with a &s.code;token&e.code; field matching &s.code;token&e.code;.
 | |
|       &s.code;*value&e.code; is only changed when a match is found so
 | |
|       it can be safely initialised with a default prior to calling this
 | |
|       function.  The function return value is as for
 | |
|       &s.code;xf86IsOptionSet()&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86GetOptValULong(const OptionInfoRec *table, int token,
 | |
| 			&f.indent;unsigned long *value)&e.code;
 | |
|     <quote><p>
 | |
|       Like &s.code;xf86GetOptValInteger()&e.code;, except the value is
 | |
|       treated as an &s.code;unsigned long&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86GetOptValReal(const OptionInfoRec *table, int token,
 | |
| 			&f.indent;double *value)&e.code;
 | |
|     <quote><p>
 | |
|       Like &s.code;xf86GetOptValInteger()&e.code;, except that
 | |
|       &s.code;value.realnum&e.code; is used.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86GetOptValFreq(const OptionInfoRec *table, int token,
 | |
| 			&f.indent;OptFreqUnits expectedUnits, double *value)&e.code;
 | |
|     <quote><p>
 | |
|       Like &s.code;xf86GetOptValInteger()&e.code;, except that the
 | |
|       &s.code;value.freq&e.code; data is returned.  The frequency value
 | |
|       is scaled to the units indicated by &s.code;expectedUnits&e.code;.
 | |
|       The scaling is exact when the units were specified explicitly in
 | |
|       the option's value.  Otherwise, the &s.code;expectedUnits&e.code;
 | |
|       field is used as a hint when doing the scaling.  In this case,
 | |
|       values larger than &s.code;1000&e.code; are assumed to have be
 | |
|       specified in the next smallest units.  For example, if the Option
 | |
|       value is "10000" and expectedUnits is &s.code;OPTUNITS_MHZ&e.code;,
 | |
|       the value returned is &s.code;10&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value)&e.code;
 | |
|     <quote><p>
 | |
|       This function is used to check boolean options
 | |
|       (&s.code;OPTV_BOOLEAN&e.code;).  If the function return value is
 | |
|       &s.code;FALSE&e.code;, it means the option wasn't set.  Otherwise
 | |
|       &s.code;*value&e.code; is set to the boolean value indicated by
 | |
|       the option's value.  No option &s.code;value&e.code; is interpreted
 | |
|       as &s.code;TRUE&e.code;.  Option values meaning &s.code;TRUE&e.code;
 | |
|       are "1", "yes", "on", "true", and option values meaning
 | |
|       &s.code;FALSE&e.code; are "0", "no", "off", "false".  Option names
 | |
|       both with the "no" prefix in their names, and with that prefix
 | |
|       removed are also checked and handled in the obvious way.
 | |
|       &s.code;*value&e.code; is not changed when the option isn't present.
 | |
|       It should normally be set to a default value before calling this
 | |
|       function.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def)&e.code;
 | |
|     <quote><p>
 | |
|       This function is used to check boolean options
 | |
|       (&s.code;OPTV_BOOLEAN&e.code;).  If the option is set, its value
 | |
|       is returned.  If the options is not set, the default value specified
 | |
|       by &s.code;def&e.code; is returned.  The option interpretation is
 | |
|       the same as for &s.code;xf86GetOptValBool()&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;int xf86NameCmp(const char *s1, const char *s2)&e.code;
 | |
|     <quote><p>
 | |
|       This function should be used when comparing strings from the config
 | |
|       file with expected values.  It works like &s.code;strcmp()&e.code;,
 | |
|       but is not case sensitive and space, tab, and `<tt>_</tt>' characters
 | |
|       are ignored in the comparison.  The use of this function isn't
 | |
|       restricted to parsing option values.  It may be used anywhere
 | |
|       where this functionality required.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect>Modules, Drivers, Include Files and Interface Issues
 | |
| <p>
 | |
| 
 | |
| NOTE: this section is incomplete.
 | |
| 
 | |
| 
 | |
| <sect1>Include files
 | |
| <p>
 | |
| 
 | |
| The following include files are typically required by video drivers:
 | |
| 
 | |
|   <quote><p>
 | |
|   All drivers should include these:
 | |
|   <quote>
 | |
|     &s.code;"xf86.h"&nl;
 | |
|     "xf86_OSproc.h"&nl;
 | |
|     "xf86_ansic.h"&nl;
 | |
|     "xf86Resources.h"&e.code;
 | |
|   </quote>
 | |
|   Wherever inb/outb (and related things) are used the following should be
 | |
|   included:
 | |
|   <quote>
 | |
|     &s.code;"compiler.h"&e.code;
 | |
|   </quote>
 | |
|   Note: in drivers, this must be included after &s.code;"xf86_ansic.h"&e.code;.
 | |
| 
 | |
|   Drivers that need to access PCI vendor/device definitions need this:
 | |
|   <quote>
 | |
|     &s.code;"xf86PciInfo.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers that need to access the PCI config space need this:
 | |
|   <quote>
 | |
|     &s.code;"xf86Pci.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers that initialise a SW cursor need this:
 | |
|   <quote>
 | |
|     &s.code;"mipointer.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   All drivers implementing backing store need this:
 | |
|   <quote>
 | |
|     &s.code;"mibstore.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   All drivers using the mi colourmap code need this:
 | |
|   <quote>
 | |
|     &s.code;"micmap.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   If a driver uses the vgahw module, it needs this:
 | |
|   <quote>
 | |
|     &s.code;"vgaHW.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers supporting VGA or Hercules monochrome screens need:
 | |
|   <quote>
 | |
|     &s.code;"xf1bpp.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers supporting VGA or EGC 16-colour screens need:
 | |
|   <quote>
 | |
|     &s.code;"xf4bpp.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers using cfb need:
 | |
|   <quote>
 | |
|     &s.code;#define PSZ 8&nl;
 | |
|     #include "cfb.h"&nl;
 | |
|     #undef PSZ&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
 | |
|   <quote>
 | |
|     &s.code;"cfb16.h"&nl;
 | |
|     "cfb24.h"&nl;
 | |
|     "cfb32.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   If a driver uses XAA, it needs these:
 | |
|   <quote>
 | |
|     &s.code;"xaa.h"&nl;
 | |
|     "xaalocal.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   If a driver uses the fb manager, it needs this:
 | |
|   <quote>
 | |
|     &s.code;"xf86fbman.h"&e.code;
 | |
|   </quote>
 | |
|   </quote>
 | |
| 
 | |
| Non-driver modules should include &s.code;"xf86_ansic.h"&e.code; to get the correct
 | |
| wrapping of ANSI C/libc functions.
 | |
| 
 | |
| All modules must NOT include any system include files, or the following:
 | |
| 
 | |
|  <quote>
 | |
|     &s.code;"xf86Priv.h"&nl;
 | |
|     "xf86Privstr.h"&nl;
 | |
|     "xf86_OSlib.h"&nl;
 | |
|     "Xos.h"&e.code;
 | |
|  </quote>
 | |
| 
 | |
| In addition, "xf86_libc.h" must not be included explicitly.  It is
 | |
| included implicitly by "xf86_ansic.h".
 | |
| 
 | |
| 
 | |
| <sect>Offscreen Memory Manager
 | |
| <p>
 | |
| 
 | |
| Management of offscreen video memory may be handled by the XFree86
 | |
| framebuffer manager.  Once the offscreen memory manager is running,
 | |
| drivers or extensions may allocate, free or resize areas of offscreen
 | |
| video memory using the following functions (definitions taken from
 | |
| &s.code;xf86fbman.h&e.code;):
 | |
| 
 | |
| <code>
 | |
|     typedef struct _FBArea {
 | |
|         ScreenPtr    pScreen;
 | |
|         BoxRec       box;
 | |
|         int          granularity;
 | |
|         void         (*MoveAreaCallback)(struct _FBArea*, struct _FBArea*)
 | |
|         void         (*RemoveAreaCallback)(struct _FBArea*)
 | |
|         DevUnion     devPrivate;
 | |
|     } FBArea, *FBAreaPtr;
 | |
| 
 | |
|     typedef void (*MoveAreaCallbackProcPtr)(FBAreaPtr from, FBAreaPtr to)
 | |
|     typedef void (*RemoveAreaCallbackProcPtr)(FBAreaPtr)
 | |
| 
 | |
|     FBAreaPtr xf86AllocateOffscreenArea (
 | |
|         ScreenPtr pScreen,
 | |
|         int width, int height,
 | |
|         int granularity,
 | |
|         MoveAreaCallbackProcPtr MoveAreaCallback,
 | |
|         RemoveAreaCallbackProcPtr RemoveAreaCallback,
 | |
|         pointer privData
 | |
|     )
 | |
| 
 | |
|     void xf86FreeOffscreenArea (FBAreaPtr area)
 | |
| 
 | |
|     Bool xf86ResizeOffscreenArea (
 | |
| 	FBAreaPtr area
 | |
| 	int w, int h
 | |
|     )
 | |
| </code>
 | |
| 
 | |
| The function:
 | |
| <quote>
 | |
|     &s.code;Bool xf86FBManagerRunning(ScreenPtr pScreen)&e.code;
 | |
| </quote>
 | |
| 
 | |
| can be used by an extension to check if the driver has initialized
 | |
| the memory manager.  The manager is not available if this returns
 | |
| &s.code;FALSE&e.code; and the functions above will all fail.
 | |
| 
 | |
| 
 | |
| &s.code;xf86AllocateOffscreenArea()&e.code; can be used to request a
 | |
| rectangle of dimensions &s.code;width&e.code; x &s.code;height&e.code;
 | |
| (in pixels) from unused offscreen memory.  &s.code;granularity&e.code;
 | |
| specifies that the leftmost edge of the rectangle must lie on some
 | |
| multiple of &s.code;granularity&e.code; pixels.  A granularity of zero
 | |
| means the same thing as a granularity of one - no alignment preference.
 | |
| A &s.code;MoveAreaCallback&e.code; can be provided to notify the requester
 | |
| when the offscreen area is moved.  If no &s.code;MoveAreaCallback&e.code;
 | |
| is supplied then the area is considered to be immovable.  The
 | |
| &s.code;privData&e.code; field will be stored in the manager's internal
 | |
| structure for that allocated area and will be returned to the requester
 | |
| in the &s.code;FBArea&e.code; passed via the
 | |
| &s.code;MoveAreaCallback&e.code;.  An optional
 | |
| &s.code;RemoveAreaCallback&e.code; is provided.  If the driver provides
 | |
| this it indicates that the area should be allocated with a lower priority.
 | |
| Such an area may be removed when a higher priority request (one that
 | |
| doesn't have a &s.code;RemoveAreaCallback&e.code;) is made.  When this
 | |
| function is called, the driver will have an opportunity to do whatever
 | |
| cleanup it needs to do to deal with the loss of the area, but it must
 | |
| finish its cleanup before the function exits since the offscreen memory
 | |
| manager will free the area immediately after.
 | |
| 
 | |
| &s.code;xf86AllocateOffscreenArea()&e.code; returns &s.code;NULL&e.code;
 | |
| if it was unable to allocate the requested area.  When no longer needed,
 | |
| areas should be freed with &s.code;xf86FreeOffscreenArea()&e.code;.
 | |
| 
 | |
| &s.code;xf86ResizeOffscreenArea()&e.code; resizes an existing
 | |
| &s.code;FBArea&e.code;.  &s.code;xf86ResizeOffscreenArea()&e.code;
 | |
| returns &s.code;TRUE&e.code; if the resize was successful.  If
 | |
| &s.code;xf86ResizeOffscreenArea()&e.code; returns &s.code;FALSE&e.code;,
 | |
| the original &s.code;FBArea&e.code; is left unmodified.  Resizing an
 | |
| area maintains the area's original &s.code;granularity&e.code;,
 | |
| &s.code;devPrivate&e.code;, and &s.code;MoveAreaCallback&e.code;.
 | |
| &s.code;xf86ResizeOffscreenArea()&e.code; has considerably less overhead
 | |
| than freeing the old area then reallocating the new size, so it should
 | |
| be used whenever possible.
 | |
| 
 | |
| The function:
 | |
|   <quote>
 | |
|    &s.code;Bool xf86QueryLargestOffscreenArea(
 | |
|      &f.indent;ScreenPtr pScreen,
 | |
|      &f.indent;int *width, int *height,
 | |
|      &f.indent;int granularity,
 | |
|      &f.indent;int preferences,
 | |
|      &f.indent;int priority
 | |
|    &nl)&e.code;
 | |
|   </quote>
 | |
| 
 | |
| is provided to query the width and height of the largest single
 | |
| &s.code;FBArea&e.code; allocatable given a particular priority.
 | |
| &s.code;preferences&e.code; can be one of the following to indicate
 | |
| whether width, height or area should be considered when determining
 | |
| which is the largest single &s.code;FBArea&e.code; available.
 | |
| 
 | |
|   <quote>
 | |
|   &s.code;FAVOR_AREA_THEN_WIDTH&nl;
 | |
|   FAVOR_AREA_THEN_HEIGHT&nl;
 | |
|   FAVOR_WIDTH_THEN_AREA&nl;
 | |
|   FAVOR_HEIGHT_THEN_AREA&e.code;
 | |
|   </quote>
 | |
| 
 | |
| &s.code;priority&e.code; is one of the following:
 | |
| 
 | |
|   <quote><p>
 | |
|   &s.code;PRIORITY_LOW&e.code;
 | |
|   <quote><p>
 | |
|      Return the largest block available without stealing anyone else's
 | |
|      space.  This corresponds to the priority of allocating a
 | |
|      &s.code;FBArea&e.code; when a &s.code;RemoveAreaCallback&e.code;
 | |
|      is provided.
 | |
| 
 | |
|   </quote>
 | |
|   &s.code;PRIORITY_NORMAL&e.code;
 | |
|   <quote><p>
 | |
|      Return the largest block available if it is acceptable to steal a
 | |
|      lower priority area from someone.  This corresponds to the priority
 | |
|      of allocating a &s.code;FBArea&e.code; without providing a
 | |
|      &s.code;RemoveAreaCallback&e.code;.
 | |
| 
 | |
|   </quote>
 | |
|   &s.code;PRIORITY_EXTREME&e.code;
 | |
|   <quote><p>
 | |
|      Return the largest block available if all &s.code;FBAreas&e.code;
 | |
|      that aren't locked down were expunged from memory first.  This
 | |
|      corresponds to any allocation made directly after a call to
 | |
|      &s.code;xf86PurgeUnlockedOffscreenAreas()&e.code;.
 | |
| 
 | |
|   </quote>
 | |
|   </quote>
 | |
| 
 | |
| 
 | |
| The function:
 | |
| 
 | |
|   <quote>
 | |
|     &s.code;Bool xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen)&e.code;
 | |
|   </quote>
 | |
| 
 | |
| is provided as an extreme method to free up offscreen memory.  This
 | |
| will remove all removable &s.code;FBArea&e.code; allocations.
 | |
| 
 | |
| 
 | |
| Initialization of the XFree86 framebuffer manager is done via
 | |
| 
 | |
|   <quote>
 | |
|     &s.code;Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox)&e.code;
 | |
|   </quote>
 | |
| 
 | |
| &s.code;FullBox&e.code; represents the area of the framebuffer that the
 | |
| manager is allowed to manage.  This is typically a box with a width of
 | |
| &s.code;pScrn->displayWidth&e.code; and a height of as many lines as
 | |
| can be fit within the total video memory, however, the driver can reserve
 | |
| areas at the extremities by passing a smaller area to the manager.
 | |
| 
 | |
| &s.code;xf86InitFBManager()&e.code; must be called before XAA is
 | |
| initialized since XAA uses the manager for it's pixmap cache.
 | |
| 
 | |
| An alternative function is provided to allow the driver to initialize
 | |
| the framebuffer manager with a Region rather than a box.
 | |
| 
 | |
|   <quote>
 | |
|    &s.code;Bool xf86InitFBManagerRegion(ScreenPtr pScreen,
 | |
| 	&f.indent;RegionPtr FullRegion)&e.code;
 | |
|   </quote>
 | |
| 
 | |
| &s.code;xf86InitFBManagerRegion()&e.code;, unlike
 | |
| &s.code;xf86InitFBManager()&e.code;, does not remove the area used for
 | |
| the visible screen so that area should not be included in the region
 | |
| passed to the function.  &s.code;xf86InitFBManagerRegion()&e.code; is
 | |
| useful when non-contiguous areas are available to be managed, and is
 | |
| required when multiple framebuffers are stored in video memory (as in
 | |
| the case where an overlay of a different depth is stored as a second
 | |
| framebuffer in offscreen memory).
 | |
| 
 | |
| 
 | |
| <sect>Colormap Handling<label id="cmap">
 | |
| <p>
 | |
| 
 | |
| A generic colormap handling layer is provided within the XFree86 common
 | |
| layer.  This layer takes care of most of the details, and only requires
 | |
| a function from the driver that loads the hardware palette when required.
 | |
| To use the colormap layer, a driver calls the
 | |
| &s.code;xf86HandleColormaps()&e.code; function.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool xf86HandleColormaps(ScreenPtr pScreen, int maxColors,
 | |
| 		&f.indent;int sigRGBbits, LoadPaletteFuncPtr loadPalette,
 | |
| 		&f.indent;SetOverscanFuncPtr setOverscan,
 | |
| 		unsigned int flags)&e.code;
 | |
|     <quote><p>
 | |
|       This function must be called after the default colormap has been
 | |
|       initialised.  The &s.code;pScrn->gamma&e.code; field must also
 | |
|       be initialised, preferably by calling &s.code;xf86SetGamma()&e.code;.
 | |
|       &s.code;maxColors&e.code; is the number of entries in the palette.
 | |
|       &s.code;sigRGBbits&e.code; is the size in bits of each color
 | |
|       component in the DAC's palette.  &s.code;loadPalette&e.code;
 | |
|       is a driver-provided function for loading a colormap into the
 | |
|       hardware, and is described below.  &s.code;setOverscan&e.code; is
 | |
|       an optional function that may be provided when the overscan color
 | |
|       is an index from the standard LUT and when it needs to be adjusted
 | |
|       to keep it as close to black as possible.  The
 | |
|       &s.code;setOverscan&e.code; function programs the overscan index.
 | |
|       It shouldn't normally be used for depths other than 8.
 | |
|       &s.code;setOverscan&e.code; should be set to &s.code;NULL&e.code;
 | |
|       when it isn't needed.  &s.code;flags&e.code; may be set to the
 | |
|       following (which may be ORed together):
 | |
| 
 | |
|       &s.code;CMAP_PALETTED_TRUECOLOR&e.code;
 | |
|       <quote><p>
 | |
| 				    the TrueColor visual is paletted and is
 | |
| 				    just a special case of DirectColor.
 | |
| 				    This flag is only valid for
 | |
| 				    &s.code;bpp > 8&e.code;.
 | |
| 
 | |
|       </quote>
 | |
| 
 | |
|       &s.code;CMAP_RELOAD_ON_MODE_SWITCH&e.code;
 | |
|       <quote><p>
 | |
| 				    reload the colormap automatically
 | |
|                                     after mode switches.  This is useful
 | |
|                                     for when the driver is resetting the
 | |
|                                     hardware during mode switches and
 | |
|                                     corrupting or erasing the hardware
 | |
|                                     palette.
 | |
| 
 | |
|       </quote>
 | |
| 
 | |
|       &s.code;CMAP_LOAD_EVEN_IF_OFFSCREEN&e.code;
 | |
|       <quote><p>
 | |
| 				    reload the colormap even if the screen
 | |
| 				    is switched out of the server's VC.
 | |
| 				    The palette is <it>not</it> reloaded when
 | |
| 				    the screen is switched back in, nor after
 | |
| 				    mode switches.  This is useful when the
 | |
| 				    driver needs to keep track of palette
 | |
| 				    changes.
 | |
| 
 | |
|       </quote>
 | |
| 
 | |
|       The colormap layer normally reloads the palette after VT enters so it
 | |
|       is not necessary for the driver to save and restore the palette
 | |
|       when switching VTs.  The driver must, however, still save the
 | |
|       initial palette during server start up and restore it during
 | |
|       server exit.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
 | |
| 		&f.indent;LOCO *colors, VisualPtr pVisual)&e.code;
 | |
|     <quote><p>
 | |
|       &s.code;LoadPalette()&e.code; is a driver-provided function for
 | |
|       loading a colormap into hardware.  &s.code;colors&e.code; is the
 | |
|       array of RGB values that represent the full colormap.
 | |
|       &s.code;indices&e.code; is a list of index values into the colors
 | |
|       array.  These indices indicate the entries that need to be updated.
 | |
|       &s.code;numColors&e.code; is the number of the indices to be
 | |
|       updated.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void SetOverscan(ScrnInfoPtr pScrn, int overscan)&e.code;
 | |
|     <quote><p>
 | |
|       &s.code;SetOverscan()&e.code; is a driver-provided function for
 | |
|       programming the &s.code;overscan&e.code; index.  As described
 | |
|       above, it is normally only appropriate for LUT modes where all
 | |
|       colormap entries are available for the display, but where one of
 | |
|       them is also used for the overscan (typically 8bpp for VGA compatible
 | |
|       LUTs).  It isn't required in cases where the overscan area is
 | |
|       never visible.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
| <sect>DPMS Extension
 | |
| <p>
 | |
| 
 | |
| Support code for the DPMS extension is included in the XFree86 common layer.
 | |
| This code provides an interface between the main extension code, and a means
 | |
| for drivers to initialise DPMS when they support it.  One function is
 | |
| available to drivers to do this initialisation, and it is always available,
 | |
| even when the DPMS extension is not supported by the core server (in
 | |
| which case it returns a failure result).
 | |
| 
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       This function registers a driver's DPMS level programming function
 | |
|       &s.code;set&e.code;.  It also checks
 | |
|       &s.code;pScrn->options&e.code; for the "dpms" option, and when
 | |
|       present marks DPMS as being enabled for that screen.  The
 | |
|       &s.code;set&e.code; function is called whenever the DPMS level
 | |
|       changes, and is used to program the requested level.
 | |
|       &s.code;flags&e.code; is currently not used, and should be
 | |
|       &s.code;0&e.code;.  If the initialisation fails for any reason,
 | |
|       including when there is no DPMS support in the core server, the
 | |
|       function returns &s.code;FALSE&e.code;.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
| Drivers that implement DPMS support must provide the following function,
 | |
| that gets called when the DPMS level is changed:
 | |
| 
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;void ChipDPMSSet(ScrnInfoPtr pScrn, int level, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       Program the DPMS level specified by &s.code;level&e.code;.  Valid
 | |
|       values of &s.code;level&e.code; are &s.code;DPMSModeOn&e.code;,
 | |
|       &s.code;DPMSModeStandby&e.code;, &s.code;DPMSModeSuspend&e.code;,
 | |
|       &s.code;DPMSModeOff&e.code;.  These values are defined in
 | |
|       &s.code;"extensions/dpms.h"&e.code;.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| 
 | |
| <sect>DGA Extension
 | |
| <p>
 | |
| 
 | |
| Drivers can support the XFree86 Direct Graphics Architecture (DGA) by
 | |
| filling out a structure of function pointers and a list of modes and
 | |
| passing them to DGAInit.
 | |
| 
 | |
|     <quote><p>
 | |
|     &s.code;Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs,
 | |
| 			&f.indent;DGAModePtr modes, int num)&e.code;
 | |
|     <quote><p>
 | |
|     <verb>
 | |
| /** The DGAModeRec **/
 | |
| 
 | |
| typedef struct {
 | |
|   int num;
 | |
|   DisplayModePtr mode;
 | |
|   int flags;
 | |
|   int imageWidth;
 | |
|   int imageHeight;
 | |
|   int pixmapWidth;
 | |
|   int pixmapHeight;
 | |
|   int bytesPerScanline;
 | |
|   int byteOrder;
 | |
|   int depth;
 | |
|   int bitsPerPixel;
 | |
|   unsigned long red_mask;
 | |
|   unsigned long green_mask;
 | |
|   unsigned long blue_mask;
 | |
|   int viewportWidth;
 | |
|   int viewportHeight;
 | |
|   int xViewportStep;
 | |
|   int yViewportStep;
 | |
|   int maxViewportX;
 | |
|   int maxViewportY;
 | |
|   int viewportFlags;
 | |
|   int offset;
 | |
|   unsigned char *address;
 | |
|   int reserved1;
 | |
|   int reserved2;
 | |
| } DGAModeRec, *DGAModePtr;
 | |
| </verb>
 | |
| 
 | |
|       &s.code;num&e.code;
 | |
| 	<quote>
 | |
| 	 Can be ignored.  The DGA DDX will assign these numbers.
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;mode&e.code;
 | |
| 	<quote>
 | |
| 	A pointer to the &s.code;DisplayModeRec&e.code; for this mode.
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;flags&e.code;
 | |
| 	<quote><p>
 | |
| 	The following flags are defined and may be OR'd together:
 | |
| 
 | |
|         &s.code;DGA_CONCURRENT_ACCESS&e.code;
 | |
| 	    <quote><p>
 | |
|             Indicates that the driver supports concurrent graphics
 | |
|             accelerator and linear framebuffer access.
 | |
| 
 | |
| 	    </quote>
 | |
| 
 | |
|         &s.code;DGA_FILL_RECT&nl;
 | |
| 	DGA_BLIT_RECT&nl;
 | |
|         DGA_BLIT_RECT_TRANS&e.code;
 | |
| 	    <quote><p>
 | |
| 	    Indicates that the driver supports the FillRect, BlitRect
 | |
|             or BlitTransRect functions in this mode.
 | |
| 
 | |
| 	    </quote>
 | |
| 
 | |
|         &s.code;DGA_PIXMAP_AVAILABLE&e.code;
 | |
| 	    <quote><p>
 | |
| 	    Indicates that Xlib may be used on the framebuffer.
 | |
|             This flag will usually be set unless the driver wishes
 | |
|             to prohibit this for some reason.
 | |
| 
 | |
| 	    </quote>
 | |
| 
 | |
|         &s.code;DGA_INTERLACED&nl;
 | |
|         DGA_DOUBLESCAN&e.code;
 | |
| 	    <quote><p>
 | |
|             Indicates that these are interlaced or double scan modes.
 | |
| 
 | |
| 	    </quote>
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;imageWidth&nl;
 | |
|       imageHeight&e.code;
 | |
| 	<quote><p>
 | |
| 		    These are the dimensions of the linear framebuffer
 | |
|                      accessible by the client.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;pixmapWidth&nl;
 | |
|       pixmapHeight&e.code;
 | |
| 	<quote><p>
 | |
| 		     These are the dimensions of the area of the
 | |
|                      framebuffer accessible by the graphics accelerator.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;bytesPerScanline&e.code;
 | |
| 	<quote><p>
 | |
| 		      Pitch of the framebuffer in bytes.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;byteOrder&e.code;
 | |
| 	<quote><p>
 | |
| 		     Usually the same as
 | |
| 		     &s.code;pScrn->imageByteOrder&e.code;.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;depth&e.code;
 | |
| 	<quote><p>
 | |
| 		     The depth of the framebuffer in this mode.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;bitsPerPixel&e.code;
 | |
| 	<quote><p>
 | |
| 		      The number of bits per pixel in this mode.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;red_mask&nl;
 | |
|       green_mask&nl;
 | |
|       blue_mask&e.code;
 | |
| 	<quote><p>
 | |
| 		      The RGB masks for this mode, if applicable.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;viewportWidth&nl;
 | |
|       viewportHeight&e.code;
 | |
| 	<quote><p>
 | |
| 		      Dimensions of the visible part of the framebuffer.
 | |
| 		      Usually &s.code;mode->HDisplay&e.code; and
 | |
| 		      &s.code;mode->VDisplay&e.code;.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;xViewportStep&nl;
 | |
|       yViewportStep&e.code;
 | |
| 	<quote><p>
 | |
| 		     The granularity of x and y viewport positions that
 | |
|                      the driver supports in this mode.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;maxViewportX&nl;
 | |
|       maxViewportY&e.code;
 | |
| 	<quote><p>
 | |
| 		      The maximum viewport position supported by the
 | |
|                        driver in this mode.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;viewportFlags&e.code;
 | |
| 	<quote><p>
 | |
| 		     The following may be OR'd together:
 | |
| 
 | |
|        &s.code;DGA_FLIP_IMMEDIATE&e.code;
 | |
| 	    <quote><p>
 | |
| 		The driver supports immediate viewport changes.
 | |
| 
 | |
| 	    </quote>
 | |
|        &s.code;DGA_FLIP_RETRACE&e.code;
 | |
| 	    <quote<p>
 | |
| 		The driver supports viewport changes at retrace.
 | |
| 
 | |
| 	    </quote>
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;offset&e.code;
 | |
| 	<quote><p>
 | |
| 	        The offset into the linear framebuffer that corresponds to
 | |
|                 pixel (0,0) for this mode.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;address&e.code;
 | |
|         <quote><p>
 | |
|                 The virtual address of the framebuffer as mapped by the driver.
 | |
|                 This is needed when DGA_PIXMAP_AVAILABLE is set.
 | |
| 
 | |
|         </quote>
 | |
| 
 | |
|       <verb>
 | |
| /** The DGAFunctionRec **/
 | |
| 
 | |
| typedef struct {
 | |
|   Bool (*OpenFramebuffer)(
 | |
|        ScrnInfoPtr pScrn,
 | |
|        char **name,
 | |
|        unsigned char **mem,
 | |
|        int *size,
 | |
|        int *offset,
 | |
|        int *extra
 | |
|   );
 | |
|   void (*CloseFramebuffer)(ScrnInfoPtr pScrn);
 | |
|   Bool (*SetMode)(ScrnInfoPtr pScrn, DGAModePtr pMode);
 | |
|   void (*SetViewport)(ScrnInfoPtr pScrn, int x, int y, int flags);
 | |
|   int  (*GetViewport)(ScrnInfoPtr pScrn);
 | |
|   void (*Sync)(ScrnInfoPtr);
 | |
|   void (*FillRect)(
 | |
|        ScrnInfoPtr pScrn,
 | |
|        int x, int y, int w, int h,
 | |
|        unsigned long color
 | |
|   );
 | |
|   void (*BlitRect)(
 | |
|        ScrnInfoPtr pScrn,
 | |
|        int srcx, int srcy,
 | |
|        int w, int h,
 | |
|        int dstx, int dsty
 | |
|   );
 | |
|   void (*BlitTransRect)(
 | |
|        ScrnInfoPtr pScrn,
 | |
|        int srcx, int srcy,
 | |
|        int w, int h,
 | |
|        int dstx, int dsty,
 | |
|        unsigned long color
 | |
|   );
 | |
| } DGAFunctionRec, *DGAFunctionPtr;
 | |
| </verb>
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool OpenFramebuffer (pScrn, name, mem, size, offset, extra)&e.code;
 | |
|     <quote><p>
 | |
|       &s.code;OpenFramebuffer()&e.code; should pass the client everything
 | |
|       it needs to know to be able to open the framebuffer.  These
 | |
|       parameters are OS specific and their meanings are to be interpreted
 | |
|       by an OS specific client library.
 | |
| 
 | |
|       &s.code;name&e.code;
 | |
| 	<quote><p>
 | |
| 	      The name of the device to open or &s.code;NULL&e.code; if
 | |
| 	      there is no special device to open.  A &s.code;NULL&e.code;
 | |
| 	      name tells the client that it should open whatever device
 | |
| 	      one would usually open to access physical memory.
 | |
| 
 | |
| 	</quote>
 | |
|       &s.code;mem&e.code;
 | |
| 	<quote><p>
 | |
| 	       The physical address of the start of the framebuffer.
 | |
| 
 | |
| 	</quote>
 | |
|       &s.code;size&e.code;
 | |
| 	<quote><p>
 | |
| 	      The size of the framebuffer in bytes.
 | |
| 
 | |
| 	</quote>
 | |
|       &s.code;offset&e.code;
 | |
| 	<quote><p>
 | |
| 	      Any offset into the device, if applicable.
 | |
| 
 | |
| 	</quote>
 | |
|       &s.code;flags&e.code;
 | |
| 	<quote><p>
 | |
| 	      Any additional information that the client may need.
 | |
| 	      Currently, only the &s.code;DGA_NEED_ROOT&e.code; flag is
 | |
| 	      defined.
 | |
| 
 | |
| 	</quote>
 | |
|    </quote>
 | |
| 
 | |
|     &s.code;void CloseFramebuffer (pScrn)&e.code;
 | |
|     <quote><p>
 | |
|       &s.code;CloseFramebuffer()&e.code; merely informs the driver (if it
 | |
|       even cares) that client no longer needs to access the framebuffer
 | |
|       directly.  This function is optional.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool SetMode (pScrn, pMode)&e.code;
 | |
|     <quote><p>
 | |
|       &s.code;SetMode()&e.code; tells the driver to initialize the mode
 | |
|       passed to it.  If &s.code;pMode&e.code; is &s.code;NULL&e.code;,
 | |
|       then the driver should restore the original pre-DGA mode.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void SetViewport (pScrn, x, y, flags)&e.code;
 | |
|     <quote><p>
 | |
|       &s.code;SetViewport()&e.code; tells the driver to make the upper
 | |
|       left-hand corner of the visible screen correspond to coordinate
 | |
|       &s.code;(x,y)&e.code; on the framebuffer.  &s.code;Flags&e.code;
 | |
|       currently defined are:
 | |
| 
 | |
|        &s.code;DGA_FLIP_IMMEDIATE&e.code;
 | |
| 	<quote><p>
 | |
| 	    The viewport change should occur immediately.
 | |
| 
 | |
| 	</quote>
 | |
|        &s.code;DGA_FLIP_RETRACE&e.code;
 | |
| 	<quote><p>
 | |
| 	    The viewport change should occur at the
 | |
|             vertical retrace, but this function should
 | |
|             return sooner if possible.
 | |
| 
 | |
| 	</quote>
 | |
|       The &s.code;(x,y)&e.code; locations will be passed as the client
 | |
|       specified them, however, the driver is expected to round these
 | |
|       locations down to the next supported location as specified by the
 | |
|       &s.code;xViewportStep&e.code; and &s.code;yViewportStep&e.code;
 | |
|       for the current mode.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;int GetViewport (pScrn)&e.code;
 | |
|     <quote><p>
 | |
|       &s.code;GetViewport()&e.code; gets the current page flip status.
 | |
|       Set bits in the returned int correspond to viewport change requests
 | |
|       still pending.  For instance, set bit zero if the last SetViewport
 | |
|       request is still pending, bit one if the one before that is still
 | |
|       pending, etc.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void Sync (pScrn)&e.code;
 | |
|     <quote><p>
 | |
|       This function should ensure that any graphics accelerator operations
 | |
|       have finished.  This function should not return until the graphics
 | |
|       accelerator is idle.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void FillRect (pScrn, x, y, w, h, color)&e.code;
 | |
|     <quote><p>
 | |
|       This optional function should fill a rectangle
 | |
|       &s.code;w × h&e.code; located at
 | |
|       &s.code;(x,y)&e.code; in the given color.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void BlitRect (pScrn, srcx, srcy, w, h, dstx, dsty)&e.code;
 | |
|     <quote><p>
 | |
|       This optional function should copy an area
 | |
|       &s.code;w × h&e.code; located at
 | |
|       &s.code;(srcx,srcy)&e.code; to location &s.code;(dstx,dsty)&e.code;.
 | |
|       This function will need to handle copy directions as appropriate.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void BlitTransRect (pScrn, srcx, srcy, w, h, dstx, dsty, color)&e.code;
 | |
|     <quote><p>
 | |
|       This optional function is the same as BlitRect except that pixels
 | |
|       in the source corresponding to the color key &s.code;color&e.code;
 | |
|       should be skipped.
 | |
| 
 | |
|     </quote>
 | |
|     </quote>
 | |
| 
 | |
| <sect>The XFree86 X Video Extension (Xv) Device Dependent Layer
 | |
| <p>
 | |
| 
 | |
| XFree86 offers the X Video Extension which allows clients to treat video
 | |
| as any another primitive and ``Put'' video into drawables.  By default,
 | |
| the extension reports no video adaptors as being available since the
 | |
| DDX layer has not been initialized.  The driver can initialize the DDX
 | |
| layer by filling out one or more &s.code;XF86VideoAdaptorRecs&e.code;
 | |
| as described later in this document and passing a list of
 | |
| &s.code;XF86VideoAdaptorPtr&e.code; pointers to the following function:
 | |
| 
 | |
|   <quote>
 | |
|   &s.code;Bool xf86XVScreenInit(
 | |
| 	&f.indent;ScreenPtr pScreen,
 | |
| 	&f.indent;XF86VideoAdaptorPtr *adaptPtrs,
 | |
| 	&f.indent;int num)&e.code;
 | |
|   </quote>
 | |
| 
 | |
| After doing this, the extension will report video adaptors as being
 | |
| available, providing the data in their respective
 | |
| &s.code;XF86VideoAdaptorRecs&e.code; was valid.
 | |
| &s.code;xf86XVScreenInit()&e.code; <em>copies</em> data from the structure
 | |
| passed to it so the driver may free it after the initialization.  At
 | |
| the moment, the DDX only supports rendering into Window drawables.
 | |
| Pixmap rendering will be supported after a sufficient survey of suitable
 | |
| hardware is completed.
 | |
| 
 | |
| The &s.code;XF86VideoAdaptorRec&e.code;:
 | |
| 
 | |
| <quote><p>
 | |
| <verb>
 | |
| typedef struct {
 | |
| 	unsigned int type;
 | |
| 	int flags;
 | |
| 	char *name;
 | |
| 	int nEncodings;
 | |
| 	XF86VideoEncodingPtr pEncodings;
 | |
| 	int nFormats;
 | |
| 	XF86VideoFormatPtr pFormats;
 | |
| 	int nPorts;
 | |
| 	DevUnion *pPortPrivates;
 | |
| 	int nAttributes;
 | |
| 	XF86AttributePtr pAttributes;
 | |
| 	int nImages;
 | |
| 	XF86ImagePtr pImages;
 | |
| 	PutVideoFuncPtr PutVideo;
 | |
| 	PutStillFuncPtr PutStill;
 | |
| 	GetVideoFuncPtr GetVideo;
 | |
| 	GetStillFuncPtr GetStill;
 | |
| 	StopVideoFuncPtr StopVideo;
 | |
| 	SetPortAttributeFuncPtr SetPortAttribute;
 | |
| 	GetPortAttributeFuncPtr GetPortAttribute;
 | |
| 	QueryBestSizeFuncPtr QueryBestSize;
 | |
| 	PutImageFuncPtr PutImage;
 | |
| 	QueryImageAttributesFuncPtr QueryImageAttributes;
 | |
| } XF86VideoAdaptorRec, *XF86VideoAdaptorPtr;
 | |
| </verb>
 | |
| 
 | |
|    Each adaptor will have its own XF86VideoAdaptorRec.  The fields are
 | |
|    as follows:
 | |
| 
 | |
|      &s.code;type&e.code;
 | |
|      <quote><p>
 | |
| 	This can be any of the following flags OR'd together.
 | |
| 
 | |
| 	&s.code;XvInputMask&e.code;
 | |
| 	&s.code;XvOutputMask&e.code;
 | |
| 	<quote><p>
 | |
| 	    These refer to the target drawable and are similar to a Window's
 | |
| 	    class. &s.code;XvInputMask&e.code; indicates that the adaptor
 | |
| 	    can put video into a drawable.  &s.code;XvOutputMask&e.code;
 | |
| 	    indicates that the adaptor can get video from a drawable.
 | |
| 	</quote>
 | |
| 
 | |
| 	&s.code;XvVideoMask&e.code;
 | |
| 	&s.code;XvStillMask&e.code;
 | |
| 	&s.code;XvImageMask&e.code;
 | |
| 	<quote><p>
 | |
| 	    These indicate that the adaptor supports video, still or
 | |
| 	    image primitives respectively.
 | |
| 	</quote>
 | |
| 
 | |
| 	&s.code;XvWindowMask&e.code;
 | |
| 	&s.code;XvPixmapMask&e.code;
 | |
| 	<quote><p>
 | |
| 	    These indicate the types of drawables the adaptor is capable
 | |
| 	    of rendering into.  At the moment, Pixmap rendering is not
 | |
| 	    supported and the &s.code;XvPixmapMask&e.code; flag is ignored.
 | |
| 	</quote>
 | |
| 
 | |
|      </quote>
 | |
| 
 | |
|      &s.code;flags&e.code;
 | |
|      <quote><p>
 | |
| 	Currently, the following flags are defined:
 | |
| 
 | |
| 	&s.code;VIDEO_NO_CLIPPING&e.code;
 | |
| 	<quote><p>
 | |
| 	   This indicates that the video adaptor does not support
 | |
| 	   clipping.  The driver will never receive ``Put'' requests
 | |
| 	   where less than the entire area determined by
 | |
| 	   &s.code;drw_x&e.code;, &s.code;drw_y&e.code;,
 | |
| 	   &s.code;drw_w&e.code; and &s.code;drw_h&e.code; is visible.
 | |
| 	   This flag does not apply to ``Get'' requests.  Hardware
 | |
| 	   that is incapable of clipping ``Gets'' may punt or get
 | |
| 	   the extents of the clipping region passed to it.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
| 	&s.code;VIDEO_INVERT_CLIPLIST&e.code;
 | |
| 	<quote><p>
 | |
| 	   This indicates that the video driver requires the clip
 | |
| 	   list to contain the regions which are obscured rather
 | |
| 	   than the regions which are are visible.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
| 	&s.code;VIDEO_OVERLAID_STILLS&e.code;
 | |
| 	<quote><p>
 | |
| 	   Implementing PutStill for hardware that does video as an
 | |
| 	   overlay can be awkward since it's unclear how long to leave
 | |
| 	   the video up for.  When this flag is set, StopVideo will be
 | |
| 	   called whenever the destination gets clipped or moved so that
 | |
| 	   the still can be left up until then.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
| 	&s.code;VIDEO_OVERLAID_IMAGES&e.code;
 | |
| 	<quote><p>
 | |
| 	    Same as &s.code;VIDEO_OVERLAID_STILLS&e.code; but for images.
 | |
| 	</quote>
 | |
| 
 | |
| 	&s.code;VIDEO_CLIP_TO_VIEWPORT&e.code;
 | |
| 	<quote><p>
 | |
| 	    Indicates that the clip region passed to the driver functions
 | |
| 	    should be clipped to the visible portion of the screen in the
 | |
| 	    case where the viewport is smaller than the virtual desktop.
 | |
| 	</quote>
 | |
| 
 | |
|      </quote>
 | |
| 
 | |
|      &s.code;name&e.code;
 | |
|      <quote><p>
 | |
| 	The name of the adaptor.
 | |
| 
 | |
|      </quote>
 | |
| 
 | |
|      &s.code;nEncodings&nl;
 | |
|      pEncodings&e.code;
 | |
|      <quote><p>
 | |
| 	The number of encodings the adaptor is capable of and pointer
 | |
| 	to the &s.code;XF86VideoEncodingRec&e.code; array.  The
 | |
| 	&s.code;XF86VideoEncodingRec&e.code; is described later on.
 | |
| 	For drivers that only support XvImages there should be an encoding
 | |
| 	named "XV_IMAGE" and the width and height should specify
 | |
| 	the maximum size source image supported.
 | |
| 
 | |
|      </quote>
 | |
| 
 | |
|      &s.code;nFormats&nl;
 | |
|      pFormats&e.code;
 | |
|      <quote><p>
 | |
| 	The number of formats the adaptor is capable of and pointer to
 | |
| 	the &s.code;XF86VideoFormatRec&e.code; array.  The
 | |
| 	&s.code;XF86VideoFormatRec&e.code; is described later on.
 | |
| 
 | |
|      </quote>
 | |
| 
 | |
|      &s.code;nPorts&nl;
 | |
|      pPortPrivates&e.code;
 | |
|      <quote><p>
 | |
| 	The number of ports is the number of separate data streams which
 | |
| 	the adaptor can handle simultaneously.  If you have more than
 | |
| 	one port, the adaptor is expected to be able to render into more
 | |
| 	than one window at a time.  &s.code;pPortPrivates&e.code; is
 | |
| 	an array of pointers or ints - one for each port.  A port's
 | |
| 	private data will be passed to the driver any time the port is
 | |
| 	requested to do something like put the video or stop the video.
 | |
| 	In the case where there may be many ports, this enables the
 | |
| 	driver to know which port the request is intended for.  Most
 | |
| 	commonly, this will contain a pointer to the data structure
 | |
| 	containing information about the port.  In Xv, all ports on
 | |
| 	a particular adaptor are expected to be identical in their
 | |
| 	functionality.
 | |
| 
 | |
|      </quote>
 | |
| 
 | |
|      &s.code;nAttributes&nl;
 | |
|      pAttributes&e.code;
 | |
|      <quote><p>
 | |
| 	The number of attributes recognized by the adaptor and a pointer to
 | |
| 	the array of &s.code;XF86AttributeRecs&e.code;.  The
 | |
| 	&s.code;XF86AttributeRec&e.code; is described later on.
 | |
| 
 | |
|      </quote>
 | |
| 
 | |
|      &s.code;nImages&nl;
 | |
|      pImages&e.code;
 | |
|      <quote><p>
 | |
| 	The number of &s.code;XF86ImageRecs&e.code; supported by the adaptor
 | |
| 	and a pointer to the array of &s.code;XF86ImageRecs&e.code;. The
 | |
| 	&s.code;XF86ImageRec&e.code; is described later on.
 | |
| 
 | |
|      </quote>
 | |
| 
 | |
| 
 | |
|      &s.code;PutVideo PutStill GetVideo GetStill StopVideo
 | |
|      SetPortAttribute GetPortAttribute QueryBestSize PutImage
 | |
|      QueryImageAttributes&e.code;
 | |
|      <quote><p>
 | |
| 	These functions define the DDX->driver interface.  In each
 | |
| 	case, the pointer &s.code;data&e.code; is passed to the driver.
 | |
| 	This is the port private for that port as described above.  All
 | |
| 	fields are required except under the following conditions:
 | |
| 
 | |
| 	<enum>
 | |
| 	 <item>&s.code;PutVideo&e.code;, &s.code;PutStill&e.code; and
 | |
| 	     the image routines &s.code;PutImage&e.code; and
 | |
| 	     &s.code;QueryImageAttributes&e.code; are not required when the
 | |
| 	     adaptor type does not contain &s.code;XvInputMask&e.code;.
 | |
| 
 | |
| 	 <item>&s.code;GetVideo&e.code; and &s.code;GetStill&e.code;
 | |
| 	     are not required when the adaptor type does not contain
 | |
| 	     &s.code;XvOutputMask&e.code;.
 | |
| 
 | |
| 	 <item>&s.code;GetVideo&e.code; and &s.code;PutVideo&e.code;
 | |
| 	     are not required when the adaptor type does not contain
 | |
| 	     &s.code;XvVideoMask&e.code;.
 | |
| 
 | |
| 	 <item>&s.code;GetStill&e.code; and &s.code;PutStill&e.code;
 | |
| 	     are not required when the adaptor type does not contain
 | |
| 	     &s.code;XvStillMask&e.code;.
 | |
| 
 | |
| 	 <item>&s.code;PutImage&e.code; and &s.code;QueryImageAttributes&e.code;
 | |
| 	     are not required when the adaptor type does not contain
 | |
| 	     &s.code;XvImageMask&e.code;.
 | |
| 
 | |
| 	</enum>
 | |
| 
 | |
| 	With the exception of &s.code;QueryImageAttributes&e.code;, these
 | |
| 	functions should return &s.code;Success&e.code; if the operation was
 | |
| 	completed successfully.  They can return &s.code;XvBadAlloc&e.code;
 | |
| 	otherwise. &s.code;QueryImageAttributes&e.code; returns the size
 | |
| 	of the XvImage queried.
 | |
| 
 | |
| 	If the &s.code;VIDEO_NO_CLIPPING&e.code;
 | |
| 	flag is set, the &s.code;clipBoxes&e.code; may be ignored by
 | |
| 	the driver.  &s.code;ClipBoxes&e.code; is an &s.code;X-Y&e.code;
 | |
| 	banded region identical to those used throughout the server.
 | |
| 	The clipBoxes represent the visible portions of the area determined
 | |
| 	by &s.code;drw_x&e.code;, &s.code;drw_y&e.code;,
 | |
| 	&s.code;drw_w&e.code; and &s.code;drw_h&e.code; in the Get/Put
 | |
| 	function.  The boxes are in screen coordinates, are guaranteed
 | |
| 	not to overlap and an empty region will never be passed.
 | |
| 	If the driver has specified &s.code;VIDEO_INVERT_CLIPLIST&e.code;,
 | |
| 	&s.code;clipBoxes&e.code; will indicate the areas of the primitive
 | |
| 	which are obscured rather than the areas visible.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
| 	&s.code;typedef  int (* PutVideoFuncPtr)( ScrnInfoPtr pScrn,
 | |
| 		&f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
 | |
| 		&f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
 | |
| 		&f.indent;RegionPtr clipBoxes, pointer data )&e.code;
 | |
|     <quote><p>
 | |
| 	  This indicates that the driver should take a subsection
 | |
| 	  &s.code;vid_w&e.code; by &s.code;vid_h&e.code; at location
 | |
| 	  &s.code;(vid_x,vid_y)&e.code; from the video stream and direct
 | |
| 	  it into the rectangle &s.code;drw_w&e.code; by &s.code;drw_h&e.code;
 | |
| 	  at location &s.code;(drw_x,drw_y)&e.code; on the screen, scaling as
 | |
| 	  necessary.  Due to the large variations in capabilities of
 | |
| 	  the various hardware expected to be used with this extension,
 | |
| 	  it is not expected that all hardware will be able to do this
 | |
| 	  exactly as described.  In that case the driver should just do
 | |
| 	  ``the best it can,'' scaling as closely to the target rectangle
 | |
| 	  as it can without rendering outside of it.  In the worst case,
 | |
| 	  the driver can opt to just not turn on the video.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
| 	&s.code;typedef  int (* PutStillFuncPtr)( ScrnInfoPtr pScrn,
 | |
| 		&f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
 | |
| 		&f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
 | |
| 		&f.indent;RegionPtr clipBoxes, pointer data )&e.code;
 | |
|     <quote><p>
 | |
| 	  This is same as &s.code;PutVideo&e.code; except that the driver
 | |
| 	  should place only one frame from the stream on the screen.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
| 	&s.code;typedef int (* GetVideoFuncPtr)( ScrnInfoPtr pScrn,
 | |
| 		&f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
 | |
| 		&f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
 | |
| 		&f.indent;RegionPtr clipBoxes, pointer data )&e.code;
 | |
|     <quote><p>
 | |
| 	  This is same as &s.code;PutVideo&e.code; except that the driver
 | |
| 	  gets video from the screen and outputs it.  The driver should
 | |
| 	  do the best it can to get the requested dimensions correct
 | |
| 	  without reading from an area larger than requested.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
| 	&s.code;typedef int (* GetStillFuncPtr)( ScrnInfoPtr pScrn,
 | |
| 		&f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
 | |
| 		&f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
 | |
| 		&f.indent;RegionPtr clipBoxes, pointer data )&e.code;
 | |
|     <quote><p>
 | |
| 	  This is the same as &s.code;GetVideo&e.code; except that the
 | |
| 	  driver should place only one frame from the screen into the
 | |
| 	  output stream.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
| 	&s.code;typedef void (* StopVideoFuncPtr)(ScrnInfoPtr pScrn,
 | |
| 			&f.indent;pointer data, Bool cleanup)&e.code;
 | |
|     <quote><p>
 | |
| 	  This indicates the driver should stop displaying the video.
 | |
| 	  This is used to stop both input and output video.  The
 | |
| 	  &s.code;cleanup&e.code; field indicates that the video is
 | |
| 	  being stopped because the client requested it to stop or
 | |
| 	  because the server is exiting the current VT.  In that case
 | |
| 	  the driver should deallocate any offscreen memory areas (if
 | |
| 	  there are any) being used to put the video to the screen.  If
 | |
| 	  &s.code;cleanup&e.code; is not set, the video is being stopped
 | |
| 	  temporarily due to clipping or moving of the window, etc...
 | |
| 	  and video will likely be restarted soon so the driver should
 | |
| 	  not deallocate any offscreen areas associated with that port.
 | |
| 
 | |
|     </quote>
 | |
| 	&s.code;typedef int (* SetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
 | |
| 		 &f.indent;Atom attribute,INT32 value, pointer data)&e.code;
 | |
| 
 | |
| 	&s.code;typedef int (* GetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
 | |
| 		&f.indent;Atom attribute,INT32 *value, pointer data)&e.code;
 | |
| 
 | |
|     <quote><p>
 | |
| 	  A port may have particular attributes such as hue,
 | |
| 	  saturation, brightness or contrast.  Xv clients set and
 | |
| 	  get these attribute values by sending attribute strings
 | |
| 	  (Atoms) to the server.  Such requests end up at these
 | |
| 	  driver functions.  It is recommended that the driver provide
 | |
| 	  at least the following attributes mentioned in the Xv client
 | |
| 	  library docs:
 | |
| 	  <quote>
 | |
| 		&s.code;XV_ENCODING&nl;
 | |
| 		XV_HUE&nl;
 | |
| 		XV_SATURATION&nl;
 | |
| 		XV_BRIGHTNESS&nl;
 | |
|   		XV_CONTRAST&e.code;
 | |
| 	  </quote>
 | |
| 	  but the driver may recognize as many atoms as it wishes.  If
 | |
| 	  a requested attribute is unknown by the driver it should return
 | |
| 	  &s.code;BadMatch&e.code;.  &s.code;XV_ENCODING&e.code; is the
 | |
| 	  attribute intended to let the client specify which video
 | |
| 	  encoding the particular port should be using (see the description
 | |
| 	  of &s.code;XF86VideoEncodingRec&e.code; below).  If the
 | |
| 	  requested encoding is unsupported, the driver should return
 | |
| 	  &s.code;XvBadEncoding&e.code;.  If the value lies outside the
 | |
| 	  advertised range &s.code;BadValue&e.code; may be returned.
 | |
| 	  &s.code;Success&e.code; should be returned otherwise.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
| 	&s.code;typedef void (* QueryBestSizeFuncPtr)(ScrnInfoPtr pScrn,
 | |
| 		&f.indent;Bool motion, short vid_w, short vid_h,
 | |
| 		&f.indent;short drw_w, short drw_h,
 | |
| 		&f.indent;unsigned int *p_w, unsigned int *p_h, pointer data)&e.code;
 | |
|     <quote><p>
 | |
| 	   &s.code;QueryBestSize&e.code; provides the client with a way
 | |
| 	   to query what the destination dimensions would end up being
 | |
| 	   if they were to request that an area
 | |
| 	   &s.code;vid_w&e.code by &s.code;vid_h&e.code; from the video
 | |
| 	   stream be scaled to rectangle of
 | |
| 	   &s.code;drw_w&e.code; by &s.code;drw_h&e.code; on the screen.
 | |
| 	   Since it is not expected that all hardware will be able to
 | |
| 	   get the target dimensions exactly, it is important that the
 | |
| 	   driver provide this function.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
| 	&s.code;typedef  int (* PutImageFuncPtr)( ScrnInfoPtr pScrn,
 | |
| 		&f.indent;short src_x, short src_y, short drw_x, short drw_y,
 | |
| 		&f.indent;short src_w, short src_h, short drw_w, short drw_h,
 | |
| 		&f.indent;int image, char *buf, short width, short height,
 | |
| 		&f.indent;Bool sync, RegionPtr clipBoxes, pointer data )&e.code;
 | |
|     <quote><p>
 | |
| 	  This is similar to &s.code;PutStill&e.code; except that the
 | |
| 	  source of the video is not a port but the data stored in a system
 | |
| 	  memory buffer at &s.code;buf&e.code;.  The data is in the format
 | |
| 	  indicated by the &s.code;image&e.code; descriptor and represents a
 | |
| 	  source of size &s.code;width&e.code; by &s.code;height&e.code;.
 | |
| 	  If &s.code;sync&e.code; is TRUE the driver should not return
 | |
| 	  from this function until it is through reading the data
 | |
| 	  from &s.code;buf&e.code;.  Returning when &s.code;sync&e.code;
 | |
| 	  is TRUE indicates that it is safe for the data at &s.code;buf&e.code;
 | |
| 	  to be replaced, freed, or modified.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
| 	&s.code;typedef  int (* QueryImageAttributesFuncPtr)( ScrnInfoPtr pScrn,
 | |
| 		&f.indent;int image, short *width, short *height,
 | |
| 		&f.indent;int *pitches, int *offsets)&e.code;
 | |
|     <quote><p>
 | |
| 	  This function is called to let the driver specify how data for
 | |
| 	  a particular &s.code;image&e.code; of size &s.code;width&e.code;
 | |
| 	  by &s.code;height&e.code; should be stored.  Sometimes only
 | |
| 	  the size and corrected width and height are needed.  In that
 | |
| 	  case &s.code;pitches&e.code; and &s.code;offsets&e.code; are
 | |
| 	  NULL.  The size of the memory required for the image is returned
 | |
| 	  by this function.  The &s.code;width&e.code; and
 | |
| 	  &s.code;height&e.code; of the requested image can be altered by
 | |
| 	  the driver to reflect format limitations (such as component
 | |
| 	  sampling periods that are larger than one).  If
 | |
| 	  &s.code;pitches&e.code; and &s.code;offsets&e.code; are not NULL,
 | |
| 	  these will be arrays with as many elements in them as there
 | |
| 	  are planes in the &s.code;image&e.code; format.  The driver
 | |
| 	  should specify the pitch (in bytes) of each scanline in the
 | |
| 	  particular plane as well as the offset to that plane (in bytes)
 | |
| 	  from the beginning of the image.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
| The XF86VideoEncodingRec:
 | |
| <quote><p>
 | |
| <verb>
 | |
| typedef struct {
 | |
| 	int id;
 | |
| 	char *name;
 | |
| 	unsigned short width, height;
 | |
| 	XvRationalRec rate;
 | |
| } XF86VideoEncodingRec, *XF86VideoEncodingPtr;
 | |
| 
 | |
| </verb>
 | |
|    The &s.code;XF86VideoEncodingRec&e.code; specifies what encodings
 | |
|    the adaptor can support.  Most of this data is just informational
 | |
|    and for the client's benefit, and is what will be reported by
 | |
|    &s.code;XvQueryEncodings&e.code;.  The &s.code;id&e.code; field is
 | |
|    expected to be a unique identifier to allow the client to request a
 | |
|    certain encoding via the &s.code;XV_ENCODING&e.code; attribute string.
 | |
| 
 | |
| </quote>
 | |
| 
 | |
| The XF86VideoFormatRec:
 | |
| 
 | |
| <quote><p>
 | |
| <verb>
 | |
| typedef struct {
 | |
| 	char  depth;
 | |
| 	short class;
 | |
| } XF86VideoFormatRec, *XF86VideoFormatPtr;
 | |
| </verb>
 | |
| 
 | |
|     This specifies what visuals the video is viewable in.
 | |
|     &s.code;depth&e.code; is the depth of the visual (not bpp).
 | |
|     &s.code;class&e.code; is the visual class such as
 | |
|     &s.code;TrueColor&e.code;, &s.code;DirectColor&e.code; or
 | |
|     &s.code;PseudoColor&e.code;.  Initialization of an adaptor will fail
 | |
|     if none of the visuals on that screen are supported.
 | |
| 
 | |
| </quote>
 | |
| 
 | |
| The XF86AttributeRec:
 | |
| 
 | |
| <quote><p>
 | |
| <verb>
 | |
| typedef struct {
 | |
| 	int   flags;
 | |
| 	int   min_value;
 | |
| 	int   max_value;
 | |
| 	char  *name;
 | |
| } XF86AttributeListRec, *XF86AttributeListPtr;
 | |
| 
 | |
| </verb>
 | |
| 
 | |
|    Each adaptor may have an array of these advertising the attributes
 | |
|    for its ports.  Currently defined flags are &s.code;XvGettable&e.code;
 | |
|    and &s.code;XvSettable&e.code; which may be OR'd together indicating that
 | |
|    attribute is ``gettable'' or ``settable'' by the client.  The
 | |
|    &s.code;min&e.code; and &s.code;max&e.code; field specify the valid range
 | |
|    for the value.  &s.code;Name&e.code; is a text string describing the
 | |
|    attribute by name.
 | |
| 
 | |
| </quote>
 | |
| 
 | |
| The XF86ImageRec:
 | |
| 
 | |
| <quote><p>
 | |
| <verb>
 | |
| typedef struct {
 | |
| 	int id;
 | |
| 	int type;
 | |
| 	int byte_order;
 | |
| 	char guid[16];
 | |
| 	int bits_per_pixel;
 | |
| 	int format;
 | |
| 	int num_planes;
 | |
| 
 | |
| 	/* for RGB formats */
 | |
| 	int depth;
 | |
| 	unsigned int red_mask;
 | |
| 	unsigned int green_mask;
 | |
| 	unsigned int blue_mask;
 | |
| 
 | |
| 	/* for YUV formats */
 | |
| 	unsigned int y_sample_bits;
 | |
| 	unsigned int u_sample_bits;
 | |
| 	unsigned int v_sample_bits;
 | |
| 	unsigned int horz_y_period;
 | |
| 	unsigned int horz_u_period;
 | |
| 	unsigned int horz_v_period;
 | |
| 	unsigned int vert_y_period;
 | |
| 	unsigned int vert_u_period;
 | |
| 	unsigned int vert_v_period;
 | |
| 	char component_order[32];
 | |
| 	int scanline_order;
 | |
| } XF86ImageRec, *XF86ImagePtr;
 | |
| </verb>
 | |
| 
 | |
|    XF86ImageRec describes how video source data is laid out in memory.
 | |
|    The fields are as follows:
 | |
| 
 | |
|     &s.code;id&e.code;
 | |
|     <quote><p>
 | |
| 	This is a unique descriptor for the format.  It is often good to
 | |
|         set this value to the FOURCC for the format when applicable.
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;type&e.code;
 | |
|     <quote><p>
 | |
| 	This is &s.code;XvRGB&e.code; or &s.code;XvYUV&e.code;.
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;byte_order&e.code;
 | |
|     <quote><p>
 | |
| 	This is &s.code;LSBFirst&e.code; or &s.code;MSBFirst&e.code;.
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;guid&e.code;
 | |
|     <quote><p>
 | |
| 	This is the Globally Unique IDentifier for the format.  When
 | |
| 	not applicable, all characters should be NULL.
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;bits_per_pixel&e.code;
 | |
|     <quote><p>
 | |
| 	The number of bits taken up (but not necessarily used) by each
 | |
| 	pixel.  Note that for some planar formats which have fractional
 | |
| 	bits per pixel (such as IF09) this number may be rounded _down_.
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;format&e.code;
 | |
|     <quote><p>
 | |
| 	This is &s.code;XvPlanar&e.code; or &s.code;XvPacked&e.code;.
 | |
|     </quote>
 | |
| 
 | |
|    &s.code;num_planes&e.code;
 | |
|     <quote><p>
 | |
| 	The number of planes in planar formats.  This should be set to
 | |
| 	one for packed formats.
 | |
|     </quote>
 | |
| 
 | |
|    &s.code;depth&e.code;
 | |
|     <quote><p>
 | |
| 	The significant bits per pixel in RGB formats (analgous to the
 | |
| 	depth of a pixmap format).
 | |
|     </quote>
 | |
| 
 | |
|    &s.code;red_mask&e.code;
 | |
|    &s.code;green_mask&e.code;
 | |
|    &s.code;blue_mask&e.code;
 | |
|     <quote><p>
 | |
| 	The red, green and blue bitmasks for packed RGB formats.
 | |
|     </quote>
 | |
| 
 | |
|    &s.code;y_sample_bits&e.code;
 | |
|    &s.code;u_sample_bits&e.code;
 | |
|    &s.code;v_sample_bits&e.code;
 | |
|     <quote><p>
 | |
| 	The y, u and v sample sizes (in bits).
 | |
|     </quote>
 | |
| 
 | |
|    &s.code;horz_y_period&e.code;
 | |
|    &s.code;horz_u_period&e.code;
 | |
|    &s.code;horz_v_period&e.code;
 | |
|     <quote><p>
 | |
| 	The y, u and v sampling periods in the horizontal direction.
 | |
|     </quote>
 | |
| 
 | |
|    &s.code;vert_y_period&e.code;
 | |
|    &s.code;vert_u_period&e.code;
 | |
|    &s.code;vert_v_period&e.code;
 | |
|     <quote><p>
 | |
| 	The y, u and v sampling periods in the vertical direction.
 | |
|     </quote>
 | |
| 
 | |
|    &s.code;component_order&e.code;
 | |
|     <quote><p>
 | |
| 	Uppercase ascii characters representing the order that
 | |
| 	samples are stored within packed formats.  For planar formats
 | |
| 	this represents the ordering of the planes.  Unused characters
 | |
| 	in the 32 byte string should be set to NULL.
 | |
|     </quote>
 | |
| 
 | |
|    &s.code;scanline_order&e.code;
 | |
|     <quote><p>
 | |
| 	This is &s.code;XvTopToBottom&e.code; or &s.code;XvBottomToTop&e.code;.
 | |
|     </quote>
 | |
| 
 | |
|   Since some formats (particular some planar YUV formats) may not
 | |
| be completely defined by the parameters above, the guid, when
 | |
| available, should provide the most accurate description of the
 | |
| format.
 | |
| 
 | |
| </quote>
 | |
| 
 | |
| <sect>The Loader
 | |
| <p>
 | |
| 
 | |
| This section describes the interfaces to the module loader.  The loader
 | |
| interfaces can be divided into two groups: those that are only available to
 | |
| the XFree86 common layer, and those that are also available to modules.
 | |
| 
 | |
| <sect1>Loader Overview
 | |
| <p>
 | |
| 
 | |
| The loader is capable of loading modules in a range of object formats,
 | |
| and knowledge of these formats is built in to the loader.  Knowledge of
 | |
| new object formats can be added to the loader in a straightforward
 | |
| manner.  This makes it possible to provide OS-independent modules (for
 | |
| a given CPU architecture type).  In addition to this, the loader can
 | |
| load modules via the OS-provided &s.code;dlopen(3)&e.code; service where
 | |
| available.  Such modules are not platform independent, and the semantics
 | |
| of &s.code;dlopen()&e.code; on most systems results in significant
 | |
| limitations in the use of modules of this type.  Support for
 | |
| &s.code;dlopen()&e.code; modules in the loader is primarily for
 | |
| experimental and development purposes.
 | |
| 
 | |
| Symbols exported by the loader (on behalf of the core X server) to
 | |
| modules are determined at compile time.  Only those symbols explicitly
 | |
| exported are available to modules.  All external symbols of loaded
 | |
| modules are exported to other modules, and to the core X server.  The
 | |
| loader can be requested to check for unresolved symbols at any time,
 | |
| and the action to be taken for unresolved symbols can be controlled by
 | |
| the caller of the loader.  Typically the caller identifies which symbols
 | |
| can safely remain unresolved and which cannot.
 | |
| 
 | |
| NOTE:  Now that ISO-C allows pointers to functions and pointers to data to
 | |
| have different internal representations, some of the following interfaces
 | |
| will need to be revisited.
 | |
| 
 | |
| <sect1>Semi-private Loader Interface
 | |
| <p>
 | |
| 
 | |
| The following is the semi-private loader interface that is available to the
 | |
| XFree86 common layer.
 | |
| 
 | |
|   <quote><p>
 | |
|   &s.code;void LoaderInit(void)&e.code;
 | |
|   <quote><p>
 | |
|     The &s.code;LoaderInit()&e.code; function initialises the loader,
 | |
|     and it must be called once before calling any other loader functions.
 | |
|     This function initialises the tables of exported symbols, and anything
 | |
|     else that might need to be initialised.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;void LoaderSetPath(const char *path)&e.code;
 | |
|   <quote><p>
 | |
|     The &s.code;LoaderSetPath()&e.code; function initialises a default
 | |
|     module search path.  This must be called if calls to other functions
 | |
|     are to be made without explicitly specifying a module search path.
 | |
|     The search path &s.code;path&e.code; must be a string of one or more
 | |
|     comma separated absolute paths.  Modules are expected to be located
 | |
|     below these paths, possibly in subdirectories of these paths.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;pointer LoadModule(const char *module, const char *path,
 | |
| 		&f.indent;const char **subdirlist, const char **patternlist,
 | |
| 		&f.indent;pointer options, const XF86ModReqInfo * modreq,
 | |
| 		&f.indent;int *errmaj, int *errmin)&e.code;
 | |
|   <quote><p>
 | |
|     The &s.code;LoadModule()&e.code; function loads the module called
 | |
|     &s.code;module&e.code;.  The return value is a module handle, and
 | |
|     may be used in future calls to the loader that require a reference
 | |
|     to a loaded module.  The module name &s.code;module&e.code; is
 | |
|     normally the module's canonical name, which doesn't contain any
 | |
|     directory path information, or any object/library file prefixes of
 | |
|     suffixes.  Currently a full pathname and/or filename is also accepted.
 | |
|     This might change.  The other parameters are:
 | |
| 
 | |
|       &s.code;path&e.code;
 | |
| 	<quote><p>
 | |
| 		  An optional comma-separated list of module search paths.
 | |
|                   When &s.code;NULL&e.code;, the default search path is used.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;subdirlist&e.code;
 | |
| 	<quote><p>
 | |
| 		  An optional &s.code;NULL&e.code; terminated list of
 | |
| 		  subdirectories to search.  When &s.code;NULL&e.code;,
 | |
| 		  the default built-in list is used (refer to
 | |
| 		  &s.code;stdSubdirs&e.code; in &s.code;loadmod.c&e.code;).
 | |
| 		  The default list is also substituted for entries in
 | |
| 		  &s.code;subdirlist&e.code; with the value
 | |
| 		  &s.code;DEFAULT_LIST&e.code;.  This makes is possible
 | |
| 		  to augment the default list instead of replacing it.
 | |
| 		  Subdir elements must be relative, and must not contain
 | |
| 		  &s.code;".."&e.code;.  If any violate this requirement,
 | |
| 		  the load fails.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;patternlist&e.code;
 | |
| 	<quote><p>
 | |
| 		  An optional &s.code;NULL&e.code; terminated list of
 | |
| 		  POSIX regular expressions used to connect module
 | |
| 		  filenames with canonical module names.  Each regex
 | |
| 		  should contain exactly one subexpression that corresponds
 | |
| 		  to the canonical module name.  When &s.code;NULL&e.code;,
 | |
| 		  the default built-in list is used (refer to
 | |
| 		  &s.code;stdPatterns&e.code; in
 | |
| 		  &s.code;loadmod.c&e.code;).  The default list is also
 | |
| 		  substituted for entries in &s.code;patternlist&e.code;
 | |
| 		  with the value &s.code;DEFAULT_LIST&e.code;.  This
 | |
| 		  makes it possible to augment the default list instead
 | |
| 		  of replacing it.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;options&e.code;
 | |
| 	<quote><p>
 | |
| 		  An optional parameter that is passed to the newly
 | |
| 		  loaded module's &s.code;SetupProc&e.code; function
 | |
| 		  (if it has one).  This argument is normally a
 | |
| 		  &s.code;NULL&e.code; terminated list of
 | |
| 		  &s.code;Options&e.code;, and must be interpreted that
 | |
| 		  way by modules loaded directly by the XFree86 common
 | |
| 		  layer.  However, it may be used for application-specific
 | |
| 		  parameter passing in other situations.
 | |
| 
 | |
| 		  When loading ``external'' modules (modules that don't
 | |
| 		  have the standard entry point, for example a
 | |
| 		  special shared library) the options parameter can be
 | |
| 		  set to &s.code;EXTERN_MODULE&e.code; to tell the
 | |
| 		  loader not to reject the module when it doesn't find
 | |
| 		  the standard entry point.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;modreq&e.code;
 | |
| 	<quote><p>
 | |
| 		  An optional &s.code;XF86ModReqInfo*&e.code; containing
 | |
| 		  version/ABI/vendor information to requirements to
 | |
| 		  check the newly loaded module against.  The main
 | |
| 		  purpose of this is to allow the loader to verify that
 | |
| 		  a module of the correct type/version before running
 | |
| 		  its &s.code;SetupProc&e.code; function.
 | |
| 
 | |
| 		  The &s.code;XF86ModReqInfo&e.code; struct is defined
 | |
| 		  as follows:
 | |
| <verb>
 | |
| typedef struct {
 | |
| 	CARD8        majorversion;  /* MAJOR_UNSPEC */
 | |
| 	CARD8        minorversion;  /* MINOR_UNSPEC */
 | |
| 	CARD16       patchlevel;    /* PATCH_UNSPEC */
 | |
| 	const char * abiclass;      /* ABI_CLASS_NONE */
 | |
| 	CARD32       abiversion;    /* ABI_VERS_UNSPEC */
 | |
| 	const char * moduleclass;   /* MOD_CLASS_NONE */
 | |
| } XF86ModReqInfo;
 | |
| </verb>
 | |
| 
 | |
| 		  The information here is compared against the equivalent
 | |
| 		  information in the module's
 | |
| 		  &s.code;XF86ModuleVersionInfo&e.code; record (which
 | |
| 		  is described below).  The values in comments above
 | |
| 		  indicate ``don't care'' settings for each of the fields.
 | |
| 		  The comparisons made are as follows:
 | |
| 
 | |
|                     &s.code;majorversion&e.code;
 | |
| 			<quote><p>
 | |
| 				   Must match the module's majorversion
 | |
| 				   exactly.
 | |
| 
 | |
| 			</quote>
 | |
|                     &s.code;minorversion&e.code;
 | |
| 			<quote><p>
 | |
| 				   The module's minor version must be
 | |
| 				   no less than this value.  This
 | |
| 				   comparison is only made if
 | |
| 				   &s.code;majorversion&e.code; is
 | |
| 				   specified and matches.
 | |
| 
 | |
| 			</quote>
 | |
|                     &s.code;patchlevel&e.code;
 | |
| 			<quote><p>
 | |
| 				   The module's patchlevel must be no
 | |
| 				   less than this value.  This comparison
 | |
| 				   is only made if
 | |
| 				   &s.code;minorversion&e.code; is
 | |
| 				   specified and matches.
 | |
| 
 | |
| 			</quote>
 | |
|                     &s.code;abiclass&e.code;
 | |
| 			<quote><p>
 | |
| 				   String must match the module's abiclass
 | |
| 				   string.
 | |
| 
 | |
| 			</quote>
 | |
|                     &s.code;abiversion&e.code;
 | |
| 			<quote><p>
 | |
| 				   Must be consistent with the module's
 | |
| 				   abiversion (major equal, minor no
 | |
| 				   older).
 | |
| 
 | |
| 			</quote>
 | |
|                     &s.code;moduleclass&e.code;
 | |
| 			<quote><p>
 | |
| 				   String must match the module's
 | |
| 				   moduleclass string.
 | |
| 
 | |
| 			</quote>
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;errmaj&e.code;
 | |
| 	<quote><p>
 | |
| 		  An optional pointer to a variable holding the major
 | |
| 		  part or the error code.  When provided,
 | |
| 		  &s.code;*errmaj&e.code; is filled in when
 | |
| 		  &s.code;LoadModule()&e.code; fails.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       &s.code;errmin&e.code;
 | |
| 	<quote><p>
 | |
| 		  Like &s.code;errmaj&e.code;, but for the minor part
 | |
| 		  of the error code.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;void UnloadModule(pointer mod)&e.code;
 | |
|   <quote><p>
 | |
|     This function unloads the module referred to by the handle mod.
 | |
|     All child modules are also unloaded recursively.  This function must
 | |
|     not be used to directly unload modules that are child modules (i.e.,
 | |
|     those that have been loaded with the &s.code;LoadSubModule()&e.code;
 | |
|     described below).
 | |
| 
 | |
|   </quote>
 | |
|   </quote>
 | |
| 
 | |
| <sect1>Module Requirements
 | |
| <p>
 | |
| 
 | |
| Modules must provide information about themselves to the loader, and
 | |
| may optionally provide entry points for "setup" and "teardown" functions
 | |
| (those two functions are referred to here as &s.code;SetupProc&e.code;
 | |
| and &s.code;TearDownProc&e.code;).
 | |
| 
 | |
| The module information is contained in the
 | |
| &s.code;XF86ModuleVersionInfo&e.code; struct, which is defined as follows:
 | |
| 
 | |
| <quote><p><verb>
 | |
| typedef struct {
 | |
|     const char * modname;      /* name of module, e.g. "foo" */
 | |
|     const char * vendor;       /* vendor specific string */
 | |
|     CARD32       _modinfo1_;   /* constant MODINFOSTRING1/2 to find */
 | |
|     CARD32       _modinfo2_;   /* infoarea with a binary editor/sign tool */
 | |
|     CARD32       xf86version;  /* contains XF86_VERSION_CURRENT */
 | |
|     CARD8        majorversion; /* module-specific major version */
 | |
|     CARD8        minorversion; /* module-specific minor version */
 | |
|     CARD16       patchlevel;   /* module-specific patch level */
 | |
|     const char * abiclass;     /* ABI class that the module uses */
 | |
|     CARD32       abiversion;   /* ABI version */
 | |
|     const char * moduleclass;  /* module class */
 | |
|     CARD32       checksum[4];  /* contains a digital signature of the */
 | |
|                                /* version info structure */
 | |
| } XF86ModuleVersionInfo;
 | |
| </verb>
 | |
| 
 | |
| The fields are used as follows:
 | |
| 
 | |
|   &s.code;modname&e.code;
 | |
| 	<quote><p>
 | |
| 		The module's name.  This field is currently only for
 | |
| 		informational purposes, but the loader may be modified
 | |
| 		in future to require it to match the module's canonical
 | |
|                 name.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;vendor&e.code;
 | |
| 	<quote><p>
 | |
| 		The module vendor.  This field is for informational purposes
 | |
|                 only.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;_modinfo1_&e.code;
 | |
| 	<quote><p>
 | |
| 		This field holds the first part of a signature that can
 | |
|                 be used to locate this structure in the binary.  It should
 | |
|                 always be initialised to &s.code;MODINFOSTRING1&e.code;.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;_modinfo2_&e.code;
 | |
| 	<quote><p>
 | |
| 		This field holds the second part of a signature that can
 | |
|                 be used to locate this structure in the binary.  It should
 | |
|                 always be initialised to &s.code;MODINFOSTRING2&e.code;.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;xf86version&e.code;
 | |
| 	<quote><p>
 | |
| 		The XFree86 version against which the module was compiled.
 | |
|                 This is mostly for informational/diagnostic purposes.  It
 | |
|                 should be initialised to &s.code;XF86_VERSION_CURRENT&e.code;, which is
 | |
|                 defined in &s.code;xf86Version.h&e.code;.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;majorversion&e.code;
 | |
| 	<quote><p>
 | |
| 		The module-specific major version.  For modules where this
 | |
| 		version is used for more than simply informational
 | |
| 		purposes, the major version should only change (be
 | |
| 		incremented) when ABI incompatibilities are introduced,
 | |
| 		or ABI components are removed.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;minorversion&e.code;
 | |
| 	<quote><p>
 | |
| 		The module-specific minor version.  For modules where this
 | |
| 		version is used for more than simply informational
 | |
| 		purposes, the minor version should only change (be
 | |
| 		incremented) when ABI additions are made in a backward
 | |
| 		compatible way.  It should be reset to zero when the major
 | |
|                 version is increased.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;patchlevel&e.code;
 | |
| 	<quote><p>
 | |
| 		The module-specific patch level.  The patch level should
 | |
| 		increase with new revisions of the module where there
 | |
| 		are no ABI changes, and it should be reset to zero when
 | |
| 		the minor version is increased.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;abiclass&e.code;
 | |
| 	<quote><p>
 | |
| 		The ABI class that the module requires.  The class is
 | |
|                 specified as a string for easy extensibility.  It should
 | |
| 		indicate which (if any) of the X server's built-in ABI
 | |
| 		classes that the module relies on, or a third-party ABI
 | |
|                 if appropriate.  Built-in ABI classes currently defined are:
 | |
| 
 | |
| 		<quote>
 | |
|                    &s.code;ABI_CLASS_NONE&e.code;
 | |
| 			<quote>no class</quote>
 | |
|                    &s.code;ABI_CLASS_ANSIC&e.code;
 | |
| 			<quote>only requires the ANSI C interfaces</quote>
 | |
|                    &s.code;ABI_CLASS_VIDEODRV&e.code;
 | |
| 			<quote>requires the video driver ABI</quote>
 | |
|                    &s.code;ABI_CLASS_XINPUT&e.code;
 | |
| 			<quote>requires the XInput driver ABI</quote>
 | |
|                    &s.code;ABI_CLASS_EXTENSION&e.code;
 | |
| 			<quote>requires the extension module ABI</quote>
 | |
|                    &s.code;ABI_CLASS_FONT&e.code;
 | |
| 			<quote>requires the font module ABI</quote>
 | |
| 		</quote>
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;abiversion&e.code;
 | |
| 	<quote><p>
 | |
| 		The version of abiclass that the module requires.  The
 | |
| 		version consists of major and minor components.  The
 | |
| 		major version must match and the minor version must be
 | |
| 		no newer than that provided by the server or parent
 | |
| 		module.  Version identifiers for the built-in classes
 | |
| 		currently defined are:
 | |
| 
 | |
| 		<quote>
 | |
|                    &s.code;ABI_ANSIC_VERSION&nl;
 | |
|                    ABI_VIDEODRV_VERSION&nl;
 | |
|                    ABI_XINPUT_VERSION&nl;
 | |
|                    ABI_EXTENSION_VERSION&nl;
 | |
|                    ABI_FONT_VERSION&e.code;
 | |
| 		</quote>
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;moduleclass&e.code;
 | |
| 	<quote><p>
 | |
| 		This is similar to the abiclass field, except that it
 | |
| 		defines the type of module rather than the ABI it
 | |
| 		requires.  For example, although all video drivers require
 | |
| 		the video driver ABI, not all modules that require the
 | |
| 		video driver ABI are video drivers.  This distinction
 | |
| 		can be made with the moduleclass.  Currently pre-defined
 | |
| 		module classes are:
 | |
| 
 | |
| 		<quote>
 | |
|                    &s.code;MOD_CLASS_NONE&nl;
 | |
|                    MOD_CLASS_VIDEODRV&nl;
 | |
|                    MOD_CLASS_XINPUT&nl;
 | |
|                    MOD_CLASS_FONT&nl;
 | |
|                    MOD_CLASS_EXTENSION&e.code;
 | |
| 		</quote>
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|   &s.code;checksum&e.code;
 | |
| 	<quote><p>
 | |
| 		Not currently used.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
| </quote>
 | |
| 
 | |
| The module version information, and the optional &s.code;SetupProc&e.code;
 | |
| and &s.code;TearDownProc&e.code; entry points are found by the loader
 | |
| by locating a data object in the module called "modnameModuleData",
 | |
| where "modname" is the canonical name of the module.  Modules must
 | |
| contain such a data object, and it must be declared with global scope,
 | |
| be compile-time initialised, and is of the following type:
 | |
| 
 | |
| <quote>
 | |
| <verb>
 | |
| typedef struct {
 | |
|     XF86ModuleVersionInfo *     vers;
 | |
|     ModuleSetupProc             setup;
 | |
|     ModuleTearDownProc          teardown;
 | |
| } XF86ModuleData;
 | |
| </verb>
 | |
| </quote>
 | |
| 
 | |
| The vers parameter must be initialised to a pointer to a correctly
 | |
| initialised &s.code;XF86ModuleVersionInfo&e.code; struct.  The other
 | |
| two parameter are optional, and should be initialised to
 | |
| &s.code;NULL&e.code; when not required.  The other parameters are defined
 | |
| as
 | |
| 
 | |
|   <quote><p>
 | |
|   &s.code;typedef pointer (*ModuleSetupProc)(pointer, pointer, int *, int *)&e.code;
 | |
| 
 | |
|   &s.code;typedef void (*ModuleTearDownProc)(pointer)&e.code;
 | |
| 
 | |
| 
 | |
|   &s.code;pointer SetupProc(pointer module, pointer options,
 | |
| 		&f.indent;int *errmaj, int *errmin)&e.code;
 | |
|   <quote><p>
 | |
|     When defined, this function is called by the loader after successfully
 | |
|     loading a module.  module is a handle for the newly loaded module,
 | |
|     and maybe used by the &s.code;SetupProc&e.code; if it calls other
 | |
|     loader functions that require a reference to it.   The remaining
 | |
|     arguments are those that were passed to the
 | |
|     &s.code;LoadModule()&e.code; (or &s.code;LoadSubModule()&e.code;),
 | |
|     and are described above. When the &s.code;SetupProc&e.code; is
 | |
|     successful it must return a non-&s.code;NULL&e.code; value.  The
 | |
|     loader checks this, and if it is &s.code;NULL&e.code; it unloads
 | |
|     the module and reports the failure to the caller of
 | |
|     &s.code;LoadModule()&e.code;.  If the &s.code;SetupProc&e.code;
 | |
|     does things that need to be undone when the module is unloaded,
 | |
|     it should define a &s.code;TearDownProc&e.code;, and return a
 | |
|     pointer that the &s.code;TearDownProc&e.code; can use to undo what
 | |
|     has been done.
 | |
| 
 | |
|     When a module is loaded multiple times, the &s.code;SetupProc&e.code;
 | |
|     is called once for each time it is loaded.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;void TearDownProc(pointer tearDownData)&e.code;
 | |
|   <quote><p>
 | |
|     When defined, this function is called when the loader unloads a
 | |
|     module.  The &s.code;tearDownData&e.code; parameter is the return
 | |
|     value of the &s.code;SetupProc()&e.code; that was called when the
 | |
|     module was loaded.  The purpose of this function is to clean up
 | |
|     before the module is unloaded (for example, by freeing allocated
 | |
|     resources).
 | |
| 
 | |
|   </quote>
 | |
|   </quote>
 | |
| 
 | |
| <sect1>Public Loader Interface
 | |
| <p>
 | |
| 
 | |
| The following is the Loader interface that is available to any part of
 | |
| the server, and may also be used from within modules.
 | |
| 
 | |
|   <quote><p>
 | |
|   &s.code;pointer LoadSubModule(pointer parent, const char *module,
 | |
| 		&f.indent;const char **subdirlist, const char **patternlist,
 | |
| 		&f.indent;pointer options, const XF86ModReqInfo * modreq,
 | |
| 		&f.indent;int *errmaj, int *errmin)&e.code;
 | |
|   <quote><p>
 | |
|     This function is like the &s.code;LoadModule()&e.code; function
 | |
|     described above, except that the module loaded is registered as a
 | |
|     child of the calling module.  The &s.code;parent&e.code; parameter
 | |
|     is the calling module's handle.  Modules loaded with this function
 | |
|     are automatically unloaded when the parent module is unloaded.  The
 | |
|     other difference is that the path parameter may not be specified.
 | |
|     The module search path used for modules loaded with this function
 | |
|     is the default search path as initialised with
 | |
|     &s.code;LoaderSetPath()&e.code;.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;void UnloadSubModule(pointer module)&e.code;
 | |
|   <quote><p>
 | |
|     This function unloads the module with handle &s.code;module&e.code;.
 | |
|     If that module itself has children, they are also unloaded.  It is
 | |
|     like &s.code;UnloadModule()&e.code;, except that it is safe to use
 | |
|     for unloading child modules.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;pointer LoaderSymbol(const char *symbol)&e.code;
 | |
|   <quote><p>
 | |
|     This function returns the address of the symbol with name
 | |
|     &s.code;symbol&e.code;.  This may be used to locate a module entry
 | |
|     point with a known name.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;char **LoaderlistDirs(const char **subdirlist,
 | |
| 			&f.indent;const char **patternlist)&e.code;
 | |
|   <quote><p>
 | |
|     This function returns a &s.code;NULL&e.code; terminated list of
 | |
|     canonical modules names for modules found in the default module
 | |
|     search path.  The &s.code;subdirlist&e.code; and
 | |
|     &s.code;patternlist&e.code; parameters are as described above, and
 | |
|     can be used to control the locations and names that are searched.
 | |
|     If no modules are found, the return value is &s.code;NULL&e.code;.
 | |
|     The returned list should be freed by calling
 | |
|     &s.code;LoaderFreeDirList()&e.code; when it is no longer needed.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;void LoaderFreeDirList(char **list)&e.code;
 | |
|   <quote><p>
 | |
|     This function frees a module list created by
 | |
|     &s.code;LoaderlistDirs()&e.code;.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;void LoaderReqSymLists(const char **list0, ...)&e.code;
 | |
|   <quote><p>
 | |
|     This function allows the registration of required symbols with the
 | |
|     loader.  It is normally used by a caller of
 | |
|     &s.code;LoadSubModule()&e.code;.  If any symbols registered in this
 | |
|     way are found to be unresolved when
 | |
|     &s.code;LoaderCheckUnresolved()&e.code; is called then
 | |
|     &s.code;LoaderCheckUnresolved()&e.code; will report a failure.
 | |
|     The function takes one or more &s.code;NULL&e.code; terminated
 | |
|     lists of symbols.  The end of the argument list is indicated by a
 | |
|     &s.code;NULL&e.code; argument.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;void LoaderReqSymbols(const char *sym0, ...)&e.code;
 | |
|   <quote><p>
 | |
|     This function is like &s.code;LoaderReqSymLists()&e.code; except
 | |
|     that its arguments are symbols rather than lists of symbols.  This
 | |
|     function is more convenient when single functions are to be registered,
 | |
|     especially when the single function might depend on runtime factors.
 | |
|     The end of the argument list is indicated by a &s.code;NULL&e.code;
 | |
|     argument.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;void LoaderRefSymLists(const char **list0, ...)&e.code;
 | |
|   <quote><p>
 | |
|     This function allows the registration of possibly unresolved symbols
 | |
|     with the loader.  When &s.code;LoaderCheckUnresolved()&e.code; is
 | |
|     run it won't generate warnings for symbols registered in this way
 | |
|     unless they were also registered as required symbols.
 | |
|     The function takes one or more &s.code;NULL&e.code; terminated
 | |
|     lists of symbols.  The end of the argument list is indicated by a
 | |
|     &s.code;NULL&e.code; argument.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;void LoaderRefSymbols(const char *sym0, ...)&e.code;
 | |
|   <quote><p>
 | |
|     This function is like &s.code;LoaderRefSymLists()&e.code; except
 | |
|     that its arguments are symbols rather than lists of symbols.  This
 | |
|     function is more convenient when single functions are to be registered,
 | |
|     especially when the single function might depend on runtime factors.
 | |
|     The end of the argument list is indicated by a &s.code;NULL&e.code;
 | |
|     argument.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;int LoaderCheckUnresolved(int delayflag)&e.code;
 | |
|   <quote><p>
 | |
|     This function checks for unresolved symbols.  It generates warnings
 | |
|     for unresolved symbols that have not been registered with
 | |
|     &s.code;LoaderRefSymLists()&e.code;, and maps them to a dummy
 | |
|     function.  This behaviour may change in future.  If unresolved
 | |
|     symbols are found that have been registered with
 | |
|     &s.code;LoaderReqSymLists()&e.code; or
 | |
|     &s.code;LoaderReqSymbols()&e.code; then this function returns a
 | |
|     non-zero value.  If none of these symbols are unresolved the return
 | |
|     value is zero, indicating success.
 | |
| 
 | |
|     The &s.code;delayflag&e.code; parameter should normally be set to
 | |
|     &s.code;LD_RESOLV_IFDONE&e.code;.
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;LoaderErrorMsg(const char *name, const char *modname,
 | |
| 			&f.indent;int errmaj, int errmin)&e.code;
 | |
|   <quote><p>
 | |
|     This function prints an error message that includes the text ``Failed
 | |
|     to load module'', the module name &s.code;modname&e.code;, a message
 | |
|     specific to the &s.code;errmaj&e.code; value, and the value if
 | |
|     &s.code;errmin&e.code;.  If &s.code;name&e.code; is
 | |
|     non-&s.code;NULL&e.code;, it is printed as an identifying prefix
 | |
|     to the message (followed by a `:').
 | |
| 
 | |
|   </quote>
 | |
|   </quote>
 | |
| 
 | |
| <sect1>Special Registration Functions
 | |
| <p>
 | |
| 
 | |
| The loader contains some functions for registering some classes of modules.
 | |
| These may be moved out of the loader at some point.
 | |
| 
 | |
|   <quote><p>
 | |
|   &s.code;void LoadExtension(ExtensionModule *ext)&e.code;
 | |
|   <quote><p>
 | |
|     This registers the entry points for the extension identified by
 | |
|     &s.code;ext&e.code;.  The &s.code;ExtensionModule&e.code; struct is
 | |
|     defined as:
 | |
| 
 | |
| <quote>
 | |
| <verb>
 | |
| typedef struct {
 | |
|     InitExtension       initFunc;
 | |
|     char *              name;
 | |
|     Bool                *disablePtr;
 | |
|     InitExtension       setupFunc;
 | |
| } ExtensionModule;
 | |
| </verb>
 | |
| </quote>
 | |
| 
 | |
|   </quote>
 | |
| 
 | |
|   &s.code;void LoadFont(FontModule *font)&e.code;
 | |
|   <quote><p>
 | |
|     This registers the entry points for the font rasteriser module
 | |
|     identified by &s.code;font&e.code;.  The &s.code;FontModule&e.code;
 | |
|     struct is defined as:
 | |
| 
 | |
| <quote>
 | |
| <verb>
 | |
| typedef struct {
 | |
|     InitFont    initFunc;
 | |
|     char *      name;
 | |
|     pointer     module;
 | |
| } FontModule;
 | |
| </verb>
 | |
| </quote>
 | |
| 
 | |
|   </quote>
 | |
|   </quote>
 | |
| 
 | |
| </sect>
 | |
| 
 | |
| 
 | |
| <sect>Helper Functions
 | |
| <p>
 | |
| 
 | |
| This section describe ``helper'' functions that video driver
 | |
| might find useful.  While video drivers are not required to use any of
 | |
| these to be considered ``compliant'', the use of appropriate helpers is
 | |
| strongly encouraged to improve the consistency of driver behaviour.
 | |
| 
 | |
| <sect1>Functions for printing messages
 | |
| <p>
 | |
| 
 | |
|   <quote><p>
 | |
|     &s.code;ErrorF(const char *format, ...)&e.code;
 | |
|     <quote><p>
 | |
|       This is the basic function for writing to the error log (typically
 | |
|       stderr and/or a log file).  Video drivers should usually avoid
 | |
|       using this directly in favour of the more specialised functions
 | |
|       described below.  This function is useful for printing messages
 | |
|       while debugging a driver.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;FatalError(const char *format, ...)&e.code;
 | |
|     <quote><p>
 | |
|       This prints a message and causes the Xserver to abort.  It should
 | |
|       rarely be used within a video driver, as most error conditions
 | |
|       should be flagged by the return values of the driver functions.
 | |
|       This allows the higher layers to decide how to proceed.  In rare
 | |
|       cases, this can be used within a driver if a fatal unexpected
 | |
|       condition is found.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;xf86ErrorF(const char *format, ...)&e.code;
 | |
|     <quote><p>
 | |
|       This is like &s.code;ErrorF()&e.code;, except that the message is
 | |
|       only printed when the Xserver's verbosity level is set to the
 | |
|       default (&s.code;1&e.code;) or higher.  It means that the messages
 | |
|       are not printed when the server is started with the
 | |
|       &s.cmd;-quiet&e.cmd; flag.  Typically this function would only be
 | |
|       used for continuing messages started with one of the more specialised
 | |
|       functions described below.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;xf86ErrorFVerb(int verb, const char *format, ...)&e.code;
 | |
|     <quote><p>
 | |
|       Like &s.code;xf86ErrorF()&e.code;, except the minimum verbosity
 | |
|       level for which the message is to be printed is given explicitly.
 | |
|       Passing a &s.code;verb&e.code; value of zero means the message
 | |
|       is always printed.  A value higher than &s.code;1&e.code; can be
 | |
|       used for information would normally not be needed, but which might
 | |
|       be useful when diagnosing problems.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;xf86Msg(MessageType type, const char *format, ...)&e.code;
 | |
|     <quote><p>
 | |
|       This is like &s.code;xf86ErrorF()&e.code;, except that the message
 | |
|       is prefixed with a marker determined by the value of
 | |
|       &s.code;type&e.code;.  The marker is used to indicate the type of
 | |
|       message (warning, error, probed value, config value, etc).  Note
 | |
|       the &s.code;xf86Verbose&e.code; value is ignored for messages of
 | |
|       type &s.code;X_ERROR&e.code;.
 | |
| 
 | |
|       The marker values are:
 | |
| 
 | |
|       <quote>
 | |
|       &s.code;X_PROBED&e.code;
 | |
| 	<quote>Value was probed.</quote>
 | |
|       &s.code;X_CONFIG&e.code;
 | |
| 	<quote>Value was given in the config file.</quote>
 | |
|       &s.code;X_DEFAULT&e.code;
 | |
| 	<quote>Value is a default.</quote>
 | |
|       &s.code;X_CMDLINE&e.code;
 | |
| 	<quote>Value was given on the command line.</quote>
 | |
|       &s.code;X_NOTICE&e.code;
 | |
| 	<quote>Notice.</quote>
 | |
|       &s.code;X_ERROR&e.code;
 | |
| 	<quote>Error message.</quote>
 | |
|       &s.code;X_WARNING&e.code;
 | |
| 	<quote>Warning message.</quote>
 | |
|       &s.code;X_INFO&e.code;
 | |
| 	<quote>Informational message.</quote>
 | |
|       &s.code;X_NONE&e.code;
 | |
| 	<quote>No prefix.</quote>
 | |
|       &s.code;X_NOT_IMPLEMENTED&e.code;
 | |
| 	<quote>The message relates to functionality that is not yet
 | |
|                implemented.</quote>
 | |
|       </quote>
 | |
| 
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;xf86MsgVerb(MessageType type, int verb, const char *format, ...)&e.code;
 | |
|     <quote><p>
 | |
|       Like &s.code;xf86Msg()&e.code;, but with the verbosity level given
 | |
|       explicitly.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)&e.code;
 | |
|     <quote><p>
 | |
|       This is like &s.code;xf86Msg()&e.code; except that the driver's
 | |
|       name (the &s.code;name&e.code; field of the
 | |
|       &s.code;ScrnInfoRec&e.code;) followed by the
 | |
|       &s.code;scrnIndex&e.code; in parentheses is printed following the
 | |
|       prefix.  This should be used by video drivers in most cases as it
 | |
|       clearly indicates which driver/screen the message is for.  If
 | |
|       &s.code;scrnIndex&e.code; is negative, this function behaves
 | |
|       exactly like &s.code;xf86Msg()&e.code;.
 | |
| 
 | |
|       NOTE: This function can only be used after the
 | |
|       &s.code;ScrnInfoRec&e.code; and its &s.code;name&e.code; field
 | |
|       have been allocated.  Normally, this means that it can not be
 | |
|       used before the END of the &s.code;ChipProbe()&e.code; function.
 | |
|       Prior to that, use &s.code;xf86Msg()&e.code;, providing the
 | |
|       driver's name explicitly.  No screen number can be supplied at
 | |
|       that point.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
 | |
| 		&f.indent;const char *format, ...)&e.code;
 | |
|     <quote><p>
 | |
|       Like &s.code;xf86DrvMsg()&e.code;, but with the verbosity level
 | |
|       given explicitly.
 | |
| 
 | |
|     </quote>
 | |
|   </quote>
 | |
| 
 | |
| 
 | |
| <sect1>Functions for setting values based on command line and config file
 | |
| <p>
 | |
| 
 | |
|   <quote><p>
 | |
|     &s.code;Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp,
 | |
|                         &f.indent;int fbbpp, int depth24flags)&e.code;
 | |
|     <quote><p>
 | |
|       This function sets the &s.code;depth&e.code;, &s.code;pixmapBPP&e.code; and &s.code;bitsPerPixel&e.code; fields
 | |
|       of the &s.code;ScrnInfoRec&e.code;.  It also determines the defaults for display-wide
 | |
|       attributes and pixmap formats the screen will support, and finds
 | |
|       the Display subsection that matches the depth/bpp.  This function
 | |
|       should normally be called very early from the
 | |
|       &s.code;ChipPreInit()&e.code; function.
 | |
| 
 | |
|       It requires that the &s.code;confScreen&e.code; field of the &s.code;ScrnInfoRec&e.code; be
 | |
|       initialised prior to calling it.  This is done by the XFree86
 | |
|       common layer prior to calling &s.code;ChipPreInit()&e.code;.
 | |
| 
 | |
|       The parameters passed are:
 | |
| 
 | |
|         &s.code;depth&e.code;
 | |
| 	<quote><p>
 | |
| 		driver's preferred default depth if no other is given.
 | |
|                 If zero, use the overall server default.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;bpp&e.code;
 | |
| 	<quote><p>
 | |
| 		Same, but for the pixmap bpp.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;fbbpp&e.code;
 | |
| 	<quote><p>
 | |
| 		Same, but for the framebuffer bpp.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;depth24flags&e.code;
 | |
| 	<quote><p>
 | |
| 		Flags that indicate the level of 24/32bpp support
 | |
|                 and whether conversion between different framebuffer
 | |
|                 and pixmap formats is supported.  The flags for this
 | |
|                 argument are defined as follows, and multiple flags
 | |
|                 may be ORed together:
 | |
| 
 | |
|                &s.code;NoDepth24Support&e.code;
 | |
| 		<quote>No depth 24 formats supported</quote>
 | |
|                &s.code;Support24bppFb&e.code;
 | |
| 		<quote>24bpp framebuffer supported</quote>
 | |
|                &s.code;Support32bppFb&e.code;
 | |
| 		<quote>32bpp framebuffer supported</quote>
 | |
|                &s.code;SupportConvert24to32&e.code;
 | |
| 		<quote>Can convert 24bpp pixmap to 32bpp fb</quote>
 | |
|                &s.code;SupportConvert32to24&e.code;
 | |
| 		<quote>Can convert 32bpp pixmap to 24bpp fb</quote>
 | |
|                &s.code;ForceConvert24to32&e.code;
 | |
| 		<quote>Force 24bpp pixmap to 32bpp fb conversion</quote>
 | |
|                &s.code;ForceConvert32to24&e.code;
 | |
| 		<quote>Force 32bpp pixmap to 24bpp fb conversion</quote>
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       It uses the command line, config file, and default values in the
 | |
|       correct order of precedence to determine the depth and bpp values.
 | |
|       It is up to the driver to check the results to see that it supports
 | |
|       them.  If not the &s.code;ChipPreInit()&e.code; function should
 | |
|       return &s.code;FALSE&e.code;.
 | |
| 
 | |
|       If only one of depth/bpp is given, the other is set to a reasonable
 | |
|       (and consistent) default.
 | |
| 
 | |
|       If a driver finds that the initial &s.code;depth24flags&e.code;
 | |
|       it uses later results in a fb format that requires more video
 | |
|       memory than is available it may call this function a second time
 | |
|       with a different &s.code;depth24flags&e.code; setting.
 | |
| 
 | |
|       On success, the return value is &s.code;TRUE&e.code;.  On failure
 | |
|       it prints an error message and returns &s.code;FALSE&e.code;.
 | |
| 
 | |
|       The following fields of the &s.code;ScrnInfoRec&e.code; are
 | |
|       initialised by this function:
 | |
| 
 | |
| 	<quote>
 | |
| 	&s.code;depth&e.code;, &s.code;bitsPerPixel&e.code;,
 | |
| 	&s.code;display&e.code;, &s.code;imageByteOrder&e.code;,
 | |
| 	&s.code;bitmapScanlinePad&e.code;,
 | |
| 	&s.code;bitmapScanlineUnit&e.code;, &s.code;bitmapBitOrder&e.code;,
 | |
| 	&s.code;numFormats&e.code;, &s.code;formats&e.code;,
 | |
| 	&s.code;fbFormat&e.code;.
 | |
| 	</quote>
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86PrintDepthBpp(scrnInfoPtr scrp)&e.code;
 | |
|     <quote><p>
 | |
|       This function can be used to print out the depth and bpp settings.
 | |
|       It should be called after the final call to
 | |
|       &s.code;xf86SetDepthBpp()&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)&e.code;
 | |
|     <quote><p>
 | |
|       This function sets the &s.code;weight&e.code;, &s.code;mask&e.code;,
 | |
|       &s.code;offset&e.code; and &s.code;rgbBits&e.code; fields of the
 | |
|       &s.code;ScrnInfoRec&e.code;.  It would normally be called fairly
 | |
|       early in the &s.code;ChipPreInit()&e.code; function for
 | |
|       depths > 8bpp.
 | |
| 
 | |
|       It requires that the &s.code;depth&e.code; and
 | |
|       &s.code;display&e.code; fields of the &s.code;ScrnInfoRec&e.code;
 | |
|       be initialised prior to calling it.
 | |
| 
 | |
|       The parameters passed are:
 | |
| 
 | |
|         &s.code;weight&e.code;
 | |
| 	<quote><p>
 | |
| 		driver's preferred default weight if no other is given.
 | |
|                 If zero, use the overall server default.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|         &s.code;mask&e.code;
 | |
| 	<quote><p>
 | |
| 		Same, but for mask.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       It uses the command line, config file, and default values in the
 | |
|       correct order of precedence to determine the weight value.  It
 | |
|       derives the mask and offset values from the weight and the defaults.
 | |
|       It is up to the driver to check the results to see that it supports
 | |
|       them.  If not the &s.code;ChipPreInit()&e.code; function should
 | |
|       return &s.code;FALSE&e.code;.
 | |
| 
 | |
|       On success, this function prints a message showing the weight
 | |
|       values selected, and returns &s.code;TRUE&e.code;.
 | |
| 
 | |
|       On failure it prints an error message and returns &s.code;FALSE&e.code;.
 | |
| 
 | |
|       The following fields of the &s.code;ScrnInfoRec&e.code; are
 | |
|       initialised by this function:
 | |
| 
 | |
| 	<quote>
 | |
|         &s.code;weight&e.code;, &s.code;mask&e.code;, &s.code;offset&e.code;.
 | |
| 	</quote>
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)&e.code;
 | |
|     <quote><p>
 | |
|       This function sets the &s.code;defaultVisual&e.code; field of the
 | |
|       &s.code;ScrnInfoRec&e.code;.  It would normally be called fairly
 | |
|       early from the &s.code;ChipPreInit()&e.code; function.
 | |
| 
 | |
|       It requires that the &s.code;depth&e.code; and
 | |
|       &s.code;display&e.code; fields of the &s.code;ScrnInfoRec&e.code;
 | |
|       be initialised prior to calling it.
 | |
| 
 | |
|       The parameters passed are:
 | |
| 
 | |
|         &s.code;visual&e.code;
 | |
| 	<quote><p>
 | |
| 		driver's preferred default visual if no other is given.
 | |
| 		If &s.code;-1&e.code;, use the overall server default.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       It uses the command line, config file, and default values in the
 | |
|       correct order of precedence to determine the default visual value.
 | |
|       It is up to the driver to check the result to see that it supports
 | |
|       it.  If not the &s.code;ChipPreInit()&e.code; function should
 | |
|       return &s.code;FALSE&e.code;.
 | |
| 
 | |
|       On success, this function prints a message showing the default visual
 | |
|       selected, and returns &s.code;TRUE&e.code;.
 | |
| 
 | |
|       On failure it prints an error message and returns &s.code;FALSE&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)&e.code;
 | |
|     <quote><p>
 | |
|       This function sets the &s.code;gamma&e.code; field of the
 | |
|       &s.code;ScrnInfoRec&e.code;.  It would normally be called fairly
 | |
|       early from the &s.code;ChipPreInit()&e.code; function in cases
 | |
|       where the driver supports gamma correction.
 | |
| 
 | |
|       It requires that the &s.code;monitor&e.code; field of the
 | |
|       &s.code;ScrnInfoRec&e.code; be initialised prior to calling it.
 | |
| 
 | |
|       The parameters passed are:
 | |
| 
 | |
|         &s.code;gamma&e.code;
 | |
| 	<quote><p>
 | |
| 		driver's preferred default gamma if no other is given.
 | |
| 		If zero (&s.code;< 0.01&e.code;), use the overall server
 | |
| 		default.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       It uses the command line, config file, and default values in the
 | |
|       correct order of precedence to determine the gamma value.  It is
 | |
|       up to the driver to check the results to see that it supports
 | |
|       them.  If not the &s.code;ChipPreInit()&e.code; function should
 | |
|       return &s.code;FALSE&e.code;.
 | |
| 
 | |
|       On success, this function prints a message showing the gamma
 | |
|       value selected, and returns &s.code;TRUE&e.code;.
 | |
| 
 | |
|       On failure it prints an error message and returns &s.code;FALSE&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)&e.code;
 | |
|     <quote><p>
 | |
|       This function sets the &s.code;xDpi&e.code; and &s.code;yDpi&e.code;
 | |
|       fields of the &s.code;ScrnInfoRec&e.code;.  The driver can specify
 | |
|       preferred defaults by setting &s.code;x&e.code; and &s.code;y&e.code;
 | |
|       to non-zero values.  The &s.cmd;-dpi&e.cmd; command line option
 | |
|       overrides all other settings.  Otherwise, if the
 | |
|       &s.key;DisplaySize&e.key; entry is present in the screen's &k.monitor;
 | |
|       config file section, it is used together with the virtual size to
 | |
|       calculate the dpi values.  This function should be called after
 | |
|       all the mode resolution has been done.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86SetBlackWhitePixels(ScrnInfoPtr pScrn)&e.code;
 | |
|     <quote><p>
 | |
|       This functions sets the &s.code;blackPixel&e.code; and
 | |
|       &s.code;whitePixel&e.code; fields of the &s.code;ScrnInfoRec&e.code;
 | |
|       according to whether or not the &s.cmd;-flipPixels&e.cmd; command
 | |
|       line options is present.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;const char *xf86GetVisualName(int visual)&e.code;
 | |
|     <quote><p>
 | |
|       Returns a printable string with the visual name matching the
 | |
|       numerical visual class provided.  If the value is outside the
 | |
|       range of valid visual classes, &s.code;NULL&e.code; is returned.
 | |
| 
 | |
|     </quote>
 | |
|   </quote>
 | |
| 
 | |
| 
 | |
| <sect1>Primary Mode functions
 | |
| <p>
 | |
| 
 | |
| The primary mode helper functions are those which would normally be
 | |
| used by a driver, unless it has unusual requirements which cannot
 | |
| be catered for the by the helpers.
 | |
| 
 | |
|   <quote><p>
 | |
|     &s.code;int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
 | |
| 		&f.indent;char **modeNames, ClockRangePtr clockRanges,
 | |
| 		&f.indent;int *linePitches, int minPitch, int maxPitch,
 | |
| 		&f.indent;int pitchInc, int minHeight, int maxHeight,
 | |
| 		&f.indent;int virtualX, int virtualY,
 | |
| 		&f.indent;unsigned long apertureSize,
 | |
| 		&f.indent;LookupModeFlags strategy)&e.code;
 | |
|     <quote><p>
 | |
|       This function basically selects the set of modes to use based on
 | |
|       those available and the various constraints.  It also sets some
 | |
|       other related parameters.  It is normally called near the end of
 | |
|       the &s.code;ChipPreInit()&e.code; function.
 | |
| 
 | |
|       The parameters passed to the function are:
 | |
| 
 | |
|         &s.code;availModes&e.code;
 | |
| 	<quote><p>
 | |
| 		List of modes available for the monitor.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;modeNames&e.code;
 | |
| 	<quote><p>
 | |
| 		List of mode names that the screen is requesting.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;clockRanges&e.code;
 | |
| 	<quote><p>
 | |
| 		A list of clock ranges allowed by the driver.  Each
 | |
| 		range includes whether interlaced or multiscan modes
 | |
| 		are supported for that range.  See below for more on
 | |
| 		&s.code;clockRanges&e.code;.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;linePitches&e.code;
 | |
| 	<quote><p>
 | |
| 		List of line pitches supported by the driver.
 | |
| 		This is optional and should be &s.code;NULL&e.code; when
 | |
| 		not used.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;minPitch&e.code;
 | |
| 	<quote><p>
 | |
| 		Minimum line pitch supported by the driver.  This must
 | |
| 		be supplied when &s.code;linePitches&e.code; is
 | |
| 		&s.code;NULL&e.code;, and is ignored otherwise.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;maxPitch&e.code;
 | |
| 	<quote><p>
 | |
| 		Maximum line pitch supported by the driver.  This is
 | |
| 		required when &s.code;minPitch&e.code; is required.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;pitchInc&e.code;
 | |
| 	<quote><p>
 | |
| 		Granularity of horizontal pitch values as supported by
 | |
| 		the chipset.  This is expressed in bits.  This must be
 | |
| 		supplied.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;minHeight&e.code;
 | |
| 	<quote><p>
 | |
| 		minimum virtual height allowed.  If zero, no limit is
 | |
| 		imposed.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;maxHeight&e.code;
 | |
| 	<quote><p>
 | |
| 		maximum virtual height allowed.  If zero, no limit is
 | |
| 		imposed.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;virtualX&e.code;
 | |
| 	<quote><p>
 | |
| 		If greater than zero, this is the virtual width value
 | |
| 		that will be used.  Otherwise, the virtual width is
 | |
| 		chosen to be the smallest that can accommodate the modes
 | |
| 		selected.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;virtualY&e.code;
 | |
| 	<quote><p>
 | |
| 		If greater than zero, this is the virtual height value
 | |
| 		that will be used.  Otherwise, the virtual height is
 | |
| 		chosen to be the smallest that can accommodate the modes
 | |
| 		selected.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;apertureSize&e.code;
 | |
| 	<quote><p>
 | |
| 		The size (in bytes) of the aperture used to access video
 | |
| 		memory.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;strategy&e.code;
 | |
| 	<quote><p>
 | |
| 		The strategy to use when choosing from multiple modes
 | |
| 		with the same name.  The options are:
 | |
| 
 | |
|                 &s.code;LOOKUP_DEFAULT&e.code;
 | |
| 		<quote>???</quote>
 | |
|                 &s.code;LOOKUP_BEST_REFRESH&e.code;
 | |
| 		<quote>mode with best refresh rate</quote>
 | |
|                 &s.code;LOOKUP_CLOSEST_CLOCK&e.code;
 | |
| 		<quote>mode with closest matching clock</quote>
 | |
|                 &s.code;LOOKUP_LIST_ORDER&e.code;
 | |
| 		<quote>first usable mode in list</quote>
 | |
| 
 | |
| 		The following options can also be combined (OR'ed) with
 | |
| 		one of the above:
 | |
| 
 | |
|                 &s.code;LOOKUP_CLKDIV2&e.code;
 | |
| 		<quote>Allow halved clocks</quote>
 | |
| 		&s.code;LOOKUP_OPTIONAL_TOLERANCES&e.code;
 | |
| 		<quote>Allow missing horizontal sync and/or vertical refresh
 | |
| 		ranges in the xorg.conf Monitor section</quote>
 | |
| 
 | |
| 		&s.code;LOOKUP_OPTIONAL_TOLERANCES&e.code; should only be
 | |
| 		specified when the driver can ensure all modes it generates
 | |
| 		can sync on, or at least not damage, the monitor or digital
 | |
| 		flat panel.  Horizontal sync and/or vertical refresh ranges
 | |
| 		specified by the user will still be honoured (and acted upon).
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       This function requires that the following fields of the
 | |
|       &s.code;ScrnInfoRec&e.code; are initialised prior to calling it:
 | |
| 
 | |
|         &s.code;clock[]&e.code;
 | |
| 	<quote>List of discrete clocks (when non-programmable)</quote>
 | |
|         &s.code;numClocks&e.code;
 | |
| 	<quote>Number of discrete clocks (when non-programmable)</quote>
 | |
|         &s.code;progClock&e.code;
 | |
| 	<quote>Whether the clock is programmable or not</quote>
 | |
|         &s.code;monitor&e.code;
 | |
| 	<quote>Pointer to the applicable xorg.conf monitor section</quote>
 | |
|         &s.code;fdFormat&e.code;
 | |
| 	<quote>Format of the screen buffer</quote>
 | |
|         &s.code;videoRam&e.code;
 | |
| 	<quote>total video memory size (in bytes)</quote>
 | |
|         &s.code;maxHValue&e.code;
 | |
| 	<quote>Maximum horizontal timing value allowed</quote>
 | |
|         &s.code;maxVValue&e.code;
 | |
| 	<quote>Maximum vertical timing value allowed</quote>
 | |
|         &s.code;xInc&e.code;
 | |
| 	<quote>Horizontal timing increment in pixels (defaults to 8)</quote>
 | |
| 
 | |
|       This function fills in the following &s.code;ScrnInfoRec&e.code;
 | |
|       fields:
 | |
| 
 | |
|         &s.code;modePool&e.code;
 | |
| 	<quote><p>
 | |
| 		A subset of the modes available to the monitor which
 | |
|                 are compatible with the driver.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;modes&e.code;
 | |
| 	<quote><p>
 | |
| 		One mode entry for each of the requested modes, with
 | |
|                 the status field of each filled in to indicate if
 | |
|                 the mode has been accepted or not.  This list of
 | |
|                 modes is a circular list.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;virtualX&e.code;
 | |
| 	<quote><p>
 | |
| 		The resulting virtual width.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;virtualY&e.code;
 | |
| 	<quote><p>
 | |
| 		The resulting virtual height.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;displayWidth&e.code;
 | |
| 	<quote><p>
 | |
| 		The resulting line pitch.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;virtualFrom&e.code;
 | |
| 	<quote><p>
 | |
| 		Where the virtual size was determined from.
 | |
| 
 | |
| 	</quote>
 | |
| 
 | |
|       The first stage of this function checks that the
 | |
|       &s.code;virtualX&e.code; and &s.code;virtualY&e.code; values
 | |
|       supplied (if greater than zero) are consistent with the line pitch
 | |
|       and &s.code;maxHeight&e.code; limitations.  If not, an error
 | |
|       message is printed, and the return value is &s.code;-1&e.code;.
 | |
| 
 | |
|       The second stage sets up the mode pool, eliminating immediately
 | |
|       any modes that exceed the driver's line pitch limits, and also
 | |
|       the virtual width and height limits (if greater than zero).  For
 | |
|       each mode removed an informational message is printed at verbosity
 | |
|       level &s.code;2&e.code;.  If the mode pool ends up being empty,
 | |
|       a warning message is printed, and the return value is
 | |
|       &s.code;0&e.code;.
 | |
| 
 | |
|       The final stage is to lookup each mode name, and fill in the remaining
 | |
|       parameters.  If an error condition is encountered, a message is
 | |
|       printed, and the return value is &s.code;-1&e.code;.  Otherwise,
 | |
|       the return value is the number of valid modes found
 | |
|       (&s.code;0&e.code; if none are found).
 | |
| 
 | |
|       Even if the supplied mode names include duplicates, no two names will
 | |
|       ever match the same mode.  Furthermore, if the supplied mode names do not
 | |
|       yield a valid mode (including the case where no names are passed at all),
 | |
|       the function will continue looking through the mode pool until it finds
 | |
|       a mode that survives all checks, or until the mode pool is exhausted.
 | |
| 
 | |
|       A message is only printed by this function when a fundamental
 | |
|       problem is found.  It is intended that this function may be called
 | |
|       more than once if there is more than one set of constraints that
 | |
|       the driver can work within.
 | |
| 
 | |
|       If this function returns &s.code;-1&e.code;, the
 | |
|       &s.code;ChipPreInit()&e.code; function should return
 | |
|       &s.code;FALSE&e.code;.
 | |
| 
 | |
|       &s.code;clockRanges&e.code; is a linked list of clock ranges
 | |
|       allowed by the driver.  If a mode doesn't fit in any of the defined
 | |
|       &s.code;clockRanges&e.code;, it is rejected.  The first
 | |
|       &s.code;clockRange&e.code; that matches all requirements is used.
 | |
|       This structure needs to be initialized to NULL when allocated.
 | |
| 
 | |
|       &s.code;clockRanges&e.code; contains the following fields:
 | |
| 
 | |
|         &s.code;minClock&nl;
 | |
|         maxClock&e.code;
 | |
| 	<quote><p>
 | |
| 		The lower and upper mode clock bounds for which the rest
 | |
| 		of the &s.code;clockRange&e.code; parameters apply.
 | |
| 		Since these are the mode clocks, they are not scaled
 | |
| 		with the &s.code;ClockMulFactor&e.code; and
 | |
| 		&s.code;ClockDivFactor&e.code;.  It is up to the driver
 | |
| 		to adjust these values if they depend on the clock
 | |
| 		scaling factors.
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;clockIndex&e.code;
 | |
| 	<quote><p>
 | |
| 		(not used yet) &s.code;-1&e.code; for programmable clocks
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;interlaceAllowed&e.code;
 | |
| 	<quote><p>
 | |
| 		&s.code;TRUE&e.code; if interlacing is allowed for this
 | |
| 		range
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;doubleScanAllowed&e.code;
 | |
| 	<quote><p>
 | |
| 		&s.code;TRUE&e.code; if doublescan or multiscan is allowed
 | |
| 		for this range
 | |
| 
 | |
| 	</quote>
 | |
|         &s.code;ClockMulFactor&nl;
 | |
|         ClockDivFactor&e.code;
 | |
| 	<quote><p>
 | |
| 		Scaling factors that are applied to the mode clocks ONLY
 | |
| 		before selecting a clock index (when there is no
 | |
| 		programmable clock) or a &s.code;SynthClock&e.code;
 | |
| 		value.  This is useful for drivers that support pixel
 | |
| 		multiplexing or that need to scale the clocks because
 | |
| 		of hardware restrictions (like sending 24bpp data to an
 | |
| 		8 bit RAMDAC using a tripled clock).
 | |
| 
 | |
| 		Note that these parameters describe what must be done
 | |
| 		to the mode clock to achieve the data transport clock
 | |
| 		between graphics controller and RAMDAC.  For example
 | |
| 		for &s.code;2:1&e.code; pixel multiplexing, two pixels
 | |
| 		are sent to the RAMDAC on each clock.  This allows the
 | |
| 		RAMDAC clock to be half of the actual pixel clock.
 | |
| 		Hence, &s.code;ClockMulFactor=1&e.code; and
 | |
| 		&s.code;ClockDivFactor=2&e.code;.  This means that the
 | |
| 		clock used for clock selection (ie, determining the
 | |
| 		correct clock index from the list of discrete clocks)
 | |
| 		or for the &s.code;SynthClock&e.code; field in case of
 | |
| 		a programmable clock is:  (&s.code;mode->Clock *
 | |
| 		ClockMulFactor) / ClockDivFactor&e.code;.
 | |
| 
 | |
| 	</quote>
 | |
| 	&s.code;PrivFlags&e.code;
 | |
| 	<quote><p>
 | |
| 		This field is copied into the
 | |
| 		&s.code;mode->PrivFlags&e.code; field when this
 | |
| 		&s.code;clockRange&e.code; is selected by
 | |
| 		&s.code;xf86ValidateModes()&e.code;.  It allows the
 | |
| 		driver to find out what clock range was selected, so it
 | |
| 		knows it needs to set up pixel multiplexing or any other
 | |
| 		range-dependent feature.  This field is purely
 | |
| 		driver-defined: it may contain flag bits, an index or
 | |
| 		anything else (as long as it is an &s.code;INT&e.code;).
 | |
| 	</quote>
 | |
| 
 | |
|       Note that the &s.code;mode->SynthClock&e.code; field is always
 | |
|       filled in by &s.code;xf86ValidateModes()&e.code;: it will contain
 | |
|       the ``data transport clock'', which is the clock that will have
 | |
|       to be programmed in the chip when it has a programmable clock, or
 | |
|       the clock that will be picked from the clocks list when it is not
 | |
|       a programmable one.  Thus:
 | |
| 
 | |
|          &s.code;mode->SynthClock =
 | |
| 		&f.indent;(mode->Clock * ClockMulFactor) / ClockDivFactor&e.code;
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86PruneDriverModes(ScrnInfoPtr scrp)&e.code;
 | |
|     <quote><p>
 | |
|       This function deletes modes in the modes field of the
 | |
|       &s.code;ScrnInfoRec&e.code; that have been marked as invalid.
 | |
|       This is normally run after having run
 | |
|       &s.code;xf86ValidateModes()&e.code; for the last time.  For each
 | |
|       mode that is deleted, a warning message is printed out indicating
 | |
|       the reason for it being deleted.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)&e.code;
 | |
|     <quote><p>
 | |
|       This function fills in the &s.code;Crtc*&e.code; fields for all
 | |
|       the modes in the &s.code;modes&e.code; field of the
 | |
|       &s.code;ScrnInfoRec&e.code;.  The &s.code;adjustFlags&e.code;
 | |
|       parameter determines how the vertical CRTC values are scaled for
 | |
|       interlaced modes.  They are halved if it is
 | |
|       &s.code;INTERLACE_HALVE_V&e.code;.  The vertical CRTC values are
 | |
|       doubled for doublescan modes, and are further multiplied by the
 | |
|       &s.code;VScan&e.code; value.
 | |
| 
 | |
|       This function is normally called after calling
 | |
|       &s.code;xf86PruneDriverModes()&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86PrintModes(ScrnInfoPtr scrp)&e.code;
 | |
|     <quote><p>
 | |
|       This function prints out the virtual size setting, and the line
 | |
|       pitch being used.  It also prints out two lines for each mode being
 | |
|       used.  The first line includes the mode's pixel clock, horizontal sync
 | |
|       rate, refresh rate, and whether it is interlaced, doublescanned and/or
 | |
|       multi-scanned.  The second line is the mode's Modeline.
 | |
| 
 | |
|       This function is normally called after calling
 | |
|       &s.code;xf86SetCrtcForModes()&e.code;.
 | |
| 
 | |
|     </quote>
 | |
|   </quote>
 | |
| 
 | |
| 
 | |
| <sect1>Secondary Mode functions
 | |
| <p>
 | |
| 
 | |
| The secondary mode helper functions are functions which are normally
 | |
| used by the primary mode helper functions, and which are not normally
 | |
| called directly by a driver.  If a driver has unusual requirements
 | |
| and needs to do its own mode validation, it might be able to make
 | |
| use of some of these secondary mode helper functions.
 | |
| 
 | |
|   <quote><p>
 | |
|     &s.code;int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
 | |
| 			&f.indent;int *divider)&e.code;
 | |
|     <quote><p>
 | |
|       This function returns the index of the closest clock to the
 | |
|       frequency &s.code;freq&e.code; given (in kHz).  It assumes that
 | |
|       the number of clocks is greater than zero.  It requires that the
 | |
|       &s.code;numClocks&e.code; and &s.code;clock&e.code; fields of the
 | |
|       &s.code;ScrnInfoRec&e.code; are initialised.  The
 | |
|       &s.code;allowDiv2&e.code; field determines if the clocks can be
 | |
|       halved.  The &s.code;*divider&e.code; return value indicates
 | |
|       whether clock division is used when determining the clock returned.
 | |
| 
 | |
|       This function is only for non-programmable clocks.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;const char *xf86ModeStatusToString(ModeStatus status)&e.code;
 | |
|     <quote><p>
 | |
|       This function converts the &s.code;status&e.code; value to a
 | |
|       descriptive printable string.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
 | |
| 		&f.indent;ClockRangePtr clockRanges, LookupModeFlags strategy)&e.code;
 | |
|     <quote><p>
 | |
|       This function takes a pointer to a mode with the name filled in,
 | |
|       and looks for a mode in the &s.code;modePool&e.code; list which
 | |
|       matches.  The parameters of the matching mode are filled in to
 | |
|       &s.code;*modep&e.code;.  The &s.code;clockRanges&e.code; and
 | |
|       &s.code;strategy&e.code; parameters are as for the
 | |
|       &s.code;xf86ValidateModes()&e.code; function above.
 | |
| 
 | |
|       This function requires the &s.code;modePool&e.code;,
 | |
|       &s.code;clock[]&e.code;, &s.code;numClocks&e.code; and
 | |
|       &s.code;progClock&e.code; fields of the &s.code;ScrnInfoRec&e.code;
 | |
|       to be initialised before being called.
 | |
| 
 | |
|       The return value is &s.code;MODE_OK&e.code; if a mode was found.
 | |
|       Otherwise it indicates why a matching mode could not be found.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp,
 | |
| 		&f.indent;DisplayModePtr mode, ClockRangePtr clockRanges,
 | |
| 		&f.indent;LookupModeFlags strategy, int maxPitch,
 | |
| 		&f.indent;int virtualX, int virtualY)&e.code;
 | |
|     <quote><p>
 | |
|       This function checks the passed mode against some basic driver
 | |
|       constraints.  Apart from the ones passed explicitly, the
 | |
|       &s.code;maxHValue&e.code; and &s.code;maxVValue&e.code; fields of
 | |
|       the &s.code;ScrnInfoRec&e.code; are also used.  If the
 | |
|       &s.code;ValidMode&e.code; field of the &s.code;ScrnInfoRec&e.code;
 | |
|       is set, that function is also called to check the mode.  Next, the
 | |
|       mode is checked against the monitor's constraints.
 | |
| 
 | |
|       If the mode is consistent with all constraints, the return value
 | |
|       is &s.code;MODE_OK&e.code;.  Otherwise the return value indicates
 | |
|       which constraint wasn't met.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)&e.code;
 | |
|     <quote><p>
 | |
|       This function deletes the &s.code;mode&e.code; given from the
 | |
|       &s.code;modeList&e.code;.  It never prints any messages, so it is
 | |
|       up to the caller to print a message if required.
 | |
| 
 | |
|     </quote>
 | |
|   </quote>
 | |
| 
 | |
| <sect1>Functions for handling strings and tokens
 | |
| <p>
 | |
| 
 | |
|     Tables associating strings and numerical tokens combined with the
 | |
|     following functions provide a compact way of handling strings from
 | |
|     the config file, and for converting tokens into printable strings.
 | |
|     The table data structure is:
 | |
| 
 | |
| <quote><verb>
 | |
| typedef struct {
 | |
|     int                 token;
 | |
|     const char *        name;
 | |
| } SymTabRec, *SymTabPtr;
 | |
| </verb></quote>
 | |
| 
 | |
|     A table is an initialised array of &s.code;SymTabRec&e.code;.  The
 | |
|     tokens must be non-negative integers.  Multiple names may be mapped
 | |
|     to a single token.  The table is terminated with an element with a
 | |
|     &s.code;token&e.code; value of &s.code;-1&e.code; and
 | |
|     &s.code;NULL&e.code; for the &s.code;name&e.code;.
 | |
| 
 | |
| 
 | |
|   <quote><p>
 | |
|     &s.code;const char *xf86TokenToString(SymTabPtr table, int token)&e.code;
 | |
|     <quote><p>
 | |
|       This function returns the first string in &s.code;table&e.code;
 | |
|       that matches &s.code;token&e.code;.  If no match is found,
 | |
|       &s.code;NULL&e.code; is returned (NOTE, older versions of this
 | |
|       function would return the string "unknown" when no match is found).
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;int xf86StringToToken(SymTabPtr table, const char *string)&e.code;
 | |
|     <quote><p>
 | |
|       This function returns the first token in &s.code;table&e.code;
 | |
|       that matches &s.code;string&e.code;.  The
 | |
|       &s.code;xf86NameCmp()&e.code; function is used to determine the
 | |
|       match.  If no match is found, &s.code;-1&e.code; is returned.
 | |
| 
 | |
|     </quote>
 | |
|   </quote>
 | |
| 
 | |
| 
 | |
| <sect1>Functions for finding which config file entries to use
 | |
| <p>
 | |
| 
 | |
|     These functions can be used to select the appropriate config file
 | |
|     entries that match the detected hardware.  They are described above
 | |
|     in the <ref id="probe" name="Probe"> and
 | |
|     <ref id="avail" name="Available Functions"> sections.
 | |
| 
 | |
| 
 | |
| <sect1>Probing discrete clocks on old hardware
 | |
| <p>
 | |
| 
 | |
|     The &s.code;xf86GetClocks()&e.code; function may be used to assist
 | |
|     in finding the discrete pixel clock values on older hardware.
 | |
| 
 | |
| 
 | |
|   <quote><p>
 | |
|     &s.code;void xf86GetClocks(ScrnInfoPtr pScrn, int num,
 | |
| 		&f.indent;Bool (*ClockFunc)(ScrnInfoPtr, int),
 | |
| 		&f.indent;void (*ProtectRegs)(ScrnInfoPtr, Bool),
 | |
| 		&f.indent;void (*BlankScreen)(ScrnInfoPtr, Bool),
 | |
| 		&f.indent;int vertsyncreg, int maskval, int knownclkindex,
 | |
| 		&f.indent;int knownclkvalue)&e.code;
 | |
|     <quote><p>
 | |
|       This function uses a comparative sampling method to measure the
 | |
|       discrete pixel clock values.  The number of discrete clocks to
 | |
|       measure is given by &s.code;num&e.code;.  &s.code;clockFunc&e.code;
 | |
|       is a function that selects the &s.code;n&e.code;'th clock.  It
 | |
|       should also save or restore any state affected by programming the
 | |
|       clocks when the index passed is &s.code;CLK_REG_SAVE&e.code; or
 | |
|       &s.code;CLK_REG_RESTORE&e.code;.  &s.code;ProtectRegs&e.code; is
 | |
|       a function that does whatever is required to protect the hardware
 | |
|       state while selecting a new clock.  &s.code;BlankScreen&e.code;
 | |
|       is a function that blanks the screen.  &s.code;vertsyncreg&e.code;
 | |
|       and &s.code;maskval&e.code; are the register and bitmask to
 | |
|       check for the presence of vertical sync pulses.
 | |
|       &s.code;knownclkindex&e.code; and &s.code;knownclkvalue&e.code;
 | |
|       are the index and value of a known clock.  These are the known
 | |
|       references on which the comparative measurements are based.  The
 | |
|       number of clocks probed is set in &s.code;pScrn->numClocks&e.code;,
 | |
|       and the probed clocks are set in the &s.code;pScrn->clock[]&e.code;
 | |
|       array.  All of the clock values are in units of kHz.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)&e.code;
 | |
|     <quote><p>
 | |
|       Print out the pixel clocks &s.code;scrp->clock[]&e.code;.
 | |
|       &s.code;from&e.code; indicates whether the clocks were probed
 | |
|       or from the config file.
 | |
| 
 | |
|     </quote>
 | |
|   </quote>
 | |
| 
 | |
| <sect1>Other helper functions
 | |
| <p>
 | |
|   <quote><p>
 | |
|     &s.code;Bool xf86IsUnblank(int mode)&e.code;
 | |
|     <quote><p>
 | |
|       Returns &s.code;TRUE&e.code; when the screen saver mode specified
 | |
|       by &s.code;mode&e.code; requires the screen be unblanked,
 | |
|       and &s.code;FALSE&e.code; otherwise.  The screen saver modes that
 | |
|       require blanking are &s.code;SCREEN_SAVER_ON&e.code; and
 | |
|       &s.code;SCREEN_SAVER_CYCLE&e.code;, and the screen saver modes that
 | |
|       require unblanking are &s.code;SCREEN_SAVER_OFF&e.code; and
 | |
|       &s.code;SCREEN_SAVER_FORCER&e.code;.  Drivers may call this helper
 | |
|       from their &s.code;SaveScreen()&e.code; function to interpret the
 | |
|       screen saver modes.
 | |
| 
 | |
|     </quote>
 | |
|   </quote>
 | |
| 
 | |
| <sect>The vgahw module
 | |
| <p>
 | |
| 
 | |
| The vgahw modules provides an interface for saving, restoring and
 | |
| programming the standard VGA registers, and for handling VGA colourmaps.
 | |
| 
 | |
| <sect1>Data Structures
 | |
| <p>
 | |
| 
 | |
|     The public data structures used by the vgahw module are
 | |
|     &s.code;vgaRegRec&e.code; and &s.code;vgaHWRec&e.code;.  They are
 | |
|     defined in &s.code;vgaHW.h.&e.code;
 | |
| 
 | |
| 
 | |
| <sect1>General vgahw Functions
 | |
| <p>
 | |
| 
 | |
|   <quote><p>
 | |
|     &s.code;Bool vgaHWGetHWRec(ScrnInfoPtr pScrn)&e.code;
 | |
|     <quote><p>
 | |
|       This function allocates a &s.code;vgaHWRec&e.code; structure, and
 | |
|       hooks it into the &s.code;ScrnInfoRec&e.code;'s
 | |
|       &s.code;privates&e.code;.  Like all information hooked into the
 | |
|       &s.code;privates&e.code;, it is persistent, and only needs to be
 | |
|       allocated once per screen.  This function should normally be called
 | |
|       from the driver's &s.code;ChipPreInit()&e.code; function.  The
 | |
|       &s.code;vgaHWRec&e.code; is zero-allocated, and the following
 | |
|       fields are explicitly initialised:
 | |
| 
 | |
|         &s.code;ModeReg.DAC[]&e.code;
 | |
| 	<quote>initialised with a default colourmap</quote>
 | |
|         &s.code;ModeReg.Attribute[0x11]&e.code;
 | |
| 	<quote>initialised with the default overscan index</quote>
 | |
|         &s.code;ShowOverscan&e.code;
 | |
| 	<quote>initialised according to the "ShowOverscan" option</quote>
 | |
|         &s.code;paletteEnabled&e.code;
 | |
| 	<quote>initialised to FALSE</quote>
 | |
|         &s.code;cmapSaved&e.code;
 | |
| 	<quote>initialised to FALSE</quote>
 | |
|         &s.code;pScrn&e.code;
 | |
| 	<quote>initialised to pScrn</quote>
 | |
| 
 | |
|       In addition to the above, &s.code;vgaHWSetStdFuncs()&e.code; is
 | |
|       called to initialise the register access function fields with the
 | |
|       standard VGA set of functions.
 | |
| 
 | |
|       Once allocated, a pointer to the &s.code;vgaHWRec&e.code; can be
 | |
|       obtained from the &s.code;ScrnInfoPtr&e.code; with the
 | |
|       &s.code;VGAHWPTR(pScrn)&e.code; macro.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWFreeHWRec(ScrnInfoPtr pScrn)&e.code;
 | |
|     <quote><p>
 | |
|       This function frees a &s.code;vgaHWRec&e.code; structure.  It
 | |
|       should be called from a driver's &s.code;ChipFreeScreen()&e.code;
 | |
|       function.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool vgaHWSetRegCounts(ScrnInfoPtr pScrn, int numCRTC,
 | |
| 		&f.indent;int numSequencer, int numGraphics, int numAttribute)&e.code;
 | |
|     <quote><p>
 | |
|       This function allows the number of CRTC, Sequencer, Graphics and
 | |
|       Attribute registers to be changed.  This makes it possible for
 | |
|       extended registers to be saved and restored with
 | |
|       &s.code;vgaHWSave()&e.code; and &s.code;vgaHWRestore()&e.code;.
 | |
|       This function should be called after a &s.code;vgaHWRec&e.code;
 | |
|       has been allocated with &s.code;vgaHWGetHWRec()&e.code;.  The
 | |
|       default values are defined in &s.code;vgaHW.h&e.code; as follows:
 | |
| 
 | |
|       <quote><verb>
 | |
| #define VGA_NUM_CRTC 25
 | |
| #define VGA_NUM_SEQ   5
 | |
| #define VGA_NUM_GFX   9
 | |
| #define VGA_NUM_ATTR 21
 | |
|       </verb></quote>
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)&e.code;
 | |
|     <quote><p>
 | |
|       This function copies the contents of the VGA saved registers in
 | |
|       &s.code;src&e.code; to &s.code;dst&e.code;.  Note that it isn't
 | |
|       possible to simply do this with &s.code;memcpy()&e.code; (or
 | |
|       similar).  This function returns &s.code;TRUE&e.code; unless there
 | |
|       is a problem allocating space for the &s.code;CRTC&e.code and
 | |
|       related fields in &s.code;dst&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWSetStdFuncs(vgaHWPtr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       This function initialises the register access function fields of
 | |
|       &s.code;hwp&e.code; with the standard VGA set of functions.  This
 | |
|       is called by &s.code;vgaHWGetHWRec()&e.code;, so there is usually
 | |
|       no need to call this explicitly.  The register access functions
 | |
|       are described below.  If the registers are shadowed in some other
 | |
|       port I/O space (for example a PCI I/O region), these functions
 | |
|       can be used to access the shadowed registers if
 | |
|       &s.code;hwp->PIOOffset&e.code; is initialised with
 | |
|       &s.code;offset&e.code;, calculated in such a way that when the
 | |
|       standard VGA I/O port value is added to it the correct offset into
 | |
|       the PIO area results.  This value is initialised to zero in
 | |
|       &s.code;vgaHWGetHWRec()&e.code;.  (Note: the PIOOffset functionality
 | |
|       is present in XFree86 4.1.0 and later.)
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)&e.code;
 | |
|     <quote><p>
 | |
|       This function initialised the register access function fields of
 | |
|       hwp with a generic MMIO set of functions.
 | |
|       &s.code;hwp->MMIOBase&e.code; is initialised with
 | |
|       &s.code;base&e.code;, which must be the virtual address that the
 | |
|       start of MMIO area is mapped to.  &s.code;hwp->MMIOOffset&e.code;
 | |
|       is initialised with &s.code;offset&e.code;, which must be calculated
 | |
|       in such a way that when the standard VGA I/O port value is added
 | |
|       to it the correct offset into the MMIO area results.  That means
 | |
|       that these functions are only suitable when the VGA I/O ports are
 | |
|       made available in a direct mapping to the MMIO space.  If that is
 | |
|       not the case, the driver will need to provide its own register
 | |
|       access functions.  The register access functions are described
 | |
|       below.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool vgaHWMapMem(ScrnInfoPtr pScrn)&e.code;
 | |
|     <quote><p>
 | |
|       This function maps the VGA memory window.  It requires that the
 | |
|       &s.code;vgaHWRec&e.code; be allocated.  If a driver requires
 | |
|       non-default &s.code;MapPhys&e.code; or &s.code;MapSize&e.code;
 | |
|       settings (the physical location and size of the VGA memory window)
 | |
|       then those fields of the &s.code;vgaHWRec&e.code; must be initialised
 | |
|       before calling this function.  Otherwise, this function initialiases
 | |
|       the default values of &s.code;0xA0000&e.code; for
 | |
|       &s.code;MapPhys&e.code; and &s.code;(64 * 1024)&e.code; for
 | |
|       &s.code;MapSize&e.code;.  This function must be called before
 | |
|       attempting to save or restore the VGA state.  If the driver doesn't
 | |
|       call it explicitly, the &s.code;vgaHWSave()&e.code; and
 | |
|       &s.code;vgaHWRestore()&e.code; functions may call it if they need
 | |
|       to access the VGA memory (in which case they will also call
 | |
|       &s.code;vgaHWUnmapMem()&e.code; to unmap the VGA memory before
 | |
|       exiting).
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWUnmapMem(ScrnInfoPtr pScrn)&e.code;
 | |
|     <quote><p>
 | |
|       This function unmaps the VGA memory window.  It must only be called
 | |
|       after the memory has been mapped.  The &s.code;Base&e.code; field
 | |
|       of the &s.code;vgaHWRec&e.code; field is set to &s.code;NULL&e.code;
 | |
|       to indicate that the memory is no longer mapped.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWGetIOBase(vgaHWPtr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       This function initialises the &s.code;IOBase&e.code; field of the
 | |
|       &s.code;vgaHWRec&e.code;.  This function must be called before
 | |
|       using any other functions that access the video hardware.
 | |
| 
 | |
|       A macro &s.code;VGAHW_GET_IOBASE()&e.code; is also available in
 | |
|       &s.code;vgaHW.h&e.code; that returns the I/O base, and this may
 | |
|       be used when the vgahw module is not loaded (for example, in the
 | |
|       &s.code;ChipProbe()&e.code; function).
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWUnlock(vgaHWPtr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       This function unlocks the VGA &s.code;CRTC[0-7]&e.code; registers,
 | |
|       and must be called before attempting to write to those registers.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWLock(vgaHWPtr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       This function locks the VGA &s.code;CRTC[0-7]&e.code; registers.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWEnable(vgaHWPtr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       This function enables the VGA subsystem.  (Note, this function is
 | |
|       present in XFree86 4.1.0 and later.).
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWDisable(vgaHWPtr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       This function disables the VGA subsystem.  (Note, this function is
 | |
|       present in XFree86 4.1.0 and later.).
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWSave(ScrnInfoPtr pScrn, vgaRegPtr save, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       This function saves the VGA state.  The state is written to the
 | |
|       &s.code;vgaRegRec&e.code; pointed to by &s.code;save&e.code;.
 | |
|       &s.code;flags&e.code; is set to one or more of the following flags
 | |
|       ORed together:
 | |
| 
 | |
|         &s.code;VGA_SR_MODE&e.code;
 | |
| 	<quote>the mode setting registers are saved</quote>
 | |
|         &s.code;VGA_SR_FONTS&e.code;
 | |
| 	<quote>the text mode font/text data is saved</quote>
 | |
|         &s.code;VGA_SR_CMAP&e.code;
 | |
| 	<quote>the colourmap (LUT) is saved</quote>
 | |
|         &s.code;VGA_SR_ALL&e.code;
 | |
| 	<quote>all of the above are saved</quote>
 | |
| 
 | |
|       The &s.code;vgaHWRec&e.code; and its &s.code;IOBase&e.code; fields
 | |
|       must be initialised before this function is called.  If
 | |
|       &s.code;VGA_SR_FONTS&e.code; is set in &s.code;flags&e.code;, the
 | |
|       VGA memory window must be mapped.  If it isn't then
 | |
|       &s.code;vgaHWMapMem()&e.code; will be called to map it, and
 | |
|       &s.code;vgaHWUnmapMem()&e.code; will be called to unmap it
 | |
|       afterwards.  &s.code;vgaHWSave()&e.code; uses the three functions
 | |
|       below in the order &s.code;vgaHWSaveColormap()&e.code;,
 | |
|       &s.code;vgaHWSaveMode()&e.code;, &s.code;vgaHWSaveFonts()&e.code; to
 | |
|       carry out the different save phases.  It is undecided at this
 | |
|       stage whether they will remain part of the vgahw module's public
 | |
|       interface or not.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWSaveMode(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
 | |
|     <quote><p>
 | |
|       This function saves the VGA mode registers.  They are saved to
 | |
|       the &s.code;vgaRegRec&e.code; pointed to by &s.code;save&e.code;.
 | |
|       The registers saved are:
 | |
| 
 | |
| 	<quote>
 | |
|         &s.code;MiscOut&nl;
 | |
|         CRTC[0-0x18]&nl;
 | |
|         Attribute[0-0x14]&nl;
 | |
|         Graphics[0-8]&nl;
 | |
|         Sequencer[0-4]&e.code;
 | |
| 	</quote>
 | |
| 
 | |
|     The number of registers actually saved may be modified by a prior call
 | |
|     to &s.code;vgaHWSetRegCounts()&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWSaveFonts(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
 | |
|     <quote><p>
 | |
|       This function saves the text mode font and text data held in the
 | |
|       video memory.  If called while in a graphics mode, no save is
 | |
|       done.  The VGA memory window must be mapped with
 | |
|       &s.code;vgaHWMapMem()&e.code; before to calling this function.
 | |
| 
 | |
|       On some platforms, one or more of the font/text plane saves may be
 | |
|       no-ops.  This is the case when the platform's VC driver already
 | |
|       takes care of this.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWSaveColormap(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
 | |
|     <quote><p>
 | |
|       This function saves the VGA colourmap (LUT).  Before saving it, it
 | |
|       attempts to verify that the colourmap is readable.  In rare cases
 | |
|       where it isn't readable, a default colourmap is saved instead.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWRestore(ScrnInfoPtr pScrn, vgaRegPtr restore, int flags)&e.code;
 | |
|     <quote><p>
 | |
|       This function programs the VGA state.  The state programmed is
 | |
|       that contained in the &s.code;vgaRegRec&e.code; pointed to by
 | |
|       &s.code;restore&e.code;.  &s.code;flags&e.code; is the same
 | |
|       as described above for the &s.code;vgaHWSave()&e.code; function.
 | |
| 
 | |
|       The &s.code;vgaHWRec&e.code; and its &s.code;IOBase&e.code; fields
 | |
|       must be initialised before this function is called.  If
 | |
|       &s.code;VGA_SR_FONTS&e.code; is set in &s.code;flags&e.code;, the
 | |
|       VGA memory window must be mapped.  If it isn't then
 | |
|       &s.code;vgaHWMapMem()&e.code; will be called to map it, and
 | |
|       &s.code;vgaHWUnmapMem()&e.code; will be called to unmap it
 | |
|       afterwards.  &s.code;vgaHWRestore()&e.code; uses the three functions
 | |
|       below in the order &s.code;vgaHWRestoreFonts()&e.code;,
 | |
|       &s.code;vgaHWRestoreMode()&e.code;,
 | |
|       &s.code;vgaHWRestoreColormap()&e.code; to carry out the different
 | |
|       restore phases.  It is undecided at this stage whether they will
 | |
|       remain part of the vgahw module's public interface or not.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWRestoreMode(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
 | |
|     <quote><p>
 | |
|       This function restores the VGA mode registers.  They are restored
 | |
|       from the data in the &s.code;vgaRegRec&e.code; pointed to by
 | |
|       &s.code;restore&e.code;.  The registers restored are:
 | |
| 
 | |
| 	<quote>
 | |
|         &s.code;MiscOut&nl;
 | |
|         CRTC[0-0x18]&nl;
 | |
|         Attribute[0-0x14]&nl;
 | |
|         Graphics[0-8]&nl;
 | |
|         Sequencer[0-4]&e.code;
 | |
| 	</quote>
 | |
| 
 | |
|     The number of registers actually restored may be modified by a prior call
 | |
|     to &s.code;vgaHWSetRegCounts()&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWRestoreFonts(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
 | |
|     <quote><p>
 | |
|       This function restores the text mode font and text data to the
 | |
|       video memory.  The VGA memory window must be mapped with
 | |
|       &s.code;vgaHWMapMem()&e.code; before to calling this function.
 | |
| 
 | |
|       On some platforms, one or more of the font/text plane restores
 | |
|       may be no-ops.  This is the case when the platform's VC driver
 | |
|       already takes care of this.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWRestoreColormap(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
 | |
|     <quote><p>
 | |
|       This function restores the VGA colourmap (LUT).
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWInit(ScrnInfoPtr pScrn, DisplayModePtr mode)&e.code;
 | |
|     <quote><p>
 | |
|       This function fills in the &s.code;vgaHWRec&e.code;'s
 | |
|       &s.code;ModeReg&e.code; field with the values appropriate for
 | |
|       programming the given video mode.  It requires that the
 | |
|       &s.code;ScrnInfoRec&e.code;'s &s.code;depth&e.code; field is
 | |
|       initialised, which determines how the registers are programmed.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWSeqReset(vgaHWPtr hwp, Bool start)&e.code;
 | |
|     <quote><p>
 | |
|       Do a VGA sequencer reset.  If start is &s.code;TRUE&e.code;, the
 | |
|       reset is started.  If start is &s.code;FALSE&e.code;, the reset
 | |
|       is ended.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWProtect(ScrnInfoPtr pScrn, Bool on)&e.code;
 | |
|     <quote><p>
 | |
|       This function protects VGA registers and memory from corruption
 | |
|       during loads.  It is typically called with on set to
 | |
|       &s.code;TRUE&e.code; before programming, and with on set to
 | |
|       &s.code;FALSE&e.code; after programming.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;Bool vgaHWSaveScreen(ScreenPtr pScreen, int mode)&e.code;
 | |
|     <quote><p>
 | |
|       This function blanks and unblanks the screen.  It is blanked when
 | |
|       &s.code;mode&e.code; is &s.code;SCREEN_SAVER_ON&e.code; or
 | |
|       &s.code;SCREEN_SAVER_CYCLE&e.code;, and unblanked when
 | |
|       &s.code;mode&e.code; is &s.code;SCREEN_SAVER_OFF&e.code; or
 | |
|       &s.code;SCREEN_SAVER_FORCER&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)&e.code;
 | |
|     <quote><p>
 | |
|       This function blanks and unblanks the screen.  It is blanked when
 | |
|       &s.code;on&e.code; is &s.code;FALSE&e.code;, and unblanked when
 | |
|       &s.code;on&e.code; is &s.code;TRUE&e.code;.  This function is
 | |
|       provided for use in cases where the &s.code;ScrnInfoRec&e.code;
 | |
|       can't be derived from the &s.code;ScreenRec&e.code; (while probing
 | |
|       for clocks, for example).
 | |
| 
 | |
|     </quote>
 | |
|   </quote>
 | |
| 
 | |
| <sect1>VGA Colormap Functions
 | |
| <p>
 | |
| 
 | |
|     The vgahw module uses the standard colormap support (see the
 | |
|     <ref id="cmap" name="Colormap Handling"> section.  This is initialised
 | |
|     with the following function:
 | |
| 
 | |
|   <quote>
 | |
|       &s.code;Bool vgaHWHandleColormaps(ScreenPtr pScreen)&e.code;
 | |
|   </quote>
 | |
| 
 | |
| 
 | |
| <sect1>VGA Register Access Functions
 | |
| <p>
 | |
| 
 | |
|     The vgahw module abstracts access to the standard VGA registers by
 | |
|     using a set of functions held in the &s.code;vgaHWRec&e.code;.  When
 | |
|     the &s.code;vgaHWRec&e.code; is created these function pointers are
 | |
|     initialised with the set of standard VGA I/O register access functions.
 | |
|     In addition to these, the vgahw module includes a basic set of MMIO
 | |
|     register access functions, and the &s.code;vgaHWRec&e.code; function
 | |
|     pointers can be initialised to these by calling the
 | |
|     &s.code;vgaHWSetMmioFuncs()&e.code; function described above.  Some
 | |
|     drivers/platforms may require a different set of functions for VGA
 | |
|     access.  The access functions are described here.
 | |
| 
 | |
| 
 | |
|   <quote><p>
 | |
|     &s.code;void writeCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)&e.code;
 | |
|     <quote><p>
 | |
|       Write &s.code;value&e.code; to CRTC register &s.code;index&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;CARD8 readCrtc(vgaHWPtr hwp, CARD8 index)&e.code;
 | |
|     <quote><p>
 | |
|       Return the value read from CRTC register &s.code;index&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void writeGr(vgaHWPtr hwp, CARD8 index, CARD8 value)&e.code;
 | |
|     <quote><p>
 | |
|       Write &s.code;value&e.code; to Graphics Controller register
 | |
|       &s.code;index&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;CARD8 readGR(vgaHWPtr hwp, CARD8 index)&e.code;
 | |
|     <quote><p>
 | |
|       Return the value read from Graphics Controller register
 | |
|       &s.code;index&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void writeSeq(vgaHWPtr hwp, CARD8 index, CARD8, value)&e.code;
 | |
|     <quote><p>
 | |
|       Write &s.code;value&e.code; to Sequencer register
 | |
|       &s.code;index&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;CARD8 readSeq(vgaHWPtr hwp, CARD8 index)&e.code;
 | |
|     <quote><p>
 | |
|       Return the value read from Sequencer register &s.code;index&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void writeAttr(vgaHWPtr hwp, CARD8 index, CARD8, value)&e.code;
 | |
|     <quote><p>
 | |
|       Write &s.code;value&e.code; to Attribute Controller register
 | |
|       &s.code;index&e.code;.  When writing out the index value this
 | |
|       function should set bit 5 (&s.code;0x20&e.code;) according to the
 | |
|       setting of &s.code;hwp->paletteEnabled&e.code; in order to
 | |
|       preserve the palette access state.  It should be cleared when
 | |
|       &s.code;hwp->paletteEnabled&e.code; is &s.code;TRUE&e.code;
 | |
|       and set when it is &s.code;FALSE&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;CARD8 readAttr(vgaHWPtr hwp, CARD8 index)&e.code;
 | |
|     <quote><p>
 | |
|       Return the value read from Attribute Controller register
 | |
|       &s.code;index&e.code;.  When writing out the index value this
 | |
|       function should set bit 5 (&s.code;0x20&e.code;) according to the
 | |
|       setting of &s.code;hwp->paletteEnabled&e.code; in order to
 | |
|       preserve the palette access state.  It should be cleared when
 | |
|       &s.code;hwp->paletteEnabled&e.code; is &s.code;TRUE&e.code;
 | |
|       and set when it is &s.code;FALSE&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void writeMiscOut(vgaHWPtr hwp, CARD8 value)&e.code;
 | |
|     <quote><p>
 | |
|       Write `&s.code;value&e.code;' to the Miscellaneous Output register.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;CARD8 readMiscOut(vgwHWPtr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       Return the value read from the Miscellaneous Output register.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void enablePalette(vgaHWPtr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       Clear the palette address source bit in the Attribute Controller
 | |
|       index register and set &s.code;hwp->paletteEnabled&e.code; to
 | |
|       &s.code;TRUE&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void disablePalette(vgaHWPtr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       Set the palette address source bit in the Attribute Controller
 | |
|       index register and set &s.code;hwp->paletteEnabled&e.code; to
 | |
|       &s.code;FALSE&e.code;.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void writeDacMask(vgaHWPtr hwp, CARD8 value)&e.code;
 | |
|     <quote><p>
 | |
|       Write &s.code;value&e.code; to the DAC Mask register.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;CARD8 readDacMask(vgaHWptr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       Return the value read from the DAC Mask register.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void writeDacReadAddress(vgaHWPtr hwp, CARD8 value)&e.code;
 | |
|     <quote><p>
 | |
|       Write &s.code;value&e.code; to the DAC Read Address register.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void writeDacWriteAddress(vgaHWPtr hwp, CARD8 value)&e.code;
 | |
|     <quote><p>
 | |
|       Write &s.code;value&e.code; to the DAC Write Address register.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void writeDacData(vgaHWPtr hwp, CARD8 value)&e.code;
 | |
|     <quote><p>
 | |
|       Write &s.code;value&e.code; to the DAC Data register.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;CARD8 readDacData(vgaHWptr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       Return the value read from the DAC Data register.
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;CARD8 readEnable(vgaHWptr hwp)&e.code;
 | |
|     <quote><p>
 | |
|       Return the value read from the VGA Enable register.  (Note: This
 | |
|       function is present in XFree86 4.1.0 and later.)
 | |
| 
 | |
|     </quote>
 | |
| 
 | |
|     &s.code;void writeEnable(vgaHWPtr hwp, CARD8 value)&e.code;
 | |
|     <quote><p>
 | |
|       Write &s.code;value&e.code; to the VGA Enable register.  (Note: This
 | |
|       function is present in XFree86 4.1.0 and later.)
 | |
| 
 | |
|     </quote>
 | |
|   </quote>
 | |
| 
 | |
| <sect>Some notes about writing a driver<label id="sample">
 | |
| <p>
 | |
| 
 | |
| <em>NOTE: some parts of this are not up to date</em>
 | |
| 
 | |
| The following is an outline for writing a basic unaccelerated driver
 | |
| for a PCI video card with a linear mapped framebuffer, and which has a
 | |
| VGA core.  It is includes some general information that is relevant to
 | |
| most drivers (even those which don't fit that basic description).
 | |
| 
 | |
| The information here is based on the initial conversion of the Matrox
 | |
| Millennium driver to the ``new design''.  For a fleshing out and sample
 | |
| implementation of some of the bits outlined here, refer to that driver.
 | |
| Note that this is an example only.  The approach used here will not be
 | |
| appropriate for all drivers.
 | |
| 
 | |
| Each driver must reserve a unique driver name, and a string that is used
 | |
| to prefix all of its externally visible symbols.  This is to avoid name
 | |
| space clashes when loading multiple drivers.  The examples here are for
 | |
| the ``ZZZ'' driver, which uses the ``ZZZ'' or ``zzz'' prefix for its externally
 | |
| visible symbols.
 | |
| 
 | |
| 
 | |
| <sect1>Include files
 | |
| <p>
 | |
| 
 | |
|   All drivers normally include the following headers:
 | |
|   <quote>
 | |
|     &s.code;"xf86.h"&nl;
 | |
|     "xf86_OSproc.h"&nl;
 | |
|     "xf86_ansic.h"&nl;
 | |
|     "xf86Resources.h"&e.code;
 | |
|   </quote>
 | |
|   Wherever inb/outb (and related things) are used the following should be
 | |
|   included:
 | |
|   <quote>
 | |
|     &s.code;"compiler.h"&e.code;
 | |
|   </quote>
 | |
|   Note: in drivers, this must be included after &s.code;"xf86_ansic.h"&e.code;.
 | |
| 
 | |
|   Drivers that need to access PCI vendor/device definitions need this:
 | |
|   <quote>
 | |
|     &s.code;"xf86PciInfo.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers that need to access the PCI config space need this:
 | |
|   <quote>
 | |
|     &s.code;"xf86Pci.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers using the mi banking wrapper need:
 | |
| 
 | |
|   <quote>
 | |
|     &s.code;"mibank.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers that initialise a SW cursor need this:
 | |
|   <quote>
 | |
|     &s.code;"mipointer.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   All drivers implementing backing store need this:
 | |
|   <quote>
 | |
|     &s.code;"mibstore.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   All drivers using the mi colourmap code need this:
 | |
|   <quote>
 | |
|     &s.code;"micmap.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   If a driver uses the vgahw module, it needs this:
 | |
|   <quote>
 | |
|     &s.code;"vgaHW.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers supporting VGA or Hercules monochrome screens need:
 | |
|   <quote>
 | |
|     &s.code;"xf1bpp.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers supporting VGA or EGC 16-colour screens need:
 | |
|   <quote>
 | |
|     &s.code;"xf4bpp.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers using cfb need:
 | |
|   <quote>
 | |
|     &s.code;#define PSZ 8&nl;
 | |
|     #include "cfb.h"&nl;
 | |
|     #undef PSZ&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
 | |
|   <quote>
 | |
|     &s.code;"cfb16.h"&nl;
 | |
|     "cfb24.h"&nl;
 | |
|     "cfb32.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   The driver's own header file:
 | |
|   <quote>
 | |
|     &s.code;"zzz.h"&e.code;
 | |
|   </quote>
 | |
| 
 | |
|   Drivers must NOT include the following:
 | |
| 
 | |
|  <quote>
 | |
|     &s.code;"xf86Priv.h"&nl;
 | |
|     "xf86Privstr.h"&nl;
 | |
|     "xf86_libc.h"&nl;
 | |
|     "xf86_OSlib.h"&nl;
 | |
|     "Xos.h"&e.code;&nl;
 | |
|     any OS header
 | |
|  </quote>
 | |
| 
 | |
| 
 | |
| <sect1>Data structures and initialisation
 | |
| <p>
 | |
| 
 | |
| <itemize>
 | |
|   <item>The following macros should be defined:
 | |
|     <code>
 | |
| #define VERSION <version-as-an-int>
 | |
| #define ZZZ_NAME "ZZZ"         /* the name used to prefix messages */
 | |
| #define ZZZ_DRIVER_NAME "zzz"  /* the driver name as used in config file */
 | |
| #define ZZZ_MAJOR_VERSION <int>
 | |
| #define ZZZ_MINOR_VERSION <int>
 | |
| #define ZZZ_PATCHLEVEL    <int>
 | |
|     </code>
 | |
| <p>
 | |
|     NOTE: &s.code;ZZZ_DRIVER_NAME&e.code; should match the name of the
 | |
|     driver module without things like the "lib" prefix, the "_drv" suffix
 | |
|     or filename extensions.
 | |
| <p>
 | |
| 
 | |
|   <item>A DriverRec must be defined, which includes the functions required
 | |
|     at the pre-probe phase.  The name of this DriverRec must be an
 | |
|     upper-case version of ZZZ_DRIVER_NAME (for the purposes of static
 | |
|     linking).
 | |
| <p>
 | |
|     <code>
 | |
| DriverRec ZZZ = {
 | |
|     VERSION,
 | |
|     ZZZ_DRIVER_NAME,
 | |
|     ZZZIdentify,
 | |
|     ZZZProbe,
 | |
|     ZZZAvailableOptions,
 | |
|     NULL,
 | |
|     0
 | |
| };
 | |
|     </code>
 | |
| 
 | |
|   <item>Define list of supported chips and their matching ID:
 | |
| <p>
 | |
|     <code>
 | |
| static SymTabRec ZZZChipsets[] = {
 | |
|     { PCI_CHIP_ZZZ1234, "zzz1234a" },
 | |
|     { PCI_CHIP_ZZZ5678, "zzz5678a" },
 | |
|     { -1,               NULL }
 | |
| };
 | |
|     </code>
 | |
| <p>
 | |
|     The token field may be any integer value that the driver may use to
 | |
|     uniquely identify the supported chipsets.  For drivers that support
 | |
|     only PCI devices using the PCI device IDs might be a natural choice,
 | |
|     but this isn't mandatory.  For drivers that support both PCI and other
 | |
|     devices (like ISA), some other ID should probably used.  When other
 | |
|     IDs are used as the tokens it is recommended that the names be
 | |
|     defined as an &s.code;enum&e.code; type.
 | |
| <p>
 | |
|   <item>If the driver uses the &s.code;xf86MatchPciInstances(&e.code;)
 | |
|     helper (recommended for drivers that support PCI cards) a list that
 | |
|     maps PCI IDs to chip IDs and fixed resources must be defined:
 | |
| <p>
 | |
|     <code>
 | |
| static PciChipsets ZZZPciChipsets[] = {
 | |
|     { PCI_CHIP_ZZZ1234, PCI_CHIP_ZZZ1234, RES_SHARED_VGA },
 | |
|     { PCI_CHIP_ZZZ5678, PCI_CHIP_ZZZ5678, RES_SHARED_VGA },
 | |
|     { -1,               -1,               RES_UNDEFINED }
 | |
| }
 | |
|     </code>
 | |
| <p>
 | |
|   <item>Define the &s.code;XF86ModuleVersionInfo&e.code; struct for the
 | |
|     driver.  This is required for the dynamically loaded version:
 | |
| <p>
 | |
|     <code>
 | |
| static XF86ModuleVersionInfo zzzVersRec =
 | |
| {
 | |
|     "zzz",
 | |
|     MODULEVENDORSTRING,
 | |
|     MODINFOSTRING1,
 | |
|     MODINFOSTRING2,
 | |
|     XF86_VERSION_CURRENT,
 | |
|     ZZZ_MAJOR_VERSION, ZZZ_MINOR_VERSION, ZZZ_PATCHLEVEL,
 | |
|     ABI_CLASS_VIDEODRV,
 | |
|     ABI_VIDEODRV_VERSION,
 | |
|     MOD_CLASS_VIDEODRV,
 | |
|     {0,0,0,0}
 | |
| };
 | |
|     </code>
 | |
| <p>
 | |
|   <item>Define a data structure to hold the driver's screen-specific data.
 | |
|     This must be used instead of global variables.  This would be defined
 | |
|     in the &s.code;"zzz.h"&e.code; file, something like:
 | |
| <p>
 | |
|     <code>
 | |
| typedef struct {
 | |
|     type1  field1;
 | |
|     type2  field2;
 | |
|     int    fooHack;
 | |
|     Bool   pciRetry;
 | |
|     Bool   noAccel;
 | |
|     Bool   hwCursor;
 | |
|     CloseScreenProcPtr CloseScreen;
 | |
|     OptionInfoPtr Options;
 | |
|     ...
 | |
| } ZZZRec, *ZZZPtr;
 | |
|     </code>
 | |
| <p>
 | |
|   <item>Define the list of config file Options that the driver accepts.  For
 | |
|     consistency between drivers those in the list of ``standard'' options
 | |
|     should be used where appropriate before inventing new options.
 | |
| <p>
 | |
|     <code>
 | |
| typedef enum {
 | |
|     OPTION_FOO_HACK,
 | |
|     OPTION_PCI_RETRY,
 | |
|     OPTION_HW_CURSOR,
 | |
|     OPTION_NOACCEL
 | |
| } ZZZOpts;
 | |
| 
 | |
| static const OptionInfoRec ZZZOptions[] = {
 | |
|   { OPTION_FOO_HACK,  "FooHack",   OPTV_INTEGER, {0}, FALSE },
 | |
|   { OPTION_PCI_RETRY, "PciRetry",  OPTV_BOOLEAN, {0}, FALSE },
 | |
|   { OPTION_HW_CURSOR, "HWcursor",  OPTV_BOOLEAN, {0}, FALSE },
 | |
|   { OPTION_NOACCEL,   "NoAccel",   OPTV_BOOLEAN, {0}, FALSE },
 | |
|   { -1,               NULL,        OPTV_NONE,    {0}, FALSE }
 | |
| };
 | |
|     </code>
 | |
| <p>
 | |
| </itemize>
 | |
| 
 | |
| <sect1>Functions
 | |
| <p>
 | |
| 
 | |
| 
 | |
| <sect2>SetupProc
 | |
| <p>
 | |
| 
 | |
|     For dynamically loaded modules, a &s.code;ModuleData&e.code;
 | |
|     variable is required.  It is should be the name of the driver
 | |
|     prepended to "ModuleData".  A &s.code;Setup()&e.code; function is
 | |
|     also required, which calls &s.code;xf86AddDriver()&e.code; to add
 | |
|     the driver to the main list of drivers.
 | |
| 
 | |
|     <code>
 | |
| static MODULESETUPPROTO(zzzSetup);
 | |
| 
 | |
| XF86ModuleData zzzModuleData = { &zzzVersRec, zzzSetup, NULL };
 | |
| 
 | |
| static pointer
 | |
| zzzSetup(pointer module, pointer opts, int *errmaj, int *errmin)
 | |
| {
 | |
|     static Bool setupDone = FALSE;
 | |
| 
 | |
|     /* This module should be loaded only once, but check to be sure. */
 | |
| 
 | |
|     if (!setupDone) {
 | |
|         /*
 | |
|          * Modules that this driver always requires may be loaded
 | |
|          * here  by calling LoadSubModule().
 | |
|          */
 | |
| 
 | |
|         setupDone = TRUE;
 | |
|         xf86AddDriver(&MGA, module, 0);
 | |
| 
 | |
|         /*
 | |
|          * The return value must be non-NULL on success even though
 | |
|          * there is no TearDownProc.
 | |
|          */
 | |
|         return (pointer)1;
 | |
|     } else {
 | |
|         if (errmaj) *errmaj = LDR_ONCEONLY;
 | |
|         return NULL;
 | |
|     }
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| <sect2>GetRec, FreeRec
 | |
| <p>
 | |
| 
 | |
|     A function is usually required to allocate the driver's
 | |
|     screen-specific data structure and hook it into the
 | |
|     &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field.
 | |
|     The &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; is
 | |
|     initialised to &s.code;NULL&e.code;, so it is easy to check if the
 | |
|     initialisation has already been done.  After allocating it, initialise
 | |
|     the fields.  By using &s.code;xnfcalloc()&e.code; to do the allocation
 | |
|     it is zeroed, and if the allocation fails the server exits.
 | |
| <p>
 | |
|     NOTE:
 | |
|     When allocating structures from inside the driver which are defined
 | |
|     on the common level it is important to initialize the structure to
 | |
|     zero.
 | |
|     Only this guarantees that the server remains source compatible to
 | |
|     future changes in common level structures.
 | |
| 
 | |
|     <code>
 | |
| static Bool
 | |
| ZZZGetRec(ScrnInfoPtr pScrn)
 | |
| {
 | |
|     if (pScrn->driverPrivate != NULL)
 | |
|         return TRUE;
 | |
|     pScrn->driverPrivate = xnfcalloc(sizeof(ZZZRec), 1);
 | |
|     /* Initialise as required */
 | |
|     ...
 | |
|     return TRUE;
 | |
| }
 | |
|     </code>
 | |
| 
 | |
|     Define a macro in &s.code;"zzz.h"&e.code; which gets a pointer to
 | |
|     the &s.code;ZZZRec&e.code; when given &s.code;pScrn&e.code;:
 | |
| 
 | |
|     <code>
 | |
| #define ZZZPTR(p) ((ZZZPtr)((p)->driverPrivate))
 | |
|     </code>
 | |
| 
 | |
|     Define a function to free the above, setting it to &s.code;NULL&e.code;
 | |
|     once it has been freed:
 | |
| 
 | |
|     <code>
 | |
| static void
 | |
| ZZZFreeRec(ScrnInfoPtr pScrn)
 | |
| {
 | |
|     if (pScrn->driverPrivate == NULL)
 | |
|         return;
 | |
|     xfree(pScrn->driverPrivate);
 | |
|     pScrn->driverPrivate = NULL;
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| <sect2>Identify
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;Identify()&e.code; function.  It is run before
 | |
|     the Probe, and typically prints out an identifying message, which
 | |
|     might include the chipsets it supports.  This function is mandatory:
 | |
| 
 | |
|     <code>
 | |
| static void
 | |
| ZZZIdentify(int flags)
 | |
| {
 | |
|     xf86PrintChipsets(ZZZ_NAME, "driver for ZZZ Tech chipsets",
 | |
|                       ZZZChipsets);
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| <sect2>Probe
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;Probe()&e.code; function.  The purpose of this
 | |
|     is to find all instances of the hardware that the driver supports,
 | |
|     and for the ones not already claimed by another driver, claim the
 | |
|     slot, and allocate a &s.code;ScrnInfoRec&e.code;.  This should be
 | |
|     a minimal probe, and it should under no circumstances leave the
 | |
|     state of the hardware changed.  Because a device is found, don't
 | |
|     assume that it will be used.  Don't do any initialisations other
 | |
|     than the required &s.code;ScrnInfoRec&e.code; initialisations.
 | |
|     Don't allocate any new data structures.
 | |
| 
 | |
|     This function is mandatory.
 | |
| 
 | |
|     NOTE: The &s.code;xf86DrvMsg()&e.code; functions cannot be used from
 | |
|     the Probe.
 | |
| 
 | |
|     <code>
 | |
| static Bool
 | |
| ZZZProbe(DriverPtr drv, int flags)
 | |
| {
 | |
|     Bool foundScreen = FALSE;
 | |
|     int numDevSections, numUsed;
 | |
|     GDevPtr *devSections;
 | |
|     int *usedChips;
 | |
|     int i;
 | |
| 
 | |
|     /*
 | |
|      * Find the config file Device sections that match this
 | |
|      * driver, and return if there are none.
 | |
|      */
 | |
|     if ((numDevSections = xf86MatchDevice(ZZZ_DRIVER_NAME,
 | |
|                                           &devSections)) <= 0) {
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Since this is a PCI card, "probing" just amounts to checking
 | |
|      * the PCI data that the server has already collected.  If there
 | |
|      * is none, return.
 | |
|      *
 | |
|      * Although the config file is allowed to override things, it
 | |
|      * is reasonable to not allow it to override the detection
 | |
|      * of no PCI video cards.
 | |
|      *
 | |
|      * The provided xf86MatchPciInstances() helper takes care of
 | |
|      * the details.
 | |
|      */
 | |
|     /* test if PCI bus present */
 | |
|     if (xf86GetPciVideoInfo()) {
 | |
| 
 | |
|         numUsed = xf86MatchPciInstances(ZZZ_NAME, PCI_VENDOR_ZZZ,
 | |
|                             ZZZChipsets, ZZZPciChipsets, devSections,
 | |
|                             numDevSections, drv, &usedChips);
 | |
| 
 | |
|         for (i = 0; i < numUsed; i++) {
 | |
|             ScrnInfoPtr pScrn = NULL;
 | |
|             if ((pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
 | |
|                                              ZZZPciChipsets, NULL, NULL,
 | |
|                                              NULL, NULL, NULL))) {
 | |
|                /* Allocate a ScrnInfoRec */
 | |
|                pScrn->driverVersion = VERSION;
 | |
|                pScrn->driverName    = ZZZ_DRIVER_NAME;
 | |
|                pScrn->name          = ZZZ_NAME;
 | |
|                pScrn->Probe         = ZZZProbe;
 | |
|                pScrn->PreInit       = ZZZPreInit;
 | |
|                pScrn->ScreenInit    = ZZZScreenInit;
 | |
|                pScrn->SwitchMode    = ZZZSwitchMode;
 | |
|                pScrn->AdjustFrame   = ZZZAdjustFrame;
 | |
|                pScrn->EnterVT       = ZZZEnterVT;
 | |
|                pScrn->LeaveVT       = ZZZLeaveVT;
 | |
|                pScrn->FreeScreen    = ZZZFreeScreen;
 | |
|                pScrn->ValidMode     = ZZZValidMode;
 | |
|                foundScreen = TRUE;
 | |
|                /* add screen to entity */
 | |
|            }
 | |
|         }
 | |
|         xfree(usedChips);
 | |
|     }
 | |
| 
 | |
| #ifdef HAS_ISA_DEVS
 | |
|     /*
 | |
|      * If the driver supports ISA hardware, the following block
 | |
|      * can be included too.
 | |
|      */
 | |
|     numUsed = xf86MatchIsaInstances(ZZZ_NAME, ZZZChipsets,
 | |
|                              ZZZIsaChipsets, drv, ZZZFindIsaDevice,
 | |
|                              devSections, numDevSections, &usedChips);
 | |
|     for (i = 0; i < numUsed; i++) {
 | |
|         ScrnInfoPtr pScrn = NULL;
 | |
| 	if ((pScrn = xf86ConfigIsaEntity(pScrn, flags, usedChips[i],
 | |
| 					 ZZZIsaChipsets, NULL, NULL, NULL,
 | |
| 					 NULL, NULL))) {
 | |
|             pScrn->driverVersion = VERSION;
 | |
|             pScrn->driverName    = ZZZ_DRIVER_NAME;
 | |
|             pScrn->name          = ZZZ_NAME;
 | |
|             pScrn->Probe         = ZZZProbe;
 | |
|             pScrn->PreInit       = ZZZPreInit;
 | |
|             pScrn->ScreenInit    = ZZZScreenInit;
 | |
|             pScrn->SwitchMode    = ZZZSwitchMode;
 | |
|             pScrn->AdjustFrame   = ZZZAdjustFrame;
 | |
|             pScrn->EnterVT       = ZZZEnterVT;
 | |
|             pScrn->LeaveVT       = ZZZLeaveVT;
 | |
|             pScrn->FreeScreen    = ZZZFreeScreen;
 | |
|             pScrn->ValidMode     = ZZZValidMode;
 | |
|             foundScreen = TRUE;
 | |
|         }
 | |
|     }
 | |
|     xfree(usedChips);
 | |
| #endif /* HAS_ISA_DEVS */
 | |
| 
 | |
|     xfree(devSections);
 | |
|     return foundScreen;
 | |
|     </code>
 | |
| 
 | |
| <sect2>AvailableOptions
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;AvailableOptions()&e.code; function. The purpose
 | |
|     of this is to return the available driver options back to the
 | |
|     -configure option, so that an xorg.conf file can be built and the
 | |
|     user can see which options are available for them to use.
 | |
| 
 | |
| <sect2>PreInit
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;PreInit()&e.code; function.  The purpose of
 | |
|     this is to find all the information required to determine if the
 | |
|     configuration is usable, and to initialise those parts of the
 | |
|     &s.code;ScrnInfoRec&e.code; that can be set once at the beginning
 | |
|     of the first server generation.  The information should be found in
 | |
|     the least intrusive way possible.
 | |
| 
 | |
|     This function is mandatory.
 | |
| 
 | |
|     NOTES:
 | |
|     <enum>
 | |
|       <item>The &s.code;PreInit()&e.code; function is only called once
 | |
| 	 during the life of the X server (at the start of the first
 | |
| 	 generation).
 | |
| 
 | |
|       <item>Data allocated here must be of the type that persists for
 | |
| 	 the life of the X server.  This means that data that hooks into
 | |
| 	 the &s.code;ScrnInfoRec&e.code;'s &s.code;privates&e.code;
 | |
| 	 field should be allocated here, but data that hooks into the
 | |
| 	 &s.code;ScreenRec&e.code;'s &s.code;devPrivates&e.code; field
 | |
| 	 should not be allocated here.  The &s.code;driverPrivate&e.code;
 | |
| 	 field should also be allocated here.
 | |
| 
 | |
|       <item>Although the &s.code;ScrnInfoRec&e.code; has been allocated
 | |
| 	 before this function is called, the &s.code;ScreenRec&e.code;
 | |
| 	 has not been allocated.  That means that things requiring it
 | |
| 	 cannot be used in this function.
 | |
| 
 | |
|       <item>Very little of the &s.code;ScrnInfoRec&e.code; has been
 | |
| 	 initialised when this function is called.  It is important to
 | |
| 	 get the order of doing things right in this function.
 | |
| 
 | |
|     </enum>
 | |
| 
 | |
|     <code>
 | |
| static Bool
 | |
| ZZZPreInit(ScrnInfoPtr pScrn, int flags)
 | |
| {
 | |
|     /* Fill in the monitor field */
 | |
|     pScrn->monitor = pScrn->confScreen->monitor;
 | |
| 
 | |
|     /*
 | |
|      * If using the vgahw module, it will typically be loaded
 | |
|      * here by calling xf86LoadSubModule(pScrn, "vgahw");
 | |
|      */
 | |
| 
 | |
|     /*
 | |
|      * Set the depth/bpp.  Use the globally preferred depth/bpp.  If the
 | |
|      * driver has special default depth/bpp requirements, the defaults should
 | |
|      * be specified here explicitly.
 | |
|      * We support both 24bpp and 32bpp framebuffer layouts.
 | |
|      * This sets pScrn->display also.
 | |
|      */
 | |
|     if (!xf86SetDepthBpp(pScrn, 0, 0, 0,
 | |
|                          Support24bppFb | Support32bppFb)) {
 | |
|         return FALSE;
 | |
|     } else {
 | |
|         if (depth/bpp isn't one we support) {
 | |
|             print error message;
 | |
|             return FALSE;
 | |
|         }
 | |
|     }
 | |
|     /* Print out the depth/bpp that was set */
 | |
|     xf86PrintDepthBpp(pScrn);
 | |
| 
 | |
|     /* Set bits per RGB for 8bpp */
 | |
|     if (pScrn->depth <= 8) {
 | |
|         /* Take into account a dac_6_bit option here */
 | |
|         pScrn->rgbBits = 6 or 8;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * xf86SetWeight() and xf86SetDefaultVisual() must be called
 | |
|      * after pScrn->display is initialised.
 | |
|      */
 | |
| 
 | |
|     /* Set weight/mask/offset for depth > 8 */
 | |
|     if (pScrn->depth > 8) {
 | |
|         if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
 | |
|             return FALSE;
 | |
|         } else {
 | |
|             if (weight isn't one we support) {
 | |
|                 print error message;
 | |
|                 return FALSE;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* Set the default visual. */
 | |
|     if (!xf86SetDefaultVisual(pScrn, -1)) {
 | |
|         return FALSE;
 | |
|     } else {
 | |
|         if (visual isn't one we support) {
 | |
|             print error message;
 | |
|             return FALSE;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* If the driver supports gamma correction, set the gamma. */
 | |
|     if (!xf86SetGamma(pScrn, default_gamma)) {
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     /* This driver uses a programmable clock */
 | |
|     pScrn->progClock = TRUE;
 | |
| 
 | |
|     /* Allocate the ZZZRec driverPrivate */
 | |
|     if (!ZZZGetRec(pScrn)) {
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     pZzz = ZZZPTR(pScrn);
 | |
| 
 | |
|     /* Collect all of the option flags (fill in pScrn->options) */
 | |
|     xf86CollectOptions(pScrn, NULL);
 | |
| 
 | |
|     /*
 | |
|      * Process the options based on the information in ZZZOptions.
 | |
|      * The results are written to pZzz->Options.  If all of the options
 | |
|      * processing is done within this function a local variable "options"
 | |
|      * can be used instead of pZzz->Options.
 | |
|      */
 | |
|     if (!(pZzz->Options = xalloc(sizeof(ZZZOptions))))
 | |
|         return FALSE;
 | |
|     (void)memcpy(pZzz->Options, ZZZOptions, sizeof(ZZZOptions));
 | |
|     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pZzz->Options);
 | |
| 
 | |
|     /*
 | |
|      * Set various fields of ScrnInfoRec and/or ZZZRec based on
 | |
|      * the options found.
 | |
|      */
 | |
|     from = X_DEFAULT;
 | |
|     pZzz->hwCursor = FALSE;
 | |
|     if (xf86IsOptionSet(pZzz->Options, OPTION_HW_CURSOR)) {
 | |
|         from = X_CONFIG;
 | |
|         pZzz->hwCursor = TRUE;
 | |
|     }
 | |
|     xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
 | |
|                pZzz->hwCursor ? "HW" : "SW");
 | |
|     if (xf86IsOptionSet(pZzz->Options, OPTION_NOACCEL)) {
 | |
|         pZzz->noAccel = TRUE;
 | |
|         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
 | |
|                    "Acceleration disabled\n");
 | |
|     } else {
 | |
|         pZzz->noAccel = FALSE;
 | |
|     }
 | |
|     if (xf86IsOptionSet(pZzz->Options, OPTION_PCI_RETRY)) {
 | |
|         pZzz->UsePCIRetry = TRUE;
 | |
|         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
 | |
|     }
 | |
|     pZzz->fooHack = 0;
 | |
|     if (xf86GetOptValInteger(pZzz->Options, OPTION_FOO_HACK,
 | |
|                              &pZzz->fooHack)) {
 | |
|         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Foo Hack set to %d\n",
 | |
|                    pZzz->fooHack);
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Find the PCI slot(s) that this screen claimed in the probe.
 | |
|      * In this case, exactly one is expected, so complain otherwise.
 | |
|      * Note in this case we're not interested in the card types so
 | |
|      * that parameter is set to NULL.
 | |
|      */
 | |
|     if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL))
 | |
|         != 1) {
 | |
|         print error message;
 | |
|         ZZZFreeRec(pScrn);
 | |
|         if (i > 0)
 | |
|             xfree(pciList);
 | |
|         return FALSE;
 | |
|     }
 | |
|     /* Note that pciList should be freed below when no longer needed */
 | |
| 
 | |
|     /*
 | |
|      * Determine the chipset, allowing config file chipset and
 | |
|      * chipid values to override the probed information.  The config
 | |
|      * chipset value has precedence over its chipid value if both
 | |
|      * are present.
 | |
|      *
 | |
|      * It isn't necessary to fill in pScrn->chipset if the driver
 | |
|      * keeps track of the chipset in its ZZZRec.
 | |
|      */
 | |
| 
 | |
|     ...
 | |
| 
 | |
|     /*
 | |
|      * Determine video memory, fb base address, I/O addresses, etc,
 | |
|      * allowing the config file to override probed values.
 | |
|      *
 | |
|      * Set the appropriate pScrn fields (videoRam is probably the
 | |
|      * most important one that other code might require), and
 | |
|      * print out the settings.
 | |
|      */
 | |
| 
 | |
|     ...
 | |
| 
 | |
|     /* Initialise a clockRanges list. */
 | |
| 
 | |
|     ...
 | |
| 
 | |
|     /* Set any other chipset specific things in the ZZZRec */
 | |
| 
 | |
|     ...
 | |
| 
 | |
|     /* Select valid modes from those available */
 | |
| 
 | |
|     i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
 | |
|                           pScrn->display->modes, clockRanges,
 | |
|                           NULL, minPitch, maxPitch, rounding,
 | |
|                           minHeight, maxHeight,
 | |
|                           pScrn->display->virtualX,
 | |
|                           pScrn->display->virtualY,
 | |
|                           pScrn->videoRam * 1024,
 | |
|                           LOOKUP_BEST_REFRESH);
 | |
|     if (i == -1) {
 | |
|         ZZZFreeRec(pScrn);
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     /* Prune the modes marked as invalid */
 | |
| 
 | |
|     xf86PruneDriverModes(pScrn);
 | |
| 
 | |
|     /* If no valid modes, return */
 | |
| 
 | |
|     if (i == 0 || pScrn->modes == NULL) {
 | |
|         print error message;
 | |
|         ZZZFreeRec(pScrn);
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Initialise the CRTC fields for the modes.  This driver expects
 | |
|      * vertical values to be halved for interlaced modes.
 | |
|      */
 | |
|     xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
 | |
| 
 | |
|     /* Set the current mode to the first in the list. */
 | |
|     pScrn->currentMode = pScrn->modes;
 | |
| 
 | |
|     /* Print the list of modes being used. */
 | |
|     xf86PrintModes(pScrn);
 | |
| 
 | |
|     /* Set the DPI */
 | |
|     xf86SetDpi(pScrn, 0, 0);
 | |
| 
 | |
|     /* Load bpp-specific modules */
 | |
|     switch (pScrn->bitsPerPixel) {
 | |
|     case 1:
 | |
|         mod = "xf1bpp";
 | |
|         break;
 | |
|     case 4:
 | |
|         mod = "xf4bpp";
 | |
|         break;
 | |
|     case 8:
 | |
|         mod = "cfb";
 | |
|         break;
 | |
|     case 16:
 | |
|         mod = "cfb16";
 | |
|         break;
 | |
|     case 24:
 | |
|         mod = "cfb24";
 | |
|         break;
 | |
|     case 32:
 | |
|         mod = "cfb32";
 | |
|         break;
 | |
|     }
 | |
|     if (mod && !xf86LoadSubModule(pScrn, mod))
 | |
|         ZZZFreeRec(pScrn);
 | |
|         return FALSE;
 | |
| 
 | |
|     /* Load XAA if needed */
 | |
|     if (!pZzz->noAccel || pZzz->hwCursor)
 | |
|         if (!xf86LoadSubModule(pScrn, "xaa")) {
 | |
|             ZZZFreeRec(pScrn);
 | |
|             return FALSE;
 | |
|         }
 | |
| 
 | |
|     /* Done */
 | |
|     return TRUE;
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| <sect2>MapMem, UnmapMem
 | |
| <p>
 | |
| 
 | |
|     Define functions to map and unmap the video memory and any other
 | |
|     memory apertures required.  These functions are not mandatory, but
 | |
|     it is often useful to have such functions.
 | |
| 
 | |
|     <code>
 | |
| static Bool
 | |
| ZZZMapMem(ScrnInfoPtr pScrn)
 | |
| {
 | |
|     /* Call xf86MapPciMem() to map each PCI memory area */
 | |
|     ...
 | |
|     return TRUE or FALSE;
 | |
| }
 | |
| 
 | |
| static Bool
 | |
| ZZZUnmapMem(ScrnInfoPtr pScrn)
 | |
| {
 | |
|     /* Call xf86UnMapVidMem() to unmap each memory area */
 | |
|     ...
 | |
|     return TRUE or FALSE;
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| <sect2>Save, Restore
 | |
| <p>
 | |
| 
 | |
|     Define functions to save and restore the original video state.  These
 | |
|     functions are not mandatory, but are often useful.
 | |
| 
 | |
|     <code>
 | |
| static void
 | |
| ZZZSave(ScrnInfoPtr pScrn)
 | |
| {
 | |
|     /*
 | |
|      * Save state into per-screen data structures.
 | |
|      * If using the vgahw module, vgaHWSave will typically be
 | |
|      * called here.
 | |
|      */
 | |
|     ...
 | |
| }
 | |
| 
 | |
| static void
 | |
| ZZZRestore(ScrnInfoPtr pScrn)
 | |
| {
 | |
|     /*
 | |
|      * Restore state from per-screen data structures.
 | |
|      * If using the vgahw module, vgaHWRestore will typically be
 | |
|      * called here.
 | |
|      */
 | |
|     ...
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| <sect2>ModeInit
 | |
| <p>
 | |
| 
 | |
|     Define a function to initialise a new video mode.  This function isn't
 | |
|     mandatory, but is often useful.
 | |
| 
 | |
|     <code>
 | |
| static Bool
 | |
| ZZZModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
 | |
| {
 | |
|     /*
 | |
|      * Program a video mode.  If using the vgahw module,
 | |
|      * vgaHWInit and vgaRestore will typically be called here.
 | |
|      * Once up to the point where there can't be a failure
 | |
|      * set pScrn->vtSema to TRUE.
 | |
|      */
 | |
|     ...
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| <sect2>ScreenInit
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;ScreenInit()&e.code; function.  This is called
 | |
|     at the start of each server generation, and should fill in as much
 | |
|     of the &s.code;ScreenRec&e.code; as possible as well as any other
 | |
|     data that is initialised once per generation.  It should initialise
 | |
|     the framebuffer layers it is using, and initialise the initial video
 | |
|     mode.
 | |
| 
 | |
|     This function is mandatory.
 | |
| 
 | |
|     NOTE: The &s.code;ScreenRec&e.code; (&s.code;pScreen&e.code;) is
 | |
| 	  passed to this driver, but it and the
 | |
| 	  &s.code;ScrnInfoRecs&e.code; are not yet hooked into each
 | |
| 	  other.  This means that in this function, and functions it
 | |
| 	  calls, one cannot be found from the other.
 | |
| 
 | |
|     <code>
 | |
| static Bool
 | |
| ZZZScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 | |
| {
 | |
|     /* Get the ScrnInfoRec */
 | |
|     pScrn = xf86Screens[pScreen->myNum];
 | |
| 
 | |
|     /*
 | |
|      * If using the vgahw module, its data structures and related
 | |
|      * things are typically initialised/mapped here.
 | |
|      */
 | |
| 
 | |
|     /* Save the current video state */
 | |
|     ZZZSave(pScrn);
 | |
| 
 | |
|     /* Initialise the first mode */
 | |
|     ZZZModeInit(pScrn, pScrn->currentMode);
 | |
| 
 | |
|     /* Set the viewport if supported */
 | |
| 
 | |
|     ZZZAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 | |
| 
 | |
|     /*
 | |
|      * Setup the screen's visuals, and initialise the framebuffer
 | |
|      * code.
 | |
|      */
 | |
| 
 | |
|     /* Reset the visual list */
 | |
|     miClearVisualTypes();
 | |
| 
 | |
|     /*
 | |
|      * Setup the visuals supported.  This driver only supports
 | |
|      * TrueColor for bpp > 8, so the default set of visuals isn't
 | |
|      * acceptable.  To deal with this, call miSetVisualTypes with
 | |
|      * the appropriate visual mask.
 | |
|      */
 | |
| 
 | |
|     if (pScrn->bitsPerPixel > 8) {
 | |
|         if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
 | |
|                               pScrn->rgbBits, pScrn->defaultVisual))
 | |
|             return FALSE;
 | |
|     } else {
 | |
|         if (!miSetVisualTypes(pScrn->depth,
 | |
|                               miGetDefaultVisualMask(pScrn->depth),
 | |
|                               pScrn->rgbBits, pScrn->defaultVisual))
 | |
|             return FALSE;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Initialise the framebuffer.
 | |
|      */
 | |
| 
 | |
|     switch (pScrn->bitsPerPixel) {
 | |
|     case 1:
 | |
|         ret = xf1bppScreenInit(pScreen, FbBase,
 | |
|                                pScrn->virtualX, pScrn->virtualY,
 | |
|                                pScrn->xDpi, pScrn->yDpi,
 | |
|                                pScrn->displayWidth);
 | |
|         break;
 | |
|     case 4:
 | |
|         ret = xf4bppScreenInit(pScreen, FbBase,
 | |
|                                pScrn->virtualX, pScrn->virtualY,
 | |
|                                pScrn->xDpi, pScrn->yDpi,
 | |
|                                pScrn->displayWidth);
 | |
|         break;
 | |
|     case 8:
 | |
|         ret = cfbScreenInit(pScreen, FbBase,
 | |
|                             pScrn->virtualX, pScrn->virtualY,
 | |
|                             pScrn->xDpi, pScrn->yDpi,
 | |
|                             pScrn->displayWidth);
 | |
|         break;
 | |
|     case 16:
 | |
|         ret = cfb16ScreenInit(pScreen, FbBase,
 | |
|                               pScrn->virtualX, pScrn->virtualY,
 | |
|                               pScrn->xDpi, pScrn->yDpi,
 | |
|                               pScrn->displayWidth);
 | |
|         break;
 | |
|     case 24:
 | |
|         ret = cfb24ScreenInit(pScreen, FbBase,
 | |
|                               pScrn->virtualX, pScrn->virtualY,
 | |
|                               pScrn->xDpi, pScrn->yDpi,
 | |
|                               pScrn->displayWidth);
 | |
|         break;
 | |
|     case 32:
 | |
|         ret = cfb32ScreenInit(pScreen, FbBase,
 | |
|                               pScrn->virtualX, pScrn->virtualY,
 | |
|                               pScrn->xDpi, pScrn->yDpi,
 | |
|                               pScrn->displayWidth);
 | |
|         break;
 | |
|     default:
 | |
|         print a message about an internal error;
 | |
|         ret = FALSE;
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     if (!ret)
 | |
|         return FALSE;
 | |
| 
 | |
|     /* Override the default mask/offset settings */
 | |
|     if (pScrn->bitsPerPixel > 8) {
 | |
|         for (i = 0, visual = pScreen->visuals;
 | |
|              i < pScreen->numVisuals; i++, visual++) {
 | |
|             if ((visual->class | DynamicClass) == DirectColor) {
 | |
|                 visual->offsetRed = pScrn->offset.red;
 | |
|                 visual->offsetGreen = pScrn->offset.green;
 | |
|                 visual->offsetBlue = pScrn->offset.blue;
 | |
|                 visual->redMask = pScrn->mask.red;
 | |
|                 visual->greenMask = pScrn->mask.green;
 | |
|                 visual->blueMask = pScrn->mask.blue;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * If banking is needed, initialise an miBankInfoRec (defined in
 | |
|      * "mibank.h"), and call miInitializeBanking().
 | |
|      */
 | |
|     if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
 | |
|                                      pScrn->displayWidth, pBankInfo))
 | |
|         return FALSE;
 | |
| 
 | |
|     /*
 | |
|      * If backing store is to be supported (as is usually the case),
 | |
|      * initialise it.
 | |
|      */
 | |
|     miInitializeBackingStore(pScreen);
 | |
| 
 | |
|     /*
 | |
|      * Set initial black & white colourmap indices.
 | |
|      */
 | |
|     xf86SetBlackWhitePixels(pScreen);
 | |
| 
 | |
|     /*
 | |
|      * Install colourmap functions.  If using the vgahw module,
 | |
|      * vgaHandleColormaps would usually be called here.
 | |
|      */
 | |
| 
 | |
|     ...
 | |
| 
 | |
|     /*
 | |
|      * Initialise cursor functions.  This example is for the mi
 | |
|      * software cursor.
 | |
|      */
 | |
|     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
 | |
| 
 | |
|     /* Initialise the default colourmap */
 | |
|     switch (pScrn->depth) {
 | |
|     case 1:
 | |
|         if (!xf1bppCreateDefColormap(pScreen))
 | |
|             return FALSE;
 | |
|         break;
 | |
|     case 4:
 | |
|         if (!xf4bppCreateDefColormap(pScreen))
 | |
|             return FALSE;
 | |
|         break;
 | |
|     default:
 | |
|         if (!cfbCreateDefColormap(pScreen))
 | |
|             return FALSE;
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Wrap the CloseScreen vector and set SaveScreen.
 | |
|      */
 | |
|     ZZZPTR(pScrn)->CloseScreen = pScreen->CloseScreen;
 | |
|     pScreen->CloseScreen = ZZZCloseScreen;
 | |
|     pScreen->SaveScreen = ZZZSaveScreen;
 | |
| 
 | |
|     /* Report any unused options (only for the first generation) */
 | |
|     if (serverGeneration == 1) {
 | |
|         xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 | |
|     }
 | |
| 
 | |
|     /* Done */
 | |
|     return TRUE;
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| 
 | |
| <sect2>SwitchMode
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;SwitchMode()&e.code; function if mode switching
 | |
|     is supported by the driver.
 | |
| 
 | |
|     <code>
 | |
| static Bool
 | |
| ZZZSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
 | |
| {
 | |
|     return ZZZModeInit(xf86Screens[scrnIndex], mode);
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| 
 | |
| <sect2>AdjustFrame
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;AdjustFrame()&e.code; function if the driver
 | |
|     supports this.
 | |
| 
 | |
|     <code>
 | |
| static void
 | |
| ZZZAdjustFrame(int scrnIndex, int x, int y, int flags)
 | |
| {
 | |
|     /* Adjust the viewport */
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| 
 | |
| <sect2>EnterVT, LeaveVT
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;EnterVT()&e.code; and &s.code;LeaveVT()&e.code;
 | |
|     functions.
 | |
| 
 | |
|     These functions are mandatory.
 | |
| 
 | |
|     <code>
 | |
| static Bool
 | |
| ZZZEnterVT(int scrnIndex, int flags)
 | |
| {
 | |
|     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 | |
|     return ZZZModeInit(pScrn, pScrn->currentMode);
 | |
| }
 | |
| 
 | |
| static void
 | |
| ZZZLeaveVT(int scrnIndex, int flags)
 | |
| {
 | |
|     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 | |
|     ZZZRestore(pScrn);
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| <sect2>CloseScreen
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;CloseScreen()&e.code; function:
 | |
| 
 | |
|     This function is mandatory.  Note that it unwraps the previously
 | |
|     wrapped &s.code;pScreen->CloseScreen&e.code;, and finishes by
 | |
|     calling it.
 | |
| 
 | |
|     <code>
 | |
| static Bool
 | |
| ZZZCloseScreen(int scrnIndex, ScreenPtr pScreen)
 | |
| {
 | |
|     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 | |
|     if (pScrn->vtSema) {
 | |
|         ZZZRestore(pScrn);
 | |
|         ZZZUnmapMem(pScrn);
 | |
|     }
 | |
|     pScrn->vtSema = FALSE;
 | |
|     pScreen->CloseScreen = ZZZPTR(pScrn)->CloseScreen;
 | |
|     return (*pScreen->CloseScreen)(scrnIndex, pScreen);
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| <sect2>SaveScreen
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;SaveScreen()&e.code; function (the screen
 | |
|     blanking function).  When using the vgahw module, this will typically
 | |
|     be:
 | |
| 
 | |
|     <code>
 | |
| static Bool
 | |
| ZZZSaveScreen(ScreenPtr pScreen, int mode)
 | |
| {
 | |
|     return vgaHWSaveScreen(pScreen, mode);
 | |
| }
 | |
|     </code>
 | |
| 
 | |
|     This function is mandatory.  Before modifying any hardware register
 | |
|     directly this function needs to make sure that the Xserver is active
 | |
|     by checking if &s.code;pScrn&e.code; is non-NULL and for
 | |
|     &s.code;pScrn->vtSema == TRUE&e.code;.
 | |
| 
 | |
| <sect2>FreeScreen
 | |
| <p>
 | |
| 
 | |
|     Define the &s.code;FreeScreen()&e.code; function.  This function
 | |
|     is optional.  It should be defined if the &s.code;ScrnInfoRec&e.code;
 | |
|     &s.code;driverPrivate&e.code; field is used so that it can be freed
 | |
|     when a screen is deleted by the common layer for reasons possibly
 | |
|     beyond the driver's control.  This function is not used in during
 | |
|     normal (error free) operation.  The per-generation data is freed by
 | |
|     the &s.code;CloseScreen()&e.code; function.
 | |
| 
 | |
|     <code>
 | |
| static void
 | |
| ZZZFreeScreen(int scrnIndex, int flags)
 | |
| {
 | |
|     /*
 | |
|      * If the vgahw module is used vgaHWFreeHWRec() would be called
 | |
|      * here.
 | |
|      */
 | |
|     ZZZFreeRec(xf86Screens[scrnIndex]);
 | |
| }
 | |
|     </code>
 | |
| 
 | |
| 
 | |
| </article>
 |