diff options
author | marha <marha@users.sourceforge.net> | 2010-05-21 06:36:23 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2010-05-21 06:36:23 +0000 |
commit | 1a038249967b51878bc492df42e24b2af797bb85 (patch) | |
tree | fb2dcd26819ab0ac4e3d3aa4b5a8a3d8e339b9c6 /xorg-server | |
parent | 3319741e6f9fc3232eb40462a261271b9af2dcb2 (diff) | |
download | vcxsrv-1a038249967b51878bc492df42e24b2af797bb85.tar.gz vcxsrv-1a038249967b51878bc492df42e24b2af797bb85.tar.bz2 vcxsrv-1a038249967b51878bc492df42e24b2af797bb85.zip |
xserver git update 21/5/2010
Diffstat (limited to 'xorg-server')
25 files changed, 23604 insertions, 15652 deletions
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 1c7875ee3..6b94bb642 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -1,2247 +1,2249 @@ -dnl Copyright © 2003-2007 Keith Packard, Daniel Stone -dnl -dnl Permission is hereby granted, free of charge, to any person obtaining a -dnl copy of this software and associated documentation files (the "Software"), -dnl to deal in the Software without restriction, including without limitation -dnl the rights to use, copy, modify, merge, publish, distribute, sublicense, -dnl and/or sell copies of the Software, and to permit persons to whom the -dnl Software is furnished to do so, subject to the following conditions: -dnl -dnl The above copyright notice and this permission notice (including the next -dnl paragraph) shall be included in all copies or substantial portions of the -dnl Software. -dnl -dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -dnl THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -dnl FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -dnl DEALINGS IN THE SOFTWARE. -dnl -dnl Authors: Keith Packard <keithp@keithp.com> -dnl Daniel Stone <daniel@fooishbar.org> -dnl an unwitting cast of miscellaneous others -dnl -dnl Process this file with autoconf to create configure. - -AC_PREREQ(2.57) -AC_INIT([xorg-server], 1.8.99.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="unreleased" -AC_CONFIG_SRCDIR([Makefile.am]) -AM_INIT_AUTOMAKE([foreign dist-bzip2]) -AM_MAINTAINER_MODE - -# Require xorg-macros: XORG_DEFAULT_OPTIONS -m4_ifndef([XORG_MACROS_VERSION], - [m4_fatal([must install xorg-macros 1.6 or later before running autoconf/autogen])]) -XORG_MACROS_VERSION(1.6) -XORG_DEFAULT_OPTIONS -XORG_WITH_DOXYGEN(1.6.1) - -m4_ifndef([XORG_FONT_MACROS_VERSION], [m4_fatal([must install fontutil 1.1 or later before running autoconf/autogen])]) -XORG_FONT_MACROS_VERSION(1.1) - -dnl this gets generated by autoheader, and thus contains all the defines. we -dnl don't ever actually use it, internally. -AC_CONFIG_HEADERS(include/do-not-use-config.h) -dnl xorg-server.h is an external header, designed to be included by loadable -dnl drivers. -AC_CONFIG_HEADERS(include/xorg-server.h) -dnl dix-config.h covers most of the DIX (i.e. everything but the DDX, not just -dnl dix/). -AC_CONFIG_HEADERS(include/dix-config.h) -dnl xorg-config.h covers the Xorg DDX. -AC_CONFIG_HEADERS(include/xorg-config.h) -dnl xkb-config.h covers XKB for the Xorg and Xnest DDXs. -AC_CONFIG_HEADERS(include/xkb-config.h) -dnl xwin-config.h covers the XWin DDX. -AC_CONFIG_HEADERS(include/xwin-config.h) -dnl kdrive-config.h covers the kdrive DDX -AC_CONFIG_HEADERS(include/kdrive-config.h) -dnl version-config.h covers the version numbers so they can be bumped without -dnl forcing an entire recompile.x -AC_CONFIG_HEADERS(include/version-config.h) - -AC_PROG_CC -AM_PROG_AS -AC_PROG_INSTALL -AC_PROG_LN_S -AC_LIBTOOL_WIN32_DLL -AC_DISABLE_STATIC -AC_PROG_LIBTOOL -DOLT -AC_PROG_MAKE_SET -PKG_PROG_PKG_CONFIG -AC_PROG_LEX -AC_PROG_YACC -AC_SYS_LARGEFILE -XORG_PROG_RAWCPP -AC_PROG_SED - -# Quoted so that make will expand $(CWARNFLAGS) in makefiles to allow -# easier overrides at build time. -XSERVER_CFLAGS='$(CWARNFLAGS)' - -dnl Check for dtrace program (needed to build Xserver dtrace probes) -dnl Also checks for <sys/sdt.h>, since some Linux distros have an -dnl ISDN trace program named dtrace -AC_ARG_WITH(dtrace, AS_HELP_STRING([--with-dtrace=PATH], - [Enable dtrace probes (default: enabled if dtrace found)]), - [WDTRACE=$withval], [WDTRACE=auto]) -if test "x$WDTRACE" = "xyes" -o "x$WDTRACE" = "xauto" ; then - AC_PATH_PROG(DTRACE, [dtrace], [not_found], [$PATH:/usr/sbin]) - if test "x$DTRACE" = "xnot_found" ; then - if test "x$WDTRACE" = "xyes" ; then - AC_MSG_FAILURE([dtrace requested but not found]) - fi - WDTRACE="no" - else - AC_CHECK_HEADER(sys/sdt.h, [HAS_SDT_H="yes"], [HAS_SDT_H="no"]) - if test "x$WDTRACE" = "xauto" -a "x$HAS_SDT_H" = "xno" ; then - WDTRACE="no" - fi - fi -fi -if test "x$WDTRACE" != "xno" ; then - AC_DEFINE(XSERVER_DTRACE, 1, - [Define to 1 if the DTrace Xserver provider probes should be built in.]) - -# Solaris/OpenSolaris require dtrace -G to build dtrace probe information into -# object files, and require linking with those as relocatable objects, not .a -# archives. MacOS X handles all this in the normal compiler toolchain, and on -# some releases (like Tiger), will error out on dtrace -G. For now, other -# platforms with Dtrace ports are assumed to support -G (the FreeBSD and Linux -# ports appear to, based on my web searches, but have not yet been tested). - case $host_os in - darwin*) SPECIAL_DTRACE_OBJECTS=no ;; - *) SPECIAL_DTRACE_OBJECTS=yes ;; - esac -fi -AM_CONDITIONAL(XSERVER_DTRACE, [test "x$WDTRACE" != "xno"]) -AM_CONDITIONAL(SPECIAL_DTRACE_OBJECTS, [test "x$SPECIAL_DTRACE_OBJECTS" = "xyes"]) - -AC_HEADER_DIRENT -AC_HEADER_STDC -AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h fnmatch.h]) - -dnl Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_C_BIGENDIAN([ENDIAN="X_BIG_ENDIAN"], [ENDIAN="X_LITTLE_ENDIAN"]) - -AC_CHECK_SIZEOF([unsigned long]) -if test "$ac_cv_sizeof_unsigned_long" = 8; then - AC_DEFINE(_XSERVER64, 1, [Define to 1 if unsigned long is 64 bits.]) -fi - -AC_TYPE_PID_T - -# Checks for headers/macros for byte swapping -# Known variants: -# <byteswap.h> bswap_16, bswap_32, bswap_64 (glibc) -# <sys/endian.h> __swap16, __swap32, __swap64 (OpenBSD) -# <sys/endian.h> bswap16, bswap32, bswap64 (other BSD's) -# and a fallback to local macros if none of the above are found - -# if <byteswap.h> is found, assume it's the correct version -AC_CHECK_HEADERS([byteswap.h]) - -# if <sys/endian.h> is found, have to check which version -AC_CHECK_HEADER([sys/endian.h], [HAVE_SYS_ENDIAN_H="yes"], [HAVE_SYS_ENDIAN_H="no"]) - -if test "x$HAVE_SYS_ENDIAN_H" = "xyes" ; then - AC_MSG_CHECKING([for __swap16 variant of <sys/endian.h> byteswapping macros]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([ -#include <sys/types.h> -#include <sys/endian.h> - ], [ -int a = 1, b; -b = __swap16(a); - ]) -], [SYS_ENDIAN__SWAP='yes'], [SYS_ENDIAN__SWAP='no']) - AC_MSG_RESULT([$SYS_ENDIAN__SWAP]) - - AC_MSG_CHECKING([for bswap16 variant of <sys/endian.h> byteswapping macros]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([ -#include <sys/types.h> -#include <sys/endian.h> - ], [ -int a = 1, b; -b = bswap16(a); - ]) -], [SYS_ENDIAN_BSWAP='yes'], [SYS_ENDIAN_BSWAP='no']) - AC_MSG_RESULT([$SYS_ENDIAN_BSWAP]) - - if test "$SYS_ENDIAN_BSWAP" = "yes" ; then - USE_SYS_ENDIAN_H=yes - BSWAP=bswap - else - if test "$SYS_ENDIAN__SWAP" = "yes" ; then - USE_SYS_ENDIAN_H=yes - BSWAP=__swap - else - USE_SYS_ENDIAN_H=no - fi - fi - - if test "$USE_SYS_ENDIAN_H" = "yes" ; then - AC_DEFINE([USE_SYS_ENDIAN_H], 1, - [Define to use byteswap macros from <sys/endian.h>]) - AC_DEFINE_UNQUOTED([bswap_16], ${BSWAP}16, - [Define to 16-bit byteswap macro]) - AC_DEFINE_UNQUOTED([bswap_32], ${BSWAP}32, - [Define to 32-bit byteswap macro]) - AC_DEFINE_UNQUOTED([bswap_64], ${BSWAP}64, - [Define to 64-bit byteswap macro]) - fi -fi - -dnl Check to see if dlopen is in default libraries (like Solaris, which -dnl has it in libc), or if libdl is needed to get it. -AC_CHECK_FUNC([dlopen], [], - AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl")) -AC_SUBST(DLOPEN_LIBS) - -dnl Checks for library functions. -AC_FUNC_VPRINTF -AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \ - strtol getopt getopt_long vsnprintf walkcontext backtrace \ - getisax getzoneid shmctl64 strcasestr ffs]) -AC_FUNC_ALLOCA -dnl Old HAS_* names used in os/*.c. -AC_CHECK_FUNC([getdtablesize], - AC_DEFINE(HAS_GETDTABLESIZE, 1, [Have the 'getdtablesize' function.])) -AC_CHECK_FUNC([getifaddrs], - AC_DEFINE(HAS_GETIFADDRS, 1, [Have the 'getifaddrs' function.])) -AC_CHECK_FUNC([getpeereid], - AC_DEFINE(HAS_GETPEEREID, 1, [Have the 'getpeereid' function.])) -AC_CHECK_FUNC([getpeerucred], - AC_DEFINE(HAS_GETPEERUCRED, 1, [Have the 'getpeerucred' function.])) -AC_CHECK_FUNC([strlcat], HAVE_STRLCAT=yes, HAVE_STRLCAT=no) -AM_CONDITIONAL(NEED_STRLCAT, [test x$HAVE_STRLCAT = xno]) -AC_CHECK_FUNC([strlcpy], AC_DEFINE(HAS_STRLCPY, 1, [Have the 'strlcpy' function])) - -AM_CONDITIONAL(NEED_VSNPRINTF, [test x$HAVE_VSNPRINTF = xno]) - -dnl Check for mmap support for Xvfb -AC_CHECK_FUNC([mmap], AC_DEFINE(HAS_MMAP, 1, [Have the 'mmap' function.])) - -dnl Find the math libary -AC_CHECK_LIB(m, sqrt) -AC_CHECK_LIB(m, cbrt, AC_DEFINE(HAVE_CBRT, 1, [Have the 'cbrt' function])) - -AC_CHECK_HEADERS([ndbm.h dbm.h rpcsvc/dbm.h]) - -dnl AGPGART headers -AC_CHECK_HEADERS([linux/agpgart.h sys/agpio.h sys/agpgart.h], AGP=yes) -AM_CONDITIONAL(AGP, [test "x$AGP" = xyes]) - -dnl APM header -AC_CHECK_HEADERS([linux/apm_bios.h], LNXAPM=yes) -AM_CONDITIONAL(LNXAPM, [test "x$LNXAPM" = xyes]) - -dnl fbdev header -AC_CHECK_HEADERS([linux/fb.h], FBDEV=yes) -AM_CONDITIONAL(FBDEVHW, [test "x$FBDEV" = xyes]) - -dnl MTRR header -AC_CHECK_HEADERS([asm/mtrr.h], ac_cv_asm_mtrr_h=yes) -if test "x$ac_cv_asm_mtrr_h" = xyes; then - HAVE_MTRR=yes -fi - -dnl BSD MTRR header -AC_CHECK_HEADERS([sys/memrange.h], ac_cv_memrange_h=yes) -if test "x$ac_cv_memrange_h" = xyes; then - HAVE_MTRR=yes -fi - -if test "x$HAVE_MTRR" = xyes; then - AC_DEFINE(HAS_MTRR_SUPPORT, 1, [MTRR support available]) -fi - -dnl A NetBSD MTRR header -AC_CHECK_HEADERS([machine/mtrr.h], ac_cv_machine_mtrr_h=yes) -if test "x$ac_cv_machine_mtrr_h" = xyes; then - AC_DEFINE(HAS_MTRR_BUILTIN, 1, [Define to 1 if NetBSD built-in MTRR - support is available]) -fi - -dnl FreeBSD kldload support (sys/linker.h) -AC_CHECK_HEADERS([sys/linker.h], - [ac_cv_sys_linker_h=yes], - [ac_cv_sys_linker_h=no], - [#include <sys/param.h>]) -AM_CONDITIONAL(FREEBSD_KLDLOAD, [test "x$ac_cv_sys_linker_h" = xyes]) - -AC_CACHE_CHECK([for SYSV IPC], - ac_cv_sysv_ipc, - [AC_TRY_LINK([ -#include <sys/types.h> -#include <sys/ipc.h> -#include <sys/shm.h> -],[ -{ - int id; - id = shmget(IPC_PRIVATE, 512, SHM_W | SHM_R); - if (id < 0) return -1; - return shmctl(id, IPC_RMID, 0); -}], - [ac_cv_sysv_ipc=yes], - [ac_cv_sysv_ipc=no])]) -if test "x$ac_cv_sysv_ipc" = xyes; then - AC_DEFINE(HAVE_SYSV_IPC, 1, [Define to 1 if SYSV IPC is available]) -fi - -dnl OpenBSD /dev/xf86 aperture driver -if test -c /dev/xf86 ; then - AC_DEFINE(HAS_APERTURE_DRV, 1, [System has /dev/xf86 aperture driver]) -fi - -dnl BSD APM support -AC_CHECK_HEADER([machine/apmvar.h],[ - AC_CHECK_HEADER([sys/event.h], - ac_cv_BSD_KQUEUE_APM=yes, - ac_cv_BSD_APM=yes)]) - -AM_CONDITIONAL(BSD_APM, [test "x$ac_cv_BSD_APM" = xyes]) -AM_CONDITIONAL(BSD_KQUEUE_APM, [test "x$ac_cv_BSD_KQUEUE_APM" = xyes]) - -dnl glibc backtrace support check (hw/xfree86/common/xf86Events.c) -AC_CHECK_HEADER([execinfo.h],[ - AC_CHECK_LIB(c, backtrace, [ - AC_DEFINE(HAVE_BACKTRACE, 1, [Has backtrace support]) - AC_DEFINE(HAVE_EXECINFO_H, 1, [Have execinfo.h]) - ])] -) - -dnl ARM needs additional compiler flags for proper backtraces if GCC is -dnl used. Compile a dummy program with the -mapcs-frame option. If it -dnl succeeds, we know that we are building for ARM with GCC. -old_CFLAGS="$CFLAGS" -CFLAGS="-mapcs-frame" -AC_COMPILE_IFELSE( - AC_LANG_PROGRAM([[ ]]), - ARM_BACKTRACE_CFLAGS="$CFLAGS", - ARM_BACKTRACE_CFLAGS="" -) -CFLAGS="$old_CFLAGS" -AC_SUBST(ARM_BACKTRACE_CFLAGS) - -dnl --------------------------------------------------------------------------- -dnl Bus options and CPU capabilities. Replaces logic in -dnl hw/xfree86/os-support/bus/Makefile.am, among others. -dnl --------------------------------------------------------------------------- -DEFAULT_INT10="x86emu" - -dnl Override defaults as needed for specific platforms: - -case $host_cpu in - alpha*) - ALPHA_VIDEO=yes - case $host_os in - *freebsd*) SYS_LIBS=-lio ;; - *netbsd*) AC_DEFINE(USE_ALPHA_PIO, 1, [NetBSD PIO alpha IO]) ;; - esac - GLX_ARCH_DEFINES="-D__GLX_ALIGN64 -mieee" - ;; - arm*) - ARM_VIDEO=yes - ;; - i*86) - I386_VIDEO=yes - case $host_os in - *freebsd*) AC_DEFINE(USE_DEV_IO) ;; - *dragonfly*) AC_DEFINE(USE_DEV_IO) ;; - *netbsd*) AC_DEFINE(USE_I386_IOPL) - SYS_LIBS=-li386 - ;; - *openbsd*) AC_DEFINE(USE_I386_IOPL) - SYS_LIBS=-li386 - ;; - esac - ;; - powerpc*) - PPC_VIDEO=yes - case $host_os in - *freebsd*) DEFAULT_INT10=stub ;; - esac - ;; - sparc*) - SPARC64_VIDEO=yes - BSD_ARCH_SOURCES="sparc64_video.c ioperm_noop.c" - GLX_ARCH_DEFINES="-D__GLX_ALIGN64" - ;; - x86_64*|amd64*) - I386_VIDEO=yes - case $host_os in - *freebsd*) AC_DEFINE(USE_DEV_IO, 1, [BSD /dev/io]) ;; - *dragonfly*) AC_DEFINE(USE_DEV_IO, 1, [BSD /dev/io]) ;; - *netbsd*) AC_DEFINE(USE_I386_IOPL, 1, [BSD i386 iopl]) - SYS_LIBS=-lx86_64 - ;; - *openbsd*) AC_DEFINE(USE_AMD64_IOPL, 1, [BSD AMD64 iopl]) - SYS_LIBS=-lamd64 - ;; - esac - GLX_ARCH_DEFINES="-D__GLX_ALIGN64" - ;; - ia64*) - GLX_ARCH_DEFINES="-D__GLX_ALIGN64" - ;; - s390*) - GLX_ARCH_DEFINES="-D__GLX_ALIGN64" - ;; -esac -AC_SUBST(GLX_ARCH_DEFINES) - -dnl BSD *_video.c selection -AM_CONDITIONAL(ALPHA_VIDEO, [test "x$ALPHA_VIDEO" = xyes]) -AM_CONDITIONAL(ARM_VIDEO, [test "x$ARM_VIDEO" = xyes]) -AM_CONDITIONAL(I386_VIDEO, [test "x$I386_VIDEO" = xyes]) -AM_CONDITIONAL(PPC_VIDEO, [test "x$PPC_VIDEO" = xyes]) -AM_CONDITIONAL(SPARC64_VIDEO, [test "x$SPARC64_VIDEO" = xyes]) - -DRI=no -USE_SIGIO_BY_DEFAULT="yes" -dnl it would be nice to autodetect these *CONS_SUPPORTs -case $host_os in - *freebsd* | *dragonfly*) - case $host_os in - kfreebsd*-gnu) ;; - *) AC_DEFINE(CSRG_BASED, 1, [System is BSD-like]) ;; - esac - AC_DEFINE(PCCONS_SUPPORT, 1, [System has PC console]) - AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console]) - AC_DEFINE(SYSCONS_SUPPORT, 1, [System has syscons console]) - DRI=yes - ;; - *netbsd*) - AC_DEFINE(CSRG_BASED, 1, [System is BSD-like]) - AC_DEFINE(PCCONS_SUPPORT, 1, [System has PC console]) - AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console]) - AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console]) - DRI=yes - ;; - *openbsd*) - AC_DEFINE(CSRG_BASED, 1, [System is BSD-like]) - AC_DEFINE(PCVT_SUPPORT, 1, [System has PC console]) - AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console]) - ;; - *linux*) - DRI=yes - ;; - *solaris*) - PKG_CHECK_EXISTS(libdrm, DRI=yes, DRI=no) - # Disable use of SIGIO by default until some system bugs are - # fixed - see Sun/OpenSolaris bug id 6879897 - USE_SIGIO_BY_DEFAULT="no" - ;; - darwin*) - AC_DEFINE(CSRG_BASED, 1, [System is BSD-like]) - ;; - cygwin*) - CFLAGS="$CFLAGS -DFD_SETSIZE=256" - ;; -esac - -dnl augment XORG_RELEASE_VERSION for our snapshot number and to expose the -dnl major number -PVMAJOR=`echo $PACKAGE_VERSION | cut -d . -f 1` -PVS=`echo $PACKAGE_VERSION | cut -d . -f 4 | cut -d - -f 1` -if test "x$PVS" = "x"; then - PVS="0" -fi - -VENDOR_RELEASE="((($PVMAJOR) * 10000000) + (($PVM) * 100000) + (($PVP) * 1000) + $PVS)" -VENDOR_MAN_VERSION="Version ${PACKAGE_VERSION}" - -VENDOR_NAME="The X.Org Foundation" -VENDOR_NAME_SHORT="X.Org" -VENDOR_WEB="http://wiki.x.org" - -m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))]) - -dnl Build options. -AC_ARG_ENABLE(werror, AS_HELP_STRING([--enable-werror], - [Obsolete - use --enable-strict-compilation instead]), - AC_MSG_ERROR([--enable-werror has been replaced by --enable-strict-compilation])) - -AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], - [Enable debugging (default: disabled)]), - [DEBUGGING=$enableval], [DEBUGGING=no]) -AC_ARG_ENABLE(unit-tests, AS_HELP_STRING([--enable-unit-tests], - [Enable unit-tests (default: auto)]), - [UNITTESTS=$enableval], [UNITTESTS=auto]) -AC_ARG_ENABLE(use-sigio-by-default, AS_HELP_STRING([--enable-use-sigio-by-default] - [Enable SIGIO input handlers by default (default: $USE_SIGIO_BY_DEFAULT)]), - [USE_SIGIO_BY_DEFAULT=$enableval], []) -AC_ARG_WITH(int10, AS_HELP_STRING([--with-int10=BACKEND], [int10 backend: vm86, x86emu or stub]), - [INT10="$withval"], - [INT10="$DEFAULT_INT10"]) -AC_ARG_WITH(vendor-name, AS_HELP_STRING([--with-vendor-name=VENDOR], - [Vendor string reported by the server]), - [ VENDOR_NAME="$withval" ], []) -AC_ARG_WITH(vendor-name-short, AS_HELP_STRING([--with-vendor-name-short=VENDOR], - [Short version of vendor string reported by the server]), - [ VENDOR_NAME_SHORT="$withval" ], []) -AC_ARG_WITH(vendor-web, AS_HELP_STRING([--with-vendor-web=URL], - [Vendor web address reported by the server]), - [ VENDOR_WEB="$withval" ], []) -AC_ARG_WITH(module-dir, AS_HELP_STRING([--with-module-dir=DIR], - [Directory where modules are installed (default: $libdir/xorg/modules)]), - [ moduledir="$withval" ], - [ moduledir="${libdir}/xorg/modules" ]) -AC_ARG_WITH(log-dir, AS_HELP_STRING([--with-log-dir=DIR], - [Directory where log files are kept (default: $localstatedir/log)]), - [ logdir="$withval" ], - [ logdir="$localstatedir/log" ]) -AC_ARG_WITH(builder-addr, AS_HELP_STRING([--with-builder-addr=ADDRESS], - [Builder address (default: xorg@lists.freedesktop.org)]), - [ BUILDERADDR="$withval" ], - [ BUILDERADDR="xorg@lists.freedesktop.org" ]) -AC_ARG_WITH(os-name, AS_HELP_STRING([--with-os-name=OSNAME], [Name of OS (default: output of "uname -srm")]), - [ OSNAME="$withval" ], - [ OSNAME=`uname -srm` ]) -AC_ARG_WITH(os-vendor, AS_HELP_STRING([--with-os-vendor=OSVENDOR], [Name of OS vendor]), - [ OSVENDOR="$withval" ], - [ OSVENDOR="" ]) -AC_ARG_WITH(builderstring, AS_HELP_STRING([--with-builderstring=BUILDERSTRING], [Additional builder string]), - [ BUILDERSTRING="$withval" ] - [ ]) - -dnl Determine font path -XORG_FONTROOTDIR -XORG_FONTSUBDIR(FONTMISCDIR, fontmiscdir, misc) -XORG_FONTSUBDIR(FONTOTFDIR, fontotfdir, OTF) -XORG_FONTSUBDIR(FONTTTFDIR, fontttfdir, TTF) -XORG_FONTSUBDIR(FONTTYPE1DIR, fonttype1dir, Type1) -XORG_FONTSUBDIR(FONT75DPIDIR, font75dpidir, 75dpi) -XORG_FONTSUBDIR(FONT100DPIDIR, font100dpidir, 100dpi) - -dnl Uses --default-font-path if set, otherwise checks for /etc/X11/fontpath.d, -dnl otherwise uses standard subdirectories of FONTROOTDIR. When cross -dnl compiling, assume default font path uses standard FONTROOTDIR directories. -DEFAULT_FONT_PATH="${FONTMISCDIR}/,${FONTTTFDIR}/,${FONTOTFDIR}/,${FONTTYPE1DIR}/,${FONT100DPIDIR}/,${FONT75DPIDIR}/" -if test "$cross_compiling" != yes; then - AC_CHECK_FILE([${sysconfdir}/X11/fontpath.d], - [DEFAULT_FONT_PATH='catalogue:${sysconfdir}/X11/fontpath.d'], - [case $host_os in - darwin*) DEFAULT_FONT_PATH="${DEFAULT_FONT_PATH},/Library/Fonts,/System/Library/Fonts" ;; - esac]) -fi -AC_ARG_WITH(default-font-path, AS_HELP_STRING([--with-default-font-path=PATH], [Comma separated list of font dirs]), - [ FONTPATH="$withval" ], - [ FONTPATH="${DEFAULT_FONT_PATH}" ]) - -AC_MSG_CHECKING([for default font path]) -AC_MSG_RESULT([$FONTPATH]) - -AC_ARG_WITH(xkb-path, AS_HELP_STRING([--with-xkb-path=PATH], [Path to XKB base dir (default: ${datadir}/X11/xkb)]), - [ XKBPATH="$withval" ], - [ XKBPATH="${datadir}/X11/xkb" ]) -AC_ARG_WITH(xkb-output, AS_HELP_STRING([--with-xkb-output=PATH], [Path to XKB output dir (default: ${datadir}/X11/xkb/compiled)]), - [ XKBOUTPUT="$withval" ], - [ XKBOUTPUT="compiled" ]) -AC_ARG_WITH(default-xkb-rules, AS_HELP_STRING([--with-default-xkb-rules=RULES], - [Keyboard ruleset (default: base/evdev)]), - [ XKB_DFLT_RULES="$withval" ], - [ XKB_DFLT_RULES="" ]) -AC_ARG_WITH(default-xkb-model, AS_HELP_STRING([--with-default-xkb-model=MODEL], - [Keyboard model (default: pc105)]), - [ XKB_DFLT_MODEL="$withval" ], - [ XKB_DFLT_MODEL="pc105" ]) -AC_ARG_WITH(default-xkb-layout, AS_HELP_STRING([--with-default-xkb-layout=LAYOUT], - [Keyboard layout (default: us)]), - [ XKB_DFLT_LAYOUT="$withval" ], - [ XKB_DFLT_LAYOUT="us" ]) -AC_ARG_WITH(default-xkb-variant, AS_HELP_STRING([--with-default-xkb-variant=VARIANT], - [Keyboard variant (default: (none))]), - [ XKB_DFLT_VARIANT="$withval" ], - [ XKB_DFLT_VARIANT="" ]) -AC_ARG_WITH(default-xkb-options, AS_HELP_STRING([--with-default-xkb-options=OPTIONS], - [Keyboard layout options (default: (none))]), - [ XKB_DFLT_OPTIONS="$withval" ], - [ XKB_DFLT_OPTIONS="" ]) -AC_ARG_WITH(serverconfig-path, AS_HELP_STRING([--with-serverconfig-path=PATH], - [Directory where ancillary server config files are installed (default: ${libdir}/xorg)]), - [ SERVERCONFIG="$withval" ], - [ SERVERCONFIG="${libdir}/xorg" ]) -AC_ARG_WITH(apple-applications-dir,AS_HELP_STRING([--with-apple-applications-dir=PATH], [Path to the Applications directory (default: /Applications/Utilities)]), - [ APPLE_APPLICATIONS_DIR="${withval}" ], - [ APPLE_APPLICATIONS_DIR="/Applications/Utilities" ]) -AC_SUBST([APPLE_APPLICATIONS_DIR]) -AC_ARG_WITH(apple-application-name,AS_HELP_STRING([--with-apple-application-name=NAME], [Name for the .app (default: X11)]), - [ APPLE_APPLICATION_NAME="${withval}" ], - [ APPLE_APPLICATION_NAME="X11" ]) -AC_SUBST([APPLE_APPLICATION_NAME]) -AC_ARG_WITH(launchd-id-prefix, AS_HELP_STRING([--with-launchd-id-prefix=PATH], [Prefix to use for launchd identifiers (default: org.x)]), - [ LAUNCHD_ID_PREFIX="${withval}" ], - [ LAUNCHD_ID_PREFIX="org.x" ]) -AC_SUBST([LAUNCHD_ID_PREFIX]) -AC_DEFINE_UNQUOTED(LAUNCHD_ID_PREFIX, "$LAUNCHD_ID_PREFIX", [Prefix to use for launchd identifiers]) -AC_ARG_ENABLE(sparkle,AS_HELP_STRING([--enable-sparkle], [Enable updating of X11.app using the Sparkle Framework (default: disabled)]), - [ XQUARTZ_SPARKLE="${enableval}" ], - [ XQUARTZ_SPARKLE="no" ]) -AC_SUBST([XQUARTZ_SPARKLE]) -AC_ARG_ENABLE(builddocs, AS_HELP_STRING([--enable-builddocs], [Build docs (default: disabled)]), - [BUILDDOCS=$enableval], - [BUILDDOCS=no]) -AC_ARG_ENABLE(install-libxf86config, - AS_HELP_STRING([--enable-install-libxf86config], - [Install libxf86config (default: disabled)]), - [INSTALL_LIBXF86CONFIG=$enableval], - [INSTALL_LIBXF86CONFIG=no]) -AC_ARG_ENABLE(visibility, AC_HELP_STRING([--enable-visibility], [Enable symbol visibility (default: auto)]), - [SYMBOL_VISIBILITY=$enableval], - [SYMBOL_VISIBILITY=auto]) -AC_ARG_ENABLE(pc98, AC_HELP_STRING([--enable-pc98], [Enable PC98 support in Xorg (default: auto)]), - [SUPPORT_PC98=$enableval], - [SUPPORT_PC98=auto]) - -dnl GLX build options -AC_ARG_WITH(dri-driver-path, AS_HELP_STRING([--with-dri-driver-path=PATH], [Path to DRI drivers (default: ${libdir}/dri)]), - [ DRI_DRIVER_PATH="$withval" ], - [ DRI_DRIVER_PATH="${libdir}/dri" ]) -AC_ARG_ENABLE(aiglx, AS_HELP_STRING([--enable-aiglx], [Build accelerated indirect GLX (default: enabled)]), - [AIGLX=$enableval], - [AIGLX=yes]) -AC_ARG_ENABLE(glx-tls, AS_HELP_STRING([--enable-glx-tls], [Build GLX with TLS support (default: disabled)]), - [GLX_USE_TLS=$enableval], - [GLX_USE_TLS=no]) - -dnl Extensions. -AC_ARG_ENABLE(registry, AS_HELP_STRING([--disable-registry], [Build string registry module (default: enabled)]), [XREGISTRY=$enableval], [XREGISTRY=yes]) -AC_ARG_ENABLE(composite, AS_HELP_STRING([--disable-composite], [Build Composite extension (default: enabled)]), [COMPOSITE=$enableval], [COMPOSITE=yes]) -AC_ARG_ENABLE(mitshm, AS_HELP_STRING([--disable-shm], [Build SHM extension (default: enabled)]), [MITSHM=$enableval], [MITSHM=yes]) -AC_ARG_ENABLE(xres, AS_HELP_STRING([--disable-xres], [Build XRes extension (default: enabled)]), [RES=$enableval], [RES=yes]) -AC_ARG_ENABLE(record, AS_HELP_STRING([--disable-record], [Build Record extension (default: enabled)]), [RECORD=$enableval], [RECORD=yes]) -AC_ARG_ENABLE(xv, AS_HELP_STRING([--disable-xv], [Build Xv extension (default: enabled)]), [XV=$enableval], [XV=yes]) -AC_ARG_ENABLE(xvmc, AS_HELP_STRING([--disable-xvmc], [Build XvMC extension (default: enabled)]), [XVMC=$enableval], [XVMC=yes]) -AC_ARG_ENABLE(dga, AS_HELP_STRING([--disable-dga], [Build DGA extension (default: auto)]), [DGA=$enableval], [DGA=auto]) -AC_ARG_ENABLE(screensaver, AS_HELP_STRING([--disable-screensaver], [Build ScreenSaver extension (default: enabled)]), [SCREENSAVER=$enableval], [SCREENSAVER=yes]) -AC_ARG_ENABLE(xdmcp, AS_HELP_STRING([--disable-xdmcp], [Build XDMCP extension (default: auto)]), [XDMCP=$enableval], [XDMCP=auto]) -AC_ARG_ENABLE(xdm-auth-1, AS_HELP_STRING([--disable-xdm-auth-1], [Build XDM-Auth-1 extension (default: auto)]), [XDMAUTH=$enableval], [XDMAUTH=auto]) -AC_ARG_ENABLE(glx, AS_HELP_STRING([--disable-glx], [Build GLX extension (default: enabled)]), [GLX=$enableval], [GLX=yes]) -AC_ARG_ENABLE(dri, AS_HELP_STRING([--enable-dri], [Build DRI extension (default: auto)]), [DRI=$enableval]) -AC_ARG_ENABLE(dri2, AS_HELP_STRING([--enable-dri2], [Build DRI2 extension (default: auto)]), [DRI2=$enableval], [DRI2=auto]) -AC_ARG_ENABLE(xinerama, AS_HELP_STRING([--disable-xinerama], [Build Xinerama extension (default: enabled)]), [XINERAMA=$enableval], [XINERAMA=yes]) -AC_ARG_ENABLE(xf86vidmode, AS_HELP_STRING([--disable-xf86vidmode], [Build XF86VidMode extension (default: auto)]), [XF86VIDMODE=$enableval], [XF86VIDMODE=auto]) -AC_ARG_ENABLE(xace, AS_HELP_STRING([--disable-xace], [Build X-ACE extension (default: enabled)]), [XACE=$enableval], [XACE=yes]) -AC_ARG_ENABLE(xselinux, AS_HELP_STRING([--enable-xselinux], [Build SELinux extension (default: disabled)]), [XSELINUX=$enableval], [XSELINUX=no]) -AC_ARG_ENABLE(xcsecurity, AS_HELP_STRING([--enable-xcsecurity], [Build Security extension (default: disabled)]), [XCSECURITY=$enableval], [XCSECURITY=no]) -AC_ARG_ENABLE(xcalibrate, AS_HELP_STRING([--enable-xcalibrate], [Build XCalibrate extension (default: disabled)]), [XCALIBRATE=$enableval], [XCALIBRATE=no]) -AC_ARG_ENABLE(tslib, AS_HELP_STRING([--enable-tslib], [Build kdrive tslib touchscreen support (default: disabled)]), [TSLIB=$enableval], [TSLIB=no]) -AC_ARG_ENABLE(dbe, AS_HELP_STRING([--disable-dbe], [Build DBE extension (default: enabled)]), [DBE=$enableval], [DBE=yes]) -AC_ARG_ENABLE(xf86bigfont, AS_HELP_STRING([--enable-xf86bigfont], [Build XF86 Big Font extension (default: disabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=no]) -AC_ARG_ENABLE(dpms, AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes]) -AC_ARG_ENABLE(config-udev, AS_HELP_STRING([--enable-config-udev], [Build udev support (default: auto)]), [CONFIG_UDEV=$enableval], [CONFIG_UDEV=auto]) -AC_ARG_ENABLE(config-dbus, AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no]) -AC_ARG_ENABLE(config-hal, AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto]) -AC_ARG_ENABLE(xfree86-utils, AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes]) -AC_ARG_ENABLE(xaa, AS_HELP_STRING([--enable-xaa], [Build XAA (default: enabled)]), [XAA=$enableval], [XAA=yes]) -AC_ARG_ENABLE(vgahw, AS_HELP_STRING([--enable-vgahw], [Build Xorg with vga access (default: enabled)]), [VGAHW=$enableval], [VGAHW=yes]) -AC_ARG_ENABLE(vbe, AS_HELP_STRING([--enable-vbe], [Build Xorg with VBE module (default: enabled)]), [VBE=$enableval], [VBE=yes]) -AC_ARG_ENABLE(int10-module, AS_HELP_STRING([--enable-int10-module], [Build Xorg with int10 module (default: enabled)]), [INT10MODULE=$enableval], [INT10MODULE=yes]) -AC_ARG_ENABLE(windowswm, AS_HELP_STRING([--enable-windowswm], [Build XWin with WindowsWM extension (default: no)]), [WINDOWSWM=$enableval], [WINDOWSWM=no]) - -dnl DDXes. -AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto]) -AC_ARG_ENABLE(dmx, AS_HELP_STRING([--enable-dmx], [Build DMX server (default: auto)]), [DMX=$enableval], [DMX=auto]) -AC_ARG_ENABLE(xvfb, AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes]) -AC_ARG_ENABLE(xnest, AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto]) -AC_ARG_ENABLE(xquartz, AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto]) -AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no]) -AC_ARG_ENABLE(xwin, AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto]) -dnl kdrive and its subsystems -AC_ARG_ENABLE(kdrive, AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no]) -AC_ARG_ENABLE(xephyr, AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto]) -AC_ARG_ENABLE(xfake, AS_HELP_STRING([--enable-xfake], [Build the kdrive 'fake' server (default: auto)]), [XFAKE=$enableval], [XFAKE=auto]) -AC_ARG_ENABLE(xfbdev, AS_HELP_STRING([--enable-xfbdev], [Build the kdrive framebuffer device server (default: auto)]), [XFBDEV=$enableval], [XFBDEV=auto]) -dnl kdrive options -AC_ARG_ENABLE(kdrive-kbd, AS_HELP_STRING([--enable-kdrive-kbd], [Build kbd driver for kdrive (default: auto)]), [KDRIVE_KBD=$enableval], [KDRIVE_KBD=auto]) -AC_ARG_ENABLE(kdrive-mouse, AC_HELP_STRING([--enable-kdrive-mouse], [Build mouse driver for kdrive (default: auto)]), [KDRIVE_MOUSE=$enableval], [KDRIVE_MOUSE=auto]) -AC_ARG_ENABLE(kdrive-evdev, AC_HELP_STRING([--enable-kdrive-evdev], [Build evdev driver for kdrive (default: auto)]), [KDRIVE_EVDEV=$enableval], [KDRIVE_EVDEV=auto]) - - -dnl chown/chmod to be setuid root as part of build -dnl Replaces InstallXserverSetUID in imake -AC_ARG_ENABLE(install-setuid, - AS_HELP_STRING([--enable-install-setuid], - [Install Xorg server as owned by root with setuid bit (default: auto)]), - [SETUID=$enableval], [SETUID=auto]) -AC_MSG_CHECKING([to see if we can install the Xorg server as root]) -if test "x$SETUID" = "xauto" ; then - case $host_os in - cygwin*) SETUID="no" ;; - darwin*) SETUID="no" ;; - *) - case $host_cpu in - sparc) SETUID="no" ;; - *) SETUID="yes" ;; - esac - esac - if test "x$SETUID" = xyes; then - touch testfile - chown root testfile > /dev/null 2>&1 || SETUID="no" - rm -f testfile - fi -fi -AC_MSG_RESULT([$SETUID]) -AM_CONDITIONAL(INSTALL_SETUID, [test "x$SETUID" = "xyes"]) - -dnl Issue an error if xtrans.m4 was not found and XTRANS_CONNECTION_FLAGS macro -dnl was not expanded, since xorg-server with no transport types is rather useless. -dnl -dnl If you're seeing an error here, be sure you installed the lib/xtrans module -dnl first and if it's not in the default location, that you set the ACLOCAL -dnl environment variable to find it, such as: -dnl ACLOCAL="aclocal -I ${PREFIX}/share/aclocal" -m4_pattern_forbid([^XTRANS_CONNECTION_FLAGS$]) - -# Transport selection macro from xtrans.m4 -XTRANS_CONNECTION_FLAGS - -# Secure RPC detection macro from xtrans.m4 -XTRANS_SECURE_RPC_FLAGS -AM_CONDITIONAL(SECURE_RPC, [test "x$SECURE_RPC" = xyes]) - -AM_CONDITIONAL(INT10_VM86, [test "x$INT10" = xvm86]) -AM_CONDITIONAL(INT10_X86EMU, [test "x$INT10" = xx86emu]) -AM_CONDITIONAL(INT10_STUB, [test "x$INT10" = xstub]) -if test "x$INT10" = xyes; then - dnl VM86 headers - AC_CHECK_HEADERS([sys/vm86.h sys/io.h]) -fi - -dnl Handle building documentation -AM_CONDITIONAL(BUILDDOCS, test "x$BUILDDOCS" = xyes) - -dnl Only build sgml docs when linuxdoc is available and -dnl def.ents has been installed -XORG_CHECK_LINUXDOC - -dnl Handle installing libxf86config -AM_CONDITIONAL(INSTALL_LIBXF86CONFIG, [test "x$INSTALL_LIBXF86CONFIG" = xyes]) - -dnl DDX Detection... Yes, it's ugly to have it here... but we need to -dnl handle this early on so that we don't require unsupported extensions -case $host_os in - cygwin*) - DGA=no - DRI2=no - XF86VIDMODE=no - XSELINUX=no - XV=no - ;; - darwin*) - DRI2=no - - if test x$XQUARTZ = xauto; then - AC_CACHE_CHECK([whether to build Xquartz],xorg_cv_Carbon_framework,[ - save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS -framework Carbon" - AC_LINK_IFELSE([char FSFindFolder(); int main() { FSFindFolder(); return 0;}], - [xorg_cv_Carbon_framework=yes], - [xorg_cv_Carbon_framework=no]) - LDFLAGS=$save_LDFLAGS]) - - if test "X$xorg_cv_Carbon_framework" = Xyes; then - XQUARTZ=yes - else - XQUARTZ=no - fi - fi - - if test "x$XQUARTZ" = xyes ; then - XQUARTZ=yes - XVFB=no - XNEST=no - - COMPOSITE=no - DGA=no - DPMSExtension=no - XF86VIDMODE=no - fi - ;; - *) XQUARTZ=no ;; -esac - -dnl --------------------------------------------------------------------------- -dnl Extension section -dnl --------------------------------------------------------------------------- -XEXT_INC='-I$(top_srcdir)/Xext' -XEXT_LIB='$(top_builddir)/Xext/libXext.la' -XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la' - -dnl Optional modules -VIDEOPROTO="videoproto" -COMPOSITEPROTO="compositeproto >= 0.4" -RECORDPROTO="recordproto >= 1.13.99.1" -SCRNSAVERPROTO="scrnsaverproto >= 1.1" -RESOURCEPROTO="resourceproto" -DRIPROTO="xf86driproto >= 2.1.0" -DRI2PROTO="dri2proto >= 2.3" -XINERAMAPROTO="xineramaproto" -BIGFONTPROTO="xf86bigfontproto >= 1.2.0" -XCALIBRATEPROTO="xcalibrateproto" -DGAPROTO="xf86dgaproto >= 2.0.99.1" -GLPROTO="glproto >= 1.4.10" -DMXPROTO="dmxproto >= 2.2.99.1" -VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1" -WINDOWSWMPROTO="windowswmproto" -APPLEWMPROTO="applewmproto >= 1.4" - -dnl Core modules for most extensions, et al. -REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.11] [fixesproto >= 4.1] [damageproto >= 1.1] [xcmiscproto >= 1.2.0] [xextproto >= 7.0.99.3] [xproto >= 7.0.13] [xtrans >= 1.2.2] [bigreqsproto >= 1.1.0] fontsproto [inputproto >= 1.9.99.902] [kbproto >= 1.0.3]" -REQUIRED_LIBS="xfont xau [pixman-1 >= 0.15.20]" - -dnl List of libraries that require a specific version -LIBAPPLEWM="applewm >= 1.4" -LIBDMX="dmx >= 1.0.99.1" -LIBDRI="dri >= 7.8.0" -LIBDRM="libdrm >= 2.3.0" -LIBGL="gl >= 7.1.0" -LIBXEXT="xext >= 1.0.99.4" -LIBXI="xi >= 1.2.99.1" -LIBXTST="xtst >= 1.0.99.2" -LIBPCIACCESS="pciaccess >= 0.8.0" -LIBGLIB="glib-2.0 >= 2.16" -LIBUDEV="libudev >= 143" -LIBSELINUX="libselinux >= 2.0.86" - -if test "x$CONFIG_UDEV" = xyes && - { test "x$CONFIG_DBUS_API" = xyes || test "x$CONFIG_HAL" = xyes; }; then - AC_MSG_ERROR([Hotplugging through both libudev and dbus/hal not allowed]) -fi - -PKG_CHECK_MODULES(UDEV, $LIBUDEV, [HAVE_LIBUDEV=yes], [HAVE_LIBUDEV=no]) -if test "x$CONFIG_UDEV" = xauto; then - CONFIG_UDEV="$HAVE_LIBUDEV" -fi -AM_CONDITIONAL(CONFIG_UDEV, [test "x$CONFIG_UDEV" = xyes]) -if test "x$CONFIG_UDEV" = xyes; then - CONFIG_DBUS_API=no - CONFIG_HAL=no - if ! test "x$HAVE_LIBUDEV" = xyes; then - AC_MSG_ERROR([udev configuration API requested, but libudev is not installed]) - fi - AC_DEFINE(CONFIG_UDEV, 1, [Use libudev for input hotplug]) -fi - -dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas -dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config -dnl API. -PKG_CHECK_MODULES(DBUS, dbus-1, [HAVE_DBUS=yes], [HAVE_DBUS=no]) -if test "x$HAVE_DBUS" = xyes; then - AC_DEFINE(HAVE_DBUS, 1, [Have D-Bus support]) -fi -AM_CONDITIONAL(HAVE_DBUS, [test "x$HAVE_DBUS" = xyes]) - -if test "x$CONFIG_DBUS_API" = xauto; then - CONFIG_DBUS_API="$HAVE_DBUS" -fi -if test "x$CONFIG_DBUS_API" = xyes; then - if ! test "x$HAVE_DBUS" = xyes; then - AC_MSG_ERROR([D-Bus configuration API requested, but D-Bus is not installed.]) - fi - - AC_DEFINE(CONFIG_DBUS_API, 1, [Use the D-Bus input configuration API]) - CONFIG_NEED_DBUS="yes" -fi -AM_CONDITIONAL(CONFIG_DBUS_API, [test "x$CONFIG_DBUS_API" = xyes]) - -PKG_CHECK_MODULES(HAL, hal, [HAVE_HAL=yes], [HAVE_HAL=no]) -if test "x$CONFIG_HAL" = xauto; then - CONFIG_HAL="$HAVE_HAL" -fi -if test "x$CONFIG_HAL" = xyes; then - if ! test "x$HAVE_HAL" = xyes; then - AC_MSG_ERROR([HAL hotplug API requested, but HAL is not installed.]) - fi - - AC_DEFINE(CONFIG_HAL, 1, [Use the HAL hotplug API]) - CONFIG_NEED_DBUS="yes" -fi -AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes]) - -if test "x$CONFIG_NEED_DBUS" = xyes; then - AC_DEFINE(CONFIG_NEED_DBUS, 1, [Use D-Bus for input hotplug]) -fi -AM_CONDITIONAL(CONFIG_NEED_DBUS, [test "x$CONFIG_NEED_DBUS" = xyes]) - -if test "x$USE_SIGIO_BY_DEFAULT" = xyes; then - USE_SIGIO_BY_DEFAULT_VALUE=TRUE -else - USE_SIGIO_BY_DEFAULT_VALUE=FALSE -fi -AC_DEFINE_UNQUOTED([USE_SIGIO_BY_DEFAULT], [$USE_SIGIO_BY_DEFAULT_VALUE], - [Use SIGIO handlers for input device events by default]) - -AC_MSG_CHECKING([for glibc...]) -AC_PREPROC_IFELSE([ -#include <features.h> -#ifndef __GLIBC__ -#error -#endif -], glibc=yes, glibc=no) -AC_MSG_RESULT([$glibc]) - -AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes], - [AC_CHECK_LIB([rt], [clock_gettime], [have_clock_gettime=-lrt], - [have_clock_gettime=no])]) - -AC_MSG_CHECKING([for a useful monotonic clock ...]) - -if ! test "x$have_clock_gettime" = xno; then - if ! test "x$have_clock_gettime" = xyes; then - CLOCK_LIBS="$have_clock_gettime" - else - CLOCK_LIBS="" - fi - - LIBS_SAVE="$LIBS" - LIBS="$CLOCK_LIBS" - CPPFLAGS_SAVE="$CPPFLAGS" - - if test x"$glibc" = xyes; then - CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=200112L" - fi - - AC_RUN_IFELSE([ -#include <time.h> - -int main(int argc, char *argv[[]]) { - struct timespec tp; - - if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) - return 0; - else - return 1; -} - ], [MONOTONIC_CLOCK=yes], [MONOTONIC_CLOCK=no], - [MONOTONIC_CLOCK="cross compiling"]) - - LIBS="$LIBS_SAVE" - CPPFLAGS="$CPPFLAGS_SAVE" -else - MONOTONIC_CLOCK=no -fi - -AC_MSG_RESULT([$MONOTONIC_CLOCK]) - -if test "x$MONOTONIC_CLOCK" = xyes; then - AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()]) - LIBS="$LIBS $CLOCK_LIBS" -fi - -AM_CONDITIONAL(XV, [test "x$XV" = xyes]) -if test "x$XV" = xyes; then - AC_DEFINE(XV, 1, [Support Xv extension]) - AC_DEFINE(XvExtension, 1, [Build Xv extension]) - REQUIRED_MODULES="$REQUIRED_MODULES $VIDEOPROTO" -else - XVMC=no -fi - -AM_CONDITIONAL(XVMC, [test "x$XVMC" = xyes]) -if test "x$XVMC" = xyes; then - AC_DEFINE(XvMCExtension, 1, [Build XvMC extension]) -fi - -AM_CONDITIONAL(XREGISTRY, [test "x$XREGISTRY" = xyes]) -if test "x$XREGISTRY" = xyes; then - AC_DEFINE(XREGISTRY, 1, [Build registry module]) -fi - -AM_CONDITIONAL(COMPOSITE, [test "x$COMPOSITE" = xyes]) -if test "x$COMPOSITE" = xyes; then - AC_DEFINE(COMPOSITE, 1, [Support Composite Extension]) - REQUIRED_MODULES="$REQUIRED_MODULES $COMPOSITEPROTO" - COMPOSITE_LIB='$(top_builddir)/composite/libcomposite.la' - COMPOSITE_INC='-I$(top_srcdir)/composite' -fi - -AM_CONDITIONAL(MITSHM, [test "x$MITSHM" = xyes]) -if test "x$MITSHM" = xyes; then - AC_DEFINE(MITSHM, 1, [Support MIT-SHM extension]) - AC_DEFINE(HAS_SHM, 1, [Support SHM]) -fi - -AM_CONDITIONAL(RECORD, [test "x$RECORD" = xyes]) -if test "x$RECORD" = xyes; then - AC_DEFINE(XRECORD, 1, [Support Record extension]) - REQUIRED_MODULES="$REQUIRED_MODULES $RECORDPROTO" - RECORD_LIB='$(top_builddir)/record/librecord.la' -fi - -AM_CONDITIONAL(SCREENSAVER, [test "x$SCREENSAVER" = xyes]) -if test "x$SCREENSAVER" = xyes; then - AC_DEFINE(SCREENSAVER, 1, [Support MIT-SCREEN-SAVER extension]) - REQUIRED_MODULES="$REQUIRED_MODULES $SCRNSAVERPROTO" -fi - -AM_CONDITIONAL(RES, [test "x$RES" = xyes]) -if test "x$RES" = xyes; then - AC_DEFINE(RES, 1, [Support X resource extension]) - REQUIRED_MODULES="$REQUIRED_MODULES $RESOURCEPROTO" -fi - -if test "x$GLX" = xyes; then - PKG_CHECK_MODULES([XLIB], [x11]) - PKG_CHECK_MODULES([GL], $GLPROTO $LIBGL) - AC_SUBST(XLIB_CFLAGS) - AC_DEFINE(GLXEXT, 1, [Build GLX extension]) - GLX_LIBS='$(top_builddir)/glx/libglx.la' - GLX_SYS_LIBS="$GLX_SYS_LIBS" -else - GLX=no -fi -AM_CONDITIONAL(GLX, test "x$GLX" = xyes) - -if test "x$AIGLX" = xyes -a "x$GLX" = xyes -a "x$DRI" = xyes; then - AC_DEFINE(AIGLX, 1, [Build AIGLX loader]) -else - AIGLX=no -fi -AM_CONDITIONAL(AIGLX, test "x$AIGLX" = xyes) - -if test "x$GLX_USE_TLS" = xyes -a "x$AIGLX" = xyes; then - GLX_DEFINES="-DGLX_USE_TLS -DPTHREADS" - GLX_SYS_LIBS="$GLX_SYS_LIBS -lpthread" -fi -AC_SUBST([GLX_DEFINES]) - -AM_CONDITIONAL(DRI, test "x$DRI" = xyes) -if test "x$DRI" = xyes; then - AC_DEFINE(XF86DRI, 1, [Build DRI extension]) - PKG_CHECK_MODULES([DRIPROTO], [$DRIPROTO]) - PKG_CHECK_MODULES([DRI], $GLPROTO $LIBDRI) - AC_SUBST(DRIPROTO_CFLAGS) -fi - -PKG_CHECK_MODULES([DRI2PROTO], $DRI2PROTO, - [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no]) -case "$DRI2,$HAVE_DRI2PROTO" in - yes,no) - AC_MSG_ERROR([DRI2 requested, but dri2proto not found.]) - ;; - yes,yes | auto,yes) - AC_DEFINE(DRI2, 1, [Build DRI2 extension]) - DRI2=yes - ;; -esac -AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes) - -if test "x$DRI" = xyes || test "x$DRI2" = xyes; then - PKG_CHECK_MODULES([LIBDRM], $LIBDRM) - AC_SUBST(LIBDRM_CFLAGS) - AC_SUBST(LIBDRM_LIBS) -fi - -if test "x$DRI2" = xyes; then - save_CFLAGS=$CFLAGS - CFLAGS="$GL_CFLAGS $LIBDRM_CFLAGS" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <GL/gl.h> -#include <GL/internal/dri_interface.h> -#ifndef __DRI_DRI2 -#error DRI2 extension not available. -#endif]])], - [HAVE_DRI2EXTENSION=yes], - [HAVE_DRI2EXTENSION=no]) - CFLAGS=$save_CFLAGS - if test "x$HAVE_DRI2EXTENSION" = xyes; then - AC_DEFINE(DRI2_AIGLX, 1, [Build DRI2 AIGLX loader]) - DRI2_AIGLX=yes - else - AC_MSG_NOTICE([DRI2 AIGLX disabled, __DRI_DRI2 not defined in dri_interface.h.]) - DRI2_AIGLX=no - fi -fi -AM_CONDITIONAL(DRI2_AIGLX, test "x$DRI2_AIGLX" = xyes) - - -AM_CONDITIONAL(XINERAMA, [test "x$XINERAMA" = xyes]) -if test "x$XINERAMA" = xyes; then - AC_DEFINE(XINERAMA, 1, [Support Xinerama extension]) - AC_DEFINE(PANORAMIX, 1, [Internal define for Xinerama]) - REQUIRED_MODULES="$REQUIRED_MODULES $XINERAMAPROTO" -fi - -AM_CONDITIONAL(XACE, [test "x$XACE" = xyes]) -if test "x$XACE" = xyes; then - AC_DEFINE(XACE, 1, [Build X-ACE extension]) -fi - -AM_CONDITIONAL(XSELINUX, [test "x$XSELINUX" = xyes]) -if test "x$XSELINUX" = xyes; then - if test "x$XACE" != xyes; then - AC_MSG_ERROR([cannot build SELinux extension without X-ACE]) - fi - AC_CHECK_HEADERS([libaudit.h], [], AC_MSG_ERROR([SELinux extension requires audit system headers])) - AC_CHECK_LIB(audit, audit_open, [], AC_MSG_ERROR([SELinux extension requires audit system library])) - PKG_CHECK_MODULES([SELINUX], $LIBSELINUX) - SELINUX_LIBS="$SELINUX_LIBS -laudit" - AC_DEFINE(XSELINUX, 1, [Build SELinux extension]) -fi - -AM_CONDITIONAL(XCSECURITY, [test "x$XCSECURITY" = xyes]) -if test "x$XCSECURITY" = xyes; then - if test "x$XACE" != xyes; then - AC_MSG_ERROR([cannot build Security extension without X-ACE]) - fi - AC_DEFINE(XCSECURITY, 1, [Build Security extension]) -fi - -AM_CONDITIONAL(DBE, [test "x$DBE" = xyes]) -if test "x$DBE" = xyes; then - AC_DEFINE(DBE, 1, [Support DBE extension]) - DBE_LIB='$(top_builddir)/dbe/libdbe.la' -fi - -AM_CONDITIONAL(XF86BIGFONT, [test "x$XF86BIGFONT" = xyes]) -if test "x$XF86BIGFONT" = xyes; then - AC_DEFINE(XF86BIGFONT, 1, [Support XF86 Big font extension]) - REQUIRED_MODULES="$REQUIRED_MODULES $BIGFONTPROTO" -fi - -AM_CONDITIONAL(DPMSExtension, [test "x$DPMSExtension" = xyes]) -if test "x$DPMSExtension" = xyes; then - AC_DEFINE(DPMSExtension, 1, [Support DPMS extension]) -fi - -if test "x$XCALIBRATE" = xyes && test "$KDRIVE" = yes; then - AC_DEFINE(XCALIBRATE, 1, [Build XCalibrate extension]) - REQUIRED_MODULES="$REQUIRED_MODULES $XCALIBRATEPROTO" -else - XCALIBRATE=no -fi -AM_CONDITIONAL(XCALIBRATE, [test "x$XCALIBRATE" = xyes]) - -AC_DEFINE(RENDER, 1, [Support RENDER extension]) -RENDER_LIB='$(top_builddir)/render/librender.la' -RENDER_INC='-I$(top_srcdir)/render' - -AC_DEFINE(RANDR, 1, [Support RANDR extension]) -RANDR_LIB='$(top_builddir)/randr/librandr.la' -RANDR_INC='-I$(top_srcdir)/randr' - -AC_DEFINE(XFIXES,1,[Support XFixes extension]) -FIXES_LIB='$(top_builddir)/xfixes/libxfixes.la' -FIXES_INC='-I$(top_srcdir)/xfixes' - -AC_DEFINE(DAMAGE,1,[Support Damage extension]) -DAMAGE_LIB='$(top_builddir)/damageext/libdamageext.la' -DAMAGE_INC='-I$(top_srcdir)/damageext' -MIEXT_DAMAGE_LIB='$(top_builddir)/miext/damage/libdamage.la' -MIEXT_DAMAGE_INC='-I$(top_srcdir)/miext/damage' - -# XINPUT extension is integral part of the server -AC_DEFINE(XINPUT, 1, [Support X Input extension]) -XI_LIB='$(top_builddir)/Xi/libXi.la' -XI_INC='-I$(top_srcdir)/Xi' - -AM_CONDITIONAL(XF86UTILS, test "x$XF86UTILS" = xyes) -AM_CONDITIONAL(XAA, test "x$XAA" = xyes) -AM_CONDITIONAL(VGAHW, test "x$VGAHW" = xyes) -AM_CONDITIONAL(VBE, test "x$VBE" = xyes) -AM_CONDITIONAL(INT10MODULE, test "x$INT10MODULE" = xyes) - -AC_DEFINE(SHAPE, 1, [Support SHAPE extension]) - -AC_DEFINE_DIR(XKB_BASE_DIRECTORY, XKBPATH, [Path to XKB data]) -AC_ARG_WITH(xkb-bin-directory, - AS_HELP_STRING([--with-xkb-bin-directory=DIR], [Directory containing xkbcomp program]), - [XKB_BIN_DIRECTORY="$withval"], - [XKB_BIN_DIRECTORY="$bindir"]) - -AC_DEFINE_DIR(XKB_BIN_DIRECTORY, XKB_BIN_DIRECTORY, [Path to XKB bin dir]) - -dnl Make sure XKM_OUTPUT_DIR is an absolute path -XKBOUTPUT_FIRSTCHAR=`echo $XKBOUTPUT | cut -b 1` -if [[ x$XKBOUTPUT_FIRSTCHAR != x/ -a x$XKBOUTPUT_FIRSTCHAR != 'x$' ]] ; then - XKBOUTPUT="$XKB_BASE_DIRECTORY/$XKBOUTPUT" -fi - -dnl XKM_OUTPUT_DIR (used in code) must end in / or file names get hosed -dnl XKB_COMPILED_DIR (used in Makefiles) must not or install-sh gets confused - -XKBOUTPUT=`echo $XKBOUTPUT/ | $SED 's|/*$|/|'` -XKB_COMPILED_DIR=`echo $XKBOUTPUT | $SED 's|/*$||'` -AC_DEFINE_DIR(XKM_OUTPUT_DIR, XKBOUTPUT, [Path to XKB output dir]) -AC_SUBST(XKB_COMPILED_DIR) - -if test "x$XKB_DFLT_RULES" = x; then - case $host_os in - linux*) - dnl doesn't take AutoAddDevices into account, but whatever. - if test "x$CONFIG_HAL" = xyes; then - XKB_DFLT_RULES="evdev" - else - XKB_DFLT_RULES="base" - fi - ;; - *) - XKB_DFLT_RULES="base" - ;; - esac -fi -AC_DEFINE_UNQUOTED(XKB_DFLT_RULES, ["$XKB_DFLT_RULES"], [Default XKB ruleset]) -AC_DEFINE_UNQUOTED(XKB_DFLT_MODEL, ["$XKB_DFLT_MODEL"], [Default XKB model]) -AC_DEFINE_UNQUOTED(XKB_DFLT_LAYOUT, ["$XKB_DFLT_LAYOUT"], [Default XKB layout]) -AC_DEFINE_UNQUOTED(XKB_DFLT_VARIANT, ["$XKB_DFLT_VARIANT"], [Default XKB variant]) -AC_DEFINE_UNQUOTED(XKB_DFLT_OPTIONS, ["$XKB_DFLT_OPTIONS"], [Default XKB options]) - -XKB_LIB='$(top_builddir)/xkb/libxkb.la' -XKB_STUB_LIB='$(top_builddir)/xkb/libxkbstubs.la' -REQUIRED_MODULES="$REQUIRED_MODULES xkbfile" - -AC_CHECK_FUNC(strcasecmp, [], AC_DEFINE([NEED_STRCASECMP], 1, - [Do not have 'strcasecmp'.])) -AC_CHECK_FUNC(strncasecmp, [], AC_DEFINE([NEED_STRNCASECMP], 1, - [Do not have 'strncasecmp'.])) -AC_CHECK_FUNC(strcasestr, [], AC_DEFINE([NEED_STRCASESTR], 1, - [Do not have 'strcasestr'.])) - -PKG_CHECK_MODULES([XDMCP], [xdmcp], [have_libxdmcp="yes"], [have_libxdmcp="no"]) -if test "x$have_libxdmcp" = xyes; then - AC_CHECK_LIB(Xdmcp, XdmcpWrap, [have_xdmcpwrap="yes"], [have_xdmcpwrap="no"], [$XDMCP_LIBS]) -fi -if test "x$XDMCP" = xauto; then - if test "x$have_libxdmcp" = xyes; then - XDMCP=yes - else - XDMCP=no - fi -fi -if test "x$XDMAUTH" = xauto; then - if test "x$have_libxdmcp" = xyes && test "x$have_xdmcpwrap" = xyes; then - XDMAUTH=yes - else - XDMAUTH=no - fi -fi - -AM_CONDITIONAL(XDMCP, [test "x$XDMCP" = xyes]) -if test "x$XDMCP" = xyes; then - AC_DEFINE(XDMCP, 1, [Support XDM Control Protocol]) - REQUIRED_LIBS="$REQUIRED_LIBS xdmcp" - XDMCP_MODULES="xdmcp" -fi - -AM_CONDITIONAL(XDMAUTH, [test "x$XDMAUTH" = xyes]) -if test "x$XDMAUTH" = xyes; then - AC_DEFINE(HASXDMAUTH,1,[Support XDM-AUTH*-1]) - if ! test "x$XDMCP" = xyes; then - REQUIRED_LIBS="$REQUIRED_LIBS xdmcp" - XDMCP_MODULES="xdmcp" - fi -fi - -AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path]) -AC_DEFINE_DIR(PCI_TXT_IDS_PATH, PCI_TXT_IDS_DIR, [Default PCI text file ID path]) -AC_DEFINE_DIR(SERVER_MISC_CONFIG_PATH, SERVERCONFIG, [Server miscellaneous config path]) -AC_DEFINE_DIR(BASE_FONT_PATH, FONTROOTDIR, [Default base font path]) -AC_DEFINE_DIR(DRI_DRIVER_PATH, DRI_DRIVER_PATH, [Default DRI driver path]) -AC_DEFINE_UNQUOTED(XVENDORNAME, ["$VENDOR_NAME"], [Vendor name]) -AC_DEFINE_UNQUOTED(XVENDORNAMESHORT, ["$VENDOR_NAME_SHORT"], [Short vendor name]) -AC_DEFINE_UNQUOTED(XORG_DATE, ["$RELEASE_DATE"], [Vendor release]) -AC_DEFINE_UNQUOTED(XORG_MAN_VERSION, ["$VENDOR_MAN_VERSION"], [Vendor man version]) -AC_DEFINE_UNQUOTED(BUILDERADDR, ["$BUILDERADDR"], [Builder address]) - -if test -z "$OSNAME"; then - OSNAME="UNKNOWN" -fi - -AC_DEFINE_UNQUOTED(OSNAME, ["$OSNAME"], [Operating System Name]) -AC_DEFINE_UNQUOTED(OSVENDOR, ["$OSVENDOR"], [Operating System Vendor]) -AC_DEFINE_UNQUOTED(BUILDERSTRING, ["$BUILDERSTRING"], [Builder string]) - -AC_SUBST([VENDOR_NAME_SHORT]) -AC_DEFINE_UNQUOTED(VENDOR_NAME, ["$VENDOR_NAME"], [Vendor name]) -AC_DEFINE_UNQUOTED(VENDOR_NAME_SHORT, ["$VENDOR_NAME_SHORT"], [Vendor name]) -AC_DEFINE_UNQUOTED(VENDOR_RELEASE, [$VENDOR_RELEASE], [Vendor release]) -AC_DEFINE_UNQUOTED(VENDOR_MAN_VERSION, ["$VENDOR_MAN_VERSION"], [Vendor man version]) - -AC_DEFINE(NO_LIBCWRAPPER, 1, [Define to 1 if modules should avoid the libcwrapper]) - -if test "x$DEBUGGING" = xyes; then - AC_DEFINE(DEBUG, 1, [Enable debugging code]) -fi -AM_CONDITIONAL(DEBUG, [test "x$DEBUGGING" = xyes]) - -# If unittests aren't explicitly disabled, check for required support -if test "x$UNITTESTS" != xno ; then - PKG_CHECK_MODULES([GLIB], $LIBGLIB, - [HAVE_GLIB=yes], [HAVE_GLIB=no]) - - # Check if linker supports -wrap, passed via compiler flags - # When cross-compiling, reports no, since unit tests run from - # "make check", so would be running on build machine, not target - AC_MSG_CHECKING([whether the linker supports -wrap]) - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -Wl,-wrap,exit" - AC_RUN_IFELSE([AC_LANG_PROGRAM([[ - void __wrap_exit (int s) - { - __real_exit (0); - }]], - [[exit (1);]])], - [linker_can_wrap="yes"], - [linker_can_wrap="no"], - [linker_can_wrap="no"]) - AC_MSG_RESULT([$linker_can_wrap]) - LDFLAGS="$save_LDFLAGS" -fi - -if test "x$UNITTESTS" = xauto; then - if test "x$HAVE_GLIB" = xyes && test "x$linker_can_wrap" = xyes; then - UNITTESTS=yes - else - UNITTESTS=no - fi -fi -if test "x$UNITTESTS" = xyes; then - if test "x$HAVE_GLIB" = xno; then - AC_MSG_ERROR([glib required to build unit tests]) - fi - if test "x$linker_can_wrap" = xno; then - AC_MSG_ERROR([ld -wrap support required to build unit tests]) - fi - AC_DEFINE(UNITTESTS, 1, [Enable unit tests]) - AC_SUBST([GLIB_LIBS]) - AC_SUBST([GLIB_CFLAGS]) -fi -AM_CONDITIONAL(UNITTESTS, [test "x$UNITTESTS" = xyes]) - -AC_DEFINE(XTEST, 1, [Support XTest extension]) -AC_DEFINE(XSYNC, 1, [Support XSync extension]) -AC_DEFINE(XCMISC, 1, [Support XCMisc extension]) -AC_DEFINE(BIGREQS, 1, [Support BigRequests extension]) - -if test "x$SPECIAL_DTRACE_OBJECTS" = "xyes" ; then - DIX_LIB='$(top_builddir)/dix/dix.O' - OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS)' -else - DIX_LIB='$(top_builddir)/dix/libdix.la' - OS_LIB='$(top_builddir)/os/libos.la' -fi -AC_SUBST([DIX_LIB]) -AC_SUBST([OS_LIB]) - -MAIN_LIB='$(top_builddir)/dix/libmain.la' -AC_SUBST([MAIN_LIB]) - -MI_LIB='$(top_builddir)/mi/libmi.la' -MI_EXT_LIB='$(top_builddir)/mi/libmiext.la' -MI_INC='-I$(top_srcdir)/mi' -FB_LIB='$(top_builddir)/fb/libfb.la' -FB_INC='-I$(top_srcdir)/fb' -MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/shadow' -MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la' -CORE_INCS='-I$(top_srcdir)/include -I$(top_builddir)/include' - -# SHA1 hashing -AC_ARG_WITH([sha1], - [AS_HELP_STRING([--with-sha1=libc|libmd|libgcrypt|libcrypto|libsha1|CommonCrypto], - [choose SHA1 implementation])]) -AC_CHECK_FUNC([SHA1Init], [HAVE_SHA1_IN_LIBC=yes]) -if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_LIBC" = xyes; then - with_sha1=libc -fi -if test "x$with_sha1" = xlibc && test "x$HAVE_SHA1_IN_LIBC" != xyes; then - AC_MSG_ERROR([libc requested but not found]) -fi -if test "x$with_sha1" = xlibc; then - AC_DEFINE([HAVE_SHA1_IN_LIBC], [1], - [Use libc SHA1 functions]) - SHA1_LIBS="" -fi -AC_CHECK_FUNC([CC_SHA1_Init], [HAVE_SHA1_IN_COMMONCRYPTO=yes]) -if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_COMMONCRYPTO" = xyes; then - with_sha1=CommonCrypto -fi -if test "x$with_sha1" = xCommonCrypto && test "x$HAVE_SHA1_IN_COMMONCRYPTO" != xyes; then - AC_MSG_ERROR([CommonCrypto requested but not found]) -fi -if test "x$with_sha1" = xCommonCrypto; then - AC_DEFINE([HAVE_SHA1_IN_COMMONCRYPTO], [1], - [Use CommonCrypto SHA1 functions]) - SHA1_LIBS="" -fi -AC_CHECK_LIB([md], [SHA1Init], [HAVE_LIBMD=yes]) -if test "x$with_sha1" = x && test "x$HAVE_LIBMD" = xyes; then - with_sha1=libmd -fi -if test "x$with_sha1" = xlibmd && test "x$HAVE_LIBMD" != xyes; then - AC_MSG_ERROR([libmd requested but not found]) -fi -if test "x$with_sha1" = xlibmd; then - AC_DEFINE([HAVE_SHA1_IN_LIBMD], [1], - [Use libmd SHA1 functions]) - SHA1_LIBS=-lmd -fi -AC_CHECK_LIB([sha1], [sha1_begin], [HAVE_LIBSHA1=yes]) -if test "x$with_sha1" = x && test "x$HAVE_LIBSHA1" = xyes; then - with_sha1=libsha1 -fi -if test "x$with_sha1" = xlibsha1 && test "x$HAVE_LIBSHA1" != xyes; then - AC_MSG_ERROR([libsha1 requested but not found]) -fi -if test "x$with_sha1" = xlibsha1; then - AC_DEFINE([HAVE_SHA1_IN_LIBSHA1], [1], - [Use libsha1 for SHA1]) - SHA1_LIBS=-lsha1 -fi -AC_CHECK_LIB([gcrypt], [gcry_md_open], [HAVE_LIBGCRYPT=yes]) -if test "x$with_sha1" = x && test "x$HAVE_LIBGCRYPT" = xyes; then - with_sha1=libgcrypt -fi -if test "x$with_sha1" = xlibgcrypt && test "x$HAVE_LIBGCRYPT" != xyes; then - AC_MSG_ERROR([libgcrypt requested but not found]) -fi -if test "x$with_sha1" = xlibgcrypt; then - AC_DEFINE([HAVE_SHA1_IN_LIBGCRYPT], [1], - [Use libgcrypt SHA1 functions]) - SHA1_LIBS=-lgcrypt -fi -# We don't need all of the OpenSSL libraries, just libcrypto -AC_CHECK_LIB([crypto], [SHA1_Init], [HAVE_LIBCRYPTO=yes]) -PKG_CHECK_MODULES([OPENSSL], [openssl], [HAVE_OPENSSL_PKC=yes], - [HAVE_OPENSSL_PKC=no]) -if test "x$HAVE_LIBCRYPTO" = xyes || test "x$HAVE_OPENSSL_PKC" = xyes; then - if test "x$with_sha1" = x; then - with_sha1=libcrypto - fi -else - if test "x$with_sha1" = xlibcrypto; then - AC_MSG_ERROR([OpenSSL libcrypto requested but not found]) - fi -fi -if test "x$with_sha1" = xlibcrypto; then - if test "x$HAVE_LIBCRYPTO" = xyes; then - SHA1_LIBS=-lcrypto - else - SHA1_LIBS="$OPENSSL_LIBS" - SHA1_CFLAGS="$OPENSSL_CFLAGS" - fi -fi -AC_MSG_CHECKING([for SHA1 implementation]) -if test "x$with_sha1" = x; then - AC_MSG_ERROR([No suitable SHA1 implementation found]) -fi -AC_MSG_RESULT([$with_sha1]) -AC_SUBST(SHA1_LIBS) -AC_SUBST(SHA1_CFLAGS) - -PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQUIRED_MODULES $REQUIRED_LIBS]) -PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS]) - -# Autotools has some unfortunate issues with library handling. In order to -# get a server to rebuild when a dependency in the tree is changed, it must -# be listed in SERVERNAME_DEPENDENCIES. However, no system libraries may be -# listed there, or some versions of autotools will break (especially if a -L -# is required to find the library). So, we keep two sets of libraries -# detected: NAMESPACE_LIBS for in-tree libraries to be linked against, which -# will go into the _DEPENDENCIES and _LDADD of the server, and -# NAMESPACE_SYS_LIBS which will go into only the _LDADD. The -# NAMESPACEMODULES_LIBS detected from pkgconfig should always go in -# NAMESPACE_SYS_LIBS. -# -# XSERVER_LIBS is the set of in-tree libraries which all servers require. -# XSERVER_SYS_LIBS is the set of out-of-tree libraries which all servers -# require. -# -XSERVER_CFLAGS="${XSERVER_CFLAGS} ${XSERVERCFLAGS_CFLAGS}" -XSERVER_LIBS="$DIX_LIB $MI_LIB $OS_LIB" -XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}" -AC_SUBST([XSERVER_LIBS]) -AC_SUBST([XSERVER_SYS_LIBS]) - -UTILS_SYS_LIBS="${SYS_LIBS}" -AC_SUBST([UTILS_SYS_LIBS]) - -# The Xorg binary needs to export symbols so that they can be used from modules -# Some platforms require extra flags to do this. libtool should set the -# necessary flags for each platform when -export-dynamic is passed to it. -LD_EXPORT_SYMBOLS_FLAG="-export-dynamic" -AC_SUBST([LD_EXPORT_SYMBOLS_FLAG]) - -dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so -dnl we need to replicate that here until those can all be fixed -AC_MSG_CHECKING([if SVR4 needs to be defined]) -AC_EGREP_CPP([I_AM_SVR4],[ -#if defined(SVR4) || defined(__svr4__) || defined(__SVR4) - I_AM_SVR4 -#endif -],[ -AC_DEFINE([SVR4],1,[Define to 1 on systems derived from System V Release 4]) -AC_MSG_RESULT([yes])], AC_MSG_RESULT([no])) - -XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC" - -dnl --------------------------------------------------------------------------- -dnl DDX section. -dnl --------------------------------------------------------------------------- - -dnl Xvfb DDX - -AC_MSG_CHECKING([whether to build Xvfb DDX]) -AC_MSG_RESULT([$XVFB]) -AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes]) - -if test "x$XVFB" = xyes; then - XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB" - XVFB_SYS_LIBS="$XVFBMODULES_LIBS $GLX_SYS_LIBS" - AC_SUBST([XVFB_LIBS]) - AC_SUBST([XVFB_SYS_LIBS]) -fi - - -dnl Xnest DDX - -PKG_CHECK_MODULES(XNESTMODULES, [xfont $LIBXEXT x11 xau $XDMCP_MODULES], [have_xnest=yes], [have_xnest=no]) -AC_MSG_CHECKING([whether to build Xnest DDX]) -if test "x$XNEST" = xauto; then - XNEST="$have_xnest" -fi -AC_MSG_RESULT([$XNEST]) -AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes]) - -if test "x$XNEST" = xyes; then - if test "x$have_xnest" = xno; then - AC_MSG_ERROR([Xnest build explicitly requested, but required modules not found.]) - fi - XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DIX_LIB $MAIN_LIB $OS_LIB" - XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS" - AC_SUBST([XNEST_LIBS]) - AC_SUBST([XNEST_SYS_LIBS]) -fi - - -dnl Xorg DDX - -AC_MSG_CHECKING([whether to build Xorg DDX]) -if test "x$XORG" = xauto; then - XORG="yes" - case $host_os in - cygwin*) XORG="no" ;; - darwin*) XORG="no" ;; - esac -fi -AC_MSG_RESULT([$XORG]) - -xorg_bus_linuxpci=no -xorg_bus_bsdpci=no -xorg_bus_sparc=no - -if test "x$XORG" = xyes; then - XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common' - XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os' - XORG_INCS="$XORG_DDXINCS $XORG_OSINCS" - XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H" - XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB" - - dnl ================================================================== - dnl symbol visibility - symbol_visibility= - have_visibility=disabled - if test x$SYMBOL_VISIBILITY != xno; then - AC_MSG_CHECKING(for symbol visibility support) - if test x$GCC = xyes; then - VISIBILITY_CFLAGS="-fvisibility=hidden" - else - AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"]) - if test x$SUNCC = xyes; then - VISIBILITY_CFLAGS="-xldscope=hidden" - else - have_visibility=no - fi - fi - if test x$have_visibility != xno; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $VISIBILITY_CFLAGS" - AC_TRY_COMPILE( - [#include <X11/Xfuncproto.h> - extern _X_HIDDEN int hidden_int; - extern _X_EXPORT int public_int; - extern _X_HIDDEN int hidden_int_func(void); - extern _X_EXPORT int public_int_func(void);], - [], - have_visibility=yes, - have_visibility=no) - CFLAGS=$save_CFLAGS - fi - AC_MSG_RESULT([$have_visibility]) - if test x$have_visibility != xno; then - symbol_visibility=$VISIBILITY_CFLAGS - XORG_CFLAGS="$XORG_CFLAGS $VISIBILITY_CFLAGS" - XSERVER_CFLAGS="$XSERVER_CFLAGS $VISIBILITY_CFLAGS" - fi - fi - dnl added to xorg-server.pc - AC_SUBST([symbol_visibility]) - dnl =================================================================== - - PKG_CHECK_MODULES([PCIACCESS], $LIBPCIACCESS) - SAVE_LIBS=$LIBS - SAVE_CFLAGS=$CFLAGS - CFLAGS=$PCIACCESS_CFLAGS - LIBS=$PCIACCESS_LIBS - AC_CHECK_FUNCS([pci_system_init_dev_mem]) - AC_CHECK_FUNCS([pci_device_enable]) - AC_CHECK_FUNCS([pci_device_is_boot_vga]) - AC_CHECK_FUNCS([pci_device_vgaarb_init]) - LIBS=$SAVE_LIBS - CFLAGS=$SAVE_CFLAGS - XORG_SYS_LIBS="$XORG_SYS_LIBS $PCIACCESS_LIBS $GLX_SYS_LIBS" - XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS" - - case $host_os in - linux*) - if test "x$LNXAPM" = xyes; then - XORG_CFLAGS="$XORG_CFLAGS -DXF86PM" - fi - XORG_OS="linux" - XORG_OS_SUBDIR="linux" - xorg_bus_linuxpci="yes" - linux_acpi="no" - case $host_cpu in - ia64*) - linux_ia64=yes - linux_acpi="yes" - ;; - alpha*) - linux_alpha=yes - ;; - i*86|amd64*|x86_64*) - linux_acpi="yes" - ;; - *) - ;; - esac - ;; - freebsd* | kfreebsd*-gnu | dragonfly*) - XORG_OS="freebsd" - XORG_OS_SUBDIR="bsd" - xorg_bus_bsdpci="yes" - ;; - netbsd*) - XORG_OS="netbsd" - XORG_OS_SUBDIR="bsd" - xorg_bus_bsdpci="yes" - ;; - openbsd*) - if test "x$ac_cv_BSD_APM" = xyes \ - -o "x$ac_cv_BSD_KQUEUE_APM" = xyes; then - XORG_CFLAGS="$XORG_CFLAGS -DXF86PM" - fi - XORG_OS="openbsd" - XORG_OS_SUBDIR="bsd" - xorg_bus_bsdpci="yes" - ;; - solaris*) - XORG_OS="solaris" - XORG_OS_SUBDIR="solaris" - XORG_CFLAGS="$XORG_CFLAGS -DXF86PM" - # Use the same stubs as BSD for old functions, since we now - # use libpciaccess for PCI - xorg_bus_bsdpci="yes" - AC_CHECK_HEADERS([sys/kd.h]) - AC_CHECK_HEADERS([sys/vt.h], [solaris_vt=yes], [solaris_vt=no]) - # Check for minimum supported release - AC_MSG_CHECKING([Solaris version]) - OS_MINOR=`echo ${host_os}|$SED -e 's/^.*solaris2\.//' -e s'/\..*$//'` - if test "${OS_MINOR}" -ge 7 ; then - AC_MSG_RESULT(Solaris ${OS_MINOR}) - else - AC_MSG_RESULT(Solaris `echo ${host_os}|$SED -e 's/^.*solaris//`) - fi - if test "${OS_MINOR}" -lt 8 ; then - AC_MSG_ERROR([This release no longer supports Solaris versions older than Solaris 8.]) - fi - AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"]) - if test "x$SUNCC" = "xyes"; then - solaris_asm_inline="yes" - fi - AC_CHECK_DECL([_LP64], [SOLARIS_64="yes"], [SOLARIS_64="no"]) - - case $host_cpu in - sparc*) - SOLARIS_INOUT_ARCH="sparcv8plus" - ;; - i*86) - if test x$SOLARIS_64 = xyes ; then - SOLARIS_INOUT_ARCH="amd64" - else - SOLARIS_INOUT_ARCH="ia32" - fi - ;; - *) - AC_MSG_ERROR([Unsupported Solaris platform. Only SPARC & x86 \ - are supported on Solaris in this release. If you are \ - interested in porting Xorg to your platform, please email \ - xorg@lists.freedesktop.org.]) ;; - esac - AC_SUBST([SOLARIS_INOUT_ARCH]) - if test x$solaris_asm_inline = xyes ; then - SOLARIS_ASM_CFLAGS='$(top_srcdir)/hw/xfree86/os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il' - XORG_CFLAGS="${XORG_CFLAGS} "'$(SOLARIS_ASM_CFLAGS)' - fi - AC_SUBST([SOLARIS_ASM_CFLAGS]) - if test "x$SUPPORT_PC98" = xauto; then - SUPPORT_PC98="no" - fi - ;; - gnu*) - XORG_OS="gnu" - XORG_OS_SUBDIR="hurd" - # Use the same stubs as BSD for old functions, since we now - # use libpciaccess for PCI - xorg_bus_bsdpci="yes" - ;; - *) - XORG_OS="unknown" - XORG_OS_SUBDIR="unknown" - AC_MSG_ERROR([m4_text_wrap(m4_join([ ], - [Your OS is unknown. Xorg currently only supports Linux,], - [Free/Open/Net/DragonFlyBSD, Solaris/OpenSolaris, & GNU Hurd.], - [If you are interested in porting Xorg to your platform,], - [please email xorg@lists.freedesktop.org.]))]) - ;; - esac - - case $host_cpu in - sparc*) - xorg_bus_sparc="yes" - ;; - i*86) - if test "x$SUPPORT_PC98" = xauto; then - SUPPORT_PC98="yes" - fi - ;; - esac - - if test "x$SUPPORT_PC98" = xauto; then - SUPPORT_PC98="no" - fi - if test "x$SUPPORT_PC98" = xyes; then - AC_DEFINE(SUPPORT_PC98, 1, [Support PC98]) - fi - if test "x$XORG_OS_PCI" = x ; then - XORG_OS_PCI=$XORG_OS - fi - if test "x$DGA" = xauto; then - PKG_CHECK_MODULES(DGA, $DGAPROTO, [DGA=yes], [DGA=no]) - fi - if test "x$DGA" = xyes; then - XORG_MODULES="$XORG_MODULES $DGAPROTO" - PKG_CHECK_MODULES(DGA, $DGAPROTO) - AC_DEFINE(DGA, 1, [Support DGA extension]) - AC_DEFINE(XFreeXDGA, 1, [Build XDGA support]) - fi - - if test "x$XF86VIDMODE" = xauto; then - PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO, [XF86VIDMODE=yes], [XF86VIDMODE=no]) - fi - if test "x$XF86VIDMODE" = xyes; then - XORG_MODULES="$XORG_MODULES $VIDMODEPROTO" - PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO) - AC_DEFINE(XF86VIDMODE, 1, [Support XFree86 Video Mode extension]) - fi - - if test -n "$XORG_MODULES"; then - PKG_CHECK_MODULES(XORG_MODULES, [$XORG_MODULES]) - XORG_CFLAGS="$XORG_CFLAGS $XORG_MODULES_CFLAGS" - XORG_SYS_LIBS="$XORG_SYS_LIBS $XORG_MODULES_LIBS" - fi - - AC_SUBST([XORG_LIBS]) - AC_SUBST([XORG_SYS_LIBS]) - AC_SUBST([XORG_INCS]) - AC_SUBST([XORG_OS]) - AC_SUBST([XORG_OS_SUBDIR]) - - AC_PATH_PROG(PERL, perl, no) - dnl unlikely as this may be ... - if test "x$PERL" = xno; then - AC_MSG_ERROR([Perl is required to build the XFree86/Xorg DDX.]) - fi - AC_SUBST(PERL) - - AC_SUBST([XORG_CFLAGS]) - - dnl these only go in xorg-config.h - XF86CONFIGFILE="xorg.conf" - XF86CONFIGDIR="xorg.conf.d" - AC_SUBST(XF86CONFIGDIR) - CONFIGFILE="$sysconfdir/$XF86CONFIGFILE" - LOGPREFIX="$logdir/Xorg." - AC_DEFINE(XORG_SERVER, 1, [Building Xorg server]) - AC_DEFINE(XORGSERVER, 1, [Building Xorg server]) - AC_DEFINE(XFree86Server, 1, [Building XFree86 server]) - AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server]) - AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version]) - AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs]) - AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions]) - AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server]) - AC_DEFINE_DIR(__XCONFIGFILE__, XF86CONFIGFILE, [Name of configuration file]) - AC_DEFINE_DIR(XF86CONFIGFILE, XF86CONFIGFILE, [Name of configuration file]) - AC_DEFINE_DIR(__XCONFIGDIR__, XF86CONFIGDIR, [Name of configuration directory]) - AC_DEFINE_DIR(DEFAULT_MODULE_PATH, moduledir, [Default module search path]) - AC_DEFINE_DIR(DEFAULT_LIBRARY_PATH, libdir, [Default library install path]) - AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default log location]) - AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support]) - AC_DEFINE(XSERVER_LIBPCIACCESS, 1, [Use libpciaccess for all pci manipulation]) - if test "x$VGAHW" = xyes; then - AC_DEFINE(WITH_VGAHW, 1, [Building vgahw module]) - fi - - driverdir="$moduledir/drivers" - AC_SUBST([moduledir]) - AC_SUBST([driverdir]) - sdkdir="$includedir/xorg" - extdir="$includedir/X11/extensions" - sysconfigdir="$datadir/X11/$XF86CONFIGDIR" - AC_SUBST([sdkdir]) - AC_SUBST([extdir]) - AC_SUBST([sysconfigdir]) - AC_SUBST([logdir]) - - # stuff the ABI versions into the pc file too - extract_abi() { - grep ^.define.*${1}_VERSION ${srcdir}/hw/xfree86/common/xf86Module.h | tr '(),' ' .' | awk '{ print $4$5 }' - } - abi_ansic=`extract_abi ANSIC` - abi_videodrv=`extract_abi VIDEODRV` - abi_xinput=`extract_abi XINPUT` - abi_extension=`extract_abi EXTENSION` - AC_SUBST([abi_ansic]) - AC_SUBST([abi_videodrv]) - AC_SUBST([abi_xinput]) - AC_SUBST([abi_extension]) -fi -AM_CONDITIONAL([XORG], [test "x$XORG" = xyes]) -AM_CONDITIONAL([XORG_BUS_LINUXPCI], [test "x$xorg_bus_linuxpci" = xyes]) -AM_CONDITIONAL([XORG_BUS_BSDPCI], [test "x$xorg_bus_bsdpci" = xyes]) -AM_CONDITIONAL([XORG_BUS_SPARC], [test "x$xorg_bus_sparc" = xyes]) -AM_CONDITIONAL([LINUX_IA64], [test "x$linux_ia64" = xyes]) -AM_CONDITIONAL([LINUX_ALPHA], [test "x$linux_alpha" = xyes]) -AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes]) -AM_CONDITIONAL([SOLARIS_ASM_INLINE], [test "x$solaris_asm_inline" = xyes]) -AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes]) -AM_CONDITIONAL([DGA], [test "x$DGA" = xyes]) -AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes]) - -dnl XWin DDX - -AC_MSG_CHECKING([whether to build XWin DDX]) -if test "x$XWIN" = xauto; then - case $host_os in - cygwin*) XWIN="yes" ;; - mingw*) XWIN="yes" ;; - *) XWIN="no" ;; - esac -fi -AC_MSG_RESULT([$XWIN]) - -if test "x$XWIN" = xyes; then - AC_DEFINE_DIR(SYSCONFDIR, sysconfdir, [Location of system.XWinrc]) - AC_DEFINE_DIR(DEFAULT_LOGDIR, logdir, [Default log location]) - AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version]) - AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support]) - AC_CHECK_TOOL(WINDRES, windres) - - PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfont]) - - if test "x$WINDOWSWM" = xauto; then - PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no]) - fi - if test "x$WINDOWSWM" = xyes ; then - PKG_CHECK_MODULES(WINDOWSWM, $WINDOWSWMPROTO) - XWINMODULES_CFLAGS="$XWINMODULES_CFLAGS $WINDOWSWM_CFLAGS" - AC_DEFINE(ROOTLESS,1,[Build Rootless code]) - fi - - case $host_os in - cygwin*) - XWIN_SERVER_NAME=XWin - AC_DEFINE(HAS_DEVWINDOWS,1,[Cygwin has /dev/windows for signaling new win32 messages]) - ;; - mingw*) - XWIN_SERVER_NAME=Xming - AC_DEFINE(RELOCATE_PROJECTROOT,1,[Make PROJECT_ROOT relative to the xserver location]) - AC_DEFINE(HAS_WINSOCK,1,[Use Windows sockets]) - XWIN_SYS_LIBS=-lwinsock2 - ;; - esac - XWIN_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $RANDR_LIB $RENDER_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $OS_LIB" - XWIN_SYS_LIBS="$XWIN_SYS_LIBS $XWINMODULES_LIBS" - AC_SUBST(XWIN_LIBS) - AC_SUBST(XWIN_SERVER_NAME) - AC_SUBST(XWIN_SYS_LIBS) - - if test "x$DEBUGGING" = xyes; then - AC_DEFINE(CYGDEBUG, 1, [Simple debug messages]) - AC_DEFINE(CYGWINDOWING_DEBUG, 1, [Debug messages for window handling]) - AC_DEFINE(CYGMULTIWINDOW_DEBUG, 1, [Debug window manager]) - fi - - AC_DEFINE(DDXOSVERRORF, 1, [Use OsVendorVErrorF]) - AC_DEFINE(DDXBEFORERESET, 1, [Use ddxBeforeReset ]) -fi -AM_CONDITIONAL(XWIN, [test "x$XWIN" = xyes]) -AM_CONDITIONAL(XWIN_MULTIWINDOW, [test "x$XWIN" = xyes]) -AM_CONDITIONAL(XWIN_MULTIWINDOWEXTWM, [test "x$XWIN" = xyes && test "x$WINDOWSWM" = xyes]) -AM_CONDITIONAL(XWIN_CLIPBOARD, [test "x$XWIN" = xyes]) -AM_CONDITIONAL(XWIN_GLX_WINDOWS, [test "x$XWIN" = xyes && false]) -AM_CONDITIONAL(XWIN_NATIVEGDI, [test "x$XWIN" = xyes && false]) -AM_CONDITIONAL(XWIN_PRIMARYFB, [test "x$XWIN" = xyes && false]) -AM_CONDITIONAL(XWIN_RANDR, [test "x$XWIN" = xyes]) -AM_CONDITIONAL(XWIN_XV, [test "x$XWIN" = xyes && test "x$XV" = xyes]) - -dnl Darwin / OS X DDX -if test "x$XQUARTZ" = xyes; then - AC_DEFINE(XQUARTZ,1,[Have Quartz]) - AC_DEFINE(ROOTLESS,1,[Build Rootless code]) - - DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB" - AC_SUBST([DARWIN_LIBS]) - - AC_CHECK_LIB([Xplugin],[xp_init],[:]) - - CFLAGS="${CFLAGS} -DROOTLESS_WORKAROUND -DROOTLESS_SAFEALPHA -DNO_ALLOCA" - - PKG_CHECK_MODULES(XPBPROXY, $APPLEWMPROTO $LIBAPPLEWM xfixes x11) - - if test "x$XQUARTZ_SPARKLE" = xyes ; then - AC_DEFINE(XQUARTZ_SPARKLE,1,[Support application updating through sparkle.]) - fi - - if test "x$STANDALONE_XPBPROXY" = xyes ; then - AC_DEFINE(STANDALONE_XPBPROXY,1,[Build a standalone xpbproxy]) - fi -fi - -# Support for objc in autotools is minimal and not documented. -OBJC='$(CC)' -OBJCLD='$(CCLD)' -OBJCLINK='$(LINK)' -OBJCFLAGS='$(CFLAGS)' -AC_SUBST([OBJC]) -AC_SUBST([OBJCCLD]) -AC_SUBST([OBJCLINK]) -AC_SUBST([OBJCFLAGS]) -# internal, undocumented automake func follows :( -_AM_DEPENDENCIES([OBJC]) -AM_CONDITIONAL(XQUARTZ, [test "x$XQUARTZ" = xyes]) -AM_CONDITIONAL(XQUARTZ_SPARKLE, [test "x$XQUARTZ_SPARKLE" != "xno"]) -AM_CONDITIONAL(STANDALONE_XPBPROXY, [test "x$STANDALONE_XPBPROXY" = xyes]) - -dnl DMX DDX -PKG_CHECK_MODULES( - [DMXMODULES], - [xmuu $LIBXEXT x11 xrender xfixes xfont $LIBXI $DMXPROTO xau $XDMCP_MODULES], - [PKG_CHECK_MODULES( - [XDMXCONFIG_DEP], - [xaw7 xmu xt xpm x11], - [have_dmx=yes], - [have_dmx=no])], - [have_dmx=no]) -AC_MSG_CHECKING([whether to build Xdmx DDX]) -if test "x$DMX" = xauto; then - DMX="$have_dmx" - case $host_os in - cygwin*) DMX="no" ;; - darwin*) DMX="no" ;; - esac -fi -AC_MSG_RESULT([$DMX]) -AM_CONDITIONAL(DMX, [test "x$DMX" = xyes]) - -if test "x$DMX" = xyes; then - if test "x$have_dmx" = xno; then - AC_MSG_ERROR([Xdmx build explicitly requested, but required - modules not found.]) - fi - DMX_INCLUDES="$XEXT_INC $RENDER_INC $RECORD_INC" - XDMX_CFLAGS="$DMXMODULES_CFLAGS" - XDMX_LIBS="$FB_LIB $MI_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $XEXT_LIB $MAIN_LIB $DIX_LIB $OS_LIB $FIXES_LIB" - XDMX_SYS_LIBS="$DMXMODULES_LIBS" - AC_SUBST([XDMX_CFLAGS]) - AC_SUBST([XDMX_LIBS]) - AC_SUBST([XDMX_SYS_LIBS]) - -dnl USB sources in DMX require <linux/input.h> - AC_CHECK_HEADER([linux/input.h], DMX_BUILD_USB="yes", - DMX_BUILD_USB="no") -dnl Linux sources in DMX require <linux/keyboard.h> - AC_CHECK_HEADER([linux/keyboard.h], DMX_BUILD_LNX="yes", - DMX_BUILD_LNX="no") - AC_SUBST(XDMXCONFIG_DEP_CFLAGS) - AC_SUBST(XDMXCONFIG_DEP_LIBS) - PKG_CHECK_MODULES([DMXEXAMPLES_DEP], [$LIBDMX $LIBXEXT x11]) - AC_SUBST(DMXEXAMPLES_DEP_LIBS) - PKG_CHECK_MODULES([DMXXMUEXAMPLES_DEP], [$LIBDMX xmu $LIBXEXT x11]) - AC_SUBST(DMXXMUEXAMPLES_DEP_LIBS) - PKG_CHECK_MODULES([DMXXIEXAMPLES_DEP], [$LIBDMX $LIBXI $LIBXEXT x11]) - AC_SUBST(DMXXIEXAMPLES_DEP_LIBS) - PKG_CHECK_MODULES([XTSTEXAMPLES_DEP], [$LIBXTST $LIBXEXT x11]) - AC_SUBST(XTSTEXAMPLES_DEP_LIBS) - PKG_CHECK_MODULES([XRESEXAMPLES_DEP], [xres $LIBXEXT x11]) - AC_SUBST(XRESEXAMPLES_DEP_LIBS) - PKG_CHECK_MODULES([X11EXAMPLES_DEP], [$LIBXEXT x11]) - AC_SUBST(X11EXAMPLES_DEP_LIBS) - -fi -AM_CONDITIONAL([DMX_BUILD_LNX], [test "x$DMX_BUILD_LNX" = xyes]) -AM_CONDITIONAL([DMX_BUILD_USB], [test "x$DMX_BUILD_USB" = xyes]) - -dnl kdrive DDX - -XEPHYR_LIBS= -XEPHYR_INCS= - -AM_CONDITIONAL(KDRIVE, [test x$KDRIVE = xyes]) - -if test "$KDRIVE" = yes; then - AC_DEFINE(KDRIVESERVER,1,[Build Kdrive X server]) - AC_DEFINE(KDRIVEDDXACTIONS,,[Build kdrive ddx]) - - AC_CHECK_HEADERS([linux/fb.h]) - if test "$ac_cv_header_linux_fb_h" = yes && test "x$XFBDEV" = xauto; then - XFBDEV=yes - fi - - if test "x$XFBDEV" = xyes; then - KDRIVEFBDEVLIB=yes - AC_DEFINE(KDRIVEFBDEV, 1, [Build fbdev-based kdrive server]) - fi - - - PKG_CHECK_MODULES([TSLIB], [tslib-0.0], [HAVE_TSLIB="yes"], [HAVE_TSLIB="no"]) - if test "x$HAVE_TSLIB" = xno; then - AC_CHECK_LIB(ts, ts_open, [HAVE_TSLIB="yes"]) - fi - - if test "xTSLIB" = xauto; then - TSLIB="$HAVE_TSLIB" - fi - - if test "x$TSLIB" = xyes; then - if ! test "x$HAVE_TSLIB" = xyes; then - AC_MSG_ERROR([tslib must be installed to build the tslib driver. See http://tslib.berlios.de/]) - else - AC_DEFINE(TSLIB, 1, [Have tslib support]) - fi - fi - - if test "x$KDRIVE_KBD" = xyes; then - AC_DEFINE(KDRIVE_KBD, 1, [Enable KDrive kbd driver]) - fi - if test "x$KDRIVE_EVDEV" = xyes; then - AC_DEFINE(KDRIVE_EVDEV, 1, [Enable KDrive evdev driver]) - fi - if test "x$KDRIVE_MOUSE" = xyes; then - AC_DEFINE(KDRIVE_MOUSE, 1, [Enable KDrive mouse driver]) - fi - - XEPHYR_REQUIRED_LIBS="x11 $LIBXEXT xfont xau xdmcp" - if test "x$XV" = xyes; then - XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xv" - fi - if test "x$DRI" = xyes && test "x$GLX" = xyes; then - XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm" - fi - - PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"]) - if test "x$XEPHYR" = xauto; then - XEPHYR=$xephyr - fi - - # Xephyr needs nanosleep() which is in librt on Solaris - AC_CHECK_FUNC([nanosleep], [], - AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt")) - - # damage shadow extension glx (NOTYET) fb mi - KDRIVE_INC='-I$(top_srcdir)/hw/kdrive/src' - KDRIVE_PURE_INCS="$KDRIVE_INC $MIEXT_DAMAGE_INC $MIEXT_SHADOW_INC $XEXT_INC $FB_INC $MI_INC" - KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux' - KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC" - - KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS" - - KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $OS_LIB" - KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.la' - case $host_os in - *linux*) - KDRIVE_OS_LIB='$(top_builddir)/hw/kdrive/linux/liblinux.la' - KDRIVELINUX=yes - if test "x$KDRIVE_EVDEV" = xauto; then - KDRIVE_EVDEV=yes - fi - if test "x$KDRIVE_KBD" = xauto; then - KDRIVE_KBD=yes - fi - if test "x$KDRIVE_MOUSE" = xauto; then - KDRIVE_MOUSE=yes - fi - ;; - *) - if test "x$KDRIVE_EVDEV" = xauto; then - KDRIVE_EVDEV=no - fi - if test "x$KDRIVE_KBD" = xauto; then - KDRIVE_KBD=no - fi - if test "x$KDRIVE_MOUSE" = xauto; then - KDRIVE_MOUSE=no - fi - ;; - esac - KDRIVE_STUB_LIB='$(top_builddir)/hw/kdrive/src/libkdrivestubs.la' - KDRIVE_LOCAL_LIBS="$MAIN_LIB $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB" - KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS" - KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB" - KDRIVE_LIBS="$TSLIB_LIBS $KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $GLX_SYS_LIBS $DLOPEN_LIBS" - - AC_SUBST([XEPHYR_LIBS]) - AC_SUBST([XEPHYR_INCS]) -fi -AC_SUBST([KDRIVE_INCS]) -AC_SUBST([KDRIVE_PURE_INCS]) -AC_SUBST([KDRIVE_CFLAGS]) -AC_SUBST([KDRIVE_PURE_LIBS]) -AC_SUBST([KDRIVE_LOCAL_LIBS]) -AC_SUBST([KDRIVE_LIBS]) -AM_CONDITIONAL(KDRIVELINUX, [test "x$KDRIVELINUX" = xyes]) -AM_CONDITIONAL(KDRIVE_EVDEV, [test "x$KDRIVE_EVDEV" = xyes]) -AM_CONDITIONAL(KDRIVE_KBD, [test "x$KDRIVE_KBD" = xyes]) -AM_CONDITIONAL(KDRIVE_MOUSE, [test "x$KDRIVE_MOUSE" = xyes]) -AM_CONDITIONAL(TSLIB, [test "x$HAVE_TSLIB" = xyes]) -AM_CONDITIONAL(KDRIVEFBDEV, [test "x$XFBDEV" = xyes]) -AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes]) -AM_CONDITIONAL(BUILD_KDRIVEFBDEVLIB, [test "x$KDRIVE" = xyes && test "x$KDRIVEFBDEVLIB" = xyes]) -AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes]) - -dnl and the rest of these are generic, so they're in config.h -dnl -dnl though, thanks to the passing of some significant amount of time, the -dnl above is probably a complete fallacy, and you should not rely on it. -dnl but this is still actually better than imake, honest. -daniels - -AC_TRY_COMPILE([ -#include <features.h> -#ifndef __GLIBC__ -#error not glibc -#endif -], [], [AC_DEFINE(_GNU_SOURCE, 1, - [ Enable GNU and other extensions to the C environment for glibc])]) - -AC_DEFINE_DIR(PROJECTROOT, prefix, [Overall prefix]) - -BUILD_DATE="`date +'%Y%m%d'`" -AC_SUBST([BUILD_DATE]) -BUILD_TIME="`date +'1%H%M%S'`" -AC_SUBST([BUILD_TIME]) - -DIX_CFLAGS="-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS" - -AC_SUBST([DIX_CFLAGS]) - -AC_SUBST([libdir]) -AC_SUBST([exec_prefix]) -AC_SUBST([prefix]) - -AC_OUTPUT([ -Makefile -glx/Makefile -include/Makefile -composite/Makefile -damageext/Makefile -dbe/Makefile -dix/Makefile -doc/Makefile -fb/Makefile -record/Makefile -config/Makefile -mi/Makefile -miext/Makefile -miext/damage/Makefile -miext/shadow/Makefile -miext/cw/Makefile -miext/rootless/Makefile -os/Makefile -randr/Makefile -render/Makefile -xkb/Makefile -Xext/Makefile -Xi/Makefile -xfixes/Makefile -exa/Makefile -hw/Makefile -hw/xfree86/Makefile -hw/xfree86/common/Makefile -hw/xfree86/common/xf86Build.h -hw/xfree86/ddc/Makefile -hw/xfree86/dixmods/Makefile -hw/xfree86/dixmods/extmod/Makefile -hw/xfree86/doc/Makefile -hw/xfree86/doc/devel/Makefile -hw/xfree86/doc/man/Makefile -hw/xfree86/doc/sgml/Makefile -hw/xfree86/dri/Makefile -hw/xfree86/dri2/Makefile -hw/xfree86/exa/Makefile -hw/xfree86/fbdevhw/Makefile -hw/xfree86/i2c/Makefile -hw/xfree86/int10/Makefile -hw/xfree86/loader/Makefile -hw/xfree86/modes/Makefile -hw/xfree86/os-support/Makefile -hw/xfree86/os-support/bsd/Makefile -hw/xfree86/os-support/bus/Makefile -hw/xfree86/os-support/hurd/Makefile -hw/xfree86/os-support/misc/Makefile -hw/xfree86/os-support/linux/Makefile -hw/xfree86/os-support/sco/Makefile -hw/xfree86/os-support/solaris/Makefile -hw/xfree86/os-support/sysv/Makefile -hw/xfree86/parser/Makefile -hw/xfree86/ramdac/Makefile -hw/xfree86/shadowfb/Makefile -hw/xfree86/vbe/Makefile -hw/xfree86/vgahw/Makefile -hw/xfree86/x86emu/Makefile -hw/xfree86/xaa/Makefile -hw/xfree86/xf8_16bpp/Makefile -hw/xfree86/utils/Makefile -hw/xfree86/utils/cvt/Makefile -hw/xfree86/utils/gtf/Makefile -hw/dmx/config/Makefile -hw/dmx/doc/Makefile -hw/dmx/examples/Makefile -hw/dmx/input/Makefile -hw/dmx/glxProxy/Makefile -hw/dmx/Makefile -hw/vfb/Makefile -hw/xnest/Makefile -hw/xwin/Makefile -hw/xwin/glx/Makefile -hw/xquartz/Makefile -hw/xquartz/GL/Makefile -hw/xquartz/bundle/Makefile -hw/xquartz/doc/Makefile -hw/xquartz/mach-startup/Makefile -hw/xquartz/pbproxy/Makefile -hw/xquartz/xpr/Makefile -hw/kdrive/Makefile -hw/kdrive/ephyr/Makefile -hw/kdrive/fake/Makefile -hw/kdrive/fbdev/Makefile -hw/kdrive/linux/Makefile -hw/kdrive/src/Makefile -test/Makefile -test/xi2/Makefile -xorg-server.pc -]) +dnl Copyright © 2003-2007 Keith Packard, Daniel Stone
+dnl
+dnl Permission is hereby granted, free of charge, to any person obtaining a
+dnl copy of this software and associated documentation files (the "Software"),
+dnl to deal in the Software without restriction, including without limitation
+dnl the rights to use, copy, modify, merge, publish, distribute, sublicense,
+dnl and/or sell copies of the Software, and to permit persons to whom the
+dnl Software is furnished to do so, subject to the following conditions:
+dnl
+dnl The above copyright notice and this permission notice (including the next
+dnl paragraph) shall be included in all copies or substantial portions of the
+dnl Software.
+dnl
+dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+dnl THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+dnl FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+dnl DEALINGS IN THE SOFTWARE.
+dnl
+dnl Authors: Keith Packard <keithp@keithp.com>
+dnl Daniel Stone <daniel@fooishbar.org>
+dnl an unwitting cast of miscellaneous others
+dnl
+dnl Process this file with autoconf to create configure.
+
+AC_PREREQ(2.57)
+AC_INIT([xorg-server], 1.8.99.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="unreleased"
+AC_CONFIG_SRCDIR([Makefile.am])
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AM_MAINTAINER_MODE
+
+# Require xorg-macros: XORG_DEFAULT_OPTIONS
+m4_ifndef([XORG_MACROS_VERSION],
+ [m4_fatal([must install xorg-macros 1.6 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.6)
+XORG_DEFAULT_OPTIONS
+XORG_WITH_DOXYGEN(1.6.1)
+
+m4_ifndef([XORG_FONT_MACROS_VERSION], [m4_fatal([must install fontutil 1.1 or later before running autoconf/autogen])])
+XORG_FONT_MACROS_VERSION(1.1)
+
+dnl this gets generated by autoheader, and thus contains all the defines. we
+dnl don't ever actually use it, internally.
+AC_CONFIG_HEADERS(include/do-not-use-config.h)
+dnl xorg-server.h is an external header, designed to be included by loadable
+dnl drivers.
+AC_CONFIG_HEADERS(include/xorg-server.h)
+dnl dix-config.h covers most of the DIX (i.e. everything but the DDX, not just
+dnl dix/).
+AC_CONFIG_HEADERS(include/dix-config.h)
+dnl xorg-config.h covers the Xorg DDX.
+AC_CONFIG_HEADERS(include/xorg-config.h)
+dnl xkb-config.h covers XKB for the Xorg and Xnest DDXs.
+AC_CONFIG_HEADERS(include/xkb-config.h)
+dnl xwin-config.h covers the XWin DDX.
+AC_CONFIG_HEADERS(include/xwin-config.h)
+dnl kdrive-config.h covers the kdrive DDX
+AC_CONFIG_HEADERS(include/kdrive-config.h)
+dnl version-config.h covers the version numbers so they can be bumped without
+dnl forcing an entire recompile.x
+AC_CONFIG_HEADERS(include/version-config.h)
+
+AC_PROG_CC
+AM_PROG_AS
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_LIBTOOL_WIN32_DLL
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+DOLT
+AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
+AC_PROG_LEX
+AC_PROG_YACC
+AC_SYS_LARGEFILE
+XORG_PROG_RAWCPP
+AC_PROG_SED
+
+# Quoted so that make will expand $(CWARNFLAGS) in makefiles to allow
+# easier overrides at build time.
+XSERVER_CFLAGS='$(CWARNFLAGS)'
+
+dnl Check for dtrace program (needed to build Xserver dtrace probes)
+dnl Also checks for <sys/sdt.h>, since some Linux distros have an
+dnl ISDN trace program named dtrace
+AC_ARG_WITH(dtrace, AS_HELP_STRING([--with-dtrace=PATH],
+ [Enable dtrace probes (default: enabled if dtrace found)]),
+ [WDTRACE=$withval], [WDTRACE=auto])
+if test "x$WDTRACE" = "xyes" -o "x$WDTRACE" = "xauto" ; then
+ AC_PATH_PROG(DTRACE, [dtrace], [not_found], [$PATH:/usr/sbin])
+ if test "x$DTRACE" = "xnot_found" ; then
+ if test "x$WDTRACE" = "xyes" ; then
+ AC_MSG_FAILURE([dtrace requested but not found])
+ fi
+ WDTRACE="no"
+ else
+ AC_CHECK_HEADER(sys/sdt.h, [HAS_SDT_H="yes"], [HAS_SDT_H="no"])
+ if test "x$WDTRACE" = "xauto" -a "x$HAS_SDT_H" = "xno" ; then
+ WDTRACE="no"
+ fi
+ fi
+fi
+if test "x$WDTRACE" != "xno" ; then
+ AC_DEFINE(XSERVER_DTRACE, 1,
+ [Define to 1 if the DTrace Xserver provider probes should be built in.])
+
+# Solaris/OpenSolaris require dtrace -G to build dtrace probe information into
+# object files, and require linking with those as relocatable objects, not .a
+# archives. MacOS X handles all this in the normal compiler toolchain, and on
+# some releases (like Tiger), will error out on dtrace -G. For now, other
+# platforms with Dtrace ports are assumed to support -G (the FreeBSD and Linux
+# ports appear to, based on my web searches, but have not yet been tested).
+ case $host_os in
+ darwin*) SPECIAL_DTRACE_OBJECTS=no ;;
+ *) SPECIAL_DTRACE_OBJECTS=yes ;;
+ esac
+fi
+AM_CONDITIONAL(XSERVER_DTRACE, [test "x$WDTRACE" != "xno"])
+AM_CONDITIONAL(SPECIAL_DTRACE_OBJECTS, [test "x$SPECIAL_DTRACE_OBJECTS" = "xyes"])
+
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h fnmatch.h])
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_BIGENDIAN([ENDIAN="X_BIG_ENDIAN"], [ENDIAN="X_LITTLE_ENDIAN"])
+
+AC_CHECK_SIZEOF([unsigned long])
+if test "$ac_cv_sizeof_unsigned_long" = 8; then
+ AC_DEFINE(_XSERVER64, 1, [Define to 1 if unsigned long is 64 bits.])
+fi
+
+AC_TYPE_PID_T
+
+# Checks for headers/macros for byte swapping
+# Known variants:
+# <byteswap.h> bswap_16, bswap_32, bswap_64 (glibc)
+# <sys/endian.h> __swap16, __swap32, __swap64 (OpenBSD)
+# <sys/endian.h> bswap16, bswap32, bswap64 (other BSD's)
+# and a fallback to local macros if none of the above are found
+
+# if <byteswap.h> is found, assume it's the correct version
+AC_CHECK_HEADERS([byteswap.h])
+
+# if <sys/endian.h> is found, have to check which version
+AC_CHECK_HEADER([sys/endian.h], [HAVE_SYS_ENDIAN_H="yes"], [HAVE_SYS_ENDIAN_H="no"])
+
+if test "x$HAVE_SYS_ENDIAN_H" = "xyes" ; then
+ AC_MSG_CHECKING([for __swap16 variant of <sys/endian.h> byteswapping macros])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([
+#include <sys/types.h>
+#include <sys/endian.h>
+ ], [
+int a = 1, b;
+b = __swap16(a);
+ ])
+], [SYS_ENDIAN__SWAP='yes'], [SYS_ENDIAN__SWAP='no'])
+ AC_MSG_RESULT([$SYS_ENDIAN__SWAP])
+
+ AC_MSG_CHECKING([for bswap16 variant of <sys/endian.h> byteswapping macros])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([
+#include <sys/types.h>
+#include <sys/endian.h>
+ ], [
+int a = 1, b;
+b = bswap16(a);
+ ])
+], [SYS_ENDIAN_BSWAP='yes'], [SYS_ENDIAN_BSWAP='no'])
+ AC_MSG_RESULT([$SYS_ENDIAN_BSWAP])
+
+ if test "$SYS_ENDIAN_BSWAP" = "yes" ; then
+ USE_SYS_ENDIAN_H=yes
+ BSWAP=bswap
+ else
+ if test "$SYS_ENDIAN__SWAP" = "yes" ; then
+ USE_SYS_ENDIAN_H=yes
+ BSWAP=__swap
+ else
+ USE_SYS_ENDIAN_H=no
+ fi
+ fi
+
+ if test "$USE_SYS_ENDIAN_H" = "yes" ; then
+ AC_DEFINE([USE_SYS_ENDIAN_H], 1,
+ [Define to use byteswap macros from <sys/endian.h>])
+ AC_DEFINE_UNQUOTED([bswap_16], ${BSWAP}16,
+ [Define to 16-bit byteswap macro])
+ AC_DEFINE_UNQUOTED([bswap_32], ${BSWAP}32,
+ [Define to 32-bit byteswap macro])
+ AC_DEFINE_UNQUOTED([bswap_64], ${BSWAP}64,
+ [Define to 64-bit byteswap macro])
+ fi
+fi
+
+dnl Check to see if dlopen is in default libraries (like Solaris, which
+dnl has it in libc), or if libdl is needed to get it.
+AC_CHECK_FUNC([dlopen], [],
+ AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl"))
+AC_SUBST(DLOPEN_LIBS)
+
+dnl Checks for library functions.
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \
+ strtol getopt getopt_long vsnprintf walkcontext backtrace \
+ getisax getzoneid shmctl64 strcasestr ffs])
+AC_FUNC_ALLOCA
+dnl Old HAS_* names used in os/*.c.
+AC_CHECK_FUNC([getdtablesize],
+ AC_DEFINE(HAS_GETDTABLESIZE, 1, [Have the 'getdtablesize' function.]))
+AC_CHECK_FUNC([getifaddrs],
+ AC_DEFINE(HAS_GETIFADDRS, 1, [Have the 'getifaddrs' function.]))
+AC_CHECK_FUNC([getpeereid],
+ AC_DEFINE(HAS_GETPEEREID, 1, [Have the 'getpeereid' function.]))
+AC_CHECK_FUNC([getpeerucred],
+ AC_DEFINE(HAS_GETPEERUCRED, 1, [Have the 'getpeerucred' function.]))
+AC_CHECK_FUNC([strlcat], HAVE_STRLCAT=yes, HAVE_STRLCAT=no)
+AM_CONDITIONAL(NEED_STRLCAT, [test x$HAVE_STRLCAT = xno])
+AC_CHECK_FUNC([strlcpy], AC_DEFINE(HAS_STRLCPY, 1, [Have the 'strlcpy' function]))
+
+AM_CONDITIONAL(NEED_VSNPRINTF, [test x$HAVE_VSNPRINTF = xno])
+
+dnl Check for mmap support for Xvfb
+AC_CHECK_FUNC([mmap], AC_DEFINE(HAS_MMAP, 1, [Have the 'mmap' function.]))
+
+dnl Find the math libary
+AC_CHECK_LIB(m, sqrt)
+AC_CHECK_LIB(m, cbrt, AC_DEFINE(HAVE_CBRT, 1, [Have the 'cbrt' function]))
+
+AC_CHECK_HEADERS([ndbm.h dbm.h rpcsvc/dbm.h])
+
+dnl AGPGART headers
+AC_CHECK_HEADERS([linux/agpgart.h sys/agpio.h sys/agpgart.h], AGP=yes)
+AM_CONDITIONAL(AGP, [test "x$AGP" = xyes])
+
+dnl APM header
+AC_CHECK_HEADERS([linux/apm_bios.h], LNXAPM=yes)
+AM_CONDITIONAL(LNXAPM, [test "x$LNXAPM" = xyes])
+
+dnl fbdev header
+AC_CHECK_HEADERS([linux/fb.h], FBDEV=yes)
+AM_CONDITIONAL(FBDEVHW, [test "x$FBDEV" = xyes])
+
+dnl MTRR header
+AC_CHECK_HEADERS([asm/mtrr.h], ac_cv_asm_mtrr_h=yes)
+if test "x$ac_cv_asm_mtrr_h" = xyes; then
+ HAVE_MTRR=yes
+fi
+
+dnl BSD MTRR header
+AC_CHECK_HEADERS([sys/memrange.h], ac_cv_memrange_h=yes)
+if test "x$ac_cv_memrange_h" = xyes; then
+ HAVE_MTRR=yes
+fi
+
+if test "x$HAVE_MTRR" = xyes; then
+ AC_DEFINE(HAS_MTRR_SUPPORT, 1, [MTRR support available])
+fi
+
+dnl A NetBSD MTRR header
+AC_CHECK_HEADERS([machine/mtrr.h], ac_cv_machine_mtrr_h=yes)
+if test "x$ac_cv_machine_mtrr_h" = xyes; then
+ AC_DEFINE(HAS_MTRR_BUILTIN, 1, [Define to 1 if NetBSD built-in MTRR
+ support is available])
+fi
+
+dnl FreeBSD kldload support (sys/linker.h)
+AC_CHECK_HEADERS([sys/linker.h],
+ [ac_cv_sys_linker_h=yes],
+ [ac_cv_sys_linker_h=no],
+ [#include <sys/param.h>])
+AM_CONDITIONAL(FREEBSD_KLDLOAD, [test "x$ac_cv_sys_linker_h" = xyes])
+
+AC_CACHE_CHECK([for SYSV IPC],
+ ac_cv_sysv_ipc,
+ [AC_TRY_LINK([
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+],[
+{
+ int id;
+ id = shmget(IPC_PRIVATE, 512, SHM_W | SHM_R);
+ if (id < 0) return -1;
+ return shmctl(id, IPC_RMID, 0);
+}],
+ [ac_cv_sysv_ipc=yes],
+ [ac_cv_sysv_ipc=no])])
+if test "x$ac_cv_sysv_ipc" = xyes; then
+ AC_DEFINE(HAVE_SYSV_IPC, 1, [Define to 1 if SYSV IPC is available])
+fi
+
+dnl OpenBSD /dev/xf86 aperture driver
+if test -c /dev/xf86 ; then
+ AC_DEFINE(HAS_APERTURE_DRV, 1, [System has /dev/xf86 aperture driver])
+fi
+
+dnl BSD APM support
+AC_CHECK_HEADER([machine/apmvar.h],[
+ AC_CHECK_HEADER([sys/event.h],
+ ac_cv_BSD_KQUEUE_APM=yes,
+ ac_cv_BSD_APM=yes)])
+
+AM_CONDITIONAL(BSD_APM, [test "x$ac_cv_BSD_APM" = xyes])
+AM_CONDITIONAL(BSD_KQUEUE_APM, [test "x$ac_cv_BSD_KQUEUE_APM" = xyes])
+
+dnl glibc backtrace support check (hw/xfree86/common/xf86Events.c)
+AC_CHECK_HEADER([execinfo.h],[
+ AC_CHECK_LIB(c, backtrace, [
+ AC_DEFINE(HAVE_BACKTRACE, 1, [Has backtrace support])
+ AC_DEFINE(HAVE_EXECINFO_H, 1, [Have execinfo.h])
+ ])]
+)
+
+dnl ARM needs additional compiler flags for proper backtraces if GCC is
+dnl used. Compile a dummy program with the -mapcs-frame option. If it
+dnl succeeds, we know that we are building for ARM with GCC.
+old_CFLAGS="$CFLAGS"
+CFLAGS="-mapcs-frame"
+AC_COMPILE_IFELSE(
+ AC_LANG_PROGRAM([[ ]]),
+ ARM_BACKTRACE_CFLAGS="$CFLAGS",
+ ARM_BACKTRACE_CFLAGS=""
+)
+CFLAGS="$old_CFLAGS"
+AC_SUBST(ARM_BACKTRACE_CFLAGS)
+
+dnl ---------------------------------------------------------------------------
+dnl Bus options and CPU capabilities. Replaces logic in
+dnl hw/xfree86/os-support/bus/Makefile.am, among others.
+dnl ---------------------------------------------------------------------------
+DEFAULT_INT10="x86emu"
+
+dnl Override defaults as needed for specific platforms:
+
+case $host_cpu in
+ alpha*)
+ ALPHA_VIDEO=yes
+ case $host_os in
+ *freebsd*) SYS_LIBS=-lio ;;
+ *netbsd*) AC_DEFINE(USE_ALPHA_PIO, 1, [NetBSD PIO alpha IO]) ;;
+ esac
+ GLX_ARCH_DEFINES="-D__GLX_ALIGN64 -mieee"
+ ;;
+ arm*)
+ ARM_VIDEO=yes
+ ;;
+ i*86)
+ I386_VIDEO=yes
+ case $host_os in
+ *freebsd*) AC_DEFINE(USE_DEV_IO) ;;
+ *dragonfly*) AC_DEFINE(USE_DEV_IO) ;;
+ *netbsd*) AC_DEFINE(USE_I386_IOPL)
+ SYS_LIBS=-li386
+ ;;
+ *openbsd*) AC_DEFINE(USE_I386_IOPL)
+ SYS_LIBS=-li386
+ ;;
+ esac
+ ;;
+ powerpc*)
+ PPC_VIDEO=yes
+ case $host_os in
+ *freebsd*) DEFAULT_INT10=stub ;;
+ esac
+ ;;
+ sparc*)
+ SPARC64_VIDEO=yes
+ BSD_ARCH_SOURCES="sparc64_video.c ioperm_noop.c"
+ GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
+ ;;
+ x86_64*|amd64*)
+ I386_VIDEO=yes
+ case $host_os in
+ *freebsd*) AC_DEFINE(USE_DEV_IO, 1, [BSD /dev/io]) ;;
+ *dragonfly*) AC_DEFINE(USE_DEV_IO, 1, [BSD /dev/io]) ;;
+ *netbsd*) AC_DEFINE(USE_I386_IOPL, 1, [BSD i386 iopl])
+ SYS_LIBS=-lx86_64
+ ;;
+ *openbsd*) AC_DEFINE(USE_AMD64_IOPL, 1, [BSD AMD64 iopl])
+ SYS_LIBS=-lamd64
+ ;;
+ esac
+ GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
+ ;;
+ ia64*)
+ GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
+ ;;
+ s390*)
+ GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
+ ;;
+esac
+AC_SUBST(GLX_ARCH_DEFINES)
+
+dnl BSD *_video.c selection
+AM_CONDITIONAL(ALPHA_VIDEO, [test "x$ALPHA_VIDEO" = xyes])
+AM_CONDITIONAL(ARM_VIDEO, [test "x$ARM_VIDEO" = xyes])
+AM_CONDITIONAL(I386_VIDEO, [test "x$I386_VIDEO" = xyes])
+AM_CONDITIONAL(PPC_VIDEO, [test "x$PPC_VIDEO" = xyes])
+AM_CONDITIONAL(SPARC64_VIDEO, [test "x$SPARC64_VIDEO" = xyes])
+
+DRI=no
+USE_SIGIO_BY_DEFAULT="yes"
+dnl it would be nice to autodetect these *CONS_SUPPORTs
+case $host_os in
+ *freebsd* | *dragonfly*)
+ case $host_os in
+ kfreebsd*-gnu) ;;
+ *) AC_DEFINE(CSRG_BASED, 1, [System is BSD-like]) ;;
+ esac
+ AC_DEFINE(PCCONS_SUPPORT, 1, [System has PC console])
+ AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console])
+ AC_DEFINE(SYSCONS_SUPPORT, 1, [System has syscons console])
+ DRI=yes
+ ;;
+ *netbsd*)
+ AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
+ AC_DEFINE(PCCONS_SUPPORT, 1, [System has PC console])
+ AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console])
+ AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console])
+ DRI=yes
+ ;;
+ *openbsd*)
+ AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
+ AC_DEFINE(PCVT_SUPPORT, 1, [System has PC console])
+ AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console])
+ ;;
+ *linux*)
+ DRI=yes
+ ;;
+ *solaris*)
+ PKG_CHECK_EXISTS(libdrm, DRI=yes, DRI=no)
+ # Disable use of SIGIO by default until some system bugs are
+ # fixed - see Sun/OpenSolaris bug id 6879897
+ USE_SIGIO_BY_DEFAULT="no"
+ ;;
+ darwin*)
+ AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
+ ;;
+ cygwin*)
+ CFLAGS="$CFLAGS -DFD_SETSIZE=256"
+ ;;
+esac
+
+dnl augment XORG_RELEASE_VERSION for our snapshot number and to expose the
+dnl major number
+PVMAJOR=`echo $PACKAGE_VERSION | cut -d . -f 1`
+PVS=`echo $PACKAGE_VERSION | cut -d . -f 4 | cut -d - -f 1`
+if test "x$PVS" = "x"; then
+ PVS="0"
+fi
+
+VENDOR_RELEASE="((($PVMAJOR) * 10000000) + (($PVM) * 100000) + (($PVP) * 1000) + $PVS)"
+VENDOR_MAN_VERSION="Version ${PACKAGE_VERSION}"
+
+VENDOR_NAME="The X.Org Foundation"
+VENDOR_NAME_SHORT="X.Org"
+VENDOR_WEB="http://wiki.x.org"
+
+m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))])
+
+dnl Build options.
+AC_ARG_ENABLE(werror, AS_HELP_STRING([--enable-werror],
+ [Obsolete - use --enable-strict-compilation instead]),
+ AC_MSG_ERROR([--enable-werror has been replaced by --enable-strict-compilation]))
+
+AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],
+ [Enable debugging (default: disabled)]),
+ [DEBUGGING=$enableval], [DEBUGGING=no])
+AC_ARG_ENABLE(unit-tests, AS_HELP_STRING([--enable-unit-tests],
+ [Enable unit-tests (default: auto)]),
+ [UNITTESTS=$enableval], [UNITTESTS=auto])
+AC_ARG_ENABLE(use-sigio-by-default, AS_HELP_STRING([--enable-use-sigio-by-default]
+ [Enable SIGIO input handlers by default (default: $USE_SIGIO_BY_DEFAULT)]),
+ [USE_SIGIO_BY_DEFAULT=$enableval], [])
+AC_ARG_WITH(int10, AS_HELP_STRING([--with-int10=BACKEND], [int10 backend: vm86, x86emu or stub]),
+ [INT10="$withval"],
+ [INT10="$DEFAULT_INT10"])
+AC_ARG_WITH(vendor-name, AS_HELP_STRING([--with-vendor-name=VENDOR],
+ [Vendor string reported by the server]),
+ [ VENDOR_NAME="$withval" ], [])
+AC_ARG_WITH(vendor-name-short, AS_HELP_STRING([--with-vendor-name-short=VENDOR],
+ [Short version of vendor string reported by the server]),
+ [ VENDOR_NAME_SHORT="$withval" ], [])
+AC_ARG_WITH(vendor-web, AS_HELP_STRING([--with-vendor-web=URL],
+ [Vendor web address reported by the server]),
+ [ VENDOR_WEB="$withval" ], [])
+AC_ARG_WITH(module-dir, AS_HELP_STRING([--with-module-dir=DIR],
+ [Directory where modules are installed (default: $libdir/xorg/modules)]),
+ [ moduledir="$withval" ],
+ [ moduledir="${libdir}/xorg/modules" ])
+AC_ARG_WITH(log-dir, AS_HELP_STRING([--with-log-dir=DIR],
+ [Directory where log files are kept (default: $localstatedir/log)]),
+ [ logdir="$withval" ],
+ [ logdir="$localstatedir/log" ])
+AC_ARG_WITH(builder-addr, AS_HELP_STRING([--with-builder-addr=ADDRESS],
+ [Builder address (default: xorg@lists.freedesktop.org)]),
+ [ BUILDERADDR="$withval" ],
+ [ BUILDERADDR="xorg@lists.freedesktop.org" ])
+AC_ARG_WITH(os-name, AS_HELP_STRING([--with-os-name=OSNAME], [Name of OS (default: output of "uname -srm")]),
+ [ OSNAME="$withval" ],
+ [ OSNAME=`uname -srm` ])
+AC_ARG_WITH(os-vendor, AS_HELP_STRING([--with-os-vendor=OSVENDOR], [Name of OS vendor]),
+ [ OSVENDOR="$withval" ],
+ [ OSVENDOR="" ])
+AC_ARG_WITH(builderstring, AS_HELP_STRING([--with-builderstring=BUILDERSTRING], [Additional builder string]),
+ [ BUILDERSTRING="$withval" ]
+ [ ])
+
+dnl Determine font path
+XORG_FONTROOTDIR
+XORG_FONTSUBDIR(FONTMISCDIR, fontmiscdir, misc)
+XORG_FONTSUBDIR(FONTOTFDIR, fontotfdir, OTF)
+XORG_FONTSUBDIR(FONTTTFDIR, fontttfdir, TTF)
+XORG_FONTSUBDIR(FONTTYPE1DIR, fonttype1dir, Type1)
+XORG_FONTSUBDIR(FONT75DPIDIR, font75dpidir, 75dpi)
+XORG_FONTSUBDIR(FONT100DPIDIR, font100dpidir, 100dpi)
+
+dnl Uses --default-font-path if set, otherwise checks for /etc/X11/fontpath.d,
+dnl otherwise uses standard subdirectories of FONTROOTDIR. When cross
+dnl compiling, assume default font path uses standard FONTROOTDIR directories.
+DEFAULT_FONT_PATH="${FONTMISCDIR}/,${FONTTTFDIR}/,${FONTOTFDIR}/,${FONTTYPE1DIR}/,${FONT100DPIDIR}/,${FONT75DPIDIR}/"
+if test "$cross_compiling" != yes; then
+ AC_CHECK_FILE([${sysconfdir}/X11/fontpath.d],
+ [DEFAULT_FONT_PATH='catalogue:${sysconfdir}/X11/fontpath.d'],
+ [case $host_os in
+ darwin*) DEFAULT_FONT_PATH="${DEFAULT_FONT_PATH},/Library/Fonts,/System/Library/Fonts" ;;
+ esac])
+fi
+AC_ARG_WITH(default-font-path, AS_HELP_STRING([--with-default-font-path=PATH], [Comma separated list of font dirs]),
+ [ FONTPATH="$withval" ],
+ [ FONTPATH="${DEFAULT_FONT_PATH}" ])
+
+AC_MSG_CHECKING([for default font path])
+AC_MSG_RESULT([$FONTPATH])
+
+AC_ARG_WITH(xkb-path, AS_HELP_STRING([--with-xkb-path=PATH], [Path to XKB base dir (default: ${datadir}/X11/xkb)]),
+ [ XKBPATH="$withval" ],
+ [ XKBPATH="${datadir}/X11/xkb" ])
+AC_ARG_WITH(xkb-output, AS_HELP_STRING([--with-xkb-output=PATH], [Path to XKB output dir (default: ${datadir}/X11/xkb/compiled)]),
+ [ XKBOUTPUT="$withval" ],
+ [ XKBOUTPUT="compiled" ])
+AC_ARG_WITH(default-xkb-rules, AS_HELP_STRING([--with-default-xkb-rules=RULES],
+ [Keyboard ruleset (default: base/evdev)]),
+ [ XKB_DFLT_RULES="$withval" ],
+ [ XKB_DFLT_RULES="" ])
+AC_ARG_WITH(default-xkb-model, AS_HELP_STRING([--with-default-xkb-model=MODEL],
+ [Keyboard model (default: pc105)]),
+ [ XKB_DFLT_MODEL="$withval" ],
+ [ XKB_DFLT_MODEL="pc105" ])
+AC_ARG_WITH(default-xkb-layout, AS_HELP_STRING([--with-default-xkb-layout=LAYOUT],
+ [Keyboard layout (default: us)]),
+ [ XKB_DFLT_LAYOUT="$withval" ],
+ [ XKB_DFLT_LAYOUT="us" ])
+AC_ARG_WITH(default-xkb-variant, AS_HELP_STRING([--with-default-xkb-variant=VARIANT],
+ [Keyboard variant (default: (none))]),
+ [ XKB_DFLT_VARIANT="$withval" ],
+ [ XKB_DFLT_VARIANT="" ])
+AC_ARG_WITH(default-xkb-options, AS_HELP_STRING([--with-default-xkb-options=OPTIONS],
+ [Keyboard layout options (default: (none))]),
+ [ XKB_DFLT_OPTIONS="$withval" ],
+ [ XKB_DFLT_OPTIONS="" ])
+AC_ARG_WITH(serverconfig-path, AS_HELP_STRING([--with-serverconfig-path=PATH],
+ [Directory where ancillary server config files are installed (default: ${libdir}/xorg)]),
+ [ SERVERCONFIG="$withval" ],
+ [ SERVERCONFIG="${libdir}/xorg" ])
+AC_ARG_WITH(apple-applications-dir,AS_HELP_STRING([--with-apple-applications-dir=PATH], [Path to the Applications directory (default: /Applications/Utilities)]),
+ [ APPLE_APPLICATIONS_DIR="${withval}" ],
+ [ APPLE_APPLICATIONS_DIR="/Applications/Utilities" ])
+AC_SUBST([APPLE_APPLICATIONS_DIR])
+AC_ARG_WITH(apple-application-name,AS_HELP_STRING([--with-apple-application-name=NAME], [Name for the .app (default: X11)]),
+ [ APPLE_APPLICATION_NAME="${withval}" ],
+ [ APPLE_APPLICATION_NAME="X11" ])
+AC_SUBST([APPLE_APPLICATION_NAME])
+AC_ARG_WITH(launchd-id-prefix, AS_HELP_STRING([--with-launchd-id-prefix=PATH], [Prefix to use for launchd identifiers (default: org.x)]),
+ [ LAUNCHD_ID_PREFIX="${withval}" ],
+ [ LAUNCHD_ID_PREFIX="org.x" ])
+AC_SUBST([LAUNCHD_ID_PREFIX])
+AC_DEFINE_UNQUOTED(LAUNCHD_ID_PREFIX, "$LAUNCHD_ID_PREFIX", [Prefix to use for launchd identifiers])
+AC_ARG_ENABLE(sparkle,AS_HELP_STRING([--enable-sparkle], [Enable updating of X11.app using the Sparkle Framework (default: disabled)]),
+ [ XQUARTZ_SPARKLE="${enableval}" ],
+ [ XQUARTZ_SPARKLE="no" ])
+AC_SUBST([XQUARTZ_SPARKLE])
+AC_ARG_ENABLE(builddocs, AS_HELP_STRING([--enable-builddocs], [Build docs (default: disabled)]),
+ [BUILDDOCS=$enableval],
+ [BUILDDOCS=no])
+AC_ARG_ENABLE(install-libxf86config,
+ AS_HELP_STRING([--enable-install-libxf86config],
+ [Install libxf86config (default: disabled)]),
+ [INSTALL_LIBXF86CONFIG=$enableval],
+ [INSTALL_LIBXF86CONFIG=no])
+AC_ARG_ENABLE(visibility, AC_HELP_STRING([--enable-visibility], [Enable symbol visibility (default: auto)]),
+ [SYMBOL_VISIBILITY=$enableval],
+ [SYMBOL_VISIBILITY=auto])
+AC_ARG_ENABLE(pc98, AC_HELP_STRING([--enable-pc98], [Enable PC98 support in Xorg (default: auto)]),
+ [SUPPORT_PC98=$enableval],
+ [SUPPORT_PC98=auto])
+
+dnl GLX build options
+AC_ARG_WITH(dri-driver-path, AS_HELP_STRING([--with-dri-driver-path=PATH], [Path to DRI drivers (default: ${libdir}/dri)]),
+ [ DRI_DRIVER_PATH="$withval" ],
+ [ DRI_DRIVER_PATH="${libdir}/dri" ])
+AC_ARG_ENABLE(aiglx, AS_HELP_STRING([--enable-aiglx], [Build accelerated indirect GLX (default: enabled)]),
+ [AIGLX=$enableval],
+ [AIGLX=yes])
+AC_ARG_ENABLE(glx-tls, AS_HELP_STRING([--enable-glx-tls], [Build GLX with TLS support (default: disabled)]),
+ [GLX_USE_TLS=$enableval],
+ [GLX_USE_TLS=no])
+
+dnl Extensions.
+AC_ARG_ENABLE(registry, AS_HELP_STRING([--disable-registry], [Build string registry module (default: enabled)]), [XREGISTRY=$enableval], [XREGISTRY=yes])
+AC_ARG_ENABLE(composite, AS_HELP_STRING([--disable-composite], [Build Composite extension (default: enabled)]), [COMPOSITE=$enableval], [COMPOSITE=yes])
+AC_ARG_ENABLE(mitshm, AS_HELP_STRING([--disable-shm], [Build SHM extension (default: enabled)]), [MITSHM=$enableval], [MITSHM=yes])
+AC_ARG_ENABLE(xres, AS_HELP_STRING([--disable-xres], [Build XRes extension (default: enabled)]), [RES=$enableval], [RES=yes])
+AC_ARG_ENABLE(record, AS_HELP_STRING([--disable-record], [Build Record extension (default: enabled)]), [RECORD=$enableval], [RECORD=yes])
+AC_ARG_ENABLE(xv, AS_HELP_STRING([--disable-xv], [Build Xv extension (default: enabled)]), [XV=$enableval], [XV=yes])
+AC_ARG_ENABLE(xvmc, AS_HELP_STRING([--disable-xvmc], [Build XvMC extension (default: enabled)]), [XVMC=$enableval], [XVMC=yes])
+AC_ARG_ENABLE(dga, AS_HELP_STRING([--disable-dga], [Build DGA extension (default: auto)]), [DGA=$enableval], [DGA=auto])
+AC_ARG_ENABLE(screensaver, AS_HELP_STRING([--disable-screensaver], [Build ScreenSaver extension (default: enabled)]), [SCREENSAVER=$enableval], [SCREENSAVER=yes])
+AC_ARG_ENABLE(xdmcp, AS_HELP_STRING([--disable-xdmcp], [Build XDMCP extension (default: auto)]), [XDMCP=$enableval], [XDMCP=auto])
+AC_ARG_ENABLE(xdm-auth-1, AS_HELP_STRING([--disable-xdm-auth-1], [Build XDM-Auth-1 extension (default: auto)]), [XDMAUTH=$enableval], [XDMAUTH=auto])
+AC_ARG_ENABLE(glx, AS_HELP_STRING([--disable-glx], [Build GLX extension (default: enabled)]), [GLX=$enableval], [GLX=yes])
+AC_ARG_ENABLE(dri, AS_HELP_STRING([--enable-dri], [Build DRI extension (default: auto)]), [DRI=$enableval])
+AC_ARG_ENABLE(dri2, AS_HELP_STRING([--enable-dri2], [Build DRI2 extension (default: auto)]), [DRI2=$enableval], [DRI2=auto])
+AC_ARG_ENABLE(xinerama, AS_HELP_STRING([--disable-xinerama], [Build Xinerama extension (default: enabled)]), [XINERAMA=$enableval], [XINERAMA=yes])
+AC_ARG_ENABLE(xf86vidmode, AS_HELP_STRING([--disable-xf86vidmode], [Build XF86VidMode extension (default: auto)]), [XF86VIDMODE=$enableval], [XF86VIDMODE=auto])
+AC_ARG_ENABLE(xace, AS_HELP_STRING([--disable-xace], [Build X-ACE extension (default: enabled)]), [XACE=$enableval], [XACE=yes])
+AC_ARG_ENABLE(xselinux, AS_HELP_STRING([--enable-xselinux], [Build SELinux extension (default: disabled)]), [XSELINUX=$enableval], [XSELINUX=no])
+AC_ARG_ENABLE(xcsecurity, AS_HELP_STRING([--enable-xcsecurity], [Build Security extension (default: disabled)]), [XCSECURITY=$enableval], [XCSECURITY=no])
+AC_ARG_ENABLE(xcalibrate, AS_HELP_STRING([--enable-xcalibrate], [Build XCalibrate extension (default: disabled)]), [XCALIBRATE=$enableval], [XCALIBRATE=no])
+AC_ARG_ENABLE(tslib, AS_HELP_STRING([--enable-tslib], [Build kdrive tslib touchscreen support (default: disabled)]), [TSLIB=$enableval], [TSLIB=no])
+AC_ARG_ENABLE(dbe, AS_HELP_STRING([--disable-dbe], [Build DBE extension (default: enabled)]), [DBE=$enableval], [DBE=yes])
+AC_ARG_ENABLE(xf86bigfont, AS_HELP_STRING([--enable-xf86bigfont], [Build XF86 Big Font extension (default: disabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=no])
+AC_ARG_ENABLE(dpms, AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes])
+AC_ARG_ENABLE(config-udev, AS_HELP_STRING([--enable-config-udev], [Build udev support (default: auto)]), [CONFIG_UDEV=$enableval], [CONFIG_UDEV=auto])
+AC_ARG_ENABLE(config-dbus, AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no])
+AC_ARG_ENABLE(config-hal, AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto])
+AC_ARG_ENABLE(xfree86-utils, AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes])
+AC_ARG_ENABLE(xaa, AS_HELP_STRING([--enable-xaa], [Build XAA (default: enabled)]), [XAA=$enableval], [XAA=yes])
+AC_ARG_ENABLE(vgahw, AS_HELP_STRING([--enable-vgahw], [Build Xorg with vga access (default: enabled)]), [VGAHW=$enableval], [VGAHW=yes])
+AC_ARG_ENABLE(vbe, AS_HELP_STRING([--enable-vbe], [Build Xorg with VBE module (default: enabled)]), [VBE=$enableval], [VBE=yes])
+AC_ARG_ENABLE(int10-module, AS_HELP_STRING([--enable-int10-module], [Build Xorg with int10 module (default: enabled)]), [INT10MODULE=$enableval], [INT10MODULE=yes])
+AC_ARG_ENABLE(windowswm, AS_HELP_STRING([--enable-windowswm], [Build XWin with WindowsWM extension (default: no)]), [WINDOWSWM=$enableval], [WINDOWSWM=no])
+
+dnl DDXes.
+AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
+AC_ARG_ENABLE(dmx, AS_HELP_STRING([--enable-dmx], [Build DMX server (default: auto)]), [DMX=$enableval], [DMX=auto])
+AC_ARG_ENABLE(xvfb, AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes])
+AC_ARG_ENABLE(xnest, AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto])
+AC_ARG_ENABLE(xquartz, AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
+AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
+AC_ARG_ENABLE(xwin, AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
+dnl kdrive and its subsystems
+AC_ARG_ENABLE(kdrive, AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no])
+AC_ARG_ENABLE(xephyr, AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto])
+AC_ARG_ENABLE(xfake, AS_HELP_STRING([--enable-xfake], [Build the kdrive 'fake' server (default: auto)]), [XFAKE=$enableval], [XFAKE=auto])
+AC_ARG_ENABLE(xfbdev, AS_HELP_STRING([--enable-xfbdev], [Build the kdrive framebuffer device server (default: auto)]), [XFBDEV=$enableval], [XFBDEV=auto])
+dnl kdrive options
+AC_ARG_ENABLE(kdrive-kbd, AS_HELP_STRING([--enable-kdrive-kbd], [Build kbd driver for kdrive (default: auto)]), [KDRIVE_KBD=$enableval], [KDRIVE_KBD=auto])
+AC_ARG_ENABLE(kdrive-mouse, AC_HELP_STRING([--enable-kdrive-mouse], [Build mouse driver for kdrive (default: auto)]), [KDRIVE_MOUSE=$enableval], [KDRIVE_MOUSE=auto])
+AC_ARG_ENABLE(kdrive-evdev, AC_HELP_STRING([--enable-kdrive-evdev], [Build evdev driver for kdrive (default: auto)]), [KDRIVE_EVDEV=$enableval], [KDRIVE_EVDEV=auto])
+
+
+dnl chown/chmod to be setuid root as part of build
+dnl Replaces InstallXserverSetUID in imake
+AC_ARG_ENABLE(install-setuid,
+ AS_HELP_STRING([--enable-install-setuid],
+ [Install Xorg server as owned by root with setuid bit (default: auto)]),
+ [SETUID=$enableval], [SETUID=auto])
+AC_MSG_CHECKING([to see if we can install the Xorg server as root])
+if test "x$SETUID" = "xauto" ; then
+ case $host_os in
+ cygwin*) SETUID="no" ;;
+ darwin*) SETUID="no" ;;
+ *)
+ case $host_cpu in
+ sparc) SETUID="no" ;;
+ *) SETUID="yes" ;;
+ esac
+ esac
+ if test "x$SETUID" = xyes; then
+ touch testfile
+ chown root testfile > /dev/null 2>&1 || SETUID="no"
+ rm -f testfile
+ fi
+fi
+AC_MSG_RESULT([$SETUID])
+AM_CONDITIONAL(INSTALL_SETUID, [test "x$SETUID" = "xyes"])
+
+dnl Issue an error if xtrans.m4 was not found and XTRANS_CONNECTION_FLAGS macro
+dnl was not expanded, since xorg-server with no transport types is rather useless.
+dnl
+dnl If you're seeing an error here, be sure you installed the lib/xtrans module
+dnl first and if it's not in the default location, that you set the ACLOCAL
+dnl environment variable to find it, such as:
+dnl ACLOCAL="aclocal -I ${PREFIX}/share/aclocal"
+m4_pattern_forbid([^XTRANS_CONNECTION_FLAGS$])
+
+# Transport selection macro from xtrans.m4
+XTRANS_CONNECTION_FLAGS
+
+# Secure RPC detection macro from xtrans.m4
+XTRANS_SECURE_RPC_FLAGS
+AM_CONDITIONAL(SECURE_RPC, [test "x$SECURE_RPC" = xyes])
+
+AM_CONDITIONAL(INT10_VM86, [test "x$INT10" = xvm86])
+AM_CONDITIONAL(INT10_X86EMU, [test "x$INT10" = xx86emu])
+AM_CONDITIONAL(INT10_STUB, [test "x$INT10" = xstub])
+if test "x$INT10" = xyes; then
+ dnl VM86 headers
+ AC_CHECK_HEADERS([sys/vm86.h sys/io.h])
+fi
+
+dnl Handle building documentation
+AM_CONDITIONAL(BUILDDOCS, test "x$BUILDDOCS" = xyes)
+XORG_ENABLE_DEVEL_DOCS
+XORG_WITH_XMLTO(0.0.20)
+XORG_WITH_FOP
+
+dnl Handle installing libxf86config
+AM_CONDITIONAL(INSTALL_LIBXF86CONFIG, [test "x$INSTALL_LIBXF86CONFIG" = xyes])
+
+dnl DDX Detection... Yes, it's ugly to have it here... but we need to
+dnl handle this early on so that we don't require unsupported extensions
+case $host_os in
+ cygwin*)
+ DGA=no
+ DRI2=no
+ XF86VIDMODE=no
+ XSELINUX=no
+ XV=no
+ ;;
+ darwin*)
+ DRI2=no
+
+ if test x$XQUARTZ = xauto; then
+ AC_CACHE_CHECK([whether to build Xquartz],xorg_cv_Carbon_framework,[
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -framework Carbon"
+ AC_LINK_IFELSE([char FSFindFolder(); int main() { FSFindFolder(); return 0;}],
+ [xorg_cv_Carbon_framework=yes],
+ [xorg_cv_Carbon_framework=no])
+ LDFLAGS=$save_LDFLAGS])
+
+ if test "X$xorg_cv_Carbon_framework" = Xyes; then
+ XQUARTZ=yes
+ else
+ XQUARTZ=no
+ fi
+ fi
+
+ if test "x$XQUARTZ" = xyes ; then
+ XQUARTZ=yes
+ XVFB=no
+ XNEST=no
+
+ COMPOSITE=no
+ DGA=no
+ DPMSExtension=no
+ XF86VIDMODE=no
+ fi
+ ;;
+ *) XQUARTZ=no ;;
+esac
+
+dnl ---------------------------------------------------------------------------
+dnl Extension section
+dnl ---------------------------------------------------------------------------
+XEXT_INC='-I$(top_srcdir)/Xext'
+XEXT_LIB='$(top_builddir)/Xext/libXext.la'
+XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
+
+dnl Optional modules
+VIDEOPROTO="videoproto"
+COMPOSITEPROTO="compositeproto >= 0.4"
+RECORDPROTO="recordproto >= 1.13.99.1"
+SCRNSAVERPROTO="scrnsaverproto >= 1.1"
+RESOURCEPROTO="resourceproto"
+DRIPROTO="xf86driproto >= 2.1.0"
+DRI2PROTO="dri2proto >= 2.3"
+XINERAMAPROTO="xineramaproto"
+BIGFONTPROTO="xf86bigfontproto >= 1.2.0"
+XCALIBRATEPROTO="xcalibrateproto"
+DGAPROTO="xf86dgaproto >= 2.0.99.1"
+GLPROTO="glproto >= 1.4.10"
+DMXPROTO="dmxproto >= 2.2.99.1"
+VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1"
+WINDOWSWMPROTO="windowswmproto"
+APPLEWMPROTO="applewmproto >= 1.4"
+
+dnl Core modules for most extensions, et al.
+REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.11] [fixesproto >= 4.1] [damageproto >= 1.1] [xcmiscproto >= 1.2.0] [xextproto >= 7.0.99.3] [xproto >= 7.0.17] [xtrans >= 1.2.2] [bigreqsproto >= 1.1.0] fontsproto [inputproto >= 1.9.99.902] [kbproto >= 1.0.3]"
+REQUIRED_LIBS="xfont xau [pixman-1 >= 0.15.20]"
+
+dnl List of libraries that require a specific version
+LIBAPPLEWM="applewm >= 1.4"
+LIBDMX="dmx >= 1.0.99.1"
+LIBDRI="dri >= 7.8.0"
+LIBDRM="libdrm >= 2.3.0"
+LIBGL="gl >= 7.1.0"
+LIBXEXT="xext >= 1.0.99.4"
+LIBXI="xi >= 1.2.99.1"
+LIBXTST="xtst >= 1.0.99.2"
+LIBPCIACCESS="pciaccess >= 0.8.0"
+LIBGLIB="glib-2.0 >= 2.16"
+LIBUDEV="libudev >= 143"
+LIBSELINUX="libselinux >= 2.0.86"
+
+if test "x$CONFIG_UDEV" = xyes &&
+ { test "x$CONFIG_DBUS_API" = xyes || test "x$CONFIG_HAL" = xyes; }; then
+ AC_MSG_ERROR([Hotplugging through both libudev and dbus/hal not allowed])
+fi
+
+PKG_CHECK_MODULES(UDEV, $LIBUDEV, [HAVE_LIBUDEV=yes], [HAVE_LIBUDEV=no])
+if test "x$CONFIG_UDEV" = xauto; then
+ CONFIG_UDEV="$HAVE_LIBUDEV"
+fi
+AM_CONDITIONAL(CONFIG_UDEV, [test "x$CONFIG_UDEV" = xyes])
+if test "x$CONFIG_UDEV" = xyes; then
+ CONFIG_DBUS_API=no
+ CONFIG_HAL=no
+ if ! test "x$HAVE_LIBUDEV" = xyes; then
+ AC_MSG_ERROR([udev configuration API requested, but libudev is not installed])
+ fi
+ AC_DEFINE(CONFIG_UDEV, 1, [Use libudev for input hotplug])
+fi
+
+dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
+dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
+dnl API.
+PKG_CHECK_MODULES(DBUS, dbus-1, [HAVE_DBUS=yes], [HAVE_DBUS=no])
+if test "x$HAVE_DBUS" = xyes; then
+ AC_DEFINE(HAVE_DBUS, 1, [Have D-Bus support])
+fi
+AM_CONDITIONAL(HAVE_DBUS, [test "x$HAVE_DBUS" = xyes])
+
+if test "x$CONFIG_DBUS_API" = xauto; then
+ CONFIG_DBUS_API="$HAVE_DBUS"
+fi
+if test "x$CONFIG_DBUS_API" = xyes; then
+ if ! test "x$HAVE_DBUS" = xyes; then
+ AC_MSG_ERROR([D-Bus configuration API requested, but D-Bus is not installed.])
+ fi
+
+ AC_DEFINE(CONFIG_DBUS_API, 1, [Use the D-Bus input configuration API])
+ CONFIG_NEED_DBUS="yes"
+fi
+AM_CONDITIONAL(CONFIG_DBUS_API, [test "x$CONFIG_DBUS_API" = xyes])
+
+PKG_CHECK_MODULES(HAL, hal, [HAVE_HAL=yes], [HAVE_HAL=no])
+if test "x$CONFIG_HAL" = xauto; then
+ CONFIG_HAL="$HAVE_HAL"
+fi
+if test "x$CONFIG_HAL" = xyes; then
+ if ! test "x$HAVE_HAL" = xyes; then
+ AC_MSG_ERROR([HAL hotplug API requested, but HAL is not installed.])
+ fi
+
+ AC_DEFINE(CONFIG_HAL, 1, [Use the HAL hotplug API])
+ CONFIG_NEED_DBUS="yes"
+fi
+AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes])
+
+if test "x$CONFIG_NEED_DBUS" = xyes; then
+ AC_DEFINE(CONFIG_NEED_DBUS, 1, [Use D-Bus for input hotplug])
+fi
+AM_CONDITIONAL(CONFIG_NEED_DBUS, [test "x$CONFIG_NEED_DBUS" = xyes])
+
+if test "x$USE_SIGIO_BY_DEFAULT" = xyes; then
+ USE_SIGIO_BY_DEFAULT_VALUE=TRUE
+else
+ USE_SIGIO_BY_DEFAULT_VALUE=FALSE
+fi
+AC_DEFINE_UNQUOTED([USE_SIGIO_BY_DEFAULT], [$USE_SIGIO_BY_DEFAULT_VALUE],
+ [Use SIGIO handlers for input device events by default])
+
+AC_MSG_CHECKING([for glibc...])
+AC_PREPROC_IFELSE([
+#include <features.h>
+#ifndef __GLIBC__
+#error
+#endif
+], glibc=yes, glibc=no)
+AC_MSG_RESULT([$glibc])
+
+AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes],
+ [AC_CHECK_LIB([rt], [clock_gettime], [have_clock_gettime=-lrt],
+ [have_clock_gettime=no])])
+
+AC_MSG_CHECKING([for a useful monotonic clock ...])
+
+if ! test "x$have_clock_gettime" = xno; then
+ if ! test "x$have_clock_gettime" = xyes; then
+ CLOCK_LIBS="$have_clock_gettime"
+ else
+ CLOCK_LIBS=""
+ fi
+
+ LIBS_SAVE="$LIBS"
+ LIBS="$CLOCK_LIBS"
+ CPPFLAGS_SAVE="$CPPFLAGS"
+
+ if test x"$glibc" = xyes; then
+ CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=200112L"
+ fi
+
+ AC_RUN_IFELSE([
+#include <time.h>
+
+int main(int argc, char *argv[[]]) {
+ struct timespec tp;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
+ return 0;
+ else
+ return 1;
+}
+ ], [MONOTONIC_CLOCK=yes], [MONOTONIC_CLOCK=no],
+ [MONOTONIC_CLOCK="cross compiling"])
+
+ LIBS="$LIBS_SAVE"
+ CPPFLAGS="$CPPFLAGS_SAVE"
+else
+ MONOTONIC_CLOCK=no
+fi
+
+AC_MSG_RESULT([$MONOTONIC_CLOCK])
+
+if test "x$MONOTONIC_CLOCK" = xyes; then
+ AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()])
+ LIBS="$LIBS $CLOCK_LIBS"
+fi
+
+AM_CONDITIONAL(XV, [test "x$XV" = xyes])
+if test "x$XV" = xyes; then
+ AC_DEFINE(XV, 1, [Support Xv extension])
+ AC_DEFINE(XvExtension, 1, [Build Xv extension])
+ REQUIRED_MODULES="$REQUIRED_MODULES $VIDEOPROTO"
+else
+ XVMC=no
+fi
+
+AM_CONDITIONAL(XVMC, [test "x$XVMC" = xyes])
+if test "x$XVMC" = xyes; then
+ AC_DEFINE(XvMCExtension, 1, [Build XvMC extension])
+fi
+
+AM_CONDITIONAL(XREGISTRY, [test "x$XREGISTRY" = xyes])
+if test "x$XREGISTRY" = xyes; then
+ AC_DEFINE(XREGISTRY, 1, [Build registry module])
+fi
+
+AM_CONDITIONAL(COMPOSITE, [test "x$COMPOSITE" = xyes])
+if test "x$COMPOSITE" = xyes; then
+ AC_DEFINE(COMPOSITE, 1, [Support Composite Extension])
+ REQUIRED_MODULES="$REQUIRED_MODULES $COMPOSITEPROTO"
+ COMPOSITE_LIB='$(top_builddir)/composite/libcomposite.la'
+ COMPOSITE_INC='-I$(top_srcdir)/composite'
+fi
+
+AM_CONDITIONAL(MITSHM, [test "x$MITSHM" = xyes])
+if test "x$MITSHM" = xyes; then
+ AC_DEFINE(MITSHM, 1, [Support MIT-SHM extension])
+ AC_DEFINE(HAS_SHM, 1, [Support SHM])
+fi
+
+AM_CONDITIONAL(RECORD, [test "x$RECORD" = xyes])
+if test "x$RECORD" = xyes; then
+ AC_DEFINE(XRECORD, 1, [Support Record extension])
+ REQUIRED_MODULES="$REQUIRED_MODULES $RECORDPROTO"
+ RECORD_LIB='$(top_builddir)/record/librecord.la'
+fi
+
+AM_CONDITIONAL(SCREENSAVER, [test "x$SCREENSAVER" = xyes])
+if test "x$SCREENSAVER" = xyes; then
+ AC_DEFINE(SCREENSAVER, 1, [Support MIT-SCREEN-SAVER extension])
+ REQUIRED_MODULES="$REQUIRED_MODULES $SCRNSAVERPROTO"
+fi
+
+AM_CONDITIONAL(RES, [test "x$RES" = xyes])
+if test "x$RES" = xyes; then
+ AC_DEFINE(RES, 1, [Support X resource extension])
+ REQUIRED_MODULES="$REQUIRED_MODULES $RESOURCEPROTO"
+fi
+
+if test "x$GLX" = xyes; then
+ PKG_CHECK_MODULES([XLIB], [x11])
+ PKG_CHECK_MODULES([GL], $GLPROTO $LIBGL)
+ AC_SUBST(XLIB_CFLAGS)
+ AC_DEFINE(GLXEXT, 1, [Build GLX extension])
+ GLX_LIBS='$(top_builddir)/glx/libglx.la'
+ GLX_SYS_LIBS="$GLX_SYS_LIBS"
+else
+ GLX=no
+fi
+AM_CONDITIONAL(GLX, test "x$GLX" = xyes)
+
+if test "x$AIGLX" = xyes -a "x$GLX" = xyes -a "x$DRI" = xyes; then
+ AC_DEFINE(AIGLX, 1, [Build AIGLX loader])
+else
+ AIGLX=no
+fi
+AM_CONDITIONAL(AIGLX, test "x$AIGLX" = xyes)
+
+if test "x$GLX_USE_TLS" = xyes -a "x$AIGLX" = xyes; then
+ GLX_DEFINES="-DGLX_USE_TLS -DPTHREADS"
+ GLX_SYS_LIBS="$GLX_SYS_LIBS -lpthread"
+fi
+AC_SUBST([GLX_DEFINES])
+
+AM_CONDITIONAL(DRI, test "x$DRI" = xyes)
+if test "x$DRI" = xyes; then
+ AC_DEFINE(XF86DRI, 1, [Build DRI extension])
+ PKG_CHECK_MODULES([DRIPROTO], [$DRIPROTO])
+ PKG_CHECK_MODULES([DRI], $GLPROTO $LIBDRI)
+ AC_SUBST(DRIPROTO_CFLAGS)
+fi
+
+PKG_CHECK_MODULES([DRI2PROTO], $DRI2PROTO,
+ [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no])
+case "$DRI2,$HAVE_DRI2PROTO" in
+ yes,no)
+ AC_MSG_ERROR([DRI2 requested, but dri2proto not found.])
+ ;;
+ yes,yes | auto,yes)
+ AC_DEFINE(DRI2, 1, [Build DRI2 extension])
+ DRI2=yes
+ ;;
+esac
+AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes)
+
+if test "x$DRI" = xyes || test "x$DRI2" = xyes; then
+ PKG_CHECK_MODULES([LIBDRM], $LIBDRM)
+ AC_SUBST(LIBDRM_CFLAGS)
+ AC_SUBST(LIBDRM_LIBS)
+fi
+
+if test "x$DRI2" = xyes; then
+ save_CFLAGS=$CFLAGS
+ CFLAGS="$GL_CFLAGS $LIBDRM_CFLAGS"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#ifndef __DRI_DRI2
+#error DRI2 extension not available.
+#endif]])],
+ [HAVE_DRI2EXTENSION=yes],
+ [HAVE_DRI2EXTENSION=no])
+ CFLAGS=$save_CFLAGS
+ if test "x$HAVE_DRI2EXTENSION" = xyes; then
+ AC_DEFINE(DRI2_AIGLX, 1, [Build DRI2 AIGLX loader])
+ DRI2_AIGLX=yes
+ else
+ AC_MSG_NOTICE([DRI2 AIGLX disabled, __DRI_DRI2 not defined in dri_interface.h.])
+ DRI2_AIGLX=no
+ fi
+fi
+AM_CONDITIONAL(DRI2_AIGLX, test "x$DRI2_AIGLX" = xyes)
+
+
+AM_CONDITIONAL(XINERAMA, [test "x$XINERAMA" = xyes])
+if test "x$XINERAMA" = xyes; then
+ AC_DEFINE(XINERAMA, 1, [Support Xinerama extension])
+ AC_DEFINE(PANORAMIX, 1, [Internal define for Xinerama])
+ REQUIRED_MODULES="$REQUIRED_MODULES $XINERAMAPROTO"
+fi
+
+AM_CONDITIONAL(XACE, [test "x$XACE" = xyes])
+if test "x$XACE" = xyes; then
+ AC_DEFINE(XACE, 1, [Build X-ACE extension])
+fi
+
+AM_CONDITIONAL(XSELINUX, [test "x$XSELINUX" = xyes])
+if test "x$XSELINUX" = xyes; then
+ if test "x$XACE" != xyes; then
+ AC_MSG_ERROR([cannot build SELinux extension without X-ACE])
+ fi
+ AC_CHECK_HEADERS([libaudit.h], [], AC_MSG_ERROR([SELinux extension requires audit system headers]))
+ AC_CHECK_LIB(audit, audit_open, [], AC_MSG_ERROR([SELinux extension requires audit system library]))
+ PKG_CHECK_MODULES([SELINUX], $LIBSELINUX)
+ SELINUX_LIBS="$SELINUX_LIBS -laudit"
+ AC_DEFINE(XSELINUX, 1, [Build SELinux extension])
+fi
+
+AM_CONDITIONAL(XCSECURITY, [test "x$XCSECURITY" = xyes])
+if test "x$XCSECURITY" = xyes; then
+ if test "x$XACE" != xyes; then
+ AC_MSG_ERROR([cannot build Security extension without X-ACE])
+ fi
+ AC_DEFINE(XCSECURITY, 1, [Build Security extension])
+fi
+
+AM_CONDITIONAL(DBE, [test "x$DBE" = xyes])
+if test "x$DBE" = xyes; then
+ AC_DEFINE(DBE, 1, [Support DBE extension])
+ DBE_LIB='$(top_builddir)/dbe/libdbe.la'
+fi
+
+AM_CONDITIONAL(XF86BIGFONT, [test "x$XF86BIGFONT" = xyes])
+if test "x$XF86BIGFONT" = xyes; then
+ AC_DEFINE(XF86BIGFONT, 1, [Support XF86 Big font extension])
+ REQUIRED_MODULES="$REQUIRED_MODULES $BIGFONTPROTO"
+fi
+
+AM_CONDITIONAL(DPMSExtension, [test "x$DPMSExtension" = xyes])
+if test "x$DPMSExtension" = xyes; then
+ AC_DEFINE(DPMSExtension, 1, [Support DPMS extension])
+fi
+
+if test "x$XCALIBRATE" = xyes && test "$KDRIVE" = yes; then
+ AC_DEFINE(XCALIBRATE, 1, [Build XCalibrate extension])
+ REQUIRED_MODULES="$REQUIRED_MODULES $XCALIBRATEPROTO"
+else
+ XCALIBRATE=no
+fi
+AM_CONDITIONAL(XCALIBRATE, [test "x$XCALIBRATE" = xyes])
+
+AC_DEFINE(RENDER, 1, [Support RENDER extension])
+RENDER_LIB='$(top_builddir)/render/librender.la'
+RENDER_INC='-I$(top_srcdir)/render'
+
+AC_DEFINE(RANDR, 1, [Support RANDR extension])
+RANDR_LIB='$(top_builddir)/randr/librandr.la'
+RANDR_INC='-I$(top_srcdir)/randr'
+
+AC_DEFINE(XFIXES,1,[Support XFixes extension])
+FIXES_LIB='$(top_builddir)/xfixes/libxfixes.la'
+FIXES_INC='-I$(top_srcdir)/xfixes'
+
+AC_DEFINE(DAMAGE,1,[Support Damage extension])
+DAMAGE_LIB='$(top_builddir)/damageext/libdamageext.la'
+DAMAGE_INC='-I$(top_srcdir)/damageext'
+MIEXT_DAMAGE_LIB='$(top_builddir)/miext/damage/libdamage.la'
+MIEXT_DAMAGE_INC='-I$(top_srcdir)/miext/damage'
+
+# XINPUT extension is integral part of the server
+AC_DEFINE(XINPUT, 1, [Support X Input extension])
+XI_LIB='$(top_builddir)/Xi/libXi.la'
+XI_INC='-I$(top_srcdir)/Xi'
+
+AM_CONDITIONAL(XF86UTILS, test "x$XF86UTILS" = xyes)
+AM_CONDITIONAL(XAA, test "x$XAA" = xyes)
+AM_CONDITIONAL(VGAHW, test "x$VGAHW" = xyes)
+AM_CONDITIONAL(VBE, test "x$VBE" = xyes)
+AM_CONDITIONAL(INT10MODULE, test "x$INT10MODULE" = xyes)
+
+AC_DEFINE(SHAPE, 1, [Support SHAPE extension])
+
+AC_DEFINE_DIR(XKB_BASE_DIRECTORY, XKBPATH, [Path to XKB data])
+AC_ARG_WITH(xkb-bin-directory,
+ AS_HELP_STRING([--with-xkb-bin-directory=DIR], [Directory containing xkbcomp program]),
+ [XKB_BIN_DIRECTORY="$withval"],
+ [XKB_BIN_DIRECTORY="$bindir"])
+
+AC_DEFINE_DIR(XKB_BIN_DIRECTORY, XKB_BIN_DIRECTORY, [Path to XKB bin dir])
+
+dnl Make sure XKM_OUTPUT_DIR is an absolute path
+XKBOUTPUT_FIRSTCHAR=`echo $XKBOUTPUT | cut -b 1`
+if [[ x$XKBOUTPUT_FIRSTCHAR != x/ -a x$XKBOUTPUT_FIRSTCHAR != 'x$' ]] ; then
+ XKBOUTPUT="$XKB_BASE_DIRECTORY/$XKBOUTPUT"
+fi
+
+dnl XKM_OUTPUT_DIR (used in code) must end in / or file names get hosed
+dnl XKB_COMPILED_DIR (used in Makefiles) must not or install-sh gets confused
+
+XKBOUTPUT=`echo $XKBOUTPUT/ | $SED 's|/*$|/|'`
+XKB_COMPILED_DIR=`echo $XKBOUTPUT | $SED 's|/*$||'`
+AC_DEFINE_DIR(XKM_OUTPUT_DIR, XKBOUTPUT, [Path to XKB output dir])
+AC_SUBST(XKB_COMPILED_DIR)
+
+if test "x$XKB_DFLT_RULES" = x; then
+ case $host_os in
+ linux*)
+ dnl doesn't take AutoAddDevices into account, but whatever.
+ if test "x$CONFIG_HAL" = xyes; then
+ XKB_DFLT_RULES="evdev"
+ else
+ XKB_DFLT_RULES="base"
+ fi
+ ;;
+ *)
+ XKB_DFLT_RULES="base"
+ ;;
+ esac
+fi
+AC_DEFINE_UNQUOTED(XKB_DFLT_RULES, ["$XKB_DFLT_RULES"], [Default XKB ruleset])
+AC_DEFINE_UNQUOTED(XKB_DFLT_MODEL, ["$XKB_DFLT_MODEL"], [Default XKB model])
+AC_DEFINE_UNQUOTED(XKB_DFLT_LAYOUT, ["$XKB_DFLT_LAYOUT"], [Default XKB layout])
+AC_DEFINE_UNQUOTED(XKB_DFLT_VARIANT, ["$XKB_DFLT_VARIANT"], [Default XKB variant])
+AC_DEFINE_UNQUOTED(XKB_DFLT_OPTIONS, ["$XKB_DFLT_OPTIONS"], [Default XKB options])
+
+XKB_LIB='$(top_builddir)/xkb/libxkb.la'
+XKB_STUB_LIB='$(top_builddir)/xkb/libxkbstubs.la'
+REQUIRED_MODULES="$REQUIRED_MODULES xkbfile"
+
+AC_CHECK_FUNC(strcasecmp, [], AC_DEFINE([NEED_STRCASECMP], 1,
+ [Do not have 'strcasecmp'.]))
+AC_CHECK_FUNC(strncasecmp, [], AC_DEFINE([NEED_STRNCASECMP], 1,
+ [Do not have 'strncasecmp'.]))
+AC_CHECK_FUNC(strcasestr, [], AC_DEFINE([NEED_STRCASESTR], 1,
+ [Do not have 'strcasestr'.]))
+
+PKG_CHECK_MODULES([XDMCP], [xdmcp], [have_libxdmcp="yes"], [have_libxdmcp="no"])
+if test "x$have_libxdmcp" = xyes; then
+ AC_CHECK_LIB(Xdmcp, XdmcpWrap, [have_xdmcpwrap="yes"], [have_xdmcpwrap="no"], [$XDMCP_LIBS])
+fi
+if test "x$XDMCP" = xauto; then
+ if test "x$have_libxdmcp" = xyes; then
+ XDMCP=yes
+ else
+ XDMCP=no
+ fi
+fi
+if test "x$XDMAUTH" = xauto; then
+ if test "x$have_libxdmcp" = xyes && test "x$have_xdmcpwrap" = xyes; then
+ XDMAUTH=yes
+ else
+ XDMAUTH=no
+ fi
+fi
+
+AM_CONDITIONAL(XDMCP, [test "x$XDMCP" = xyes])
+if test "x$XDMCP" = xyes; then
+ AC_DEFINE(XDMCP, 1, [Support XDM Control Protocol])
+ REQUIRED_LIBS="$REQUIRED_LIBS xdmcp"
+ XDMCP_MODULES="xdmcp"
+fi
+
+AM_CONDITIONAL(XDMAUTH, [test "x$XDMAUTH" = xyes])
+if test "x$XDMAUTH" = xyes; then
+ AC_DEFINE(HASXDMAUTH,1,[Support XDM-AUTH*-1])
+ if ! test "x$XDMCP" = xyes; then
+ REQUIRED_LIBS="$REQUIRED_LIBS xdmcp"
+ XDMCP_MODULES="xdmcp"
+ fi
+fi
+
+AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path])
+AC_DEFINE_DIR(PCI_TXT_IDS_PATH, PCI_TXT_IDS_DIR, [Default PCI text file ID path])
+AC_DEFINE_DIR(SERVER_MISC_CONFIG_PATH, SERVERCONFIG, [Server miscellaneous config path])
+AC_DEFINE_DIR(BASE_FONT_PATH, FONTROOTDIR, [Default base font path])
+AC_DEFINE_DIR(DRI_DRIVER_PATH, DRI_DRIVER_PATH, [Default DRI driver path])
+AC_DEFINE_UNQUOTED(XVENDORNAME, ["$VENDOR_NAME"], [Vendor name])
+AC_DEFINE_UNQUOTED(XVENDORNAMESHORT, ["$VENDOR_NAME_SHORT"], [Short vendor name])
+AC_DEFINE_UNQUOTED(XORG_DATE, ["$RELEASE_DATE"], [Vendor release])
+AC_DEFINE_UNQUOTED(XORG_MAN_VERSION, ["$VENDOR_MAN_VERSION"], [Vendor man version])
+AC_DEFINE_UNQUOTED(BUILDERADDR, ["$BUILDERADDR"], [Builder address])
+
+if test -z "$OSNAME"; then
+ OSNAME="UNKNOWN"
+fi
+
+AC_DEFINE_UNQUOTED(OSNAME, ["$OSNAME"], [Operating System Name])
+AC_DEFINE_UNQUOTED(OSVENDOR, ["$OSVENDOR"], [Operating System Vendor])
+AC_DEFINE_UNQUOTED(BUILDERSTRING, ["$BUILDERSTRING"], [Builder string])
+
+AC_SUBST([VENDOR_NAME_SHORT])
+AC_DEFINE_UNQUOTED(VENDOR_NAME, ["$VENDOR_NAME"], [Vendor name])
+AC_DEFINE_UNQUOTED(VENDOR_NAME_SHORT, ["$VENDOR_NAME_SHORT"], [Vendor name])
+AC_DEFINE_UNQUOTED(VENDOR_RELEASE, [$VENDOR_RELEASE], [Vendor release])
+AC_DEFINE_UNQUOTED(VENDOR_MAN_VERSION, ["$VENDOR_MAN_VERSION"], [Vendor man version])
+
+AC_DEFINE(NO_LIBCWRAPPER, 1, [Define to 1 if modules should avoid the libcwrapper])
+
+if test "x$DEBUGGING" = xyes; then
+ AC_DEFINE(DEBUG, 1, [Enable debugging code])
+fi
+AM_CONDITIONAL(DEBUG, [test "x$DEBUGGING" = xyes])
+
+# If unittests aren't explicitly disabled, check for required support
+if test "x$UNITTESTS" != xno ; then
+ PKG_CHECK_MODULES([GLIB], $LIBGLIB,
+ [HAVE_GLIB=yes], [HAVE_GLIB=no])
+
+ # Check if linker supports -wrap, passed via compiler flags
+ # When cross-compiling, reports no, since unit tests run from
+ # "make check", so would be running on build machine, not target
+ AC_MSG_CHECKING([whether the linker supports -wrap])
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -Wl,-wrap,exit"
+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+ void __wrap_exit (int s)
+ {
+ __real_exit (0);
+ }]],
+ [[exit (1);]])],
+ [linker_can_wrap="yes"],
+ [linker_can_wrap="no"],
+ [linker_can_wrap="no"])
+ AC_MSG_RESULT([$linker_can_wrap])
+ LDFLAGS="$save_LDFLAGS"
+fi
+
+if test "x$UNITTESTS" = xauto; then
+ if test "x$HAVE_GLIB" = xyes && test "x$linker_can_wrap" = xyes; then
+ UNITTESTS=yes
+ else
+ UNITTESTS=no
+ fi
+fi
+if test "x$UNITTESTS" = xyes; then
+ if test "x$HAVE_GLIB" = xno; then
+ AC_MSG_ERROR([glib required to build unit tests])
+ fi
+ if test "x$linker_can_wrap" = xno; then
+ AC_MSG_ERROR([ld -wrap support required to build unit tests])
+ fi
+ AC_DEFINE(UNITTESTS, 1, [Enable unit tests])
+ AC_SUBST([GLIB_LIBS])
+ AC_SUBST([GLIB_CFLAGS])
+fi
+AM_CONDITIONAL(UNITTESTS, [test "x$UNITTESTS" = xyes])
+
+AC_DEFINE(XTEST, 1, [Support XTest extension])
+AC_DEFINE(XSYNC, 1, [Support XSync extension])
+AC_DEFINE(XCMISC, 1, [Support XCMisc extension])
+AC_DEFINE(BIGREQS, 1, [Support BigRequests extension])
+
+if test "x$SPECIAL_DTRACE_OBJECTS" = "xyes" ; then
+ DIX_LIB='$(top_builddir)/dix/dix.O'
+ OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS)'
+else
+ DIX_LIB='$(top_builddir)/dix/libdix.la'
+ OS_LIB='$(top_builddir)/os/libos.la'
+fi
+AC_SUBST([DIX_LIB])
+AC_SUBST([OS_LIB])
+
+MAIN_LIB='$(top_builddir)/dix/libmain.la'
+AC_SUBST([MAIN_LIB])
+
+MI_LIB='$(top_builddir)/mi/libmi.la'
+MI_EXT_LIB='$(top_builddir)/mi/libmiext.la'
+MI_INC='-I$(top_srcdir)/mi'
+FB_LIB='$(top_builddir)/fb/libfb.la'
+FB_INC='-I$(top_srcdir)/fb'
+MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/shadow'
+MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la'
+CORE_INCS='-I$(top_srcdir)/include -I$(top_builddir)/include'
+
+# SHA1 hashing
+AC_ARG_WITH([sha1],
+ [AS_HELP_STRING([--with-sha1=libc|libmd|libgcrypt|libcrypto|libsha1|CommonCrypto],
+ [choose SHA1 implementation])])
+AC_CHECK_FUNC([SHA1Init], [HAVE_SHA1_IN_LIBC=yes])
+if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_LIBC" = xyes; then
+ with_sha1=libc
+fi
+if test "x$with_sha1" = xlibc && test "x$HAVE_SHA1_IN_LIBC" != xyes; then
+ AC_MSG_ERROR([libc requested but not found])
+fi
+if test "x$with_sha1" = xlibc; then
+ AC_DEFINE([HAVE_SHA1_IN_LIBC], [1],
+ [Use libc SHA1 functions])
+ SHA1_LIBS=""
+fi
+AC_CHECK_FUNC([CC_SHA1_Init], [HAVE_SHA1_IN_COMMONCRYPTO=yes])
+if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_COMMONCRYPTO" = xyes; then
+ with_sha1=CommonCrypto
+fi
+if test "x$with_sha1" = xCommonCrypto && test "x$HAVE_SHA1_IN_COMMONCRYPTO" != xyes; then
+ AC_MSG_ERROR([CommonCrypto requested but not found])
+fi
+if test "x$with_sha1" = xCommonCrypto; then
+ AC_DEFINE([HAVE_SHA1_IN_COMMONCRYPTO], [1],
+ [Use CommonCrypto SHA1 functions])
+ SHA1_LIBS=""
+fi
+AC_CHECK_LIB([md], [SHA1Init], [HAVE_LIBMD=yes])
+if test "x$with_sha1" = x && test "x$HAVE_LIBMD" = xyes; then
+ with_sha1=libmd
+fi
+if test "x$with_sha1" = xlibmd && test "x$HAVE_LIBMD" != xyes; then
+ AC_MSG_ERROR([libmd requested but not found])
+fi
+if test "x$with_sha1" = xlibmd; then
+ AC_DEFINE([HAVE_SHA1_IN_LIBMD], [1],
+ [Use libmd SHA1 functions])
+ SHA1_LIBS=-lmd
+fi
+AC_CHECK_LIB([sha1], [sha1_begin], [HAVE_LIBSHA1=yes])
+if test "x$with_sha1" = x && test "x$HAVE_LIBSHA1" = xyes; then
+ with_sha1=libsha1
+fi
+if test "x$with_sha1" = xlibsha1 && test "x$HAVE_LIBSHA1" != xyes; then
+ AC_MSG_ERROR([libsha1 requested but not found])
+fi
+if test "x$with_sha1" = xlibsha1; then
+ AC_DEFINE([HAVE_SHA1_IN_LIBSHA1], [1],
+ [Use libsha1 for SHA1])
+ SHA1_LIBS=-lsha1
+fi
+AC_CHECK_LIB([gcrypt], [gcry_md_open], [HAVE_LIBGCRYPT=yes])
+if test "x$with_sha1" = x && test "x$HAVE_LIBGCRYPT" = xyes; then
+ with_sha1=libgcrypt
+fi
+if test "x$with_sha1" = xlibgcrypt && test "x$HAVE_LIBGCRYPT" != xyes; then
+ AC_MSG_ERROR([libgcrypt requested but not found])
+fi
+if test "x$with_sha1" = xlibgcrypt; then
+ AC_DEFINE([HAVE_SHA1_IN_LIBGCRYPT], [1],
+ [Use libgcrypt SHA1 functions])
+ SHA1_LIBS=-lgcrypt
+fi
+# We don't need all of the OpenSSL libraries, just libcrypto
+AC_CHECK_LIB([crypto], [SHA1_Init], [HAVE_LIBCRYPTO=yes])
+PKG_CHECK_MODULES([OPENSSL], [openssl], [HAVE_OPENSSL_PKC=yes],
+ [HAVE_OPENSSL_PKC=no])
+if test "x$HAVE_LIBCRYPTO" = xyes || test "x$HAVE_OPENSSL_PKC" = xyes; then
+ if test "x$with_sha1" = x; then
+ with_sha1=libcrypto
+ fi
+else
+ if test "x$with_sha1" = xlibcrypto; then
+ AC_MSG_ERROR([OpenSSL libcrypto requested but not found])
+ fi
+fi
+if test "x$with_sha1" = xlibcrypto; then
+ if test "x$HAVE_LIBCRYPTO" = xyes; then
+ SHA1_LIBS=-lcrypto
+ else
+ SHA1_LIBS="$OPENSSL_LIBS"
+ SHA1_CFLAGS="$OPENSSL_CFLAGS"
+ fi
+fi
+AC_MSG_CHECKING([for SHA1 implementation])
+if test "x$with_sha1" = x; then
+ AC_MSG_ERROR([No suitable SHA1 implementation found])
+fi
+AC_MSG_RESULT([$with_sha1])
+AC_SUBST(SHA1_LIBS)
+AC_SUBST(SHA1_CFLAGS)
+
+PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQUIRED_MODULES $REQUIRED_LIBS])
+PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
+
+# Autotools has some unfortunate issues with library handling. In order to
+# get a server to rebuild when a dependency in the tree is changed, it must
+# be listed in SERVERNAME_DEPENDENCIES. However, no system libraries may be
+# listed there, or some versions of autotools will break (especially if a -L
+# is required to find the library). So, we keep two sets of libraries
+# detected: NAMESPACE_LIBS for in-tree libraries to be linked against, which
+# will go into the _DEPENDENCIES and _LDADD of the server, and
+# NAMESPACE_SYS_LIBS which will go into only the _LDADD. The
+# NAMESPACEMODULES_LIBS detected from pkgconfig should always go in
+# NAMESPACE_SYS_LIBS.
+#
+# XSERVER_LIBS is the set of in-tree libraries which all servers require.
+# XSERVER_SYS_LIBS is the set of out-of-tree libraries which all servers
+# require.
+#
+XSERVER_CFLAGS="${XSERVER_CFLAGS} ${XSERVERCFLAGS_CFLAGS}"
+XSERVER_LIBS="$DIX_LIB $MI_LIB $OS_LIB"
+XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}"
+AC_SUBST([XSERVER_LIBS])
+AC_SUBST([XSERVER_SYS_LIBS])
+
+UTILS_SYS_LIBS="${SYS_LIBS}"
+AC_SUBST([UTILS_SYS_LIBS])
+
+# The Xorg binary needs to export symbols so that they can be used from modules
+# Some platforms require extra flags to do this. libtool should set the
+# necessary flags for each platform when -export-dynamic is passed to it.
+LD_EXPORT_SYMBOLS_FLAG="-export-dynamic"
+AC_SUBST([LD_EXPORT_SYMBOLS_FLAG])
+
+dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so
+dnl we need to replicate that here until those can all be fixed
+AC_MSG_CHECKING([if SVR4 needs to be defined])
+AC_EGREP_CPP([I_AM_SVR4],[
+#if defined(SVR4) || defined(__svr4__) || defined(__SVR4)
+ I_AM_SVR4
+#endif
+],[
+AC_DEFINE([SVR4],1,[Define to 1 on systems derived from System V Release 4])
+AC_MSG_RESULT([yes])], AC_MSG_RESULT([no]))
+
+XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC"
+
+dnl ---------------------------------------------------------------------------
+dnl DDX section.
+dnl ---------------------------------------------------------------------------
+
+dnl Xvfb DDX
+
+AC_MSG_CHECKING([whether to build Xvfb DDX])
+AC_MSG_RESULT([$XVFB])
+AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes])
+
+if test "x$XVFB" = xyes; then
+ XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB"
+ XVFB_SYS_LIBS="$XVFBMODULES_LIBS $GLX_SYS_LIBS"
+ AC_SUBST([XVFB_LIBS])
+ AC_SUBST([XVFB_SYS_LIBS])
+fi
+
+
+dnl Xnest DDX
+
+PKG_CHECK_MODULES(XNESTMODULES, [xfont $LIBXEXT x11 xau $XDMCP_MODULES], [have_xnest=yes], [have_xnest=no])
+AC_MSG_CHECKING([whether to build Xnest DDX])
+if test "x$XNEST" = xauto; then
+ XNEST="$have_xnest"
+fi
+AC_MSG_RESULT([$XNEST])
+AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes])
+
+if test "x$XNEST" = xyes; then
+ if test "x$have_xnest" = xno; then
+ AC_MSG_ERROR([Xnest build explicitly requested, but required modules not found.])
+ fi
+ XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DIX_LIB $MAIN_LIB $OS_LIB"
+ XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS"
+ AC_SUBST([XNEST_LIBS])
+ AC_SUBST([XNEST_SYS_LIBS])
+fi
+
+
+dnl Xorg DDX
+
+AC_MSG_CHECKING([whether to build Xorg DDX])
+if test "x$XORG" = xauto; then
+ XORG="yes"
+ case $host_os in
+ cygwin*) XORG="no" ;;
+ darwin*) XORG="no" ;;
+ esac
+fi
+AC_MSG_RESULT([$XORG])
+
+xorg_bus_linuxpci=no
+xorg_bus_bsdpci=no
+xorg_bus_sparc=no
+
+if test "x$XORG" = xyes; then
+ XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
+ XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
+ XORG_INCS="$XORG_DDXINCS $XORG_OSINCS"
+ XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H"
+ XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB"
+
+ dnl ==================================================================
+ dnl symbol visibility
+ symbol_visibility=
+ have_visibility=disabled
+ if test x$SYMBOL_VISIBILITY != xno; then
+ AC_MSG_CHECKING(for symbol visibility support)
+ if test x$GCC = xyes; then
+ VISIBILITY_CFLAGS="-fvisibility=hidden"
+ else
+ AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
+ if test x$SUNCC = xyes; then
+ VISIBILITY_CFLAGS="-xldscope=hidden"
+ else
+ have_visibility=no
+ fi
+ fi
+ if test x$have_visibility != xno; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $VISIBILITY_CFLAGS"
+ AC_TRY_COMPILE(
+ [#include <X11/Xfuncproto.h>
+ extern _X_HIDDEN int hidden_int;
+ extern _X_EXPORT int public_int;
+ extern _X_HIDDEN int hidden_int_func(void);
+ extern _X_EXPORT int public_int_func(void);],
+ [],
+ have_visibility=yes,
+ have_visibility=no)
+ CFLAGS=$save_CFLAGS
+ fi
+ AC_MSG_RESULT([$have_visibility])
+ if test x$have_visibility != xno; then
+ symbol_visibility=$VISIBILITY_CFLAGS
+ XORG_CFLAGS="$XORG_CFLAGS $VISIBILITY_CFLAGS"
+ XSERVER_CFLAGS="$XSERVER_CFLAGS $VISIBILITY_CFLAGS"
+ fi
+ fi
+ dnl added to xorg-server.pc
+ AC_SUBST([symbol_visibility])
+ dnl ===================================================================
+
+ PKG_CHECK_MODULES([PCIACCESS], $LIBPCIACCESS)
+ SAVE_LIBS=$LIBS
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS=$PCIACCESS_CFLAGS
+ LIBS=$PCIACCESS_LIBS
+ AC_CHECK_FUNCS([pci_system_init_dev_mem])
+ AC_CHECK_FUNCS([pci_device_enable])
+ AC_CHECK_FUNCS([pci_device_is_boot_vga])
+ AC_CHECK_FUNCS([pci_device_vgaarb_init])
+ LIBS=$SAVE_LIBS
+ CFLAGS=$SAVE_CFLAGS
+ XORG_SYS_LIBS="$XORG_SYS_LIBS $PCIACCESS_LIBS $GLX_SYS_LIBS"
+ XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS"
+
+ case $host_os in
+ linux*)
+ if test "x$LNXAPM" = xyes; then
+ XORG_CFLAGS="$XORG_CFLAGS -DXF86PM"
+ fi
+ XORG_OS="linux"
+ XORG_OS_SUBDIR="linux"
+ xorg_bus_linuxpci="yes"
+ linux_acpi="no"
+ case $host_cpu in
+ ia64*)
+ linux_ia64=yes
+ linux_acpi="yes"
+ ;;
+ alpha*)
+ linux_alpha=yes
+ ;;
+ i*86|amd64*|x86_64*)
+ linux_acpi="yes"
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | kfreebsd*-gnu | dragonfly*)
+ XORG_OS="freebsd"
+ XORG_OS_SUBDIR="bsd"
+ xorg_bus_bsdpci="yes"
+ ;;
+ netbsd*)
+ XORG_OS="netbsd"
+ XORG_OS_SUBDIR="bsd"
+ xorg_bus_bsdpci="yes"
+ ;;
+ openbsd*)
+ if test "x$ac_cv_BSD_APM" = xyes \
+ -o "x$ac_cv_BSD_KQUEUE_APM" = xyes; then
+ XORG_CFLAGS="$XORG_CFLAGS -DXF86PM"
+ fi
+ XORG_OS="openbsd"
+ XORG_OS_SUBDIR="bsd"
+ xorg_bus_bsdpci="yes"
+ ;;
+ solaris*)
+ XORG_OS="solaris"
+ XORG_OS_SUBDIR="solaris"
+ XORG_CFLAGS="$XORG_CFLAGS -DXF86PM"
+ # Use the same stubs as BSD for old functions, since we now
+ # use libpciaccess for PCI
+ xorg_bus_bsdpci="yes"
+ AC_CHECK_HEADERS([sys/kd.h])
+ AC_CHECK_HEADERS([sys/vt.h], [solaris_vt=yes], [solaris_vt=no])
+ # Check for minimum supported release
+ AC_MSG_CHECKING([Solaris version])
+ OS_MINOR=`echo ${host_os}|$SED -e 's/^.*solaris2\.//' -e s'/\..*$//'`
+ if test "${OS_MINOR}" -ge 7 ; then
+ AC_MSG_RESULT(Solaris ${OS_MINOR})
+ else
+ AC_MSG_RESULT(Solaris `echo ${host_os}|$SED -e 's/^.*solaris//`)
+ fi
+ if test "${OS_MINOR}" -lt 8 ; then
+ AC_MSG_ERROR([This release no longer supports Solaris versions older than Solaris 8.])
+ fi
+ AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
+ if test "x$SUNCC" = "xyes"; then
+ solaris_asm_inline="yes"
+ fi
+ AC_CHECK_DECL([_LP64], [SOLARIS_64="yes"], [SOLARIS_64="no"])
+
+ case $host_cpu in
+ sparc*)
+ SOLARIS_INOUT_ARCH="sparcv8plus"
+ ;;
+ i*86)
+ if test x$SOLARIS_64 = xyes ; then
+ SOLARIS_INOUT_ARCH="amd64"
+ else
+ SOLARIS_INOUT_ARCH="ia32"
+ fi
+ ;;
+ *)
+ AC_MSG_ERROR([Unsupported Solaris platform. Only SPARC & x86 \
+ are supported on Solaris in this release. If you are \
+ interested in porting Xorg to your platform, please email \
+ xorg@lists.freedesktop.org.]) ;;
+ esac
+ AC_SUBST([SOLARIS_INOUT_ARCH])
+ if test x$solaris_asm_inline = xyes ; then
+ SOLARIS_ASM_CFLAGS='$(top_srcdir)/hw/xfree86/os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il'
+ XORG_CFLAGS="${XORG_CFLAGS} "'$(SOLARIS_ASM_CFLAGS)'
+ fi
+ AC_SUBST([SOLARIS_ASM_CFLAGS])
+ if test "x$SUPPORT_PC98" = xauto; then
+ SUPPORT_PC98="no"
+ fi
+ ;;
+ gnu*)
+ XORG_OS="gnu"
+ XORG_OS_SUBDIR="hurd"
+ # Use the same stubs as BSD for old functions, since we now
+ # use libpciaccess for PCI
+ xorg_bus_bsdpci="yes"
+ ;;
+ *)
+ XORG_OS="unknown"
+ XORG_OS_SUBDIR="unknown"
+ AC_MSG_ERROR([m4_text_wrap(m4_join([ ],
+ [Your OS is unknown. Xorg currently only supports Linux,],
+ [Free/Open/Net/DragonFlyBSD, Solaris/OpenSolaris, & GNU Hurd.],
+ [If you are interested in porting Xorg to your platform,],
+ [please email xorg@lists.freedesktop.org.]))])
+ ;;
+ esac
+
+ case $host_cpu in
+ sparc*)
+ xorg_bus_sparc="yes"
+ ;;
+ i*86)
+ if test "x$SUPPORT_PC98" = xauto; then
+ SUPPORT_PC98="yes"
+ fi
+ ;;
+ esac
+
+ if test "x$SUPPORT_PC98" = xauto; then
+ SUPPORT_PC98="no"
+ fi
+ if test "x$SUPPORT_PC98" = xyes; then
+ AC_DEFINE(SUPPORT_PC98, 1, [Support PC98])
+ fi
+ if test "x$XORG_OS_PCI" = x ; then
+ XORG_OS_PCI=$XORG_OS
+ fi
+ if test "x$DGA" = xauto; then
+ PKG_CHECK_MODULES(DGA, $DGAPROTO, [DGA=yes], [DGA=no])
+ fi
+ if test "x$DGA" = xyes; then
+ XORG_MODULES="$XORG_MODULES $DGAPROTO"
+ PKG_CHECK_MODULES(DGA, $DGAPROTO)
+ AC_DEFINE(DGA, 1, [Support DGA extension])
+ AC_DEFINE(XFreeXDGA, 1, [Build XDGA support])
+ fi
+
+ if test "x$XF86VIDMODE" = xauto; then
+ PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO, [XF86VIDMODE=yes], [XF86VIDMODE=no])
+ fi
+ if test "x$XF86VIDMODE" = xyes; then
+ XORG_MODULES="$XORG_MODULES $VIDMODEPROTO"
+ PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO)
+ AC_DEFINE(XF86VIDMODE, 1, [Support XFree86 Video Mode extension])
+ fi
+
+ if test -n "$XORG_MODULES"; then
+ PKG_CHECK_MODULES(XORG_MODULES, [$XORG_MODULES])
+ XORG_CFLAGS="$XORG_CFLAGS $XORG_MODULES_CFLAGS"
+ XORG_SYS_LIBS="$XORG_SYS_LIBS $XORG_MODULES_LIBS"
+ fi
+
+ AC_SUBST([XORG_LIBS])
+ AC_SUBST([XORG_SYS_LIBS])
+ AC_SUBST([XORG_INCS])
+ AC_SUBST([XORG_OS])
+ AC_SUBST([XORG_OS_SUBDIR])
+
+ AC_PATH_PROG(PERL, perl, no)
+ dnl unlikely as this may be ...
+ if test "x$PERL" = xno; then
+ AC_MSG_ERROR([Perl is required to build the XFree86/Xorg DDX.])
+ fi
+ AC_SUBST(PERL)
+
+ AC_SUBST([XORG_CFLAGS])
+
+ dnl these only go in xorg-config.h
+ XF86CONFIGFILE="xorg.conf"
+ XF86CONFIGDIR="xorg.conf.d"
+ AC_SUBST(XF86CONFIGDIR)
+ CONFIGFILE="$sysconfdir/$XF86CONFIGFILE"
+ LOGPREFIX="$logdir/Xorg."
+ AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
+ AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
+ AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
+ AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server])
+ AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+ AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
+ AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
+ AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
+ AC_DEFINE_DIR(__XCONFIGFILE__, XF86CONFIGFILE, [Name of configuration file])
+ AC_DEFINE_DIR(XF86CONFIGFILE, XF86CONFIGFILE, [Name of configuration file])
+ AC_DEFINE_DIR(__XCONFIGDIR__, XF86CONFIGDIR, [Name of configuration directory])
+ AC_DEFINE_DIR(DEFAULT_MODULE_PATH, moduledir, [Default module search path])
+ AC_DEFINE_DIR(DEFAULT_LIBRARY_PATH, libdir, [Default library install path])
+ AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default log location])
+ AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
+ AC_DEFINE(XSERVER_LIBPCIACCESS, 1, [Use libpciaccess for all pci manipulation])
+ if test "x$VGAHW" = xyes; then
+ AC_DEFINE(WITH_VGAHW, 1, [Building vgahw module])
+ fi
+
+ driverdir="$moduledir/drivers"
+ AC_SUBST([moduledir])
+ AC_SUBST([driverdir])
+ sdkdir="$includedir/xorg"
+ extdir="$includedir/X11/extensions"
+ sysconfigdir="$datadir/X11/$XF86CONFIGDIR"
+ AC_SUBST([sdkdir])
+ AC_SUBST([extdir])
+ AC_SUBST([sysconfigdir])
+ AC_SUBST([logdir])
+
+ # stuff the ABI versions into the pc file too
+ extract_abi() {
+ grep ^.define.*${1}_VERSION ${srcdir}/hw/xfree86/common/xf86Module.h | tr '(),' ' .' | awk '{ print $4$5 }'
+ }
+ abi_ansic=`extract_abi ANSIC`
+ abi_videodrv=`extract_abi VIDEODRV`
+ abi_xinput=`extract_abi XINPUT`
+ abi_extension=`extract_abi EXTENSION`
+ AC_SUBST([abi_ansic])
+ AC_SUBST([abi_videodrv])
+ AC_SUBST([abi_xinput])
+ AC_SUBST([abi_extension])
+fi
+AM_CONDITIONAL([XORG], [test "x$XORG" = xyes])
+AM_CONDITIONAL([XORG_BUS_LINUXPCI], [test "x$xorg_bus_linuxpci" = xyes])
+AM_CONDITIONAL([XORG_BUS_BSDPCI], [test "x$xorg_bus_bsdpci" = xyes])
+AM_CONDITIONAL([XORG_BUS_SPARC], [test "x$xorg_bus_sparc" = xyes])
+AM_CONDITIONAL([LINUX_IA64], [test "x$linux_ia64" = xyes])
+AM_CONDITIONAL([LINUX_ALPHA], [test "x$linux_alpha" = xyes])
+AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes])
+AM_CONDITIONAL([SOLARIS_ASM_INLINE], [test "x$solaris_asm_inline" = xyes])
+AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes])
+AM_CONDITIONAL([DGA], [test "x$DGA" = xyes])
+AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
+
+dnl XWin DDX
+
+AC_MSG_CHECKING([whether to build XWin DDX])
+if test "x$XWIN" = xauto; then
+ case $host_os in
+ cygwin*) XWIN="yes" ;;
+ mingw*) XWIN="yes" ;;
+ *) XWIN="no" ;;
+ esac
+fi
+AC_MSG_RESULT([$XWIN])
+
+if test "x$XWIN" = xyes; then
+ AC_DEFINE_DIR(SYSCONFDIR, sysconfdir, [Location of system.XWinrc])
+ AC_DEFINE_DIR(DEFAULT_LOGDIR, logdir, [Default log location])
+ AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+ AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
+ AC_CHECK_TOOL(WINDRES, windres)
+
+ PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfont])
+
+ if test "x$WINDOWSWM" = xauto; then
+ PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no])
+ fi
+ if test "x$WINDOWSWM" = xyes ; then
+ PKG_CHECK_MODULES(WINDOWSWM, $WINDOWSWMPROTO)
+ XWINMODULES_CFLAGS="$XWINMODULES_CFLAGS $WINDOWSWM_CFLAGS"
+ AC_DEFINE(ROOTLESS,1,[Build Rootless code])
+ fi
+
+ case $host_os in
+ cygwin*)
+ XWIN_SERVER_NAME=XWin
+ AC_DEFINE(HAS_DEVWINDOWS,1,[Cygwin has /dev/windows for signaling new win32 messages])
+ ;;
+ mingw*)
+ XWIN_SERVER_NAME=Xming
+ AC_DEFINE(RELOCATE_PROJECTROOT,1,[Make PROJECT_ROOT relative to the xserver location])
+ AC_DEFINE(HAS_WINSOCK,1,[Use Windows sockets])
+ XWIN_SYS_LIBS=-lwinsock2
+ ;;
+ esac
+ XWIN_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $RANDR_LIB $RENDER_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $OS_LIB"
+ XWIN_SYS_LIBS="$XWIN_SYS_LIBS $XWINMODULES_LIBS"
+ AC_SUBST(XWIN_LIBS)
+ AC_SUBST(XWIN_SERVER_NAME)
+ AC_SUBST(XWIN_SYS_LIBS)
+
+ if test "x$DEBUGGING" = xyes; then
+ AC_DEFINE(CYGDEBUG, 1, [Simple debug messages])
+ AC_DEFINE(CYGWINDOWING_DEBUG, 1, [Debug messages for window handling])
+ AC_DEFINE(CYGMULTIWINDOW_DEBUG, 1, [Debug window manager])
+ fi
+
+ AC_DEFINE(DDXOSVERRORF, 1, [Use OsVendorVErrorF])
+ AC_DEFINE(DDXBEFORERESET, 1, [Use ddxBeforeReset ])
+fi
+AM_CONDITIONAL(XWIN, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_MULTIWINDOW, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_MULTIWINDOWEXTWM, [test "x$XWIN" = xyes && test "x$WINDOWSWM" = xyes])
+AM_CONDITIONAL(XWIN_CLIPBOARD, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_GLX_WINDOWS, [test "x$XWIN" = xyes && false])
+AM_CONDITIONAL(XWIN_NATIVEGDI, [test "x$XWIN" = xyes && false])
+AM_CONDITIONAL(XWIN_PRIMARYFB, [test "x$XWIN" = xyes && false])
+AM_CONDITIONAL(XWIN_RANDR, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_XV, [test "x$XWIN" = xyes && test "x$XV" = xyes])
+
+dnl Darwin / OS X DDX
+if test "x$XQUARTZ" = xyes; then
+ AC_DEFINE(XQUARTZ,1,[Have Quartz])
+ AC_DEFINE(ROOTLESS,1,[Build Rootless code])
+
+ DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB"
+ AC_SUBST([DARWIN_LIBS])
+
+ AC_CHECK_LIB([Xplugin],[xp_init],[:])
+
+ CFLAGS="${CFLAGS} -DROOTLESS_WORKAROUND -DROOTLESS_SAFEALPHA -DNO_ALLOCA"
+
+ PKG_CHECK_MODULES(XPBPROXY, $APPLEWMPROTO $LIBAPPLEWM xfixes x11)
+
+ if test "x$XQUARTZ_SPARKLE" = xyes ; then
+ AC_DEFINE(XQUARTZ_SPARKLE,1,[Support application updating through sparkle.])
+ fi
+
+ if test "x$STANDALONE_XPBPROXY" = xyes ; then
+ AC_DEFINE(STANDALONE_XPBPROXY,1,[Build a standalone xpbproxy])
+ fi
+fi
+
+# Support for objc in autotools is minimal and not documented.
+OBJC='$(CC)'
+OBJCLD='$(CCLD)'
+OBJCLINK='$(LINK)'
+OBJCFLAGS='$(CFLAGS)'
+AC_SUBST([OBJC])
+AC_SUBST([OBJCCLD])
+AC_SUBST([OBJCLINK])
+AC_SUBST([OBJCFLAGS])
+# internal, undocumented automake func follows :(
+_AM_DEPENDENCIES([OBJC])
+AM_CONDITIONAL(XQUARTZ, [test "x$XQUARTZ" = xyes])
+AM_CONDITIONAL(XQUARTZ_SPARKLE, [test "x$XQUARTZ_SPARKLE" != "xno"])
+AM_CONDITIONAL(STANDALONE_XPBPROXY, [test "x$STANDALONE_XPBPROXY" = xyes])
+
+dnl DMX DDX
+PKG_CHECK_MODULES(
+ [DMXMODULES],
+ [xmuu $LIBXEXT x11 xrender xfixes xfont $LIBXI $DMXPROTO xau $XDMCP_MODULES],
+ [PKG_CHECK_MODULES(
+ [XDMXCONFIG_DEP],
+ [xaw7 xmu xt xpm x11],
+ [have_dmx=yes],
+ [have_dmx=no])],
+ [have_dmx=no])
+AC_MSG_CHECKING([whether to build Xdmx DDX])
+if test "x$DMX" = xauto; then
+ DMX="$have_dmx"
+ case $host_os in
+ cygwin*) DMX="no" ;;
+ darwin*) DMX="no" ;;
+ esac
+fi
+AC_MSG_RESULT([$DMX])
+AM_CONDITIONAL(DMX, [test "x$DMX" = xyes])
+
+if test "x$DMX" = xyes; then
+ if test "x$have_dmx" = xno; then
+ AC_MSG_ERROR([Xdmx build explicitly requested, but required
+ modules not found.])
+ fi
+ DMX_INCLUDES="$XEXT_INC $RENDER_INC $RECORD_INC"
+ XDMX_CFLAGS="$DMXMODULES_CFLAGS"
+ XDMX_LIBS="$FB_LIB $MI_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $XEXT_LIB $MAIN_LIB $DIX_LIB $OS_LIB $FIXES_LIB"
+ XDMX_SYS_LIBS="$DMXMODULES_LIBS"
+ AC_SUBST([XDMX_CFLAGS])
+ AC_SUBST([XDMX_LIBS])
+ AC_SUBST([XDMX_SYS_LIBS])
+
+dnl USB sources in DMX require <linux/input.h>
+ AC_CHECK_HEADER([linux/input.h], DMX_BUILD_USB="yes",
+ DMX_BUILD_USB="no")
+dnl Linux sources in DMX require <linux/keyboard.h>
+ AC_CHECK_HEADER([linux/keyboard.h], DMX_BUILD_LNX="yes",
+ DMX_BUILD_LNX="no")
+ AC_SUBST(XDMXCONFIG_DEP_CFLAGS)
+ AC_SUBST(XDMXCONFIG_DEP_LIBS)
+ PKG_CHECK_MODULES([DMXEXAMPLES_DEP], [$LIBDMX $LIBXEXT x11])
+ AC_SUBST(DMXEXAMPLES_DEP_LIBS)
+ PKG_CHECK_MODULES([DMXXMUEXAMPLES_DEP], [$LIBDMX xmu $LIBXEXT x11])
+ AC_SUBST(DMXXMUEXAMPLES_DEP_LIBS)
+ PKG_CHECK_MODULES([DMXXIEXAMPLES_DEP], [$LIBDMX $LIBXI $LIBXEXT x11])
+ AC_SUBST(DMXXIEXAMPLES_DEP_LIBS)
+ PKG_CHECK_MODULES([XTSTEXAMPLES_DEP], [$LIBXTST $LIBXEXT x11])
+ AC_SUBST(XTSTEXAMPLES_DEP_LIBS)
+ PKG_CHECK_MODULES([XRESEXAMPLES_DEP], [xres $LIBXEXT x11])
+ AC_SUBST(XRESEXAMPLES_DEP_LIBS)
+ PKG_CHECK_MODULES([X11EXAMPLES_DEP], [$LIBXEXT x11])
+ AC_SUBST(X11EXAMPLES_DEP_LIBS)
+
+fi
+AM_CONDITIONAL([DMX_BUILD_LNX], [test "x$DMX_BUILD_LNX" = xyes])
+AM_CONDITIONAL([DMX_BUILD_USB], [test "x$DMX_BUILD_USB" = xyes])
+
+dnl kdrive DDX
+
+XEPHYR_LIBS=
+XEPHYR_INCS=
+
+AM_CONDITIONAL(KDRIVE, [test x$KDRIVE = xyes])
+
+if test "$KDRIVE" = yes; then
+ AC_DEFINE(KDRIVESERVER,1,[Build Kdrive X server])
+ AC_DEFINE(KDRIVEDDXACTIONS,,[Build kdrive ddx])
+
+ AC_CHECK_HEADERS([linux/fb.h])
+ if test "$ac_cv_header_linux_fb_h" = yes && test "x$XFBDEV" = xauto; then
+ XFBDEV=yes
+ fi
+
+ if test "x$XFBDEV" = xyes; then
+ KDRIVEFBDEVLIB=yes
+ AC_DEFINE(KDRIVEFBDEV, 1, [Build fbdev-based kdrive server])
+ fi
+
+
+ PKG_CHECK_MODULES([TSLIB], [tslib-0.0], [HAVE_TSLIB="yes"], [HAVE_TSLIB="no"])
+ if test "x$HAVE_TSLIB" = xno; then
+ AC_CHECK_LIB(ts, ts_open, [HAVE_TSLIB="yes"])
+ fi
+
+ if test "xTSLIB" = xauto; then
+ TSLIB="$HAVE_TSLIB"
+ fi
+
+ if test "x$TSLIB" = xyes; then
+ if ! test "x$HAVE_TSLIB" = xyes; then
+ AC_MSG_ERROR([tslib must be installed to build the tslib driver. See http://tslib.berlios.de/])
+ else
+ AC_DEFINE(TSLIB, 1, [Have tslib support])
+ fi
+ fi
+
+ if test "x$KDRIVE_KBD" = xyes; then
+ AC_DEFINE(KDRIVE_KBD, 1, [Enable KDrive kbd driver])
+ fi
+ if test "x$KDRIVE_EVDEV" = xyes; then
+ AC_DEFINE(KDRIVE_EVDEV, 1, [Enable KDrive evdev driver])
+ fi
+ if test "x$KDRIVE_MOUSE" = xyes; then
+ AC_DEFINE(KDRIVE_MOUSE, 1, [Enable KDrive mouse driver])
+ fi
+
+ XEPHYR_REQUIRED_LIBS="x11 $LIBXEXT xfont xau xdmcp"
+ if test "x$XV" = xyes; then
+ XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xv"
+ fi
+ if test "x$DRI" = xyes && test "x$GLX" = xyes; then
+ XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm"
+ fi
+
+ PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"])
+ if test "x$XEPHYR" = xauto; then
+ XEPHYR=$xephyr
+ fi
+
+ # Xephyr needs nanosleep() which is in librt on Solaris
+ AC_CHECK_FUNC([nanosleep], [],
+ AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt"))
+
+ # damage shadow extension glx (NOTYET) fb mi
+ KDRIVE_INC='-I$(top_srcdir)/hw/kdrive/src'
+ KDRIVE_PURE_INCS="$KDRIVE_INC $MIEXT_DAMAGE_INC $MIEXT_SHADOW_INC $XEXT_INC $FB_INC $MI_INC"
+ KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux'
+ KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC"
+
+ KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS"
+
+ KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $OS_LIB"
+ KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.la'
+ case $host_os in
+ *linux*)
+ KDRIVE_OS_LIB='$(top_builddir)/hw/kdrive/linux/liblinux.la'
+ KDRIVELINUX=yes
+ if test "x$KDRIVE_EVDEV" = xauto; then
+ KDRIVE_EVDEV=yes
+ fi
+ if test "x$KDRIVE_KBD" = xauto; then
+ KDRIVE_KBD=yes
+ fi
+ if test "x$KDRIVE_MOUSE" = xauto; then
+ KDRIVE_MOUSE=yes
+ fi
+ ;;
+ *)
+ if test "x$KDRIVE_EVDEV" = xauto; then
+ KDRIVE_EVDEV=no
+ fi
+ if test "x$KDRIVE_KBD" = xauto; then
+ KDRIVE_KBD=no
+ fi
+ if test "x$KDRIVE_MOUSE" = xauto; then
+ KDRIVE_MOUSE=no
+ fi
+ ;;
+ esac
+ KDRIVE_STUB_LIB='$(top_builddir)/hw/kdrive/src/libkdrivestubs.la'
+ KDRIVE_LOCAL_LIBS="$MAIN_LIB $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB"
+ KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
+ KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB"
+ KDRIVE_LIBS="$TSLIB_LIBS $KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $GLX_SYS_LIBS $DLOPEN_LIBS"
+
+ AC_SUBST([XEPHYR_LIBS])
+ AC_SUBST([XEPHYR_INCS])
+fi
+AC_SUBST([KDRIVE_INCS])
+AC_SUBST([KDRIVE_PURE_INCS])
+AC_SUBST([KDRIVE_CFLAGS])
+AC_SUBST([KDRIVE_PURE_LIBS])
+AC_SUBST([KDRIVE_LOCAL_LIBS])
+AC_SUBST([KDRIVE_LIBS])
+AM_CONDITIONAL(KDRIVELINUX, [test "x$KDRIVELINUX" = xyes])
+AM_CONDITIONAL(KDRIVE_EVDEV, [test "x$KDRIVE_EVDEV" = xyes])
+AM_CONDITIONAL(KDRIVE_KBD, [test "x$KDRIVE_KBD" = xyes])
+AM_CONDITIONAL(KDRIVE_MOUSE, [test "x$KDRIVE_MOUSE" = xyes])
+AM_CONDITIONAL(TSLIB, [test "x$HAVE_TSLIB" = xyes])
+AM_CONDITIONAL(KDRIVEFBDEV, [test "x$XFBDEV" = xyes])
+AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes])
+AM_CONDITIONAL(BUILD_KDRIVEFBDEVLIB, [test "x$KDRIVE" = xyes && test "x$KDRIVEFBDEVLIB" = xyes])
+AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes])
+
+dnl and the rest of these are generic, so they're in config.h
+dnl
+dnl though, thanks to the passing of some significant amount of time, the
+dnl above is probably a complete fallacy, and you should not rely on it.
+dnl but this is still actually better than imake, honest. -daniels
+
+AC_TRY_COMPILE([
+#include <features.h>
+#ifndef __GLIBC__
+#error not glibc
+#endif
+], [], [AC_DEFINE(_GNU_SOURCE, 1,
+ [ Enable GNU and other extensions to the C environment for glibc])])
+
+AC_DEFINE_DIR(PROJECTROOT, prefix, [Overall prefix])
+
+AC_SUBST([RELEASE_DATE])
+BUILD_DATE="`date +'%Y%m%d'`"
+AC_SUBST([BUILD_DATE])
+BUILD_TIME="`date +'1%H%M%S'`"
+AC_SUBST([BUILD_TIME])
+
+DIX_CFLAGS="-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS"
+
+AC_SUBST([DIX_CFLAGS])
+
+AC_SUBST([libdir])
+AC_SUBST([exec_prefix])
+AC_SUBST([prefix])
+
+AC_OUTPUT([
+Makefile
+glx/Makefile
+include/Makefile
+composite/Makefile
+damageext/Makefile
+dbe/Makefile
+dix/Makefile
+doc/Makefile
+doc/xml/Makefile
+doc/xml/xserver.ent
+fb/Makefile
+record/Makefile
+config/Makefile
+mi/Makefile
+miext/Makefile
+miext/damage/Makefile
+miext/shadow/Makefile
+miext/cw/Makefile
+miext/rootless/Makefile
+os/Makefile
+randr/Makefile
+render/Makefile
+xkb/Makefile
+Xext/Makefile
+Xi/Makefile
+xfixes/Makefile
+exa/Makefile
+hw/Makefile
+hw/xfree86/Makefile
+hw/xfree86/common/Makefile
+hw/xfree86/common/xf86Build.h
+hw/xfree86/ddc/Makefile
+hw/xfree86/dixmods/Makefile
+hw/xfree86/dixmods/extmod/Makefile
+hw/xfree86/doc/Makefile
+hw/xfree86/doc/devel/Makefile
+hw/xfree86/doc/man/Makefile
+hw/xfree86/doc/sgml/Makefile
+hw/xfree86/dri/Makefile
+hw/xfree86/dri2/Makefile
+hw/xfree86/exa/Makefile
+hw/xfree86/fbdevhw/Makefile
+hw/xfree86/i2c/Makefile
+hw/xfree86/int10/Makefile
+hw/xfree86/loader/Makefile
+hw/xfree86/modes/Makefile
+hw/xfree86/os-support/Makefile
+hw/xfree86/os-support/bsd/Makefile
+hw/xfree86/os-support/bus/Makefile
+hw/xfree86/os-support/hurd/Makefile
+hw/xfree86/os-support/misc/Makefile
+hw/xfree86/os-support/linux/Makefile
+hw/xfree86/os-support/sco/Makefile
+hw/xfree86/os-support/solaris/Makefile
+hw/xfree86/os-support/sysv/Makefile
+hw/xfree86/parser/Makefile
+hw/xfree86/ramdac/Makefile
+hw/xfree86/shadowfb/Makefile
+hw/xfree86/vbe/Makefile
+hw/xfree86/vgahw/Makefile
+hw/xfree86/x86emu/Makefile
+hw/xfree86/xaa/Makefile
+hw/xfree86/xf8_16bpp/Makefile
+hw/xfree86/utils/Makefile
+hw/xfree86/utils/cvt/Makefile
+hw/xfree86/utils/gtf/Makefile
+hw/dmx/config/Makefile
+hw/dmx/doc/Makefile
+hw/dmx/examples/Makefile
+hw/dmx/input/Makefile
+hw/dmx/glxProxy/Makefile
+hw/dmx/Makefile
+hw/vfb/Makefile
+hw/xnest/Makefile
+hw/xwin/Makefile
+hw/xwin/glx/Makefile
+hw/xquartz/Makefile
+hw/xquartz/GL/Makefile
+hw/xquartz/bundle/Makefile
+hw/xquartz/doc/Makefile
+hw/xquartz/mach-startup/Makefile
+hw/xquartz/pbproxy/Makefile
+hw/xquartz/xpr/Makefile
+hw/kdrive/Makefile
+hw/kdrive/ephyr/Makefile
+hw/kdrive/fake/Makefile
+hw/kdrive/fbdev/Makefile
+hw/kdrive/linux/Makefile
+hw/kdrive/src/Makefile
+test/Makefile
+test/xi2/Makefile
+xorg-server.pc
+])
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c index f419a98fd..fae5361e8 100644 --- a/xorg-server/dix/devices.c +++ b/xorg-server/dix/devices.c @@ -311,10 +311,6 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) }
}
- /* Before actually enabling the device, we need to make sure the event
- * list's events have enough memory for a ClassesChangedEvent from the
- * device
- */
if ((*prev != dev) || !dev->inited ||
((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
ErrorF("[dix] couldn't enable device %d\n", dev->id);
diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index 181fafa77..a14853624 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -3916,7 +3916,6 @@ AddScreen( any of the strings pointed to by argv. They may be passed to
multiple screens.
*/
- pScreen->rgf = ~0L; /* there are no scratch GCs yet*/
WindowTable[i] = NullWindow;
screenInfo.screens[i] = pScreen;
screenInfo.numScreens++;
diff --git a/xorg-server/dix/gc.c b/xorg-server/dix/gc.c index c93b04496..d39a5a76a 100644 --- a/xorg-server/dix/gc.c +++ b/xorg-server/dix/gc.c @@ -537,6 +537,9 @@ CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus, pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
pGC->stipple->refcnt++;
+ /* this is not a scratch GC */
+ pGC->scratch_inuse = FALSE;
+
/* security creation/labeling check */
*pStatus = XaceHook(XACE_RESOURCE_ACCESS, client, gcid, RT_GC, pGC,
RT_NONE, NULL, DixCreateAccess|DixSetAttrAccess);
@@ -844,6 +847,9 @@ CreateScratchGC(ScreenPtr pScreen, unsigned depth) pGC->lastWinOrg.x = 0;
pGC->lastWinOrg.y = 0;
+ /* scratch GCs in the GCperDepth pool start off unused */
+ pGC->scratch_inuse = FALSE;
+
pGC->stateChanges = GCAllBits;
if (!(*pScreen->CreateGC)(pGC))
{
@@ -864,8 +870,10 @@ FreeGCperDepth(int screenNum) ppGC = pScreen->GCperDepth;
for (i = 0; i <= pScreen->numDepths; i++)
+ {
(void)FreeGC(ppGC[i], (XID)0);
- pScreen->rgf = ~0L;
+ ppGC[i] = NULL;
+ }
}
@@ -878,7 +886,6 @@ CreateGCperDepth(int screenNum) GCPtr *ppGC;
pScreen = screenInfo.screens[screenNum];
- pScreen->rgf = 0;
ppGC = pScreen->GCperDepth;
/* do depth 1 separately because it's not included in list */
if (!(ppGC[0] = CreateScratchGC(pScreen, 1)))
@@ -1097,12 +1104,11 @@ GetScratchGC(unsigned depth, ScreenPtr pScreen) GCPtr pGC;
for (i=0; i<=pScreen->numDepths; i++)
- if ( pScreen->GCperDepth[i]->depth == depth &&
- !(pScreen->rgf & (1L << (i+1)))
- )
+ {
+ pGC = pScreen->GCperDepth[i];
+ if (pGC && pGC->depth == depth && !pGC->scratch_inuse)
{
- pScreen->rgf |= (1L << (i+1));
- pGC = (pScreen->GCperDepth[i]);
+ pGC->scratch_inuse = TRUE;
pGC->alu = GXcopy;
pGC->planemask = ~0;
@@ -1127,6 +1133,7 @@ GetScratchGC(unsigned depth, ScreenPtr pScreen) pGC->stateChanges = GCAllBits;
return pGC;
}
+ }
/* if we make it this far, need to roll our own */
pGC = CreateScratchGC(pScreen, depth);
if (pGC)
@@ -1142,16 +1149,8 @@ mark it as available. void
FreeScratchGC(GCPtr pGC)
{
- ScreenPtr pScreen = pGC->pScreen;
- int i;
-
- for (i=0; i<=pScreen->numDepths; i++)
- {
- if ( pScreen->GCperDepth[i] == pGC)
- {
- pScreen->rgf &= ~(1L << (i+1));
- return;
- }
- }
- (void)FreeGC(pGC, (GContext)0);
+ if (pGC->scratch_inuse)
+ pGC->scratch_inuse = FALSE;
+ else
+ FreeGC(pGC, (GContext)0);
}
diff --git a/xorg-server/doc/Makefile.am b/xorg-server/doc/Makefile.am index 2ff683c7f..1cfc1d6a1 100644 --- a/xorg-server/doc/Makefile.am +++ b/xorg-server/doc/Makefile.am @@ -1,24 +1,26 @@ - -# Xserver.man covers options generic to all X servers built in this tree -# (i.e. those handled in the os/utils.c options processing instead of in -# the DDX-level options processing) -appmandir = $(APP_MAN_DIR) -appman_PRE = Xserver.man.pre - -appman_PROCESSED = $(appman_PRE:man.pre=man) -appman_DATA = $(appman_PRE:man.pre=@APP_MAN_SUFFIX@) - -BUILT_SOURCES = $(appman_PROCESSED) -CLEANFILES = $(appman_PROCESSED) $(appman_DATA) - -include $(top_srcdir)/cpprules.in - -.man.$(APP_MAN_SUFFIX): - $(AM_V_at)cp $< $@ - -EXTRAMANDEFS = -D__default_font_path__="`echo $(COMPILEDDEFAULTFONTPATH) | $(SED) -e 's/,/, /g'`" - -# Docs about X server internals that we ship with source but don't install -DEVEL_DOCS = smartsched - -EXTRA_DIST = $(DEVEL_DOCS) $(appman_PRE) $(fileman_PRE) +
+# Xserver.man covers options generic to all X servers built in this tree
+# (i.e. those handled in the os/utils.c options processing instead of in
+# the DDX-level options processing)
+appmandir = $(APP_MAN_DIR)
+appman_PRE = Xserver.man.pre
+
+appman_PROCESSED = $(appman_PRE:man.pre=man)
+appman_DATA = $(appman_PRE:man.pre=@APP_MAN_SUFFIX@)
+
+BUILT_SOURCES = $(appman_PROCESSED)
+CLEANFILES = $(appman_PROCESSED) $(appman_DATA)
+
+include $(top_srcdir)/cpprules.in
+
+.man.$(APP_MAN_SUFFIX):
+ $(AM_V_at)cp $< $@
+
+EXTRAMANDEFS = -D__default_font_path__="`echo $(COMPILEDDEFAULTFONTPATH) | $(SED) -e 's/,/, /g'`"
+
+# Docs about X server internals that we ship with source but don't install
+DEVEL_DOCS = smartsched
+
+EXTRA_DIST = $(DEVEL_DOCS) $(appman_PRE) $(fileman_PRE)
+
+SUBDIRS = xml
diff --git a/xorg-server/doc/xml/Makefile.am b/xorg-server/doc/xml/Makefile.am new file mode 100644 index 000000000..3eba24e8c --- /dev/null +++ b/xorg-server/doc/xml/Makefile.am @@ -0,0 +1,33 @@ +#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+
+XML_FILES = Xserver-spec.xml
+
+include xmlrules.in
+
+if ENABLE_DEVEL_DOCS
+noinst_DATA = $(BUILT_DOC_FILES)
+endif
+CLEANFILES = $(CLEAN_DOC_FILES)
+
+EXTRA_DIST = $(XML_FILES)
diff --git a/xorg-server/doc/xml/Xserver-spec.xml b/xorg-server/doc/xml/Xserver-spec.xml new file mode 100644 index 000000000..022023f5e --- /dev/null +++ b/xorg-server/doc/xml/Xserver-spec.xml @@ -0,0 +1,5182 @@ +<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+ <!ENTITY % defs SYSTEM "/xserver/doc/xml/xserver.ent"> %defs;
+]>
+
+<article>
+ <articleinfo>
+ <author>
+ <firstname>Susan</firstname><surname>Angebranndt</surname>
+ <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
+ </author>
+ <author>
+ <firstname>Raymond</firstname><surname>Drewry</surname>
+ <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
+ </author>
+ <author>
+ <firstname>Philip</firstname><surname>Karlton</surname>
+ <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
+ </author>
+ <author>
+ <firstname>Todd</firstname><surname>Newman</surname>
+ <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation>
+ </author>
+ <author>
+ <firstname>Bob</firstname><surname>Scheifler</surname>
+ <affiliation><orgname>Massachusetts Institute of Technology</orgname></affiliation>
+ </author>
+ <author>
+ <firstname>Keith</firstname><surname>Packard</surname>
+ <affiliation><orgname>MIT X Consortium</orgname></affiliation>
+ </author>
+ <author>
+ <firstname>David</firstname><othername>P.</othername><surname>Wiggins</surname>
+ <affiliation><orgname>X Consortium</orgname></affiliation>
+ </author>
+ <author>
+ <firstname>Jim</firstname><surname>Gettys</surname>
+ <affiliation><orgname>X.org Foundation and Hewlett Packard</orgname></affiliation>
+ </author>
+ <publisher><publishername>The X.Org Foundation</publishername></publisher>
+ <pubdate>&xserver.reldate;</pubdate>
+ <releaseinfo>X server version &xserver.version;</releaseinfo>
+ <title>Definition of the Porting Layer for the X v11 Sample Server</title>
+ <titleabbrev>X Porting Layer</titleabbrev>
+ <revhistory>
+ <revision>
+ <revnumber>1.0</revnumber>
+ <date>27 Oct 2004</date>
+ <authorinitials>sa</authorinitials>
+ <revremark>Initial Version</revremark>
+ </revision>
+ <revision>
+ <revnumber>1.1</revnumber>
+ <date>27 Oct 2004</date>
+ <authorinitials>bs</authorinitials>
+ <revremark>Minor Revisions</revremark>
+ </revision>
+ <revision>
+ <revnumber>2.0</revnumber>
+ <date>27 Oct 2004</date>
+ <authorinitials>kp</authorinitials>
+ <revremark>Revised for Release 4 and 5</revremark>
+ </revision>
+ <revision>
+ <revnumber>3.0</revnumber>
+ <date>27 Oct 2004</date>
+ <authorinitials>dpw</authorinitials>
+ <revremark>Revised for Release 6</revremark>
+ </revision>
+ <revision>
+ <revnumber>3.1</revnumber>
+ <date>27 Oct 2004</date>
+ <authorinitials>jg</authorinitials>
+ <revremark>Revised for Release 6.8.2</revremark>
+ </revision>
+ <revision>
+ <revnumber>3.2</revnumber>
+ <date>17 Dec 2006</date>
+ <authorinitials>efw</authorinitials>
+ <revremark>DocBook conversion</revremark>
+ </revision>
+ <revision>
+ <revnumber>3.3</revnumber>
+ <date>17 Feb 2008</date>
+ <authorinitials>aj</authorinitials>
+ <revremark>Revised for backing store changes</revremark>
+ </revision>
+ <revision>
+ <revnumber>3.4</revnumber>
+ <date>31 Mar 2008</date>
+ <authorinitials>efw</authorinitials>
+ <revremark>Revised for devPrivates changes</revremark>
+ </revision>
+ </revhistory>
+ <legalnotice>
+ <para>Copyright © 1994 X Consortium, Inc., 2004 X.org Foundation, Inc.</para>
+ <para>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</para>
+ <para>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</para>
+ <para>THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</para>
+ <para>LK201 and DEC are trademarks of Digital Equipment Corporation. Macintosh and Apple are trademarks of Apple Computer, Inc. PostScript is a trademark of Adobe Systems, Inc. Ethernet is a trademark of Xerox Corporation. X Window System is a trademark of the X.org Foundation, Inc. Cray is a trademark of Cray Research, Inc.</para>
+ </legalnotice>
+ <abstract>
+ <para>The following document explains the structure of the X Window System display server and the interfaces among the larger pieces. It is intended as a reference for programmers who are implementing an X Display Server on their workstation hardware. It is included with the X Window System source tape, along with the document "Strategies for Porting the X v11 Sample Server." The order in which you should read these documents is:
+ <orderedlist>
+ <listitem><para>Read the first section of the "Strategies for Porting" document (Overview of Porting Process).</para></listitem>
+ <listitem><para>Skim over this document (the Definition document).</para></listitem>
+ <listitem><para>Skim over the remainder of the Strategies document.</para></listitem>
+ <listitem><para>Start planning and working, referring to the Strategies and Definition documents.</para></listitem>
+ </orderedlist>
+ You may also want to look at the following documents:
+ <itemizedlist>
+ <listitem><para>"The X Window System" for an overview of X.</para></listitem>
+ <listitem><para>"Xlib - C Language X Interface" for a view of what the client programmer sees.</para></listitem>
+ <listitem><para>"X Window System Protocol" for a terse description of the byte stream protocol between the client and server.</para></listitem>
+ </itemizedlist>
+ </para>
+ <para>To understand this document and the accompanying source code, you should know the C language. You should be familiar with 2D graphics and windowing concepts such as clipping, bitmaps, fonts, etc. You should have a general knowledge of the X Window System. To implement the server code on your hardware, you need to know a lot about your hardware, its graphic display device(s), and (possibly) its networking and multitasking facilities. This document depends a lot on the source code, so you should have a listing of the code handy.</para>
+ <para>Some source in the distribution is directly compilable on your machine. Some of it will require modification. Other parts may have to be completely written from scratch. The distribution also includes source for a sample implementation of a display server which runs on a very wide variety of color and monochrome displays on Linux and *BSD which you will find useful for implementing any type of X server.</para>
+ <para>Note to the 2008 edition: at this time this document must be considered incomplete, though improved over the 2004 edition. In particular, the new Render extension is still lacking good documentation, and has become vital to high performance X implementations. Modern applications and desktop environments are now much more sensitive to good implementation of the Render extension than in most operations of the old X graphics model. The shadow frame buffer implementation is also very useful in many circumstances, and also needs documentation. We hope to rectify these shortcomings in our documentation in the future. Help would be greatly appreciated.</para>
+ </abstract>
+ </articleinfo>
+
+<!-- Original authorship information:
+
+.OF 'Porting Layer Definition'- % -'October 27, 2004'
+Definition of the Porting Layer
+for the X v11 Sample Server
+Susan Angebranndt
+Raymond Drewry
+Philip Karlton
+Todd Newman
+Digital Equipment Corporation
+
+minor revisions by
+Bob Scheifler
+Massachusetts Institute of Technology
+
+Revised for Release 4 and Release 5 by
+Keith Packard
+MIT X Consortium
+
+Revised for Release 6 by
+David P. Wiggins
+X Consortium
+
+Minor Revisions for Release 6.8.2 by
+Jim Gettys
+X.org Foundation and Hewlett Packard
+-->
+
+<section>
+ <title>The X Window System</title>
+<para>
+The X Window System, or simply "X," is a
+windowing system that provides high-performance, high-level,
+device-independent graphics.
+</para>
+<para>
+X is a windowing system designed for bitmapped graphic displays.
+The display can have a
+simple, monochrome display or it can have a color display with up to 32 bits
+per pixel with a special graphics processor doing the work. (In this
+document, monochrome means a black and white display with one bit per pixel.
+Even though the usual meaning of monochrome is more general, this special
+case is so common that we decided to reserve the word for this purpose.)
+In practice, monochrome displays are now almost unheard of, with 4 bit
+gray scale displays being the low end.
+</para>
+<para>
+X is designed for a networking environment where
+users can run applications on machines other than their own workstations.
+Sometimes, the connection is over an Ethernet network with a protocol such as TCP/IP;
+but, any "reliable" byte stream is allowable.
+A high-bandwidth byte stream is preferable; RS-232 at
+9600 baud would be slow without compression techniques.
+</para>
+<para>
+X by itself allows great freedom of design.
+For instance, it does not include any user interface standard.
+Its intent is to "provide mechanism, not policy."
+By making it general, it can be the foundation for a wide
+variety of interactive software.
+</para>
+<para>
+For a more detailed overview, see the document "The X Window System."
+For details on the byte stream protocol, see "X Window System protocol."
+</para>
+</section>
+<section>
+<title>Overview of the Server</title>
+<para>
+The display server
+manages windows and simple graphics requests
+for the user on behalf of different client applications.
+The client applications can be running on any machine on the network.
+The server mainly does three things:
+<itemizedlist>
+ <listitem><para>Responds to protocol requests from existing clients (mostly graphic and text drawing commands)</para></listitem>
+ <listitem><para>Sends device input (keystrokes and mouse actions) and other events to existing clients</para></listitem>
+ <listitem><para>Maintains client connections</para></listitem>
+</itemizedlist>
+</para>
+<para>
+The server code is organized into four major pieces:
+<itemizedlist>
+ <listitem><para>Device Independent (DIX) layer - code shared among all implementations</para></listitem>
+ <listitem><para>Operating System (OS) layer - code that is different for each operating system but is shared among all graphic devices for this operating system</para></listitem>
+ <listitem><para>Device Dependent (DDX) layer - code that is (potentially) different for each combination of operating system and graphic device</para></listitem>
+ <listitem><para>Extension Interface - a standard way to add features to the X server</para></listitem>
+</itemizedlist>
+</para>
+<para>
+The "porting layer" consists of the OS and DDX layers; these are
+actually parallel and neither one is on top of the other.
+The DIX layer is intended to be portable
+without change to target systems and is not
+detailed here, although several routines
+in DIX that are called by DDX are
+documented.
+Extensions incorporate new functionality into the server; and require
+additional functionality over a simple DDX.
+</para>
+<para>
+The following sections outline the functions of the layers.
+Section 3 briefly tells what you need to know about the DIX layer.
+The OS layer is explained in Section 4.
+Section 5 gives the theory of operation and procedural interface for the
+DDX layer.
+Section 6 describes the functions which exist for the extension writer.
+</para>
+</section>
+
+<section>
+ <title>DIX Layer</title>
+<para>
+The DIX layer is the machine and device independent part of X.
+The source should be common to all operating systems and devices.
+The port process should not include changes to this part, therefore internal interfaces to DIX
+modules are not discussed, except for public interfaces to the DDX and the OS layers.
+The functions described in this section are available for extension writers to use.
+</para>
+<para>
+In the process of getting your server to work, if
+you think that DIX must be modified for purposes other than bug fixes,
+you may be doing something wrong.
+Keep looking for a more compatible solution.
+When the next release of the X server code is available,
+you should be able to just drop in the new DIX code and compile it.
+If you change DIX,
+you will have to remember what changes you made and will have
+to change the new sources before you can update to the new version.
+</para>
+<para>
+The heart of the DIX code is a loop called the dispatch loop.
+Each time the processor goes around the loop, it sends off accumulated input events
+from the input devices to the clients, and it processes requests from the clients.
+This loop is the most organized way for the server to
+process the asynchronous requests that
+it needs to process.
+Most of these operations are performed by OS and DDX routines that you must supply.
+</para>
+<section>
+ <title>Server Resource System</title>
+<para>
+X resources are C structs inside the server.
+Client applications create and manipulate these objects
+according to the rules of the X byte stream protocol.
+Client applications refer to resources with resource IDs,
+which are 32-bit integers that are sent over the network.
+Within the server, of course, they are just C structs, and we refer to them
+by pointers.
+</para>
+<section>
+ <title>Pre-Defined Resource Types</title>
+<para>
+The DDX layer has several kinds of resources:
+<itemizedlist>
+<listitem><para>Window</para></listitem>
+<listitem><para>Pixmap</para></listitem>
+<listitem><para>Screen</para></listitem>
+<listitem><para>Device</para></listitem>
+<listitem><para>Colormap</para></listitem>
+<listitem><para>Font</para></listitem>
+<listitem><para>Cursor</para></listitem>
+<listitem><para>Graphics Contexts</para></listitem>
+</itemizedlist>
+</para>
+<para>
+The type names of the more
+important server
+structs usually end in "Rec," such as "DeviceRec;"
+the pointer types usually end in "Ptr," such as "DevicePtr."
+</para>
+<para>
+The structs and
+important defined constants are declared
+in .h files that have names that suggest the name of the object.
+For instance, there are two .h files for windows,
+window.h and windowstr.h.
+window.h defines only what needs to be defined in order to use windows
+without peeking inside of them;
+windowstr.h defines the structs with all of their components in great detail
+for those who need it.
+</para>
+<para>
+Three kinds of fields are in these structs:
+<itemizedlist>
+<listitem><para>Attribute fields - struct fields that contain values like normal structs</para></listitem>
+<listitem><para>Pointers to procedures, or structures of procedures, that operate on the object</para></listitem>
+<listitem><para>A single private field or a devPrivates list (see <xref linkend="wrappers_and_privates"/>)
+used by your DDX code to store private data.</para></listitem>
+</itemizedlist>
+</para>
+<para>
+DIX calls through
+the struct's procedure pointers to do its tasks.
+These procedures are set either directly or indirectly by DDX procedures.
+Most of
+the procedures described in the remainder of this
+document are accessed through one of these structs.
+For example, the procedure to create a pixmap
+is attached to a ScreenRec and might be called by using the expression
+</para>
+<para>
+<blockquote>
+<programlisting>(* pScreen->CreatePixmap)(pScreen, width, height, depth).</programlisting>
+</blockquote>
+</para>
+<para>
+All procedure pointers must be set to some routine unless noted otherwise;
+a null pointer will have unfortunate consequences.
+</para>
+<para>
+Procedure routines will be indicated in the documentation by this convention:
+<blockquote>
+<programlisting>void pScreen->MyScreenRoutine(arg, arg, ...)</programlisting>
+</blockquote>
+as opposed to a free routine, not in a data structure:
+<blockquote>
+<programlisting>void MyFreeRoutine(arg, arg, ...)</programlisting>
+</blockquote>
+</para>
+<para>
+The attribute fields are mostly set by DIX; DDX should not modify them
+unless noted otherwise.
+</para>
+</section>
+<section>
+ <title>Creating Resources and Resource Types</title>
+<para>
+These functions should also be called from your extensionInitProc to
+allocate all of the various resource classes and types required for
+the extension. Each time the server resets, these types must be reallocated
+as the old allocations will have been discarded.
+Resource types are integer values starting at 1. Get
+a resource type by calling
+<blockquote><programlisting>
+
+ RESTYPE CreateNewResourceType(deleteFunc)
+
+</programlisting></blockquote>
+deleteFunc will be called to destroy all resources with this
+type.</para>
+<para>
+Resource classes are masks starting at 1 << 31 which can
+be or'ed with any resource type to provide attributes for the
+type. To allocate a new class bit, call
+<blockquote><programlisting>
+
+ RESTYPE CreateNewResourceClass()
+
+</programlisting></blockquote>
+</para>
+<para>
+There are two ways of looking up resources, by type or
+by class. Classes are non-exclusive subsets of the space of
+all resources, so you can lookup the union of multiple classes.
+(RC_ANY is the union of all classes).</para>
+<para>
+Note that the appropriate class bits must be or'ed into the value returned
+by CreateNewResourceType when calling resource lookup functions.</para>
+<para>
+If you need to create a ``private'' resource ID for internal use, you
+can call FakeClientID.
+<blockquote><programlisting>
+
+ XID FakeClientID(client)
+ int client;
+
+</programlisting></blockquote>
+This allocates from ID space reserved for the server.</para>
+<para>
+To associate a resource value with an ID, use AddResource.
+<blockquote><programlisting>
+
+ Bool AddResource(id, type, value)
+ XID id;
+ RESTYPE type;
+ pointer value;
+
+</programlisting></blockquote>
+The type should be the full type of the resource, including any class
+bits. If AddResource fails to allocate memory to store the resource,
+it will call the deleteFunc for the type, and then return False.</para>
+<para>
+To free a resource, use one of the following.
+<blockquote><programlisting>
+
+ void FreeResource(id, skipDeleteFuncType)
+ XID id;
+ RESTYPE skipDeleteFuncType;
+
+ void FreeResourceByType(id, type, skipFree)
+ XID id;
+ RESTYPE type;
+ Bool skipFree;
+
+</programlisting></blockquote>
+FreeResource frees all resources matching the given id, regardless of
+type; the type's deleteFunc will be called on each matching resource,
+except that skipDeleteFuncType can be set to a single type for which
+the deleteFunc should not be called (otherwise pass RT_NONE).
+FreeResourceByType frees a specific resource matching a given id
+and type; if skipFree is true, then the deleteFunc is not called.
+</para>
+</section>
+<section>
+ <title>Looking Up Resources</title>
+<para>
+To look up a resource, use one of the following.
+<blockquote><programlisting>
+
+ pointer LookupIDByType(id, rtype)
+ XID id;
+ RESTYPE rtype;
+
+ pointer LookupIDByClass(id, classes)
+ XID id;
+ RESTYPE classes;
+
+</programlisting></blockquote>
+LookupIDByType finds a resource with the given id and exact type.
+LookupIDByClass finds a resource with the given id whose type is
+included in any one of the specified classes.</para>
+</section>
+</section>
+<section>
+ <title>Callback Manager</title>
+<para>
+To satisfy a growing number of requests for the introduction of ad hoc
+notification style hooks in the server, a generic callback manager was
+introduced in R6. A callback list object can be introduced for each
+new hook that is desired, and other modules in the server can register
+interest in the new callback list. The following functions support
+these operations.</para>
+<para>
+Before getting bogged down in the interface details, an typical usage
+example should establish the framework. Let's look at the
+ClientStateCallback in dix/dispatch.c. The purpose of this particular
+callback is to notify intereseted parties when a client's state
+(initial, running, gone) changes. The callback is "created" in this
+case by simply declaring a variable:
+<blockquote><programlisting>
+ CallbackListPtr ClientStateCallback;
+</programlisting></blockquote>
+</para>
+<para>
+Whenever the client's state changes, the following code appears, which notifies
+all intereseted parties of the change:
+<blockquote><programlisting>
+ if (ClientStateCallback) CallCallbacks(&ClientStateCallback, (pointer)client);
+</programlisting></blockquote>
+</para>
+<para>
+Interested parties subscribe to the ClientStateCallback list by saying:
+<blockquote><programlisting>
+ AddCallback(&ClientStateCallback, func, data);
+</programlisting></blockquote>
+</para>
+<para>
+When CallCallbacks is invoked on the list, func will be called thusly:
+<blockquote><programlisting>
+ (*func)(&ClientStateCallback, data, client)
+</programlisting></blockquote>
+</para>
+<para>
+Now for the details.
+<blockquote><programlisting>
+
+ Bool CreateCallbackList(pcbl, cbfuncs)
+ CallbackListPtr *pcbl;
+ CallbackFuncsPtr cbfuncs;
+
+</programlisting></blockquote>
+CreateCallbackList creates a callback list. We envision that this
+function will be rarely used because the callback list is created
+automatically (if it doesn't already exist) when the first call to
+AddCallback is made on the list. The only reason to explicitly create
+the callback list with this function is if you want to override the
+implementation of some of the other operations on the list by passing
+your own cbfuncs. You also lose something by explicit creation: you
+introduce an order dependency during server startup because the list
+must be created before any modules subscribe to it. Returns TRUE if
+successful.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool AddCallback(pcbl, callback, subscriber_data)
+ CallbackListPtr *pcbl;
+ CallbackProcPtr callback;
+ pointer subscriber_data;
+
+</programlisting></blockquote>
+Adds the (callback, subscriber_data) pair to the given callback list. Creates the callback
+list if it doesn't exist. Returns TRUE if successful.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool DeleteCallback(pcbl, callback, subscriber_data)
+ CallbackListPtr *pcbl;
+ CallbackProcPtr callback;
+ pointer subscriber_data;
+
+</programlisting></blockquote>
+Removes the (callback, data) pair to the given callback list if present.
+Returns TRUE if (callback, data) was found.</para>
+<para>
+<blockquote><programlisting>
+
+ void CallCallbacks(pcbl, call_data)
+ CallbackListPtr *pcbl;
+ pointer call_data;
+
+</programlisting></blockquote>
+For each callback currently registered on the given callback list, call
+it as follows:
+<blockquote><programlisting>
+
+ (*callback)(pcbl, subscriber_data, call_data);
+</programlisting></blockquote>
+</para>
+<para>
+<blockquote><programlisting>
+ void DeleteCallbackList(pcbl)
+ CallbackListPtr *pcbl;
+
+</programlisting></blockquote>
+Destroys the given callback list.</para>
+</section>
+<section>
+ <title>Extension Interfaces</title>
+<para>
+This function should be called from your extensionInitProc which
+should be called by InitExtensions.
+<blockquote><programlisting>
+
+ ExtensionEntry *AddExtension(name, NumEvents,NumErrors,
+ MainProc, SwappedMainProc, CloseDownProc, MinorOpcodeProc)
+
+ char *name; /*Null terminate string; case matters*/
+ int NumEvents;
+ int NumErrors;
+ int (* MainProc)(ClientPtr);/*Called if client matches server order*/
+ int (* SwappedMainProc)(ClientPtr);/*Called if client differs from server*/
+ void (* CloseDownProc)(ExtensionEntry *);
+ unsigned short (*MinorOpcodeProc)(ClientPtr);
+
+</programlisting></blockquote>
+name is the name used by clients to refer to the extension. NumEvents is the
+number of event types used by the extension, NumErrors is the number of
+error codes needed by the extension. MainProc is called whenever a client
+accesses the major opcode assigned to the extension. SwappedMainProc is
+identical, except the client using the extension has reversed byte-sex.
+CloseDownProc is called at server reset time to deallocate any private
+storage used by the extension. MinorOpcodeProc is used by DIX to place the
+appropriate value into errors. The DIX routine StandardMinorOpcode can be
+used here which takes the minor opcode from the normal place in the request
+(i.e. just after the major opcode).</para>
+</section>
+<section>
+ <title>Macros and Other Helpers</title>
+<para>
+There are a number of macros in Xserver/include/dix.h which
+are useful to the extension writer. Ones of particular interest
+are: REQUEST, REQUEST_SIZE_MATCH, REQUEST_AT_LEAST_SIZE,
+REQUEST_FIXED_SIZE, LEGAL_NEW_RESOURCE, LOOKUP_DRAWABLE, VERIFY_GC, and
+VALIDATE_DRAWABLE_AND_GC. Useful byte swapping macros can be found
+in Xserver/include/misc.h: lswapl, lswaps, LengthRestB, LengthRestS,
+LengthRestL, SwapRestS, SwapRestL, swapl, swaps, cpswapl, and cpswaps.</para>
+</section>
+</section>
+
+<section>
+ <title>OS Layer</title>
+<para>
+This part of the source consists of a few routines that you have to rewrite
+for each operating system.
+These OS functions maintain the client connections and schedule work
+to be done for clients.
+They also provide an interface to font files,
+font name to file name translation, and
+low level memory management.
+<blockquote>
+<programlisting>void OsInit()</programlisting>
+</blockquote>
+OsInit initializes your OS code, performing whatever tasks need to be done.
+Frequently there is not much to be done.
+The sample server implementation is in Xserver/os/osinit.c.
+</para>
+<section>
+ <title>Scheduling and Request Delivery</title>
+<para>
+The main dispatch loop in DIX creates the illusion of multitasking between
+different windows, while the server is itself but a single process.
+The dispatch loop breaks up the work for each client into small digestible parts.
+Some parts are requests from a client, such as individual graphic commands.
+Some parts are events delivered to the client, such as keystrokes from the user.
+The processing of events and requests for different
+clients can be interleaved with one another so true multitasking
+is not needed in the server.
+</para>
+<para>
+You must supply some of the pieces for proper scheduling between clients.
+<blockquote>
+<programlisting>
+ int WaitForSomething(pClientReady)
+ int *pClientReady;
+</programlisting>
+</blockquote>
+</para>
+<para>
+WaitForSomething is the scheduler procedure you must write that will
+suspend your server process until something needs to be done.
+This call should
+make the server suspend until one or more of the following occurs:
+<itemizedlist>
+<listitem><para>There is an input event from the user or hardware (see SetInputCheck())</para></listitem>
+<listitem><para>There are requests waiting from known clients, in which case you should return a count of clients stored in pClientReady</para></listitem>
+<listitem><para>A new client tries to connect, in which case you should create the client and then continue waiting</para></listitem>
+</itemizedlist>
+</para>
+<para>
+Before WaitForSomething() computes the masks to pass to select, poll or
+similar operating system interface, it needs to
+see if there is anything to do on the work queue; if so, it must call a DIX
+routine called ProcessWorkQueue.
+<blockquote>
+<programlisting>
+ extern WorkQueuePtr workQueue;
+
+ if (workQueue)
+ ProcessWorkQueue ();
+</programlisting>
+</blockquote>
+</para>
+<para>
+If WaitForSomething() decides it is about to do something that might block
+(in the sample server, before it calls select() or poll) it must call a DIX
+routine called BlockHandler().
+<blockquote>
+<programlisting>
+ void BlockHandler(pTimeout, pReadmask)
+ pointer pTimeout;
+ pointer pReadmask;
+</programlisting>
+</blockquote>
+The types of the arguments are for agreement between the OS and DDX
+implementations, but the pTimeout is a pointer to the information
+determining how long the block is allowed to last, and the
+pReadmask is a pointer to the information describing the descriptors
+that will be waited on.
+</para>
+<para>
+In the sample server, pTimeout is a struct timeval **, and pReadmask is
+the address of the select() mask for reading.
+</para>
+<para>
+The DIX BlockHandler() iterates through the Screens, for each one calling
+its BlockHandler. A BlockHandler is declared thus:
+<blockquote>
+<programlisting>
+ void xxxBlockHandler(nscreen, pbdata, pptv, pReadmask)
+ int nscreen;
+ pointer pbdata;
+ struct timeval ** pptv;
+ pointer pReadmask;
+</programlisting>
+</blockquote>
+The arguments are the index of the Screen, the blockData field
+of the Screen, and the arguments to the DIX BlockHandler().
+</para>
+<para>
+Immediately after WaitForSomething returns from the
+block, even if it didn't actually block, it must call the DIX routine
+WakeupHandler().
+<blockquote>
+<programlisting>
+ void WakeupHandler(result, pReadmask)
+ int result;
+ pointer pReadmask;
+</programlisting>
+</blockquote>
+Once again, the types are not specified by DIX. The result is the
+success indicator for the thing that (may have) blocked,
+and the pReadmask is a mask of the descriptors that came active.
+In the sample server, result is the result from select() (or equivalent
+operating system function), and pReadmask is
+the address of the select() mask for reading.
+</para>
+<para>
+The DIX WakeupHandler() calls each Screen's
+WakeupHandler. A WakeupHandler is declared thus:
+<blockquote>
+<programlisting>
+ void xxxWakeupHandler(nscreen, pbdata, err, pReadmask)
+ int nscreen;
+ pointer pbdata;
+ unsigned long result;
+ pointer pReadmask;
+</programlisting>
+</blockquote>
+The arguments are the index of the Screen, the blockData field
+of the Screen, and the arguments to the DIX WakeupHandler().
+</para>
+<para>
+In addition to the per-screen BlockHandlers, any module may register
+block and wakeup handlers (only together) using:
+<blockquote>
+<programlisting>
+ Bool RegisterBlockAndWakeupHandlers (blockHandler, wakeupHandler, blockData)
+ BlockHandlerProcPtr blockHandler;
+ WakeupHandlerProcPtr wakeupHandler;
+ pointer blockData;
+</programlisting>
+</blockquote>
+A FALSE return code indicates that the registration failed for lack of
+memory. To remove a registered Block handler at other than server reset time
+(when they are all removed automatically), use:
+<blockquote>
+<programlisting>
+ RemoveBlockAndWakeupHandlers (blockHandler, wakeupHandler, blockData)
+ BlockHandlerProcPtr blockHandler;
+ WakeupHandlerProcPtr wakeupHandler;
+ pointer blockData;
+</programlisting>
+</blockquote>
+All three arguments must match the values passed to
+RegisterBlockAndWakeupHandlers.
+</para>
+<para>
+These registered block handlers are called after the per-screen handlers:
+<blockquote>
+<programlisting>
+ void (*BlockHandler) (blockData, pptv, pReadmask)
+ pointer blockData;
+ OSTimePtr pptv;
+ pointer pReadmask;
+</programlisting>
+</blockquote>
+</para>
+<para>
+Sometimes block handlers need to adjust the time in a OSTimePtr structure,
+which on UNIX family systems is generally represented by a struct timeval
+consisting of seconds and microseconds in 32 bit values.
+As a convenience to reduce error prone struct timeval computations which
+require modulus arithmetic and correct overflow behavior in the face of
+millisecond wrapping throrugh 32 bits,
+<blockquote><programlisting>
+
+ void AdjustWaitForDelay(pointer /*waitTime*, unsigned long /* newdelay */)
+
+</programlisting></blockquote>
+has been provided.
+</para>
+<para>
+Any wakeup handlers registered with RegisterBlockAndWakeupHandlers will
+be called before the Screen handlers:
+<blockquote><programlisting>
+
+ void (*WakeupHandler) (blockData, err, pReadmask)
+ pointer blockData;
+ int err;
+ pointer pReadmask;
+</programlisting></blockquote>
+</para>
+<para>
+The WaitForSomething on the sample server also has a built
+in screen saver that darkens the screen if no input happens for a period of time.
+The sample server implementation is in Xserver/os/WaitFor.c.
+</para>
+<para>
+Note that WaitForSomething() may be called when you already have several
+outstanding things (events, requests, or new clients) queued up.
+For instance, your server may have just done a large graphics request,
+and it may have been a long time since WaitForSomething() was last called.
+If many clients have lots of requests queued up, DIX will only service
+some of them for a given client
+before going on to the next client (see isItTimeToYield, below).
+Therefore, WaitForSomething() will have to report that these same clients
+still have requests queued up the next time around.
+</para>
+<para>
+An implementation should return information on as
+many outstanding things as it can.
+For instance, if your implementation always checks for client data first and does not
+report any input events until there is no client data left,
+your mouse and keyboard might get locked out by an application that constantly
+barrages the server with graphics drawing requests.
+Therefore, as a general rule, input devices should always have priority over graphics
+devices.
+</para>
+<para>
+A list of indexes (client->index) for clients with data ready to be read or
+processed should be returned in pClientReady, and the count of indexes
+returned as the result value of the call.
+These are not clients that have full requests ready, but any clients who have
+any data ready to be read or processed.
+The DIX dispatcher
+will process requests from each client in turn by calling
+ReadRequestFromClient(), below.
+</para>
+<para>
+WaitForSomething() must create new clients as they are requested (by
+whatever mechanism at the transport level). A new client is created
+by calling the DIX routine:
+<blockquote><programlisting>
+
+ ClientPtr NextAvailableClient(ospriv)
+ pointer ospriv;
+</programlisting></blockquote>
+This routine returns NULL if a new client cannot be allocated (e.g. maximum
+number of clients reached). The ospriv argument will be stored into the OS
+private field (pClient->osPrivate), to store OS private information about the
+client. In the sample server, the osPrivate field contains the
+number of the socket for this client. See also "New Client Connections."
+NextAvailableClient() will call InsertFakeRequest(), so you must be
+prepared for this.
+</para>
+<para>
+If there are outstanding input events,
+you should make sure that the two SetInputCheck() locations are unequal.
+The DIX dispatcher will call your implementation of ProcessInputEvents()
+until the SetInputCheck() locations are equal.
+</para>
+<para>
+The sample server contains an implementation of WaitForSomething().
+The
+following two routines indicate to WaitForSomething() what devices should
+be waited for. fd is an OS dependent type; in the sample server
+it is an open file descriptor.
+<blockquote><programlisting>
+
+ int AddEnabledDevice(fd)
+ int fd;
+
+ int RemoveEnabledDevice(fd)
+ int fd;
+</programlisting></blockquote>
+These two routines are
+usually called by DDX from the initialize cases of the
+Input Procedures that are stored in the DeviceRec (the
+routine passed to AddInputDevice()).
+The sample server implementation of AddEnabledDevice
+and RemoveEnabledDevice are in Xserver/os/connection.c.
+</para>
+<section>
+ <title>Timer Facilities</title>
+<para>
+Similarly, the X server or an extension may need to wait for some timeout.
+Early X releases implemented this functionality using block and wakeup handlers,
+but this has been rewritten to use a general timer facilty, and the
+internal screen saver facilties reimplemented to use Timers.
+These functions are TimerInit, TimerForce, TimerSet, TimerCheck, TimerCancel,
+and TimerFree, as defined in Xserver/include/os.h. A callback function will be called
+when the timer fires, along with the current time, and a user provided argument.
+<blockquote><programlisting>
+ typedef struct _OsTimerRec *OsTimerPtr;
+
+ typedef CARD32 (*OsTimerCallback)(
+ OsTimerPtr /* timer */,
+ CARD32 /* time */,
+ pointer /* arg */);
+
+ OsTimerPtr TimerSet( OsTimerPtr /* timer */,
+ int /* flags */,
+ CARD32 /* millis */,
+ OsTimerCallback /* func */,
+ pointer /* arg */);
+
+</programlisting></blockquote>
+</para>
+<para>
+TimerSet returns a pointer to a timer structure and sets a timer to the specified time
+with the specified argument. The flags can be TimerAbsolute and TimerForceOld.
+The TimerSetOld flag controls whether if the timer is reset and the timer is pending, the
+whether the callback function will get called.
+The TimerAbsolute flag sets the callback time to an absolute time in the future rather
+than a time relative to when TimerSet is called.
+TimerFree should be called to free the memory allocated
+for the timer entry.
+<blockquote><programlisting>
+ void TimerInit(void)
+
+ Bool TimerForce(OsTimerPtr /* pTimer */)
+
+ void TimerCheck(void);
+
+ void TimerCancel(OsTimerPtr /* pTimer */)
+
+ void TimerFree(OSTimerPtr /* pTimer */)
+</programlisting></blockquote>
+</para>
+<para>
+TimerInit frees any exisiting timer entries. TimerForce forces a call to the timer's
+callback function and returns true if the timer entry existed, else it returns false and
+does not call the callback function. TimerCancel will cancel the specified timer.
+TimerFree calls TimerCancel and frees the specified timer.
+Calling TimerCheck will force the server to see if any timer callbacks should be called.
+</para>
+</section>
+</section>
+<section>
+ <title>New Client Connections</title>
+<para>
+The process whereby a new client-server connection starts up is
+very dependent upon what your byte stream mechanism.
+This section describes byte stream initiation using examples from the TCP/IP
+implementation on the sample server.
+</para>
+<para>
+The first thing that happens is a client initiates a connection with the server.
+How a client knows to do this depends upon your network facilities and the
+Xlib implementation.
+In a typical scenario, a user named Fred
+on his X workstation is logged onto a Cray
+supercomputer running a command shell in an X window. Fred can type shell
+commands and have the Cray respond as though the X server were a dumb terminal.
+Fred types in a command to run an X client application that was linked with Xlib.
+Xlib looks at the shell environment variable DISPLAY, which has the
+value "fredsbittube:0.0."
+The host name of Fred's workstation is "fredsbittube," and the 0s are
+for multiple screens and multiple X server processes.
+(Precisely what
+happens on your system depends upon how X and Xlib are implemented.)
+</para>
+<para>
+The client application calls a TCP routine on the
+Cray to open a TCP connection for X
+to communicate with the network node "fredsbittube."
+The TCP software on the Cray does this by looking up the TCP
+address of "fredsbittube" and sending an open request to TCP port 6000
+on fredsbittube.
+</para>
+<para>
+All X servers on TCP listen for new clients on port 6000 by default;
+this is known as a "well-known port" in IP terminology.
+</para>
+<para>
+The server receives this request from its port 6000
+and checks where it came from to see if it is on the server's list
+of "trustworthy" hosts to talk to.
+Then, it opens another port for communications with the client.
+This is the byte stream that all X communications will go over.
+</para>
+<para>
+Actually, it is a bit more complicated than that.
+Each X server process running on the host machine is called a "display."
+Each display can have more than one screen that it manages.
+"corporatehydra:3.2" represents screen 2 on display 3 on
+the multi-screened network node corporatehydra.
+The open request would be sent on well-known port number 6003.
+</para>
+<para>
+Once the byte stream is set up, what goes on does not depend very much
+upon whether or not it is TCP.
+The client sends an xConnClientPrefix struct (see Xproto.h) that has the
+version numbers for the version of Xlib it is running, some byte-ordering information,
+and two character strings used for authorization.
+If the server does not like the authorization strings
+or the version numbers do not match within the rules,
+or if anything else is wrong, it sends a failure
+response with a reason string.
+</para>
+<para>
+If the information never comes, or comes much too slowly, the connection
+should be broken off. You must implement the connection timeout. The
+sample server implements this by keeping a timestamp for each still-connecting
+client and, each time just before it attempts to accept new connections, it
+closes any connection that are too old.
+The connection timeout can be set from the command line.
+</para>
+<para>
+You must implement whatever authorization schemes you want to support.
+The sample server on the distribution tape supports a simple authorization
+scheme. The only interface seen by DIX is:
+<blockquote><programlisting>
+
+ char *
+ ClientAuthorized(client, proto_n, auth_proto, string_n, auth_string)
+ ClientPtr client;
+ unsigned int proto_n;
+ char *auth_proto;
+ unsigned int string_n;
+ char *auth_string;
+</programlisting></blockquote>
+DIX will only call this once per client, once it has read the full initial
+connection data from the client. If the connection should be
+accepted ClientAuthorized() should return NULL, and otherwise should
+return an error message string.
+</para>
+<para>
+Accepting new connections happens internally to WaitForSomething().
+WaitForSomething() must call the DIX routine NextAvailableClient()
+to create a client object.
+Processing of the initial connection data will be handled by DIX.
+Your OS layer must be able to map from a client
+to whatever information your OS code needs to communicate
+on the given byte stream to the client.
+DIX uses this ClientPtr to refer to
+the client from now on. The sample server uses the osPrivate field in
+the ClientPtr to store the file descriptor for the socket, the
+input and output buffers, and authorization information.
+</para>
+<para>
+To initialize the methods you choose to allow clients to connect to
+your server, main() calls the routine
+<blockquote><programlisting>
+
+ void CreateWellKnownSockets()
+</programlisting></blockquote>
+This routine is called only once, and not called when the server
+is reset. To recreate any sockets during server resets, the following
+routine is called from the main loop:
+<blockquote><programlisting>
+
+ void ResetWellKnownSockets()
+</programlisting></blockquote>
+Sample implementations of both of these routines are found in
+Xserver/os/connection.c.
+</para>
+<para>
+For more details, see the section called "Connection Setup" in the X protocol specification.
+</para>
+</section>
+<section>
+ <title>Reading Data from Clients</title>
+<para>
+Requests from the client are read in as a byte stream by the OS layer.
+They may be in the form of several blocks of bytes delivered in sequence; requests may
+be broken up over block boundaries or there may be many requests per block.
+Each request carries with it length information.
+It is the responsibility of the following routine to break it up into request blocks.
+<blockquote><programlisting>
+
+ int ReadRequestFromClient(who)
+ ClientPtr who;
+</programlisting></blockquote>
+</para>
+<para>
+You must write
+the routine ReadRequestFromClient() to get one request from the byte stream
+belonging to client "who."
+You must swap the third and fourth bytes (the second 16-bit word) according to the
+byte-swap rules of
+the protocol to determine the length of the
+request.
+This length is measured in 32-bit words, not in bytes. Therefore, the
+theoretical maximum request is 256K.
+(However, the maximum length allowed is dependent upon the server's input
+buffer. This size is sent to the client upon connection. The maximum
+size is the constant MAX_REQUEST_SIZE in Xserver/include/os.h)
+The rest of the request you return is
+assumed NOT to be correctly swapped for internal
+use, because that is the responsibility of DIX.
+</para>
+<para>
+The 'who' argument is the ClientPtr returned from WaitForSomething.
+The return value indicating status should be set to the (positive) byte count if the read is successful,
+0 if the read was blocked, or a negative error code if an error happened.
+</para>
+<para>
+You must then store a pointer to
+the bytes of the request in the client request buffer field;
+who->requestBuffer. This can simply be a pointer into your buffer;
+DIX may modify it in place but will not otherwise cause damage.
+Of course, the request must be contiguous; you must
+shuffle it around in your buffers if not.
+</para>
+<para>
+The sample server implementation is in Xserver/os/io.c.
+</para>
+<section><title>Inserting Data for Clients</title>
+<para>
+DIX can insert data into the client stream, and can cause a "replay" of
+the current request.
+<blockquote><programlisting>
+
+ Bool InsertFakeRequest(client, data, count)
+ ClientPtr client;
+ char *data;
+ int count;
+
+ int ResetCurrentRequest(client)
+ ClientPtr client;
+</programlisting></blockquote>
+</para>
+<para>
+InsertFakeRequest() must insert the specified number of bytes of data
+into the head of the input buffer for the client. This may be a
+complete request, or it might be a partial request. For example,
+NextAvailableCient() will insert a partial request in order to read
+the initial connection data sent by the client. The routine returns FALSE
+if memory could not be allocated. ResetCurrentRequest()
+should "back up" the input buffer so that the currently executing request
+will be reexecuted. DIX may have altered some values (e.g. the overall
+request length), so you must recheck to see if you still have a complete
+request. ResetCurrentRequest() should always cause a yield (isItTimeToYield).
+</para>
+</section>
+</section>
+
+<section>
+ <title>Sending Events, Errors And Replies To Clients</title>
+<para>
+<blockquote><programlisting>
+
+ int WriteToClient(who, n, buf)
+ ClientPtr who;
+ int n;
+ char *buf;
+</programlisting></blockquote>
+WriteToClient should write n bytes starting at buf to the
+ClientPtr "who".
+It returns the number of bytes written, but for simplicity,
+the number returned must be either the same value as the number
+requested, or -1, signaling an error.
+The sample server implementation is in Xserver/os/io.c.
+</para>
+<para>
+<blockquote><programlisting>
+ void SendErrorToClient(client, majorCode, minorCode, resId, errorCode)
+ ClientPtr client;
+ unsigned int majorCode;
+ unsigned int minorCode;
+ XID resId;
+ int errorCode;
+</programlisting></blockquote>
+SendErrorToClient can be used to send errors back to clients,
+although in most cases your request function should simply return
+the error code, having set client->errorValue to the appropriate
+error value to return to the client, and DIX will call this
+function with the correct opcodes for you.
+</para>
+<para>
+<blockquote><programlisting>
+
+ void FlushAllOutput()
+
+ void FlushIfCriticalOutputPending()
+
+ void SetCriticalOutputPending()
+</programlisting></blockquote>
+These three routines may be implemented to support buffered or delayed
+writes to clients, but at the very least, the stubs must exist.
+FlushAllOutput() unconditionally flushes all output to clients;
+FlushIfCriticalOutputPending() flushes output only if
+SetCriticalOutputPending() has be called since the last time output
+was flushed.
+The sample server implementation is in Xserver/os/io.c and
+actually ignores requests to flush output on a per-client basis
+if it knows that there
+are requests in that client's input queue.
+</para>
+</section>
+<section>
+ <title>Font Support</title>
+<para>
+In the sample server, fonts are encoded in disk files or fetched from the
+font server.
+For disk fonts, there is one file per font, with a file name like
+"fixed.pcf". Font server fonts are read over the network using the
+X Font Server Protocol. The disk directories containing disk fonts and
+the names of the font servers are listed together in the current "font path."
+</para>
+<para>
+In principle, you can put all your fonts in ROM or in RAM in your server.
+You can put them all in one library file on disk.
+You could generate them on the fly from stroke descriptions. By placing the
+appropriate code in the Font Library, you will automatically export fonts in
+that format both through the X server and the Font server.
+</para>
+<para>
+With the incorporation of font-server based fonts and the Speedo donation
+from Bitstream, the font interfaces have been moved into a separate
+library, now called the Font Library (../fonts/lib). These routines are
+shared between the X server and the Font server, so instead of this document
+specifying what you must implement, simply refer to the font
+library interface specification for the details. All of the interface code to the Font
+library is contained in dix/dixfonts.c
+</para>
+</section>
+<section>
+ <title>Memory Management</title>
+<para>
+Memory management is based on functions in the C runtime library.
+Xalloc(), Xrealloc(), and Xfree() work just like malloc(), realloc(),
+and free(), except that you can pass a null pointer to Xrealloc() to
+have it allocate anew or pass a null pointer to Xfree() and nothing
+will happen. The versions in the sample server also do some checking
+that is useful for debugging. Consult a C runtime library reference
+manual for more details.
+</para>
+<para>
+The macros ALLOCATE_LOCAL and DEALLOCATE_LOCAL are provided in
+Xserver/include/os.h. These are useful if your compiler supports
+alloca() (or some method of allocating memory from the stack); and are
+defined appropriately on systems which support it.
+</para>
+<para>
+Treat memory allocation carefully in your implementation. Memory
+leaks can be very hard to find and are frustrating to a user. An X
+server could be running for days or weeks without being reset, just
+like a regular terminal. If you leak a few dozen k per day, that will
+add up and will cause problems for users that leave their workstations
+on.
+</para>
+</section>
+<section>
+ <title>Client Scheduling</title>
+<para>
+The X server
+has the ability to schedule clients much like an operating system would,
+suspending and restarting them without regard for the state of their input
+buffers. This functionality allows the X server to suspend one client and
+continue processing requests from other clients while waiting for a
+long-term network activity (like loading a font) before continuing with the
+first client.
+<blockquote><programlisting>
+ Bool isItTimeToYield;
+</programlisting></blockquote>
+isItTimeToYield is a global variable you can set
+if you want to tell
+DIX to end the client's "time slice" and start paying attention to the next client.
+After the current request is finished, DIX will move to the next client.
+</para>
+<para>
+In the sample
+server, ReadRequestFromClient() sets isItTimeToYield after
+10 requests packets in a row are read from the same client.
+</para>
+<para>
+This scheduling algorithm can have a serious effect upon performance when two
+clients are drawing into their windows simultaneously.
+If it allows one client to run until its request
+queue is empty by ignoring isItTimeToYield, the client's queue may
+in fact never empty and other clients will be blocked out.
+On the other hand, if it switchs between different clients too quickly,
+performance may suffer due to too much switching between contexts.
+For example, if a graphics processor needs to be set up with drawing modes
+before drawing, and two different clients are drawing with
+different modes into two different windows, you may
+switch your graphics processor modes so often that performance is impacted.
+</para>
+<para>
+See the Strategies document for
+heuristics on setting isItTimeToYield.
+</para>
+<para>
+The following functions provide the ability to suspend request
+processing on a particular client, resuming it at some later time:
+<blockquote><programlisting>
+
+ int IgnoreClient (who)
+ ClientPtr who;
+
+ int AttendClient (who)
+ ClientPtr who;
+</programlisting></blockquote>
+Ignore client is responsible for pretending that the given client doesn't
+exist. WaitForSomething should not return this client as ready for reading
+and should not return if only this client is ready. AttendClient undoes
+whatever IgnoreClient did, setting it up for input again.
+</para>
+<para>
+Three functions support "process control" for X clients:
+<blockquote><programlisting>
+
+ Bool ClientSleep (client, function, closure)
+ ClientPtr client;
+ Bool (*function)();
+ pointer closure;
+
+</programlisting></blockquote>
+This suspends the current client (the calling routine is responsible for
+making its way back to Dispatch()). No more X requests will be processed
+for this client until ClientWakeup is called.
+<blockquote><programlisting>
+
+ Bool ClientSignal (client)
+ ClientPtr client;
+
+</programlisting></blockquote>
+This function causes a call to the (*function) parameter passed to
+ClientSleep to be queued on the work queue. This does not automatically
+"wakeup" the client, but the function called is free to do so by calling:
+<blockquote><programlisting>
+
+ ClientWakeup (client)
+ ClientPtr client;
+
+</programlisting></blockquote>
+This re-enables X request processing for the specified client.
+</para>
+</section>
+<section>
+ <title>Other OS Functions</title>
+<para>
+<blockquote><programlisting>
+ void
+ ErrorF(char *f, ...)
+
+ void
+ FatalError(char *f, ...)
+
+ void
+ Error(str)
+ char *str;
+</programlisting></blockquote>
+You should write these three routines to provide for diagnostic output
+from the dix and ddx layers, although implementing them to produce no
+output will not affect the correctness of your server. ErrorF() and
+FatalError() take a printf() type of format specification in the first
+argument and an implementation-dependent number of arguments following
+that. Normally, the formats passed to ErrorF() and FatalError()
+should be terminated with a newline. Error() provides an os interface
+for printing out the string passed as an argument followed by a
+meaningful explanation of the last system error. Normally the string
+does not contain a newline, and it is only called by the ddx layer.
+In the sample implementation, Error() uses the perror() function.
+</para>
+<para>
+After printing the message arguments, FatalError() must be implemented
+such that the server will call AbortDDX() to give the ddx layer
+a chance to reset the hardware, and then
+terminate the server; it must not return.
+</para>
+<para>
+The sample server implementation for these routines
+is in Xserver/os/util.c.
+</para>
+</section>
+<section>
+ <title>Idiom Support</title>
+<para>
+The DBE specification introduces the notion of idioms, which are
+groups of X requests which can be executed more efficiently when taken
+as a whole compared to being performed individually and sequentially.
+This following server internal support to allows DBE
+implementations, as well as other parts of the server,
+to do idiom processing.
+</para>
+<para>
+<blockquote><programlisting>
+
+ xReqPtr PeekNextRequest(xReqPtr req, ClientPtr client, Bool readmore)
+</programlisting></blockquote>
+If req is NULL, the return value will be a pointer to the start of the
+complete request that follows the one currently being executed for the
+client. If req is not NULL, the function assumes that req is a
+pointer to a request in the client's request buffer, and the return
+value will be a pointer to the the start of the complete request that
+follows req. If the complete request is not available, the function
+returns NULL; pointers to partial requests will never be returned. If
+(and only if) readmore is TRUE, PeekNextRequest should try to read an
+additional request from the client if one is not already available in
+the client's request buffer. If PeekNextRequest reads more data into
+the request buffer, it should not move or change the existing data.
+</para>
+<para>
+<blockquote><programlisting>
+
+ void SkipRequests(xReqPtr req, ClientPtr client, int numskipped)
+</programlisting></blockquote>
+The requests for the client up to and including the one specified by
+req will be skipped. numskipped must be the number of requests being
+skipped. Normal request processing will resume with the request that
+follows req. The caller must not have modified the contents of the
+request buffer in any way (e.g., by doing byte swapping in place).
+</para>
+<para>
+Additionally, two macros in os.h operate on the xReq
+pointer returned by PeekNextRequest:
+<blockquote><programlisting>
+
+ int ReqLen(xReqPtr req, ClientPtr client)
+</programlisting></blockquote>
+The value of ReqLen is the request length in bytes of the given xReq.
+<blockquote><programlisting>
+
+ otherReqTypePtr CastxReq(xReq *req, otherReqTypePtr)
+</programlisting></blockquote>
+The value of CastxReq is the conversion of the given request pointer
+to an otherReqTypePtr (which should be a pointer to a protocol
+structure type). Only those fields which come after the length field
+of otherReqType may be accessed via the returned pointer.
+</para>
+<para>
+Thus the first two fields of a request, reqType and data, can be
+accessed directly using the xReq * returned by PeekNextRequest. The
+next field, the length, can be accessed with ReqLen. Fields beyond
+that can be accessed with CastxReq. This complexity was necessary
+because of the reencoding of core protocol that can happen due to the
+BigRequests extension.
+</para>
+</section>
+</section>
+
+<section>
+ <title>DDX Layer</title>
+<para>
+This section describes the
+interface between DIX and DDX.
+While there may be an OS-dependent driver interface between DDX
+and the physical device, that interface is left to the DDX
+implementor and is not specified here.
+</para>
+<para>
+The DDX layer does most of its work through procedures that are
+pointed to by different structs.
+As previously described, the behavior of these resources is largely determined by
+these procedure pointers.
+Most of these routines are for graphic display on the screen or support functions thereof.
+The rest are for user input from input devices.
+</para>
+<section>
+ <title>Input</title>
+<para>
+In this document "input" refers to input from the user,
+such as mouse, keyboard, and
+bar code readers.
+X input devices are of several types: keyboard, pointing device, and
+many others. The core server has support for extension devices as
+described by the X Input Extension document; the interfaces used by
+that extension are described elsewhere. The core devices are actually
+implemented as two collections of devices, the mouse is a ButtonDevice,
+a ValuatorDevice and a PtrFeedbackDevice while the keyboard is a KeyDevice,
+a FocusDevice and a KbdFeedbackDevice. Each part implements a portion of
+the functionality of the device. This abstraction is hidden from view for
+core devices by DIX.
+</para>
+<para>
+You, the DDX programmer, are
+responsible for some of the routines in this section.
+Others are DIX routines that you should call to do the things you need to do in these DDX routines.
+Pay attention to which is which.
+</para>
+<section>
+ <title>Input Device Data Structures</title>
+<para>
+DIX keeps a global directory of devices in a central data structure
+called InputInfo.
+For each device there is a device structure called a DeviceRec.
+DIX can locate any DeviceRec through InputInfo.
+In addition, it has a special pointer to identify the main pointing device
+and a special pointer to identify the main keyboard.
+</para>
+<para>
+The DeviceRec (Xserver/include/input.h) is a device-independent
+structure that contains the state of an input device.
+A DevicePtr is simply a pointer to a DeviceRec.
+</para>
+<para>
+An xEvent describes an event the server reports to a client.
+Defined in Xproto.h, it is a huge struct of union of structs that have fields for
+all kinds of events.
+All of the variants overlap, so that the struct is actually very small in memory.
+</para>
+</section>
+<section>
+ <title>Processing Events</title>
+<para>
+The main DDX input interface is the following routine:
+<blockquote><programlisting>
+
+ void ProcessInputEvents()
+</programlisting></blockquote>
+You must write this routine to deliver input events from the user.
+DIX calls it when input is pending (see next section), and possibly
+even when it is not.
+You should write it to get events from each device and deliver
+the events to DIX.
+To deliver the events to DIX, DDX should call the following
+routine:
+<blockquote><programlisting>
+
+ void DevicePtr->processInputProc(pEvent, device, count)
+ xEventPtr events;
+ DeviceIntPtr device;
+ int count;
+</programlisting></blockquote>
+This is the "input proc" for the device, a DIX procedure.
+DIX will fill in this procedure pointer to one of its own routines by
+the time ProcessInputEvents() is called the first time.
+Call this input proc routine as many times as needed to
+deliver as many events as should be delivered.
+DIX will buffer them up and send them out as needed. Count is set
+to the number of event records which make up one atomic device event and
+is always 1 for the core devices (see the X Input Extension for descriptions
+of devices which may use count > 1).
+</para>
+<para>
+For example, your ProcessInputEvents() routine might check the mouse and the
+keyboard.
+If the keyboard had several keystrokes queued up, it could just call
+the keyboard's processInputProc as many times as needed to flush its internal queue.
+</para>
+<para>
+event is an xEvent struct you pass to the input proc.
+When the input proc returns, it is finished with the event rec, and you can fill
+in new values and call the input proc again with it.
+</para>
+<para>
+You should deliver the events in the same order that they were generated.
+</para>
+<para>
+For keyboard and pointing devices the xEvent variant should be keyButtonPointer.
+Fill in the following fields in the xEvent record:
+<itemizedlist>
+
+<listitem><para>type - is one of the following: KeyPress, KeyRelease, ButtonPress,
+ ButtonRelease, or MotionNotify</para></listitem>
+<listitem><para>detail - for KeyPress or KeyRelease fields, this should be the
+ key number (not the ASCII code); otherwise unused</para></listitem>
+<listitem><para>time - is the time that the event happened (32-bits, in milliseconds, arbitrary origin)</para></listitem>
+<listitem><para>rootX - is the x coordinate of cursor</para></listitem>
+<listitem><para>rootY - is the y coordinate of cursor</para></listitem>
+
+</itemizedlist>
+The rest of the fields are filled in by DIX.
+</para>
+<para>
+The time stamp is maintained by your code in the DDX layer, and it is your responsibility to
+stamp all events correctly.
+</para>
+<para>
+The x and y coordinates of the pointing device and the time must be filled in for all event types
+including keyboard events.
+</para>
+<para>
+The pointing device must report all button press and release events.
+In addition, it should report a MotionNotify event every time it gets called
+if the pointing device has moved since the last notify.
+Intermediate pointing device moves are stored in a special GetMotionEvents buffer,
+because most client programs are not interested in them.
+</para>
+<para>
+There are quite a collection of sample implementations of this routine,
+one for each supported device.
+</para>
+</section>
+<section>
+<title>Telling DIX When Input is Pending</title>
+<para>
+In the server's dispatch loop, DIX checks to see
+if there is any device input pending whenever WaitForSomething() returns.
+If the check says that input is pending, DIX calls the
+DDX routine ProcessInputEvents().
+</para>
+<para>
+This check for pending input must be very quick; a procedure call
+is too slow.
+The code that does the check is a hardwired IF
+statement in DIX code that simply compares the values
+pointed to by two pointers.
+If the values are different, then it assumes that input is pending and
+ProcessInputEvents() is called by DIX.
+</para>
+<para>
+You must pass pointers to DIX to tell it what values to compare.
+The following procedure
+is used to set these pointers:
+<blockquote><programlisting>
+
+ void SetInputCheck(p1, p2)
+ long *p1, *p2;
+</programlisting></blockquote>
+You should call it sometime during initialization to indicate to DIX the
+correct locations to check.
+You should
+pay special attention to the size of what they actually point to,
+because the locations are assumed to be longs.
+</para>
+<para>
+These two pointers are initialized by DIX
+to point to arbitrary values that
+are different.
+In other words, if you forget to call this routine during initialization,
+the worst thing that will happen is that
+ProcessInputEvents will be called when
+there are no events to process.
+</para>
+<para>
+p1 and p2 might
+point at the head and tail of some shared
+memory queue.
+Another use would be to have one point at a constant 0, with the
+other pointing at some mask containing 1s
+for each input device that has
+something pending.
+</para>
+<para>
+The DDX layer of the sample server calls SetInputCheck()
+once when the
+server's private internal queue is initialized.
+It passes pointers to the queue's head and tail. See Xserver/mi/mieq.c.
+</para>
+<para>
+<blockquote><programlisting>
+ int TimeSinceLastInputEvent()
+</programlisting></blockquote>
+DDX must time stamp all hardware input
+events. But DIX sometimes needs to know the
+time and the OS layer needs to know the time since the last hardware
+input event in
+order for the screen saver to work. TimeSinceLastInputEvent() returns
+the this time in milliseconds.
+</para>
+</section>
+<section>
+ <title>Controlling Input Devices</title>
+<para>
+You must write four routines to do various device-specific
+things with the keyboard and pointing device.
+They can have any name you wish because
+you pass the procedure pointers to DIX routines.
+</para>
+<para>
+<blockquote><programlisting>
+
+ int pInternalDevice->valuator->GetMotionProc(pdevice, coords, start, stop, pScreen)
+ DeviceIntPtr pdevice;
+ xTimecoord * coords;
+ unsigned long start;
+ unsigned long stop;
+ ScreenPtr pScreen;
+</programlisting></blockquote>
+You write this DDX routine to fill in coords with all the motion
+events that have times (32-bit count of milliseconds) between time
+start and time stop. It should return the number of motion events
+returned. If there is no motion events support, this routine should
+do nothing and return zero. The maximum number of coords to return is
+set in InitPointerDeviceStruct(), below.
+</para>
+<para>
+When the user drags the pointing device, the cursor position
+theoretically sweeps through an infinite number of points. Normally,
+a client that is concerned with points other than the starting and
+ending points will receive a pointer-move event only as often as the
+server generates them. (Move events do not queue up; each new one
+replaces the last in the queue.) A server, if desired, can implement
+a scheme to save these intermediate events in a motion buffer. A
+client application, like a paint program, may then request that these
+events be delivered to it through the GetMotionProc routine.
+</para>
+<para>
+<blockquote><programlisting>
+
+ void pInternalDevice->bell->BellProc(percent, pDevice, ctrl, unknown)
+ int percent;
+ DeviceIntPtr pDevice;
+ pointer ctrl;
+ int class;
+</programlisting></blockquote>
+You need to write this routine to ring the bell on the keyboard.
+loud is a number from 0 to 100, with 100 being the loudest.
+Class is either BellFeedbackClass or KbdFeedbackClass (from XI.h).
+</para>
+<para>
+<blockquote><programlisting>
+
+ void pInternalDevice->somedevice->CtrlProc(device, ctrl)
+ DevicePtr device;
+ SomethingCtrl *ctrl;
+
+</programlisting></blockquote>
+You write two versions of this procedure, one for the keyboard and one for the pointing device.
+DIX calls it to inform DDX when a client has requested changes in the current
+settings for the particular device.
+For a keyboard, this might be the repeat threshold and rate.
+For a pointing device, this might be a scaling factor (coarse or fine) for position reporting.
+See input.h for the ctrl structures.
+</para>
+</section>
+<section>
+ <title>Input Initialization</title>
+<para>
+Input initialization is a bit complicated.
+It all starts with InitInput(), a routine that you write to call
+AddInputDevice() twice
+(once for pointing device and once for keyboard.)
+You also want to call RegisterKeyboardDevice() and RegisterPointerDevice()
+on them.
+</para>
+<para>
+When you Add the devices, a routine you supply for each device
+gets called to initialize them.
+Your individual initialize routines must call InitKeyboardDeviceStruct()
+or InitPointerDeviceStruct(), depending upon which it is.
+In other words, you indicate twice that the keyboard is the keyboard and
+the pointer is the pointer.
+</para>
+<para>
+<blockquote><programlisting>
+
+ void InitInput(argc, argv)
+ int argc;
+ char **argv;
+</programlisting></blockquote>
+InitInput is a DDX routine you must write to initialize the
+input subsystem in DDX.
+It must call AddInputDevice() for each device that might generate events.
+In addition, you must register the main keyboard and pointing devices by
+calling RegisterPointerDevice() and RegisterKeyboardDevice().
+</para>
+<para>
+<blockquote><programlisting>
+
+ DevicePtr AddInputDevice(deviceProc, autoStart)
+ DeviceProc deviceProc;
+ Bool autoStart;
+</programlisting></blockquote>
+AddInputDevice is a DIX routine you call to create a device object.
+deviceProc is a DDX routine that is called by DIX to do various operations.
+AutoStart should be TRUE for devices that need to be turned on at
+initialization time with a special call, as opposed to waiting for some
+client application to
+turn them on.
+This routine returns NULL if sufficient memory cannot be allocated to
+install the device.
+</para>
+<para>
+Note also that except for the main keyboard and pointing device,
+an extension is needed to provide for a client interface to a device.
+</para>
+<para>
+<blockquote><programlisting>
+
+ void RegisterPointerDevice(device)
+ DevicePtr device;
+</programlisting></blockquote>
+RegisterPointerDevice is a DIX routine that your DDX code calls that
+makes that device the main pointing device.
+This routine is called once upon initialization and cannot be called again.
+</para>
+<para>
+<blockquote><programlisting>
+
+ void RegisterKeyboardDevice(device)
+ DevicePtr device;
+</programlisting></blockquote>
+RegisterKeyboardDevice makes the given device the main keyboard.
+This routine is called once upon initialization and cannot be called again.
+</para>
+<para>
+The following DIX
+procedures return the specified DevicePtr. They may or may not be useful
+to DDX implementors.
+</para>
+<para>
+<blockquote><programlisting>
+
+ DevicePtr LookupKeyboardDevice()
+</programlisting></blockquote>
+LookupKeyboardDevice returns pointer for current main keyboard device.
+</para>
+<para>
+<blockquote><programlisting>
+
+ DevicePtr LookupPointerDevice()
+</programlisting></blockquote>
+LookupPointerDevice returns pointer for current main pointing device.
+</para>
+<para>
+A DeviceProc (the kind passed to AddInputDevice()) in the following form:
+<blockquote><programlisting>
+
+ Bool pInternalDevice->DeviceProc(device, action);
+ DeviceIntPtr device;
+ int action;
+</programlisting></blockquote>
+You must write a DeviceProc for each device.
+device points to the device record.
+action tells what action to take;
+it will be one of these defined constants (defined in input.h):
+<itemizedlist>
+<listitem><para>
+DEVICE_INIT -
+At DEVICE_INIT time, the device should initialize itself by calling
+InitPointerDeviceStruct(), InitKeyboardDeviceStruct(), or a similar
+routine (see below)
+and "opening" the device if necessary.
+If you return a non-zero (i.e., != Success) value from the DEVICE_INIT
+call, that device will be considered unavailable. If either the main keyboard
+or main pointing device cannot be initialized, the DIX code will refuse
+to continue booting up.</para></listitem>
+<listitem><para>
+DEVICE_ON - If the DeviceProc is called with DEVICE_ON, then it is
+allowed to start
+putting events into the client stream by calling through the ProcessInputProc
+in the device.</para></listitem>
+<listitem><para>
+DEVICE_OFF - If the DeviceProc is called with DEVICE_OFF, no further
+events from that
+device should be given to the DIX layer.
+The device will appear to be dead to the user.</para></listitem>
+<listitem><para>
+DEVICE_CLOSE - At DEVICE_CLOSE (terminate or reset) time, the device should
+be totally closed down.</para></listitem>
+</itemizedlist>
+</para>
+<para>
+<blockquote><programlisting>
+
+ void InitPointerDeviceStruct(device, map, mapLength,
+ GetMotionEvents, ControlProc, numMotionEvents)
+ DevicePtr device;
+ CARD8 *map;
+ int mapLength;
+ ValuatorMotionProcPtr ControlProc;
+ PtrCtrlProcPtr GetMotionEvents;
+ int numMotionEvents;
+</programlisting></blockquote>
+InitPointerDeviceStruct is a DIX routine you call at DEVICE_INIT time to declare
+some operating routines and data structures for a pointing device.
+map and mapLength are as described in the X Window
+System protocol specification.
+ControlProc and GetMotionEvents are DDX routines, see above.
+</para>
+<para>
+numMotionEvents is for the motion-buffer-size for the GetMotionEvents
+request.
+A typical length for a motion buffer would be 100 events.
+A server that does not implement this capability should set
+numMotionEvents to zero.
+</para>
+<para>
+<blockquote><programlisting>
+
+ void InitKeyboardDeviceStruct(device, pKeySyms, pModifiers, Bell, ControlProc)
+ DevicePtr device;
+ KeySymsPtr pKeySyms;
+ CARD8 *pModifiers;
+ BellProcPtr Bell;
+ KbdCtrlProcPtr ControlProc;
+
+</programlisting></blockquote>
+You call this DIX routine when a keyboard device is initialized and
+its device procedure is called with
+DEVICE_INIT.
+The formats of the keysyms and modifier maps are defined in
+Xserver/include/input.h.
+They describe the layout of keys on the keyboards, and the glyphs
+associated with them. ( See the next section for information on
+setting up the modifier map and the keysym map.)
+ControlProc and Bell are DDX routines, see above.
+</para>
+</section>
+<section>
+ <title>Keyboard Mapping and Keycodes</title>
+<para>
+When you send a keyboard event, you send a report that a given key has
+either been pressed or has been released. There must be a keycode for
+each key that identifies the key; the keycode-to-key mapping can be
+any mapping you desire, because you specify the mapping in a table you
+set up for DIX. However, you are restricted by the protocol
+specification to keycode values in the range 8 to 255 inclusive.
+</para>
+<para>
+The keycode mapping information that you set up consists of the following:
+<itemizedlist>
+<listitem><para>
+A minimum and maximum keycode number</para></listitem>
+<listitem><para>
+An array of sets of keysyms for each key, that is of length
+maxkeycode - minkeycode + 1.
+Each element of this array is a list of codes for symbols that are on that key.
+There is no limit to the number of symbols that can be on a key.</para></listitem>
+</itemizedlist>
+Once the map is set up, DIX keeps and
+maintains the client's changes to it.
+</para>
+<para>
+The X protocol defines standard names to indicate the symbol(s)
+printed on each keycap. (See X11/keysym.h)
+</para>
+<para>
+Legal modifier keys must generate both up and down transitions. When
+a client tries to change a modifier key (for instance, to make "A" the
+"Control" key), DIX calls the following routine, which should retuurn
+TRUE if the key can be used as a modifier on the given device:
+<blockquote><programlisting>
+
+ Bool LegalModifier(key, pDev)
+ unsigned int key;
+ DevicePtr pDev;
+</programlisting></blockquote>
+</para>
+</section>
+</section>
+<section>
+<title>Screens</title>
+<para>
+Different computer graphics
+displays have different capabilities.
+Some are simple monochrome
+frame buffers that are just lying
+there in memory, waiting to be written into.
+Others are color displays with many bits per pixel using some color lookup table.
+Still others have high-speed graphic processors that prefer to do all of the work
+themselves,
+including maintaining their own high-level, graphic data structures.
+</para>
+<section>
+ <title>Screen Hardware Requirements</title>
+<para>
+The only requirement on screens is that you be able to both read
+and write locations in the frame buffer.
+All screens must have a depth of 32 or less (unless you use
+an X extension to allow a greater depth).
+All screens must fit into one of the classes listed in the section
+in this document on Visuals and Depths.
+</para>
+<para>
+X uses the pixel as its fundamental unit of distance on the screen.
+Therefore, most programs will measure everything in pixels.</para>
+<para>
+The sample server assumes square pixels.
+Serious WYSIWYG (what you see is what you get) applications for
+publishing and drawing programs will adjust for
+different screen resolutions automatically.
+Considerable work
+is involved in compensating for non-square pixels (a bit in the DDX
+code for the sample server but quite a bit in the client applications).</para>
+</section>
+<section>
+ <title>Data Structures</title>
+<para>
+X supports multiple screens that are connected to the same
+server. Therefore, all the per-screen information is bundled into one data
+structure of attributes and procedures, which is the ScreenRec (see
+Xserver/include/scrnintstr.h).
+The procedure entry points in a ScreenRec operate on
+regions, colormaps, cursors, and fonts, because these resources
+can differ in format from one screen to another.</para>
+<para>
+Windows are areas on the screen that can be drawn into by graphic
+routines. "Pixmaps" are off-screen graphic areas that can be drawn
+into. They are both considered drawables and are described in the
+section on Drawables. All graphic operations work on drawables, and
+operations are available to copy patches from one drawable to another.</para>
+<para>
+The pixel image data in all drawables is in a format that is private
+to DDX. In fact, each instance of a drawable is associated with a
+given screen. Presumably, the pixel image data for pixmaps is chosen
+to be conveniently understood by the hardware. All screens in a
+single server must be able to handle all pixmaps depths declared in
+the connection setup information.</para>
+<para>
+Pixmap images are transferred to the server in one of two ways:
+XYPixmap or ZPimap. XYPixmaps are a series of bitmaps, one for each
+bit plane of the image, using the bitmap padding rules from the
+connection setup. ZPixmaps are a series of bits, nibbles, bytes or
+words, one for each pixel, using the format rules (padding and so on)
+for the appropriate depth.</para>
+<para>
+All screens in a given server must agree on a set of pixmap image
+formats (PixmapFormat) to support (depth, number of bits per pixel,
+etc.).</para>
+<para>
+There is no color interpretation of bits in the pixmap. Pixmaps
+do not contain pixel values. The interpretation is made only when
+the bits are transferred onto the screen.</para>
+<para>
+The screenInfo structure (in scrnintstr.h) is a global data structure
+that has a pointer to an array of ScreenRecs, one for each screen on
+the server. (These constitute the one and only description of each
+screen in the server.) Each screen has an identifying index (0, 1, 2, ...).
+In addition, the screenInfo struct contains global server-wide
+details, such as the bit- and byte- order in all bit images, and the
+list of pixmap image formats that are supported. The X protocol
+insists that these must be the same for all screens on the server.</para>
+</section>
+<section>
+ <title>Output Initialization</title>
+<para>
+<blockquote><programlisting>
+
+ InitOutput(pScreenInfo, argc, argv)
+ ScreenInfo *pScreenInfo;
+ int argc;
+ char **argv;
+</programlisting></blockquote>
+Upon initialization, your DDX routine InitOutput() is called by DIX.
+It is passed a pointer to screenInfo to initialize. It is also passed
+the argc and argv from main() for your server for the command-line
+arguments. These arguments may indicate what or how many screen
+device(s) to use or in what way to use them. For instance, your
+server command line may allow a "-D" flag followed by the name of the
+screen device to use.</para>
+<para>
+Your InitOutput() routine should initialize each screen you wish to
+use by calling AddScreen(), and then it should initialize the pixmap
+formats that you support by storing values directly into the
+screenInfo data structure. You should also set certain
+implementation-dependent numbers and procedures in your screenInfo,
+which determines the pixmap and scanline padding rules for all screens
+in the server.</para>
+<para>
+<blockquote><programlisting>
+
+ int AddScreen(scrInitProc, argc, argv)
+ Bool (*scrInitProc)();
+ int argc;
+ char **argv;
+</programlisting></blockquote>
+You should call AddScreen(), a DIX procedure, in InitOutput() once for
+each screen to add it to the screenInfo database. The first argument
+is an initialization procedure for the screen that you supply. The
+second and third are the argc and argv from main(). It returns the
+screen number of the screen installed, or -1 if there is either
+insufficient memory to add the screen, or (*scrInitProc) returned
+FALSE.</para>
+<para>
+The scrInitProc should be of the following form:
+<blockquote><programlisting>
+
+ Bool scrInitProc(iScreen, pScreen, argc, argv)
+ int iScreen;
+ ScreenPtr pScreen;
+ int argc;
+ char **argv;
+</programlisting></blockquote>
+iScreen is the index for this screen; 0 for the first one initialized,
+1 for the second, etc. pScreen is the pointer to the screen's new
+ScreenRec. argc and argv are as before. Your screen initialize
+procedure should return TRUE upon success or FALSE if the screen
+cannot be initialized (for instance, if the screen hardware does not
+exist on this machine).</para>
+<para>
+This procedure must determine what actual device it is supposed to initialize.
+If you have a different procedure for each screen, then it is no problem.
+If you have the same procedure for multiple screens, it may have trouble
+figuring out which screen to initialize each time around, especially if
+InitOutput() does not initialize all of the screens.
+It is probably easiest to have one procedure for each screen.</para>
+<para>
+The initialization procedure should fill in all the screen procedures
+for that screen (windowing functions, region functions, etc.) and certain
+screen attributes for that screen.</para>
+</section>
+<section>
+ <title>Region Routines in the ScreenRec</title>
+<para>
+A region is a dynamically allocated data structure that describes an
+irregularly shaped piece of real estate in XY pixel space. You can
+think of it as a set of pixels on the screen to be operated upon with
+set operations such as AND and OR.</para>
+<para>
+A region is frequently implemented as a list of rectangles or bitmaps
+that enclose the selected pixels. Region operators control the
+"clipping policy," or the operations that work on regions. (The
+sample server uses YX-banded rectangles. Unless you have something
+already implemented for your graphics system, you should keep that
+implementation.) The procedure pointers to the region operators are
+located in the ScreenRec data structure. The definition of a region
+can be found in the file Xserver/include/regionstr.h. The region code
+is found in Xserver/mi/miregion.c. DDX implementations using other
+region formats will need to supply different versions of the region
+operators.</para>
+<para>
+Since the list of rectangles is unbounded in size, part of the region
+data structure is usually a large, dynamically allocated chunk of
+memory. As your region operators calculate logical combinations of
+regions, these blocks may need to be reallocated by your region
+software. For instance, in the sample server, a RegionRec has some
+header information and a pointer to a dynamically allocated rectangle
+list. Periodically, the rectangle list needs to be expanded with
+Xrealloc(), whereupon the new pointer is remembered in the RegionRec.</para>
+<para>
+Most of the region operations come in two forms: a function pointer in
+the Screen structure, and a macro. The server can be compiled so that
+the macros make direct calls to the appropriate functions (instead of
+indirecting through a screen function pointer), or it can be compiled
+so that the macros are identical to the function pointer forms.
+Making direct calls is faster on many architectures.</para>
+<para>
+<blockquote><programlisting>
+
+ RegionPtr pScreen->RegionCreate( rect, size)
+ BoxPtr rect;
+ int size;
+
+ macro: RegionPtr REGION_CREATE(pScreen, rect, size)
+
+</programlisting></blockquote>
+RegionCreate creates a region that describes ONE rectangle. The
+caller can avoid unnecessary reallocation and copying by declaring the
+probable maximum number of rectangles that this region will need to
+describe itself. Your region routines, though, cannot fail just
+because the region grows beyond this size. The caller of this routine
+can pass almost anything as the size; the value is merely a good guess
+as to the maximum size until it is proven wrong by subsequent use.
+Your region procedures are then on their own in estimating how big the
+region will get. Your implementation might ignore size, if
+applicable.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->RegionInit (pRegion, rect, size)
+ RegionPtr pRegion;
+ BoxPtr rect;
+ int size;
+
+ macro: REGION_INIT(pScreen, pRegion, rect, size)
+
+</programlisting></blockquote>
+Given an existing raw region structure (such as an local variable), this
+routine fills in the appropriate fields to make this region as usable as
+one returned from RegionCreate. This avoids the additional dynamic memory
+allocation overhead for the region structure itself.
+</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->RegionCopy(dstrgn, srcrgn)
+ RegionPtr dstrgn, srcrgn;
+
+ macro: Bool REGION_COPY(pScreen, dstrgn, srcrgn)
+
+</programlisting></blockquote>
+RegionCopy copies the description of one region, srcrgn, to another
+already-created region,
+dstrgn; returning TRUE if the copy succeeded, and FALSE otherwise.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->RegionDestroy( pRegion)
+ RegionPtr pRegion;
+
+ macro: REGION_DESTROY(pScreen, pRegion)
+
+</programlisting></blockquote>
+RegionDestroy destroys a region and frees all allocated memory.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->RegionUninit (pRegion)
+ RegionPtr pRegion;
+
+ macro: REGION_UNINIT(pScreen, pRegion)
+
+</programlisting></blockquote>
+Frees everything except the region structure itself, useful when the
+region was originally passed to RegionInit instead of received from
+RegionCreate. When this call returns, pRegion must not be reused until
+it has been RegionInit'ed again.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->Intersect(newReg, reg1, reg2)
+ RegionPtr newReg, reg1, reg2;
+
+ macro: Bool REGION_INTERSECT(pScreen, newReg, reg1, reg2)
+
+ Bool pScreen->Union(newReg, reg1, reg2)
+ RegionPtr newReg, reg1, reg2;
+
+ macro: Bool REGION_UNION(pScreen, newReg, reg1, reg2)
+
+ Bool pScreen->Subtract(newReg, regMinuend, regSubtrahend)
+ RegionPtr newReg, regMinuend, regSubtrahend;
+
+ macro: Bool REGION_UNION(pScreen, newReg, regMinuend, regSubtrahend)
+
+ Bool pScreen->Inverse(newReg, pReg, pBox)
+ RegionPtr newReg, pReg;
+ BoxPtr pBox;
+
+ macro: Bool REGION_INVERSE(pScreen, newReg, pReg, pBox)
+
+</programlisting></blockquote>
+The above four calls all do basic logical operations on regions. They
+set the new region (which already exists) to describe the logical
+intersection, union, set difference, or inverse of the region(s) that
+were passed in. Your routines must be able to handle a situation
+where the newReg is the same region as one of the other region
+arguments.</para>
+<para>
+The subtract function removes the Subtrahend from the Minuend and
+puts the result in newReg.</para>
+<para>
+The inverse function returns a region that is the pBox minus the
+region passed in. (A true "inverse" would make a region that extends
+to infinity in all directions but has holes in the middle.) It is
+undefined for situations where the region extends beyond the box.</para>
+<para>
+Each routine must return the value TRUE for success.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->RegionReset(pRegion, pBox)
+ RegionPtr pRegion;
+ BoxPtr pBox;
+
+ macro: REGION_RESET(pScreen, pRegion, pBox)
+
+</programlisting></blockquote>
+RegionReset sets the region to describe
+one rectangle and reallocates it to a size of one rectangle, if applicable.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->TranslateRegion(pRegion, x, y)
+ RegionPtr pRegion;
+ int x, y;
+
+ macro: REGION_TRANSLATE(pScreen, pRegion, x, y)
+
+</programlisting></blockquote>
+TranslateRegion simply moves a region +x in the x direction and +y in the y
+direction.</para>
+<para>
+<blockquote><programlisting>
+
+ int pScreen->RectIn(pRegion, pBox)
+ RegionPtr pRegion;
+ BoxPtr pBox;
+
+ macro: int RECT_IN_REGION(pScreen, pRegion, pBox)
+
+</programlisting></blockquote>
+RectIn returns one of the defined constants rgnIN, rgnOUT, or rgnPART,
+depending upon whether the box is entirely inside the region, entirely
+outside of the region, or partly in and partly out of the region.
+These constants are defined in Xserver/include/region.h.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->PointInRegion(pRegion, x, y, pBox)
+ RegionPtr pRegion;
+ int x, y;
+ BoxPtr pBox;
+
+ macro: Bool POINT_IN_REGION(pScreen, pRegion, x, y, pBox)
+
+</programlisting></blockquote>
+PointInRegion returns true if the point x, y is in the region. In
+addition, it fills the rectangle pBox with coordinates of a rectangle
+that is entirely inside of pRegion and encloses the point. In the mi
+implementation, it is the largest such rectangle. (Due to the sample
+server implementation, this comes cheaply.)</para>
+<para>
+This routine used by DIX when tracking the pointing device and
+deciding whether to report mouse events or change the cursor. For
+instance, DIX needs to change the cursor when it moves from one window
+to another. Due to overlapping windows, the shape to check may be
+irregular. A PointInRegion() call for every pointing device movement
+may be too expensive. The pBox is a kind of wake-up box; DIX need not
+call PointInRegion() again until the cursor wanders outside of the
+returned box.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->RegionNotEmpty(pRegion)
+ RegionPtr pRegion;
+
+ macro: Bool REGION_NOTEMPTY(pScreen, pRegion)
+
+</programlisting></blockquote>
+RegionNotEmpty is a boolean function that returns
+true or false depending upon whether the region encloses any pixels.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->RegionEmpty(pRegion)
+ RegionPtr pRegion;
+
+ macro: REGION_EMPTY(pScreen, pRegion)
+
+</programlisting></blockquote>
+RegionEmpty sets the region to be empty.</para>
+<para>
+<blockquote><programlisting>
+
+ BoxPtr pScreen->RegionExtents(pRegion)
+ RegionPtr pRegion;
+
+ macro: REGION_EXTENTS(pScreen, pRegion)
+
+</programlisting></blockquote>
+RegionExtents returns a rectangle that is the smallest
+possible superset of the entire region.
+The caller will not modify this rectangle, so it can be the one
+in your region struct.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->RegionAppend (pDstRgn, pRegion)
+ RegionPtr pDstRgn;
+ RegionPtr pRegion;
+
+ macro: Bool REGION_APPEND(pScreen, pDstRgn, pRegion)
+
+ Bool pScreen->RegionValidate (pRegion, pOverlap)
+ RegionPtr pRegion;
+ Bool *pOverlap;
+
+ macro: Bool REGION_VALIDATE(pScreen, pRegion, pOverlap)
+
+</programlisting></blockquote>
+These functions provide an optimization for clip list generation and
+must be used in conjunction. The combined effect is to produce the
+union of a collection of regions, by using RegionAppend several times,
+and finally calling RegionValidate which takes the intermediate
+representation (which needn't be a valid region) and produces the
+desired union. pOverlap is set to TRUE if any of the original
+regions overlap; FALSE otherwise.</para>
+<para>
+<blockquote><programlisting>
+
+ RegionPtr pScreen->BitmapToRegion (pPixmap)
+ PixmapPtr pPixmap;
+
+ macro: RegionPtr BITMAP_TO_REGION(pScreen, pPixmap)
+
+</programlisting></blockquote>
+Given a depth-1 pixmap, this routine must create a valid region which
+includes all the areas of the pixmap filled with 1's and excludes the
+areas filled with 0's. This routine returns NULL if out of memory.</para>
+<para>
+<blockquote><programlisting>
+
+ RegionPtr pScreen->RectsToRegion (nrects, pRects, ordering)
+ int nrects;
+ xRectangle *pRects;
+ int ordering;
+
+ macro: RegionPtr RECTS_TO_REGION(pScreen, nrects, pRects, ordering)
+
+</programlisting></blockquote>
+Given a client-supplied list of rectangles, produces a region which includes
+the union of all the rectangles. Ordering may be used as a hint which
+describes how the rectangles are sorted. As the hint is provided by a
+client, it must not be required to be correct, but the results when it is
+not correct are not defined (core dump is not an option here).</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->SendGraphicsExpose(client,pRegion,drawable,major,minor)
+ ClientPtr client;
+ RegionPtr pRegion;
+ XID drawable;
+ int major;
+ int minor;
+
+</programlisting></blockquote>
+SendGraphicsExpose dispatches a list of GraphicsExposure events which
+span the region to the specified client. If the region is empty, or
+a NULL pointer, a NoExpose event is sent instead.</para>
+</section>
+<section>
+ <title>Cursor Routines for a Screen</title>
+<para>
+A cursor is the visual form tied to the pointing device. The default
+cursor is an "X" shape, but the cursor can have any shape. When a
+client creates a window, it declares what shape the cursor will be
+when it strays into that window on the screen.</para>
+<para>
+For each possible shape the cursor assumes, there is a CursorRec data
+structure. This data structure contains a pointer to a CursorBits
+data structure which contains a bitmap for the image of the cursor and
+a bitmap for a mask behind the cursor, in addition, the CursorRec data
+structure contains foreground and background colors for the cursor.
+The CursorBits data structure is shared among multiple CursorRec
+structures which use the same font and glyph to describe both source
+and mask. The cursor image is applied to the screen by applying the
+mask first, clearing 1 bits in its form to the background color, and
+then overwriting on the source image, in the foreground color. (One
+bits of the source image that fall on top of zero bits of the mask
+image are undefined.) This way, a cursor can have transparent parts,
+and opaque parts in two colors. X allows any cursor size, but some
+hardware cursor schemes allow a maximum of N pixels by M pixels.
+Therefore, you are allowed to transform the cursor to a smaller size,
+but be sure to include the hot-spot.</para>
+<para>
+CursorBits in Xserver/include/cursorstr.h is a device-independent
+structure containing a device-independent representation of the bits
+for the source and mask. (This is possible because the bitmap
+representation is the same for all screens.)</para>
+<para>
+When a cursor is created, it is "realized" for each screen. At
+realization time, each screen has the chance to convert the bits into
+some other representation that may be more convenient (for instance,
+putting the cursor into off-screen memory) and set up its
+device-private area in either the CursorRec data structure or
+CursorBits data structure as appropriate to possibly point to whatever
+data structures are needed. It is more memory-conservative to share
+realizations by using the CursorBits private field, but this makes the
+assumption that the realization is independent of the colors used
+(which is typically true). For instance, the following are the device
+private entries for a particular screen and cursor:
+<blockquote><programlisting>
+
+ pCursor->devPriv[pScreen->myNum]
+ pCursor->bits->devPriv[pScreen->myNum]
+
+</programlisting></blockquote>
+This is done because the change from one cursor shape to another must
+be fast and responsive; the cursor image should be able to flutter as
+fast as the user moves it across the screen.</para>
+<para>
+You must implement the following routines for your hardware:
+<blockquote><programlisting>
+
+ Bool pScreen->RealizeCursor( pScr, pCurs)
+ ScreenPtr pScr;
+ CursorPtr pCurs;
+
+ Bool pScreen->UnrealizeCursor( pScr, pCurs)
+ ScreenPtr pScr;
+ CursorPtr pCurs;
+
+</programlisting></blockquote>
+</para>
+<para>
+RealizeCursor and UnrealizeCursor should realize (allocate and
+calculate all data needed) and unrealize (free the dynamically
+allocated data) a given cursor when DIX needs them. They are called
+whenever a device-independent cursor is created or destroyed. The
+source and mask bits pointed to by fields in pCurs are undefined for
+bits beyond the right edge of the cursor. This is so because the bits
+are in Bitmap format, which may have pad bits on the right edge. You
+should inhibit UnrealizeCursor() if the cursor is currently in use;
+this happens when the system is reset.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->DisplayCursor( pScr, pCurs)
+ ScreenPtr pScr;
+ CursorPtr pCurs;
+
+</programlisting></blockquote>
+DisplayCursor should change the cursor on the given screen to the one
+passed in. It is called by DIX when the user moves the pointing
+device into a different window with a different cursor. The hotspot
+in the cursor should be aligned with the current cursor position.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->RecolorCursor( pScr, pCurs, displayed)
+ ScreenPtr pScr;
+ CursorPtr pCurs;
+ Bool displayed;
+</programlisting></blockquote>
+RecolorCursor notifies DDX that the colors in pCurs have changed and
+indicates whether this is the cursor currently being displayed. If it
+is, the cursor hardware state may have to be updated. Whether
+displayed or not, state created at RealizeCursor time may have to be
+updated. A generic version, miRecolorCursor, may be used that
+does an unrealize, a realize, and possibly a display (in micursor.c);
+however this constrains UnrealizeCursor and RealizeCursor to always return
+TRUE as no error indication is returned here.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->ConstrainCursor( pScr, pBox)
+ ScreenPtr pScr;
+ BoxPtr pBox;
+
+</programlisting></blockquote>
+ConstrainCursor should cause the cursor to restrict its motion to the
+rectangle pBox. DIX code is capable of enforcing this constraint by
+forcefully moving the cursor if it strays out of the rectangle, but
+ConstrainCursor offers a way to send a hint to the driver or hardware
+if such support is available. This can prevent the cursor from
+wandering out of the box, then jumping back, as DIX forces it back.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->PointerNonInterestBox( pScr, pBox)
+ ScreenPtr pScr;
+ BoxPtr pBox;
+
+</programlisting></blockquote>
+PointerNonInterestBox is DIX's way of telling the pointing device code
+not to report motion events while the cursor is inside a given
+rectangle on the given screen. It is optional and, if not
+implemented, it should do nothing. This routine is called only when
+the client has declared that it is not interested in motion events in
+a given window. The rectangle you get may be a subset of that window.
+It saves DIX code the time required to discard uninteresting mouse
+motion events. This is only a hint, which may speed performance.
+Nothing in DIX currently calls PointerNonInterestBox.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->CursorLimits( pScr, pCurs, pHotBox, pTopLeftBox)
+ ScreenPtr pScr;
+ CursorPtr pCurs;
+ BoxPtr pHotBox;
+ BoxPtr pTopLeftBox; /* return value */
+
+</programlisting></blockquote>
+CursorLimits should calculate the box that the cursor hot spot is
+physically capable of moving within, as a function of the screen pScr,
+the device-independent cursor pCurs, and a box that DIX hypothetically
+would want the hot spot confined within, pHotBox. This routine is for
+informing DIX only; it alters no state within DDX.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->SetCursorPosition( pScr, newx, newy, generateEvent)
+ ScreenPtr pScr;
+ int newx;
+ int newy;
+ Bool generateEvent;
+
+</programlisting></blockquote>
+SetCursorPosition should artificially move the cursor as though the
+user had jerked the pointing device very quickly. This is called in
+response to the WarpPointer request from the client, and at other
+times. If generateEvent is True, the device should decide whether or
+not to call ProcessInputEvents() and then it must call
+DevicePtr->processInputProc. Its effects are, of course, limited in
+value for absolute pointing devices such as a tablet.</para>
+<para>
+<blockquote><programlisting>
+
+ void NewCurrentScreen(newScreen, x, y)
+ ScreenPtr newScreen;
+ int x,y;
+
+</programlisting></blockquote>
+If your ddx provides some mechanism for the user to magically move the
+pointer between multiple screens, you need to inform DIX when this
+occurs. You should call NewCurrentScreen to accomplish this, specifying
+the new screen and the new x and y coordinates of the pointer on that screen.</para>
+</section>
+<section>
+ <title>Visuals, Depths and Pixmap Formats for Screens</title>
+<para>
+The "depth" of a image is the number of bits that are used per pixel to display it.</para>
+<para>
+The "bits per pixel" of a pixmap image that is sent over the client
+byte stream is a number that is either 4, 8, 16, 24 or 32. It is the
+number of bits used per pixel in Z format. For instance, a pixmap
+image that has a depth of six is best sent in Z format as 8 bits per
+pixel.</para>
+<para>
+A "pixmap image format" or a "pixmap format" is a description of the
+format of a pixmap image as it is sent over the byte stream. For each
+depth available on a server, there is one and only one pixmap format.
+This pixmap image format gives the bits per pixel and the scanline
+padding unit. (For instance, are pixel rows padded to bytes, 16-bit
+words, or 32-bit words?)</para>
+<para>
+For each screen, you must decide upon what depth(s) it supports. You
+should only count the number of bits used for the actual image. Some
+displays store additional bits to indicate what window this pixel is
+in, how close this object is to a viewer, transparency, and other
+data; do not count these bits.</para>
+<para>
+A "display class" tells whether the display is monochrome or color,
+whether there is a lookup table, and how the lookup table works.</para>
+<para>
+A "visual" is a combination of depth, display class, and a description
+of how the pixel values result in a color on the screen. Each visual
+has a set of masks and offsets that are used to separate a pixel value
+into its red, green, and blue components and a count of the number of
+colormap entries. Some of these fields are only meaningful when the
+class dictates so. Each visual also has a screen ID telling which
+screen it is usable on. Note that the depth does not imply the number
+of map_entries; for instance, a display can have 8 bits per pixel but
+only 254 colormap entries for use by applications (the other two being
+reserved by hardware for the cursor).</para>
+<para>
+Each visual is identified by a 32-bit visual ID which the client uses
+to choose what visual is desired on a given window. Clients can be
+using more than one visual on the same screen at the same time.</para>
+<para>
+The class of a display describes how this translation takes place.
+There are three ways to do the translation.
+<itemizedlist>
+<listitem><para>
+Pseudo - The pixel value, as a whole, is looked up
+in a table of length map_entries to
+determine the color to display.</para></listitem>
+<listitem><para>
+True - The
+pixel value is broken up into red, green, and blue fields, each of which
+are looked up in separate red, green, and blue lookup tables,
+each of length map_entries.</para></listitem>
+<listitem><para>
+Gray - The pixel value is looked up in a table of length map_entries to
+determine a gray level to display.</para></listitem>
+</itemizedlist>
+</para>
+<para>
+In addition, the lookup table can be static (resulting colors are fixed for each
+pixel value)
+or dynamic (lookup entries are under control of the client program).
+This leads to a total of six classes:
+<itemizedlist>
+<listitem><para>
+Static Gray - The pixel value (of however many bits) determines directly the
+level of gray
+that the pixel assumes.</para></listitem>
+<listitem><para>
+Gray Scale - The pixel value is fed through a lookup table to arrive at the level
+of gray to display
+for the given pixel.</para></listitem>
+<listitem><para>
+Static Color - The pixel value is fed through a fixed lookup table that yields the
+color to display
+for that pixel.</para></listitem>
+<listitem><para>
+PseudoColor - The whole pixel value is fed through a programmable lookup
+table that has one
+color (including red, green, and blue intensities) for each possible pixel value,
+and that color is displayed.</para></listitem>
+<listitem><para>
+True Color - Each pixel value consists of one or more bits
+that directly determine each primary color intensity after being fed through
+a fixed table.</para></listitem>
+<listitem><para>
+Direct Color - Each pixel value consists of one or more bits for each primary color.
+Each primary color value is individually looked up in a table for that primary
+color, yielding
+an intensity for that primary color.
+For each pixel, the red value is looked up in the
+red table, the green value in the green table, and
+the blue value in the blue table.</para></listitem>
+</itemizedlist>
+</para>
+<para>
+Here are some examples:
+<itemizedlist>
+<listitem><para>
+A simple monochrome 1 bit per pixel display is Static Gray.</para></listitem>
+<listitem><para>
+A display that has 2 bits per pixel for a choice
+between the colors of black, white, green and violet is Static Color.</para></listitem>
+<listitem><para>
+A display that has three bits per pixel, where
+each bit turns on or off one of the red, green or
+blue guns, is in the True Color class.</para></listitem>
+<listitem><para>
+If you take the last example and scramble the
+correspondence between pixel values and colors
+it becomes a Static Color display.</para></listitem>
+</itemizedlist></para>
+<para>
+A display has 8 bits per pixel. The 8 bits select one entry out of 256 entries
+in a lookup table, each entry consisting of 24 bits (8bits each for red, green,
+and blue).
+The display can show any 256 of 16 million colors on the screen at once.
+This is a pseudocolor display.
+The client application gets to fill the lookup table in this class of display.</para>
+<para>
+Imagine the same hardware from the last example.
+Your server software allows the user, on the
+command line that starts up the server
+program,
+to fill the lookup table to his liking once and for all.
+From then on, the server software would not change the lookup table
+until it exits.
+For instance, the default might be a lookup table with a reasonable sample of
+colors from throughout the color space.
+But the user could specify that the table be filled with 256 steps of gray scale
+because he knew ahead of time he would be manipulating a lot of black-and-white
+scanned photographs
+and not very many color things.
+Clients would be presented with this unchangeable lookup table.
+Although the hardware qualifies as a PseudoColor display,
+the facade presented to the X client is that this is a Static Color display.</para>
+<para>
+You have to decide what kind of display you have or want
+to pretend you have.
+When you initialize the screen(s), this class value must be set in the
+VisualRec data structure along with other display characteristics like the
+depth and other numbers.</para>
+<para>
+The allowable DepthRec's and VisualRec's are pointed to by fields in the ScreenRec.
+These are set up when InitOutput() is called; you should Xalloc() appropriate blocks
+or use static variables initialized to the correct values.</para>
+</section>
+<section>
+<title>Colormaps for Screens</title>
+<para>
+A colormap is a device-independent
+mapping between pixel values and colors displayed on the screen.</para>
+<para>
+Different windows on the same screen can have different
+colormaps at the same time.
+At any given time, the most recently installed
+colormap(s) will be in use in the server
+so that its (their) windows' colors will be guaranteed to be correct.
+Other windows may be off-color.
+Although this may seem to be chaotic, in practice most clients
+use the default colormap for the screen.</para>
+<para>
+The default colormap for a screen is initialized when the screen is initialized.
+It always remains in existence and is not owned by any regular client. It
+is owned by client 0 (the server itself).
+Many clients will simply use this default colormap for their drawing.
+Depending upon the class of the screen, the entries in this colormap may
+be modifiable by client applications.</para>
+</section>
+<section>
+ <title>Colormap Routines</title>
+<para>
+You need to implement the following routines to handle the device-dependent
+aspects of color maps. You will end up placing pointers to these procedures
+in your ScreenRec data structure(s). The sample server implementations of
+many of these routines are in fbcmap.c.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->CreateColormap(pColormap)
+ ColormapPtr pColormap;
+
+</programlisting></blockquote>
+This routine is called by the DIX CreateColormap routine after it has allocated
+all the data for the new colormap and just before it returns to the dispatcher.
+It is the DDX layer's chance to initialize the colormap, particularly if it is
+a static map. See the following
+section for more details on initializing colormaps.
+The routine returns FALSE if creation failed, such as due to memory
+limitations.
+Notice that the colormap has a devPriv field from which you can hang any
+colormap specific storage you need. Since each colormap might need special
+information, we attached the field to the colormap and not the visual.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->DestroyColormap(pColormap)
+ ColormapPtr pColormap;
+
+</programlisting></blockquote>
+This routine is called by the DIX FreeColormap routine after it has uninstalled
+the colormap and notified all interested parties, and before it has freed
+any of the colormap storage.
+It is the DDX layer's chance to free any data it added to the colormap.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->InstallColormap(pColormap)
+ ColormapPtr pColormap;
+
+</programlisting></blockquote>
+InstallColormap should
+fill a lookup table on the screen with which the colormap is associated with
+the colors in pColormap.
+If there is only one hardware lookup table for the screen, then all colors on
+the screen may change simultaneously.</para>
+<para>
+In the more general case of multiple hardware lookup tables,
+this may cause some other colormap to be
+uninstalled, meaning that windows that subscribed to the colormap
+that was uninstalled may end up being off-color.
+See the note, below, about uninstalling maps.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->UninstallColormap(pColormap)
+ ColormapPtr pColormap;
+
+</programlisting></blockquote>
+UninstallColormap should
+remove pColormap from screen pColormap->pScreen.
+Some other map, such as the default map if possible,
+should be installed in place of pColormap if applicable.
+If
+pColormap is the default map, do nothing.
+If any client has requested ColormapNotify events, the DDX layer must notify the client.
+(The routine WalkTree() is
+be used to find such windows. The DIX routines TellNoMap(),
+TellNewMap() and TellGainedMap() are provided to be used as
+the procedure parameter to WalkTree. These procedures are in
+Xserver/dix/colormap.c.)</para>
+<para>
+<blockquote><programlisting>
+
+ int pScreen->ListInstalledColormaps(pScreen, pCmapList)
+ ScreenPtr pScreen;
+ XID *pCmapList;
+
+
+</programlisting></blockquote>
+ListInstalledColormaps fills the pCMapList in with the resource ids
+of the installed maps and returns a count of installed maps.
+pCmapList will point to an array of size MaxInstalledMaps that was allocated
+by the caller.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->StoreColors (pmap, ndef, pdefs)
+ ColormapPtr pmap;
+ int ndef;
+ xColorItem *pdefs;
+
+</programlisting></blockquote>
+StoreColors changes some of the entries in the colormap pmap.
+The number of entries to change are ndef, and pdefs points to the information
+describing what to change.
+Note that partial changes of entries in the colormap are allowed.
+Only the colors
+indicated in the flags field of each xColorItem need to be changed.
+However, all three color fields will be sent with the proper value for the
+benefit of screens that may not be able to set part of a colormap value.
+If the screen is a static class, this routine does nothing.
+The structure of colormap entries is nontrivial; see colormapst.h
+and the definition of xColorItem in Xproto.h for
+more details.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->ResolveColor(pRed, pGreen, pBlue, pVisual)
+ unsigned short *pRed, *pGreen, *pBlue;
+ VisualPtr pVisual;
+
+
+</programlisting></blockquote>
+Given a requested color, ResolveColor returns the nearest color that this hardware is
+capable of displaying on this visual.
+In other words, this rounds off each value, in place, to the number of bits
+per primary color that your screen can use.
+Remember that each screen has one of these routines.
+The level of roundoff should be what you would expect from the value
+you put in the bits_per_rgb field of the pVisual.</para>
+<para>
+Each value is an unsigned value ranging from 0 to 65535.
+The bits least likely to be used are the lowest ones.</para>
+<para>
+For example, if you had a pseudocolor display
+with any number of bits per pixel
+that had a lookup table supplying 6 bits for each color gun
+(a total of 256K different colors), you would
+round off each value to 6 bits. Please don't simply truncate these values
+to the upper 6 bits, scale the result so that the maximum value seen
+by the client will be 65535 for each primary. This makes color values
+more portable between different depth displays (a 6-bit truncated white
+will not look white on an 8-bit display).</para>
+<section>
+<title>Initializing a Colormap</title>
+<para>
+When a client requests a new colormap and when the server creates the default
+colormap, the procedure CreateColormap in the DIX layer is invoked.
+That procedure allocates memory for the colormap and related storage such as
+the lists of which client owns which pixels.
+It then sets a bit, BeingCreated, in the flags field of the ColormapRec
+and calls the DDX layer's CreateColormap routine.
+This is your chance to initialize the colormap.
+If the colormap is static, which you can tell by looking at the class field,
+you will want to fill in each color cell to match the hardwares notion of the
+color for that pixel.
+If the colormap is the default for the screen, which you can tell by looking
+at the IsDefault bit in the flags field, you should allocate BlackPixel
+and WhitePixel to match the values you set in the pScreen structure.
+(Of course, you picked those values to begin with.)</para>
+<para>
+You can also wait and use AllocColor() to allocate blackPixel
+and whitePixel after the default colormap has been created.
+If the default colormap is static and you initialized it in
+pScreen->CreateColormap, then use can use AllocColor afterwards
+to choose pixel values with the closest rgb values to those
+desired for blackPixel and whitePixel.
+If the default colormap is dynamic and uninitialized, then
+the rgb values you request will be obeyed, and AllocColor will
+again choose pixel values for you.
+These pixel values can then be stored into the screen.</para>
+<para>
+There are two ways to fill in the colormap.
+The simplest way is to use the DIX function AllocColor.
+<blockquote><programlisting>
+
+int AllocColor (pmap, pred, pgreen, pblue, pPix, client)
+ ColormapPtr pmap;
+ unsigned short *pred, *pgreen, *pblue;
+ Pixel *pPix;
+ int client;
+
+</programlisting></blockquote>
+This takes three pointers to 16 bit color values and a pointer to a suggested
+pixel value. The pixel value is either an index into one colormap or a
+combination of three indices depending on the type of pmap.
+If your colormap starts out empty, and you don't deliberately pick the same
+value twice, you will always get your suggested pixel.
+The truly nervous could check that the value returned in *pPix is the one
+AllocColor was called with.
+If you don't care which pixel is used, or would like them sequentially
+allocated from entry 0, set *pPix to 0. This will find the first free
+pixel and use that.</para>
+<para>
+AllocColor will take care of all the bookkeeping and will
+call StoreColors to get the colormap rgb values initialized.
+The hardware colormap will be changed whenever this colormap
+is installed.</para>
+<para>
+If for some reason AllocColor doesn't do what you want, you can do your
+own bookkeeping and call StoreColors yourself. This is much more difficult
+and shouldn't be necessary for most devices.</para>
+</section>
+</section>
+<section>
+ <title>Fonts for Screens</title>
+<para>
+A font is a set of bitmaps that depict the symbols in a character set.
+Each font is for only one typeface in a given size, in other words,
+just one bitmap for each character. Parallel fonts may be available
+in a variety of sizes and variations, including "bold" and "italic."
+X supports fonts for 8-bit and 16-bit character codes (for oriental
+languages that have more than 256 characters in the font). Glyphs are
+bitmaps for individual characters.</para>
+<para>
+The source comes with some useful font files in an ASCII, plain-text
+format that should be comprehensible on a wide variety of operating
+systems. The text format, referred to as BDF, is a slight extension
+of the current Adobe 2.1 Bitmap Distribution Format (Adobe Systems,
+Inc.).</para>
+<para>
+A short paper in PostScript format is included with the sample server
+that defines BDF. It includes helpful pictures, which is why it is
+done in PostScript and is not included in this document.</para>
+<para>
+Your implementation should include some sort of font compiler to read
+these files and generate binary files that are directly usable by your
+server implementation. The sample server comes with the source for a
+font compiler.</para>
+<para>
+It is important the font properties contained in the BDF files are
+preserved across any font compilation. In particular, copyright
+information cannot be casually tossed aside without legal
+ramifications. Other properties will be important to some
+sophisticated applications.</para>
+<para>
+All clients get font information from the server. Therefore, your
+server can support any fonts it wants to. It should probably support
+at least the fonts supplied with the X11 tape. In principle, you can
+convert fonts from other sources or dream up your own fonts for use on
+your server.</para>
+<section>
+<title>Portable Compiled Format</title>
+<para>
+A font compiler is supplied with the sample server. It has
+compile-time switches to convert the BDF files into a portable binary
+form, called Portable Compiled Format or PCF. This allows for an
+arbitrary data format inside the file, and by describing the details
+of the format in the header of the file, any PCF file can be read by
+any PCF reading client. By selecting the format which matches the
+required internal format for your renderer, the PCF reader can avoid
+reformatting the data each time it is read in. The font compiler
+should be quite portable.</para>
+<para>
+The fonts included with the tape are stored in fonts/bdf. The
+font compiler is found in fonts/tools/bdftopcf.</para>
+</section>
+<section>
+ <title>Font Realization</title>
+<para>
+Each screen configured into the server
+has an opportunity at font-load time
+to "realize" a font into some internal format if necessary.
+This happens every time the font is loaded into memory.</para>
+<para>
+A font (FontRec in Xserver/include/dixfontstr.h) is
+a device-independent structure containing a device-independent
+representation of the font. When a font is created, it is "realized"
+for each screen. At this point, the screen has the chance to convert
+the font into some other format. The DDX layer can also put information
+in the devPrivate storage.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->RealizeFont(pScr, pFont)
+ ScreenPtr pScr;
+ FontPtr pFont;
+
+ Bool pScreen->UnrealizeFont(pScr, pFont)
+ ScreenPtr pScr;
+ FontPtr pFont;
+
+</programlisting></blockquote>
+RealizeFont and UnrealizeFont should calculate and allocate these extra data structures and
+dispose of them when no longer needed.
+These are called in response to OpenFont and CloseFont requests from
+the client.
+The sample server implementation is in fbscreen.c (which does very little).</para>
+</section>
+</section>
+<section>
+ <title>Other Screen Routines</title>
+<para>
+You must supply several other screen-specific routines for
+your X server implementation.
+Some of these are described in other sections:
+<itemizedlist>
+<listitem><para>
+GetImage() is described in the Drawing Primitives section.</para></listitem>
+<listitem><para>
+GetSpans() is described in the Pixblit routine section.</para></listitem>
+<listitem><para>
+Several window and pixmap manipulation procedures are
+described in the Window section under Drawables.</para></listitem>
+<listitem><para>
+The CreateGC() routine is described under Graphics Contexts.</para></listitem>
+</itemizedlist>
+</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->QueryBestSize(kind, pWidth, pHeight)
+ int kind;
+ unsigned short *pWidth, *pHeight;
+ ScreenPtr pScreen;
+
+</programlisting></blockquote>
+QueryBestSize() returns the best sizes for cursors, tiles, and stipples
+in response to client requests.
+kind is one of the defined constants CursorShape, TileShape, or StippleShape
+(defined in X.h).
+For CursorShape, return the maximum width and
+height for cursors that you can handle.
+For TileShape and StippleShape, start with the suggested values in pWidth
+and pHeight and modify them in place to be optimal values that are
+greater than or equal to the suggested values.
+The sample server implementation is in Xserver/fb/fbscreen.c.</para>
+<para>
+<blockquote><programlisting>
+
+ pScreen->SourceValidate(pDrawable, x, y, width, height)
+ DrawablePtr pDrawable;
+ int x, y, width, height;
+
+</programlisting></blockquote>
+SourceValidate should be called by CopyArea/CopyPlane primitives when
+the source drawable is not the same as the destination, and the
+SourceValidate function pointer in the screen is non-null. If you know that
+you will never need SourceValidate, you can avoid this check. Currently,
+SourceValidate is used by the mi software cursor code to remove the cursor
+from the screen when the source rectangle overlaps the cursor position.
+x,y,width,height describe the source rectangle (source relative, that is)
+for the copy operation.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->SaveScreen(pScreen, on)
+ ScreenPtr pScreen;
+ int on;
+
+</programlisting></blockquote>
+SaveScreen() is used for Screen Saver support (see WaitForSomething()).
+pScreen is the screen to save.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->CloseScreen(pScreen)
+ ScreenPtr pScreen;
+
+</programlisting></blockquote>
+When the server is reset, it calls this routine for each screen.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->CreateScreenResources(pScreen)
+ ScreenPtr pScreen;
+
+</programlisting></blockquote>
+If this routine is not NULL, it will be called once per screen per
+server initialization/reset after all modules have had a chance to
+request private space on all structures that support them (see
+<xref linkend="wrappers_and_privates"/> below). You may create resources
+in this function instead of in the
+screen init function passed to AddScreen in order to guarantee that
+all pre-allocated space requests have been registered first. With the
+new devPrivates mechanism, this is not strictly necessary, however.
+This routine returns TRUE if successful.</para>
+</section>
+</section>
+<section>
+<title>Drawables</title>
+<para>
+A drawable is a descriptor of a surface that graphics are drawn into, either
+a window on the screen or a pixmap in memory.</para>
+<para>
+Each drawable has a type, class,
+ScreenPtr for the screen it is associated with, depth, position, size,
+and serial number.
+The type is one of the defined constants DRAWABLE_PIXMAP,
+DRAWABLE_WINDOW and UNDRAWABLE_WINDOW.
+(An undrawable window is used for window class InputOnly.)
+The serial number is guaranteed to be unique across drawables, and
+is used in determining
+the validity of the clipping information in a GC.
+The screen selects the set of procedures used to manipulate and draw into the
+drawable. Position is used (currently) only by windows; pixmaps must
+set these fields to 0,0 as this reduces the amount of conditional code
+executed throughout the mi code. Size indicates the actual client-specified
+size of the drawable.
+There are, in fact, no other fields that a window drawable and pixmap
+drawable have in common besides those mentioned here.</para>
+<para>
+Both PixmapRecs and WindowRecs are structs that start with a drawable
+and continue on with more fields. Pixmaps have a single pointer field
+named devPrivate which usually points to the pixmap data but could conceivably be
+used for anything that DDX wants. Both windows and pixmaps also have a
+devPrivates field which can be used for DDX specific data (see <xref linkend="wrappers_and_privates"/>
+below). This is done because different graphics hardware has
+different requirements for management; if the graphics is always
+handled by a processor with an independent address space, there is no
+point having a pointer to the bit image itself.</para>
+<para>
+The definition of a drawable and a pixmap can be found in the file
+Xserver/include/pixmapstr.h.
+The definition of a window can be found in the file Xserver/include/windowstr.h.</para>
+<section>
+ <title>Pixmaps</title>
+<para>
+A pixmap is a three-dimensional array of bits stored somewhere offscreen,
+rather than in the visible portion of the screen's display frame buffer. It
+can be used as a source or destination in graphics operations. There is no
+implied interpretation of the pixel values in a pixmap, because it has no
+associated visual or colormap. There is only a depth that indicates the
+number of significant bits per pixel. Also, there is no implied physical
+size for each pixel; all graphic units are in numbers of pixels. Therefore,
+a pixmap alone does not constitute a complete image; it represents only a
+rectangular array of pixel values.</para>
+<para>
+Note that the pixmap data structure is reference-counted.</para>
+<para>
+The server implementation is free to put the pixmap data
+anywhere it sees fit, according to its graphics hardware setup. Many
+implementations will simply have the data dynamically allocated in the
+server's address space. More sophisticated implementations may put the
+data in undisplayed framebuffer storage.</para>
+<para>
+In addition to dynamic devPrivates (see <xref linkend="wrappers_and_privates"/>
+below), the pixmap data structure has two fields that are private to
+the device. Although you can use them for anything you want, they
+have intended purposes. devKind is intended to be a device specific
+indication of the pixmap location (host memory, off-screen, etc.). In
+the sample server, since all pixmaps are in memory, devKind stores the
+width of the pixmap in bitmap scanline units. devPrivate is usually
+a pointer to the bits in the pixmap.</para>
+<para>
+A bitmap is a pixmap that is one bit deep.</para>
+<para>
+<blockquote><programlisting>
+
+ PixmapPtr pScreen->CreatePixmap(pScreen, width, height, depth)
+ ScreenPtr pScreen;
+ int width, height, depth;
+
+</programlisting></blockquote>
+This ScreenRec procedure must create a pixmap of the size
+requested.
+It must allocate a PixmapRec and fill in all of the fields.
+The reference count field must be set to 1.
+If width or height are zero, no space should be allocated
+for the pixmap data, and if the implementation is using the
+devPrivate field as a pointer to the pixmap data, it should be
+set to NULL.
+If successful, it returns a pointer to the new pixmap; if not, it returns NULL.
+See Xserver/fb/fbpixmap.c for the sample server implementation.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->DestroyPixmap(pPixmap)
+ PixmapPtr pPixmap;
+
+</programlisting></blockquote>
+This ScreenRec procedure must "destroy" a pixmap.
+It should decrement the reference count and, if zero, it
+must deallocate the PixmapRec and all attached devPrivate blocks.
+If successful, it returns TRUE.
+See Xserver/fb/fbpixmap.c for the sample server implementation.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool
+ pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData)
+ PixmapPtr pPixmap;
+ int width;
+ int height;
+ int depth;
+ int bitsPerPixel;
+ int devKind;
+ pointer pPixData;
+
+</programlisting></blockquote>
+This routine takes a pixmap header and initializes the fields of the PixmapRec to the
+parameters of the same name. pPixmap must have been created via
+pScreen->CreatePixmap with a zero width or height to avoid
+allocating space for the pixmap data. pPixData is assumed to be the
+pixmap data; it will be stored in an implementation-dependent place
+(usually pPixmap->devPrivate.ptr). This routine returns
+TRUE if successful. See Xserver/mi/miscrinit.c for the sample
+server implementation.</para>
+<para>
+<blockquote><programlisting>
+
+ PixmapPtr
+ GetScratchPixmapHeader(pScreen, width, height, depth, bitsPerPixel, devKind, pPixData)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+ int bitsPerPixel;
+ int devKind;
+ pointer pPixData;
+
+ void FreeScratchPixmapHeader(pPixmap)
+ PixmapPtr pPixmap;
+
+</programlisting></blockquote>
+DDX should use these two DIX routines when it has a buffer of raw
+image data that it wants to manipulate as a pixmap temporarily,
+usually so that some other part of the server can be leveraged to
+perform some operation on the data. The data should be passed in
+pPixData, and will be stored in an implementation-dependent place
+(usually pPixmap->devPrivate.ptr). The other
+fields go into the corresponding PixmapRec fields.
+If successful, GetScratchPixmapHeader returns a valid PixmapPtr which can
+be used anywhere the server expects a pixmap, else
+it returns NULL. The pixmap should be released when no longer needed
+(usually within the same function that allocated it)
+with FreeScratchPixmapHeader.</para>
+</section>
+<section>
+ <title>Windows</title>
+<para>
+A window is a visible, or potentially visible, rectangle on the screen.
+DIX windowing functions maintain an internal n-ary tree data structure, which
+represents the current relationships of the mapped windows.
+Windows that are contained in another window are children of that window and
+are clipped to the boundaries of the parent.
+The root window in the tree is the window for the entire screen.
+Sibling windows constitute a doubly-linked list; the parent window has a pointer
+to the head and tail of this list.
+Each child also has a pointer to its parent.</para>
+<para>
+The border of a window is drawn by a DDX procedure when DIX requests that it
+be drawn. The contents of the window is drawn by the client through
+requests to the server.</para>
+<para>
+Window painting is orchestrated through an expose event system.
+When a region is exposed,
+DIX generates an expose event, telling the client to repaint the window and
+passing the region that is the minimal area needed to be repainted.</para>
+<para>
+As a favor to clients, the server may retain
+the output to the hidden parts of windows
+in off-screen memory; this is called "backing store".
+When a part of such a window becomes exposed, it
+can quickly move pixels into place instead of
+triggering an expose event and waiting for a client on the other
+end of the network to respond.
+Even if the network response is insignificant, the time to
+intelligently paint a section of a window is usually more than
+the time to just copy already-painted sections.
+At best, the repainting involves blanking out the area to a background color,
+which will take about the
+same amount of time.
+In this way, backing store can dramatically increase the
+performance of window moves.</para>
+<para>
+On the other hand, backing store can be quite complex, because
+all graphics drawn to hidden areas must be intercepted and redirected
+to the off-screen window sections.
+Not only can this be complicated for the server programmer,
+but it can also impact window painting performance.
+The backing store implementation can choose, at any time, to
+forget pieces of backing that are written into, relying instead upon
+expose events to repaint for simplicity.</para>
+<para>
+In X, the decision to use the backing-store scheme is made
+by you, the server implementor. The sample server implements
+backing store "for free" by reusing the infrastructure for the Composite
+extension. As a side effect, it treats the WhenMapped and Always hints
+as equivalent. However, it will never forget pixel contents when the
+window is mapped.</para>
+<para>
+When a window operation is requested by the client,
+such as a window being created or moved,
+a new state is computed.
+During this transition, DIX informs DDX what rectangles in what windows are about to
+become obscured and what rectangles in what windows have become exposed.
+This provides a hook for the implementation of backing store.
+If DDX is unable to restore exposed regions, DIX generates expose
+events to the client.
+It is then the client's responsibility to paint the
+window parts that were exposed but not restored.</para>
+<para>
+If a window is resized, pixels sometimes need to be
+moved, depending upon
+the application.
+The client can request "Gravity" so that
+certain blocks of the window are
+moved as a result of a resize.
+For instance, if the window has controls or other items
+that always hang on the edge of the
+window, and that edge is moved as a result of the resize,
+then those pixels should be moved
+to avoid having the client repaint it.
+If the client needs to repaint it anyway, such an operation takes
+time, so it is desirable
+for the server to approximate the appearance of the window as best
+it can while waiting for the client
+to do it perfectly.
+Gravity is used for that, also.</para>
+<para>
+The window has several fields used in drawing
+operations:
+<itemizedlist>
+<listitem><para>
+clipList - This region, in conjunction with
+the client clip region in the gc, is used to clip output.
+clipList has the window's children subtracted from it, in addition to pieces of sibling windows
+that overlap this window. To get the list with the
+children included (subwindow-mode is IncludeInferiors),
+the routine NotClippedByChildren(pWin) returns the unclipped region.</para></listitem>
+<listitem><para>
+borderClip is the region used by CopyWindow and
+includes the area of the window, its children, and the border, but with the
+overlapping areas of sibling children removed.</para></listitem>
+</itemizedlist>
+Most of the other fields are for DIX use only.</para>
+<section>
+<title>Window Procedures in the ScreenRec</title>
+<para>
+You should implement
+all of the following procedures and store pointers to them in the screen record.</para>
+<para>
+The device-independent portion of the server "owns" the window tree.
+However, clever hardware might want to know the relationship of
+mapped windows. There are pointers to procedures
+in the ScreenRec data structure that are called to give the hardware
+a chance to update its internal state. These are helpers and
+hints to DDX only;
+they do not change the window tree, which is only changed by DIX.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->CreateWindow(pWin)
+ WindowPtr pWin;
+
+</programlisting></blockquote>
+This routine is a hook for when DIX creates a window.
+It should fill in the "Window Procedures in the WindowRec" below
+and also allocate the devPrivate block for it.</para>
+<para>
+See Xserver/fb/fbwindow.c for the sample server implementation.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->DestroyWindow(pWin);
+ WindowPtr pWin;
+
+</programlisting></blockquote>
+This routine is a hook for when DIX destroys a window.
+It should deallocate the devPrivate block for it and any other blocks that need
+to be freed, besides doing other cleanup actions.</para>
+<para>
+See Xserver/fb/fbwindow.c for the sample server implementation.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->PositionWindow(pWin, x, y);
+ WindowPtr pWin;
+ int x, y;
+
+</programlisting></blockquote>
+This routine is a hook for when DIX moves or resizes a window.
+It should do whatever private operations need to be done when a window is moved or resized.
+For instance, if DDX keeps a pixmap tile used for drawing the background
+or border, and it keeps the tile rotated such that it is longword
+aligned to longword locations in the frame buffer, then you should rotate your tiles here.
+The actual graphics involved in moving the pixels on the screen and drawing the
+border are handled by CopyWindow(), below.</para>
+<para>
+See Xserver/fb/fbwindow.c for the sample server implementation.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->RealizeWindow(pWin);
+ WindowPtr pWin;
+
+ Bool pScreen->UnrealizeWindow(pWin);
+ WindowPtr pWin;
+
+</programlisting></blockquote>
+These routines are hooks for when DIX maps (makes visible) and unmaps
+(makes invisible) a window. It should do whatever private operations
+need to be done when these happen, such as allocating or deallocating
+structures that are only needed for visible windows. RealizeWindow
+does NOT draw the window border, background or contents;
+UnrealizeWindow does NOT erase the window or generate exposure events
+for underlying windows; this is taken care of by DIX. DIX does,
+however, call PaintWindowBackground() and PaintWindowBorder() to
+perform some of these.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->ChangeWindowAttributes(pWin, vmask)
+ WindowPtr pWin;
+ unsigned long vmask;
+
+</programlisting></blockquote>
+ChangeWindowAttributes is called whenever DIX changes window
+attributes, such as the size, front-to-back ordering, title, or
+anything of lesser severity that affects the window itself. The
+sample server implements this routine. It computes accelerators for
+quickly putting up background and border tiles. (See description of
+the set of routines stored in the WindowRec.)</para>
+<para>
+<blockquote><programlisting>
+
+ int pScreen->ValidateTree(pParent, pChild, kind)
+ WindowPtr pParent, pChild;
+ VTKind kind;
+
+</programlisting></blockquote>
+ValidateTree calculates the clipping region for the parent window and
+all of its children. This routine must be provided. The sample server
+has a machine-independent version in Xserver/mi/mivaltree.c. This is
+a very difficult routine to replace.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->PostValidateTree(pParent, pChild, kind)
+ WindowPtr pParent, pChild;
+ VTKind kind;
+
+</programlisting></blockquote>
+If this routine is not NULL, DIX calls it shortly after calling
+ValidateTree, passing it the same arguments. This is useful for
+managing multi-layered framebuffers.
+The sample server sets this to NULL.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->WindowExposures(pWin, pRegion, pBSRegion)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ RegionPtr pBSRegion;
+
+</programlisting></blockquote>
+The WindowExposures() routine
+paints the border and generates exposure events for the window.
+pRegion is an unoccluded region of the window, and pBSRegion is an
+occluded region that has backing store.
+Since exposure events include a rectangle describing what was exposed,
+this routine may have to send back a series of exposure events, one for
+each rectangle of the region.
+The count field in the expose event is a hint to the
+client as to the number of
+regions that are after this one.
+This routine must be provided. The sample
+server has a machine-independent version in Xserver/mi/miexpose.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->ClipNotify (pWin, dx, dy)
+ WindowPtr pWin;
+ int dx, dy;
+
+</programlisting></blockquote>
+Whenever the cliplist for a window is changed, this function is called to
+perform whatever hardware manipulations might be necessary. When called,
+the clip list and border clip regions in the window are set to the new
+values. dx,dy are the distance that the window has been moved (if at all).</para>
+</section>
+<section>
+ <title>Window Painting Procedures</title>
+<para>
+In addition to the procedures listed above, there are two routines which
+manipulate the actual window image directly.
+In the sample server, mi implementations will work for
+most purposes and fb routines speed up situations, such
+as solid backgrounds/borders or tiles that are 8, 16 or 32 pixels square.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->ClearToBackground(pWin, x, y, w, h, generateExposures);
+ WindowPtr pWin;
+ int x, y, w, h;
+ Bool generateExposures;
+
+</programlisting></blockquote>
+This routine is called on a window in response to a ClearToBackground request
+from the client.
+This request has two different but related functions, depending upon generateExposures.</para>
+<para>
+If generateExposures is true, the client is declaring that the given rectangle
+on the window is incorrectly painted and needs to be repainted.
+The sample server implementation calculates the exposure region
+and hands it to the DIX procedure HandleExposures(), which
+calls the WindowExposures() routine, below, for the window
+and all of its child windows.</para>
+<para>
+If generateExposures is false, the client is trying to simply erase part
+of the window to the background fill style.
+ClearToBackground should write the background color or tile to the
+rectangle in question (probably using PaintWindowBackground).
+If w or h is zero, it clears all the way to the right or lower edge of the window.</para>
+<para>
+The sample server implementation is in Xserver/mi/miwindow.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->CopyWindow(pWin, oldpt, oldRegion);
+ WindowPtr pWin;
+ DDXPointRec oldpt;
+ RegionPtr oldRegion;
+
+</programlisting></blockquote>
+CopyWindow is called when a window is moved, and graphically moves to
+pixels of a window on the screen. It should not change any other
+state within DDX (see PositionWindow(), above).</para>
+<para>
+oldpt is the old location of the upper-left corner. oldRegion is the
+old region it is coming from. The new location and new region is
+stored in the WindowRec. oldRegion might modified in place by this
+routine (the sample implementation does this).</para>
+<para>
+CopyArea could be used, except that this operation has more
+complications. First of all, you do not want to copy a rectangle onto
+a rectangle. The original window may be obscured by other windows,
+and the new window location may be similarly obscured. Second, some
+hardware supports multiple windows with multiple depths, and your
+routine needs to take care of that.</para>
+<para>
+The pixels in oldRegion (with reference point oldpt) are copied to the
+window's new region (pWin->borderClip). pWin->borderClip is gotten
+directly from the window, rather than passing it as a parameter.</para>
+<para>
+The sample server implementation is in Xserver/fb/fbwindow.c.</para>
+</section>
+<section>
+<title>Screen Operations for Multi-Layered Framebuffers</title>
+<para>
+The following screen functions are useful if you have a framebuffer with
+multiple sets of independent bit planes, e.g. overlays or underlays in
+addition to the "main" planes. If you have a simple single-layer
+framebuffer, you should probably use the mi versions of these routines
+in mi/miwindow.c. This can be easily accomplished by calling miScreenInit.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->MarkWindow(pWin)
+ WindowPtr pWin;
+
+</programlisting></blockquote>
+This formerly dix function MarkWindow has moved to ddx and is accessed
+via this screen function. This function should store something,
+usually a pointer to a device-dependent structure, in pWin->valdata so
+that ValidateTree has the information it needs to validate the window.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->MarkOverlappedWindows(parent, firstChild, ppLayerWin)
+ WindowPtr parent;
+ WindowPtr firstChild;
+ WindowPtr * ppLayerWin;
+
+</programlisting></blockquote>
+This formerly dix function MarkWindow has moved to ddx and is accessed
+via this screen function. In the process, it has grown another
+parameter: ppLayerWin, which is filled in with a pointer to the window
+at which save under marking and ValidateTree should begin. In the
+single-layered framebuffer case, pLayerWin == pWin.</para>
+<para>
+<blockquote><programlisting>
+
+ Bool pScreen->ChangeSaveUnder(pLayerWin, firstChild)
+ WindowPtr pLayerWin;
+ WindowPtr firstChild;
+
+</programlisting></blockquote>
+The dix functions ChangeSaveUnder and CheckSaveUnder have moved to ddx and
+are accessed via this screen function. pLayerWin should be the window
+returned in the ppLayerWin parameter of MarkOverlappedWindows. The function
+may turn on backing store for windows that might be covered, and may partially
+turn off backing store for windows. It returns TRUE if PostChangeSaveUnder
+needs to be called to finish turning off backing store.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->PostChangeSaveUnder(pLayerWin, firstChild)
+ WindowPtr pLayerWin;
+ WindowPtr firstChild;
+
+</programlisting></blockquote>
+The dix function DoChangeSaveUnder has moved to ddx and is accessed via
+this screen function. This function completes the job of turning off
+backing store that was started by ChangeSaveUnder.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->MoveWindow(pWin, x, y, pSib, kind)
+ WindowPtr pWin;
+ int x;
+ int y;
+ WindowPtr pSib;
+ VTKind kind;
+
+</programlisting></blockquote>
+The formerly dix function MoveWindow has moved to ddx and is accessed via
+this screen function. The new position of the window is given by
+x,y. kind is VTMove if the window is only moving, or VTOther if
+the border is also changing.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->ResizeWindow(pWin, x, y, w, h, pSib)
+ WindowPtr pWin;
+ int x;
+ int y;
+ unsigned int w;
+ unsigned int h;
+ WindowPtr pSib;
+
+</programlisting></blockquote>
+The formerly dix function SlideAndSizeWindow has moved to ddx and is accessed via
+this screen function. The new position is given by x,y. The new size
+is given by w,h.</para>
+<para>
+<blockquote><programlisting>
+
+ WindowPtr pScreen->GetLayerWindow(pWin)
+ WindowPtr pWin
+
+</programlisting></blockquote>
+This is a new function which returns a child of the layer parent of pWin.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->HandleExposures(pWin)
+ WindowPtr pWin;
+
+</programlisting></blockquote>
+The formerly dix function HandleExposures has moved to ddx and is accessed via
+this screen function. This function is called after ValidateTree and
+uses the information contained in valdata to send exposures to windows.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->ReparentWindow(pWin, pPriorParent)
+ WindowPtr pWin;
+ WindowPtr pPriorParent;
+
+</programlisting></blockquote>
+This function will be called when a window is reparented. At the time of
+the call, pWin will already be spliced into its new position in the
+window tree, and pPriorParent is its previous parent. This function
+can be NULL.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->SetShape(pWin)
+ WindowPtr pWin;
+
+</programlisting></blockquote>
+The formerly dix function SetShape has moved to ddx and is accessed via
+this screen function. The window's new shape will have already been
+stored in the window when this function is called.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->ChangeBorderWidth(pWin, width)
+ WindowPtr pWin;
+ unsigned int width;
+
+</programlisting></blockquote>
+The formerly dix function ChangeBorderWidth has moved to ddx and is accessed via
+this screen function. The new border width is given by width.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->MarkUnrealizedWindow(pChild, pWin, fromConfigure)
+ WindowPtr pChild;
+ WindowPtr pWin;
+ Bool fromConfigure;
+
+</programlisting></blockquote>
+This function is called for windows that are being unrealized as part of
+an UnrealizeTree. pChild is the window being unrealized, pWin is an
+ancestor, and the fromConfigure value is simply propogated from UnrealizeTree.</para>
+</section>
+</section>
+</section>
+<section>
+<title>Graphics Contexts and Validation</title>
+<para>
+This graphics context (GC) contains state variables such as foreground and
+background pixel value (color), the current line style and width,
+the current tile or stipple for pattern generation, the current font for text
+generation, and other similar attributes.</para>
+<para>
+In many graphics systems, the equivalent of the graphics context and the
+drawable are combined as one entity.
+The main distinction between the two kinds of status is that a drawable
+describes a writing surface and the writings that may have already been done
+on it, whereas a graphics context describes the drawing process.
+A drawable is like a chalkboard.
+A GC is like a piece of chalk.</para>
+<para>
+Unlike many similar systems, there is no "current pen location."
+Every graphic operation is accompanied by the coordinates where it is to happen.</para>
+<para>
+The GC also includes two vectors of procedure pointers, the first
+operate on the GC itself and are called GC funcs. The second, called
+GC ops,
+contains the functions that carry out the fundamental graphic operations
+such as drawing lines, polygons, arcs, text, and copying bitmaps.
+The DDX graphic software can, if it
+wants to be smart, change these two vectors of procedure pointers
+to take advantage of hardware/firmware in the server machine, which can do
+a better job under certain circumstances. To reduce the amount of memory
+consumed by each GC, it is wise to create a few "boilerplate" GC ops vectors
+which can be shared by every GC which matches the constraints for that set.
+Also, it is usually reasonable to have every GC created by a particular
+module to share a common set of GC funcs. Samples of this sort of
+sharing can be seen in fb/fbgc.c.</para>
+<para>
+The DDX software is notified any time the client (or DIX) uses a changed GC.
+For instance, if the hardware has special support for drawing fixed-width
+fonts, DDX can intercept changes to the current font in a GC just before
+drawing is done. It can plug into either a fixed-width procedure that makes
+the hardware draw characters, or a variable-width procedure that carefully
+lays out glyphs by hand in software, depending upon the new font that is
+selected.</para>
+<para>
+A definition of these structures can be found in the file
+Xserver/include/gcstruct.h.</para>
+<para>
+Also included in each GC is support for dynamic devPrivates, which the
+DDX can use for any purpose (see <xref linkend="wrappers_and_privates"/> below).</para>
+<para>
+The DIX routines available for manipulating GCs are
+CreateGC, ChangeGC, CopyGC, SetClipRects, SetDashes, and FreeGC.
+<blockquote><programlisting>
+
+ GCPtr CreateGC(pDrawable, mask, pval, pStatus)
+ DrawablePtr pDrawable;
+ BITS32 mask;
+ XID *pval;
+ int *pStatus;
+
+ int ChangeGC(pGC, mask, pval)
+ GCPtr pGC;
+ BITS32 mask;
+ XID *pval;
+
+ int CopyGC(pgcSrc, pgcDst, mask)
+ GCPtr pgcSrc;
+ GCPtr pgcDst;
+ BITS32 mask;
+
+ int SetClipRects(pGC, xOrigin, yOrigin, nrects, prects, ordering)
+ GCPtr pGC;
+ int xOrigin, yOrigin;
+ int nrects;
+ xRectangle *prects;
+ int ordering;
+
+ SetDashes(pGC, offset, ndash, pdash)
+ GCPtr pGC;
+ unsigned offset;
+ unsigned ndash;
+ unsigned char *pdash;
+
+ int FreeGC(pGC, gid)
+ GCPtr pGC;
+ GContext gid;
+
+</programlisting></blockquote>
+</para>
+<para>
+As a convenience, each Screen structure contains an array of
+GCs that are preallocated, one at each depth the screen supports.
+These are particularly useful in the mi code. Two DIX routines
+must be used to get these GCs:
+<blockquote><programlisting>
+
+ GCPtr GetScratchGC(depth, pScreen)
+ int depth;
+ ScreenPtr pScreen;
+
+ FreeScratchGC(pGC)
+ GCPtr pGC;
+
+</programlisting></blockquote>
+Always use these two routines, don't try to extract the scratch
+GC yourself -- someone else might be using it, so a new one must
+be created on the fly.</para>
+<para>
+If you need a GC for a very long time, say until the server is restarted,
+you should not take one from the pool used by GetScratchGC, but should
+get your own using CreateGC or CreateScratchGC.
+This leaves the ones in the pool free for routines that only need it for
+a little while and don't want to pay a heavy cost to get it.
+<blockquote><programlisting>
+
+ GCPtr CreateScratchGC(pScreen, depth)
+ ScreenPtr pScreen;
+ int depth;
+
+</programlisting></blockquote>
+NULL is returned if the GC cannot be created.
+The GC returned can be freed with FreeScratchGC.</para>
+<section>
+ <title>Details of Operation</title>
+<para>
+At screen initialization, a screen must supply a GC creation procedure.
+At GC creation, the screen must fill in GC funcs and GC ops vectors
+(Xserver/include/gcstruct.h). For any particular GC, the func vector
+must remain constant, while the op vector may vary. This invariant is to
+ensure that Wrappers work correctly.</para>
+<para>
+When a client request is processed that results in a change
+to the GC, the device-independent state of the GC is updated.
+This includes a record of the state that changed.
+Then the ChangeGC GC func is called.
+This is useful for graphics subsystems that are able to process
+state changes in parallel with the server CPU.
+DDX may opt not to take any action at GC-modify time.
+This is more efficient if multiple GC-modify requests occur
+between draws using a given GC.</para>
+<para>
+Validation occurs at the first draw operation that specifies the GC after
+that GC was modified. DIX calls then the ValidateGC GC func. DDX should
+then update its internal state. DDX internal state may be stored as one or
+more of the following: 1) device private block on the GC; 2) hardware
+state; 3) changes to the GC ops.</para>
+<para>
+The GC contains a serial number, which is loaded with a number fetched from
+the window that was drawn into the last time the GC was used. The serial
+number in the drawable is changed when the drawable's
+clipList or absCorner changes. Thus, by
+comparing the GC serial number with the drawable serial number, DIX can
+force a validate if the drawable has been changed since the last time it
+was used with this GC.</para>
+<para>
+In addition, the drawable serial number is always guaranteed to have the
+most significant bit set to 0. Thus, the DDX layer can set the most
+significant bit of the serial number to 1 in a GC to force a validate the next time
+the GC is used. DIX also uses this technique to indicate that a change has
+been made to the GC by way of a SetGC, a SetDashes or a SetClip request.</para>
+</section>
+<section>
+ <title>GC Handling Routines</title>
+<para>
+The ScreenRec data structure has a pointer for
+CreateGC().
+<blockquote><programlisting>
+
+ Bool pScreen->CreateGC(pGC)
+ GCPtr pGC;
+</programlisting></blockquote>
+This routine must fill in the fields of
+a dynamically allocated GC that is passed in.
+It does NOT allocate the GC record itself or fill
+in the defaults; DIX does that.</para>
+<para>
+This must fill in both the GC funcs and ops; none of the drawing
+functions will be called before the GC has been validated,
+but the others (dealing with allocating of clip regions,
+changing and destroying the GC, etc.) might be.</para>
+<para>
+The GC funcs vector contains pointers to 7
+routines and a devPrivate field:
+<blockquote><programlisting>
+
+ pGC->funcs->ChangeGC(pGC, changes)
+ GCPtr pGC;
+ unsigned long changes;
+
+</programlisting></blockquote>
+This GC func is called immediately after a field in the GC is changed.
+changes is a bit mask indicating the changed fields of the GC in this
+request.</para>
+<para>
+The ChangeGC routine is useful if you have a system where
+state-changes to the GC can be swallowed immediately by your graphics
+system, and a validate is not necessary.</para>
+<para>
+<blockquote><programlisting>
+
+ pGC->funcs->ValidateGC(pGC, changes, pDraw)
+ GCPtr pGC;
+ unsigned long changes;
+ DrawablePtr pDraw;
+
+</programlisting></blockquote>
+ValidateGC is called by DIX just before the GC will be used when one
+of many possible changes to the GC or the graphics system has
+happened. It can modify devPrivates data attached to the GC,
+change the op vector, or change hardware according to the
+values in the GC. It may not change the device-independent portion of
+the GC itself.</para>
+<para>
+In almost all cases, your ValidateGC() procedure should take the
+regions that drawing needs to be clipped to and combine them into a
+composite clip region, which you keep a pointer to in the private part
+of the GC. In this way, your drawing primitive routines (and whatever
+is below them) can easily determine what to clip and where. You
+should combine the regions clientClip (the region that the client
+desires to clip output to) and the region returned by
+NotClippedByChildren(), in DIX. An example is in Xserver/fb/fbgc.c.</para>
+<para>
+Some kinds of extension software may cause this routine to be called
+more than originally intended; you should not rely on algorithms that
+will break under such circumstances.</para>
+<para>
+See the Strategies document for more information on creatively using
+this routine.</para>
+<para>
+<blockquote><programlisting>
+
+ pGC->funcs->CopyGC(pGCSrc, mask, pGCDst)
+ GCPtr pGCSrc;
+ unsigned long mask;
+ GCPtr pGCDst;
+
+</programlisting></blockquote>
+This routine is called by DIX when a GC is being copied to another GC.
+This is for situations where dynamically allocated chunks of memory
+are stored in the GC's dynamic devPrivates and need to be transferred to
+the destination GC.</para>
+<para>
+<blockquote><programlisting>
+
+ pGC->funcs->DestroyGC(pGC)
+ GCPtr pGC;
+
+</programlisting></blockquote>
+This routine is called before the GC is destroyed for the
+entity interested in this GC to clean up after itself.
+This routine is responsible for freeing any auxiliary storage allocated.</para>
+</section>
+<section>
+ <title>GC Clip Region Routines</title>
+<para>
+The GC clientClip field requires three procedures to manage it. These
+procedures are in the GC funcs vector. The underlying principle is that dix
+knows nothing about the internals of the clipping information, (except when
+it has come from the client), and so calls ddX whenever it needs to copy,
+set, or destroy such information. It could have been possible for dix not
+to allow ddX to touch the field in the GC, and require it to keep its own
+copy in devPriv, but since clip masks can be very large, this seems like a
+bad idea. Thus, the server allows ddX to do whatever it wants to the
+clientClip field of the GC, but requires it to do all manipulation itself.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->funcs->ChangeClip(pGC, type, pValue, nrects)
+ GCPtr pGC;
+ int type;
+ char *pValue;
+ int nrects;
+
+</programlisting></blockquote>
+This routine is called whenever the client changes the client clip
+region. The pGC points to the GC involved, the type tells what form
+the region has been sent in. If type is CT_NONE, then there is no
+client clip. If type is CT_UNSORTED, CT_YBANDED or CT_YXBANDED, then
+pValue pointer to a list of rectangles, nrects long. If type is
+CT_REGION, then pValue pointer to a RegionRec from the mi region code.
+If type is CT_PIXMAP pValue is a pointer to a pixmap. (The defines
+for CT_NONE, etc. are in Xserver/include/gc.h.) This routine is
+responsible for incrementing any necessary reference counts (e.g. for
+a pixmap clip mask) for the new clipmask and freeing anything that
+used to be in the GC's clipMask field. The lists of rectangles passed
+in can be freed with Xfree(), the regions can be destroyed with the
+RegionDestroy field in the screen, and pixmaps can be destroyed by
+calling the screen's DestroyPixmap function. DIX and MI code expect
+what they pass in to this to be freed or otherwise inaccessible, and
+will never look inside what's been put in the GC. This is a good
+place to be wary of storage leaks.</para>
+<para>
+In the sample server, this routine transforms either the bitmap or the
+rectangle list into a region, so that future routines will have a more
+predictable starting point to work from. (The validate routine must
+take this client clip region and merge it with other regions to arrive
+at a composite clip region before any drawing is done.)</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->funcs->DestroyClip(pGC)
+ GCPtr pGC;
+
+</programlisting></blockquote>
+This routine is called whenever the client clip region must be destroyed.
+The pGC points to the GC involved. This call should set the clipType
+field of the GC to CT_NONE.
+In the sample server, the pointer to the client clip region is set to NULL
+by this routine after destroying the region, so that other software
+(including ChangeClip() above) will recognize that there is no client clip region.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->funcs->CopyClip(pgcDst, pgcSrc)
+ GCPtr pgcDst, pgcSrc;
+
+</programlisting></blockquote>
+This routine makes a copy of the clipMask and clipType from pgcSrc
+into pgcDst. It is responsible for destroying any previous clipMask
+in pgcDst. The clip mask in the source can be the same as the
+clip mask in the dst (clients do the strangest things), so care must
+be taken when destroying things. This call is required because dix
+does not know how to copy the clip mask from pgcSrc.</para>
+</section>
+</section>
+<section>
+ <title>Drawing Primitives</title>
+<para>
+The X protocol (rules for the byte stream that goes between client and server)
+does all graphics using primitive
+operations, which are called Drawing Primitives.
+These include line drawing, area filling, arcs, and text drawing.
+Your implementation must supply 16 routines
+to perform these on your hardware.
+(The number 16 is arbitrary.)</para>
+<para>
+More specifically, 16 procedure pointers are in each
+GC op vector.
+At any given time, ALL of them MUST point to a valid procedure that
+attempts to do the operation assigned, although
+the procedure pointers may change and may
+point to different procedures to carry out the same operation.
+A simple server will leave them all pointing to the same 16 routines, while
+a more optimized implementation will switch each from one
+procedure to another, depending upon what is most optimal
+for the current GC and drawable.</para>
+<para>
+The sample server contains a considerable chunk of code called the
+mi (machine independent)
+routines, which serve as drawing primitive routines.
+Many server implementations will be able to use these as-is,
+because they work for arbitrary depths.
+They make no assumptions about the formats of pixmaps
+and frame buffers, since they call a set of routines
+known as the "Pixblit Routines" (see next section).
+They do assume that the way to draw is
+through these low-level routines that apply pixel values rows at a time.
+If your hardware or firmware gives more performance when
+things are done differently, you will want to take this fact into account
+and rewrite some or all of the drawing primitives to fit your needs.</para>
+<section>
+ <title>GC Components</title>
+<para>
+This section describes the fields in the GC that affect each drawing primitive.
+The only primitive that is not affected is GetImage, which does not use a GC
+because its destination is a protocol-style bit image.
+Since each drawing primitive mirrors exactly the X protocol request of the
+same name, you should refer to the X protocol specification document
+for more details.</para>
+<para>
+ALL of these routines MUST CLIP to the
+appropriate regions in the drawable.
+Since there are many regions to clip to simultaneously,
+your ValidateGC routine should combine these into a unified
+clip region to which your drawing routines can quickly refer.
+This is exactly what the fb routines supplied with the sample server
+do.
+The mi implementation passes responsibility for clipping while drawing
+down to the Pixblit routines.</para>
+<para>
+Also, all of them must adhere to the current plane mask.
+The plane mask has one bit for every bit plane in the drawable;
+only planes with 1 bits in the mask are affected by any drawing operation.</para>
+<para>
+All functions except for ImageText calls must obey the alu function.
+This is usually Copy, but could be any of the allowable 16 raster-ops.</para>
+<para>
+All of the functions, except for CopyArea, might use the current
+foreground and background pixel values.
+Each pixel value is 32 bits.
+These correspond to foreground and background colors, but you have
+to run them through the colormap to find out what color the pixel values
+represent. Do not worry about the color, just apply the pixel value.</para>
+<para>
+The routines that draw lines (PolyLine, PolySegment, PolyRect, and PolyArc)
+use the line width, line style, cap style, and join style.
+Line width is in pixels.
+The line style specifies whether it is solid or dashed, and what kind of dash.
+The cap style specifies whether Rounded, Butt, etc.
+The join style specifies whether joins between joined lines are Miter, Round or Beveled.
+When lines cross as part of the same polyline, they are assumed to be drawn once.
+(See the X protocol specification for more details.)</para>
+<para>
+Zero-width lines are NOT meant to be really zero width; this is the client's way
+of telling you that you can optimize line drawing with little regard to
+the end caps and joins.
+They are called "thin" lines and are meant to be one pixel wide.
+These are frequently done in hardware or in a streamlined assembly language
+routine.</para>
+<para>
+Lines with widths greater than zero, though, must all be drawn with the same
+algorithm, because client software assumes that every jag on every
+line at an angle will come at the same place.
+Two lines that should have
+one pixel in the space between them
+(because of their distance apart and their widths) should have such a one-pixel line
+of space between them if drawn, regardless of angle.</para>
+<para>
+The solid area fill routines (FillPolygon, PolyFillRect, PolyFillArc)
+all use the fill rule, which specifies subtle interpretations of
+what points are inside and what are outside of a given polygon.
+The PolyFillArc routine also uses the arc mode, which specifies
+whether to fill pie segments or single-edge slices of an ellipse.</para>
+<para>
+The line drawing, area fill, and PolyText routines must all
+apply the correct "fill style."
+This can be either a solid foreground color, a transparent stipple,
+an opaque stipple, or a tile.
+Stipples are bitmaps where the 1 bits represent that the foreground color is written,
+and 0 bits represent that either the pixel is left alone (transparent) or that
+the background color is written (opaque).
+A tile is a pixmap of the full depth of the GC that is applied in its full glory to all areas.
+The stipple and tile patterns can be any rectangular size, although some implementations
+will be faster for certain sizes such as 8x8 or 32x32.
+The mi implementation passes this responsibility down to the Pixblit routines.</para>
+<para>
+See the X protocol document for full details.
+The description of the CreateGC request has a very good, detailed description of these
+attributes.</para>
+</section>
+<section>
+<title>The Primitives</title>
+<para>
+The Drawing Primitives are as follows:
+
+<blockquote><programlisting>
+
+ RegionPtr pGC->ops->CopyArea(src, dst, pGC, srcx, srcy, w, h, dstx, dsty)
+ DrawablePtr dst, src;
+ GCPtr pGC;
+ int srcx, srcy, w, h, dstx, dsty;
+
+</programlisting></blockquote>
+CopyArea copies a rectangle of pixels from one drawable to another of
+the same depth. To effect scrolling, this must be able to copy from
+any drawable to itself, overlapped. No squeezing or stretching is done
+because the source and destination are the same size. However,
+everything is still clipped to the clip regions of the destination
+drawable.</para>
+<para>
+If pGC->graphicsExposures is True, any portions of the destination which
+were not valid in the source (either occluded by covering windows, or
+outside the bounds of the drawable) should be collected together and
+returned as a region (if this resultant region is empty, NULL can be
+returned instead). Furthermore, the invalid bits of the source are
+not copied to the destination and (when the destination is a window)
+are filled with the background tile. The sample routine
+miHandleExposures generates the appropriate return value and fills the
+invalid area using pScreen->PaintWindowBackground.</para>
+<para>
+For instance, imagine a window that is partially obscured by other
+windows in front of it. As text is scrolled on your window, the pixels
+that are scrolled out from under obscuring windows will not be
+available on the screen to copy to the right places, and so an exposure
+event must be sent for the client to correctly repaint them. Of
+course, if you implement backing store, you could do this without resorting
+to exposure events.</para>
+<para>
+An example implementation is fbCopyArea() in Xserver/fb/fbcopy.c.</para>
+<para>
+<blockquote><programlisting>
+
+ RegionPtr pGC->ops->CopyPlane(src, dst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
+ DrawablePtr dst, src;
+ GCPtr pGC;
+ int srcx, srcy, w, h, dstx, dsty;
+ unsigned long plane;
+
+</programlisting></blockquote>
+CopyPlane must copy one plane of a rectangle from the source drawable
+onto the destination drawable. Because this routine only copies one
+bit out of each pixel, it can copy between drawables of different
+depths. This is the only way of copying between drawables of
+different depths, except for copying bitmaps to pixmaps and applying
+foreground and background colors to it. All other conditions of
+CopyArea apply to CopyPlane too.</para>
+<para>
+An example implementation is fbCopyPlane() in
+Xserver/fb/fbcopy.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->PolyPoint(dst, pGC, mode, n, pPoint)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int mode;
+ int n;
+ DDXPointPtr pPoint;
+
+</programlisting></blockquote>
+PolyPoint draws a set of one-pixel dots (foreground color)
+at the locations given in the array.
+mode is one of the defined constants Origin (absolute coordinates) or Previous
+(each coordinate is relative to the last).
+Note that this does not use the background color or any tiles or stipples.</para>
+<para>
+Example implementations are fbPolyPoint() in Xserver/fb/fbpoint.c and
+miPolyPoint in Xserver/mi/mipolypnt.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->Polylines(dst, pGC, mode, n, pPoint)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int mode;
+ int n;
+ DDXPointPtr pPoint;
+
+</programlisting></blockquote>
+Similar to PolyPoint, Polylines draws lines between the locations given in the array.
+Zero-width lines are NOT meant to be really zero width; this is the client's way of
+telling you that you can maximally optimize line drawing with little regard to
+the end caps and joins.
+mode is one of the defined constants Previous or Origin, depending upon
+whether the points are each relative to the last or are absolute.</para>
+<para>
+Example implementations are miWideLine() and miWideDash() in
+mi/miwideline.c and miZeroLine() in mi/mizerline.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->PolySegment(dst, pGC, n, pPoint)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int n;
+ xSegment *pSegments;
+
+</programlisting></blockquote>
+PolySegments draws unconnected
+lines between pairs of points in the array; the array must be of
+even size; no interconnecting lines are drawn.</para>
+<para>
+An example implementation is miPolySegment() in mipolyseg.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->PolyRectangle(dst, pGC, n, pRect)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int n;
+ xRectangle *pRect;
+
+</programlisting></blockquote>
+PolyRectangle draws outlines of rectangles for each rectangle in the array.</para>
+<para>
+An example implementation is miPolyRectangle() in Xserver/mi/mipolyrect.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->PolyArc(dst, pGC, n, pArc)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int n;
+ xArc*pArc;
+
+</programlisting></blockquote>
+PolyArc draws connected conic arcs according to the descriptions in the array.
+See the protocol specification for more details.</para>
+<para>
+Example implementations are miZeroPolyArc in Xserver/mi/mizerarc. and
+miPolyArc() in Xserver/mi/miarc.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pPoint)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int shape;
+ int mode;
+ int count;
+ DDXPointPtr pPoint;
+
+</programlisting></blockquote>
+FillPolygon fills a polygon specified by the points in the array
+with the appropriate fill style.
+If necessary, an extra border line is assumed between the starting and ending lines.
+The shape can be used as a hint
+to optimize filling; it indicates whether it is convex (all interior angles
+less than 180), nonconvex (some interior angles greater than 180 but
+border does not cross itself), or complex (border crosses itself).
+You can choose appropriate algorithms or hardware based upon mode.
+mode is one of the defined constants Previous or Origin, depending upon
+whether the points are each relative to the last or are absolute.</para>
+<para>
+An example implementation is miFillPolygon() in Xserver/mi/mipoly.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->PolyFillRect(dst, pGC, n, pRect)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int n;
+ xRectangle *pRect;
+
+</programlisting></blockquote>
+PolyFillRect fills multiple rectangles.</para>
+<para>
+Example implementations are fbPolyFillRect() in Xserver/fb/fbfillrect.c and
+miPolyFillRect() in Xserver/mi/mifillrct.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->PolyFillArc(dst, pGC, n, pArc)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int n;
+ xArc *pArc;
+
+</programlisting></blockquote>
+PolyFillArc fills a shape for each arc in the
+list that is bounded by the arc and one or two
+line segments with the current fill style.</para>
+<para>
+An example implementation is miPolyFillArc() in Xserver/mi/mifillarc.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBinImage)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int x, y, w, h;
+ int format;
+ char *pBinImage;
+
+</programlisting></blockquote>
+PutImage copies a pixmap image into the drawable. The pixmap image
+must be in X protocol format (either Bitmap, XYPixmap, or ZPixmap),
+and format tells the format. (See the X protocol specification for
+details on these formats). You must be able to accept all three
+formats, because the client gets to decide which format to send.
+Either the drawable and the pixmap image have the same depth, or the
+source pixmap image must be a Bitmap. If a Bitmap, the foreground and
+background colors will be applied to the destination.</para>
+<para>
+An example implementation is fbPutImage() in Xserver/fb/fbimage.c.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->GetImage(src, x, y, w, h, format, planeMask, pBinImage)
+ DrawablePtr src;
+ int x, y, w, h;
+ unsigned int format;
+ unsigned long planeMask;
+ char *pBinImage;
+
+</programlisting></blockquote>
+GetImage copies the bits from the source drawable into
+the destination pointer. The bits are written into the buffer
+according to the server-defined pixmap padding rules.
+pBinImage is guaranteed to be big enough to hold all
+the bits that must be written.</para>
+<para>
+This routine does not correspond exactly to the X protocol GetImage
+request, since DIX has to break the reply up into buffers of a size
+requested by the transport layer. If format is ZPixmap, the bits are
+written in the ZFormat for the depth of the drawable; if there is a 0
+bit in the planeMask for a particular plane, all pixels must have the
+bit in that plane equal to 0. If format is XYPixmap, planemask is
+guaranteed to have a single bit set; the bits should be written in
+Bitmap format, which is the format for a single plane of an XYPixmap.</para>
+<para>
+An example implementation is miGetImage() in Xserver/mi/mibitblt.c.
+<blockquote><programlisting>
+
+ void pGC->ops->ImageText8(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+
+</programlisting></blockquote>
+ImageText8 draws text. The text is drawn in the foreground color; the
+background color fills the remainder of the character rectangles. The
+coordinates specify the baseline and start of the text.</para>
+<para>
+An example implementation is miImageText8() in Xserver/mi/mipolytext.c.</para>
+<para>
+<blockquote><programlisting>
+
+ int pGC->ops->PolyText8(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+
+</programlisting></blockquote>
+PolyText8 works like ImageText8, except it draws with
+the current fill style for special effects such as
+shaded text.
+See the X protocol specification for more details.</para>
+<para>
+An example implementation is miPolyText8() in Xserver/mi/mipolytext.c.</para>
+<para>
+<blockquote><programlisting>
+
+ int pGC->ops->PolyText16(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+
+ void pGC->ops->ImageText16(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+
+</programlisting></blockquote>
+These two routines are the same as the "8" versions,
+except that they are for 16-bit character codes (useful
+for oriental writing systems).</para>
+<para>
+The primary difference is in the way the character information is
+looked up. The 8-bit and the 16-bit versions obviously have different
+kinds of character values to look up; the main goal of the lookup is
+to provide a pointer to the CharInfo structs for the characters to
+draw and to pass these pointers to the Glyph routines. Given a
+CharInfo struct, lower-level software can draw the glyph desired with
+little concern for other characteristics of the font.</para>
+<para>
+16-bit character fonts have a row-and-column scheme, where the 2bytes
+of the character code constitute the row and column in a square matrix
+of CharInfo structs. Each font has row and column minimum and maximum
+values; the CharInfo structures form a two-dimensional matrix.</para>
+<para>
+Example implementations are miPolyText16() and
+miImageText16() in Xserver/mi/mipolytext.c.</para>
+<para>
+See the X protocol specification for more details on these graphic operations.</para>
+<para>
+There is a hook in the GC ops, called LineHelper, that used to be used in the
+sample implementation by the code for wide lines. It no longer servers any
+purpose in the sample servers, but still exists, #ifdef'ed by NEED_LINEHELPER,
+in case someone needs it.</para>
+</section>
+</section>
+<section>
+ <title>Pixblit Procedures</title>
+<para>
+The Drawing Primitive functions must be defined for your server.
+One possible way to do this is to use the mi routines from the sample server.
+If you choose to use the mi routines (even part of them!) you must implement
+these Pixblit routines.
+These routines read and write pixel values
+and deal directly with the image data.</para>
+<para>
+The Pixblit routines for the sample server are part of the "fb"
+routines. As with the mi routines, the fb routines are
+portable but are not as portable as the mi routines.</para>
+<para>
+The fb subsystem is a depth-independent framebuffer core, capable of
+operating at any depth from 1 to 32, based on the depth of the window
+or pixmap it is currently operating on. In particular, this means it
+can support pixmaps of multiple depths on the same screen. It supplies
+both Pixblit routines and higher-level optimized implementations of the
+Drawing Primitive routines. It does make the assumption that the pixel
+data it touches is available in the server's address space.</para>
+<para>
+In other words, if you have a "normal" frame buffer type display, you
+can probably use the fb code, and the mi code. If you
+have a stranger hardware, you will have to supply your own Pixblit
+routines, but you can use the mi routines on top of them. If you have
+better ways of doing some of the Drawing Primitive functions, then you
+may want to supply some of your own Drawing Primitive routines. (Even
+people who write their own Drawing Primitives save at least some of
+the mi code for certain special cases that their hardware or library
+or fancy algorithm does not handle.)</para>
+<para>
+The client, DIX, and the machine-independent routines do not carry the
+final responsibility of clipping. They all depend upon the Pixblit
+routines to do their clipping for them. The rule is, if you touch the
+frame buffer, you clip.</para>
+<para>
+(The higher level routines may decide to clip at a high level, but
+this is only for increased performance and cannot substitute for
+bottom-level clipping. For instance, the mi routines, DIX, or the
+client may decide to check all character strings to be drawn and chop
+off all characters that would not be displayed. If so, it must retain
+the character on the edge that is partly displayed so that the Pixblit
+routines can clip off precisely at the right place.)</para>
+<para>
+To make this easier, all of the reasons to clip can be combined into
+one region in your ValidateGC procedure. You take this composite clip
+region with you into the Pixblit routines. (The sample server does
+this.)</para>
+<para>
+Also, FillSpans() has to apply tile and stipple patterns. The
+patterns are all aligned to the window origin so that when two people
+write patches that are contiguous, they will merge nicely. (Really,
+they are aligned to the patOrg point in the GC. This defaults to (0,
+0) but can be set by the client to anything.)</para>
+<para>
+However, the mi routines can translate (relocate) the points from
+window-relative to screen-relative if desired. If you set the
+miTranslate field in the GC (set it in the CreateGC or ValidateGC
+routine), then the mi output routines will translate all coordinates.
+If it is false, then the coordinates will be passed window-relative.
+Screens with no hardware translation will probably set miTranslate to
+TRUE, so that geometry (e.g. polygons, rectangles) can be translated,
+rather than having the resulting list of scanlines translated; this is
+good because the list vertices in a drawing request will generally be
+much smaller than the list of scanlines it produces. Similarly,
+hardware that does translation can set miTranslate to FALSE, and avoid
+the extra addition per vertex, which can be (but is not always)
+important for getting the highest possible performance. (Contrast the
+behavior of GetSpans, which is not expected to be called as often, and
+so has different constraints.) The miTranslate field is settable in
+each GC, if , for example, you are mixing several kinds of
+destinations (offscreen pixmaps, main memory pixmaps, backing store,
+and windows), all of which have different requirements, on one screen.</para>
+<para>
+As with other drawing routines, there are fields in the GC to direct
+higher code to the correct routine to execute for each function. In
+this way, you can optimize for special cases, for example, drawing
+solids versus drawing stipples.</para>
+<para>
+The Pixblit routines are broken up into three sets. The Span routines
+simply fill in rows of pixels. The Glyph routines fill in character
+glyphs. The PushPixels routine is a three-input bitblt for more
+sophisticated image creation.</para>
+<para>
+It turns out that the Glyph and PushPixels routines actually have a
+machine-independent implementation that depends upon the Span
+routines. If you are really pressed for time, you can use these
+versions, although they are quite slow.</para>
+<section>
+<title>Span Routines</title>
+<para>
+For these routines, all graphic operations have been reduced to "spans."
+A span is a horizontal row of pixels.
+If you can design these routines which write into and read from
+rows of pixels at a time, you can use the mi routines.</para>
+<para>
+Each routine takes
+a destination drawable to draw into, a GC to use while drawing,
+the number of spans to do, and two pointers to arrays that indicate the list
+of starting points and the list of widths of spans.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->FillSpans(dst, pGC, nSpans, pPoints, pWidths, sorted)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int nSpans;
+ DDXPointPtr pPoints;
+ int *pWidths;
+ int sorted;
+
+</programlisting></blockquote>
+FillSpans should fill horizontal rows of pixels with
+the appropriate patterns, stipples, etc.,
+based on the values in the GC.
+The starting points are in the array at pPoints; the widths are in pWidths.
+If sorted is true, the scan lines are in increasing y order, in which case
+you may be able to make assumptions and optimizations.</para>
+<para>
+GC components: alu, clipOrg, clientClip, and fillStyle.</para>
+<para>
+GC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
+(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
+and stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->SetSpans(pDrawable, pGC, pSrc, ppt, pWidths, nSpans, sorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ char *pSrc;
+ DDXPointPtr pPoints;
+ int *pWidths;
+ int nSpans;
+ int sorted;
+
+</programlisting></blockquote>
+For each span, this routine should copy pWidths bits from pSrc to
+pDrawable at pPoints using the raster-op from the GC.
+If sorted is true, the scan lines are in increasing y order.
+The pixels in pSrc are
+padded according to the screen's padding rules.
+These
+can be used to support
+interesting extension libraries, for example, shaded primitives. It does not
+use the tile and stipple.</para>
+<para>
+GC components: alu, clipOrg, and clientClip</para>
+<para>
+The above functions are expected to handle all modifiers in the current
+GC. Therefore, it is expedient to have
+different routines to quickly handle common special cases
+and reload the procedure pointers
+at validate time, as with the other output functions.</para>
+<para>
+<blockquote><programlisting>
+
+ void pScreen->GetSpans(pDrawable, wMax, pPoints, pWidths, nSpans)
+ DrawablePtr pDrawable;
+ int wMax;
+ DDXPointPtr pPoints;
+ int *pWidths;
+ int nSpans;
+ char *pDst;
+
+</programlisting></blockquote>
+For each span, GetSpans gets bits from the drawable starting at pPoints
+and continuing for pWidths bits.
+Each scanline returned will be server-scanline padded.
+The routine can return NULL if memory cannot be allocated to hold the
+result.</para>
+<para>
+GetSpans never translates -- for a window, the coordinates are already
+screen-relative. Consider the case of hardware that doesn't do
+translation: the mi code that calls ddX will translate each shape
+(rectangle, polygon,. etc.) before scan-converting it, which requires
+many fewer additions that having GetSpans translate each span does.
+Conversely, consider hardware that does translate: it can set its
+translation point to (0, 0) and get each span, and the only penalty is
+the small number of additions required to translate each shape being
+scan-converted by the calling code. Contrast the behavior of
+FillSpans and SetSpans (discussed above under miTranslate), which are
+expected to be used more often.</para>
+<para>
+Thus, the penalty to hardware that does hardware translation is
+negligible, and code that wants to call GetSpans() is greatly
+simplified, both for extensions and the machine-independent core
+implementation.</para>
+<section>
+ <title>Glyph Routines</title>
+<para>
+The Glyph routines draw individual character glyphs for text drawing requests.</para>
+<para>
+You have a choice in implementing these routines. You can use the mi
+versions; they depend ultimately upon the span routines. Although
+text drawing will work, it will be very slow.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x , y;
+ unsigned int nglyph;
+ CharInfoRec **ppci; /* array of character info */
+ pointer unused; /* unused since R5 */
+
+</programlisting></blockquote>
+GC components: alu, clipOrg, clientClip, font, and fillStyle.</para>
+<para>
+GC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
+(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
+and stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x , y;
+ unsigned int nglyph;
+ CharInfoRec **ppci; /* array of character info */
+ pointer unused; /* unused since R5 */
+
+</programlisting></blockquote>
+GC components: clipOrg, clientClip, font, fgPixel, bgPixel</para>
+<para>
+These routines must copy the glyphs defined by the bitmaps in
+pglyphBase and the font metrics in ppci to the DrawablePtr, pDrawable.
+The poly routine follows all fill, stipple, and tile rules. The image
+routine simply blasts the glyph onto the glyph's rectangle, in
+foreground and background colors.</para>
+<para>
+More precisely, the Image routine fills the character rectangle with
+the background color, and then the glyph is applied in the foreground
+color. The glyph can extend outside of the character rectangle.
+ImageGlyph() is used for terminal emulators and informal text purposes
+such as button labels.</para>
+<para>
+The exact specification for the Poly routine is that the glyph is
+painted with the current fill style. The character rectangle is
+irrelevant for this operation. PolyText, at a higher level, includes
+facilities for font changes within strings and such; it is to be used
+for WYSIWYG word processing and similar systems.</para>
+<para>
+Both of these routines must clip themselves to the overall clipping region.</para>
+<para>
+Example implementations in mi are miPolyGlyphBlt() and
+miImageGlyphBlt() in Xserver/mi/miglblt.c.</para>
+</section>
+<section>
+<title>PushPixels routine</title>
+<para>
+The PushPixels routine writes the current fill style onto the drawable
+in a certain shape defined by a bitmap. PushPixels is equivalent to
+using a second stipple. You can thing of it as pushing the fillStyle
+through a stencil. PushPixels is not used by any of the mi rendering code,
+but is used by the mi software cursor code.
+<blockquote><para>
+ Suppose the stencil is: 00111100
+ and the stipple is: 10101010
+ PushPixels result: 00101000
+</para></blockquote>
+</para>
+<para>
+You have a choice in implementing this routine.
+You can use the mi version which depends ultimately upon FillSpans().
+Although it will work, it will be slow.</para>
+<para>
+<blockquote><programlisting>
+
+ void pGC->ops->PushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
+ GCPtr pGC;
+ PixmapPtr pBitMap;
+ DrawablePtr pDrawable;
+ int dx, dy, xOrg, yOrg;
+
+</programlisting></blockquote>
+GC components: alu, clipOrg, clientClip, and fillStyle.</para>
+<para>
+GC mode-dependent components: fgPixel (for fillStyle Solid); tile, patOrg
+(for fillStyle Tile); stipple, patOrg, fgPixel (for fillStyle Stipple);
+and stipple, patOrg, fgPixel and bgPixel (for fillStyle OpaqueStipple).</para>
+<para>
+PushPixels applys the foreground color, tile, or stipple from the pGC
+through a stencil onto pDrawable. pBitMap points to a stencil (of
+which we use an area dx wide by dy high), which is oriented over the
+drawable at xOrg, yOrg. Where there is a 1 bit in the bitmap, the
+destination is set according to the current fill style. Where there
+is a 0 bit in the bitmap, the destination is left the way it is.</para>
+<para>
+This routine must clip to the overall clipping region.</para>
+<para>
+An Example implementation is miPushPixels() in Xserver/mi/mipushpxl.c.</para>
+</section>
+</section>
+</section>
+<section>
+ <title>Shutdown Procedures</title>
+<para>
+<blockquote><programlisting>
+ void AbortDDX()
+ void ddxGiveUp()
+</programlisting></blockquote>
+Some hardware may require special work to be done before the server
+exits so that it is not left in an intermediate state. As explained
+in the OS layer, FatalError() will call AbortDDX() just before
+terminating the server. In addition, ddxGiveUp() will be called just
+before terminating the server on a "clean" death. What AbortDDX() and
+ddxGiveUP do is left unspecified, only that stubs must exist in the
+ddx layer. It is up to local implementors as to what they should
+accomplish before termination.</para>
+<section>
+ <title>Command Line Procedures</title>
+<para>
+<blockquote><programlisting>
+ int ddxProcessArgument(argc, argv, i)
+ int argc;
+ char *argv[];
+ int i;
+
+ void
+ ddxUseMsg()
+
+</programlisting></blockquote>
+You should write these routines to deal with device-dependent command line
+arguments. The routine ddxProcessArgument() is called with the command line,
+and the current index into argv; you should return zero if the argument
+is not a device-dependent one, and otherwise return a count of the number
+of elements of argv that are part of this one argument. For a typical
+option (e.g., "-realtime"), you should return the value one. This
+routine gets called before checks are made against device-independent
+arguments, so it is possible to peek at all arguments or to override
+device-independent argument processing. You can document the
+device-dependent arguments in ddxUseMsg(), which will be
+called from UseMsg() after printing out the device-independent arguments.</para>
+</section>
+</section>
+<section id="wrappers_and_privates">
+ <title>Wrappers and Privates</title>
+<para>
+Two new extensibility concepts have been developed for release 4, Wrappers
+and devPrivates. These replace the R3 GCInterest queues, which were not a
+general enough mechanism for many extensions and only provided hooks into a
+single data structure. devPrivates have been revised substantially for
+X.org X server relase 1.5.</para>
+<section>
+ <title>devPrivates</title>
+<para>
+devPrivates provides a way to attach arbitrary private data to various server structures.
+Any structure which contains a <structfield>devPrivates</structfield> field of
+type <type>PrivateRec</type> supports this mechanism. Private data can be allocated at
+any time during an object's life cycle and callbacks are available to initialize and clean
+up allocated space.</para>
+<para>
+To attach a piece of private data to an object, use:
+<blockquote><programlisting>
+ int dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
+</programlisting></blockquote>
+The first argument is the address of the <structfield>devPrivates</structfield> field
+in the target structure. This field is managed privately by the DIX layer and
+should not be directly modified. The second argument is some address value which
+will serve as the unique identifier for the private data. Typically this is the address
+of some global variable in your code. Only one piece of data with a given key can be attached to an object. However, you
+can use the same key to store data in any object that supports the devPrivates mechanism. The third
+argument is the value to store.</para>
+<para>
+If private data with the given key is already associated with the object, <function>dixSetPrivate</function> will
+overwrite the old value with the new one. Otherwise, new space will be allocated to hold the pointer value.
+The function returns <literal>TRUE</literal> unless memory allocation fails, but note that since memory allocation only
+occurs on the first reference to the private data, all subsequent calls are guaranteed to succeed.</para>
+
+<para>
+To look up a piece of private data, use one of:
+<blockquote><programlisting>
+ pointer dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
+ pointer *dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
+</programlisting></blockquote>
+The first argument is the address of the <structfield>devPrivates</structfield> field
+in the target structure. The second argument is the key to look up. If private data with the given key is already associated
+with the object, <function>dixLookupPrivate</function> will return the stored pointer value while <function>dixLookupPrivateAddr</function>
+will return the address of the stored pointer. Otherwise, new space will be first allocated to hold the pointer value
+and it will be initialized to NULL. Both functions return <literal>NULL</literal> if memory allocation fails, but note that
+since memory allocation only occurs on the first reference to the private data, all subsequent calls are guaranteed to succeed.</para>
+
+<para>
+To request pre-allocated private space, use
+<blockquote><programlisting>
+ int dixRequestPrivate(const DevPrivateKey key, unsigned size)
+</programlisting></blockquote>
+The first argument is the key for which space is being requested. The second argument is the size of the space being requested.
+After this function has been called,
+future calls to <function>dixLookupPrivate</function> or <function>dixLookupPrivateAddr</function> that cause the private pointer
+to be initially allocated will also allocate <varname>size</varname> bytes of space cleared to zero and initialize the private pointer to point
+to this space instead of <literal>NULL</literal>. This space will be automatically freed. Note that a call to <function>dixSetPrivate</function>
+that changes the pointer value may cause the space to be unreachable by the caller, however it will still be automatically freed.
+The function returns <literal>TRUE</literal> unless memory allocation fails. If the function is called more than once, the largest value
+of <type>size</type> is used.</para>
+
+<para>
+To set callbacks for initializing and cleaning up private space, use
+<blockquote><programlisting>
+ typedef struct {
+ DevPrivateKey key;
+ pointer *value;
+ } PrivateCallbackRec;
+
+ int dixRegisterPrivateInitFunc(const DevPrivateKey key,
+ CallbackProcPtr callback,
+ pointer userdata)
+ int dixRegisterPrivateDeleteFunc(const DevPrivateKey key,
+ CallbackProcPtr callback,
+ pointer userdata)
+</programlisting></blockquote>
+The first argument is the key for which the callbacks are being registered. The second argument is the callback function. The third argument
+will be passed as the user data argument to the callback function when it is called. The call data argument to the callback is a pointer to
+a structure of type <type>PrivateCallbackRec</type>.</para>
+<para>
+The init callback is called immediately after new private space has been allocated for the given key. The delete callback is called immediately
+before the private space is freed when the object is being destroyed. The <type>PrivateCallbackRec</type> structure contains the devPrivate key
+and the address of the private pointer. The init callback may be used to initialize any pre-allocated space requested by
+<function>dixRequestPrivate</function>, while the delete callback may be used to free any data stored there. However the callbacks are called even
+if no pre-allocated space was requested.</para>
+
+<para>
+When implementing new server resource objects that support devPrivates, there are three steps to perform:
+Declare a field of type <type>PrivateRec *</type> in your structure;
+initialize this field to <literal>NULL</literal> when creating any objects; and
+call the <function>dixFreePrivates</function> function, passing in the field value, when freeing any objects.</para>
+</section>
+<section>
+ <title>Wrappers</title>
+<para>
+Wrappers are not a body of code, nor an interface spec. They are, instead,
+a technique for hooking a new module into an existing calling sequence.
+There are limitations on other portions of the server implementation which
+make using wrappers possible; limits on when specific fields of data
+structures may be modified. They are intended as a replacement for
+GCInterest queues, which were not general enough to support existing
+modules; in particular software cursors needed more
+control over the activity. The general mechanism for using wrappers is:
+<blockquote><programlisting>
+privateWrapperFunction (object, ...)
+ ObjectPtr object;
+{
+ pre-wrapped-function-stuff ...
+
+ object->functionVector = dixLookupPrivate(&object->devPrivates, privateKey);
+ (*object->functionVector) (object, ...);
+ /*
+ * this next line is occasionally required by the rules governing
+ * wrapper functions. Always using it will not cause problems.
+ * Not using it when necessary can cause severe troubles.
+ */
+ dixSetPrivate(&object->devPrivates, privateKey, object->functionVector);
+ object->functionVector = privateWrapperFunction;
+
+ post-wrapped-function-stuff ...
+}
+
+privateInitialize (object)
+ ObjectPtr object;
+{
+ dixSetPrivate(&object->devPrivates, privateKey, object->functionVector);
+ object->functionVector = privateWrapperFunction;
+}
+</programlisting></blockquote>
+</para>
+<para>
+Thus the privateWrapperFunction provides hooks for performing work both
+before and after the wrapped function has been called; the process of
+resetting the functionVector is called "unwrapping" while the process of
+fetching the wrapped function and replacing it with the wrapping function
+is called "wrapping". It should be clear that GCInterest queues could
+be emulated using wrappers. In general, any function vectors contained in
+objects can be wrapped, but only vectors in GCs and Screens have been tested.</para>
+<para>
+Wrapping screen functions is quite easy; each vector is individually
+wrapped. Screen functions are not supposed to change after initialization,
+so rewrapping is technically not necessary, but causes no problems.</para>
+<para>
+Wrapping GC functions is a bit more complicated. GC's have two tables of
+function vectors, one hanging from gc->ops and the other from gc->funcs, which
+should be initially wrapped from a CreateGC wrapper. Wrappers should modify
+only table pointers, not the contents of the tables, as they
+may be shared by more than one GC (and, in the case of funcs, are probably
+shared by all gcs). Your func wrappers may change the GC funcs or ops
+pointers, and op wrappers may change the GC op pointers but not the funcs.</para>
+<para>
+Thus, the rule for GC wrappings is: wrap the funcs from CreateGC and, in each
+func wrapper, unwrap the ops and funcs, call down, and re-wrap. In each op
+wrapper, unwrap the ops, call down, and rewrap afterwards. Note that in
+re-wrapping you must save out the pointer you're replacing again. This way the
+chain will be maintained when wrappers adjust the funcs/ops tables they use.</para>
+</section>
+</section>
+<section>
+ <title>Work Queue</title>
+<para>
+To queue work for execution when all clients are in a stable state (i.e.
+just before calling select() in WaitForSomething), call:
+<blockquote><programlisting>
+ Bool QueueWorkProc(function,client,closure)
+ Bool (*function)();
+ ClientPtr client;
+ pointer closure;
+</programlisting></blockquote>
+</para>
+<para>
+When the server is about to suspend itself, the given function will be
+executed:
+<blockquote><programlisting>
+ (*function) (client, closure)
+</programlisting></blockquote>
+</para>
+<para>
+Neither client nor closure are actually used inside the work queue routines.</para>
+</section>
+</section>
+<section>
+ <title>Summary of Routines</title>
+<para>
+This is a summary of the routines discussed in this document.
+The procedure names are in alphabetical order.
+The Struct is the structure it is attached to; if blank, this
+procedure is not attached to a struct and must be named as shown.
+The sample server provides implementations in the following
+categories. Notice that many of the graphics routines have both
+mi and fb implementations.</para>
+<para>
+<itemizedlist>
+<listitem><para>dix portable to all systems; do not attempt to rewrite (Xserver/dix)</para></listitem>
+<listitem><para>os routine provided in Xserver/os or Xserver/include/os.h</para></listitem>
+<listitem><para>ddx frame buffer dependent (examples in Xserver/fb)</para></listitem>
+<listitem><para>mi routine provided in Xserver/mi</para></listitem>
+<listitem><para>hd hardware dependent (examples in many Xserver/hw directories)</para></listitem>
+<listitem><para>none not implemented in sample implementation</para></listitem>
+</itemizedlist>
+</para>
+ <table frame="all" id="routines-1">
+ <title>Server Routines (Page 1)</title>
+ <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+ <thead>
+ <row>
+ <entry>Procedure</entry>
+ <entry>Port</entry>
+ <entry>Struct</entry>
+ </row>
+ </thead>
+ <tbody>
+<row><entry><function>ALLOCATE_LOCAL</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>AbortDDX</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
+<row><entry><function>AddCallback</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>AddEnabledDevice</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>AddInputDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>AddScreen</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>AdjustWaitForDelay</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>Bell</function></entry><entry><literal>hd</literal></entry><entry><para>Device</para></entry></row>
+<row><entry><function>ChangeClip</function></entry><entry><literal>mi</literal></entry><entry><para>GC func</para></entry></row>
+<row><entry><function>ChangeGC</function></entry><entry><literal></literal></entry><entry><para>GC func</para></entry></row>
+<row><entry><function>ChangeWindowAttributes</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>ClearToBackground</function></entry><entry><literal>ddx</literal></entry><entry><para>Window</para></entry></row>
+<row><entry><function>ClientAuthorized</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>ClientSignal</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>ClientSleep</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>ClientWakeup</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>ClipNotify</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>CloseScreen</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
+<row><entry><function>ConstrainCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>CopyArea</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>CopyGCDest</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
+<row><entry><function>CopyGCSource</function></entry><entry><literal>none</literal></entry><entry><para>GC func</para></entry></row>
+<row><entry><function>CopyPlane</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>CopyWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Window</para></entry></row>
+<row><entry><function>CreateGC</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>CreateCallbackList</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>CreatePixmap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>CreateScreenResources</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>CreateWellKnowSockets</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>CreateWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>CursorLimits</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>DEALLOCATE_LOCAL</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>DeleteCallback</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>DeleteCallbackList</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>DestroyClip</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
+<row><entry><function>DestroyGC</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
+<row><entry><function>DestroyPixmap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>DestroyWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>DisplayCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>Error</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>ErrorF</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>FatalError</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>FillPolygon</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>FillSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>FlushAllOutput</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>FlushIfCriticalOutputPending</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>FreeScratchPixmapHeader</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>GetImage</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>GetMotionEvents</function></entry><entry><literal>hd</literal></entry><entry><para>Device</para></entry></row>
+<row><entry><function>GetScratchPixmapHeader</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>GetSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>GetStaticColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="all" id="routines-2">
+ <title>Server Routines (Page 2)</title>
+ <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+ <thead>
+ <row>
+ <entry>Procedure</entry>
+ <entry>Port</entry>
+ <entry>Struct</entry>
+ </row>
+ </thead>
+ <tbody>
+<row><entry><function>ImageGlyphBlt</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>ImageText16</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>ImageText8</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>InitInput</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
+<row><entry><function>InitKeyboardDeviceStruct</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>InitOutput</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
+<row><entry><function>InitPointerDeviceStruct</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>InsertFakeRequest</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>InstallColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>Intersect</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>Inverse</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>LegalModifier</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
+<row><entry><function>LineHelper</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>ListInstalledColormaps</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>LookupKeyboardDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>LookupPointerDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>ModifyPixmapheader</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>NextAvailableClient</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>OsInit</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>PaintWindowBackground</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
+<row><entry><function>PaintWindowBorder</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
+<row><entry><function>PointerNonInterestBox</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>PointInRegion</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>PolyArc</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>PolyFillArc</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>PolyFillRect</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>PolyGlyphBlt</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>Polylines</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>PolyPoint</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>PolyRectangle</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>PolySegment</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>PolyText16</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>PolyText8</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>PositionWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>ProcessInputEvents</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
+<row><entry><function>PushPixels</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>PutImage</function></entry><entry><literal>mi</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>QueryBestSize</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>ReadRequestFromClient</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>RealizeCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RealizeFont</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RealizeWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RecolorCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RectIn</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RegionCopy</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RegionCreate</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RegionDestroy</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RegionEmpty</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RegionExtents</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RegionNotEmpty</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>RegionReset</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>ResolveColor</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="all" id="routines-3">
+ <title>Server Routines (Page 3)</title>
+ <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+ <thead>
+ <row>
+ <entry>Procedure</entry>
+ <entry>Port</entry>
+ <entry>Struct</entry>
+ </row>
+ </thead>
+ <tbody>
+<row><entry><function>RegisterKeyboardDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>RegisterPointerDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>RemoveEnabledDevice</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>ResetCurrentRequest</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>SaveScreen</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>SetCriticalOutputPending</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>SetCursorPosition</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>SetInputCheck</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
+<row><entry><function>SetSpans</function></entry><entry><literal>ddx</literal></entry><entry><para>GC op</para></entry></row>
+<row><entry><function>StoreColors</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>Subtract</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>TimerCancel</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>TimerCheck</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>TimerForce</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>TimerFree</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>TimerInit</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>TimerSet</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>TimeSinceLastInputEvent</function></entry><entry><literal>hd</literal></entry><entry><para></para></entry></row>
+<row><entry><function>TranslateRegion</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>UninstallColormap</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>Union</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>UnrealizeCursor</function></entry><entry><literal>hd</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>UnrealizeFont</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>UnrealizeWindow</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>ValidateGC</function></entry><entry><literal>ddx</literal></entry><entry><para>GC func</para></entry></row>
+<row><entry><function>ValidateTree</function></entry><entry><literal>mi</literal></entry><entry><para>Screen</para></entry></row>
+<row><entry><function>WaitForSomething</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>WindowExposures</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
+<row><entry><function>WriteToClient</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>Xalloc</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>Xfree</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+<row><entry><function>Xrealloc</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+</section>
+</article>
diff --git a/xorg-server/doc/xml/xmlrules.in b/xorg-server/doc/xml/xmlrules.in new file mode 100644 index 000000000..1db7f128e --- /dev/null +++ b/xorg-server/doc/xml/xmlrules.in @@ -0,0 +1,68 @@ +#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+
+# This file is included by Makefile.am in subdirectories that have
+# DocBook XML documentation files.
+#
+# No files are automatically distributed or installed by this subset of rules
+# Any files to be distributed or installed would be listed in the including
+# Makefile.am
+
+TXT_FILES = $(XML_FILES:%.xml=%.txt)
+HTML_FILES = $(XML_FILES:%.xml=%.html)
+PDF_FILES = $(XML_FILES:%.xml=%.pdf)
+
+BUILT_DOC_FILES =
+
+SUFFIXES = .xml .txt .html .pdf
+
+XML_ENT_DIR = $(abs_top_builddir)/doc/xml
+XMLTO_FLAGS = --searchpath $(XML_ENT_DIR)
+
+if HAVE_XMLTO
+BUILT_DOC_FILES += $(TXT_FILES)
+.xml.txt:
+ @rm -f $@
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) txt $<
+
+BUILT_DOC_FILES += $(HTML_FILES)
+.xml.html:
+ @rm -f $@
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) xhtml-nochunks $<
+
+if HAVE_FOP
+BUILT_DOC_FILES += $(PDF_FILES)
+.xml.pdf:
+ @rm -f $@
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) --with-fop pdf $<
+endif
+
+endif
+
+CLEAN_DOC_FILES = $(TXT_FILES) $(HTML_FILES) $(PDF_FILES)
+
+# All the files we build depend on the entities
+$(BUILT_DOC_FILES): $(XML_ENT_DIR)/xserver.ent
+
+$(XML_ENT_DIR)/xserver.ent:
+ (cd $(XML_ENT_DIR) && $(MAKE) $(AM_MAKEFLAGS) $(@F))
diff --git a/xorg-server/doc/xml/xserver.ent.in b/xorg-server/doc/xml/xserver.ent.in new file mode 100644 index 000000000..aa02d7b93 --- /dev/null +++ b/xorg-server/doc/xml/xserver.ent.in @@ -0,0 +1,3 @@ +<!-- shared -*-xml-*- entity definitions for the X server documentation -->
+<!ENTITY xserver.version "@PACKAGE_VERSION@">
+<!ENTITY xserver.reldate "@RELEASE_DATE@">
diff --git a/xorg-server/exa/exa.c b/xorg-server/exa/exa.c index c16870e5d..a7bb5a29f 100644 --- a/xorg-server/exa/exa.c +++ b/xorg-server/exa/exa.c @@ -932,8 +932,11 @@ exaDriverInit (ScreenPtr pScreen, if (ps) {
wrap(pExaScr, ps, Composite, exaComposite);
- if (pScreenInfo->PrepareComposite)
+ if (pScreenInfo->PrepareComposite) {
wrap(pExaScr, ps, Glyphs, exaGlyphs);
+ } else {
+ wrap(pExaScr, ps, Glyphs, ExaCheckGlyphs);
+ }
wrap(pExaScr, ps, Trapezoids, exaTrapezoids);
wrap(pExaScr, ps, Triangles, exaTriangles);
wrap(pExaScr, ps, AddTraps, ExaCheckAddTraps);
diff --git a/xorg-server/exa/exa_priv.h b/xorg-server/exa/exa_priv.h index ed8be31f6..575d836b8 100644 --- a/xorg-server/exa/exa_priv.h +++ b/xorg-server/exa/exa_priv.h @@ -1,707 +1,718 @@ -/* - * - * Copyright (C) 2000 Keith Packard, member of The XFree86 Project, Inc. - * 2005 Zack Rusin, Trolltech - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef EXAPRIV_H -#define EXAPRIV_H - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "exa.h" - -#include <X11/X.h> -#include <X11/Xproto.h> -#ifdef MITSHM -#include "shmint.h" -#endif -#include "scrnintstr.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "servermd.h" -#include "mibstore.h" -#include "colormapst.h" -#include "gcstruct.h" -#include "input.h" -#include "mipointer.h" -#include "mi.h" -#include "dix.h" -#include "fb.h" -#include "fboverlay.h" -#include "fbpict.h" -#include "glyphstr.h" -#include "damage.h" - -#define DEBUG_TRACE_FALL 0 -#define DEBUG_MIGRATE 0 -#define DEBUG_PIXMAP 0 -#define DEBUG_OFFSCREEN 0 -#define DEBUG_GLYPH_CACHE 0 - -#if DEBUG_TRACE_FALL -#define EXA_FALLBACK(x) \ -do { \ - ErrorF("EXA fallback at %s: ", __FUNCTION__); \ - ErrorF x; \ -} while (0) - -char -exaDrawableLocation(DrawablePtr pDrawable); -#else -#define EXA_FALLBACK(x) -#endif - -#if DEBUG_PIXMAP -#define DBG_PIXMAP(a) ErrorF a -#else -#define DBG_PIXMAP(a) -#endif - -#ifndef EXA_MAX_FB -#define EXA_MAX_FB FB_OVERLAY_MAX -#endif - -#ifdef DEBUG -#define EXA_FatalErrorDebug(x) FatalError x -#define EXA_FatalErrorDebugWithRet(x, ret) FatalError x -#else -#define EXA_FatalErrorDebug(x) ErrorF x -#define EXA_FatalErrorDebugWithRet(x, ret) \ -do { \ - ErrorF x; \ - return ret; \ -} while (0) -#endif - -/** - * This is the list of migration heuristics supported by EXA. See - * exaDoMigration() for what their implementations do. - */ -enum ExaMigrationHeuristic { - ExaMigrationGreedy, - ExaMigrationAlways, - ExaMigrationSmart -}; - -typedef struct { - unsigned char sha1[20]; -} ExaCachedGlyphRec, *ExaCachedGlyphPtr; - -typedef struct { - /* The identity of the cache, statically configured at initialization */ - unsigned int format; - int glyphWidth; - int glyphHeight; - - int size; /* Size of cache; eventually this should be dynamically determined */ - - /* Hash table mapping from glyph sha1 to position in the glyph; we use - * open addressing with a hash table size determined based on size and large - * enough so that we always have a good amount of free space, so we can - * use linear probing. (Linear probing is preferrable to double hashing - * here because it allows us to easily remove entries.) - */ - int *hashEntries; - int hashSize; - - ExaCachedGlyphPtr glyphs; - int glyphCount; /* Current number of glyphs */ - - PicturePtr picture; /* Where the glyphs of the cache are stored */ - int yOffset; /* y location within the picture where the cache starts */ - int columns; /* Number of columns the glyphs are layed out in */ - int evictionPosition; /* Next random position to evict a glyph */ -} ExaGlyphCacheRec, *ExaGlyphCachePtr; - -#define EXA_NUM_GLYPH_CACHES 4 - -#define EXA_FALLBACK_COPYWINDOW (1 << 0) -#define EXA_ACCEL_COPYWINDOW (1 << 1) - -typedef struct _ExaMigrationRec { - Bool as_dst; - Bool as_src; - PixmapPtr pPix; - RegionPtr pReg; -} ExaMigrationRec, *ExaMigrationPtr; - -typedef void (*EnableDisableFBAccessProcPtr)(int, Bool); -typedef struct { - ExaDriverPtr info; - ScreenBlockHandlerProcPtr SavedBlockHandler; - ScreenWakeupHandlerProcPtr SavedWakeupHandler; - CreateGCProcPtr SavedCreateGC; - CloseScreenProcPtr SavedCloseScreen; - GetImageProcPtr SavedGetImage; - GetSpansProcPtr SavedGetSpans; - CreatePixmapProcPtr SavedCreatePixmap; - DestroyPixmapProcPtr SavedDestroyPixmap; - CopyWindowProcPtr SavedCopyWindow; - ChangeWindowAttributesProcPtr SavedChangeWindowAttributes; - BitmapToRegionProcPtr SavedBitmapToRegion; - CreateScreenResourcesProcPtr SavedCreateScreenResources; - ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader; - SourceValidateProcPtr SavedSourceValidate; - CompositeProcPtr SavedComposite; - TrianglesProcPtr SavedTriangles; - GlyphsProcPtr SavedGlyphs; - TrapezoidsProcPtr SavedTrapezoids; - AddTrapsProcPtr SavedAddTraps; - void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); - Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap); - void (*do_move_in_pixmap) (PixmapPtr pPixmap); - void (*do_move_out_pixmap) (PixmapPtr pPixmap); - void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg); - - Bool swappedOut; - enum ExaMigrationHeuristic migration; - Bool checkDirtyCorrectness; - unsigned disableFbCount; - Bool optimize_migration; - unsigned offScreenCounter; - unsigned numOffscreenAvailable; - CARD32 lastDefragment; - CARD32 nextDefragment; - PixmapPtr deferred_mixed_pixmap; - - /* Reference counting for accessed pixmaps */ - struct { - PixmapPtr pixmap; - int count; - Bool retval; - } access[EXA_NUM_PREPARE_INDICES]; - - /* Holds information on fallbacks that cannot be relayed otherwise. */ - unsigned int fallback_flags; - unsigned int fallback_counter; - - ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES]; - - /** - * Regions affected by fallback composite source / mask operations. - */ - - RegionRec srcReg; - RegionRec maskReg; - PixmapPtr srcPix; - -} ExaScreenPrivRec, *ExaScreenPrivPtr; - -/* - * This is the only completely portable way to - * compute this info. - */ -#ifndef BitsPerPixel -#define BitsPerPixel(d) (\ - PixmapWidthPaddingInfo[d].notPower2 ? \ - (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \ - ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \ - (PixmapWidthPaddingInfo[d].padRoundUp+1))) -#endif - -extern DevPrivateKey exaScreenPrivateKey; -extern DevPrivateKey exaPixmapPrivateKey; -extern DevPrivateKey exaGCPrivateKey; -#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixLookupPrivate(&(s)->devPrivates, exaScreenPrivateKey)) -#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s) - -#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixLookupPrivate(&(gc)->devPrivates, exaGCPrivateKey)) -#define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc) - -/* - * Some macros to deal with function wrapping. - */ -#define wrap(priv, real, mem, func) {\ - priv->Saved##mem = real->mem; \ - real->mem = func; \ -} - -#define unwrap(priv, real, mem) {\ - real->mem = priv->Saved##mem; \ -} - -#define swap(priv, real, mem) {\ - void *tmp = priv->Saved##mem; \ - priv->Saved##mem = real->mem; \ - real->mem = tmp; \ -} - -#define EXA_PRE_FALLBACK(_screen_) \ - ExaScreenPriv(_screen_); \ - pExaScr->fallback_counter++; - -#define EXA_POST_FALLBACK(_screen_) \ - pExaScr->fallback_counter--; - -#define EXA_PRE_FALLBACK_GC(_gc_) \ - ExaScreenPriv(_gc_->pScreen); \ - ExaGCPriv(_gc_); \ - pExaScr->fallback_counter++; \ - swap(pExaGC, _gc_, ops); - -#define EXA_POST_FALLBACK_GC(_gc_) \ - pExaScr->fallback_counter--; \ - swap(pExaGC, _gc_, ops); - -/** Align an offset to an arbitrary alignment */ -#define EXA_ALIGN(offset, align) (((offset) + (align) - 1) - \ - (((offset) + (align) - 1) % (align))) -/** Align an offset to a power-of-two alignment */ -#define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1)) - -#define EXA_PIXMAP_SCORE_MOVE_IN 10 -#define EXA_PIXMAP_SCORE_MAX 20 -#define EXA_PIXMAP_SCORE_MOVE_OUT -10 -#define EXA_PIXMAP_SCORE_MIN -20 -#define EXA_PIXMAP_SCORE_PINNED 1000 -#define EXA_PIXMAP_SCORE_INIT 1001 - -#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixLookupPrivate(&(p)->devPrivates, exaPixmapPrivateKey)) -#define ExaSetPixmapPriv(p,a) dixSetPrivate(&(p)->devPrivates, exaPixmapPrivateKey, a) -#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p) - -#define EXA_RANGE_PITCH (1 << 0) -#define EXA_RANGE_WIDTH (1 << 1) -#define EXA_RANGE_HEIGHT (1 << 2) - -typedef struct { - ExaOffscreenArea *area; - int score; /**< score for the move-in vs move-out heuristic */ - Bool use_gpu_copy; - - CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */ - int sys_pitch; /**< pitch of pixmap in system memory */ - - CARD8 *fb_ptr; /**< pointer to pixmap data in framebuffer memory */ - int fb_pitch; /**< pitch of pixmap in framebuffer memory */ - unsigned int fb_size; /**< size of pixmap in framebuffer memory */ - - /** - * Holds information about whether this pixmap can be used for - * acceleration (== 0) or not (> 0). - * - * Contains a OR'ed combination of the following values: - * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range - * EXA_RANGE_WIDTH - set if the pixmap's width is out of range - * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range - */ - unsigned int accel_blocked; - - /** - * The damage record contains the areas of the pixmap's current location - * (framebuffer or system) that have been damaged compared to the other - * location. - */ - DamagePtr pDamage; - /** - * The valid regions mark the valid bits (at least, as they're derived from - * damage, which may be overreported) of a pixmap's system and FB copies. - */ - RegionRec validSys, validFB; - /** - * Driver private storage per EXA pixmap - */ - void *driverPriv; -} ExaPixmapPrivRec, *ExaPixmapPrivPtr; - -typedef struct { - /* GC values from the layer below. */ - GCOps *Savedops; - GCFuncs *Savedfuncs; -} ExaGCPrivRec, *ExaGCPrivPtr; - -typedef struct { - PicturePtr pDst; - INT16 xSrc; - INT16 ySrc; - INT16 xMask; - INT16 yMask; - INT16 xDst; - INT16 yDst; - INT16 width; - INT16 height; -} ExaCompositeRectRec, *ExaCompositeRectPtr; - -/** - * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place - * to set EXA options or hook in screen functions to handle using EXA as the AA. - */ -void exaDDXDriverInit (ScreenPtr pScreen); - -/* exa_unaccel.c */ -void -exaPrepareAccessGC(GCPtr pGC); - -void -exaFinishAccessGC(GCPtr pGC); - -void -ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans, - DDXPointPtr ppt, int *pwidth, int fSorted); - -void -ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc, - DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); - -void -ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, - int x, int y, int w, int h, int leftPad, int format, - char *bits); - -void -ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, - Bool upsidedown, Pixel bitplane, void *closure); - -RegionPtr -ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty); - -RegionPtr -ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty, - unsigned long bitPlane); - -void -ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr pptInit); - -void -ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, - int mode, int npt, DDXPointPtr ppt); - -void -ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, - int nsegInit, xSegment *pSegInit); - -void -ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, - int narcs, xArc *pArcs); - -void -ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, - int nrect, xRectangle *prect); - -void -ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase); - -void -ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase); - -void -ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, - int w, int h, int x, int y); - -void -ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); - -void -ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d); - -void -ExaCheckGetSpans (DrawablePtr pDrawable, - int wMax, - DDXPointPtr ppt, - int *pwidth, - int nspans, - char *pdstStart); - -void -ExaCheckAddTraps (PicturePtr pPicture, - INT16 x_off, - INT16 y_off, - int ntrap, - xTrap *traps); - -/* exa_accel.c */ - -static _X_INLINE Bool -exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask, - unsigned int fillStyle, unsigned char alu, - unsigned int clientClipType) -{ - return ((alu != GXcopy && alu != GXclear && alu != GXset && - alu != GXcopyInverted) || fillStyle == FillStippled || - clientClipType != CT_NONE || !EXA_PM_IS_SOLID(pDrawable, planemask)); -} - -void -exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); - -Bool -exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, - DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu, - unsigned int clientClipType); - -void -exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d); - -RegionPtr -exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, - int srcx, int srcy, int width, int height, int dstx, int dsty); - -Bool -exaHWCopyNtoN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown); - -void -exaCopyNtoN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); - -extern const GCOps exaOps; - -void -ExaCheckComposite (CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height); - -/* exa_offscreen.c */ -void -ExaOffscreenSwapOut (ScreenPtr pScreen); - -void -ExaOffscreenSwapIn (ScreenPtr pScreen); - -ExaOffscreenArea* -ExaOffscreenDefragment (ScreenPtr pScreen); - -Bool -exaOffscreenInit(ScreenPtr pScreen); - -void -ExaOffscreenFini (ScreenPtr pScreen); - -/* exa.c */ -Bool -ExaDoPrepareAccess(PixmapPtr pPixmap, int index); - -void -exaPrepareAccess(DrawablePtr pDrawable, int index); - -void -exaFinishAccess(DrawablePtr pDrawable, int index); - -void -exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2); - -void -exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap, - int *xp, int *yp); - -Bool -exaPixmapHasGpuCopy(PixmapPtr p); - -PixmapPtr -exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp); - -PixmapPtr -exaGetDrawablePixmap(DrawablePtr pDrawable); - -void -exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, - int w, int h, int bpp); - -void -exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, - int w, int h, int bpp); - -void -exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); - -Bool -exaPixmapIsPinned (PixmapPtr pPix); - -extern const GCFuncs exaGCFuncs; - -/* exa_classic.c */ -PixmapPtr -exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint); - -Bool -exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth, - int bitsPerPixel, int devKind, pointer pPixData); - -Bool -exaDestroyPixmap_classic (PixmapPtr pPixmap); - -Bool -exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap); - -/* exa_driver.c */ -PixmapPtr -exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint); - -Bool -exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth, - int bitsPerPixel, int devKind, pointer pPixData); - -Bool -exaDestroyPixmap_driver (PixmapPtr pPixmap); - -Bool -exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap); - -/* exa_mixed.c */ -PixmapPtr -exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint); - -Bool -exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, - int bitsPerPixel, int devKind, pointer pPixData); - -Bool -exaDestroyPixmap_mixed(PixmapPtr pPixmap); - -Bool -exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap); - -/* exa_migration_mixed.c */ -void -exaCreateDriverPixmap_mixed(PixmapPtr pPixmap); - -void -exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); - -void -exaMoveInPixmap_mixed(PixmapPtr pPixmap); - -void -exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure); - -void -exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg); - -/* exa_render.c */ -Bool -exaOpReadsDestination (CARD8 op); - -void -exaComposite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height); - -void -exaCompositeRects(CARD8 op, - PicturePtr Src, - PicturePtr pMask, - PicturePtr pDst, - int nrect, - ExaCompositeRectPtr rects); - -void -exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int ntrap, xTrapezoid *traps); - -void -exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int ntri, xTriangle *tris); - -/* exa_glyph.c */ -void -exaGlyphsInit(ScreenPtr pScreen); - -void -exaGlyphsFini (ScreenPtr pScreen); - -void -exaGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs); - -/* exa_migration_classic.c */ -void -exaCopyDirtyToSys (ExaMigrationPtr migrate); - -void -exaCopyDirtyToFb (ExaMigrationPtr migrate); - -void -exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); - -void -exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area); - -void -exaMoveOutPixmap_classic (PixmapPtr pPixmap); - -void -exaMoveInPixmap_classic (PixmapPtr pPixmap); - -void -exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg); - -#endif /* EXAPRIV_H */ +/*
+ *
+ * Copyright (C) 2000 Keith Packard, member of The XFree86 Project, Inc.
+ * 2005 Zack Rusin, Trolltech
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef EXAPRIV_H
+#define EXAPRIV_H
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "exa.h"
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#ifdef MITSHM
+#include "shmint.h"
+#endif
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mibstore.h"
+#include "colormapst.h"
+#include "gcstruct.h"
+#include "input.h"
+#include "mipointer.h"
+#include "mi.h"
+#include "dix.h"
+#include "fb.h"
+#include "fboverlay.h"
+#include "fbpict.h"
+#include "glyphstr.h"
+#include "damage.h"
+
+#define DEBUG_TRACE_FALL 0
+#define DEBUG_MIGRATE 0
+#define DEBUG_PIXMAP 0
+#define DEBUG_OFFSCREEN 0
+#define DEBUG_GLYPH_CACHE 0
+
+#if DEBUG_TRACE_FALL
+#define EXA_FALLBACK(x) \
+do { \
+ ErrorF("EXA fallback at %s: ", __FUNCTION__); \
+ ErrorF x; \
+} while (0)
+
+char
+exaDrawableLocation(DrawablePtr pDrawable);
+#else
+#define EXA_FALLBACK(x)
+#endif
+
+#if DEBUG_PIXMAP
+#define DBG_PIXMAP(a) ErrorF a
+#else
+#define DBG_PIXMAP(a)
+#endif
+
+#ifndef EXA_MAX_FB
+#define EXA_MAX_FB FB_OVERLAY_MAX
+#endif
+
+#ifdef DEBUG
+#define EXA_FatalErrorDebug(x) FatalError x
+#define EXA_FatalErrorDebugWithRet(x, ret) FatalError x
+#else
+#define EXA_FatalErrorDebug(x) ErrorF x
+#define EXA_FatalErrorDebugWithRet(x, ret) \
+do { \
+ ErrorF x; \
+ return ret; \
+} while (0)
+#endif
+
+/**
+ * This is the list of migration heuristics supported by EXA. See
+ * exaDoMigration() for what their implementations do.
+ */
+enum ExaMigrationHeuristic {
+ ExaMigrationGreedy,
+ ExaMigrationAlways,
+ ExaMigrationSmart
+};
+
+typedef struct {
+ unsigned char sha1[20];
+} ExaCachedGlyphRec, *ExaCachedGlyphPtr;
+
+typedef struct {
+ /* The identity of the cache, statically configured at initialization */
+ unsigned int format;
+ int glyphWidth;
+ int glyphHeight;
+
+ int size; /* Size of cache; eventually this should be dynamically determined */
+
+ /* Hash table mapping from glyph sha1 to position in the glyph; we use
+ * open addressing with a hash table size determined based on size and large
+ * enough so that we always have a good amount of free space, so we can
+ * use linear probing. (Linear probing is preferrable to double hashing
+ * here because it allows us to easily remove entries.)
+ */
+ int *hashEntries;
+ int hashSize;
+
+ ExaCachedGlyphPtr glyphs;
+ int glyphCount; /* Current number of glyphs */
+
+ PicturePtr picture; /* Where the glyphs of the cache are stored */
+ int yOffset; /* y location within the picture where the cache starts */
+ int columns; /* Number of columns the glyphs are layed out in */
+ int evictionPosition; /* Next random position to evict a glyph */
+} ExaGlyphCacheRec, *ExaGlyphCachePtr;
+
+#define EXA_NUM_GLYPH_CACHES 4
+
+#define EXA_FALLBACK_COPYWINDOW (1 << 0)
+#define EXA_ACCEL_COPYWINDOW (1 << 1)
+
+typedef struct _ExaMigrationRec {
+ Bool as_dst;
+ Bool as_src;
+ PixmapPtr pPix;
+ RegionPtr pReg;
+} ExaMigrationRec, *ExaMigrationPtr;
+
+typedef void (*EnableDisableFBAccessProcPtr)(int, Bool);
+typedef struct {
+ ExaDriverPtr info;
+ ScreenBlockHandlerProcPtr SavedBlockHandler;
+ ScreenWakeupHandlerProcPtr SavedWakeupHandler;
+ CreateGCProcPtr SavedCreateGC;
+ CloseScreenProcPtr SavedCloseScreen;
+ GetImageProcPtr SavedGetImage;
+ GetSpansProcPtr SavedGetSpans;
+ CreatePixmapProcPtr SavedCreatePixmap;
+ DestroyPixmapProcPtr SavedDestroyPixmap;
+ CopyWindowProcPtr SavedCopyWindow;
+ ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
+ BitmapToRegionProcPtr SavedBitmapToRegion;
+ CreateScreenResourcesProcPtr SavedCreateScreenResources;
+ ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
+ SourceValidateProcPtr SavedSourceValidate;
+ CompositeProcPtr SavedComposite;
+ TrianglesProcPtr SavedTriangles;
+ GlyphsProcPtr SavedGlyphs;
+ TrapezoidsProcPtr SavedTrapezoids;
+ AddTrapsProcPtr SavedAddTraps;
+ void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+ Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap);
+ void (*do_move_in_pixmap) (PixmapPtr pPixmap);
+ void (*do_move_out_pixmap) (PixmapPtr pPixmap);
+ void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg);
+
+ Bool swappedOut;
+ enum ExaMigrationHeuristic migration;
+ Bool checkDirtyCorrectness;
+ unsigned disableFbCount;
+ Bool optimize_migration;
+ unsigned offScreenCounter;
+ unsigned numOffscreenAvailable;
+ CARD32 lastDefragment;
+ CARD32 nextDefragment;
+ PixmapPtr deferred_mixed_pixmap;
+
+ /* Reference counting for accessed pixmaps */
+ struct {
+ PixmapPtr pixmap;
+ int count;
+ Bool retval;
+ } access[EXA_NUM_PREPARE_INDICES];
+
+ /* Holds information on fallbacks that cannot be relayed otherwise. */
+ unsigned int fallback_flags;
+ unsigned int fallback_counter;
+
+ ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES];
+
+ /**
+ * Regions affected by fallback composite source / mask operations.
+ */
+
+ RegionRec srcReg;
+ RegionRec maskReg;
+ PixmapPtr srcPix;
+
+} ExaScreenPrivRec, *ExaScreenPrivPtr;
+
+/*
+ * This is the only completely portable way to
+ * compute this info.
+ */
+#ifndef BitsPerPixel
+#define BitsPerPixel(d) (\
+ PixmapWidthPaddingInfo[d].notPower2 ? \
+ (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \
+ ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
+ (PixmapWidthPaddingInfo[d].padRoundUp+1)))
+#endif
+
+extern DevPrivateKey exaScreenPrivateKey;
+extern DevPrivateKey exaPixmapPrivateKey;
+extern DevPrivateKey exaGCPrivateKey;
+#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixLookupPrivate(&(s)->devPrivates, exaScreenPrivateKey))
+#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
+
+#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixLookupPrivate(&(gc)->devPrivates, exaGCPrivateKey))
+#define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc)
+
+/*
+ * Some macros to deal with function wrapping.
+ */
+#define wrap(priv, real, mem, func) {\
+ priv->Saved##mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+ real->mem = priv->Saved##mem; \
+}
+
+#define swap(priv, real, mem) {\
+ void *tmp = priv->Saved##mem; \
+ priv->Saved##mem = real->mem; \
+ real->mem = tmp; \
+}
+
+#define EXA_PRE_FALLBACK(_screen_) \
+ ExaScreenPriv(_screen_); \
+ pExaScr->fallback_counter++;
+
+#define EXA_POST_FALLBACK(_screen_) \
+ pExaScr->fallback_counter--;
+
+#define EXA_PRE_FALLBACK_GC(_gc_) \
+ ExaScreenPriv(_gc_->pScreen); \
+ ExaGCPriv(_gc_); \
+ pExaScr->fallback_counter++; \
+ swap(pExaGC, _gc_, ops);
+
+#define EXA_POST_FALLBACK_GC(_gc_) \
+ pExaScr->fallback_counter--; \
+ swap(pExaGC, _gc_, ops);
+
+/** Align an offset to an arbitrary alignment */
+#define EXA_ALIGN(offset, align) (((offset) + (align) - 1) - \
+ (((offset) + (align) - 1) % (align)))
+/** Align an offset to a power-of-two alignment */
+#define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1))
+
+#define EXA_PIXMAP_SCORE_MOVE_IN 10
+#define EXA_PIXMAP_SCORE_MAX 20
+#define EXA_PIXMAP_SCORE_MOVE_OUT -10
+#define EXA_PIXMAP_SCORE_MIN -20
+#define EXA_PIXMAP_SCORE_PINNED 1000
+#define EXA_PIXMAP_SCORE_INIT 1001
+
+#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixLookupPrivate(&(p)->devPrivates, exaPixmapPrivateKey))
+#define ExaSetPixmapPriv(p,a) dixSetPrivate(&(p)->devPrivates, exaPixmapPrivateKey, a)
+#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
+
+#define EXA_RANGE_PITCH (1 << 0)
+#define EXA_RANGE_WIDTH (1 << 1)
+#define EXA_RANGE_HEIGHT (1 << 2)
+
+typedef struct {
+ ExaOffscreenArea *area;
+ int score; /**< score for the move-in vs move-out heuristic */
+ Bool use_gpu_copy;
+
+ CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */
+ int sys_pitch; /**< pitch of pixmap in system memory */
+
+ CARD8 *fb_ptr; /**< pointer to pixmap data in framebuffer memory */
+ int fb_pitch; /**< pitch of pixmap in framebuffer memory */
+ unsigned int fb_size; /**< size of pixmap in framebuffer memory */
+
+ /**
+ * Holds information about whether this pixmap can be used for
+ * acceleration (== 0) or not (> 0).
+ *
+ * Contains a OR'ed combination of the following values:
+ * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range
+ * EXA_RANGE_WIDTH - set if the pixmap's width is out of range
+ * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range
+ */
+ unsigned int accel_blocked;
+
+ /**
+ * The damage record contains the areas of the pixmap's current location
+ * (framebuffer or system) that have been damaged compared to the other
+ * location.
+ */
+ DamagePtr pDamage;
+ /**
+ * The valid regions mark the valid bits (at least, as they're derived from
+ * damage, which may be overreported) of a pixmap's system and FB copies.
+ */
+ RegionRec validSys, validFB;
+ /**
+ * Driver private storage per EXA pixmap
+ */
+ void *driverPriv;
+} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
+
+typedef struct {
+ /* GC values from the layer below. */
+ GCOps *Savedops;
+ GCFuncs *Savedfuncs;
+} ExaGCPrivRec, *ExaGCPrivPtr;
+
+typedef struct {
+ PicturePtr pDst;
+ INT16 xSrc;
+ INT16 ySrc;
+ INT16 xMask;
+ INT16 yMask;
+ INT16 xDst;
+ INT16 yDst;
+ INT16 width;
+ INT16 height;
+} ExaCompositeRectRec, *ExaCompositeRectPtr;
+
+/**
+ * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place
+ * to set EXA options or hook in screen functions to handle using EXA as the AA.
+ */
+void exaDDXDriverInit (ScreenPtr pScreen);
+
+/* exa_unaccel.c */
+void
+exaPrepareAccessGC(GCPtr pGC);
+
+void
+exaFinishAccessGC(GCPtr pGC);
+
+void
+ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+
+void
+ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
+
+void
+ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *bits);
+
+void
+ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
+ Bool upsidedown, Pixel bitplane, void *closure);
+
+RegionPtr
+ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty);
+
+RegionPtr
+ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty,
+ unsigned long bitPlane);
+
+void
+ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
+
+void
+ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr ppt);
+
+void
+ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
+ int nsegInit, xSegment *pSegInit);
+
+void
+ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *pArcs);
+
+void
+ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrect, xRectangle *prect);
+
+void
+ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase);
+
+void
+ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase);
+
+void
+ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int w, int h, int x, int y);
+
+void
+ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
+void
+ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d);
+
+void
+ExaCheckGetSpans (DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart);
+
+void
+ExaCheckAddTraps (PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off,
+ int ntrap,
+ xTrap *traps);
+
+/* exa_accel.c */
+
+static _X_INLINE Bool
+exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask,
+ unsigned int fillStyle, unsigned char alu,
+ unsigned int clientClipType)
+{
+ return ((alu != GXcopy && alu != GXclear && alu != GXset &&
+ alu != GXcopyInverted) || fillStyle == FillStippled ||
+ clientClipType != CT_NONE || !EXA_PM_IS_SOLID(pDrawable, planemask));
+}
+
+void
+exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
+Bool
+exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
+ DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
+ unsigned int clientClipType);
+
+void
+exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d);
+
+RegionPtr
+exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty);
+
+Bool
+exaHWCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown);
+
+void
+exaCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+extern const GCOps exaOps;
+
+void
+ExaCheckComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+ExaCheckGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+/* exa_offscreen.c */
+void
+ExaOffscreenSwapOut (ScreenPtr pScreen);
+
+void
+ExaOffscreenSwapIn (ScreenPtr pScreen);
+
+ExaOffscreenArea*
+ExaOffscreenDefragment (ScreenPtr pScreen);
+
+Bool
+exaOffscreenInit(ScreenPtr pScreen);
+
+void
+ExaOffscreenFini (ScreenPtr pScreen);
+
+/* exa.c */
+Bool
+ExaDoPrepareAccess(PixmapPtr pPixmap, int index);
+
+void
+exaPrepareAccess(DrawablePtr pDrawable, int index);
+
+void
+exaFinishAccess(DrawablePtr pDrawable, int index);
+
+void
+exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
+
+void
+exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
+ int *xp, int *yp);
+
+Bool
+exaPixmapHasGpuCopy(PixmapPtr p);
+
+PixmapPtr
+exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
+
+PixmapPtr
+exaGetDrawablePixmap(DrawablePtr pDrawable);
+
+void
+exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
+ int w, int h, int bpp);
+
+void
+exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
+ int w, int h, int bpp);
+
+void
+exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+
+Bool
+exaPixmapIsPinned (PixmapPtr pPix);
+
+extern const GCFuncs exaGCFuncs;
+
+/* exa_classic.c */
+PixmapPtr
+exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
+ unsigned usage_hint);
+
+Bool
+exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth,
+ int bitsPerPixel, int devKind, pointer pPixData);
+
+Bool
+exaDestroyPixmap_classic (PixmapPtr pPixmap);
+
+Bool
+exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap);
+
+/* exa_driver.c */
+PixmapPtr
+exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
+ unsigned usage_hint);
+
+Bool
+exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth,
+ int bitsPerPixel, int devKind, pointer pPixData);
+
+Bool
+exaDestroyPixmap_driver (PixmapPtr pPixmap);
+
+Bool
+exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap);
+
+/* exa_mixed.c */
+PixmapPtr
+exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
+ unsigned usage_hint);
+
+Bool
+exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
+ int bitsPerPixel, int devKind, pointer pPixData);
+
+Bool
+exaDestroyPixmap_mixed(PixmapPtr pPixmap);
+
+Bool
+exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap);
+
+/* exa_migration_mixed.c */
+void
+exaCreateDriverPixmap_mixed(PixmapPtr pPixmap);
+
+void
+exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+
+void
+exaMoveInPixmap_mixed(PixmapPtr pPixmap);
+
+void
+exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure);
+
+void
+exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
+
+/* exa_render.c */
+Bool
+exaOpReadsDestination (CARD8 op);
+
+void
+exaComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+exaCompositeRects(CARD8 op,
+ PicturePtr Src,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ int nrect,
+ ExaCompositeRectPtr rects);
+
+void
+exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid *traps);
+
+void
+exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntri, xTriangle *tris);
+
+/* exa_glyph.c */
+void
+exaGlyphsInit(ScreenPtr pScreen);
+
+void
+exaGlyphsFini (ScreenPtr pScreen);
+
+void
+exaGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+/* exa_migration_classic.c */
+void
+exaCopyDirtyToSys (ExaMigrationPtr migrate);
+
+void
+exaCopyDirtyToFb (ExaMigrationPtr migrate);
+
+void
+exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+
+void
+exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area);
+
+void
+exaMoveOutPixmap_classic (PixmapPtr pPixmap);
+
+void
+exaMoveInPixmap_classic (PixmapPtr pPixmap);
+
+void
+exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg);
+
+#endif /* EXAPRIV_H */
diff --git a/xorg-server/exa/exa_unaccel.c b/xorg-server/exa/exa_unaccel.c index 2f8c4622d..46be2eff9 100644 --- a/xorg-server/exa/exa_unaccel.c +++ b/xorg-server/exa/exa_unaccel.c @@ -1,740 +1,762 @@ -/* - * - * Copyright © 1999 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#include "exa_priv.h" - -#include "mipict.h" - -/* - * These functions wrap the low-level fb rendering functions and - * synchronize framebuffer/accelerated drawing by stalling until - * the accelerator is idle - */ - -/** - * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the - * current fill style. - * - * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are - * 1bpp and never in fb, so we don't worry about them. - * We should worry about them for completeness sake and going forward. - */ -void -exaPrepareAccessGC(GCPtr pGC) -{ - if (pGC->stipple) - exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); - if (pGC->fillStyle == FillTiled) - exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC); -} - -/** - * Finishes access to the tile in the GC, if used. - */ -void -exaFinishAccessGC(GCPtr pGC) -{ - if (pGC->fillStyle == FillTiled) - exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC); - if (pGC->stipple) - exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); -} - -#if DEBUG_TRACE_FALL -char -exaDrawableLocation(DrawablePtr pDrawable) -{ - return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm'; -} -#endif /* DEBUG_TRACE_FALL */ - -void -ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans, - DDXPointPtr ppt, int *pwidth, int fSorted) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc, - DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, - int x, int y, int w, int h, int leftPad, int format, - char *bits) -{ - PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); - ExaPixmapPriv(pPixmap); - - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage || - exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, - pGC->alu, pGC->clientClipType)) - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - else - pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, - DamagePendingRegion(pExaPixmap->pDamage)); - pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, - Bool upsidedown, Pixel bitplane, void *closure) -{ - RegionRec reg; - int xoff, yoff; - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, - exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); - - if (pExaScr->prepare_access_reg) { - PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc); - - exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff); - REGION_INIT(pScreen, ®, pbox, nbox); - REGION_TRANSLATE(pScreen, ®, xoff + dx, yoff + dy); - pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®); - REGION_UNINIT(pScreen, ®); - } else - exaPrepareAccess (pSrc, EXA_PREPARE_SRC); - - if (pExaScr->prepare_access_reg && - !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle, - pGC->alu, pGC->clientClipType)) { - PixmapPtr pPixmap = exaGetDrawablePixmap(pDst); - - exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff); - REGION_INIT(pScreen, ®, pbox, nbox); - REGION_TRANSLATE(pScreen, ®, xoff, yoff); - pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®); - REGION_UNINIT(pScreen, ®); - } else - exaPrepareAccess (pDst, EXA_PREPARE_DEST); - - /* This will eventually call fbCopyNtoN, with some calculation overhead. */ - while (nbox--) { - pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y); - pbox++; - } - exaFinishAccess (pSrc, EXA_PREPARE_SRC); - exaFinishAccess (pDst, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -static void -ExaFallbackPrepareReg(DrawablePtr pDrawable, - GCPtr pGC, - int x, int y, int width, int height, - int index, Bool checkReads) -{ - ScreenPtr pScreen = pDrawable->pScreen; - ExaScreenPriv(pScreen); - - if (pExaScr->prepare_access_reg && - !(checkReads && exaGCReadsDestination(pDrawable, - pGC->planemask, - pGC->fillStyle, - pGC->alu, - pGC->clientClipType))) { - BoxRec box; - RegionRec reg; - int xoff, yoff; - PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); - - exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); - box.x1 = pDrawable->x + x + xoff; - box.y1 = pDrawable->y + y + yoff; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - - REGION_INIT(pScreen, ®, &box, 1); - pExaScr->prepare_access_reg(pPixmap, index, ®); - REGION_UNINIT(pScreen, ®); - } else - exaPrepareAccess(pDrawable, index); -} - - -RegionPtr -ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty) -{ - RegionPtr ret; - - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, - exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); - ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, - EXA_PREPARE_SRC, FALSE); - ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, - EXA_PREPARE_DEST, TRUE); - ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); - exaFinishAccess (pSrc, EXA_PREPARE_SRC); - exaFinishAccess (pDst, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); - - return ret; -} - -RegionPtr -ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty, - unsigned long bitPlane) -{ - RegionPtr ret; - - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, - exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); - ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, - EXA_PREPARE_SRC, FALSE); - ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, - EXA_PREPARE_DEST, TRUE); - ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, - bitPlane); - exaFinishAccess (pSrc, EXA_PREPARE_SRC); - exaFinishAccess (pDst, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); - - return ret; -} - -void -ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr pptInit) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, - int mode, int npt, DDXPointPtr ppt) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n", - pDrawable, exaDrawableLocation(pDrawable), - pGC->lineWidth, mode, npt)); - - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, - int nsegInit, xSegment *pSegInit) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable, - exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit)); - - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, - int narcs, xArc *pArcs) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, - int nrect, xRectangle *prect) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, - exaDrawableLocation(pDrawable))); - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable, - exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu)); - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, - int w, int h, int x, int y) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable, - exaDrawableLocation(&pBitmap->drawable), - exaDrawableLocation(pDrawable))); - ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h, - EXA_PREPARE_DEST, TRUE); - ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h, - EXA_PREPARE_SRC, FALSE); - exaPrepareAccessGC (pGC); - pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y); - exaFinishAccessGC (pGC); - exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -{ - DrawablePtr pDrawable = &pWin->drawable; - ScreenPtr pScreen = pDrawable->pScreen; - EXA_PRE_FALLBACK(pScreen); - EXA_FALLBACK(("from %p\n", pWin)); - - /* Only need the source bits, the destination region will be overwritten */ - if (pExaScr->prepare_access_reg) { - PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin); - int xoff, yoff; - - exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff); - REGION_TRANSLATE(pScreen, prgnSrc, xoff, yoff); - pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc); - REGION_TRANSLATE(pScreen, prgnSrc, -xoff, -yoff); - } else - exaPrepareAccess(pDrawable, EXA_PREPARE_SRC); - - swap(pExaScr, pScreen, CopyWindow); - pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc); - swap(pExaScr, pScreen, CopyWindow); - exaFinishAccess (pDrawable, EXA_PREPARE_SRC); - EXA_POST_FALLBACK(pScreen); -} - -void -ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d) -{ - ScreenPtr pScreen = pDrawable->pScreen; - EXA_PRE_FALLBACK(pScreen); - EXA_FALLBACK(("from %p (%c)\n", pDrawable, - exaDrawableLocation(pDrawable))); - - ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h, - EXA_PREPARE_SRC, FALSE); - swap(pExaScr, pScreen, GetImage); - pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d); - swap(pExaScr, pScreen, GetImage); - exaFinishAccess (pDrawable, EXA_PREPARE_SRC); - EXA_POST_FALLBACK(pScreen); -} - -void -ExaCheckGetSpans (DrawablePtr pDrawable, - int wMax, - DDXPointPtr ppt, - int *pwidth, - int nspans, - char *pdstStart) -{ - ScreenPtr pScreen = pDrawable->pScreen; - - EXA_PRE_FALLBACK(pScreen); - EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - exaPrepareAccess (pDrawable, EXA_PREPARE_SRC); - swap(pExaScr, pScreen, GetSpans); - pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); - swap(pExaScr, pScreen, GetSpans); - exaFinishAccess (pDrawable, EXA_PREPARE_SRC); - EXA_POST_FALLBACK(pScreen); -} - -static void -ExaSrcValidate(DrawablePtr pDrawable, - int x, - int y, - int width, - int height) -{ - ScreenPtr pScreen = pDrawable->pScreen; - ExaScreenPriv(pScreen); - PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); - BoxRec box; - RegionRec reg; - RegionPtr dst; - int xoff, yoff; - - exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff); - - box.x1 = x + xoff; - box.y1 = y + yoff; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - - dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg : - &pExaScr->maskReg; - - REGION_INIT(pScreen, ®, &box, 1); - REGION_UNION(pScreen, dst, dst, ®); - REGION_UNINIT(pScreen, ®); - - if (pExaScr->SavedSourceValidate) { - swap(pExaScr, pScreen, SourceValidate); - pScreen->SourceValidate(pDrawable, x, y, width, height); - swap(pExaScr, pScreen, SourceValidate); - } -} - -static Bool -ExaPrepareCompositeReg(ScreenPtr pScreen, - CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) -{ - RegionRec region; - RegionPtr dstReg = NULL; - RegionPtr srcReg = NULL; - RegionPtr maskReg = NULL; - PixmapPtr pSrcPix = NULL; - PixmapPtr pMaskPix = NULL; - PixmapPtr pDstPix; - ExaScreenPriv(pScreen); - Bool ret; - - - REGION_NULL(pScreen, ®ion); - - if (pSrc->pDrawable) { - pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); - REGION_NULL(pScreen, &pExaScr->srcReg); - srcReg = &pExaScr->srcReg; - pExaScr->srcPix = pSrcPix; - if (pSrc != pDst) - REGION_TRANSLATE(pScreen, pSrc->pCompositeClip, - -pSrc->pDrawable->x, - -pSrc->pDrawable->y); - } - - if (pMask && pMask->pDrawable) { - pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); - REGION_NULL(pScreen, &pExaScr->maskReg); - maskReg = &pExaScr->maskReg; - if (pMask != pDst && pMask != pSrc) - REGION_TRANSLATE(pScreen, pMask->pCompositeClip, - -pMask->pDrawable->x, - -pMask->pDrawable->y); - } - - REGION_TRANSLATE(pScreen, pDst->pCompositeClip, - -pDst->pDrawable->x, - -pDst->pDrawable->y); - - pExaScr->SavedSourceValidate = ExaSrcValidate; - swap(pExaScr, pScreen, SourceValidate); - ret = miComputeCompositeRegion (®ion, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, - xDst, - yDst, - width, height); - swap(pExaScr, pScreen, SourceValidate); - - REGION_TRANSLATE(pScreen, pDst->pCompositeClip, - pDst->pDrawable->x, - pDst->pDrawable->y); - if (pSrc->pDrawable && pSrc != pDst) - REGION_TRANSLATE(pScreen, pSrc->pCompositeClip, - pSrc->pDrawable->x, - pSrc->pDrawable->y); - if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc) - REGION_TRANSLATE(pScreen, pMask->pCompositeClip, - pMask->pDrawable->x, - pMask->pDrawable->y); - - if (!ret) { - if (srcReg) - REGION_UNINIT(pScreen, srcReg); - if (maskReg) - REGION_UNINIT(pScreen, maskReg); - - return FALSE; - } - - /** - * Don't limit alphamaps readbacks for now until we've figured out how that - * should be done. - */ - - if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) - pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable), - EXA_PREPARE_AUX_SRC, - NULL); - if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) - pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable), - EXA_PREPARE_AUX_MASK, - NULL); - - if (pSrcPix) - pExaScr->prepare_access_reg(pSrcPix, - EXA_PREPARE_SRC, - srcReg); - - if (pMaskPix) - pExaScr->prepare_access_reg(pMaskPix, - EXA_PREPARE_MASK, - maskReg); - - if (srcReg) - REGION_UNINIT(pScreen, srcReg); - if (maskReg) - REGION_UNINIT(pScreen, maskReg); - - pDstPix = exaGetDrawablePixmap(pDst->pDrawable); - if (!exaOpReadsDestination(op)) { - int xoff; - int yoff; - - exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff); - REGION_TRANSLATE(pScreen, ®ion, pDst->pDrawable->x + xoff, - pDst->pDrawable->y + yoff); - dstReg = ®ion; - } - - if (pDst->alphaMap && pDst->alphaMap->pDrawable) - pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable), - EXA_PREPARE_AUX_DEST, - dstReg); - pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg); - - REGION_UNINIT(pScreen, ®ion); - return TRUE; -} - -void -ExaCheckComposite (CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - EXA_PRE_FALLBACK(pScreen); - - if (pExaScr->prepare_access_reg) { - if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc, - ySrc, xMask, yMask, xDst, yDst, width, - height)) - goto out_no_clip; - } else { - - /* We need to prepare access to any separate alpha maps first, - * in case the driver doesn't support EXA_PREPARE_AUX*, - * in which case EXA_PREPARE_SRC may be used for moving them out. - */ - - if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) - exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); - if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) - exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); - if (pDst->alphaMap && pDst->alphaMap->pDrawable) - exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); - - exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST); - - EXA_FALLBACK(("from picts %p/%p to pict %p\n", - pSrc, pMask, pDst)); - - if (pSrc->pDrawable != NULL) - exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC); - if (pMask && pMask->pDrawable != NULL) - exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK); - } - - swap(pExaScr, ps, Composite); - ps->Composite (op, - pSrc, - pMask, - pDst, - xSrc, - ySrc, - xMask, - yMask, - xDst, - yDst, - width, - height); - swap(pExaScr, ps, Composite); - if (pMask && pMask->pDrawable != NULL) - exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK); - if (pSrc->pDrawable != NULL) - exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC); - exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST); - if (pDst->alphaMap && pDst->alphaMap->pDrawable) - exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); - if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) - exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); - if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) - exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); - -out_no_clip: - EXA_POST_FALLBACK(pScreen); -} - -void -ExaCheckAddTraps (PicturePtr pPicture, - INT16 x_off, - INT16 y_off, - int ntrap, - xTrap *traps) -{ - ScreenPtr pScreen = pPicture->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - EXA_PRE_FALLBACK(pScreen); - - EXA_FALLBACK(("to pict %p (%c)\n", - exaDrawableLocation(pPicture->pDrawable))); - exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); - swap(pExaScr, ps, AddTraps); - ps->AddTraps (pPicture, x_off, y_off, ntrap, traps); - swap(pExaScr, ps, AddTraps); - exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK(pScreen); -} - -/** - * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps - * that happen to be 1x1. Pixmap must be at least 8bpp. - */ -CARD32 -exaGetPixmapFirstPixel (PixmapPtr pPixmap) -{ - switch (pPixmap->drawable.bitsPerPixel) { - case 32: - { - CARD32 pixel; - - pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, - ZPixmap, ~0, (char*)&pixel); - return pixel; - } - case 16: - { - CARD16 pixel; - - pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, - ZPixmap, ~0, (char*)&pixel); - return pixel; - } - case 8: - { - CARD8 pixel; - - pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, - ZPixmap, ~0, (char*)&pixel); - return pixel; - } - default: - FatalError("%s called for invalid bpp %d\n", __func__, - pPixmap->drawable.bitsPerPixel); - } -} +/*
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "exa_priv.h"
+
+#include "mipict.h"
+
+/*
+ * These functions wrap the low-level fb rendering functions and
+ * synchronize framebuffer/accelerated drawing by stalling until
+ * the accelerator is idle
+ */
+
+/**
+ * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the
+ * current fill style.
+ *
+ * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
+ * 1bpp and never in fb, so we don't worry about them.
+ * We should worry about them for completeness sake and going forward.
+ */
+void
+exaPrepareAccessGC(GCPtr pGC)
+{
+ if (pGC->stipple)
+ exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
+ if (pGC->fillStyle == FillTiled)
+ exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+}
+
+/**
+ * Finishes access to the tile in the GC, if used.
+ */
+void
+exaFinishAccessGC(GCPtr pGC)
+{
+ if (pGC->fillStyle == FillTiled)
+ exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+ if (pGC->stipple)
+ exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
+}
+
+#if DEBUG_TRACE_FALL
+char
+exaDrawableLocation(DrawablePtr pDrawable)
+{
+ return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm';
+}
+#endif /* DEBUG_TRACE_FALL */
+
+void
+ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *bits)
+{
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ ExaPixmapPriv(pPixmap);
+
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
+ exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
+ pGC->alu, pGC->clientClipType))
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ else
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
+ DamagePendingRegion(pExaPixmap->pDamage));
+ pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
+ Bool upsidedown, Pixel bitplane, void *closure)
+{
+ RegionRec reg;
+ int xoff, yoff;
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+
+ if (pExaScr->prepare_access_reg) {
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
+
+ exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+ REGION_INIT(pScreen, ®, pbox, nbox);
+ REGION_TRANSLATE(pScreen, ®, xoff + dx, yoff + dy);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®);
+ REGION_UNINIT(pScreen, ®);
+ } else
+ exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+
+ if (pExaScr->prepare_access_reg &&
+ !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
+ pGC->alu, pGC->clientClipType)) {
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
+
+ exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+ REGION_INIT(pScreen, ®, pbox, nbox);
+ REGION_TRANSLATE(pScreen, ®, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®);
+ REGION_UNINIT(pScreen, ®);
+ } else
+ exaPrepareAccess (pDst, EXA_PREPARE_DEST);
+
+ /* This will eventually call fbCopyNtoN, with some calculation overhead. */
+ while (nbox--) {
+ pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y);
+ pbox++;
+ }
+ exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+static void
+ExaFallbackPrepareReg(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y, int width, int height,
+ int index, Bool checkReads)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ExaScreenPriv(pScreen);
+
+ if (pExaScr->prepare_access_reg &&
+ !(checkReads && exaGCReadsDestination(pDrawable,
+ pGC->planemask,
+ pGC->fillStyle,
+ pGC->alu,
+ pGC->clientClipType))) {
+ BoxRec box;
+ RegionRec reg;
+ int xoff, yoff;
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ box.x1 = pDrawable->x + x + xoff;
+ box.y1 = pDrawable->y + y + yoff;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ REGION_INIT(pScreen, ®, &box, 1);
+ pExaScr->prepare_access_reg(pPixmap, index, ®);
+ REGION_UNINIT(pScreen, ®);
+ } else
+ exaPrepareAccess(pDrawable, index);
+}
+
+
+RegionPtr
+ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty)
+{
+ RegionPtr ret;
+
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+ ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
+ EXA_PREPARE_DEST, TRUE);
+ ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+ exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+
+ return ret;
+}
+
+RegionPtr
+ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty,
+ unsigned long bitPlane)
+{
+ RegionPtr ret;
+
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+ ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
+ EXA_PREPARE_DEST, TRUE);
+ ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
+ bitPlane);
+ exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+
+ return ret;
+}
+
+void
+ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr ppt)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
+ pDrawable, exaDrawableLocation(pDrawable),
+ pGC->lineWidth, mode, npt));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
+ int nsegInit, xSegment *pSegInit)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
+ exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *pArcs)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrect, xRectangle *prect)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable,
+ exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
+ exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int w, int h, int x, int y)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
+ exaDrawableLocation(&pBitmap->drawable),
+ exaDrawableLocation(pDrawable)));
+ ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h,
+ EXA_PREPARE_DEST, TRUE);
+ ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ DrawablePtr pDrawable = &pWin->drawable;
+ ScreenPtr pScreen = pDrawable->pScreen;
+ EXA_PRE_FALLBACK(pScreen);
+ EXA_FALLBACK(("from %p\n", pWin));
+
+ /* Only need the source bits, the destination region will be overwritten */
+ if (pExaScr->prepare_access_reg) {
+ PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, prgnSrc, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
+ REGION_TRANSLATE(pScreen, prgnSrc, -xoff, -yoff);
+ } else
+ exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+
+ swap(pExaScr, pScreen, CopyWindow);
+ pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
+ swap(pExaScr, pScreen, CopyWindow);
+ exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+void
+ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ EXA_PRE_FALLBACK(pScreen);
+ EXA_FALLBACK(("from %p (%c)\n", pDrawable,
+ exaDrawableLocation(pDrawable)));
+
+ ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ swap(pExaScr, pScreen, GetImage);
+ pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
+ swap(pExaScr, pScreen, GetImage);
+ exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+void
+ExaCheckGetSpans (DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ EXA_PRE_FALLBACK(pScreen);
+ EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
+ swap(pExaScr, pScreen, GetSpans);
+ pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+ swap(pExaScr, pScreen, GetSpans);
+ exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+static void
+ExaSrcValidate(DrawablePtr pDrawable,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ExaScreenPriv(pScreen);
+ PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr dst;
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
+
+ box.x1 = x + xoff;
+ box.y1 = y + yoff;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg :
+ &pExaScr->maskReg;
+
+ REGION_INIT(pScreen, ®, &box, 1);
+ REGION_UNION(pScreen, dst, dst, ®);
+ REGION_UNINIT(pScreen, ®);
+
+ if (pExaScr->SavedSourceValidate) {
+ swap(pExaScr, pScreen, SourceValidate);
+ pScreen->SourceValidate(pDrawable, x, y, width, height);
+ swap(pExaScr, pScreen, SourceValidate);
+ }
+}
+
+static Bool
+ExaPrepareCompositeReg(ScreenPtr pScreen,
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ RegionRec region;
+ RegionPtr dstReg = NULL;
+ RegionPtr srcReg = NULL;
+ RegionPtr maskReg = NULL;
+ PixmapPtr pSrcPix = NULL;
+ PixmapPtr pMaskPix = NULL;
+ PixmapPtr pDstPix;
+ ExaScreenPriv(pScreen);
+ Bool ret;
+
+
+ REGION_NULL(pScreen, ®ion);
+
+ if (pSrc->pDrawable) {
+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ REGION_NULL(pScreen, &pExaScr->srcReg);
+ srcReg = &pExaScr->srcReg;
+ pExaScr->srcPix = pSrcPix;
+ if (pSrc != pDst)
+ REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
+ -pSrc->pDrawable->x,
+ -pSrc->pDrawable->y);
+ }
+
+ if (pMask && pMask->pDrawable) {
+ pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+ REGION_NULL(pScreen, &pExaScr->maskReg);
+ maskReg = &pExaScr->maskReg;
+ if (pMask != pDst && pMask != pSrc)
+ REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
+ -pMask->pDrawable->x,
+ -pMask->pDrawable->y);
+ }
+
+ REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
+ -pDst->pDrawable->x,
+ -pDst->pDrawable->y);
+
+ pExaScr->SavedSourceValidate = ExaSrcValidate;
+ swap(pExaScr, pScreen, SourceValidate);
+ ret = miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask,
+ xDst,
+ yDst,
+ width, height);
+ swap(pExaScr, pScreen, SourceValidate);
+
+ REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
+ pDst->pDrawable->x,
+ pDst->pDrawable->y);
+ if (pSrc->pDrawable && pSrc != pDst)
+ REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
+ pSrc->pDrawable->x,
+ pSrc->pDrawable->y);
+ if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc)
+ REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
+ pMask->pDrawable->x,
+ pMask->pDrawable->y);
+
+ if (!ret) {
+ if (srcReg)
+ REGION_UNINIT(pScreen, srcReg);
+ if (maskReg)
+ REGION_UNINIT(pScreen, maskReg);
+
+ return FALSE;
+ }
+
+ /**
+ * Don't limit alphamaps readbacks for now until we've figured out how that
+ * should be done.
+ */
+
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_SRC,
+ NULL);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_MASK,
+ NULL);
+
+ if (pSrcPix)
+ pExaScr->prepare_access_reg(pSrcPix,
+ EXA_PREPARE_SRC,
+ srcReg);
+
+ if (pMaskPix)
+ pExaScr->prepare_access_reg(pMaskPix,
+ EXA_PREPARE_MASK,
+ maskReg);
+
+ if (srcReg)
+ REGION_UNINIT(pScreen, srcReg);
+ if (maskReg)
+ REGION_UNINIT(pScreen, maskReg);
+
+ pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
+ if (!exaOpReadsDestination(op)) {
+ int xoff;
+ int yoff;
+
+ exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, ®ion, pDst->pDrawable->x + xoff,
+ pDst->pDrawable->y + yoff);
+ dstReg = ®ion;
+ }
+
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_DEST,
+ dstReg);
+ pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg);
+
+ REGION_UNINIT(pScreen, ®ion);
+ return TRUE;
+}
+
+void
+ExaCheckComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ EXA_PRE_FALLBACK(pScreen);
+
+ if (pExaScr->prepare_access_reg) {
+ if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
+ ySrc, xMask, yMask, xDst, yDst, width,
+ height))
+ goto out_no_clip;
+ } else {
+
+ /* We need to prepare access to any separate alpha maps first,
+ * in case the driver doesn't support EXA_PREPARE_AUX*,
+ * in which case EXA_PREPARE_SRC may be used for moving them out.
+ */
+
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
+
+ exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+
+ EXA_FALLBACK(("from picts %p/%p to pict %p\n",
+ pSrc, pMask, pDst));
+
+ if (pSrc->pDrawable != NULL)
+ exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+ if (pMask && pMask->pDrawable != NULL)
+ exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ }
+
+ swap(pExaScr, ps, Composite);
+ ps->Composite (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ swap(pExaScr, ps, Composite);
+ if (pMask && pMask->pDrawable != NULL)
+ exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ if (pSrc->pDrawable != NULL)
+ exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
+
+out_no_clip:
+ EXA_POST_FALLBACK(pScreen);
+}
+
+/**
+ * Avoid migration ping-pong when using a mask.
+ */
+void
+ExaCheckGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ EXA_PRE_FALLBACK(pScreen);
+
+ miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+
+ EXA_POST_FALLBACK(pScreen);
+}
+
+void
+ExaCheckAddTraps (PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off,
+ int ntrap,
+ xTrap *traps)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ EXA_PRE_FALLBACK(pScreen);
+
+ EXA_FALLBACK(("to pict %p (%c)\n",
+ exaDrawableLocation(pPicture->pDrawable)));
+ exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+ swap(pExaScr, ps, AddTraps);
+ ps->AddTraps (pPicture, x_off, y_off, ntrap, traps);
+ swap(pExaScr, ps, AddTraps);
+ exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+/**
+ * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps
+ * that happen to be 1x1. Pixmap must be at least 8bpp.
+ */
+CARD32
+exaGetPixmapFirstPixel (PixmapPtr pPixmap)
+{
+ switch (pPixmap->drawable.bitsPerPixel) {
+ case 32:
+ {
+ CARD32 pixel;
+
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char*)&pixel);
+ return pixel;
+ }
+ case 16:
+ {
+ CARD16 pixel;
+
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char*)&pixel);
+ return pixel;
+ }
+ case 8:
+ {
+ CARD8 pixel;
+
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char*)&pixel);
+ return pixel;
+ }
+ default:
+ FatalError("%s called for invalid bpp %d\n", __func__,
+ pPixmap->drawable.bitsPerPixel);
+ }
+}
diff --git a/xorg-server/hw/dmx/doc/Makefile.am b/xorg-server/hw/dmx/doc/Makefile.am index ef7c23da1..58cb27c17 100644 --- a/xorg-server/hw/dmx/doc/Makefile.am +++ b/xorg-server/hw/dmx/doc/Makefile.am @@ -1,290 +1,267 @@ -# Copyright 2005 Red Hat, Inc. -# -# Permission to use, copy, modify, distribute, and sell this software -# and its documentation for any purpose is hereby granted without -# fee, provided that the above copyright notice appear in all copies -# and that both that copyright notice and this permission notice -# appear in supporting documentation, and that the name of Red Hat -# not be used in advertising or publicity pertaining to distribution -# of the software without specific, written prior permission. Red -# Hat makes no representations about the suitability of this software -# for any purpose. It is provided "as is" without express or implied -# warranty. -# -# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -# NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR -# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -SGML_FILES = dmx.sgml scaled.sgml - -if BUILD_LINUXDOC -TXT_FILES = $(SGML_FILES:%.sgml=%.txt) -PS_FILES = $(SGML_FILES:%.sgml=%.ps) -if BUILD_PDFDOC -PDF_FILES = $(SGML_FILES:%.sgml=%.pdf) -endif -HTML_FILES = $(SGML_FILES:%.sgml=%.html) - -SUFFIXES = .sgml .txt .html .ps .pdf - -.sgml.txt: - @rm -f $@ - $(AM_V_GEN)$(MAKE_TEXT) $< - -.sgml.ps: - @rm -f $@ - $(AM_V_GEN)$(MAKE_PS) $< - -.ps.pdf: - @rm -f $@ - $(AM_V_GEN)$(MAKE_PDF) $< - -.sgml.html: - @rm -f $@ - $(AM_V_GEN)$(MAKE_HTML) $< - -noinst_DATA = $(TXT_FILES) $(PS_FILES) $(PDF_FILES) $(HTML_FILES) -CLEANFILES = $(TXT_FILES) $(PS_FILES) $(PDF_FILES) $(HTML_FILES) -endif - -if HAVE_DOXYGEN - -DOXYGEN_SRC=doxygen.head doxygen.foot doxygen.css doxygen.conf - -all-local: html/annotated.html - -dist-local: html/annotated.html - -html/annotated.html: $(DOXYGEN_SRC) - $(DOXYGEN) $(srcdir)/doxygen.conf - -maintainer-clean-local: - rm -rf html/ -endif - -EXTRA_DIST = \ - $(SGML_FILES) \ - DMXSpec.txt \ - DMXSpec-v1.txt \ - dmx.txt \ - doxygen.conf \ - doxygen.css \ - doxygen.foot \ - doxygen.head \ - scaled.txt \ - html/annotated.html \ - html/ChkNotMaskEv_8c.html \ - html/ChkNotMaskEv_8h.html \ - html/ChkNotMaskEv_8h_source.html \ - html/classes.html \ - html/dmx_8h.html \ - html/dmx_8h_source.html \ - html/dmxarg_8c.html \ - html/dmxarg_8h.html \ - html/dmxarg_8h_source.html \ - html/dmxbackend_8c.html \ - html/dmxbackend_8h.html \ - html/dmxbackend_8h_source.html \ - html/dmxcb_8c.html \ - html/dmxcb_8h.html \ - html/dmxcb_8h_source.html \ - html/dmxclient_8h.html \ - html/dmxclient_8h_source.html \ - html/dmxcmap_8c.html \ - html/dmxcmap_8h.html \ - html/dmxcmap_8h_source.html \ - html/dmxcommon_8c.html \ - html/dmxcommon_8h.html \ - html/dmxcommon_8h_source.html \ - html/dmxcompat_8c.html \ - html/dmxcompat_8h.html \ - html/dmxcompat_8h_source.html \ - html/dmxconfig_8c.html \ - html/dmxconfig_8h.html \ - html/dmxconfig_8h_source.html \ - html/dmxconsole_8c.html \ - html/dmxconsole_8h.html \ - html/dmxconsole_8h_source.html \ - html/dmxcursor_8c.html \ - html/dmxcursor_8h.html \ - html/dmxcursor_8h_source.html \ - html/dmxdetach_8c.html \ - html/dmxdpms_8c.html \ - html/dmxdpms_8h.html \ - html/dmxdpms_8h_source.html \ - html/dmxdummy_8c.html \ - html/dmxdummy_8h.html \ - html/dmxdummy_8h_source.html \ - html/dmxevents_8c.html \ - html/dmxevents_8h.html \ - html/dmxevents_8h_source.html \ - html/dmxextension_8c.html \ - html/dmxextension_8h.html \ - html/dmxextension_8h_source.html \ - html/dmxfont_8c.html \ - html/dmxfont_8h.html \ - html/dmxfont_8h_source.html \ - html/dmxgc_8c.html \ - html/dmxgc_8h.html \ - html/dmxgc_8h_source.html \ - html/dmxgcops_8c.html \ - html/dmxgcops_8h.html \ - html/dmxgcops_8h_source.html \ - html/dmx__glxvisuals_8h_source.html \ - html/dmxinit_8c.html \ - html/dmxinit_8h.html \ - html/dmxinit_8h_source.html \ - html/dmxinput_8c.html \ - html/dmxinput_8h.html \ - html/dmxinput_8h_source.html \ - html/dmxinputinit_8c.html \ - html/dmxinputinit_8h.html \ - html/dmxinputinit_8h_source.html \ - html/dmxlog_8c.html \ - html/dmxlog_8h.html \ - html/dmxlog_8h_source.html \ - html/dmxmap_8c.html \ - html/dmxmap_8h.html \ - html/dmxmap_8h_source.html \ - html/dmxmotion_8c.html \ - html/dmxmotion_8h.html \ - html/dmxmotion_8h_source.html \ - html/dmxparse_8c.html \ - html/dmxparse_8h.html \ - html/dmxparse_8h_source.html \ - html/dmxpict_8c.html \ - html/dmxpict_8h.html \ - html/dmxpict_8h_source.html \ - html/dmxpixmap_8c.html \ - html/dmxpixmap_8h.html \ - html/dmxpixmap_8h_source.html \ - html/dmxprint_8c.html \ - html/dmxprint_8h.html \ - html/dmxprint_8h_source.html \ - html/dmxprop_8c.html \ - html/dmxprop_8h.html \ - html/dmxprop_8h_source.html \ - html/dmxscrinit_8c.html \ - html/dmxscrinit_8h.html \ - html/dmxscrinit_8h_source.html \ - html/dmxshadow_8c.html \ - html/dmxshadow_8h.html \ - html/dmxshadow_8h_source.html \ - html/dmxsigio_8c.html \ - html/dmxsigio_8h.html \ - html/dmxsigio_8h_source.html \ - html/dmxstat_8c.html \ - html/dmxstat_8h.html \ - html/dmxstat_8h_source.html \ - html/dmxsync_8c.html \ - html/dmxsync_8h.html \ - html/dmxsync_8h_source.html \ - html/dmxvisual_8c.html \ - html/dmxvisual_8h.html \ - html/dmxvisual_8h_source.html \ - html/dmxwindow_8c.html \ - html/dmxwindow_8h.html \ - html/dmxwindow_8h_source.html \ - html/dmxxinput_8c.html \ - html/doxygen.css \ - html/doxygen.png \ - html/files.html \ - html/ftv2blank.png \ - html/ftv2doc.png \ - html/ftv2folderclosed.png \ - html/ftv2folderopen.png \ - html/ftv2lastnode.png \ - html/ftv2link.png \ - html/ftv2mlastnode.png \ - html/ftv2mnode.png \ - html/ftv2node.png \ - html/ftv2plastnode.png \ - html/ftv2pnode.png \ - html/ftv2vertline.png \ - html/functions.html \ - html/functions_vars.html \ - html/globals_defs.html \ - html/globals_enum.html \ - html/globals_eval.html \ - html/globals_func.html \ - html/globals.html \ - html/globals_type.html \ - html/globals_vars.html \ - html/index.html \ - html/lnx-keyboard_8c.html \ - html/lnx-keyboard_8h.html \ - html/lnx-keyboard_8h_source.html \ - html/lnx-ms_8c.html \ - html/lnx-ms_8h.html \ - html/lnx-ms_8h_source.html \ - html/lnx-ps2_8c.html \ - html/lnx-ps2_8h.html \ - html/lnx-ps2_8h_source.html \ - html/main.html \ - html/struct__dmxArg.html \ - html/struct__dmxColormapPriv.html \ - html/structDMXConfigCmdStruct.html \ - html/struct__DMXConfigComment.html \ - html/struct__DMXConfigDisplay.html \ - html/struct__DMXConfigEntry.html \ - html/struct__DMXConfigFullDim.html \ - html/structDMXConfigListStruct.html \ - html/struct__DMXConfigNumber.html \ - html/struct__DMXConfigOption.html \ - html/struct__DMXConfigPair.html \ - html/struct__DMXConfigParam.html \ - html/struct__DMXConfigPartDim.html \ - html/struct__DMXConfigString.html \ - html/struct__DMXConfigSub.html \ - html/struct__DMXConfigToken.html \ - html/struct__DMXConfigVirtual.html \ - html/struct__DMXConfigWall.html \ - html/struct__dmxCursorPriv.html \ - html/structDMXDesktopAttributesRec.html \ - html/struct__DMXEventMap.html \ - html/struct__dmxFontPriv.html \ - html/struct__dmxGCPriv.html \ - html/structdmxGlxVisualPrivate.html \ - html/struct__dmxGlyphPriv.html \ - html/structDMXInputAttributesRec.html \ - html/struct__DMXInputInfo.html \ - html/struct__DMXLocalInitInfo.html \ - html/struct__DMXLocalInputInfo.html \ - html/struct__dmxPictPriv.html \ - html/struct__dmxPixPriv.html \ - html/structDMXScreenAttributesRec.html \ - html/struct__DMXScreenInfo.html \ - html/struct__DMXStatAvg.html \ - html/struct__DMXStatInfo.html \ - html/structDMXWindowAttributesRec.html \ - html/struct__dmxWinPriv.html \ - html/struct__myPrivate.html \ - html/tree.html \ - html/usb-common_8c.html \ - html/usb-common_8h.html \ - html/usb-common_8h_source.html \ - html/usb-keyboard_8c.html \ - html/usb-keyboard_8h.html \ - html/usb-keyboard_8h_source.html \ - html/usb-mouse_8c.html \ - html/usb-mouse_8h.html \ - html/usb-mouse_8h_source.html \ - html/usb-other_8c.html \ - html/usb-other_8h.html \ - html/usb-other_8h_source.html \ - html/usb-private_8h.html \ - html/usb-private_8h_source.html - -$(builddir)/doxygen.head: - $(LN_S) $(srcdir)/doxygen.head $@ - -$(builddir)/doxygen.foot: - $(LN_S) $(srcdir)/doxygen.foot $@ - -$(builddir)doxygen.css: - $(LN_S) $(srcdir)/doxygen.css $@ - +# Copyright 2005 Red Hat, Inc.
+#
+# Permission to use, copy, modify, distribute, and sell this software
+# and its documentation for any purpose is hereby granted without
+# fee, provided that the above copyright notice appear in all copies
+# and that both that copyright notice and this permission notice
+# appear in supporting documentation, and that the name of Red Hat
+# not be used in advertising or publicity pertaining to distribution
+# of the software without specific, written prior permission. Red
+# Hat makes no representations about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied
+# warranty.
+#
+# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+# NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+XML_FILES = dmx.xml scaled.xml
+
+include ../../../doc/xml/xmlrules.in
+
+if ENABLE_DEVEL_DOCS
+noinst_DATA = $(BUILT_DOC_FILES)
+endif
+CLEANFILES = $(CLEAN_DOC_FILES)
+
+if HAVE_DOXYGEN
+
+DOXYGEN_SRC=doxygen.head doxygen.foot doxygen.css doxygen.conf
+
+all-local: html/annotated.html
+
+dist-local: html/annotated.html
+
+html/annotated.html: $(DOXYGEN_SRC)
+ $(DOXYGEN) $(srcdir)/doxygen.conf
+
+maintainer-clean-local:
+ rm -rf html/
+endif
+
+EXTRA_DIST = \
+ $(XML_FILES) \
+ DMXSpec.txt \
+ DMXSpec-v1.txt \
+ dmx.txt \
+ doxygen.conf \
+ doxygen.css \
+ doxygen.foot \
+ doxygen.head \
+ scaled.txt \
+ html/annotated.html \
+ html/ChkNotMaskEv_8c.html \
+ html/ChkNotMaskEv_8h.html \
+ html/ChkNotMaskEv_8h_source.html \
+ html/classes.html \
+ html/dmx_8h.html \
+ html/dmx_8h_source.html \
+ html/dmxarg_8c.html \
+ html/dmxarg_8h.html \
+ html/dmxarg_8h_source.html \
+ html/dmxbackend_8c.html \
+ html/dmxbackend_8h.html \
+ html/dmxbackend_8h_source.html \
+ html/dmxcb_8c.html \
+ html/dmxcb_8h.html \
+ html/dmxcb_8h_source.html \
+ html/dmxclient_8h.html \
+ html/dmxclient_8h_source.html \
+ html/dmxcmap_8c.html \
+ html/dmxcmap_8h.html \
+ html/dmxcmap_8h_source.html \
+ html/dmxcommon_8c.html \
+ html/dmxcommon_8h.html \
+ html/dmxcommon_8h_source.html \
+ html/dmxcompat_8c.html \
+ html/dmxcompat_8h.html \
+ html/dmxcompat_8h_source.html \
+ html/dmxconfig_8c.html \
+ html/dmxconfig_8h.html \
+ html/dmxconfig_8h_source.html \
+ html/dmxconsole_8c.html \
+ html/dmxconsole_8h.html \
+ html/dmxconsole_8h_source.html \
+ html/dmxcursor_8c.html \
+ html/dmxcursor_8h.html \
+ html/dmxcursor_8h_source.html \
+ html/dmxdetach_8c.html \
+ html/dmxdpms_8c.html \
+ html/dmxdpms_8h.html \
+ html/dmxdpms_8h_source.html \
+ html/dmxdummy_8c.html \
+ html/dmxdummy_8h.html \
+ html/dmxdummy_8h_source.html \
+ html/dmxevents_8c.html \
+ html/dmxevents_8h.html \
+ html/dmxevents_8h_source.html \
+ html/dmxextension_8c.html \
+ html/dmxextension_8h.html \
+ html/dmxextension_8h_source.html \
+ html/dmxfont_8c.html \
+ html/dmxfont_8h.html \
+ html/dmxfont_8h_source.html \
+ html/dmxgc_8c.html \
+ html/dmxgc_8h.html \
+ html/dmxgc_8h_source.html \
+ html/dmxgcops_8c.html \
+ html/dmxgcops_8h.html \
+ html/dmxgcops_8h_source.html \
+ html/dmx__glxvisuals_8h_source.html \
+ html/dmxinit_8c.html \
+ html/dmxinit_8h.html \
+ html/dmxinit_8h_source.html \
+ html/dmxinput_8c.html \
+ html/dmxinput_8h.html \
+ html/dmxinput_8h_source.html \
+ html/dmxinputinit_8c.html \
+ html/dmxinputinit_8h.html \
+ html/dmxinputinit_8h_source.html \
+ html/dmxlog_8c.html \
+ html/dmxlog_8h.html \
+ html/dmxlog_8h_source.html \
+ html/dmxmap_8c.html \
+ html/dmxmap_8h.html \
+ html/dmxmap_8h_source.html \
+ html/dmxmotion_8c.html \
+ html/dmxmotion_8h.html \
+ html/dmxmotion_8h_source.html \
+ html/dmxparse_8c.html \
+ html/dmxparse_8h.html \
+ html/dmxparse_8h_source.html \
+ html/dmxpict_8c.html \
+ html/dmxpict_8h.html \
+ html/dmxpict_8h_source.html \
+ html/dmxpixmap_8c.html \
+ html/dmxpixmap_8h.html \
+ html/dmxpixmap_8h_source.html \
+ html/dmxprint_8c.html \
+ html/dmxprint_8h.html \
+ html/dmxprint_8h_source.html \
+ html/dmxprop_8c.html \
+ html/dmxprop_8h.html \
+ html/dmxprop_8h_source.html \
+ html/dmxscrinit_8c.html \
+ html/dmxscrinit_8h.html \
+ html/dmxscrinit_8h_source.html \
+ html/dmxshadow_8c.html \
+ html/dmxshadow_8h.html \
+ html/dmxshadow_8h_source.html \
+ html/dmxsigio_8c.html \
+ html/dmxsigio_8h.html \
+ html/dmxsigio_8h_source.html \
+ html/dmxstat_8c.html \
+ html/dmxstat_8h.html \
+ html/dmxstat_8h_source.html \
+ html/dmxsync_8c.html \
+ html/dmxsync_8h.html \
+ html/dmxsync_8h_source.html \
+ html/dmxvisual_8c.html \
+ html/dmxvisual_8h.html \
+ html/dmxvisual_8h_source.html \
+ html/dmxwindow_8c.html \
+ html/dmxwindow_8h.html \
+ html/dmxwindow_8h_source.html \
+ html/dmxxinput_8c.html \
+ html/doxygen.css \
+ html/doxygen.png \
+ html/files.html \
+ html/ftv2blank.png \
+ html/ftv2doc.png \
+ html/ftv2folderclosed.png \
+ html/ftv2folderopen.png \
+ html/ftv2lastnode.png \
+ html/ftv2link.png \
+ html/ftv2mlastnode.png \
+ html/ftv2mnode.png \
+ html/ftv2node.png \
+ html/ftv2plastnode.png \
+ html/ftv2pnode.png \
+ html/ftv2vertline.png \
+ html/functions.html \
+ html/functions_vars.html \
+ html/globals_defs.html \
+ html/globals_enum.html \
+ html/globals_eval.html \
+ html/globals_func.html \
+ html/globals.html \
+ html/globals_type.html \
+ html/globals_vars.html \
+ html/index.html \
+ html/lnx-keyboard_8c.html \
+ html/lnx-keyboard_8h.html \
+ html/lnx-keyboard_8h_source.html \
+ html/lnx-ms_8c.html \
+ html/lnx-ms_8h.html \
+ html/lnx-ms_8h_source.html \
+ html/lnx-ps2_8c.html \
+ html/lnx-ps2_8h.html \
+ html/lnx-ps2_8h_source.html \
+ html/main.html \
+ html/struct__dmxArg.html \
+ html/struct__dmxColormapPriv.html \
+ html/structDMXConfigCmdStruct.html \
+ html/struct__DMXConfigComment.html \
+ html/struct__DMXConfigDisplay.html \
+ html/struct__DMXConfigEntry.html \
+ html/struct__DMXConfigFullDim.html \
+ html/structDMXConfigListStruct.html \
+ html/struct__DMXConfigNumber.html \
+ html/struct__DMXConfigOption.html \
+ html/struct__DMXConfigPair.html \
+ html/struct__DMXConfigParam.html \
+ html/struct__DMXConfigPartDim.html \
+ html/struct__DMXConfigString.html \
+ html/struct__DMXConfigSub.html \
+ html/struct__DMXConfigToken.html \
+ html/struct__DMXConfigVirtual.html \
+ html/struct__DMXConfigWall.html \
+ html/struct__dmxCursorPriv.html \
+ html/structDMXDesktopAttributesRec.html \
+ html/struct__DMXEventMap.html \
+ html/struct__dmxFontPriv.html \
+ html/struct__dmxGCPriv.html \
+ html/structdmxGlxVisualPrivate.html \
+ html/struct__dmxGlyphPriv.html \
+ html/structDMXInputAttributesRec.html \
+ html/struct__DMXInputInfo.html \
+ html/struct__DMXLocalInitInfo.html \
+ html/struct__DMXLocalInputInfo.html \
+ html/struct__dmxPictPriv.html \
+ html/struct__dmxPixPriv.html \
+ html/structDMXScreenAttributesRec.html \
+ html/struct__DMXScreenInfo.html \
+ html/struct__DMXStatAvg.html \
+ html/struct__DMXStatInfo.html \
+ html/structDMXWindowAttributesRec.html \
+ html/struct__dmxWinPriv.html \
+ html/struct__myPrivate.html \
+ html/tree.html \
+ html/usb-common_8c.html \
+ html/usb-common_8h.html \
+ html/usb-common_8h_source.html \
+ html/usb-keyboard_8c.html \
+ html/usb-keyboard_8h.html \
+ html/usb-keyboard_8h_source.html \
+ html/usb-mouse_8c.html \
+ html/usb-mouse_8h.html \
+ html/usb-mouse_8h_source.html \
+ html/usb-other_8c.html \
+ html/usb-other_8h.html \
+ html/usb-other_8h_source.html \
+ html/usb-private_8h.html \
+ html/usb-private_8h_source.html
+
+$(builddir)/doxygen.head:
+ $(LN_S) $(srcdir)/doxygen.head $@
+
+$(builddir)/doxygen.foot:
+ $(LN_S) $(srcdir)/doxygen.foot $@
+
+$(builddir)doxygen.css:
+ $(LN_S) $(srcdir)/doxygen.css $@
+
diff --git a/xorg-server/hw/dmx/doc/dmx.sgml b/xorg-server/hw/dmx/doc/dmx.xml index 4342c2fce..06716d1d7 100644 --- a/xorg-server/hw/dmx/doc/dmx.sgml +++ b/xorg-server/hw/dmx/doc/dmx.xml @@ -1,30 +1,39 @@ -<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
- <article>
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+]>
+<article>
+
+ <articleinfo>
<!-- Title information -->
- <title>Distributed Multihead X design
- <author>Kevin E. Martin, David H. Dawes, and Rickard E. Faith
- <date>29 June 2004 (created 25 July 2001)
- <abstract>
+ <title>Distributed Multihead X design</title>
+ <authorgroup>
+ <author><firstname>Kevin E.</firstname><surname>Martin</surname></author>
+ <author><firstname>David H.</firstname><surname>Dawes</surname></author>
+ <author><firstname>Rickard E.</firstname><surname>Faith</surname></author>
+ </authorgroup>
+ <pubdate>29 June 2004 (created 25 July 2001)</pubdate>
+ <abstract><para>
This document covers the motivation, background, design, and
implementation of the distributed multihead X (DMX) system. It
is a living document and describes the current design and
implementation details of the DMX system. As the project
progresses, this document will be continually updated to reflect
- the changes in the code and/or design. <it>Copyright 2001 by VA
+ the changes in the code and/or design. <emphasis remap="it">Copyright 2001 by VA
Linux Systems, Inc., Fremont, California. Copyright 2001-2004
- by Red Hat, Inc., Raleigh, North Carolina</it>
- </abstract>
-
- <!-- Table of contents -->
- <toc>
+ by Red Hat, Inc., Raleigh, North Carolina</emphasis>
+ </para></abstract>
+ </articleinfo>
<!-- Begin the document -->
-<sect>Introduction
+<sect1>
+<title>Introduction</title>
-<sect1>The Distributed Multihead X Server
+<sect2>
+<title>The Distributed Multihead X Server</title>
-<p>Current Open Source multihead solutions are limited to a single
+<para>Current Open Source multihead solutions are limited to a single
physical machine. A single X server controls multiple display devices,
which can be arranged as independent heads or unified into a single
desktop (with Xinerama). These solutions are limited to the number of
@@ -35,8 +44,9 @@ paper will eliminate the requirement that the display devices reside in the same physical machine. This will be accomplished by developing a
front-end proxy X server that will control multiple back-end X servers
that make up the large display.
+</para>
-<p>The overall structure of the distributed multihead X (DMX) project is
+<para>The overall structure of the distributed multihead X (DMX) project is
as follows: A single front-end X server will act as a proxy to a set of
back-end X servers, which handle all of the visible rendering. X
clients will connect to the front-end server just as they normally would
@@ -47,13 +57,15 @@ standard X clients will continue to operate without modification server). Clients that are DMX-aware will be able to use an extension to
obtain information about the back-end servers (e.g., for placement of
pop-up windows, window alignments by the window manager, etc.).
+</para>
-<p>The architecture of the DMX server is divided into two main sections:
+<para>The architecture of the DMX server is divided into two main sections:
input (e.g., mouse and keyboard events) and output (e.g., rendering and
windowing requests). Each of these are describe briefly below, and the
rest of this design document will describe them in greater detail.
+</para>
-<p>The DMX server can receive input from three general types of input
+<para>The DMX server can receive input from three general types of input
devices: "local" devices that are physically attached to the machine on
which DMX is running, "backend" devices that are physically attached to
one or more of the back-end X servers (and that generate events via the
@@ -62,8 +74,9 @@ abstracted from any non-back-end X server. Backend and console devices are treated differently because the pointer device on the back-end X
server also controls the location of the hardware X cursor. Full
support for XInput extension devices is provided.
+</para>
-<p>Rendering requests will be accepted by the front-end server; however,
+<para>Rendering requests will be accepted by the front-end server; however,
rendering to visible windows will be broken down as needed and sent to
the appropriate back-end server(s) via X11 library calls for actual
rendering. The basic framework will follow a Xnest-style approach. GC
@@ -75,34 +88,44 @@ front-end server. If the request requires a visible change, the windowing operation will be translated into requests for the appropriate
back-end server(s). Window state will be mirrored in the back-end
server(s) as needed.
+</para>
+</sect2>
-<sect1>Layout of Paper
+<sect2>
+<title>Layout of Paper</title>
-<p>The next section describes the general development plan that was
+<para>The next section describes the general development plan that was
actually used for implementation. The final section discusses
outstanding issues at the conclusion of development. The first appendix
provides low-level technical detail that may be of interest to those
intimately familiar with the X server architecture. The final appendix
describes the four phases of development that were performed during the
first two years of development.
+</para>
-<p>The final year of work was divided into 9 tasks that are not
+<para>The final year of work was divided into 9 tasks that are not
described in specific sections of this document. The major tasks during
that time were the enhancement of the reconfiguration ability added in
Phase IV, addition of support for a dynamic number of back-end displays
(instead of a hard-coded limit), and the support for back-end display
and input removal and addition. This work is mentioned in this paper,
but is not covered in detail.
+</para>
+</sect2>
+</sect1>
<!-- ============================================================ -->
-<sect>Development plan
+<sect1>
+<title>Development plan</title>
-<p>This section describes the development plan from approximately June
+<para>This section describes the development plan from approximately June
2001 through July 2003.
+</para>
-<sect1>Bootstrap code
+<sect2>
+<title>Bootstrap code</title>
-<p>To allow for rapid development of the DMX server by multiple
+<para>To allow for rapid development of the DMX server by multiple
developers during the first development stage, the problem will be
broken down into three tasks: the overall DMX framework, back-end
rendering services and input device handling services. However, before
@@ -112,31 +135,38 @@ framework renders to a single back-end server and provides dummy input devices (i.e., the keyboard and mouse). The simple back-end rendering
service was implemented using the shadow framebuffer support currently
available in the XFree86 environment.
+</para>
-<p>Using this bootstrapping framework, each developer has been able to
+<para>Using this bootstrapping framework, each developer has been able to
work on each of the tasks listed above independently as follows: the
framework will be extended to handle arbitrary back-end server
configurations; the back-end rendering services will be transitioned to
the more efficient Xnest-style implementation; and, an input device
framework to handle various input devices via the input extension will
be developed.
+</para>
-<p>Status: The boot strap code is complete. <!-- August 2001 -->
+<para>Status: The boot strap code is complete. <!-- August 2001 -->
+</para>
+</sect2>
-<sect1>Input device handling
+<sect2>
+<title>Input device handling</title>
-<p>An X server (including the front-end X server) requires two core
+<para>An X server (including the front-end X server) requires two core
input devices -- a keyboard and a pointer (mouse). These core devices
are handled and required by the core X11 protocol. Additional types of
input devices may be attached and utilized via the XInput extension.
These are usually referred to as ``XInput extension devices'',
+</para>
-<p>There are some options as to how the front-end X server gets its core
+<para>There are some options as to how the front-end X server gets its core
input devices:
-<enum>
- <item>Local Input. The physical input devices (e.g., keyboard and
+<orderedlist>
+<listitem>
+ <para>Local Input. The physical input devices (e.g., keyboard and
mouse) can be attached directly to the front-end X server. In this
case, the keyboard and mouse on the machine running the front-end X
server will be used. The front-end will have drivers to read the
@@ -152,12 +182,14 @@ input devices: implemented and works for a limited number of Linux-specific
devices. Adding additional local input devices for other
architectures is expected to be relatively simple.
+</para>
- <p>The following options are available for implementing local input
+ <para>The following options are available for implementing local input
devices:
- <enum>
- <item>The XFree86 X server has modular input drivers that could
+<orderedlist>
+<listitem>
+ <para>The XFree86 X server has modular input drivers that could
be adapted for this purpose. The mouse driver supports a wide
range of mouse types and interfaces, as well as a range of
Operating System platforms. The keyboard driver in XFree86 is
@@ -169,27 +201,37 @@ input devices: devices across multiple architectures; and rely so heavily on
XFree86-specific helper-functions, that this option was not
pursued.
+</para>
+</listitem>
-
- <item>The <tt/kdrive/ X server in XFree86 has built-in drivers that
+<listitem>
+ <para>The <command>kdrive</command> X server in XFree86 has built-in drivers that
support PS/2 mice and keyboard under Linux. The mouse driver
can indirectly handle other mouse types if the Linux utility
- <tt/gpm/ is used as to translate the native mouse protocol into
+ <command>gpm</command> is used as to translate the native mouse protocol into
PS/2 mouse format. These drivers could be adapted and built in
to the front-end X server if this range of hardware and OS
support is sufficient. While much simpler than the XFree86
- drivers, the <tt/kdrive/ drivers were not used for the DMX
+ drivers, the <command>kdrive</command> drivers were not used for the DMX
implementation.
+</para>
+</listitem>
- <item>Reimplementation of keyboard and mouse drivers from
+<listitem>
+ <para>Reimplementation of keyboard and mouse drivers from
scratch for the DMX framework. Because keyboard and mouse
drivers are relatively trivial to implement, this pathway was
selected. Other drivers in the X source tree were referenced,
and significant contributions from other drivers are noted in
the DMX source code.
- </enum>
-
- <item>Backend Input. The front-end can make use of the core input
+</para>
+</listitem>
+</orderedlist>
+</para>
+</listitem>
+
+<listitem>
+ <para>Backend Input. The front-end can make use of the core input
devices attached to one or more of the back-end X servers. Core
input events from multiple back-ends are merged into a single input
event stream. This can work sanely when only a single set of input
@@ -200,8 +242,11 @@ input devices: mouse on that back-end, core pointers cannot be treated as XInput
extension devices. However, all back-end XInput extensions devices
can be mapped to either DMX core or DMX XInput extension devices.
+</para>
+</listitem>
- <item>Console Input. The front-end server could create a console
+<listitem>
+ <para>Console Input. The front-end server could create a console
window that is displayed on an X server independent of the back-end
X servers. This console window could display things like the
physical screen layout, and the front-end could get its core input
@@ -209,33 +254,45 @@ input devices: implemented and works well. To help the human navigate, window
outlines are also displayed in the console window. Further, console
windows can be used as either core or XInput extension devices.
+</para>
+</listitem>
- <item>Other options were initially explored, but they were all
+<listitem>
+ <para>Other options were initially explored, but they were all
partial subsets of the options listed above and, hence, are
irrelevant.
+</para>
+</listitem>
-</enum>
+</orderedlist>
+</para>
-<p>Although extended input devices are not specifically mentioned in the
+<para>Although extended input devices are not specifically mentioned in the
Distributed X requirements, the options above were all implemented so
that XInput extension devices were supported.
+</para>
-<p>The bootstrap code (Xdmx) had dummy input devices, and these are
+<para>The bootstrap code (Xdmx) had dummy input devices, and these are
still supported in the final version. These do the necessary
initialization to satisfy the X server's requirements for core pointer
and keyboard devices, but no input events are ever generated.
+</para>
-<p>Status: The input code is complete. Because of the complexity of the
+<para>Status: The input code is complete. Because of the complexity of the
XFree86 input device drivers (and their heavy reliance on XFree86
infrastructure), separate low-level device drivers were implemented for
Xdmx. The following kinds of drivers are supported (in general, the
devices can be treated arbitrarily as "core" input devices or as XInput
"extension" devices; and multiple instances of different kinds of
devices can be simultaneously available):
- <enum>
- <item> A "dummy" device drive that never generates events.
-
- <item> "Local" input is from the low-level hardware on which the
+<orderedlist>
+<listitem>
+ <para> A "dummy" device drive that never generates events.
+</para>
+</listitem>
+
+<listitem>
+ <para> "Local" input is from the low-level hardware on which the
Xdmx binary is running. This is the only area where using the
XFree86 driver infrastructure would have been helpful, and then
only partially, since good support for generic USB devices does
@@ -243,22 +300,28 @@ devices can be simultaneously available): code was used where possible). Currently, the following local
devices are supported under Linux (porting to other operating
systems should be fairly straightforward):
- <itemize>
- <item>Linux keyboard
- <item>Linux serial mouse (MS)
- <item>Linux PS/2 mouse
- <item>USB keyboard
- <item>USB mouse
- <item>USB generic device (e.g., joystick, gamepad, etc.)
- </itemize>
-
- <item> "Backend" input is taken from one or more of the back-end
+ <itemizedlist>
+ <listitem><para>Linux keyboard</para></listitem>
+ <listitem><para>Linux serial mouse (MS)</para></listitem>
+ <listitem><para>Linux PS/2 mouse</para></listitem>
+ <listitem><para>USB keyboard</para></listitem>
+ <listitem><para>USB mouse</para></listitem>
+ <listitem><para>USB generic device (e.g., joystick, gamepad, etc.)</para></listitem>
+ </itemizedlist>
+</para>
+</listitem>
+
+<listitem>
+ <para> "Backend" input is taken from one or more of the back-end
displays. In this case, events are taken from the back-end X
server and are converted to Xdmx events. Care must be taken so
that the sprite moves properly on the display from which input
is being taken.
+</para>
+</listitem>
- <item> "Console" input is taken from an X window that Xdmx
+<listitem>
+ <para> "Console" input is taken from an X window that Xdmx
creates on the operator's display (i.e., on the machine running
the Xdmx binary). When the operator's mouse is inside the
console window, then those events are converted to Xdmx events.
@@ -267,27 +330,36 @@ devices can be simultaneously available): navigation), the cursor can be confined to the console, and a
"fine" mode can be activated to allow very precise cursor
positioning.
- </enum>
+</para>
+</listitem>
+</orderedlist>
+</para>
+
+</sect2>
<!-- May 2002; July 2003 -->
-<sect1>Output device handling
+<sect2>
+<title>Output device handling</title>
-<p>The output of the DMX system displays rendering and windowing
+<para>The output of the DMX system displays rendering and windowing
requests across multiple screens. The screens are typically arranged in
a grid such that together they represent a single large display.
+</para>
-<p>The output section of the DMX code consists of two parts. The first
+<para>The output section of the DMX code consists of two parts. The first
is in the front-end proxy X server (Xdmx), which accepts client
connections, manages the windows, and potentially renders primitives but
does not actually display any of the drawing primitives. The second
part is the back-end X server(s), which accept commands from the
front-end server and display the results on their screens.
+</para>
-<sect2>Initialization
+<sect3>
+<title>Initialization</title>
-<p>The DMX front-end must first initialize its screens by connecting to
+<para>The DMX front-end must first initialize its screens by connecting to
each of the back-end X servers and collecting information about each of
these screens. However, the information collected from the back-end X
servers might be inconsistent. Handling these cases can be difficult
@@ -301,38 +373,48 @@ these cases (e.g., in PanoramiXConsolidate()) and will be used as a starting point. In general, the best solution is to use homogeneous X
servers and display devices. Using back-end servers with the same depth
is a requirement of the final DMX implementation.
+</para>
-<p>Once this screen consolidation is finished, the relative position of
+<para>Once this screen consolidation is finished, the relative position of
each back-end X server's screen in the unified screen is initialized. A
full-screen window is opened on each of the back-end X servers, and the
cursor on each screen is turned off. The final DMX implementation can
also make use of a partial-screen window, or multiple windows per
back-end screen.
+</para>
+</sect3>
-<sect2>Handling rendering requests
+<sect3>
+<title>Handling rendering requests</title>
-<p>After initialization, X applications connect to the front-end server.
+<para>After initialization, X applications connect to the front-end server.
There are two possible implementations of how rendering and windowing
requests are handled in the DMX system:
-<enum>
- <item>A shadow framebuffer is used in the front-end server as the
+<orderedlist>
+<listitem>
+ <para>A shadow framebuffer is used in the front-end server as the
render target. In this option, all protocol requests are completely
handled in the front-end server. All state and resources are
maintained in the front-end including a shadow copy of the entire
framebuffer. The framebuffers attached to the back-end servers are
updated by XPutImage() calls with data taken directly from the
shadow framebuffer.
+</para>
- <p>This solution suffers from two main problems. First, it does not
+ <para>This solution suffers from two main problems. First, it does not
take advantage of any accelerated hardware available in the system.
Second, the size of the XPutImage() calls can be quite large and
thus will be limited by the bandwidth available.
+</para>
- <p>The initial DMX implementation used a shadow framebuffer by
+ <para>The initial DMX implementation used a shadow framebuffer by
default.
+</para>
+</listitem>
- <item>Rendering requests are sent to each back-end server for
+<listitem>
+ <para>Rendering requests are sent to each back-end server for
handling (as is done in the Xnest server described above). In this
option, certain protocol requests are handled in the front-end
server and certain requests are repackaged and then sent to the
@@ -341,8 +423,9 @@ requests are handled in the DMX system: on each back-end and can take advantage of any acceleration
available on the back-end servers' graphics display device. State
is maintained both in the front and back-end servers.
+</para>
- <p>This solution suffers from two main drawbacks. First, protocol
+ <para>This solution suffers from two main drawbacks. First, protocol
requests are sent to all back-end servers -- even those that will
completely clip the rendering primitive -- which wastes bandwidth
and processing time. Second, state is maintained both in the front-
@@ -350,26 +433,35 @@ requests are handled in the DMX system: option 1 (above) and can either be overcome through optimizations or
are acceptable. Therefore, this option will be used in the final
implementation.
+</para>
- <p>The final DMX implementation defaults to this mechanism, but also
+ <para>The final DMX implementation defaults to this mechanism, but also
supports the shadow framebuffer mechanism. Several optimizations
were implemented to eliminate the drawbacks of the default
mechanism. These optimizations are described the section below and
in Phase II of the Development Results (see appendix).
+</para>
+</listitem>
-</enum>
+</orderedlist>
+</para>
-<p>Status: Both the shadow framebuffer and Xnest-style code is complete.
+<para>Status: Both the shadow framebuffer and Xnest-style code is complete.
<!-- May 2002 -->
+</para>
+</sect3>
+</sect2>
-<sect1>Optimizing DMX
+<sect2>
+<title>Optimizing DMX</title>
-<p>Initially, the Xnest-style solution's performance will be measured
+<para>Initially, the Xnest-style solution's performance will be measured
and analyzed to determine where the performance bottlenecks exist.
There are four main areas that will be addressed.
+</para>
-<p>First, to obtain reasonable interactivity with the first development
+<para>First, to obtain reasonable interactivity with the first development
phase, XSync() was called after each protocol request. The XSync()
function flushes any pending protocol requests. It then waits for the
back-end to process the request and send a reply that the request has
@@ -379,8 +471,9 @@ development phase, the batching that the X11 library performs is effectively defeated. The XSync() call usage will be analyzed and
optimized by batching calls and performing them at regular intervals,
except where interactivity will suffer (e.g., on cursor movements).
+</para>
-<p>Second, the initial Xnest-style solution described above sends the
+<para>Second, the initial Xnest-style solution described above sends the
repackaged protocol requests to all back-end servers regardless of
whether or not they would be completely clipped out. The requests that
are trivially rejected on the back-end server wastes the limited
@@ -389,26 +482,30 @@ windowing code (e.g., by opening, closing, moving or resizing windows), we can determine whether or not back-end windows are visible so that
trivial tests in the front-end server's GC ops drawing functions can
eliminate these unnecessary protocol requests.
+</para>
-<p>Third, each protocol request will be analyzed to determine if it is
+<para>Third, each protocol request will be analyzed to determine if it is
possible to break the request into smaller pieces at display boundaries.
The initial ones to be analyzed are put and get image requests since
they will require the greatest bandwidth to transmit data between the
front and back-end servers. Other protocol requests will be analyzed
and those that will benefit from breaking them into smaller requests
will be implemented.
+</para>
-<p>Fourth, an extension is being considered that will allow font glyphs to
+<para>Fourth, an extension is being considered that will allow font glyphs to
be transferred from the front-end DMX X server to each back-end server.
This extension will permit the front-end to handle all font requests and
eliminate the requirement that all back-end X servers share the exact
same fonts as the front-end server. We are investigating the
feasibility of this extension during this development phase.
+</para>
-<p>Other potential optimizations will be determined from the performance
+<para>Other potential optimizations will be determined from the performance
analysis.
+</para>
-<p>Please note that in our initial design, we proposed optimizing BLT
+<para>Please note that in our initial design, we proposed optimizing BLT
operations (e.g., XCopyArea() and window moves) by developing an
extension that would allow individual back-end servers to directly copy
pixel data to other back-end servers. This potential optimization was
@@ -423,22 +520,27 @@ with Xinerama. It also eliminates the potential setup problems and security issues resulting from having each back-end server open
connections to all other back-end servers. Therefore, we suggest
accepting Xinerama's expose event solution.
+</para>
-<p>Also note that the approach proposed in the second and third
+<para>Also note that the approach proposed in the second and third
optimizations might cause backing store algorithms in the back-end to be
defeated, so a DMX X server configuration flag will be added to disable
these optimizations.
+</para>
-<p>Status: The optimizations proposed above are complete. It was
+<para>Status: The optimizations proposed above are complete. It was
determined that the using the xfs font server was sufficient and
creating a new mechanism to pass glyphs was redundant; therefore, the
fourth optimization proposed above was not included in DMX.
<!-- September 2002 -->
+</para>
+</sect2>
-<sect1>DMX X extension support
+<sect2>
+<title>DMX X extension support</title>
-<p>The DMX X server keeps track of all the windowing information on the
+<para>The DMX X server keeps track of all the windowing information on the
back-end X servers, but does not currently export this information to
any client applications. An extension will be developed to pass the
screen information and back-end window IDs to DMX-aware clients. These
@@ -448,37 +550,47 @@ clients to break up complex rendering requests on their own and send them directly to the windows on the back-end server's screens. An
example of a client that can make effective use of this extension is
Chromium.
+</para>
-<p>Status: The extension, as implemented, is fully documented in
+<para>Status: The extension, as implemented, is fully documented in
"Client-to-Server DMX Extension to the X Protocol". Future changes
might be required based on feedback and other proposed enhancements to
DMX. Currently, the following facilities are supported:
-<enum>
- <item>
+<orderedlist>
+<listitem><para>
Screen information (clipping rectangle for each screen relative
to the virtual screen)
- <item>
+</para></listitem>
+<listitem><para>
Window information (window IDs and clipping information for each
back-end window that corresponds to each DMX window)
- <item>
+</para></listitem>
+<listitem><para>
Input device information (mappings from DMX device IDs to
back-end device IDs)
- <item>
+</para></listitem>
+<listitem><para>
Force window creation (so that a client can override the
server-side lazy window creation optimization)
- <item>
+</para></listitem>
+<listitem><para>
Reconfiguration (so that a client can request that a screen
position be changed)
- <item>
+</para></listitem>
+<listitem><para>
Addition and removal of back-end servers and back-end and
console inputs.
-</enum>
+</para></listitem>
+</orderedlist>
+</para>
<!-- September 2002; July 2003 -->
+</sect2>
-<sect1>Common X extension support
+<sect2>
+<title>Common X extension support</title>
-<p>The XInput, XKeyboard and Shape extensions are commonly used
+<para>The XInput, XKeyboard and Shape extensions are commonly used
extensions to the base X11 protocol. XInput allows multiple and
non-standard input devices to be accessed simultaneously. These input
devices can be connected to either the front-end or back-end servers.
@@ -486,18 +598,21 @@ XKeyboard allows much better keyboard mappings control. Shape adds support for arbitrarily shaped windows and is used by various window
managers. Nearly all potential back-end X servers make these extensions
available, and support for each one will be added to the DMX system.
+</para>
-<p>In addition to the extensions listed above, support for the X
+<para>In addition to the extensions listed above, support for the X
Rendering extension (Render) is being developed. Render adds digital
image composition to the rendering model used by the X Window System.
While this extension is still under development by Keith Packard of HP,
support for the current version will be added to the DMX system.
+</para>
-<p>Support for the XTest extension was added during the first
+<para>Support for the XTest extension was added during the first
development phase.
+</para>
<!-- WARNING: this list is duplicated in the Phase IV discussion -->
-<p>Status: The following extensions are supported and are discussed in
+<para>Status: The following extensions are supported and are discussed in
more detail in Phase IV of the Development Results (see appendix):
BIG-REQUESTS,
DEC-XTRAP,
@@ -520,16 +635,20 @@ more detail in Phase IV of the Development Results (see appendix): XKEYBOARD, and
XTEST.
<!-- November 2002; updated February 2003, July 2003 -->
+</para>
+</sect2>
-<sect1>OpenGL support
+<sect2>
+<title>OpenGL support</title>
-<p>OpenGL support using the Mesa code base exists in XFree86 release 4
+<para>OpenGL support using the Mesa code base exists in XFree86 release 4
and later. Currently, the direct rendering infrastructure (DRI)
provides accelerated OpenGL support for local clients and unaccelerated
OpenGL support (i.e., software rendering) is provided for non-local
clients.
+</para>
-<p>The single head OpenGL support in XFree86 4.x will be extended to use
+<para>The single head OpenGL support in XFree86 4.x will be extended to use
the DMX system. When the front and back-end servers are on the same
physical hardware, it is possible to use the DRI to directly render to
the back-end servers. First, the existing DRI will be extended to
@@ -540,68 +659,88 @@ existing Xinerama extension or a DMX-specific extension). Support for synchronized swap buffers will also be added (on hardware that supports
it). Note that a single front-end server with a single back-end server
on the same physical machine can emulate accelerated indirect rendering.
+</para>
-<p>When the front and back-end servers are on different physical
+<para>When the front and back-end servers are on different physical
hardware or are using non-XFree86 4.x X servers, a mechanism to render
primitives across the back-end servers will be provided. There are
several options as to how this can be implemented.
+</para>
-<enum>
- <item>The existing OpenGL support in each back-end server can be
+<orderedlist>
+<listitem>
+ <para>The existing OpenGL support in each back-end server can be
used by repackaging rendering primitives and sending them to each
back-end server. This option is similar to the unoptimized
Xnest-style approach mentioned above. Optimization of this solution
is beyond the scope of this project and is better suited to other
distributed rendering systems.
+</para></listitem>
- <item>Rendering to a pixmap in the front-end server using the
+<listitem>
+ <para>Rendering to a pixmap in the front-end server using the
current XFree86 4.x code, and then displaying to the back-ends via
calls to XPutImage() is another option. This option is similar to
the shadow frame buffer approach mentioned above. It is slower and
bandwidth intensive, but has the advantage that the back-end servers
are not required to have OpenGL support.
-</enum>
+</para></listitem>
+</orderedlist>
-<p>These, and other, options will be investigated in this phase of the
+<para>These, and other, options will be investigated in this phase of the
work.
+</para>
-<p>Work by others have made Chromium DMX-aware. Chromium will use the
+<para>Work by others have made Chromium DMX-aware. Chromium will use the
DMX X protocol extension to obtain information about the back-end
servers and will render directly to those servers, bypassing DMX.
+</para>
-<p>Status: OpenGL support by the glxProxy extension was implemented by
+<para>Status: OpenGL support by the glxProxy extension was implemented by
SGI and has been integrated into the DMX code base.
+</para>
<!-- May 2003-->
+</sect2>
+</sect1>
<!-- ============================================================ -->
-<sect>Current issues
+<sect1>
+<title>Current issues</title>
-<p>In this sections the current issues are outlined that require further
+<para>In this sections the current issues are outlined that require further
investigation.
+</para>
-<sect1>Fonts
+<sect2>
+<title>Fonts</title>
-<p>The font path and glyphs need to be the same for the front-end and
+<para>The font path and glyphs need to be the same for the front-end and
each of the back-end servers. Font glyphs could be sent to the back-end
servers as necessary but this would consume a significant amount of
available bandwidth during font rendering for clients that use many
different fonts (e.g., Netscape). Initially, the font server (xfs) will
be used to provide the fonts to both the front-end and back-end servers.
Other possibilities will be investigated during development.
+</para>
+</sect2>
-<sect1>Zero width rendering primitives
+<sect2>
+<title>Zero width rendering primitives</title>
-<p>To allow pixmap and on-screen rendering to be pixel perfect, all
+<para>To allow pixmap and on-screen rendering to be pixel perfect, all
back-end servers must render zero width primitives exactly the same as
the front-end renders the primitives to pixmaps. For those back-end
servers that do not exactly match, zero width primitives will be
automatically converted to one width primitives. This can be handled in
the front-end server via the GC state.
+</para>
+</sect2>
-<sect1>Output scaling
+<sect2>
+<title>Output scaling</title>
-<p>With very large tiled displays, it might be difficult to read the
+<para>With very large tiled displays, it might be difficult to read the
information on the standard X desktop. In particular, the cursor can be
easily lost and fonts could be difficult to read. Automatic primitive
scaling might prove to be very useful. We will investigate the
@@ -609,10 +748,13 @@ possibility of scaling the cursor and providing a set of alternate pre-scaled fonts to replace the standard fonts that many applications
use (e.g., fixed). Other options for automatic scaling will also be
investigated.
+</para>
+</sect2>
-<sect1>Per-screen colormaps
+<sect2>
+<title>Per-screen colormaps</title>
-<p>Each screen's default colormap in the set of back-end X servers
+<para>Each screen's default colormap in the set of back-end X servers
should be able to be adjusted via a configuration utility. This support
is would allow the back-end screens to be calibrated via custom gamma
tables. On 24-bit systems that support a DirectColor visual, this type
@@ -620,26 +762,35 @@ of correction can be accommodated. One possible implementation would be to advertise to X client of the DMX server a TrueColor visual while
using DirectColor visuals on the back-end servers to implement this type
of color correction. Other options will be investigated.
+</para>
+</sect2>
+</sect1>
<!-- ============================================================ -->
<appendix>
+<title>Appendix</title>
-<sect>Background
+<sect1>
+<title>Background</title>
-<p>This section describes the existing Open Source architectures that
+<para>This section describes the existing Open Source architectures that
can be used to handle multiple screens and upon which this development
project is based. This section was written before the implementation
was finished, and may not reflect actual details of the implementation.
It is left for historical interest only.
+</para>
-<sect1>Core input device handling
+<sect2>
+<title>Core input device handling</title>
-<p>The following is a description of how core input devices are handled
+<para>The following is a description of how core input devices are handled
by an X server.
+</para>
-<sect2>InitInput()
+<sect3>
+<title>InitInput()</title>
-<p>InitInput() is a DDX function that is called at the start of each
+<para>InitInput() is a DDX function that is called at the start of each
server generation from the X server's main() function. Its purpose is
to determine what input devices are connected to the X server, register
them with the DIX and MI layers, and initialize the input event queue.
@@ -647,19 +798,25 @@ InitInput() does not have a return value, but the X server will abort if either a core keyboard device or a core pointer device are not
registered. Extended input (XInput) devices can also be registered in
InitInput().
+</para>
-<p>InitInput() usually has implementation specific code to determine
+<para>InitInput() usually has implementation specific code to determine
which input devices are available. For each input device it will be
using, it calls AddInputDevice():
-<descrip>
-<tag/AddInputDevice()/ This DIX function allocates the device structure,
+<variablelist>
+<varlistentry>
+<term>AddInputDevice()</term>
+<listitem><para>This DIX function allocates the device structure,
registers a callback function (which handles device init, close, on and
off), and returns the input handle, which can be treated as opaque. It
is called once for each input device.
-</descrip>
+</para></listitem>
+</varlistentry>
+</variablelist>
+</para>
-<p>Once input handles for core keyboard and core pointer devices have
+<para>Once input handles for core keyboard and core pointer devices have
been obtained from AddInputDevice(), they are registered as core devices
by calling RegisterPointerDevice() and RegisterKeyboardDevice(). Each
of these should be called once. If both core devices are not
@@ -667,24 +824,34 @@ registered, then the X server will exit with a fatal error when it attempts to start the input devices in InitAndStartDevices(), which is
called directly after InitInput() (see below).
-<descrip>
-<tag/Register{Pointer,Keyboard}Device()/ These DIX functions take a
+<variablelist>
+<varlistentry>
+<term>Register{Pointer,Keyboard}Device()</term>
+<listitem><para>These DIX functions take a
handle returned from AddInputDevice() and initialize the core input
device fields in inputInfo, and initialize the input processing and grab
functions for each core input device.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>The core pointer device is then registered with the miPointer code
+<para>The core pointer device is then registered with the miPointer code
(which does the high level cursor handling). While this registration
is not necessary for correct miPointer operation in the current XFree86
code, it is still done mostly for compatibility reasons.
+</para>
+
+<para><variablelist>
-<descrip>
-<tag/miRegisterPointerDevice()/ This MI function registers the core
+<varlistentry>
+<term>miRegisterPointerDevice()</term>
+<listitem><para>This MI function registers the core
pointer's input handle with with the miPointer code.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>The final part of InitInput() is the initialization of the input
+<para>The final part of InitInput() is the initialization of the input
event queue handling. In most cases, the event queue handling provided
in the MI layer is used. The primary XFree86 X server uses its own
event queue handling to support some special cases related to the XInput
@@ -692,20 +859,27 @@ extension and the XFree86-specific DGA extension. For our purposes, the MI event queue handling should be suitable. It is initialized by
calling mieqInit():
-<descrip>
-<tag/mieqInit()/ This MI function initializes the MI event queue for the
+<variablelist>
+<varlistentry>
+<term>mieqInit()</term>
+<listitem><para>This MI function initializes the MI event queue for the
core devices, and is passed the public component of the input handles
for the two core devices.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>If a wakeup handler is required to deliver synchronous input
+<para>If a wakeup handler is required to deliver synchronous input
events, it can be registered here by calling the DIX function
RegisterBlockAndWakeupHandlers(). (See the devReadInput() description
below.)
+</para>
+</sect3>
-<sect2>InitAndStartDevices()
+<sect3>
+<title>InitAndStartDevices()</title>
-<p>InitAndStartDevices() is a DIX function that is called immediately
+<para>InitAndStartDevices() is a DIX function that is called immediately
after InitInput() from the X server's main() function. Its purpose is
to initialize each input device that was registered with
AddInputDevice(), enable each input device that was successfully
@@ -715,50 +889,71 @@ devices is checked to make sure that both a core keyboard device and core pointer device were registered and successfully enabled. If not,
InitAndStartDevices() returns failure, and results in the the X server
exiting with a fatal error.
+</para>
-<p>Each registered device is initialized by calling its callback
+<para>Each registered device is initialized by calling its callback
(dev->deviceProc) with the DEVICE_INIT argument:
-<descrip>
-<tag/(*dev->deviceProc)(dev, DEVICE_INIT)/ This function initializes the
+<variablelist>
+<varlistentry>
+<term>(*dev->deviceProc)(dev, DEVICE_INIT)</term>
+<listitem>
+<para>This function initializes the
device structs with core information relevant to the device.
+</para>
-<p>For pointer devices, this means specifying the number of buttons,
+<para>For pointer devices, this means specifying the number of buttons,
default button mapping, the function used to get motion events (usually
miPointerGetMotionEvents()), the function used to change/control the
core pointer motion parameters (acceleration and threshold), and the
motion buffer size.
+</para>
-<p>For keyboard devices, this means specifying the keycode range,
+<para>For keyboard devices, this means specifying the keycode range,
default keycode to keysym mapping, default modifier mapping, and the
functions used to sound the keyboard bell and modify/control the
keyboard parameters (LEDs, bell pitch and duration, key click, which
keys are auto-repeating, etc).
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>Each initialized device is enabled by calling EnableDevice():
+<para>Each initialized device is enabled by calling EnableDevice():
-<descrip>
-<tag/EnableDevice()/ EnableDevice() calls the device callback with
+<variablelist>
+<varlistentry>
+<term>EnableDevice()</term>
+<listitem>
+<para>EnableDevice() calls the device callback with
DEVICE_ON:
- <descrip>
- <tag/(*dev->deviceProc)(dev, DEVICE_ON)/ This typically opens and
+ <variablelist>
+ <varlistentry>
+ <term>(*dev->deviceProc)(dev, DEVICE_ON)</term>
+ <listitem>
+ <para>This typically opens and
initializes the relevant physical device, and when appropriate,
registers the device's file descriptor (or equivalent) as a valid
input source.
- </descrip>
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
- <p>EnableDevice() then adds the device handle to the X server's
+ <para>EnableDevice() then adds the device handle to the X server's
global list of enabled devices.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>InitAndStartDevices() then verifies that a valid core keyboard and
+<para>InitAndStartDevices() then verifies that a valid core keyboard and
pointer has been initialized and enabled. It returns failure if either
are missing.
+</para>
+</sect3>
-<sect2>devReadInput()
+<sect3>
+<title>devReadInput()</title>
-<p>Each device will have some function that gets called to read its
+<para>Each device will have some function that gets called to read its
physical input. These may be called in a number of different ways. In
the case of synchronous I/O, they will be called from a DDX
wakeup-handler that gets called after the server detects that new input is
@@ -769,51 +964,80 @@ enqueued, and make sure that the cursor gets moved for motion events (except if these are handled later by the driver's own event queue
processing function, which cannot be done when using the MI event queue
handling).
+</para>
-<p>Events are queued by calling mieqEnqueue():
+<para>Events are queued by calling mieqEnqueue():
-<descrip>
-<tag/mieqEnqueue()/ This MI function is used to add input events to the
+<variablelist>
+<varlistentry>
+<term>mieqEnqueue()</term>
+<listitem>
+<para>This MI function is used to add input events to the
event queue. It is simply passed the event to be queued.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>The cursor position should be updated when motion events are
+<para>The cursor position should be updated when motion events are
enqueued, by calling either miPointerAbsoluteCursor() or
miPointerDeltaCursor():
-<descrip>
-<tag/miPointerAbsoluteCursor()/ This MI function is used to move the
+<variablelist>
+<varlistentry>
+<term>miPointerAbsoluteCursor()</term>
+<listitem>
+<para>This MI function is used to move the
cursor to the absolute coordinates provided.
-<tag/miPointerDeltaCursor()/ This MI function is used to move the cursor
+</para></listitem></varlistentry>
+<varlistentry>
+<term>miPointerDeltaCursor()</term>
+<listitem>
+<para>This MI function is used to move the cursor
relative to its current position.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+</sect3>
-<sect2>ProcessInputEvents()
+<sect3>
+<title>ProcessInputEvents()</title>
-<p>ProcessInputEvents() is a DDX function that is called from the X
+<para>ProcessInputEvents() is a DDX function that is called from the X
server's main dispatch loop when new events are available in the input
event queue. It typically processes the enqueued events, and updates
the cursor/pointer position. It may also do other DDX-specific event
processing.
+</para>
-<p>Enqueued events are processed by mieqProcessInputEvents() and passed
+<para>Enqueued events are processed by mieqProcessInputEvents() and passed
to the DIX layer for transmission to clients:
-<descrip>
-<tag/mieqProcessInputEvents()/ This function processes each event in the
+<variablelist>
+<varlistentry>
+<term>mieqProcessInputEvents()</term>
+<listitem>
+<para>This function processes each event in the
event queue, and passes it to the device's input processing function.
The DIX layer provides default functions to do this processing, and they
handle the task of getting the events passed back to the relevant
clients.
-<tag/miPointerUpdate()/ This function resynchronized the cursor position
+</para></listitem></varlistentry>
+<varlistentry>
+<term>miPointerUpdate()</term>
+<listitem>
+<para>This function resynchronized the cursor position
with the new pointer position. It also takes care of moving the cursor
between screens when needed in multi-head configurations.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+</sect3>
-<sect2>DisableDevice()
+<sect3>
+<title>DisableDevice()</title>
-<p>DisableDevice is a DIX function that removes an input device from the
+<para>DisableDevice is a DIX function that removes an input device from the
list of enabled devices. The result of this is that the device no
longer generates input events. The device's data structures are kept in
place, and disabling a device like this can be reversed by calling
@@ -821,70 +1045,96 @@ EnableDevice(). DisableDevice() may be called from the DDX when it is desirable to do so (e.g., the XFree86 server does this when VT
switching). Except for special cases, this is not normally called for
core input devices.
+</para>
-<p>DisableDevice() calls the device's callback function with
-<tt/DEVICE_OFF/:
+<para>DisableDevice() calls the device's callback function with
+<constant>DEVICE_OFF</constant>:
-<descrip>
-<tag/(*dev->deviceProc)(dev, DEVICE_OFF)/ This typically closes the
+<variablelist>
+<varlistentry>
+<term>(*dev->deviceProc)(dev, DEVICE_OFF)</term>
+<listitem>
+<para>This typically closes the
relevant physical device, and when appropriate, unregisters the device's
file descriptor (or equivalent) as a valid input source.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>DisableDevice() then removes the device handle from the X server's
+<para>DisableDevice() then removes the device handle from the X server's
global list of enabled devices.
+</para>
+</sect3>
-<sect2>CloseDevice()
+<sect3>
+<title>CloseDevice()</title>
-<p>CloseDevice is a DIX function that removes an input device from the
+<para>CloseDevice is a DIX function that removes an input device from the
list of available devices. It disables input from the device and frees
all data structures associated with the device. This function is
usually called from CloseDownDevices(), which is called from main() at
the end of each server generation to close all input devices.
+</para>
-<p>CloseDevice() calls the device's callback function with
-<tt/DEVICE_CLOSE/:
+<para>CloseDevice() calls the device's callback function with
+<constant>DEVICE_CLOSE</constant>:
-<descrip>
-<tag/(*dev->deviceProc)(dev, DEVICE_CLOSE)/ This typically closes the
+<variablelist>
+<varlistentry>
+<term>(*dev->deviceProc)(dev, DEVICE_CLOSE)</term>
+<listitem>
+<para>This typically closes the
relevant physical device, and when appropriate, unregisters the device's
file descriptor (or equivalent) as a valid input source. If any device
specific data structures were allocated when the device was initialized,
they are freed here.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>CloseDevice() then frees the data structures that were allocated
+<para>CloseDevice() then frees the data structures that were allocated
for the device when it was registered/initialized.
+</para>
+</sect3>
-<sect2>LegalModifier()
-<!-- dmx/dmxinput.c - currently returns TRUE -->
-<p>LegalModifier() is a required DDX function that can be used to
+<sect3>
+<title>LegalModifier()</title>
+<!-- dmx/dmxinput.c - currently returns TRUE -->
+<para>LegalModifier() is a required DDX function that can be used to
restrict which keys may be modifier keys. This seems to be present for
historical reasons, so this function should simply return TRUE
unconditionally.
+</para>
+</sect3>
+</sect2>
-<sect1>Output handling
+<sect2>
+<title>Output handling</title>
-<p>The following sections describe the main functions required to
+<para>The following sections describe the main functions required to
initialize, use and close the output device(s) for each screen in the X
server.
+</para>
-<sect2>InitOutput()
+<sect3>
+<title>InitOutput()</title>
-<p>This DDX function is called near the start of each server generation
+<para>This DDX function is called near the start of each server generation
from the X server's main() function. InitOutput()'s main purpose is to
initialize each screen and fill in the global screenInfo structure for
each screen. It is passed three arguments: a pointer to the screenInfo
struct, which it is to initialize, and argc and argv from main(), which
can be used to determine additional configuration information.
+</para>
-<p>The primary tasks for this function are outlined below:
+<para>The primary tasks for this function are outlined below:
-<enum>
- <item><bf/Parse configuration info:/ The first task of InitOutput()
+<orderedlist>
+<listitem>
+ <para><emphasis remap="bf">Parse configuration info:</emphasis> The first task of InitOutput()
is to parses any configuration information from the configuration
file. In addition to the XF86Config file, other configuration
information can be taken from the command line. The command line
@@ -895,92 +1145,132 @@ can be used to determine additional configuration information. server, the XF86Config file specifies the monitor information, the
screen resolution, the graphics devices and slots in which they are
located, and, for Xinerama, the screens' layout.
+</para>
+</listitem>
- <item><bf/Initialize screen info:/ The next task is to initialize
+<listitem>
+ <para><emphasis remap="bf">Initialize screen info:</emphasis> The next task is to initialize
the screen-dependent internal data structures. For example, part of
what the XFree86 X server does is to allocate its screen and pixmap
private indices, probe for graphics devices, compare the probed
devices to the ones listed in the XF86Config file, and add the ones that
match to the internal xf86Screens[] structure.
+</para>
+</listitem>
- <item><bf/Set pixmap formats:/ The next task is to initialize the
+<listitem>
+ <para><emphasis remap="bf">Set pixmap formats:</emphasis> The next task is to initialize the
screenInfo's image byte order, bitmap bit order and bitmap scanline
unit/pad. The screenInfo's pixmap format's depth, bits per pixel
and scanline padding is also initialized at this stage.
+</para>
+</listitem>
- <item><bf/Unify screen info:/ An optional task that might be done at
+<listitem>
+ <para><emphasis remap="bf">Unify screen info:</emphasis> An optional task that might be done at
this stage is to compare all of the information from the various
screens and determines if they are compatible (i.e., if the set of
screens can be unified into a single desktop). This task has
potential to be useful to the DMX front-end server, if Xinerama's
PanoramiXConsolidate() function is not sufficient.
-</enum>
+</para>
+</listitem>
+</orderedlist>
+</para>
-<p>Once these tasks are complete, the valid screens are known and each
+<para>Once these tasks are complete, the valid screens are known and each
of these screens can be initialized by calling AddScreen().
+</para>
+</sect3>
-<sect2>AddScreen()
+<sect3>
+<title>AddScreen()</title>
-<p>This DIX function is called from InitOutput(), in the DDX layer, to
+<para>This DIX function is called from InitOutput(), in the DDX layer, to
add each new screen to the screenInfo structure. The DDX screen
initialization function and command line arguments (i.e., argc and argv)
are passed to it as arguments.
+</para>
-<p>This function first allocates a new Screen structure and any privates
+<para>This function first allocates a new Screen structure and any privates
that are required. It then initializes some of the fields in the Screen
struct and sets up the pixmap padding information. Finally, it calls
the DDX screen initialization function ScreenInit(), which is described
below. It returns the number of the screen that were just added, or -1
if there is insufficient memory to add the screen or if the DDX screen
initialization fails.
+</para>
+</sect3>
-<sect2>ScreenInit()
+<sect3>
+<title>ScreenInit()</title>
-<p>This DDX function initializes the rest of the Screen structure with
+<para>This DDX function initializes the rest of the Screen structure with
either generic or screen-specific functions (as necessary). It also
fills in various screen attributes (e.g., width and height in
millimeters, black and white pixel values).
+</para>
-<p>The screen init function usually calls several functions to perform
+<para>The screen init function usually calls several functions to perform
certain screen initialization functions. They are described below:
-<descrip>
-<tag/{mi,*fb}ScreenInit()/ The DDX layer's ScreenInit() function usually
+<variablelist>
+<varlistentry>
+<term>{mi,*fb}ScreenInit()</term>
+<listitem>
+<para>The DDX layer's ScreenInit() function usually
calls another layer's ScreenInit() function (e.g., miScreenInit() or
fbScreenInit()) to initialize the fallbacks that the DDX driver does not
specifically handle.
+</para>
-<p>After calling another layer's ScreenInit() function, any
+<para>After calling another layer's ScreenInit() function, any
screen-specific functions either wrap or replace the other layer's
function pointers. If a function is to be wrapped, each of the old
function pointers from the other layer are stored in a screen private
area. Common functions to wrap are CloseScreen() and SaveScreen().
+</para></listitem></varlistentry>
-<tag/miInitializeBackingStore()/ This MI function initializes the
+<varlistentry>
+<term>miInitializeBackingStore()</term>
+<listitem>
+<para>This MI function initializes the
screen's backing storage functions, which are used to save areas of
windows that are currently covered by other windows.
+</para></listitem></varlistentry>
-<tag/miDCInitialize()/ This MI function initializes the MI cursor
+<varlistentry>
+<term>miDCInitialize()</term>
+<listitem>
+<para>This MI function initializes the MI cursor
display structures and function pointers. If a hardware cursor is used,
the DDX layer's ScreenInit() function will wrap additional screen and
the MI cursor display function pointers.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>Another common task for ScreenInit() function is to initialize the
+<para>Another common task for ScreenInit() function is to initialize the
output device state. For example, in the XFree86 X server, the
ScreenInit() function saves the original state of the video card and
then initializes the video mode of the graphics device.
+</para>
+</sect3>
-<sect2>CloseScreen()
+<sect3>
+<title>CloseScreen()</title>
-<p>This function restores any wrapped screen functions (and in
+<para>This function restores any wrapped screen functions (and in
particular the wrapped CloseScreen() function) and restores the state of
the output device to its original state. It should also free any
private data it created during the screen initialization.
+</para>
+</sect3>
-<sect2>GC operations
+<sect3>
+<title>GC operations</title>
-<p>When the X server is requested to render drawing primitives, it does
+<para>When the X server is requested to render drawing primitives, it does
so by calling drawing functions through the graphics context's operation
function pointer table (i.e., the GCOps functions). These functions
render the basic graphics operations such as drawing rectangles, lines,
@@ -988,8 +1278,9 @@ text or copying pixmaps. Default routines are provided either by the MI layer, which draws indirectly through a simple span interface, or by the
framebuffer layers (e.g., CFB, MFB, FB), which draw directly to a
linearly mapped frame buffer.
+</para>
-<p>To take advantage of special hardware on the graphics device,
+<para>To take advantage of special hardware on the graphics device,
specific GCOps functions can be replaced by device specific code.
However, many times the graphics devices can handle only a subset of the
possible states of the GC, so during graphics context validation,
@@ -998,38 +1289,52 @@ the hardware. For example, some graphics hardware can accelerate single pixel width lines with certain dash patterns. Thus, for dash patterns
that are not supported by hardware or for width 2 or greater lines, the
default routine is chosen during GC validation.
+</para>
-<p>Note that some pointers to functions that draw to the screen are
+<para>Note that some pointers to functions that draw to the screen are
stored in the Screen structure. They include GetImage(), GetSpans(),
CopyWindow() and RestoreAreas().
+</para>
+</sect3>
-<sect2>Xnest
+<sect3>
+<title>Xnest</title>
-<p>The Xnest X server is a special proxy X server that relays the X
+<para>The Xnest X server is a special proxy X server that relays the X
protocol requests that it receives to a ``real'' X server that then
processes the requests and displays the results, if applicable. To the X
applications, Xnest appears as if it is a regular X server. However,
Xnest is both server to the X application and client of the real X
server, which will actually handle the requests.
+</para>
-<p>The Xnest server implements all of the standard input and output
+<para>The Xnest server implements all of the standard input and output
initialization steps outlined above.
+</para>
-<descrip>
-<tag/InitOutput()/ Xnest takes its configuration information from
+<para><variablelist>
+<varlistentry>
+<term>InitOutput()</term>
+<listitem>
+<para>Xnest takes its configuration information from
command line arguments via ddxProcessArguments(). This information
includes the real X server display to connect to, its default visual
class, the screen depth, the Xnest window's geometry, etc. Xnest then
connects to the real X server and gathers visual, colormap, depth and
pixmap information about that server's display, creates a window on that
server, which will be used as the root window for Xnest.
+</para>
-<p>Next, Xnest initializes its internal data structures and uses the
+<para>Next, Xnest initializes its internal data structures and uses the
data from the real X server's pixmaps to initialize its own pixmap
formats. Finally, it calls AddScreen(xnestOpenScreen, argc, argv) to
initialize each of its screens.
+</para></listitem></varlistentry>
-<tag/ScreenInit()/ Xnest's ScreenInit() function is called
+<varlistentry>
+<term>ScreenInit()</term>
+<listitem>
+<para>Xnest's ScreenInit() function is called
xnestOpenScreen(). This function initializes its screen's depth and
visual information, and then calls miScreenInit() to set up the default
screen functions. It then calls miInitializeBackingStore() and
@@ -1037,13 +1342,21 @@ miDCInitialize() to initialize backing store and the software cursor. Finally, it replaces many of the screen functions with its own
functions that repackage and send the requests to the real X server to
which Xnest is attached.
+</para></listitem></varlistentry>
-<tag/CloseScreen()/ This function frees its internal data structure
+<varlistentry>
+<term>CloseScreen()</term>
+<listitem>
+<para>This function frees its internal data structure
allocations. Since it replaces instead of wrapping screen functions,
there are no function pointers to unwrap. This can potentially lead to
problems during server regeneration.
+</para></listitem></varlistentry>
-<tag/GC operations/ The GC operations in Xnest are very simple since
+<varlistentry>
+<term>GC operations</term>
+<listitem>
+<para>The GC operations in Xnest are very simple since
they leave all of the drawing to the real X server to which Xnest is
attached. Each of the GCOps takes the request and sends it to the
real X server using standard Xlib calls. For example, the X
@@ -1054,14 +1367,16 @@ function is only a single line, which calls XDrawLines() using the same arguments that were passed into it. Other GCOps functions are very
similar. Two exceptions to the simple GCOps functions described above
are the image functions and the BLT operations.
+</para>
-<p>The image functions, GetImage() and PutImage(), must use a temporary
+<para>The image functions, GetImage() and PutImage(), must use a temporary
image to hold the image to be put of the image that was just grabbed
from the screen while it is in transit to the real X server or the
client. When the image has been transmitted, the temporary image is
destroyed.
+</para>
-<p>The BLT operations, CopyArea() and CopyPlane(), handle not only the
+<para>The BLT operations, CopyArea() and CopyPlane(), handle not only the
copy function, which is the same as the simple cases described above,
but also the graphics exposures that result when the GC's graphics
exposure bit is set to True. Graphics exposures are handled in a helper
@@ -1069,32 +1384,45 @@ function, xnestBitBlitHelper(). This function collects the exposure events from the real X server and, if any resulting in regions being
exposed, then those regions are passed back to the MI layer so that it
can generate exposure events for the X application.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>The Xnest server takes its input from the X server to which it is
+<para>The Xnest server takes its input from the X server to which it is
connected. When the mouse is in the Xnest server's window, keyboard and
mouse events are received by the Xnest server, repackaged and sent back
to any client that requests those events.
+</para>
+</sect3>
-<sect2>Shadow framebuffer
+<sect3>
+<title>Shadow framebuffer</title>
-<p>The most common type of framebuffer is a linear array memory that
+<para>The most common type of framebuffer is a linear array memory that
maps to the video memory on the graphics device. However, accessing
that video memory over an I/O bus (e.g., ISA or PCI) can be slow. The
shadow framebuffer layer allows the developer to keep the entire
framebuffer in main memory and copy it back to video memory at regular
intervals. It also has been extended to handle planar video memory and
rotated framebuffers.
+</para>
-<p>There are two main entry points to the shadow framebuffer code:
+<para>There are two main entry points to the shadow framebuffer code:
-<descrip>
-<tag/shadowAlloc(width, height, bpp)/ This function allocates the in
+<variablelist>
+<varlistentry>
+<term>shadowAlloc(width, height, bpp)</term>
+<listitem>
+<para>This function allocates the in
memory copy of the framebuffer of size width*height*bpp. It returns a
pointer to that memory, which will be used by the framebuffer
ScreenInit() code during the screen's initialization.
+</para></listitem></varlistentry>
-<tag/shadowInit(pScreen, updateProc, windowProc)/ This function
+<varlistentry>
+<term>shadowInit(pScreen, updateProc, windowProc)</term>
+<listitem>
+<para>This function
initializes the shadow framebuffer layer. It wraps several screen
drawing functions, and registers a block handler that will update the
screen. The updateProc is a function that will copy the damaged regions
@@ -1102,21 +1430,28 @@ to the screen, and the windowProc is a function that is used when the entire linear video memory range cannot be accessed simultaneously so
that only a window into that memory is available (e.g., when using the
VGA aperture).
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
-<p>The shadow framebuffer code keeps track of the damaged area of each
+<para>The shadow framebuffer code keeps track of the damaged area of each
screen by calculating the bounding box of all drawing operations that
have occurred since the last screen update. Then, when the block handler
is next called, only the damaged portion of the screen is updated.
+</para>
-<p>Note that since the shadow framebuffer is kept in main memory, all
+<para>Note that since the shadow framebuffer is kept in main memory, all
drawing operations are performed by the CPU and, thus, no accelerated
hardware drawing operations are possible.
+</para>
+</sect3>
+</sect2>
-<sect1>Xinerama
+<sect2>
+<title>Xinerama</title>
-<p>Xinerama is an X extension that allows multiple physical screens
+<para>Xinerama is an X extension that allows multiple physical screens
controlled by a single X server to appear as a single screen. Although
the extension allows clients to find the physical screen layout via
extension requests, it is completely transparent to clients at the core
@@ -1126,33 +1461,43 @@ and improving both X11 core protocol compliance and performance. The Xinerama extension will be passing through X.Org's standardization
process in the near future, and the sample implementation will be based
on this rewritten version.
+</para>
-<p>The current implementation of Xinerama is based primarily in the DIX
+<para>The current implementation of Xinerama is based primarily in the DIX
(device independent) and MI (machine independent) layers of the X
server. With few exceptions the DDX layers do not need any changes to
support Xinerama. X server extensions often do need modifications to
provide full Xinerama functionality.
+</para>
-<p>The following is a code-level description of how Xinerama functions.
+<para>The following is a code-level description of how Xinerama functions.
+</para>
-<p>Note: Because the Xinerama extension was originally called the
+<para>Note: Because the Xinerama extension was originally called the
PanoramiX extension, many of the Xinerama functions still have the
PanoramiX prefix.
+</para>
-<descrip>
- <tag/PanoramiXExtensionInit()/ PanoramiXExtensionInit() is a
+<variablelist>
+<varlistentry>
+<term>PanoramiXExtensionInit()</term>
+<listitem>
+ <para>PanoramiXExtensionInit() is a
device-independent extension function that is called at the start of
each server generation from InitExtensions(), which is called from
the X server's main() function after all output devices have been
initialized, but before any input devices have been initialized.
+ </para>
- <p>PanoramiXNumScreens is set to the number of physical screens. If
+ <para>PanoramiXNumScreens is set to the number of physical screens. If
only one physical screen is present, the extension is disabled, and
PanoramiXExtensionInit() returns without doing anything else.
+ </para>
- <p>The Xinerama extension is registered by calling AddExtension().
-
- <p>A local per-screen array of data structures
+ <para>The Xinerama extension is registered by calling AddExtension().
+ </para>
+
+ <para>A local per-screen array of data structures
(panoramiXdataPtr[])
is allocated for each physical screen, and GC and Screen private
indexes are allocated, and both GC and Screen private areas are
@@ -1162,8 +1507,9 @@ PanoramiX prefix. XineramaCloseScreen() respectively. Some new resource classes are
created for Xinerama drawables and GCs, and resource types for
Xinerama windows, pixmaps and colormaps.
+ </para>
- <p>A region (XineramaScreenRegions[i]) is initialized for each
+ <para>A region (XineramaScreenRegions[i]) is initialized for each
physical screen, and single region (PanoramiXScreenRegion) is
initialized to be the union of the screen regions. The
panoramiXdataPtr[] array is also initialized with the size and
@@ -1173,8 +1519,9 @@ PanoramiX prefix. the DDX layer must initialize in InitOutput(). The bounds of the
combined screen is also calculated (PanoramiXPixWidth and
PanoramiXPixHeight).
+ </para>
- <p>The DIX layer has a list of function pointers
+ <para>The DIX layer has a list of function pointers
(ProcVector[]) that
holds the entry points for the functions that process core protocol
requests. The requests that Xinerama must intercept and break up
@@ -1186,22 +1533,33 @@ PanoramiX prefix. transparently to the DIX layer. Some operations cannot be dealt with
in this way and are handled with Xinerama-specific code within the
DIX layer.
+ </para>
+</listitem></varlistentry>
- <tag/PanoramiXConsolidate()/ PanoramiXConsolidate() is a
+<varlistentry>
+<term>PanoramiXConsolidate()</term>
+<listitem>
+ <para>PanoramiXConsolidate() is a
device-independent extension function that is called directly from
the X server's main() function after extensions and input/output
devices have been initialized, and before the root windows are
defined and initialized.
+</para>
- <p>This function finds the set of depths (PanoramiXDepths[]) and
+ <para>This function finds the set of depths (PanoramiXDepths[]) and
visuals (PanoramiXVisuals[])
common to all of the physical screens.
PanoramiXNumDepths is set to the number of common depths, and
PanoramiXNumVisuals is set to the number of common visuals.
Resources are created for the single root window and the default
colormap. Each of these resources has per-physical screen entries.
+ </para>
+</listitem></varlistentry>
- <tag/PanoramiXCreateConnectionBlock()/ PanoramiXConsolidate() is a
+<varlistentry>
+<term>PanoramiXCreateConnectionBlock()</term>
+<listitem>
+ <para>PanoramiXConsolidate() is a
device-independent extension function that is called directly from
the X server's main() function after the per-physical screen root
windows are created. It is called instead of the standard DIX
@@ -1209,52 +1567,66 @@ PanoramiX prefix. the X server exits with a fatal error. This function will return
FALSE if no common depths were found in PanoramiXConsolidate().
With no common depths, Xinerama mode is not possible.
+ </para>
- <p>The connection block holds the information that clients get when
+ <para>The connection block holds the information that clients get when
they open a connection to the X server. It includes information
such as the supported pixmap formats, number of screens and the
sizes, depths, visuals, default colormap information, etc, for each
- of the screens (much of information that <tt/xdpyinfo/ shows). The
+ of the screens (much of information that <command>xdpyinfo</command> shows). The
connection block is initialized with the combined single screen
values that were calculated in the above two functions.
+ </para>
- <p>The Xinerama extension allows the registration of connection
+ <para>The Xinerama extension allows the registration of connection
block callback functions. The purpose of these is to allow other
extensions to do processing at this point. These callbacks can be
registered by calling XineramaRegisterConnectionBlockCallback() from
the other extension's ExtensionInit() function. Each registered
connection block callback is called at the end of
PanoramiXCreateConnectionBlock().
-</descrip>
+ </para>
+</listitem></varlistentry>
+</variablelist>
-<sect2>Xinerama-specific changes to the DIX code
+<sect3>
+<title>Xinerama-specific changes to the DIX code</title>
-<p>There are a few types of Xinerama-specific changes within the DIX
+<para>There are a few types of Xinerama-specific changes within the DIX
code. The main ones are described here.
+</para>
-<p>Functions that deal with colormap or GC -related operations outside of
+<para>Functions that deal with colormap or GC -related operations outside of
the intercepted protocol requests have a test added to only do the
-processing for screen numbers > 0. This is because they are handled for
+processing for screen numbers > 0. This is because they are handled for
the single Xinerama screen and the processing is done once for screen 0.
+</para>
-<p>The handling of motion events does some coordinate translation between
+<para>The handling of motion events does some coordinate translation between
the physical screen's origin and screen zero's origin. Also, motion
events must be reported relative to the composite screen origin rather
than the physical screen origins.
+</para>
-<p>There is some special handling for cursor, window and event processing
+<para>There is some special handling for cursor, window and event processing
that cannot (either not at all or not conveniently) be done via the
intercepted protocol requests. A particular case is the handling of
pointers moving between physical screens.
+</para>
+</sect3>
-<sect2>Xinerama-specific changes to the MI code
+<sect3>
+<title>Xinerama-specific changes to the MI code</title>
-<p>The only Xinerama-specific change to the MI code is in miSendExposures()
+<para>The only Xinerama-specific change to the MI code is in miSendExposures()
to handle the coordinate (and window ID) translation for expose events.
+</para>
+</sect3>
-<sect2>Intercepted DIX core requests
+<sect3>
+<title>Intercepted DIX core requests</title>
-<p>Xinerama breaks up drawing requests for dispatch to each physical
+<para>Xinerama breaks up drawing requests for dispatch to each physical
screen. It also breaks up windows into pieces for each physical screen.
GCs are translated into per-screen GCs. Colormaps are replicated on
each physical screen. The functions handling the intercepted requests
@@ -1266,77 +1638,114 @@ necessary state information for the single composite screen. Requests (usually those with replies) that can be satisfied completely from this
stored state information do not call the standard request handling
functions.
+</para>
+
+</sect3>
+
+</sect2>
+
+</sect1>
<!-- ============================================================ -->
-<sect>Development Results
+<sect1>
+<title>Development Results</title>
-<p>In this section the results of each phase of development are
+<para>In this section the results of each phase of development are
discussed. This development took place between approximately June 2001
and July 2003.
+</para>
-<sect1>Phase I
+<sect2>
+<title>Phase I</title>
-<p>The initial development phase dealt with the basic implementation
+<para>The initial development phase dealt with the basic implementation
including the bootstrap code, which used the shadow framebuffer, and the
unoptimized implementation, based on an Xnest-style implementation.
+</para>
-<sect2>Scope
+<sect3>
+<title>Scope</title>
-<p>The goal of Phase I is to provide fundamental functionality that can
+<para>The goal of Phase I is to provide fundamental functionality that can
act as a foundation for ongoing work:
-<enum>
- <item>Develop the proxy X server
- <itemize>
- <item>The proxy X server will operate on the X11 protocol and
+<orderedlist>
+<listitem>
+ <para>Develop the proxy X server
+ <itemizedlist>
+ <listitem>
+ <para>The proxy X server will operate on the X11 protocol and
relay requests as necessary to correctly perform the request.
- <item>Work will be based on the existing work for Xinerama and
+ </para></listitem>
+ <listitem>
+ <para>Work will be based on the existing work for Xinerama and
Xnest.
- <item>Input events and windowing operations are handled in the
+ </para></listitem>
+ <listitem>
+ <para>Input events and windowing operations are handled in the
proxy server and rendering requests are repackaged and sent to
each of the back-end servers for display.
- <item>The multiple screen layout (including support for
+ </para></listitem>
+ <listitem>
+ <para>The multiple screen layout (including support for
overlapping screens) will be user configurable via a
configuration file or through the configuration tool.
- </itemize>
- <item>Develop graphical configuration tool
- <itemize>
- <item>There will be potentially a large number of X servers to
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem>
+ <para>Develop graphical configuration tool
+ <itemizedlist>
+ <listitem>
+ <para>There will be potentially a large number of X servers to
configure into a single display. The tool will allow the user
to specify which servers are involved in the configuration and
how they should be laid out.
- </itemize>
- <item>Pass the X Test Suite
- <itemize>
- <item>The X Test Suite covers the basic X11 operations. All
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem>
+ <para>Pass the X Test Suite
+ <itemizedlist>
+ <listitem>
+ <para>The X Test Suite covers the basic X11 operations. All
tests known to succeed must correctly operate in the distributed
X environment.
- </itemize>
-</enum>
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+</orderedlist>
-<p>For this phase, the back-end X servers are assumed to be unmodified X
+</para>
+
+<para>For this phase, the back-end X servers are assumed to be unmodified X
servers that do not support any DMX-related protocol extensions; future
optimization pathways are considered, but are not implemented; and the
configuration tool is assumed to rely only on libraries in the X source
tree (e.g., Xt).
+</para>
+</sect3>
-<sect2>Results
+<sect3>
+<title>Results</title>
-<p>The proxy X server, Xdmx, was developed to distribute X11 protocol
+<para>The proxy X server, Xdmx, was developed to distribute X11 protocol
requests to the set of back-end X servers. It opens a window on each
back-end server, which represents the part of the front-end's root
window that is visible on that screen. It mirrors window, pixmap and
other state in each back-end server. Drawing requests are sent to
either windows or pixmaps on each back-end server. This code is based
on Xnest and uses the existing Xinerama extension.
+</para>
-<p>Input events can be taken from (1) devices attached to the back-end
+<para>Input events can be taken from (1) devices attached to the back-end
server, (2) core devices attached directly to the Xdmx server, or (3)
from a ``console'' window on another X server. Events for these devices
are gathered, processed and delivered to clients attached to the Xdmx
server.
+</para>
-<p>An intuitive configuration format was developed to help the user
+<para>An intuitive configuration format was developed to help the user
easily configure the multiple back-end X servers. It was defined (see
grammar in Xdmx man page) and a parser was implemented that is used by
the Xdmx server and by a standalone xdmxconfig utility. The parsing
@@ -1344,83 +1753,103 @@ support was implemented such that it can be easily factored out of the X source tree for use with other tools (e.g., vdl). Support for
converting legacy vdl-format configuration files to the DMX format is
provided by the vdltodmx utility.
+</para>
-<p>Originally, the configuration file was going to be a subsection of
+<para>Originally, the configuration file was going to be a subsection of
XFree86's XF86Config file, but that was not possible since Xdmx is a
completely separate X server. Thus, a separate config file format was
developed. In addition, a graphical configuration
tool, xdmxconfig, was developed to allow the user to create and arrange
-the screens in the configuration file. The <bf/-configfile/ and <bf/-config/
+the screens in the configuration file. The <emphasis remap="bf">-configfile</emphasis> and <emphasis remap="bf">-config</emphasis>
command-line options can be used to start Xdmx using a configuration
file.
+</para>
-<p>An extension that enables remote input testing is required for the X
+<para>An extension that enables remote input testing is required for the X
Test Suite to function. During this phase, this extension (XTEST) was
implemented in the Xdmx server. The results from running the X Test
Suite are described in detail below.
+</para>
+</sect3>
-<sect2>X Test Suite
+<sect3>
+<title>X Test Suite</title>
- <sect3> Introduction
- <p>
+ <sect4>
+ <title>Introduction</title>
+ <para>
The X Test Suite contains tests that verify Xlib functions
operate correctly. The test suite is designed to run on a
single X server; however, since X applications will not be
able to tell the difference between the DMX server and a
standard X server, the X Test Suite should also run on the
DMX server.
- <p>
+ </para>
+ <para>
The Xdmx server was tested with the X Test Suite, and the
existing failures are noted in this section. To put these
results in perspective, we first discuss expected X Test
failures and how errors in underlying systems can impact
Xdmx test results.
+ </para>
+ </sect4>
- <sect3>Expected Failures for a Single Head
- <p>
+ <sect4>
+ <title>Expected Failures for a Single Head</title>
+ <para>
A correctly implemented X server with a single screen is
expected to fail certain X Test tests. The following
well-known errors occur because of rounding error in the X
server code:
- <verb>
+ <literallayout>
XDrawArc: Tests 42, 63, 66, 73
XDrawArcs: Tests 45, 66, 69, 76
- </verb>
- <p>
+ </literallayout>
+ </para>
+ <para>
The following failures occur because of the high-level X
server implementation:
- <verb>
+ <literallayout>
XLoadQueryFont: Test 1
XListFontsWithInfo: Tests 3, 4
XQueryFont: Tests 1, 2
- </verb>
- <p>
+ </literallayout>
+ </para>
+ <para>
The following test fails when running the X server as root
under Linux because of the way directory modes are
interpreted:
- <verb>
+ <literallayout>
XWriteBitmapFile: Test 3
- </verb>
- <p>
+ </literallayout>
+ </para>
+ <para>
Depending on the video card used for the back-end, other
failures may also occur because of bugs in the low-level
driver implementation. Over time, failures of this kind
are usually fixed by XFree86, but will show up in Xdmx
testing until then.
+ </para>
+ </sect4>
- <sect3>Expected Failures for Xinerama
- <p>
+ <sect4>
+ <title>Expected Failures for Xinerama</title>
+ <para>
Xinerama fails several X Test Suite tests because of
design decisions made for the current implementation of
Xinerama. Over time, many of these errors will be
corrected by XFree86 and the group working on a new
Xinerama implementation. Therefore, Xdmx will also share
X Suite Test failures with Xinerama.
- <p>
+ </para>
+
+ <para>
We may be able to fix or work-around some of these
failures at the Xdmx level, but this will require
additional exploration that was not part of Phase I.
- <p>
+ </para>
+
+ <para>
Xinerama is constantly improving, and the list of
Xinerama-related failures depends on XFree86 version and
the underlying graphics hardware. We tested with a
@@ -1430,36 +1859,44 @@ XWriteBitmapFile: Test 3 Xinerama layer, and does not include failures listed in
the previous section, or failures that appear to be from
the low-level graphics driver itself:
- <p>
+ </para>
+
+ <para>
These failures were noted with multiple Xinerama
configurations:
- <verb>
+ <literallayout>
XCopyPlane: Tests 13, 22, 31 (well-known Xinerama implementation issue)
XSetFontPath: Test 4
XGetDefault: Test 5
XMatchVisualInfo: Test 1
- </verb>
- <p>
+ </literallayout>
+ </para>
+ <para>
These failures were noted only when using one dual-head
video card with a 4.2.99.x XFree86 server:
- <verb>
+ <literallayout>
XListPixmapFormats: Test 1
XDrawRectangles: Test 45
- </verb>
- <p>
+ </literallayout>
+ </para>
+ <para>
These failures were noted only when using two video cards
from different vendors with a 4.1.99.x XFree86 server:
- <verb>
+ <literallayout>
XChangeWindowAttributes: Test 32
XCreateWindow: Test 30
XDrawLine: Test 22
XFillArc: Test 22
XChangeKeyboardControl: Tests 9, 10
XRebindKeysym: Test 1
- </verb>
+ </literallayout>
+ </para>
+ </sect4>
- <sect3>Additional Failures from Xdmx
- <p>
+ <sect4>
+ <title>Additional Failures from Xdmx</title>
+
+ <para>
When running Xdmx, no unexpected failures were noted.
Since the Xdmx server is based on Xinerama, we expect to
have most of the Xinerama failures present in the Xdmx
@@ -1467,7 +1904,7 @@ XRebindKeysym: Test 1 low-level device drivers on each back-end server, we also
expect that Xdmx will exhibit most of the back-end
failures. Here is a summary:
- <verb>
+ <literallayout>
XListPixmapFormats: Test 1 (configuration dependent)
XChangeWindowAttributes: Test 32
XCreateWindow: Test 30
@@ -1476,15 +1913,20 @@ XSetFontPath: Test 4 XGetDefault: Test 5 (configuration dependent)
XMatchVisualInfo: Test 1
XRebindKeysym: Test 1 (configuration dependent)
- </verb>
- <p>
+ </literallayout>
+ </para>
+ <para>
Note that this list is shorter than the combined list for
Xinerama because Xdmx uses different code paths to perform
some Xinerama operations. Further, some Xinerama failures
have been fixed in the XFree86 4.2.99.x CVS repository.
-
- <sect3>Summary and Future Work
- <p>
+ </para>
+ </sect4>
+
+ <sect4>
+ <title>Summary and Future Work</title>
+
+ <para>
Running the X Test Suite on Xdmx does not produce any
failures that cannot be accounted for by the underlying
Xinerama subsystem used by the front-end or by the
@@ -1492,64 +1934,87 @@ XRebindKeysym: Test 1 (configuration dependent) servers. The Xdmx server therefore is as ``correct'' as
possible with respect to the standard set of X Test Suite
tests.
- <p>
+ </para>
+
+ <para>
During the following phases, we will continue to verify
Xdmx correctness using the X Test Suite. We may also use
other tests suites or write additional tests that run
under the X Test Suite that specifically verify the
expected behavior of DMX.
+ </para>
+ </sect4>
+</sect3>
-<sect2>Fonts
+<sect3>
+<title>Fonts</title>
-<p>In Phase I, fonts are handled directly by both the front-end and the
+<para>In Phase I, fonts are handled directly by both the front-end and the
back-end servers, which is required since we must treat each back-end
server during this phase as a ``black box''. What this requires is that
-<bf/the front- and back-end servers must share the exact same font
-path/. There are two ways to help make sure that all servers share the
+<emphasis remap="bf">the front- and back-end servers must share the exact same font
+path</emphasis>. There are two ways to help make sure that all servers share the
same font path:
-<enum>
- <item>First, each server can be configured to use the same font
+<orderedlist>
+ <listitem>
+ <para>First, each server can be configured to use the same font
server. The font server, xfs, can be configured to serve fonts to
multiple X servers via TCP.
+ </para></listitem>
- <item>Second, each server can be configured to use the same font
+ <listitem>
+ <para>Second, each server can be configured to use the same font
path and either those font paths can be copied to each back-end
machine or they can be mounted (e.g., via NFS) on each back-end
machine.
-</enum>
+ </para></listitem>
+</orderedlist>
+</para>
-<p>One additional concern is that a client program can set its own font
+<para>One additional concern is that a client program can set its own font
path, and if it does so, then that font path must be available on each
back-end machine.
+</para>
-<p>The -fontpath command line option was added to allow users to
+<para>The -fontpath command line option was added to allow users to
initialize the font path of the front end server. This font path is
propagated to each back-end server when the default font is loaded. If
there are any problems, an error message is printed, which will describe
the problem and list the current font path. For more information about
setting the font path, see the -fontpath option description in the man
page.
+</para>
+</sect3>
-<sect2>Performance
+<sect3>
+<title>Performance</title>
-<p>Phase I of development was not intended to optimize performance. Its
+<para>Phase I of development was not intended to optimize performance. Its
focus was on completely and correctly handling the base X11 protocol in
the Xdmx server. However, several insights were gained during Phase I,
which are listed here for reference during the next phase of
development.
+</para>
-<enum>
- <item>Calls to XSync() can slow down rendering since it requires a
+<orderedlist>
+ <listitem>
+ <para>Calls to XSync() can slow down rendering since it requires a
complete round trip to and from a back-end server. This is
especially problematic when communicating over long haul networks.
- <item>Sending drawing requests to only the screens that they overlap
+ </para></listitem>
+
+ <listitem>
+ <para>Sending drawing requests to only the screens that they overlap
should improve performance.
-</enum>
+ </para></listitem>
+</orderedlist>
+</sect3>
-<sect2>Pixmaps
+<sect3>
+<title>Pixmaps</title>
-<p>Pixmaps were originally expected to be handled entirely in the
+<para>Pixmaps were originally expected to be handled entirely in the
front-end X server; however, it was found that this overly complicated
the rendering code and would have required sending potentially large
images to each back server that required them when copying from pixmap
@@ -1558,86 +2023,105 @@ as it is with regular window state. With this implementation, the same rendering code that draws to windows can be used to draw to pixmaps on
the back-end server, and no large image transfers are required to copy
from pixmap to window.
+</para>
+
+</sect3>
+
+</sect2>
<!-- ============================================================ -->
-<sect1>Phase II
+<sect2>
+<title>Phase II</title>
-<p>The second phase of development concentrates on performance
+<para>The second phase of development concentrates on performance
optimizations. These optimizations are documented here, with
-<tt/x11perf/ data to show how the optimizations improve performance.
+<command>x11perf</command> data to show how the optimizations improve performance.
+</para>
-<p>All benchmarks were performed by running Xdmx on a dual processor
+<para>All benchmarks were performed by running Xdmx on a dual processor
1.4GHz AMD Athlon machine with 1GB of RAM connecting over 100baseT to
two single-processor 1GHz Pentium III machines with 256MB of RAM and ATI
Rage 128 (RF) video cards. The front end was running Linux
2.4.20-pre1-ac1 and the back ends were running Linux 2.4.7-10 and
version 4.2.99.1 of XFree86 pulled from the XFree86 CVS repository on
August 7, 2002. All systems were running Red Hat Linux 7.2.
+</para>
-<sect2>Moving from XFree86 4.1.99.1 to 4.2.0.0
+<sect3>
+<title>Moving from XFree86 4.1.99.1 to 4.2.0.0</title>
-<p>For phase II, the working source tree was moved to the branch tagged
+<para>For phase II, the working source tree was moved to the branch tagged
with dmx-1-0-branch and was updated from version 4.1.99.1 (20 August
2001) of the XFree86 sources to version 4.2.0.0 (18 January 2002).
After this update, the following tests were noted to be more than 10%
faster:
- <verb>
-1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple)
-1.16 Fill 1x1 tiled trapezoid (161x145 tile)
-1.13 Fill 10x10 tiled trapezoid (161x145 tile)
-1.17 Fill 100x100 tiled trapezoid (161x145 tile)
-1.16 Fill 1x1 tiled trapezoid (216x208 tile)
-1.20 Fill 10x10 tiled trapezoid (216x208 tile)
-1.15 Fill 100x100 tiled trapezoid (216x208 tile)
-1.37 Circulate Unmapped window (200 kids)
- </verb>
+<screen>
+1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple)
+1.16 Fill 1x1 tiled trapezoid (161x145 tile)
+1.13 Fill 10x10 tiled trapezoid (161x145 tile)
+1.17 Fill 100x100 tiled trapezoid (161x145 tile)
+1.16 Fill 1x1 tiled trapezoid (216x208 tile)
+1.20 Fill 10x10 tiled trapezoid (216x208 tile)
+1.15 Fill 100x100 tiled trapezoid (216x208 tile)
+1.37 Circulate Unmapped window (200 kids)
+</screen>
And the following tests were noted to be more than 10% slower:
- <verb>
-0.88 Unmap window via parent (25 kids)
-0.75 Circulate Unmapped window (4 kids)
-0.79 Circulate Unmapped window (16 kids)
-0.80 Circulate Unmapped window (25 kids)
-0.82 Circulate Unmapped window (50 kids)
-0.85 Circulate Unmapped window (75 kids)
- </verb>
-<p>These changes were not caused by any changes in the DMX system, and
+<screen>
+0.88 Unmap window via parent (25 kids)
+0.75 Circulate Unmapped window (4 kids)
+0.79 Circulate Unmapped window (16 kids)
+0.80 Circulate Unmapped window (25 kids)
+0.82 Circulate Unmapped window (50 kids)
+0.85 Circulate Unmapped window (75 kids)
+</screen>
+</para>
+
+<para>These changes were not caused by any changes in the DMX system, and
may point to changes in the XFree86 tree or to tests that have more
-"jitter" than most other <tt/x11perf/ tests.
+"jitter" than most other <command>x11perf</command> tests.
+</para>
+</sect3>
-<sect2>Global changes
+<sect3>
+<title>Global changes</title>
-<p>During the development of the Phase II DMX server, several global
+<para>During the development of the Phase II DMX server, several global
changes were made. These changes were also compared with the Phase I
server. The following tests were noted to be more than 10% faster:
- <verb>
-1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple)
-1.15 Fill 1x1 tiled trapezoid (161x145 tile)
-1.13 Fill 10x10 tiled trapezoid (161x145 tile)
-1.17 Fill 100x100 tiled trapezoid (161x145 tile)
-1.16 Fill 1x1 tiled trapezoid (216x208 tile)
-1.19 Fill 10x10 tiled trapezoid (216x208 tile)
-1.15 Fill 100x100 tiled trapezoid (216x208 tile)
-1.15 Circulate Unmapped window (4 kids)
- </verb>
-
-<p>The following tests were noted to be more than 10% slower:
- <verb>
-0.69 Scroll 10x10 pixels
-0.68 Scroll 100x100 pixels
-0.68 Copy 10x10 from window to window
-0.68 Copy 100x100 from window to window
-0.76 Circulate Unmapped window (75 kids)
-0.83 Circulate Unmapped window (100 kids)
- </verb>
-
-<p>For the remainder of this analysis, the baseline of comparison will
+<screen>
+1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple)
+1.15 Fill 1x1 tiled trapezoid (161x145 tile)
+1.13 Fill 10x10 tiled trapezoid (161x145 tile)
+1.17 Fill 100x100 tiled trapezoid (161x145 tile)
+1.16 Fill 1x1 tiled trapezoid (216x208 tile)
+1.19 Fill 10x10 tiled trapezoid (216x208 tile)
+1.15 Fill 100x100 tiled trapezoid (216x208 tile)
+1.15 Circulate Unmapped window (4 kids)
+</screen>
+</para>
+
+<para>The following tests were noted to be more than 10% slower:
+<screen>
+0.69 Scroll 10x10 pixels
+0.68 Scroll 100x100 pixels
+0.68 Copy 10x10 from window to window
+0.68 Copy 100x100 from window to window
+0.76 Circulate Unmapped window (75 kids)
+0.83 Circulate Unmapped window (100 kids)
+</screen>
+</para>
+
+<para>For the remainder of this analysis, the baseline of comparison will
be the Phase II deliverable with all optimizations disabled (unless
otherwise noted). This will highlight how the optimizations in
isolation impact performance.
+</para>
+</sect3>
-<sect2>XSync() Batching
+<sect3>
+<title>XSync() Batching</title>
-<p>During the Phase I implementation, XSync() was called after every
+<para>During the Phase I implementation, XSync() was called after every
protocol request made by the DMX server. This provided the DMX server
with an interactive feel, but defeated X11's protocol buffering system
and introduced round-trip wire latency into every operation. During
@@ -1647,21 +2131,26 @@ noted, and XSync() calls are only made every 100mS or when the DMX server specifically needs to make a call to guarantee interactivity.
With this new system, X11 buffers protocol as much as possible during a
100mS interval, and many unnecessary XSync() calls are avoided.
+</para>
-<p>Out of more than 300 <tt/x11perf/ tests, 8 tests became more than 100
+<para>Out of more than 300 <command>x11perf</command> tests, 8 tests became more than 100
times faster, with 68 more than 50X faster, 114 more than 10X faster,
and 181 more than 2X faster. See table below for summary.
+</para>
-<p>The following tests were noted to be more than 10% slower with
+<para>The following tests were noted to be more than 10% slower with
XSync() batching on:
- <verb>
-0.88 500x500 tiled rectangle (161x145 tile)
-0.89 Copy 500x500 from window to window
- </verb>
+<screen>
+0.88 500x500 tiled rectangle (161x145 tile)
+0.89 Copy 500x500 from window to window
+</screen>
+</para>
+</sect3>
-<sect2>Offscreen Optimization
+<sect3>
+<title>Offscreen Optimization</title>
-<p>Windows span one or more of the back-end servers' screens; however,
+<para>Windows span one or more of the back-end servers' screens; however,
during Phase I development, windows were created on every back-end
server and every rendering request was sent to every window regardless
of whether or not that window was visible. With the offscreen
@@ -1672,25 +2161,30 @@ between the front and back-end servers, and it reduces the number of XSync() calls. The performance tests were run on a DMX system with only
two back-end servers. Greater performance gains will be had as the
number of back-end servers increases.
+</para>
-<p>Out of more than 300 <tt/x11perf/ tests, 3 tests were at least twice as
+<para>Out of more than 300 <command>x11perf</command> tests, 3 tests were at least twice as
fast, and 146 tests were at least 10% faster. Two tests were more than
10% slower with the offscreen optimization:
- <verb>
-0.88 Hide/expose window via popup (4 kids)
-0.89 Resize unmapped window (75 kids)
- </verb>
+<screen>
+0.88 Hide/expose window via popup (4 kids)
+0.89 Resize unmapped window (75 kids)
+</screen>
+</para>
+</sect3>
-<sect2>Lazy Window Creation Optimization
+<sect3>
+<title>Lazy Window Creation Optimization</title>
-<p>As mentioned above, during Phase I, windows were created on every
+<para>As mentioned above, during Phase I, windows were created on every
back-end server even if they were not visible on that back-end. With
the lazy window creation optimization, the DMX server does not create
windows on a back-end server until they are either visible or they
become the parents of a visible window. This optimization builds on the
offscreen optimization (described above) and requires it to be enabled.
+</para>
-<p>The lazy window creation optimization works by creating the window
+<para>The lazy window creation optimization works by creating the window
data structures in the front-end server when a client creates a window,
but delays creation of the window on the back-end server(s). A private
window structure in the DMX server saves the relevant window data and
@@ -1703,38 +2197,45 @@ case occurs when a window is mapped or when a visible window is copied, moved or resized and now overlaps the back-end server's screen. The
second case occurs when starting a window manager after having created
windows to which the window manager needs to add decorations.
+</para>
-<p>When either case occurs, a window on the back-end server is created
+<para>When either case occurs, a window on the back-end server is created
using the data saved in the DMX server's window private data structure.
The stacking order is then adjusted to correctly place the window on the
back-end and lastly the window is mapped. From this time forward, the
window is handled exactly as if the window had been created at the time
of the client's request.
+</para>
-<p>Note that when a window is no longer visible on a back-end server's
+<para>Note that when a window is no longer visible on a back-end server's
screen (e.g., it is moved offscreen), the window is not destroyed;
rather, it is kept and reused later if the window once again becomes
visible on the back-end server's screen. Originally with this
optimization, destroying windows was implemented but was later rejected
because it increased bandwidth when windows were opaquely moved or
resized, which is common in many window managers.
+</para>
-<p>The performance tests were run on a DMX system with only two back-end
+<para>The performance tests were run on a DMX system with only two back-end
servers. Greater performance gains will be had as the number of
back-end servers increases.
+</para>
-<p>This optimization improved the following <tt/x11perf/ tests by more
+<para>This optimization improved the following <command>x11perf</command> tests by more
than 10%:
- <verb>
-1.10 500x500 rectangle outline
-1.12 Fill 100x100 stippled trapezoid (161x145 stipple)
-1.20 Circulate Unmapped window (50 kids)
-1.19 Circulate Unmapped window (75 kids)
- </verb>
-
-<sect2>Subdividing Rendering Primitives
-
-<p>X11 imaging requests transfer significant data between the client and
+<screen>
+1.10 500x500 rectangle outline
+1.12 Fill 100x100 stippled trapezoid (161x145 stipple)
+1.20 Circulate Unmapped window (50 kids)
+1.19 Circulate Unmapped window (75 kids)
+</screen>
+</para>
+</sect3>
+
+<sect3>
+<title>Subdividing Rendering Primitives</title>
+
+<para>X11 imaging requests transfer significant data between the client and
the X server. During Phase I, the DMX server would then transfer the
image data to each back-end server. Even with the offscreen
optimization (above), these requests still required transferring
@@ -1742,58 +2243,67 @@ significant data to each back-end server that contained a visible portion of the window. For example, if the client uses XPutImage() to
copy an image to a window that overlaps the entire DMX screen, then the
entire image is copied by the DMX server to every back-end server.
+</para>
-<p>To reduce the amount of data transferred between the DMX server and
+<para>To reduce the amount of data transferred between the DMX server and
the back-end servers when XPutImage() is called, the image data is
subdivided and only the data that will be visible on a back-end server's
screen is sent to that back-end server. Xinerama already implements a
subdivision algorithm for XGetImage() and no further optimization was
needed.
+</para>
-<p>Other rendering primitives were analyzed, but the time required to
+<para>Other rendering primitives were analyzed, but the time required to
subdivide these primitives was a significant proportion of the time
required to send the entire rendering request to the back-end server, so
this optimization was rejected for the other rendering primitives.
+</para>
-<p>Again, the performance tests were run on a DMX system with only two
+<para>Again, the performance tests were run on a DMX system with only two
back-end servers. Greater performance gains will be had as the number
of back-end servers increases.
+</para>
-<p>This optimization improved the following <tt/x11perf/ tests by more
+<para>This optimization improved the following <command>x11perf</command> tests by more
than 10%:
- <verb>
-1.12 Fill 100x100 stippled trapezoid (161x145 stipple)
-1.26 PutImage 10x10 square
-1.83 PutImage 100x100 square
-1.91 PutImage 500x500 square
-1.40 PutImage XY 10x10 square
-1.48 PutImage XY 100x100 square
-1.50 PutImage XY 500x500 square
-1.45 Circulate Unmapped window (75 kids)
-1.74 Circulate Unmapped window (100 kids)
- </verb>
-
-<p>The following test was noted to be more than 10% slower with this
+<screen>
+1.12 Fill 100x100 stippled trapezoid (161x145 stipple)
+1.26 PutImage 10x10 square
+1.83 PutImage 100x100 square
+1.91 PutImage 500x500 square
+1.40 PutImage XY 10x10 square
+1.48 PutImage XY 100x100 square
+1.50 PutImage XY 500x500 square
+1.45 Circulate Unmapped window (75 kids)
+1.74 Circulate Unmapped window (100 kids)
+</screen>
+</para>
+
+<para>The following test was noted to be more than 10% slower with this
optimization:
- <verb>
-0.88 10-pixel fill chord partial circle
- </verb>
+<screen>
+0.88 10-pixel fill chord partial circle
+</screen>
+</para>
+</sect3>
-<sect2>Summary of x11perf Data
+<sect3>
+<title>Summary of x11perf Data</title>
-<p>With all of the optimizations on, 53 <tt/x11perf/ tests are more than
+<para>With all of the optimizations on, 53 <command>x11perf</command> tests are more than
100X faster than the unoptimized Phase II deliverable, with 69 more than
50X faster, 73 more than 10X faster, and 199 more than twice as fast.
No tests were more than 10% slower than the unoptimized Phase II
deliverable. (Compared with the Phase I deliverable, only Circulate
Unmapped window (100 kids) was more than 10% slower than the Phase II
deliverable. As noted above, this test seems to have wider variability
-than other <tt/x11perf/ tests.)
+than other <command>x11perf</command> tests.)
+</para>
-<p>The following table summarizes relative <tt/x11perf/ test changes for
+<para>The following table summarizes relative <command>x11perf</command> test changes for
all optimizations individually and collectively. Note that some of the
optimizations have a synergistic effect when used together.
- <verb>
+<screen>
1: XSync() batching only
2: Off screen optimizations only
@@ -1803,351 +2313,358 @@ optimizations have a synergistic effect when used together. 1 2 3 4 5 Operation
------ ---- ---- ---- ------ ---------
- 2.14 1.85 1.00 1.00 4.13 Dot
- 1.67 1.80 1.00 1.00 3.31 1x1 rectangle
- 2.38 1.43 1.00 1.00 2.44 10x10 rectangle
- 1.00 1.00 0.92 0.98 1.00 100x100 rectangle
- 1.00 1.00 1.00 1.00 1.00 500x500 rectangle
- 1.83 1.85 1.05 1.06 3.54 1x1 stippled rectangle (8x8 stipple)
- 2.43 1.43 1.00 1.00 2.41 10x10 stippled rectangle (8x8 stipple)
- 0.98 1.00 1.00 1.00 1.00 100x100 stippled rectangle (8x8 stipple)
- 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (8x8 stipple)
- 1.75 1.75 1.00 1.00 3.40 1x1 opaque stippled rectangle (8x8 stipple)
- 2.38 1.42 1.00 1.00 2.34 10x10 opaque stippled rectangle (8x8 stipple)
- 1.00 1.00 0.97 0.97 1.00 100x100 opaque stippled rectangle (8x8 stipple)
- 1.00 1.00 1.00 1.00 0.99 500x500 opaque stippled rectangle (8x8 stipple)
- 1.82 1.82 1.04 1.04 3.56 1x1 tiled rectangle (4x4 tile)
- 2.33 1.42 1.00 1.00 2.37 10x10 tiled rectangle (4x4 tile)
- 1.00 0.92 1.00 1.00 1.00 100x100 tiled rectangle (4x4 tile)
- 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (4x4 tile)
- 1.94 1.62 1.00 1.00 3.66 1x1 stippled rectangle (17x15 stipple)
- 1.74 1.28 1.00 1.00 1.73 10x10 stippled rectangle (17x15 stipple)
- 1.00 1.00 1.00 0.89 0.98 100x100 stippled rectangle (17x15 stipple)
- 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (17x15 stipple)
- 1.94 1.62 1.00 1.00 3.67 1x1 opaque stippled rectangle (17x15 stipple)
- 1.69 1.26 1.00 1.00 1.66 10x10 opaque stippled rectangle (17x15 stipple)
- 1.00 0.95 1.00 1.00 1.00 100x100 opaque stippled rectangle (17x15 stipple)
- 1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (17x15 stipple)
- 1.93 1.61 0.99 0.99 3.69 1x1 tiled rectangle (17x15 tile)
- 1.73 1.27 1.00 1.00 1.72 10x10 tiled rectangle (17x15 tile)
- 1.00 1.00 1.00 1.00 0.98 100x100 tiled rectangle (17x15 tile)
- 1.00 1.00 0.97 0.97 1.00 500x500 tiled rectangle (17x15 tile)
- 1.95 1.63 1.00 1.00 3.83 1x1 stippled rectangle (161x145 stipple)
- 1.80 1.30 1.00 1.00 1.83 10x10 stippled rectangle (161x145 stipple)
- 0.97 1.00 1.00 1.00 1.01 100x100 stippled rectangle (161x145 stipple)
- 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (161x145 stipple)
- 1.95 1.63 1.00 1.00 3.56 1x1 opaque stippled rectangle (161x145 stipple)
- 1.65 1.25 1.00 1.00 1.68 10x10 opaque stippled rectangle (161x145 stipple)
+ 2.14 1.85 1.00 1.00 4.13 Dot
+ 1.67 1.80 1.00 1.00 3.31 1x1 rectangle
+ 2.38 1.43 1.00 1.00 2.44 10x10 rectangle
+ 1.00 1.00 0.92 0.98 1.00 100x100 rectangle
+ 1.00 1.00 1.00 1.00 1.00 500x500 rectangle
+ 1.83 1.85 1.05 1.06 3.54 1x1 stippled rectangle (8x8 stipple)
+ 2.43 1.43 1.00 1.00 2.41 10x10 stippled rectangle (8x8 stipple)
+ 0.98 1.00 1.00 1.00 1.00 100x100 stippled rectangle (8x8 stipple)
+ 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (8x8 stipple)
+ 1.75 1.75 1.00 1.00 3.40 1x1 opaque stippled rectangle (8x8 stipple)
+ 2.38 1.42 1.00 1.00 2.34 10x10 opaque stippled rectangle (8x8 stipple)
+ 1.00 1.00 0.97 0.97 1.00 100x100 opaque stippled rectangle (8x8 stipple)
+ 1.00 1.00 1.00 1.00 0.99 500x500 opaque stippled rectangle (8x8 stipple)
+ 1.82 1.82 1.04 1.04 3.56 1x1 tiled rectangle (4x4 tile)
+ 2.33 1.42 1.00 1.00 2.37 10x10 tiled rectangle (4x4 tile)
+ 1.00 0.92 1.00 1.00 1.00 100x100 tiled rectangle (4x4 tile)
+ 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (4x4 tile)
+ 1.94 1.62 1.00 1.00 3.66 1x1 stippled rectangle (17x15 stipple)
+ 1.74 1.28 1.00 1.00 1.73 10x10 stippled rectangle (17x15 stipple)
+ 1.00 1.00 1.00 0.89 0.98 100x100 stippled rectangle (17x15 stipple)
+ 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (17x15 stipple)
+ 1.94 1.62 1.00 1.00 3.67 1x1 opaque stippled rectangle (17x15 stipple)
+ 1.69 1.26 1.00 1.00 1.66 10x10 opaque stippled rectangle (17x15 stipple)
+ 1.00 0.95 1.00 1.00 1.00 100x100 opaque stippled rectangle (17x15 stipple)
+ 1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (17x15 stipple)
+ 1.93 1.61 0.99 0.99 3.69 1x1 tiled rectangle (17x15 tile)
+ 1.73 1.27 1.00 1.00 1.72 10x10 tiled rectangle (17x15 tile)
+ 1.00 1.00 1.00 1.00 0.98 100x100 tiled rectangle (17x15 tile)
+ 1.00 1.00 0.97 0.97 1.00 500x500 tiled rectangle (17x15 tile)
+ 1.95 1.63 1.00 1.00 3.83 1x1 stippled rectangle (161x145 stipple)
+ 1.80 1.30 1.00 1.00 1.83 10x10 stippled rectangle (161x145 stipple)
+ 0.97 1.00 1.00 1.00 1.01 100x100 stippled rectangle (161x145 stipple)
+ 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (161x145 stipple)
+ 1.95 1.63 1.00 1.00 3.56 1x1 opaque stippled rectangle (161x145 stipple)
+ 1.65 1.25 1.00 1.00 1.68 10x10 opaque stippled rectangle (161x145 stipple)
1.00 1.00 1.00 1.00 1.01 100x100 opaque stippled rectangle (161x145...
1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (161x145...
- 1.95 1.63 0.98 0.99 3.80 1x1 tiled rectangle (161x145 tile)
- 1.67 1.26 1.00 1.00 1.67 10x10 tiled rectangle (161x145 tile)
- 1.13 1.14 1.14 1.14 1.14 100x100 tiled rectangle (161x145 tile)
- 0.88 1.00 1.00 1.00 0.99 500x500 tiled rectangle (161x145 tile)
- 1.93 1.63 1.00 1.00 3.53 1x1 tiled rectangle (216x208 tile)
- 1.69 1.26 1.00 1.00 1.66 10x10 tiled rectangle (216x208 tile)
- 1.00 1.00 1.00 1.00 1.00 100x100 tiled rectangle (216x208 tile)
- 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (216x208 tile)
- 1.82 1.70 1.00 1.00 3.38 1-pixel line segment
- 2.07 1.56 0.90 1.00 3.31 10-pixel line segment
- 1.29 1.10 1.00 1.00 1.27 100-pixel line segment
- 1.05 1.06 1.03 1.03 1.09 500-pixel line segment
- 1.30 1.13 1.00 1.00 1.29 100-pixel line segment (1 kid)
- 1.32 1.15 1.00 1.00 1.32 100-pixel line segment (2 kids)
- 1.33 1.16 1.00 1.00 1.33 100-pixel line segment (3 kids)
- 1.92 1.64 1.00 1.00 3.73 10-pixel dashed segment
- 1.34 1.16 1.00 1.00 1.34 100-pixel dashed segment
- 1.24 1.11 0.99 0.97 1.23 100-pixel double-dashed segment
- 1.72 1.77 1.00 1.00 3.25 10-pixel horizontal line segment
- 1.83 1.66 1.01 1.00 3.54 100-pixel horizontal line segment
- 1.86 1.30 1.00 1.00 1.84 500-pixel horizontal line segment
- 2.11 1.52 1.00 0.99 3.02 10-pixel vertical line segment
- 1.21 1.10 1.00 1.00 1.20 100-pixel vertical line segment
- 1.03 1.03 1.00 1.00 1.02 500-pixel vertical line segment
- 4.42 1.68 1.00 1.01 4.64 10x1 wide horizontal line segment
- 1.83 1.31 1.00 1.00 1.83 100x10 wide horizontal line segment
- 1.07 1.00 0.96 1.00 1.07 500x50 wide horizontal line segment
- 4.10 1.67 1.00 1.00 4.62 10x1 wide vertical line segment
- 1.50 1.24 1.06 1.06 1.48 100x10 wide vertical line segment
- 1.06 1.03 1.00 1.00 1.05 500x50 wide vertical line segment
- 2.54 1.61 1.00 1.00 3.61 1-pixel line
- 2.71 1.48 1.00 1.00 2.67 10-pixel line
- 1.19 1.09 1.00 1.00 1.19 100-pixel line
- 1.04 1.02 1.00 1.00 1.03 500-pixel line
- 2.68 1.51 0.98 1.00 3.17 10-pixel dashed line
- 1.23 1.11 0.99 0.99 1.23 100-pixel dashed line
- 1.15 1.08 1.00 1.00 1.15 100-pixel double-dashed line
- 2.27 1.39 1.00 1.00 2.23 10x1 wide line
- 1.20 1.09 1.00 1.00 1.20 100x10 wide line
- 1.04 1.02 1.00 1.00 1.04 500x50 wide line
- 1.52 1.45 1.00 1.00 1.52 100x10 wide dashed line
- 1.54 1.47 1.00 1.00 1.54 100x10 wide double-dashed line
- 1.97 1.30 0.96 0.95 1.95 10x10 rectangle outline
- 1.44 1.27 1.00 1.00 1.43 100x100 rectangle outline
- 3.22 2.16 1.10 1.09 3.61 500x500 rectangle outline
- 1.95 1.34 1.00 1.00 1.90 10x10 wide rectangle outline
- 1.14 1.14 1.00 1.00 1.13 100x100 wide rectangle outline
- 1.00 1.00 1.00 1.00 1.00 500x500 wide rectangle outline
- 1.57 1.72 1.00 1.00 3.03 1-pixel circle
- 1.96 1.35 1.00 1.00 1.92 10-pixel circle
- 1.21 1.07 0.86 0.97 1.20 100-pixel circle
- 1.08 1.04 1.00 1.00 1.08 500-pixel circle
- 1.39 1.19 1.03 1.03 1.38 100-pixel dashed circle
- 1.21 1.11 1.00 1.00 1.23 100-pixel double-dashed circle
- 1.59 1.28 1.00 1.00 1.58 10-pixel wide circle
- 1.22 1.12 0.99 1.00 1.22 100-pixel wide circle
- 1.06 1.04 1.00 1.00 1.05 500-pixel wide circle
- 1.87 1.84 1.00 1.00 1.85 100-pixel wide dashed circle
- 1.90 1.93 1.01 1.01 1.90 100-pixel wide double-dashed circle
- 2.13 1.43 1.00 1.00 2.32 10-pixel partial circle
- 1.42 1.18 1.00 1.00 1.42 100-pixel partial circle
- 1.92 1.85 1.01 1.01 1.89 10-pixel wide partial circle
- 1.73 1.67 1.00 1.00 1.73 100-pixel wide partial circle
- 1.36 1.95 1.00 1.00 2.64 1-pixel solid circle
- 2.02 1.37 1.00 1.00 2.03 10-pixel solid circle
- 1.19 1.09 1.00 1.00 1.19 100-pixel solid circle
- 1.02 0.99 1.00 1.00 1.01 500-pixel solid circle
- 1.74 1.28 1.00 0.88 1.73 10-pixel fill chord partial circle
- 1.31 1.13 1.00 1.00 1.31 100-pixel fill chord partial circle
- 1.67 1.31 1.03 1.03 1.72 10-pixel fill slice partial circle
- 1.30 1.13 1.00 1.00 1.28 100-pixel fill slice partial circle
- 2.45 1.49 1.01 1.00 2.71 10-pixel ellipse
- 1.22 1.10 1.00 1.00 1.22 100-pixel ellipse
- 1.09 1.04 1.00 1.00 1.09 500-pixel ellipse
- 1.90 1.28 1.00 1.00 1.89 100-pixel dashed ellipse
- 1.62 1.24 0.96 0.97 1.61 100-pixel double-dashed ellipse
- 2.43 1.50 1.00 1.00 2.42 10-pixel wide ellipse
- 1.61 1.28 1.03 1.03 1.60 100-pixel wide ellipse
- 1.08 1.05 1.00 1.00 1.08 500-pixel wide ellipse
- 1.93 1.88 1.00 1.00 1.88 100-pixel wide dashed ellipse
- 1.94 1.89 1.01 1.00 1.94 100-pixel wide double-dashed ellipse
- 2.31 1.48 1.00 1.00 2.67 10-pixel partial ellipse
- 1.38 1.17 1.00 1.00 1.38 100-pixel partial ellipse
- 2.00 1.85 0.98 0.97 1.98 10-pixel wide partial ellipse
- 1.89 1.86 1.00 1.00 1.89 100-pixel wide partial ellipse
- 3.49 1.60 1.00 1.00 3.65 10-pixel filled ellipse
- 1.67 1.26 1.00 1.00 1.67 100-pixel filled ellipse
- 1.06 1.04 1.00 1.00 1.06 500-pixel filled ellipse
- 2.38 1.43 1.01 1.00 2.32 10-pixel fill chord partial ellipse
- 2.06 1.30 1.00 1.00 2.05 100-pixel fill chord partial ellipse
- 2.27 1.41 1.00 1.00 2.27 10-pixel fill slice partial ellipse
- 1.98 1.33 1.00 0.97 1.97 100-pixel fill slice partial ellipse
- 57.46 1.99 1.01 1.00 114.92 Fill 1x1 equivalent triangle
- 56.94 1.98 1.01 1.00 73.89 Fill 10x10 equivalent triangle
- 6.07 1.75 1.00 1.00 6.07 Fill 100x100 equivalent triangle
- 51.12 1.98 1.00 1.00 102.81 Fill 1x1 trapezoid
- 51.42 1.82 1.01 1.00 94.89 Fill 10x10 trapezoid
- 6.47 1.80 1.00 1.00 6.44 Fill 100x100 trapezoid
- 1.56 1.28 1.00 0.99 1.56 Fill 300x300 trapezoid
- 51.27 1.97 0.96 0.97 102.54 Fill 1x1 stippled trapezoid (8x8 stipple)
- 51.73 2.00 1.02 1.02 67.92 Fill 10x10 stippled trapezoid (8x8 stipple)
- 5.36 1.72 1.00 1.00 5.36 Fill 100x100 stippled trapezoid (8x8 stipple)
- 1.54 1.26 1.00 1.00 1.59 Fill 300x300 stippled trapezoid (8x8 stipple)
- 51.41 1.94 1.01 1.00 102.82 Fill 1x1 opaque stippled trapezoid (8x8 stipple)
+ 1.95 1.63 0.98 0.99 3.80 1x1 tiled rectangle (161x145 tile)
+ 1.67 1.26 1.00 1.00 1.67 10x10 tiled rectangle (161x145 tile)
+ 1.13 1.14 1.14 1.14 1.14 100x100 tiled rectangle (161x145 tile)
+ 0.88 1.00 1.00 1.00 0.99 500x500 tiled rectangle (161x145 tile)
+ 1.93 1.63 1.00 1.00 3.53 1x1 tiled rectangle (216x208 tile)
+ 1.69 1.26 1.00 1.00 1.66 10x10 tiled rectangle (216x208 tile)
+ 1.00 1.00 1.00 1.00 1.00 100x100 tiled rectangle (216x208 tile)
+ 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (216x208 tile)
+ 1.82 1.70 1.00 1.00 3.38 1-pixel line segment
+ 2.07 1.56 0.90 1.00 3.31 10-pixel line segment
+ 1.29 1.10 1.00 1.00 1.27 100-pixel line segment
+ 1.05 1.06 1.03 1.03 1.09 500-pixel line segment
+ 1.30 1.13 1.00 1.00 1.29 100-pixel line segment (1 kid)
+ 1.32 1.15 1.00 1.00 1.32 100-pixel line segment (2 kids)
+ 1.33 1.16 1.00 1.00 1.33 100-pixel line segment (3 kids)
+ 1.92 1.64 1.00 1.00 3.73 10-pixel dashed segment
+ 1.34 1.16 1.00 1.00 1.34 100-pixel dashed segment
+ 1.24 1.11 0.99 0.97 1.23 100-pixel double-dashed segment
+ 1.72 1.77 1.00 1.00 3.25 10-pixel horizontal line segment
+ 1.83 1.66 1.01 1.00 3.54 100-pixel horizontal line segment
+ 1.86 1.30 1.00 1.00 1.84 500-pixel horizontal line segment
+ 2.11 1.52 1.00 0.99 3.02 10-pixel vertical line segment
+ 1.21 1.10 1.00 1.00 1.20 100-pixel vertical line segment
+ 1.03 1.03 1.00 1.00 1.02 500-pixel vertical line segment
+ 4.42 1.68 1.00 1.01 4.64 10x1 wide horizontal line segment
+ 1.83 1.31 1.00 1.00 1.83 100x10 wide horizontal line segment
+ 1.07 1.00 0.96 1.00 1.07 500x50 wide horizontal line segment
+ 4.10 1.67 1.00 1.00 4.62 10x1 wide vertical line segment
+ 1.50 1.24 1.06 1.06 1.48 100x10 wide vertical line segment
+ 1.06 1.03 1.00 1.00 1.05 500x50 wide vertical line segment
+ 2.54 1.61 1.00 1.00 3.61 1-pixel line
+ 2.71 1.48 1.00 1.00 2.67 10-pixel line
+ 1.19 1.09 1.00 1.00 1.19 100-pixel line
+ 1.04 1.02 1.00 1.00 1.03 500-pixel line
+ 2.68 1.51 0.98 1.00 3.17 10-pixel dashed line
+ 1.23 1.11 0.99 0.99 1.23 100-pixel dashed line
+ 1.15 1.08 1.00 1.00 1.15 100-pixel double-dashed line
+ 2.27 1.39 1.00 1.00 2.23 10x1 wide line
+ 1.20 1.09 1.00 1.00 1.20 100x10 wide line
+ 1.04 1.02 1.00 1.00 1.04 500x50 wide line
+ 1.52 1.45 1.00 1.00 1.52 100x10 wide dashed line
+ 1.54 1.47 1.00 1.00 1.54 100x10 wide double-dashed line
+ 1.97 1.30 0.96 0.95 1.95 10x10 rectangle outline
+ 1.44 1.27 1.00 1.00 1.43 100x100 rectangle outline
+ 3.22 2.16 1.10 1.09 3.61 500x500 rectangle outline
+ 1.95 1.34 1.00 1.00 1.90 10x10 wide rectangle outline
+ 1.14 1.14 1.00 1.00 1.13 100x100 wide rectangle outline
+ 1.00 1.00 1.00 1.00 1.00 500x500 wide rectangle outline
+ 1.57 1.72 1.00 1.00 3.03 1-pixel circle
+ 1.96 1.35 1.00 1.00 1.92 10-pixel circle
+ 1.21 1.07 0.86 0.97 1.20 100-pixel circle
+ 1.08 1.04 1.00 1.00 1.08 500-pixel circle
+ 1.39 1.19 1.03 1.03 1.38 100-pixel dashed circle
+ 1.21 1.11 1.00 1.00 1.23 100-pixel double-dashed circle
+ 1.59 1.28 1.00 1.00 1.58 10-pixel wide circle
+ 1.22 1.12 0.99 1.00 1.22 100-pixel wide circle
+ 1.06 1.04 1.00 1.00 1.05 500-pixel wide circle
+ 1.87 1.84 1.00 1.00 1.85 100-pixel wide dashed circle
+ 1.90 1.93 1.01 1.01 1.90 100-pixel wide double-dashed circle
+ 2.13 1.43 1.00 1.00 2.32 10-pixel partial circle
+ 1.42 1.18 1.00 1.00 1.42 100-pixel partial circle
+ 1.92 1.85 1.01 1.01 1.89 10-pixel wide partial circle
+ 1.73 1.67 1.00 1.00 1.73 100-pixel wide partial circle
+ 1.36 1.95 1.00 1.00 2.64 1-pixel solid circle
+ 2.02 1.37 1.00 1.00 2.03 10-pixel solid circle
+ 1.19 1.09 1.00 1.00 1.19 100-pixel solid circle
+ 1.02 0.99 1.00 1.00 1.01 500-pixel solid circle
+ 1.74 1.28 1.00 0.88 1.73 10-pixel fill chord partial circle
+ 1.31 1.13 1.00 1.00 1.31 100-pixel fill chord partial circle
+ 1.67 1.31 1.03 1.03 1.72 10-pixel fill slice partial circle
+ 1.30 1.13 1.00 1.00 1.28 100-pixel fill slice partial circle
+ 2.45 1.49 1.01 1.00 2.71 10-pixel ellipse
+ 1.22 1.10 1.00 1.00 1.22 100-pixel ellipse
+ 1.09 1.04 1.00 1.00 1.09 500-pixel ellipse
+ 1.90 1.28 1.00 1.00 1.89 100-pixel dashed ellipse
+ 1.62 1.24 0.96 0.97 1.61 100-pixel double-dashed ellipse
+ 2.43 1.50 1.00 1.00 2.42 10-pixel wide ellipse
+ 1.61 1.28 1.03 1.03 1.60 100-pixel wide ellipse
+ 1.08 1.05 1.00 1.00 1.08 500-pixel wide ellipse
+ 1.93 1.88 1.00 1.00 1.88 100-pixel wide dashed ellipse
+ 1.94 1.89 1.01 1.00 1.94 100-pixel wide double-dashed ellipse
+ 2.31 1.48 1.00 1.00 2.67 10-pixel partial ellipse
+ 1.38 1.17 1.00 1.00 1.38 100-pixel partial ellipse
+ 2.00 1.85 0.98 0.97 1.98 10-pixel wide partial ellipse
+ 1.89 1.86 1.00 1.00 1.89 100-pixel wide partial ellipse
+ 3.49 1.60 1.00 1.00 3.65 10-pixel filled ellipse
+ 1.67 1.26 1.00 1.00 1.67 100-pixel filled ellipse
+ 1.06 1.04 1.00 1.00 1.06 500-pixel filled ellipse
+ 2.38 1.43 1.01 1.00 2.32 10-pixel fill chord partial ellipse
+ 2.06 1.30 1.00 1.00 2.05 100-pixel fill chord partial ellipse
+ 2.27 1.41 1.00 1.00 2.27 10-pixel fill slice partial ellipse
+ 1.98 1.33 1.00 0.97 1.97 100-pixel fill slice partial ellipse
+ 57.46 1.99 1.01 1.00 114.92 Fill 1x1 equivalent triangle
+ 56.94 1.98 1.01 1.00 73.89 Fill 10x10 equivalent triangle
+ 6.07 1.75 1.00 1.00 6.07 Fill 100x100 equivalent triangle
+ 51.12 1.98 1.00 1.00 102.81 Fill 1x1 trapezoid
+ 51.42 1.82 1.01 1.00 94.89 Fill 10x10 trapezoid
+ 6.47 1.80 1.00 1.00 6.44 Fill 100x100 trapezoid
+ 1.56 1.28 1.00 0.99 1.56 Fill 300x300 trapezoid
+ 51.27 1.97 0.96 0.97 102.54 Fill 1x1 stippled trapezoid (8x8 stipple)
+ 51.73 2.00 1.02 1.02 67.92 Fill 10x10 stippled trapezoid (8x8 stipple)
+ 5.36 1.72 1.00 1.00 5.36 Fill 100x100 stippled trapezoid (8x8 stipple)
+ 1.54 1.26 1.00 1.00 1.59 Fill 300x300 stippled trapezoid (8x8 stipple)
+ 51.41 1.94 1.01 1.00 102.82 Fill 1x1 opaque stippled trapezoid (8x8 stipple)
50.71 1.95 0.99 1.00 65.44 Fill 10x10 opaque stippled trapezoid (8x8...
5.33 1.73 1.00 1.00 5.36 Fill 100x100 opaque stippled trapezoid (8x8...
1.58 1.25 1.00 1.00 1.58 Fill 300x300 opaque stippled trapezoid (8x8...
- 51.56 1.96 0.99 0.90 103.68 Fill 1x1 tiled trapezoid (4x4 tile)
- 51.59 1.99 1.01 1.01 62.25 Fill 10x10 tiled trapezoid (4x4 tile)
- 5.38 1.72 1.00 1.00 5.38 Fill 100x100 tiled trapezoid (4x4 tile)
- 1.54 1.25 1.00 0.99 1.58 Fill 300x300 tiled trapezoid (4x4 tile)
- 51.70 1.98 1.01 1.01 103.98 Fill 1x1 stippled trapezoid (17x15 stipple)
- 44.86 1.97 1.00 1.00 44.86 Fill 10x10 stippled trapezoid (17x15 stipple)
- 2.74 1.56 1.00 1.00 2.73 Fill 100x100 stippled trapezoid (17x15 stipple)
- 1.29 1.14 1.00 1.00 1.27 Fill 300x300 stippled trapezoid (17x15 stipple)
+ 51.56 1.96 0.99 0.90 103.68 Fill 1x1 tiled trapezoid (4x4 tile)
+ 51.59 1.99 1.01 1.01 62.25 Fill 10x10 tiled trapezoid (4x4 tile)
+ 5.38 1.72 1.00 1.00 5.38 Fill 100x100 tiled trapezoid (4x4 tile)
+ 1.54 1.25 1.00 0.99 1.58 Fill 300x300 tiled trapezoid (4x4 tile)
+ 51.70 1.98 1.01 1.01 103.98 Fill 1x1 stippled trapezoid (17x15 stipple)
+ 44.86 1.97 1.00 1.00 44.86 Fill 10x10 stippled trapezoid (17x15 stipple)
+ 2.74 1.56 1.00 1.00 2.73 Fill 100x100 stippled trapezoid (17x15 stipple)
+ 1.29 1.14 1.00 1.00 1.27 Fill 300x300 stippled trapezoid (17x15 stipple)
51.41 1.96 0.96 0.95 103.39 Fill 1x1 opaque stippled trapezoid (17x15...
45.14 1.96 1.01 1.00 45.14 Fill 10x10 opaque stippled trapezoid (17x15...
2.68 1.56 1.00 1.00 2.68 Fill 100x100 opaque stippled trapezoid (17x15...
1.26 1.10 1.00 1.00 1.28 Fill 300x300 opaque stippled trapezoid (17x15...
- 51.13 1.97 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (17x15 tile)
- 47.58 1.96 1.00 1.00 47.86 Fill 10x10 tiled trapezoid (17x15 tile)
- 2.74 1.56 1.00 1.00 2.74 Fill 100x100 tiled trapezoid (17x15 tile)
- 1.29 1.14 1.00 1.00 1.28 Fill 300x300 tiled trapezoid (17x15 tile)
- 51.13 1.97 0.99 0.97 103.39 Fill 1x1 stippled trapezoid (161x145 stipple)
- 45.14 1.97 1.00 1.00 44.29 Fill 10x10 stippled trapezoid (161x145 stipple)
- 3.02 1.77 1.12 1.12 3.38 Fill 100x100 stippled trapezoid (161x145 stipple)
- 1.31 1.13 1.00 1.00 1.30 Fill 300x300 stippled trapezoid (161x145 stipple)
+ 51.13 1.97 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (17x15 tile)
+ 47.58 1.96 1.00 1.00 47.86 Fill 10x10 tiled trapezoid (17x15 tile)
+ 2.74 1.56 1.00 1.00 2.74 Fill 100x100 tiled trapezoid (17x15 tile)
+ 1.29 1.14 1.00 1.00 1.28 Fill 300x300 tiled trapezoid (17x15 tile)
+ 51.13 1.97 0.99 0.97 103.39 Fill 1x1 stippled trapezoid (161x145 stipple)
+ 45.14 1.97 1.00 1.00 44.29 Fill 10x10 stippled trapezoid (161x145 stipple)
+ 3.02 1.77 1.12 1.12 3.38 Fill 100x100 stippled trapezoid (161x145 stipple)
+ 1.31 1.13 1.00 1.00 1.30 Fill 300x300 stippled trapezoid (161x145 stipple)
51.27 1.97 1.00 1.00 103.10 Fill 1x1 opaque stippled trapezoid (161x145...
45.01 1.97 1.00 1.00 45.01 Fill 10x10 opaque stippled trapezoid (161x145...
2.67 1.56 1.00 1.00 2.69 Fill 100x100 opaque stippled trapezoid (161x145..
1.29 1.13 1.00 1.01 1.27 Fill 300x300 opaque stippled trapezoid (161x145..
- 51.41 1.96 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (161x145 tile)
- 45.01 1.96 0.98 1.00 45.01 Fill 10x10 tiled trapezoid (161x145 tile)
- 2.62 1.36 1.00 1.00 2.69 Fill 100x100 tiled trapezoid (161x145 tile)
- 1.27 1.13 1.00 1.00 1.22 Fill 300x300 tiled trapezoid (161x145 tile)
- 51.13 1.98 1.00 1.00 103.39 Fill 1x1 tiled trapezoid (216x208 tile)
- 45.14 1.97 1.01 0.99 45.14 Fill 10x10 tiled trapezoid (216x208 tile)
- 2.62 1.55 1.00 1.00 2.71 Fill 100x100 tiled trapezoid (216x208 tile)
- 1.28 1.13 1.00 1.00 1.20 Fill 300x300 tiled trapezoid (216x208 tile)
- 50.71 1.95 1.00 1.00 54.70 Fill 10x10 equivalent complex polygon
- 5.51 1.71 0.96 0.98 5.47 Fill 100x100 equivalent complex polygons
- 8.39 1.97 1.00 1.00 16.75 Fill 10x10 64-gon (Convex)
- 8.38 1.83 1.00 1.00 8.43 Fill 100x100 64-gon (Convex)
- 8.50 1.96 1.00 1.00 16.64 Fill 10x10 64-gon (Complex)
- 8.26 1.83 1.00 1.00 8.35 Fill 100x100 64-gon (Complex)
- 14.09 1.87 1.00 1.00 14.05 Char in 80-char line (6x13)
- 11.91 1.87 1.00 1.00 11.95 Char in 70-char line (8x13)
- 11.16 1.85 1.01 1.00 11.10 Char in 60-char line (9x15)
- 10.09 1.78 1.00 1.00 10.09 Char16 in 40-char line (k14)
- 6.15 1.75 1.00 1.00 6.31 Char16 in 23-char line (k24)
- 11.92 1.90 1.03 1.03 11.88 Char in 80-char line (TR 10)
- 8.18 1.78 1.00 0.99 8.17 Char in 30-char line (TR 24)
- 42.83 1.44 1.01 1.00 42.11 Char in 20/40/20 line (6x13, TR 10)
- 27.45 1.43 1.01 1.01 27.45 Char16 in 7/14/7 line (k14, k24)
- 12.13 1.85 1.00 1.00 12.05 Char in 80-char image line (6x13)
- 10.00 1.84 1.00 1.00 10.00 Char in 70-char image line (8x13)
- 9.18 1.83 1.00 1.00 9.12 Char in 60-char image line (9x15)
- 9.66 1.82 0.98 0.95 9.66 Char16 in 40-char image line (k14)
- 5.82 1.72 1.00 1.00 5.99 Char16 in 23-char image line (k24)
- 8.70 1.80 1.00 1.00 8.65 Char in 80-char image line (TR 10)
- 4.67 1.66 1.00 1.00 4.67 Char in 30-char image line (TR 24)
- 84.43 1.47 1.00 1.00 124.18 Scroll 10x10 pixels
- 3.73 1.50 1.00 0.98 3.73 Scroll 100x100 pixels
- 1.00 1.00 1.00 1.00 1.00 Scroll 500x500 pixels
- 84.43 1.51 1.00 1.00 134.02 Copy 10x10 from window to window
- 3.62 1.51 0.98 0.98 3.62 Copy 100x100 from window to window
- 0.89 1.00 1.00 1.00 1.00 Copy 500x500 from window to window
- 57.06 1.99 1.00 1.00 88.64 Copy 10x10 from pixmap to window
- 2.49 2.00 1.00 1.00 2.48 Copy 100x100 from pixmap to window
- 1.00 0.91 1.00 1.00 0.98 Copy 500x500 from pixmap to window
- 2.04 1.01 1.00 1.00 2.03 Copy 10x10 from window to pixmap
- 1.05 1.00 1.00 1.00 1.05 Copy 100x100 from window to pixmap
- 1.00 1.00 0.93 1.00 1.04 Copy 500x500 from window to pixmap
- 58.52 1.03 1.03 1.02 57.95 Copy 10x10 from pixmap to pixmap
- 2.40 1.00 1.00 1.00 2.45 Copy 100x100 from pixmap to pixmap
- 1.00 1.00 1.00 1.00 1.00 Copy 500x500 from pixmap to pixmap
- 51.57 1.92 1.00 1.00 85.75 Copy 10x10 1-bit deep plane
- 6.37 1.75 1.01 1.01 6.37 Copy 100x100 1-bit deep plane
- 1.26 1.11 1.00 1.00 1.24 Copy 500x500 1-bit deep plane
- 4.23 1.63 0.98 0.97 4.38 Copy 10x10 n-bit deep plane
- 1.04 1.02 1.00 1.00 1.04 Copy 100x100 n-bit deep plane
- 1.00 1.00 1.00 1.00 1.00 Copy 500x500 n-bit deep plane
- 6.45 1.98 1.00 1.26 12.80 PutImage 10x10 square
- 1.10 1.87 1.00 1.83 2.11 PutImage 100x100 square
- 1.02 1.93 1.00 1.91 1.91 PutImage 500x500 square
- 4.17 1.78 1.00 1.40 7.18 PutImage XY 10x10 square
- 1.27 1.49 0.97 1.48 2.10 PutImage XY 100x100 square
- 1.00 1.50 1.00 1.50 1.52 PutImage XY 500x500 square
- 1.07 1.01 1.00 1.00 1.06 GetImage 10x10 square
- 1.01 1.00 1.00 1.00 1.01 GetImage 100x100 square
- 1.00 1.00 1.00 1.00 1.00 GetImage 500x500 square
- 1.56 1.00 0.99 0.97 1.56 GetImage XY 10x10 square
- 1.02 1.00 1.00 1.00 1.02 GetImage XY 100x100 square
- 1.00 1.00 1.00 1.00 1.00 GetImage XY 500x500 square
- 1.00 1.00 1.01 0.98 0.95 X protocol NoOperation
- 1.02 1.03 1.04 1.03 1.00 QueryPointer
- 1.03 1.02 1.04 1.03 1.00 GetProperty
-100.41 1.51 1.00 1.00 198.76 Change graphics context
- 45.81 1.00 0.99 0.97 57.10 Create and map subwindows (4 kids)
- 78.45 1.01 1.02 1.02 63.07 Create and map subwindows (16 kids)
- 73.91 1.01 1.00 1.00 56.37 Create and map subwindows (25 kids)
- 73.22 1.00 1.00 1.00 49.07 Create and map subwindows (50 kids)
- 72.36 1.01 0.99 1.00 32.14 Create and map subwindows (75 kids)
- 70.34 1.00 1.00 1.00 30.12 Create and map subwindows (100 kids)
- 55.00 1.00 1.00 0.99 23.75 Create and map subwindows (200 kids)
- 55.30 1.01 1.00 1.00 141.03 Create unmapped window (4 kids)
- 55.38 1.01 1.01 1.00 163.25 Create unmapped window (16 kids)
- 54.75 0.96 1.00 0.99 166.95 Create unmapped window (25 kids)
- 54.83 1.00 1.00 0.99 178.81 Create unmapped window (50 kids)
- 55.38 1.01 1.01 1.00 181.20 Create unmapped window (75 kids)
- 55.38 1.01 1.01 1.00 181.20 Create unmapped window (100 kids)
- 54.87 1.01 1.01 1.00 182.05 Create unmapped window (200 kids)
- 28.13 1.00 1.00 1.00 30.75 Map window via parent (4 kids)
- 36.14 1.01 1.01 1.01 32.58 Map window via parent (16 kids)
- 26.13 1.00 0.98 0.95 29.85 Map window via parent (25 kids)
- 40.07 1.00 1.01 1.00 27.57 Map window via parent (50 kids)
- 23.26 0.99 1.00 1.00 18.23 Map window via parent (75 kids)
- 22.91 0.99 1.00 0.99 16.52 Map window via parent (100 kids)
- 27.79 1.00 1.00 0.99 12.50 Map window via parent (200 kids)
- 22.35 1.00 1.00 1.00 56.19 Unmap window via parent (4 kids)
- 9.57 1.00 0.99 1.00 89.78 Unmap window via parent (16 kids)
- 80.77 1.01 1.00 1.00 103.85 Unmap window via parent (25 kids)
- 96.34 1.00 1.00 1.00 116.06 Unmap window via parent (50 kids)
- 99.72 1.00 1.00 1.00 124.93 Unmap window via parent (75 kids)
-112.36 1.00 1.00 1.00 125.27 Unmap window via parent (100 kids)
-105.41 1.00 1.00 0.99 120.00 Unmap window via parent (200 kids)
- 51.29 1.03 1.02 1.02 74.19 Destroy window via parent (4 kids)
- 86.75 0.99 0.99 0.99 116.87 Destroy window via parent (16 kids)
-106.43 1.01 1.01 1.01 127.49 Destroy window via parent (25 kids)
-120.34 1.01 1.01 1.00 140.11 Destroy window via parent (50 kids)
-126.67 1.00 0.99 0.99 145.00 Destroy window via parent (75 kids)
-126.11 1.01 1.01 1.00 140.56 Destroy window via parent (100 kids)
-128.57 1.01 1.00 1.00 137.91 Destroy window via parent (200 kids)
- 16.04 0.88 1.00 1.00 20.36 Hide/expose window via popup (4 kids)
- 19.04 1.01 1.00 1.00 23.48 Hide/expose window via popup (16 kids)
- 19.22 1.00 1.00 1.00 20.44 Hide/expose window via popup (25 kids)
- 17.41 1.00 0.91 0.97 17.68 Hide/expose window via popup (50 kids)
- 17.29 1.01 1.00 1.01 17.07 Hide/expose window via popup (75 kids)
- 16.74 1.00 1.00 1.00 16.17 Hide/expose window via popup (100 kids)
- 10.30 1.00 1.00 1.00 10.51 Hide/expose window via popup (200 kids)
- 16.48 1.01 1.00 1.00 26.05 Move window (4 kids)
- 17.01 0.95 1.00 1.00 23.97 Move window (16 kids)
- 16.95 1.00 1.00 1.00 22.90 Move window (25 kids)
- 16.05 1.01 1.00 1.00 21.32 Move window (50 kids)
- 15.58 1.00 0.98 0.98 19.44 Move window (75 kids)
- 14.98 1.02 1.03 1.03 18.17 Move window (100 kids)
- 10.90 1.01 1.01 1.00 12.68 Move window (200 kids)
- 49.42 1.00 1.00 1.00 198.27 Moved unmapped window (4 kids)
- 50.72 0.97 1.00 1.00 193.66 Moved unmapped window (16 kids)
- 50.87 1.00 0.99 1.00 195.09 Moved unmapped window (25 kids)
- 50.72 1.00 1.00 1.00 189.34 Moved unmapped window (50 kids)
- 50.87 1.00 1.00 1.00 191.33 Moved unmapped window (75 kids)
- 50.87 1.00 1.00 0.90 186.71 Moved unmapped window (100 kids)
- 50.87 1.00 1.00 1.00 179.19 Moved unmapped window (200 kids)
- 41.04 1.00 1.00 1.00 56.61 Move window via parent (4 kids)
- 69.81 1.00 1.00 1.00 130.82 Move window via parent (16 kids)
- 95.81 1.00 1.00 1.00 141.92 Move window via parent (25 kids)
- 95.98 1.00 1.00 1.00 149.43 Move window via parent (50 kids)
- 96.59 1.01 1.01 1.00 153.98 Move window via parent (75 kids)
- 97.19 1.00 1.00 1.00 157.30 Move window via parent (100 kids)
- 96.67 1.00 0.99 0.96 159.44 Move window via parent (200 kids)
- 17.75 1.01 1.00 1.00 27.61 Resize window (4 kids)
- 17.94 1.00 1.00 0.99 25.42 Resize window (16 kids)
- 17.92 1.01 1.00 1.00 24.47 Resize window (25 kids)
- 17.24 0.97 1.00 1.00 24.14 Resize window (50 kids)
- 16.81 1.00 1.00 0.99 22.75 Resize window (75 kids)
- 16.08 1.00 1.00 1.00 21.20 Resize window (100 kids)
- 12.92 1.00 0.99 1.00 16.26 Resize window (200 kids)
- 52.94 1.01 1.00 1.00 327.12 Resize unmapped window (4 kids)
- 53.60 1.01 1.01 1.01 333.71 Resize unmapped window (16 kids)
- 52.99 1.00 1.00 1.00 337.29 Resize unmapped window (25 kids)
- 51.98 1.00 1.00 1.00 329.38 Resize unmapped window (50 kids)
- 53.05 0.89 1.00 1.00 322.60 Resize unmapped window (75 kids)
- 53.05 1.00 1.00 1.00 318.08 Resize unmapped window (100 kids)
- 53.11 1.00 1.00 0.99 306.21 Resize unmapped window (200 kids)
- 16.76 1.00 0.96 1.00 19.46 Circulate window (4 kids)
- 17.24 1.00 1.00 0.97 16.24 Circulate window (16 kids)
- 16.30 1.03 1.03 1.03 15.85 Circulate window (25 kids)
- 13.45 1.00 1.00 1.00 14.90 Circulate window (50 kids)
- 12.91 1.00 1.00 1.00 13.06 Circulate window (75 kids)
- 11.30 0.98 1.00 1.00 11.03 Circulate window (100 kids)
- 7.58 1.01 1.01 0.99 7.47 Circulate window (200 kids)
- 1.01 1.01 0.98 1.00 0.95 Circulate Unmapped window (4 kids)
- 1.07 1.07 1.01 1.07 1.02 Circulate Unmapped window (16 kids)
- 1.04 1.09 1.06 1.05 0.97 Circulate Unmapped window (25 kids)
- 1.04 1.23 1.20 1.18 1.05 Circulate Unmapped window (50 kids)
- 1.18 1.53 1.19 1.45 1.24 Circulate Unmapped window (75 kids)
- 1.08 1.02 1.01 1.74 1.01 Circulate Unmapped window (100 kids)
- 1.01 1.12 0.98 0.91 0.97 Circulate Unmapped window (200 kids)
- </verb>
-
-<sect2>Profiling with OProfile
-
-<p>OProfile (available from http://oprofile.sourceforge.net/) is a
+ 51.41 1.96 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (161x145 tile)
+ 45.01 1.96 0.98 1.00 45.01 Fill 10x10 tiled trapezoid (161x145 tile)
+ 2.62 1.36 1.00 1.00 2.69 Fill 100x100 tiled trapezoid (161x145 tile)
+ 1.27 1.13 1.00 1.00 1.22 Fill 300x300 tiled trapezoid (161x145 tile)
+ 51.13 1.98 1.00 1.00 103.39 Fill 1x1 tiled trapezoid (216x208 tile)
+ 45.14 1.97 1.01 0.99 45.14 Fill 10x10 tiled trapezoid (216x208 tile)
+ 2.62 1.55 1.00 1.00 2.71 Fill 100x100 tiled trapezoid (216x208 tile)
+ 1.28 1.13 1.00 1.00 1.20 Fill 300x300 tiled trapezoid (216x208 tile)
+ 50.71 1.95 1.00 1.00 54.70 Fill 10x10 equivalent complex polygon
+ 5.51 1.71 0.96 0.98 5.47 Fill 100x100 equivalent complex polygons
+ 8.39 1.97 1.00 1.00 16.75 Fill 10x10 64-gon (Convex)
+ 8.38 1.83 1.00 1.00 8.43 Fill 100x100 64-gon (Convex)
+ 8.50 1.96 1.00 1.00 16.64 Fill 10x10 64-gon (Complex)
+ 8.26 1.83 1.00 1.00 8.35 Fill 100x100 64-gon (Complex)
+ 14.09 1.87 1.00 1.00 14.05 Char in 80-char line (6x13)
+ 11.91 1.87 1.00 1.00 11.95 Char in 70-char line (8x13)
+ 11.16 1.85 1.01 1.00 11.10 Char in 60-char line (9x15)
+ 10.09 1.78 1.00 1.00 10.09 Char16 in 40-char line (k14)
+ 6.15 1.75 1.00 1.00 6.31 Char16 in 23-char line (k24)
+ 11.92 1.90 1.03 1.03 11.88 Char in 80-char line (TR 10)
+ 8.18 1.78 1.00 0.99 8.17 Char in 30-char line (TR 24)
+ 42.83 1.44 1.01 1.00 42.11 Char in 20/40/20 line (6x13, TR 10)
+ 27.45 1.43 1.01 1.01 27.45 Char16 in 7/14/7 line (k14, k24)
+ 12.13 1.85 1.00 1.00 12.05 Char in 80-char image line (6x13)
+ 10.00 1.84 1.00 1.00 10.00 Char in 70-char image line (8x13)
+ 9.18 1.83 1.00 1.00 9.12 Char in 60-char image line (9x15)
+ 9.66 1.82 0.98 0.95 9.66 Char16 in 40-char image line (k14)
+ 5.82 1.72 1.00 1.00 5.99 Char16 in 23-char image line (k24)
+ 8.70 1.80 1.00 1.00 8.65 Char in 80-char image line (TR 10)
+ 4.67 1.66 1.00 1.00 4.67 Char in 30-char image line (TR 24)
+ 84.43 1.47 1.00 1.00 124.18 Scroll 10x10 pixels
+ 3.73 1.50 1.00 0.98 3.73 Scroll 100x100 pixels
+ 1.00 1.00 1.00 1.00 1.00 Scroll 500x500 pixels
+ 84.43 1.51 1.00 1.00 134.02 Copy 10x10 from window to window
+ 3.62 1.51 0.98 0.98 3.62 Copy 100x100 from window to window
+ 0.89 1.00 1.00 1.00 1.00 Copy 500x500 from window to window
+ 57.06 1.99 1.00 1.00 88.64 Copy 10x10 from pixmap to window
+ 2.49 2.00 1.00 1.00 2.48 Copy 100x100 from pixmap to window
+ 1.00 0.91 1.00 1.00 0.98 Copy 500x500 from pixmap to window
+ 2.04 1.01 1.00 1.00 2.03 Copy 10x10 from window to pixmap
+ 1.05 1.00 1.00 1.00 1.05 Copy 100x100 from window to pixmap
+ 1.00 1.00 0.93 1.00 1.04 Copy 500x500 from window to pixmap
+ 58.52 1.03 1.03 1.02 57.95 Copy 10x10 from pixmap to pixmap
+ 2.40 1.00 1.00 1.00 2.45 Copy 100x100 from pixmap to pixmap
+ 1.00 1.00 1.00 1.00 1.00 Copy 500x500 from pixmap to pixmap
+ 51.57 1.92 1.00 1.00 85.75 Copy 10x10 1-bit deep plane
+ 6.37 1.75 1.01 1.01 6.37 Copy 100x100 1-bit deep plane
+ 1.26 1.11 1.00 1.00 1.24 Copy 500x500 1-bit deep plane
+ 4.23 1.63 0.98 0.97 4.38 Copy 10x10 n-bit deep plane
+ 1.04 1.02 1.00 1.00 1.04 Copy 100x100 n-bit deep plane
+ 1.00 1.00 1.00 1.00 1.00 Copy 500x500 n-bit deep plane
+ 6.45 1.98 1.00 1.26 12.80 PutImage 10x10 square
+ 1.10 1.87 1.00 1.83 2.11 PutImage 100x100 square
+ 1.02 1.93 1.00 1.91 1.91 PutImage 500x500 square
+ 4.17 1.78 1.00 1.40 7.18 PutImage XY 10x10 square
+ 1.27 1.49 0.97 1.48 2.10 PutImage XY 100x100 square
+ 1.00 1.50 1.00 1.50 1.52 PutImage XY 500x500 square
+ 1.07 1.01 1.00 1.00 1.06 GetImage 10x10 square
+ 1.01 1.00 1.00 1.00 1.01 GetImage 100x100 square
+ 1.00 1.00 1.00 1.00 1.00 GetImage 500x500 square
+ 1.56 1.00 0.99 0.97 1.56 GetImage XY 10x10 square
+ 1.02 1.00 1.00 1.00 1.02 GetImage XY 100x100 square
+ 1.00 1.00 1.00 1.00 1.00 GetImage XY 500x500 square
+ 1.00 1.00 1.01 0.98 0.95 X protocol NoOperation
+ 1.02 1.03 1.04 1.03 1.00 QueryPointer
+ 1.03 1.02 1.04 1.03 1.00 GetProperty
+100.41 1.51 1.00 1.00 198.76 Change graphics context
+ 45.81 1.00 0.99 0.97 57.10 Create and map subwindows (4 kids)
+ 78.45 1.01 1.02 1.02 63.07 Create and map subwindows (16 kids)
+ 73.91 1.01 1.00 1.00 56.37 Create and map subwindows (25 kids)
+ 73.22 1.00 1.00 1.00 49.07 Create and map subwindows (50 kids)
+ 72.36 1.01 0.99 1.00 32.14 Create and map subwindows (75 kids)
+ 70.34 1.00 1.00 1.00 30.12 Create and map subwindows (100 kids)
+ 55.00 1.00 1.00 0.99 23.75 Create and map subwindows (200 kids)
+ 55.30 1.01 1.00 1.00 141.03 Create unmapped window (4 kids)
+ 55.38 1.01 1.01 1.00 163.25 Create unmapped window (16 kids)
+ 54.75 0.96 1.00 0.99 166.95 Create unmapped window (25 kids)
+ 54.83 1.00 1.00 0.99 178.81 Create unmapped window (50 kids)
+ 55.38 1.01 1.01 1.00 181.20 Create unmapped window (75 kids)
+ 55.38 1.01 1.01 1.00 181.20 Create unmapped window (100 kids)
+ 54.87 1.01 1.01 1.00 182.05 Create unmapped window (200 kids)
+ 28.13 1.00 1.00 1.00 30.75 Map window via parent (4 kids)
+ 36.14 1.01 1.01 1.01 32.58 Map window via parent (16 kids)
+ 26.13 1.00 0.98 0.95 29.85 Map window via parent (25 kids)
+ 40.07 1.00 1.01 1.00 27.57 Map window via parent (50 kids)
+ 23.26 0.99 1.00 1.00 18.23 Map window via parent (75 kids)
+ 22.91 0.99 1.00 0.99 16.52 Map window via parent (100 kids)
+ 27.79 1.00 1.00 0.99 12.50 Map window via parent (200 kids)
+ 22.35 1.00 1.00 1.00 56.19 Unmap window via parent (4 kids)
+ 9.57 1.00 0.99 1.00 89.78 Unmap window via parent (16 kids)
+ 80.77 1.01 1.00 1.00 103.85 Unmap window via parent (25 kids)
+ 96.34 1.00 1.00 1.00 116.06 Unmap window via parent (50 kids)
+ 99.72 1.00 1.00 1.00 124.93 Unmap window via parent (75 kids)
+112.36 1.00 1.00 1.00 125.27 Unmap window via parent (100 kids)
+105.41 1.00 1.00 0.99 120.00 Unmap window via parent (200 kids)
+ 51.29 1.03 1.02 1.02 74.19 Destroy window via parent (4 kids)
+ 86.75 0.99 0.99 0.99 116.87 Destroy window via parent (16 kids)
+106.43 1.01 1.01 1.01 127.49 Destroy window via parent (25 kids)
+120.34 1.01 1.01 1.00 140.11 Destroy window via parent (50 kids)
+126.67 1.00 0.99 0.99 145.00 Destroy window via parent (75 kids)
+126.11 1.01 1.01 1.00 140.56 Destroy window via parent (100 kids)
+128.57 1.01 1.00 1.00 137.91 Destroy window via parent (200 kids)
+ 16.04 0.88 1.00 1.00 20.36 Hide/expose window via popup (4 kids)
+ 19.04 1.01 1.00 1.00 23.48 Hide/expose window via popup (16 kids)
+ 19.22 1.00 1.00 1.00 20.44 Hide/expose window via popup (25 kids)
+ 17.41 1.00 0.91 0.97 17.68 Hide/expose window via popup (50 kids)
+ 17.29 1.01 1.00 1.01 17.07 Hide/expose window via popup (75 kids)
+ 16.74 1.00 1.00 1.00 16.17 Hide/expose window via popup (100 kids)
+ 10.30 1.00 1.00 1.00 10.51 Hide/expose window via popup (200 kids)
+ 16.48 1.01 1.00 1.00 26.05 Move window (4 kids)
+ 17.01 0.95 1.00 1.00 23.97 Move window (16 kids)
+ 16.95 1.00 1.00 1.00 22.90 Move window (25 kids)
+ 16.05 1.01 1.00 1.00 21.32 Move window (50 kids)
+ 15.58 1.00 0.98 0.98 19.44 Move window (75 kids)
+ 14.98 1.02 1.03 1.03 18.17 Move window (100 kids)
+ 10.90 1.01 1.01 1.00 12.68 Move window (200 kids)
+ 49.42 1.00 1.00 1.00 198.27 Moved unmapped window (4 kids)
+ 50.72 0.97 1.00 1.00 193.66 Moved unmapped window (16 kids)
+ 50.87 1.00 0.99 1.00 195.09 Moved unmapped window (25 kids)
+ 50.72 1.00 1.00 1.00 189.34 Moved unmapped window (50 kids)
+ 50.87 1.00 1.00 1.00 191.33 Moved unmapped window (75 kids)
+ 50.87 1.00 1.00 0.90 186.71 Moved unmapped window (100 kids)
+ 50.87 1.00 1.00 1.00 179.19 Moved unmapped window (200 kids)
+ 41.04 1.00 1.00 1.00 56.61 Move window via parent (4 kids)
+ 69.81 1.00 1.00 1.00 130.82 Move window via parent (16 kids)
+ 95.81 1.00 1.00 1.00 141.92 Move window via parent (25 kids)
+ 95.98 1.00 1.00 1.00 149.43 Move window via parent (50 kids)
+ 96.59 1.01 1.01 1.00 153.98 Move window via parent (75 kids)
+ 97.19 1.00 1.00 1.00 157.30 Move window via parent (100 kids)
+ 96.67 1.00 0.99 0.96 159.44 Move window via parent (200 kids)
+ 17.75 1.01 1.00 1.00 27.61 Resize window (4 kids)
+ 17.94 1.00 1.00 0.99 25.42 Resize window (16 kids)
+ 17.92 1.01 1.00 1.00 24.47 Resize window (25 kids)
+ 17.24 0.97 1.00 1.00 24.14 Resize window (50 kids)
+ 16.81 1.00 1.00 0.99 22.75 Resize window (75 kids)
+ 16.08 1.00 1.00 1.00 21.20 Resize window (100 kids)
+ 12.92 1.00 0.99 1.00 16.26 Resize window (200 kids)
+ 52.94 1.01 1.00 1.00 327.12 Resize unmapped window (4 kids)
+ 53.60 1.01 1.01 1.01 333.71 Resize unmapped window (16 kids)
+ 52.99 1.00 1.00 1.00 337.29 Resize unmapped window (25 kids)
+ 51.98 1.00 1.00 1.00 329.38 Resize unmapped window (50 kids)
+ 53.05 0.89 1.00 1.00 322.60 Resize unmapped window (75 kids)
+ 53.05 1.00 1.00 1.00 318.08 Resize unmapped window (100 kids)
+ 53.11 1.00 1.00 0.99 306.21 Resize unmapped window (200 kids)
+ 16.76 1.00 0.96 1.00 19.46 Circulate window (4 kids)
+ 17.24 1.00 1.00 0.97 16.24 Circulate window (16 kids)
+ 16.30 1.03 1.03 1.03 15.85 Circulate window (25 kids)
+ 13.45 1.00 1.00 1.00 14.90 Circulate window (50 kids)
+ 12.91 1.00 1.00 1.00 13.06 Circulate window (75 kids)
+ 11.30 0.98 1.00 1.00 11.03 Circulate window (100 kids)
+ 7.58 1.01 1.01 0.99 7.47 Circulate window (200 kids)
+ 1.01 1.01 0.98 1.00 0.95 Circulate Unmapped window (4 kids)
+ 1.07 1.07 1.01 1.07 1.02 Circulate Unmapped window (16 kids)
+ 1.04 1.09 1.06 1.05 0.97 Circulate Unmapped window (25 kids)
+ 1.04 1.23 1.20 1.18 1.05 Circulate Unmapped window (50 kids)
+ 1.18 1.53 1.19 1.45 1.24 Circulate Unmapped window (75 kids)
+ 1.08 1.02 1.01 1.74 1.01 Circulate Unmapped window (100 kids)
+ 1.01 1.12 0.98 0.91 0.97 Circulate Unmapped window (200 kids)
+</screen>
+</para>
+</sect3>
+
+<sect3>
+<title>Profiling with OProfile</title>
+
+<para>OProfile (available from http://oprofile.sourceforge.net/) is a
system-wide profiler for Linux systems that uses processor-level
counters to collect sampling data. OProfile can provide information
-that is similar to that provided by <tt/gprof/, but without the
+that is similar to that provided by <command>gprof</command>, but without the
necessity of recompiling the program with special instrumentation (i.e.,
OProfile can collect statistical profiling information about optimized
programs). A test harness was developed to collect OProfile data for
-each <tt/x11perf/ test individually.
+each <command>x11perf</command> test individually.
+</para>
-<p>Test runs were performed using the RETIRED_INSNS counter on the AMD
+<para>Test runs were performed using the RETIRED_INSNS counter on the AMD
Athlon and the CPU_CLK_HALTED counter on the Intel Pentium III (with a
test configuration different from the one described above). We have
-examined OProfile output and have compared it with <tt/gprof/ output.
+examined OProfile output and have compared it with <command>gprof</command> output.
This investigation has not produced results that yield performance
-increases in <tt/x11perf/ numbers.
+increases in <command>x11perf</command> numbers.
+</para>
+
+</sect3>
<!--
<sect3>Retired Instructions
@@ -2170,7 +2687,7 @@ was spent looking at Hash() function, but optimizations in this routine did not lead to a dramatic increase in <tt/x11perf/ performance.
-->
-<!--
+<!--
<sect3>Clock Cycles
<p>Retired instructions can be misleading because Intel/AMD instructions
@@ -2197,11 +2714,12 @@ StandardReadRequestFromClient(). Hash() time was generally above 5% but less than 10% of total time.
-->
-<sect2>X Test Suite
+<sect3>
+<title>X Test Suite</title>
-<p>The X Test Suite was run on the fully optimized DMX server using the
+<para>The X Test Suite was run on the fully optimized DMX server using the
configuration described above. The following failures were noted:
- <verb>
+<screen>
XListPixmapFormats: Test 1 [1]
XChangeWindowAttributes: Test 32 [1]
XCreateWindow: Test 30 [1]
@@ -2217,23 +2735,34 @@ XChangeKeyboardControl: Test 9, 10 [1] behavior of the Xinerama implementation.
[3] Newly noted error that has been verified as a Xinerama
implementation bug.
- </verb>
-
+</screen>
+</para>
+
+</sect3>
+
+</sect2>
+
<!-- ============================================================ -->
-<sect1>Phase III
+<sect2>
+<title>Phase III</title>
-<p>During the third phase of development, support was provided for the
+<para>During the third phase of development, support was provided for the
following extensions: SHAPE, RENDER, XKEYBOARD, XInput.
+</para>
-<sect2>SHAPE
+<sect3>
+<title>SHAPE</title>
-<p>The SHAPE extension is supported. Test applications (e.g., xeyes and
+<para>The SHAPE extension is supported. Test applications (e.g., xeyes and
oclock) and window managers that make use of the SHAPE extension will
work as expected.
+</para>
+</sect3>
-<sect2>RENDER
+<sect3>
+<title>RENDER</title>
-<p>The RENDER extension is supported. The version included in the DMX
+<para>The RENDER extension is supported. The version included in the DMX
CVS tree is version 0.2, and this version is fully supported by Xdmx.
Applications using only version 0.2 functions will work correctly;
however, some apps that make use of functions from later versions do not
@@ -2242,10 +2771,13 @@ will fail with a Bad Implementation error when using post-version 0.2 functions. This is expected behavior. When the DMX CVS tree is updated
to include newer versions of RENDER, support for these newer functions
will be added to the DMX X server.
+</para>
+</sect3>
-<sect2>XKEYBOARD
+<sect3>
+<title>XKEYBOARD</title>
-<p>The XKEYBOARD extension is supported. If present on the back-end X
+<para>The XKEYBOARD extension is supported. If present on the back-end X
servers, the XKEYBOARD extension will be used to obtain information
about the type of the keyboard for initialization. Otherwise, the
keyboard will be initialized using defaults. Note that this departs
@@ -2253,39 +2785,52 @@ from older behavior: when Xdmx is compiled without XKEYBOARD support, the map from the back-end X server will be preserved. With XKEYBOARD
support, the map is not preserved because better information and control
of the keyboard is available.
+</para>
+</sect3>
-<sect2>XInput
+<sect3>
+<title>XInput</title>
-<p>The XInput extension is supported. Any device can be used as a core
+<para>The XInput extension is supported. Any device can be used as a core
device and be used as an XInput extension device, with the exception of
core devices on the back-end servers. This limitation is present
because cursor handling on the back-end requires that the back-end
cursor sometimes track the Xdmx core cursor -- behavior that is
incompatible with using the back-end pointer as a non-core device.
+</para>
-<p>Currently, back-end extension devices are not available as Xdmx
+<para>Currently, back-end extension devices are not available as Xdmx
extension devices, but this limitation should be removed in the future.
+</para>
-<p>To demonstrate the XInput extension, and to provide more examples for
+<para>To demonstrate the XInput extension, and to provide more examples for
low-level input device driver writers, USB device drivers have been
written for mice (usb-mou), keyboards (usb-kbd), and
non-mouse/non-keyboard USB devices (usb-oth). Please see the man page
for information on Linux kernel drivers that are required for using
these Xdmx drivers.
+</para>
+</sect3>
+
+<sect3>
+<title>DPMS</title>
-<sect2>DPMS
+<para>The DPMS extension is exported but does not do anything at this time.
+</para>
-<p>The DPMS extension is exported but does not do anything at this time.
+</sect3>
-<sect2>Other Extensions
+<sect3>
+<title>Other Extensions</title>
-<p>The LBX,
+<para>The LBX,
SECURITY,
XC-APPGROUP, and
XFree86-Bigfont
extensions do not require any special Xdmx support and have been exported.
+</para>
-<p>The
+<para>The
BIG-REQUESTS,
DEC-XTRAP,
DOUBLE-BUFFER,
@@ -2307,74 +2852,99 @@ extensions do not require any special Xdmx support and have been exported. XFree86-Misc,
XFree86-VidModeExtension, and
XVideo
-extensions are <it/not/ supported at this time, but will be evaluated
-for inclusion in future DMX releases. <bf>See below for additional work
-on extensions after Phase III.</bf>
+extensions are <emphasis remap="it">not</emphasis> supported at this time, but will be evaluated
+for inclusion in future DMX releases. <emphasis remap="bf">See below for additional work
+on extensions after Phase III.</emphasis>
+</para>
+</sect3>
+</sect2>
-<sect1>Phase IV
+<sect2>
+<title>Phase IV</title>
-<sect2>Moving to XFree86 4.3.0
+<sect3>
+<title>Moving to XFree86 4.3.0</title>
-<p>For Phase IV, the recent release of XFree86 4.3.0 (27 February 2003)
+<para>For Phase IV, the recent release of XFree86 4.3.0 (27 February 2003)
was merged onto the dmx.sourceforge.net CVS trunk and all work is
proceeding using this tree.
+</para>
+</sect3>
-<sect2>Extensions
+<sect3>
+<title>Extensions </title>
-<sect3>XC-MISC (supported)
+<sect4>
+<title>XC-MISC (supported)</title>
-<p>XC-MISC is used internally by the X library to recycle XIDs from the
+<para>XC-MISC is used internally by the X library to recycle XIDs from the
X server. This is important for long-running X server sessions. Xdmx
supports this extension. The X Test Suite passed and failed the exact
same tests before and after this extension was enabled.
<!-- Tested February/March 2003 -->
+</para>
+</sect4>
-<sect3>Extended-Visual-Information (supported)
+<sect4>
+<title>Extended-Visual-Information (supported)</title>
-<p>The Extended-Visual-Information extension provides a method for an X
+<para>The Extended-Visual-Information extension provides a method for an X
client to obtain detailed visual information. Xdmx supports this
-extension. It was tested using the <tt>hw/dmx/examples/evi</tt> example
-program. <bf/Note that this extension is not Xinerama-aware/ -- it will
+extension. It was tested using the <filename>hw/dmx/examples/evi</filename> example
+program. <emphasis remap="bf">Note that this extension is not Xinerama-aware</emphasis> -- it will
return visual information for each screen even though Xinerama is
causing the X server to export a single logical screen.
<!-- Tested March 2003 -->
+</para>
+</sect4>
-<sect3>RES (supported)
+<sect4>
+<title>RES (supported)</title>
-<p>The X-Resource extension provides a mechanism for a client to obtain
+<para>The X-Resource extension provides a mechanism for a client to obtain
detailed information about the resources used by other clients. This
-extension was tested with the <tt>hw/dmx/examples/res</tt> program. The
+extension was tested with the <filename>hw/dmx/examples/res</filename> program. The
X Test Suite passed and failed the exact same tests before and after
this extension was enabled.
<!-- Tested March 2003 -->
+</para>
+</sect4>
-<sect3>BIG-REQUESTS (supported)
+<sect4>
+<title>BIG-REQUESTS (supported)</title>
-<p>This extension enables the X11 protocol to handle requests longer
+<para>This extension enables the X11 protocol to handle requests longer
than 262140 bytes. The X Test Suite passed and failed the exact same
tests before and after this extension was enabled.
<!-- Tested March 2003 -->
+</para>
+</sect4>
-<sect3>XSYNC (supported)
+<sect4>
+<title>XSYNC (supported)</title>
-<p>This extension provides facilities for two different X clients to
+<para>This extension provides facilities for two different X clients to
synchronize their requests. This extension was minimally tested with
-<tt/xdpyinfo/ and the X Test Suite passed and failed the exact same
+<command>xdpyinfo</command> and the X Test Suite passed and failed the exact same
tests before and after this extension was enabled.
<!-- Tested March 2003 -->
+</para>
+</sect4>
-<sect3>XTEST, RECORD, DEC-XTRAP (supported) and XTestExtension1 (not supported)
+<sect4>
+<title>XTEST, RECORD, DEC-XTRAP (supported) and XTestExtension1 (not supported)</title>
-<p>The XTEST and RECORD extension were developed by the X Consortium for
+<para>The XTEST and RECORD extension were developed by the X Consortium for
use in the X Test Suite and are supported as a standard in the X11R6
tree. They are also supported in Xdmx. When X Test Suite tests that
make use of the XTEST extension are run, Xdmx passes and fails exactly
the same tests as does a standard XFree86 X server. When the
-<tt/rcrdtest/ test (a part of the X Test Suite that verifies the RECORD
+<literal remap="tt">rcrdtest</literal> test (a part of the X Test Suite that verifies the RECORD
extension) is run, Xdmx passes and fails exactly the same tests as does
a standard XFree86 X server. <!-- Tested February/March 2003 -->
+</para>
-<p>There are two older XTEST-like extensions: DEC-XTRAP and
+<para>There are two older XTEST-like extensions: DEC-XTRAP and
XTestExtension1. The XTestExtension1 extension was developed for use by
the X Testing Consortium for use with a test suite that eventually
became (part of?) the X Test Suite. Unlike XTEST, which only allows
@@ -2382,63 +2952,90 @@ events to be sent to the server, the XTestExtension1 extension also allowed events to be recorded (similar to the RECORD extension). The
second is the DEC-XTRAP extension that was developed by the Digital
Equipment Corporation.
+</para>
-<p>The DEC-XTRAP extension is available from Xdmx and has been tested
-with the <tt/xtrap*/ tools which are distributed as standard X11R6
+<para>The DEC-XTRAP extension is available from Xdmx and has been tested
+with the <command>xtrap*</command> tools which are distributed as standard X11R6
clients. <!-- Tested March 2003 -->
+</para>
-<p>The XTestExtension1 is <em/not/ supported because it does not appear
+<para>The XTestExtension1 is <emphasis>not</emphasis> supported because it does not appear
to be used by any modern X clients (the few that support it also support
XTEST) and because there are no good methods available for testing that
it functions correctly (unlike XTEST and DEC-XTRAP, the code for
XTestExtension1 is not part of the standard X server source tree, so
additional testing is important). <!-- Tested March 2003 -->
+</para>
-<p>Most of these extensions are documented in the X11R6 source tree.
+<para>Most of these extensions are documented in the X11R6 source tree.
Further, several original papers exist that this author was unable to
locate -- for completeness and historical interest, citations are
provide:
-<descrip>
-<tag/XRECORD/ Martha Zimet. Extending X For Recording. 8th Annual X
+<variablelist>
+<varlistentry>
+<term>XRECORD</term>
+<listitem>
+<para>Martha Zimet. Extending X For Recording. 8th Annual X
Technical Conference Boston, MA January 24-26, 1994.
-<tag/DEC-XTRAP/ Dick Annicchiarico, Robert Chesler, Alan Jamison. XTrap
+</para></listitem></varlistentry>
+<varlistentry>
+<term>DEC-XTRAP</term>
+<listitem>
+<para>Dick Annicchiarico, Robert Chesler, Alan Jamison. XTrap
Architecture. Digital Equipment Corporation, July 1991.
-<tag/XTestExtension1/ Larry Woestman. X11 Input Synthesis Extension
+</para></listitem></varlistentry>
+<varlistentry>
+<term>XTestExtension1</term>
+<listitem>
+<para>Larry Woestman. X11 Input Synthesis Extension
Proposal. Hewlett Packard, November 1991.
-</descrip>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+</sect4>
-<sect3>MIT-MISC (not supported)
+<sect4>
+<title>MIT-MISC (not supported)</title>
-<p>The MIT-MISC extension is used to control a bug-compatibility flag
+<para>The MIT-MISC extension is used to control a bug-compatibility flag
that provides compatibility with xterm programs from X11R1 and X11R2.
There does not appear to be a single client available that makes use of
this extension and there is not way to verify that it works correctly.
-The Xdmx server does <em/not/ support MIT-MISC.
+The Xdmx server does <emphasis>not</emphasis> support MIT-MISC.
+</para>
+</sect4>
-<sect3>SCREENSAVER (not supported)
+<sect4>
+<title>SCREENSAVER (not supported)</title>
-<p>This extension provides special support for the X screen saver. It
+<para>This extension provides special support for the X screen saver. It
was tested with beforelight, which appears to be the only client that
-works with it. When Xinerama was not active, <tt/beforelight/ behaved
-as expected. However, when Xinerama was active, <tt/beforelight/ did
+works with it. When Xinerama was not active, <command>beforelight</command> behaved
+as expected. However, when Xinerama was active, <command>beforelight</command> did
not behave as expected. Further, when this extension is not active,
-<tt/xscreensaver/ (a widely-used X screen saver program) did not behave
+<command>xscreensaver</command> (a widely-used X screen saver program) did not behave
as expected. Since this extension is not Xinerama-aware and is not
commonly used with expected results by clients, we have left this
extension disabled at this time.
+</para>
+</sect4>
-<sect3>GLX (supported)
+<sect4>
+<title>GLX (supported)</title>
-<p>The GLX extension provides OpenGL and GLX windowing support. In
+<para>The GLX extension provides OpenGL and GLX windowing support. In
Xdmx, the extension is called glxProxy, and it is Xinerama aware. It
works by either feeding requests forward through Xdmx to each of the
back-end servers or handling them locally. All rendering requests are
handled on the back-end X servers. This code was donated to the DMX
project by SGI. For the X Test Suite results comparison, see below.
+</para>
+</sect4>
-<sect3>RENDER (supported)
+<sect4>
+<title>RENDER (supported)</title>
-<p>The X Rendering Extension (RENDER) provides support for digital image
+<para>The X Rendering Extension (RENDER) provides support for digital image
composition. Geometric and text rendering are supported. RENDER is
partially Xinerama-aware, with text and the most basic compositing
operator; however, its higher level primitives (triangles, triangle
@@ -2446,18 +3043,22 @@ strips, and triangle fans) are not yet Xinerama-aware. The RENDER extension is still under development, and is currently at version 0.8.
Additional support will be required in DMX as more primitives and/or
requests are added to the extension.
+</para>
-<p>There is currently no test suite for the X Rendering Extension;
+<para>There is currently no test suite for the X Rendering Extension;
however, there has been discussion of developing a test suite as the
extension matures. When that test suite becomes available, additional
testing can be performed with Xdmx. The X Test Suite passed and failed
the exact same tests before and after this extension was enabled.
+</para>
+</sect4>
-<sect3>Summary
+<sect4>
+<title>Summary</title>
<!-- WARNING: this list is duplicated in the "Common X extension
support" section -->
-<p>To summarize, the following extensions are currently supported:
+<para>To summarize, the following extensions are currently supported:
BIG-REQUESTS,
DEC-XTRAP,
DMX,
@@ -2478,8 +3079,9 @@ support" section --> XInputExtension,
XKEYBOARD, and
XTEST.
+</para>
-<p>The following extensions are <em/not/ supported at this time:
+<para>The following extensions are <emphasis>not</emphasis> supported at this time:
DOUBLE-BUFFER,
FontCache,
MIT-SCREEN-SAVER,
@@ -2491,28 +3093,36 @@ support" section --> XFree86-VidModeExtension,
XTestExtensionExt1, and
XVideo.
+</para>
+</sect4>
+</sect3>
-<sect2>Additional Testing with the X Test Suite
+<sect3>
+<title>Additional Testing with the X Test Suite</title>
-<sect3>XFree86 without XTEST
+<sect4>
+<title>XFree86 without XTEST</title>
-<p>After the release of XFree86 4.3.0, we retested the XFree86 X server
+<para>After the release of XFree86 4.3.0, we retested the XFree86 X server
with and without using the XTEST extension. When the XTEST extension
-was <em/not/ used for testing, the XFree86 4.3.0 server running on our
+was <emphasis>not</emphasis> used for testing, the XFree86 4.3.0 server running on our
usual test system with a Radeon VE card reported unexpected failures in
the following tests:
-<verb>
+<literallayout>
XListPixmapFormats: Test 1
XChangeKeyboardControl: Tests 9, 10
XGetDefault: Test 5
XRebindKeysym: Test 1
-</verb>
+</literallayout>
+</para>
+</sect4>
-<sect3>XFree86 with XTEST
+<sect4>
+<title>XFree86 with XTEST</title>
-<p>When using the XTEST extension, the XFree86 4.3.0 server reported the
+<para>When using the XTEST extension, the XFree86 4.3.0 server reported the
following errors:
-<verb>
+<literallayout>
XListPixmapFormats: Test 1
XChangeKeyboardControl: Tests 9, 10
XGetDefault: Test 5
@@ -2523,19 +3133,23 @@ XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25 XGrabKey: Test 8
XSetPointerMapping: Test 3
XUngrabButton: Test 4
-</verb>
+</literallayout>
+</para>
-<p>While these errors may be important, they will probably be fixed
+<para>While these errors may be important, they will probably be fixed
eventually in the XFree86 source tree. We are particularly interested
in demonstrating that the Xdmx server does not introduce additional
failures that are not known Xinerama failures.
+</para>
+</sect4>
-<sect3>Xdmx with XTEST, without Xinerama, without GLX
+<sect4>
+<title>Xdmx with XTEST, without Xinerama, without GLX</title>
-<p>Without Xinerama, but using the XTEST extension, the following errors
+<para>Without Xinerama, but using the XTEST extension, the following errors
were reported from Xdmx (note that these are the same as for the XFree86
4.3.0, except that XGetDefault no longer fails):
-<verb>
+<literallayout>
XListPixmapFormats: Test 1
XChangeKeyboardControl: Tests 9, 10
XRebindKeysym: Test 1
@@ -2545,13 +3159,16 @@ XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25 XGrabKey: Test 8
XSetPointerMapping: Test 3
XUngrabButton: Test 4
-</verb>
+</literallayout>
+</para>
+</sect4>
-<sect3>Xdmx with XTEST, with Xinerama, without GLX
+<sect4>
+<title>Xdmx with XTEST, with Xinerama, without GLX</title>
-<p>With Xinerama, using the XTEST extension, the following errors
+<para>With Xinerama, using the XTEST extension, the following errors
were reported from Xdmx:
-<verb>
+<literallayout>
XListPixmapFormats: Test 1
XChangeKeyboardControl: Tests 9, 10
XRebindKeysym: Test 1
@@ -2566,20 +3183,23 @@ XCopyPlane: Tests 13, 22, 31 (well-known XTEST/Xinerama interaction issue) XDrawLine: Test 67
XDrawLines: Test 91
XDrawSegments: Test 68
-</verb>
+</literallayout>
Note that the first two sets of errors are the same as for the XFree86
4.3.0 server, and that the XCopyPlane error is a well-known error
resulting from an XTEST/Xinerama interaction when the request crosses a
screen boundary. The XDraw* errors are resolved when the tests are run
individually and they do not cross a screen boundary. We will
investigate these errors further to determine their cause.
+</para>
+</sect4>
-<sect3>Xdmx with XTEST, with Xinerama, with GLX
+<sect4>
+<title>Xdmx with XTEST, with Xinerama, with GLX</title>
-<p>With GLX enabled, using the XTEST extension, the following errors
+<para>With GLX enabled, using the XTEST extension, the following errors
were reported from Xdmx (these results are from early during the Phase
IV development, but were confirmed with a late Phase IV snapshot):
-<verb>
+<literallayout>
XListPixmapFormats: Test 1
XChangeKeyboardControl: Tests 9, 10
XRebindKeysym: Test 1
@@ -2596,7 +3216,7 @@ XCopyPlane: Tests 6, 7, 10, 19, 22, 31 XDrawArcs: Tests 89, 100, 102
XDrawLine: Test 67
XDrawSegments: Test 68
-</verb>
+</literallayout>
Note that the first two sets of errors are the same as for the XFree86
4.3.0 server, and that the third set has different failures than when
Xdmx does not include GLX support. Since the GLX extension adds new
@@ -2606,26 +3226,34 @@ presumably more of them crossed a screen boundary. This conclusion is supported by the fact that nearly all of the rendering errors reported
are resolved when the tests are run individually and they do no cross a
screen boundary.
+</para>
-<p>Further, when hardware rendering is disabled on the back-end displays,
+<para>Further, when hardware rendering is disabled on the back-end displays,
many of the errors in the third set are eliminated, leaving only:
-<verb>
+<literallayout>
XClearArea: Test 8
XCopyArea: Test 4, 5, 11, 14, 17, 23, 25, 27, 30
XCopyPlane: Test 6, 7, 10, 19, 22, 31
-</verb>
+</literallayout>
+</para>
+</sect4>
-<sect3>Conclusion
+<sect4>
+<title>Conclusion</title>
-<p>We conclude that all of the X Test Suite errors reported for Xdmx are
+<para>We conclude that all of the X Test Suite errors reported for Xdmx are
the result of errors in the back-end X server or the Xinerama
implementation. Further, all of these errors that can be reasonably
fixed at the Xdmx layer have been. (Where appropriate, we have
submitted patches to the XFree86 and Xinerama upstream maintainers.)
+</para>
+</sect4>
+</sect3>
-<sect2>Dynamic Reconfiguration
+<sect3>
+<title>Dynamic Reconfiguration</title>
-<p>During this development phase, dynamic reconfiguration support was
+<para>During this development phase, dynamic reconfiguration support was
added to DMX. This support allows an application to change the position
and offset of a back-end server's screen. For example, if the
application would like to shift a screen slightly to the left, it could
@@ -2634,32 +3262,39 @@ reconfigure that screen to be at position <x+10,y>. When a screen is dynamically reconfigured, input handling and a screen's root window
dimensions are adjusted as needed. These adjustments are transparent to
the user.
+</para>
-<sect3>Dynamic reconfiguration extension
+<sect4>
+<title>Dynamic reconfiguration extension</title>
-<p>The application interface to DMX's dynamic reconfiguration is through
+<para>The application interface to DMX's dynamic reconfiguration is through
a function in the DMX extension library:
-<verb>
+<programlisting>
Bool DMXReconfigureScreen(Display *dpy, int screen, int x, int y)
-</verb>
-where <it/dpy/ is DMX server's display, <it/screen/ is the number of the
-screen to be reconfigured, and <it/x/ and <it/y/ are the new upper,
+</programlisting>
+where <parameter>dpy</parameter> is DMX server's display, <parameter>screen</parameter> is the number of the
+screen to be reconfigured, and <parameter>x</parameter> and <parameter>y</parameter> are the new upper,
left-hand coordinates of the screen to be reconfigured.
+</para>
-<p>The coordinates are not limited other than as required by the X
+<para>The coordinates are not limited other than as required by the X
protocol, which limits all coordinates to a signed 16 bit number. In
addition, all coordinates within a screen must also be legal values.
Therefore, setting a screen's upper, left-hand coordinates such that the
right or bottom edges of the screen is greater than 32,767 is illegal.
+</para>
+</sect4>
-<sect3>Bounding box
+<sect4>
+<title>Bounding box</title>
-<p>When the Xdmx server is started, a bounding box is calculated from
+<para>When the Xdmx server is started, a bounding box is calculated from
the screens' layout given either on the command line or in the
configuration file. This bounding box is currently fixed for the
lifetime of the Xdmx server.
+</para>
-<p>While it is possible to move a screen outside of the bounding box, it
+<para>While it is possible to move a screen outside of the bounding box, it
is currently not possible to change the dimensions of the bounding box.
For example, it is possible to specify coordinates of <-100,-100>
for the upper, left-hand corner of the bounding box, which was
@@ -2668,66 +3303,84 @@ down and to the right; however, since the bounding box is fixed, the left side and upper portions of the screen exposed by the
reconfiguration are no longer accessible on that screen. Those
inaccessible regions are filled with black.
+</para>
-<p>This fixed bounding box limitation will be addressed in a future
+<para>This fixed bounding box limitation will be addressed in a future
development phase.
+</para>
+</sect4>
-<sect3>Sample applications
+<sect4>
+<title>Sample applications</title>
-<p>An example of where this extension is useful is in setting up a video
+<para>An example of where this extension is useful is in setting up a video
wall. It is not always possible to get everything perfectly aligned,
and sometimes the positions are changed (e.g., someone might bump into a
projector). Instead of physically moving projectors or monitors, it is
now possible to adjust the positions of the back-end server's screens
using the dynamic reconfiguration support in DMX.
+</para>
-<p>Other applications, such as automatic setup and calibration tools,
+<para>Other applications, such as automatic setup and calibration tools,
can make use of dynamic reconfiguration to correct for projector
alignment problems, as long as the projectors are still arranged
rectilinearly. Horizontal and vertical keystone correction could be
applied to projectors to correct for non-rectilinear alignment problems;
however, this must be done external to Xdmx.
+</para>
-<p>A sample test program is included in the DMX server's examples
+<para>A sample test program is included in the DMX server's examples
directory to demonstrate the interface and how an application might use
-dynamic reconfiguration. See <tt/dmxreconfig.c/ for details.
+dynamic reconfiguration. See <filename>dmxreconfig.c</filename> for details.
+</para>
+</sect4>
-<sect3>Additional notes
+<sect4>
+<title>Additional notes</title>
-<p>In the original development plan, Phase IV was primarily devoted to
+<para>In the original development plan, Phase IV was primarily devoted to
adding OpenGL support to DMX; however, SGI became interested in the DMX
project and developed code to support OpenGL/GLX. This code was later
donated to the DMX project and integrated into the DMX code base, which
freed the DMX developers to concentrate on dynamic reconfiguration (as
described above).
+</para>
+</sect4>
+</sect3>
-<sect2>Doxygen documentation
+<sect3>
+<title>Doxygen documentation</title>
-<p>Doxygen is an open-source (GPL) documentation system for generating
+<para>Doxygen is an open-source (GPL) documentation system for generating
browseable documentation from stylized comments in the source code. We
have placed all of the Xdmx server and DMX protocol source code files
under Doxygen so that comprehensive documentation for the Xdmx source
code is available in an easily browseable format.
+</para>
+</sect3>
-<sect2>Valgrind
+<sect3>
+<title>Valgrind</title>
-<p>Valgrind, an open-source (GPL) memory debugger for Linux, was used to
+<para>Valgrind, an open-source (GPL) memory debugger for Linux, was used to
search for memory management errors. Several memory leaks were detected
and repaired. The following errors were not addressed:
-<enum>
- <item>
+<orderedlist>
+ <listitem><para>
When the X11 transport layer sends a reply to the client, only
those fields that are required by the protocol are filled in --
unused fields are left as uninitialized memory and are therefore
noted by valgrind. These instances are not errors and were not
repaired.
- <item>
+ </para></listitem>
+ <listitem><para>
At each server generation, glxInitVisuals allocates memory that
is never freed. The amount of memory lost each generation
approximately equal to 128 bytes for each back-end visual.
Because the code involved is automatically generated, this bug
has not been fixed and will be referred to SGI.
- <item>
+ </para></listitem>
+ <listitem><para>
At each server generation, dmxRealizeFont calls XLoadQueryFont,
which allocates a font structure that is not freed.
dmxUnrealizeFont can free the font structure for the first
@@ -2737,11 +3390,15 @@ and repaired. The following errors were not addressed: to 80 bytes per font per back-end. When this bug is fixed in
the the X server's device-independent (dix) code, DMX will be
able to properly free the memory allocated by XLoadQueryFont.
-</enum>
+ </para></listitem>
+</orderedlist>
+</para>
+</sect3>
-<sect2>RATS
+<sect3>
+<title>RATS</title>
-<p>RATS (Rough Auditing Tool for Security) is an open-source (GPL)
+<para>RATS (Rough Auditing Tool for Security) is an open-source (GPL)
security analysis tool that scans source code for common
security-related programming errors (e.g., buffer overflows and TOCTOU
races). RATS was used to audit all of the code in the hw/dmx directory
@@ -2749,29 +3406,42 @@ and all "High" notations were checked manually. The code was either re-written to eliminate the warning, or a comment containing "RATS" was
inserted on the line to indicate that a human had checked the code.
Unrepaired warnings are as follows:
-<enum>
- <item>
+<orderedlist>
+ <listitem><para>
Fixed-size buffers are used in many areas, but code has been
added to protect against buffer overflows (e.g., XmuSnprint).
The only instances that have not yet been fixed are in
config/xdmxconfig.c (which is not part of the Xdmx server) and
input/usb-common.c.
- <item>
+ </para></listitem>
+ <listitem><para>
vprintf and vfprintf are used in the logging routines. In
general, all uses of these functions (e.g., dmxLog) provide a
constant format string from a trusted source, so the use is
relatively benign.
- <item>
+ </para></listitem>
+ <listitem><para>
glxProxy/glxscreens.c uses getenv and strcat. The use of these
functions is safe and will remain safe as long as
ExtensionsString is longer then GLXServerExtensions (ensuring
this may not be ovious to the casual programmer, but this is in
automatically generated code, so we hope that the generator
enforces this constraint).
-</enum>
+ </para></listitem>
+</orderedlist>
+
+</para>
+
+</sect3>
+
+</sect2>
+
+</sect1>
+
+</appendix>
</article>
-
+
<!-- Local Variables: -->
<!-- fill-column: 72 -->
<!-- End: -->
diff --git a/xorg-server/hw/dmx/doc/scaled.sgml b/xorg-server/hw/dmx/doc/scaled.xml index 6b8ee413f..575cafd9d 100644 --- a/xorg-server/hw/dmx/doc/scaled.sgml +++ b/xorg-server/hw/dmx/doc/scaled.xml @@ -1,707 +1,725 @@ -<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN"> - <article> - - <!-- Title information --> - <title>Scaled Window Support in DMX</title> - <author>Rickard E. Faith and Kevin E. Martin</author> - <date>15 October 2003 (created 19 September 2003)</date> - <abstract> - This document investigates the possibility of adding scaled window - support to the DMX X server, thereby allowing a window or some - selected part of the logical DMX area to be displayed using a - scaling factor. For example, this might allow the contents of a - window to be magnified for easier viewing. In particular, scaling - for the VNC client is explored. <it>Copyright 2003 - by Red Hat, Inc., Raleigh, North Carolina</it> - </abstract> - - <!-- Table of contents --> - <toc> - - <!-- Begin the document --> - <sect>Introduction - <sect1>DMX - <p> - The DMX X server (Xdmx) is a proxy server that is designed - to allow X servers on multiple machines to be combined into - a single multi-headed X server. Combined with Xinerama, - these heads can appear as a single very high-resolution - screen. Typical applications include the creation of a - video wall with 16 1280x1024 displays arranged in a - rectangle, for a total resolution of of 5120x4096. - </p> - </sect1> - <sect1>Problem Statement - <p> - Applications displayed on a physically large video wall that - provides high pixel-resolution may be difficult to see, - especially if the application is designed for use on a - typical desktop computer with a relatively small display - located close to the human operator. The goal of this paper - is to describe and discuss solutions to this problem. - </p> - <p> - The original driving problem for this work is to provide - scaling for the <tt>vncviewer</tt> application when - displayed using DMX (VNC scaling is currently available only - with the Windows client, and there is no plan to extend that - capability to other clients). While this specific problem - will be addressed in this paper, the general solution space - will also be explored, since this may lead to a good - solution not only for <tt>vncviewer</tt> but also for - other applications. - </p> - </sect1> - <sect1>Task - <p> - For reference, here is the original description of the task - this paper addresses: - <itemize> - <item>Scaled window support (for VNC) - <itemize> - <item> - Investigate possibility of implementing a "scaled - window" extension: - <itemize> - <item> - Add XCreateScaledWindow call that could be used - in place of XCreateWindow - </item> - <item> - All primitives drawn to scaled window would be - scaled by appropriate (integral?) scaling factor - </item> - </itemize> - </item> - <item> - Alternate approach: special case VNC support - </item> - </itemize> - </item> - </itemize> - </p> - </sect1> - </sect> - - <sect>Previous Work - <p> - This section reviews relevant previous work. - </p> - <sect1>VNC - <sect2>Scaling under VNC - <p> - When using the <tt>vncviewer</tt> program for Windows, it - is possible to specify a scaling factor (as numerator and - denominator). When scaling is in effect, the viewer - software uses StretchBlt (instead of BitBlt) to display - the pixels for the user. When this call is made, the - viewer already has received all of the pixel information - (at full unscaled resolution). - </p> - <p> - The scaling in VNC is primitive. It does not conserve - bandwidth, it does not treat textual information - differently (i.e., by using a suitably scaled font), and - it does not provide any anti-aliasing other than that - provided by the underlying (Windows-only) system library. - </p> - </sect2> - </sect1> - <sect1>The X Video Extension - <p> - The X Video Extension is a widely-available extension to the - X11 protocol that provides support for streaming video. - Integral to this support is the ability to arbitrarily scale - the output. In version 2.2 of the X Video specification, - support for scaled still images was provided, using both - shared memory and traditional transport. The API for this - support uses calls that are quite similar to XCreateWindow, - XPutImage, and XShmPutImage. Currently, most of the drivers - implemented in XFree86 only support data in various YUV - formats. However, several modern video adaptors support RGB - as well. - </p> - <p> - Note, though, that the target output for this scaling is an - overlay plane -- so X Video provides functionality that is - fundamentally different from that provided by the Windows - StrechBlt call. - </p> - </sect1> - </sect> - - <sect>Possible Solutions - <p> - This section briefly discusses possible solutions, including - major advantages and disadvantages from both the - implementation and the end-user programmer standpoint. - </p> - <sect1>VNC-like Scaling - <sect2>Software Scaling - <p> - The <tt>vncviewer</tt> application could be modified to - provide software scaling. This is not a general solution, - but it does solve one of the goals of this work. - </p> - <p> - A prototype of this solution was implemented and a patch - against <tt>vnc-3.3.7-unixsrc</tt> is available in the - <tt>dmx/external</tt> directory. Because of limited time - available for this work, all of the edge cases were not - considered and the solution works well mainly for integer - scaling. - </p> - <p> - Currently, <tt>vncviewer</tt> writes to the X display - with XPutImage, XCopyArea, and XFillRectangle. All - instances of these calls have to be aware of scaling - and must round correctly. In the prototype solution, - rounding is incorrect and can cause artifacts. - </p> - <p> - A better solution would be to cache all updates to the - desktop image in <tt>vncviewer</tt> and only send the - damaged area to the X display with XPutImage. This would - allow the damaged area to be computed so that rounding - errors do not create artifacts. This method is probably - similar to what is used in the Window client. (The whole - VNC suite is being re-written in C++ and the forthcoming - version 4 has not been evaluated.) - </p> - </sect2> - <sect2>Scaling with the X Video Extension - <p> - The scaling in the Windows <tt>vncviewer</tt> application - makes use of a scaled blit that is supplied by the - underlying system library. Several video cards currently - provide support for a scaled blit, and some X servers - (including XFree86) expose this capability to applications - via the XvPutImage interface of the X Video Extension. - The capability exposed by XvPutImage results in the scaled - image being drawn to an overlay plane. Most video cards - also provide support for a scaled blit into the normal - output planes, but this is not exposed via XvPutImage. - </p> - <p> - The <tt>vncviewer</tt> program could be modified to use - the X Video Extension to provide scaling under X11 that is - similar to the scaling currently provided under Windows. - Unfortunately, Xdmx does not currently export the X Video - Extension, so this would not provide an immediate solution - usable with DMX. - </p> - <p> - A very early-stage proof-of-concept prototype was - implemented and a preliminary patch against - <tt>vnc-3.3.7-unixsrc</tt> is available in the - <tt>dmx/external</tt> directory. This prototype was - implemented to better understand the problems that must be - solved to make this solution viable: - <itemize> - <item> - As noted under the software scaling section above, - <tt>vncviewer</tt> writes to the X display with - several different calls. These calls write to the - normal output planes and are compatible with - XvPutImage, which writes to an overlay plane. To - eliminate artifacts caused by this problem, - <tt>vncviewer</tt> should be modified so that a cached - copy of the desktop is available, either as a - client-side image or a server-side off-screen pixmap, - so that XvPutImage would be the only method for - writing to the X display. - </item> - <item> - <p> - Although several modern graphics adaptors support - hardware scaling using an RGB format (e.g., ATI - Radeon, nVidia, etc.), XFree86 drivers typically - only implement YUV formats. YUV generally compress - the pixel information in some way. For example, two - commonly implemented formats, YUY2 and UYVY provide - intensity information for every RGB pixel, but only - provide chroma and luminance information for pairs - of horizontal pixels. Since VNC uses - pixel-resolution for communicating updates on the - wire, additional artifacts are introduced (because - there may not be enough information from the wire to - update a pair of pixels). - <p> - Further, the well-known problem with YUV encoding - is even more evident when the image is a desktop - instead of a movie. For example, consider a - 1-pixel-wide vertical window border. If the border - changes in color but not intensity (e.g., because a - window manager uses color to indicate focus), there - may or may not be a change in the YUY2 image, - depending on the algorithm used for RGB to YUV - conversion and on how the border pixel is ordered in - the pair of pixels used by the algorithm. - <p> - Many of these artifacts could be eliminated if - <tt>vncviewer</tt> cached a complete RGB image of - the desktop, and only did the conversion to YUV for - properly aligned areas of damage. The remaining artifacts - could be eliminated if an RGB format was used with X - Video (which may require the extension of existing - XFree86 drivers to support RGB). - </item> - <item> - Most modern video cards support exactly one overlay - plane that is suitable for use with X Video. - Therefore, only one application can use X Video at any - given time. This is a severe limitation in a desktop - environment. - </item> - </itemize> - </p> - <sect3>Implementing the X Video Extension for DMX - <p> - The user-level API for X Video is fairly simple, but the - underlying support required for the full specification - is large. However, since the API provides a method to - query supported capabilities, a usable subset of X - Video can be implemented that would support XvPutImage - and little else. This would require support for the - following: - <itemize> - <item> - X Video Extension API calls, including the - following: - <itemize> - <item>XvQueryExtension</item> - <item>XvQueryAdaptors</item> - <item>XvQueryPortAttributes</item> - <item>XvFreeAdaptorInfo</item> - <item>XvListImageFormats</item> - <item>XvGrabPort</item> - <item>XvCreateImage</item> - <item>XvPutImage</item> - <item>XvShmCreateImage</item> - <item>XvShmPutImage</item> - </itemize> - </item> - <item> - Support for querying back-end X Video Extension - capabilities. - </item> - <item> - Support for sending the image to the back-ends. - Because X Video requires sending full images, there - may be a trade-off between bandwidth limitations and - additional complexity to divide the image up such - that is scales properly. - </item> - <item> - Possible support for a software fall-back. For - example, if all of the back-ends do not support the X - Video Extension, software scaling can be implemented - such that the image is sent to the back-end with - XPutImage. This pathway would have poor - performance. - </item> - </itemize> - </p> - </sect3> - <sect3>Supporting RGB formats for the X Video Extension - <p> - Assuming an XFree86 driver already supports the X Video - Extension, and assuming the target hardware supports an - RGB format, then adding support for that format is - relatively simple and straightforward. - </p> - </sect3> - </sect2> - <sect2>Scaling with an XPutImageScaled Extension - <p> - Instead of (or in addition to) implementing the X Video - Extension in DMX, one obvious solution would be to - implement a new extension that provides access to - hardware-assisted scaled blits, similar to the StretchBlt - call available under Windows. This call would scale RGB - images and would not use the overlay plane (unlike the X - Video Extension). - </p> - <p> - This approach has many of the same advantages and - disadvantages as the XCopyAreaScaled Extension, discussed - in the next section. Discussion of XPutImageScaled is - deferred in favor of XCopyAreaScaled for the following - reasons: - <itemize> - <item> - XPutImageScaled can be emulated with XCopyAreaScaled - by first using XPutImage to copy the image to an - off-screen pixmap, and then calling XCopyAreaScaled - between that off-screen pixmap and the target - drawable. - </item> - <item> - Since XCopyAreaScaled would copy between two areas of - on-screen or off-screen memory, it has additional uses - and can be viewed as efficiently providing a superset - of XPutImageScaled functionality. - </item> - </itemize> - </p> - </sect2> - <sect2>Scaling with an XCopyAreaScaled Extension - <p> - As noted in the previous section, because XCopyAreaScaled - provides a superset of the functionality provided by - XPutImageScaled, we will consider this extension instead. - </p> - <p> - First, XCopyAreaScaled would provide for RGB scaling - between pixmaps (i.e., on-screen or off-screen areas of - memory that reside on the video card). Unlike the X Video - Extension, which writes into an overlay plane, - XCopyAreaScaled would write into the non-overlay areas of - the screen. Key points to consider are as follows: - <itemize> - <item> - Because different planes are involved, the two scaling - operations are usually implemented in hardware - differently, so an XCopyAreaScaled extension could be - added in a manner that would neither conflict with nor - interact with the X Video extension in any way. - </item> - <item> - The XCopyAreaScaled extension provides new - functionality that the X Video Extension does not - provide. Based on anecdotal feedback, we believe that - many people outside the DMX and VNC communities would - be excited about this extension. - </item> - <item> - The main drawback to this extension is that it is new - and needs to be implemented at the driver level in - XFree86 for each video card to be supported. At the - present time, it is more likely that the X Video - Extension will be implemented for a particular piece - hardware because the X Video extension has multimedia - uses. However, over time, we would expect the - XCopyAreaScaled extension to be implemented along with - the X Video extension, especially if it becomes - popular. - </item> - <item> - Another drawback is that not all modern cards provide - support for a simple scaled blit operation. However, - these cards usually do provide a 3D pipeline which - could be used to provide this functionality in a - manner that is transparent to the client application - that is using the XCopyAreaScaled extension. However, - this implementation pathway would make this extension - somewhat more difficult to implement on certain cards. - </item> - </itemize> - </p> - </sect2> - <sect2>Scaling with OpenGL - <p> - Another general solution to the scaling problem is to use - the texture scaling found in all 3D hardware. This - ability is already exposed through OpenGL and can be - exploited by clients without X server modification (i.e., - other than the ability to support OpenGL). An application - using OpenGL would transmit the non-scaled image to the X - server as a texture, and would then display a single - non-transformed rect using that texture. This also works - around the single overlay problem with the X Video - Extension as well as the need to implement additional - scaled primitive extensions. - </p> - <p> - The downside is that most OpenGL implementations require - power of 2 texture sizes and this can be very wasteful of - memory if, for example, the application needs to scale a - 1025x1025 image, which would require a 2048x2048 texture - area (even a 640x480 image would require a 1024x512 - texture). Another downside is that some OpenGL - implementations have a limited about of texture memory and - cannot handle textures that are very large. For example, - they might limit the texture size to 1024x1024. - </p> - </sect2> - </sect1> - <sect1>Application-transparent Scaling for DMX - <sect2>Back-end Scaling Without Disconnect/Reconnect - <p> - VNC does scaling on the client side (in the - <tt>vncviewer</tt> application). Implementing a similar - solution for DMX would require support in the back-end X - servers and, therefore, is not a general solution. - </p> - <p> - XFree86 already implements some support for "scaling" that - could be used with DMX: if, in the XF86Config file, - multiple Modes are listed in the Display Subsection of the - Screen Section, then pressing Ctrl-Alt-Plus and - Ctrl-Alt-Minus can be used to iterate through the listed - modes. The display dimensions will change to the - dimensions in the Modes line, but the logical dimensions - of the X server (i.e., the dimensions that Xdmx knows - about) will not change. - </p> - <p> - Further, the dimensions of the XFree86 display are under - software control (via the XFree86-VidModeExtension), so - the Xdmx server could change the screen dimensions on a - per-display basis, thereby scaling the information on part - of that display. - </p> - <p> - However, this scaling appears to have limited use. For - example, assume a 4 by 4 display wall consisting of 16 - 1280x1024 displays. If all of the back-end servers were - simultaneously configured to display 640x480, the left - hand corner of each display would be magnified, but the - composite result would be unreadable. Magnifying one - display at a time could be usable, but could have limited - utility, since the result would still be no larger than a - single display. - </p> - </sect2> - <sect2>Back-end Scaling With Disconnect/Reconnect - <p> - Disconnect and reconnect features are not currently - supported in DMX, but are scheduled to be implemented in - the future. These features, combined with the - XFree86-VidModeExtension Extension, would allow an - application to do the following: - <itemize> - <item> - Disconnect a specific back-end server (via the DMX - Extension), - </item> - <item> - reconfigure the XFree86 back-end server resolution, - and - </item> - <item> - reconnect the back-end server to DMX -- at a new - origin with the new screen resolution. - </item> - </itemize> - </p> - <p> - For example, consider a display wall consisting of 16 - 1280x1024 displays with a total resolution of 5120x4096. - All of the screens could be disconnected, repositioned, - and reconnected each at a resolution of 640x480. The - total resolution of the display wall would be 2560x1920, - allowing a view of a selected area approximately - one-fourth of the size of the DMX display. This change - would be completely application independent (except, - perhaps, for a DMX-aware window manager). When work at - the increased resolution was completed, the back-end - servers could be disconnected, reconfigured, and - reconnected for the original 5120x4096 view. - </p> - <p> - Support for this type of scaling can be implemented in a - DMX-aware X11 client assuming the DMX server support - arbitrary disconnect and reconnect semantics. Because - this application cannot be written before - disconnect/reconnect is implemented, this solution will - not be discussed further in this paper. - </p> - </sect2> - <sect2>Server-side Scaling - <p> - In earlier versions of DMX, a frame buffer was maintained - on the server side, and XPutImage was used to move the - information from the server to the client (similar to some - early VNC implementations). The use of a server-side - frame buffer would allow the server to do scaling, but is - not a recommended solution because of overall performance - issues and server-side memory issues (i.e., the frame - buffer would be very large for large display walls). - </p> - <p> - Exploration of this path is not recommended. - </p> - </sect2> - </sect1> - <sect1>XCreateScaledWindow API - <p> - The implementation of X Video Extension in DMX, and the use - of XvPutImage by applications requiring scaling requires - significant changes in DMX Further, XvPutImage is, - essentially a scaled blit, and it is only useful for - applications which are already using (or can be modified to - use) XPutImage. Therefore, a more general API will be - discussed as another possibility. - </p> - <p> - X applications typically create windows with the - XCreateWindow call. A new extension could provide an - XCreateScaledWindow call that could be used in place of the - XCreateWindow call and be otherwise transparent to the - application. This would allow applications, even those that - do not depend on XPutImage, to take advantage of window - scaling. In this section we describe how the call would - work, what transparency it provides, and how to solve the - potential problems that transparency creates. - </p> - <sect2>XCreateWindow - <p> - The XCreateWindow call takes width and height as - parameters. An XCreateScaledWindow call could take all - the same parameters, with the addition of a scaling factor. - </p> - </sect2> - <sect2>XSetWindowAttributes - <p> - An X11 window has several attributes that would have to be - scaled: - <itemize> - <item>Background and border pixmaps</item> - <item>Border width</item> - <item>Cursor</item> - </itemize> - </p> - </sect2> - <sect2>XGetWindowAttributes, XGetGeometry - <p> - For transparency, calls that query the window attributes - should return unscaled information. This suggests that - all unscaled pixmaps and window attributes should be - cached. - </p> - <p> - Unfortunately, a window manager requires the scaled - geometry to properly decorate the window. The X server - can probably determine which client is acting as the - window manager (e.g., because that client will select - events that are used exclusively by the window manager). - However, other Scaled Window Extension aware clients may - also need to determine the scaled geometry. Therefore, at - least two additional extension calls should be - implemented: XGetScaledWindowAttributes and - XGetScaledGeometry. - </p> - </sect2> - <sect2>Popup and Child window positions - <p> - Some applications may position popup and child windows - based on an unscaled notion of the main window geometry. - In this case, additional modifications to the client would - be required. - </p> - </sect2> - <sect2>Events - <p> - Most events (e.g., for mouse motion) return information - about the coordinates at which the even occurred. These - coordinates would have to be modified so that unscaled - values were presented to the client. - </p> - </sect2> - <sect2>Implementation - <p> - There are many implementation issues, some of which are - similar to the issues involved in implementing the X Video - Extension for DMX. The window contents must be scaled, - either by performing all operations to a frame buffer and - then writing the image to the display (perhaps using - hardware scaling support), or by modifying all of the - various drawing operations to perform scaling. Because of - the complexity involved, the frame buffer option is - recommended. - </p> - </sect2> - </sect1> - </sect> - - <sect>Conclusion and Recommendations - <p> - We recommend a three phase implementation strategy, based on - how an application could be written to take advantage of - scaling: - <enum> - <item> - <p> - The XCopyAreaScaled extension should be implemented, since - this is the ideal solution for applications like VNC, and - since making use of this extension will require minimal - changes to applications that already use XPutImage or - XCopyArea. - <p> - The initial implementation work would include the design - of the X protocol extension, writing this up in the - usual format for extension documentation, implementation - of the protocol transport pieces in XFree86, - implementation of a software fall-back in XFree86 and - DMX, one example hardware implementation for XFree86, - and implementation of support for this extension in DMX. - <p> - We suggest implementing the extension first on the ATI - Radeon cards. However, since these cards do not provide - a 2D scaled blit primitive, the implementation would - have to make use of the 3D texture engine to emulate a - scaled blit. This is recommended, since other modern - graphics cards also do not provide a simple 2D scaled - blit operation and an example of the more difficult - implementation pathway would be helpful to others. - </item> - <item> - <p> - Until XCopyAreaScaled is widely supported, applications - that require scaling will have to fall back to another - scaling method. We suggest OpenGL as the first fall-back - method because it is widely available and supported by - DMX. - <p> - A project centered around OpenGL-based scaling would - implement this scaling in VNC as an example. This work - would include re-writing the <tt>vncviewer</tt> - rendering engine to cache a master copy of the desktop - image for all operations. - </item> - <item> - <p> - Since OpenGL is not implemented everywhere, and may not - provide hardware-assisted performance in every - implementation, an application that requires scaling - should also fall back to using the X Video Extension. - <p> - This project would add support for the X Video Extension - to DMX and would add support to VNC to take advantage of - this extension without introducing artifacts. This - would require modifying the <tt>vncviewer</tt> rendering - engine to cache a master copy of the desktop image for - all operations. This project should also add support - for the RGB format to at least one XFree86 driver (e.g., - ATI Radeon). - <p> - The X Video Extension is one of the few popular - extensions that DMX does not support. We recommend - implementing the X Video Extension even if scaling is - the specific goal of that work. - </item> - </enum> - </p> - <p> - We do <bf>not</bf> recommend implementation of the - XCreateScaledWindow extension because of the complexity - involved. We do <bf>not</bf> recommend implementation of the - XPutImageScaled extension because it requires the same amount - of work as the XCopyAreaScaled extension, but provides less - functionality. Further, server-side scaling with a large - frame buffer is <bf>not</bf> recommended because of the - performance implications. - </p> - <p> - The back-end scaling, especially with disconnect/reconnect - support should be explored in the future after - disconnect/reconnect is implemented, but not at the present - time. - </p> - </sect> - - </article> - <!-- Local Variables: --> - <!-- fill-column: 72 --> - <!-- End: --> +<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+]>
+ <article>
+
+ <articleinfo>
+ <!-- Title information -->
+ <title>Scaled Window Support in DMX</title>
+ <authorgroup>
+ <author><firstname>Kevin E.</firstname><surname>Martin</surname></author>
+ <author><firstname>Rickard E.</firstname><surname>Faith</surname></author>
+ </authorgroup>
+ <pubdate>15 October 2003 (created 19 September 2003)</pubdate>
+ <abstract>
+ <para>
+ This document investigates the possibility of adding scaled window
+ support to the DMX X server, thereby allowing a window or some
+ selected part of the logical DMX area to be displayed using a
+ scaling factor. For example, this might allow the contents of a
+ window to be magnified for easier viewing. In particular, scaling
+ for the VNC client is explored. <emphasis remap="it">Copyright 2003
+ by Red Hat, Inc., Raleigh, North Carolina</emphasis>
+ </para>
+ </abstract>
+ </articleinfo>
+
+ <!-- Begin the document -->
+ <sect1><title>Introduction</title>
+ <sect2><title>DMX</title>
+ <para>
+ The DMX X server (Xdmx) is a proxy server that is designed
+ to allow X servers on multiple machines to be combined into
+ a single multi-headed X server. Combined with Xinerama,
+ these heads can appear as a single very high-resolution
+ screen. Typical applications include the creation of a
+ video wall with 16 1280x1024 displays arranged in a
+ rectangle, for a total resolution of of 5120x4096.
+ </para>
+ </sect2>
+ <sect2><title>Problem Statement</title>
+ <para>
+ Applications displayed on a physically large video wall that
+ provides high pixel-resolution may be difficult to see,
+ especially if the application is designed for use on a
+ typical desktop computer with a relatively small display
+ located close to the human operator. The goal of this paper
+ is to describe and discuss solutions to this problem.
+ </para>
+ <para>
+ The original driving problem for this work is to provide
+ scaling for the <command>vncviewer</command> application when
+ displayed using DMX (VNC scaling is currently available only
+ with the Windows client, and there is no plan to extend that
+ capability to other clients). While this specific problem
+ will be addressed in this paper, the general solution space
+ will also be explored, since this may lead to a good
+ solution not only for <command>vncviewer</command> but also for
+ other applications.
+ </para>
+ </sect2>
+ <sect2><title>Task</title>
+ <para>
+ For reference, here is the original description of the task
+ this paper addresses:
+ <itemizedlist>
+ <listitem><para>Scaled window support (for VNC)
+ <itemizedlist>
+ <listitem><para>
+ Investigate possibility of implementing a "scaled
+ window" extension:
+ <itemizedlist>
+ <listitem><para>
+ Add XCreateScaledWindow call that could be used
+ in place of XCreateWindow
+ </para></listitem>
+ <listitem><para>
+ All primitives drawn to scaled window would be
+ scaled by appropriate (integral?) scaling factor
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem><para>
+ Alternate approach: special case VNC support
+ </para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1><title>Previous Work</title>
+ <para>
+ This section reviews relevant previous work.
+ </para>
+ <sect2><title>VNC</title>
+ <sect3><title>Scaling under VNC</title>
+ <para>
+ When using the <command>vncviewer</command> program for Windows, it
+ is possible to specify a scaling factor (as numerator and
+ denominator). When scaling is in effect, the viewer
+ software uses StretchBlt (instead of BitBlt) to display
+ the pixels for the user. When this call is made, the
+ viewer already has received all of the pixel information
+ (at full unscaled resolution).
+ </para>
+ <para>
+ The scaling in VNC is primitive. It does not conserve
+ bandwidth, it does not treat textual information
+ differently (i.e., by using a suitably scaled font), and
+ it does not provide any anti-aliasing other than that
+ provided by the underlying (Windows-only) system library.
+ </para>
+ </sect3>
+ </sect2>
+ <sect2><title>The X Video Extension</title>
+ <para>
+ The X Video Extension is a widely-available extension to the
+ X11 protocol that provides support for streaming video.
+ Integral to this support is the ability to arbitrarily scale
+ the output. In version 2.2 of the X Video specification,
+ support for scaled still images was provided, using both
+ shared memory and traditional transport. The API for this
+ support uses calls that are quite similar to XCreateWindow,
+ XPutImage, and XShmPutImage. Currently, most of the drivers
+ implemented in XFree86 only support data in various YUV
+ formats. However, several modern video adaptors support RGB
+ as well.
+ </para>
+ <para>
+ Note, though, that the target output for this scaling is an
+ overlay plane -- so X Video provides functionality that is
+ fundamentally different from that provided by the Windows
+ StrechBlt call.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1><title>Possible Solutions</title>
+ <para>
+ This section briefly discusses possible solutions, including
+ major advantages and disadvantages from both the
+ implementation and the end-user programmer standpoint.
+ </para>
+ <sect2><title>VNC-like Scaling</title>
+ <sect3><title>Software Scaling</title>
+ <para>
+ The <command>vncviewer</command> application could be modified to
+ provide software scaling. This is not a general solution,
+ but it does solve one of the goals of this work.
+ </para>
+ <para>
+ A prototype of this solution was implemented and a patch
+ against <filename>vnc-3.3.7-unixsrc</filename> is available in the
+ <filename>dmx/external</filename> directory. Because of limited time
+ available for this work, all of the edge cases were not
+ considered and the solution works well mainly for integer
+ scaling.
+ </para>
+ <para>
+ Currently, <command>vncviewer</command> writes to the X display
+ with XPutImage, XCopyArea, and XFillRectangle. All
+ instances of these calls have to be aware of scaling
+ and must round correctly. In the prototype solution,
+ rounding is incorrect and can cause artifacts.
+ </para>
+ <para>
+ A better solution would be to cache all updates to the
+ desktop image in <command>vncviewer</command> and only send the
+ damaged area to the X display with XPutImage. This would
+ allow the damaged area to be computed so that rounding
+ errors do not create artifacts. This method is probably
+ similar to what is used in the Window client. (The whole
+ VNC suite is being re-written in C++ and the forthcoming
+ version 4 has not been evaluated.)
+ </para>
+ </sect3>
+ <sect3><title>Scaling with the X Video Extension</title>
+ <para>
+ The scaling in the Windows <command>vncviewer</command> application
+ makes use of a scaled blit that is supplied by the
+ underlying system library. Several video cards currently
+ provide support for a scaled blit, and some X servers
+ (including XFree86) expose this capability to applications
+ via the XvPutImage interface of the X Video Extension.
+ The capability exposed by XvPutImage results in the scaled
+ image being drawn to an overlay plane. Most video cards
+ also provide support for a scaled blit into the normal
+ output planes, but this is not exposed via XvPutImage.
+ </para>
+ <para>
+ The <command>vncviewer</command> program could be modified to use
+ the X Video Extension to provide scaling under X11 that is
+ similar to the scaling currently provided under Windows.
+ Unfortunately, Xdmx does not currently export the X Video
+ Extension, so this would not provide an immediate solution
+ usable with DMX.
+ </para>
+ <para>
+ A very early-stage proof-of-concept prototype was
+ implemented and a preliminary patch against
+ <filename>vnc-3.3.7-unixsrc</filename> is available in the
+ <filename>dmx/external</filename> directory. This prototype was
+ implemented to better understand the problems that must be
+ solved to make this solution viable:
+ <itemizedlist>
+ <listitem><para>
+ As noted under the software scaling section above,
+ <command>vncviewer</command> writes to the X display with
+ several different calls. These calls write to the
+ normal output planes and are compatible with
+ XvPutImage, which writes to an overlay plane. To
+ eliminate artifacts caused by this problem,
+ <command>vncviewer</command> should be modified so that a cached
+ copy of the desktop is available, either as a
+ client-side image or a server-side off-screen pixmap,
+ so that XvPutImage would be the only method for
+ writing to the X display.
+ </para></listitem>
+ <listitem>
+ <para>
+ Although several modern graphics adaptors support
+ hardware scaling using an RGB format (e.g., ATI
+ Radeon, nVidia, etc.), XFree86 drivers typically
+ only implement YUV formats. YUV generally compress
+ the pixel information in some way. For example, two
+ commonly implemented formats, YUY2 and UYVY provide
+ intensity information for every RGB pixel, but only
+ provide chroma and luminance information for pairs
+ of horizontal pixels. Since VNC uses
+ pixel-resolution for communicating updates on the
+ wire, additional artifacts are introduced (because
+ there may not be enough information from the wire to
+ update a pair of pixels).
+ </para>
+ <para>
+ Further, the well-known problem with YUV encoding
+ is even more evident when the image is a desktop
+ instead of a movie. For example, consider a
+ 1-pixel-wide vertical window border. If the border
+ changes in color but not intensity (e.g., because a
+ window manager uses color to indicate focus), there
+ may or may not be a change in the YUY2 image,
+ depending on the algorithm used for RGB to YUV
+ conversion and on how the border pixel is ordered in
+ the pair of pixels used by the algorithm.
+ </para>
+ <para>
+ Many of these artifacts could be eliminated if
+ <command>vncviewer</command> cached a complete RGB image of
+ the desktop, and only did the conversion to YUV for
+ properly aligned areas of damage. The remaining artifacts
+ could be eliminated if an RGB format was used with X
+ Video (which may require the extension of existing
+ XFree86 drivers to support RGB).
+ </para>
+ </listitem>
+ <listitem><para>
+ Most modern video cards support exactly one overlay
+ plane that is suitable for use with X Video.
+ Therefore, only one application can use X Video at any
+ given time. This is a severe limitation in a desktop
+ environment.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ <sect4><title>Implementing the X Video Extension for DMX</title>
+ <para>
+ The user-level API for X Video is fairly simple, but the
+ underlying support required for the full specification
+ is large. However, since the API provides a method to
+ query supported capabilities, a usable subset of X
+ Video can be implemented that would support XvPutImage
+ and little else. This would require support for the
+ following:
+ <itemizedlist>
+ <listitem><para>
+ X Video Extension API calls, including the
+ following:
+ <itemizedlist>
+ <listitem><para>XvQueryExtension</para></listitem>
+ <listitem><para>XvQueryAdaptors</para></listitem>
+ <listitem><para>XvQueryPortAttributes</para></listitem>
+ <listitem><para>XvFreeAdaptorInfo</para></listitem>
+ <listitem><para>XvListImageFormats</para></listitem>
+ <listitem><para>XvGrabPort</para></listitem>
+ <listitem><para>XvCreateImage</para></listitem>
+ <listitem><para>XvPutImage</para></listitem>
+ <listitem><para>XvShmCreateImage</para></listitem>
+ <listitem><para>XvShmPutImage</para></listitem>
+ </itemizedlist>
+ </para></listitem>
+ <listitem><para>
+ Support for querying back-end X Video Extension
+ capabilities.
+ </para></listitem>
+ <listitem><para>
+ Support for sending the image to the back-ends.
+ Because X Video requires sending full images, there
+ may be a trade-off between bandwidth limitations and
+ additional complexity to divide the image up such
+ that is scales properly.
+ </para></listitem>
+ <listitem><para>
+ Possible support for a software fall-back. For
+ example, if all of the back-ends do not support the X
+ Video Extension, software scaling can be implemented
+ such that the image is sent to the back-end with
+ XPutImage. This pathway would have poor
+ performance.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ </sect4>
+ <sect4><title>Supporting RGB formats for the X Video Extension</title>
+ <para>
+ Assuming an XFree86 driver already supports the X Video
+ Extension, and assuming the target hardware supports an
+ RGB format, then adding support for that format is
+ relatively simple and straightforward.
+ </para>
+ </sect4>
+ </sect3>
+ <sect3><title>Scaling with an XPutImageScaled Extension</title>
+ <para>
+ Instead of (or in addition to) implementing the X Video
+ Extension in DMX, one obvious solution would be to
+ implement a new extension that provides access to
+ hardware-assisted scaled blits, similar to the StretchBlt
+ call available under Windows. This call would scale RGB
+ images and would not use the overlay plane (unlike the X
+ Video Extension).
+ </para>
+ <para>
+ This approach has many of the same advantages and
+ disadvantages as the XCopyAreaScaled Extension, discussed
+ in the next section. Discussion of XPutImageScaled is
+ deferred in favor of XCopyAreaScaled for the following
+ reasons:
+ <itemizedlist>
+ <listitem><para>
+ XPutImageScaled can be emulated with XCopyAreaScaled
+ by first using XPutImage to copy the image to an
+ off-screen pixmap, and then calling XCopyAreaScaled
+ between that off-screen pixmap and the target
+ drawable.
+ </para></listitem>
+ <listitem><para>
+ Since XCopyAreaScaled would copy between two areas of
+ on-screen or off-screen memory, it has additional uses
+ and can be viewed as efficiently providing a superset
+ of XPutImageScaled functionality.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ </sect3>
+ <sect3><title>Scaling with an XCopyAreaScaled Extension</title>
+ <para>
+ As noted in the previous section, because XCopyAreaScaled
+ provides a superset of the functionality provided by
+ XPutImageScaled, we will consider this extension instead.
+ </para>
+ <para>
+ First, XCopyAreaScaled would provide for RGB scaling
+ between pixmaps (i.e., on-screen or off-screen areas of
+ memory that reside on the video card). Unlike the X Video
+ Extension, which writes into an overlay plane,
+ XCopyAreaScaled would write into the non-overlay areas of
+ the screen. Key points to consider are as follows:
+ <itemizedlist>
+ <listitem><para>
+ Because different planes are involved, the two scaling
+ operations are usually implemented in hardware
+ differently, so an XCopyAreaScaled extension could be
+ added in a manner that would neither conflict with nor
+ interact with the X Video extension in any way.
+ </para></listitem>
+ <listitem><para>
+ The XCopyAreaScaled extension provides new
+ functionality that the X Video Extension does not
+ provide. Based on anecdotal feedback, we believe that
+ many people outside the DMX and VNC communities would
+ be excited about this extension.
+ </para></listitem>
+ <listitem><para>
+ The main drawback to this extension is that it is new
+ and needs to be implemented at the driver level in
+ XFree86 for each video card to be supported. At the
+ present time, it is more likely that the X Video
+ Extension will be implemented for a particular piece
+ hardware because the X Video extension has multimedia
+ uses. However, over time, we would expect the
+ XCopyAreaScaled extension to be implemented along with
+ the X Video extension, especially if it becomes
+ popular.
+ </para></listitem>
+ <listitem><para>
+ Another drawback is that not all modern cards provide
+ support for a simple scaled blit operation. However,
+ these cards usually do provide a 3D pipeline which
+ could be used to provide this functionality in a
+ manner that is transparent to the client application
+ that is using the XCopyAreaScaled extension. However,
+ this implementation pathway would make this extension
+ somewhat more difficult to implement on certain cards.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ </sect3>
+ <sect3><title>Scaling with OpenGL</title>
+ <para>
+ Another general solution to the scaling problem is to use
+ the texture scaling found in all 3D hardware. This
+ ability is already exposed through OpenGL and can be
+ exploited by clients without X server modification (i.e.,
+ other than the ability to support OpenGL). An application
+ using OpenGL would transmit the non-scaled image to the X
+ server as a texture, and would then display a single
+ non-transformed rect using that texture. This also works
+ around the single overlay problem with the X Video
+ Extension as well as the need to implement additional
+ scaled primitive extensions.
+ </para>
+ <para>
+ The downside is that most OpenGL implementations require
+ power of 2 texture sizes and this can be very wasteful of
+ memory if, for example, the application needs to scale a
+ 1025x1025 image, which would require a 2048x2048 texture
+ area (even a 640x480 image would require a 1024x512
+ texture). Another downside is that some OpenGL
+ implementations have a limited about of texture memory and
+ cannot handle textures that are very large. For example,
+ they might limit the texture size to 1024x1024.
+ </para>
+ </sect3>
+ </sect2>
+ <sect2><title>Application-transparent Scaling for DMX
+ </title><sect3><title>Back-end Scaling Without Disconnect/Reconnect</title>
+ <para>
+ VNC does scaling on the client side (in the
+ <command>vncviewer</command> application). Implementing a similar
+ solution for DMX would require support in the back-end X
+ servers and, therefore, is not a general solution.
+ </para>
+ <para>
+ XFree86 already implements some support for "scaling" that
+ could be used with DMX: if, in the XF86Config file,
+ multiple Modes are listed in the Display Subsection of the
+ Screen Section, then pressing Ctrl-Alt-Plus and
+ Ctrl-Alt-Minus can be used to iterate through the listed
+ modes. The display dimensions will change to the
+ dimensions in the Modes line, but the logical dimensions
+ of the X server (i.e., the dimensions that Xdmx knows
+ about) will not change.
+ </para>
+ <para>
+ Further, the dimensions of the XFree86 display are under
+ software control (via the XFree86-VidModeExtension), so
+ the Xdmx server could change the screen dimensions on a
+ per-display basis, thereby scaling the information on part
+ of that display.
+ </para>
+ <para>
+ However, this scaling appears to have limited use. For
+ example, assume a 4 by 4 display wall consisting of 16
+ 1280x1024 displays. If all of the back-end servers were
+ simultaneously configured to display 640x480, the left
+ hand corner of each display would be magnified, but the
+ composite result would be unreadable. Magnifying one
+ display at a time could be usable, but could have limited
+ utility, since the result would still be no larger than a
+ single display.
+ </para>
+ </sect3>
+ <sect3><title>Back-end Scaling With Disconnect/Reconnect</title>
+ <para>
+ Disconnect and reconnect features are not currently
+ supported in DMX, but are scheduled to be implemented in
+ the future. These features, combined with the
+ XFree86-VidModeExtension Extension, would allow an
+ application to do the following:
+ <itemizedlist>
+ <listitem><para>
+ Disconnect a specific back-end server (via the DMX
+ Extension),
+ </para></listitem>
+ <listitem><para>
+ reconfigure the XFree86 back-end server resolution,
+ and
+ </para></listitem>
+ <listitem><para>
+ reconnect the back-end server to DMX -- at a new
+ origin with the new screen resolution.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ For example, consider a display wall consisting of 16
+ 1280x1024 displays with a total resolution of 5120x4096.
+ All of the screens could be disconnected, repositioned,
+ and reconnected each at a resolution of 640x480. The
+ total resolution of the display wall would be 2560x1920,
+ allowing a view of a selected area approximately
+ one-fourth of the size of the DMX display. This change
+ would be completely application independent (except,
+ perhaps, for a DMX-aware window manager). When work at
+ the increased resolution was completed, the back-end
+ servers could be disconnected, reconfigured, and
+ reconnected for the original 5120x4096 view.
+ </para>
+ <para>
+ Support for this type of scaling can be implemented in a
+ DMX-aware X11 client assuming the DMX server support
+ arbitrary disconnect and reconnect semantics. Because
+ this application cannot be written before
+ disconnect/reconnect is implemented, this solution will
+ not be discussed further in this paper.
+ </para>
+ </sect3>
+ <sect3><title>Server-side Scaling</title>
+ <para>
+ In earlier versions of DMX, a frame buffer was maintained
+ on the server side, and XPutImage was used to move the
+ information from the server to the client (similar to some
+ early VNC implementations). The use of a server-side
+ frame buffer would allow the server to do scaling, but is
+ not a recommended solution because of overall performance
+ issues and server-side memory issues (i.e., the frame
+ buffer would be very large for large display walls).
+ </para>
+ <para>
+ Exploration of this path is not recommended.
+ </para>
+ </sect3>
+ </sect2>
+ <sect2><title>XCreateScaledWindow API</title>
+ <para>
+ The implementation of X Video Extension in DMX, and the use
+ of XvPutImage by applications requiring scaling requires
+ significant changes in DMX Further, XvPutImage is,
+ essentially a scaled blit, and it is only useful for
+ applications which are already using (or can be modified to
+ use) XPutImage. Therefore, a more general API will be
+ discussed as another possibility.
+ </para>
+ <para>
+ X applications typically create windows with the
+ XCreateWindow call. A new extension could provide an
+ XCreateScaledWindow call that could be used in place of the
+ XCreateWindow call and be otherwise transparent to the
+ application. This would allow applications, even those that
+ do not depend on XPutImage, to take advantage of window
+ scaling. In this section we describe how the call would
+ work, what transparency it provides, and how to solve the
+ potential problems that transparency creates.
+ </para>
+ <sect3><title>XCreateWindow</title>
+ <para>
+ The XCreateWindow call takes width and height as
+ parameters. An XCreateScaledWindow call could take all
+ the same parameters, with the addition of a scaling factor.
+ </para>
+ </sect3>
+ <sect3><title>XSetWindowAttributes</title>
+ <para>
+ An X11 window has several attributes that would have to be
+ scaled:
+ <itemizedlist>
+ <listitem><para>Background and border pixmaps</para></listitem>
+ <listitem><para>Border width</para></listitem>
+ <listitem><para>Cursor</para></listitem>
+ </itemizedlist>
+ </para>
+ </sect3>
+ <sect3><title>XGetWindowAttributes, XGetGeometry</title>
+ <para>
+ For transparency, calls that query the window attributes
+ should return unscaled information. This suggests that
+ all unscaled pixmaps and window attributes should be
+ cached.
+ </para>
+ <para>
+ Unfortunately, a window manager requires the scaled
+ geometry to properly decorate the window. The X server
+ can probably determine which client is acting as the
+ window manager (e.g., because that client will select
+ events that are used exclusively by the window manager).
+ However, other Scaled Window Extension aware clients may
+ also need to determine the scaled geometry. Therefore, at
+ least two additional extension calls should be
+ implemented: XGetScaledWindowAttributes and
+ XGetScaledGeometry.
+ </para>
+ </sect3>
+ <sect3><title>Popup and Child window positions</title>
+ <para>
+ Some applications may position popup and child windows
+ based on an unscaled notion of the main window geometry.
+ In this case, additional modifications to the client would
+ be required.
+ </para>
+ </sect3>
+ <sect3><title>Events</title>
+ <para>
+ Most events (e.g., for mouse motion) return information
+ about the coordinates at which the even occurred. These
+ coordinates would have to be modified so that unscaled
+ values were presented to the client.
+ </para>
+ </sect3>
+ <sect3><title>Implementation</title>
+ <para>
+ There are many implementation issues, some of which are
+ similar to the issues involved in implementing the X Video
+ Extension for DMX. The window contents must be scaled,
+ either by performing all operations to a frame buffer and
+ then writing the image to the display (perhaps using
+ hardware scaling support), or by modifying all of the
+ various drawing operations to perform scaling. Because of
+ the complexity involved, the frame buffer option is
+ recommended.
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1><title>Conclusion and Recommendations
+ </title><para>
+ We recommend a three phase implementation strategy, based on
+ how an application could be written to take advantage of
+ scaling:
+ <orderedlist>
+ <listitem>
+ <para>
+ The XCopyAreaScaled extension should be implemented, since
+ this is the ideal solution for applications like VNC, and
+ since making use of this extension will require minimal
+ changes to applications that already use XPutImage or
+ XCopyArea.
+ </para>
+ <para>
+ The initial implementation work would include the design
+ of the X protocol extension, writing this up in the
+ usual format for extension documentation, implementation
+ of the protocol transport pieces in XFree86,
+ implementation of a software fall-back in XFree86 and
+ DMX, one example hardware implementation for XFree86,
+ and implementation of support for this extension in DMX.
+ </para>
+ <para>
+ We suggest implementing the extension first on the ATI
+ Radeon cards. However, since these cards do not provide
+ a 2D scaled blit primitive, the implementation would
+ have to make use of the 3D texture engine to emulate a
+ scaled blit. This is recommended, since other modern
+ graphics cards also do not provide a simple 2D scaled
+ blit operation and an example of the more difficult
+ implementation pathway would be helpful to others.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Until XCopyAreaScaled is widely supported, applications
+ that require scaling will have to fall back to another
+ scaling method. We suggest OpenGL as the first fall-back
+ method because it is widely available and supported by
+ DMX.
+ </para>
+ <para>
+ A project centered around OpenGL-based scaling would
+ implement this scaling in VNC as an example. This work
+ would include re-writing the <command>vncviewer</command>
+ rendering engine to cache a master copy of the desktop
+ image for all operations.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Since OpenGL is not implemented everywhere, and may not
+ provide hardware-assisted performance in every
+ implementation, an application that requires scaling
+ should also fall back to using the X Video Extension.
+ </para>
+ <para>
+ This project would add support for the X Video Extension
+ to DMX and would add support to VNC to take advantage of
+ this extension without introducing artifacts. This
+ would require modifying the <command>vncviewer</command> rendering
+ engine to cache a master copy of the desktop image for
+ all operations. This project should also add support
+ for the RGB format to at least one XFree86 driver (e.g.,
+ ATI Radeon).
+ </para>
+ <para>
+ The X Video Extension is one of the few popular
+ extensions that DMX does not support. We recommend
+ implementing the X Video Extension even if scaling is
+ the specific goal of that work.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ <para>
+ We do <emphasis>not</emphasis> recommend implementation of the
+ XCreateScaledWindow extension because of the complexity
+ involved. We do <emphasis>not</emphasis> recommend implementation of the
+ XPutImageScaled extension because it requires the same amount
+ of work as the XCopyAreaScaled extension, but provides less
+ functionality. Further, server-side scaling with a large
+ frame buffer is <emphasis>not</emphasis> recommended because of the
+ performance implications.
+ </para>
+ <para>
+ The back-end scaling, especially with disconnect/reconnect
+ support should be explored in the future after
+ disconnect/reconnect is implemented, but not at the present
+ time.
+ </para>
+ </sect1>
+
+ </article>
+ <!-- Local Variables: -->
+ <!-- fill-column: 72 -->
+ <!-- End: -->
diff --git a/xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre b/xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre index f7ff6f617..2eb52ae4d 100644 --- a/xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre +++ b/xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre @@ -1,2430 +1,2438 @@ -.\" shorthand for double quote that works everywhere. -.ds q \N'34' -.TH __xconfigfile__ __filemansuffix__ __vendorversion__ -.SH NAME -__xconfigfile__ and __xconfigdir__ \- configuration files for -__xservername__ X server -.SH INTRODUCTION -.B __xservername__ -supports several mechanisms for supplying/obtaining configuration and -run-time parameters: command line options, environment variables, the -__xconfigfile__ and __xconfigdir__ configuration files, auto-detection, -and fallback defaults. When the same information is supplied in more -than one way, the highest precedence mechanism is used. The list of -mechanisms is ordered from highest precedence to lowest. Note that not -all parameters can be supplied via all methods. The available command -line options and environment variables (and some defaults) are -described in the Xserver(__appmansuffix__) and -__xservername__(__appmansuffix__) manual pages. Most configuration file -parameters, with their defaults, are described below. Driver and module -specific configuration parameters are described in the relevant driver -or module manual page. -.SH DESCRIPTION -.B __xservername__ -uses a configuration file called -.I __xconfigfile__ -and files ending in the suffix -.I .conf -from the directory -.I __xconfigdir__ -for its initial setup. -The -.I __xconfigfile__ -configuration file is searched for in the following places when the -server is started as a normal user: -.PP -.RS 4 -.nf -.IR /etc/X11/ <cmdline> -.IR __projectroot__/etc/X11/ <cmdline> -.IB /etc/X11/ $XORGCONFIG -.IB __projectroot__/etc/X11/ $XORGCONFIG -.I /etc/X11/__xconfigfile__\-4 -.I /etc/X11/__xconfigfile__ -.I /etc/__xconfigfile__ -.IR __projectroot__/etc/X11/__xconfigfile__. <hostname> -.I __projectroot__/etc/X11/__xconfigfile__\-4 -.I __projectroot__/etc/X11/__xconfigfile__ -.IR __projectroot__/lib/X11/__xconfigfile__. <hostname> -.I __projectroot__/lib/X11/__xconfigfile__\-4 -.I __projectroot__/lib/X11/__xconfigfile__ -.fi -.RE -.PP -where -.I <cmdline> -is a relative path (with no \(lq..\(rq components) specified with the -.B \-config -command line option, -.B $XORGCONFIG -is the relative path (with no \(lq..\(rq components) specified by that -environment variable, and -.I <hostname> -is the machine's hostname as reported by -.BR gethostname (__libmansuffix__). -.PP -When the __xservername__ server is started by the \(lqroot\(rq user, the config file -search locations are as follows: -.PP -.RS 4 -.nf -<cmdline> -.IR /etc/X11/ <cmdline> -.IR __projectroot__/etc/X11/ <cmdline> -.B $XORGCONFIG -.IB /etc/X11/ $XORGCONFIG -.IB __projectroot__/etc/X11/ $XORGCONFIG -.I /etc/X11/__xconfigfile__\-4 -.I /etc/X11/__xconfigfile__ -.I /etc/__xconfigfile__ -.IR __projectroot__/etc/X11/__xconfigfile__. <hostname> -.I __projectroot__/etc/X11/__xconfigfile__\-4 -.I __projectroot__/etc/X11/__xconfigfile__ -.IR __projectroot__/lib/X11/__xconfigfile__. <hostname> -.I __projectroot__/lib/X11/__xconfigfile__\-4 -.I __projectroot__/lib/X11/__xconfigfile__ -.fi -.RE -.PP -where -.I <cmdline> -is the path specified with the -.B \-config -command line option (which may be absolute or relative), -.B $XORGCONFIG -is the path specified by that -environment variable (absolute or relative), -.B $HOME -is the path specified by that environment variable (usually the home -directory), and -.I <hostname> -is the machine's hostname as reported by -.BR gethostname (__libmansuffix__). -.PP -Additional configuration files are searched for in the following -directories when the server is started as a normal user: -.PP -.RS 4 -.nf -.IR /etc/X11/ <cmdline> -.IR __sysconfdir__/X11/ <cmdline> -.I /etc/X11/__xconfigdir__ -.I __sysconfdir__/X11/__xconfigdir__ -.fi -.RE -.PP -where -.I <cmdline> -is a relative path (with no \(lq..\(rq components) specified with the -.B \-configdir -command line option. -.PP -When the __xservername__ server is started by the \(lqroot\(rq user, the -config directory search locations are as follows: -.PP -.RS 4 -.nf -<cmdline> -.IR /etc/X11/ <cmdline> -.IR __sysconfdir__/X11/ <cmdline> -.I /etc/X11/__xconfigdir__ -.I __sysconfdir__/X11/__xconfigdir__ -.fi -.RE -.PP -where -.I <cmdline> -is the path specified with the -.B \-configdir -command line option (which may be absolute or relative). -.PP -Finally, configuration files will also be searched for in directories -reserved for system use. These are to separate configuration files from -the vendor or 3rd party packages from those of local administration. -These files are found in the following directories: -.PP -.RS 4 -.nf -.I /usr/share/X11/__xconfigdir__ -.I __datadir__/X11/__xconfigdir__ -.fi -.RE -.PP -The -.I __xconfigfile__ -and -.I __xconfigdir__ -files are composed of a number of sections which may be present in any order, -or omitted to use default configuration values. -Each section has the form: -.PP -.RS 4 -.nf -.BI "Section \*q" SectionName \*q -.RI " " SectionEntry - ... -.B EndSection -.fi -.RE -.PP -The section names are: -.PP -.RS 4 -.nf -.BR "Files " "File pathnames" -.BR "ServerFlags " "Server flags" -.BR "Module " "Dynamic module loading" -.BR "Extensions " "Extension enabling" -.BR "InputDevice " "Input device description" -.BR "InputClass " "Input class description" -.BR "Device " "Graphics device description" -.BR "VideoAdaptor " "Xv video adaptor description" -.BR "Monitor " "Monitor description" -.BR "Modes " "Video modes descriptions" -.BR "Screen " "Screen configuration" -.BR "ServerLayout " "Overall layout" -.BR "DRI " "DRI\-specific configuration" -.BR "Vendor " "Vendor\-specific configuration" -.fi -.RE -.PP -The following obsolete section names are still recognised for compatibility -purposes. -In new config files, the -.B InputDevice -section should be used instead. -.PP -.RS 4 -.nf -.BR "Keyboard " "Keyboard configuration" -.BR "Pointer " "Pointer/mouse configuration" -.fi -.RE -.PP -The old -.B XInput -section is no longer recognised. -.PP -The -.B ServerLayout -sections are at the highest level. -They bind together the input and output devices that will be used in a session. -The input devices are described in the -.B InputDevice -sections. -Output devices usually consist of multiple independent components (e.g., -a graphics board and a monitor). -These multiple components are bound together in the -.B Screen -sections, and it is these that are referenced by the -.B ServerLayout -section. -Each -.B Screen -section binds together a graphics board and a monitor. -The graphics boards are described in the -.B Device -sections, and the monitors are described in the -.B Monitor -sections. -.PP -Config file keywords are case\-insensitive, and \(lq_\(rq characters are -ignored. -Most strings (including -.B Option -names) are also case-insensitive, and insensitive to white space and -\(lq_\(rq characters. -.PP -Each config file entry usually takes up a single line in the file. They -consist of a keyword, which is possibly followed by one or more arguments, -with the number and types of the arguments depending on the keyword. -The argument types are: -.PP -.RS 4 -.nf -.BR "Integer " "an integer number in decimal, hex or octal" -.BR "Real " "a floating point number" -.BR "String " "a string enclosed in double quote marks (\*q)" -.fi -.RE -.PP -Note: hex integer values must be prefixed with \(lq0x\(rq, and octal values -with \(lq0\(rq. -.PP -A special keyword called -.B Option -may be used to provide free\-form data to various components of the server. -The -.B Option -keyword takes either one or two string arguments. -The first is the option name, and the optional second argument is the -option value. -Some commonly used option value types include: -.PP -.RS 4 -.nf -.BR "Integer " "an integer number in decimal, hex or octal" -.BR "Real " "a floating point number" -.BR "String " "a sequence of characters" -.BR "Boolean " "a boolean value (see below)" -.BR "Frequency " "a frequency value (see below)" -.fi -.RE -.PP -Note that -.I all -.B Option -values, not just strings, must be enclosed in quotes. -.PP -Boolean options may optionally have a value specified. -When no value is specified, the option's value is -.BR TRUE . -The following boolean option values are recognised as -.BR TRUE : -.PP -.RS 4 -.BR 1 , -.BR on , -.BR true , -.B yes -.RE -.PP -and the following boolean option values are recognised as -.BR FALSE : -.PP -.RS 4 -.BR 0 , -.BR off , -.BR false , -.B no -.RE -.PP -If an option name is prefixed with -.RB \*q No \*q, -then the option value is negated. -.PP -Example: the following option entries are equivalent: -.PP -.RS 4 -.nf -.B "Option \*qAccel\*q \*qOff\*q" -.B "Option \*qNoAccel\*q" -.B "Option \*qNoAccel\*q \*qOn\*q" -.B "Option \*qAccel\*q \*qfalse\*q" -.B "Option \*qAccel\*q \*qno\*q" -.fi -.RE -.PP -Frequency option values consist of a real number that is optionally -followed by one of the following frequency units: -.PP -.RS 4 -.BR Hz , -.BR k , -.BR kHz , -.BR M , -.B MHz -.RE -.PP -When the unit name is omitted, the correct units will be determined from -the value and the expectations of the appropriate range of the value. -It is recommended that the units always be specified when using frequency -option values to avoid any errors in determining the value. -.SH "FILES SECTION" -The -.B Files -section is used to specify some path names required by the server. -Some of these paths can also be set from the command line (see -.BR Xserver (__appmansuffix__) -and -.BR __xservername__ (__appmansuffix__)). -The command line settings override the values specified in the config -file. -The -.B Files -section is optional, as are all of the entries that may appear in it. -.PP -The entries that can appear in this section are: -.TP 7 -.BI "FontPath \*q" path \*q -sets the search path for fonts. -This path is a comma separated list of font path elements which the __xservername__ -server searches for font databases. -Multiple -.B FontPath -entries may be specified, and they will be concatenated to build up the -fontpath used by the server. Font path elements can be absolute -directory paths, catalogue directories or a font server identifier. The -formats of the later two are explained below: -.PP -.RS 7 -Catalogue directories: -.PP -.RS 4 -Catalogue directories can be specified using the prefix \fBcatalogue:\fR -before the directory name. The directory can then be populated with -symlinks pointing to the real font directories, using the following -syntax in the symlink name: -.PP -.RS 4 -.IR <identifier> : [attribute]: pri= <priority> -.RE -.PP -where -.I <identifier> -is an alphanumeric identifier, -.I [attribute] -is an attribute which will be passed to the underlying FPE and -.I <priority> -is a number used to order the fontfile FPEs. Examples: -.PP -.RS 4 -.nf -.I 75dpi:unscaled:pri=20 -> /usr/share/X11/fonts/75dpi -.I gscript:pri=60 -> /usr/share/fonts/default/ghostscript -.I misc:unscaled:pri=10 \-> /usr/share/X11/fonts/misc -.fi -.PP -.RE .RE .RE -.PP -.RS 7 -Font server identifiers: -.PP -.RS 4 -Font server identifiers have the form: -.RS 4 -.PP -.IR <trans> / <hostname> : <port\-number> -.RE -.PP -where -.I <trans> -is the transport type to use to connect to the font server (e.g., -.B unix -for UNIX\-domain sockets or -.B tcp -for a TCP/IP connection), -.I <hostname> -is the hostname of the machine running the font server, and -.I <port\-number> -is the port number that the font server is listening on (usually 7100). -.RE -.PP -When this entry is not specified in the config file, the server falls back -to the compiled\-in default font path, which contains the following -font path elements (which can be set inside a catalogue directory): -.PP -.RS 4 -.nf -.I __datadir__/fonts/X11/misc/ -.I __datadir__/fonts/X11/TTF/ -.I __datadir__/fonts/X11/OTF/ -.I __datadir__/fonts/X11/Type1/ -.I __datadir__/fonts/X11/100dpi/ -.I __datadir__/fonts/X11/75dpi/ -.fi -.RE -.PP -Font path elements that are found to be invalid are removed from the -font path when the server starts up. -.RE -.TP 7 -.BI "ModulePath \*q" path \*q -sets the search path for loadable __xservername__ server modules. -This path is a comma separated list of directories which the __xservername__ server -searches for loadable modules loading in the order specified. -Multiple -.B ModulePath -entries may be specified, and they will be concatenated to build the -module search path used by the server. The default module path is -.PP -.RS 11 -__modulepath__ -.RE -.\" The LogFile keyword is not currently implemented -.ig -.TP 7 -.BI "LogFile \*q" path \*q -sets the name of the __xservername__ server log file. -The default log file name is -.PP -.RS 11 -.RI __logdir__/__xservername__. <n> .log -.RE -.PP -.RS 7 -where -.I <n> -is the display number for the __xservername__ server. -.. -.TP 7 -.BI "XkbDir \*q" path \*q -sets the base directory for keyboard layout files. The -.B \-xkbdir -command line option can be used to override this. The default directory is -.PP -.RS 11 -__xkbdir__ -.RE -.SH "SERVERFLAGS SECTION" -In addition to options specific to this section (described below), the -.B ServerFlags -section is used to specify some global -__xservername__ server options. -All of the entries in this section are -.BR Options , -although for compatibility purposes some of the old style entries are -still recognised. -Those old style entries are not documented here, and using them is -discouraged. -The -.B ServerFlags -section is optional, as are the entries that may be specified in it. -.PP -.B Options -specified in this section (with the exception of the -.B \*qDefaultServerLayout\*q -.BR Option ) -may be overridden by -.B Options -specified in the active -.B ServerLayout -section. -Options with command line equivalents are overridden when their command -line equivalent is used. -The options recognised by this section are: -.TP 7 -.BI "Option \*qDefaultServerLayout\*q \*q" layout\-id \*q -This specifies the default -.B ServerLayout -section to use in the absence of the -.B \-layout -command line option. -.TP 7 -.BI "Option \*qNoTrapSignals\*q \*q" boolean \*q -This prevents the __xservername__ server from trapping a range of unexpected fatal -signals and exiting cleanly. -Instead, the __xservername__ server will die and drop core where the fault occurred. -The default behaviour is for the __xservername__ server to exit cleanly, but still drop a -core file. -In general you never want to use this option unless you are debugging an __xservername__ -server problem and know how to deal with the consequences. -.TP 7 -.BI "Option \*qUseSIGIO\*q \*q" boolean \*q -This controls whether the __xservername__ server requests that events from -input devices be reported via a SIGIO signal handler (also known as SIGPOLL -on some platforms), or only reported via the standard select(3) loop. -The default behaviour is platform specific. In general you do not want to -use this option unless you are debugging the __xservername__ server, or -working around a specific bug until it is fixed, and understand the -consequences. -.TP 7 -.BI "Option \*qDontVTSwitch\*q \*q" boolean \*q -This disallows the use of the -.BI Ctrl+Alt+F n -sequence (where -.RI F n -refers to one of the numbered function keys). -That sequence is normally used to switch to another \*qvirtual terminal\*q -on operating systems that have this feature. -When this option is enabled, that key sequence has no special meaning and -is passed to clients. -Default: off. -.TP 7 -.BI "Option \*qDontZap\*q \*q" boolean \*q -This disallows the use of the -.B Terminate_Server -XKB action (usually on Ctrl+Alt+Backspace, depending on XKB options). -This action is normally used to terminate the __xservername__ server. -When this option is enabled, the action has no effect. -Default: off. -.TP 7 -.BI "Option \*qDontZoom\*q \*q" boolean \*q -This disallows the use of the -.B Ctrl+Alt+Keypad\-Plus -and -.B Ctrl+Alt+Keypad\-Minus -sequences. -These sequences allows you to switch between video modes. -When this option is enabled, those key sequences have no special meaning -and are passed to clients. -Default: off. -.TP 7 -.BI "Option \*qDisableVidModeExtension\*q \*q" boolean \*q -This disables the parts of the VidMode extension used by the xvidtune client -that can be used to change the video modes. -Default: the VidMode extension is enabled. -.TP 7 -.BI "Option \*qAllowNonLocalXvidtune\*q \*q" boolean \*q -This allows the xvidtune client (and other clients that use the VidMode -extension) to connect from another host. -Default: off. -.TP 7 -.BI "Option \*qAllowMouseOpenFail\*q \*q" boolean \*q -This tells the mousedrv(__drivermansuffix__) and vmmouse(__drivermansuffix__) -drivers to not report failure if the mouse device can't be opened/initialised. -It has no effect on the evdev(__drivermansuffix__) or other drivers. -The previous functionality of allowing the server to start up even if -the mouse device can't be opened/initialised is now handled by the -AllowEmptyInput option. -Default: false. -.TP 7 -.BI "Option \*qVTSysReq\*q \*q" boolean \*q -enables the SYSV\-style VT switch sequence for non\-SYSV systems -which support VT switching. -This sequence is -.B Alt\-SysRq -followed by a function key -.RB ( Fn ). -This prevents the __xservername__ server trapping the -keys used for the default VT switch sequence, which means that clients can -access them. -Default: off. -.TP 7 -.BI "Option \*qBlankTime\*q \*q" time \*q -sets the inactivity timeout for the -.B blank -phase of the screensaver. -.I time -is in minutes. -This is equivalent to the __xservername__ server's -.B \-s -flag, and the value can be changed at run\-time with -.BR xset(__appmansuffix__). -Default: 10 minutes. -.TP 7 -.BI "Option \*qStandbyTime\*q \*q" time \*q -sets the inactivity timeout for the -.B standby -phase of DPMS mode. -.I time -is in minutes, and the value can be changed at run\-time with -.BR xset(__appmansuffix__). -Default: 10 minutes. -This is only suitable for VESA DPMS compatible monitors, and may not be -supported by all video drivers. -It is only enabled for screens that have the -.B \*qDPMS\*q -option set (see the MONITOR section below). -.TP 7 -.BI "Option \*qSuspendTime\*q \*q" time \*q -sets the inactivity timeout for the -.B suspend -phase of DPMS mode. -.I time -is in minutes, and the value can be changed at run\-time with -.BR xset(__appmansuffix__). -Default: 10 minutes. -This is only suitable for VESA DPMS compatible monitors, and may not be -supported by all video drivers. -It is only enabled for screens that have the -.B \*qDPMS\*q -option set (see the MONITOR section below). -.TP 7 -.BI "Option \*qOffTime\*q \*q" time \*q -sets the inactivity timeout for the -.B off -phase of DPMS mode. -.I time -is in minutes, and the value can be changed at run\-time with -.BR xset(__appmansuffix__). -Default: 10 minutes. -This is only suitable for VESA DPMS compatible monitors, and may not be -supported by all video drivers. -It is only enabled for screens that have the -.B \*qDPMS\*q -option set (see the MONITOR section below). -.TP 7 -.BI "Option \*qPixmap\*q \*q" bpp \*q -This sets the pixmap format to use for depth 24. -Allowed values for -.I bpp -are 24 and 32. -Default: 32 unless driver constraints don't allow this (which is rare). -Note: some clients don't behave well when this value is set to 24. -.TP 7 -.BI "Option \*qPC98\*q \*q" boolean \*q -Specify that the machine is a Japanese PC\-98 machine. -This should not be enabled for anything other than the Japanese\-specific -PC\-98 architecture. -Default: auto\-detected. -.TP 7 -.BI "Option \*qNoPM\*q \*q" boolean \*q -Disables something to do with power management events. -Default: PM enabled on platforms that support it. -.TP 7 -.BI "Option \*qXinerama\*q \*q" boolean \*q -enable or disable XINERAMA extension. -Default is disabled. -.TP 7 -.BI "Option \*qAIGLX\*q \*q" boolean \*q -enable or disable AIGLX. AIGLX is enabled by default. -.TP 7 -.BI "Option \*qDRI2\*q \*q" boolean \*q -enable or disable DRI2. DRI2 is disabled by default. -.TP 7 -.BI "Option \*qGlxVisuals\*q \*q" string \*q -This option controls how many GLX visuals the GLX modules sets up. -The default value is -.BR "typical" , -which will setup up a typical subset of -the GLXFBConfigs provided by the driver as GLX visuals. Other options are -.BR "minimal" , -which will set up the minimal set allowed by the GLX specification and -.BR "all" -which will setup GLX visuals for all GLXFBConfigs. -.TP 7 -.BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q -Include the default font path even if other paths are specified in -xorg.conf. If enabled, other font paths are included as well. Enabled by -default. -.TP 7 -.BI "Option \*qIgnoreABI\*q \*q" boolean \*q -Allow modules built for a different, potentially incompatible version of -the X server to load. Disabled by default. -.TP 7 -.BI "Option \*qAllowEmptyInput\*q \*q" boolean \*q -If enabled, don't add the standard keyboard and mouse drivers, if there are no -input devices in the config file. Enabled by default if AutoAddDevices and -AutoEnableDevices is enabled, otherwise disabled. -If AllowEmptyInput is on, devices using the kbd, mouse or vmmouse driver are ignored. -.TP 7 -.BI "Option \*qAutoAddDevices\*q \*q" boolean \*q -If this option is disabled, then no devices will be added from HAL events. -Enabled by default. -.TP 7 -.BI "Option \*qAutoEnableDevices\*q \*q" boolean \*q -If this option is disabled, then the devices will be added (and the -DevicePresenceNotify event sent), but not enabled, thus leaving policy up -to the client. -Enabled by default. -.TP 7 -.BI "Option \*qLog\*q \*q" string \*q -This option controls whether the log is flushed and/or synced to disk after -each message. -Possible values are -.B flush -or -.BR sync . -Unset by default. -.SH "MODULE SECTION" -The -.B Module -section is used to specify which __xservername__ server modules should be loaded. -This section is ignored when the __xservername__ server is built in static form. -The type of modules normally loaded in this section are __xservername__ server -extension modules. -Most other module types are loaded automatically when they are needed via -other mechanisms. -The -.B Module -section is optional, as are all of the entries that may be specified in -it. -.PP -Entries in this section may be in two forms. -The first and most commonly used form is an entry that uses the -.B Load -keyword, as described here: -.TP 7 -.BI "Load \*q" modulename \*q -This instructs the server to load the module called -.IR modulename . -The module name given should be the module's standard name, not the -module file name. -The standard name is case\-sensitive, and does not include the \(lqlib\(rq -prefix, or the \(lq.a\(rq, \(lq.o\(rq, or \(lq.so\(rq suffixes. -.PP -.RS 7 -Example: the DRI extension module can be loaded with the following entry: -.PP -.RS 4 -.B "Load \*qdri\*q" -.RE -.RE -.TP 7 -.BI "Disable \*q" modulename \*q -This instructs the server to not load the module called -.IR modulename . -Some modules are loaded by default in the server, and this overrides that -default. If a -.B Load -instruction is given for the same module, it overrides the -.B Disable -instruction and the module is loaded. The module name given should be the -module's standard name, not the module file name. As with the -.B Load -instruction, the standard name is case-sensitive, and does not include the -"lib" prefix, or the ".a", ".o", or ".so" suffixes. -.PP -The second form of entry is a -.BR SubSection, -with the subsection name being the module name, and the contents of the -.B SubSection -being -.B Options -that are passed to the module when it is loaded. -.PP -Example: the extmod module (which contains a miscellaneous group of -server extensions) can be loaded, with the XFree86\-DGA extension -disabled by using the following entry: -.PP -.RS 4 -.nf -.B "SubSection \*qextmod\*q" -.B " Option \*qomit XFree86\-DGA\*q" -.B EndSubSection -.fi -.RE -.PP -Modules are searched for in each directory specified in the -.B ModulePath -search path, and in the drivers, extensions, input, internal, and -multimedia subdirectories of each of those directories. -In addition to this, operating system specific subdirectories of all -the above are searched first if they exist. -.PP -To see what extension modules are available, check the extensions -subdirectory under: -.PP -.RS 4 -.nf -__modulepath__ -.fi -.RE -.PP -The \(lqextmod\(rq, \(lqdbe\(rq, \(lqdri\(rq, \(lqdri2\(rq, \(lqglx\(rq, -and \(lqrecord\(rq extension modules are loaded automatically, if they -are present, unless disabled with \*qDisable\*q entries. -It is recommended -that at very least the \(lqextmod\(rq extension module be loaded. -If it isn't, some commonly used server extensions (like the SHAPE -extension) will not be available. -.SH "EXTENSIONS SECTION" -The -.B Extensions -section is used to specify which X11 protocol extensions should be enabled -or disabled. -The -.B Extensions -section is optional, as are all of the entries that may be specified in -it. -.PP -Entries in this section are listed as Option statements with the name of -the extension as the first argument, and a boolean value as the second. -The extension name is case\-sensitive, and matches the form shown in the output -of \*qXorg -extension ?\*q. -.PP -.RS 7 -Example: the MIT-SHM extension can be disabled with the following entry: -.PP -.RS 4 -.nf -.B "Section \*qExtensions\*q" -.B " Option \*qMIT-SHM\*q \*qDisable\*q" -.B "EndSection" -.fi -.RE -.RE -.SH "INPUTDEVICE SECTION" -The config file may have multiple -.B InputDevice -sections. -Recent X servers employ input hotplugging to add input devices, with the HAL -backend being the default backend for X servers since 1.4. It is usually not -necessary to provide -.B InputDevice -sections in the xorg.conf if hotplugging is enabled. -.PP -If hotplugging is disabled, there will normally -be at least two: one for the core (primary) keyboard -and one for the core pointer. -If either of these two is missing, a default configuration for the missing -ones will be used. In the absence of an explicitly specified core input -device, the first -.B InputDevice -marked as -.B CorePointer -(or -.BR CoreKeyboard ) -is used. -If there is no match there, the first -.B InputDevice -that uses the \(lqmouse\(rq (or \(lqkbd\(rq) driver is used. -The final fallback is to use built\-in default configurations. -Currently the default configuration may not work as expected on all platforms. -.PP -.B InputDevice -sections have the following format: -.PP -.RS 4 -.nf -.B "Section \*qInputDevice\*q" -.BI " Identifier \*q" name \*q -.BI " Driver \*q" inputdriver \*q -.I " options" -.I " ..." -.B "EndSection" -.fi -.RE -.PP -The -.B Identifier -and -.B Driver -entries are required in all -.B InputDevice -sections. -All other entries are optional. -.PP -The -.B Identifier -entry specifies the unique name for this input device. -The -.B Driver -entry specifies the name of the driver to use for this input device. -When using the loadable server, the input driver module -.RI \*q inputdriver \*q -will be loaded for each active -.B InputDevice -section. -An -.B InputDevice -section is considered active if it is referenced by an active -.B ServerLayout -section, if it is referenced by the -.B \-keyboard -or -.B \-pointer -command line options, or if it is selected implicitly as the core pointer -or keyboard device in the absence of such explicit references. -The most commonly used input drivers are -.BR evdev (__drivermansuffix__) -on Linux systems, and -.BR kbd (__drivermansuffix__) -and -.BR mousedrv (__drivermansuffix__) -on other platforms. -.PP -.PP -.B InputDevice -sections recognise some driver\-independent -.BR Options , -which are described here. -See the individual input driver manual pages for a description of the -device\-specific options. -.TP 7 -.BI "Option \*qAutoServerLayout\*q \*q" boolean \*q -Always add the device to the ServerLayout section used by this instance of -the server. This affects implied layouts as well as explicit layouts -specified in the configuration and/or on the command line. -.TP 7 -.BI "Option \*qCorePointer\*q" -Deprecated, use -.B SendCoreEvents -instead. -.TP 7 -.BI "Option \*qCoreKeyboard\*q" -Deprecated, use -.B SendCoreEvents -instead. -.TP 7 -.BI "Option \*qAlwaysCore\*q \*q" boolean \*q -.B -Deprecated, use -.B SendCoreEvents -instead. -.TP 7 -.BI "Option \*qSendCoreEvents\*q \*q" boolean \*q -Both of these options are equivalent, and when enabled cause the -input device to report core events through the master device. They are -enabled by default. Any device configured to send core events will be -attached to the virtual core pointer or keyboard and control the cursor by -default. Devices with -.B SendCoreEvents -disabled will be \*qfloating\*q and only accessible by clients employing the -X Input extension. This option controls the startup behavior only, a device -may be reattached or set floating at runtime. -.TP 7 -.BI "Option \*qSendDragEvents\*q \*q" boolean \*q -Send core events while dragging. Enabled by default. -.PP -For pointing devices, the following options control how the pointer -is accelerated or decelerated with respect to physical device motion. Most of -these can be adjusted at runtime, see the xinput(1) man page for details. Only -the most important acceleration options are discussed here. -.TP 7 -.BI "Option \*qAccelerationProfile\*q \*q" integer \*q -Select the profile. In layman's terms, the profile constitutes the "feeling" of -the acceleration. More formally, it defines how the transfer function (actual -acceleration as a function of current device velocity and acceleration controls) -is constructed. This is mainly a matter of personal preference. -.PP -.RS 6 -.nf -.B " 0 classic (mostly compatible)" -.B "-1 none (only constant deceleration is applied)" -.B " 1 device-dependent" -.B " 2 polynomial (polynomial function)" -.B " 3 smooth linear (soft knee, then linear)" -.B " 4 simple (normal when slow, otherwise accelerated)" -.B " 5 power (power function)" -.B " 6 linear (more speed, more acceleration)" -.B " 7 limited (like linear, but maxes out at threshold)" -.fi -.RE -.TP 7 -.BI "Option \*qConstantDeceleration\*q \*q" real \*q -Makes the pointer go -.B deceleration -times slower than normal. Most useful for high-resolution devices. -.TP 7 -.BI "Option \*qAdaptiveDeceleration\*q \*q" real \*q -Allows to actually decelerate the pointer when going slow. At most, it will be -.B adaptive deceleration -times slower. Enables precise pointer placement without sacrificing speed. -.TP 7 -.BI "Option \*qAccelerationScheme\*q \*q" string \*q -Selects the scheme, which is the underlying algorithm. -.PP -.RS 7 -.nf -.B "predictable default algorithm (behaving more predictable)" -.B "lightweight old acceleration code (as specified in the X protocol spec)" -.B "none no acceleration or deceleration" -.fi -.RE -.TP 7 -.BI "Option \*qAccelerationNumerator\*q \*q" integer \*q -.TP 7 -.BI "Option \*qAccelerationDenominator\*q \*q" integer \*q -Set numerator and denominator of the acceleration factor. The acceleration -factor is a rational which, together with threshold, can be used to tweak -profiles to suit the users needs. The -.B simple -and -.B limited -profiles use it directly (i.e. they accelerate by the factor), for other -profiles it should hold that a higher acceleration factor leads to a faster -pointer. Typically, 1 is unaccelerated and values up to 5 are sensible. -.TP 7 -.BI "Option \*qAccelerationThreshold\*q \*q" integer \*q -Set the threshold, which is roughly the velocity (usually device units per 10 -ms) required for acceleration to become effective. The precise effect varies -with the profile however. - -.SH "INPUTCLASS SECTION" -The config file may have multiple -.B InputClass -sections. -These sections are optional and are used to provide configuration for a -class of input devices as they are automatically added. An input device can -match more than one -.B InputClass -section. Each class can override settings from a previous class, so it is -best to arrange the sections with the most generic matches first. -.PP -.B InputClass -sections have the following format: -.PP -.RS 4 -.nf -.B "Section \*qInputClass\*q" -.BI " Identifier \*q" name \*q -.I " entries" -.I " ..." -.I " options" -.I " ..." -.B "EndSection" -.fi -.RE -.PP -The -.B Identifier -entry is required in all -.B InputClass -sections. -All other entries are optional. -.PP -The -.B Identifier -entry specifies the unique name for this input class. -The -.B Driver -entry specifies the name of the driver to use for this input device. -After all classes have been examined, the -.RI \*q inputdriver \*q -module from the first -.B Driver -entry will be enabled when using the loadable server. -.PP -When an input device is automatically added, its characteristics are -checked against all -.B InputClass -sections. Each section can contain optional entries to narrow the match -of the class. If none of the optional entries appear, the -.B InputClass -section is generic and will match any input device. If more than one of -these entries appear, they all must match for the configuration to apply. -The allowed matching entries are shown below. -.PP -.TP 7 -.BI "MatchProduct \*q" matchproduct \*q -This entry can be used to check if the substring -.RI \*q matchproduct \*q -occurs in the device's product name. Multiple substrings can be matched by -separating arguments with a '|' character. -.TP 7 -.BI "MatchVendor \*q" matchvendor \*q -This entry can be used to check if the substring -.RI \*q matchvendor \*q -occurs in the device's vendor name. Multiple substrings can be matched by -separating arguments with a '|' character. -.TP 7 -.BI "MatchDevicePath \*q" matchdevice \*q -This entry can be used to check if the device file matches the -.RI \*q matchdevice \*q -pathname pattern. Multiple patterns can be matched by separating arguments -with a '|' character. -.TP 7 -.BI "MatchTag \*q" matchtag \*q -This entry can be used to check if tags assigned by the config backend -matches the -.RI \*q matchtag \*q -pattern. Multiple patterns can be matched by separating arguments -with a '|' character. A match is found if at least one of the tags given in -.RI \*q matchtag \*q -matches at least one of the tags assigned by the backend. -.TP 7 -.BI "MatchIsKeyboard \*q" bool \*q -.TP 7 -.BI "MatchIsPointer \*q" bool \*q -.TP 7 -.BI "MatchIsJoystick \*q" bool \*q -.TP 7 -.BI "MatchIsTablet \*q" bool \*q -.TP 7 -.BI "MatchIsTouchpad \*q" bool \*q -.TP 7 -.BI "MatchIsTouchscreen \*q" bool \*q -Match device types. These entries take a boolean argument similar to -.B Option -entries. -.PP -When an input device has been matched to the -.B InputClass -section, any -.B Option -entries are applied to the device. One -.B InputClass -specific -.B Option -is recognized. See the -.B InputDevice -section above for a description of the remaining -.B Option -entries. -.TP 7 -.BI "Option \*qIgnore\*q \*q" boolean \*q -This optional entry specifies that the device should be ignored entirely, -and not added to the server. This can be useful when the device is handled -by another program and no X events should be generated. -.SH "DEVICE SECTION" -The config file may have multiple -.B Device -sections. -There must be at least one, for the video card being used. -.PP -.B Device -sections have the following format: -.PP -.RS 4 -.nf -.B "Section \*qDevice\*q" -.BI " Identifier \*q" name \*q -.BI " Driver \*q" driver \*q -.I " entries" -.I " ..." -.B "EndSection" -.fi -.RE -.PP -The -.B Identifier -and -.B Driver -entries are required in all -.B Device -sections. All other entries are optional. -.PP -The -.B Identifier -entry specifies the unique name for this graphics device. -The -.B Driver -entry specifies the name of the driver to use for this graphics device. -When using the loadable server, the driver module -.RI \*q driver \*q -will be loaded for each active -.B Device -section. -A -.B Device -section is considered active if it is referenced by an active -.B Screen -section. -.PP -.B Device -sections recognise some driver\-independent entries and -.BR Options , -which are described here. -Not all drivers make use of these -driver\-independent entries, and many of those that do don't require them -to be specified because the information is auto\-detected. -See the individual graphics driver manual pages for further information -about this, and for a description of the device\-specific options. -Note that most of the -.B Options -listed here (but not the other entries) may be specified in the -.B Screen -section instead of here in the -.B Device -section. -.TP 7 -.BI "BusID \*q" bus\-id \*q -This specifies the bus location of the graphics card. -For PCI/AGP cards, -the -.I bus\-id -string has the form -.BI PCI: bus : device : function -(e.g., \(lqPCI:1:0:0\(rq might be appropriate for an AGP card). -This field is usually optional in single-head configurations when using -the primary graphics card. -In multi-head configurations, or when using a secondary graphics card in a -single-head configuration, this entry is mandatory. -Its main purpose is to make an unambiguous connection between the device -section and the hardware it is representing. -This information can usually be found by running the pciaccess tool -scanpci. -.TP 7 -.BI "Screen " number -This option is mandatory for cards where a single PCI entity can drive more -than one display (i.e., multiple CRTCs sharing a single graphics accelerator -and video memory). -One -.B Device -section is required for each head, and this -parameter determines which head each of the -.B Device -sections applies to. -The legal values of -.I number -range from 0 to one less than the total number of heads per entity. -Most drivers require that the primary screen (0) be present. -.TP 7 -.BI "Chipset \*q" chipset \*q -This usually optional entry specifies the chipset used on the graphics -board. -In most cases this entry is not required because the drivers will probe the -hardware to determine the chipset type. -Don't specify it unless the driver-specific documentation recommends that you -do. -.TP 7 -.BI "Ramdac \*q" ramdac\-type \*q -This optional entry specifies the type of RAMDAC used on the graphics -board. -This is only used by a few of the drivers, and in most cases it is not -required because the drivers will probe the hardware to determine the -RAMDAC type where possible. -Don't specify it unless the driver-specific documentation recommends that you -do. -.TP 7 -.BI "DacSpeed " speed -.TP 7 -.BI "DacSpeed " "speed\-8 speed\-16 speed\-24 speed\-32" -This optional entry specifies the RAMDAC speed rating (which is usually -printed on the RAMDAC chip). -The speed is in MHz. -When one value is given, it applies to all framebuffer pixel sizes. -When multiple values are given, they apply to the framebuffer pixel sizes -8, 16, 24 and 32 respectively. -This is not used by many drivers, and only needs to be specified when the -speed rating of the RAMDAC is different from the defaults built in to -driver, or when the driver can't auto-detect the correct defaults. -Don't specify it unless the driver-specific documentation recommends that you -do. -.TP 7 -.BI "Clocks " "clock ..." -specifies the pixel that are on your graphics board. -The clocks are in MHz, and may be specified as a floating point number. -The value is stored internally to the nearest kHz. -The ordering of the clocks is important. -It must match the order in which they are selected on the graphics board. -Multiple -.B Clocks -lines may be specified, and each is concatenated to form the list. -Most drivers do not use this entry, and it is only required for some older -boards with non-programmable clocks. -Don't specify this entry unless the driver-specific documentation explicitly -recommends that you do. -.TP -.BI "ClockChip \*q" clockchip\-type \*q -This optional entry is used to specify the clock chip type on graphics -boards which have a programmable clock generator. -Only a few __xservername__ drivers support programmable clock chips. -For details, see the appropriate driver manual page. -.TP 7 -.BI "VideoRam " "mem" -This optional entry specifies the amount of video ram that is installed -on the graphics board. -This is measured in kBytes. -In most cases this is not required because the __xservername__ server probes -the graphics board to determine this quantity. -The driver-specific documentation should indicate when it might be needed. -.TP 7 -.BI "BiosBase " "baseaddress" -This optional entry specifies the base address of the video BIOS for -the VGA board. -This address is normally auto-detected, and should only be specified if the -driver-specific documentation recommends it. -.TP 7 -.BI "MemBase " "baseaddress" -This optional entry specifies the memory base address of a graphics -board's linear frame buffer. -This entry is not used by many drivers, and it should only be specified if -the driver-specific documentation recommends it. -.TP 7 -.BI "IOBase " "baseaddress" -This optional entry specifies the IO base address. -This entry is not used by many drivers, and it should only be specified if -the driver-specific documentation recommends it. -.TP 7 -.BI "ChipID " "id" -This optional entry specifies a numerical ID representing the chip type. -For PCI cards, it is usually the device ID. -This can be used to override the auto-detection, but that should only be done -when the driver-specific documentation recommends it. -.TP 7 -.BI "ChipRev " "rev" -This optional entry specifies the chip revision number. -This can be used to override the auto-detection, but that should only be done -when the driver-specific documentation recommends it. -.TP 7 -.BI "TextClockFreq " "freq" -This optional entry specifies the pixel clock frequency that is used -for the regular text mode. -The frequency is specified in MHz. -This is rarely used. -.TP 7 -.BI "Option \*qModeDebug\*q \*q" boolean \*q -Enable printing of additional debugging information about modesetting to -the server log. -.ig -.TP 7 -This optional entry allows an IRQ number to be specified. -.. -.TP 7 -.B Options -Option flags may be specified in the -.B Device -sections. -These include driver\-specific options and driver\-independent options. -The former are described in the driver\-specific documentation. -Some of the latter are described below in the section about the -.B Screen -section, and they may also be included here. - -.SH "VIDEOADAPTOR SECTION" -Nobody wants to say how this works. -Maybe nobody knows ... - -.SH "MONITOR SECTION" -The config file may have multiple -.B Monitor -sections. -There should normally be at least one, for the monitor being used, -but a default configuration will be created when one isn't specified. -.PP -.B Monitor -sections have the following format: -.PP -.RS 4 -.nf -.B "Section \*qMonitor\*q" -.BI " Identifier \*q" name \*q -.I " entries" -.I " ..." -.B "EndSection" -.fi -.RE -.PP -The only mandatory entry in a -.B Monitor -section is the -.B Identifier -entry. -.PP -The -.B Identifier -entry specifies the unique name for this monitor. -The -.B Monitor -section may be used to provide information about the specifications of the -monitor, monitor-specific -.BR Options , -and information about the video modes to use with the monitor. -.PP -With RandR 1.2-enabled drivers, monitor sections may be tied to specific -outputs of the video card. Using the name of the output defined by the video -driver plus the identifier of a monitor section, one associates a monitor -section with an output by adding an option to the Device section in the -following format: - -.B Option \*qMonitor-outputname\*q \*qmonitorsection\*q - -(for example, -.B Option \*qMonitor-VGA\*q \*qVGA monitor\*q -for a VGA output) -.PP -In the absence of specific association of monitor sections to outputs, if a -monitor section is present the server will associate it with an output to -preserve compatibility for previous single-head configurations. -.PP -Specifying video modes is optional because the server will use the DDC or other -information provided by the monitor to automatically configure the list of -modes available. -When modes are specified explicitly in the -.B Monitor -section (with the -.BR Modes , -.BR ModeLine , -or -.B UseModes -keywords), built-in modes with the same names are not included. -Built-in modes with different names are, however, still implicitly included, -when they meet the requirements of the monitor. -.PP -The entries that may be used in -.B Monitor -sections are described below. -.TP 7 -.BI "VendorName \*q" vendor \*q -This optional entry specifies the monitor's manufacturer. -.TP 7 -.BI "ModelName \*q" model \*q -This optional entry specifies the monitor's model. -.TP 7 -.BI "HorizSync " "horizsync\-range" -gives the range(s) of horizontal sync frequencies supported by the -monitor. -.I horizsync\-range -may be a comma separated list of either discrete values or ranges of -values. -A range of values is two values separated by a dash. -By default the values are in units of kHz. -They may be specified in MHz or Hz -if -.B MHz -or -.B Hz -is added to the end of the line. -The data given here is used by the __xservername__ server to determine if video -modes are within the specifications of the monitor. -This information should be available in the monitor's handbook. -If this entry is omitted, a default range of 28\-33kHz is used. -.TP 7 -.BI "VertRefresh " "vertrefresh\-range" -gives the range(s) of vertical refresh frequencies supported by the -monitor. -.I vertrefresh\-range -may be a comma separated list of either discrete values or ranges of -values. -A range of values is two values separated by a dash. -By default the values are in units of Hz. -They may be specified in MHz or kHz -if -.B MHz -or -.B kHz -is added to the end of the line. -The data given here is used by the __xservername__ server to determine if video -modes are within the specifications of the monitor. -This information should be available in the monitor's handbook. -If this entry is omitted, a default range of 43\-72Hz is used. -.TP 7 -.BI "DisplaySize " "width height" -This optional entry gives the width and height, in millimetres, of the -picture area of the monitor. -If given this is used to calculate the horizontal and vertical pitch (DPI) of -the screen. -.TP 7 -.BI "Gamma " "gamma\-value" -.TP 7 -.BI "Gamma " "red\-gamma green\-gamma blue\-gamma" -This is an optional entry that can be used to specify the gamma correction -for the monitor. -It may be specified as either a single value or as three separate RGB values. -The values should be in the range 0.1 to 10.0, and the default is 1.0. -Not all drivers are capable of using this information. -.TP 7 -.BI "UseModes \*q" modesection\-id \*q -Include the set of modes listed in the -.B Modes -section called -.IR modesection\-id. -This makes all of the modes defined in that section available for use by -this monitor. -.TP 7 -.BI "Mode \*q" name \*q -This is an optional multi-line entry that can be used to provide -definitions for video modes for the monitor. -In most cases this isn't necessary because the built-in set of VESA standard -modes will be sufficient. -The -.B Mode -keyword indicates the start of a multi-line video mode description. -The mode description is terminated with the -.B EndMode -keyword. -The mode description consists of the following entries: -.RS 7 -.TP 4 -.BI "DotClock " clock -is the dot (pixel) clock rate to be used for the mode. -.TP 4 -.BI "HTimings " "hdisp hsyncstart hsyncend htotal" -specifies the horizontal timings for the mode. -.TP 4 -.BI "VTimings " "vdisp vsyncstart vsyncend vtotal" -specifies the vertical timings for the mode. -.TP 4 -.BI "Flags \*q" flag \*q " ..." -specifies an optional set of mode flags, each of which is a separate -string in double quotes. -.B \*qInterlace\*q -indicates that the mode is interlaced. -.B \*qDoubleScan\*q -indicates a mode where each scanline is doubled. -.B \*q+HSync\*q -and -.B \*q\-HSync\*q -can be used to select the polarity of the HSync signal. -.B \*q+VSync\*q -and -.B \*q\-VSync\*q -can be used to select the polarity of the VSync signal. -.B \*qComposite\*q -can be used to specify composite sync on hardware where this is supported. -Additionally, on some hardware, -.B \*q+CSync\*q -and -.B \*q\-CSync\*q -may be used to select the composite sync polarity. -.TP 4 -.BI "HSkew " hskew -specifies the number of pixels (towards the right edge of the screen) by -which the display enable signal is to be skewed. -Not all drivers use this information. -This option might become necessary to override the default value supplied -by the server (if any). -\(lqRoving\(rq horizontal lines indicate this value needs to be increased. -If the last few pixels on a scan line appear on the left of the screen, -this value should be decreased. -.TP 4 -.BI "VScan " vscan -specifies the number of times each scanline is painted on the screen. -Not all drivers use this information. -Values less than 1 are treated as 1, which is the default. -Generally, the -.B \*qDoubleScan\*q -.B Flag -mentioned above doubles this value. -.RE -.TP 7 -.BI "ModeLine \*q" name \*q " mode\-description" -This entry is a more compact version of the -.B Mode -entry, and it also can be used to specify video modes for the monitor. -is a single line format for specifying video modes. -In most cases this isn't necessary because the built\-in set of VESA -standard modes will be sufficient. -.PP -.RS 7 -The -.I mode\-description -is in four sections, the first three of which are mandatory. -The first is the dot (pixel) clock. -This is a single number specifying the pixel clock rate for the mode in -MHz. -The second section is a list of four numbers specifying the horizontal -timings. -These numbers are the -.IR hdisp , -.IR hsyncstart , -.IR hsyncend , -and -.I htotal -values. -The third section is a list of four numbers specifying the vertical -timings. -These numbers are the -.IR vdisp , -.IR vsyncstart , -.IR vsyncend , -and -.I vtotal -values. -The final section is a list of flags specifying other characteristics of -the mode. -.B Interlace -indicates that the mode is interlaced. -.B DoubleScan -indicates a mode where each scanline is doubled. -.B +HSync -and -.B \-HSync -can be used to select the polarity of the HSync signal. -.B +VSync -and -.B \-VSync -can be used to select the polarity of the VSync signal. -.B Composite -can be used to specify composite sync on hardware where this is supported. -Additionally, on some hardware, -.B +CSync -and -.B \-CSync -may be used to select the composite sync polarity. -The -.B HSkew -and -.B VScan -options mentioned above in the -.B Modes -entry description can also be used here. -.RE -.TP 7 -.BI "Option " "\*qDPMS\*q " \*qbool\*q -This option controls whether the server should enable the DPMS extension -for power management for this screen. The default is to enable the -extension. -.TP 7 -.BI "Option " "\*qSyncOnGreen\*q " \*qbool\*q -This option controls whether the video card should drive the sync signal -on the green color pin. Not all cards support this option, and most -monitors do not require it. The default is off. -.TP 7 -.BI "Option " "\*qPrimary\*q " \*qbool\*q -This optional entry specifies that the monitor should be treated as the primary -monitor. (RandR 1.2-supporting drivers only) -.TP 7 -.BI "Option " "\*qPreferredMode\*q " \*qstring\*q -This optional entry specifies a mode to be marked as the preferred initial mode -of the monitor. -(RandR 1.2-supporting drivers only) -.TP 7 -.BI "Option " "\*qPosition\*q " "\*qx y\*q" -This optional entry specifies the position of the monitor within the X -screen. -(RandR 1.2-supporting drivers only) -.TP 7 -.BI "Option " "\*qLeftOf\*q " \*qoutput\*q -This optional entry specifies that the monitor should be positioned to the -left of the output (not monitor) of the given name. -(RandR 1.2-supporting drivers only) -.TP 7 -.BI "Option " "\*qRightOf\*q " \*qoutput\*q -This optional entry specifies that the monitor should be positioned to the -right of the output (not monitor) of the given name. -(RandR 1.2-supporting drivers only) -.TP 7 -.BI "Option " "\*qAbove\*q " \*qoutput\*q -This optional entry specifies that the monitor should be positioned above the -output (not monitor) of the given name. -(RandR 1.2-supporting drivers only) -.TP 7 -.BI "Option " "\*qBelow\*q " \*qoutput\*q -This optional entry specifies that the monitor should be positioned below the -output (not monitor) of the given name. -(RandR 1.2-supporting drivers only) -.TP 7 -.BI "Option " "\*qEnable\*q " \*qbool\*q -This optional entry specifies whether the monitor should be turned on -at startup. By default, the server will attempt to enable all connected -monitors. -(RandR 1.2-supporting drivers only) -.TP 7 -.BI "Option " "\*qMinClock\*q " \*qfrequency\*q -This optional entry specifies the minimum dot clock, in kHz, that is supported -by the monitor. -.TP 7 -.BI "Option " "\*qMaxClock\*q " \*qfrequency\*q -This optional entry specifies the maximum dot clock, in kHz, that is supported -by the monitor. -.TP 7 -.BI "Option " "\*qIgnore\*q " \*qbool\*q -This optional entry specifies that the monitor should be ignored entirely, -and not reported through RandR. This is useful if the hardware reports the -presence of outputs that don't exist. -(RandR 1.2-supporting drivers only) -.TP 7 -.BI "Option " "\*qRotate\*q " \*qrotation\*q -This optional entry specifies the initial rotation of the given monitor. -Valid values for rotation are \*qnormal\*q, \*qleft\*q, \*qright\*q, and -\*qinverted\*q. -(RandR 1.2-supporting drivers only) - -.SH "MODES SECTION" -The config file may have multiple -.B Modes -sections, or none. -These sections provide a way of defining sets of video modes independently -of the -.B Monitor -sections. -.B Monitor -sections may include the definitions provided in these sections by -using the -.B UseModes -keyword. -In most cases the -.B Modes -sections are not necessary because the built\-in set of VESA standard modes -will be sufficient. -.PP -.B Modes -sections have the following format: -.PP -.RS 4 -.nf -.B "Section \*qModes\*q" -.BI " Identifier \*q" name \*q -.I " entries" -.I " ..." -.B "EndSection" -.fi -.RE -.PP -The -.B Identifier -entry specifies the unique name for this set of mode descriptions. -The other entries permitted in -.B Modes -sections are the -.B Mode -and -.B ModeLine -entries that are described above in the -.B Monitor -section. -.SH "SCREEN SECTION" -The config file may have multiple -.B Screen -sections. -There must be at least one, for the \(lqscreen\(rq being used. -A \(lqscreen\(rq represents the binding of a graphics device -.RB ( Device -section) and a monitor -.RB ( Monitor -section). -A -.B Screen -section is considered \(lqactive\(rq if it is referenced by an active -.B ServerLayout -section or by the -.B \-screen -command line option. -If neither of those is present, the first -.B Screen -section found in the config file is considered the active one. -.PP -.B Screen -sections have the following format: -.PP -.RS 4 -.nf -.B "Section \*qScreen\*q" -.BI " Identifier \*q" name \*q -.BI " Device \*q" devid \*q -.BI " Monitor \*q" monid \*q -.I " entries" -.I " ..." -.BI " SubSection \*qDisplay\*q" -.I " entries" -.I " ... -.B " EndSubSection" -.I " ..." -.B "EndSection" -.fi -.RE -.PP -The -.B Identifier -and -.B Device -entries are mandatory. -All others are optional. -.PP -The -.B Identifier -entry specifies the unique name for this screen. -The -.B Screen -section provides information specific to the whole screen, including -screen\-specific -.BR Options . -In multi\-head configurations, there will be multiple active -.B Screen -sections, one for each head. -The entries available -for this section are: -.TP 7 -.BI "Device \*q" device\-id \*q -This mandatory entry specifies the -.B Device -section to be used for this screen. -This is what ties a specific graphics card to a screen. -The -.I device\-id -must match the -.B Identifier -of a -.B Device -section in the config file. -.TP 7 -.BI "Monitor \*q" monitor\-id \*q -specifies which monitor description is to be used for this screen. -If a -.B Monitor -name is not specified, a default configuration is used. -Currently the default configuration may not function as expected on all -platforms. -.TP 7 -.BI "VideoAdaptor \*q" xv\-id \*q -specifies an optional Xv video adaptor description to be used with this -screen. -.TP 7 -.BI "DefaultDepth " depth -specifies which color depth the server should use by default. -The -.B \-depth -command line option can be used to override this. -If neither is specified, the default depth is driver\-specific, but in most -cases is 8. -.TP 7 -.BI "DefaultFbBpp " bpp -specifies which framebuffer layout to use by default. -The -.B \-fbbpp -command line option can be used to override this. -In most cases the driver will chose the best default value for this. -The only case where there is even a choice in this value is for depth 24, -where some hardware supports both a packed 24 bit framebuffer layout and a -sparse 32 bit framebuffer layout. -.TP 7 -.B Options -Various -.B Option -flags may be specified in the -.B Screen -section. -Some are driver\-specific and are described in the driver documentation. -Others are driver\-independent, and will eventually be described here. -.\" XXX These should really be in an xaa man page. -.TP 7 -.BI "Option \*qAccel\*q" -Enables XAA (X Acceleration Architecture), a mechanism that makes video cards' -2D hardware acceleration available to the __xservername__ server. -This option is on by default, but it may be necessary to turn it off if -there are bugs in the driver. -There are many options to disable specific accelerated operations, listed -below. -Note that disabling an operation will have no effect if the operation is -not accelerated (whether due to lack of support in the hardware or in the -driver). -.TP 7 -.BI "Option \*qInitPrimary\*q \*q" boolean \*q -Use the Int10 module to initialize the primary graphics card. -Normally, only secondary cards are soft-booted using the Int10 module, as the -primary card has already been initialized by the BIOS at boot time. -Default: false. -.TP 7 -.BI "Option \*qNoInt10\*q \*q" boolean \*q -Disables the Int10 module, a module that uses the int10 call to the BIOS -of the graphics card to initialize it. -Default: false. -.TP 7 -.BI "Option \*qNoMTRR\*q" -Disables MTRR (Memory Type Range Register) support, a feature of modern -processors which can improve video performance by a factor of up to 2.5. -Some hardware has buggy MTRR support, and some video drivers have been -known to exhibit problems when MTRR's are used. -.TP 7 -.BI "Option \*qXaaNoCPUToScreenColorExpandFill\*q" -Disables accelerated rectangular expansion blits from source patterns -stored in system memory (using a memory\-mapped aperture). -.TP 7 -.BI "Option \*qXaaNoColor8x8PatternFillRect\*q" -Disables accelerated fills of a rectangular region with a full\-color -pattern. -.TP 7 -.BI "Option \*qXaaNoColor8x8PatternFillTrap\*q" -Disables accelerated fills of a trapezoidal region with a full\-color -pattern. -.TP 7 -.BI "Option \*qXaaNoDashedBresenhamLine\*q" -Disables accelerated dashed Bresenham line draws. -.TP 7 -.BI "Option \*qXaaNoDashedTwoPointLine\*q" -Disables accelerated dashed line draws between two arbitrary points. -.TP 7 -.BI "Option \*qXaaNoImageWriteRect\*q" -Disables accelerated transfers of full\-color rectangular patterns from -system memory to video memory (using a memory\-mapped aperture). -.TP 7 -.BI "Option \*qXaaNoMono8x8PatternFillRect\*q" -Disables accelerated fills of a rectangular region with a monochrome -pattern. -.TP 7 -.BI "Option \*qXaaNoMono8x8PatternFillTrap\*q" -Disables accelerated fills of a trapezoidal region with a monochrome -pattern. -.TP 7 -.BI "Option \*qXaaNoOffscreenPixmaps\*q" -Disables accelerated draws into pixmaps stored in offscreen video memory. -.TP 7 -.BI "Option \*qXaaNoPixmapCache\*q" -Disables caching of patterns in offscreen video memory. -.TP 7 -.BI "Option \*qXaaNoScanlineCPUToScreenColorExpandFill\*q" -Disables accelerated rectangular expansion blits from source patterns -stored in system memory (one scan line at a time). -.TP 7 -.BI "Option \*qXaaNoScanlineImageWriteRect\*q" -Disables accelerated transfers of full\-color rectangular patterns from -system memory to video memory (one scan line at a time). -.TP 7 -.BI "Option \*qXaaNoScreenToScreenColorExpandFill\*q" -Disables accelerated rectangular expansion blits from source patterns -stored in offscreen video memory. -.TP 7 -.BI "Option \*qXaaNoScreenToScreenCopy\*q" -Disables accelerated copies of rectangular regions from one part of -video memory to another part of video memory. -.TP 7 -.BI "Option \*qXaaNoSolidBresenhamLine\*q" -Disables accelerated solid Bresenham line draws. -.TP 7 -.BI "Option \*qXaaNoSolidFillRect\*q" -Disables accelerated solid\-color fills of rectangles. -.TP 7 -.BI "Option \*qXaaNoSolidFillTrap\*q" -Disables accelerated solid\-color fills of Bresenham trapezoids. -.TP 7 -.BI "Option \*qXaaNoSolidHorVertLine\*q" -Disables accelerated solid horizontal and vertical line draws. -.TP 7 -.BI "Option \*qXaaNoSolidTwoPointLine\*q" -Disables accelerated solid line draws between two arbitrary points. -.PP -Each -.B Screen -section may optionally contain one or more -.B Display -subsections. -Those subsections provide depth/fbbpp specific configuration information, -and the one chosen depends on the depth and/or fbbpp that is being used for -the screen. -The -.B Display -subsection format is described in the section below. - -.SH "DISPLAY SUBSECTION" -Each -.B Screen -section may have multiple -.B Display -subsections. -The \(lqactive\(rq -.B Display -subsection is the first that matches the depth and/or fbbpp values being -used, or failing that, the first that has neither a depth or fbbpp value -specified. -The -.B Display -subsections are optional. -When there isn't one that matches the depth and/or fbbpp values being used, -all the parameters that can be specified here fall back to their defaults. -.PP -.B Display -subsections have the following format: -.PP -.RS 4 -.nf -.B " SubSection \*qDisplay\*q" -.BI " Depth " depth -.I " entries" -.I " ..." -.B " EndSubSection" -.fi -.RE -.TP 7 -.BI "Depth " depth -This entry specifies what colour depth the -.B Display -subsection is to be used for. -This entry is usually specified, but it may be omitted to create a match\-all -.B Display -subsection or when wishing to match only against the -.B FbBpp -parameter. -The range of -.I depth -values that are allowed depends on the driver. -Most drivers support 8, 15, 16 and 24. -Some also support 1 and/or 4, and some may support other values (like 30). -Note: -.I depth -means the number of bits in a pixel that are actually used to determine -the pixel colour. -32 is not a valid -.I depth -value. -Most hardware that uses 32 bits per pixel only uses 24 of them to hold the -colour information, which means that the colour depth is 24, not 32. -.TP 7 -.BI "FbBpp " bpp -This entry specifies the framebuffer format this -.B Display -subsection is to be used for. -This entry is only needed when providing depth 24 configurations that allow -a choice between a 24 bpp packed framebuffer format and a 32bpp sparse -framebuffer format. -In most cases this entry should not be used. -.TP 7 -.BI "Weight " "red\-weight green\-weight blue\-weight" -This optional entry specifies the relative RGB weighting to be used -for a screen is being used at depth 16 for drivers that allow multiple -formats. -This may also be specified from the command line with the -.B \-weight -option (see -.BR __xservername__(__appmansuffix__)). -.TP 7 -.BI "Virtual " "xdim ydim" -This optional entry specifies the virtual screen resolution to be used. -.I xdim -must be a multiple of either 8 or 16 for most drivers, and a multiple -of 32 when running in monochrome mode. -The given value will be rounded down if this is not the case. -Video modes which are too large for the specified virtual size will be -rejected. -If this entry is not present, the virtual screen resolution will be set to -accommodate all the valid video modes given in the -.B Modes -entry. -Some drivers/hardware combinations do not support virtual screens. -Refer to the appropriate driver\-specific documentation for details. -.TP 7 -.BI "ViewPort " "x0 y0" -This optional entry sets the upper left corner of the initial display. -This is only relevant when the virtual screen resolution is different -from the resolution of the initial video mode. -If this entry is not given, then the initial display will be centered in -the virtual display area. -.TP 7 -.BI "Modes \*q" mode\-name \*q " ..." -This optional entry specifies the list of video modes to use. -Each -.I mode\-name -specified must be in double quotes. -They must correspond to those specified or referenced in the appropriate -.B Monitor -section (including implicitly referenced built\-in VESA standard modes). -The server will delete modes from this list which don't satisfy various -requirements. -The first valid mode in this list will be the default display mode for -startup. -The list of valid modes is converted internally into a circular list. -It is possible to switch to the next mode with -.B Ctrl+Alt+Keypad\-Plus -and to the previous mode with -.BR Ctrl+Alt+Keypad\-Minus . -When this entry is omitted, the valid modes referenced by the appropriate -.B Monitor -section will be used. If the -.B Monitor -section contains no modes, then the selection will be taken from the -built-in VESA standard modes. -.TP 7 -.BI "Visual \*q" visual\-name \*q -This optional entry sets the default root visual type. -This may also be specified from the command line (see the -.BR Xserver(__appmansuffix__) -man page). -The visual types available for depth 8 are (default is -.BR PseudoColor ): -.PP -.RS 11 -.nf -.B StaticGray -.B GrayScale -.B StaticColor -.B PseudoColor -.B TrueColor -.B DirectColor -.fi -.RE -.PP -.RS 7 -The visual type available for the depths 15, 16 and 24 are (default is -.BR TrueColor ): -.PP -.RS 4 -.nf -.B TrueColor -.B DirectColor -.fi -.RE -.PP -Not all drivers support -.B DirectColor -at these depths. -.PP -The visual types available for the depth 4 are (default is -.BR StaticColor ): -.PP -.RS 4 -.nf -.B StaticGray -.B GrayScale -.B StaticColor -.B PseudoColor -.fi -.RE -.PP -The visual type available for the depth 1 (monochrome) is -.BR StaticGray . -.RE -.TP 7 -.BI "Black " "red green blue" -This optional entry allows the \(lqblack\(rq colour to be specified. -This is only supported at depth 1. -The default is black. -.TP 7 -.BI "White " "red green blue" -This optional entry allows the \(lqwhite\(rq colour to be specified. -This is only supported at depth 1. -The default is white. -.TP 7 -.B Options -Option flags may be specified in the -.B Display -subsections. -These may include driver\-specific options and driver\-independent options. -The former are described in the driver\-specific documentation. -Some of the latter are described above in the section about the -.B Screen -section, and they may also be included here. -.SH "SERVERLAYOUT SECTION" -The config file may have multiple -.B ServerLayout -sections. -A \(lqserver layout\(rq represents the binding of one or more screens -.RB ( Screen -sections) and one or more input devices -.RB ( InputDevice -sections) to form a complete configuration. -In multi\-head configurations, it also specifies the relative layout of the -heads. -A -.B ServerLayout -section is considered \(lqactive\(rq if it is referenced by the -.B \-layout -command line option or by an -.B "Option \*qDefaultServerLayout\*q" -entry in the -.B ServerFlags -section (the former takes precedence over the latter). -If those options are not used, the first -.B ServerLayout -section found in the config file is considered the active one. -If no -.B ServerLayout -sections are present, the single active screen and two active (core) -input devices are selected as described in the relevant sections above. -.PP -.B ServerLayout -sections have the following format: -.PP -.RS 4 -.nf -.B "Section \*qServerLayout\*q" -.BI " Identifier \*q" name \*q -.BI " Screen \*q" screen\-id \*q -.I " ..." -.BI " InputDevice \*q" idev\-id \*q -.I " ..." -.I " options" -.I " ..." -.B "EndSection" -.fi -.RE -.PP -Each -.B ServerLayout -section must have an -.B Identifier -entry and at least one -.B Screen -entry. -.PP -The -.B Identifier -entry specifies the unique name for this server layout. -The -.B ServerLayout -section provides information specific to the whole session, including -session\-specific -.BR Options . -The -.B ServerFlags -options (described above) may be specified here, and ones given here -override those given in the -.B ServerFlags -section. -.PP -The entries that may be used in this section are described here. -.TP 7 -.BI "Screen " "screen\-num" " \*qscreen\-id\*q " "position\-information" -One of these entries must be given for each screen being used in -a session. -The -.I screen\-id -field is mandatory, and specifies the -.B Screen -section being referenced. -The -.I screen\-num -field is optional, and may be used to specify the screen number -in multi\-head configurations. -When this field is omitted, the screens will be numbered in the order that -they are listed in. -The numbering starts from 0, and must be consecutive. -The -.I position\-information -field describes the way multiple screens are positioned. -There are a number of different ways that this information can be provided: -.RS 7 -.TP 4 -.I "x y" -.TP 4 -.BI "Absolute " "x y" -These both specify that the upper left corner's coordinates are -.RI ( x , y ). -The -.B Absolute -keyword is optional. -Some older versions of XFree86 (4.2 and earlier) don't recognise the -.B Absolute -keyword, so it's safest to just specify the coordinates without it. -.TP 4 -.BI "RightOf \*q" screen\-id \*q -.TP 4 -.BI "LeftOf \*q" screen\-id \*q -.TP 4 -.BI "Above \*q" screen\-id \*q -.TP 4 -.BI "Below \*q" screen\-id \*q -.TP 4 -.BI "Relative \*q" screen\-id \*q " x y" -These give the screen's location relative to another screen. -The first four position the screen immediately to the right, left, above or -below the other screen. -When positioning to the right or left, the top edges are aligned. -When positioning above or below, the left edges are aligned. -The -.B Relative -form specifies the offset of the screen's origin (upper left corner) -relative to the origin of another screen. -.RE -.TP 7 -.BI "InputDevice \*q" idev\-id "\*q \*q" option \*q " ..." -One of these entries should be given for each input device being used in -a session. -Normally at least two are required, one each for the core pointer and -keyboard devices. -If either of those is missing, suitable -.B InputDevice -entries are searched for using the method described above in the -.B INPUTDEVICE -section. The -.I idev\-id -field is mandatory, and specifies the name of the -.B InputDevice -section being referenced. -Multiple -.I option -fields may be specified, each in double quotes. -The options permitted here are any that may also be given in the -.B InputDevice -sections. -Normally only session\-specific input device options would be used here. -The most commonly used options are: -.PP -.RS 11 -.nf -.B \*qCorePointer\*q -.B \*qCoreKeyboard\*q -.B \*qSendCoreEvents\*q -.fi -.RE -.PP -.RS 7 -and the first two should normally be used to indicate the core pointer -and core keyboard devices respectively. -.RE -.TP 7 -.B Options -In addition to the following, any option permitted in the -.B ServerFlags -section may also be specified here. -When the same option appears in both places, the value given here overrides -the one given in the -.B ServerFlags -section. -.TP 7 -.BI "Option \*qIsolateDevice\*q \*q" bus\-id \*q -Restrict device resets to the specified -.IR bus\-id . -See the -.B BusID -option (described in -.BR "DEVICE SECTION" , -above) for the format of the -.I bus\-id -parameter. -This option overrides -.BR SingleCard , -if specified. -At present, only PCI devices can be isolated in this manner. -.TP 7 -.BI "Option \*qSingleCard\*q \*q" boolean \*q -As -.BR IsolateDevice , -except that the bus ID of the first device in the layout is used. -.PP -Here is an example of a -.B ServerLayout -section for a dual headed configuration with two mice: -.PP -.RS 4 -.nf -.B "Section \*qServerLayout\*q" -.B " Identifier \*qLayout 1\*q" -.B " Screen \*qMGA 1\*q" -.B " Screen \*qMGA 2\*q RightOf \*qMGA 1\*q" -.B " InputDevice \*qKeyboard 1\*q \*qCoreKeyboard\*q" -.B " InputDevice \*qMouse 1\*q \*qCorePointer\*q" -.B " InputDevice \*qMouse 2\*q \*qSendCoreEvents\*q" -.B " Option \*qBlankTime\*q \*q5\*q" -.B "EndSection" -.fi -.RE -.SH "DRI SECTION" -This optional section is used to provide some information for the -Direct Rendering Infrastructure. -Details about the format of this section -can be found in the README.DRI document, which is also available on-line at -.IR <http://dri.freedesktop.org/> . -.SH "VENDOR SECTION" -The optional -.B Vendor -section may be used to provide vendor\-specific configuration information. -Multiple -.B Vendor -sections may be present, and they may contain an -.B Identifier -entry and multiple -.B Option -flags. -The data therein is not used in this release. -.PP -.SH "SEE ALSO" -General: -.BR X (__miscmansuffix__), -.BR Xserver (__appmansuffix__), -.BR __xservername__ (__appmansuffix__), -.BR cvt (__appmansuffix__), -.BR gtf (__appmansuffix__). -.PP -.B "Not all modules or interfaces are available on all platforms." -.PP -Display drivers: -.BR apm (__drivermansuffix__), -.BR ati (__drivermansuffix__), -.BR chips (__drivermansuffix__), -.BR cirrus (__drivermansuffix__), -.BR cyrix (__drivermansuffix__), -.BR fbdev (__drivermansuffix__), -.BR glide (__drivermansuffix__), -.BR glint (__drivermansuffix__), -.BR i128 (__drivermansuffix__), -.BR i740 (__drivermansuffix__), -.BR imstt (__drivermansuffix__), -.BR intel (__drivermansuffix__), -.BR mga (__drivermansuffix__), -.BR neomagic (__drivermansuffix__), -.BR nv (__drivermansuffix__), -.BR openchrome (__drivermansuffix__), -.BR r128 (__drivermansuffix__), -.BR radeon (__drivermansuffix__), -.BR rendition (__drivermansuffix__), -.BR savage (__drivermansuffix__), -.BR s3virge (__drivermansuffix__), -.BR siliconmotion (__drivermansuffix__), -.BR sis (__drivermansuffix__), -.BR sisusb (__drivermansuffix__), -.BR sunbw2 (__drivermansuffix__), -.BR suncg14 (__drivermansuffix__), -.BR suncg3 (__drivermansuffix__), -.BR suncg6 (__drivermansuffix__), -.BR sunffb (__drivermansuffix__), -.BR sunleo (__drivermansuffix__), -.BR suntcx (__drivermansuffix__), -.BR tdfx (__drivermansuffix__), -.\" .BR tga (__drivermansuffix__), -.BR trident (__drivermansuffix__), -.BR tseng (__drivermansuffix__), -.BR vesa (__drivermansuffix__), -.BR vmware (__drivermansuffix__), -.BR voodoo (__drivermansuffix__), -.BR wsfb (__drivermansuffix__), -.BR xgi (__drivermansuffix__), -.BR xgixp (__drivermansuffix__). -.PP -Input drivers: -.BR acecad (__drivermansuffix__), -.BR citron (__drivermansuffix__), -.BR elographics (__drivermansuffix__), -.BR evdev (__drivermansuffix__), -.BR fpit (__drivermansuffix__), -.BR joystick (__drivermansuffix__), -.BR kbd (__drivermansuffix__), -.BR mousedrv (__drivermansuffix__), -.BR mutouch (__drivermansuffix__), -.BR penmount (__drivermansuffix__), -.BR synaptics (__drivermansuffix__), -.BR vmmouse (__drivermansuffix__), -.BR void (__drivermansuffix__), -.BR wacom (__drivermansuffix__). -.PP -Other modules and interfaces: -.BR exa (__drivermansuffix__), -.BR fbdevhw (__drivermansuffix__), -.\" .BR shadowfb (__drivermansuffix__), -.BR v4l (__drivermansuffix__). -.br -.SH AUTHORS -This manual page was largely rewritten by David Dawes -.IR <dawes@xfree86.org> . +.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH __xconfigfile__ __filemansuffix__ __vendorversion__
+.SH NAME
+__xconfigfile__ and __xconfigdir__ \- configuration files for
+__xservername__ X server
+.SH INTRODUCTION
+.B __xservername__
+supports several mechanisms for supplying/obtaining configuration and
+run-time parameters: command line options, environment variables, the
+__xconfigfile__ and __xconfigdir__ configuration files, auto-detection,
+and fallback defaults. When the same information is supplied in more
+than one way, the highest precedence mechanism is used. The list of
+mechanisms is ordered from highest precedence to lowest. Note that not
+all parameters can be supplied via all methods. The available command
+line options and environment variables (and some defaults) are
+described in the Xserver(__appmansuffix__) and
+__xservername__(__appmansuffix__) manual pages. Most configuration file
+parameters, with their defaults, are described below. Driver and module
+specific configuration parameters are described in the relevant driver
+or module manual page.
+.SH DESCRIPTION
+.B __xservername__
+uses a configuration file called
+.I __xconfigfile__
+and files ending in the suffix
+.I .conf
+from the directory
+.I __xconfigdir__
+for its initial setup.
+The
+.I __xconfigfile__
+configuration file is searched for in the following places when the
+server is started as a normal user:
+.PP
+.RS 4
+.nf
+.IR /etc/X11/ <cmdline>
+.IR __projectroot__/etc/X11/ <cmdline>
+.IB /etc/X11/ $XORGCONFIG
+.IB __projectroot__/etc/X11/ $XORGCONFIG
+.I /etc/X11/__xconfigfile__\-4
+.I /etc/X11/__xconfigfile__
+.I /etc/__xconfigfile__
+.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
+.I __projectroot__/etc/X11/__xconfigfile__\-4
+.I __projectroot__/etc/X11/__xconfigfile__
+.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
+.I __projectroot__/lib/X11/__xconfigfile__\-4
+.I __projectroot__/lib/X11/__xconfigfile__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is a relative path (with no \(lq..\(rq components) specified with the
+.B \-config
+command line option,
+.B $XORGCONFIG
+is the relative path (with no \(lq..\(rq components) specified by that
+environment variable, and
+.I <hostname>
+is the machine's hostname as reported by
+.BR gethostname (__libmansuffix__).
+.PP
+When the __xservername__ server is started by the \(lqroot\(rq user, the config file
+search locations are as follows:
+.PP
+.RS 4
+.nf
+<cmdline>
+.IR /etc/X11/ <cmdline>
+.IR __projectroot__/etc/X11/ <cmdline>
+.B $XORGCONFIG
+.IB /etc/X11/ $XORGCONFIG
+.IB __projectroot__/etc/X11/ $XORGCONFIG
+.I /etc/X11/__xconfigfile__\-4
+.I /etc/X11/__xconfigfile__
+.I /etc/__xconfigfile__
+.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
+.I __projectroot__/etc/X11/__xconfigfile__\-4
+.I __projectroot__/etc/X11/__xconfigfile__
+.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
+.I __projectroot__/lib/X11/__xconfigfile__\-4
+.I __projectroot__/lib/X11/__xconfigfile__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is the path specified with the
+.B \-config
+command line option (which may be absolute or relative),
+.B $XORGCONFIG
+is the path specified by that
+environment variable (absolute or relative),
+.B $HOME
+is the path specified by that environment variable (usually the home
+directory), and
+.I <hostname>
+is the machine's hostname as reported by
+.BR gethostname (__libmansuffix__).
+.PP
+Additional configuration files are searched for in the following
+directories when the server is started as a normal user:
+.PP
+.RS 4
+.nf
+.IR /etc/X11/ <cmdline>
+.IR __sysconfdir__/X11/ <cmdline>
+.I /etc/X11/__xconfigdir__
+.I __sysconfdir__/X11/__xconfigdir__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is a relative path (with no \(lq..\(rq components) specified with the
+.B \-configdir
+command line option.
+.PP
+When the __xservername__ server is started by the \(lqroot\(rq user, the
+config directory search locations are as follows:
+.PP
+.RS 4
+.nf
+<cmdline>
+.IR /etc/X11/ <cmdline>
+.IR __sysconfdir__/X11/ <cmdline>
+.I /etc/X11/__xconfigdir__
+.I __sysconfdir__/X11/__xconfigdir__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is the path specified with the
+.B \-configdir
+command line option (which may be absolute or relative).
+.PP
+Finally, configuration files will also be searched for in directories
+reserved for system use. These are to separate configuration files from
+the vendor or 3rd party packages from those of local administration.
+These files are found in the following directories:
+.PP
+.RS 4
+.nf
+.I /usr/share/X11/__xconfigdir__
+.I __datadir__/X11/__xconfigdir__
+.fi
+.RE
+.PP
+The
+.I __xconfigfile__
+and
+.I __xconfigdir__
+files are composed of a number of sections which may be present in any order,
+or omitted to use default configuration values.
+Each section has the form:
+.PP
+.RS 4
+.nf
+.BI "Section \*q" SectionName \*q
+.RI " " SectionEntry
+ ...
+.B EndSection
+.fi
+.RE
+.PP
+The section names are:
+.PP
+.RS 4
+.nf
+.BR "Files " "File pathnames"
+.BR "ServerFlags " "Server flags"
+.BR "Module " "Dynamic module loading"
+.BR "Extensions " "Extension enabling"
+.BR "InputDevice " "Input device description"
+.BR "InputClass " "Input class description"
+.BR "Device " "Graphics device description"
+.BR "VideoAdaptor " "Xv video adaptor description"
+.BR "Monitor " "Monitor description"
+.BR "Modes " "Video modes descriptions"
+.BR "Screen " "Screen configuration"
+.BR "ServerLayout " "Overall layout"
+.BR "DRI " "DRI\-specific configuration"
+.BR "Vendor " "Vendor\-specific configuration"
+.fi
+.RE
+.PP
+The following obsolete section names are still recognised for compatibility
+purposes.
+In new config files, the
+.B InputDevice
+section should be used instead.
+.PP
+.RS 4
+.nf
+.BR "Keyboard " "Keyboard configuration"
+.BR "Pointer " "Pointer/mouse configuration"
+.fi
+.RE
+.PP
+The old
+.B XInput
+section is no longer recognised.
+.PP
+The
+.B ServerLayout
+sections are at the highest level.
+They bind together the input and output devices that will be used in a session.
+The input devices are described in the
+.B InputDevice
+sections.
+Output devices usually consist of multiple independent components (e.g.,
+a graphics board and a monitor).
+These multiple components are bound together in the
+.B Screen
+sections, and it is these that are referenced by the
+.B ServerLayout
+section.
+Each
+.B Screen
+section binds together a graphics board and a monitor.
+The graphics boards are described in the
+.B Device
+sections, and the monitors are described in the
+.B Monitor
+sections.
+.PP
+Config file keywords are case\-insensitive, and \(lq_\(rq characters are
+ignored.
+Most strings (including
+.B Option
+names) are also case-insensitive, and insensitive to white space and
+\(lq_\(rq characters.
+.PP
+Each config file entry usually takes up a single line in the file. They
+consist of a keyword, which is possibly followed by one or more arguments,
+with the number and types of the arguments depending on the keyword.
+The argument types are:
+.PP
+.RS 4
+.nf
+.BR "Integer " "an integer number in decimal, hex or octal"
+.BR "Real " "a floating point number"
+.BR "String " "a string enclosed in double quote marks (\*q)"
+.fi
+.RE
+.PP
+Note: hex integer values must be prefixed with \(lq0x\(rq, and octal values
+with \(lq0\(rq.
+.PP
+A special keyword called
+.B Option
+may be used to provide free\-form data to various components of the server.
+The
+.B Option
+keyword takes either one or two string arguments.
+The first is the option name, and the optional second argument is the
+option value.
+Some commonly used option value types include:
+.PP
+.RS 4
+.nf
+.BR "Integer " "an integer number in decimal, hex or octal"
+.BR "Real " "a floating point number"
+.BR "String " "a sequence of characters"
+.BR "Boolean " "a boolean value (see below)"
+.BR "Frequency " "a frequency value (see below)"
+.fi
+.RE
+.PP
+Note that
+.I all
+.B Option
+values, not just strings, must be enclosed in quotes.
+.PP
+Boolean options may optionally have a value specified.
+When no value is specified, the option's value is
+.BR TRUE .
+The following boolean option values are recognised as
+.BR TRUE :
+.PP
+.RS 4
+.BR 1 ,
+.BR on ,
+.BR true ,
+.B yes
+.RE
+.PP
+and the following boolean option values are recognised as
+.BR FALSE :
+.PP
+.RS 4
+.BR 0 ,
+.BR off ,
+.BR false ,
+.B no
+.RE
+.PP
+If an option name is prefixed with
+.RB \*q No \*q,
+then the option value is negated.
+.PP
+Example: the following option entries are equivalent:
+.PP
+.RS 4
+.nf
+.B "Option \*qAccel\*q \*qOff\*q"
+.B "Option \*qNoAccel\*q"
+.B "Option \*qNoAccel\*q \*qOn\*q"
+.B "Option \*qAccel\*q \*qfalse\*q"
+.B "Option \*qAccel\*q \*qno\*q"
+.fi
+.RE
+.PP
+Frequency option values consist of a real number that is optionally
+followed by one of the following frequency units:
+.PP
+.RS 4
+.BR Hz ,
+.BR k ,
+.BR kHz ,
+.BR M ,
+.B MHz
+.RE
+.PP
+When the unit name is omitted, the correct units will be determined from
+the value and the expectations of the appropriate range of the value.
+It is recommended that the units always be specified when using frequency
+option values to avoid any errors in determining the value.
+.SH "FILES SECTION"
+The
+.B Files
+section is used to specify some path names required by the server.
+Some of these paths can also be set from the command line (see
+.BR Xserver (__appmansuffix__)
+and
+.BR __xservername__ (__appmansuffix__)).
+The command line settings override the values specified in the config
+file.
+The
+.B Files
+section is optional, as are all of the entries that may appear in it.
+.PP
+The entries that can appear in this section are:
+.TP 7
+.BI "FontPath \*q" path \*q
+sets the search path for fonts.
+This path is a comma separated list of font path elements which the __xservername__
+server searches for font databases.
+Multiple
+.B FontPath
+entries may be specified, and they will be concatenated to build up the
+fontpath used by the server. Font path elements can be absolute
+directory paths, catalogue directories or a font server identifier. The
+formats of the later two are explained below:
+.PP
+.RS 7
+Catalogue directories:
+.PP
+.RS 4
+Catalogue directories can be specified using the prefix \fBcatalogue:\fR
+before the directory name. The directory can then be populated with
+symlinks pointing to the real font directories, using the following
+syntax in the symlink name:
+.PP
+.RS 4
+.IR <identifier> : [attribute]: pri= <priority>
+.RE
+.PP
+where
+.I <identifier>
+is an alphanumeric identifier,
+.I [attribute]
+is an attribute which will be passed to the underlying FPE and
+.I <priority>
+is a number used to order the fontfile FPEs. Examples:
+.PP
+.RS 4
+.nf
+.I 75dpi:unscaled:pri=20 -> /usr/share/X11/fonts/75dpi
+.I gscript:pri=60 -> /usr/share/fonts/default/ghostscript
+.I misc:unscaled:pri=10 \-> /usr/share/X11/fonts/misc
+.fi
+.PP
+.RE .RE .RE
+.PP
+.RS 7
+Font server identifiers:
+.PP
+.RS 4
+Font server identifiers have the form:
+.RS 4
+.PP
+.IR <trans> / <hostname> : <port\-number>
+.RE
+.PP
+where
+.I <trans>
+is the transport type to use to connect to the font server (e.g.,
+.B unix
+for UNIX\-domain sockets or
+.B tcp
+for a TCP/IP connection),
+.I <hostname>
+is the hostname of the machine running the font server, and
+.I <port\-number>
+is the port number that the font server is listening on (usually 7100).
+.RE
+.PP
+When this entry is not specified in the config file, the server falls back
+to the compiled\-in default font path, which contains the following
+font path elements (which can be set inside a catalogue directory):
+.PP
+.RS 4
+.nf
+.I __datadir__/fonts/X11/misc/
+.I __datadir__/fonts/X11/TTF/
+.I __datadir__/fonts/X11/OTF/
+.I __datadir__/fonts/X11/Type1/
+.I __datadir__/fonts/X11/100dpi/
+.I __datadir__/fonts/X11/75dpi/
+.fi
+.RE
+.PP
+Font path elements that are found to be invalid are removed from the
+font path when the server starts up.
+.RE
+.TP 7
+.BI "ModulePath \*q" path \*q
+sets the search path for loadable __xservername__ server modules.
+This path is a comma separated list of directories which the __xservername__ server
+searches for loadable modules loading in the order specified.
+Multiple
+.B ModulePath
+entries may be specified, and they will be concatenated to build the
+module search path used by the server. The default module path is
+.PP
+.RS 11
+__modulepath__
+.RE
+.\" The LogFile keyword is not currently implemented
+.ig
+.TP 7
+.BI "LogFile \*q" path \*q
+sets the name of the __xservername__ server log file.
+The default log file name is
+.PP
+.RS 11
+.RI __logdir__/__xservername__. <n> .log
+.RE
+.PP
+.RS 7
+where
+.I <n>
+is the display number for the __xservername__ server.
+..
+.TP 7
+.BI "XkbDir \*q" path \*q
+sets the base directory for keyboard layout files. The
+.B \-xkbdir
+command line option can be used to override this. The default directory is
+.PP
+.RS 11
+__xkbdir__
+.RE
+.SH "SERVERFLAGS SECTION"
+In addition to options specific to this section (described below), the
+.B ServerFlags
+section is used to specify some global
+__xservername__ server options.
+All of the entries in this section are
+.BR Options ,
+although for compatibility purposes some of the old style entries are
+still recognised.
+Those old style entries are not documented here, and using them is
+discouraged.
+The
+.B ServerFlags
+section is optional, as are the entries that may be specified in it.
+.PP
+.B Options
+specified in this section (with the exception of the
+.B \*qDefaultServerLayout\*q
+.BR Option )
+may be overridden by
+.B Options
+specified in the active
+.B ServerLayout
+section.
+Options with command line equivalents are overridden when their command
+line equivalent is used.
+The options recognised by this section are:
+.TP 7
+.BI "Option \*qDefaultServerLayout\*q \*q" layout\-id \*q
+This specifies the default
+.B ServerLayout
+section to use in the absence of the
+.B \-layout
+command line option.
+.TP 7
+.BI "Option \*qNoTrapSignals\*q \*q" boolean \*q
+This prevents the __xservername__ server from trapping a range of unexpected fatal
+signals and exiting cleanly.
+Instead, the __xservername__ server will die and drop core where the fault occurred.
+The default behaviour is for the __xservername__ server to exit cleanly, but still drop a
+core file.
+In general you never want to use this option unless you are debugging an __xservername__
+server problem and know how to deal with the consequences.
+.TP 7
+.BI "Option \*qUseSIGIO\*q \*q" boolean \*q
+This controls whether the __xservername__ server requests that events from
+input devices be reported via a SIGIO signal handler (also known as SIGPOLL
+on some platforms), or only reported via the standard select(3) loop.
+The default behaviour is platform specific. In general you do not want to
+use this option unless you are debugging the __xservername__ server, or
+working around a specific bug until it is fixed, and understand the
+consequences.
+.TP 7
+.BI "Option \*qDontVTSwitch\*q \*q" boolean \*q
+This disallows the use of the
+.BI Ctrl+Alt+F n
+sequence (where
+.RI F n
+refers to one of the numbered function keys).
+That sequence is normally used to switch to another \*qvirtual terminal\*q
+on operating systems that have this feature.
+When this option is enabled, that key sequence has no special meaning and
+is passed to clients.
+Default: off.
+.TP 7
+.BI "Option \*qDontZap\*q \*q" boolean \*q
+This disallows the use of the
+.B Terminate_Server
+XKB action (usually on Ctrl+Alt+Backspace, depending on XKB options).
+This action is normally used to terminate the __xservername__ server.
+When this option is enabled, the action has no effect.
+Default: off.
+.TP 7
+.BI "Option \*qDontZoom\*q \*q" boolean \*q
+This disallows the use of the
+.B Ctrl+Alt+Keypad\-Plus
+and
+.B Ctrl+Alt+Keypad\-Minus
+sequences.
+These sequences allows you to switch between video modes.
+When this option is enabled, those key sequences have no special meaning
+and are passed to clients.
+Default: off.
+.TP 7
+.BI "Option \*qDisableVidModeExtension\*q \*q" boolean \*q
+This disables the parts of the VidMode extension used by the xvidtune client
+that can be used to change the video modes.
+Default: the VidMode extension is enabled.
+.TP 7
+.BI "Option \*qAllowNonLocalXvidtune\*q \*q" boolean \*q
+This allows the xvidtune client (and other clients that use the VidMode
+extension) to connect from another host.
+Default: off.
+.TP 7
+.BI "Option \*qAllowMouseOpenFail\*q \*q" boolean \*q
+This tells the mousedrv(__drivermansuffix__) and vmmouse(__drivermansuffix__)
+drivers to not report failure if the mouse device can't be opened/initialised.
+It has no effect on the evdev(__drivermansuffix__) or other drivers.
+The previous functionality of allowing the server to start up even if
+the mouse device can't be opened/initialised is now handled by the
+AllowEmptyInput option.
+Default: false.
+.TP 7
+.BI "Option \*qVTSysReq\*q \*q" boolean \*q
+enables the SYSV\-style VT switch sequence for non\-SYSV systems
+which support VT switching.
+This sequence is
+.B Alt\-SysRq
+followed by a function key
+.RB ( Fn ).
+This prevents the __xservername__ server trapping the
+keys used for the default VT switch sequence, which means that clients can
+access them.
+Default: off.
+.TP 7
+.BI "Option \*qBlankTime\*q \*q" time \*q
+sets the inactivity timeout for the
+.B blank
+phase of the screensaver.
+.I time
+is in minutes.
+This is equivalent to the __xservername__ server's
+.B \-s
+flag, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+.TP 7
+.BI "Option \*qStandbyTime\*q \*q" time \*q
+sets the inactivity timeout for the
+.B standby
+phase of DPMS mode.
+.I time
+is in minutes, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+This is only suitable for VESA DPMS compatible monitors, and may not be
+supported by all video drivers.
+It is only enabled for screens that have the
+.B \*qDPMS\*q
+option set (see the MONITOR section below).
+.TP 7
+.BI "Option \*qSuspendTime\*q \*q" time \*q
+sets the inactivity timeout for the
+.B suspend
+phase of DPMS mode.
+.I time
+is in minutes, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+This is only suitable for VESA DPMS compatible monitors, and may not be
+supported by all video drivers.
+It is only enabled for screens that have the
+.B \*qDPMS\*q
+option set (see the MONITOR section below).
+.TP 7
+.BI "Option \*qOffTime\*q \*q" time \*q
+sets the inactivity timeout for the
+.B off
+phase of DPMS mode.
+.I time
+is in minutes, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+This is only suitable for VESA DPMS compatible monitors, and may not be
+supported by all video drivers.
+It is only enabled for screens that have the
+.B \*qDPMS\*q
+option set (see the MONITOR section below).
+.TP 7
+.BI "Option \*qPixmap\*q \*q" bpp \*q
+This sets the pixmap format to use for depth 24.
+Allowed values for
+.I bpp
+are 24 and 32.
+Default: 32 unless driver constraints don't allow this (which is rare).
+Note: some clients don't behave well when this value is set to 24.
+.TP 7
+.BI "Option \*qPC98\*q \*q" boolean \*q
+Specify that the machine is a Japanese PC\-98 machine.
+This should not be enabled for anything other than the Japanese\-specific
+PC\-98 architecture.
+Default: auto\-detected.
+.TP 7
+.BI "Option \*qNoPM\*q \*q" boolean \*q
+Disables something to do with power management events.
+Default: PM enabled on platforms that support it.
+.TP 7
+.BI "Option \*qXinerama\*q \*q" boolean \*q
+enable or disable XINERAMA extension.
+Default is disabled.
+.TP 7
+.BI "Option \*qAIGLX\*q \*q" boolean \*q
+enable or disable AIGLX. AIGLX is enabled by default.
+.TP 7
+.BI "Option \*qDRI2\*q \*q" boolean \*q
+enable or disable DRI2. DRI2 is disabled by default.
+.TP 7
+.BI "Option \*qGlxVisuals\*q \*q" string \*q
+This option controls how many GLX visuals the GLX modules sets up.
+The default value is
+.BR "typical" ,
+which will setup up a typical subset of
+the GLXFBConfigs provided by the driver as GLX visuals. Other options are
+.BR "minimal" ,
+which will set up the minimal set allowed by the GLX specification and
+.BR "all"
+which will setup GLX visuals for all GLXFBConfigs.
+.TP 7
+.BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q
+Include the default font path even if other paths are specified in
+xorg.conf. If enabled, other font paths are included as well. Enabled by
+default.
+.TP 7
+.BI "Option \*qIgnoreABI\*q \*q" boolean \*q
+Allow modules built for a different, potentially incompatible version of
+the X server to load. Disabled by default.
+.TP 7
+.BI "Option \*qAllowEmptyInput\*q \*q" boolean \*q
+If enabled, don't add the standard keyboard and mouse drivers, if there are no
+input devices in the config file. Enabled by default if AutoAddDevices and
+AutoEnableDevices is enabled, otherwise disabled.
+If AllowEmptyInput is on, devices using the kbd, mouse or vmmouse driver are ignored.
+.TP 7
+.BI "Option \*qAutoAddDevices\*q \*q" boolean \*q
+If this option is disabled, then no devices will be added from HAL events.
+Enabled by default.
+.TP 7
+.BI "Option \*qAutoEnableDevices\*q \*q" boolean \*q
+If this option is disabled, then the devices will be added (and the
+DevicePresenceNotify event sent), but not enabled, thus leaving policy up
+to the client.
+Enabled by default.
+.TP 7
+.BI "Option \*qLog\*q \*q" string \*q
+This option controls whether the log is flushed and/or synced to disk after
+each message.
+Possible values are
+.B flush
+or
+.BR sync .
+Unset by default.
+.SH "MODULE SECTION"
+The
+.B Module
+section is used to specify which __xservername__ server modules should be loaded.
+This section is ignored when the __xservername__ server is built in static form.
+The type of modules normally loaded in this section are __xservername__ server
+extension modules.
+Most other module types are loaded automatically when they are needed via
+other mechanisms.
+The
+.B Module
+section is optional, as are all of the entries that may be specified in
+it.
+.PP
+Entries in this section may be in two forms.
+The first and most commonly used form is an entry that uses the
+.B Load
+keyword, as described here:
+.TP 7
+.BI "Load \*q" modulename \*q
+This instructs the server to load the module called
+.IR modulename .
+The module name given should be the module's standard name, not the
+module file name.
+The standard name is case\-sensitive, and does not include the \(lqlib\(rq
+prefix, or the \(lq.a\(rq, \(lq.o\(rq, or \(lq.so\(rq suffixes.
+.PP
+.RS 7
+Example: the DRI extension module can be loaded with the following entry:
+.PP
+.RS 4
+.B "Load \*qdri\*q"
+.RE
+.RE
+.TP 7
+.BI "Disable \*q" modulename \*q
+This instructs the server to not load the module called
+.IR modulename .
+Some modules are loaded by default in the server, and this overrides that
+default. If a
+.B Load
+instruction is given for the same module, it overrides the
+.B Disable
+instruction and the module is loaded. The module name given should be the
+module's standard name, not the module file name. As with the
+.B Load
+instruction, the standard name is case-sensitive, and does not include the
+"lib" prefix, or the ".a", ".o", or ".so" suffixes.
+.PP
+The second form of entry is a
+.BR SubSection,
+with the subsection name being the module name, and the contents of the
+.B SubSection
+being
+.B Options
+that are passed to the module when it is loaded.
+.PP
+Example: the extmod module (which contains a miscellaneous group of
+server extensions) can be loaded, with the XFree86\-DGA extension
+disabled by using the following entry:
+.PP
+.RS 4
+.nf
+.B "SubSection \*qextmod\*q"
+.B " Option \*qomit XFree86\-DGA\*q"
+.B EndSubSection
+.fi
+.RE
+.PP
+Modules are searched for in each directory specified in the
+.B ModulePath
+search path, and in the drivers, extensions, input, internal, and
+multimedia subdirectories of each of those directories.
+In addition to this, operating system specific subdirectories of all
+the above are searched first if they exist.
+.PP
+To see what extension modules are available, check the extensions
+subdirectory under:
+.PP
+.RS 4
+.nf
+__modulepath__
+.fi
+.RE
+.PP
+The \(lqextmod\(rq, \(lqdbe\(rq, \(lqdri\(rq, \(lqdri2\(rq, \(lqglx\(rq,
+and \(lqrecord\(rq extension modules are loaded automatically, if they
+are present, unless disabled with \*qDisable\*q entries.
+It is recommended
+that at very least the \(lqextmod\(rq extension module be loaded.
+If it isn't, some commonly used server extensions (like the SHAPE
+extension) will not be available.
+.SH "EXTENSIONS SECTION"
+The
+.B Extensions
+section is used to specify which X11 protocol extensions should be enabled
+or disabled.
+The
+.B Extensions
+section is optional, as are all of the entries that may be specified in
+it.
+.PP
+Entries in this section are listed as Option statements with the name of
+the extension as the first argument, and a boolean value as the second.
+The extension name is case\-sensitive, and matches the form shown in the output
+of \*qXorg -extension ?\*q.
+.PP
+.RS 7
+Example: the MIT-SHM extension can be disabled with the following entry:
+.PP
+.RS 4
+.nf
+.B "Section \*qExtensions\*q"
+.B " Option \*qMIT-SHM\*q \*qDisable\*q"
+.B "EndSection"
+.fi
+.RE
+.RE
+.SH "INPUTDEVICE SECTION"
+The config file may have multiple
+.B InputDevice
+sections.
+Recent X servers employ input hotplugging to add input devices, with the HAL
+backend being the default backend for X servers since 1.4. It is usually not
+necessary to provide
+.B InputDevice
+sections in the xorg.conf if hotplugging is enabled.
+.PP
+If hotplugging is disabled, there will normally
+be at least two: one for the core (primary) keyboard
+and one for the core pointer.
+If either of these two is missing, a default configuration for the missing
+ones will be used. In the absence of an explicitly specified core input
+device, the first
+.B InputDevice
+marked as
+.B CorePointer
+(or
+.BR CoreKeyboard )
+is used.
+If there is no match there, the first
+.B InputDevice
+that uses the \(lqmouse\(rq (or \(lqkbd\(rq) driver is used.
+The final fallback is to use built\-in default configurations.
+Currently the default configuration may not work as expected on all platforms.
+.PP
+.B InputDevice
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qInputDevice\*q"
+.BI " Identifier \*q" name \*q
+.BI " Driver \*q" inputdriver \*q
+.I " options"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+and
+.B Driver
+entries are required in all
+.B InputDevice
+sections.
+All other entries are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this input device.
+The
+.B Driver
+entry specifies the name of the driver to use for this input device.
+When using the loadable server, the input driver module
+.RI \*q inputdriver \*q
+will be loaded for each active
+.B InputDevice
+section.
+An
+.B InputDevice
+section is considered active if it is referenced by an active
+.B ServerLayout
+section, if it is referenced by the
+.B \-keyboard
+or
+.B \-pointer
+command line options, or if it is selected implicitly as the core pointer
+or keyboard device in the absence of such explicit references.
+The most commonly used input drivers are
+.BR evdev (__drivermansuffix__)
+on Linux systems, and
+.BR kbd (__drivermansuffix__)
+and
+.BR mousedrv (__drivermansuffix__)
+on other platforms.
+.PP
+.PP
+.B InputDevice
+sections recognise some driver\-independent
+.BR Options ,
+which are described here.
+See the individual input driver manual pages for a description of the
+device\-specific options.
+.TP 7
+.BI "Option \*qAutoServerLayout\*q \*q" boolean \*q
+Always add the device to the ServerLayout section used by this instance of
+the server. This affects implied layouts as well as explicit layouts
+specified in the configuration and/or on the command line.
+.TP 7
+.BI "Option \*qCorePointer\*q"
+Deprecated, use
+.B SendCoreEvents
+instead.
+.TP 7
+.BI "Option \*qCoreKeyboard\*q"
+Deprecated, use
+.B SendCoreEvents
+instead.
+.TP 7
+.BI "Option \*qAlwaysCore\*q \*q" boolean \*q
+.B
+Deprecated, use
+.B SendCoreEvents
+instead.
+.TP 7
+.BI "Option \*qSendCoreEvents\*q \*q" boolean \*q
+Both of these options are equivalent, and when enabled cause the
+input device to report core events through the master device. They are
+enabled by default. Any device configured to send core events will be
+attached to the virtual core pointer or keyboard and control the cursor by
+default. Devices with
+.B SendCoreEvents
+disabled will be \*qfloating\*q and only accessible by clients employing the
+X Input extension. This option controls the startup behavior only, a device
+may be reattached or set floating at runtime.
+.TP 7
+.BI "Option \*qSendDragEvents\*q \*q" boolean \*q
+Send core events while dragging. Enabled by default.
+.PP
+For pointing devices, the following options control how the pointer
+is accelerated or decelerated with respect to physical device motion. Most of
+these can be adjusted at runtime, see the xinput(1) man page for details. Only
+the most important acceleration options are discussed here.
+.TP 7
+.BI "Option \*qAccelerationProfile\*q \*q" integer \*q
+Select the profile. In layman's terms, the profile constitutes the "feeling" of
+the acceleration. More formally, it defines how the transfer function (actual
+acceleration as a function of current device velocity and acceleration controls)
+is constructed. This is mainly a matter of personal preference.
+.PP
+.RS 6
+.nf
+.B " 0 classic (mostly compatible)"
+.B "-1 none (only constant deceleration is applied)"
+.B " 1 device-dependent"
+.B " 2 polynomial (polynomial function)"
+.B " 3 smooth linear (soft knee, then linear)"
+.B " 4 simple (normal when slow, otherwise accelerated)"
+.B " 5 power (power function)"
+.B " 6 linear (more speed, more acceleration)"
+.B " 7 limited (like linear, but maxes out at threshold)"
+.fi
+.RE
+.TP 7
+.BI "Option \*qConstantDeceleration\*q \*q" real \*q
+Makes the pointer go
+.B deceleration
+times slower than normal. Most useful for high-resolution devices.
+.TP 7
+.BI "Option \*qAdaptiveDeceleration\*q \*q" real \*q
+Allows to actually decelerate the pointer when going slow. At most, it will be
+.B adaptive deceleration
+times slower. Enables precise pointer placement without sacrificing speed.
+.TP 7
+.BI "Option \*qAccelerationScheme\*q \*q" string \*q
+Selects the scheme, which is the underlying algorithm.
+.PP
+.RS 7
+.nf
+.B "predictable default algorithm (behaving more predictable)"
+.B "lightweight old acceleration code (as specified in the X protocol spec)"
+.B "none no acceleration or deceleration"
+.fi
+.RE
+.TP 7
+.BI "Option \*qAccelerationNumerator\*q \*q" integer \*q
+.TP 7
+.BI "Option \*qAccelerationDenominator\*q \*q" integer \*q
+Set numerator and denominator of the acceleration factor. The acceleration
+factor is a rational which, together with threshold, can be used to tweak
+profiles to suit the users needs. The
+.B simple
+and
+.B limited
+profiles use it directly (i.e. they accelerate by the factor), for other
+profiles it should hold that a higher acceleration factor leads to a faster
+pointer. Typically, 1 is unaccelerated and values up to 5 are sensible.
+.TP 7
+.BI "Option \*qAccelerationThreshold\*q \*q" integer \*q
+Set the threshold, which is roughly the velocity (usually device units per 10
+ms) required for acceleration to become effective. The precise effect varies
+with the profile however.
+
+.SH "INPUTCLASS SECTION"
+The config file may have multiple
+.B InputClass
+sections.
+These sections are optional and are used to provide configuration for a
+class of input devices as they are automatically added. An input device can
+match more than one
+.B InputClass
+section. Each class can override settings from a previous class, so it is
+best to arrange the sections with the most generic matches first.
+.PP
+.B InputClass
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qInputClass\*q"
+.BI " Identifier \*q" name \*q
+.I " entries"
+.I " ..."
+.I " options"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+entry is required in all
+.B InputClass
+sections.
+All other entries are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this input class.
+The
+.B Driver
+entry specifies the name of the driver to use for this input device.
+After all classes have been examined, the
+.RI \*q inputdriver \*q
+module from the first
+.B Driver
+entry will be enabled when using the loadable server.
+.PP
+When an input device is automatically added, its characteristics are
+checked against all
+.B InputClass
+sections. Each section can contain optional entries to narrow the match
+of the class. If none of the optional entries appear, the
+.B InputClass
+section is generic and will match any input device. If more than one of
+these entries appear, they all must match for the configuration to apply.
+The allowed matching entries are shown below.
+.PP
+.TP 7
+.BI "MatchProduct \*q" matchproduct \*q
+This entry can be used to check if the substring
+.RI \*q matchproduct \*q
+occurs in the device's product name. Multiple substrings can be matched by
+separating arguments with a '|' character.
+.TP 7
+.BI "MatchVendor \*q" matchvendor \*q
+This entry can be used to check if the substring
+.RI \*q matchvendor \*q
+occurs in the device's vendor name. Multiple substrings can be matched by
+separating arguments with a '|' character.
+.TP 7
+.BI "MatchDevicePath \*q" matchdevice \*q
+This entry can be used to check if the device file matches the
+.RI \*q matchdevice \*q
+pathname pattern. Multiple patterns can be matched by separating arguments
+with a '|' character.
+.TP 7
+.BI "MatchTag \*q" matchtag \*q
+This entry can be used to check if tags assigned by the config backend
+matches the
+.RI \*q matchtag \*q
+pattern. Multiple patterns can be matched by separating arguments
+with a '|' character. A match is found if at least one of the tags given in
+.RI \*q matchtag \*q
+matches at least one of the tags assigned by the backend.
+.TP 7
+.BI "MatchIsKeyboard \*q" bool \*q
+.TP 7
+.BI "MatchIsPointer \*q" bool \*q
+.TP 7
+.BI "MatchIsJoystick \*q" bool \*q
+.TP 7
+.BI "MatchIsTablet \*q" bool \*q
+.TP 7
+.BI "MatchIsTouchpad \*q" bool \*q
+.TP 7
+.BI "MatchIsTouchscreen \*q" bool \*q
+Match device types. These entries take a boolean argument similar to
+.B Option
+entries.
+.PP
+When an input device has been matched to the
+.B InputClass
+section, any
+.B Option
+entries are applied to the device. One
+.B InputClass
+specific
+.B Option
+is recognized. See the
+.B InputDevice
+section above for a description of the remaining
+.B Option
+entries.
+.TP 7
+.BI "Option \*qIgnore\*q \*q" boolean \*q
+This optional entry specifies that the device should be ignored entirely,
+and not added to the server. This can be useful when the device is handled
+by another program and no X events should be generated.
+.SH "DEVICE SECTION"
+The config file may have multiple
+.B Device
+sections.
+There must be at least one, for the video card being used.
+.PP
+.B Device
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" name \*q
+.BI " Driver \*q" driver \*q
+.I " entries"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+and
+.B Driver
+entries are required in all
+.B Device
+sections. All other entries are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this graphics device.
+The
+.B Driver
+entry specifies the name of the driver to use for this graphics device.
+When using the loadable server, the driver module
+.RI \*q driver \*q
+will be loaded for each active
+.B Device
+section.
+A
+.B Device
+section is considered active if it is referenced by an active
+.B Screen
+section.
+.PP
+.B Device
+sections recognise some driver\-independent entries and
+.BR Options ,
+which are described here.
+Not all drivers make use of these
+driver\-independent entries, and many of those that do don't require them
+to be specified because the information is auto\-detected.
+See the individual graphics driver manual pages for further information
+about this, and for a description of the device\-specific options.
+Note that most of the
+.B Options
+listed here (but not the other entries) may be specified in the
+.B Screen
+section instead of here in the
+.B Device
+section.
+.TP 7
+.BI "BusID \*q" bus\-id \*q
+This specifies the bus location of the graphics card.
+For PCI/AGP cards,
+the
+.I bus\-id
+string has the form
+.BI PCI: bus : device : function
+(e.g., \(lqPCI:1:0:0\(rq might be appropriate for an AGP card).
+This field is usually optional in single-head configurations when using
+the primary graphics card.
+In multi-head configurations, or when using a secondary graphics card in a
+single-head configuration, this entry is mandatory.
+Its main purpose is to make an unambiguous connection between the device
+section and the hardware it is representing.
+This information can usually be found by running the pciaccess tool
+scanpci.
+.TP 7
+.BI "Screen " number
+This option is mandatory for cards where a single PCI entity can drive more
+than one display (i.e., multiple CRTCs sharing a single graphics accelerator
+and video memory).
+One
+.B Device
+section is required for each head, and this
+parameter determines which head each of the
+.B Device
+sections applies to.
+The legal values of
+.I number
+range from 0 to one less than the total number of heads per entity.
+Most drivers require that the primary screen (0) be present.
+.TP 7
+.BI "Chipset \*q" chipset \*q
+This usually optional entry specifies the chipset used on the graphics
+board.
+In most cases this entry is not required because the drivers will probe the
+hardware to determine the chipset type.
+Don't specify it unless the driver-specific documentation recommends that you
+do.
+.TP 7
+.BI "Ramdac \*q" ramdac\-type \*q
+This optional entry specifies the type of RAMDAC used on the graphics
+board.
+This is only used by a few of the drivers, and in most cases it is not
+required because the drivers will probe the hardware to determine the
+RAMDAC type where possible.
+Don't specify it unless the driver-specific documentation recommends that you
+do.
+.TP 7
+.BI "DacSpeed " speed
+.TP 7
+.BI "DacSpeed " "speed\-8 speed\-16 speed\-24 speed\-32"
+This optional entry specifies the RAMDAC speed rating (which is usually
+printed on the RAMDAC chip).
+The speed is in MHz.
+When one value is given, it applies to all framebuffer pixel sizes.
+When multiple values are given, they apply to the framebuffer pixel sizes
+8, 16, 24 and 32 respectively.
+This is not used by many drivers, and only needs to be specified when the
+speed rating of the RAMDAC is different from the defaults built in to
+driver, or when the driver can't auto-detect the correct defaults.
+Don't specify it unless the driver-specific documentation recommends that you
+do.
+.TP 7
+.BI "Clocks " "clock ..."
+specifies the pixel that are on your graphics board.
+The clocks are in MHz, and may be specified as a floating point number.
+The value is stored internally to the nearest kHz.
+The ordering of the clocks is important.
+It must match the order in which they are selected on the graphics board.
+Multiple
+.B Clocks
+lines may be specified, and each is concatenated to form the list.
+Most drivers do not use this entry, and it is only required for some older
+boards with non-programmable clocks.
+Don't specify this entry unless the driver-specific documentation explicitly
+recommends that you do.
+.TP
+.BI "ClockChip \*q" clockchip\-type \*q
+This optional entry is used to specify the clock chip type on graphics
+boards which have a programmable clock generator.
+Only a few __xservername__ drivers support programmable clock chips.
+For details, see the appropriate driver manual page.
+.TP 7
+.BI "VideoRam " "mem"
+This optional entry specifies the amount of video ram that is installed
+on the graphics board.
+This is measured in kBytes.
+In most cases this is not required because the __xservername__ server probes
+the graphics board to determine this quantity.
+The driver-specific documentation should indicate when it might be needed.
+.TP 7
+.BI "BiosBase " "baseaddress"
+This optional entry specifies the base address of the video BIOS for
+the VGA board.
+This address is normally auto-detected, and should only be specified if the
+driver-specific documentation recommends it.
+.TP 7
+.BI "MemBase " "baseaddress"
+This optional entry specifies the memory base address of a graphics
+board's linear frame buffer.
+This entry is not used by many drivers, and it should only be specified if
+the driver-specific documentation recommends it.
+.TP 7
+.BI "IOBase " "baseaddress"
+This optional entry specifies the IO base address.
+This entry is not used by many drivers, and it should only be specified if
+the driver-specific documentation recommends it.
+.TP 7
+.BI "ChipID " "id"
+This optional entry specifies a numerical ID representing the chip type.
+For PCI cards, it is usually the device ID.
+This can be used to override the auto-detection, but that should only be done
+when the driver-specific documentation recommends it.
+.TP 7
+.BI "ChipRev " "rev"
+This optional entry specifies the chip revision number.
+This can be used to override the auto-detection, but that should only be done
+when the driver-specific documentation recommends it.
+.TP 7
+.BI "TextClockFreq " "freq"
+This optional entry specifies the pixel clock frequency that is used
+for the regular text mode.
+The frequency is specified in MHz.
+This is rarely used.
+.TP 7
+.BI "Option \*qModeDebug\*q \*q" boolean \*q
+Enable printing of additional debugging information about modesetting to
+the server log.
+.ig
+.TP 7
+This optional entry allows an IRQ number to be specified.
+..
+.TP 7
+.B Options
+Option flags may be specified in the
+.B Device
+sections.
+These include driver\-specific options and driver\-independent options.
+The former are described in the driver\-specific documentation.
+Some of the latter are described below in the section about the
+.B Screen
+section, and they may also be included here.
+
+.SH "VIDEOADAPTOR SECTION"
+Nobody wants to say how this works.
+Maybe nobody knows ...
+
+.SH "MONITOR SECTION"
+The config file may have multiple
+.B Monitor
+sections.
+There should normally be at least one, for the monitor being used,
+but a default configuration will be created when one isn't specified.
+.PP
+.B Monitor
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qMonitor\*q"
+.BI " Identifier \*q" name \*q
+.I " entries"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The only mandatory entry in a
+.B Monitor
+section is the
+.B Identifier
+entry.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this monitor.
+The
+.B Monitor
+section may be used to provide information about the specifications of the
+monitor, monitor-specific
+.BR Options ,
+and information about the video modes to use with the monitor.
+.PP
+With RandR 1.2-enabled drivers, monitor sections may be tied to specific
+outputs of the video card. Using the name of the output defined by the video
+driver plus the identifier of a monitor section, one associates a monitor
+section with an output by adding an option to the Device section in the
+following format:
+
+.B Option \*qMonitor-outputname\*q \*qmonitorsection\*q
+
+(for example,
+.B Option \*qMonitor-VGA\*q \*qVGA monitor\*q
+for a VGA output)
+.PP
+In the absence of specific association of monitor sections to outputs, if a
+monitor section is present the server will associate it with an output to
+preserve compatibility for previous single-head configurations.
+.PP
+Specifying video modes is optional because the server will use the DDC or other
+information provided by the monitor to automatically configure the list of
+modes available.
+When modes are specified explicitly in the
+.B Monitor
+section (with the
+.BR Modes ,
+.BR ModeLine ,
+or
+.B UseModes
+keywords), built-in modes with the same names are not included.
+Built-in modes with different names are, however, still implicitly included,
+when they meet the requirements of the monitor.
+.PP
+The entries that may be used in
+.B Monitor
+sections are described below.
+.TP 7
+.BI "VendorName \*q" vendor \*q
+This optional entry specifies the monitor's manufacturer.
+.TP 7
+.BI "ModelName \*q" model \*q
+This optional entry specifies the monitor's model.
+.TP 7
+.BI "HorizSync " "horizsync\-range"
+gives the range(s) of horizontal sync frequencies supported by the
+monitor.
+.I horizsync\-range
+may be a comma separated list of either discrete values or ranges of
+values.
+A range of values is two values separated by a dash.
+By default the values are in units of kHz.
+They may be specified in MHz or Hz
+if
+.B MHz
+or
+.B Hz
+is added to the end of the line.
+The data given here is used by the __xservername__ server to determine if video
+modes are within the specifications of the monitor.
+This information should be available in the monitor's handbook.
+If this entry is omitted, a default range of 28\-33kHz is used.
+.TP 7
+.BI "VertRefresh " "vertrefresh\-range"
+gives the range(s) of vertical refresh frequencies supported by the
+monitor.
+.I vertrefresh\-range
+may be a comma separated list of either discrete values or ranges of
+values.
+A range of values is two values separated by a dash.
+By default the values are in units of Hz.
+They may be specified in MHz or kHz
+if
+.B MHz
+or
+.B kHz
+is added to the end of the line.
+The data given here is used by the __xservername__ server to determine if video
+modes are within the specifications of the monitor.
+This information should be available in the monitor's handbook.
+If this entry is omitted, a default range of 43\-72Hz is used.
+.TP 7
+.BI "DisplaySize " "width height"
+This optional entry gives the width and height, in millimetres, of the
+picture area of the monitor.
+If given this is used to calculate the horizontal and vertical pitch (DPI) of
+the screen.
+.TP 7
+.BI "Gamma " "gamma\-value"
+.TP 7
+.BI "Gamma " "red\-gamma green\-gamma blue\-gamma"
+This is an optional entry that can be used to specify the gamma correction
+for the monitor.
+It may be specified as either a single value or as three separate RGB values.
+The values should be in the range 0.1 to 10.0, and the default is 1.0.
+Not all drivers are capable of using this information.
+.TP 7
+.BI "UseModes \*q" modesection\-id \*q
+Include the set of modes listed in the
+.B Modes
+section called
+.IR modesection\-id.
+This makes all of the modes defined in that section available for use by
+this monitor.
+.TP 7
+.BI "Mode \*q" name \*q
+This is an optional multi-line entry that can be used to provide
+definitions for video modes for the monitor.
+In most cases this isn't necessary because the built-in set of VESA standard
+modes will be sufficient.
+The
+.B Mode
+keyword indicates the start of a multi-line video mode description.
+The mode description is terminated with the
+.B EndMode
+keyword.
+The mode description consists of the following entries:
+.RS 7
+.TP 4
+.BI "DotClock " clock
+is the dot (pixel) clock rate to be used for the mode.
+.TP 4
+.BI "HTimings " "hdisp hsyncstart hsyncend htotal"
+specifies the horizontal timings for the mode.
+.TP 4
+.BI "VTimings " "vdisp vsyncstart vsyncend vtotal"
+specifies the vertical timings for the mode.
+.TP 4
+.BI "Flags \*q" flag \*q " ..."
+specifies an optional set of mode flags, each of which is a separate
+string in double quotes.
+.B \*qInterlace\*q
+indicates that the mode is interlaced.
+.B \*qDoubleScan\*q
+indicates a mode where each scanline is doubled.
+.B \*q+HSync\*q
+and
+.B \*q\-HSync\*q
+can be used to select the polarity of the HSync signal.
+.B \*q+VSync\*q
+and
+.B \*q\-VSync\*q
+can be used to select the polarity of the VSync signal.
+.B \*qComposite\*q
+can be used to specify composite sync on hardware where this is supported.
+Additionally, on some hardware,
+.B \*q+CSync\*q
+and
+.B \*q\-CSync\*q
+may be used to select the composite sync polarity.
+.TP 4
+.BI "HSkew " hskew
+specifies the number of pixels (towards the right edge of the screen) by
+which the display enable signal is to be skewed.
+Not all drivers use this information.
+This option might become necessary to override the default value supplied
+by the server (if any).
+\(lqRoving\(rq horizontal lines indicate this value needs to be increased.
+If the last few pixels on a scan line appear on the left of the screen,
+this value should be decreased.
+.TP 4
+.BI "VScan " vscan
+specifies the number of times each scanline is painted on the screen.
+Not all drivers use this information.
+Values less than 1 are treated as 1, which is the default.
+Generally, the
+.B \*qDoubleScan\*q
+.B Flag
+mentioned above doubles this value.
+.RE
+.TP 7
+.BI "ModeLine \*q" name \*q " mode\-description"
+This entry is a more compact version of the
+.B Mode
+entry, and it also can be used to specify video modes for the monitor.
+is a single line format for specifying video modes.
+In most cases this isn't necessary because the built\-in set of VESA
+standard modes will be sufficient.
+.PP
+.RS 7
+The
+.I mode\-description
+is in four sections, the first three of which are mandatory.
+The first is the dot (pixel) clock.
+This is a single number specifying the pixel clock rate for the mode in
+MHz.
+The second section is a list of four numbers specifying the horizontal
+timings.
+These numbers are the
+.IR hdisp ,
+.IR hsyncstart ,
+.IR hsyncend ,
+and
+.I htotal
+values.
+The third section is a list of four numbers specifying the vertical
+timings.
+These numbers are the
+.IR vdisp ,
+.IR vsyncstart ,
+.IR vsyncend ,
+and
+.I vtotal
+values.
+The final section is a list of flags specifying other characteristics of
+the mode.
+.B Interlace
+indicates that the mode is interlaced.
+.B DoubleScan
+indicates a mode where each scanline is doubled.
+.B +HSync
+and
+.B \-HSync
+can be used to select the polarity of the HSync signal.
+.B +VSync
+and
+.B \-VSync
+can be used to select the polarity of the VSync signal.
+.B Composite
+can be used to specify composite sync on hardware where this is supported.
+Additionally, on some hardware,
+.B +CSync
+and
+.B \-CSync
+may be used to select the composite sync polarity.
+The
+.B HSkew
+and
+.B VScan
+options mentioned above in the
+.B Modes
+entry description can also be used here.
+.RE
+.TP 7
+.BI "Option " "\*qDPMS\*q " \*qbool\*q
+This option controls whether the server should enable the DPMS extension
+for power management for this screen. The default is to enable the
+extension.
+.TP 7
+.BI "Option " "\*qSyncOnGreen\*q " \*qbool\*q
+This option controls whether the video card should drive the sync signal
+on the green color pin. Not all cards support this option, and most
+monitors do not require it. The default is off.
+.TP 7
+.BI "Option " "\*qPrimary\*q " \*qbool\*q
+This optional entry specifies that the monitor should be treated as the primary
+monitor. (RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qPreferredMode\*q " \*qstring\*q
+This optional entry specifies a mode to be marked as the preferred initial mode
+of the monitor.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qPosition\*q " "\*qx y\*q"
+This optional entry specifies the position of the monitor within the X
+screen.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qLeftOf\*q " \*qoutput\*q
+This optional entry specifies that the monitor should be positioned to the
+left of the output (not monitor) of the given name.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qRightOf\*q " \*qoutput\*q
+This optional entry specifies that the monitor should be positioned to the
+right of the output (not monitor) of the given name.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qAbove\*q " \*qoutput\*q
+This optional entry specifies that the monitor should be positioned above the
+output (not monitor) of the given name.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qBelow\*q " \*qoutput\*q
+This optional entry specifies that the monitor should be positioned below the
+output (not monitor) of the given name.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qEnable\*q " \*qbool\*q
+This optional entry specifies whether the monitor should be turned on
+at startup. By default, the server will attempt to enable all connected
+monitors.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qDefaultModes\*q " \*qbool\*q
+This optional entry specifies whether the server should add supported default
+modes to the list of modes offered on this monitor. By default, the server
+will add default modes; you should only disable this if you can guarantee
+that EDID will be available at all times, or if you have added custom modelines
+which the server can use.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qMinClock\*q " \*qfrequency\*q
+This optional entry specifies the minimum dot clock, in kHz, that is supported
+by the monitor.
+.TP 7
+.BI "Option " "\*qMaxClock\*q " \*qfrequency\*q
+This optional entry specifies the maximum dot clock, in kHz, that is supported
+by the monitor.
+.TP 7
+.BI "Option " "\*qIgnore\*q " \*qbool\*q
+This optional entry specifies that the monitor should be ignored entirely,
+and not reported through RandR. This is useful if the hardware reports the
+presence of outputs that don't exist.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qRotate\*q " \*qrotation\*q
+This optional entry specifies the initial rotation of the given monitor.
+Valid values for rotation are \*qnormal\*q, \*qleft\*q, \*qright\*q, and
+\*qinverted\*q.
+(RandR 1.2-supporting drivers only)
+
+.SH "MODES SECTION"
+The config file may have multiple
+.B Modes
+sections, or none.
+These sections provide a way of defining sets of video modes independently
+of the
+.B Monitor
+sections.
+.B Monitor
+sections may include the definitions provided in these sections by
+using the
+.B UseModes
+keyword.
+In most cases the
+.B Modes
+sections are not necessary because the built\-in set of VESA standard modes
+will be sufficient.
+.PP
+.B Modes
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qModes\*q"
+.BI " Identifier \*q" name \*q
+.I " entries"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+entry specifies the unique name for this set of mode descriptions.
+The other entries permitted in
+.B Modes
+sections are the
+.B Mode
+and
+.B ModeLine
+entries that are described above in the
+.B Monitor
+section.
+.SH "SCREEN SECTION"
+The config file may have multiple
+.B Screen
+sections.
+There must be at least one, for the \(lqscreen\(rq being used.
+A \(lqscreen\(rq represents the binding of a graphics device
+.RB ( Device
+section) and a monitor
+.RB ( Monitor
+section).
+A
+.B Screen
+section is considered \(lqactive\(rq if it is referenced by an active
+.B ServerLayout
+section or by the
+.B \-screen
+command line option.
+If neither of those is present, the first
+.B Screen
+section found in the config file is considered the active one.
+.PP
+.B Screen
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qScreen\*q"
+.BI " Identifier \*q" name \*q
+.BI " Device \*q" devid \*q
+.BI " Monitor \*q" monid \*q
+.I " entries"
+.I " ..."
+.BI " SubSection \*qDisplay\*q"
+.I " entries"
+.I " ...
+.B " EndSubSection"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+and
+.B Device
+entries are mandatory.
+All others are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this screen.
+The
+.B Screen
+section provides information specific to the whole screen, including
+screen\-specific
+.BR Options .
+In multi\-head configurations, there will be multiple active
+.B Screen
+sections, one for each head.
+The entries available
+for this section are:
+.TP 7
+.BI "Device \*q" device\-id \*q
+This mandatory entry specifies the
+.B Device
+section to be used for this screen.
+This is what ties a specific graphics card to a screen.
+The
+.I device\-id
+must match the
+.B Identifier
+of a
+.B Device
+section in the config file.
+.TP 7
+.BI "Monitor \*q" monitor\-id \*q
+specifies which monitor description is to be used for this screen.
+If a
+.B Monitor
+name is not specified, a default configuration is used.
+Currently the default configuration may not function as expected on all
+platforms.
+.TP 7
+.BI "VideoAdaptor \*q" xv\-id \*q
+specifies an optional Xv video adaptor description to be used with this
+screen.
+.TP 7
+.BI "DefaultDepth " depth
+specifies which color depth the server should use by default.
+The
+.B \-depth
+command line option can be used to override this.
+If neither is specified, the default depth is driver\-specific, but in most
+cases is 8.
+.TP 7
+.BI "DefaultFbBpp " bpp
+specifies which framebuffer layout to use by default.
+The
+.B \-fbbpp
+command line option can be used to override this.
+In most cases the driver will chose the best default value for this.
+The only case where there is even a choice in this value is for depth 24,
+where some hardware supports both a packed 24 bit framebuffer layout and a
+sparse 32 bit framebuffer layout.
+.TP 7
+.B Options
+Various
+.B Option
+flags may be specified in the
+.B Screen
+section.
+Some are driver\-specific and are described in the driver documentation.
+Others are driver\-independent, and will eventually be described here.
+.\" XXX These should really be in an xaa man page.
+.TP 7
+.BI "Option \*qAccel\*q"
+Enables XAA (X Acceleration Architecture), a mechanism that makes video cards'
+2D hardware acceleration available to the __xservername__ server.
+This option is on by default, but it may be necessary to turn it off if
+there are bugs in the driver.
+There are many options to disable specific accelerated operations, listed
+below.
+Note that disabling an operation will have no effect if the operation is
+not accelerated (whether due to lack of support in the hardware or in the
+driver).
+.TP 7
+.BI "Option \*qInitPrimary\*q \*q" boolean \*q
+Use the Int10 module to initialize the primary graphics card.
+Normally, only secondary cards are soft-booted using the Int10 module, as the
+primary card has already been initialized by the BIOS at boot time.
+Default: false.
+.TP 7
+.BI "Option \*qNoInt10\*q \*q" boolean \*q
+Disables the Int10 module, a module that uses the int10 call to the BIOS
+of the graphics card to initialize it.
+Default: false.
+.TP 7
+.BI "Option \*qNoMTRR\*q"
+Disables MTRR (Memory Type Range Register) support, a feature of modern
+processors which can improve video performance by a factor of up to 2.5.
+Some hardware has buggy MTRR support, and some video drivers have been
+known to exhibit problems when MTRR's are used.
+.TP 7
+.BI "Option \*qXaaNoCPUToScreenColorExpandFill\*q"
+Disables accelerated rectangular expansion blits from source patterns
+stored in system memory (using a memory\-mapped aperture).
+.TP 7
+.BI "Option \*qXaaNoColor8x8PatternFillRect\*q"
+Disables accelerated fills of a rectangular region with a full\-color
+pattern.
+.TP 7
+.BI "Option \*qXaaNoColor8x8PatternFillTrap\*q"
+Disables accelerated fills of a trapezoidal region with a full\-color
+pattern.
+.TP 7
+.BI "Option \*qXaaNoDashedBresenhamLine\*q"
+Disables accelerated dashed Bresenham line draws.
+.TP 7
+.BI "Option \*qXaaNoDashedTwoPointLine\*q"
+Disables accelerated dashed line draws between two arbitrary points.
+.TP 7
+.BI "Option \*qXaaNoImageWriteRect\*q"
+Disables accelerated transfers of full\-color rectangular patterns from
+system memory to video memory (using a memory\-mapped aperture).
+.TP 7
+.BI "Option \*qXaaNoMono8x8PatternFillRect\*q"
+Disables accelerated fills of a rectangular region with a monochrome
+pattern.
+.TP 7
+.BI "Option \*qXaaNoMono8x8PatternFillTrap\*q"
+Disables accelerated fills of a trapezoidal region with a monochrome
+pattern.
+.TP 7
+.BI "Option \*qXaaNoOffscreenPixmaps\*q"
+Disables accelerated draws into pixmaps stored in offscreen video memory.
+.TP 7
+.BI "Option \*qXaaNoPixmapCache\*q"
+Disables caching of patterns in offscreen video memory.
+.TP 7
+.BI "Option \*qXaaNoScanlineCPUToScreenColorExpandFill\*q"
+Disables accelerated rectangular expansion blits from source patterns
+stored in system memory (one scan line at a time).
+.TP 7
+.BI "Option \*qXaaNoScanlineImageWriteRect\*q"
+Disables accelerated transfers of full\-color rectangular patterns from
+system memory to video memory (one scan line at a time).
+.TP 7
+.BI "Option \*qXaaNoScreenToScreenColorExpandFill\*q"
+Disables accelerated rectangular expansion blits from source patterns
+stored in offscreen video memory.
+.TP 7
+.BI "Option \*qXaaNoScreenToScreenCopy\*q"
+Disables accelerated copies of rectangular regions from one part of
+video memory to another part of video memory.
+.TP 7
+.BI "Option \*qXaaNoSolidBresenhamLine\*q"
+Disables accelerated solid Bresenham line draws.
+.TP 7
+.BI "Option \*qXaaNoSolidFillRect\*q"
+Disables accelerated solid\-color fills of rectangles.
+.TP 7
+.BI "Option \*qXaaNoSolidFillTrap\*q"
+Disables accelerated solid\-color fills of Bresenham trapezoids.
+.TP 7
+.BI "Option \*qXaaNoSolidHorVertLine\*q"
+Disables accelerated solid horizontal and vertical line draws.
+.TP 7
+.BI "Option \*qXaaNoSolidTwoPointLine\*q"
+Disables accelerated solid line draws between two arbitrary points.
+.PP
+Each
+.B Screen
+section may optionally contain one or more
+.B Display
+subsections.
+Those subsections provide depth/fbbpp specific configuration information,
+and the one chosen depends on the depth and/or fbbpp that is being used for
+the screen.
+The
+.B Display
+subsection format is described in the section below.
+
+.SH "DISPLAY SUBSECTION"
+Each
+.B Screen
+section may have multiple
+.B Display
+subsections.
+The \(lqactive\(rq
+.B Display
+subsection is the first that matches the depth and/or fbbpp values being
+used, or failing that, the first that has neither a depth or fbbpp value
+specified.
+The
+.B Display
+subsections are optional.
+When there isn't one that matches the depth and/or fbbpp values being used,
+all the parameters that can be specified here fall back to their defaults.
+.PP
+.B Display
+subsections have the following format:
+.PP
+.RS 4
+.nf
+.B " SubSection \*qDisplay\*q"
+.BI " Depth " depth
+.I " entries"
+.I " ..."
+.B " EndSubSection"
+.fi
+.RE
+.TP 7
+.BI "Depth " depth
+This entry specifies what colour depth the
+.B Display
+subsection is to be used for.
+This entry is usually specified, but it may be omitted to create a match\-all
+.B Display
+subsection or when wishing to match only against the
+.B FbBpp
+parameter.
+The range of
+.I depth
+values that are allowed depends on the driver.
+Most drivers support 8, 15, 16 and 24.
+Some also support 1 and/or 4, and some may support other values (like 30).
+Note:
+.I depth
+means the number of bits in a pixel that are actually used to determine
+the pixel colour.
+32 is not a valid
+.I depth
+value.
+Most hardware that uses 32 bits per pixel only uses 24 of them to hold the
+colour information, which means that the colour depth is 24, not 32.
+.TP 7
+.BI "FbBpp " bpp
+This entry specifies the framebuffer format this
+.B Display
+subsection is to be used for.
+This entry is only needed when providing depth 24 configurations that allow
+a choice between a 24 bpp packed framebuffer format and a 32bpp sparse
+framebuffer format.
+In most cases this entry should not be used.
+.TP 7
+.BI "Weight " "red\-weight green\-weight blue\-weight"
+This optional entry specifies the relative RGB weighting to be used
+for a screen is being used at depth 16 for drivers that allow multiple
+formats.
+This may also be specified from the command line with the
+.B \-weight
+option (see
+.BR __xservername__(__appmansuffix__)).
+.TP 7
+.BI "Virtual " "xdim ydim"
+This optional entry specifies the virtual screen resolution to be used.
+.I xdim
+must be a multiple of either 8 or 16 for most drivers, and a multiple
+of 32 when running in monochrome mode.
+The given value will be rounded down if this is not the case.
+Video modes which are too large for the specified virtual size will be
+rejected.
+If this entry is not present, the virtual screen resolution will be set to
+accommodate all the valid video modes given in the
+.B Modes
+entry.
+Some drivers/hardware combinations do not support virtual screens.
+Refer to the appropriate driver\-specific documentation for details.
+.TP 7
+.BI "ViewPort " "x0 y0"
+This optional entry sets the upper left corner of the initial display.
+This is only relevant when the virtual screen resolution is different
+from the resolution of the initial video mode.
+If this entry is not given, then the initial display will be centered in
+the virtual display area.
+.TP 7
+.BI "Modes \*q" mode\-name \*q " ..."
+This optional entry specifies the list of video modes to use.
+Each
+.I mode\-name
+specified must be in double quotes.
+They must correspond to those specified or referenced in the appropriate
+.B Monitor
+section (including implicitly referenced built\-in VESA standard modes).
+The server will delete modes from this list which don't satisfy various
+requirements.
+The first valid mode in this list will be the default display mode for
+startup.
+The list of valid modes is converted internally into a circular list.
+It is possible to switch to the next mode with
+.B Ctrl+Alt+Keypad\-Plus
+and to the previous mode with
+.BR Ctrl+Alt+Keypad\-Minus .
+When this entry is omitted, the valid modes referenced by the appropriate
+.B Monitor
+section will be used. If the
+.B Monitor
+section contains no modes, then the selection will be taken from the
+built-in VESA standard modes.
+.TP 7
+.BI "Visual \*q" visual\-name \*q
+This optional entry sets the default root visual type.
+This may also be specified from the command line (see the
+.BR Xserver(__appmansuffix__)
+man page).
+The visual types available for depth 8 are (default is
+.BR PseudoColor ):
+.PP
+.RS 11
+.nf
+.B StaticGray
+.B GrayScale
+.B StaticColor
+.B PseudoColor
+.B TrueColor
+.B DirectColor
+.fi
+.RE
+.PP
+.RS 7
+The visual type available for the depths 15, 16 and 24 are (default is
+.BR TrueColor ):
+.PP
+.RS 4
+.nf
+.B TrueColor
+.B DirectColor
+.fi
+.RE
+.PP
+Not all drivers support
+.B DirectColor
+at these depths.
+.PP
+The visual types available for the depth 4 are (default is
+.BR StaticColor ):
+.PP
+.RS 4
+.nf
+.B StaticGray
+.B GrayScale
+.B StaticColor
+.B PseudoColor
+.fi
+.RE
+.PP
+The visual type available for the depth 1 (monochrome) is
+.BR StaticGray .
+.RE
+.TP 7
+.BI "Black " "red green blue"
+This optional entry allows the \(lqblack\(rq colour to be specified.
+This is only supported at depth 1.
+The default is black.
+.TP 7
+.BI "White " "red green blue"
+This optional entry allows the \(lqwhite\(rq colour to be specified.
+This is only supported at depth 1.
+The default is white.
+.TP 7
+.B Options
+Option flags may be specified in the
+.B Display
+subsections.
+These may include driver\-specific options and driver\-independent options.
+The former are described in the driver\-specific documentation.
+Some of the latter are described above in the section about the
+.B Screen
+section, and they may also be included here.
+.SH "SERVERLAYOUT SECTION"
+The config file may have multiple
+.B ServerLayout
+sections.
+A \(lqserver layout\(rq represents the binding of one or more screens
+.RB ( Screen
+sections) and one or more input devices
+.RB ( InputDevice
+sections) to form a complete configuration.
+In multi\-head configurations, it also specifies the relative layout of the
+heads.
+A
+.B ServerLayout
+section is considered \(lqactive\(rq if it is referenced by the
+.B \-layout
+command line option or by an
+.B "Option \*qDefaultServerLayout\*q"
+entry in the
+.B ServerFlags
+section (the former takes precedence over the latter).
+If those options are not used, the first
+.B ServerLayout
+section found in the config file is considered the active one.
+If no
+.B ServerLayout
+sections are present, the single active screen and two active (core)
+input devices are selected as described in the relevant sections above.
+.PP
+.B ServerLayout
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B "Section \*qServerLayout\*q"
+.BI " Identifier \*q" name \*q
+.BI " Screen \*q" screen\-id \*q
+.I " ..."
+.BI " InputDevice \*q" idev\-id \*q
+.I " ..."
+.I " options"
+.I " ..."
+.B "EndSection"
+.fi
+.RE
+.PP
+Each
+.B ServerLayout
+section must have an
+.B Identifier
+entry and at least one
+.B Screen
+entry.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this server layout.
+The
+.B ServerLayout
+section provides information specific to the whole session, including
+session\-specific
+.BR Options .
+The
+.B ServerFlags
+options (described above) may be specified here, and ones given here
+override those given in the
+.B ServerFlags
+section.
+.PP
+The entries that may be used in this section are described here.
+.TP 7
+.BI "Screen " "screen\-num" " \*qscreen\-id\*q " "position\-information"
+One of these entries must be given for each screen being used in
+a session.
+The
+.I screen\-id
+field is mandatory, and specifies the
+.B Screen
+section being referenced.
+The
+.I screen\-num
+field is optional, and may be used to specify the screen number
+in multi\-head configurations.
+When this field is omitted, the screens will be numbered in the order that
+they are listed in.
+The numbering starts from 0, and must be consecutive.
+The
+.I position\-information
+field describes the way multiple screens are positioned.
+There are a number of different ways that this information can be provided:
+.RS 7
+.TP 4
+.I "x y"
+.TP 4
+.BI "Absolute " "x y"
+These both specify that the upper left corner's coordinates are
+.RI ( x , y ).
+The
+.B Absolute
+keyword is optional.
+Some older versions of XFree86 (4.2 and earlier) don't recognise the
+.B Absolute
+keyword, so it's safest to just specify the coordinates without it.
+.TP 4
+.BI "RightOf \*q" screen\-id \*q
+.TP 4
+.BI "LeftOf \*q" screen\-id \*q
+.TP 4
+.BI "Above \*q" screen\-id \*q
+.TP 4
+.BI "Below \*q" screen\-id \*q
+.TP 4
+.BI "Relative \*q" screen\-id \*q " x y"
+These give the screen's location relative to another screen.
+The first four position the screen immediately to the right, left, above or
+below the other screen.
+When positioning to the right or left, the top edges are aligned.
+When positioning above or below, the left edges are aligned.
+The
+.B Relative
+form specifies the offset of the screen's origin (upper left corner)
+relative to the origin of another screen.
+.RE
+.TP 7
+.BI "InputDevice \*q" idev\-id "\*q \*q" option \*q " ..."
+One of these entries should be given for each input device being used in
+a session.
+Normally at least two are required, one each for the core pointer and
+keyboard devices.
+If either of those is missing, suitable
+.B InputDevice
+entries are searched for using the method described above in the
+.B INPUTDEVICE
+section. The
+.I idev\-id
+field is mandatory, and specifies the name of the
+.B InputDevice
+section being referenced.
+Multiple
+.I option
+fields may be specified, each in double quotes.
+The options permitted here are any that may also be given in the
+.B InputDevice
+sections.
+Normally only session\-specific input device options would be used here.
+The most commonly used options are:
+.PP
+.RS 11
+.nf
+.B \*qCorePointer\*q
+.B \*qCoreKeyboard\*q
+.B \*qSendCoreEvents\*q
+.fi
+.RE
+.PP
+.RS 7
+and the first two should normally be used to indicate the core pointer
+and core keyboard devices respectively.
+.RE
+.TP 7
+.B Options
+In addition to the following, any option permitted in the
+.B ServerFlags
+section may also be specified here.
+When the same option appears in both places, the value given here overrides
+the one given in the
+.B ServerFlags
+section.
+.TP 7
+.BI "Option \*qIsolateDevice\*q \*q" bus\-id \*q
+Restrict device resets to the specified
+.IR bus\-id .
+See the
+.B BusID
+option (described in
+.BR "DEVICE SECTION" ,
+above) for the format of the
+.I bus\-id
+parameter.
+This option overrides
+.BR SingleCard ,
+if specified.
+At present, only PCI devices can be isolated in this manner.
+.TP 7
+.BI "Option \*qSingleCard\*q \*q" boolean \*q
+As
+.BR IsolateDevice ,
+except that the bus ID of the first device in the layout is used.
+.PP
+Here is an example of a
+.B ServerLayout
+section for a dual headed configuration with two mice:
+.PP
+.RS 4
+.nf
+.B "Section \*qServerLayout\*q"
+.B " Identifier \*qLayout 1\*q"
+.B " Screen \*qMGA 1\*q"
+.B " Screen \*qMGA 2\*q RightOf \*qMGA 1\*q"
+.B " InputDevice \*qKeyboard 1\*q \*qCoreKeyboard\*q"
+.B " InputDevice \*qMouse 1\*q \*qCorePointer\*q"
+.B " InputDevice \*qMouse 2\*q \*qSendCoreEvents\*q"
+.B " Option \*qBlankTime\*q \*q5\*q"
+.B "EndSection"
+.fi
+.RE
+.SH "DRI SECTION"
+This optional section is used to provide some information for the
+Direct Rendering Infrastructure.
+Details about the format of this section
+can be found in the README.DRI document, which is also available on-line at
+.IR <http://dri.freedesktop.org/> .
+.SH "VENDOR SECTION"
+The optional
+.B Vendor
+section may be used to provide vendor\-specific configuration information.
+Multiple
+.B Vendor
+sections may be present, and they may contain an
+.B Identifier
+entry and multiple
+.B Option
+flags.
+The data therein is not used in this release.
+.PP
+.SH "SEE ALSO"
+General:
+.BR X (__miscmansuffix__),
+.BR Xserver (__appmansuffix__),
+.BR __xservername__ (__appmansuffix__),
+.BR cvt (__appmansuffix__),
+.BR gtf (__appmansuffix__).
+.PP
+.B "Not all modules or interfaces are available on all platforms."
+.PP
+Display drivers:
+.BR apm (__drivermansuffix__),
+.BR ati (__drivermansuffix__),
+.BR chips (__drivermansuffix__),
+.BR cirrus (__drivermansuffix__),
+.BR cyrix (__drivermansuffix__),
+.BR fbdev (__drivermansuffix__),
+.BR glide (__drivermansuffix__),
+.BR glint (__drivermansuffix__),
+.BR i128 (__drivermansuffix__),
+.BR i740 (__drivermansuffix__),
+.BR imstt (__drivermansuffix__),
+.BR intel (__drivermansuffix__),
+.BR mga (__drivermansuffix__),
+.BR neomagic (__drivermansuffix__),
+.BR nv (__drivermansuffix__),
+.BR openchrome (__drivermansuffix__),
+.BR r128 (__drivermansuffix__),
+.BR radeon (__drivermansuffix__),
+.BR rendition (__drivermansuffix__),
+.BR savage (__drivermansuffix__),
+.BR s3virge (__drivermansuffix__),
+.BR siliconmotion (__drivermansuffix__),
+.BR sis (__drivermansuffix__),
+.BR sisusb (__drivermansuffix__),
+.BR sunbw2 (__drivermansuffix__),
+.BR suncg14 (__drivermansuffix__),
+.BR suncg3 (__drivermansuffix__),
+.BR suncg6 (__drivermansuffix__),
+.BR sunffb (__drivermansuffix__),
+.BR sunleo (__drivermansuffix__),
+.BR suntcx (__drivermansuffix__),
+.BR tdfx (__drivermansuffix__),
+.\" .BR tga (__drivermansuffix__),
+.BR trident (__drivermansuffix__),
+.BR tseng (__drivermansuffix__),
+.BR vesa (__drivermansuffix__),
+.BR vmware (__drivermansuffix__),
+.BR voodoo (__drivermansuffix__),
+.BR wsfb (__drivermansuffix__),
+.BR xgi (__drivermansuffix__),
+.BR xgixp (__drivermansuffix__).
+.PP
+Input drivers:
+.BR acecad (__drivermansuffix__),
+.BR citron (__drivermansuffix__),
+.BR elographics (__drivermansuffix__),
+.BR evdev (__drivermansuffix__),
+.BR fpit (__drivermansuffix__),
+.BR joystick (__drivermansuffix__),
+.BR kbd (__drivermansuffix__),
+.BR mousedrv (__drivermansuffix__),
+.BR mutouch (__drivermansuffix__),
+.BR penmount (__drivermansuffix__),
+.BR synaptics (__drivermansuffix__),
+.BR vmmouse (__drivermansuffix__),
+.BR void (__drivermansuffix__),
+.BR wacom (__drivermansuffix__).
+.PP
+Other modules and interfaces:
+.BR exa (__drivermansuffix__),
+.BR fbdevhw (__drivermansuffix__),
+.\" .BR shadowfb (__drivermansuffix__),
+.BR v4l (__drivermansuffix__).
+.br
+.SH AUTHORS
+This manual page was largely rewritten by David Dawes
+.IR <dawes@xfree86.org> .
diff --git a/xorg-server/hw/xfree86/doc/sgml/DESIGN.sgml b/xorg-server/hw/xfree86/doc/sgml/DESIGN.sgml deleted file mode 100644 index c6fc63edb..000000000 --- a/xorg-server/hw/xfree86/doc/sgml/DESIGN.sgml +++ /dev/null @@ -1,7420 +0,0 @@ -<!DOCTYPE linuxdoc PUBLIC "-//Xorg//DTD linuxdoc//EN" [
- <!ENTITY % defs SYSTEM "X11/defs.ent"> %defs;
- <!-- config file keyword markup -->
- <!ENTITY s.key STARTTAG "bf">
- <!ENTITY e.key ENDTAG "bf">
- <!-- specific config file keywords -->
- <!ENTITY k.device "&s.key;Device&e.key;">
- <!ENTITY k.monitor "&s.key;Monitor&e.key;">
- <!ENTITY k.display "&s.key;Display&e.key;">
- <!ENTITY k.inputdevice "&s.key;InputDevice&e.key;">
- <!ENTITY k.screen "&s.key;Screen&e.key;">
- <!ENTITY k.serverlayout "&s.key;ServerLayout&e.key;">
- <!ENTITY k.driver "&s.key;Driver&e.key;">
- <!ENTITY k.module "&s.key;Module&e.key;">
- <!ENTITY k.identifier "&s.key;Identifier&e.key;">
- <!ENTITY k.serverflags "&s.key;ServerFlags&e.key;">
- <!-- command line markup -->
- <!ENTITY s.cmd STARTTAG "tt">
- <!ENTITY e.cmd ENDTAG "tt">
- <!-- inline code markup -->
- <!ENTITY s.code STARTTAG "tt">
- <!ENTITY e.code ENDTAG "tt">
- <!-- function indent -->
- <!ENTITY f.indent "&nl          ">
-] >
-
-<article>
-
-<title>XFree86 server 4.x Design (DRAFT)
-<author>The XFree86 Project, Inc
-<and>Updates for X11R&relvers; by Jim Gettys
-<date>19 December 2003
-
-
-
-
-
-
-
-<ident>
-$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DESIGN.sgml,v 1.53 2003/08/23 14:10:14 dawes Exp $
-</ident>
-
-
-<p>
-<bf>NOTE</bf>: This is a DRAFT document, and the interfaces described here
-are subject to change without notice.
-
-
-<sect>Preface
-<p>
-
-The broad design principles are:
-<itemize>
- <item>keep it reasonable
- <itemize>
- <item>We cannot rewrite the complete server
- <item>We don't want to re-invent the wheel
- </itemize>
- <item>keep it modular
- <itemize>
- <item>As many things as possible should go into modules
- <item>The basic loader binary should be minimal
- <item>A clean design with well defined layering is important
- <item>DDX specific global variables are a nono
- <item>The structure should be flexible enough to allow
- future extensions
- <item> The structure should minimize duplication of common code
- </itemize>
- <item>keep important features in mind
- <itemize>
- <item>multiple screens, including multiple instances of drivers
- <item>mixing different color depths and visuals on different
- and ideally even on the same screen
- <item>better control of the PCI device used
- <item>better config file parser
- <item>get rid of all VGA compatibility assumptions
- </itemize>
-</itemize>
-
-Unless we find major deficiencies in the DIX layer, we should avoid
-making changes there.
-
-<sect>The xorg.conf File
-<p>
-
-The xorg.conf file format is similar to the old format, with the following
-changes:
-
-<sect1>&k.device; section
-<p>
-
- The &k.device; sections are similar to what they used to be, and
- describe hardware-specific information for a single video card.
- &k.device;
- Some new keywords are added:
-
-
- <descrip>
- <tag>Driver "drivername"</tag>
- Specifies the name of the driver to be used for the card. This
- is mandatory.
- <tag>BusID "busslot"</tag>
- Specifies uniquely the location of the card on the bus. The
- purpose is to identify particular cards in a multi-headed
- configuration. The format of the argument is intentionally
- vague, and may be architecture dependent. For a PCI bus, it
- is something like "bus:slot:func".
- </descrip>
-
- A &k.device; section is considered ``active'' if there is a reference
- to it in an active &k.screen; section.
-
-<sect1>&k.screen; section
-<p>
-
- The &k.screen; sections are similar to what they used to be. They
- no longer have a &k.driver; keyword, but an &k.identifier; keyword
- is added. (The &k.driver; keyword may be accepted in place of the
- &k.identifier; keyword for compatibility purposes.) The identifier
- can be used to identify which screen is to be active when multiple
- &k.screen sections are present. It is possible to specify the active
- screen from the command line. A default is chosen in the absence
- of one being specified. A &k.screen; section is considered ``active''
- if there is a reference to it either from the command line, or from
- an active &k.serverlayout; section.
-
-<sect1>&k.inputdevice; section
-<p>
-
- The &k.inputdevice; section is a new section that describes
- configuration information for input devices. It replaces the old
- &s.key;Keyboard&e.key;, &s.key;Pointer&e.key; and &s.key;XInput&e.key;
- sections. Like the &k.device; section, it has two mandatory keywords:
- &k.identifier; and &k.driver;. For compatibility purposes the old
- &s.key;Keyboard&e.key; and &s.key;Pointer&e.key; sections are
- converted by the parser into &k.inputdevice; sections as follows:
-
- <descrip>
- <tag>&s.key;Keyboard&e.key;</tag>
- &k.identifier; "Implicit Core Keyboard"<newline>
- &k.driver; "keyboard"
- <tag>&s.key;Pointer&e.key;</tag>
- &k.identifier; "Implicit Core Pointer"<newline>
- &k.driver; "mouse"
- </descrip>
-
- An &k.inputdevice; section is considered active if there is a
- reference to it in an active &k.serverlayout; section. An
- &k.inputdevice; section may also be referenced implicitly if there
- is no &k.serverlayout; section, if the &s.cmd;-screen&e.cmd; command
- line options is used, or if the &k.serverlayout; section doesn't
- reference any &k.inputdevice; sections. In this case, the first
- sections with drivers "keyboard" and "mouse" are used as the core
- keyboard and pointer respectively.
-
-<sect1>&k.serverlayout; section
-<p>
-
- The &k.serverlayout; section is a new section that is used to identify
- which &k.screen; sections are to be used in a multi-headed configuration,
- and the relative layout of those screens. It also identifies which
- &k.inputdevice; sections are to be used. Each &k.serverlayout section
- has an identifier, a list of &k.screen; section identifiers, and a list of
- &k.inputdevice; section identifiers. &k.serverflags; options may also be
- included in a &k.serverlayout; section, making it possible to override
- the global values in the &k.serverflags; section.
-
- A &k.serverlayout; section can be made active by being referenced on
- the command line. In the absence of this, a default will be chosen
- (the first one found). The screen names may optionally be followed
- by a number specifying the preferred screen number, and optionally
- by information specifying the physical positioning of the screen,
- either in absolute terms or relative to another screen (or screens).
- When no screen number is specified, they are numbered according to
- the order in which they are listed. The old (now obsolete) method
- of providing the positioning information is to give the names of
- the four adjacent screens. The order of these is top, bottom, left,
- right. Here is an example of a &k.serverlayout; section for two
- screens using the old method, with the second located to the right
- of the first:
-
- <code>
- Section "ServerLayout"
- Identifier "Main Layout"
- Screen 0 "Screen 1" "" "" "" "Screen 2"
- Screen 1 "Screen 2"
- Screen "Screen 3"
- EndSection
- </code>
-
- The preferred way of specifying the layout is to explicitly specify
- the screen's location in absolute terms or relative to another
- screen.
-
- In the absolute case, the upper left corner's coordinates are given
- after the &s.key;Absolute&e.key; keyword. If the coordinates are
- omitted, a value of &s.code;(0,0)&e.code; is assumed. An example
- of absolute positioning follows:
-
- <code>
- Section "ServerLayout"
- Identifier "Main Layout"
- Screen 0 "Screen 1" Absolute 0 0
- Screen 1 "Screen 2" Absolute 1024 0
- Screen "Screen 3" Absolute 2048 0
- EndSection
- </code>
-
- In the relative case, the position is specified by either using one of
- the following keywords followed by the name of the reference screen:
-
- <quote>
- &s.key;RightOf&nl;
- LeftOf&nl;
- Above&nl;
- Below&nl;
- Relative&e.key;
- </quote>
-
- When the &s.key;Relative&e.key; keyword is used, the reference screen
- name is followed by the coordinates of the new screen's origin
- relative to reference screen. The following example shows how to use
- some of the relative positioning options.
-
- <code>
- Section "ServerLayout"
- Identifier "Main Layout"
- Screen 0 "Screen 1"
- Screen 1 "Screen 2" RightOf "Screen 1"
- Screen "Screen 3" Relative "Screen 1" 2048 0
- EndSection
- </code>
-
-<sect1>Options
-<p>
-
- Options are used more extensively. They may appear in most sections
- now. Options related to drivers can be present in the &k.screen;,
- &k.device; and &k.monitor; sections and the &k.display; subsections.
- The order of precedence is &k.display;, &k.screen;, &k.monitor;,
- &k.device;. Options have been extended to allow an optional value
- to be specified in addition to the option name. For more details
- about options, see the <ref id="options" name="Options"> section
- for details.
-
-<sect>Driver Interface
-<p>
-
-The driver interface consists of a minimal set of entry points that are
-required based on the external events that the driver must react to.
-No non-essential structure is imposed on the way they are used beyond
-that. This is a significant difference compared with the old design.
-
-The entry points for drawing operations are already taken care of by
-the framebuffer code (including, XAA). Extensions and enhancements to
-framebuffer code are outside the scope of this document.
-
-This approach to the driver interface provides good flexibility, but does
-increase the complexity of drivers. To help address this, the XFree86
-common layer provides a set of ``helper'' functions to take care of things
-that most drivers need. These helpers help minimise the amount of code
-duplication between drivers. The use of helper functions by drivers is
-however optional, though encouraged. The basic philosophy behind the
-helper functions is that they should be useful to many drivers, that
-they should balance this against the complexity of their interface. It
-is inevitable that some drivers may find some helpers unsuitable and
-need to provide their own code.
-
-Events that a driver needs to react to are:
-
- <descrip>
- <tag>ScreenInit</tag>
-
- An initialisation function is called from the DIX layer for each
- screen at the start of each server generation.
-
- <tag>Enter VT</tag>
-
- The server takes control of the console.
-
- <tag>Leave VT</tag>
-
- The server releases control of the console.
-
- <tag>Mode Switch</tag>
-
- Change video mode.
-
- <tag>ViewPort change</tag>
-
- Change the origin of the physical view port.
-
- <tag>ScreenSaver state change</tag>
-
- Screen saver activation/deactivation.
-
- <tag>CloseScreen</tag>
-
- A close screen function is called from the DIX layer for each screen
- at the end of each server generation.
- </descrip>
-
-
-In addition to these events, the following functions are required by
-the XFree86 common layer:
-
- <descrip>
- <tag>Identify</tag>
-
- Print a driver identifying message.
-
- <tag>Probe</tag>
-
- This is how a driver identifies if there is any hardware present that
- it knows how to drive.
-
- <tag>PreInit</tag>
-
- Process information from the xorg.conf file, determine the
- full characteristics of the hardware, and determine if a valid
- configuration is present.
- </descrip>
-
-The VidMode extension also requires:
-
- <descrip>
- <tag>ValidMode</tag>
-
- Identify if a new mode is usable with the current configuration.
- The PreInit function (and/or helpers it calls) may also make use
- of the ValidMode function or something similar.
- </descrip>
-
-
-Other extensions may require other entry points. The drivers will
-inform the common layer of these in such cases.
-
-<sect>Resource Access Control Introduction
-<p>
-
-Graphics devices are accessed through ranges in I/O or memory space.
-While most modern graphics devices allow relocation of such ranges many
-of them still require the use of well established interfaces such as
-VGA memory and IO ranges or 8514/A IO ranges. With modern buses (like
-PCI) it is possible for multiple video devices to share access to these
-resources. The RAC (Resource Access Control) subsystem provides a
-mechanism for this.
-
-<sect1>Terms and Definitions
-<p>
-
-<sect2>Bus
-<p>
-
- ``Bus'' is ambiguous as it is used for different things: it may refer
- to physical incompatible extension connectors in a computer system.
- The RAC system knows two such systems: The ISA bus and the PCI bus.
- (On the software level EISA, MCA and VL buses are currently treated
- like ISA buses). ``Bus'' may also refer to logically different
- entities on a single bus system which are connected via bridges. A
- PCI system may have several distinct PCI buses connecting each other
- by PCI-PCI bridges or to the host CPU by HOST-PCI bridges.
-
- Systems that host more than one bus system link these together using
- bridges. Bridges are a concern to RAC as they might block or pass
- specific resources. PCI-PCI bridges may be set up to pass VGA
- resources to the secondary bus. PCI-ISA buses pass any resources not
- decoded on the primary PCI bus to the ISA bus. This way VGA resources
- (although exclusive on the ISA bus) can be shared by ISA and PCI
- cards. Currently HOST-PCI bridges are not yet handled by RAC as they
- require specific drivers.
-
-<sect2>Entity
-<p>
-
- The smallest independently addressable unit on a system bus is
- referred to as an entity. So far we know ISA and PCI entities. PCI
- entities can be located on the PCI bus by an unique ID consisting of
- the bus, card and function number.
-
-<sect2>Resource
-<p>
-
- ``Resource'' refers to a range of memory or I/O addresses an entity
- can decode.
-
- If a device is capable of disabling this decoding the resource is
- called sharable. For PCI devices a generic method is provided to
- control resource decoding. Other devices will have to provide a
- device specific function to control decoding.
-
- If the entity is capable of decoding this range at a different
- location this resource is considered relocatable.
-
- Resources which start at a specific address and occupy a single
- continuous range are called block resources.
-
- Alternatively resource addresses can be decoded in a way that they
- satisfy the conditions:
- <quote><verb>
- address & mask == base
- </verb></quote>
- and
- <quote><verb>
- base & mask == base
- </verb></quote>
- Resources addressed in such a way are called sparse resources.
-
-<sect2>Server States
-<p>
-
- The resource access control system knows two server states: the
- SETUP and the OPERATING state. The SETUP state is entered whenever
- a mode change takes place or the server exits or does VT switching.
- During this state all entity resources are under resource access
- control. During OPERATING state only those entities are controlled
- which actually have shared resources that conflict with others.
-
-<sect>Control Flow in the Server and Mandatory Driver Functions
-<p>
-
-At the start of each server generation, &s.code;main()&e.code;
-(&s.code;dix/main.c&e.code;) calls the DDX function
-&s.code;InitOutput()&e.code;. This is the first place that the DDX gets
-control. &s.code;InitOutput()&e.code; is expected to fill in the global
-&s.code;screenInfo&e.code; struct, and one
-&s.code;screenInfo.screen[]&e.code; entry for each screen present. Here
-is what &s.code;InitOutput()&e.code; does:
-
-<sect1>Parse the xorg.conf file
-<p>
-
- This is done at the start of the first server generation only.
-
- The xorg.conf file is read in full, and the resulting information
- stored in data structures. None of the parsed information is
- processed at this point. The parser data structures are opaque to
- the video drivers and to most of the common layer code.
-
- The entire file is parsed first to remove any section ordering
- requirements.
-
-
-<sect1>Initial processing of parsed information and command line options
-<p>
-
- This is done at the start of the first server generation only.
-
- The initial processing is to determine paths like the
- &s.key;ModulePath&e.key;, etc, and to determine which &k.serverlayout;,
- &k.screen; and &k.device; sections are active.
-
-
-<sect1>Enable port I/O access
-<p>
-
- Port I/O access is controlled from the XFree86 common layer, and is
- ``all or nothing''. It is enabled prior to calling driver probes, at
- the start of subsequent server generations, and when VT switching
- back to the Xserver. It is disabled at the end of server generations,
- and when VT switching away from the Xserver.
-
- The implementation details of this may vary on different platforms.
-
-
-<sect1>General bus probe
-<p>
-
- This is done at the start of the first server generation only.
-
- In the case of ix86 machines, this will be a general PCI probe.
- The full information obtained here will be available to the drivers.
- This information persists for the life of the Xserver. In the PCI
- case, the PCI information for all video cards found is available by
- calling &s.code;xf86GetPciVideoInfo()&e.code;.
-
- <quote>
- &s.code;pciVideoPtr *xf86GetPciVideoInfo(void)&e.code;
- <quote><p>
- returns a pointer to a list of pointers to
- &s.code;pciVideoRec&e.code; entries, of which there is one for
- each detected PCI video card. The list is terminated with a
- &s.code;NULL&e.code; pointer. If no PCI video cards were
- detected, the return value is &s.code;NULL&e.code;.
-
- </quote>
- </quote>
-
- After the bus probe, the resource broker is initialised.
-
-
-<sect1>Load initial set of modules
-<p>
-
- This is done at the start of the first server generation only.
-
- The core server contains a list of mandatory modules. These are loaded
- first. Currently the only module on this list is the bitmap font module.
-
- The next set of modules loaded are those specified explicitly in the
- &k.module; section of the config file.
-
- The final set of initial modules are the driver modules referenced
- by the active &k.device; and &k.inputdevice; sections in the config
- file. Each of these modules is loaded exactly once.
-
-
-<sect1>Register Video and Input Drivers
-<p>
-
- This is done at the start of the first server generation only.
-
- When a driver module is loaded, the loader calls its
- &s.code;Setup&e.code; function. For video drivers, this function
- calls &s.code;xf86AddDriver()&e.code; to register the driver's
- &s.code;DriverRec&e.code;, which contains a small set of essential
- details and driver entry points required during the early phase of
- &s.code;InitOutput()&e.code;. &s.code;xf86AddDriver()&e.code; adds
- it to the global &s.code;xf86DriverList[]&e.code; array.
-
- The &s.code;DriverRec&e.code; contains the driver canonical name,
- the &s.code;Identify()&e.code;,
- &s.code;Probe()&e.code; and &s.code;AvailableOptions()&e.code;
- function entry points as well as a pointer
- to the driver's module (as returned from the loader when the driver
- was loaded) and a reference count which keeps track of how many
- screens are using the driver. The entry driver entry points are
- those required prior to the driver allocating and filling in its
- &s.code;ScrnInfoRec&e.code;.
-
- For a static server, the &s.code;xf86DriverList[]&e.code; array is
- initialised at build time, and the loading of modules is not done.
-
- A similar procedure is used for input drivers. The input driver's
- &s.code;Setup&e.code; function calls
- &s.code;xf86AddInputDriver()&e.code; to register the driver's
- &s.code;InputDriverRec&e.code;, which contains a small set of
- essential details and driver entry points required during the early
- phase of &s.code;InitInput()&e.code;.
- &s.code;xf86AddInputDriver()&e.code; adds it to the global
- &s.code;xf86InputDriverList[]&e.code; array. For a static server,
- the &s.code;xf86InputDriverList[]&e.code; array is initialised at
- build time.
-
- Both the &s.code;xf86DriverList[]&e.code; and
- &s.code;xf86InputDriverList[]&e.code; arrays have been initialised
- by the end of this stage.
-
- Once all the drivers are registered, their
- &s.code;ChipIdentify()&e.code; functions are called.
-
- <quote>
- &s.code;void ChipIdentify(int flags)&e.code;
- <quote>
- This is expected to print a message indicating the driver name,
- a short summary of what it supports, and a list of the chipset
- names that it supports. It may use the xf86PrintChipsets() helper
- to do this.
- </quote>
- </quote>
-
- <quote>
- &s.code;void xf86PrintChipsets(const char *drvname, const char *drvmsg,
- &f.indent;SymTabPtr chips)&e.code;
- <quote>
- This function provides an easy way for a driver's ChipIdentify
- function to format the identification message.
- </quote>
- </quote>
-
-<sect1>Initialise Access Control
-<p>
-
- This is done at the start of the first server generation only.
-
- The Resource Access Control (RAC) subsystem is initialised before
- calling any driver functions that may access hardware. All generic
- bus information is probed and saved (for restoration later). All
- (shared resource) video devices are disabled at the generic bus
- level, and a probe is done to find the ``primary'' video device. These
- devices remain disabled for the next step.
-
-
-<sect1>Video Driver Probe<label id="probe">
-<p>
- This is done at the start of the first server generation only. The
- &s.code;ChipProbe()&e.code; function of each registered video driver
- is called.
-
- <quote><p>
- &s.code;Bool ChipProbe(DriverPtr drv, int flags)&e.code;
- <quote><p>
- The purpose of this is to identify all instances of hardware
- supported by the driver. The flags value is currently either 0,
- &s.code;PROBE_DEFAULT&e.code; or &s.code;PROBE_DETECT&e.code;.
- &s.code;PROBE_DETECT&e.code; is used if "-configure" or "-probe"
- command line arguments are given and indicates to the
- &s.code;Probe()&e.code; function that it should not configure the
- bus entities and that no xorg.conf information is available.
-
- The probe must find the active device sections that match the
- driver by calling &s.code;xf86MatchDevice()&e.code;. The number
- of matches found limits the maximum number of instances for this
- driver. If no matches are found, the function should return
- &s.code;FALSE&e.code; immediately.
-
- Devices that cannot be identified by using device-independent
- methods should be probed at this stage (keeping in mind that access
- to all resources that can be disabled in a device-independent way
- are disabled during this phase). The probe must be a minimal
- probe. It should just determine if there is a card present that
- the driver can drive. It should use the least intrusive probe
- methods possible. It must not do anything that is not essential,
- like probing for other details such as the amount of memory
- installed, etc. It is recommended that the
- &s.code;xf86MatchPciInstances()&e.code; helper function be used
- for identifying matching PCI devices, and similarly the
- &s.code;xf86MatchIsaInstances()&e.code; for ISA (non-PCI) devices
- (see the <ref id="rac" name="RAC"> section). These helpers also
- checks and claims the appropriate entity. When not using the
- helper, that should be done with &s.code;xf86CheckPciSlot()&e.code;
- and &s.code;xf86ClaimPciSlot()&e.code; for PCI devices and
- &s.code;xf86ClaimIsaSlot()&e.code; for ISA devices (see the
- <ref id="rac" name="RAC"> section).
-
- The probe must register all non-relocatable resources at this
- stage. If a resource conflict is found between exclusive resources
- the driver will fail immediately. This is usually best done with
- the &s.code;xf86ConfigPciEntity()&e.code; helper function
- for PCI and &s.code;xf86ConfigIsaEntity()&e.code; for ISA
- (see the <ref id="rac" name="RAC"> section). It is possible to
- register some entity specific functions with those helpers. When
- not using the helpers, the &s.code;xf86AddEntityToScreen()&e.code;
- &s.code;xf86ClaimFixedResources()&e.code; and
- &s.code;xf86SetEntityFuncs()&e.code; should be used instead (see
- the <ref id="rac" name="RAC"> section).
-
- If a chipset is specified in an active device section which the
- driver considers relevant (ie it has no driver specified, or the
- driver specified matches the driver doing the probe), the Probe
- must return &s.code;FALSE&e.code; if the chipset doesn't match
- one supported by the driver.
-
- If there are no active device sections that the driver considers
- relevant, it must return &s.code;FALSE&e.code;.
-
- Allocate a &s.code;ScrnInfoRec&e.code; for each active instance of the
- hardware found, and fill in the basic information, including the
- other driver entry points. This is best done with the
- &s.code;xf86ConfigIsaEntity()&e.code; helper function for ISA
- instances or &s.code;xf86ConfigPciEntity()&e.code; for PCI instances.
- These functions allocate a &s.code;ScrnInfoRec&e.code; for active
- entities. Optionally &s.code;xf86AllocateScreen()&e.code;
- function may also be used to allocate the &s.code;ScrnInfoRec&e.code;.
- Any of these functions take care of initialising fields to defined
- ``unused'' values.
-
- Claim the entities for each instance of the hardware found. This
- prevents other drivers from claiming the same hardware.
-
- Must leave hardware in the same state it found it in, and must not
- do any hardware initialisation.
-
- All detection can be overridden via the config file, and that
- parsed information is available to the driver at this stage.
-
- Returns &s.code;TRUE&e.code; if one or more instances are found,
- and &s.code;FALSE&e.code; otherwise.
-
- </quote>
-
- &s.code;int xf86MatchDevice(const char *drivername,
- &f.indent;GDevPtr **driversectlist)&e.code;
- <quote><p>
-
- This function takes the name of the driver and returns via
- &s.code;driversectlist&e.code; a list of device sections that
- match the driver name. The function return value is the number
- of matches found. If a fatal error is encountered the return
- value is &s.code;-1&e.code;.
-
- The caller should use &s.code;xfree()&e.code; to free
- &s.code;*driversectlist&e.code; when it is no longer needed.
-
- </quote>
-
- &s.code;ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags)&e.code;
- <quote><p>
- This function allocates a new &s.code;ScrnInfoRec&e.code; in the
- &s.code;xf86Screens[]&e.code; array. This function is normally
- called by the video driver &s.code;ChipProbe()&e.code; functions.
- The return value is a pointer to the newly allocated
- &s.code;ScrnInfoRec&e.code;. The &s.code;scrnIndex&e.code;,
- &s.code;origIndex&e.code;, &s.code;module&e.code; and
- &s.code;drv&e.code; fields are initialised. The reference count
- in &s.code;drv&e.code; is incremented. The storage for any
- currently allocated ``privates'' pointers is also allocated and
- the &s.code;privates&e.code; field initialised (the privates data
- is of course not allocated or initialised). This function never
- returns on failure. If the allocation fails, the server exits
- with a fatal error. The flags value is not currently used, and
- should be set to zero.
- </quote>
- </quote>
-
- At the completion of this, a list of &s.code;ScrnInfoRecs&e.code;
- have been allocated in the &s.code;xf86Screens[]&e.code; array, and
- the associated entities and fixed resources have been claimed. The
- following &s.code;ScrnInfoRec&e.code; fields must be initialised at
- this point:
-
- <quote><verb>
- driverVersion
- driverName
- scrnIndex(*)
- origIndex(*)
- drv(*)
- module(*)
- name
- Probe
- PreInit
- ScreenInit
- EnterVT
- LeaveVT
- numEntities
- entityList
- access
- </verb></quote>
-
- <tt>(*)</tt> These are initialised when the &s.code;ScrnInfoRec&e.code;
- is allocated, and not explicitly by the driver.
-
- The following &s.code;ScrnInfoRec&e.code; fields must be initialised
- if the driver is going to use them:
-
- <quote><verb>
- SwitchMode
- AdjustFrame
- FreeScreen
- ValidMode
- </verb></quote>
-
-<sect1>Matching Screens
-<p>
-
- This is done at the start of the first server generation only.
-
- After the Probe phase is finished, there will be some number of
- &s.code;ScrnInfoRecs&e.code;. These are then matched with the active
- &k.screen; sections in the xorg.conf, and those not having an active
- &k.screen; section are deleted. If the number of remaining screens
- is 0, &s.code;InitOutput()&e.code; sets
- &s.code;screenInfo.numScreens&e.code; to &s.code;0&e.code; and
- returns.
-
- At this point the following fields of the &s.code;ScrnInfoRecs&e.code;
- must be initialised:
-
- <quote><verb>
- confScreen
- </verb></quote>
-
-
-<sect1>Allocate non-conflicting resources
-<p>
-
- This is done at the start of the first server generation only.
-
- Before calling the drivers again, the resource information collected
- from the Probe phase is processed. This includes checking the extent
- of PCI resources for the probed devices, and resolving any conflicts
- in the relocatable PCI resources. It also reports conflicts, checks
- bus routing issues, and anything else that is needed to enable the
- entities for the next phase.
-
- If any drivers registered an &s.code;EntityInit()&e.code; function
- during the Probe phase, then they are called here.
-
-
-<sect1>Sort the Screens and pre-check Monitor Information
-<p>
-
- This is done at the start of the first server generation only.
-
- The list of screens is sorted to match the ordering requested in the
- config file.
-
- The list of modes for each active monitor is checked against the
- monitor's parameters. Invalid modes are pruned.
-
-
-<sect1>PreInit
-<p>
-
- This is done at the start of the first server generation only.
-
- For each &s.code;ScrnInfoRec&e.code;, enable access to the screens entities and call
- the &s.code;ChipPreInit()&e.code; function.
-
- <quote><p>
- &s.code;Bool ChipPreInit(ScrnInfoRec screen, int flags)&e.code;
- <quote><p>
- The purpose of this function is to find out all the information
- required to determine if the configuration is usable, and to
- initialise those parts of the &s.code;ScrnInfoRec&e.code; that
- can be set once at the beginning of the first server generation.
-
- The number of entities registered for the screen should be checked
- against the expected number (most drivers expect only one). The
- entity information for each of them should be retrieved (with
- &s.code;xf86GetEntityInfo()&e.code;) and checked for the correct
- bus type and that none of the sharable resources registered during
- the Probe phase was rejected.
-
- Access to resources for the entities that can be controlled in a
- device-independent way are enabled before this function is called.
- If the driver needs to access any resources that it has disabled
- in an &s.code;EntityInit()&e.code; function that it registered,
- then it may enable them here providing that it disables them before
- this function returns.
-
- This includes probing for video memory, clocks, ramdac, and all
- other HW info that is needed. It includes determining the
- depth/bpp/visual and related info. It includes validating and
- determining the set of video modes that will be used (and anything
- that is required to determine that).
-
- This information should be determined in the least intrusive way
- possible. The state of the HW must remain unchanged by this
- function. Although video memory (including MMIO) may be mapped
- within this function, it must be unmapped before returning. Driver
- specific information should be stored in a structure hooked into
- the &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code;
- field. Any other modules which require persistent data (ie data
- that persists across server generations) should be initialised in
- this function, and they should allocate a ``privates'' index to
- hook their data into by calling
- &s.code;xf86AllocateScrnInfoPrivateIndex().&e.code; The ``privates''
- data is persistent.
-
- Helper functions for some of these things are provided at the
- XFree86 common level, and the driver can choose to make use of
- them.
-
- All additional resources that the screen needs must be registered
- here. This should be done with
- &s.code;xf86RegisterResources()&e.code;. If some of the fixed
- resources registered in the Probe phase are not needed or not
- decoded by the hardware when in the OPERATING server state, their
- status should be updated with
- &s.code;xf86SetOperatingState()&e.code;.
-
- Modules may be loaded at any point in this function, and all
- modules that the driver will need must be loaded before the end
- of this function. Either the &s.code;xf86LoadSubModule()&e.code;
- or the &s.code;xf86LoadDrvSubModule()&e.code; function should be
- used to load modules depending on whether a
- &s.code;ScrnInfoRec&e.code; has been set up. A driver may unload
- a module within this function if it was only needed temporarily,
- and the &s.code;xf86UnloadSubModule()&e.code; function should be used
- to do that. Otherwise there is no need to explicitly unload modules
- because the loader takes care of module dependencies and will
- unload submodules automatically if/when the driver module is
- unloaded.
-
- The bulk of the &s.code;ScrnInfoRec&e.code; fields should be filled
- out in this function.
-
- &s.code;ChipPreInit()&e.code; returns &s.code;FALSE&e.code; when
- the configuration is unusable in some way (unsupported depth, no
- valid modes, not enough video memory, etc), and &s.code;TRUE&e.code;
- if it is usable.
-
- It is expected that if the &s.code;ChipPreInit()&e.code; function
- returns &s.code;TRUE&e.code;, then the only reasons that subsequent
- stages in the driver might fail are lack or resources (like xalloc
- failures). All other possible reasons for failure should be
- determined by the &s.code;ChipPreInit()&e.code; function.
-
- </quote>
- </quote>
-
- The &s.code;ScrnInfoRecs&e.code; for screens where the &s.code;ChipPreInit()&e.code; fails are removed.
- If none remain, &s.code;InitOutput()&e.code; sets &s.code;screenInfo.numScreens&e.code; to &s.code;0&e.code; and returns.
-
- At this point, further fields of the &s.code;ScrnInfoRecs&e.code; would normally be
- filled in. Most are not strictly mandatory, but many are required
- by other layers and/or helper functions that the driver may choose
- to use. The documentation for those layers and helper functions
- indicates which they require.
-
- The following fields of the &s.code;ScrnInfoRecs&e.code; should be filled in if the
- driver is going to use them:
-
- <quote><verb>
- monitor
- display
- depth
- pixmapBPP
- bitsPerPixel
- weight (>8bpp only)
- mask (>8bpp only)
- offset (>8bpp only)
- rgbBits (8bpp only)
- gamma
- defaultVisual
- maxHValue
- maxVValue
- virtualX
- virtualY
- displayWidth
- frameX0
- frameY0
- frameX1
- frameY1
- zoomLocked
- modePool
- modes
- currentMode
- progClock (TRUE if clock is programmable)
- chipset
- ramdac
- clockchip
- numClocks (if not programmable)
- clock[] (if not programmable)
- videoRam
- biosBase
- memBase
- memClk
- driverPrivate
- chipID
- chipRev
- </verb></quote>
-
- <quote><p>
- &s.code;pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)&e.code:
- and
- &s.code;pointer xf86LoadDrvSubModule(DriverPtr drv, const char *name)&e.code:
- <quote><p>
- Load a module that a driver depends on. This function loads the
- module &s.code;name&e.code; as a sub module of the driver. The
- return value is a handle identifying the new module. If the load
- fails, the return value will be &s.code;NULL&e.code;. If a driver
- needs to explicitly unload a module it has loaded in this way,
- the return value must be saved and passed to
- &s.code;xf86UnloadSubModule()&e.code; when unloading.
-
- </quote>
-
- &s.code;void xf86UnloadSubModule(pointer module)&e.code;
- <quote><p>
- Unloads the module referenced by &s.code;module&e.code;.
- &s.code;module&e.code; should be a pointer returned previously
- by &s.code;xf86LoadSubModule()&e.code; or
- &s.code;xf86LoadDrvSubModule()&e.code; .
-
- </quote>
- </quote>
-
-<sect1>Cleaning up Unused Drivers
-<p>
-
- At this point it is known which screens will be in use, and which
- drivers are being used. Unreferenced drivers (and modules they
- may have loaded) are unloaded here.
-
-
-<sect1>Consistency Checks
-<p>
-
- The parameters that must be global to the server, like pixmap formats,
- bitmap bit order, bitmap scanline unit and image byte order are
- compared for each of the screens. If a mismatch is found, the server
- exits with an appropriate message.
-
-
-<sect1>Check if Resource Control is Needed
-<p>
-
- Determine if resource access control is needed. This is the case
- if more than one screen is used. If necessary the RAC wrapper module
- is loaded.
-
-<sect1>AddScreen (ScreenInit)
-<p>
-
- At this point, the valid screens are known.
- &s.code;AddScreen()&e.code; is called for each of them, passing
- &s.code;ChipScreenInit()&e.code; as the argument.
- &s.code;AddScreen()&e.code; is a DIX function that allocates a new
- &s.code;screenInfo.screen[]&e.code; entry (aka
- &s.code;pScreen&e.code;), and does some basic initialisation of it.
- It then calls the &s.code;ChipScreenInit()&e.code; function, with
- &s.code;pScreen&e.code; as one of its arguments. If
- &s.code;ChipScreenInit()&e.code; returns &s.code;FALSE&e.code;,
- &s.code;AddScreen()&e.code; returns &s.code;-1&e.code;. Otherwise
- it returns the index of the screen. &s.code;AddScreen()&e.code;
- should only fail because of programming errors or failure to allocate
- resources (like memory). All configuration problems should be
- detected BEFORE this point.
-
- <quote><p>
- &s.code;Bool ChipScreenInit(int index, ScreenPtr pScreen,
- &f.indent;int argc, char **argv)&e.code;
- <quote><p>
- This is called at the start of each server generation.
-
- Fill in all of &s.code;pScreen&e.code;, possibly doing some of
- this by calling ScreenInit functions from other layers like mi,
- framebuffers (cfb, etc), and extensions.
-
- Decide which operations need to be placed under resource access
- control. The classes of operations are the frame buffer operations
- (&s.code;RAC_FB&e.code;), the pointer operations
- (&s.code;RAC_CURSOR&e.code;), the viewport change operations
- (&s.code;RAC_VIEWPORT&e.code;) and the colormap operations
- (&s.code;RAC_COLORMAP&e.code;). Any operation that requires
- resources which might be disabled during OPERATING state should
- be set to use RAC. This can be specified separately for memory
- and IO resources (the &s.code;racMemFlags&e.code; and
- &s.code;racIoFlags&e.code; fields of the &s.code;ScrnInfoRec&e.code;
- respectively).
-
- Map any video memory or other memory regions.
-
- Save the video card state. Enough state must be saved so that
- the original state can later be restored.
-
- Initialise the initial video mode. The &s.code;ScrnInfoRec&e.code;'s
- &s.code;vtSema&e.code; field should be set to &s.code;TRUE&e.code;
- just prior to changing the video hardware's state.
-
- </quote>
- </quote>
-
-
- The &s.code;ChipScreenInit()&e.code; function (or functions from other
- layers that it calls) should allocate entries in the
- &s.code;ScreenRec&e.code;'s &s.code;devPrivates&e.code; area by
- calling &s.code;AllocateScreenPrivateIndex()&e.code; if it needs
- per-generation storage. Since the &s.code;ScreenRec&e.code;'s
- &s.code;devPrivates&e.code; information is cleared for each server
- generation, this is the correct place to initialise it.
-
- After &s.code;AddScreen()&e.code; has successfully returned, the
- following &s.code;ScrnInfoRec&e.code; fields are initialised:
-
- <quote><verb>
- pScreen
- racMemFlags
- racIoFlags
- </verb></quote>
-
- The &s.code;ChipScreenInit()&e.code; function should initialise the
- &s.code;CloseScreen&e.code; and &s.code;SaveScreen&e.code; fields
- of &s.code;pScreen&e.code;. The old value of
- &s.code;pScreen->CloseScreen&e.code; should be saved as part of
- the driver's per-screen private data, allowing it to be called from
- &s.code;ChipCloseScreen()&e.code;. This means that the existing
- &s.code;CloseScreen()&e.code; function is wrapped.
-
-<sect1>Finalising RAC Initialisation
-<p>
-
- After all the &s.code;ChipScreenInit()&e.code; functions have been
- called, each screen has registered its RAC requirements. This
- information is used to determine which shared resources are requested
- by more than one driver and set the access functions accordingly.
- This is done following these rules:
-
- <enum>
- <item>The sharable resources registered by each entity are compared.
- If a resource is registered by more than one entity the entity
- will be marked to indicate that it needs to share this resources
- type (IO or MEM).
-
- <item>A resource marked ``disabled'' during OPERATING state will be
- ignored entirely.
-
- <item>A resource marked ``unused'' will only conflict with an overlapping
- resource of an other entity if the second is actually in use
- during OPERATING state.
-
- <item>If an ``unused'' resource was found to conflict but the entity
- does not use any other resource of this type the entire resource
- type will be disabled for that entity.
- </enum>
-
-
-<sect1>Finishing InitOutput()
-<p>
-
- At this point &s.code;InitOutput()&e.code; is finished, and all the
- screens have been setup in their initial video mode.
-
-
-<sect1>Mode Switching
-<p>
-
- When a SwitchMode event is received, &s.code;ChipSwitchMode()&e.code;
- is called (when it exists):
-
- <quote><p>
- &s.code;Bool ChipSwitchMode(int index, DisplayModePtr mode, int flags)&e.code;
- <quote><p>
- Initialises the new mode for the screen identified by
- &s.code;index;&e.code;. The viewport may need to be adjusted
- also.
-
- </quote>
- </quote>
-
-
-<sect1>Changing Viewport
-<p>
-
- When a Change Viewport event is received,
- &s.code;ChipAdjustFrame()&e.code; is called (when it exists):
-
- <quote><p>
- &s.code;void ChipAdjustFrame(int index, int x, int y, int flags)&e.code;
- <quote><p>
- Changes the viewport for the screen identified by
- &s.code;index;&e.code;.
-
- It should be noted that many chipsets impose restrictions on where the
- viewport may be placed in the virtual resolution, either for alignment
- reasons, or to prevent the start of the viewport from being positioned
- within a pixel (as can happen in a 24bpp mode). After calculating the
- value the chipset's panning registers need to be set to for non-DGA
- modes, this function should recalculate the ScrnInfoRec's
- &s.code;frameX0&e.code;, &s.code;frameY0&e.code, &s.code;frameX1&e.code;
- and &s.code;frameY1&e.code; fields to correspond to that value. If
- this is not done, switching to another mode might cause the position
- of a hardware cursor to change.
-
- </quote>
- </quote>
-
-
-<sect1>VT Switching
-<p>
-
- When a VT switch event is received, &s.code;xf86VTSwitch()&e.code;
- is called. &s.code;xf86VTSwitch()&e.code; does the following:
-
- <descrip>
- <tag>On ENTER:</tag>
- <itemize>
- <item>enable port I/O access
-
- <item>save and initialise the bus/resource state
-
- <item>enter the SETUP server state
-
- <item>calls &s.code;ChipEnterVT()&e.code; for each screen
-
- <item>enter the OPERATING server state
-
- <item>validate GCs
-
- <item>Restore fb from saved pixmap for each screen
-
- <item>Enable all input devices
- </itemize>
- <tag>On LEAVE:</tag>
- <itemize>
- <item>Save fb to pixmap for each screen
-
- <item>validate GCs
-
- <item>enter the SETUP server state
-
- <item>calls &s.code;ChipLeaveVT()&e.code; for each screen
-
- <item>disable all input devices
-
- <item>restore bus/resource state
-
- <item>disables port I/O access
- </itemize>
- </descrip>
-
- <quote><p>
- &s.code;Bool ChipEnterVT(int index, int flags)&e.code;
- <quote><p>
- This function should initialise the current video mode and
- initialise the viewport, turn on the HW cursor if appropriate,
- etc.
-
- Should it re-save the video state before initialising the video
- mode?
-
- </quote>
-
- &s.code;void ChipLeaveVT(int index, int flags)&e.code;
- <quote><p>
- This function should restore the saved video state. If
- appropriate it should also turn off the HW cursor, and invalidate
- any pixmap/font caches.
-
- </quote>
-
- Optionally, &s.code;ChipLeaveVT()&e.code; may also unmap memory
- regions. If so, &s.code;ChipEnterVT()&e.code; will need to remap
- them. Additionally, if an aperture used to access video memory is
- unmapped and remapped in this fashion, &s.code;ChipEnterVT()&e.code;
- will also need to notify the framebuffer layers of the aperture's new
- location in virtual memory. This is done with a call to the screen's
- &s.code;ModifyPixmapHeader()&e.code; function, as follows
-
- <quote><p>
- &s.code;(*pScreen->ModifyPixmapHeader)(pScrn->ppix,
- &f.indent;-1, -1, -1, -1, -1, <it>NewApertureAddress</it>);&e.code;
- <quote><p>
- where the &s.code``ppix''&e.code; field in a ScrnInfoRec
- points to the pixmap used by the screen's
- &s.code;SaveRestoreImage()&e.code; function to hold the screen's
- contents while switched out.
-
- </quote>
- </quote>
-
- Currently, aperture remapping, as described here, should not be
- attempted if the driver uses the &s.code;xf8_16bpp&e.code; or
- &s.code;xf8_32bpp&e.code; framebuffer layers. A pending
- restructuring of VT switching will address this restriction in
- the near future.
-
- </quote>
-
- Other layers may wrap the &s.code;ChipEnterVT()&e.code; and
- &s.code;ChipLeaveVT()&e.code; functions if they need to take some
- action when these events are received.
-
-<sect1>End of server generation
-<p>
-
- At the end of each server generation, the DIX layer calls
- &s.code;ChipCloseScreen()&e.code; for each screen:
-
- <quote><p>
- &s.code;Bool ChipCloseScreen(int index, ScreenPtr pScreen)&e.code;
- <quote><p>
- This function should restore the saved video state and unmap the
- memory regions.
-
- It should also free per-screen data structures allocated by the
- driver. Note that the persistent data held in the
- &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field
- should not be freed here because it is needed by subsequent server
- generations.
-
- The &s.code;ScrnInfoRec&e.code;'s &s.code;vtSema&e.code; field
- should be set to &s.code;FALSE&e.code; once the video HW state
- has been restored.
-
- Before freeing the per-screen driver data the saved
- &s.code;CloseScreen&e.code; value should be restored to
- &s.code;pScreen->CloseScreen&e.code;, and that function should
- be called after freeing the data.
-
- </quote>
- </quote>
-
-<sect>Optional Driver Functions
-<p>
-
-The functions outlined here can be called from the XFree86 common layer,
-but their presence is optional.
-
-<sect1>Mode Validation
-<p>
-
- When a mode validation helper supplied by the XFree86-common layer is
- being used, it can be useful to provide a function to check for hw
- specific mode constraints:
-
- <quote><p>
- &s.code;ModeStatus ChipValidMode(int index, DisplayModePtr mode,
- &f.indent;Bool verbose, int flags)&e.code;
- <quote><p>
- Check the passed mode for hw-specific constraints, and return the
- appropriate status value.
-
- </quote>
- </quote>
-
-<p>
-This function may also modify the effective timings and clock of the passed
-mode. These have been stored in the mode's &s.code;Crtc*&e.code; and
-&s.code;SynthClock&e.code; elements, and have already been adjusted for
-interlacing, doublescanning, multiscanning and clock multipliers and dividers.
-The function should not modify any other mode field, unless it wants to modify
-the mode timings reported to the user by &s.code;xf86PrintModes()&e.code;.
-
-<p>
-The function is called once for every mode in the xorg.conf Monitor section
-assigned to the screen, with &s.code;flags&e.code; set to
-&s.code;MODECHECK_INITIAL&e.code;. It is subsequently called for every mode
-in the xorg.conf Display subsection assigned to the screen, with
-&s.code;flags&e.code; set to &s.code;MODECHECK_FINAL&e.code;. In the second
-case, the mode will have successfully passed all other tests. In addition,
-the &s.code;ScrnInfoRec&e.code;'s &s.code;virtualX&e.code;,
-&s.code;virtualY&e.code; and &s.code;displayWidth&e.code; fields will have been
-set as if the mode to be validated were to be the last mode accepted.
-
-<p>
-In effect, calls with MODECHECK_INITIAL are intended for checks that do not
-depend on any mode other than the one being validated, while calls with
-MODECHECK_FINAL are intended for checks that may involve more than one mode.
-
-<sect1>Free screen data
-<p>
-
- When a screen is deleted prior to the completion of the ScreenInit
- phase the &s.code;ChipFreeScreen()&e.code; function is called when defined.
-
- <quote><p>
- &s.code;void ChipFreeScreen(int scrnindex, int flags)&e.code;
- <quote><p>
- Free any driver-allocated data that may have been allocated up to
- and including an unsuccessful &s.code;ChipScreenInit()&e.code;
- call. This would predominantly be data allocated by
- &s.code;ChipPreInit()&e.code; that persists across server
- generations. It would include the &s.code;driverPrivate&e.code;,
- and any ``privates'' entries that modules may have allocated.
-
- </quote>
- </quote>
-
-
-<sect>Recommended driver functions
-<p>
-
-The functions outlined here are for internal use by the driver only.
-They are entirely optional, and are never accessed directly from higher
-layers. The sample function declarations shown here are just examples.
-The interface (if any) used is up to the driver.
-
-<sect1>Save
-<p>
-
- Save the video state. This could be called from &s.code;ChipScreenInit()&e.code; and
- (possibly) &s.code;ChipEnterVT()&e.code;.
-
- <quote><p>
- &s.code;void ChipSave(ScrnInfoPtr pScrn)&e.code;
- <quote><p>
- Saves the current state. This will only be saving pre-server
- states or states before returning to the server. There is only
- one current saved state per screen and it is stored in private
- storage in the screen.
-
- </quote>
- </quote>
-
-<sect1>Restore
-<p>
-
- Restore the original video state. This could be called from the
- &s.code;ChipLeaveVT()&e.code; and &s.code;ChipCloseScreen()&e.code;
- functions.
-
- <quote><p>
- &s.code;void ChipRestore(ScrnInfoPtr pScrn)&e.code;
- <quote><p>
- Restores the saved state from the private storage. Usually only
- used for restoring text modes.
-
- </quote>
- </quote>
-
-
-<sect1>Initialise Mode
-<p>
-
- Initialise a video mode. This could be called from the
- &s.code;ChipScreenInit()&e.code;, &s.code;ChipSwitchMode()&e.code;
- and &s.code;ChipEnterVT()&e.code; functions.
-
- <quote><p>
- &s.code;Bool ChipModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)&e.code;
- <quote><p>
- Programs the hardware for the given video mode.
-
- </quote>
- </quote>
-
-
-<sect>Data and Data Structures
-<p>
-
-<sect1>Command line data
-<p>
-
-Command line options are typically global, and are stored in global
-variables. These variables are read-only and are available to drivers
-via a function call interface. Most of these command line values are
-processed via helper functions to ensure that they are treated consistently
-by all drivers. The other means of access is provided for cases where
-the supplied helper functions might not be appropriate.
-
-Some of them are:
-
-<quote><verb>
- xf86Verbose verbosity level
- xf86Bpp -bpp from the command line
- xf86Depth -depth from the command line
- xf86Weight -weight from the command line
- xf86Gamma -{r,g,b,}gamma from the command line
- xf86FlipPixels -flippixels from the command line
- xf86ProbeOnly -probeonly from the command line
- defaultColorVisualClass -cc from the command line
-</verb></quote>
-
-If we ever do allow for screen-specific command line options, we may
-need to rethink this.
-
-These can be accessed in a read-only manner by drivers with the following
-functions:
-
- <quote><p>
- &s.code;int xf86GetVerbosity()&e.code;
- <quote><p>
- Returns the value of &s.code;xf86Verbose&e.code;.
-
- </quote>
-
- &s.code;int xf86GetDepth()&e.code;
- <quote><p>
- Returns the &s.cmd;-depth&e.cmd; command line setting. If not
- set on the command line, &s.code;-1&e.code; is returned.
-
- </quote>
-
- &s.code;rgb xf86GetWeight()&e.code;
- <quote><p>
- Returns the &s.cmd;-weight&e.cmd; command line setting. If not
- set on the command line, &s.code;{0, 0, 0}&e.code; is returned.
-
- </quote>
-
- &s.code;Gamma xf86GetGamma()&e.code;
- <quote><p>
- Returns the &s.cmd;-gamma&e.cmd; or &s.cmd;-rgamma&e.cmd;,
- &s.cmd;-ggamma&e.cmd;, &s.cmd;-bgamma&e.cmd; command line settings.
- If not set on the command line, &s.code;{0.0, 0.0, 0.0}&e.code;
- is returned.
-
- </quote>
-
- &s.code;Bool xf86GetFlipPixels()&e.code;
- <quote><p>
- Returns &s.code;TRUE&e.code; if &s.cmd;-flippixels&e.cmd; is
- present on the command line, and &s.code;FALSE&e.code; otherwise.
-
- </quote>
-
- &s.code;const char *xf86GetServerName()&e.code;
- <quote><p>
- Returns the name of the X server from the command line.
-
- </quote>
- </quote>
-
-<sect1>Data handling
-<p>
-
-Config file data contains parts that are global, and parts that are
-Screen specific. All of it is parsed into data structures that neither
-the drivers or most other parts of the server need to know about.
-
-The global data is typically not required by drivers, and as such, most
-of it is stored in the private &s.code;xf86InfoRec&e.code;.
-
-The screen-specific data collected from the config file is stored in
-screen, device, display, monitor-specific data structures that are separate
-from the &s.code;ScrnInfoRecs&e.code;, with the appropriate elements/fields
-hooked into the &s.code;ScrnInfoRecs&e.code; as required. The screen
-config data is held in &s.code;confScreenRec&e.code;, device data in
-the &s.code;GDevRec&e.code;, monitor data in the &s.code;MonRec&e.code;,
-and display data in the &s.code;DispRec&e.code;.
-
-The XFree86 common layer's screen specific data (the actual data in use
-for each screen) is held in the &s.code;ScrnInfoRecs&e.code;. As has
-been outlined above, the &s.code;ScrnInfoRecs&e.code; are allocated at probe
-time, and it is the responsibility of the Drivers' &s.code;Probe()&e.code;
-and &s.code;PreInit()&e.code; functions to finish filling them in based
-on both data provided on the command line and data provided from the
-Config file. The precedence for this is:
-
- <quote>
- command line -> config file -> probed/default data
- </quote>
-
-For most things in this category there are helper functions that the
-drivers can use to ensure that the above precedence is consistently
-used.
-
-As well as containing screen-specific data that the XFree86 common layer
-(including essential parts of the server infrastructure as well as helper
-functions) needs to access, it also contains some data that drivers use
-internally. When considering whether to add a new field to the
-&s.code;ScrnInfoRec&e.code;, consider the balance between the convenience
-of things that lots of drivers need and the size/obscurity of the
-&s.code;ScrnInfoRec&e.code;.
-
-Per-screen driver specific data that cannot be accommodated with the
-static &s.code;ScrnInfoRec&e.code; fields is held in a driver-defined
-data structure, a pointer to which is assigned to the
-&s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field. This
-is per-screen data that persists across server generations (as does the
-bulk of the static &s.code;ScrnInfoRec&e.code; data). It would typically
-also include the video card's saved state.
-
-Per-screen data for other modules that the driver uses (for example,
-the XAA module) that is reset for each server generation is hooked into
-the &s.code;ScrnInfoRec&e.code; through it's &s.code;privates&e.code;
-field.
-
-Once it has stabilised, the data structures and variables accessible to
-video drivers will be documented here. In the meantime, those things
-defined in the &s.code;xf86.h&e.code; and &s.code;xf86str.h&e.code;
-files are visible to video drivers. Things defined in
-&s.code;xf86Priv.h&e.code; and &s.code;xf86Privstr.h&e.code; are NOT
-intended to be visible to video drivers, and it is an error for a driver
-to include those files.
-
-
-<sect1>Accessing global data
-<p>
-
-Some other global state information that the drivers may access via
-functions is as follows:
-
- <quote><p>
- &s.code;Bool xf86ServerIsExiting()&e.code;
- <quote><p>
- Returns &s.code;TRUE&e.code; if the server is at the end of a
- generation and is in the process of exiting, and
- &s.code;FALSE&e.code; otherwise.
-
- </quote>
-
- &s.code;Bool xf86ServerIsResetting()&e.code;
- <quote><p>
- Returns &s.code;TRUE&e.code; if the server is at the end of a
- generation and is in the process of resetting, and
- &s.code;FALSE&e.code; otherwise.
-
- </quote>
-
- &s.code;Bool xf86ServerIsInitialising()&e.code;
- <quote><p>
- Returns &s.code;TRUE&e.code; if the server is at the beginning of
- a generation and is in the process of initialising, and
- &s.code;FALSE&e.code; otherwise.
-
- </quote>
-
- &s.code;Bool xf86ServerIsOnlyProbing()&e.code;
- <quote><p>
- Returns &s.code;TRUE&e.code; if the -probeonly command line flag
- was specified, and &s.code;FALSE&e.code; otherwise.
-
- </quote>
-
- &s.code;Bool xf86CaughtSignal()&e.code;
- <quote><p>
- Returns &s.code;TRUE&e.code; if the server has caught a signal,
- and &s.code;FALSE&e.code; otherwise.
-
- </quote>
- </quote>
-
-<sect1>Allocating private data
-<p>
-
-A driver and any module it uses may allocate per-screen private storage
-in either the &s.code;ScreenRec&e.code; (DIX level) or
-&s.code;ScrnInfoRec&e.code; (XFree86 common layer level).
-&s.code;ScreenRec&e.code; storage persists only for a single server
-generation, and &s.code;ScrnInfoRec&e.code; storage persists across
-generations for the lifetime of the server.
-
-The &s.code;ScreenRec&e.code; &s.code;devPrivates&e.code; data must be
-reallocated/initialised at the start of each new generation. This is
-normally done from the &s.code;ChipScreenInit()&e.code; function, and
-Init functions for other modules that it calls. Data allocated in this
-way should be freed by the driver's &s.code;ChipCloseScreen()&e.code;
-functions, and Close functions for other modules that it calls. A new
-&s.code;devPrivates&e.code; entry is allocated by calling the
-&s.code;AllocateScreenPrivateIndex()&e.code; function.
-
- <quote><p>
- &s.code;int AllocateScreenPrivateIndex()&e.code;
- <quote><p>
- This function allocates a new element in the
- &s.code;devPrivates&e.code; field of all currently existing
- &s.code;ScreenRecs&e.code;. The return value is the index of this
- new element in the &s.code;devPrivates&e.code; array. The
- &s.code;devPrivates&e.code; field is of type
- &s.code;DevUnion&e.code;:
-
- <verb>
- typedef union _DevUnion {
- pointer ptr;
- long val;
- unsigned long uval;
- pointer (*fptr)(void);
- } DevUnion;
- </verb>
-
- which allows the element to be used for any of the above types.
- It is commonly used as a pointer to data that the caller allocates
- after the new index has been allocated.
-
- This function will return &s.code;-1&e.code; when there is an
- error allocating the new index.
-
- </quote>
- </quote>
-
-The &s.code;ScrnInfoRec&e.code; &s.code;privates&e.code; data persists
-for the life of the server, so only needs to be allocated once. This
-should be done from the &s.code;ChipPreInit()&e.code; function, and Init
-functions for other modules that it calls. Data allocated in this way
-should be freed by the driver's &s.code;ChipFreeScreen()&e.code; functions,
-and Free functions for other modules that it calls. A new
-&s.code;privates&e.code; entry is allocated by calling the
-&s.code;xf86AllocateScrnInfoPrivateIndex()&e.code; function.
-
-
- <quote><p>
- &s.code;int xf86AllocateScrnInfoPrivateIndex()&e.code;
- <quote><p>
- This function allocates a new element in the &s.code;privates&e.code;
- field of all currently existing &s.code;ScrnInfoRecs&e.code;.
- The return value is the index of this new element in the
- &s.code;privates&e.code; array. The &s.code;privates&e.code;
- field is of type &s.code;DevUnion&e.code;:
-
- <verb>
- typedef union _DevUnion {
- pointer ptr;
- long val;
- unsigned long uval;
- pointer (*fptr)(void);
- } DevUnion;
- </verb>
-
- which allows the element to be used for any of the above types.
- It is commonly used as a pointer to data that the caller allocates
- after the new index has been allocated.
-
- This function will not return when there is an error allocating
- the new index. When there is an error it will cause the server
- to exit with a fatal error. The similar function for allocation
- privates in the &s.code;ScreenRec&e.code;
- (&s.code;AllocateScreenPrivateIndex()&e.code;) differs in this
- respect by returning &s.code;-1&e.code; when the allocation fails.
-
- </quote>
- </quote>
-
-<sect>Keeping Track of Bus Resources<label id="rac">
-<p>
-
-<sect1>Theory of Operation
-<p>
-
-The XFree86 common layer has knowledge of generic access control mechanisms
-for devices on certain bus systems (currently the PCI bus) as well as
-of methods to enable or disable access to the buses itself. Furthermore
-it can access information on resources decoded by these devices and if
-necessary modify it.
-
-When first starting the Xserver collects all this information, saves it
-for restoration, checks it for consistency, and if necessary, corrects
-it. Finally it disables all resources on a generic level prior to
-calling any driver function.
-
-When the &s.code;Probe()&e.code; function of each driver is called the
-device sections are matched against the devices found in the system.
-The driver may probe devices at this stage that cannot be identified by
-using device independent methods. Access to all resources that can be
-controlled in a device independent way is disabled. The
-&s.code;Probe()&e.code; function should register all non-relocatable
-resources at this stage. If a resource conflict is found between
-exclusive resources the driver will fail immediately. Optionally the
-driver might specify an &s.code;EntityInit()&e.code;,
-&s.code;EntityLeave()&e.code; and &s.code;EntityEnter()&e.code; function.
-
-&s.code;EntityInit()&e.code; can be used to disable any shared resources
-that are not controlled by the generic access control functions. It is
-called prior to the PreInit phase regardless if an entity is active or
-not. When calling the &s.code;EntityInit()&e.code;,
-&s.code;EntityEnter()&e.code; and &s.code;EntityLeave()&e.code; functions
-the common level will disable access to all other entities on a generic
-level. Since the common level has no knowledge of device specific
-methods to disable access to resources it cannot be guaranteed that
-certain resources are not decoded by any other entity until the
-&s.code;EntityInit()&e.code; or &s.code;EntityEnter()&e.code; phase is
-finished. Device drivers should therefore register all those resources
-which they are going to disable. If these resources are never to be
-used by any driver function they may be flagged &s.code;ResInit&e.code;
-so that they can be removed from the resource list after processing all
-&s.code;EntityInit()&e.code; functions. &s.code;EntityEnter()&e.code;
-should disable decoding of all resources which are not registered as
-exclusive and which are not handled by the generic access control in
-the common level. The difference to &s.code;EntityInit()&e.code; is
-that the latter one is only called once during lifetime of the server.
-It can therefore be used to set up variables prior to disabling resources.
-&s.code;EntityLeave()&e.code; should restore the original state when
-exiting the server or switching to a different VT. It also needs to
-disable device specific access functions if they need to be disabled on
-server exit or VT switch. The default state is to enable them before
-giving up the VT.
-
-In &s.code;PreInit()&e.code; phase each driver should check if any
-sharable resources it has registered during &s.code;Probe()&e.code; has
-been denied and take appropriate action which could simply be to fail.
-If it needs to access resources it has disabled during
-&s.code;EntitySetup()&e.code; it can do so provided it has registered
-these and will disable them before returning from
-&s.code;PreInit()&e.code;. This also applies to all other driver
-functions. Several functions are provided to request resource ranges,
-register these, correct PCI config space and add replacements for the
-generic access functions. Resources may be marked ``disabled'' or
-``unused'' during OPERATING stage. Although these steps could also be
-performed in &s.code;ScreenInit()&e.code;, this is not desirable.
-
-Following &s.code;PreInit()&e.code; phase the common level determines
-if resource access control is needed. This is the case if more than
-one screen is used. If necessary the RAC wrapper module is loaded. In
-&s.code;ScreenInit()&e.code; the drivers can decide which operations
-need to be placed under RAC. Available are the frame buffer operations,
-the pointer operations and the colormap operations. Any operation that
-requires resources which might be disabled during OPERATING state should
-be set to use RAC. This can be specified separately for memory and IO
-resources.
-
-When &s.code;ScreenInit()&e.code; phase is done the common level will
-determine which shared resources are requested by more than one driver
-and set the access functions accordingly. This is done following these
-rules:
-
-<enum>
-<item>The sharable resources registered by each entity are compared. If
- a resource is registered by more than one entity the entity will be
- marked to need to share this resources type (&s.code;IO&e.code; or
- &s.code;MEM&e.code;).
-
-<item>A resource marked ``disabled'' during OPERATING state will be ignored
- entirely.
-
-<item>A resource marked ``unused'' will only conflicts with an overlapping
- resource of an other entity if the second is actually in use during
- OPERATING state.
-
-<item>If an ``unused'' resource was found to conflict however the entity
- does not use any other resource of this type the entire resource type
- will be disabled for that entity.
-</enum>
-
-The driver has the choice among different ways to control access to
-certain resources:
-
-<enum>
-<item>It can rely on the generic access functions. This is probably the
- most common case. Here the driver only needs to register any resource
- it is going to use.
-
-<item>It can replace the generic access functions by driver specific
- ones. This will mostly be used in cases where no generic access
- functions are available. In this case the driver has to make sure
- these resources are disabled when entering the &s.code;PreInit()&e.code;
- stage. Since the replacement functions are registered in
- &s.code;PreInit()&e.code; the driver will have to enable these
- resources itself if it needs to access them during this state. The
- driver can specify if the replacement functions can control memory
- and/or I/O resources separately.
-
-<item>The driver can enable resources itself when it needs them. Each
- driver function enabling them needs to disable them before it will
- return. This should be used if a resource which can be controlled
- in a device dependent way is only required during SETUP state. This
- way it can be marked ``unused'' during OPERATING state.
-</enum>
-
-A resource which is decoded during OPERATING state however never accessed
-by the driver should be marked unused.
-
-Since access switching latencies are an issue during Xserver operation,
-the common level attempts to minimize the number of entities that need
-to be placed under RAC control. When a wrapped operation is called,
-the &s.code;EnableAccess()&e.code; function is called before control is
-passed on. &s.code;EnableAccess()&e.code; checks if a screen is under
-access control. If not it just establishes bus routing and returns.
-If the screen needs to be under access control,
-&s.code;EnableAccess()&e.code; determines which resource types
-(&s.code;MEM&e.code;, &s.code;IO&e.code;) are required. Then it tests
-if this access is already established. If so it simply returns. If
-not it disables the currently established access, fixes bus routing and
-enables access to all entities registered for this screen.
-
-Whenever a mode switch or a VT-switch is performed the common level will
-return to SETUP state.
-
-<sect1>Resource Types
-<p>
-
-Resource have certain properties. When registering resources each range
-is accompanied by a flag consisting of the ORed flags of the different
-properties the resource has. Each resource range may be classified
-according to
-
-<itemize>
- <item>its physical properties i.e., if it addresses
- memory (&s.code;ResMem&e.code;) or
- I/O space (&s.code;ResIo&e.code;),
- <item>if it addresses a
- block (&s.code;ResBlock&e.code;) or
- sparse (&s.code;ResSparse&e.code;)
- range,
- <item>its access properties.
-</itemize>
-
-There are two known access properties:
-
-<itemize>
- <item>&s.code;ResExclusive&e.code;
- for resources which may not be shared with any other device and
- <item>&s.code;ResShared&e.code;
- for resources which can be disabled and therefore can be shared.
-</itemize>
-
-If it is necessary to test a resource against any type a generic access
-type &s.code;ResAny&e.code; is provided. If this is set the resource
-will conflict with any resource of a different entity intersecting its
-range. Further it can be specified that a resource is decoded however
-never used during any stage (&s.code;ResUnused&e.code;) or during
-OPERATING state (&s.code;ResUnusedOpr&e.code;). A resource only visible
-during the init functions (ie. &s.code;EntityInit()&e.code;,
-&s.code;EntityEnter()&e.code; and &s.code;EntityLeave()&e.code; should
-be registered with the flag &s.code;ResInit&e.code;. A resource that
-might conflict with background resource ranges may be flagged with
-&s.code;ResBios&e.code;. This might be useful when registering resources
-ranges that were assigned by the system Bios.
-
-Several predefined resource lists are available for VGA and 8514/A
-resources in &s.code;common/xf86Resources.h&e.code;.
-
-<sect1>Available Functions<label id="avail">
-<p>
-
-The functions provided for resource management are listed in their order
-of use in the driver.
-
-
-<sect2>Probe Phase
-<p>
-
-In this phase each driver detects those resources it is able to drive,
-creates an entity record for each of them, registers non-relocatable
-resources and allocates screens and adds the resources to screens.
-
-Two helper functions are provided for matching device sections in the
-xorg.conf file to the devices:
-
- <quote><p>
- &s.code;int xf86MatchPciInstances(const char *driverName, int vendorID,
- &f.indent;SymTabPtr chipsets, PciChipsets *PCIchipsets,
- &f.indent;GDevPtr *devList, int numDevs, DriverPtr drvp,
- &f.indent;int **foundEntities)&e.code;
- <quote><p>
- This function finds matches between PCI cards that a driver supports
- and config file device sections. It is intended for use in the
- &s.code;ChipProbe()&e.code; function of drivers for PCI cards.
- Only probed PCI devices with a vendor ID matching
- &s.code;vendorID&e.code; are considered. &s.code;devList&e.code;
- and &s.code;numDevs&e.code; are typically those found from
- calling &s.code;xf86MatchDevice()&e.code;, and represent the active
- config file device sections relevant to the driver.
- &s.code;PCIchipsets&e.code; is a table that provides a mapping
- between the PCI device IDs, the driver's internal chipset tokens
- and a list of fixed resources.
-
- When a device section doesn't have a &s.key;BusID&e.key; entry it
- can only match the primary video device. Secondary devices are
- only matched with device sections that have a matching
- &s.key;BusID&e.key; entry.
-
- Once the preliminary matches have been found, a final match is
- confirmed by checking if the chipset override, ChipID override or
- probed PCI chipset type match one of those given in the
- &s.code;chipsets&e.code; and &s.code;PCIchipsets&e.code; lists.
- The &s.code;PCIchipsets&e.code; list includes a list of the PCI
- device IDs supported by the driver. The list should be terminated
- with an entry with PCI ID &s.code;-1&e.code;". The
- &s.code;chipsets&e.code; list is a table mapping the driver's
- internal chipset tokens to names, and should be terminated with
- a &s.code;NULL&e.code; entry. Only those entries with a
- corresponding entry in the &s.code;PCIchipsets&e.code; list are
- considered. The order of precedence is: config file chipset,
- config file ChipID, probed PCI device ID.
-
- In cases where a driver handles PCI chipsets with more than one
- vendor ID, it may set &s.code;vendorID&e.code; to
- &s.code;0&e.code;, and OR each devID in the list with (the
- vendor ID << 16).
-
- Entity index numbers for confirmed matches are returned as an
- array via &s.code;foundEntities&e.code;. The PCI information,
- chipset token and device section for each match are found in the
- &s.code;EntityInfoRec&e.code; referenced by the indices.
-
- The function return value is the number of confirmed matches. A
- return value of &s.code;-1&e.code; indicates an internal error.
- The returned &s.code;foundEntities&e.code; array should be freed
- by the driver with &s.code;xfree()&e.code; when it is no longer
- needed in cases where the return value is greater than zero.
-
- </quote>
-
- &s.code;int xf86MatchIsaInstances(const char *driverName,
- &f.indent;SymTabPtr chipsets, IsaChipsets *ISAchipsets,
- &f.indent;DriverPtr drvp, FindIsaDevProc FindIsaDevice,
- &f.indent;GDevPtr *devList, int numDevs,
- int **foundEntities)&e.code;
- <quote><p>
- This function finds matches between ISA cards that a driver supports
- and config file device sections. It is intended for use in the
- &s.code;ChipProbe()&e.code; function of drivers for ISA cards.
- &s.code;devList&e.code; and &s.code;numDevs&e.code; are
- typically those found from calling &s.code;xf86MatchDevice()&e.code;,
- and represent the active config file device sections relevant to
- the driver. &s.code;ISAchipsets&e.code; is a table that provides
- a mapping between the driver's internal chipset tokens and the
- resource classes. &s.code;FindIsaDevice&e.code; is a
- driver-provided function that probes the hardware and returns the
- chipset token corresponding to what was detected, and
- &s.code;-1&e.code; if nothing was detected.
-
- If the config file device section contains a chipset entry, then
- it is checked against the &s.code;chipsets&e.code; list. When
- no chipset entry is present, the &s.code;FindIsaDevice&e.code;
- function is called instead.
-
- Entity index numbers for confirmed matches are returned as an
- array via &s.code;foundEntities&e.code;. The chipset token and
- device section for each match are found in the
- &s.code;EntityInfoRec&e.code; referenced by the indices.
-
- The function return value is the number of confirmed matches. A
- return value of &s.code;-1&e.code; indicates an internal error.
- The returned &s.code;foundEntities&e.code; array should be freed
- by the driver with &s.code;xfree()&e.code; when it is no longer
- needed in cases where the return value is greater than zero.
-
- </quote>
- </quote>
-
-These two helper functions make use of several core functions that are
-available at the driver level:
-
- <quote><p>
- &s.code;Bool xf86ParsePciBusString(const char *busID, int *bus,
- &f.indent;int *device, int *func)&e.code;
- <quote><p>
- Takes a &s.code;BusID&e.code; string, and if it is in the correct
- format, returns the PCI &s.code;bus&e.code;, &s.code;device&e.code;,
- &s.code;func&e.code; values that it indicates. The format of the
- string is expected to be "PCI:bus:device:func" where each of `bus',
- `device' and `func' are decimal integers. The ":func" part may
- be omitted, and the func value assumed to be zero, but this isn't
- encouraged. The "PCI" prefix may also be omitted. The prefix
- "AGP" is currently equivalent to the "PCI" prefix. If the string
- isn't a valid PCI BusID, the return value is &s.code;FALSE&e.code;.
-
- </quote>
-
-
- &s.code;Bool xf86ComparePciBusString(const char *busID, int bus,
- &f.indent;int device, int func)&e.code;
- <quote><p>
- Compares a &s.code;BusID&e.code; string with PCI &s.code;bus&e.code;,
- &s.code;device&e.code;, &s.code;func&e.code; values. If they
- match &s.code;TRUE&e.code; is returned, and &s.code;FALSE&e.code;
- if they don't.
-
- </quote>
-
- &s.code;Bool xf86ParseIsaBusString(const char *busID)&e.code;
- <quote><p>
- Compares a &s.code;BusID&e.code; string with the ISA bus ID string
- ("ISA" or "ISA:"). If they match &s.code;TRUE&e.code; is returned,
- and &s.code;FALSE&e.code; if they don't.
-
- </quote>
-
- &s.code;Bool xf86CheckPciSlot(int bus, int device, int func)&e.code;
- <quote><p>
- Checks if the PCI slot &s.code;bus:device:func&e.code; has been
- claimed. If so, it returns &s.code;FALSE&e.code;, and otherwise
- &s.code;TRUE&e.code;.
-
- </quote>
-
- &s.code;int xf86ClaimPciSlot(int bus, int device, int func, DriverPtr drvp,
- &f.indent;int chipset, GDevPtr dev, Bool active)&e.code;
- <quote><p>
- This function is used to claim a PCI slot, allocate the associated
- entity record and initialise their data structures. The return
- value is the index of the newly allocated entity record, or
- &s.code;-1&e.code; if the claim fails. This function should always
- succeed if &s.code;xf86CheckPciSlot()&e.code; returned
- &s.code;TRUE&e.code; for the same PCI slot.
-
- </quote>
-
- &s.code;Bool xf86IsPrimaryPci(void)&e.code;
- <quote><p>
- This function returns &s.code;TRUE&e.code; if the primary card is
- a PCI device, and &s.code;FALSE&e.code; otherwise.
-
- </quote>
-
- &s.code;int xf86ClaimIsaSlot(DriverPtr drvp, int chipset,
- &f.indent;GDevPtr dev, Bool active)&e.code;
- <quote><p>
- This allocates an entity record entity and initialise the data
- structures. The return value is the index of the newly allocated
- entity record.
-
- </quote>
-
- &s.code;Bool xf86IsPrimaryIsa(void)&e.code;
- <quote><p>
- This function returns &s.code;TRUE&e.code; if the primary card is
- an ISA (non-PCI) device, and &s.code;FALSE&e.code; otherwise.
-
- </quote>
- </quote>
-
-Two helper functions are provided to aid configuring entities:
- <quote><p>
- &s.code;ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn,
- &f.indent;int scrnFlag, int entityIndex,
- &f.indent;PciChipsets *p_chip,
- &f.indent;resList res, EntityProc init,
- &f.indent;EntityProc enter, EntityProc leave,
- &f.indent;pointer private)&e.code;
- <p>
- &s.code;ScrnInfoPtr xf86ConfigIsaEntity(ScrnInfoPtr pScrn,
- &f.indent;int scrnFlag, int entityIndex,
- &f.indent;IsaChipsets *i_chip,
- &f.indent;resList res, EntityProc init,
- &f.indent;EntityProc enter, EntityProc leave,
- &f.indent;pointer private)&e.code;
- <quote><p>
- These functions are used to register the non-relocatable resources
- for an entity, and the optional entity-specific &s.code;Init&e.code;, &s.code;Enter&e.code; and
- &s.code;Leave&e.code; functions. Usually the list of fixed resources is obtained
- from the Isa/PciChipsets lists. However an additional list of
- resources may be passed. Generally this is not required.
- For active entities a &s.code;ScrnInfoRec&e.code; is allocated
- if the &s.code;pScrn&e.code; argument is &s.code;NULL&e.code;.
-The
- return value is &s.code;TRUE&e.code; when successful. The init, enter, leave
- functions are defined as follows:
-
- <quote>
- &s.code;typedef void (*EntityProc)(int entityIndex,
- &f.indent;pointer private)&e.code;
- </quote>
-
- They are passed the entity index and a pointer to a private scratch
- area. This can be set up during &s.code;Probe()&e.code; and
- its address can be passed to
- &s.code;xf86ConfigIsaEntity()&e.code; and
- &s.code;xf86ConfigPciEntity()&e.code; as the last argument.
-
- </quote>
- </quote>
-
-These two helper functions make use of several core functions that are
-available at the driver level:
- <quote><p>
- &s.code;void xf86ClaimFixedResources(resList list, int entityIndex)&e.code;
- <quote><p>
- This function registers the non-relocatable resources which cannot
- be disabled and which therefore would cause the server to fail
- immediately if they were found to conflict. It also records
- non-relocatable but sharable resources for processing after the
- &s.code;Probe()&e.code; phase.
-
- </quote>
-
- &s.code;Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
- &f.indent;EntityProc enter, EntityProc leave, pointer)&e.code;
- <quote><p>
- This function registers with an entity the &s.code;init&e.code;,
- &s.code;enter&e.code;, &s.code;leave&e.code; functions along
- with the pointer to their private area.
-
- </quote>
-
- &s.code;void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)&e.code;
- <quote><p>
- This function associates the entity referenced by
- &s.code;entityIndex&e.code; with the screen.
-
- </quote>
- </quote>
-
-<sect2>PreInit Phase
-<p>
-
-During this phase the remaining resources should be registered.
-&s.code;PreInit()&e.code; should call &s.code;xf86GetEntityInfo()&e.code;
-to obtain a pointer to an &s.code;EntityInfoRec&e.code; for each entity
-it is able to drive and check if any resource are listed in its
-&s.code;resources&e.code; field. If resources registered in the Probe
-phase have been rejected in the post-Probe phase
-(&s.code;resources&e.code; is non-&s.code;NULL&e.code;), then the driver should
-decide if it can continue without using these or if it should fail.
-
- <quote><p>
- &s.code;EntityInfoPtr xf86GetEntityInfo(int entityIndex)&e.code;
- <quote><p>
- This function returns a pointer to the &s.code;EntityInfoRec&e.code;
- referenced by &s.code;entityIndex&e.code;. The returned
- &s.code;EntityInfoRec&e.code; should be freed with
- &s.code;xfree()&e.code; when no longer needed.
-
- </quote>
- </quote>
-Several functions are provided to simplify resource registration:
- <quote><p>
- &s.code;Bool xf86IsEntityPrimary(int entityIndex)&e.code;
- <quote><p>
- This function returns &s.code;TRUE&e.code; if the entity referenced
- by &s.code;entityIndex&e.code; is the primary display device (i.e.,
- the one initialised at boot time and used in text mode).
-
- </quote>
-
- &s.code;Bool xf86IsScreenPrimary(int scrnIndex)&e.code;
- <quote><p>
- This function returns &s.code;TRUE&e.code; if the primary entity
- is registered with the screen referenced by
- &s.code;scrnIndex&e.code;.
-
- </quote>
-
- &s.code;pciVideoPtr xf86GetPciInfoForEntity(int entityIndex)&e.code;
- <quote><p>
- This function returns a pointer to the &s.code;pciVideoRec&e.code;
- for the specified entity. If the entity is not a PCI device,
- &s.code;NULL&e.code; is returned.
-
- </quote>
- </quote>
-
-The primary function for registration of resources is:
- <quote><p>
- &s.code;resPtr xf86RegisterResources(int entityIndex, resList list,
- &f.indent;int access)&e.code;
- <quote><p>
- This function tries to register the resources in
- &s.code;list&e.code;. If list is &s.code;NULL&e.code; it tries
- to determine the resources automatically. This only works for
- entities that provide a generic way to read out the resource ranges
- they decode. So far this is only the case for PCI devices. By
- default the PCI resources are registered as shared
- (&s.code;ResShared&e.code;) if the driver wants to set a different
- access type it can do so by specifying the access flags in the
- third argument. A value of &s.code;0&e.code; means to use the
- default settings. If for any reason the resource broker is not
- able to register some of the requested resources the function will
- return a pointer to a list of the failed ones. In this case the
- driver may be able to move the resource to different locations.
- In case of PCI bus entities this is done by passing the list of
- failed resources to &s.code;xf86ReallocatePciResources()&e.code;.
- When the registration succeeds, the return value is
- &s.code;NULL&e.code;.
-
- </quote>
-
- &s.code;resPtr xf86ReallocatePciResources(int entityIndex, resPtr pRes)&e.code;
- <quote><p>
- This function takes a list of PCI resources that need to be
- reallocated and returns &s.code;NULL&e.code when all relocations are
- successful.
- &s.code;xf86RegisterResources()&e.code; should be called again to
- register the relocated resources with the broker.
- If the reallocation fails, a list of the resources that could not be
- relocated is returned.
-
- </quote>
- </quote>
-
-Two functions are provided to obtain a resource range of a given type:
- <quote><p>
- &s.code;resRange xf86GetBlock(long type, memType size,
- &f.indent;memType window_start, memType window_end,
- &f.indent;memType align_mask, resPtr avoid)&e.code;
- <quote><p>
- This function tries to find a block range of size
- &s.code;size&e.code; and type &s.code;type&e.code; in a window
- bound by &s.code;window_start&e.code; and &s.code;window_end&e.code;
- with the alignment specified in &s.code;align_mask&e.code;.
- Optionally a list of resource ranges which should be avoided within
- the window can be supplied. On failure a zero-length range of
- type &s.code;ResEnd&e.code; will be returned.
-
- </quote>
- &s.code;resRange xf86GetSparse(long type, memType fixed_bits,
- &f.indent;memType decode_mask, memType address_mask,
- &f.indent;resPtr avoid)&e.code;
- <quote><p>
- This function is like the previous one, but attempts to find a
- sparse range instead of a block range. Here three values have to
- be specified: the &s.code;address_mask&e.code; which marks all
- bits of the mask part of the address, the &s.code;decode_mask&e.code;
- which masks out the bits which are hardcoded and are therefore
- not available for relocation and the values of the fixed bits.
- The function tries to find a base that satisfies the given condition.
- If the function fails it will return a zero range of type
- &s.code;ResEnd&e.code;. Optionally it might be passed a list of
- resource ranges to avoid.
-
- </quote>
- </quote>
-
-Some PCI devices are broken in the sense that they return invalid size
-information for a certain resource. In this case the driver can supply
-the correct size and make sure that the resource range allocated for
-the card is large enough to hold the address range decoded by the card.
-The function &s.code;xf86FixPciResource()&e.code; can be used to do this:
- <quote><p>
- &s.code;Bool xf86FixPciResource(int entityIndex, unsigned int prt,
- &f.indent;CARD32 alignment, long type)&e.code;
- <quote><p>
- This function fixes a PCI resource allocation. The
- &s.code;prt&e.code; parameter contains the number of the PCI base
- register that needs to be fixed (&s.code;0-5&e.code;, and
- &s.code;6&e.code; for the BIOS base register). The size is
- specified by the alignment. Since PCI resources need to span an
- integral range of size &s.code;2^n&e.code;, the alignment also
- specifies the number of addresses that will be decoded. If the
- driver specifies a type mask it can override the default type for
- PCI resources which is &s.code;ResShared&e.code;. The resource
- broker needs to know that to find a matching resource range. This
- function should be called before calling
- &s.code;xf86RegisterResources()&e.code;. The return value is
- &s.code;TRUE&e.code; when the function succeeds.
-
- </quote>
-
- &s.code;Bool xf86CheckPciMemBase(pciVideoPtr pPci, memType base)&e.code;
- <quote><p>
- This function checks that the memory base address specified matches
- one of the PCI base address register values for the given PCI
- device. This is mostly used to check that an externally provided
- base address (e.g., from a config file) matches an actual value
- allocated to a device.
-
- </quote>
- </quote>
-
-The driver may replace the generic access control functions for an entity.
-This is done with the &s.code;xf86SetAccessFuncs()&e.code;:
- <quote><p>
- &s.code;void xf86SetAccessFuncs(EntityInfoPtr pEnt,
- &f.indent;xf86SetAccessFuncPtr funcs,
- &f.indent;xf86SetAccessFuncPtr oldFuncs)&e.code;
- <quote><p>
- with:
- </quote>
-
- <verb>
- typedef struct {
- xf86AccessPtr mem;
- xf86AccessPtr io;
- xf86AccessPtr io_mem;
- } xf86SetAccessFuncRec, *xf86SetAccessFuncPtr;
- </verb>
-
- <quote><p>
- The driver can pass three functions: one for I/O access, one for
- memory access and one for combined memory and I/O access. If the
- memory access and combined access functions are identical the
- common level assumes that the memory access cannot be controlled
- independently of I/O access, if the I/O access function and the
- combined access functions are the same it is assumed that I/O can
- not be controlled independently. If memory and I/O have to be
- controlled together all three values should be the same. If a
- non &s.code;NULL&e.code; value is passed as third argument it is
- interpreted as an address where to store the old access record.
- If the third argument is &s.code;NULL&e.code; it will be assumed
- that the generic access should be enabled before replacing the
- access functions. Otherwise it will be disabled. The driver may
- enable them itself using the returned values. It should do this
- from its replacement access functions as the generic access may
- be disabled by the common level on certain occasions. If replacement
- functions are specified they must control all resources of the
- specific type registered for the entity.
-
- </quote>
- </quote>
-
-To find out if a specific resource range conflicts with another
-resource the &s.code;xf86ChkConflict()&e.code; function may be used:
- <quote><p>
- &s.code;memType xf86ChkConflict(resRange *rgp, int entityIndex)&e.code;
- <quote><p>
- This function checks if the resource range &s.code;rgp&e.code; of
- for the specified entity conflicts with with another resource.
- If a conflict is found, the address of the start of the conflict
- is returned. The return value is zero when there is no conflict.
-
- </quote>
- </quote>
-
-The OPERATING state properties of previously registered fixed resources
-can be set with the &s.code;xf86SetOperatingState()&e.code; function:
- <quote><p>
- &s.code;resPtr xf86SetOperatingState(resList list, int entityIndex,
- &f.indent;int mask)&e.code;
- <quote><p>
- This function is used to set the status of a resource during
- OPERATING state. &s.code;list&e.code; holds a list to which
- &s.code;mask&e.code; is to be applied. The parameter
- &s.code;mask&e.code; may have the value &s.code;ResUnusedOpr&e.code;
- and &s.code;ResDisableOpr&e.code;. The first one should be used
- if a resource isn't used by the driver during OPERATING state
- although it is decoded by the device, while the latter one indicates
- that the resource is not decoded during OPERATING state. Note
- that the resource ranges have to match those specified during
- registration. If a range has been specified starting at
- &s.code;A&e.code; and ending at &s.code;B&e.code; and suppose
- &s.code;C&e.code; us a value satisfying
- &s.code;A < C < B&e.code; one may not
- specify the resource range &s.code;(A,B)&e.code; by splitting it
- into two ranges &s.code;(A,C)&e.code; and &s.code;(C,B)&e.code;.
-
- </quote>
- </quote>
-
-The following two functions are provided for special cases:
- <quote><p>
- &s.code;void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)&e.code;
- <quote><p>
- This function may be used to remove an entity from a screen. This
- only makes sense if a screen has more than one entity assigned or
- the screen is to be deleted. No test is made if the screen has
- any entities left.
-
- </quote>
-
- &s.code;void xf86DeallocateResourcesForEntity(int entityIndex, long type)&e.code;
- <quote><p>
- This function deallocates all resources of a given type registered
- for a certain entity from the resource broker list.
-
- </quote>
- </quote>
-
-<sect2>ScreenInit Phase
-<p>
-
-All that is required in this phase is to setup the RAC flags. Note that
-it is also permissible to set these flags up in the PreInit phase. The
-RAC flags are held in the &s.code;racIoFlags&e.code; and &s.code;racMemFlags&e.code; fields of the
-&s.code;ScrnInfoRec&e.code; for each screen. They specify which graphics operations
-might require the use of shared resources. This can be specified
-separately for memory and I/O resources. The available flags are defined
-in &s.code;rac/xf86RAC.h&e.code;. They are:
-
- &s.code;RAC_FB&e.code;
- <quote>
- for framebuffer operations (including hw acceleration)
- </quote>
- &s.code;RAC_CURSOR&e.code;
- <quote>
- for Cursor operations
- (??? I'm not sure if we need this for SW cursor it depends
- on which level the sw cursor is drawn)
- </quote>
- &s.code;RAC_COLORMAP&e.code;
- <quote>
- for colormap operations
- </quote>
- &s.code;RAC_VIEWPORT&e.code;
- <quote>
- for the call to &s.code;ChipAdjustFrame()&e.code; </quote>
-
-
-The flags are ORed together.
-
-<sect>Config file ``Option'' entries<label id="options">
-<p>
-
-Option entries are permitted in most sections and subsections of the
-config file. There are two forms of option entries:
-
-<descrip>
-<tag>Option "option-name"</tag>
- A boolean option.
-<tag>Option "option-name" "option-value"</tag>
- An option with an arbitrary value.
-</descrip>
-
-The option entries are handled by the parser, and a list of the parsed
-options is included with each of the appropriate data structures that
-the drivers have access to. The data structures used to hold the option
-information are opaque to the driver, and a driver must not access the
-option data directly. Instead, the common layer provides a set of
-functions that may be used to access, check and manipulate the option
-data.
-
-First, the low level option handling functions. In most cases drivers
-would not need to use these directly.
-
- <quote><p>
- &s.code;pointer xf86FindOption(pointer options, const char *name)&e.code;
- <quote><p>
- Takes a list of options and an option name, and returns a handle
- for the first option entry in the list matching the name. Returns
- &s.code;NULL&e.code; if no match is found.
-
- </quote>
-
- &s.code;char *xf86FindOptionValue(pointer options, const char *name)&e.code;
- <quote><p>
- Takes a list of options and an option name, and returns the value
- associated with the first option entry in the list matching the
- name. If the matching option has no value, an empty string
- (&s.code;""&e.code;) is returned. Returns &s.code;NULL&e.code;
- if no match is found.
-
- </quote>
-
- &s.code;void xf86MarkOptionUsed(pointer option)&e.code;
- <quote><p>
- Takes a handle for an option, and marks that option as used.
-
- </quote>
-
- &s.code;void xf86MarkOptionUsedByName(pointer options, const char *name)&e.code;
- <quote><p>
- Takes a list of options and an option name and marks the first
- option entry in the list matching the name as used.
-
- </quote>
- </quote>
-
-
-Next, the higher level functions that most drivers would use.
- <quote><p>
- &s.code;void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)&e.code;
- <quote><p>
- Collect the options from each of the config file sections used by
- the screen (&s.code;pScrn&e.code;) and return the merged list as
- &s.code;pScrn->options&e.code;. This function requires that
- &s.code;pScrn->confScreen&e.code;, &s.code;pScrn->display&e.code;,
- &s.code;pScrn->monitor&e.code;,
- &s.code;pScrn->numEntities&e.code;, and
- &s.code;pScrn->entityList&e.code; are initialised.
- &s.code;extraOpts&e.code; may optionally be set to an additional
- list of options to be combined with the others. The order of
- precedence for options is &s.code;extraOpts&e.code;, display,
- confScreen, monitor, device.
-
- </quote>
-
- &s.code;void xf86ProcessOptions(int scrnIndex, pointer options,
- &f.indent;OptionInfoPtr optinfo)&e.code;
- <quote><p>
- Processes a list of options according to the information in the
- array of &s.code;OptionInfoRecs&e.code; (&s.code;optinfo&e.code;).
- The resulting information is stored in the &s.code;value&e.code;
- fields of the appropriate &s.code;optinfo&e.code; entries. The
- &s.code;found&e.code; fields are set to &s.code;TRUE&e.code;
- when an option with a value of the correct type if found, and
- &s.code;FALSE&e.code; otherwise. The &s.code;type&e.code; field
- is used to determine the expected value type for each option.
- Each option in the list of options for which there is a name match
- (but not necessarily a value type match) is marked as used.
- Warning messages are printed when option values don't match the
- types specified in the optinfo data.
-
- NOTE: If this function is called before a driver's screen number
- is known (e.g., from the &s.code;ChipProbe()&e.code; function) a
- &s.code;scrnIndex&e.code; value of &s.code;-1&e.code; should be
- used.
-
- NOTE 2: Given that this function stores into the
- &s.code;OptionInfoRecs&e.code; pointed to by &s.code;optinfo&e.code,
- the caller should ensure the &s.code;OptionInfoRecs&e.code; are
- (re-)initialised before the call, especially if the caller expects
- to use the predefined option values as defaults.
-
- The &s.code;OptionInfoRec&e.code; is defined as follows:
-
- <verb>
- typedef struct {
- double freq;
- int units;
- } OptFrequency;
-
- typedef union {
- unsigned long num;
- char * str;
- double realnum;
- Bool bool;
- OptFrequency freq;
- } ValueUnion;
-
- typedef enum {
- OPTV_NONE = 0,
- OPTV_INTEGER,
- OPTV_STRING, /* a non-empty string */
- OPTV_ANYSTR, /* Any string, including an empty one */
- OPTV_REAL,
- OPTV_BOOLEAN,
- OPTV_PERCENT,
- OPTV_FREQ
- } OptionValueType;
-
- typedef enum {
- OPTUNITS_HZ = 1,
- OPTUNITS_KHZ,
- OPTUNITS_MHZ
- } OptFreqUnits;
-
- typedef struct {
- int token;
- const char* name;
- OptionValueType type;
- ValueUnion value;
- Bool found;
- } OptionInfoRec, *OptionInfoPtr;
- </verb>
-
- &s.code;OPTV_FREQ&e.code; can be used for options values that are
- frequencies. These values are a floating point number with an
- optional unit name appended. The unit name can be one of "Hz",
- "kHz", "k", "MHz", "M". The multiplier associated with the unit
- is stored in &s.code;freq.units&e.code;, and the scaled frequency
- is stored in &s.code;freq.freq&e.code;. When no unit is specified,
- &s.code;freq.units&e.code; is set to &s.code;0&e.code;, and
- &s.code;freq.freq&e.code; is unscaled.
-
- &s.code;OPTV_PERCENT&e.code; can be used for option values that are
- specified in percent (e.g. "20%"). These values are a floating point
- number with a percent sign appended. If the percent sign is missing,
- the parser will fail to match the value.
-
- Typical usage is to setup an array of
- &s.code;OptionInfoRecs&e.code; with all fields initialised.
- The &s.code;value&e.code; and &s.code;found&e.code; fields get
- set by &s.code;xf86ProcessOptions()&e.code;. For cases where the
- value parsing is more complex, the driver should specify
- &s.code;OPTV_STRING&e.code;, and parse the string itself. An
- example of using this option handling is included in the
- <ref id="sample" name="Sample Driver"> section.
-
- </quote>
-
- &s.code;void xf86ShowUnusedOptions(int scrnIndex, pointer options)&e.code;
- <quote><p>
- Prints out warning messages for each option in the list of options
- that isn't marked as used. This is intended to show options that
- the driver hasn't recognised. It would normally be called near
- the end of the &s.code;ChipScreenInit()&e.code; function, but only
- when &s.code;serverGeneration == 1&e.code;.
-
- </quote>
-
- &s.code;OptionInfoPtr xf86TokenToOptinfo(const OptionInfoRec *table,
- &f.indent;int token)&e.code;
-
- <quote><p>
- Returns a pointer to the &s.code;OptionInfoRec&e.code; in
- &s.code;table&e.code; with a token field matching
- &s.code;token&e.code;. Returns &s.code;NULL&e.code; if no match
- is found.
-
- </quote>
-
- &s.code;Bool xf86IsOptionSet(const OptionInfoRec *table, int token)&e.code;
- <quote><p>
- Returns the &s.code;found&e.code; field of the
- &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; with a
- &s.code;token&e.code; field matching &s.code;token&e.code;. This
- can be used for options of all types. Note that for options of
- type &s.code;OPTV_BOOLEAN&e.code;, it isn't sufficient to check
- this to determine the value of the option. Returns
- &s.code;FALSE&e.code; if no match is found.
-
- </quote>
-
- &s.code;char *xf86GetOptValString(const OptionInfoRec *table, int token)&e.code;
- <quote><p>
- Returns the &s.code;value.str&e.code; field of the
- &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; with a
- token field matching &s.code;token&e.code;. Returns
- &s.code;NULL&e.code; if no match is found.
-
- </quote>
-
- &s.code;Bool xf86GetOptValInteger(const OptionInfoRec *table, int token,
- &f.indent;int *value)&e.code;
- <quote><p>
- Returns via &s.code;*value&e.code; the &s.code;value.num&e.code;
- field of the &s.code;OptionInfoRec&e.code; in &s.code;table&e.code;
- with a &s.code;token&e.code; field matching &s.code;token&e.code;.
- &s.code;*value&e.code; is only changed when a match is found so
- it can be safely initialised with a default prior to calling this
- function. The function return value is as for
- &s.code;xf86IsOptionSet()&e.code;.
-
- </quote>
-
- &s.code;Bool xf86GetOptValULong(const OptionInfoRec *table, int token,
- &f.indent;unsigned long *value)&e.code;
- <quote><p>
- Like &s.code;xf86GetOptValInteger()&e.code;, except the value is
- treated as an &s.code;unsigned long&e.code;.
-
- </quote>
-
- &s.code;Bool xf86GetOptValReal(const OptionInfoRec *table, int token,
- &f.indent;double *value)&e.code;
- <quote><p>
- Like &s.code;xf86GetOptValInteger()&e.code;, except that
- &s.code;value.realnum&e.code; is used.
-
- </quote>
-
- &s.code;Bool xf86GetOptValFreq(const OptionInfoRec *table, int token,
- &f.indent;OptFreqUnits expectedUnits, double *value)&e.code;
- <quote><p>
- Like &s.code;xf86GetOptValInteger()&e.code;, except that the
- &s.code;value.freq&e.code; data is returned. The frequency value
- is scaled to the units indicated by &s.code;expectedUnits&e.code;.
- The scaling is exact when the units were specified explicitly in
- the option's value. Otherwise, the &s.code;expectedUnits&e.code;
- field is used as a hint when doing the scaling. In this case,
- values larger than &s.code;1000&e.code; are assumed to have be
- specified in the next smallest units. For example, if the Option
- value is "10000" and expectedUnits is &s.code;OPTUNITS_MHZ&e.code;,
- the value returned is &s.code;10&e.code;.
-
- </quote>
-
- &s.code;Bool xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value)&e.code;
- <quote><p>
- This function is used to check boolean options
- (&s.code;OPTV_BOOLEAN&e.code;). If the function return value is
- &s.code;FALSE&e.code;, it means the option wasn't set. Otherwise
- &s.code;*value&e.code; is set to the boolean value indicated by
- the option's value. No option &s.code;value&e.code; is interpreted
- as &s.code;TRUE&e.code;. Option values meaning &s.code;TRUE&e.code;
- are "1", "yes", "on", "true", and option values meaning
- &s.code;FALSE&e.code; are "0", "no", "off", "false". Option names
- both with the "no" prefix in their names, and with that prefix
- removed are also checked and handled in the obvious way.
- &s.code;*value&e.code; is not changed when the option isn't present.
- It should normally be set to a default value before calling this
- function.
-
- </quote>
-
- &s.code;Bool xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def)&e.code;
- <quote><p>
- This function is used to check boolean options
- (&s.code;OPTV_BOOLEAN&e.code;). If the option is set, its value
- is returned. If the options is not set, the default value specified
- by &s.code;def&e.code; is returned. The option interpretation is
- the same as for &s.code;xf86GetOptValBool()&e.code;.
-
- </quote>
-
- &s.code;int xf86NameCmp(const char *s1, const char *s2)&e.code;
- <quote><p>
- This function should be used when comparing strings from the config
- file with expected values. It works like &s.code;strcmp()&e.code;,
- but is not case sensitive and space, tab, and `<tt>_</tt>' characters
- are ignored in the comparison. The use of this function isn't
- restricted to parsing option values. It may be used anywhere
- where this functionality required.
-
- </quote>
- </quote>
-
-<sect>Modules, Drivers, Include Files and Interface Issues
-<p>
-
-NOTE: this section is incomplete.
-
-
-<sect1>Include files
-<p>
-
-The following include files are typically required by video drivers:
-
- <quote><p>
- All drivers should include these:
- <quote>
- &s.code;"xf86.h"&nl;
- "xf86_OSproc.h"&nl;
- "xf86_ansic.h"&nl;
- "xf86Resources.h"&e.code;
- </quote>
- Wherever inb/outb (and related things) are used the following should be
- included:
- <quote>
- &s.code;"compiler.h"&e.code;
- </quote>
- Note: in drivers, this must be included after &s.code;"xf86_ansic.h"&e.code;.
-
- Drivers that need to access PCI vendor/device definitions need this:
- <quote>
- &s.code;"xf86PciInfo.h"&e.code;
- </quote>
-
- Drivers that need to access the PCI config space need this:
- <quote>
- &s.code;"xf86Pci.h"&e.code;
- </quote>
-
- Drivers that initialise a SW cursor need this:
- <quote>
- &s.code;"mipointer.h"&e.code;
- </quote>
-
- All drivers implementing backing store need this:
- <quote>
- &s.code;"mibstore.h"&e.code;
- </quote>
-
- All drivers using the mi colourmap code need this:
- <quote>
- &s.code;"micmap.h"&e.code;
- </quote>
-
- If a driver uses the vgahw module, it needs this:
- <quote>
- &s.code;"vgaHW.h"&e.code;
- </quote>
-
- Drivers supporting VGA or Hercules monochrome screens need:
- <quote>
- &s.code;"xf1bpp.h"&e.code;
- </quote>
-
- Drivers supporting VGA or EGC 16-colour screens need:
- <quote>
- &s.code;"xf4bpp.h"&e.code;
- </quote>
-
- Drivers using cfb need:
- <quote>
- &s.code;#define PSZ 8&nl;
- #include "cfb.h"&nl;
- #undef PSZ&e.code;
- </quote>
-
- Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
- <quote>
- &s.code;"cfb16.h"&nl;
- "cfb24.h"&nl;
- "cfb32.h"&e.code;
- </quote>
-
- If a driver uses XAA, it needs these:
- <quote>
- &s.code;"xaa.h"&nl;
- "xaalocal.h"&e.code;
- </quote>
-
- If a driver uses the fb manager, it needs this:
- <quote>
- &s.code;"xf86fbman.h"&e.code;
- </quote>
- </quote>
-
-Non-driver modules should include &s.code;"xf86_ansic.h"&e.code; to get the correct
-wrapping of ANSI C/libc functions.
-
-All modules must NOT include any system include files, or the following:
-
- <quote>
- &s.code;"xf86Priv.h"&nl;
- "xf86Privstr.h"&nl;
- "xf86_OSlib.h"&nl;
- "Xos.h"&e.code;
- </quote>
-
-In addition, "xf86_libc.h" must not be included explicitly. It is
-included implicitly by "xf86_ansic.h".
-
-
-<sect>Offscreen Memory Manager
-<p>
-
-Management of offscreen video memory may be handled by the XFree86
-framebuffer manager. Once the offscreen memory manager is running,
-drivers or extensions may allocate, free or resize areas of offscreen
-video memory using the following functions (definitions taken from
-&s.code;xf86fbman.h&e.code;):
-
-<code>
- typedef struct _FBArea {
- ScreenPtr pScreen;
- BoxRec box;
- int granularity;
- void (*MoveAreaCallback)(struct _FBArea*, struct _FBArea*)
- void (*RemoveAreaCallback)(struct _FBArea*)
- DevUnion devPrivate;
- } FBArea, *FBAreaPtr;
-
- typedef void (*MoveAreaCallbackProcPtr)(FBAreaPtr from, FBAreaPtr to)
- typedef void (*RemoveAreaCallbackProcPtr)(FBAreaPtr)
-
- FBAreaPtr xf86AllocateOffscreenArea (
- ScreenPtr pScreen,
- int width, int height,
- int granularity,
- MoveAreaCallbackProcPtr MoveAreaCallback,
- RemoveAreaCallbackProcPtr RemoveAreaCallback,
- pointer privData
- )
-
- void xf86FreeOffscreenArea (FBAreaPtr area)
-
- Bool xf86ResizeOffscreenArea (
- FBAreaPtr area
- int w, int h
- )
-</code>
-
-The function:
-<quote>
- &s.code;Bool xf86FBManagerRunning(ScreenPtr pScreen)&e.code;
-</quote>
-
-can be used by an extension to check if the driver has initialized
-the memory manager. The manager is not available if this returns
-&s.code;FALSE&e.code; and the functions above will all fail.
-
-
-&s.code;xf86AllocateOffscreenArea()&e.code; can be used to request a
-rectangle of dimensions &s.code;width&e.code; x &s.code;height&e.code;
-(in pixels) from unused offscreen memory. &s.code;granularity&e.code;
-specifies that the leftmost edge of the rectangle must lie on some
-multiple of &s.code;granularity&e.code; pixels. A granularity of zero
-means the same thing as a granularity of one - no alignment preference.
-A &s.code;MoveAreaCallback&e.code; can be provided to notify the requester
-when the offscreen area is moved. If no &s.code;MoveAreaCallback&e.code;
-is supplied then the area is considered to be immovable. The
-&s.code;privData&e.code; field will be stored in the manager's internal
-structure for that allocated area and will be returned to the requester
-in the &s.code;FBArea&e.code; passed via the
-&s.code;MoveAreaCallback&e.code;. An optional
-&s.code;RemoveAreaCallback&e.code; is provided. If the driver provides
-this it indicates that the area should be allocated with a lower priority.
-Such an area may be removed when a higher priority request (one that
-doesn't have a &s.code;RemoveAreaCallback&e.code;) is made. When this
-function is called, the driver will have an opportunity to do whatever
-cleanup it needs to do to deal with the loss of the area, but it must
-finish its cleanup before the function exits since the offscreen memory
-manager will free the area immediately after.
-
-&s.code;xf86AllocateOffscreenArea()&e.code; returns &s.code;NULL&e.code;
-if it was unable to allocate the requested area. When no longer needed,
-areas should be freed with &s.code;xf86FreeOffscreenArea()&e.code;.
-
-&s.code;xf86ResizeOffscreenArea()&e.code; resizes an existing
-&s.code;FBArea&e.code;. &s.code;xf86ResizeOffscreenArea()&e.code;
-returns &s.code;TRUE&e.code; if the resize was successful. If
-&s.code;xf86ResizeOffscreenArea()&e.code; returns &s.code;FALSE&e.code;,
-the original &s.code;FBArea&e.code; is left unmodified. Resizing an
-area maintains the area's original &s.code;granularity&e.code;,
-&s.code;devPrivate&e.code;, and &s.code;MoveAreaCallback&e.code;.
-&s.code;xf86ResizeOffscreenArea()&e.code; has considerably less overhead
-than freeing the old area then reallocating the new size, so it should
-be used whenever possible.
-
-The function:
- <quote>
- &s.code;Bool xf86QueryLargestOffscreenArea(
- &f.indent;ScreenPtr pScreen,
- &f.indent;int *width, int *height,
- &f.indent;int granularity,
- &f.indent;int preferences,
- &f.indent;int priority
- &nl)&e.code;
- </quote>
-
-is provided to query the width and height of the largest single
-&s.code;FBArea&e.code; allocatable given a particular priority.
-&s.code;preferences&e.code; can be one of the following to indicate
-whether width, height or area should be considered when determining
-which is the largest single &s.code;FBArea&e.code; available.
-
- <quote>
- &s.code;FAVOR_AREA_THEN_WIDTH&nl;
- FAVOR_AREA_THEN_HEIGHT&nl;
- FAVOR_WIDTH_THEN_AREA&nl;
- FAVOR_HEIGHT_THEN_AREA&e.code;
- </quote>
-
-&s.code;priority&e.code; is one of the following:
-
- <quote><p>
- &s.code;PRIORITY_LOW&e.code;
- <quote><p>
- Return the largest block available without stealing anyone else's
- space. This corresponds to the priority of allocating a
- &s.code;FBArea&e.code; when a &s.code;RemoveAreaCallback&e.code;
- is provided.
-
- </quote>
- &s.code;PRIORITY_NORMAL&e.code;
- <quote><p>
- Return the largest block available if it is acceptable to steal a
- lower priority area from someone. This corresponds to the priority
- of allocating a &s.code;FBArea&e.code; without providing a
- &s.code;RemoveAreaCallback&e.code;.
-
- </quote>
- &s.code;PRIORITY_EXTREME&e.code;
- <quote><p>
- Return the largest block available if all &s.code;FBAreas&e.code;
- that aren't locked down were expunged from memory first. This
- corresponds to any allocation made directly after a call to
- &s.code;xf86PurgeUnlockedOffscreenAreas()&e.code;.
-
- </quote>
- </quote>
-
-
-The function:
-
- <quote>
- &s.code;Bool xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen)&e.code;
- </quote>
-
-is provided as an extreme method to free up offscreen memory. This
-will remove all removable &s.code;FBArea&e.code; allocations.
-
-
-Initialization of the XFree86 framebuffer manager is done via
-
- <quote>
- &s.code;Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox)&e.code;
- </quote>
-
-&s.code;FullBox&e.code; represents the area of the framebuffer that the
-manager is allowed to manage. This is typically a box with a width of
-&s.code;pScrn->displayWidth&e.code; and a height of as many lines as
-can be fit within the total video memory, however, the driver can reserve
-areas at the extremities by passing a smaller area to the manager.
-
-&s.code;xf86InitFBManager()&e.code; must be called before XAA is
-initialized since XAA uses the manager for it's pixmap cache.
-
-An alternative function is provided to allow the driver to initialize
-the framebuffer manager with a Region rather than a box.
-
- <quote>
- &s.code;Bool xf86InitFBManagerRegion(ScreenPtr pScreen,
- &f.indent;RegionPtr FullRegion)&e.code;
- </quote>
-
-&s.code;xf86InitFBManagerRegion()&e.code;, unlike
-&s.code;xf86InitFBManager()&e.code;, does not remove the area used for
-the visible screen so that area should not be included in the region
-passed to the function. &s.code;xf86InitFBManagerRegion()&e.code; is
-useful when non-contiguous areas are available to be managed, and is
-required when multiple framebuffers are stored in video memory (as in
-the case where an overlay of a different depth is stored as a second
-framebuffer in offscreen memory).
-
-
-<sect>Colormap Handling<label id="cmap">
-<p>
-
-A generic colormap handling layer is provided within the XFree86 common
-layer. This layer takes care of most of the details, and only requires
-a function from the driver that loads the hardware palette when required.
-To use the colormap layer, a driver calls the
-&s.code;xf86HandleColormaps()&e.code; function.
-
- <quote><p>
- &s.code;Bool xf86HandleColormaps(ScreenPtr pScreen, int maxColors,
- &f.indent;int sigRGBbits, LoadPaletteFuncPtr loadPalette,
- &f.indent;SetOverscanFuncPtr setOverscan,
- unsigned int flags)&e.code;
- <quote><p>
- This function must be called after the default colormap has been
- initialised. The &s.code;pScrn->gamma&e.code; field must also
- be initialised, preferably by calling &s.code;xf86SetGamma()&e.code;.
- &s.code;maxColors&e.code; is the number of entries in the palette.
- &s.code;sigRGBbits&e.code; is the size in bits of each color
- component in the DAC's palette. &s.code;loadPalette&e.code;
- is a driver-provided function for loading a colormap into the
- hardware, and is described below. &s.code;setOverscan&e.code; is
- an optional function that may be provided when the overscan color
- is an index from the standard LUT and when it needs to be adjusted
- to keep it as close to black as possible. The
- &s.code;setOverscan&e.code; function programs the overscan index.
- It shouldn't normally be used for depths other than 8.
- &s.code;setOverscan&e.code; should be set to &s.code;NULL&e.code;
- when it isn't needed. &s.code;flags&e.code; may be set to the
- following (which may be ORed together):
-
- &s.code;CMAP_PALETTED_TRUECOLOR&e.code;
- <quote><p>
- the TrueColor visual is paletted and is
- just a special case of DirectColor.
- This flag is only valid for
- &s.code;bpp > 8&e.code;.
-
- </quote>
-
- &s.code;CMAP_RELOAD_ON_MODE_SWITCH&e.code;
- <quote><p>
- reload the colormap automatically
- after mode switches. This is useful
- for when the driver is resetting the
- hardware during mode switches and
- corrupting or erasing the hardware
- palette.
-
- </quote>
-
- &s.code;CMAP_LOAD_EVEN_IF_OFFSCREEN&e.code;
- <quote><p>
- reload the colormap even if the screen
- is switched out of the server's VC.
- The palette is <it>not</it> reloaded when
- the screen is switched back in, nor after
- mode switches. This is useful when the
- driver needs to keep track of palette
- changes.
-
- </quote>
-
- The colormap layer normally reloads the palette after VT enters so it
- is not necessary for the driver to save and restore the palette
- when switching VTs. The driver must, however, still save the
- initial palette during server start up and restore it during
- server exit.
-
- </quote>
-
- &s.code;void LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
- &f.indent;LOCO *colors, VisualPtr pVisual)&e.code;
- <quote><p>
- &s.code;LoadPalette()&e.code; is a driver-provided function for
- loading a colormap into hardware. &s.code;colors&e.code; is the
- array of RGB values that represent the full colormap.
- &s.code;indices&e.code; is a list of index values into the colors
- array. These indices indicate the entries that need to be updated.
- &s.code;numColors&e.code; is the number of the indices to be
- updated.
-
- </quote>
-
- &s.code;void SetOverscan(ScrnInfoPtr pScrn, int overscan)&e.code;
- <quote><p>
- &s.code;SetOverscan()&e.code; is a driver-provided function for
- programming the &s.code;overscan&e.code; index. As described
- above, it is normally only appropriate for LUT modes where all
- colormap entries are available for the display, but where one of
- them is also used for the overscan (typically 8bpp for VGA compatible
- LUTs). It isn't required in cases where the overscan area is
- never visible.
-
- </quote>
- </quote>
-
-
-<sect>DPMS Extension
-<p>
-
-Support code for the DPMS extension is included in the XFree86 common layer.
-This code provides an interface between the main extension code, and a means
-for drivers to initialise DPMS when they support it. One function is
-available to drivers to do this initialisation, and it is always available,
-even when the DPMS extension is not supported by the core server (in
-which case it returns a failure result).
-
-
- <quote><p>
- &s.code;Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)&e.code;
- <quote><p>
- This function registers a driver's DPMS level programming function
- &s.code;set&e.code;. It also checks
- &s.code;pScrn->options&e.code; for the "dpms" option, and when
- present marks DPMS as being enabled for that screen. The
- &s.code;set&e.code; function is called whenever the DPMS level
- changes, and is used to program the requested level.
- &s.code;flags&e.code; is currently not used, and should be
- &s.code;0&e.code;. If the initialisation fails for any reason,
- including when there is no DPMS support in the core server, the
- function returns &s.code;FALSE&e.code;.
-
- </quote>
- </quote>
-
-
-Drivers that implement DPMS support must provide the following function,
-that gets called when the DPMS level is changed:
-
-
- <quote><p>
- &s.code;void ChipDPMSSet(ScrnInfoPtr pScrn, int level, int flags)&e.code;
- <quote><p>
- Program the DPMS level specified by &s.code;level&e.code;. Valid
- values of &s.code;level&e.code; are &s.code;DPMSModeOn&e.code;,
- &s.code;DPMSModeStandby&e.code;, &s.code;DPMSModeSuspend&e.code;,
- &s.code;DPMSModeOff&e.code;. These values are defined in
- &s.code;"extensions/dpms.h"&e.code;.
-
- </quote>
- </quote>
-
-
-<sect>DGA Extension
-<p>
-
-Drivers can support the XFree86 Direct Graphics Architecture (DGA) by
-filling out a structure of function pointers and a list of modes and
-passing them to DGAInit.
-
- <quote><p>
- &s.code;Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs,
- &f.indent;DGAModePtr modes, int num)&e.code;
- <quote><p>
- <verb>
-/** The DGAModeRec **/
-
-typedef struct {
- int num;
- DisplayModePtr mode;
- int flags;
- int imageWidth;
- int imageHeight;
- int pixmapWidth;
- int pixmapHeight;
- int bytesPerScanline;
- int byteOrder;
- int depth;
- int bitsPerPixel;
- unsigned long red_mask;
- unsigned long green_mask;
- unsigned long blue_mask;
- int viewportWidth;
- int viewportHeight;
- int xViewportStep;
- int yViewportStep;
- int maxViewportX;
- int maxViewportY;
- int viewportFlags;
- int offset;
- unsigned char *address;
- int reserved1;
- int reserved2;
-} DGAModeRec, *DGAModePtr;
-</verb>
-
- &s.code;num&e.code;
- <quote>
- Can be ignored. The DGA DDX will assign these numbers.
- </quote>
-
- &s.code;mode&e.code;
- <quote>
- A pointer to the &s.code;DisplayModeRec&e.code; for this mode.
- </quote>
-
- &s.code;flags&e.code;
- <quote><p>
- The following flags are defined and may be OR'd together:
-
- &s.code;DGA_CONCURRENT_ACCESS&e.code;
- <quote><p>
- Indicates that the driver supports concurrent graphics
- accelerator and linear framebuffer access.
-
- </quote>
-
- &s.code;DGA_FILL_RECT&nl;
- DGA_BLIT_RECT&nl;
- DGA_BLIT_RECT_TRANS&e.code;
- <quote><p>
- Indicates that the driver supports the FillRect, BlitRect
- or BlitTransRect functions in this mode.
-
- </quote>
-
- &s.code;DGA_PIXMAP_AVAILABLE&e.code;
- <quote><p>
- Indicates that Xlib may be used on the framebuffer.
- This flag will usually be set unless the driver wishes
- to prohibit this for some reason.
-
- </quote>
-
- &s.code;DGA_INTERLACED&nl;
- DGA_DOUBLESCAN&e.code;
- <quote><p>
- Indicates that these are interlaced or double scan modes.
-
- </quote>
- </quote>
-
- &s.code;imageWidth&nl;
- imageHeight&e.code;
- <quote><p>
- These are the dimensions of the linear framebuffer
- accessible by the client.
-
- </quote>
-
- &s.code;pixmapWidth&nl;
- pixmapHeight&e.code;
- <quote><p>
- These are the dimensions of the area of the
- framebuffer accessible by the graphics accelerator.
-
- </quote>
-
- &s.code;bytesPerScanline&e.code;
- <quote><p>
- Pitch of the framebuffer in bytes.
-
- </quote>
-
- &s.code;byteOrder&e.code;
- <quote><p>
- Usually the same as
- &s.code;pScrn->imageByteOrder&e.code;.
-
- </quote>
-
- &s.code;depth&e.code;
- <quote><p>
- The depth of the framebuffer in this mode.
-
- </quote>
-
- &s.code;bitsPerPixel&e.code;
- <quote><p>
- The number of bits per pixel in this mode.
-
- </quote>
-
- &s.code;red_mask&nl;
- green_mask&nl;
- blue_mask&e.code;
- <quote><p>
- The RGB masks for this mode, if applicable.
-
- </quote>
-
- &s.code;viewportWidth&nl;
- viewportHeight&e.code;
- <quote><p>
- Dimensions of the visible part of the framebuffer.
- Usually &s.code;mode->HDisplay&e.code; and
- &s.code;mode->VDisplay&e.code;.
-
- </quote>
-
- &s.code;xViewportStep&nl;
- yViewportStep&e.code;
- <quote><p>
- The granularity of x and y viewport positions that
- the driver supports in this mode.
-
- </quote>
-
- &s.code;maxViewportX&nl;
- maxViewportY&e.code;
- <quote><p>
- The maximum viewport position supported by the
- driver in this mode.
-
- </quote>
-
- &s.code;viewportFlags&e.code;
- <quote><p>
- The following may be OR'd together:
-
- &s.code;DGA_FLIP_IMMEDIATE&e.code;
- <quote><p>
- The driver supports immediate viewport changes.
-
- </quote>
- &s.code;DGA_FLIP_RETRACE&e.code;
- <quote<p>
- The driver supports viewport changes at retrace.
-
- </quote>
- </quote>
-
- &s.code;offset&e.code;
- <quote><p>
- The offset into the linear framebuffer that corresponds to
- pixel (0,0) for this mode.
-
- </quote>
-
- &s.code;address&e.code;
- <quote><p>
- The virtual address of the framebuffer as mapped by the driver.
- This is needed when DGA_PIXMAP_AVAILABLE is set.
-
- </quote>
-
- <verb>
-/** The DGAFunctionRec **/
-
-typedef struct {
- Bool (*OpenFramebuffer)(
- ScrnInfoPtr pScrn,
- char **name,
- unsigned char **mem,
- int *size,
- int *offset,
- int *extra
- );
- void (*CloseFramebuffer)(ScrnInfoPtr pScrn);
- Bool (*SetMode)(ScrnInfoPtr pScrn, DGAModePtr pMode);
- void (*SetViewport)(ScrnInfoPtr pScrn, int x, int y, int flags);
- int (*GetViewport)(ScrnInfoPtr pScrn);
- void (*Sync)(ScrnInfoPtr);
- void (*FillRect)(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned long color
- );
- void (*BlitRect)(
- ScrnInfoPtr pScrn,
- int srcx, int srcy,
- int w, int h,
- int dstx, int dsty
- );
- void (*BlitTransRect)(
- ScrnInfoPtr pScrn,
- int srcx, int srcy,
- int w, int h,
- int dstx, int dsty,
- unsigned long color
- );
-} DGAFunctionRec, *DGAFunctionPtr;
-</verb>
-
- </quote>
-
- &s.code;Bool OpenFramebuffer (pScrn, name, mem, size, offset, extra)&e.code;
- <quote><p>
- &s.code;OpenFramebuffer()&e.code; should pass the client everything
- it needs to know to be able to open the framebuffer. These
- parameters are OS specific and their meanings are to be interpreted
- by an OS specific client library.
-
- &s.code;name&e.code;
- <quote><p>
- The name of the device to open or &s.code;NULL&e.code; if
- there is no special device to open. A &s.code;NULL&e.code;
- name tells the client that it should open whatever device
- one would usually open to access physical memory.
-
- </quote>
- &s.code;mem&e.code;
- <quote><p>
- The physical address of the start of the framebuffer.
-
- </quote>
- &s.code;size&e.code;
- <quote><p>
- The size of the framebuffer in bytes.
-
- </quote>
- &s.code;offset&e.code;
- <quote><p>
- Any offset into the device, if applicable.
-
- </quote>
- &s.code;flags&e.code;
- <quote><p>
- Any additional information that the client may need.
- Currently, only the &s.code;DGA_NEED_ROOT&e.code; flag is
- defined.
-
- </quote>
- </quote>
-
- &s.code;void CloseFramebuffer (pScrn)&e.code;
- <quote><p>
- &s.code;CloseFramebuffer()&e.code; merely informs the driver (if it
- even cares) that client no longer needs to access the framebuffer
- directly. This function is optional.
-
- </quote>
-
- &s.code;Bool SetMode (pScrn, pMode)&e.code;
- <quote><p>
- &s.code;SetMode()&e.code; tells the driver to initialize the mode
- passed to it. If &s.code;pMode&e.code; is &s.code;NULL&e.code;,
- then the driver should restore the original pre-DGA mode.
-
- </quote>
-
- &s.code;void SetViewport (pScrn, x, y, flags)&e.code;
- <quote><p>
- &s.code;SetViewport()&e.code; tells the driver to make the upper
- left-hand corner of the visible screen correspond to coordinate
- &s.code;(x,y)&e.code; on the framebuffer. &s.code;Flags&e.code;
- currently defined are:
-
- &s.code;DGA_FLIP_IMMEDIATE&e.code;
- <quote><p>
- The viewport change should occur immediately.
-
- </quote>
- &s.code;DGA_FLIP_RETRACE&e.code;
- <quote><p>
- The viewport change should occur at the
- vertical retrace, but this function should
- return sooner if possible.
-
- </quote>
- The &s.code;(x,y)&e.code; locations will be passed as the client
- specified them, however, the driver is expected to round these
- locations down to the next supported location as specified by the
- &s.code;xViewportStep&e.code; and &s.code;yViewportStep&e.code;
- for the current mode.
-
- </quote>
-
- &s.code;int GetViewport (pScrn)&e.code;
- <quote><p>
- &s.code;GetViewport()&e.code; gets the current page flip status.
- Set bits in the returned int correspond to viewport change requests
- still pending. For instance, set bit zero if the last SetViewport
- request is still pending, bit one if the one before that is still
- pending, etc.
-
- </quote>
-
- &s.code;void Sync (pScrn)&e.code;
- <quote><p>
- This function should ensure that any graphics accelerator operations
- have finished. This function should not return until the graphics
- accelerator is idle.
-
- </quote>
-
- &s.code;void FillRect (pScrn, x, y, w, h, color)&e.code;
- <quote><p>
- This optional function should fill a rectangle
- &s.code;w × h&e.code; located at
- &s.code;(x,y)&e.code; in the given color.
-
- </quote>
-
- &s.code;void BlitRect (pScrn, srcx, srcy, w, h, dstx, dsty)&e.code;
- <quote><p>
- This optional function should copy an area
- &s.code;w × h&e.code; located at
- &s.code;(srcx,srcy)&e.code; to location &s.code;(dstx,dsty)&e.code;.
- This function will need to handle copy directions as appropriate.
-
- </quote>
-
- &s.code;void BlitTransRect (pScrn, srcx, srcy, w, h, dstx, dsty, color)&e.code;
- <quote><p>
- This optional function is the same as BlitRect except that pixels
- in the source corresponding to the color key &s.code;color&e.code;
- should be skipped.
-
- </quote>
- </quote>
-
-<sect>The XFree86 X Video Extension (Xv) Device Dependent Layer
-<p>
-
-XFree86 offers the X Video Extension which allows clients to treat video
-as any another primitive and ``Put'' video into drawables. By default,
-the extension reports no video adaptors as being available since the
-DDX layer has not been initialized. The driver can initialize the DDX
-layer by filling out one or more &s.code;XF86VideoAdaptorRecs&e.code;
-as described later in this document and passing a list of
-&s.code;XF86VideoAdaptorPtr&e.code; pointers to the following function:
-
- <quote>
- &s.code;Bool xf86XVScreenInit(
- &f.indent;ScreenPtr pScreen,
- &f.indent;XF86VideoAdaptorPtr *adaptPtrs,
- &f.indent;int num)&e.code;
- </quote>
-
-After doing this, the extension will report video adaptors as being
-available, providing the data in their respective
-&s.code;XF86VideoAdaptorRecs&e.code; was valid.
-&s.code;xf86XVScreenInit()&e.code; <em>copies</em> data from the structure
-passed to it so the driver may free it after the initialization. At
-the moment, the DDX only supports rendering into Window drawables.
-Pixmap rendering will be supported after a sufficient survey of suitable
-hardware is completed.
-
-The &s.code;XF86VideoAdaptorRec&e.code;:
-
-<quote><p>
-<verb>
-typedef struct {
- unsigned int type;
- int flags;
- char *name;
- int nEncodings;
- XF86VideoEncodingPtr pEncodings;
- int nFormats;
- XF86VideoFormatPtr pFormats;
- int nPorts;
- DevUnion *pPortPrivates;
- int nAttributes;
- XF86AttributePtr pAttributes;
- int nImages;
- XF86ImagePtr pImages;
- PutVideoFuncPtr PutVideo;
- PutStillFuncPtr PutStill;
- GetVideoFuncPtr GetVideo;
- GetStillFuncPtr GetStill;
- StopVideoFuncPtr StopVideo;
- SetPortAttributeFuncPtr SetPortAttribute;
- GetPortAttributeFuncPtr GetPortAttribute;
- QueryBestSizeFuncPtr QueryBestSize;
- PutImageFuncPtr PutImage;
- QueryImageAttributesFuncPtr QueryImageAttributes;
-} XF86VideoAdaptorRec, *XF86VideoAdaptorPtr;
-</verb>
-
- Each adaptor will have its own XF86VideoAdaptorRec. The fields are
- as follows:
-
- &s.code;type&e.code;
- <quote><p>
- This can be any of the following flags OR'd together.
-
- &s.code;XvInputMask&e.code;
- &s.code;XvOutputMask&e.code;
- <quote><p>
- These refer to the target drawable and are similar to a Window's
- class. &s.code;XvInputMask&e.code; indicates that the adaptor
- can put video into a drawable. &s.code;XvOutputMask&e.code;
- indicates that the adaptor can get video from a drawable.
- </quote>
-
- &s.code;XvVideoMask&e.code;
- &s.code;XvStillMask&e.code;
- &s.code;XvImageMask&e.code;
- <quote><p>
- These indicate that the adaptor supports video, still or
- image primitives respectively.
- </quote>
-
- &s.code;XvWindowMask&e.code;
- &s.code;XvPixmapMask&e.code;
- <quote><p>
- These indicate the types of drawables the adaptor is capable
- of rendering into. At the moment, Pixmap rendering is not
- supported and the &s.code;XvPixmapMask&e.code; flag is ignored.
- </quote>
-
- </quote>
-
- &s.code;flags&e.code;
- <quote><p>
- Currently, the following flags are defined:
-
- &s.code;VIDEO_NO_CLIPPING&e.code;
- <quote><p>
- This indicates that the video adaptor does not support
- clipping. The driver will never receive ``Put'' requests
- where less than the entire area determined by
- &s.code;drw_x&e.code;, &s.code;drw_y&e.code;,
- &s.code;drw_w&e.code; and &s.code;drw_h&e.code; is visible.
- This flag does not apply to ``Get'' requests. Hardware
- that is incapable of clipping ``Gets'' may punt or get
- the extents of the clipping region passed to it.
-
- </quote>
-
- &s.code;VIDEO_INVERT_CLIPLIST&e.code;
- <quote><p>
- This indicates that the video driver requires the clip
- list to contain the regions which are obscured rather
- than the regions which are are visible.
-
- </quote>
-
- &s.code;VIDEO_OVERLAID_STILLS&e.code;
- <quote><p>
- Implementing PutStill for hardware that does video as an
- overlay can be awkward since it's unclear how long to leave
- the video up for. When this flag is set, StopVideo will be
- called whenever the destination gets clipped or moved so that
- the still can be left up until then.
-
- </quote>
-
- &s.code;VIDEO_OVERLAID_IMAGES&e.code;
- <quote><p>
- Same as &s.code;VIDEO_OVERLAID_STILLS&e.code; but for images.
- </quote>
-
- &s.code;VIDEO_CLIP_TO_VIEWPORT&e.code;
- <quote><p>
- Indicates that the clip region passed to the driver functions
- should be clipped to the visible portion of the screen in the
- case where the viewport is smaller than the virtual desktop.
- </quote>
-
- </quote>
-
- &s.code;name&e.code;
- <quote><p>
- The name of the adaptor.
-
- </quote>
-
- &s.code;nEncodings&nl;
- pEncodings&e.code;
- <quote><p>
- The number of encodings the adaptor is capable of and pointer
- to the &s.code;XF86VideoEncodingRec&e.code; array. The
- &s.code;XF86VideoEncodingRec&e.code; is described later on.
- For drivers that only support XvImages there should be an encoding
- named "XV_IMAGE" and the width and height should specify
- the maximum size source image supported.
-
- </quote>
-
- &s.code;nFormats&nl;
- pFormats&e.code;
- <quote><p>
- The number of formats the adaptor is capable of and pointer to
- the &s.code;XF86VideoFormatRec&e.code; array. The
- &s.code;XF86VideoFormatRec&e.code; is described later on.
-
- </quote>
-
- &s.code;nPorts&nl;
- pPortPrivates&e.code;
- <quote><p>
- The number of ports is the number of separate data streams which
- the adaptor can handle simultaneously. If you have more than
- one port, the adaptor is expected to be able to render into more
- than one window at a time. &s.code;pPortPrivates&e.code; is
- an array of pointers or ints - one for each port. A port's
- private data will be passed to the driver any time the port is
- requested to do something like put the video or stop the video.
- In the case where there may be many ports, this enables the
- driver to know which port the request is intended for. Most
- commonly, this will contain a pointer to the data structure
- containing information about the port. In Xv, all ports on
- a particular adaptor are expected to be identical in their
- functionality.
-
- </quote>
-
- &s.code;nAttributes&nl;
- pAttributes&e.code;
- <quote><p>
- The number of attributes recognized by the adaptor and a pointer to
- the array of &s.code;XF86AttributeRecs&e.code;. The
- &s.code;XF86AttributeRec&e.code; is described later on.
-
- </quote>
-
- &s.code;nImages&nl;
- pImages&e.code;
- <quote><p>
- The number of &s.code;XF86ImageRecs&e.code; supported by the adaptor
- and a pointer to the array of &s.code;XF86ImageRecs&e.code;. The
- &s.code;XF86ImageRec&e.code; is described later on.
-
- </quote>
-
-
- &s.code;PutVideo PutStill GetVideo GetStill StopVideo
- SetPortAttribute GetPortAttribute QueryBestSize PutImage
- QueryImageAttributes&e.code;
- <quote><p>
- These functions define the DDX->driver interface. In each
- case, the pointer &s.code;data&e.code; is passed to the driver.
- This is the port private for that port as described above. All
- fields are required except under the following conditions:
-
- <enum>
- <item>&s.code;PutVideo&e.code;, &s.code;PutStill&e.code; and
- the image routines &s.code;PutImage&e.code; and
- &s.code;QueryImageAttributes&e.code; are not required when the
- adaptor type does not contain &s.code;XvInputMask&e.code;.
-
- <item>&s.code;GetVideo&e.code; and &s.code;GetStill&e.code;
- are not required when the adaptor type does not contain
- &s.code;XvOutputMask&e.code;.
-
- <item>&s.code;GetVideo&e.code; and &s.code;PutVideo&e.code;
- are not required when the adaptor type does not contain
- &s.code;XvVideoMask&e.code;.
-
- <item>&s.code;GetStill&e.code; and &s.code;PutStill&e.code;
- are not required when the adaptor type does not contain
- &s.code;XvStillMask&e.code;.
-
- <item>&s.code;PutImage&e.code; and &s.code;QueryImageAttributes&e.code;
- are not required when the adaptor type does not contain
- &s.code;XvImageMask&e.code;.
-
- </enum>
-
- With the exception of &s.code;QueryImageAttributes&e.code;, these
- functions should return &s.code;Success&e.code; if the operation was
- completed successfully. They can return &s.code;XvBadAlloc&e.code;
- otherwise. &s.code;QueryImageAttributes&e.code; returns the size
- of the XvImage queried.
-
- If the &s.code;VIDEO_NO_CLIPPING&e.code;
- flag is set, the &s.code;clipBoxes&e.code; may be ignored by
- the driver. &s.code;ClipBoxes&e.code; is an &s.code;X-Y&e.code;
- banded region identical to those used throughout the server.
- The clipBoxes represent the visible portions of the area determined
- by &s.code;drw_x&e.code;, &s.code;drw_y&e.code;,
- &s.code;drw_w&e.code; and &s.code;drw_h&e.code; in the Get/Put
- function. The boxes are in screen coordinates, are guaranteed
- not to overlap and an empty region will never be passed.
- If the driver has specified &s.code;VIDEO_INVERT_CLIPLIST&e.code;,
- &s.code;clipBoxes&e.code; will indicate the areas of the primitive
- which are obscured rather than the areas visible.
-
- </quote>
-
- &s.code;typedef int (* PutVideoFuncPtr)( ScrnInfoPtr pScrn,
- &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
- &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
- &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
- <quote><p>
- This indicates that the driver should take a subsection
- &s.code;vid_w&e.code; by &s.code;vid_h&e.code; at location
- &s.code;(vid_x,vid_y)&e.code; from the video stream and direct
- it into the rectangle &s.code;drw_w&e.code; by &s.code;drw_h&e.code;
- at location &s.code;(drw_x,drw_y)&e.code; on the screen, scaling as
- necessary. Due to the large variations in capabilities of
- the various hardware expected to be used with this extension,
- it is not expected that all hardware will be able to do this
- exactly as described. In that case the driver should just do
- ``the best it can,'' scaling as closely to the target rectangle
- as it can without rendering outside of it. In the worst case,
- the driver can opt to just not turn on the video.
-
- </quote>
-
- &s.code;typedef int (* PutStillFuncPtr)( ScrnInfoPtr pScrn,
- &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
- &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
- &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
- <quote><p>
- This is same as &s.code;PutVideo&e.code; except that the driver
- should place only one frame from the stream on the screen.
-
- </quote>
-
- &s.code;typedef int (* GetVideoFuncPtr)( ScrnInfoPtr pScrn,
- &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
- &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
- &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
- <quote><p>
- This is same as &s.code;PutVideo&e.code; except that the driver
- gets video from the screen and outputs it. The driver should
- do the best it can to get the requested dimensions correct
- without reading from an area larger than requested.
-
- </quote>
-
- &s.code;typedef int (* GetStillFuncPtr)( ScrnInfoPtr pScrn,
- &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
- &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
- &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
- <quote><p>
- This is the same as &s.code;GetVideo&e.code; except that the
- driver should place only one frame from the screen into the
- output stream.
-
- </quote>
-
- &s.code;typedef void (* StopVideoFuncPtr)(ScrnInfoPtr pScrn,
- &f.indent;pointer data, Bool cleanup)&e.code;
- <quote><p>
- This indicates the driver should stop displaying the video.
- This is used to stop both input and output video. The
- &s.code;cleanup&e.code; field indicates that the video is
- being stopped because the client requested it to stop or
- because the server is exiting the current VT. In that case
- the driver should deallocate any offscreen memory areas (if
- there are any) being used to put the video to the screen. If
- &s.code;cleanup&e.code; is not set, the video is being stopped
- temporarily due to clipping or moving of the window, etc...
- and video will likely be restarted soon so the driver should
- not deallocate any offscreen areas associated with that port.
-
- </quote>
- &s.code;typedef int (* SetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
- &f.indent;Atom attribute,INT32 value, pointer data)&e.code;
-
- &s.code;typedef int (* GetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
- &f.indent;Atom attribute,INT32 *value, pointer data)&e.code;
-
- <quote><p>
- A port may have particular attributes such as hue,
- saturation, brightness or contrast. Xv clients set and
- get these attribute values by sending attribute strings
- (Atoms) to the server. Such requests end up at these
- driver functions. It is recommended that the driver provide
- at least the following attributes mentioned in the Xv client
- library docs:
- <quote>
- &s.code;XV_ENCODING&nl;
- XV_HUE&nl;
- XV_SATURATION&nl;
- XV_BRIGHTNESS&nl;
- XV_CONTRAST&e.code;
- </quote>
- but the driver may recognize as many atoms as it wishes. If
- a requested attribute is unknown by the driver it should return
- &s.code;BadMatch&e.code;. &s.code;XV_ENCODING&e.code; is the
- attribute intended to let the client specify which video
- encoding the particular port should be using (see the description
- of &s.code;XF86VideoEncodingRec&e.code; below). If the
- requested encoding is unsupported, the driver should return
- &s.code;XvBadEncoding&e.code;. If the value lies outside the
- advertised range &s.code;BadValue&e.code; may be returned.
- &s.code;Success&e.code; should be returned otherwise.
-
- </quote>
-
- &s.code;typedef void (* QueryBestSizeFuncPtr)(ScrnInfoPtr pScrn,
- &f.indent;Bool motion, short vid_w, short vid_h,
- &f.indent;short drw_w, short drw_h,
- &f.indent;unsigned int *p_w, unsigned int *p_h, pointer data)&e.code;
- <quote><p>
- &s.code;QueryBestSize&e.code; provides the client with a way
- to query what the destination dimensions would end up being
- if they were to request that an area
- &s.code;vid_w&e.code by &s.code;vid_h&e.code; from the video
- stream be scaled to rectangle of
- &s.code;drw_w&e.code; by &s.code;drw_h&e.code; on the screen.
- Since it is not expected that all hardware will be able to
- get the target dimensions exactly, it is important that the
- driver provide this function.
-
- </quote>
-
- &s.code;typedef int (* PutImageFuncPtr)( ScrnInfoPtr pScrn,
- &f.indent;short src_x, short src_y, short drw_x, short drw_y,
- &f.indent;short src_w, short src_h, short drw_w, short drw_h,
- &f.indent;int image, char *buf, short width, short height,
- &f.indent;Bool sync, RegionPtr clipBoxes, pointer data )&e.code;
- <quote><p>
- This is similar to &s.code;PutStill&e.code; except that the
- source of the video is not a port but the data stored in a system
- memory buffer at &s.code;buf&e.code;. The data is in the format
- indicated by the &s.code;image&e.code; descriptor and represents a
- source of size &s.code;width&e.code; by &s.code;height&e.code;.
- If &s.code;sync&e.code; is TRUE the driver should not return
- from this function until it is through reading the data
- from &s.code;buf&e.code;. Returning when &s.code;sync&e.code;
- is TRUE indicates that it is safe for the data at &s.code;buf&e.code;
- to be replaced, freed, or modified.
-
- </quote>
-
- &s.code;typedef int (* QueryImageAttributesFuncPtr)( ScrnInfoPtr pScrn,
- &f.indent;int image, short *width, short *height,
- &f.indent;int *pitches, int *offsets)&e.code;
- <quote><p>
- This function is called to let the driver specify how data for
- a particular &s.code;image&e.code; of size &s.code;width&e.code;
- by &s.code;height&e.code; should be stored. Sometimes only
- the size and corrected width and height are needed. In that
- case &s.code;pitches&e.code; and &s.code;offsets&e.code; are
- NULL. The size of the memory required for the image is returned
- by this function. The &s.code;width&e.code; and
- &s.code;height&e.code; of the requested image can be altered by
- the driver to reflect format limitations (such as component
- sampling periods that are larger than one). If
- &s.code;pitches&e.code; and &s.code;offsets&e.code; are not NULL,
- these will be arrays with as many elements in them as there
- are planes in the &s.code;image&e.code; format. The driver
- should specify the pitch (in bytes) of each scanline in the
- particular plane as well as the offset to that plane (in bytes)
- from the beginning of the image.
-
- </quote>
-
- </quote>
-
-The XF86VideoEncodingRec:
-<quote><p>
-<verb>
-typedef struct {
- int id;
- char *name;
- unsigned short width, height;
- XvRationalRec rate;
-} XF86VideoEncodingRec, *XF86VideoEncodingPtr;
-
-</verb>
- The &s.code;XF86VideoEncodingRec&e.code; specifies what encodings
- the adaptor can support. Most of this data is just informational
- and for the client's benefit, and is what will be reported by
- &s.code;XvQueryEncodings&e.code;. The &s.code;id&e.code; field is
- expected to be a unique identifier to allow the client to request a
- certain encoding via the &s.code;XV_ENCODING&e.code; attribute string.
-
-</quote>
-
-The XF86VideoFormatRec:
-
-<quote><p>
-<verb>
-typedef struct {
- char depth;
- short class;
-} XF86VideoFormatRec, *XF86VideoFormatPtr;
-</verb>
-
- This specifies what visuals the video is viewable in.
- &s.code;depth&e.code; is the depth of the visual (not bpp).
- &s.code;class&e.code; is the visual class such as
- &s.code;TrueColor&e.code;, &s.code;DirectColor&e.code; or
- &s.code;PseudoColor&e.code;. Initialization of an adaptor will fail
- if none of the visuals on that screen are supported.
-
-</quote>
-
-The XF86AttributeRec:
-
-<quote><p>
-<verb>
-typedef struct {
- int flags;
- int min_value;
- int max_value;
- char *name;
-} XF86AttributeListRec, *XF86AttributeListPtr;
-
-</verb>
-
- Each adaptor may have an array of these advertising the attributes
- for its ports. Currently defined flags are &s.code;XvGettable&e.code;
- and &s.code;XvSettable&e.code; which may be OR'd together indicating that
- attribute is ``gettable'' or ``settable'' by the client. The
- &s.code;min&e.code; and &s.code;max&e.code; field specify the valid range
- for the value. &s.code;Name&e.code; is a text string describing the
- attribute by name.
-
-</quote>
-
-The XF86ImageRec:
-
-<quote><p>
-<verb>
-typedef struct {
- int id;
- int type;
- int byte_order;
- char guid[16];
- int bits_per_pixel;
- int format;
- int num_planes;
-
- /* for RGB formats */
- int depth;
- unsigned int red_mask;
- unsigned int green_mask;
- unsigned int blue_mask;
-
- /* for YUV formats */
- unsigned int y_sample_bits;
- unsigned int u_sample_bits;
- unsigned int v_sample_bits;
- unsigned int horz_y_period;
- unsigned int horz_u_period;
- unsigned int horz_v_period;
- unsigned int vert_y_period;
- unsigned int vert_u_period;
- unsigned int vert_v_period;
- char component_order[32];
- int scanline_order;
-} XF86ImageRec, *XF86ImagePtr;
-</verb>
-
- XF86ImageRec describes how video source data is laid out in memory.
- The fields are as follows:
-
- &s.code;id&e.code;
- <quote><p>
- This is a unique descriptor for the format. It is often good to
- set this value to the FOURCC for the format when applicable.
- </quote>
-
- &s.code;type&e.code;
- <quote><p>
- This is &s.code;XvRGB&e.code; or &s.code;XvYUV&e.code;.
- </quote>
-
- &s.code;byte_order&e.code;
- <quote><p>
- This is &s.code;LSBFirst&e.code; or &s.code;MSBFirst&e.code;.
- </quote>
-
- &s.code;guid&e.code;
- <quote><p>
- This is the Globally Unique IDentifier for the format. When
- not applicable, all characters should be NULL.
- </quote>
-
- &s.code;bits_per_pixel&e.code;
- <quote><p>
- The number of bits taken up (but not necessarily used) by each
- pixel. Note that for some planar formats which have fractional
- bits per pixel (such as IF09) this number may be rounded _down_.
- </quote>
-
- &s.code;format&e.code;
- <quote><p>
- This is &s.code;XvPlanar&e.code; or &s.code;XvPacked&e.code;.
- </quote>
-
- &s.code;num_planes&e.code;
- <quote><p>
- The number of planes in planar formats. This should be set to
- one for packed formats.
- </quote>
-
- &s.code;depth&e.code;
- <quote><p>
- The significant bits per pixel in RGB formats (analgous to the
- depth of a pixmap format).
- </quote>
-
- &s.code;red_mask&e.code;
- &s.code;green_mask&e.code;
- &s.code;blue_mask&e.code;
- <quote><p>
- The red, green and blue bitmasks for packed RGB formats.
- </quote>
-
- &s.code;y_sample_bits&e.code;
- &s.code;u_sample_bits&e.code;
- &s.code;v_sample_bits&e.code;
- <quote><p>
- The y, u and v sample sizes (in bits).
- </quote>
-
- &s.code;horz_y_period&e.code;
- &s.code;horz_u_period&e.code;
- &s.code;horz_v_period&e.code;
- <quote><p>
- The y, u and v sampling periods in the horizontal direction.
- </quote>
-
- &s.code;vert_y_period&e.code;
- &s.code;vert_u_period&e.code;
- &s.code;vert_v_period&e.code;
- <quote><p>
- The y, u and v sampling periods in the vertical direction.
- </quote>
-
- &s.code;component_order&e.code;
- <quote><p>
- Uppercase ascii characters representing the order that
- samples are stored within packed formats. For planar formats
- this represents the ordering of the planes. Unused characters
- in the 32 byte string should be set to NULL.
- </quote>
-
- &s.code;scanline_order&e.code;
- <quote><p>
- This is &s.code;XvTopToBottom&e.code; or &s.code;XvBottomToTop&e.code;.
- </quote>
-
- Since some formats (particular some planar YUV formats) may not
-be completely defined by the parameters above, the guid, when
-available, should provide the most accurate description of the
-format.
-
-</quote>
-
-<sect>The Loader
-<p>
-
-This section describes the interfaces to the module loader. The loader
-interfaces can be divided into two groups: those that are only available to
-the XFree86 common layer, and those that are also available to modules.
-
-<sect1>Loader Overview
-<p>
-
-The loader is capable of loading modules in a range of object formats,
-and knowledge of these formats is built in to the loader. Knowledge of
-new object formats can be added to the loader in a straightforward
-manner. This makes it possible to provide OS-independent modules (for
-a given CPU architecture type). In addition to this, the loader can
-load modules via the OS-provided &s.code;dlopen(3)&e.code; service where
-available. Such modules are not platform independent, and the semantics
-of &s.code;dlopen()&e.code; on most systems results in significant
-limitations in the use of modules of this type. Support for
-&s.code;dlopen()&e.code; modules in the loader is primarily for
-experimental and development purposes.
-
-Symbols exported by the loader (on behalf of the core X server) to
-modules are determined at compile time. Only those symbols explicitly
-exported are available to modules. All external symbols of loaded
-modules are exported to other modules, and to the core X server. The
-loader can be requested to check for unresolved symbols at any time,
-and the action to be taken for unresolved symbols can be controlled by
-the caller of the loader. Typically the caller identifies which symbols
-can safely remain unresolved and which cannot.
-
-NOTE: Now that ISO-C allows pointers to functions and pointers to data to
-have different internal representations, some of the following interfaces
-will need to be revisited.
-
-<sect1>Semi-private Loader Interface
-<p>
-
-The following is the semi-private loader interface that is available to the
-XFree86 common layer.
-
- <quote><p>
- &s.code;void LoaderInit(void)&e.code;
- <quote><p>
- The &s.code;LoaderInit()&e.code; function initialises the loader,
- and it must be called once before calling any other loader functions.
- This function initialises the tables of exported symbols, and anything
- else that might need to be initialised.
-
- </quote>
-
- &s.code;void LoaderSetPath(const char *path)&e.code;
- <quote><p>
- The &s.code;LoaderSetPath()&e.code; function initialises a default
- module search path. This must be called if calls to other functions
- are to be made without explicitly specifying a module search path.
- The search path &s.code;path&e.code; must be a string of one or more
- comma separated absolute paths. Modules are expected to be located
- below these paths, possibly in subdirectories of these paths.
-
- </quote>
-
- &s.code;pointer LoadModule(const char *module, const char *path,
- &f.indent;const char **subdirlist, const char **patternlist,
- &f.indent;pointer options, const XF86ModReqInfo * modreq,
- &f.indent;int *errmaj, int *errmin)&e.code;
- <quote><p>
- The &s.code;LoadModule()&e.code; function loads the module called
- &s.code;module&e.code;. The return value is a module handle, and
- may be used in future calls to the loader that require a reference
- to a loaded module. The module name &s.code;module&e.code; is
- normally the module's canonical name, which doesn't contain any
- directory path information, or any object/library file prefixes of
- suffixes. Currently a full pathname and/or filename is also accepted.
- This might change. The other parameters are:
-
- &s.code;path&e.code;
- <quote><p>
- An optional comma-separated list of module search paths.
- When &s.code;NULL&e.code;, the default search path is used.
-
- </quote>
-
- &s.code;subdirlist&e.code;
- <quote><p>
- An optional &s.code;NULL&e.code; terminated list of
- subdirectories to search. When &s.code;NULL&e.code;,
- the default built-in list is used (refer to
- &s.code;stdSubdirs&e.code; in &s.code;loadmod.c&e.code;).
- The default list is also substituted for entries in
- &s.code;subdirlist&e.code; with the value
- &s.code;DEFAULT_LIST&e.code;. This makes is possible
- to augment the default list instead of replacing it.
- Subdir elements must be relative, and must not contain
- &s.code;".."&e.code;. If any violate this requirement,
- the load fails.
-
- </quote>
-
- &s.code;patternlist&e.code;
- <quote><p>
- An optional &s.code;NULL&e.code; terminated list of
- POSIX regular expressions used to connect module
- filenames with canonical module names. Each regex
- should contain exactly one subexpression that corresponds
- to the canonical module name. When &s.code;NULL&e.code;,
- the default built-in list is used (refer to
- &s.code;stdPatterns&e.code; in
- &s.code;loadmod.c&e.code;). The default list is also
- substituted for entries in &s.code;patternlist&e.code;
- with the value &s.code;DEFAULT_LIST&e.code;. This
- makes it possible to augment the default list instead
- of replacing it.
-
- </quote>
-
- &s.code;options&e.code;
- <quote><p>
- An optional parameter that is passed to the newly
- loaded module's &s.code;SetupProc&e.code; function
- (if it has one). This argument is normally a
- &s.code;NULL&e.code; terminated list of
- &s.code;Options&e.code;, and must be interpreted that
- way by modules loaded directly by the XFree86 common
- layer. However, it may be used for application-specific
- parameter passing in other situations.
-
- When loading ``external'' modules (modules that don't
- have the standard entry point, for example a
- special shared library) the options parameter can be
- set to &s.code;EXTERN_MODULE&e.code; to tell the
- loader not to reject the module when it doesn't find
- the standard entry point.
-
- </quote>
-
- &s.code;modreq&e.code;
- <quote><p>
- An optional &s.code;XF86ModReqInfo*&e.code; containing
- version/ABI/vendor information to requirements to
- check the newly loaded module against. The main
- purpose of this is to allow the loader to verify that
- a module of the correct type/version before running
- its &s.code;SetupProc&e.code; function.
-
- The &s.code;XF86ModReqInfo&e.code; struct is defined
- as follows:
-<verb>
-typedef struct {
- CARD8 majorversion; /* MAJOR_UNSPEC */
- CARD8 minorversion; /* MINOR_UNSPEC */
- CARD16 patchlevel; /* PATCH_UNSPEC */
- const char * abiclass; /* ABI_CLASS_NONE */
- CARD32 abiversion; /* ABI_VERS_UNSPEC */
- const char * moduleclass; /* MOD_CLASS_NONE */
-} XF86ModReqInfo;
-</verb>
-
- The information here is compared against the equivalent
- information in the module's
- &s.code;XF86ModuleVersionInfo&e.code; record (which
- is described below). The values in comments above
- indicate ``don't care'' settings for each of the fields.
- The comparisons made are as follows:
-
- &s.code;majorversion&e.code;
- <quote><p>
- Must match the module's majorversion
- exactly.
-
- </quote>
- &s.code;minorversion&e.code;
- <quote><p>
- The module's minor version must be
- no less than this value. This
- comparison is only made if
- &s.code;majorversion&e.code; is
- specified and matches.
-
- </quote>
- &s.code;patchlevel&e.code;
- <quote><p>
- The module's patchlevel must be no
- less than this value. This comparison
- is only made if
- &s.code;minorversion&e.code; is
- specified and matches.
-
- </quote>
- &s.code;abiclass&e.code;
- <quote><p>
- String must match the module's abiclass
- string.
-
- </quote>
- &s.code;abiversion&e.code;
- <quote><p>
- Must be consistent with the module's
- abiversion (major equal, minor no
- older).
-
- </quote>
- &s.code;moduleclass&e.code;
- <quote><p>
- String must match the module's
- moduleclass string.
-
- </quote>
-
- </quote>
-
- &s.code;errmaj&e.code;
- <quote><p>
- An optional pointer to a variable holding the major
- part or the error code. When provided,
- &s.code;*errmaj&e.code; is filled in when
- &s.code;LoadModule()&e.code; fails.
-
- </quote>
-
- &s.code;errmin&e.code;
- <quote><p>
- Like &s.code;errmaj&e.code;, but for the minor part
- of the error code.
-
- </quote>
-
- </quote>
-
- &s.code;void UnloadModule(pointer mod)&e.code;
- <quote><p>
- This function unloads the module referred to by the handle mod.
- All child modules are also unloaded recursively. This function must
- not be used to directly unload modules that are child modules (i.e.,
- those that have been loaded with the &s.code;LoadSubModule()&e.code;
- described below).
-
- </quote>
- </quote>
-
-<sect1>Module Requirements
-<p>
-
-Modules must provide information about themselves to the loader, and
-may optionally provide entry points for "setup" and "teardown" functions
-(those two functions are referred to here as &s.code;SetupProc&e.code;
-and &s.code;TearDownProc&e.code;).
-
-The module information is contained in the
-&s.code;XF86ModuleVersionInfo&e.code; struct, which is defined as follows:
-
-<quote><p><verb>
-typedef struct {
- const char * modname; /* name of module, e.g. "foo" */
- const char * vendor; /* vendor specific string */
- CARD32 _modinfo1_; /* constant MODINFOSTRING1/2 to find */
- CARD32 _modinfo2_; /* infoarea with a binary editor/sign tool */
- CARD32 xf86version; /* contains XF86_VERSION_CURRENT */
- CARD8 majorversion; /* module-specific major version */
- CARD8 minorversion; /* module-specific minor version */
- CARD16 patchlevel; /* module-specific patch level */
- const char * abiclass; /* ABI class that the module uses */
- CARD32 abiversion; /* ABI version */
- const char * moduleclass; /* module class */
- CARD32 checksum[4]; /* contains a digital signature of the */
- /* version info structure */
-} XF86ModuleVersionInfo;
-</verb>
-
-The fields are used as follows:
-
- &s.code;modname&e.code;
- <quote><p>
- The module's name. This field is currently only for
- informational purposes, but the loader may be modified
- in future to require it to match the module's canonical
- name.
-
- </quote>
-
- &s.code;vendor&e.code;
- <quote><p>
- The module vendor. This field is for informational purposes
- only.
-
- </quote>
-
- &s.code;_modinfo1_&e.code;
- <quote><p>
- This field holds the first part of a signature that can
- be used to locate this structure in the binary. It should
- always be initialised to &s.code;MODINFOSTRING1&e.code;.
-
- </quote>
-
- &s.code;_modinfo2_&e.code;
- <quote><p>
- This field holds the second part of a signature that can
- be used to locate this structure in the binary. It should
- always be initialised to &s.code;MODINFOSTRING2&e.code;.
-
- </quote>
-
- &s.code;xf86version&e.code;
- <quote><p>
- The XFree86 version against which the module was compiled.
- This is mostly for informational/diagnostic purposes. It
- should be initialised to &s.code;XF86_VERSION_CURRENT&e.code;, which is
- defined in &s.code;xf86Version.h&e.code;.
-
- </quote>
-
- &s.code;majorversion&e.code;
- <quote><p>
- The module-specific major version. For modules where this
- version is used for more than simply informational
- purposes, the major version should only change (be
- incremented) when ABI incompatibilities are introduced,
- or ABI components are removed.
-
- </quote>
-
- &s.code;minorversion&e.code;
- <quote><p>
- The module-specific minor version. For modules where this
- version is used for more than simply informational
- purposes, the minor version should only change (be
- incremented) when ABI additions are made in a backward
- compatible way. It should be reset to zero when the major
- version is increased.
-
- </quote>
-
- &s.code;patchlevel&e.code;
- <quote><p>
- The module-specific patch level. The patch level should
- increase with new revisions of the module where there
- are no ABI changes, and it should be reset to zero when
- the minor version is increased.
-
- </quote>
-
- &s.code;abiclass&e.code;
- <quote><p>
- The ABI class that the module requires. The class is
- specified as a string for easy extensibility. It should
- indicate which (if any) of the X server's built-in ABI
- classes that the module relies on, or a third-party ABI
- if appropriate. Built-in ABI classes currently defined are:
-
- <quote>
- &s.code;ABI_CLASS_NONE&e.code;
- <quote>no class</quote>
- &s.code;ABI_CLASS_ANSIC&e.code;
- <quote>only requires the ANSI C interfaces</quote>
- &s.code;ABI_CLASS_VIDEODRV&e.code;
- <quote>requires the video driver ABI</quote>
- &s.code;ABI_CLASS_XINPUT&e.code;
- <quote>requires the XInput driver ABI</quote>
- &s.code;ABI_CLASS_EXTENSION&e.code;
- <quote>requires the extension module ABI</quote>
- &s.code;ABI_CLASS_FONT&e.code;
- <quote>requires the font module ABI</quote>
- </quote>
-
- </quote>
-
- &s.code;abiversion&e.code;
- <quote><p>
- The version of abiclass that the module requires. The
- version consists of major and minor components. The
- major version must match and the minor version must be
- no newer than that provided by the server or parent
- module. Version identifiers for the built-in classes
- currently defined are:
-
- <quote>
- &s.code;ABI_ANSIC_VERSION&nl;
- ABI_VIDEODRV_VERSION&nl;
- ABI_XINPUT_VERSION&nl;
- ABI_EXTENSION_VERSION&nl;
- ABI_FONT_VERSION&e.code;
- </quote>
-
- </quote>
-
- &s.code;moduleclass&e.code;
- <quote><p>
- This is similar to the abiclass field, except that it
- defines the type of module rather than the ABI it
- requires. For example, although all video drivers require
- the video driver ABI, not all modules that require the
- video driver ABI are video drivers. This distinction
- can be made with the moduleclass. Currently pre-defined
- module classes are:
-
- <quote>
- &s.code;MOD_CLASS_NONE&nl;
- MOD_CLASS_VIDEODRV&nl;
- MOD_CLASS_XINPUT&nl;
- MOD_CLASS_FONT&nl;
- MOD_CLASS_EXTENSION&e.code;
- </quote>
-
- </quote>
-
- &s.code;checksum&e.code;
- <quote><p>
- Not currently used.
-
- </quote>
-
-</quote>
-
-The module version information, and the optional &s.code;SetupProc&e.code;
-and &s.code;TearDownProc&e.code; entry points are found by the loader
-by locating a data object in the module called "modnameModuleData",
-where "modname" is the canonical name of the module. Modules must
-contain such a data object, and it must be declared with global scope,
-be compile-time initialised, and is of the following type:
-
-<quote>
-<verb>
-typedef struct {
- XF86ModuleVersionInfo * vers;
- ModuleSetupProc setup;
- ModuleTearDownProc teardown;
-} XF86ModuleData;
-</verb>
-</quote>
-
-The vers parameter must be initialised to a pointer to a correctly
-initialised &s.code;XF86ModuleVersionInfo&e.code; struct. The other
-two parameter are optional, and should be initialised to
-&s.code;NULL&e.code; when not required. The other parameters are defined
-as
-
- <quote><p>
- &s.code;typedef pointer (*ModuleSetupProc)(pointer, pointer, int *, int *)&e.code;
-
- &s.code;typedef void (*ModuleTearDownProc)(pointer)&e.code;
-
-
- &s.code;pointer SetupProc(pointer module, pointer options,
- &f.indent;int *errmaj, int *errmin)&e.code;
- <quote><p>
- When defined, this function is called by the loader after successfully
- loading a module. module is a handle for the newly loaded module,
- and maybe used by the &s.code;SetupProc&e.code; if it calls other
- loader functions that require a reference to it. The remaining
- arguments are those that were passed to the
- &s.code;LoadModule()&e.code; (or &s.code;LoadSubModule()&e.code;),
- and are described above. When the &s.code;SetupProc&e.code; is
- successful it must return a non-&s.code;NULL&e.code; value. The
- loader checks this, and if it is &s.code;NULL&e.code; it unloads
- the module and reports the failure to the caller of
- &s.code;LoadModule()&e.code;. If the &s.code;SetupProc&e.code;
- does things that need to be undone when the module is unloaded,
- it should define a &s.code;TearDownProc&e.code;, and return a
- pointer that the &s.code;TearDownProc&e.code; can use to undo what
- has been done.
-
- When a module is loaded multiple times, the &s.code;SetupProc&e.code;
- is called once for each time it is loaded.
-
- </quote>
-
- &s.code;void TearDownProc(pointer tearDownData)&e.code;
- <quote><p>
- When defined, this function is called when the loader unloads a
- module. The &s.code;tearDownData&e.code; parameter is the return
- value of the &s.code;SetupProc()&e.code; that was called when the
- module was loaded. The purpose of this function is to clean up
- before the module is unloaded (for example, by freeing allocated
- resources).
-
- </quote>
- </quote>
-
-<sect1>Public Loader Interface
-<p>
-
-The following is the Loader interface that is available to any part of
-the server, and may also be used from within modules.
-
- <quote><p>
- &s.code;pointer LoadSubModule(pointer parent, const char *module,
- &f.indent;const char **subdirlist, const char **patternlist,
- &f.indent;pointer options, const XF86ModReqInfo * modreq,
- &f.indent;int *errmaj, int *errmin)&e.code;
- <quote><p>
- This function is like the &s.code;LoadModule()&e.code; function
- described above, except that the module loaded is registered as a
- child of the calling module. The &s.code;parent&e.code; parameter
- is the calling module's handle. Modules loaded with this function
- are automatically unloaded when the parent module is unloaded. The
- other difference is that the path parameter may not be specified.
- The module search path used for modules loaded with this function
- is the default search path as initialised with
- &s.code;LoaderSetPath()&e.code;.
-
- </quote>
-
- &s.code;void UnloadSubModule(pointer module)&e.code;
- <quote><p>
- This function unloads the module with handle &s.code;module&e.code;.
- If that module itself has children, they are also unloaded. It is
- like &s.code;UnloadModule()&e.code;, except that it is safe to use
- for unloading child modules.
-
- </quote>
-
- &s.code;pointer LoaderSymbol(const char *symbol)&e.code;
- <quote><p>
- This function returns the address of the symbol with name
- &s.code;symbol&e.code;. This may be used to locate a module entry
- point with a known name.
-
- </quote>
-
- &s.code;char **LoaderlistDirs(const char **subdirlist,
- &f.indent;const char **patternlist)&e.code;
- <quote><p>
- This function returns a &s.code;NULL&e.code; terminated list of
- canonical modules names for modules found in the default module
- search path. The &s.code;subdirlist&e.code; and
- &s.code;patternlist&e.code; parameters are as described above, and
- can be used to control the locations and names that are searched.
- If no modules are found, the return value is &s.code;NULL&e.code;.
- The returned list should be freed by calling
- &s.code;LoaderFreeDirList()&e.code; when it is no longer needed.
-
- </quote>
-
- &s.code;void LoaderFreeDirList(char **list)&e.code;
- <quote><p>
- This function frees a module list created by
- &s.code;LoaderlistDirs()&e.code;.
-
- </quote>
-
- &s.code;void LoaderReqSymLists(const char **list0, ...)&e.code;
- <quote><p>
- This function allows the registration of required symbols with the
- loader. It is normally used by a caller of
- &s.code;LoadSubModule()&e.code;. If any symbols registered in this
- way are found to be unresolved when
- &s.code;LoaderCheckUnresolved()&e.code; is called then
- &s.code;LoaderCheckUnresolved()&e.code; will report a failure.
- The function takes one or more &s.code;NULL&e.code; terminated
- lists of symbols. The end of the argument list is indicated by a
- &s.code;NULL&e.code; argument.
-
- </quote>
-
- &s.code;void LoaderReqSymbols(const char *sym0, ...)&e.code;
- <quote><p>
- This function is like &s.code;LoaderReqSymLists()&e.code; except
- that its arguments are symbols rather than lists of symbols. This
- function is more convenient when single functions are to be registered,
- especially when the single function might depend on runtime factors.
- The end of the argument list is indicated by a &s.code;NULL&e.code;
- argument.
-
- </quote>
-
- &s.code;void LoaderRefSymLists(const char **list0, ...)&e.code;
- <quote><p>
- This function allows the registration of possibly unresolved symbols
- with the loader. When &s.code;LoaderCheckUnresolved()&e.code; is
- run it won't generate warnings for symbols registered in this way
- unless they were also registered as required symbols.
- The function takes one or more &s.code;NULL&e.code; terminated
- lists of symbols. The end of the argument list is indicated by a
- &s.code;NULL&e.code; argument.
-
- </quote>
-
- &s.code;void LoaderRefSymbols(const char *sym0, ...)&e.code;
- <quote><p>
- This function is like &s.code;LoaderRefSymLists()&e.code; except
- that its arguments are symbols rather than lists of symbols. This
- function is more convenient when single functions are to be registered,
- especially when the single function might depend on runtime factors.
- The end of the argument list is indicated by a &s.code;NULL&e.code;
- argument.
-
- </quote>
-
- &s.code;int LoaderCheckUnresolved(int delayflag)&e.code;
- <quote><p>
- This function checks for unresolved symbols. It generates warnings
- for unresolved symbols that have not been registered with
- &s.code;LoaderRefSymLists()&e.code;, and maps them to a dummy
- function. This behaviour may change in future. If unresolved
- symbols are found that have been registered with
- &s.code;LoaderReqSymLists()&e.code; or
- &s.code;LoaderReqSymbols()&e.code; then this function returns a
- non-zero value. If none of these symbols are unresolved the return
- value is zero, indicating success.
-
- The &s.code;delayflag&e.code; parameter should normally be set to
- &s.code;LD_RESOLV_IFDONE&e.code;.
-
- </quote>
-
- &s.code;LoaderErrorMsg(const char *name, const char *modname,
- &f.indent;int errmaj, int errmin)&e.code;
- <quote><p>
- This function prints an error message that includes the text ``Failed
- to load module'', the module name &s.code;modname&e.code;, a message
- specific to the &s.code;errmaj&e.code; value, and the value if
- &s.code;errmin&e.code;. If &s.code;name&e.code; is
- non-&s.code;NULL&e.code;, it is printed as an identifying prefix
- to the message (followed by a `:').
-
- </quote>
- </quote>
-
-<sect1>Special Registration Functions
-<p>
-
-The loader contains some functions for registering some classes of modules.
-These may be moved out of the loader at some point.
-
- <quote><p>
- &s.code;void LoadExtension(ExtensionModule *ext)&e.code;
- <quote><p>
- This registers the entry points for the extension identified by
- &s.code;ext&e.code;. The &s.code;ExtensionModule&e.code; struct is
- defined as:
-
-<quote>
-<verb>
-typedef struct {
- InitExtension initFunc;
- char * name;
- Bool *disablePtr;
- InitExtension setupFunc;
-} ExtensionModule;
-</verb>
-</quote>
-
- </quote>
-
- &s.code;void LoadFont(FontModule *font)&e.code;
- <quote><p>
- This registers the entry points for the font rasteriser module
- identified by &s.code;font&e.code;. The &s.code;FontModule&e.code;
- struct is defined as:
-
-<quote>
-<verb>
-typedef struct {
- InitFont initFunc;
- char * name;
- pointer module;
-} FontModule;
-</verb>
-</quote>
-
- </quote>
- </quote>
-
-</sect>
-
-
-<sect>Helper Functions
-<p>
-
-This section describe ``helper'' functions that video driver
-might find useful. While video drivers are not required to use any of
-these to be considered ``compliant'', the use of appropriate helpers is
-strongly encouraged to improve the consistency of driver behaviour.
-
-<sect1>Functions for printing messages
-<p>
-
- <quote><p>
- &s.code;ErrorF(const char *format, ...)&e.code;
- <quote><p>
- This is the basic function for writing to the error log (typically
- stderr and/or a log file). Video drivers should usually avoid
- using this directly in favour of the more specialised functions
- described below. This function is useful for printing messages
- while debugging a driver.
-
- </quote>
-
- &s.code;FatalError(const char *format, ...)&e.code;
- <quote><p>
- This prints a message and causes the Xserver to abort. It should
- rarely be used within a video driver, as most error conditions
- should be flagged by the return values of the driver functions.
- This allows the higher layers to decide how to proceed. In rare
- cases, this can be used within a driver if a fatal unexpected
- condition is found.
-
- </quote>
-
- &s.code;xf86ErrorF(const char *format, ...)&e.code;
- <quote><p>
- This is like &s.code;ErrorF()&e.code;, except that the message is
- only printed when the Xserver's verbosity level is set to the
- default (&s.code;1&e.code;) or higher. It means that the messages
- are not printed when the server is started with the
- &s.cmd;-quiet&e.cmd; flag. Typically this function would only be
- used for continuing messages started with one of the more specialised
- functions described below.
-
- </quote>
-
- &s.code;xf86ErrorFVerb(int verb, const char *format, ...)&e.code;
- <quote><p>
- Like &s.code;xf86ErrorF()&e.code;, except the minimum verbosity
- level for which the message is to be printed is given explicitly.
- Passing a &s.code;verb&e.code; value of zero means the message
- is always printed. A value higher than &s.code;1&e.code; can be
- used for information would normally not be needed, but which might
- be useful when diagnosing problems.
-
- </quote>
-
- &s.code;xf86Msg(MessageType type, const char *format, ...)&e.code;
- <quote><p>
- This is like &s.code;xf86ErrorF()&e.code;, except that the message
- is prefixed with a marker determined by the value of
- &s.code;type&e.code;. The marker is used to indicate the type of
- message (warning, error, probed value, config value, etc). Note
- the &s.code;xf86Verbose&e.code; value is ignored for messages of
- type &s.code;X_ERROR&e.code;.
-
- The marker values are:
-
- <quote>
- &s.code;X_PROBED&e.code;
- <quote>Value was probed.</quote>
- &s.code;X_CONFIG&e.code;
- <quote>Value was given in the config file.</quote>
- &s.code;X_DEFAULT&e.code;
- <quote>Value is a default.</quote>
- &s.code;X_CMDLINE&e.code;
- <quote>Value was given on the command line.</quote>
- &s.code;X_NOTICE&e.code;
- <quote>Notice.</quote>
- &s.code;X_ERROR&e.code;
- <quote>Error message.</quote>
- &s.code;X_WARNING&e.code;
- <quote>Warning message.</quote>
- &s.code;X_INFO&e.code;
- <quote>Informational message.</quote>
- &s.code;X_NONE&e.code;
- <quote>No prefix.</quote>
- &s.code;X_NOT_IMPLEMENTED&e.code;
- <quote>The message relates to functionality that is not yet
- implemented.</quote>
- </quote>
-
-
- </quote>
-
- &s.code;xf86MsgVerb(MessageType type, int verb, const char *format, ...)&e.code;
- <quote><p>
- Like &s.code;xf86Msg()&e.code;, but with the verbosity level given
- explicitly.
-
- </quote>
-
- &s.code;xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)&e.code;
- <quote><p>
- This is like &s.code;xf86Msg()&e.code; except that the driver's
- name (the &s.code;name&e.code; field of the
- &s.code;ScrnInfoRec&e.code;) followed by the
- &s.code;scrnIndex&e.code; in parentheses is printed following the
- prefix. This should be used by video drivers in most cases as it
- clearly indicates which driver/screen the message is for. If
- &s.code;scrnIndex&e.code; is negative, this function behaves
- exactly like &s.code;xf86Msg()&e.code;.
-
- NOTE: This function can only be used after the
- &s.code;ScrnInfoRec&e.code; and its &s.code;name&e.code; field
- have been allocated. Normally, this means that it can not be
- used before the END of the &s.code;ChipProbe()&e.code; function.
- Prior to that, use &s.code;xf86Msg()&e.code;, providing the
- driver's name explicitly. No screen number can be supplied at
- that point.
-
- </quote>
-
- &s.code;xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
- &f.indent;const char *format, ...)&e.code;
- <quote><p>
- Like &s.code;xf86DrvMsg()&e.code;, but with the verbosity level
- given explicitly.
-
- </quote>
- </quote>
-
-
-<sect1>Functions for setting values based on command line and config file
-<p>
-
- <quote><p>
- &s.code;Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp,
- &f.indent;int fbbpp, int depth24flags)&e.code;
- <quote><p>
- This function sets the &s.code;depth&e.code;, &s.code;pixmapBPP&e.code; and &s.code;bitsPerPixel&e.code; fields
- of the &s.code;ScrnInfoRec&e.code;. It also determines the defaults for display-wide
- attributes and pixmap formats the screen will support, and finds
- the Display subsection that matches the depth/bpp. This function
- should normally be called very early from the
- &s.code;ChipPreInit()&e.code; function.
-
- It requires that the &s.code;confScreen&e.code; field of the &s.code;ScrnInfoRec&e.code; be
- initialised prior to calling it. This is done by the XFree86
- common layer prior to calling &s.code;ChipPreInit()&e.code;.
-
- The parameters passed are:
-
- &s.code;depth&e.code;
- <quote><p>
- driver's preferred default depth if no other is given.
- If zero, use the overall server default.
-
- </quote>
- &s.code;bpp&e.code;
- <quote><p>
- Same, but for the pixmap bpp.
-
- </quote>
- &s.code;fbbpp&e.code;
- <quote><p>
- Same, but for the framebuffer bpp.
-
- </quote>
- &s.code;depth24flags&e.code;
- <quote><p>
- Flags that indicate the level of 24/32bpp support
- and whether conversion between different framebuffer
- and pixmap formats is supported. The flags for this
- argument are defined as follows, and multiple flags
- may be ORed together:
-
- &s.code;NoDepth24Support&e.code;
- <quote>No depth 24 formats supported</quote>
- &s.code;Support24bppFb&e.code;
- <quote>24bpp framebuffer supported</quote>
- &s.code;Support32bppFb&e.code;
- <quote>32bpp framebuffer supported</quote>
- &s.code;SupportConvert24to32&e.code;
- <quote>Can convert 24bpp pixmap to 32bpp fb</quote>
- &s.code;SupportConvert32to24&e.code;
- <quote>Can convert 32bpp pixmap to 24bpp fb</quote>
- &s.code;ForceConvert24to32&e.code;
- <quote>Force 24bpp pixmap to 32bpp fb conversion</quote>
- &s.code;ForceConvert32to24&e.code;
- <quote>Force 32bpp pixmap to 24bpp fb conversion</quote>
-
- </quote>
-
- It uses the command line, config file, and default values in the
- correct order of precedence to determine the depth and bpp values.
- It is up to the driver to check the results to see that it supports
- them. If not the &s.code;ChipPreInit()&e.code; function should
- return &s.code;FALSE&e.code;.
-
- If only one of depth/bpp is given, the other is set to a reasonable
- (and consistent) default.
-
- If a driver finds that the initial &s.code;depth24flags&e.code;
- it uses later results in a fb format that requires more video
- memory than is available it may call this function a second time
- with a different &s.code;depth24flags&e.code; setting.
-
- On success, the return value is &s.code;TRUE&e.code;. On failure
- it prints an error message and returns &s.code;FALSE&e.code;.
-
- The following fields of the &s.code;ScrnInfoRec&e.code; are
- initialised by this function:
-
- <quote>
- &s.code;depth&e.code;, &s.code;bitsPerPixel&e.code;,
- &s.code;display&e.code;, &s.code;imageByteOrder&e.code;,
- &s.code;bitmapScanlinePad&e.code;,
- &s.code;bitmapScanlineUnit&e.code;, &s.code;bitmapBitOrder&e.code;,
- &s.code;numFormats&e.code;, &s.code;formats&e.code;,
- &s.code;fbFormat&e.code;.
- </quote>
-
- </quote>
-
- &s.code;void xf86PrintDepthBpp(scrnInfoPtr scrp)&e.code;
- <quote><p>
- This function can be used to print out the depth and bpp settings.
- It should be called after the final call to
- &s.code;xf86SetDepthBpp()&e.code;.
-
- </quote>
-
- &s.code;Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)&e.code;
- <quote><p>
- This function sets the &s.code;weight&e.code;, &s.code;mask&e.code;,
- &s.code;offset&e.code; and &s.code;rgbBits&e.code; fields of the
- &s.code;ScrnInfoRec&e.code;. It would normally be called fairly
- early in the &s.code;ChipPreInit()&e.code; function for
- depths > 8bpp.
-
- It requires that the &s.code;depth&e.code; and
- &s.code;display&e.code; fields of the &s.code;ScrnInfoRec&e.code;
- be initialised prior to calling it.
-
- The parameters passed are:
-
- &s.code;weight&e.code;
- <quote><p>
- driver's preferred default weight if no other is given.
- If zero, use the overall server default.
-
- </quote>
-
- &s.code;mask&e.code;
- <quote><p>
- Same, but for mask.
-
- </quote>
-
- It uses the command line, config file, and default values in the
- correct order of precedence to determine the weight value. It
- derives the mask and offset values from the weight and the defaults.
- It is up to the driver to check the results to see that it supports
- them. If not the &s.code;ChipPreInit()&e.code; function should
- return &s.code;FALSE&e.code;.
-
- On success, this function prints a message showing the weight
- values selected, and returns &s.code;TRUE&e.code;.
-
- On failure it prints an error message and returns &s.code;FALSE&e.code;.
-
- The following fields of the &s.code;ScrnInfoRec&e.code; are
- initialised by this function:
-
- <quote>
- &s.code;weight&e.code;, &s.code;mask&e.code;, &s.code;offset&e.code;.
- </quote>
-
- </quote>
-
- &s.code;Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)&e.code;
- <quote><p>
- This function sets the &s.code;defaultVisual&e.code; field of the
- &s.code;ScrnInfoRec&e.code;. It would normally be called fairly
- early from the &s.code;ChipPreInit()&e.code; function.
-
- It requires that the &s.code;depth&e.code; and
- &s.code;display&e.code; fields of the &s.code;ScrnInfoRec&e.code;
- be initialised prior to calling it.
-
- The parameters passed are:
-
- &s.code;visual&e.code;
- <quote><p>
- driver's preferred default visual if no other is given.
- If &s.code;-1&e.code;, use the overall server default.
-
- </quote>
-
- It uses the command line, config file, and default values in the
- correct order of precedence to determine the default visual value.
- It is up to the driver to check the result to see that it supports
- it. If not the &s.code;ChipPreInit()&e.code; function should
- return &s.code;FALSE&e.code;.
-
- On success, this function prints a message showing the default visual
- selected, and returns &s.code;TRUE&e.code;.
-
- On failure it prints an error message and returns &s.code;FALSE&e.code;.
-
- </quote>
-
- &s.code;Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)&e.code;
- <quote><p>
- This function sets the &s.code;gamma&e.code; field of the
- &s.code;ScrnInfoRec&e.code;. It would normally be called fairly
- early from the &s.code;ChipPreInit()&e.code; function in cases
- where the driver supports gamma correction.
-
- It requires that the &s.code;monitor&e.code; field of the
- &s.code;ScrnInfoRec&e.code; be initialised prior to calling it.
-
- The parameters passed are:
-
- &s.code;gamma&e.code;
- <quote><p>
- driver's preferred default gamma if no other is given.
- If zero (&s.code;< 0.01&e.code;), use the overall server
- default.
-
- </quote>
-
- It uses the command line, config file, and default values in the
- correct order of precedence to determine the gamma value. It is
- up to the driver to check the results to see that it supports
- them. If not the &s.code;ChipPreInit()&e.code; function should
- return &s.code;FALSE&e.code;.
-
- On success, this function prints a message showing the gamma
- value selected, and returns &s.code;TRUE&e.code;.
-
- On failure it prints an error message and returns &s.code;FALSE&e.code;.
-
- </quote>
-
- &s.code;void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)&e.code;
- <quote><p>
- This function sets the &s.code;xDpi&e.code; and &s.code;yDpi&e.code;
- fields of the &s.code;ScrnInfoRec&e.code;. The driver can specify
- preferred defaults by setting &s.code;x&e.code; and &s.code;y&e.code;
- to non-zero values. The &s.cmd;-dpi&e.cmd; command line option
- overrides all other settings. Otherwise, if the
- &s.key;DisplaySize&e.key; entry is present in the screen's &k.monitor;
- config file section, it is used together with the virtual size to
- calculate the dpi values. This function should be called after
- all the mode resolution has been done.
-
- </quote>
-
- &s.code;void xf86SetBlackWhitePixels(ScrnInfoPtr pScrn)&e.code;
- <quote><p>
- This functions sets the &s.code;blackPixel&e.code; and
- &s.code;whitePixel&e.code; fields of the &s.code;ScrnInfoRec&e.code;
- according to whether or not the &s.cmd;-flipPixels&e.cmd; command
- line options is present.
-
- </quote>
-
- &s.code;const char *xf86GetVisualName(int visual)&e.code;
- <quote><p>
- Returns a printable string with the visual name matching the
- numerical visual class provided. If the value is outside the
- range of valid visual classes, &s.code;NULL&e.code; is returned.
-
- </quote>
- </quote>
-
-
-<sect1>Primary Mode functions
-<p>
-
-The primary mode helper functions are those which would normally be
-used by a driver, unless it has unusual requirements which cannot
-be catered for the by the helpers.
-
- <quote><p>
- &s.code;int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
- &f.indent;char **modeNames, ClockRangePtr clockRanges,
- &f.indent;int *linePitches, int minPitch, int maxPitch,
- &f.indent;int pitchInc, int minHeight, int maxHeight,
- &f.indent;int virtualX, int virtualY,
- &f.indent;unsigned long apertureSize,
- &f.indent;LookupModeFlags strategy)&e.code;
- <quote><p>
- This function basically selects the set of modes to use based on
- those available and the various constraints. It also sets some
- other related parameters. It is normally called near the end of
- the &s.code;ChipPreInit()&e.code; function.
-
- The parameters passed to the function are:
-
- &s.code;availModes&e.code;
- <quote><p>
- List of modes available for the monitor.
-
- </quote>
- &s.code;modeNames&e.code;
- <quote><p>
- List of mode names that the screen is requesting.
-
- </quote>
- &s.code;clockRanges&e.code;
- <quote><p>
- A list of clock ranges allowed by the driver. Each
- range includes whether interlaced or multiscan modes
- are supported for that range. See below for more on
- &s.code;clockRanges&e.code;.
-
- </quote>
- &s.code;linePitches&e.code;
- <quote><p>
- List of line pitches supported by the driver.
- This is optional and should be &s.code;NULL&e.code; when
- not used.
-
- </quote>
- &s.code;minPitch&e.code;
- <quote><p>
- Minimum line pitch supported by the driver. This must
- be supplied when &s.code;linePitches&e.code; is
- &s.code;NULL&e.code;, and is ignored otherwise.
-
- </quote>
- &s.code;maxPitch&e.code;
- <quote><p>
- Maximum line pitch supported by the driver. This is
- required when &s.code;minPitch&e.code; is required.
-
- </quote>
- &s.code;pitchInc&e.code;
- <quote><p>
- Granularity of horizontal pitch values as supported by
- the chipset. This is expressed in bits. This must be
- supplied.
-
- </quote>
- &s.code;minHeight&e.code;
- <quote><p>
- minimum virtual height allowed. If zero, no limit is
- imposed.
-
- </quote>
- &s.code;maxHeight&e.code;
- <quote><p>
- maximum virtual height allowed. If zero, no limit is
- imposed.
-
- </quote>
- &s.code;virtualX&e.code;
- <quote><p>
- If greater than zero, this is the virtual width value
- that will be used. Otherwise, the virtual width is
- chosen to be the smallest that can accommodate the modes
- selected.
-
- </quote>
- &s.code;virtualY&e.code;
- <quote><p>
- If greater than zero, this is the virtual height value
- that will be used. Otherwise, the virtual height is
- chosen to be the smallest that can accommodate the modes
- selected.
-
- </quote>
- &s.code;apertureSize&e.code;
- <quote><p>
- The size (in bytes) of the aperture used to access video
- memory.
-
- </quote>
- &s.code;strategy&e.code;
- <quote><p>
- The strategy to use when choosing from multiple modes
- with the same name. The options are:
-
- &s.code;LOOKUP_DEFAULT&e.code;
- <quote>???</quote>
- &s.code;LOOKUP_BEST_REFRESH&e.code;
- <quote>mode with best refresh rate</quote>
- &s.code;LOOKUP_CLOSEST_CLOCK&e.code;
- <quote>mode with closest matching clock</quote>
- &s.code;LOOKUP_LIST_ORDER&e.code;
- <quote>first usable mode in list</quote>
-
- The following options can also be combined (OR'ed) with
- one of the above:
-
- &s.code;LOOKUP_CLKDIV2&e.code;
- <quote>Allow halved clocks</quote>
- &s.code;LOOKUP_OPTIONAL_TOLERANCES&e.code;
- <quote>Allow missing horizontal sync and/or vertical refresh
- ranges in the xorg.conf Monitor section</quote>
-
- &s.code;LOOKUP_OPTIONAL_TOLERANCES&e.code; should only be
- specified when the driver can ensure all modes it generates
- can sync on, or at least not damage, the monitor or digital
- flat panel. Horizontal sync and/or vertical refresh ranges
- specified by the user will still be honoured (and acted upon).
-
- </quote>
-
- This function requires that the following fields of the
- &s.code;ScrnInfoRec&e.code; are initialised prior to calling it:
-
- &s.code;clock[]&e.code;
- <quote>List of discrete clocks (when non-programmable)</quote>
- &s.code;numClocks&e.code;
- <quote>Number of discrete clocks (when non-programmable)</quote>
- &s.code;progClock&e.code;
- <quote>Whether the clock is programmable or not</quote>
- &s.code;monitor&e.code;
- <quote>Pointer to the applicable xorg.conf monitor section</quote>
- &s.code;fdFormat&e.code;
- <quote>Format of the screen buffer</quote>
- &s.code;videoRam&e.code;
- <quote>total video memory size (in bytes)</quote>
- &s.code;maxHValue&e.code;
- <quote>Maximum horizontal timing value allowed</quote>
- &s.code;maxVValue&e.code;
- <quote>Maximum vertical timing value allowed</quote>
- &s.code;xInc&e.code;
- <quote>Horizontal timing increment in pixels (defaults to 8)</quote>
-
- This function fills in the following &s.code;ScrnInfoRec&e.code;
- fields:
-
- &s.code;modePool&e.code;
- <quote><p>
- A subset of the modes available to the monitor which
- are compatible with the driver.
-
- </quote>
- &s.code;modes&e.code;
- <quote><p>
- One mode entry for each of the requested modes, with
- the status field of each filled in to indicate if
- the mode has been accepted or not. This list of
- modes is a circular list.
-
- </quote>
- &s.code;virtualX&e.code;
- <quote><p>
- The resulting virtual width.
-
- </quote>
- &s.code;virtualY&e.code;
- <quote><p>
- The resulting virtual height.
-
- </quote>
- &s.code;displayWidth&e.code;
- <quote><p>
- The resulting line pitch.
-
- </quote>
- &s.code;virtualFrom&e.code;
- <quote><p>
- Where the virtual size was determined from.
-
- </quote>
-
- The first stage of this function checks that the
- &s.code;virtualX&e.code; and &s.code;virtualY&e.code; values
- supplied (if greater than zero) are consistent with the line pitch
- and &s.code;maxHeight&e.code; limitations. If not, an error
- message is printed, and the return value is &s.code;-1&e.code;.
-
- The second stage sets up the mode pool, eliminating immediately
- any modes that exceed the driver's line pitch limits, and also
- the virtual width and height limits (if greater than zero). For
- each mode removed an informational message is printed at verbosity
- level &s.code;2&e.code;. If the mode pool ends up being empty,
- a warning message is printed, and the return value is
- &s.code;0&e.code;.
-
- The final stage is to lookup each mode name, and fill in the remaining
- parameters. If an error condition is encountered, a message is
- printed, and the return value is &s.code;-1&e.code;. Otherwise,
- the return value is the number of valid modes found
- (&s.code;0&e.code; if none are found).
-
- Even if the supplied mode names include duplicates, no two names will
- ever match the same mode. Furthermore, if the supplied mode names do not
- yield a valid mode (including the case where no names are passed at all),
- the function will continue looking through the mode pool until it finds
- a mode that survives all checks, or until the mode pool is exhausted.
-
- A message is only printed by this function when a fundamental
- problem is found. It is intended that this function may be called
- more than once if there is more than one set of constraints that
- the driver can work within.
-
- If this function returns &s.code;-1&e.code;, the
- &s.code;ChipPreInit()&e.code; function should return
- &s.code;FALSE&e.code;.
-
- &s.code;clockRanges&e.code; is a linked list of clock ranges
- allowed by the driver. If a mode doesn't fit in any of the defined
- &s.code;clockRanges&e.code;, it is rejected. The first
- &s.code;clockRange&e.code; that matches all requirements is used.
- This structure needs to be initialized to NULL when allocated.
-
- &s.code;clockRanges&e.code; contains the following fields:
-
- &s.code;minClock&nl;
- maxClock&e.code;
- <quote><p>
- The lower and upper mode clock bounds for which the rest
- of the &s.code;clockRange&e.code; parameters apply.
- Since these are the mode clocks, they are not scaled
- with the &s.code;ClockMulFactor&e.code; and
- &s.code;ClockDivFactor&e.code;. It is up to the driver
- to adjust these values if they depend on the clock
- scaling factors.
-
- </quote>
- &s.code;clockIndex&e.code;
- <quote><p>
- (not used yet) &s.code;-1&e.code; for programmable clocks
-
- </quote>
- &s.code;interlaceAllowed&e.code;
- <quote><p>
- &s.code;TRUE&e.code; if interlacing is allowed for this
- range
-
- </quote>
- &s.code;doubleScanAllowed&e.code;
- <quote><p>
- &s.code;TRUE&e.code; if doublescan or multiscan is allowed
- for this range
-
- </quote>
- &s.code;ClockMulFactor&nl;
- ClockDivFactor&e.code;
- <quote><p>
- Scaling factors that are applied to the mode clocks ONLY
- before selecting a clock index (when there is no
- programmable clock) or a &s.code;SynthClock&e.code;
- value. This is useful for drivers that support pixel
- multiplexing or that need to scale the clocks because
- of hardware restrictions (like sending 24bpp data to an
- 8 bit RAMDAC using a tripled clock).
-
- Note that these parameters describe what must be done
- to the mode clock to achieve the data transport clock
- between graphics controller and RAMDAC. For example
- for &s.code;2:1&e.code; pixel multiplexing, two pixels
- are sent to the RAMDAC on each clock. This allows the
- RAMDAC clock to be half of the actual pixel clock.
- Hence, &s.code;ClockMulFactor=1&e.code; and
- &s.code;ClockDivFactor=2&e.code;. This means that the
- clock used for clock selection (ie, determining the
- correct clock index from the list of discrete clocks)
- or for the &s.code;SynthClock&e.code; field in case of
- a programmable clock is: (&s.code;mode->Clock *
- ClockMulFactor) / ClockDivFactor&e.code;.
-
- </quote>
- &s.code;PrivFlags&e.code;
- <quote><p>
- This field is copied into the
- &s.code;mode->PrivFlags&e.code; field when this
- &s.code;clockRange&e.code; is selected by
- &s.code;xf86ValidateModes()&e.code;. It allows the
- driver to find out what clock range was selected, so it
- knows it needs to set up pixel multiplexing or any other
- range-dependent feature. This field is purely
- driver-defined: it may contain flag bits, an index or
- anything else (as long as it is an &s.code;INT&e.code;).
- </quote>
-
- Note that the &s.code;mode->SynthClock&e.code; field is always
- filled in by &s.code;xf86ValidateModes()&e.code;: it will contain
- the ``data transport clock'', which is the clock that will have
- to be programmed in the chip when it has a programmable clock, or
- the clock that will be picked from the clocks list when it is not
- a programmable one. Thus:
-
- &s.code;mode->SynthClock =
- &f.indent;(mode->Clock * ClockMulFactor) / ClockDivFactor&e.code;
-
- </quote>
-
- &s.code;void xf86PruneDriverModes(ScrnInfoPtr scrp)&e.code;
- <quote><p>
- This function deletes modes in the modes field of the
- &s.code;ScrnInfoRec&e.code; that have been marked as invalid.
- This is normally run after having run
- &s.code;xf86ValidateModes()&e.code; for the last time. For each
- mode that is deleted, a warning message is printed out indicating
- the reason for it being deleted.
-
- </quote>
-
- &s.code;void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)&e.code;
- <quote><p>
- This function fills in the &s.code;Crtc*&e.code; fields for all
- the modes in the &s.code;modes&e.code; field of the
- &s.code;ScrnInfoRec&e.code;. The &s.code;adjustFlags&e.code;
- parameter determines how the vertical CRTC values are scaled for
- interlaced modes. They are halved if it is
- &s.code;INTERLACE_HALVE_V&e.code;. The vertical CRTC values are
- doubled for doublescan modes, and are further multiplied by the
- &s.code;VScan&e.code; value.
-
- This function is normally called after calling
- &s.code;xf86PruneDriverModes()&e.code;.
-
- </quote>
-
- &s.code;void xf86PrintModes(ScrnInfoPtr scrp)&e.code;
- <quote><p>
- This function prints out the virtual size setting, and the line
- pitch being used. It also prints out two lines for each mode being
- used. The first line includes the mode's pixel clock, horizontal sync
- rate, refresh rate, and whether it is interlaced, doublescanned and/or
- multi-scanned. The second line is the mode's Modeline.
-
- This function is normally called after calling
- &s.code;xf86SetCrtcForModes()&e.code;.
-
- </quote>
- </quote>
-
-
-<sect1>Secondary Mode functions
-<p>
-
-The secondary mode helper functions are functions which are normally
-used by the primary mode helper functions, and which are not normally
-called directly by a driver. If a driver has unusual requirements
-and needs to do its own mode validation, it might be able to make
-use of some of these secondary mode helper functions.
-
- <quote><p>
- &s.code;int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
- &f.indent;int *divider)&e.code;
- <quote><p>
- This function returns the index of the closest clock to the
- frequency &s.code;freq&e.code; given (in kHz). It assumes that
- the number of clocks is greater than zero. It requires that the
- &s.code;numClocks&e.code; and &s.code;clock&e.code; fields of the
- &s.code;ScrnInfoRec&e.code; are initialised. The
- &s.code;allowDiv2&e.code; field determines if the clocks can be
- halved. The &s.code;*divider&e.code; return value indicates
- whether clock division is used when determining the clock returned.
-
- This function is only for non-programmable clocks.
-
- </quote>
-
- &s.code;const char *xf86ModeStatusToString(ModeStatus status)&e.code;
- <quote><p>
- This function converts the &s.code;status&e.code; value to a
- descriptive printable string.
-
- </quote>
-
- &s.code;ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
- &f.indent;ClockRangePtr clockRanges, LookupModeFlags strategy)&e.code;
- <quote><p>
- This function takes a pointer to a mode with the name filled in,
- and looks for a mode in the &s.code;modePool&e.code; list which
- matches. The parameters of the matching mode are filled in to
- &s.code;*modep&e.code;. The &s.code;clockRanges&e.code; and
- &s.code;strategy&e.code; parameters are as for the
- &s.code;xf86ValidateModes()&e.code; function above.
-
- This function requires the &s.code;modePool&e.code;,
- &s.code;clock[]&e.code;, &s.code;numClocks&e.code; and
- &s.code;progClock&e.code; fields of the &s.code;ScrnInfoRec&e.code;
- to be initialised before being called.
-
- The return value is &s.code;MODE_OK&e.code; if a mode was found.
- Otherwise it indicates why a matching mode could not be found.
-
- </quote>
-
- &s.code;ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp,
- &f.indent;DisplayModePtr mode, ClockRangePtr clockRanges,
- &f.indent;LookupModeFlags strategy, int maxPitch,
- &f.indent;int virtualX, int virtualY)&e.code;
- <quote><p>
- This function checks the passed mode against some basic driver
- constraints. Apart from the ones passed explicitly, the
- &s.code;maxHValue&e.code; and &s.code;maxVValue&e.code; fields of
- the &s.code;ScrnInfoRec&e.code; are also used. If the
- &s.code;ValidMode&e.code; field of the &s.code;ScrnInfoRec&e.code;
- is set, that function is also called to check the mode. Next, the
- mode is checked against the monitor's constraints.
-
- If the mode is consistent with all constraints, the return value
- is &s.code;MODE_OK&e.code;. Otherwise the return value indicates
- which constraint wasn't met.
-
- </quote>
-
- &s.code;void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)&e.code;
- <quote><p>
- This function deletes the &s.code;mode&e.code; given from the
- &s.code;modeList&e.code;. It never prints any messages, so it is
- up to the caller to print a message if required.
-
- </quote>
- </quote>
-
-<sect1>Functions for handling strings and tokens
-<p>
-
- Tables associating strings and numerical tokens combined with the
- following functions provide a compact way of handling strings from
- the config file, and for converting tokens into printable strings.
- The table data structure is:
-
-<quote><verb>
-typedef struct {
- int token;
- const char * name;
-} SymTabRec, *SymTabPtr;
-</verb></quote>
-
- A table is an initialised array of &s.code;SymTabRec&e.code;. The
- tokens must be non-negative integers. Multiple names may be mapped
- to a single token. The table is terminated with an element with a
- &s.code;token&e.code; value of &s.code;-1&e.code; and
- &s.code;NULL&e.code; for the &s.code;name&e.code;.
-
-
- <quote><p>
- &s.code;const char *xf86TokenToString(SymTabPtr table, int token)&e.code;
- <quote><p>
- This function returns the first string in &s.code;table&e.code;
- that matches &s.code;token&e.code;. If no match is found,
- &s.code;NULL&e.code; is returned (NOTE, older versions of this
- function would return the string "unknown" when no match is found).
-
- </quote>
-
- &s.code;int xf86StringToToken(SymTabPtr table, const char *string)&e.code;
- <quote><p>
- This function returns the first token in &s.code;table&e.code;
- that matches &s.code;string&e.code;. The
- &s.code;xf86NameCmp()&e.code; function is used to determine the
- match. If no match is found, &s.code;-1&e.code; is returned.
-
- </quote>
- </quote>
-
-
-<sect1>Functions for finding which config file entries to use
-<p>
-
- These functions can be used to select the appropriate config file
- entries that match the detected hardware. They are described above
- in the <ref id="probe" name="Probe"> and
- <ref id="avail" name="Available Functions"> sections.
-
-
-<sect1>Probing discrete clocks on old hardware
-<p>
-
- The &s.code;xf86GetClocks()&e.code; function may be used to assist
- in finding the discrete pixel clock values on older hardware.
-
-
- <quote><p>
- &s.code;void xf86GetClocks(ScrnInfoPtr pScrn, int num,
- &f.indent;Bool (*ClockFunc)(ScrnInfoPtr, int),
- &f.indent;void (*ProtectRegs)(ScrnInfoPtr, Bool),
- &f.indent;void (*BlankScreen)(ScrnInfoPtr, Bool),
- &f.indent;int vertsyncreg, int maskval, int knownclkindex,
- &f.indent;int knownclkvalue)&e.code;
- <quote><p>
- This function uses a comparative sampling method to measure the
- discrete pixel clock values. The number of discrete clocks to
- measure is given by &s.code;num&e.code;. &s.code;clockFunc&e.code;
- is a function that selects the &s.code;n&e.code;'th clock. It
- should also save or restore any state affected by programming the
- clocks when the index passed is &s.code;CLK_REG_SAVE&e.code; or
- &s.code;CLK_REG_RESTORE&e.code;. &s.code;ProtectRegs&e.code; is
- a function that does whatever is required to protect the hardware
- state while selecting a new clock. &s.code;BlankScreen&e.code;
- is a function that blanks the screen. &s.code;vertsyncreg&e.code;
- and &s.code;maskval&e.code; are the register and bitmask to
- check for the presence of vertical sync pulses.
- &s.code;knownclkindex&e.code; and &s.code;knownclkvalue&e.code;
- are the index and value of a known clock. These are the known
- references on which the comparative measurements are based. The
- number of clocks probed is set in &s.code;pScrn->numClocks&e.code;,
- and the probed clocks are set in the &s.code;pScrn->clock[]&e.code;
- array. All of the clock values are in units of kHz.
-
- </quote>
-
- &s.code;void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)&e.code;
- <quote><p>
- Print out the pixel clocks &s.code;scrp->clock[]&e.code;.
- &s.code;from&e.code; indicates whether the clocks were probed
- or from the config file.
-
- </quote>
- </quote>
-
-<sect1>Other helper functions
-<p>
- <quote><p>
- &s.code;Bool xf86IsUnblank(int mode)&e.code;
- <quote><p>
- Returns &s.code;TRUE&e.code; when the screen saver mode specified
- by &s.code;mode&e.code; requires the screen be unblanked,
- and &s.code;FALSE&e.code; otherwise. The screen saver modes that
- require blanking are &s.code;SCREEN_SAVER_ON&e.code; and
- &s.code;SCREEN_SAVER_CYCLE&e.code;, and the screen saver modes that
- require unblanking are &s.code;SCREEN_SAVER_OFF&e.code; and
- &s.code;SCREEN_SAVER_FORCER&e.code;. Drivers may call this helper
- from their &s.code;SaveScreen()&e.code; function to interpret the
- screen saver modes.
-
- </quote>
- </quote>
-
-<sect>The vgahw module
-<p>
-
-The vgahw modules provides an interface for saving, restoring and
-programming the standard VGA registers, and for handling VGA colourmaps.
-
-<sect1>Data Structures
-<p>
-
- The public data structures used by the vgahw module are
- &s.code;vgaRegRec&e.code; and &s.code;vgaHWRec&e.code;. They are
- defined in &s.code;vgaHW.h.&e.code;
-
-
-<sect1>General vgahw Functions
-<p>
-
- <quote><p>
- &s.code;Bool vgaHWGetHWRec(ScrnInfoPtr pScrn)&e.code;
- <quote><p>
- This function allocates a &s.code;vgaHWRec&e.code; structure, and
- hooks it into the &s.code;ScrnInfoRec&e.code;'s
- &s.code;privates&e.code;. Like all information hooked into the
- &s.code;privates&e.code;, it is persistent, and only needs to be
- allocated once per screen. This function should normally be called
- from the driver's &s.code;ChipPreInit()&e.code; function. The
- &s.code;vgaHWRec&e.code; is zero-allocated, and the following
- fields are explicitly initialised:
-
- &s.code;ModeReg.DAC[]&e.code;
- <quote>initialised with a default colourmap</quote>
- &s.code;ModeReg.Attribute[0x11]&e.code;
- <quote>initialised with the default overscan index</quote>
- &s.code;ShowOverscan&e.code;
- <quote>initialised according to the "ShowOverscan" option</quote>
- &s.code;paletteEnabled&e.code;
- <quote>initialised to FALSE</quote>
- &s.code;cmapSaved&e.code;
- <quote>initialised to FALSE</quote>
- &s.code;pScrn&e.code;
- <quote>initialised to pScrn</quote>
-
- In addition to the above, &s.code;vgaHWSetStdFuncs()&e.code; is
- called to initialise the register access function fields with the
- standard VGA set of functions.
-
- Once allocated, a pointer to the &s.code;vgaHWRec&e.code; can be
- obtained from the &s.code;ScrnInfoPtr&e.code; with the
- &s.code;VGAHWPTR(pScrn)&e.code; macro.
-
- </quote>
-
- &s.code;void vgaHWFreeHWRec(ScrnInfoPtr pScrn)&e.code;
- <quote><p>
- This function frees a &s.code;vgaHWRec&e.code; structure. It
- should be called from a driver's &s.code;ChipFreeScreen()&e.code;
- function.
-
- </quote>
-
- &s.code;Bool vgaHWSetRegCounts(ScrnInfoPtr pScrn, int numCRTC,
- &f.indent;int numSequencer, int numGraphics, int numAttribute)&e.code;
- <quote><p>
- This function allows the number of CRTC, Sequencer, Graphics and
- Attribute registers to be changed. This makes it possible for
- extended registers to be saved and restored with
- &s.code;vgaHWSave()&e.code; and &s.code;vgaHWRestore()&e.code;.
- This function should be called after a &s.code;vgaHWRec&e.code;
- has been allocated with &s.code;vgaHWGetHWRec()&e.code;. The
- default values are defined in &s.code;vgaHW.h&e.code; as follows:
-
- <quote><verb>
-#define VGA_NUM_CRTC 25
-#define VGA_NUM_SEQ 5
-#define VGA_NUM_GFX 9
-#define VGA_NUM_ATTR 21
- </verb></quote>
-
- </quote>
-
- &s.code;Bool vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)&e.code;
- <quote><p>
- This function copies the contents of the VGA saved registers in
- &s.code;src&e.code; to &s.code;dst&e.code;. Note that it isn't
- possible to simply do this with &s.code;memcpy()&e.code; (or
- similar). This function returns &s.code;TRUE&e.code; unless there
- is a problem allocating space for the &s.code;CRTC&e.code and
- related fields in &s.code;dst&e.code;.
-
- </quote>
-
- &s.code;void vgaHWSetStdFuncs(vgaHWPtr hwp)&e.code;
- <quote><p>
- This function initialises the register access function fields of
- &s.code;hwp&e.code; with the standard VGA set of functions. This
- is called by &s.code;vgaHWGetHWRec()&e.code;, so there is usually
- no need to call this explicitly. The register access functions
- are described below. If the registers are shadowed in some other
- port I/O space (for example a PCI I/O region), these functions
- can be used to access the shadowed registers if
- &s.code;hwp->PIOOffset&e.code; is initialised with
- &s.code;offset&e.code;, calculated in such a way that when the
- standard VGA I/O port value is added to it the correct offset into
- the PIO area results. This value is initialised to zero in
- &s.code;vgaHWGetHWRec()&e.code;. (Note: the PIOOffset functionality
- is present in XFree86 4.1.0 and later.)
-
- </quote>
-
- &s.code;void vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)&e.code;
- <quote><p>
- This function initialised the register access function fields of
- hwp with a generic MMIO set of functions.
- &s.code;hwp->MMIOBase&e.code; is initialised with
- &s.code;base&e.code;, which must be the virtual address that the
- start of MMIO area is mapped to. &s.code;hwp->MMIOOffset&e.code;
- is initialised with &s.code;offset&e.code;, which must be calculated
- in such a way that when the standard VGA I/O port value is added
- to it the correct offset into the MMIO area results. That means
- that these functions are only suitable when the VGA I/O ports are
- made available in a direct mapping to the MMIO space. If that is
- not the case, the driver will need to provide its own register
- access functions. The register access functions are described
- below.
-
- </quote>
-
- &s.code;Bool vgaHWMapMem(ScrnInfoPtr pScrn)&e.code;
- <quote><p>
- This function maps the VGA memory window. It requires that the
- &s.code;vgaHWRec&e.code; be allocated. If a driver requires
- non-default &s.code;MapPhys&e.code; or &s.code;MapSize&e.code;
- settings (the physical location and size of the VGA memory window)
- then those fields of the &s.code;vgaHWRec&e.code; must be initialised
- before calling this function. Otherwise, this function initialiases
- the default values of &s.code;0xA0000&e.code; for
- &s.code;MapPhys&e.code; and &s.code;(64 * 1024)&e.code; for
- &s.code;MapSize&e.code;. This function must be called before
- attempting to save or restore the VGA state. If the driver doesn't
- call it explicitly, the &s.code;vgaHWSave()&e.code; and
- &s.code;vgaHWRestore()&e.code; functions may call it if they need
- to access the VGA memory (in which case they will also call
- &s.code;vgaHWUnmapMem()&e.code; to unmap the VGA memory before
- exiting).
-
- </quote>
-
- &s.code;void vgaHWUnmapMem(ScrnInfoPtr pScrn)&e.code;
- <quote><p>
- This function unmaps the VGA memory window. It must only be called
- after the memory has been mapped. The &s.code;Base&e.code; field
- of the &s.code;vgaHWRec&e.code; field is set to &s.code;NULL&e.code;
- to indicate that the memory is no longer mapped.
-
- </quote>
-
- &s.code;void vgaHWGetIOBase(vgaHWPtr hwp)&e.code;
- <quote><p>
- This function initialises the &s.code;IOBase&e.code; field of the
- &s.code;vgaHWRec&e.code;. This function must be called before
- using any other functions that access the video hardware.
-
- A macro &s.code;VGAHW_GET_IOBASE()&e.code; is also available in
- &s.code;vgaHW.h&e.code; that returns the I/O base, and this may
- be used when the vgahw module is not loaded (for example, in the
- &s.code;ChipProbe()&e.code; function).
-
- </quote>
-
- &s.code;void vgaHWUnlock(vgaHWPtr hwp)&e.code;
- <quote><p>
- This function unlocks the VGA &s.code;CRTC[0-7]&e.code; registers,
- and must be called before attempting to write to those registers.
-
- </quote>
-
- &s.code;void vgaHWLock(vgaHWPtr hwp)&e.code;
- <quote><p>
- This function locks the VGA &s.code;CRTC[0-7]&e.code; registers.
-
- </quote>
-
- &s.code;void vgaHWEnable(vgaHWPtr hwp)&e.code;
- <quote><p>
- This function enables the VGA subsystem. (Note, this function is
- present in XFree86 4.1.0 and later.).
-
- </quote>
-
- &s.code;void vgaHWDisable(vgaHWPtr hwp)&e.code;
- <quote><p>
- This function disables the VGA subsystem. (Note, this function is
- present in XFree86 4.1.0 and later.).
-
- </quote>
-
- &s.code;void vgaHWSave(ScrnInfoPtr pScrn, vgaRegPtr save, int flags)&e.code;
- <quote><p>
- This function saves the VGA state. The state is written to the
- &s.code;vgaRegRec&e.code; pointed to by &s.code;save&e.code;.
- &s.code;flags&e.code; is set to one or more of the following flags
- ORed together:
-
- &s.code;VGA_SR_MODE&e.code;
- <quote>the mode setting registers are saved</quote>
- &s.code;VGA_SR_FONTS&e.code;
- <quote>the text mode font/text data is saved</quote>
- &s.code;VGA_SR_CMAP&e.code;
- <quote>the colourmap (LUT) is saved</quote>
- &s.code;VGA_SR_ALL&e.code;
- <quote>all of the above are saved</quote>
-
- The &s.code;vgaHWRec&e.code; and its &s.code;IOBase&e.code; fields
- must be initialised before this function is called. If
- &s.code;VGA_SR_FONTS&e.code; is set in &s.code;flags&e.code;, the
- VGA memory window must be mapped. If it isn't then
- &s.code;vgaHWMapMem()&e.code; will be called to map it, and
- &s.code;vgaHWUnmapMem()&e.code; will be called to unmap it
- afterwards. &s.code;vgaHWSave()&e.code; uses the three functions
- below in the order &s.code;vgaHWSaveColormap()&e.code;,
- &s.code;vgaHWSaveMode()&e.code;, &s.code;vgaHWSaveFonts()&e.code; to
- carry out the different save phases. It is undecided at this
- stage whether they will remain part of the vgahw module's public
- interface or not.
-
- </quote>
-
- &s.code;void vgaHWSaveMode(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
- <quote><p>
- This function saves the VGA mode registers. They are saved to
- the &s.code;vgaRegRec&e.code; pointed to by &s.code;save&e.code;.
- The registers saved are:
-
- <quote>
- &s.code;MiscOut&nl;
- CRTC[0-0x18]&nl;
- Attribute[0-0x14]&nl;
- Graphics[0-8]&nl;
- Sequencer[0-4]&e.code;
- </quote>
-
- The number of registers actually saved may be modified by a prior call
- to &s.code;vgaHWSetRegCounts()&e.code;.
-
- </quote>
-
- &s.code;void vgaHWSaveFonts(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
- <quote><p>
- This function saves the text mode font and text data held in the
- video memory. If called while in a graphics mode, no save is
- done. The VGA memory window must be mapped with
- &s.code;vgaHWMapMem()&e.code; before to calling this function.
-
- On some platforms, one or more of the font/text plane saves may be
- no-ops. This is the case when the platform's VC driver already
- takes care of this.
-
- </quote>
-
- &s.code;void vgaHWSaveColormap(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
- <quote><p>
- This function saves the VGA colourmap (LUT). Before saving it, it
- attempts to verify that the colourmap is readable. In rare cases
- where it isn't readable, a default colourmap is saved instead.
-
- </quote>
-
- &s.code;void vgaHWRestore(ScrnInfoPtr pScrn, vgaRegPtr restore, int flags)&e.code;
- <quote><p>
- This function programs the VGA state. The state programmed is
- that contained in the &s.code;vgaRegRec&e.code; pointed to by
- &s.code;restore&e.code;. &s.code;flags&e.code; is the same
- as described above for the &s.code;vgaHWSave()&e.code; function.
-
- The &s.code;vgaHWRec&e.code; and its &s.code;IOBase&e.code; fields
- must be initialised before this function is called. If
- &s.code;VGA_SR_FONTS&e.code; is set in &s.code;flags&e.code;, the
- VGA memory window must be mapped. If it isn't then
- &s.code;vgaHWMapMem()&e.code; will be called to map it, and
- &s.code;vgaHWUnmapMem()&e.code; will be called to unmap it
- afterwards. &s.code;vgaHWRestore()&e.code; uses the three functions
- below in the order &s.code;vgaHWRestoreFonts()&e.code;,
- &s.code;vgaHWRestoreMode()&e.code;,
- &s.code;vgaHWRestoreColormap()&e.code; to carry out the different
- restore phases. It is undecided at this stage whether they will
- remain part of the vgahw module's public interface or not.
-
- </quote>
-
- &s.code;void vgaHWRestoreMode(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
- <quote><p>
- This function restores the VGA mode registers. They are restored
- from the data in the &s.code;vgaRegRec&e.code; pointed to by
- &s.code;restore&e.code;. The registers restored are:
-
- <quote>
- &s.code;MiscOut&nl;
- CRTC[0-0x18]&nl;
- Attribute[0-0x14]&nl;
- Graphics[0-8]&nl;
- Sequencer[0-4]&e.code;
- </quote>
-
- The number of registers actually restored may be modified by a prior call
- to &s.code;vgaHWSetRegCounts()&e.code;.
-
- </quote>
-
- &s.code;void vgaHWRestoreFonts(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
- <quote><p>
- This function restores the text mode font and text data to the
- video memory. The VGA memory window must be mapped with
- &s.code;vgaHWMapMem()&e.code; before to calling this function.
-
- On some platforms, one or more of the font/text plane restores
- may be no-ops. This is the case when the platform's VC driver
- already takes care of this.
-
- </quote>
-
- &s.code;void vgaHWRestoreColormap(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
- <quote><p>
- This function restores the VGA colourmap (LUT).
-
- </quote>
-
- &s.code;void vgaHWInit(ScrnInfoPtr pScrn, DisplayModePtr mode)&e.code;
- <quote><p>
- This function fills in the &s.code;vgaHWRec&e.code;'s
- &s.code;ModeReg&e.code; field with the values appropriate for
- programming the given video mode. It requires that the
- &s.code;ScrnInfoRec&e.code;'s &s.code;depth&e.code; field is
- initialised, which determines how the registers are programmed.
-
- </quote>
-
- &s.code;void vgaHWSeqReset(vgaHWPtr hwp, Bool start)&e.code;
- <quote><p>
- Do a VGA sequencer reset. If start is &s.code;TRUE&e.code;, the
- reset is started. If start is &s.code;FALSE&e.code;, the reset
- is ended.
-
- </quote>
-
- &s.code;void vgaHWProtect(ScrnInfoPtr pScrn, Bool on)&e.code;
- <quote><p>
- This function protects VGA registers and memory from corruption
- during loads. It is typically called with on set to
- &s.code;TRUE&e.code; before programming, and with on set to
- &s.code;FALSE&e.code; after programming.
-
- </quote>
-
- &s.code;Bool vgaHWSaveScreen(ScreenPtr pScreen, int mode)&e.code;
- <quote><p>
- This function blanks and unblanks the screen. It is blanked when
- &s.code;mode&e.code; is &s.code;SCREEN_SAVER_ON&e.code; or
- &s.code;SCREEN_SAVER_CYCLE&e.code;, and unblanked when
- &s.code;mode&e.code; is &s.code;SCREEN_SAVER_OFF&e.code; or
- &s.code;SCREEN_SAVER_FORCER&e.code;.
-
- </quote>
-
- &s.code;void vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)&e.code;
- <quote><p>
- This function blanks and unblanks the screen. It is blanked when
- &s.code;on&e.code; is &s.code;FALSE&e.code;, and unblanked when
- &s.code;on&e.code; is &s.code;TRUE&e.code;. This function is
- provided for use in cases where the &s.code;ScrnInfoRec&e.code;
- can't be derived from the &s.code;ScreenRec&e.code; (while probing
- for clocks, for example).
-
- </quote>
- </quote>
-
-<sect1>VGA Colormap Functions
-<p>
-
- The vgahw module uses the standard colormap support (see the
- <ref id="cmap" name="Colormap Handling"> section. This is initialised
- with the following function:
-
- <quote>
- &s.code;Bool vgaHWHandleColormaps(ScreenPtr pScreen)&e.code;
- </quote>
-
-
-<sect1>VGA Register Access Functions
-<p>
-
- The vgahw module abstracts access to the standard VGA registers by
- using a set of functions held in the &s.code;vgaHWRec&e.code;. When
- the &s.code;vgaHWRec&e.code; is created these function pointers are
- initialised with the set of standard VGA I/O register access functions.
- In addition to these, the vgahw module includes a basic set of MMIO
- register access functions, and the &s.code;vgaHWRec&e.code; function
- pointers can be initialised to these by calling the
- &s.code;vgaHWSetMmioFuncs()&e.code; function described above. Some
- drivers/platforms may require a different set of functions for VGA
- access. The access functions are described here.
-
-
- <quote><p>
- &s.code;void writeCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)&e.code;
- <quote><p>
- Write &s.code;value&e.code; to CRTC register &s.code;index&e.code;.
-
- </quote>
-
- &s.code;CARD8 readCrtc(vgaHWPtr hwp, CARD8 index)&e.code;
- <quote><p>
- Return the value read from CRTC register &s.code;index&e.code;.
-
- </quote>
-
- &s.code;void writeGr(vgaHWPtr hwp, CARD8 index, CARD8 value)&e.code;
- <quote><p>
- Write &s.code;value&e.code; to Graphics Controller register
- &s.code;index&e.code;.
-
- </quote>
-
- &s.code;CARD8 readGR(vgaHWPtr hwp, CARD8 index)&e.code;
- <quote><p>
- Return the value read from Graphics Controller register
- &s.code;index&e.code;.
-
- </quote>
-
- &s.code;void writeSeq(vgaHWPtr hwp, CARD8 index, CARD8, value)&e.code;
- <quote><p>
- Write &s.code;value&e.code; to Sequencer register
- &s.code;index&e.code;.
-
- </quote>
-
- &s.code;CARD8 readSeq(vgaHWPtr hwp, CARD8 index)&e.code;
- <quote><p>
- Return the value read from Sequencer register &s.code;index&e.code;.
-
- </quote>
-
- &s.code;void writeAttr(vgaHWPtr hwp, CARD8 index, CARD8, value)&e.code;
- <quote><p>
- Write &s.code;value&e.code; to Attribute Controller register
- &s.code;index&e.code;. When writing out the index value this
- function should set bit 5 (&s.code;0x20&e.code;) according to the
- setting of &s.code;hwp->paletteEnabled&e.code; in order to
- preserve the palette access state. It should be cleared when
- &s.code;hwp->paletteEnabled&e.code; is &s.code;TRUE&e.code;
- and set when it is &s.code;FALSE&e.code;.
-
- </quote>
-
- &s.code;CARD8 readAttr(vgaHWPtr hwp, CARD8 index)&e.code;
- <quote><p>
- Return the value read from Attribute Controller register
- &s.code;index&e.code;. When writing out the index value this
- function should set bit 5 (&s.code;0x20&e.code;) according to the
- setting of &s.code;hwp->paletteEnabled&e.code; in order to
- preserve the palette access state. It should be cleared when
- &s.code;hwp->paletteEnabled&e.code; is &s.code;TRUE&e.code;
- and set when it is &s.code;FALSE&e.code;.
-
- </quote>
-
- &s.code;void writeMiscOut(vgaHWPtr hwp, CARD8 value)&e.code;
- <quote><p>
- Write `&s.code;value&e.code;' to the Miscellaneous Output register.
-
- </quote>
-
- &s.code;CARD8 readMiscOut(vgwHWPtr hwp)&e.code;
- <quote><p>
- Return the value read from the Miscellaneous Output register.
-
- </quote>
-
- &s.code;void enablePalette(vgaHWPtr hwp)&e.code;
- <quote><p>
- Clear the palette address source bit in the Attribute Controller
- index register and set &s.code;hwp->paletteEnabled&e.code; to
- &s.code;TRUE&e.code;.
-
- </quote>
-
- &s.code;void disablePalette(vgaHWPtr hwp)&e.code;
- <quote><p>
- Set the palette address source bit in the Attribute Controller
- index register and set &s.code;hwp->paletteEnabled&e.code; to
- &s.code;FALSE&e.code;.
-
- </quote>
-
- &s.code;void writeDacMask(vgaHWPtr hwp, CARD8 value)&e.code;
- <quote><p>
- Write &s.code;value&e.code; to the DAC Mask register.
-
- </quote>
-
- &s.code;CARD8 readDacMask(vgaHWptr hwp)&e.code;
- <quote><p>
- Return the value read from the DAC Mask register.
-
- </quote>
-
- &s.code;void writeDacReadAddress(vgaHWPtr hwp, CARD8 value)&e.code;
- <quote><p>
- Write &s.code;value&e.code; to the DAC Read Address register.
-
- </quote>
-
- &s.code;void writeDacWriteAddress(vgaHWPtr hwp, CARD8 value)&e.code;
- <quote><p>
- Write &s.code;value&e.code; to the DAC Write Address register.
-
- </quote>
-
- &s.code;void writeDacData(vgaHWPtr hwp, CARD8 value)&e.code;
- <quote><p>
- Write &s.code;value&e.code; to the DAC Data register.
-
- </quote>
-
- &s.code;CARD8 readDacData(vgaHWptr hwp)&e.code;
- <quote><p>
- Return the value read from the DAC Data register.
-
- </quote>
-
- &s.code;CARD8 readEnable(vgaHWptr hwp)&e.code;
- <quote><p>
- Return the value read from the VGA Enable register. (Note: This
- function is present in XFree86 4.1.0 and later.)
-
- </quote>
-
- &s.code;void writeEnable(vgaHWPtr hwp, CARD8 value)&e.code;
- <quote><p>
- Write &s.code;value&e.code; to the VGA Enable register. (Note: This
- function is present in XFree86 4.1.0 and later.)
-
- </quote>
- </quote>
-
-<sect>Some notes about writing a driver<label id="sample">
-<p>
-
-<em>NOTE: some parts of this are not up to date</em>
-
-The following is an outline for writing a basic unaccelerated driver
-for a PCI video card with a linear mapped framebuffer, and which has a
-VGA core. It is includes some general information that is relevant to
-most drivers (even those which don't fit that basic description).
-
-The information here is based on the initial conversion of the Matrox
-Millennium driver to the ``new design''. For a fleshing out and sample
-implementation of some of the bits outlined here, refer to that driver.
-Note that this is an example only. The approach used here will not be
-appropriate for all drivers.
-
-Each driver must reserve a unique driver name, and a string that is used
-to prefix all of its externally visible symbols. This is to avoid name
-space clashes when loading multiple drivers. The examples here are for
-the ``ZZZ'' driver, which uses the ``ZZZ'' or ``zzz'' prefix for its externally
-visible symbols.
-
-
-<sect1>Include files
-<p>
-
- All drivers normally include the following headers:
- <quote>
- &s.code;"xf86.h"&nl;
- "xf86_OSproc.h"&nl;
- "xf86_ansic.h"&nl;
- "xf86Resources.h"&e.code;
- </quote>
- Wherever inb/outb (and related things) are used the following should be
- included:
- <quote>
- &s.code;"compiler.h"&e.code;
- </quote>
- Note: in drivers, this must be included after &s.code;"xf86_ansic.h"&e.code;.
-
- Drivers that need to access PCI vendor/device definitions need this:
- <quote>
- &s.code;"xf86PciInfo.h"&e.code;
- </quote>
-
- Drivers that need to access the PCI config space need this:
- <quote>
- &s.code;"xf86Pci.h"&e.code;
- </quote>
-
- Drivers using the mi banking wrapper need:
-
- <quote>
- &s.code;"mibank.h"&e.code;
- </quote>
-
- Drivers that initialise a SW cursor need this:
- <quote>
- &s.code;"mipointer.h"&e.code;
- </quote>
-
- All drivers implementing backing store need this:
- <quote>
- &s.code;"mibstore.h"&e.code;
- </quote>
-
- All drivers using the mi colourmap code need this:
- <quote>
- &s.code;"micmap.h"&e.code;
- </quote>
-
- If a driver uses the vgahw module, it needs this:
- <quote>
- &s.code;"vgaHW.h"&e.code;
- </quote>
-
- Drivers supporting VGA or Hercules monochrome screens need:
- <quote>
- &s.code;"xf1bpp.h"&e.code;
- </quote>
-
- Drivers supporting VGA or EGC 16-colour screens need:
- <quote>
- &s.code;"xf4bpp.h"&e.code;
- </quote>
-
- Drivers using cfb need:
- <quote>
- &s.code;#define PSZ 8&nl;
- #include "cfb.h"&nl;
- #undef PSZ&e.code;
- </quote>
-
- Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
- <quote>
- &s.code;"cfb16.h"&nl;
- "cfb24.h"&nl;
- "cfb32.h"&e.code;
- </quote>
-
- The driver's own header file:
- <quote>
- &s.code;"zzz.h"&e.code;
- </quote>
-
- Drivers must NOT include the following:
-
- <quote>
- &s.code;"xf86Priv.h"&nl;
- "xf86Privstr.h"&nl;
- "xf86_libc.h"&nl;
- "xf86_OSlib.h"&nl;
- "Xos.h"&e.code;&nl;
- any OS header
- </quote>
-
-
-<sect1>Data structures and initialisation
-<p>
-
-<itemize>
- <item>The following macros should be defined:
- <code>
-#define VERSION <version-as-an-int>
-#define ZZZ_NAME "ZZZ" /* the name used to prefix messages */
-#define ZZZ_DRIVER_NAME "zzz" /* the driver name as used in config file */
-#define ZZZ_MAJOR_VERSION <int>
-#define ZZZ_MINOR_VERSION <int>
-#define ZZZ_PATCHLEVEL <int>
- </code>
-<p>
- NOTE: &s.code;ZZZ_DRIVER_NAME&e.code; should match the name of the
- driver module without things like the "lib" prefix, the "_drv" suffix
- or filename extensions.
-<p>
-
- <item>A DriverRec must be defined, which includes the functions required
- at the pre-probe phase. The name of this DriverRec must be an
- upper-case version of ZZZ_DRIVER_NAME (for the purposes of static
- linking).
-<p>
- <code>
-DriverRec ZZZ = {
- VERSION,
- ZZZ_DRIVER_NAME,
- ZZZIdentify,
- ZZZProbe,
- ZZZAvailableOptions,
- NULL,
- 0
-};
- </code>
-
- <item>Define list of supported chips and their matching ID:
-<p>
- <code>
-static SymTabRec ZZZChipsets[] = {
- { PCI_CHIP_ZZZ1234, "zzz1234a" },
- { PCI_CHIP_ZZZ5678, "zzz5678a" },
- { -1, NULL }
-};
- </code>
-<p>
- The token field may be any integer value that the driver may use to
- uniquely identify the supported chipsets. For drivers that support
- only PCI devices using the PCI device IDs might be a natural choice,
- but this isn't mandatory. For drivers that support both PCI and other
- devices (like ISA), some other ID should probably used. When other
- IDs are used as the tokens it is recommended that the names be
- defined as an &s.code;enum&e.code; type.
-<p>
- <item>If the driver uses the &s.code;xf86MatchPciInstances(&e.code;)
- helper (recommended for drivers that support PCI cards) a list that
- maps PCI IDs to chip IDs and fixed resources must be defined:
-<p>
- <code>
-static PciChipsets ZZZPciChipsets[] = {
- { PCI_CHIP_ZZZ1234, PCI_CHIP_ZZZ1234, RES_SHARED_VGA },
- { PCI_CHIP_ZZZ5678, PCI_CHIP_ZZZ5678, RES_SHARED_VGA },
- { -1, -1, RES_UNDEFINED }
-}
- </code>
-<p>
- <item>Define the &s.code;XF86ModuleVersionInfo&e.code; struct for the
- driver. This is required for the dynamically loaded version:
-<p>
- <code>
-static XF86ModuleVersionInfo zzzVersRec =
-{
- "zzz",
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XF86_VERSION_CURRENT,
- ZZZ_MAJOR_VERSION, ZZZ_MINOR_VERSION, ZZZ_PATCHLEVEL,
- ABI_CLASS_VIDEODRV,
- ABI_VIDEODRV_VERSION,
- MOD_CLASS_VIDEODRV,
- {0,0,0,0}
-};
- </code>
-<p>
- <item>Define a data structure to hold the driver's screen-specific data.
- This must be used instead of global variables. This would be defined
- in the &s.code;"zzz.h"&e.code; file, something like:
-<p>
- <code>
-typedef struct {
- type1 field1;
- type2 field2;
- int fooHack;
- Bool pciRetry;
- Bool noAccel;
- Bool hwCursor;
- CloseScreenProcPtr CloseScreen;
- OptionInfoPtr Options;
- ...
-} ZZZRec, *ZZZPtr;
- </code>
-<p>
- <item>Define the list of config file Options that the driver accepts. For
- consistency between drivers those in the list of ``standard'' options
- should be used where appropriate before inventing new options.
-<p>
- <code>
-typedef enum {
- OPTION_FOO_HACK,
- OPTION_PCI_RETRY,
- OPTION_HW_CURSOR,
- OPTION_NOACCEL
-} ZZZOpts;
-
-static const OptionInfoRec ZZZOptions[] = {
- { OPTION_FOO_HACK, "FooHack", OPTV_INTEGER, {0}, FALSE },
- { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE }
-};
- </code>
-<p>
-</itemize>
-
-<sect1>Functions
-<p>
-
-
-<sect2>SetupProc
-<p>
-
- For dynamically loaded modules, a &s.code;ModuleData&e.code;
- variable is required. It is should be the name of the driver
- prepended to "ModuleData". A &s.code;Setup()&e.code; function is
- also required, which calls &s.code;xf86AddDriver()&e.code; to add
- the driver to the main list of drivers.
-
- <code>
-static MODULESETUPPROTO(zzzSetup);
-
-XF86ModuleData zzzModuleData = { &zzzVersRec, zzzSetup, NULL };
-
-static pointer
-zzzSetup(pointer module, pointer opts, int *errmaj, int *errmin)
-{
- static Bool setupDone = FALSE;
-
- /* This module should be loaded only once, but check to be sure. */
-
- if (!setupDone) {
- /*
- * Modules that this driver always requires may be loaded
- * here by calling LoadSubModule().
- */
-
- setupDone = TRUE;
- xf86AddDriver(&MGA, module, 0);
-
- /*
- * The return value must be non-NULL on success even though
- * there is no TearDownProc.
- */
- return (pointer)1;
- } else {
- if (errmaj) *errmaj = LDR_ONCEONLY;
- return NULL;
- }
-}
- </code>
-
-<sect2>GetRec, FreeRec
-<p>
-
- A function is usually required to allocate the driver's
- screen-specific data structure and hook it into the
- &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field.
- The &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; is
- initialised to &s.code;NULL&e.code;, so it is easy to check if the
- initialisation has already been done. After allocating it, initialise
- the fields. By using &s.code;xnfcalloc()&e.code; to do the allocation
- it is zeroed, and if the allocation fails the server exits.
-<p>
- NOTE:
- When allocating structures from inside the driver which are defined
- on the common level it is important to initialize the structure to
- zero.
- Only this guarantees that the server remains source compatible to
- future changes in common level structures.
-
- <code>
-static Bool
-ZZZGetRec(ScrnInfoPtr pScrn)
-{
- if (pScrn->driverPrivate != NULL)
- return TRUE;
- pScrn->driverPrivate = xnfcalloc(sizeof(ZZZRec), 1);
- /* Initialise as required */
- ...
- return TRUE;
-}
- </code>
-
- Define a macro in &s.code;"zzz.h"&e.code; which gets a pointer to
- the &s.code;ZZZRec&e.code; when given &s.code;pScrn&e.code;:
-
- <code>
-#define ZZZPTR(p) ((ZZZPtr)((p)->driverPrivate))
- </code>
-
- Define a function to free the above, setting it to &s.code;NULL&e.code;
- once it has been freed:
-
- <code>
-static void
-ZZZFreeRec(ScrnInfoPtr pScrn)
-{
- if (pScrn->driverPrivate == NULL)
- return;
- xfree(pScrn->driverPrivate);
- pScrn->driverPrivate = NULL;
-}
- </code>
-
-<sect2>Identify
-<p>
-
- Define the &s.code;Identify()&e.code; function. It is run before
- the Probe, and typically prints out an identifying message, which
- might include the chipsets it supports. This function is mandatory:
-
- <code>
-static void
-ZZZIdentify(int flags)
-{
- xf86PrintChipsets(ZZZ_NAME, "driver for ZZZ Tech chipsets",
- ZZZChipsets);
-}
- </code>
-
-<sect2>Probe
-<p>
-
- Define the &s.code;Probe()&e.code; function. The purpose of this
- is to find all instances of the hardware that the driver supports,
- and for the ones not already claimed by another driver, claim the
- slot, and allocate a &s.code;ScrnInfoRec&e.code;. This should be
- a minimal probe, and it should under no circumstances leave the
- state of the hardware changed. Because a device is found, don't
- assume that it will be used. Don't do any initialisations other
- than the required &s.code;ScrnInfoRec&e.code; initialisations.
- Don't allocate any new data structures.
-
- This function is mandatory.
-
- NOTE: The &s.code;xf86DrvMsg()&e.code; functions cannot be used from
- the Probe.
-
- <code>
-static Bool
-ZZZProbe(DriverPtr drv, int flags)
-{
- Bool foundScreen = FALSE;
- int numDevSections, numUsed;
- GDevPtr *devSections;
- int *usedChips;
- int i;
-
- /*
- * Find the config file Device sections that match this
- * driver, and return if there are none.
- */
- if ((numDevSections = xf86MatchDevice(ZZZ_DRIVER_NAME,
- &devSections)) <= 0) {
- return FALSE;
- }
-
- /*
- * Since this is a PCI card, "probing" just amounts to checking
- * the PCI data that the server has already collected. If there
- * is none, return.
- *
- * Although the config file is allowed to override things, it
- * is reasonable to not allow it to override the detection
- * of no PCI video cards.
- *
- * The provided xf86MatchPciInstances() helper takes care of
- * the details.
- */
- /* test if PCI bus present */
- if (xf86GetPciVideoInfo()) {
-
- numUsed = xf86MatchPciInstances(ZZZ_NAME, PCI_VENDOR_ZZZ,
- ZZZChipsets, ZZZPciChipsets, devSections,
- numDevSections, drv, &usedChips);
-
- for (i = 0; i < numUsed; i++) {
- ScrnInfoPtr pScrn = NULL;
- if ((pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
- ZZZPciChipsets, NULL, NULL,
- NULL, NULL, NULL))) {
- /* Allocate a ScrnInfoRec */
- pScrn->driverVersion = VERSION;
- pScrn->driverName = ZZZ_DRIVER_NAME;
- pScrn->name = ZZZ_NAME;
- pScrn->Probe = ZZZProbe;
- pScrn->PreInit = ZZZPreInit;
- pScrn->ScreenInit = ZZZScreenInit;
- pScrn->SwitchMode = ZZZSwitchMode;
- pScrn->AdjustFrame = ZZZAdjustFrame;
- pScrn->EnterVT = ZZZEnterVT;
- pScrn->LeaveVT = ZZZLeaveVT;
- pScrn->FreeScreen = ZZZFreeScreen;
- pScrn->ValidMode = ZZZValidMode;
- foundScreen = TRUE;
- /* add screen to entity */
- }
- }
- xfree(usedChips);
- }
-
-#ifdef HAS_ISA_DEVS
- /*
- * If the driver supports ISA hardware, the following block
- * can be included too.
- */
- numUsed = xf86MatchIsaInstances(ZZZ_NAME, ZZZChipsets,
- ZZZIsaChipsets, drv, ZZZFindIsaDevice,
- devSections, numDevSections, &usedChips);
- for (i = 0; i < numUsed; i++) {
- ScrnInfoPtr pScrn = NULL;
- if ((pScrn = xf86ConfigIsaEntity(pScrn, flags, usedChips[i],
- ZZZIsaChipsets, NULL, NULL, NULL,
- NULL, NULL))) {
- pScrn->driverVersion = VERSION;
- pScrn->driverName = ZZZ_DRIVER_NAME;
- pScrn->name = ZZZ_NAME;
- pScrn->Probe = ZZZProbe;
- pScrn->PreInit = ZZZPreInit;
- pScrn->ScreenInit = ZZZScreenInit;
- pScrn->SwitchMode = ZZZSwitchMode;
- pScrn->AdjustFrame = ZZZAdjustFrame;
- pScrn->EnterVT = ZZZEnterVT;
- pScrn->LeaveVT = ZZZLeaveVT;
- pScrn->FreeScreen = ZZZFreeScreen;
- pScrn->ValidMode = ZZZValidMode;
- foundScreen = TRUE;
- }
- }
- xfree(usedChips);
-#endif /* HAS_ISA_DEVS */
-
- xfree(devSections);
- return foundScreen;
- </code>
-
-<sect2>AvailableOptions
-<p>
-
- Define the &s.code;AvailableOptions()&e.code; function. The purpose
- of this is to return the available driver options back to the
- -configure option, so that an xorg.conf file can be built and the
- user can see which options are available for them to use.
-
-<sect2>PreInit
-<p>
-
- Define the &s.code;PreInit()&e.code; function. The purpose of
- this is to find all the information required to determine if the
- configuration is usable, and to initialise those parts of the
- &s.code;ScrnInfoRec&e.code; that can be set once at the beginning
- of the first server generation. The information should be found in
- the least intrusive way possible.
-
- This function is mandatory.
-
- NOTES:
- <enum>
- <item>The &s.code;PreInit()&e.code; function is only called once
- during the life of the X server (at the start of the first
- generation).
-
- <item>Data allocated here must be of the type that persists for
- the life of the X server. This means that data that hooks into
- the &s.code;ScrnInfoRec&e.code;'s &s.code;privates&e.code;
- field should be allocated here, but data that hooks into the
- &s.code;ScreenRec&e.code;'s &s.code;devPrivates&e.code; field
- should not be allocated here. The &s.code;driverPrivate&e.code;
- field should also be allocated here.
-
- <item>Although the &s.code;ScrnInfoRec&e.code; has been allocated
- before this function is called, the &s.code;ScreenRec&e.code;
- has not been allocated. That means that things requiring it
- cannot be used in this function.
-
- <item>Very little of the &s.code;ScrnInfoRec&e.code; has been
- initialised when this function is called. It is important to
- get the order of doing things right in this function.
-
- </enum>
-
- <code>
-static Bool
-ZZZPreInit(ScrnInfoPtr pScrn, int flags)
-{
- /* Fill in the monitor field */
- pScrn->monitor = pScrn->confScreen->monitor;
-
- /*
- * If using the vgahw module, it will typically be loaded
- * here by calling xf86LoadSubModule(pScrn, "vgahw");
- */
-
- /*
- * Set the depth/bpp. Use the globally preferred depth/bpp. If the
- * driver has special default depth/bpp requirements, the defaults should
- * be specified here explicitly.
- * We support both 24bpp and 32bpp framebuffer layouts.
- * This sets pScrn->display also.
- */
- if (!xf86SetDepthBpp(pScrn, 0, 0, 0,
- Support24bppFb | Support32bppFb)) {
- return FALSE;
- } else {
- if (depth/bpp isn't one we support) {
- print error message;
- return FALSE;
- }
- }
- /* Print out the depth/bpp that was set */
- xf86PrintDepthBpp(pScrn);
-
- /* Set bits per RGB for 8bpp */
- if (pScrn->depth <= 8) {
- /* Take into account a dac_6_bit option here */
- pScrn->rgbBits = 6 or 8;
- }
-
- /*
- * xf86SetWeight() and xf86SetDefaultVisual() must be called
- * after pScrn->display is initialised.
- */
-
- /* Set weight/mask/offset for depth > 8 */
- if (pScrn->depth > 8) {
- if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
- return FALSE;
- } else {
- if (weight isn't one we support) {
- print error message;
- return FALSE;
- }
- }
- }
-
- /* Set the default visual. */
- if (!xf86SetDefaultVisual(pScrn, -1)) {
- return FALSE;
- } else {
- if (visual isn't one we support) {
- print error message;
- return FALSE;
- }
- }
-
- /* If the driver supports gamma correction, set the gamma. */
- if (!xf86SetGamma(pScrn, default_gamma)) {
- return FALSE;
- }
-
- /* This driver uses a programmable clock */
- pScrn->progClock = TRUE;
-
- /* Allocate the ZZZRec driverPrivate */
- if (!ZZZGetRec(pScrn)) {
- return FALSE;
- }
-
- pZzz = ZZZPTR(pScrn);
-
- /* Collect all of the option flags (fill in pScrn->options) */
- xf86CollectOptions(pScrn, NULL);
-
- /*
- * Process the options based on the information in ZZZOptions.
- * The results are written to pZzz->Options. If all of the options
- * processing is done within this function a local variable "options"
- * can be used instead of pZzz->Options.
- */
- if (!(pZzz->Options = xalloc(sizeof(ZZZOptions))))
- return FALSE;
- (void)memcpy(pZzz->Options, ZZZOptions, sizeof(ZZZOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pZzz->Options);
-
- /*
- * Set various fields of ScrnInfoRec and/or ZZZRec based on
- * the options found.
- */
- from = X_DEFAULT;
- pZzz->hwCursor = FALSE;
- if (xf86IsOptionSet(pZzz->Options, OPTION_HW_CURSOR)) {
- from = X_CONFIG;
- pZzz->hwCursor = TRUE;
- }
- xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
- pZzz->hwCursor ? "HW" : "SW");
- if (xf86IsOptionSet(pZzz->Options, OPTION_NOACCEL)) {
- pZzz->noAccel = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Acceleration disabled\n");
- } else {
- pZzz->noAccel = FALSE;
- }
- if (xf86IsOptionSet(pZzz->Options, OPTION_PCI_RETRY)) {
- pZzz->UsePCIRetry = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
- }
- pZzz->fooHack = 0;
- if (xf86GetOptValInteger(pZzz->Options, OPTION_FOO_HACK,
- &pZzz->fooHack)) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Foo Hack set to %d\n",
- pZzz->fooHack);
- }
-
- /*
- * Find the PCI slot(s) that this screen claimed in the probe.
- * In this case, exactly one is expected, so complain otherwise.
- * Note in this case we're not interested in the card types so
- * that parameter is set to NULL.
- */
- if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL))
- != 1) {
- print error message;
- ZZZFreeRec(pScrn);
- if (i > 0)
- xfree(pciList);
- return FALSE;
- }
- /* Note that pciList should be freed below when no longer needed */
-
- /*
- * Determine the chipset, allowing config file chipset and
- * chipid values to override the probed information. The config
- * chipset value has precedence over its chipid value if both
- * are present.
- *
- * It isn't necessary to fill in pScrn->chipset if the driver
- * keeps track of the chipset in its ZZZRec.
- */
-
- ...
-
- /*
- * Determine video memory, fb base address, I/O addresses, etc,
- * allowing the config file to override probed values.
- *
- * Set the appropriate pScrn fields (videoRam is probably the
- * most important one that other code might require), and
- * print out the settings.
- */
-
- ...
-
- /* Initialise a clockRanges list. */
-
- ...
-
- /* Set any other chipset specific things in the ZZZRec */
-
- ...
-
- /* Select valid modes from those available */
-
- i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
- pScrn->display->modes, clockRanges,
- NULL, minPitch, maxPitch, rounding,
- minHeight, maxHeight,
- pScrn->display->virtualX,
- pScrn->display->virtualY,
- pScrn->videoRam * 1024,
- LOOKUP_BEST_REFRESH);
- if (i == -1) {
- ZZZFreeRec(pScrn);
- return FALSE;
- }
-
- /* Prune the modes marked as invalid */
-
- xf86PruneDriverModes(pScrn);
-
- /* If no valid modes, return */
-
- if (i == 0 || pScrn->modes == NULL) {
- print error message;
- ZZZFreeRec(pScrn);
- return FALSE;
- }
-
- /*
- * Initialise the CRTC fields for the modes. This driver expects
- * vertical values to be halved for interlaced modes.
- */
- xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
-
- /* Set the current mode to the first in the list. */
- pScrn->currentMode = pScrn->modes;
-
- /* Print the list of modes being used. */
- xf86PrintModes(pScrn);
-
- /* Set the DPI */
- xf86SetDpi(pScrn, 0, 0);
-
- /* Load bpp-specific modules */
- switch (pScrn->bitsPerPixel) {
- case 1:
- mod = "xf1bpp";
- break;
- case 4:
- mod = "xf4bpp";
- break;
- case 8:
- mod = "cfb";
- break;
- case 16:
- mod = "cfb16";
- break;
- case 24:
- mod = "cfb24";
- break;
- case 32:
- mod = "cfb32";
- break;
- }
- if (mod && !xf86LoadSubModule(pScrn, mod))
- ZZZFreeRec(pScrn);
- return FALSE;
-
- /* Load XAA if needed */
- if (!pZzz->noAccel || pZzz->hwCursor)
- if (!xf86LoadSubModule(pScrn, "xaa")) {
- ZZZFreeRec(pScrn);
- return FALSE;
- }
-
- /* Done */
- return TRUE;
-}
- </code>
-
-<sect2>MapMem, UnmapMem
-<p>
-
- Define functions to map and unmap the video memory and any other
- memory apertures required. These functions are not mandatory, but
- it is often useful to have such functions.
-
- <code>
-static Bool
-ZZZMapMem(ScrnInfoPtr pScrn)
-{
- /* Call xf86MapPciMem() to map each PCI memory area */
- ...
- return TRUE or FALSE;
-}
-
-static Bool
-ZZZUnmapMem(ScrnInfoPtr pScrn)
-{
- /* Call xf86UnMapVidMem() to unmap each memory area */
- ...
- return TRUE or FALSE;
-}
- </code>
-
-<sect2>Save, Restore
-<p>
-
- Define functions to save and restore the original video state. These
- functions are not mandatory, but are often useful.
-
- <code>
-static void
-ZZZSave(ScrnInfoPtr pScrn)
-{
- /*
- * Save state into per-screen data structures.
- * If using the vgahw module, vgaHWSave will typically be
- * called here.
- */
- ...
-}
-
-static void
-ZZZRestore(ScrnInfoPtr pScrn)
-{
- /*
- * Restore state from per-screen data structures.
- * If using the vgahw module, vgaHWRestore will typically be
- * called here.
- */
- ...
-}
- </code>
-
-<sect2>ModeInit
-<p>
-
- Define a function to initialise a new video mode. This function isn't
- mandatory, but is often useful.
-
- <code>
-static Bool
-ZZZModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- /*
- * Program a video mode. If using the vgahw module,
- * vgaHWInit and vgaRestore will typically be called here.
- * Once up to the point where there can't be a failure
- * set pScrn->vtSema to TRUE.
- */
- ...
-}
- </code>
-
-<sect2>ScreenInit
-<p>
-
- Define the &s.code;ScreenInit()&e.code; function. This is called
- at the start of each server generation, and should fill in as much
- of the &s.code;ScreenRec&e.code; as possible as well as any other
- data that is initialised once per generation. It should initialise
- the framebuffer layers it is using, and initialise the initial video
- mode.
-
- This function is mandatory.
-
- NOTE: The &s.code;ScreenRec&e.code; (&s.code;pScreen&e.code;) is
- passed to this driver, but it and the
- &s.code;ScrnInfoRecs&e.code; are not yet hooked into each
- other. This means that in this function, and functions it
- calls, one cannot be found from the other.
-
- <code>
-static Bool
-ZZZScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
-{
- /* Get the ScrnInfoRec */
- pScrn = xf86Screens[pScreen->myNum];
-
- /*
- * If using the vgahw module, its data structures and related
- * things are typically initialised/mapped here.
- */
-
- /* Save the current video state */
- ZZZSave(pScrn);
-
- /* Initialise the first mode */
- ZZZModeInit(pScrn, pScrn->currentMode);
-
- /* Set the viewport if supported */
-
- ZZZAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
- /*
- * Setup the screen's visuals, and initialise the framebuffer
- * code.
- */
-
- /* Reset the visual list */
- miClearVisualTypes();
-
- /*
- * Setup the visuals supported. This driver only supports
- * TrueColor for bpp > 8, so the default set of visuals isn't
- * acceptable. To deal with this, call miSetVisualTypes with
- * the appropriate visual mask.
- */
-
- if (pScrn->bitsPerPixel > 8) {
- if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
- pScrn->rgbBits, pScrn->defaultVisual))
- return FALSE;
- } else {
- if (!miSetVisualTypes(pScrn->depth,
- miGetDefaultVisualMask(pScrn->depth),
- pScrn->rgbBits, pScrn->defaultVisual))
- return FALSE;
- }
-
- /*
- * Initialise the framebuffer.
- */
-
- switch (pScrn->bitsPerPixel) {
- case 1:
- ret = xf1bppScreenInit(pScreen, FbBase,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth);
- break;
- case 4:
- ret = xf4bppScreenInit(pScreen, FbBase,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth);
- break;
- case 8:
- ret = cfbScreenInit(pScreen, FbBase,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth);
- break;
- case 16:
- ret = cfb16ScreenInit(pScreen, FbBase,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth);
- break;
- case 24:
- ret = cfb24ScreenInit(pScreen, FbBase,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth);
- break;
- case 32:
- ret = cfb32ScreenInit(pScreen, FbBase,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth);
- break;
- default:
- print a message about an internal error;
- ret = FALSE;
- break;
- }
-
- if (!ret)
- return FALSE;
-
- /* Override the default mask/offset settings */
- if (pScrn->bitsPerPixel > 8) {
- for (i = 0, visual = pScreen->visuals;
- i < pScreen->numVisuals; i++, visual++) {
- if ((visual->class | DynamicClass) == DirectColor) {
- visual->offsetRed = pScrn->offset.red;
- visual->offsetGreen = pScrn->offset.green;
- visual->offsetBlue = pScrn->offset.blue;
- visual->redMask = pScrn->mask.red;
- visual->greenMask = pScrn->mask.green;
- visual->blueMask = pScrn->mask.blue;
- }
- }
- }
-
- /*
- * If banking is needed, initialise an miBankInfoRec (defined in
- * "mibank.h"), and call miInitializeBanking().
- */
- if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
- pScrn->displayWidth, pBankInfo))
- return FALSE;
-
- /*
- * If backing store is to be supported (as is usually the case),
- * initialise it.
- */
- miInitializeBackingStore(pScreen);
-
- /*
- * Set initial black & white colourmap indices.
- */
- xf86SetBlackWhitePixels(pScreen);
-
- /*
- * Install colourmap functions. If using the vgahw module,
- * vgaHandleColormaps would usually be called here.
- */
-
- ...
-
- /*
- * Initialise cursor functions. This example is for the mi
- * software cursor.
- */
- miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
-
- /* Initialise the default colourmap */
- switch (pScrn->depth) {
- case 1:
- if (!xf1bppCreateDefColormap(pScreen))
- return FALSE;
- break;
- case 4:
- if (!xf4bppCreateDefColormap(pScreen))
- return FALSE;
- break;
- default:
- if (!cfbCreateDefColormap(pScreen))
- return FALSE;
- break;
- }
-
- /*
- * Wrap the CloseScreen vector and set SaveScreen.
- */
- ZZZPTR(pScrn)->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = ZZZCloseScreen;
- pScreen->SaveScreen = ZZZSaveScreen;
-
- /* Report any unused options (only for the first generation) */
- if (serverGeneration == 1) {
- xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
- }
-
- /* Done */
- return TRUE;
-}
- </code>
-
-
-<sect2>SwitchMode
-<p>
-
- Define the &s.code;SwitchMode()&e.code; function if mode switching
- is supported by the driver.
-
- <code>
-static Bool
-ZZZSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
-{
- return ZZZModeInit(xf86Screens[scrnIndex], mode);
-}
- </code>
-
-
-<sect2>AdjustFrame
-<p>
-
- Define the &s.code;AdjustFrame()&e.code; function if the driver
- supports this.
-
- <code>
-static void
-ZZZAdjustFrame(int scrnIndex, int x, int y, int flags)
-{
- /* Adjust the viewport */
-}
- </code>
-
-
-<sect2>EnterVT, LeaveVT
-<p>
-
- Define the &s.code;EnterVT()&e.code; and &s.code;LeaveVT()&e.code;
- functions.
-
- These functions are mandatory.
-
- <code>
-static Bool
-ZZZEnterVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- return ZZZModeInit(pScrn, pScrn->currentMode);
-}
-
-static void
-ZZZLeaveVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- ZZZRestore(pScrn);
-}
- </code>
-
-<sect2>CloseScreen
-<p>
-
- Define the &s.code;CloseScreen()&e.code; function:
-
- This function is mandatory. Note that it unwraps the previously
- wrapped &s.code;pScreen->CloseScreen&e.code;, and finishes by
- calling it.
-
- <code>
-static Bool
-ZZZCloseScreen(int scrnIndex, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- if (pScrn->vtSema) {
- ZZZRestore(pScrn);
- ZZZUnmapMem(pScrn);
- }
- pScrn->vtSema = FALSE;
- pScreen->CloseScreen = ZZZPTR(pScrn)->CloseScreen;
- return (*pScreen->CloseScreen)(scrnIndex, pScreen);
-}
- </code>
-
-<sect2>SaveScreen
-<p>
-
- Define the &s.code;SaveScreen()&e.code; function (the screen
- blanking function). When using the vgahw module, this will typically
- be:
-
- <code>
-static Bool
-ZZZSaveScreen(ScreenPtr pScreen, int mode)
-{
- return vgaHWSaveScreen(pScreen, mode);
-}
- </code>
-
- This function is mandatory. Before modifying any hardware register
- directly this function needs to make sure that the Xserver is active
- by checking if &s.code;pScrn&e.code; is non-NULL and for
- &s.code;pScrn->vtSema == TRUE&e.code;.
-
-<sect2>FreeScreen
-<p>
-
- Define the &s.code;FreeScreen()&e.code; function. This function
- is optional. It should be defined if the &s.code;ScrnInfoRec&e.code;
- &s.code;driverPrivate&e.code; field is used so that it can be freed
- when a screen is deleted by the common layer for reasons possibly
- beyond the driver's control. This function is not used in during
- normal (error free) operation. The per-generation data is freed by
- the &s.code;CloseScreen()&e.code; function.
-
- <code>
-static void
-ZZZFreeScreen(int scrnIndex, int flags)
-{
- /*
- * If the vgahw module is used vgaHWFreeHWRec() would be called
- * here.
- */
- ZZZFreeRec(xf86Screens[scrnIndex]);
-}
- </code>
-
-
-</article>
diff --git a/xorg-server/hw/xfree86/doc/sgml/DESIGN.xml b/xorg-server/hw/xfree86/doc/sgml/DESIGN.xml new file mode 100644 index 000000000..ff132a182 --- /dev/null +++ b/xorg-server/hw/xfree86/doc/sgml/DESIGN.xml @@ -0,0 +1,9401 @@ +<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+ <!ENTITY % defs SYSTEM "/xserver/doc/xml/xserver.ent"> %defs;
+ <!-- config file keyword markup -->
+ <!-- specific config file keywords -->
+ <!ENTITY k.device "<emphasis>Device</emphasis>">
+ <!ENTITY k.monitor "<emphasis>Monitor</emphasis>">
+ <!ENTITY k.display "<emphasis>Display</emphasis>">
+ <!ENTITY k.inputdevice "<emphasis>InputDevice</emphasis>">
+ <!ENTITY k.screen "<emphasis>Screen</emphasis>">
+ <!ENTITY k.serverlayout "<emphasis>ServerLayout</emphasis>">
+ <!ENTITY k.driver "<emphasis>Driver</emphasis>">
+ <!ENTITY k.module "<emphasis>Module</emphasis>">
+ <!ENTITY k.identifier "<emphasis>Identifier</emphasis>">
+ <!ENTITY k.serverflags "<emphasis>ServerFlags</emphasis>">
+] >
+
+<article>
+ <articleinfo>
+
+ <title>XFree86 DDX Design (Xorg server version &xserver.version;)</title>
+
+ <authorgroup>
+ <corpauthor><ulink url="http://www.xfree86.org/">
+ The XFree86 Project, Inc.</ulink></corpauthor>
+ <corpauthor><ulink url="http://www.x.org/">
+ The X.Org Foundation, Inc.</ulink></corpauthor>
+
+ <othercredit>
+ <firstname>Jim</firstname><surname>Gettys</surname>
+ <contrib>Updates for X11R6.7</contrib>
+ </othercredit>
+ </authorgroup>
+
+ <pubdate>&xserver.reldate;</pubdate>
+ <releaseinfo>Xorg server version &xserver.version;</releaseinfo>
+
+ </articleinfo>
+
+ <note><para>
+This document describes software undergoing continual evolution, and
+the interfaces described here are subject to change without notice.
+This document is intended to cover the interfaces as found in the
+xorg-server-&xserver.version; release, but is probably not completely
+in sync with the code base.
+ </para></note>
+
+
+ <sect1>
+ <title>Preface</title>
+
+ <para>
+This document was originally the design spec for the DDX layer of the
+XFree86 4.0 X server. The X.Org Foundation adopted the XFree86 4.4rc2
+version of that server as the basis of the Xorg server project, and has
+evolved the XFree86 DDX layer greatly since forking. This document thus
+covers only the current implementation of the XFree86 DDX as found in the
+Xorg server &xserver.version; release, and no longer matches the XFree86
+server itself.
+ </para>
+
+ <para>
+The XFree86 Project's broad design principles for XFree86 4.0 were:
+ <itemizedlist>
+ <listitem><para>keep it reasonable
+ <itemizedlist>
+ <listitem><para>We cannot rewrite the complete server
+ </para></listitem>
+ <listitem><para>We don't want to re-invent the wheel
+ </para></listitem>
+ </itemizedlist></para></listitem>
+ <listitem><para>keep it modular
+ <itemizedlist>
+ <listitem><para>As many things as possible should go into modules
+ </para></listitem>
+ <listitem><para>The basic loader binary should be minimal
+ </para></listitem>
+ <listitem><para>A clean design with well defined layering is
+ important</para></listitem>
+ <listitem><para>DDX specific global variables are a nono
+ </para></listitem>
+ <listitem><para>The structure should be flexible enough to allow
+ future extensions</para></listitem>
+ <listitem><para>The structure should minimize duplication of
+ common code</para></listitem>
+ </itemizedlist></para></listitem>
+ <listitem><para>keep important features in mind
+ <itemizedlist>
+ <listitem><para>multiple screens, including multiple instances
+ of drivers</para></listitem>
+ <listitem><para>mixing different color depths and visuals on
+ different and ideally even on the same screen
+ </para></listitem>
+ <listitem><para>better control of the PCI device used
+ </para></listitem>
+ <listitem><para>better config file parser</para></listitem>
+ <listitem><para>get rid of all VGA compatibility assumptions
+ </para></listitem>
+ </itemizedlist></para></listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+While the XFree86 project had a goal of avoiding changes to the DIX
+layer unless they found major deficiencies there, to avoid divergence from
+the X.Org sample implementation they were integrating changes from, the
+X.Org developers now maintain both sides, and make changes where they are
+most appropriate. This document concentrates on the XFree86 DDX layer used
+in the Xorg server itself (the code found in <filename>hw/xfree86</filename>
+in the source tree), and developers will also want to refer to the
+<filename>Xserver-spec</filename> documentation that covers the DIX layer
+routines common to all the X servers in the sample implementation.
+ </para>
+ </sect1>
+
+ <sect1>
+ <title>The xorg.conf File</title>
+
+ <para>
+The xorg.conf file format is similar to the old format, with the following
+changes:
+ </para>
+
+ <sect2>
+ <title>&k.device; section</title>
+
+ <para>
+ The &k.device; sections are similar to what they used to be, and
+ describe hardware-specific information for a single video card.
+ &k.device;
+ Some new keywords are added:
+
+
+ <variablelist>
+ <varlistentry><term>Driver "drivername"</term>
+ <listitem><para>
+ Specifies the name of the driver to be used for the card. This
+ is mandatory.
+ </para></listitem></varlistentry>
+ <varlistentry><term>BusID "busslot"</term>
+ <listitem><para>
+ Specifies uniquely the location of the card on the bus. The
+ purpose is to identify particular cards in a multi-headed
+ configuration. The format of the argument is intentionally
+ vague, and may be architecture dependent. For a PCI bus, it
+ is something like "bus:slot:func".
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ A &k.device; section is considered <quote>active</quote> if there is a reference
+ to it in an active &k.screen; section.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>&k.screen; section</title>
+
+ <para>
+ The &k.screen; sections are similar to what they used to be. They
+ no longer have a &k.driver; keyword, but an &k.identifier; keyword
+ is added. (The &k.driver; keyword may be accepted in place of the
+ &k.identifier; keyword for compatibility purposes.) The identifier
+ can be used to identify which screen is to be active when multiple
+ &k.screen; sections are present. It is possible to specify the active
+ screen from the command line. A default is chosen in the absence
+ of one being specified. A &k.screen; section is considered <quote>active</quote>
+ if there is a reference to it either from the command line, or from
+ an active &k.serverlayout; section.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>&k.inputdevice; section</title>
+
+ <para>
+ The &k.inputdevice; section is a new section that describes
+ configuration information for input devices. It replaces the old
+ <emphasis>Keyboard</emphasis>, <emphasis>Pointer</emphasis> and <emphasis>XInput</emphasis>
+ sections. Like the &k.device; section, it has two mandatory keywords:
+ &k.identifier; and &k.driver;. For compatibility purposes the old
+ <emphasis>Keyboard</emphasis> and <emphasis>Pointer</emphasis> sections are
+ converted by the parser into &k.inputdevice; sections as follows:
+
+ <variablelist>
+ <varlistentry><term><emphasis>Keyboard</emphasis></term>
+ <listitem><literallayout>
+ &k.identifier; "Implicit Core Keyboard"
+ &k.driver; "keyboard"
+ </literallayout></listitem></varlistentry>
+ <varlistentry><term><emphasis>Pointer</emphasis></term>
+ <listitem><literallayout>
+ &k.identifier; "Implicit Core Pointer"
+ &k.driver; "mouse"
+ </literallayout></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ An &k.inputdevice; section is considered active if there is a
+ reference to it in an active &k.serverlayout; section. An
+ &k.inputdevice; section may also be referenced implicitly if there
+ is no &k.serverlayout; section, if the <option>-screen</option> command
+ line options is used, or if the &k.serverlayout; section doesn't
+ reference any &k.inputdevice; sections. In this case, the first
+ sections with drivers "keyboard" and "mouse" are used as the core
+ keyboard and pointer respectively.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>&k.serverlayout; section</title>
+
+ <para>
+ The &k.serverlayout; section is a new section that is used to identify
+ which &k.screen; sections are to be used in a multi-headed configuration,
+ and the relative layout of those screens. It also identifies which
+ &k.inputdevice; sections are to be used. Each &k.serverlayout; section
+ has an identifier, a list of &k.screen; section identifiers, and a list of
+ &k.inputdevice; section identifiers. &k.serverflags; options may also be
+ included in a &k.serverlayout; section, making it possible to override
+ the global values in the &k.serverflags; section.
+ </para>
+
+ <para>
+ A &k.serverlayout; section can be made active by being referenced on
+ the command line. In the absence of this, a default will be chosen
+ (the first one found). The screen names may optionally be followed
+ by a number specifying the preferred screen number, and optionally
+ by information specifying the physical positioning of the screen,
+ either in absolute terms or relative to another screen (or screens).
+ When no screen number is specified, they are numbered according to
+ the order in which they are listed. The old (now obsolete) method
+ of providing the positioning information is to give the names of
+ the four adjacent screens. The order of these is top, bottom, left,
+ right. Here is an example of a &k.serverlayout; section for two
+ screens using the old method, with the second located to the right
+ of the first:
+
+ <programlisting>
+ Section "ServerLayout"
+ Identifier "Main Layout"
+ Screen 0 "Screen 1" "" "" "" "Screen 2"
+ Screen 1 "Screen 2"
+ Screen "Screen 3"
+ EndSection
+ </programlisting>
+ </para>
+
+ <para>
+ The preferred way of specifying the layout is to explicitly specify
+ the screen's location in absolute terms or relative to another
+ screen.
+ </para>
+
+ <para>
+ In the absolute case, the upper left corner's coordinates are given
+ after the <emphasis>Absolute</emphasis> keyword. If the coordinates are
+ omitted, a value of <code>(0,0)</code> is assumed. An example
+ of absolute positioning follows:
+
+ <programlisting>
+ Section "ServerLayout"
+ Identifier "Main Layout"
+ Screen 0 "Screen 1" Absolute 0 0
+ Screen 1 "Screen 2" Absolute 1024 0
+ Screen "Screen 3" Absolute 2048 0
+ EndSection
+ </programlisting>
+ </para>
+
+ <para>
+ In the relative case, the position is specified by either using one of
+ the following keywords followed by the name of the reference screen:
+
+ <simplelist type='vert' columns='1'>
+ <member><emphasis>RightOf</emphasis></member>
+ <member><emphasis>LeftOf</emphasis></member>
+ <member><emphasis>Above</emphasis></member>
+ <member><emphasis>Below</emphasis></member>
+ <member><emphasis>Relative</emphasis></member>
+ </simplelist>
+ </para>
+
+ <para>
+ When the <emphasis>Relative</emphasis> keyword is used, the reference screen
+ name is followed by the coordinates of the new screen's origin
+ relative to reference screen. The following example shows how to use
+ some of the relative positioning options.
+
+ <programlisting>
+ Section "ServerLayout"
+ Identifier "Main Layout"
+ Screen 0 "Screen 1"
+ Screen 1 "Screen 2" RightOf "Screen 1"
+ Screen "Screen 3" Relative "Screen 1" 2048 0
+ EndSection
+ </programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Options</title>
+
+ <para>
+ Options are used more extensively. They may appear in most sections
+ now. Options related to drivers can be present in the &k.screen;,
+ &k.device; and &k.monitor; sections and the &k.display; subsections.
+ The order of precedence is &k.display;, &k.screen;, &k.monitor;,
+ &k.device;. Options have been extended to allow an optional value
+ to be specified in addition to the option name. For more details
+ about options, see the <link linkend="options">Options</link> section
+ for details.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>Driver Interface</title>
+
+ <para>
+The driver interface consists of a minimal set of entry points that are
+required based on the external events that the driver must react to.
+No non-essential structure is imposed on the way they are used beyond
+that. This is a significant difference compared with the old design.
+ </para>
+
+ <para>
+The entry points for drawing operations are already taken care of by
+the framebuffer code (including, XAA). Extensions and enhancements to
+framebuffer code are outside the scope of this document.
+ </para>
+
+ <para>
+This approach to the driver interface provides good flexibility, but does
+increase the complexity of drivers. To help address this, the XFree86
+common layer provides a set of <quote>helper</quote> functions to take care of things
+that most drivers need. These helpers help minimise the amount of code
+duplication between drivers. The use of helper functions by drivers is
+however optional, though encouraged. The basic philosophy behind the
+helper functions is that they should be useful to many drivers, that
+they should balance this against the complexity of their interface. It
+is inevitable that some drivers may find some helpers unsuitable and
+need to provide their own code.
+ </para>
+
+ <para>
+Events that a driver needs to react to are:
+
+ <variablelist>
+ <varlistentry><term>ScreenInit</term>
+
+ <listitem><para>
+ An initialisation function is called from the DIX layer for each
+ screen at the start of each server generation.
+ </para></listitem></varlistentry>
+
+ <varlistentry><term>Enter VT</term>
+
+ <listitem><para>
+ The server takes control of the console.
+ </para></listitem></varlistentry>
+
+ <varlistentry><term>Leave VT</term>
+
+ <listitem><para>
+ The server releases control of the console.
+ </para></listitem></varlistentry>
+
+ <varlistentry><term>Mode Switch</term>
+
+ <listitem><para>
+ Change video mode.
+ </para></listitem></varlistentry>
+
+ <varlistentry><term>ViewPort change</term>
+
+ <listitem><para>
+ Change the origin of the physical view port.
+ </para></listitem></varlistentry>
+
+ <varlistentry><term>ScreenSaver state change</term>
+
+ <listitem><para>
+ Screen saver activation/deactivation.
+ </para></listitem></varlistentry>
+
+ <varlistentry><term>CloseScreen</term>
+
+ <listitem><para>
+ A close screen function is called from the DIX layer for each screen
+ at the end of each server generation.
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+
+ <para>
+In addition to these events, the following functions are required by
+the XFree86 common layer:
+
+ <variablelist>
+ <varlistentry><term>Identify</term>
+
+ <listitem><para>
+ Print a driver identifying message.
+ </para></listitem></varlistentry>
+
+ <varlistentry><term>Probe</term>
+
+ <listitem><para>
+ This is how a driver identifies if there is any hardware present that
+ it knows how to drive.
+ </para></listitem></varlistentry>
+
+ <varlistentry><term>PreInit</term>
+
+ <listitem><para>
+ Process information from the xorg.conf file, determine the
+ full characteristics of the hardware, and determine if a valid
+ configuration is present.
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+The VidMode extension also requires:
+
+ <variablelist>
+ <varlistentry><term>ValidMode</term>
+
+ <listitem><para>
+ Identify if a new mode is usable with the current configuration.
+ The PreInit function (and/or helpers it calls) may also make use
+ of the ValidMode function or something similar.
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+
+ <para>
+Other extensions may require other entry points. The drivers will
+inform the common layer of these in such cases.
+ </para>
+ </sect1>
+
+ <sect1>
+ <title>Resource Access Control Introduction</title>
+
+ <para>
+Graphics devices are accessed through ranges in I/O or memory space.
+While most modern graphics devices allow relocation of such ranges many
+of them still require the use of well established interfaces such as
+VGA memory and IO ranges or 8514/A IO ranges. With modern buses (like
+PCI) it is possible for multiple video devices to share access to these
+resources. The RAC (Resource Access Control) subsystem provides a
+mechanism for this.
+ </para>
+
+ <sect2>
+ <title>Terms and Definitions</title>
+
+ <sect3>
+ <title>Bus</title>
+
+ <para>
+ <quote>Bus</quote> is ambiguous as it is used for different things: it may refer
+ to physical incompatible extension connectors in a computer system.
+ The RAC system knows two such systems: The ISA bus and the PCI bus.
+ (On the software level EISA, MCA and VL buses are currently treated
+ like ISA buses). <quote>Bus</quote> may also refer to logically different
+ entities on a single bus system which are connected via bridges. A
+ PCI system may have several distinct PCI buses connecting each other
+ by PCI-PCI bridges or to the host CPU by HOST-PCI bridges.
+ </para>
+
+ <para>
+ Systems that host more than one bus system link these together using
+ bridges. Bridges are a concern to RAC as they might block or pass
+ specific resources. PCI-PCI bridges may be set up to pass VGA
+ resources to the secondary bus. PCI-ISA buses pass any resources not
+ decoded on the primary PCI bus to the ISA bus. This way VGA resources
+ (although exclusive on the ISA bus) can be shared by ISA and PCI
+ cards. Currently HOST-PCI bridges are not yet handled by RAC as they
+ require specific drivers.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Entity</title>
+
+ <para>
+ The smallest independently addressable unit on a system bus is
+ referred to as an entity. So far we know ISA and PCI entities. PCI
+ entities can be located on the PCI bus by an unique ID consisting of
+ the bus, card and function number.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Resource</title>
+
+ <para>
+ <quote>Resource</quote> refers to a range of memory or I/O addresses an entity
+ can decode.
+ </para>
+
+ <para>
+ If a device is capable of disabling this decoding the resource is
+ called sharable. For PCI devices a generic method is provided to
+ control resource decoding. Other devices will have to provide a
+ device specific function to control decoding.
+ </para>
+
+ <para>
+ If the entity is capable of decoding this range at a different
+ location this resource is considered relocatable.
+ </para>
+
+ <para>
+ Resources which start at a specific address and occupy a single
+ continuous range are called block resources.
+ </para>
+
+ <para>
+ Alternatively resource addresses can be decoded in a way that they
+ satisfy the conditions:
+ <programlisting>
+ address & mask == base
+ </programlisting>
+ and
+ <programlisting>
+ base & mask == base
+ </programlisting>
+ Resources addressed in such a way are called sparse resources.
+ </para>
+
+ </sect3>
+
+ <sect3>
+ <title>Server States</title>
+
+ <para>
+ The resource access control system knows two server states: the
+ SETUP and the OPERATING state. The SETUP state is entered whenever
+ a mode change takes place or the server exits or does VT switching.
+ During this state all entity resources are under resource access
+ control. During OPERATING state only those entities are controlled
+ which actually have shared resources that conflict with others.
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>Control Flow in the Server and Mandatory Driver Functions</title>
+
+ <para>
+At the start of each server generation, <function>main()</function>
+(<filename>dix/main.c</filename>) calls the DDX function
+<function>InitOutput()</function>. This is the first place that the DDX gets
+control. <function>InitOutput()</function> is expected to fill in the global
+<structname>screenInfo</structname> struct, and one
+<structfield>screenInfo.screen[]</structfield> entry for each screen present.
+Here is what <function>InitOutput()</function> does:
+ </para>
+
+ <sect2>
+ <title>Parse the xorg.conf file</title>
+
+ <para>
+ This is done at the start of the first server generation only.
+ </para>
+
+ <para>
+ The xorg.conf file is read in full, and the resulting information
+ stored in data structures. None of the parsed information is
+ processed at this point. The parser data structures are opaque to
+ the video drivers and to most of the common layer code.
+ </para>
+
+ <para>
+ The entire file is parsed first to remove any section ordering
+ requirements.
+ </para>
+ </sect2>
+
+
+ <sect2>
+ <title>Initial processing of parsed information and command line options
+ </title>
+
+ <para>
+ This is done at the start of the first server generation only.
+ </para>
+
+ <para>
+ The initial processing is to determine paths like the
+ <emphasis>ModulePath</emphasis>, etc, and to determine which &k.serverlayout;,
+ &k.screen; and &k.device; sections are active.
+ </para>
+ </sect2>
+
+
+ <sect2>
+ <title>Enable port I/O access</title>
+
+ <para>
+ Port I/O access is controlled from the XFree86 common layer, and is
+ <quote>all or nothing</quote>. It is enabled prior to calling driver probes, at
+ the start of subsequent server generations, and when VT switching
+ back to the Xserver. It is disabled at the end of server generations,
+ and when VT switching away from the Xserver.
+ </para>
+
+ <para>
+ The implementation details of this may vary on different platforms.
+ </para>
+ </sect2>
+
+
+ <sect2>
+ <title>General bus probe</title>
+
+ <para>
+ This is done at the start of the first server generation only.
+ </para>
+
+ <para>
+ In the case of ix86 machines, this will be a general PCI probe.
+ The full information obtained here will be available to the drivers.
+ This information persists for the life of the Xserver. In the PCI
+ case, the PCI information for all video cards found is available by
+ calling <function>xf86GetPciVideoInfo()</function>.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ pciVideoPtr *xf86GetPciVideoInfo(void);
+ </programlisting>
+ <blockquote><para>
+ returns a pointer to a list of pointers to
+ <structname>pciVideoRec</structname> entries, of which there is one for
+ each detected PCI video card. The list is terminated with a
+ <constant>NULL</constant> pointer. If no PCI video cards were
+ detected, the return value is <constant>NULL</constant>.
+
+ </para></blockquote>
+ </para></blockquote>
+
+ <para>
+ After the bus probe, the resource broker is initialised.
+ </para>
+ </sect2>
+
+
+ <sect2>
+ <title>Load initial set of modules</title>
+
+ <para>
+ This is done at the start of the first server generation only.
+ </para>
+
+ <para>
+ The core server contains a list of mandatory modules. These are loaded
+ first. Currently the only module on this list is the bitmap font module.
+ </para>
+
+ <para>
+ The next set of modules loaded are those specified explicitly in the
+ &k.module; section of the config file.
+ </para>
+
+ <para>
+ The final set of initial modules are the driver modules referenced
+ by the active &k.device; and &k.inputdevice; sections in the config
+ file. Each of these modules is loaded exactly once.
+ </para>
+ </sect2>
+
+
+ <sect2>
+ <title>Register Video and Input Drivers</title>
+
+ <para>
+ This is done at the start of the first server generation only.
+ </para>
+
+ <para>
+ When a driver module is loaded, the loader calls its
+ <function>Setup</function> function. For video drivers, this function
+ calls <function>xf86AddDriver()</function> to register the driver's
+ <structname>DriverRec</structname>, which contains a small set of essential
+ details and driver entry points required during the early phase of
+ <function>InitOutput()</function>. <function>xf86AddDriver()</function>
+ adds it to the global <varname>xf86DriverList[]</varname> array.
+ </para>
+
+ <para>
+ The <structname>DriverRec</structname> contains the driver canonical name,
+ the <function>Identify()</function>,
+ <function>Probe()</function> and <function>AvailableOptions()</function>
+ function entry points as well as a pointer
+ to the driver's module (as returned from the loader when the driver
+ was loaded) and a reference count which keeps track of how many
+ screens are using the driver. The entry driver entry points are
+ those required prior to the driver allocating and filling in its
+ <structname>ScrnInfoRec</structname>.
+ </para>
+
+ <para>
+ For a static server, the <varname>xf86DriverList[]</varname> array is
+ initialised at build time, and the loading of modules is not done.
+ </para>
+
+ <para>
+ A similar procedure is used for input drivers. The input driver's
+ <function>Setup</function> function calls
+ <function>xf86AddInputDriver()</function> to register the driver's
+ <structname>InputDriverRec</structname>, which contains a small set of
+ essential details and driver entry points required during the early
+ phase of <function>InitInput()</function>.
+ <function>xf86AddInputDriver()</function> adds it to the global
+ <varname>xf86InputDriverList[]</varname> array. For a static server,
+ the <varname>xf86InputDriverList[]</varname> array is initialised at
+ build time.
+ </para>
+
+ <para>
+ Both the <varname>xf86DriverList[]</varname> and
+ <varname>xf86InputDriverList[]</varname> arrays have been initialised
+ by the end of this stage.
+ </para>
+
+ <para>
+ Once all the drivers are registered, their
+ <function>ChipIdentify()</function> functions are called.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ void ChipIdentify(int flags);
+ </programlisting>
+ <blockquote><para>
+ This is expected to print a message indicating the driver name,
+ a short summary of what it supports, and a list of the chipset
+ names that it supports. It may use the xf86PrintChipsets() helper
+ to do this.
+ </para></blockquote>
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86PrintChipsets(const char *drvname, const char *drvmsg,
+ SymTabPtr chips);
+ </programlisting>
+ <blockquote><para>
+ This function provides an easy way for a driver's ChipIdentify
+ function to format the identification message.
+ </para></blockquote>
+ </para></blockquote>
+ </sect2>
+
+ <sect2>
+ <title>Initialise Access Control</title>
+
+ <para>
+ This is done at the start of the first server generation only.
+ </para>
+
+ <para>
+ The Resource Access Control (RAC) subsystem is initialised before
+ calling any driver functions that may access hardware. All generic
+ bus information is probed and saved (for restoration later). All
+ (shared resource) video devices are disabled at the generic bus
+ level, and a probe is done to find the <quote>primary</quote> video device. These
+ devices remain disabled for the next step.
+ </para>
+ </sect2>
+
+
+ <sect2 id="probe">
+ <title>Video Driver Probe</title>
+
+ <para>
+ This is done at the start of the first server generation only. The
+ <function>ChipProbe()</function> function of each registered video driver
+ is called.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool ChipProbe(DriverPtr drv, int flags);
+ </programlisting>
+ <blockquote><para>
+ The purpose of this is to identify all instances of hardware
+ supported by the driver. The flags value is currently either 0,
+ <constant>PROBE_DEFAULT</constant> or <constant>PROBE_DETECT</constant>.
+ <constant>PROBE_DETECT</constant> is used if "-configure" or "-probe"
+ command line arguments are given and indicates to the
+ <function>Probe()</function> function that it should not configure the
+ bus entities and that no xorg.conf information is available.
+ </para>
+
+ <para>
+ The probe must find the active device sections that match the
+ driver by calling <function>xf86MatchDevice()</function>. The number
+ of matches found limits the maximum number of instances for this
+ driver. If no matches are found, the function should return
+ <constant>FALSE</constant> immediately.
+ </para>
+
+ <para>
+ Devices that cannot be identified by using device-independent
+ methods should be probed at this stage (keeping in mind that access
+ to all resources that can be disabled in a device-independent way
+ are disabled during this phase). The probe must be a minimal
+ probe. It should just determine if there is a card present that
+ the driver can drive. It should use the least intrusive probe
+ methods possible. It must not do anything that is not essential,
+ like probing for other details such as the amount of memory
+ installed, etc. It is recommended that the
+ <function>xf86MatchPciInstances()</function> helper function be used
+ for identifying matching PCI devices, and similarly the
+ <function>xf86MatchIsaInstances()</function> for ISA (non-PCI) devices
+ (see the <link linkend="rac">RAC</link> section). These helpers also
+ checks and claims the appropriate entity. When not using the
+ helper, that should be done with <function>xf86CheckPciSlot()</function>
+ and <function>xf86ClaimPciSlot()</function> for PCI devices and
+ <function>xf86ClaimIsaSlot()</function> for ISA devices (see the
+ <link linkend="rac">RAC</link> section).
+ </para>
+
+ <para>
+ The probe must register all non-relocatable resources at this
+ stage. If a resource conflict is found between exclusive resources
+ the driver will fail immediately. This is usually best done with
+ the <function>xf86ConfigPciEntity()</function> helper function
+ for PCI and <function>xf86ConfigIsaEntity()</function> for ISA
+ (see the <link linkend="rac">RAC</link> section). It is possible to
+ register some entity specific functions with those helpers. When
+ not using the helpers, the <function>xf86AddEntityToScreen()</function>
+ <function>xf86ClaimFixedResources()</function> and
+ <function>xf86SetEntityFuncs()</function> should be used instead (see
+ the <link linkend="rac">RAC</link> section).
+ </para>
+
+ <para>
+ If a chipset is specified in an active device section which the
+ driver considers relevant (ie it has no driver specified, or the
+ driver specified matches the driver doing the probe), the Probe
+ must return <constant>FALSE</constant> if the chipset doesn't match
+ one supported by the driver.
+ </para>
+
+ <para>
+ If there are no active device sections that the driver considers
+ relevant, it must return <constant>FALSE</constant>.
+ </para>
+
+ <para>
+ Allocate a <structname>ScrnInfoRec</structname> for each active instance of the
+ hardware found, and fill in the basic information, including the
+ other driver entry points. This is best done with the
+ <function>xf86ConfigIsaEntity()</function> helper function for ISA
+ instances or <function>xf86ConfigPciEntity()</function> for PCI instances.
+ These functions allocate a <structname>ScrnInfoRec</structname> for active
+ entities. Optionally <function>xf86AllocateScreen()</function>
+ function may also be used to allocate the <structname>ScrnInfoRec</structname>.
+ Any of these functions take care of initialising fields to defined
+ <quote>unused</quote> values.
+ </para>
+
+ <para>
+ Claim the entities for each instance of the hardware found. This
+ prevents other drivers from claiming the same hardware.
+ </para>
+
+ <para>
+ Must leave hardware in the same state it found it in, and must not
+ do any hardware initialisation.
+ </para>
+
+ <para>
+ All detection can be overridden via the config file, and that
+ parsed information is available to the driver at this stage.
+ </para>
+
+ <para>
+ Returns <constant>TRUE</constant> if one or more instances are found,
+ and <constant>FALSE</constant> otherwise.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86MatchDevice(const char *drivername,
+ GDevPtr **driversectlist)
+ </programlisting>
+ <blockquote><para>
+ This function takes the name of the driver and returns via
+ <parameter>driversectlist</parameter> a list of device sections that
+ match the driver name. The function return value is the number
+ of matches found. If a fatal error is encountered the return
+ value is <literal>-1</literal>.
+ </para>
+
+ <para>
+ The caller should use <function>xfree()</function> to free
+ <parameter>*driversectlist</parameter> when it is no longer needed.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags)
+ </programlisting>
+ <blockquote><para>
+ This function allocates a new <structname>ScrnInfoRec</structname> in the
+ <varname>xf86Screens[]</varname> array. This function is normally
+ called by the video driver <function>ChipProbe()</function> functions.
+ The return value is a pointer to the newly allocated
+ <structname>ScrnInfoRec</structname>. The <structfield>scrnIndex</structfield>,
+ <structfield>origIndex</structfield>, <structfield>module</structfield> and
+ <structfield>drv</structfield> fields are initialised. The reference count
+ in <parameter>drv</parameter> is incremented. The storage for any
+ currently allocated <quote>privates</quote> pointers is also allocated and
+ the <structfield>privates</structfield> field initialised (the privates data
+ is of course not allocated or initialised). This function never
+ returns on failure. If the allocation fails, the server exits
+ with a fatal error. The flags value is not currently used, and
+ should be set to zero.
+ </para></blockquote>
+ </para></blockquote>
+
+ <para>
+ At the completion of this, a list of <structname>ScrnInfoRecs</structname>
+ have been allocated in the <varname>xf86Screens[]</varname> array, and
+ the associated entities and fixed resources have been claimed. The
+ following <structname>ScrnInfoRec</structname> fields must be initialised at
+ this point:
+
+ <literallayout>
+ driverVersion
+ driverName
+ scrnIndex(*)
+ origIndex(*)
+ drv(*)
+ module(*)
+ name
+ Probe
+ PreInit
+ ScreenInit
+ EnterVT
+ LeaveVT
+ numEntities
+ entityList
+ access
+ </literallayout>
+
+ <literal>(*)</literal> These are initialised when the <structname>ScrnInfoRec</structname>
+ is allocated, and not explicitly by the driver.
+ </para>
+
+ <para>
+ The following <structname>ScrnInfoRec</structname> fields must be initialised
+ if the driver is going to use them:
+
+ <literallayout>
+ SwitchMode
+ AdjustFrame
+ FreeScreen
+ ValidMode
+ </literallayout>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Matching Screens</title>
+
+ <para>
+ This is done at the start of the first server generation only.
+ </para>
+
+ <para>
+ After the Probe phase is finished, there will be some number of
+ <structname>ScrnInfoRec</structname>s. These are then matched with the active
+ &k.screen; sections in the xorg.conf, and those not having an active
+ &k.screen; section are deleted. If the number of remaining screens
+ is 0, <function>InitOutput()</function> sets
+ <structfield>screenInfo.numScreens</structfield> to <constant>0</constant> and
+ returns.
+ </para>
+
+ <para>
+ At this point the following fields of the <structname>ScrnInfoRec</structname>s
+ must be initialised:
+
+ <literallayout>
+ confScreen
+ </literallayout>
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Allocate non-conflicting resources</title>
+
+ <para>
+ This is done at the start of the first server generation only.
+ </para>
+
+ <para>
+ Before calling the drivers again, the resource information collected
+ from the Probe phase is processed. This includes checking the extent
+ of PCI resources for the probed devices, and resolving any conflicts
+ in the relocatable PCI resources. It also reports conflicts, checks
+ bus routing issues, and anything else that is needed to enable the
+ entities for the next phase.
+ </para>
+
+ <para>
+ If any drivers registered an <function>EntityInit()</function> function
+ during the Probe phase, then they are called here.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Sort the Screens and pre-check Monitor Information</title>
+
+ <para>
+ This is done at the start of the first server generation only.
+ </para>
+
+ <para>
+ The list of screens is sorted to match the ordering requested in the
+ config file.
+ </para>
+
+ <para>
+ The list of modes for each active monitor is checked against the
+ monitor's parameters. Invalid modes are pruned.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>PreInit</title>
+
+ <para>
+ This is done at the start of the first server generation only.
+ </para>
+
+ <para>
+ For each <structname>ScrnInfoRec</structname>, enable access to the screens entities and call
+ the <function>ChipPreInit()</function> function.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool ChipPreInit(ScrnInfoRec screen, int flags);
+ </programlisting>
+ <blockquote><para>
+ The purpose of this function is to find out all the information
+ required to determine if the configuration is usable, and to
+ initialise those parts of the <structname>ScrnInfoRec</structname> that
+ can be set once at the beginning of the first server generation.
+ </para>
+
+ <para>
+ The number of entities registered for the screen should be checked
+ against the expected number (most drivers expect only one). The
+ entity information for each of them should be retrieved (with
+ <function>xf86GetEntityInfo()</function>) and checked for the correct
+ bus type and that none of the sharable resources registered during
+ the Probe phase was rejected.
+ </para>
+
+ <para>
+ Access to resources for the entities that can be controlled in a
+ device-independent way are enabled before this function is called.
+ If the driver needs to access any resources that it has disabled
+ in an <function>EntityInit()</function> function that it registered,
+ then it may enable them here providing that it disables them before
+ this function returns.
+ </para>
+
+ <para>
+ This includes probing for video memory, clocks, ramdac, and all
+ other HW info that is needed. It includes determining the
+ depth/bpp/visual and related info. It includes validating and
+ determining the set of video modes that will be used (and anything
+ that is required to determine that).
+ </para>
+
+ <para>
+ This information should be determined in the least intrusive way
+ possible. The state of the HW must remain unchanged by this
+ function. Although video memory (including MMIO) may be mapped
+ within this function, it must be unmapped before returning. Driver
+ specific information should be stored in a structure hooked into
+ the <structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield>
+ field. Any other modules which require persistent data (ie data
+ that persists across server generations) should be initialised in
+ this function, and they should allocate a <quote>privates</quote> index to
+ hook their data into by calling
+ <function>xf86AllocateScrnInfoPrivateIndex()</function>. The <quote>privates</quote>
+ data is persistent.
+ </para>
+
+ <para>
+ Helper functions for some of these things are provided at the
+ XFree86 common level, and the driver can choose to make use of
+ them.
+ </para>
+
+ <para>
+ All additional resources that the screen needs must be registered
+ here. This should be done with
+ <function>xf86RegisterResources()</function>. If some of the fixed
+ resources registered in the Probe phase are not needed or not
+ decoded by the hardware when in the OPERATING server state, their
+ status should be updated with
+ <function>xf86SetOperatingState()</function>.
+ </para>
+
+ <para>
+ Modules may be loaded at any point in this function, and all
+ modules that the driver will need must be loaded before the end
+ of this function. Either the <function>xf86LoadSubModule()</function>
+ or the <function>xf86LoadDrvSubModule()</function> function should be
+ used to load modules depending on whether a
+ <structname>ScrnInfoRec</structname> has been set up. A driver may unload
+ a module within this function if it was only needed temporarily,
+ and the <function>xf86UnloadSubModule()</function> function should be used
+ to do that. Otherwise there is no need to explicitly unload modules
+ because the loader takes care of module dependencies and will
+ unload submodules automatically if/when the driver module is
+ unloaded.
+ </para>
+
+ <para>
+ The bulk of the <structname>ScrnInfoRec</structname> fields should be filled
+ out in this function.
+ </para>
+
+ <para>
+ <function>ChipPreInit()</function> returns <constant>FALSE</constant> when
+ the configuration is unusable in some way (unsupported depth, no
+ valid modes, not enough video memory, etc), and <constant>TRUE</constant>
+ if it is usable.
+ </para>
+
+ <para>
+ It is expected that if the <function>ChipPreInit()</function> function
+ returns <constant>TRUE</constant>, then the only reasons that subsequent
+ stages in the driver might fail are lack or resources (like xalloc
+ failures). All other possible reasons for failure should be
+ determined by the <function>ChipPreInit()</function> function.
+ </para></blockquote>
+ </para></blockquote>
+
+ <para>
+ The <structname>ScrnInfoRec</structname>s for screens where the <function>ChipPreInit()</function> fails are removed.
+ If none remain, <function>InitOutput()</function> sets <structfield>screenInfo.numScreens</structfield> to <constant>0</constant> and returns.
+ </para>
+
+ <para>
+ At this point, further fields of the <structname>ScrnInfoRec</structname>s would normally be
+ filled in. Most are not strictly mandatory, but many are required
+ by other layers and/or helper functions that the driver may choose
+ to use. The documentation for those layers and helper functions
+ indicates which they require.
+ </para>
+
+ <para>
+ The following fields of the <structname>ScrnInfoRec</structname>s should be filled in if the
+ driver is going to use them:
+
+ <literallayout>
+ monitor
+ display
+ depth
+ pixmapBPP
+ bitsPerPixel
+ weight (>8bpp only)
+ mask (>8bpp only)
+ offset (>8bpp only)
+ rgbBits (8bpp only)
+ gamma
+ defaultVisual
+ maxHValue
+ maxVValue
+ virtualX
+ virtualY
+ displayWidth
+ frameX0
+ frameY0
+ frameX1
+ frameY1
+ zoomLocked
+ modePool
+ modes
+ currentMode
+ progClock (TRUE if clock is programmable)
+ chipset
+ ramdac
+ clockchip
+ numClocks (if not programmable)
+ clock[] (if not programmable)
+ videoRam
+ biosBase
+ memBase
+ memClk
+ driverPrivate
+ chipID
+ chipRev
+ </literallayout>
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name);
+ and
+ pointer xf86LoadDrvSubModule(DriverPtr drv, const char *name);
+ </programlisting>
+ <blockquote><para>
+ Load a module that a driver depends on. This function loads the
+ module <parameter>name</parameter> as a sub module of the driver. The
+ return value is a handle identifying the new module. If the load
+ fails, the return value will be <constant>NULL</constant>. If a driver
+ needs to explicitly unload a module it has loaded in this way,
+ the return value must be saved and passed to
+ <function>xf86UnloadSubModule()</function> when unloading.
+
+ </para></blockquote>
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86UnloadSubModule(pointer module);
+ </programlisting>
+ <blockquote><para>
+ Unloads the module referenced by <parameter>module</parameter>.
+ <parameter>module</parameter> should be a pointer returned previously
+ by <function>xf86LoadSubModule()</function> or
+ <function>xf86LoadDrvSubModule()</function> .
+
+ </para></blockquote>
+ </para></blockquote>
+ </sect2>
+
+ <sect2>
+ <title>Cleaning up Unused Drivers</title>
+
+ <para>
+ At this point it is known which screens will be in use, and which
+ drivers are being used. Unreferenced drivers (and modules they
+ may have loaded) are unloaded here.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Consistency Checks</title>
+
+ <para>
+ The parameters that must be global to the server, like pixmap formats,
+ bitmap bit order, bitmap scanline unit and image byte order are
+ compared for each of the screens. If a mismatch is found, the server
+ exits with an appropriate message.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Check if Resource Control is Needed</title>
+
+ <para>
+ Determine if resource access control is needed. This is the case
+ if more than one screen is used. If necessary the RAC wrapper module
+ is loaded.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>AddScreen (ScreenInit)</title>
+
+ <para>
+ At this point, the valid screens are known.
+ <function>AddScreen()</function> is called for each of them, passing
+ <function>ChipScreenInit()</function> as the argument.
+ <function>AddScreen()</function> is a DIX function that allocates a new
+ <structfield>screenInfo.screen[]</structfield> entry (aka
+ <varname>pScreen</varname>), and does some basic initialisation of it.
+ It then calls the <function>ChipScreenInit()</function> function, with
+ <parameter>pScreen</parameter> as one of its arguments. If
+ <function>ChipScreenInit()</function> returns <constant>FALSE</constant>,
+ <function>AddScreen()</function> returns <constant>-1</constant>. Otherwise
+ it returns the index of the screen. <function>AddScreen()</function>
+ should only fail because of programming errors or failure to allocate
+ resources (like memory). All configuration problems should be
+ detected BEFORE this point.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool ChipScreenInit(int index, ScreenPtr pScreen,
+ int argc, char **argv);
+ </programlisting>
+ <blockquote><para>
+ This is called at the start of each server generation.
+ </para>
+
+ <para>
+ Fill in all of <parameter>pScreen</parameter>, possibly doing some of
+ this by calling ScreenInit functions from other layers like mi,
+ framebuffers (cfb, etc), and extensions.
+ </para>
+
+ <para>
+ Decide which operations need to be placed under resource access
+ control. The classes of operations are the frame buffer operations
+ (<constant>RAC_FB</constant>), the pointer operations
+ (<constant>RAC_CURSOR</constant>), the viewport change operations
+ (<constant>RAC_VIEWPORT</constant>) and the colormap operations
+ (<constant>RAC_COLORMAP</constant>). Any operation that requires
+ resources which might be disabled during OPERATING state should
+ be set to use RAC. This can be specified separately for memory
+ and IO resources (the <structfield>racMemFlags</structfield> and
+ <structfield>racIoFlags</structfield> fields of the <structname>ScrnInfoRec</structname>
+ respectively).
+ </para>
+
+ <para>
+ Map any video memory or other memory regions.
+ </para>
+
+ <para>
+ Save the video card state. Enough state must be saved so that
+ the original state can later be restored.
+ </para>
+
+ <para>
+ Initialise the initial video mode. The <structname>ScrnInfoRec</structname>'s
+ <structfield>vtSema</structfield> field should be set to <constant>TRUE</constant>
+ just prior to changing the video hardware's state.
+
+ </para></blockquote>
+ </para></blockquote>
+
+
+ <para>
+ The <function>ChipScreenInit()</function> function (or functions from other
+ layers that it calls) should allocate entries in the
+ <structname>ScreenRec</structname>'s <structfield>devPrivates</structfield> area by
+ calling <function>AllocateScreenPrivateIndex()</function> if it needs
+ per-generation storage. Since the <structname>ScreenRec</structname>'s
+ <structfield>devPrivates</structfield> information is cleared for each server
+ generation, this is the correct place to initialise it.
+ </para>
+
+ <para>
+ After <function>AddScreen()</function> has successfully returned, the
+ following <structname>ScrnInfoRec</structname> fields are initialised:
+
+ <literallayout>
+ pScreen
+ racMemFlags
+ racIoFlags
+ </literallayout>
+ </para>
+
+ <para>
+ The <function>ChipScreenInit()</function> function should initialise the
+ <structfield>CloseScreen</structfield> and <structfield>SaveScreen</structfield> fields
+ of <parameter>pScreen</parameter>. The old value of
+ <structfield>pScreen->CloseScreen</structfield> should be saved as part of
+ the driver's per-screen private data, allowing it to be called from
+ <function>ChipCloseScreen()</function>. This means that the existing
+ <function>CloseScreen()</function> function is wrapped.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Finalising RAC Initialisation</title>
+
+ <para>
+ After all the <function>ChipScreenInit()</function> functions have been
+ called, each screen has registered its RAC requirements. This
+ information is used to determine which shared resources are requested
+ by more than one driver and set the access functions accordingly.
+ This is done following these rules:
+
+ <orderedlist>
+ <listitem><para>
+ The sharable resources registered by each entity are compared.
+ If a resource is registered by more than one entity the entity
+ will be marked to indicate that it needs to share this resources
+ type (IO or MEM).
+ </para></listitem>
+
+ <listitem><para>
+ A resource marked <quote>disabled</quote> during OPERATING state will be
+ ignored entirely.
+ </para></listitem>
+
+ <listitem><para>
+ A resource marked <quote>unused</quote> will only conflict with an overlapping
+ resource of an other entity if the second is actually in use
+ during OPERATING state.
+ </para></listitem>
+
+ <listitem><para>
+ If an <quote>unused</quote> resource was found to conflict but the entity
+ does not use any other resource of this type the entire resource
+ type will be disabled for that entity.
+ </para></listitem>
+ </orderedlist>
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Finishing InitOutput()</title>
+
+ <para>
+ At this point <function>InitOutput()</function> is finished, and all the
+ screens have been setup in their initial video mode.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Mode Switching</title>
+
+ <para>
+ When a SwitchMode event is received, <function>ChipSwitchMode()</function>
+ is called (when it exists):
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool ChipSwitchMode(int index, DisplayModePtr mode, int flags);
+ </programlisting>
+ <blockquote><para>
+ Initialises the new mode for the screen identified by
+ <parameter>index;</parameter>. The viewport may need to be adjusted
+ also.
+
+ </para></blockquote>
+ </para></blockquote>
+
+ </sect2>
+
+ <sect2>
+ <title>Changing Viewport</title>
+
+ <para>
+ When a Change Viewport event is received,
+ <function>ChipAdjustFrame()</function> is called (when it exists):
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ void ChipAdjustFrame(int index, int x, int y, int flags);
+ </programlisting>
+ <blockquote><para>
+ Changes the viewport for the screen identified by
+ <parameter>index;</parameter>.
+ </para>
+
+ <para>
+ It should be noted that many chipsets impose restrictions on where the
+ viewport may be placed in the virtual resolution, either for alignment
+ reasons, or to prevent the start of the viewport from being positioned
+ within a pixel (as can happen in a 24bpp mode). After calculating the
+ value the chipset's panning registers need to be set to for non-DGA
+ modes, this function should recalculate the ScrnInfoRec's
+ <structfield>frameX0</structfield>, <structfield>frameY0</structfield>, <structfield>frameX1</structfield>
+ and <structfield>frameY1</structfield> fields to correspond to that value. If
+ this is not done, switching to another mode might cause the position
+ of a hardware cursor to change.
+
+ </para></blockquote>
+ </para></blockquote>
+
+ </sect2>
+
+ <sect2>
+ <title>VT Switching</title>
+
+ <para>
+ When a VT switch event is received, <function>xf86VTSwitch()</function>
+ is called. <function>xf86VTSwitch()</function> does the following:
+
+ <variablelist>
+ <varlistentry><term>On ENTER:</term>
+ <listitem>
+ <itemizedlist>
+ <listitem><para>
+ enable port I/O access
+ </para></listitem>
+
+ <listitem><para>
+ save and initialise the bus/resource state
+ </para></listitem>
+
+ <listitem><para>
+ enter the SETUP server state
+ </para></listitem>
+
+ <listitem><para>
+ calls <function>ChipEnterVT()</function> for each screen
+ </para></listitem>
+
+ <listitem><para>
+ enter the OPERATING server state
+ </para></listitem>
+
+ <listitem><para>
+ validate GCs
+ </para></listitem>
+
+ <listitem><para>
+ Restore fb from saved pixmap for each screen
+ </para></listitem>
+
+ <listitem><para>
+ Enable all input devices
+ </para></listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>On LEAVE:</term>
+ <listitem>
+ <itemizedlist>
+ <listitem><para>
+ Save fb to pixmap for each screen
+ </para></listitem>
+
+ <listitem><para>
+ validate GCs
+ </para></listitem>
+
+ <listitem><para>
+ enter the SETUP server state
+ </para></listitem>
+
+ <listitem><para>
+ calls <function>ChipLeaveVT()</function> for each screen
+ </para></listitem>
+
+ <listitem><para>
+ disable all input devices
+ </para></listitem>
+
+ <listitem><para>
+ restore bus/resource state
+ </para></listitem>
+
+ <listitem><para>
+ disables port I/O access
+ </para></listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool ChipEnterVT(int index, int flags);
+ </programlisting>
+ <blockquote><para>
+ This function should initialise the current video mode and
+ initialise the viewport, turn on the HW cursor if appropriate,
+ etc.
+ </para>
+
+ <para>
+ Should it re-save the video state before initialising the video
+ mode?
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void ChipLeaveVT(int index, int flags);
+ </programlisting>
+ <blockquote><para>
+ This function should restore the saved video state. If
+ appropriate it should also turn off the HW cursor, and invalidate
+ any pixmap/font caches.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <para>
+ Optionally, <function>ChipLeaveVT()</function> may also unmap memory
+ regions. If so, <function>ChipEnterVT()</function> will need to remap
+ them. Additionally, if an aperture used to access video memory is
+ unmapped and remapped in this fashion, <function>ChipEnterVT()</function>
+ will also need to notify the framebuffer layers of the aperture's new
+ location in virtual memory. This is done with a call to the screen's
+ <function>ModifyPixmapHeader()</function> function, as follows
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ (*pScreen->ModifyPixmapHeader)(pScrn->ppix,
+ -1, -1, -1, -1, -1, NewApertureAddress);
+ </programlisting>
+ <blockquote><para>
+ where the <structfield>ppix</structfield> field in a ScrnInfoRec
+ points to the pixmap used by the screen's
+ <function>SaveRestoreImage()</function> function to hold the screen's
+ contents while switched out.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <para>
+ Currently, aperture remapping, as described here, should not be
+ attempted if the driver uses the <literal remap="tt">xf8_16bpp</literal> or
+ <literal remap="tt">xf8_32bpp</literal> framebuffer layers. A pending
+ restructuring of VT switching will address this restriction in
+ the near future.
+ </para>
+
+ <para>
+ Other layers may wrap the <function>ChipEnterVT()</function> and
+ <function>ChipLeaveVT()</function> functions if they need to take some
+ action when these events are received.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>End of server generation</title>
+
+ <para>
+ At the end of each server generation, the DIX layer calls
+ <function>ChipCloseScreen()</function> for each screen:
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool ChipCloseScreen(int index, ScreenPtr pScreen);
+ </programlisting>
+ <blockquote><para>
+ This function should restore the saved video state and unmap the
+ memory regions.
+ </para>
+
+ <para>
+ It should also free per-screen data structures allocated by the
+ driver. Note that the persistent data held in the
+ <structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield> field
+ should not be freed here because it is needed by subsequent server
+ generations.
+ </para>
+
+ <para>
+ The <structname>ScrnInfoRec</structname>'s <structfield>vtSema</structfield> field
+ should be set to <constant>FALSE</constant> once the video HW state
+ has been restored.
+ </para>
+
+ <para>
+ Before freeing the per-screen driver data the saved
+ <structfield>CloseScreen</structfield> value should be restored to
+ <structfield>pScreen->CloseScreen</structfield>, and that function should
+ be called after freeing the data.
+
+ </para></blockquote>
+ </para></blockquote>
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>Optional Driver Functions</title>
+
+ <para>
+The functions outlined here can be called from the XFree86 common layer,
+but their presence is optional.
+ </para>
+
+ <sect2>
+ <title>Mode Validation</title>
+
+ <para>
+ When a mode validation helper supplied by the XFree86-common layer is
+ being used, it can be useful to provide a function to check for hw
+ specific mode constraints:
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ ModeStatus ChipValidMode(int index, DisplayModePtr mode,
+ Bool verbose, int flags);
+ </programlisting>
+ <blockquote><para>
+ Check the passed mode for hw-specific constraints, and return the
+ appropriate status value.
+
+ </para></blockquote>
+ </para></blockquote>
+
+ <para>
+This function may also modify the effective timings and clock of the passed
+mode. These have been stored in the mode's <structfield>Crtc*</structfield> and
+<structfield>SynthClock</structfield> elements, and have already been adjusted for
+interlacing, doublescanning, multiscanning and clock multipliers and dividers.
+The function should not modify any other mode field, unless it wants to modify
+the mode timings reported to the user by <function>xf86PrintModes()</function>.
+ </para>
+
+ <para>
+The function is called once for every mode in the xorg.conf Monitor section
+assigned to the screen, with <parameter>flags</parameter> set to
+<constant>MODECHECK_INITIAL</constant>. It is subsequently called for every mode
+in the xorg.conf Display subsection assigned to the screen, with
+<parameter>flags</parameter> set to <constant>MODECHECK_FINAL</constant>. In the second
+case, the mode will have successfully passed all other tests. In addition,
+the <structname>ScrnInfoRec</structname>'s <structfield>virtualX</structfield>,
+<structfield>virtualY</structfield> and <structfield>displayWidth</structfield> fields will have been
+set as if the mode to be validated were to be the last mode accepted.
+ </para>
+
+ <para>
+In effect, calls with MODECHECK_INITIAL are intended for checks that do not
+depend on any mode other than the one being validated, while calls with
+MODECHECK_FINAL are intended for checks that may involve more than one mode.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Free screen data</title>
+
+ <para>
+ When a screen is deleted prior to the completion of the ScreenInit
+ phase the <function>ChipFreeScreen()</function> function is called when defined.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ void ChipFreeScreen(int scrnindex, int flags);
+ </programlisting>
+ <blockquote><para>
+ Free any driver-allocated data that may have been allocated up to
+ and including an unsuccessful <function>ChipScreenInit()</function>
+ call. This would predominantly be data allocated by
+ <function>ChipPreInit()</function> that persists across server
+ generations. It would include the <structfield>driverPrivate</structfield>,
+ and any <quote>privates</quote> entries that modules may have allocated.
+
+ </para></blockquote>
+ </para></blockquote>
+
+ </sect2>
+</sect1>
+
+ <sect1>
+ <title>Recommended driver functions</title>
+
+ <para>
+The functions outlined here are for internal use by the driver only.
+They are entirely optional, and are never accessed directly from higher
+layers. The sample function declarations shown here are just examples.
+The interface (if any) used is up to the driver.
+ </para>
+
+ <sect2>
+ <title>Save</title>
+
+ <para>
+ Save the video state. This could be called from <function>ChipScreenInit()</function> and
+ (possibly) <function>ChipEnterVT()</function>.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ void ChipSave(ScrnInfoPtr pScrn);
+ </programlisting>
+ <blockquote><para>
+ Saves the current state. This will only be saving pre-server
+ states or states before returning to the server. There is only
+ one current saved state per screen and it is stored in private
+ storage in the screen.
+
+ </para></blockquote>
+ </para></blockquote>
+ </sect2>
+
+ <sect2>
+ <title>Restore</title>
+
+ <para>
+ Restore the original video state. This could be called from the
+ <function>ChipLeaveVT()</function> and <function>ChipCloseScreen()</function>
+ functions.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ void ChipRestore(ScrnInfoPtr pScrn);
+ </programlisting>
+ <blockquote><para>
+ Restores the saved state from the private storage. Usually only
+ used for restoring text modes.
+
+ </para></blockquote>
+ </para></blockquote>
+
+ </sect2>
+
+ <sect2>
+ <title>Initialise Mode</title>
+
+ <para>
+ Initialise a video mode. This could be called from the
+ <function>ChipScreenInit()</function>, <function>ChipSwitchMode()</function>
+ and <function>ChipEnterVT()</function> functions.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool ChipModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+ </programlisting>
+ <blockquote><para>
+ Programs the hardware for the given video mode.
+
+ </para></blockquote>
+ </para></blockquote>
+
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>Data and Data Structures</title>
+
+ <sect2>
+ <title>Command line data</title>
+
+ <para>
+Command line options are typically global, and are stored in global
+variables. These variables are read-only and are available to drivers
+via a function call interface. Most of these command line values are
+processed via helper functions to ensure that they are treated consistently
+by all drivers. The other means of access is provided for cases where
+the supplied helper functions might not be appropriate.
+ </para>
+
+ <para>
+Some of them are:
+
+ <literallayout>
+ xf86Verbose verbosity level
+ xf86Bpp -bpp from the command line
+ xf86Depth -depth from the command line
+ xf86Weight -weight from the command line
+ xf86Gamma -{r,g,b,}gamma from the command line
+ xf86FlipPixels -flippixels from the command line
+ xf86ProbeOnly -probeonly from the command line
+ defaultColorVisualClass -cc from the command line
+ </literallayout>
+ </para>
+
+ <para>
+If we ever do allow for screen-specific command line options, we may
+need to rethink this.
+ </para>
+
+ <para>
+These can be accessed in a read-only manner by drivers with the following
+functions:
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86GetVerbosity();
+ </programlisting>
+ <blockquote><para>
+ Returns the value of <varname>xf86Verbose</varname>.
+ </para></blockquote>
+
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86GetDepth();
+ </programlisting>
+ <blockquote><para>
+ Returns the <option>-depth</option> command line setting. If not
+ set on the command line, <constant>-1</constant> is returned.
+ </para></blockquote>
+
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ rgb xf86GetWeight();
+ </programlisting>
+ <blockquote><para>
+ Returns the <option>-weight</option> command line setting. If not
+ set on the command line, <literal remap="tt">{0, 0, 0}</literal> is returned.
+ </para></blockquote>
+
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Gamma xf86GetGamma();
+ </programlisting>
+ <blockquote><para>
+ Returns the <option>-gamma</option> or <option>-rgamma</option>,
+ <option>-ggamma</option>, <option>-bgamma</option> command line settings.
+ If not set on the command line, <literal remap="tt">{0.0, 0.0, 0.0}</literal>
+ is returned.
+ </para></blockquote>
+
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86GetFlipPixels();
+ </programlisting>
+ <blockquote><para>
+ Returns <constant>TRUE</constant> if <option>-flippixels</option> is
+ present on the command line, and <constant>FALSE</constant> otherwise.
+ </para></blockquote>
+
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ const char *xf86GetServerName();
+ </programlisting>
+ <blockquote><para>
+ Returns the name of the X server from the command line.
+ </para></blockquote>
+
+ </para></blockquote>
+ </sect2>
+
+ <sect2>
+ <title>Data handling</title>
+
+ <para>
+Config file data contains parts that are global, and parts that are
+Screen specific. All of it is parsed into data structures that neither
+the drivers or most other parts of the server need to know about.
+ </para>
+
+ <para>
+The global data is typically not required by drivers, and as such, most
+of it is stored in the private <structname>xf86InfoRec</structname>.
+ </para>
+
+ <para>
+The screen-specific data collected from the config file is stored in
+screen, device, display, monitor-specific data structures that are separate
+from the <varname>ScrnInfoRecs</varname>, with the appropriate elements/fields
+hooked into the <varname>ScrnInfoRecs</varname> as required. The screen
+config data is held in <structname>confScreenRec</structname>, device data in
+the <structname>GDevRec</structname>, monitor data in the <structname>MonRec</structname>,
+and display data in the <structname>DispRec</structname>.
+ </para>
+
+ <para>
+The XFree86 common layer's screen specific data (the actual data in use
+for each screen) is held in the <varname>ScrnInfoRecs</varname>. As has
+been outlined above, the <varname>ScrnInfoRecs</varname> are allocated at probe
+time, and it is the responsibility of the Drivers' <function>Probe()</function>
+and <function>PreInit()</function> functions to finish filling them in based
+on both data provided on the command line and data provided from the
+Config file. The precedence for this is:
+
+ <blockquote><para>
+ command line -> config file -> probed/default data
+ </para></blockquote>
+ </para>
+
+ <para>
+For most things in this category there are helper functions that the
+drivers can use to ensure that the above precedence is consistently
+used.
+ </para>
+
+ <para>
+As well as containing screen-specific data that the XFree86 common layer
+(including essential parts of the server infrastructure as well as helper
+functions) needs to access, it also contains some data that drivers use
+internally. When considering whether to add a new field to the
+<structname>ScrnInfoRec</structname>, consider the balance between the convenience
+of things that lots of drivers need and the size/obscurity of the
+<structname>ScrnInfoRec</structname>.
+ </para>
+
+ <para>
+Per-screen driver specific data that cannot be accommodated with the
+static <structname>ScrnInfoRec</structname> fields is held in a driver-defined
+data structure, a pointer to which is assigned to the
+<structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield> field. This
+is per-screen data that persists across server generations (as does the
+bulk of the static <structname>ScrnInfoRec</structname> data). It would typically
+also include the video card's saved state.
+ </para>
+
+ <para>
+Per-screen data for other modules that the driver uses (for example,
+the XAA module) that is reset for each server generation is hooked into
+the <structname>ScrnInfoRec</structname> through it's <structfield>privates</structfield>
+field.
+ </para>
+
+ <para>
+Once it has stabilised, the data structures and variables accessible to
+video drivers will be documented here. In the meantime, those things
+defined in the <filename>xf86.h</filename> and <filename>xf86str.h</filename>
+files are visible to video drivers. Things defined in
+<filename>xf86Priv.h</filename> and <filename>xf86Privstr.h</filename> are NOT
+intended to be visible to video drivers, and it is an error for a driver
+to include those files.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Accessing global data</title>
+
+ <para>
+Some other global state information that the drivers may access via
+functions is as follows:
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86ServerIsExiting();
+ </programlisting>
+ <blockquote><para>
+ Returns <constant>TRUE</constant> if the server is at the end of a
+ generation and is in the process of exiting, and
+ <constant>FALSE</constant> otherwise.
+ </para></blockquote>
+
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86ServerIsResetting();
+ </programlisting>
+ <blockquote><para>
+ Returns <constant>TRUE</constant> if the server is at the end of a
+ generation and is in the process of resetting, and
+ <constant>FALSE</constant> otherwise.
+ </para></blockquote>
+
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86ServerIsInitialising();
+ </programlisting>
+ <blockquote><para>
+ Returns <constant>TRUE</constant> if the server is at the beginning of
+ a generation and is in the process of initialising, and
+ <constant>FALSE</constant> otherwise.
+ </para></blockquote>
+
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86ServerIsOnlyProbing();
+ </programlisting>
+ <blockquote><para>
+ Returns <constant>TRUE</constant> if the -probeonly command line flag
+ was specified, and <constant>FALSE</constant> otherwise.
+ </para></blockquote>
+
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86CaughtSignal();
+ </programlisting>
+ <blockquote><para>
+ Returns <constant>TRUE</constant> if the server has caught a signal,
+ and <constant>FALSE</constant> otherwise.
+ </para></blockquote>
+
+ </para></blockquote>
+ </sect2>
+
+ <sect2>
+ <title>Allocating private data</title>
+
+ <para>
+A driver and any module it uses may allocate per-screen private storage
+in either the <structname>ScreenRec</structname> (DIX level) or
+<structname>ScrnInfoRec</structname> (XFree86 common layer level).
+<structname>ScreenRec</structname> storage persists only for a single server
+generation, and <structname>ScrnInfoRec</structname> storage persists across
+generations for the lifetime of the server.
+ </para>
+
+ <para>
+The <structname>ScreenRec</structname> <structfield>devPrivates</structfield> data must be
+reallocated/initialised at the start of each new generation. This is
+normally done from the <function>ChipScreenInit()</function> function, and
+Init functions for other modules that it calls. Data allocated in this
+way should be freed by the driver's <function>ChipCloseScreen()</function>
+functions, and Close functions for other modules that it calls. A new
+<structfield>devPrivates</structfield> entry is allocated by calling the
+<function>AllocateScreenPrivateIndex()</function> function.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ int AllocateScreenPrivateIndex();
+ </programlisting>
+ <blockquote><para>
+ This function allocates a new element in the
+ <structfield>devPrivates</structfield> field of all currently existing
+ <literal remap="tt">ScreenRecs</literal>. The return value is the index of this
+ new element in the <structfield>devPrivates</structfield> array. The
+ <structfield>devPrivates</structfield> field is of type
+ <structname>DevUnion</structname>:
+
+ <programlisting>
+ typedef union _DevUnion {
+ pointer ptr;
+ long val;
+ unsigned long uval;
+ pointer (*fptr)(void);
+ } DevUnion;
+ </programlisting>
+
+ which allows the element to be used for any of the above types.
+ It is commonly used as a pointer to data that the caller allocates
+ after the new index has been allocated.
+ </para>
+
+ <para>
+ This function will return <constant>-1</constant> when there is an
+ error allocating the new index.
+ </para>
+
+ </blockquote>
+ </para></blockquote>
+
+ <para>
+The <structname>ScrnInfoRec</structname> <structfield>privates</structfield> data persists
+for the life of the server, so only needs to be allocated once. This
+should be done from the <function>ChipPreInit()</function> function, and Init
+functions for other modules that it calls. Data allocated in this way
+should be freed by the driver's <function>ChipFreeScreen()</function> functions,
+and Free functions for other modules that it calls. A new
+<structfield>privates</structfield> entry is allocated by calling the
+<function>xf86AllocateScrnInfoPrivateIndex()</function> function.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86AllocateScrnInfoPrivateIndex();
+ </programlisting>
+ <blockquote><para>
+ This function allocates a new element in the <structfield>privates</structfield>
+ field of all currently existing <varname>ScrnInfoRecs</varname>.
+ The return value is the index of this new element in the
+ <structfield>privates</structfield> array. The <structfield>privates</structfield>
+ field is of type <structfield>DevUnion</structfield>:
+
+ <programlisting>
+ typedef union _DevUnion {
+ pointer ptr;
+ long val;
+ unsigned long uval;
+ pointer (*fptr)(void);
+ } DevUnion;
+ </programlisting>
+
+ which allows the element to be used for any of the above types.
+ It is commonly used as a pointer to data that the caller allocates
+ after the new index has been allocated.
+ </para>
+
+ <para>
+ This function will not return when there is an error allocating
+ the new index. When there is an error it will cause the server
+ to exit with a fatal error. The similar function for allocation
+ privates in the <structname>ScreenRec</structname>
+ (<function>AllocateScreenPrivateIndex()</function>) differs in this
+ respect by returning <constant>-1</constant> when the allocation fails.
+ </para>
+
+ </blockquote>
+ </para></blockquote>
+ </sect2>
+ </sect1>
+
+ <sect1 id="rac">
+ <title>Keeping Track of Bus Resources</title>
+
+ <sect2>
+ <title>Theory of Operation</title>
+
+ <para>
+The XFree86 common layer has knowledge of generic access control mechanisms
+for devices on certain bus systems (currently the PCI bus) as well as
+of methods to enable or disable access to the buses itself. Furthermore
+it can access information on resources decoded by these devices and if
+necessary modify it.
+ </para>
+
+ <para>
+When first starting the Xserver collects all this information, saves it
+for restoration, checks it for consistency, and if necessary, corrects
+it. Finally it disables all resources on a generic level prior to
+calling any driver function.
+ </para>
+
+ <para>
+When the <function>Probe()</function> function of each driver is called the
+device sections are matched against the devices found in the system.
+The driver may probe devices at this stage that cannot be identified by
+using device independent methods. Access to all resources that can be
+controlled in a device independent way is disabled. The
+<function>Probe()</function> function should register all non-relocatable
+resources at this stage. If a resource conflict is found between
+exclusive resources the driver will fail immediately. Optionally the
+driver might specify an <function>EntityInit()</function>,
+<function>EntityLeave()</function> and <function>EntityEnter()</function> function.
+ </para>
+
+ <para>
+<function>EntityInit()</function> can be used to disable any shared resources
+that are not controlled by the generic access control functions. It is
+called prior to the PreInit phase regardless if an entity is active or
+not. When calling the <function>EntityInit()</function>,
+<function>EntityEnter()</function> and <function>EntityLeave()</function> functions
+the common level will disable access to all other entities on a generic
+level. Since the common level has no knowledge of device specific
+methods to disable access to resources it cannot be guaranteed that
+certain resources are not decoded by any other entity until the
+<function>EntityInit()</function> or <function>EntityEnter()</function> phase is
+finished. Device drivers should therefore register all those resources
+which they are going to disable. If these resources are never to be
+used by any driver function they may be flagged <constant>ResInit</constant>
+so that they can be removed from the resource list after processing all
+<function>EntityInit()</function> functions. <function>EntityEnter()</function>
+should disable decoding of all resources which are not registered as
+exclusive and which are not handled by the generic access control in
+the common level. The difference to <function>EntityInit()</function> is
+that the latter one is only called once during lifetime of the server.
+It can therefore be used to set up variables prior to disabling resources.
+<function>EntityLeave()</function> should restore the original state when
+exiting the server or switching to a different VT. It also needs to
+disable device specific access functions if they need to be disabled on
+server exit or VT switch. The default state is to enable them before
+giving up the VT.
+ </para>
+
+ <para>
+In <function>PreInit()</function> phase each driver should check if any
+sharable resources it has registered during <function>Probe()</function> has
+been denied and take appropriate action which could simply be to fail.
+If it needs to access resources it has disabled during
+<function>EntitySetup()</function> it can do so provided it has registered
+these and will disable them before returning from
+<function>PreInit()</function>. This also applies to all other driver
+functions. Several functions are provided to request resource ranges,
+register these, correct PCI config space and add replacements for the
+generic access functions. Resources may be marked <quote>disabled</quote> or
+<quote>unused</quote> during OPERATING stage. Although these steps could also be
+performed in <function>ScreenInit()</function>, this is not desirable.
+ </para>
+
+ <para>
+Following <function>PreInit()</function> phase the common level determines
+if resource access control is needed. This is the case if more than
+one screen is used. If necessary the RAC wrapper module is loaded. In
+<function>ScreenInit()</function> the drivers can decide which operations
+need to be placed under RAC. Available are the frame buffer operations,
+the pointer operations and the colormap operations. Any operation that
+requires resources which might be disabled during OPERATING state should
+be set to use RAC. This can be specified separately for memory and IO
+resources.
+ </para>
+
+ <para>
+When <function>ScreenInit()</function> phase is done the common level will
+determine which shared resources are requested by more than one driver
+and set the access functions accordingly. This is done following these
+rules:
+
+ <orderedlist>
+ <listitem><para>
+ The sharable resources registered by each entity are compared. If
+ a resource is registered by more than one entity the entity will be
+ marked to need to share this resources type (<constant>IO</constant> or
+ <constant>MEM</constant>).
+ </para></listitem>
+
+ <listitem><para>
+ A resource marked <quote>disabled</quote> during OPERATING state will be ignored
+ entirely.
+ </para></listitem>
+
+ <listitem><para>
+ A resource marked <quote>unused</quote> will only conflicts with an overlapping
+ resource of an other entity if the second is actually in use during
+ OPERATING state.
+ </para></listitem>
+
+ <listitem><para>
+ If an <quote>unused</quote> resource was found to conflict however the entity
+ does not use any other resource of this type the entire resource type
+ will be disabled for that entity.
+ </para></listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+The driver has the choice among different ways to control access to
+certain resources:
+
+ <orderedlist>
+ <listitem><para>
+ It can rely on the generic access functions. This is probably the
+ most common case. Here the driver only needs to register any resource
+ it is going to use.
+ </para></listitem>
+
+ <listitem><para>
+ It can replace the generic access functions by driver specific
+ ones. This will mostly be used in cases where no generic access
+ functions are available. In this case the driver has to make sure
+ these resources are disabled when entering the <function>PreInit()</function>
+ stage. Since the replacement functions are registered in
+ <function>PreInit()</function> the driver will have to enable these
+ resources itself if it needs to access them during this state. The
+ driver can specify if the replacement functions can control memory
+ and/or I/O resources separately.
+ </para></listitem>
+
+ <listitem><para>
+ The driver can enable resources itself when it needs them. Each
+ driver function enabling them needs to disable them before it will
+ return. This should be used if a resource which can be controlled
+ in a device dependent way is only required during SETUP state. This
+ way it can be marked <quote>unused</quote> during OPERATING state.
+ </para></listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+A resource which is decoded during OPERATING state however never accessed
+by the driver should be marked unused.
+ </para>
+
+ <para>
+Since access switching latencies are an issue during Xserver operation,
+the common level attempts to minimize the number of entities that need
+to be placed under RAC control. When a wrapped operation is called,
+the <function>EnableAccess()</function> function is called before control is
+passed on. <function>EnableAccess()</function> checks if a screen is under
+access control. If not it just establishes bus routing and returns.
+If the screen needs to be under access control,
+<function>EnableAccess()</function> determines which resource types
+(<literal remap="tt">MEM</literal>, <literal remap="tt">IO</literal>) are required. Then it tests
+if this access is already established. If so it simply returns. If
+not it disables the currently established access, fixes bus routing and
+enables access to all entities registered for this screen.
+ </para>
+
+ <para>
+Whenever a mode switch or a VT-switch is performed the common level will
+return to SETUP state.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Resource Types</title>
+
+ <para>
+Resource have certain properties. When registering resources each range
+is accompanied by a flag consisting of the ORed flags of the different
+properties the resource has. Each resource range may be classified
+according to
+
+ <itemizedlist>
+ <listitem><para>
+ its physical properties i.e., if it addresses
+ memory (<constant>ResMem</constant>) or
+ I/O space (<constant>ResIo</constant>),
+ </para></listitem>
+ <listitem><para>
+ if it addresses a
+ block (<constant>ResBlock</constant>) or
+ sparse (<constant>ResSparse</constant>)
+ range,
+ </para></listitem>
+ <listitem><para>
+ its access properties.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+There are two known access properties:
+
+ <itemizedlist>
+ <listitem><para>
+ <constant>ResExclusive</constant>
+ for resources which may not be shared with any other device and
+ </para></listitem>
+ <listitem><para>
+ <constant>ResShared</constant>
+ for resources which can be disabled and therefore can be shared.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+If it is necessary to test a resource against any type a generic access
+type <constant>ResAny</constant> is provided. If this is set the resource
+will conflict with any resource of a different entity intersecting its
+range. Further it can be specified that a resource is decoded however
+never used during any stage (<constant>ResUnused</constant>) or during
+OPERATING state (<constant>ResUnusedOpr</constant>). A resource only visible
+during the init functions (ie. <function>EntityInit()</function>,
+<function>EntityEnter()</function> and <function>EntityLeave()</function> should
+be registered with the flag <constant>ResInit</constant>. A resource that
+might conflict with background resource ranges may be flagged with
+<constant>ResBios</constant>. This might be useful when registering resources
+ranges that were assigned by the system Bios.
+ </para>
+
+ <para>
+Several predefined resource lists are available for VGA and 8514/A
+resources in <filename>common/xf86Resources.h</filename>.
+ </para>
+ </sect2>
+
+ <sect2 id="avail">
+ <title>Available Functions</title>
+
+ <para>
+The functions provided for resource management are listed in their order
+of use in the driver.
+ </para>
+
+ <sect3>
+ <title>Probe Phase</title>
+
+ <para>
+In this phase each driver detects those resources it is able to drive,
+creates an entity record for each of them, registers non-relocatable
+resources and allocates screens and adds the resources to screens.
+ </para>
+
+ <para>
+Two helper functions are provided for matching device sections in the
+xorg.conf file to the devices:
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86MatchPciInstances(const char *driverName, int vendorID,
+ SymTabPtr chipsets, PciChipsets *PCIchipsets,
+ GDevPtr *devList, int numDevs, DriverPtr drvp,
+ int **foundEntities);
+ </programlisting>
+ <blockquote><para>
+ This function finds matches between PCI cards that a driver supports
+ and config file device sections. It is intended for use in the
+ <function>ChipProbe()</function> function of drivers for PCI cards.
+ Only probed PCI devices with a vendor ID matching
+ <parameter>vendorID</parameter> are considered. <parameter>devList</parameter>
+ and <parameter>numDevs</parameter> are typically those found from
+ calling <function>xf86MatchDevice()</function>, and represent the active
+ config file device sections relevant to the driver.
+ <parameter>PCIchipsets</parameter> is a table that provides a mapping
+ between the PCI device IDs, the driver's internal chipset tokens
+ and a list of fixed resources.
+ </para>
+
+ <para>
+ When a device section doesn't have a <emphasis>BusID</emphasis> entry it
+ can only match the primary video device. Secondary devices are
+ only matched with device sections that have a matching
+ <emphasis>BusID</emphasis> entry.
+ </para>
+
+ <para>
+ Once the preliminary matches have been found, a final match is
+ confirmed by checking if the chipset override, ChipID override or
+ probed PCI chipset type match one of those given in the
+ <parameter>chipsets</parameter> and <parameter>PCIchipsets</parameter> lists.
+ The <parameter>PCIchipsets</parameter> list includes a list of the PCI
+ device IDs supported by the driver. The list should be terminated
+ with an entry with PCI ID <constant>-1</constant>". The
+ <parameter>chipsets</parameter> list is a table mapping the driver's
+ internal chipset tokens to names, and should be terminated with
+ a <constant>NULL</constant> entry. Only those entries with a
+ corresponding entry in the <parameter>PCIchipsets</parameter> list are
+ considered. The order of precedence is: config file chipset,
+ config file ChipID, probed PCI device ID.
+ </para>
+
+ <para>
+ In cases where a driver handles PCI chipsets with more than one
+ vendor ID, it may set <parameter>vendorID</parameter> to
+ <constant>0</constant>, and OR each devID in the list with (the
+ vendor ID << 16).
+ </para>
+
+ <para>
+ Entity index numbers for confirmed matches are returned as an
+ array via <parameter>foundEntities</parameter>. The PCI information,
+ chipset token and device section for each match are found in the
+ <structname>EntityInfoRec</structname> referenced by the indices.
+ </para>
+
+ <para>
+ The function return value is the number of confirmed matches. A
+ return value of <constant>-1</constant> indicates an internal error.
+ The returned <parameter>foundEntities</parameter> array should be freed
+ by the driver with <function>xfree()</function> when it is no longer
+ needed in cases where the return value is greater than zero.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86MatchIsaInstances(const char *driverName,
+ SymTabPtr chipsets, IsaChipsets *ISAchipsets,
+ DriverPtr drvp, FindIsaDevProc FindIsaDevice,
+ GDevPtr *devList, int numDevs,
+ int **foundEntities);
+ </programlisting>
+ <blockquote><para>
+ This function finds matches between ISA cards that a driver supports
+ and config file device sections. It is intended for use in the
+ <function>ChipProbe()</function> function of drivers for ISA cards.
+ <parameter>devList</parameter> and <parameter>numDevs</parameter> are
+ typically those found from calling <function>xf86MatchDevice()</function>,
+ and represent the active config file device sections relevant to
+ the driver. <parameter>ISAchipsets</parameter> is a table that provides
+ a mapping between the driver's internal chipset tokens and the
+ resource classes. <parameter>FindIsaDevice</parameter> is a
+ driver-provided function that probes the hardware and returns the
+ chipset token corresponding to what was detected, and
+ <constant>-1</constant> if nothing was detected.
+ </para>
+
+ <para>
+ If the config file device section contains a chipset entry, then
+ it is checked against the <parameter>chipsets</parameter> list. When
+ no chipset entry is present, the <parameter>FindIsaDevice</parameter>
+ function is called instead.
+ </para>
+
+ <para>
+ Entity index numbers for confirmed matches are returned as an
+ array via <parameter>foundEntities</parameter>. The chipset token and
+ device section for each match are found in the
+ <structname>EntityInfoRec</structname> referenced by the indices.
+ </para>
+
+ <para>
+ The function return value is the number of confirmed matches. A
+ return value of <constant>-1</constant> indicates an internal error.
+ The returned <parameter>foundEntities</parameter> array should be freed
+ by the driver with <function>xfree()</function> when it is no longer
+ needed in cases where the return value is greater than zero.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <para>
+These two helper functions make use of several core functions that are
+available at the driver level:
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86ParsePciBusString(const char *busID, int *bus,
+ int *device, int *func);
+ </programlisting>
+ <blockquote><para>
+ Takes a <parameter>BusID</parameter> string, and if it is in the correct
+ format, returns the PCI <parameter>bus</parameter>, <parameter>device</parameter>,
+ <parameter>func</parameter> values that it indicates. The format of the
+ string is expected to be "PCI:bus:device:func" where each of <quote>bus</quote>,
+ <quote>device</quote> and <quote>func</quote> are decimal integers. The ":func" part may
+ be omitted, and the func value assumed to be zero, but this isn't
+ encouraged. The "PCI" prefix may also be omitted. The prefix
+ "AGP" is currently equivalent to the "PCI" prefix. If the string
+ isn't a valid PCI BusID, the return value is <constant>FALSE</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86ComparePciBusString(const char *busID, int bus,
+ int device, int func);
+ </programlisting>
+ <blockquote><para>
+ Compares a <parameter>BusID</parameter> string with PCI <parameter>bus</parameter>,
+ <parameter>device</parameter>, <parameter>func</parameter> values. If they
+ match <constant>TRUE</constant> is returned, and <constant>FALSE</constant>
+ if they don't.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86ParseIsaBusString(const char *busID);
+ </programlisting>
+ <blockquote><para>
+ Compares a <parameter>BusID</parameter> string with the ISA bus ID string
+ ("ISA" or "ISA:"). If they match <constant>TRUE</constant> is returned,
+ and <constant>FALSE</constant> if they don't.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86CheckPciSlot(int bus, int device, int func);
+ </programlisting>
+ <blockquote><para>
+ Checks if the PCI slot <literal remap="tt">bus:device:func</literal> has been
+ claimed. If so, it returns <constant>FALSE</constant>, and otherwise
+ <constant>TRUE</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86ClaimPciSlot(int bus, int device, int func, DriverPtr drvp,
+ int chipset, GDevPtr dev, Bool active);
+ </programlisting>
+ <blockquote><para>
+ This function is used to claim a PCI slot, allocate the associated
+ entity record and initialise their data structures. The return
+ value is the index of the newly allocated entity record, or
+ <constant>-1</constant> if the claim fails. This function should always
+ succeed if <function>xf86CheckPciSlot()</function> returned
+ <constant>TRUE</constant> for the same PCI slot.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86IsPrimaryPci(void);
+ </programlisting>
+ <blockquote><para>
+ This function returns <constant>TRUE</constant> if the primary card is
+ a PCI device, and <constant>FALSE</constant> otherwise.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86ClaimIsaSlot(DriverPtr drvp, int chipset,
+ GDevPtr dev, Bool active);
+ </programlisting>
+ <blockquote><para>
+ This allocates an entity record entity and initialise the data
+ structures. The return value is the index of the newly allocated
+ entity record.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86IsPrimaryIsa(void);
+ </programlisting>
+ <blockquote><para>
+ This function returns <constant>TRUE</constant> if the primary card is
+ an ISA (non-PCI) device, and <constant>FALSE</constant> otherwise.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <para>
+Two helper functions are provided to aid configuring entities:
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn,
+ int scrnFlag, int entityIndex,
+ PciChipsets *p_chip,
+ resList res, EntityProc init,
+ EntityProc enter, EntityProc leave,
+ pointer private);
+
+ ScrnInfoPtr xf86ConfigIsaEntity(ScrnInfoPtr pScrn,
+ int scrnFlag, int entityIndex,
+ IsaChipsets *i_chip,
+ resList res, EntityProc init,
+ EntityProc enter, EntityProc leave,
+ pointer private);
+ </programlisting>
+ <blockquote><para>
+ These functions are used to register the non-relocatable resources
+ for an entity, and the optional entity-specific <parameter>Init</parameter>, <parameter>Enter</parameter> and
+ <parameter>Leave</parameter> functions. Usually the list of fixed resources is obtained
+ from the Isa/PciChipsets lists. However an additional list of
+ resources may be passed. Generally this is not required.
+ For active entities a <structname>ScrnInfoRec</structname> is allocated
+ if the <parameter>pScrn</parameter> argument is <constant>NULL</constant>.
+The
+ return value is <constant>TRUE</constant> when successful. The init, enter, leave
+ functions are defined as follows:
+
+ <blockquote><para>
+ <programlisting>
+ typedef void (*EntityProc)(int entityIndex,
+ pointer private);
+ </programlisting>
+ </para></blockquote>
+
+ They are passed the entity index and a pointer to a private scratch
+ area. This can be set up during <function>Probe()</function> and
+ its address can be passed to
+ <function>xf86ConfigIsaEntity()</function> and
+ <function>xf86ConfigPciEntity()</function> as the last argument.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <para>
+These two helper functions make use of several core functions that are
+available at the driver level:
+
+ <blockquote><para>
+ <programlisting>
+ void xf86ClaimFixedResources(resList list, int entityIndex);
+ </programlisting>
+ <blockquote><para>
+ This function registers the non-relocatable resources which cannot
+ be disabled and which therefore would cause the server to fail
+ immediately if they were found to conflict. It also records
+ non-relocatable but sharable resources for processing after the
+ <function>Probe()</function> phase.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
+ EntityProc enter, EntityProc leave, pointer);
+ </programlisting>
+ <blockquote><para>
+ This function registers with an entity the <parameter>init</parameter>,
+ <parameter>enter</parameter>, <parameter>leave</parameter> functions along
+ with the pointer to their private area.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex);
+ </programlisting>
+ <blockquote><para>
+ This function associates the entity referenced by
+ <parameter>entityIndex</parameter> with the screen.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>PreInit Phase</title>
+
+ <para>
+During this phase the remaining resources should be registered.
+<function>PreInit()</function> should call <function>xf86GetEntityInfo()</function>
+to obtain a pointer to an <structname>EntityInfoRec</structname> for each entity
+it is able to drive and check if any resource are listed in its
+<structfield>resources</structfield> field. If resources registered in the Probe
+phase have been rejected in the post-Probe phase
+(<structfield>resources</structfield> is non-<constant>NULL</constant>), then the driver should
+decide if it can continue without using these or if it should fail.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ EntityInfoPtr xf86GetEntityInfo(int entityIndex);
+ </programlisting>
+ <blockquote><para>
+ This function returns a pointer to the <structname>EntityInfoRec</structname>
+ referenced by <parameter>entityIndex</parameter>. The returned
+ <structname>EntityInfoRec</structname> should be freed with
+ <function>xfree()</function> when no longer needed.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <para>
+Several functions are provided to simplify resource registration:
+ <blockquote><para>
+ <programlisting>
+ Bool xf86IsEntityPrimary(int entityIndex);
+ </programlisting>
+ <blockquote><para>
+ This function returns <constant>TRUE</constant> if the entity referenced
+ by <parameter>entityIndex</parameter> is the primary display device (i.e.,
+ the one initialised at boot time and used in text mode).
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86IsScreenPrimary(int scrnIndex);
+ </programlisting>
+ <blockquote><para>
+ This function returns <constant>TRUE</constant> if the primary entity
+ is registered with the screen referenced by
+ <parameter>scrnIndex</parameter>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ pciVideoPtr xf86GetPciInfoForEntity(int entityIndex);
+ </programlisting>
+ <blockquote><para>
+ This function returns a pointer to the <structname>pciVideoRec</structname>
+ for the specified entity. If the entity is not a PCI device,
+ <constant>NULL</constant> is returned.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ <para>
+The primary function for registration of resources is:
+ <blockquote><para>
+ <programlisting>
+ resPtr xf86RegisterResources(int entityIndex, resList list,
+ int access);
+ </programlisting>
+ <blockquote><para>
+ This function tries to register the resources in
+ <parameter>list</parameter>. If list is <constant>NULL</constant> it tries
+ to determine the resources automatically. This only works for
+ entities that provide a generic way to read out the resource ranges
+ they decode. So far this is only the case for PCI devices. By
+ default the PCI resources are registered as shared
+ (<constant>ResShared</constant>) if the driver wants to set a different
+ access type it can do so by specifying the access flags in the
+ third argument. A value of <constant>0</constant> means to use the
+ default settings. If for any reason the resource broker is not
+ able to register some of the requested resources the function will
+ return a pointer to a list of the failed ones. In this case the
+ driver may be able to move the resource to different locations.
+ In case of PCI bus entities this is done by passing the list of
+ failed resources to <function>xf86ReallocatePciResources()</function>.
+ When the registration succeeds, the return value is
+ <constant>NULL</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ resPtr xf86ReallocatePciResources(int entityIndex, resPtr pRes);
+ </programlisting>
+ <blockquote><para>
+ This function takes a list of PCI resources that need to be
+ reallocated and returns <constant>NULL</constant> when all relocations are
+ successful.
+ <function>xf86RegisterResources()</function> should be called again to
+ register the relocated resources with the broker.
+ If the reallocation fails, a list of the resources that could not be
+ relocated is returned.
+ </para>
+
+ </blockquote></para></blockquote>
+
+<para>
+Two functions are provided to obtain a resource range of a given type:
+ <blockquote><para>
+ <programlisting>
+ resRange xf86GetBlock(long type, memType size,
+ memType window_start, memType window_end,
+ memType align_mask, resPtr avoid);
+ </programlisting>
+ <blockquote><para>
+ This function tries to find a block range of size
+ <parameter>size</parameter> and type <parameter>type</parameter> in a window
+ bound by <parameter>window_start</parameter> and <parameter>window_end</parameter>
+ with the alignment specified in <parameter>align_mask</parameter>.
+ Optionally a list of resource ranges which should be avoided within
+ the window can be supplied. On failure a zero-length range of
+ type <constant>ResEnd</constant> will be returned.
+ </para>
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ resRange xf86GetSparse(long type, memType fixed_bits,
+ memType decode_mask, memType address_mask,
+ resPtr avoid);
+ </programlisting>
+ <blockquote><para>
+ This function is like the previous one, but attempts to find a
+ sparse range instead of a block range. Here three values have to
+ be specified: the <parameter>address_mask</parameter> which marks all
+ bits of the mask part of the address, the <parameter>decode_mask</parameter>
+ which masks out the bits which are hardcoded and are therefore
+ not available for relocation and the values of the fixed bits.
+ The function tries to find a base that satisfies the given condition.
+ If the function fails it will return a zero range of type
+ <constant>ResEnd</constant>. Optionally it might be passed a list of
+ resource ranges to avoid.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ <para>
+Some PCI devices are broken in the sense that they return invalid size
+information for a certain resource. In this case the driver can supply
+the correct size and make sure that the resource range allocated for
+the card is large enough to hold the address range decoded by the card.
+The function <function>xf86FixPciResource()</function> can be used to do this:
+ <blockquote><para>
+ <programlisting>
+ Bool xf86FixPciResource(int entityIndex, unsigned int prt,
+ CARD32 alignment, long type);
+ </programlisting>
+ <blockquote><para>
+ This function fixes a PCI resource allocation. The
+ <parameter>prt</parameter> parameter contains the number of the PCI base
+ register that needs to be fixed (<constant>0-5</constant>, and
+ <constant>6</constant> for the BIOS base register). The size is
+ specified by the alignment. Since PCI resources need to span an
+ integral range of size <literal remap="tt">2ˆn</literal>, the alignm ent also
+ specifies the number of addresses that will be decoded. If the
+ driver specifies a type mask it can override the default type for
+ PCI resources which is <constant>ResShared</constant>. The resource
+ broker needs to know that to find a matching resource range. This
+ function should be called before calling
+ <function>xf86RegisterResources()</function>. The return value is
+ <constant>TRUE</constant> when the function succeeds.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86CheckPciMemBase(pciVideoPtr pPci, memType base);
+ </programlisting>
+ <blockquote><para>
+ This function checks that the memory base address specified matches
+ one of the PCI base address register values for the given PCI
+ device. This is mostly used to check that an externally provided
+ base address (e.g., from a config file) matches an actual value
+ allocated to a device.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ <para>
+The driver may replace the generic access control functions for an entity.
+This is done with the <function>xf86SetAccessFuncs()</function>:
+ <blockquote><para>
+ <programlisting>
+ void xf86SetAccessFuncs(EntityInfoPtr pEnt,
+ xf86SetAccessFuncPtr funcs,
+ xf86SetAccessFuncPtr oldFuncs);
+ </programlisting>
+ with:
+ <programlisting>
+ typedef struct {
+ xf86AccessPtr mem;
+ xf86AccessPtr io;
+ xf86AccessPtr io_mem;
+ } xf86SetAccessFuncRec, *xf86SetAccessFuncPtr;
+ </programlisting>
+ <blockquote><para>
+ The driver can pass three functions: one for I/O access, one for
+ memory access and one for combined memory and I/O access. If the
+ memory access and combined access functions are identical the
+ common level assumes that the memory access cannot be controlled
+ independently of I/O access, if the I/O access function and the
+ combined access functions are the same it is assumed that I/O can
+ not be controlled independently. If memory and I/O have to be
+ controlled together all three values should be the same. If a
+ non <constant>NULL</constant> value is passed as third argument it is
+ interpreted as an address where to store the old access record.
+ If the third argument is <constant>NULL</constant> it will be assumed
+ that the generic access should be enabled before replacing the
+ access functions. Otherwise it will be disabled. The driver may
+ enable them itself using the returned values. It should do this
+ from its replacement access functions as the generic access may
+ be disabled by the common level on certain occasions. If replacement
+ functions are specified they must control all resources of the
+ specific type registered for the entity.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ <para>
+To find out if a specific resource range conflicts with another
+resource the <function>xf86ChkConflict()</function> function may be used:
+ <blockquote><para>
+ <programlisting>
+ memType xf86ChkConflict(resRange *rgp, int entityIndex);
+ </programlisting>
+ <blockquote><para>
+ This function checks if the resource range <parameter>rgp</parameter> of
+ for the specified entity conflicts with with another resource.
+ If a conflict is found, the address of the start of the conflict
+ is returned. The return value is zero when there is no conflict.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ <para>
+The OPERATING state properties of previously registered fixed resources
+can be set with the <function>xf86SetOperatingState()</function> function:
+ <blockquote><para>
+ <programlisting>
+ resPtr xf86SetOperatingState(resList list, int entityIndex,
+ int mask);
+ </programlisting>
+ <blockquote><para>
+ This function is used to set the status of a resource during
+ OPERATING state. <parameter>list</parameter> holds a list to which
+ <parameter>mask</parameter> is to be applied. The parameter
+ <parameter>mask</parameter> may have the value <constant>ResUnusedOpr</constant>
+ and <constant>ResDisableOpr</constant>. The first one should be used
+ if a resource isn't used by the driver during OPERATING state
+ although it is decoded by the device, while the latter one indicates
+ that the resource is not decoded during OPERATING state. Note
+ that the resource ranges have to match those specified during
+ registration. If a range has been specified starting at
+ <literal remap="tt">A</literal> and ending at <literal remap="tt">B</literal> and suppose
+ <literal remap="tt">C</literal> us a value satisfying
+ <literal remap="tt">A < C < B</literal> one may not
+ specify the resource range <literal remap="tt">(A,B)</literal> by splitting it
+ into two ranges <literal remap="tt">(A,C)</literal> and <literal remap="tt">(C,B)</literal>.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ <para>
+The following two functions are provided for special cases:
+ <blockquote><para>
+ <programlisting>
+ void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex);
+ </programlisting>
+ <blockquote><para>
+ This function may be used to remove an entity from a screen. This
+ only makes sense if a screen has more than one entity assigned or
+ the screen is to be deleted. No test is made if the screen has
+ any entities left.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86DeallocateResourcesForEntity(int entityIndex, long type);
+ </programlisting>
+ <blockquote><para>
+ This function deallocates all resources of a given type registered
+ for a certain entity from the resource broker list.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ </sect3>
+
+ <sect3>
+ <title>ScreenInit Phase</title>
+
+ <para>
+All that is required in this phase is to setup the RAC flags. Note that
+it is also permissible to set these flags up in the PreInit phase. The
+RAC flags are held in the <structfield>racIoFlags</structfield> and <structfield>racMemFlags</structfield> fields of the
+<structname>ScrnInfoRec</structname> for each screen. They specify which graphics operations
+might require the use of shared resources. This can be specified
+separately for memory and I/O resources. The available flags are defined
+in <filename>rac/xf86RAC.h</filename>. They are:
+
+ <variablelist>
+ <varlistentry><term><constant>RAC_FB</constant></term>
+ <listitem><para>
+ for framebuffer operations (including hw acceleration)
+ </para></listitem></varlistentry>
+ <varlistentry><term><constant>RAC_CURSOR</constant></term>
+ <listitem><para>
+ for Cursor operations
+ (??? I'm not sure if we need this for SW cursor it depends
+ on which level the sw cursor is drawn)
+ </para></listitem></varlistentry>
+ <varlistentry><term><constant>RAC_COLORMAP</constant></term>
+ <listitem><para>
+ for colormap operations
+ </para></listitem></varlistentry>
+ <varlistentry><term><constant>RAC_VIEWPORT</constant></term>
+ <listitem><para>
+ for the call to <function>ChipAdjustFrame()</function>
+ </para></listitem></varlistentry>
+ </variablelist>
+
+
+The flags are ORed together.
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 id="options">
+ <title>Config file <quote>Option</quote> entries</title>
+
+ <para>
+Option entries are permitted in most sections and subsections of the
+config file. There are two forms of option entries:
+
+ <variablelist>
+ <varlistentry><term>Option "option-name"</term>
+ <listitem><para>
+ A boolean option.
+ </para></listitem></varlistentry>
+ <varlistentry><term>Option "option-name" "option-value"</term>
+ <listitem><para>
+ An option with an arbitrary value.
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+The option entries are handled by the parser, and a list of the parsed
+options is included with each of the appropriate data structures that
+the drivers have access to. The data structures used to hold the option
+information are opaque to the driver, and a driver must not access the
+option data directly. Instead, the common layer provides a set of
+functions that may be used to access, check and manipulate the option
+data.
+ </para>
+
+ <para>
+First, the low level option handling functions. In most cases drivers
+would not need to use these directly.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ pointer xf86FindOption(pointer options, const char *name);
+ </programlisting>
+ <blockquote><para>
+ Takes a list of options and an option name, and returns a handle
+ for the first option entry in the list matching the name. Returns
+ <constant>NULL</constant> if no match is found.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ char *xf86FindOptionValue(pointer options, const char *name);
+ </programlisting>
+ <blockquote><para>
+ Takes a list of options and an option name, and returns the value
+ associated with the first option entry in the list matching the
+ name. If the matching option has no value, an empty string
+ (<constant>""</constant>) is returned. Returns <constant>NULL</constant>
+ if no match is found.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86MarkOptionUsed(pointer option);
+ </programlisting>
+ <blockquote><para>
+ Takes a handle for an option, and marks that option as used.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86MarkOptionUsedByName(pointer options, const char *name);
+ </programlisting>
+ <blockquote><para>
+ Takes a list of options and an option name and marks the first
+ option entry in the list matching the name as used.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <para>
+Next, the higher level functions that most drivers would use.
+ </para>
+ <blockquote><para>
+ <programlisting>
+ void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts);
+ </programlisting>
+ <blockquote><para>
+ Collect the options from each of the config file sections used by
+ the screen (<parameter>pScrn</parameter>) and return the merged list as
+ <structfield>pScrn->options</structfield>. This function requires that
+ <structfield>pScrn->confScreen</structfield>, <structfield>pScrn->display</structfield>,
+ <structfield>pScrn->monitor</structfield>,
+ <structfield>pScrn->numEntities</structfield>, and
+ <structfield>pScrn->entityList</structfield> are initialised.
+ <parameter>extraOpts</parameter> may optionally be set to an additional
+ list of options to be combined with the others. The order of
+ precedence for options is <parameter>extraOpts</parameter>, display,
+ confScreen, monitor, device.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86ProcessOptions(int scrnIndex, pointer options,
+ OptionInfoPtr optinfo);
+ </programlisting>
+ <blockquote><para>
+ Processes a list of options according to the information in the
+ array of <structname>OptionInfoRecs</structname> (<parameter>optinfo</parameter>).
+ The resulting information is stored in the <structfield>value</structfield>
+ fields of the appropriate <parameter>optinfo</parameter> entries. The
+ <structfield>found</structfield> fields are set to <constant>TRUE</constant>
+ when an option with a value of the correct type if found, and
+ <constant>FALSE</constant> otherwise. The <structfield>type</structfield> field
+ is used to determine the expected value type for each option.
+ Each option in the list of options for which there is a name match
+ (but not necessarily a value type match) is marked as used.
+ Warning messages are printed when option values don't match the
+ types specified in the optinfo data.
+ </para>
+
+ <para>
+ NOTE: If this function is called before a driver's screen number
+ is known (e.g., from the <function>ChipProbe()</function> function) a
+ <parameter>scrnIndex</parameter> value of <constant>-1</constant> should be
+ used.
+ </para>
+
+ <para>
+ NOTE 2: Given that this function stores into the
+ <literal remap="tt">OptionInfoRecs</literal> pointed to by <parameter>optinfo</parameter>,
+ the caller should ensure the <literal remap="tt">OptionInfoRecs</literal> are
+ (re-)initialised before the call, especially if the caller expects
+ to use the predefined option values as defaults.
+ </para>
+
+ <para>
+ The <structname>OptionInfoRec</structname> is defined as follows:
+
+ <programlisting>
+ typedef struct {
+ double freq;
+ int units;
+ } OptFrequency;
+
+ typedef union {
+ unsigned long num;
+ char * str;
+ double realnum;
+ Bool bool;
+ OptFrequency freq;
+ } ValueUnion;
+
+ typedef enum {
+ OPTV_NONE = 0,
+ OPTV_INTEGER,
+ OPTV_STRING, /* a non-empty string */
+ OPTV_ANYSTR, /* Any string, including an empty one */
+ OPTV_REAL,
+ OPTV_BOOLEAN,
+ OPTV_PERCENT,
+ OPTV_FREQ
+ } OptionValueType;
+
+ typedef enum {
+ OPTUNITS_HZ = 1,
+ OPTUNITS_KHZ,
+ OPTUNITS_MHZ
+ } OptFreqUnits;
+
+ typedef struct {
+ int token;
+ const char* name;
+ OptionValueType type;
+ ValueUnion value;
+ Bool found;
+ } OptionInfoRec, *OptionInfoPtr;
+ </programlisting>
+ </para>
+ <para>
+ <constant>OPTV_FREQ</constant> can be used for options values that are
+ frequencies. These values are a floating point number with an
+ optional unit name appended. The unit name can be one of "Hz",
+ "kHz", "k", "MHz", "M". The multiplier associated with the unit
+ is stored in <structfield>freq.units</structfield>, and the scaled frequency
+ is stored in <structfield>freq.freq</structfield>. When no unit is specified,
+ <structfield>freq.units</structfield> is set to <constant>0</constant>, and
+ <structfield>freq.freq</structfield> is unscaled.
+ </para>
+
+ <para>
+ <constant>OPTV_PERCENT</constant> can be used for option values that are
+ specified in percent (e.g. "20%"). These values are a floating point
+ number with a percent sign appended. If the percent sign is missing,
+ the parser will fail to match the value.
+ </para>
+
+ <para>
+ Typical usage is to setup an array of
+ <structname>OptionInfoRec</structname>s with all fields initialised.
+ The <structfield>value</structfield> and <structfield>found</structfield> fields get
+ set by <function>xf86ProcessOptions()</function>. For cases where the
+ value parsing is more complex, the driver should specify
+ <constant>OPTV_STRING</constant>, and parse the string itself. An
+ example of using this option handling is included in the
+ <link linkend="sample">Sample Driver</link> section.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86ShowUnusedOptions(int scrnIndex, pointer options);
+ </programlisting>
+ <blockquote><para>
+ Prints out warning messages for each option in the list of options
+ that isn't marked as used. This is intended to show options that
+ the driver hasn't recognised. It would normally be called near
+ the end of the <function>ChipScreenInit()</function> function, but only
+ when <code>serverGeneration == 1</code>
+ </para>
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ OptionInfoPtr xf86TokenToOptinfo(const OptionInfoRec *table,
+ int token);
+ </programlisting>
+ <blockquote><para>
+ Returns a pointer to the <structname>OptionInfoRec</structname> in
+ <parameter>table</parameter> with a token field matching
+ <parameter>token</parameter>. Returns <constant>NULL</constant> if no match
+ is found.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86IsOptionSet(const OptionInfoRec *table, int token);
+ </programlisting>
+ <blockquote><para>
+ Returns the <literal remap="tt">found</literal> field of the
+ <structname>OptionInfoRec</structname> in <parameter>table</parameter> with a
+ <structfield>token</structfield> field matching <parameter>token</parameter>. This
+ can be used for options of all types. Note that for options of
+ type <constant>OPTV_BOOLEAN</constant>, it isn't sufficient to check
+ this to determine the value of the option. Returns
+ <constant>FALSE</constant> if no match is found.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ char *xf86GetOptValString(const OptionInfoRec *table, int token);
+ </programlisting>
+ <blockquote><para>
+ Returns the <structfield>value.str</structfield> field of the
+ <structname>OptionInfoRec</structname> in <parameter>table</parameter> with a
+ token field matching <parameter>token</parameter>. Returns
+ <constant>NULL</constant> if no match is found.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86GetOptValInteger(const OptionInfoRec *table, int token,
+
+ int *value);
+ </programlisting>
+ <blockquote><para>
+ Returns via <parameter>*value</parameter> the <structfield>value.num</structfield>
+ field of the <structname>OptionInfoRec</structname> in <parameter>table</parameter>
+ with a <structfield>token</structfield> field matching <parameter>token</parameter>.
+ <parameter>*value</parameter> is only changed when a match is found so
+ it can be safely initialised with a default prior to calling this
+ function. The function return value is as for
+ <function>xf86IsOptionSet()</function>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86GetOptValULong(const OptionInfoRec *table, int token,
+ unsigned long *value);
+ </programlisting>
+ <blockquote><para>
+ Like <function>xf86GetOptValInteger()</function>, except the value is
+ treated as an <type>unsigned long</type>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86GetOptValReal(const OptionInfoRec *table, int token,
+ double *value);
+ </programlisting>
+ <blockquote><para>
+ Like <function>xf86GetOptValInteger()</function>, except that
+ <structfield>value.realnum</structfield> is used.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86GetOptValFreq(const OptionInfoRec *table, int token,
+ OptFreqUnits expectedUnits, double *value);
+ </programlisting>
+ <blockquote><para>
+ Like <function>xf86GetOptValInteger()</function>, except that the
+ <structfield>value.freq</structfield> data is returned. The frequency value
+ is scaled to the units indicated by <parameter>expectedUnits</parameter>.
+ The scaling is exact when the units were specified explicitly in
+ the option's value. Otherwise, the <parameter>expectedUnits</parameter>
+ field is used as a hint when doing the scaling. In this case,
+ values larger than <constant>1000</constant> are assumed to have be
+ specified in the next smallest units. For example, if the Option
+ value is "10000" and expectedUnits is <constant>OPTUNITS_MHZ</constant>,
+ the value returned is <constant>10</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value);
+ </programlisting>
+ <blockquote><para>
+ This function is used to check boolean options
+ (<constant>OPTV_BOOLEAN</constant>). If the function return value is
+ <constant>FALSE</constant>, it means the option wasn't set. Otherwise
+ <parameter>*value</parameter> is set to the boolean value indicated by
+ the option's value. No option <parameter>value</parameter> is interpreted
+ as <constant>TRUE</constant>. Option values meaning <constant>TRUE</constant>
+ are "1", "yes", "on", "true", and option values meaning
+ <constant>FALSE</constant> are "0", "no", "off", "false". Option names
+ both with the "no" prefix in their names, and with that prefix
+ removed are also checked and handled in the obvious way.
+ <parameter>*value</parameter> is not changed when the option isn't present.
+ It should normally be set to a default value before calling this
+ function.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def);
+ </programlisting>
+ <blockquote><para>
+ This function is used to check boolean options
+ (<constant>OPTV_BOOLEAN</constant>). If the option is set, its value
+ is returned. If the options is not set, the default value specified
+ by <parameter>def</parameter> is returned. The option interpretation is
+ the same as for <function>xf86GetOptValBool()</function>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86NameCmp(const char *s1, const char *s2);
+ </programlisting>
+ <blockquote><para>
+ This function should be used when comparing strings from the config
+ file with expected values. It works like <function>strcmp()</function>,
+ but is not case sensitive and space, tab, and <quote><literal>_</literal></quote> characters
+ are ignored in the comparison. The use of this function isn't
+ restricted to parsing option values. It may be used anywhere
+ where this functionality required.
+ </para>
+
+ </blockquote></para></blockquote>
+ </sect1>
+
+ <sect1>
+ <title>Modules, Drivers, Include Files and Interface Issues</title>
+
+ <para>
+NOTE: this section is incomplete.
+ </para>
+
+
+ <sect2>
+ <title>Include files</title>
+
+ <para>
+The following include files are typically required by video drivers:
+
+ <blockquote><para>
+ All drivers should include these:
+ <literallayout><filename>
+ "xf86.h"
+ "xf86_OSproc.h"
+ "xf86_ansic.h"
+ "xf86Resources.h"
+ </filename></literallayout>
+ Wherever inb/outb (and related things) are used the following should be
+ included:
+ <literallayout><filename>
+ "compiler.h"
+ </filename></literallayout>
+ Note: in drivers, this must be included after <filename>"xf86_ansic.h"</filename>.
+ </para>
+
+ <para>
+ Drivers that need to access PCI vendor/device definitions need this:
+ <literallayout><filename>
+ "xf86PciInfo.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers that need to access the PCI config space need this:
+ <literallayout><filename>
+ "xf86Pci.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers that initialise a SW cursor need this:
+ <literallayout><filename>
+ "mipointer.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ All drivers implementing backing store need this:
+ <literallayout><filename>
+ "mibstore.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ All drivers using the mi colourmap code need this:
+ <literallayout><filename>
+ "micmap.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ If a driver uses the vgahw module, it needs this:
+ <literallayout><filename>
+ "vgaHW.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers supporting VGA or Hercules monochrome screens need:
+ <literallayout><filename>
+ "xf1bpp.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers supporting VGA or EGC 16-colour screens need:
+ <literallayout><filename>
+ "xf4bpp.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers using cfb need:
+ <programlisting>
+ #define PSZ 8
+ #include "cfb.h"
+ #undef PSZ
+ </programlisting>
+ </para>
+
+ <para>
+ Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
+ <literallayout><filename>
+ "cfb16.h"
+ "cfb24.h"
+ "cfb32.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ If a driver uses XAA, it needs these:
+ <literallayout><filename>
+ "xaa.h"
+ "xaalocal.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ If a driver uses the fb manager, it needs this:
+ <literallayout><filename>
+ "xf86fbman.h"
+ </filename></literallayout>
+ </para>
+ </blockquote>
+ </para>
+
+ <para>
+Non-driver modules should include <filename>"xf86_ansic.h"</filename> to get the correct
+wrapping of ANSI C/libc functions.
+ </para>
+
+ <para>
+All modules must NOT include any system include files, or the following:
+
+ <literallayout><filename>
+ "xf86Priv.h"
+ "xf86Privstr.h"
+ "xf86_OSlib.h"
+ "Xos.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+In addition, "xf86_libc.h" must not be included explicitly. It is
+included implicitly by "xf86_ansic.h".
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>Offscreen Memory Manager</title>
+
+ <para>
+Management of offscreen video memory may be handled by the XFree86
+framebuffer manager. Once the offscreen memory manager is running,
+drivers or extensions may allocate, free or resize areas of offscreen
+video memory using the following functions (definitions taken from
+<filename>xf86fbman.h</filename>):
+
+ <programlisting>
+ typedef struct _FBArea {
+ ScreenPtr pScreen;
+ BoxRec box;
+ int granularity;
+ void (*MoveAreaCallback)(struct _FBArea*, struct _FBArea*)
+ void (*RemoveAreaCallback)(struct _FBArea*)
+ DevUnion devPrivate;
+ } FBArea, *FBAreaPtr;
+
+ typedef void (*MoveAreaCallbackProcPtr)(FBAreaPtr from, FBAreaPtr to)
+ typedef void (*RemoveAreaCallbackProcPtr)(FBAreaPtr)
+
+ FBAreaPtr xf86AllocateOffscreenArea (
+ ScreenPtr pScreen,
+ int width, int height,
+ int granularity,
+ MoveAreaCallbackProcPtr MoveAreaCallback,
+ RemoveAreaCallbackProcPtr RemoveAreaCallback,
+ pointer privData
+ )
+
+ void xf86FreeOffscreenArea (FBAreaPtr area)
+
+ Bool xf86ResizeOffscreenArea (
+ FBAreaPtr area
+ int w, int h
+ )
+ </programlisting>
+ </para>
+
+ <para>
+The function:
+ <programlisting>
+ Bool xf86FBManagerRunning(ScreenPtr pScreen);
+ </programlisting>
+
+can be used by an extension to check if the driver has initialized
+the memory manager. The manager is not available if this returns
+<constant>FALSE</constant> and the functions above will all fail.
+ </para>
+
+
+ <para>
+<function>xf86AllocateOffscreenArea()</function> can be used to request a
+rectangle of dimensions <parameter>width</parameter> × <parameter>height</parameter>
+(in pixels) from unused offscreen memory. <parameter>granularity</parameter>
+specifies that the leftmost edge of the rectangle must lie on some
+multiple of <parameter>granularity</parameter> pixels. A granularity of zero
+means the same thing as a granularity of one - no alignment preference.
+A <parameter>MoveAreaCallback</parameter> can be provided to notify the requester
+when the offscreen area is moved. If no <parameter>MoveAreaCallback</parameter>
+is supplied then the area is considered to be immovable. The
+<parameter>privData</parameter> field will be stored in the manager's internal
+structure for that allocated area and will be returned to the requester
+in the <parameter>FBArea</parameter> passed via the
+<parameter>MoveAreaCallback</parameter>. An optional
+<parameter>RemoveAreaCallback</parameter> is provided. If the driver provides
+this it indicates that the area should be allocated with a lower priority.
+Such an area may be removed when a higher priority request (one that
+doesn't have a <parameter>RemoveAreaCallback</parameter>) is made. When this
+function is called, the driver will have an opportunity to do whatever
+cleanup it needs to do to deal with the loss of the area, but it must
+finish its cleanup before the function exits since the offscreen memory
+manager will free the area immediately after.
+ </para>
+
+ <para>
+<function>xf86AllocateOffscreenArea()</function> returns <constant>NULL</constant>
+if it was unable to allocate the requested area. When no longer needed,
+areas should be freed with <function>xf86FreeOffscreenArea()</function>.
+ </para>
+
+ <para>
+<function>xf86ResizeOffscreenArea()</function> resizes an existing
+<literal remap="tt">FBArea</literal>. <function>xf86ResizeOffscreenArea()</function>
+returns <constant>TRUE</constant> if the resize was successful. If
+<function>xf86ResizeOffscreenArea()</function> returns <constant>FALSE</constant>,
+the original <literal remap="tt">FBArea</literal> is left unmodified. Resizing an
+area maintains the area's original <literal remap="tt">granularity</literal>,
+<literal remap="tt">devPrivate</literal>, and <literal remap="tt">MoveAreaCallback</literal>.
+<function>xf86ResizeOffscreenArea()</function> has considerably less overhead
+than freeing the old area then reallocating the new size, so it should
+be used whenever possible.
+ </para>
+
+ <para>
+The function:
+ <programlisting>
+ Bool xf86QueryLargestOffscreenArea(
+ ScreenPtr pScreen,
+ int *width, int *height,
+ int granularity,
+ int preferences,
+ int priority
+ );
+ </programlisting>
+
+is provided to query the width and height of the largest single
+<structname>FBArea</structname> allocatable given a particular priority.
+<parameter>preferences</parameter> can be one of the following to indicate
+whether width, height or area should be considered when determining
+which is the largest single <structname>FBArea</structname> available.
+
+ <programlisting>
+ FAVOR_AREA_THEN_WIDTH
+ FAVOR_AREA_THEN_HEIGHT
+ FAVOR_WIDTH_THEN_AREA
+ FAVOR_HEIGHT_THEN_AREA
+ </programlisting>
+ </para>
+
+ <para>
+<parameter>priority</parameter> is one of the following:
+
+ <blockquote>
+ <para>
+ <constant>PRIORITY_LOW</constant>
+ <blockquote><para>
+ Return the largest block available without stealing anyone else's
+ space. This corresponds to the priority of allocating a
+ <structname>FBArea</structname> when a <function>RemoveAreaCallback</function>
+ is provided.
+ </para></blockquote>
+ </para>
+
+ <para>
+ <constant>PRIORITY_NORMAL</constant>
+ <blockquote><para>
+ Return the largest block available if it is acceptable to steal a
+ lower priority area from someone. This corresponds to the priority
+ of allocating a <structname>FBArea</structname> without providing a
+ <function>RemoveAreaCallback</function>.
+ </para></blockquote>
+ </para>
+
+ <para>
+ <constant>PRIORITY_EXTREME</constant>
+ <blockquote><para>
+ Return the largest block available if all <structname>FBArea</structname>s
+ that aren't locked down were expunged from memory first. This
+ corresponds to any allocation made directly after a call to
+ <function>xf86PurgeUnlockedOffscreenAreas()</function>.
+ </para></blockquote>
+ </para>
+
+ </blockquote>
+ </para>
+
+
+ <para>
+The function:
+
+ <programlisting>
+ Bool xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen);
+ </programlisting>
+
+is provided as an extreme method to free up offscreen memory. This
+will remove all removable <structname>FBArea</structname> allocations.
+ </para>
+
+
+ <para>
+Initialization of the XFree86 framebuffer manager is done via
+
+ <programlisting>
+ Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox);
+ </programlisting>
+
+<parameter>FullBox</parameter> represents the area of the framebuffer that the
+manager is allowed to manage. This is typically a box with a width of
+<structfield>pScrn->displayWidth</structfield> and a height of as many lines as
+can be fit within the total video memory, however, the driver can reserve
+areas at the extremities by passing a smaller area to the manager.
+ </para>
+
+ <para>
+<function>xf86InitFBManager()</function> must be called before XAA is
+initialized since XAA uses the manager for it's pixmap cache.
+ </para>
+
+ <para>
+An alternative function is provided to allow the driver to initialize
+the framebuffer manager with a Region rather than a box.
+
+ <programlisting>
+ Bool xf86InitFBManagerRegion(ScreenPtr pScreen,
+ RegionPtr FullRegion);
+ </programlisting>
+
+<function>xf86InitFBManagerRegion()</function>, unlike
+<function>xf86InitFBManager()</function>, does not remove the area used for
+the visible screen so that area should not be included in the region
+passed to the function. <function>xf86InitFBManagerRegion()</function> is
+useful when non-contiguous areas are available to be managed, and is
+required when multiple framebuffers are stored in video memory (as in
+the case where an overlay of a different depth is stored as a second
+framebuffer in offscreen memory).
+ </para>
+
+ </sect1>
+
+ <sect1 id="cmap">
+ <title>Colormap Handling</title>
+
+ <para>
+A generic colormap handling layer is provided within the XFree86 common
+layer. This layer takes care of most of the details, and only requires
+a function from the driver that loads the hardware palette when required.
+To use the colormap layer, a driver calls the
+<function>xf86HandleColormaps()</function> function.
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86HandleColormaps(ScreenPtr pScreen, int maxColors,
+ int sigRGBbits, LoadPaletteFuncPtr loadPalette,
+ SetOverscanFuncPtr setOverscan,
+ unsigned int flags);
+ </programlisting>
+ <blockquote><para>
+ This function must be called after the default colormap has been
+ initialised. The <structfield>pScrn->gamma</structfield> field must also
+ be initialised, preferably by calling <function>xf86SetGamma()</function>.
+ <parameter>maxColors</parameter> is the number of entries in the palette.
+ <parameter>sigRGBbits</parameter> is the size in bits of each color
+ component in the DAC's palette. <parameter>loadPalette</parameter>
+ is a driver-provided function for loading a colormap into the
+ hardware, and is described below. <parameter>setOverscan</parameter> is
+ an optional function that may be provided when the overscan color
+ is an index from the standard LUT and when it needs to be adjusted
+ to keep it as close to black as possible. The
+ <parameter>setOverscan</parameter> function programs the overscan index.
+ It shouldn't normally be used for depths other than 8.
+ <parameter>setOverscan</parameter> should be set to <constant>NULL</constant>
+ when it isn't needed. <parameter>flags</parameter> may be set to the
+ following (which may be ORed together):
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>CMAP_PALETTED_TRUECOLOR</constant></term>
+ <listitem><para>
+ the TrueColor visual is paletted and is
+ just a special case of DirectColor.
+ This flag is only valid for
+ <code>bpp > 8</code>.
+
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>CMAP_RELOAD_ON_MODE_SWITCH</constant></term>
+ <listitem><para>
+ reload the colormap automatically
+ after mode switches. This is useful
+ for when the driver is resetting the
+ hardware during mode switches and
+ corrupting or erasing the hardware
+ palette.
+
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>CMAP_LOAD_EVEN_IF_OFFSCREEN</constant></term>
+ <listitem><para>
+ reload the colormap even if the screen
+ is switched out of the server's VC.
+ The palette is <emphasis>not</emphasis> reloaded when
+ the screen is switched back in, nor after
+ mode switches. This is useful when the
+ driver needs to keep track of palette
+ changes.
+
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The colormap layer normally reloads the palette after VT enters so it
+ is not necessary for the driver to save and restore the palette
+ when switching VTs. The driver must, however, still save the
+ initial palette during server start up and restore it during
+ server exit.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual);
+ </programlisting>
+ <blockquote><para>
+ <function>LoadPalette()</function> is a driver-provided function for
+ loading a colormap into hardware. <parameter>colors</parameter> is the
+ array of RGB values that represent the full colormap.
+ <parameter>indices</parameter> is a list of index values into the colors
+ array. These indices indicate the entries that need to be updated.
+ <parameter>numColors</parameter> is the number of the indices to be
+ updated.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void SetOverscan(ScrnInfoPtr pScrn, int overscan);
+ </programlisting>
+ <blockquote><para>
+ <function>SetOverscan()</function> is a driver-provided function for
+ programming the <parameter>overscan</parameter> index. As described
+ above, it is normally only appropriate for LUT modes where all
+ colormap entries are available for the display, but where one of
+ them is also used for the overscan (typically 8bpp for VGA compatible
+ LUTs). It isn't required in cases where the overscan area is
+ never visible.
+ </para>
+
+ </blockquote></para>
+ </blockquote></para>
+
+ </sect1>
+
+ <sect1>
+ <title>DPMS Extension</title>
+
+ <para>
+Support code for the DPMS extension is included in the XFree86 common layer.
+This code provides an interface between the main extension code, and a means
+for drivers to initialise DPMS when they support it. One function is
+available to drivers to do this initialisation, and it is always available,
+even when the DPMS extension is not supported by the core server (in
+which case it returns a failure result).
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags);
+ </programlisting>
+ <blockquote><para>
+ This function registers a driver's DPMS level programming function
+ <parameter>set</parameter>. It also checks
+ <structfield>pScrn->options</structfield> for the "dpms" option, and when
+ present marks DPMS as being enabled for that screen. The
+ <parameter>set</parameter> function is called whenever the DPMS level
+ changes, and is used to program the requested level.
+ <parameter>flags</parameter> is currently not used, and should be
+ <constant>0</constant>. If the initialisation fails for any reason,
+ including when there is no DPMS support in the core server, the
+ function returns <constant>FALSE</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+
+ <para>
+Drivers that implement DPMS support must provide the following function,
+that gets called when the DPMS level is changed:
+
+
+ <blockquote><para>
+ <programlisting>
+ void ChipDPMSSet(ScrnInfoPtr pScrn, int level, int flags);
+ </programlisting>
+ <blockquote><para>
+ Program the DPMS level specified by <parameter>level</parameter>. Valid
+ values of <parameter>level</parameter> are <constant>DPMSModeOn</constant>,
+ <constant>DPMSModeStandby</constant>, <constant>DPMSModeSuspend</constant>,
+ <constant>DPMSModeOff</constant>. These values are defined in
+ <filename>"extensions/dpms.h"</filename>.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ </sect1>
+
+ <sect1>
+ <title>DGA Extension</title>
+
+ <para>
+Drivers can support the XFree86 Direct Graphics Architecture (DGA) by
+filling out a structure of function pointers and a list of modes and
+passing them to DGAInit.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs,
+ DGAModePtr modes, int num);
+
+/** The DGAModeRec **/
+
+typedef struct {
+ int num;
+ DisplayModePtr mode;
+ int flags;
+ int imageWidth;
+ int imageHeight;
+ int pixmapWidth;
+ int pixmapHeight;
+ int bytesPerScanline;
+ int byteOrder;
+ int depth;
+ int bitsPerPixel;
+ unsigned long red_mask;
+ unsigned long green_mask;
+ unsigned long blue_mask;
+ int viewportWidth;
+ int viewportHeight;
+ int xViewportStep;
+ int yViewportStep;
+ int maxViewportX;
+ int maxViewportY;
+ int viewportFlags;
+ int offset;
+ unsigned char *address;
+ int reserved1;
+ int reserved2;
+} DGAModeRec, *DGAModePtr;
+ </programlisting>
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>num</structfield></term>
+ <listitem><para>
+ Can be ignored. The DGA DDX will assign these numbers.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>mode</structfield></term>
+ <listitem><para>
+ A pointer to the <structname>DisplayModeRec</structname> for this mode.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>flags</structfield></term>
+ <listitem><para>
+ The following flags are defined and may be OR'd together:
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>DGA_CONCURRENT_ACCESS</constant></term>
+ <listitem><para>
+ Indicates that the driver supports concurrent graphics
+ accelerator and linear framebuffer access.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><constant>DGA_FILL_RECT
+ DGA_BLIT_RECT
+ DGA_BLIT_RECT_TRANS</constant></term>
+ <listitem><para>
+ Indicates that the driver supports the FillRect, BlitRect
+ or BlitTransRect functions in this mode.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><constant>DGA_PIXMAP_AVAILABLE</constant></term>
+ <listitem><para>
+ Indicates that Xlib may be used on the framebuffer.
+ This flag will usually be set unless the driver wishes
+ to prohibit this for some reason.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><constant>DGA_INTERLACED
+ DGA_DOUBLESCAN</constant></term>
+ <listitem><para>
+ Indicates that these are interlaced or double scan modes.
+
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>imageWidth
+ imageHeight</structfield></term>
+ <listitem><para>
+ These are the dimensions of the linear framebuffer
+ accessible by the client.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>pixmapWidth
+ pixmapHeight</structfield></term>
+ <listitem><para>
+ These are the dimensions of the area of the
+ framebuffer accessible by the graphics accelerator.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>bytesPerScanline</structfield></term>
+ <listitem><para>
+ Pitch of the framebuffer in bytes.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>byteOrder</structfield></term>
+ <listitem><para>
+ Usually the same as
+ <structfield>pScrn->imageByteOrder</structfield>.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>depth</structfield></term>
+ <listitem><para>
+ The depth of the framebuffer in this mode.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>bitsPerPixel</structfield></term>
+ <listitem><para>
+ The number of bits per pixel in this mode.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>red_mask</structfield></term>
+ <term><structfield>green_mask</structfield></term>
+ <term><structfield>blue_mask</structfield></term>
+ <listitem><para>
+ The RGB masks for this mode, if applicable.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>viewportWidth</structfield></term>
+ <term><structfield>viewportHeight</structfield></term>
+ <listitem><para>
+ Dimensions of the visible part of the framebuffer.
+ Usually <structfield>mode->HDisplay</structfield> and
+ <structfield>mode->VDisplay</structfield>.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>xViewportStep
+ yViewportStep</structfield></term>
+ <listitem><para>
+ The granularity of x and y viewport positions that
+ the driver supports in this mode.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>maxViewportX
+ maxViewportY</structfield></term>
+ <listitem><para>
+ The maximum viewport position supported by the
+ driver in this mode.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>viewportFlags</structfield></term>
+ <listitem><para>
+ The following may be OR'd together:
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>DGA_FLIP_IMMEDIATE</constant></term>
+ <listitem><para>
+ The driver supports immediate viewport changes.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><constant>DGA_FLIP_RETRACE</constant></term>
+
+ <listitem><para>
+ The driver supports viewport changes at retrace.
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>offset</structfield></term>
+ <listitem><para>
+ The offset into the linear framebuffer that corresponds to
+ pixel (0,0) for this mode.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>address</structfield></term>
+ <listitem><para>
+ The virtual address of the framebuffer as mapped by the driver.
+ This is needed when DGA_PIXMAP_AVAILABLE is set.
+ </para></listitem></varlistentry>
+
+ </variablelist>
+
+ <programlisting>
+/** The DGAFunctionRec **/
+
+typedef struct {
+ Bool (*OpenFramebuffer)(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *extra
+ );
+ void (*CloseFramebuffer)(ScrnInfoPtr pScrn);
+ Bool (*SetMode)(ScrnInfoPtr pScrn, DGAModePtr pMode);
+ void (*SetViewport)(ScrnInfoPtr pScrn, int x, int y, int flags);
+ int (*GetViewport)(ScrnInfoPtr pScrn);
+ void (*Sync)(ScrnInfoPtr);
+ void (*FillRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+ );
+ void (*BlitRect)(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+ );
+ void (*BlitTransRect)(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+ );
+} DGAFunctionRec, *DGAFunctionPtr;
+ </programlisting>
+
+
+ <blockquote><para>
+ <programlisting>
+ Bool OpenFramebuffer (pScrn, name, mem, size, offset, extra);
+ </programlisting>
+ <blockquote><para>
+ <function>OpenFramebuffer()</function> should pass the client everything
+ it needs to know to be able to open the framebuffer. These
+ parameters are OS specific and their meanings are to be interpreted
+ by an OS specific client library.
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem><para>
+ The name of the device to open or <constant>NULL</constant> if
+ there is no special device to open. A <constant>NULL</constant>
+ name tells the client that it should open whatever device
+ one would usually open to access physical memory.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>mem</parameter></term>
+ <listitem><para>
+ The physical address of the start of the framebuffer.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>size</parameter></term>
+ <listitem><para>
+ The size of the framebuffer in bytes.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>offset</parameter></term>
+ <listitem><para>
+ Any offset into the device, if applicable.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>flags</parameter></term>
+ <listitem><para>
+ Any additional information that the client may need.
+ Currently, only the <constant>DGA_NEED_ROOT</constant> flag is
+ defined.
+ </para></listitem></varlistentry>
+
+ </variablelist>
+ </para></blockquote>
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void CloseFramebuffer (pScrn);
+ </programlisting>
+ <blockquote><para>
+ <function>CloseFramebuffer()</function> merely informs the driver (if it
+ even cares) that client no longer needs to access the framebuffer
+ directly. This function is optional.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool SetMode (pScrn, pMode);
+ </programlisting>
+ <blockquote><para>
+ <function>SetMode()</function> tells the driver to initialize the mode
+ passed to it. If <parameter>pMode</parameter> is <constant>NULL</constant>,
+ then the driver should restore the original pre-DGA mode.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void SetViewport (pScrn, x, y, flags);
+ </programlisting>
+ <blockquote><para>
+ <function>SetViewport()</function> tells the driver to make the upper
+ left-hand corner of the visible screen correspond to coordinate
+ <literal remap="tt">(x,y)</literal> on the framebuffer. <parameter>flags</parameter>
+ currently defined are:
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>DGA_FLIP_IMMEDIATE</constant></term>
+ <listitem><para>
+ The viewport change should occur immediately.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><constant>DGA_FLIP_RETRACE</constant></term>
+ <listitem><para>
+ The viewport change should occur at the
+ vertical retrace, but this function should
+ return sooner if possible.
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The <literal remap="tt">(x,y)</literal> locations will be passed as the client
+ specified them, however, the driver is expected to round these
+ locations down to the next supported location as specified by the
+ <structfield>xViewportStep</structfield> and <structfield>yViewportStep</structfield>
+ for the current mode.
+ </para>
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ int GetViewport (pScrn);
+ </programlisting>
+ <blockquote><para>
+ <function>GetViewport()</function> gets the current page flip status.
+ Set bits in the returned int correspond to viewport change requests
+ still pending. For instance, set bit zero if the last SetViewport
+ request is still pending, bit one if the one before that is still
+ pending, etc.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void Sync (pScrn);
+ </programlisting>
+ <blockquote><para>
+ This function should ensure that any graphics accelerator operations
+ have finished. This function should not return until the graphics
+ accelerator is idle.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void FillRect (pScrn, x, y, w, h, color);
+ </programlisting>
+ <blockquote><para>
+ This optional function should fill a rectangle
+ <parameter>w × h</parameter> located at
+ <parameter>(x,y)</parameter> in the given color.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void BlitRect (pScrn, srcx, srcy, w, h, dstx, dsty);
+ </programlisting>
+ <blockquote><para>
+ This optional function should copy an area
+ <parameter>w × h</parameter> located at
+ <parameter>(srcx,srcy)</parameter> to location <parameter>(dstx,dsty)</parameter>.
+ This function will need to handle copy directions as appropriate.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void BlitTransRect (pScrn, srcx, srcy, w, h, dstx, dsty, color);
+ </programlisting>
+ <blockquote><para>
+ This optional function is the same as BlitRect except that pixels
+ in the source corresponding to the color key <parameter>color</parameter>
+ should be skipped.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para></blockquote>
+
+ </sect1>
+
+ <sect1>
+ <title>The XFree86 X Video Extension (Xv) Device Dependent Layer</title>
+
+ <para>
+XFree86 offers the X Video Extension which allows clients to treat video
+as any another primitive and <quote>Put</quote> video into drawables. By default,
+the extension reports no video adaptors as being available since the
+DDX layer has not been initialized. The driver can initialize the DDX
+layer by filling out one or more <literal remap="tt">XF86VideoAdaptorRecs</literal>
+as described later in this document and passing a list of
+<literal remap="tt">XF86VideoAdaptorPtr</literal> pointers to the following function:
+
+ <programlisting>
+ Bool xf86XVScreenInit(ScreenPtr pScreen,
+ XF86VideoAdaptorPtr *adaptPtrs,
+ int num);
+ </programlisting>
+ </para>
+
+ <para>
+After doing this, the extension will report video adaptors as being
+available, providing the data in their respective
+<literal remap="tt">XF86VideoAdaptorRecs</literal> was valid.
+<function>xf86XVScreenInit()</function> <emphasis>copies</emphasis> data from the structure
+passed to it so the driver may free it after the initialization. At
+the moment, the DDX only supports rendering into Window drawables.
+Pixmap rendering will be supported after a sufficient survey of suitable
+hardware is completed.
+ </para>
+
+ <para>
+The <structname>XF86VideoAdaptorRec</structname>:
+
+ <programlisting>
+typedef struct {
+ unsigned int type;
+ int flags;
+ char *name;
+ int nEncodings;
+ XF86VideoEncodingPtr pEncodings;
+ int nFormats;
+ XF86VideoFormatPtr pFormats;
+ int nPorts;
+ DevUnion *pPortPrivates;
+ int nAttributes;
+ XF86AttributePtr pAttributes;
+ int nImages;
+ XF86ImagePtr pImages;
+ PutVideoFuncPtr PutVideo;
+ PutStillFuncPtr PutStill;
+ GetVideoFuncPtr GetVideo;
+ GetStillFuncPtr GetStill;
+ StopVideoFuncPtr StopVideo;
+ SetPortAttributeFuncPtr SetPortAttribute;
+ GetPortAttributeFuncPtr GetPortAttribute;
+ QueryBestSizeFuncPtr QueryBestSize;
+ PutImageFuncPtr PutImage;
+ QueryImageAttributesFuncPtr QueryImageAttributes;
+} XF86VideoAdaptorRec, *XF86VideoAdaptorPtr;
+ </programlisting></para>
+
+ <para>
+Each adaptor will have its own XF86VideoAdaptorRec. The fields are
+as follows:
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>type</structfield></term>
+ <listitem><para>
+ This can be any of the following flags OR'd together.
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>XvInputMask</constant>
+ <constant>XvOutputMask</constant></term>
+ <listitem><para>
+ These refer to the target drawable and are similar to a Window's
+ class. <literal remap="tt">XvInputMask</literal> indicates that the adaptor
+ can put video into a drawable. <literal remap="tt">XvOutputMask</literal>
+ indicates that the adaptor can get video from a drawable.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><constant>XvVideoMask</constant>
+ <constant>XvStillMask</constant>
+ <constant>XvImageMask</constant></term>
+ <listitem><para>
+ These indicate that the adaptor supports video, still or
+ image primitives respectively.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><constant>XvWindowMask</constant>
+ <constant>XvPixmapMask</constant></term>
+ <listitem><para>
+ These indicate the types of drawables the adaptor is capable
+ of rendering into. At the moment, Pixmap rendering is not
+ supported and the <constant>XvPixmapMask</constant> flag is ignored.
+ </para></listitem></varlistentry>
+ </variablelist>
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>flags</structfield></term>
+ <listitem><para>
+ Currently, the following flags are defined:
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>VIDEO_NO_CLIPPING</constant></term>
+ <listitem><para>
+ This indicates that the video adaptor does not support
+ clipping. The driver will never receive <quote>Put</quote> requests
+ where less than the entire area determined by
+ <parameter>drw_x</parameter>, <parameter>drw_y</parameter>,
+ <parameter>drw_w</parameter> and <parameter>drw_h</parameter> is visible.
+ This flag does not apply to <quote>Get</quote> requests. Hardware
+ that is incapable of clipping <quote>Gets</quote> may punt or get
+ the extents of the clipping region passed to it.
+ </para></listitem>
+
+ </varlistentry>
+
+ <varlistentry>
+ <term><constant>VIDEO_INVERT_CLIPLIST</constant></term>
+ <listitem><para>
+ This indicates that the video driver requires the clip
+ list to contain the regions which are obscured rather
+ than the regions which are are visible.
+ </para></listitem>
+
+ </varlistentry>
+
+ <varlistentry>
+ <term><constant>VIDEO_OVERLAID_STILLS</constant></term>
+ <listitem><para>
+ Implementing PutStill for hardware that does video as an
+ overlay can be awkward since it's unclear how long to leave
+ the video up for. When this flag is set, StopVideo will be
+ called whenever the destination gets clipped or moved so that
+ the still can be left up until then.
+ </para></listitem>
+
+ </varlistentry>
+
+ <varlistentry>
+ <term><constant>VIDEO_OVERLAID_IMAGES</constant></term>
+ <listitem><para>
+ Same as <constant>VIDEO_OVERLAID_STILLS</constant> but for images.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><constant>VIDEO_CLIP_TO_VIEWPORT</constant></term>
+ <listitem><para>
+ Indicates that the clip region passed to the driver functions
+ should be clipped to the visible portion of the screen in the
+ case where the viewport is smaller than the virtual desktop.
+ </para></listitem></varlistentry>
+
+ </variablelist>
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>name</structfield></term>
+ <listitem><para>
+ The name of the adaptor.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>nEncodings</structfield>
+ <structfield>pEncodings</structfield></term>
+ <listitem><para>
+ The number of encodings the adaptor is capable of and pointer
+ to the <structname>XF86VideoEncodingRec</structname> array. The
+ <structname>XF86VideoEncodingRec</structname> is described later on.
+ For drivers that only support XvImages there should be an encoding
+ named "XV_IMAGE" and the width and height should specify
+ the maximum size source image supported.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>nFormats</structfield>
+ <structfield>pFormats</structfield></term>
+ <listitem><para>
+ The number of formats the adaptor is capable of and pointer to
+ the <structname>XF86VideoFormatRec</structname> array. The
+ <structname>XF86VideoFormatRec</structname> is described later on.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>nPorts</structfield>
+ <structfield>pPortPrivates</structfield></term>
+ <listitem><para>
+ The number of ports is the number of separate data streams which
+ the adaptor can handle simultaneously. If you have more than
+ one port, the adaptor is expected to be able to render into more
+ than one window at a time. <structfield>pPortPrivates</structfield> is
+ an array of pointers or ints - one for each port. A port's
+ private data will be passed to the driver any time the port is
+ requested to do something like put the video or stop the video.
+ In the case where there may be many ports, this enables the
+ driver to know which port the request is intended for. Most
+ commonly, this will contain a pointer to the data structure
+ containing information about the port. In Xv, all ports on
+ a particular adaptor are expected to be identical in their
+ functionality.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>nAttributes</structfield>
+ <structfield>pAttributes</structfield></term>
+ <listitem><para>
+ The number of attributes recognized by the adaptor and a pointer to
+ the array of <structname>XF86AttributeRecs</structname>. The
+ <structname>XF86AttributeRec</structname> is described later on.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>nImages</structfield>
+ <structfield>pImages</structfield></term>
+ <listitem><para>
+ The number of <structname>XF86ImageRecs</structname> supported by the adaptor
+ and a pointer to the array of <structname>XF86ImageRecs</structname>. The
+ <structname>XF86ImageRec</structname> is described later on.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>
+ PutVideo PutStill GetVideo GetStill StopVideo
+ SetPortAttribute GetPortAttribute QueryBestSize PutImage
+ QueryImageAttributes
+ </structfield></term>
+ <listitem><para>
+ These functions define the DDX->driver interface. In each
+ case, the pointer <parameter>data</parameter> is passed to the driver.
+ This is the port private for that port as described above. All
+ fields are required except under the following conditions:
+
+ <orderedlist>
+ <listitem><para>
+ <structfield>PutVideo</structfield>, <structfield>PutStill</structfield> and
+ the image routines <structfield>PutImage</structfield> and
+ <structfield>QueryImageAttributes</structfield> are not required when the
+ adaptor type does not contain <constant>XvInputMask</constant>.
+ </para></listitem>
+
+ <listitem><para>
+ <structfield>GetVideo</structfield> and <structfield>GetStill</structfield>
+ are not required when the adaptor type does not contain
+ <constant>XvOutputMask</constant>.
+ </para></listitem>
+
+ <listitem><para>
+ <structfield>GetVideo</structfield> and <structfield>PutVideo</structfield>
+ are not required when the adaptor type does not contain
+ <constant>XvVideoMask</constant>.
+ </para></listitem>
+
+ <listitem><para>
+ <structfield>GetStill</structfield> and <structfield>PutStill</structfield>
+ are not required when the adaptor type does not contain
+ <constant>XvStillMask</constant>.
+ </para></listitem>
+
+ <listitem><para>
+ <structfield>PutImage</structfield> and <structfield>QueryImageAttributes</structfield>
+ are not required when the adaptor type does not contain
+ <constant>XvImageMask</constant>.
+ </para></listitem>
+
+ </orderedlist>
+
+ </para>
+
+ <para>
+ With the exception of <structfield>QueryImageAttributes</structfield>, these
+ functions should return <constant>Success</constant> if the operation was
+ completed successfully. They can return <constant>XvBadAlloc</constant>
+ otherwise. <structfield>QueryImageAttributes</structfield> returns the size
+ of the XvImage queried.
+ </para>
+
+ <para>
+ If the <constant>VIDEO_NO_CLIPPING</constant>
+ flag is set, the <literal remap="tt">clipBoxes</literal> may be ignored by
+ the driver. <literal remap="tt">ClipBoxes</literal> is an <literal remap="tt">X-Y</literal>
+ banded region identical to those used throughout the server.
+ The clipBoxes represent the visible portions of the area determined
+ by <literal remap="tt">drw_x</literal>, <literal remap="tt">drw_y</literal>,
+ <literal remap="tt">drw_w</literal> and <literal remap="tt">drw_h</literal> in the Get/Put
+ function. The boxes are in screen coordinates, are guaranteed
+ not to overlap and an empty region will never be passed.
+ If the driver has specified <constant>VIDEO_INVERT_CLIPLIST</constant>,
+ <literal remap="tt">clipBoxes</literal> will indicate the areas of the primitive
+ which are obscured rather than the areas visible.
+
+ </para></listitem></varlistentry>
+ </variablelist>
+
+ <blockquote><para>
+ <programlisting>
+ typedef int (* PutVideoFuncPtr)( ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data );
+ </programlisting>
+ <blockquote><para>
+ This indicates that the driver should take a subsection
+ <parameter>vid_w</parameter> by <parameter>vid_h</parameter> at location
+ <parameter>(vid_x,vid_y)</parameter> from the video stream and direct
+ it into the rectangle <parameter>drw_w</parameter> by <parameter>drw_h</parameter>
+ at location <parameter>(drw_x,drw_y)</parameter> on the screen, scaling as
+ necessary. Due to the large variations in capabilities of
+ the various hardware expected to be used with this extension,
+ it is not expected that all hardware will be able to do this
+ exactly as described. In that case the driver should just do
+ <quote>the best it can,</quote> scaling as closely to the target rectangle
+ as it can without rendering outside of it. In the worst case,
+ the driver can opt to just not turn on the video.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ typedef int (* PutStillFuncPtr)( ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data );
+ </programlisting>
+ <blockquote><para>
+ This is same as <structfield>PutVideo</structfield> except that the driver
+ should place only one frame from the stream on the screen.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ typedef int (* GetVideoFuncPtr)( ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data );
+ </programlisting>
+ <blockquote><para>
+ This is same as <structfield>PutVideo</structfield> except that the driver
+ gets video from the screen and outputs it. The driver should
+ do the best it can to get the requested dimensions correct
+ without reading from an area larger than requested.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ typedef int (* GetStillFuncPtr)( ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data );
+ </programlisting>
+ <blockquote><para>
+ This is the same as <literal remap="tt">GetVideo</literal> except that the
+ driver should place only one frame from the screen into the
+ output stream.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ typedef void (* StopVideoFuncPtr)(ScrnInfoPtr pScrn,
+ pointer data, Bool cleanup);
+ </programlisting>
+ <blockquote><para>
+ This indicates the driver should stop displaying the video.
+ This is used to stop both input and output video. The
+ <parameter>cleanup</parameter> field indicates that the video is
+ being stopped because the client requested it to stop or
+ because the server is exiting the current VT. In that case
+ the driver should deallocate any offscreen memory areas (if
+ there are any) being used to put the video to the screen. If
+ <parameter>cleanup</parameter> is not set, the video is being stopped
+ temporarily due to clipping or moving of the window, etc...
+ and video will likely be restarted soon so the driver should
+ not deallocate any offscreen areas associated with that port.
+ </para>
+
+ </blockquote></para></blockquote>
+ <blockquote><para>
+ <programlisting>
+ typedef int (* SetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
+ Atom attribute,INT32 value, pointer data);
+ </programlisting>
+
+ <programlisting>
+ typedef int (* GetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
+ Atom attribute,INT32 *value, pointer data);
+ </programlisting>
+ <blockquote><para>
+ A port may have particular attributes such as hue,
+ saturation, brightness or contrast. Xv clients set and
+ get these attribute values by sending attribute strings
+ (Atoms) to the server. Such requests end up at these
+ driver functions. It is recommended that the driver provide
+ at least the following attributes mentioned in the Xv client
+ library docs:
+ <literallayout><constant>
+ XV_ENCODING
+ XV_HUE
+ XV_SATURATION
+ XV_BRIGHTNESS
+ XV_CONTRAST
+ </constant></literallayout>
+ but the driver may recognize as many atoms as it wishes. If
+ a requested attribute is unknown by the driver it should return
+ <constant>BadMatch</constant>. <constant>XV_ENCODING</constant> is the
+ attribute intended to let the client specify which video
+ encoding the particular port should be using (see the description
+ of <structname>XF86VideoEncodingRec</structname> below). If the
+ requested encoding is unsupported, the driver should return
+ <constant>XvBadEncoding</constant>. If the value lies outside the
+ advertised range <constant>BadValue</constant> may be returned.
+ <constant>Success</constant> should be returned otherwise.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ typedef void (* QueryBestSizeFuncPtr)(ScrnInfoPtr pScrn,
+ Bool motion, short vid_w, short vid_h,
+ short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h, pointer data);
+ </programlisting>
+ <blockquote><para>
+ <function>QueryBestSize</function> provides the client with a way
+ to query what the destination dimensions would end up being
+ if they were to request that an area
+ <parameter>vid_w</parameter> by <parameter>vid_h</parameter> from the video
+ stream be scaled to rectangle of
+ <parameter>drw_w</parameter> by <parameter>drw_h</parameter> on the screen.
+ Since it is not expected that all hardware will be able to
+ get the target dimensions exactly, it is important that the
+ driver provide this function.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ typedef int (* PutImageFuncPtr)( ScrnInfoPtr pScrn,
+ short src_x, short src_y, short drw_x, short drw_y,
+ short src_w, short src_h, short drw_w, short drw_h,
+ int image, char *buf, short width, short height,
+ Bool sync, RegionPtr clipBoxes, pointer data );
+ </programlisting>
+ <blockquote><para>
+ This is similar to <structfield>PutStill</structfield> except that the
+ source of the video is not a port but the data stored in a system
+ memory buffer at <parameter>buf</parameter>. The data is in the format
+ indicated by the <parameter>image</parameter> descriptor and represents a
+ source of size <parameter>width</parameter> by <parameter>height</parameter>.
+ If <parameter>sync</parameter> is TRUE the driver should not return
+ from this function until it is through reading the data
+ from <parameter>buf</parameter>. Returning when <parameter>sync</parameter>
+ is TRUE indicates that it is safe for the data at <parameter>buf</parameter>
+ to be replaced, freed, or modified.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ typedef int (* QueryImageAttributesFuncPtr)( ScrnInfoPtr pScrn,
+ int image, short *width, short *height,
+ int *pitches, int *offsets);
+ </programlisting>
+ <blockquote><para>
+ This function is called to let the driver specify how data for
+ a particular <parameter>image</parameter> of size <parameter>width</parameter>
+ by <parameter>height</parameter> should be stored. Sometimes only
+ the size and corrected width and height are needed. In that
+ case <parameter>pitches</parameter> and <parameter>offsets</parameter> are
+ NULL. The size of the memory required for the image is returned
+ by this function. The <parameter>width</parameter> and
+ <parameter>height</parameter> of the requested image can be altered by
+ the driver to reflect format limitations (such as component
+ sampling periods that are larger than one). If
+ <parameter>pitches</parameter> and <parameter>offsets</parameter> are not NULL,
+ these will be arrays with as many elements in them as there
+ are planes in the <parameter>image</parameter> format. The driver
+ should specify the pitch (in bytes) of each scanline in the
+ particular plane as well as the offset to that plane (in bytes)
+ from the beginning of the image.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ <para>
+The XF86VideoEncodingRec:
+
+ <blockquote><para>
+ <programlisting>
+typedef struct {
+ int id;
+ char *name;
+ unsigned short width, height;
+ XvRationalRec rate;
+} XF86VideoEncodingRec, *XF86VideoEncodingPtr;
+
+ </programlisting>
+ <blockquote><para>
+ The <structname>XF86VideoEncodingRec</structname> specifies what encodings
+ the adaptor can support. Most of this data is just informational
+ and for the client's benefit, and is what will be reported by
+ <function>XvQueryEncodings</function>. The <parameter>id</parameter> field is
+ expected to be a unique identifier to allow the client to request a
+ certain encoding via the <constant>XV_ENCODING</constant> attribute string.
+
+ </para>
+ </blockquote></para></blockquote>
+ </para>
+
+ <para>
+The XF86VideoFormatRec:
+
+ <blockquote><para>
+ <programlisting>
+typedef struct {
+ char depth;
+ short class;
+} XF86VideoFormatRec, *XF86VideoFormatPtr;
+
+ </programlisting>
+ <blockquote><para>
+ This specifies what visuals the video is viewable in.
+ <parameter>depth</parameter> is the depth of the visual (not bpp).
+ <parameter>class</parameter> is the visual class such as
+ <constant>TrueColor</constant>, <constant>DirectColor</constant> or
+ <constant>PseudoColor</constant>. Initialization of an adaptor will fail
+ if none of the visuals on that screen are supported.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+
+ <para>
+The XF86AttributeRec:
+
+ <blockquote><para>
+ <programlisting>
+typedef struct {
+ int flags;
+ int min_value;
+ int max_value;
+ char *name;
+} XF86AttributeListRec, *XF86AttributeListPtr;
+
+ </programlisting>
+ <blockquote><para>
+ Each adaptor may have an array of these advertising the attributes
+ for its ports. Currently defined flags are <literal remap="tt">XvGettable</literal>
+ and <literal remap="tt">XvSettable</literal> which may be OR'd together indicating that
+ attribute is <quote>gettable</quote> or <quote>settable</quote> by the client. The
+ <literal remap="tt">min</literal> and <literal remap="tt">max</literal> field specify the valid range
+ for the value. <literal remap="tt">Name</literal> is a text string describing the
+ attribute by name.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ </para>
+
+ <para>
+The XF86ImageRec:
+
+ <blockquote><para>
+ <programlisting>
+typedef struct {
+ int id;
+ int type;
+ int byte_order;
+ char guid[16];
+ int bits_per_pixel;
+ int format;
+ int num_planes;
+
+ /* for RGB formats */
+ int depth;
+ unsigned int red_mask;
+ unsigned int green_mask;
+ unsigned int blue_mask;
+
+ /* for YUV formats */
+ unsigned int y_sample_bits;
+ unsigned int u_sample_bits;
+ unsigned int v_sample_bits;
+ unsigned int horz_y_period;
+ unsigned int horz_u_period;
+ unsigned int horz_v_period;
+ unsigned int vert_y_period;
+ unsigned int vert_u_period;
+ unsigned int vert_v_period;
+ char component_order[32];
+ int scanline_order;
+} XF86ImageRec, *XF86ImagePtr;
+
+ </programlisting>
+ <blockquote><para>
+ XF86ImageRec describes how video source data is laid out in memory.
+ The fields are as follows:
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>id</structfield></term>
+ <listitem><para>
+ This is a unique descriptor for the format. It is often good to
+ set this value to the FOURCC for the format when applicable.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>type</structfield></term>
+ <listitem><para>
+ This is <constant>XvRGB</constant> or <constant>XvYUV</constant>.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>byte_order</structfield></term>
+ <listitem><para>
+ This is <constant>LSBFirst</constant> or <constant>MSBFirst</constant>.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>guid</structfield></term>
+ <listitem><para>
+ This is the Globally Unique IDentifier for the format. When
+ not applicable, all characters should be NULL.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>bits_per_pixel</structfield></term>
+ <listitem><para>
+ The number of bits taken up (but not necessarily used) by each
+ pixel. Note that for some planar formats which have fractional
+ bits per pixel (such as IF09) this number may be rounded _down_.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>format</structfield></term>
+ <listitem><para>
+ This is <constant>XvPlanar</constant> or <constant>XvPacked</constant>.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>num_planes</structfield></term>
+ <listitem><para>
+ The number of planes in planar formats. This should be set to
+ one for packed formats.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>depth</structfield></term>
+ <listitem><para>
+ The significant bits per pixel in RGB formats (analgous to the
+ depth of a pixmap format).
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>red_mask</structfield></term>
+ <term><structfield>green_mask</structfield></term>
+ <term><structfield>blue_mask</structfield></term>
+ <listitem><para>
+ The red, green and blue bitmasks for packed RGB formats.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>y_sample_bits</structfield></term>
+ <term><structfield>u_sample_bits</structfield></term>
+ <term><structfield>v_sample_bits</structfield></term>
+ <listitem><para>
+ The y, u and v sample sizes (in bits).
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>horz_y_period</structfield></term>
+ <term><structfield>horz_u_period</structfield></term>
+ <term><structfield>horz_v_period</structfield></term>
+ <listitem><para>
+ The y, u and v sampling periods in the horizontal direction.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>vert_y_period</structfield></term>
+ <term><structfield>vert_u_period</structfield></term>
+ <term><structfield>vert_v_period</structfield></term>
+ <listitem><para>
+ The y, u and v sampling periods in the vertical direction.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>component_order</structfield></term>
+ <listitem><para>
+ Uppercase ascii characters representing the order that
+ samples are stored within packed formats. For planar formats
+ this represents the ordering of the planes. Unused characters
+ in the 32 byte string should be set to NULL.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>scanline_order</structfield></term>
+ <listitem><para>
+ This is <constant>XvTopToBottom</constant> or <constant>XvBottomToTop</constant>.
+ </para></listitem></varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ Since some formats (particular some planar YUV formats) may not
+be completely defined by the parameters above, the guid, when
+available, should provide the most accurate description of the
+format.
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+ </sect1>
+
+ <sect1>
+ <title>The Loader</title>
+
+ <para>
+This section describes the interfaces to the module loader. The loader
+interfaces can be divided into two groups: those that are only available to
+the XFree86 common layer, and those that are also available to modules.
+ </para>
+
+ <sect2>
+ <title>Loader Overview</title>
+
+ <para>
+The loader is capable of loading modules in a range of object formats,
+and knowledge of these formats is built in to the loader. Knowledge of
+new object formats can be added to the loader in a straightforward
+manner. This makes it possible to provide OS-independent modules (for
+a given CPU architecture type). In addition to this, the loader can
+load modules via the OS-provided <function>dlopen(3)</function> service where
+available. Such modules are not platform independent, and the semantics
+of <function>dlopen()</function> on most systems results in significant
+limitations in the use of modules of this type. Support for
+<function>dlopen()</function> modules in the loader is primarily for
+experimental and development purposes.
+ </para>
+
+ <para>
+Symbols exported by the loader (on behalf of the core X server) to
+modules are determined at compile time. Only those symbols explicitly
+exported are available to modules. All external symbols of loaded
+modules are exported to other modules, and to the core X server. The
+loader can be requested to check for unresolved symbols at any time,
+and the action to be taken for unresolved symbols can be controlled by
+the caller of the loader. Typically the caller identifies which symbols
+can safely remain unresolved and which cannot.
+ </para>
+
+ <para>
+NOTE: Now that ISO-C allows pointers to functions and pointers to data to
+have different internal representations, some of the following interfaces
+will need to be revisited.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Semi-private Loader Interface</title>
+
+ <para>
+The following is the semi-private loader interface that is available to the
+XFree86 common layer.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ void LoaderInit(void);
+ </programlisting>
+ <blockquote><para>
+ The <function>LoaderInit()</function> function initialises the loader,
+ and it must be called once before calling any other loader functions.
+ This function initialises the tables of exported symbols, and anything
+ else that might need to be initialised.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void LoaderSetPath(const char *path);
+ </programlisting>
+ <blockquote><para>
+ The <function>LoaderSetPath()</function> function initialises a default
+ module search path. This must be called if calls to other functions
+ are to be made without explicitly specifying a module search path.
+ The search path <parameter>path</parameter> must be a string of one or more
+ comma separated absolute paths. Modules are expected to be located
+ below these paths, possibly in subdirectories of these paths.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ pointer LoadModule(const char *module, const char *path,
+ const char **subdirlist, const char **patternlist,
+ pointer options, const XF86ModReqInfo * modreq,
+ int *errmaj, int *errmin);
+ </programlisting>
+ <blockquote><para>
+ The <function>LoadModule()</function> function loads the module called
+ <parameter>module</parameter>. The return value is a module handle, and
+ may be used in future calls to the loader that require a reference
+ to a loaded module. The module name <parameter>module</parameter> is
+ normally the module's canonical name, which doesn't contain any
+ directory path information, or any object/library file prefixes of
+ suffixes. Currently a full pathname and/or filename is also accepted.
+ This might change. The other parameters are:
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>path</parameter></term>
+ <listitem><para>
+ An optional comma-separated list of module search paths.
+ When <constant>NULL</constant>, the default search path is used.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><parameter>subdirlist</parameter></term>
+ <listitem><para>
+ An optional <constant>NULL</constant> terminated list of
+ subdirectories to search. When <constant>NULL</constant>,
+ the default built-in list is used (refer to
+ <varname>stdSubdirs</varname> in <filename>loadmod.c</filename>).
+ The default list is also substituted for entries in
+ <parameter>subdirlist</parameter> with the value
+ <constant>DEFAULT_LIST</constant>. This makes is possible
+ to augment the default list instead of replacing it.
+ Subdir elements must be relative, and must not contain
+ <literal remap="tt">".."</literal>. If any violate this requirement,
+ the load fails.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><parameter>patternlist</parameter></term>
+ <listitem><para>
+ An optional <constant>NULL</constant> terminated list of
+ POSIX regular expressions used to connect module
+ filenames with canonical module names. Each regex
+ should contain exactly one subexpression that corresponds
+ to the canonical module name. When <constant>NULL</constant>,
+ the default built-in list is used (refer to
+ <varname>stdPatterns</varname> in
+ <filename>loadmod.c</filename>). The default list is also
+ substituted for entries in <parameter>patternlist</parameter>
+ with the value <constant>DEFAULT_LIST</constant>. This
+ makes it possible to augment the default list instead
+ of replacing it.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><parameter>options</parameter></term>
+ <listitem><para>
+ An optional parameter that is passed to the newly
+ loaded module's <literal remap="tt">SetupProc</literal> function
+ (if it has one). This argument is normally a
+ <constant>NULL</constant> terminated list of
+ <structname>Options</structname>, and must be interpreted that
+ way by modules loaded directly by the XFree86 common
+ layer. However, it may be used for application-specific
+ parameter passing in other situations.
+ </para>
+
+ <para>
+ When loading <quote>external</quote> modules (modules that don't
+ have the standard entry point, for example a
+ special shared library) the options parameter can be
+ set to <constant>EXTERN_MODULE</constant> to tell the
+ loader not to reject the module when it doesn't find
+ the standard entry point.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><parameter>modreq</parameter></term>
+ <listitem><para>
+ An optional <structname>XF86ModReqInfo*</structname> containing
+ version/ABI/vendor information to requirements to
+ check the newly loaded module against. The main
+ purpose of this is to allow the loader to verify that
+ a module of the correct type/version before running
+ its <function>SetupProc</function> function.
+ </para>
+
+ <para>
+ The <literal remap="tt">XF86ModReqInfo</literal> struct is defined
+ as follows:
+ <programlisting>
+typedef struct {
+ CARD8 majorversion; /* MAJOR_UNSPEC */
+ CARD8 minorversion; /* MINOR_UNSPEC */
+ CARD16 patchlevel; /* PATCH_UNSPEC */
+ const char * abiclass; /* ABI_CLASS_NONE */
+ CARD32 abiversion; /* ABI_VERS_UNSPEC */
+ const char * moduleclass; /* MOD_CLASS_NONE */
+} XF86ModReqInfo;
+ </programlisting>
+
+ The information here is compared against the equivalent
+ information in the module's
+ <structname>XF86ModuleVersionInfo</structname> record (which
+ is described below). The values in comments above
+ indicate <quote>don't care</quote> settings for each of the fields.
+ The comparisons made are as follows:
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>majorversion</structfield></term>
+ <listitem><para>
+ Must match the module's majorversion
+ exactly.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>minorversion</structfield></term>
+ <listitem><para>
+ The module's minor version must be
+ no less than this value. This
+ comparison is only made if
+ <structfield>majorversion</structfield> is
+ specified and matches.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>patchlevel</structfield></term>
+ <listitem><para>
+ The module's patchlevel must be no
+ less than this value. This comparison
+ is only made if
+ <structfield>minorversion</structfield> is
+ specified and matches.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>abiclass</structfield></term>
+ <listitem><para>
+ String must match the module's abiclass
+ string.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>abiversion</structfield></term>
+ <listitem><para>
+ Must be consistent with the module's
+ abiversion (major equal, minor no
+ older).
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>moduleclass</structfield></term>
+ <listitem><para>
+ String must match the module's
+ moduleclass string.
+ </para></listitem></varlistentry>
+
+ </variablelist>
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>errmaj</parameter></term>
+ <listitem><para>
+ An optional pointer to a variable holding the major
+ part or the error code. When provided,
+ <parameter>*errmaj</parameter> is filled in when
+ <function>LoadModule()</function> fails.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>errmin</parameter></term>
+ <listitem><para>
+ Like <parameter>errmaj</parameter>, but for the minor part
+ of the error code.
+ </para></listitem></varlistentry>
+
+ </variablelist>
+
+ </para></blockquote>
+ </para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void UnloadModule(pointer mod);
+ </programlisting>
+ <blockquote><para>
+ This function unloads the module referred to by the handle mod.
+ All child modules are also unloaded recursively. This function must
+ not be used to directly unload modules that are child modules (i.e.,
+ those that have been loaded with the <function>LoadSubModule()</function>
+ described below).
+ </para>
+
+ </blockquote></para></blockquote>
+ </sect2>
+
+ <sect2>
+ <title>Module Requirements</title>
+
+ <para>
+Modules must provide information about themselves to the loader, and
+may optionally provide entry points for "setup" and "teardown" functions
+(those two functions are referred to here as <function>SetupProc</function>
+and <function>TearDownProc</function>).
+ </para>
+
+ <para>
+The module information is contained in the
+<structname>XF86ModuleVersionInfo</structname> struct, which is defined as follows:
+
+ <programlisting>
+typedef struct {
+ const char * modname; /* name of module, e.g. "foo" */
+ const char * vendor; /* vendor specific string */
+ CARD32 _modinfo1_; /* constant MODINFOSTRING1/2 to find */
+ CARD32 _modinfo2_; /* infoarea with a binary editor/sign tool */
+ CARD32 xf86version; /* contains XF86_VERSION_CURRENT */
+ CARD8 majorversion; /* module-specific major version */
+ CARD8 minorversion; /* module-specific minor version */
+ CARD16 patchlevel; /* module-specific patch level */
+ const char * abiclass; /* ABI class that the module uses */
+ CARD32 abiversion; /* ABI version */
+ const char * moduleclass; /* module class */
+ CARD32 checksum[4]; /* contains a digital signature of the */
+ /* version info structure */
+} XF86ModuleVersionInfo;
+ </programlisting>
+
+The fields are used as follows:
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>modname</structfield></term>
+ <listitem><para>
+ The module's name. This field is currently only for
+ informational purposes, but the loader may be modified
+ in future to require it to match the module's canonical
+ name.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>vendor</structfield></term>
+ <listitem><para>
+ The module vendor. This field is for informational purposes
+ only.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>_modinfo1_</structfield></term>
+ <listitem><para>
+ This field holds the first part of a signature that can
+ be used to locate this structure in the binary. It should
+ always be initialised to <constant>MODINFOSTRING1</constant>.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>_modinfo2_</structfield></term>
+ <listitem><para>
+ This field holds the second part of a signature that can
+ be used to locate this structure in the binary. It should
+ always be initialised to <constant>MODINFOSTRING2</constant>.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>xf86version</structfield></term>
+ <listitem><para>
+ The XFree86 version against which the module was compiled.
+ This is mostly for informational/diagnostic purposes. It
+ should be initialised to <constant>XF86_VERSION_CURRENT</constant>, which is
+ defined in <filename>xf86Version.h</filename>.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>majorversion</structfield></term>
+ <listitem><para>
+ The module-specific major version. For modules where this
+ version is used for more than simply informational
+ purposes, the major version should only change (be
+ incremented) when ABI incompatibilities are introduced,
+ or ABI components are removed.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>minorversion</structfield></term>
+ <listitem><para>
+ The module-specific minor version. For modules where this
+ version is used for more than simply informational
+ purposes, the minor version should only change (be
+ incremented) when ABI additions are made in a backward
+ compatible way. It should be reset to zero when the major
+ version is increased.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>patchlevel</structfield></term>
+ <listitem><para>
+ The module-specific patch level. The patch level should
+ increase with new revisions of the module where there
+ are no ABI changes, and it should be reset to zero when
+ the minor version is increased.
+ </para></listitem></varlistentry>
+
+
+ <varlistentry>
+ <term><structfield>abiclass</structfield></term>
+ <listitem><para>
+ The ABI class that the module requires. The class is
+ specified as a string for easy extensibility. It should
+ indicate which (if any) of the X server's built-in ABI
+ classes that the module relies on, or a third-party ABI
+ if appropriate. Built-in ABI classes currently defined are:
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>ABI_CLASS_NONE</constant></term>
+ <listitem><para>no class
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>ABI_CLASS_ANSIC</constant></term>
+ <listitem><para>only requires the ANSI C interfaces
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>ABI_CLASS_VIDEODRV</constant></term>
+ <listitem><para>requires the video driver ABI
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>ABI_CLASS_XINPUT</constant></term>
+ <listitem><para>requires the XInput driver ABI
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>ABI_CLASS_EXTENSION</constant></term>
+ <listitem><para>requires the extension module ABI
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>ABI_CLASS_FONT</constant></term>
+ <listitem><para>requires the font module ABI
+ </para></listitem></varlistentry>
+ </variablelist>
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>abiversion</structfield></term>
+ <listitem><para>
+ The version of abiclass that the module requires. The
+ version consists of major and minor components. The
+ major version must match and the minor version must be
+ no newer than that provided by the server or parent
+ module. Version identifiers for the built-in classes
+ currently defined are:
+
+ <literallayout><constant>
+ ABI_ANSIC_VERSION
+ ABI_VIDEODRV_VERSION
+ ABI_XINPUT_VERSION
+ ABI_EXTENSION_VERSION
+ ABI_FONT_VERSION
+ </constant></literallayout>
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>moduleclass</structfield></term>
+ <listitem><para>
+ This is similar to the abiclass field, except that it
+ defines the type of module rather than the ABI it
+ requires. For example, although all video drivers require
+ the video driver ABI, not all modules that require the
+ video driver ABI are video drivers. This distinction
+ can be made with the moduleclass. Currently pre-defined
+ module classes are:
+
+ <literallayout><constant>
+ MOD_CLASS_NONE
+ MOD_CLASS_VIDEODRV
+ MOD_CLASS_XINPUT
+ MOD_CLASS_FONT
+ MOD_CLASS_EXTENSION
+ </constant></literallayout>
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>checksum</structfield></term>
+ <listitem><para>
+ Not currently used.
+ </para></listitem></varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+The module version information, and the optional <function>SetupProc</function>
+and <function>TearDownProc</function> entry points are found by the loader
+by locating a data object in the module called "modnameModuleData",
+where "modname" is the canonical name of the module. Modules must
+contain such a data object, and it must be declared with global scope,
+be compile-time initialised, and is of the following type:
+
+ <programlisting>
+typedef struct {
+ XF86ModuleVersionInfo * vers;
+ ModuleSetupProc setup;
+ ModuleTearDownProc teardown;
+} XF86ModuleData;
+ </programlisting>
+ </para>
+
+ <para>
+The vers parameter must be initialised to a pointer to a correctly
+initialised <structname>XF86ModuleVersionInfo</structname> struct. The other
+two parameter are optional, and should be initialised to
+<constant>NULL</constant> when not required. The other parameters are defined
+as
+
+ <blockquote><para>
+ <programlisting>
+ typedef pointer (*ModuleSetupProc)(pointer, pointer, int *, int *);
+
+ typedef void (*ModuleTearDownProc)(pointer);
+
+ pointer SetupProc(pointer module, pointer options,
+ int *errmaj, int *errmin);
+ </programlisting>
+ <blockquote><para>
+ When defined, this function is called by the loader after successfully
+ loading a module. module is a handle for the newly loaded module,
+ and maybe used by the <function>SetupProc</function> if it calls other
+ loader functions that require a reference to it. The remaining
+ arguments are those that were passed to the
+ <function>LoadModule()</function> (or <function>LoadSubModule()</function>),
+ and are described above. When the <function>SetupProc</function> is
+ successful it must return a non-<constant>NULL</constant> value. The
+ loader checks this, and if it is <constant>NULL</constant> it unloads
+ the module and reports the failure to the caller of
+ <function>LoadModule()</function>. If the <function>SetupProc</function>
+ does things that need to be undone when the module is unloaded,
+ it should define a <function>TearDownProc</function>, and return a
+ pointer that the <function>TearDownProc</function> can use to undo what
+ has been done.
+ </para>
+
+ <para>
+ When a module is loaded multiple times, the <function>SetupProc</function>
+ is called once for each time it is loaded.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void TearDownProc(pointer tearDownData);
+ </programlisting>
+ <blockquote><para>
+ When defined, this function is called when the loader unloads a
+ module. The <parameter>tearDownData</parameter> parameter is the return
+ value of the <function>SetupProc()</function> that was called when the
+ module was loaded. The purpose of this function is to clean up
+ before the module is unloaded (for example, by freeing allocated
+ resources).
+ </para>
+
+ </blockquote></para></blockquote>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Public Loader Interface</title>
+
+ <para>
+The following is the Loader interface that is available to any part of
+the server, and may also be used from within modules.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ pointer LoadSubModule(pointer parent, const char *module,
+ const char **subdirlist, const char **patternlist,
+ pointer options, const XF86ModReqInfo * modreq,
+ int *errmaj, int *errmin);
+ </programlisting>
+ <blockquote><para>
+ This function is like the <function>LoadModule()</function> function
+ described above, except that the module loaded is registered as a
+ child of the calling module. The <parameter>parent</parameter> parameter
+ is the calling module's handle. Modules loaded with this function
+ are automatically unloaded when the parent module is unloaded. The
+ other difference is that the path parameter may not be specified.
+ The module search path used for modules loaded with this function
+ is the default search path as initialised with
+ <function>LoaderSetPath()</function>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void UnloadSubModule(pointer module);
+ </programlisting>
+ <blockquote><para>
+ This function unloads the module with handle <parameter>module</parameter>.
+ If that module itself has children, they are also unloaded. It is
+ like <function>UnloadModule()</function>, except that it is safe to use
+ for unloading child modules.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ pointer LoaderSymbol(const char *symbol);
+ </programlisting>
+ <blockquote><para>
+ This function returns the address of the symbol with name
+ <parameter>symbol</parameter>. This may be used to locate a module entry
+ point with a known name.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ char **LoaderlistDirs(const char **subdirlist,
+ const char **patternlist);
+ </programlisting>
+ <blockquote><para>
+ This function returns a <constant>NULL</constant> terminated list of
+ canonical modules names for modules found in the default module
+ search path. The <parameter>subdirlist</parameter> and
+ <parameter>patternlist</parameter> parameters are as described above, and
+ can be used to control the locations and names that are searched.
+ If no modules are found, the return value is <constant>NULL</constant>.
+ The returned list should be freed by calling
+ <function>LoaderFreeDirList()</function> when it is no longer needed.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void LoaderFreeDirList(char **list);
+ </programlisting>
+ <blockquote><para>
+ This function frees a module list created by
+ <function>LoaderlistDirs()</function>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void LoaderReqSymLists(const char **list0, ...);
+ </programlisting>
+ <blockquote><para>
+ This function allows the registration of required symbols with the
+ loader. It is normally used by a caller of
+ <function>LoadSubModule()</function>. If any symbols registered in this
+ way are found to be unresolved when
+ <function>LoaderCheckUnresolved()</function> is called then
+ <function>LoaderCheckUnresolved()</function> will report a failure.
+ The function takes one or more <constant>NULL</constant> terminated
+ lists of symbols. The end of the argument list is indicated by a
+ <constant>NULL</constant> argument.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void LoaderReqSymbols(const char *sym0, ...);
+ </programlisting>
+ <blockquote><para>
+ This function is like <function>LoaderReqSymLists()</function> except
+ that its arguments are symbols rather than lists of symbols. This
+ function is more convenient when single functions are to be registered,
+ especially when the single function might depend on runtime factors.
+ The end of the argument list is indicated by a <constant>NULL</constant>
+ argument.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void LoaderRefSymLists(const char **list0, ...);
+ </programlisting>
+ <blockquote><para>
+ This function allows the registration of possibly unresolved symbols
+ with the loader. When <function>LoaderCheckUnresolved()</function> is
+ run it won't generate warnings for symbols registered in this way
+ unless they were also registered as required symbols.
+ The function takes one or more <constant>NULL</constant> terminated
+ lists of symbols. The end of the argument list is indicated by a
+ <constant>NULL</constant> argument.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void LoaderRefSymbols(const char *sym0, ...);
+ </programlisting>
+ <blockquote><para>
+ This function is like <function>LoaderRefSymLists()</function> except
+ that its arguments are symbols rather than lists of symbols. This
+ function is more convenient when single functions are to be registered,
+ especially when the single function might depend on runtime factors.
+ The end of the argument list is indicated by a <constant>NULL</constant>
+ argument.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ int LoaderCheckUnresolved(int delayflag);
+ </programlisting>
+ <blockquote><para>
+ This function checks for unresolved symbols. It generates warnings
+ for unresolved symbols that have not been registered with
+ <function>LoaderRefSymLists()</function>, and maps them to a dummy
+ function. This behaviour may change in future. If unresolved
+ symbols are found that have been registered with
+ <function>LoaderReqSymLists()</function> or
+ <function>LoaderReqSymbols()</function> then this function returns a
+ non-zero value. If none of these symbols are unresolved the return
+ value is zero, indicating success.
+ </para>
+
+ <para>
+ The <parameter>delayflag</parameter> parameter should normally be set to
+ <constant>LD_RESOLV_IFDONE</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ LoaderErrorMsg(const char *name, const char *modname,
+ int errmaj, int errmin);
+ </programlisting>
+ <blockquote><para>
+ This function prints an error message that includes the text <quote>Failed
+ to load module</quote>, the module name <parameter>modname</parameter>, a message
+ specific to the <parameter>errmaj</parameter> value, and the value if
+ <parameter>errmin</parameter>. If <parameter>name</parameter> is
+ non-<constant>NULL</constant>, it is printed as an identifying prefix
+ to the message (followed by a <quote>:</quote>).
+ </para>
+
+ </blockquote></para></blockquote>
+ </sect2>
+
+ <sect2>
+ <title>Special Registration Functions</title>
+
+ <para>
+The loader contains some functions for registering some classes of modules.
+These may be moved out of the loader at some point.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ void LoadExtension(ExtensionModule *ext);
+ </programlisting>
+ <blockquote><para>
+ This registers the entry points for the extension identified by
+ <parameter>ext</parameter>. The <structname>ExtensionModule</structname> struct is
+ defined as:
+
+ <programlisting>
+typedef struct {
+ InitExtension initFunc;
+ char * name;
+ Bool *disablePtr;
+ InitExtension setupFunc;
+} ExtensionModule;
+ </programlisting>
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void LoadFont(FontModule *font);
+ </programlisting>
+ <blockquote><para>
+ This registers the entry points for the font rasteriser module
+ identified by <parameter>font</parameter>. The <structname>FontModule</structname>
+ struct is defined as:
+
+ <programlisting>
+ typedef struct {
+ InitFont initFunc;
+ char * name;
+ pointer module;
+} FontModule;
+ </programlisting>
+ </para>
+
+ </blockquote></para></blockquote>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1>
+ <title>Helper Functions</title>
+
+ <para>
+This section describe <quote>helper</quote> functions that video driver
+might find useful. While video drivers are not required to use any of
+these to be considered <quote>compliant</quote>, the use of appropriate helpers is
+strongly encouraged to improve the consistency of driver behaviour.
+ </para>
+
+ <sect2>
+ <title>Functions for printing messages</title>
+
+ <blockquote><para>
+ <programlisting>
+ ErrorF(const char *format, ...);
+ </programlisting>
+ <blockquote><para>
+ This is the basic function for writing to the error log (typically
+ stderr and/or a log file). Video drivers should usually avoid
+ using this directly in favour of the more specialised functions
+ described below. This function is useful for printing messages
+ while debugging a driver.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ FatalError(const char *format, ...);
+ </programlisting>
+ <blockquote><para>
+ This prints a message and causes the Xserver to abort. It should
+ rarely be used within a video driver, as most error conditions
+ should be flagged by the return values of the driver functions.
+ This allows the higher layers to decide how to proceed. In rare
+ cases, this can be used within a driver if a fatal unexpected
+ condition is found.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ xf86ErrorF(const char *format, ...);
+ </programlisting>
+ <blockquote><para>
+ This is like <function>ErrorF()</function>, except that the message is
+ only printed when the Xserver's verbosity level is set to the
+ default (<constant>1</constant>) or higher. It means that the messages
+ are not printed when the server is started with the
+ <option>-quiet</option> flag. Typically this function would only be
+ used for continuing messages started with one of the more specialised
+ functions described below.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ xf86ErrorFVerb(int verb, const char *format, ...);
+ </programlisting>
+ <blockquote><para>
+ Like <function>xf86ErrorF()</function>, except the minimum verbosity
+ level for which the message is to be printed is given explicitly.
+ Passing a <parameter>verb</parameter> value of zero means the message
+ is always printed. A value higher than <constant>1</constant> can be
+ used for information would normally not be needed, but which might
+ be useful when diagnosing problems.
+ </para>
+
+ </blockquote></para></blockquote>
+
+
+ <blockquote><para>
+ <programlisting>
+ xf86Msg(MessageType type, const char *format, ...);
+ </programlisting>
+ <blockquote><para>
+ This is like <function>xf86ErrorF()</function>, except that the message
+ is prefixed with a marker determined by the value of
+ <parameter>type</parameter>. The marker is used to indicate the type of
+ message (warning, error, probed value, config value, etc). Note
+ the <varname>xf86Verbose</varname> value is ignored for messages of
+ type <constant>X_ERROR</constant>.
+ </para>
+
+ <para>
+ The marker values are:
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>X_PROBED</constant></term>
+ <listitem><para>Value was probed.
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>X_CONFIG</constant></term>
+ <listitem><para>Value was given in the config file.
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>X_DEFAULT</constant></term>
+ <listitem><para>Value is a default.
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>X_CMDLINE</constant></term>
+ <listitem><para>Value was given on the command line.
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>X_NOTICE</constant></term>
+ <listitem><para>Notice.
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>X_ERROR</constant></term>
+ <listitem><para>Error message.
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>X_WARNING</constant></term>
+ <listitem><para>Warning message.
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>X_INFO</constant></term>
+ <listitem><para>Informational message.
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>X_NONE</constant></term>
+ <listitem><para>No prefix.
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>X_NOT_IMPLEMENTED</constant></term>
+ <listitem><para>The message relates to functionality
+ that is not yetimplemented.
+ </para></listitem></varlistentry>
+ </variablelist>
+
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ xf86MsgVerb(MessageType type, int verb, const char *format, ...);
+ </programlisting>
+ <blockquote><para>
+ Like <function>xf86Msg()</function>, but with the verbosity level given
+ explicitly.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...);
+ </programlisting>
+ <blockquote><para>
+ This is like <function>xf86Msg()</function> except that the driver's
+ name (the <structfield>name</structfield> field of the
+ <structname>ScrnInfoRec</structname>) followed by the
+ <parameter>scrnIndex</parameter> in parentheses is printed following the
+ prefix. This should be used by video drivers in most cases as it
+ clearly indicates which driver/screen the message is for. If
+ <parameter>scrnIndex</parameter> is negative, this function behaves
+ exactly like <function>xf86Msg()</function>.
+ </para>
+
+ <para>
+ NOTE: This function can only be used after the
+ <structname>ScrnInfoRec</structname> and its <structfield>name</structfield> field
+ have been allocated. Normally, this means that it can not be
+ used before the END of the <function>ChipProbe()</function> function.
+ Prior to that, use <function>xf86Msg()</function>, providing the
+ driver's name explicitly. No screen number can be supplied at
+ that point.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
+ const char *format, ...);
+ </programlisting>
+ <blockquote><para>
+ Like <function>xf86DrvMsg()</function>, but with the verbosity level
+ given explicitly.
+ </para>
+
+ </blockquote></para></blockquote>
+ </sect2>
+
+
+ <sect2>
+ <title>Functions for setting values based on command line and config file</title>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp,
+
+ int fbbpp, int depth24flags);
+ </programlisting>
+ <blockquote><para>
+ This function sets the <structfield>depth</structfield>, <structfield>pixmapBPP</structfield> and <structfield>bitsPerPixel</structfield> fields
+ of the <structname>ScrnInfoRec</structname>. It also determines the defaults for display-wide
+ attributes and pixmap formats the screen will support, and finds
+ the Display subsection that matches the depth/bpp. This function
+ should normally be called very early from the
+ <function>ChipPreInit()</function> function.
+ </para>
+
+ <para>
+ It requires that the <structfield>confScreen</structfield> field of the <structname>ScrnInfoRec</structname> be
+ initialised prior to calling it. This is done by the XFree86
+ common layer prior to calling <function>ChipPreInit()</function>.
+ </para>
+
+ <para>
+ The parameters passed are:
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>depth</parameter></term>
+ <listitem><para>
+ driver's preferred default depth if no other is given.
+ If zero, use the overall server default.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>bpp</parameter></term>
+ <listitem><para>
+ Same, but for the pixmap bpp.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>fbbpp</parameter></term>
+ <listitem><para>
+ Same, but for the framebuffer bpp.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>depth24flags</parameter></term>
+ <listitem><para>
+ Flags that indicate the level of 24/32bpp support
+ and whether conversion between different framebuffer
+ and pixmap formats is supported. The flags for this
+ argument are defined as follows, and multiple flags
+ may be ORed together:
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>NoDepth24Support</constant></term>
+ <listitem><para>No depth 24 formats supported
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>Support24bppFb</constant></term>
+ <listitem><para>24bpp framebuffer supported
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>Support32bppFb</constant></term>
+ <listitem><para>32bpp framebuffer supported
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>SupportConvert24to32</constant></term>
+ <listitem><para>Can convert 24bpp pixmap to 32bpp fb
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>SupportConvert32to24</constant></term>
+ <listitem><para>Can convert 32bpp pixmap to 24bpp fb
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>ForceConvert24to32</constant></term>
+ <listitem><para>Force 24bpp pixmap to 32bpp fb conversion
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>ForceConvert32to24</constant></term>
+ <listitem><para>Force 32bpp pixmap to 24bpp fb conversion
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para></listitem></varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ It uses the command line, config file, and default values in the
+ correct order of precedence to determine the depth and bpp values.
+ It is up to the driver to check the results to see that it supports
+ them. If not the <function>ChipPreInit()</function> function should
+ return <constant>FALSE</constant>.
+ </para>
+
+ <para>
+ If only one of depth/bpp is given, the other is set to a reasonable
+ (and consistent) default.
+ </para>
+
+ <para>
+ If a driver finds that the initial <parameter>depth24flags</parameter>
+ it uses later results in a fb format that requires more video
+ memory than is available it may call this function a second time
+ with a different <parameter>depth24flags</parameter> setting.
+ </para>
+
+ <para>
+ On success, the return value is <constant>TRUE</constant>. On failure
+ it prints an error message and returns <constant>FALSE</constant>.
+ </para>
+
+ <para>
+ The following fields of the <structname>ScrnInfoRec</structname> are
+ initialised by this function:
+
+ <blockquote><para>
+<structfield>depth</structfield>, <structfield>bitsPerPixel</structfield>,
+<structfield>display</structfield>, <structfield>imageByteOrder</structfield>,
+<structfield>bitmapScanlinePad</structfield>,
+<structfield>bitmapScanlineUnit</structfield>, <structfield>bitmapBitOrder</structfield>,
+<structfield>numFormats</structfield>, <structfield>formats</structfield>,
+<structfield>fbFormat</structfield>.
+ </para></blockquote>
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86PrintDepthBpp(scrnInfoPtr scrp);
+ </programlisting>
+ <blockquote><para>
+ This function can be used to print out the depth and bpp settings.
+ It should be called after the final call to
+ <function>xf86SetDepthBpp()</function>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask);
+ </programlisting>
+ <blockquote><para>
+ This function sets the <structfield>weight</structfield>, <structfield>mask</structfield>,
+ <structfield>offset</structfield> and <structfield>rgbBits</structfield> fields of the
+ <structname>ScrnInfoRec</structname>. It would normally be called fairly
+ early in the <function>ChipPreInit()</function> function for
+ depths > 8bpp.
+ </para>
+
+ <para>
+ It requires that the <structfield>depth</structfield> and
+ <structfield>display</structfield> fields of the <structname>ScrnInfoRec</structname>
+ be initialised prior to calling it.
+ </para>
+
+ <para>
+ The parameters passed are:
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>weight</parameter></term>
+ <listitem><para>
+ driver's preferred default weight if no other is given.
+ If zero, use the overall server default.
+
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>mask</parameter></term>
+ <listitem><para>
+ Same, but for mask.
+
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ It uses the command line, config file, and default values in the
+ correct order of precedence to determine the weight value. It
+ derives the mask and offset values from the weight and the defaults.
+ It is up to the driver to check the results to see that it supports
+ them. If not the <function>ChipPreInit()</function> function should
+ return <constant>FALSE</constant>.
+ </para>
+
+ <para>
+ On success, this function prints a message showing the weight
+ values selected, and returns <constant>TRUE</constant>.
+ </para>
+
+ <para>
+ On failure it prints an error message and returns <constant>FALSE</constant>.
+ </para>
+
+ <para>
+ The following fields of the <structname>ScrnInfoRec</structname> are
+ initialised by this function:
+
+ <blockquote><para>
+ <structfield>weight</structfield>,
+ <structfield>mask</structfield>,
+ <structfield>offset</structfield>.
+ </para></blockquote>
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual);
+ </programlisting>
+ <blockquote><para>
+ This function sets the <structfield>defaultVisual</structfield> field of the
+ <structname>ScrnInfoRec</structname>. It would normally be called fairly
+ early from the <function>ChipPreInit()</function> function.
+ </para>
+
+ <para>
+ It requires that the <structfield>depth</structfield> and
+ <structfield>display</structfield> fields of the <structname>ScrnInfoRec</structname>
+ be initialised prior to calling it.
+ </para>
+
+ <para>
+ The parameters passed are:
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>visual</parameter></term>
+ <listitem><para>
+ driver's preferred default visual if no other is given.
+ If <constant>-1</constant>, use the overall server default.
+ </para></listitem></varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ It uses the command line, config file, and default values in the
+ correct order of precedence to determine the default visual value.
+ It is up to the driver to check the result to see that it supports
+ it. If not the <function>ChipPreInit()</function> function should
+ return <constant>FALSE</constant>.
+ </para>
+
+ <para>
+ On success, this function prints a message showing the default visual
+ selected, and returns <constant>TRUE</constant>.
+ </para>
+
+ <para>
+ On failure it prints an error message and returns <constant>FALSE</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma);
+ </programlisting>
+ <blockquote><para>
+ This function sets the <structfield>gamma</structfield> field of the
+ <structname>ScrnInfoRec</structname>. It would normally be called fairly
+ early from the <function>ChipPreInit()</function> function in cases
+ where the driver supports gamma correction.
+ </para>
+
+ <para>
+ It requires that the <structfield>monitor</structfield> field of the
+ <structname>ScrnInfoRec</structname> be initialised prior to calling it.
+ </para>
+
+ <para>
+ The parameters passed are:
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>gamma</parameter></term>
+ <listitem><para>
+ driver's preferred default gamma if no other is given.
+ If zero (<code>< 0.01</code>), use the overall server
+ default.
+ </para></listitem></varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ It uses the command line, config file, and default values in the
+ correct order of precedence to determine the gamma value. It is
+ up to the driver to check the results to see that it supports
+ them. If not the <function>ChipPreInit()</function> function should
+ return <constant>FALSE</constant>.
+ </para>
+
+ <para>
+ On success, this function prints a message showing the gamma
+ value selected, and returns <constant>TRUE</constant>.
+ </para>
+
+ <para>
+ On failure it prints an error message and returns <constant>FALSE</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+
+ <blockquote><para>
+ <programlisting>
+ void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y);
+ </programlisting>
+ <blockquote><para>
+ This function sets the <structfield>xDpi</structfield> and <structfield>yDpi</structfield>
+ fields of the <structname>ScrnInfoRec</structname>. The driver can specify
+ preferred defaults by setting <parameter>x</parameter> and <parameter>y</parameter>
+ to non-zero values. The <option>-dpi</option> command line option
+ overrides all other settings. Otherwise, if the
+ <emphasis>DisplaySize</emphasis> entry is present in the screen's &k.monitor;
+ config file section, it is used together with the virtual size to
+ calculate the dpi values. This function should be called after
+ all the mode resolution has been done.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86SetBlackWhitePixels(ScrnInfoPtr pScrn);
+ </programlisting>
+ <blockquote><para>
+ This functions sets the <structfield>blackPixel</structfield> and
+ <structfield>whitePixel</structfield> fields of the <structname>ScrnInfoRec</structname>
+ according to whether or not the <option>-flipPixels</option> command
+ line options is present.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ const char *xf86GetVisualName(int visual);
+ </programlisting>
+ <blockquote><para>
+ Returns a printable string with the visual name matching the
+ numerical visual class provided. If the value is outside the
+ range of valid visual classes, <constant>NULL</constant> is returned.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ </sect2>
+
+ <sect2>
+ <title>Primary Mode functions</title>
+
+ <para>
+The primary mode helper functions are those which would normally be
+used by a driver, unless it has unusual requirements which cannot
+be catered for the by the helpers.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
+ char **modeNames, ClockRangePtr clockRanges,
+ int *linePitches, int minPitch, int maxPitch,
+ int pitchInc, int minHeight, int maxHeight,
+ int virtualX, int virtualY,
+ unsigned long apertureSize,
+ LookupModeFlags strategy);
+ </programlisting>
+ <blockquote><para>
+ This function basically selects the set of modes to use based on
+ those available and the various constraints. It also sets some
+ other related parameters. It is normally called near the end of
+ the <function>ChipPreInit()</function> function.
+ </para>
+
+ <para>
+ The parameters passed to the function are:
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>availModes</parameter></term>
+ <listitem><para>
+ List of modes available for the monitor.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>modeNames</parameter></term>
+ <listitem><para>
+ List of mode names that the screen is requesting.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>clockRanges</parameter></term>
+ <listitem><para>
+ A list of clock ranges allowed by the driver. Each
+ range includes whether interlaced or multiscan modes
+ are supported for that range. See below for more on
+ <parameter>clockRanges</parameter>.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>linePitches</parameter></term>
+ <listitem><para>
+ List of line pitches supported by the driver.
+ This is optional and should be <constant>NULL</constant> when
+ not used.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>minPitch</parameter></term>
+ <listitem><para>
+ Minimum line pitch supported by the driver. This must
+ be supplied when <parameter>linePitches</parameter> is
+ <constant>NULL</constant>, and is ignored otherwise.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>maxPitch</parameter></term>
+ <listitem><para>
+ Maximum line pitch supported by the driver. This is
+ required when <parameter>minPitch</parameter> is required.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>pitchInc</parameter></term>
+ <listitem><para>
+ Granularity of horizontal pitch values as supported by
+ the chipset. This is expressed in bits. This must be
+ supplied.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>minHeight</parameter></term>
+ <listitem><para>
+ minimum virtual height allowed. If zero, no limit is
+ imposed.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>maxHeight</parameter></term>
+ <listitem><para>
+ maximum virtual height allowed. If zero, no limit is
+ imposed.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>virtualX</parameter></term>
+ <listitem><para>
+ If greater than zero, this is the virtual width value
+ that will be used. Otherwise, the virtual width is
+ chosen to be the smallest that can accommodate the modes
+ selected.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>virtualY</parameter></term>
+ <listitem><para>
+ If greater than zero, this is the virtual height value
+ that will be used. Otherwise, the virtual height is
+ chosen to be the smallest that can accommodate the modes
+ selected.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>apertureSize</parameter></term>
+ <listitem><para>
+ The size (in bytes) of the aperture used to access video
+ memory.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><parameter>strategy</parameter></term>
+ <listitem><para>
+ The strategy to use when choosing from multiple modes
+ with the same name. The options are:
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>LOOKUP_DEFAULT</constant></term>
+ <listitem><para>???
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>LOOKUP_BEST_REFRESH</constant></term>
+ <listitem><para>mode with best refresh rate
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>LOOKUP_CLOSEST_CLOCK</constant></term>
+ <listitem><para>mode with closest matching clock
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>LOOKUP_LIST_ORDER</constant></term>
+ <listitem><para>first usable mode in list
+ </para></listitem></varlistentry>
+ </variablelist>
+
+ The following options can also be combined (OR'ed) with
+ one of the above:
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>LOOKUP_CLKDIV2</constant></term>
+ <listitem><para>Allow halved clocks
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>LOOKUP_OPTIONAL_TOLERANCES</constant></term>
+ <listitem><para>
+ Allow missing horizontal sync and/or vertical refresh
+ ranges in the xorg.conf Monitor section
+ </para></listitem></varlistentry>
+ </variablelist>
+
+ <constant>LOOKUP_OPTIONAL_TOLERANCES</constant> should only be
+ specified when the driver can ensure all modes it generates
+ can sync on, or at least not damage, the monitor or digital
+ flat panel. Horizontal sync and/or vertical refresh ranges
+ specified by the user will still be honoured (and acted upon).
+
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ This function requires that the following fields of the
+ <structname>ScrnInfoRec</structname> are initialised prior to calling it:
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>clock[]</structfield></term>
+ <listitem><para>
+ List of discrete clocks (when non-programmable)
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>numClocks</structfield></term>
+ <listitem><para>
+ Number of discrete clocks (when non-programmable)
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>progClock</structfield></term>
+ <listitem><para>
+ Whether the clock is programmable or not
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>monitor</structfield></term>
+ <listitem><para>
+ Pointer to the applicable xorg.conf monitor section
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>fdFormat</structfield></term>
+ <listitem><para>
+ Format of the screen buffer
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>videoRam</structfield></term>
+ <listitem><para>
+ total video memory size (in bytes)
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>maxHValue</structfield></term>
+ <listitem><para>
+ Maximum horizontal timing value allowed
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>maxVValue</structfield></term>
+ <listitem><para>
+ Maximum vertical timing value allowed
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>xInc</structfield></term>
+ <listitem><para>
+ Horizontal timing increment in pixels (defaults to 8)
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ This function fills in the following <structname>ScrnInfoRec</structname>
+ fields:
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>modePool</structfield></term>
+ <listitem><para>
+ A subset of the modes available to the monitor which
+ are compatible with the driver.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>modes</structfield></term>
+ <listitem><para>
+ One mode entry for each of the requested modes, with
+ the status field of each filled in to indicate if
+ the mode has been accepted or not. This list of
+ modes is a circular list.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>virtualX</structfield></term>
+ <listitem><para>
+ The resulting virtual width.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>virtualY</structfield></term>
+ <listitem><para>
+ The resulting virtual height.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>displayWidth</structfield></term>
+ <listitem><para>
+ The resulting line pitch.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>virtualFrom</structfield></term>
+ <listitem><para>
+ Where the virtual size was determined from.
+ </para></listitem></varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ The first stage of this function checks that the
+ <parameter>virtualX</parameter> and <parameter>virtualY</parameter> values
+ supplied (if greater than zero) are consistent with the line pitch
+ and <parameter>maxHeight</parameter> limitations. If not, an error
+ message is printed, and the return value is <constant>-1</constant>.
+ </para>
+
+ <para>
+ The second stage sets up the mode pool, eliminating immediately
+ any modes that exceed the driver's line pitch limits, and also
+ the virtual width and height limits (if greater than zero). For
+ each mode removed an informational message is printed at verbosity
+ level <constant>2</constant>. If the mode pool ends up being empty,
+ a warning message is printed, and the return value is
+ <constant>0</constant>.
+ </para>
+
+ <para>
+ The final stage is to lookup each mode name, and fill in the remaining
+ parameters. If an error condition is encountered, a message is
+ printed, and the return value is <constant>-1</constant>. Otherwise,
+ the return value is the number of valid modes found
+ (<constant>0</constant> if none are found).
+ </para>
+
+ <para>
+ Even if the supplied mode names include duplicates, no two names will
+ ever match the same mode. Furthermore, if the supplied mode names do not
+ yield a valid mode (including the case where no names are passed at all),
+ the function will continue looking through the mode pool until it finds
+ a mode that survives all checks, or until the mode pool is exhausted.
+ </para>
+
+ <para>
+ A message is only printed by this function when a fundamental
+ problem is found. It is intended that this function may be called
+ more than once if there is more than one set of constraints that
+ the driver can work within.
+ </para>
+
+ <para>
+ If this function returns <constant>-1</constant>, the
+ <function>ChipPreInit()</function> function should return
+ <constant>FALSE</constant>.
+ </para>
+
+ <para>
+ <parameter>clockRanges</parameter> is a linked list of clock ranges
+ allowed by the driver. If a mode doesn't fit in any of the defined
+ <parameter>clockRanges</parameter>, it is rejected. The first
+ <literal remap="tt">clockRange</literal> that matches all requirements is used.
+ This structure needs to be initialized to NULL when allocated.
+ </para>
+
+ <para>
+ <parameter>clockRanges</parameter> contains the following fields:
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>minClock</structfield></term>
+ <term><structfield>maxClock</structfield></term>
+ <listitem><para>
+ The lower and upper mode clock bounds for which the rest
+ of the <structname>clockRange</structname> parameters apply.
+ Since these are the mode clocks, they are not scaled
+ with the <structfield>ClockMulFactor</structfield> and
+ <structfield>ClockDivFactor</structfield>. It is up to the driver
+ to adjust these values if they depend on the clock
+ scaling factors.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>clockIndex</structfield></term>
+ <listitem><para>
+ (not used yet) <constant>-1</constant> for programmable clocks
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>interlaceAllowed</structfield></term>
+ <listitem><para>
+ <constant>TRUE</constant> if interlacing is allowed for this
+ range
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>doubleScanAllowed</structfield></term>
+ <listitem><para>
+ <constant>TRUE</constant> if doublescan or multiscan is allowed
+ for this range
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>ClockMulFactor</structfield></term>
+ <term><structfield>ClockDivFactor</structfield></term>
+ <listitem><para>
+ Scaling factors that are applied to the mode clocks ONLY
+ before selecting a clock index (when there is no
+ programmable clock) or a <structfield>SynthClock</structfield>
+ value. This is useful for drivers that support pixel
+ multiplexing or that need to scale the clocks because
+ of hardware restrictions (like sending 24bpp data to an
+ 8 bit RAMDAC using a tripled clock).
+ </para>
+
+ <para>
+ Note that these parameters describe what must be done
+ to the mode clock to achieve the data transport clock
+ between graphics controller and RAMDAC. For example
+ for <literal remap="tt">2:1</literal> pixel multiplexing, two pixels
+ are sent to the RAMDAC on each clock. This allows the
+ RAMDAC clock to be half of the actual pixel clock.
+ Hence, <code>ClockMulFactor=1</code> and
+ <code>ClockDivFactor=2</code>. This means that the
+ clock used for clock selection (ie, determining the
+ correct clock index from the list of discrete clocks)
+ or for the <structfield>SynthClock</structfield> field in case of
+ a programmable clock is: (<code>mode->Clock *
+ ClockMulFactor) / ClockDivFactor</code>.
+ </para></listitem></varlistentry>
+
+ <varlistentry>
+ <term><structfield>PrivFlags</structfield></term>
+ <listitem><para>
+ This field is copied into the
+ <literal remap="tt">mode->PrivFlags</literal> field when this
+ <literal remap="tt">clockRange</literal> is selected by
+ <function>xf86ValidateModes()</function>. It allows the
+ driver to find out what clock range was selected, so it
+ knows it needs to set up pixel multiplexing or any other
+ range-dependent feature. This field is purely
+ driver-defined: it may contain flag bits, an index or
+ anything else (as long as it is an <literal remap="tt">INT</literal>).
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Note that the <structfield>mode->SynthClock</structfield> field is always
+ filled in by <function>xf86ValidateModes()</function>: it will contain
+ the <quote>data transport clock</quote>, which is the clock that will have
+ to be programmed in the chip when it has a programmable clock, or
+ the clock that will be picked from the clocks list when it is not
+ a programmable one. Thus:
+
+ <programlisting>
+ mode->SynthClock = (mode->Clock * ClockMulFactor) / ClockDivFactor
+ </programlisting>
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86PruneDriverModes(ScrnInfoPtr scrp);
+ </programlisting>
+ <blockquote><para>
+ This function deletes modes in the modes field of the
+ <structname>ScrnInfoRec</structname> that have been marked as invalid.
+ This is normally run after having run
+ <function>xf86ValidateModes()</function> for the last time. For each
+ mode that is deleted, a warning message is printed out indicating
+ the reason for it being deleted.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags);
+ </programlisting>
+ <blockquote><para>
+ This function fills in the <structname>Crtc*</structname> fields for all
+ the modes in the <structfield>modes</structfield> field of the
+ <structname>ScrnInfoRec</structname>. The <parameter>adjustFlags</parameter>
+ parameter determines how the vertical CRTC values are scaled for
+ interlaced modes. They are halved if it is
+ <constant>INTERLACE_HALVE_V</constant>. The vertical CRTC values are
+ doubled for doublescan modes, and are further multiplied by the
+ <literal remap="tt">VScan</literal> value.
+ </para>
+
+ <para>
+ This function is normally called after calling
+ <function>xf86PruneDriverModes()</function>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86PrintModes(ScrnInfoPtr scrp);
+ </programlisting>
+ <blockquote><para>
+ This function prints out the virtual size setting, and the line
+ pitch being used. It also prints out two lines for each mode being
+ used. The first line includes the mode's pixel clock, horizontal sync
+ rate, refresh rate, and whether it is interlaced, doublescanned and/or
+ multi-scanned. The second line is the mode's Modeline.
+ </para>
+
+ <para>
+ This function is normally called after calling
+ <function>xf86SetCrtcForModes()</function>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ </sect2>
+
+ <sect2>
+ <title>Secondary Mode functions</title>
+
+ <para>
+The secondary mode helper functions are functions which are normally
+used by the primary mode helper functions, and which are not normally
+called directly by a driver. If a driver has unusual requirements
+and needs to do its own mode validation, it might be able to make
+use of some of these secondary mode helper functions.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
+ int *divider);
+ </programlisting>
+ <blockquote><para>
+ This function returns the index of the closest clock to the
+ frequency <parameter>freq</parameter> given (in kHz). It assumes that
+ the number of clocks is greater than zero. It requires that the
+ <structfield>numClocks</structfield> and <structfield>clock</structfield> fields of the
+ <structname>ScrnInfoRec</structname> are initialised. The
+ <structfield>allowDiv2</structfield> field determines if the clocks can be
+ halved. The <parameter>*divider</parameter> return value indicates
+ whether clock division is used when determining the clock returned.
+ </para>
+
+ <para>
+ This function is only for non-programmable clocks.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ const char *xf86ModeStatusToString(ModeStatus status);
+ </programlisting>
+ <blockquote><para>
+ This function converts the <parameter>status</parameter> value to a
+ descriptive printable string.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
+ ClockRangePtr clockRanges, LookupModeFlags strategy);
+ </programlisting>
+ <blockquote><para>
+ This function takes a pointer to a mode with the name filled in,
+ and looks for a mode in the <structfield>modePool</structfield> list which
+ matches. The parameters of the matching mode are filled in to
+ <parameter>*modep</parameter>. The <parameter>clockRanges</parameter> and
+ <parameter>strategy</parameter> parameters are as for the
+ <function>xf86ValidateModes()</function> function above.
+ </para>
+
+ <para>
+ This function requires the <structfield>modePool</structfield>,
+ <structfield>clock[]</structfield>, <structfield>numClocks</structfield> and
+ <structfield>progClock</structfield> fields of the <structname>ScrnInfoRec</structname>
+ to be initialised before being called.
+ </para>
+
+ <para>
+ The return value is <constant>MODE_OK</constant> if a mode was found.
+ Otherwise it indicates why a matching mode could not be found.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp,
+ DisplayModePtr mode, ClockRangePtr clockRanges,
+ LookupModeFlags strategy, int maxPitch,
+ int virtualX, int virtualY);
+ </programlisting>
+ <blockquote><para>
+ This function checks the passed mode against some basic driver
+ constraints. Apart from the ones passed explicitly, the
+ <structfield>maxHValue</structfield> and <structfield>maxVValue</structfield> fields of
+ the <structname>ScrnInfoRec</structname> are also used. If the
+ <structfield>ValidMode</structfield> field of the <structname>ScrnInfoRec</structname>
+ is set, that function is also called to check the mode. Next, the
+ mode is checked against the monitor's constraints.
+ </para>
+
+ <para>
+ If the mode is consistent with all constraints, the return value
+ is <constant>MODE_OK</constant>. Otherwise the return value indicates
+ which constraint wasn't met.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode);
+ </programlisting>
+ <blockquote><para>
+ This function deletes the <parameter>mode</parameter> given from the
+ <parameter>modeList</parameter>. It never prints any messages, so it is
+ up to the caller to print a message if required.
+ </para>
+
+ </blockquote></para></blockquote>
+ </sect2>
+
+ <sect2>
+ <title>Functions for handling strings and tokens</title>
+
+ <para>
+ Tables associating strings and numerical tokens combined with the
+ following functions provide a compact way of handling strings from
+ the config file, and for converting tokens into printable strings.
+ The table data structure is:
+
+ <programlisting>
+typedef struct {
+ int token;
+ const char * name;
+} SymTabRec, *SymTabPtr;
+ </programlisting>
+ </para>
+
+ <para>
+ A table is an initialised array of <structname>SymTabRec</structname>. The
+ tokens must be non-negative integers. Multiple names may be mapped
+ to a single token. The table is terminated with an element with a
+ <structfield>token</structfield> value of <constant>-1</constant> and
+ <constant>NULL</constant> for the <structfield>name</structfield>.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ const char *xf86TokenToString(SymTabPtr table, int token);
+ </programlisting>
+ <blockquote><para>
+ This function returns the first string in <parameter>table</parameter>
+ that matches <parameter>token</parameter>. If no match is found,
+ <constant>NULL</constant> is returned (NOTE, older versions of this
+ function would return the string "unknown" when no match is found).
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ int xf86StringToToken(SymTabPtr table, const char *string);
+ </programlisting>
+ <blockquote><para>
+ This function returns the first token in <parameter>table</parameter>
+ that matches <parameter>string</parameter>. The
+ <function>xf86NameCmp()</function> function is used to determine the
+ match. If no match is found, <constant>-1</constant> is returned.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ </sect2>
+
+ <sect2>
+ <title>Functions for finding which config file entries to use</title>
+
+ <para>
+ These functions can be used to select the appropriate config file
+ entries that match the detected hardware. They are described above
+ in the <link linkend="probe">Probe</link> and
+ <link linkend="avail">Available Functions</link> sections.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Probing discrete clocks on old hardware</title>
+
+ <para>
+ The <function>xf86GetClocks()</function> function may be used to assist
+ in finding the discrete pixel clock values on older hardware.
+ </para>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86GetClocks(ScrnInfoPtr pScrn, int num,
+ Bool (*ClockFunc)(ScrnInfoPtr, int),
+ void (*ProtectRegs)(ScrnInfoPtr, Bool),
+ void (*BlankScreen)(ScrnInfoPtr, Bool),
+ int vertsyncreg, int maskval, int knownclkindex,
+ int knownclkvalue);
+ </programlisting>
+ <blockquote><para>
+ This function uses a comparative sampling method to measure the
+ discrete pixel clock values. The number of discrete clocks to
+ measure is given by <parameter>num</parameter>. <parameter>clockFunc</parameter>
+ is a function that selects the <parameter>n</parameter>'th clock. It
+ should also save or restore any state affected by programming the
+ clocks when the index passed is <constant>CLK_REG_SAVE</constant> or
+ <constant>CLK_REG_RESTORE</constant>. <parameter>ProtectRegs</parameter> is
+ a function that does whatever is required to protect the hardware
+ state while selecting a new clock. <parameter>BlankScreen</parameter>
+ is a function that blanks the screen. <parameter>vertsyncreg</parameter>
+ and <parameter>maskval</parameter> are the register and bitmask to
+ check for the presence of vertical sync pulses.
+ <parameter>knownclkindex</parameter> and <parameter>knownclkvalue</parameter>
+ are the index and value of a known clock. These are the known
+ references on which the comparative measurements are based. The
+ number of clocks probed is set in <structfield>pScrn->numClocks</structfield>,
+ and the probed clocks are set in the <structfield>pScrn->clock[]</structfield>
+ array. All of the clock values are in units of kHz.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from);
+ </programlisting>
+ <blockquote><para>
+ Print out the pixel clocks <parameter>scrp->clock[]</parameter>.
+ <parameter>from</parameter> indicates whether the clocks were probed
+ or from the config file.
+ </para>
+
+ </blockquote></para></blockquote>
+ </sect2>
+
+ <sect2>
+ <title>Other helper functions</title>
+
+ <blockquote><para>
+ <programlisting>
+ Bool xf86IsUnblank(int mode);
+ </programlisting>
+ <blockquote><para>
+ Returns <constant>TRUE</constant> when the screen saver mode specified
+ by <parameter>mode</parameter> requires the screen be unblanked,
+ and <constant>FALSE</constant> otherwise. The screen saver modes that
+ require blanking are <constant>SCREEN_SAVER_ON</constant> and
+ <constant>SCREEN_SAVER_CYCLE</constant>, and the screen saver modes that
+ require unblanking are <constant>SCREEN_SAVER_OFF</constant> and
+ <constant>SCREEN_SAVER_FORCER</constant>. Drivers may call this helper
+ from their <function>SaveScreen()</function> function to interpret the
+ screen saver modes.
+ </para>
+
+ </blockquote></para></blockquote>
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>The vgahw module</title>
+
+ <para>
+The vgahw modules provides an interface for saving, restoring and
+programming the standard VGA registers, and for handling VGA colourmaps.
+ </para>
+
+ <sect2>
+ <title>Data Structures</title>
+
+ <para>
+ The public data structures used by the vgahw module are
+ <structname>vgaRegRec</structname> and <structname>vgaHWRec</structname>. They are
+ defined in <filename>vgaHW.h.</filename>
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>General vgahw Functions</title>
+
+ <blockquote><para>
+ <programlisting>
+ Bool vgaHWGetHWRec(ScrnInfoPtr pScrn);
+ </programlisting>
+ <blockquote><para>
+ This function allocates a <structname>vgaHWRec</structname> structure, and
+ hooks it into the <structname>ScrnInfoRec</structname>'s
+ <structfield>privates</structfield>. Like all information hooked into the
+ <structfield>privates</structfield>, it is persistent, and only needs to be
+ allocated once per screen. This function should normally be called
+ from the driver's <function>ChipPreInit()</function> function. The
+ <structname>vgaHWRec</structname> is zero-allocated, and the following
+ fields are explicitly initialised:
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>ModeReg.DAC[]</structfield></term>
+ <listitem><para>initialised with a default colourmap
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>ModeReg.Attribute[0x11]</structfield></term>
+ <listitem><para>initialised with the default overscan index
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>ShowOverscan</structfield></term>
+ <listitem><para>initialised according to the "ShowOverscan" option
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>paletteEnabled</structfield></term>
+ <listitem><para>initialised to FALSE
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>cmapSaved</structfield></term>
+ <listitem><para>initialised to FALSE
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><structfield>pScrn</structfield></term>
+ <listitem><para>initialised to pScrn
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ In addition to the above, <function>vgaHWSetStdFuncs()</function> is
+ called to initialise the register access function fields with the
+ standard VGA set of functions.
+ </para>
+
+ <para>
+ Once allocated, a pointer to the <structname>vgaHWRec</structname> can be
+ obtained from the <literal remap="tt">ScrnInfoPtr</literal> with the
+ <literal remap="tt">VGAHWPTR(pScrn)</literal> macro.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWFreeHWRec(ScrnInfoPtr pScrn);
+ </programlisting>
+ <blockquote><para>
+ This function frees a <structname>vgaHWRec</structname> structure. It
+ should be called from a driver's <function>ChipFreeScreen()</function>
+ function.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool vgaHWSetRegCounts(ScrnInfoPtr pScrn, int numCRTC,
+ int numSequencer, int numGraphics, int numAttribute);
+ </programlisting>
+ <blockquote><para>
+ This function allows the number of CRTC, Sequencer, Graphics and
+ Attribute registers to be changed. This makes it possible for
+ extended registers to be saved and restored with
+ <function>vgaHWSave()</function> and <function>vgaHWRestore()</function>.
+ This function should be called after a <structname>vgaHWRec</structname>
+ has been allocated with <function>vgaHWGetHWRec()</function>. The
+ default values are defined in <filename>vgaHW.h</filename> as follows:
+
+ <programlisting>
+#define VGA_NUM_CRTC 25
+#define VGA_NUM_SEQ 5
+#define VGA_NUM_GFX 9
+#define VGA_NUM_ATTR 21
+ </programlisting>
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src);
+ </programlisting>
+ <blockquote><para>
+ This function copies the contents of the VGA saved registers in
+ <parameter>src</parameter> to <parameter>dst</parameter>. Note that it isn't
+ possible to simply do this with <function>memcpy()</function> (or
+ similar). This function returns <constant>TRUE</constant> unless there
+ is a problem allocating space for the <structfield>CRTC</structfield> and
+ related fields in <parameter>dst</parameter>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWSetStdFuncs(vgaHWPtr hwp);
+ </programlisting>
+ <blockquote><para>
+ This function initialises the register access function fields of
+ <parameter>hwp</parameter> with the standard VGA set of functions. This
+ is called by <function>vgaHWGetHWRec()</function>, so there is usually
+ no need to call this explicitly. The register access functions
+ are described below. If the registers are shadowed in some other
+ port I/O space (for example a PCI I/O region), these functions
+ can be used to access the shadowed registers if
+ <structfield>hwp->PIOOffset</structfield> is initialised with
+ <literal remap="tt">offset</literal>, calculated in such a way that when the
+ standard VGA I/O port value is added to it the correct offset into
+ the PIO area results. This value is initialised to zero in
+ <function>vgaHWGetHWRec()</function>. (Note: the PIOOffset functionality
+ is present in XFree86 4.1.0 and later.)
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset);
+ </programlisting>
+ <blockquote><para>
+ This function initialised the register access function fields of
+ hwp with a generic MMIO set of functions.
+ <structfield>hwp->MMIOBase</structfield> is initialised with
+ <parameter>base</parameter>, which must be the virtual address that the
+ start of MMIO area is mapped to. <structfield>hwp->MMIOOffset</structfield>
+ is initialised with <parameter>offset</parameter>, which must be calculated
+ in such a way that when the standard VGA I/O port value is added
+ to it the correct offset into the MMIO area results. That means
+ that these functions are only suitable when the VGA I/O ports are
+ made available in a direct mapping to the MMIO space. If that is
+ not the case, the driver will need to provide its own register
+ access functions. The register access functions are described
+ below.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool vgaHWMapMem(ScrnInfoPtr pScrn);
+ </programlisting>
+ <blockquote><para>
+ This function maps the VGA memory window. It requires that the
+ <structname>vgaHWRec</structname> be allocated. If a driver requires
+ non-default <structfield>MapPhys</structfield> or <structfield>MapSize</structfield>
+ settings (the physical location and size of the VGA memory window)
+ then those fields of the <structname>vgaHWRec</structname> must be initialised
+ before calling this function. Otherwise, this function initialiases
+ the default values of <constant>0xA0000</constant> for
+ <structfield>MapPhys</structfield> and <code>(64 * 1024)</code> for
+ <structfield>MapSize</structfield>. This function must be called before
+ attempting to save or restore the VGA state. If the driver doesn't
+ call it explicitly, the <function>vgaHWSave()</function> and
+ <function>vgaHWRestore()</function> functions may call it if they need
+ to access the VGA memory (in which case they will also call
+ <function>vgaHWUnmapMem()</function> to unmap the VGA memory before
+ exiting).
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWUnmapMem(ScrnInfoPtr pScrn);
+ </programlisting>
+ <blockquote><para>
+ This function unmaps the VGA memory window. It must only be called
+ after the memory has been mapped. The <structfield>Base</structfield> field
+ of the <structname>vgaHWRec</structname> field is set to <constant>NULL</constant>
+ to indicate that the memory is no longer mapped.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWGetIOBase(vgaHWPtr hwp);
+ </programlisting>
+ <blockquote><para>
+ This function initialises the <structfield>IOBase</structfield> field of the
+ <structname>vgaHWRec</structname>. This function must be called before
+ using any other functions that access the video hardware.
+ </para>
+
+ <para>
+ A macro <function>VGAHW_GET_IOBASE()</function> is also available in
+ <filename>vgaHW.h</filename> that returns the I/O base, and this may
+ be used when the vgahw module is not loaded (for example, in the
+ <function>ChipProbe()</function> function).
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWUnlock(vgaHWPtr hwp);
+ </programlisting>
+ <blockquote><para>
+ This function unlocks the VGA <literal remap="tt">CRTC[0-7]</literal> registers,
+ and must be called before attempting to write to those registers.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWLock(vgaHWPtr hwp);
+ </programlisting>
+ <blockquote><para>
+ This function locks the VGA <literal remap="tt">CRTC[0-7]</literal> registers.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWEnable(vgaHWPtr hwp);
+ </programlisting>
+ <blockquote><para>
+ This function enables the VGA subsystem. (Note, this function is
+ present in XFree86 4.1.0 and later.).
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWDisable(vgaHWPtr hwp);
+ </programlisting>
+ <blockquote><para>
+ This function disables the VGA subsystem. (Note, this function is
+ present in XFree86 4.1.0 and later.).
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWSave(ScrnInfoPtr pScrn, vgaRegPtr save, int flags);
+ </programlisting>
+ <blockquote><para>
+ This function saves the VGA state. The state is written to the
+ <structname>vgaRegRec</structname> pointed to by <parameter>save</parameter>.
+ <parameter>flags</parameter> is set to one or more of the following flags
+ ORed together:
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>VGA_SR_MODE</constant></term>
+ <listitem><para>the mode setting registers are saved
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>VGA_SR_FONTS</constant></term>
+ <listitem><para>the text mode font/text data is saved
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>VGA_SR_CMAP</constant></term>
+ <listitem><para>the colourmap (LUT) is saved
+ </para></listitem></varlistentry>
+ <varlistentry>
+ <term><constant>VGA_SR_ALL</constant></term>
+ <listitem><para>all of the above are saved
+ </para></listitem></varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The <structname>vgaHWRec</structname> and its <structfield>IOBase</structfield> fields
+ must be initialised before this function is called. If
+ <constant>VGA_SR_FONTS</constant> is set in <parameter>flags</parameter>, the
+ VGA memory window must be mapped. If it isn't then
+ <function>vgaHWMapMem()</function> will be called to map it, and
+ <function>vgaHWUnmapMem()</function> will be called to unmap it
+ afterwards. <function>vgaHWSave()</function> uses the three functions
+ below in the order <function>vgaHWSaveColormap()</function>,
+ <function>vgaHWSaveMode()</function>, <function>vgaHWSaveFonts()</function> to
+ carry out the different save phases. It is undecided at this
+ stage whether they will remain part of the vgahw module's public
+ interface or not.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWSaveMode(ScrnInfoPtr pScrn, vgaRegPtr save);
+ </programlisting>
+ <blockquote><para>
+ This function saves the VGA mode registers. They are saved to
+ the <structname>vgaRegRec</structname> pointed to by <parameter>save</parameter>.
+ The registers saved are:
+
+ <literallayout>
+ MiscOut
+ CRTC[0-0x18]
+ Attribute[0-0x14]
+ Graphics[0-8]
+ Sequencer[0-4]
+ </literallayout>
+ </para>
+
+ <para>
+ The number of registers actually saved may be modified by a prior call
+ to <function>vgaHWSetRegCounts()</function>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWSaveFonts(ScrnInfoPtr pScrn, vgaRegPtr save);
+ </programlisting>
+ <blockquote><para>
+ This function saves the text mode font and text data held in the
+ video memory. If called while in a graphics mode, no save is
+ done. The VGA memory window must be mapped with
+ <function>vgaHWMapMem()</function> before to calling this function.
+ </para>
+
+ <para>
+ On some platforms, one or more of the font/text plane saves may be
+ no-ops. This is the case when the platform's VC driver already
+ takes care of this.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWSaveColormap(ScrnInfoPtr pScrn, vgaRegPtr save);
+ </programlisting>
+ <blockquote><para>
+ This function saves the VGA colourmap (LUT). Before saving it, it
+ attempts to verify that the colourmap is readable. In rare cases
+ where it isn't readable, a default colourmap is saved instead.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWRestore(ScrnInfoPtr pScrn, vgaRegPtr restore, int flags);
+ </programlisting>
+ <blockquote><para>
+ This function programs the VGA state. The state programmed is
+ that contained in the <structname>vgaRegRec</structname> pointed to by
+ <parameter>restore</parameter>. <parameter>flags</parameter> is the same
+ as described above for the <function>vgaHWSave()</function> function.
+ </para>
+
+ <para>
+ The <structname>vgaHWRec</structname> and its <structfield>IOBase</structfield> fields
+ must be initialised before this function is called. If
+ <constant>VGA_SR_FONTS</constant> is set in <parameter>flags</parameter>, the
+ VGA memory window must be mapped. If it isn't then
+ <function>vgaHWMapMem()</function> will be called to map it, and
+ <function>vgaHWUnmapMem()</function> will be called to unmap it
+ afterwards. <function>vgaHWRestore()</function> uses the three functions
+ below in the order <function>vgaHWRestoreFonts()</function>,
+ <function>vgaHWRestoreMode()</function>,
+ <function>vgaHWRestoreColormap()</function> to carry out the different
+ restore phases. It is undecided at this stage whether they will
+ remain part of the vgahw module's public interface or not.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWRestoreMode(ScrnInfoPtr pScrn, vgaRegPtr restore);
+ </programlisting>
+ <blockquote><para>
+ This function restores the VGA mode registers. They are restored
+ from the data in the <structname>vgaRegRec</structname> pointed to by
+ <parameter>restore</parameter>. The registers restored are:
+
+ <literallayout>
+ MiscOut
+ CRTC[0-0x18]
+ Attribute[0-0x14]
+ Graphics[0-8]
+ Sequencer[0-4]
+ </literallayout>
+ </para>
+
+ <para>
+ The number of registers actually restored may be modified by a prior call
+ to <function>vgaHWSetRegCounts()</function>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWRestoreFonts(ScrnInfoPtr pScrn, vgaRegPtr restore);
+ </programlisting>
+ <blockquote><para>
+ This function restores the text mode font and text data to the
+ video memory. The VGA memory window must be mapped with
+ <function>vgaHWMapMem()</function> before to calling this function.
+ </para>
+
+ <para>
+ On some platforms, one or more of the font/text plane restores
+ may be no-ops. This is the case when the platform's VC driver
+ already takes care of this.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWRestoreColormap(ScrnInfoPtr pScrn, vgaRegPtr restore);
+ </programlisting>
+ <blockquote><para>
+ This function restores the VGA colourmap (LUT).
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+ </programlisting>
+ <blockquote><para>
+ This function fills in the <structname>vgaHWRec</structname>'s
+ <structfield>ModeReg</structfield> field with the values appropriate for
+ programming the given video mode. It requires that the
+ <structname>ScrnInfoRec</structname>'s <structfield>depth</structfield> field is
+ initialised, which determines how the registers are programmed.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWSeqReset(vgaHWPtr hwp, Bool start);
+ </programlisting>
+ <blockquote><para>
+ Do a VGA sequencer reset. If start is <constant>TRUE</constant>, the
+ reset is started. If start is <constant>FALSE</constant>, the reset
+ is ended.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWProtect(ScrnInfoPtr pScrn, Bool on);
+ </programlisting>
+ <blockquote><para>
+ This function protects VGA registers and memory from corruption
+ during loads. It is typically called with on set to
+ <constant>TRUE</constant> before programming, and with on set to
+ <constant>FALSE</constant> after programming.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ Bool vgaHWSaveScreen(ScreenPtr pScreen, int mode);
+ </programlisting>
+ <blockquote><para>
+ This function blanks and unblanks the screen. It is blanked when
+ <parameter>mode</parameter> is <constant>SCREEN_SAVER_ON</constant> or
+ <constant>SCREEN_SAVER_CYCLE</constant>, and unblanked when
+ <parameter>mode</parameter> is <constant>SCREEN_SAVER_OFF</constant> or
+ <constant>SCREEN_SAVER_FORCER</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on);
+ </programlisting>
+ <blockquote><para>
+ This function blanks and unblanks the screen. It is blanked when
+ <parameter>on</parameter> is <constant>FALSE</constant>, and unblanked when
+ <parameter>on</parameter> is <constant>TRUE</constant>. This function is
+ provided for use in cases where the <structname>ScrnInfoRec</structname>
+ can't be derived from the <structname>ScreenRec</structname> (while probing
+ for clocks, for example).
+ </para>
+
+ </blockquote></para></blockquote>
+
+ </sect2>
+
+ <sect2>
+ <title>VGA Colormap Functions</title>
+
+ <para>
+ The vgahw module uses the standard colormap support (see the
+ <link linkend="cmap">Colormap Handling</link> section. This is initialised
+ with the following function:
+
+ <blockquote><para>
+ <programlisting>
+ Bool vgaHWHandleColormaps(ScreenPtr pScreen);
+ </programlisting>
+ </para></blockquote>
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>VGA Register Access Functions</title>
+
+ <para>
+ The vgahw module abstracts access to the standard VGA registers by
+ using a set of functions held in the <structname>vgaHWRec</structname>. When
+ the <structname>vgaHWRec</structname> is created these function pointers are
+ initialised with the set of standard VGA I/O register access functions.
+ In addition to these, the vgahw module includes a basic set of MMIO
+ register access functions, and the <structname>vgaHWRec</structname> function
+ pointers can be initialised to these by calling the
+ <function>vgaHWSetMmioFuncs()</function> function described above. Some
+ drivers/platforms may require a different set of functions for VGA
+ access. The access functions are described here.
+ </para>
+
+
+ <blockquote><para>
+ <programlisting>
+ void writeCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value);
+ </programlisting>
+ <blockquote><para>
+ Write <parameter>value</parameter> to CRTC register <parameter>index</parameter>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ CARD8 readCrtc(vgaHWPtr hwp, CARD8 index);
+ </programlisting>
+ <blockquote><para>
+ Return the value read from CRTC register <parameter>index</parameter>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void writeGr(vgaHWPtr hwp, CARD8 index, CARD8 value);
+ </programlisting>
+ <blockquote><para>
+ Write <parameter>value</parameter> to Graphics Controller register
+ <parameter>index</parameter>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ CARD8 readGR(vgaHWPtr hwp, CARD8 index);
+ </programlisting>
+ <blockquote><para>
+ Return the value read from Graphics Controller register
+ <parameter>index</parameter>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void writeSeq(vgaHWPtr hwp, CARD8 index, CARD8, value);
+ </programlisting>
+ <blockquote><para>
+ Write <parameter>value</parameter> to Sequencer register
+ <parameter>index</parameter>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ CARD8 readSeq(vgaHWPtr hwp, CARD8 index);
+ </programlisting>
+ <blockquote><para>
+ Return the value read from Sequencer register <parameter>index</parameter>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void writeAttr(vgaHWPtr hwp, CARD8 index, CARD8, value);
+ </programlisting>
+ <blockquote><para>
+ Write <parameter>value</parameter> to Attribute Controller register
+ <parameter>index</parameter>. When writing out the index value this
+ function should set bit 5 (<constant>0x20</constant>) according to the
+ setting of <structfield>hwp->paletteEnabled</structfield> in order to
+ preserve the palette access state. It should be cleared when
+ <structfield>hwp->paletteEnabled</structfield> is <constant>TRUE</constant>
+ and set when it is <constant>FALSE</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ CARD8 readAttr(vgaHWPtr hwp, CARD8 index);
+ </programlisting>
+ <blockquote><para>
+ Return the value read from Attribute Controller register
+ <parameter>index</parameter>. When writing out the index value this
+ function should set bit 5 (<constant>0x20</constant>) according to the
+ setting of <structfield>hwp->paletteEnabled</structfield> in order to
+ preserve the palette access state. It should be cleared when
+ <structfield>hwp->paletteEnabled</structfield> is <constant>TRUE</constant>
+ and set when it is <constant>FALSE</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void writeMiscOut(vgaHWPtr hwp, CARD8 value);
+ </programlisting>
+ <blockquote><para>
+ Write <quote><parameter>value</parameter></quote> to the Miscellaneous Output register.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ CARD8 readMiscOut(vgwHWPtr hwp);
+ </programlisting>
+ <blockquote><para>
+ Return the value read from the Miscellaneous Output register.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void enablePalette(vgaHWPtr hwp);
+ </programlisting>
+ <blockquote><para>
+ Clear the palette address source bit in the Attribute Controller
+ index register and set <literal remap="tt">hwp->paletteEnabled</literal> to
+ <constant>TRUE</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void disablePalette(vgaHWPtr hwp);
+ </programlisting>
+ <blockquote><para>
+ Set the palette address source bit in the Attribute Controller
+ index register and set <literal remap="tt">hwp->paletteEnabled</literal> to
+ <constant>FALSE</constant>.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void writeDacMask(vgaHWPtr hwp, CARD8 value);
+ </programlisting>
+ <blockquote><para>
+ Write <parameter>value</parameter> to the DAC Mask register.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ CARD8 readDacMask(vgaHWptr hwp);
+ </programlisting>
+ <blockquote><para>
+ Return the value read from the DAC Mask register.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void writeDacReadAddress(vgaHWPtr hwp, CARD8 value);
+ </programlisting>
+ <blockquote><para>
+ Write <parameter>value</parameter> to the DAC Read Address register.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void writeDacWriteAddress(vgaHWPtr hwp, CARD8 value);
+ </programlisting>
+ <blockquote><para>
+ Write <parameter>value</parameter> to the DAC Write Address register.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void writeDacData(vgaHWPtr hwp, CARD8 value);
+ </programlisting>
+ <blockquote><para>
+ Write <parameter>value</parameter> to the DAC Data register.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ CARD8 readDacData(vgaHWptr hwp);
+ </programlisting>
+ <blockquote><para>
+ Return the value read from the DAC Data register.
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ CARD8 readEnable(vgaHWptr hwp);
+ </programlisting>
+ <blockquote><para>
+ Return the value read from the VGA Enable register. (Note: This
+ function is present in XFree86 4.1.0 and later.)
+ </para>
+
+ </blockquote></para></blockquote>
+
+ <blockquote><para>
+ <programlisting>
+ void writeEnable(vgaHWPtr hwp, CARD8 value);
+ </programlisting>
+ <blockquote><para>
+ Write <parameter>value</parameter> to the VGA Enable register. (Note: This
+ function is present in XFree86 4.1.0 and later.)
+ </para>
+
+ </blockquote></para></blockquote>
+ </sect2>
+ </sect1>
+
+ <sect1 id="sample">
+ <title>Some notes about writing a driver</title>
+
+ <note><para>NOTE: some parts of this are not up to date</para></note>
+
+ <para>
+The following is an outline for writing a basic unaccelerated driver
+for a PCI video card with a linear mapped framebuffer, and which has a
+VGA core. It is includes some general information that is relevant to
+most drivers (even those which don't fit that basic description).
+ </para>
+
+ <para>
+The information here is based on the initial conversion of the Matrox
+Millennium driver to the <quote>new design</quote>. For a fleshing out and sample
+implementation of some of the bits outlined here, refer to that driver.
+Note that this is an example only. The approach used here will not be
+appropriate for all drivers.
+ </para>
+
+ <para>
+Each driver must reserve a unique driver name, and a string that is used
+to prefix all of its externally visible symbols. This is to avoid name
+space clashes when loading multiple drivers. The examples here are for
+the <quote>ZZZ</quote> driver, which uses the <quote>ZZZ</quote> or <quote>zzz</quote> prefix for its externally
+visible symbols.
+ </para>
+
+ <sect2>
+ <title>Include files</title>
+
+ <para>
+ All drivers normally include the following headers:
+ <literallayout><filename>
+ "xf86.h"
+ "xf86_OSproc.h"
+ "xf86_ansic.h"
+ "xf86Resources.h"
+ </filename></literallayout>
+ Wherever inb/outb (and related things) are used the following should be
+ included:
+ <literallayout><filename>
+ "compiler.h"
+ </filename></literallayout>
+ Note: in drivers, this must be included after <filename>"xf86_ansic.h"</filename>.
+ </para>
+
+ <para>
+ Drivers that need to access PCI vendor/device definitions need this:
+ <literallayout><filename>
+ "xf86PciInfo.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers that need to access the PCI config space need this:
+ <literallayout><filename>
+ "xf86Pci.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers using the mi banking wrapper need:
+
+ <literallayout><filename>
+ "mibank.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers that initialise a SW cursor need this:
+ <literallayout><filename>
+ "mipointer.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ All drivers implementing backing store need this:
+ <literallayout><filename>
+ "mibstore.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ All drivers using the mi colourmap code need this:
+ <literallayout><filename>
+ "micmap.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ If a driver uses the vgahw module, it needs this:
+ <literallayout><filename>
+ "vgaHW.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers supporting VGA or Hercules monochrome screens need:
+ <literallayout><filename>
+ "xf1bpp.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers supporting VGA or EGC 16-colour screens need:
+ <literallayout><filename>
+ "xf4bpp.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers using cfb need:
+ <programlisting>
+ #define PSZ 8
+ #include "cfb.h"
+ #undef PSZ
+ </programlisting>
+ </para>
+
+ <para>
+ Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
+ <literallayout><filename>
+ "cfb16.h"
+ "cfb24.h"
+ "cfb32.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ The driver's own header file:
+ <literallayout><filename>
+ "zzz.h"
+ </filename></literallayout>
+ </para>
+
+ <para>
+ Drivers must NOT include the following:
+
+ <literallayout><filename>
+ "xf86Priv.h"
+ "xf86Privstr.h"
+ "xf86_libc.h"
+ "xf86_OSlib.h"
+ "Xos.h"</filename>
+ any OS header
+ </literallayout>
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Data structures and initialisation</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>The following macros should be defined:
+ <programlisting>
+#define VERSION <version-as-an-int>
+#define ZZZ_NAME "ZZZ" /* the name used to prefix messages */
+#define ZZZ_DRIVER_NAME "zzz" /* the driver name as used in config file */
+#define ZZZ_MAJOR_VERSION <int>
+#define ZZZ_MINOR_VERSION <int>
+#define ZZZ_PATCHLEVEL <int>
+ </programlisting>
+ </para>
+ <para>
+ NOTE: <constant>ZZZ_DRIVER_NAME</constant> should match the name of the
+ driver module without things like the "lib" prefix, the "_drv" suffix
+ or filename extensions.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A DriverRec must be defined, which includes the functions required
+ at the pre-probe phase. The name of this DriverRec must be an
+ upper-case version of ZZZ_DRIVER_NAME (for the purposes of static
+ linking).
+ <programlisting>
+DriverRec ZZZ = {
+ VERSION,
+ ZZZ_DRIVER_NAME,
+ ZZZIdentify,
+ ZZZProbe,
+ ZZZAvailableOptions,
+ NULL,
+ 0
+};
+ </programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>Define list of supported chips and their matching ID:
+ <programlisting>
+static SymTabRec ZZZChipsets[] = {
+ { PCI_CHIP_ZZZ1234, "zzz1234a" },
+ { PCI_CHIP_ZZZ5678, "zzz5678a" },
+ { -1, NULL }
+};
+ </programlisting>
+ </para>
+ <para>
+ The token field may be any integer value that the driver may use to
+ uniquely identify the supported chipsets. For drivers that support
+ only PCI devices using the PCI device IDs might be a natural choice,
+ but this isn't mandatory. For drivers that support both PCI and other
+ devices (like ISA), some other ID should probably used. When other
+ IDs are used as the tokens it is recommended that the names be
+ defined as an <type>enum</type> type.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the driver uses the <function>xf86MatchPciInstances()</function>
+ helper (recommended for drivers that support PCI cards) a list that
+ maps PCI IDs to chip IDs and fixed resources must be defined:
+ <programlisting>
+static PciChipsets ZZZPciChipsets[] = {
+ { PCI_CHIP_ZZZ1234, PCI_CHIP_ZZZ1234, RES_SHARED_VGA },
+ { PCI_CHIP_ZZZ5678, PCI_CHIP_ZZZ5678, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+}
+ </programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Define the <structname>XF86ModuleVersionInfo</structname> struct for the
+ driver. This is required for the dynamically loaded version:
+ <programlisting>
+static XF86ModuleVersionInfo zzzVersRec =
+{
+ "zzz",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ ZZZ_MAJOR_VERSION, ZZZ_MINOR_VERSION, ZZZ_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+ </programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Define a data structure to hold the driver's screen-specific data.
+ This must be used instead of global variables. This would be defined
+ in the <filename>"zzz.h"</filename> file, something like:
+ <programlisting>
+typedef struct {
+ type1 field1;
+ type2 field2;
+ int fooHack;
+ Bool pciRetry;
+ Bool noAccel;
+ Bool hwCursor;
+ CloseScreenProcPtr CloseScreen;
+ OptionInfoPtr Options;
+ ...
+} ZZZRec, *ZZZPtr;
+ </programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Define the list of config file Options that the driver accepts. For
+ consistency between drivers those in the list of <quote>standard</quote> options
+ should be used where appropriate before inventing new options.
+
+ <programlisting>
+typedef enum {
+ OPTION_FOO_HACK,
+ OPTION_PCI_RETRY,
+ OPTION_HW_CURSOR,
+ OPTION_NOACCEL
+} ZZZOpts;
+
+static const OptionInfoRec ZZZOptions[] = {
+ { OPTION_FOO_HACK, "FooHack", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+ </programlisting>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Functions</title>
+
+
+ <sect3>
+ <title>SetupProc</title>
+
+ <para>
+ For dynamically loaded modules, a <varname>ModuleData</varname>
+ variable is required. It is should be the name of the driver
+ prepended to "ModuleData". A <function>Setup()</function> function is
+ also required, which calls <function>xf86AddDriver()</function> to add
+ the driver to the main list of drivers.
+ </para>
+
+ <programlisting>
+static MODULESETUPPROTO(zzzSetup);
+
+XF86ModuleData zzzModuleData = { &zzzVersRec, zzzSetup, NULL };
+
+static pointer
+zzzSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ /* This module should be loaded only once, but check to be sure. */
+
+ if (!setupDone) {
+ /*
+ * Modules that this driver always requires may be loaded
+ * here by calling LoadSubModule().
+ */
+
+ setupDone = TRUE;
+ xf86AddDriver(&MGA, module, 0);
+
+ /*
+ * The return value must be non-NULL on success even though
+ * there is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>GetRec, FreeRec</title>
+
+ <para>
+ A function is usually required to allocate the driver's
+ screen-specific data structure and hook it into the
+ <structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield> field.
+ The <structname>ScrnInfoRec</structname>'s <structfield>driverPrivate</structfield> is
+ initialised to <constant>NULL</constant>, so it is easy to check if the
+ initialisation has already been done. After allocating it, initialise
+ the fields. By using <function>xnfcalloc()</function> to do the allocation
+ it is zeroed, and if the allocation fails the server exits.
+ </para>
+
+ <para>
+ NOTE:
+ When allocating structures from inside the driver which are defined
+ on the common level it is important to initialize the structure to
+ zero.
+ Only this guarantees that the server remains source compatible to
+ future changes in common level structures.
+ </para>
+
+ <programlisting>
+static Bool
+ZZZGetRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+ pScrn->driverPrivate = xnfcalloc(sizeof(ZZZRec), 1);
+ /* Initialise as required */
+ ...
+ return TRUE;
+}
+ </programlisting>
+
+ <para>
+ Define a macro in <filename>"zzz.h"</filename> which gets a pointer to
+ the <structname>ZZZRec</structname> when given <parameter>pScrn</parameter>:
+
+ <programlisting>
+#define ZZZPTR(p) ((ZZZPtr)((p)->driverPrivate))
+ </programlisting>
+ </para>
+
+ <para>
+ Define a function to free the above, setting it to <constant>NULL</constant>
+ once it has been freed:
+
+ <programlisting>
+static void
+ZZZFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+ </programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Identify</title>
+
+ <para>
+ Define the <function>Identify()</function> function. It is run before
+ the Probe, and typically prints out an identifying message, which
+ might include the chipsets it supports. This function is mandatory:
+
+ <programlisting>
+static void
+ZZZIdentify(int flags)
+{
+ xf86PrintChipsets(ZZZ_NAME, "driver for ZZZ Tech chipsets",
+ ZZZChipsets);
+}
+ </programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Probe</title>
+
+ <para>
+ Define the <function>Probe()</function> function. The purpose of this
+ is to find all instances of the hardware that the driver supports,
+ and for the ones not already claimed by another driver, claim the
+ slot, and allocate a <structname>ScrnInfoRec</structname>. This should be
+ a minimal probe, and it should under no circumstances leave the
+ state of the hardware changed. Because a device is found, don't
+ assume that it will be used. Don't do any initialisations other
+ than the required <structname>ScrnInfoRec</structname> initialisations.
+ Don't allocate any new data structures.
+ </para>
+
+ <para>
+ This function is mandatory.
+ </para>
+
+ <para>
+ NOTE: The <function>xf86DrvMsg()</function> functions cannot be used from
+ the Probe.
+ </para>
+
+ <programlisting>
+static Bool
+ZZZProbe(DriverPtr drv, int flags)
+{
+ Bool foundScreen = FALSE;
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+
+ /*
+ * Find the config file Device sections that match this
+ * driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(ZZZ_DRIVER_NAME,
+ &devSections)) <= 0) {
+ return FALSE;
+ }
+
+ /*
+ * Since this is a PCI card, "probing" just amounts to checking
+ * the PCI data that the server has already collected. If there
+ * is none, return.
+ *
+ * Although the config file is allowed to override things, it
+ * is reasonable to not allow it to override the detection
+ * of no PCI video cards.
+ *
+ * The provided xf86MatchPciInstances() helper takes care of
+ * the details.
+ */
+ /* test if PCI bus present */
+ if (xf86GetPciVideoInfo()) {
+
+ numUsed = xf86MatchPciInstances(ZZZ_NAME, PCI_VENDOR_ZZZ,
+ ZZZChipsets, ZZZPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+ if ((pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
+ ZZZPciChipsets, NULL, NULL,
+ NULL, NULL, NULL))) {
+ /* Allocate a ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = ZZZ_DRIVER_NAME;
+ pScrn->name = ZZZ_NAME;
+ pScrn->Probe = ZZZProbe;
+ pScrn->PreInit = ZZZPreInit;
+ pScrn->ScreenInit = ZZZScreenInit;
+ pScrn->SwitchMode = ZZZSwitchMode;
+ pScrn->AdjustFrame = ZZZAdjustFrame;
+ pScrn->EnterVT = ZZZEnterVT;
+ pScrn->LeaveVT = ZZZLeaveVT;
+ pScrn->FreeScreen = ZZZFreeScreen;
+ pScrn->ValidMode = ZZZValidMode;
+ foundScreen = TRUE;
+ /* add screen to entity */
+ }
+ }
+ xfree(usedChips);
+ }
+
+#ifdef HAS_ISA_DEVS
+ /*
+ * If the driver supports ISA hardware, the following block
+ * can be included too.
+ */
+ numUsed = xf86MatchIsaInstances(ZZZ_NAME, ZZZChipsets,
+ ZZZIsaChipsets, drv, ZZZFindIsaDevice,
+ devSections, numDevSections, &usedChips);
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+ if ((pScrn = xf86ConfigIsaEntity(pScrn, flags, usedChips[i],
+ ZZZIsaChipsets, NULL, NULL, NULL,
+ NULL, NULL))) {
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = ZZZ_DRIVER_NAME;
+ pScrn->name = ZZZ_NAME;
+ pScrn->Probe = ZZZProbe;
+ pScrn->PreInit = ZZZPreInit;
+ pScrn->ScreenInit = ZZZScreenInit;
+ pScrn->SwitchMode = ZZZSwitchMode;
+ pScrn->AdjustFrame = ZZZAdjustFrame;
+ pScrn->EnterVT = ZZZEnterVT;
+ pScrn->LeaveVT = ZZZLeaveVT;
+ pScrn->FreeScreen = ZZZFreeScreen;
+ pScrn->ValidMode = ZZZValidMode;
+ foundScreen = TRUE;
+ }
+ }
+ xfree(usedChips);
+#endif /* HAS_ISA_DEVS */
+
+ xfree(devSections);
+ return foundScreen;
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>AvailableOptions</title>
+
+ <para>
+ Define the <function>AvailableOptions()</function> function. The purpose
+ of this is to return the available driver options back to the
+ -configure option, so that an xorg.conf file can be built and the
+ user can see which options are available for them to use.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>PreInit</title>
+
+ <para>
+ Define the <function>PreInit()</function> function. The purpose of
+ this is to find all the information required to determine if the
+ configuration is usable, and to initialise those parts of the
+ <structname>ScrnInfoRec</structname> that can be set once at the beginning
+ of the first server generation. The information should be found in
+ the least intrusive way possible.
+ </para>
+
+ <para>
+ This function is mandatory.
+ </para>
+
+ <para>
+ NOTES:
+ <orderedlist>
+ <listitem><para>
+ The <function>PreInit()</function> function is only called once
+ during the life of the X server (at the start of the first
+ generation).
+ </para></listitem>
+
+ <listitem><para>
+ Data allocated here must be of the type that persists for
+ the life of the X server. This means that data that hooks into
+ the <structname>ScrnInfoRec</structname>'s <structfield>privates</structfield>
+ field should be allocated here, but data that hooks into the
+ <structname>ScreenRec</structname>'s <structfield>devPrivates</structfield> field
+ should not be allocated here. The <structfield>driverPrivate</structfield>
+ field should also be allocated here.
+ </para></listitem>
+
+ <listitem><para>
+ Although the <structname>ScrnInfoRec</structname> has been allocated
+ before this function is called, the <structname>ScreenRec</structname>
+ has not been allocated. That means that things requiring it
+ cannot be used in this function.
+ </para></listitem>
+
+ <listitem><para>
+ Very little of the <structname>ScrnInfoRec</structname> has been
+ initialised when this function is called. It is important to
+ get the order of doing things right in this function.
+ </para></listitem>
+
+ </orderedlist>
+ </para>
+
+ <programlisting>
+static Bool
+ZZZPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ /* Fill in the monitor field */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * If using the vgahw module, it will typically be loaded
+ * here by calling xf86LoadSubModule(pScrn, "vgahw");
+ */
+
+ /*
+ * Set the depth/bpp. Use the globally preferred depth/bpp. If the
+ * driver has special default depth/bpp requirements, the defaults should
+ * be specified here explicitly.
+ * We support both 24bpp and 32bpp framebuffer layouts.
+ * This sets pScrn->display also.
+ */
+ if (!xf86SetDepthBpp(pScrn, 0, 0, 0,
+ Support24bppFb | Support32bppFb)) {
+ return FALSE;
+ } else {
+ if (depth/bpp isn't one we support) {
+ print error message;
+ return FALSE;
+ }
+ }
+ /* Print out the depth/bpp that was set */
+ xf86PrintDepthBpp(pScrn);
+
+ /* Set bits per RGB for 8bpp */
+ if (pScrn->depth <= 8) {
+ /* Take into account a dac_6_bit option here */
+ pScrn->rgbBits = 6 or 8;
+ }
+
+ /*
+ * xf86SetWeight() and xf86SetDefaultVisual() must be called
+ * after pScrn->display is initialised.
+ */
+
+ /* Set weight/mask/offset for depth > 8 */
+ if (pScrn->depth > 8) {
+ if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
+ return FALSE;
+ } else {
+ if (weight isn't one we support) {
+ print error message;
+ return FALSE;
+ }
+ }
+ }
+
+ /* Set the default visual. */
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ if (visual isn't one we support) {
+ print error message;
+ return FALSE;
+ }
+ }
+
+ /* If the driver supports gamma correction, set the gamma. */
+ if (!xf86SetGamma(pScrn, default_gamma)) {
+ return FALSE;
+ }
+
+ /* This driver uses a programmable clock */
+ pScrn->progClock = TRUE;
+
+ /* Allocate the ZZZRec driverPrivate */
+ if (!ZZZGetRec(pScrn)) {
+ return FALSE;
+ }
+
+ pZzz = ZZZPTR(pScrn);
+
+ /* Collect all of the option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /*
+ * Process the options based on the information in ZZZOptions.
+ * The results are written to pZzz->Options. If all of the options
+ * processing is done within this function a local variable "options"
+ * can be used instead of pZzz->Options.
+ */
+ if (!(pZzz->Options = xalloc(sizeof(ZZZOptions))))
+ return FALSE;
+ (void)memcpy(pZzz->Options, ZZZOptions, sizeof(ZZZOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pZzz->Options);
+
+ /*
+ * Set various fields of ScrnInfoRec and/or ZZZRec based on
+ * the options found.
+ */
+ from = X_DEFAULT;
+ pZzz->hwCursor = FALSE;
+ if (xf86IsOptionSet(pZzz->Options, OPTION_HW_CURSOR)) {
+ from = X_CONFIG;
+ pZzz->hwCursor = TRUE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pZzz->hwCursor ? "HW" : "SW");
+ if (xf86IsOptionSet(pZzz->Options, OPTION_NOACCEL)) {
+ pZzz->noAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Acceleration disabled\n");
+ } else {
+ pZzz->noAccel = FALSE;
+ }
+ if (xf86IsOptionSet(pZzz->Options, OPTION_PCI_RETRY)) {
+ pZzz->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ pZzz->fooHack = 0;
+ if (xf86GetOptValInteger(pZzz->Options, OPTION_FOO_HACK,
+ &pZzz->fooHack)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Foo Hack set to %d\n",
+ pZzz->fooHack);
+ }
+
+ /*
+ * Find the PCI slot(s) that this screen claimed in the probe.
+ * In this case, exactly one is expected, so complain otherwise.
+ * Note in this case we're not interested in the card types so
+ * that parameter is set to NULL.
+ */
+ if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL))
+ != 1) {
+ print error message;
+ ZZZFreeRec(pScrn);
+ if (i > 0)
+ xfree(pciList);
+ return FALSE;
+ }
+ /* Note that pciList should be freed below when no longer needed */
+
+ /*
+ * Determine the chipset, allowing config file chipset and
+ * chipid values to override the probed information. The config
+ * chipset value has precedence over its chipid value if both
+ * are present.
+ *
+ * It isn't necessary to fill in pScrn->chipset if the driver
+ * keeps track of the chipset in its ZZZRec.
+ */
+
+ ...
+
+ /*
+ * Determine video memory, fb base address, I/O addresses, etc,
+ * allowing the config file to override probed values.
+ *
+ * Set the appropriate pScrn fields (videoRam is probably the
+ * most important one that other code might require), and
+ * print out the settings.
+ */
+
+ ...
+
+ /* Initialise a clockRanges list. */
+
+ ...
+
+ /* Set any other chipset specific things in the ZZZRec */
+
+ ...
+
+ /* Select valid modes from those available */
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, minPitch, maxPitch, rounding,
+ minHeight, maxHeight,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pScrn->videoRam * 1024,
+ LOOKUP_BEST_REFRESH);
+ if (i == -1) {
+ ZZZFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+
+ xf86PruneDriverModes(pScrn);
+
+ /* If no valid modes, return */
+
+ if (i == 0 || pScrn->modes == NULL) {
+ print error message;
+ ZZZFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Initialise the CRTC fields for the modes. This driver expects
+ * vertical values to be halved for interlaced modes.
+ */
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list. */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used. */
+ xf86PrintModes(pScrn);
+
+ /* Set the DPI */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ mod = "xf1bpp";
+ break;
+ case 4:
+ mod = "xf4bpp";
+ break;
+ case 8:
+ mod = "cfb";
+ break;
+ case 16:
+ mod = "cfb16";
+ break;
+ case 24:
+ mod = "cfb24";
+ break;
+ case 32:
+ mod = "cfb32";
+ break;
+ }
+ if (mod && !xf86LoadSubModule(pScrn, mod))
+ ZZZFreeRec(pScrn);
+ return FALSE;
+
+ /* Load XAA if needed */
+ if (!pZzz->noAccel || pZzz->hwCursor)
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ ZZZFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Done */
+ return TRUE;
+}
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>MapMem, UnmapMem</title>
+
+ <para>
+ Define functions to map and unmap the video memory and any other
+ memory apertures required. These functions are not mandatory, but
+ it is often useful to have such functions.
+ </para>
+
+ <programlisting>
+static Bool
+ZZZMapMem(ScrnInfoPtr pScrn)
+{
+ /* Call xf86MapPciMem() to map each PCI memory area */
+ ...
+ return TRUE or FALSE;
+}
+
+static Bool
+ZZZUnmapMem(ScrnInfoPtr pScrn)
+{
+ /* Call xf86UnMapVidMem() to unmap each memory area */
+ ...
+ return TRUE or FALSE;
+}
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Save, Restore</title>
+
+ <para>
+ Define functions to save and restore the original video state. These
+ functions are not mandatory, but are often useful.
+ </para>
+
+ <programlisting>
+static void
+ZZZSave(ScrnInfoPtr pScrn)
+{
+ /*
+ * Save state into per-screen data structures.
+ * If using the vgahw module, vgaHWSave will typically be
+ * called here.
+ */
+ ...
+}
+
+static void
+ZZZRestore(ScrnInfoPtr pScrn)
+{
+ /*
+ * Restore state from per-screen data structures.
+ * If using the vgahw module, vgaHWRestore will typically be
+ * called here.
+ */
+ ...
+}
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>ModeInit</title>
+
+ <para>
+ Define a function to initialise a new video mode. This function isn't
+ mandatory, but is often useful.
+ </para>
+
+ <programlisting>
+static Bool
+ZZZModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ /*
+ * Program a video mode. If using the vgahw module,
+ * vgaHWInit and vgaRestore will typically be called here.
+ * Once up to the point where there can't be a failure
+ * set pScrn->vtSema to TRUE.
+ */
+ ...
+}
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>ScreenInit</title>
+
+ <para>
+ Define the <function>ScreenInit()</function> function. This is called
+ at the start of each server generation, and should fill in as much
+ of the <structname>ScreenRec</structname> as possible as well as any other
+ data that is initialised once per generation. It should initialise
+ the framebuffer layers it is using, and initialise the initial video
+ mode.
+ </para>
+
+ <para>
+ This function is mandatory.
+ </para>
+
+ <para>
+ NOTE: The <structname>ScreenRec</structname> (<parameter>pScreen</parameter>) is
+ passed to this driver, but it and the
+ <varname>ScrnInfoRecs</varname> are not yet hooked into each
+ other. This means that in this function, and functions it
+ calls, one cannot be found from the other.
+ </para>
+
+ <programlisting>
+static Bool
+ZZZScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ /* Get the ScrnInfoRec */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ /*
+ * If using the vgahw module, its data structures and related
+ * things are typically initialised/mapped here.
+ */
+
+ /* Save the current video state */
+ ZZZSave(pScrn);
+
+ /* Initialise the first mode */
+ ZZZModeInit(pScrn, pScrn->currentMode);
+
+ /* Set the viewport if supported */
+
+ ZZZAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * Setup the screen's visuals, and initialise the framebuffer
+ * code.
+ */
+
+ /* Reset the visual list */
+ miClearVisualTypes();
+
+ /*
+ * Setup the visuals supported. This driver only supports
+ * TrueColor for bpp > 8, so the default set of visuals isn't
+ * acceptable. To deal with this, call miSetVisualTypes with
+ * the appropriate visual mask.
+ */
+
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Initialise the framebuffer.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ ret = cfb24ScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ print a message about an internal error;
+ ret = FALSE;
+ break;
+ }
+
+ if (!ret)
+ return FALSE;
+
+ /* Override the default mask/offset settings */
+ if (pScrn->bitsPerPixel > 8) {
+ for (i = 0, visual = pScreen->visuals;
+ i < pScreen->numVisuals; i++, visual++) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ /*
+ * If banking is needed, initialise an miBankInfoRec (defined in
+ * "mibank.h"), and call miInitializeBanking().
+ */
+ if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
+ pScrn->displayWidth, pBankInfo))
+ return FALSE;
+
+ /*
+ * If backing store is to be supported (as is usually the case),
+ * initialise it.
+ */
+ miInitializeBackingStore(pScreen);
+
+ /*
+ * Set initial black & white colourmap indices.
+ */
+ xf86SetBlackWhitePixels(pScreen);
+
+ /*
+ * Install colourmap functions. If using the vgahw module,
+ * vgaHandleColormaps would usually be called here.
+ */
+
+ ...
+
+ /*
+ * Initialise cursor functions. This example is for the mi
+ * software cursor.
+ */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Initialise the default colourmap */
+ switch (pScrn->depth) {
+ case 1:
+ if (!xf1bppCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+ case 4:
+ if (!xf4bppCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+ default:
+ if (!cfbCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+ }
+
+ /*
+ * Wrap the CloseScreen vector and set SaveScreen.
+ */
+ ZZZPTR(pScrn)->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = ZZZCloseScreen;
+ pScreen->SaveScreen = ZZZSaveScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Done */
+ return TRUE;
+}
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>SwitchMode</title>
+
+ <para>
+ Define the <function>SwitchMode()</function> function if mode switching
+ is supported by the driver.
+ </para>
+
+ <programlisting>
+static Bool
+ZZZSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return ZZZModeInit(xf86Screens[scrnIndex], mode);
+}
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>AdjustFrame</title>
+
+ <para>
+ Define the <function>AdjustFrame()</function> function if the driver
+ supports this.
+ </para>
+
+ <programlisting>
+static void
+ZZZAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ /* Adjust the viewport */
+}
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>EnterVT, LeaveVT</title>
+
+ <para>
+ Define the <function>EnterVT()</function> and <function>LeaveVT()</function>
+ functions.
+ </para>
+
+ <para>
+ These functions are mandatory.
+ </para>
+
+ <programlisting>
+static Bool
+ZZZEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ return ZZZModeInit(pScrn, pScrn->currentMode);
+}
+
+static void
+ZZZLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ ZZZRestore(pScrn);
+}
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>CloseScreen</title>
+
+ <para>
+ Define the <function>CloseScreen()</function> function:
+ </para>
+
+ <para>
+ This function is mandatory. Note that it unwraps the previously
+ wrapped <structfield>pScreen->CloseScreen</structfield>, and finishes by
+ calling it.
+ </para>
+
+ <programlisting>
+static Bool
+ZZZCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ if (pScrn->vtSema) {
+ ZZZRestore(pScrn);
+ ZZZUnmapMem(pScrn);
+ }
+ pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = ZZZPTR(pScrn)->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>SaveScreen</title>
+
+ <para>
+ Define the <function>SaveScreen()</function> function (the screen
+ blanking function). When using the vgahw module, this will typically
+ be:
+
+ <programlisting>
+static Bool
+ZZZSaveScreen(ScreenPtr pScreen, int mode)
+{
+ return vgaHWSaveScreen(pScreen, mode);
+}
+ </programlisting>
+ </para>
+
+ <para>
+ This function is mandatory. Before modifying any hardware register
+ directly this function needs to make sure that the Xserver is active
+ by checking if <parameter>pScrn</parameter> is non-NULL and for
+ <literal remap="tt">pScrn->vtSema == TRUE</literal>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>FreeScreen</title>
+
+ <para>
+ Define the <function>FreeScreen()</function> function. This function
+ is optional. It should be defined if the <structname>ScrnInfoRec</structname>
+ <structfield>driverPrivate</structfield> field is used so that it can be freed
+ when a screen is deleted by the common layer for reasons possibly
+ beyond the driver's control. This function is not used in during
+ normal (error free) operation. The per-generation data is freed by
+ the <function>CloseScreen()</function> function.
+ </para>
+
+ <programlisting>
+static void
+ZZZFreeScreen(int scrnIndex, int flags)
+{
+ /*
+ * If the vgahw module is used vgaHWFreeHWRec() would be called
+ * here.
+ */
+ ZZZFreeRec(xf86Screens[scrnIndex]);
+}
+
+ </programlisting>
+
+ </sect3>
+
+ </sect2>
+
+ </sect1>
+
+</article>
diff --git a/xorg-server/hw/xfree86/doc/sgml/Makefile.am b/xorg-server/hw/xfree86/doc/sgml/Makefile.am index 09b64f7b0..7756c47ac 100644 --- a/xorg-server/hw/xfree86/doc/sgml/Makefile.am +++ b/xorg-server/hw/xfree86/doc/sgml/Makefile.am @@ -1,54 +1,31 @@ -# Copyright 2005 Red Hat, Inc. -# -# Permission to use, copy, modify, distribute, and sell this software -# and its documentation for any purpose is hereby granted without -# fee, provided that the above copyright notice appear in all copies -# and that both that copyright notice and this permission notice -# appear in supporting documentation, and that the name of Red Hat -# not be used in advertising or publicity pertaining to distribution -# of the software without specific, written prior permission. Red -# Hat makes no representations about the suitability of this software -# for any purpose. It is provided "as is" without express or implied -# warranty. -# -# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -# NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR -# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -SGML_FILES = DESIGN.sgml - -if BUILD_LINUXDOC -TXT_FILES = $(SGML_FILES:%.sgml=%.txt) -PS_FILES = $(SGML_FILES:%.sgml=%.ps) -if BUILD_PDFDOC -PDF_FILES = $(SGML_FILES:%.sgml=%.pdf) -endif -HTML_FILES = $(SGML_FILES:%.sgml=%.html) - -SUFFIXES = .sgml .txt .html .ps .pdf - -.sgml.txt: - @rm -f $@ - $(AM_V_GEN)$(MAKE_TEXT) $< - -.sgml.ps: - @rm -f $@ - $(AM_V_GEN)$(MAKE_PS) $< - -.ps.pdf: - @rm -f $@ - $(AM_V_GEN)$(MAKE_PDF) $< - -.sgml.html: - @rm -f $@ - $(AM_V_GEN)$(MAKE_HTML) $< - -noinst_DATA = $(TXT_FILES) $(PS_FILES) $(PDF_FILES) $(HTML_FILES) -CLEANFILES = $(TXT_FILES) $(PS_FILES) $(PDF_FILES) $(HTML_FILES) -endif - -EXTRA_DIST = $(SGML_FILES) +# Copyright 2005 Red Hat, Inc.
+#
+# Permission to use, copy, modify, distribute, and sell this software
+# and its documentation for any purpose is hereby granted without
+# fee, provided that the above copyright notice appear in all copies
+# and that both that copyright notice and this permission notice
+# appear in supporting documentation, and that the name of Red Hat
+# not be used in advertising or publicity pertaining to distribution
+# of the software without specific, written prior permission. Red
+# Hat makes no representations about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied
+# warranty.
+#
+# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+# NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+XML_FILES = DESIGN.xml
+
+include ../../../../doc/xml/xmlrules.in
+
+if ENABLE_DEVEL_DOCS
+noinst_DATA = $(BUILT_DOC_FILES)
+endif
+CLEANFILES = $(CLEAN_DOC_FILES)
+
+EXTRA_DIST = $(XML_FILES)
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c index 9dbeea8a5..417a75ff6 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.c +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c @@ -439,6 +439,7 @@ typedef enum { OPTION_ROTATE,
OPTION_PANNING,
OPTION_PRIMARY,
+ OPTION_DEFAULT_MODES,
} OutputOpts;
static OptionInfoRec xf86OutputOptions[] = {
@@ -456,6 +457,7 @@ static OptionInfoRec xf86OutputOptions[] = { {OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE },
{OPTION_PANNING, "Panning", OPTV_STRING, {0}, FALSE },
{OPTION_PRIMARY, "Primary", OPTV_BOOLEAN, {0}, FALSE },
+ {OPTION_DEFAULT_MODES, "DefaultModes", OPTV_BOOLEAN, {0}, FALSE },
{-1, NULL, OPTV_NONE, {0}, FALSE },
};
@@ -1560,7 +1562,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) int min_clock = 0;
int max_clock = 0;
double clock;
- Bool add_default_modes = TRUE;
+ Bool add_default_modes = xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE);
Bool debug_modes = config->debug_modes ||
xf86Initialising;
enum det_monrec_source sync_source = sync_default;
diff --git a/xorg-server/hw/xnest/Screen.c b/xorg-server/hw/xnest/Screen.c index 5a035ac8f..d25666508 100644 --- a/xorg-server/hw/xnest/Screen.c +++ b/xorg-server/hw/xnest/Screen.c @@ -243,7 +243,6 @@ xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[]) pScreen->saveUnderSupport = NotUseful;
pScreen->whitePixel = xnestWhitePixel;
pScreen->blackPixel = xnestBlackPixel;
- /* rgf */
/* GCperDepth */
/* PixmapPerDepth */
pScreen->devPrivate = NULL;
diff --git a/xorg-server/hw/xwin/Makefile.am b/xorg-server/hw/xwin/Makefile.am index 073885365..a5425d4a7 100644 --- a/xorg-server/hw/xwin/Makefile.am +++ b/xorg-server/hw/xwin/Makefile.am @@ -117,7 +117,6 @@ SRCS = InitInput.c \ winms.h \
winmultiwindowclass.h \
winprefs.h \
- winpriv.h \
winresource.h \
winwindow.h \
XWin.rc \
diff --git a/xorg-server/hw/xwin/glx/Makefile.am b/xorg-server/hw/xwin/glx/Makefile.am index aadd44268..dae58bf89 100644 --- a/xorg-server/hw/xwin/glx/Makefile.am +++ b/xorg-server/hw/xwin/glx/Makefile.am @@ -1,59 +1,60 @@ -noinst_LTLIBRARIES = libXwinGLX.la - -libXwinGLX_la_SOURCES = \ - winpriv.c \ - glwindows.h \ - glwrap.c \ - indirect.c \ - wgl_ext_api.c - -if XWIN_MULTIWINDOW -DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW -endif - -if XWIN_MULTIWINDOWEXTWM -DEFS_MULTIWINDOWEXTWM = -DXWIN_MULTIWINDOWEXTWM -endif - -DEFS = $(DEFS_MULTIWINDOW) $(DEFS_MULTIWINDOWEXTWM) - -INCLUDES = -I$(top_srcdir)/miext/rootless - -AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \ - $(XWINMODULES_CFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/hw/xwin/ - -glwrap.c: generated_gl_wrappers.c -wgl_ext_api.c: generated_wgl_wrappers.c wglext.h -wgl_ext_api.h: wglext.h -indirect.c: wgl_ext_api.h - -SPEC_FILES = gl.spec gl.tm wglext.spec wgl.tm - -gl.spec: - wget http://www.opengl.org/registry/api/gl.spec - -gl.tm: - wget http://www.opengl.org/registry/api/gl.tm - -wglext.spec: - wget http://www.opengl.org/registry/api/wglext.spec - -wgl.tm: - wget http://www.opengl.org/registry/api/wgl.tm - -generated_gl_wrappers.c: gen_gl_wrappers.py gl.spec gl.tm - ./gen_gl_wrappers.py --spec=gl.spec --typemap=gl.tm --dispatch-header=$(top_srcdir)/glx/dispatch.h --staticwrappers >generated_gl_wrappers.c - -generated_wgl_wrappers.c: gen_gl_wrappers.py wglext.spec wgl.tm - ./gen_gl_wrappers.py --spec=wglext.spec --typemap=wgl.tm --prefix=wgl --preresolve >generated_wgl_wrappers.c - -wglext.h: - wget http://www.opengl.org/registry/api/wglext.h - -BUILT_SOURCES = generated_gl_wrappers.c generated_wgl_wrappers.c -CLEANFILES = $(BUILT_SOURCES) -DISTCLEANFILES = $(SPEC_FILES) wglext.h - -EXTRA_DIST = gen_gl_wrappers.py $(SPEC_FILES) wglext.h +noinst_LTLIBRARIES = libXwinGLX.la
+
+libXwinGLX_la_SOURCES = \
+ winpriv.c \
+ winpriv.h \
+ glwindows.h \
+ glwrap.c \
+ indirect.c \
+ wgl_ext_api.c
+
+if XWIN_MULTIWINDOW
+DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW
+endif
+
+if XWIN_MULTIWINDOWEXTWM
+DEFS_MULTIWINDOWEXTWM = -DXWIN_MULTIWINDOWEXTWM
+endif
+
+DEFS = $(DEFS_MULTIWINDOW) $(DEFS_MULTIWINDOWEXTWM)
+
+INCLUDES = -I$(top_srcdir)/miext/rootless
+
+AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \
+ $(XWINMODULES_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/hw/xwin/
+
+glwrap.c: generated_gl_wrappers.c
+wgl_ext_api.c: generated_wgl_wrappers.c wglext.h
+wgl_ext_api.h: wglext.h
+indirect.c: wgl_ext_api.h
+
+SPEC_FILES = gl.spec gl.tm wglext.spec wgl.tm
+
+gl.spec:
+ wget http://www.opengl.org/registry/api/gl.spec
+
+gl.tm:
+ wget http://www.opengl.org/registry/api/gl.tm
+
+wglext.spec:
+ wget http://www.opengl.org/registry/api/wglext.spec
+
+wgl.tm:
+ wget http://www.opengl.org/registry/api/wgl.tm
+
+generated_gl_wrappers.c: gen_gl_wrappers.py gl.spec gl.tm
+ $(srcdir)/gen_gl_wrappers.py --spec=$(srcdir)/gl.spec --typemap=$(srcdir)/gl.tm --dispatch-header=$(top_srcdir)/glx/dispatch.h --staticwrappers >generated_gl_wrappers.c
+
+generated_wgl_wrappers.c: gen_gl_wrappers.py wglext.spec wgl.tm
+ $(srcdir)/gen_gl_wrappers.py --spec=$(srcdir)/wglext.spec --typemap=$(srcdir)/wgl.tm --prefix=wgl --preresolve >generated_wgl_wrappers.c
+
+wglext.h:
+ wget http://www.opengl.org/registry/api/wglext.h
+
+BUILT_SOURCES = generated_gl_wrappers.c generated_wgl_wrappers.c
+CLEANFILES = $(BUILT_SOURCES)
+DISTCLEANFILES = $(SPEC_FILES) wglext.h
+
+EXTRA_DIST = gen_gl_wrappers.py $(SPEC_FILES) wglext.h
diff --git a/xorg-server/include/gcstruct.h b/xorg-server/include/gcstruct.h index c56dd9294..c2f057a4a 100644 --- a/xorg-server/include/gcstruct.h +++ b/xorg-server/include/gcstruct.h @@ -292,7 +292,8 @@ typedef struct _GC { unsigned int tileIsPixel:1; /* tile is solid pixel */
unsigned int fExpose:1; /* Call exposure handling */
unsigned int freeCompClip:1; /* Free composite clip */
- unsigned int unused:14; /* see comment above */
+ unsigned int scratch_inuse:1; /* is this GC in a pool for reuse? */
+ unsigned int unused:13; /* see comment above */
unsigned long planemask;
unsigned long fgPixel;
unsigned long bgPixel;
diff --git a/xorg-server/include/scrnintstr.h b/xorg-server/include/scrnintstr.h index e07bee3c3..8684c8f19 100644 --- a/xorg-server/include/scrnintstr.h +++ b/xorg-server/include/scrnintstr.h @@ -455,7 +455,6 @@ typedef struct _Screen { short minInstalledCmaps, maxInstalledCmaps;
char backingStoreSupport, saveUnderSupport;
unsigned long whitePixel, blackPixel;
- unsigned long rgf; /* array of flags; she's -- HUNGARIAN */
GCPtr GCperDepth[MAXFORMATS+1];
/* next field is a stipple to use as default in
a GC. we don't build default tiles of all depths
|